diff --git a/información/ADAPTACIONESLOGO.pdf b/información/ADAPTACIONESLOGO.pdf new file mode 100644 index 00000000..26290775 --- /dev/null +++ b/información/ADAPTACIONESLOGO.pdf @@ -0,0 +1,4771 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + ADAPTACIONESLOGO + + + + + 2011-04-01T12:01:51+02:00 + 2011-04-01T12:01:51+02:00 + 2011-04-01T12:01:51+02:00 + Adobe Illustrator CS4 + + + + 256 + 36 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAJAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q0yqylWFVYUI9jiqj a2VtaqywJwDkFviZqkCn7ROSlInmgABXyKXYq7FXnv57/wDkvp/+YiD/AIlmy7J/vx7i6ztf/Fz8 PvfNOdW8c7FWaflfqd63nTQrIyD6sLgfBxXsGYfFTl1PjmBr8Y8KR607TszPPxYxv0/2vqTORewd iqldWkF1EYZ15Rkg0BK7jcbqQcMZEGwgi10EEUESxRLxjWtBUnqa98SbUBfgS7FXYqwP87//ACXO of8AGS3/AOTy5seyv78fH7nW9rf4vL4feHzHnWPGuxVl35e6rfv5v0CzaQG2W8hATio2Egb7QHLr 75g63HHwpnrRdn2fnmcsI36bfVWcg9i7FVssSSxtG4qjgqwqRsfcYQaVTtLO3tIjFbrwjLFqVLbt uftE4ZSJ5oApWyKXYq7FUs80f8ozq/8AzBXH/Jpstwf3kfeGvN9B9xfHWdw+fuxVFW+p3tvbSW0U gWGXl6i8VNeQAO5BP7IyEsYJstsM0oxMQdi+utd8yaXoYszfs4+uzi3hEaFzyKlqkDfiAu+cXiwS yXXQW91lzRhV9TSl5Y816d5it5p7NJYvQYLJHMFDjmvJSQrNSqmtDuO4w59PLGaKMOYZBYTnKG52 KsG1384vKWj31/YyrdT3Om3CW136UQ9NWeA3DMZZGji4og+KrVrQU3GKs1triO4t4riI1jmRZEJ2 PFhUfrxVgP57/wDkvp/+YiD/AIlmy7J/vx7i6ztf/Fz8PvfO+h6VJq2sWemJKkLXcqxetJ9lAx3Y /IZ0+XJwRMu55TBiOSYiNrZJ5j/LW80PQDq019HLxlETwKjJ9p2VCrPTkWCcqcemYmDXDJPhAc7U 9mHFj4zJD/ld/wCTB0P/AJiB/wAROT7Q/uJe5q7M/wAYj+Oj6uzjntUl1/zfomhTwwahI6zTxTTR JGjSEpAvJvs+PRfE5fh008guPSvtacuojA0fP7Fuj+dfL+qpCbe44STyNFHDIAHLoaEUBYDp44cm mnDmFx54y5FPMx25pnRftMBWtKmnTrirGfMn5j+WPL2pJpuoSym7kt2uhHBE0tEV/ToSvQsQ1K/y mtKYqreXvPvlrXYrI2lyI7m+jaSGymKiYCNmR1YIXXkrRsGAbbFUk/O//wAlzqH/ABkt/wDk8ubH sr+/Hx+51va3+Ly+H3h8yKrOwRAWZiAqgVJJ6ADOreOAtld3+V/nG0tryee1RBZEiWL1UMjUVHJj QElwBIv2cw46/ESADzdhLsvMASRy/Gyn5Ctbm1/MHQ4bmF4JlvIC0cilGFWBGzUOHWSBwSI32LHQ wMdREEUbfWGcc9qoX19Z2FpLeXkywWsCl5pnNFVR3JyUIGRobljKQiLOwQ1j5h0S/vpbGzvYri7h QSSxRtyIQnjWo265KWGcRZFBjHLEmgd0wytsdiqD1jWdK0bTpdS1W6jsrCDj61zMeKLzYItT7swA xVB6N5w8ta1f3lhpV/Hd3VgxW7SMMQjK5jYciOLUZSDxJxVV80f8ozq//MFcf8mmy3B/eR94a830 H3F8dZ3D5+yLQfIfmHXLOO9so4xayTPAJZZFQBoo/VZiDvxC96ddsxc2shjNHm5uDQZMseKPK0q1 nSL7R9TuNNvk9O6tmCyqDUbgMPvBy7FkE4iQ5Fx82GWOZjLmH0t5pt/MOv2M1g/l9o4lYyWly91b Fw61CloiJEoVY1BY5ymAwxm+P7C9pmEpiuH7Qq+Xk1zRbVbK28riG2VgZZUvIGlkJoGc/DGHYAft EVFMGYwmbM9/cU4hKAoQ297MBuOlPbMJykDrN7qVnZmXTtOfU7okBLdJYoR82eVlAHyBPtiry3WP J+u6t5lXzDfeSkmdlb6zpr6haPDNIoCRs7PEW4si0aP7J2b7Q3KvRtB1TzHdSPFq2hfopAitFKl1 DcoT0KNxEbKw7UUj3wKxf89//JfT/wDMRB/xLNl2T/fj3F1na/8Ai5+H3vBtEm8q2oiubyfUk1GJ hLE1okCrG6GqEM7sTuK1oM6LKMh2Ajw+dvNYJYY0ZGfEO6k+8w+afKevzJLqU2qsIkVYoYY7WKME D4mpybdjU1P6sx8Ony4xUeH7XL1Grw5j6jP/AGKF/LsWI/MvRxYvK9r9aHpNOqpJTidmCs67eNcn rb/Ly4udNWg4fzMeG6vr7n0/fadY38SxXkCTxq3NVcVo1CtR70YjOSjMx5F7CUQebH9e/LzQtUtI oIUFg0Uvq+rCikkNQSCjVFWVdm7Hx6HJxaycDZ3aMumjIVybsPy78uWN7bXUSyE2Z5W0RKBEYHkG HBVb7W/WlcE9ZOQIPVMdLCJBHRk+YrkILVND0XVo0j1XT7bUI4zyjS6hjmVSe6iQNQ4qxTzb+UHl PzDHaIkK6V9Wdi7WMUUZeOTjzXiVKBiUWjlSR2xVGaV+WXlfTNcXWLdJDPEXNrCSiwwl+vprGqHp t8RPj9rfFUv/ADv/APJc6h/xkt/+Ty5seyv78fH7nW9rf4vL4feHz0vmzzCtotoL1hbogjVeKVCK vBRy48tl2650v5bHd1u8uNblEeHi2+DKLr84ddltbaFLeHkgBuy4PGV1NR8MZjovwhvGte22Ykez IAk2fJzpdsTIFAeaG8t+Yb/XvzK0C+vRGsq3MESrEvBQivUClT/N45LPhjj08gO4sNPqZZtTCUn1 BIgkjZCSA4KkqSrCopsRuDnJgvXpDqfkuw1CxubSa6vHS4QrxluJZUDEDi3puxU8WAYV75kQ1JiQ QBt5NE8AkCDe6B8keRBoPK8vZhc6o4ZA6FvTjiYqeIrTk1V3biPAAZPVarxNhtFhp9Pwbk3Jl2Yb lKd1bpc201u7OiTI0bPE7RSAOKEpIhVkbfZlNR2xVjGufl5p+q6Ne6dJe3kn1lP3ZuriW5jSRSHj f05GKni6A/qpiqG/Lr8t7Xyok97O4uNavV43MytI0aJyL+lF6pZuPI1J25HegxVkPmj/AJRnV/8A mCuP+TTZbg/vI+8Neb6D7i+SNM1rVNMLmxnMPqFWf4VapSvE/ED05HO0yYoz+oPC4tRPH9Jpkehf mfrulw3ocLeT3RWSKaQ8PSkAClqIF5fCBQVFCAfY4mXQQmR0pzcPamSAN+olil5eXV7dy3d3K01z OxeWVjUsx6nM2MREUOTr5zMyZSNkvtLOEfQXYq7FXYq7FXYq89/Pf/yX0/8AzEQf8SzZdk/349xd Z2v/AIufh975pzq3jnYqyr8rv/Jg6H/zED/iJzD7Q/uJe5z+zP8AGI/jo+rs457V2KuxV2KuxV2K uxVgf53/APkudQ/4yW//ACeXNj2V/fj4/c63tb/F5fD7w+Y86x412Ksj/Ln/AJTvQf8AmNh/4kMx db/cy9zm9nf38Pe+tc4x7d2KuxV2KuxV2KuxVLPNH/KM6v8A8wVx/wAmmy3B/eR94a830H3F8dZ3 D5+7FXYq+2M4J9EdirsVdirsVdirCfzg/Q3+C5f0x9Y+pevDy+qcPV5cvhp6nw08cz+zePxRw1dd XA7S4PBPHfDty5vB/wDkF3/a8/6dM6L/AAj+h9rzP+Cf7Z/sXf8AILv+15/06Y/4R/Q+1f8ABP8A bP8AYsh/L3/lXv8AjTSf0f8Apb67649D6x9W9LlxP2+HxU+WYus8fwpcXBVdLczQfl/Gjw8fF51T 6NzmHqXYq7FXYq7FXYq7FWH/AJtfoj/A97+lvrH1HnD6n1Th6tfVXjT1Ph69czezuLxhw1e/P3OD 2jweCeO+Hblz5vAf+QXf9rz/AKdM6T/CP6H2vMf4J/tn+xd/yC7/ALXn/Tpj/hH9D7V/wT/bP9in nkf/AJV3/jDR/qP6X+ufWovQ9f6t6XPltz4/FT5Zj6vx/ClxcFV5uVovy3jR4ePivrVPpLOWerdi rsVdirsVdirsVQOvfVv0HqP1vn9V+qzev6VPU9P025cOW3KnSuWYr4xXOwwyVwm+VPmv/kCv/fyf 9OGdT/hf+1/7J4//AAP/AG3/AGLv+QK/9/J/04Y/4X/tf+yX/A/9t/2Lv+QK/wDfyf8AThj/AIX/ ALX/ALJf8D/23/Yv/9k= + + + + + + uuid:ffd75fb3-c246-ec40-a3e6-d8cb85a6cc2f + xmp.did:FE7F117407206811BD35D1CCAD61FC5D + uuid:5B20892493BFDB11914A8590D31508C8 + proof:pdf + + uuid:c84f3d63-a3b0-1540-b436-63918709a69e + xmp.did:F87F117407206811A961E94A1D713520 + uuid:5B20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + converted + from application/pdf to <unknown> + + + saved + xmp.iid:CF7F11740720681191099C3B601C4548 + 2008-04-17T14:19:07+05:30 + Adobe Illustrator CS4 + + + / + + + + + converted + from application/pdf to <unknown> + + + converted + from application/pdf to <unknown> + + + saved + xmp.iid:0080117407206811BDDDFD38D0CF24DD + 2008-05-16T12:18:29-07:00 + Adobe Illustrator CS4 + + + / + + + + + converted + from application/vnd.adobe.illustrator to application/vnd.adobe.illustrator + + + saved + xmp.iid:F87F117407206811B628E3BF27C8C41B + 2008-05-22T12:59:33-07:00 + Adobe Illustrator CS4 + + + / + + + + + converted + from application/vnd.adobe.illustrator to application/vnd.adobe.illustrator + + + saved + xmp.iid:0BC3BD25102DDD1181B594070CEB88D9 + 2008-05-28T17:02:32-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:F87F117407206811BB1DBF8F242B6F84 + 2008-06-09T15:05:10-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:F97F117407206811BB1DBF8F242B6F84 + 2008-06-09T15:05:47-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:F77F117407206811ACAFB8DA80854E76 + 2008-06-11T14:30:01-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:FEE440664A3DDD11BD33D3EB8D3A1068 + 2008-06-18T22:22:44+07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:2F85BBCD703EDD11A8D1DFE8FDCD79D1 + 2008-06-19T19:30:09-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:676AE2A5723EDD11A6F1BABF7C5A7A51 + 2008-06-19T19:43:22-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:ABAA68A98142DD118730E3EA0327430E + 2008-06-25T13:40:55+07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:E6A2668C200711689FE8CB9EA85C5459 + 2008-06-26T05:51:38-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:0A91C12D6B48DD1194DA8463B7D22218 + 2008-07-02T12:17:25-07:00 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:F77F117407206811AFFDD853DED9F9CC + 2008-07-21T15:08:16+05:30 + Adobe Illustrator CS4 + + + / + + + + + saved + xmp.iid:5275D63B08206811AB08B3D97C297869 + 2008-10-22T03:12:28-07:00 + Adobe Illustrator CS4 + / + + + saved + xmp.iid:5375D63B08206811AB08B3D97C297869 + 2008-10-22T03:12:41-07:00 + Adobe Illustrator CS4 + / + + + saved + xmp.iid:5775D63B08206811AB08B3D97C297869 + 2008-10-22T03:16:57-07:00 + Adobe Illustrator CS4 + / + + + saved + xmp.iid:F87F117407206811A961E94A1D713520 + 2011-03-02T10:26:41+01:00 + Adobe Illustrator CS4 + / + + + saved + xmp.iid:FE7F117407206811BD35D1CCAD61FC5D + 2011-04-01T11:59:46+02:00 + Adobe Illustrator CS4 + / + + + + + + Basic CMYK + + + False + False + 1 + + 210.001652 + 296.999959 + Millimeters + + + + Black + PANTONE 285 C + + + + + + Grupo de muestras por defecto + 0 + + + + Blanco + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 0.000000 + + + Negro + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 100.000000 + + + PANTONE 285 C + SPOT + 100.000000 + CMYK + 89.000000 + 42.999996 + 0.000000 + 0.000000 + + + + + + Grises + 1 + + + + C=0 M=0 Y=0 K=100 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 100.000000 + + + + + + + + + Adobe PDF library 9.00 + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 20 0 R/TrimBox[0.0 0.0 595.28 841.89]/Type/Page>> endobj 8 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.275 841.89]/Type/Page>> endobj 9 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.275 841.89]/Type/Page>> endobj 10 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.275 841.89]/Type/Page>> endobj 11 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.275 841.89]/Type/Page>> endobj 12 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.275 841.89]/Type/Page>> endobj 13 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.275 841.89]/Type/Page>> endobj 14 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.275 841.89]/Type/Page>> endobj 15 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 595.28 841.89]/Type/Page>> endobj 29 0 obj <>stream +HdWK%ܿSpmk^аn$ oXJ/ھkoҬ_|}+՟ޣ6x|Ӟ}~?zۯ~dLc~)OXk Ago/gho3?>s5{|f{|20Ϛio ~>GԵǾ6U_vce؅, ۘLk>=ƍ;?q9Mom茶i=v8 u6r *qlO:Fd,YXŝbR3FqgհS3Sr_Y;ŬJ'åa_F5r`pvQNa UO۰ZYe '\U` 1CX1Y 8ȔmBQ͵'tc7 +iZ*XmApHarh,pzCfQU0#&`Y0=$ ԡ@^[+8 ɮhJϩy +=c6Aa'U҈OϘ0T0XuKhJ@ sijy + Ԙ1b 8fdg["QO+ZCgcR9Y52BJ)c@B XH'b|tB+Ԧϕh{?g0T7+>dRuurs)&ZS spD >渔M6+&''؃J?8] ē'k$p4>XzLьd cHkO[!؞UbI$X%,-"k1c Z(Js -'LTy#rk|MOvN=!Ars #&-D ip%!6:{Ԕ" 9; Λt7 +} N6ϘT!X/#2cjI bTq9UUG`Fjq,qE@\S}c+tlfhb{fH Ӏn %:1dnDb)12["-jCiGvΪ:rqlfm҂eZwH/" 8SP:/c-e&G6"vLqITb') ,[Qa~%\XĐu!?g&GU(RYP+6/)_PV=طM1y%^uB"TMܴy +,sX H? PTZ=BF~2q<dSuOѮd7vi+OM{QHC/v5/$JF5ッ+KABϣI˲Y\2R) eCʯIGƵ ?U<(~IDt.&j.+sB +{,4 "당4UU:i9`F4tT.4QE@ +d3 BJb/ECT(Q2t K5ШlK6j&uRe+@;;ɞGŚhOtʙ[rNqVPn<6~w22ؘԉ.F\NݭYĖM8ƛ IlP: [pGޫ $uR,` +^+( #yKX3й*м`dpQԕu;k18`k>/OydR.&<{NCLoAm7CTd vW#<i rKe^ÔC$A]p\$*/"8$=!ᑹ$N䰿?r‡>p<J)G5&׆%(O*7H +em&B5Ǿ:Rɡ"S>ԅB k^l@rTn{/;.$B(֖gK[G+Ǝ|[EN<r彴!ÅGj POeC.ItuޡfXsW *.QG/:J]H½nUT8u*=.zIu ?\{V~I 7XF(bgdp\C\e*]A׷0㚧uːP8kb\% MPlï^@SO0_\,u"H&A/T2k0^8{뫗y <^=.H4YՆ3IaD_՚{ꄋ񏡞b BEMƴeSedN&+p T-Ͳ(:>hζ*˼X'[H5L֝ ]y%32Fd֯{=5{Y^ڙg#m%Y蝟`E)׏,cg UMQM=EYUaˆ$6tCAz1n/QhfHI +z4`G(f{Et5C˭[Cj%&n:SzMBwMS`'j=HĉJiۖh e!sBUҦm lpM2/s)c=Gw͡fg|=& ,X=*ꤕkC67⵷?ռJ= Q5{7$+zD\W~_HgYRk4P8VN&~] +`e5KVhի6[kՅʽW}^@l,}&ipT35=кo$m%j *)VY5-9Ukj&T%^c: I@˘X\R$ʤ4P4($pRqCUS21d E3k{*~k$Q}nۦ(GZtBgV:"1lnX )ԷmZ, 4-90 !WOit Ty\N@QjtbBusF2V +lXہQXORmNHF\p=V |yd+tX8}œq|]sx:jCHJ ?* RfBUS;M~cbtS1swj$ ٷ@++QI lR+W5O-k"<}*h!Zj+Dj <d`M]?AejF/ޯei8#߲(p:,Z̕'_ͻn>N8b9VhT#/{’T:n{!nk8BGWOL Q\m'MisAHca>@vsRD2Ҋtk]ZazHMàhR6r2UIU/!u/-II`=4%_͍]u-9_L{i(wħ +tfFGv4/LG-“EK56,uZ;)z<1tgUYGkzfUBUDow=Xb_sż+/Zڗu~|Spe ?$ke@mzo~V_}ÆߺL%ZjU˓4=?Ҏ@5k>Ks@vDNϞAsAa@2 ZM,}5Y䂝+zĄ0"?ՂP /lq4X:׊6 "Z†@qYc쩁ϵYKy/_7y'Z DX7mT8Yk}rձR7hA?rǪ/<Y>3Ԃ1]k%VZJTw8߽S~:M{ KuXO|gѽR.},KA-Ekވ!E9DcE0byn@轗r  z.˶T?֝~'{xWm~Zߕ=w|N i.l\ ˭"Tʧr4ʟ ]Kfr4+Ҵ,I-D-yh3L/oaX[G% 8e>?צpw\d*(vMW'kC$``B', 9n_I->4"~~DSď+`]Oۺz!+ ?V( +|%5?aD_҈#ϣIi\Qa (k% +T3J!ޫR}7ngO#<c. Y^ |]0M؎lY*xaxB%\ +La,+]`D U1-̫(-{CPf3o|A9THY`)eB]uAr~hS:Wx}ȇ_{tJ2/J**p]Oii N'1ie&839)&?`Jb-y7mYz%-Uu/qj):i]C{[ҷmYWhBs#.y0q+0Аj?[e! סgM]-HY `H炠#泚^$^ V^cz>߮CntD@j%ki.M%13I3j@ jH4cL&{F]1zׅ) &M&RT*C!UVgtb9Y2`zo+:o/gEiG"PuiQP +_âs_V}TU=73+>v+`HdTՏOdٴwbK?{ɇq&I%ɔuqj9+/g/jK9Ud6MZ[63W*$d5e + P@ݤ7i!yXQBVz™#b9M9):Q_$E-'E,Ry9#.[9[/!{*Dm-wԼ2:4Vi۪~mHh0 -x,&l`GO(`ƍݝ=Z`-[>)@6@UUk! +*zQ^BZnĽb}1eZiKn>\2NJTĿɊ 4T@aR7P+zN!vSj>z䛥z-(PQY#ִF(I-U\I.ⷲQv]iVvUؖIk+^E jXcͼpbRmiaUkLhdc"FWsџ(ٺ~=߾mf ʋM{#)>W !V thf8Sx"]<bkIAl`$b݆ګDy m j7r[ 7O[%c#9ЍV{ +"m!s> endobj 30 0 obj [/View/Design] endobj 31 0 obj <>>> endobj 19 0 obj <> endobj 18 0 obj [/Separation/PANTONE#20285#20C 22 0 R<>] endobj 22 0 obj [/ICCBased 32 0 R] endobj 32 0 obj <>stream +HwPHP%BׄzJ#қQ$&  TAQAb;p{޹ly$u V 'k8{x"K^xssc> 68*U >^OQPPES%`( 7i)@c&`J)5SXN4X!}=HGPPE1 @(>X(7Rόh*" ̐rX V$OSKȿiP)xLM}п) DQP,)ޤ飽F 1Go1 2V0E3CQ-A*x5ah,CDrsK@xy;'pPG@ N:*3DDMŰ9Rҥ2) Y[:9PXj. \њ:[tn }MtMUͰB|Vk ԖɎv8rsvtYw]w[w:be + 8-$ Q + +3 p#FFI*.$'a4qrA2S +_LFEWfTVFܦy EїŶKťˇL_uvUԫIUX[UZ?p{a.=M͡-i~7u#m.s|tީ/3,< a?-[ZYe⿚V޿tc_sy8}tD+7}XZ]: H =8TdaGaax+b;ǞWoD3R^Y+Ppز]B) ͎ސ}y,wrg& Q\SPPUa +:-dF&!~f.V&6D[WwO4|Ҁ]AoBv˜Ñ2$H3Qaѩ1ػq=S gIsF)ɩ{\9\!yyw + ...ԒJp_UfstfcHj5w˶6\{J͏[&?o|$ių__@%;;}=M/_}=Cc =↋z3/c<~_VfiXy/*򃴘t塟 WkNa[e;wvWk"0&HF}#c%fwt9äa~rӜ,W3w&3/oD;RIU;Sp(FYlQWZ2US/#Bvaj䲱A'-q +‚bRrJj:^CF[Vk ?M~S[KL52326&(ʚ[pXBAև6[v*xY}|U|#BΆ憕Fz#,EbETM#f&kL~2Μ!e[u=cJ!TEK!Y+K㥛+諆|޸qyDV5{-۝ 3wWiol.j`R+c':Oݞݱ{*u]_gӰзY*ƞ2N3IƤŔtL쵹W_>-}c1}_\+k[^~AM 2S4Nt! LLߘA,,-lq0)ɹxʕmM띀GQy&d QAv ޒRtR 2Ih+YQ]̐\%6N'?P䨌UaTW}Va)E5o#\юqU$?0lC4LMiL 7YX&Zy[ٜ嵣[sxXTFty<ټS>ç}KrN]CC JD(D4<%1>.&|:JNҥ1C3`,l\y|ջ?لZީ`KBJhAUkozɻ~㓨~w~[\*~<~x}'~lz~b~hȬ~W~&v~Z(<a}& + },ğ}D^}u}uJ}iY~JP<~Z X|:ܠ|Jl|gR|U|t}BY"}<}狡j~\{|`{sS{Ϧ||Wr|WXh}<}N}3{=iZ{Im{f{i{줠q|CW|Z0iʖ@Q8UY7 8q ڹȡ<񘻂m ڡiZPݗu6b>l6 ` ڶחk%聑9h1 +P%|~6Z ~ źíςP~Zg{ө=O96~k zĞՑƂjd~26fဨOL 6^"~ l|`|G|z|}`||e63}BL0.}0~ ~i oC%!'6{{d+5Kp1DݐFþ_<*wz.c=GKG%.1dDŽ͏zV_ԖՊ=y9ݑ +b@~Jg +1uݎQ Y\wQaV +^J=Ȑ1ɹpȮڣ.gv`HIDžD1Tꂤ2ΣqgRòʉ"u燩_̆C?Iaښq1ăЋdeTBΌm̈ius8_' ?I&1\-UZJ؅͌_ ɉԼtaLw^ݬ5H_1ؚ׀ɜt{ͳju{{y {r|X\|Dʎ }_+KX~ 2jƸ>lO32qP[:BDt+ց:7šPel:w*o,|p'ZoӇD"z,+ x얡Ø딧[o!lYÍ(C,pf-sk`񥥬HRtb9ҐޙpnXnCy[,񇄿ט_ϕʫ݁m-XKOC Ȕ",Ð,̾n4ĔѮBl?7WB։P,Ƈ'1ӽpN;}odskW\lB ; XD6Q)B%ռ5ط-'G9+Sn͐w}``AHʦl:t<=Jm|~^%5 Vl)b=^"8y=ϛ-e8m@4L (=BHEF&?hӉUH%RŇV}Y?Dqx`$ Nɜ(`ȭ|mK\` +z!3B6Aw.Q+ +)A <<%r'OҼA1LOzH̑SX*4?9;fn#4r@`8Jz!*< nKLI.*?{?͏gYBVmQ@Yj#a#UY/<7Q};䌑OOyBnD+{%d/If۪Zf;Eh\PzKTmB#gAd> L{ &*w=K@bAUtoZgCs*-,CRPLTw@n0n2b))|9xGx烈Σ./0|FOy^_))<^[[A1RDQ]mMk>'jƫ. wB/^,#*ZH_cziMvnE'}@z \OK# %h6܂5,unpL_sT,y8G/Av(J9)%@X^9hx*˯i%cAR5c>0M~ݜJz;L*3M~h jYlGRt%b9| ofȣYI +qUˢ6b1|<Є.%DbI8Awg;r,)k +J|1|ݥq$fHBK kDd` ~sGu 7r^ jNHk) l +a[w?x|k2$/^c*U,8jð 2>J8W1^A #sޒ ctprF7o01 ЄkUy)rՂ9p-^OvWRwBdّw*&0y|΢3bi9B4 wׄo*sL䰦DӘv {.&d {X C}`Dz[mIS.80A/ϕb`=U0(pC3$喺2Xl"7%jT\ SLK|"ho);w[^ݦ/Ic~6P/PpO;?ZE?NWm8& #XCGvl'ze {p}p5 ^WP](j"X+0"")3L&d@@RDiF,u)[ z/.8h|Xo71<_h}C(Nͷ0 زnULlêՆ =Db啌. h~I85ݙ6m3lg%'Jp<5{Edjh[JUv[AHeMkkHϖ[ib;QzU ,0n Sy:wQerG&s!+rc<wr0b "4O' i҄ڀ_`A ~>Kv9ϿwBϝC<zi'xzr'Gi?x+KY)f3"" '\U +cb]W*v_13^,xφCkeVtCfCsYڗt}|"6Roԏq7m[A(1<}$~}n2Jh{7۶njv,JL@xQZJԅޥIvS䥳KeSCiXGGӝ#N[W qzmT>&%ymRF@c; +㗖NAmK#9'}i*Ny r~ +=!FY5i+ʧ<_D: oQ_S9f{q']_b@7-`iHEʓS,eDRrH=' g`hP "Z+b*XȨHe AS@F\Ⱥ\2' I bpa( +GCP(D%ғv༌!C]/J]SIhn\,|`]AI*M kkυ6Еw݉[#`xγu#CޗdJtϷ J,&q;GMΜQ[m9yG P$Yפң?!Jݷ9Mւf`kQe9T}W.0H +SϣW#75,$w;).Jv[XqHPVZdbO8E +L/o%TO%\*b[Fh\c8pJI=+z:ˬJQ Ō33|"#o=}YW[4(^<,QYߥ2K;z)}ЫSJ6wQ.~FAݭކIV|ZtTgE1ܛ(Ғ3|1.? .X\߲c.hbצXijyFVzSW~ BW*{v ЕuEkJ aIޚb~yjq AE"2p`VP>+%CZ=ny;xLMa7Y5G؟ήT'hkiv=`/Ɛ> SUD zeqWgtԊ#Da Q]Z+R=&eoϗ?߃K6yNJr_D6(߷ZN VǃDuXE&2qy'ޫM]4Wvm`c X^nVJ0fq) fW Dutтf ׶V6!º ܾaA (!C">~&xz4 ?(zԖ%ҟky:J0_gg>|WN-Qc&YxCΥVe2O2bS1LO|#i0{Y0aÊ֍o "633RzUIJ"J}øl溇cgLꧺҫwi_,Z\ifKtq;k\ Oj[\H#Rw\uZ3=Fqc*DjA|`yY)mD,6b^uSݑt[5۔Cd< ,\>G._cҝtғz]oDo iq:*USL:vv6)'ԺjFf>'+LG;>&otojCDyc-'9_骡lvSP +,p<T`?9Di5y-n)Z k" t'5AN+D :c]~奚Xv]a(:b+aiE.ޙ4Q>4JIm"}3]w)7I?-e&]uJ>%+E^ -g:yesYI_[-f󶜗\=)7c]^(ov`=M0;ȓMuƎɞFM9G_dlTQ9Oj|CV֥MdueO ļBq-]Gc;HSԀ:۴n}^Gz~}y-o?}O Zk|ld{J{={|Pt|3^&}%eF}-~ ,~zBz{zݏ:{PsT{ɋ7]#|@kFW|-} }ayHy1yztzDr{ F\2{{E{-|:|6,x +Vy#OyĆzpz~w[`zEb{\-{{>.xWxԙy'#yozZzEzᖥ-{zw³xŽsx{~xߴyLoyçYz7Dz-zyڊwίZxUgxLynVyYsyD?zFd-zP'ydMpxqQrׂtms*umWv@Ԅw''xۆ*yȆ{E_{G{lE{l| V|h@fO|'| +̈́|u+lTRjԂUӂW!@'(k& zUߺYUێۑۂg}͂iiTn?,i( ӂTZ#.|fMhxT?Hc8(ǀdˢu}*_{ɚgppSom>(L~ˡ6haȧ5ybRf ҇_S* (*L,*"K6LjeYfx/㽼 dh8 +U믢Ϊ}×} |=5>i8s]6p?[S>nCfjv p@*&}[Sti]c"8Nǯ J;IǶ ={.fYuetۊu8hɠĒ17IDid+^<ˆkJ$#uDTlUX?/WC> +1wpƢcTPW;Ƹ,[%8Iy'ۇߡTnysiu_z}8s}u®+_Q".ռ T4BgbNlsG(I{vE]xpᝮg97^us~S![l )njv)L\(]yC Ѣ)]_lߘ N/XEhCMVsatR90cZL@h:+9ڵ +m"M#lmU R=e#j -x,E2I YIU>VvaHE:W 5cIU3lH߃NEJCyx6.B+n&}3UhI5DnʻBd([I":p@<\=q*̵9APW݀B5 ָ+ke@ڤ,R2򓸒 P p'>Nf45a~=ٯdSk[W(5#i>Ѹ9@ϋܖc8 goa|В* up"0YL4,-e3ya#ꮯ;t*_Pz"׾j8Vd}/W̺E!UW-3?E}EuÚ+[ X]qHWY׷WH _W.)'k=WBueЏ'Ĉ%l*wImPᐬaCoB@#եs%^Re^cf=]P(~{$t moD,?\|u F|!YBvQϹ4/"/tgI)[99$6֫?ˆniڔuAOKE&@"'1aJ7ߔpϭ4OsW7r1лN6fTxL)O[8,!mrg(brjZiS ++u +60j)ɠ!{!PGePYϷ>MB:L64VA)ş̑-J1ޔ!H*q +eüܨqYMiwB5wy6=)ܟ-MQ]˃U*q[lrnDusou&qyvqsEawtIxu-zvx +|%tnxtpWxqyesQywtz~`v4zHmw{A-x{ zlyL@l΄YfnqpՌq‚BvBs\_jt2GvT.!wdx}S˜k?3l8`nYptr5^SsևpG=uS.@vexw/j kZm؉oshqLF]SrFt .Su<viY汲k*ldqnʛpr'p\srOF4sڐ?.[tquĆ!)hɳׯjVlh n:qp [qƚ1EsSY.bti{uÝhi鮐j53lmЬ[p*oSZq`mEare.]t,tRh3/_ivwwJxw*yxmzSySX1{ yA{z(|z +i~zuNev2twUxl{xGWyAz({l~ "|}s؍B(t֋uщvՈk!w҇7V"xą@y)zK+ {IrȘ{sӕtݓ~u䐅iv*U@w@xȉ)-y]PzfHr As֐nt'|u3hv=2T~w;?x)Hx\yt,q| r + s/{~tgu1Sv?[w)`x5xյ*qzbr-Ts8WztCguN'S%vL?w`)gwkLx%pKqŌrysfXuRu>v˝)Ow2w*ӂjlBsnyoeqPsY;t"uR whCu4u׋[vwwfd Ӊ?ԉpЁn(2kZPڐJ(G%J1319R*hS^k7z뵫^6v%}/P]4Q2{Mj[KtǺf$\Jː,IBzw?5IwEsB1`_>C[(m? #4~CH~`\=Z  2_?~ݡMfVe+“-pY8. +wï M^uHHG_2;'}vX.H\*e@Gȴ]#DI3|mRcY ִϴxFys[uг@mxP$"x2wEfF= 9W/ZHn^\gEX!M9X!-K)0p? '|_/$6؈^+QV ӕwcp+e VE2Bx~*3,9LF9@+v!CL)yIS\ұU;G(X6z)>)Z ܘBM=>߃CiR P\|w~$KKt͂jr>SmXA*3"9ŤczOp2;ӈwiQg-#bozVw +E)b!-qD)%q|kT [\7'ƥ .{yd=uͼ0X|yvy#zy^R [z "֔Oj +ORktڥRumUPŏ법*M.?$͆DriUv5Rc*Et=5OK5N֣rQjVJq{%U=WLu^U2k|T\q0}Ju|OԾsD{4?y4s)FGɉkŗN9l+Yzd\ݺFEPo|2K{&hsWq}-yJχ2e[C ϿDa又ԴyѪI{(f (lQ{xeA%gѲqË +YXS0ΞѡkM*TEݮ-*s8a75q!07mf7G=V-yP_ILv-tL^ ԥ66i/C B Sm(djaɢʷ&>˛hx-6:jT؝,++b3fr])Zbg6rAq=Gs[WjKfը9&3ͼJ}u%F&%Pt8O5z$7XI9y:Hyf#;Nw8M%>iixŰAm|H'5L׬P9RW瞪xMcJ9WS+aO$!wm36;gm}1ɴZ¥yrz=}U;/I;dQw;;Az!9D47zXXY%gΝF/9C\ОX)z2V<%IS_ɑceuځ|߷W5I١*zچ4 +aL´߄ףZ]E/*v5n+ $~+"xFZ^bNl-(yp s>`g!͢Vb|AzA}h>20xw!{mˏ6Ut͢g"oY3ALG>0_F7!^t?ށsf[YeK=>?3I0i>"m,DžAsKA4e˝4X\K]}>lL0kf"ki!/rΣe7pCXK3=͕ 04ǒ"bdTr'd6WJĖ}=Y0G"C%Sk2ig^zjQڪllEn47ãp)qs +xv!u|jw0q~]ҬrFQPs3DtL7$u)ǝv.Nw +y獲}iiƯyq]:MyPҧ!yDV,zD7ooz){_"{ x}~i@:\P[ŀWD + 7H)oC Bbh}+\ڇO䤤C75* 3t 𑑂)ɈMgQm[OzC_(7*/`ٔQ sgn[->.O$CԐj6КߎT*,Z:2҅FgZᦘNJvB&z6)*JRN؆gGf#Z'NɝB❔26ڙ*T+]i@RN5jGl2;5m/o"qCsUkw!}%]M~pR*qFr;s/u"v]x\wzm}] x|QܵexFȰ2y;Gy/ͦz9#Xqz5{ {S}:&~\˹:QwF<;/#,ٜB +N +\QmFt\;pUa0#Ah =ԉ\MQ:NFP@;V3q0 \;$B"R #u?U\QfF3X7;GC=0dq$^W; "hp:[oEP=Fa;?~0 a$Zۍ! cv^mO[롐PȯiFC;90$s+Uc 9͂lSfmhoojȆqYmpso3ZKtq%Bv*r(wCszriWqӮkIr`m=t qo*uLoqvgYrwaB7tx$(ux> +xw f}~h}k*}wzmK}moZ}WqP}As}n)+t:| wb{ ?d%g5i{рkŅlmVp +A$q䂭)[s; ^v$~czeےXh8jjlۋVo@p)r'ubp2dۜ/gBa}i1ikU2n1@;p%)qgt>a%d'f|;hbhkGATpm-?o )pύs3a`cpe{-h_gjTSm7?~o)pXv7s`c,$eeMzLgfj^YS7l#?n)oOrԶtEe3BuHg|vPi{w]l,gxmndRyps;zrA#/{sB~t(qmpdrq.sryu>tevuSQwvz;xwr#yw|xo {Fp{q{wsk{d4t|=Pv,|t;wm|$x^|5 n{D{m7 n΅$p]v.qbsuOtb:v0$Gw +y~kՑ~mnTo&ztpËar\NGsۈK:Iu+$}v xʁFjӜm+lOn8OsKo և_S`QH!5$Z X( +Ȭ@d_;Dr=N=i]wjEŎ~>l8(t1}Zt@ Rz_[}ig;QF*wkGjTK{O"Aဥ8hR$0t/%)':GNS@?QڕƟn;]*^|;OB8'd 1X̓*N 9܇ǝK+N}-Dm;$@_VsН |7߰w>/9f+9r{oG?nrŲ4^-2tЙɹ ~)"D)iqWS"9X|()aklX +xil&pI+I)$*b\@g^#`.QI{|̵`ج4m^*)yԸ*&H\7E$0M*BlICe+4{eT@+Y wgNS&!dWdH4v[caPBvW ]|^fM, L1XwNo±sa_Ո>%4`{w*RtpV[)(AfBx> qs@gO8j,`ֱ.$W<Owg7[^^t3x Ђ,Q(@ SC_CBӁ +Hi=1C w D})`7`/cxlS!>Hn հir´gK۪Od9jB ڝ_7\ys+k#i!VAHĤU4V S,?^^:I)՚RӁ?Ԡ,45UuY6*-!Ϊ%D04G=j(ycBnE5 WhD2%Ry!7Pת`W$\ILL4b l0"уl s~騺eRNXK&">Sv0#"t߂lyoCcb eTXgGi9l7+RntPpq +rzmKl`圷mNS;nFp@9gq+'so +t vK{l˝etg_ݚuSduF5v8wj*xROy isz}k!}uk|^S|RA|E|8_|*ؐf}}G G}`p~j]Q|)EK89*ʍ+N w-i]*#!PϔDtHg7ՐB*΍Ԇ3υ5N׃ځiĔ\>SPOŐDd7C*ьފƄ_h].e[@O֓ECʐ7w`*#֋/̆j˂+gϗģ[{/ OpLC{.7?ԕ*Mm4G acVxeJW g4>\i{1ɞk$Kn ovs{a k7UP?lIn=⟦o1qJ$_LrFtTvwf|`3s(TTsIt=su1Pv$n5wŖBx PNz}_j?zS颻{HS{1={o1{$}f|54%| + }h~^SJhHt<1$܀Yk +@$*m^RXG凎0$ߐčԋD ]†xTNbJRd?Kf5C2i)֦k^amoיXt'|T4j\I\k?mN5n)ܤ#prZ̞sܖMx;}oSIJqIUr?]s4t)uvvx{2b~S[2y8I.y?*y4ԣzQ)"zK{^{t}~RZHܫ! +>Ӧ4x* 'PRSH_>n42)2 ߙnkdRWHWx>tg4g#)mCUB 1ʂdi/R̔H$R>P/4YE=)6{Y> ɃńQ3G|>4 4N)|5 Ò  g_i"bbk1e|gmEhYgoRkRqGmw<so#bspy%pck9AemhInzSjpfGlr6Qo#s;q t#r u]wvu`zvĞcwiexxjhaxdjy]PmDy;{oUz>$,pgy 4vy3^%C`恨c:vfcei4qOk ;my$qo~x +t|ˬ\:e_.χbJudb.gՇxNjw:l$m sϪbZؘ]ߕ`ޓRscՐaf}Mit":;kΉ$m rMYƣg\؟i_OrZb_eٕlM3h9k $lm% r8MX\ 0_$@qVb0_*e,?Lh9js~%k⎰Rq⥧Xs![,^#p~ao^dLg90i4$kttqBn^:p2a܄qdqs g^tjR ׉_L.e#*oݩD)?]:Tiyo5o{s5Lt"r~DZr-r+ֽV9?^ȹ"̲kڱGwC`ʁ84$\5^ +e@6uY9r+&x $9wF]7 E ++E1UR9Vu'1Bf˼sN`UyRBTEX0W֔OeWTX{rZ%ѼEgog9Y.Ҳwh <ă7}Azt,7o\'f礗^3AͅDZ0 i/U]T+b@עM.X:jH,4e'f +k8Q' D.@0!=% V"ZDB] ܇>*|?]4 \< +VU:IyqJud+"H)*ӂE_grLqZd%O8VG‹o0q߼4^ȥ6 KH89+:rp{]\ѥhld '\sڠfuceFH>ļ9?MHJ7BdlvTGHUס0V,FZѐ?7GX +5Doæ)XH2w2 |kxيW[/~ѥf@F*-r7Uc=FSZ0%\y :Atn*3cIXa @tr5Tli9T+@AsKD6âkcAW|BN8ՐDCⴐZ6: 1(&*iCA-Ce2\];/_eJ"+>Jm꾒MGYNT{0ǂ>lB};M51QuÿKs 2~2»VĶN+T<|[ʛZE)FU +x2(-ǸCm@JjO +S+hC`d,Cx0iqeĦѲiq&gr#(KM7{fAb& VM y )JFH$RL&\d=e[>{T 1ՄL% Gו u]'BR^z%nD?}YAa+.ILâX$UU&$fXR" `S[dPsh'!;2  x)?'E8ȇDݩ s񙝞9;V&bY+1{4[O:y50nu˜sUebG + Jzajzjry]ЄڏbQlmE\8|+gҁQ6ǀqiߙ]PʃSD88+8Ài a5hׄS\lPEjD1+7сB.*倏G ~9~{ez]yYqt_M>b@ڔeV3[h%pjڒlpz%dNeX.gL*i?Vk3Km%o0qot|{acTnZW +oK/p?6-q2ÎsZ%tu(u KIxN`|paȓavUvJKw>Tx2Mx%]yuz + *{}`~}U~>Iyb~=~1^~%B"~!~% +e~g5_[T"ӅdHÍ#=T10%QI"  GEB^t.SzxH9 <{v1O-%P> Âȁ[^/RڌGG:<1, %.? ф/]$RXYGS|:@T|P5ߔ,||*|.|͎i}2~Y'TUJ?ЕKd5vՁ*W{J8kiWSI~܉?f3H5'7*voFIHlA g҂S;I?K4̌L*]}-SD"x Mxf4gRȘHN>Вk4ݐ*{pvTA] pi`L\B^9aY/#d#$SfO"it ,ldrR|eKfcB e8`g.ʢj#$7:lO%nP ӚrpvA}?JkmAsl8(ng.|o$qɚs ctcKy_}J(~r@臘s7t.Ju$v6w x!{0~Iy@|z,7[Iz.z$ {^;;{\|Q~!I&Y@7ՀC-ƚr$U͑"5H1?àU6Ӝ-9#`..UрHmE +?~ez6-9#ݕ!!Zyv_H(G?E6x-rj(#ߔ7b<^)S{apY,c\&fG`8rwhc_Ak,fKJmsi6Jo\lM:omezCo]d_gbispqek]hLmJ5jp5lqmrvMw +sgY_p0\q\}_rnbs\Y{l~o]{l`t{Zc|HMf|F5i#|Aj{Ts{1S9WW|[kU^YaGzeC4gbh؀ r~?RȔ'zYsMi]X`FcՈ-4Zfj ga +uq€ŚPTiyfX%h[ד@W_oFb̍4eJ Qgs ;q̙OSYx3W#gZV^1Era3d kf pfN_mR)w6VdfZ.=V5]❝Da\3fdL Vf Rp hX̋j\Cr2i;0sktmC|pdc͈ff%xihfkLjU\m~m,CooK/qhq!rtr ztGancoufqDe(hrSjsBmFuf..hߎ`j^ sV|Ymr\?^(_Nc >^e-h?j6 spX}q[o{s _._$t_bNMue`t9bnee_'VgHj 8l#?(m߈a&pwƁ_o~sadd\V3f”Gpi8+kEq(mZoD}v^ ra#ccUfFhc7jt([lZUnv|xxXKsy[dy^UzbE{weS5||h\#}k: ltoxtb2qud}bvfTwiDDxk4ym#{o}[q-bw+~Hq7korom]a/snRtpXCv.q3wtsh#xt{u~y|Fn\umov%_q2vQurw_Btx!3ubx#vyshxy}9|_zgl"l@m~^Do:~ePIp~BAr?~32s~.#it~wc}|~`xj`Hjl]mO:o=A*p˄02rBg#ZsuCv{wNhyij`[l\iN_n@|o2&q~#UrIt?z2\vgߚhi[kXMm?n1p3s#/q\.t*yiugghןZbjM lEo?m>1moz:"psy;uހX.h [RZ@^LBa={d.R$g]j mvs} af!}[cX}f6J~"h<~k-dmZwoW qPxzqyjdfzVlLWzmI{ol;|-q-|r}t u"zpw+sbwtUxuDHyGv :z +v,zw{x ;}y|nbt|a]u|T{v|GwV|:hx+|,qy|y} {}b~\~hls&`t SdtFũ9v~, wxIoqa:A ɥLB˖G1K+‡;z}6hz׽eGdW4ŵاqL[Ո4$>,.`&I,4uJj6*=v!PQ2o$L 4#g'*ͳQ7:E[fSX^ @!\jǐAh*2K#C`7a<8@@ +7MMB= |+ExI$**Ee6(1J؊`cXr g4BPhgMd{dQUq%Nh +t^6yGØEL9tI+阋ouB4MTX@: tpnؿ_ v#*:^G5jrm};aF?MT.ԋSK*k6S:aV/wiH~bS\Qe6dNvj~MqDĔ;uFaYV_2.gPjT ';ɫ+~iSlZIZ7?᱂(c+3zVˤ4KPuF=0Ay7޾ϳ#Ie.Ģ 2i3BD)N+.vZ Q1U9LBHH Q#fQd <*;1N͎03;y2Jr1+ȹ]K5ˣX_Y;nc3 +E]HHE^1 k0e~D*qSHG[]', +ۯY~:%S:*HK)O79 5>PfT]qVgb Wk}5u R*)B@) +f I /e#@ hAĻqj:uXܳ~?ӗ +%{wT58r,\wu11&ßWhgܯϩ6`&;Hk3^'nRHt q=6o|i"d Cb UkXK`l<|==20eK!vh&ڄJo> i'KM@_7 .W).JQS%}[16:=Rӫ|'JqK ғ\t_o~C׈!MR&+[R+"J 7m`7|;Gpr%2uMQq#=9*Ii0pnkJ@n0aޅ: Y_`6VZCb ’ZC,4?º{dYZ /IA|aDz:S-m^%" Qsk7K/|UX9u W^6⨂{xՔJ3| 3[%U1c_h^ﭫ։x-)_ f1/=ViYB{X9|&C |Qj~kտ?4$Hv)ht^&E|%(q(S%) ΙQUqXxjƌX Yno+rX,jW +Wɉ&\1[UtC:^o-5<0 ?è}"WC d$GM)[0E<7wћX-sY/,_:zECes$$]a -!=v{*Ŵ՞,^4_Np;|Jm +8.8he_7 l{V6q-T36psSɪ^E|'c I^J>7Ņf'\[;AI$3vʺݷ(; 62 +l:0XԦDBGh +k{F8M&L͌3=RLit/kAEPxmgsSo x*X3eAK.eA?EUrx7 ޠєKq"y$_-DIDd˞EdF7ߕoIȂEOr8ޫˁ D*hZUkVO@zpy=y| `. + z%T/)9a5d sR +LhDUx.7$6b|NЈ=_Jn0; r15'̈<9 hsu^2fx[ՈQLd$I/ m~^u]_@$YduIkPq^s`kzszoI:Xy֜ʒهxjQd +˷`3ꀺ93rÓvL ѳT6t>SO\F0.«,qXLURH_@DwK/C;&lcFCZ >Clgᡘɏ`obwdm+7(-+PvVOz;{iN_0׫0'r8Ǘ`-TGJ릃kǽ>d64[xK +[6}N0i&Z, \ْD_d^a"Ey6C"%WY%_'?MM൒pj |Txe[)@|I!$+<;%O))`)Dso7z/)%'vӝeQYFlXc D(lb# +0"lEq>Iה:IwD͙8椧N$YG)B0 D!|,5O.m"o{HCT֊$Tr04)?uu|糂ӛw@x^f*r|odp?-5.ߢ2g&O{DYE6NպyV Dʾ6ƞfѠ=cQI FS|!6EpRghr[(%ߠHФ/pXꏺθ0~k,+pc£LSGB‡U1囂xяkܷj 'tjPP7Z%lX_KeRՋ!JL# yUæ1 PTLӖ:xx9esލ#! + =X-ӽ=SԄ8AQђR!N 27t5o Ҏ׻g!IwJUwx1jSJ2|ըĬct_ޤt?mM- r'H!^W8ǯ:d7c{ R2k* {jfmwv7F;@ `Y؛E)W~~AN'%tou؅Fcߚ>8̔`PHQ@E$L!*adAȂDdJDp{T\gGRAj-:Zw^jxz>[zxW=asҐ;a;5̄%;jhF?zJuJ,yzp Qyasg>Hm7@Ve?5Po؏vPԂ%mVV +,{eTKcE*"Ð- S۴V +Qy޶982DL6EgF6BuKFq`گ^( c0Cqy@` %9# -P`{9{E7|PE,nP^L*_Xk>NAghЂ @[W{9h9R%\+Ni-Pd n(wÎU/TB3TA{n"s֤]};YHG Q!;E0OiB~j C 3+?i 7]0 + lM/ɰ^C 3Xf32{Y5*zќΆ{a'(4}SQϺЭ~*%׬7Oy(GF7X.ĺ⾍5Kʬ.A-ܯ ˌ){7OQe~;"3|A҇w-Av4.֌['tܐ٘uKi-&wFgQ vq~&Dfbka<xPv_ҷqxF@Fݔ z;} 8Dv=E N2-yԛ"LSxi/<=̴U4&_&]&혡:=98%EOC+?D#RxC#:>?qE G0a-ZJ$a\;nV~e? 1{.Jb]Dm?DI5.ӑ59zIc=C1cQ");Cs t<[%ڪLN&lYn^$c>P̟v)`F3h5 e]꾕GZMsZ`Ny$#EZ`5 +g A*A48Yqx!b4 x!0^ꙵrD#qiGac+ + XpN mŸo +,MX_hf_]M9"io l-M+~C~hm-iMgї;с=}F_Yk.W( +C%G[3e.ݸE7rW5Ⱦ|g_ʷ":A>QQWkqhhTK'j'>S vR\q2œs8&ޝ6>Dm6A6I:_Oj/iPp2N/o帀F` [!SVfUJC`B{86ur8r'ꡪW)2 ? + R 21>fWM2 eP7)!5+rg;S\-1~Zm)A`ؚ֛p龵 YXf-|Ny|Ke&y L7*-Oh+h& NzF9rbdYx΢+^o qT*`-̵xX6IzX6Q%%^a)@IxyI@Pps=Y᜕V-"Y*Uj~}'*o9`߷ IHȕQVG,/Y!!9)[S["z5"]b1<jqExuobFr4Lfٻ*:9}Ork58 ƹI $3 ?Dn{>Pg[LSQ;R4i\6>'f)!,r'^}tWI_ +@XNDsAa<*Gx1"?Ы͔Uuhdڰji\|i]8AT~$| +VפWR|5а) Püfay n xVG\wվk/96}_}^9$=-$>~Zjf-f?f#\ =2t솚w!mb¡֓qh-y5OqE6wLvkzoyFeh^ (":ee,j'| # GϘ+fSbyRV\:rL& iqf}GiMC-bJ{d)1&+JTL"8{+~G~M&`߇ FDwcni{ {M bP֋Azy4wV-wUN +ڵ\7K{y=jZ.Hfi*; ~t@5QX~y~|i%Gj#y6E9U_}iO=y0s%'q@8?ec?L +r_zM#}HkYIeךG#[9E}:a%#jj3n`\gnkE2֢I`v9#s/sYm]Ro겉[ [8|w㥊/2TUG+M{->ֻ Plmz[kIͺY} #< ʝc q"}LMC.͟KT"rz;cr>6V GP~ &`afyqnZ[{X' V- jv %N_b'({̔}hR~LH޸r= KZP,RFd~N 1[tJ)jKrE#PPt٤'6uf[&?5z0J ]Ì~J;{yYx&;eJ5~7cCٸ77F f 8a,2P>v\ݱ'#n[vTSmQu wMN` fR˿ "ngd9) 39/*@Vt]~W +Ĩ&~H}rR҇e4dXyRQ}plM}CWE-VXq)ItU҃wJt};] !XJxmЎ!;P/2E%XIE~dt + 3?[hl"MF]Wm0J|(a󽫐(CgËYe?tlXSMq ^+d[dri~\b>m=ȾAT.b8Ʃ%s?v1Ka?Iw6umZ{"P/9cM̀um+eNGPhc-Y:]y" +ehvu(SNw8{?);w9D !I$ZB"%HBG +˗7o2>a:@MğsfHEpR'DNAIm#8^I+am Dia$S3a<*쁓KdZ' &lٿ5:"sE1u1%|hl)!.Ly%8 ebNo:z%~G + Q-4.|J'HถĿ!I-<g!;ԂBi[4|?op~_ G_d LzMTƓ (RPPQӌҖӡMA}QJ&,ؖBŲVa\.]rwο #X!&,b.*/;_x#$U, Ւ+,*)=U.WSMP Qw0Tf!]ԛ\~`Pjj52 bjif`a!o)a%hmہȝΝ]\vw%~z]%Bq6"r b%K",]'+*Z()+PlΪhjhBx`3+ -FUDkW(3ynaOH *i {8⋖FjƘźERǘ|A"3tLH!6\L[J?dR̶}7zW>bc!VNQ x6ve{'+נjum?<46:6O̶<|N(kUDio@8j!Ȱf<if>5}:p\fX" +ZcVl1oKE>:<99]=|R2!u Nt%5Fv$yzs\RaRP6md G:+,7,Oӥ ^O>U~FP¶"kbU)RzPLl\|2@yUeXYD=Y#LAKO[ZCBw[o6qΠ0301qbj +3S3bP^2vG;N;i^l}C/7/ğ7@4P.H#bHȎ,nGĮǝuY'.:1_Dx<{>M8];!32++Zw75n +3nUugJwLܻwel~Kڌ՛c4>]o~&r >~WQώэ OhO:LExW>,'sV Ŭ+|Z]ڟۿ7|wO*O{?I&349BC1GYFIODSNK'B ð„Øi'XllېT N+;o.*",D!+$I)9#U/ȈɎUȣ,&kUj+/5uuKzN*l{iV[&{mo4n1jlUdb`@8\RJp ww{*z x3|~w4VgCaAH(((vljWE־Tהvɻm+aDג4cysar#Yg9r+!rJ.mrhmu"f՜!S؄kB܄XL.ӫu< V"#He1rB!S +75ډلe[q;)$LQ3ͯ-=7#yNGkJ&ʖp) +skLknԉ+&oY66S-O-;:E{{?CLJ>\=|'M~~o*k7϶ax.b㏹\[ǵKT( Opgo8{ޡkp5g7킣AiXL)d~K pێ;".Ĭڡ~h[S1}a{ 5g,pE20Vڣ Kv.3!GǺNNw~lݙ0Ϭ'A?GxW>㬂>}wIh‹J (#膠F%rg +.݉Gr͞ҺP*z IIRd [Ž8ո +r/21X(q/tA d0`oX)̋z~'G &$#SۅDyH#ӟ#'m4f ָ,a?҅%e҄SH;<095I(#bOyOגH);idi="jKl$w?k vZ9GncwjY{+)T8GWd's„ ls ζ Ӊc!Hʽ;#V9ROӈNӐi+BKh1z05R ͗z9yq7Ң!e ILjWmh C~8F?f!KtOu\"I1Kﯗ`B T[h2XP?czgSip62n)yGZQdEL ‰"^ 2jrBD8jܛ"y.;\h^R,)16LΝ>Ln9UH4{mKةn:@mD&GpF@6ki 񒤆R#[d4LZH,Ww FRaux\4S'@7* Nɩqɾ?OD^<=P1-cRx6$0?1QjżJ#tš=K[ⲴuؗN_e|K2wĄϴ=KoMDW$僬aL'|`u42Ub-^͠9 j*}0$=~_e `GbTJ]/KB&MS7WM1yrRBȃ)}yYVf.sD%C6qMЕtA + 埃b~`|x3d.h:]]yWTZ͹#~t:P9F鎁H1ե* _bն3_+KuVElSs{B,~/kXx,>pm#[xr_MD6wE),ZE m] NSSUCRaE~0B/lоAz*d#W)ZbV#-[('eUIj"xŝ#1 >lPArCOS)G)*e@VF ;ͳKׄ!CL+۸AݾNTDaPisKʾLRU-!,\cisWw->9cڜLB${bOkag.=gcEM1K8(&cHd&{vLaKfT|L(0g0\]9[05ڲX {}Yf#9:T\El7{jRL9>Eu{9BzO; 7,6 Ħ[v2:e3:lGA*`@G=ΊSi҃@l &|x)ZKm075f.Ӕr]iH8Q!8PIJީ(2 Tl)aV_3 'cVJS*Bt ~-> =l'ٰpClGKFZ(Vj/ IVʏ +Ӫ?|v X;ڜ{JGe!e?pJ*PrQZ$GWݨa^rYnev-'=isS53,S}"uȲd4Z>/7z~Y(m>?ɴ+w`sLک˶UnTP*;67`k%L:7uTtT~Xƚmp,Ts`.i塷-9t[9vݕ[JTIH_]Ș`ks:?O j#<:@$`5>R+PB$J< nt>7RMeB~,^H,lE@̈́=ewc">W܌Yp25,R-A׻?#W]%lۈCHI3dy +DF]W>q.1DS,([$s!%-bDt`?#škۢڝ/9LʬI1R2XhGPM y A+ݑӦ9jG{-,zMʯ"Inēya6E;k^9+,++[J*U'-. cxOV"_ASy*S89jp+KzpqӍE&7kqNo9ȅ/z0`cG7x rS8RH G Ǎ4?rNWb+"޾ve@.OgV2҅ 2aYl1'lѢ6!~%]ߠCшWm>z0k*Vj1I.HXBahB2(τ)RNҭdO]ADxE1?9*{Ef-enP9?ȉe,%~Y#L؅H_r@ ﮎvp_H "={^c-PD7A!_G҅s8GVO^Xd.}SxI3XP' ^)ϫwwTnJ +2xC%I#l6M5|cNc3`GHJ.m~v꒭?|粡[-ۢ֜?+?)Q pX`bRB*C.LE׺J>xhg{ >G=Xmcͥirv +#Pn4L \Y=Sw\rq3BE?մ&tqw`)v *t#U[}=^Ƴl:qluěmeD~DSU  oa"M2v6qٛö])({ AWGB4 23s5vW;dY!+7'$ָ( 6 ̞)3YgԾ9 TI:e6DžhuiZxPonc&/dq6.Yw֘i?(;ڤqT/E!Iq-A'@Omsg)Q\^[-XEsTiA+.ZfC T"T}`'l2BPʛ燛,\~"R8+dvsS ^>[DuoϮ嫰ŠqzG.[O91؄Xvp?ƉYnsNpy^ui%qN`&4!, 3R}HؓKE]yNǶRn..[c+I[*[3.Zp^>%l#@?}?ʱm-_.J ExiL ~ @)"!ׁ0 +jxcA.վD%'/Zk/DD()̽_:7^گi\TP9DMJ=b.}oۇlRnڰE'JzʸU5<6W]}n=RC, +qSڀ +]DsS%"Pr7as{hOm-(pB-~ M+((bD?C⑭(q\Y ,^yHH])Z&.&JVQű`*;OB~lz+P2A{.8؏,V&CzW<ԆVXN)6 Ea6 L |̊E7鐍8b9b(m}qb }PwC+mz:֦~"U^ZN 89 +b͗*`xUF:TvEs+U^N$Ʈx:f'#eJ*v<ܟ-$t){|!܉5Qݜ8`謮9:b6H`0gZ ,.3drbc'~]U0^ Aᖿ tt@qze;D'&VD?;> x %( mY-Fl].]"?ax{0ć$Lp[fϠqȚ!GHQsͨ!?HC׊L?a%.;IVc?48(cOUhHɋ"3D63 b*&!.x wu="Js*%E\a *Q[^+ꭈ 8$z>i>+$~3iV9xM9^DG.໲^wT4}nƇliлŒ0:qtm& V˽̐:/yqz+Y;Fd]şvfOFr=r^O0rM7M^Z\cWS)9t̐9۸V&I4 +y!W%C6֧ +bHݮL~B46YM-|5u Zwgғ( C!J!p*S@^_K^zYBdY*==T<Jω.i^_ߖK]SKt{8uM)Kv:C'ۍ\/!+ .y؏5!O$Yd:a{ Cg47˫SK4!YÁqjtlh{02-imfPqΤ74z*!B}\8\_{Q$v3Wgx+h;w{7vAu5#Pʆq$O[G5ۺKc!kvht#O"5%N[ +)w"֍) Ž3Sa_VUKTf+ǹ [xW]h 'Ӿ! +S_`~ gp_e_pj<q9qC, U}Ĉxr0ÄEcч>>Ŷ2%f;, Ga\0 oɇ&i#Ff +w'Z!E=`jz!D)3!bZqJF@d7 #!x2rmeKJQ-941Qy>:ՅR,` pF˛>OtlȖ(z{`+-RI^$q{8ɂV;zXI̅ERx,rс |Gd#w֦єAs 9*1S$\8B ->nƷo9XG,52Hi\A *iGHZ*X9WKД*7MK|~\}_Q8ukmcUsbN>źl}OJkSxHQ㨐J[{y *ұM,բuJZ5Z4z'nAd_w3l6pRBqb:Z뫒NTޑwT2*"΂ 5{bP!KL@͎Tˋ֟nh$hS`3ux~'o@6-s Ɛ-Q3 A %w )%17L*n!VM23-a95{$L~\|u;T/ +s"¶n\MTe@4WDc8CtN?t'fYhv;=7`x<2qkjUJ2gvu +Ta] /W1LQDoW5&rB~h.R n +sޅ"^=Jc\C +<,+ :3QdQO 2a"MHhjT%%b!ǐ&4٢>{#vگR!5fOGVKY/.htc]suPh+LJ#Pȟ*YCc-B:QO}zz>I4Ք m}HU o5}8}s"]$"T-u( TiJ2;PPg+YnP֣n4_+fdWSia@6U8jCQ<+삸alnWBo+p4u@}Vf\Cق~z㍠ĩǙ.䞤WbN#{~L<${c`gQ깪֢RdR:đk`7 T) "p?sd_~2QTӿ +CrRx+UGo>c#[443u0V;Z޲._mVuy8g]r^zL95JMapǧ DRy2n#c1?)ꬢ`r=|\y"Yٍ:q&d[{7KFmyT(1vH^!䌫|佀||+48-"SjEFLt彩ӌV4iISG:u44ds>@fў'??kfȵ`YYj^Ѱ2l؞.V +&n8s.Շu'1P^Gs<ڥSfdWZN=}Bΐ8\.އx'gyKplȱq`rTئ!tI:vF="x.3z3*|O" ~YxõxYlKx`F y*TyI#!z>{3 |*~##~n'IJ44+>*$=wkg_TH񜨃 >7%n4s+'$݆w=j*_-Sۡ'iH⛫>E+F4, \%a'vñjn^֥ޏS_H->]V4…,aAd%̅Z5 ,>&"viGB^\S@*H>K(5AD,&e%4uȯ&i蠰^"AxS+H3>om5E @,t&Ƃklwq#arVksWLtB v8Nx0z()|"~ljxPaudxVy'L«yBˤcz98{0}$(ՐC~N"PZlW7af~V1~Lɩ~B~9z30ui)g#lnwpr$ztKevQRxr=;z*|(~̞kǏ·mopЍqXy\sBHdu3Pw5=QyQ+q{k@j,]ln~Ō`ppxrrct{Pav=^xÅ,"{ i{jkݡm͝oșbvqѕ8c1sOv=dxR,zETilkUmFFoGuqXVb}syOu=iwA-$zTWiajSl箰nupas'BOJu]9=fw-~z3ÐhǕ;j#NlntmpcaZr7Nu&=Pw-yŒyk/zSmzo{qht{|CsJ`S}u(L}w 9~x'vK|whpyx]y*KOz惱9|2)}Ts-5tHufvGo^w\x)Jz<~9{*|rvGns6mt@uqnVw!\,xfJy9{+||ٸ(qФst<\umVmrvc[w^J^yG69z+|ɶq+rs1~ulvRZwmJx9zc+{τq`Brjs}tҪ +lvZwcIxr9z,, { s kjl吘n}pk\rX끑 [ಬd$ +QQ!""&$!." j@m<'uUWh0=$y^f]smb(Y_ImPtE"] `ZTحC/Xs^YG"jv a m Els'Kh!"K 0U E +cC3hBx4c܋ 4X50l8.,s^}bل!B2 +L0W/+jVǕ, Uydh\xd_TA[ꥦ<^eU&O'2@xu@e(֤C 68t{:@fgSCrsEVaL .hZ,@x2$i)zfB&GMtyJZ,€ -@V-߁ Oȅ<ԨT]1(o%zx"y. I0 +3bGhQʕ_D˶vpC($OɼB:ĖcqDU\G̅gعĕ΅b,p dv#"Y_)/Xj(yHb2sM"Pn_wᝂ4|6 3`vXl'>M ΃Y(%fnØ6c'`?$(}Fc몣H'K{К! +[ +qʹ`,Z=W0 WCy wF̯Iq.ydK$yMY>v].*g{'sA,.5=[he|YjnF(zFT1(M+pʦ5^09W/jO( WE1ƥ^g"\"Ʋ%fm"(Se|#o]MsA_d;o|TF ^Do IԮzH]a è֊%7WߨG{TČ7><;|J,'6ppXRTAošg{DUU((mOLRxG]wHWz\0=x93.ZF/WԴ'2Tt|&p-݄-tؾ1BoebL&!n֥}Vw&nG鸕ߧMmFi?$VV'e.=Mo1n ;Jjk0vu,t'5;e'HҼI8]Rq7sW.Y߁ݾnXcqwBj;m-M5wD_}^[*W~9gSx˳(e"1Sk#{Z'vW_४WȻ*` z9<);Uz {(ޤwZW;8B^r +3qBG'֓ZS- קmF| ^ưżCh& jnK*EQ򔶓RELUC64"v2*v?#$QJ#%u?}69M5U(0S.&j])$;"@ixĐU%ˤ7v&Mhq1zi*CUzcLzr)6_%0XUYvBWIOLb|{pPb8B(3WHPuq,?o45nVR}=iv\R=*ZW^!v PQsMGi; +%fGN7(<`=iIy|gO]DᣃG/Vى&gHmN%e^k-U b$>#Ww + +jY:`cɈx^04VATa[ z@0l %H #(ea,'$1!l#UAU+R빐֊"{#$f7h2!=&tl|VVf/゗h?\E<Q՜g +6@oEvUGyOn>:܄%ܒeQmmț4 lz[qjt?279jF4v}n*9ku[Rse+nQ8^.*SYKݱu_:l7+5ieTCLkdB!%ƙ%Ew3Iau`4F[L~v1U'Wf%|`!Zxµ߹K薿2Vu&:9Mޮ^QH >ʥ=OJ̃)&[ӱN-|mO8i| +Jsn})Ҋj֖s$}Se&МwQ?MsaDRjo> vI-|2q\nBzX;<J7D窶7Dʖ;rp-(4{?i +D<>\<2*Q.PAȞu-7xRx% Y!H[ ˉmjn15UgĒEh4(G!^vПi(l3<>$wBj1"S.7dmIMaM[ce㭁 +\h2dE:sjZ`n+VژEYh&X8f%jz®غ`ZB#i7) RSK;0}_.˪KR>2ދcxׂ,c9FieuPs )PgrF*V<0@ihglpיݣE9P(SEc JM6|#Te(,k\^k'P[݂";+H42ρoRBbf-SіtrzT\ ߋxGI,{2:1W[TqkYcgg4Ov}fQƸ/Iqv{؟SC AWiMɓRf@ +\DJ ٩GhL#ĚeQxTG6qN\ܮH ,o;m?o.g*D3K_Ši|~"ܕ湔$$W )r(E ±C C/4E0*ȏ≀x~i&hW!vfs`<u[)KZ)(=J&*QjzLM;{3i<!6y,\9Iaؖ?ۇ̹!e'ra]>sxϡf+F5q$s`QQ7&;TQ_S]-:ūjQP"2Mćv]]! 4|xLɍh[ºzΖbd^Stcۿ5au!+o}uRz!.1W1˸'lHz@NʆۊRx}{ѱt8qzQawV+ ߔ@So4ytf(ag <YL vϔ'[Z,g߯=MDl{ͿqS{SYmb<{A¦> ʜ"(I7EmEEw X_, պS|\@-P/ƚ+OJnž곹 $Dz_%ђ +"ԕgǗf Ni"TqŰ]Im_*kbk~$ 8A( +_5^D+}h@rt:U2 cKhf很|Mly0#._Dn7.x B0aDiJw qQ>Р fehP6U`VNLJ(LS'?? ##VRS_S-P4[C"Q?[s+5Ņ,/k%kox׍VlP`XTAzIȆ ?5zFs,l%Rx0IkCk_㉋TؕAI.>5^,\6%>tFJe h5Lgg\MiQ0LlF Iou;?Er1SJu(Kjx!(|$s%mIg-;n[UpvPmrXEte;"v1x(Ԉ{,"V}\rQu9f@wuZ핟vOwELy;zf1D{)G}#"Å ~hp|e^|Z96|Ozo}&D}:}1Ή~b)\~#`MpId܃sYNRD:ڊҁ(1)j^# o.hcՔX('NjDq_:2#;*N$KYnޒCcKXXAN4DD::2e*$ā-mMbÓ"X!MD(V:2b*Ń$OmpfbUWɐLMCC::2RR*уK%he#]wgqSqdiISl?Ao6-r.'v&zIyl |~gMdl\]nnR^p6I0br5?ftb6fv.bry '{m!uW}ftC\Bu2Rdv7Hטwm?x6z<.{'<}3"*~eأ{e[ {Q{H=|N?dd|6}y.݋~' ~"Me2<[́Q}6H@ +?R66ge/8(S #>dŻhQ(G ?(@6Ѝv/J(:7#8dZ9P͘Gщ6+/u). $4$NchYĕP^ӒYG? +E6鋙/)A$fǁ\Te/SlgJڧ{j#BzBm:9 p2KsP+6v$y )|[loSn*J_pBW9r0:=t|2~v+yP%;{ 4}[seR¨tJ_uB7pw:Bdx2Zz,+o{& }K!~[-JzRvztJ&zB'{:H|T2Ԓ},B}&~"9MZتNR1IB:^2,&"ZƆ@Q=IƟ}PA皂}:S3, ,ʌ +g'5#`ZKۋQIYAԙ:K_3;-G'{#cYZ QJIՋAʘቶ:J +36F-'gJ#܁Y觏CQs[ Iq>A˜K1:Oz3E-/'…#Ђ{O:g`ZCj ckblDf}~nimplyZsbo]Hur=5xu%P{w5dwkģfmio~l0qgl nsEYquGtv6_Am{b'ͦAS&/i?]&*E8lEcJ?Y`ұ O>, M"=]ч+||,>XN$chާ)?g%0'X,/7êgiZmPMP5 +TVBbSv#]HC\sB!.>-D=G4d>T7MW"+\K+ 6M!"ajru]BD*P2 6QO߉(mju5YPr^m{ +:6G7nBj\~>3LSb$:(ڨɱtbH͆{3_:@.8=38-Zʦ'pm39QU٬yk@Y"ileXn2ոG']X=ЛفoZ%B=<~~kG{,H}MRKÿ(FYOcK{~ŸgƟyrZ _$kkFGkYi]|>ǚ22NR!lu9U>G^HSyPYf7gt::~C|G71QƵW] [eS/՚p-{I|m2.8{qxD2#5CFڃ ݙ7 ,Ɂl}P4ʜq s=&TiMrV{N0E]\ ǐ_a_)Ɖ|+k/6䗃cMQ{4azfBߠoS$s =!z.X3OE7k*m/Lk6ggJë6U9 [^͡^idmCE)I٫qcbӺ x<4#\#BFB ;l%zC@I7iC=M i?Z"8-%d5!!ײWH[|t0*2yޝLMGdӰZ܇}!2,EE?κD\K Ǔag$ [F`t}|@_1Ur.Pqw]g3$-iq]?qd#A=0aglԥ:+S.giƧauďz@1G.~Aڎ=/85DR) +p}%_ua; a|Ib*gM¼1aif"jX-:<7, *1/2BoE~GvYky|P7CXTuaEF"%%pH"S@HN~{d-ET8N;@S>X|^a˜wB%FS(S*VFj{h{#MDI m8&Iac9hjNm#Nig?Yy_ ISb#hy M놛ԗB5D:Z @Z]:ǁ rPW@grg {Ak}U܍Lbl**nGn7&Fz0 +@r= |9PE`R$F7ًl㎝b3k9؅N1{Ḁhr3 )ݰ=It$[%$ @|A!lFܟSRN +7ZހE:FPppezTA6,څ>Vg>F=7jL+B: otDg}d#GنKo챢e2>wTF'a\RN8E>]K8za%2gt~XkJ5%DYTɒ,mc!?bʧc_#}XW)\Jh:>9`4"¾P͙2xȹD)fYI[?ɱfm^Oc}Aޓ)NXV@T$\Iw4h7Nlwr2y&8j,Q_jd6L+ +X=l2]fNJ63z8" `;^Җ#8p/&#)AadǛf1y{yDjg,欞@uw32yӉ=1ҟ8I[}7f^%T>za;ȼf$w/RciV^h\>Ej6wfgsVQґ8+=ݿ'X0jՅC.L ^Ļ@hA9 '+sTMaq>.>ά$+ A^K eКmzCu%IW2s؂Tꑕb/.gS<'KbUс:_{xg@(z|]pgE-<ֲoԗ3f+cm8Z= ""/e'?5;%7I..$G'{F3쫌DU_ &m.V\ G +{}t*>R+_XPX Z(0=^HY>.gpqi/F3 +DPCzO]9#Fﭹ.Y"~(_,d_pIAqbb8qQ K@P(( {*2_3 %yj [(T:XmUD=W|8&ƜIq E7OyG%TQOMo=2-жGy +9N~|P6k}"㌣KV].cef 5iBnUc%cf{ܠ|#7!y-E酾AWM 9_)} XZss +co;ki=5o b}d}K'KY,QE\ z|Jj3PomQu#MEOqd{JL|rh nZUc}0ط[6 e8"ORov3xG淩c!T.B1 +=5٢la8ɓ ]L9_1-S: K(o_e&Eu IyDjLSYPF?Ǧ P֯kB0/'"3Y+?`ГGx]//'~y̤&4z])%l^M YV]gy,gz;悚 +qc6o{hdJf&a5uݰ =*6nߘnM4: uaݯM->O4qTׯX+(YKnil3Kh m6@ >,l.+hhGf +8MqMUIPX\CdO&ȧ m-s耶RpSyk +zSebf*S&scԪ*h`Rw \ErEhM"\k4}%ӄFzt]"Qת\K35ҁI^GT(7Lf!Ƒ OO͓ɗ1I EQ-/;7g:COrћL]Ee>U֘꾑Eᶔmҕ[zWT265% C뺅& 2ȧvEIlBniv3 mKN*XG"%ʎIhqLQ}/aߨwK{ ٻd_$)=5-{#+L}RtE}l .>gYd82AD*mWkhnc6ZnqS!zсm))[|<+މFx?nE'kc8ul<ɫJpJ_lqC-tU; ME!Ht Ugz0^HQ4'U0|bgd{Q%XVdlL&h +|"y_PWi;`ctBMc5i:iSl/?l3})臞|B͓<̒SBa1>}X3i`Ţ @][x^!hsoߔʿn+oLOָTzC"ӳHqM s|2n5?/4}&k +R]i7Wsb1pKE:hxH.Y;_),T'nn˪wwU E.~:.^(^dӼ9Y;1u.Xt2Tg 56ۡ5͆US T,^${@ˤ)IyloL,&~3t.{71e $TJXܫdLP]u*~eqO՞'_#N=Bsq!$]'8h^jJ"ݯ>Av?c.Q/40tZ _&J) ؟DR7BIX=`bZ\@U"`o/<tiWDKfz24=HS )= =n%MLS3}|籧P-VlY.gS9j9+î?xǯ/nCdoqng#WPY]*OFaUf5)2L^|V1UګmQAMFK|nђ!޷:7:StlɠWsQ5UyH+5ucZY+]iPtCW5%9H^)[8̩jA'R MyK4xoGk[K*CPTE\Z[%L"o(3"W`nI}$s}U뉮bS{5b}*Ry$&W^0XOUFu6 :Q:QPM7 =P +;ZV@ c(5vCAa\lnhf@ QT=$ZkMS^bClE݁"j +[[o?3@VSoA\Ih(6k58IUj߁sCWsA~? P>dóq|>z#'Ƒ_ _/K_ ! i^ض"5v t|Ni%tDʛj72Nڮ֬|bXXkʯ-4?c>Zfawb4 +XT̗QUň* E/ٍ&Ftr +)lDnۚlA9JzmRa5~kM#(>%< w} eHBo'Ygohi:F*/k/S# -j^* x$|c'D(oK*Prc\iEQy*0'5QQ71=)܉BeyzAI`&)e.v))TQD2} I<>:;_Z˜D}OL*#x#.o!&o<_obUYՓScdCX>cD*,_e۰ޱc@1CS%m F +'eV[2έhr~{:V[)V +|_KſơYdfշj;ҕMŲٜ4gck-ifNu9è>͙GrPɦMm .۶|dK]&xcxqʄxda1qҗoy JM`tIa۩) 8و9%$eJC!r#QSz_4^;'` U`6YM-ԛb1h.Pa)d!9#\x8WA\x]ivYAe\0%1H[$+|>='J):s5qlXf_-P0h 5 3vp|gu|M͜П !gF Y+IO5 h Լ^n-v*他wtnj ZdޒY>+oNז:v}@ +u_] CGaN.>́[4$ٿ+7^Tl(YWj_2=2=.4Yc3mv! %knVv0J%kvD 7uriLM|[]霌BPqzm@bF>τZS +0Ɔ@%٢^. ֍7zlgDrۄ$(gTa3 c.Wq<$61? 6 @*v9dlZ9?Tի| 4 7O I ۺEIrOUHQMHC^7u"͆fGR xW'YcJ7HYS7!ycR,4˂Bw'ӵwgݫ!XD7cY0mō? +} +(}W,a%AfJ}e$BZ3Nc>sxG*þ%Ø!Sjf[V oG^1BtUy =?C͢T + ΢C!wL[ܓv:Җ ƿ0m2kI!r?]!zfG] o]e7t}5Q6C`%vUPiiSm1;\W8)*kY\>Ճ׊G1;&FBTBm@" *d!@E3I^Ll叱-ݐ$ GV)޲n07K{:Gt;#<(0z5-qB.$I:_T+IGWD?%30l8 jĿBq!$b: Ի8 %T+hpwZ/2Sa6D#tC7ěӆL1_~8enVpg<>p|2 XlX, 2P-^]?ZOk ݸ)|ȑ^F[js +iksδbS,pϵw!FB;ld1qþ޲;2M~zՀzKtrǐ@/ҍa*ka{@ŅbO +p`N<*:.0Q3r ^_&KZ .?Cԝqp(Pjq@$D,(D^De_PC>k\TuJtIј +!".b{lSfSqK՟Z Sh=@O#q]qoJ$e N*UZZu=8('^ݎ1Vf#'*#R"@1U*Ti!<`^}÷ ێt'nrS)9#)wjcj;=6KYw;%YR|.$3:VVտϤ(qbj{,PC7xs qK!,erl;+))s1k0v5 2D)"^Iy#i0'(ңfMg]gϵlhUgh)˼ȭzaC!t)'J?#d[`*ʱ,ͽv/wM)rj̭|.OX+prf6}YayR./T=JgМn&ڳMmxmIsc.ϊ+%`P2OB6jz.û#Z+7L\/ƝЩ:3xC<H0WP `䑭P9r?#щGhwT&a밫m.܁ӼD! AnPm% ?!K'uͤHrBf b\%x: KgǔMN2dE~7 +.$Bl/z Ya> У&o +F+@,CTצq{F7xVZ9.{LG}kݘ|,fSdH NԵJ/,y(f9*OMr-9njX7 aRK}I$:TW!7_W|7BT=;fı;ݭG-ɞLĬyԦB|q;⮡_M#^_)-G3YdS/Q WW :Հk-Q ՄݢP(c#IaI{Rqcrd?B¯3c~F(Rn)q!9CG$%1ѿIblS00Q+*б;&fhZˢ ( µ77 xR $GɄThC<'J-ɢ/yp6O?{4Zx6ɽΞowwkIC'J/ +}y'o!.v?V7,#εn*.mK.9,gUy#7lbm3cr xk=1f/X?AԁXOQ=aJB$$)3@dx/e,-ZhP:P:zgQ8~[5SY͆Td~ 9AhaRO +Zj_A~F^ %=mFh\}xs ;8~mͧ7m{frJ'wncG"CC7p'=E^f.ӸVG}f^YvM#օN 7g9xy1 s/z,"89>4y`Mb6#4 +'"7_τp;9*x ?bmd.C!i*06LX 6o^?#!0BEPniNe')߸Y[%[vҜqTcY3smކdf/+/#hDN^S +ߩa7 ެ*ɑ3 `*V$}ƷUQ5w nIJ ec WiW<MʏO$aN%\1%ΖN'cˈ::)~%rM:9!c9$N"K82}VAӼmV6.1NG_T+)萤2M54jql=%PVgbHҠѶӇE//Պe81#HVuWS8M >W+ʎli6ZDXYnTΚuTJ*)OL2n*qWlX$9ܾ϶('O}N*$c9 k6)ku FEj"X`v]Hq@RTX}.ʾ ]ol l͜ j Wm&^|BD&Zա#, ?q퍕^p felG;i Aos]7|ؖki=j',D;OjNRNֈs[D+̻QMpΰzݒޡ&-\5KOOBXlYԧ"8 u.LByƽ8ͭ ͯ=Oi.lQI1*TSrf*6i*G1္ҟ \ + 'KK1o9cX_rJ4nqup"a3ac/(jɎ3KȢiu?gdRB@cXl'F3mΕ$36=b :z!wEiՑn[;j~+7}*V4 g"(!vJդ&~}I+l>_v/#?Y +R}V./7+@^HR[`1i=r,~>`8  tf^gjSBD,Vvs}P+*Wq>RNMD0}na^;HZ6 o<.ZlѥtH`)xaNx,g(i2 s`n[]dx"cFp+~:/p +O官"k@8zG  M ̰LM$ ɳ uڞ}kqѳZ@FK#b?wWPrRtk%Ѯτo'Mew+_aZ_|5ol{RXSP}5ЭtCndyDt ˆ.W,SIWibrue)n)7Vx P3x\ +Wy K1aޚʲIiQ{/Y(bkK F^*?k-X_%ͪB:/3^i5|-Gt %!..H YCŠ;ʪh&4nؐ5{Ɔ(`]qCt]Tt͓LN2O{J>A4Ȝl 01hWK!ٵ^4|(K!!qRSWVSw?gZ\( RI~y ɭ{k2).(-%'#"|NZ5ͬ]jsypC +r[tdS웄H:ŕa+dnV0^l+`}aNۂE>rLJU~P)!!N\l[w^$ZqהB7gj"N?ņbo6E%t( +'/F7ܦTɯqG\Aq$Ab:"Oax_0j]AT,BKC +FC_.׻UUuy{˜f 鮹dzI0"/ğo!}Nϝx7LGIKQ4ӡ! 2 VW nŦn$);.)B;P~xM/pwF<NJյy~Or֭_ni-[oعk׷p{{E+M(p8 ̗4_-Η6pko[XYrtv + +S>O{*3;7ۂBX:~l kž(l +®Avx'aٹy{qiiyyv_?Z_",S Nxo\.)'W$T1]u0ʺ2ā%aHdڃ[qC[sxvm<&Wc}/eVǩ"zb.-mE K 4Kq=0̱/O`'n.mmenB6׷2H/f$LHϠ?]u4"@gj+5Zn**ihe5xs0=T6y[fd#a&"y^-|feaXxpl|(q26]  w[\&f 3];2n)[#`2T`%<:NoU += !-q~-EÎLy^;|8)arE rt監:;M~:j&+z(CI)'{Ïʺr + rtm6ZmsE!S 4uTNXOJmx@;fPV 2 &7<3_Rk\]")˃VЂi +a*jK'u> q"zb8}n?4Оd6X7Ku6 s!lv^؛_B>m +' pM |0#wP#;eTᩡ:]W񆑮$ڄ˓"GNv{IZwœ6G-ڸfL]LHG4&Y7B1}e'i;鵫vڙMם$Ʈ15j3{ }StdVDhVd\3n&,*Ř} j2Oޠ(RdM|#3皍v~z˻MzI7H;,r77SzF,ԗ&8A1ժչs8erXU՚"^i^r|vYURm{h.it3-KP^>_=]ɛ)UIUiB{>oJn1 !8؅d&4#S(1N> th!JV9.(9FU伉F$`)uн4| qSwMɻ椝S#['r1f#x4\rI:ұGe C |;__}`M>ĕHiAsG>Z34T tbMճ9uQ*P(1tBP-Nߕpe2_H҅a88y<7n B6`dsW.ghh5MzҭP(XZZ*NV +/ w{AnjP -<٧' tA3ur X7o)k+ygQX׳zf_Cat> CaG^3:le6ܗ1tYUSlC%XV2ppSƑ{;Ð?{;F]86ngZi锕LةӠ;lwE_3kim͹PEDDa;цZKoWQOP=V0}#3)f:p6[[a.4"N)]+߾x?x߶u#"%+ǑͲ3le@5wk%'. +K;9K?dtOOv|.@P"8(\B lF6oЉk~ݞ4Q33i߅Y!v\]O۞;|YNB;̪{!TvLn+1eEKzyy܌HoAm[׉m+8?W`W|SrIEi]deKtjKIFH}&l!g3|j_.\\ݩEV|q)²QobrCT~!C~\;H-<Gd@NG/vM?*%Bp͟Ӂ7 @0±)0"*=qa ! 5vS{yo0`vD!^lL~V(vPlCV҃QKSh&p$)C<:k.S'"B⽡ehl aCv4yO|}^c9yݎ2JrqRm̒ŬA"~\>N*ɉh_ށ?q +:*hm*췖V,EE&RbG@VgNMij4O#UP mux~ސ7H~|ٸцa8i{]^D`ԊtB.Ga$ +TJ-SiJY҉20\smݘṯK_pu$:ے;m4BP0_Q%1ܣɵdRE(&uS)=Z?Gwhnpv$; l֮rt{摹 ϛkՔI +U-) + +0t@e Lڻ;gAim7vtfӤI:}v66\x%QDEDAF"⁀EPE|_|ݎL[k 35سJ0R:ʋWwwgs噢ƌvm:WWZ{{w2gȁ6Ȕ%:{[4-Ւ1œ~Y~Ɉ4j&EW1s4z^Fg Pe>Tw;nrvkn+AUWE ɬԷ$JHW%uؙBֈix9Ic'Jj[?JAbo{$wzok>X2ŀXW (鬥*+%R(L[Z`(*RO,`6-Nvn^(fyfi #aR$zN-L rGK8ĐUM敨'KjAh>Tuw[\zܼV<Ѧ9w̴wvߏ. -nAMr1ʬ*2j 镪'.V{lƝuu[Dx u\t +>Lar4mdwxB/e1HrGC,D>5CݍK6Xo=3}ָ j7B;6ulU7b2^3dh`A!KA|;ٍVZW-_dܴZd#˨LV2;KQfb;"^vszJI&pSm > \>s/f|1zwa| }Te"&ZG'(srl"fGLY'@zm߿87f uמ} wvZ"(q.%.Շ̧6粚psfKK ^L?wWRu@#X3+-{''m @p<A@Z $PCAK "bZ ML%Nd;/UϺw]*?q'aTܩGi]D6}͌±6C aR:[a^% 2-q8iOFNvlϴ + \IEy'P}SQ{A nh )Cء1Q1Oۉ~[),Kl#/N\q|ܽwYQp@& (ad 8 w68 mh2ꐔ<$"iя}-1>?R_\׬ +;KN +%@3(@W Q9v.Iw-%b%>R4[lVɒƅ0u%.MP] c*a ++Ȧs2R*EqER#]и)nhm# (u#V]@T98+x9J:Onӱ}L۴v^vLݗYyeJxJH*yh('^$?5'J+5M4&ﲽ޼?>Uѫ%<+x&#Erp2U?A6EG5ɇ)]AEg䠢:D3ݯvmmߪc>zՠKU~»I&|"#I89K<n쏮DIPJ WQU1XӁ}x(2JjkPsٔnH<##Dę*BT ` Q?=CҝIkĈJjwGcL.O-uᯟ@/b2ZGRw+ :>QE{ =BYNYTh ڛԍ:M]|OguBogebT\x8jm,?79{ZB|ɰEDVY(bӄjV-3Q&KOv4]nmyrO/T*sƇF{;3bYᆛkC+P1 fwUp)TӥMt$3O)Jiu]*/[I1Lc<[_{lopr_Taf՞I5ި҇@`jk%ʲpasqT*lYW 3 ӭ3էCC3Rk5-%RIx +y\NOhRaQ Kck +YmS16t};??7X(n.gpwx+i+^ jQeGs9| RYC<2M3x&+*;9m؋gקCpȐ3BĩN, p4U/W^RKʠ.dHbCPJAo*PPz3ϺƴvmظOD}GRՠs$A")d ilM"CT>dAP<Ǡ7(z'(5_9q~N{|ؘ3Wxsf5FYׅ-PVbfcdsFWpq>D +A> 3eCC+?.6\49`ur9S/e +%d  ek R*DkS$(Oo=:Gb:PfjD4;-J$HS꓁ f#q .΀/b&$aIî㗰yŜ2B&v.ßI ⵢ td +F‘fk?@ G/vZW5"t'hG>m +MR3QMR5 Ţfj1G@ g|wM7.\[=|m]pʀY)@ 4V×Q$""A34= 1K{[h8s g1A>voA@~:GV端:ܝ纽<ǻÆ A)B$05Y|!@£V(k4-S+U-Vd$- +>L =^errib쀧hgɝHMP b}>&OfjTU VXJ6q$s+hn&@}@|пm^^?d0j?erv2 x^[c@9\QKxdf[skհ~dlCt;~|ryѱp'^#i[:*CT*˓4H3$ d5Qb2ͭ5:l`ɿ~P~cWuuʄJzJuVjIM +XRj8Fef:DdT!tHh  C7B EqdAGtiFEE&3ys ={\~_|-A韌vnŨgi6ͻ\pT-xJ1y2m! 3eLp?3$ f:M~|{SZ3լ^|r˶ulFnEMG+WmTH);^U'45#&+j.͑Y0`'ɕx/"'m@݀~󋶥㛛bgX+[[ {f#*\@F'_| "!<)L:1%+`J[b0,䂌P#n<݀h[e#NV11XZڅ +>dpFŃg8|q8"ChLDġD?$&%2HrR]WDik#DW:DFD#JZ&D`v'. l\b ~ 4C!<"0zC, ix8GpfZ2B=6B4frU>`405Ip*C  ހBB`} @ tZrh@ ye5nK;pH?8+qRTk^·悯 +>o +gQAâ)Ըx"dR<щ^ ![o` mz>E3TbRVԏD!}`/8\XCHh6g d\ >>$^J 9z[o`|Adw. raP p1$9O2bssfżV8m o ) +}*|4|\އ{!@{uy7 5~2r+Vaإ+29Mf%9SD5A#~ .']yQ̰7%P܎yQp#v`ޜ S@ncNP鼪[ pD[ZjtKGp'I +8T:]#_P G^/[9|D(艝(슛Po8jؽ z?!(OCr\>:tZ$ 5 eARQn_V4'=^@ѝ⎄6>8zCސ{r/ZCYR7o0 )>qHfSY46iX\ \y/N_7KouǏ]%&=W$x߬=-gIJF+ +$ixiG,>/Iߢn$Wt%;I?%<д'h.&T4QF*7OR˃PagXl=]J7^ +*>');\+'&Q^PwjW(䫕w-!mcʐ&uXM3vP -Zek:Wdqk:0ܑ'1n +3)(l+H--?^[ٔv!VM]@MU`&cZM2 > Tf;brLfWf`_Шex NY]@rYF*BM%NC}VW9PWLUk 7l f߃#~]pzwA}pH +UzN,VqDeUJ SS]Fo+We=nPu5B[6߻luE{Ӊ6'v7'6p7#$As^VTU +j5/(FnW5ٽ2v_ߠP BA~x Mu̵9x욣@v햠zLr[%~įS+TRZ%iZAmo7 }  DVNiܧ98`{<7/`~V;j1UuU>qEEDuQR7YlK[=#:vBu)g?64,!n4ЅW.q*/fו KKJD%ŃRAѨ4P.9k{C!43$2ݫs?&s:L|ocݝ$825>vU%]*l+ ʚ$dp 'B:0*RLH)ȸby]7p1p`)wpK3Ԇo@g\.W6[2z2p:@{ءחdk5;ኑJ7:J֓Hz=߻YO{*ya|I NIQs1YM;%uH_Lخ-ZSw"OٔV]vF*C* +[!rTt.1AEH"}HH/Ał\| ÅAVq.2@xLtͷ7[eӊg7*:OYLX #4'&o^=RC4d.wQ}YL6 7~+ҹOWf_neR',pFC@ +ɀ%!$*18BB?+h(Hq!ƙm=@{ZH:ȵmHӫ#e`nRVG2֚ kyE.8Apo<f+. c"NMB:GV0Ъp L3΂M r PpGO?'D!:(H +< 'Al!GaiڀTNR0˅;p`L$;4 ̓ +aqt +gx\NA,A}\DQ^ڀmɰG?NAoC|/lAOp .(@= ^fNw0;~niVVcmTtB`3u&H!0Nap0C=j"bYQa%TLƔXqzu'޴5SG%i { +3~bX_6 uM {BTe~ p Lu]2:yECffMXNI&/%r( 9ɪJ,3&N=c:/] 2X<Gs"/Wi`B巐o +]̡ +0nkQ4*y>0{6>1]Ξ$ކ_ zMx,xI#(YP\<<%n`l^QM # 륢U׺JETT*DE@!{O& ٌ7d(HW!kO==e|y}n"NGU#<衎E/Ԁgo_%gkQxw +<ňГOP!$KiIZ惄Z{x=t7qjJϩMϩapۗ·v ~p(ܱ9i)QE=7LeeazTB-z!av5PKr3N~sSYA5|VP:+(M3d2M d y#m]ql{Ii= A qD "0,ZK݌T@a-KT WΈK3›/ȗ"s@5 @vhoꣻz99h(\] ~$ρ#:h"ؔE7`s85()2@X-&"[ED1c Y7@xK8cO2o}ُT$ѱdD mH$2D-F-.@UH-yʌ~5)CO 3-5倹ŇwOVp9:\[%i%5 5,4F`P/Tes帒<)IUp +nRϜ>n`'_Gwߕm>csX@S=ڠmMҸZ![e,NH(!J%"Bݠ(z'۠dgO?L lg* sTu3۞71t@_ɮKw +¢1V$!S&C O˕B9\d43F2(hIylv(yb놩fMmG rzpD{եW#%$F ʄhGq"6[(3 + +ZEdt '}BM& +s@05v*ۏeNvVuc]7VrޯrZ2:_gi4Jh[TSZegubH,Ps Tyjg _Y;/61t~r5iI@70s5JLH#%c1mdNx[/M%nvė^Bnψԙ_XZO%kLY [{bUCۊy9˞z{GeġSqI:xfE 'RsuJv@P^잇.uضl諗ڭa:kX:X>j=v(N'z0 AA}XB>OAFѡ =; odwr|~l7@5@L, 5X޳u[ÚXT;6*'\^9_?1x-c7&A Xd+jߢ}&7Cp>F9$ְ%-^KXӓe_쭊8wā ί'OڇcN8ֽ֖u"laJVH 6AE +n zQ(8ūRRdU0{u_|^?ߙ9 |YK&GM1hĩx.<%|. !r^*۲iXNDЙ:2cY$}Z:"=@ B1@ h8`A2(^OsR+T3 wjoBG /TάYP:o]!xmJ۝7<ۅO`4?CA07P\ '#"GrA"H39;) aw*ر26҈'<". Cs0 1ޮqD?H5 +^ H+9]ŠJXX[ +x5M-$pNWcx9v~D8q%HBtRىF J`"l[DΕD0_ A`?8o-^p|@v'b;l +-kMvf@нDWq{~==@oB-܁I bRϊBb{6k( &,1 O0G4$ ,6փ@r# qa@RE z+yWN=x[O Θl>f~ +x͜c}X7tF/ lfAf>AI|=)lLʍ/hSjWk!CKhpg8x3r:vao 6@biަd 2+c|X)HZr6yt:QHdjc+[ܑ67{{ᵼn.y}\{Hׁy+(2 +B]d$i :n|>]*g Ox?@Gx&xKGZAg䔨Gݗ$.Zp jOcP[e8"'q!0“F13(\?/T+xuMyOWd+%iDGO%uR}@6$d)(,Mq_CXljLؠ!)+l@$OPP{FV"_*yӜfֱ.!ڐ6_ gLxZ r)$xK~fG>QS8UQ~~t 5vCXoq%x޸ZHBDhC/C +8fvn>y c0:qN|DOkQȸJqT#&)J*,S6+U uYu^"oTs?]!  P`J֞8RӸ'Qmf vS%^KON+jgֈ˳.j4Ɯ*A[nϼ +HiH h>_$[ s,/ݻjf*ǟ{ݶ6(:?( h9~3MmqTɒ yMjNyQUdvE3矒*(K*(I/NdhC"yFݵdVk.myx< r]Kl,6񹗳jBQ>Z)W\_p\\xLh¢ÅT|iP3fF-V]Yo]4~p>D4J1R[^̓H43Y*x?1 [ͯJ"Ն)a c3܌[81_&W[BUmRR*󹐒-J*p*s>,'A~vk 1r#f*H}Ruo٬qc5t +7O~銜Ҭ,n~RKn2nspb$!_5)JO%j2kyu:uF[Mv \hЊK1v\N?;22dnwA"wLiBL5$( G)(S^.e̓e{EhGnB,)- :_x&6OҸܼ<^rNI^BX^oTM bf b38'jHNJԇ^W]?{``ʍvnkYCӡgY_PaEh$,*&$61(x>WPί? " ?[#āxY<(HAv*Eۦ{v@`S;tn_~ͽ7[pDVu;")OL)̌.FTb'K K^1q AԐ./ Kq۶Ƿ! ⍁#;[H=TVf/?ޕ3 .'Gpê<&U5[ ^B$HO@mO7g{H{r|c )[ +{a92WףG̿2#&m'ҦVSOV lĈ/&m^ iT?(Q5V앑j I;qb6vLpvtwfİgRm_a+C-_w"=Iy1L!tAv_7ʒ4wH!}pg9cɬL+vP| wb'"o|IXǖDh}]CxT1/+\QcC'KG,h6 B=caՕM@nK~֞Hl 3ಋtЇ 7 taj *Y"뫒tcWr(7PM 47c@9dcH0ZA5Mmtzj@nL4!l2`΂h/+3>;֢%8$)x@a#? +zo\#mD *VuQG ]£8 JDV)DO[頯`Ɗ4 )Y'sR% ՍeQ{X?Bl- Y4b\B:)\@IvuT8 7  o=TC`Mk-P? +leqGn~)<6ZG!Dz<-,R.fLG˦ϤO7E"c` +wy^cP@{ `邗!FfTͳZ-P/گX:~ht2#N9}4{hilٲBY n#~"m_AYBA.XNs]_MkA(jG܋UQ˞!$!!H F{JD@QT8".ED {~@z_<A?z~YS>ňo^IϳA_=Q_[`nOFט1!̈ =>h2PC{b5l,vX.?BXoA ~_/ 2gjjNcg/vv<= 67m ;ulxm\3`NS.$36߄J 4"sQcufܰokȐoGȠow;~&\TH? @Psn y\}>[b10`w 2N"}>Ԉ>h88 ] *ǽG7 o}.BO i +}8M|7P"@0${߀iJcBo"܇h"pe@X<}tCX7: 7%3H|6)0vk ն PC˾C;I;,yϣ} tC^e +ßOpW)m?v>Df +`/lg79/q~չ6j=6v ȰES\{ߗ1N +@xDI'= ϧhjmM{V“77B-Sþs. 7Tlv,a\xH_t>;] +N1qTTCo בnÛWf6P OK;l0ھ-]=4灘+oU9kiff~%z"UOmQ_jCWa`yլ ̛pH~+\wHޭ +6DH"/ F];QU:#a6T1n+A)愸4⫸_ o^Y@v֏sL9;+f>W>Z>⏋Y8Ȫ$&\ǧjĬBU,/O/ʒKҥIe^%ůONbR$ȟ޼_A+ߗqyZ,Yr`̰T:4C)r u(U"IW+*TZyZ-=H1&2p52d.Tܪ +WZ=:}ݚZN`mڭ27aȤ9QD)/9^-JK%.PFA]ʨǚ sn:XDG9G˾G -m=w`isM>K\Oȸ,VxzOU"MR46!K)/ĺ[qBKبV5FKfboC,zX +5GMQM3t yoEyͺy8I*=\!e+WKv^([qe'ϋ-=^-)QvUI3w{D6 4Ag*]GKS~,WY^_yye@Zޛ/8^ ??flgУ8u*[ mtu걟ˁz:!𾜝SݠLIWgn.Hڳ1h Qյ,AuS7Kp{"[x}"k^!+E +B_E*kDg[?< s%&'1Zט(ҥպ(nWlH@w&XnjLa7$tSMzp;*jqLg[SmL`mל6VqPrתeFԭi\uBvHm;a_dd눤7hS^@!]FB?5GtZ]f;} +i,_L4Hӣ&*{cd7#shJJiP'' 2SABu7P 3tx`eۇ s8pI0iecM3bT _/ DžSlCi i?0q4Y 7vL{]*zNs{|>а"gܤb.4RW(XeS5b|'CT?dB1B ɔ^AG +-P2pnZ𞫂;@]2 qb "CakCx=pd;^ަ6B%܌Vr 8p`g*X5C +x恿 Bҁ< ;ppQ H׃jD-Y i.w`1l}o|PbiRXh.:ذj:ܬ5 !־@ ^7غv5Duy!md/Xvl%\lPBaԸ4D>- jgH@*%O/Rk#u2u"fyC 颍 R?F k@X +kB"GP"$ ``"I_迒'g)e U>Nj_3AqO6@0±-d 4{8V + cOST68O3h7{c%SOdQ8ndtрa ([ +dnxЮ[H,#]@5N l#Dc#Qa_̏K!u g6/= =5zϚcPb aXu&z͂$H%-rH7DzMD%3GaP!^t9 ?]*=;nC?N-Omx)k.^o,@ +"f|f`3sٗ4!I97)X#)wz0ecwINr;wމn +gעKEd?NI@,׀XFw RPKAYgD` 3 ؼf&b70x8ԟ-qNOM~Angy\sLL}2쉪Xڤ,7*5Gፊ6eVaPU +sG _EY6Rο<8?!AP)#Z\RmhnREY IHBI^ B ,bBBe()Th ǎZGPy~ssc'D~)JYL~rl?{B/rٓaoiIJ6~"0Qy3")=n$07?w?~kո?qHb"OG mvB$8!Kdy/Y7AڹK }'xP8[bK F^\kIR;xܝ`tML|Im#e큊%hrz7́O4_1]p48,r,ULor'v&UPvʕVJGP~7R0S1nͼfwOsQї3߬c\s`TN&e^!|$g]&-̲fFLoMD`&XGjsV-L@HhLt/%qr#cܳ"/'v/{߿bwJo)SR"9Rj=@eW1YJf/^d>䕱qy_p̛6`_n>EoIѵcŁ^CԄcIm +6ޒ*2KS pfbHT $M2kv\@ǽ/(GP̛@h<4A:fK79<؆|2#S~љ{MMhV2 +ATM$R K4#eEea=B#|hF= @[b̫t@41`ܯو[{XkƓztg۵_[H |eʀid,z)5\MaX0 B(8DE2=0 <05xǕh[&v->oQzfUc.LK:kaGUB…L(=/װr.S *ΐ 鲩X!{-V態Ah!f^ +Vֺ)3R+ h%伬tZ(+*rN$RlTDr@W%inpMִ}ɀ:-Uw7*+%1qH i'NU,JЦ(YXc +r/n 'gBy`zN^^E䮘W}#L:;8`kw[q]+Z,>wTԇ0DUƟ֔STe̘R1U/MJe0 [X:1CۙBӎ~Nsbh!pZG`/ǂ; Xp;>][{>hl?9bsѼSD%&"(gr O-&^KoDc1RL͉u… "̼ p +ƛ0`2Π#Ku݇<;o]<5%OL 5ŗرzUwJU%k8 Օ6(چzEWbLo CK1O5])LgG7ڕrPy L9kcc +bR"EI%X ++beYF9GP{Nإ! +x`Fu04>c n_Wy_^ ?"='$_PxľތȞ|RXEٞZP#ZP NԱg*ܬ:ưt&7apQ9>Ez;`~g<f/e,?ac6M19.`l?OoIA ymtכmos3k0;sOneOM}bv$~> ؞8mn O?1k3Y=tfq A! "Ŗ*J-(U[u8Z*@}Q^A {ʆ^>?繮9窺P#=3BMQGkTxGe`4KvI <4:JPq }-(fq;ٝ'׳rC빌.sK3 l/"t&B"t zgvأm&}^9v꒔AK`{|l(G<'ތ o#0GJуTiy:4N tk t) +"}7(wdøEDIr8f4rB<-q]ndlZl7up.?< J?<UcJlN>_bo֌7C&({(}n招|,!Z$/{!At[F +h[WAu7u_ <<C.bﰼ_`mjE(c! X#%,1<̄c@+61fL*plIÃ.RzA5e;-q].p/54!PN B):g9d +n!eF?sY2V%R)^|?eKzi`|,cKE=("!F )sʂؿOO0OƙKQF5qq4LL7b7}'v2A! n% 6`H6fڃZhgոFeyMKN}aϜ3!v%y0y 6UKc5PYVY!驟€tC@u(OKP̓$|H/d$ʜ*"{L7,4$ ? /E]ba0>_0ދ>ЛD=7QVpR_kRW PY@%dc!sDz+2n})] |\r;52,'ߑWla2nz[L8Vʂ0s57&7S_k~b?IíSKPY.q?ZrW@rG &VLG]S@U H,_ L!)l4kWi//j) _TMM'Y!փSKwnko%HVWɯD_U=R\V\TOV!W@60"w^]%V%dw?rKWk6g* -UIYrry̥ʤq5O4ʳIg&O'A9!aJU&22uc)kI}qj~I'/s-_H|)gYeC'gΩNVS%LmJ<ڝx,mL>94+?dA7TDd ;! ;$!!a % 1 "(zXF; +ZZEZXי~;ss:ֲP2(U^78k{SlTc܌BF˥ƣfg69N}lnԞNnPyreDcb>Z9+Ѫ9*z%-"KlEQEag ef%ܓI%{JoKv* G;v0]۲Hga`cZ^W)EW4V$˒G%Iq(JL/JA4ee% >/ԃ:nn\ 7Ԯ靗`XruxL8h-8O%&1=X=IݢȮЮA]TTy*=܆Z[ ```4@yl-qc\͸f݊ uQV9sHބ(Yv&=lࡢCu~>½}j>4>$Rj.`f ? Un%׷9Oໍs5`-zTXO2߷.E"y!?(F08KZo.xluA]'Lv~UA?T9h/p.}X Odyg[ /NZ/GP5ߍ=HnGU&#Իz3:FP\OawX~#ECH | SqC[DC,[_4 M 䥹i[E{3b.ۀ:Pw-*]$ˍPRW$X~X_ly8/W'K1fXa,c0Øa3NHD\[RnWV-77EW$EZsz>9AAEؠ01N`Q +V*@G*V3en5u!CS +4A9/pū*upQMݴ < \M\ f3M=imvG:S DŽq1 ~7'ku`ZhS|WRX30ׯu-1Ra^k>n”~aIW/]wGio#Q°aa,Pb,:R4@@ׂ.OѬ;g")IjW/X|vg i8#iiCzO _[ G-^;OZ gȯ`5`B 8Duр G-B>3i^$7RG1&{ =;a-!F c9J~ΘzƘy'զBJ H –}ƛ|6Yp5ol3yźdu9#~$֬}PsJUyjAՀHgOkѐo7B_K~ 6羿z곗1"e{3HL9p(繀}#hD#Ak27]4h4$ J_HIOVKlD~a Amv߿Q^{op|?zn/\ +p 7A<}j +[d$ /bO"cr,^h!7v'ҡG\t+~3ť[t[UaSqI8~A8qN3Ǟ 8^*\D Ә?=K5%xy_B7&Ѳ'2r3<ֽ隬7e.K!W_ng>:+>#`wo|H?ڤ?xR qn$C,da&כ`F +ؗGY n/j޹.brݹ4\qݏǔۣ*Dns &?*^+`Y +D-Br 7!CƘ%xL_ZOѕ\1|tZ2U!6!}F ++2 J/S6ZʋkIpޗ'=Gj)CQK>iWPmOKvV}5"q +!<Hu]@2Q yTG5%HwYV'3[K+V*l-͏snMv=;ݘې^įK+ ^WX3B_EqRZ|MV< S&HP$5hU r5bUL_T/Fj 9hwl08MD޻)̶yc =/]í.Wf)*2Ci%ÊS)J}z1uR1 й B봐Oyj,WC!7 WͱghZǪcTJYP-LaWdr+eKʜM =5aDX^&QZ>j Xܭ"kUk z[#uE՜T%Ꮅ8FզdvyQly<ǟaƒ-- )0eicHDPd˒Ȓ5"Eˡۂ{ntjNM^D9ny>kv=;32w KNnߖ|'bk(y'IF}|It{sd@2 +\TEJrkզRfAF%b(X}Y]v;/5#'09@HҮ-;[7]^;a$"!m"@Ake\- k2-*fevbYnj3]v$ydݖeoQpžaq۪a D1!{0 +/v#?E@2  + L8ѠOmPqU/);*](YgV'L.LtZ)Oy+cr+EsZks"d" EDe ڇa3HCr+J:3mj|ttmB. j}tWr2ļԊ(be]J6dE *>Y,(:/"> (O[g*NvptsM{#*ԵjKU0/9f='ECF +vjt[j-? cos[W{uexEiHppР~£РCc!Ae8#/HH}HIGH#ugAeBC,U;3&l:aײz8嫚y) lo m   ï :D;@C'@yi8E]ԬM9碹V™ b5fkN#Nm8pdgi/mZǼ]L.א  7"МU{E늱lrrb@-gOVuBu"/EMB.$^i]]-pn_.!v,_5&G_"7xYn?&=pW,k@R~s*.0#+{nxs]{ͅU<6c5C7V׿^i(AG+12?{׉ ̆wCH:J—8)$$%ٰ.uWoq_=l`%SKɗi| W niz,'Д4h#?(Py(@h5DZ C Y,=e6ګewdB;<5@?t & cDM'+-{Αzu~)Pp|d:Tٖob瘏%ec':7zCh?D |O  p\Bq~'%xo,GYM dxd>ț|Z9s _b6,ًuBD4"/ _Kˆ53ʂ;k\BD]9J W- Ж2ti" ea,0E~fŃT4j/"̯>/$;`(\Tҁ @)KQl"4bIz.K`UèrF4)LGțPѐMC Zˠg"DJh^T2 b]ɠR~}JA^N>{Oו y\g\ޔS]߃ }І#r(ފh*h?YOL&9wF5IFƄq[ӌqß})}=NaO1Ff2*АO +-dQg;O>iM0/d1L3ߘ6hhk49GܤW&aq#)A\~,"O?ŀfi+Qiü -c7{5^Zh>Wh>e=lf=ᵲFygX#a ֐m֠=g6QN7°2nncvUK#ǎf\r Q:JJEIqQ9w>6Cx[ :!op7R{0?@OoJDb|g& ? yF/}sޕ&/4MgاY_=37O `|EY;GN\`ѳL@ٴٔ_c.I^}/&wq|7m8azmnmA7,GP4d0c/V>gFu7g4o +2^{t*!pD\{ǣ8f"R-FX"r^e Q_x1iq|y9~,Ƭ)]'7A2W` +r SQ84k)O)$R׌&36e0Z`}12kyNX}4.Úwr=<t9͜8ó#L R @UրuE K&f4HXǧlcg؟q:D<Y~4ݳ3ǻ5κs Ăo}-@x59ܓآGܿ&"$`lOI71Ѷ'!͡#v>'.r-hxF#EGNEp0 +b4oz].x&S]0w=Yk Kw^_՟IxZf~"-ƪ;%a{WrcGbkK£)^}(NMѿxGTUNWU?"K,gï=H邿Sts<`l +7#+r2Ӓ =bH#q󓜚S.xb$&ا@_uB}`%#sT5DTaKQޥa/Y(d>WhU`uIO,xPpLmT/HuѤԩRByrY@i&HxT=A.R +s,"¯p`.I5(x!(%8ЯtX[}w>HݴUoK$ڶNq\2ӳT +,L Oi!~xhgjoÃ~mf2EiQ% + .LA_vmyWqTl|ZY6uNcev"4+M)*|Ły$"Ieb8#_f!e1xHs 9Vt'W*Jc[ s|ײvAlRWBaSvPrTK-%$Eq.gCӄwtp&BbS;H- +kHsTk3 GmvkYPF2) TQ̲V'8yGvyF5fa!D$$"0:e+Ց`WŎFQG1؎ MPA?>?y{,u^V"^X0ky5K?Nپ$bգn2fn-r̔)-ޔ+€)m3& ܤepqi_`/;i_"%^5GVJx ]:wewF@vQf/\ N.(I,0 +M{:] "Tl8K?`1Rͤ?iyĔR2 f6xccD3J3SK'˿?:/dܠR7&8"Ș#cuFGGP"l( p/>Px`iugI`ʝaQuAyp Fi瓄;ˤsYMe%O=/rU™ƲCC%VCy?8$ &%{g6BWj ̬VҦW[fWؓm&Tq[^nI\9nX[]m"J9فdyj`m{tHzgHy,@JBňi4YF5[&#su96Km5-샞t |R*Z-P=kZ +F4A#D<@> x;@B+ ڜ\Q/K55kMiO`h;,՝YVӬUrX#^/g~S:n޾dV +`u2$4t\!=# HJ@oUIU|0|^} Y}\jia2/35CG^Andd?d] 0!1nm~J ;PD8cU4HtYǰ|1,vO7rj>>@|#@M+h A;pG'p! C  Q| Sd&P(A̦%,%B (̇ro:*t@V3i1Q5(^,依ѽ=ඏVs;vzOv-j`=gut:D}v 9נė^r:0j Ց`LTd[֠|! +v篜>9"{!nNZ}+Vsw8$9.siM2kPPFhQK p BM:ɬO3Y?(smuu)>.uxW5znԻDg"b,G;נܓJwj4 'yhh@HW;N&p%uZ΀M6{/U{/T6y~*eMנ청W)8>T_~ta <=b5A޲/|duEds:u6/ٶhLoTЮEsЮISjר9kנ{e[}iԪѹ&E4%b M*&0%ޗ6qi18Q3xO %vM+"?PQXð}t%ӂZ 9M]kV!Q1 (FɃ:0v;-=Uoٚhݒ4hjS?al}rݘN߆Dp=p]n0]7Tj] -^(G`#c(8F@Lgʗ,1Doj{VٸPX棌t|5󅷒9L\rݔ'ѭ:>߽2nj\"JlBvX#`l8g*32jLܰ( Dv" [  !$$,!BXBk@,YYTbjN㌎mL7g゚=}3qZm-fm;`YfICfŽlݬ6X+|ǫɥ{,wT[j\.%\Otpǧ=f)턛%fWK[*&,f hSl 6e%p;ǔxr*|UF?c`_Fo Sp}:~9+nhGCmco%>Yj%ܖJ~XZ.fDǶO +FNy.Cn1ORv3[:sgᭌ-1&O,q -ԃ9||`UbYuRrfe#FJLBӀr[ 6$Nn;Gg7u6Mc Q̏j_uFYւ%Ϲo##ߩ0l`IW-*7NӜJ.!۽SPVTo-h AM|}Y!8 JjhQւ#}(@YZ5 zX.X+C֟"m鯠؟f:,VTo*hU"uPF) ++yrއr__W1r ,+A| yu4}K`N՞jk7Uǿ]rܚ\I^]*PT+EaUB-@ L1ҢXI +Y@.[Z#I\  n VjgL@+:P{dG2qNǦJ~M9۳V^WJRyp&L&n"HJKKI"r8ψcXZlVQ7(4<&`լ]ocM&ή.I\_Z[*+ʂRYAX- +%Sq<8K2O2'HkyxTz@a-_"hmVXvm7nkn$;}:G*WV#+%APAU=_a$q'yűǒAf͓c|Z2@g7 >mm!-x{Gќ+ov6K5|bui "W[Vrkbr 29KJΪ!Hkyvڃ{. w`pOs!Zi<-YtX(,f5r^"]3DxF_7xn]D\t"As +gmƷAkt5-U7V&+4qnNl0ڪ0@Hn=[$&[ALԾ@`QͿjP?ߋ20 4 5&_JSuPmQ;uWA?m/ 2g{ei{! =g(= O㻞"ֲބk47t!mPYCո#'<$ざ vy#ɻ#{:'N0㏙ ;$4s;D|% /l .! (ɕ*|K*[>'$J\<pW6b?Kr`)~.,7 +H =Xq@"FNEcH}A>P_e_W»rpf=L]NV1.vSfCPM+&{L֦^G\gj~7pXo\S F'q_>z ˰ '!5,k[dժ6 fXsY$KRUzE9tDue]g79FI.ﺎg@~=@T@p-O#{' n=&[98Uc+(y@Yz`1jp5[0IX|B}C~`(0@@e,c,@؀0˓x7} +g_'<{0=Q !,L!!LCA +X `B00r20`~əHH {lɢIdBee5aAFfGȏf'fg!Brд0-#;~ kJtt&D'|GTXM Ƀ@@)HdD!tzBdңajj5hʥEǨS;yOXDޤznA5%h!_Y!Tpn"u +H$T G"MOKbݯLo;鷶9tGGw~]t~-_IQm6Tz)dF)2hM)oFZ)y([F>> !crZ)Qodި0]ۙNߘWU.]uiSaZe Ӭ,g^*Fe3]* UU*{BFT6l"d#O +X(Й< rpVDx3]338i-m3mu'kI{B{۠=ŭr׸{Sn౦vId9YF, b) +YZ@/ѫ %;LJNӬq}l1x˴j]ϼVy==*=,2zYfqgmOe|r~_> ZPgLvǜ@9"j KBT2 ^o8xѣMl p20?piE@Yy)oY\]*Cbs a)8K/#a:)Λ]7/gE'۵B-(HloEf_yFK`YFoP 8UɺDSߥYϩ2/2G4cT1/k`ﻀ3El yL{ZF/lݗP/Lu]| ?߫"|KY9Z/Х!t g*a(;9~QЫ !Ri0ƶNʰ$;UgT*Ы4eʀ"^C$&sχ +7g!B[&5o{_PL@ˬO]*?P}ʍ [mx{MQ24ݥL,%",jy`an-7w0/8 oCxtHΛ$Ԛiϕ*}zT8C{/IM]Z?_[WkM%ĥ4gE1ǣ)-R9Y(4n@HLG4=ߟB8t8)`;OT`ȁJ _ HD}%LlU]\(/Kv.,t/Px"Rؗ'+. 2 +K'BӤҤ$?I~K3x>Apg?]h :3h}AWC1h-ʫ#-Ule]ҽIN +P_*ᔕgh)ifjG1T\ e! a~'ɌӅUHJjkvPbA۵Wi Vy8fp`ihj.4.uy]QsAy9[8l3ڙimf;' +w{lV{4lm"G7x?[7QwQL-b߁tw@GI"wCd>+yF_؅w$1zَqN=R=*ڕ6t {^Iߑ"ڍsų5xM{`1~#G Y@#GVkBL gxqCIVC,mGs좏"Km.lwQ5yzG! .V᳀B[;P>GXIǬ9 㫁1N%č51e}ŰoA~K+g-WZ^Y\j?3ڎ;@ft +݊qY6.9f N9}h7(@on@AgbםnwO{ 3?z?!D+fCw p.ݱW">|_ V>h]?nΏ'OO<;OqO7~(ù8w$kv +?</ӿKwEWa ,z V?r]Pnkfmq&dNmT[H$kJHN$)%6]S* Qb:޵;<;=ɠڛ / +z=FϠg:ڿhmO})4۞f[ +@+>6yME] ;` : `aZi!Nz#c{B׾Rzai# 4ۖ{|+@@@0 0-JQJJMfQm -d;IA-1c3GD`M &ZޘbŽDe9&x(@CihP)}W:1P>T +_QBt- # ]Ch1"g5 3&}H<7mE_8Yz}}V=>^*WJ5g=.f3t(wB;TP*AlG#z!"2F\Ğ^"b:@ 3an2)?2&̇@L4[$_,$gk?*nf"bx)Ic4K2sI6nō?_f<W12͛uNZI/dH厄H{4"֦d!g3z9wN3n_N8q MJ [ا*ۧ+?P~(aI Z=5];ji_nN ҎUu 4> vB9uB4xpïiucNMbݝ]Δ5N{Uo9eo:rn8p˹ +zU6rO? +]?}^:Z=$1x@=|3+XTo%or­tݡV\i钭q%_Z_*^Ż\;?wv7hd2/&'^i1ྯ3bܔ1ωP^Ĺ:{xn,uiV +)u/q?{n="fBw' 19@O?o3i ++tBf*]*G]DoVl-gi9E{Oz2(}3r|^GsDE^d Bg~P!JP b*] +r>ğS~:`VIDA|I0̟&̛{87Otطh\䠬4K`_i)bO6l!#c7~_ZrYhuT@]T8+Fy=h+@3+-SYm|MXn hd6@;-mtut޹MKeύc¥eP +90NĹxsr5bX"c+rYj.-LHf%&)fshС ChC>! ޣ7*hπs 8R p~tfrO3b#{/߽(N0Qd"yTIrTe҂ v#[nu6"h_A ͯZE^:\3U|8z<[=UJvfL=}?o0Aj\~%mKEŮ5ݲ8|Ӣ ZɵY(](Rܓ&FHfr.<4ΞעQ]QQ^[~ E EA@ A($*0ԡ uHGRTԨkDoA%vmhE6lI/pzY:Y^B~8/8:7vjDNEXvՆ,j i3?PzXoUa@A@+Gg'wŔA뉪t6 ̖];tZJ2ͫ&b "FᛢM6&H +W7ڭ;hw: +'gxe|E1$_A}@QC@I%PXjCdnFږYJ*UZQ\QEnhA&kKJd|7[y͊>[Ϣ˶Q[M/m= B)" y[j*jFg- iurM{ZlrIi4lȖoؼY۴Fӯ uwFzx6Zxnۦ.~̥f.̜^;2iîR6P[rdb666"AXXcOڪvΊ`M Kۤ<׽r=5_m5zpn믆s:3rlyo|jr߱hi: oڃ6@A~tN+x)yčҒ#>ʋ*nj.|EۍN0.Llt +W]w  ,PnuApFqgQw)0rVup<_L.@sCcP`,*=t>} +p&C rGq';?vX\!@6:(?aXxaDXOGb= 9}ƨн$z'NP =@9Q:{%U&O B])#ʄ&^o +P{|zg?X53ÞJ 0rb=H[dOC ӈ؃GCta?>p0i1 x;4GMs50c+5ZuxD +9/G3 exjrג{y[F΃:F^"7=mZ-!%!=c0F}G0<7@ṺORX5T +Pe3(W>pW ìVr Qu 9.Nk +U*!4+' aI BX#7vdE +({$,H$@ad ""h7 {uZ\?s{6؀[[?17 ^ S)f OX +!W&gӴpnS8BI=kWppaҷa>b#_o0T> OlZ 0mw-5p۲n*&nuV3L:`X}p5Yg5hyY$Y%@ɟА>b7\x|̓_p&),&15\ + W2%la'\ VOX'v8 rG9giI0=eaE;w3x-Ly`{z>|1xʑUV*Wf*\QOۿpz}.ޠިq'ox/v&pӶ6 ڤ?&: +\Á^#kIktbu{ eҺר V.36廅ӧդgiwVM޿5zg6o >ck~% ym0l8 aBאlۻ>Π38+HNTc՚89=`YohĪϪŪ7'蛻"S44G1 Bߛ'jeWd~{x -,*5`4d6n(`n]_f\m^͢6ò&զa ֕6_T.ĿP &2߉-ZL uSZc6Ӛ"dƖH%."׬&|SX%2"ͦ<Ƕ4]Iyvq6vE!olBY@up`2yD4#s} DMdBv] H- )MA[EDFMtSY)1V%Q6f.vAĠ}~ĸ}^m܈r#>s#Y<܉?0l)@:KO +vK.YORc7!i~8V 0cT%)J*s0߲0ZSkc#p97J>OQ-D(F~O!lY 4܈ ^:R*zjEr$,)Q,%$dZ'ZUe핢ݎ~B8 o`ro/Gy{y,>?:8/Aub pэ;ТƌРXLI_S%_W. ӋIi^LNαR%d[;0i$:&Ñƿw<@oӐB?d :ѾM M*shPaPr%T*3}t3*B |c,4[lJ[dfYK leԔ-))^L|4xx9b1{=\A58=Fchw` j{R;r6؏ #\˗_rGrP"TB;ZA +A]DTkydUnF:yAaF`,ę&姘%),rֱb[ANͼfNXq,4 +zq SLޮDT{Tǿᄂ-]$+]QbuTd I1:q&DBԔ.GTn6Rȥ23qZ^gw~}AX<݄I>IzK68]8M#7F HXjrv|u؆9!q㪝k!}8uMu\XT0gmP3IB?q)|jvIi^q@/R ")#uɜ-_%3(4y崤S6gڼnRb}`%M7L!IܓRH&ْFv;v1J,TaqQX+Y9A6/#H/R8ΰj Oy#"?ܖĊyu%^ğEqUtѷLrhͲw%:Jg t\=f$/=D!(рW =X'f1HMht%ѕB4}ZNW븁> X6| +MyZ9A4J[?]x&'B [EW`#][J+i7R骥-2#(tY^:D~heq9D C(<3c)4"q[[5t(qU mB"-B\R8.(kq^ьsh4^޸u&"NGD3=z#b' t;8mˉi1sѦZV\V%\PţYSY.4Z4XEU NY5VՁG*lIN؈BDz\O-p 7qu8 Y8M΋Wyp9YU ?3uP.*եBBA}FRnSwJZ[YZcp^s[!4ruQ⚫ZFg=&#u8P=bJՒ +8$[ݶKw˖u+i5M~>ŚEOJzmG^`<(B5+Of|"-xBC QTR-31zd LW=Y,dy8vŸfmOolҟM&`>Sbw]xq> Njv”aR4"e ֭;zF^(wZ4NJes9\O@c-:߮qϱXMt0CG*1٥)8+ij5ݡa-J[MjZqc7yFyy򯹆8@b/{`ÈW3zLc`԰ /GLM;t֪UқZFS11^SWkRsZ9^FNj׼j3n2Tcp[`\s0` m1CXp1d74JzZ[Ű#5(r4U*lUk>JPk5ϸMu~p9d ஍2m˺: L"i+Zfs%heꍖ(%Fkյ'Z?OQyrG rW<OQn][wنC蹚hA-}l;$$7 )ƆP}*Lg1HMtV '8eUfB^Bo %J ?rK Mb1PV2ւ>F hul&::GjɞECt%TmK]ӢeYS/m8ŕ4+|+-ȕX `/\E/ ^\~u3 `w霙DSL,:4E&].kF9 -Iؾz#j#j~~ws4ZYd q-iF׃78$ +Ty jwZ-"rYo)E֫ԄI-ݭ]Kllalaǿ¶[x5[B=/2tjHfz~ #l8  *Ť!EHސ3hg 432\~_o-:ou~QOYG{^lr ~p`Gܨ݆V:GH>2o<{A o{SA&x SjpJ6HLv +Ke'.~pq/F2 ?z'uO { cFQ4hJg$D@K,N탌Ði 9plAJH)}ҡy|e4uYs{Q~N}775}cuhOQ[7XDe,H9GNodAsU1W^?+*1w|G~9yQJO HAh(6VP,$] XE0 b `Ƃ &ƆDQss~.Iz6̼|pk@o -F\-0C*`p nd@Bg\5Dér+3Ы=+¡[8T܁CS/gޭyzfcB`3r> ; Nѫ=j{¡ޫu#ѽ1Nˠ4&˜ 3c)3P?7lzӘ9XJ +>t +>3uE%d!9<¦a+Vn>+Vles<=y@R[5czCc~#04Я6  +&+no-߯9㢳 Bà82ɨF6 +GQRThcQ]$ҦvP)k +BKߥIr]G{W[T}%ݥe!~<QvGmRjSn+{rx *qx,B"cP'|Z=Y}d{t{4߽X~L vU~GE{b.nÙGq9Zj/GTzAhCd ?zϓxS{̗]cbyce^ke;R9^,Bmf̷x^6&ϟ-6z$SL^h|idʴaoe}:;Üj$hLBv Q iBJs"EqՂB}0/7VMrbN휭KT,M{fN<{4-*KQIVMRMV=IV=%+G6.gX|[~1&@SeQR8 p@_n+i +g9*NjdHi+6J圹+\7M+@UA).+L5%'Wd8&Vd;ŗ繼Vu݆ Qem\k +7~( +& +? +/~^4fkW +tsKRcbU@~ NiȨ֯DrAb}]B]0.>VSG֔:UZ龺GHW=M<+{?#c6N6}琘jo4;5"yZ^DBĵⵖkDE6' #fCb՛V5h,o<京k+ w]FFm G;P ?N1v aP~p:!`AAxI >ׯw6vœn 3$t.%sJ 9@A.:ps.p\@! +S>{: }?.hg ̹5ћD|BNk=r|J YNM?*6;w7xȇxXܡtrw>r|N _,+n3\sy{8>Od ^tϠ7D:mWȼ骢,ɥJ>0?6zwmV%w/@kL`zØ|:SyULW%sg |An-.p5n*ªs=i?d/[VL_sG=`zљl +tSJzjzzqqmtuҵ}1.xep{+@şGɞc]0wD#nɸ)qCrTRH qYZKR&\Zq^9i3z葎ԋS5 G8 G}K [#~E#⏊<;zC"px\~͂>8-Ym9zpF[exK'm8݈cڝ8ampH{>ac=a-w_s ?E,E΄S:N81]1*pXWn]q@uW {tKw +;uWCwF-cxMl$x79^rrsSQ$pǢ{b +Nc>ї`~vkC߀ئofa~IBب$l*>ئE|:cn + 8=eƣ;ȀA7(#( ۃ25ȅ-A +*6 ZaQ\oh:6.iᨴpAZmxGgJd͆oKYT y}#`.V0TZ =#t Xl +53ԆYBG[h)B*5!5RkH*E!k.o +V4S,Xo|gT1y2~l檰+|1  OZ3UssĖRRiBY:9M9m->ua}kz {W/_UηjwHy<.)ɵC2TOMWN3K3*Ϛ_gCt5p=hM`Z8'c}:*P%"[XhK[kZ.I[L[tXv3-4{}ƞڞ\eOr5{d;t43aYQ5 (rD +XiݙV)73KpffeTg6-}ښ~Tfb}XP[ՖW~ǚ5딋{!}udXxjsDT5 +5x\pWNcr2l"#7You. dQdmU';k̎>qOcXcx6e<'T͚y<@65dsU£Dux~MOGN~тÓ fzR$.iyE>~VebfU[纨͹K㲟TqWڟ d=i! W"!x,K&!d2Kf^ [I`-1bR-7(*} c W 1UQWGy>'Tc8f$!TL%1nUwdmI82*!$3D{EX}Rs;ϳx}}?t{K\"rZEIK +ШP%&Ӈɍ4,%NCRhpJg Ja?y_Ā{%0HJ3%Xu.= v6!Sÿ*O~9NDgJcgw͑hHjm 5@[Zmm_Ա]SvNMiN^vޠ6y=M/Am wk +uIV1q.}|iWWo{z٣n6JwVW{uW}}_ImgN_jAn 6?mw7).)n|yĺSYE8l4b)!+D]j):8:=x_-#1,+4k_l2k/D/>y?jѽF}ǎ4|NȄ G~AT\jwUYG͝ QSW 5qW+A1>jh(5rN45p:,0Xr7|k_OC'~}lJg-RY3R\fVI%kAEr7Pw"-dqwP{pWmLt/ٽJ% +-(SՂ +YV?g>F/a,tRRwRI Ku6̞Zᱨ'ZfR^R@'b=sY&?Fۍg˰.<3Lg OTO[j f[ۥ +"7EeyIDz[#+ w|!FR탷Kg[B g>xИ1(ǁxQzGPom▭w*;_Uļ`O #?gďAxp1.^x$A8GH?O/ 9O ×>2(Si*iEv'ζ8cqFZBIL(-M&@btj4+x_c׹npddbv>[1'ޡԳ=7-8p{邋@*iD7nP[Ui\F3_yƁ hrB~ކ8=SGҞzAtUu_SuO3ZmM#rҧAnVG(U-0\&Dboꆷj8_9 @5n㟴8^^d4v,m3VBm6eĔbS:Ve +,Sƒ|MyVE8"%WDr#JW#вZy[K"ܐY㶅c\KiÕmkSt64պƭUhk/[(:T+Za+urӕceʶfj5GeY=LnCaan}n-q}#W|ջcx*k]eyEv aMY%6ƒlK%K,Yeٖd˒7XlcIěX%@lR 0YJ&K6 tMNҦtɤ.E7Iѹ9'͘8Lr{q(gaΆ48WQΏ.a >&%fiv;p~G8A/ >I~<>q8"MyJL*q`;(0^hA pPiGJ#lT36<)G1夠G1/V\Fo"_u*!sσ QH +ڟ'KqX4!)BB+յS{^Q(U "aa꘨C5+jS]UoC_IZ,n-Z,z zuC#I=lzӑ~ #5H6aHeJuUGW:;LDvjlSЦ)QkqtA("R+WrxC{1K̘cHj6,BҰ +g7lC̰ *D :t[6 V}@Է 1a"!U4U6Tzߐ՗SSv/y/wo' |!f [U9w\6s Bf=*LTM>6!q)-3 g|Y wWLAܒ w. *rDGQI+0`"f[m:mfہV-V52&4Yk+zzkՃbwzF洜;,v5yM nCܗ>٭Y:Dq.F93M"48:+qZ:^"ut~>*٧e֚3-5WU n-;2~Pݴxzh#t:zݷW"gυ_:<0q7 l|ꎋ-a5)3#7^W~ 7~"tޔW:*3K}VGCy8TOTK7]sK>24xǻw\^j4p4`kg}Bc}PPLH=eeW庺ݔ۲2 oSt&P$)=tNז&'xj7؆@>"T +acM{D:_J\;&)ij^ޗ'S7]ޖj2\>ϓ)"G~+)4uAԄVʂ%s1\p1a=*km˖lq[%DEGą%2ccs2p[pΒDl8k@uaEEd#"ۡFi%Q&v"fo)tȠ`w!a^)Ѯ΋"=ΎD\"+1zyDv iEHrWe}%}˂/{;QW ^ E\=jkgvř}c ;o9&J&:I^D"j{.ҭJ(MH.%%`grv +=Um)#Md+6%cؘFvry:qJŬd+5o6k g)b4INڕ 4(n!w|MlLoņt>Ex:]*uҩ9H&_h*7 9~c3L y7'i<Ԥ?IO :+^Ihn ds!-A03O/y:xiѐ稙9Y +o1N|J Gyi 〓"-'a)..Y@=E2 dHȔdA{6yz *1YZ4N(}?<3߹x!a[ }0iQ2D2dBD$!I"+∸ qEոh:UէֹvQTd?>|ys_.u?vID s l;9l)jfmS%Js6N#T<SCঢ়a /|̯_%aB b}M:pr)M!14' )Si>M2Oix+L>Nػ]ꅟlw>FdJ;8:`Pa19r&Ջq2q¿Jn@8x+M!i:n4xn|Ju# ,tQb bE~18 &?0(Ŏ{4G~6`j^Cs̙˧(F?1eƼ͌yrgֿuy]Yt +S%vY{}&zS-3nL>jgzn{]L螼Yߊ #Dٺ<83)J]Kh6̮U,+τj Җp;cu0>g0Øo4"-s,Tg6RW'(|s #7ua7!o_:񭏾%?E,8S)ip +̃W@]TE6>f+R5UY  /A]\& +>8%FTl,9P ^}1’IvD+V-_$v]WoXÈfx0҈8YprINvJbSh MdF,\Fm<{}-G9-XQ#N$|I ' melF7S'E`k\)\Eu2QVE܈Q{& G?ǟ_Y{Ӯj\\o*oFi_6kD5~U?WĿT++ -lx_ -hX\9ߔr}ޚc#\Mո*ZYm +p, JjU@JFke-eYZŁZX-,ݚ3 Jͯkv*hվuosގ+kpk*uoVVJ=WˬaZbEZhS5QETͷNHKmUŶ*y46Hsl*ŨYʹt[o\)^)C3,U$]DD[ 5\8?>1!Di3R)m@Iguj[^s:kíPMwiϫC1BC" ##"M Wf ]'4(P't-K6,&4>+>&uSlRON +ȤaRmm fK1D٦$'7 JZiH`x>%<%nwRVN9t‡949t#s_\{+5r(X`(Y'=,Ioa-5Q r):"VG6HS_G#;}18+})(Sϴ1M|h +J}bJ}n^!h(8`*>v46l+KM^_Vf(4+\}($k++U=2FV3݆u;njݦ}nz?̴ ^1u.9/PT ԟ:s6Bs*RN_9So8*huwߙםSTgbuY9uDfW7;wc̰^dz\ꝎԜ ;v4|4h6ُ+O +̯Fή`)_(JT{WںfkZ{"RӼl 5>FOUF+L#T`|EaR|)Ĩ +]A-h~jP wo5w;JMqz՝F 7+T\T-/?Znyh~;a6O +D:/Ӛ2Qa}xF <~'Dx'Fߟ;EYYz _ፀ'$]T0r9Y0܌Z͒"tJYƣ,'tW_//1Ƌj 5vًEg#Hc8 #F. E0Ѷ:țt/<]hq .WE%_́]_:ɦ gS'F ;눦Ȇc<8wʴWtE%3vQN׷y_>Ysnk^.x/ 8#aX#]^汇y\8aatVm橍8SeTYJg%_<wBuUfox' +(j°QN:48q~6|m2(YϷF+bߥ=tr!^2lq_k+}mP횭KWs-Pƾjfc6Fk)^e*1zS֚fj)WEz׼L"2n0AgrUZUP +jKl%9rVA{| UGۼhSR~Z=Xk}k$㓬0\QMvޫck*I$@ Wx&JEkZ7=uzڹ<6=;{lݺGgk}9M~oJ R:q(%!̥` fR@)L~#Ock>#cwWs'X<̱ ܰix!KXhqHbFRbǜąYI#f$LK0%Ƥ?c +c1q#"qc83?%0y +Gk+_g1k mYlf;1-5`RZlg1hvaĥĤ1 I'0(G"E4盈\C=9C>yw8f_ʑ#|Q<~|Jc@DA 0*`x *h@A Z "Dl=.֯C~ZѬ+CNΆF}^C6 eHuÂpJt.5_vhkī_%~G-d>1hN2 d@^S)L;16Uer܀Zs3N8*PS_6l擢h1_-w* bE7?O ~\d0Nj]fj챦kB5nuV-V3jvحTۚ`ab*mIl;!D;nݖ#+W8G"WYY.;W؄ZG.be94:8lrPln`p zǗD㼨u)%C9C1FZ>uH/_ky1ZZZԸ3as.DfwLn Z=^ +so{I&zAxe+o߾ )Pӱ#p>a9J*u( +W0\ Y؏p;x.Qt[n)i琶<NyI^0eiG^K`^@I +EAyE +ݎ +DFȊ6`Kl!3rHﻌ{>3dtNjt&#f鮦H& K!BVl=66ac9<߆x$]HWaCwcm|9NKX5| +UO>7Hm.>+LhT[Lb5؀MHM"%Q*LTO&<юe,MLC8ay`?8C cۘo .^w3mtb̞Л7A5+cY2KiX !*'vI&NMrØsg=?WsSr3N}qj"tAED7M%QH.) ƥqeǸֲk1.evegf^0O_>>>Oy&{"3;H׹>-bWIHo߮G8lDl~,Z]0^ӼV_GTw4K$ޓY%o Tfukmԁvuǎر;`VFQTOP\Oק#bQ{;q>/U7x'H\y~; +K4f_Y.eGh'n^? !ȼǎ` GE8Π3;9;G ՙt`|D8i8DO#](z8H(OPŽl$| ζ8L^0'-\Jbcu1~{ 9CvI?·:N4j~Ѡ_(/ +K9^eN1ט6 N)T쏿|uGGvG;K3tN/VDIӴ\'~OW}3T@%sX\8lM׻EW[e=A-9ݍ55^3u_-WKU6U,*1xBC + 3( 7)0OY XtǵEi5R?Um7f9>Gw#+L8زtpWrP*s->3PϫG>+{&x{*_}iOB}*w}35֯PA~ +U> w8[a )PA >[E+2\4.]!c૱ + +P`d͐PtE}a] +QW +^Q %"nDXAxA Zo&IUgrh=5c$6F{>=yo|B%4)ibvhbo3 Z1?&&_s9􂬦j0M1V)X)JHU|JR4Vkw2^ #R; ;7 i\4z$?{_  i}`OV?{^竏\7ުUzU>T3:xUXS;*"鰭KX^v\gdP?GOuSorcz:"nTuu1C<zr:WVGթ:WܖrP+-0P>4v|9{UX-Z$uszGz9L/8_Ugg:9'd;.';Yafk1p0g VsQԺN"R(~5Y.ÃqwCylɣ@ċbh] P}a`1uW]i-LO3`9 @KwI,ߕ\:Wy"j.\M\>x6%tl&jĢM,҄m%p^}W5I`2Ǽ"7?ԸB]%y5JnעNR qlRzR\Ƹxqh'm }[)m+/4zSLw,Ӈ=[`nDmhb).Hp /۹%u7}C{y#},yt]w!&r!#>KO#{>rCpE|Yto +pjuGuou%s]-^@%>} y 1'8'3f<3OgȅQ_/|e-N"<,C{9E!'y+)CYi$BxjQ/# Fe/c:M$q~"mZ\Kh.F倎DzH0Ji7't^Q_j4X& ~>S2֟ͨT1] +Mvnǿc9-!=bv=F wrI>a0鬟_V)aQ +F [NNjZl7[yr l&&n㊾@g1jqH}` 0ؚ10&Het90lNۈc+ql!ZzlB$xݳ}5TiofO?އɫ;a  #T08ZmXO_֪"_F*~'"3 tMb6]<;fs;Ǒ[1C sQd '$ÙJpr)8\8U]|W'RG-]LL~԰Ok]ۏW_'R8bZ !k)էO vd83`WRNCj ˵ФjC {3tnߢ#}ڋ#ᣍh?7s6usSKZ_ ru Rx-z;K so4Om;7@56l !! d 0,b͎o`'Bڱ:i;M:tINL44?iL&LL[N~d߽ZLc<>&hҷIP3 &@'ǁ5;}Au]uWt^9]7g2d=6.df6fp49v0RdJZ3HJ>SHaogx^1n2G_v]G;t X/NdqqGezK&[M/d8!cjaI[5vc+cΌtd=sfDKؗD|*e=cvrJQ=;yMV2jJaȔɀiL6f'2z~A:QZӒ5ƾIJOӔ} 4fHC!>9/Jt exB֔i=\F5-K]O"w3=&,ytX +ihhTl )Ƽ>F&j=Ez)/ר{Gw|Ώ}^t*gbZvp\φ y}=5t ۶bˡfdCO-D^{ ?DS])U#7x^5?-:"&}Xs׼d;Ec%-dbtfV"u!G55ET+U98]|*RQ|W>9#s\'bT{/[)ZE̵Fz4®mԺr lT8rp]ZJw~ݓx='(#q#ܮOK^g˵\Z]z*4zb5j;:yݔ(+okOooCӧ7-Yvi\2Tj dEi.Mzuƿ?J|~^.Jw(]Cqg@Αx{yl-{-+rU9^T}".bzgmrYFy:Ir6/iַumf}?6|CҜQ/:ToLvˤ[;gS& $rHNؐ(a}Z$b$%zXcE,.){^gi?X}]w8-ÊâGY=vE;[ y`VL2+ ~u+IͬΊ F +Y:a6a6#B!rHoHi5mwNS< K; mjv$*]2a ֎+N.c7t +SNuZ/۴yJLi)̩u(HN*8NȵNɏF4^֡HѴFY-;tbPSҿO*Kt&u\w&SŸU:CfVՠ3̌P=~](x_`R}]"~IR5ji TQQMxPi2_g42sB^9bNyULz]jUBy45P:׿8"ͤSt5L,2ꀓV?.5G4y]:ͫ*jzzd`LJנʐx ;;L=MLmlכo 9 ਺qO048.k ϐYY=svв ?8{#=F=Cm̎Sta{˸b. >B ʟ0\Jw&$ٹǩOin+Zn᫾~2]Snq:Wj6̟q@]a..R9]`zg0N'xNe“G1+":>D9=dzn'J3JCPē)ۗz y /C3T8_@2w[txxw &WԢ:%8Hu|+o0\O,rf'v[9?0T0~]ƁlteX*RCdO Ҩ0%YMZh+!ɩqMVX ؞ٶL#m/d%ME'} ܐ)6yc-F*0E|7=Y:AUe{+{ъ[l99M#29T^QVE8:;v*qTfTG:{ ++0V*@1Y =z)1+&}2G(:ݬ(UE8,ThFB24"E +xQÝ<+(}i KiIc`"( -CgYn1SQپTXvBsL/C]s22N2>zEVPQĘh$rrʲ,.*"b"EGMڌAkx]Zp@1p.F-Ȅ ;|FMHMʏQ\~bdOTmReel+VlkikWm*,->)s)"硺WCT_)(Y`>̇<UbxIYrLS$81Wagerd(Q +q4h;d?,C9|(CuݕLuR9(y`9KoC{›P"Mq_*]Pw㞤2ep')Н< w;5]l8bqB׸X>i\\z>'($,JIp϶K3ZJ)Z1(\\n\v Z\- %^AEy!jS-Y_b:r2#kT4budi qz>o  Mmր(\65!2E<3K^@?HqWIFɸ IJ׌kfZ€e0~orie2dZE+F[qzvb؂(\*\  |!K9$މI 6$rɃ6vx?:c3~lEɠwRNoc~pwz j@sH]N׼A +3 tm6S i'K.x?G775!&սP=*b7f-U|gd5HL] +s4nf, 0C0uG{=\?gA?LeF^H̳71x,bɇpoB ptHNS4䣗eKpg0x7{/d}bqqv)Pq`u<?lB>#&]pz X4]?o)T=b {M +8#X/87$\ CB/DJ| ^wƻAoBxo@GD|z=s-Z掊 z +ebKTMu80P=i?C[}J?A%^%iWpc]yha<G?5 %,|• mh~+E#upюe]ާI{~.MX_BP$|̀oH˰ЗuKÏ~P}9H!&(h/ߞ!o_i|>B%xxcsv!.+v=}N~=IMs ?(o0a@`zoQ\$x_qXNs]c(~Q=دm ǩMbū|S"7)wCFFG<" ؟$2tD Ov;_}WawvS]L&vi;tmD,o;*tCc5"1 tp +(!b'+n6:߯p9g{|~8}C? ޽nk  (cS&#QqvҝQR3e\VEev(2sfVD_(qOSӾQ{֘bg)(|>i|ngR\8(& ˬhMQLEr=KٕP+,]{Mt\\5!&:*6eNf13A .'H`EORD~MoQXC34X +*4^c )` H?Әw QpHniBy-OJb ERDPV{&hۨ +rg)=SߛUQnV{7kX>^aE5o@EX@R,إ9R@OF{B5Xx5̓!Oxf1O<&QQ*,g?$Y6{Z2rl@ps*9'ὰiS F4r>%~$6xн\^./%1/{Cـmֳa؞_j9Z ɳ"0sH[)E; zIkYp,0ᥚxy\ZX[ZE El~4j mEp/D @y:9\+Eաn04#H_ +~P+[YBVȯm'm\m6i-Ofb%汕 nZX1жrPHȮN R" h +Ko8z2"CIO:9t4 +@$x0l|+z,H C5D4(X\X8>B_PmŃEf.E tяm.b+f Ւs.X]sHnZɿݧXvƋ%_Yɳ,{JAf A > ܿpF]hUL\˘r6PLA٧[36Js9ʬ’|%)S) +}Z3m3!Fo0_֧_EpgH} +^gL5y@=z7z9' |/ f^`6:s*D{:I|9~קu>Sxg~oRK2Cf#*U.«5y==?(h(àB%8rinq>Op-7qqOMWq"O_sGz$ޣ8[]AQ|O5 +yGcupC)Ǽ4fk<`r +$0_uZ/:z[]ם'_&/M|#-fDҾ#:o +L_F;<@m q1bѰГ𗧉Uq jFUGq/qA>L-!X +Q؏/Ѽ/ZC bO\0{8.p_#YpVYfc7.jػn]&`v`ԏajqZP8O? n.|`NGqt6تeLC6LWvi"*v29TпC=ڧw{41{$q'5 \fAmW?@00,6@$"Bl *va0fKxĵݺ z:vio}h4CڙLcw2:n_֟_/߹\?!`֏Ɉ5s8Od^n)`OO)2'1YYRtY 4'*&ַbs).֯vla&vl`8M~s^NjXƊӴ׳k%J?12(8a#ߧ%I zrrs9Y٦^lO+Qp*vec8q֝r,jv!S}}xX_]8ߦߤ\J%-xZ>N*.d• +jO<]01=OdV5c(91B&㇩TC!*{Cޤ\՝nȢ$þ1{Kel,p [=\~խѨA GMh(zV+PTO'}?uHO;e/ g\Lt|ǥ+8FK5_x۪]MWO˜B3 +&.+qC.# +$Q{jKք}/݆g4\O`2?V#4dР~Mr՝U0ůΔ߫N5Zȟv^Mi7Kƴ!7O3?.<߱"퐂`D2Dd_3 +4XcJ5Qmgv˗Vca5d-ʛs;!O~_x(wu o =sHI#Ė>l 237NAm 3T\ͪ'o@ ?)WYUCo˙*<3U=3n +|rY>]/y։bߒƂt䨮"OAܖJX<.Uء*k1UͩhMeE/EUIѻ[-S |'^@OaЇ r{Z?5:^yl)eUlVeqrUkTfoPiI%!8FdwVe-}]۲8~*KG*(TڿU|݆︓Y9>QE @kŞ&{bUY*+3QV({Cr+*hTsH+WdV^U:#'ʩD/[.|KH)(]oMnP*p%JU+KVW,vT;_푹ƯܚNj>l2[p_Լ>Tz=pݗHuEƳI!xkh^8/v'Nk3['S]ʕUVQFoxT{7$wWXuԾ?(s_# |s=x@+q]kgct=l_2dlQzEiM]JoSWIq%_WthN{/o+i8F }ny^*+%@J +!T|=bAQT`!.NWnC)P-s pL6 ڀԂ*K׬ai=Sl(]1E8!Q a [@6]y(: fPjnlF@d)a{&/̇0k 2][#>\ہx+qŎÛ~FǨQMufG,ba/"8/G(#xs8iq~g>;OaDKg}cO n&TDa/fi~sy +y5F~sSzkhym%Gw9']6M |up:qa[eycXeXvaYXcWXQƤZ8o{Nئ6Z:鑘LԴN~m=}O5QjMaQz,B afap!a!h jUbs<gNq&| +טQcj%jx<||ՠޤ׃F14izа9iy E6 =$C~mGLƱ!Oद [͔Aԛ4*g ̺ +uqK\n&&)wMDn9H\G%3>=zc~C>{m\- +&.:Is3'x˺ށG] ,g!/z ѳ;x۪ |5U_ +#8a) +朾IԷ W337x47cf +kqowI57}bAmTf3&FJQ8fExD)}Z!|*^LSMpφ9ߠ^fq{^bSZ.Xv0dv'oD̏u*>Uln7@ 2dmeC}-h_&JQHVo 7?ǂ?YPcO; +'eWm?𷑁s"8OR!sDe l=ʨNrԜen??ɭqOl+A~/ +~o8P_6U<}/G +Vsx#C#siWsd"=j>^6UӯY1ŮQufUQeT{Z G_ڋh>Ъ>0߂.-\oh[ jSS|Pm[K:EUI]H82j43yJUb<-񂊓n8r&>ZM警vƂRclMO ?5J5)IT*RKTQY,J*1-W rdlTQN3fWiB*H|z6soͻ:R˚KUf*q*7mΔ˜CL3rdի0]^,T`Ue,;k9kdWvupWO":VҎ/-6x睏T1uɕ-gN9&srd˵ TּJ)/MYK]JYY]#2YO*zNPz]rh+k[A+>@&wqbPh!-^Tڲcbw*УQ-c@iXNjJvhLIEgXxMdFo6<mqmyY1re.1+$O%EJ+u+ԧF]Jr+BڦXAŔҷ]rU*y_Eo-hu{l⽃<>eCd*Tjye,(ܮK*y㙣芅Ҍ5zyEx97VvEeX_ b{p_ ܼs;׹+t쓱:B8zSTתHS<*ת0_B|(FɇYK{iR9Ziq@facӱMYߵ!I6@ /0nU=\G礬k%_9Ԁ*A1Z5aai"uEyaqpr*" ) "r*+tϨQktMc&5SEc64!j3&M'5mi'3~t:#~}\ρxǺ] '5nV7bC=KJ=H [8b[7jweJ8gs olŶ\ȵn=vf&ooZūku2Po.6gxlY2r[vp.]/Nb xxXf;ɉNxaEgl^\ց U; D#`K@{e7a]!祹{ /bŽRbej9ǷפG?2VVg (BlF(ӱ7c=|R!CGLu,bB7 d=^#/0]ϴ9Tbs16O ˜ekz&؂1;All'0hAۈC"y6jW-"zwI6ΠH-L߰:q/C//n!co(A4^;B G0b8y޿x]<.: ?x5[>0._= (7@zO$?FɍQ> + <`?:[I8[M'Xs0~Pn,D($03o9I~' gSǥcT%ܞNlS9 +{ͻ }=c +B됱qc23-D\_$/󛹏ϢS;n;ܱ2b]c7f?.ܩZ+~ |=n1"&7IVI7ȋŵ#lZ/ }͞}0cLwn3] & +:oH_<Wr=~_]b oO? >cʃk6\}>ua=.{. x-, 3:W?ES5?`8W' L(8B8JunBb {r{!w#@N4— +cH:u=^vDDSȅUq(+lsG^F!4HdE錒Isht>O>mڸ? ;}!Z P(";d":^.D~ ˑ_|oAfG[Xɿ +G7kF ]~;*|:Y|+,8QG pTc Fdr/ZzHBvk1[yC֍` ׫LK,W0G6Sl+qQ&-VhAB34dg#ֺ\7>t#7xqh5rŨ1Ʀ xBቅ' x̀g&; !ToyDuHLV՚R4e4]UUKTaTY<-М*he-*Q +,GU0 ]V'}c +FN4170kѥ8#̪ QUp*U`fPIHCUZa*kW~xf0 FlUNİEoyȘ A +efK!n.q2Ype&)#9Y)JKUjj*RbzlY3V)>cb3_G"&Rv䯃QuQ߹{Ч3'}nR=X)h%me+!sY*UlvbXHJ;6)̱Kc8JKO@Bi}ZCi@VV .dޚQ74<DEsF9l3vdn&ˌٖlKzgɲ?{>|?׻(,{0 +J?wv|VXb n$SoRP$P畏1cctŔYQ#*gd lª%QP:6Fn1jTcHUq*ߏ!g*!UWTӜ >lTBY9qV3& +k&FAMITFn.rM茬ZB>_K# !aA1%g[:g3 O/k)hfHjY%n<9;&aˎ1~T Yށ I%$$Kzi2Nv{mkyjR }7.\Rҩp^vd5&I6~L5$L(6̈́Q b>3q=lws-_aiyyaSIAЀi84v ڽGD;]NmK-մ^Honbv51J^"V|λoq6.j5w^/n߁oSCaVX;ԐȋuzwfA,686D:B6{ѧJlBgm[™9x,"_e pFz`Rŏʏmd;١FvFs~.#(-ǽCM~˹{vgGq?ms=lX,fUt ,|?{׀~s>ҙWɉ=nX5Cw\+4o/A3ZKcZ~4F!Zg-/oE\˹:ٙGinwGf2½u`PܒYTws<=ď{n>ۂwN}c~jwRELu1•{yi}k3|7/ ߂Cq]/-XZ9*7#.a|axD4=]s~#yʈr=Jm@bk`|NZ9(_pϻgi9s x7{;;1(|cPm?P:w@8)b^Н| N+w#oGDW:>78kSK6ӶwۊgT5{)yE^^~>GCe3m5~+h{̧Gyśaxܟç>\xOh$qz!?q qQ ~ +!tX>Hg~_,c}UT~~)#ΏM1az|G{s2- nbNI˕lw#m6E +d*_wt7os E~w!Refwn1]ZR6v'Kپnv{܈uq>si/vg_:#O!xƪI㙉g:< l+ DGgsdWuOĄNБr<{+(wrXlEi6nZ|YYEFkUO=fv;|ZγZFUɲJ[!/r}b0Sw*+ߍs5b+qfhbEmK_|/yy1w Q]ˢ::rDeNcm(]3z$oWLFq޽1u15嘚^L:_DZF2eQ -9|($J +bFamL/jiZxX* _Fl#v?\}P?<) y!e(yNGEjVuZ`n9Zk>]{vιzݶ[&H~y睓9)bʸ(YĘuj oe>5:Zl{_j̓ݲ)5$K^'ųĮϕBMr7xĒ^(f21IiLDo:*Sa(IzMI7ܑJf(A0>yǍ/eR»EfNL2%d@Lfs*%;Nr[ yK%òF-Eg#i1NKr{b-o<4?߽RoR/v޵O0'1?] Y/HfAdXn]ad-"3l+$>$IoH$ؘʅ,|Vf pKF%hP||'9Ŏ/VL`O4%,.RI.$8K%y,TSE~K6nj~廛eR/gf>g,Ñ$ieR)J9Ar-h +֍0rs\Nr|(Ç[2O/wW9y T̉/|Ns62]J +k%ìJ5*^ \+b>&{X*_%IZ8V +'nb߭ Fr6R@1ji:Ob8G[xtM#:t^-˹ +MG+nss~r 0 &]3h&Y z"HM{yjF44"HsCrJY|ëÏ\bXc R-䣕X'm"L,.p#@Іxmlmmqc qN";`?|Ϳ;kYN=dʌ+  bZ;IuE]DEXD^|DnEl]90B[p)ޑE-#|xls5p^m).O8\]$?r˧0x9H^De/Bklko=ηzY}\L-AzMl'e&kc`6 9d Rc=ru 3b5cifjslҨW8W(>/[§?JNc?F ̋$vŒJ2R#OrYҟnJ+fuH9Ӗh_ps|wإ-{ٽ1B2P{=mf^f.O^??ɱXki}zsK|;{"-pX~$/R23~I$Cxw#5 m'ֻw:z G _~g4OiP\oR8?"IiuUWQq^A\ςp~ >'> xrAv6o4~\ŏ +s?.(() 2A"5Д/.)8ϵ g*gc(UXj""yy9q>C㞢K?N!^7%Ip܂]p\R|,I9ضr΋m?eZnv#~<uB{U2l4+^jOh%8BN1Je?ďqA.Uc?3d;%;=G/2ZD}~ +D*J֢;^Oh-pDkEŽ`ۅU/csf;61z`^Ae'[dXDF<$9hpBkڈP#x;= >ن?6/èM1_' us45^&[j4q6D }=0bAP -}KH,!ZZ7-:9BG ?qcu-WR9 d\PIpR=pQ\FvR=xlvQa|>,˿ƿ +0b5ۏ{>;NjWG;~܃aF^ḆVǼGDg4&*i{&]g@~cb| Y"Um$gc7^LDBk?Ѫ#kDIk8q5ٯ"#jS]b\:RBܱsCLIMYx|^|ɐ7_QN/0˱mB"Hc${<\:%C$*ZB,_L`y9)7&S$ShVRhRR81$ ^8x@n'Ц-7h=J .D4^h%iSY\~Q?4W4.4h霂~N4q*9=o 'ݠݒ?\M0q3tl~6 6L6lM#~"2?"&-g*$dqZg!~Jz3^>iC͡XzD&!hQ,b&y~(ISđ +qL4y =ҕA{,\܄k3jY +# + Z)G)}L[=ZEQYAC[FM.۱6T>S% ҕi"~%up/\#Z~8hGCC3s҅]+ +6@j,g}vƵtv|OmVJ䳜2\, ne("i<zLח5-HGo7{D.Kp=!eWLr.̯  nh`IP(As]l @jcPH5ZT3Rš^5H]`T/m*"pS[-.|ʼT3^t1,QO`b429&'2@qb0b^VmZgcGg}נADuOCbfXqYY,h1&2c"Ә/J1YZzM' Oog7oٺ;jvWvgߟ^o?x=~䩆3~>|.\k׿_SBT*(r6mdRi{T$2T{JTeߞ;+R%`aRa82V:LPBLF{?RjCJ%Je(BIk:DyR {};(eX`c!m 2O'570IG#k;܊LJ.0B% LfC=)` 671>*0c 7& +nb`3F$Db i%p=ϲ$+6?H%}(8 s2Ch^!Ϻ!kݜ5lQ 9v>֯9GžEo-̵mdRغ`bkGBXe'2\<͋ǵ^ƸI3nR$3ZH57yNdV59eO-9'y7 ]5+k*[/X/_~"n_b>\(l'dh`mAL hk,' sE)la4SՑ.ȕ +/tWEwx<;~pwQuOuAϾyl.NVDTW&*3Sd%(iFśKV~-ܒm|!bNyx5m6L ӆA2\okzW|Fu²x6.{&8 (! ( Qx.gO ~kFl3eH`?H'2F Z`P+k:# P`N`2z| 0aF /g1?6( V0dZ&4]׳LFtJr50!eY.C[`?H{/e| Tuu D:.FWCDN*e*:YpNcs*;f 6x souZyPcSCT"0<zT%sj_of}FmhؼT|BZ7 o=8T-ө[کߦRd!v\CUrc&nw^ P/#׭\"nUh3 R;xN9`q2 %|9Czq1hLC̳#p6X nC⅒6Kj\WIW6qcD`m +;.ugd` o8|$7= %5|=[ܽ[d +!9ԅ!DϲZ PK(Oq*;v`0gn4unD"B>Wh^7d?Dy+:#`XYFgh?gC_)킭vVD+L+/hT#Vz&?fo|%ӂQm&CHNEɒ˂Le>/[Ugsՙ4霋کF`Y}m}m?dNmWXo[S}HpAsJhR$IiY ++#ԑ9)M5\3+=Z=<]ی; +w[f4>r1 CbK> LK8m9VO5ޢ?Z"зy8$~xpe{DJޓiw]}LE|_lU]}r%.L!sjs&f)qQQFc|OB?]b %b^*Ħg pFﵷ^b ӆiô Ay̶r|>rm(%zb$))!гhs,O-ܠ>VzRGa3e4lك轣XS`e-^pۢKuXن-^&2O2|4#a_0B\WxX]aj0X؋f8 eZQ#B]1~=Y h@>LUQ[ !{S˵u8 e@Qc(3&~@c /:0P! Q `D$Bnz3 fBn!06yN+ֽ0 Pz'R+ë9Kg(o4𷢭]庶]JPQqW,801+w>,o`⇣(rXA?T@@s;z4: j8o>3+.UWAz4T)"JAC4r܄$$$s'$\&p$$!q?ejlO{?yy1ѣriў`"w(7(u"p=x-{;4|/ ߵeDQ 4 .#*_if5.qpx e1N}.1Ip\p{K5{ çp] ``0fw73^4g;{SL T Q]:edAD*ڑV^kFxQ:!u74ܻ[;gVw0P3r;BM4ӧg+e~˜{iryŦ^ǩސVիoW3rlu|<H[U+R)%ksz2{Ciizlw$w$Uq]GoUL Z,]Ih2TDPuyڻܬhaz_&NڛНNIRHRe * EܫL)>j/^ʉ;EA +ɍP\4.k[³HbH%I% ?`<cu#փdv`*}ƽ8RL~Eb +kT}>]8oRԈ.K GOb0 -w QmSoaci$OxC=s { cg'_a$`<D1*eWr]iEǕ_T\re쓪Ϫ=M8˟_)wz>r6},3}|RĆ/I [q{lf-!+Ė}$iDZaزl B;IIȒ:L&Uكa9UyZ װ5[6ÆWïO 6 AKexcB;ȡɦ2C]`C<_UU匈j f5fnmSWĮ_a74́4; Z#qՓ Kvo;`2BvCkdxPL#""8D Zo`/SR yS^Z8#C|RImpmhyi;n`n``@n;Ra`09?~u=6ۼ +mg>6KǙ~]#eG*\dRh0/`@⺁"ܷEm&0b)%qK*2)5nAkt"fכзnzaau9 +1ˆ")5l,J%0&DB7t ][7X mfa> p. 6-PFqVz`hr1۱u# \_owB!I˅- |9릖ׁ]dQLn :ap7w~}Gx[]~&Q^ +IomRf+|jE\c2r0dxB fVynyq^S +=#9oPkN BEƀ˜ b?6YN2 >:'9ż(=)ᾓJ,RSs24f*rRZW\"6P lZ5BtxR/ Of$?9?|ew"DՈt(KIFv^}as^Zk*v]j/eW؋5Bv%ͣz4'ݟL'.鿌O?͜c 45FJv?EXCuWN1S,Ț̽g 2c4IjH>pBc?tN)N_IcτI#UīeҔ=C9X}$}$]9玥SeR4)cѨ:pp,Pl +:j2182n"3K׾7#>("ld5 kH%@ٓ/ !EH0"!׏z ;^NeQiD %w +k*m~[7_QFm6˴-ZX,0ز0y/IS\IL~![Ȗl/dU֢Ry +e*N̘\Sɂ`VWkѬ;Ňi,l9y7'~JlHY}F(]b; yKyKeJaF@3,֯`oeяL^ GGU?Co? J=9,bZ@+*"*}|J^E%*fpoϋOy޸1| Nn̪=,GWE؏MnIdxys)[/ړ7 ;6_v&xj“W]giZ >H||%"M(x+Vc +OJҎʞS+Ȅ_PO|W1ȺG_??7^ߥw <> |, M2`FN  xGE`iݓb ,9`09uym88IF`\)s %Zhi7aڄ_toQ4m4T LjYTk`?50>! 2 )KBnf_~d;p5wiS^clHF=fײ-Z;,jr^J>?^xa A6dCC!)Lo_#fvR:Q2a[޶vip^0lԱB,ZfW2 -X@.d@F><& T)${*-]#:Zlme>pPAo +xH@;5 b G&V=*~Tr|5Z'3KE ='Eڳ'e~K [d'Ь?}_ +9 z(ߚRGhjLۭhfBC%3KEl:] ;Y?" +ʄ|BH¯$Ưj#sfxhX[DDovTʀэnNnb&R&xZY6h,@}ɥ+7ofƾ7ɰ8W6]H +Gp̒ ̹j+y5*1F]'':yJ;O83=9LU:{I'tj*ՕIwzdѴE * + ( "L$*&nI4IGKMs˳;ֽ+ 6;mi7#F|gnEװYoX4h^t5_1_7P,*WhE-[b#)D,ɰ-[4h.e f섗֑|Jt7w)f/-5')\Llb}L| א:e@n^O@[cߞ+]0zy|'bd)ڍ*#X*kdOj(RdYOp i"}:/Pat%SID_N;KmN\8i|^C(ADTUmplyO;sq=DK6]$ aY#f8a@gbJQ)$s9-O?^=ܺ_]G~m?6RXh+Z%!*Z ۑ43iV7ji-色2{#,BG 8`g_H~/nZ;<97=DQ:VtEKTuML=ҎmQ$N YcM= Ac_[Mzpۧ e¡/>})]HvAM,=ubAk #UZaG,~SCg:(MkC7g b-z\KH΃tp? %EPLL ;BbCcq2}ߓQɎ;Ab#=9E5p|w+ +nOwQ=0 +x#@@ "@xtF$zxOptPЎ&AoR"ذN5EgĊB}`S{0#KhbXOc# +ܜCa6l ^:uT/7ҲJetz-ĺ "N 6cTt!E%ӧjdI2k6aӀs?L ]q>kW9|h \盠 tyG}L{UnoCqWI\-5*ujln^3f2Sg1!7zG#34Æ[7@aW;Q@ʁ(+(|d&L9jʛ+)jFMj1GRsS+3r̅ÏO[<ދ<ѯ‹_ D?ƴt%.`6Y9WY<.h52$"Dg.qR3)35 6†z磞{~IۣH[—WOM'x6[gvƵ1s{wrVPQDAB74`hR^Ɉ"$HD Tˎyx;U7UMj J2+/Fܘ(gTEy +vz+M a蒢Pk(PfW _\YvMslؙ.״ngX]+l>,PMS90&ueJGO^5RUutqvU"q*I{9d5+rZiY|YZfk]ӰʏrMf mV=[רJ7^!_8QSOt $ɃxJd\'͊d@:K"Y+φKg[Lݷl'\GVC4.{Γ:K*h ?-bA]e0YY]"THa]>i* .gAhjYXJoN:͸tc +3*gmԋ EHzdA$0mb`Xq\ߴeܰKz0eg)c^Mѯ[C$]Ź"ʫ~c?SK2,V||9gAu}?DSg;P6UgrÚ{XͲGrƍŚvNbc^/GxAHLU,)"I;=zFݒ"j7w+'xP斡`ΡqfY^@g3no0܈ Sy^Oj%7e9-xi'%jե\م8l}=+ {pr6C٫NE8++B)ko3 {22^C+ϱ + Msԩ +C7F>W3Zߙq)X;{>s.*n)1r F_޳'!q&?Y/s,wU+\TJgKBY^%Sb0 <|blk.1+wT%4EǸl(Zvc:αg:%AF=d7ҶxlWƹ`t.]Ɇk)`~7=m':u50?Ơƹ&8D%:%)6X$z }|=mxҰydw%@5ΜOC(0fN`Nx2ؓBŀ|@wj'@{A`փ`͘ˍ0]m@aR7wtp08Y6`.hGps; +<16,  KBK|k v1o{/?#~q +"s`|]uKS;1by ܬ,{x\/)xۙU;^H']jNdjg$|U7|b>wpYs@?Εkq.~?(kvBA$^OtabcWiI˔,I"4-i>ggczI F;SJ='sdKcNR~)ZC52Xĸa!Nz0a/9u-%/kas59U#+ eDe2QKr0C{ Yk3> &d4b [QwC#KH{뛞5Oc59ru,HM%*##9b{ugCkH9y&EA >[Џ1+a)Kc/0Y_V,PM*!7N˦=r|:~5a0^AM _Zֺ33vwclvVVx!GI p3I! Ba!"Lj_g|}}J,?uwEg()NFf'LƐ(rB$n>8m 2G*<6цm[ +J8P|@[}@=H^ˊí@S uQ&sQO˳eoȱvIX f'v7nu{l3u< ձ"li#szNgӚg{C Pvt?EK@*9:Pv)I[$UI8n97ld=)nIl5F3:]\yW?ӝ8ӑ4BsG 6>PϟA3w=B$nUfBJ 9)s #c:=9ث'x]I:~[x5 եk6NOZK#` =x;n?sa")b8ƘŜH+c&6bMWFؒ6jit-kZl †jA`1(B*ZfqdT+NVYi*qCj&S-fj0Jo? G?$@> Yپar3=~;D5U$4s(73]Pj1 +5K)`Ub2V-*jHXm6Ԟ7`]=Ͷu]{ cyrTaբx&m-2d9r%9W )d<E\M^7TܷڮZmvڬE$w2GW_(noUOC*[K*U)Jq25X,)KҒB@-*e"n ÆS_lw^aˋ"Gy+¨A 'GA^J{k!#*PY:(Sy +YN)/V4Bs=/ 6T:?}}y:í[I*="~@ T66Wv10dybH*SLB!(%XZ5@o(.4I1.feiOx(}+Rc6;UEsL"V!GW+)d84BsT@лO Pudo;]^<1arxJ5,g|;&=uH"IXkGK}RQ/ UJ#Z8%Vidmdڡ@Ƀ-HN/~O;KH_@~ cSeO !豄.?4BO=ڡ`hQuXoJڮl`/˃FF}w:)^v_Cw+ %$oc#񭨩\Nd oRW uð>O[:j;|tlاzs5Y Ak PH;sndŊEܣ w[5da?!r12M zZ7W=[5fx1c=;0b *-M#S,m8X38sh;8TWvUT)j11` M}BTB΂~wz1<]k.f hchD} X+{q~q$;dpx.ɻwbR¶27[+^MyûZ2䲬"~>i:`@АCH>'Hfp[*|n/ 8b"< xFv}CSDyn%eofd!6]69\y%7BpI@=P8Q#8} +9g~~5y`qZL[fڎ-M [dHBHBB@$l/"U9ub{D@hqPQAd7O=}y}}?1G=` _ +¢q" HMr~OvX-l*lO?5A\@n>#2lY "6hL,aa']I7LuEX3 xYAnȏu aͲRM_uc vDxoL/l-Aܥx =$9! N #pNc$O|O-e.դ.6罻s^=txuhmM2b 1mTy/L(04E'r)kWG6!|l͐o_H-ŧKg$Y9Sa!mA&<+++=Zv6f+vLk/! ZҐAdoD.(lAlOKBcgѩi,LXydTb"te~Hͨ':7R?RْDk" ⯖@v98i(6A1{))!rZ45)H0nKP7 Xթ*(%=K & ֠xZT܂K&[f'fw15A1"ٷ7d\WYRw0{Z[}m }쾖rN2΀Q[ _,Aַˑm5|z滧[mL'l4n^>55v5}$VzYō.&^1L mi#޾f{;O5K5KMw*nvVWuVJa/J#]Ț5i8`"J}D%jmV5[n|XzmC[CkO{ifK~>M=ז[~e+]ʻJB_ +^2pj81+>4͡u(u8`|pe}{W|w\~Oxdg_T/9<]yޭxw{.ott{.j85J'g-7H㠱[;3'?GIC!߽É^C O4mi3-or7S4!cg4H%yrs"iyN/]b2+]Xi.o~Q'QoҨ07B:Ƌ  &IQ&I;9(S1槖 @1 Yd}<yZE M\U.X1f4f?mVaLW<\p vQXq.ecʓF+SSNeدJt|;'z)~sA7[ |`ώ3x'PED+#HtDy1+ⶍ7[('ҙOȃJj'4Ry*9Eg?+`j/L7RmB80/'Dg r#v"5Vq)Dx$Vq1! שB.wiv3R]0Xb o8mm +O{&|!`A l+$Y ct܄BR~!ydc- 3'&)Й? adm>,جc썶no f؂p&n5Al mk\;UDŽ}AH!Ah0i3C0?g|k`͋`K-ap]+Mj=V"tDBJ^iF7SNw2HH  Dkp0o2 5t6Nڙf0 g|zlok>\YO]w.օX[: +dhSN]M ] !zq7BG= !N (Εp&cS(m?_ÌRM!jӝ ÙZhaF,! v@ OxWy XBTqM 禝p|W9f|="(%=^W* j"l u1F%G%nHo2M;rUfS8[ߝzF0>F?GDz*x2GAjB f"T z1AG8aG?|ap+ ^ +VSOe ?Ƽ|zy!S 1s ]2"!z!:dN@僠Dv +D<#:\bYmq]qMy (h-MV oaAWisl$Ng)s&,A,>|o )k,A5@v<0/)ncs#MxNd8TJ ;h:WSizb0b:>r:9QH`2XVk/Auӷd~ฝ{q!Xlhck#!DUH c 5e7t>jdENr'9c&ٷb0_mM +ܷ=s\qy^dGHI1SH$&El.9RYzӅELp yeq ^Q\ k2w~ ?$J.^hzs‚q}i8L.+K[cJxͨ{ȧQAuhnyḧ́Q&qTN/ !@\eRXڎgo(?ݼ̾)cF՟$n!ϲP_4rZ3lL'܍u~׋K b (RcBEH,y4W<*0gCɀ3ۗ?};SxzXam|KϤ~]Hd+'Aԧ3kٕ)rmI EV2y^*I1HD8HF7X6kg 偵:YzP~v[vϷU@6cul,AaS89ũQ>D5*eAUtrQ/!$|QH @lX +u8Vy|p?wV|E>>!Qu">Z!5L+*rlK*:yY/ l if.2 EX5]qhW۞ם-e^U2QEdzYt0/fUl&OLg4IɘTddHifoY;ߗY1Q߽tgmI@ĭPK<EΒ2*ZCf +(a55C2tr]/ s*?C%@o[eWnovhCWө_tWQY(. MRjPiyJ4+%0D,)9W *4ɂ'Xk ;&pTNNbꥦ$l _[z3ۗ-kinksoh:澫{PueP,+N`2 +|!*YYAK'*HVcZ%d8^b.@3_k-nO j뱵USuo7_v4xI52N.r%4a\q<*3?`XkU1b">O'KK@ɐn2pՐ {&xkG8/E{jRԔhV\mZND5O\]$iWV!:yZ/(A-2'@_ؘzYzo+3+}xߎl/)u§W9]ᴎD|k1%L7e}4y-"FЯ( +,703_&Cy~)ꮳ:,PN;W>m[ɠ^;ŵ b*YCHd^->ouqg{Տ}cR48Р +z*`Pgj鲄6Pqխ#_iFN.8e]tOX6$Fjq8/]&M\66\ c+}t7kMo2=M sB\vb*,w)<{B?׊\;4T#M&6ŴXFAzuhMYG\o";QNHݴ#ьEX9C2+Ro<2 \pCaXKHc8想|pK79CG}AHM!b3XG&|g-s b0a`- wiD^k>(^VzV/A]g[S3G͠5!%= B*GܜR93iX]7!pFF[ Yel"=1s` Z7G(:#}W8 /D9AlB%)Hϩ`#13uV"-YB?;> **|*($/3 H^) ՉHٓ؈;rAC >b.DTc"DOi2 I B{5~SaȎ@^7?($GBd ^Ґ)̣\$qQBZ?hSa$=)t!i@j + T\?WHBݡ -jQ0TQCd!H;EOnߴ]3IS;-ovQd&(3i̳\UL:ACe0ς5QO_Z~H_a +;v呂׊/˹PR~\-a@ib;zkxy>sʠ[ OTsÎMGû2{*%mƬWOukr_^ޝW[[TnG?F;ZѤwhŹA8@Vj =O7xOm`vɊuGNʫZ=Y٣% ?}Rc)mmSEiumOePͅ¡ C5g'C;Dfb N٘맙Q/e'dRgݭܦmZWe7͇׋U]5Rxr&CWy@/Mu̓u_j]a1mgR^ZEIDҁtTsi%%!k +mRUxWMcwy/M8P 輂Pn_ UK^Ӧ;z$x~vFZt[27&Km+a5TgGrj5VČsqSԷY%ԷE24T + cfkagdW\[wf)gl?-s0-~/Rwv5s9=#b860VoSeԗRژ(A/HP9o4C,Dʌ>Sl*E}v&N[wu)mG5c2ӓ|YFnV]/I$>tGRB*>&ռl8GH#fQ0]Bf=a8Q scBS&Ӑy$u"p2fcW 69mnt?sPUih0*(7!9Wde\@ůxm4Sy:M32UBv;~`eO0Zm]i3"?h5l޾ZEc~^gOED'I +L^.˖ŌrY>Z}AG%{?ʌˋuwzCs꟠tM&Hwo8d D~' j{bN ͖ o]޹1ג6&j!l(=p(af۰4UEk1תpg"z?G9v}qk&!z &ZPfI>JW4 SeijnSek#c>.QnNoyvvo0cSWSϧOğ9]gn6\i'(YByW>M\7w|r4 !k/Gl\uFݻg*{_ +!_=M|j؃[u׈߉Z2%~3ҡ}7яFh8wC~}0#lf -1g9۽m{LFD{Mܮh!1E7HԂDEpn0F9pYyzBտbFZ mFdo\9Ljja}+pb&Z(O3>H qN +FC.9ƺh/g4` lY &oQ u9Icqg0F‰\0om|\ YA9B-(oṇA7Лv Kp ]k5kyr`}rk#tx[OH#2K x."l t6B4k +I_ N7x`1y gϤ%}b23glp9!jfZXO1Hp4 ܕl0Bי +Ɣ^I*qYޗ>y{y=sp~z@ɁVB2?h!d :oC*iH#9dlBTIG,(ȫ <_@[{~ݼA~[*K.}AWw!Np& G. Z1A%O;gD+GV4o ~rw׼?C_ UᏂÇ+ []P1dD˴r>r,tG̣BeǤa[3bS|ʸAυȦgW" = +{ގ@ܵ(_!GF5̴BkCYwjn6Z^3Tij:Ia֑ԑ.ʺ(>'>55kϩ_f6Jf3A1D BђyX6oJJsf#[Wu4'ޫ(m+$ߛ,5y<#[r1>|Yg$md'R+kȚӦeGӧsg2ff|U 2bD6yKLɨ2#-'ׯz`Aϕ=5[PFoT&v;e%g$m9R"Eޱ_G3SАP֤.{*@6{ZZ= ěh"ׄ54?`1`N~dlgxsŝz[2Re*|y"q":hòW) +&ղ=)R6k@L[dT,ԘkB;4d*V;kyQ#W&۪D+ceeKvUU쒿+YE@UX%W'Sy ȐLtBC T>. 1$nYH;\wZ]r!v>}&1tQ.PeIe延7+*۷T|x\R+& +ˋ&|u qO) 4w鑆tHϚ擞QH-%uԻ}fv{S{ST9ZeQgb8gN"$kJ4M֝M)NLI"z"))r)7=}ֵσդ>or٦͵M' +JPi$:tڊԶ ؖ9-]-Or#1 غ q59|R +MD7jjq7tӀz4-h_t%Mv96 1+V',93)ܡsgׅ.SF̨̈Gg]od?ϳDxtU=0Qsnj=Ew}dCn-H_һ&lEofԒȞ+zjWv$|" M ]H +9VX]l!:{CxTXv|R6`3hY_mdxXxG ,\dݟK!D>GDyrhTN,#F|hoFXȬ(#q&_ݾdP]B{ԉle/\+`Llc3Pw~IQ7DkY2F;8kCSP .X6ȘeBC>v[n)Κ3# Rl/aXD9DI"Z + .' 3U0G|5o4 8ڶ$@%VN1ETctgLo&q@j&c3Xq, _(r(DxC뎯UsU{TYA5K;-NЃddjkC4Q;Ig3Xv`Yȏ{2.t8LZb&*F0QK xWՅdxi_M \jH` +5 +>YþI6D6]cP! Gm>6ma;(H`*@Bk#O #k&+E +.8 +`űEѸ%1^;nXݠx#Do`F oj:I32bYFQ.H $$!ЛAC t MX―belp6:[s>C@ kz[Bv"- jAqOa Y6_y?*wYF];ry{o&^98Ln{_8g Kyf滔̀-(Vs$aj>붿jiW S">$=Ou< !X(L<8 f'z̆wDJW!O +;hry ?&}=r?vocn?\ +݆%x_e +<;}YP6brm-ϣq|B*tyQ0~׃v^⽐_wB~zȌh?~#p9B!p  _Xe ` ry_~T.y-~Ji+06yCrq]yR}=y5r(?*Rn0y:i6dad? ),C%b, XiH6ٛ4Dž/S=O&} m+z+^x>Vy0 |/3*iCԾ衈sѷHO'! +Q=tꌁHCi{tRVd'WژLeo3T-j<5kl2%Q2b|\^9Nq[O:j<枃w2C}=k][[;]-l 5R\5ݪZ~ȞjYTZUZLb#-/ՊyGdrv dN+1_ B \#l*By!4`;scFPfG,z֗o';b<S$d>ůصFMV3,V?s +2KA @h*ql#jD?8PI/GL/)=Z{&h[JGqX,H ŵgQY4LZNTkg"?9liTWo6E5@@B$l ` `qAQZzpZ:G;CZGkQA+ (k;|xo17J ~C`!,^=>@G 9J Q?l(dX斟O:7YL^_ cNMsrIzቕUVVLϬM=#L׳\[.zQ|yX<<?iO#k=Bʚ ʊzʘ/bˍބe X&Y'Nռͷ*rZK^w>VyIG%#޾}kst do5Ns2!SHGGnDԎJIcFqcJDhD>Ph-|?|9Q '<\`*!;q YB%_FHf!i`dL q2b `FARBƦ'Fd,A2M=1͌Rs,pzKladmvBgpB6SO&BfSw! !0&a`81d3 dB!,7D1cT r,Phll2ab)NJAv_&d BrIH B©?O9i-\27 +eRrŔUMrRdr#&5Lki%|KU-T{~r=k6[۠Qpz!Ak@o# ,)b Y5lDGxosG.:SjWxQz~t F m@xB7A#DC2ET9ٖ-F|[ȿ:'H7r7HvB )'x獉>oͼ!sޠ _4Z >1}"xPAc^D}7VnShjDγC\ǂFGx/;NV# +%x(x2ߣW6#gO%xvfAAk@CNRi&Rc͑f|hJbs?W GElRVwyMa)k^ا!|x Vt;^李+ iSCkPz1FM2.j,=q(y@r~7I^n~ݧ7z'qJܥ T׉;TMv3q߷Y5*} +&E!hhYP tFfҞqƊCLfE[b[ԕ_{-{5sYA0;dMi?;5!SCni^צE^IATM +TTPqԝDȶcb&9LaLf7/¬4~:E3xf?s߻_ߙRؐ)>Bq3kW2+#kuQWt7U5t}tg'CsrRMU{jDe.Ef {IɓEі >ݙ3ۻxƬAu%L8 z]݊"rEobp  `8 \DAԠS]wW +^w5`=4;e !;Nr4ىΔ6Y^1(Q5j%] }8*6"<=LD+ *9({ yxX` ++X*ΖWyL"w+9.9bl cfjPcdH) $1t ҄QV+>jh(1 "9(o!~aƮ}K,V-V|c9U6BK{~GsD"9&;+*3?<$U*Ni媓IsU'#9(Қ`-X6Lg~HgS^L?ЬT1'Ay9ybΪd2b+?&<;80;1L4Y@_6g湩{ESnmEmy(kž +4(*-,"72AaĖ9ѥ|QPXy+jOT""9HoaXa8_v[hcivXy׮#ku[*oOo''3j׷q8qKo1pYU!6%iM.k> +v6n[F6zG)޻RJH @F)zWp`{Z֎crg\3OlIrrrW1S̽ɨ +s"œ:C.5&/GQ0"#R` +5IL7\~0 P> Px 5d-섴kd 7G ޤgF){_{=|!㗑ħ7^;w)3Y@% #!tRh:k +a[&eO2;MW{|Wj`c+nwё#6:jB0܋7߄+9"v;1& ?^ǽڏ>Ÿ@ZW9E>K~؋2{m_q8sC 9:"}h93Q^?ek8 @y@y=P~"^ rk]qMX[Od vBX K V!Aa>ib(8māEp!ezz}|{|=1̠^-;UWݗkua&S4%4d*ɿ Pp`N @ +ɟ h!| +B)ܩ~|i>#tQ hh*S1͒}mk<)-&f|%3HuKt[G. +QnJqB/ vFX9Naz\íLd"OXL2$~)}=Sv x L*8!hvhh St'E.S@a* 0(%rb'q3? $}>L!g#Wu(H քaz "w"@C{a;G  *`XOl :֕vnttP2ΛC8}LbY MXhXBMv6F~ + i.^&n ;8WwÜ!>!x㡋5 H 2g::ɓNz(GLd4l4[Ml6.J<4=D#~&.>獘< {yoC1rMG(]I $ɑ. +:3#@U}tѲPF<-*[lM%n1`y57[3iA + zh#EaC7+*tT]Ӟn Cu>NBlTr+Ge15E;ǝÎC[aYJD-2S>dRP)GG4URЛoK':z104XX{S. zCƳhck>j+UWuTܣjw.RT:]g!J4kWE +-[(=,iE7a#ZNXc0Jz  + {'.uO +?vJ:%/ԵIsES-cuUewH|ѶxiACCDT3b.4N`K e$$pzR]ن/5&#$O͟mhaDz5CK4I[Bڬt +vANWiHԚR0ɊrH;?9@k9u*ٔ Ǔ癴NZd(~Ń5V-mT6G﴿}vT)JKe͐˅Ht;ʳ:9!w&L71-e@L=ё|6(uQKryF&*Sɯ%nV\󯓪].O:v)B%չ{3 /zGq@ť4.`0r͡;ϞґFm лý9øiڬy6,]N]t!y빤r[;ʳq~SSN8=s\{۷^̷N;wDAf +FdȮÆ<oЖ/> "iEY^ʱ?Y8=W֫a&cu)G&In W'agaxt(Kv"^DRsDIT98Vtx(CVWzxAGo|ߛ6:kSs*ë2ivꣾ]{w譺Q[t#70boTh^ʀM.Գ+اFחhd\/\๧X+ĪC*ߞW.:fKOqonߐ>{,<cu٨ Ovv󵔐}g9@J*\)3TPԬUF'[,I+ѹzWUqraI`EѪЭ]QMY)`QAA`AP@ABI( U0iA4EPl8*ec,Vֱ;޽9{ΞwɛQT'r;x*ħr__CK6~oD-c&J{=52 N bhNWɒE|݅˦uhI-KQ+N_L+ ,OojK eka#GA/?PߺI3RH%g_}Ӡr>gagZa$[=` OJQt GYF38/I'ͯbCWtjSyo^jZXTD)1Ne%"hkQ~,^ R&Z+GAL)a&Po,d-zvok<4McԶ9s; ZdۅVyQ:5$~W/ܸ5'NRrU5Qg˫ +oDU!?J!+ˑoٔ/3=HuPuZs[C_?)o)ik}uN$u=cZ +|V5W/ojh,j:6> Fyz n0r5yBwu/3"vSKg?ʻMۖY3!{MD$_a/.S7eEGG2/ўz_~{}?ܶQԊ-_%u)@E9l"=ZH[E=P~>YAf#;SOr,@|?yH#֫ό:l'Ao nAPOG@B~]|Ś(T]@wn1ҧ.>M&`W'z)}?OE^ =4[v|ۍtۗwgnD&,0tl4cƎ7sfAs[h @o/o9N( b., &=6>2ŏx>u> g,HHI_su^(l[?m~{?g}89Nү!gH{U[><1_p~ewW{Ͱw c[7棹Zfc['О,gQ_;PBޥ]LWw w `k`!Ld֟`*ڂ:$+l&,&az4}Eodw1y_3@m?|`Hǁ1N}t,l: OFȉԤ4l5퟼I1Oy GZt@=€0!,ėx\HHw|Z` MߙؙF^l4Oبl2,"*Ȩ%YN8Dy`9o `it3{Zv =hFp-4\POJl&Z[Fθ8B:'ٟ8g9WYcwXo^^3_j#%ل:roaf #f&y1dQHC0c0vʒuc˾DQ#%GҢҫrz#Gڋԩ\sAǐl9[F=|mh.k@Yt|IJeaqF3c/~'F?#c'g,.iFuJ+տ_ҁ Px|kHҔVr`ʗcO@?uY'Iv-yNA{'eVCy̰(Ӭ k;ZOOOX)L@qBkm\}|l"hZτ1NM*n4=6e61|`G3 \1l5 h@ms\;[8Wө-Z)NY*MZ4IM{饍si8i9ôQoIQΌ//̛P +\_ +$N'uM, κI/)Hdq^r}v*wlw=Ÿb¼a;Nsh^Y ZCkusu{ex0xkhǔ˚8N(ݗ=zOOsMW%~ۥy˹Z톰iuvkĩW1ay+Z.=AG08^/L4^.CO֛ t(>%W +5Y5VVs?ikn D/ >E`|,=G7 AQ MT&zbBmB])?ц71/JWi0]IV>|/?=^c&z}4nO0[ LBD6ɡ +=bE7c, b(o  K?1߰?}8fE_`m+3!(gENm.)N9]`}p #X|?݄C~'8 +)Bג xbENĆkGEJUm iܽk:Zߴ8.TD'ub ^BwyZm9![3-%ʔǒ.'Yb0q9_q?O _ E[Y]/q2:Ru)vm2_͖ zMĢ2[jU)dTҚNanai%׬{،sV +8a|mF̙[psexߌ3f":XUwWrm-eM%ApvuaiEA +4/J[-Vrv9gdrM˸ J͸MPs8F|.%#t#xqc8FC[Ps G~RU+GS_ΖřfԦpRdq<β~G!JK@DD!HGQ,xpDup8kkeA@EAVckCi#*o‡9@{˻wį [[>bS״O[DH*N迥zvWYBcMؽG 鎰%}ߐh:-bEX(ekҮ;zٱP}mӶ&o 44fsuMm!1qx̿PO&nNlCW/vr<   m޸WUe륿d^s3NCZ%) ;9poK)JEz㰞ܧTՠr_@\G ʕ<XrGX5N %`CBN\YS_>㲷kfg:9dd֍84b֝[]H?;.lR r6Xyc"XPh(r"aN8p,Xմɶ f(bu>5J{WznvB sP-7r@O1(R .8@b RH(s^0}ϠNyI}H}oH}v Ѵ&@u  *OU@puhk"Y`MP M2R׮4K6'Ya:{g3U5Z VPPs +r?K{J+k])x+:x0T @٘.MtsIӣ;"Ǧ!QЈRHKb|r"QaA7w<ܞ7g*pzE쟏`j!3f1w}#7~_!a&~;ž<K !WS}l:d]AğA%k=JHِD y` žL"rK_s'w_r=z `.F#(M(H鑊?4.^%t#rbbM5T 06> {3 [LDaBXrLqcFƸ @G;GS%G#wܛ## DYW4[h7 +/x,pPPP2ΑG?+V"`@ܧ_rאVxAyN|N.z~ mi׵qah?>3 +(h23D,obx2: k#>NS6+"}x-\{D56nN :abOðO0Chy "X6fkJ^카IXk1KIA +( ) ]z3T=]zR=Oys4t\;.kxbHOi1Vx.Ө+_@dPC=f؂%-` [ "DqD֙驞NvN{z,^:_2~}W'E?|OE]4yYfYcp^xۡ^ˍaVwBoZܷf%rD}?=< y3xtgI$9Da2p+)m61l#ApN|-fM67:lWb>U/8,E_?ql!|+٨9D4E" d$ |oR^,Cxj;^ 6#h==e;jjBrJՑ%VbrQuR\i6aIy2.*\F2$u >/w }c;\+u@[ƫى܌C8yVL lqHJmw2vahʜ0Po<"p W]`fcз>؟1xۼqt}j1ǵ-IY2Nˉ7e%/Eƻ7m~NbѻMx OCݯ~_fsb|л쇵hJǘ,&|Ui8_2Oҟ֗ٓNtd]mܣp~EkWCPoK"됈!c]f QVAћMG&ZJms|_{ڵޣݚOm5.r7u92d9_ӥ9?Ф9A(8 u?sAV+Rԛ2WUqzK H]r{q[@)/j4| +G`=,G1G* ]#,_k 3R7q^Um&:ŦGq'dyȭLU'ԖЪGb\@E_PQ'BGɯp>?Dطdt<[DT ~{g)btK%-5NM|zqګG\E 3JKgKkAӠ"JtOPLݙxV +![KM\xNa8 5S Su7E7&ng5e;ʤΒZkD)) ~L`aō ^œD WPNt[ŧ[RCAT:<ڏ[Q[[iQ|V*n?^ p)(Rd (qᅣ3b2HTbUaHؾKqE,˂Lۼ<R1XIfԻ<b'5KjL;jL7Ev]^<`a CWJ9:P3*l|St3Q&y Ex5{]X˲G;1\#U mW2a!Pϓ0<3ly\?gsQ912 +Tdv,!1hu[&ɞDDC, Yf{_t.S>Zs~T>UQy@^qU^P{V(ʄaܘrП0H=dG?T +=Wv*5\|5B}7o¡:fv:l9X~[BbY-71{ʺ>{6s@t z,ܫ@`}K +Z>pI;P< +@GCR r'A&V}HDOsˀ.8M6`V( )$/T [ +?U0/Q>onwW ,W2$Hwy%:q,A/ `|l|h|IM(0b3KﱛYWxI*MRDj%B>DIW҇ &#d2t:љEV:~&8NW9ǿxg #ԓMJo"j ҙd8aGGbFIvгNQ]G*!ߪ(ɽ&sDX:@XBX;AzBX}aځd4>j4v;p2&Ixj2ixߌ8 3PkF[P܅;\VZY˸ T5H.YE !hppVm̥l xygK&PZu2jSpG= P7W:\s܄*v\Qeu!*%.Hhd5B^ 4Z9DKZ:^х.7tI^S~~~>Cz^)-gKsde|Y촾BvsbO"oatH/ +¸1]e+& Z㱯ZeT Ao4*%g'ϐϗ/68Z~Y~GrE甅 +||?fɾ&/)5сkg>P +ԴĵZTvj],(BR4Hv2hqGMYeQQƅKTt^o94n +w*5N wۚ r~;Nk{Jp5HN8%q,,LZPh`(^Uy1sޞ-Xc#zW6;n>e-]v# n¾1%c'\"KQn}(l¨~"7dO19-wa#|ͶT߯rqsꬰ\aǜ3C+ׇ9eMpL/GWP˞z[7ΑgDQ +nኜͶ imnSlQ)oھ{2"ڕo#>uYih Je`? cadu3wɈY>pv,?{,sIty{_{,YJ6Ft<ߋa .$3)?9#[`YMI}M2X`6q}F.+q]!+=Rg6_4hWJAcƾ͍OE2+Q2$;`Xodm/8&X!9dG٬6bӲ)aSU֨NwUOR-KQS<0/)8[f)JKLINȲIbcc6DFFwG_q z%8ED +DBs^<߮Lրlk3:{*sEe*YSd7J OO 1KITm2ıB(ycxzЄiHa~נG.qq $^<trۙYGV`E HPT0N9?K='sܹz9 %e&fELHoVZS(T|Y*Kz"Sq)ErA2>e/v39ST,Sl1Jܔ=TӋk$ȗ3/\lSfkb+)Ȳkdmw) c@@$pSboX̝ +9 RQJbz|,͘/t# JCCJVlEbek +:p)''Wy{>9ow{9s@I +=+{RGr)5׌UY=cHت9Z!UuVF/L4 XaWQ4ҧfԬ-3z]^~ֻdֻX.ă9_G{{ +(RrbYouR,]T?Ueq,/М_' 65kFuuՔ^{YO9y0rr9t{~*%tg@xFu,n2 7afs|U}91JgzcԆ_t] H +-`:\wлis@oQ劸p7kgX}r/p3ǻ&[|bdo$/'_K;u s = +L?&ˀUGn":4A!.32|{< ?<y:ֻ|??f݁t20 ѫ1?'B+өMsx>+~x/7lzExp+\<^Bi1aѫzr##04J^ЫO-.3!#pυ%=%32 x F^A%~j/ш+"mx7Z}m/$OFgE)gDSq6feQ}k&]#f{"#;Մ[;ߠ?AcnoƼZ(™`8)8G4qáMJJñ:Pepc#}FoccxE>kÌmW^;7ۺQWg6įñ71\ۊ~ W|Ig\B&0smuc,IUht u$֓R]:Oksk#lOkKjIMzߘޖŭWKGw* ®^U2W)>s 9=7}UVS: c̪jRRXe/aLkTrʳ.jd󁥲u|uC8o[x˨}sרx+.5v.K*r{i}:Tb*t+{ +5*^Y4rF/PGɠ¼A? P|g8s/ +8w9UK`{y(<ҾA+v2%4n5RNajKXbPX;P:$WNɕsAgBywy> +ybEwP~@:2+ЪI&:FDZNBUd{hjfIY%Pc*K +uO`0\Ӡ⯅YE +dED#)Џ4=kUa@5j=F`0S [5),wu«H_P+86&,fhIAieOio  )%o/qn'O, 1#͘G]`AiM+Hz>Vd̠+r= +s ZP˒6s%5]!Arx`RխDSAb囀$O xw؇IX=҇XMx\5͎P孋@L*i]C)jW;)hM2SX#ifYIVN| /x/6uOmoxb"5g;8WgM8 170"1hO(@iYU$e=%Dz>#I!IrzJ{GJ&_q/m+{C vTQMo vT2-Ë؃S{cH?bEZ + @ 96A-2l$-bK9&tgSU.rz:fHk1FuzcFo oq&Qsg1r1g.Mi + Rs"rq9cm-NFIMDK׉vV8u\.+s8nyy~= Yd x$S>\DbC D#D8x4iqll"y`r14;!_gckhYp~DcO|2߻32M$e ݋SL-ň2)B˜b@ AQ,F@'t3~%R:0SitX>쪵G6 u< l71/lfˁ + G3߽2T;aX;V{B[ gd 6͋0Jߜ%ҘK&So`շRf漢c"`cNd Ioĕ" "d*CH $9R xlta+1 vw?'Vv,~U=~?ߍWJFOL%`tѵobLlOwT}2f1K[^HF<etNk=K"=6ЕEW.]tб2l .m;f!s\f˝R78[b/ d t͢g=KYVp8Oɣۭb5γ%{y-#g!HWE.[f1o:[K"zҳditm'=%tf۵8Ifhc%1Gi [ɡ,(]3kW;<@:BLN $ҳ +g &phNmfqma ]4J PO!ؽtN=j9[lzt.pAs68m; 8am%8f VUGԙhQ6YmB &ԩOU:=9%UN觻SN-7W{JpEiκ I@Gkxvyhr_X:ZԤfj5ا՚zTiNRӉ~DMqFvew8\r׾kd8G F 4ynH,zO~?cch?A6QW$Ԧh3\.m\[!1iJJIvx_{ߕn* ^UA7>rAe_phC#GvT0jP QnhrInT,-ѥ[m϶*7ȶd~ Z:sGݖoDy -<}Wq;N7ݠ1nbSH4d$d8dt[b+cg2UcSy6y=rwnԢ +RoEF/ "=@MFkpSE;OGAe8zaW`ED?E BI~U~lkBȿlX#;"6+|]fx2c|}J&Uj9պC5%{Cz0zsLZþTFP>%1P;`Q~^7Q%n,;vuV|̘Ŷ1)?HRMXo:![.]:)Ii[Gzy^)p$ى\  +Ij5O܄1 ⬄ifB,cG)s{_Hr5R&nt\gp^\cO4l{Teǿ3U ZI.B"r2 ~0(^iBꚗV:juljkex)g<<2烙w˂{^"p2=`ګ˵6]>itiѡ kWkZ4qIIIzU|Ju٘rUWib8aSQ?wwEa/7+xpq η<i̜s-[3:uJXS`>-pqcRXڹJsHt+K6{h=-jY^R´jOQ,՗L L{<3t帳8#3ZӟAS fDU8T':] n\˜Z%յȳS|2_MO>4hU굗z=FPpe)mf6,il@u?uiČ UilKgy>IOg}J B[Ƣh +,EA((/6["r-1DdWCA>4&%KW'SDfו+sO)cs>Sf5 +,ANd#\>aнl%ݤq-_Ka*yIFY,14iTJi$]]\PTW&[a٨X^'oT%; 'Ynz7-y5gdUbvFdlXhlX` |RVhӊ2%BZY39M[wiN:v +X+ + +.#a7[GZIUP`e֮bK6sz]냠I7/cf[[0uk*DU&~W<Ŀ#'n&< kX2YKŊ;yM}@6 x05.ܯ Ǹ(<5؁t(,hbi7I_ҝd}`J*ͣ=`,|ޅ' >Cp| +, y0 +NC0dP$Ck!Ɂ/ߗ > ā'즳w3A-7^n f/AC~ϣ1@tܑcaL^0~{47og"y|LX +}2JK~mͽ?#GM}x1-w[Em =9L18W[ Ā +'aCIx ^2c(ɣ+%r2L#@t$A9~F-~B3??0g~-۹=Ǽ{Y.S&\->-rדo4yzWЧ/`oV:|:ʖ7؏qwp:_|vo_~'[_eXc8ѬOŚ̃>89AkծdLmQA9 BBH $!r ((7'R>Gǣ^;nݣ]v;?ke?>abChF}8o;´q!wikx1+:S:=Iǹ(>F|F`PT[ Bɣ|ZZ\{n +^%tQ4M6:5NW҉::DGCX&:2HBhq Dސi Lv`DBsц^E+YlDfҙ:J +]ͥs `h1@h57>y+o~%M1hX}r { +-K<5y\Q9Ot6TH^cߠïGhXiY`] ++T8iXf )jYMmրU1޲w$gӂۜ?s¿t?nc8A8H;=ɥxO(tdL:wQZKÑh(2ri ꏲD8#8"۸ݑ=A^%ŷm?,y~"F'zn$vApCx/ ]Ci(Mc/n5ks).gt9n^Gl}:]>-+|c bN 7?[nςo2Ʒf3Wo 0vyEqߑUq1_ Kh0amM +HQFթdw(s9J Mi$4'{|ޤ-u {jNxV^V|(\u@EOx-D f\e݁SzSzuWPj%UaSgs&7ߐV6RPZQTzvS])Wĥʏ%ʟd&O9|p=#:دދ ^};}&mȘGoQv95kX4NV]ifx22~uQG\zġ/IiImiR2"0_wc;>kc:t35;s/zJV^ũgps;.pKu5BgVXQbnZ3 +3.,_I?JFOb~6_4{1{wzܩ F :bYUvE[/3|KEĿ8ZX(.wI-9상y /e$-#in1nYf~ЃO >f!Y^"O|* ]Z:-Y5\((2; +fWl 5 r9A:à ]#NTHwN|NЊ;yYkߐ6\Tj_FN{ئl<-ק"0[MVPX/,[eZH`y2(|?PH1=jIOs?#?F ;=xm1L%ιp$JXũ;yaY +׉2mtڶOZt&PUnOTUHTF DSE]'tuXOjAE)2~.gSakdqGP;܉,;/rˍ,7U) H+m*(KJD=i IšǒbFhgDBcA;b5,'rV`"T3SGA95Qceդ3=GUW[ߔ*怄Mݢ؊qqL]qE1e0Q76BsZ(n޵H_%]Ce6̡tFMDRyX),vr`7ToD2wfrdQU2Z\B2θulu6Dr HD&!BYZuulwK,tWݵ~6}>}V4Ǧ4,fI}hymYȡӉ8h1}I2ײ9~fP[7 i-FlIRdDTc|λ9鞽sV{;"wxU|2>a7 F(lX.!M[.ϑFJ)$kQxEnU}z*>Q0bï+Z%)8)x\gnEr*rsyO=XhB)nY⡞%-W +u+'c9Fk8u)_:櫓#SkV\V@CZѿm/|+sZKVHWJiT4D/ſA +(udR@e3W]eW6Xm9CMisY):&o˷bc#ո |3Oο'Ŭ_)TIhYVKMU'Sm;jxbsՒd>ؚ3N[FIHp'Li{xAv_\qqcב;1(/c?By;ou6) gNn^~I?6q0N1y}8N8a{~dOIp5PlxS;a*9ZqF aOπdIyY4e-%,z'xi7ȧ;zFgQ8g4Y<6 8 +5jrf$#6]}#3 d1 qO:?`lO~O_¹|o(+) >t8<Fn6\@ h-#X[0^tK^=zݻwU;UTE&{ +v"n[/|9XFҥ6x?UV:񳈟K|XK2ʱYU^crIdPO/ &x_&pW_rJ^c0T(/& 8Vx박4.Ӷ;<ײ5/SH(MD8g&ZrѬ_>}Q_$nЗJzԗ4ʽFQޡveu+i*2qd~gCeO邢>^/ۜnlaʵ(Q2>dZgcK@-n[e3+mfZ&-䥖 +%*)Y6k +/kMaEf(5 +$ FAR爍^l"k +4L)}\p:QHzQ@bۤ{VQT֤,(kUni{ZVWrW+D3q~:hIHH;/m9Ng *\̕[U*lQ(6J$. 5ꬊ m}@fI+N+T؆x>^@NIKEC{5yꙂ0{Q]oL0 فq NAFy_IJ`23`(9X!J +֊@D:i셦sߕn$ڟi:1cvaL +1cFLjc o#7{oD!`'@s@{j]h7 ;ہgvЃ[ǺFaXStM+=PIl =X.?SBIs-/Cv;xZu8zss6mn2u&F(f2/]6b=|c&|zXys&4젻tRmkǩ۸QwI00'_䇨Oˊb>Tues:Ec#?$<֢W%溞4TdV1TO͙{(X/ 1KrIR`,/~6':N;v}IgX3ř[AڸY)%Qs&Sk-@tz_S49Cx_FD |4D lH.=AX+ 0_ u`~q|>_Zg%ot>:&:Ҋ{.6:5v3W8eһL :/߿1cH_FD}C]!&j^o-z̿c:X[&]g|pn~ ΢]k*#?w5{z]8ssA淌z)e +_!^Xw.a'.=>nI|o=}SB=vj t#V@p H pI$\. JQ,*n[tZǮkmr\۝]vc5*?>B~yK>b>|d gn*~3, +(7HG+_iYQN}'x?ENnq)eDK+a-9r/2'5]#1(8~oc2[؃7Y8 L1ﳚgf$OoM@p>M(QKs|'7^:袣cq6i.N1ۓ8z3(9<^R 5΋a)sZMW2]zQ@r:Ym^vz6Ov9Y|a w-Ln?\ć[ ~s./0(:5IGO=&zJ詠Z/ [_؍} bL=OKQ'~x?̟{!t/.xJ8x'cߌ1319gab{g1KAԍA[0 ;'#]pЇ +=`#6?YXngWp~J'թߖj~+U}!V?\+v_3wd~X˖5㬝PlHDgR,: XMCk-Ʌ%MkdѮRMҨ:™\xMH|]cc_rhڿ5ɫGvfg)@o2@t.@.i1hN =2(.ZIo]RUZ"mD.Mvԫʒ_)m)wekUWX\x2d;^Ʋtd@[ַѬ_hȎ'[ !\̂P&TbevTݦ7ɥ-k85%ҜqSi\iJ/IW<z׾xv!ޛWiɑ͝ P1 UF*B&؍bY[*oUu˖a)w"0T1r@〼;<}9/?M_~y^UD":#dtz¿5p9Uf*kPnNݢG(X\,2JfSдQ6nU )8`072@Gϻe}40&^\K:I+7g[WLTZܺv[JmjlZXm(b&],UKV"%(̢Ki_̷/_Ls?CT1{N+ׁ5 H#?ײE*e3Pj6B;∅ɑBF( w4Jt+SSjKT&\hL~)'Ģi0L3RuH:IrV0;Q ѹyhap%#ە,.tz1.%UmV$TT5??{/KD)!0}=#̟mA)5 @;yr HΓTO=9z,H8S'hܭ+bKH1ץHѮ{h_S5ҵ :.bIw9E{6iD_8ƧFO / q`*Ou ˽#2!qi91#!bD=1"Ӝ :Al _+{vO!x1̣<81Jd& +@`c.eQQ׈PkwM`6[ŨX{Z%9Mbѓ?͜{^) /\ޔ^ƩO^|r;@^fy}!-8/Fe?2eY1eZs=Zlюɑ3EK!I})%=mP/WV ɱ*|` ~VLd@#$Ǡ=@Z$ 4H.zVRYr4{W`uy 1?DC:qq|)įz ҉p>U@3 419Cz"h!Dd^Ʃ+Ǥ_B#4M,m!RK9wgZ'Og9 YF:57R#qfbxvwz{WCgI6t+]ج p\*\f۠xmhA? MSg%Ѭ8lEz9C;@$Oe:LĚҏv?Ѥh 2}jgu bm&F~iS/24{Xt&%b?s< +uD,w/Hs,E嗼={s_.~f8 GwhT'a{6Adc?[Ťb"t6rTIӪg8ڜm5P5n]͕^ZD=O4's$gc?n G,ab6(#>"2(1V9O۶%zqahF,eb"a?YY~RVj']Ȋԏ)g؝#jZ7yq8xۇh[hF#N;ȍVD#M[ )BUd}?ca-Ee ѵvgcm \)B-as`;ڲXqvQq@OQ^-a1 x NVzp҂+5D)K53h!)h!qqC€K遷 ?2Zߟ !jXzJYK1WoaH'ꡜޚRz>ZiqJ D OSrxË afôu)G7'j4L0a0! }6tohhWBKYKkg}tԼ'HE(5*B)Q53%GURD͈NPBtEgF&GU'F1Nj7cЋ؈Fc쐇pq.(47Y4M4]KR$ +a8 @2YjtZ6-;xu]MxU[Zj֞Jҝ!vey~im}2Z5$ TunK)ŪҖ +[ٲURrj mQdk5 +WufӒm8Y g̹!337ن&Fuv#]w3kYgTkM*xUأIQY\8=SnG +*H#7̶,ÖMG=%-SK2ӬK>wB3ﱐZWeӼT5V%YvNWs +w:r*YgtLӑf3f>mel$gXZ-ִyԐܐ9X>WkE's(o +"rMU+V9Dere+U$BvWj2ly+LkfbFܜmO̸͸̐.tEg}&sP( +-r PnHe+ L9SR@6wیDߘ[܌+ߜ]9ւ̘cf2cr!'dv'VdZ +R +AITP"0g:oTj-y)3[I$%z5דxOxjY[˗33=aN+{ٜR#>cF)FDo 4YexZcyzRkP}7)ޙk7U1^fzݚToEV֤ǍU[}Ƅ#Fļ3F'dDCYxq-z%?C%Ehg3k$+5W_1iFMTEbKdC|_nCѸtc ]WoXkOkLMꐱG赒k#Byv'V-n4rMT5?V7'jh?Ec +hV#uM=iHW8 _HOЄMhxlLٌ*n @8 L ՠ]OX~uekZv{__m@ywB2ЄC7Rri +3@* \<(200~Lw \4~7}Mnؽ>\Ec=9|эyBfx'}K +l _.M& $ߦ;Z:P>tnףڥ:ba.$ʬ^!?P:.eX=F~{SNq'(q /{ +?yB?E=7t tt?xPnGBek>Ɲ};;=Tpzg ĊB^kT04f4dž(/'~>T-](qb.&ۇJ{ፋ|͍ESah^K^݂ бC|7=؍^L-ZE Ӷ7J;玲1:qU8Zld _pB{]pC-VZX ~9"hQ;DVЫz#,WH7W~2_Bkz_[ힶVעVZӉF +"b#uzN :ٓM*<\lOқOvn{4{LƟMHIҀqC9`0c1ۀ~\m $ )Y$Jn5vU.[4Ekҩݤik5ikvҤ*ߞGO>z#x+! OEV 9UBF#-ddږ#ǟKʵ̼x3ܼȝYg8]=9L: 0>DTS0ǰji >Л|1Stg;da}ez9ג+l˖8$#^XE:DL0V܄b/FRCPOO=^)ŗUMt~P~@@bi}yP5b˧'ls%+م ~k +0ZVr: 7b@A.Atkv@{-~}xK?D!:%ި.39 %:0R< KЧD Ѐn ?†0B~ 0$f8 ~^R*UoUwtFsf^'erffX<[8(6Oɘ~5k2W l6"d"Xۄ@!W; +o4ZKp/YY} n|dKKd^c˵feOR15ymEw"`-CՀ6~^[ ZmDmhMi]ú낭B=Pg /y;|g]ؾANt8 |hmD . M68]pРil o<`!`ʂ^Lu#rE%Z̃&5J gGw@[ [[&w#+&4x|z¨ ♀} &YTAP:tMBFYtPvYŘAκVv`RCTsEwyɗ/ vl~ z-0[PA(tUTh?Ci_Qn.YP/3do>5EOimޓ=%w sjBjCPrC6$<4Mh%SP/(" +w}dzeHV&!J$7@'DEZ Tw'C/fRBXAFwHXD8|qy2T_EN )w Y!;AvsdGj +S~b~@HiPKJI(/i'p@j@AB4'#+-A9x>p{"=2gZ#k$F S =d71~Z* ЌDٍ}=CPF+ÜubO Gz+AZd;"<~o#i6lf<$#JiңE*L+#Ie|4M VI9-`w|>&(I +`K06LJH|}ߝzId'9!"Y'(Cu ssu|r mc "tuvnѸq,2 } <FAC]|x*&,bN$q, 9;Oqy͑,?3JL>v | nRwb07w> y5L&B4}AQuO OT]T4mNj&7(P8h>\}'ZJӷhQFq E%s*sڍBTW钾 ]P|>* _ +|!I#9/~1Yc+%DYl4؋ѦEMzТ`SNVmc../x gj4\q دnݱȱ*=@/hS~[}mշpgܟ~NL# K &H8b0Y((x` O!pTñY5/VrVmDU7RKzl`?kG- bW('O +[rJjU8,Qjuجb*?!g5{e,Fql'+o4:axPտ#U;2PՎahRSʝRU攩N3U\"yPW*iP㛚xZ#߂5¢-:x2JލYJ.ruV(OS[J"U9*tOW {VGr=hreotה֡ѧ4ugJu+S%QGJcQE'Kw{kX  Jy9 U{)_9eDiz@2R4- SyJ (є,Ur@+b'T'G1W8b|-:>2v#`*0g[!ȟh쬬OeWFH FM5h!YilUH*^!kM +~O?Vd-E~c |#5\A1cX!)')#b#ܔTc&Ôl4)ɘc95*8O&bE*2b""(, ad%BC, + qk$D@ /f{iRM5$7kR9NT] BE +3Ԫ`~MzWQySƇ +((ܢwbrq.9 Y TJ{Aq/)&S2OTTQ 1HL2¼% +A# +R@, +u",6,> 5q5Z&sĨM'ڦ5bM%\̻}wb|Ǘhl\5)2nFW9FNo6ͮv+<ñV@0x|_ϊ>3YӒ<5%Wц`M2 W!R Qoq1)ҐCFjԨI4,qB+d% I!gWh]"\MScӲ\h`&?5![cHc"48YX4&kѤa\Z4(uSG)( g?T`]A`:Z`M@&H;. Z>i.+ML +3j)XM5PSBL5ؔy +2Y`i27h@ndwE|yתW^z!sC=sek \Ck)Z Tc". ,*kOy[>!򴎒uNWf5ZnZ93ETy):x Ip <6h,r"K,,F_[&vjگ)&yvz^R;wjcnz0(rYKia0*3_(B55G'@TǹǞ8 )/@y 5+̗8;\q]$ |ϼNvp \=zO@]<皧778?8'*# + !c]`C'~rF@Bhxb1HsIw$ _F|k)D쵔j3%E^)eMYq305ɧs=>pƓ=^S2gOYqs9~9~9NuO33ޢ&ojYO;N+Fk0> cB)9Z=GG(<h1:"pӹY7s= ]Fm:}A~AA2nъm;adHI{n>p1(c8$F "~ +)Y]H2mW58kK ֟͜j7Bz3ÑvpGn#O 'qpL&L')OGm*,:-+^fn^KF:yu:Gco/rG(舀g"Sህ# TG6pצbY72Y"nL[W WƉ1897?:=y6qG`'icO&~1Zsv$iV3Kyr:]w(Y)Q96e;W,c2ʜTiyg{Ii2ۢ2Du\`-XH$X9Woޯ F/+Q,첹gkۣ,wzYܭpٵQ^K +~wi^\ޜ:yS7A^fu([$ק4oR-]&wzyFS_QœӚ\tQ \QM)&.ó `.^i_&ѽUDStLB%K5_D`4ѷ]}?׸5쏊+BJn(U'5pET2PÏ@g~V=\8M NVRШeTBp&= (>b^ՏުnzI+gYq]sGg\ȳ x|n[%#͍uq&b5> MӘEr5*Vlȧz -Ԑ jܢ {pXO鞺 Ҁ`T;@ +c @%˸·;V2c,ݺ#v^-L͈Q59><8kDĀa1^w «ē4IjqrN҉kjZ$BEFx㟖p*v?\/kȄѼczLʛ=f&gs9z#c<|OOxa~KӨdxc_g"|L0[mNQ 3U5߰-I_+w`H n S NZ[\7˯{|7 +rx>i%x[a  7  +y/%Nq|Aggק 48sL,g4݇ ++[]5g\8U :J-2*]?"~tf~]c:N5ݦ2} {r " * rYeY` md%5֤h/Uc&IkƦi2L[:C3ic~SM;j;}ys{>- +'#.S1cL>P^CF-[Y{ZaǻEm.2uOMvMvMo|E`>@d*$ʀ/Ip)cc&R&EY{t%m6V֛&w(j)bWy +qә'zx !N +lV(v :oa q.W2vcǫ->rNtRYv4t<%~9>Itn(N>aRK`Xa4P.]an<1amD.L'GxE=G9#¿ ^}Z_&.Γ#甉aè 0<0z`fq^8{]n-?nl7ѾA=-q %'셫/Vפ NV±qpZH/8#p6f!|l mӚugƱezȗMƽ4x^\W[;rFA_ȝ};G=u+iUGSVt_Z +&T[΂95Ϫl_:=PMnT 1ڝ; +W Т!_u$S|*wY\e-j.󪩬WNqՕV Ք,%wTQʋ* +,b@mFA4h~~&%NdZUsU,rZrXToݠ:O6jY;ez^U/rY%TT+V|*.4k\ h#P ~ԁ=]f[mirrTo+P\6{jNU[Ue> +3*O~@E2۾ʫUϕWHUQ]SpgD߂hPjC- ޱTvGjkUWDU*otSōUq*|.CpW2OH\Yi2i8v r͒l AS3r3s' pmn=`/YYA?+ǸxxG9#Po/⁚8)~亖ec3aGv^t/9+*08$K =!FaI;Bt>9G%3ii[juˈN-7X(_;\.1k[u-hD^Ə+2|+GwU:$6rK뀛` \b[Xk&36 @9u bl0`I FQu(}Rz7jzqfIn2nُKm&?}y +{yMuGz}I?>Ə};~?'‘GyzepTQG 6gPs`!˧`!v"nُwܣ=5Ả#pxHmpp};)8iQxҡ9XitZ9YD:/LK`c ʵ +kX"_B2 ]Oi,\%@%\up38%xFh U4n⛘&MLFr\sՠwPV{ /bJ+Lr*"aj47 _LƳͪk*&GüO+z|ztd`v,|k6!1L3TxMhW&z;_MK0J4gj|g*|Vi`{J낊<&W&UF4'|^"YNŗ)?蟠dd60OՁE +PE`MVYl-RQ*nV~^d{1~N¿.8rf鬅 _!dBU;"BՆxU,*7i|]* -SqX +Z46U ]!{&e(p\#ސ-B(mcg^¿Xy3d3|W?_"T*5h1QQ)*(J]1ʉveD-SZ{l|Y J&KĿdXp 5ϱ{lRUUK9?q*QAQ&LVe7*\,s2̍J3OWy͝kiw^@L1evj/7Ug25 x_ y' Qn0ٓF*,K2,6[rd(:^zYSd}J get).[1IG5"ʘЧ(#E!.x:XRȤfP +P ʖT[mm˒ŖQR%&d8\ؖ*ʶN;rV+20#[Zl/a ú5%*ޗB9 mJ5k,Y,Ul8EgW˘ݢ +~FYk]qFvKllsj 45:;HKc{AbLyA Sl^et*ґB9*ep4+ѪaE +d PϢ l@XPC@"ovy, "(Uc4VNөdM&h|Ljb3jDjkS4eיL:qs=y}2R +͹i=c9l..C԰‡ +,B[ %<{(9cVr)W!EU(aR#V +w*̑PG +Ѱ2T"4=J<|g4bN~x2၅ihtԒ h _g0idY=2D<˦!>RxA:u1ĜO< o|ɰ%X*X0*hgNZ_YCAuc{j1ͭA>xp"n-u:H5-:@Ђ[ց,b8,> n } L"{0ҳȶ,kl/w57y,j73Ϸ0#ʋַtn/.,C,E;^Mm>{)^wf{6xfk+ESw,&x|[#e--ޥ|/:5rt^9Lm>ևYiGɵritYr o|^_ 3*lC~arԻ R)8rpa|?C,̉DZ;rrŤ(X棉5c(_/syɛ 4BC +ѫU +| 8~/~rvI~ƹB\B[]DSKׯ|#zt?O47O,`>DS +o~.ǻq?ΡAE mu&:M!$oR4P(8> ޣLPqhDwRᘂy_G#}G:s\"s2~[TSVZN:]m6[h0aZOElzie)}΃3?ob?uO㰟Xx|leDU`߉Zl7b +9.<ب^!Dn`pG~6=Cc0X,%`Fdgc?VW0_=^>֡wRk';x5QuP%DN#h,o7s<IpOhppb&y\qmB6q~AEϩ}콂Wk&̋x8x]x +T6x*f[b1YEf764 +Ey2=C}YͶqm|W4W ' yLeRM2੅꘏7+蜵dgfPEnfE bZD\s?j ϼhU8qE5$X W6\ypeǃU77TA<=2uG`P?a39s_115CGLF65Di4MFIi֪1[MIvˌӎsc{,ufTlʗTB[57flBY}J7mŴ[#JIyCɓ5) $ i7ՇDZ͎ L]%+2qf$#FE *(ߚ\]vkr2'+++kf3[d\ SJX7)ɺK3+1Ƨ]ה`D3v7µ<'$Z@#U6A9sbP3LyQ)ǖ,Ele f/>M\Rr(ޥJoTmPcm4&u=b>Ql=Y4@<9`&$d;[ RJ+Lő*#S)| Q$GJpX2aY)ܡQ4"Vd{WQbM`,$@2YK$sp8dMp)exWƹ(5]&v+ʵD#ܮ{5F?Ұ; +s<bbLA 9Ow"%*Fh{6)ƝhweT^Vњm8|RelK;zR'l6>P=镝wrYϓ##T+:Z&+ܛ0/EY/'o7@@TqVr+OCLc!{~[;5`*|+yx_@@uZC "CNh5v _k~&J)N9S +k@"ikf~ ?_A?b֏lfhBkB5-6C::+dPijӉ9~Ӏ#a%..o傝G.1x Pbq#f#maKA z@)i<~xG1^R\nXǐbLzpr/x6\Ȧ؍XzCW"9p \@ +376)< (1lR̲Ec%~\_YMAh_+Xߨl+^lK'R;\͸ZG9o<8gX@Y,Y>Xv6P9x3ybތ5&Zgs䀟M.NI fxC,1[ ޝeF셸B6D- GJY/@D_$ $Ey(<{GzK!v^!JY%[m6 --&}ڼkg D`*l_c's3{Er!^'P$W # N.3/a58NA(o'h;l7uM( W?%x"@&(Hڛ$, *t 8~b5x&<'Dc+د֟qNsߎ.lp4ˈo Pu$x Ɵqj@Ӏ# _S. ㍄#d8pcI nrXM, c +(ԣ4aѾ8DNpkQV1J:8u*ZgS`߅m7خ#Fnlz?^ +xvq&;DLo7m`+~hiphNu"-~! ~|:@Yn*6Nۋa_Eun&o?dS^6:ka1laa1 v;"nWTl|NXʕe Y  +3ϡ?-Cc10&؎X'b?V8r""uᆣjF-Nӷ=['`Zn :}/qB` +\U+2rTcq8 ñk ᅧMx0ltRbm.lï߁ +"p6qeThE\K1pdxɆ' +(i1ԫ&>HFf&J:}>C>/po$=#CѷC+ShU-WURaS&?x33\q{@U4{&4s71;gi4\D_<8ʻl.MJM6k$k$&@CHJI`)MJ:LkAYE[`@)0&ogj<~=Yx_-Ԣ /CTA T]QE+D9I[d*ۈϥU24j:kTy|"wmmQg)jFSƘ +>RuaՄ7:SUjt|yV4lJLT4;MS=Ǒs3@7脎򬅘xUlh.&K5|U7"VMv,G%.;v[gޭܘʉ> g$AS8'6y6 +}ok#T)HhS>GeJU ORIr%͒3irVa٢ %*[Yߑ-l#h+W?>w8jAڪXʭƨjQծb[<m*崷*%}2f[.mR<Dz:ԷeIXIM\H\FWx||SF<%xdˑ)#ObegˑPFXeM-kRXD&gT\&P)Ť_9b53<ޅAAϽS<9ÕU3Y4e*=P<@)5WqyKd۠ݧ +ySW֐EN4:S!pq)0ZvOR=YJ+SĢ*5*C梇43['Yᅜnos>' +U̐TPrPO9jiфiD4 GP Q_g?fPJ795L XtTb}M W_9k*7s>ZB"7C$18~zc}!X>y0>f\XKl{D۴㯁|\Ag$_C+DXjHXF=Vjzc5Z̉Rww4#Zlg'uo~M>|_h~,+j5FH&)g荧٫OOa|+c3i;6?V'u9Χv}"ig\k>j|gC|쀔Ko?_]$ر!:_Xrm=,Wm@}MI^glv($N~Xjęk̰#aN^ā_HCqR%2<7} +x 6E` JD);'9_'o/@-rv!ӿW%GPX9zQm ?K9(LNXz=o!,{Jҗ|(Z_(`@o32z srruf}]."Z(N)AY,G .Ը0݂DKD| +35,"m;j<q8"A]3p_IN__G| >f_kG EEY6O$c"jM9١Pr)jL ("C>K,LƲEU]r3 U$=S*sH^t$iT5Y,s;kaƆVoŸ +fknfYg9 Ykrg/3{ʳTjݣbafSAIgR^yCy7t1i($|fփoǏ?[ͷ˓_*U*i2{JC*ݾEݲ<$k1eTz)^P}>Ang=2xI@ |ǟZ~!F% ,ɐ$O(UcaQ;Sc2;^J-KN(U%SB%^3f\ BxA(sԕbW +]*p( Ur+=Tz%S B:*{ |ߡjRZxoJA9|oIR~Ml|xT*S4oHo=JYt:Áa^C7FVqCV\7 hDA@kՀJYzAdKT/Mi~,b%J{5H0?O!Z}܆:ֽpV'IN6HenhB8CkA5İG.SQ܀~f=ߧ.n7hM V/5]. JiqT19< +(?T%@8EЊ:iah‡ +*x[Sgv9(g gksSZ9|M&IY@,8<] ]&pw :P)/A?\v-7K=& lf]b[D,zE l1MCO,~?@ 1#Eع5C_m +ދ1Ûd5..>\n˸X}!x#k||eWC K DW+t0 KOk/z ݸW1Xc>Rkd |O]Np>Qnc] K:k%~U_M5x#&80E:ym߂Ӝ 9C1Ͱmن&(73mB=jyz9 i&&Sm5E}>~jc?9Ob"}b5az县 nFo zsqcqsLq7mm ݸ5>Sp8yy ?r%'_!aQ6qzqG~{v6SI&a\"b'ۜRrVC!b#q)懲=7ыph%i[Mg2oZpl@2DI6r g\?B]L`H~}> +{2r58\ur1,Ab&30_X߁sٷi)s, -5Ξ~Spo.qNxܫ$=;q >c8|%8 ڟ.KkcjkއzM]~U]%J@50om(98,dJѾO^Xߥh!y%i:Y,Yp&n>oŞ'|uJ2o4?ǟ8ihǏ,7$W$ :IzM`D?\3l1OPfpA%u]qmҦIIۤifi>ڥcծi+{vsŹl 瘛ۘt +'N=PϓPQ)__~{I>#wk*xkU¦<%9w\}'mCjO6!X%1m +eg;4M)E +豄QxJPK&JHd=νnA,4/Ic(A~7,s0{{ +=Ki@n)"Ҕp5n䫭v㔔M;>8PϢE +zd(ȠmFK+u2wB/Iʔ6P |Ez,hA~i"r-dF[]#a+oCsD̬n2r+W}T/(rSknY?( Z@~7!wh9< Sh;xo'k3V$[vKjUP֭bFdxAp#G kكd( lC_$ $Z @ޓoyi!ZVcʘ<$bP +O%7'FhN!߈FX ~wŏ -O~g4|S;ܣ%mz[B8'hDઓ.iۘbX$t< .K /C.j0~L1 +9lYcآLIUW%K5b֬'*GZ\-0Jgq # # }689밲5j0q/ Lv\ܡ /F%mo=BT-Dhz}/G #_E1LA?X`-d '0$npJ _9|!Oi&!CT%` +,EI KRWYZ Ut𽅳FVJL}FZRk.%2 D$` +K[֊Ϻ^JΊ˲K,i>-KbϹ*ƟJN ;i|'h{#gq0:U\i*GV 8^"JRZU܎.)v ñQ +sbs,qP̎Sk_+bCdpmb] :@3,>aBUO(>W v;$E8)>Pe&).I"s MX d`c(gqa-yG} 7x+\%{Hz~ׂj rC⻣$XHN\j1_Xz5p`H+V|efa-cmM|p]<(jjH0X^FU%B0?Ftf:Tom +su> Y5[3w'tkgvTe?zAlI|ށc@A^bbnrcW">^ܵ&ƿ%fsN0ǧ/%Q-; G~9M''q Kܻᙚb0=_&u-aIݾ_#X,C1.pPEe =ΓO%{0xҎ눩)z~5n[^y?.?jPC: 5mA{Pa"v '_BE3XK#1Hm.ݾwTwTC}w?S[ Ũ*}.jYU˓Z^~K& kM.s.=en>Gu޳|WuWk-f҈|D~H{gǾɟ.ɧX=:,mlI6&i$6 4BRh)TCPFAV ( +SQQ3^u@ FTtQt}3dw}>fP)jr#Vn&Ÿ4?HkSoƯL/:9r0[)[E%9xL3m6SMSOdxy,Ѵy|M?Ďˊb'\#eKc}Chœ7u8]/Y:?CbLdQZ@Ãb)>vˎ.Lb0Kܦ?ǎ[>|iQB; . Y\ߋS8ǥ&k7Ь$:MK|+#E~7zRοx/+.Ҷ8h寬˜'͋[㲻1.ťye )ѭwĉ/8ml~6z:s\Z] WfŻNS "| +tPWlQK5j$TBϭ.z?d0fqk]!?iSNV';Eiܦhpo D5jZftMR.ut+ٿAرSEnr6x'w\I%O[w)+"O;Dh6]8zy>cľy+;*g}uד w^| jW-:FW \P uЬKڇc~eL]T6]U^ȜYy+) x9o=_ȿGܑlqӊ˝PՐuO~#UzVM:axυ[_|.v+3V2hI&ޏ#$RvY, +\x:À>Ox!BKv9*zIsvN$q{] +#d6-`E# exW3v\c8V[(kv賜%>4ɉ8 ?vx#$2#0˦nt* !t`iE-"fh 1#'jhNVi>;G .ϔ+~}T;x~Ů=V63&Ck,$B6Q͡1sC}b dKBmbUH'և꒩PY'J3ryip}Ou")F`Yv+빦ʙ"KCCY*dҡ!ԔtYW.#|e(KJS!:- 3ʉ2ݨJ>ihxx6GOBr Td94BUUU<,R-3̮ E!^JkÌ&NӺ_5ZņJ6P.cx}:7 ̃NkmBg23Bmm"kfҐ*Bi6$3M!3~hz~z05lH ^{O;I =Ch]#[6SuPIT}26DS*hfdxn_rt35ج\jv،wM~0:z3[ؒij +R%avs"$UA hg:(g3tء v@tV6dW83[Q2.V5p)kl,iS FEhz=a0_={ϙ +ܭ}9zl{;l7ảvnRߕxN';k}bpywPN nn>Izs:I1a:q5s)ާL#l0ĎbX:Qg1ʑQyw\b@14-2,4 ɇ6&{ea@JeV ^Jyf;yK5ebR3wڸ**sJ +h6f;Bma$&JX ;r~5xSx.2.V.uvBO8 7zXN֩nwU"χ5acG7ux+'\~_ MדfˎIMLIޭRSԫr=z5a([s%GDCףcQql̹)IH*)^@g^t:g0 ~yE v3,|lbrU9?cbQ1朊CTg$V`DžrBAM2j7 + -w˫='ݜW|!h0 +ҝL +` +17Q}P߾4q[RV+)*Ύy?UMQħv#6D?җ +YN;k\p2Seօ(D ^ ((rQV@ٛ B @aɆ/z\&"W<_$c[Xtm0tEMPGt&z(JyA~`O 7 + n޳΂AL$/u\ܼlq]iϿݷAbGvԩ2rgΞSPT|QUM]CSKݫz Yްwprvqy>w?zOžY/_&)4bzFf6)'7_H)PRZV^YU][W`OLN_X\Zc c:oF۠Ny@_!~K ^#0 +*p %Ё p(!` +3XxpE)n^(qF=BQpX$%y(J +B@]PLJST85i}:P :,ԇ F,i +UCW(kد? ?]fu7/zaƍ6ok?nEvM`Xf]`Tf56_YmӨ[ I8}#cSsKk}=x(4,YdXx@_)~v\DPzBQh +Uk_?eBhYq^iA`Yەن 4xM0&5Qkjk*JJ]$Xt^[&aWCdȐ);ƪRRnV1t_ Ŵt׷PʩՅ5rOtȐ. GdI OUTxWÕ~֯ۀXf\hQQkC}SU* +awKayAlIRhD U\o>10]FFndV\oU]mVF ,cwK[(?^Rp\F|^KӸfP˂^N-E1n4lY#h^]i )됛7BǝYn쮫3ZkG2E@N&ȫE%@<h}c[Km|nS1*CdHȊ2%jZӥ:VS^%fO8zSF[;1޻PzIh`oHڊI_Od+P.W՚lͪfU TX&ЊndKyP};c1rJ{0aH9g$spHAzXHU!ibWun:MjIwGN}Q/2YaOICߺUd!+  xf˞u{X6Z@bC:(( E*E ER $ t(EF۞vRqu*J3lS㽆#<0"dža;50T?T&(x6O(J/ $}3U8Z\]{ xPh ,+XL:۝S澢c(U%3)q{Jޜ߻Tt|xPpN0z3?y.4m_ND֗:5p̀ǵ5ir򤸭$~Ȑ'2߳HW:6բ,/Sն ꙾i5oQVcSqhIoqNh2BFlKt*p/.wS«m76/Q*l=cwu@Ӳte}LʢQLܬiT̄]Fs*%"8  lՒ;yRaO2eMulvN]IX6p/*d&.p!g%s6s Hdx6'MC~f[{)"(ga +hY?=(0 +Y \Fb|>:y.>\b?[_u;"sQ&J2r2ƂHе€CXz岎q~7v50Pz+7![wR?W(2ʪƍ{ M<=X8#<`~^ سAths!̄3RX9 !pYԮyu 70qS=iHpm.w<,XXUK!Hpp[‰Qp`0Ϻh+ڂe+0z̮Ks@)8]@idJ Ntpr値N21[%ڸ.v Zy2IFg%R<))rVzXM {SFaaaa?0l4!]n/t +XWsrGfՃAi#rƿ?~^΋Ȭ %vW09TC3 h%_ '%!Cv/]: +oTe5WȆf,ڇ'_e +*H!=wG3;0çh+f77[!dċGXEv9j6S4^ zMu%7phcv7=+s : Fl!Kdx)2 J?];LXePmY=8>) {2CڒcZX IuO{ie<t`:6wn )^-&T\]4~X݋A+ҊXL gW''tVZ gkn&0** b;(3ˍQ0*~H*Ѿ3\!`qDOPD6tZ*+^Uʃ;DEKC~9U|,:w^E,g\8^j{VTS +ZTT +" DI  0 +;Hd$B !$LRE˼{OѹG92jgt\{'7 VuU:57{:"> 3iؗU7^2m3wgCPzv2k*w{gu\sOg&ՌQ7n$-q-ECuA},2%w@ +6^*H*vM4j_q.e,%Ns_Y'Gu9B>ͿÕ5ϖWkio@K~_}o8r_]>=~m{YnHalIfk aخ +PD8 < ݲ"4o/ POZex# +ި+4/i1ֵA%è9IcvW~Cn՞uN}<˲;ټ;[(PpXb5I?]OEuu M-{ڧ[U\Ilej42+`!mԧa$ 9"rھV}l_uYPwRܸS٠ ߭&=߸\g|2rXD$bсϖ Dlh&iCɚ +(#OR}1΢nޒ6Rqbbb?5eHO. {s3R}01Y|i:3$2TB)E:NlǮ*q@o!Ie* MKeff%k9@KKL .{)6w~CK;MX#N*2H~"Cʯ 1(T,^fZbfDCzw BO<SG"*p!Ԇfo ڃ*jgӰ{ |(Ю٨T^/Wؾ--r|6E$%FV' KbrZZb.o'HmԿ s?@PrJmkͽDMW? f +::kjep4~f{ ϯc I"CƹPpf//n(.3o}y 5Q:^T~Z 9!ɌnV緗jy! / ,N5H̳*F򩵺 +K,MvSMfQMdtA;Gg&ch"#:2X]IXvD4!Yd>h?~+Za+,orNYQ]/RɾfYR8#d +2 IX\ "N ?rdAE/Ԯ,ptgl_ 8Qz$]L+Wd2iad?H&'t6MB|DK8,=^8Z(ؤvyMdHok%5T;ҋ=l,;=#O$ch]䆞VGX4'N.7I"Cnȓ¡w kS:t PBH:޾ҭ*̠>!'QC:{g86fgJsTTըZZURK2"Jlڃ؅b-bDI5qj7Q[)Es1|? ̦&r~qҰsCJ%MgfʓZcOތ| oLw̬"pX_CbBwxtsC$XsYjwTuQ[S潓H5İI*jwUP,pn9-Ɓ8 ~Wncj&4ouQMF!UCɅ'eqmua]E-鹖-̝5M6cP' +(cOp"&٦/򕹐j*䴚uyڏ,]Pp3&)?~yY[vqrq8m2c7Gǽp(Ì+mX ųM MIJ9R(=gS{;Uq߫˳7X:6u36׍—Q6qs)n#7\IJDTqz1rD̽=sFzx1IٽūX M"En(|Wm{`#޻D;-zy'̅fLg1EG%渒ȷuUdXv t4-HG?g2X{m> GB:^{n!8|n!" t>D/mVzGEI(`r)7uB@0M} ,x@;]퀈[a^h8Kޗ;{ C9( ʲTPU +kd=}w0z(_\-`H@AB!D Zv"8_#= rǣ@T.SG`k&`!`Սpa7ICmD I 7d# +rΚ#1! /3tx.낓mp Ċ6NݓaJ VߐyRT  6bpV"INύhzP*e?7tŧ4rTL[$tĿ'I*@Oзo"D jH8zW Dn:[oFy9oןS()s—}KKڢgS;?i} e7LpKAoоQC趏mބO@MY`^C&Iy|bPF0yλ"mؘփ=p*hu.IJ@趏5Ĉf 0A-ߙ:P&ɮ gs33k)+oP4/t:1}ɵAO 5QMQЪN_:)j9vMr<:&prGaLJ>%ɾ! m!}gqp++bICӥ y,ITSDCpc˿1i*kC.xLAe9!кUg7}n}Ai_Ϩ"gR[yL!#l;s|^MFF/*][ }ljm`v=l˶{űQPKG3qcJױrп`5hޞ3Z_P[\@*a[fEoouuI7vC>C"/Oq&/h8[7W9cWUߛ$| 5D$-?T~l1Mԏ\Qr%֮Vj۱o`ךqyK꾫\SmM]sO[0 [GF;Cgxa>c3ݧ#(N'ifcUcm{ @6YfM:{P7-uWT=[EY2M[s${ƬXBH8|i.&q6>9r kM "6"iAxE#"em|.)fZ2\5]֮7ѫwBVBl#(w-~G jAjn06-0UD>ӉpY945#AG?L8ww\ \!bж@tмABHk0RsMˇS3A~%0Pkj>`xuM᎙-߄pK+YYAZ;HY$pl+ N`PU۠u P`|,/ۀ58[%x]1f20mc1XRߋ C8m͑ -{!w$ ;v d-D ,LV:c.g }0OIu L` ~?5EaF 2  +T v:HÍ`vLFZ e&Wj}RP@,^QhE 4 I_,U IfP(ψTr(o)!:EEߞyw1߼FqCA7 $~ 8@7$iHA@"Jw1C=] ) +]o|1Q(xkd $.qAHS;d94+^9;)yk.8I ˋ\F}B,qyʔ۴ۃn^1sTA@y<6LiE ~7b [!.Q2^_aMmUjV닳PZWEQ@DePD{h0l@ ,ɀ{|N]6*^Q}fHydO Xb4hЃ|U()tA?gC>bF6ټ}kz']GlwYe3j )>qrQvnh*Ô38*6A+Dčaz:|0$C !14ԽƏog_/:=0B"&(1Inr3Ƀi -}!茯lUKZc:eM2eNR5ʕ~|_A +V#k5axpUmBK*aH.酼w Ur ٛt?+l)z*wqD0Bb,fS_V&V&eM*Q!MW+Q!gG&y +'oJm'NL(NHzh|+ Cmy|VDNL)ɵ5^%#q@I9"-> b(@&ere߿|:~`ڋa9* 8o$PUɬj\@W$gdkJUEF,_]2\EJ _p,߶pt-(}āi4GJbIYerZ%5G&g3j Cr|JCE#–%2e6_YO}q^r^Wd[U@j `ESķ1,.9M,Η`2,. +[s!8/['6 E[._yQoyȯ{uxw7xF4\JQIB +eH +yż"(/ˑJ0*(4x&`P?"1b(F L%@ӊ7_W={pd}'q=/*8f9 +(Ȓn\j*"Dޤ^Tj #RCDPHL/m_6tǁ=12lw瞣ݎhuoTu%[J$>KrXp:Lbu +&l@ytXfHKİ7~[Mۖhe6ٳw^Т_̶s{Ck +hP_-%Ñt,-N +sxG-PՅHڰ̐>k|1l^Fea:ݾcoǬ7nj%DnGPKau,'ȒD8f)5 E:H4Xs;"3$PbjW&@daˢ{CW>6igw;.\i/uPZ71f,.|V *P!NlHd +b`3~/~t:q?obgOٟN80ƒi~Aᴘv6ԇW}R[N٨ UƀzoҎo1noecV'Y~e3'}Wp$xlyx"=I=?ܿuՎ eW.x+ +ҵ.FL?-5_XZ1_?M=I==2ܘ LA +M_%ΐH/X s(ΏԻrck)SC}]'fPëkDȜ=@;w͙wMw ̣qA1'\+.1}Rn ʳϿ9/אfi }WԚ@sk?-~ܳo~:jR p3"@`@(@kW@"H@(oPq$&/P 47H`|`3ǂD8 φ[^ 2Q ^! !SA RHM*bcU.m +X`ͮ` N +\l# +a^ $qX u$g@?gH]0r C}3#X6-+ε `φ`Czg8\$t.KB?3l&;031)(% +u*]"%:HH}ߍߍv? .VcxY;Nv s~'PWuGOGO/ ~ʄ%i`4;V͏uQ0 {MNphQp1sui 68axB6:BlGnS=@))`0-hn0Np;#'8Ap2vוab'Llk~8c|MwCf(̟ +Ddᑍe$6d:(6@[lW3Z)f|Ċ&0E!KƨЇg1C/|Gu~$ofM `ڮa Lo/4GJ"{.65-Ũ#WQoB_QW%ϋJΣpl=jMso99:,2N#Wa;.bz0OBn+`  !.yE?Y^tAmǿ>\;CN`52Rӄ5$~^eBJ(JUlwqQLOaY?I 10C6o_-+cZko_qئGsAؖ4v%-WH^HBH,'P+Ą>(_+H\5͛o1S%#/*,^i[ئpl\ZU&MT v#Qd|r*7Ttךaѽ---NNW=[Y{*\b:!.xaFAR>C,Keqq6ZP?Vze4\6C 3^_5kÎ{:T~Z!Uѳ#8ezqBI)P, >D>V2]A)B @i4ux`w{,XzR|"LzL\N?Sd/kS +"B-. UK47K~C1Jt[TZp[d[82Y>3f2C$%-:Ϋ{iS]V$ q΃{>x?~^v~*Nj@!@ ή CMFo:ʹ^vw.ηZ/BH9%ڴ2NMW5F^QyC9Fyu [ UzS]RcƠyevOsoE-x929%;"]RB?zX_r!ůw=>\sF(FpbU]^4hOzo>uU_u>pݧ;2C;3T(n'ۘY6&)$e, j~ڿI_RWKp/htB-WAC!eC6Cvt/sހ>s}L'ed ??|j~v)ԙ;/aP]MPAO,F#TZV(Mʔۋ6 +KgPJSi1+jC㲄DYQ nItw +vZ4@u Ti)ܴڴs{flgΘuqz +fbq9b;#=68/$F̧RB!QpJԳS 5V"yAwfWk\ߤ},+ޘ;Dഇv9Ā@D&3p/ҏ<Ap`/xN ji@{ thzcE7 vS!n,p"!6x!$'_HsW/(tPγOU[Q:]~IiDJO|E7fbUPE;u!kjeӜk1+s(e\ܐT6 Q޸⸞ +Q*jCF--/5e$6\L{+oG g1XIB@$Cmm^:Pk7t5|kQGo^TPwҙ&˒$(R+l)yɮ`Q3f:F!EMp=27xB YGD{3YufoӁp`gv - xo[3fi(;^PZ$<V9 E՜΢{*Vf2}!o]Et^2owCqɯԮN%Rʑ#"NJF9:01e013fƌ[B~n%E Wm;y|{(ګa~: +CNIyF&ch-yT).W_RP?+K.F-Pӵi dۖ@үx8b1_}ny~XЯqN&L 7i8vvMSTī@+!,5,*J*г$5C@”5ټ9[Mp闂}د-;np9`AH`02D53ѸZjzM:QE)KJ"a%'Ř0-3/Y@l^c(޹L]f]Ϳ;os_QpCɕ6 +w/ ^A#eP2YJ"WIR"\$Tǩ7.n>{? 8MulM>,}[u|aӫzgjS=%A&^|J ^Ti,I'$|Rq>P/ezd9eL”Ic3 @!U@`Pnet-F_yaEsѥ:Yt|R&YL ++D9JIVƠtiq95}RL%ry6 5w7Ū& fmv[OzpDG+ՅqBHa3<=S.`T]r"㕂@'Rgr96iH[mPAbKu6ݦc8q|gݏԝ + (rSYx=Y"' D[@`e|*+"eR9oB0 h:>5;ƍ\U.6CCDae3K%slm`iQ/0v ~C;nw7:rؾg.oV߅pjX+ḥ ]zT%;þQ zo6ֽejiF:c +^+:}שvNㄭ]uw~?;qΘ7}|a$8:yzv5)f(5LD g CLgMLL9O۵@2 u H}Mh{a-f.+_?h}sc͕8㇝ E¢bUQQ*dB*))DEL0OJS5$7Ss$ xϑwi,}0V@5t@k>[*ceT.sGwNjX{: +P# I! k2c>yoU:mVo @k?*XSrԏGOb>9y<髟/G|B?KJ@JPoUKW}KKCxP0fZ+ # 6 GW( T^?0d!#;h=< GOQ@Gk u6B]ئk^܃ خN 7oC1c +Hu%p\lOCH;FxlqPSћP!Wļ#u.BK|*ށ?Nx 'qHB́<@62⯊cP!igaK#j\'5RTE{Wn<ǵqۢ;yO) Iw@2XLZ: T[l';~ˇTF{HCDJV^sh&%ŗs~#]<&\Jx$~Oxs2Ԛ@2@8N Y>2]fvx炑ri0^JWR&]ȏkHOYYG =Dp?J|Rz;rM}u i+Wr%aLB4&La94k,A>P~ppؠ?ȧC}}ͿT$(Ok.S[o&-og|14t9fL=rc]]~.{=QS0YXpt%* ǪsN9pF ӑ/\c A*y~u3Ol\wMC۟F% ]s-TN0G+ʨT(ku3ɗ4XiN *+8#2A|p Y^iPp|e s-xygE[偭K0 Wf(qsji(_^%8hʹOpr_ł1144!7gT8jAN)՘6p+_`y͠i=g]^haÚ[n RC7u z˭J+ҌleH] 9KkMN}צj25ic4ͫt0Bo' qjWj&ٿ]r_˱K4z.S-eEj^Q(ѤSZu,lDf f`TPٙBx"NoO{~Q~x*2[},V^,ORj:Jup0c.~)7% 파yo@J@cLlASA^Ӈk#eT$xvA6fh|Wא.tmQ9_R :]l)= IhȈ=R=>Ǔ944]Y2ω`)xtMP׭{u+z Tސ _[er$'1}<ûD!]؝]eR˚8zxqn/c&3 $@{ H΅PݷN_To^oo18"C* dB$_^?cI@e`cQ<Qp8[Asy8y%:ܑ#ZƏu1 +eC<Ķ~Pl`<3;K1QqusOM8ۗv'h;RΔOSzƚҙ3TЯN2r &ofoad6X06.Xh'챆fS{R t J  b^anPB}h"-W]t\Alf`+h@t#*[1KF&4Dy=IR\0uq ՅhV+H[@ծvB`6(ѱ" +Ư#cz3`B fFxf^TwpH3 r\&/FEB"hfjNhACۥTt\fZAF +3Wb*}bP6c<=wN<NC z8 7)ڠK4V")ZT27zEҵt /[B +y"i%+PB_J|2v3S"79%F>amȬ1Eнb>xh>xa>xK2>M#y BWBoC߮4M pBZl@T=SyE&)7E_͐}*yմ}ygW49e-e}2.aLSH<הGoblQB +c&JZA(ڽ} Q +fe3o+SI[֓6_ld^k%f,z.@tQ@ ܪ;1F\pWC7a`>5K7ɣL ZNzx^+x/se(":*bԿtwTHIh.ǹ==<]wmku]DHK RHBEAAVYAt.o;37o[C']GW}ypM1cv&K}CPK{p(s tE:'oF><=z!vj nb`#gπ s;=K׬(p$ x% S&1΀z5?*G`EbwnG^"?DF}10_ ׻A=o<(χb9Ձ}P084'lɇ4q"!s 1F:4 `#F;Ӎ8[ NݻɿlyB힐a ȧn97҈aJvrE>\uBOCec1.SZ>Z0ֺB+LdO'ȰHhe7+Vr⟝ZiȈ I%c*q%j!ŬHdʵ<4S)6KEՉVepHC%2EBC^dt}'̴i3uy )m>xZ\X+is׮x;u\޵|ȧ2٣U/TDK"*Qa$yߤs 2zYA1ZUDcwR~8 gM(y@$LtG3B$vM`tGvzַhi9[tpv=/݊Iar+J~BQX'(b +:U*ldbl;u2ݑP +&v  _D$EU={-qC˹Z[x!^|&W"21UUyXո㼿= +Ž&H8$|mӲ"lټJAC|_d{/ne.1xX!k_Ag`c>./0r'e׃OpEcQī$4'&j!Fj`q;89! Q~C6o~MvsNL߻tgTYAPTPE0$41IHHBZH "{Uq9g\wmؕQ ((]@³~ tAaB+W&U-U֤ʫ6e$Tˌq,[P}#W]{ѝ6 X> /=Aȵ? !'#&_9&ۛ|m66L/m\඼1Q b6( ,@h,'4(oڣ4my+OJ?_)uWtEݺo]n4}?9m7[= rW *JSLF?wD9r#4oB9l,KȟTCկ$d5![k YkFV OW42d<-2k`;5"*3-|'$B(f2Lh,X?7 ;h!8ЙcD7 1u*BCbeaq:\Z8DN!z2)G!!iNFS ffz8< ]rTxF5!u6Ban8Ep3f΁% LHZa0 h/'yCcGnMqCX;u&6;c# ^RR@ AFvYp4I(}~_EGş w#-|% 0[lbh +3=̑e }dOB: k\GRr=4I|[z?1{d #!_ _ oI6559?Ab̯{4PR$Ԯv3\Q[T"Uzfռ]rh+.d<>sF2甾5TVdH<(O,b4H2)ƣ̉\yh4.m*t o\[YpTyqGw}GE}eq3!"*n,=K44A:&}(S7 euMA%+HܳPjAA/w}wú + ]vR#Cn4ޏk7EEz| +WQQ&PUk"v vj,c2bf!'2U'18 +63GPgԬ%]`d#2"mģD-xlD nwao' :`uIlAm*+R O,I)(:E)h4fG,XaL#:DxXxX0X?Р}C[A]Nޖ njzʭE1"R\eXQ̈*W#ʯpʧe:1Du{ct p`xd tj2WXw:q&+\JGoN 5 4&E4HU={@XZD A .S)Vw:c mhOzQ]y#F!7A_+~{|ٗ ]ʈU@瘟xwyvMQ=::?|QO"1 ևJX Fz.ac_P=%afKmNrTpˌ5x6~4ܑxFJ=k"G\G]GE P3Xv\qi-(~X'yprK}/3XǨ~fS!Vv!T Dׅ<_ɾ@{A/'V _qdX F[.]O9‡Z  cyݔyob漎D c4hx`fպA5X gU>?}?@#Hy2h6Ns",%N3 !H3"$ +pL0,b9.oU +t'`gyDηT#K[`AŠFhw3#ٓA30Q4C̵N@ƒ+uो_]Kęg +\=c͇x}P *tYX_b#3%@˷j%X_5ƒ^T7fwWc_WeezVh4QX2^pL ,Bk @C` P[m! ua,W__ ~Ӿ}m'}gl'|l}f@JAf!DQ6pp;ͪCP-0sok:쾮9`v3_g k:d?E}i?AOG{K7T j,[H +@n"?#a@4 "˰N +!ff.&} +1yy>B~K'gȯs X>€e + AA w%n Alja bYE|, /sU>rZ'C;&'\X\޳ s} ۟!3C期 5PK,e Hry ,krVL(qQ\Fބz{%׋[)B)C(CYχ͔9)3S|ʩ U;[oKvuoƞ]IGU(bBw'M_"ؚ CV u0PaXe}MaMqe( BǛ=\, : +=דQ?MpT*N#>8&9rA_ޗW$ab,KYЕ]MAv([ViLlČl%j=jt4.]˲Yʆx󥊀%'ŽEtVF̮ٟۓߙ~8#]ٛKGr[ڻض,nˆM f^|,D>W#LrMF VWk"+6&_ܭ;v]ľ +AW~MlG^dWήI;NY7R3MYsf$y=4XcmH7@!Cd|x12շk&ztxƴea]k#;T]k7[ƫ ZdM{N*r(* + APM@@ 1Nڬ 7"CjNy^ٱfFBJEPgEVXֲRtIU'ݺVTWܙR[tLY]x9msazeKOT FtтfLy]E:8l17v2h~Jp1zz_W^ڲ)?b{JmFq}YMBmisrպ.p(6 2ζM"fq~#raC)")"TtZ-mvڷzk"krOqy}7D?6(I9.;0' 7c%4/E>`1GLV:*oةp)`tYʛyߢl]MIKenKTdjfd O˜O~yDI +&Û\{\n8 VVCf+[k= OV?Ϋ,Zv8q[qIECa1ym”{s$$N'͛N_ O-`Q`!o~-& +Qzϟooh:_Wgz&Զ*ʩhGA^eyai%⚘Vab q$$*ZH*`Q`e)߅$JFIIzץC/.+(PG##kc"{bêo C ê"W, +LxHpp+w\}Y5(͗Xҵ}R>YaXg&1-mWoaK;*i$گQt@~#D(>~A@g(|U%*v\v;N[%ty.;+/Yy.ܫs8pP( i+1tv#قmTo8k]s(a("f0VCC}.<z{:028%q^xO28Ff 0 w,7ǥ:J͒YnQO^ VĘ4x,*`4w4~hhh؈贻E7tqƭ$8F2Nv@ S ' }jxII'ȉmaa~;I 3"+lj[&;[S3\ۉ.!pf r^h~_A0%f,dgxAO]z4H@Yƭmrxg`fZX/^>d[x˶|,p#r=m_՟GiPAJ ^k11k-=k/1pUr~.R7f~:C-Wk.kqmoF (Ar.p> r +a NlG}Lr*evˮO>rV֘0LVV+1PkT]m/:B$}d:4W +A@ s@]q2i6hJD+ 3IrYۤ oPV SYr蚵ؼ[WǛ"$78 +pkCuC9&@ 1 f⛑ECZѴG'zJa2 +( fBxLz6yLϟx`?`ҀIGE.SQľC]154SF#q!*NT c 0HH#IͿ"ۀfzt4@S)M-4JR@f"n>BUD&B"\" n)~6YaW3E׌ye9}\@ /~]:ZKG +pEmJ $]*qՐo7*# +K3OkPy5WTZd(gRc.(22Q?hCCt$NFl-βh+$(U2Z䩠yg*Of˦-KgU?~0PsiY+ל*,+y)"o@C;-:ѝ% ^k)DcVx)*9jK6Ec>J#V MPq1HP !  $B7C @H( %b2"`aU, ++ :;_s|}s_\L>m0KK^>wAӷa )ܴ$nd5 yp[C>Z/&`#HYc|!}ymxUaSm>KXj1eii˖SVoZMYrz6g9;xF戙67ӃD2!MFl0]b2K6!XN)V[`3Al|zl_\}}nsϼFl|4L6IGz>i \h&\t<p>kj>wt7!w߷ݦ-h#}օaH.ߨ.kчx_9 [*g>Nefۍl{(8Hs8CSܡ6 n:u7k{5:ڠ5g[BzX4>=xy82}}{%sT tr u|ݽ/堗oCqB0#F2@rMuugO +v4dO]3n9cw;6a'p8_,r鋨_f׹_bi۽1{2τ%Ü:͆'8蓺`)WXmLmt^Gai\Dl_Bӥ\1R^^)4Wu*x2ŷ;qy1ίN3٧- +ڸ ]A*z" L20s).Z 0v:R]1q-a,%~,\jdkOأ;^[F쌩i(mԣgh-f&$ѯ)/M,$ ` ^"g!i20^ +<) 9-(2*Y\ ;#Hr>Ow + )>I~G(؞! u܇uŸ~DxiF:pڃ5R0V* 2+mbʋ3P(lWNsGVh/&6StuRspmKa!fe˰ʤ)HRB6Sb0*V' ܪ\Q-71lG`b[)LƬ\R}F!.]A_Jӄv)S·+RJYQ|jC > 0` xT T5&aJ(}MJ6X;Z +xq"A搪ɕZy*XZ. )9G>Z5P ), 10fsPo|J*pVRW[ָ,1H A#ƻyY<1Y+T0daRA+Ku5!2_$90huo+Pw` ? +\h;u`ϒc5^[UMeJ#jc]UB4TZKK +RqC"R3EGBᩈl,Hl !07r>\@!)'[[j(^gk: =Na^l@5%ULͳ[[5B]4X' ++k{w?8T4_I. _5XXP%IJ4 I6Ś7%E7#Y5nbԒzDZ"V<+ZDӛ>M8~&{H2xĿjͿ|U`A# R_Ar=%]Bӡԏ cuƲB:MT]i w=-d=2+Ͼ+^+h98SOn/Xs`) +p 4)a=i!}AJFZo0`|#ϡeƒulmN#{8\hak?͵{gϑ ^!;H?k>@#'@1#D[GG/SM?g]1BBLѷ%\ch2OLsɇg!y@"(z?NH!r@|@+Bޅ"0FW +Rjs h+  ?'nttqJP歏2J(I6Bt6o'bݿG1ڞ&JYh[a}7i1`~|c=do}(q9|e T( 'Dz,2F/輑Nߛc6a L'أ쏢K5񀰉V8 t'g$ 2P9™eOe+Ls)Ga:*q;v;rrU\u&.OLz\.}! m":oG z0P0P&YFe_qF|6s?xgxydyoe7S~b^e^ k.i#]R}!>"Um_@p:FLDc#Ycd%UwM靱ӼyӯWoW\)*_o}oV(oC'V4T[0֖Z':b6p4>55yI/7Vgwne*x務O{ʟtZt^tUФnT6X7(_Z? ԩpZ +&4 0ڜ *h7:W 9ب/!֤kV +- 1-Fmjl4EimGAc + e{Uzgu:lv +Gh; aZ3*ZiGδE2F@nKB~c +m̓Ymfkc:ݍuRuʵ:mM䖦VrC^v5zХ<bPLMgG8CEM g}zR_KBsNumj;]QM_i~YĥXZl\@ oa $I%@I,B%@wE6DE .SsڱtϜAk8-|{'L~N[MgW]6ˌA%$}"]kw5Ld5Dg)]^}D{LSx;+\/Y6Ϲi{Fв&f'8+^9w%~6q&li*ty2Dȷc!G0?pQv=v@!{W')uٔwV̮ ɼ3Wg SJɸ*Kn#QQSġ="_zF۵7cO E]XEmjgm77v"x"9FwHoyQfs, ˉ4X~$YtrLuOh!zuǍt-:cƳ-nȩ5 9肂X)cM$X\Y sy<>NK[ޕZّma)I_ױIKݳ.ե"g]RsĮ'E.7%ق␣yCLB7Oɕe{{5r4v=_:CUҪRURާ7]Pv7#Yp X.2W_.&-dDr96Ac3?ߵ![F*3[+2e7A_|K + ga\nVbirOJ} Ew$Xل,Ǻ%ba=U&XKro_w +.(-?/މWj4aޥZj.TPlU|ݨ9S`V9l҂|B*#*T;FkL~`~ a[jn>J{ynjs`k4.6h<TJSu,Fdۗ(\Ź¢WXCHۃÌ,B0W(8S%ݠ񤈜]HlމW9{x曱wn#bm䶫FdVU~RUw"ŮH,-xJ%>9Gr[3C`vԢW4#Gt9"R.~AgϿ0ӎBwak~uSUC.RV"Hӝ9J7BQ^yjH.'1J3Kb$nX\HBqW\5ԃݯzO4t;ګ8uaKiqsMn#>!˅[GhdrJbM#5/0zUFPG71jDU#.]x{X3\S8{a.׫"lS xV?/ :*7\uftd:2RtK=%|h4-IKc67nPBoX#pMwas=q vKuA=qTgCq-8I)>Kd#W h~ >]+ uyh{?/I)Y9S(;/ߚ;K4{/c~=aƺ"~}:jg6.:W8ոPǺ)c=ƴDK?yuAa:~W]\L<*@1vQ1.emiKOh& C\9q-Xb b)ڂwpkAkyo<`{#]Xwq5CKD7GkkǁF0_sI6hW6܄7 Цi yk+I WEΫ?rww`r߁^+{) f"BsyzN0)و};(cg]ϸ: kJ&7{L$A$,&$,",EY"*8Zڢ.(VPqX- ZTA@y|?>s[SĥiN׌:<24,sP +PJ#{WH5@m{M>2a >/hޭ(V?{[˵-mO9udN${m΃"뮳"{"ˮ^EvOvcEtp @@?}#^Cpm}s߉NC3loYL&Џ\pO:R77Oq$@Gd{]FG^OzqqL4`;n@5 -=i2\@7pJ d19s<ȚXl *\4[Cӯyl޸<7&5)69༕Usd79Fv)buH'RdZsL(̢pl +]6.,t +&x6VÖ[97}~e!O+߫(u+ sn\1}@Sj*ShoDGg:37YOMļqHވs2Sƴ7g 5.MӮ@]}Jت>/x&x'hQ?\OmΞG=<,8.mKuu7=ztx\D˞(DK0h: #ǚblWQ.̶pNKX9$AB|/p^}@ |gt?iUr+U>|M/˫|L*Ygx2tЏMcug)t')i 8fcL>zN]dލEi\J~03xم|A,UTQ W +x:gQ8f[. BdE LT[6ږR+ZC+N?z"QM|~ul_ȪכVF~m~6[řETwYߺ<ئ,|Ή Bԥ!-#6%a%a,G Cáa(3`8 iJ@K hXiWΥjW]^"+LNUJ~*qYʲ͖cm.ε-ޫ5ꐦ8/EN#_-Bh$TB&`$9ɬӕFf 2se2<jWSՙUA(˓eKfKT&,Ids8q(!GS@\#?ǜw\b:bwǡzwCʓ1 +\ M¸AϜc'=s߻$|b +=b%{fW^8 I뀵R[7E>KUYUϸT(g)MK) B9I YIހW:6'-'4㔑LɄ%fp{ߐ ;O +*^ EV#2Bo]%r!׬0;Rŷd3R:>gJj?'97/wr[K +8× 3qf3@b=LӚJr/ +Vݒ2IBQ(/"77&[䈜ҲR2k=xc^ ޱo<Ӯ DpI8읷pC<_>*J3j]Je{Qi楲" c3%I TQ/wϭzr}(ޑ9Q9o< ]BŒH|C>0UGZjքRUc\VRUh+۵*$DP'Z%BR^IWD ?℉<Ӯ{ń9_>==H}Bn4ƍJzg5!ڭYՁ+ӫBפVD[L.fD:7.:*($bO=sxq!"f_p 3hA~uZi#*ً27i5%7YP8.,PL cwuS`UK@e5__Ŕ4s{9a13(ûX ي3hi(@a:M(yv7jtsFr׆I\%":n[s榓Lߦ!OO㔃oÌzb;M9a8 >G2{ !גT?}jFCNF77;kܧΊeqՆКf#'+vD,dd6r}Qͧp?Ϣ  u nmi\ضp@:co9·?g_}1 S.}kԹKg0.y o *Ѓa3=lO f}nQ("58D-"SMq@YQTt;(`(&_a7D l?Wq?gCwEe4t]z 6{ |F{Ey(B]ƢUc|5ƸHvbxս4,MhX4a,Y?N>tѝΟ6xL 5`>^M쟺o)6϶S7> YN7L +=*0EʚwTVxb49Y0>ܿN<+@w-pc`6X6Zf3(S71T;9}fJZƕMI=k. +^@M;d3#t?X_tXou04ݏ{X23>(ʟ(JDJ&*RD~Vנ_g`w1mm1 [D ŠNbe lC3"!hlG."Ww.6sܷ>p `nY!: "DG x̄#ࣄ +FtMd1,[G#6҈3hЉz F<2&AZI#z ]aMeiMMBBP"-J@w#* KҥI/tAEPPDAłeQq\e"=sx ̇s?s f B.c_M O ;0y&('yd@8TP9 +O!\{!p(SC&SO fiԋJ#e&Fwkl{a8Ɖ T@ HރcNdhz8 fեT$n#ϪT3*O*G){vR7yJ~4;Ja{I#C %H~  - p,aĬ2F̣gn'e}$xSOL4otN]kv?0(4W|XYL4*}H >@|4 LP&9I Nuxu̸:ʮb識dR)X?Q:)OX=cmb1 _ؐvo@Mne .U?51褏4 rXKL,لS_Zo>J=ʥXn=E=~5 r;dp/ޔs_M}A_߁ˣ +:@X'W6鼌<.HG0uxy,mhY̠c쯎r;9^tǡjQ?7]}_ӯ/PğSm0HA,B:೧X^ m'n+׬#S#dWKoJU*޷PSrSUWVԩhR$P kh8+Uo@3E{L!H@o:^ {݈۞^2}_&]Wz[kvjv:zPNK+gf f#f8I5O|.G{KT0A?#pᷚ){_{cJ׆xNQ 3y:mۙt[V7 k N +Op½{Q ? !d +!c!(@WYoF7 P~ wB@f+J,w7# X/jOS>)&, 70<&0d׭o0lYRy Ӭj7*4@xePѬ? .Gc?G-'Fk )7i52mJԫH78ctد]㻋sʤڻtW^nJ~^O-v{O|5.FBox|8w(őx -6g|t\sRc#aQC!Ɇ}A=JM+*sw*ioĪyIII4. A7>0փ yZ"U9)NOnqm uq^bDVE O4K7.ߜk+ج4[|в8uQP>ۂm&- @|/A0dTKWەΤSdLԍ^EV-[mP#ae=Т0|eAXuc9ۗfg>]oӵxOMwxKw/3Y;TWa>`|vV9޻OuJ9uWrj^WnN6+Yksb2 s"J, `]9֔CQZLC'y -:@߯toik>FxH4*a9DYrRQҠBQAQĬ @5 A9@F@8Vu `y.U`i-,VӅ՞UV:HwƱ`}caCn:hģrԽrq?*dGڇ+dL}?NK1=FoRj'q&;G`F s4#a|λ'Qӹ^}5KzjV j2 jΚC4 CT:843RbC9=pl/@9;~`9f +0*[q 㩮GS]/\XߨX׽*jtטH~jsyDZNDX{ݳ`|=m.]}OaT;( 9øC +t{:B Lw%{+ѻ  H|X ЋO EȻ~Eρ؃|螈n'f @ @ g؟H[p?ӆq@& 3 C$V&RPf`IaB+Jxn/`![$ Ev#eJN@/h@7܄ o.XQfsazjM?Pd$$!|bt>K7+hN\K|}i6t$a)bB1|4ޏ!+}(S&O(Ov#MK)h/}縊.A säɆ!FY\N03wLC|0;F/t饓׃wWSя] jEx[Ѡ.hicڰƄYѭ%m Li~غSY풭LӍ4ISs,bK&O%%0y$"%H5d|ܗ%] eՆYZ"`c sQDZN[5vV`lT}2j=}͊DڤHٴQOɋ!Jmi-˜ۜ'ş>e_B~6J>Jz}kW54ӟhl_jnh]Z]w3=D0G1AmZ}dWtu6K^H^wH_ykU/tޓ o_`7ZMP{x QP~=4_s+\s9ԤԮw1ZB)Հo.?4\p`O֟ {Q?b8xbx n22U?ejnѾSH]UE>Y.p)h!lب\Uӡ[O)SR&C2xa<F)Bx;aO* QВ>ԔܐvEK}ڏNO'l"D _ԿoKpwm&,-a[u$Dk{$/L&dpLl%66t7O9fsrg=<"EwQ6Ag6GǨ{]UaBrO M9?K$wssMEͅ|ƂJk VPwYwd-6Y Xt+gv*g"?gam\3D8=b*%8]e "Gz_C&8)?Vj6iSKJjZZUQCE̹`ԭ\(Νy"/1 1U{q2ϓ50Rc5owtzLL:Ak%*XWi^ciIKI;^ݠݧs^xpR%{E~`bp;5<} 4>J`@bz5imvSuD_#J7W(Rr'htu z\'sוsb {E^p3p"vssx3`66[AWS1P^E'Wե ksʪ9<1W +EgV[viLE =]-f +b pfq=g ف;P@_:tS@J5\%io2)n3/ίڰkۜ2j宩53Gkw='w]=1aȓ|O[+]2A/=ػzz젶-eQ+D3TґH.jO7ⴱ"V56!sBӔ+[l؆nq ${ as@65_pZ9\4sbaQ=Uxڜ>.7E?Gm)+0K)HSm:c:':V":n;?uhѶg)%h/|Yl+?`=@jQu(5ޘ#pG= >9DJ 3O& V 4ZEe֡ ` +-&w:*\K'у1`s02 BJf rOA֌rLJLz4C3~:U'v*W7T9(tRb4M8:qw▥S ] Q{ntxqj`%2T!eiLƲRrrrJRZRfG;`XЩ_,|ߙijfnaP.MY*!h ]({auskg-=l.!TnJ ~-8}w9|kc]E;?u2lN¹9xBw('W/WɎr?C f3c:HAJ< GS77\(7?gGJN]vOfe,?\~/<אnn28l8hqP`[2\W5#9ͳ&*j:]3g~[bj-}5B2CLvBNۯbrnm+Mj]//{ݗ\J"(쌼z"#;2To!q;WAԛ~o>p/4ÓW8:`cNW ]V]Vo;/3p\fKž}D_98>sOp4ȉBVv>P1,F)&jcX 6FN֤F`f,UC9 ^|pje[K" weP[򠛺Z,i~ps2g  +H?Ū.6tsQ/Ci_Ye*nmJvˇt 1I.&Gt]6/jO˹<"/z̉rvSQBK\/ρW}5/u_3qLT s+Ʀ1uUV$[/9V8~.(+M\@P&$ըѺW *uagaq```dGTwwFqIj%&Ӛ*czs͜=Xq0{yHCv{B:+.2'5(6a I "Es Lc%YMmhVMX4z]5KW++bbKbG+.y%yQcd4;cTV>|weW^Hpp+S{Tg4a}xZuUM<۪I%E &5WW[a.G8ꛡ8t +IB"_̽|B'{,{rp׎:XQfUezҴE+ R"%9U#U׬$>PMΈoU+?KQ'ݑ'+Ȓ/Sx 5yc,0rvX)AMhQ~enMv|R܌aiYiI#ZuGFJ85BT}3remeI/ IM{/$gs8}`Zq9QʜwP=Ѣ0ڔ9Q<İ2t^&8ghR]4z+}eu8}D +,ÛHu9$9d ]$yB핫1ʼnNQE# n!E +VK7Izd M_J$AxQ< lGy|Ϊ 5rkƉT5,VZU/UT/Ui^R괬"sdpyۢ*eMKH斞,! , +,< \=!ov; )٩`:HzrS-p9מp~,r,\N +.'~F3cN)tFn#? p p8C/̀ݥEBh4 \asyoa}l. + \-w=c.;d ;hzC3y"|9`u +;p,n 6/wܝ,p|Nlcwc6RN:{FU: +t;|pw$ r) s߰@8ob~eJf^|x0fs\ x6zG`7~M{o[.:'r)g,~ +@Skjaܱt=)w`:H/yL~ ?gt:O4XX d3i}o_ğL ETDGxb/@6؆ЎgGqS2aO=^!Xm/37 @$kxcY:Ө8`T@1$BkQQ).XqRAKQQqZ;qvixjߙr{~˻w>cB\ w)| Z=!g3tP̰FuaK3!='C讯nFY]9锢N*bS4а(Ґr *w!^PyWޣ/DÁSi0('Pp:/leqsj;V8t:|p%#ƀ~?6N?,aD\:д t C1zgİg$w9]!fC޶-7Okpiz S9{m שת ר VR8ST|‰ECtcx؃Ro;2"f;#9[S6g:f7wlԩmf`µaM.kZE2tkK! +B-kc/PƥaoGmԝ4'DuxQz1sboG'ڢ2FZ:S$\9ٵܚ"W7Flh/Y~kq7"~E^~?1g jajt;$s%#CjO c&$Vŧ:㲅M6yvecx,n\0SR]uJZ=kiU7Qh A +_JAk0sڦM@Z^~kJNvlL9/M2 $i4 u5%Uk+-=.ޑ>Ľ1@<ïshz ݸD:2ԦP~*{E,n.4]8-͹. fjnU)Zo{Ͳģ~r[?}m?Imx 5'zrtmF?h-j1M&Y2øK sxuS22Y2]{iz8ZRT7/Ϫ[G9ڛ;Y'- $#<D!}A\^5[@-9rZEڬHj< +csYfО)*6X E~Ԓ"(VtCJ:x*7^uԘx8(|[\~r}+<ϗS5:S;ˡͷhSffqf-rIq,l7T JVax%00>w!GOF-TȡB -,|j +PE]?[l+̋wVȒkv3&K$3gT$eZ!e2%<%L:]HUN,{Pm*OvXE%GE$Pb*0eX=vt[45oor:Dg +u@o},O})K0> # Uths]%Qe V*REAlKEdl $_lRo +'C%WrVUi<eXd}&>709& fi2HS32&9L\?i\. Vzn}[F˼Gk}ؽ i-^Tsx\J[ ,yl f8cF?ĔpL9#q9c 9dc+FgiYI#ֹGgy ܣYyMѮ4(#3uX͜Wп]C&,!"㋔H(ꎱE_EW#E2ptD;aκ|ˀ*W]÷]Zmm5ON*rtdYd>^$X#͞nV#Qf040/<xCE3X9W3vN{)Oo\o0t*nȧsr|IE0'vg^ؤi 6,?Nj;yr\V&+2{ +^L ^_cC=|I섡{'N7YW9 y<"%wBKd ~G# eSOPw9N1a?[N CoߋtiGҗ %oM"zRX_d;}W;f.k뇜ƿ;ߙ"ady5a=t$1TzC&#%r[%c4dO~jgڧQQw +*v%=;9qK"Fqg ",I]t m~s#j]N;4d] go25#k ]sӳzE71-tmr\Q\I\z\mRG<Ǖ=Ko툝g[Wwc/9~N pRrKʟV!ADu%Nݹx*]BqI&QW\qc!<2 TQ2'yXuRXUԨR5*=G^-a!E%{K&><!@B۟p;<W-~o=w:Ch嚊22&Dl:FVQd2*4=kO)l(Hms޶K :DŽ;"ړG%}ٚmDKҿޤ\}A5&bP22g/4d1sJmn*d9û2kx;3m _DKHohGqFԬ*nRFܠAP\+@#]SFԘa^ +Ro>u +çbTazvG^ix[ۚ[oDsNOdc_=^yRR"U>(T+)VB3|*FcXo=X`NF^+4[JtGYj/ k-(`{pm8 :[퉬WuFժiU2ܙYđ#(Js8g1f&ucðZQ\f7z^gꪅՅMU~`DfӞ[˵-?-MH D3|<ż_J`a0gNf^E^Sٔl(dKٵBN2Z*i/n[vK-Ef}0ڤSS:DD  6ڧjoPg.+:2j#u95o wVf%U]VUT \·*&wdYiTꓖ %EcbtƯbdzCH +$@j؏'Q$#GL]xQjp.zZq$2i +{vîlEr_fu +Kur#[ Ƣec4ewb?g29$՘B"׭}'PA9>1a^v͡Z"rVS+p0mUYa*\ /,+삢#*pvKԎ|\9Ocmα=XCR >Ux=yb-nA\n1T^@v +7ŽaOg +8EuFnau U5MQy՝j45*t>W=W>W$! 9M@h;A4v@LUٛ%dJf*%g39kV +lMS1Gh6V  QG$)Ii4XTTT\\pIt ^B8tt#hzvB\2&}B*XIڎMnObg0sXm6'MkuSZڄI-CQ ޳xMQ܎GQq'QqϣB?s9?!: 1hf`Uh>~>}2F9%R/2|HS2R{5̔^#+N Oinou!z$D#$\?.#y8L؋<b?Q)S-_G[ٯ.2z; [=c,ӂ2\Gs[`&A3 Ь`C1 Ƀ$cOI~4Đb>;F8QZӒDh S#@zD/!lRNWIzDDA>B^&sH+"5 +n㖔_Cq~%w_\aXL?_c |#};jSq#\;*+ÿP͆Yϑ(IE&U *EQz/ ei" +JDVD,VFcΚX0&{41JN<(}rݗtd=KΓ䒔c++^F>eqG+q|-xrCλ8osȏo= bMl'ĝbJ+ӵOzzic{6{;Fto#y$ sOGW"]Y̧zSMO-hc m5]=&ly:q[WBHl4| +^-XRʡϥ:hYIO+`]|lpߜcE23\}C"I_tL"$ЕNO..c6tTaKi)$9W=|^a8BŞ>cSd^!Eӕ\2=Ex=,7'Yэ}d/+aUv|_q{T1gKhΉO-Jc+KaYq@^'_=Z/.jt+ѥv!lS tb:l|tȿ9xčc% +FGߙy YDbEvY2]n9۬aU 6[գj6Yjڭ`Y fV' 1a ^v߁G?8>X|hXc6`6jbV5 hrJSrQZԤ5jV4vK펉]ݓ,UNԼ< 9>i"\ywbw2߫N0ǫ(sqYL~ '*`?=;kb A + GMXTQ<%A>`ɬ@ 0E- (T/7_lln$IM$IAyZp$9u$I;Vj9*cPCک(z +yaZINh4;4Q)PRB&7'7egA0 +5_kp(3g +%iIɺ,d=놡4jBD뜑s͌gF3"uҴxYjD"9"O^6kjLfQa'ta#]؀.T0 `?ߙYWudc=*YzcG@rLddƺc}DAiR^QFtQL"tt'B#5 |h9`! b4E=l൤i&k[Qcf'~ĩHN%&}B,&>Y/RUךwꏛ^#MbLchhC/=y殓ONb^5 6i)m|ͧc>cgpTBiA-5 }Jq7I0 7F$y<=}W9OMd:+MQ"7E|q年Y=@7waw̆i|?W-fV[blmP-R=m-69?!g|cyy6WĬ3k|"fbkX_ŵuX:,f I DڣгC]'doH{'u?X?/=EYօ6CeFka1`yQc=Bxu{q{f+^WRriNRHw1Ѕjh6E!jUEZYE=VOEC1FMԄBPA2:s,%5n=6xñR*XEM`(ARuRK! +r3LvzYFQ5eStr,9TM>%κdZ{KkjVaR+^yđOK:LJaY!~MjA +Uy+P^!3E7fȅЬV^6rr➋'D#!eF͡s,o7\"~.:5'eZ2##\?q @(?5Hk$|i-GUX,EU}_c@ogwq5F1J +8^f\yaDZW2f&)I6qO}fYp.nyb][j u& [3QgXSƶ6|< 2^Ÿel*[H/9lYuw>r@a<8=gq$3 p, +żB C)HeY|켏p n&#_؆:o D<#2ēg&x +p,R;Tʎpil LF7ap\R8bpQb$8#t#>ګxzxFI'Soj:Yz=:k\N既hY2NP-'{|1nJQJg߳DS}i_ fUeNW9K9ZoWe-KTfY-eJ,۴r@-T\VԿn9`]n6~xCy=B?܊RJolл kgP;m袪mh4ط{N1;Xї7Raa˰ø5ՊTE2 * b#i16 e&}y}G򺔿RbS|Dcw&{.,!>2E2f$!ls\ Kf\'6%S4(3צPT_UQVVY2+yEZ>d,Ceq1N4/ɹu=j;2Q鰡±I9^enP.=.U+-t\Ŧ!*:ھWOjKSS%z0AG;h,d6% QQޒ(+YҒtxJ,(* +=n) X&$k}kP\'yudU)ib˛RMRMRMc1&Ӽ>M%{zGaI[ym<WHch6Rc]w, 8܅»0| M nۻq}II~@؂􀴒j :@Daqd.^,¢ +,:̋H.`n/D0;"9rG]̡7c'(5lK; 8HI&mZ(|TY03EaztEC͂2<(9yʤc޼ Gu@"? ?EӀzL86_MX/$c4y:Cg\$g<J?gǸY`SXvf_TX_E\X*81 #n>b&O30SZ*9SZW u@~L=Lpjsӏc1=q=.󸦮4 77ZQKlJ*& &,}U(uVk.:i݆JUyAq7<=ι眏p>b#7/m2r M +D'矾>Z׽r|NRܕ遼EQ7&n4M\ML"\F%EtgǷ,m\e+wdё*G3h:=^`= 7No$3#SȤAG>tQps)}^6^ +iNV4g\'W..Y3 'y9x:R;Uϧ_\a-~c336pE^OvZ["p\n{ԕt1p#a+˜L=LzrɧPFO5c/G#Z~ZV=Vv5+]'<%_cߋ@X#ݽ7N-}~t``! + hTb" k3XqVX%.Jͨ?F8HWPX q;/s{Vra0ׁ#}']S?l2 ze^0X: ]uj]u!."Uxm#8ݮbaXӉcwc<چ[H3 }ը7K[P?cP힄*t@l̽ + WcyDǗ-pg; +=(h]=:ykT;VqGay},='SFg0=ӎq(U`* %\QAZVAj;TG!GXp)WxI<'3?lxgԌ胪CQ1j4Qa:s&PB:4.Lur5 u0]>$d toQNEZ;?{NF^}xϺ,+blO,y^1GBۘC&PD M +k25BZYHlQhɚbYLzD(:~\l7s,^_X/-^Jػ? +*iDvZk5!SkC6 +iDLf\!Y[HV)bvݧ~EN1jSp?ac97E.3uC1C7 +Y: 2C.)P$"G>M(bŊ][ۨ"tgpMeĩ y):2]o:%pyrG8^Ȓ"]~$H'+#FA0"ҿP0y&K)d/Y&;m:9yAh+bxe$!iF$UH0Fab >2Șj hE1 +d!̘gSeJVi24J!.S.ARP})(ي/Xmo<,8Ls7$"4Ѧiz3a3bَPs`1g*L|1ؼ@dZ4>MN\Ϲ[oLkRR^gcED[_:YjFU5f!-]aRXKEZ|$rM҇ޓ9!qOB{a +.,g2ʉ4%2!* )(*+"5M1^l <=JgE,kUvw=ZUZP~Fr=NL݄dc^} L}Mc?w;&wXYIwY>QldϖҸ 'x>jҨ$_LjIfk[c5:P5:Fkz[bNcϤ| ^=*MݓΚ&~mJ|l6u_Qr?=~HZ%R\f/eۚi͢puV_mXPF-AѶam-2t0v;M0FN;c1r#nI5&{ْ:0-ٓ|Kc%F:mo{ m{zأnAj.8uORݮew mg7+0Md {m K߁~dTZȔ91ъ?cx6b_ N`utU:8WᎡj0D:#M!Yk*uR?V˔ +PAs݆95#XQ-1f_URi|>y|4*X@qZNgg;{sZ:G3^o8)Й"3KU%ߌS]tMMo[~ jI7ZtV0&K]R/+ -sMjj"+P.^w|]1j\eO,PBmqG2\{2e?w6EwJ˰z%P$SЇwvfhTbRd*i& %RI7*,x XLٮY198?(1#`zZD;_'Y^zL2aRI}9.`݁&_ΦH1od17=[ƀBeĴ +A9uI-DoH![F^ÃC>؅Cd^.{9=y=ޗpO]V +:S`tzD'$~@%ҫCu6"Htt ?U&Ul*j5F ?HĚ=ơ7t/- Z?3 +#NO|3~ -㒈9/p ^\.!x #E5~TVѝN+wu?QV]I8'pgwgPb`~?Fp(aM-`!w1|/ޫV:vM$"GiۣG) +/p(}];,~6?JOGJϨ4 }qI ]/ 8Ꙓf̧IKrX+` =`τ =Bj:BkњX>swDc_o$o3eb*tS u7z[+ce9y &ooSp И̶Hf{u|"'F6vcHGm:L##TDTA~)c 7 +V :C<48iHFîCq|TGb?jX]*N~Vo&rQ^=ܪb/c^#>dڶt\Ci=OZVf5ѭbK=CO h+󴸳MhyޞWvEMLaB'DtPbG;B'd z@ +*u9b墽{-킅D+q TRU͵Mmuzi}Z[VUT +뿯>s>q)קT9>ԧBY>7+g'h֢ZeZ9;|*}{k  ײ$-5OSy2)ZbNӜ sмO'f\fwT)u Iz w\|)ٚ4Pq +VUSV- )g-$(2I ,ɚo4KLZ5K\.ͶTi!w43f5RΡ{s1sM9BhN B/-* MNyc>&ɛ.]Zi +{۽j^V{ZM;stّRcnj:RYQkQcO5y8x_.%h}#";v^zu:kӪ6<:[1gejtUUzWNoPm~Q׈53+]oYLP0mI~3UP g-uur8 +/SZ3T=WMnsU[X:UtӭJV1<%o/Rw,-'2]|L>cqQ7ERݪ-T[*_*}aUkToV؟Phm1J}F,?k07|_E%טhBX}~ @KC>VGq4R}`:`QU G + + +U(Ӓ`DF* Vqp1|GMOu0>MO%^ S Ki=r"!.,ZhxCש2tCw*%!|B^JU?\/_x.yFAasQ +t~g>Mג*M/gi{=F-$nyuTjTMQjJf(rFidG_53~fd^iI/PO2c$ VS IJC#yG vcSԂ͏s)/UnTě_ߡY}%ce~O 1mX)=̘Es7C-FuRU)XLSnKL-D&pkvXD,ze&uGbf&zu{!MoҴuk5SMkiMoI'y :|M \;_NlxON^Y $(3yHSlpLz-3 zqi999TXP}$01>s0u׏~?ꡌnȄ MhB/rp  2L f  3\{x΃Ѥsu!d[EG>}qWSc| y,6aa0b"8C8dz8AhmB#㼿w>H @KGtlIxZ_6۫SJ3/4s2F7BᏐӼh5I_hEj?> t&<#]~ +-@!E8/)+U'4oЌE?986\zsvѬEqͧ|<6#/P0{„3I_M4.A#|Ăd̋?a|zkQt.d|@WբI oۋfLK]xއEz9%&+}o:ScOx!$4s1 I 1 ^.M#B"C[[mꜮvvlw5Z5j_Cg>D '[3?fdn0Xr!8s*צ SK,-(0௜/opՉ&.'k8T8ϴ4c4DC<1Q\$22e'CFŴ_Na\AeXOMJ۝,n6^\d,^Ǜ6WsܧxrqQx<6<2W`!A|/rF9L5.u6Md:މ3/_ F8t>JCϿ_ԭX\DIH,-X@Fb05?i?nK;JlZC;99\E8D?0/LNw*vbcY0˛ILvϠo|^{oPyܟwhr'q}r/deѺks!$ zI-$M@{TڢvcMh:(V>aw8;4 tGo)WQZJ/xX9c 8& fscX;ma-4KZچFi7VIzJa2"?E͓ߠIN +xJԒVd}cvcIX;Y)&LIG'VO!:Uх.Em2E$1g5lc}wct)ZgLE84ƪ*vde "Ḟ|TJUbBk;?d sPĉR[d%{[kaF8PL}&-Mr%DFF$!ʍd$hu+ +AlH&$HܞHViBڵɶ]JkۭRd]ڢOH|yB,>Z( YFez%OSD{bXRiT]Wbvh7&t3.&^@.s% +_F`11.Y]jPuS7ۋ,/[/z'9mW0(|E"z!A +c-е.Eچ*֯>뵬$yjiχ2"o :BP)se)Ni7`, *)\@ ll FWC$M`XD\k֓ol + /@ oij6f*ڀ+x~TG%MGWRT*Y +1˿&TF%.m,e01hSI֣h Gm?ATZo +;x +K_y8]9. ZYŽ;{v;R$%?ud=h&$S9\,z=SZE,Ehe4Ơ1 4|}A0@S Y#gMq$Nh`-0Z44 -C7bi,_wҬ~pY)0|:At9CH3Hsxitrv +ANGw:1Fꃦ7z.ugZi<45r!YGzAĞ4dӱfgO3 qcBGJR2sݿ/1~tiSm[Lbߒ07٬8~]_k|lp26=59QhĢF +֬vcv`Xb +eK$Q#hOZ/N4g*seM<,R}Lk[q?a-NLkJNqs ??{pά%e`F4bOTH?l/eK"jYQ #)u-4ss .#z݈%03(b?Ož#ű#4a[e-k}DYLy^;Q4nNi*z"G18^RY6 c)h$JRPCg1lWk6U6cUFހve w[ϷS-G0y;^he(:#x Ihb=^5V-ƏMZFWBY-Zj&CVedy)͔R)p?:=+{ujKȚ%h Cg4:щ&XtљN*Y`%#+tc5Uyzl9wTrt?ğN[ځ}weI{=W GM,DOHD+ T;ZE/T([H\-ӽsl8M;ڇO7k;rݶvC[[M? rU-iv*h?MR~$-l!{l8/be9ks:2+÷Jwy wF=Z>Jȕ +_ʍV*vsײN*|.Hwί1V91YYq瑠Y iXtr)ŰUɆJ2Wt])i}br{voE?6kE^ւn&>PsHeF(7Ji1Jd$%f*ј%J0,c{4xLӍ_-SNB;iK6pݮŧb+GFeRY)~$1?^ 4?M3XI15%&UtM8Ї]G/Nڞj7\6ގ5g؛>GI}4'ؤ#XyL$Rp%Z 5&!J 7ϐ颊qk#-yםű!?i<)I4cDV38?!nWՊH֑}m'/{$i׈? :z{=DuTam -\cwq<scB63jՁvV kH!~q(2Cv=t󶐏zO垀C :㌝#s :07N{NHUCr48HWhԫoAzСnC C4TaB[ fVl|[Hވc܁}$M$UF7y=+7k{i(Yz6Ahzc2#&O݋JԵh:UG:6-Ul86xUcW |^ +RrX99ŘCr}AjqZm]emYV*_B ڔQsO:dWi֛tZUg-r'c|Ⱦ ~1SEǐm71UWJ&hKr|)fԜ )ET1u֥SC&է6WaM{A5S6.*|GKWg_@#7g{Ԗ&Hm\DMZnQC]MwjmKk,ulPuF\;T11UX_VJiJ$rf=622`>t/8:GMUgK۶\56m9rيTYՙkUʣUUj>!O059Q +V2M߄[$*䕍82`|G;HZ쥪NQEEevșSWaW. (?r+'ߕ='O\YAe<7L <$䣕8=ı)vD'#I+TȔÑSU+lPN&eUS,UYo*2(kCY Z]~_uy'qtQ=~uUYjP3VNiuTviJd/TfYle],J/2+J+LҠ;z\a>=ӏ`VqO ' +heUk+Y6E+]veʕ^V˫djSjuR*z\IճJ~~/+Jo!3_{~D,Z1fbtRr]p/V;Qev۔ZR=W[2mQB-ђcM~~' *^fv {:O?bGyK,m!'՛"$X̞yJnVRR%zR2O=EӠXWݴ[QMGV h׊h"u_M`CO$(!רXI1^_"hfu*71yO){E!+EaSAy$!=Ql}z6 pG^ҨQ<14ϿD4oQ?[s% +0O~:vLR;fd}lJvaa` P~$4KnI'ư|`}\}\}4q#}lwR`v%C Wzi<}(uG8|n&*$$\@(i1@ a00`gCfQY%fn38)Y|/q/L-S3z9c?v _9 c1|Cw\ I!8tMbf3cG/uwjP' t]C~[AH I"xS)b?EMRI u7 _O"Ӥ0fP|@$E|E f910E2q㠝c3xݙ[׋pvu[Y5KXƚ7? WKwGEAaE] e.8#00L (7/᭬k\x\KӼ7lU\-ˬYni^vMt^y~}v7{`xzh ޢWp^>m/ZE+_8X`Ic Fo@o?0B@m +[Y4#EzSϸ8\ml%IZX_#L/B֔/^Csuuq0' ]i7p~ҵޘI 8\nODȄyq%w-M88븏븟qxB[uM[}Cv]i6<z gg *[K&6w&qgI}˺{'>MqVg]|G>DO7>% uY9~Mm"n3#yG{o9g9{ў݅ɍiWtAXO0$V%b{ZM8*MfLa, bJ2yl}+S;ZG f  #T֑E|.߫䱃<^U#0fr͡&R:s5;Lv!ĠZm"ԾL;*뉆e'(%FZ'u<B*?ZF8U aY=q>q~p0 LL(xSEi3xS_BEVmC:l6 h߮ϸVqj=iؤ.pagg0sYOR88c*NhIpBOvݻtyp~GJ'R| +K\+ٓe"EK + +!5RXX^Xհ`M_@FS @g6t\_~pՐ9Ɵ&]h#F5xEk zPPx͢7ftJc~65ijBMT>oɒtt^m$瑱oZH>d.!R +RH UnJrR╕b֐LRsdM-PfZ2ҼJbJI^PR^%'-7v+j:x XŗT <3ȣ<٫r(w2>e 8ed$*="KfR+e0%[GlQmLd[x+2(vR/4!ف5RřǙĞ-sNkRE_V}"'4~I97sO>*M5܋X #sw3?>MO .S#@ rD*aa@Gb/RtGQ*E84٢pb9+ԹK!Vu)$9*lOoP_Ȼk|vX:eJ\jb& %WK1]"J,_T_DvR/sZ@NE|ճȧal2d#iXAԂ=B>ZBM[lyg p(PwBFq۪`CAa +xSeyGE\ **r +\"]z** )AAQrE3q^fuƫx~ +|iweT֓;t6IKG$Hu1=JK/4|<_'?+El^Cd*țn<W&"Nss 9ѾlPϵe̦HRj ,[E-K6%c&ɑ/qq޳deB3rFjy4qF(@ᾑfk-mEl'*#x5L~RJPT?z!|<h11 iB r  i>,nνH*µ +jce#/>~GT +>eT +Z|rS*ïMZh\91hW3|(-Qvc8.jiZ `hu3!xF\\j l`Avj}/Bh?fj43i&6Q ~z`?߹@*\r >,Qp#&'Xŏ)\JIOW[ + 8b;EPO,ǀrCWX>bt))w x"LS r^13?~k?Chiwc`Ib5}azw`PDTY騂Yz}xxx%O=]+v|;^mxчdÓ_ +s <؞Zݙ؝\m ~u uy}wuxy]']K^3~Oԍ3, +G,'`;|'q?.q ];Gi܋4yy'`|::.8npqViN=|p0?)=ʟKυߌKgY?3}o +Θ5+kNH>Õ7\}5qRS4_&~4i4iv*-:}[q~瀙uV,W|8^kY+YV%حXU󹂧TϜT? %F*5^떮<ŹVbxQG"=vhǛ80 +xpޡw8pEӶ''DϬ`d +!J)}DOo PW聉HmTB*gB|5理S ^hsH݃lz ^Aŧ| #DWoz*OCpH NP?E#5P`J 3TkQA_)pVg +0W;t3! xϖ?Ofw9 `m9z,7:Pطqh$2U +1) +4?5ESѰ4|f'mӬ2i&m. J;ix.;22GNݝ6 $u˨gՈuwShp5.AަD HWF<3-Y.*fրMrSQpVΦObJҿAj팻''Br)˞&$ 7og?$O . qp \B%xjbSRzw675k# )_194r#pGi=ۉi.J.ʑz%dT"h>"IE*eZTNe͚#Huzu<* rKH 6I.jaerZh\Vja尯54 V]ʄ#jj@.|f '%o ɣ40E0p6ЏU4r s@ZԸ68[A?Uy<>)ǑW( acرQyظm 6ta_@iš 4cڄyꮶQK.`s׎/ph1MF[#=ٚ "ꠘ;foԶ]Yd +d>Àeaw@'5oG~{=ׅ́(nW7ϜοFU~ ̝K r?{>1s)@~S~ a8gq61x} VS G)7 A9bv?b7(v&x .G=Πѳ[8lϳSe,+ &hr?074^"eM&8\Ƀ g H&ʠĵ:GxuDd0qVTI@Uh +2 . +~ea$a O)pJɆKc^(%dPr!>A +A> 6T ʘMa +BCfTNY*GC1Xg(-Fl\$c;oƓ3b5bP}'ɻ]mgQljL8RG'gd2#Ô%{dR#mJPrTlѓ=M 1d5bZX5udzB12])fPG'ߑ{ߟ n%| yZʎPX? J0?6AֱvYbظ2-U2Y*ڤHzv(zHf,j埊9`[ˑӱ!Qˌ*H3w[񁊋h,2%(:ѡE&ʘT[mKVl+mtC!Izf*|$jd6ٷzS鿕=ڿ7:<>gԎ k԰X>ғ stb +b9zUY/=I}Xn:X\E|>̤'EIOᯙ{+0wF//JyjXS䙏,jMG!#~߻Hچjko𷉟SllTz2ZѳxB'%)WAEE"Ӭb׃`= +0 Bj4ߍZ;۴ +BГlzcI! uq8X], HSLk2TT|%m[)}.z2XW7hrV˥RVAV!_͡Ryh\"A%^sZ)Q2fT/yݾzQmB/.rvn; x]Ce\j(j +NշzVFm6.6xJ/Z!O+@ ЮAѬPeq 0:$# ;n~tQ'_'@4p5[oh.ʣn( <xۍ=n<z;$\ؑ\ ~ռ$Bm^ b7<@8!Xq ams"9ʾ!D}}}o'hVs[J\'q-E\=?ǀϹ ʐIzp4y:Z \yHxptR'4r+\a~'qp7nstguǰ Ƌ f9>3Ɓ!˨{}^ WnuF" +sgO?OG!^\/ * B[L7ipok<͗ \vYӈ[wQWPoSǟML!];=ü@=83kI=5 ;ˇE.y vK"n%صQ/1S`ï+9PhmnXKnꨓȆRj 'gIp*),QaiJϑ=H "e(ڢh&EYiVB7d/+,򩮢_/{ +ڹZ@ Bz޵Zj2 UΣFq%EehbVT"Yc*"ZqM +mٶCmC2^Sm?T펂yq[` (:^uxl 5C8ȍ!.P=Ndg/sBBWʔؠ.tH~IM9Is&ޗ_]fj{h#u%l|iǏSZFS#&D;|$sJBRbdJMTpj<:puuvܦNDB,:! 4.q0G!hٽн\@ji* 7NGdVpF3ψ_f|3jNV|4+Y8Uz) 霅7} QdW[MH=\zⲒ\H%7eph+BN(lb. +@  Q.Ȱ t|vDu!v^$.d1e*K>nN&nf3n{x+F<,%}Ģ:%s݌ X/5eȕ2h\dV*0‰H$F )]f qPFJqpNw9s +"| <_N\I&7K-pHѴ/0@= RC><4y(>afim%LmŇ ^|XP$Kdw{%x6RX&xr)`x_E3h"MĢ1c6R0P#6V#$L/tW'=L^6@ +> _lŌ?Ć#X{?Ä.:E|tP@џ0u5?bC#8m3$|ʸwGlh(m>Ï>FN^Y/KP=6}bCHn^`icÜX?upB R'$rv0F^?O4.zcEP')Cy̫MXU<+L.ˈ_iC_y!c>̐&az? .0uiBê%t,wA#wa̴1u܌RcdhgF Y q|Zʤ,̆OI8؅g"dJ 1~"p +*D*st _ル+vbլW尦5M3׼lm~~-L~m^fb|xz;fPrEh7S<^'ďWWjkJKx оɞc_o>{\bJGb(Q7{T/Q[}X:߬]J\{hL8tWƧq1%=.|X*ki&)Q{ |7}ı oҢ]|OQOĽ8Ecz5sp?7l{km˭ɃQ=c,Fxݸn&]|eMur*˓r\tQGXp2ng.alqLQs#M:o)0axmjrȧri}+=h UՔ/:tqC-sEy0e~%v8lmZyN#~\6]eoeagN#1<8`\ cZ &aiRW鄳;:xܪ :uLzWu~A^U㹻}9r>ah{`~[Mv.OilǣK]q[ؤ.GGgw؞X#kmVU&g/7Mr^̰OzvLo%=ьm+`])B1z8j5Vm&#.:h >l&qA}_==Gi{q[xx9*S*Mi-XnZ8Nuin-m:[ή:rz=`Ӕ씗.dozE.Zl.X`-RXmozdUٌ,[B=*lg=WivsI*<$c/ ^.|X%*k!B75rQ%KdBw2Tj[6,y.¿@s;'ȃ]mmv'louQ;";fȋꄫ2azT$T91c((NZ%IDQ1-yO$E~ٸ2阒RLNz#ޏ?JCm mo Ӫ6K}[GJT̔(KW% xtYVŴ(HkcZb؛#om;vwrD؏)? {4;IvsIlq +#WV:J4lZEqոWfL)%7"r3k#'s~\1aIdg͑uwddٟ/Ejwbt#5O1f? }y,4zrkf>YGH)UN8qrdO,+fĄ1>g^dL1Ƙ[#5Hɻ/ȼ'#!H}=sߎIcigֱeu~N]ڴ蕅z^TtvJAbdMNy197ҧĘ)veU)#9U,茄Vs8i`s4l? p,v\6FgXR"9$' +S"uZFLˉH*E"bE-qK%tbx(q<;E'.ţb>#M vҹ4x6rY+'exM# KE[FIЌ +\ tLq~{3h2fR<,;{דDhuᲄ +bgn2$x`jzz23Zj4zjⴆ!U^JzY<30On4fz.;Y%/VNʗ(b9b\ !M2]Uo[UHmSG:̯bתŜ9a'u m;}B?oc`(N9;$X4RZ <| ԣQ= q(Y q%O0]Jy8}?u?cwKԾp`Qsr2Qayz[ԣE=Z͖GmִY_"KvFKtMr#1n?b6rF.BmGhL|Oq]G+宷e8|gȿ._]ʆ_).qI5sDH1 l;E\tNvp|?DZzxȜHǷ0j^C)8j;-l=k:'Ih?a ĀءcCvW]^Q!% !aI%!@da al BU@[̸ZQ@k˸QmZcmeiyqyK;".Cb;?zmڸGl4X[4߱gG%Cl!)a"D^Q?tDYjCAb%gWcDZ`5 ٣x.=snfO=̆3ykO~ `XuX +h&Gs5[W=#N!gN'n-w┃zD%T}_qOOp?`QZRbRcO)'_ +bOq;ac3?%>>Ƅ?ÞߴIq.W8^KTы/g53D]<_S9Méɾdb6'\JCDO=?G?<+gqBq{ROqKe(m:`D~@VCd_}~`-gNp嬘2xg?t ?VژlhzX4/nUwཟlrǣsdW.0Jwߣ f\g|0XVz]E6fnt*zNvҮcɼLT?{by):'IPRQ:YeAMtU_;jI[Ű[4m'Fo?T#2a +ژdtM\jSbl52hKT~.\ ?i/FJ5/OOX LZ'*īr) 6e#QANL^IÜZ zgd5l`]RX Aʺ ,ڀWnUn7*Çf?N}l.f# +k,#XCau_ldk ZA`AHl9Cs+fVE8N SM ~?~k K~VKNpB+|v+@tEŠ%(CxI 7c IoY̬$($A%YI&% Sp6Ѓ"׮~=쀘+LPZwyFc-=Ȁ$3 J5TjծS^}47mZm׾V_wֽg}?`o vz ǎ30q)&SϘi6k/Xda;[\pu[o +!pK;vGFEڳ7f_O&$&%>r4_S;~3g?bz+W]ϼq;wq^~g_zgQqIٛO )iƵhstȺM ͻ#$ޅfރ Chccj4`N]X6XQP# gjJƒHL SK"'+/14j)90ujOM RP^IԥRjӻ Gmk(V w_aB}ehGS`/\ +xZ6UWNh4hl v4m+p,OplTL1x#JI̝z2Gn^7lڶ#84<2z7 햟(*2D 2( +$d iB(d +>|CO!/^"y]X']\RRZZ-/RH!RH!R/]^b JbcWB +)(-V8 XpWgB +)"e @D ݝY*yDCs@S[^+|e +u)3"DBYbK~ȰtEiz[ h\џ8hRU+h}10ֺGF ^Ǹ.qMat%$) +ߛד] 2MbMW'JD՟ZQN8 +5뛂12,U-[hW6"#,RG88.br:ʵۭӹ?[Z;oQ7yE +d)ۣ,X)qbm{׆0.?4Vqz +TdOPϲhPٛNB>UM >dЈY ։їf\Ea50]p]^и +0{"pyz-ey 6311iT\B +/o`5NZy5ZIeorGHr\S->tV=խ8PסVd7={H׉5 L YyోE'ŷNhؽnVN +Fےx'eEVb9ջQvZӊ(ziU XU w }|g;;Zכ07<^4_a|0NF:|=1v@DݽIn(ggo]}ߎ}B(9w~6qC8 iˇԪ BJG WLqeּO+8\ ĉl}% Po)Fv }9t?Z]@+>Д9RFT pӆբa]5U5u]SJqpRBb]B_H]LN +tmAB}dRogY]Qn'_rf~Q~~29(TZHͯGZ ``?bj#00A,a enH#tG=~ HO> 7wL!\W.!}8zi+P DEjOtb C@zhwмNPxခ#@<cORn(0xޑc sZv_{Sαe2[Y N3W!_g +IN?̽|ҲfvirRCTq:|` .f| 8at`|91`s C7"QEpp0荁 @7 p-ԙ:o,=zVX\^@3VjhvCm055;!0{ۍ;4=։?XK@<L {=0z"f{@6@2@&$1p@;^̡uB0p؂n%pan3K)p3{x.hկ" _fagbrڷ8odLHRBJKyd̐ȐLtRRdʐ{F"cQǥ(2d:y>ys3}:M3 ЂQ m|}1 A4dXC@O1(#(=5JMFR(DMk41d&zCC +1h@ ` پ`͔t{w:,t8ǵ(^Wh] +&;rvvv@=` 90("[0v}&`P$)ꤥ?uבg.9+w IzS[7UȽ^mf[YY̲]r})'%xXh8Sc 7M](B XV\$J蜄r!*4T{)ry_~/N{Ȅ,'Z/t_R_NV1|)JO;y"2<<T +nj +Ǖ,ߦEo^Z&dqxQ@*KnG>`.y < t g(5vɎ`9NtǝoqU'^ Vo >y9C1b|,ɺyŔ䔴kYo0Xr1NZP2(pk(-xK&nAx0l;[k}at~&ֆ>UIr\FY.v9SSKnJvqC51btspP>{BsCPhAPwh+(<·&@ x p9,arbף7Qk:j,5ehrej-t}ZA1MĈk'?*|~g5W9tvYn\2M{wU\{ٶ4 P{cٱܴzBji!}_R1Kz-}Ml"2DqNî<%uK@Tʽuix4#ŒK(95j +bW-o3o> endobj 33 0 obj <> endobj 34 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 14.0 %%AI8_CreatorVersion: 14.0.0 %%For: (Pep Mar\622n) () %%Title: (ADAPTACIONESLOGO.ai) %%CreationDate: 01/04/11 12:01 %%Canvassize: 16383 %%BoundingBox: 102 -1 6270 847 %%HiResBoundingBox: 102.7158 -0.000977 6269.2695 846.0488 %%DocumentProcessColors: Black %AI5_FileFormat 10.0 %AI12_BuildNumber: 367 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%DocumentCustomColors: (PANTONE 285 C) %%CMYKCustomColor: 0.89 0.43 0 0 (PANTONE 285 C) %%CMYKProcessColor: 1 1 1 1 ([Registro]) %AI3_Cropmarks: 0 0 595.2803 841.8896 %AI3_TemplateBox: 298.5 420.3887 298.5 420.3887 %AI3_TileBox: 18.1401 40.9453 577.1406 823.9448 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 1 %AI9_ColorModel: 2 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -1414.9849 2847.9102 0.1667 1595 867 18 1 0 43 169 0 0 0 1 1 0 1 1 0 %AI5_OpenViewLayers: 7 %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 35 0 obj <>stream +%%BoundingBox: 102 -1 6270 847 %%HiResBoundingBox: 102.7158 -0.000977 6269.2695 846.0488 %AI7_Thumbnail: 128 20 8 %%BeginData: 4182 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD07FFAFAFA9FD10FFAF0D360E360D360E360D365A5AA8FD0BFF84 %FD13FF0D360E360D360E360D365A5A84FD0BFFA9A9AFFD11FF84360E360D %360E360D36368436FD08FFA9FD11FFA80E0D140D0E0D140D0E0D360DA9FD %0CFFAFFD11FFA90E0D140D0E0D140D0E0D360DA9FD0CFFA9FD12FFA90D14 %0D0E0D140D0E0D360D0EFD1AFFAF0E140D360E140D360E140D14A9FD1FFF %0E140D360E140D360E140D1484FD1FFF840E0D360E140D360E140D360EFD %1AFF840E0D0E0D0E0D0E0D0E0D0E0DA9FD1EFFA80E0D0E0D0E0D0E0D0E0D %0E0DA9FD1FFFA90D0E0D0E0D0E0D0E0D0E0D0EFD1AFFAF0E360D360E360D %360E360D36A9FD1FFF0E140D360E360D360E360D3684FD1FFF84140D360E %360D360E360D360EFD1AFFA80E0D0E0D0E0D0E0D140D0E0DA9FD1EFFA814 %0D0E0D140D0E0D140D0E0DA9FD1FFFA90D0E0D140D0E0D140D0E0D14FD1A %FFA90D360E1430365A360D360E14A8FD1FFF0D360E140D140E0E0D360E0E %84FD1FFF84140E140D360E0E0D360E140DFFFF84A85AA9FD0AFFA8A87D7D %A8FD05FFA80E0D0E0D847EAF7E0E0D0E0DA9FD06FF84A97EFD0DFF7DA87D %FD05FFA80E0D0E0D0E305A7E360D0E0DA9FD08FFAFFD0FFFA8A9FD05FFA9 %0D0E0D0E0D5A5A7E5A0E0D0EFFFF7E365A5AFD0BFF275327AFFD05FFAF0D %360E1484FFA9A90D360E14A8FFFFFFA9FFA9365A367E85A9FD07FFA8FF7D %5252527D7DFD04FF0D3636365AFFA9FF7E85300E84FD07FF7EA95AA9FD0C %FF527D27A8FD04FF84360E36303684FFA9FF0E360DFFFF845A5AAFFD0AFF %A87D527DFD06FFA80E0D0E0D5AA8850D0E0D140DA9FFFFA8A97EA95A5A5A %7E30A9FD06FFA8A87DA828FD0452FFFFFFA90E30857E5AA8FFA8A9A85A0D %A9FD04FF84A9845A305A7EFD08FFA87DA87D522727A8FD04FFA90D365A84 %5A84A8AF5A0E0D0EFFFFFF5AA9FD0CFF7D7DFD07FFAF0E1430855AA95A7E %7E5A0D36A9FD06FFA95AFFA8AFFD0BFFA87DFF7DFD05FF0E140D360E7EA8 %5A5A7E301484FD04FFAFA8FF84367EFD09FFA9A8A8FF7D527DFD05FF840E %0D360E140DA97E0E0D360E7E5A5A845A5A5AA9FD06FFA87D527D527D527D %A8FFFFFF840E0D7E7E845A7E7E845A0E0DA9FD16FFA8FD07FFA80E0D0E0D %0E0D360D0E0D0E0DA9FD08FF7EFD0FFF7DFD06FFA90D0E0D0E0D0E0D0E0D %0E0D0EFFA9FFA9FFA9FFA9FD07FFA8FFA8FFA8FFA8FD04FFAF0E360D360E %140D360E360D36A9FD1FFF0E360D360E360D360E360D3684FD1FFF84140D %360E360D360E360D360EFD1AFFA80E0D0E0D140D0E0D140D0E0DA9FD1EFF %A8140D0E0D140D0E0D140D0E0DA9FD1FFFA90D0E0D140D0E0D140D0E0D14 %FD1AFFA90D360E140D360E140D360E14A8FD1FFF0D360E140D360E140D36 %0E0E84FD1FFF84140E140D360E140D360E140DFD1AFFA80E0D0E0D0E0D0E %0D0E0D0E0DA9FD1EFFA80E0D0E0D0E0D0E0D0E0D0E0DA9FD1FFFA90D0E0D %0E0D0E0D0E0D0E0D0EFD1AFFAF0D360E360D360E360D360E14A8FD1FFF0D %360E360D360E360D360E1484FD1FFF84360E360D360E360D360E360DFD1A %FFA80E0D140D0E0D140D0E0D140DA9FD1EFFA90E0D140D0E0D140D0E0D14 %0DA9FD1FFFA90D140D0E0D140D0E0D140D0EFD1AFFAF0D0E0D140D0E0D14 %0D0E0D0EA9FD1FFF0D0E0D140D0E0D140D0E0D0E84FD1FFF840E0D0E0D0E %0D0E0D0E0D0E0DFD1AFFA87E5A7E5A7E5A7E5A7E5A7E5AFD1FFFA8845A7E %5A7E5A7E5A7E5A7E5AAFFD20FF7E847E857E847E857E847E85 %%EndData endstream endobj 36 0 obj <>stream +H\ǒj+"8fQ Y@lN]]v;f! w +M ѻigI8! m>%S+47.csl +F)C˦k޸ %>^YLG\7\>̞ /S@w` VG5OwR8*TUX*Z9G'/Rk\ҭ=. K5GvB+[9|j>LGI9Ԭ"&bx @x# g;k ^UH B `=/.Ϧ:ۺii:6;PG6Iˁ{Ϟtb.=/ +|ưl' n.Wk@UEw0UW0|_9 X$ + +MzHu 7s4_~{Ɇω#wl9;lUi^gIlhoXׅށqH=uBǰ2ߧYͩUy,c"Qv+ѣbJJHThcfC?#FQjKahʈ +%74uէۊTi(8I6-*0C᧙/ d ne+IN D :[nC_ +ݻ@3JMD#漮66k֌카h.P1iP>wԻ\əD5L!.t Fh)g_k V:;_|S@9*qְqzBccb>UD望e2C(>NTt8qH,`Ȕ;0'J^x?ќ@l|[{x+/@؏aMk35g xj`%`ȷF1t* A_lE=s%ynL>d'JbGѧ(r>n"7ڇm>:MǦMMK|w?/@~\fXA,dGRKj`Ѓ^+SeJ)έ,\fPrʍ43d'zշsGɡ.1`dErsw/ٶh*9\ͲmV׷YȻY \sWk<OĨpZ3%ȡb{gyA#[x4Hݾ$NGh޷FPR?v\л]=2@"ShX:{-z:4he0 +H)X5}_'8^"9 -[^xyhsvB2ݷ* +DlVvDWmMl ?_<4־J?狵GN󪨘,dފ1'܄edz{ڝuCf zU !Llp% +mJ}i]jN9t(ey,u,AGsğ{a=v_>[n?ZTNs͈IaOqJ沨xKs(yXرNK}X)NvcONaJ,ᵽ)p]#k][ [ $2SRDԗ"?δZ:~{zޣ@JoӕvIcߐ(M {ڝӰ]/y⺭/:<֚h[|'|ڃwcp~Ե V%X)}/OydMِ,$XF aĞU?iD oy F:D;gS7Yx1Ώn5<ԛ .u3y |Ҟ.y[VRHm C=Jowo"ww~(g%;w.x"\6Hh0(B:~] oیQ;+b4}OlYKgRq/闲ۖuB1/co@LzO7KWsQ/#8͝9 MϘU0354x^3G #ni<# +pǫ`*MGL9\+S"NFc{/Z+뒪FNC*Ju66K0_L.5n~N取N-HDQH ޏ5]ԲrGpξ矗OOrrH;.Y0@V͙s::'<\ΕXd{-zgH"qPm$pgq;g#I(Z5", EƇvBB_0K'*I[U5&n6W6%Gj4d#m[DE,X8›i.}(d,Ћ7Sr +&D+}m s烑l⓪C T;ŗ%Os ,ͱj,"Y㼞dJ6 =kՃ+㴣'43u +d|Q1dQ?YW=|=dpyW]?qA}ϱ#Ķ;NbbM:FSKF8skRߑݡy. 'f `2z:hZTL#oBP<^/8, 16h^7^?F%-&aֆu(+q(T~ .w.d|F;OEsK&;"laQhQX-u /|vYXw-lFl_a( D CƴH b6qQ7J;lD7XB#%2+d/v^H#1@uQʷPhq)he_DCE6.-R:ӢbLl#K +*{*@X^nab?C%NcTg}Gf=]֫urc9\h/(@ ! lk9H(UZ}GM]+!h &.@Y56G(҈pѵL_0H GDY^F\|0_E{8Cd+6n{7AO%RNnJ6q*dΨ"8Ώ#P<`mPE[?2.?C3 +_ن^3GK﨤%R0M$8Og xēl{9v>x`N _ŗ=ֆmPx\[)7]P¾P(aeQ\ +xMnJ$fEN? >cJܺ@Lk~<% L j +u ܮgs.`  +աcσ~Fuj=#^yMȸwzO.t;mbAfn-Jyʺ^x4=8 ^S(zس0/2y68uWu/ŻVvWƥk^[o1 ;'vqdb?۱ Hddt9b%Ü`Nhį꾒b-_ +Ej|``z2~G{zՁqpħ]\x ;/[xݸw\.u;0Qc ri6:ƪu[u&A;߹3heT>(ASrޮتʠso'=ejp;puτ&~`O,mkگV9bT"x Jg{H^oTC#u;K o`0wa^byXi]A Z3zRZ)CwݲrOdңme=0f|iaj3iklԥtu~E3> %б57_j$XEAuyǓbŕd}qsȆk| clm7]L-۞*na5hj(atd~ح&uR#S"\Fn"6Zorl%/ˢiwV#tG_?> RP.H¢"ٹFv|d-iصj|mQMRrmF~yz*3r)J gzDKCqۥ<:&^ @Cs}4rڍ9nQ~^- בM گ^}02{_3 +jz5yEV]VV_Ҁ:J=i}6XN™s깙@u!1!"0↶5%L e0y\J(fݮOtMٚZqvu7ŃƒmI++J+bQlE8̅@B7P8rJl&` +!Dw-vL=Z0ciӔF5qute5-g5&^H3=U +QrBx+c?kp\\?(N}jDTbRCMv6khHyKY} +%%@-8.k1l Y]qUqu޿ +]juE/`ms`dLE}rGp{M?9[@5tg':YJ2Ҍufoͅi+e9ט~[mzC_O'_ 12Dnm`Nl֋6-y'`L?=E-]~BJ|GIAgkQO1/.@IblT\:-hÑO٭Μuk%Wg:|]C*)lJvtF%z/qHCIRNC p9ssW3fX"F'5\Z*_J@{HkLi}A`|N#g*,wMG<ʣ + *2(F +of])?73K@TAQoBǙlŦݎ<`!jMd4ǍZ,ɟ7wm;vw0co.P=GypBw<nv*n>}>=r|$Ͽl3]fs$o8 +Ȑuñ" !J()]=J]\N7S8T#T7ܭQ-׽̼AZz&2l&w Fp TSi~PbeQ"CP'`9J O˴vQ0i.|fV"4eW& !{{_9qfG4fLH9SʼJH!!h0>aykWC蓺./`XsbrX5^\28aeh4Fg 0VU{:5 +S/#t9|׭31hBƩKTF*H]xeDUrX}E+W] nnϿ?Ptf0tbſZ_EZh.˼Z eo|YBǰƣN' 8/7p쑄ӲW;@% Uɀ^<K )lV AcM/g%MgY펵(%kC#?jݗv>_`2 @cDv ح&^XUky:vE?fpAݙY۞E" -ә)Lu:dAᲞ9鴿8Y<' `] 0\lAs6` 8s Se[̴ x;F,5Im[~gΦTu&&DőD@@\|hftKgl+` 05^;[ޑ # 7SSٽ*K[-]<ЀiZGHRLd®0E D￑$!$$XAkAu댓/oZ"ZkW~EL7b,q3&vm9M} Cr/O{ !F. CJG0Ȱ{4N}5pϣX_X,2`i4gYg2'޵b fظ\G$A<#R"eK}1|F%5pjLs=ȥ! 6Cu< +נ+wi('?ڷWZ(%s~}å6"yӂv:-UQ1#}w0bl. }P+9o(O +NmNP>gaƜS+&ر8Erwg&o oh5hUm+o( oCn}$'MFwpbth)Ǯftv6{1Kܢ:w*{b/{î/ +fռfd掕w-:gc+{zM?z[_赝i~:0 }rDύS@9N:1rpz &5w!e7z|hmǼIFـӨapqJ}(5ҳfo~N[=4}Mx4U WRgͶQeFwvj৞:r2cFᮘ|ZDrAN[Y3:V fz:,p\&GiΝHV+T)ܒe}e4;;fr>F_p_%y>㳞u%LsT7ާR Ӎl(DW:CpVmTUi{;~|n;Q^cvt6N(*x=V1cVTr bsK| ,Mp'?owyϵEMUc 8"o"O,S_xw퓻7$HL(je4\pN۸>v Uy乄 @̾%:id: mfvO:>ci[C.] [07Y6?m5SatT>;$6N)8W"ͼcX?xɄz[-h9;[>s(K\ɼV]Äm`Zh8P+b.J?J#X;e[ŧS\00n/OWRҍ!7 ЁN.˓wr{`VO:Mk̖{~& }R5H+, '5 uM;Z,w"l9GJa^I,&X]M<I㓕)Hv;YfjLrc użhՕ[ДyxJv*)?FS<>o]UXŋ*XwTL?nVǖxNڐю[P2I=niDE⋾gIS[3@p[eþ{/@BlǞ"CWt`3E[*jlyq\ Ds;Au󱖃EG}TN-sLZFi6HtZ}PIwScW:F4|3tBѩς{…UP’YckS4*Pֿ$l퓬ŨoBI:L D^-ZAwiYUfdM#G\L*?gJ-HyX "#S_jcCMl4 +BgHiw/r9MQY-Quտxbj䈓MRQxڦ_)>t+H$SN&F}s@P_Խ1쩮Y +)䔼VSڪ)CRsn_V&?Q4 6TǸ-۝nE{h6㉡,W$ǥVFXS?|bCۋx< ֿŽ8$c^Fn&=#(K޳! .}ZI +!y83D f83Ly]8X*N߶PV3%bjZ.>)t^BHX+X)̬~(19R%V=Salc!wWk6 Eg?Ke>ď/v9"ޏo')ujr".Og0o1gboH9S&s +ƿD{-$Hbgka=A|: #5d ^3Ŷ03d: LF2tM| 0 lRdrFD{0h6cTR/Ž5/֒TT6Ka_Fua %*1-$2uv/;19Z*ϡkpΞL 0TެED˞>|9 : -2& C`P ]N]j[2[D0U'-5և7ɓ65,r4u>UU0>z1 JPrP QaP1 *޻)o?բ?zJdTOGE7p~ԌȋU3Jo?C"ٻ, +zӔ_zـ ##{ƗV `'4nEiXW\VTTzܓg 3V-Y:.=M`x&u'J~pj^W]48$Y]V_`<~6smUaF[ގ 69:k?d%fh$oUV u$K'- E>)zhK`Hہ(݁3fP՗4t^`w (!s<+MenD[>7}VjWSXgegܛ~]^pʛ/jWJÅ ڀ }| ߪx(@ȋt@Pljw yՆ^peXɡVfk 7ƛZyw) K9α̚s4\Fo^}!ʚgW @D٫DgAb\~ TD܇@*]@*_H .Kl8xm̚{ޠ̅f)h@u"[rlixҵ'@X{3 % +\wpzXr 34Ib@# 7 9I2W)cֳHsk(eL϶,"] V۴Dkn$@C %F,> +_C'Pܩ ("Y I!$C$T݄II;.NZ5 ѐțJ | + vt%g ?S3;H#>CbcbLs8;.]X忄 ?aq`Ʋ]aLt ѽ딐pbW!#ߴ*QY& ~|%OTlLu^&s'6]dOs^a\Klr%Hۋ6s:M+h,Q +}by9mmYH"ʷO`1wrƆ⛃갞NsgAm xlXQ HoJ) +P@sN%ϓ_kf%kM5*o^`2FW—Ф̅IcrPE<9D' +Ǐ+qGN2jW~ ?ɯB.2hG\MN57a/6;p3B,iriuT 4g|~16n@ -&'#K,hzT}(Pq3{HvĭDQ99T5ьU ut{K^ꅿkDWJ,絣PY (;."+(3Hn7T{kj,qSQW3 #zfʖھ6toz)=Um?--SyQS+?xخbCJB‡<]6lܤ wG.[ yN֗#2g.mǛ[Af͎eӹJ?YRSK ۶').$҇~exD5ŵ_\ +u[fK8zQ*k^Ȇ= {8/I_kmz9otjUf.72(.40 +/瓽n"/DY{StTFHD!9 ̓{]tcݘo1D4:9~,RN )mũyiSϾH]Cs)Xr ԉZK\^3LƉ +'i ZS ^u3 ++^T0}h%r*_Ԃ IӾ/r!ب'N[t 8օq"N]F0DNKJȽQԌAE{ݛ}DGwvnq!n38wg ˩TulnޒͽF&Awcf&x &+S_?0I43A *wc?eCyE'QS$bp4fx$cVgҢ+ vcJC zx M71`?LGJE"($D1b(8wrAϚ1,OK|cY|=%-?.;8vOnt}1ѯtg nөmIJEx7EEO ӘQ,5BWk:Hԣ *.߄W3Ůo.8{8-_r9{~q>!ͳ?1}(y˳RttJ-{Qi)_4֒5ޱKieJ=뽊:3[OR=𹅼xypL8.58EnM_,np?Nl+ŪF.]]y܎Pj%Uo\j˭"!t˺J-k:9=ε?W!qÒo8NX1~^ 9ga{7Gf*,GoT?uWyZv+X3-iQ6Վca;{v_Ɉ(οj|WH\ih7p̈ 'f,J5y< R!IiZMĴ7DFo8Zx˜ \ X,+~0L+B}xap?svdcd[]pvN(:9-gSImiωEVjOcrgߌ_V{,y\-`oE4]Ͳ=GnH 򎄂g5 +Mt,t,mP,OcDPOD.Mkm! FF`u"z9#fGwo Q2#z^<NܔZ9jwp&|)_V-:>{oxm.%h,Բu{ҭF%܄Q*ՂVCeL-, at#My ~Bl5wc]wDKL<2ؼY a +U(vP48+ r% yV3μ5'o+[]cv ^ޕhЃȇ.J"*aS$U_7iʣ<16=Z5s;OD;ME+S)5V{g0_~׮?(DȵUyVR*f^jlPfoi3BG5*%S&eT G\G]ca-A4v) 1κRp~|Z + +uc;;nrjxV#M2|8O΁H?迤l9[2LUVSLiH gc:zRφ̣qr} [\z<yBau9kT˭p7uY1t=Zk{cÞ.uuR7ڦT8b`\_N'fr +y*-#\2qH ^KqaOvN{l)fo1;eoUM։oQl\ր,!1G=L7aϊ?\Mr( C-4U 'CsAL19o3U7F0 dJ:v8p?v$8ay^ZsQЫiH-t\'f3=5 %eP O)|Wv#qwl?ʟ:ىԗgk@>lu܂#n/dYbD/WV'G}K{+w !u!ߥ6uEIN8 B8gY+b?uˉW|Bm8+ȳp wIvcoĸ}~Ζ/_>׳SXI@JKM/R۲ֽ)Y}?` M^Y-L)&{!YּNs󄁕G&c!jzZ`jb`sukUոZ|VYMGWΐ6% ِ!:YZm1/hhO9ȳRF->=>7-"6𞠑B~:I($> n.{-dh0 J{өi˲<ת\Δ"J3n;d$FMΡ=P~o R?fu #d p|b3 RԆƏul bꮣ?o5B/=k3]&mG_QRތ; {i|nBݲphH@ 秷DdoO#G{v hcwh T-Ǖ":xk"*$mrXS%21_}@9wҲCrO:@Ky$VVn.܇y->n +|qRqX؟sȂQjF37qH>?-{b{`q8@כ3D}~rSxT `+fVCu2"7gn/nRMBT1OͅHoNeߡn5~eS`O\h#;,|Ȣ9o?짆N `yc쮇;lTD~3xgl3iBmWtO/{1u`skwϻ?>Ut? K"ف 1`B L +׵z$] 7ĔÐ@K,|AL+N  U{]ҒqT0mub} ;'mp^{ԄG@d3^Wι{BvKMWŚU}wXU⤊`B#Md6Vq]g˪PX* +*̈⌢VPDP:E.֟*Y\ .NlcbfƔ>IOF:K3eVZyQ/^DY8*HksHH da c[_pձTTz6Qg8n>= +9BH 1K{T̗viKVTD5l+Y$*3xr/dxmW~oeW~o? Gg=+"$t[~BuG}c;v*5NqY73dLC)sGlh.e PN61M7MC<*ڀ0DFuA{Ub<(mA¥3HKb3ݠ1xji-PU̔8J&0zaE.&vFIfd(hOzi 2#1q + W +|IA:o)T&-*2ꓡrϗLGcdv ΍/uyQToN6n (KIB2a宮B AUDmq[`kG6TofA2T;UCU5ƒDc^K# ~^BXl +Mju|w79ĖIz*l[ϖsQcEO"^D,g6Ǡ&Ems Fy8)(nt!D?ǫ޻_@L- (!^&ZدO{xO;xlt,^ftX൓յx?/55 +譠߃fǼ|o//jgRɞK`h8`~&ed22O|}ʥό&"^0s" +ԍ'QœUb<3׸~S5757bst\Z=s']Zb48/P$>=4w9R'pG-t/׼~vՍ/GOTnݕEK-KU;IGyj]Qka>/ZH`ltSzgiĻ>3>:Q;|v%MHMmVcGz&~FUܟ½yknQZ0ϋ܍5]˦9P^ΙCidPx|M>LO=~iֱ!nZAya'֥)◿>-\O7z9ļ嵬,'8!YcDAI?_Su۷z^Lûa4lDPf+wˆlt)=y1^ަtvi8g§7NaksW֓,X)' .Ҫ4$>^}Y >7'^^k'Bvf pJ n6Zo_?\y͒3`--'̍Ew3`߳CG +`R"!#k珢C!ۦ)9i~6{b=}YgҬN0\Xw+wȁuj;`&8}z5%,!xSH_ 9/gx-{GU62=~ .+4% lm*ajA]0 i)=n2 3>_Z10j6=$I6R9?T?˷H k'Ml{Z]??TNuCiDb%S QlBY.$84)kiܺc4 x6E٭5t0.mlKd?!A\WfHUX}]SuNP%P%A)mU.-WGO?g1"_5oFC;Sn-8Un {.OiG%hG*A8 lq+^)}<2k +:J{V.%ZRRc4~@1~P؞2~ O /ׇ>Ԉ5żψ,l3`d"8#=Lp7drJL^\$BBHk־jq-uaRQ\ Pj! ?oWVU >QIqjKWʖ"e5G̨p(ށ(P!Is[pguصIlGja Q?@W&&.\)vvY_pa3gg_ϰv'oQb}WةzPIYJv&L2Arjl|&~!D/CNPd"ǻ.7K-[vՍi*C _xU8)AswbO+U5b?%Iv=8F&>2QezMhfT?Dz<q8>XWAٔJ`5g +\ {E{`}K·ݤƠ[gSъ=b22 kh_Wy2fݢM4Ts.?)(7m;ZlW. =rWLYL氋y#aP}XEӛ*&ȌjOϊ8J"1?:5{Nԑ|߶%ڭ rjd%t)TG2VdDž^OnJDⱖ`3Ui!YR Ωȣ +]7oG-W(f-v*C]r ekbO!tD l;oYޜNVxޤ]Lvͳ~.kPʍ2] f+ʪ^t'Tg=}* C +(HITܳ[uWP5 =S\e;2aw3_&r`$4ۺrۙkhyyTqtReSe_)u+;++0N_69045DWxMKzCՅ|_GU,lHdof+TfLߊa^7qMODMlK4PD!6uR/wlEM~EAiAW 1V&6Gx#W i +6v.5kA7Nj7ZXһ }yJE. ?7]^ץ5OZ Yj}&?Ȟ^A햊_Z"Wڸ4뭅Zsʕn#i8ҊF-D9Ra,Y.KsӁ2]7[kDfml5l#l8bZ/Kʔ<6>Kn|/T|NT 4V/F_fJJ~iSuıgMY즦X}1_ۆ#d7 gxcPWۢ*Uġ%B*HM!FzG*/]F^~ +VNxYϺXq!6}y'%o*2)y6+vlN8*/kVaIӯH"G7[.PQEY+ց,D,<]f#=>"傌zW&*RưDgV$nLc^JqXWqxS,l-"NvN:V\A{kVP'Me5_T pP`}ރlҿ:.Jse:-WS!$fR` ng9d)zɅ"5 2Yvs ^}}/2 ȞKq^sl@/MK8ynК-f% ^A ~ u%wcw D$TreaYGDfG(ulBX,Nyy XctwV4`4|?C/jnP\ \ި җeY9۹IE +.VEȏ +`/#n, 8$TG~lIFpuٷp9x|8.,A]3si,rKJFN@HΕ'y2n?˛g^{FpEw2 j mT0@,) D%B@ +n/d Tn MG4"?ϋR@/c~*owst%+ ĨՁ F0H= ]g[*Y SSLgAePoN֩U惸X}Rw*V@ `c0j@L)fIA#;a3ۼUV8n'l~@BPֈ{YUkxtv/3 C/d=&s`Mi Jg0q ӑY^9> N~J~+ټft'F0fsugyy˷ͭk\Q" 9FC͈Po3b8MD ',}V'O yIŻ"FȹrZr}pz8 J^%ZoPG4F^r'<2.y1-q/Tpč2˳BНnd' nX_eHZE)ar:to9 wFәwFxXvQ;qtFlv9uږ_4W "M"T.&7StZx P#]1 箋Ȏ܀5;†bfu-;Lx|2gbɴ'z\%vXhh0Hh[_ _r-N+u3_(KSEpʬ<W`QVso{Cp.T7( 5PgVYYMyQwc[籬(L !ߴ1(9z~8(\:ěA "Ѝ^nӋ VZ*Xm:Jj4*ht"o&uyܵVHғnu4A~{n{wepj bzDF!^=cZ*6z%5WUun*xu9d`l"J'W@FNMl@l#TRa؎ϊU`8__3pyX6Q?OW%",_QVZh+pXjEʂRٹeN7uDv2ѓI-G7ʤĎo3}~מQM2aTic?mɦz ՕM>NT; ;_}_1NS/*`~STl|шVP`vXKݒQ_D)ݒ9_W![u 2~ט47QnKmP<_ yZw1=gj& jux2 +زR +'Ҳw$cUoUJsC8j7][DYmQ, +td% fDO^ճtV f<)?,WXWЋ@ń"QrF 9"fuz غ5zvlYu?U贔y)pseKS"Jl~_7~#QZq:R?S–+%Mj2f_L|wU Z. +W#^SKKթx\x(p<ɗ˝[ I#)ŗFvD}JE&8{o\ XD w^M\eYT4O8:`@ݹٷ-Gw} Oe-AH/50R$(NV Ŕ9[IIDrl75c{B[/HqODrd734ۖŴA"oEstc%}v p]FUOUCՋ ++΢ԗ(J޸m/9)T\ +sK<ڭs[sV$\ .]>@JpRуpTx27o zsS {u͜/QFxY+Ok Z'/&om;Ux[TL h,/؞/?lC)&V\41F?rqs`h}Yn35<1$MkPmRi G̒D0_1e6_ѐ+-Ody>dӔm~ƔG*} mRMIDiJߺP[<_uEiھ,wBOft 4Ms)ITΜ>rSWЩ)j ҏEXa"Ӈ“ʪ q\mӬ^cD&$޸o-}J77˔0 djdL{u}@5f-R`83GnCU(V.+,KH(+^Ј ̍cj`!jQc0mMҏjC1uF]d:}!c%8m#% "~!4]mLgڻQ0l_HGČ* |h\ϩUzF;exe-_ﰭlDI㠏RuMD2"O>ŷla!#X?X}0`u +auzx!ƾT3Ξ՝0n;D~)Qˊ, 7Y51 A˦gmFDoGM+֙I.w^ƥBJ(p4[53zn1/H[tsy:Bp^ؾ>X,ve0GPTmGV5sV>+Nx&YSAq +4pk=47cM {D{05hb6=6 a"Y!52`;ϿL;?v_LmaX(\foqY]LͦnkJ@*:M.KW hbxNQe-I-̇{#h't}d!ٶ~p{Cd +Uo0蠡.t`=th"aq㜢[nkɇJ=ՁU`*gY;O#!DzhXx4|ݜV8Z)tzZj6r6ItFBZ?fME;N&tr +"5j,yenQ3Ǩ-r4=: E0A!,%mZp "rvCj#P䫼Sa>orǙr3wmq9}*mHǟׇNG'򨚛q#xteEOZ )ݻPE>|9 ۆg nGqAh*ߦ-9ȥoo4Sfc2]6ݚR㯘Dw(F+y-Uh?ҁ04=s!v.ll9"_.>[fItqOPpe$c$8hiSS껖V&ڕWʗ.imeuJghMC\Mr0sMAwV:OhlP>Z:T{{.]BJlg;& ӗ7l>V꾶Yy|{gV2'SԟA"1#l_T += +ݪ*vb0[om.n㡾V|M^=B[tWx<:-g_VT[=4e%rq0"W)*ѿ.me$ +?0GT3AP8?Y|u]vpza7m˝ -~\@~zO~| dWq n'4[3]fYWN'lVv?6z3Am Tethwo~ ֢u?7v~u˖le{)VZ(ZYz7!gpYxC#Y66_MK΋U,76 - ^?]9)*9@WO[!WN,lz)u܃_s>- A7_^jSze>0OxX`ɍaԒJߠIoWkHkgW^U]^>]g_8 ?n2 Ol:R {nOBjuޕ$עW|oշ!<U֤đscg (3r7efu +<ޚfȪ$ׂGB&"8*Nwj;yEjߕw*Άc7 +jĿѢ [Iv|Ğgߚ'>ܔI^w(Z-N!m,5cȋEۛ暞ʍG|?9 @+$ +R+:$`Ek{K"iS22&ŭ +3%Kq9bMB#jC6Q'22l/V'vTm2&[ˎM)HA=Іe+Dut!sJ>oG.?샼ߏM'su7ueˉdJ"Ҋ"=-h3 TNIr45;_G>(hxKCd$pD\ θ! W:&/  ===Zvk3X; 1}F9,*͢/u= + 9XcHI}̴Ӯ>S"ØUPhq`,*V?_+܀|t(΢H}nn2DK蜭G";ZꔚHRQ)iE0/17dC&o۩q + %$сH`./.AL3cKg̣с*s#{/|>nTawa+l +IܼMЍ+17WdP fz5pd]Q$5~D4QE)ngp~^/zVCOg?g82"Y3{ o2iqˎM#j/M>L/.F5 BU#5oT @ 8̐?Tײ`=D+ +J1.L1{9|S535]Ѯ :tͲscbE`#Q~E7fO&F+} УwfjUV#?+C&VJOW!^m^Ml.Np?~y0E۟]ܭ-#a:ԄkCT3nomOvЭF>SK(R %?rVPCtimwp,HƄ3y;cEmumRhiVWg׎{e+Ͱ|U{=-GBbKשK*u=ߍY/a$Tԋ$Jb'`{7z`R>W~bo2rB}Afoppe9դ +x ̅?)Ympɇ\J^71T +0*m%޹[]n.-6\SHrqimpź8ኅ̘+h=y } +nG& e+t6,#U9uist:)>#'#Pw\(4 {<#nٵ SL|ٝ|/me'\8bp`p1A7f{Z.If9Ώ}xls3 !fHڦnL=8F^}b 1sY-Z:CZoSS)8ʏn"5K2dm厚M.&<BP!eh?/Ne o-綍cvEb_ƻno*%䗥/)Ew溼v;SaH|rr^qIoU$OT^t@. :$n]׀DqX 2%%Ӓo +IG맶CKߺoWw!dG_jx3E+N}c2^m@҃#!Q d mЌ`qIYi9 $U&<u6"xN7s-p1q#{ֱQհʜcuIYpbekOWF+^)w1& 7 E~ʇi@KT5 @ht H @ h.PkC\#-(7]lw\LQR]X(.]5JdX,=#Pz/-_] ȴTl_ 4" w`,x(f= p'{ 8)@ɳͳ{#ʄG)ކggVŸ6VZ{bF뀧2z# |I_?$2 5ܵSU^%KtV +(e]^qDɲ/rk@s1(w,P̑` 2uds~*Ls1>J.؃ciTel E^@eA9 ԴA +Ŗjaz>hU4@ۡ/hZ?Yos?L8L -&K6OD?11Dz+5n@_Ɓ T. *^8u,/urNxx{_1U^'fIk=]+_ěUϢ{>_ ~B={/44 }%]/NJ<6 +ZztL;Y#qّ|i!^]H>H; Ǘʿc^յz++汼MbgwUL7e漳Mf>GBǸo>Wn<Nռ# >7].[R FvnT ld[hi$rcKeZưɀOP;4W+׼Ŋ4hHH/z}xmQ ]1}0T);Nmz:y}H ̠ +h}Ig}M8gL󘨭!`,Ku95(YZ,P:)ɉ>XyPhRj7`ReɅ-X^И c{ľ~x3L2gP@M54n59k>pջRsP"UbE+(DD?!>?n?ɜ)1ٕ8-"6+ +ق+: fJʗoBtjsෳYmTL~fCWK/ŽPKeh*}̔R˿w@5#Cq +-"xeÉWVKO$fK?`]>,*C@|V} ?fxL%fn~sSCCiithJkkDߵJJ"jeUF;nP#xyɔtڢ[cVE[_Ok.kx [} "7+#5~ sqbRTR(hIQިE8\..1#.Bx|wn|ppЄt ? 3-"ǐ*n6.;.7p'3C:L1` zjt)rsT=u*},Z{3i?Ь^Ykw\ + ؾ 4(,œ$)V\Ҫ,s̯Ҕ݁ -SET>恦 ]2L)_n)9boϔVMZGj2y˝dS&`Ώ?JVUh lI"9#JAY1֭3~w՚{֯je -,! tϻRx&LK|yBZ6g.O7tvܟKvmY]Z +>.Ԍw5!m1u7y Z^rFNL/K?9HR O5-9+u46#aoŷ84Sfn 1KhnadCE>Eot\lƅ[S-! +*!p}ɼ,\;%}&ۚnX'u3׈Q6W[%B݀YS>HoEOJHJw1>vb} T1U e rn/qV>9\#˨?|2M`@] +~ˣ۾n7~~k=p +7E>DOJiYar-un?V'\J-ciF8߶K\C&*svjީ6N +^&B# +fTO>wDgˆ$S6 Q3伲ph\"Fk9`kEqOHl߸>U]Q@D#cE%r\ċJ`ةJ<,xo,8-~g4^n [  mkY *%Ǹ$.7.[Ϻ6;K !UTWaV7EIбmbLY+f{X|vmR~t,4C.B!Y%ZDR5[% @m B4Iw =_DM)aFj()jg}֡斾 _k[_}dQn7GLר=u`u\?t[UW/" ey3(9HZEVų")7 KU@Pt9vE# (: G&Bq@U(=g8#N8֑flI>QZ+o$Q;,^y6sTE SܿeDRPiUJeI$PwK#;P~ zs@Pc ~t +"!6~c.XOj|--mMYHJ8Y<:p.~@7=Уʸ^@;m(eE`uWs B!&m`Ҽ?<Џ z8NaHYBҸ⨘^V%l?< zY|fC܁10o6CQV +Lة;+ͤD/M67hyKQmgJ`{ Wmvjn:ΈsQn}uZjPiSb&8q*7ڲlZ~ F*%?P*`pKCilKpW}`5Gڳ&p89^uwgKɮx;K2 +d7Ofd? C<@juy<ܽOTJ*xA{Yπ« yA] h¦!,x5MPEY_-̊fJDR(|ݐ!Qn*jrWe ГA Ba!@'](3DhV + ^s$4$:HmuJ u;Hr5muN=4m3=gE6MoSd+BԳA ©ׁrFCrFd".AlW ^NHljT^.Ȕc,v5e 5@i}9(|AF6YS[p^IO<|㐊,:E]/#gAo^>fY?؝~^+Ğ;P%4Bu*IQ2k%+4Bj, 󧙛n#3~+,_gyT<{7ػ?o, *n߰91BqZfW SCmwc e33{{ O3bQݐ˭Z۵4~G-7}ooF!0otmZws;pk;&x.JgL3܉w5[ԡ-zi9qL:{4$C:b/#e|+q^>'˶N +X/k9>~-V͍Tie{Ma {5F +zx&5Ǖ_ +coF[92Yi}`}&OXZvstR;XV'b  s#oY;JsCjKk{ǟˋNO-vB륭z $X>V񘚥*NNGsOƛ =aG<tT1 ]7Su";X:3<ɬ%-- uu"pzsRZZ_zj?g6ʓD_-IU飽ei)b)lkfS;Ěs{I.p8-'=/5kCn>]? v]2RTUfv4:r8>2YM$ڇ" Q$0;,fPu1ޠDȔXV/diT~k#C3:S%P| z6  +8S61ڭ=T*Arn ew@KKʕVM8bp&~Z-`˧d՟\ ?ҚcۜfQgd1gXyT@t~8:_%|q|y|`89A[; zjiNYRU[.>eJ ݛLBb#%nGGX8WBϟܕcH5 X̘l30d]$4>Z֩; EPc#w2 30p]R<~x^g?Uª_RX :(/1 q<P!(申ܲ˦}e1GD`NM3W@mZ%ŝrC?UR*>v&}6QWaI9z?<Y^5K23F{FB)oP`EB'cS:ɓ 3 ]b= GP"%-V T7 I[ ]2r^QmX0?IƆ3xKV*g.qw ؚۖ4ވɾA^_ЖM=P'jM :;H/"Hbn0;3a'Đz+[)I`AXeq`awcF? is!RKxpٷs|2t#F`/R~yC|@,I,07}U +Ed ՈppI1ڸjCa8+. y y4Ar@r:{O,n!"H wo^6keJXU1\b[V }ESeDȺ'>d9•%9n :Qhؿr?kE-7 7qr29(\VgX"ZQ{/XzO~37ϛ$w3IvwQ +r*x1- p6Ǵ.{LG+V1H8䅍_ +?QXްD[NhT,H~4#=>(7y+f.7D1+e;MI2r<9HO:fs<`gIێ0.\Y1qtP8ŎR|^>9싺7chso\N߭=dknhھwGD,#GkEҼJ-}4_@s$`d2ɳ[0wFoUg-6(r&;ؾW+~f~0+u4rvԮ4(UɯG( !ɣ¹ raOPdrC:ߢ-LnV;dٷw\gXWb\>]_?\$E Y62i'ZKnBG\II+%㎷iTu$g:wO5L2F,pqgZpNzlM;V-qc;'0q8 i5ޏ`j# ( aN.fW@|\@~krd iI(MkAi?U +j-]L`,opv9B$-3iߣ–f9b2@@ E0,, +* J ךK1}:Y@˂nu)N־TFZ6ˏ+F-?X +~cՒw:GBnor: oE"Z, P=@۷Aebbb +(UE~Aa&i/ +(e*WbyZn9iF*]:y.5RGi`x +S A-FPT*ڈA6iP*#jj-ܩZ)mAxP-' ++WFT N5+oa=)N`2~Ell#Wdwb.Adm@wB` N_u' E +hv/S'N@{aπN5Ӡ=h//vN4@ ߨRkjAk}̵ʴ{Qy +ɝyP0߁Fdԉًr@W wu Kb@YE!1'8&x<=9Zz~Q,?ʜl;kJX?\7C8";=/)P]> ^ix^?D X,Q*Fr&9H`d06&ʃ;`5m 橡;U8K3`1XBrN$dw i{USM_W +-'$"+cB)`eu0f0<$ȂCNږH[5?n` '7E+}VܺU0 ֏HBI'E)St Xy|ǜc@1 =kR,qŀLYh_5E@@l}Ho)@w5ݻ=@hL\ol_Mi +@Bct[h D @ 22TKt4sp9WOPdzo}A=;<+YFəlr `8_݄[ͪQ.FGW&1Sl#Ǥ? +sz(gLOY6ise/ jsq=fǥ[6*7rÑ࿯yܺ2O\D}A砧6'ċ0b(;0/&An" ׃= _xàDNf*Ɲ5M&~ֺ̹T ;֏B\lwTJCSWXr |MYpO^zc̎y[A?`/(_W/dH]܍b9UteN\zl6H:l8ȽHzU=:b-VD lEWa1VkEtg8aDA>GvI[1yܛ7HW1=[(C0.ЬEѡhbKۭmnٲ-Zi^rx[Hï8+8B$3[6v7Ŭ%xE~PWwVE] 3C!%=./QK_BEȻrtyzk24#[2d87yDf̉Йf}BmwW,C|}woďZ¡撑\_~"Z߮x iN9\Wf}So=F<{ $JAdtfk"Jz5}PQّڰ/`:n}r?@- +ACa?-Vq'ב"Ax{USG-ll>Y=>鏮iϙkòekq+ƒUy"##Ag§h3Rd3SN?Gםh{9Xɘ8Xx~Ѥ6Kr08#[ӯy TT }jE)bPLd$ӳS4Τhnےzb<9B~H|xrepL!ܰbEo/fn'Et۵#aU3X[+A+vpTFT("cělRsߘx3ρi+lRm*c:c8lh\VE>H=ܣmɞUrٴbbAw)HG=k^Bڙ^ +/Eo(& +7ʿ勈)Jq>1/l]YKs?qMwtVKJ>yZmx޽a19{Y10=\-0Ƙ^m +@ҶW F4\CJ*H̼A$mv#ް',ȯ\Ze#^m±gtX#Vސ:Ҋ!`3bH{,14߶椿_.-.?ZLl|&w(}$dM9|@+ }:er"^q'O|K$aρRe[ucKU G(IrPH* [E \o5[ι73:#%-H[U뻽N*@Ojt?mkZ=nV'jIr{,%_/?KɆ @y,d//U[.߹Xͻ:9hL)*6X}4L(Z( 7ۺyt0L?n-TO:仗D`,(\vYO`!y)p%0τKQ=z`+Ŷ4w3c(S= Fw? vF* +@d+5ley[lsS[ʦԗxUV"]/^Wx.jv99G>ٷ&chrZK|drnFHʎ[=R3&B@ڡmֵO.-hDt8|Jp:f vg?Uex2i1F?3Tc dRdq{1w^;&X/LZQyxI€4g阴K 3zu!M!3E_^Ǽ5c5}cVԀD[E>w)gws(C1, j8/;T#NW;,u~4\w&\$ WB!<_cÇ KBi$ zˬbԢZD[iC4/6O"/Cz'.& x 'C79՗m]hvBƒ.tsEܳVn2]%$Xb>; sN%XgV7ufI X>6ʦ;t)B=LcE^ɪO.suOތF86?j7H°>P +ꥍ@,5OY~[2d  +Ɣ0o TsfOn*KM'Dp4#azb*ХX(?0 +q#3\]dpW+'(l!@vmBL;@ʷ}.gƔnDF?0yev7q+01)i /"}i梫՞mԻnr G/!ɶ\G_w^DLhr [ +>6rs;a]RbLݝc2Gğc<?)Ա#6߫7 »o3paF^:.c vO5F/td2gCxں~ܦ8u)K- +'RO9\D>: {(w&{ƫ{s@w]66.P*8 B"p 4Wtzk3 +6o5ni0M֠eu+n׭)2hx6' ≳Pnꄗ8 ?043RѦc^%W0!ud@ + M+Fz@G9#@-:8$'<a$@ƕm-"sNAS&.xRTC9nu7h8ޗ] ` ~O_%P/6/Ɠ;9:`{&]_ +"[`?RDbs1 *&EQzvͩSg^UݬDhGEVKTm(XXhw^N=EwVe6&|²$Mԁ= ' a~h47 1!^"Va:)AX >BJ" ܳLVC b5efqT#>3o ϔ2xY _fty8/ܻ@*P T:Jh_=z@idj +@D@}a"gy(S@MPҭ"ޚ־\2̩ e|{Per礁%ԝ=v8|"K5pMFG~=l(P +}с^spt.$/`C J3WѰ1tfh3.iug8rLnU馤^[YZ<gV9T;74A0`ЧvG`;yfx۴"`M< eGQ G F\3EЍҠ[Ii +A8x%2ze_{EVd#F`OER3Pn?! Lp5: `y4exDࣛ +B0A/.1U@Lu;2 AХ3Svœo,-K7,_gSn[>uAV _$h} 4F"mī bxt@b@ nșdKi@hYJY'֣T]ג: ̿;]t,H@.WqYkP RdC d2c+(?! %5@iq?BiBoB)v6 %G,*JjQT肸q7V:T}+9$8K𠭹ʦkԞ&f7#˯_}H`UI]\oQvMrAΚ'F8;wu"T'/v &—_9~®+{q4}uR8o|e8LMf +] 8h+q7j76ΊUʈ]<+~s,# kt]q{T|MO|Ojp=~X{{pZ= BsE#)M讄3I#n_ApvUKu[jTxozY O7\K f$u |a#\}֑FF5G͍W7Ԩ>F0c+W.b3mM,"` ,x5#_kUs?Yq?=r4~mAk\P+ōQ?ƫl=V @W:lfl9tr UɐwW14q'Cu3KN\\?֦N?ēo~ *פM76 I-T[XuZ{t[۽ƶs[e5{-Ä́Wf2dQ <U <3E0dsL01G?]{Z*j!kpnܥPnq?rs2nyS8MiWn)|G&?ЩGɚS}W ~8!B~Q6gQ*@\B4Afد@kqm6ioශnd4[]ռP1C6#DO9t\!N?kQ1ƀpp.X(}&ȴ@۱kafy{ozr-\ީ<:;'g/ Ȧ5bwh,vaLkN[ÉU{C ?(%5 rdmoo?"U> ǥsIT܉hc.m334s,8Ffg + pamloȰ뙿t pm mhSdJ%x(JU@NjHfMg`~+T'Cm"˦"܉ξz#Ok$R_XZn17ܐ[ gHеF6LW8U)2W +ʗELˑy?L@Fog-X"odL_ܔzn q/խlM?z^*V*#3U:Kcntvpg/&kO^?fcPkaڑ(V4 49ɞLģ6Kl` A)U4tO|-AQ3Ĝ,.$4C?}=kotlBo(k`(DױfɕzE/jcʹTC erŤI̮&/0E$?0CPo6ܺN\Ú&֎s7ͭ%k|+-` *Πʭx0>[?'lq׏T>ͷr_'yJ VD~붅58 Y z3 +v{'as!Daq<;a62/02l{ ӪiwC'͍rDk"pʉsN1X= K 5Gukr[HDSspyN>xb@_?PXt=7I4 |r2=pZQրDlPS%wA%#vTlMHGXyBF\\sҿrmpb]cWa s}8ӟ,Efdסƫ$?|IrL,VA}righ +W8Y/z*Ucr A8wj(aY<[[όN^$LL1k[lRŐ(Rx.p~=a;bl4Cɨ{@Xy\/T}˕;IDS~| ~q>1CI^G@?Wjrȯ+BA%" k'eb{aMQ8>"(/Rxk]M8vo}mud;ZYΰLU͇?ݗC e-!H .3z %99- 'D6tlM񗒼rnrvzU?fx͘@%BO?΅f*̇qM|.pw] +W9g*&vc/a(_7&"^{ԆWX"(nTy^=6AlXdBpusp'".Wp- +``~,^(r +JSi +|-juȧ檷I + 8Yq !>Me9zڜ~hvzLAWf;16heNb+ tm}YpKItCGmV7ͷ,QO5hNyďfKis4֠KSR4}؃^@'/Q%08[%`r=10.O|@8`Mf3u1o~xW7LYPV'vMWB# ̃*L3&R`R,*B`)>v^^`ql[%X1 a8urYTA໖>stream +Hl북+pI-֊Pt)"""1{/9=@G{5_m8LU@@wF%~Ri 9v$[MgтE;ʾee 9|5UA~, +@FA0Щ)A'ie:.{miU荓bhh@@;!@Uy G.@ !YL!My +7˨ +t +|<ˆ([ +>,1A1/PO6\TR]TӚ>{wQQOnQ[oZ.f.X.BN$\18쳃G>yF`+p)2KPq t4l\!^6t VIKa28II6[ j\z0}i9<՟P'ZA­%(OG]`5fNwp[`ǕW_-51Lkrګ:˙ҳŪ$1G%(;q(fpR4H`{|v4kJ}蟑\~#R_[8(zݠ&ߟ?J2g}🼜11OVխSD<&Na$~tow jzϫ FF&B̸X&KT+S]:٢9LMl܎u%WK= ,/} ~B1G%h6]r>,fPE6Q٠|IIJ(vwuڹ,᮲>?E{ I#h%۷=$$YZ}6c&IlWE7Xu2EK-|6ZQ|E0~aᚉrL9n+x91R|7,ֳTy줥R=Uᨛ*dk}$`7ЁPuõffYk`''35xUء6o}Q ڜmA+mYwrUbG.*H@q"xiddMRb] {gx[֢I d?|w¥GyM=JO{[-_=.7Bcɻ + X?9[2)zRb8 {>xfe4fB궖E=>!$P Ѝ4n>8Q@9 q=YvOі?r 4Rk^ҭ` a)~M,A"J@_>:(ON{^oBz xJ1H1to6Wk>+Wp(CUc xv>T{pj{ے_eL6!L]s/jJֆE!f…)A=mQ׆L4E5vxKfA"J\<"_7n~.B 䨳EnyPdS18qNpTSy6d%0}"0M6趶^}pݎ0\?ѐWmE2ruMr{AZRC^(,kC׆/7Erf2'_k˄zӵrT +Yy ^>SC# jLzwv][<ۺia5_7k$6~F_^G·Kz tVBS!_@ .ZO|MopXi*.kYԗm%txwG /̓ۄԬ~[}V5lEfmЫnXѷ/LWGָ^FNzh]Tf*PCgR$ ;b7}łu:}< .&3n as*-'CO zmeKiGzA=Znp4<4TlJXzٗ0c&~^L^q*8`mk# 1k}DIFRct(6d%hR |7"aOR͖[Ys}!e

jbui\s^LˉM{e+}eoZ +05~ԧ1|~pDϘ;bF6sfJem >\*7,3cZ#`qݗ'ɕuM"TC73ia1sLsN=BNcA|m-(Ujc-g8w^en0<¿A:B(~x m>uw;J5zP})] v9eݥ2 (;jP1¹䧥oI~Kvx{`L>=j#C򪳫L'}W4_U e9"P:]58fdN& CY_S_6ۃBB^"o_&5f6E1º}t^UG.d1+,W@=`V4VŮG$ 8blT{vuODE(KV|i3"ԩx$G"He\YDk;êFK+Pztc?O[Ɔ@;&lbcR9oa.Vj(Ptuv^\ű%yb ` 5Y6nmKlےK7`;E|2d]zQ ʨ \tPY/c㣲RF#1L+Ըlk-ZlB`:Z=yOZ-S[:>^C [-qxjt_-T!{2k+%p}({z ?7ZzQXN`.2M95?幬'8EDQxQ%QT Swς;4Ѥ}B.y"1@1 /j*ާo1Bow TWΣX T8JTEvԷF$zm ja:ZxTo5PR#҆8-'I%B C==ЮLgEp@mv)8 tIݜM}F~=iyQҸ]@kq lzKpunʺ!J0x{/K?rx]؈zKiq%mi ,&#t)=PI&CW0ts`v<0AD8q0s `/c-:*{10lAHs̲dz>Ʉ>X|Q>INdnVF%[ c  Ĭjԁ R+ X9k c`%O-NI(H<Հ,t{]6*Ou;s]v[%X|Vn,Dֆy%i-;=7?6ljB"6h)pz܃gG; U) k+hxNP/lHkEgy+͏i{r^*MS룆D_{ xtC5[WK>vJ="3 DfI D{8 Z\DQM@̤Q1l4T"Y&s!"T?`92_;~p~kD{1 1V m-d)%u_)D^˰R!bmRY AHC#ˎ .ap|e'@-=xP2 +@M0GB̿ ]¥KUI^c1<}$hrRi#K/ rnA <(\E3VA﴿6T|m*xE 2?PP#(\#-#bx! +q Z*@]oǟR|`}Fd??uO?̵z{34N&vJzF A5+73Klcŷ*jp|a~LqjG+[mIRkb~m#ǧBdfP^[JBfHr?azPQL;9~cfx;Tݤbx#7#*+mN5g= [/ y+z;ܾ"m޽l1YAtC8D)Y/S۞ni+^ulFMwBho{3|^nWm,M_r9RdZVOw׃d6VX4wwsRuaW_Տ7M|/BV[̬h$]dSK\q_#NQI_k1su;\k2n6ۓmc{94H7ꆿm=4 +>ݭ5wiEbň~,#om!:zB3g~YPk7΅MkB(le옋4vGG2CklJ;wy/Emn4_᳝CkKYf W01A$IR$(*bo쓧zUz',m3Yv-wZA%D>װB zQX/*"n0WӠ܈?_ح[~xw7.r11( +?xs3ηӔ}'yx]&(G~Jw 2 N3~c ݵ1r"T p[6rnǶO+o+Q5ڂZGfjf__ڰds1F%Z >i窑xkܝ\];G=9^wV:TICZ~V"hjlM0 +zNfw:@I@ ,דnxl!T|inEPj^݋k#󁃝ioO=+#zeo|V٘Iivɟ˚ÚٽUzճ馠M\J1K+r_a'LCTWը8{QvͦAf~-5*'\zn4qW*k4CNzz6ocTu +H2B|/~P]5eRbIHIL/>Ch-(Djw UxV c?̚4W+Wohn=aodd֛߳%C;JBPgCW( P3)э\Zn"} "|ۧt>^ Q8έ̀`pƒg<#1*j6Fw|MpUuQOISF+ʷGNQW&2o3$*c,NEtkF|&)[g g:mU8L0)YņL] +ќ, J&B&H-U]?]`-g ZuW.ͅ.M$f #J%?׃ve͢,9[XG5SEǂAF1I\%$l.dxv]ղĮ u:,zg3Rht%QB>*D~i 8OQn;\س e>Lf@>}YuB uTR,moxx"~ f[ _0huѷ{mvwcr\1'?U6M|oB ZH ZU8q'qm`X9,v +0fUQI:%3b/{Ls@|sL木mk\C#8ى;69c|#1쯣~45.H7$6殆$u4FJ_ʼ=)suDH̢oεR9mAӡQ/]dR1<1/%skǛ4ꚇ,Bcձد]΂~Aj#(‘n7R )A3>o~&΅~]ՐBq(,[s5"M NN}#2k uNw7 èqܮj^rTvZdw{^*E=$pgUP#8ꃼ P PjCǢ1mbKPnb1b[; !0ZAWqWwen }j纣__I|>Al+Cw-)$Q !hEqcGDQEEPEy/ĩʪhmm@AP( t&|U +8Up~pxq>, s1oڝR3!2tc?)YgL8O?#[<ם1O @G 8mwwU%}, @vrS99 ZL_4jDBJly>8>?k+ɤxOWq<3?S4tT 7tV\AI WKFz>J ,c<ȿeod@OɇI}(7v|G,L?VKo'6].^QnóN&<Sy:dxt㾋^.^&Α Xx6[rO)̲N|F$Gg!Y3 +Yf}z`r:y||pz}z4wjmo#wژ+0YprvƟڱX U}+Ϡ&w >ÖSΗ\}9>="Z;x?H]Ts*4~Vl8iiRn@!ZqV*<; Z[*DL¤u$Jxdi yQl +ڤs.urE:Π;b5_ؠS +G9Sە +Q2R㲼Yg3f6|,@YenvǾጚ3xSOS?r\-i a V-nCⷶAJFj&WFY7{IH _w/MJ]eٲvE^L=QBbx {I |r-Zd&&>GOIۓX*+&wOɕ?0MZv/E5Nl :mf,[O=OkrQBtOBmOxj!P ̦%*ckJӑ%m=ћ>eћ͡( x\MUh`f&v hF*+:ʖ=[ڏݕ4~3T c8PP8W`u!TwNT\Fh[UI#7 +P3,Bs]Zc?E" ֕\pmLTKXúZ(L_='P+TI],CbT밨0L*׺Ӗ̛g%;A(w<7Z^|,),¦,JQtx(iF/#9lsdn0ͮ+_+g1v_ې +r_?x[jR^U_ņ؅]G~mqcc1@f耋o4qt-^WJjy,$ QnU.muxt6 ;%mu%9zos$"FNI!MOWOx|ā1dgqɬnM cUqX"OĚ"G1"ƶ6f?{s^s~o0ʖ<&~!T5Vy*z'7೺qpecMeI3~oـ\:s@'ٞ8$2RϚ [UG6duĥF.$>nt%atXt~SfzEHJ +O#pSdqʒ͔wAAc(x:5*6#⹛rs#~jZɉi1GVA-z'81nu@]Rj WU#^v&ɰU K6P<;@5/@hPbh9u $2koAyy8߿0s߾|#ǂF3R,#އ'Rxpl8&^)8k͏]4+ZMd ht@x|x@>. Pcny@FuM^ڻmd]D AErh:%UП.5RA }z%a.*7\V!nfSQt)zGaC@@[=4f{@^믂w^7m⸤-8yEJ_WD%0% ʡ>cH(b3> `) vVp`KV0t +NuiЯk$7Cf0kM=D%Zs +R 1%~ܹ2[`>J_"XaS@! ` c +`9T"`jva<L@m'`LoR5`}h];MahvU"_e*'EG +(/Ғ"KRzC|03|F*=q|fK"]Xy6K8m.eU% _6AI*YAEQ^{}uS[PCM?0ŗHg$\~=BHY_Bp;-ј[iۥ)Q A}ĵON~VrC$2G5 L@ . 1kDMg=Fb;y s"μ ,r]7-zG'T$6H)F ĥ'!oUƛ\QVw䦲g?. #@j8ԎD;C4P!Ů@]ByCBSZk@ܟUd]I _u OuSq a<<@3V(s[*K5پrR r]3Z=x@˽ nuK)u}@gZ 9'VNA;.W(J?{xJwl95/RwVjH4- 9F jOr3L +`5ؐOo/3g<3<`:;D'tCGGhR.qd>LA;GX7͑2Ձ< ө m|qBջ\ +Vl[XVec`q}t#(9I4B=CAz0PQITqgF{7$X wN}OqLȧEI +>o݁U'8OjaxY/q/( +M'jq\? |*ɥE2+~O}c_whBl{',sij$h#5Ax\pE38Aq&/ȿ' 3;R{z1] w||i '_w 0vOo%09$)[Cq+P*vg(ݵ<-nA* $ɧAb.HDwRPަP6:G-)?RőBը&$_LybsރwfƟU"WX lWodg+ލ+3٩ӥU"Wmo{7^M + baZ)PfƯNyS}7BkNzPjycS ًȍ֯# +j˯)3!ףpJ%7ٕWvwjAx +Kcf#eFFo̬Wؾ s {p5W7ic{-\[|gk)8^JpQد> +ZfKn\nP;VEy j{ϗ?}(xqem&wapz_p9څܧ^};[]7585a^+n&v^rGmQ +e ی;+ 03y; a3.vZ̛ܶ ՛1§vJ'u>ju=P?6o}wzpV1`=V"ecފK]B鳙 uƫ(Ux(Id-Uux% 'F^]aMG5KSFc託P[ewՔ~[+))euzQaj'ojD4-=kI4QgZ8Nn5ihvX9)y7n2BD#+u݀_0|!NfxGziolyO撛X|EI=uޤ+{=n6V6V61pkآ> t^Oqʋw1@OU:Yߑ^7n-71C-l|~Kĉ3ԶijC.]^~R <[:Z{q%6c;v2Ɲ51ѩINu?qgyKϿ:u{ݣ$?UM;lFuD?,61*5iՌ)C7CᗞTU&HÞ0-c/-諺>u=z_J ra篾i72JM4ccbckc Xbz]'AdcmgZyo-hU]vg +)oVYk#Gj.GޤEj"OKP|$9?_Id!b^Y0]'@#w 8*ej64[Fcb CSѬg]~۞r4' +,Džt<3Ik-?( ǁˍy)jutNoRzfh8W_e]C+i߻T)RSU*Dˑd(Rv\>C2CQ~gB:b62.rx2[Lε/@+G#Es2mJSx[kr7,ͩX+JrXܥ{:Kw~bGL**pm՚J%XLiqmp9q(%loXޘC G}(ļ%- +*-BGaW%4қXQV9ݪ,qN>jkg,Q5/ow!} +U>(9s3]a߬,O\&d>})->55;WUR,:-"9~79zJi2u$v',¾@ƮR+mXlN/a5jyK|{ÿ/>9ڕW +N(M꡻F 1 `+Mkg W-[~PC(Ye؀|h݆ÍuE.+U r:eY#bhQ9MPugÑl'd)iO0pEz72 Ą$ b>&I +l,D#TY{CTӇ'h69/#򞎅㖪?gORkJGm+Lp*3.r#| +PewD58 ,HUi |\8kxjʁ4 oչ/H}l̅<;➨'A7ے]|rG]+j 0(#O1`qv!;Δ +DF-z!+dS a}3O[ߕIQ"rmKO?,JO om\Ya$lЮW;V`$R_~n軃L8F`39b24M1Ʉ&a >VRIjO_.5>RU0i lX8P4K]A=3[] 8-km>Kǚ/QXm7oGj+drK؝R_q'l|KkO},MjRJ&D0;$h*F>0B, +`oC0y &~TG> +)2{FsRcTV3R^/M:_Ya.^Vl +~2_[wS lU<`[s=g`߾CżV忦cZd} q0r[ιZ'5>svrUb(j7ƪc)R^t&Df<OjM_E^Ӥ" 'p LpmgEAMI=8YMI\^]@Hm`bi.ⲟs?$d|3 +!ڲPr")o[<zԊ X7V2Ow Nt?{VIJfI y-\2OAݽ.2]%wb5KmֽOV' 5ίM_ 5Vl惻V˜ +O3P + ?2˃rAu@p%ؽ"ˁo]e>Y$^~4I<(MTuk[ر.5J(X;<ɠ| +Ez%l!L@Q$@X sBh-h +! H@%6c;T? G,MIݒU!o 얝BI)O~Rl+yBiyo?J>l4@8uXrc@yHm *>$&$`!q gV*!v,E-1Z@Ԟa#9vL/;ך?|\ M(?uZb +$y__J[DF+"߾^r62M4ULHQ' $+YnVZrOC& NjmȪ@xHKqKe)$w;~vqJ,(J\6#/ŦFp^J:GK/b9% &"JBCU(A؅*|Rg2?KPhҡu(JYc6Y>o=S1YԃɱO˯<:Y&·P46GD4)_w԰ ^UO+϶:szBg2)Mbі: C,#h )e#p8,lV^ ts]ijV~~66;;<:.5,@P.}N:mAKպ>n~N/賢2{``%&Շ06Gu +䨟K1/Ɖf}c%K[jU^ɿ~odh4<X cGl9O0VաaE[ +vi6kNQkHQY`IU*6$G\d̂G^$yUz +~n._>&>`n',%ͩN2 +6y񜒇/jp}߇;* 2efķoēQ'ܒBNZ>{WGRnozm m_v^JؐQґ/88u ^ +[ qޏgH%{;um96[Fh5%ˈ(QD)y|ι\ss}~ (e5)SoffwJiS_)v#)[ۿ3xrI l^Q(fw9tv7L9L'\Pe3TWWʙz!?yi\\;Y /y&B;@HJ9}JwZa{hp'O}!=trcUԮRz]sY{ppl' !e%C˃ʅv Wޤ +~Wy.xp#l7;IX_]X]=g%.zu^:aPftCr^;_m>U+5E}o<[ӕꏟ8dG"sk61C Lwʟ1o!LzwtPpWв}b |Q'ue#b?%#,L76Ekg_Y+фbꡜo46I5+]d9= u.l{\pn(F`t"6̛Fh2kn4X)?99\UDyfN75 殘ϑkq1ڸݠF/cBN%M&2h}L͙'ySYE˒<YɆCrاI0I4P@$ X.m K>P96<oTpL_"_2n+Y T~T^z55'~FQxN_bMF]nl z\:/,1R^mF9 v{etcrrBks*xo>)TH0?jtv\VÌ`@s8*y8~ZeK,Z-%8\u~Kz@W`.\wZm_MVg]/dሃ fLzW +4 ]=ى.[׾"Q|?H UO.).Dτ2V e,+"J˛rۂ6_u_ (pPfFmҥUZ;g, 8 ȴOD|5"6!V![__'_瀫<ߓ1]Z$C9g(M4>z#B{c&8?yfhO\fD et'[L&*T9r)`@bW0! 7F(m^z=ynH}̺ՅU`;Vʶ:RqưPV++ 'J]> +zqzÎ}I9^ccxv@wEM) Q%(Ն*.UCHh*T(x1- ~擥( sG]݅Ppi EڡPݗÐNgsɋ=jmt7o*tiF ao+y~0E?1=¡ )=~1zaW gLOGdF@AXjM]w ?i[n (TZ9h+ڤHnRTlRΧICg>幬,D+x/!Y1"͂`ƌ yY9-T[.EV:V̝ OgJ5QiiR僡|PdX+4<*xWJ[J|X(ExEٜ4v\8b9pt&zkzz!\7zgNYˎ1*5+ŕJ4F$z}~hAsqٓ5#K@ҭ='z,f^?$){e!PrKplfg3Gc:]jC2RMT{EcI2]+OecKBdmQ 4sV3RdO>33Œ:ͅ4s:|Vдt9vߚp98U;(+d gǐ +[Q)?8@D5E)(Y[LfsSlk-Zs K%}ي9ÏOsҝ9܊ps2c.{ +,x2g. 3=z(f6-8_ aAS+H7HhScB1 pcUZ%_'׳{Z)_E胘{7B./J:7s_*NCGb%7h`cS cQߗPZk$xM !H$ OceXK%sjc)[Lf15.=텒V]ܺw?h۬UƌZxM~v?~J9(=[$@MG/]usF h#.>1$[-bv^2㸧Sxkɷ)e{pc"^b:w#4/`YI?8]> {Hy]\e@'Xi`wėb@>@G{5[uJ͞7 {L\'Lz1rk +k)>:~DC3 h =@W>/i@憀*O +HVaԭdӄz19iU9V5ڑ4O1T/dgwurC5Yc@aFX/)>0bh"xPH'T40?L|20ڈo@FgsZm3*j!USzoQ-)x5;`Aw\-YE1jgO g50Q6ۤ~E`Dy`[&e io`? X)YL撒bq9{|[BIcu+$]`}z.8I `X#mS'kɥS!uK3p$ GįzU%F-n+%W Vz$T`r8]W=zQS Ih6m=ΜNR{T7lhց)P {g#}TMU1Jf% ל#R%51m3}T#i1{l6=-Sf}| },/ƫzׁ*fP~܆U=:[~!59hrK_Ghn}|/*fzMܣ¿TJoƅ"X UK NY)_ -@Z( 4&9J.0B?B҉Q.l]ԡ7h L_#`**潮Nd趒eU3y},|bF{oP?w~x!flgLwHq  +\$] +w;3s#'9ʱ,~SxA_îlCZy026Iۘ e +Hw2Qsu??nkXYm?ϵ['@ޑ~+H<1TW$_V-_N4 /}ֿԞΦo7_=]Q}ۺ<%]Y cb6aܥbn\~-@HxK/Nn6='{}n̉^#T-gC@rB;Z1ۊY +/O9& >(W,fܙ:U}8M:Gw_ƽ#3t@LVVa81469Խovve -6U=aVv"v/ 3yc0)Ml-˵;̏cT˘vA떲0AG8+dƋeְfb./Z=n.p烛NjO[Kܚ瑑VSB$ +t .g" V\ÜU9vĘ^?/%+vj3C#3_'/gT7.J#('uX$E.qXl)EY8S8y7a:r%□yiCru򜆞S=:s]D;,t +_j|m7TY]2cSuHV?#HbNF55G~'nE~ rot.=mڒwEflCayI[Gk3)Tj/6q&RR(.T_C + {9ɷD/`\jX4JY<۽.@Hj\ +>27Z)fCY'_B4?9 mF-#$nHjHGr})Ca{U((vPgTlX󟼧YYy| Lׅ?jbPӟk|2wzZ#[ :StR-0 Wc3QNb/^s?($JWZ@_bgXo,d@:]lk6c#l`Or\>FR:,zǒ-Z`exgbp.(j+j:G?let=n^ V_]#Ft==9k?νiR@K/k/j,^qF!yxP*,FbUAߌ+g^X^G +fS.o^GG8%_j+tb}1l췅|&h9 +!ʻ`e;ˤZVYAQ^G);FZi~~̿v'>tH/,kNmךrĎ"bFnd!Jx#xR_cKw}^;NY1T+θ sUnMn閵2`4??xaZK +~ğ1/a{Mdʚw?d*+:Ҹw#Rӡ'sΕdNu8'::!u놝swfR;, ~%p3L*u:4kȵ ߢe&M. +y2}ȴ? ;ʂO*V>xi5R.SU;D'g:xVaAa{kuoDzE ~0$9+l @m]aЫaF,撏)K\;:Wrz`?^eՐJ/8%M%9 +> ݪ}xX0v|wQs !s iGHhlm=5@ Z 7u'Ca+n#g~(MkԮ梸j[& ZGT +!EW̨OtkE复XQtWAX1MBzvk4d4W]coL @ 2m 5K!"*'"LJMfQEtGTχAKoG) 6 0k6|C| % 90!3J +`"_]A:*v(4Zx9T<w>O csHE/6{ςV BtQC4 F `ɦZR\YGl!F4'޻SĽ7&beKrg)FKt4&Dk0v1Dn:#%/`D L4 +3Йa9FN4lElLgJ+ϓ|1>3i'RsBՍI #_7".n*Y04&UM069`}΁HA&0q5D~~ݑZ LG4Tn0lϔR0@5Y+2-aW&B~q 7YV=V~HBk";1fJnll[ [" KI)DfaE_.# X `3XTlV)9! zKdm(^jr`O}3o^uQݭBEIXu&-CFp@ޮ&[,n;*-nĵ N]π[oL$2V4#S +OR7M }{-~#lm[|ف'K"D\!HG7|kKyy' P56Iԗ圤%_ÇȔ +=#iSPC[1rtw>_(~KܹB>(zFX<!~3"DنVMQ b.2)R B{>ilAVO /w[ZJs*ȑ&~:o%xڀ?_H/ڣ=OȊ6ɼ!# KEȺ cH`#@j|8l_!$GM$R&V,(rWaS2igG%l |z!ETFxH*k!CAt0Y r:ERP2a@T%78wCqp\G Hy5V׸*w.V\A ՗/^P#B]TbbaP +a,C9ԽQf{MhcsNdx6%hI~}uA]u}d$cP>T$3fnG1|M}s}.SF07ͩI|B}yZO.9}9Y Oυ`9JF;B.4j)@` -m };E'PPgRf4mA]_S{sNɝ_-_}1]F@lCX:C^ eXmڊ #~Pm(AW S$AogĄ<s02^}yY7ϑ=__x` +f/~#) VÂu9vi"}epQw$K(.!EǗ|6*fɪc̓.Zᪿ]`3Fgrct#&l.B-QO~&D& gmn׎E:#)ߘiiΕlUry lߞh_.鷣 ֳyﰇxC 3h'ZBYc lm9(ҒrS5i"JP Ӹ| _7Ip8Bf4#{<:4!TC-,kc ];jv16ŻE)5;W_Ĭ&Fcvk1܍g;]qYֳ}IMm!2~ (19-dzk$x/;2.]DȿB +ß߻9EeW![)|~|ƍ{( 'R CwPi$cJKE[#%Y#*̦fyM87lj,h `BjY(> +Y:Jj{9&t0j/,"j)B+ߦ!vEQ+hM{N̺q慰:,)p`3aVW0l}$r̎.Lh_ (I~27]}}xs f{^[xswxBg/ &|'zysJ xsOxs67_//#A%/GF{J SQLRݔt>y^ǝ^Cwc"sAwYڭV:M5oogTgW,\*ȉgKut<.G%KoFA*jԞ(ң;w|(hr|u36V͂Ud+ +jyݔ͢pNz#9.>\V}YNݚLˊ` +n+`~t5ͲL~,uH,؈bOmӂC7P{]=2Sd +qx$`w'~ Gᴌڻow[; 2Z=+l*&Flys`a1ÌGј@nDYҹ; +ck7Q*B]y>Vd|uvYT"#,dkiqBsyx܆ZqNgT"Z=76wЯ8%IB#bq5~+)Y;]CyP]ן<[)Tlj9&4 b4x+~XYp `¬z%[2[H,%8iׯ_{82xVv"{6Sl>7:y+gs9qYkB [GeGŧ@֊e=dc?V!g~+N xu(6ZR' 1dQ|QDECqN{ ;ѽ4|V l1,ؽU:ca7zhooZY''h5k9TPK:Cz0aӠ{ E/9N:/|.#Na vՌ +.o&gYa*<ݳSsD{ܲID)\!Sķ۾ݝ?V8Yo%Z,xNƉX7@dr@=~ffz@"힎zH/B"lZ8V QqsC2|ajOuN瀘?srռn#,:~@Ft040ᾐhgKffԺ:=w"PP&}seeR'^۩*[}P} =(J""8}3τQŏG%o~ +1c]g.^TƨͅjeIF/O|QsvFgFlbt?DIbJb;ʄ@ k{pIr\:H5Nec=De^\[FLԠJ^F׋&i6QJmK]y1SdzhG1 5E$ʲ9eHwM4=YǻLZ"O_Z x2BA}$_"un${ߐ~#}p@MtXF)<"#azj㙾 2UjSmq;AZyl*5٪Ao+a$@l#9j߭-`Xº bvے2adNp8NTavQDv ++ISo1Z^a57;\'3wbՊfdTC7Ck_#xs$y%OUO2$ix9̃K|ixGnpq삳rΔ}":PݚNoƿwtx(`sJ=dύ?BihhREǞ]eSmI+W.%gu5>gEJygѵUAM/dȏƽ&x1ćx\|>6E;)'<_0D{Q7n̩z +o +%-Eޠ&a Gz8PfD_[a$lJDRӱ-!?2o= ]幦'Yk u@QDjD^P};PwvPx¼=cÊw n7+3s4wqZܲ<]v^ѱT +31\ܹQӪ[ﭪnWqNn-(`/Adh\GSyCڋu0YLr6ϼFco=3Y1\biSoY|ZrehdUsQ2T *b?zTPTFTfQFHJDu"e +GQz`A,ů wakrцjO,YdIm[i"/ pjS轉&`W ]/໵?5A6w?f j~G#$ D78 pE \%"tgAc~ԃ|zlo1/3qQ+3xwSc.'<MïmQĸzNcf6z~Z7򸜩TY1qR]~koT(*0΋$q3>ɆqW#^*' +KJr Y{suǵ9e^~9*vXLUME#А"¡YAcXQ(D:(3^U rd_!H* +|\J/Ghμ#LUrP7NxA<_PO D]1KVCHǢ aΘ}Ўr? z5#ziT"\Al'AXx24x l%h0L[\vVՎi<ܽ3TwlrgD>*I)zM={\m9w yP"_4F`aW-g+FJJޘm6~Nu7qLU$Q>2 }thWk^g?Îg^S]e0N-eFBā::C-[ty`0ל]&~i&[?x;~wLy 2ť"ӿ +y!"o q&8q&>EJh`,cGz"ԼLZ#{ Td'7߫6,7Jutgq)GZs~~('9nZt#ᵣST}m谛 c&]Q_\^7=@0*hQreF.F[=8h:zF}oL1+/!gբ8LNBi0lv +ǺŲ.0Rҙ2⨿ 7#5-@]K:s xJ@rOnCzLӣ$GEӂUWsӍO?k\aj1eJk gџ&"xzn%\:# ֢@Aaya߹It)f"j,BJhM3ojfk zis04k:Z>woH\%@GZŢ/kV ? UK%S*m9%ݼ9 &/ %3^psb,dYt5|_C^O]*TF2(hovͼ stБ!c4$@ޘ@nƒela祶dfT|WToZ߷HouJ ߚy&VABsUpbK>d9G U-쇓#d3^,b5'dvǰgk}w />/hߟ~A؟~A34?&I&OMcn?5^ 5Mj!|C͋L xEWi 퇤lA'Cng/|ܫ. amމݷ;Ҙ +W gQu(Zo-?&!sTboa9&Am|-ۚJ;Dk̹~vΎ➇'+نZYɡ147dqk5aUWX+ +Dd[>N%<`ޫ˔g9?gOI5wQYf+iɗͪ]=ZD0.O/r*ɏjҋzq<݋m2Q.\b00\4ryp(om H ?v4xτ + D/FSb.N:mKyeWExnvmg=1mtk]־⹻|OM8(vm.6]:&W?4UVZ~ E: " 8"NΐogAtwUu-ONus̊=îv`j.o5Nݼׯe?+2iD1Vjw3v/.ec2/y40LwS#PHΦW.ξmq"kg;ͪ4K Ml=} qNne> @}Ҵ|9 kL#ؐ,wA^n9-}|_vi;nʲuzrsyS4oNkWM@",+W41ߢ_E J!QzAqM:K9o~ Z K˱p]94bk~|u$re-hfW Zc*i؍05,,}qNa^pC3[Lڰ/{gheTRJK55UaqrwKY|:y0{4kx !zur\`{Z<&gvwo% z-j-RY"8 a|<&ja +s37d~Nz! D+~׃sX?jE!lgK5uXiы2 +-sEb(5""MG4vlic^~i%?9% ]L@*C0ڑo4wg,s6{k. jG#:P&Y᫝&sX4ޏywϠ#](RN| ^ji5K\ޓClkȬA\vyoQe ۺWEH#r;ϋ1M5v!y=f˄ZuRoAuO+lLlѽ'l:Uϩ>_<8:5yh;C6 @3LuŒόr2ފG=h[zVgԉiE@=tlSĻ]Ncnmۣ9i}g$\7T(~xߓ_Suk;fO곩s0TvFӇQM$ם1|]/z}'[an^ )줱=k-ko'%.ꓡ77}({Vni ThfSIGҁ(Ն/d>xW;!<ß[ﵖpEi 6Qg 'F:2JmWjUvIպbq}Yg>2$m8LdN3ɡQQ2b3&O0 vC[fk8c+ӾQgg2YRVN -\tOu6z0"| 3끚J 0&$1 Wbz(rWWyjkErT%sb4-6Ln8|Ij@ţzZw8у0ٲኒǑv7Q& GAV@-ETEjR,(ϑ&M&mse.{&LMp~ .k&[(rʹyoհ3qjL +~n +Ov~qķuS-U* +c/hV~YAq>upBQoZCV?X¹X @粰0_ endstream endobj 38 0 obj <>stream +HҪHF pqDeQIdTA߿q:*+Y/2Wv䕰ύhk>&nN\t456>cUUy. F?B +W?r)pOrML6y{9P +FlQkkbyS+&=ct5VSer{.Ŧ>-E'?oO3Mei- BA7.*:Bȁ~3ӭ;4*hB#ӍV8◢TV)C?( ϶xˏ w /H9L4`vi%?e$DKR'ܼ.[^K5mws"JKN4N ]}P<^?8/Yb,zDgƛ?g ڡ3I1c&l ɶ\b:npu.V#J 8< +q}^?H}:ƙ>R$Df|, H4)x~h8ws]Es1>y@JF8kv{@YkLFȿ ݉am |Hx۰eSa3r_ +#AZ/J"}I<^y4iA߄y:Օ? @^[}tYi |CSFtO͸_NMڛoy~_ 㥛 +پ@ Nj !߭c]A!L czLP`ʻ?yGRjinۣ-)R JV}O`!lƐw@3^kD[ ~ru2pgg . +o 嶶2{N<q ;I֦rMM9{9>E:YGC]}HŇ^OE#NDD-/Vđjp.k3}b~}'f ֍odi'WL%zjBL43:Kr`+K!=ahmOM浘 +" \H'(4voo F׮-(KQ4B{.Bg8DrZ_ѴYx^w0G֝ ]b ]T(&}` syY%?N֌D"K{לU565n2[Bjo-wYDl5}G服'κO'áv)!IkKlw=aT_/QP9r"Ftaݲ#~ZN]<A[Ic)"j'wpOژMZ.@h*>tMp˟`ٜSHO焲H^zbMgx}ظa_^>FK 4.&O?DFT*:P^-9j)@# +ʴdM7HON ;0l_0yo.GtI^ԝK$ZXqul]bQ|ٮʼn?h/eEu5 _PA QQqgA?Y]Ϯ]]ϓTÛ%YғsWZW?4|W~ F$XXJ͟ 6YġvgFR7%\D0˞o5y$Vqv=3I䩕&[@VK4'0$BՉGE뾟fj") ѷQlY@#He\OJs*?r8_u4pzlNzTsW{j\t~?ۓҫElat,e0BS@bJbMw sc sbWdmZZmO%,YoǏh[OZSruګ\:K [(*Jĵ7cꅜo}H_'& Dp Ʉd™6}7X Y|}jdx1N;y]䅹ӭ0eF,e1yU6/X " ~lij,$f CmՄ䩖V |!Zz{].[Nwd^GRI0~>Tiġd.Vc]+ۆ`{+hq>O3w5-SX?ʕ |HI:F8fmH-$շol{S`v򳛓p`k}%6bgϳfpS=\TVZZ{hE*{ +b%/y ac>@,)riD"Ob`j^s'l]t=P1smcOz!Zr-ta:g=vXKɏs%s2%rGE3Fq(=,tnw4BQʏ+W,tt̪$fƵ((=גV,n)^ĵC?"ĎI{+ $%`;He!|.FO6^⚠_M,/MVz}O;[UY$02sM_oy5Nw}OK^9]ZƱ"%2"u?&Ζ_b44/9PVEީ *Szc[$KXe*E'BGQTADeAQYPo讈S|Vr妷{.Gq{\H3(޷H~ȿfGbdQ9D}+ǗpfP>-su;PQx[gs`+~IUHolUlE{\Zv +F2to[hVr#Le:IX{-gS'z6M5l \P>A>\A)qENj[n@lC#y <ԐWc ?@>LT#r9}j!@A#\FG7Jg5Ңa :}QU3'GjQjT ]m\"E.Vf.-+[Y3=Y˻KpCy4hWRޝ}Ep)W[jC@ +l=(3ݒb]27g`QrַH ȬQCOd>}촗 -30(iUl~:TZW<oBiK7e./A8ͧ?o Lw#u|vg~?E2}ԝ4'^݇u嶹sL~X7شg*K!DFBݲ74Q`~jS]~Otnj(ٸԻdZ"L6H/Ib+~%dѽ)|k^]5G) vqxoxY+ư%\쁩$I=e2'nzyO\š9gʼjO l +j]>k4$,cOz!Fl(0hԔ7q p [D{ X KoP^dg>[[$xsޱs0cG^Y5?VYP|pIWcTrqkti<蔅dFd#&nPFF[͚c{@@AvwdghtE͖1ŁӶ\c(f?|֣ U+̶LJ3=- +0Je Zp}Ui2ZAV+ىnta06ŕ\)[e3ڍ>iTk` vH`D'qba!e +.?w*-{am $6zÀ۔z"чR8#!{˙6qѲ~ґ[]<`{}n:PG#XtGzKl1V_8-z)鍢j3o9PkeQ*lU8e{Ԭ\Ȁs s_LxcFo̯1nQvӇ6YٍU4`ۥoqrH[$VgvaȀS2?fثz3WoUT,aװSjӳ3ހ8~ FsG""{!yiU)iks?PyUiNd~!0)Qy=bƴcWmFti=M(`T-x-jaX₱=~4/E?Єߊ~L`J\}\0Mh^rGJ1P"ce,F -43 Q{2*<}dz^(dwZR7?:~߅ mSz f3 Zbm)vKVodb?hs"юwn^Nwsryc,:h&[u|ݍC>/_  ^BQqY) l\ˁ8%o{!j3HM$қVe{6i}>q&8p~]]So&0$ 3V@,(yH苁6y8Mi>eh\ܸ[C6tР̭~{tF-v5s{Զ M(eUY%zMe>e=/?[/)cBg H.2JrAJV031PEw^\{iu'͚E05$I3z 㫥/5;0;H~@c(r.ĥᨍ=js_:_Y-JϪqB/eUVڨYo+pϿw(n,| +}tv4\B FB +1UЀbe)A@<57j9tf/?УG\ gTo+W_m*^+Ӣ;Db2:ҮGZ%4Slꀪr,1l6O?-&Ƽ*UNvqv t$~gb,Y=b˱l+͹kR>%\Skֆ<^l.7M ^X׎^#s/p.Hc'_0IXdۂ^xd[ ~VK BᆾS׺fŅ.8N IʽO2BUb1Vɀvr[LYgdu!S{ɻmH41/G,-zSYkIkm*--#{+L@Z\(EdO2f.ӌ?Dk~s~vP9@V&E >׆gui)بڧUc)#JYf)7dj _7-≹Z 9sI͂Ocæܶgoa]]~[>;=zl}-?nqӮUA`2Z:Y(YyuU +:!p?C[|?{ %%8SqfV 8)/gQ_S5yVtCl\w*72U D+p\7H-T-W^(l @9gr 6 :c0K};\m׸b/wjw[K +{$+Raߞmq~( {.r!9;[潢kW}Չ m\8,XUd&ѮOr0Kc&6$xtx0ߠ + +yg"8byo1? ^UviN^mzmr\\@;9쮈/qATR{ugBB\٨!~#H`p`HYJ@GQj}˶i!wբhVml{5/<Oj-{L~sܐ֓xR|WAd^(_B^! +ސn 'hZvCX [EԜѰܯf$X}FH;f *|M8JlӦviDJJf0J!11Թl١@ӄcC{CT/ߢ mڸ +-iA[E{zvJzL ͔_椎C)U~[ <$1E ƍ\+gK6k +D6V]s ` <4w_`G"f3m!- DCMs@S1[caGILHh6_C? +ê% %L7trwn1O{hxGʐ l?P&)zg-[ T<>I{¼WdkP,u 0wNP$KnfܺTIBe.c;Yoo5o߉~|KB]*UZ luqv+olW +(FmCz.da |KI--g@DdA@1oq:nܮ2#vn2H<֞GCUotоs_Lbl'dfjzlɮbxeN L!4s-ߚj~"S9K࣠t <[EȖˈ:K䌤ZNsJ+xmƽUTs.̤-o0.~V +(jn-e=J/n žple_6`rHjnFH+vOy$gMj̼{eSWuFQ 9PԂa|I߿G=@L:Hk6Qѿѩ=: ZLO +g9“F{Z:ك%yE4\\Ub5kj:/[ya5[6 ` Oc(^̬x[ 68(ڗ4Ωg , 2/_`.Ȼ4c']RxV(Z<$tI("BFuӉۣ2½XG!u }ȿ^hxkYǃmצãOZo]xez;eXsĸ{PT ұ92uUW:<|\04!DnS +kN0=͆}PƻSv8*/&z +q#R#w|  }Xj$Z6)ϩsS}mu>-9ñߟ0n)hPֶV}D_;5CdgCC*WD+t*rYn qƦgnP?;( Ȃyn_İTV~^E8ũgi-UGqPl 5+m%d"\_/3)zq!YptCNѧ3*,bEv7yT@PS<,뮈NyVCӽ6<{+@uwzxƱ>7KKqvǢzAxf>$ٿ!D: (G3Ջ7Q摯nN20I3[J5/?ʷ?ݛ琽xiE}h;kp |qxʼep[7'g zm +7W"7ſE OCfPA$D%"?٪sfz -n)id5 i0sOUOXUU?((ȦCP⠙ yjAc!!ﬢ3%KモjS}C#^zAayN~o i~ýAxy۬Cf|Jdn(-nID~LG"@ P.ϧũF10K3*9Hk<:}T[{kg{atDAem[ (ݯb𷙔,唺 {z8^@m_uc6Ɇޖ77R;+}>jJC*#:TCٙ~ i(]Gix!GGḣ xa71ŜyD=}77٥*ec3eJ3Ғ!nhLC'VAU-f!>뗞1kf}Sa)yH%N+ƶฆTA5~@vث6[tGو/{ܰv.?x.l/UގuRe*2~7}P*,/Wk/3Ł]aUx}?R&e3Vsޖ Y$zyDZH2/z3ˮ׆9 ק_&u̡BcXf#tvA k}R7;ϨXof%idnfl[9W_M ib7LL.aQf&{˵< ˔XNm*2#ï SpwX5\.bEBͫz8~X;eډ<8ub7\+ٴyGYK@HjpxGc9ˑ$ OIܷkC<à )kS o._[c|s腖pB#-tE0wjl4mJ\lfAU}&HC&cor YiآkYvO{p>bk>^Qz85؊^hhtNXĢ|<'9Cii0J3Y#Xvzz(o^5幄+",4;vŎ`CE?ٳ;sfuɓ$2!5'"e(~ב^_Y\71Gu +$6oI({nB94 xggͅuo&wRiX}34_kfįE/ +Yt꣕yG5 ŁYuWŔ #'?PtՍ =!3)Y^O?BuN,tBY֪FS{:MZEGP[xW h1LCWg1yu2͞޸|+< GCL5 yL4v{9AEfg~ˢH}H3542T);Ո|kN>Vvj|[}v;+:ot 4Z + +e |ᛮϗ`&R& 0ɵy <ڋ҇[]~T읩N뇙DDY[ 7x,P_{syMUr"emtvB=6jp7Lraͥ9l[S/^P"L@Kڵ(j̽֌o͸_/_V'y|\~r'o:o~!M6.HjH,XY;#3%c̴߽j}{YѼR$xy;Jaw-N ϭA+[\b^̢N nvFTڍՎP2"̓qL ސ]j4 F>HЭgcwȺ:W2K7O/1Ro1ٿ.U?aY@$A2*JPT kNծcպ zu@tEϞMt4va|,BBA#ʤf*v7? +P[q^5yՄdAUSţ ;+un{I B-k,_sCǙq=gVf+_E E;_snPnx|NC6ĕڎЕh+M˾Iq7[MoR|.izvO}vzYY16RRC| n!,y{Q|I[bOze\}K<o˩3}B%Mֆ6f6ߙlw6#OW_2*qV4zU'\( +P=C\.tEyN^i6ĝxV[dJrh䱟y`ک1퇅}h %i;b/QS?$DfDnpR.DmTFĉ_V\ޱ/v{ 7B_,! kr ~9Ud̐bCsZ`y;,T_q<hwCUwWw|.St)qٜITMzmKiWM0-̖Z5~O3p3\꾢OSRH\/Ёъ~VW'.Wra[U<(]rqu8^Ad1}p9!mhV8`Y퐝5>@:|;IuaCxWih(l5E<2Z +]:/}#u oSwA8]d$?+Gܧޙk-6v\Fx>Req{s_A UQ%f~el O€ 4-J3!/RHxHbXJ;yxY>C" 2OoFޮN2G=;$ Lod7V`IN E*p"a0iu\R(JO|'Jw (i4S#~%bz* .x8Nφ1ꦋuHu=vjd>Eȭ- N/CD|k;(!9I U_Pch2\ /z/''5ǡWjr:㵆ÐV0U6z2:B{^sKχW} `0S{` XTt亮,G0V'ْ?or]9`CjPζ XA;-[+ѧJU^f1\\wCk.xȟFɼ?]fKjI?a3 +*(SSY"̐͹p":J"3!29heE+D?ơRZ3YҬJ+Rpڝ~vv2]~O11ϙWa_n9iOh)Ii).kjӦDw'PN쀥-s{iֈ/>p dGF:O^$wHCߥtz'x3N6 ?-LNz*uU.*;`r5f\Y]nk]z;iqDI_hFWoPv '?k +a;c} (o.iXc&~eX( h' PaPK&kCCU!'y/ȭ-6i9=+40,|wWA#M()XK,$0v{L-n+[lV׀RW]@4 0TbbhE͢| +XΥy,e/'y7{u[èBBW$fDN#jkQV|w9Ǧx0٤U ]Ht*)>M;\OhM RH +XU}7<(]OyDѬ<*d ِ.g +@LDΣD=\);yDo6 KM+T₲Xn<9=5XFZLJn~.Q&˴9^"i+R=@K 5 -<JxT##Q{kCsՍ}˕mυs?Nlum,;ҹ`MWϪgfe+h<\YK`f|>TJds(%t6 +'F͋[ȸi;] N!{fgɚFn7=E3d㌽lq8%; D9KOK{ ȧ6d{j_e~fsHV^HPU[-+71{V*JFp~saeSHq a~ȝ;vo_xOj>J@{&PJ?2Ѳl (S[7Z0G5Ujq]y _ɮ|'v9pF jnu+;"xA"^5a">/^m nu Mp<37\yM㱟}}od,rI sF +&ڠ?V ^te3yR+U9˼|nr)v DS@sR}jzu&W?(ŲZbXbcsSIU]ٗpgcL]8x*~Ź][_n&|~w~9w9^&?!`Nh7hչ.U9GI*gC Hw/ȫLN0/+Yy{VVJz]y\+JkBwlQnwn|tQQ=Z#%iʰaAB2/ɍCI`Ci;)?7qqvT!_^@tx3.^Q-{6pqנ*bҀΥ b9=dOs]f˪*i~ʨ2"*?Ǿ +2*4b7au|%݌aoBi.R3"02^K/?D*bZ'\S}*37h#ӲnYFyKҦ@zhtZrZwmڸ`W=|o*.no׬e~[lW>J͇÷^%)U#Ѧ=^@B+w0K=PݒZG*Y՟L?sPd.SߦMMCo1xeDCxpnmb%\4-I=[phui1^|OZw׬Ҳ|] +ݓ ,XLRFuc?F;csd#c)ϤA<}>7Ol;~20XlLDnzmK +KW;n+Ƚ-\uip̓BT|v?@"c;lAӮgU_JvjA>։qUYqĮ6T21M42|=5̔7ix@";xx4"7yf>sc>OȿI덻,я5]:9!iKgP^M2qQNM;[oy@Bc83Y{{3ǼVs/n!J_D$ _VJ[}=enDLu>lneG^jZؚȨ/fYOJGE*_"Jy1Ŏwlrı"+[1WRcC1o!EZ^cC 'γĥޞj*x{wusJMvu$rg֊{I? Bo;~YŊqҸY[ +(7UjyQQC2m#| +-'{u~FwyaYӞG͖ H,uQ/Ѩ/O7MxڭMF\uGB(En4qys)UTPQl.拦~f3uĮ%hѝzg(MJ *Sf;6e`C2s`=ΡŇإtG:(ؐL*Z5ipɢ"Q3?_Ƽ]MvJz4B]^3nuQiО`o,N4^h ~vWkDZ O4F2٣n@lf;s1LDt\nU +K+a8ubYKnm4&ٝ Lof uDD [-}4+nǁ 4O_BCnM3 ˈqkyΧOѧX$܍q&o's +I5==ѕ!%d:Mp\ -GKzYhPtPt4.(GG?F +֝0M#Briba]FmBr#xWU-MLfn4 kUl>Dp3?;oKzS686B@Y?ΛyvL.0چv^J(חNc(RX" +UTIOWd7Jm嵭/#$*A`Ą9e@QQ2=gIӤFWUqQk w>QQ%nȷNzdhm.Ȓ0[rPM1q9! +ͻ!i㯺K:-'ЍڮcU#I9paQ*w +jp +esŷżAY$e9~Nz_Kg#%`qYE.`+uC*Œnй3Iԩݗ{rQKMVhU}61`R)l"mҊƛ_\:~CX]J 8:&@Y'Jz-͎kLC::#^BHxFM*n-dlR>TD}rbs CDÀˀ" TuڽMVMZ+T6jW^=v?^IGW]WYW4"*3G'V*}QpwBn"U~\>jLL%]LxiBF&v& ZcRȀ|H^<%7INk쳪hK/ӟ[".I%s̞1mKEP,}PSY">S*Gr!f\4N{FY In=5׹ +onD [\0@ԏ *P,@t3@T9w!J$s"Є@dY"Qs #jCޅd|ɀ`G\Z$Y>~DW!j!?F@Os@[3DQ )Zd|^&1ȘZPe(Ǡ6>Bٞ} { NJQ*Syv1|yCHHi}Q+Mu{ֱcד\t+Ȩ{Ji P (mڟ'C˦]k[+ii˩uI sm[1 v5 ubA X~b5beG5m X "&L(}{3v5u놣խ_˩NvMD& e)=..5%ՄCERd bƤwEDs16{ZcM 4"~yݥ<1>ʞ3nO\9_uprilhC!gg?w~p2#":&wxA"!<уѤ4 x9ܽݸ\j!(0̲N +ETҾoվ *-)!U|WϹ#?Ē_'CߧV{HLoHؓ\}v)*h͗؅ʺ4cܧJDY(f{MkV ^ ^>c?Vjd'M+@5!bCrDR/r^5C/GaE/Lr/>_' Y.>,Z}Oy$C8BSrtʺyEFqE[SEG0+Yy>y{HjuYaj2u5OǨq 'IkmlNm|ܡ@"0`}u3JJq>NW-7h̃]p?KC&)NmI&WQnSNjUU7Pbn:aBusv.whRp\F{/lawƉŮm6hɮ\QQ}omq̵W@JHyګ)Gw"r!SEQd=-_PEЮOb99$(̓up +{Fs_KY͇C-|S}Ӡ>zP!sY]KꇪTT?'r +;ar wkyҗCn9|n:ޯqaNoGU3pNr72d.J,Fe)JiNԕei &t(w DyL}w~}ylRu#wIjWiDr%f HNTzb]oϓ/JҺ!ڲzB~axau>л0=Bz B"CS&[>i89h0;?6i䲯1%]i42C]+ ݭYݖQGt$ c}W@plRі@Ź-, Q3<'x|m`\U!UFӘyvpAa\DhQ|j0-GO|5'$R|`9e, ,M( +pgAh]YD I B@nQ0#kq,4ڡ nw:*9Rca%WEL^c + ?81*Km1OH2_B4;1+^4YZ\ZOO䰾fbԡn/9}nTf:g84{$i]֦`ݠjڻ0_w,[G7&v#T5b PCDJ$F?a̭:W׻G>Zތ;Ԯ90rڎl] Y VY))fzJ ~V718ּPis3gj!=I:sf`>)jBi̭vB׏w 9^ѳvhcRI`3z$QC|9NL0Y#-:E-!ll#l/< zL&֙e4Sord8 Fʟxc[Y;t_Bp]k?nrWkgEn +]2No1۰P;K󆬘̳-!Ӌ MCqw,/mrû !ZS|}L$(QQVQ +JϜgӯU`uE$O_ ͂.rL,#bkn)Cv5؞lLޘ̎ZVC`V>=u=Ωn}ܒjv񴹾 k6QM"q !_|ǃU.F-?b,Oٍ/H;ܯ R՛U4+#Ue׭ΛgMf;^-N&#_oyE=n׭gjwɭ[0⫦RE6-k# MI AgfG:N=<ᴨgH +: +d +O|4xxvUKidHQڒӄcB57nxAh]~9-+qJDF+_ѯEjebLc[ +*PX +=*Ic_Zv֧P4ǂ/:'/0>7~b P&L2:gDtP4tӧa^|ڝ)kT؟Y3ٕ53FyDWϳ=K6LWJ⸵sEbY ߺܳ6ͮQl)J[]l e2~MBDhK_d5C-˩7#nA[<:7*YHRaPk +ϊoqWl)TVD)#[:ݩ5L +mf6مC\8F&V6ۨ"1y3l)swUµKh[4&,D <ΛTID[JQ2^ēE٠Qcs%VR>-l2gPC5 zـ]=ῲʸ6-/cjiGupVZp_ŚlET;vH )j \W#ݫld/8lb1Y<]mQ5z+a,PERnyHF@v]` +:l Sf9_&~?ME&N24_ְm:_ӞֿcZz*b^1/6ȏ.6/_bV[#9Q+9D0{YDA:\>d~q@qHoze% }ڙ|;1|`Gey)8/&b"l֙"YO9 `)'Z',Xԕ) ёU,<_ ^]PDƞ Ϛ{xT ! sPYfWZjn袧z*tXŀbm?6@hMo +E[bPʷsﺫ#ެO}L!|l(%.VA]DBTJeԿM>J./·-g}[j(Le a6sĘ:(٭@?oЉ~wI"bMK~r 'Ѯ'$MӕS#ϮS(fДe:%km1t}!Wݿ `dObA,%ɷJ"_m-@>1OHR + d覍в%ʱLwf5`՟ L.DZV˱z:KyeBI569P>wZgcX@O=7o ۬1e_Gib4ݻ3//˾ޡOsyUWz0PV +!f #" .Ƥ" Y|-?.(mmvsxP-˳o +jRS-vpAMyqrklth B, E\2˕5U(ڰtMlOy%o%foJ v>'t5(@)eBOӘSȆ]l۟5a^"vN-k&Ȑ%ȗ2λhHw6/Rd|b %_"<Ѓ'< "~-Y-(7zt/8sd[TK8˹ږ_^KVJ-5WƲj"g+RMl7c]g΀=7 27/D7/o|Aſ1 J(|}E:4,/[μiN7gh]PsV]^#NR!6s)6"։#|:ܷQT={1*ǧ^= RBGXQv9:C ݐně&_Ȧ%T3>~u$r-#}gx+Dv=mkvꄤO_YIDQx\R\sE8 Ų쩙$>)[~"~O]g0~? IN$筢|&nRsUu,2Z׸ǫneP{oMLcѸKvYnb@T :Ql\zW7>F|2䐫TKIp/6@yNBIԼ߮9MZɳnvvq׫h˯.2?ǧY=!jƠ[T y#^wt9Sxd#EÍ4/{V/YLk;BY;p{7W\߅`. BN1x9Xo6XS{tL[a0pb!ymn'ŭI[ۃ:Swv}/dJɍV\+NTKh3{y;G$Ümݟ_U:6w-WGv{74,yjlQDWϭ#~ y}3UoC*KcݤXiL*VTg_>fY1yZZ >I$ID1aB0 *rsU[|3]3=ӱjx,tN>m;ҩC=vho)Y^:dۋD nwcPdWɨa`ҾKLOTmo7eQϦ )gv`:#e|[qaNGqo;ŰeCr^ 2:!ZDv~oyR}4Sog_Sn^ZTQya(87ޝ_*8ՀsXAh%EgtSHz&x6v=Oyd|A[-+6Ki +da`4M ~*%dD*m+Ǘvy!?jǾe6Θ06yqxsyޔ% ",;!5 @UݪH)LN8( ?a?9?B|=ϲXX81zKl: xs5,q=ZL=oZx2/KhKs!(g1K\dD!^gE|mJm{t*; O_93n_7$ܞ7D[a)=/]h2"&Nӆ Y?ڱ\?}0B^@vm u;pkz:h/onY~!9m:'Ev °f~m݊;(rZ=xnViOQTmc5F-gS"Y,*6Wp~?`KRY5s6X^OZoޣc󊂏j;17o&b cy@_޽2\4]f*kIj K+5R ^aQ5RujNcF{Ocl.S8T<Q_n}iCTTqN C&$iLQ}::ykeQeWEӊ5+-Wz̕գ +OKwJ'xiw1kr}Xd,کr,E-Nq|7a3m_}GC/XPqFT>.X +CTvi1 %X'^[#HQ7<ޕ^b=vqh {Sw$m`&sfGҕ`xQɦxVdžV&*^ppm`[ ^K, `nۨb7|ƁI.Ψf|(C?Eh3P^V}Z*gb+EqT&s\Χ m@yLBxe8$\G +4&ĕ56JŒ6iKFCrkZȿ RntxC`q^C\q}2|2@m*#V4#F +B(+|)})mg3?8f,ifO{@̧P)f(|N= ˸oHQ'N V~Dւ~m!ni->W_RA,yNJ +Yb/𶗂>=7ڛNR`) Yn6F{ƎQĸn_Ek QeOC4bY1JR@AD%#:蛮Z?6S$BN"/q-#0P͗ +0\a]AYuCfd ;1uLL]&)[#^LT}aUBMW!_bH힍$F[bYr^ Bq@h _sСg[IdD4+Aw rVy&H`jDWxauq~|ٓx='5Bg5]#GѮ;7CnDag}\a&#$bvgJ I\b}t +pɦַ""GBIB/b[< 2B#RSi+տ +r!-`Xob7UhxIU+W}]DVsHIT9avv'w/8VlBu(bֲ~4?ڜncrE0bKG/C!(8yu%J<9_#$J,t,l-0ۿ~sJ})k;p׏iW$r9pZ1z w7iٻ(ZũkM0:TCar"So|6'}AŮLqVf/ d1kg9ݗ)SBg? +sB-|W%6fS (gn X`Eoܘ ΃oc16ŦAq 2Vy\t8mXqEf'pQL:^+h I:(¶!d D.$%kb2iҗ֬k=6S T.7F{q +#Eyd*q!hcJ4ѭfT%˙zN ];{Ů S&C +;C@EtKlߔuj_܏6?$]Q% ++EFF@iA@D[TeNg<Pݩ{ b)g9m?FꁳXiiG˻YJ1#TO/r9:Q$ ɰ+Xf!;7|WoL&.ر6 }@r:e2·dB/ЛҦ!}jdWK-r1PSfą}X>?XeA!gE)Kq-*WAMc)>fkۥ^+mGbYʧo0ނ/jkŪu*STB&^z$^eQxBGpʛp qZ9_+Z7s(eH XP/o/_qڋ0WTs}y]$Gz+5ua)ɖ0;6ecb[ PB]߸s]b=wYZwιQ<&o@քm z:qZci+!5LOТNƁj_y1$W&iXt#:3bn +va.薛!-g?|Yh+W]ưxs4{U W5i'N\5#xnN +#Y_NRo @#\2XdJ)Zyx_Z$ ڐqvLofVp&/%\5߰q1ehVC;jji< 1TYHgk}›g2"KiK>_:eZC]r3F_DхLJ£A2MPNmuM%B}Q ;7fTFSiHT2 JdqX "?tf+k<ѽ2A:`زTn}Jlo42~{Pot8>~xAEt"!<@J?y׳y{whAW%* `'<޹!B,nC6A>D13v e kѵtq#:)v]2%U_ͽ,bM?~êԽ^[ E`[F4},kU1(&Sd" W}{x)u֭ѡK jο(\kKäk7gկf2ļJZpZɈY4=]jJWLilշ"<ݎ: R/M_Л%[ži[_-T:pu C-**b"(= ZUvծyn>R\ dB#|R^4P #sXJ%c2Ks:ZRVz3͖>ʜѺlvpLI٨!qL՜~Au:lR!PT<́'wWl3}Sun6Y!>zqS1k?N>[G&N0qlQxB~QԓYj 7EF7,F9`z\)@V?F}BCY^1> yD Q$ +QNaq(+?x3!ĚY(%[ h6@gl8$ox(ĈCĭOĨG\@\t"\8Wނ4:UgJDFSI ҟWfbƉW viQEA/AOo):ēq9CW f.-^T$ppf袵rlx;|8n0kI\A/nnHT|b:X>_JĭZN&Q-:iѭ–Vɜx)`yͫ3֣(=Qw a;S/HU}HfԠ.ZkgG-_7i3IK"7^!_5U2<ِ̕l6W׿{ozgj)&+) grZ,j*}Ħkj_Ε&OMG[Gg݅7]] EZ5jLF4=Z,6J{zds}|z TJ<$&Dj +ysL , ɇs˗ڳYyl?5N;%H猇)l\C|YuQ+)NO +ZSSw2|/B]L=]/[AP/=1uu_m솖AO,Kܧr+o;1=O<@~N>Nh?6}vLrkˡV8?l)K`kå-nSA|)E2}׆<'31[hv|uMNY5sH>-hSu\+^Ʈt=u|Z*~HECE>ă?$sB)B[ϻ|JgUjYh+t>QZ j'm_>vw%Mjb',._U%Q<(=نyܪ K9J*#BWƤHk[Qf 9lD2(Q b Q8s._ٯt5z^9Xt ˃d\kݛ'QÚ4=rt}'6{M/8Tg08[[ٷwzk:}Ew.tKgps#KaAu|e P/9"llnvx4'hSp'-tPع\ ϥ/F-*ug<0g}Y }; Qd=[Uq:[]G3*K5-Ko >4m'r1Sӄv.%HvckW(ĭ)Y7n{WėDR-\\ߧ&eGؠWexJ؃wu/R.^ ]&cXQglhj[o#8%,$ M`+]yU3-^?vS^=@FQFrC&BP 䑔G>JŻ< >lVm|{TбP^e(>. #TI?Cl] +ڗV\·Ut2ݡ})}k|\q"I|&DIIĿ7o?4=E'9 7{.F<`{@:[?i\YNE(BQD: *'[3(;w{ E !p * 5D^.(.f^zi1!_<)Zp#u4[iP]/!ݚE(0)B3󺛾u6}O~zЌ4s۵Kv*YM yP%eA,*_lI2!so*hu2R!H|D+x#-N͂r4Bxf:g0^wi9r)j1f;^Y!{z㤎:2;+ёՏsJ,X Xuro,r+%qq8VN/d.a;! Czm'9Pחi),Tr~u[{zǾD SvzgKcqѪF=Lk\pi~Qfq),V9In鸫GLSͲdOW#vXnfsݶ|Fhľÿ)0@8(tVpҩ)sv neɲj7̒ҷ(8OcESҒ0DS;w;WufP +Aڢ;&k֒lN-=x80a`7V& +nfl(F`kHWڑ[B?Yw=I 饓 r M*$zʇHZ:^9eb> *l*3|E㝯3tWVvGo\LNeLP "SI8^%-|׳Fo!0^3fԿ0Q>!/0)F1j`S3/Fs4DЄ+TiĕQT|&<Q{BOx4"?y纞5ƕ9ט*;F1EL0a~c,_/ʆCj0n +3ٙw[.9+}YߵNZMl) +C,1.M5?g7,Q5RZ[SP~"E [UL x@,=EX ;s'$7]$W͈Ic=;{YwH 1!v4:B 1]H3ԉjG;hD<;N|U +}"{h7U՗MhxUDXXOI*\2 wK:_3iJx_1č, &AjCyA,Pd2}I7z9t d8:,K nbwzTxsw1L\=_ޟǁ i, 0iD@@*lF 7Ev͎ZɲЎ"gq/Ϛk.g9oiwW9COᾖ]lMu/V|9^z4;g=T +U/@2ԋ%)_؜ѷ A[ΰڱ ~'MX82eFSz` +#@se64.HK 2?5H0b\:ӑX?Wk>J{>!"B-q[.zЉ-܍10VcΡOFдܽ6\*>E\B +0Ee4HKO=wZ=a$K] !A1L&rl~3PnuEO}z󩿟Gh)g(c&͐q_]"[E&n[HD& +S㵁O|*vW +&Kth }w?C#RTR?ipj x_:u(^eyY?͕Ԑ+8-=>G>|&x%џGԎmqo"-k T.M0k0Wk{,Z. OkUmݓTiʹ Q*P96zm/_Ц*x|du8aLOn9qM`KO͖Wc`4˧fRx`_n7zxl$ |-L+ղBb2?3ѣkyj-3-C9eM@YDB fЊ2~z7SeOJOG(>z-8{:6E[V\Xʹ6ؓA[{|i}pa̴o|L#e /'tL8O"u1cש#al(iS3I}tE8˥%Ƒgo$%|,JݬbgZM +YGl)/ "yi71> +Ca=Vb=bovyr/WP/xR}1dT9LP";.*WO#k5ev}Ci"×1  7sx,p"1CRח}jtl5jnv4\^nyGHyIsxZ^]G)ކݲf\ϏUۥhVY~R (2z٫Os]>KЈ@Cu?Gɠțl|6_]iwe䪆ҍFaNVZՆ*c+ym +J֗t +hO >֩8=YqaCw>6"|:ZNv>H D@:\&{hpJ 'w1$ Q($arא02X[/W_zكO%TRe$!l~;}:;Hij0 wV:,}$//as1S +,>SJ "IIa2 K"LB +D_S~I fyQC6[!nq^ 6 @pܺK:4$n?D A q9vʯQ9[<>?v8+jƤsG}ݖT48NkD휱'C̵ S{`&hik -۶H gք}WskKAmO>y vnB=p,r{pMfB9Ô~@/NPo؍U2H5^$^R614j?]{ʽE6;: >\5Yʩ8AZKyH7r4sq䶒4ԾSbw!d1:Y 2"`x&Dp(L LAo+lA_ʼXسw4SՓy[2C^ (5})[p®shC&3IEtI ^Mn!: v0lG?hS\~,&W\ 4I1;%F{m zXnqoO^?6VO2^?h38ўt;>|A^Nj͠,{QjԆS};9CsPQN{@ʑ+~?/>/1Wron$HFcٙ屖KmyW$[, {|UqVuRvQ3lN+#r]V<1NvJbR>TJm5!!ohC-gvgrʳugUD.y@]ZK;*)բGCp*=6>Tw5&λ)L _2Vy>x}湓XRssVoVeC3kU*t#t4jЅ~%6:Y\pRMO*/] ́V^mLr ~qK"b/?Bdn5DZ{V:(_0oe(yUHb+ARMVH`BÀBRӇ$)$I:l${@ӌf+nNW%DJ|4_~##&gcqB!A x"]a6 Ҏ* +SU / (gi.ViFG/ҏ>8iύӴ€AT; 4U>@U+,KF~з7<*z=#7_?K\]SwfH@4CIp3f?i +֢4w āx0 `2^ߎz{{ if6^rk<."=gķx&6 piv\u~%b~M~Ke$fU~$~$?lײ@< c9($)9 +7Sujnk^k2bˎ"*!*niQ>dI$yy%MZgSLIŢ_Bq\To\﬐*l1싫 ?,*7iyJ\a«1anO?gF[y>RSpgY~jȌyRGXK>VyuG `GSic9yȈς{Tx8z 6tL%s:3@.&hiOj@ZV˅g<\ei蹍 'U3=w,(9@&U`y +}TcVι;?FicMȷ}c6"]\(ٮmP@G4ۜN Gvww: +*Mjs`K9c8b+/ۣ6nZi0?-3e2g߄cn/&VߍS&UUuex~sW)"( ,I +P^H|?<y00{jښTLlrml֮4GFߪgMؿӫxs˽.$AS -PyV>'UoIۻϡ[{D.; >cݼ#ǡ+{@wN4Wۍ|?ji׬<_u%v^ud UY="+69EmjbI+]e^N +/ (w_C?6 Z\ةU]$x7e퍣ģ"ɳQ<Y%ڔV/&[P-׃෩1Qs|gmڎ李6^S;Y$/+A +zLɦˑ I@TX9a8PQq,>Hﴝhu ;*GGF f7f:O??PJ$\hCZxJUsqW#c` )VJy.CƇ5jکn7=*t2bE+#[@6];'}H2w?t6DY.6wcyZd%O~Q7_FcVp#*(3_k^i3 dDX2Ne#Bƪ}dyH9LZ!1wxJ\ 4ݺA٤ݧnۼ:du0ٔ>ɛVzk&q<|3_Y@/jk]?fMѩ9Pԉ1'Ǘ1!4 ׋5l/;Zho#ׅ9C3EY &F{rcKUf E9 +(0ɿVOǢ^@tP^'+g)_Z4Z4J{HN}J-s96/Tʱ"hI됺uX: +:vgSImUw=[7ꓝ[.'m\mqb;zFllZe8Ŵ=m+?JR*m6z\_<S<`MD1)\`^MDGU$5jt 0N[]Ά,XC&FcS%x-$2şB]#$%\a3V0*+jHi8sų&BBX7&rVަVo["X8HV(͝ ϩ%:j%&I71u}W/-'#/䃮R0c2.D4f #29G'=Q]5WGER ?~QIW}Rwi cUE|D3通TD +*l K%$x9dDl__ & Яx<iD+njio3-L4~G yQ4d#ħj`!#٣m*4.g5ei6* c~q2H?rUI?mHLX0[s<#sI=>ZKQ+RRzY8QI/i|;%^[vvv%whOt+CЂ"sc"G`ւ+/]jYظXZs>~~c9C , aޔjM| {tv)OJҭz8Bj Ej?D2C/{8e]kz^Y0?ۨ}='v`؈tPl/]RnV|<)ة^;!6*<{Az1w>{i/_/n nk]}OEQ6*+`CE`ƕȃU1dz#*l#s4` $Bvd͵kd[5UZk{r{Ayf߫?asCCqCwJtMiH5nGyt쨊r0سNGEW6:kb6lܾqE{uj9W+k=v73^,%kg>=n6ɦX2\_ASՕ֜LӐ=s d]9|ܹ_#򨒂 a?@ 0E7T\me+?Jq]_KbQ +H+j%4Lm@11V:7ߺO#EJ}*AHo/m\:kĘ߮6P6Kuٱ(yu62%DL,y8jFy/Ӡ:U=#3Kz5Zh-<ѝ4pam WN߈J r&;:Nq7LwGx勸tiNvr&,\ +Z-OOD1[(fkIs?K( ↸ +  \/&C+jD%O#*(B»CB9_bG~t vJW[Z4[)if|>"ϩ^>7$Fh؈?_1]@s8/HL$48 M8Dhne$#c4Q46b"yf/ 1njH;0s: +nfs wof5~@ؿVd;wZ۪/yzSN>stream +H\v +'!`Hw(}cM7߬7xp|N%rpQ&˪ҕJ%0+` ԰ƭ1*GzFңc>a=DoLE!=]-*\gߑu@=M62߅LmϷgM7B(_gR)Y&}im|_.O FR G¶>Mk@&֔  <,DCG&p q)@9𧏯]أ'@q?۶_*:%SN*kh~x2,ކYx~Z^T"iFj7A8"^:hB'4;DhkV@|8.>Bw8zei+ M0_K5-曵Fndyx& //g:ݨLۅݑ@E)%m5j ) { +L;$. )vax"*duE#i,PeC8P]LI)k\ -WNM_Hei FƦaH!۾MOo`O63*tRje (RFE :b5\Gz7AcEXtq9E>_*k,ihZdA=;I0":bBljq򻰖_mNYDžu6*7pup>P7KVX4w @|nnCj"} + (kнzLM7).ں KN:KհjlnzEOm)u$]u'F$!Y&LPI,(5qI@`ˋo/. Gw3J}6}d,-GW.>jI)%`>xbN=&uJbiU@zR4WX2<;\ fV(ٹ^ iiwYW4hiyo/?Ws}RY#zb%l{CBke6GNV/TU*ǧTúqTB#!n҂4ԉ@# ?IڗvaMWAwkqQu{Ջ  +TD'q*^u}vYV(-vT5) 5"Jrbu4?v+\R_/WYp32BPTDhkQ3 m8qf\E2럛Iev= F!CSZ.'$lIbM +*7uH}Ha,w,-{׮?.7(gu 軨%ٶ͘;Ej)jJ6md=9:C&) UiAj1;8B3b`Qx>*-".Fݵ3zj({a!t@~2@@$(/qش|~FhN =dXKQUb' ? +(n:'y]Z璉SeW/~A }ߝ]]5򗽊ܮ^boKzg7CcR>X|z'$e*^M?U߃ ݼ2DWtP?c)ןֶJo'KW2e}%}/}?XCi_wz0u)lHY0>u89{.aP߮t刯с&AQl޷a=5ݻLF~B,e,q(^ǂosʍ&N[:tB$9N4eK.}z2wq2uWc5u} +ڨ8jЬl1NirUտc$ +5 Q܉U5{,1c}K݇>L NԴۅqשɔ-~_V c{8v$D6'~ѝP@הTRL$$ysf;P~Qh96dNٚϯЩͼSeiul̖ZA~Z,n؋S["K6yl._a٪Ʃh i[|NY +7 +0CoyO_̽A7&1A >>ku*N6vZ.|b27%'7vaިl8PA#bVU߃/ol5s\5*ɵd;$VJ5<|a-8R[%`roes3X<`Z Th4}TU)X,7۽fLUn34>v5 ALV{,Lv<0}oGd,A)p{ [44 T<=W@TƱ +pUVCd]ƩޡriB&j)TTXxgJ #整_Jy{}RuiGcQY{PoE}M2XNTa x`:ʹt>k +X(bjmjI>@%@n% :-AZRd%kL:sU<qi t`[PkR^H{t@"b з010u.ja00zcUٜ:FW$dZdcTx >E0_L[F̀1AFzfԮΟ۫n89zӰL[ֶ\p¶Ed dhw+w2Ì*I3 y+ϔ O._ LFL@/oK[\ɾK$sU&ߥ=G+fh!rab(jW?M?^9QB9GAaEH$L`ξp(Q -$ W7H PUN 5>U+[>%QNA"?ԯ}Abbj5YDI'= &Ę5 p + _ EplCL%Œz5o*m&1[1Y!u::!gM>y.9Qޤhgׄ YOag5 k 8DE+ȕ:D arȅy=ͯ(U?n$f@yUr{=>: F#\ѰɲC~?Ng<-z`" d[lAv-AfAV. +* 7y:3)jrJ7Ha q0<.q:K>FlMu7GvIq>k7զo2w'o! Vsݰ$b "<|ɬ=B0ղO>5?贽iy%~4yHm[MUYw[+c6WKvmK5L_ESz):ZOekb'Ko\z#{&-͇gPzrJVWmgՙGeXꪙ%f^zBn\(땾.+F|e||j!|*fȳfm)'.#NO>_.Z%N4Y>dÐ/Y2,"Muw]u^uibkk,G3AwG宣K[lhnDnIVb΢ 6 gbq'EGOF,)ν*SX_NRN՛IHaS%g57yKo0eg'j,.gO;c(ߒ/=QK(qnKl\qTMɧ{)71qgxfX\Go^xA5h\WEZQN8˅Ulwrgx,ڳa7{{t,2v7vDl} ŶlNY4Ŀ~y>h썫\a^]-RK9JK)yTa +B/kMU(YC0"$,1`6aMo_U*£e׻! [:dY&]@-cUVz(d5n~zHdjp}@sT+l`悲`̄ԛ=Ifkyrr$rh^&۳?\iXׄAqdxH"'h1Z$DOj:*s՚Wڂ J\~73`V`[&Nk\f\p :-:o Mg4#{hDr%iLxUyY]Fl=Z|yZm*kAmXiv;yu,1j˗A#Reeˣ}8 imS,L, { :9rAɷ &Trsĝ #'@6V uX4 #+Ս&B5_n+çŬVVJ2# g-nRw{zҘYԸNgGu7A!5#̚D؎n~J4FsBIބ]1jʈ@V]BCd䦕ѓ}s#W"DRyo3ʍL +ﭓ,E +DŽ,Kڶ@eӣac*DUK%V3њ+myϏx/ootAzŸit *-Etax-_R8 h?ӥ=y:aM aknʖޤK;nrҥÓߑMm§qeVnmgތҹݛD#S|:!A$rGYwtp7kwv^g+l]2bMFip,P6u 19'v-vs8m Q{u7[w(ԟUqP<0E]y\-UwH/YXЪ(?)㉹p1reZ;^ $ /!Xvxįx46#0yC$?6 Kv'sGZumxuXͷLUPvSlO%EMj] `vHZ#Uvϑ<.?YH3u'+=K0Ū]Pq~1v*ee\:v>ZdX3)Boe0z_67~ < WȝK/pY-Y[6KkjR,up'mơ<{a`/H5ڲ|gԍ+OQ:E>Ъyҙ.f[Oah&JX/ iYc|@^t' +?䨡w_ |0Ȩ7iXHm敽 JOtƆg ዗@7|@~3!|: 4&&fE:!ҭߠ$r݁3WR|}6&T,&00" I |3syX/:v>*{tƢSnRկJu+2:NG4wfr+53p/{gw^w9ch);gQ@z9|nSؗ6fG_b܌WÒۣw,A`8PZZD~x  pIDs5D!! ,g5U=d߅?eb|mX_e +v\!K[nOe4: g! H,C./f?UC H/2V8<|d_MǜcmlOc KQwNӸ6Gp6GjjsHe7JY)WhM}r@߈o@{%r{{<{8'#&`ޭj{j?#\C760 TOZjne*r*# +tL#Fw>` `|R]VES1r;M؜Xk2 GP6:$WnT̤+ +ԁy&Ca8]{~8bɉt8JvG~INOS.e!pp0˜x^x}5firgX1\;&~wCAѶ>ElhN-ÌCFsXd"͌'f +"&q8x}ܼ66yѲ;´e. G,=GT_oE%n|l𷜊LpwǺ=D=Wn46DG,?M!m XH({+dIe;¥ۮxEҢp^h2x*}o뷷nz\Z.Wa /sȥNh<;C՚5hd2m̟C.Q+bE2<+<"xގR3kl(|S[P ;x\Qx%t74qkZqs^Etz8JqzmRԱ̖9#c:Pø^k6%@ *3nN?Pגι7+S+0'-?]Z EA9zߏU=GrtN9H.mI-t^y3|4$FT~3Wmnՙ%D*p9_\3ɥ[[7I1bD}gF=rLBهg=I Gn:k:4@MбV:ZEE{|z'ِlISriŤA5ʅ+C>n<7.zZvpLwd6k DjuPmh交t $ϰggz3Alj =չ-A.[@ ~~AL??2ؐk˻и_ຈ|XxOv 6uW*9/5YȨ,^aUդ:kǩ+)-nI̱o5 @ɽ۰#AE¸qؘ J+9 +$L! 0hʖ9J\ɀW G_3/kĂYxoTHW:zle,SyK-C4lHs138m#}GFJM +_>RV7BܗƳLJE\{='e=[6mo{df;y:MGX"'߲V(TyQs{0q*Qd'2D}ї[)r/p$baPQ^"|!'m?Zowmj%i:Ͱ|ђ$1Ҫ K9KQ"g|fO.fTe١i4d!(hh[f;3V +ѫAhWMxFCvi0 0O SO*zXČ*fWS-; w+6-<7#uHzm3rw64aดxK2y{0ׯsc>IFeqpb^#~7{-+C3z%TeU%OhDQAA9g]7 Ew1Nؓ0 bs=', ;gsuOMJML'mlݶrjwٮcLMv)c5ͳVkrz|Ǭ\+浇fńM dl*r߼2V˛dFÎ3?5/Q}mXU&_teˋQ!٦^g33\2B婽ܧ'7dLz ]} GT'#D(6 Qva,S6uGagͬ;;a˛-"|L +1cط4Bμ,WJG;ScO*GO)^|Wq|Ĕ,R_/Ί[C[GE[{?,0Ro( O?Tv`/v"Kpd J`ƪTwU7cexICW3ب{Ŵ| +|c{q`ogZdOO5*)S.}Jt=ߙxZeQg<ϰOf׿:S~5jtT_PKity\3 _ +w(ơȯSKoMnGQ&ݽ*;ʹtO$tR j];u{G~*/TTގGI&.=˟hF(cM۴퇮G>hV=\a)Խyƞܑ-okceΝ%eKbUKyڰlSӆLjT+\ud~gBF|,ô*ufWk5*0rNrUQ]Ѡ PvӒ+*琉Mc3}I$LF/U$5U8T1P\tas.tD<@ƈe..O1eaNڸ ӝۃWϷjyd LbU/.c1bR` :\ '5Se*3Dx 5ޮ#5$l|xNzx˼怯\ شct~]jTdI(Uإy7~份6~7imB&Y4Z  a7ALUDr2D>}Dt@,!% evU7<^- p(5iq/{:S?_|% +3Djb.aL + q@\cR{= Hk«{@LPu3 䔍ǀҞ;8F- ڤ 4i\ҌȮq2vfA2 H$\Tx yn/@^2#l]Wȗ!| JdݦA|{Ъma=mz'u4,X oG"ھSDh\O#@$)%YP_XIDv܃N`Ke@yuP|tU(PE!qgPN?X} 1a^XS a*!(%w Ixu}--a~€LL(9"ok7Pɇ2w Iq-JO.+Ϲ똱rܘav%Sk?jGΐFqk +`\)17^dpqf '~ +?9 )S2=Zc~"ch{f[>je9=W`ѽ襇\ OpLpU=\/Yc+fL+e,O2(*#ОsDŽ_M&Qɼ 0 %aL㏰ S28C'0V'}_aUDdxx[Vӽ㕮u+윞״Kr@pk7׻!ɭ!٭с 8FyyE + "-TiG?DzPt4}5>KQRnV^2n^] 'ҽR*J\4].׹tsƟR?UfG^\n.ۏcnpse˳BcgjΤaS3$B]B,n:x83BgmWvbsiXBcl#Nhnj ն$=hnQJxT]ƚTfSj8Y?.!M/>a(TVM7_?y}}*u_uװn8 +wyg֔m4tC\.iWgp͢}J%63¸ɎX~ůI14;EgV篛GU06{I~O:T&a1Y ꪟ +R?`Kai=hbs*Y̊H#1.=ޜ\C1Hfyx-( o6ĮvX v!J& T $*Ȉ0f,MBT5WZ]s2)ZE緈gF;0] 2[}~ *(1 +*9҆~Ӄw vQ_=Mi8SZ]:-Ge w2'kyy'ݗV]q zmZb^涵g6"oV;aJrmE;84Z[qdJQSO +SrO]9Nصn>Č? zcjOnnid2Tv?S{'/L,(9=]/~$Ƶ@VظW8Jv:dr +o*txFtV҈3:@ϰU$X4:}oڕ|W9lja}^*c(*s9m8_K*vH$]$r4)PnhB3N0Pq1wu!G h_-FFx+}\^ ?gYU^0V;-kd$ =hc"@ħq)q=`q# +d֛[xSŋOY ΋˱q/(nd TuHJEPi 3oxBY$T˪߫k žd-gŢʀomye(e0(2> ($|bݩS-u[ X׼}|6'=Fb2PFOz#!n5wȢb,p\4NW+s3b_ynC h®؊67yR0<(i&AěAc2 +Ṗ5ho[ߤ[&,zE +J26J (p0qܰuuN5OSfIb Ե{Bo0Y5f:y> +M|ׅ[즵e_nCA>f6T!]!r; jlU9T^@.6V |C A0E6RRzz! n!Y{b`1]2oJV"]ۆ.(@Ɩۚ"$j$ܴخeUy, W/bqgEQDQEQETPT&"Ii0Y'7ַ5l K*9M_Ⱥ50YjRiձ@I=.j`:Px"?fmVDK=ty&K +IӄkZoMi;^)Y"44+m" 8@jTzw侨|TbNb5lSXߩfn4 R3>fJIѶXT тրIj <  Kb m +Q\#LͅY 2L*3rF~zd,jxe*iҽ5t@Gݘc[A,ctSq>McO&RI5ShyUw l:[N?W`9WSu]&zgrpwgƗ|V, cֽI-3}S AU@L笿dW Mæ3v=pn+)-*pͥhڀT7"PӀ}Ox$(堖U߫˶gvӺqIRJg]@tJuf3c`W? KරTC X}9 -j93h.m"<nPM1%p(ۈ<=BGQ3@ s6!'bAث06xObC40Cafn^ÌSZ|kbq {;|针2fe i%zx)ԓPC\Rr E-46T|OX}뗷sŜWavwսh$<ƫy?\_B G1a5O42~'1<srVOy2|jZ,uVƹq"o;woߥ#rG5/G:!Vvܡf-=ދdcZͧgv:NX 2zk):S]k"za?bImWlTIgjEcwan`Юqh<^"״ffqsD2ޑڎݢ 5ސ `#}S .\W9Թþ&tp)۳p=H*7(Sa3l%Ճ#wf)E`JqO9aoG|;Nۂ=[29YeWnU"ڻEcįXq2ۊjsj  9#\v[?JJ&ė[GUhƺwݧۙ턴Ƭzf6~6KWOOHgrݱuKV{kx^uO[ <.&d̋Xo1˼<Y-w/I&==O+c:&!O"TU(a#"QrDEUP1r<]k*:9n\|}XSk|쯨4-%qJ.-L-Qn:{hg^d=w~YD5;} |$ݠVg뙗~鹢5cNߡ$YpjKЃzaX7YlݼۦB'eHhl5kp֮.>)cVӄXL5\}ZP2DSMJ,n]dCerKk;<=^-&qTnFY7OZO{_'[Y?=~R#DZLx5f`(\R}}&2v 5_q"}>{Rx%oo;@;r$yzqeUY̒]hvVK5OؗcG~@Ǿ<3DZD"WZA& Msh.4wq;X\p~\X|dVwQ?0.^G()BdMnj`JAh;jD9a䥬T%OR5!qU`!ҔOe:';7_R`ruŞLh72U>fs3W" TǍ@dF!_Iy65q!+p=&Ç-+ +^5M^5!ӄ953_;:]BƉgfj40&ʋ EI`n?N;ە{!Bi^ Fy9 -S6s fк7{v_6َZ#M/2E>)%`ψsho (T-}$[$oD<g%_엻dBQ9{v`i1YЏ8Vݖhob k`pZL5}zI):Sg 1/4Є2t~=oZ>̥`O=\v}~ Fd + H6mk>ݼY\sNc/ɋחOD&v[e;^}ܣ捙zo@yb*JUOrH$vZnƕ.|51gy$L`f}L`Ccs~k.+즚Ԫ;&9\75P>ձ3fsZ=49*5-)}#DGSgM`5Xbf|ǷN:=z;0rw;k&#wޯ\]# 1p~ p Zk͚^kֲju)@Bg@$;FHbUٝ`ө1KmQEߧSW~- E5.'~y?ոi@P?tIAC4(rx . +(z +gI*?R U0tS ̼14^Zt*bPޛrqYbTND&7/ !iFQ+e:J-) E6~x&nʎ$vArE])Z &Za,.gO8Xc1Zà{1L}ڮ=ɭDa@{y*.Jr*ݝ*cJիo :%,gPrTx왺d^-,\q^ . R;ռ"U\;kw4[[/ҥYd3m5Cig_YP[qGrgm" p<% eN&:]8:mb-d*hX/,\n ÿ~>fo]ES`?\gZ޵T]*e|JʶwR][nRU8&:l`>. }~0:~d?Jak̯E0 _/,[/3ښGjD*x?T=H?R[&0Lz⛷j9/S-|[JcjEhDݾd_xVfT/k@U3.Ŵ!43 7g./3}#S9S\7H=q_f+}EX"E >*[aZ?u ̏b/}CʘBZ陇VխdwL_2E2\ /"[=49rc %לpYv1C9ϦGi~(e |E"+ˍ>lF~BuӕavdugzT66e|ٺl7c혃SFp%DRX"f!'2Fx8EAZ C6#3͞SmW#?Ff~듾 7rm˲j3lfJڜ*z?F6EáE"'!'b`iԤ~G`ku +ХdRQ (%ǿ_[Z$F,j%X˃JYCFQb\Ygl^Yn 'E@N t'oX.(P݂]ow`d7Ŷ:Hw.G(% 4~5ɠ.ku@yݶ"5PjLkNP>V IP&A?kЄ&j :GKx"ǁ^cZYʛOƻc<%0r|(NEoT(o_XN6 j"xm Yv_@,S\sDlTP2\HP +V9h.XFaDzE: n6ޙn!]lwOd@#mEѫ I5~C)0(MʡlCcTT:CEkl7Tt#M+CY@L4QyiZ#NӺA!fb:ϥӺՓz. +7ؿg+?ŌoQFu漧q+NzG㫇' ʬI#Eee#1ʰMˋ=;,tgֹ_#턻u)Bp/~s\V"PqU՘yݟ&Z?vh5h2g$\(8j<5f#b4:,\zy1)K㈹o[3꣯8ruueHsҍ!xˠVTd@OUKx2A>ˈͬ|@ލ<-p[E#ދUKW76[Ի\YD;?5?2G#ZsS Vղ8YKX=uCi6m3Юn_ӥ32O-Au6u=:xbVĤq5L Gq:\[O\sutFstE95>rp{UsKv푝zۨ eu5fsKmΰVhiYw`P׻&hӸ"wXe$L/j-A]]Z~Q}Q7ߗo9Eq3'\5N~{n_bZgI=-5D\[@߷NV̱F7_5ĕvn͝2 MBYgiI/yvQWeS sk[r#A8C)g'tK!4rOw'Yf ƞ9 iB19jAPSΙMYzOMZUsG͐ aD cIt%002?1ot<S;QVElQɇq~WU6nPcG2%9hXm=&0!; +8+ѩg30<70~94Νfp|Jx!}{Uz-G9L"NCkvxZNvSjzW#)=LU2Ӥb PEO??:G7TGIoOxb7e c+햠&5ק=mO&b3;XS9j \kruukIY#LyG4eHH+p32>1\\HdfhNCWM= g~bݰlJH!/'C y+*ƕrK5`]Ce^SϷK=S4,=ά<-䴗oNj{\ܧ8SS'&gFzK*!ʰZX:ߣ4PҋQdhkIܝxzo=-SR+ nDc!w FCٳSaUHLMnM_o,MdkYWGjUE9/7ӡ.0*-B<^ebE;j ʯ˻ި@ 7dW/`p|ԉyV|{Cnn֔@4(zf_^P)U\_,Gֲ8T0HQ +@sF1{PE+(~P(%ʺ+veRwm>oL1:-u*Kj\OAFE6w>[ϻA9fmfkv=DXuK'ECR򉷜&(C,̄CN#"g+.ggCxbMx"l~$Of?аę ipq1׊Cx_녝r2qb7˦JzS,]-{{VU2TȲ]05u k0 8Ml^ll/67H[YCچs~1җVyД^AlnJU}벢S6+m~*ODVlf8×L +O~M.$c=Iy,o h"4^ن^?GТOKgSO#xRl@l?g7|VA>5P[u^T<W"+HG7 ov@VH14#oHC͂26UJ!r]Қz+\:Gs=* uW)`/11ZoNs +41,3X_iZ69?=X0e(z~bJ@CQڎQQ$;n"w'j.'3HÉ2xqh +߈ͥBOwQ-g5DcɳةSk2C8"V[+NiF2'N!S1-<H'e"8 + vK':r}:3:Q:C=:+?/2&PԽ#7o퐍⮺`yl>k)iWod,ŝ!FћMs"/t8HbUP]@ ף2]tGygz]jEcFH@.x"ej컱8PjC6/:c꯿!hq "r6#Nv[6 t9*{sQ*lx/M(:'#hb{_VJr(Wyk ϝC,y-VTc0,YF<`z 4Jm/ +_#/[ɏQgFثg؛Wo`[yL%%3֢6Pp۴5L\"k|("O l?-ĺ꽿l `Q * RBe @}Gdf? @е.@ q w(S1C%q];"Q/h(*"( +,. (?u2V'WrRShPs7Ȥ7lp?ȏOҶM75'.U'NfX"UJ4P4 PL?pj[@Mc䷂fZwMq1u9P ((1\Z]{ʌw4]6t4 Bw*-b3NR; +k;fM\"l}Q~(G +DrjnUtچ*%ڿ-lUjb k ՛:Z@/%qm=l CcW>z*4'vFvWw<)yu|]].딷=S'&2[A/VWIK*ܐSe*@WL +0{ئvTSrwv{P:X7SB0$ԽO[j;~0z+DvnX:'HPm`vB jC`{X5udঘ]Zjj5֡`/Wz8zA^\B HhvO(xV &o?.QĔ*=TY:<0il/KؾQ{zԪ +""*+PwG5ļ $4UihQj7yA1Ĭt!>8n [rD:jz텗AWǹ>{CQ}[ `.݀P.سP YGdſᗯ?P)(c݊yc~I§t[9-&{`?KOx|{,A;}ooJnw9||ޓ)/YfzN$T/-/㿠~\Z'\Qhq9-aX|h6M0g ?򾖟d:&=$^z)Am͡ӏHoĞ?N%+^y!/r~L_';,+<|n! <7NɊN +};vtpķ1Håa>jYtrI5̎/D0zӻMv<Ÿ^3YLRV+_Idhb0I"qNOVIgI壵 ErJLn滳ҒA_E1GgIP?d\G< +ᔖaֱ~3O:;nDiSYDٗvͼ8!&ߗէȚIFXvXwmmeW eO/Jr@m9HZ7LbkNW]/6((%$d8C-oZ<V*nmE$v"7Gv$D_E8Lj՚1GPWX伩JWcwY'bA%go9b@camx&,̞)q;kTi}%J_+2- 8>E\6ݎ{GC3䡸5kؼ6SAw-Oܰcd$1l̝rBri8)4 1 *ͷT}ET[aj +Yr|r*Nh- RaTFӪ"xQo쐻7{>ܞYdu|0/663_{K)ҥxJ1?&ѮOOM"WkA')!&%J<6a_@ _;ֵ󤶇fX[(j W(Y8.[:7'+u= 7c45Vt)_|Tj.x%O6=Nb4nكHJ&=@]!Taf;0\fͮL}vߔLv"fmwDigFn@/OM:&S,>ņɒoBnF +/I6<<ik40qPЫ τ|[M熃)T1쪽yMGm/^# +~_l)1CE찲{4DLWN>uǝߢ: +<~ EX1>ǝH;;dNa[ġbcNHjLCtAgnM; )\+|- .#P +EF3 r}hUģif]'Uˋ+I[Q҈g@t4tXyL.~ n+6?|9(g^WW<3#u~4LLgcOŖ! AsR;_&v1쨖'j%r`fa~ᶝؽ`uC_5p?6Aq,.O'B*RF=Y8\&҈f:8 `XJa;CIm6C:ΞyZ [-r±Ps$e/3mF_+B @oB5SJbȢz2k[J}y䀧AR%.c$njvd2 a:j[W.oY~߆%fw~p] +*I txpwszl̬Xke +5Ď%ͻ_=_-1CdC܇_V;~M[$ZgB(k7o7lweX]{sucr}0 Rqž^^ptڭR.Ho؃U:f2ŻT-י1ys'J29+9\(a\A$GWUBc=kL3w鴳kɩoʣjC-]<~ g/o&8{:qJy+w͔j9 +ȔXI~[}D~2Fտ ,|=Բ٤eV;|0z6OhNU{.M^iN|}BCfXev,'p{1}f)%s[}(Mbm/_pvB395 8N'8Җ}Ubez*ivH#6=]Ms܁Ro^Bw\-@o:b;u5=co*%c[G +k|1h_RЄBL_ 2]7;юIP=%J +ntnxi.{5ZulR:}K}V)B/bKK L" +ͩ# ̌;Bsat@6 A(z`Xlх*Q7[W =/ϥV +mnLP#.V1Hn1?8yV2 /;[4XF%%$8s LܪPSg e$;^0r Bǟ WFe3}_QC| +Hk M+H& RFId:#Udf\<@!=2ʁ -S4 + iG>5|4z:>Rp}:%(_%,=b̭g9=rɂ<ʠZ%P@*(@CPLɀ{*ڋ+в4A#2]и4G"BGZ3mo1Fqe>M\ٙQ \DNBI׶Nu.=BX冱L{Faݯkŭy q<ȶ#8w;$5렕l0֖<s22W1 ,ob[ x W?Њ.^)u +lwU@}td/l>kkx}m$Ʌ6#SC 0 x_UY؃lQ AWV֊Tg%i'r /!$] )[?%i @ű!VB-nhss@d,DG@A)x:Qu + _Ue픐 J/da ߤj$g2Ӄ˔QCZ/ϰx#׋kgUyN={'f9H2AGiOމ@O13Wn&'|^%=@SQϖBf)*w}xC<ہbA[>,oԿsԷ0\uCOŢj)%Y^N8V7 c(pVH4ϝuݪ.m2/g?\,C"i.-}xcnnnjD/ <;g7=mC3/ nLh@m IT7J8ۢP0Zlp>Cخն;l2y:`pAVVk`C2+2ڦP(#Cdy{rez=|WˣI˄2"/` +HW ci}z<+$ȷ4|oLBʛEJԩfU1!EB=,lJVDґju5i~N:|URt%qxZ-4EwhiİPS:l̶B497JOiC_07eQp({ljE dHu!.\D' <Ώ]i &46@5Kժ<vB=րTҟv ފҾ~a -5-V"`&i0:4 +InW;UncKzm|v38ƬѦj$dTZDUFxBs6Jy43j:k{i\dY2 Ls+n{ά׼@z᰼U(: (H#$,FTd/᫮Pko zǾ݆sOD|wnl﬉p^[kM77!we%ymz/n_πPo/^3fzgDz>Xr1BUU2Aw%{ՁӖ`뿂DF'-B:FINK> ɛ{-v+wȖ4_1DL` ީj֫ -8{TⳚ<n<1,d/2/7)\D=I2~nll&(Y/SEVbզZ9G/Fj뾕D +֯UifiWN3EI0JWPPJz5ҝ4_q>AQ,e*n?c10h +\Y$KΏ!:y(0f-t؎~%̬&aZW%T­76n,ʲMib_;s|QS9afEъ,溁r(Y?Vc@}?8~8'v)jN*6gՏGt1>ݙ`߿fo591EWe\P,45%*i)*u̷^Yi:#n۶OC }d0n0C~;.у렡apjѻNW`fc:!>LT4Ë-{ ?%A]at#^h<[3ǔ*SpR3_( /6X^m=P7~{bsg'Ǒn>BO}Y=?Z~ a!y3cr^~,ȹHdd¬4xVmS1{/eC{ֱ|PcQ2vJ-ɐ1HjH6J3{mՙp07 +p;7PIώ'BIiKokk\_jR<>)~.P~5=V2Jru>>H͗TEbiZo`f'<]Qh]qTNmX_~iM/]6fozUd,$cLi+DdFkNlշޫJ&RiðO (* ! iSv|NbغX@< }  Z՘t9]2+[xp=ӆfUmwUшOFc+vd1ʐpav-|!>@O@rJ9džTbJ @&حD\6M  LJ=@I {r93VS$+\>]+mh뼑N$7JГqi|Gwx`43G?kJm Pz(W%*PPUPw\w2z@n:@EPq+-BMe&@!@ud~,G(~w-ն<~;[2x%XaĿA&mGM0Ow0@r*wa 0\dkrO0?謓ȩ$tRBJ˚Ͼo~^x1UNA);:,E+<`E|'à쾡q.صvV~ۺ4[ 1\Vz ۏ̡fV|Z;6~KR.sC1~!+Dy"W:ZLd5ÏL@Xr6ECWߌ/Β^rC1%w{۶i߲m0ӎ<;p;uRCZY0/GvJW;D"־b{=buMS(ݣ+_ެROmNUeri{񠰽8q;Q)P,tKG+՞3IPt +ز"o'fxˁquaW5h9MW~CcDT@Efᦓ՛W ?i<ҰxP5[P:"'OS6~fKe.4.!\$ +^Q"}$|;$#{j,dQQw2o{ _WEbDHI@@ň s?tu[^A#(ْ_Qpat}}~_HE=~y]~v (;{96JUzPz{@>sUlk nUѾ{BHGb2 A>nqw>ojo)oy6g>\ZiqϰQ=$z:Ŝ)$shvҰ~J2k.hm|I@kXof껹953*3Qn=]^Ysm:1il]4]}׌MI e],q뉮ܺoە7*3}My}#kgQ~&04Zr]VeޔDw Ō&P+g _v[^Ή;ᵂKW_ kU6J~-h>~ch2NRQUW-͔";^zE=p[iK/T$*a!*Nz$DnOrjpunqAYkXH:XWq5i.wt${Q.2^{uvyggǛS\ɣrC-Rc +cl |Z9} hb+wݻKU}T f3rC)u|y|VͿu2bxT^}CdԽ +cvrW3mnRfNsA[5})}|pKE-ߧuF1Q#!? gH, #bhYs'*~!m^\6~+E3 cBqymhP!ˣ,=Xjҋtz.n1  RZm$CNEI*g&t S49o|ŏaQYEQ' q,&*J^Q#̼K59z~(UW.'M c%?1}iEv,B⿁ +^՘sU<-z:oFgGXڳ' ׿ YR àJFkSBatl!-D &9-"Cˤߞl.vjvrg/:Vy EIJ]m w8s.rOAAax^PSyì{EOn9:#Xü;"N|6'+ -]_[*IssPT?={s137M*-krA-lrEኄs2xx^<;q4~.<}Pc;k~)f鲣uyVZJKdvH_/1=1OTF~9n%uxQFl~BSFfG%z> Mr #[wVIPa:OQyւ/]I ’X5-mkQ#8 #{ϭnڋ<89!?(g1G(JӦzۭO#vBLH A#  +d,2<} x`ҫo} ,鈥O~EU A%}[馉 BJXtq1mF -.drS(J-h +>2?z)TۿŁPs6)NR>G㈷x!+>6r-gxϖq՚S+ZzZړ/v#O#,X5ETqA@P񫁠9Ġ F.SAT; `>3K"*"ws/%tWf.5'>x7>ze3MǕ\(kS{_h?9 }t#D;@ l{DK~D( 4D^s y0A"tQ?6z Qaz6R˗"y^PQ/D{Pz֗$>wx He?AIĤJFF.HURv4 7HV{ $1@7#oߞP1[/U6ve5eV%Sxk3[g@CzN似a#&yT;䱔EL O rGW"WZu^ k#!ʷzzvv^ml%' գ3tI9R/ M4vt_f@,s2zYfn•55pAy=P(区]%_ehkBA8[=bnm_'nƶMײ]kRh"`۳ ;P[_:xx>a_MX̵jJ 2BՒx^ )3u#2Tuv\mW7$_8"Г$+nx@%q㵠ªgY8Dl~G1LH;#hf%׿]2M]V襢%GuQyup?>,ذ>>?'ps_:<V=Ɇ7{02:?\ɒERKEAAAGAEA5=+bgٙLYZr;z|%MoK$[e 3".}BE]Wx\tEt>C0 | 4k +U +৘;_/~u`uK769Fo;&h^WZs9l/[X.|d7j''eQOnW^7z4b΀֧-]7[? %ҠU5 {:U钔3k3ඓ0˩*:3nƉޔ+u?%S & cAlS^jؓ1@t[ID `[~{%ݲ2hWLl}Rq>yYDĺ6x_&<:Λu3dqlpj@ÍC\S:'tE1YmqkӟU@s߻;fz˩6BZӠ8o+xOzxSCXrApن*ږܺǵ0{kv d\HԪ++,)q֖b:ua4z[2gg]5,TŴ?m0 |)6 2IH*KtM!0R-y#I{-%q>fߐ[D(PaWwWϒe>S |bs$&9IhH +Hv!͎ԟ0.o#WȤ'W<7Z;w-\Z:mElul̹b>FԽg)cKC᠜+(K?Tskj#c݌, A.|o^1$ \0GN0vWgiКР;vbk(ֈDzLW,ޡkQsVEMڗ-m)^knxxipeK4`+8Ī5)_i:M-jԙj2eukB$onSHM:V_b?E1x,(1'(^ +kB M +/4ESg45Wֻ74|+SI? $~63aW5OԂ[(3_O28.qGFCORn[+87|/St4gew# +MVCEɉ,v"KmuBg؉b+cHIX K)왱rЦVN' ZI:8 c .g^aOI +[zntSf>z#%h4uRDq="c|{;\gf5IFaIm>؟ӸvpFRaF3OVa0l>OZpvNk-dyN}~W#fVez@qs#|LۂP fV3c0`TB 7\-7sWmpТ5,킸"+F "cG@N: t<{5;ΦfVGbx"a9ĕi;}#2( ~ H[ 4@aY"dfza~&I {%&RJqAsb!:뷽u}ir?z~ . uH+kn|8 Le6 CB|3P}`؞BraXk&hʦ%ͣWo=4b-jـؔZv`ϫ 9`bJoyE pǣ9T[ + cpk„ [p-\729 v \C!3aNJ#l);>K{ ?*h8Z-KA$p5 +ag W,imsJCH) @dhq' +eRj>[—6$iHv˵\ `}UNTD9""JD|ֳ +{|/;Zi;vWV0T+pI+6ߙќMM.躑۩S1m{LQDb9oUs 6}3R#]5èb\&[jN\ |(=Q3\ʥ/32ʚJKi8svS6&]I51誆xUgOvAanPN,e[iV6Ϣhi2#%k-1_N0ݴ1'fsΌ<1RyN שVS6'zUVcP4͋cKIs2½K7e"G??=8{f'ڎ\,-E< >m7M%T$ 4d ujqrk[#nG=(=?)?| iPԪVf4h yՏ ]_xzޱ$,lMb\(~E"CH)J3ϗ=<{r2>`N =T.hînQt\7Kk8BfeMV3eL #NuÅo4jqdaUB8 3}' )^F.!4_v.j`;Z߁"dVGn EZ +Yl]$U%bWc<&.~NEr)ԅjF@A3AHe~sHTjFfnv<"i\UL(Co7EL{WW?P{bNf==NY_XcuSoҼRmW~NK@gxwܾv ^FtГk'_PۅSK⛾~xR=X60WU+Gl+'ٶ7OⷶIŮ=y +Uw~ݭ b27C^J[>rʵzuj{dώy/0*K %mrwfplZb nk<ȔɞWva]c%H$w?uvK*h]osK.KgM?uv0m06Ћ_$}]Fw> *P(ccR3݊Mvng"yTp:5W'S=_@&sD~o()s`OE*BN #bH d.,"Ѕh>jl2x@yKfy'^ZNOb%,:MIq5=a'[cag*uߔ'U25ɰ٥HpnD] bx735CA ; tՏRכԇ?gGk+E3}-FBwBmu9{cs.K!q|Jn>$x&D<3Be~u\W6"윍4-Fm{Go9+W+ԍ `YzYCiýY990 +-̌DNwN[NET'2&BdY!oX?n@T?Tb8H$,:B +J{ {o};`,̲RuU-[3gzYJa#OL7e28T i<~ 1#w/'d4ܐ ,5EɠM.e?P+5vRSO_,W8TN3X+ͅj4p2kI4REÈmk+]]eTYuL?hZ,Y{~g0_߶S,ܛ7tSÍ +Ӆo@k6%Ysx/1yn(/PdgaM?Ng3l~A8~;j_ʝ=%h pS:H2eeD6?n9nOw}-a~M  +怊 , *:UbjW\a5x!n&57}!ev:*5u- 1 +1[oa(m'G9Koo?;J귌rmrG+Af1HYw,-$Gvx\*3L>'D M(UqIt~O֍=o" ˜I|x;ژGˋi["–d*G3<ǗI;1X]x_]>SN f.ĥ` +*5za#=\T!j'yHLW|0F_lk.^OVw?C}*fG|r;-`S +X1UxtͣҘ&\]#q;=,%޽_vU2B8>)Fݯ4>9'X NDyH$:BthFw8^O` }buJb[&~­rw/B·ю|'ٔLa!E;#*-lQ&ʡJYB1" #forp%_I!6&PC:c-A{DX MY@QU!HԬ* X E-HRHA`k]-M(72cu^_A-QXSfF]AU/G#twe!3:bҀ$ _U }w+tnA^-ۻȣ b}]F_qp\طXJYq$1${~eܤ$ߩ(U3A=$iA"EP1(N?e@i7ێM:T.Wqv:C _U&9NP*ǟ* ;mbPΧ7(**j@-J8A(Ss45gVA;+##h4"*gkЮZ"BmP sfa;'Vn+wĀYЌ +}L1 4_LBʩ*wҐZƞ&Eaw::'f@/$[_σ><5@_7Oْ'gxÑqyh3-uR?RcM IE7 N/G6Xge2 DԽ)/>\ڢӏ0]6ggȆY*Fmoiwtm +Q38t9Ad +[Ǽ`9HB{:Xz+nI5}C[[N~]#xO8xGs?Ǜ-uH5Pj#儹?t$lv%ml% +N⾄\:- &FBiJf2&"$g゠^cS[ҨchdB:KZD6v ȇNz0`Y凍4!vUkP^]lh0L霣rE7j:' +:HGc&Q-hUu(Op"қ`AEDQ/ {yɝ|ݬ8 ,!% +)m 㪘p w`'r9N6 \(=BeI'ymye!m,qoK1&SR٧tK,i:<%|Iy-Eq }Cɼۛj<.p5'{YZx†8=VKNekRkji3ZR~7XL0FmUñ>wtˋurY{qCd NʼŀNzU/S۴zw2ouֽ%O1ؘc.w^VnG+hx:ÔۘU+ &D]=kp\>{_%Gf>ޘFSF5VV ңt?;䄓2lHsևgDuţ4}QӠIU.}k3t [+"˟V)uI/WeQ(lm4ԘvØFtvӭ+҅PmS(Q$yu]IMy5qXчI6fOeaT"42?1wp\+V &) |&e"K[tteZ3*3MƧI@RvN?`{\g_/RQZY:VD4*1O2M}XynSg2I,o>ݸN3E79!NG9 Tea7wŠON1>F52D&-mM\DQQ!V} RX:[@:>g!0, +y ZO A%,)?wNOsS&ݒnQ]-uaKL2r'eoUϓP&%yvVUh D KlG (xc}@dpE{bNJl Ky7踾w`_ۏ*.qezY殡J6Dd'!@M誎=#P&eR +ru! {r \ ȃU@Y 7T H/3}@M9u;f;PFϵd3*+FJ%fQ3eb +D!SPl9 P e@- Pm (]hOU\(ynF7ʷsp^EGgj7Grd+!By>3z"<+RSS,4@5(ZA"@zӀ]+^m)@7:ek h`Ơh C|->'sW)Sx;moŨhaI'5%O/^A{Y9k@-d.`b݁ǐ{DA70+CO,WPUu 4_ko gkEPrDC!=NO&M{g|ΡB -A,]TsH6Q M~mʦK&}0i<`&YN endstream endobj 40 0 obj <>stream +HTmױJKHJDDDDo~1s}XcǚsrS R@@3@"18-(I# +(hZu*hK:h;O8juD@Hk^v(}SȐy! hOɰ:mnў >Y0ITV0*V>hk~hM!CvGJ_ H1eDcE3<7>ހbo@) P Pt_T2dd/7):V (6?jXH\G=f݄Ɲء.c[H$rj(åyͧއ+l6~/Bz'vCC9MvH_؝NKɩSecA^zͻ+U.!..YRZy^%?)d; yx fw3Ct ȟGR{`sv`n|>[wF~nG:yIAs)GMD`{AiO߱>7ӞMΣd'mؓ!UЌڄd31M^7ۼ=5NT8>}. 7nI_R\Yw Gp$=̧#gW{' 8*2 ?Ǯ^kkxұčYN6 AK6WWb)<{@ n_}qsq>\swт*A۳wxCmXֶضlp;v]W8^M8]uZ8dvt{ʒc[HdqTM +Un7xoQb6̒2ف/qDz}W?h~ϔ6w 70͵Ycz/ycdADz}Y؞P~] +M7_c&aĞgGw#q:j*ğ/nY1Zx~ov*QG2~̅Pܺ6eĺ쎣ҙtnϴl+T,)zNGj0Ui2 DN*:Ix=Zb1Lvߡ- /\?S0֓^iK5htO0kMېh`NR1*B +^eơ^ƓVCV"1VNG˞5"rRU(;S(qu1q 6}/ѷz.i}ݠҢw AV(#zfl4|/ϪRƓ:QtbŶ[ڌ[ˎ"ב\9K)O<}-DB` ;ZF~\.@2BOƚSgl*&9.ѵb+Y8EMKL{DdZ6Nd qyx + rсK|hU~BM\:\ Z1)d&zaagg;o.A091}pvr] W{Úl$SiW|32uUv$XՏV@@Y|h==7N?l>+졘0ς&׻eڝ?4|Wɞg"SJk +ܢnK]uo +ȷhe<^{~,_3ͺޒы652aV?ytV{E7E2n&kᄈ~KIb KUE֬ۙr,e@弱v jvG*ɧEx/I2%^5}1?-/+d+D;6,csϊC5m W ڭ2Z}iꪚgbrúVI[ubٵ~9j^I|sspen M`y 񾽮6 + \[݂lRY+YfܾFTGWZk1~oXg? 8)7[w$4IX4-1==aNw -K'\]jV?gCc)Z3No1 mr Slc?x1SigGC賑&)پLyIflU;)/"'(Υ/wU5n1NnRq2'+1իTYTujE?BEC->WY+*q+{`/k_b5v',;*4kU+2k+ʜɸvh3,+7܅˫[?Cqۉl]9BGZԛ< rtMY |yPދL4qf\݂`R'G p^[g({'vOL=z̡ +W6]{(XoO97}}9omiMJOXs Q0e@pQ`t #@T% pPB7 /QzfiQ]g˪"i<įAQg٢( (8e'o>.J4E d?xnzl?HSkwGy'ڋ +G)ԒCK$g͖%.I)=];lD  B[*с(Dm#F>"9A) GtFZE<[>cG{,py cM)h6nZ fO[sh}um +nBc&Uy n˓zu g^H}\}vHn1$k<`@b d #XFͼ X]FQaZ]BkrPU|^XhceS ++ +k@#o(4x1 Єd(Te(V + +B[P  *@) }}9'iН8%Ys5)՘bs)*O¢D zh +/~m0F>8lrgZfh&V)27@Y'PMr(oHRruh7fu)RR a_-y(c03|*눳Nkz;?R> qc(fsiĘb#vSߵ#q*8:cWh{$c`T;y˵Ֆ* +Fh}Jd_Jbox07pl{Cm?T+0CfDr,v: Y[,y`v ۘӫk20-nڝZQP3Z1TEWLe]jG?)Kc`+el֚> ~yW1ണܤg7喈8+=2579UD)!xF{:**?$5e W]vs*EyC! (Ng +z=y# ,RY D,U@sUcX ۧm}+j8Hg:gN57ʔV~??O_ +?"![PBw(*WbPjF0yҴHOZPXurP̡̜ϧ?)dq5q刺o8v6*2N˯ Op7ZY6g*Dq+.0mixu#Ѣ(*w|Z#r~ Lj~͂쨳P>NIOYWed8!a$ o?7N^7__܈[ߝ|;NeSm2ܦa +tN?HG(hXW>_f(*늧wHbcqЈk=~}rZ +$K5ۻamǂ[D@l1nWkY4th RQTR:H5S|ۻp_TPԊڽFZ\n!v ~6߹ccGy<ge#5)򠲍9Y4QB*\g d4L|\K[Viouo=-Is. cIC_6'M"-a;If~a4?VQ`^YIQ@=na, IE_Ǵ_Hw8ql|z2qUMp5uuzv_)X/+xGuv֧M#5>$ŴGr4#~J$K\K+Ix FI7kv,$4yw! +K,{b1wuf줳)SviqvvYm\WmQH7ļ4xVU +iTKaJ=1Xk3fi48N뗪g12U(IE}Ə.+Vi: r;D 5a0Ir?;U BhVm)iS<;S^QA|i 5oD

x7Z-`2tӯG $K MCuae:Ѷk6ŮDXBF96rUWX Q‰nϠPu[˵יts!UZle3滅uȭ_jezbP_S솚L^0k +0{5iX}6578SI0aAw au5,k+xmmi>܍c,;L MW$$/|^XO +1-G?Mԋw3Ϣo}:3lU[Gv}n$~EI06*P iP33g󱔖F3ڴf;rgT*[#TELĆvzҿhr%Fo{{|yK: FnnݮiR[8I:œi]MfQq,. ܯ vcV)?޼ +h:85ZPTm6QF{E{םz]Ja<$Z=@t AO \s_?ݸtk]Ys@HIxglJ +DYۣGНQr%M&K|LL(Iƣ_^{k L{]0, L LN"D/p }{m6vêVt)<_?A ҅źndWn9kg56kl9ͯ2ZASn'z +ڊg`#I`-X1v=UT##q GƷ?2 Ps*:no .];y[)FV5q,lp*rIfv6L29ZU"xH7UB&6pD!_H_=(p87)pN.Nd,ӳg>sG- +M_ k.Y ]( <5?O< +g!sg39tET!1|7ԣJ Fy0WѬʱf.}ᾘ#8CPA$'!_a!a8nb.3aTY!qk v58@H:x%]sǑ\d89 XGY̊O62ɲķ>Q<k&D$jėL?缅s lVqkHbx݂8U͂87@!"Vy f(~*x9iM!-4% } *S"ӟ¿d HG6^8G!)vU6/JkzG<Ar>H H{i[(*Yty^z/NUHM!*7F[oMOy?,1}%(2BȠ +c(@ O&$AnRTy1jܜ-[GZ>IDݢ 1&?2+NK`eC_1X +V[-;Fvv+uaa+e.oE)!%$VuÜk1ջOL6o0{CDHZ̯'5~[U浿Po`}sФ0hLPOqq6o3 @*@$ +|U~[z9U|z5ΦKmj蘺*o˹#ǿc{'er#BPu-qquTt/د9L.J=BNn.im>&s^w8ʂ;mg!x׊q3+~Bᕉer 8@9"ʹiIS[ZC~brH^Bwp{r2FnkM}3Zsut_ۑ9 uV}a&޵)Nr3RA;knHW=<aڌ֝~Ui{sb娹1ڸ:j鲛}Yٙ8[Q[Tf +"}<|Q|3ArygF)؟h-R}PhxNeB2ńw&⴬\Э3-󉘍$ KSw6nu3 'D)JT"y>?XeSBaG/:@o:.$KzsF,tnrc~U7`;9Eظnit.,uM^U+C,%օt8r ]1CUIzw{|vͲ 7i 5Y<)bt$yM'*3|+5ߦk*R8y](l%;(FKr 6e|%',bA'ȉP1穃s}Cxu,W) aƛ}G}~\m~o\&蜸#seRFYKktбBMJԠ$crAȢJy7sX35B!?]esQ{ +^N,)ꖇ `DBt:ue!б@UGAI[BISS)[βfS&fW!:CNٟh{k>M"'4˔d`}¤g85r2Yo)llj]2-^W8([/bYWE[2 暈 +`TxUpr^9DPph:b41~L08`FaЖ4˳RΊmS`͆y= ,+|yQdB xdF$ SdU]tnbm@W)>sN\Wc 6-).+a42y?0t3̨"큵u:C(cȁ08t*{!>х%D''"&<L8z*TgW.d͞2kD:X P oc4B:@?HoT W[m?TZnyJX{\9tṷgL;~{Q47)JtPg'ϐ:Kt:\}ǺፆV=*]~V,yo^5 Ah_ӁlwIN>mvZ5h[Pt<prrIe#'L6?Uz5WHKXvg$vVlvx2 "n)YNtC7WwZZW|q;y95Ĥ +_(ᒔ*UŅ81wnH0"^g+lm%ޜ3z7 4y1M21ٻd 9I[fQkoO>Gj>W)fE՜WV"3oۅwwmerR>ygk,;i(< E4v)kDQ?CHC+jyЧ#6 ~y/|/Mgm+a&B)&\n۔dnT)sC W,7S7LcYGЛ[R{xRVZP4H2 JN/]&N VU +̃u߱Rw oV(pޭ߻?e3VƜVe4¢q=gETX?l=r#kKҩR`#17!S* 7A}6V=?Q =^ +7vE!'/^[kv~$! +o V{ +5#qU.73G$&QļxbA>߭SGbx~?;+,F*,SpWI&D}c1WL^{$fRf)6 SҺfJ}@fB9A hP8Pte deCOa:\^qW#ݚAרϪk0bZl̚އ%f̦:#-˵xtCĥ XL4ЧkX\V,e*"~V``UfҀOx5;DtYY-W/"*y  AQPAp^>뜪?zZ )]J.u OsN!{59תrL/ ~Nry5Ǭs<\>pw~¾K|țď8bp8,.2>^4 XKPSDW=ǢqmO5diAf'k??Vhk9?K_x &m\ +9-GdR~}ɶrtk'RոE\ ҳ0lHEx_tBya]@ؓ>W +K +@LC-YqhV ZąQ)h N \vvĠ?jETm䜟?3- +1m|CoHJ~ jhLIyq,@6G'/Y[NB6[f{km L;HX3wy,9d:[~:Bt} 3+W[ʏ,v~wd?37v@|I@:KR5иɗ oh1G*7އ|C2:m6gǧs)*#gPJ(.a Sӫ,١VE/3KB.ؐώVѫ-$okP3v{C$PvG-^#︾g(2>\n~^^򡐹`$#1r ѫ` ׯ-W?!l=Ä}|&{I3Yٕ2m-.U;N8׽Yy +]q^ٺ~³0WVz߳o%˳|NOGn ;Wt;bo-D鍌|])rdn_wi5ߵȶytVҕ/Qi(DeiWYgyL1O)mue=n8?_x6ruxtYnlm>7rGkzW_٢&BF%/۴7ܩީyr]3m{4eͩ[DxR2[#V]Xi?a5E -a+#`{bWr&EE_j&f>: F^:M=%XM|-Lt}Xxd\4_* XbSc̰{5'U*=C~!llۨvvi7-:00:{j"ơXQҨUFcЮ3!3vJn^nZsީ}Ož?}z -/D6ߍ-}Rd&QAEW\]:uR\yj[ ;fQM^#ohWmi|T_UR#PaEry- dA +hADQ"( EE>af6WU'c{Q =U+TƦonjo!]臶9% {}X5WJ|k?K*K_Hy,WCh5L9[( wtZHR3&%_]K?]=q5nD+݁,4B\>*@99r4'rK̖f߂Ef'zStp3q3P: Oe:ZIu57*VI"d+hy<&d`{%(D"ct Z+XV).F|xk# + W{>V0e7XҰDR uѸCw73qƂC [^_̜cp߽|)OFmCnnSW[;hO6)ϢU÷N}N_F ++s k63)YhZ< Z<:)uµhqkhOSθj!\[ {;HS1>YŒEH$V -o.+3,}u@35qL:#㭃m/e}|SE١Ȩ:EzLtO~Z՞\\Ǔ䰓-mNԲGyf-K)7_?e0 +L(C%I*/{٬L߫%x^cI(&|OM0hIU_ -5f;V돥d BtyIrȂ}IDQ#C(T?"sΡ@/pDaӕ{furּ&'|JWߏPG~%c˅|`hh:EUJYf*@ǜO|}rrdb[10C|kQk$>m&3jt72ٗ&ڝ,gi$xuW7T`D*[yTtpуSQ4S;2Wجl43ʅZ\`f3{4uK }Vz''^|T!.6)QbhLk\V% 6C­{V^iBɉF' lzuJOR!mc.UCvx*rcKFwmBI b[ lQ/G4&!f H6MRcBkOj +\|w  qls5=J>mzvj]&`z~i-4H4ZO[hcH̑0C !HJz\ɒ9Cz-៴ˍ>o6w.+:kk|5dcIoH0BE&P  QƗP4rA*) ٿe*+uCaGz_H?a:{k e,,ŵjlCAu/>ԯɸ@ .,E}-h\ }hxpPon"FMeE:b~e'!*"@&8 ℳ(N Oߐt*L: ??cA`aZ,Wf\ ,"Bғ!W.݉zi}-l*KŚ'~9יN<۾Ft+uؒz%ۻVSbJ!uUF&Sx=l?3cab{ݾZ5~W恝tj<}jn;yϺBN 7SP5v2CP/Pb#UadEXg_BDN; [ɣit\\S-+E2—q5*veZDqo *z`'ZEW聝tu?2R\Kq).ťR\KP& u{|!Mױrg*R\Kq)ߖ D˟ӌ3),"]ӹgi rvA1R\Ku&3F ߐ82-T&B9&݀$~P&,FZR+6Pzv޼ť`┣ )ƾ!^#+c8Ev^0F) ^ŏ Ue%?;fOP\oiH縷Knh? +$p[=}/TtFuZU]LAĠsH֒[1|EzoY.HmMl9E6A|%+P +gf.ť8P^)}8髃6pi"h@TX +N_89[36<_VAM30v=}H Yxh<:3~F9VŹL,b3}dKaikCiCavt<{ \s# ++xߚ@fOR$ +vJc&H#Y.5P_3qFߺȼD#y;B,A¥WQEEYJo`/diA a" gO3YZ-]qxc1;CLbDӹkx$t~~ݾ w 8Pr*:?bW,~ .F1ؿ/ę$ _\"LN + dd#c9WF>뷒v),*tPu#\҃<Tz9jx/]+ءݻS3O +Lɣlvǝ/'bT .0] mmi2@!apE\T*| 6N0~a*:$ɨk5=r#;yfN5f).Ffn2\bIM-#SEm3qėV+Y]O_rp:_p([ ||w/FFS Y0UʕLp?w( )ԅ\]!+QTI- ̱;OOb[3kq+W,>j` jٵ,\Ί !]T4k^7ƘyMr8s:ܣ&8׽($&Yc{\/>,6Z>[7*U'D.j͉ؠ ͧomĵ8XLaɂ|Zrj'nq!!eWsoS]3ЮHVfL + 1!xwz\y<,sIH.۩jF}gVoy(¶zq TOь(+ YUXEnᷴT(S#P[4B[V [VRk +qLՋn6Ԝ߸ECu܂=tYɓlr#[IJe +EA.~E+e(C70G3(CICY̹ `wun-9&C%8_sϖD'K8׻㩒3./^ng,:k||z 1Hyt4A-sr/4 8;|tG6vg^p Ve#4j geL5 +1zIJ?nU!JIXB2IS= 497]"]ܔEbRF5z/X9lM> g֛{0w':Wlt֥XMg_x p\s5D[YBUi4F+ܨVyn_77lF[ajp!K%Š#&u(%a\{;D\I%ρ/4y$b<{Ͻ~`TG4ݍduw@0(<ScʦSF2K]iI60^Jsb7BY5kXJ7 _q 8r3.i22}4RQ8Z'6y=% Ip–-ypų$^sGv,t焩dEEI^(4YA&Ic" ߣkF>Ry*peLHQO4Yd+G7gravlj~A,NLfBbrȈWϼɡ~W7? 6e浐.7/n%;QٶG(YPK\i?PтG)ܗקI+g]oч8a?"ˉh7- D:`sCnft0nd診M+-iS*Ėm6134A/܇ ul8>jpb1jmR&ka\&}S<TF^mmz()d`+~ՄPϡ%-"tJ_zdrLN~NQ/T|.1@QmsvA)-5^`|Rn<79)t.gmHGUYRP֧ɽvU fX^m^<^IU3g_pv}xF'ʴg$ֶ#pV\XIS^F)J#t 5MD%Bߠ ʱEB +8e0C"́9J.ƫu |2)9`m}@/ֱL<}7 +8|i;uJ_'gݓ͊-4SIVA+55[Pʬ\6i,>E:rzmUZѸSwBY k$_cHO `>RɴDIYҹǣrq,W}"$C}T@XN|Tp6=jcx(;KQrVS #8nr!bVdJiOC76!`.4b*Mb!8Ի_rDo>RKĐIqd8Zau6*kJ1-"[P%pe {ִroqfst}F,/҈A1eVkM%{k{lD<ٻ_kkny +/f Dh5[&hea{d6܂?yLNy__(((gz@qck™x +C9>CDͶw\[T+qbR7EEBixγ,gnd돒?] K[v̷%4-bTN !Rĭ_ G6Y'yQ9g{qFWl+w9|O_Amq ś|PsvNܓse# =㸞dgxwJ~}Gݩ4պomktVg*OF pU: +FIOAo9 8>x&y[¾PF|hnJO v"$eU}~d]ܨY5SVJƞE:U}B=(h* tEU=Ϫpm,q &WJD*ahy脁JTuf'l*]ݒniՋDvi)ˏ5>1k;'GZPrt%QչszJi͍-kS,.dL>V),ۗVs3!;_ ǣ22nbt"[{ąWg4(vFVĪ=C~)VX䴔b:dʴ.0\ |0abetnvN8\_ZFkEz[.ˉ?B >Q"j4hD)TPEP6*S8V6SS3lz}OۗP0'?WQy\Dr(ўq|aנFW޺4nmo&D +C>Բta"t7.W# @>QpPȳQ&Yh l0~#>stream +HWrL~DA"H&06 &]gߙH}Nm[n%4_Ǘv[_r8^/뇿۷n x&=եIQ'Z@' +b . 483hje;,TZcYR÷F'\Ŵz78Wfb[th&ä@ ik(`NB@~2 iMW7V%L ө#Klk==b +y`J>6UBxi"j%yJl@t +H qaD8'-q9-exPCt - +sUR!LU(āN"+U +KzdվЗ~S+} BTw<ANZS\MJ\W7=܃. xaT +3 ;L03wo&)|}=iI> ;S^양j<)䝨#ۀJ!8w'c pB`C]-f)0yJlw3,4qa,N6_jx|Tr~Nw5 +d=_WV6ʃOy(*[v¯I*ri$ﮌO1Ek 螣0@RK:.N 7'@闍'Z]͗k/9$5OP5TDy8x^#qOʃF [߆2~rl2zraNU+| _*Y1"<q"p-+B =37E4=4Z(~Al0팩=XAH~7px bq@Ws<O0kE?sBCOW[Dzc/dB2 {7BИwMIJ!-r?A;$=m2!u׭˶KMfHp+;jѷ W]iYEuOI&XĿP/,]g`X?|{|/U}5Ǜd!UlNZ[ӽPD4Պ//-nź9+ٲpkVt~M U Sf@90V!!n\mu,⽙)nFU"}(k0~i%oW*41hV ZͤRV!ַ7q*lT ܟ5!}]7zR4`NR6w5bL43y^WCh1bֽxrNJq%Jwg^ ^ ~>_ 2~EŬET;F>fa( ,{`+lŒ1!7DL!Mק;\.lcmVߴ^XypahTH`WZ-U,Zj ~_rlsKq[HVQ-{z.{y?0ÀWr8[< 0_%~q422hkVr)jbt6}{WΫaM1hN^]*Q C(wTDw+jϢ($&sK°e0PW5 2oJď!qu$3ȈLed,c݀ \\yGox`쎦VdD(kG&_wcf&a`jM, RnztL{G%YG]!#Z?uu/V >6Rl2p s|:%]eu U9xTT Dv.tgؒMw=a$5TiYm~pRw1 h%lzs/="bb/ __k2'{mR#!_SI#!9Zq +ICH'_Vm3^7ZVp{biQDTa4-dVFqmbڍkA~!_Ͽ0%W#j7D4~9<--Tqf6Ut卓-6IK8qhKo7g r#ifedxCf }-YqKk$ XrgYX!OXT x9 E gK}$d SZqjD8QRT{K%G]B|SPzƳL^zr({O bfI!}H>xc^90~g;aY=Eq !ec|杫 bkۦJ}-Tɏ/7[K >wISn^GR La߻Arr¦(|d,T*LDjQ !1&{͵R .KR(-׋(MͤiiԲRr-@mϠ%r1a;̉ρ9V62%560E#[:rn\ǐЬuqml&,.1~Vå:X"˄¾w 1,\wEm9ф$P74uN}cڧN;~oL3_2 +WA%^¢S\ x9*@7=¬-/"&;Ɔ,<#/H@ J``j~JRsP ̈Ac~anۗeo(\gyi'[$?lI-^VZҋ3ThrJS(7-_h^sQ&8KfںG sd%.ܽ16 v1}}>eeol{9i..4B.ǧe'Td#-9zIPаMV([w"(JTZ-z0_kkOl.ȵ3p1fzF,PV].U4G cv(e65=C+ F+ )ȗ]qij%;!$\9S^%‘۝J>{B< +f@r' 8Bˆ/~KpU,}Bg#qmTy Mf6#a`0$M)\zSD +ڎsE\еzg^ 1-GV)&.nġ\M70tyӂ#Ca F0•%Ô4/Fr-HN\ S42ʷ[*MIL_.>״\[6˵9,;=LU Nx/W;Ëol0]F>?c8$ˆV1']bjy\G rż[BmB!G__bUtK@jj[az*r!WCPS8 )( nP4 L'8uin΋J81Af|I:uUT*NHߛ ٦瓹F!./ w$FlU/OF%NE|7in\.clZ84W 9C lJ}{mA`s," =9il,m"|vkZ?]ijZfguz_څnYqa0n%Υ|BC/~8e/y8BrMvPW~74w{ݟ$9R' +VyRϮ|:>cyXGe缬:C60͸sP!#!Ta|֝{[**fdO390s_odDV&R MMtޡ^   DŽ_#,>J˜x4T5ZX hz a&Xi -S(?N&m44T% b[: ^LK8`uBn7h%֘LcE? 'bMa:SD0OT,D'kb@Y׉D3VlįEt.B.F$a?݇Σa!2E;>,([,;;4sM]OwBTymd󛣞G +Y%A'ZW&hU֨R=gJJF!H'89%rיKs|sba;jtu[4ֳ7W_ߺ1$پ"͡woJF@ѱê_ 0uv Xy&zlSL3H(M%4ʆl$[زl9=yP2s57S8NsaAbN%85տ4K տi.сn]uSS3}W)ŕ )ȱBt*P蹞I/*ө)]ns4uo"Z}|}P![(ѹPfE=%:>7TМyÿ!*'AP=-FL|3aFQ7ju9Pr_к [?mM6URiM\1;XA/ eޒhA}[DPxHÍ +Jj9݂xFl+N|T:~[0SEf~dhܾ߭~!;1ZP<Yf Lq4%_@ԕk"[x^G;7F^<޸ lݥ׺zLJZ!T,cZ̈Gkց "Y]yR)f&-unt #Z +bXVӫ^F"PB4ֹ>݆x +_c<զSzU$e2q:9oywc|PFe4x< lzW?JLtbg:%rs`#?Ag )ˇ-ItJ=4SSЅa j?S^@P%\g=D,wgj򉳑`XjV{pocQip[PJP0T`4H[vrB?$7[–{YcZ4L0U>]ZjiJࣕjLh8̀mIJUb̲i 3sK`lqXv_dϔ0w752 +azzTX؆b cF_mk>`^V> ]?GQD޸2#FGaPKL ߊvչ" ڣOv=# xa"Cl!W%c9 GL醔ҠDb!t,=f#{㭄1ʽ#l 4;Yީy~|aTWwȹJjfq@'>o{"e:ĠCrF]z:7e~)fa\$U[ڴs߼#-/EFXKi9[Sy<ێ{ ٕ[;ve&+[Nb'܃Jeop"@_"n Mh|1Qٿ 9 4',;f|ƃ3^0}0v{ Ic&`h}0x5}`'8'hЊh֬7AS\C~A +]>5]+QooϛD1_%8Y4 ݋HV4 }iன(q0>iϴsv=# hV fydt$a݆~ 8Ti~M"K7_iPC }OfYtW|S GcVY)fڡ{{{eᝆ޳d5 +b^NC}!u4"^vuiIp(a% n69۷(/׺㒻ۗ^Xx$WywU}I%BbVſTM&vR5+9^mX4=]RfND&&u>(9kb`S񾤱̜iLT:wqXn4 \ӑ'bG$XZ7/9LzT2isAF5gE4V:tНS7 jP_b,*& +1빨nxHf/aA"dp%Jċ7W eUY+29I/oQNuj:UoVIOl^m`G@;*:@[Q8 &&m&!iSK.΁ƀ [: 4qrjd,?.?l3&Ms\Y=^\d%w5s:C=t(2}FPBs;Spqxn\K#9ԙ_9N{)RxS;ՓoO\q4:pPp7iwgd` +=D9߽n߁\իڽc*}i+ m/)7P(>GMS0P)5BS$^vDcm 9_wthHh^v `ָ9U6B^e[Oy(KoN^{3T8ĉvէ='j'~ d;NJ~q3sp~Rf27?w{"zH kbmW5 ,kTYwgkȘbt,_Z1Sc=c5TY iSظVx +Y)fV>7:Ԝj$OW%M;e#CX`3X IS/1e1_ƖxoC"vyϝTd)|ЮiG"lĔ |W^qʯǒUY+GG q=K̎`kNHාDXdt_:si(mkcJd}G'PUwv^G[ML210 a-ϛt7Ğ<޿ a3 =}.04Vft7¡4:$.NҫvRDc1N[ʸd8{!0>Yz86{1Qj1B!ch5{oiSyc +1c!"ԗ:< />z5|++i'+$@ c| 1XRjՕJKE6Lo.@|vOtv h< C?PAŷϦzYAnEsH40h,Y h1o;3';}yxN*p>ۅȎ3r;P1bK%U}PGٚ}ǓT$M|tVJU^xua"Ϧ_*}+H!0kl(Sg&ndX%LV)CPd+rev!w!R$5tHhrsqu'7Nx}<;޲ ږkqscU +rXHϔ=^?jߓ"&LOG'dޖx:fXw c^]@􏐭pc4 FK[R4%P˭[rP il#xEYɅa bsX q^zM|GŔ^Xiwd ɪ^ᕧoqr}[/&IDnyK,SK 03k)qQY)s 聽^M^J;ufԓ{%9rc 2EX.g_ oFd hb)PH`A~؟s +csĸWL=ag/Ou< +pa"5y.pZeP8(yWSs(,[!<*8j\h%NS +v0FSa]L؋fET̘9Gx4JJwk/8OsD+&EIf+m = ctSU䷨.lr"I%ȐYY8 3-7zefKL",Oϥa0: +poF=!] Sړ;%unaɳxanZߐ1jdF?/-.\j,Ԫ) +\Tq#]ӢZSngcWn1VIe\@ctX v20Ց税sj%ªsjeWe~R-TA,[oQJBFǏ\obc{Ao\;$v-$bg $VcKN%1VCM<cum>-5;yyI"cI*dF."(uIHWNObg')Yn@;Ms[fnuR:}.ī H~wҦX*|ėo?yDf{J21d@!Dc !a@6 )(QVKbpdz$AIX{ XY:4TBZEޕV]q!۴ +%a!$ a#g EB7xg@S%ǐؘKYcI4;?hbc)8ѹ +an+û6j4,b}h/4CCyY^8s_.<8hNF=ٌoxQ3_`z)꧑xQ +œBG\_֮i +^G!z-vu|vZiVw?B:X/ Wx*rX+ɌBNt8\"Y ̵`ES9K;\Pch{EK".sZbN%kEN8Εui=@Vkpz/cc,Vvj]EDN8iObkevjqnd6>\<[}{F}8]Gb2]D9˼t?l&!<ؓz¼yIi&Tm7##2ݢP)Vhz׼Ґp'A5\PlHQʏfK,8xpZWtQHk0$-.)ϳ)ĉ슥s4 MSp+ݭ>Q<[du;%?ncX-eYI˂z^~N |X;⠜x$niЕɑҕ9:_b \eJF^ԗ{ÈoV8tHmSNLMI[S5&P^{$͍uB &Tx*  W*Tv&9`)pj cΔswH +yj^'Sj ʜNN%5x\΅U(Sgq)O\s:Ϗ,F{ WFodE)<3T,ϱk:"A=&h $ohaSP]6粀b}_,v ^X2Bˆ1Aw'm`q&A/y`P# endstream endobj 42 0 obj <>stream +HWB@|HH +5 ] +REi)%4?QH|m曕CI`$) Xʮ>dn*Y;WkLBd{se&l@_ h^njFñ_',[ȡwZ +au*)\Y|J1\urO9&{w[AB|1S >+!-?-!p~NkV[s ibȒOL}s#ۍ֡Lc󒑩)J UuO,+fr^$ɀwh1/N+q@.uON؆sWM,Er: 0eA& +~i2jXR3! )=ZSʕw"JVS z~^P1ny&T;/.zM%` ,K^eQ9T„uRձpa!u|nol=6ua@͍;Yv!ۥgön1'(ŕ.a?bp줺_D%wl=&!d +{ۜ}kWb7pN/⊭ 7È*AqJ,Lq@jzauwu؛%HEUw+-F˯YPW EdrLCxTUA.{Ŭ4y4: {S> [v>!;g1 |j[Op`iA} +mY8-:b0;lki42UMe%a%Xra30Aڏ-:6 &!ӆ~ѥϐMw +x+9zu P PЌÅGcQK#fOkY 箥q<&U2j-2߰IÄ-&":a,[hwK9ٻ6] \gn\8#2dZ1eX q7+a+&d{O+A/i=xO0AYGk4^ω`'4@' c^|fcld>?XvW) ǾU'3x >|y>? Ef[A'+(P1'0~egL&\glãG"*/0MR UV\۲+ bVrKZPX}HeEUښ2mȣ Io°2$ڐ~˫ X+ 5Xf|-4~_T#ͻ];[GWNntSJroC3_u]\bhk`̒ɯ}o, d%nnUx<-E4#R 8zԥ@rg˯/5i˿7rx˩e>PWLO L-ޘ߅.Kk N=lG&0uQ+*H3"`A\[VXއ{ 3s[XՀ6y;?k~rrsIo-B}A4=JSj@ qo Q]Xd_˙ bz]܍Hh@T1dl14/ g ge8'Iug. Uڬl7D#XeR( (R>"P>>8O./ItTg_ǹ?Fp⮓T7^gvA$Ʈ7 0Yō[@>2m| ָ,6ި(͕E|l]0nL{]QSc(&nyTEn>gZ- +Y䝛oVB '$ +^b-¾<8teabk]>-Zy ~Dǹ &@:1@t) @`YS/>-u/$b>>Ix/Sca*ߏ+?UGܦ@.uG;u<\x,5=Nk~1pJG}bc/1]/U4cy( +ZEwtRbʍI(='_;>㿶aAނD߹:NvN憩m y<٠ΎS 4bZ66b;`éPB~؉@ZGƩ~yȰ`p=y4`q1ƾ!],'޷Aaoa~F:#!:F{-Ug~Hu)NYq h+j41ΒhQ۝gN79e")0Fk.~bʝQZS4@r +6(A1EnTγV@?l*8ESq$7#(*P! +eŖKu|b>RA:+"P]oȈ+m "'u-㗄[4^ڭp._CYjeGQe7Qu|Yj%qې>(u-V{J^jٖjcCv|_~pH=u^wy[@;W+#&'G" +X#+ oZ¥&0Dދ7(,3>R-Tx @w6@V,&*"{t6E(#{fbHOpg^řV_J:C-J//b{!KQ? 0n4!r`|m/yk +L8{$ACV֧2hh>Hpj[jjl,)3#zRDX٩3,G?|jk  OXr:qWG?)W,~>+cgR4veu&\R(t]ƃ!~:噔mjr<7S 8fsZ@(l \A!8EHNr7>t7[FO"iB vIJ%7_a= +0y]xUoLӔ.Ť3i?KHl6+ qo2cxF<,bd@F=t惏ms_\&No]EU ̈́)#uJLp1iEB=lSyAv,F&k]EPҢ\BrI[٘tj&ўhe !j\Pϭ˃e*[NqA*;Ҡآw9RlA{5˚bZxɠ}rQԆλQL}BJƀ Sm8b`[غG 8P !1kDzf¶&It Ԟ 7IuؼKr +ȫ|~̷R=(ϤGǍ +,\iS`Uʝ75r7x4ɘ}}AuR@[<^Ik R$ +{#+z>EY'ak>"r껄aё}\ m?]I=qvLx?۲TPP|n2cU PhP5I I2c1^miLVdH6< "XOT(*(<m-$sO2'i| {͌Ia&љrRlTT Ͻ,yZn}:ar}.2=2vU_QΜ?cB piJ-OL,a*J˫c6ydΚ}^|jx~ o㵌)DU&N 8fp9S2չ+<^lf Y8nTe "bD/Ϯ<>GVk`vĥ33`o5݁Q JiO:q~? m2 &ݣ;_JAFJ؛))D| ;ctr A=M B`8l +BDA@;ګSPGʢFq, ;@`Aq6V lƹ10 7xP>OPl"q=*p8Vn>ҋ ˛*:R|;d_F||qZFTtx/pzZrS}D >Vxut^9o#xsQ9~űÌ;̱>̱kQAg09{kF+b?CM?;{;-+JT v,BEo46s? /(>L=lNU-ޞD}t~}Dn䷐tfN팤 g=-;uoCQN梟y*:,}gR- +w7=S`N{H^xhaCo +[e\ +T}%8y 館dv3~՛6YϖN)7N Y%NxN^5{qc}<"ͩ}>:w9mfv]rygi:k ny??D8j T٤;+g?TQ-fiJcuwiܤ2aXgf + A1_qCqWZ e`zyƮ%JhqČYҽL.:;G{o#!(7EX1h_czuܩ6gb/5TS[[.nՒ+W[wqV"o3+s드*~.o YD9]?]2o$de1uVw[m=X,eyfR[{s׶'t`1vJ%R5_{sœ,OL9Vwqb_@wq&y KwO>k)%Pei&ޥRsYQY$$]7L'EɎ1#MD[9޻Gu/8\DLdPVtrO+ū(w;{\xr@/G8Fߐ +X.Y;KSV@]!ZͧC3IyHtĄ8~t}K؞ekMN,Ul?-{D+5xzk[$veLmaꊕ/I[{ b_l(ƙ[)i|IU?,V1 1/ Rցu~(Ǥ2v2³'aMyq;TIX1J0%H4s)SC+$3WjGZ1mfsa?,Wfscf,*&4Wb3(k.Mʖ(fK qZJUNZ If1GyX&Uشqm-l&ݎRlԻ# +?9U1 :aߵa.*yD(kUͿ9w}10yo$T؅Z" HKk Z99{ɶ +6w{WǺF3\g=S]\d? C +?hkV-^^{44Yc}ɓ@Q0wP=U.?sYAu+Ӻ2-X(7jz}7 X++5p8c:tt 1+ZHj`Qj;Z'nF"zr󖂛yRtGNޅ?t4o֍ )ӁXykɸ#2=0h}\#|;l(RU8/#Gzb=U3|Ie_GM-%c-'tz˰._SDwnkZ'P_Fd# )Pk ~~sbHHg`VUbH5VE3ub5ٟdzpN +Ȥ,2X*YmR@ Nb, ,}FȨ]?yG=` @hLiS3=Mjnzz 'Š=_v 3hZ$z>r?s޻բ(既@AY25xNj3b=>7_=jeCL7 ueTt w?VGсRCÝy@䢅`utm|?+i ێQ8G]p.*l>G;﹟m= ǔX8/VPsnd %y%|qjSF#1y ?V%b!*9p $&;#X. n rIU48 QV ! 췈'ޛO{PƿdDjVn%ud*Ό0XެDT#EEklVhc^^;[XYϒl!Bw沧uw>>wY\FI"˯x0_k[_Rǧŕͼ67#*Y2miK q[5Y(u@ +ײPw}s鴇C& \m'RB삏0< +ȿ.Wi{˷Õ洘^zܸm8Ԭ{ +"rǣon9MMSpVԘ:\s;_dMs{ +~9x +ehʚ4s5bRO!sYUf:4qbN0w|V8X8h:w̱X!d9κHe$A_s-3~tmP `{zSJWW=i‚s*'J1RamFnO۵gs\rK]}iN8ƑƑ-zӃʋKHU AG3w-Y%4c9xhoi,-wt63~J6 4z'&Г[$k(¼+-!XËݺ+7Ok~(}ڸ; >.P4hғv*.fN"C y\HIPD۱QƘ4;[QyQ):Kʞt?`d6R=ou`.GqM[רNk1J6#U";M čļWԑZX>f=>ύpcjALu|7_BYZզsι$زDxW +\`C!/y0X$\[ۿ+D#eDeWum^zӀة\o*6]r`0^-+8v^C[gcr25ek!h|SdWز-Lv: 6FMY#$ 饸4wzd}U'~ip +%Je$X8#w7.VK<84Mji]`?o4O3vFTU@k,Jx4Ef9YΌiQ'p$U40n@:h +2ȡe*ξP.\GՁP&e7TG! ;s-,!) D氙u⁐[uU]96z᫆!^֞!%>(ijRGϴviBs8jZ}.0xqB|x㗆tT4XC}C=Ҁ=[q*AՉ+2 9ݚe˰luDF'z];X5;4x:ФSo b5G_:-tSpzo׉2qN`[9i^'ӠgUX:@O-^cQ! (@C@d0; szU~+d2?}B8dRH&kc L\" op]ɑ|ݨpשC2-؟ܥhE4>C}AM6C_5C3ۉRH>ABt8 91ӣʌߦy S)3<~@}=o> 7n~酽* VPB08a+mZJK $1C}dk]9- !:h`@Anz a`8[ +, }QyqI)l'E$,h +"m 7^TYul8(zOZwJE6V6ڭ#SK틴Q#-ct d&k21-cGt\͉A_|΃ L Og9URmHH ?3X%w.bF x,7RFy6r]o>os3ZXf08+IW4S.Y' +s+ϰrh}-ɚx2N6t]4z *6k;š~淦 +׏f8)i +#LbeiƇVټͱ|NvTL4"l/i8VrXմͻ]\f$ "LjmY'k,i^ۦ9*}ݣ2(~J=5b Fe'l^30N/˳yI¡)Ղdieˮ63saZ罬ZS.n9 :%q;y+'}8@y:p/]곋%FfK3֤Feho#z[ӜG~*f$40~ޥiFTLĖRomg/_(O+"]ٳ7ԪQ6ͯx}B&DWy5‡9OΕά"+5ܱ>괝eF\`;EIX㸽fm`LGێ_c3O +=I`O6ğ=RJK|diO<ئPs컫ہEYq-ېQYȃ)~T%s N2ǁ2&' Yvv`äI5qFd!R&܋diNԪ"AM޾=fe\JAhfb'K=3's#JK1v?ϼٱ@>e]{%Hλwqh!MjdeX$''+2vyENŎ1x5QLEx߬ T$~K$Ɂ'Bېh)EWS Q/%L t`ƽM]I%Ns0"jlT)2!U[j.P:ntDQF`̶hFׅ*Zb6Ed?Џɍ/h~:"#Qxӌ?Mǿ??>~ׇ2CZ\o3kz*=CHږ +9TŒ6/kyTV5EtX½-nM};5?X;1;T;Q]za~Iek +\,dqb;㹥$î9T،lC訬.td.Å yTUs426B$~B-xm`TW⮬ T:׍2}\’*9<ʠ'rT\t-L",5'T.Y羯g`LTDyT}~QI}y_⍿}̭½ޭ)ݿ/I%Z@*v_9]撄)klW9 `sPxBuݜeN *.,D)F!Zy.qM⳧6} ȵč=li#t'DE4]*RbwJAj̴'6j}m6H}+&/:5́u98s5t\]+BI cL7ľLa!.hBZ2$AGF`k|:PCWBDfWb}8U>W039Gn{0p\8i420zs2W$p۷IR1Z:'&9`n]?'>cWf =Wl} 79otව|~"rRc|^&^OO]5 +B!vF9# +"oy'^ +uggvhFfuFbfk4tJKI.Rם#̫%%}5oTorb49ڨNI$fwNMC;є%%n0<6M=?DS@ ⤱Ata56ΎW}N@1uIF QB4mwyx9,{|j۪մǥ/*y߃81jY KabnNO\6|-;j9\G40)L%$OX2X] 7]ԮUlsDKȔ _ѼQ.+1?D?￐?OgY ֗~[9{X 3J\%HJN^5m8| -i!k}82ʦ?d} +xWkHMy>8*B9ƝtֳOXy*׿ePK~6XY .-rz˱My\wv2ƌzﻘyo=?na0 +VO9K T_Z(Zfc{8y9o<}K{"1vH[?01@x {.8Y|JRiJi`V1/c88, VrxX# ;䛭~<,\[c?עZaf>}>DľAȸKADV"V]#)aTEMnX iaN[/No-‰l_g\O Mg $ 5rLWkBMQYb>6uڸW%!gM{L@ԛ|aHqد9fAG%H@ ҩn.^mvL[?p QUˁMç3-U5-_)I#mAjM!-b[YÞ`]fgjO_"5.5Clz4m] mecP׊$3y^wʵۖ +k0;ƚ6\>_CW 64SYΏ>ŗl(]eba8*ا)J=e&:DLjdqusmt3mᔵh+6S#|.mǶ-Rn~5IH~0'1sR52WSڊύ0W8|FްYuZ %̑4n춙Am]EևgqJnHgU&_[}Q.q<{I#~3qkk@`3?>wxӮdTNllJx qCD+/jiΰ߳`ުK$X h_731$]fD+;e~u L~|,ʜv+~tXoK+W0S,#??8q'RwI']F"h  ҾJ_oYiE,c٩%; A%nqBUԓ]*SjCnFMYZ]Y2¦ .eZ&٦c^p}*_1\Ge/AK;g,.փHGɵe$o>M%\b%g| +fLevq@FE$lüSWRnfCyoӇ.0|1:"@컓/[/ S+.-R m$4oU*EwBaijo,?UBCikKIJ\Q,9;t6,9K'N_;yGűK"&^oZ-NYihlݮ)-s־pR}ii0c[W@JWvSպ)xh?8 [vS}e- Rچ"H8JRh ʭZ4dF@ 4mՙWMՌ*ˣoZs +7ű5@mc4ؿkPl`:kHV+YHoĦ-w4hPzm3r-Q$:PckSI2Z Sz +V+hʱo}ҷ fc/j<1>cSdmn0'-4E<Om[9l(E[<رscQBy5D(GKQ5:M5Ɓ=8p5܄Pg~#=1{_R.˪DL}pNzҬ;Q=r}3wzk}ٯ{z"I`8csZ +d>XFzxo},09v.^!>an͊c=߲NXoUքP:kjz }\ՌczF7"%Ǒ-̒6>l-c|?.k}&gHpڡz+տ:TG]Kе%Уw0 4.'bIt 5&3c h]"3*7Yys)s&8=,::M_G{{dKN.t}\-!SӋ 4)Z٣M1(qBY5)2p +ZKhcƧW 1YnSܻck-G ]p4 YSoV>MImG׊x ڞJpW5dn' ěM Juo9t Gl{ʹ +J#;>Wdu߉7^ M"ʞa0@SMÚGM+LK~e )ev8_ *S;9>'hm7`7W]}.LdS.&vq̙~5$hz-Q?w6PI V`㮈 SڔQ#9ŷ`PAAorwEI/-{6ǘmf0yQNεl,J8+gЧ]X|W8zX~WbS/ϭ}M]U"EeniYPg)rA ЅكpzT +eSH1"&CXieF6ϪbeGS*g]Z +޶lzY9=ຈ%۷yb;"tg3 -d-@ʫ-~s(lTlNSV3Ӽ'l ,f[/mcLkxëˈ`ecNۜ#3j.ypAAz (rZ 7 /Zˡf~SÈk"[n=1GK¥8[>r[cEv1?-R wm0~4BaXHNa)0Xcjqf5X::uN +nt[m3]+"F؛f,,c¦i"֫HczU~@#RX2,+6iw2R@G~f$HOfslcK u[+{!w!^RE43Q]QΚ n(qא5 +50gLl`wD]wu[2_e9$9!ceM rULhܵ +z;q,]5jm@.Ϳs}J>5[9bU$B gC974AN(0 w^38FQkgT0G'{]$Olv,IAjVjߤo i1z%yezQ6(ᙹ8+2J؟DicU+1Q֦I.TVe`YOs +?lh`=~צ=4Jܒl/蛜èX,\wBB3Rl"xQTv | FlUJ u M ?GhZ5ڿh$Ym}јJcKD V׃v.qxcrq^%;bټi C}L9z<vX [=5ҊUV%Ӝ]gZl[qX*A/` ŝڒmΪtGȲikL等hRT[Ksa4lgy, +1`iTGĔx?F#Ǭɼdʊt{|7Kʧ9cY*IKKP?S;~;{d}3Od*穻둉xLfh%sgL &-yd\ +(ydb^w#s#[x*23:x<2zd=Ud"䵢P'.m瑉XJ*YG&DG~<پ5㑉M7m׭gh%LSxdއȼGˑ=ݶ5EĜOo<2-{$lĴ +=*,4egLl$Qz.璉:sɏS\%nWpQ, +\lX[\2.H++d^GhO>%<7mi "!1J^<~o0I>adc뷐1 4Q=XW}7I~HI"~b4GUgvXNDyq%3¨>wLs%i/ +%V5(lSt1W')31g.6ݞjhR. OZGˣ +e.'+}(;9 ũf:|-҆us`bmϓz& vctTԖ惐3` [M0K uk7p/^RvP{|otb"34gwlE!Q󿧡,ʆ/mfLHY6Ga6d]~BX~Boꋷ\YFTӻ7՗nʨ+Js}) Xo1oV^'sVϡxh7s"c&O-cެcQk%\utg)l@Vֆ&#9d48u/;)\xٿ }O @M%b1 +*%FtћxPdOD\Hegj9PDlvr!7۵5cxfQw+9l9dǼ-\*qYpS9 _eibbT5eⶨP=#2ye4c'G9rsgZe^Zt"o73rGRteՆ ;,R36缁i/и^/h>a.kWo|Z AV؀g)a'/lE8fD7>>~ 9>c;_ynȽ+5<ۄ +R<`6UVaSbe^Q9Xn-qlK=R4 +Ng%kqc9]zd):k-"ѪA-$5XIGsƚЖJdBVaQɅX"w9dҖTHTG| x%mvkA*TYL"irƈ@ǢukN!]:[05[]cA/C5g[S܎.b!`F}`G biP4_]A6' do+HH/-k0DSjEi#(65j0",5Upp`yDVreɺ{*UwR!vutRxąI`Kw endstream endobj 43 0 obj <>stream +HtW1$9{A5*D%uq֌y?dffnHKx{ߦE|&sXV c@\"M X[U2f"b{7[S{k޳1?YC$>W {knLƪeN<|C<>lu0|?fB]ac`= dt@KݏUZ%#c&;T2lXԗf> O = +?#u(D3"Q7x(8&\د8/Cs}k ׾f33 +- ?ŋbf# l?0 EæNR *Rd遌s7:  9s{M?8tPQD,ݝUJȘ`0 !"gW*Hٺ|`RI;ͣU2T3+\uZS`j@2 DZˍ22Lе, |y=wފkY#%nHRřt 5O$;hAa~hm}Sl@(~6G\닀e۱=i>#i3Z"c1|iBt]Ccqe_(mCHAvX\a6/VM~t8;9!+Jw,sp`mAa;zv@~9b(VضP  }~>nB)"VfK!t~.PTw e:WIEAi9GR~H`\<*hܽv6BPw S$X#VzZ?BDI[{]Ah VmmUE@z" x+7ˁ+' P˾K|0Ats.Cg3adМ=/eʦSvb@-3Dlq!u9?w5" '18cA5<f! L<=8 c!GɴjAVa/jy!f luϿz6A% +ߡȢ݂ˎZN k֏ ;\`䇀e}"q"mvx\Ư8~r>Jl2U Xʃmݸt +W1 +~2_UAӈLpt2~YI34[ge9 }XڳĂ7FޟtSl÷Í +B?b>ƌK3D"v,,*_.g Xں(lDyLXs-+jU>b9ԁc^PO#AE4sh}8i^;_< B3m8mbWw Yu#Yب &r‰ߩ#6\E+Yؖ,lQ{H^R,]e1~iHrhqUg$ qH=G:˕,ӪeKE#HK `< 2sТXA-Kȏb1Q,b҃bYJ+"'ۊŝb3y5XޖnHllyRmh6iiL} .3?Ի>V5L0p Na٦x<4F}Rv6G +xDՀiU"C`&Ht u5Ki B5@`7LMO`ۈ)UEO)g|؞'w&h[6iL3  +--΀@t붖R@wAtl@ܱ1u<k볅0\4>-ogL_k$gϑhOЎY*aylKmwǵc %%g|IZoR.:G"zvmikv#6Lګ5!s=Nm|~?=gW{%L *9 ޿2r\=z};=73wMŨ.qı5XCбqrj}F~:d( (/TQ;b:awp?UB9}ЧadtAs@3}A`6 5"yz3pPl<\qsiZX7wAP֧ Dļ Js(},OAz@t\a< V5F`z-ح:kB=˳z3n߰ނz}F9< +PnMΓKa$_)E^#Qțޢ$bfihi=IYewmAv񐲦,g]j}e7b2l*.SYUDNQPqqWv YeN).LeԡV!Ќ\iVBD/p$-J.1S #R+?XY>H HDe_ ?v 0ڐāՑ]49I:=D$a#*kC 'a0;$b;b 5u̼S3x& v_M)]G,Vk%T7<Pۃps}ݻJ8$wR.58Jq1(>2t˧ng6'ͪ}^$Ϙ{ߖ6s-dة& yqc>WIw1FH -SYKXw,M8M-+z9Mֵz^A5$z_l;ʒO?>AbIkp޺6{fb7vc>%cnCn } +D d2mOA2K"ԲO?+S #W moV/qC*!AnAK+>^E߃%o C2X)5T7k̵fӨŢ +z6Ej|c|| ,S 6$\ڂqS9;~Ƭ&S\7 %`~+/OqHnMk|$A5Rx05?of֣/Syeb2 0p;V?CnV1s"@<"4"{ւ@D4ZZT$r>-vK]쪖50\BI<\KG.vd N/de Xa!(9~ XU[ KC2`ʇ,)ُ. B߀ +#Łz1^v.;.tAijfʄ쥠*(1LNbkNqbfڥe#Y{DžiMňD\6bnZ5}'nH_~J?;+>`@C:¤_\\/|ḧ[qJLePEC@A"'sꀬq^Kh[֛[06b^hFȹLukU$gL]WHL#K&*Q)y_߰y1F]k3~| P36a^YyYlI>cuy39#Ul;'o>翝8:%0Jz^vFڼ)w{۬ +hRZ3\k/lcD&9t;>swYLD59:EF16XxjA &N=DK$v^ն?  + :3# +E1*]SJ#>;gaS^Ī0AAR~lN$5Q ^#'҃Ry޺V{+SF`F9">,GB؈n^l&F1b%lo]s!H,`3*I4 TtK40q1hmi#f eӼy@Bg_gm_"&Bzk+c-im5juM'Y߅r 'aD0.TʼU0K`z +_燣&:`u=X$~2'{kbvL,6*ە9R%23E|=۹h +jbehB=L&IkΕ@ft;XT=@¾eJȠQ +hl7t|X2 A۔w,6ǻN3ɻie]3rv]m[򮟯]P!D)ޟ 2_-v9e O ͪAxf_ @.) v@H]y#`|lQ]ʂLNxg܎ JBGHi +zw[cmfxa9{(9pΘ`ؓ~\Yndni_Nk n{`@c}XL&LG;4 ^A3VMUE[i"RE NޓvY &7?wOHqrx@9 [ZZo;u_,?;y~C fR`mg0fR +|IZUbֻ;&L;vkKy*xM{*E였T(2SETz5b)#"H#VM4Y Ң^%MaV#i P +,m"w(J f{(yVGCUg {(, %/hy=C!,J=5*T>ޅp;&lM<qey!2PcRJ02:V|îp O2gV1ڣ.Wl|o؊%Pc&!V S >y T eZ7SI\I–NQ=o0 k2v*WO 1έVz`S\B&aɨl-BRxQ7GOF!-eUzĮWĵϷz⫽b8ֵ^=S8r"aYe֫'=^=þg67,URUwM~+6ZQT*I  ?UMI :pT9ױ,;N Q? ,``3cB"uQ\L0Ւ%ENpZ1]חtaX빘|>Mt>ǔK}Qw eWs Y-&km8f^{B|jzVrqߍ)e'yot$?o8vjإ:ע |ihNh½ +Qq_'@xA}C* =ro]BFyvY5MUs. ?XGlmr`T X;R]};-O=-- +9[/l%Go`x!݅9/~B7h6Ue{eJE =5۞`u,}C&j4rHzig`(LNl7%5[>a3QȦ!fcoaixw|Aa%THxV (VGSb=N 81gU|}S!nc_`GC0Poo+H=+D`-RZjS5g(ldعǏۓ F;Vdhp,̀bASIu\K,'ϴ1oŚ퍐"~HfpB' ?*yTFvvQGZ^ 4Q0gar+9Nwٶ<4hNmDZCуS[j2׺y٣z9\ŔyۿB~ygJUkHu!2uni8KZ]eMb߬Hls2Lk^;oj`>Ëȡ'߱Gua %\qЖ)6%nyd8:: I; 'K17p4|̐s\,}cVFGɌv Q8/Q8oH\y( So_ '`56ͥj +nF~;*{ +l.{,፦=a,nNiZOb(ymZH8V ++s~[gp{Ro"}L?}]zA~R)΂1eH4Tu9gX I ΊJbKDԐl*,GY^Z=gg҈V;QUydyXW\Rjw;CR}'09ziu䖆M_kCT[8^) x'Yl4G є3LQZ'2h3CL;-wayåюʙ[B|p; xOii;Qn|U%_AҰN}^VyŮQN&ӑ GKWCd.Dom?$WrSf}M;S=,t)侖BҠk)݊=36Vuwk/|ӏ[Gz{t.Nq[^'!(7u_VP#ޫ?CyvV}`&6?59i*(?ۜuP#39_$L [`H0/MQ'W jMl=(HIVr,DpCEӾ3eyҴeˆ:fm]uJ]A@0tiYdlKT=\ 5CQ3S {ϴ")N40UF#_tcݹbww=AV<8tc@ljj)FJ^bH4VQ'|-WJ< 'túfHC=,"+Hb+&?uZϵ@6RJyr+V[5MفP$#]SɌ) m$ ؇ˑf]tcyU p|zKva!6h/p ^@dj?q ~iY35$Tˢ 5A/-]s04}¼\xΫg:F в2ȸXbd4,R0!՘`0kvC=IN2OKr*ꒀjRԒZYMʑ/,ĩfJi5TmT A6^WDsr8:mMC߾¬0g_HR[r.دCn7\1V}zeuy>ӊQ @o $f +'Sa@Jj5{zi 6m"R ITP7&?^#%RĎle$9\-unNWԍ6"t/@ȸujӐՖP+X3dZkohBw؀269Ud'`Fow"H \6 GR HAIgVw֙-"8_H- Ȧ7$|^U7n En)Re-F%F&Ϥ&AFF7@e8+YWx@F T ݰ䆳b5!HpM7E +kЈ+zdJOٯ]|5Bkt OMZh aU ]~Q7ZtzJ:gtlյR?O[.w*:&*[B(#-R"m̊$Lp[@he=SvG~WET4X5V]-^=[P## G4W#JrwU[W0gLQ=lCEto5YF55=EVSy0diB85,`ԍ]kMhw"j~`jӊ K-wK| oqI[y!s2`B/gqK|OKOVF72l|QCM>.^\+Sr\呴pbV=TAjfY@{sW_˟2Td=KR4D&C#iv Y*X>u>YDm&uV$/6|R$ qdTÓ fo\=*,ٴKE-byվSOtmfȨPo^* c_NcӶ- Uj~6pyS7^M7 @O +f཭s9eM3>={d j>g}:}&~ Q˜ ꍐgY0d[sؑjyi$4Wl@-/V$jJfj—Z_.5'ͺ!|<=iY} *DX/q3bz\l=SN:A` ̖IDl>&`YwX*HJOnO$ p9FtdZW</$ͫp|?y&^DxZ J 5-oSL7]jV)C蛱RE)El;j* ix,@& nw !EW2y(al&uItŋBBX͏WU +R -}gRIa;$ s>q`NpSC_Ps۠JzhEƚi6Np͡tCJ-X0k.E UX\گq (4]^y_.k`^VHIL[)zREj$Iܱ(Qޭ4,I?UL`E-ә ̕OŲi\82ʄj\!r%GA$5$o\]p !U{M$Y%}F"]p=Lzn5uċULa,F/r/&63F?oUš]᱈ZbA2yj9퉺dXÙfƹЪy9ziߚq"ǤךB_WN aZ)&BQUaSM 1SҐk1@4)wb'kHhV +{Tn1|ɜM>9\jAs +H6gFH;A&O2ADlQḴ"qJ"D?_a@y/TA> M#Դ$U/UuR}[I毒K!5βwߚH0M ܵK~T{eDp^}yz{*FfJmϽzMgCMS&bmZkf|33|ylهlsZ>DAkhD +%զ.[lEtzs~[ SnzMGvҥHd-TϴOu.SZ݊1YY8ˑSO ܊q>dBDGEa~_GĨ` +c,>)#Kv ]yDcgTa^ +qP J}؟Oֽ_O!A 32GЊ Ր E\ 퓝''saFoFgW6yͤZ cOpnnx&n\!%̭+- +[Icǫ5C.KQa3Ek +rDmFlu  8OC_4QRP zҜ5I2NIQ\ UݷM ZƙhTu8U9mvVq*##;&9ZΉճLo>i +^ۍ̓^'U8Wfivю)̋DH(2t?P_F804( Ğ!C!4I,V +ӎdp"6.@MQ+B O\*K t fT0{/fSG^vd਎El9.*K,q/xHiQ͍% "ڐ*sч@zI|,ֻ.Jah l sKIf| #|5zJKpvs +BFkd㐃0J!n] Z1xf:૔y/IoT}ɻXI2iBq1H8IFқf!.9_p*j#OL~xEM[|/2ǿG} hA$VhK0zdžkC&'crB9`xEm}xCv5[/ D8H~ϸFt `.,)zK"\ !x20#^A;`4(oKtAn3ZBb(FLiGv $f!(7, +B.ZuXInN >jw$Ȟ{4uGmj8DGs@i _zNKYD( ^87=؍yK1z@; : +^[+͸((??=;4D-y 28#ՙH)ÈrJQAew-D*d7hf wYJPnh[dBkˑQ9IZn\el׀Y+`UcgBb*u$ίd7axvUf,;M2 -IqѯI9Y5=S*FC!%y+ MoJf(!MkA0|A/Y33d_,^Sc]ѵu #lϰbgʚ0,i> „jwU;Ѫ;Uʚi5gݍ&e1,5Te ie? A4Q0[m<CVeE.tV{}U,&6՞fݬ>L8X<22$= Yi:HdXj xYI-p\"wAVA0q,M{GQV^}5~ NVkۇYZtSZN[>j½4BYݽ~)*q3wO8k~k۴aBm+t`a |N{j"Tkﳻ3R!?0(Eέ̵Ԧ)s/m ,{ԭk`VWi}wz+&V*3ou:sľ:,3*zrm?rvP&uȘGH˪ :82&K&fLһܜfڐ!Z+Ke@fRNATfBU<]ӄFL%fps+pҌ)RYI1IuXV Z N.yifQN'{{@s7F7Roe> {9gUP޿~*QB3B0vZ`RC|BUgywP}N +_{)$ܹۛ˷ +"VUn=:cz̰Sz696;*Tʬ2~) ]}z} ^5ǼCɼ2 B_9ȭ{K6J(F*fPjl.4]ДlxsvwEӃ71RF!:wM]iR2]SCqVi~pc!W]Ra=EY ąSe~mywLKOU;;i1Te?kҶg }Sa ds릴ݲ]ĵg(D.áH;iOOa> b} +Tu:>`rd+K{ϙϙiQGpIf>2ܵ:OZ=o>3ƇT>o(C7_/SyT͛k{ 6RS (fsy=6|i4ywTK Qn>Psp=PPc= |"p@D'Q߄a[Pްi=sf=3.7*>=xЈz ˡx"lϫ<\(uckoęN2űoޤԍHE~KEoӷ9(lpm G{Γz54B3jFGF g!p yȹ6vWvsV^/=]}AI'hFH,ѻr@XR3DTzEæ$9w3')YAl (re #2&"%I#ܡZR N]uض.Ș}rjd#oj+,j;~ jvOy$ihTT3Me6*JRomݣA8/Bri %Sh0,yO0M|~i?Gn+ۊ-Sד([L9\B$&-GTRKO!᷊]ܗ~oߔEY"KxkFSu($ɀr6+iF"K\`Vkc4K~3ˠM`uٔe&x2K"Щ})_֗?$cL+Qsaڵtz߱ΟJn9_pheNmZ}], d bɓ[y/ԀH)[Q3yH?=T|@#-g/ߧ6뙱&eқYlxzwnH~J f|h]c uvS]f!zse7ȽExܰx5ǧ>,F[UtsǞ hiPԁ40p 1@de.,Ve҉pD_tKJA@\k1{KQPF-N詾t_ҔAizEZ9n:٨ Bm)m[jvtLֽ`ؽ,Vx +DZ{NDKɅP%{zozm&ٟv2QO{'  n#9QŴd:Fd5b~k8s_`+l7Ý3C3Uͳ֌GixV^LOyI@0~qejY6>#PN {G+֠|@ x Q6'g!+A/s)'+W7(A0@0HDܣm2kDҒ#mǖB.Fdms6(+:ͧiᴬL#"HDkt˔ϺM^c"iKhVh 94b}~ +NG ӜsSd!PEDTbٍX3+''\y P/CS4JBCEϬErO^ ]~C%EyԧDDcipiK1h&:K8=4* I4NDcx߅*3|?IMNְYyc|.PQe>K;)kk^~ʝrtrqBfגJe-Y/ggmt򬸊d j{BVP ] 9LwB)~:xƐ9o^Oй/\?U!3 "ag =,aʐʙ4wπ8L5j[X%ZTKT tpm8m@1i8=צdcbݶ϶:vBJe,]KPύsRQqfmu]~ S3}!wr27I~답迵35ǁ뜩`U gU3*m+p]pƲ-<-Y3~k7^; Z:5ֹrCGns6i,y qV)KךϘV#9sM;XsѪysUn@wݹJ!=s.#:tqY0ǣ j5z_K}(rm$MxV_Mi|'.,Mt>Anj?4%)}J MD4RzД ++hT UxnGS m)}4GSZI>P>~hJC,)-ˀGMgj ++Iny )a R{`څ?QMn#*m|Dݷ_Q8Ǝ2\J\TM#*+*YvqQ[ + +*( +GTPz +=GTxQ8X R}rsY?)ʃOTؼJWTl(GTM* +Z?Uԕ/^ǫ*>TU7-AU"xU?TnwQUJpMAԯ7(QjJ'^MMi}B(jJkUĴ0rȻF:y 2,E<~"v*Oύ͞A"G؈2kT1huC9Nމ̚QA\-GҠclv MkxUVjJ^gP8SyO5$Q_.e0C'1T47ifi"uwj6^bT 3wPWwO 3H4_Һ㠠(rתxm)m/t_ZzK <ɽ+oBp۟g1W!?gv>4Q͝=V@zinm ;R"sFnAULpv _y|oEh?eU endstream endobj 44 0 obj <>stream +Ht;;EW= +rgK2gYg>"$p¯վH֋ȶBkmnҀt8R HLO8^[,$MUm +qLe.˚,"e)pLyylA cj>={S"Dq$f029d,_/RvQH( r!B.͙{FL@<)ΠĈZ^;y2\͆Pb] T+Ck;UcT_W˩HٹȄ:fl*4ٰY|ETp= mSq(2Wu *\ud,8)Z: W(R2Ma@aJOUhw]ssFQ ŝB9oyeȺ>>oT)gH"}"jud;hDY56ZβPua2zI\Gk"zǹV:[:!g#eK4s_0^W˜ T\Ҝ!ll!aWvW8´>L4~̐# ^)><)gnۑ|O \q?ނ/4r%*!uۻ]g -&su瞂2,mVҬ7ޫXR͢Jg3NG\4SF᢬gGWR|k{˸X윣I1*˼zv5guڋ>!5k^W!~`!.P4::ct^&Erhz\t1{cqOhQ&" Xv׏A#e!_c^٠cs~h3,<[ +l51f7hV )HNr\ y)r:=ji \ҸzEZ +#\sgat̘QU|GMH2$gQf7g. p&nh2 :ҹKxpೝe*Ǻp2Ϗy.>[iŨŧ-7RޜFdkɃw \t,<#o|\hry[z~y\G{Tk8K8)me~PQ NJWw_b^]4jbUXOUHcFk͙ttyGNS_"n uz=E)H7Tԫo ʮ̺mg7gb3 džPY?OmVe)jpt6" +iĀ5D8qE߳ -sP=F.o|gK:I<}F|*ߨLsXd.ĩ> krOHp}9nJQOH[^\;j#XWw#Tʁ\1ﶲko9e"[E]^be1k@^H3cb0WDZWy*Vr jƣD%nlL$m eW䑪\8dr)$P7:udtWS^"CO>}mޗo69} žuuvţt6]L9Ur7?/gQ+7jXWϒ9Z +brA -[kS/Ì[E2j˚]靤t&D6|PkUAQE +S^("N*z:VENH}\S_"2?]q*(ݢHffE5#(7QS֦(ݢH8I BgOoQ-G?_գGw%<]=A5D'Ph !3k`?AbB (Q=3fƐۺ|zf՛%\,jb^cB5^ _7`?ޮJi*VL1u7d#X/B1! +3۞9Og5EtR 5 G:GJ| +f"fZ\WA*+ Z$H܃Zc]S3C]$g/hPG>$uKO]N{s1G= qz>>#M>z%U^ˊV{0fڒe(ܼYز-yvHj.A{b׸Y0rD^Qu΢xsz}+afUjOwΦȏ][2.tX؊_dJU&2 j yd@YM 'jΥ^lmSX몉}MhԹS=i"_[B^o0%!\ vR ZrX,Pi-TOei&EpsA9 Ը !mvTJAc +ת:LBs1bc ʗbPJCfZRpJW*Y.$~r1U={cFS}*TjbO]Bm *ɕo1% oם@e{@m ٥{rSX&[A=Q>cہUrϤK%s,7{sR"uPB7rː$IVս}mPhNBo%QN ?< i$$| N4<%ڣ#M vXO^\cFiEJzH $+Y"*Ej)cG֙3c&[]D8j)8Q5A}JS\N v %dX/a Mz,Έ5sj-bCir;G!qGaN88$w_(vduIj9hؿ?y3a_FgDne'˹+j9DW@O.hgtCWY;7_,w{ȶp12"E vl_spԫ59F0lTކ!S-UfیA@p txPN̻*CŲiEڏ]7>wl!욆#sJf9/,.W~ wqƮuy]| K{7/E0\C G(7u )әo F}JFG?^_ĻbP wug>+u'be7;RՀL),ѷ?PYju$;1[N%׺y 7׷ g6Pn7@3Pieo yMUCh~=Z#J/=\K7<_uV9 =N4^U|ݩ=-5vxPlǼ˼9S [۽uIi+2`%6 >[L|*&?]c fl3ȅzN!+ws#&4Ct = 49х5VyPj6.Eb+GVx!“Kd:*KosI\}[=G+$/E8F3JLʊ!_ZU4gY@CfO ARr 9]rnbDGq5M$j2 %'ln68%!JҴ]&k0lK N=4UHtaEuF!5:˱'o], +5$a9 o2SʊFqCg|{g"A<oYzqc(@'uE]UۯsY^Ѣ̫;Saf$IDdmUI~LU5^XMlyH+D7ӈ`R~(tԅlytm`}{{4!($ΐ51WWSA=dA-t#210q{טw1;f,Z':v9n9xN쮃!h]u# +& ; +i'dk"V?c;hZ-RMWHDֺBVAϽ8' v<qhT+z@Ky +-}@bx rl9jpoKC#֠[|'nRaCm +XYjU޶׮G橜C "v~ IGQOѽ`dt @>7uatTr 6Q3+!~ŢC1eC//M_fr9q8C][DU'm@9[ ac{ O5vGbhu>r]Uß7ƪQNK[F0*`MH^If2v)<-u5:`ˋbrتȷn +%M䭒Zloe[}f +v,lz_~WOscӾao,s9 9$3T?R{\SlW9v%9 JO+%Ɲ:"mX$@P4Ԙ šsn!9p'BOE +|"=J +)lvs!*3aAd0|+AF(ٴkAAKӟŃTm9#-نV8bUO",V,C5:2nZ*­sǣN .c"x%(k:"-JZyVx\:E"]̮Y:u怙NF]) 5~XNɓ{PS4[\]NiS2zNQ_t*"}[:%; A{`:}"Ci'Xk؞vd6u\ YgZk5gf.EsB>[cU(I^:{qu 2kPo917 'V>˚2*bWޟ)T7 ozA>(Re!KU n7,DY(UԒdH=o,A7l<"l7+0`-6[ @ΰhF*iܡJ::IL9%7kTشFL@ AHt;zዼE1 +իp=!’{ǀc3=zm5S)]) 'PFWeRz2*|0$ 5c'J,o#&MFz hIvYAdZuOW'd]5 M!wk$F} QOKzH*2{bf z u^ QM'YIZRaz"ӌ#5U,4V[$FʈJIt-=F8rќɵG-nAZp%+:)QӲ~%6\u'HBfTI[d?5ngp꽈Nt8%S0\JcPGW3!@قCyeI8Wt1qnjNBrNf/ wk(JCܡE^t(p4:fF6dv!}U  l8bvbrkqbpR5}b 2ʹq!bA* P01C$b$DZ*qU=2BL!+WX=B6&Bq׸Jo*3ā/B DJ4̮*VUGzTTwpTb\Q^JHJ(*YSK܃6W3N _U\ 3Pgj死2ujuyDI{N!ΪlyU+Oʰ6BW &.TΨ˰Z*1͸Jq*tKT*kٝ}ݍcHE.(;`A_w!˕l-L^Q3#wU= +E xy"a |1وbijƅF*}ZYpTu@iS@翊ԬO#o[I*x OѠf~!adnXUWX-@N7bOj`K~:{6Ak((AJ*t2yD`fAn$~cKɰӸR/5$n +):HAJ ;O4K"fR&zK%8y) MQ2FbiŠ%d%F(wNLH+S[ʰRF.:A=RG kbbv;AWnY@r7xc>XÍLhOcLfXDVX<zCBz&`ǀأr;V7 +WɦgZ䉺ȊLk +~5V`8iJd r+sXbmGѤ1pЁMBx7 F^clij]Ӄ"X\zA763viކ>}I%) wd2T/]~)VLVl h.˅}n4OLnLNYWqsކGoE p {0(D ,Fvx\- p:+j3pxFjHov.&N׺S&tH,:unz742p^#I/v2,ÞX_ĸktmbׇi`%vwxF ]EK7:TQ[d~^xe:+:-:)INxlXp_I0Bo[YI;i|Ry.s3nG~{΢]u +(ZZհG$ވBOvqhHU_lϐn gM՞ +Iu`IV ED ? -KʜKzhe`.A>MPi-X_ڤTeºԝQ.UlixUxρ˪Խ -dM\HCřOSꭒYRB\U*C؛ZiK ˒-!RZ>bgѝN/ŃS, kk:3bRæW|$yk|޷E,zq%t4٭dDG֡1t5ĄW%9N,h>%mM맜ltxc/G3Qfk(LKla`FG.{@ԷֵAspVu[VDt%4hGyUιl !5zE44zVع:evH+6$’<^Δgu +SRӒ,qTNS/7d[Z9q[$o}S#w*ؖCcκ>"3n\>X^2Oxv9H^.''%1Dl`@L)s#Ѝ)0 H@oZL_=r1 |ϩiоLÂY~4="vwX!ZXʲed7݄Ra|2 + zbȹeAmٗYcb:QѶ)&Hj r$aƹα_m:O{(ELu03_'t!n?*ɵW]pyf툒L`ňKD9fUF$ml-JlB|ccFxȗqM%7FhFs|DB)L㘢M" !?Sf%ȫn64SpQH)F$YM2 'os\qHL_IgM%7T$v 3>sl3M*ll y^} ם>swP08Ϥ3B@oY>o@8=s$n0˥0pn.9L%^GIՋe79`|ƒHN>Y:rOeщ;%{3߻a(M: &8R&ɚ4i)) u2Ev Z{9jt; +$/M#zwPIwh>%MU)E?_".9w*8[dvDU(9} +{CkK!j` ^EQC6%Rn3xH$UZ JWP ?l:.ۏ'GBZ +_u]/H w~3 +pwwdq΋r…K'jC5r8ʜc+XRMvnخn$± S,ILL5K<JXjFtϡfzoIBe*LcΊ@J?ŝہ4VX|3ɳ 3;P5Xf4˲ז&〮#?/kW_E): ꍛi:XحUhWNGZ6mlrڊGf[S9.tB :F"YhCxC]} Rimq:2Ct$/:AcFN}ޙg)<mS=?KT9l7AA;'OPl c7AAJ OPϨJYjd߲|1?3ā!s]UX@) m&5fޕ*g\dT)c)xL2ת8Ek,c>YNd~oKyS)$i-kriy_yy+_"찯|b_Sh@9}۟6xm[lş{p~__?I_.D~㷁 !#C[ <GGq + t5 Ź!zg) AH4Gh98-H'+:%@h,?GC GTн@6107h$(9Dţyahm;oSCT^yiS)2(+i>E"U/nATTF-0w++䝕3SCjPI!wsF`<8mI9E!o8,ٹtgopwGae.C\RX+P֓Se{z !tWׅЊ\TQ,͈ Xh88Dt} DbԇZ.L4w-[P+|Ȧ=Z:B䛿 +)]Kuqi3;v9g  +aE{qt̝|!jRgPzC8<+o ',n6 5sBuR]#j^]sQ2&I͞0 + -|}FO0LŀK*n W39!XǨ&0Ǜ?zN3G2I?v$ ]pc&Rx9Et&}y +E\r=5T$RΩZ*r%~t ]F v>?Z4tKKx2V$ߟ NuN2 0,k>Jwj ;j_`۳Tz>xpAmhY?TX`nJa'X 52 C+LbeZJEsy6 u&V}ʋ2U=5FRL.\7t>ϩOERv^h, +hl)tݙB_QS!Ej#˭, n]P+iTntO>]%ZZL@nZagf3eFlYQfL +u-pybgZ.!}I#% lFlYk^n,e;y3:ellt5\y}'ե5 $>1[oͧ R%S$l;͛Q wUs ~'VVfu'G$08F,/(d6\7kC8&+<= +vW<#4M~ +pqdwm,n +9/#rZl}9b?!,"|[^5%]^ReY13]&*h'#q-d&f!]4Z1ayĸީOь͉?j\nc4*`.!? eөS`ʫVBI$|xF +pOCFF-[Nm+O#3Ǽ_/FSZ߶g,B.Sq]K#"Ŵ!RKvylFuA萺,64戨j)E<(+fGS BbO&kiS{ ңЫjǯ}Pފ%'RUqb0Kф,w%%9$g?Nc:ud/m뙿Yμ#anH l3_>3䯤|&s *CA==;$!;qKqװn6W%tf%ڮin} y;>mmHLTl5;>%(d!@_U.jKrvovlkʿokPz6^Z NI5YH|6 iͪAqQ=r`SId[QI-U'V^c u#?n`fhFѡrzuBMjȅhPy \c e`oG7bӚޟ1z$b9U">nx#HN@_ ςXZoRB`{ʚ6q\21"~kiV6.ֆ# `CA2U/3_Wב +S-k-#hM~ͨŦ>-p>l9T<\$5~o3:mI$=ג,Ϻ蓲s)ϫYڠ֗ŚQ"A~ɢe1=Mr~k>@#i$\qjpyK驠cy5_qҍuJ1N0[*9뫵!tЂcLz;},3EHM'9s֨n:U8QslaaBP2|:ڡ}j}Jh@cO ^k/GW[ cK|"u}'(4Gŷ2G,o[eDKJf +rtcM5hAO)QD3W*,Z4O0|$gˡzH0`omacFR|7|QM;Tdf6 + f[++F꜖dKKO<&&A0%AJ5oI -mBzHuŽ[=_sń\ZKa AF}H \UKgui +~ﰣ6[luf%dsC,1'$;2Hf~j\2BuJk`RJ@zL?VWY~# +>mMu1tPl`ghI3\<QcYFv=^7PEH Ϊ\XBhډɘSLJOġK`}U/[ֻܚ SE+Oc%/6|=ZUF1fsQ+/>u۵PA>lv:dLG[B{}`VrՆh~ض YzTRP21`rӏR]U<Kо-l}١hK3nf},?l?EԓQҢpϡFLs8E(BunFz*x6ɝ/ o.Xh>XH()$@F;+a&_=3-B]00J RY1Ym$00^th1Œcҝwg"g⻴}J:Pv]3_C?`GGSc9)Fm5iݥE5aFG'䥆qn3˃[H/I@rA>6<f%%5]AKYa+JSEuiU3q[b=;/&#Ӛrw ᓎr5//ĬTau*D[NQV1'D fת}IU=RLܣHi5{6+W Wz v>n/%DY?^yΥHlIj=ygi/a=W-0uخ7:̸^91bs/l̗kt.&H">G=R>Gz}rυ# !$LE@"WkD+BO ;\9~Ǻ5OG-{%RU.ɸ3ygB?mE-Eu!,9CДJ]=ݥ%$'eC+snC]f}B?؝Vg])3Ҩq#5EL/`2Y+e $YR.ʯS^}Zy| +)۵~Ÿ+c;Y_T,sDj7E !7=qI`,{|K>.>Wk /Wi\֓s[j_20DTz*4*y>Eo7?Y0ΙKxa ˥/EρZd> +`vOğ%B~jV(mB#0#5\rԃDSbD(Vvq[/xpR!d`F +k8FF>?5z,.$PUXF޿{#ijdN(id!>jIհT,Z0Ig"[K2bkI1)sinfqX̲V.=64wD :lAs[Hg5[$q*"`ptH@Pp ]Ż!(GN9tQmpG\v/K-7jfz[3E"D;A,V(JLMK#'\D!xTLkmKC``,q+4%QaY`[zNg s jEV#lXF"wʏiH8z`$ a=8Al:`Cž vIoDTKp}$]o_^;/#>|MXm3]R#sSYPpYOAt튶C)Hݷ?˿>{\x<c=bV ,C0!#{ IDn#!tl9  [9t| NƸ%Z#`DmpjNcS;HO<ŷ1h昗udTA6$ i 邴uwIj#$,TT +UAS aIhc%Zh]L{匊.f>̲ ؓU:_h?[cU9L +bw, rLS̤i'sp.9Fr- ÷Yug6f9Z HK[^QZ!c>}4?a: S$|wb:ܣ酏x +}3lU*_Q7s+>~/~B|dk?<0v=>?, пc +av2b>ˆn(4 <|?qh>ǀ7wE<"V3VTGUvE!|F_& +zz$|^ʙ6ɣV F[FZ +shUoTb65}N\E][:"+2}6`T UX jjk× 0xD+d%Add"Pr..2Y;*@0յՃ 7#J WВץ5pvŪ:<pgQ +/'Ar- B#g +>H*gQ@Q4Z+ +S"f,-:G`.+=(i/-.,-˟j32rz՞Ir10[^Ɵ3uč+tY`l I(o\$鉳ɸ<6`#@FLO<|X~2jnu{,Ŵ%ooHuނ0qxUF] |=ooGNL#VùF= +eK垲kXF>T366UX끂&}MNqY>Dx܋oǍPIwֺv/ƒa֕.2Zj)C"Pn-xr1pG':GKf!:sk}-ȊR\><cbY!gsN:UP+im޼:~`w- +J~g\tJ82C'Lh7*牛^8vf K81`D+jfi}yV|Sfm1[T|SYyL0?i]!e XUTۍ5E,,%]}XrCTl_- scҚ[ Nh`b\WA~'ڥu5!m{ .wDs"n9$ltUJU܃m;*D fa; 9!pBʯ}^-gjtL U,*/O}r3{ # fhIXGfv ;gմ6 +t>5{8Oqew-SZB!&uC^9T%Z:z\_YXTTuXn?Րd@YĴ!{gVP/oŠq_!:!wjv4l)%33b(w2N pOF^--+,.-ohx6@ϫh$8Ha.J#ܻx]mNo>T4SūkׇbhΉfu s-B+<#]lL.@KuHжAMW??u]Ovԏ1 +^]Z>Pgs]lݦs!d냭3(Rq!XVOjBPawŋշEH-󍉑vF<j3A=wȋB>Tyo7Б˕CbYfM-zEGzJ=d/.Ugs``0qS\CnMа16LMPZB m *-RIUݵJuKBp(fդaӚj4s:4tI\MW7*J_X!Q0¢BtO~H0;={E~ }Qے0ڊ_ll~^ 5]TJGSpJĕ]3+Uxf`}'gdr;fU7_\4" +K7}+~u=(. CUUjzPq*TB;{$^qs +X{httu*qTb&yf11wPbBuuf$a5ْΫ's-˅"Rri]gR@*DqEx͍ y&d.|e=qhAݩG!Vk85u2PSb/saZ  Jp,)kNݾ*qއA+l*dzEjj~*uҕhb*yN +9?#!][ *؀6Aəʒo*\ne)^l.EX\h&/G%`OBT6Ad5X@\-_x4Rs}3N>\5L!jUcXYЦ"շg;mi?;ʗLM&#~@T))ﮏٰ)K QCgK↝~xk_Sq=?Bc'4p]UW˭W,QkOˠBm:F@#Sl֗&{vXVp4,VCjJ509$?8(X~Ȗݛ`ڇ3ьdGb-d{j+vd5vJ7K4IxAņ0[*Y9rqn.xs9̒MxQ N'5*WC VXc5 )K"5`և1y Dš[WW'rY6Aet`q'q@NYѱ!IiS$Z'5{*7>V|@m((yO+;"A]>9s7.z5#iQgf$?9ќbSwe%B=u!#6)csP-$+ FkuO9\ܳgʵ$z.N[ Wz&J4+ JɐK 0^H('ve ;ZӲW5ul/g endstream endobj 45 0 obj <>stream +HtW͎ |y!$6=;%;G?xPӔ(X,w|sg~y0/0|q6 KкZ_k^9~|ChJvM¦_=9‚(.k} K1wc<=C~W*_"кz^yt7%2V9 KȾcҦuȥHqL)>[Uصu,ik32/3g%׵m&#CKW˜r&6b1HZ` 6=hx1y {ZKJ0 Oӯyy=tS<Ӯȏ~A>*\- sAʇe*`G݂g]Nh7WFjqO˯Ahőaz>sňɯEW'r6e|yYJБ3v-OCrAhvHi pXIQՃUE_{j5ZYA>!Ljri$6k?Q.EvG&f'tc뻅ȭD';V4l`\OyYPYߨ+ZrD EsFkЅzt$'tUPl+cuj?*:DU0]Y0 -<z'KTWRڴEы.,֎2R#*(RQ@2lrTH=Z8}&9ӱDM':Z5jQx13Yɡ):GX~8B^Zj=Z<"H9JyquӞy@'T#=jǩ=dhYE"qlYRcn Ch;G>*ȭM5g)q@r\p(PM#nT>B}UTc)ݝ NG@<3ό*6=iog4nXA5E/܂2Bs# '2Z5C˶dcQFcQ2,lc5n nĜ!+]5cLo:jA`9 tBIf>KLp6se{0VkOkŃeJ~e6lIa\NieJ9F[LCf ,ԍNRfYfK ^׉= sۅN\ձh3& {>_qrv3a ÔsrS޻"bI`oe ̮n/&jkePح&tf\ib BG-v{OvqzreN~ +,jH iq +ͣ.QA9SԼ %c$|'#hQ00^%11P8'U8c׾\F, K&4Y *8zսj( BWV)溑8G֊nq-jX¹c%$YHKDˡoaQ4p5W^ʡ~Hh'6ou ;oX/lڣ6뵅"A5 *tsfi4MF,%ެ?Oߟ~O=P0rWoL RC(A"ο)dͬ,_}c|rESj 7n].ٴ{f=L^vHo?$Wԑ$|juq}݌ԌI9 *r&V[.6ZY*P8<0؁Δ1.ŏ|P slr 4]JG@w9vfav<-q4f^'19tA)s]@[r4+;{'@Yj. ö uU@S5{m|@VL;wMSx7rz3 ++⧝?/W4x܍4x%FNInʖ쨒:qV*țk(;K%B} $ujmq$I q/$ qؘV^T(QE׿Cx)'{F?ëEؤFiTɔEv._WR~] :l3ĉ!YVO, w&dL{lmjS̆ܐDU6>jZfɇB'VT OMvi thL2%@wwfق4#t" z2 p2̅VڮT q$!6V8l= 2ݙ+F,el:0_g!d)ZQIVoIhrrK9kAkYc.֍T3D84Xo%wp&9` rƂf u5ļРIp0<PlU lf96`R0Ӷu^ٲ^>V{f& YJtpjnckI+oc]%R͡5!{قI2 8[L1liS,mL~m}]IA^|tʪڙm 5c /WsU-\" U7RÞzICsF?䷮zt2j+k1{{:׍ +O0yF 1 +5,4xA6we_adzK¬~ʡ'ZHO/NFAP䍈IvŽz0rh6 Cr =?"2!{\Xڔp޳¿" +en'Ec dv13xȬƭ1j5+j6SW ̇Ga-" /iQ7C9a` /wIĘRYG=F/z{!!7,z(dsL)mCʁ:/cs"ؽͷrpn6SZֆս [VNgD4T$"MzYnh2h~ô١i[/!9͍UcjnY;Lh}=m%㞴NaȣM'E g5u ?B!lUs|O˂.3h,gnI8dpk͐N 3ƏYfA"[!3;T"ZtZ'*͡(v*pNDK,C7zLSuy]12bME_Bǽ/F;lFA +ZRsrcE2 +`x-WX5ɒ ET8n@g"@N.ەph +N;7yl{ITivB/hH,#!Ml`qnLcw. Y5iNnKJtXqhŜ gҔ9ў˄i6Y35W*t +ⵦu:a^8V g.ȡ{ +pcܼ>mpT 3$MעB{ՠHD*1xbs `4LubGf&G_ i?wQv{ ~.Og]p?%{973M\Lt HPT*Cf]^\8SblEP#5skL07q(&4P|ϔPF2K=,3:_#TV}Hc##CG'G>LV/@6I[<,G<}K<^ xԼ+(xA xFxh&q1*>#ޭ\d,“G;"c{UpR$+BNHkr$U#$*zONs\N(IVo& 5hTYV3_w9sY~(=C] Rn#PYr0ڊ*M'^1†4P3G40h!0v cjaA+0hkkw} wV?i1>_s@7OL}vE?i8nIl#ui>?Cܓn7x6[+Ӽ;y"b]pEDV&jfjusaͦsu 7[o<\?vJ,Ku؎oi_ Df" nd)tNe'k *F{:;{&-!C=kv3ǜWf8ʌ,hu*& f . +Dz'%ncWmidk0\ٻ>_U.,T}nd*@BR9Ze0' +^,L`0]%@,rXF;M]mhj $ +eWS= +*vlDAνV KMt7O(|j`Г +\?@4ȅCsVj:uLofWb̾\cw,=(?AreғC\^NÉcY͑=TVݿ*ȷw|?s[2"q@-9$A5´\^06rvwlz +5?+ۧyw/"QWث3n<*xuӾ9_}j.yCLS'"ON/> s4iK)lrcSe1lQ(.T@B#|(g~pId M#뒍-@J9񑊂t [L7M\[ɎGjl3F$7"he nʡ`J@}`Gdgx"kun~v27k@f\1@ybo7Vh ['#Ȅmɍȟu9yI> /0.PD+dU\ʼn5O eO*@'18=ք㹕N@]6 e~Vtd@dm3TtЕ6"(g2>yK~ޭ/@Pö3}dAsgc(V3 H_fs|NxRr# HY+ÉfTUZ:>WP?=¼2b!Lg}`7`(kw=4!yU-{8ΊrJJ{#9$,54߷f+\Pգ-f-rw*kp4޳>&>  poY,nMqGJoݲL@ +e؜NxmlUXP`nDGs_0ҋk?A lY4GKdw mmIy͓7w|$4N]y-J0 ˔ +кԗIpdaٚټfG8V>e $iZdlߺ}=I4-d0߱GS]yV olR@*t4Z z b[[˪ɏyb=2M 8X?%4RRLna3;׭- KI NEDžg'Wcv ߒM#7u:MUQ'Ezsj5{e/"R͕KֱsvQ!/L! +mMbM7ht9YAxn2pv-z(dh{k<>AVT|jȮ$A"*Qo&O>)2 #۵ʽVȘrscs#D<:4AV[R)`btC Оo=+XrW6i$ yyO/:DLҼ%5^E{6N'M?-z1<в'M$ߘ哛뙧>:$pm~)Wg˱L6I$7_ 0ӄA?rǪTN !98濽UУ>⠽wVg?𝒷ADغw92m|/i!n|1>/|ْ)Yہ~Rۅ&>=',.|@~/Q} S]E&l xO5ESK7EJOi+mg<N<%Gul~?/q5YvϟJ~wmq?\w/>qq9=տ YFMZR7FBq-v/S/+87 ]נ Dԩs^S?򊏫(RnU h@=)]EѝƼ\Z*rHc*J(F/WQ] Jb*y].W~]Ev#Up$*ݮet +ӢPSQT>/SQSF^*MRm2*c*{_@2c*]iF!y +e*p$OEx#Zr)%@.EeI\ +aE& 0B5;g|AiiBωbkhhܐl;Csu= ,1'@zN,#]j{54b̭11R8H=_9 @R|."y݆Ϗ:d_$$$y D֊_ $܉M"M!I~Vx!]Vꖋ[9]AֽOϋV 6Dߜ& vlmZUP/f +4//`ӉpwJm5D=/f?@ʰy1R悴u-ÿV&f!dkh3;`[%>" o笇-H^k{?BӪm8+LEs,A^ OӰ>ְ(佻4FDv jYc\K*EEy'9ȁ"ĢkBSR)3ZDdW({x6]mu5/h/>bbVr`'JPJ]PT"<+&OE:,q$Ur|3$14S(%#Ĺ)L$_qqIfww=.\֣ќ0"~~K/$g{Gِ6cCT, }KC  k EAju@Eč5-Ě'M:>CPB1ev(˴^YkfUO'@zSP26+,.U>`FHh+K?@Ow;}\=⒙ g9[*ƳEvhuԵZH;$kX}> +/=ZEH-@m`Q 5z͏y:k"xMd%YhJ}+ e| + ^d,~#K̚t)RL.cjL#Fڙc{=8"}e($ r钹y\\;XsjHHăhK^%Zy9[,&Y=^ɚe69V0mu\8&UXY̟b8a2һ=KP͸нuWn=ޅ ( ,cz'H@2T"A4*̬c<5ZK{yDsnVRϩ;2)!ta05߽ZuEw9NJ:J`#tNpqǃO/{/UAN.*)IM)NfƱ}3{uؚ%J +5' 0hL~Gx) *-f ,`h'>^\j3P8 BXO(H3stf9ֵa}UobL*;\zu$q+ {zH&^ߙD=И7S0IGh)Қr,c +0DWe2 ߣzahD1d# %qTЬcl_2xr+zUgCn[[+16I+wJ_kC+/&G5D2: ܿXNOGe:z _UΛ$*![RL' :q~'\HfmUP !i{.*eu-#&Z +TÜ+/qd&~j2^:W+8EZJmG2im$Cw3B;]ӰHml)Y#>DqE fȽΫbFT40Q&Gܥ^+L٘Z/gfT(m+u;eAiP;qh#<̘8W5V|lݲ ~>Ql{̊ܛ"{I}gМusYtW͙-+`rǐl2u^iuQF%0)T߈=/&2Lv` h v%YS >uϫ|?9؂uY\kTx/X5Ϋp%V+F!ʘ a$7Jlc#hP۞`/TsBMm\X1+Q Ƙ))Ͻсͨ,1#JsO.FUb$RZ\/t@f_YOb:XUkP (]=jlqxMՒK{WeGJȥӲ4K:ҳhYYU_|cjBcJn*c6EAFCNP54ƕn$9Ց*QuCrץLBA8B}rdp YYկQN fjxfruՄ8~1&ca6Y7fʙc';KT#ɩ%2!AK!IҏFrK-zU/kmsȕKj !kilČ*-וr" Zk|N"yh- ӕ SRFMw0=c%JK x1u3!͈#HFD˴4y3"dư.ky1"7#>!]ތpPKJ_7#|,/J8P"QKʑuɆ}(l7ȕ:>M D))qM n{kn_C}>CKy i-,kLLaGz(k(飕Ba)J:|56y7U72JnέkGE[]]y5ЁHyc _!=!3[&&_C2 Ft=$Ìp=l-\*P 8 x89*G8$&\>A n #'^/q+>@|8`% uJ:/[uGe4mGwB,r#cyeٕ/{>ꮥ{oz_Isaif_(]CCR6KQfZ-PRaus`G08Ҧ5-WMI¡b]ݧF|;A}T?_ZRˈ(kDtmMVW/w<Ԫ4RR«d.TH1aJ+PhhYٸ< gKy=n-4 +6߇.p,;EY/c. ^LA)u ـC-BѻI)v' Kͥ jR*JRZg$l\ș"-0AvdTP92݈H}&׭^/Q8CnN"8ClShRXJڔ7ncuuڌSB6 +Ōpew{M/93agHYC261>dU|7ZPS5aDºsJb(5,$^xֻ|A8ARW}ZFgw& +_zճK95y)[DYwy#ϺG+GiPԝgP nQ490$0}2D='*8y /TO{ݷz쯾wwqnbfE]nvq_ /j}U{w{ɭģ;= fa0mpE2y'HUv*KP\Cf0zg|9)Rc",ll4z&}Qj~1BA݂2}Jܢ`PхAFp3*U&y:8JNfHC9r%>w@T؈JOGbm5s퀞 Q6OE$\ Vh` +}{o ZZZ_ zE$:EPbfowːs'/G#hT^8az=%o9k |_!awS|\ `JTO]s"azUF|iJttդW/Ik&:MjX og'|*A)Ra(^KQB9qjI,aWt`{m#نg2ز,5w:b:=zҀhs 4lfe߂vxs[&ho2<+#R-Чl@kPh6D(9w9#JdKsn.$9t9ڦcgGc_sHYǥ=8 +8Vs_A$۵ $gk=ƦwMfoI=Í!N BrO *Iۋr(nsuOE[A23U8iT& k4RQWA[RT  Uvl$[jx6Ϙ)/BUĬ{^Ej΁~cݎClN0Z lq<(i]*t@hIĠRz46CG~U1&~ƀy?y[/(l#Btqs;v($pD.~,ܱ3l R.O)FAFIM+iÔ2̣1 +bN K2+K4>^ `n=yZU:'v i2uPќ1'[I-}sK RhP0fPAPG`@t+&L(4uHzFiPLIEoW:(V] `*0BE1eukcKw,;NUfZe#w jw#vE 3/(2˵5:/;H`Ǝuz1uT6(tW# +]Oá:@^B){퀴(t=uj(te=1:r9 P.u{K9@2gu^uI^wG˭s +r<:wtiCyt#:7@s&/k]WfMM˱7JaN,8kJmk|:up94TW9z[G쫳$1Ә>My: e/XN#y"\k +7賛AeڇgRK nOǦ1_MefyȊ-)ݭdwk-;|vu)6ސzv*vńm5Ie?hLOcQ{}4{k=q(IQI-73>ìd̛NcDc(߮%踳ڈt{VrZ܂v•ҽu w@,][+}L_۲˭}:[ A[ln>L6tTNbz^ c@F>@4%”j;9z74 + +3ciog(dvQ-|7Chq%AޭN:=j߄ {N Yb]-9z+H u{ +<_Ӻ~b L)M*85!痑&.3伈}1C8d:E Zl|d7!꿿e϶$eL>Xe~.bӨCz\2ru4ڬXKv@{THVAWQir!y4<hߒisXGε oxRa>5.*ǒmŁ+=$s.ڿۡ8\ +7 Jわ q( yUVT$jcB요@@x| +Dp_ J-2!]r8"wl +D8e,\$1!,\QX ͗^µm=G~l,H@v|DQT; 0Yh@@Vxy˅^@(.; Ԇ؇U+iYۈXLgHhvlYY|!`Ax0*46! ,(VRw/j ЂeGxP` >mPI-هCBLN93!}DXB552nn1sDg'8,#wx]Y GCxz!j_ m68-zӐO`ȪYB\P4rm_0"nGm u>`آnʽ~K=O}s]2%~VtF+٨ѼmcܢAn.U[M;1δK<&b6YnGؗ(4yõȺԱ˪W$ c/>IU2v#zzNfUH9 H#'ջ\=a &RipRXPnvn / <9`T)le@d.翂azx-GC|y? UbyvXozW7p#3ehPK|p@ˈ)5#֩86^9U[?@/x_.#eG/aH@bw/cƭDj`&M"4)`j"؍ܾo"*xľf}Ɗ}/s }/q@Ot*CkTN.NJ2c?(@k}M\~~4ĶV@QjfXt!ؑ1}Y 9 ۘ E? CqljaG-,0AIAd`56'%09`Z"b ΩVkjh>toeT˻uCYݍ<Qպ)b>*#T2EB{[XԓoBLrU/;./$V7hMOF}CER9UɅi45bW^ Ro-C{3h4zpՔJzF3O=c\,>5R᪋d=iQ2cogs7bn(JHj$[sI5 +I}iYd5!B3u-,YuqZ<95k~?JKDx9_̤9}#6ae-eZPC㽔}Y +I(THYLmݖWۂ+J.9XjރЋ2y&|j#}ʴ,Ѿ!εЩކUjj M?¹K'=P%3DdfWJzfк2^Z݋K(A!KRErI`?&y`AHqf/X,"u,T 8%T־dkTQF_(]XK,dm@~DA+3BPO6̂u'*_cbQIYP/r|h`%\9rH?>3dQ0WIđc9Y9#M} D{;y1Pnmm A^BLj9+O#ZfmE /"yF/C|oojZmiACŬ!òa>~Kޛ,#O)V!:ӟ)E!w9'ʮmeTg!v7mщ{-m;$RC +_@Bq< Vq_yP~'xD>ݫOm#xAl nU+IU֚.#ˍk +@;qia& 9!/ic[P<m=ݕ,Vb|*A`Y*GM>mK'`i3`juR^@4캒r1Krv >5]e m2 v!rAn+yzoT! ~ _oVHΜٮOP-lDr@5$\xXʃ0˒*S.x6Ur˼RJJxK̋V(fL,O#y8?/ 3)IЦcJ2L`S+@m8$MwVv 6C.2{dP@e Ct>-@#9eat45|s +PL j|AWnFYx~ôO*I)56 Gq ٛL_i뜯%n5|POi`~xA{дx03(hu[>9_{zA[@TgP#-6At RDR<ԭ +Pηb\PDQ@EhGa[@)Vs,L^Q6b$3mץv!(͉p XT#9'HoFpO~J?FoP\f*[gf +AM}ulxnDjF y< 2T1"[6Ժ8y +RfMQT%ewsۓ%XjŧӇTJdPk;sJmh5-vx&NLːh&2 2SivJ卄N@Z+"N 7 m +2^ RSO%1.'2 endstream endobj 46 0 obj <>stream +HWn~ s$9NZ`i$Zބ\9Kqp@ ̹_.NTR̞<9zbDŋr :x}($N^"mG|ಹ׺;8n7G'N.O^\ŷUdzVo@%Si*%>*}^š&`[iR#%RDpu +Eq]L!ާ +K6F|Ϸ\Ye?鲞2yl`ހi7vx]mCxͺs͋fv`.\N:{4\ń/k/W1:$unUd璫tQUfuDF+'1|X)+JBȀQ 6]p,^]S|2lJX+e.'fxӵ2Ew!f͘ݑ% /ͰpqtwGʢR J9)eBc!+Ӥ"'s},3EGC/?Bw=*v#@<4?,P.9iRP߽o יG-ûvwWoe^BPG0/Mzevл[ ~;S"ļ_m~wH}51u7hK=w<-z,R3)N< |ďg@⇟Xd׳#T,ّI?a]/k 1L~1H_2c62f"X ފzH*2C`8#!O LbWڤSVNnUԖ6* >1ln)Y;+H=|ǀbCj3ypzz2Dzߌ +ϨEBd3ZmƂ"L{&'P{' 6 q'c0aĉh{GUN|քToٓt*E2$HC#6y GP0w@\t*jî-ØmlX4^r0,٠dcerC"gτ,h`1=k^ ) +Zd?ةo!ҕ \7dW@)[* +h,2jL)J /EC\?&'Xb;ü/b㸜.M lik +XU|(vY@=/~F)|"eI r4a"ڨ iJMjE]0޹iXBG?j* WA s 2\ d&-B% rC"kȳBTٳAֱ$<` JWR`CvDs 4Rĺyɨ 򴛄V#Rv:)Z4'iRTg*O #!*(YH_}?gJM2\t̖L#[ գ [rAy*igJ2YA +DM=?zԎ7$Ǵܛ HfI#鐵Xڔ&PfEİ0C7:-10c],7D7!(#Z7@$+sqxh.3-E-&c٤5ļM "k$ޚ ;1p;tGsbPY|=(M<^L4^wT—cyFHGh)aro(/ٸ~:?dz501r@ l#?\KK e=kdiM"Z8<6IM`jA=DʃzO 4c n Tj!$ ^12+#YO#5Z1HKUvA(Kc~ô1B +L]R+HY5#ˍ-p-06NMP,s7gA0b#ssV]P@z^¼&#I g\ /v/ %3AOcbNMo_y7,].pfhCKS^Zb3ay,& u$$,vct,ɉ74kQhM`a*/ i31_-7 ۸L9bcЕM:vءL1؋/ " gq"y,Sm}N_mm#I | M6o'_6Ac{; M,RËco5l*;Rc&FY.砑3GcԂ< y]LAamv]S0Eg,h nܧv5J]uGtXm @"3"4|MTV>*[~pGlvSE*,=O}XzGmD*ٚ- #HqF K?!bjū0Ág-P0C}Hc7+sgnYPvtf"!pwf6gz:U ؁z qzz&|3vnk 3*D*Bsn"hsUC"+]<صըVkNPmlon`t!x2bj{J'cQHG 6,GFhҲJ1ֆeG(s#]|88Aj<0Ԭcb,4Fs+ +:^\-B;.&(%Bjzl}nm\ 9h5ߒ;(ӖyٌpۄwTwuEFg n}$G]ka @ə_܅ f%!k3*bV:m*#B#3ԝ8^1+WG#pRm ӗ9xA-I p$ 'c?u+gh(2LGmtڽ,3MXBwԁ?;Ϙ6 Ev. 7swC/P4:օ;;WE5Q*>haQ$q(+￶."ɮ8'J(o3F:oMܨ'\j֊+XCf4p^Fmd+rO@fat6ރiY{/l pz|u:~{6<*r*Ydx$lμ)D-~ w_j-?֩P~>EV0#Mhi{Ex<蘘Z0&ypfWw}5 }iwrh4P(NNo̼u`3=,E;%DJ mQV)4;wz/ lbv0];h<14 +t=ezg@T6Ttf?]|~.IA+tTεxkM aU]R*ty!y$e:UUgA)Kb0yui=vTMTMT}1%㘮H 2ɰѠwer=Ȑ1~zWF ;4gHd\u6؎%]>C4j&V%F@ԗ)YU,ļO!:wq_9,*^2g2I%άCՓ@=خD)[ =I_NQ&#@@䔗qtOBE-S+/.b7$z5Z I~# Qں8eRQgА>8#NNѦ={8pz'Nޚylc;S{;S{f~>-{|k: wT$D/!؛%0)1k"=Xl ҁ)@ +Y)}f&r i^܌4n±5j[n@ 2pHo05CSlM~>ڠ>"Dz'%y'1_mɬmOB^JxLU6ޗI*zThY=9Ir d#+fڕ(B~eνSk[IuqUܠ;*)}w'_-q[Gnr~lfHtw<Y& ʸ 2W +rRm$M*b9Yu*n6hM\uMȶ̏W6+uOo/5ۋkM38OԌMwϨYGH6eDY Om"T@t7w2}B.a)9)ڹ/=* Lz괄\gG^9gXuGr,".d<0*QZʑolȼ|Wob:ݹwjmK.,&2,czx%׹v qflnHtw<Y& ʸ 2W +rRm$M*b9Yu*n6hM\uMȶ{'eߚEFwyqjǦ̻gTV{z#d$2'6* қ;^e(sǚTRepFz +W~>\>Nz;8r% !O YRL5D,yd?) +`@~n_,.'eFyrA"hKEg^ߑ ǣ{sg8D-sǠI)н 4\|PU,A-iKo$N^/igICwIZ'i-,ʧt>([ia53jui/i[ےF4"g[,QUHZ'Ns +:T7}R`.:UZI#$ + +5)<'r,WQFe N8cل>[)@'1¢H' +M,kL^~gRvW;U2qF&$,ߐ;4zMl#\#rPH eݢ5AAD<._-#8g;6J8=A"8dWkdlpBxI4s:SBp4Q>dR606??!8.XV]xx +_Zn_6mqi i 7:vƶ;lȄJ%9(%~V"k +2e,3H{IѢ%krd`-g-p(OeLK/WW@TسMicCch;X7]/EuP7A[nL#c|E 2"1OF2;bzw;Cgo}эnH<  f2Ewsrd`-g-p(V ruTO=TbP]u:]TUkx->Q +1:J ܔ]!whk.5Q^f#.a7쏽Wmxp@&H(x9=󸒵| (rr8]Bp2!fRN\US % 5pO ѐ}yy~,a3+rDYH(Lx!oFZqV?[h,1 2exp#,P\3p 4V3)0'(Ӫ"^rHX=T.8RXKa#'W^{",FNp;\`8[oTrߧ'Q~l&a&V[LPd_J}|/=#4PuM5Om1r'H endstream endobj 47 0 obj <>stream +Ht9rd-Owh7*1 1ȜO.+}^4 ckF Ɇl/Dт~7߿߯_~ՔkpNڠ|iY{)H$Y6Jq˸unP!(0E'$;RŪ uYme|AS.Q:B(s \() +Z>f!f/DT&M%WܜW{0=,=er$ +s1̈BDzYl4=ִuŔ_Ll9l2 a׺+M LTغᴢ_BbWSvi$,UXeZj-}<&HbTlJhX@s(l7(yFyU;׈^SHĞ 0ژe,1:k:@`6!lC3Ĕl p:*j[>MW@w9:b83a4ӂaHby ߠ^id$b(יop QD7A*$~?GI>/JЏw$o|t|3j,fBm$xি<W>5o×Zwo\ȿ +dKOx4tj qzDQ +'Bu"i +T%BeUUlީgZ}ϲVDi@VɅN+3`^MBQMTGS7Mce!!.YFzcRW[|KU/w+V)uJ|4H5um_@ӡwC8zׄ}!hZ95s\s\>y2)\Ѐ^8x$6~P-pç&/~y\0uiaB5ٸOW7 $:P0]hBG;j&i>Q"7;:xu {xT[7{`99xC,!bhj!:UbR/rXc׹GuVqwżj 8-| $Kaa8L |V/co =UKeC~b",>Ȩ{e LF3ZI7c^:'F)0*mi]հ:f7kI'Č7'ȸ>]-(,Dv?RUnk&Ә>-lsDխJ `K4,?9y,trnhӡ +orgtu]El5u*MYu\DZFЛ/e6`EfD36;"Pzǀ̭wJ1Mzoskr]'oE)\Wx*A2zy"U"^$%whU3Sfmj͸Kgkt!jG[10!ԤPb*X=mm^T~ir\߿+N[4f"FC)7 cuD]ڞyZЊkktƖ(/*fӟZx}S{_q>AX|9*TEw=I}&GY_Us`<+iȚgY[W69wb,x%RAUgh'i!\(J5ldJnTm@Vd A{kT|%JIZh{l_~`!ҺE ӑֻO6)vF C*:WP݃Dc>1 A +:m[; Im UrBg7<r[] Jz4Ipzza*Zeltrܐl>e8Gڰˤ^Pm!MM,bnCqel@RUϖD~bp$i*5ҍi8@ },gTD2-NpxBUk}gb |sE{Nϑ>-ķuRDMﱳy 9KhmnV ̧|m _atZ~j<ʞ դAv(oG2Lf<89,UǹYud4p/酪^QSm9@bϖZ@UU@6FjlQsީd9Eq22ߤߵ*HTe%e67,j+jΩ]{C@z ]uux@vS~nFFRS5Z(ɸ4u\t&?֓1NuV.bc8Ech,(6ӣ垫~~6B:$L1:2T}UѤ$S_Ia,(yl3zZ $z0Ǜ GlTD촞eѡ1&5X 0nVrM[v$ƲuДC6LP&`9l{ݝ"GĜIE']M'kOPz>:i j(PmZ9NuWh6dv5z]tI9{t- +39t+i.xRsbn.oiq2*1p_yln+35` ,Sƶ5\9&E2F%54'/ V ic>ӳUݸ~Lwa Ej]w}{ڿZ^:D%P!3BZ`z]]ZmC}O~[ǟD1SeT h嶺Fo b2bLzyͪuNlcQYj5/cՠ&2\V'r˜pTZ2JCcŸ_cf,Vq[=OmIMia]Aƿș`.iՐ$M*e'xTjeg6QL(JEq GL&Ш ɳB+w{3Dp>? V'uWWɜ^oscm Fmb䚱lfiK1{׉"獝\x J0Ҫ"1m/fuml@HLIƒL]%3xLz0˺GQ#O?GF\Zj7ĜD, 6Oz'[e\e +Oj;~Oj-cGuFmJ)de)"TOpu QT(bD`0bD@5Rd%Ax>m +pRҚ C3) 1cdlC"Q]rݢ& X4cs b85]D<`'`Os&Fmaejjawiv,z(ULTl^}%gQ4rAFAIC0]F,H.\vcf3GpkQ2lU;"@ -(Mo$bm*Y{"~ڴyJȼ /f95jƘHۤn0 4s[hRgšuki:nb-#/2#7 ?I%UU\9^Ljt:GG(*{Q٘2\h!G?n>DT6O\ s0lǘU!h۹HX-jP~h~" ]dmi԰Cba螘]Xv%G +V0r獈@R4Vj6y(zf&{ѕ ݶa"#`id؊uoUhTt(R.-X P)oJ~z7#=>*wJW^'9Q;ub1cbw Ԃ7JKq{N~Ngң + SS\ +96݋Nڳ׷JưE"#Ы0Ok +6큶aE} i&5D Jm;];2eƭi.~N_%h=q +ZCWQ!GTO!i5G4C:JpyЭ|+E@QSh~,ܵI <`i1u,Q (2KtUM5x !۫~zZo~tQ(P|'I{̤#K Z:YKZ$ˌlG= I.q@.=5glD\m֡Ggoiw j}g5 +[W{>g{f|-ܢ(2HwSj]찠)r:~>dh6gftuRӡ/RKH(ڳ~} f}E3y^r cMT&n8_=}N'Yyg>sB/#؇.ʑH=:M,h7]A |Je[,=2)M+Rѡ!BE: ~;t@JoS?&I8jkQYo祣9}jOWNږ2)4z{^/=|% +PQ \4U[(KŘ3B7($<;!D]vI_}ty_J"kI,fygr)gGh@ϔ + +?c.J-'vBoF0?p'KD=L~hO +*Q FjrOD4H ?X(ݍF`%#T6id2o2Dhk2}?o (2cJA:u%Pl3Vj)ᮮ. 9g[\hU:Qo˙I)S+n՗Bvաcs'w 6Dc$U%[C|O("V!Wg{ȧ v?T)S!V6)S:iʾ)[tāRֶ?{ k UŘ] B +Jh>G"վw"G@"I_!ٰ=~yZJuBZG|Wp0JeVqCh_3Z98ժEgf?cEKP0Sݗ;2wW -걆~+3xՍ VmnTj/s?d\a΢ԏlQdpvo]V#<2K=[7Ql' 6p &e%H%XB4njNT ǩf8aN$"`E-?1r^՞vV +2-B泧߰2=^  C_z](CҋH6w{xkg?̧9][c 59w[#sIOs9M`!D^D.TBnCExP +5Xȓ&k +)' kxHz^AvҪ&-EH !v>-yAMmTn9Tm1m&KFʐvW]ia!s4ݔ`)~UZeKI(]gm3g }UJB* gDSRêZ V{Չ D{ޚ%e8bpH\ĕa|$'4'L I;kL1돶@+)X7$d_cOMuIB/y*̀BPK]KCXP}3/ "EBjOmL3o\`9dI}<=7`*D>N# +IްP](; + Q|T0l'ǝ,"KwF/hS++˦K@vlʓh|#Yl93DtU/M"BW,tiDO(Uoㄥj_F4'Wcv @4R B +&S/ +MUHU9Z0p) }ׇg{ʁ?ƞpfi2aH#ڮ8Q!E26 WM .Ӳavx@ t6fUi^AFxXU͜ҩD),։/&^H^wkNOMOOWl "s OX/3n/$1r*pkC٧o@萸U:gDoє%ic%r],ܠɟCٝf&uT[33y{asdt-nȕ.p5ư"cp:ehD)<'4ex6Ui ZM#߭7wE6_< cgb:PBb7Cp +A4EnpP 6#%SiۢPEb<=`23IX@yYvJ2/FBdg ZYDzVA>NّF5c.Cn(kioe{UH rlH޼[4K76/_D",Wu՛2THprzjT;(g.`JeHlr9k +KhUmaKU9_Gӱ 54mS(Lrm><ȡ`!#*}K3ؾ9<>ݝ:pSA 8k<J>15hoiq=4nrx7,37L6.!FJ6KVvqN?9YK,ۋUߎ1şhVO(+VX؏E٦Ladu +<؟&aǍ&7ItVa9ll>O3N?Lwc}+@#a,-ɈsǨӋa\;\zA (eϜ +䭮Cɶ1  t)ڡ@9K8n7v󫳃" & W<+|.O:Т,_Ea'ྺ3l j WQOU4_͙xJ.-q㬹b%/W*1KϚX(' hNɵ +h{p_{& 4u(jpxR|Ǹ2d +t"yqQKw"heǶ(dr[9Mu*nbd_+Xƈ#A)ͫkC22+ +7C3]V>l&,{r3#|~*]Pk6* FRd93M94` A Tj29YW #EO;NQ`l|W=˸fб#LFQ, X"k')qNM[jFDl:P;y$sF=av1+r@~(kc.Wc +1h 7qK w 5|\xJBXdeKM"Rq.()J2M_6sRU95IF.&.i$ .a~MHhͬcgO<Pn@*s|LVO|u*uCT +9kͥ,7Yc;K3 ,ek\P-_a^SgzU^޷o^4rW(AS1 gӇuzcIZ ]w`i$xu@؜ Xyx@[N郯. 4N_V24rJ z6:[R_ڊ)i+tNR $Om +b@=i6 v,4Sm(J_ IKad!KEk$W>Y;E;X~XHxn5c2+iXҪ@P$htݚ]z{bB<^~qGd?NQ."wx(A S3i^4Gsv_tCv/=!'}nDjOeH"`JX^sr*#j6.=Jʗ9d&8D{5˫TJ6UN* S"h3c_ۃtQ^ hFDp\Du*qcs. +FD%4 Yȝ*vU 4.g ̢!dKc2p撬#,8شxĻAS@uq4jD}u 4P ܯ#tTVɩ홊Re^ _@|mPJjߏ +I4ռ\ KuC S>cǙpMV)Dp&V|hBE0 ;q%#R-WsONB4Cy}A*MQOSs0Gӣ5p7שx|{=ばTPY8Â2 \Mh7)~Z0Nm\=U\º$,u83Dq+;p#p2vS37n +F.tetjaٰpM%o>Ԕ2%6gd)]bhJǻ%͔N=\xut0;:h:i:z͏=DЫ y@:ީ]M/кB6Rq k/v] ^=PO gr5cID}!zf֞i)(E`LYG*KPr5 9˜@J G8""cHC3¢ +G}}:TU}z,B_J" 1kٺPD9x #rQPh& ]#C4TR1𝎪EnH[Sn[Ғ۶Eǎ;K69ApH#+rCWl @]e=z;*l +J O_c6&Dmpx}~R`a`L-#n}{y?!uc㏌'a]W $8Ig)ZژTGNsde^H14Z^Dyq;˰ՊB[F1dњe6?]:؆uK}tu[}j& +6}P o>\!GӢYD;>#Ӂ"Aoʐ%}[e{ +!FykP "xtڎzWΎvc;;|4\JW֍amS);EOsEZ@<֡'$.p},Ր`GR7d]F Ɏh3Wn +y_?_~,jB|}j$$$RwN+KyOWSpjַ8S҈QVnayUa~sB8x*vۻĊSÂ}[!ťr*vP:8qN,h=)/IDKzM #t6uHxj>J{j^;A}DGxTSP:_$4ѻS8]8{< +!BFtPCzzy*56Tºn9h<|Tv.-//CTupXFC j4i4a 5aiʛӐ@q5tbF/ +B: )ER|uXDm  \4dZY3ٺ,$iH)nC9ypLZ] q,kϠe6}zRP>\fUo딞Z|DPcP53;xR8.q,3KB5})\5-2Ke".ӧLGH/m6۞l.մ(6M (F֝XqYߟ^>bu5Q1RfD"K Wd8yC ΋K;Rd.˺UޑB@mz:椢|#hB@0-έErp%e+b%[ [a1 +TPb8(Gs-L)Dxy˦un/dJQ _7yjڶɟ w 8:sX(;̼h.C!EKh3 LT𨃃z|rn %+IIK7 CkQ :kdlَ>= f&DlsK66x r=p(聃G[+4>tTٴs|zejA(&٨ h[<hᚰ- {}]kB{ܚ 1b{4UzBw)N`WU=Aie( +-ipSGk_WX`0H5@>۩+8Zp*q<$׺X婻`T JȄZ}|Zy졇!K M׋ O}EsFê^p%f|%//p/QBh[#Xd:$}Bf<^KOZ[c)$[ pJx%*,ƃ0C2zܺ t~TG<%}?"C@W E $'ZBu땨}2Z]+m>R) ^#J:TJ1z%E2;A9g^`<>C|g;e% +>[, +ms;Hv0,F=ġp11G֡g.m_H>_ 3S3XԔ~sH-UPՊI$܎OǽnYS&&`ysuJӡj3bq , s]GI3l٠>AEFjGs1TSt9ڵC F?ȧ =y*oe~1"Iҁ$Lcj?UPn4OR-NE=]K\AKJ)bSc`h>곥Ȋ.W/0 m}T9n9; lP5C_o!牋[ Pj~uA$=g]3oLy4^- Sy*1@@nQ-  +((.knPPI @d аm!2AVpo6ˌ2K3ǜp@'LO3*M#e@[ruHs ¥x=/όm=妒L3o_z3eo|QK(DޡJH[QJ Ŗ~yAH+Mxdt] כ[Fd+WP҇%"fY^=z> n:zہ&e|PZwY9VbJYbP"Zm %5)_lDmkSC^ʔT6@6k@:^sSbAT Kӊ]Rrk^GԠV%䁼-v" +q0(8ڗR7}3R/-?UkJkk&o*V@}4R-{؛qeKDµOebIY'Bk+؝ ?M%E@: a@nY6PRz3VbHJ;+sXs{w0eґm<×3ok5z~# Y%Nz`Y'csY +\rYg\RÅ0.3L +Ct0ߚʋ_MDb5A~ħ:Kr)D<G{ n(ca蹝֡ݍtcogbєb1Yqj@?ߊߣrO]Y1PE{(ê 'P&Ui GPY2@j"ђp,dYPE7|߷y`LIEz~' +>%՘nNg'Mc:@WTE5o{^`?5jjF ;eԀtQl6>ԻT9#o&,u ܿ; +e[ mfmN9eXdGo5PY% )sSW=Ys+k  ѓ}`)0(h|Zj0h}LZ`yXfp-U9) ']@O5g$LAiЎQ3TL$Br{~f(<,"0}~'WiVX*ϑD6/!B52;*>h楃˜i9^(%qڭ4ϻ.]^ +sQU"Ӓ:,"-?57u^<` ˚zK!hmSloS\`%&Q⨞r9 -MHi(me)*R*r!Ԯe`K*hB(SCJ<( +u o<_IށEkw&ZJl)I2`E&+/*_ +IQ΄[S-`s9 'dh# ϗ$%@*[I@jķV9h9lwL>$VZ;> y Kd圝;7l x>}3V~ݚIi$t +_yĒ2V~-uMGǒξ'oю4!S%5<Df#0%ͿrGYs`ek)ӣ/wѩ@&;,C aASР%?Ʒ,>&-r5ҽ.Ľ`R~4͘N{K5@\C'7;Poފ)MK恭#HF 琊bgm`$ڦZ'Ymc*ډ)v<=|+KOR^$kī8TqBz_(s'`-JkXM 2%lf LB6#<|s]NR6;=]Yu}bA=_qCfI`c7l ;-̣Z5Tu.xtn'-o9\G]$ U.ʒ#?.g6M,ƻfc1o ~|Yܫn!D:U>颖zވ|qQ>e9.j(ʋ;3ʼ{}N"ro/ŴRsˏ5I#~ ,A4ʵ=FXbT֡uך'2Jiݠ#At>[a ,bŐ sjڒbk6| C|tDjb AEL4S-IT?Fl.szZ01 ) ䷻%WV9C9\kS_wN۶XWO_F BkWd[k^-TG<dJ:yxhЋ'?tUi:J|o"fqjlDt*qlկD\p"WyD.k|5 u 3l0tXߑĘKf˥N @(gu*Pw +'Sv[X9b\&FQA9$`mz_ua]n]ic %m}-i96zU2k)Hs9iEEې0f`sG$}g*nchu*.,ag@h`BJH-F*>wM`}v*JVKjuҕkc3p"1j|~%TWc`\t[*Yy3Ӫyլ~"s+X ݅Șѽ:$C$A[1^ܚ++i$楏 +CRqX{@+W&^ɳL1]r٥i]BhڭtS<fFWn# McPf7f8 izoFL1D/}R(+x>*sWj&nWؖBS5q.R7}#xV"FWedG%XY]듍kd7CB+ + TtaUyDo׾ΘN*L,ۢb\f{粗%߉ + ńKPчk}ۅlՇ&rh$XsoL4edER3&.<]WS^~]Zfjk+ +cS΢3G\wwZ-v+tt2;Hr3ѬKB'79 څ3Ut*þf@4FatY >踞\FB01J#Vq)[=cC& v`*wX-5@lRޔ"3! ݙ4Q]h 77!ۊ:(gr}o#Rr d1Hs4i)2#˳( SNM/ϳZky CQgYH ̪)E)GK9RtpҶRkYKWBeٺ ̲GZU+Qϓ-V9͕t|U,^<>4{JV@\'8XJխkt&ugo7,!XV YR + +->ܷ4/4gU!!t-֡L +| Ghlr`(O:mf̒_ښe$ 7Db%Xs.7=^7qvEN_;}bLZq#`0aEc=|y,v^8:!&K`&ڳaNR4䪴F#3I Y`p[Xy*C]3 +WnAiGSho-$c(r,vDҷXi]L]R1"VniDSo)`zbխd).B>IQԨugʣpO9G 6RWLI/K!J yv:GHW~GZFn\8+M\kz$^iz<;efr0A *|nҕ}M㦙Qn?+Qf)Q.EEC.W޻x(VAZ#uM$sey>V;b>߃GЕ=+7 `GJLQ8,*q'݄ p#d}H-˼5MMekӄLB &1`f5.\v,N!.!F3Vt>wU%Yn Nx}ip#Arn +[XE461>Tqupi!/t +y]z?pl +jX-3*6R">ײU"NTߚk}Vl%hɜE\q6(t΄EmIO @9IK]. / ]zօgZ+˜NEPix4!*.n `XbHE/"kʙ &M 3˧#,Q)ykUPpq԰2.yDnrdQnuBƛ-Iאl(<ޏ_xz|6pԨ>Ԇ$RJ!ݯRo˖IbIuדOV==ۥqU{ 2]VǗ@[Z*]Qص~UdfZީ15 j`Z."Or5RFxnu.zdA+skFKRTZ}IoӿҰ:B"!6=R +iRy{NBI_ +ZR3CBંV$o!}1D$hUHصعe?"p$V%2xΫl!\kюpfV t HT "AT \r6kXU+x}F@"`Ԗ$(v>Fy #Ϭ(LR%޼juO0_v6 +"!@5ˑY~SR4(E٭~$3 +` Q̠mU}K2꧀ҖOY#u}e l'L5_O $CO 3Ԇ'@'8m1mijz_*ً~1Fx{zdJEgbj-޾EBs9#9@?-`50\X*oPJn)Tst-dOv#>DIAI(JֳqS/likS*g8]%e*1s@s_OٝrGca.ΪsmR Kθ='bN8*y<uL%2g<JBI>Pwj}Fr#-$fE56U ٟEGB@~q:@غ%derUDgzI`;HQQȲ] +ZAd=KO5vʖs"hmFz:Qϡ,;Sކ_m׾_U#~6γ24t~\)˜<ӎW-5>Z'|U_ղܠOESuJ6 NΫ?olb&ScyxEh4$I5R_[j$.RTUG*Gt3moM["uղ:HXRTvObS4~—g?uih7Geي2 HYIoBV@ei} ZFi$p1Va^ig|˺ o(46RVn:$;s +iyU[=uAM3o q;m<2&WFيk 5;kGBN+?kj"=a(+~uPAtuL綏?K#3 +9%47 tDB.i~ 2%T;!}Qj1BU׵#ҥ܊GjOe_j]yo8cu76db׺JC sge獘]i-a5zlYi[B m~i?5U QZbn$ť1k 7"EDA*BFJ5E$)ڕK3O%v ;ǡmܧ⻡f!zժG%@\yG5XtSgY3(ungA}`8e~HrmGPBOR_/ ,7z(tzsf%Ȭ7ڇZ;!!8A]MWJb>۱ tDC B̂[ov$G 1KY~{pRW +Ce>im67SP5wKIl/%54 ĵ w| /aVjeB_Pg@>Bec¹jh9%i ~qsW"@cͤ(U2|mXnPTjpߡNS+0B, y,M٩?p +֒0]6pCDHC'GE#NWy,"iBŖO<;:dҹҺz' +?PmJ@ǰ4nh]/S 8<)BY g PD®a0$>X#e4t<"}ڞ)OmxʼnǬ$9Ye8Hz (uo9ޝ^ `ģ endstream endobj 48 0 obj <>stream +HtWˎ hTY.qv+"XYM ~!Gw U!ْnۦRzZݥ"?J4oZ^`J^P֡]N*Ւ+nvͼOT++VꦊƐ|Ò1؞',+?{JeMi&=]xXGJPa>2_D0'4JWI.jWJ{NV7{>mYk#텗(@">Z>Խk0eqZ +b{C(.g[aT{ T8'wk^h1{/e-[<^&eNͶs|}?G>}޾/[ޛIǤdpkMul:o1QD</ȏ~xga3tu޸nLu,\ JU4AU+@Y(J2oģD$j@x}@KSo=>@ Ќ]7G ַCYVú'TgF1 jg;! Za@y&5Ux ֏$A}CЏ:|+-C"9!^080DEtdPfvp ɟSƁGIVv4y k DS!~A;=yB5RAK38JECWyT#E]hPVh+$Q׺"v0;ӅL91uܵ>,{ +#>ͦv'4JfLȏ +ݾCG!6a5 +ǛwJŹt N'l ZI7z z +N"d\ީ q+ L>V-P{'ȈROA ( |V(Ff*e:RN +$h(\L% ).?cV6\P';Vp qI.XU4l&/-R-S2ye ~A`=#e+tU\"!dj4 a-Y.D ?-g\ 'RBA{kx$!`>5|:nuF)/h\-N wE !6'=+[0C7hЄrKߑ4'#o5zOt>@x9L~.iڜzv);#KTlU0D4Z%¯{N׍ adRL;G^GY8 }N\`J"pFNΝc]c] Сu0(Gf5h7eks[X;h0O aB^|2t<:fA"v^$ vF=9ŗJ]?AEC=Z!.0`/^w .BWotH$Etn\ߝ&c<8!];KGm`%׌?<&s9=,XY5+ͯg ԡi{̶|4|CbXPq%} r'Pun@wY4 %1( #?׺~wF;\e?jط^~S+Q޻-92]ǟq>0UVo~]2Z^ǟOv2ans`wLb +-s޼ &V +1Vu4,Z/][˔ ?P6TYYgGͳVf24 Yra\pK_zfd NBw[֋~Y׳t1ѶQȞؠyBc y8-Xoۓ2)ҭzNn9<bQc`?CʹE;Nw5HZO<5`ǔ~5yKv$IeԭTf;VzΎp"vm|kW\Y@zNPtAxϣiNC4hOAE-aݵjˎ!` +GlD7 '>+E[uֲP["#PQ)>t: H|x…T /]נmišdW0=mxl|`tן巿og =P<:euҘe?R,39~8q~)x̣R!(9,݆Nj_sRZ;&hwm4} +mPPDPJs@o8U7gcjb==ahlu^psDdvƢ4!p߭FC, ^B>wf^P@iz,n42BlDz w;$82}~*m(_0v6EraW`]]N< ˥2znqMR`ϙ- tK$O0w襴X0lXҳLn 0hHfFFFMC&鴿ZU@Z*-Vg|,? +3:x ٭?q!tN7_Uw9k◛ +z,#:]Su&\첫JLcN ADf$Xr&]+yT=>ԕ|΀0Ժ\9V^IC^}ag \w~Z:~",0I + Jǯ&9OpTJMc82e8KBý vSAL2vښXLLF6e*6Ϣ]>hxSf(vC6~HsxJ֑ٙT%$ez0TOk4P}%fc9jmgAV mN\.F-wj5|:=%?6R, cG ekڤO8f0vb}@ŷT|,fFF0$Ҹ_N`NseO +aވy-XkIEWڧ3IbdgL#[rj-_#rV,Av]d. +rZg?QˤGH(UǾv$7cD4sNϝ2"tk{ C[{i(U7K2M㶻"Lrӗ:xhx3NI8(NHo[/ن+žK?jH7E"ա ]DڼY^6obh|b-T$zzQ7P9=*ݶʩ~^Xw]; nQ-z]5)F{^vmoҖea̳nqTgno``4s/^t'tu)Xo[3.ڙg2[y>)/9"/%^[qeh/=R \=A u<x@ ̨徨ІY"dO@cPyۧ欴WV[Pc! Nvm:P|sz ;#a))LRnP^NHu$`עG~ i E`TtȖU):.'c{R;FۘY.Qlͧ WCaWS[V6%iCA"X#D! "&MĸѣaMмГ,tT,uFP^uBǼTWT^J[Edhn6s52@l7jbZǚ=!VM ܘtbj o7j,c2fPTneԱdoQtTVk93}z i FT5;wh JUi 9[0cZR{P5B]#T4 2ՠLZYp=2i͞d),yX7 +Y \:Uϊ^Qa*vk7MpZb Jm*IկPoi92.e,#,ѲͦkM#EhQ I. bͳ˂4e6F[GF22\݃"ŔCΕ@rSk}RRApB ~6_"zJ&ϏC(ԊN$!,sSL5 ʪc}-XN P0P[deTcA6*ٔ/c^gX9+djދ6.*MUMgjjMZ {uZ1j[)MR X€V$Th1R-q2d&ȴ ٴO$:MF"Z8咄Ql+?R/uBE\u -fllxSٶllզ=!rJ6[:x\hmn_0FkL^mj b\dWNaRӽ< Z'2G39b t@Qbӕ=cӖ P9CёZ2Hc]ѣt 0ayV?BՔfO5h +fi|Ko\0O|Z-҅yH7"kQ +3G6Hbn% ׬&"o"{)Ư5Iaw}Z֨xV~wuS3}B fH#K1̳HP㈉e)m(&|_a:z9&gHxi%8BGٷ+S*6OGbrw44Q˪'t M­s5c{].Bό*`,CVsxN(\䪿$~Ս( M%m@n%^@̥L#$_&$ޚ~5>]V݆o@n]sw+*x 9E")c̩By}L¦׊( B)VWR44ut$:} +n ]޼ +#ٶN@N hj@nϝ]7q!r!l--lKx +۝R)7](|]nT@*>7TU}2.Gq4I5וC 9T]Q!IІ⥯xۋ[Ffw1[ٍB ``U\Ntos꽳]@&D):Rz{D-"~E3E)dLraQ^,֕a('.?Rovy ?{%QplÅ@G(۞4VvOwllv+e-V>A*_G +GKJ\Y{A@kߝDšMqHS}%tn]Nb7ϧbVG +_mfg}xԺ[-(ˢW؈8.9W1&3JQxTUzGtf\f8l}z0+CtIVLvO~(5th:uKͳv4< ǞQ3JDm"cДu{kA.vENJ~}ꏈ1ex 7N[ua՗l +pfˣܶb(W!el{)W;*ё*=L{T]m涿ݍd%(89/J)ZEEYGH[G$e vI>/ڸјB@H -xEA0 O_ͅ +,t?T Hπ听a|V)?4;h4tʀ>X;?ʙa-GK_:VN;ˠP zy|_hsd]$XeS49;EnUn ,sUOa1H!~b>_'.UBIr/ A7%xhWĞV9]}.Y^W͕ɻ.zTZ`8c6/4d{gb +U^=gf1(/P,~3_4 +MkԹlpfztgPL@F%&tWyMuf(Iz%SO)Qb U7HM/ib@-<"v`= x&sP)4xKSdpaJ9Z߉ٛ%/ y3cX@C|i,Qj&өƠה<zu(J.62<$;!x˻HhTjPToPCk_oN.- [ko+Y[QWQVIa BV"hv>F4O'#=uCʑM&lǵJ42YA/[&0…شMUl18lEύ9/ +%jHn)%U{V+,?!se~+DzҴzLd5@4Q+X6G}6-$KޢnЩ|a&"͌B,\]7hؗuv)Ǭ#*~wx2\UO+09(tiGuP_ fhwi=id+%ïzJK&z^UE;;S]O3[US\!,whI%nR,4Vۂ4Pr,dr3.s'-roKkP8-tG{$pK9;ʁ{KU^6_gk%*tG)FVd$|5ʽpJqnlK.gej>1F@k\9Պ`7ĩ՝ki9t^3wv7\ +󦎐oW +kppBCbiwL֙1=}l{`<d֦.`n 8LsBh~-Q֙;躬H .xLާE77y0?j2G(S'[2C N+~)nci]WO^yIwW4 +tj>J'- rK%HOc+1WGRidoS۰Л& +xұWb8˰ml]@KgS ȝ$"]wM.{/ZeHqkin%P0ɚ ȅRT`'Pґ+x^7߻?rkC,KNjζ)L's4g7 IC6ҕaW\v71S'8=}>"pD"]55k!7MR=) Xށ05vKWkҾCS;b#LrUt|=Jk~m|5moHR]ŇW"/lf +ȏ>bBoy2iGiIoPƕ\֒ɝj:VM~3Q抴auE-O%z[Z}%' ?_r#'ET)+e&b2ޘ"ܵ>gJ0SC7 ;JQred<0r-9f. ??jhɗ\07/nYb4jȋBzZ/2A~QB#˝ݐ mGbOM1.GjTY(q pDg-v#-E +ڡ;,-%#1 3u@=N0gM؝Cx(^Nv՝+*ߧweKOrܔpzLufZy`e@jtzi~0|V1)upDClITUK2UHl& 1MB+;I~5vwŅtsWrL/OĢl1c9PS:ŝ UrгT^D"tVpӈݾ6 +O*{8VqK+ ̩X2Yl[}{o6Kq=!>=']kjo;LWޛw:c_ + EyPT{0CZT%XH&gm=epG_X\ڄe||bT(P:9`̈́(ئ{Lb`S˥N+~5ڿ~-Fzs.mi.\iR]D{:7/="p!=5YC,rE-u]qxL}(YEdj-gڱ\2dAwⲷtר-Nzl +GؖK.hI7{)Yti;WS=(*G@ r)Wl=8̓KJklɰ3T4](II '佱d׃Ȳľ"Yi2BM[Ns#C=MR`\nݻWSD 0Ia'ZWMyr6zc1CFGrmq: *Ta:amk>zs2o9~eER83J9E}\ʐcfd@"v{JelIr\7DO; 5^;BkwMIBT5Ԑ\g͡2IV\TN"!d/Sd,]WN2j^ +1OMR{2V@ͮn/lsfHq m )6Ƭ\4`JKfV,[/U H4HV_N#U\`F1[7Yлq 乡*ocVYPhR :FSevv+u71w7updMwHN/b%AZfC=jzEŚ4x/D[jîba` F}q1"I)Gvk^RRy'Ո/cf2Y{t27 UYCqGS-%\fazzX{R#ߨ^`2p5)$zJ qz?[@*2# JjfRU|2_S8>H[s`> FL. ; q>9-g}wdOx~tDvЪ4 +SϯGʾɡ巂3'{RҲlF2LMwnedM߄ k%:YRr;%t)wjNό!aiUZ2ϒݣ^Ϲ- s&o~! g6|!`Ս֤0B9dG!O6֔kTgX9BN6+IBBbMwm )G_ąA-Y(Q,H85yvv=G L3CrB~_ +\ZF +ƎHB#PcR )L.F:B(*c*W0PQ,)top)VWDJR@8,ۙj} u $8Tx?%R9sN6hvMD׮N66Or48ZȑwM[Rnm[N궂СViqsdt:Wj|$ouHf Y ԓkT,ps0g ?+Ukܼt T4&ӃF38 H@Y CR?oe |l6Ez"]j;^K0gg[T䡬=Nrn[o #y<42{V,'RHPW +O;iPZ-1Q͚YehU"5ԃ=ϧLP!Gh1fJ;‰!j 8D\:[cBAK%L/JywHSdǦ0nArO P|Pu?U!H٪.C'3[WP/7ٲ\N4&l d$xw18@͂[YjSҒØ3u6eLRjBԇ? i-.BQPyUse5QZ%x̕a;NPr LO\ΊB2EDRFWaʼQcq¡j|U6-e:NK 9G}Z &*h?g*!i&m[-a5٥⚭[Gƌ0jh*3LN5_?cE ooml?IQB܃йq.Ku=rY$NG}r1,g@+(xBsU8|C72.,~J뮓 S \Ofa,nJ*Q'"-m[iQK|6 F%K畨dpPe՞ΥP(NMPI*}v,'ˌ6(ag@UK[R@4Fx=U\3e@Tڵ|o26|xs[ †Qz+QĨr}DSKK,2tgZGcܻOIcj x9 'icX)Uw>;:PM"gU#qDOw(!侘@ހ "6IzKd_=Mg*l̎SlJawʼnL܇Vm:=*˯ڜh(H-!=; ЭcUCަe2uw iK`ףw)cql^ +u (0bgGA5,ENͮl5O5:T>\ Ls+EzW83Ҍ-nl%w #ήSuPUk5R`Ap$GX pTiɔh,Yv]&B IaYA?l-բFZǯC!jH3q:L3a3tѺ8qUiapJ$ R*̙>'w+7GAa_̷ K +:~ʝQ hsuJd*AĪ5dĩ2PBq扺Ex~h uP@0b4){ 7UeJ[.r lUIֶJ-0d5mu5/ F iР&?gD6i C-X&/HR)/Úv^V,2IkCIʎaw5n~todĊ6 +Qu +L%luCgbNӴ()LmN>כ p6|ȕl:w UHߑ2 A1NK4 2Z5QC &Qm;;[< ~K6 f&4=\(hjvBJ9#\ .NK{+z-[R@d\lES+Dl%: +tKPȹΦbhL&,o c H}Ly~P\/99G#t@A iNE6*ۋ4/;a0Ar5 +\xV=!/b%f=S⥎s$EUc0_>){Rqf*ɊF2T90bsd58p]arDYf]8s.]- F0b%/yYX_˦% h S995F^32^P !`Smh^ rg%.N#&R;{v401\⛝ޜ2婾3[<]L +v |wŸf ivMM˘rhvpE)΃{ g~o2ͣgǒ D +t{iu{Cf&k+0LІsɠf~]gwp&$d7qJȊNQ9~)1Hu/(-5*m +(w 0*'Q:AN$OIiuL#|wGn`[E!koI!z-jؤ5{#Ԁ +UW0}_D)>Z29&'7Lj: +Kݦ0ϰf 1U;r qiz"W*ǧ%[Rdj2@S~P;€TSea䚪mSM8㓝q ;}BpHf{qקczqo/toʒxԣpp$4yw|%񀙾ϲG⪳@03aY p#dH`>hCwzxldlE=kOᗨApTx4i𰯯7߷/y/⁽GoPQI55 tmOAZ +#B Q?L <[y~sJPr&~u<3Vj0e1K(y֤qAxy`TTBT!#cَG'4 };41 (hD"?W%{˽ʡ+KI,I/Nu& I{i<5|~؁lMI3(%D`&ޠ xg} +~Vrhes= #77P3/åiTTq~")enj͠`^0NxCO/W@w79m/259^{XS0xuMw]KaX[vvEeoߓ ijeX1-_&%6v.}Wo#Q* L('->uϧVm 7 FÕ0#]M;>̴@,@(| xssH;Y(_%- 0Rw" Z iF~AcATCnmحʭ)y4U{<y3m4j_@:HWde()岮s#ctGXljkh"?krcQu:ϝ?3 F;SCױ떳W]oƮU2v>;PFKσa򡫬GͰB7zVʯxjӤ9KK^ $}}iIR|>qh*qerUrMUIw$,ڀz(#X^j0\ /s҆h _bjc!o/:xݡ Ո}yg@ܘ ?|@ojWݽsuH6|HOjg|/[ye9m}^5?N.:ic#Ow+u/Pxkٖ.+U|7l$F*Ӻ<: +x & rhy +F*I% 5嫥JL֜^^g7d7Θu;6$y%&#cjqkjyLPà˨#Afr-@ȕ +WU"dݤ uz)&E +Hf1ac?Vj7ْ5JuC<ك: GnJH\SG}VNPbD~ޣcM2 8w~L17zOd|u(蔟:Տ|DU6Ps~#Mųb:c^T1lnb%ԧ^'KѴ4v,`~'pN_tCRnFӾDKwԷ}JuP2ĭb3(C\ +IHn\m80@)'??RDՍ3hQ9so#ϪGбDFqC:)m$c0ʐj@ZѤ=DV8HC$ع! a&ߘxڂ4YF\%~Y䍡ش&L!G^. k&-(QǏǏw yool |~A/Zx72 i, t #-6P41F{S%;yu4[PCtyn,gR beރ>}/{cL<0u2D~G31Ɂ);AXL+#Tg~s@%6ɱÐB|hPtDjAO4֑uv E 8FN$KI8+DƃO_ WqA_7Ԫ[;L)AMQ#=XxTAH  1trRᑉ˄pVL8r1)RHd&.Lz)y@~aDB! Q %b:PJPyD_;"\U ? 3 rŠV%! BfJJ&h +=uvLT: z»,U4C#ԡ3xm +zg_t`*`4h.r@Dc?YݮƩ&aذrCݸx܌zɳ'zU\ Xmey5!g;`OgM5 +q|tՏ94+ +~D۔GEXd]!a䲰ʁvpzCGdAG*eI,~*ę:u $03 /e79"sunj Y:m ub*RiuȈcӃ+9ye%gvMBcii[R},Pȃ.(Ǫ9çX5hk4\:(2J +74/vS09m`V&5`J--^hѝ nbyk&xrATr̈́,T2!ze9ˢ毙mȕM0!JC!|ΒPfr[$He {jaH֡H{D퐕\IxS;by!L6s`܅廛;jdbEk+ZK Zܖޅ,ƌ"ۈ@;ڊgfzwyѫazM;qZծH샚:l@Qz-eJRnYUvoʑAbBhH]RR +9Lƒh ?Qhy@DJVY77O6zKq:8eJଢT:6A+e47s; Pב :u&;dRyiay"ѾTХ4B[P6<1{ P镋8jGXq9.J;:n[CP%s2ofԙºA:+%'qh`5ݗz=c槌!R/Pc JzH1 XM4#ΓRB8^2֥iy꺾?LfĖRkTڰK+vZcsuѢ%6_Nw28 [m Q_:}:Gťھc})ω]ɔd35ԣL*5~TԆGŦ6x+UaOAU&K!A~T<ݔWBq'@İ!u,O?PJe1 P:<!NgMՙ( n]n:%_Wz߽OXO +m^MM ۂ= ixHiHRq'?77y1B`Z3}4Ol:I 'pa~ 5hmīSFnz!nٿU8=R mdt[+dEɴוյp6 +gV8MAvѧ] 3\ꙵn9Գn6huCP +Gx @M nЦ/~ 2+ +NhVdQYHd疗^ť[5b^^_Zu)%S0LJn!N qfS+ ^P%LXqQ. \Z4y|nz^ uޣ>{)jC|5\1f-J$`kEy7X_mc ݠlyh9ip+- "t9Uz@%f\ŀ~(CЩ̶aBob%U /t*mJkapv%"S*m&BÅl>?mZLjߺ)UjѢG!:QK(NW25([F:2v Z/3C&ᵑWe 8I Sz^ۛ70q +'jb)7rVm'e[%^][1Ö8L|@Y.`T"i.KCmN$];L{@C~7aT5,"{/HgMž%Q=e3vcNPj^VۗeC$V]VmJ@‡WWϾnIW3tdŗZ^樮]Ys\fpniW i5:A) +\ff`(k +1,%&qmHCY3hfʚLY'$.-WY$MY]1t3u1^ +Zh׻~86m dR~V~X>2d)eЧn@hZsB$<evni dpbd_riecY|:SЂTʮ`Q͖Nr3vr`B=<Glr224ch]n'EՑ!t+8΢5#V,_З*Q9+[@FZI ->|8s +f'woeQF5Cv/*rr2,Cq!Ljem9տLy ;j\hwGԬ4y!sZH8 Ȃǟxw(܆l\xuF?[>ȚHcIz߅ I)0=W.SSC%ȜstVH[HduUVz}Qi_fSMAbdE~QVMRX?-)Ө/OZPEݗi J9;UyjʈJ'xFGj%E* rvS['euT +s drHY`)e9ωuf*x+h$c:زcȊ0H41<.եDPǴ#p?U$1 e,ɖIӥ̑0AN :U֮*w6eM N-lcϊ "nĕ5@`fHPSy@$r@|$3u۝?<IQ-b֓D(9Ki5]fh;iu$9}>卜7&:K kOt7<⍂AofBw9k;1/e+!ȋCf*e D3B{){,rgwt"Gim9v[6( bArFGuVvxlʿ4i3,9j[4K܉N\D$gMl_x|Kq~*FXQ%Q/|g~RVRW,rϴXb(/F6UgK-wW/KlxßY  JZN(̩ThŐAzjĪK%6=Ya#j)!/ē endstream endobj 49 0 obj <>stream +HtWˮd hH$JKc݅1}dc Cs^N(Q, (%ڣaL't"^PX8 8&~yg#HEO^- #" ã$ucQEGe̎6BMoV$#?+ O91s}xBQh˳hX4@SY`>) >EJy}c;?E7} f*SJ4z#1ygA5P'Q=r@ӏ}lˋ *Ϟ +k5JԙUP[ xmor5b"6P9wC0b9}pKSwSG1>ݩ l-T9uީyL #W#O^YsDkqPȬ7xIfP4ŭƭY( \sk4PB>^*m\U{CG6f#mܠ +X:! jtW(K}.?W(K6B)sR(6 3.S۪j묄(|/e53S3!Ӝ$̐8~d *'1:`,kT16zl DYj{mws[Ȥp*m:4-\\Kbo$Ls,۱Xd)qSY*$Al̴ؤ?pzZ!c+ ^65<EχigR yH{t N+W¸[9W`[i6Hey1<m=ן؟$?_=c28?>AӜ3'Hpa }hTMxsstkl zDE,mHJ+l )V} $C祖02]Dh)pw^Y V<. +h֢ G=`qI4 e'ǂ^j0 & #uB£_{fh`zMF2K@$2-,XMXrgoi~AE;ŗK!+/:vKgQ6d5*})Jڣ!x."}:xtuP| HmaS1n=xb- :9@:Z)WyS"˨r/w] h +0ĤcagtRY!V}$IUg(NB$[cyLp42 2L Z3ؐ(CcJ-ozmMD%W&4!]1ԁ/7U#/ x+M&f텇%[cՙ]]AwU2]T)qoAfqOЋS#I PΝ|ΫYB\#1Tw4@|!sdX8Pt:Li\R+\7%tļ\ŀ+&O\ R'Y >3[Kڂ Q0;y}j+Su7?3 +6rXSZdU vTXvADxaI7 i/Qk\U$ 9[E27k:HkMQ|Ѧ&&T<.SLQ_hg}ҹ譔Xd!|bէ9|Mِm_z 3: t$aHd/E= ?ecr/?)9DmYMl׉;Cr:ü]KFRD4\nv>>%鱪b?T$TVT[R(%-}8{EyP>FqvTNמsJI?O4ך砐{9- /8b2NJ3-.yľ)c~쥭8tbQ/2F'^>P]x/k%K?2RiQvs%.v]RiyBw(gK#Rmz:l^Ʌoc(,lyT){fΑ$\>C㥀Zk?ŏOCu̷?W@ӕ7ґD>3 g{Q\؃ ZGyW[棋 P!tt㱶ɯt<>`9vy޴>D=/yUgΝ~~!! #;-vd`03$0#@6 xHp}P=%eKY0GML#;(m+Qa;̖V*7v8sh=:.eal`R6^mme->;ýb 58-o(;bS +qrzhEcN"(p]Je+E%0U2BY\7Er=1Ah%6;ϒ)!* +]^"ܰ9{|.AȒ'27>}=yx4EgҘFbmIԸNciR;6_4G(xN3tHpCLˆ&$_jNszpKڈ4pϫ]2h]O3 MJ,_EV.ԢG`ł6'%s@­./'tnpN֑W3ObL]I6;LEڸWg#']AROUcCzuLhѱOr,o2{7R=̷[vlᆐ~ g&:jϱƇOgzmV14hU@PH[.muAvur"K5,f%).IBllzRiyʘ[!ّ!ld2DeB`ԇ)qy2pZ))!Y^rEy-Iѳ-ML^LI,M,S-+~fdgYx8<ȭlÑ-nhR)5uTf'n |gybaXv<;?O}.:#jj[Mɢπ"WwC.,Nb;5U]j}9CuWOeh![e͡RDz>o2i ]0j[WԽD|f׷GRC6CV-ҥk{|uKIXwidJn\i#݉׉UQ6q2PI1@geY9Uwk84dH,Źsw`J(2+$f"REdk;'K(j<M~Ytf45KjZ3zs]cqbYpnVd [tcR~kcDY bHW$?p1V:]c,h8z*f4qdL2/ӄӲ*c䥎qlKN5Uٝ?w}$z"qaϿU˰G;}Jk2KB9r8]GTCmkxf}\HdK}跟]"0>]QҔHӯ" :II_)(h_ +s(Odž.]V갑wrޓ + 8U0|W whH=z0 +;a261/|Rq )Zr-QfgjC_e=H'.sf>,31%w -{D1,YnfsP v QwVY.QCk!T ܖ+:Vp^©ɢ; aݷxd_7CHCRT̳F!ZZhuT 6 zN?a/&(/>r.},zMGO &j{L +jz핍Q1)#6>u I?cPWwn"%&kJgv`,cPjƄf3uSt՚lAR3H(TGEXX'"+vr]Z˽߮z&*?wʼYj"ڜ'3Ѳ3-u$2I"WVXAz՘1ZwW^`A*7V$8zLR,4.E$ʣ +|l[ХU${L,I8]. 9nB7V?R— +~0xQyBfM+Cߏ `D#7_ܳ9%@HTlk"ZOd壴0q[IX*s㓝$Ԓڑ,B,8tU"/w%Zn *Y6pLsIMtߗN!G䕣w: {ezC;uiܦOHg/{dUރ,DzJ)NsW;V\$ٱt)c zш7+@Ih"v[J0|̓? ,݇C\CDlw;SoYl$CyR-x#5wwՋŨ1ӽI5/ޅ2܁lkn/ _E첱9Jm"n%[1'}!t i<'zt#4i3"gftX6֐"B8Gvѳ݆-g9Jfr6\lr,Е цivk7UjtC\#@a2`Ҁ5ZƷ/H!Co[g~VUm5,Seò>-<=BAlOXhLߍ, 12vY=e']l_9=0%HG86A5D䀧R7= +nvw7(?UQմZmē$1Ȋ(+l`D~eOB3KIPV~Irt=SU J쓰BV]<ٚM>u)b:ʨ8HiY +%nCX^Cr)5}dTq筱y\cM-áD &/ Zki]WY56՚ +Z0ہ3[圴Ű L2o8|]Yz.YF!)a(1oH7;9>ֶlFW}C&ΫZsiR#YJL$jf@Mu܏fU1&F 5\{ +4JSdݣ0SB&Sm@ TZo9 +>ΰ#qiY,Okjtݣi"wֆx@41{CEOɝMwS%ᮿ%3@HH7!Хz*Ro$RB/JޓtáSf2ҥMTzm -&wK/!b?RŸsǎKm@9tD +^\@Ỉ\}G+DT +rWKh窥Xq2=,t 0$uz(k(}6<hD2ۏw]ӭ61]3%ebnj2}TFy˜+` Mi-*}͙] "~ +Abɥgx%KHE%{E/= 﨨N-rM`OyqjGAx%/E>bvŪfWʱ$@!IW 3MpP#"RWEyOv[Y#`ss>)7Dˍ-d0'*mfpbÍҙa׷ۼWkE/E-e m!O>,+}[[v`,d` ˬ % YIXiΫɺ +4QqLID軖°U+-x -Jk&vk'۰d0K!X.ĉ<S(9fKrڀA)n*ȔxaF&vp{,n%rnVdy9eTݍ CA|ps~b@'+ zU8I:4L[bQA zH UQM +εs|=9*txi~oU UX*^(%,eN]Zs69)t5nu5 w#o:Oɏajj`6k yu)[Ud djȽoXP"t=^*VުHͷȮ U]Vp[thĶxqy]'R0k<'l! G1/=Q E;:ϺZy':@J*׺e/teQ5\9I>dnj$` B6ʰp{[ZB-O*#XA'\;^qM4jgi#z%o +&fs?+uEnp{_wPn/3i658UY$65fn(Z07L6$p"pɝz b Vu9X&<\$jssʚހ(𹘤쟽[TP"7ZWS4 ?L] م_e JpZg2Y*|;'q(_)YSM4DO'I^0Dgp֨ى?& aqt^ |`J?1]fuۮ i񶮲gvqWyqҒP68%{o] Bz"ӷ&ڲk`\vy g}Lyv?AϿ}_o?ߠ3159=(Bo.t|c3JmIw/ T9deG6{ן0< i$Uy&dkCF5+?6Nz 9A/bBC5P=k^>O,1XH񼸭HY+ ;o1] +y PlFl u'.N!j3QiPL1ZL}v +D6c'Qd(1.Q5#F)6s0l R'.1-dPԪ(.#9"MKh(@LD?tҠUYF!,zw2iD׫9 qgPWT@z1f!/ 0l+Ϛ3*T,6RʜoZ.*:1@ 7r,H:rvq&˭/ݽk@=(i4f \c/rC @ k]2P09K\H6N!8A"M%.w]kԐT BHNNp{9$ʸCvNqCZVk YU4pUb +X{!Uq*S5ᛓ%0e8STϋ:d_bڻV LN?YQXʹY@=7H|5c`d.kzt \ɿO)k }\S`6޼€A>T[ 5ϝ"Ʃsq5뒑5k  RrOۋ,~WQ5﹎Swمj l +g(_|L4 ¹k.* i:Eh3^7URf2Z%^{hz-{uAB p< x;XPͦ;`nC׺y <߁xZcR";?f' PQfpW3U7%k;ymc碁Cԥu]$wŹ.++ 7K^EWꫴMw3AqtPu O{Xof'՗g=' +Ò¬B`v՗ ͫ=CX + }PaP=LPاNl430O_!MV+ꅼ +?逸r4$Y,BF*=' +<i:RF]+L67TIdS1#0r*揠[\f#c`<$sЖ6Bkh8t菺95>Pl譹=~o 9i[q>58r+1ly(syҰ1Ĺ:BbVͥyikqY4cư#>"K@Io~iLle/ӑ, ' e}O +Qn!SQiv޾9<9Pz nU>Oj dy%)!9sakf&׿!05XwLeKi3)CE%S/\lt][l_.(4,"KhEP]!7y!0 -K0$Sqdu$m/[LN2ݗ^_oZa鷡*suAx{miM|5{&{cĦw//*P/mJ%:霹`Ģm> B j)]khyDhwNul5mqZPv`kC&nP@=αreOD;GtAi0Wnx#;`[zzxK1Vu/[GmzSTޱ +$zG'<C{5j!A +SCyZ&?q&Z6sW.%8~-8\^v@¼[,M+ok9G'10IF[**8q&|R"6nR$$ެH>bk~Êl;ܝ^0b'_8QN|{É7O9fD$ȉ?щw;*r,l< v; -$@J$B!_|r" |GpgWAU*2)I7*QCbXڐTϲcum1rǣ c6hCp_jsELYA +A>T,?m¦~8\0N ?FJ& 5)&JF䃃:8a\ȱIr"i-& e{u>`fEq@ lP#4x17LNc\`^gG7!| a&CB'מ>?|0Es\xk-Cy̛ k`?`HUd GU-O.p(/)PaCRD9j5PNEgp+5̓zLfEw1z )&4va9KU v!gm&˃OG_)Re^xI 0j-%Mu f'Hu8ޤʃx呸d,D4y*eh蹦mmk&5ysD#>մ路4LVT4RP&BEHyќ]%=68=`Sw7!$Ta)\U'>0ْ@+ȟG&V^ X 36Ϋ#egA}'څ/eϲQ@D(@n#)Ik  +uH>@*3S@Eu:h |puf=OQYoc[CTμ%emT|8 8>us9H`2-R|f +8@ڞ(8(\rq@Iֺ|8@sMSk 7u +2 %YI@3nD(z/CZ_@orim5Hԟ<'[s7ݏZf#Eioc@>,l^H#h".8k<!+澷{_$1 ȋc "A!0ɴk9^+cQ"ŠAŠm8/c/nK4*+zZLutdnDBH-81047ul(MJW(0mi ]KCnpyKK <Ŷncf$άMBQ%{fpa餣)X==V*nNJ@AM-଍?CAu N,*EWa!}b  MFc)v-%d?@M-5ǁL9@!L%S<{!T!% ެr_۴{i.$OMNβoɉ ]Əz#r$@\u)}ֺ!TNȋ0/EԵᵷHG܌S&ƎWUP7穈=jS@)1 2SQTp)R)m1LGo>,9b2IGC`1yrߏyO\o57+["$2YQ4r^[i{{CAX;x_WRcbTα:= +krY܇/_]YϺk?(kSz"V.pYvgDW8vT{:AJsJ!(wIյŰ^_xQb3~`K/U *gTQk5J\9FL^?fMLXOpwV >+M >%^o"PJaL }~J>~APWOȳɧh+ Zzi~C@k'yaܳ)@FCw<TOp]x2UUs15}JT}}NrtC5dV&xyTuBU$[nO;)9 +j[c)4~S+wg|Xub,sVd\sFtx`B8̢gstbUS\}]b]|k+\XCul|Ȗgf0|s+4(Bu9egٶ!|(q_7D6(.)Cz,'9*??o+R,w^9d;ɁNʀ gi ӂ +T#,JFQM.7u ́/Y6Z xVR`A~+bƶej*DqJa p@g{hȚ\i +ϹSǜQ Hzt}MEF}^iv  EW7X(l A$%B'{ dTUwo&%b`+ +0TX oꗽ ֟f;̾\6:IFk ؙ9<S#U +}5}V:*\d6 )0R][sD^. a'kzW(C}d ӈK%bM]<JN3\-uYD{lT@EV[%z +z+'9 yeiwTI(ӈHo85EGjd'bSG:#B/hTWeмw0=?#LHjUE(uѵa*h"nA,y +ҝty_c1 +6>O}܆b>;C G0oo,^FMϥ$'+wz/Z~?:ұlwV!% !u-i +|զUl~5O+Ŷ:PZ +I~zTCR_شÏj*&ū)A=謏.Bh-.bR@! +RJ^3WR +R +> &AJ!&6bϱVRu%uӪKI5Y+|op+)ywTKIʪ${Fs uC, àhy-z~i@RigclkD'jMP#νgFX\qr\_r.nsj_uP:*\jmʔX2G)Z!Nmj];Ŏ=~<|[&bSPDt9>):xѨ8|#'ܐ#6D<~ecc\~_h־? `_3DǃDT5lc[&p"R @fmh w=RA-O;UHR 5 (+"zߺA`累Fs,/ sBjW 4mRhW! uT\luC< &$]@3iPռQ&Poo$t+ N 7ȉ@v7dhՉoI*(+z˪ՉDo +._O5!> ~U@1JJ[}n la%T*TmڐzZֹb "rS1gōhNf +j5ҵ^V:icJHC)e<uv%{ۼkme ,-B8;~_% {DS8arg:}ϑWba;MG„siLVv5 RH{"縎5 uk!Rӻ>%r!$P1"7')GarjZnm苆I!k9B\ɲ54{EJ>q 6{6(%[&O"I(g˸A"[ka"$eUA |] [RȤmu$6Vo3)"FE@v* WD:WeUJ!нIj:O<;Ouqlve_yK+}P:ڴoX(`Ɉ@xDg) +ua{-ydk ~CEordrx3Ж[mMt7XUBW5@ͅBfq3w’RO5KT9:*Ss㈺Vk(BX&΃{Rh~\` j^t|QN1&mR\\/ik>9sCIc =кe O*ǩTjI9,ZJ%q? i֥'mק x"V?ҩlA'673hM djІ4D7,\$9mu5۫6{h(*e u +o;/ס:OvI{p sNQj8ضv,K헵C@,V̒h㩣+8O]C Ρ;{!lnfWA-yU 2׊SyB4Wi3R U`iF=*p@}*JÒc4J U0]*6Dx1I[,nnJPdQōBMkƈ5jWLf|6&UwѨ߀gi||+a|'!c[G`\tl~4wa7?1qzj%8ühюRml.HV,*J!Cl`x環g7^-eІ*g1u*$X/{y}~5"PSz ĥe.o4Ssŧ ChyHJ+eOE{ P g&^ (bFA{hU~#!l ݊Q72ɐ=IZdHn!/ f\O;[4>>1l[%,tBifhDt PdW{Dp;cHΑzii#$[)zi\?Q 7(H2Wg2"1~gy nȫ ܅%lD;rs=)șd/RgDc10'.y6vCWDL#{[SVMӸ]-u c ^WpP>DN A& DZȦz)CZ@Qw*֯\/HD̮kX '>_ıG؞^T>R|xt =I!٘DiRe_ιFcBcA\t+ ic!l`QY_4)u4YfzY }jϻgT{aoqi>X QI׹bW!7k "Qݣ^ H^% eRp:rN)%#N2 ǾO-Dx9jZǚ WےƕcME;oS@sa뽜j4ZƵk~ՖNeaWu|%{kd>,_nΞC X(kLɽ61RQ +spa#BS@`3I#4z+in c աDS@1Сs3Vc"G;קrX-}9a\y+ +Ds;ӶB iY`x%Ϧ&CKqA( UqsIլ[g'ǖA~~BM<`8jU*j8H£o`M٠#é٥׾EMdVwC;| D?\!"嚼mxyGX#B7toWf"5yuox&D+5D + D6H4N@f<ss즶F^tzc:`+Bv&V͂{0Z=_.iEʐNvh `#n'-*QF{JuVOCeW$B$(͎˄.YsˢTK4Ezc|Hil9$=^Ae|wTAIJɣ7K?e6>Cfb`Oĩ^\δB5R21Q{x^d;): ^6{D u讷9|8mߗ^Rs&S@Sj9_OJuH\*TN6q}B:%zu}tU(n_q5 cP +VݵcP[G2 3uNegFQu/6VP|)˺:dSFcDTG0gל\D?: +bvCZ))|Ʊ<^c*AX\?XyЅF֡d + r<j; ڗ?'x Ġb6+DOANJ<ĺ+iЖ-9T鬂ڝj<&7\7sIuLDº kƿ9\3FpvV +5ean>ՏM!5yաs +Ԉp;ȁ!\TJ+#*-zmDxz9\Yi؞mAKj#;R0 ' a^~(\ׇt>_#+m1Gk0(\ j џRmc(R휊RWT"4Qˊp,&1t nfǫ&>cP\ +{(j: +ΚPC1$PcQTZ]-Y(p+>*0~|LV4S@qE<2LX4zzwRvN];X>)5`؂6˂X1pm'O +Ԣr [;Ȇ D<Ֆ'SKe:cEY"v!+EB~y;\ +-" JOf4cր$ TZ IgA = ?먗$#T498ؤ ̜o/ 70oD#VbuD ]N([̐"!n6[M?lh}'_TdnļW86^f M=@z,veq~pOc0MuWHg뒳bpaT/̋-8y{=%Jk[y!N +>(H Q`0tX8HB9"d86mi%g:>id㚸GijuhrjҪxYhC*xj$;BP.=5n=!\y%Zs +Ҹosy펧9!l.M꟠߯"X޺ [@g/mEfOOˬFUa) [C#bFh^"Sxeɴ5@; $ E}\7FPvJF\[ Q؆ h tȼ ;ũ}ig%րf{Bf$x/c83kQ PT)2kcz!: PL4O(eBQ ¥6fDJɴws#(sqK}eD`!1rhdrkS4uHxCC>,J'dҥKD Tz61n_z:(۫dTj,9sJJ(׮l(BQr-|$:/6r! 2qV>sA)"q -]TDv endstream endobj 50 0 obj <>stream +Ht, `aBIAA)ɁUV>.GPU~|MrO G~\ZπI-3wHD)5yߏ_~/(z0kˠzdZ ,yB b.f2;A]ٝ{{8:ܟ; !ry"amKmF)PG L͑GkڻD~p5- =o j^߇̾ KYRQ΁ +킧.qPK5Va i "S8Lj9Guқ&Pnq+K}*އ 6p3Rr&7%!Mpk R bk2M#ш\E +8Q0/\rHR(U+5[u/Wo0 Jϓsn`#S%GjY 4~J?jY^Vi ^#x,4b<)[L/Vԅ3 zZCBe 3:]'Y+֟ü_a'|F*w0젙%l(\'˙H1[t.#7k::qB/͍)~m<_ψƯEπ]ZbIZXUk1D%y#&+#׹Fb!Fs Pc#WՀKTe +Sf6h4ZW[y?0rż/;ّ7[GOWIP};Z!Ga_Mm>;K[swĉyu&hI6K21bؙ'A ,ڬƒIZ]l<Ҡy ͒(!r-|Q׭?!O'-Lopn"Uz/}8Zsh/ڜg6,2SݦGuFYcނ>aEO[ I羲 + B9Ε2ƿ>6,%&!IUf3["s*zWַcOJnbއnGeC8 |hGS 6_k( +BY7}ulƤ~ (-]1Ԕu #c#}z[#Þʼjz,Q8 Y!mǚ29,A^p6HC&!ҴqvHXZ/픶N +i!B{˚atH"6CNd5/6?Cr#%J}BAꖬ0ɬkd(^/{fΡYuR$uKH ZpSdLKX-19Hn((DXOq'>7u)J +j✈{]cJfzHiE{V .`gMe;VGQ)JNQPRAs\3p^kɳ~ jZcz)7;B,9 '?x_ + ZUkVY0?7vmRbqؗVQ,Lzdví5|~66GE4|ޗZ0Ÿ^ه(l+6˶ȘbD x ^)9n"PB(5u!7_ER+t1: 8Y}^ሪ[=> C,TsXDB,-R7vRZ7~zk0o=JްYe8Rg`< kKgh>Bx[_#, +/ TaҢByJ^:CDc 4RO$_zm[Z[nMi=C@]&":y8C?`ehϓUꙫеY&m7Y'+|Am +U_3r+"Hߚ m9D6t(5 ZqiA!Q,2Qø缡Wɬ;Y5k K&zJ@:L7 eq6'JhՑioL]p3=pnVkdXwzxXo/_+V-P\zPuF]溱G~ V>Ѐߧކl^j=eBdJTjE6Fy¤EErc.Qsxtdf9%| g+V܋E0MzK3~ =%^wBH2†Cu@'P(SӀ:!Ҕ6.VyLM~KVqf@aU~FIdP;rHQw-B +ۘ\Fk<C'mK +Oz*V+.E! ;y= +kٵK"·ȰqR.RCضY9BOv7َuxN;sP3Pv}>1Ѱ!SVفeN*C%Ч_ ];d4=Gln}^NgEYjqǺ[B8ua0-xB!SO˜ω}&`}8,x f3Po )Pka@5fIH6u,¥ K"Hȫ":sUi'Ey:zfx9L *ajY,q)\Ez̆KqG|+!F5_Cm(ު|7a P{%zUja}J$ϯ%KбV_dgTbA`lt '"L8]>#*'ʪk.=YFw]; )[T{ZI*Xk;eƥy*sJ|6$W6)" EKF(jtU c@u$x*h"z׷^~y o+MW?~VTᅡnrDrhZ7&4$7[CaטuV'1 :\BҾ< *~u)WM1&(yhL7Fvffts٧~VP!nn->݂ي℆:ц =*sKn2RBۆ Z}Z\=uv#dpǝOo@C 7l8eiW fsxU~P}-ZM 5WZM!i/e-C%lKT[~8jcWCǵݺ/zB4u%^dsNJxB{}i2OnbP#֩*?v+ItH쥺&"rt;P)e%Ag# ve8<PH`pk"B0&A +;mW+ e64[ j_Eiz!8e +TCoӃ"!K.n4r"PϏ~I2Ʉuŋ>&>Զ2ԦVꁲ +P,*V&zU]۵ncT7Liٽ5t0|UoP6ӀPNtC7zTdjaVʼ/x&afLuZ:} +䖯u0\5$6 ՝o M"=a'ɥp52*}VZ-iF@:52^k㋑(*rFKgP+B1?{BgopwMvwoTDVVoʩ7cA:&óF0'z-\HeՇ8'Zqm^ y _FA(`>[IHӜʰTJūb2y j-b>$BQq3?I=\kГ=:H{#Uv.떐>N)j\@uyӹȐ׉cѪϚV?VKˁS1Z'QunJ% Iʅ{J|6xBO ΁yuO0XR<a>O֤ fעүu`lqa:OWUl>re/Y_iD\E* HrzdBCh8_Hk!)WQ:Rh{ק݈"<\J4lP=jƩs]á۬e+Ҫ2ֲkojnӘQb3E֋#fpyW!m10J~n0 ɹ/cMDcxMEÏVN,o>5)AH/@OL[앯1JZC!sem^W =G/$.>nBe< aKE5-OwzW)nP#OUǾD !OkVOw#זzWʙjƁ]\G|w!(]gW-m>D{2;npo +tXCGk<⯰ icH׼kh%BèN4dIbf Il:]=/A/XnʺJ\`(̯_N#YfS =|<01x| ~4tʜi%9R6oPdt +/tĽ +& 3$Da/`dL=^Zt|sDwHP]㲼m)EKqßGۑ^^zE_'s@:X)]@XV.ˠ8[rM9 ޚ>_6z*q}0LfvK]Ы. ɲژd +kdf XjW'Ia*bfu8]mDdƍrOA.p?o.2~lSu4v!V<1>#5y-[W0J6&.MS„IWkڊ5Yʜ|b nƴBY)/c~(2{F iތWNZӴʺb\wqTT12E`Wڀ搗].r-?lVķjXVXfO+p+|DKNi/%,J&#>qh5HSNZT8,Y!ƍ<!ő%/WS +@{iZc\%^kP)9eL$a7TnW9k*!iik] J4sis!td!HX3hG5冻:^ſEd(cX:4+SNaTHf ~aoNH݈'9[!OYkU' $;Ux=l//_c /p tR߸/ot_We}S2iu&F#ΜP7uD'ZJ]V]֔UW1\FO{;,݋U-i 6(@CȷC%m>t"t'/Dq@kfI=ڍ< {0)uUe CZvU-[ZCQe-X. !c +̟$ÿ1qy >ԗxTf % H&iav^AH~46\rŠ.ZzB8, d5gROJd +YTP + hҕ׸ZTf`TT})c?D Lw:Iy9&{4sw5'f+ QwY@Up6dOzGj~/ʧ?2 V+4̪JKM#Ո ʼ JCۀO$|+<΃:V r?1u8Y-c%:ػb=K}C'Bz+UAΑCmE&֟C &g{ϱR5/+_DDHmpi Y|X"e45yݫRԊ2KS[ XOd]Uh;{!5vyk,$^ 0/STpTՊ(XP(t HibVI;ȴ!qly,CYLy h+[+lX؋]/0@SRH%?GL]/) ,Bxдr\]ͪ:-Lg0j>c+._] IHq3~rqXK⑃d}\C\Z#[tSAh15OZ5Rmqմxki.#VS`_X65@4zd`[4z[ƈ>{1bض1pI2͞$'h1"K1>Xt돊]XN`%l:*MZ2iE>3-حe4g他,-ID9QSX>H$&)CVNNÞY`=xobmu){4TDgKRXkKmC[X$ :\i?C}oi 5N%iF2rHEkm/Ci\ك|-":˕C +?V2@?_ &0H$7i|ApkUlT즦uQд-ooMv_Sk$46@(I]j\u+Ҥbp~uAl0yk<C/ąDWig[Ьj٭_&,&c !E١(s%9VQ=؜%spŞ$ 5{Pڡ30w0f?8uZn " |(ƬCBDtn\ը=c6I,ܜa^]?^~dn ΅ nXZxvՕoT rB )4iR7gy[й"͌BǢ.O9h-~r1 XXFm*7gH) 3̩ʎ l9C< +8zTއI<9r_)lsmz +32ve{B3ۃR;sRC +[;cA]51m")0)za 3I!4Nʿ@Cg&瘻"ÔߝV)uP ߊRMBѬgZ0rZZ?;ŀFv2K$̡CHR3,k< '<Q{GP@h`ww"aSػr뫶!UNQރ멜O8P9zK![vuUϰIByXG}(yb2 ߨlS9*+ ^!5@2iV?MťZ?,>(1~qDd֐4q3kJS6rYz;|ˈMk +U\=ȵlBh)es0--&lcoضڑ3cDzy7 &{ +^cG趘*.nY\6w x ?u[o Q1?:G=nKa0A#,)޻w f_߸uP'7wp.uK$і-jؑ{fiSEs+L +E, Th,=(`ȪRvl$ Dwqڢ@'*t梙`A `g5d)Lp7!JnD Eq.DV +͹N0w-(_E6A95i8FHvEð=EbA/aɮPk4ĹCSk;fÇD9ϕaF` +eڽ{&7m{8Le27MeM@Qa*A?/ ~G^?e"1bF#RbPn#Eֲm(f7{n5C4H2C?jF2,l430.?}h|{鷋/.~{8|_狇NwOwˇ叧vO?\/4%Ĺ endstream endobj 51 0 obj <>stream +Hnۺ ԇ$EQ_qcȡ}bC})P]X\q< Np]oJE'r0uJtd9]o,%yĔxwZP|7ad9 /'t-!SD_sq^S90&GK G#C'*p$$KT }8y T$@TKf4(b8- ,F&4NG׌N4#*)H Ck\*?i @7J,n?# ~t3Ӥ_hF}ta~D_M|,PMUpdLi)t(ܬxZ>7=h1ƠAg)=wfVN oměp)xy/l?'6OyaK%D&'bژ4 e;ynf7 3y|[ 0`_JxewKYG;h]4Ph52qž +͓O7E4Zcy;=Q@r I} o wAT$@ԢWk1ʁi>/hmBd<2tS f-ŁIY>xaH5:k[w%s7 clNڲ>#&Zl4VQ8t㠁jnLS[!n53]a^mo֊բ <Z0fiLχ/bl]{w큔/ Yec%)HL^ƴMpO"IEF[5#.r9 rd1DA@BE:C/^ $IcdT}!$8T7;}nvVg'"ν3iD_nv4ݗkݭQoA.x:Ni|vo +]omvUfxԗ뇹H<;341 X|@Ma~xUuCUt;9KB,ɱXӆ>`[LSx8k7eIU}@õ1,[ A7dYy Tq%$V:9%韱_c|Jef1 tw/lK} aC7.|༏&y4D1eƙs,$y@oQ44jEӼ\|@Ma~0 + ]E+9~X[Jo(S()MrffDg%|R-V#6!l.5BfF|W3EJHtzomstK߹Wպ_U\a7"%L4\K{n|vo +]omvUfxC.l hs<3 UYG{M]x oi|0Bl +|@Q5"%՘;f:e*%ŁXI\Ɍ,O)kgqbA8t1mw5n4G$lхgyOz&*w.od)pЮ׌K3E8!_RambhH-#< 6ԦG7[V ^pWCh=A):‡ݬE\h1ko:^H [[c&8SK"ڗ>х'9M ruE ubL4LFBMdf&T (|i>/cWDQj´Hq7"d+X)S M!:Ϳͮ D!_9Vh gǓ }ߨԊTX*3$ip,`a_$6ai^~2Nቒ@;k=əeIU,?ڄxNxq +]8'+5\Ee`PhsES\p ᘥ19R;M"c"< ӂqtRI$jb +X2f,YfY2]آQ>GC$ϗ$FlÄ$Q֘ δR$Ȩ1F =r` wՊRL')_ĪXxўJPx.cp5·iC^%-#]w0ʗa18C&Zxn3X }, Cq4P-ÙǚRo!lցPLunB` "mށG9yHRm%&v~K_}٥.a0_p \h1&.㛆0NtM~K$RDYm3}I*"E#.r9 rh 4t^|I48ɨB(?I$Uq +_nv&p"N|E<{gOQӍntz>:ge(@M1Kcrk訠 PyKb jq"IE؝`JFI sͅVoFB3Pm\UA诔F47F>YS'{߿-HW_uiP A +ڂPѮC($҅8s aˆVisBػ_ +;Z6Oz1FD][m%.q2ݗ? +蹔]P8i˧,S]|f=ch*I}3 +x"%j%U89#:.*Sg<[|p`2 HW+O%SxgT]M}*>kۜ-G' ))U(pԞ4pB"5Rm2u6l}4M9Lا%ϡ9q%+P aawg UV0RE5M*M먳[Xgk@e#^xL/ Azj̱'-wQ&ɬ&k/螽#f *O1ENH$+¦owlgKAE'G46;n(ppWWJ6=ߋ59qM"]T5dxڏ'KJkf"F%R0-#<< +} h574 izEku4Wj5[#kDM^B^l҆o|K%AZVWhe˱W0fsC.kM +֦9X eyc )#zd+P>89gԧ~VV + cD>5/aPqb8D30oL,nz%jRwCw~ɩa}'0(̚څZʍXRtLPE ]9% 5,LR" #?iR:*YFt endstream endobj 52 0 obj <>stream +HWnۺ  wpFeI?vYċӢCoQE﴿vHI-/u-}[FoQHP/CzR]}FXf[pvwMInk#d5~ϳ;_ PMOo~q_X0>4.9̅~I +r4FՄpPBo ؂X d>+'Z]1@*-_[n}wI\ c?EO@Ёz4m!6 E|Z zhB&$JI6̔v II߁$sSTTDŽͿ 0L`yt .a$'LaiT2%~8Aq 8T]%WE'?x%j4:ի?SNu sDk,UbJeJh{Xpy<#Q4}xxirێõ{h[XG}c߷<٦ԨJpjonwk()S~;bBC`"J2x8QmtS"!=YCڷcHS>Q?G"48)8Ply 0N`cJ6EH͛n#>"K +7xvYoi:B$UToD2pG)-m e䎢HJ.R&CN2J"tA4j5&}a|}Bhٽs˔za9l(! `q3S_sJ#]y Rmڨ0d.iCV`fb 7Xmi^vmow|í qb0w +nV9:~[NǷ._vly~k;pl{kqt1v6 Gu0;svt[9]dqɱp'@ +S@]Nr=pA8;m sk9#d؉IORb"ROH:AL@c^(Cb4#w1 wlU%z9h mBFG+ w*dNnWqSP.WUTIqO 8,"2N8 +EDB%[LL@'Utf `@2x8V0$aaR +#j=# :|ua5(0 O+ 7Sy~ZEVo ֢55M2)IP7"Y{vlF>hlԺjW{L,f>B,6n)Sx 1+JlCpWC`Ot4t]jph[8F_K1p$lar =ch 0: 72A5Wa5w߮s6|͏}.Z5{/`n03QK#ɸ2qL2^٣MǵJ,RtA$bck-_= -y3RʔcoM-ZRs>q{  6Z-MSv"иv(8J7s4@q8#鐩1I6Cs\HUK+1`DiroR'*r=o6a+Q+,[ABNkT7Y/[r7h[l1yͼY\ߌW vsEEo؋ 6(Ĩ k%:ޅӪ7M2w'/BWAN4THA_i^@7_I}OJ;QwQ}3\^EoNgLUm]1ӉѭBc>wj?*IH~B]\cT~.y}Įˊ/o@弽,ce#|RP^Y)]اk Gd S 'dw'Q4`L/~,M̧qTs:4F0j+)i'(v@P$䕠h/h,/3{'M`%!!?To&jkO$ߢt0wYhH׿,jYt-(B/+vWR]eY,௫ +=g_YG-I^М,)$J@Z12aě] &ި)QV"Ϝ!v~ŴE][ @X :I׻d?nb[7^Ngva 6*WB0{PI2/bgo]'[Ns"_a-lW{7Rt܌Po*箸V4y@ȀC%ʸMUE(Sspnt OgWWs>q~ + +ςn)HgJEEhE_g@xnw*˳l*͛tcc[:*;Kskq 'Z~g2 78 Ȼ,@ _w>~&2dp/Gˊepͻ!Ԍ Ƚ8?^qIG)MpIDN*_6r̅)=em6Ñ6 2D` 8 D.#ӈN]v/L\Tf*9sk:sN; mm0Xcwzv{JTH4'!|#j?Yr3C~&@O@ }lXT8e!*yi5(TVC7-&!T8w9l%עRYzIzқﻳ&Ж#\χAqπ$h }N}G?x#b LJ\`ʴ#?HRZvgqxnaw\EGAym:]'E):b4R7IF9n E}/iTZ9F.eԺ;O=T +ե{{52 5r^tf$r@(tDo].u gg ]MIn,cjCu"3$-8{I EX'qO-phiQc(pV6iNo` ױ`Y;DICQ%Bv r /MHKtBo}=_+QGGCE6yL. +x}pN+}2?G+NV~Zߪ {l<fߕ֑/T.8'90MFlp~z!^d̋M_ʔk ,Q)r(v|MZd.t:٭pMw;M:4lGxӊ ̲pw=٨]2;0;9A08; +_&GYN3$6ďqf8/L1@)Y;ό6cQ(I]oh3M֓-!&zIS3#qSoq)}c$aD؝rj!]2j"|aLwH2:TJ"dRL4 kQ`zv|RoȌOOa?Y@̸\^I#X,*k ~2`V>G]}敭@PB&wXoUIK]U) CX<<4F4.}n_KbNHK.CD׹I/9GźK^ehs./1eN5\Ԧ΋(2 -3̫O9Dfhzpzp,SD5*1mOV@1"FHi*= ~y(8o |w~wbAJ_\\+@&G49OhZjB7XuˎGzN~KV+fL-T"˯Fg޺jkkn|\ALfv[m}d`ޘGj2y[\埘 +/,9KҒKT=`iaIq"^:|k8I"miFn6)uRXiz0_=m$g%6|p[}K`}mXrmE%ўP)2\ &-02o~ *03rP#a#r3+$AP6-46*zs? +@$R^I} WU(:/)-[z4x^JIV[#+:wMḿvj;^m1<297u:͵  sTl{T WE}FPb=.`~6Qg7NjLwlZry)ޟV=YP=>guI}>R+K1%(Rc|7qTexEZ+QBRc(ljb7|fAlEGGW-Fϭ%CAb{&*, t+IpPz ܨQ]Tu}!IrDTuѳ_ڧ5* +U( &b >`'a|iK]UeW$_$n +KAgo_UˮmZy"r ObW؉Gts0R?,TY;79}]`TUq:|!!<~l#Y,O!ߛa|m\j@p6B{5#;%y:0{#gWOyT?{$,Xv&phe{Aǽj5sū]rpT<r0mxt8Ui֐jIqKofp k]qW:;,x?Oݪ6V̷buӛFub XZΣeuP= +NF;Fdy.QjB +۴h5t~n^l:l&҂tmn>h м>=-:~*nI6睡h{h}s"h`D~C(Q z_4Llp[qk͚ +O&c5(hMRqlz'Lpu&]h<5@ڻɜ˭+JumEM^c#/mjJW9*.K{A#S1[{8q\o/5xc ,wOCGw ̲ɣpI]lxW_5ZM2BS5ڰNulSn>T眬QzkZ/QK9dWG0[Sץau Rb _6н՞ڋ#͔X/PT\B +=@zHus\cS41b@1U_0q4/An17/3\ +و919@si^1b(FKP@o9kUms .=X[˖'kJ,˺v 푼ZBv~T븁E{2ˁHǷrrk2fcMX籯P[~p.C֥*RԾ*hΝCxi·ewGk~얾dg ܚ^xꁱsHS^XyW莤 .n:ak=eE_yyw^}.~򖈁VpUH~1bIMD%)6:^?KC:l+;$G_=Cl W·`>.-8 Deg}<i2?%U,دX^?\(bUsvWN8i*#7m`b(F +ot{^.^V g aWB<@u-N($q†˅)="{#:7]F9s;v=2/C@ Rb%I&#]O9yCe]MY*LR2musӚz9VhC5v3$I/[NLa}r,ծva_!::BXI+%`nNkF>'|!8W(-5vmQ_ɥsMxuBɏai9.|}]/$ڗh5S}D C-Z4vO ܇~B<̝nv.ASa;q%Ip>0M?Osגń5es]oTjoYI|0& g7EpµɌ|'\S%y&cfbK%˛ KF\/ڪdY.&:)wU ksd:ɫw5avEw"w]EܩWRO&nsw"RCl,,"5RRkKRbuS^f[k3nٯ4Ll^!TJf>7j쑳[`!}smd8E.O)א>'sRĭAqz`WTF8qݨ~vӂw+V-.E\cau}wdvLoX@ U'%cD>VSh UUz ۰_gh6,Dū-^ =cp;v}/}G|+Cqn +JV9WN{Ϛ2(r5ĀGw,P6Z$].z>' z-v)&yet뿔cubdLKaF ՃFUYhӋY=]-/9b"{$ՠľNaU*)}K4> ULv3N_ndȰCcN։Im>k\?!'4F6[I/{H-Wv J@PG}sK9o繱[ +ZnPgc"4$<yFvI|4G=SR iiwv?W(,6U[ ~D@2^C!C  Ąl9{B=߇0(hrj` J;tic[%(KWĽ8w Q)Zfes,,q js\#bTty:F.f22љ|jI_BUA^/kby/[Y*`zY,z'٪$F "kx4j=&2f bJC(w=2b}u!d9*Qv J`\Sje/S!xL8艨;gɣ+I?ї}lS|-FqC؛f/5J,nRu> $#c-4;0%X4[ ƻSN-hJ .G/T)Ѱ^ r'.0 7k!Tvz墌ۖ8LϐnW,Ew=\M3^Z;L]7e2\ VnہcI{9 D2+P_K?ױǯ#lsɊ32:qT-a +:YؚԈee7[l +ʫdՌh?Vr2yJ?ܒ^avN ֌=[%_ڜ8q:$HBȀYU}&t D+T1sJU'Q򛺅]1X@^(,o׹lC왅L6ê:?ӑ4JU8>7T4zڴZS:4ny҉qm._}mHZ +Vu_&|mMyf!5tNŭ< 1\&jˁA> JRi%J%-:53=8hv-x H1"bC&p 萀wT JkNDIưm~0q!ﵘCg~̔i,.Uj ;)Va)^Q^e0r0&6/smZ9+&X_~dzop*s ll8kg:(w:DGKUyyaϘg~dEf/˼t_Nߨexߩ,Ț{Ml4|׺oysӖܓk K_C֝V RM@<cwQ,F-had_TD2P_,)i{텶t"*~f#6 TV +78fPľ7x\(<&c;M0Ju~y9DQֻ\T=fwNI+mfx ak?Ժ ĶCuVg0s,:ڈSun+|wH\3IRVgZy9+3}ɑki&u.wPTBBƶuᒁ1z%8NG#mD;gpJN)WJ #Nޱ'KO0wٷu=2* 8??WiH~Ji@r{uWmΎT7[#uiͯ) SCgθ4e$bgP>GjP"COCPT9,UzS͍C|)T(mNN=&z'H#%b]+ve-feF7Gl|ԉ9ArCԿ]r-%v,qQY%њAF9f]$^-b~EbP +tQ|_8-Eb!%~">6RôUtĝ Sh_M_( N%Er} +_ฤDn&9vJԐ̙>|tB5=m)Ϋ%-i:e|+l'[K|p 7]}PfMD^g̹᡽S/^}VxlmjoVzN;ƕ^aͶZM&p(ByQ֍>'2,1Z~z|;[3We3*ir=r ]\D6UNճh$a8,kIkb+מ Q.i@0NlWك`2ܲ< BX_Guk?\kfGR[5)}z,>˷u 6r +3lоw@ EJ*h*\${o>~^^T(<b  Ĺũ|a8/UE4l<._i[C)0{~\=e~''wxl>3xnbm2fRfp~d_({VDٕ'[P쨾ìbӍf:q +g|}*kV7eDva("Tl>1FYI5l)&5DKmnOaFW{ief !itX6ͼME+ۤ`blCiot·5Bylj*K-犽 R{xhw2jPJZ.7DތGdҾvX F9<]0K2ț\v?mZs>~q +6y9$n|d|ow5Iu=qĥl{ [|~%š_eYHϮ {zސRŠ)q[ƩǶlJuLm^T RhZ=%-f71ZΛ )/G6wύ[<`u>/'D/`Wjg䖤?OwoFya4Agf@Op7ڽR[Dq˔!jn _BW ^u ٢qͻ56oC齻ӷh}Πauˑϰkq.*4  EZѼځd4ףwU0wikj>zzkn@BAC(!48|w`T>%إZ{)+iD9mV82oZܚNl>V6_ӯF4Pҥ+=02BewSgWt5j|WHh ? 9{]?R +BV3#0M툊/.@ %-*:M +?jh\ 'q(E?B_.nz/8re&7i h%Px:MߍK&khAcwt EU۾^Sl k46%U,&[ݭO*{Jy|e562ܹ*eQy*\ԍ(C]mQDjuG(WRC-қm[s5^*nIr +I'@9U X[s5lF!Ō̈́iFu4i3_p(m5 C%/!s;љuL +)6NaJ k1Tv7BkY +Zk~ch 5:E5gj֞*e:#B/3IEqDpxex9v$x +Tm~OL>Aڲ:\o0%=hݫ>f/ +ۗ>QDH F=rsK3 -`T?hͱP!) ib<$,q1qWJt#{5vIڠ`>ӻ!9J`VӈcK&[0l'֧:.,SuY]z$d>>I_,uJ%Ud +/be&#F.J7t(pz }Ë +2~h6*էe$À_=}@T c +f.F$s +buu<7N]*.x.T](Ȯ/HeTeYՕ[3yWڃ4Ӧ + ֚:D9C9ƵQ,n{[؏_gyzhb\2hLp~!]12C豵UU&L#+J^v+[3t(y@| +8m `yUk߽O_g΀,Z"tl?Bj,ݢ!noG_@&1D=%`aϚΚf,LE>nE)*Xm=F@uғ8Hn(ϭg|T@ 9 \{ʌuҥT2b8L^W}CjHr^E.&ʦLkʌэ&Kr[% g4ۤӑ]R ֘4(z갋z6`C1%*󃳘>!bejLuSB]#,_ؙ9kۯNS14RjE 2cv~`'3]3+aj}Tߦ@\4vWBq:ϖQa^:)X5K\0Iݞ`4W 5 ~ѷ$0jDFo9HЂcOnܦm45J~| mBGssyF+Jonr-A͍b|ܻU礔Ժb:XÕCyڻt;KEX8b1~ *#ԣ{@vg^^o[J*{˅20݆z2ct PǃN܀Yd;b弳Pg/]&D^cq)c6AӖe3y +b ڸbYCtfM\}sn `0(ζW~JZrsKINr!HiɁ82TkZA@_H! %P2c%o.zd^R'lr) #滩&khi5kk_r +@7VL=W V(9j"'n%b$$dsXmm]Z|5xe.q4yΰW9$=V XV,arb,>0"Ч{#5lg>|hn,h3n~wz'PUJ_gCsf $=cZVHA4}hX"vyͽ/<ژI`_nD㵗 [U;UGH/P!;"7~D6mH3Y%ֆn(I Ώ5_wJEs=Ui(pebTi=Kzt=dV$S0Mo/Gh 7 reVW]v,%|3Εpi4f[QlQ@0>?o + +}pZW^;Rc|1a/]tVsv~&NN\E Њob1w4y׈KkiOghQ.ZlV(sg +ܻ5 pcz8P!e;KW; +}: kG$ 5:U&ܤo<ͿQ}]\׃WfLWʺ y }Hxv쪼 x 6H9Jm7kE,jβDaF;=mi͓]V.ެ}nD^f9С7P}`we(!̆ky\K6yh/9̎M-:eړfk2:܇ !JQ$I2_Op:h򣂳hx 9:{tϝM^SŸYHZ5뛛+wON'eG(| +ͭ;l-/8f`T,+ng%F2hZY|:UV)Zh0]*|N5S[Z[+&baxԂ1@jt8 Qֲ^,c̫u7IXD-]xrKu3_(^q1F:YeE:0_HG( Pd5)$5uqۋ$5qWRTu]pN.QC'㈤+/;QE@;sES(1xQT6 w&B1X Sԧ~#1or]Vh;vM#&iy$sWd*??o5#{Op?R4ڂIyEM *}o^1nC) +5|qn_NU]J'npNG2KbDǴ6&ѓ)?Ҷ9^sUh"z? g5diZ}P:3mUhFw cH%;#W^z711IX7\x_ =-\-ciEL܊r@}k_) +oNԎNeB72'ذ-yN]*ȓXv6 \rܰu|b5zb^|qsb+ݨC|q{{|Y@wP* T|h^Ms%g|n0;L1&֘2v,J}}_R{"Љ,c+r4_tcgMyP Xxr[*#5ZvwlxP>={5eo7m<]`%B Lc#N܁^|`2gL4:P J-A՛h@R}-U鄝ql;/WcWf$t tE dtd* 2^ĂCOс妼Qt5,ŌU )33==-]UfQ$&Ӟl.w* {q7حaG_o۪V&Dad"ij,㳝Zzœ'Ȧ@w7*:{]VT/|5ox>c+e6 ylDsyXJLGxI<֕ա(CEņ(%$tAPn}.%k1VU1Ro~էXurR{Ef+*NNУ1ОQq9,3kZ`c]-X، 04e\0 W CkTq{,Co_ݫ^]N>)'82i-en\Uâ{ty 54FqC?59هϛ"܄_a ^?oܯ9qVE-޲6 C}|j]+Z#nKܡ`=&֒%o ='AM6P$x'8&-.Ȟ#X o5T=SNcU.GO>Sޥݩ,X8c*OL_܉82`kr۽'PcFYxh?eOz^.¤$ Q—9VuNDO/qi7F!( ~!yupyYIoYh ֦ݢ~w f ?x=v},GX#KT(c>Nu4p+7nc & 7ֱ̳E/\^$a5Iyuu~ +C0 +?\ٓcti tnX%? [YRA\-᜕/O`u' +BP`DZnI%xXD]iYjr "dŸb^/ z{{ӖV'B:9sxHeMepy2}ai'6]UʳK!}EZ}ʀ(. ^dⱐhb})@cGp(p4fI2osŭ-^0HsAԜ󱄨`3>*>/xak{yh֊\ +C UV[gyA~ moov+):Pz]2mOw7ttEv` +mMm7zth`La[FOJsA$n|EziSUcέ)nT^%ʪ(Z(EqTHFyRFdwOk`S3!{@#gI 4RL\Y0l/6ZFD.#yoN;g뒆6 q(GbA,f %?oݴ^E3?v\e |A)D$H}==d]!;fA#i6GzY#d(S7!~nb*f\01BYݣ gٕ̻М4O`yܓF9B~w]+>;p4TǸ 75z+|[I! b5mTS&b*V<PnTx[c k Upcw~Ė *e%O(a EJBW8jyW+v젒5kzd])a}2.K8Z'?˶1[=R؞=&̌uUnDڨ˜Y9eUjYVeY 543OaU(tOëwx^{cB}f4KHvʸmzô${qm?.}9>p_1L.;7lRsx%'2,JHm#`Ƚ:/aIţT.H Cqw{F?IhZň;R$mz`r{<_ح_ ʼnAg;Ģ^bn=-F?ndU1]ؤ9°X82F dЃTJ8e32Yʣ蹠,yt[Y̔ ,J\X{KGI>AO"}Mf!$!}DmX,Xoߛ#hdkcj݂WLC`P _ n+Wp;gwY!-fg(+2IQҒe+KJ}w;x qDI*4aL(ˇcq`vQ5\ uj2Y9Fv=8W~VU0ǒF:T,: 5-5eNK|pKxCַ`bT qF3nIai^Ш6=xR \&Vn0l'D `Ke oA 8Z]}ao+lYzݳ3&vfMՉk|*2R{Kn)zJy]5V{O+]{t?lc ULI(U.\~( ߔQxN ؝-BGN/T v:pziqIfRfc6]dt>=sUo%\1k5X\.z6iX=:՘r,obPRd7 j`CLlQ%j^J]<ҐV׿qMxoU;Plq_ 7Jx?L?3/^?Hc<(Y($(E[#"aݪ+3$=ha}8l=MLj֋D=6{|ll<ט%J.g{)?n}^61Csz)\c56Ӷ7C{寲ݜDʟ} +Ӫu` d"F{ v8uoDң&D_ڮ1`0D-sݛ900͝w-&f5ysCT!OFӫnb7 6T=mu'}摚4i;e1iS 3w.Bֲn V]SEd:-\W ]j¬8GKn{K RlLR-!KBtľ,>R>+kvis.UϏ9M0FE(lq]a?TaiAE(+">Z ]-.ҤߗPlSPKߺG#$f bzs1{\9ޱ]ݶ6Vj{澛Ɵl9PE$%e=tQfc@]"ο#R`zR{_\Y j߀7Ara! uT jCBc]WF\b2iX[AÙD_G95D+۹(1lE)`S | ؓ[G*J9RsVdB |^-qyʴ]N['̥I]Ts$$]k;E2J?,CcʥjUA=2/f#i" 0v7 a(ph9ZQ4x.;TZ,' m#3 ыM:z(X&Rx )t^ Fi6DĬ EۓNݳddc1rΌG?ep,E#xRI4(DBfz2w}unѵX9c &[f9䤹*Kchow|arVٟJf/V w&:=_B?jJkﷱz=n&ZY˔7`ZrO>ZK7,Q]>Bzj=jz܎Pz +HplEqQ*3һW]l +c_]{jEofX1<~@ cr="rb6QƝEeR`cH=RcZWHCKt+w`;>h7Ve9V1fiopn)ChRk l .+ԖԣWMnC?4+mh 16ײXA _i]nW4ӫɄ +|RJjLgbW-IMA3zt?nR}mf#ke4R;U{I5Y9fNkr`_ڠzgr_+,kM`S d`KD}F1ݺ?-f~#{gN$`S/Dt|x߾S4\XJЃr9 YmZ>s}"?j7d9|춱pIήI2 Zs Ͽ4^ 1,Q < "vDV+5//i{OYy6``;U)`ʴy[xC kKrJ2@[=+ +Ļjfq}gUuji`i(O;az]ƕ09L't`,rb# 95MKWkQ?(@SȽ"Rm4s nP$i ZTOZ$PNc] CV+Ġ9|:ƚ46#rfcCMiKm;:d|@bv'w$`8Y@[:䍣fJc :_zL~< {<<&AhP-ZS}k*?.gls`mj|dcGhɾsN`leHV!;7SG[zJY' "Њ?N=m:Qfd#[<Ϊ{B:n_Wm7k#-)bb8 'jڎsvs|Fܺ@m`Pq#ݩVLS A_(qLa+x-q{pբ^I p +A9bTu7}hlnwbTf@ߗf( -5 9aAFuݸ#t眘Pq6ݾG S-(ir +(ʾi,r*+K>d!=fSG gT}kj2V XJ{߹9Q-K7[vkun+eµ'qiJ$/LHS 3,Բ`cm@YY 9Y]^3m>x}`_ .#+{ +{?9V\,c$̠ ]}InZo^Y.@4~)ntطus Ql4Zx 5V/jጵKn!8Ȗ+Rqv= r.MZFk>% +]N>wjG[,p>]EJ +)to MˡNMOn'(tbv7ȫ.Wd$uӂ_͋L"J3FQ8H:96X[f>V: G/L4J;p,#w/n59Po?|,޿`+j㽤6ǐǞrd0W/+;=?BvjF{ݿJt҂z*&AjY> - y>eRnJ,Q}Dz5"X}z]#iaB]7KRB0P/AX t;ų*BY6:[6M `f.\g rhCY&*Jˑ>P/蛫JB]:2VBtb)HWY81@3ZD3wm6w婵k/BiG m[h"z'~\iAy+S%kԇ.hZ-bx!Y{f"|f7'!fQ2¬W;\xt"+dgjWA٬a}^;t5%Pb8˞Uf~peML~?ݒw@Ϫ|wlWƙ5wtH؄Ud{ +_-b+%K1F>2>~R?"ˁbH).DU BPPDQMs?gWZܞLv<g jvs -;ϳ5?T$˽N,\QR^YЛ|ёh]VgF:$w~O|{vvq< cNu]zg9.FDJ_qU +)fģuPEok{t퓠-+=VJ)Ga?բ^I- x$?Āqʖle0Ufmi*l7}ή&&KJ@h^%R +*ldT#uRn?M,黥{C+J[ma +Zi ϗ@P+Y +S7(T4'mJ!#u? c*sν!sQ>途)~ArD,yeCVA9U'}/wZ%{AoTGV PW1Ã51Fakd]avDL:qܓUWnmzƊwNڟz[T*柡\nWtqo_ExP,ꊼ0ʽ(Pjd!ʕ~+>x}1h(0HӖ@A*=H$?z)|J`rpԪ"YlnJIwE,yixiA@é^/5;8mFBbӧǞ䕶) +kjS Q8θܧ.O12[ J*&+Zd6?Y! ܴ|˷ՀL +. +4KȐxir*WȜ63kJc.u)6@Pk#l2h` t +cKjP2lRxZ0-R_;ats_kڤUj^ ?-m)hm >]hi 7U'4PZ˧ +ʾ/s,%Aoc>K>߄j~Fwk[ #NPuq,}=l,"E NK-LQ?d~5/*HX КK7@yrR`zMnX>,* Ucnm|NGh+-_=ë3Hі6+O؛ ΰ`W|u3CUaOp8sOL6]/?j=Փ>SƘmCW&?'WfhEy_F޵ܽ}-9M43rЫO%,bc@Cne/[ecmԴɭxO c ^#(DfYB u :7] ?7|n\.ۍf|ikM\|Ms㘷)eQg2ni5-ɛ@mIp4گgjfR'gs h[/ɮ4ABP8Yw)ΌC`+jXZ-+p+nDCdYZ OiuJSi%]Fu@l2]qd>̹)b슕"ĭ7H, llKA==5}3_&:0|k?ίH*&x.ݱ["n!<:*=#N:>eFO[0Z溝"z)?aP>Ѻ[3~3kʿwSJ& 1&f;?pNf-{3h_sJ5 ZѲoL&!{*>ԩn,tKVEJr4Ԍ]Ypg8M OR|aztԔR_G?NhRJ:ߦ&?h5zz]N_}A&SN&WՀh(0p64BG :sc:Xfy& uS +Mno'ݾuZX:VLsoo6Ɖe:H)F_>&鱡Kxw[- ݚ"ejwsеP$0c Kn15X@FM˫F!G} {) l}d`Ӡ0 ܆ƎOh2"8gB}ϰ:xN'| JcbV+ϭ~*z EV;ԕ Q=>DW+81 Ӭ?ȬْWy$;'.p +ɟbfߋ@X,DBS&7E6ql\&2Lҧ{MPiZh64idYЁ NOIRvT=۩|43%r7~7!2WPc?=^gl'W;ϰ bA4SC~v3|0.% Ϻ8FJrO*Fr!u q2,ﻚNfd^ғ<2vg= 3*Pf5S෨kdhfvS7= 6Lļᴾ)8Ƈb l|*~_PR{\x~N!M.nMk9nu Ji G :MRV+N+M{c5_7{S q.&}kvh{4@<{1ˇeWmSkkԦF{~E[v"N p D<9YvG3+0b}v?VxeVCw' r~~eyQ7qCh5FHPnqd@hLc۔|zmr6ne(/qY.<.%Ņ{nGI;+x.aW9F@xOTDkf꿽ceڕ́W (ٸd1lQ?$3!S52M>oEKR_z *OUs|ir<+KˢY9G v{mmlsxЌ5WIRuxJ5]8#bH6 !eYH| ~=~'"p6hjڶY1-j~{NO޳HyGȗ'Iff&[eXiXb@POlJrx6Pax|>)m'M)0P5OLs/!>HrBhL%]cOn4,2__%&s2T-1\& +Q}Ҁ(g$yzkr2W[ҷϻt`^gE5#mV~5+*Ouz΄+Z -zʴYF/]mq욱+.j ؇O~MYTmiЯULU;Fh +A];E:xbC |JLΪ5 +W?Zˁvz˧\^L=T 8ET Lw 4۩wzs ӛPE<*x0kh +>J~[D=[u}5RBWqVξ[U?=Ԟ/e3kYqJP5% JQjow5IXFY k,WE4m4mWQe m=; .5V&?!C,1z}=Ɗl#L6Q%\| D.=ddJ_٫$Ɣ_NJ#m*n6xn,6䎃i +J1eejjcHPq'LǬ5$k F oif]}LQ%̦p&yRmv3ӲԤ/(5"-S_K/u3w7؝:jw/}繒\~ς1~g+&w;'Ҧ7N֝Ta+ދS /,}<2DhN*µ?VcO_txc\*ieB(ۚq8Te5_ͼgnfiچ>uΌqH~+z˴Ug 'dQk { v#fUiz8H^,ܤ.Sa˥)ʶ1cB[;9օgo\3 WFf̔Z RZG7VȻ٤VʖR(YdF8Ltw fWnmMyff6~z!Mo=Kʏ`3qk]3K?L%-6+s݌6V) rrұZf`+!70ܾƹ):T7>W[/K Pn#_hKM5?? + #kw Jy/v UV-榟;iW%a+vK $ y ]0VЯr).DU( AQ%&AIM(L޵vZm@lCe_֭!V;=ZҬFV#fZs*տ~9Da!,pr:MfjIr Skc[#X (e&G8jvӋRRc:I;ڮu@ o +`X+~t+}Ռ͡MiĜޢOiO /K,'8gczU5nz%@+#MS.C*qfEm_Kvٔ1*cǧ, gff1INKm|Ywɓg3E{u-fdVm5ӓ8@Y<tbx!0=Z]:>{36Kx-/)LfeEX{;fqb*{H^tܬjL!o|l#1zv烍=#mD|D.|^+7 VgwlWYd(Y߁rRp>vZ \vA<ȔU,}Gv7u RJE3k *;>VCnѴ6;@&zq|닌M5[1i^]ҿדܽ%x#YFg*#eg˴ ty8nÝ38yDm>:~P6nx6wؙ!>a#tG\ a`rb=x.m W~Zg,8} :XUx+([_Ɔf{o*c.> hL#,Lſ%F;Tti}X5hUGh?l#s DΊ Hwtn`<ܿҩ&8s昕sߍ>%;Sg#kzUcChGW 5T>n;`ZK8@;/T&Ŝ1XPEW_uѣt#/8Mw=)[IwS-T!3J@p(oNf&; Hv뛂?3 ls<\W<KÁT̿6$oE; 0Z \nE\O'*ZL>EB DKGfؚ}qsq}Hh8[udf4b5ᲀ\4)6r. 6/3:56ʜÇ3NߵYt2khiǽ| S/HNZut=YLbb{')wf +y//55(Vcr0 +C0`p p;5$/S$!rYR֭]K ,7r`l^ LP@8r6*k]q3wCzn,7o&0 >h<&eT0ƭ J)xT U۝2A> twP!b ĔO :oJt@1&MeE.؄tS+XY%Yh +ǮEX!4J=vu*z0" $ʫvp c2YO*#PWԠ9u"e@醊mUbwA%y:QUΦѭx4K!O3Z_n=0\ (9q} +)p]veDoܪ z"6%aaKDžWx20RE&:gWCfZ}jX+5BMDKفl_puGxۄR?p.ywnMN=+:cn>9t)= C 1k mcԚ<,U>2IH{xpRyܖT{)|Qmd$ϫ + Vv[Ơ%su2<twEȎ_e&>pۭ8/)C$aܕ|4V=&j]HLC1풩ADa9P4/';OHUi*DܒP++ᩆ}$X1תnfVtT]V[>U~UgY +#G'@; +jb7zzn 8>h}_7 |:jZAljMK;kߺL/8ƀ<җvM`zL aϹҐقUcm&B҄hE>-%ѥƪzx9% };-=bC={i_ Imk擧$"C%cyBa>FتWm t]MN:,bvu^Uܱ jH-t[UlrJpvCrpIeiK:hb5ݒRkYłNϵhaPf[KwYr:X5"WLTڀ"L{ؿ_^@Q'B2ס$_S-aʯx5gЌ>˘^ +kܪ޹mR>wh؜V;#J|VqekE50_pFʽp" [w );&+R~[ڲysb!zTWr@2c ŋR3"UR!CaP./M /gOeΕ ~C_rUK7Zz:z*yy1d?+kYe-JR1$"sl/FܻDgqSCI]>;A|a)XlOUW:B䣋/5Q PmTUvG):l{^@=\XUqJT*3Ff䌴ج6\U f +J-|G6㖭˖8% md/Ve0܂u5?. ++_ݒd zi=CT~ɏV;챮R I}n ^vS`(M{粗?RQ?\>t8Ɍr*3iNs0(&_-cߘGBx{P&r'[W0:?mP62U˛WfoI;8Ww?z }[ +oPkyPrLEܒI6^4jPeƦ\x#^NYV",֍Q3$…v-Y}MU;w?%]-+ *(Y/H ^N."W +llxyMˤpF?ogsX{F2s5IX|}5-M@!/3dL, +*H^|d=t[RjU/񣈒f74ganIfiol7l0я[#v&w9$y=(XHv;>S$u\"=:8[s); :i)]JvLbyy\ +usU1!wxv,n%1[t΄^`BkGF05š/ n(~f} /L{{]vO6餥.|WڗÛyqX}]hw VjDlp̱ePHf.kW>z`B۞僩QAI c[ c<W46yݦj^:nآEo{*Vm/mZFԠܣY*^ߥ;Yw<.Xuק*3{Hu?=oR 8^Pr3P!M;U1\kn{uz+ Sa]N"Q2t\a$ +Pdm dagoq o47ӛ/%cCʷ\ QYK{7nʵ\XrKA$HRT$`̹uzڧ[U{?R]nFd*wzY"1%z2, k7Vzțp,d..wl-جZZaѹr?M/`Vֿ @VWiFs@|Պ͗5?h#$W~pvr?!'1=5i +]/L5h?@A\ aؚR(<)5RE[_Ribgg۪̘OR 4 ! mc=צ<<~ϼ}ÙN0m$( +{ܔ }XY~殛]/3+t~$@ Ӭڅr~keBnƭ43|? 5T4~u82|v|zHC{JՈE.6ꩵ6ӒY~; J8sW(V"w\~cz؂-iz(,(9ٺl.5{:㜰3vybG0^XsIӭ>/q66 eיAh.xe1a!cƱ <Òn^&^qiz<a^jXq.Mڡπ?6h?v%2O@L)w_beP:V= hQ뀃}}Torgfv6r`؎+*߼T.51?ilh?~ëH][<~2tɵe9# TRT!9q~ȓݳ[K?<:T{3ΫqgFKZ> fUH{j7J HCrԱsʹozdᚇǡa3 >M)E$ 5qCn;I҆%L%S1Of@26Ҧzix6As좛n*d_Bo n5VWYc Da1^v$цEӓEd<'ք+!4CD%,;R{W?; kz^| I9qZGIeP}I:45WB-bi:O {94l1aƏet"EEnJfXAX+j9((l ww!x';V=KZål4(rw.ƨbM[$%yv*׸t{d>WF.WzuX&_>5=h|u2(_l2i) +pW'oʬi kԝm +^9k@{uׂѩu@]W*7y/8v tQJI`;K-x +k~{w~[QSCژ&ᜟݣ{HqLڳН! _SFi>L鬸aP*+ea%׋l#("To(؄!B)<׺u:CLt-` +_A׀5RHO;]!Cl~ʯ}!Osr"!;F|cb/[wfwO g%DR(u#Ú( 6؏ZPq +m{k{V|Ev Gfg@ T: GLs>'eAayYjZnUCd&Ȁ%4S'Ll$ak%:@F*V322:k GRɝ(wn ؜\+ϭIRG\li/Ĺ3,/a@ z_ !ϊ,k0f;Л]9!Xi=o3xo+9 :+3ѩXԓ'AC9Ca85x^܎%&~#! cb!T*4f֍ =(AV򾮭߿x8@`:PNIzirpKהDcJ;fPl;9G;tWv_v Y2~4Y7’ ԰L Az)*{sĶJm|k0T%b"R7.^'JQBm^YLfiJi*m84©5hgҶ@m.: i=M;i*2 =I@o}c Δ`)[7^Z/`q; endstream endobj 53 0 obj <>stream +H$E[p +H9'Q̊YSԞeqDiO!)Ofq0ja9a]>PIb#?صpd4zj*e\? +yQ"qbƘ6{Ֆm1k..ꎳX|?[2 p{0ƴ4Z Ga,+>OUW-Gd߭smM +V`mvS[éu!F۴z3ñ +ګn|fߔ`;/I4}$ Ճd`0bOR4ϘoL\=OfNRKꃤVQ:R9/>so]n|F l-!آp+ IxMMq4UYvpidI1+[R? ϡطjrRC&R|]xNMɌDGخ18қUBMwUڕSm$pGu^<_ج}6db,N1碐[} +W '$?$g-|x`uqWk˵ [@4yE9F|V:q4C\4 +]1 @Յ/OJi|u}³0%qOfi7oc"f0ߛ@-Icr}2k6EԌ}Dx0 `Pct-cS'\Uq*IRAXkEZr:b| }eYɚ!nt54^<[ڞ쭸#%=QA-!m+^7ʓe=?T91%9sTV#~X3ޟȨ{[vy 5?OAYטfGV{$MdPrF Y1[E9z`xhݒJ3 =iR9ٻ~ le +r~t <ٞns/#ar-<ڗO1lq@/7R%Zw-f3%BI>r4hLҏeFZZSbu֌PzUcrTl, k Ý'#8.{j2wKv\֮w,) +I0 {~1<`iWdfP1nuYU} U=7v|N+C["XS߇ܚz9e))q'R<7H-BLtDImVCZg̐Z!C6S +_8TWPT9-} t jE +H/!)~ ;íi^P`E;w3dWY:~N/}?wa dtwlE3C:a?acp&AL6-5L^_`+@"د֬Z|<`6D04ɼݵnebbhNqQ~v`^"!bdS #z7&Ak0mA5H]), G@Å6%9@hC؜wvpYz7VQ3S['\}^b5K%HIU7u,K#UU-! #&̊ +xgyv;7.FkFF֋?G*ʗwST.p `8P6@, +:H!Mu H%inM|%]-hu1foZ\km8(\J" Q4Jl 'ʶ[lVC%hR}\}~)&}mJJi>uF45oyuP}n;~Rj7Z8]~0 ~,vqL3G[*):HIffPAqȀ{"rooA}GXl~6#-kO,+a{GMeTZ>DoހCO䉺TżnqkTh'yS"yg9*Գ<^|J`Tk.t au8f;[+S+#nˌfck!z]%#c/G*&PaCWg༯Vb])sUajNv߄,dʯo2~@'G pw#qB7j;8 +pG7eb~{*^mU 9tv +Qoȱ1At@|; Yl^lYT'CW.6x!&?MIfA6W?;悯pV;G\CS<_}>8KԫUUiFM/;^0VwQ"!BBcȯlP`q(wP~Rx`i}9 25;N'z_nevwL +F4nfX\ g,.,E7[QTbE(qb-Gt˞ RCzCyQ~됏+9ꡢz1wڳka%7Pk%&RXCSד,=G͢HDtn#pҸl$o3v{ھ~Prs9m_}裯UHXiYXuG/l@4y_Sm"+ՇG$U7[uxQD0g!z4 <.SQEuѧ$ZcЪR9WN=htoz&jRi&휊^qFsfO+Ld1pĬ<0cL匧А,hdiO1"g&]06g7dLǮ2޽^ ^ `j|j t5RY-KpЈydCd}1ZI TQ̕qmoz[J3/lpoTjhW¬11תc+D8hѩ:lnnuMy_odosRa֜[:=3#fisc{=Qvz(r:O!jY Nv\ Q{9^cwfR +g;z'es6u&98Jr+1t 4'LJcPr % +{[Ro#?-8cYEvf:,?FګoBB_a  B::k% ֖eO_QhQISSs0-t}GC9H#TֲК A3(zxs6dU9; :†Վ$*6 lhGq.˄aރXvɒ] +˦53mDEo6uu/-"} "Ba8hX_>Q|QC5:"OV"WH.rL{(ר`*WlM4ILVCN?70hS4̙X1+Lm]bOlw=P;\8b ;8W +brZUf%ouF) Al+˨vDEZ^lp~zÏji⛷$'W{,'r%gYj9q&Vyo>2 VJ)XզNJi'oG$O(-1-1=pfgAKi8 _vp诊 hҁG-S0J L?U {zg َ[᳨Ȏ !jҥ +9yWjv7 A_7Ddڀ_N O$sxnQv"cVHDuu:h,5sxUo +_] }l 6 5lC)2weS +̪S+_k:$@ә/qw ЖH/H|w `ۉ ԃSxY0[ (P +-Dtz +[ohIL +WLRebc0r-fU0:qpsq0ƿP3"1i¥|#qPnF^\'ٽ^)=e]03 +wn_Т4os5E:0{ht2B{J b2EhvIfM|}mCYɊ98yQ x#ڹkydvf'cbRdt`pKx vڎXѶ-V-PW2%_",=gfiU+m>⺜smfn +usSg :}U^P4/3|~tMF(lR`#6^^vh-o"Kc +.V]mq2X1þxؽGb>VCo,}hr@_I/?o+Vmz?>˗ҥP|̞trA9[~e%@Ʈ~y85 Nٸ<(f~c-a[kL E]r`j=-}ZzlmƜ3 鹓7j\S? ptS&&dC)(:3Pg!dRW4>@按8G.cU8nYq֖4RB865f;"",p' RѩD-R o(L]8iIȒ= JQmb],F"L5;[ZWNasbNINϛ6SkK.zdtJ!]#U?ͯ2׋Z\Hޠ$5jj9[NetSF&#ѼU>c%ů\62r:Qg<4kڰͨH s$꘡ov&W+Opu&F1!Lq*(PzGUwSv"'y6j{nZ&qO$oY%EBdj:thqlJ;|"Vo8I>AGqy`-At"Ā1 0̐A0g@y>5Su0G9p^i.ͮDޏ4vXm,}-wnn>]_qz`_5A}r9֘iSފJ^lx/@2upnݘ=^.;Nx!~0[^l:||6tMUS,6j1͍ ]CBOyGPQcʨ菡$|^%kK)MԬx_am(>ϊ)Wa3Ekf6 9M؏>X#'OA;)4I1r[} HS-v>+৲t)0]rJj̙jYF iAx7QhbE93YsvȽ,Ťy>c\ 7ݠN"&?xbJ.Vɨj Q! W9; +1RX!Ӧrg̿h-ȞJR{Q)Hun]]T5_FDm$Fyt;Kna~N^={V=2\hSq\M4苁^hVki$}t\xM;/gY^0EO:s%m{~R$-}*xO7AkD1QHҽdDZ଴gT1Wa)hw'Hl|%B\.3@ݼz82æc!Bx1;aVy#Dyp/z֖~a)x<'ACaӸ[ Wby(/Ǔrk>7uSjVqXlQp9Ұ]r>sh&w\Â}9F_`2#ܳV.p|-+p4L8D_MUf187֟zºKM͋Xhߋ=1W3D|\ЍDi>oBsvK|$esQÎ*G.l~&ON oAEnS'%Osuխ[ѺEɱ!'U!gnV.u=KWW3^o(K?S1}bɻ9z n۷Nl2iWjdRT:1z<0ok;fU ӝGWrEnu{C\7(9Jfjq} œb1| wS)xBzm5>[wj#= p TX +Kٚ";RJo菆JJagW+ʙTd}m#>7?"Q~!x;>) +6?=iPvxp(hV-[djMC +s?8Gan7 d;klGS45<6<:`y` +AtLQE9yT} [fފWl%Psi'J^]iRQ߫s=/-bj+Z% ,wk"5RunšY&S>t:ýh]ٱ +hx:Ube.2?9#k'koiJn~1lWy U?Ԟ-!X ]u=vYM[8M$_lG2\2 )qgӤ3y7bcFw̕aW3ЋB =fugX +1{TE/=Ær)s@oKJ!~-y"UӯI#qCʇB9FȕfSyD*:Wk[Vּɏ +OΌ +dJ]qBzgx7AAll1R2:}wCRw ?H&;ݾߏ4eՙunO}l6>0R|4,7 pB>m`E94La׈湒d2\,RSv a]*Ⱦ ɚҬ܋&IHbU()xF Yk0v2[oBe,nk3BGIByl{9QqebSkllZjD!mjp72[퓚vw҇L&xSx{IA7Qzo3CXr%qi8-MnoVJ[ւ ||4RlH2X08eݫ]U>[h5fW9Tdnڪˇ۪O~4@v5[c%jѾq-AjY2gSKy]6z֥uЊ8)7l^Ji]fZ^쨽u"~[թ9aiv@>16*k DY/_R ty9<[7J!{6/VRxR@+Hjֺx?A>+.| v"OnfnV"Xe'|&1"KH;kU^#E저"- , AVVNއq6˕گ8Q >:һ|z(=3ze]?ahVƟu7Jd4tZX#z=e>W]"ݙ  9}SlԱr<%l=t_7?ɧ1Br kFS9$8ޗTmͅˏD'3%.Sv}=eL7隰}y4 R=e];**|~6?O[1X2ϥ@FҐزxeqO; oٲC[bs+{WC^)(!s QH#.`]&oVNUt>UuکVceo^5Pߕkq:M&={IiW+-aeoԷmuьS-(eɳ媫Q]w{g-QE]yE;BnסHR S;lV}(aJrt\jk)2?~ǟ*.3>6 ED< +k82$:Y},7py*JS=*•I*ԵiWcRJĢ|}WNG҄O q'+ yd"×"4L*l38vAh3+8P@c"(י %(nrZx`XoU!h]o[-vH"#{[^@+P!3#m \:EQT,2ΧGF8I%!r8$L|U4?[xsHv Xߝk銰E7cVi  u IR+r;zH0.")ep˂u. |݅_i 6zi$A}_[ /DHOmC]mPxmẇyJ,s -Ń~{/kcҗXw -8˘7-\KҾ*v#QӪI)3z[juf4wQzDFVoɣ)L2Eg|_du/h~lH|[ET_4^Q zeB@J T&vZzlFM9t1mgS OzwW`[* CcS¢je#7k{QV@NNtrt4}2Etb4Oli e|41-nY8h}97%kwYcŞ +mH7n>M0b>|S5=(~vX^upKdAOFlۿ>Fu(=K6Lঅ4ݙՕR7. Hš9cMHNdAlM@I3F;740 +2-6]N f)7۽Tu9kq`ӧs4>PҎ@SWaq2-ȸbmV׶$[ NWzѭ٥߼ECp=|+FHOvwVU  Q*" +* !E0`Ϡ{^]inJ/) l¶qT3oM N{+hcB~Z:YeT FH8F:5 @IW?VM8),%4Tֵ;YWШh{u3{ƝK]j_@GNՖLݖ*S,[%:U]s3cP9P'{L=NW6.yk-Oz0 ž cx?v\&_X&j49XJǩ5~jU ݋vuT/gp+p3!w\8(+l`Ơ!U28hdkkL;X/0eWo)qgIRx͈8yniⶸ9DadXؘaf+ٵK c(k(M L%&;/?uXM(VAb53|6]5>30<^ёW&g&<ƱS}Kٸgjz/yB0x;"اub2ncm~^Bc#pg ոZ D* +?W_!9Vݑkb6:w@5TRB0vu:'gRI]k=Y 49DZ%'S< >rEHP +3dޟcbHP~TGƇ|Ւ6;H XrVNznP^*xYf5ѥ,fb~!]#/ֵ!R_R6#V] =fㅥ=-b;8Spm}zƇ,gZ-$30U멍Nx23M."Ds}4n +(-\3֕:Ӷ,fDET_,vz8a@3ғGVIpq.wSMCS/;}ƔKG?d{̞}0P 1 v֦8* 8F[ݛK8;z"㳟<\؍xE^47틲^Et =~L]?'ᆶWϑ>WZ#p +0.T0̥ms$lĩ5]pPOepRbk\g$ھUgp\ز|ePvq_;oD][:kaD/\"cl!$Eivhep}"ߣT+9fW:'X]ˏ|7=Ycw,iS C.T]Z胥I(^,+:ӀGo.z}v2]bצuHOPz|%2ʎK/z#瘸Bp\42K_Y e %! <Ř_?R +>Dn!QQ#+(.oL!o{A.b{WM +wK =_V%I@ک(> s63)~2 ®x]Io.Z + +(Ywqœ)GtVw5ō7Hn]RTTv +}x8c^ 'i?z.XR"y+gIѶaYߔ#' VvDb߈ +ڠ;g̐1 =mǒRU$A-`6QV%#,=A}9Fk0n3h- Ub . gzqV6=A>r6 M~e1n+{Ţ3)6k)tݏE3a4nvcU :7QĈ&d0ESUQn/b垩/F*[vPD %;BjBE +8P3s]gDT}6iiEAD WOLoYf)rO.D=' 2K+}Sy'F)׿0W`v^Z]HGdvLq[/Q/\8(6Fm7;Y֓K:Ycpäڵ"[ ArԲjcټɥӳ9k{o233} E;uŀzC4>q车Fh'Yw( M#PuA@=[0Nk +<Ɣ / Vt2K[Eʛ8*(* WFf)bZ`q 8u]څ^xfMw,o|V,SM/~oWJR\3u{iN|{4|-)Zk&6<Hp}%]kw*ÏaetbR&]T}Vͼ3FTY ݉-n?yc;QXݫF +ʯjե|$za tRci&4MM6*@cX [N'w"ʍU rϜ!IN\iC PKsgMtE‰©)Us8j 'P_ jte#if{|wønnJ+Rjg,'ac2@hzXpx =J[Hњ[O8m,4WScgۂyވPю)-`ą'AsPYkї*oSVݼ9{䤳z^)ږV0/x>yEJg|uOU 7sx`=/Juh".V17DϩgV\ϲ.8GD2o FGānD~ŝ àrOZ=|XZ-f)|$Euly"m=ի:7Ni2mW]&= +szNi߁ FoC[O@>Kpp%}AӭH N*heVL4t=:x_cTIw`^^e!^ot[G Γcڒ 'N\mͪ׾~Ѿ/wwX=^"^!(᪏V%!zfnd|3ⴇ?db@_t8qb4=\mm\dJv$;Շ$BG5E]?Ӟ'xۋt_ikh +ĥ2[l>kɺ8LLqOP?:o8pmlHeƺ +h̚;'%%(Z@S6!_sf@#R>;NPB'榬@'il]4Q%)75NT0ƖStѥ5n|cFs/g}+9Vi`?CnvYi1P{@WSM7޿7/帲%NJ Dэ„ߤlYGn[ќ͌Q?xքMY)K;杭< ~Pkzut"8l!>͌XNr5tU z_CawńC5>2R xVCw \v pCYZ[;};jHhLL|k T&-&>=6DޔTڇ-e:FxG~tWwӅeF~6B}33w?5 <8d~YŒ]wD61:zXJry#bBs2Oj_-ӍH9^DΤ!d FT\}QF툤1[ +"tvtӣޣ~ +SKӫpn E&M~IOXoxS/vV;jޟQTJg"Z1a1& (mn(jSV*;terzUhi>0Z_=7+q}]`ex;V~xZ2 `Ws^[~d*M7ӵ*ƕzDSWΕLJyklczSسJB{4pqE +YΊa 3Qh-r KC&kuG!(_{>+ +d|@N&_FJ؄Fv჻u+T7sVVou:84 'g.zjNs9pvqI4Z:nU {0r4El]ղ8s;QGrz^4("} +>v6UmhA(TjԴ)%(}]J`~_mRe(Y/ͧEk䕑55 7#=#>^xO4zIu]X-VEpJ#|@aeB$;"oDu닏ޣH7jQIJ ɘ۬xW5xQ$&PM=Bo8c*f:O$plYOsySUE-j؞҂Qc_J=WƟpÍ%F=o/,G]\FH _Zjf;t`n\q e^)t +w㵪vZSԵOh~<0em @=2ľ=0}Nl`'$l]!`!)*楤n=/Am]])6Tq56GiZk\7V>c]Q1ʥuxI6߀#Ge9+^7kP}1ж)Y0كӍ͜SmyI;}gTf}sppNW7C~R4Ѿ >=В~>CH +}|ߴȦnϮVAZ/H2o e`YL5=T}`Bo4bHOOW*NaFl u1~oaVFqBULxCe6)CG`Zzta-K)o~{f̓*Wj$2r}S{wۏa"PqHS]Ъ\_fЯU]0 ث3/+cxtMUY]'Ĥmir +Sh[*T_Ps?cm\5/keO'=VH*u$7jf3~1,:y.YCw-w;9,"M,-^)Pr\Dt{ejvPfP,'_9% +>r bdjQ_c ,C)UM +/j̟GҔ}6{F1S>7i5l. 0).DU Bc#""(&sQx_|7UZ0*e 0M7qϖ,1 _9hH`Sٜv6C])iW+S6S8Oa/@=4f2/֫r d>:Q֗;߅43ǣm?`zT4[^ڌa6ɛ'a9mxMVR lo+>Wp2>_龡rK 8 R`Ĭ}MZ%}uS U>U!a9\͍3N Eou(޺դ 9[)kѵ+Fm7Nfyg~)'[ (qhƠz٢٘HMә{K&r  C;DK3ZoΧa1 jO`gMVM"ху>lSgȡ5A%K N;q}(wwhrېm֨_lgI9ܭvo QPJI< pZ +6yQKbNzY:=b"s>ITXVG /pܧ؟{Ijs'rz/ȃdVF+;,A/qx?)ζ\uuu Мuxd:lk(os_05iiyj݆Xhy_Kԧ!ʲIzY?(ac +=\)[ ?SOwIABX#ڑ|J5Bg0tѣpRY`IS4Q=y];gBU.gk~+ojS"k8HZڃ.̹{Ż1XohT}wry( V,)OŸ8.feU4V%G#QJq-Fw3Rx T< jErz>lʌmBQG7k`ݝQeÀsC=jƱ:a!rYifo}r4]?\Cu~=^՟Ru1+E <ˌ=# YwfXG֠R+}V]:6/'u>җ,Ӷ_)\Mve&*3#ae'V3QzDy@$iT$)P˕7nX].%%{y%6fJC)t~7SYy!yJd&x'YVW8+xPӊƻ R>t l>)`8'r\I_ vLE;7tpk%lHm^ +nJ`y+Ty^ֵ}&pwe=b#ȃZ VvJ~?}U+?Ž*e3Tiu0|$8XD,]TPQK6կQەk`ݛï<8\oQ;Ajmf1NMĎsD\;GmǨQ?PW;ţŮ]6ճخdjxz452I 6db)^Vb9g݉\nBchą4qL"_$XP`1bV&?c_\ eʅY-sTa$ؽH7&L:,< +*8kZ\!Eγٝz&:Q{4 =RW N]]{BeT\0%@V_df{DF LHG ƿM'X&}qpe9V/FGuXC}FFG +j(_|O4")P]J)TA}DFY;g'T&RG:5ލF`l_@T!*ݴQisr 0@=V𓹹&Ufeݮf0ۭ=8*,pp O3}RωT7V{SYv%hkOtaqmwHP;˪ݟx݁=eEWdNa'jĮZLkq ($ -J֔dij<>mޯ2\kls aF垩/Ӥ< JA$* ^RXaZr+H1.Gv_)ԽaЁWkUGP`_EHOjsӮjS$b"n>kc] !(cԼD +|wrBc1Ea[ZD;ՊneC %W$ݒ 5/0S33e[5S/7{&Mfo_#_ͽЈ=!NsWЎ{lfaQ N丕#aX#1rzZC3fPuG.yBl +?*l5ݫB}ӰԁyMHF :67o'g4(}G,/6if2{Z n\a\ $#}Y~Qm)6|jɹg$6AU7'zȨuCLD.OKi"JGޫMPd½өq0CC) T } 2HTa 1-pL: CZ4|M0ʶ~Ml׌65rtʜ6k*Q1\X]_*:J)Dg9y%ܥid$SǷgkoW10s0I]7ra׵)Ծ@T>` üf×N(Bn;MD_`mfMzVp[zJcqG|rzq;e~K.O^ /V[;o"bәYP'3UoeJ k`ĉ^R3ܩ?b+)[bbLMAVڔpplSCh=\Z&v(Y9~+3STwؘ!rզ4?T޾NoB]GQe;Cig͍"mјXg}BT{{&6\JШcg*[yp?:Nc #MT3Z]ϤwK=7ϊƈd.Wy̒gD4C +f26!H0.$rߘPnӷȘKi7(hP¬1{[_3mkN q6z[G|=X~=9]۹CA+q>nST"8Ě]fkq[l qFH\vFR|^ufv2Ԋ9 -J[XPqFW_/W6t=*ec>~Byb"fqVO-=yOG|6vg ןrQy@4&۩w_;hs 6 "c[&Y&yGͦ(QǶoS:~R*lԪY*PWx1\S$۴=T-O$\6Y/,KJ%,R?@&) Z +(ˇpyzRb4تC4f6`M HħO"8bpy|lmmzs9O^wM>ڣ&>9<2mN~vSln)ղ۽8ʏ}?(mi'9p%8iAL:&?;:4vk?c!~-p̷+Aq?]kP.*W6MBG4|vLΗ9"s hţB*ڼ!6^ =g68MlH2<`H)#h6i])i_9/.qWUz2> h2g9]Ea;'IؙQ[8o i8ȬP z|ܫQ U/^W0咕H\M5WߧVrO+7Z|yn.FIXEAJd3+laY0IW;rk ^/wNz }k 0?I\jw_﫤(;^N ꨸~Mȼy|Se(bNNuXy|o#l:rGQ_ ~5Hx~7ps@HցLkƓ rl12 I8ON-QZr Ǐ?健DA0b Db$ b#kUwK<Vٟ4q\o20\ ] \QW1T?w݆ )s:$Sm*kG\O>*j?tW1[.t:D437݂0uw3{)[-^8 -d$TU.'*G?ھ2 +\F|U: +nꃕ)Zy8 F,  zYIIq\=َXqɥG)=W%uAy$%6/7NuP/D ;S} @GL] C,nɼґkWvqd,H`'u[+kzۚ7_>kjڥ d(Tmӽ٩-XJA^Arb)q{ǹ}a+^v.wRqhkjn>k{i jTB :M`[QY.F ¶CAinX:B4zeΙ:@\ +|e9Jx}.O.b/R8ըvv߀0ԝqB1aRg#]zMI͙s8g +\JpWňNZ_)Shnj=k˵\3{عlOh#~%{w8⸳EjϪMuEoƉ>ZOѕ~%`jϚ6ZXjC(Z+V1Yʷ@g./ rձ(c/3744,iΛh*vR2*k +b{y[h+]biQYS-kݹguWX9xvU|XHy`W7p$}x_sZ]1.ΤǷ6:j[WWx,>%JX$lb'.`-[mvi%"`]$: F|}y{ᇈ= +lX}C^\/$M~B;0c +Dӳݝïk&nr%A_+{Y{(/7܇6OE^ CGˎߠ/EgG G]D߿; ]l{e +a?G´>灹; +r0 unHPnXUI78m:iA%5"$-+VjH ə[ @/04а/V^SD'rzޛB9[)|Ā_+V1l<L7:CT{jPyr-tWy뿢 :t(GiGAg9uUJ.[dmegS˴^EKCK᧊K"6i_eǔ>z-]f&⃭< !-ܥVa'"57σXKDVwz4C7 ׿nXҜ5ySLa} j&7\KiN̂%OzBwWП뛊ǖ nu ~xѩ3<TRzߩCۏ_3!IpK*b|^^MlgA׉7-7QwX'ޕtDGqy AtoDAT D`bb %tuwթǷLg9f//elۺ겡[>ߝYծ'aw&cEBivcoxǺ ø};-Bw\#|C%%VgOu@ʵl{KB^4}`D:E#@SS ESoGOڟT6?(\L(\_UGKn2$M/@k4ܵ1g/goSAɅ<Kj OǠXDtj!$֮JߊȷjxK۝K~|l< Bm&=q,cM((}u\ZT?2k~#O'-L3QIWjB=ëWAEpv~Q95PZng!yWBή,U|{.k@8*u'H'/R*I¾UOVTA1G&Oi`ceNUlODӄ <ݔ]y46RN#?l[-CtMۈX#,U^ Cd01B-u|O m؄9aW;J ׊nKc`hYdI,$RJ]E9d\8_8G?ū7c~6b^*Bӽݑ?h:0 {z#4_.ͶI{R35ٶU)HS\mXݲlxA),B$jӌ-)oA8/^pHu2HȐϚL6(-Q2ɸ :}&g_YVbg<_CqdΔ_gjC KK.WtUnC|I}kd\ykBO5'f;yWTfB$) W&?5'J]j@]tv^V qS=I_@Sti5w"wh92ҿRW<`:/xT: %`o +wW^vʼnB1ߡ;k]0f غ6)~d8G5*MG.+TX*uk%eNpŭ]T r,Gn̑ +krk1h^'3Y ʔbFR*cCXdQh:cG>ǖ_)cͮ5y*85LY:Vp4̋TA ҫ +4<J6V2GtTcS'/s'}͒Y?i=ӪoutF6Ǫ=#2/e<@SB[u{CF2(P̀0UR5|x: Z{L-6`g[ckq8\L|5M=높tLk@! } (%a6ƍʛٓlnt/̖劙1nmt +a11jWAmUM@mྋȄ32ws_,O@:I\cZkS}0wyñb[6)2}N Fi9YK?QD9 HZ1T8Tx Q,Ԡ +뱹1vih(j[ҁӻ)p{O,NÉG,lPp11t[ :TtIdݫZa5_K6t1Oڲ^gְ:x=Le1so C8ZyҝkE2'oY?u\VY \[ѹ9.4ʅsD]xٜ5eDU|4ϕRѴTHےbOYSٕvHKAռɵ<\$&.H۷g~G:w-!OG 'qzɹ*A]Вhjb֏{]XF𨞞D(Yٻ'v)?36Iv+[ RI~z13J#\?hl(0s,:5hC?'X`tŋ%j$+MrOnn=&3[ + Z#EIA\ݮL8al%|"+ƬB_e֝PF|A"ةRh=IID8QM1ˡ++UO11'eRęajx!UR9ܑʘO6LhlRJY>݁4"'Aypse2fvR}Lt۞m!\a̚z-Ofia_xAObzv+)f.'c]}[{VOj9 Tv ]+DIFTr h XVd5E׎=X^E/+YD\4Dxw86&ǹL)^Y)|[nA.Уbw nmCr]תI,}q`oGMr?ns*;~@9ՍH&D%PlHCfǽ(!V,U3d8 {d苼/h3fgiL<䤐ӛNo +uJteTk`f:7.< yTT)W +fwDŽa߂ͩJ^]X<؞7H5#ӹ`w;jWW>կ]~v[!`^;[_.l/- Sݬ]*-J4]uȾ da^c+5H!g`hI1ʸ5_@)+ͨ1Uy_F{03#j6Ϊmcܔ&4*7ז\#Ik2S=NJ~)Y?xSFtڇ˭UjDАҊ +NJ'#e3!m.NM(~ʂ KZA?՞8kjiW_cvݯ atҞ9Ǎ[t$vfLc=^oZh4^2u\Xp@aoU3V::uo1IDʿdf?O`dO>@"ҭDDz!ߘԱ)6Sf&PP_ P.;yCDRt]@aɄӋ#NAH0ۗ%z*=%,S4L} * +'4Qc>b{' 3-W=%p +FaA iT(eHfBd: zֳ\!3Jwu@M/Nȉmo +XbNg_al&}V׭URʕΩ9hү&䴴-=lmmpԻq pׯ 'թ='iWUj:]0\BgȌlk4 j 7_!#Į{hzV~"U'fW ] + {kd/wz#˂N$"2wjvE"cSjHzM3@v;H@Lyf\2vCO";fg`C"eUf +, p jf†= k>6:mj|?>88W1vcq+sDs a~lUCt6@An;50.K$^)e߭e'}r_XDw,R}f Wz#^Yg )Y1YK:Duh}lɵ\%,~i(L +Vms힛Ę(m*%ڲGLTj~\b`K^&G,.o H]2&= +!gʞS'ȓpFH,œGX0SP5woVux|M{m!߆#Ywf|n@c_P/xPBfrnFEQ[/5|T{=QYЈSH>$6/jX󷱘H}S*.r,%:ilDt.jW PF_C&͋'Nz 9(41: y<|#ih:ry p8ߣ<@{VuSO +KҶL˭\N~4%+rEvh7Okgk%띵vǵ;yƚhhgknlfB3 +Krn! + J{N[;27ƺV'{{MFL/DS*+n_:Qj=.4Gf +<Uo@{Y>Ir h+iaYidl2ķP#-6ӓ:^0ZקAGY]a4TL>ZA%goG_KBwJ(L#զҗ\dLeSHKy oy^! bMgJޓ$xє}&*1 Xe5J["L{t*sY.dU -E d1bB T骮) sPVKi'r/1MPAǾ"~1'$1AEE@(JƐX88 SAtωe+R=#MK^4{멠(2/dw2>Մie2 h^SȤʹJ޴/C +kqfeU=A-J5RVӱuN6K,^)I)?ck vZ{[K}U.88zkI՛ F\7ZSpW)[WyϘWbq<Xz׮-1|6 >ϾM$o%h8ױ:_OOƿS`]]}8bWf^XyNfZpŹ9nH+z,~_rC*>/Sj".wrg6yUQ'yLMifVI:3&DUY+Zӣ-˽?L)̓^ĝqK +OF1ie( o4 wVp ]٦<I[C[rpP2U}ϟGo;vGYr@*<5bs¬u9Co@W·Dl@{Ic~C@M}<;if{5A8SXؼDZ`j=1g. #cv>`LU:PK#ZpA~'6N<Jb*Ӯ?S7ݾKW +D]g򁻇`)UU-`}T6vnhcQ$>o(DqD[`Hrr"\[g#' OcCsLhI~u%IL8C#kFdq~۬>j]ȋAbTcYs=SRqzwߘ"ۨzl0  d?@ttXrBXsr#ZӺ +:$&-=+tGP%ֽ~ QVe FԖPLk]9 b'7KG8|2 !l +}ꓽ4E`ɋRu,HQM +!qnvRQ^䡷7q#3(X>8l]HI*.i [>Fc΂cDufW;>se=ʽu@9~D7e9fj.(OԶ^"uotGA7,ϬÉh|8 1f]:͜<PwڃN#_la~=?eP1E$`p̜sҼn5^3ZŰқ=3;j/<"(Eg-ÒVBcκ6?# gRU*cs$]k%ѴϖQuAZ|W@̩Xivv%! wؿ }^Ѥ}nՓWmлdO᧧yH<>ws.m\טq#ү v_Uո-yeFsx8D{S6 +fLcZg$8QY;ӡARaSM5^zEP~╋g+t[q<^T?X[Y+w&D]?tB^I#2R)vl;Hr * c04v<_Fx4f.&$BM?"mGZu HHw FSbb^!^2bgv+o5-㈆ Ь{x]&fX5}x2u %P/ǍJ?y5Ͻ3,'O\]z'd_ T:& lAl7($PRfv,&S|v Mf4tz:s4N䱱֘핤c{e._j=D'fK#B^sb`t &fU._.Bw}1s|mLpCϘT/t»vַ[;S^4`IH[ʋ9*շ6 N`jn|Jy]QS,z O`ѵJ>fkjS3cMIT.ue*7$Rh/[Z Ӯ_eC4;s]4`+8HXOz=j\)Z!)d:V*vjxT*ӿ\>[<Ϳ*xZaT"9JRCQ2;,p!CzGF3 ;k.0t$!'(ᬯ8WStaU`Ny?L;,X@lyRfO Sa Iq\ec71cy7EW2f<kJʿtQx> z9*QadZAܪatQ-R6DEJH҃QTۂQemBol_hsF/!GgG|i؍[ ashO=7Ӻ/ԻXG[rT2T:ȪNlmxyv'$B.OW2l \˩3G<) jBZT҇ 24s= .,C jrɵHsSffֶ)~_\~x^xqDZ[Y;ܥz%a;|ĖF ZQ8GY]aw"+~nƵk;:_N&VF:%8mtޗiF*feחl0~4 veSydV(X6ߊT)+asA$23=ӝo +K^wy7Z[-XGqy%axwcV Yrn@QDGGŌQ_{TW+$6P,-qwbyRa&&M:-:'B\ |u,?zNn'F`Еc O>]}W*jI2yQHʛ3W]mm]Ƹ$hy-c`𲪯]쓩! yQmϯZvP]&WT1LpO1b_gX1jS޼Ff@坎D|d.ķe2G"\ wa=+nӈՎ #AVk&y],R}uAT<.|R99 !+ȃbçӿgf?DѦGvIneZ:Ԝ[wlH,~HO^]>N7$ Jkv:ql#0{ +ad82.36?n++^c1M\f)GcK4RO[Z͢CСE(j7m(*ƿ$31]/Y7z@-)uOR#N+W26֚%:oXF&wsf0tس^F͘N%n'J9mr9Qua=&C7_bp\߶$Ҧnl?WU{V0A-~G?]U~l.6WFޣH)/ΐih#ңn&lڱ!Aƪ9V'bhCuY3tf;9Of~3bK6rD +a3BDfnZ֤੎2lGj,d3VYѽz ޒI-ڴQ g?SlmuSd`Jrp(krǥp*UͻprE(\bS~+t061*~OZ. +$2t14[((ir&/*p;-P:Gv:Kfe"^1'C dj.jYUO #C RpXƉ s3:;}Ey +gCg:)cN;3#"m3G\>ݲa7IOLGHq6YvmZ-lrhs 7KJ'&oQBΐj9(m,:}JKBeʽbϿoLОsx&eiZ^-40VN mU *6ZV{w|Jy/2 4wQ =c+K +R3"9e)@ck!Kt{ +9B]>|nX/U.U0:2oLM PtNW%ځW[f{g芳R(@6PӍnkJE\7 +9(ԫ5u3C3p*{Vg鞼K`=s1x }Ouy+,a +E`VrT0tcb( +:gv3WZUz֣ؐQ(eW[yJNi ɈG˥-ڪǎE +&\`mفӹ)R&VS_[?N*Q %C;h U#0UX]ڪ ($ +$沈L)s}H0VPVjdHFBq7 5ԫ(3 6|[1_%hOJW -2VHk89>?zqnf //u%]37 Q2 `3 +LmEiljN?#|B)}9/,SvX*4`~մ;^B-:cAZ“qos|.۷Y-x׻'؊e;_"7mxz#y=u#L܇sHeIVo;cr)R;!_KC~]ryaxvM^~]d9Oz?,Y>HQf~gmZE5n"k>ĕA4]5f`^RȯQ/wH %kVk,tG*.xbB)HH%!?aaf[_՜7ͩW#S `jk #,¦іٝHK˩E)?~?nEeJ0O)n"5|~KF1pCuQOLTBrtߵRUd+!`? f}frF-k-hZ ֲ9>!48[*vsTp"JY3τZn5%[0eΰtT'HԺcQ_Ģx4 Qyu`Q";&OB7WW?V{lL p,sT +Qj)wL x +{Ii3o>*۰zdcɇx T*"szfKD$g?>»lqMJ>@g1fSK@PГx{+V8*'Q\/U=ŭ"HElog_GYf[Q{8r@"}kĒPǘ9R +¶+_Sђ)ڛK;8\k7K{44x&N :4CeLIn{X{),MZm{"tե>FGd.K|%q]~&8"l [Y]/M`{%ȥeyVW%Ojm7QQmpZZ_GmØ0$o=1:7-yzXST2T735ۂh+U&sB1p7E+6\ZF?,vjܿ +Yo=?r.V/%*LU6m + o_>$~G>YBWD2fuKi~%tC{. arbK}mm|;Kew?;V^5TeOh-%E5><8 (2D}]z __$`?X,"r')i% kTN>xo..g̠t [{ꦸ|9^M!v.Q|8; WV +P`[5%"gm0˄*oCN3]kY:ɮ#VTޜlb +6w*N6n>:WG4(lm ևǘvp:dLʩwR[\.ʰV֐.f(71ValxxQtfu[>D7 P_2Unzk8Dma㽚NX6qWܾ:3)[3|nv'@Q&4,NB"S?n!ԗY#(Ot(_@yekd2ʡuTyN8}2q[=}mOЗ_m_y|E|!G{#lqh!L#YsAd+/ q4mp(g4x:Ć'8AB|?9˿ ,o)cLowo.Y~3hw7 7,-3f{Ap!A.3fp{o?k[>!2˯B +λk/ +1ܬ ɘV_6ֶjIWޅ=hZTN!EZ{Sj0魖}Em +%E[6xwpcruG233ĈKX_c|]Ϡw-wd_t=jҾ?!=ttc)ْI}$9qm?z`qmklÛK>2!y_٤tp"G|RɴY'VbG[6Yf1:+__ +.1~s.WMR茚5fƵ}ġ]#NLT7V"MrX@/?#wY%b0N.?u.ji %TIsElu^j_w;|jͪ?[bs>EWvQFl]"Bx8Np%+3kČ΀σ9< <m it|2WV3ZovKj'NiS-@´GP&^%Zd5>stream +H鲢H+"\PEE + ;"7uf"jy 23"$$e9˲<xK9\|y6x!EAfИPʱtW45T0Ì`\DO2*F,zM;? +8M΢ѩH'^ޒ+5KnOؚXBTu2.|1REC nx<(;|>˕Ҭe&'kF${2@#01DgcHwjcN DRoW6 u\vei 2o J=/ʆQ-p.?6mGA\>c/Ϡq5HICw;/'pXLgFXm8Im=][sU]`ˤ;DJcQ+\Z`H)ύ_)MoQwz#}cm[s,&b>kM-KXTZGd_v'(jW J =A5dK,DŽk@B=e<;"7556#;c Ҷh>Gv GQߕ[vVks; , gЈ Α> D|}-/[17.?~~H4xH\~JbiQsDb- rz=?|mއd@UU)[Kײ|bF+ Ԃ[_Ck-]cJ~[.vw{$G%_'Ԁ۟:kmoы ͚S5rq4^ff]$l[,"v&6~z!Y+ ÊG%НcL$p!uW&`ۉpiI:ygm[=\++{n}hI]lUg93ƴl,cfS[Y&?tlhkb¦z|*rz*Vl+7`E(EHkoJ ɋyi}?m: ?hȁ-呋*Q>ԎuPgˋ|i?Ewʩ$?,n7?M|vRTB}\s,(EZngRђA^VDp#aa:d%Tkb3kDځ>5< X @kpú姶ֻJ2Wp'5#ʳ>-]n0{"zM% +߲ y z 9Y!֫SrM˥!ƠOL0~͟`V;M"RGqWeEX F0QӣcT6Ւ@B@sb>:C+)ҳ^o2)Y?=ܣNaL-C_w9o\v6Eo^["[}BD95t@AAAPDeA޿yWUU7og|}dע6IhGk(U]|Մg{ 43Ӣ_̀O~RŞg࿔Sϴ?4?࿾_g׻)M{3o KO!qV +'xs/uO{~UM3+څfvWDKTJޛƣFpȐ#D濊.ѸNqKF} +wtxZ+6:_Y^3{Y@^y|%mY3Qs/znDV=,\obg)yˢkۖgwRQy>гX_E&c]b[$5 !m +Ѹ^轣`wX^z\1OWMDWuFi'\Z^Pe Quy! _ȀuŧFz|=z2Z<\,-ׯ5᪗vJ M`ɇ6[Uh½:d9yVצv^tWr4ģoO^Xbpٳ)3~z2Mt/`/NE 5ż +=PIpdP!kWdIՀb'¾Pm,F7rtxbWSψW;*Л*oA6yM!"Z%’}Z(\fSY^9"roQTȨ%A+@Զnu5yQt)g5l2,]^HlU8ag<]aV;1І~/ttwt?qЇh?%؅7gS#i2ۅPGgr{T`',^&rPYC9pa^_C?j,V`xm+P:n7Q(*뾡j] >,; фu!Vs&Z*d*MȀ@d+ +dX]aBۅ7bZ$W> +HO_Iv~=%$kd!+o%h{lRe#w`zea%'Y̼qucN{6g bZ_8b]>iyBjni欔rpk;Tl]oğ'E6N#zcP FKH[b!.h/;#~>)T5`!=Duxq DQ)>ߒDMJc"Rnѕ6Y=g@BR2>UttV9}tQ]_ZUZMc5z^3*]^yJm0< 78e P 1M+8a7_U5M'~^`wAk}mm +^smҕr&g}n1ʕ2CPhJo7$x1>>*9h5oMr/Yn\aAeqPuEyOx_;b *IT;fT&vuQ9ZWy;}\ d߄a)K`S,s:`ݺdP}Ju^No96*N%2~`Ÿ~@34W\1苃׻|Io Ma._f /hI!45%6M: V@t L-}K=ȺV-%kz<=#Jm/$CJԯgAz7QcD;:e@'Loc4'[= %$oM򺽮!:ڏCH--U>`eax8H[\i$^WK]%@4D(Q8j8Ⅲ!NpaŶg.0il4ڈm^6^nF/.9̹>oi&|x]̄F#рΐd }r|{S˹%.$DNqNҽv +Itl# BaM3j~&:5Aʾ=^5>VVBج#< FH gs HrD RF$xjUtGK.\Wt'O ^">WMu@+"x=V>[=VE^T9ЬɘFcq񕉤Z ]*rf~ӣb'1LƣOM{=} 7^#[ wBŠ/k&zZ$ߝ{Z?VD|XƹT>Ot-Jv[8dĴAT02|S}P(x0x٭3 +Wk-5qtuȐѵaߞYJW-UdՅ#:hgSOz`hQOP][8K½  +nRY{.Y[-ȏ ,sRdRw6e[:H2/Yd4 +}p9MY9ܬoJq奓2 2D^ J?zC7L] 1O"f9UD?wx>eՖM)Uv365,#h] (gRLoժ^oAp@? l7ܸKw)^신J\ZaCҔ(J$ꧣ$SA}rE{>E#[$eA?+ +:@9w܆FOţr-)y"=RJMayI4'ĢM DxCF$aas hX?Z:Jn%t34E~]k=b}k#cNiZgh+u^aH:'k{.U4f.0dA?~QZwC{}.)na/€J0D0 " A]sN煂*a-Ь35h7;ݘ(DKoAًbbw+*ZVfxHU,>iX>JKJ ۾>/E0Nqkv8<9EpRZ_RpWú:/4$8,yOrUڳsH@\즎ElJ~3 "jsC݅؈4=00udV Zf]I#4(m Ě*-zm]VKXe7RĨJ@w~G(k/Og˒Si/aij^ҫȯ).d'I0t.E "xo&`L'iSzi}=%ƫQts+gwq" c_ZjWD/Â}l +jm-.Kf`>bL<)Ѱc.3@ڴə3 =,X^>\6NXȭ(;,7kR#aX,M}904YJp"Gq ,8!\WsO^l-3$;M gpܗ£)Mcb +a!cX-gtJ|Ц^7-Uۂ*IjXr w,0ryc Rv*uwkk̥f a8ц]R9R1SX n%t8cmW $@XBVO-L7۶ =l7[ +fh݊o;rsetE&H@~j{'¦%g`> 'ި)b NΫpIꀽeǛY2P= }m 7&3͈S;%/cDQW7R+L^WœXu O&tzF jE531L)O0ߺWEƿ3_n/6 w ̷AQ^ @C jK@/7;_&HƈIw00u0']/8_y踾3 ݃xvʿbZ@9wq^NJK f<sa> 1r}bQ@YIPJ6ưAlR8l1;nV+_S z9rpvy1ųחe3?۰zayLb/1vtwclQ̆~$ٛI x]wOע39(UyWUY?}^g>o.~,_5H@Ct*F895GywgOV#o]x<9]X'4*o^㔼93#c-Z'znrl${`l81Р]{iðu߿e-Un3gk{V-ES;ƁG^+>u߫82Pv!?SƼDt, +Q.AG9?OVSjkvkS 6i+kU#w~ߠ!,}t{-D̗hsEܺ0OosQLڻ5kZ]́k\.SGK/˿2?鲢JFpx=N 32 ((* wVEuUŗ3w +ٿ~}<+oȎ;?]ucI;e%t<ǢiG$`= +-m]m1:j~@#m2 ܒܙ߻3q ^DT>pHb"lX 7pckҕ\_Z=,wߍ D旨QiG[+/-p߾Ϋ2zѩ.i/9hEwunC.̏Uv wT+}ݲ9[t<M= tZmI}3^l1zb>" /hS]Y^ ;7G^fr$*ͼTAϠCk~nesZ`F%sJnɕj"A@l@A +5ߜ`D푲, ]5o{iUT2l{6EO(ǃ_X5jkwYKb:{k;fL۝2V /.)%)Sdm6dg%BY|_tD?V'YbT@Iok䟱`pk'~àyJ9_u@AS/f:P*.ZGޛ|~ s_fpӯmM5%e{u~ Qf7J7댜i3ЋN-> W&Hj]hDZv'O?"q*kp0]@T,T na- x=¶ҍ\t7$QMd"#|4" ~wI>FZ}9ì~tJ~U*`炸AOZa}le Kni#5V#6*d6ip0- wk"c =ڊ=ɠ,mZDC}dͳd04ڥQW%Q6퓗wq3w@;g#9]L;VT{ &Tnd:g]~ϊ*kPN]+:D7rF3esW^78 +NKn7èu!]sMz@\u<|2[:p|IE[2OQ@&A'A}wlۇYZ_@7>C'Oê?HF~,F6uưjTjܖhmgkqKm e<ةذŦY5othݑ?4 yKVfԁu"&_o6>ﺻIm^|l/9 o1~S䠿ޏa}s^ +*p9 Xf(Iyt MzmZ!*$U0}f0r95GR(- }8Z 㓏k,╘rF!Ζ)ZGU:U?E{.)la |Q,E q AEĉyF%OV}ʌfww]_lBT"P) #Z ZC*4snX?G, q{]>dNQIOooI՘<wOo![%f0FL#q\'  n=@2\T7SUYc/h&?&S/h~&'_Єw ]Є?-4Psb?fk1yApB5" OIoAGxQA[~og3UO$`敁+osM34!Bs SnbP3=@CڼX|à^"X3U_a3== +m5wF2QH'\DՂR]uxjb:7Phkم\F.N4sɬ D ۚ0i_ٳu) \[! +*i KGRx-v@-߶o5:|9~pSRמ*A^m:-#{+@Τo:$kSm ?5(  eM(Qn_aX/FιAϩG)z85kcƌ@5x̍`;Dk]jC{)T^U8!0Gd(j.eSMGI"Byrg&wJkj|{e/CQ4GMon:WẾCI̴+cd,]tP?֙u4]hilDIWCrO>jvd2@@tMYB}؏r޷lsr.dԵ$S v(茵Blw θ+ jB^3:t)(;6s+UȖQpgfN.PňS2EHʨo=?ϣԘv:ki__ٲLFPDEP'P '@dH}Ϊ舊\2{BH;k\jÀKb /axolE-Uy@ϨwڍVLl$ԕW;{#竫e20 sf@y1֧+~m ?Ŝ㌻Ί+ΧF lo(8C3(?_[\G nfSܞ?8pj$ZN yP!$dy%_d?^֒J^Y|1K~t@E%XVn8K90ɟpAiqX-e:[8L頎{U>bave(GO$`Hΰ 7cE]}=$lsY{YDdXDCW/ +$ +g,5S)UWC~g)pU_7k}ga;!#Sihn VGGC!ۦ1e뛶w>w"n$ nYfy2,舒(ݐ.4B\)#y+Z{^m8zy_Qz]'5'S;MrYVD ~Elpad'af-u}%'nPdDQOHj5vKzPGn59q^=XlʔXnaݭ2">%vXSz:-S }O =4{R{tNL%dp0Uo(VdđdW1gfvxdZvF&Yy8œUYZPNC P1O{O9}}J!~ .m6ȇoA {儦͓V?"+(OjyĤ [V@|zapaɒvVf 4+Ydd-~u[֨Mse1mﶜ9z)7UzR>ʔŬ+9C9bttF!W<M6fnP*h~ٔiQ2h;aԨpy\8^jlDIe6!s C5衰(gep)ÒѼz}U/X Hd5>ľl.*~&&V E NOH^+ 'g[!, 9AyҪ'xɬ;LnN6,Y ^,#4Q=T=5-h$;{?ja%({ 6! EQ$ȢTd鰲G/׌qȇ˶K<g-44)/GyP*PCyCQfx +?F1Q@! +r|̈́f#h֌dZ O몗uSń99zjԔwU#nḰyN-۠P 5 +G3dzUWH#m힔fdsSueKyo(݂-WTnoN n / D!LT09d +ME,R#g_!]>R7*9׋ײ }Fu$OٹU/]U%?!Aō,("9'tfRZUn<Ӊ.E7_EGӾ,3[V]gK]\)~,En>): x:Gxa'ǖ< [9wz6 檕Zꣶ=cueM#!V3}O0*')\6spX'6>dsKNCk5eZP#JdB#/W鼫sj nXO򑮩F\~_ݲcSCZ)՘a E)!K(.w-%6muxf-ˆ MwA]T|;wt*BCH/P{@zLΦg{<~>0*v3?[b)~ZkuHV-Xep}uiLNAiuPMSqX۴t؆)i.8|:uߎ-I`lp6ά37zzVmڹMhWDgNU, +qRWzɬLC^W/V~毿r5E}~ +h{Oل^^E_plh +KwzlBQk&6k@tF>?psk> ~-{KTS <o۩ESF}J]u$v6z(M+Kx^o`"4Ƞ:|`zp6]ۢ/&ŭleoS +ES:!:2TI_y-e< +ּ-ĢA6S=e+Jz_ a%$id0[m'Nk3YWVVV8$6ey)Bzy~T~1x?Iqh:[4WʟzuGMTm܃DVcB,b"yu4DύqH[Q&RԽ CЁKJT`v/ j+-օqK#AѮ(>k Gٯ-M 9<Հ'eb(R8*)ȝ !\y +d;yk_N=8H=8Ϻdۤl^q1w1*RAgSǝMɔf'})r'EFn4;\{从Ju%qYj1q,4[qO)+4aM3 +"Js?fOֻ69)7u䕔dŮ+"Eڭ, b!FEG|@ൠ]bc1'Xy;%La2(K{7+m-={F%k6'Lm<1Ek11N3Q>rXLǜ>T2OR:ݐeK }>1{3$n?j +;gq\]#\wU8|^PN"KQQEEQ9Kdg&1/OI?Ч=QQ{ rK MnOdssr`>ɦŶamar$?"O ^DZp;xUGVoh\o" D{'HLދl SP )Pn\S6=SM1DmWSXR3̜uioN9hD]7?FI(KNfF|֏Oq(7BURGxtg 2bݫܓ0ZPhT (i<޶liT"OSa1 +vD5 I#>Gj]]]m?v#: fЦ9h(@ P,pyT|*-Dr [,ut)2׊yy%ޱC K.{ԣ~kfW4s@3@3{μ@:@G֨su2@-@tJ1_U6j o$J'KPe2̅6~MV$ubsBj>TNiz!G& BJZ,:zNcժN`~g蝉&!D1:tsVIbuKρ6˹_X$;2}9 m.- ^IX8@!H^<$IܛuޜhDnՁXfε/kP)dYH 󰺟B#Mo<xbOOo]54odLו}=Ʒ-ؠ䔯ݬz*]ހЫ3^hE +8;8Q;1}L.34 #>@,THֻuľ_IpNeaӺg+<]=_6P['r.;Rqk/ɿ/eU- ?T9gDT(I2*IA޵>]曳?Gdü(?AMA~_d5fYԗFD񊂱 lA{ yRuz}" z-F-I:ڸMTil`eH3ed#} b BA.3Ӌ^LcTy+~Ԋ#{MXocO/[銢zp6@'[/h)9O*z ;ϕd[2;\`t$4ԡGouƮ *T3 i%|E{M ^J ur"3G;@乾q? dOLO*&Y|ʅ(N''( +eKBY~ő詧|UE[=BQT$kSi29Y9\vux9,0|9o u-r>41=WΨU7gh/RRˌkAJ7 az9*J(n[,sf$}2W07ROA)ԤyRڙbs94n/M+(15zZꑪO3DlS`vJs)VjPΥoҋ (Bumkƻ>4[k)"h+ Le! +)}[JXFXzv>ky@ #xHD aJs;ͻ} +r" $B׮〺Z +T3IRc/,op+d0ذt !fRpI< %58yXSIҹ]igeXRFcxvq>N|^3TMLȧq V)gk󠲗~v6WM0hƾ ߐA2P(^_dT[OS;K>l¶7TtGG%+~>x*X5Ǹ@>v&`}n۶3CCzᗎ5ޙd ɷ׬Gy|)̙Ȑ5*gkU'84kt~/>тkb A=&+Y{xێN61=D&ܦmq76Oy/yfIxb!-67%6=(y]ݚGO9TlhrۑDExϱyכFA2~U|T]mpikCfUu\(kP)|*',fw]|AMq`|v 𪟪t:`Zޖ(|_AGO!gp]Wzr'^Fs2=r:N%P3ìASyVN xsmV(٧q;y$8UN_9K.$7EED1m>a.uW_m eceyL0YJ"=RKvZ+C,[o/Q0U_T4Ä]~%#',:aw3=63o3U 7[rP}tM?ycU|7!1vOYFfkz_G7?bcW/4\_/ {`zF Dld~L 7X묒xhr1:޺73WSB{ՔÊ^}%Ew/'@@ĶO1@L(P_K.k Kj~%71H|/BAWܴ#ڂx ͍;_~Q(Z&mXVe@lt v0xU'> VٳW;Ćw>y|^3QUrOOui 52:l;4[]@j ԼpMB#rc7xELJuiX^Wcr Ν-1TgW,w͠}?ȟ?@:U qA\]tYU4U n;/o_Rׯ$W;7!=uiܳRdJNiX<" vTcEW"F`1 =/2KCy$%BpҋM^-y#D>ms7,GlJiM_iX }׷ʺv.v|\7N;Wɠ'pRs dÇ5N4aa +1pwO~Ú^߲vcw lQ} +1VkY>2 cB(̻o%ZXpDWi#A$Ez/SAD^ d Uֺ;z`ZH*莬/|uP-nIԔ'u93:PFW {ika (\cP Ըi+jK#Nsg;ږdA++>^tO_V#@ƺ_W'ފo +zpu3`dgžAnYG +Q1nwXF߯Ndi +Kjm`oɫVM<nǷEZhw]6R:w T>SJKey%(rdR ֓`w Pv0XH}L=(UҸFNszUfxa-^~O=],Sshx6.}9ԾMbb>|o0d"4nXGz]A^h1Z+yI^-Ƞ9iZ_<\rJ1WT٩ +Qަ܇=`kuesQ6u4"(mSD^?% 7`I_vd/HIvl?א6O)w|;EbÃЇr+!_A77jΦY鴠>PG-,߶xܐд8sh F;Dk0Țdm\z|#K'Wp|!Sۑμq$*{M.cK_;ZSz4s-*yzb4T܌5NHk%xwMjqN)+̚ajOI.7c˳xJM}ݙzʅcJZ~TgmDel{{;_u.v-G0H0 ǫ3<=;6sqwk$z^v !iMgmW|[eUw&B|XiU~cb+,yOT +_z˱O +7;f`է,rR4%'BԘQκEy,&m +4ЙLGw@a}h|{e/# +NQ@DRޗUtlrKn"Opuyd=?3-u^>mo\2~e8k Q5\8xr-D*1x}DզZnGem KIe?ԼaO~q87tͿ;}8QKM6ՉEz_WiqQ1~jCj6}_{d+:KJj~]\8x1ɔW9&+i5؍y3r7`1B7nvEtQ"z4bw"*YW.&Z.m7.HEqojՇZ +n8ݜyQ0E f|dBў1F|rfGVxNC4TNI&?uYw8\כZõjG}ܘvV;b][Z5UZ[Ќ1y0;H cWQ_RSъڦgPd)(7d?,_?@am5``CXifBBhkL bZp|&PH+ 찓UsFlV܇q3[o-lq P0 +Q(m;orPT\s;J.VL=oV|=HzUQdAR\᭲ ׺x s` +E*5`,x.L+t$/)j.{NMqדa˵bGL^8EqeNc3z3>Zg9pG ]h< ]"l[}i@[ሔVT\#[MJ:CL3&U?'W/,ZKTj|X&r 3?٫9'~X:B\0b)vn׸q8ŏHŔ%_[sh _]~ǴAhvy5I]Shm' O̎2<߽zSj+4dc(E@ BqQf5&bj-cG7 @?dǁ\D1'8O=wz@OΪy5i,Bؼԃ,#G6TPJ;Lq6$i5^#h7=_)c V~{lzko\ jzNtbG0/0~v5&pJEP$ +z㼢<"!7 } S|ްN1s+M}󘎶]w>u~bFnwо}^6)Y5=ePT`(%P0i(x;E Akcy}UFN$>5k[o;D9'B8lX{e>n +Ѩg `&KA+Qb}WJMyY‰g"s۝dHVZ]gg {9WCxy--Q |9!QDA@#6afsѵV5ݫkоI+mg~I[J[=@  #@+iR] Ts Ng|w^:WΏhSpʡIߏa Zng=$G0Ճ훥.Μ5& Y(CtՓ(Bjp|M +PJ>_D&V0]ڪ>YtJ[xuShsݗ_)nikpxtu?J*d1ğ-Zj\*ꇛy=~8XuwuSxl]tN_h,p=wVJη2-G#u4 qpPV^mrKJ֢<[_2|*cZT&@Oނ:K'1*y_9🜃͉eέ41ę Q(۵ A.>kҨϤ,lD7b5eNPI*W4Ş l%uo[(;7vBq dwG)s"OZVJ5;]P )>E;zzx-θ3_K>@Eۤ up߹XHm> ^=:9; !55UaoI !RuqiۃK/-s +{ _5 BHjTEO@"O|46.=OGGֽtpt +06wI?҄pWB&t .j^zbYh r$yߋ'R71ٓV>Zgj4q!TJO^YI_7c(nxv,},IL߫} +>`sjj'WOtaK*?)R"UKf#(o ITzwn@|.bt0b#2b`-ǵl*G6sW, =x[+U+n4״c{2Y܅f9[\`暯EhБKyZ. or2,Bc!fƵ qlL 5%}WD:ea|UX]USWtNUV>tF%Gua9dzfTž'G\L&/ תQ!sWt?ɻ;uWφ׏YLZzBL._bwq i\'/Z:gu}mf^qKœnQ){o*ˮزC.3VM<s;. 5e5@Q4تּc̟,uG {ef~ZbQct+ +Ƞ s 2xwX; ~߆͈r%3.IËNZ@ȩ+h|G}"f_wӹwd6i@ z:>I 9lO|L6s{){A7nMqI0:*kR43=,xTZxOP#V:ۛ|9ȫ)}Ő^3e0GRJx98b\-qM qXVn^䬳ehmR㽡dٓyޠmoCnDN<~h&2y*}ҞEҭtRFGis5nU \Z̀,/P}:갿b<ɃvyL MVbVNC>ak}2[8vRmeX7=p=NH*45%q\p*QA?c,<ߑ5pBgVc6N}hJBA"yz}iŠJy`H+[o9hUV=5WU~k;?WB{(-3WZ-R@m m% !H{6R?6 @#hP8<( +~:~;˗K/aғip|LZ_6vς{N[?+|3A]8m?t 8 P2p^ЌgZk 1Y{ߢ5LehHKf5~Rʯxh#_Oja2pQ ? +}5s F ; @Z@ZtKu->屗ȓԑN*_1>Ah˺4HLjR(M?( Q&s M6@׵Ņg8^X<&z3w-Z\J:aZ[ `}!D*@u[nmWƕzȄmEA^:M Eqɺsu㯨5Ѭ'-ǽ"o´Qmu ܍J!|+?xg˞5'7󁗕 zpPޠ]EP&BZ vF?lIA&O +ظ5" 0sGLLWuq"*d6/KL5O_vΟpqJgx*RIWxqM#VCӛaG:b.,8-mj!W@=L +M!6/Qnv)\pM DTJ}O69yt>f1qU82'!5|ѫ[A}6ĿeW?Q wRwj1"d-xL&C4yZ_և>KLo4|~<՗L\-fK*5J|"7Ks5bF5?`_UvS'ǧѧp>ӧ = -T~G':2~'Y^@4/s<9·['sylat/3 'EZdtw9 -ԯ/v}|b5: mąWUO]@X4qWZN-kD͏;!}ΰ-Ⱦ%_m-𳜪4<>ljUr>=yr@Ly͡#ۦr.C͛ _,LQ7{h󛩆+*ljbpMbk3Kd+HEMǖoL#Fr?y?,ZW:4IXng Ljf3n.N 0&XLw|~qSvs̯,/ TT]^[GQf[PQR֐$ዹ> yV{|5`vzgs+.K*=w=W(O!ZB_瘈 Pj$59Y5gˑ':6j.^d8,G 8:rLkwOyv\d$|ֵtk[US+ 9ZD?QJ2`w +䍗% +)!RB[@ mwTWCgܔǥLIǖ {ǐ'#9QNumkoE)oo.I&ÝDi}Yurw'g- HR}n匊، =zV/e]_1Un+)-n:^C}f13SڤM4|7H& {kι-WB C"kkDV+VnRDO@cY)ϙuf ^hmݔ+Oz͇x.hK*~峬Z %d?7t)A+Qd.sf@itνex 4)WI8i`/dYU$_G8 +2 ""∨eoEtݜ ,WndimMj h1UzΠ‰\.9oj,uUk'~~'ݧbީ6=:Z(%5ym(&xfקauQKAgǣ(I>m[0^@>>Љ %Wl>A!UwL{DV.]C'h/())“| k_2? MyoSZ]ʶqq.Mk,k^m߇Z%|ZU~^;/2bU&2DXMdU@ I.ٿ}B,#! TP$Ue\eN"q6j_$pIԪ)1s&Ns7LZuE*KAiqCr:0LTACz3f`wuO7[gQ>-ME-Cg-lbg5O=r~eEƬ=L~2exvD6]vF! c4=fE (&+>)=.nl^PiH5R*5[)JYQ身j+.R?ʣ%5q?Pl 6 +SuJmebR ͪT' =9t1zR}#r7;q7vj,5dswxwC جܧ|h T ϠbU)d`f};+u4+}/tH*5S<%& vK/%JYqcER pߑk\8wAJw}r| bAi ?A.T +] ^5 ];Q'SP 8籚Od;BAVqVU94:z^ZgAҨx$6W#BAt +K^KIxMZ_{ms?]ؐQ[Żz\HRI kIH C +?1V/2_feɿ AX&b\hmW_TQsN؍'Yݔ6䑺x 3IpLhFy<' ۸,hJ ++ezytR'dʹP!:eFTws9<#EL)>Ƈk,>XWH hޭZ=`; QG5{t_v|oo7AK|^=PA/?IOYlwJū@6N H[@-6z?녿л拏C5y3:i=_%j*Ye/ w`$Z;0 +BM31~1~%1v*֮4'wG!×{M+}g<vYZ_a$376uޓV< +1 $+ + Am*Fӱ3m%1" *>wnt:'X:}[eW47^DW{ $yh 6T\ʣxZm7Cox yL%2odeʣ{3Vl72vq_@@ \(}V3[pQC/n ޽ʋ6fcmD&G[+.u;*z1q0P#k)[A4X}C`M\LXoylX'_U;EC)Hk=:p1-'L +nNco>T\f;PIk\l1u|mmhƥ({yȫ Yz"9Zʖ%쪖n;TK19lC"ϳl8VƠ"`PVG.فjx}}B_8_[5">W )~"#% X0;-2}{s +^. i`~Ewym%a C(sEE1c°{|.kԬ~@ӴiUF0o/88iU*[ȪVe(e{yZߞ-W4ݛ4F-O;1Z4ĭ6gG{эhޏJ,s?&BdOQVڽk:h7fG]ܩLEF*ě*bCryQWk}pmxbiV\4}.&3CYxYxkv\jt (V}c+Yȱ/>}E.vzFq& bjѫvIգׁKU[O5Fa-LU_6 2l@FHIޥ -L.d`-&~E!ϊ+#;E!ŪNjnH':~zC羛h7S#r'|k4_=õNRNXgA-t!X" ?П' ++'!k!ZICg>FNX761zv +v_s~%oV5pekTyRr#jǎ]Kl%2yz+n3ᢴaZCfk 1}q /:}{X|9Ъ_FًgmbE_ZW=YӔT3#O@׮R06Rg]13)2-}*aS-z$u䲼N:64GZhyHS՞{;]@X%~LV-p'Se2cW.aam4q;q+rLnhL٥6$'[rŞ۲M&X=%}ӲQE)G&&x[߼Mb|ȥB@m.Iw:#ejFUCѐJJRrnrJu|F8P`*>N˦7zZ#'%<%!fEU[(?, QJ)) w}^T5kh}v<@,b`tLF 栿\:%mf2+ljb 6Nr߆om0JwYR ;P)O*4]CR~j8T+$QDyLLhk&6;טW$fy ;剱'G{[J 5= +xPe[8b\ݘso]=2!Wx{. Lƫ%[>B6J ΏA_, <:-Ddӗ>Z;aM"Eo͈|J nQ*X%F \/3 +䨽UFMd*bLKn/ru +2 WZ Ut="èWor~](l *]M {[hөS:,CyxCGȀC3v< Lzyxgg2z̃?tǚ+&6995* QHΡ{Ξ?yYWTyv1_~$\3Cs,=~f㵙m "r}B5KBNF(Y3b/oȿ&Fl(2pRl @VBFR"-^̄B3wz8 h/2B|X ʕxl#Đ)|Hy}0@h 3+4.:a򵪊zV갂fLu$\KJ;~y(]7$,>B +Lc 3O譒d@ <JF,:Ū&Teb钺ZHBKNN3/.$-wI2ĨFW>hDq<O0[ FW=(( W=] "k # T^x~+seҠd^ E d{NJQ&n6 q=_s"׏^s{;: ح! ar8谵+r+7ŲKIvuF%SÏ9)Q̼恺GRwWZlH9W,7{=DHُ.@1@T qLȄFT#ql4ÙnjŎ\!z;{;\x\b:ͯ$/T^؝* +[,V>2j9OM{Hg(T0sRJu2cnK,G9Ym *; ֲV OþWϹ̥Wg+5)e!771} c\=}u +Mhz՜)T)(~ ^\;~)?7$0^f]qivd ʜ|G?RYCk\e295u_z5v5"=WJĜ[rR_H(^Z@6dTѳMYBN[S{ OuVkճ1}M=wow%]+1-h<[2!%( ª`@LX7 *4,ä;m%;O=-qŷ'=S "njPnΠ1֨T/+樰]/?;*OC y.癸$ X0!lԘၯ=sO5b+['mex_a@T"IRt[ItX?/5rmHC6RҼ2~$ANuFu,~oc΃G/{]?g-hV]0a8,.ڀlTltauH9~&)3I\X}S/5AUx,gȸLl1mLV\9/oй?m {,۾L~1f4:T-Ie2K2<<-QLOr& N +)twirgp?кu "S7oWCJOє?;-Õ/2b2Qzn$6/(5ϫQLszX/=Kq$o +mTk%%uyf5Mmi'7])"}x ;5aN[|]ufŖ ~KC{82-qW9$͖UAPw)+v&J[g͘V#{7pi%/맰$'/e=^TmFa:g펾aU58kW\a!úIvnv\\F:֓ :\]881f9OW t=mȻAq:mB `-F$i5m+m\< Ϯ,Hz|HAd+=n,O_,-d$>|%?rT|.݉jľR^e$sPI" 0e{@]fh>T&aKE +y9I7B_V4eܯ!u%Sl +'arPN֮gRA}ay6Խw[\:co6^#ubjeM%K^_ao3Y#/gbzzC5 R:FN1aG_۹mzZR:&3CfӸ-0.d欬T 7yp&l)iNٌzGqJv>܊sL(7$|??simK)h εCsHO)D |=帎@Q-yc hoT[_|DQ)= -}!8+>L+_D^ 'Z:É}DfDo>\h3'Jlsڢ3f2 NS +Zw=w5pe^WSUs*ڝ5bTВsbwkBι"!0Ȫ%l%ApAUAJ??¸}L0p Vw`ڵ{GR , x/6amI֩zƽ-<"TkQ>Z&س%)兙pU1҇@a١0du2^/c4ymcb-* DxIfs#5v[V +OEc#L-JnR gy(޽N/ +n/7=iN q+!_͋m%i32OwQ.TςM_0}-c0]\5(Nj° 3`.cXc/*c*sJѩ5g((sHYUN͛wՎNE5l(g` 'yy]i<1 Oi"Qx :+?&%R4<)(.Q]ly5;Ҹ^qPHCtsS$曧Y9kg| kuxs;rC޴ҩLϊQrz]=iHy +q55rCk1)nliͤ_辳cV2_&Q N-9c̤+vĕHs,QXw#BxBc\m}kz(=zu^X.O~S@܎VI$μN=M;(akҫ`:7Pj=wzYlKjWq3ZN)ES% {r|QZu5Cy, +"1Ĉ9 ̫,9z?3sUկLV|wTnX;v9[M #^C /NTC3c"5®Vhz@|Dz6]2b YR< &_6[:|,3k>Ha| +jueZ{hjw6[gf(9/PФ*-*l5+( xp;v1~ g\ySOEluBTo_E{ vpq _quG&z)պ95̤q9mأ\U~Vg{ܭFܟ ۾'-Ꮣ̹QbAm\MW0zf5hn-MNםKbn2sezcJ-*u>GJcވ}p +{_h`CDWy! M\3uyG'#G"GѱՁ;]Ovu s"2la ;Zz9wh8?ޓNi ,!#TRѺ! 'AMt"3*-L^C+Ę;fdsAȀ uZ ['<&S&e=)\sbB bz"/6a谹7DVȏ;  +\ذ+AJ>!KV/jE2ZX#g6 +=_P^;+8p>tJf~]Yao[udbQ wqnx>Qәzsx D5clvG~{UsaL잽ÕĹLVݪ=߬|8-5Vqԟf?w@^%!h6FvE09[cѓ0&HAN;`G- endstream endobj 55 0 obj <>stream +Htײ'!T""i J$(愾欛]korhg%HS{刖F {Cf6O3z +Ŧ +y%O@x%ȝ!N4{ȫ́,949 |+S]Cm(G^EՀN5mptŀ{*аר$gOF[\vmD=܅)CҖjD7w#⨓CpnȖ> o}nEbEVgZj#y4.fTlg۸SFA M6%'D@=؛T?o'ɓȇޝ窳+7nrx{M]e}♀ubx8$R`R;X{IIabXL WXLQٮ^@o%̷-b-!ߦZf+zkwU_J`cF7ZgqJkAAiZvy6~p+d=3n }ĩVz ﮅ8Ҥ3^1F':ʺv4_VLU׷>ٍQ5I+ G֋ΩQ^}Xx*Ll͛i&]>A~;9y fc&NzZk^wU^YV7ȟeܣ@鏀 &ťť7 Dd>b7XeəX9א>j}w#~,KW==ˈi ay7סlkۗ:[GP1R}&!G˕+KslcRىH@@ >L/xR=Ao$}C,v<@$txDxǬ;R^jLh%KZyi]1GIb\$ͥX[|cWT~UBsA<11ūf,~L4b4e_1>t(Д89ňi&IQo%b"J@_3 7]#[M[mU ͵(#眻hi5 XSf?L:LJE?t_qumi ,F̯6aL(O\Wv,R.?s]UZ 3cԏj^GGLu\4xkiY(ۢO= +fd +bso_\{zRD,6LQ]dkAmwk7XhpySG^?#P+!}>>пADaEW`jsfO2gZ5j0./Nظ fY+c.;]QӽѰ .ީi#l Bog9H'#''6^xi<_mTX]: +˸O1wKx\&$-m:|5w-`ѯԜRՒU8H X%=#'/ܖФxx%kpt>JUX̆.!R`xu4ʌQPeuhHX ][ݍ~g:)*̺Ⲍ|[Tn\тJ[ 3`_ +{Kf_?))aKf=N]x7e`m6LKyNwGjQF6>_I{<,#2|N0CfC\ܤ~pSɵ⥚g:Zf '򆶺Ep aW'$d\|՟6epk-4>)]:ktgkک@u|>mJ ߤ"\1;R,qﱁ͘ҹ3mYeEf]3`r!\\ \rRv:汷E_8Y0;ysfGA.dCKlV`)\;KtA-2sϵ~g/Ak!lMDU]./lѶ!sW1<;8wjoUjάeoaC05"`AQ^iGFǫAꅾx{K({;ǯЌv5)BǬLwC9|{΄'Ka - [O?{GsֆFp]@<Զ!'؁.bsE2r2NZV~7ȑ3 7uaI rz,9(F<+)Ba 9jlk8=lco[68"sar_^@baQ3`˅>n̖§ʝB 㲁ƾڵJ}Wh* " >C.>vpo Y +MtDޣUeƬ}U>Lb*M-.ĴlbĠD*oFg]E}T;W+ZxkT~avL)K)OՓAX5=0a8y0L41#ntHoͩ@CZƕDҫب^oW2yr!$KmW?=Py/S +w.֊)x#ݪZL$w>Ycj:7泱sY8;Kx˷z_nK&,߇I^$ +&c)VE~p +]44'x?E/LCZ?OO/w#g](6qsqnӍA'X(amǨ~Qm(&UGуsˁX.ݮEGV+Dۏ~iH9L;%7?64@}Y!Ŭ<̬"Rn+zd1ݖ7sdE&UZ;ne }箟O/V Ĝ3&̂A +sY:7_^kwUKQaӚ An{c3T?w+28 6XPaDr&ٲT(&ɼAi>;Tщ>:+$E6vChkH +@:fA&[_\ϏoJYK3/.ս wcU v39W$%g+՞ե]Qp#hBKct}ŧ[J`yZ%v'-4d/kμs8ҍ/dv-k]&4yA~Ŧ6"BDvXp.[F9>O{퍒rSzuɈw'Fvd;$NUZTmYhhܰՙql@69G 7ct=@[fx?jh+}3 x;(xc]uEi;/l;w\9A-, +Vd W+S;z-\ )P xAbrÎ~lѼ :bG;Z^N&fddZ%bRB4\8'p2Qկ!齩`kQ&*(5+j6LŦa\v +}" + + +sԢ5,}GtʹaWKh5Ujxh |lU~UZzXjڨU` 7*Oj)T敯v.:\ ľo/hn_W %PhI}PgDk05l5Nv|WdkIG4!Uز +tS!-{jo71/(^ J]EEP\@gs3D֫ +ojwEl Õ"K-bYo|k#U1\b]~25Jdd/v_G?}H?/7o1x'HH]$@!2 $쎓9 OOҬ(Á2ڷrϸյ&Ԙ"C=Y yU҃au/|D~kO/2 +ֿwX&g!s|0(1zzkY3 zno'r@Ku~>nG'򴚈9Y*Rjbxע^o5ʶ9-`|n6)P6Ñ/dAVu|H,'7ML:jdM:Xl&[xΏ&/!k)WEnUŸ'`c|iyDpy>QyM/3=rɓ0(NfHҒځٵHOT3EyV[Vs8BH7_=8[SͿHteFhu2;"/yoÞV=9):mplr|w "u+D`P@3shz6c(_Y +΍g|g-Ǘ3[ո{4e3-j}:?4އ봤/ϩܸ ;/]uzrVSHoǽ2R6Ƈ PJCeCy(FPgFdáqZTQWTd M^pK0>>o Siש.zg9"'ūZǎ$_SmߓkKQf C(jۊ$( A $QϹzWuvΠ&P{UlI_jAr28ثz䝒mԶ@)f*v?#֢4Jky6}+"v\R-SwU#0%m}8A}2lF{('X((rhjU=K3q>㫛}G6`kOzN.kR^Z{ȳ7j"xsͬ*lO?-"&ܖtj2PZڂSCECƽ~dŌI=tu6Suɷb?X/ (*/fzjm׺ dTL5єIPQ6MA>VU|Q},[7eW/M:JxX1$(XGmnP_#25g< 滙郭j\k;Jݺ[R.LND6ZoВCޙӓ1 Oְ(G:JvMKMl3 +gmy:z.+KSw箈 MJ8N#TVFmÛ*KYJXĮ=.׼Ų+0kaւgd!xiKòc8.v?v -YgV>˂_"FPVW{9xޕ +x!(65ap=YC0it C ad@/i[i/'5|QͩAaQ`OPJy*Oc% sl+sO/Wy¦I1zBcNRLTꇍ2x)|D /n cRgB"v__<*ktW*ivRoUʝ7-s[?!<`|gJ<ѕqByj<qy2хwWuHWHXȍ"Rp1G:%$KlF,Z$x5,~m+UG=q.WUiG+Я`*X9<Ձ˸.b}k=0)evk|mu|-|_|U>}8e:+ūp^OdTMྸʞ$p xDrG`>ˋ{jSR!7o|?i]s>(}gNPR (ݎEp>RnG7v K`fv9o)>,'Cj]p5#>>`mrN);iȐĬEF:Ke~ネh eo!"i,U4T_@݈A >S,7w^ֵ|EtqC RIISiԌ{NkK%˄>Wu,6s0xU-ea:p%.tByO k Ӓ~ C[MQ-L(:T^$pxVvЕڧǚ۬RsHTZ:{D"A+Q1CA6J Zk329qgؘgǭ$F`@B~K^h>Kس +#9)J0XXgXly|Ab#EΰXA8~' yoO{+]Fn jcT0?< +"b0$Ihx>7jj|]ЬU(%F>FMp]kIWXX >r(>ouVsa̧ŅM6[}ltzmk_摹41 ez9o5mH# N#9h,}JyoBMQ\ǿP1.S8qIt\²UcP'uq* í~٤{C&^h<x4T(5%5zFֹcU9 pXt +NZ!t$lV`D>{H\u}cS~ڻ1>h?exͺG5'LWdPFd[ E Ձs;uKFetSEKœ#Ӄ]OF1)Z^/{D?ڝi Ɯ^T4aqf|+(Cv #&z0k!Z9j=EUZ+$0- 4lcU U 4ֹH'4{w4.x G@+YNQ/z4oiR=}5xNa yTO.nC z>Jc}xoJ~؉A~"fT-yP16VI-Cwn~}klm +kvՠkUA?ޞԮ#/E0YvBG9@J~N6޴M! )I)^4ިt=E6\5F_bmH.@xZeZemtFȦF1nP2} %t +oYK7^>YlccX6Ye̓Ģd+7~f\jt<5zNBU'!GgE 2Uf Cȯ[:Qfc焱Au. /~.UՍϬU(&פU҇"kk#J@}jXPWL)d7  %Nh+\Zr8Yߙ# {P]j$^4{lke~9 +8W^oM"_uBn>m~h"{7b-`N|f +#~L{*<)7?or(&yUN:lXQ.s$lHZV o &DD (Q Oɭry_tO%<Ӈ~HV*⋡͞4QbG ཚ9 SI˜}8n=ݓ^Z 'dgEjj'{ +aXe,I_VE z<8OW{qZaŻ +qEʥ)wn,{%-uG*0t㈹ ,,Icqqw_ #V*fTv]%ʐaZh%&[J}7Gx2(طHGlK}Ļrvp ?Zˋ'q^NYꛊ$ PBj>hT3]!PtxS[;=H[}zfM5Z'8& 7X4eICe!s+Վbdk|+.M+WSIm u'ac5ihL7BxIl+xm+e%]{Hᳶ*dߝ/dvi&[L,L,h! ՚l/m^0+@9-ՀR_ +0zFOyq;?GK}]֭V%5Vp|Ec+^^]dj9EN}Um3C w355xt 7_ߥ;!yg~AO;7qļju#͑A{C{5E8 +]vJ^.SFu4|*ydGg2uboIF{WܻRzQ\~ב:˽%͇:JzѸ.;֥ȫ] +ߖc6\fdJbˌSǝ"5Ƙ#DLjĻ@+c-bD%GR +Hg@zyZŖ,[jj48jm1DєJbeX$}}t\%[jX32eѻ+1*M[Fq74>Ѿ13uњ't,27=VEFa{j[3а[]jYƟ[! uZ갸~41%X# {'ڝN.MJCR5gU&o*g=V o +5)4QruCUjw0Q+@9MdvllOPzcJbatDoZ@UKʥwiVߣ!ls`cKeH@E?+:sKs#@k`C~7Qס&\cD)=ʪF) 'F5Kl|wjZ q&`Z>SEIιn_rR-Ĝ[>Nל$zGOx(Q׌Iz$tb} f ;Q#=h:WEh0/#j9 "c+>p][E5XC >?eWŻŧn\IuÇ;feg_[y߬%Sոb{q'l˳mEI@Ԇ:U-t44~Ys3҈Z`޳=R +?rCeio:"jqq!%ނ̦XF8|DOzJ_͸ili#RyW9+*+ jjz5+ryĔT(̡E'I|7 BoG" ͑'3o[#BajE__^{v3Yb]}7>:e߇\d"u:$U$"9 +|τ +.@B ?gɖ-+aPA +VЄV-AM#}JKm"\>+R>*&SUӛth]jMb]#i-%<|W$aD+#M!tua ZuޛoWg}Rt X~xDG +tG3 Ǐ"!)bEYņh7B;ҪqÕ\9@l0bE>51zjoe X@Zwy,R0rD۽؝s6]hv'[_o/UvG%ٸ9=q'tK[$ +5+ǀ!XuThc"hXz.]RQ,V(!z $Ѽb 9.XpŘQ\k{W Hǧ\['֘{eNYy? "Ϭ-NMʘ /(7u7.D5IPOK |Z*ȡ2M`2c\LQDcRi[6 tُg67י٥Lm =f<'*f.qCCmjh=5'??wr^%߂/;(^n Վƍ`~5\6X퓐$Žīz]i1Woѕa+WjqM1}=,zzz +mT^C2}ow/R }BZR[|s " $ +TĀbֹ]૚gUqBՂ~ǥжp$"#ρ1;ܓcJ &+-@ښ:8}&USldN0Sֻ1`I4lԞOke5>R2FU*@_+UAss>MN j. ꭤ6/K:L怖Mfw?˿k\+).Pʕ:"SOJ%53T'53c~_\ 2WBv6HzeYY;~AЯ!!-M+zѮuL6Qxʃsr^6,#YeMQDnNj:b!jKri&'u<'BXpU9fVϽh90(_$g{|9Ŧ-L& oBūݾZZqմGW4::2΃{QV=N,!89&29\?{4Ab0 FVX~ ݤ3z7cYS ; +n`|#ן< >.M\xc!-v +9]Swv+fpq: +' + a\r5K(kFk 1oU4ȷ1it*If>Whq=MmbF0c/,-Bü#.)ᣧq2併Sw[Y*}Vxg6f:^ o2RKw(z/,YA5m}q]Me;iQsQU ;8.j#ci.]xu>N!ە"tEYfGv:;K6ls9}5I?xn %If׬`"r˓s6qy8lz$`=0KM+3;/twF ! \@$O nT:+h?.nn¹;Ty +OnGOTglo] }_F;/ ;HH|חH6epS=m{Ziaؼ.ش1Ehb43Huޤѿ7Xbo^yuCH>T6kFU%z.O$,[?@íz(Ч/,_u= +spl6:@{.v{Uh13묛z}-C1799;`Hڍ^awZ/!;_@_MO)֬WT7_1WoܟPg\DW"OMz-xV`%^7QԨH(-Jo2g] $t9@dl:fφk!xީzIoiN[i&%j \WJE`Y1gQ2* J;FF|)? #q-"#=cAX7!7қEbT'wjr:ıPA.9\6YBܝ٠0}}yX튢!mSEF\b!xo[zbf/#|E?GpvJ"*1>ǝ"2F2TTAT\I^= -6 d+`*y +ȡ +q@O.m>=zV&JG …n^ ++}1|*S: =A"0#m7f.W^)DH$\H@>Vy|QW ib +MV>¤*$ZR7*ϻp= wgo)z݇d\Q3pe:mB>`y̞ng^H HK W#0YW"lf ly;)ۥѣu?r8ƺ :bL)YksdS֭kE\nY9~5~oWu[] @ +83Arid{L!jXXׂBy6x3s|mrw6fW3al٩1L~/O`4dz4➗{S`,ƶv~]ٝ1UV{:Ԯ7֯0a< p +~~5az|kιVe/ȄJ3%{Уk_{rP_<WS]A 5^<x [uƪtG`YHo4OyVXz0W}LƵrEZ%ۯ*ojMdi;-JCNt.GF2zr᳁ǚxE>֔];9oTr_ /)^K?kIU-C LjsFIb@T0;͜oWuwukWVbi ʆLN͞nkm˻^V{GxF;fumo,Ł/u0#Ee<2[/ЮD=7Ss97)1Tnz8.{;zA%-skM)s؋'Zb3ǜҪ5c2 _"n+=ꫫ+u]Ǣ}D؉= ?9*Z=>9-6BmfERTE= }wue-WT-?Ft75i*!~e94}>/@GX'vW ~=x~ <ےù?jpu3=b2'DftZ*Y% Mj9rG5_.AnLު?֔߶te3 ɹ36h YBØgGmW* Ǧa͸l GN o09mF˵j@7Bh 0~)dUai=*օg'KPJTƸSi6b AzՂH>! o:Ł&sdJa3!-J. S qf\&vQ9؂Tm9[tZ;٨wL}v߼lQ-;wy^ WpPM͖@%>|o88Vu7/.6qEݢ.J@/nHݴ鏓H_WIY8VW^ѽd֚"tzatx.o<.rby+B\m&O!~<|(~NXF }{'Bێ|'9@0A|E|:DL΄}yvyM}^njqjn 3i1kNꩫ̵"*םnb[NSiypbq;d.ŐVP&MM1Y&1X^+-:%={>9KK! ya%}myF@ D6#˾&cYe٢aQh}6!}lF!<؜7,9pXj1qM11$|o} :/#tv zf/=Aou75}e1!%{_/̮!bz7KU'޸CDp5ߵj `j5A LJ? +iwb8ZE@d"{ykz;92:?tR-' +Uq'?ۤcx]"_H덻pR1YR4, ڭ]SdN?OAaˮO>7_'=XQg3D'=6{|݆ }Nbz؛P3 +؞P;#, ?c ZGT@cR#Xld5PI;A"I*84^# OQwS$NpA>Kyzܬ } 31TgsHZmHO$5G;G3YE$t^N1 WFJ!FxI4D"9i@p3|2QyS7O I9=Lβ@+x/bP(E{GTFdLHIY954j$vL3ڤ1" {\VЛߏ7هbzw3Jy6~}M)3"KiD5H,\xm5x_>P[}\N\:.w|YV +L]biZ?dꃆ*pɣ}2_HHm~q/qsּۘ-盖37Xw,jmR}" cs_ck­¬BiDNg[ +=[2\eV)_- ?З';b"z[S7:/wxZN(,>tcKecQGݒY^OO'Vt#; ɫ(s5G[&^+2,Vs_2-YH$_/&|>ߓ<!-@}D[B~(c:5< j.*kj)IVdMqO?ǥ2 +&kaeg&;O O- 62 ̘pD 1K\ġY6lHiⵓ@u9\/l:Ms܌GXBƮOEJ#|w'ABbvuv@Ov>4.@{&>[O DqۡozHҬd@ +,v-hm?ҴEv xtFs I2 !_ՐnĆ=|1Ӵ5{2M>fNDqܢN""ɒJ m0-1- ~|F#h#V4j4)Nr̋?xLC\_yL +.Onٌݎ4UpvX]|~<%aq֨q+iؕ gP ~8כ +N zQWIl̷8IH7DEV?,T|ߓ$׌kǩ}7}cfx~)~I]*wJŀwruY݅SNj"Z O+WxQr䛆Y[14[(J'%TE|&¶:fz4ZGǕY6P%EgWm&34l@%+UT3©k^Q<ˍѳ? 3%'i^쿗iVP'V ji[, +Eb\fE$D@ŀbN֮}TLp)A^!]xї>`T;-1s:a8ZJf_Mu!p%9wӨa}ԑ>oPǑ5}?(Rk(=^ȞRL9 DAnr ndC=7)_ D+b5 +p-Q`\d+g9i~@;|jU+Fxl}=xnz1zj|yګ5u" . -sf17da9o *rtNN9K {dsZVhS`Mf~VLHo5A `VLwZaNq!t̠2KW3d] _c x +X2fm{~5qwGj:3zx_pԇ'hehڪH7#%^L8y!xDՏ(d +Fl!䖎*ϭyj8G^Mi^KӞ^OdQ>WUJ&;d#mHRx*Wz5'DJIb0 +({׻:14(2|n۝z[]3k!:Qabf:}Cԕ݇]}u!eue r`2VcR=S"co|kB'] ~\q\_}3a2lx2741b22{JSG3߭jk ׋RNwyU}hV7E:E <}ܵ:tO{e`g g^5D,LƊ]l~OcKS@FKmAh'YGG^ Zg[(xfQVjIQ|M2I!AwbuV1ѮW PR& .zϚ-=7A3 Cشd"H.:VI1EԶu8fH=ڒm'|36 +RMMԝS2^'o(NѬ5R ɍ +`ɼ2?Z>1㶉)Z'-#e[k>'HBeu?Õj~@ TT/P?\>_PmnUp,!=Wq21sA<$?|Xq/]4NL׉׭w QNjGJiNI+.v`.T8ȿՁ<k)u>#-_'-wi% +!Mr9I M{I#1{OhдTZ=-RއYRD@"QהKj̡{> Kh7䠹ڇ};_LG ~R]VպU4 fB8a#y3}|l<5f(ZtfݗcC) c-w#{Ed(?6x-Nuj;ucg0Nr`d[(X;.lU|>U(< Ifz6[|m>FjU%JKOGi1t8=~L%76ReI +]J Ib'*O`-psjipp?u Xt,;իk=%OQ|R|t)F=N|~6 s?sכ6>!ePreuUWHCGGٕ ?*)k_{{Q!A9KS󋒃Zvj[ֲ5fFtOۓPUj1YO*X+Xg_`MBēd1Zet6,)#ۻbް|b_!n 7)M[̂483=/E>R]k$qpR:06v\O5۶&acg>c>>GLX̂ :j;fPk5ˆT+-&izF`R>r8afy(1|AL R!8?Z.C(yOxZ^ǏX,BJDW3zz-Xj&q0p iR*r7J2B~|[)բG\*vu}v2,`m fS.iqv5q׀=ߌ1PChNQ+^3 +f…_ZsiP{A8>'T+ dvN[}Ip._.;i#bgx-1jNm|Bm7Ac˻ubGK4]Ra$:qݢ37rF>pG<>I !}@pJ +[7w |D&2Ȳ[o@kv)z)exx2Y[T G%d z 3iy1B;R!Mz6@1]][_A/4OҨd!B"u|k߰8wCxowAEX E%L-#I2$`.'d  ௜0[ +}P~ZW&2<%.!S@dWW?XypǛ+{j'tjevfvAup 0F94mr.X"| [r&goِ~X96G#Idpo&jkmGBXw3|twU2x~ӚgK;kIs6[d63VzDຌe$T-0;9P8cc$J~-IQOJAW}GKsr6B~C~!")YV@"3~&8̑V\n<5>2 !;|mj`xLZnS1#m|KR2Nzi3%lP ~!pUi&ʢ% ?͜L&L<#-NBCwQE]qg}:W!mǨk{T;njg<eU0ϵ1IHR %Z[w +=#$^&B`F~x 6I*w84/ھy߭Ks?'?Ōy_m(ލ*ɁnHkҬbbjh7Ay'Sq/opG%$2T4|CЙQ|dy%^%IU޾n*ÑWy2f*bZEj~*~kO{<v88?Ύ-3;LX'XBCH{h1Zo赼CyíYfM*Y5%=@(ɕ^aм:V{ɬp\n< _}c^Gy̰bڌN yaG-)nw J+m&T,Ur8$GE@߳rǭ=(;Z#LA \kPc㔙K:1-^9IzϘ*6Iԇ^y` ]%TՁs,2\zm9.wzuAbmF^wu0%п;VXnSڬUq]#{i/gpLEuv(/794[n(^W>VVR+Asa7:DmRUԛm{Ks?i253+s1'JiڊjWØ}' Le;YW1j攤'ˍt<1; n˄Uޯ4.lN\x r\ڨ967y/',ϊh-/hPrP^ ؃jh0Њª'+mJZr= }gu*mK{ܤoec"ZIy +r]ҥv-E[eFRI3H)4آ w6%zH|Z<;jJiqUdhqܗr- e1 +rFuI\qa:>ͬu9/FM5fc|TpԔdѓLw! d賘p$} ˸ 3 >Z S=SMq% e] {oK! 4[;^aaξÖ66kFf] +X,>gjl)|5.K/@3!:("CDJNȖŒhyCGZJRE5.HP%RJq + Z:*rM!ϬHJT|8y`\jȻ$,+wz~9sl +`lPV : d׼c8ia2ȱ9쵷j ^Z(^E/Sҧ]ٸdDOx읣rɬ>S5$WoMZw@\j^^NV~ce:rNA2;E=A;#K KG ޴9ŵ[mNstb4}?-zG{[i f񢛃njS}c!{E{-2cfJH +;"O]{}T,@('0??An9{N#\lh+v]_K +*k`E@ *рPQAASg׾*.zQ~T+QVNl]; o}W^YGVLQNS0f}&f}!T_Lbm=Ӵ4Z$wNV`&X0W[}ќ +ͱۭ TC{jG@(Y jr{_6mfM\1T~ѴK%h9 +*572VrfPn/jYHחYm&F7ppI;} paTc-A" |U>RDz乃}u&᭎f3۽ܕtftRE63CJ|RESp7=݅ &@ %' e  !& +/Z@Hq,j-·}?A593P^%r!"\X)YMYKB/a`@H N/恘Y$m4܆@1 sHbA${1o^LSJ'.oq' i+ŗX^A_%y QqDpp@">{ 5#HȬGy:h9

ֺ;c_,jꛍ\б¾onh)FJlΊӬ`f,nlj1u1U_EUە%@KA%'[L\jCenyh$S3j'LڹC\JC^ڍںoq|S.#3i۟[P1괺Y>eWEg-S 9σJ,|ԭcHN􆯰%5U[ri)5wwPz]"WErIe$ G|r|rXqީg+ XD#2CϽ,k9QШwPDNWCVV,\dD i‘+qRa!O´y<8y F&gaS>@6 ^A2p +MV[#1kPxʝHݘU{qwpVWu؍ =0^.wKYpkSX3_R떯s '=TU%Μ>/cc:tP0yGjޯ̦_m4 +wwnB35RDpGS^lһjcR$EVIaSDI=cp͢Hɼ\ if黆:^ʴWOڃ~{{5!DT+;S&+eUwT:MHIg_a t!IЄCҔ=ma<`0ug0A{Jkn)5&6U;p}pA|[!2@ωaq *ۥwbiD=QiD&97xsnqg5<*;G{閏x~>Yih0ΩRU&mNL9ۂ˗dF,h}I<,.ǿ%sUn,Y;K^2a0T`wj745-jw\.59`G"[< ծ? ʭxsc; Gk=/h~룽7?6KsUcg7l J\ 1.] kmrY}=˲L3٘l\, +J^DDD)V`/;IXYE4>'G3&aQ[Q_[v# ߦKU=}Q-[_e#eJ82U|T)'OBhǪJYLf q1~]~d ϼm|ɝ9E:I+Zv|5TnL2a{ׯ u>j=63iK%}Ju; b<9EhDQ(E蠐?R;cI0=⦠9u>RzKPlo?3[n4`hejߴ2h?uDe_J|FgNT +)iȧɌLERgnn׹qjyX8c^ $U^Nk?Yu s!ӷ4YbVk_&z<8Š W/|9cF·$`3C|(粮ـOdfԙ^6`d7dK9aKĖ%K17nj~#N;43jnwrJ߃ ^D[?@%Zt$g2u|.>>A[cB.Vd|RuMr3DT~+S)Tp*3;*MT1*btn)'ހ_²϶ow6 z{(Ǎؗմ#|i"휯nETn}T얶Pu ?b''f $7.kdW 2Wa;ė~I*݈I ǤQPP}R~`h[SSָus16CABz~SYc\hol)~j\Ik|[MkF&fY1K=S~}WJV,ﰙ]v'ϧ>eא2"G'#o{e/&^\ Yt ٝy4:Mr|y6F\Tq78RxJ;e"dɒ0b&Gby!ac$l1޾Amv U#yd6m-qҟpr''=Y-R-D4n|ثI&S]r h +ˉo}o~ϔ8ك3SV:#нe#҇v[a*^X#/Yx;JCZJM{llJu-r#qL\.榦` 2*P<p+4}d +<媟9~ ewf1,ǯ^/92];tRV (Y !sPDJ{G o56/bGuS&B9VV ~W\nlVcCxWudYlB+a 1_5WnN|yϯ"pXl_Qw|> 7nv|kr6

x뢫aeoN^-Ј)h$1*4G 4:484.Yh4ni:Qڀ}lp[Ac'y3!"/vu$k7p}+7$'&Ǻ +lN>@7$RQq$1s,Lz ~;C?0x/y1槵,35sf`!ZbL`& +/fܕϧX> i6g'+>E*hjQ,X SWW{$H+ez,E&iX.3Oth%*U;ZI ԘqFjdLyTKokW +-\TrhvckS_e}ŝ*bb2O;ArLÜ~:.rXȏX OUwӪS-Py˺ҟ}ϲ|z,>D'׀U-&=sY.{mӧKaOSGhjj*q?"×dq{+.o@!#(rf8,{wQmʜ4$tŽî5Abڤo86Y9~H}L?nUsضmMݠCM$uHDf v 2ƗfZkNvwP-M׹Y76!:$|Ikc>Ch6Q t扲Zq WW<jhܷjbk\5-Ui!1.JRz=* +@$(@1bRLMzN5us͹ CJjvbև;y'`} J`}XݵQcËͲHy ~5Fk3gX9VlbMRohmd,{S]=y7tvCjva吠p0^YhdKCuF>kǠԚw^'*@!q !9(PYȱ*?`uO']$ԛ 2(Q.R}7΃Σ[[a?oI;9ʏ4m +!zd>R^iӞXۄF?JM>)tM+ԗZ2D^\vP'C,J$X AQd֬)7 .7uCǖr՟ڮPN )]D Yg?0*-q- l)&ro~ҫƬLT r(7ie|W9҈;PW'tJs$jڥ1t,ˤ&ٲ6W`ꕵIח>XV7{q;U5nƞLZ *Elڻ:v^VȒ!R%p,'lj%mfdmAO@1TW JPVeA;W,=a 2__RFr }=}2wZh +XtM *$&m hVG@!$=T .G^%q~fZhЮ U0 1[Md5G|Pn>Ë\Loo򲁟BV~5+{ +n<.6UT=0td5̴rqx$׺ *eLXnB`"y5;ҜRn61xUEIEBvQr y_FAijv0q XCg+LY¦SX<VY6̎}IFnސ!pܮ^@Bp| +8A?N0mtPyvUJrs]BcobH,D'`?<`ϖߛ8[e88. 5W=%ρP&@uz]p5D F*~B yQi]J!`Ы:4wR&Qc=O8;DbLN x /=ZցXte@g?M;־!ys]ڀbJ\:VO9f-I!{s)uI*gdFvZ8{FUᶭ47zXτQlJ,ZU]Αɼ/ |FBN!i8~?ŕ!d 2$ _E3V2j;H6mO,qȌX8/^+P_$h0[)!5l^msx8l'|˱arŖ_6d-^-#Ry@nYoSN_P"|\|a> \xSL䱾f-_{su!u~|`=l9K)UkMGfEsgx]ʧs +g*rRFI_1cNc |EW~{yAV}ʪ<#scZCX3[UZ ks?ntusăY=ug?q +Oxq;Uy9Rы8t}.V-?|5r=Ɍܨ2>𑤝x~pMԃS2tpBB 6NKHs~gMS8L$c<}:2;R!6?*8[f-ceoFa^n>w[3UNN?g3_XJYQ/~ S)6Ls:_!=5HGn8}9^HC0Tԋ]Տ฼U0C(b@Lۄ"9( +( +?ԹY3wS]=-#K3-\SDRG_/;UM[S+mַ|Wxs˾,z-xjnK6w>,?00֟t= +k!_ocquKf.5r +qۀ:("N9O%[5u}+p?ffgqXFaa`~sѱCXҸUr9'd}G?& cΟ"c^Z IC Ih?˼SklpVDB3T[$1[ .UJfY#V6D?8Gȣi0wyCR(‹?ӠZcI.Mf.N@.{z|G|ڜqQ8%9E6,ǝ&9Վ(srNF+&`\[LCOcyjG\d\)v,̠d_\{caQ09A_[Uh `> Ⱦps9,MuWU'1G{*KI6_< ~Ox\sg,sv\3q2zp +ʄU +@ʣE:ހxcp"Ppfc qQ@A0ЃA/@}@nB6$kx†~εTjZ_%:DZX/+&[=֖Ex<>\}^(4pwp\~qXxD>2ŮEV}EW +fw +YAPʊ +d8@qc)U޾ɐ%Ź(0zcgF1=?;V$rzDĪK\p8( /b..8XN0±+P{! +26eRe?bR"Hm:O|뮎BILOM3([Zn9(tXHtv1r-aF,;A$]ėk-JC=V`~Wyٵh! "֪UA& 4}+ddY e`n\ݙyn^xPj-)'\R|A<(""7Q* \ IBIZwl([ZsQ%@+[&jLѤqs#TrЯ3 ɱDWL甸fsoC!w7mr;yȽU}oLVA; uA=d٫pV/_V=..k|f{ab%4HUZnJ3ZI["/gĂ%y$b/fVupN`ڍ {Ŭ3A=&f)Ǘ,2Mud_=#j+ ݛv]?FވbE4ˎ*>^_M^ltmY߻8P&'VW%|ZƩUؽݙfCk;^FA4ܳ1GQq'E)$J-YS\W/-/z {+T Ik5]8)}'X貃:78~D3|ގ sG.>1ҶZ s.UeWȚʬsJ;E/8ea6ch-B\)@zf奔f>!bq^RwS$;jT9E]CcYʕYUJ^P~d267zFo#+B3A}Dk2 o6߈u t(Ga *@m{IA+o@4KfYV8A1hʱ^պ8" B,tRDN}ݸ{70ۋM# 1yrF/PEYd^1z Z40\& 0trMlc&bHozP *A) :bzrm=Mw?/\\"-'cNʞ?F]=ruC9v<[7:8Htq)v7TX&5u}tw_ĝ\mt F'coBgOBPqUw/(xN"("rq`?DTRu}o`%wn_vǎ&du4h,kY[DZ_%ƊOeӜVȱ;r",6U}u)3N!IW)Ak)*1~ ~Eef[ufiOg=/j +f MN$ 9"+hQT&EžļO>}|o+SJDf0Evpo95*s;?տiCuiKW,Á0M'tحh|4%kzfƆnm_tJ-NJfg6hG&a0W}c8T% h)o_macMz˼#{_D'EHkN)mqk_F 88W>kΛAm٠UУS'l-Jo|_Xz/Q= 䮏e9?ޙKbE*BP6y>s׿p?囿 F`e,jz1tSRR]^cvc]mjITEO 7ߴὲ] VhUAkVآ2^tr_EXMxx"cM'xFh3tn)'=9u+4 Gy!SV^㶲Yȧ8dɐIqd;d + +edunfr:ÄLQZ} 0\呭*A<(HT@ `BĀ9:{n㮪ڧ@W\ +1rGqJbm}oUslYI̿g95}:n R4ݖu6{62NyURR&0h8.JktFNu|Tn۷SzX Hk^d;n۠V>͛-;X8x<$DڨZvXL=!D8?UO OSU몢&J%)\פ &Bb:ux۳6-=)`abIjIn1yax﯑8hH!\3ߓVʮT H}uCI uQ"Xg\n{{-x20g![з5U\kewh` Q /xܐLN◖΋f ST#P7zAXđXb+_eL͉}B*"^,϶`C8nJT?,6Z0^<_vKZS5skY9TiMm} vjG&fk/s;y]N(}eQPR/Tb8㑭phaԻʌJ$3>Yf]"{[wtx`f-e/9/XWb0Ũ?BiHꊂM )WqBOKr6NIJ"^[2(<KIPvOӚW.s$fMg!D +r'|-׌fǭ.zvsER8jG.{ɏ;YG0ôǢG >h<nq|RJS3\"ט~+ӊCɇI +/T1r鏶9=Y* ;P 'o([.H + +9x&Ŕҙ35N+X@zDp2ƙ_iB{~ 3,e@Ϸi|NAR -6ug6g02`Pɧz߀%bLS-Geq#Dk!\} +~iLqwoW- qIb&[_nDa8-JQQ`J +LPWvi| ~>ȡynq WW0l#Dz<`|[ʉB)m #"ޭ9]ԽHw~rjΦ:ey昛Z%wݱp.0d1OcJCoܬ5lm4>Vyn}0'Urg_(r: L |fu-$a~)( *#r@AG?DȿZk^yNh|]Dii0].~<Ԗ]ruR +M*U{H)''Vx*oaoThpD}V&ɹ+\"cXqҟrEڠ{19??xW*l +ª@,!fnQǶ׍,Lj+J2-n>V=qP +{F*9mK|Q.qO9曢}>c"s1z L,{̵J!0;fY`~fj mfjQ{c vG:o.,}4 ?)[E_=&^'`e ]j4^QnjSK)VH+̪~FBx4Y^az3pc +ܺ 24h*}:8[ QCGk+z/ q'% \R[ism_+u[-c u2 elXcަVyu0w |ߟ?_l^3!=@UdBm;@"}A 8q@XUaC,ny$xћhp\) D1xv3GLMf@hvNfAe @:$9"ɂȿ8[UEm ķS. \%@ W/:A&jFΣݏªyKtJG9@6a-=<891[DA"T$-d (RAzP1M~E/A3 j9Fk'@*EO/dpuc|oat;=qTGVgw $&o=_Љ4TQRbGAqס svF9Ǡȡ n|]Adu(MNSM?X!$UJ} 4Nq((k[PԂ۹]^O1{yu [du*Zt~{}!"b)ZٸE 'Hk߫ O )0: ⣝?deǁz=~Jlk}qyM}握/gbb4&>Z<1y#-vQ +؅`ړdG|C2 ׃BS퍙X6(il| ˡgrʙ,ѩͱ<١ xm:O>s'y\Y"uX:l{'dw;m[ƍu+jǭ͵nl +d녘[[*'ץU a2m˿ |qh,wZ^xUw[ J3c=&;嵮+/vTAK "{Zk6:PL4N)o8+J*D2WC 8+lTkY䦔f^;g#)v}-) +iKJ;beW&^i2f?]d:Eg[};L{ rj&#~a]yp+x8;3vhHؿSUT暆I{&NyOy|X YH a\\p:9S~\AX^N]o8tG%?hy'cءle6jsp<+he%1e`Kf<;w}CëHДd5ʬ3uhMv|W|Sjb=M<[ut'JC^ ?nZ_U4uot  s2xBצ޻%\%qQ5o@;"=0X?}tjڃ֨ 뙐w®ˑ3oÆoIvlodf1131{2zmN}h5,kkxS~8,e,A peX 𑤬:Bc$[ZH)5"vҌ66پa^>櫠_ :gew/9Gj-'$QRZٜ'>R5 V [ZP e3@zS^XFh'̞rRAsa~?}tZsN*U]%P)mD^(p탳I+cK􏭓& +SuAƄf + B3-x4 C%mCz 篟Ea&n$nN秦ߨaQd5TlY)K͐&7#5[Ȣ'x$ؐv/vR=[M.FB}mЄĎhB0%!6 W_IڡWM{9jUmzxɔ! $9:Ȗ5yr;LN#VV۔{Է+nwsV!aǑ3?jeFs̰;Sc*#zB xHJyB Xt?+y&RHܪVYka'OoͰ%,Έe3iqvSed9øiD7jOF>X$.1G0r\w䙒~y3 <7!/ ruK<߳[fk+|ӑ2GPO=$&"f +9f$IO`+M\:P:"YT5G,ԅ^"iKL! 5im7Sշs8_888<:MmU_p?"Q(ET `?zXe +YX?Kj7խ˂C'cK- UQ[[/&Y;F2GZ2fsgƵS9 y0rcK {&>[Ċ^*z*S%^No3?2e3Sٹ3*rQ6mR:Q/ک +5T njhQ&VkdK6%ݢGUnZܠz)~TÕw|řgHZ8B`jx=6|* +a>4 +{KT)'qEҋ ymvSvurdtmLgo`8F*9pẹzC۾]Mr#E9J)(?j.nԤn=F-FeQߪ45!Ure[:v¨\^;1s6 +UVW(I~9;KUr嫊*->UFsA#mI→!yX fţ볜qVrLI3nX'3?vЪ_nF]W}tt֪!I V.XpOݕCO?Ō*ϲpO]&Ƣ.GGX,~ܵ~.BQBz`"y0E\n2{FB)jy~v]Ev􏭏( uS +c^λlQ\,1497ΗbiTi"  nݧȋZτbA?tvާ?Ϋ1c{H,kn^xQCbs,r o°LfȔ9b9P5%]ُjk\P~[.ӜҸ[:9URI˥)KƺM&?z +ūo gF{*ZNZSfaV C=x +3g-YqK4mJtz5ȲwH;6ΚOx]2Š2,?M7KU8C gW5s(&L [ꃰ@Vy3! OtK;V\<ڄkJY2eCUZSJ7@|JL2Mm)PzBX &<@ǒG<dwʀ]J?_[䷣|n9 fҋn&֞g2մa2!c͠',(^X>W~XRKj1ymׄ vI !Am P,@4A)'*([F-gW"zaԩ([eQ0/D^nT^3G.:Տ"giIxR$֌'O7`,h.*@ǃ +Ux}$D:XB +0|-Q ( CRd̔EQHyoˎAoT>BWM6f!knb0ҟW*q&;bi]m{QCbwy\-)ȫg]E)(zm0Ɓ}P endstream endobj 56 0 obj <>stream +HTkOC"K*%(ٳwϬ75Z9з90͂ ^ tIs a6wdO)f/MwR l y],6(C&[;@/84p>oM`˯kc32@.-b{J @d@  b[1sd O^y>Q)P=]Yx b1[*'ccKwZD8w˱lTc*ln?k,߹MzuQJ,y}JC筃h9.~VЏ:/%V@,4#&1:- ۘ6ǫxWh''8?4vHS^Ek|Lgϼ\HѫZOo]Н|tMrdF2?;!Nhެܸ:]B*5O [MH7Gwgg^.Gѳ[ktVtyreLPc6We+oF}b AqN!b?0 ~V4۞Sl­lvxr'Q'ށ-[<(T:]u[_MKi}.z&oZD|7]7_?U4؀CGeL7͵\x7; +gGL 3Ҵ&Xhc A㤙)$R|jj^ Mp{k;g6wL,Luؿ[3o[`m}@hb( +[R:gVTp` cK;3iؠ2빷H+O>AyOtkG: F߶B`*AbLlԲ J韚ٟyF%ˡ^ɝuѩ՞MÃ{L"1JQ]ҽY]acll[R7R{n,bK5>w늚뚪ǶJ|nbϩ3+ɫ4eE22tmc' +[e%y= {#/񳣿ZYg+Vs+"'%PF'=čPZ g+p E nrsVhF22ف,dE(EHsN +G1gAE?߾Ux4jp:T'y0V 5ѳ77Vɏ@Ha,;|ǵp >\ebY"< ++\jJ hudmAYŲOL^r}k"p8C6r^>u1ZeX,%s[ L\~pz#:ynX>-O +ݢ5#Yp424aрF[@yMbTGY2xַFhpmY8rjlc65 q=\Z!&_Cƛ?u{iJuM&2)a[VD3lĠpKuTaچ2Y:-;W`5;20wiGJ'M`s1=v:QX+w1O7_CoGm&t>Ro(O@ܻˋ+eQ6۲hzw5LX)X'g KkM_cNXә)]I5P-A_ְVGj>w&^ e!ǽW+p4d$w9},Fg{qVhDl!t+^iU`֜*hKU]#Rpҗb1GJR"۪dIZڱ!U#.FtR-_OZ_d6,N.SsC&aOk%ۃ[:H^NUyĭ"4L }V Y*O[zH]jZG^֢+bgʣw"@Su)1K~T9$+U@=n.7Yȝ,wa4hCenU^%j^K_5- GZū#U`M=!8Vcm C~O7|xf<^\&1x/jg3g"%8Z_H\+NP zQv܉}3¿I;^Ǖ.v']%p,D~MUۇ j\.!Ǡ>{>S,OmTtG# dHٔ+7:_~0F,H;s8j>ۭ_Asb7O2ضD]FLKh'J kRso<9_IJAP[nh߽$&V.a1ު=pnQ,@;9ۙWǤ}8yuP#*T`z2~1NfN|癐t 8/xޔ73;mEwWaϸva{@#DI? ƩrOB$ĺ6\ywUq CJ~e8a ި,02y싴VdǪPVt A$l{Az˷wyg3qu^#ŭثNͨm+#iw!g (Tn8vF&(s;zQ V{\nmnkiA@-U8V+MHi .9~Bl8X1םQ@;:[M`1{?@y+J qZKJ 8u`>4GsȖ'p٦,t8.36ak:[RU٢KB;Tl-QAPyy'!3\kjqjIw6oBE8~_2QG CnF6.5:'srt&Yω55Op̯1#"l2m|+@ؼ 2-5|G됷 1\ci^7R8P@7>7 w{#FW:2l~0 ^@3`,vl 0'Ely`| bA|,`%"1,0L#R]OZѸnr K~^RB)l 舦 +}*[ʨsl&JaX]." +2։H`׌W>nvvk|hum;ms7`+l5+u6&Jiz>JyKk1B4kBwymOS'V +# wNKJw#zW@#8^`*#5ත!$8pRn]f #Rر!Ŷ|j899^[m\Ωs! }X;F8*._,_l[G.)n~oO1@ M@ dڋ}!zы4eMaҋ갤)v }7ͮZ`l ^X;(''Ah_b wQi 2-G)c<@XwMiqZO@%IETF]ttaV%#t+o :fTg7ihR0~P<3| +1JAP?A/$U$@MX?oLv@Ȳ7> 0ᣅz/+`l\uk7 }Y%w_[Vw*G$׫?mPʿU" 9,H rnE,4ȭ33 +@1.(q@e8jc>u`lQ:}@'2V qTw㼘6>-2? Z XC*H2":,ɃET.1TA-5PQ ^nPIja8uY{<$I kbS=)GfDѕ]|:y(rbuI gݾc( #Wqu"tӰ +&6ٽ3f|,o-* 6;&ޑN_ 7v༣.^ƮycVb?6o)݇mtaHz3uTMq'L(Dr + K(B%`'$׉r2_/ӆK<Qp# \ k qb[nf%ȉ͝L~UKu-Gu[êZ7Pi~^)+톪HO;#g7&C}w߱XV;-~ (F5bڰ0jȹJҋ+oц\&0ju\Tڱ%$"5M 5ϠRk|$+3tǍce%qXnu497ͼ;Zв') &ᖥTRx%:jB3S+sm(טJݽ԰JWP@ly=a?4XA?+4z?EWya0Aa7Jנw}+w2NLc6+ [m7Uʷ.7>efm川eb2@#iR-b۔@̦B7W͹ze6@?r;_5%A5{?" ac{Dz7Zb C{ң~RKŠET)&U۷(J8/@B9 ΕuqgC@^0o214x>F[/v%DtF,Yw~q1{3*/<նVnXՕ$Ǖv1nB,޼c4\vn59 nAl^Kr4|j +В.0fќsڰMJdFi3);TlҷΒ\V#ޅΉ};K~MSiWwjk( IepOS(831E~5wW8Q]c*q6Y:@H Bbd@AE_j.A,](obM֌>Kf~kle8yPҼm-MP;d1LI®\ ^%p.G,@7?BpF% jE1dU=l>AeI+Їp!gg[eXY2sFf6QA/q&>6{cX0W1URxx@^Fb "G@VBVy3FV YMZSY.ջi'PN&Bľ4tF&GdG\p&3CT},x2=b>èCjCh}Qtu)2Z,mDl^gH}OďrXV0xpNY;a, }MG}DZ .PڽBp6#X ZU!""X T v}sdVfe&B9Qlr0rX~g몓)-*9NhecWRRP񖟵"V̎Fm@;{2Gv*2Wki4'jmX~ }5{0Elx?˗Jsín.j(;U#7PnjK rP-vnzJ8]2?J|H2}" +% {?H#6;u_T.淜'I&w5b2D٬D3ZJsbjQ3o%_rpڒy ye☺b~τomt<BqAp.?LFTB&(6O=ݾط-+~b1v;>ȕLqjq"R~DK'b(ﳛJ$߳/*>}\|\v^fGlJl qC93]7 n˔)Ņˣ)R5W;@VN=C\c ?a k◹pW>^O&S{.3iIAt7I_辸 +Qtriu{{lƄZn*zrK~nz.;V*M-l1k39v1G\[ۧ/V{7{@(RTnPS9Tyaj)roa4O͎L}}6_owޕ?z.\TN WvFau*zk$դ'Z+ûc%^Olzzc 2[DRTw*Iԗ+xWc x, ';'iWVOJ"RRV5k~*:|kUbmܞR7Od Dz97 h~/@ЙƽabAxL3yVAkoA3 +{ hsj\'k+Un÷IfNvP\Lxr|AYZ.]g{`N +bZZaDIa-70D1?} %IBJZlيhU:}>DY32wR +x߄O$рQu@VikA0HthM-.@ S RS&ףb߀Sڶ%ҧ1 >ûr>;lzXFU? +1o<H=>ij@D -H? +2~AրŔ5Y3ڐ3,dWY ?ԜhZ!,V9P[S)Q{%(x>ރ)@V>n03 +A"cr9(Z$P +}@{# Pr~c@MJv .i^ gG ӼxaE4f | -5%ykP ܀(n +-r2:l3#w8*( /cR+Cu~XC@K-r6V/?bܢDd馒"RI[Ds8|y˚Ϛs5\ݧBr?wDaĠuA/+S7f1r0c .8k|\s&G<`^pwC9m_I-j@Cu=$$/gфO4 p|{D6Gߠl*YV LO98@: *b]A{TV6l6Z6c\W +IZuCJps~˯OrQyvYm̭#}ic@m@Rvq@(AGѠeeMtvlU怜d R @ ":Э7t&^AK?f@mݰ;ͻ)/:*׳gH'6JO6٧ azi+`D}|4T =?r_啍wM~W^H===CRUYk8`X]+7V4tW}ߨO|p35v* +ECpd n%쪾u_m8܋,^Fǔ'{f,G!#R~2c>I/k㗑;?'{{9[rp-Xqn FFjcSyaMbCܼWi~mdM$/~½WÀ? O؏Y^)D{xx8 +m#ޢ>V)*Xa@v6DD!kT&՝s )+!צWe 479S?QLyOݹOhG]X*26F׵ qm։xVE%bl=nBkr~ +Iã%Wx2ؒIIρ.uV)f7=>9LU ad.Mk0_C7jPWdMtaÄL3uU2ц3+.C_/Kk +4? "~ǪF4*_ћJkʠlwQʐ?$SBOL$ΑJ'״0 GE6Mks\!-k^㳨awU)M\%"ѹ"M4ElK*1QHIwK]E䄼@ABUs|bBm3f e_Cb@!| ҰHTWRcuV%?HBEb%T!rv_DP>#t)Sa.2G~74#wڞ&j0AԘK,F̗֞V,# |&0a#JmI,ʫRxg:0S#xWW]u] HZ"ǝnz4<c˞iO+>O{ yp8I}X+RWg^iLOd(kLՔhEś A"z&,oZ +k]~&[o|G]Pnyl"!| +~[^MG|?Hmӱ&r9%|~#MʍIp$*}4 +*!aBiMMV̈́WKa`ycWֹ5&ےMźo"YgۅAbYӦfx'3fjf\mդtpql8%Dp [M|V\SPo1XJ3ao}D5wtCZ$ %HZ|!EE޼K یPt UUOb]UOc|hH1@,hgcs{7}h4l!к)ϻo?-cD _ݙ4^B6봚LGm71\ՈrAdލ1k1Z-nmH<ޭ@QAGi!GE0njyů/Z^vAhK5aDz4nT^-D"Ǻ;'n[ +2iь_M&5fFUdb$SXk7gZQTt>% Hfh69|h6&EeJn)`ӛ^ʍ4\3!WH  gЌN 'M Ө ۅƞنWghRթ\FlȥIJ#vzG mzhe- #9(FLŀ̨eP97^ OԁghgTer%'տx'77O +l펅:qUh \2.oVcD$V~Z¦춠G d|!KrӬ-c8J@v- dk:X +,J\lZG2-z qiLA20ooSa 7 +"9?r /4s@yVqn5F@M3K'F\)85-Dt1*rX*;ϳyUYÒ_#(sdIA9a |Bn4n]bߚ% +k9U h16.=Dw +{Dc@JЭuAK;JFsU[菙΍pbݿn;d]'royFW8pnZNN+:Fn~iAG`8{SS<` D^`p dp٥х +0m{%j.g~5%Np +6'(-O&^**VSӨs6M=`Xb7 h.>/#8Bl` YC ` +XC|[ G +KŎsKxٯe0H=cC9-`KavK +2pp\  +|Z5 L\H 2priCmeXDSKF}Qva̞dznKZЙכYy9pxchw|w=[|20J N킰 / @0"܃P 4XWLU)eI|^|~lzz0#$r l=EsQX[5# q#_A7k'V@R2 uɴXzzFbD I +"J MT+= 1i˟4%Q%ߺhNQ~Ab0a 5)g +dlM 9'QA %LVnnUe*3vf<}]4H+oU5R<%XE[5զ t|h:.m/WDe[@+(qLJ%P)|8$ҽZTqN(7nGfF^e]Ԁ tC=w'WcHX-s R_r53V>(&=̃Evڣu3xAt77AHk oeڶʆqk9/lvhu'GO$is5VaE'|̂~<|;~>fa{!.nP_0Sή+cӟMzS&ҿIn;G/˭C3^qs6߉.F5ݭJRXUXKYmĔ+Vs8;Vz5Vh-ͅ-_1ܟ/V^hOiۻ|UCG@}kTpPt߯+!FyqJڡ}6Sj@7;T߶7ҋM-9]hϱ8_\. +sʳkXA-2-#C[H%U0 +OC8b@P d`8xCsꮿ{SJ&fLL>Nw=U/񁹴:"  o,Fe^LU{`^[L*]NtyM>1;9|w2gwXpptqh`ذ훵+/QsYFXlM @q?STZ&f{GNcR^OS7 K^gA]ģc#^`vmLA~uMf2UrgWSLcV[_;zz}qz~q*_={ "a;bՖ%Ѫcycsn;}o :XPU K^J6J6۲7 35ī/Oz,skg~v-gV}L:/3m@6>DsdDW_'iL&52 zlb*u* 5W#:4yʵ ֖4SIɢ^F'`>I\OMZx0Rɷfttg`zo|┪"SU* SS: +Ŏl\DځCX% + @NR +:\ +KNZD}\w +r$-kcivةĝUJ u$|x.-sfYf}|O.@] _~|~,>m2{ Q°u7j +jBjKJ%'4!u[)o%벿/Ɖbɷ l̐ymzQmOqģ91z@8]wP*nInnX/}3T4(vFezykbFecfC/?3oM/0or%Mmf%QDŨFCIU[v90x{L-[A|xvJamWFy<ʠΘNt!AkZ6 4i5+ +vS"J-ڑ@FiN~ }ϒC*ŦpLْsL FC,yGx@.?9ż;iJ6^4:ڎdH8NdVI;@ݬVqfD4w`Ap؍D4RB@֎֭/"//.ޯ$XyM 2ܦ7r۔aآ˛xF@)5MjwH:Ljl{z?`QBSɱG剹g84c {z6€N*C5^_<}0WF=2m~cQa9'>XZ#;ovm +wtU?v?qA +D,E%^!w'b/[$,6`zhP8 +@ԁ?yX(`X^ܙfvȮYN˻A:>tCWcbb/1JCnbAd>!cg퍍e/\x7£W>jWC`bd3}VLܪeX[F.1sY:gk{ZR[Tĸ +k] x[xՑ1FŅ'lO,6*Z(=JkOtA-#CZIC3bTPڮ\t܌9d$l-`ȖZь\~J?,:u#g5tUd|lN~9*r喓Z^QJ15d"kRx +!|rxe8l]ẕuVNj2N{ʥVzc~KICګԴ˻[ +9Rb|xr!\O]Jnlڵ~dԂDq/[R=g{Jk]Myb~i"}%:bBSJ46 +J^<t߽*QPybqvX~[M&ҽʫ]-*;|/[SKyj~4*E-JZצ}:+/4mو (%].ҏ:+cYO;8;!T; pD%ǖ`?*_7Luӂ >*кYs?AbԫAO"-i~^fds"!>Kcރ jb > =a"u2 ^u%vCpdՁ[-Bf0(.ߣ~ܿ`+f! +']B[eU*K;M釦֕x"@_ T@Ǽ '7$ ~B[ 5@qvJĀЯbJD*ش-s"?z=t{FiI3 r+2珣ѤR%:/OMQF9k|?׀e{ڛ5\Ly2>2-9+|DO6.] ǒ(7T$SR?3i*R-(KzbEײ$Fgsvpv68-Q>~A`*{Ndؗ)&=25 x#Z<|/w+]:7Nr';SAĢXI~ +:ɦOΖ\΅BMSh@]{}"Ao΢*êkd.s$H{(YwuXr{~&|71uHp6$ $an=(~^ρTۙ vOԳS5sF[q;zM YФWؾHɨ۶FCF# w0]]qQϏXyTJJ )D)=~\>Zs=&l N07RIu*7Ͱ@eS <}yv5WO$(({ٮ@w، n&@7`_'s6wYAP'#q6t z8 V j>e T ULe/k4}ٔGQٶ;µ(~7ۢg|Eb<-./Y(%^) b: "V Z ֠ |iȶhr$]dIM@Kgܦ8)[jRB˃tW_|U֝0x +@d_"]ڨhD: Ay ~5@S |дf9дh~/ hμ=h\ +b$_?#}']lݻ$1ڭՈR[W2!?p^P;kGtӋ| 1{ +YڷYD٥se'Xga͵/6>3|A#߅hz'C86Ր%b-?b,r[T FN:2DmMqG\a RAJ}+CßMD,yI+$[#Z'؊xxݣ~qhdi+ǽt +_{"Oㅜ̗xT'9Pv$%4 `Q^`IͲ*im>~8`OFτ{%.mΑc!C q 6idt;m:=Kpz47e&bQ%gb4umQk; x,~"o176z"2no *Mhz9RR4T!<_eٲx3=bK(+=m{:Wi:\b?&+:fBYE k9g*_{ƥۣ1 FX:*v!ԛ-^{?!CTʃPlѶ>uwc”~fʻPyd+=C2=Cvm645P`WR(?7w)13rBkd8:b?*lȂ-x]~Iz뵋BfkgN9vԎD3[sa[X=Cwضje +-H1\ +?F@lŮg#cs6;~niGwQi\:y"nx?I.INH >>5*5$~6mXZ/yoL&g _L }H2QO5hʸ2UOE eVUZ]` xEVLv<{u8سc7+'UFU,*E<bc5 4buAu'/5 w7Q Vz:!GԐEHoIHɴ8n9Ѐ7 Ki &cͧ]G2Qmײw{\D6"H7u_щ}ÅE]i[s_Dhx^BǙȪaO9yKFp\Y2 4 #/2?>9>J^(.Ňx;/R4΃t+ǮaοY%o`NJˤzq^SUSe"?/JC$d|C1.&MS|gŧb}54S^àpK;f,]XΫlm+sm޳꥖Rrued8c9Aʙ ]S(C+rd?q)ǮU,a8z~vbU\v8S%2 +W^Dߎz PwkLSw.e\ېJ~U}cV͠ŴDx$ɛ, P&`/ +4?5MbOscfd9zgpRBƯ޸K+SǕ(}ȯ%)ڐV,gd1<[7l~.d+'}k,wܮkV[-Alo5Lz5w o{O7 +aYVvxz2˒Y+/(u:.WM}c!cG lwzV_ٻו=sLGI(!h3dErzd}HPG[;ҨM5,⿐Gyk`erXX]`hD/F|naL]n$ +X4{+[e/bcW[.*jXL*"2@8~H  SrNߏA!FUuïwI.v\gI =-X1EM !Yqq8Bʩ3ԛjwZNX?muпWqe% 称>-sK(5^9r‹&^r`-W0!=¯j'&z&,8G%=9h"8DoO/iW8h)qK` ++cn$G_@s>XtrT4 dM- !$t z}l(/0d̡lS}c-Ј/`חQuޱ2 j 0<0d}qHjb0b5!`695mwD@q!4y@Ȑ-ŮľEP{X``jq|Zm]}=X*6C(۔'/"0hݤB:ɤן4[y G"Q1\Z^2?幫@'X1Tޤ{/ˎ(6b"09TSniU/zk'nÑ.biroNU扸?h] WPYڵ҅Wx uCݏ×.&&`=`-U]ofn &0(M04z&YQX A~!^]39٤lfe̖卂|7YUSْhqYa?t)/%Ey +V&pykB03A'L{ypXbo19c2 :}3T͇}u!+v$Lz)E:5pn!8oypn ]I>~|oOG|O|AO_ cy޼GK Xuw4Hgm|7둰 W{w +Ux\6X/sfe.Z62eDO]3y=\ts 7-V 舺q?j>_gʎr:F'ۚY׶ا޲cgw4[~J`Z̦7K5BSLn̺u-8hAy{W'pr~̩_> BvSKçag#f#OZ?EM>3 σE㨫~N1eXܐ?C>0V#9ew+_on{Y%픟bkȶI~Q{kL,gxMx.EPE HRA104/3A[W gt;| oTkS҂}P$i[p_ n2ErN$ɺw?Mn[zL2PO(J=@VgjzjMt!\|* + d29r"8k4A6vVjCɵeS MLL%rwG/[R czL#q|l!5پ&3)di323Zbc 3oc+ɪCeN} +L{-!J X*_J +plJ-W@~KC-ɉ%u [v_<I}pȚH{gkKWIe %,W 2<?h:3N:|ɔʉ ddIC$45nkO![kPWh1GN#)|ghp8Vp"9HN 'ҍ}zsig}TS#RB%-W +(_F|!xY/HGybneQGN +WCϤ!d!TgLpS]i5$6lsRVh ܉F 0Vv|Ku>R67$N} +Ӻ)cp즗Ck[s>@.%>OFaRt\Q4y<ݝ5]fV70|` +(ЯnNYM;ͭY1bWNJ}E7w;z޸* 9՛e!p c ~+_ UF 3etGIv&^6Od02"4Q-ɏ}+-eʼn߫G b>R'U {ѓ8Tot":4jҚT讃 ,4햪L,v|19Njxᦆ՘ոiF߼,{ߕ[zp̻m'$-FLčg8Xy+K%vPfLKv +a{k3][;tNemIL܌2[N亹?Mc:AEy-ע[OwٯVr:i5S'y7Dჾ:v&~xq +eMЀG +]F@3&jsQ6; r'dv@0% 3@u+9v{Y_ u- =ys.3xnd%gN/q:\EOT,Y4^@f~w +…!' 7u~bX2*п q^:O蕟3ԏ /а:{!ЖZ E^gK{ak4'l71uxw2׍K^"^SCMl0q8@=Vh j ż/xWgg WqA 6Z b [|4Lf3J|I;AVyΎI5ˍeԯIT㡊n2=*dV1 K 'R#e4 ]u!YOAȎ%_"dm 3EZOƔ-ѽ{ .syj&U޵vN~7TGUIڷ H| iEvjd͂eߕ&((%k@)KAhyPE݀"F_P[`u@^to=2 7;e Vɽ F= BII2Xv ?5j2!@%P2(:Ijm[}21lZu^A]rWh{9Pm~=Z##G;2.(V"/ ͛,74.5U >A=D2Y* +2"( 88(zs6gfD俷OC_en3AyJ0T nǀ.E@/@#RXZr4/>@6 ‡ bȧ'-l~;uh09}צsEXW#y轹B%e2 f݆XLTqpQx 0y *ރ5\aqݎƹ=Dѵ7ƱWWdAɟMk|Lrxzط>fpOXR&Y.Fˀ m5>j\%TvWs + @/4k`99||`*6lgt  : HU.\Հ S x +aؑ\ @TTW xxHa ホ~8R6q&@Lӭ)4 _֎u(=`zS]|ɶCB,Y+7*YEb"fH\^.oЩ YQCwx#w'5f9/7i@<_OhqU^IO8UȎͣ^\+ZEǮGXaYZXQY+0rV$;lv_vɂ@r*i諘`b٘LGƆǷ t~[icoFV(?KE(?_xv&R +Z&UgQMj:uS5J4y&|ኧ2R$q[Ƥ]ɏn ˤBk~T:Ek<ԉ[_7sO4ꍙZ +xujRZ onov>R˔bJVoD-˅NIzG,^ES4׭k,֯#nFH41žg˚);! `@k:z(U|gsMYG Ql`UuUD^Y ?II&g4vFe{;3}CSiϱVqw`uXZ>hz-yJliak:3 jXb[õdka#oE7LٱAwTЦ}\=t?ZdP-NO +\GǒZA@Yi|OӴWRRj?UmV %FffX,5;P(Vc~7!*0d'ٯR^fRVRl_TNzt,.#4??__ɳ ҳ-/+ojy~ZP'x!țPVEdU'ö$PXU>{>m[zMd#[^H$LmwIŔdwµXCcZ ޺*+)RVOٙ?`vB2 %20MkfUcֶdw9R{Pf-lLAp9f%o!^ gu,K+> +XaS:!'t`^ ܌-ťd4^w{_SjO'I8Oyrw)r؂_H 01g)armO 6Wsiϣ=m73'[9H:]JR&0 # ҥa!71i5d\]@RfFg~F771Ald:& :K=Xj6B5oޤfzz홺-':sE5)&Ի2pz)?>u]L1ٻc0迟Pw Unu&*dA\Gm@!ξV n I6:>qrRjzzJ R߹粇`nZ)= 4]~ dL} ;B@z 9Fpx|9_ީfZ#[)~'I'n-%f ݖA4ȈkHN|L/d a +IBUGXB<$)_8oW7k[QyuI>mV06c@k^@7oel=04o-Wk0'b H:)9\9۽9!BUDY

Br!I\R$ sYnV'Oo-=iUt,kΎxbfP;ƛYrÉ:z}.wIƀ/Q"dnEwπ*]2@5yd*BE:P.-U- +?~e fE1"bB1+VySݻggQߚ f]ѼI^<]Ew-]6կPFq"}^<Ӭ˨h)OE,Ti&fm#@HB5"|~n@7Z\ BW4$* (QH{ %[0zйv` edDY6 g׷f10vPSӾZ- hs@2 Obbo$k$pI|@!ͦT ]v =z86?H>f tu@&z eA )Uc D'7~@b0|QCϊnOb/ЛY[Q"onKKmm' /""V_ZfC }O63d3#[0;m])`}1k=|1=V[Vh@!3q U0c`"qoKrIf޾,Ja;{ԩF~ٍaQ){wͨrÀ0#55P^ܺșύ êw˝dsj)pi}(x-]S+=4_h(qW}J)(sOɏ':e1 NgFƾm$SCd|p7Vo-g^/,ZU__+"T].BJ#wηQ6~s$j-!SB +H_=~QGyRWRʡ5vM$=Fe\5ZvPjLgK17$B2ORB K"i1pig^XU=;^;~fsӦV]Jm\$"o\'ͧhq[rc\{¼`KeQ P5Ta@ŧ{>]7I3Heh6*+sј[n fÀ> QCN$)˞KUi~yn1t0qP\ceS oIF7`2ڬܠ;w74s>ofn:CL댥ՑC2_6ZL阴MmVt&I9R/ˌ/=[ ̚>n6qhhͨh@` aב1qK6dMJݑ;45 R >4 B4Vv?Vc۫z"#z+Z4A*-oҺ^u &@m}3ػ$ZhHvb?2Jd&;~w >\Li|AVu :{L.Xe|FVB%V#ڣ~j!t[R!+ +X >̤C~Wΐo +9a.P{cb҃)l!.zZ[ +qlA#Ldm4FQ4VwdQm'rx3Nzͤ"(y@9BӆsZɵ(:]Zָ3&,n/H\/SB,a;7 +]\l[{}u`mمx}+X IVoKث;/?Q΢/-}$? QˌkYHWKD,Qb]ߩ Rnڼ7!(O.Q(}p\HVcs`XvNw>,\{?o2}w[Nå2n9-tzRNK,rPU޹» ɾdX4U`#o&I]΁8aQw MZ+w!ёGK%赗Q/gxP8z~_\OPɬ/*3CH>'%pSw+SlE/XB9g9>>Yx$ +^4-}G>Et2BX0_g-2*<)7=/{䂻b2R):(WW ~ZXmOƀ *6Ȃ~NC0RM• ;?Wz_ŤY!cƟ~[i,ZP?o-IoYPxW`:L;CsxZ)σ]Ta(,Pyg0W'qʄBگ)Qy2#3m*?6U?"F|\io +L` jmaӫ,lg`/械+lpNQ'q'1:oN#+- n?t;Qm OCl[W{TZEETy13r-h~d$#c5fZLZ]?QiF5 mf Z R:Q ,uC@@O"Zav zX#h=kco@냢H ]i`R % +&6wxޡ>02& bS$ + $0qIAS8sڀE aAnqxև.lsupiR';Ȫ %谕3xҧtaɁU˿SѠ _#JN+NjPn2dk],]{S{I@yWCC`quL15AymyKHBzTBmYR5^ޚaqVh8{Iɖ}qrx{;1 O O!-o=mC?nO!kz* \IwgKMް%ʀs,{<>'B{kYC!zwXTDn΍&3/|oiTMQJ' ;&WOE#u)[r% 9:waodsjBdCё]Oϳ>ۍ/uoatG82V}͜=7 qE-ͽɼH).\꟧6ZFY0( a2mmk#ؗsxZ%S:<9{Gi>nd,>޼qjI(n#JHB; Q|u)c$zxC8+LٽSeWVFmekp_/$KreFY=ҵ-57| EWv ]w-]'wAf+RwnJaa}׻Fg%g 3G$1wʹձ +}(94'ް^Rԫɖ0O9FK,,]DZ~Y YYٵRǴL: 'B.L + hvZk4Ȩ`TDXyZL38#']>;.l d,tA ]@G=x]:T^\@A0.eSR>{#Mr]z_f.ˎaFF,fJ6N?ݲ<>"hpnx|E]JKiC /)5\[T+] SĆ>, G[ U%;$VAOto?m|#;0? {}. o<03?<}Ra:?5ous=SO&|?7M }m< &U OԂԔּb.~nگ/7 r|L */4~]Y4>!fo|[YAs-)WiVy +(LzRZ|zT^f>]+J#(z\,iLAЫib$Ą'(0M E/LAPQtXu%J^ׇ)xzaqdIc@w,jEI4Wqfؾ,ztbz7xN";2NCY=(DZ$3>s-^CNWtlMJteANtvS̷.G%r( a%#ty*ʼnilj>C) .R}Y?!#-ҷWݺf<uD ^n ͬM1[Tv?t-U. x"<C*((3(b*tBo[韧.{O ء:k69)_sI:+%sf)zȞLdx?B1g ϡ>]A^uzh@gB.AN_^Zm7Z>8Ȃ =Q5&C7ˍɅN:x9?kyKAIM*XVA <ȥy +ac?@d0N51):.7zd)Z{D5|!ėLkNJי[7*ZnWUq<rL-_]) 7. +_:OhO6;C:Wh@yyۿML6 %f0TZ[y]Sdz>WP׽%l0EGfĻ)`1oL}_}z}ght'2(1Yc ۅ,N 2CϘqbCQgw;Y*`ZKeQr +_Cs`}m&2> :vy$?*& +i߂}múm+@{=W>*l qEM@d&TͅkZ;~Ye@NEХ;Q=k(;7V:;mi0͢lrOXiyI +gwj9F%/ƣjEJtQz]h?Uߒ +;G|^I[TwGhqgWp(~< -QK|V\ajKz8rQ 0!<; ;˳,Q~kDq nD 9N*Jڢ}H@760a _gW_Wu{ѐAVUVqrH tf;9͗Xp# zq_RYXWIUCiHt+l{~d>*գ A`^}p&AT:@ (5j(1D\#қ/VUUQԙVLJNt֔]|n*Ƶu.I"r +CU֯Jx'k+ 1=eY 'Yz[N1{E1xd05j`tWP4΅CHUPP›4<\ibP'9ƢU2˹#PBEm8@a,4oR(r7 z?IGd/5Rݩ4IvJVj+LF9"_BW ~QTnBJ#JV`ԛCJU)gNmaTݴbۊ&;ƒB5\lb yA[Yn( ׬#Q;`bvxJP':ArPXEI=,OYŏp|Oƒ|#f-cq2KtFraQ)@TKhXA >}7,g u8qxqa + } +kl@rA` Zb!SܷF-SE/&2'{./v6rzE|A~ >_˷0S/0O߲yܶrOߢӃܸyڿe&hG${cz5f4-[uU k>H+>vm?3{N~/Ыy-g(a&FMmFۖ7ܵptQ*?E-L)Z<[Wgf 0&Y<9DZAo(=]j>.t{*_Aݿn/Ekќ|B&I8I6 .4 ̜,1f1p_A?/^{ S#f"=0MuXP62zVn%gy{cRcn֏j&*ԆNg+))yg<8hn$TI }`ZJb]0᡽, @idS)bߘ k\gKwF>hޚdeB݉E0>D}ߢ" + "((n?e3$tU?bDQ!D5:]&An_nZ/A@0 4a g({';VGwQ^c }E[)R hͥh +jaI Ф@SExwM&ʦ_d6FVUT1cb<5q% rm\W5!JoԋU"Tt"oGĶbl ^UoUSaUTS T. +.m*;w`#ޑ +Ӷ0,Bdz-4PBӌѥa]h5i+<:ŗF\&9#0+JrȸD_,XRȜՕ}fG;V=!C)`S_? fl3jjkNv!1b\hOY[<&SZr1`Tm˱(q;_y!ݩlҜovCczHiHu~,v\΢tF>iØX=?kLJoB[Ιß&>/=N]MݥdTرf9{ +k ftRFLvdS5›rD%aޡk3 {/Z8yt)ri?J&4ڪ@!^"7J&KiRQEq(:H /bw/tȌ|\Es+RN&ץ['Nf%u֥L{\gȩi9Do>fc'^Yɗn%҇d8_@B 4܏/r;ѷzPYiQ э~J/M_ endstream endobj 57 0 obj <>stream +H関EyA@d&}&Λg+Xo91%BwlXbA"̨Byd#<" CoYe 6JTK֠{Qb/=PguR> @d2}gCs0[QH6(Dt ),ejJ|q{m||%Q` +2!~f?D#`Wh}ܼ2#V݄>4OdJ|u؍D4Jwgl?߾5Y16iy\"Q&΁ +uA! zn/QDK3hhN2 ߦ'_5m s{9;By^%d 9ޢԲu8M!$)^D4Hı4|Vz=Cy2z0W +\ǔfVeвM&Gr{< Dk${mgڮ_Y(Ӂz 3z_ !-@!}=@k}\{pj[DtYI4/pE6a*?LM~૶5 a.BIWuc톚D`LVJDt\PXl(~ M>-MؿJk); H{+@QOޢ ]( 2|P={8V ,>EJc+Jlz2b*!M=(ž5}]hZ6&_7W #j48Zۢز S8)d~Nh<"'ra>+D08}]|yOEvYS)K7!X{f\w$}yH_u<\'+b^OقEXtsK-gTeYLN8FqW[*mIn*yS58nm7l)0Yq+ѳhvr»arKxfRL~8s!0}>tE{^+wͬeK<0Bq\0EƝse%0W9]:88rOpez +4|I_{F[H˕fQ2j쾛Ob~FDi[_YXG';)MP=P1ad}Iʙ; +=saȝYVYa_=И9:5aܣ0?X+Wn7V7)ʞ09ٕ\Mkh̩=UbZ?,; (O>.GU(*@ +]X-ʩSKJ7xF;9v-- +2>0?am +Ń.h?M%ʐ-^8mɄ\Wsd$ #0bD$ƙh.`ߢ%ye0|M[Sj7,l8hۭʄXfq)+xp@?>[_.mיкB:7ܡEϗ9Q,%2cdJȥ3):>h|uq|GF13{p7ElסʟE +ˆ$SaOʦ-BÐna:Zq93ŧ;;^4KCԒ)4i ' Q$@grO7Cz:~㚦#wFar'Ww*ﶣ)ۦC5ݫԾ>*1vE|^LU> .h)㆖;* *;oS1}{j?<'GyٮtQC3zaY4>5=>JS}"fۢ__?~A3m/hfgx8?O,#ؘH[:i+nzbMcXˆֱ~=qY^s184Ƣ3? kOQ~ ׄ!\.+_D,~}B]ly|7m&n?km٫mI˞1,b_Au-H<>EQWԖΔ.K”> +D +囙( +eiˈܴF0ȀʚW{}t%O>FX0iw{RWəUkkBVk+3|,b׷!$Z єL!;K[Jfְ:WB WMf}تEVj]Q}>m4RHlƜ$ ;i}OHRg{D*[r>ita/e ++~ڢh{mOW[P/d5:=lGUqDPA}QM=pC*xrK{|UY,гJ[Ll{ 8]p +6ޯ6E\i+~Q +H-|')Cu +ysXd]QOg񄅊8i"pn;6;u|l\ kxFl'RjsJd=9?z.`z^VI{XY_EK0Jpq7n]n聯m>wrQop慬b|GFV5>]%̳܍uÿ7iaQz;{)$!aE?0 L'ȫc"hF(i\׈0є;"=I$W镮s+Xf7$q߯;!sN/ե}Xw@fM4N(}C'!JtXmkkblj̇A['V9X% Z[jx7bNL܂KO! +u4&y; Qt;Ɓ0@ioCjNYvX'5%ؐ}2슁QDtSYqJE726io^ic۠i߇5xM} jrL,(|u#!)o7mל>ڝ'5&7W<]ƻ+.j"71LZ|*A&5DJ| ?f|f/Ѡ?4I~Awחe9BUX0mU2q6c)%xY5paNJ:9]K/ 2a&,Bf8<˷(X =$ +' cDhޗ=hڋ+7u5YDTCܹ<*gؽʾeeW2r߇c*&qt+w,D7U ;N] ]n#.OLe|_Kw{;ncx#jHa}s$r{'-ipmRG:Gɧ~%`O~q*rhI0|+|ˠT,SX aL*Ū#-^mpӻCP!gqnqo 7$ׇi\"`C|f H&4[x JT}[@ڙczR"Vx [ww7oe('!Q9 +" ("0gΩJ.? P5rU+tR\Mqfy?j-l!=sm +"=Ryk//@2T-\ƪARtWc$gx8Yy%=d6t| YX*>]}~K`F j`ki&Gptqv>Fy] +#c15;WZ&K_"AmVrA՚)qTw V߇C &Qn f7%4(c/Wd}ڋϛG[975W[OyM t 13<hT`g2Ҫ:9xU\6"w?!'^:U3dAnr6-*}3[еiĪG|c52 [̻zI׍99 ++B"б:%/OHbbEV3v*:ӛ|C;PIgAAtȚRf6 *W$SoZ,bB]7D~pܿ"{JY6 G04 [c݄*h~4nͩVJ0됊>dil"CRU4ʯVd9#ۋ$| "w+=a|Vs#zqope^>G]#Ѯ {Kq:γ̷C34OEX Ewk🚿se9Aw(A d/wNl']ur [y5D~9K vJww9pBUGZ8al/ +)Z/f;2O w}m3Gs x; l6dؙ/`)?0n +Ǫu͊h4)Rr1fi-Y~M5pLy3[]#WJ;O-J5e2IlK;&O]MxqWY: W8M';~&ȋt1]d +:=Pkwe3vnT:0ٽOdT>*RRc!]/>T$U[B q{)>^%e͖;5<92[VTY8VQ&dDEPT/w=}n~YE$L6evIh*"gM2xm)#O+[9v3湜6m UaچQ1|C+ܭ }5נ?2lvܴ +]>_w+86_}c3-[(zp͐?5 BrU{ߚk%m:BڊQLwcnx D꾜nn=mlbF8uO paՇ꠆ WS+PDv_rcXE +1#EDJ!yȺeԗz1ǗtJ^?$qӍŒcGA]"k(B䏐طhChmj)&whv؍C힖 $ۆ2J ܝ؟_VK!n))a-X"~4ĤNdޙ adV6)I|8;~6izjdw%6'ӯ?Q<*@#){32Z.J/\{ +RڒLTki8aUp +(ռ ޯW?}ZnaiBih#\Gu.S3CՋQ. S30VZIa:ޕҠD0d\iFςa4:r࿾GW(va5,'ɋ$3R:,'9O=\5KsePI>Jg}DVԣ؋%T1ǁGvkc=F]s#aPd4ϾmH3zOe*LbwA%Y>s$ѓ\BB/, mÿtyu|E#\7nXveyg d L*7Xdz*p׏+FA ?N۵& !e]_{` +v2n6Y_ʗWhpw2Nw,v(Brə_GˏvWr_/CG>SccXhXa͊gwƹZ:G{{,dQ3Vr OKӍw۸4%DV=[e ,!O0ܵũYӳ{vM;wXi٨TGy,L/@N* 1!E<=U1v#xz#BdKߵN|4ij郝h}WB(n$.wi@"1- Yiê(A@)|I~4e6qM68*Yi #c]VS%w_Rp@{G{>`GY$\ãlPy;[?G77v!cS @kRi]犼@mJLӿަS^CDHAEӤ-{/i_y{geM}b&mtq+muifc2 +dD1Z|A+Ӽ^f'q'F7Qa~]y3)n!!M_z</=;h/]U%?U" "*V ({sOItNX_Uk봽:¾Вz(5D O{UPWFmu<+4Xrі0XVSلfu+xgie^_lS迂iWѠ +8DWT.lRٮ 3m\5:sGGr HGka5JLuӃ?v9ƒəMgKBXJ +}ݬO?A\3fm)烦PiXޢB}wIrS]KK*P*br 6w:-TL.f ??|-cw'n$|c/ faSO/r35 +î[NpJ=&0O+pq?8{ق;=Ns&! \=J +=oלpV~fỏ`(SRGqZE1"!fG+xQYGAg3|U\0`<8ﳶu ,&s}C3g74TZ.["(z[.{[R `O2w9$MG~QBZ}3H;!u*&%YUE4c4t&^kw˳5ED6LKtm)]0m,zxnXE8qlW|+⫙jHN} ]zv6C/G[T|ȉďGtOv}Yh[_0BpgW1(Imp 'qOr Dqܮ? `SU;N0(k|[|%[MK= +˗I0EqGpKw\ 9oY/)R%xn4UWcNmYmc?j{H]Hb3=yuяv ax>~9 lGF1e";3GHdS0:_K)V]jVͪP,w? lnqȎgḿfW2jT/4&~Źx #a} xTKx̲;׾-%>{N`]|KDBZ( fԅݦ $(K3ErnS"R?@jC_s~,Z_̱^Xڕ16B=EPr?+Ux%MחlBqt1<m'T2 ԌAC bŌ07y_8h8%[=΁ lQ/bkꥴ(펮#2'RJ>p#3e~δ+&Ӏ#IܝF6& CcMmٖ {~qx +64ZSv)_c>%.UVihu;$YxCG Pٓs}® '뗁%=vɕ":Qaׅ%Sr]nhwXp:UPMGP6S.=r tQۀzJO#wt^[K[Gyh19[Ͳo)yi2E&K"޵4@mz:vFI*WiqBjI 's_#;̕~䗜}P35d}[@?@LFDFʏ5Q1tl|U΍&0/߁$A-J7_t٧IjSJو6XrG~9;6oBZ?A$6ЊxD`kk AlpX7P  1iL!ymƫ}[-ɖ/ZEw42G1Bw-z 6LԀ9`t-s܁rmIkDrVA){Ғ=>G6o^Ό4T Ợ{a6HT^P]b]زK+v{ϋLxDT1:S=d,⥦x|qۉcdʛTaY̖;obfS0l"Mm4Lиc(`_rͅ##EKB0֗~k'c'L6iV;5/JWnR:VȘ7cJ= |;Է (.L(7|hPNȱF7)%5Za#OɬC.cZ\yʦWOH:<]_sMwJRsS(Fs s ?_l3j0v^)1 .KJOB9t y'll3m<9u6۽h1q4Rd?-Kldkxszu@<= +0o!ns7dALtKwmYs4SwFZڔq܄ ):ѩ48.?ધrS& )/&b֯ =މ~-wCTxHf+$ r/n8za7(b`7-et}6QQ[tn<,[Qeg߰a ._A.OFPet'9Omq +mL|Ë})W_ֲ~1,Bfa5%S=J鋋%^^2[1#y[i8Bۇ5W'پv +y)Cw@xzSQMtq:TնpMGWl4PI7YI]>?{$"z`/)O|eBIˬUY3&7~Q4\g}7P(.zD5l#Ajux>\m ~e*Rޔ:2j= pt_es 3jrqi+᫲Snµ=WONH[';r'Ґ:ޕ]S r{M,RO\ +`iu|[]KŐ7(#.YL]rkd$n'h97ȼ4cc-em1خːt* gB 2`WM)L} +M6ݭ5_:_[21{5c+!Ufy)+m 0np( ;ִIE\9O U,_? Wlz%E☳$MLԤP8Yi@Y&}bE\]vuMihߙmJ7]"mO6f2V18eh0#I$Q^6ODʜJ'+F[S`w+sSۓ"fhNuDGυ!KZ +yT6cvpi + AL64Л29>>@n꒿y'kN]^x׸F6m ` \cKЍc…*h:\i=83Ps^]B'̤ҫY~2K%װՁPEʀ冥& wz'&_N6?ɬ?G JTtI1S(Q1|g`E^Q{XC)~xU}r}$z*ZR ZP2r|Kk&Ԗ;M#0ĹC!B/ '?|.QIj>_WӃ\+ǕLxjˈ*3,澈Sq'ms:vH&q8ey~xQ ׼F;|ݏ?w㮣@Ca`PK;8P%g)/ɛ΀6e,BurH ֗=Й(떋##]|9ƱTN ~|@To"KFVrp9-#hޞS_: kI*kO0Ja%&_?%Fyqüq}%}Esk@uMGk;b̝oq^SXEr9jP# V/ߛYVݷY-MnYNZieeM1 e^?|GQm"3NhUT Ί( 2'9I>~lHWT[NxzȆ\Bǹ72_ODBb yDWa( A V5 }r}@OP1=j)ܐcH{(a ļ?C +uH?vQb9't&3X2#~k`*'5N2("Q0꽰 ai[+1Nzht_Qy̺&du8 +a+jaV:bB5Sm.9?ߖdGkrK>z"C772::^_"CrX]PQ]Uq`ovRn{'߁{덁U[`ɺl|=2vRSb-8Ub>x-?uyʶGl ̜~Ub8,5E-b\UK+Xtz_r#)ya4EpJ[;5^k_nj.3}8!K14M)Wsu<:#Nxk{G񪧥5]}&9Cgzz\⏒kx mHLjYV ԕFק8Ru1)Q>r C+әR] X*qvZf}[vMˡ!n|zJ: 99dn"]>>y4$ //|@w+~9rqΈf{6ޓZ;6~ky:fE*R @V&Ld Y8 A=A:nMa:Xâ-w+l2oݛҸuۦyy-;J{TrNWyrq\=.R6 /vJNVqO2Wjdcd@ + +\~u״DJUbzos5,hz8Ju=lc;w2ĞVBo_D{wUG8do1AZBL6_ЊR TY65P{Ȓ"t 5)GMt#6g}U| +@`m-;}IÛ9!x>kdTTޡl`$8u%':(kۺENvBSOqsJ kgArB :g Hs%E;zcFNlcQ>_[v99>ߣZZRe%?/Pэ׾{^]y侏jW1&OFIIiّs:|3+Q0F&g%= }6KP lg<`KWt5y׈8Y؅ފۍiSv^gWAAuBt|Rc7gcTWk}zPO0'J!g8l02}fTW|=cT/xɇ _fsTbMto [uz{=+OyM1G>&?H|Sb2G"dC佸X˯x!ᖛ<Ù!ȬwWo0hXn=:1{R|xbCxB_z8{8ujEY7 I,6hΜVߒ.R:0e^t&3AƷ:L?rbW}/_PiwL Pc{J9q{I9p~ {M01(z˗eU"m GfL UQgߎvB@t3!JM#K|0jp~)dDJ)~mgQn^&#+ODr5=3gPRC>z]K^L'W3콒r浢uniѪ-o<źƎKЈFRsLf@:S|;  }|) бs#6G]Y-5jBTPr'?cr +9To/A3?{Oj&^. BYjN:v?a~'s=Aۑx\ɦwLht3p0"VVQJd^u>)X>@&lIU O+Ȣ +"[Os3'bzn>?("^n]@Y +(ܕO K H*V'@kȲ) Kpm^OUwݦ*`ql 8` Nd,nF&@f Q v_xGP~*#͢e)5Br4c@5s >| ِ@$\owyYጔ\`e>`01,wWÂ\$Ih-99@(Q6PE@K \P-+H6>n +<dž(BjBєk}^sG8wR86@Ii_@Wo-X4|#iٮn h\5+k~|rmqn$&?Gn|KE#4 vfz#S@6hGE٢I*)k|."NPA3y4X w%9+^BÛ(Exh-cyd:aK'{A<*P5R:`s=`VG y.RqgD5m|5 0Lj5O9sB܏rGnTŗ{lZ-UJ˧t $Az5wvi0|l.K|` өΧ W,9V#'yZQ!C%)aeJN^A,-}Is`z9w,ήW|eBL>3j!M~`g[[VFg?G.OXAy!|L!}Yls\xK牝> 6봾9nP1)nv8y[/F $Z" ^eeD{~SZw,_ܦ]vs>fW~צV6O8: GsO\to`UL?^#o=$z0Pݱs~-5Է3{8\ȓy/wϩL]Gق+7:UMZ$Ey$Xc7Af&)I?xOk] *z'q|2ϻgZ#Q t4Gr\vY5w!§iq=E=B.tzA,K륗z#~6{mEyܬM~.w1=iS_BÝƍ)_bJ߉ -2g.$S +R1LAj1Qȿ#l!~ O p<_Gtii7CN|~[yRM~1 +df6jT^s&*ݰ'/Ze;N5Hn| A #w埐m.tXSED/ 3N>At +R =p=X`w X;h_%\̈!2)ȜNI|>]hiwȟ;;Һvuw>⵳j'eO;V|p Rs@8!nu͵}6!Ky-+ PnIċЊIVFmWe=eg3 +T$6)XN^vz0vji\l)AOƶ_ċXDp Ɣ1B.ygNْgn4Q{ׄ|YF J*o[. +?4dthb8*5g_5Hnqߕ.F󚂚kk `cta&V~ +g6C;>Heu*ɓ%Klm f0]|iskۊzOדPzpN׃$<;NQk-wm$a !DQqPqPDeB߿sW׹`՗d_ @Rf5C L Y,doZ-rZ1?T +q] +nq׋B;~9Œ8qqq5jC:0zj7H:I1b3Өؕ DuZ9/$NuuyD5C~yKRrP @HsOG ̎o6S$O),Tl6*g,3bst͝L$rw:ЌT:=@$]@R%n&b;6\ + df"<{@h [yҁ褁@4q}N:vӕjS_/ AԴe@DE-}fY@ƣhD.3PӲ J),l- !^$L ^! 41Ҩkz8 Vսd;xXs }ݨ@utƶ $@mwԀrHer\K/ Zl)҉OhХ +V[jr@+(,cz0䴷@O>w_71YJ@;S E%@YdY7OkTqCO@iHFF"'pd+[^$M _T+LzLf5` L-:}%l /㎐5@9Tu"1"ÌT[Sn7eV3̈́_Ly^XOqX`'',5H$hLPҀw`E[nqq$n˫U螂*߃|vDR)fS9[WpҘ =*Wol{W#鏈-΁QrG,Gx,t c@bLr53AIQNr|;R Z5s t\[[ + $Y3zz@׮Z?ȩnQ4;)ŧ7.-k_ۍ;YAIK!kd+rA'Ozvs l=h;Ǎ^*kVxqά]BӞ!8=®:<).}(4PP\J`t(BSQJI됾|uM!&Qqh;6=3\;^E}`-[L+5ً~?"qou"Yf3M +J]022THKM5eW?ὄ;kyzh:`7.arRޘ-_jEtWz~uKd*{k)g"cxP/'&wy&SΊO؊ƛH:&~9k2*WLX jMV^,+"ū6mvy'vpm{.*ɻ_" +]LyrP=+GigS|R(a2RHaҗsxV[_:I7&h$DP{m q\>}pUw9FLLk"_f]WV%V3v8gl+LbZ- ?-uM'-K һ,##YR%.]/qk0pin<İ35N,)Xq#ץ:'it.Q + *d|H5 w"΀AZULBK&J}0.fxK&]?=xW|q9V`MpkGԘVMS>O2z/sQe%e]ҳG%;cvwKhv3b7PZ.[ .bn䃂ϸV`W 1z4;Xm I`L&]^!#NVIfP?E h^bW`@30jLgh|C2W<El犉 a}Uurꓚ֜׆Åw Ge9o}ZOc͌K2jɉ|A:ϊ$ۮhw1#:{%o +6(ѱ@uHoӎI{ ¨Ϗ=pNm._b{jy^ЧPpɹ lR b8!VU/\Ƈ_m4P)2l ح0ؐzҹM8Ovۜ njie"ĕ6ғ֫6gHI1k3?ܱ9 f;gJ6+*L[^&Q%{}Ք{bxqzCoe'!(بݎ8L9ku +7R *ZYݬҰ3/Фi}dV%kkJY3T{vAKf$MJTyPTCEIa')D*lYF9/_;W6_k9v"#JC tkN^gML`l lPLW*2nby4Ҫs܏$.Ӂr3mIUk| l)tZIy3mޕU;`A&4=6ط#E5WbYJyvB_Cv׷ii.YI\uS {M}r35yd|Qgw%1~Wl{u/J I-҈N'tE$?WR/%"J],WFM9/$wF60*рmIm|AF٘*| +&59]'DN`8v j͆YOsu$lYJVאv\潫ȺG=ƝEn*9|.l}{"›>K?/dZshXdZ7@qB$Y% &nҚk1?s@b)6ĝt7NvaBF/isk-rړ hS~T # SƘ32kZ@ES;&0D?γWIXJjp7qkÃˇ\H 24k^g-BKO;'@GL(`Y:skQ#a019 b!PI!6MwڦCq4<{7d發=<"ZUAߧ+xڊڭQV}0V$_gth<[d/R_Xo#9AX_d(7'&p~6\ש[>;h1?!o]XRpbf5o;9Bg:H'ϭ,ʂU zi3!s^gW+p|A:F*?%ױuvw ֵ89V|jK_Z_0_ʹ+O}}|uxge}(&=\0' +=qa.=C8DDHQ:DBD|1n~5j͹sw˽<i{PG} ȔNݶx8ft>X VP;nR;sNjm[aœ*YYC;\Le,`5 tmdxܮ\M#QFy8󫪨JeٽT{_uyU6wa@lLj@rs|8no"X%pkĴDVqj2cϏ ǛwNQLBQi\ѧw=.%0ߡFvJkA *CFHŗ2I5^QW,Y%4:7m'W`_j_)ζHY>@cv&P \n1Cdj=Wo[ w73zW+?Ŵ!)Sϓ͓"+Ukv@qx᚟E (+>L}CYqׇ(gBgX2L" "q¡tC +=1?1l="<%=Od :{t> xxϷ0=|i خyTOUf ;sR,j5o'5!b^S=X} GU#~ǣלP?{Ƃ7AMލo 1}mȠfgrާb x uwB>r'*ke.w8jjyB]X#Dhۡؤ\P{SQ>rK t$5xOLߨ6;3xPXߊIE/u^tY~-P.(gOX1CߌK<A;H$&VZ7d'^@B4!Cm AF=)uDrd̥nac-v'C?BOҙIfJD{6fۚdѤn{E~n,A]:[NU>2(8k΢E?SG7jj0mVA)Cw]+Ը{!m]aH뉗r1fOct1 ^ޕ_|V+bh^UNmWO羦U09}+m=)3>CGnK䎗$7]r2g8`QS$yX, 3jE,YM;2omhnFsûRtjպs"!JTf RQ'm8)O.z[)nnNSZgPACIߌ;%]5Q%[Gw1%{o 䛞̙W Db\edQ4),TqGțTV@LC3G [ЈL,_ ie2h%ٳޖeujS0قVOA(sc*KCXX-E QmeqR|^8}Y?j5c6ciPiމF6lqzcom^U1],YN,#*9*KƉD^B$,]HUiHb6Ga@ftݰ ΰxj4w +gbh:ah?pzʒU~K>.^2 nt'4ͿtxC1FT s8Ŏi4*@wC(׶r_>H90y&i̓Q69I-I-,NRS ;.It5ى-K>-ԌK5&~#C<Hnt@ +ԊOMO +#y- e ƣc 3 ŋ@j^r& I +I󃯿J'8f,l77(_S H&yI}Kp/b ``4 -2@+q 0(]5/H}{AEt3f\? +IQ-C68TB} +0hJi}z%M p p` +h4f0FvB۫&Wʽ/E&1;ٕ#njNF> ^mWtrAdNhc)#$/*  5v!c crPNlw0~я,6v4Jn +;|*Fyx=?09zxd{/4iy} IYd={p/$IȽzosE" I=y2]xg3A`H>V>wvw[d<ܱ¯8`aķxk +D,8@ E ț5W:AAҭxaPg3|׏c{rz;k|{ ]^Kr[~~-fTPAHAdzUr\3{]cu[t#Rad +Aօsy e Mk YG+{r$4?!lVAXd[((~vozc=a优~_ڢ]\ R\jcؑҟVP3I[rlL~?_lNrwkvN{?r@tΎ<86,oX-<0 %!N8zP^Z^\!_z~A\O R]HBVz,רOk۶+3Y{ӏdZaVەױqsU@=-RReTmU3p͗lf@A`we米]H.U|y8jm-L[W]7{(մ/:Z͆g*k[RBg{-/iVY[^F@"73Bʊq-s a**^#;<e=12l,3+כB8{K^^ਾEYxyn>|xŒYW{ٌH'RJ*t1}%g3OϢb:(Bw[2tYb.^⦫Y]֟FW?~m}ֻ6IdIhw9u"mTGS<Ft$pi(;A" yiuԭ&@4֠]s K6x7BEL\,v~s)W)|>+ +~vZ{c%&'[ٟ흳vwLYX.tl +M#ܴFTצWEYªK`D4p*2ĐlNykG&A04O4eC8NJ3z_02ȅFVFw7En|DTut8o\Q 6/Ӌ+",ҷJ_6sI3f`]u i췧}X}t{n*~Cv#J~&5vg=P!yf^wy{UFwh )6Jb1ass !=\gp:vs;!(0fή/ϣ*L@G·\,lrIJPu-L&>2bR~zWJU \Pҩ_t` B[Uy8*=>ŗhzvJ^5xߧ-- +[c' +<'؁2l5{ʢ8YryC-E<]mN&(۬?&C/裁a}%$愵]EhIhM=#[)]<s{K!!k,@DUuf +&5b2'E"ΠZCk~3eVԡĐ0;mJXϝ(pe8]:d .і?_f^ +{qkJB!eG#x B^f~QyԶ[ph狌SVЈbkUԦ1PD_Se oEDÙ?d16V"kPN/lkzWЋ@H$"v]iw?σ3s'1]ug4"Sq8$9bcb?׸wi7ݖ#fK\JqD|dnYbnv +1[ٵRI)5{yo&3턾c872(_)V"{Yiٹݹl^ ZhN4sc9=j60|&EXGRB4Ġƶ{v6ȸWIɕhi<0zSJU17y~Vcb0F1 hXpx7"2):&=]EoTѻ4-&x:-h5C^oT|;'m:IPiҦ/ɏB adbRZ"(u\ a0 ; dpXo)!m{/~ +1?c5}w03Tgi:jpl#/DM̃7+)6`P'v`)PaU3Ff9?DSF ӟ>o܏iN|Zr`T8ΥyKW"by޴ifp\znRS3Rd}w[S`ߞVVGsۍg?鎕(i:ia^JG ~(UbRZk@EV E +~xTs56G!h*art!j&:ؑ.넕^q+.˲o쾲Nܚe3?eN&&j-ΗݯUz<^q6a)vSp^jO=NmIvpcfrx{=| +:Qn>d.]״²1g{+ ѰҡC=>;y]E}rt3x&}C9?qXxNK\;YPMX#r}Bd_G)]Qc[lӘGL0-Lٵ +m~C@tv^.! +Ojx;!+ 3xNCG᲏U6a B#oKb,2FDBv(H H-H_X7H> + -BC? J C̈$GC~v|*`QFbD1ҩ!19RXm-F*1H%Hm ~ȃ)M ŕ:d +3FH2`ӀgpE?]R;^fQG1ZlFe0Ǩs1ڴbԈsN]tkP;º# +L<`5@-#pVvy,+DQ C(sΊY$3n9Q/޽WR($xXd[fOp0 C> n( 4^dtXZdM2)* +*d dkC䭈}nZɕI汾R69E,y@UnG?jIN! + ăŕ/ k?_=@yUh4B "xϭ'Y8[]yYFUMeg̈gLmCWh ̐ Yi047`aLr O9\͛d/<@edX6E)up`H6rw 얣NxZ$ NvzJOi˝˺Cd鑽{s[ιp0_W@ 4f'; 5#-ǖߣUۖwF^[!"G&8D36E;VOpp72/5c}$eVt Wa+G=&s΀אh YZF,mj_̓{G +ySSn˦!٣И,NokzK8)=\Bzr:yB^wRSLAr{Dne=Aٕq+}Cwz.Wqӫ  +Zg2ņv*3MYNJY~7䆥0[p<p7 /Uaḵgqjd'keߺ~|ZG KFkIe]y-8OA^]iejdXinWĹ,$7ځ\K)Ƚ* 043#ǍGdF޽$Ū} pe`7frŜ.8y$vsźʪ*hvی@&ԫjo% ozRV ?9\{ЯZ/0%u.voX&Vy!V\fbn,]t)Д͞r(`HBRO4–NkCs1ոPXi^OrQB@ԞTqۡ\lzG^ިhk+oC +e>^oImMq 'NA}@Q+9npF'I1b{zdf`՚*r׹|ZjO<]+^v؏`Kc,ʽZ_ӫ +k3OGG$F5g]Vԡ)knTU(F q@/v4qc霪kj[9TeS59ϗBc[w58 /Sz/U+S*U!}RpKKXk^e~Pӛ8 iB.9$յLC=sξYĬJ1IB1-[S/V~}ޕZi&*-SPpwRFqn5E=Pmkօb3{/-=ِ{RI PޖW-&PDE7WA%jz1?J7!kVaa+um(p}BJJH%n/rO(hE=.g//hⷕјtX^LԹxMO>$0c٠V׫JT,H70u S|&_apߖ˿V=SDwgاxsu]}.;i rwg +sLz[N:F3jTZeI%4h /i +(9%me4FqCr/BR &Nݍ7;rOr>@zm e80ǫ1DMFm渚:C)?&m /^tgZ_Ov +y/WNP2'g~!5SU KSd-@"~a!-0]-6OYP>KP=fQ/zm/<$;KwtK#FZFuȍ1v:ea77ǯލ1k=XpJk N9B Tf^㙦KU9iNc{F*spŰ74lm'v#[?U~twTX z[ Y]gqm+`ԗ ׫/W"?gVC۽|꾛^l1z8漝fϥ<4y%<ۇSU~ޛaZ )$ʈb7pAsXZ|JIujt:Z~P7]h6*m +8 +hGҽnT]1a/ k+N'7&,Ì>E$IۉC~P&#otg->`ј(1<+j13{Sy~;+zM)DNL+j?cو.ym2QˠH5 8ā,LjNugYtP x~<0r0 |v/7qNĈm8d ~~G?,$|!g^cWdk18E'*Uz \nuąѴ PzaWIG8vnI@^-;+5- '-D4 kJ+s͕b 8u}z;H%{,Go*ۍK_AI9 r_9Y+L51߇hײPqZF[V8UUjNNH۞˶y{ e#nA'f^<zM,D}ӰV~& ^X`Ņ$2&n$@oK$خe- W(팂" +H.'>y +z*Zs #N7%v][d.f Sryd"frg;yf]D^^z{Wq yE-10Y #Ƶ.J"Q/$떵fk.!N:ylPX+H6Ir7Y%3AF,{rMxh?qtG ebe割VQiNfwi&Y$\@{6Qg-YtyݵE?cCg*X5suۊWJN_t>d䃜rl=-Z>̛:c̭ +kM4sC:cr%y #y +lk*w1i nx +;Ioӭd&<g +^ߎ-3:??j%Q.ɻ]ϸ6R(2ɡ#K_ġzR  %HRQDpfg6^xеrve*u?5UǸUMN +ëO +Wi['Og +C]\w{h[zΘ jkfz VMKX<.wM/jiOcDu^xCVNEn Od>7klB=yTxn)>fo> +z`x;ydo& VYm7+zY%P*Z2g,t+KYJ% Yظ..& K>2=$sBD>ؿns-x +:}"65[P'sja>NQUڀܶ+ߊg ig".%Ax|ീ/o &__^"dױd_N2VG^m9`?eǢaRHY$e]/_N[գU_ Y}.EIUqś=DW_ՌLшs +6mi0_?Ci&渉?"x}!-`C{j9G P: eT 9]4^< +kx<;҂KD0O"Ld3~s_/巋οJy8xrҪkomr63f堗n[^+2#*"­ec +8>)f`j%wm q*u?#:^rtet_Z_?<绐vbC)qc9g|Dv~m +%(ZniC(RYaWnѩ +4;Еۇ^ +=` Dș>{.@"!Bu8,A"qgYTlz;M ^U4G4 |B{Qr7ck3TQEL'݅@59̕P}0& Ka]<6t63zn'֎9K7tڨJn/QW|Ta>ǃ…͆JaHݮ4e3%@T᤺x3 ,`L7;XL(,*/ހi{v el?]4<6OJ|\/Dz(qs{)Z*5-Z|gR Pd!Nà y|w3Lо$hLh"I 5?bQA3ߑt5&ZZ hG1T$=8-rQkd 1Co|e6{(nvz$K ?* +-xV a<*XBb"Hp!8Rqꚧzقbϭj-kΨ#_ %x"qOHW'hlO)Ex6i KNGkao|p)GA,  T@#ccanB 7sys"jd.$R;ʑLjUV~faYjcS2K"gz(VS¯c j1bjPũ!zWǸx`Fp1 5uܕAw0U]Y~8`3 YmrS¹|*XHTQ,q>KEotBBhm\c @z?lևH+"HQ Ǯ`=@r;l6{y78~#|qJ63lk4/o5UajA9zFs3xKE u$kQ] g/LC`SSY|Ed9|+*hh5{Ζu,޾PLh}1yټc(QxZGhbgm,Dُh(lvQ2&HUXnks|ülXLߴ5/)wq\ɨ<;¬\J +j.B~fzyQ!I6'}ňޫ,1/f8E&U.8 +: SĚY!~~܆W  wQh!!k`dQ/@ҫXɔ[ +>cD{QȈ :bb! @t]A1J6V!toot ;EȥX2quXڐ2{0w:0_o"ott#^GPO|ZI#~7\iC0v,xl`xgOu@D +y 9Cc +Sd[ѕwzEp}u"f(ü'&W + n`1*/O{v-ׅ)nA*H1A8i"fᎥ6 RjƒΖ8)obÚö)=D{w [ m/ BϜ{KW_%Kt5]'{H=~s'Dw$v7 MY{+[E^ %I5De/ޗkKc} { }/-iK6࡬~tK^2xc5̉ZxOL;շ 0_^ endstream endobj 28 0 obj <>stream +HdWˎ$ W@判^z d, s;"SLDЗ_^_]ۣ]۽9n_zz?v5ÿ=~Ãz:G^]z{ Lj=ۇ_~geOgѯsZ\Wl9M?-jZɱo/qzXޫ 8B.yy܃{] !}aXmmkq5hn=?Ɓ`0rD'ŹYǯco,| [ y{0{ #ЯˁnZx6+x띧uGrRx?0kּb#IgVM\!eOcAvptI0 We4Bu$`S0O@M z[lA0j`0v|. gl_`7 +Ɔ0!FHdƼ A$rk5Py[UZſ(QY3.a\Sa]F Y+X Rch#R)Nz=&;x'Cm!1}k+dGtD0MrZ}@sMrVgt(X4k^Ošͫr(5  :i+b9 +ݔjGTWE.ON1gcA߄7t Ox\ARi5t&0gB1IRHXQXԄQ24V1> 3(BTb!17D#0*%śl!-`cZ#&%^bD*hal. 67GRA(@Ϊ6Pr7NiKڭJ32++zR:؇`t!i2tvNCPQjS5C$gsq Y1TOh9\U2iP2fբCj 8e@D3b(X2X1 h2 \g G4XaVh+ ԍڸTbvF=/ك|795xb+JtWge;vmG6!S8T\KllP ;y3aM]eY#D z3(9~ բa.Jܩn=KYU`嚂YN*f8ՖC3ZH%eˊwj<@KUmM< Ӌx<52LÒ"NW\}hKHˏTXL'UwOn]4*,ToV"zpp<]ROhI(1&LLbKg]t=pDc ! "Fb`hl4?ܑqF={P=lKMIaWUC` !FTV&-t=J)t@&KMX,';Mub6{dg]Ul ξi~-Kc^-T!ى"<>ա +-O+DlۮK.g*QAysުr;f"@?w1w +:WU3)]^Ӄ[nPqN*GQbTT i;[֜+$WܨܵhsTTG8iB ^1GI;Q٨ŭ/;(+[hr.=BK$s;QPFcJ3 JMwy tb ON8g |a[Gi;/u33l&1d+%BX L6%r U`uKi/z"%]z4r s\*u2di8 :&鶹faҥC>{ԷpE(>+{%iQӬM9?تSͬ|. 4dŖ|p٭,[aY[ٌShd]Q2u`]_vrްP}Oij߻ϡ@@+RCyxYrؑ(Uh24އkw`UIL&ffۼbWuN/@&M0wu>~@s.7W>[KPoBTئ~\ kW[ NI4AdLo>oc jpwI5(mVƞ&2PJudo4)jx-QEb3 7Fx8EBbekr$ncECXu7x4HМ"h+ A@" +0)kLknK a+n4.TLXbb^Z9S%bGhآf/c+%~Cdx9WHjNM2QB{`(c͇4^'[>aͮ);S!Lʉ%K =sFRf)V@BΥКV8ѐ>ʤeNm@%*~4x,Vd^:5&8Ao"J£dIHpRFx{I/Bܹd)9ɀ:P,E#Hcc!xN: >DzIhߓffaLr#+lZ^j&,2U@P 8R`ː4jX`Ŋkހ6zt'}Ko%$~Yv8π eǼI>=~ո+!S?PBf*=y4jљM$c6-՚ vahұ+o$v?Su X_Z,@,q(C;l9X2!P#?x1eXmU7Lռy>]{/ Qȭ1Oc{Hn-vHlݹ/Q.+.R{$HLA^*ͣYv]ۙմ2*  Dpx;AG L@/,LhFSq n.=c}f6qMU4U/:4TU)t貑KЖ:ˉykNomA:2̹|how{0Zk<|:;N;K]Ӡ'kW O@N)YZs ڵۦƓ0Rz$'Fۋ?U^q_BqZ(U K04d$',נK.UA@nzQ={9+2Hta򺀇@a4} +M!U,T@Zt=tkc(6I%s+g]ʾf9 C+ӣ: M BI[:cgZ,awwV'bVRk. 5|c&f|QBeY&ruwahxmFBvBdrE6pCi]ОݛٜJ"GxbTY5*Ps!Mq:Xݗ`tE߲}{(zO{:[Q +As ;+V2w]:J)F jd.8&ߦ,dTtP^okJ3=KC_iߕG_ʯ{tIH*rūvS !_W/WW*>}^zwhJA)dy=!h\R!zJܖJ^㚓=A ȫ6|yW Y}!zQj*d'Jw=sϷf8#4Yk +Vjo?x }ۙ$G\& +ƏeZTD69 +-pF-8e5#dZ!"z.s-`iin zBEAG,cYX=\7#Zh KQHP}EJ帺ɱ4{"jWVCȯĊHw3Ԭಡ!~tsJXw6SaQFmAm?B:@>Loqŷ"-Նvx= !k=C6q&6 mh}c^y1`~g)N:&잔 q]߃n@M +T'fETnS 1ytN_o9̈q!J}|E;XOnKTӾH/of?'29 y( =2 ;h#|a[#{-(WsK>@D:¶" +xO(^Eq| #BGޱv##]QG~+~3_ww_3pC^B7qN\kBwe]F*~^qo~Ym`m0nؗITU  1ܫ OX,HɛҐה#@R^szoR1^2UW^'k=ۭL֑{Q+)j$@;U1 cٱ % +_|^@Aɑu=@r#Ocl[P_a |ZҤ8r DjQu2egMx!xt +ФX\.P2QMڰG-1ˠmSy[Tn)k=ڢgBje;u./0BF|kKgF 5 wUa_2zh~nI)XtMq7̓.ESP 1ʳ/.Zu+XeSNy-' +#E<mM\Q$ n~o-G_2'HJΏ#- k,Dś"K؏KZ)ׯ #fBr;%2ڵ3:E 3qVg_ +?ntY0t;:_5-ˏ ? endstream endobj 27 0 obj <>stream +HWA$ +lr$ǀOaafpDPYU=h+dRd0ׯǗ|-}r<~8~<~}3N+e^~#o~ڎo(]Oo ?K;4{i\fǽ=rZ,B9i߱8 +B\5n;r}+!WYe_kiqɌu|#x\]Tg44|w(dƁ3Wui$ , 2z5jV ]Ndt9-gu *_G,G ' ճl,!r]?nm7dF9*$։@;B{ϵ}';6`TL@#cyd3"2z冯]S +C za+5kS3\~7DY}FJ!0adu"!$ +cAtSW ,gÉ АVր;{(ܦQN2ckUEpCg+sl md| }n6ّI<*3:Lܱpzy2GHM2"}ây YzⶼMh `"YU/1Nd"^I.`wR<tMS-֊ qq_!`"i=.VyM,NˋTT;2gnGߖHI`er|ΗIa贕Hj +D{z_Q1u/Е惮Py='}V`ڰzeEqL(C'!U/jeV}=$w/YjB_2MeM~ [*gTh秳"Y=l`:)<6;1ODn✱3H~Fm-;(fR.N'U +$arXj9k.+@U]{\8L϶CX,qT L-sQMR̶74iUyX}>-ܳ. +Y"VuE:{g7ՃLy翼: ؀9?2[]ol8|0WNCx}p0ikipk& *5$nemS0*hrYY.:]n)B$ s7";Wlbzr`"M+Q E%k럱]6"J)Yyݴ,k*$5eu V2 􀳞]KKqf>7٬"}LcmqPP^v@T̎0Ή\S2C) +t)('%˕gBRm4E{R!І ^fIƬn $ZOfh\e2lp"F +ᖋ tw&! + ǻBud; s!8 Ϋi\zc%+ې\6SY<&32ˤ4kKu .[ L!w/db[Iv} aI +;2 +S>op# Pvha|1ڎ%-@pC7 X1bqx 14It!LG4k|Oie TqNxK9?o) +yJ VX֛EM]Ƅ\"'{-\͙$5-#sZh2^O:OiAƓԍJ GS2;^xZ!B{Ϲc)f9͛؜-5@`p1!Z`i̖0rӖrIF\ugx;g\X(;*)&HN5$ `}wLgBIPU4,}Lb8g4BAGJjy1JSb-ybE+{cKykht-HhxcHZ]tnYLc35U+ru%&Ÿ9(("y4O1Erkuhc#=OXdD?#yb_+dlo'Y1c[o :ҚkUcjmr`l<7fCk$`zMQO0}bjE*"YHD+Ao}rLncՌ7'O1 C(jlUP 2-蒞{!va|$kKl%{ȵx' O)-fr7u}P[s1Vass!Mj +:bQpw]Lp% zb6sL$U-B( I%jnE݊`6箯FRpE%1W.:go.LZv%/r0E/~.I=tKC</03ގn/<  Y$=hO\)C K5ozfP>n-՘w?q1ǫòg V ;H=t8A^{!zL,Fw.=WrZN_c]{~ &$| B㭹eR|EQ/pO`o/ +S8ݛ HJslRVe 10:s-:~^]1۟vau SVt<_szA< +P;=ґ{qE$'zP +GA3!AG$\xQeiu+j(37W*~VKJPbuQPA/NnCS?H {<:C~1#1CP xw yG|>E'ݹG ׵xG*tPz ABŠ>L&sv +gLJt; =cqMGS[^>'LUE|)UA%kOF:bף,>OM;μž Z 0119\{R]jG̃rAMw5nx]br$nyk ܀꿁:vy&|ʜ"tG=z|wqntA8b3^Yi${W+qXWgWC3:BM&rdhfyk>#݄0cTݲbe/͒::~q[h2XKRp\(|߆p,hnVC0&9잼eh%ZMOo_.7䞑Ys [W)0?Z)әoSuuyvuQ6]=cMX0'`tJҼ P,6Ьפ4Qq-|:JUg|!/3@F֦ +??('K' C`Ii%GϞΥ"`'& "{9"h=0ij$4gzUDg<~%J7=5rm #a }\^Deho+ TOOJ7Mg=gbIl_8*pZy ߶ux|7|Bu("xpf{ZhZyFhE`|BC6ԠEwnEoFUsqu6k'\MfG!Bw]u$X)ѫ`aDSRhj_ݻ ytt$J+ +d˜Fܯ w`gQ߳I 댂9_O7AS2N^ɒk"JBR$Wr䃶,o x+FMNX*˗[Ye`5YKj_WR+!P +XGdwtcnC; @BNlهAJN@ͥ%Cz\rC 5wMhOv44u, {0h?),wRll_V_EHO:S,;?k]^f& R|%4 geCS7V'o[չ\'`!T|%qvt$G"Zj@7^R'i F:N*|K|E4rۍVD24~ Ss|FjUcJ%FV7Ss1:U{ҝJBHEWkF:ŨܺgΖEq^W*SCMkA2͵Y!|:!=IhvQZ@/7mg.HT1,̸ntA@wixiADh!Tc+z6$Ji0<O5u$% Msjx_NP3x0ϛ`aڑ云SZސ`嬡o~ +i@!$^Teeem-S>d'=KVNI8G4r謾ߖ*Q57m +!ʲ$?k^y(#Ynn&ņd҂tB86d]>LCϪz9;B#; fxj,a<]Eg5M PNMDb-RX TjRF#ݕ;fo 9㋔e1 RIB Pd^r$K!7 bm/tu$CjlESaV% װl,KiZ/&ęv"7r]]_džwjCF NT<4u_v <0aK гl0H8s݁Zz1{u<1x}ngMKx9'TZm>TՋ_{oǗHi_-L^ _~o M]SzyyJjҜ<d[ "ꌯƒVZxNA^s(~x& 3`AQu)TiDQgsXg/IU{YT}A8P(:aXr[ʹcG}\ VLϩ ]?I[5XB4`{6*9.o;2ɌȰ;7.竌$XƤA &3b0% I<ʭMIGS^U$\I]D X'8տ"|+勎M=d$"01,E[)Ѽb N*e[ԟxPIKIO0gwaEy%'ߢAWM4~; +ʚ(CD]uA +H8-TST +sIGAPFWJ/B.ڧ>IӲ29H!pQj)iJ+eqrdP[=k;@!,ۦwɿW OmmeM6>yM~F %MSmN=K/Gpx ף߬`F8Bo.^ĺ%eZwˆ7""H zo ?wA`:A5IY`iDE0 Zg[|[E]I`E=S[!T&\n ermmS6&4fO:8Ӯy,:= ?/#x-ؖZ*Ba{bzaq'C{K^@g{l + UGBPu_eQQ_â(%d{Wg~΁L:VkP9.YY>ȒdX%M%OkV-T5axn/^b2K!9U1o'YZGʅ}lANVEK:Ÿk\ٓ鮜^ *!PE͞3aGz+r]'<,%o2h6dLXtyL} :   mAQ(xee w ;YkA3@w2:h0,<.@,sZx91aH=8x>6v77s7<ʯ:а {@v?TUUk *[zQ^AZm}\{bȴƖ9,-Se[1NjH|@!Ui06^î^#o>ہ!AU&j&fI>ZLċ;SY$dX$}@x +oBO5!x-y":OfzL]=2 P, t^>4P3/wCB+5hinUh:hwd#ɫ5ћ(٦~"=|J4Xِ *_N}j3!Lum97T4a{8"_ P˃`K& Tž4T= W<,iRr.)kMtKeir¡TP@΋toɨ/g5]թXtLA:Žsx@Bg;QeypT>{x5 jzP{1X)mh g<a!n,+%ZsGD2y%GjLkd> M endstream endobj 26 0 obj <>stream +HWK)jmKL&$ h؞4X7WY&ׯǗ|-}r<~v?޾QYG?fs?ˍ_Ӱcֳףyfx|VnQmg'Um;}kGodtw=plkgf2lN8Sv_˼(g0c `ƥ~.\Vki8ds"V'.ā8Ùܱ9V-d4<ƂbfnY)1q3<@-tw}ߪk^`<΂ճdĆ,3Zg fNG9* + V6߄≒  ͈hY*k&/#rlZVS +N7n2RC _8\F,! ?Rç +q5_gsolVЦ=Ɣ p/,r_ko ͆sՂ ygق cـ|Wk̆>c ˣjfjh²½^eI a/cAYa^1"odKvgc>Cidj.5q$Ѳ O 1~ a̸_m@KY[%m-_ hUqOKCL0 ` c2fO dP sRzDHxloƋъ/!bEz\o[trDa>hX읋` eb)f"y"Z2 9ɼgI2\"Tv~4佋Mݿ*C1zԘj;wRRbiBk"2+M="ƭ_&3sjꗱ U6xy*kl\q~bXlf}%Ȕ~N|j/b8]"^+_9c? 2srqژE|arbj9kf+îc&Z>{f&x8KzGln+5C 9îaO &yf̶[}~YsX빕]=> +A[r|o \cL %*f-L.X >2&TېFùMT n`'^P +- u 4\%gp*]R'F F5\VKe`YB cf,"ؿŷz61#㖬v|%$u]|O%0@@^7; +I2;^ë+ `hhׁiɟeIOH6mɥ7_?QF?$Ao8*dԨ[*tIU(j']X|e'RxRRp^qM7 \$)"d#V]إ0s [5TLμr"qul]&PJ.h"m stQk\9FyhzlgXs@L)38s)9p| +۶8R+1v/פs2iIq2{f?n, nS.d̒:][(|`Ua.jH|Xkw r$4$b0 t]N*9 +iKTaqNMMkh" FpԷcTʢqzc?,\.` M3by7\K\(#Fr7oI@pEr* ݿ.O2$h\0E$x&!=ۖ+2P!0$D BRБEj5ayɓVXDEե{S`1*_N?+0ؽŚx5OXZ$RqRx:3ؤw/H_ eWbͶ@C$8$Hj*@"=hh$!eFmyg $oKxL[o`TΫ"-'dq][B(]?w Jt '&陫XZTaP\'-G6Rs92b&e8ew`&"^`߉;u2`&h6JItF"T4 \Dh҃"rj*< kJq̷TA{nؔg .e ,ҥuMnT:Ҩ-LGf3E-<Sz>8(۸cܓ캺8RT?p QyܘCQsKGFPnHKrhcIogpD.rT88\3\Ύ$ 8l!դuK#lSk櫺(ǡ1xmMNs FQ -FW%#HUB'+ճP-5NEqP9%cr-_,Hm((,ۻK)RDy + xrAz88Gҟ%]"ϐ=$T^dEK) 5EqRsbyesZ^>,'^\&[% +Iۣ&X,R ѐ,eN(%p`I2+KU,#!FeD3vS dfV7ÖGrlAɼQ125@p.d9n%ε +m9;uwp,Y誺Yd&p0p!B J{j>Mml>~-P*ǫ Kwc3{cۦ,-Y,vx'Gz&:?X(w jؙ&}`mѐDjZ $mYWMmLnJ5yhP'LMZ`s&xb1 idz{!?ud#,HO;bՒ4"{,p85M;o7GCt < +Uę_ +?7㥁C\׏Å=9COruT7鄃͒}=B  FEShk*G?/HpFzlOo6%LoHTX&0y&W&|~)>1V*P~لI{W+ơxBYp eyQU&3G|];^wlٳ~Zhz.U!8MA^`G" #uKRg tz(Bj%0)s@^uKe)Ez GNL=u^YMoZxXLfNMG{ڤGEJT@oԬos wUJfJ)7@o&Gc?Ɂ)2/y+NKLq'"\Q6zE(γpBB +bNrP{e9w?j垦Љ%WZ#!|SyFlV;!8=-DԬV'{Lv סqPi 97hZ폝刁#c)i_?!@Sg瑙dtij}d7Zv•6$^tʼhfЙC M é?oKgM7]NWc$k L*q( +U=7*ŷݶۋ@SaŝFߒB+ +:S !lZbI=. *ҩ`;pTwTɼn垏Nno%E5ldgy`yPn qx5^B7mXp'ofjƴarFc*=n]lι(_q$+d =e_jlp4:Hִb}%&=_/YGUG*ڼ3Ve8Ȩo4WݲCT*$N<=.֕m s-.+4Gh%1ߊ4__¾@XC}FWғԀHb?;c- +]jdApXVu׷g$⑂jV3άVnae&[VY{)[f_/pY[Q_PEA]XJi,Mb-, Hdtܜ_@GOI3(9rT=dRRg =8(ǒ_ia.8)IDG|hxʶR+:25nTSXϢ*Fe8qiX:f j@55˅u;vʼn&ᄍ +1PFTΒVHQ3}$fbDu>=(.=t>r?&R=mðdAe{us"%_QH=dey\H(Q- yu|u UpJu^]܊HjlկTf݂>`L)(|VO?oN×kࣦRK~yG]vv9Zh:):/[6 *0k>T[atE%6Mz{W`1K% +V)EYݚ1jf-SW,=cKnu\K s&065r/p6 !CpJ]E6 }YoE4B{^cUϦR:ja'M'uL/45}#`<I][ugۉ1m4hN*v O5`wrB-{H k4n(9'tZ`-eP ItŹj~bk[D֪3 K6*X؁fnPX)f:^ӫf6+cBMD#bu>@OB8!هUR*lL1XB,'% E:]635v?LZ{j 2w7mbV;hf?"}U["eQA[)$&>p%X;Mo0k58gZva}b` z{ r_rUEgg]'A0VM?b/|˨tmW(%s] pS8nXCgLqPiٝ1gT>ɴ(jtT쨴rwuY.=pwT0r8{e:ˋjˮ gDIeguAݡz. @יN~7ȏi1}`pZ۬{њ(e7Ncm؊ȬaYYRLD4'Ņ-~ ţW$9%Tp*5 g۰t<5W=1i[ _1 +H&PigXB|~_#{נju @ 2  5T"/83:)M]_T|e'TLkH\a5[CH1&S(A1TcbP ]DŐD1M`ta\"Jݍ E4%o kn{I5܆[h" <=ֳ .U|qjJR n@jiP.tah@=R֍v +XwCG/CZ)$G/O^n_ Mi># F_F,`Ē޵yΘNP2aM}NfDJ7{9DdyJ?I3rz@C@ ,4޽o|'(Oo08@'`.=߬F<:; j%ӻ T='tjYp:I!B%wX +]恣/<*OM7(9_ /J9[O4WruJUd뜬g:2p4ڧ Jvfg}.H<&Dd AY$ FT̚ Dzdĕ\៑, +ޢbR+5Ks0Iќ1~G硌j̠'MP +Ip[8?IN7d>RqeeF©TBUZ7J|Z|^DB U ;>D# {;4V*t9F7Jg0\IkPL7M%$q=,KhԔAq> +JԾF5Z~{d: {|#cuF䒩Oێ헸ޘ얼xkA{?\RE4T\6{ZB9V︗MP=%»?K;n!݉s7}ps(gߦ`shn-mvJ RoIc~*eoier s_B4 M9͠e6jv-{S8n6)K8NM8T}T+'x2]*tgi1n=y:ՇjBnkvܴq'kRcI6MESK0MhrUp1.m+g3[QϭT1!` 7x. )2w\[W~6A+3vGP!Xo6aarEU WxJtSuٿ+W=pKO8:Z՚+ ʢuaM%b@MQ=ķXKSIhmJjٰ̻p0Q +&3| g s3&‰Ĺ2ﲐ{Vh#ItbдC1rgиg +dɌHP4h=_43#[4+b/mmvv댫~>uǶ;ʐc>ǵA Zw[:d>H̒kKZEWO;9)V?`Sfwwwٯ$ɑ#v+{glds9 siH1\E&߼[͛}ro2o.MLX˳wc,TXGd~^ZfX֯ii5IDaA!T86x&{bSG}f3EU%J9ވc6i+h4hGR>tQ /99pK0*7]G5ˍg&Q+{h=\m1NqcRVJWߑ sд?y+I&9?/x}M7޳>Ϣ," H#{P̼PۆhjW߀v} x(MS{ i7i7iw {9*KY +{i2Ee_ݥO2ev󖿲7cIg+-PvLF +i_]:W ?Or՛̞^\me~&_Yg9e-o+l%޺m:9'2GsY[2SAV I{Uc $܈ &M`S/rgTlv@RJ,H +SK}D(˾bH2.B~1WKuVTBA柲:='mg)6'Ƥ1 ZBLY`OO z ]E3͟63vzsdE tgJQ+1}!))dڹ)q@3YBk(*7493zI:›§QP$sediy9Kg1e_a],_z5 SnN(j-^CNָS Ӫ\N%l&hxzVm:h3j+ma SkULUht8B Zc>1_2}M]}ca<2>k3<7z*{ch 3 -4Mm@WvWK@ʹ)䩒} ća k +;{DH>/3_R@#+{%L$)TcP ∁W\ܹƀEJõl౳+NR^}DfDk=E0q)DPUs +1υ6?ԥqcM5>.Уw0&Ɣ^,\e3|c3[A~l^9@_Y(*rypf~"=@,UPrTf0ѮUӆRtRC[H(Hc G%4ӻdu[& L8;p6ܫtFuk oʅŎ+w1ZP/׸v $nH *?HzqFEN-|/xY0t#Pmt{dZS_0|`FT%#缞1@Vl_&)IsboTOgaX7^]r- |O[fX+&F*oe$Ft:Te\Po0Pv5m9ο%'~&cUZ"$i*+>sms͑y5mv)8C"Hz &C҇z}dVv8댆 *BҺΝ%>ՊFuLe=g8ٍ +NSF!C83ޮGym'Π@$uorKlq]@ݩ>,K5=i|J&'[Q=$wdAt7Z3T ;V|tGԜIO:l `27!*-kAgХ u'\˲VZx[kh7iӸ ùNg`fa]]jJg6ϭkagFiC,t/0G^)I&"8º +gBw"+e|5g8foZUÿ`|Ƃz)c1rb*7̒+`! EdY!;2]܊#Z A;ɾ?_Q endstream endobj 25 0 obj <>stream +HWˎ$ W@iDRϫǀOahxvGU=> t%SJ"Чz_>o>߾ݫ~_?nE^LbV}qjqrVf;ˢMsGJU?nËլ}8ۻR}O`sGO2Ù?z~cq8Z Đ4qj=ki g.mCJCŕ=ew# UaiZD?xRyƴQ^#ԆDZ9Ryյc,l%Gz^fzz__'9+`ح_0,u*sKGC{ ;8.y,)$YTvD_[pwח0seM^Ol`eeqkbb1dzm&/U~8Mp7\Sw/qğq,Jq!Nt(!Kk pE@\lv,c۩-"nxmP-4D@9]C L;@,0X{*4 5~XX5wZ\ѷZU"pF *t_ɜ=c"{VdH& U/ m{pt +8񬉋tƕ}U YC$rOfkb|Ck-Z#). 1* )Hƈ56I58v|Gsp$Dr,k[=3kS!/ZmT=[ A]Rg\4 hwV%8npƒ we$Di{+^XD( +ֆ y|U ɰ?45&'v]$.8]6I3a26;UqM*3%)XfHJ\Ʃ UIq @ +&ʬֳJ!nb=-%tQh4q-TAҮUFɖ:홫Sc + =f?6DLbw4EKg/S‡f&J(I0QذmTs샂?Yz;0}1㦻ع2b{-9>֩0ÙB㿼˩K AR,wЙ:-.{#<05P.Nv +a0Xd"ϧ ;8\B"o7(8 ZbreT591:X avIBzbk%LUiܚeqP]6<#֑!>]ঝ=D-t.D }]vGuD`f Ш:e!o3G ;E Slm tqX-tl`7KG˭&x &z(QUY!GQ99. + ;WȩLջ#?wHg/ Tzw]t,D]JMH9-6r$mPqcg7/pi+Y09^b[$Қpyq7jE,dmb!EC|Lw.mHkPnd-DM!n0ܤ3iF`0L]K%I6xĖI(fdioT[q^@k/F4zip*efN99 .&!})kvuqsz\") ;")HpET+6M`+"H+ fQ6_1MYR}&e2"P>͘pfJ<2.,;] !w]W4\$Fm`8HNvPCFgkRٟ@UšjklX툽v\=O +CΠxxWp@L2Ԥ44b< 6dJ 'p[ \K[o`z0xza+' B+)S9%1l?0[3ŽV(҅7+3sݵCb2;fi?0#b/ٞHDEBOc0eȲ#_fQK3H_ٻ`%Љɕ+UM (,) >˚dA-:V\z aVE-u>iAm )od?*4 [H+9EAu@UfQqjB!ɺX=zxjXC?qSXzyQ/F07H 23U֚{M4*ְ$rk^TX?;lbpF^ +xY;fJ"%@ll,ͥ2ks!^!u-=CYe8Q8Vj\%ۼjPa]U?Г5ht;X!5=0()h k.>ăD:jnV+ +T'vj a8 ek*cjx`j/eW=O ,<ֶYT7~fd܁6ψ4K{|Ҩ)aXx :VW/r[eNOM׃U?Q^OKĻ +z/_ToL;*OYn֭_:zv_hk*UvP!N6LvZe'կB #[@kF.>' lXRAΟIthtXX8X̙Y,*ٰI[ϑTA>!:|n={Wp0tʆ%xS&`^<iR§sEz\<}8=6|9U"9F)< Ԓ7-@(1 +[Ӡ:]{J}q +/c\wx!9}9Ԁ"ML`5 i'~;?/}.мxvCK~Ӂ =]"+.>NmH5xބy簪O%M?y >dX@uF^"bZ9nt1lJ|$q_*қk?xse,dtv) j;]]8Ot"sOwqeÌWm!} >hb8f%x.Ɖw%| UNx,}LQ\Q+$Nx~I]MNU UoTxDӶ!p%/H`8LpYcSn8]=-=1 'xjc9.#{],LhڮfØx hJx{?z.7f}9yr'N{lYTm&W4QƧ^ .r}:f }ΚhB +֞m QMK)8%mHQ8K:{=" 4w8OG=}2y,#b ǚ)O }'[ @EPKV֚7: 8pX_[\y9dLX?̰780ח sueF[N*i«h m[p]`efA)&ִraLhdƤ:Nį'1W:Ρ;]k W p'“K$b7qTHH c}&^d1㌫6\hz^bƹܷN G{i}k_.Axtkl]stq7Whs)^OL.hZ ;^ u[UR\`G*W[}ъ֫m>RP +B(~Au=ʅfz{UVVD̪`ӛɓ=y{X1M (n(1`S=`B_r(܇jCkVSh [P'bún5/()uܩOmtUrEv[r ==Ӓu*{ܗV8?NRmKRd=_KX5ue[+X񨣘.N.A&hۈ!L0ggJ2HTGjwyI6dۤ{מٶGѝ2u^?­*u1Pt3? J^)+$43^p|hCgj]' n}][qq+ s?P0kA2mRhh~ĺt,AFX BH']C#]Uِ P|H0?1 AWσUȌP]jVCX՚]@vJu;NLwZO?l/no +OR(fڮ#dr Q~-{0HTS}pr[>)&?|ٵ2NX,ZUz%r[azu10SHԿ-dU u6)#m9¶|D|kMOof7X%&4˙t,+Z,ͫUB2?ԯ'8p`9k6^KC)Z[-a BIdhRU-!= X_N_F#_ϫj(揮$3E ĩ e흳hj[?*\`۪ǖHVO:3t[KMk2&JTUiQC;gۅxrB$Ez?|AHWWfD9V{Ay50DjktM+VW8hzmIՕhn?m= VK8:v>_w;級qf˕@f:N/ QAi|WIGo.፽x#go kz => 5'߱.E<G߼YEN%Q3'1!)+4^c[T F 'a8pk@-SdBMwV-MQ7 kAn=kQVNVC ?" +&bYQ5+}6u>J2L^qi3@./2P9x|fG'`F\" MaXBLڨ'sv4er\<4(x^ R7hhkW6z%D$끴2qQw(L qW;h/-p߿濦a̕hˮ%555{^/Q%ٳu'K?{KA0tFȫ8n.W9ÍBQn7$;Q5OTgʿ7 kܾ) ݍk'6 ]6#{O&,xEČ.Й[M-w7[yA0/wK۫%.,Ȇ]3Yañ%Xw:өiǁry]vHa ->J{FoqlΈuiV8WvƞQae`%Ӟ'T`*Z+}Rtp /: +f!(61֖!É`{ٵ?^b |f׈5 +6Kʁfx5cy3]UR1 +}S(CF}Tg.H+FTTHT>XZ`*`lu+YUjCE vǗZ(ʙ`{*NG$}E : #fax_Qc'3("tVp݂'NWcbRPy$QS=1Sƙz+]_0HV7q86_ qc؈D0*k`tx7wҺ|!g6v[O~c3_tx|Ǎֳ^^zϮz//gj>j?r%Rp{!zGa ĂS hA8 e# 4-ASJ*/l +k +HYA.[EtCTXȋ]z`***:@w.gn4.:W{(Ra2/E~۫6h)ǖK7 : mA@v ~omiɟLIVhу{f7N`j U#.ZZ ӄTPZ"ljZяkYDL>bj6`ѶZlՐa.[htӦRjѳ1Pz+)XkI2}H?mv.ҙW(g>3_)g~lڞxOkS˖ٮ4s̼Hf̥7~-Y0sx>*/fMyNn'mebJ3%b CmN@`ϋvX2*C`yQKhc2;/S NF/}34<_ ]ҐFqQ#y}Q\Ey c3ޥkgxyx/[O:W//=wkiFגWo5Y#%8A!rX8ܾޥ[o=%' tPLc+ǘ8|PS]S=1E1 2Ȏ#ާ :/˜[ۨNWFcG Rתrh=k{Eq+w'hES^L8h[ߡ)ҙV=t‡ƒ/pu&Ӑ 4^c AyCyuXdqb4P9P_P*e߼F; QP6;B.͋FEX0Ȣ &!m8j;.GF͢vh&ƒ!@_WwX>ѼhrZШDuҶh-kTZ\\b9eY2CY'E4F61Ob،S$CsM%l%,)R烙eݒ 2]ARz2s: h A+\uBhc1/Or!7\c%Py}]ȥUV1#FK ^ +&O*StK _jJk*$-$d([j^EzTF鶼xdzC͕ԵG;އB<5)ݹ=NZbt + ue}ôDiB2O;[Gfr8.i4\(R=,E8?\#:xbm\QתiR(!`Gmƍo.vth+K +# AT8)'8钇 nCC$#FWb1='i Zj{' ) 7R/cAZjIq>'MT48hbƉ]WhѧG U g~ą(;,PmnV.x:+*'e&۱-UdF[CJjv.nWa`3 endstream endobj 24 0 obj <>stream +HdWˎ$ W@&zdG'"٣/ެb2d0_/ڮzhJ׾~==~~}|s޾]v]ް ï~z{޽lqݯg{eq=- |~ϱv{3nϹ9ڗ^1ʟ{NS{pf‹q=q}y +<Fs_08oۢ36~ƃ>ƃ찺Çgq4,(_̅)6[AGyzrۆLpDBF;6 @vlO-W, ᲈ2g'͵ʲ +w 7v 3`;Ί0NLK]dwk!+x/\KГ8!{xP/{9'NzQk0Q `>/L`M'mYaGذpi>hfyCx|ˁCZa-J˩}ܑ hN #F4`EtF#aˉH%#¤',"pvkxmf?pUK'X* +~h6U8B7 џt88I3wܧns=?'X$GGٸI`O$Uv `:xV `Z$ |b/@rL{1X@U&z'~pɦiCT~%9!"VJvOcq7V)P:`XpMy=Ddi/"t% 2 Ys|ߘS^נ+DEaCkt7p˲,gSك+K{]%xh:5b`*\8ѠYw +.WbPo~I +UE4da{Q3 +Y&hx@VN(x2J<9 jk{-NԃjX;{ J2$p\+&TzhѪBU 1KTѥ8"qvI6eWT;DS槞!uY1?[VK#ޅAJ V\:`0Ui*e0bΆ5fthq +ku|rs ŗG- +TJ/ ;Qs@P7$ &MRh}jAI碪JD?HLhNHp1lvL7 ZrdϢWCdBNlBlפ>!cؓJ9INN.U4c%YBv+KBrјؙKm@hij3A\Z%ɵfn,M b*~ 3iܤ9D1I=$Tͬ;ޔ&:0TfRFRM{*`ٶՍ9XBseh#Ut&;sphS=}'%JCt>@3{RIqUk!}t%o*!MR)EUPc+MAQb>pF +KU@uRp5ɬҗʼU3i n+Ja䩆GFZϪbf!aJ̣f|'eR&꾔쥌Ut*Q ˩D8Zi !C hIhyƩ8V?ĨQiԄvGMN5,.RQN$5]`]p!^~ATNbkr. +K@b@)S#?_GE\'Ā%VC8*bԈgxwg+")zh%;èq,t!$Z4"5ZITd-Kd%Ղfj{Km\*>[ +HQ?yU.Kd(k(C ȯ)`gwR}v{+?JVԕį_*(*k@ٱ_ג&.jY 8<دf蓓5t Zt dIc8}})+,7b +&MĨC p!J&{Mx@9Z } IqW,QR09i$Gr &I⑰ x +|%H_6VTQJvvY,HmhpCt,YqÞ67;qeLNt0D0d vpY=ZtFw>|x&sug)t9Vt:^{ +W+tx8!q Ż{}>)i$k1|bCQ8+lKm9Ө|mN'G Yk?4#d\[w r%>V\/8PGU RZfj;sg"˙U +_`κxO\J;?Q=R>UceUMAMqQ3ZtVUY0* :eCwZ] V*1ߛ2k$R}oۧ(IoKPui@貢Wc͖~)=v-Vu͉ +zm7֞N7prI:#!CGtFrV + mXۄQ;Y1ZعL"`$mĵ)c %#w }0O +jYfG?iP~iLj_)L٣S,єn*nU7Mb݇Y[^Dľ~PS t4XYf,+B B{´_|ms-_p$+ʬ v4+7KE_yuټ&c>wMfF CSgZUUHioևбm4i*e;C>WH&ڝێ'nCz0Bu%zaNRTFR[P6حII /|J-e{0/ms4gKCv#0 >U55 }ex;Z ,@ꑋZ@p|RfgGJF״;*:/[vIV,Te1 v>{ aX0U2/o]VVE-/-¿o[| C|VZJװo(R6l~^6CjU˓19>b 4Ts &+*Goa<2T37hM.Xg<Ą0">zRP.lqb׹V); x:YS>k鲖bl|^~WґëHNm>UF!幖hǍu`@jlwMٟ83r? _b5g6CLmW:#mwU + )͌^m] +sYj! 6KǟGCR{@Hxw lig1w>fh>,OC{ٚf,rlKxLcpR1!kmZFnj 9{hNsڞm dURУʧn/yi?V!{CFr4渘&4)s(`߰`y.{A))l ?-СVUK-Gb\F!F2A8c]bC.#z]9.?xDE?txV+IFy<ŐByFVww17Oh&<mPK5~YƅzXfWsw ~?*"ϖ/4MJ8X"齈2JM*1rD@Ub;;71lӒ-vm κ (FYgdIYg]\gU,{<:7i{o=arj bDGZvj6nzvԞa+j8!N(>Ic/7oi>o0ߺ;W-GȺx,EccWKn8ud#<ʵ/:#")QyjL(xd~"#\TǘۦQ1k,wj^1B|p&RTFƃg>)OQH=mhP:3Wz +(5_݈61;~ [7P(+tqq' {)Zd"VTZv&%9xԒ=<ȸI1˶OE뾻q-Lʝy5kb_ݭcQhZ~xFȂx?" ڢI7BeѾTւJu`;7ͯQŀ=OP(TSJӔE +fzwQW*r*T[$IMgbtbpO(' DF&.mH$$FgS8S;|&6h舼Rs%J)Y@gc%÷#kG+?%T(|;j 5':[=FЭ2dG&Ex ܬ zHp=ԮINa"@ßOO0X!13XLI0۳ wg갎Rn篖ݶ:ue[(PHKQ#]z-o$lѡ M <'Q3#YjεH :F)Zw)Jz/ِw*jV$IxC& maswc5c/2?84h$|ac9W/(_lzą2NTB䤤4 + ֚ǻ,6PZg*gjRa5fXJIw8Ւ>m6xI+$WqbĪFisMsp-$ +fHE [w㐥%ݑF=}^ +P 3ch|w#'ʐ å47+&Oiv)L-G* ^ܑd3CHC5!RBMר/M^U}iD q"k^/yTvp=V \E.gAzk~)VЇJbh*ĠZyu!eOF#0lnj]*"$e6(T+?>&PWO0nSLOc&F5cF:ADkM>SBTa22@Z}WBu%y!LN.&/A 'dZAusld +\۶hZ_$U8TJv%W +xٷ|MW_j sg91^tXIo"N{%!8퓋݃^IמN>QD2A({>? yG+*1F7I1"baH9;U`u%@-Ue#UBe)wxFM(wQPP'5J'iHjc$2 l}Q|ѹc s #E|UͧR)l D 5P06fA6k|ll'HM'I +UK61׹~I9fgʽ\v[>9XJFti=q4讈̷m k7ygMbTIn +U%8NOv𮔨:=t*Nz0XrcMjHRo;r7LwZd:I%mlvII{ \;< +9o|@U=~!m#Xd~'ڧ#(y uD3}eO*M軞t;[+3#5$h|4m+$"wL7AkZ5Aݵfi:IAN>T8qVԿo@OR~?XyDէ mL4Ņ"d†݆͆͆…O;6…] jBe_̧}~vi9 J,'9e?o=/MӷxOO?7ps-ͣyU + ǨlH6YF@ɍblw{g#&Ύ*qdFXg<4HY,+9fIh;yrm +u?ڵJZg0[ALQK +x(#s## Y)hYaUzaWVL(~!8'.-@7na21 ,ȜPzT\ȱr9؋ 9J3.z[.țoٯKnN)]d5o2k5Ml&?Fz'$5zLR9G~13m8Usv@zJ-xࡦѨukIaS>#c +wdǫ4TZxBtiuVD4wiUEw)*Ȥ24*B4[`tQŋ Α˾ +_?:8׿Z|qރ8͜ J NIk(a#hehfFBw} *[-;'^/YgάsiO6)Q}CA{iXc];LWg"%Oodj0 +(>fƹߛlpdƒI=.nYsФŭ4~3E;[N1kVjP046huI ++;3V-y>X8X !D*Hݲƪ4 `d/`.# ShNͧ7ӯ^x YB[p1l'b:ԟ^͎Gg]:#U e?{_x3bVEQѫRX heb<|g*j/; , `uܽ4ky6z*Kףg 6 4_ۀ~K~5 &1o)+Rj=C%8 ]x + {(d3 +YywmŐt1D?UYlE\Fs$EZV6畊ě F=@(FCT&G|8 IV9vBbRi| =p>ZjtVYZnKϩ3}IYz.wf)sPT5!,7AV[f<i!0U=ȝ]EҢ~ery R_d|RCYHHHTc DbtӒ +hq-Ǯkxt[gv(֠a5byQ..v\9Ur h +Oԉ![<]1Py\M>ꍬ4Q[e5G1q@m*'{w-,:)/LqQhF%#Z@Vl?")Iob oT_gae[7nҍ*D9Ζԃk%}L仑<[y^~ڬl}Gsii4sVV=}(ܤ}?P[ t^#{$oC7z< UFi$H;֦ޖ髾xo%dS,j~w>Y<9:t߽_JY\P`Sr;#T'^J* qVɬ0>Lkb\srwZy{-jY6pBP!A^}s?r:β'!H!n4[i]Np>Պʔ{x6{y9ΓFC~M83>^uCM4%+N¦ +r:սlC tpɈv`Z?[N]]2:UMҼ +Õ] +]g 0>gy n'#>stream +HdW$ W9J$EI׬ !0s {߻y~oVjJ"U/z}v0G5mƵk_79z=}ʀ!>r<5"^h5~mîg{ߖX9mg3~ڙ:ؖކLӆ^cٱ a&wF,=7\ۛc-[q {۶>\jm`x0q2lOBJZ_҈l^y{pn@ln9ֵxNl!-x9 +U !P@\ʑ(/_]wm;õ1Dy# IqS\;Q[faI쁄.CQSyNQ;i_8c dz*XksAb>ީ 8 Aaxe>,:Ni)PQ [B\QEƙHvEVZ*t2buIt:H"ғ9ΐ]{tT0i61#Vbz%vgL&YHĶ@a^ gx"Qi'C-!oUs)uBJ)-=zoܕ6hel6\̦@7Ɵ[/~氉XaO`ϑ󤚴5Ah| f/JR[Ͱi|. @6!f;c|Ap KOIt9Q850[Z3ge/mi{+Y5a%kQW07lq t MUƒ$8fs ++‘'J[#cgCi˰L*J-UFd n5A..BCf̶-F 7Gd7}MZwf&b~ bX +$ ѓ2(NS#Ml3e-H 4Mc  tArE3W笮1/.K,v1bƁRvdD;s(h'@pwV.v !3,#[l. @\'aWË(v bQ<3]dKz.͵2GFBGpjnNZ8xbI0ACM ?(f"c^mZF'ռYraqт` `z5`㢸oBd-S:u$lJ8Qi Ihj<|c)R4RRO1llϓ̣^ߠՌV2jZ.Dy,)vJ,dֲ4qmWD,i +Ln/'BPˎq]$褄*A6`aneYCB H:Eo3x(ZQG O"nF+wA'=%F$c-Ix.Ѣ/nխ΋Kw I~> 3lc0'˕-qUPz%9 otP2KЮVLvi.b8mE6uF@de9Pdva h[՜~Rq0%xPK8SFs  +Je9H;| #>OgMוقR .,}\H!kw: +9!>yޥG +}MzF]PZ'Zo-aXlteu+Ǩ B 3%w^2o ;5QʁWX3Yh:TQ߃ &Z0f&E"ԱН=] Ҷn8Sf b!)J u5fPB!x%aE+BG+& uo! +B ݸ {pk)ЊI/sѤjB/wiF8|7ht< \*- Wut:g~کӼHSQꕰ<'f+JQYÏ?w&F*PVv9h3i/yڒ8*lk0dUn+qZ0N&*dŝq6Z 9.n)p  ȳ >pf좍dJSuc18 @sY(oJ^D4'M*o25r^#(gxv.K.BeÖe" dAgL]4#6&wJ0CMC?Z*zL rɚ"` !LGq"!=[^ʻfRI] -Z/eu)%s*˺E + ?T`S^꩜ߪgY RV;3 na[;xЅEܽP~^0`}.Oj?U=PcC$b;%7 sB1x{jwq"2z"+YL2n|AY0o%D뼁+lQAtaew۾uԩ>qW tY+RAfnE CMI,< E䊉kڏ~}nr12B3$J=KZh',*ܐ /eaTIXIz Gk\i%v +1#&9W˴dMXP +%rPkhMMR/\K"`c.8KJ2EǪpQ+!*~CIbF{GWv֠nuE\iB7\HU/) OӱT-֤,MX"X.fqRBӝ!}iU_0WXc@nj[#jCRGHDQ{w-.by# ``OsRn-4KjׁI :-P58FH$&b(׈;AcsC~XFw1}T)Pȧ!i ȩ;T灲W- +e\e</`?նbB>ukفba΁Ձ+S|E ,i }qKpiVKːrƃ>FIp,r+Ђ(TFՎ%6ҚCaFc-|5uhO +'+ǧaѢ3ľz[J%0yaI+gޯƮ;qP2jl("%ٷ-(CəV݀n]cCvYcow7&V^o /ِK5hZ I{@=G5q0AF/g_/M&XKvͦ3w6վ]!u ŗ?m"69ZuOo,Jr\aBk NQ7zǮk$Syeq}0쮒=ܙtXi~ז;kZ@:6Eվ")@$TJ?EyشEzW3i1Er7$JIa_'[vB}24 os!bmy5>7Naۺx P.LEpymS%-׆uj72lϫ[u5,f¾$ZV=O.jY)zqwqW(B:~R8ex)E +fWZG-wה.q*ɂ3z +V3n[h|iơʆ5)6bxeީņX@c +0ȻQʫ2z N}]jP\D^-sZm00+/CBUZh-ܶZ! EubW5f1x^votV0s%;m3n;,nL:%nyrxkj>؋B5idzF 8u5u)ysf馇8u!_^͸ӌhX}eP/kZ*8yF +q`ZRڰVRO~"j*}&BՈ{0bdwK S`=&-7vmUs\ :xͷ8r]$< V¥bʸF]H=fn ȹC://:5u:90 "TوP k^0٫Uv00AKL:Iju[~!4Bi`!&dvO؅;kܵ)3]3tv[iqygǜ˽[ԗF[?J'gKm]mc 8<ꦁTnuyHmwݺg PTJZjuLP8^B4,Q5SuKAɒ"+rV(MYRk RxI {W^ܞ`TiF* H#: ibίOU{ށgUZcejHoewO @5Tg<hHWG;I2`t.I+6fۮ ?PoW,[%$1~ Bp?}@}UfMs(F`%}?:zosBR6 ˅=y,n۱->ceuqbِcqT8GX.y<1$wx]WʭI#$D#Am3(q'3*\fA Gʙj6^cMu,.n DHT禟>>1aA+GzLH^$שoɼ*/e]5owp}égdmNor/pW< /YsBU#Fء}AJfT7Sj,1 |x,\#H($w{G +j @ + )m?h`? n[Pr6lZ'l[ uP 2ޞ{Űsslڏz3 y!o7lG؂Z>,OCAh[G h3`bkYl;O, +d#^=q^  K$-6T۶c=tM)ȱ= ~jM.6T 4#|;)/>܌{ 2x4 g]쯶y>$H&YSX Oh'X43W|QO5Dy2VY6SC%F,YY=lبSMHpL;]hWFz}5ZcJq_QHH\#1ԗa`dzL%*A/S 1~(>%dlLid(?L^EN%B%Q 6ȩ`uwFĿ(=dL:D8κM`827:K8GMw^0ǟg [`X t>S``1j!hH%,ɩ1u豴|sPҦt~m 5hqkktrHvMQ {ObF8Bs ׺DK1 ̭vU!jĄ&s@|_Ta6=.j= b3%5q-tHGpp{M{3!r6oN:3a7oլl $ ÊhqD@[㛉oBVޗ(5p3xFҶlQ2d'WJpd;9+\c3Ԭ 5fr"9>OK Ņ +LMA| 꾅`Ch FBpLoءl. /^8WGvO]FL75~ϭflbNރ +mkTH.gc2G-#{xIxGy#H(X`M #!J׌ȡ СY@w@E_U4ۺ= مa&R[Rl#ޏ]`f"G| BrNBCfeO}2 #ehl<ڥآ;5̼锴qsG$f&S=]Rx&D[> +~5`j+Fi&3.3p9a)%Ŭ yTCkCh"9XB1XP+-WѐL 5ZK´wϖkqk) m00\IϯqσeЗsxRy8ys$8X`ǭ⓼;i@x ؠ<cp5|p%gQ{H;X<_p@s>Ls^km.XIPUzowD + a$P8Gh<]ovkF^,5|R'traG2#9PT~*a+;/-3+$ɸYֿ9 Y:c$dnهxЭhP2]˿* +$l{@|fu97M!BCuYus ?iA4ldgo*=*{ަڢnZ-stMR5`u^D־W_y`35gՐ.[@hD;[D[*ִD-?ȳ+MǹkjB|\ML}J Y $vA-+oK|=c݊O*Nx*i5kٚ5w1 6M&p>:JPټ]Bt3/}(nʲjf.^3+t +g]:C-:@߾:UN0X[+=02 Lo-9D,"~GX\τڶTꮖ5 D҂ N])ҺvzPMA.(:L55%8~+~k*x? dXIV ^b:`IeOrƞ-:Ŗ9~=7~dsHO"P*?9 # m'yOz\d5 LQCzPb`!=}V +e^[=3t'#NkZK{6u˥-2>n_owN!{~kl,-fφj6e49m )D9@%~A52;%%<9ŊStc흀{-E( T-xAs ǁE=인W̞R2|քj>3fjZ.d9ЯP!碘*伾zK/2>+,]Vz>E*!Rct*JxXM253h>Mwƅ0L7`"Ɣ3}*lQ8?xH #Ce qZH#KɚȲYLd*H}E*GoXa"C 4|p{f$pw9O4ܤȜ~!wjٙ QhDR3?MN݈IÎ`s~Ct{hʼJӀaBR$_nfF?p.x7E7G]S "6U)[ nHsnN6Ӣa +|'҇q~ Đm.ڛ}G}-6r76!yOj۟yIExmJUsktBR.E :#ݟA/2oqȷA;ݨtW"~?tZ=DC9S9rpXDd(y+_k4]Z{<͓dڊ&CY[НlFQÉszu5z b-~u@xSd1*-m02d HBR9ZUTM4ٶ +CsSDp`8(R2;f-vuwl`4= iϤxg5v,`N/\ >}_7a%ֳ֟BwvC}K} cNXOێG7Wb]Xl /sh\b"xz$Zm%qB kl(ӵ*6YKb=CFY|6&G*vc 4-\XkFu>]A^ +^ӈC Zw$ܻ*_@x1Y8Ģ5MDI% +WUk?6HR0=U$+JNՁԱkXQoo*j +r9玬nX@'Z֎I~|CFe]յV6σ7 A8PP N5DrU#щQnTm_8:a^gr%cF)I 7ǪJm+39js? +J}4 +<'\.9A59.e Sflf-yh?ΩSqf!"aWJĚF,vqPձE# PFjåir"xu1&D !&ueLҧ0 +MULZoq_w[[ W4MK\W/ }71!¯Fǫ .pUvƅ&# +c0Y=HW lb(jȘYQMc~Jnj& Q4I|9zƁ >"@1O-uwLȞRPp_cwn[S4\+3rG>kϮQ pL@dX#M E5j8XGIS1އDχoA? "OQ?!b# ] 0qbƓCv7d-Am0#!~D?ӗlJma +0 +0-r8+m)~SPߴ}Y_DM<טTD0T7o\D[E"c#&c"_a;hEry5$˪rEЩ.oԸ c]8J?1Er;(Jzhnݏ8ĩh`.f4ZiA^rs:O]!!j:Cz>"Ԗw3"dR1-Os ="CrzΤ^heE {c^w9fKT 5:Q놖B/XPj5?14uZ)(*=FqH6o-"ɣU4l&0ğaUMЩADRUkShro_G'Q`+;(FfIIȵl?ty'W^q?ABC*(=U%g-mPWld(EYD @ +D~9!O11Ư_zl G3&GB<&+f cDTHH`'@$7(lجj2ȷZGcCK%U80F.v o\j0i!Dx ۊ`r_ڱNG^SѰRLvI}-5D*"J2ܺS )_c㑠RDsĒ@eBUWn0Z?_b@T vr;r͎HҔUEaCW~#HFDI9ˆ{o7ǽ su+?OTJ5Fq۬O8!{Qd(_7GG-( 3ݝmɿC>M ҕ">UG"=YȜwnI % +ɊP. /@&DWb(JO/%/af^BQ(< 6OgzBCoT((̿ *"$=Ѡ`0YP(("@h(O'S$  }¾C}o }0/ }b!O;{=XO0'yD<O|'g +vB;P~؉g:P Ht~ʑ#(C +}B:1@/7sPVV=zӘ;T0H9@bN_:RN{<$rRr#rRrI GI LJZz#R=$䮙V]Ѭ6RISA}?N\X\ 4L`DS2Ma{)LJܔAS3 ++G7fiGQmNMܩ~y.K5̛[ZPd +l'`;9 _?V;ǮdC9-b2+IzL^U&pOs`-Wx͡0{?1Ybm։jdTT,.*Bj2!VC)hMZdWC-:i7g. M,);"3Q3o窮$~MGޣ_֮*k9:*v\J<)}ʲaN7Sj~Wݷw&lQ3wi| ›Ƒm)5c?Vl"=urh֊dtB4xCLl; A'@Y ԝjlɑ4sn;`6%Zy8sѻ*Ƭq0wLP%n \#nYtE?`7 guldǐ2Ȣa#fa#%(5 +k|%ti87!ĆU)x٥E ͘t^:Ceqk]E Re3l1M6=Ӆp!'jMVfZXlNci8ܹ-:wяmQWsGzpBtybBbJpb] `"%2 ѩ1ji.V+gDGO;s )R8kȺJnqJ2 ieC]np +Ѿ\((Y׍Isa+|\ʆ ,u$xf;^?۰vepM}di'6]$fz҈T553"40ckt2+iIխ.9O,!;x:y[\wAFG5'%\l ?^h@q~?'I6=cpJH~q ;V:!װM'tz>#@q8DžfP$~o\c4lcͅJ#-<?(>J%TS {vϰZo31 ܷI`J4!aV1:rv&qzjjǃ $H; +3mN6C RfGD&8m_Í/gAݘݣvB][nQPȬ/uF{=G/]#g= 0PX#4M QXQ}}b(^(S@9Rˆx%!Ԙx>'K3aQ!-ZukWdqkK +Sڱf<ҞʹCmOP/)cGsl5xj|: Y)~ctYkFmj=>6QbI}iٍ*RA +KMd)x4>Wu_>o^b.~S>Ҟ,HpCeeUo\4MDdd65?*"({B'%+CD DI C-`2;"+% ًPimb"̥ s {K cvޕs9)ySjTGoZ_W_?/ʪ{մ[Ռת_VTUU^6˺[7i;O {"?Z8nW,8*IFwBh=}m:[Djd6#H83+@xxxƻNԦ:*jG^:Nx u_v@8 :MhY?tY0ȽDdtmwTXˊBLGM~nZ*MHȑM:A4ԁ ]3TP68&H)>w&"WE.DDn<ܓ=I|uv,q&q.qYƳ3zz]vFle9)ĴH3~Uvn!"K[Ơŕ97(:yM +?9U*C\Z\o!#(H^_3A$BxU [qPμ>qD W}unksO]bmVM^y[ޓV?o09!:6Ë彍BAWxYڈh6T{,keQc!>cF|$Ѓ7VgV濅gY9rgeyfe2XXyAK\#g]aH!]bp)z1KS)&dΑV;Net>Yf[m"vGUvUn|gV_:APw= +n%8a2jf^^V3N΢6fe0M^kMgdWcRA4x"C'{4Voc\싌cm eȩq^hVyɄͼc_.1$t/>&Wgfp|"cH*0$HJja7z|\dpʡ)3TTbt~' Պݭx! -g K9,mJ:2ckE 8Tj<@vD%*R]߾DQjpc[NlxjCA4uPST]( ~EFw7tPztecl:өZs|!{=qՇ +g_?#HT?cZ bdRnL;_/aY9*k}TLN6ı;Re|ָ$WdKؖBd+-]\Pˊ"LGP6y^6b%r 2r^Ur˗˒.LP }(Vxﰾ: Hַ[6P9`.vu,6$抜U &Z]"4YA}T~)oZX*+p)30-+[P%sc~EnY0[HҎ(O?p^sȱ6[l'wtS[)73W,2A;89#)UUV v0"vknW +2RɎs}<vZi\ +:m9[{|^}ʃ?Zsꃱ_-]H߾PVځA\Qc +L4l/X+/q? \1FޏN OA~Jٕ'Oj uOgs%SJ`>lt7i{S賟!/ +N7g1uf'(N7 ymvL sϗAUyVӗŢ Yj|M6/Oд#>n*kQi3klc +U,VoЄ$׾.ؘZ>mI6, At./T%tZ#bhRw}0bHv noCΜ".Z`jw-!UxESj &09: ?%uO`QTUY1dA5>ζS[MbOyPq\ه[.鯈b/:L4I->aM%hQfM8e^[%ա23slu8Ks]eF/`2=J?*џ盕 +RrwaoU/_ Tm *Äx'/ȋ_B' Ae^J**߽:Y.$xXҾ$ ƴ䤘HApx(ti[vf%ꕴ8W Y=^bRu_YX?`*%Aɚ6څ,O_og.?_3Т5Ď '.pD1{ˆkxV1q@C\*|W3:2#S\Aʷ:dfc%w4湞FiLh59$=+(]Q)r9T]۔t3IK.wƒȵ]f*m>e@iQRdrcoy+l%n9d&RmuAq;ԇEц3GBO)0yoѫohxC;ӆsQkUXh<,l5 ;>Kv%;kWU9ec= qo,>w{ɇq&˒I%5Fcڱ~9+/k/tU٥ q2&O[63W>$d5e<"Zxor[i?C%9}#ǫ]*{,%X҇06$pXq 6}a蠵唈CN"/:ԑwp.mQ=Pǜ;rET>U?5ґ^!0 |nYP-<>xD 4!Nm`l[?U}q=| [4{)W0o !޶ltxL˰8D܉vhà$Mg*QB3 +Ƕ-U07#SEUyuH + +aNA\c~G v; T,'}>> glP8(rEo7NF}v,*b1;BYg$ 8:ό2μV>s j §+\a/&k%#Xj?_01IGU)' e:袌LN^Q Qk^#o|߿ ~n# endstream endobj 21 0 obj <>stream +HdWˎ$IWr"yeV ̉_{D4;jK23ח?-z=~}kz}zǗ+UW 8sޯβ+{Y5;z\volwq=k[sQ̻Ϲ9:^cz}ijϊK|ŸGW{}E޽7|qg4=)6;xmT-nsc1BOOdA_x{6e랰zؔ׺{ta[I D5i):?@lːp"6@rDc{ӲqB"Z}\v\[1YK+# A~ 2H-Vƒe<쎀.C.VqaxRň=LVz{) M=H޻j,e8k9xYPq!4::[^_`w2/X#kXm\Y EYւ++H;Ѧb)mh_*Ew (\ Er:j^N(g+Jɬ+m̔XFG%úg=YFqG/ݗ$r8}XkToDFTX,UKKGg;qwV=Q5~Ps%!-oV<"nן{atHo{p@Lژ'Ԅ5尫+:څ&]3*oLR6`yu6,@+v4F$/I]1X]ɪR!2<LAQhD#֬.dԆn,{h*BPiJ[;Rq*9SЍ.ϭj-409pe a|ӓņca.QZxx=:mDe\GDZMf]jˍM | LEQ _?ꄽ$?lu*%@8|[:jDN49F,&VՎaTz7V*2E;x{iN 5Ke 9li0r:嶓mih6:ԏ0h=U +g,[I?^l#JQ@Y ebGW˘_M[?XVa-WnK@g;WR3\pX&E/TZKPXb$3YDfnmITĺox ܇5 ~g*/&r)HBh  \&$U 0xDs%+2+L?/P 1N #:CIְD<Ҵ3LaQix:(5:tc^nj]Q,C1͡A x:v;1#JQ +,jԏ143(WQHgB h թp9&|!GGTVL伮$5^la;uT +yqVK! uፔMsX:>EUTfW[]CƧ5 m@QmKb=M$Ux%ުi:H(}DhSz K[RrXx.~*ٷ;_"O@}{ڔǦ%If-/7|BDg$[4t("YXO39'ሑR| 06[6VJՅP/@d#]4 =IIL +:jrIւW Q djɞt(țe01i%~b +A퐜-ӯO!26ڴ 4Q7Iw};8,;~ՊZuxqC.pvN%Ǧ +48FٯƗilWQ + +&2PVk%rMS[a"X5$%k =c/ T.*x]Hw1~QWd f$RMpㅺ%-@ 1hv{SZӺ1ҽQd5CG;t"_@n:;rU9]ArtuֈhTCeǫjwWa|R=uزgqi*v侮o9f)g_0@}T!8q~%v&u`b#ܐ=jPM)qox(j抐/h4vTxEd2?;mXNӑB%Cdmr%1T( + sՍR;|[DmMd%PA^_7a%>J +KrB1h3 fR}]TkfvOBJaН'Ǎ% fbƇ8㖩a ihvBrB +5f[VH4βا67v,3o϶uܪr)ðvXm̴bC +,ml3ib Ե);7lTM]Dejֆ 8陉=]qXU=A  ]팎՝_ܰ/7i*ʑ+-IsMIfю&Q0#Nf#Qj`Hׯjۏ ЀPYӌ3 +LH JN!("d#z"6fpuSJBA 5 1bWXx_n\pXC.ΕJvTGK s'6cF[q2wHn*B_ Wo{Om3bz}uSAӚ|rӾ!-㹕۟oNjU[Rb, @BrMǓJWn]v4iLkG~J%=3(S,+A Ydq{DM\cRo3ԠzlJЊ-U('.nn`kAYu^r 1 Zk6Q$571v_zlf$22{=l8 ׃7 +R*. ޟDހ3Af#w-z@ [A a< _1q07Lc`> y2[E|lڀvYJ^1z@̾` `:YZ t!DC{ T90_(_vwՃ3?A+])+hMpF~DxC2lGA~x];g|V=}__j~ىj +bH޺t)LvJ<+y՗4z=#5y5j< +<˶m*A ڢnPlrl(6g~+fۧpO~!X"h ҢlYgjZZ.MƩW-yFL\l] ȼ[ϧry+9Lg=rg^W,Ov0Fhui;k|( ]ug,_8Q5Rp%uy+7X7ۅSq) +‡BWG+hn |e 4J΅Ķ%r}'$J<"{3_ #@֓%~%R++Z(2kn!+b<}m@? +IȂxlPw]DHyKP'6tKe#1*A;3oB yv;Mhw<"JwӴ¨ek ۶j,-wz`fZBx+M_x#oql A# ^rg2nmSՠ] 橶fKq@Z8LF5rQ6fty]KJIy-KRIǏjW1fJK㬥Mh@/Sa{C3Mj"y! EPyK^=9!4k!ˣidk /)a vS(Œܴ\۔-i133cmyv-lO2E<vB}4,'OHblTgLǑD;VhRaXqRFX zj$E3Q†;"JH^YYMȯJ* /f/:;buf,LNZhЯ~q &hЗRbRAJ!*>QSM>: y"‘[MS.[aw a6dw滣PHpIsQSD_[]e;!cDPst.It4O|>CkPUxVJ9ʉ2o)H*%jYcL1ym{?mJ8 9э& UΦF^ח$8_e5 ?K_-1?} Pȝ2*KJ,@e ?W(yun"R^#< g$\hQN2Y_z.T40^.9VBTVb8(2{y7''XȬ8i%B3um1q*1}= wmNU{F {F&toqM2!bv-2X(Qz3 ? !jߒ0E>3ϣ6y);Ӳ:&)bw?4d*ȗJǛ!w,>TZk.} q>F3f^"HT@$qFP'#a]9bQRS!/fh +4Ote D?#A'+1\Ht3 +sDQN 7zP^hmTZTg;ϻB$pBR90I (_$wwk-% dӲQ<q6ܡ;5}~{=`F׌&>C[Bb@?7h!1:Rv{9mHtY={<Ԫ iөwK娙Nt;Ksxv8:ʘŧ.Q(I:Fk%O\/_Yy};/gʮw6w +\9T볠׫y/׫m2Oa<LN%%O6Bg*WYSہ. 47m)X͡ d1$ O+P%(FxqfQ".-;n a\伋`e +;Gʟ2Omல€woWuvtY$$JIc #'dyx(a d@ +3Hʿt6;H`Fۆʔ'*#woOEs*Z8>e\jp;9]V)/)GxVshX OV_Ԟfdu̕wN{NlvrH#C&7;\بLtؓb䭓N!}",Ʃd` +5N =F:1K:Mt: u5OQP?حX^˯Ƶ +Rx?5&;rjPӹ:[IAE +$@K"\(WY 8H]7Pܑz<% pɩ֤"doE:@S/ ]x( +OkEE xtKHRo\?b Nɓb,$/m7:4z VJ 9t !ƯH8>Ci(Vw2 +ߋ*.];EjhyxC_muFOD/dYgH)iaB2JKlthSZ# +-AWm'k')R]|ԆY*"څv*L05x놅95)I%GvȔ'P$zB>̲'UfuS\梅F3k ۘ<:OW`~ ))GqQB=_:)C18Efj]4Hz.Sv=GJA-)n' +Dױt>+ѣZbԩlr[/eQ{ 'K(>F$N()z,W1 ܵD) 6w|{ZTjAUN =WW=)"Yh35WgrNOť |JZl닚UZY&: =5;Iϸ:Y {e]-絅ʓbhuf:DU`\TI!hHCHotVfk9֢.n.Q-}7A`U(ɵ.dcTKnq} 3BS71w.nL\q +" CGlR{Iض@:H{DDPVb|sy~lEײBĒ; 8?5dM;T .|4HhFy2a72ժjY`aoy;Rb@?i& 1_֗bA +A/Iu0A;/a7/> ?}S~XCMpBDžb0A A+A؇QQ?!y'A_"u#!A̯g )_ D:c):> kG!Z?$*GJma=iؖ4gUM6y&Ǿ̊dFB=qQ@EQ6CH.ky> +q& +S3 XmjRYq`V[1 `V N90g]gGϨo`Sۑ r"`^dx|}`kc"dMcܩE<H_*өUdwj7DaMRKSc!/9q*M?ry6p]R?VIbSQcP]7=moRq'f!vb(['RM2VRHEzdʨK,$5E}P82A(TgV& *a_1kzd:`û* +[6ex,Cd"ldVγGdD#ăF.Fs4pttX`KTiҨx[\TߟaX]ήt]j3]<Y(qYU=aDJŕK89Ѷıp;e?9|leSÈr^þ1v4A'"{TA-dOp&FrPl_4h)$Khtn(JjgLAIzO`ĩ\/VV&v/B +dAv$u4lo."L4hHqA&r{b){wZ ScUuXx0As +O2W\\Z:?W"^ w~^g +k^^Ok6x/^u^֯kn_y +uk^^?_CBb:jNʑh ?c3|ϻHm̕kΐ4 +BA0(h`os,R57 i@Ĭ?ssxqT'VRcj!2FK/̕8Q$røDbVn`UhxC kX8>*YpQD= 77"bѸe.Wd_ x)Q@'JylahsE'(><~'e;?{>$V`G"%BS=X]/Rc4!Mݤt.g<5)2r + +:887e86E,x$Tgx2\?b3LQm x +qa%DFHXqHH7㰢 γ%rBP!VtaP`ĉpD}QGBÇ'Bv=aKD~|PT((NX{d)Թ\ƃ&ң'=Xc/UdaX$em9Ry&#;f[ƙQE&guB%L6+^VPeJ[<,y{I{ AX]Gb%*= -P zm45Sٳu-l=Y&Jݘ<' bSU9g`d{_c9Q]2,{YLokLUi9#K0Rc)& +`="6?HK|E-u%dE67-nvЙ54fzLrUE*xUZ#")`>ߚI%dI.%JJ'{/<ÑՀ!0l |Oy*TAQvm;)d/#.s*!? G'pg5zvnD88>]!0 +cKVP]%dY +xNe{ĉaBI\P7مʙ0OL1:qv),d!wB1z9!j Ǧ Lvd0RKۘ>:N"NfߓmM \KqmOu0T^x,8[N]x KQϨۄ!잭؅ +^yæ- +7U$(E֨BOڭN=ofD,d)R;#&/5Dޥ4GqbM(H9`{Q;FSബ?,(9uiK ]}1"SmIivIMOP3 +8lS.4@bTutaL4ghV BURl"T |=۰&w؊8ژߛ7=Y:۩&-Bmp)uwvC03IUdގM G ?T  {)QQh,5TflH3C|ܽYHs>ojʭ4TcD`[]6 mVO?B.>C?Y&O OZ`DT~Gh6bZA+v%x)(͋PH&xc2Ͳ,QdBVm\&5yDðWp+'J!+M~͔rKrԵ-a(F"{P2$J.9#)/ \&hJ|cƥ HSHPZ˽P#hy_Cr~\8i< K }H62,z5;: Ng ?4/+ĥM YE*n%;TH7~nO_ H8yE%dk/I|=b+YM&'k]2t@ !ap9%&`֔xG}aZuqRڕj<ގkGݞBY&o # pzTF֯h>y"| ;XI<[CWmA%5Y- (HMpg3$Ff,TѮ} +goG։?g>S +;Bg4[y50?1]:&ɔ**GSb I7ZS/)-Bl=R3;!#GƂ8Xĝ%*oSqOf$\kCoٲ6ѕN](l@[oT'tH[q_A4Uj)ڞakŒ7QT~]ZUIY |εg'Qȏ*QoH/g hh4Ab#e،_S;6ܱY_dž}3{Z,%KKxM9"BVOfUעv:X0ϡIKä)SǪ4I(w6WkrOӆB/BH'mV$LI%$B4AN?vmpxyQ/5>8{./w,S]˂ Y1ɚR41l³9]Z$vB2ח*7oأỜ6Tؿ!Kc5_ZGFU<:/#w?CV*rxi;J-TJYoeBZU +A:&fЋ0/¯ +Վk^,ůL 4ѶlRR|oܪg]-Zew ExO?5%am=(ѱlj=E|zĕ4򊒤eTTSNq:"Wp +HD]c伕㋍C=hZRWO+b7)GIo(Y Vݾ(iMQ) +l_>.Y$R_@\^FO׬4`{ʆxNEgGG[uKI[g~:S:S7].4!0'а!UFב"G魯r yavMGXN9vRk|r\Ji})5d@e_wQR_Sye@LxR۬ՑQ_ȕF)V)|\~#"8$DPYYYn2chFTԑ V+@Q;SV}euJ^gy @>;,Qy(G2Gie_ 832C2 gWM,9Y>e4[pnO|h9Qg*3ӕ:Tg* ˝]LnecLn_5c`[`2Jj AIϲ.\C1fmnPpe:JS^yX{+5MMmEX=zTLfoS2q566g[t9){i. .vGtXo:4ED(J`jR+x +gijvGDžR7O +Ljv`Bn]@95yw(D;NɜT~lN?8';'M +U">$T"HbAyn@5Kg(u/EקgTRaBWՓ4 Ig&Uh=mb7uMt!`LPƴImw?4r`ϕ˱Ub;IRpK`4|.zAXvl(qd'L泙,g3Yfdn3?639?4d&Lfr^xd; I=K5?cR%=Ð*"H8,PIxk*y"RI%5^u$YU_9o =8v0QY{kS q xzd7mhdvS"&qI /+7PչA&kI.(4"N[V7zVt\kyIN" njAW #,bwp_c_,>znu#^Oa=q7[Q:;ٙқMO\ʶD3ѨF:rEճMƝ1HfZ/ak _2G;Ў]@I Yqק:;t aMF~Òc YDA>ˊ&p0ڵsuh(gO*D/Mi =vyʹD![?iȯ9B ͜^kh|M9IR?(j Q4Ӯ˨Iv'sM +T1nfW$!cҪUBvd\әWOnSj`PGpJ_x > endstream endobj 16 0 obj <>stream +HdWˮ W:ER/nYAE>`d_ƫ99asԭbXׯח|mzhvF<Ǘoe1ǯxϮ_-z}{Lj=ۇ_~'s\Ow~oǽ-gfiiQSJ}mGМ +W\+! +q˜vNL ;>vûp|C<ҝmیjk{^ǃ;$f4}/lz0TL +(Bt;/01>趩w cRy +d0[]öI<+l"rm@ن!SX$.iFpU0an]7XsndCl̓4>*f|pGȤVf;6[zX$'7 ;KGx"X~ ab%"}OJ&C~XaH"YVUZJ(4@LϚq0VWZ 4_z_b#vaqg,,1c )gwqwOɎ?jIlP`!,wLڊ?+EF#D`&9c->Yo 9& J9uBpwSwzK[^ϕz}ְeL]}!N}h @u:~ j Vrh %)_ F>$h;+/]1c bB{ @< $P"kK/@HM`( c쥐66 dh2Aac}08fPĜCc 9)os*IJD +FG`|MO6K1RB^FF +"*hal. 67GRA(@ΪxAf"@w# zVՙXiu| +=Fd1bbd$ơIw**Rbtq.s!:+3EPU%c(!1`V-:QDt8#R%ӨZpi& Yu`yp{Df@ȹ[+Nn13"{w6&G6Ol@ sҮƁ?d +gkՐ ~aG:xF09k8Po~%/Z4"7E B5; #'z) +\SP\9IE 2yhuF#W UlY\ S䁖ƫDۚx %3x#{Y92#Skdx%}Ev{hKHˏTXL'UwOn]4*,T/逍D(x[ROh e#u8 ,Y阍nKm|Q-.v(]CdknؙyxB>Zs}p4-v:\|wYC;f;@NJ]eǵȺ0B\82S$/Z6Z7B-Ye +CQtb@3%b4%v9^%Xx }A<-UH +M~^gS:]HQ EH1ևĠhQer`Ȳ$E<䕭pUΫ6ܧi8%2g)#eiVjT5ܺwNB9P8s^toϞw⑶,h Ԉ>_ 6&+PX=\&LSp,9]E(DAXݯ'L9aC>~%%ڱƪg|@qY*+K\ҏʺ@ZBVQjR|XNwV:ĀmwdgݹUl !ݯw24C1U'Րc17^ bRfdMF V6(6v콫upy2'p@)>?yV?JiKnkOAB&Gyrajjdž,Ii92kQ= .ee-%4,,gP~N#\Gٹ- !`lzKYk਌!X- +MWl[.BeɶqJ1gqg,]4׭ONb`d|0m78T +eĥɒf!Lr>ԪdG};WWnf!FJMOi{頼.#w!nY@ LnTologY Ȝ 9F-%#T@oU)S'zgN>z"<+R %8œ.q,νkr==^lj^*P~LQy7>u&a*bL:HyN, +{_Qd}Mwd^QsZiǑUuh26[Ի:EH-= X\!# +!}P3ͤPso? ie*I m&ԋ_eWwé?ˎDzWqB:i8ITHZKkE[uj܌ svS*l1@ uV$R[I`c.HKRwAe/,cj\^4Q] H{OA"ŲUmGKKƖ@mt9-{oj4zC1cuq7jlooSD`]OX H@uir#nM60]:ؼ㖪[hҁVP(WX`_OsRn%̗KGq mmӸ NݮbfG[!UXxwcD`K$h6-at. #My̞:TSrqv'vtm0 dqa̓븠 FEgnpNսE~9nac +ǚ_úbM /[쥺4;6MW=FIpʸ8p.xBl;((BU>jc"8YThbEg\M6xnqA_Σ+ zuCu=mOz7orb9W +683ha`e:.#ھ`>ooCkj_ +'[KDnUJPraimſPn-ʟU/"ZçHGu?Q+[y{ W h_[! Q /ش?1=L0s\zq% l +X4z_5Hl:CLBN*(Q풯ǖ;Nlp?8oMk0 HY@_Ǥ($ΜgYg󰩅xZ5|RѴ}\5R%ssMdEuҚm[mU<ᐋb`4GĦ&6|,_ֆuu@a߯p< Jư8R'b$D5UҩeeuS$i +7?I;8@hDVJ^kp&@|!Ys!Ռ=֭ڥNC;35w_Ko_ ^xUa+*Z\QxF۵F ~mOKz4ZB2)DR@6{g0-B݄{Cna- Mu<>l3+Bڒ,b)njDNW8\ ,8~k46.1oMk \&!pi9вٴW10婣iU(OL +awgZM`zn&kΝ8Q1^0G1m"kNM%B +$K2_TbMcKVh^+Ybk `kJ(3+\,v8C9&:ě.ԺUh& +q'"5tұkx;A*H}ld W#x ^IZNrOvUrFVy:SI `\0%t1i wBN8vd3xlmӦ_m@:xZQePNN"X<bx MIr>ÿ39T82'-'s n;aҙ|?!X$IK <gܪXF[,xf$f"ç 0ntKl7?Q_E; ~ŀؿbį+(V+îptlzgK?O& 1f6 hW@̾6t` +:B {\EPu=+ f_7h0 `6,ƬF'?n z0Ⱦ@\YL d_fYod_ Dv.[k'@m2<~nl4[t}?|^MߪvS`g&ޅu?u])>iܲw{w=5x?&QgYд- l#o?6 g7} Z?xsr F#_~{z unfٓO"ߧEgW>I YgfZZ.Mʩ t݉x}_wk>]mS7ѫi[Te|[":ٮ\;r)CD 1k_4#g7 ؏RE0wZF ǹj}"UT_TmTSA viUkXv-qG$hfFG1&@b ~mT'(ʃGAz(pi' a cP}BDJOl?@c05Ż./-Xυ-/vPsp6G"H5nUgz͘`^U6]6r:,&>KIȬT i-&G^XP[i(\g&в&zkEއm C/`%=,Ũa-֊ZAAuǷShLGvR,eHBC"] ϨW2,: +8kjѲF"HVI(uܯa*.n01߮)*C0'\$t|B`lqB) ̑gf-' +/ayX iIP$"eAaa(?>6 i5&]ܥzrq!Mvڴ C٪{Ҵ΅]6)'ns*'8.vl\Os1Ϋ,Rd+WXR~i .ao`d|YM,z^:Cgkd6|RXz5vP;Hѓ ?G E,茢V@aBv&S:!ClħL>1 #Q* VͯZ'KLNψogcjxz# nZ-)2'aMҋxgT,^ׄu8s76nah5IM-46߅27 +G3ʾ=1s"7 hd:C4"8(}<]ɈypVJ)i_KR=H?(} qFr K}dѸv'zy^H{{?MVF4ᮩ,ìjJk+sB\{ zC85KwBZd ,~"rbnh,3h4(PVMš"ZB<"ts"j[Єe,Zp*a1==kw']kiGt F&YvoqU32x*|P3p 5UyV!$cxJ{pWYVfj'4]|FӖbPCHdRЂu1MP4SJ,KF!1YQ% Z E#z@GLz<> L[m ُRrf͊\:BI}R)vv?!?.(Z#~}d?5 5T؈U<ьr˩GS2.l+n`%4N@’6@7\|p!iw 6rkD1,?H\S&Um2ʼn] ROJBd3,5u{/r}z_zLNq]z:>zuRA0o:L=Ԏ3XFeȟi q>fĂMU|+P'(F'[*.b>z-%\T\켋зY`eDB)2Y ' ;&]։QQV W;c EOfq5+`z~,-9ft) $Vdd07lW1#[A' +me2a.\ 5-%@%hYJ +g䋺kN^SmqzZwYZTيB*ي>cёYdF@S-M:)#hH s&JVexNkR˶Tj)ӐrGQfBv ~7bv!;+V5@Pw meD#/~SFw?ċA|0!C)ў^~7a#%1La0 ^ 7cz +g=@|0<v4E(^gQy o:UW@!:ݠxA.^&OO8R?wCZSM%+$F{&h](U򇬲1$j40p$WϥVU)8Rj%MFg)4ʸ]M!c0Cڃb V*"B.f:uCQztM\!_ (u^U +Kf軺)._\^M% +Di o] +BQALD:QgNڡȲbhplC~޴*5(i()7fL"M(# +D$<^K1W 3^ K^$QR ki4u/>JgY0nQb¸qzuo z?u]ZuHbRk|i,A) +RmLzh^g)?{:la'՝!BLf K3>o) $s_qMuM֊rK()^0xoY여7P')DBe\3MYyi~]mBL5Zm%^+GXW-mς&P&՚S lX&$%,S$KgL#{**.;@F}X%6 +&pmqF)08K +ԓ{ѓe7 &]S7\om쟬(tlMmk.\9iray Nv* Og9{F|`_s)F*6^8_oz$dK +gJa2ǎaVzf>? ew񡿇`O``Ň~LJQ|0^~NOv {cP^_ 8FT[IԎ,˗|T!WEl ܣ#w$i,Ł\zO *ޫ9'I2 +cK&rky c]=ۛzO4:dh3u0ibXFWуV8T_)흙#3e}or<ϔg~0.hܛĘISOU?Y4l$[8=SPk8ulݚ8%@Ȇ7[T72ghfmmpk9w\"'C'[,FI焍wMoθeHl܃vmg&\i1[Μ)yT<7W'^ulC3͹rY(, cmJ,ʉb5TX1. .-3]K_%n4>U:Ѱw 8v7=ۦpquG;co`*YG4S̾A7t`4hI-Kՠ#uk;u^!vv(FˬDj1ҝu["86&[ *R=6RxJy8Ċ6oޟg%8Tp XsmK?dkX6k\Cel4CͳHӄ N07E.ፉW ] ]k{0,E$hy_wZ@!/Q.Qz*K 6ZpAQ%քT;P$~C""0o >%JjǷI )N߼~|'==7,.cx|CϮ( kQj0g[<74~)f{lkȸ +,8K_c&!ڱac L{^5:&*+m~ڞO\<l# +0GNn+wI3_9 +hFs_wN_ch %#eL(whwptoM]韅jzh=0)+]^HtG%so8 +`s>C,+?fT +?ᝲ|QC_C8J.7!}!x +]Et~<\6f8XndvK#goϞwy-2>7Rd9~U)-5G! #rZo-59-t;kE-]Rrΰ]2ei].,nϖVۅXIկ/!߆NR`!H#71P'F<{9$(H<)SBA %"DP9q4b`£ +bB!!p{A`PPE#(PHO'S$ 6 }! 껠`{ |">x{bWS$Oxj'O|'܉vX\!u60.~  Vorm|>Al$';rHN w6 @'HN C!ȝb\ILX*;.YE+%_%HpS C xzzj^mtC q1C6^N)j/PC+qSNFkSlx_ :hSs9h\}rB< \E`hVRKtIÐ+2(85dP*kQUvϮ@KQm3p}a+k!jm-7gn*u qu"$|uE NƮ_)˹)@9T# ǹʦ^Ƨ72lR;3}'Vc9,Ui@Ŗ`-2!cx&37X|lؚzd1!gK-4M12^X`u +C&] .6>.W +IVޯTDQ-r8UK +sS΂9Gņ] H]:U۵AV5]nA\q }֊U<63QPsrwʔ;Hpƣ=lGjm^cR4"-ni6ՃT xHݎ!BA#`V(aIZdcORf~ډsn;z(lHp^Frf(|$hX4l[닲(PJ%:,FttǨ(/q3߯OP0Yفh゜1TW6ZQ&3!Bb2I_۸?~ +Qq0yEB5D1#ïyj/3p8/Q {Q3GO(le|w) Ԡk,;lM~}2䜺Fw1VrbwUF'zƒ-'@ȴ? ]nˀ$qoұ"1FzAΰdƏ;ap~:5c8R +tϻ%=x:աo=S3l7cLT'~8Aaj4?0+F.6Nz +"[q{Ք(hNԏp;Q%9;CanCi[Ext^ORNYiѬWTiH4r8#-l? A5($GMh2zFq:)aX,^ml ۘM%2 :b"d4dbG8'_YXrםoѼr *{ɮX#~^@ _\-I5ݵRK*Gs8 +k 8تF 4FP|I 0Pu~$I9ޓM0Ǖ 42a!sXn͙wf_gf忘4ͼg{ӬRD|F`2ũՔa*|V !!4 ?k.(4s +F~i mP_aH-uC?A4pJE؀/PeELToS3r|LK>>JwWD@T44Dqk0 r:ڹ8C8W;Vr!qBZP~)ϯQRHth<< <s(Q>T)\p):`o\^'^e^)^+LA(1ἒzC-Pw:K;$4x[bFl\h46< ɶ-'I<Ocw"QPRf"cѱ8P 1s)$KuE܋8Q֞/r yfoɰ5Zz$V'|?:5AU8 60X!Ƙ< |WDh[?TF{7C¡ml{hǍ38C?8q;c[gͭ6bR; {"? +?C>xdbܾ5;(n!֥-"Y`*KVpHj`$ NۂpS\ޛT9 6&:r%pV>|e*h;xد8$x+b_K_"=i 0!@ +SfEz8!gz3Ҏu^(i&L.<i~@'So:Wy\eh_ 8-ͬ;2Ø= w}hJh5߭|3-e97k,]_H嵴m #QM!S T9aOFᘶ<|Mܥ M\ morzB:rCOT]!`M0 DJY $B_}uz00 oQɺU̳5b͓L9k(TҚʿdi2@jK/F[ UjtωSHWQS'ؼij_:  08<4(9)Ĵ$@Z8ɧu +BǪt,5&.LFAI{7mN*r"](>Y2reGQ=Y:"Ar@\x)~k8W@$HG+*:7m,i +.6#FO<%;Lpi{R({Q+jN<]ЩɚP,Z&qmoC_SkŗV9 j2 -es|SG?E6q%;JϊU`zǗ$4w0mr>cQ\- .F̖bUƀ.IW[YA/gzxxSLoZӰcኁ_Y<[l nnƐSdTOyK&"#=Zh.ȧp]ZѝS{o,^hfINj,o'K[Z<ȮCچ>Z_n p.weI(jyJYɜĮ[#v\꫎@$kI:K]%Ot;2oT'2N^68c5 +({&a?^Pɡ{F4pc1*z^t7U*0ҁiUz"/b5(G0 xwM=`َ>&.s歞ש-BBđXEYΈW4u.yGTriI< gy/u8'hsa-Q\p9<?[3g>l89Jl +O +g̯,E.<+k-ɍH-Ip+{I]<7eVꖬC/zI,J qQ3tJJVw>@~qGFR_H=BƯ nτ1uvU{揓VFO't*~:[cJp25RŒԤ D8*OuqPm\@BN{;~9j'IH|dyj */UF%ա` [33j2D U9ӋU9f(vsfQ@YeR]u?AoCbʑ$)5} LNA@`07IU&eK[2/6jaY'Ƌ/ȇ@Kυ.:R5ʼ-{ŌohxC;ӆBs*W @g/ˎRdWU=kV8՛_NxcT͏7dtpRK-V'xc79{-Tk6ybX!Au2WYo"Ÿl\鮜^\B1!REr:8q4#08q oDk֖k" 9q\JVG : G nQxe g 蝻Ň.Yjlߪ&騯!0 ,eٳGrc}p,3}Ó;AVfh_] mUcCJM/5 dK[1u%ґW.Lam ber|S-"I*7_ +oʖFf@BہBǥh3*nM>H[LE˝,bGyj ' F3]J;/lɣ-5_ǮGruVD83|\Rf׸KeirpLp^{%"؂GJtRyat.31݁L B\w3μ8{=< z Ƨ/`a7&kx&O=]1-@$,dyaacv϶RrO Q|(PFv7/Y͐5ן?? m endstream endobj 20 0 obj <>stream +8;Z]"d1*u9$q*U908,d#`_7`M9`'%WdC%#noM*3(tg*_78+k?qNQSg7F_u: +#U+k_?RG!'DjoH.aEH,7KlYB\\$IDb;$rZ.P]YatS\*:)0HnLJ]$)dOAh;$8De.Og3rksRY^WbFrQX6*][d%hCLu!+bUCna endstream endobj 58 0 obj [/Indexed/DeviceRGB 255 59 0 R] endobj 59 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 6 0 obj [5 0 R] endobj 60 0 obj <> endobj xref 0 61 0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000025296 00000 n +0000000000 00000 f +0000036811 00000 n +0001211656 00000 n +0000025401 00000 n +0000025769 00000 n +0000026127 00000 n +0000026487 00000 n +0000026846 00000 n +0000027205 00000 n +0000027566 00000 n +0000027925 00000 n +0000028284 00000 n +0001191823 00000 n +0000428738 00000 n +0000037109 00000 n +0000036996 00000 n +0001210680 00000 n +0001174706 00000 n +0000037290 00000 n +0001155758 00000 n +0001143906 00000 n +0001134059 00000 n +0001122062 00000 n +0001113919 00000 n +0001107731 00000 n +0000028649 00000 n +0000036880 00000 n +0000036911 00000 n +0000037325 00000 n +0000428812 00000 n +0000429510 00000 n +0000430629 00000 n +0000435014 00000 n +0000485641 00000 n +0000524405 00000 n +0000569806 00000 n +0000620878 00000 n +0000645752 00000 n +0000661202 00000 n +0000683840 00000 n +0000706991 00000 n +0000730587 00000 n +0000752185 00000 n +0000759249 00000 n +0000782790 00000 n +0000806804 00000 n +0000828746 00000 n +0000838494 00000 n +0000842333 00000 n +0000885836 00000 n +0000934539 00000 n +0000973677 00000 n +0001024389 00000 n +0001065197 00000 n +0001211095 00000 n +0001211143 00000 n +0001211679 00000 n +trailer <<09B1BF319EAF40F7970CFEC84FBD9EA8>]>> startxref 1211859 %%EOF \ No newline at end of file diff --git a/información/lqdvi_bestline.jpg b/información/lqdvi_bestline.jpg new file mode 100644 index 00000000..3c535612 Binary files /dev/null and b/información/lqdvi_bestline.jpg differ diff --git a/referencia/WordPress/wordpress-3.1.3-es_ES.zip b/referencia/WordPress/wordpress-3.1.3-es_ES.zip new file mode 100644 index 00000000..13f403d2 Binary files /dev/null and b/referencia/WordPress/wordpress-3.1.3-es_ES.zip differ diff --git a/referencia/plantillas/bloggingstream.zip b/referencia/plantillas/bloggingstream.zip new file mode 100644 index 00000000..0ab351d2 Binary files /dev/null and b/referencia/plantillas/bloggingstream.zip differ diff --git a/src/index.php b/src/index.php new file mode 100644 index 00000000..49403ecc --- /dev/null +++ b/src/index.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/src/licencia.txt b/src/licencia.txt new file mode 100644 index 00000000..c87e9547 --- /dev/null +++ b/src/licencia.txt @@ -0,0 +1,322 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, Junio 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +675 Mass Ave, Cambridge, MA 02139, EEUU + +Se permiten la copia y distribución de copias literales de este documento, +pero no se permite su modificación. + +----------------------------------------------------------------------- + + NOTA IMPORTANTE + +Esta es una traducción no oficial al español de la GNU General Public +License. No ha sido publicada por la Free Software Foundation, y no +establece legalmente las condiciones de distribución para el software que +usa la GNU GPL. Estas condiciones se establecen solamente por el texto +original, en inglés, de la GNU GPL. Sin embargo, esperamos que esta +traducción ayude a los hispanohablantes a entender mejor la GNU GPL. + + AUTORES DE LA TRADUCCIÓN + + * Jesús González Barahona + * Pedro de las Heras Quirós + * Jordi J. Canals (Revisión y Formato. Junio de 2008) + * Fernando Tellado (A partir de Noviembre de 2009) + + +----------------------------------------------------------------------- + + Preámbulo + + Las licencias que cubren la mayor parte del software están diseñadas +para quitarle a usted la libertad de compartirlo y modificarlo. Por el +contrario, la Licencia Pública General de GNU pretende garantizarle la +libertad de compartir y modificar software libre, para asegurar que el +software es libre para todos sus usuarios. Esta Licencia Pública General +se aplica a la mayor parte del software del la Free Software Foundation y +a cualquier otro programa si sus autores se comprometen a utilizarla. +(Existe otro software de la Free Software Foundation que está cubierto por +la Licencia Pública General de GNU para Bibliotecas). Si quiere, también +puede aplicarla a sus propios programas. + + Cuando hablamos de software libre, estamos refiriéndonos a libertad, no +a precio. Nuestras Licencias Públicas Generales están diseñadas para +asegurarnos de que tenga la libertad de distribuir copias de software +libre (y cobrar por ese servicio si quiere), de que reciba el código +fuente o que pueda conseguirlo si lo quiere, de que pueda modificar el +software o usar fragmentos de él en nuevos programas libres, y de que sepa +que puede hacer todas estas cosas. + + Para proteger sus derechos necesitamos algunas restricciones que +prohiban a cualquiera negarle a usted estos derechos o pedirle que +renuncie a ellos. Estas restricciones se traducen en ciertas obligaciones +que le afectan si distribuye copias del software, o si lo modifica. + + Por ejemplo, si distribuye copias de uno de estos programas, sea +gratuitamente, o a cambio de una contraprestación, debe dar a los +receptores todos los derechos que tiene. Debe asegurarse de que ellos +también reciben, o pueden conseguir, el código fuente. Y debe mostrarles +estas condiciones de forma que conozcan sus derechos. + + Protegemos sus derechos con la combinación de dos medidas: + + 1. Ponemos el software bajo copyright y + 2. le ofrecemos esta licencia, que le da permiso legal para copiar, + distribuir y/o modificar el software. + + También, para la protección de cada autor y la nuestra propia, queremos +asegurarnos de que todo el mundo comprende que no se proporciona ninguna +garantía para este software libre. Si el software se modifica por +cualquiera y éste a su vez lo distribuye, queremos que sus receptores +sepan que lo que tienen no es el original, de forma que cualquier problema +introducido por otros no afecte a la reputación de los autores originales. + + Por último, cualquier programa libre está constantemente amenazado por +patentes sobre el software. Queremos evitar el peligro de que los +redistribuidores de un programa libre obtengan patentes por su cuenta, +convirtiendo de facto el programa en propietario. Para evitar esto, hemos +dejado claro que cualquier patente debe ser pedida para el uso libre de +cualquiera, o no ser pedida. + + Los términos exactos y las condiciones para la copia, distribución y +modificación se exponen a continuación. + + + GNU GENERAL PUBLIC LICENSE + TERMINOS Y CONDICIONES PARA LA COPIA, DISTRIBUCIÓN Y MODIFICACIÓN + + 0. Esta Licencia se aplica a cualquier programa u otro tipo de trabajo +que contenga una nota colocada por el tenedor del copyright diciendo que +puede ser distribuido bajo los términos de esta Licencia Pública General. +En adelante, «Programa» se referirá a cualquier programa o trabajo que +cumpla esa condición y «trabajo basado en el Programa» se referirá bien al +Programa o a cualquier trabajo derivado de él según la ley de copyright. +Esto es, un trabajo que contenga el programa o una proción de él, bien en +forma literal o con modificaciones y/o traducido en otro lenguaje. Por +lo tanto, la traducción está incluida sin limitaciones en el término +«modificación». Cada concesionario (licenciatario) será denominado «usted». + +Cualquier otra actividad que no sea la copia, distribución o modificación +no está cubierta por esta Licencia, está fuera de su ámbito. El acto de +ejecutar el Programa no está restringido, y los resultados del Programa +están cubiertos únicamente si sus contenidos constituyen un trabajo basado +en el Programa, independientemente de haberlo producido mediante la +ejecución del programa. El que esto se cumpla, depende de lo que haga el +programa. + + 1. Usted puede copiar y distribuir copias literales del código fuente +del Programa, según lo has recibido, en cualquier medio, supuesto que de +forma adecuada y bien visible publique en cada copia un anuncio de +copyright adecuado y un repudio de garantía, mantenga intactos todos los +anuncios que se refieran a esta Licencia y a la ausencia de garantía, y +proporcione a cualquier otro receptor del programa una copia de esta +Licencia junto con el Programa. + +Puede cobrar un precio por el acto físico de transferir una copia, y +puede, según su libre albedrío, ofrecer garantía a cambio de unos +honorarios. + + 3. Puede modificar su copia o copias del Programa o de cualquier +porción de él, formando de esta manera un trabajo basado en el Programa, y +copiar y distribuir esa modificación o trabajo bajo los términos del +apartado 1, antedicho, supuesto que además cumpla las siguientes +condiciones: + + a) Debe hacer que los ficheros modificados lleven anuncios prominentes + indicando que los ha cambiado y la fecha de cualquier cambio. + + b) Debe hacer que cualquier trabajo que distribuya o publique y que en + todo o en parte contenga o sea derivado del Programa o de cualquier + parte de él sea licenciada como un todo, sin carga alguna, a todas las + terceras partes y bajo los términos de esta Licencia. + + c) Si el programa modificado lee normalmente órdenes interactivamente + cuando es ejecutado, debe hacer que, cuando comience su ejecución para + ese uso interactivo de la forma más habitual, muestre o escriba un + mensaje que incluya un anuncio de copyright y un anuncio de que no se + ofrece ninguna garantía (o por el contrario que sí se ofrece garantía) + y que los usuarios pueden redistribuir el programa bajo estas + condiciones, e indicando al usuario cómo ver una copia de esta + licencia. (Excepción: si el propio programa es interactivo pero + normalmente no muestra ese anuncio, no se requiere que su trabajo + basado en el Programa muestre ningún anuncio). + + +Estos requisitos se aplican al trabajo modificado como un todo. Si partes +identificables de ese trabajo no son derivadas del Programa, y pueden, +razonablemente, ser consideradas trabajos independientes y separados por +ellos mismos, entonces esta Licencia y sus términos no se aplican a esas +partes cuando sean distribuidas como trabajos separados. Pero cuando +distribuya esas mismas secciones como partes de un todo que es un trabajo +basado en el Programa, la distribución del todo debe ser según los +términos de esta licencia, cuyos permisos para otros licenciatarios se +extienden al todo completo, y por lo tanto a todas y cada una de sus +partes, con independencia de quién la escribió. Por lo tanto, no es la +intención de este apartado reclamar derechos o desafiar sus derechos sobre +trabajos escritos totalmente por usted mismo. El intento es ejercer el +derecho a controlar la distribución de trabajos derivados o colectivos +basados en el Programa. + +Además, el simple hecho de reunir un trabajo no basado en el Programa con +el Programa (o con un trabajo basado en el Programa) en un volumen de +almacenamiento o en un medio de distribución no hace que dicho trabajo +entre dentro del ámbito cubierto por esta Licencia. + + 3. Puede copiar y distribuir el Programa (o un trabajo basado en él, +según se especifica en el apartado 2, como código objeto o en formato +ejecutable según los términos de los apartados 1 y 2, supuesto que además +cumpla una de las siguientes condiciones: + + a) Acompañarlo con el código fuente completo correspondiente, en + formato electrónico, que debe ser distribuido según se especifica en + los apartados 1 y 2 de esta Licencia en un medio habitualmente + utilizado para el intercambio de programas, o + + b) Acompañarlo con una oferta por escrito, válida durante al menos + tres años, de proporcionar a cualquier tercera parte una copia completa + en formato electrónico del código fuente correspondiente, a un coste + no mayor que el de realizar físicamente la distribución del fuente, + que será distribuido bajo las condiciones descritas en los apartados 1 + y 2 anteriores, en un medio habitualmente utilizado para el + intercambio de programas, o + + c) Acompañarlo con la información que recibiste ofreciendo distribuir + el código fuente correspondiente. (Esta opción se permite sólo para + distribución no comercial y sólo si usted recibió el programa como + código objeto o en formato ejecutable con tal oferta, de acuerdo con + el apartado b anterior). + +Por código fuente de un trabajo se entiende la forma preferida del trabajo +cuando se le hacen modificaciones. Para un trabajo ejecutable, se entiende +por código fuente completo todo el código fuente para todos los módulos +que contiene, más cualquier fichero asociado de definición de interfaces, +más los guiones utilizados para controlar la compilación e instalación del +ejecutable. Como excepción especial el código fuente distribuido no +necesita incluir nada que sea distribuido normalmente (bien como fuente, +bien en forma binaria) con los componentes principales (compilador, kernel +y similares) del sistema operativo en el cual funciona el ejecutable, a no +ser que el propio componente acompañe al ejecutable. + +Si la distribución del ejecutable o del código objeto se hace mediante la +oferta acceso para copiarlo de un cierto lugar, entonces se considera la +oferta de acceso para copiar el código fuente del mismo lugar como +distribución del código fuente, incluso aunque terceras partes no estén +forzadas a copiar el fuente junto con el código objeto. + + 4. No puede copiar, modificar, sublicenciar o distribuir el Programa +excepto como prevé expresamente esta Licencia. Cualquier intento de +copiar, modificar sublicenciar o distribuir el Programa de otra forma es +inválida, y hará que cesen automáticamente los derechos que te proporciona +esta Licencia. En cualquier caso, las partes que hayan recibido copias o +derechos de usted bajo esta Licencia no cesarán en sus derechos mientras +esas partes continúen cumpliéndola. + + 5. No está obligado a aceptar esta licencia, ya que no la ha firmado. +Sin embargo, no hay hada más que le proporcione permiso para modificar o +distribuir el Programa o sus trabajos derivados. Estas acciones están +prohibidas por la ley si no acepta esta Licencia. Por lo tanto, si +modifica o distribuye el Programa (o cualquier trabajo basado en el +Programa), está indicando que acepta esta Licencia para poder hacerlo, y +todos sus términos y condiciones para copiar, distribuir o modificar el +Programa o trabajos basados en él. + + 6. Cada vez que redistribuya el Programa (o cualquier trabajo basado en +el Programa), el receptor recibe automáticamente una licencia del +licenciatario original para copiar, distribuir o modificar el Programa, de +forma sujeta a estos términos y condiciones. No puede imponer al receptor +ninguna restricción más sobre el ejercicio de los derechos aquí +garantizados. No es usted responsable de hacer cumplir esta licencia por +terceras partes. + + 7. Si como consecuencia de una resolución judicial o de una alegación de +infracción de patente o por cualquier otra razón (no limitada a asuntos +relacionados con patentes) se le imponen condiciones (ya sea por mandato +judicial, por acuerdo o por cualquier otra causa) que contradigan las +condiciones de esta Licencia, ello no le exime de cumplir las condiciones +de esta Licencia. Si no puede realizar distribuciones de forma que se +satisfagan simultáneamente sus obligaciones bajo esta licencia y cualquier +otra obligación pertinente entonces, como consecuencia, no puede +distribuir el Programa de ninguna forma. Por ejemplo, si una patente no +permite la redistribución libre de derechos de autor del Programa por +parte de todos aquellos que reciban copias directa o indirectamente a +través de usted, entonces la única forma en que podría satisfacer tanto +esa condición como esta Licencia sería evitar completamente la +distribución del Programa. + +Si cualquier porción de este apartado se considera inválida o imposible de +cumplir bajo cualquier circunstancia particular ha de cumplirse el resto y +la sección por entero ha de cumplirse en cualquier otra circunstancia + +No es el propósito de este apartado inducirle a infringir ninguna +reivindicación de patente ni de ningún otro derecho de propiedad o +impugnar la validez de ninguna de dichas reivindicaciones. Este apartado +tiene el único propósito de proteger la integridad del sistema de +distribución de software libre, que se realiza mediante prácticas de +licencia pública. Mucha gente ha hecho contribuciones generosas a la gran +variedad de software distribuido mediante ese sistema con la confianza de +que el sistema se aplicará consistentemente. Será el autor/donante quien +decida si quiere distribuir software mediante cualquier otro sistema y una +licencia no puede imponer esa elección. + +Este apartado pretende dejar completamente claro lo que se cree que es una +consecuencia del resto de esta Licencia. + + 8. Si la distribución y/o uso de el Programa está restringida en ciertos +países, bien por patentes o por interfaces bajo copyright, el tenedor del +copyright que coloca este Programa bajo esta Licencia puede añadir una +limitación explícita de distribución geográfica excluyendo esos países, de +forma que la distribución se permita sólo en o entre los países no +excluidos de esta manera. En ese caso, esta Licencia incorporará la +limitación como si estuviese escrita en el cuerpo de esta Licencia. + + 9. La Free Software Foundation puede publicar versiones revisadas y/o +nuevas de la Licencia Pública General de tiempo en tiempo. Dichas nuevas +versiones serán similares en espíritu a la presente versión, pero pueden +ser diferentes en detalles para considerar nuevos problemas o situaciones. + +Cada versión recibe un número de versión que la distingue de otras. Si el +Programa especifica un número de versión de esta Licencia que se refiere a +ella y a «cualquier versión posterior», tienes la opción de seguir los +términos y condiciones, bien de esa versión, bien de cualquier versión +posterior publicada por la Free Software Foundation. Si el Programa no +especifica un número de versión de esta Licencia, puedes escoger cualquier +versión publicada por la Free Software Foundation. + + 10. Si quiere incorporar partes del Programa en otros programas libres +cuyas condiciones de distribución son diferentes, escribe al autor para +pedirle permiso. Si el software tiene copyright de la Free Software +Foundation, escribe a la Free Software Foundation: algunas veces hacemos +excepciones en estos casos. Nuestra decisión estará guiada por el doble +objetivo de de preservar la libertad de todos los derivados de nuestro +software libre y promover el que se comparta y reutilice el software en +general. + + + AUSENCIA DE GARANTÍA + + 11. Como el programa se licencia libre de cargas, no se ofrece ninguna +garantía sobre el programa, en todas la extensión permitida por la +legislación aplicable. Excepto cuando se indique de otra forma por +escrito, los tenedores del copyright y/u otras partes proporcionan el +programa «tal cual», sin garantía de ninguna clase, bien expresa o +implícita, con inclusión, pero sin limitación a las garantías mercantiles +implícitas o a la conveniencia para un propósito particular. Cualquier +riesgo referente a la calidad y prestaciones del programa es asumido por +usted. Si se probase que el Programa es defectuoso, asume el coste de +cualquier servicio, reparación o corrección. + + 12. En ningún caso, salvo que lo requiera la legislación aplicable o +haya sido acordado por escrito, ningún tenedor del copyright ni ninguna +otra parte que modifique y/o redistribuya el Programa según se permite en +esta Licencia será responsable ante usted por daños, incluyendo cualquier +daño general, especial, incidental o resultante producido por el uso o la +imposibilidad de uso del Programa (con inclusión, pero sin limitación a la +pérdida de datos o a la generación incorrecta de datos o a pérdidas +sufridas por usted o por terceras partes o a un fallo del Programa al +funcionar en combinación con cualquier otro programa), incluso si dicho +tenedor u otra parte ha sido advertido de la posibilidad de dichos daños. + + FIN DE TÉRMINOS Y CONDICIONES diff --git a/src/license.txt b/src/license.txt new file mode 100644 index 00000000..d31195ab --- /dev/null +++ b/src/license.txt @@ -0,0 +1,281 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/src/readme.html b/src/readme.html new file mode 100644 index 00000000..3be02a8a --- /dev/null +++ b/src/readme.html @@ -0,0 +1,104 @@ + + + + + WordPress › Léame + + + +

+ WordPress +
Versión 3.1.3 +

+

Plataforma Semántica de Publicación Personal

+ +

Para empezar

+

Te damos la bienvenida. WordPress es un proyecto muy especial para mí. Cada desarrollador o colaborador añade algo único a la mezcla, y juntos vamos creando algo hermoso de lo que me enorgullece formar parte. Se han dedicado miles de horas a WordPress y nos seguimos empleando en mejorarlo cada día. Gracias por hacerlo parte de tu mundo.

+

— Matt Mullenweg

+ +

Instalación: la famosa Instalación en 5 minutos

+
    +
  1. Descomprime el paquete en una carpeta vacía.
  2. +
  3. Abre wp-config-sample.php con un editor de texto como WordPad o similar y rellena los datos de tu conexión a la base de datos.
  4. +
  5. Guarda el archivo como wp-config.php.
  6. +
  7. Sube todo a tu servidor.
  8. +
  9. Abre /wp-admin/install.php en tu navegador. Con esto deberán crearse las tablas necesarias para tu blog. Si hay algún error, haz el favor de comprobar tu archivo wp-config.php y probar de nuevo. Si vuelve a fallar, visita los foros de ayuda con todos los datos que puedas aportar.
  10. +
  11. Anota la contraseña que se te proporcionará.
  12. +
  13. El programa de instalación te enviará entonces a la página de entrada. Entra con el nombre de usuario admin y la contraseña generada durante la instalación. Ahora podrás hacer clic en 'Perfil' y cambiar la contraseña.
  14. +
+ +

Actualizar

+

Usar el Actualizador automático

+

Si estás actualizando desde la versión 2.7 o superior puedes usar el actualizador automático:

+
    +
  1. Abre wp-admin/update-core.php en tu navegador y sigue las instrucciones.
  2. +
  3. ¿Querías más?.¡Eso es todo!
  4. +
+ +

Actualizar manualmente:

+
    +
  1. Antes de actualizar nada, asegúrate de tener copias de seguridad de cualquier archivo que hayas modificado, como index.php.
  2. +
  3. Elimina tus archivos de WP anteriores, guardando aquellos que hayas modificado.
  4. +
  5. Sube los nuevos archivos a tu servidor.
  6. +
  7. Dirige tu navegador a /wp-admin/upgrade.php.
  8. +
+

Cambios en las plantillas

+

Si has modificado tus plantillas, es posible que debas hacerles algunos cambios cuando actualices entre versiones mayores.

+ +

Migrar desde otros sistemas

+

WordPress puede importar contenido de otros sistemas. Lo primero que tienes que hacer es instalar WordPress y ponerlo en marcha como se ha descrito arriba, y luego usar nuestras herramientas de importación.

+ +

Requisitos del sistema

+
    +
  • PHP versión 4.3 o superior.
  • +
  • MySQL versión 4.1.2 o superior.
  • +
+ +

Recomendaciones del sistema

+ + + +

Recursos en la red

+

Si alguna de tus preguntas no encuentra respuesta en este documento, te sugerimos que aproveches los numerosos recursos de WordPress en la red:

+
+
El Codex de WordPress
+
El Codex es la enciclopedia de todo lo relacionado con WordPress. Es la fuente de información más detallada disponible sobre WordPress.
+
El blog de desarrollo
+
Aquí encontrarás las últimas actualizaciones y noticias relacionadas con WordPress. Inclúyelo en tus marcadores y visítalo con frecuencia.
+
WordPress Planet
+
El WordPress Planet (Planeta WordPress) es un agregador de noticias que recopila entradas de blogs de WordPress por toda la web.
+
Foros de ayuda de WordPress
+
Si has buscado por todas partes pero sigues sin encontrar la respuesta, en los foros de ayuda, muy activos, cuentas con una amplia comunidad deseosa de ayudar. Para ayudarles a ayudarte, asegúrate de usar un título descriptivo e incluir en tu pregunta tantos detalles como te sea posible.
+
Canal IRC de WordPress
+
Por último, existe un canal de chat utilizado por la gente que usa Wordpress para intercambiar opiniones y eventualmente solicitar ayuda. La página del wiki que ves arriba podrá orientarte. (irc.freenode.net #wordpress)
+
+ +

Interfaz XML-RPC y Atom

+

Ahora puedes publicar en tu blog de WordPress con herramientas como Windows Live Writer, Ecto, Bloggar, Radio Userland (es decir, puedes utilizar la función de blog por e-mail de Radio Userland), NewzCrawler, y otras herramientas compatibles con las API (en inglés, Interfaz de Programación de la Aplicación) de blog. :) Puedes ampliar la información en XML-RPC support en el Codex.

+ +

Publicar por e-mail

+

Puedes publicar por medio de un cliente de e-mail. Para configurar esta opción, ve a la pantalla de opciones de "Escribir" y rellena los datos de tu cuenta POP3 secreta. Después tendrás que configurar la ejecución periódica de wp-mail.php para que revise el buzón en busca de correo nuevo. Puedes hacerlo mediante Cron-jobs o, si tu proveedor de alojamiento no lo permite, buscar uno de los muchos servicios de monitorización web para que compruebe la URL de tu wp-mail.php.

+

Publicar es sencillo: cualquier mensaje que envíes a la dirección especificada será publicado, con el asunto como título. Por eso es mejor mantener en privado la dirección. El script borrará los mensajes una vez publicados.

+ +

Perfiles de usuario

+

Hemos introducido un sistema flexible de perfiles de usuario en la versión 2.0. Puedes leer más sobre Funciones y Competencias en el Codex.

+ +

Notas finales

+
    +
  • Si tienes alguna sugerencia, idea, comentario, o si encuentras (ejem) un fallo, únete a nosotros en los Foros de ayuda.
  • +
  • WordPress tiene ahora una robusta API de plugins que facilita la ampliación del código. Si eres un desarrollador interesado en utilizarla, mira la documentación para plugins en el Codex. En la mayoría de los casos, no tendrás que modificar nada del código central.
  • +
+ +

Comparte tu afición

+

WordPress no cuenta con campañas de publicidad multimillonarias ni promotores famosos, pero tiene algo aún mejor: tú. Si disfrutas con WordPress, por favor, piensa en decírselo a un amigo, instalárselo a alguien menos entendido que tú o escribir al autor de un artículo que pase de nosotros.

+ +

WordPress es la continuación oficial de b2/cafélog, de Michel V. El trabajo se ha continuado gracias a los desarrolladores de WordPress. Si quieres apoyar a WordPress puedes dar un donativo.

+ +

Copyright

+

WordPress se distribuye bajo la GPLv2 (ver la licencia).

+ + + diff --git a/src/wp-activate.php b/src/wp-activate.php new file mode 100644 index 00000000..6bc019c7 --- /dev/null +++ b/src/wp-activate.php @@ -0,0 +1,102 @@ +cache_enabled = false; + +do_action("activate_header"); + +function do_activate_header() { + do_action("activate_wp_head"); +} +add_action( 'wp_head', 'do_activate_header' ); + +function wpmu_activate_stylesheet() { + ?> + + + +
+ + +

+
+

+ +
+

+

+ +

+
+ + get_error_code() || 'blog_taken' == $result->get_error_code() ) { + $signup = $result->get_error_data(); + ?> +

+ '; + if ( $signup->domain . $signup->path == '' ) { + printf( __('Your account has been activated. You may now log in to the site using your chosen username of “%2$s”. Please check your email inbox at %3$s for your password and login instructions. If you do not receive an email, please check your junk or spam folder. If you still do not receive an email within an hour, you can reset your password.'), network_site_url( 'wp-login.php', 'login' ), $signup->user_login, $signup->user_email, network_site_url( 'wp-login.php?action=lostpassword', 'login' ) ); + } else { + printf( __('Your site at %2$s is active. You may now log in to your site using your chosen username of “%3$s”. Please check your email inbox at %4$s for your password and login instructions. If you do not receive an email, please check your junk or spam folder. If you still do not receive an email within an hour, you can reset your password.'), 'http://' . $signup->domain, $signup->domain, $signup->user_login, $signup->user_email, network_site_url( 'wp-login.php?action=lostpassword' ) ); + } + echo '

'; + } else { + ?> +

+ '.$result->get_error_message().'

'; + } + } else { + extract($result); + $url = get_blogaddress_by_id( (int) $blog_id); + $user = new WP_User( (int) $user_id); + ?> +

+ +
+

user_login ?>

+

+
+ + +

View your site or Login'), $url, $url . 'wp-login.php' ); ?>

+ +

Login or go back to the homepage.' ), network_site_url('wp-login.php', 'login'), network_home_url() ); ?>

+ +
+ + \ No newline at end of file diff --git a/src/wp-admin/admin-ajax.php b/src/wp-admin/admin-ajax.php new file mode 100644 index 00000000..a7e0b48d --- /dev/null +++ b/src/wp-admin/admin-ajax.php @@ -0,0 +1,1477 @@ +ALERT: You are logged out! Could not save draft. Please log in again.'), wp_login_url() ); + $x = new WP_Ajax_Response( array( + 'what' => 'autosave', + 'id' => $id, + 'data' => $message + ) ); + $x->send(); + } + + if ( !empty( $_REQUEST['action'] ) ) + do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] ); + + die('-1'); +} + +if ( isset( $_GET['action'] ) ) : +switch ( $action = $_GET['action'] ) : +case 'fetch-list' : + + $list_class = $_GET['list_args']['class']; + check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' ); + + $current_screen = (object) $_GET['list_args']['screen']; + //TODO fix this in a better way see #15336 + $current_screen->is_network = 'false' === $current_screen->is_network ? false : true; + $current_screen->is_user = 'false' === $current_screen->is_user ? false : true; + + define( 'WP_NETWORK_ADMIN', $current_screen->is_network ); + define( 'WP_USER_ADMIN', $current_screen->is_user ); + + $wp_list_table = _get_list_table( $list_class ); + if ( ! $wp_list_table ) + die( '0' ); + + if ( ! $wp_list_table->ajax_user_can() ) + die( '-1' ); + + $wp_list_table->ajax_response(); + + die( '0' ); + break; +case 'ajax-tag-search' : + if ( isset( $_GET['tax'] ) ) { + $taxonomy = sanitize_key( $_GET['tax'] ); + $tax = get_taxonomy( $taxonomy ); + if ( ! $tax ) + die( '0' ); + if ( ! current_user_can( $tax->cap->assign_terms ) ) + die( '-1' ); + } else { + die('0'); + } + + $s = stripslashes( $_GET['q'] ); + + if ( false !== strpos( $s, ',' ) ) { + $s = explode( ',', $s ); + $s = $s[count( $s ) - 1]; + } + $s = trim( $s ); + if ( strlen( $s ) < 2 ) + die; // require 2 chars for matching + + $results = $wpdb->get_col( $wpdb->prepare( "SELECT t.name FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.name LIKE (%s)", $taxonomy, '%' . like_escape( $s ) . '%' ) ); + + echo join( $results, "\n" ); + die; + break; +case 'wp-compression-test' : + if ( !current_user_can( 'manage_options' ) ) + die('-1'); + + if ( ini_get('zlib.output_compression') || 'ob_gzhandler' == ini_get('output_handler') ) { + update_site_option('can_compress_scripts', 0); + die('0'); + } + + if ( isset($_GET['test']) ) { + header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' ); + header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); + header( 'Cache-Control: no-cache, must-revalidate, max-age=0' ); + header( 'Pragma: no-cache' ); + header('Content-Type: application/x-javascript; charset=UTF-8'); + $force_gzip = ( defined('ENFORCE_GZIP') && ENFORCE_GZIP ); + $test_str = '"wpCompressionTest Lorem ipsum dolor sit amet consectetuer mollis sapien urna ut a. Eu nonummy condimentum fringilla tempor pretium platea vel nibh netus Maecenas. Hac molestie amet justo quis pellentesque est ultrices interdum nibh Morbi. Cras mattis pretium Phasellus ante ipsum ipsum ut sociis Suspendisse Lorem. Ante et non molestie. Porta urna Vestibulum egestas id congue nibh eu risus gravida sit. Ac augue auctor Ut et non a elit massa id sodales. Elit eu Nulla at nibh adipiscing mattis lacus mauris at tempus. Netus nibh quis suscipit nec feugiat eget sed lorem et urna. Pellentesque lacus at ut massa consectetuer ligula ut auctor semper Pellentesque. Ut metus massa nibh quam Curabitur molestie nec mauris congue. Volutpat molestie elit justo facilisis neque ac risus Ut nascetur tristique. Vitae sit lorem tellus et quis Phasellus lacus tincidunt nunc Fusce. Pharetra wisi Suspendisse mus sagittis libero lacinia Integer consequat ac Phasellus. Et urna ac cursus tortor aliquam Aliquam amet tellus volutpat Vestibulum. Justo interdum condimentum In augue congue tellus sollicitudin Quisque quis nibh."'; + + if ( 1 == $_GET['test'] ) { + echo $test_str; + die; + } elseif ( 2 == $_GET['test'] ) { + if ( !isset($_SERVER['HTTP_ACCEPT_ENCODING']) ) + die('-1'); + if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') && ! $force_gzip ) { + header('Content-Encoding: deflate'); + $out = gzdeflate( $test_str, 1 ); + } elseif ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') ) { + header('Content-Encoding: gzip'); + $out = gzencode( $test_str, 1 ); + } else { + die('-1'); + } + echo $out; + die; + } elseif ( 'no' == $_GET['test'] ) { + update_site_option('can_compress_scripts', 0); + } elseif ( 'yes' == $_GET['test'] ) { + update_site_option('can_compress_scripts', 1); + } + } + + die('0'); + break; +case 'imgedit-preview' : + $post_id = intval($_GET['postid']); + if ( empty($post_id) || !current_user_can('edit_post', $post_id) ) + die('-1'); + + check_ajax_referer( "image_editor-$post_id" ); + + include_once( ABSPATH . 'wp-admin/includes/image-edit.php' ); + if ( ! stream_preview_image($post_id) ) + die('-1'); + + die(); + break; +case 'menu-quick-search': + if ( ! current_user_can( 'edit_theme_options' ) ) + die('-1'); + + require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; + + _wp_ajax_menu_quick_search( $_REQUEST ); + + exit; + break; +case 'oembed-cache' : + $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0'; + die( $return ); + break; +default : + do_action( 'wp_ajax_' . $_GET['action'] ); + die('0'); + break; +endswitch; +endif; + +/** + * Sends back current comment total and new page links if they need to be updated. + * + * Contrary to normal success AJAX response ("1"), die with time() on success. + * + * @since 2.7 + * + * @param int $comment_id + * @return die + */ +function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) { + $total = (int) @$_POST['_total']; + $per_page = (int) @$_POST['_per_page']; + $page = (int) @$_POST['_page']; + $url = esc_url_raw( @$_POST['_url'] ); + // JS didn't send us everything we need to know. Just die with success message + if ( !$total || !$per_page || !$page || !$url ) + die( (string) time() ); + + $total += $delta; + if ( $total < 0 ) + $total = 0; + + // Only do the expensive stuff on a page-break, and about 1 other time per page + if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) { + $post_id = 0; + $status = 'total_comments'; // What type of comment count are we looking for? + $parsed = parse_url( $url ); + if ( isset( $parsed['query'] ) ) { + parse_str( $parsed['query'], $query_vars ); + if ( !empty( $query_vars['comment_status'] ) ) + $status = $query_vars['comment_status']; + if ( !empty( $query_vars['p'] ) ) + $post_id = (int) $query_vars['p']; + } + + $comment_count = wp_count_comments($post_id); + + if ( isset( $comment_count->$status ) ) // We're looking for a known type of comment count + $total = $comment_count->$status; + // else use the decremented value from above + } + + $time = time(); // The time since the last comment count + + $x = new WP_Ajax_Response( array( + 'what' => 'comment', + 'id' => $comment_id, // here for completeness - not used + 'supplemental' => array( + 'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ), + 'total_pages' => ceil( $total / $per_page ), + 'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ), + 'total' => $total, + 'time' => $time + ) + ) ); + $x->send(); +} + +function _wp_ajax_add_hierarchical_term() { + $action = $_POST['action']; + $taxonomy = get_taxonomy(substr($action, 4)); + check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name ); + if ( !current_user_can( $taxonomy->cap->edit_terms ) ) + die('-1'); + $names = explode(',', $_POST['new'.$taxonomy->name]); + $parent = isset($_POST['new'.$taxonomy->name.'_parent']) ? (int) $_POST['new'.$taxonomy->name.'_parent'] : 0; + if ( 0 > $parent ) + $parent = 0; + if ( $taxonomy->name == 'category' ) + $post_category = isset($_POST['post_category']) ? (array) $_POST['post_category'] : array(); + else + $post_category = ( isset($_POST['tax_input']) && isset($_POST['tax_input'][$taxonomy->name]) ) ? (array) $_POST['tax_input'][$taxonomy->name] : array(); + $checked_categories = array_map( 'absint', (array) $post_category ); + $popular_ids = wp_popular_terms_checklist($taxonomy->name, 0, 10, false); + + foreach ( $names as $cat_name ) { + $cat_name = trim($cat_name); + $category_nicename = sanitize_title($cat_name); + if ( '' === $category_nicename ) + continue; + if ( !($cat_id = term_exists($cat_name, $taxonomy->name, $parent)) ) { + $new_term = wp_insert_term($cat_name, $taxonomy->name, array('parent' => $parent)); + $cat_id = $new_term['term_id']; + } + $checked_categories[] = $cat_id; + if ( $parent ) // Do these all at once in a second + continue; + $category = get_term( $cat_id, $taxonomy->name ); + ob_start(); + wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids )); + $data = ob_get_contents(); + ob_end_clean(); + $add = array( + 'what' => $taxonomy->name, + 'id' => $cat_id, + 'data' => str_replace( array("\n", "\t"), '', $data), + 'position' => -1 + ); + } + + if ( $parent ) { // Foncy - replace the parent and all its children + $parent = get_term( $parent, $taxonomy->name ); + $term_id = $parent->term_id; + + while ( $parent->parent ) { // get the top parent + $parent = &get_term( $parent->parent, $taxonomy->name ); + if ( is_wp_error( $parent ) ) + break; + $term_id = $parent->term_id; + } + + ob_start(); + wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids)); + $data = ob_get_contents(); + ob_end_clean(); + $add = array( + 'what' => $taxonomy->name, + 'id' => $term_id, + 'data' => str_replace( array("\n", "\t"), '', $data), + 'position' => -1 + ); + } + + ob_start(); + wp_dropdown_categories( array( + 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name', + 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —' + ) ); + $sup = ob_get_contents(); + ob_end_clean(); + $add['supplemental'] = array( 'newcat_parent' => $sup ); + + $x = new WP_Ajax_Response( $add ); + $x->send(); +} + +$id = isset($_POST['id'])? (int) $_POST['id'] : 0; +switch ( $action = $_POST['action'] ) : +case 'delete-comment' : // On success, die with time() instead of 1 + if ( !$comment = get_comment( $id ) ) + die( (string) time() ); + if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) ) + die('-1'); + + check_ajax_referer( "delete-comment_$id" ); + $status = wp_get_comment_status( $comment->comment_ID ); + + $delta = -1; + if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) { + if ( 'trash' == $status ) + die( (string) time() ); + $r = wp_trash_comment( $comment->comment_ID ); + } elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) { + if ( 'trash' != $status ) + die( (string) time() ); + $r = wp_untrash_comment( $comment->comment_ID ); + if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash + $delta = 1; + } elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) { + if ( 'spam' == $status ) + die( (string) time() ); + $r = wp_spam_comment( $comment->comment_ID ); + } elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) { + if ( 'spam' != $status ) + die( (string) time() ); + $r = wp_unspam_comment( $comment->comment_ID ); + if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam + $delta = 1; + } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) { + $r = wp_delete_comment( $comment->comment_ID ); + } else { + die('-1'); + } + + if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts + _wp_ajax_delete_comment_response( $comment->comment_ID, $delta ); + die( '0' ); + break; +case 'delete-tag' : + $tag_id = (int) $_POST['tag_ID']; + check_ajax_referer( "delete-tag_$tag_id" ); + + $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag'; + $tax = get_taxonomy($taxonomy); + + if ( !current_user_can( $tax->cap->delete_terms ) ) + die('-1'); + + $tag = get_term( $tag_id, $taxonomy ); + if ( !$tag || is_wp_error( $tag ) ) + die('1'); + + if ( wp_delete_term($tag_id, $taxonomy)) + die('1'); + else + die('0'); + break; +case 'delete-link' : + check_ajax_referer( "delete-bookmark_$id" ); + if ( !current_user_can( 'manage_links' ) ) + die('-1'); + + $link = get_bookmark( $id ); + if ( !$link || is_wp_error( $link ) ) + die('1'); + + if ( wp_delete_link( $id ) ) + die('1'); + else + die('0'); + break; +case 'delete-meta' : + check_ajax_referer( "delete-meta_$id" ); + if ( !$meta = get_post_meta_by_id( $id ) ) + die('1'); + + if ( !current_user_can( 'edit_post', $meta->post_id ) || is_protected_meta( $meta->meta_key ) ) + die('-1'); + if ( delete_meta( $meta->meta_id ) ) + die('1'); + die('0'); + break; +case 'delete-post' : + check_ajax_referer( "{$action}_$id" ); + if ( !current_user_can( 'delete_post', $id ) ) + die('-1'); + + if ( !get_post( $id ) ) + die('1'); + + if ( wp_delete_post( $id ) ) + die('1'); + else + die('0'); + break; +case 'trash-post' : +case 'untrash-post' : + check_ajax_referer( "{$action}_$id" ); + if ( !current_user_can( 'delete_post', $id ) ) + die('-1'); + + if ( !get_post( $id ) ) + die('1'); + + if ( 'trash-post' == $action ) + $done = wp_trash_post( $id ); + else + $done = wp_untrash_post( $id ); + + if ( $done ) + die('1'); + + die('0'); + break; +case 'delete-page' : + check_ajax_referer( "{$action}_$id" ); + if ( !current_user_can( 'delete_page', $id ) ) + die('-1'); + + if ( !get_page( $id ) ) + die('1'); + + if ( wp_delete_post( $id ) ) + die('1'); + else + die('0'); + break; +case 'dim-comment' : // On success, die with time() instead of 1 + + if ( !$comment = get_comment( $id ) ) { + $x = new WP_Ajax_Response( array( + 'what' => 'comment', + 'id' => new WP_Error('invalid_comment', sprintf(__('Comment %d does not exist'), $id)) + ) ); + $x->send(); + } + + if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) ) + die('-1'); + + $current = wp_get_comment_status( $comment->comment_ID ); + if ( $_POST['new'] == $current ) + die( (string) time() ); + + check_ajax_referer( "approve-comment_$id" ); + if ( in_array( $current, array( 'unapproved', 'spam' ) ) ) + $result = wp_set_comment_status( $comment->comment_ID, 'approve', true ); + else + $result = wp_set_comment_status( $comment->comment_ID, 'hold', true ); + + if ( is_wp_error($result) ) { + $x = new WP_Ajax_Response( array( + 'what' => 'comment', + 'id' => $result + ) ); + $x->send(); + } + + // Decide if we need to send back '1' or a more complicated response including page links and comment counts + _wp_ajax_delete_comment_response( $comment->comment_ID ); + die( '0' ); + break; +case 'add-link-category' : // On the Fly + check_ajax_referer( $action ); + if ( !current_user_can( 'manage_categories' ) ) + die('-1'); + $names = explode(',', $_POST['newcat']); + $x = new WP_Ajax_Response(); + foreach ( $names as $cat_name ) { + $cat_name = trim($cat_name); + $slug = sanitize_title($cat_name); + if ( '' === $slug ) + continue; + if ( !$cat_id = term_exists( $cat_name, 'link_category' ) ) { + $cat_id = wp_insert_term( $cat_name, 'link_category' ); + } + $cat_id = $cat_id['term_id']; + $cat_name = esc_html(stripslashes($cat_name)); + $x->add( array( + 'what' => 'link-category', + 'id' => $cat_id, + 'data' => "", + 'position' => -1 + ) ); + } + $x->send(); + break; +case 'add-tag' : + check_ajax_referer( 'add-tag' ); + $post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post'; + $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag'; + $tax = get_taxonomy($taxonomy); + + if ( !current_user_can( $tax->cap->edit_terms ) ) + die('-1'); + + $x = new WP_Ajax_Response(); + + $tag = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST ); + + if ( !$tag || is_wp_error($tag) || (!$tag = get_term( $tag['term_id'], $taxonomy )) ) { + $message = __('An error has occurred. Please reload the page and try again.'); + if ( is_wp_error($tag) && $tag->get_error_message() ) + $message = $tag->get_error_message(); + + $x->add( array( + 'what' => 'taxonomy', + 'data' => new WP_Error('error', $message ) + ) ); + $x->send(); + } + + set_current_screen( $_POST['screen'] ); + + $wp_list_table = _get_list_table('WP_Terms_List_Table'); + + $level = 0; + if ( is_taxonomy_hierarchical($taxonomy) ) { + $level = count( get_ancestors( $tag->term_id, $taxonomy ) ); + ob_start(); + $wp_list_table->single_row( $tag, $level ); + $noparents = ob_get_clean(); + } + + ob_start(); + $wp_list_table->single_row( $tag ); + $parents = ob_get_clean(); + + $x->add( array( + 'what' => 'taxonomy', + 'supplemental' => compact('parents', 'noparents') + ) ); + $x->add( array( + 'what' => 'term', + 'position' => $level, + 'supplemental' => (array) $tag + ) ); + $x->send(); + break; +case 'get-tagcloud' : + if ( isset( $_POST['tax'] ) ) { + $taxonomy = sanitize_key( $_POST['tax'] ); + $tax = get_taxonomy( $taxonomy ); + if ( ! $tax ) + die( '0' ); + if ( ! current_user_can( $tax->cap->assign_terms ) ) + die( '-1' ); + } else { + die('0'); + } + + $tags = get_terms( $taxonomy, array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) ); + + if ( empty( $tags ) ) + die( isset( $tax->no_tagcloud ) ? $tax->no_tagcloud : __('No tags found!') ); + + if ( is_wp_error( $tags ) ) + die( $tags->get_error_message() ); + + foreach ( $tags as $key => $tag ) { + $tags[ $key ]->link = '#'; + $tags[ $key ]->id = $tag->term_id; + } + + // We need raw tag names here, so don't filter the output + $return = wp_generate_tag_cloud( $tags, array('filter' => 0) ); + + if ( empty($return) ) + die('0'); + + echo $return; + + exit; + break; +case 'get-comments' : + check_ajax_referer( $action ); + + set_current_screen( 'edit-comments' ); + + $wp_list_table = _get_list_table('WP_Post_Comments_List_Table'); + + if ( !current_user_can( 'edit_post', $post_id ) ) + die('-1'); + + $wp_list_table->prepare_items(); + + if ( !$wp_list_table->has_items() ) + die('1'); + + $comment_list_item = ''; + $x = new WP_Ajax_Response(); + foreach ( $wp_list_table->items as $comment ) { + get_comment( $comment ); + ob_start(); + $wp_list_table->single_row( $comment ); + $comment_list_item .= ob_get_contents(); + ob_end_clean(); + } + $x->add( array( + 'what' => 'comments', + 'data' => $comment_list_item + ) ); + $x->send(); + break; +case 'replyto-comment' : + check_ajax_referer( $action, '_ajax_nonce-replyto-comment' ); + + set_current_screen( 'edit-comments' ); + + $comment_post_ID = (int) $_POST['comment_post_ID']; + if ( !current_user_can( 'edit_post', $comment_post_ID ) ) + die('-1'); + + $status = $wpdb->get_var( $wpdb->prepare("SELECT post_status FROM $wpdb->posts WHERE ID = %d", $comment_post_ID) ); + + if ( empty($status) ) + die('1'); + elseif ( in_array($status, array('draft', 'pending', 'trash') ) ) + die( __('Error: you are replying to a comment on a draft post.') ); + + $user = wp_get_current_user(); + if ( $user->ID ) { + $comment_author = $wpdb->escape($user->display_name); + $comment_author_email = $wpdb->escape($user->user_email); + $comment_author_url = $wpdb->escape($user->user_url); + $comment_content = trim($_POST['content']); + if ( current_user_can('unfiltered_html') ) { + if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) { + kses_remove_filters(); // start with a clean slate + kses_init_filters(); // set up the filters + } + } + } else { + die( __('Sorry, you must be logged in to reply to a comment.') ); + } + + if ( '' == $comment_content ) + die( __('Error: please type a comment.') ); + + $comment_parent = absint($_POST['comment_ID']); + $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID'); + + $comment_id = wp_new_comment( $commentdata ); + $comment = get_comment($comment_id); + if ( ! $comment ) die('1'); + + $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1'; + + $x = new WP_Ajax_Response(); + + ob_start(); + if ( 'dashboard' == $_REQUEST['mode'] ) { + require_once( ABSPATH . 'wp-admin/includes/dashboard.php' ); + _wp_dashboard_recent_comments_row( $comment ); + } else { + if ( 'single' == $_REQUEST['mode'] ) { + $wp_list_table = _get_list_table('WP_Post_Comments_List_Table'); + } else { + $wp_list_table = _get_list_table('WP_Comments_List_Table'); + } + $wp_list_table->single_row( $comment ); + } + $comment_list_item = ob_get_contents(); + ob_end_clean(); + + $x->add( array( + 'what' => 'comment', + 'id' => $comment->comment_ID, + 'data' => $comment_list_item, + 'position' => $position + )); + + $x->send(); + break; +case 'edit-comment' : + check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' ); + + set_current_screen( 'edit-comments' ); + + $comment_post_ID = (int) $_POST['comment_post_ID']; + if ( ! current_user_can( 'edit_post', $comment_post_ID ) ) + die('-1'); + + if ( '' == $_POST['content'] ) + die( __('Error: please type a comment.') ); + + $comment_id = (int) $_POST['comment_ID']; + $_POST['comment_status'] = $_POST['status']; + edit_comment(); + + $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1'; + $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : ''; + + $checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0; + $wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table' ); + + ob_start(); + $wp_list_table->single_row( get_comment( $comment_id ) ); + $comment_list_item = ob_get_contents(); + ob_end_clean(); + + $x = new WP_Ajax_Response(); + + $x->add( array( + 'what' => 'edit_comment', + 'id' => $comment->comment_ID, + 'data' => $comment_list_item, + 'position' => $position + )); + + $x->send(); + break; +case 'add-menu-item' : + if ( ! current_user_can( 'edit_theme_options' ) ) + die('-1'); + + check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' ); + + require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; + + // For performance reasons, we omit some object properties from the checklist. + // The following is a hacky way to restore them when adding non-custom items. + + $menu_items_data = array(); + foreach ( (array) $_POST['menu-item'] as $menu_item_data ) { + if ( + ! empty( $menu_item_data['menu-item-type'] ) && + 'custom' != $menu_item_data['menu-item-type'] && + ! empty( $menu_item_data['menu-item-object-id'] ) + ) { + switch( $menu_item_data['menu-item-type'] ) { + case 'post_type' : + $_object = get_post( $menu_item_data['menu-item-object-id'] ); + break; + + case 'taxonomy' : + $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] ); + break; + } + + $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) ); + $_menu_item = array_shift( $_menu_items ); + + // Restore the missing menu item properties + $menu_item_data['menu-item-description'] = $_menu_item->description; + } + + $menu_items_data[] = $menu_item_data; + } + + $item_ids = wp_save_nav_menu_items( 0, $menu_items_data ); + if ( is_wp_error( $item_ids ) ) + die('-1'); + + foreach ( (array) $item_ids as $menu_item_id ) { + $menu_obj = get_post( $menu_item_id ); + if ( ! empty( $menu_obj->ID ) ) { + $menu_obj = wp_setup_nav_menu_item( $menu_obj ); + $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items + $menu_items[] = $menu_obj; + } + } + + if ( ! empty( $menu_items ) ) { + $args = array( + 'after' => '', + 'before' => '', + 'link_after' => '', + 'link_before' => '', + 'walker' => new Walker_Nav_Menu_Edit, + ); + echo walk_nav_menu_tree( $menu_items, 0, (object) $args ); + } + break; +case 'add-meta' : + check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' ); + $c = 0; + $pid = (int) $_POST['post_id']; + $post = get_post( $pid ); + + if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) { + if ( !current_user_can( 'edit_post', $pid ) ) + die('-1'); + if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) ) + die('1'); + if ( $post->post_status == 'auto-draft' ) { + $save_POST = $_POST; // Backup $_POST + $_POST = array(); // Make it empty for edit_post() + $_POST['action'] = 'draft'; // Warning fix + $_POST['post_ID'] = $pid; + $_POST['post_type'] = $post->post_type; + $_POST['post_status'] = 'draft'; + $now = current_time('timestamp', 1); + $_POST['post_title'] = sprintf('Draft created on %s at %s', date(get_option('date_format'), $now), date(get_option('time_format'), $now)); + + if ( $pid = edit_post() ) { + if ( is_wp_error( $pid ) ) { + $x = new WP_Ajax_Response( array( + 'what' => 'meta', + 'data' => $pid + ) ); + $x->send(); + } + $_POST = $save_POST; // Now we can restore original $_POST again + if ( !$mid = add_meta( $pid ) ) + die(__('Please provide a custom field value.')); + } else { + die('0'); + } + } else if ( !$mid = add_meta( $pid ) ) { + die(__('Please provide a custom field value.')); + } + + $meta = get_post_meta_by_id( $mid ); + $pid = (int) $meta->post_id; + $meta = get_object_vars( $meta ); + $x = new WP_Ajax_Response( array( + 'what' => 'meta', + 'id' => $mid, + 'data' => _list_meta_row( $meta, $c ), + 'position' => 1, + 'supplemental' => array('postid' => $pid) + ) ); + } else { // Update? + $mid = (int) array_pop( $var_by_ref = array_keys($_POST['meta']) ); + $key = $_POST['meta'][$mid]['key']; + $value = $_POST['meta'][$mid]['value']; + if ( '' == trim($key) ) + die(__('Please provide a custom field name.')); + if ( '' == trim($value) ) + die(__('Please provide a custom field value.')); + if ( !$meta = get_post_meta_by_id( $mid ) ) + die('0'); // if meta doesn't exist + if ( !current_user_can( 'edit_post', $meta->post_id ) ) + die('-1'); + if ( is_protected_meta( $meta->meta_key ) ) + die('-1'); + if ( $meta->meta_value != stripslashes($value) || $meta->meta_key != stripslashes($key) ) { + if ( !$u = update_meta( $mid, $key, $value ) ) + die('0'); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems). + } + + $key = stripslashes($key); + $value = stripslashes($value); + $x = new WP_Ajax_Response( array( + 'what' => 'meta', + 'id' => $mid, 'old_id' => $mid, + 'data' => _list_meta_row( array( + 'meta_key' => $key, + 'meta_value' => $value, + 'meta_id' => $mid + ), $c ), + 'position' => 0, + 'supplemental' => array('postid' => $meta->post_id) + ) ); + } + $x->send(); + break; +case 'add-user' : + check_ajax_referer( $action ); + if ( !current_user_can('create_users') ) + die('-1'); + if ( !$user_id = add_user() ) + die('0'); + elseif ( is_wp_error( $user_id ) ) { + $x = new WP_Ajax_Response( array( + 'what' => 'user', + 'id' => $user_id + ) ); + $x->send(); + } + $user_object = new WP_User( $user_id ); + + $wp_list_table = _get_list_table('WP_Users_List_Table'); + + $x = new WP_Ajax_Response( array( + 'what' => 'user', + 'id' => $user_id, + 'data' => $wp_list_table->single_row( $user_object, '', $user_object->roles[0] ), + 'supplemental' => array( + 'show-link' => sprintf(__( 'User %s added' ), "user-$user_id", $user_object->user_login), + 'role' => $user_object->roles[0] + ) + ) ); + $x->send(); + break; +case 'autosave' : // The name of this action is hardcoded in edit_post() + define( 'DOING_AUTOSAVE', true ); + + $nonce_age = check_ajax_referer( 'autosave', 'autosavenonce' ); + + $_POST['post_category'] = explode(",", $_POST['catslist']); + if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) ) + unset($_POST['post_category']); + + $do_autosave = (bool) $_POST['autosave']; + $do_lock = true; + + $data = ''; + /* translators: draft saved date format, see http://php.net/date */ + $draft_saved_date_format = __('g:i:s a'); + /* translators: %s: date and time */ + $message = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) ); + + $supplemental = array(); + if ( isset($login_grace_period) ) + $supplemental['session_expired'] = add_query_arg( 'interim-login', 1, wp_login_url() ); + + $id = $revision_id = 0; + + $post_ID = (int) $_POST['post_ID']; + $_POST['ID'] = $post_ID; + $post = get_post($post_ID); + if ( 'auto-draft' == $post->post_status ) + $_POST['post_status'] = 'draft'; + + if ( $last = wp_check_post_lock( $post->ID ) ) { + $do_autosave = $do_lock = false; + + $last_user = get_userdata( $last ); + $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' ); + $data = new WP_Error( 'locked', sprintf( + $_POST['post_type'] == 'page' ? __( 'Autosave disabled: %s is currently editing this page.' ) : __( 'Autosave disabled: %s is currently editing this post.' ), + esc_html( $last_user_name ) + ) ); + + $supplemental['disable_autosave'] = 'disable'; + } + + if ( 'page' == $post->post_type ) { + if ( !current_user_can('edit_page', $post_ID) ) + die(__('You are not allowed to edit this page.')); + } else { + if ( !current_user_can('edit_post', $post_ID) ) + die(__('You are not allowed to edit this post.')); + } + + if ( $do_autosave ) { + // Drafts and auto-drafts are just overwritten by autosave + if ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) { + $id = edit_post(); + } else { // Non drafts are not overwritten. The autosave is stored in a special post revision. + $revision_id = wp_create_post_autosave( $post->ID ); + if ( is_wp_error($revision_id) ) + $id = $revision_id; + else + $id = $post->ID; + } + $data = $message; + } else { + if ( isset( $_POST['auto_draft'] ) && '1' == $_POST['auto_draft'] ) + $id = 0; // This tells us it didn't actually save + else + $id = $post->ID; + } + + if ( $do_lock && ( isset( $_POST['auto_draft'] ) && ( $_POST['auto_draft'] != '1' ) ) && $id && is_numeric($id) ) + wp_set_post_lock( $id ); + + if ( $nonce_age == 2 ) { + $supplemental['replace-autosavenonce'] = wp_create_nonce('autosave'); + $supplemental['replace-getpermalinknonce'] = wp_create_nonce('getpermalink'); + $supplemental['replace-samplepermalinknonce'] = wp_create_nonce('samplepermalink'); + $supplemental['replace-closedpostboxesnonce'] = wp_create_nonce('closedpostboxes'); + if ( $id ) { + if ( $_POST['post_type'] == 'post' ) + $supplemental['replace-_wpnonce'] = wp_create_nonce('update-post_' . $id); + elseif ( $_POST['post_type'] == 'page' ) + $supplemental['replace-_wpnonce'] = wp_create_nonce('update-page_' . $id); + } + } + + $x = new WP_Ajax_Response( array( + 'what' => 'autosave', + 'id' => $id, + 'data' => $id ? $data : '', + 'supplemental' => $supplemental + ) ); + $x->send(); + break; +case 'closed-postboxes' : + check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' ); + $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array(); + $closed = array_filter($closed); + + $hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array(); + $hidden = array_filter($hidden); + + $page = isset( $_POST['page'] ) ? $_POST['page'] : ''; + + if ( !preg_match( '/^[a-z_-]+$/', $page ) ) + die('-1'); + + if ( ! $user = wp_get_current_user() ) + die('-1'); + + if ( is_array($closed) ) + update_user_option($user->ID, "closedpostboxes_$page", $closed, true); + + if ( is_array($hidden) ) { + $hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown + update_user_option($user->ID, "metaboxhidden_$page", $hidden, true); + } + + die('1'); + break; +case 'hidden-columns' : + check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' ); + $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : ''; + $hidden = explode( ',', $_POST['hidden'] ); + $page = isset( $_POST['page'] ) ? $_POST['page'] : ''; + + if ( !preg_match( '/^[a-z_-]+$/', $page ) ) + die('-1'); + + if ( ! $user = wp_get_current_user() ) + die('-1'); + + if ( is_array($hidden) ) + update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true); + + die('1'); + break; +case 'menu-get-metabox' : + if ( ! current_user_can( 'edit_theme_options' ) ) + die('-1'); + + require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; + + if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) { + $type = 'posttype'; + $callback = 'wp_nav_menu_item_post_type_meta_box'; + $items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' ); + } elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) { + $type = 'taxonomy'; + $callback = 'wp_nav_menu_item_taxonomy_meta_box'; + $items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' ); + } + + if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) { + $item = apply_filters( 'nav_menu_meta_box_object', $items[ $_POST['item-object'] ] ); + ob_start(); + call_user_func_array($callback, array( + null, + array( + 'id' => 'add-' . $item->name, + 'title' => $item->labels->name, + 'callback' => $callback, + 'args' => $item, + ) + )); + + $markup = ob_get_clean(); + + echo json_encode(array( + 'replace-id' => $type . '-' . $item->name, + 'markup' => $markup, + )); + } + + exit; + break; +case 'menu-quick-search': + if ( ! current_user_can( 'edit_theme_options' ) ) + die('-1'); + + require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; + + _wp_ajax_menu_quick_search( $_REQUEST ); + + exit; + break; +case 'wp-link-ajax': + require_once ABSPATH . 'wp-admin/includes/internal-linking.php'; + + check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' ); + + $args = array(); + + if ( isset( $_POST['search'] ) ) + $args['s'] = stripslashes( $_POST['search'] ); + $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; + + $results = wp_link_query( $args ); + + if ( ! isset( $results ) ) + die( '0' ); + + echo json_encode( $results ); + echo "\n"; + + exit; + break; +case 'menu-locations-save': + if ( ! current_user_can( 'edit_theme_options' ) ) + die('-1'); + check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' ); + if ( ! isset( $_POST['menu-locations'] ) ) + die('0'); + set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) ); + die('1'); + break; +case 'meta-box-order': + check_ajax_referer( 'meta-box-order' ); + $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false; + $page_columns = isset( $_POST['page_columns'] ) ? (int) $_POST['page_columns'] : 0; + $page = isset( $_POST['page'] ) ? $_POST['page'] : ''; + + if ( !preg_match( '/^[a-z_-]+$/', $page ) ) + die('-1'); + + if ( ! $user = wp_get_current_user() ) + die('-1'); + + if ( $order ) + update_user_option($user->ID, "meta-box-order_$page", $order, true); + + if ( $page_columns ) + update_user_option($user->ID, "screen_layout_$page", $page_columns, true); + + die('1'); + break; +case 'get-permalink': + check_ajax_referer( 'getpermalink', 'getpermalinknonce' ); + $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0; + die(add_query_arg(array('preview' => 'true'), get_permalink($post_id))); +break; +case 'sample-permalink': + check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' ); + $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0; + $title = isset($_POST['new_title'])? $_POST['new_title'] : ''; + $slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null; + die(get_sample_permalink_html($post_id, $title, $slug)); +break; +case 'inline-save': + check_ajax_referer( 'inlineeditnonce', '_inline_edit' ); + + if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) ) + exit; + + if ( 'page' == $_POST['post_type'] ) { + if ( ! current_user_can( 'edit_page', $post_ID ) ) + die( __('You are not allowed to edit this page.') ); + } else { + if ( ! current_user_can( 'edit_post', $post_ID ) ) + die( __('You are not allowed to edit this post.') ); + } + + set_current_screen( $_POST['screen'] ); + + if ( $last = wp_check_post_lock( $post_ID ) ) { + $last_user = get_userdata( $last ); + $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' ); + printf( $_POST['post_type'] == 'page' ? __( 'Saving is disabled: %s is currently editing this page.' ) : __( 'Saving is disabled: %s is currently editing this post.' ), esc_html( $last_user_name ) ); + exit; + } + + $data = &$_POST; + + $post = get_post( $post_ID, ARRAY_A ); + $post = add_magic_quotes($post); //since it is from db + + $data['content'] = $post['post_content']; + $data['excerpt'] = $post['post_excerpt']; + + // rename + $data['user_ID'] = $GLOBALS['user_ID']; + + if ( isset($data['post_parent']) ) + $data['parent_id'] = $data['post_parent']; + + // status + if ( isset($data['keep_private']) && 'private' == $data['keep_private'] ) + $data['post_status'] = 'private'; + else + $data['post_status'] = $data['_status']; + + if ( empty($data['comment_status']) ) + $data['comment_status'] = 'closed'; + if ( empty($data['ping_status']) ) + $data['ping_status'] = 'closed'; + + // update the post + edit_post(); + + $wp_list_table = _get_list_table('WP_Posts_List_Table'); + + $mode = $_POST['post_view']; + $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ) ); + + exit; + break; +case 'inline-save-tax': + check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' ); + + $taxonomy = sanitize_key( $_POST['taxonomy'] ); + $tax = get_taxonomy( $taxonomy ); + if ( ! $tax ) + die( '0' ); + + if ( ! current_user_can( $tax->cap->edit_terms ) ) + die( '-1' ); + + set_current_screen( 'edit-' . $taxonomy ); + + $wp_list_table = _get_list_table('WP_Terms_List_Table'); + + if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) ) + die(-1); + + $tag = get_term( $id, $taxonomy ); + $_POST['description'] = $tag->description; + + $updated = wp_update_term($id, $taxonomy, $_POST); + if ( $updated && !is_wp_error($updated) ) { + $tag = get_term( $updated['term_id'], $taxonomy ); + if ( !$tag || is_wp_error( $tag ) ) { + if ( is_wp_error($tag) && $tag->get_error_message() ) + die( $tag->get_error_message() ); + die( __('Item not updated.') ); + } + + echo $wp_list_table->single_row( $tag ); + } else { + if ( is_wp_error($updated) && $updated->get_error_message() ) + die( $updated->get_error_message() ); + die( __('Item not updated.') ); + } + + exit; + break; +case 'find_posts': + check_ajax_referer( 'find-posts' ); + + if ( empty($_POST['ps']) ) + exit; + + if ( !empty($_POST['post_type']) && in_array( $_POST['post_type'], get_post_types() ) ) + $what = $_POST['post_type']; + else + $what = 'post'; + + $s = stripslashes($_POST['ps']); + preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $s, $matches); + $search_terms = array_map('_search_terms_tidy', $matches[0]); + + $searchand = $search = ''; + foreach ( (array) $search_terms as $term ) { + $term = esc_sql( like_escape( $term ) ); + $search .= "{$searchand}(($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%'))"; + $searchand = ' AND '; + } + $term = esc_sql( like_escape( $s ) ); + if ( count($search_terms) > 1 && $search_terms[0] != $s ) + $search .= " OR ($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%')"; + + $posts = $wpdb->get_results( "SELECT ID, post_title, post_status, post_date FROM $wpdb->posts WHERE post_type = '$what' AND post_status IN ('draft', 'publish') AND ($search) ORDER BY post_date_gmt DESC LIMIT 50" ); + + if ( ! $posts ) { + $posttype = get_post_type_object($what); + exit($posttype->labels->not_found); + } + + $html = ''; + foreach ( $posts as $post ) { + + switch ( $post->post_status ) { + case 'publish' : + case 'private' : + $stat = __('Published'); + break; + case 'future' : + $stat = __('Scheduled'); + break; + case 'pending' : + $stat = __('Pending Review'); + break; + case 'draft' : + $stat = __('Draft'); + break; + } + + if ( '0000-00-00 00:00:00' == $post->post_date ) { + $time = ''; + } else { + /* translators: date format in table columns, see http://php.net/date */ + $time = mysql2date(__('Y/m/d'), $post->post_date); + } + + $html .= ''; + $html .= ''."\n\n"; + } + $html .= '

'.__('Title').''.__('Date').''.__('Status').'
'.esc_html( $time ).''.esc_html( $stat ).'
'; + + $x = new WP_Ajax_Response(); + $x->add( array( + 'what' => $what, + 'data' => $html + )); + $x->send(); + + break; +case 'widgets-order' : + check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' ); + + if ( !current_user_can('edit_theme_options') ) + die('-1'); + + unset( $_POST['savewidgets'], $_POST['action'] ); + + // save widgets order for all sidebars + if ( is_array($_POST['sidebars']) ) { + $sidebars = array(); + foreach ( $_POST['sidebars'] as $key => $val ) { + $sb = array(); + if ( !empty($val) ) { + $val = explode(',', $val); + foreach ( $val as $k => $v ) { + if ( strpos($v, 'widget-') === false ) + continue; + + $sb[$k] = substr($v, strpos($v, '_') + 1); + } + } + $sidebars[$key] = $sb; + } + wp_set_sidebars_widgets($sidebars); + die('1'); + } + + die('-1'); + break; +case 'save-widget' : + check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' ); + + if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) ) + die('-1'); + + unset( $_POST['savewidgets'], $_POST['action'] ); + + do_action('load-widgets.php'); + do_action('widgets.php'); + do_action('sidebar_admin_setup'); + + $id_base = $_POST['id_base']; + $widget_id = $_POST['widget-id']; + $sidebar_id = $_POST['sidebar']; + $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0; + $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false; + $error = '

' . __('An error has occurred. Please reload the page and try again.') . '

'; + + $sidebars = wp_get_sidebars_widgets(); + $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array(); + + // delete + if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { + + if ( !isset($wp_registered_widgets[$widget_id]) ) + die($error); + + $sidebar = array_diff( $sidebar, array($widget_id) ); + $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1'); + } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) { + if ( !$multi_number ) + die($error); + + $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) ); + $widget_id = $id_base . '-' . $multi_number; + $sidebar[] = $widget_id; + } + $_POST['widget-id'] = $sidebar; + + foreach ( (array) $wp_registered_widget_updates as $name => $control ) { + + if ( $name == $id_base ) { + if ( !is_callable( $control['callback'] ) ) + continue; + + ob_start(); + call_user_func_array( $control['callback'], $control['params'] ); + ob_end_clean(); + break; + } + } + + if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { + $sidebars[$sidebar_id] = $sidebar; + wp_set_sidebars_widgets($sidebars); + echo "deleted:$widget_id"; + die(); + } + + if ( !empty($_POST['add_new']) ) + die(); + + if ( $form = $wp_registered_widget_controls[$widget_id] ) + call_user_func_array( $form['callback'], $form['params'] ); + + die(); + break; +case 'image-editor': + $attachment_id = intval($_POST['postid']); + if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) ) + die('-1'); + + check_ajax_referer( "image_editor-$attachment_id" ); + include_once( ABSPATH . 'wp-admin/includes/image-edit.php' ); + + $msg = false; + switch ( $_POST['do'] ) { + case 'save' : + $msg = wp_save_image($attachment_id); + $msg = json_encode($msg); + die($msg); + break; + case 'scale' : + $msg = wp_save_image($attachment_id); + break; + case 'restore' : + $msg = wp_restore_image($attachment_id); + break; + } + + wp_image_editor($attachment_id, $msg); + die(); + break; +case 'set-post-thumbnail': + $post_ID = intval( $_POST['post_id'] ); + if ( !current_user_can( 'edit_post', $post_ID ) ) + die( '-1' ); + $thumbnail_id = intval( $_POST['thumbnail_id'] ); + + check_ajax_referer( "set_post_thumbnail-$post_ID" ); + + if ( $thumbnail_id == '-1' ) { + delete_post_meta( $post_ID, '_thumbnail_id' ); + die( _wp_post_thumbnail_html() ); + } + + if ( set_post_thumbnail( $post_ID, $thumbnail_id ) ) + die( _wp_post_thumbnail_html( $thumbnail_id ) ); + die( '0' ); + break; +case 'date_format' : + die( date_i18n( sanitize_option( 'date_format', $_POST['date'] ) ) ); + break; +case 'time_format' : + die( date_i18n( sanitize_option( 'time_format', $_POST['date'] ) ) ); + break; +default : + do_action( 'wp_ajax_' . $_POST['action'] ); + die('0'); + break; +endswitch; +?> diff --git a/src/wp-admin/admin-footer.php b/src/wp-admin/admin-footer.php new file mode 100644 index 00000000..c43ef2e8 --- /dev/null +++ b/src/wp-admin/admin-footer.php @@ -0,0 +1,43 @@ + + +
+
+
+ + + + + + + + diff --git a/src/wp-admin/admin-functions.php b/src/wp-admin/admin-functions.php new file mode 100644 index 00000000..b8c84fda --- /dev/null +++ b/src/wp-admin/admin-functions.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/src/wp-admin/admin-header.php b/src/wp-admin/admin-header.php new file mode 100644 index 00000000..ac793409 --- /dev/null +++ b/src/wp-admin/admin-header.php @@ -0,0 +1,196 @@ + + + > + + +<?php echo $admin_title; ?> + + + + + + +"> + + +
+
+ + +
+parent_file = $parent_file; +$current_screen->parent_base = preg_replace('/\?.*$/', '', $parent_file); +$current_screen->parent_base = str_replace('.php', '', $current_screen->parent_base); +?> + +
+ \ No newline at end of file diff --git a/src/wp-admin/admin.php b/src/wp-admin/admin.php new file mode 100644 index 00000000..ebb99c5e --- /dev/null +++ b/src/wp-admin/admin.php @@ -0,0 +1,238 @@ +flush_rules(); + update_option( 'db_upgraded', false ); + + /** + * Runs on the next page load after successful upgrade + * + * @since 2.8 + */ + do_action('after_db_upgrade'); +} elseif ( get_option('db_version') != $wp_db_version ) { + if ( !is_multisite() ) { + wp_redirect(admin_url('upgrade.php?_wp_http_referer=' . urlencode(stripslashes($_SERVER['REQUEST_URI'])))); + exit; + } elseif ( apply_filters( 'do_mu_upgrade', true ) ) { + /** + * On really small MU installs run the upgrader every time, + * else run it less often to reduce load. + * + * @since 2.8.4b + */ + $c = get_blog_count(); + if ( $c <= 50 || ( $c > 50 && mt_rand( 0, (int)( $c / 50 ) ) == 1 ) ) { + require_once( ABSPATH . WPINC . '/http.php' ); + $response = wp_remote_get( admin_url( 'upgrade.php?step=1' ), array( 'timeout' => 120, 'httpversion' => '1.1' ) ); + do_action( 'after_mu_upgrade', $response ); + unset($response); + } + unset($c); + } +} + +require_once(ABSPATH . 'wp-admin/includes/admin.php'); + +auth_redirect(); + +nocache_headers(); + +// Schedule trash collection +if ( !wp_next_scheduled('wp_scheduled_delete') && !defined('WP_INSTALLING') ) + wp_schedule_event(time(), 'daily', 'wp_scheduled_delete'); + +set_screen_options(); + +$date_format = get_option('date_format'); +$time_format = get_option('time_format'); + +wp_reset_vars(array('profile', 'redirect', 'redirect_url', 'a', 'text', 'trackback', 'pingback')); + +wp_enqueue_script( 'common' ); +wp_enqueue_script( 'jquery-color' ); + +$editing = false; + +if ( isset($_GET['page']) ) { + $plugin_page = stripslashes($_GET['page']); + $plugin_page = plugin_basename($plugin_page); +} + +if ( isset($_GET['post_type']) ) + $typenow = sanitize_key($_GET['post_type']); +else + $typenow = ''; + +if ( isset($_GET['taxonomy']) ) + $taxnow = sanitize_key($_GET['taxonomy']); +else + $taxnow = ''; + +if ( WP_NETWORK_ADMIN ) + require(ABSPATH . 'wp-admin/network/menu.php'); +elseif ( WP_USER_ADMIN ) + require(ABSPATH . 'wp-admin/user/menu.php'); +else + require(ABSPATH . 'wp-admin/menu.php'); + +if ( current_user_can( 'manage_options' ) ) + @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', '256M' ) ); + +do_action('admin_init'); + +if ( isset($plugin_page) ) { + if ( !empty($typenow) ) + $the_parent = $pagenow . '?post_type=' . $typenow; + else + $the_parent = $pagenow; + if ( ! $page_hook = get_plugin_page_hook($plugin_page, $the_parent) ) { + $page_hook = get_plugin_page_hook($plugin_page, $plugin_page); + // backwards compatibility for plugins using add_management_page + if ( empty( $page_hook ) && 'edit.php' == $pagenow && '' != get_plugin_page_hook($plugin_page, 'tools.php') ) { + // There could be plugin specific params on the URL, so we need the whole query string + if ( !empty($_SERVER[ 'QUERY_STRING' ]) ) + $query_string = $_SERVER[ 'QUERY_STRING' ]; + else + $query_string = 'page=' . $plugin_page; + wp_redirect( admin_url('tools.php?' . $query_string) ); + exit; + } + } + unset($the_parent); +} + +$hook_suffix = ''; +if ( isset($page_hook) ) + $hook_suffix = $page_hook; +else if ( isset($plugin_page) ) + $hook_suffix = $plugin_page; +else if ( isset($pagenow) ) + $hook_suffix = $pagenow; + +set_current_screen(); + +// Handle plugin admin pages. +if ( isset($plugin_page) ) { + if ( $page_hook ) { + do_action('load-' . $page_hook); + if (! isset($_GET['noheader'])) + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + do_action($page_hook); + } else { + if ( validate_file($plugin_page) ) + wp_die(__('Invalid plugin page')); + + + if ( !( file_exists(WP_PLUGIN_DIR . "/$plugin_page") && is_file(WP_PLUGIN_DIR . "/$plugin_page") ) && !( file_exists(WPMU_PLUGIN_DIR . "/$plugin_page") && is_file(WPMU_PLUGIN_DIR . "/$plugin_page") ) ) + wp_die(sprintf(__('Cannot load %s.'), htmlentities($plugin_page))); + + do_action('load-' . $plugin_page); + + if ( !isset($_GET['noheader'])) + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + if ( file_exists(WPMU_PLUGIN_DIR . "/$plugin_page") ) + include(WPMU_PLUGIN_DIR . "/$plugin_page"); + else + include(WP_PLUGIN_DIR . "/$plugin_page"); + } + + include(ABSPATH . 'wp-admin/admin-footer.php'); + + exit(); +} else if (isset($_GET['import'])) { + + $importer = $_GET['import']; + + if ( ! current_user_can('import') ) + wp_die(__('You are not allowed to import.')); + + if ( validate_file($importer) ) { + wp_redirect( admin_url( 'import.php?invalid=' . $importer ) ); + exit; + } + + // Allow plugins to define importers as well + if ( !isset($wp_importers) || !isset($wp_importers[$importer]) || ! is_callable($wp_importers[$importer][2])) { + if (! file_exists(ABSPATH . "wp-admin/import/$importer.php")) { + wp_redirect( admin_url( 'import.php?invalid=' . $importer ) ); + exit; + } + include(ABSPATH . "wp-admin/import/$importer.php"); + } + + $parent_file = 'tools.php'; + $submenu_file = 'import.php'; + $title = __('Import'); + + if (! isset($_GET['noheader'])) + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + + define('WP_IMPORTING', true); + + if ( apply_filters( 'force_filtered_html_on_import', false ) ) + kses_init_filters(); // Always filter imported data with kses on multisite. + + call_user_func($wp_importers[$importer][2]); + + include(ABSPATH . 'wp-admin/admin-footer.php'); + + // Make sure rules are flushed + global $wp_rewrite; + $wp_rewrite->flush_rules(false); + + exit(); +} else { + do_action("load-$pagenow"); + // Backwards compatibility with old load-page-new.php, load-page.php, + // and load-categories.php actions. + if ( $typenow == 'page' ) { + if ( $pagenow == 'post-new.php' ) + do_action( 'load-page-new.php' ); + elseif ( $pagenow == 'post.php' ) + do_action( 'load-page.php' ); + } elseif ( $pagenow == 'edit-tags.php' ) { + if ( $taxnow == 'category' ) + do_action( 'load-categories.php' ); + elseif ( $taxnow == 'link_category' ) + do_action( 'load-edit-link-categories.php' ); + } +} + +if ( !empty($_REQUEST['action']) ) + do_action('admin_action_' . $_REQUEST['action']); + +?> diff --git a/src/wp-admin/async-upload.php b/src/wp-admin/async-upload.php new file mode 100644 index 00000000..6fa65181 --- /dev/null +++ b/src/wp-admin/async-upload.php @@ -0,0 +1,70 @@ +post_type ) + wp_die( __( 'Unknown post type.' ) ); + $post_type_object = get_post_type_object( 'attachment' ); + if ( ! current_user_can( $post_type_object->cap->edit_post, $id ) ) + wp_die( __( 'You are not allowed to edit this item.' ) ); + + if ( 2 == $_REQUEST['fetch'] ) { + add_filter('attachment_fields_to_edit', 'media_single_attachment_fields_to_edit', 10, 2); + echo get_media_item($id, array( 'send' => false, 'delete' => true )); + } else { + add_filter('attachment_fields_to_edit', 'media_post_single_attachment_fields_to_edit', 10, 2); + echo get_media_item($id); + } + exit; +} + +check_admin_referer('media-form'); + +$id = media_handle_upload('async-upload', $_REQUEST['post_id']); +if ( is_wp_error($id) ) { + echo '
+ ' . __('Dismiss') . ' + ' . sprintf(__('“%s” has failed to upload due to an error'), esc_html($_FILES['async-upload']['name']) ) . '
' . + esc_html($id->get_error_message()) . '
'; + exit; +} + +if ( $_REQUEST['short'] ) { + // short form response - attachment ID only + echo $id; +} else { + // long form response - big chunk o html + $type = $_REQUEST['type']; + echo apply_filters("async_upload_{$type}", $id); +} + +?> diff --git a/src/wp-admin/comment.php b/src/wp-admin/comment.php new file mode 100644 index 00000000..3e6245e3 --- /dev/null +++ b/src/wp-admin/comment.php @@ -0,0 +1,289 @@ +

$msg

"; + include('./admin-footer.php'); + die; +} + +switch( $action ) { + +case 'editcomment' : + $title = __('Edit Comment'); + + add_contextual_help( $current_screen, '

' . __( 'You can edit the information left in a comment if needed. This is often useful when you notice that a commenter has made a typographical error.' ) . '

' . + '

' . __( 'You can also moderate the comment from this screen using the Status box, where you can also change the timestamp of the comment.' ) . '

' . + '

' . __( 'For more information:' ) . '

' . + '

' . __( 'Documentation on Comments' ) . '

' . + '

' . __( 'Support Forums' ) . '

' + ); + + wp_enqueue_script('comment'); + require_once('./admin-header.php'); + + $comment_id = absint( $_GET['c'] ); + + if ( !$comment = get_comment( $comment_id ) ) + comment_footer_die( __('Oops, no comment with this ID.') . sprintf(' '.__('Go back').'!', 'javascript:history.go(-1)') ); + + if ( !current_user_can( 'edit_comment', $comment_id ) ) + comment_footer_die( __('You are not allowed to edit this comment.') ); + + if ( 'trash' == $comment->comment_approved ) + comment_footer_die( __('This comment is in the Trash. Please move it out of the Trash if you want to edit it.') ); + + $comment = get_comment_to_edit( $comment_id ); + + include('./edit-form-comment.php'); + + break; + +case 'delete' : +case 'approve' : +case 'trash' : +case 'spam' : + + $title = __('Moderate Comment'); + + $comment_id = absint( $_GET['c'] ); + + if ( !$comment = get_comment_to_edit( $comment_id ) ) { + wp_redirect( admin_url('edit-comments.php?error=1') ); + die(); + } + + if ( !current_user_can( 'edit_comment', $comment->comment_ID ) ) { + wp_redirect( admin_url('edit-comments.php?error=2') ); + die(); + } + + // No need to re-approve/re-trash/re-spam a comment. + if ( $action == str_replace( '1', 'approve', $comment->comment_approved ) ) { + wp_redirect( admin_url( 'edit-comments.php?same=' . $comment_id ) ); + die(); + } + + require_once('./admin-header.php'); + + $formaction = $action . 'comment'; + $nonce_action = 'approve' == $action ? 'approve-comment_' : 'delete-comment_'; + $nonce_action .= $comment_id; + +?> +
+ +
+ + +

+ +comment_approved != '0' ) { // if not unapproved + $message = ''; + switch ( $comment->comment_approved ) { + case '1' : + $message = __('This comment is currently approved.'); + break; + case 'spam' : + $message = __('This comment is currently marked as spam.'); + break; + case 'trash' : + $message = __('This comment is currently in the Trash.'); + break; + } + if ( $message ) + echo '

' . $message . '

'; +} +?> +

+ + + + + + +comment_author_email ) { ?> + + + + + +comment_author_url ) { ?> + + + + + + + + + +
comment_author; ?>
comment_author_email; ?>
comment_author_url; ?>
comment_content; ?>
+ +

+ +
+ + + + + + +
+ + + + + +
+ +
+
+'.__('Go back').'!', 'edit-comments.php') ); + if ( !current_user_can( 'edit_comment', $comment->comment_ID ) ) + comment_footer_die( __('You are not allowed to edit comments on this post.') ); + + if ( '' != wp_get_referer() && ! $noredir && false === strpos(wp_get_referer(), 'comment.php') ) + $redir = wp_get_referer(); + elseif ( '' != wp_get_original_referer() && ! $noredir ) + $redir = wp_get_original_referer(); + elseif ( in_array( $action, array( 'approvecomment', 'unapprovecomment' ) ) ) + $redir = admin_url('edit-comments.php?p=' . absint( $comment->comment_post_ID ) ); + else + $redir = admin_url('edit-comments.php'); + + $redir = remove_query_arg( array('spammed', 'unspammed', 'trashed', 'untrashed', 'deleted', 'ids', 'approved', 'unapproved'), $redir ); + + switch ( $action ) { + case 'deletecomment' : + wp_delete_comment( $comment_id ); + $redir = add_query_arg( array('deleted' => '1'), $redir ); + break; + case 'trashcomment' : + wp_trash_comment($comment_id); + $redir = add_query_arg( array('trashed' => '1', 'ids' => $comment_id), $redir ); + break; + case 'untrashcomment' : + wp_untrash_comment($comment_id); + $redir = add_query_arg( array('untrashed' => '1'), $redir ); + break; + case 'spamcomment' : + wp_spam_comment($comment_id); + $redir = add_query_arg( array('spammed' => '1', 'ids' => $comment_id), $redir ); + break; + case 'unspamcomment' : + wp_unspam_comment($comment_id); + $redir = add_query_arg( array('unspammed' => '1'), $redir ); + break; + case 'approvecomment' : + wp_set_comment_status( $comment_id, 'approve' ); + $redir = add_query_arg( array( 'approved' => 1 ), $redir ); + break; + case 'unapprovecomment' : + wp_set_comment_status( $comment_id, 'hold' ); + $redir = add_query_arg( array( 'unapproved' => 1 ), $redir ); + break; + } + + wp_redirect( $redir ); + die; + break; + +case 'editedcomment' : + + $comment_id = absint( $_POST['comment_ID'] ); + $comment_post_id = absint( $_POST['comment_post_ID'] ); + + check_admin_referer( 'update-comment_' . $comment_id ); + + edit_comment(); + + $location = ( empty( $_POST['referredby'] ) ? "edit-comments.php?p=$comment_post_id" : $_POST['referredby'] ) . '#comment-' . $comment_id; + $location = apply_filters( 'comment_edit_redirect', $location, $comment_id ); + wp_redirect( $location ); + + exit(); + break; + +default: + wp_die( __('Unknown action.') ); + break; + +} // end switch + +include('./admin-footer.php'); + +?> diff --git a/src/wp-admin/css/colors-classic-rtl.css b/src/wp-admin/css/colors-classic-rtl.css new file mode 100644 index 00000000..e50945a5 --- /dev/null +++ b/src/wp-admin/css/colors-classic-rtl.css @@ -0,0 +1 @@ +.bar{border-right-color:transparent;border-left-color:#99d;}.plugins .togl{border-right-color:transparent;border-left-color:#ccc;}.post-com-count{background-image:url(../images/bubble_bg-rtl.gif);}.tablenav .tablenav-pages a{background:#eee url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -379px;}#upload-menu li.current{border-right-color:transparent;border-left-color:#448abd;}#adminmenu .wp-submenu .current a.current{background:transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat scroll right -289px;}#adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px;}.folded #adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px;}#adminmenu li.wp-has-current-submenu .wp-menu-toggle,#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle{background:transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -207px;}#adminmenu .wp-has-current-submenu ul li a.current{background:url(../images/menu-dark-rtl-vs.gif) top right no-repeat!important;}#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu,#adminmenu .menu-top .current{background:url(../images/menu-bits-rtl-vs.gif?ver=20101117) top right repeat-x;}#adminmenu li.wp-has-current-submenu ul li a{background:url(../images/menu-dark-rtl-vs.gif) bottom right no-repeat!important;}#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle,#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle{background:transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat right -207px;}#adminmenu .wp-has-submenu:hover .wp-menu-toggle,#adminmenu .wp-menu-open .wp-menu-toggle{background:transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -109px;}#adminmenu a.wp-has-submenu{background:#eff8ff url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -379px;}#adminmenu .wp-submenu a{background:#fff url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat scroll right -99px;}#adminmenu li.wp-has-current-submenu a.wp-has-submenu{background:#b5b5b5 url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right top;}.meta-box-sortables .postbox:hover .handlediv{background:transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat scroll right -111px;}#favorite-toggle{background:transparent url(../images/fav-arrow-rtl.gif?ver=20100531) no-repeat right -4px;} \ No newline at end of file diff --git a/src/wp-admin/css/colors-classic-rtl.dev.css b/src/wp-admin/css/colors-classic-rtl.dev.css new file mode 100644 index 00000000..f88d9785 --- /dev/null +++ b/src/wp-admin/css/colors-classic-rtl.dev.css @@ -0,0 +1,78 @@ +.bar { + border-right-color: transparent; + border-left-color: #99d; +} + +.plugins .togl { + border-right-color: transparent; + border-left-color: #ccc; +} + +.post-com-count { + background-image: url(../images/bubble_bg-rtl.gif); +} +.tablenav .tablenav-pages a { + background: #eee url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -379px; +} +#upload-menu li.current { + border-right-color: transparent; + border-left-color: #448abd; +} + +#adminmenu .wp-submenu .current a.current { + background: transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat scroll right -289px; +} + +#adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px; +} + +.folded #adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px; +} + +#adminmenu li.wp-has-current-submenu .wp-menu-toggle, +#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle { + background: transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -207px; +} + +#adminmenu .wp-has-current-submenu ul li a.current { + background: url(../images/menu-dark-rtl-vs.gif) top right no-repeat !important; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu, +#adminmenu .menu-top .current { + background: url(../images/menu-bits-rtl-vs.gif?ver=20101117) top right repeat-x; +} + +#adminmenu li.wp-has-current-submenu ul li a { + background: url(../images/menu-dark-rtl-vs.gif) bottom right no-repeat !important; +} + +#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle, #adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle { + background: transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat right -207px; +} + +#adminmenu .wp-has-submenu:hover .wp-menu-toggle, +#adminmenu .wp-menu-open .wp-menu-toggle { + background: transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -109px; +} + +#adminmenu a.wp-has-submenu { + background: #eff8ff url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right -379px; +} + +#adminmenu .wp-submenu a { + background: #fff url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat scroll right -99px; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-submenu { + background: #b5b5b5 url(../images/menu-bits-rtl-vs.gif?ver=20101117) repeat-x scroll right top; +} + +.meta-box-sortables .postbox:hover .handlediv { + background: transparent url(../images/menu-bits-rtl-vs.gif?ver=20101117) no-repeat scroll right -111px; +} +#favorite-toggle { + background: transparent url(../images/fav-arrow-rtl.gif?ver=20100531) no-repeat right -4px; +} diff --git a/src/wp-admin/css/colors-classic.css b/src/wp-admin/css/colors-classic.css new file mode 100644 index 00000000..5383c296 --- /dev/null +++ b/src/wp-admin/css/colors-classic.css @@ -0,0 +1 @@ +html,.wp-dialog{background-color:#fcfcfb;}* html input,* html .widget{border-color:#dfdfdf;}textarea,input[type="text"],input[type="password"],input[type="file"],input[type="button"],input[type="submit"],input[type="reset"],select{border-color:#dfdfdf;background-color:#fff;}kbd,code{background:#eaeaea;}input[readonly]{background-color:#eee;}.find-box-search{border-color:#dfdfdf;background-color:#f1f1f1;}.find-box{background-color:#f1f1f1;}.find-box-inside{background-color:#fff;}a.page-numbers:hover{border-color:#999;}body,#wpbody,.form-table .pre{color:#174f69;}body>#upload-menu{border-bottom-color:#fff;}#postcustomstuff table,#your-profile fieldset,#rightnow,div.dashboard-widget,#dashboard-widgets p.dashboard-widget-links,#replyrow #ed_reply_toolbar input{border-color:#D1E5EE;}#poststuff .inside label.spam,#poststuff .inside label.deleted{color:red;}#poststuff .inside label.waiting{color:orange;}#poststuff .inside label.approved{color:green;}#postcustomstuff table{border-color:#dfdfdf;background-color:#F9F9F9;}#postcustomstuff thead th{background-color:#F1F1F1;}#postcustomstuff table input,#postcustomstuff table textarea{border-color:#dfdfdf;background-color:#fff;}.widefat{border-color:#D1E5EE;background-color:#fff;}div.dashboard-widget-error{background-color:#c43;}div.dashboard-widget-notice{background-color:#cfe1ef;}div.dashboard-widget-submit{border-top-color:#ccc;}div.tabs-panel,.wp-tab-panel,ul.category-tabs li.tabs,ul.add-menu-item-tabs li.tabs,.wp-tab-active{border-color:#dfdfdf;}ul.category-tabs li.tabs,ul.add-menu-item-tabs li.tabs,.wp-tab-active{background-color:#f1f1f1;}input.disabled,textarea.disabled{background-color:#ccc;}#plugin-information .action-button a,#plugin-information .action-button a:hover,#plugin-information .action-button a:visited{color:#fff;}.widget .widget-top,.postbox h3,.stuffbox h3{background:#cfdfe9 url("../images/blue-grad.png?ver=20101102") repeat-x left top;text-shadow:#fff 0 1px 0;}.form-table th,.form-wrap label{color:#222;text-shadow:#fff 0 1px 0;}.description,.form-wrap p{color:#666;}strong .post-com-count span{background-color:#21759b;}.sorthelper{background-color:#ccf3fa;}.ac_match,.subsubsub a.current{color:#000;}.wrap h2{color:#174f69;}.ac_over{background-color:#f0f0b8;}.ac_results{background-color:#fff;border-color:#808080;}.ac_results li{color:#101010;}.alternate,.alt{background-color:#F8F7F3;}.available-theme a.screenshot{background-color:#f1f1f1;border-color:#ddd;}.bar{background-color:#e8e8e8;border-right-color:#99d;}#media-upload,#media-upload .media-item .slidetoggle{background:#fff;}#media-upload .slidetoggle{border-top-color:#dfdfdf;}div.error,.login #login_error{background-color:#ffebe8;border-color:#c00;}div.error a{color:#c00;}.form-invalid{background-color:#ffebe8!important;}.form-invalid input,.form-invalid select{border-color:#c00!important;}.submit{border-color:#DFDFDF;}.highlight{background-color:#e4f2fd;color:#000;}.howto,.nonessential,#edit-slug-box,.form-input-tip,.rss-widget span.rss-date,.subsubsub{color:#666;}.media-item{border-bottom-color:#dfdfdf;}#wpbody-content #media-items .describe{border-top-color:#dfdfdf;}.media-upload-form label.form-help,td.help{color:#9a9a9a;}.post-com-count{background-image:url(../images/bubble_bg.gif);color:#fff;}.post-com-count span{background-color:#bbb;color:#fff;}.post-com-count:hover span{background-color:#d54e21;}.quicktags,.search{background-color:#ccc;color:#000;}.side-info h5{border-bottom-color:#dadada;}.side-info ul{color:#666;}.button,.button-secondary,.submit input,input[type=button],input[type=submit]{border-color:#bbb;color:#464646;}.button:hover,.button-secondary:hover,.submit input:hover,input[type=button]:hover,input[type=submit]:hover{color:#000;border-color:#666;}.button,.submit input,.button-secondary{background:#f2f2f2 url(../images/white-grad.png) repeat-x scroll left top;text-shadow:rgba(255,255,255,1) 0 1px 0;}.button:active,.submit input:active,.button-secondary:active{background:#eee url(../images/white-grad-active.png) repeat-x scroll left top;}input.button-primary,button.button-primary,a.button-primary{border-color:#298cba;font-weight:bold;color:#fff;background:#21759B url(../images/button-grad.png) repeat-x scroll left top;text-shadow:rgba(0,0,0,0.3) 0 -1px 0;}input.button-primary:active,button.button-primary:active,a.button-primary:active{background:#21759b url(../images/button-grad-active.png) repeat-x scroll left top;color:#eaf2fa;}input.button-primary:hover,button.button-primary:hover,a.button-primary:hover,a.button-primary:focus,a.button-primary:active{border-color:#13455b;color:#eaf2fa;}.button-disabled,.button[disabled],.button:disabled,.button-secondary[disabled],.button-secondary:disabled,a.button.disabled{color:#aaa!important;border-color:#ddd!important;}.button-primary-disabled,.button-primary[disabled],.button-primary:disabled{color:#9FD0D5!important;background:#298CBA!important;}a:hover,a:active,a:focus{color:#d54e21;}#wphead #viewsite a:hover,#adminmenu a:hover,#adminmenu ul.wp-submenu a:hover,#the-comment-list .comment a:hover,#rightnow a:hover,#media-upload a.del-link:hover,div.dashboard-widget-submit input:hover,.subsubsub a:hover,.subsubsub a.current:hover,.ui-tabs-nav a:hover,.plugins .inactive a:hover,#all-plugins-table .plugins .inactive a:hover,#search-plugins-table .plugins .inactive a:hover{color:#d54e21;}#the-comment-list .comment-item,#dashboard-widgets #dashboard_quick_press form p.submit{border-color:#dfdfdf;}#side-sortables .category-tabs .tabs a,#side-sortables .add-menu-item-tabs .tabs a,.wp-tab-bar .wp-tab-active a{color:#333;}#rightnow .rbutton{background-color:#ebebeb;color:#264761;}.submitbox .submit{background-color:#464646;color:#ccc;}.plugins a.delete:hover,#all-plugins-table .plugins a.delete:hover,#search-plugins-table .plugins a.delete:hover,.submitbox .submitdelete{color:#f00;border-bottom-color:#f00;}.submitbox .submitdelete:hover,#media-items a.delete:hover{color:#fff;background-color:#f00;border-bottom-color:#f00;}#normal-sortables .submitbox .submitdelete:hover{color:#000;background-color:#f00;border-bottom-color:#f00;}.tablenav .dots{border-color:transparent;}.tablenav .next,.tablenav .prev{border-color:transparent;color:#21759b;}.tablenav .next:hover,.tablenav .prev:hover{border-color:transparent;color:#d54e21;}div.updated,.login .message{background-color:#ffffe0;border-color:#e6db55;}.update-message{color:#000;}a.page-numbers{border-bottom-color:#B8D3E2;}.commentlist li{border-bottom-color:#ccc;}.widefat td,.widefat th{border-color:#dfdfdf;}.widefat th{text-shadow:rgba(255,255,255,0.8) 0 1px 0;}.widefat thead tr th,.widefat tfoot tr th,h3.dashboard-widget-title,h3.dashboard-widget-title span,h3.dashboard-widget-title small,.find-box-head{color:#333;background:#cfdfe9 url(../images/blue-grad.png?ver=20101102) repeat-x scroll left top;}th.sortable a:hover,th.sortable a:active,th.sortable a:focus{color:#333;}h3.dashboard-widget-title small a{color:#d7d7d7;}h3.dashboard-widget-title small a:hover{color:#fff;}a,#adminmenu a,#poststuff #edButtonPreview,#poststuff #edButtonHTML,#the-comment-list p.comment-author strong a,#media-upload a.del-link,#media-items a.delete,.plugins a.delete,.ui-tabs-nav a{color:#21759b;}#adminmenu #awaiting-mod,#adminmenu .update-plugins,#sidemenu a .update-plugins,#rightnow .reallynow{background-color:#464646;color:#fff;-moz-box-shadow:#fff 0 -1px 0;-khtml-box-shadow:#fff 0 -1px 0;-webkit-box-shadow:#fff 0 -1px 0;box-shadow:#fff 0 -1px 0;}#plugin-information .action-button{background-color:#d54e21;color:#fff;}#adminmenu li.current a #awaiting-mod,#adminmenu li a.wp-has-current-submenu .update-plugins{background-color:#464646;color:#fff;-moz-box-shadow:#fff 0 -1px 0;-khtml-box-shadow:#fff 0 -1px 0;-webkit-box-shadow:#fff 0 -1px 0;box-shadow:#fff 0 -1px 0;}div#media-upload-header,div#plugin-information-header{background-color:#f9f9f9;border-bottom-color:#dfdfdf;}#currenttheme img{border-color:#666;}#dashboard_secondary div.dashboard-widget-content ul li a{background-color:#f9f9f9;}input.readonly,textarea.readonly{background-color:#ddd;}#ed_toolbar input,#ed_reply_toolbar input{background:#fff url("../images/fade-butt.png") repeat-x 0 -2px;}#editable-post-name{background-color:#fffbcc;}#edit-slug-box strong,.tablenav .displaying-num,#submitted-on,.submitted-on{color:#777;}.login #nav a{color:#21759b!important;}.login #nav a:hover{color:#d54e21!important;}#footer{color:#777;border-color:#b0c8d7;background:#cfdfe9;background:-moz-linear-gradient(bottom,#cfdfe9,#eff8ff);background:-webkit-gradient(linear,left bottom,left top,from(#cfdfe9),to(#eff8ff));}#media-items,.imgedit-group{border-color:#dfdfdf;}.checkbox,.side-info,.plugins tr,#your-profile #rich_editing{background-color:#fff;}.plugins .inactive,.plugins .inactive th,.plugins .inactive td,tr.inactive+tr.plugin-update-tr .plugin-update{background-color:#efede7;}.plugin-update-tr .update-message{background-color:#fffbe4;border-color:#dfdfdf;}.plugins .active,.plugins .active th,.plugins .active td{color:#000;}.plugins .inactive a{color:#579;}#the-comment-list tr.undo,#the-comment-list div.undo{background-color:#f4f4f4;}#the-comment-list .unapproved{background-color:#ffffe0;}#the-comment-list .approve a{color:#006505;}#the-comment-list .unapprove a{color:#d98500;}table.widefat span.delete a,table.widefat span.trash a,table.widefat span.spam a,#dashboard_recent_comments .delete a,#dashboard_recent_comments .trash a,#dashboard_recent_comments .spam a{color:#bc0b0b;}.widget,#widget-list .widget-top,.postbox,#titlediv,#poststuff .postarea,.stuffbox{border-color:#D1E5EE;}.widget,.postbox{background-color:#fff;}.ui-sortable .postbox h3{color:#174f69;}.widget .widget-top,.ui-sortable .postbox h3:hover{color:#174f69;}.curtime #timestamp{background-image:url(../images/date-button.gif);}#quicktags #ed_link{color:#00f;}#rightnow .youhave{background-color:#f0f6fb;}#rightnow a{color:#448abd;}.tagchecklist span a,#bulk-titles div a{background:url(../images/xit.gif) no-repeat;}.tagchecklist span a:hover,#bulk-titles div a:hover{background:url(../images/xit.gif) no-repeat -10px 0;}#update-nag,.update-nag{background-color:#FFFBCC;border-color:#E6DB55;color:#555;}.login #backtoblog a{color:#464646;}#wphead{border-bottom:#b0c8d7 1px solid;background:#cfdfe9;background:-moz-linear-gradient(bottom,#cfdfe9,#eff8ff);background:-webkit-gradient(linear,left bottom,left top,from(#cfdfe9),to(#eff8ff));}#wphead h1 a{color:#174f69;}#user_info{color:#777;}#user_info a:link,#user_info a:visited,#footer a:link,#footer a:visited{color:#174f69;text-decoration:none;}#user_info a:hover,#footer a:hover{color:#000;text-decoration:underline!important;}div#media-upload-error,.file-error,abbr.required,.widget-control-remove:hover,table.widefat .delete a:hover,table.widefat .trash a:hover,table.widefat .spam a:hover,#dashboard_recent_comments .delete a:hover,#dashboard_recent_comments .trash a:hover #dashboard_recent_comments .spam a:hover{color:#f00;}#pass-strength-result{background-color:#eee;border-color:#ddd!important;}#pass-strength-result.bad{background-color:#ffb78c;border-color:#ff853c!important;}#pass-strength-result.good{background-color:#ffec8b;border-color:#fc0!important;}#pass-strength-result.short{background-color:#ffa0a0;border-color:#f04040!important;}#pass-strength-result.strong{background-color:#c3ff88;border-color:#8dff1c!important;}#quicktags{border-color:#cfdfe9;background-color:#cfdfe9;background-image:url("../images/ed-bg-vs.gif?ver=20101102");}#ed_toolbar input{border-color:#C3C3C3;}#ed_toolbar input:hover{border-color:#aaa;background:#ddd;}#poststuff .wp_themeSkin .mceStatusbar{border-color:#EDEDED;}#poststuff #edButtonPreview,#poststuff #edButtonHTML{background-color:#eff8ff;border-color:#D1E5EE;color:#999;}#poststuff #editor-toolbar .active{border-bottom-color:#eff8ff;background-color:#eff8ff;color:#333;}#post-status-info{background-color:#eff8ff;}.wp_themeSkin *,.wp_themeSkin a:hover,.wp_themeSkin a:link,.wp_themeSkin a:visited,.wp_themeSkin a:active{color:#000;}.wp_themeSkin iframe{background:#fff;}.wp_themeSkin .mceStatusbar{color:#000;background-color:#f5f5f5;}.wp_themeSkin .mceButton{background-color:#e9e8e8;border-color:#B2B2B2;}.wp_themeSkin a.mceButtonEnabled:hover,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonSelected{background:#d5d5d5;border-color:#777!important;}.wp_themeSkin .mceButtonDisabled{border-color:#ccc!important;}.wp_themeSkin .mceListBox .mceText,.wp_themeSkin .mceListBox .mceOpen{border-color:#B2B2B2;background-color:#d5d5d5;}.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen,.wp_themeSkin .mceListBoxSelected .mceText{border-color:#777!important;background-color:#d5d5d5;}.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText{border-color:#777!important;}.wp_themeSkin select.mceListBox{border-color:#B2B2B2;background-color:#fff;}.wp_themeSkin .mceSplitButton a.mceAction,.wp_themeSkin .mceSplitButton a.mceOpen{border-color:#B2B2B2;}.wp_themeSkin .mceSplitButton a.mceOpen:hover,.wp_themeSkin .mceSplitButtonSelected a.mceOpen,.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction,.wp_themeSkin .mceSplitButton a.mceAction:hover{background-color:#d5d5d5;border-color:#777!important;}.wp_themeSkin .mceSplitButtonActive{background-color:#B2B2B2;}.wp_themeSkin div.mceColorSplitMenu table{background-color:#ebebeb;border-color:#B2B2B2;}.wp_themeSkin .mceColorSplitMenu a{border-color:#B2B2B2;}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors{border-color:#fff;}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover{border-color:#0A246A;background-color:#B6BDD2;}.wp_themeSkin a.mceMoreColors:hover{border-color:#0A246A;}.wp_themeSkin .mceMenu{border-color:#ddd;}.wp_themeSkin .mceMenu table{background-color:#ebeaeb;}.wp_themeSkin .mceMenu .mceText{color:#000;}.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover,.wp_themeSkin .mceMenu .mceMenuItemActive{background-color:#f5f5f5;}.wp_themeSkin td.mceMenuItemSeparator{background-color:#aaa;}.wp_themeSkin .mceMenuItemTitle a{background-color:#ccc;border-bottom-color:#aaa;}.wp_themeSkin .mceMenuItemTitle span.mceText{color:#000;}.wp_themeSkin .mceMenuItemDisabled .mceText{color:#888;}.wp_themeSkin tr.mceFirst td.mceToolbar{background:#cfdfe9 url("../images/ed-bg-vs.gif?ver=20101102") repeat-x scroll left top;border-color:#cfdfe9;}.wp-admin #mceModalBlocker{background:#000;}.wp-admin .clearlooks2 .mceFocus .mceTop .mceLeft{background:#444;border-left:1px solid #999;border-top:1px solid #999;-moz-border-radius:4px 0 0 0;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px;}.wp-admin .clearlooks2 .mceFocus .mceTop .mceRight{background:#444;border-right:1px solid #999;border-top:1px solid #999;border-top-right-radius:4px;-khtml-border-top-right-radius:4px;-webkit-border-top-right-radius:4px;-moz-border-radius:0 4px 0 0;}.wp-admin .clearlooks2 .mceMiddle .mceLeft{background:#f1f1f1;border-left:1px solid #999;}.wp-admin .clearlooks2 .mceMiddle .mceRight{background:#f1f1f1;border-right:1px solid #999;}.wp-admin .clearlooks2 .mceBottom{background:#f1f1f1;border-bottom:1px solid #999;}.wp-admin .clearlooks2 .mceBottom .mceLeft{background:#f1f1f1;border-bottom:1px solid #999;border-left:1px solid #999;}.wp-admin .clearlooks2 .mceBottom .mceCenter{background:#f1f1f1;border-bottom:1px solid #999;}.wp-admin .clearlooks2 .mceBottom .mceRight{background:#f1f1f1;border-bottom:1px solid #999;border-right:1px solid #999;}.wp-admin .clearlooks2 .mceFocus .mceTop span{color:#e5e5e5;}#editorcontainer,#post-status-info,#titlediv #title,.editwidget .widget-inside{border-color:#D1E5EE;}#titlediv #title{background-color:#fff;}#tTips p#tTips_inside{background-color:#ddd;color:#333;}#timestampdiv input,#namediv input,#poststuff .inside .the-tagcloud{border-color:#ddd;}#adminmenu *{border-color:#d1e5ee;}#adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px;}.folded #adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px;}#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle,#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle{background:transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -207px;}#adminmenu .wp-has-submenu:hover .wp-menu-toggle,#adminmenu .wp-menu-open .wp-menu-toggle{background:transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -109px;}#adminmenu a.menu-top{background:#eff8ff url(../images/menu-bits-vs.gif?ver=20101102) repeat-x scroll left -379px;}#adminmenu .wp-submenu a{background:#fff url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll 0 -99px;}#adminmenu .wp-has-current-submenu ul li a{background:none;}#adminmenu .wp-has-current-submenu ul li a.current{background:url(../images/menu-dark-vs.gif) top left no-repeat!important;}.wp-has-current-submenu .wp-submenu{border-top:none!important;}#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu{border-bottom:#aaa 1px solid;}#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu,#adminmenu li.current a.menu-top{background:#d0dfe9 url(../images/menu-bits-vs.gif?ver=20101102) top left repeat-x;border:#5589aa 1px solid;color:#464646;}#adminmenu li.wp-has-current-submenu .wp-submenu,#adminmenu li.wp-has-current-submenu ul li a{border-right-color:#5589aa!important;border-left-color:#5589aa!important;}#adminmenu li.wp-has-current-submenu ul li a{background:url(../images/menu-dark-vs.gif) bottom left no-repeat!important;}#adminmenu li.wp-has-current-submenu ul{border-bottom-color:#5589aa;}#adminmenu .wp-submenu .current a.current{background:transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll 0 -289px;}#adminmenu .wp-submenu a:hover{background-color:#f8f7f3!important;color:#333!important;}#adminmenu .wp-submenu li.current,#adminmenu .wp-submenu li.current a,#adminmenu .wp-submenu li.current a:hover{color:#333;background-color:#efede7;background-image:none;border-color:#5589aa;}#adminmenu .wp-submenu ul{background-color:#fff;}.folded #adminmenu li.menu-top,#adminmenu .wp-submenu .wp-submenu-head{background:#eff8ff url(../images/menu-bits-vs.gif?ver=20101102) repeat-x scroll left -379px;}.folded #adminmenu li.wp-has-current-submenu,.folded #adminmenu li.menu-top.current{background:#e0e0e0 url(../images/menu-bits-vs.gif?ver=20101102) top left repeat-x;border:#5589aa 1px solid;color:#464646;}#adminmenu .wp-has-current-submenu .wp-submenu .wp-submenu-head{background:#d0dfe9 url(../images/menu-bits-vs.gif?ver=20101102) repeat-x 0 0;border:1px solid;color:#464646;}#adminmenu div.wp-submenu{background-color:transparent;}#adminmenu .menu-icon-dashboard div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -61px -33px;}#adminmenu .menu-icon-dashboard:hover div.wp-menu-image,#adminmenu .menu-icon-dashboard.wp-has-current-submenu div.wp-menu-image,#adminmenu .menu-icon-dashboard.current div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -61px -1px;}#adminmenu .menu-icon-post div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -272px -33px;}#adminmenu .menu-icon-post:hover div.wp-menu-image,#adminmenu .menu-icon-post.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -272px -1px;}#adminmenu .menu-icon-media div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -121px -33px;}#adminmenu .menu-icon-media:hover div.wp-menu-image,#adminmenu .menu-icon-media.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -121px -1px;}#adminmenu .menu-icon-links div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -91px -33px;}#adminmenu .menu-icon-links:hover div.wp-menu-image,#adminmenu .menu-icon-links.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -91px -1px;}#adminmenu .menu-icon-page div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -151px -33px;}#adminmenu .menu-icon-page:hover div.wp-menu-image,#adminmenu .menu-icon-page.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -151px -1px;}#adminmenu .menu-icon-comments div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -31px -33px;}#adminmenu .menu-icon-comments:hover div.wp-menu-image,#adminmenu .menu-icon-comments.wp-has-current-submenu div.wp-menu-image,#adminmenu .menu-icon-comments.current div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -31px -1px;}#adminmenu .menu-icon-appearance div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -1px -33px;}#adminmenu .menu-icon-appearance:hover div.wp-menu-image,#adminmenu .menu-icon-appearance.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -1px -1px;}#adminmenu .menu-icon-plugins div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -181px -33px;}#adminmenu .menu-icon-plugins:hover div.wp-menu-image,#adminmenu .menu-icon-plugins.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -181px -1px;}#adminmenu .menu-icon-users div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -301px -33px;}#adminmenu .menu-icon-users:hover div.wp-menu-image,#adminmenu .menu-icon-users.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -301px -1px;}#adminmenu .menu-icon-tools div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -211px -33px;}#adminmenu .menu-icon-tools:hover div.wp-menu-image,#adminmenu .menu-icon-tools.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -211px -1px;}#adminmenu .menu-icon-settings div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -241px -33px;}#adminmenu .menu-icon-settings:hover div.wp-menu-image,#adminmenu .menu-icon-settings.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -241px -1px;}#adminmenu .menu-icon-site div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -361px -33px;}#adminmenu .menu-icon-site:hover div.wp-menu-image,#adminmenu .menu-icon-site.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -361px -1px;}table.diff .diff-deletedline{background-color:#fdd;}table.diff .diff-deletedline del{background-color:#f99;}table.diff .diff-addedline{background-color:#dfd;}table.diff .diff-addedline ins{background-color:#9f9;}#att-info{background-color:#E4F2FD;}#sidemenu a{background-color:#f9f9f9;border-color:#f9f9f9;border-bottom-color:#dfdfdf;}#sidemenu a.current{background-color:#fff;border-color:#dfdfdf #dfdfdf #fff;color:#D54E21;}#screen-options-wrap,#contextual-help-wrap{background-color:#F8F7F3;border-color:#D1e5ee;}#screen-meta-links a.show-settings{color:#606060;}#screen-meta-links a.show-settings:hover{color:#000;}#replysubmit{background-color:#f1f1f1;border-top-color:#ddd;}#replyerror{border-color:#ddd;background-color:#f9f9f9;}#edithead,#replyhead{background-color:#f1f1f1;}#ed_reply_toolbar{background-color:#e9e9e9;}.vim-current,.vim-current th,.vim-current td{background-color:#E4F2FD!important;}.star-average,.star.star-rating{background-color:#fc0;}div.star.select:hover{background-color:#d00;}#plugin-information .fyi ul{background-color:#eaf3fa;}#plugin-information .fyi h2.mainheader{background-color:#cee1ef;}#plugin-information pre,#plugin-information code{background-color:#ededff;}#plugin-information pre{border:1px solid #ccc;}.inline-edit-row fieldset input[type="text"],.inline-edit-row fieldset textarea,#bulk-titles,#replyrow input{border-color:#ddd;}.inline-editor div.title{background-color:#EAF3FA;}.inline-editor ul.cat-checklist{background-color:#fff;border-color:#ddd;}.inline-editor .categories .catshow,.inline-editor .categories .cathide{color:#21759b;}.inline-editor .quick-edit-save{background-color:#f1f1f1;}#replyrow #ed_reply_toolbar input:hover{border-color:#aaa;background:#ddd;}fieldset.inline-edit-col-right .inline-edit-col{border-color:#dfdfdf;}.attention{color:#D54E21;}body.press-this .postbox:hover .handlediv,body.press-this .stuffbox:hover .handlediv,.meta-box-sortables .postbox:hover .handlediv{background:transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -111px;}#major-publishing-actions{background:#eaf2fa;}.tablenav .tablenav-pages{color:#555;}.tablenav .tablenav-pages a{border-color:#d1e5ee;background:#eee url('../images/menu-bits-vs.gif?ver=20101102') repeat-x scroll left -379px;}.tablenav .tablenav-pages a:hover,.tablenav .tablenav-pages a:focus{color:#d54e21;}.tablenav .tablenav-pages a.disabled,.tablenav .tablenav-pages a.disabled:hover,.tablenav .tablenav-pages a.disabled:focus{color:#aaa;}.tablenav .tablenav-pages .current{background:#dfdfdf;border-color:#d3d3d3;}#availablethemes,#availablethemes td{border-color:#ddd;}#current-theme img{border-color:#999;}#TB_window #TB_title a.tb-theme-preview-link,#TB_window #TB_title a.tb-theme-preview-link:visited{color:#999;}#TB_window #TB_title a.tb-theme-preview-link:hover,#TB_window #TB_title a.tb-theme-preview-link:focus{color:#ccc;}.misc-pub-section{border-bottom-color:#eee;}#minor-publishing{border-bottom-color:#ddd;}#post-body .misc-pub-section{border-right-color:#eee;}.post-com-count span{background-color:#bbb;}.form-table .color-palette td{border-color:#fff;}.sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;}#post-body ul.category-tabs li.tabs a,#post-body ul.add-menu-item-tabs li.tabs a,body.press-this ul.category-tabs li.tabs a{color:#333;}#wp_editimgbtn,#wp_delimgbtn,#wp_editgallery,#wp_delgallery{border-color:#999;background-color:#eee;}#wp_editimgbtn:hover,#wp_delimgbtn:hover,#wp_editgallery:hover,#wp_delgallery:hover{border-color:#555;background-color:#ccc;}#favorite-first{border-color:#c0c0c0;background:#f1f1f1;background:-moz-linear-gradient(bottom,#e7e7e7,#fff);background:-webkit-gradient(linear,left bottom,left top,from(#e7e7e7),to(#fff));}#favorite-inside{border-color:#c0c0c0;background-color:#fff;}#favorite-toggle{background:transparent url(../images/fav-arrow.gif?ver=20100531) no-repeat 0 -4px;}#favorite-actions a{color:#464646;}#favorite-actions a:hover{color:#000;}#favorite-inside a:hover{text-decoration:underline;}#screen-meta .screen-meta-toggle{background:#D1E5ee;}#screen-meta a.show-settings,.toggle-arrow{background-image:url("../images/screen-options-toggle-vs.gif?ver=20100531");}#icon-edit,#icon-post{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -552px -5px;}#icon-index{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -137px -5px;}#icon-upload{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -251px -5px;}#icon-link-manager,#icon-link,#icon-link-category{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -190px -5px;}#icon-edit-pages,#icon-page{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -312px -5px;}#icon-edit-comments{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -72px -5px;}#icon-themes{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -11px -5px;}#icon-plugins{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -370px -5px;}#icon-users,#icon-profile,#icon-user-edit{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -600px -5px;}#icon-tools,#icon-admin{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -432px -5px;}#icon-options-general{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -492px -5px;}#icon-ms-admin{background:transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -659px -5px;}.view-switch #view-switch-list{background:transparent url(../images/list.png) no-repeat 0 0;}.view-switch .current #view-switch-list{background:transparent url(../images/list.png) no-repeat -40px 0;}.view-switch #view-switch-excerpt{background:transparent url(../images/list.png) no-repeat -20px 0;}.view-switch .current #view-switch-excerpt{background:transparent url(../images/list.png) no-repeat -60px 0;}#header-logo{background:transparent url(../images/wp-logo-vs.png?ver=20101102) no-repeat scroll center center;}.popular-tags,.feature-filter{background-color:#fff;border-color:#DFDFDF;}#theme-information .action-button{border-top-color:#DFDFDF;}.theme-listing br.line{border-bottom-color:#ccc;}div.widgets-sortables,#widgets-left .inactive{border-color:#D1E5EE;background-color:#f8f7f3;-moz-border-radius-bottomleft:8px;-moz-border-radius-bottomright:8px;}#available-widgets .widget-holder{background-color:#fff;border-color:#ddd;}#widgets-left .sidebar-name{background-color:#aaa;background-image:url(../images/ed-bg-vs.gif?ver=20101102);text-shadow:#fff 0 1px 0;border-color:#dfdfdf;}#widgets-right .sidebar-name{background-image:url(../images/button-grad.png);text-shadow:#174f69 0 -1px 0;background-color:#cfdfe9;border-color:#174f69;color:#fff;}.sidebar-name:hover,#removing-widget{color:#d54e21;}#removing-widget span{color:black;}#widgets-left .sidebar-name-arrow{background:transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -109px;}#widgets-right .sidebar-name-arrow{background:url("../images/widgets-arrow-vs.gif?ver=20100531") no-repeat scroll 0 -1px transparent;}.in-widget-title{color:#606060;}.deleting .widget-title *{color:#aaa;}.imgedit-menu div{border-color:#d5d5d5;background-color:#f1f1f1;}.imgedit-menu div:hover{border-color:#c1c1c1;background-color:#eaeaea;}.imgedit-menu div.disabled{border-color:#ccc;background-color:#ddd;filter:alpha(opacity=50);opacity:.5;}#dashboard_recent_comments div.undo{border-top-color:#dfdfdf;}.comment-ays,.comment-ays th{border-color:#ddd;}.comment-ays th{background-color:#f1f1f1;}#nav-menu-header,#nav-menu-footer,.menu-item-handle{background:url("../images/ed-bg-vs.gif?ver=20101102") repeat-x scroll left top #cfdfe9;border-top:solid #D1E5EE 1px;}#menu-management .nav-tab-active{background:#eff8ff;border-bottom-color:#eff8ff;} \ No newline at end of file diff --git a/src/wp-admin/css/colors-classic.dev.css b/src/wp-admin/css/colors-classic.dev.css new file mode 100644 index 00000000..26cb7081 --- /dev/null +++ b/src/wp-admin/css/colors-classic.dev.css @@ -0,0 +1,1706 @@ +html, +.wp-dialog { + background-color: #fcfcfb; +} + +* html input, +* html .widget { + border-color: #dfdfdf; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="file"], +input[type="button"], +input[type="submit"], +input[type="reset"], +select { + border-color: #dfdfdf; + background-color: #fff; +} + +kbd, +code { + background: #eaeaea; +} + +input[readonly] { + background-color: #eee; +} + +.find-box-search { + border-color: #dfdfdf; + background-color: #f1f1f1; +} + +.find-box { + background-color: #f1f1f1; +} + +.find-box-inside { + background-color: #fff; +} + +a.page-numbers:hover { + border-color: #999; +} + +body, +#wpbody, +.form-table .pre { + color: #174f69; +} + +body > #upload-menu { + border-bottom-color: #fff; +} + +#postcustomstuff table, +#your-profile fieldset, +#rightnow, +div.dashboard-widget, +#dashboard-widgets p.dashboard-widget-links, +#replyrow #ed_reply_toolbar input { + border-color: #D1E5EE +} + +#poststuff .inside label.spam, +#poststuff .inside label.deleted { + color: red; +} + +#poststuff .inside label.waiting { + color: orange; +} + +#poststuff .inside label.approved { + color: green; +} + +#postcustomstuff table { + border-color: #dfdfdf; + background-color: #F9F9F9; +} + +#postcustomstuff thead th { + background-color: #F1F1F1; +} + +#postcustomstuff table input, +#postcustomstuff table textarea { + border-color: #dfdfdf; + background-color: #fff; +} + +.widefat { + border-color: #D1E5EE; + background-color: #fff; +} + +div.dashboard-widget-error { + background-color: #c43; +} + +div.dashboard-widget-notice { + background-color: #cfe1ef; +} + +div.dashboard-widget-submit { + border-top-color: #ccc; +} + +div.tabs-panel, +.wp-tab-panel, +ul.category-tabs li.tabs, +ul.add-menu-item-tabs li.tabs, +.wp-tab-active { + border-color: #dfdfdf; +} + +ul.category-tabs li.tabs, +ul.add-menu-item-tabs li.tabs, +.wp-tab-active { + background-color: #f1f1f1; +} + +input.disabled, +textarea.disabled { + background-color: #ccc; +} +/* #upload-menu li a.upload-tab-link, */ +#plugin-information .action-button a, +#plugin-information .action-button a:hover, +#plugin-information .action-button a:visited { + color: #fff; +} + +.widget .widget-top, +.postbox h3, +.stuffbox h3 { + background: #cfdfe9 url("../images/blue-grad.png?ver=20101102") repeat-x left top; + text-shadow: #fff 0 1px 0; +} + +.form-table th, +.form-wrap label { + color: #222; + text-shadow: #fff 0 1px 0; +} + +.description, +.form-wrap p { + color: #666; +} + +strong .post-com-count span { + background-color: #21759b; +} + +.sorthelper { + background-color: #ccf3fa; +} + +.ac_match, +.subsubsub a.current { + color: #000; +} + +.wrap h2 { + color: #174f69; +} + +.ac_over { + background-color: #f0f0b8; +} + +.ac_results { + background-color: #fff; + border-color: #808080; +} + +.ac_results li { + color: #101010; +} + +.alternate, +.alt { + background-color: #F8F7F3; +} + +.available-theme a.screenshot { + background-color: #f1f1f1; + border-color: #ddd; +} + +.bar { + background-color: #e8e8e8; + border-right-color: #99d; +} + +#media-upload, +#media-upload .media-item .slidetoggle { + background: #fff; +} + +#media-upload .slidetoggle { + border-top-color: #dfdfdf; +} + +div.error, +.login #login_error { + background-color: #ffebe8; + border-color: #c00; +} + +div.error a { + color: #c00; +} + +.form-invalid { + background-color: #ffebe8 !important; +} + +.form-invalid input, +.form-invalid select { + border-color: #c00 !important; +} + +.submit { + border-color: #DFDFDF; +} + +.highlight { + background-color: #e4f2fd; + color: #000; +} + +.howto, +.nonessential, +#edit-slug-box, +.form-input-tip, +.rss-widget span.rss-date, +.subsubsub { + color: #666; +} + +.media-item { + border-bottom-color: #dfdfdf; +} + +#wpbody-content #media-items .describe { + border-top-color: #dfdfdf; +} + +.media-upload-form label.form-help, +td.help { + color: #9a9a9a; +} + +.post-com-count { + background-image: url(../images/bubble_bg.gif); + color: #fff; +} + +.post-com-count span { + background-color: #bbb; + color: #fff; +} + +.post-com-count:hover span { + background-color: #d54e21; +} + +.quicktags, .search { + background-color: #ccc; + color: #000; +} + +.side-info h5 { + border-bottom-color: #dadada; +} + +.side-info ul { + color: #666; +} + +.button, +.button-secondary, +.submit input, +input[type=button], +input[type=submit] { + border-color: #bbb; + color: #464646; +} + +.button:hover, +.button-secondary:hover, +.submit input:hover, +input[type=button]:hover, +input[type=submit]:hover { + color: #000; + border-color: #666; +} + +.button, +.submit input, +.button-secondary { + background: #f2f2f2 url(../images/white-grad.png) repeat-x scroll left top; + text-shadow: rgba(255,255,255,1) 0 1px 0; +} + +.button:active, +.submit input:active, +.button-secondary:active { + background: #eee url(../images/white-grad-active.png) repeat-x scroll left top; +} + +input.button-primary, +button.button-primary, +a.button-primary { + border-color: #298cba; + font-weight: bold; + color: #fff; + background: #21759B url(../images/button-grad.png) repeat-x scroll left top; + text-shadow: rgba(0,0,0,0.3) 0 -1px 0; +} + +input.button-primary:active, +button.button-primary:active, +a.button-primary:active { + background: #21759b url(../images/button-grad-active.png) repeat-x scroll left top; + color: #eaf2fa; +} + +input.button-primary:hover, +button.button-primary:hover, +a.button-primary:hover, +a.button-primary:focus, +a.button-primary:active { + border-color: #13455b; + color: #eaf2fa; +} + +.button-disabled, +.button[disabled], +.button:disabled, +.button-secondary[disabled], +.button-secondary:disabled, +a.button.disabled { + color: #aaa !important; + border-color: #ddd !important; +} + +.button-primary-disabled, +.button-primary[disabled], +.button-primary:disabled { + color: #9FD0D5 !important; + background: #298CBA !important; +} + +a:hover, +a:active, +a:focus { + color: #d54e21; +} + +#wphead #viewsite a:hover, +#adminmenu a:hover, +#adminmenu ul.wp-submenu a:hover, +#the-comment-list .comment a:hover, +#rightnow a:hover, +#media-upload a.del-link:hover, +div.dashboard-widget-submit input:hover, +.subsubsub a:hover, +.subsubsub a.current:hover, +.ui-tabs-nav a:hover, +.plugins .inactive a:hover, +#all-plugins-table .plugins .inactive a:hover, +#search-plugins-table .plugins .inactive a:hover { + color: #d54e21; +} + +#the-comment-list .comment-item, +#dashboard-widgets #dashboard_quick_press form p.submit { + border-color: #dfdfdf; +} + +#side-sortables .category-tabs .tabs a, +#side-sortables .add-menu-item-tabs .tabs a, +.wp-tab-bar .wp-tab-active a { + color: #333; +} + +#rightnow .rbutton { + background-color: #ebebeb; + color: #264761; +} + +.submitbox .submit { + background-color: #464646; + color: #ccc; +} + +.plugins a.delete:hover, +#all-plugins-table .plugins a.delete:hover, +#search-plugins-table .plugins a.delete:hover, +.submitbox .submitdelete { + color: #f00; + border-bottom-color: #f00; +} + +.submitbox .submitdelete:hover, +#media-items a.delete:hover { + color: #fff; + background-color: #f00; + border-bottom-color: #f00; +} + +#normal-sortables .submitbox .submitdelete:hover { + color: #000; + background-color: #f00; + border-bottom-color: #f00; +} + +.tablenav .dots { + border-color: transparent; +} + +.tablenav .next, +.tablenav .prev { + border-color: transparent; + color: #21759b; +} + +.tablenav .next:hover, +.tablenav .prev:hover { + border-color: transparent; + color: #d54e21; +} + +div.updated, +.login .message { + background-color: #ffffe0; + border-color: #e6db55; +} + +.update-message { + color: #000; +} + +a.page-numbers { + border-bottom-color: #B8D3E2; +} + +.commentlist li { + border-bottom-color: #ccc; +} + +.widefat td, +.widefat th { + border-color: #dfdfdf; +} + +.widefat th { + text-shadow: rgba(255,255,255,0.8) 0 1px 0; +} + +.widefat thead tr th, +.widefat tfoot tr th, +h3.dashboard-widget-title, +h3.dashboard-widget-title span, +h3.dashboard-widget-title small, +.find-box-head { + color: #333; + background: #cfdfe9 url(../images/blue-grad.png?ver=20101102) repeat-x scroll left top; +} + +th.sortable a:hover, th.sortable a:active, th.sortable a:focus { + color: #333; +} + +h3.dashboard-widget-title small a { + color: #d7d7d7; +} + +h3.dashboard-widget-title small a:hover { + color: #fff; +} + +a, +#adminmenu a, +#poststuff #edButtonPreview, +#poststuff #edButtonHTML, +#the-comment-list p.comment-author strong a, +#media-upload a.del-link, +#media-items a.delete, +.plugins a.delete, +.ui-tabs-nav a { + color: #21759b; +} + +#adminmenu #awaiting-mod, +#adminmenu .update-plugins, +#sidemenu a .update-plugins, +#rightnow .reallynow { + background-color: #464646; + color: #fff; + -moz-box-shadow: #fff 0 -1px 0; + -khtml-box-shadow: #fff 0 -1px 0; + -webkit-box-shadow: #fff 0 -1px 0; + box-shadow: #fff 0 -1px 0; +} +#plugin-information .action-button { + background-color: #d54e21; + color: #fff; +} + +#adminmenu li.current a #awaiting-mod, +#adminmenu li a.wp-has-current-submenu .update-plugins{ + background-color: #464646; + color: #fff; + -moz-box-shadow: #fff 0 -1px 0; + -khtml-box-shadow: #fff 0 -1px 0; + -webkit-box-shadow: #fff 0 -1px 0; + box-shadow: #fff 0 -1px 0; +} + +div#media-upload-header, +div#plugin-information-header { + background-color: #f9f9f9; + border-bottom-color: #dfdfdf; +} + +#currenttheme img { + border-color: #666; +} + +#dashboard_secondary div.dashboard-widget-content ul li a { + background-color: #f9f9f9; +} + +input.readonly, textarea.readonly { + background-color: #ddd; +} + +#ed_toolbar input, +#ed_reply_toolbar input { + background: #fff url("../images/fade-butt.png") repeat-x 0 -2px; +} + +#editable-post-name { + background-color: #fffbcc; +} + +#edit-slug-box strong, +.tablenav .displaying-num, +#submitted-on, +.submitted-on { + color: #777; +} + +.login #nav a { + color: #21759b !important; +} + +.login #nav a:hover { + color: #d54e21 !important; +} + +#footer { + color: #777; + border-color: #b0c8d7; + background: #cfdfe9; /* fallback color */ + background:-moz-linear-gradient(bottom, #cfdfe9, #eff8ff); + background:-webkit-gradient(linear, left bottom, left top, from(#cfdfe9), to(#eff8ff)); +} + +#media-items, +.imgedit-group { + border-color: #dfdfdf; +} + +.checkbox, +.side-info, +.plugins tr, +#your-profile #rich_editing { + background-color: #fff; +} + +.plugins .inactive, +.plugins .inactive th, +.plugins .inactive td, +tr.inactive + tr.plugin-update-tr .plugin-update { + background-color: #efede7; +} + +.plugin-update-tr .update-message { + background-color: #fffbe4; + border-color: #dfdfdf; +} + +.plugins .active, +.plugins .active th, +.plugins .active td { + color: #000; +} + +.plugins .inactive a { + color: #557799; +} + +#the-comment-list tr.undo, +#the-comment-list div.undo { + background-color: #f4f4f4; +} + +#the-comment-list .unapproved { + background-color: #ffffe0; +} + +#the-comment-list .approve a { + color: #006505; +} + +#the-comment-list .unapprove a { + color: #d98500; +} + +table.widefat span.delete a, +table.widefat span.trash a, +table.widefat span.spam a, +#dashboard_recent_comments .delete a, +#dashboard_recent_comments .trash a, +#dashboard_recent_comments .spam a { + color: #bc0b0b; +} + +.widget, +#widget-list .widget-top, +.postbox, +#titlediv, +#poststuff .postarea, +.stuffbox { + border-color: #D1E5EE; +} + +.widget, +.postbox { + background-color: #fff; +} + +.ui-sortable .postbox h3 { + color: #174f69; +} + +.widget .widget-top, +.ui-sortable .postbox h3:hover { + color: #174f69; +} + +.curtime #timestamp { + background-image: url(../images/date-button.gif); +} + +#quicktags #ed_link { + color: #00f; +} + +#rightnow .youhave { + background-color: #f0f6fb; +} + +#rightnow a { + color: #448abd; +} + +.tagchecklist span a, +#bulk-titles div a { + background: url(../images/xit.gif) no-repeat; +} + +.tagchecklist span a:hover, +#bulk-titles div a:hover { + background: url(../images/xit.gif) no-repeat -10px 0; +} + +#update-nag, .update-nag { + background-color: #FFFBCC; + border-color: #E6DB55; + color: #555; +} + +.login #backtoblog a { + color: #464646; +} + +#wphead { + border-bottom:#b0c8d7 1px solid; + background: #cfdfe9; /* fallback color */ + background:-moz-linear-gradient(bottom, #cfdfe9, #eff8ff); + background:-webkit-gradient(linear, left bottom, left top, from(#cfdfe9), to(#eff8ff)); +} + +#wphead h1 a { + color: #174f69; +} + +#user_info { + color: #777; +} + +#user_info a:link, +#user_info a:visited, +#footer a:link, +#footer a:visited { + color: #174f69; + text-decoration: none; +} + +#user_info a:hover, +#footer a:hover { + color: #000; + text-decoration: underline !important; +} + +div#media-upload-error, +.file-error, +abbr.required, +.widget-control-remove:hover, +table.widefat .delete a:hover, +table.widefat .trash a:hover, +table.widefat .spam a:hover, +#dashboard_recent_comments .delete a:hover, +#dashboard_recent_comments .trash a:hover +#dashboard_recent_comments .spam a:hover { + color: #f00; +} + +#pass-strength-result { + background-color: #eee; + border-color: #ddd !important; +} + +#pass-strength-result.bad { + background-color: #ffb78c; + border-color: #ff853c !important; +} + +#pass-strength-result.good { + background-color: #ffec8b; + border-color: #fc0 !important; +} + +#pass-strength-result.short { + background-color: #ffa0a0; + border-color: #f04040 !important; +} + +#pass-strength-result.strong { + background-color: #c3ff88; + border-color: #8dff1c !important; +} + +/* editors */ +#quicktags { + border-color: #cfdfe9; + background-color: #cfdfe9; + background-image: url("../images/ed-bg-vs.gif?ver=20101102"); +} + +#ed_toolbar input { + border-color: #C3C3C3; +} + +#ed_toolbar input:hover { + border-color: #aaa; + background: #ddd; +} + +#poststuff .wp_themeSkin .mceStatusbar { + border-color: #EDEDED; +} + +#poststuff #edButtonPreview, +#poststuff #edButtonHTML { + background-color: #eff8ff; + border-color: #D1E5EE; + color: #999; +} + +#poststuff #editor-toolbar .active { + border-bottom-color: #eff8ff; + background-color: #eff8ff; + color: #333; +} + +/* TinyMCE */ +#post-status-info { + background-color: #eff8ff; +} + +.wp_themeSkin *, +.wp_themeSkin a:hover, +.wp_themeSkin a:link, +.wp_themeSkin a:visited, +.wp_themeSkin a:active { + color: #000; +} + +/* Containers */ +.wp_themeSkin iframe { + background: #fff; +} + +/* Layout */ +.wp_themeSkin .mceStatusbar { + color: #000; + background-color: #f5f5f5; +} + +/* Button */ +.wp_themeSkin .mceButton { + background-color: #e9e8e8; + border-color: #B2B2B2; +} + +.wp_themeSkin a.mceButtonEnabled:hover, +.wp_themeSkin a.mceButtonActive, +.wp_themeSkin a.mceButtonSelected { + background: #d5d5d5; + border-color: #777 !important; +} + +.wp_themeSkin .mceButtonDisabled { + border-color: #ccc !important; +} + +/* ListBox */ +.wp_themeSkin .mceListBox .mceText, +.wp_themeSkin .mceListBox .mceOpen { + border-color: #B2B2B2; + background-color: #d5d5d5; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen, +.wp_themeSkin .mceListBoxHover .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceText { + border-color: #777 !important; + background-color: #d5d5d5; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceText, +.wp_themeSkin .mceListBoxHover .mceText { + border-color: #777 !important; +} + +.wp_themeSkin select.mceListBox { + border-color: #B2B2B2; + background-color: #fff; +} + +/* SplitButton */ +.wp_themeSkin .mceSplitButton a.mceAction, +.wp_themeSkin .mceSplitButton a.mceOpen { + border-color: #B2B2B2; +} + +.wp_themeSkin .mceSplitButton a.mceOpen:hover, +.wp_themeSkin .mceSplitButtonSelected a.mceOpen, +.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction, +.wp_themeSkin .mceSplitButton a.mceAction:hover { + background-color: #d5d5d5; + border-color: #777 !important; +} + +.wp_themeSkin .mceSplitButtonActive { + background-color: #B2B2B2; +} + +/* ColorSplitButton */ +.wp_themeSkin div.mceColorSplitMenu table { + background-color: #ebebeb; + border-color: #B2B2B2; +} + +.wp_themeSkin .mceColorSplitMenu a { + border-color: #B2B2B2; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors { + border-color: #fff; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover { + border-color: #0A246A; + background-color: #B6BDD2; +} + +.wp_themeSkin a.mceMoreColors:hover { + border-color: #0A246A; +} + +/* Menu */ +.wp_themeSkin .mceMenu { + border-color: #ddd; +} + +.wp_themeSkin .mceMenu table { + background-color: #ebeaeb; +} + +.wp_themeSkin .mceMenu .mceText { + color: #000; +} + +.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover, +.wp_themeSkin .mceMenu .mceMenuItemActive { + background-color: #f5f5f5; +} +.wp_themeSkin td.mceMenuItemSeparator { + background-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle a { + background-color: #ccc; + border-bottom-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle span.mceText { + color: #000; +} +.wp_themeSkin .mceMenuItemDisabled .mceText { + color: #888; +} + +.wp_themeSkin tr.mceFirst td.mceToolbar { + background: #cfdfe9 url("../images/ed-bg-vs.gif?ver=20101102") repeat-x scroll left top; + border-color: #cfdfe9; +} + +.wp-admin #mceModalBlocker { + background: #000; +} + +.wp-admin .clearlooks2 .mceFocus .mceTop .mceLeft { + background: #444444; + border-left: 1px solid #999; + border-top: 1px solid #999; + -moz-border-radius: 4px 0 0 0; + -webkit-border-top-left-radius: 4px; + -khtml-border-top-left-radius: 4px; + border-top-left-radius: 4px; +} + +.wp-admin .clearlooks2 .mceFocus .mceTop .mceRight { + background: #444444; + border-right: 1px solid #999; + border-top: 1px solid #999; + border-top-right-radius: 4px; + -khtml-border-top-right-radius: 4px; + -webkit-border-top-right-radius: 4px; + -moz-border-radius: 0 4px 0 0; +} + +.wp-admin .clearlooks2 .mceMiddle .mceLeft { + background: #f1f1f1; + border-left: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceMiddle .mceRight { + background: #f1f1f1; + border-right: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom { + background: #f1f1f1; + border-bottom: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom .mceLeft { + background: #f1f1f1; + border-bottom: 1px solid #999; + border-left: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom .mceCenter { + background: #f1f1f1; + border-bottom: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom .mceRight { + background: #f1f1f1; + border-bottom: 1px solid #999; + border-right: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceFocus .mceTop span { + color: #e5e5e5; +} +/* end TinyMCE */ + +#editorcontainer, +#post-status-info, +#titlediv #title, +.editwidget .widget-inside { + border-color: #D1E5EE; +} + +#titlediv #title { + background-color: #fff; +} + +#tTips p#tTips_inside { + background-color: #ddd; + color: #333; +} + +#timestampdiv input, +#namediv input, +#poststuff .inside .the-tagcloud { + border-color: #ddd; +} + +/* menu */ +#adminmenu * { + border-color: #d1e5ee; +} + +#adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px; +} + +.folded #adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px; +} + +#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle, +#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle { + background: transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -207px; +} + +#adminmenu .wp-has-submenu:hover .wp-menu-toggle, +#adminmenu .wp-menu-open .wp-menu-toggle { + background: transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -109px; +} + +#adminmenu a.menu-top { + background: #eff8ff url(../images/menu-bits-vs.gif?ver=20101102) repeat-x scroll left -379px; +} + +#adminmenu .wp-submenu a { + background: #fff url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll 0 -99px; +} + +#adminmenu .wp-has-current-submenu ul li a { + background: none; +} + +#adminmenu .wp-has-current-submenu ul li a.current { + background: url(../images/menu-dark-vs.gif) top left no-repeat !important; +} + +.wp-has-current-submenu .wp-submenu { + border-top: none !important; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu { + border-bottom: #aaa 1px solid; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu, +#adminmenu li.current a.menu-top { + background: #d0dfe9 url(../images/menu-bits-vs.gif?ver=20101102) top left repeat-x; + border: #5589aa 1px solid; + color: #464646; +} + +#adminmenu li.wp-has-current-submenu .wp-submenu, +#adminmenu li.wp-has-current-submenu ul li a { + border-right-color: #5589aa !important; + border-left-color: #5589aa !important; +} + +#adminmenu li.wp-has-current-submenu ul li a { + background: url(../images/menu-dark-vs.gif) bottom left no-repeat !important; +} + +#adminmenu li.wp-has-current-submenu ul { + border-bottom-color: #5589aa; +} + +#adminmenu .wp-submenu .current a.current { + background: transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll 0 -289px; +} + +#adminmenu .wp-submenu a:hover { + background-color: #f8f7f3 !important; + color: #333 !important; +} + +#adminmenu .wp-submenu li.current, +#adminmenu .wp-submenu li.current a, +#adminmenu .wp-submenu li.current a:hover { + color: #333; + background-color: #efede7; + background-image: none; + border-color: #5589aa; +} + +#adminmenu .wp-submenu ul { + background-color: #fff; +} + +.folded #adminmenu li.menu-top, +#adminmenu .wp-submenu .wp-submenu-head { + background: #eff8ff url(../images/menu-bits-vs.gif?ver=20101102) repeat-x scroll left -379px; +} + +.folded #adminmenu li.wp-has-current-submenu, +.folded #adminmenu li.menu-top.current { + background: #e0e0e0 url(../images/menu-bits-vs.gif?ver=20101102) top left repeat-x; + border: #5589aa 1px solid; + color: #464646; +} + +#adminmenu .wp-has-current-submenu .wp-submenu .wp-submenu-head { + background: #d0dfe9 url(../images/menu-bits-vs.gif?ver=20101102) repeat-x 0% 0%; + border: 1px solid; + color: #464646; +} + +#adminmenu div.wp-submenu { + background-color: transparent; +} + +/* menu icons */ +#adminmenu .menu-icon-dashboard div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -61px -33px; +} + +#adminmenu .menu-icon-dashboard:hover div.wp-menu-image, +#adminmenu .menu-icon-dashboard.wp-has-current-submenu div.wp-menu-image, +#adminmenu .menu-icon-dashboard.current div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -61px -1px; +} + +#adminmenu .menu-icon-post div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -272px -33px; +} + +#adminmenu .menu-icon-post:hover div.wp-menu-image, +#adminmenu .menu-icon-post.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -272px -1px; +} + +#adminmenu .menu-icon-media div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -121px -33px; +} + +#adminmenu .menu-icon-media:hover div.wp-menu-image, +#adminmenu .menu-icon-media.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -121px -1px; +} + +#adminmenu .menu-icon-links div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -91px -33px; +} + +#adminmenu .menu-icon-links:hover div.wp-menu-image, +#adminmenu .menu-icon-links.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -91px -1px; +} + +#adminmenu .menu-icon-page div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -151px -33px; +} + +#adminmenu .menu-icon-page:hover div.wp-menu-image, +#adminmenu .menu-icon-page.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -151px -1px; +} + +#adminmenu .menu-icon-comments div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -31px -33px; +} + +#adminmenu .menu-icon-comments:hover div.wp-menu-image, +#adminmenu .menu-icon-comments.wp-has-current-submenu div.wp-menu-image, +#adminmenu .menu-icon-comments.current div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -31px -1px; +} + +#adminmenu .menu-icon-appearance div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -1px -33px; +} + +#adminmenu .menu-icon-appearance:hover div.wp-menu-image, +#adminmenu .menu-icon-appearance.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -1px -1px; +} + +#adminmenu .menu-icon-plugins div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -181px -33px; +} + +#adminmenu .menu-icon-plugins:hover div.wp-menu-image, +#adminmenu .menu-icon-plugins.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -181px -1px; +} + +#adminmenu .menu-icon-users div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -301px -33px; +} + +#adminmenu .menu-icon-users:hover div.wp-menu-image, +#adminmenu .menu-icon-users.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -301px -1px; +} + +#adminmenu .menu-icon-tools div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -211px -33px; +} + +#adminmenu .menu-icon-tools:hover div.wp-menu-image, +#adminmenu .menu-icon-tools.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -211px -1px; +} + +#adminmenu .menu-icon-settings div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -241px -33px; +} + +#adminmenu .menu-icon-settings:hover div.wp-menu-image, +#adminmenu .menu-icon-settings.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -241px -1px; +} + +#adminmenu .menu-icon-site div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -361px -33px; +} + +#adminmenu .menu-icon-site:hover div.wp-menu-image, +#adminmenu .menu-icon-site.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu-vs.png?ver=20100531') no-repeat scroll -361px -1px; +} +/* end menu */ + + +/* Diff */ +table.diff .diff-deletedline { + background-color: #fdd; +} + +table.diff .diff-deletedline del { + background-color: #f99; +} + +table.diff .diff-addedline { + background-color: #dfd; +} + +table.diff .diff-addedline ins { + background-color: #9f9; +} + +#att-info { + background-color: #E4F2FD; +} + +/* edit image */ +#sidemenu a { + background-color: #f9f9f9; + border-color: #f9f9f9; + border-bottom-color: #dfdfdf; +} + +#sidemenu a.current { + background-color: #fff; + border-color: #dfdfdf #dfdfdf #fff; + color: #D54E21; +} + +#screen-options-wrap, +#contextual-help-wrap { + background-color: #F8F7F3; + border-color: #D1e5ee; +} + +#screen-meta-links a.show-settings { + color: #606060; +} + +#screen-meta-links a.show-settings:hover { + color: #000; +} + +#replysubmit { + background-color: #f1f1f1; + border-top-color: #ddd; +} + +#replyerror { + border-color: #ddd; + background-color: #f9f9f9; +} + +#edithead, +#replyhead { + background-color: #f1f1f1; +} + +#ed_reply_toolbar { + background-color: #e9e9e9; +} + +/* table vim shortcuts */ +.vim-current, +.vim-current th, +.vim-current td { + background-color: #E4F2FD !important; +} + +/* Install Plugins */ +.star-average, +.star.star-rating { + background-color: #fc0; +} + +div.star.select:hover { + background-color: #d00; +} + +#plugin-information .fyi ul { + background-color: #eaf3fa; +} + +#plugin-information .fyi h2.mainheader { + background-color: #cee1ef; +} + +#plugin-information pre, +#plugin-information code { + background-color: #ededff; +} + +#plugin-information pre { + border: 1px solid #ccc; +} + +/* inline editor */ +.inline-edit-row fieldset input[type="text"], +.inline-edit-row fieldset textarea, +#bulk-titles, +#replyrow input { + border-color: #ddd; +} + +.inline-editor div.title { + background-color: #EAF3FA; +} + +.inline-editor ul.cat-checklist { + background-color: #fff; + border-color: #ddd; +} + +.inline-editor .categories .catshow, +.inline-editor .categories .cathide { + color: #21759b; +} + +.inline-editor .quick-edit-save { + background-color: #f1f1f1; +} + +#replyrow #ed_reply_toolbar input:hover { + border-color: #aaa; + background: #ddd; +} + +fieldset.inline-edit-col-right .inline-edit-col { + border-color: #dfdfdf; +} + +.attention { + color: #D54E21; +} + +body.press-this .postbox:hover .handlediv, +body.press-this .stuffbox:hover .handlediv, +.meta-box-sortables .postbox:hover .handlediv { + background: transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -111px; +} + +#major-publishing-actions { + background: #eaf2fa; +} + +.tablenav .tablenav-pages { + color: #555; +} + +.tablenav .tablenav-pages a { + border-color: #d1e5ee; + background: #eee url('../images/menu-bits-vs.gif?ver=20101102') repeat-x scroll left -379px; +} + +.tablenav .tablenav-pages a:hover, +.tablenav .tablenav-pages a:focus { + color: #d54e21; +} + +.tablenav .tablenav-pages a.disabled, +.tablenav .tablenav-pages a.disabled:hover, +.tablenav .tablenav-pages a.disabled:focus { + color: #aaa; +} + +.tablenav .tablenav-pages .current { + background: #dfdfdf; + border-color: #d3d3d3; +} + +#availablethemes, +#availablethemes td { + border-color: #ddd; +} + +#current-theme img { + border-color: #999; +} + +#TB_window #TB_title a.tb-theme-preview-link, +#TB_window #TB_title a.tb-theme-preview-link:visited { + color: #999; +} + +#TB_window #TB_title a.tb-theme-preview-link:hover, +#TB_window #TB_title a.tb-theme-preview-link:focus { + color: #ccc; +} + +.misc-pub-section { + border-bottom-color: #eee; +} + +#minor-publishing { + border-bottom-color: #ddd; +} + +#post-body .misc-pub-section { + border-right-color: #eee; +} + +.post-com-count span { + background-color: #bbb; +} + +.form-table .color-palette td { + border-color: #fff; +} + +.sortable-placeholder { + border-color: #bbb; + background-color: #f5f5f5; +} + +#post-body ul.category-tabs li.tabs a, +#post-body ul.add-menu-item-tabs li.tabs a, +body.press-this ul.category-tabs li.tabs a { + color: #333; +} + +#wp_editimgbtn, +#wp_delimgbtn, +#wp_editgallery, +#wp_delgallery { + border-color: #999; + background-color: #eee; +} + +#wp_editimgbtn:hover, +#wp_delimgbtn:hover, +#wp_editgallery:hover, +#wp_delgallery:hover { + border-color: #555; + background-color: #ccc; +} + +#favorite-first { + border-color: #c0c0c0; + background: #f1f1f1; /* fallback color */ + background:-moz-linear-gradient(bottom, #e7e7e7, #fff); + background:-webkit-gradient(linear, left bottom, left top, from(#e7e7e7), to(#fff)); +} + +#favorite-inside { + border-color: #c0c0c0; + background-color: #fff; +} + +#favorite-toggle { + background: transparent url(../images/fav-arrow.gif?ver=20100531) no-repeat 0 -4px; +} + +#favorite-actions a { + color: #464646; +} + +#favorite-actions a:hover { + color: #000; +} + +#favorite-inside a:hover { + text-decoration: underline; +} + +#screen-meta .screen-meta-toggle { + background: #D1E5ee; +} + +#screen-meta a.show-settings, +.toggle-arrow { + background-image:url("../images/screen-options-toggle-vs.gif?ver=20100531"); +} + +#icon-edit, +#icon-post { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -552px -5px; +} + +#icon-index { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -137px -5px; +} + +#icon-upload { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -251px -5px; +} + +#icon-link-manager, +#icon-link, +#icon-link-category { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -190px -5px; +} + +#icon-edit-pages, +#icon-page { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -312px -5px; +} + +#icon-edit-comments { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -72px -5px; +} + +#icon-themes { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -11px -5px; +} + +#icon-plugins { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -370px -5px; +} + +#icon-users, +#icon-profile, +#icon-user-edit { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -600px -5px; +} + +#icon-tools, +#icon-admin { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -432px -5px; +} + +#icon-options-general { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -492px -5px; +} + +#icon-ms-admin { + background: transparent url(../images/icons32-vs.png?ver=20100531) no-repeat -659px -5px; +} + +.view-switch #view-switch-list { + background: transparent url(../images/list.png) no-repeat 0 0; +} + +.view-switch .current #view-switch-list { + background: transparent url(../images/list.png) no-repeat -40px 0; +} + +.view-switch #view-switch-excerpt { + background: transparent url(../images/list.png) no-repeat -20px 0; +} + +.view-switch .current #view-switch-excerpt { + background: transparent url(../images/list.png) no-repeat -60px 0; +} + +#header-logo { + background: transparent url(../images/wp-logo-vs.png?ver=20101102) no-repeat scroll center center; +} + +.popular-tags, +.feature-filter { + background-color: #fff; + border-color: #DFDFDF; +} + +#theme-information .action-button { + border-top-color: #DFDFDF; +} + +.theme-listing br.line { + border-bottom-color: #ccc; +} + +div.widgets-sortables, +#widgets-left .inactive { + border-color: #D1E5EE; + background-color: #f8f7f3; + -moz-border-radius-bottomleft:8px; +-moz-border-radius-bottomright:8px +} + +#available-widgets .widget-holder { + background-color: #fff; + border-color: #ddd; +} + +#widgets-left .sidebar-name { + background-color: #aaa; + background-image: url(../images/ed-bg-vs.gif?ver=20101102); + text-shadow: #fff 0 1px 0; + border-color: #dfdfdf; +} + +#widgets-right .sidebar-name { + background-image: url(../images/button-grad.png); + text-shadow: #174f69 0 -1px 0; + background-color: #cfdfe9; + border-color: #174f69; + color: #ffffff; +} + +.sidebar-name:hover, +#removing-widget { + color: #d54e21; +} + +#removing-widget span { + color: black; +} + +#widgets-left .sidebar-name-arrow { + background: transparent url(../images/menu-bits-vs.gif?ver=20101102) no-repeat scroll left -109px; +} + +#widgets-right .sidebar-name-arrow { + background: url("../images/widgets-arrow-vs.gif?ver=20100531") no-repeat scroll 0 -1px transparent; +} + +.in-widget-title { + color: #606060; +} + +.deleting .widget-title * { + color: #aaa; +} + +.imgedit-menu div { + border-color: #d5d5d5; + background-color: #f1f1f1; +} + +.imgedit-menu div:hover { + border-color: #c1c1c1; + background-color: #eaeaea; +} + +.imgedit-menu div.disabled { + border-color: #ccc; + background-color: #ddd; + filter: alpha(opacity=50); + opacity: 0.5; +} + +#dashboard_recent_comments div.undo { + border-top-color: #dfdfdf; +} + +.comment-ays, +.comment-ays th { + border-color: #ddd; +} + +.comment-ays th { + background-color: #f1f1f1; +} + +#nav-menu-header, #nav-menu-footer, .menu-item-handle { + background: url("../images/ed-bg-vs.gif?ver=20101102") repeat-x scroll left top #cfdfe9; + border-top: solid #D1E5EE 1px; +} + +#menu-management .nav-tab-active { + background: #eff8ff; + border-bottom-color: #eff8ff; +} diff --git a/src/wp-admin/css/colors-fresh-rtl.css b/src/wp-admin/css/colors-fresh-rtl.css new file mode 100644 index 00000000..18930fdc --- /dev/null +++ b/src/wp-admin/css/colors-fresh-rtl.css @@ -0,0 +1 @@ +.bar{border-right-color:transparent;border-left-color:#99d;}.plugins .togl{border-right-color:transparent;border-left-color:#ccc;}.post-com-count{background-image:url(../images/bubble_bg-rtl.gif);}.tablenav .tablenav-pages a{background:#eee url('../images/menu-bits-rtl.gif?ver=20100531') repeat-x scroll right -379px;}#upload-menu li.current{border-right-color:transparent;border-left-color:#448abd;}#adminmenu .wp-submenu .current a.current{background:transparent url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -289px;}#adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px;}.folded #adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px;}#adminmenu li.wp-has-current-submenu .wp-menu-toggle,#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle{background:transparent url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right -207px;}#adminmenu .wp-has-current-submenu ul li a.current{background:url(../images/menu-dark-rtl.gif) top right no-repeat!important;}#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu,#adminmenu .menu-top .current{background:url(../images/menu-bits-rtl.gif?ver=20100531) top right repeat-x;}#adminmenu li.wp-has-current-submenu ul li a{background:url(../images/menu-dark-rtl.gif) bottom right no-repeat!important;}#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle,#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle{background:transparent url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat right -207px;}#adminmenu .wp-has-submenu:hover .wp-menu-toggle,#adminmenu .wp-menu-open .wp-menu-toggle{background:transparent url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right -109px;}#adminmenu a.wp-has-submenu{background:#f1f1f1 url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right -379px;}#adminmenu .wp-submenu a{background:#fff url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -310px;}#adminmenu li.wp-has-current-submenu a.wp-has-submenu{background:#b5b5b5 url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right top;}.meta-box-sortables .postbox:hover .handlediv{background:transparent url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -111px;}#favorite-toggle{background:transparent url(../images/fav-arrow-rtl.gif?ver=20100531) no-repeat right -4px;} \ No newline at end of file diff --git a/src/wp-admin/css/colors-fresh-rtl.dev.css b/src/wp-admin/css/colors-fresh-rtl.dev.css new file mode 100644 index 00000000..8071127d --- /dev/null +++ b/src/wp-admin/css/colors-fresh-rtl.dev.css @@ -0,0 +1,78 @@ +.bar { + border-right-color: transparent; + border-left-color: #99d; +} + +.plugins .togl { + border-right-color: transparent; + border-left-color: #ccc; +} + +.post-com-count { + background-image: url(../images/bubble_bg-rtl.gif); +} +.tablenav .tablenav-pages a { + background: #eee url('../images/menu-bits-rtl.gif?ver=20100531') repeat-x scroll right -379px; +} +#upload-menu li.current { + border-right-color: transparent; + border-left-color: #448abd; +} + +#adminmenu .wp-submenu .current a.current { + background: transparent url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -289px; +} + +#adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px; +} + +.folded #adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px; +} + +#adminmenu li.wp-has-current-submenu .wp-menu-toggle, +#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle { + background: transparent url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right -207px; +} + +#adminmenu .wp-has-current-submenu ul li a.current { + background: url(../images/menu-dark-rtl.gif) top right no-repeat !important; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu, +#adminmenu .menu-top .current { + background: url(../images/menu-bits-rtl.gif?ver=20100531) top right repeat-x; +} + +#adminmenu li.wp-has-current-submenu ul li a { + background: url(../images/menu-dark-rtl.gif) bottom right no-repeat !important; +} + +#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle, #adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle { + background: transparent url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat right -207px; +} + +#adminmenu .wp-has-submenu:hover .wp-menu-toggle, +#adminmenu .wp-menu-open .wp-menu-toggle { + background: transparent url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right -109px; +} + +#adminmenu a.wp-has-submenu { + background: #f1f1f1 url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right -379px; +} + +#adminmenu .wp-submenu a { + background: #fff url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -310px; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-submenu { + background: #b5b5b5 url(../images/menu-bits-rtl.gif?ver=20100531) repeat-x scroll right top; +} + +.meta-box-sortables .postbox:hover .handlediv { + background: transparent url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -111px; +} +#favorite-toggle { + background: transparent url(../images/fav-arrow-rtl.gif?ver=20100531) no-repeat right -4px; +} diff --git a/src/wp-admin/css/colors-fresh.css b/src/wp-admin/css/colors-fresh.css new file mode 100644 index 00000000..709b9b04 --- /dev/null +++ b/src/wp-admin/css/colors-fresh.css @@ -0,0 +1 @@ +html,.wp-dialog{background-color:#f9f9f9;}* html input,* html .widget{border-color:#dfdfdf;}textarea,input[type="text"],input[type="password"],input[type="file"],input[type="button"],input[type="submit"],input[type="reset"],select{border-color:#dfdfdf;background-color:#fff;}kbd,code{background:#eaeaea;}input[readonly]{background-color:#eee;}.find-box-search{border-color:#dfdfdf;background-color:#f1f1f1;}.find-box{background-color:#f1f1f1;}.find-box-inside{background-color:#fff;}a.page-numbers:hover{border-color:#999;}body,#wpbody,.form-table .pre{color:#333;}body>#upload-menu{border-bottom-color:#fff;}#postcustomstuff table,#your-profile fieldset,#rightnow,div.dashboard-widget,#dashboard-widgets p.dashboard-widget-links,#replyrow #ed_reply_toolbar input{border-color:#ccc;}#poststuff .inside label.spam,#poststuff .inside label.deleted{color:red;}#poststuff .inside label.waiting{color:orange;}#poststuff .inside label.approved{color:green;}#postcustomstuff table{border-color:#dfdfdf;background-color:#F9F9F9;}#postcustomstuff thead th{background-color:#F1F1F1;}#postcustomstuff table input,#postcustomstuff table textarea{border-color:#dfdfdf;background-color:#fff;}.widefat{border-color:#dfdfdf;background-color:#fff;}div.dashboard-widget-error{background-color:#c43;}div.dashboard-widget-notice{background-color:#cfe1ef;}div.dashboard-widget-submit{border-top-color:#ccc;}div.tabs-panel,.wp-tab-panel,ul.category-tabs li.tabs,ul.add-menu-item-tabs li.tabs,.wp-tab-active{border-color:#dfdfdf;}ul.category-tabs li.tabs,ul.add-menu-item-tabs li.tabs,.wp-tab-active{background-color:#f1f1f1;}input.disabled,textarea.disabled{background-color:#ccc;}#plugin-information .action-button a,#plugin-information .action-button a:hover,#plugin-information .action-button a:visited{color:#fff;}.widget .widget-top,.postbox h3,.stuffbox h3{background:#dfdfdf url("../images/gray-grad.png") repeat-x left top;text-shadow:#fff 0 1px 0;}.form-table th,.form-wrap label{color:#222;text-shadow:#fff 0 1px 0;}.description,.form-wrap p{color:#666;}strong .post-com-count span{background-color:#21759b;}.sorthelper{background-color:#ccf3fa;}.ac_match,.subsubsub a.current{color:#000;}.wrap h2{color:#464646;}.ac_over{background-color:#f0f0b8;}.ac_results{background-color:#fff;border-color:#808080;}.ac_results li{color:#101010;}.alternate,.alt{background-color:#f9f9f9;}.available-theme a.screenshot{background-color:#f1f1f1;border-color:#ddd;}.bar{background-color:#e8e8e8;border-right-color:#99d;}#media-upload,#media-upload .media-item .slidetoggle{background:#fff;}#media-upload .slidetoggle{border-top-color:#dfdfdf;}div.error,.login #login_error{background-color:#ffebe8;border-color:#c00;}div.error a{color:#c00;}.form-invalid{background-color:#ffebe8!important;}.form-invalid input,.form-invalid select{border-color:#c00!important;}.submit{border-color:#DFDFDF;}.highlight{background-color:#e4f2fd;color:#000;}.howto,.nonessential,#edit-slug-box,.form-input-tip,.rss-widget span.rss-date,.subsubsub{color:#666;}.media-item{border-bottom-color:#dfdfdf;}#wpbody-content #media-items .describe{border-top-color:#dfdfdf;}.media-upload-form label.form-help,td.help{color:#9a9a9a;}.post-com-count{background-image:url(../images/bubble_bg.gif);color:#fff;}.post-com-count span{background-color:#bbb;color:#fff;}.post-com-count:hover span{background-color:#d54e21;}.quicktags,.search{background-color:#ccc;color:#000;}.side-info h5{border-bottom-color:#dadada;}.side-info ul{color:#666;}.button,.button-secondary,.submit input,input[type=button],input[type=submit]{border-color:#bbb;color:#464646;}.button:hover,.button-secondary:hover,.submit input:hover,input[type=button]:hover,input[type=submit]:hover{color:#000;border-color:#666;}.button,.submit input,.button-secondary{background:#f2f2f2 url(../images/white-grad.png) repeat-x scroll left top;text-shadow:rgba(255,255,255,1) 0 1px 0;}.button:active,.submit input:active,.button-secondary:active{background:#eee url(../images/white-grad-active.png) repeat-x scroll left top;}input.button-primary,button.button-primary,a.button-primary{border-color:#298cba;font-weight:bold;color:#fff;background:#21759B url(../images/button-grad.png) repeat-x scroll left top;text-shadow:rgba(0,0,0,0.3) 0 -1px 0;}input.button-primary:active,button.button-primary:active,a.button-primary:active{background:#21759b url(../images/button-grad-active.png) repeat-x scroll left top;color:#eaf2fa;}input.button-primary:hover,button.button-primary:hover,a.button-primary:hover,a.button-primary:focus,a.button-primary:active{border-color:#13455b;color:#eaf2fa;}.button-disabled,.button[disabled],.button:disabled,.button-secondary[disabled],.button-secondary:disabled,a.button.disabled{color:#aaa!important;border-color:#ddd!important;}.button-primary-disabled,.button-primary[disabled],.button-primary:disabled{color:#9FD0D5!important;background:#298CBA!important;}a:hover,a:active,a:focus{color:#d54e21;}#wphead #viewsite a:hover,#adminmenu a:hover,#adminmenu ul.wp-submenu a:hover,#the-comment-list .comment a:hover,#rightnow a:hover,#media-upload a.del-link:hover,div.dashboard-widget-submit input:hover,.subsubsub a:hover,.subsubsub a.current:hover,.ui-tabs-nav a:hover,.plugins .inactive a:hover,#all-plugins-table .plugins .inactive a:hover,#search-plugins-table .plugins .inactive a:hover{color:#d54e21;}#the-comment-list .comment-item,#dashboard-widgets #dashboard_quick_press form p.submit{border-color:#dfdfdf;}#side-sortables .category-tabs .tabs a,#side-sortables .add-menu-item-tabs .tabs a,.wp-tab-bar .wp-tab-active a{color:#333;}#rightnow .rbutton{background-color:#ebebeb;color:#264761;}.submitbox .submit{background-color:#464646;color:#ccc;}.plugins a.delete:hover,#all-plugins-table .plugins a.delete:hover,#search-plugins-table .plugins a.delete:hover,.submitbox .submitdelete{color:#f00;border-bottom-color:#f00;}.submitbox .submitdelete:hover,#media-items a.delete:hover{color:#fff;background-color:#f00;border-bottom-color:#f00;}#normal-sortables .submitbox .submitdelete:hover{color:#000;background-color:#f00;border-bottom-color:#f00;}.tablenav .dots{border-color:transparent;}.tablenav .next,.tablenav .prev{border-color:transparent;color:#21759b;}.tablenav .next:hover,.tablenav .prev:hover{border-color:transparent;color:#d54e21;}div.updated,.login .message{background-color:#ffffe0;border-color:#e6db55;}.update-message{color:#000;}a.page-numbers{border-bottom-color:#B8D3E2;}.commentlist li{border-bottom-color:#ccc;}.widefat td,.widefat th{border-color:#dfdfdf;}.widefat th{text-shadow:rgba(255,255,255,0.8) 0 1px 0;}.widefat thead tr th,.widefat tfoot tr th,h3.dashboard-widget-title,h3.dashboard-widget-title span,h3.dashboard-widget-title small,.find-box-head{color:#333;background:#dfdfdf url(../images/gray-grad.png) repeat-x scroll left top;}th.sortable a:hover,th.sortable a:active,th.sortable a:focus{color:#333;}h3.dashboard-widget-title small a{color:#d7d7d7;}h3.dashboard-widget-title small a:hover{color:#fff;}a,#adminmenu a,#poststuff #edButtonPreview,#poststuff #edButtonHTML,#the-comment-list p.comment-author strong a,#media-upload a.del-link,#media-items a.delete,.plugins a.delete,.ui-tabs-nav a{color:#21759b;}#adminmenu #awaiting-mod,#adminmenu .update-plugins,#sidemenu a .update-plugins,#rightnow .reallynow{background-color:#464646;color:#fff;-moz-box-shadow:#fff 0 -1px 0;-khtml-box-shadow:#fff 0 -1px 0;-webkit-box-shadow:#fff 0 -1px 0;box-shadow:#fff 0 -1px 0;}#plugin-information .action-button{background-color:#d54e21;color:#fff;}#adminmenu li.current a #awaiting-mod,#adminmenu li a.wp-has-current-submenu .update-plugins{background-color:#464646;color:#fff;-moz-box-shadow:#fff 0 -1px 0;-khtml-box-shadow:#fff 0 -1px 0;-webkit-box-shadow:#fff 0 -1px 0;box-shadow:#fff 0 -1px 0;}div#media-upload-header,div#plugin-information-header{background-color:#f9f9f9;border-bottom-color:#dfdfdf;}#currenttheme img{border-color:#666;}#dashboard_secondary div.dashboard-widget-content ul li a{background-color:#f9f9f9;}input.readonly,textarea.readonly{background-color:#ddd;}#ed_toolbar input,#ed_reply_toolbar input{background:#fff url("../images/fade-butt.png") repeat-x 0 -2px;}#editable-post-name{background-color:#fffbcc;}#edit-slug-box strong,.tablenav .displaying-num,#submitted-on,.submitted-on{color:#777;}.login #nav a{color:#21759b!important;}.login #nav a:hover{color:#d54e21!important;}#footer{color:#777;border-color:#d1d1d1;background:#d9d9d9;background:-moz-linear-gradient(bottom,#d7d7d7,#e4e4e4);background:-webkit-gradient(linear,left bottom,left top,from(#d7d7d7),to(#e4e4e4));}#media-items,.imgedit-group{border-color:#dfdfdf;}.checkbox,.side-info,.plugins tr,#your-profile #rich_editing{background-color:#fff;}.plugins .inactive,.plugins .inactive th,.plugins .inactive td,tr.inactive+tr.plugin-update-tr .plugin-update{background-color:#eee;}.plugin-update-tr .update-message{background-color:#fffbe4;border-color:#dfdfdf;}.plugins .active,.plugins .active th,.plugins .active td{color:#000;}.plugins .inactive a{color:#579;}#the-comment-list tr.undo,#the-comment-list div.undo{background-color:#f4f4f4;}#the-comment-list .unapproved{background-color:#ffffe0;}#the-comment-list .approve a{color:#006505;}#the-comment-list .unapprove a{color:#d98500;}table.widefat span.delete a,table.widefat span.trash a,table.widefat span.spam a,#dashboard_recent_comments .delete a,#dashboard_recent_comments .trash a,#dashboard_recent_comments .spam a{color:#bc0b0b;}.widget,#widget-list .widget-top,.postbox,#titlediv,#poststuff .postarea,.stuffbox{border-color:#dfdfdf;}.widget,.postbox{background-color:#fff;}.ui-sortable .postbox h3{color:#464646;}.widget .widget-top,.ui-sortable .postbox h3:hover{color:#000;}.curtime #timestamp{background-image:url(../images/date-button.gif);}#quicktags #ed_link{color:#00f;}#rightnow .youhave{background-color:#f0f6fb;}#rightnow a{color:#448abd;}.tagchecklist span a,#bulk-titles div a{background:url(../images/xit.gif) no-repeat;}.tagchecklist span a:hover,#bulk-titles div a:hover{background:url(../images/xit.gif) no-repeat -10px 0;}#update-nag,.update-nag{background-color:#FFFBCC;border-color:#E6DB55;color:#555;}.login #backtoblog a{color:#464646;}#wphead{border-bottom:#c6c6c6 1px solid;background:#d9d9d9;background:-moz-linear-gradient(bottom,#d7d7d7,#e4e4e4);background:-webkit-gradient(linear,left bottom,left top,from(#d7d7d7),to(#e4e4e4));}#wphead h1 a{color:#464646;}#user_info{color:#777;}#user_info a:link,#user_info a:visited,#footer a:link,#footer a:visited{color:#222;text-decoration:none;}#user_info a:hover,#footer a:hover{color:#000;text-decoration:underline!important;}div#media-upload-error,.file-error,abbr.required,.widget-control-remove:hover,table.widefat .delete a:hover,table.widefat .trash a:hover,table.widefat .spam a:hover,#dashboard_recent_comments .delete a:hover,#dashboard_recent_comments .trash a:hover #dashboard_recent_comments .spam a:hover{color:#f00;}#pass-strength-result{background-color:#eee;border-color:#ddd!important;}#pass-strength-result.bad{background-color:#ffb78c;border-color:#ff853c!important;}#pass-strength-result.good{background-color:#ffec8b;border-color:#fc0!important;}#pass-strength-result.short{background-color:#ffa0a0;border-color:#f04040!important;}#pass-strength-result.strong{background-color:#c3ff88;border-color:#8dff1c!important;}#quicktags{border-color:#dfdfdf;background-color:#dfdfdf;background-image:url("../images/ed-bg.gif");}#ed_toolbar input{border-color:#C3C3C3;}#ed_toolbar input:hover{border-color:#aaa;background:#ddd;}#poststuff .wp_themeSkin .mceStatusbar{border-color:#EDEDED;}#poststuff #edButtonPreview,#poststuff #edButtonHTML{background-color:#f1f1f1;border-color:#dfdfdf;color:#999;}#poststuff #editor-toolbar .active{border-bottom-color:#e9e9e9;background-color:#e9e9e9;color:#333;}#post-status-info{background-color:#EDEDED;}.wp_themeSkin *,.wp_themeSkin a:hover,.wp_themeSkin a:link,.wp_themeSkin a:visited,.wp_themeSkin a:active{color:#000;}.wp_themeSkin iframe{background:#fff;}.wp_themeSkin .mceStatusbar{color:#000;background-color:#f5f5f5;}.wp_themeSkin .mceButton{background-color:#e9e8e8;border-color:#B2B2B2;}.wp_themeSkin a.mceButtonEnabled:hover,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonSelected{background:#d5d5d5;border-color:#777!important;}.wp_themeSkin .mceButtonDisabled{border-color:#ccc!important;}.wp_themeSkin .mceListBox .mceText,.wp_themeSkin .mceListBox .mceOpen{border-color:#B2B2B2;background-color:#d5d5d5;}.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen,.wp_themeSkin .mceListBoxSelected .mceText{border-color:#777!important;background-color:#d5d5d5;}.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText{border-color:#777!important;}.wp_themeSkin select.mceListBox{border-color:#B2B2B2;background-color:#fff;}.wp_themeSkin .mceSplitButton a.mceAction,.wp_themeSkin .mceSplitButton a.mceOpen{border-color:#B2B2B2;}.wp_themeSkin .mceSplitButton a.mceOpen:hover,.wp_themeSkin .mceSplitButtonSelected a.mceOpen,.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction,.wp_themeSkin .mceSplitButton a.mceAction:hover{background-color:#d5d5d5;border-color:#777!important;}.wp_themeSkin .mceSplitButtonActive{background-color:#B2B2B2;}.wp_themeSkin div.mceColorSplitMenu table{background-color:#ebebeb;border-color:#B2B2B2;}.wp_themeSkin .mceColorSplitMenu a{border-color:#B2B2B2;}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors{border-color:#fff;}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover{border-color:#0A246A;background-color:#B6BDD2;}.wp_themeSkin a.mceMoreColors:hover{border-color:#0A246A;}.wp_themeSkin .mceMenu{border-color:#ddd;}.wp_themeSkin .mceMenu table{background-color:#ebeaeb;}.wp_themeSkin .mceMenu .mceText{color:#000;}.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover,.wp_themeSkin .mceMenu .mceMenuItemActive{background-color:#f5f5f5;}.wp_themeSkin td.mceMenuItemSeparator{background-color:#aaa;}.wp_themeSkin .mceMenuItemTitle a{background-color:#ccc;border-bottom-color:#aaa;}.wp_themeSkin .mceMenuItemTitle span.mceText{color:#000;}.wp_themeSkin .mceMenuItemDisabled .mceText{color:#888;}.wp_themeSkin tr.mceFirst td.mceToolbar{background:#dfdfdf url("../images/ed-bg.gif") repeat-x scroll left top;border-color:#dfdfdf;}.wp-admin #mceModalBlocker{background:#000;}.wp-admin .clearlooks2 .mceFocus .mceTop .mceLeft{background:#444;border-left:1px solid #999;border-top:1px solid #999;-moz-border-radius:4px 0 0 0;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px;}.wp-admin .clearlooks2 .mceFocus .mceTop .mceRight{background:#444;border-right:1px solid #999;border-top:1px solid #999;border-top-right-radius:4px;-khtml-border-top-right-radius:4px;-webkit-border-top-right-radius:4px;-moz-border-radius:0 4px 0 0;}.wp-admin .clearlooks2 .mceMiddle .mceLeft{background:#f1f1f1;border-left:1px solid #999;}.wp-admin .clearlooks2 .mceMiddle .mceRight{background:#f1f1f1;border-right:1px solid #999;}.wp-admin .clearlooks2 .mceBottom{background:#f1f1f1;border-bottom:1px solid #999;}.wp-admin .clearlooks2 .mceBottom .mceLeft{background:#f1f1f1;border-bottom:1px solid #999;border-left:1px solid #999;}.wp-admin .clearlooks2 .mceBottom .mceCenter{background:#f1f1f1;border-bottom:1px solid #999;}.wp-admin .clearlooks2 .mceBottom .mceRight{background:#f1f1f1;border-bottom:1px solid #999;border-right:1px solid #999;}.wp-admin .clearlooks2 .mceFocus .mceTop span{color:#e5e5e5;}#editorcontainer,#post-status-info,#titlediv #title,.editwidget .widget-inside{border-color:#dfdfdf;}#titlediv #title{background-color:#fff;}#tTips p#tTips_inside{background-color:#ddd;color:#333;}#timestampdiv input,#namediv input,#poststuff .inside .the-tagcloud{border-color:#ddd;}#adminmenu *{border-color:#e3e3e3;}#adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px;}.folded #adminmenu li.wp-menu-separator{background:transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px;}#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle,#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle{background:transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -207px;}#adminmenu .wp-has-submenu:hover .wp-menu-toggle,#adminmenu .wp-menu-open .wp-menu-toggle{background:transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -109px;}#adminmenu a.menu-top{background:#f1f1f1 url(../images/menu-bits.gif?ver=20100610) repeat-x scroll left -379px;}#adminmenu .wp-submenu a{background:#fff url(../images/menu-bits.gif?ver=20100610) no-repeat scroll 0 -310px;}#adminmenu .wp-has-current-submenu ul li a{background:none;}#adminmenu .wp-has-current-submenu ul li a.current{background:url(../images/menu-dark.gif) top left no-repeat!important;}.wp-has-current-submenu .wp-submenu{border-top:none!important;}#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu{border-bottom:#aaa 1px solid;}#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu,#adminmenu li.current a.menu-top{background:#e0e0e0 url(../images/menu-bits.gif?ver=20100610) top left repeat-x;border:#aaa 1px solid;color:#000;}#adminmenu li.wp-has-current-submenu .wp-submenu,#adminmenu li.wp-has-current-submenu ul li a{border-right-color:#aaa!important;border-left-color:#aaa!important;}#adminmenu li.wp-has-current-submenu ul li a{background:url(../images/menu-dark.gif) bottom left no-repeat!important;}#adminmenu li.wp-has-current-submenu ul{border-bottom-color:#aaa;}#adminmenu .wp-submenu .current a.current{background:transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll 0 -289px;}#adminmenu .wp-submenu a:hover{background-color:#EAF2FA!important;color:#333!important;}#adminmenu .wp-submenu li.current,#adminmenu .wp-submenu li.current a,#adminmenu .wp-submenu li.current a:hover{color:#333;background-color:#f5f5f5;background-image:none;border-color:#e3e3e3;}#adminmenu .wp-submenu ul{background-color:#fff;}.folded #adminmenu li.menu-top,#adminmenu .wp-submenu .wp-submenu-head{background-color:#F1F1F1;}.folded #adminmenu li.wp-has-current-submenu,.folded #adminmenu li.menu-top.current{background-color:#e6e6e6;}#adminmenu .wp-has-current-submenu .wp-submenu .wp-submenu-head{background-color:#EAEAEA;border-color:#aaa;}#adminmenu div.wp-submenu{background-color:transparent;}#adminmenu .menu-icon-dashboard div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -61px -33px;}#adminmenu .menu-icon-dashboard:hover div.wp-menu-image,#adminmenu .menu-icon-dashboard.wp-has-current-submenu div.wp-menu-image,#adminmenu .menu-icon-dashboard.current div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -61px -1px;}#adminmenu .menu-icon-post div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -272px -33px;}#adminmenu .menu-icon-post:hover div.wp-menu-image,#adminmenu .menu-icon-post.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -272px -1px;}#adminmenu .menu-icon-media div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -121px -33px;}#adminmenu .menu-icon-media:hover div.wp-menu-image,#adminmenu .menu-icon-media.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -121px -1px;}#adminmenu .menu-icon-links div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -91px -33px;}#adminmenu .menu-icon-links:hover div.wp-menu-image,#adminmenu .menu-icon-links.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -91px -1px;}#adminmenu .menu-icon-page div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -151px -33px;}#adminmenu .menu-icon-page:hover div.wp-menu-image,#adminmenu .menu-icon-page.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -151px -1px;}#adminmenu .menu-icon-comments div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -31px -33px;}#adminmenu .menu-icon-comments:hover div.wp-menu-image,#adminmenu .menu-icon-comments.wp-has-current-submenu div.wp-menu-image,#adminmenu .menu-icon-comments.current div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -31px -1px;}#adminmenu .menu-icon-appearance div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -1px -33px;}#adminmenu .menu-icon-appearance:hover div.wp-menu-image,#adminmenu .menu-icon-appearance.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -1px -1px;}#adminmenu .menu-icon-plugins div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -181px -33px;}#adminmenu .menu-icon-plugins:hover div.wp-menu-image,#adminmenu .menu-icon-plugins.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -181px -1px;}#adminmenu .menu-icon-users div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -301px -33px;}#adminmenu .menu-icon-users:hover div.wp-menu-image,#adminmenu .menu-icon-users.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -301px -1px;}#adminmenu .menu-icon-tools div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -211px -33px;}#adminmenu .menu-icon-tools:hover div.wp-menu-image,#adminmenu .menu-icon-tools.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -211px -1px;}#adminmenu .menu-icon-settings div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -241px -33px;}#adminmenu .menu-icon-settings:hover div.wp-menu-image,#adminmenu .menu-icon-settings.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -241px -1px;}#adminmenu .menu-icon-site div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -361px -33px;}#adminmenu .menu-icon-site:hover div.wp-menu-image,#adminmenu .menu-icon-site.wp-has-current-submenu div.wp-menu-image{background:transparent url('../images/menu.png?ver=20100531') no-repeat scroll -361px -1px;}table.diff .diff-deletedline{background-color:#fdd;}table.diff .diff-deletedline del{background-color:#f99;}table.diff .diff-addedline{background-color:#dfd;}table.diff .diff-addedline ins{background-color:#9f9;}#att-info{background-color:#E4F2FD;}#sidemenu a{background-color:#f9f9f9;border-color:#f9f9f9;border-bottom-color:#dfdfdf;}#sidemenu a.current{background-color:#fff;border-color:#dfdfdf #dfdfdf #fff;color:#D54E21;}#screen-options-wrap,#contextual-help-wrap{background-color:#f1f1f1;border-color:#dfdfdf;}#screen-meta-links a.show-settings{color:#606060;}#screen-meta-links a.show-settings:hover{color:#000;}#replysubmit{background-color:#f1f1f1;border-top-color:#ddd;}#replyerror{border-color:#ddd;background-color:#f9f9f9;}#edithead,#replyhead{background-color:#f1f1f1;}#ed_reply_toolbar{background-color:#e9e9e9;}.vim-current,.vim-current th,.vim-current td{background-color:#E4F2FD!important;}.star-average,.star.star-rating{background-color:#fc0;}div.star.select:hover{background-color:#d00;}#plugin-information .fyi ul{background-color:#eaf3fa;}#plugin-information .fyi h2.mainheader{background-color:#cee1ef;}#plugin-information pre,#plugin-information code{background-color:#ededff;}#plugin-information pre{border:1px solid #ccc;}.inline-edit-row fieldset input[type="text"],.inline-edit-row fieldset textarea,#bulk-titles,#replyrow input{border-color:#ddd;}.inline-editor div.title{background-color:#EAF3FA;}.inline-editor ul.cat-checklist{background-color:#fff;border-color:#ddd;}.inline-editor .categories .catshow,.inline-editor .categories .cathide{color:#21759b;}.inline-editor .quick-edit-save{background-color:#f1f1f1;}#replyrow #ed_reply_toolbar input:hover{border-color:#aaa;background:#ddd;}fieldset.inline-edit-col-right .inline-edit-col{border-color:#dfdfdf;}.attention{color:#D54E21;}.meta-box-sortables .postbox:hover .handlediv{background:transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -111px;}#major-publishing-actions{background:#eaf2fa;}.tablenav .tablenav-pages{color:#555;}.tablenav .tablenav-pages a{border-color:#e3e3e3;background:#eee url('../images/menu-bits.gif?ver=20100610') repeat-x scroll left -379px;}.tablenav .tablenav-pages a:hover,.tablenav .tablenav-pages a:focus{color:#d54e21;}.tablenav .tablenav-pages a.disabled,.tablenav .tablenav-pages a.disabled:hover,.tablenav .tablenav-pages a.disabled:focus{color:#aaa;}.tablenav .tablenav-pages .current{background:#dfdfdf;border-color:#d3d3d3;}#availablethemes,#availablethemes td{border-color:#ddd;}#current-theme img{border-color:#999;}#TB_window #TB_title a.tb-theme-preview-link,#TB_window #TB_title a.tb-theme-preview-link:visited{color:#999;}#TB_window #TB_title a.tb-theme-preview-link:hover,#TB_window #TB_title a.tb-theme-preview-link:focus{color:#ccc;}.misc-pub-section{border-bottom-color:#eee;}#minor-publishing{border-bottom-color:#ddd;}#post-body .misc-pub-section{border-right-color:#eee;}.post-com-count span{background-color:#bbb;}.form-table .color-palette td{border-color:#fff;}.sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;}#post-body ul.category-tabs li.tabs a,#post-body ul.add-menu-item-tabs li.tabs a,body.press-this ul.category-tabs li.tabs a{color:#333;}#wp_editimgbtn,#wp_delimgbtn,#wp_editgallery,#wp_delgallery{border-color:#999;background-color:#eee;}#wp_editimgbtn:hover,#wp_delimgbtn:hover,#wp_editgallery:hover,#wp_delgallery:hover{border-color:#555;background-color:#ccc;}#favorite-first{border-color:#c0c0c0;background:#f1f1f1;background:-moz-linear-gradient(bottom,#e7e7e7,#fff);background:-webkit-gradient(linear,left bottom,left top,from(#e7e7e7),to(#fff));}#favorite-inside{border-color:#c0c0c0;background-color:#fff;}#favorite-toggle{background:transparent url(../images/fav-arrow.gif?ver=20100531) no-repeat 0 -4px;}#favorite-actions a{color:#464646;}#favorite-actions a:hover{color:#000;}#favorite-inside a:hover{text-decoration:underline;}#screen-meta a.show-settings,.toggle-arrow{background-image:url("../images/screen-options-toggle.gif?ver=20100531");}#icon-edit,#icon-post{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -552px -5px;}#icon-index{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -137px -5px;}#icon-upload{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -251px -5px;}#icon-link-manager,#icon-link,#icon-link-category{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -190px -5px;}#icon-edit-pages,#icon-page{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -312px -5px;}#icon-edit-comments{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -72px -5px;}#icon-themes{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -11px -5px;}#icon-plugins{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -370px -5px;}#icon-users,#icon-profile,#icon-user-edit{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -600px -5px;}#icon-tools,#icon-admin{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -432px -5px;}#icon-options-general{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -492px -5px;}#icon-ms-admin{background:transparent url(../images/icons32.png?ver=20100531) no-repeat -659px -5px;}.view-switch #view-switch-list{background:transparent url(../images/list.png) no-repeat 0 0;}.view-switch .current #view-switch-list{background:transparent url(../images/list.png) no-repeat -40px 0;}.view-switch #view-switch-excerpt{background:transparent url(../images/list.png) no-repeat -20px 0;}.view-switch .current #view-switch-excerpt{background:transparent url(../images/list.png) no-repeat -60px 0;}#header-logo{background:transparent url(../images/wp-logo.png?ver=20100531) no-repeat scroll center center;}.popular-tags,.feature-filter{background-color:#fff;border-color:#DFDFDF;}#theme-information .action-button{border-top-color:#DFDFDF;}.theme-listing br.line{border-bottom-color:#ccc;}div.widgets-sortables,#widgets-left .inactive{background-color:#f1f1f1;border-color:#ddd;}#available-widgets .widget-holder{background-color:#fff;border-color:#ddd;}#widgets-left .sidebar-name{background-color:#aaa;background-image:url(../images/ed-bg.gif);text-shadow:#fff 0 1px 0;border-color:#dfdfdf;}#widgets-right .sidebar-name{background-image:url(../images/fav.png);text-shadow:#3f3f3f 0 -1px 0;background-color:#636363;border-color:#636363;color:#fff;}.sidebar-name:hover,#removing-widget{color:#d54e21;}#removing-widget span{color:black;}#widgets-left .sidebar-name-arrow{background:transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -109px;}#widgets-right .sidebar-name-arrow{background:transparent url(../images/widgets-arrow.gif?ver=20100531) no-repeat scroll 0 -1px;}.in-widget-title{color:#606060;}.deleting .widget-title *{color:#aaa;}.imgedit-menu div{border-color:#d5d5d5;background-color:#f1f1f1;}.imgedit-menu div:hover{border-color:#c1c1c1;background-color:#eaeaea;}.imgedit-menu div.disabled{border-color:#ccc;background-color:#ddd;filter:alpha(opacity=50);opacity:.5;}#dashboard_recent_comments div.undo{border-top-color:#dfdfdf;}.comment-ays,.comment-ays th{border-color:#ddd;}.comment-ays th{background-color:#f1f1f1;}#nav-menu-header,#nav-menu-footer,.menu-item-handle{background:url("../images/gray-grad.png") repeat-x scroll left top #dfdfdf;}#menu-management .nav-tab-active{background:#ececec;border-bottom-color:#ececec;} \ No newline at end of file diff --git a/src/wp-admin/css/colors-fresh.dev.css b/src/wp-admin/css/colors-fresh.dev.css new file mode 100644 index 00000000..63259178 --- /dev/null +++ b/src/wp-admin/css/colors-fresh.dev.css @@ -0,0 +1,1694 @@ +html, +.wp-dialog { + background-color: #f9f9f9; +} + +* html input, +* html .widget { + border-color: #dfdfdf; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="file"], +input[type="button"], +input[type="submit"], +input[type="reset"], +select { + border-color: #dfdfdf; + background-color: #fff; +} + +kbd, +code { + background: #eaeaea; +} + +input[readonly] { + background-color: #eee; +} + +.find-box-search { + border-color: #dfdfdf; + background-color: #f1f1f1; +} + +.find-box { + background-color: #f1f1f1; +} + +.find-box-inside { + background-color: #fff; +} + +a.page-numbers:hover { + border-color: #999; +} + +body, +#wpbody, +.form-table .pre { + color: #333; +} + +body > #upload-menu { + border-bottom-color: #fff; +} + +#postcustomstuff table, +#your-profile fieldset, +#rightnow, +div.dashboard-widget, +#dashboard-widgets p.dashboard-widget-links, +#replyrow #ed_reply_toolbar input { + border-color: #ccc; +} + +#poststuff .inside label.spam, +#poststuff .inside label.deleted { + color: red; +} + +#poststuff .inside label.waiting { + color: orange; +} + +#poststuff .inside label.approved { + color: green; +} + +#postcustomstuff table { + border-color: #dfdfdf; + background-color: #F9F9F9; +} + +#postcustomstuff thead th { + background-color: #F1F1F1; +} + +#postcustomstuff table input, +#postcustomstuff table textarea { + border-color: #dfdfdf; + background-color: #fff; +} + +.widefat { + border-color: #dfdfdf; + background-color: #fff; +} + +div.dashboard-widget-error { + background-color: #c43; +} + +div.dashboard-widget-notice { + background-color: #cfe1ef; +} + +div.dashboard-widget-submit { + border-top-color: #ccc; +} + +div.tabs-panel, +.wp-tab-panel, +ul.category-tabs li.tabs, +ul.add-menu-item-tabs li.tabs, +.wp-tab-active { + border-color: #dfdfdf; +} + +ul.category-tabs li.tabs, +ul.add-menu-item-tabs li.tabs, +.wp-tab-active { + background-color: #f1f1f1; +} + +input.disabled, +textarea.disabled { + background-color: #ccc; +} +/* #upload-menu li a.upload-tab-link, */ +#plugin-information .action-button a, +#plugin-information .action-button a:hover, +#plugin-information .action-button a:visited { + color: #fff; +} + +.widget .widget-top, +.postbox h3, +.stuffbox h3 { + background: #dfdfdf url("../images/gray-grad.png") repeat-x left top; + text-shadow: #fff 0 1px 0; +} + +.form-table th, +.form-wrap label { + color: #222; + text-shadow: #fff 0 1px 0; +} + +.description, +.form-wrap p { + color: #666; +} + +strong .post-com-count span { + background-color: #21759b; +} + +.sorthelper { + background-color: #ccf3fa; +} + +.ac_match, +.subsubsub a.current { + color: #000; +} + +.wrap h2 { + color: #464646; +} + +.ac_over { + background-color: #f0f0b8; +} + +.ac_results { + background-color: #fff; + border-color: #808080; +} + +.ac_results li { + color: #101010; +} + +.alternate, +.alt { + background-color: #f9f9f9; +} + +.available-theme a.screenshot { + background-color: #f1f1f1; + border-color: #ddd; +} + +.bar { + background-color: #e8e8e8; + border-right-color: #99d; +} + +#media-upload, +#media-upload .media-item .slidetoggle { + background: #fff; +} + +#media-upload .slidetoggle { + border-top-color: #dfdfdf; +} + +div.error, +.login #login_error { + background-color: #ffebe8; + border-color: #c00; +} + +div.error a { + color: #c00; +} + +.form-invalid { + background-color: #ffebe8 !important; +} + +.form-invalid input, +.form-invalid select { + border-color: #c00 !important; +} + +.submit { + border-color: #DFDFDF; +} + +.highlight { + background-color: #e4f2fd; + color: #000; +} + +.howto, +.nonessential, +#edit-slug-box, +.form-input-tip, +.rss-widget span.rss-date, +.subsubsub { + color: #666; +} + +.media-item { + border-bottom-color: #dfdfdf; +} + +#wpbody-content #media-items .describe { + border-top-color: #dfdfdf; +} + +.media-upload-form label.form-help, +td.help { + color: #9a9a9a; +} + +.post-com-count { + background-image: url(../images/bubble_bg.gif); + color: #fff; +} + +.post-com-count span { + background-color: #bbb; + color: #fff; +} + +.post-com-count:hover span { + background-color: #d54e21; +} + +.quicktags, .search { + background-color: #ccc; + color: #000; +} + +.side-info h5 { + border-bottom-color: #dadada; +} + +.side-info ul { + color: #666; +} + +.button, +.button-secondary, +.submit input, +input[type=button], +input[type=submit] { + border-color: #bbb; + color: #464646; +} + +.button:hover, +.button-secondary:hover, +.submit input:hover, +input[type=button]:hover, +input[type=submit]:hover { + color: #000; + border-color: #666; +} + +.button, +.submit input, +.button-secondary { + background: #f2f2f2 url(../images/white-grad.png) repeat-x scroll left top; + text-shadow: rgba(255,255,255,1) 0 1px 0; +} + +.button:active, +.submit input:active, +.button-secondary:active { + background: #eee url(../images/white-grad-active.png) repeat-x scroll left top; +} + +input.button-primary, +button.button-primary, +a.button-primary { + border-color: #298cba; + font-weight: bold; + color: #fff; + background: #21759B url(../images/button-grad.png) repeat-x scroll left top; + text-shadow: rgba(0,0,0,0.3) 0 -1px 0; +} + +input.button-primary:active, +button.button-primary:active, +a.button-primary:active { + background: #21759b url(../images/button-grad-active.png) repeat-x scroll left top; + color: #eaf2fa; +} + +input.button-primary:hover, +button.button-primary:hover, +a.button-primary:hover, +a.button-primary:focus, +a.button-primary:active { + border-color: #13455b; + color: #eaf2fa; +} + +.button-disabled, +.button[disabled], +.button:disabled, +.button-secondary[disabled], +.button-secondary:disabled, +a.button.disabled { + color: #aaa !important; + border-color: #ddd !important; +} + +.button-primary-disabled, +.button-primary[disabled], +.button-primary:disabled { + color: #9FD0D5 !important; + background: #298CBA !important; +} + +a:hover, +a:active, +a:focus { + color: #d54e21; +} + +#wphead #viewsite a:hover, +#adminmenu a:hover, +#adminmenu ul.wp-submenu a:hover, +#the-comment-list .comment a:hover, +#rightnow a:hover, +#media-upload a.del-link:hover, +div.dashboard-widget-submit input:hover, +.subsubsub a:hover, +.subsubsub a.current:hover, +.ui-tabs-nav a:hover, +.plugins .inactive a:hover, +#all-plugins-table .plugins .inactive a:hover, +#search-plugins-table .plugins .inactive a:hover { + color: #d54e21; +} + +#the-comment-list .comment-item, +#dashboard-widgets #dashboard_quick_press form p.submit { + border-color: #dfdfdf; +} + +#side-sortables .category-tabs .tabs a, +#side-sortables .add-menu-item-tabs .tabs a, +.wp-tab-bar .wp-tab-active a { + color: #333; +} + +#rightnow .rbutton { + background-color: #ebebeb; + color: #264761; +} + +.submitbox .submit { + background-color: #464646; + color: #ccc; +} + +.plugins a.delete:hover, +#all-plugins-table .plugins a.delete:hover, +#search-plugins-table .plugins a.delete:hover, +.submitbox .submitdelete { + color: #f00; + border-bottom-color: #f00; +} + +.submitbox .submitdelete:hover, +#media-items a.delete:hover { + color: #fff; + background-color: #f00; + border-bottom-color: #f00; +} + +#normal-sortables .submitbox .submitdelete:hover { + color: #000; + background-color: #f00; + border-bottom-color: #f00; +} + +.tablenav .dots { + border-color: transparent; +} + +.tablenav .next, +.tablenav .prev { + border-color: transparent; + color: #21759b; +} + +.tablenav .next:hover, +.tablenav .prev:hover { + border-color: transparent; + color: #d54e21; +} + +div.updated, +.login .message { + background-color: #ffffe0; + border-color: #e6db55; +} + +.update-message { + color: #000; +} + +a.page-numbers { + border-bottom-color: #B8D3E2; +} + +.commentlist li { + border-bottom-color: #ccc; +} + +.widefat td, +.widefat th { + border-color: #dfdfdf; +} + +.widefat th { + text-shadow: rgba(255,255,255,0.8) 0 1px 0; +} + +.widefat thead tr th, +.widefat tfoot tr th, +h3.dashboard-widget-title, +h3.dashboard-widget-title span, +h3.dashboard-widget-title small, +.find-box-head { + color: #333; + background: #dfdfdf url(../images/gray-grad.png) repeat-x scroll left top; +} + +th.sortable a:hover, th.sortable a:active, th.sortable a:focus { + color: #333; +} + +h3.dashboard-widget-title small a { + color: #d7d7d7; +} + +h3.dashboard-widget-title small a:hover { + color: #fff; +} + +a, +#adminmenu a, +#poststuff #edButtonPreview, +#poststuff #edButtonHTML, +#the-comment-list p.comment-author strong a, +#media-upload a.del-link, +#media-items a.delete, +.plugins a.delete, +.ui-tabs-nav a { + color: #21759b; +} + +#adminmenu #awaiting-mod, +#adminmenu .update-plugins, +#sidemenu a .update-plugins, +#rightnow .reallynow { + background-color: #464646; + color: #fff; + -moz-box-shadow: #fff 0 -1px 0; + -khtml-box-shadow: #fff 0 -1px 0; + -webkit-box-shadow: #fff 0 -1px 0; + box-shadow: #fff 0 -1px 0; +} +#plugin-information .action-button { + background-color: #d54e21; + color: #fff; +} + +#adminmenu li.current a #awaiting-mod, +#adminmenu li a.wp-has-current-submenu .update-plugins{ + background-color: #464646; + color: #fff; + -moz-box-shadow: #fff 0 -1px 0; + -khtml-box-shadow: #fff 0 -1px 0; + -webkit-box-shadow: #fff 0 -1px 0; + box-shadow: #fff 0 -1px 0; +} + +div#media-upload-header, +div#plugin-information-header { + background-color: #f9f9f9; + border-bottom-color: #dfdfdf; +} + +#currenttheme img { + border-color: #666; +} + +#dashboard_secondary div.dashboard-widget-content ul li a { + background-color: #f9f9f9; +} + +input.readonly, textarea.readonly { + background-color: #ddd; +} + +#ed_toolbar input, +#ed_reply_toolbar input { + background: #fff url("../images/fade-butt.png") repeat-x 0 -2px; +} + +#editable-post-name { + background-color: #fffbcc; +} + +#edit-slug-box strong, +.tablenav .displaying-num, +#submitted-on, +.submitted-on { + color: #777; +} + +.login #nav a { + color: #21759b !important; +} + +.login #nav a:hover { + color: #d54e21 !important; +} + +#footer { + color: #777; + border-color: #d1d1d1; + background: #d9d9d9; /* fallback color */ + background:-moz-linear-gradient(bottom, #d7d7d7, #e4e4e4); + background:-webkit-gradient(linear, left bottom, left top, from(#d7d7d7), to(#e4e4e4)); +} + +#media-items, +.imgedit-group { + border-color: #dfdfdf; +} + +.checkbox, +.side-info, +.plugins tr, +#your-profile #rich_editing { + background-color: #fff; +} + +.plugins .inactive, +.plugins .inactive th, +.plugins .inactive td, +tr.inactive + tr.plugin-update-tr .plugin-update { + background-color: #eee; +} + +.plugin-update-tr .update-message { + background-color: #fffbe4; + border-color: #dfdfdf; +} + +.plugins .active, +.plugins .active th, +.plugins .active td { + color: #000; +} + +.plugins .inactive a { + color: #557799; +} + +#the-comment-list tr.undo, +#the-comment-list div.undo { + background-color: #f4f4f4; +} + +#the-comment-list .unapproved { + background-color: #ffffe0; +} + +#the-comment-list .approve a { + color: #006505; +} + +#the-comment-list .unapprove a { + color: #d98500; +} + +table.widefat span.delete a, +table.widefat span.trash a, +table.widefat span.spam a, +#dashboard_recent_comments .delete a, +#dashboard_recent_comments .trash a, +#dashboard_recent_comments .spam a { + color: #bc0b0b; +} + +.widget, +#widget-list .widget-top, +.postbox, +#titlediv, +#poststuff .postarea, +.stuffbox { + border-color: #dfdfdf; +} + +.widget, +.postbox { + background-color: #fff; +} + +.ui-sortable .postbox h3 { + color: #464646; +} + +.widget .widget-top, +.ui-sortable .postbox h3:hover { + color: #000; +} + +.curtime #timestamp { + background-image: url(../images/date-button.gif); +} + +#quicktags #ed_link { + color: #00f; +} + +#rightnow .youhave { + background-color: #f0f6fb; +} + +#rightnow a { + color: #448abd; +} + +.tagchecklist span a, +#bulk-titles div a { + background: url(../images/xit.gif) no-repeat; +} + +.tagchecklist span a:hover, +#bulk-titles div a:hover { + background: url(../images/xit.gif) no-repeat -10px 0; +} + +#update-nag, .update-nag { + background-color: #FFFBCC; + border-color: #E6DB55; + color: #555; +} + +.login #backtoblog a { + color: #464646; +} + +#wphead { + border-bottom:#c6c6c6 1px solid; + background: #d9d9d9; /* fallback color */ + background:-moz-linear-gradient(bottom, #d7d7d7, #e4e4e4); + background:-webkit-gradient(linear, left bottom, left top, from(#d7d7d7), to(#e4e4e4)); +} + +#wphead h1 a { + color: #464646; +} + +#user_info { + color: #777; +} + +#user_info a:link, +#user_info a:visited, +#footer a:link, +#footer a:visited { + color: #222; + text-decoration: none; +} + +#user_info a:hover, +#footer a:hover { + color: #000; + text-decoration: underline !important; +} + +div#media-upload-error, +.file-error, +abbr.required, +.widget-control-remove:hover, +table.widefat .delete a:hover, +table.widefat .trash a:hover, +table.widefat .spam a:hover, +#dashboard_recent_comments .delete a:hover, +#dashboard_recent_comments .trash a:hover +#dashboard_recent_comments .spam a:hover { + color: #f00; +} + +#pass-strength-result { + background-color: #eee; + border-color: #ddd !important; +} + +#pass-strength-result.bad { + background-color: #ffb78c; + border-color: #ff853c !important; +} + +#pass-strength-result.good { + background-color: #ffec8b; + border-color: #fc0 !important; +} + +#pass-strength-result.short { + background-color: #ffa0a0; + border-color: #f04040 !important; +} + +#pass-strength-result.strong { + background-color: #c3ff88; + border-color: #8dff1c !important; +} + +/* editors */ +#quicktags { + border-color: #dfdfdf; + background-color: #dfdfdf; + background-image: url("../images/ed-bg.gif"); +} + +#ed_toolbar input { + border-color: #C3C3C3; +} + +#ed_toolbar input:hover { + border-color: #aaa; + background: #ddd; +} + +#poststuff .wp_themeSkin .mceStatusbar { + border-color: #EDEDED; +} + +#poststuff #edButtonPreview, +#poststuff #edButtonHTML { + background-color: #f1f1f1; + border-color: #dfdfdf; + color: #999; +} + +#poststuff #editor-toolbar .active { + border-bottom-color: #e9e9e9; + background-color: #e9e9e9; + color: #333; +} + +/* TinyMCE */ +#post-status-info { + background-color: #EDEDED; +} + +.wp_themeSkin *, +.wp_themeSkin a:hover, +.wp_themeSkin a:link, +.wp_themeSkin a:visited, +.wp_themeSkin a:active { + color: #000; +} + +/* Containers */ +.wp_themeSkin iframe { + background: #fff; +} + +/* Layout */ +.wp_themeSkin .mceStatusbar { + color: #000; + background-color: #f5f5f5; +} + +/* Button */ +.wp_themeSkin .mceButton { + background-color: #e9e8e8; + border-color: #B2B2B2; +} + +.wp_themeSkin a.mceButtonEnabled:hover, +.wp_themeSkin a.mceButtonActive, +.wp_themeSkin a.mceButtonSelected { + background: #d5d5d5; + border-color: #777 !important; +} + +.wp_themeSkin .mceButtonDisabled { + border-color: #ccc !important; +} + +/* ListBox */ +.wp_themeSkin .mceListBox .mceText, +.wp_themeSkin .mceListBox .mceOpen { + border-color: #B2B2B2; + background-color: #d5d5d5; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen, +.wp_themeSkin .mceListBoxHover .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceText { + border-color: #777 !important; + background-color: #d5d5d5; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceText, +.wp_themeSkin .mceListBoxHover .mceText { + border-color: #777 !important; +} + +.wp_themeSkin select.mceListBox { + border-color: #B2B2B2; + background-color: #fff; +} + +/* SplitButton */ +.wp_themeSkin .mceSplitButton a.mceAction, +.wp_themeSkin .mceSplitButton a.mceOpen { + border-color: #B2B2B2; +} + +.wp_themeSkin .mceSplitButton a.mceOpen:hover, +.wp_themeSkin .mceSplitButtonSelected a.mceOpen, +.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction, +.wp_themeSkin .mceSplitButton a.mceAction:hover { + background-color: #d5d5d5; + border-color: #777 !important; +} + +.wp_themeSkin .mceSplitButtonActive { + background-color: #B2B2B2; +} + +/* ColorSplitButton */ +.wp_themeSkin div.mceColorSplitMenu table { + background-color: #ebebeb; + border-color: #B2B2B2; +} + +.wp_themeSkin .mceColorSplitMenu a { + border-color: #B2B2B2; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors { + border-color: #fff; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover { + border-color: #0A246A; + background-color: #B6BDD2; +} + +.wp_themeSkin a.mceMoreColors:hover { + border-color: #0A246A; +} + +/* Menu */ +.wp_themeSkin .mceMenu { + border-color: #ddd; +} + +.wp_themeSkin .mceMenu table { + background-color: #ebeaeb; +} + +.wp_themeSkin .mceMenu .mceText { + color: #000; +} + +.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover, +.wp_themeSkin .mceMenu .mceMenuItemActive { + background-color: #f5f5f5; +} +.wp_themeSkin td.mceMenuItemSeparator { + background-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle a { + background-color: #ccc; + border-bottom-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle span.mceText { + color: #000; +} +.wp_themeSkin .mceMenuItemDisabled .mceText { + color: #888; +} + +.wp_themeSkin tr.mceFirst td.mceToolbar { + background: #dfdfdf url("../images/ed-bg.gif") repeat-x scroll left top; + border-color: #dfdfdf; +} + +.wp-admin #mceModalBlocker { + background: #000; +} + +.wp-admin .clearlooks2 .mceFocus .mceTop .mceLeft { + background: #444444; + border-left: 1px solid #999; + border-top: 1px solid #999; + -moz-border-radius: 4px 0 0 0; + -webkit-border-top-left-radius: 4px; + -khtml-border-top-left-radius: 4px; + border-top-left-radius: 4px; +} + +.wp-admin .clearlooks2 .mceFocus .mceTop .mceRight { + background: #444444; + border-right: 1px solid #999; + border-top: 1px solid #999; + border-top-right-radius: 4px; + -khtml-border-top-right-radius: 4px; + -webkit-border-top-right-radius: 4px; + -moz-border-radius: 0 4px 0 0; +} + +.wp-admin .clearlooks2 .mceMiddle .mceLeft { + background: #f1f1f1; + border-left: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceMiddle .mceRight { + background: #f1f1f1; + border-right: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom { + background: #f1f1f1; + border-bottom: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom .mceLeft { + background: #f1f1f1; + border-bottom: 1px solid #999; + border-left: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom .mceCenter { + background: #f1f1f1; + border-bottom: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceBottom .mceRight { + background: #f1f1f1; + border-bottom: 1px solid #999; + border-right: 1px solid #999; +} + +.wp-admin .clearlooks2 .mceFocus .mceTop span { + color: #e5e5e5; +} +/* end TinyMCE */ + +#editorcontainer, +#post-status-info, +#titlediv #title, +.editwidget .widget-inside { + border-color: #dfdfdf; +} + +#titlediv #title { + background-color: #fff; +} + +#tTips p#tTips_inside { + background-color: #ddd; + color: #333; +} + +#timestampdiv input, +#namediv input, +#poststuff .inside .the-tagcloud { + border-color: #ddd; +} + +/* menu */ +#adminmenu * { + border-color: #e3e3e3; +} + +#adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll left 5px; +} + +.folded #adminmenu li.wp-menu-separator { + background: transparent url(../images/menu-arrows.gif) no-repeat scroll right -34px; +} + +#adminmenu li.wp-has-current-submenu.wp-menu-open .wp-menu-toggle, +#adminmenu li.wp-has-current-submenu:hover .wp-menu-toggle { + background: transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -207px; +} + +#adminmenu .wp-has-submenu:hover .wp-menu-toggle, +#adminmenu .wp-menu-open .wp-menu-toggle { + background: transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -109px; +} + +#adminmenu a.menu-top { + background: #f1f1f1 url(../images/menu-bits.gif?ver=20100610) repeat-x scroll left -379px; +} + +#adminmenu .wp-submenu a { + background: #fff url(../images/menu-bits.gif?ver=20100610) no-repeat scroll 0 -310px; +} + +#adminmenu .wp-has-current-submenu ul li a { + background: none; +} + +#adminmenu .wp-has-current-submenu ul li a.current { + background: url(../images/menu-dark.gif) top left no-repeat !important; +} + +.wp-has-current-submenu .wp-submenu { + border-top: none !important; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu { + border-bottom: #aaa 1px solid; +} + +#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu, +#adminmenu li.current a.menu-top { + background: #e0e0e0 url(../images/menu-bits.gif?ver=20100610) top left repeat-x; + border: #aaa 1px solid; + color: #000; +} + +#adminmenu li.wp-has-current-submenu .wp-submenu, +#adminmenu li.wp-has-current-submenu ul li a { + border-right-color: #aaa !important; + border-left-color: #aaa !important; +} + +#adminmenu li.wp-has-current-submenu ul li a { + background: url(../images/menu-dark.gif) bottom left no-repeat !important; +} + +#adminmenu li.wp-has-current-submenu ul { + border-bottom-color: #aaa; +} + +#adminmenu .wp-submenu .current a.current { + background: transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll 0 -289px; +} + +#adminmenu .wp-submenu a:hover { + background-color: #EAF2FA !important; + color: #333 !important; +} + +#adminmenu .wp-submenu li.current, +#adminmenu .wp-submenu li.current a, +#adminmenu .wp-submenu li.current a:hover { + color: #333; + background-color: #f5f5f5; + background-image: none; + border-color: #e3e3e3; +} + +#adminmenu .wp-submenu ul { + background-color: #fff; +} + +.folded #adminmenu li.menu-top, +#adminmenu .wp-submenu .wp-submenu-head { + background-color: #F1F1F1; +} + +.folded #adminmenu li.wp-has-current-submenu, +.folded #adminmenu li.menu-top.current { + background-color: #e6e6e6; +} + +#adminmenu .wp-has-current-submenu .wp-submenu .wp-submenu-head { + background-color: #EAEAEA; + border-color: #aaa; +} + +#adminmenu div.wp-submenu { + background-color: transparent; +} + +/* menu icons */ +#adminmenu .menu-icon-dashboard div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -61px -33px; +} + +#adminmenu .menu-icon-dashboard:hover div.wp-menu-image, +#adminmenu .menu-icon-dashboard.wp-has-current-submenu div.wp-menu-image, +#adminmenu .menu-icon-dashboard.current div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -61px -1px; +} + +#adminmenu .menu-icon-post div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -272px -33px; +} + +#adminmenu .menu-icon-post:hover div.wp-menu-image, +#adminmenu .menu-icon-post.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -272px -1px; +} + +#adminmenu .menu-icon-media div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -121px -33px; +} + +#adminmenu .menu-icon-media:hover div.wp-menu-image, +#adminmenu .menu-icon-media.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -121px -1px; +} + +#adminmenu .menu-icon-links div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -91px -33px; +} + +#adminmenu .menu-icon-links:hover div.wp-menu-image, +#adminmenu .menu-icon-links.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -91px -1px; +} + +#adminmenu .menu-icon-page div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -151px -33px; +} + +#adminmenu .menu-icon-page:hover div.wp-menu-image, +#adminmenu .menu-icon-page.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -151px -1px; +} + +#adminmenu .menu-icon-comments div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -31px -33px; +} + +#adminmenu .menu-icon-comments:hover div.wp-menu-image, +#adminmenu .menu-icon-comments.wp-has-current-submenu div.wp-menu-image, +#adminmenu .menu-icon-comments.current div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -31px -1px; +} + +#adminmenu .menu-icon-appearance div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -1px -33px; +} + +#adminmenu .menu-icon-appearance:hover div.wp-menu-image, +#adminmenu .menu-icon-appearance.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -1px -1px; +} + +#adminmenu .menu-icon-plugins div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -181px -33px; +} + +#adminmenu .menu-icon-plugins:hover div.wp-menu-image, +#adminmenu .menu-icon-plugins.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -181px -1px; +} + +#adminmenu .menu-icon-users div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -301px -33px; +} + +#adminmenu .menu-icon-users:hover div.wp-menu-image, +#adminmenu .menu-icon-users.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -301px -1px; +} + +#adminmenu .menu-icon-tools div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -211px -33px; +} + +#adminmenu .menu-icon-tools:hover div.wp-menu-image, +#adminmenu .menu-icon-tools.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -211px -1px; +} + +#adminmenu .menu-icon-settings div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -241px -33px; +} + +#adminmenu .menu-icon-settings:hover div.wp-menu-image, +#adminmenu .menu-icon-settings.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -241px -1px; +} + +#adminmenu .menu-icon-site div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -361px -33px; +} + +#adminmenu .menu-icon-site:hover div.wp-menu-image, +#adminmenu .menu-icon-site.wp-has-current-submenu div.wp-menu-image { + background: transparent url('../images/menu.png?ver=20100531') no-repeat scroll -361px -1px; +} +/* end menu */ + + +/* Diff */ +table.diff .diff-deletedline { + background-color: #fdd; +} + +table.diff .diff-deletedline del { + background-color: #f99; +} + +table.diff .diff-addedline { + background-color: #dfd; +} + +table.diff .diff-addedline ins { + background-color: #9f9; +} + +#att-info { + background-color: #E4F2FD; +} + +/* edit image */ +#sidemenu a { + background-color: #f9f9f9; + border-color: #f9f9f9; + border-bottom-color: #dfdfdf; +} + +#sidemenu a.current { + background-color: #fff; + border-color: #dfdfdf #dfdfdf #fff; + color: #D54E21; +} + +#screen-options-wrap, +#contextual-help-wrap { + background-color: #f1f1f1; + border-color: #dfdfdf; +} + +#screen-meta-links a.show-settings { + color: #606060; +} + +#screen-meta-links a.show-settings:hover { + color: #000; +} + +#replysubmit { + background-color: #f1f1f1; + border-top-color: #ddd; +} + +#replyerror { + border-color: #ddd; + background-color: #f9f9f9; +} + +#edithead, +#replyhead { + background-color: #f1f1f1; +} + +#ed_reply_toolbar { + background-color: #e9e9e9; +} + +/* table vim shortcuts */ +.vim-current, +.vim-current th, +.vim-current td { + background-color: #E4F2FD !important; +} + +/* Install Plugins */ +.star-average, +.star.star-rating { + background-color: #fc0; +} + +div.star.select:hover { + background-color: #d00; +} + +#plugin-information .fyi ul { + background-color: #eaf3fa; +} + +#plugin-information .fyi h2.mainheader { + background-color: #cee1ef; +} + +#plugin-information pre, +#plugin-information code { + background-color: #ededff; +} + +#plugin-information pre { + border: 1px solid #ccc; +} + +/* inline editor */ +.inline-edit-row fieldset input[type="text"], +.inline-edit-row fieldset textarea, +#bulk-titles, +#replyrow input { + border-color: #ddd; +} + +.inline-editor div.title { + background-color: #EAF3FA; +} + +.inline-editor ul.cat-checklist { + background-color: #fff; + border-color: #ddd; +} + +.inline-editor .categories .catshow, +.inline-editor .categories .cathide { + color: #21759b; +} + +.inline-editor .quick-edit-save { + background-color: #f1f1f1; +} + +#replyrow #ed_reply_toolbar input:hover { + border-color: #aaa; + background: #ddd; +} + +fieldset.inline-edit-col-right .inline-edit-col { + border-color: #dfdfdf; +} + +.attention { + color: #D54E21; +} + +.meta-box-sortables .postbox:hover .handlediv { + background: transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -111px; +} + +#major-publishing-actions { + background: #eaf2fa; +} + +.tablenav .tablenav-pages { + color: #555; +} + +.tablenav .tablenav-pages a { + border-color: #e3e3e3; + background: #eee url('../images/menu-bits.gif?ver=20100610') repeat-x scroll left -379px; +} + +.tablenav .tablenav-pages a:hover, +.tablenav .tablenav-pages a:focus { + color: #d54e21; +} + +.tablenav .tablenav-pages a.disabled, +.tablenav .tablenav-pages a.disabled:hover, +.tablenav .tablenav-pages a.disabled:focus { + color: #aaa; +} + +.tablenav .tablenav-pages .current { + background: #dfdfdf; + border-color: #d3d3d3; +} + +#availablethemes, +#availablethemes td { + border-color: #ddd; +} + +#current-theme img { + border-color: #999; +} + +#TB_window #TB_title a.tb-theme-preview-link, +#TB_window #TB_title a.tb-theme-preview-link:visited { + color: #999; +} + +#TB_window #TB_title a.tb-theme-preview-link:hover, +#TB_window #TB_title a.tb-theme-preview-link:focus { + color: #ccc; +} + +.misc-pub-section { + border-bottom-color: #eee; +} + +#minor-publishing { + border-bottom-color: #ddd; +} + +#post-body .misc-pub-section { + border-right-color: #eee; +} + +.post-com-count span { + background-color: #bbb; +} + +.form-table .color-palette td { + border-color: #fff; +} + +.sortable-placeholder { + border-color: #bbb; + background-color: #f5f5f5; +} + +#post-body ul.category-tabs li.tabs a, +#post-body ul.add-menu-item-tabs li.tabs a, +body.press-this ul.category-tabs li.tabs a { + color: #333; +} + +#wp_editimgbtn, +#wp_delimgbtn, +#wp_editgallery, +#wp_delgallery { + border-color: #999; + background-color: #eee; +} + +#wp_editimgbtn:hover, +#wp_delimgbtn:hover, +#wp_editgallery:hover, +#wp_delgallery:hover { + border-color: #555; + background-color: #ccc; +} + +#favorite-first { + border-color: #c0c0c0; + background: #f1f1f1; /* fallback color */ + background:-moz-linear-gradient(bottom, #e7e7e7, #fff); + background:-webkit-gradient(linear, left bottom, left top, from(#e7e7e7), to(#fff)); +} + +#favorite-inside { + border-color: #c0c0c0; + background-color: #fff; +} + +#favorite-toggle { + background: transparent url(../images/fav-arrow.gif?ver=20100531) no-repeat 0 -4px; +} + +#favorite-actions a { + color: #464646; +} + +#favorite-actions a:hover { + color: #000; +} + +#favorite-inside a:hover { + text-decoration: underline; +} + +#screen-meta a.show-settings, +.toggle-arrow { + background-image:url("../images/screen-options-toggle.gif?ver=20100531"); +} + +#icon-edit, +#icon-post { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -552px -5px; +} + +#icon-index { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -137px -5px; +} + +#icon-upload { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -251px -5px; +} + +#icon-link-manager, +#icon-link, +#icon-link-category { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -190px -5px; +} + +#icon-edit-pages, +#icon-page { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -312px -5px; +} + +#icon-edit-comments { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -72px -5px; +} + +#icon-themes { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -11px -5px; +} + +#icon-plugins { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -370px -5px; +} + +#icon-users, +#icon-profile, +#icon-user-edit { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -600px -5px; +} + +#icon-tools, +#icon-admin { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -432px -5px; +} + +#icon-options-general { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -492px -5px; +} + +#icon-ms-admin { + background: transparent url(../images/icons32.png?ver=20100531) no-repeat -659px -5px; +} + +.view-switch #view-switch-list { + background: transparent url(../images/list.png) no-repeat 0 0; +} + +.view-switch .current #view-switch-list { + background: transparent url(../images/list.png) no-repeat -40px 0; +} + +.view-switch #view-switch-excerpt { + background: transparent url(../images/list.png) no-repeat -20px 0; +} + +.view-switch .current #view-switch-excerpt { + background: transparent url(../images/list.png) no-repeat -60px 0; +} + +#header-logo { + background: transparent url(../images/wp-logo.png?ver=20100531) no-repeat scroll center center; +} + +.popular-tags, +.feature-filter { + background-color: #fff; + border-color: #DFDFDF; +} + +#theme-information .action-button { + border-top-color: #DFDFDF; +} + +.theme-listing br.line { + border-bottom-color: #ccc; +} + +div.widgets-sortables, +#widgets-left .inactive { + background-color: #f1f1f1; + border-color: #ddd; +} + +#available-widgets .widget-holder { + background-color: #fff; + border-color: #ddd; +} + +#widgets-left .sidebar-name { + background-color: #aaa; + background-image: url(../images/ed-bg.gif); + text-shadow: #fff 0 1px 0; + border-color: #dfdfdf; +} + +#widgets-right .sidebar-name { + background-image: url(../images/fav.png); + text-shadow: #3f3f3f 0 -1px 0; + background-color: #636363; + border-color: #636363; + color: #fff; +} + +.sidebar-name:hover, +#removing-widget { + color: #d54e21; +} + +#removing-widget span { + color: black; +} + +#widgets-left .sidebar-name-arrow { + background: transparent url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -109px; +} + +#widgets-right .sidebar-name-arrow { + background: transparent url(../images/widgets-arrow.gif?ver=20100531) no-repeat scroll 0 -1px; +} + +.in-widget-title { + color: #606060; +} + +.deleting .widget-title * { + color: #aaa; +} + +.imgedit-menu div { + border-color: #d5d5d5; + background-color: #f1f1f1; +} + +.imgedit-menu div:hover { + border-color: #c1c1c1; + background-color: #eaeaea; +} + +.imgedit-menu div.disabled { + border-color: #ccc; + background-color: #ddd; + filter: alpha(opacity=50); + opacity: 0.5; +} + +#dashboard_recent_comments div.undo { + border-top-color: #dfdfdf; +} + +.comment-ays, +.comment-ays th { + border-color: #ddd; +} + +.comment-ays th { + background-color: #f1f1f1; +} + +#nav-menu-header, #nav-menu-footer, .menu-item-handle { + background: url("../images/gray-grad.png") repeat-x scroll left top #dfdfdf; +} + +#menu-management .nav-tab-active { + background: #ececec; + border-bottom-color: #ececec; +} diff --git a/src/wp-admin/css/dashboard-rtl.css b/src/wp-admin/css/dashboard-rtl.css new file mode 100644 index 00000000..f7c4949a --- /dev/null +++ b/src/wp-admin/css/dashboard-rtl.css @@ -0,0 +1 @@ +#dashboard-widgets-wrap .has-sidebar{margin-right:0;margin-left:-51%;}#dashboard-widgets-wrap .has-sidebar .has-sidebar-content{margin-right:0;margin-left:51%;}.view-all{right:auto;left:0;}#dashboard_right_now p.sub,#dashboard-widgets h4,#dashboard_quick_press h4,a.rsswidget,#dashboard_plugins h4,#dashboard_plugins h5,#dashboard_recent_comments .comment-meta .approve{font-family:Tahoma,Arial;}#dashboard_right_now p.sub{font-style:normal;left:auto;right:15px;}#dashboard_right_now td.b{padding-right:0;padding-left:6px;text-align:left;font-family:Tahoma,Arial;}#dashboard_right_now .t{padding-right:0;padding-left:12px;}#dashboard_right_now .table_content{float:right;}#dashboard_right_now .table_discussion{float:left;}#dashboard_right_now .versions a{font-family:Tahoma,Arial;}#dashboard_right_now a.button{float:left;clear:left;}#dashboard-widgets h3 .postbox-title-action{right:auto;left:30px;}#the-comment-list .pingback{padding-left:0!important;padding-right:9px!important;}#the-comment-list .comment-item{padding:1em 70px 1em 10px;}#the-comment-list .comment-item .avatar{float:right;margin-left:0;margin-right:-60px;}.rss-widget cite{text-align:left;}.rss-widget span.rss-date{font-family:Tahoma,Arial;margin-left:0;margin-right:3px;}#dashboard_quick_press h4{float:right;text-align:left;}#dashboard_quick_press h4 label{margin-right:0;margin-left:10px;}#dashboard_quick_press .input-text-wrap,#dashboard_quick_press .textarea-wrap{margin:0 5em 1em 0;}#dashboard_quick_press #media-buttons{margin:0 5em .5em 0;padding:0 10px 0 0;}#dashboard-widgets #dashboard_quick_press form p.submit{margin-left:0;margin-right:4.6em;}#dashboard-widgets #dashboard_quick_press form p.submit input{float:right;}#dashboard-widgets #dashboard_quick_press form p.submit #save-post{margin:0 10px 0 1em;}#dashboard-widgets #dashboard_quick_press form p.submit #publish{float:left;}#dashboard-widgets #dashboard_quick_press form p.submit img.waiting{margin:4px 0 0 6px;}#dashboard_recent_drafts h4 abbr{font-family:Tahoma,Arial;margin-left:0;margin-right:3px;} \ No newline at end of file diff --git a/src/wp-admin/css/dashboard-rtl.dev.css b/src/wp-admin/css/dashboard-rtl.dev.css new file mode 100644 index 00000000..b0219f2a --- /dev/null +++ b/src/wp-admin/css/dashboard-rtl.dev.css @@ -0,0 +1,107 @@ +#dashboard-widgets-wrap .has-sidebar { + margin-right: 0; + margin-left: -51%; +} +#dashboard-widgets-wrap .has-sidebar .has-sidebar-content { + margin-right: 0; + margin-left: 51%; +} +.view-all { + right: auto; + left: 0; +} +#dashboard_right_now p.sub, #dashboard-widgets h4, #dashboard_quick_press h4, a.rsswidget, #dashboard_plugins h4, #dashboard_plugins h5, #dashboard_recent_comments .comment-meta .approve { + font-family: Tahoma, Arial; +} +#dashboard_right_now p.sub { + font-style:normal; + left:auto; + right:15px; +} +#dashboard_right_now td.b { + padding-right: 0; + padding-left: 6px; + text-align: left; + font-family: Tahoma, Arial; +} +#dashboard_right_now .t { + padding-right: 0; + padding-left: 12px; +} +#dashboard_right_now .table_content { + float:right; +} +#dashboard_right_now .table_discussion { + float:left; +} +#dashboard_right_now .versions a { + font-family: Tahoma, Arial; +} +#dashboard_right_now a.button { + float: left; + clear: left; +} +#dashboard-widgets h3 .postbox-title-action { + right: auto; + left: 30px; +} +#the-comment-list .pingback { + padding-left: 0 !important; + padding-right: 9px !important; +} +/* Recent Comments */ +#the-comment-list .comment-item { + padding: 1em 70px 1em 10px; +} +#the-comment-list .comment-item .avatar { + float: right; + margin-left: 0; + margin-right: -60px; +} +/* Feeds */ +.rss-widget cite { + text-align: left; +} +.rss-widget span.rss-date { + font-family: Tahoma, Arial; + margin-left: 0; + margin-right: 3px; +} +/* QuickPress */ +#dashboard_quick_press h4 { + float: right; + text-align: left; +} +#dashboard_quick_press h4 label { + margin-right: 0; + margin-left: 10px; +} +#dashboard_quick_press .input-text-wrap, #dashboard_quick_press .textarea-wrap { + margin: 0 5em 1em 0; +} +#dashboard_quick_press #media-buttons { + margin: 0 5em .5em 0; + padding: 0 10px 0 0; +} +#dashboard-widgets #dashboard_quick_press form p.submit { + margin-left: 0; + margin-right: 4.6em; +} +#dashboard-widgets #dashboard_quick_press form p.submit input { + float: right; +} +#dashboard-widgets #dashboard_quick_press form p.submit #save-post { + margin: 0 10px 0 1em; +} +#dashboard-widgets #dashboard_quick_press form p.submit #publish { + float: left; +} +#dashboard-widgets #dashboard_quick_press form p.submit img.waiting { + margin: 4px 0 0 6px; +} +/* Recent Drafts */ +#dashboard_recent_drafts h4 abbr { + font-family: Tahoma, Arial; + margin-left:0; + margin-right: 3px; +} \ No newline at end of file diff --git a/src/wp-admin/css/dashboard.css b/src/wp-admin/css/dashboard.css new file mode 100644 index 00000000..4d8ffddf --- /dev/null +++ b/src/wp-admin/css/dashboard.css @@ -0,0 +1 @@ +.postbox p,.postbox ul,.postbox ol,.postbox blockquote,#wp-version-message{font-size:11px;}.edit-box{display:none;}h3:hover .edit-box{display:inline;}form .input-text-wrap{border-style:solid;border-width:1px;padding:2px 3px;border-color:#ccc;}#dashboard-widgets form .input-text-wrap input{border:0 none;outline:none;margin:0;padding:0;width:99%;color:#333;}form .textarea-wrap{border-style:solid;border-width:1px;padding:2px;border-color:#ccc;}#dashboard-widgets form .textarea-wrap textarea{border:0 none;padding:0;outline:none;width:99%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;}#dashboard-widgets .postbox form .submit{float:none;margin:.5em 0 0;padding:0;border:none;}#dashboard-widgets-wrap #dashboard-widgets .postbox form .submit input{margin:0;}#dashboard-widgets-wrap #dashboard-widgets .postbox form .submit #publish{min-width:0;}div.postbox div.inside{margin:10px;position:relative;}#dashboard-widgets a{text-decoration:none;}#dashboard-widgets h3 a{text-decoration:underline;}#dashboard-widgets h3 .postbox-title-action{position:absolute;right:30px;padding:0;}#dashboard-widgets h4{font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-size:13px;margin:0 0 .2em;padding:0;}#dashboard_right_now p.sub,#dashboard_right_now .table,#dashboard_right_now .versions{margin:-12px;}#dashboard_right_now .inside{font-size:12px;padding-top:20px;}#dashboard_right_now p.sub{font-style:italic;font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;padding:5px 10px 15px;color:#777;font-size:13px;position:absolute;top:-17px;left:15px;}#dashboard_right_now .table{margin:0 -9px;padding:0 10px;position:relative;}#dashboard_right_now .table_content{float:left;border-top:#ececec 1px solid;width:45%;}#dashboard_right_now .table_discussion{float:right;border-top:#ececec 1px solid;width:45%;}#dashboard_right_now table td{padding:3px 0;white-space:nowrap;}#dashboard_right_now table tr.first td{border-top:none;}#dashboard_right_now td.b{padding-right:6px;text-align:right;font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-size:14px;width:1%;}#dashboard_right_now td.b a{font-size:18px;}#dashboard_right_now td.b a:hover{color:#d54e21;}#dashboard_right_now .t{font-size:12px;padding-right:12px;padding-top:6px;color:#777;}#dashboard_right_now .t a{white-space:nowrap;}#dashboard_right_now .spam{color:red;}#dashboard_right_now .waiting{color:#e66f00;}#dashboard_right_now .approved{color:green;}#dashboard_right_now .versions{padding:6px 10px 12px;clear:both;}#dashboard_right_now .versions .b{font-weight:bold;}#dashboard_right_now a.button{float:right;clear:right;position:relative;top:-5px;}#dashboard_recent_comments h3{margin-bottom:0;}#dashboard_recent_comments .inside{margin-top:0;}#dashboard_recent_comments .comment-meta .approve{font-style:italic;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-size:10px;}#the-comment-list{position:relative;}#the-comment-list .comment-item{padding:1em 10px;border-top:1px solid;}#the-comment-list .pingback{padding-left:9px!important;}#the-comment-list .comment-item,#the-comment-list #replyrow{margin:0 -10px;}#the-comment-list .comment-item:first-child{border-top:none;}#the-comment-list .comment-item .avatar{float:left;margin:0 10px 5px 0;}#the-comment-list .comment-item h4{line-height:1.4;margin-top:-.2em;font-weight:normal;color:#999;}#the-comment-list .comment-item h4 cite{font-style:normal;font-weight:normal;}#the-comment-list .comment-item blockquote,#the-comment-list .comment-item blockquote p{margin:0;padding:0;display:inline;}#dashboard_recent_comments #the-comment-list .trackback blockquote,#dashboard_recent_comments #the-comment-list .pingback blockquote{display:block;}#the-comment-list .comment-item p.row-actions{margin:3px 0 0;padding:0;font-size:10px;}#dashboard_quick_press h4{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;float:left;width:5.5em;clear:both;font-weight:normal;text-align:right;padding-top:5px;font-size:12px;}#dashboard_quick_press h4 label{margin-right:10px;}#dashboard_quick_press{min-height:200px;}#dashboard_quick_press.closed{min-height:0;}#dashboard_quick_press .input-text-wrap,#dashboard_quick_press .textarea-wrap{margin:0 0 1em 5em;}#dashboard_quick_press #media-buttons{margin:0 0 .5em 5em;padding:0 0 0 10px;font-size:11px;}#dashboard_quick_press #media-buttons a{vertical-align:bottom;}#dashboard-widgets #dashboard_quick_press form p.submit{margin-left:4.6em;}#dashboard-widgets #dashboard_quick_press form p.submit input{float:left;}#dashboard-widgets #dashboard_quick_press form p.submit #save-post{margin:0 1em 0 10px;}#dashboard-widgets #dashboard_quick_press form p.submit #publish{float:right;}#dashboard-widgets #dashboard_quick_press form p.submit img.waiting{vertical-align:middle;visibility:hidden;margin:4px 6px 0 0;}#dashboard_recent_drafts ul{margin:0;padding:0;list-style:none;}#dashboard_recent_drafts ul li{margin-bottom:.6em;}#dashboard_recent_drafts h4{font-weight:normal;}#dashboard_recent_drafts h4 abbr{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-size:11px;color:#999;margin-left:3px;}#dashboard_recent_drafts p{margin:0;padding:0;}.rss-widget ul{margin:0;padding:0;list-style:none;}a.rsswidget{font-size:13px;font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;line-height:1.7em;}.rss-widget ul li{line-height:1.5em;margin-bottom:12px;}.rss-widget span.rss-date{margin-left:3px;}.rss-widget cite{display:block;text-align:right;margin:0 0 1em;padding:0;}.rss-widget cite:before{content:'\2014';}#dashboard_plugins h4{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;}#dashboard_plugins h5{font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-size:13px!important;margin:0;display:inline;line-height:1.4em;}#dashboard_plugins h5 a{font-weight:normal;line-height:1.7em;}#dashboard_plugins p{margin:0 0 1.4em;line-height:1.4em;}.dashboard-comment-wrap{overflow:hidden;word-wrap:break-word;} \ No newline at end of file diff --git a/src/wp-admin/css/dashboard.dev.css b/src/wp-admin/css/dashboard.dev.css new file mode 100644 index 00000000..15da8507 --- /dev/null +++ b/src/wp-admin/css/dashboard.dev.css @@ -0,0 +1,413 @@ +.postbox p, .postbox ul, .postbox ol, .postbox blockquote, #wp-version-message { font-size: 11px; } + +.edit-box { + display: none; +} + +h3:hover .edit-box { + display: inline; +} + +form .input-text-wrap { + border-style: solid; + border-width: 1px; + padding: 2px 3px; + border-color: #ccc; +} + +#dashboard-widgets form .input-text-wrap input { + border: 0 none; + outline: none; + margin: 0; + padding: 0; + width: 99%; + color: #333; +} + +form .textarea-wrap { + border-style: solid; + border-width: 1px; + padding: 2px; + border-color: #ccc; +} + +#dashboard-widgets form .textarea-wrap textarea { + border: 0 none; + padding: 0; + outline: none; + width: 99%; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#dashboard-widgets .postbox form .submit { + float: none; + margin: .5em 0 0; + padding: 0; + border: none; +} + +#dashboard-widgets-wrap #dashboard-widgets .postbox form .submit input { + margin: 0; +} + +#dashboard-widgets-wrap #dashboard-widgets .postbox form .submit #publish { + min-width: 0; +} + +div.postbox div.inside { + margin: 10px; + position: relative; +} + +#dashboard-widgets a { + text-decoration: none; +} + +#dashboard-widgets h3 a { + text-decoration: underline; +} + +#dashboard-widgets h3 .postbox-title-action { + position: absolute; + right: 30px; + padding: 0; +} + +#dashboard-widgets h4 { + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-size: 13px; + margin: 0 0 .2em; + padding: 0; +} + +/* Right Now */ + +#dashboard_right_now p.sub, +#dashboard_right_now .table, #dashboard_right_now .versions { + margin: -12px; +} + +#dashboard_right_now .inside { + font-size: 12px; + padding-top: 20px; +} + +#dashboard_right_now p.sub { + font-style: italic; + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + padding: 5px 10px 15px; + color: #777; + font-size: 13px; + position: absolute; + top: -17px; + left: 15px; +} + +#dashboard_right_now .table { + margin: 0 -9px; + padding: 0 10px; + position: relative; +} + +#dashboard_right_now .table_content { + float: left; + border-top: #ececec 1px solid; + width: 45%; +} + +#dashboard_right_now .table_discussion { + float: right; + border-top: #ececec 1px solid; + width: 45%; +} + +#dashboard_right_now table td { + padding: 3px 0; + white-space: nowrap; +} + +#dashboard_right_now table tr.first td { + border-top: none; +} + +#dashboard_right_now td.b { + padding-right: 6px; + text-align: right; + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-size: 14px; + width: 1%; +} + +#dashboard_right_now td.b a { + font-size: 18px; +} + +#dashboard_right_now td.b a:hover { + color: #d54e21; +} + +#dashboard_right_now .t { + font-size: 12px; + padding-right: 12px; + padding-top: 6px; + color: #777; +} + +#dashboard_right_now .t a { + white-space: nowrap; +} + +#dashboard_right_now .spam { + color: red; +} + +#dashboard_right_now .waiting { + color: #e66f00; +} + +#dashboard_right_now .approved { + color: green; +} + +#dashboard_right_now .versions { + padding: 6px 10px 12px; + clear: both; +} + +#dashboard_right_now .versions .b { + font-weight: bold; +} + +#dashboard_right_now a.button { + float: right; + clear: right; + position: relative; + top: -5px; +} + +/* Recent Comments */ + +#dashboard_recent_comments h3 { + margin-bottom: 0; +} + +#dashboard_recent_comments .inside { + margin-top: 0; +} + +#dashboard_recent_comments .comment-meta .approve { + font-style: italic; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-size: 10px; +} + +#the-comment-list { + position: relative; +} + +#the-comment-list .comment-item { + padding: 1em 10px; + border-top: 1px solid; +} + +#the-comment-list .pingback { + padding-left: 9px !important; +} + +#the-comment-list .comment-item, +#the-comment-list #replyrow { + margin: 0 -10px; +} + +#the-comment-list .comment-item:first-child { + border-top: none; +} + +#the-comment-list .comment-item .avatar { + float: left; + margin: 0 10px 5px 0; +} + +#the-comment-list .comment-item h4 { + line-height: 1.4; + margin-top: -.2em; + font-weight: normal; + color: #999; +} + +#the-comment-list .comment-item h4 cite { + font-style: normal; + font-weight: normal; +} + +#the-comment-list .comment-item blockquote, +#the-comment-list .comment-item blockquote p { + margin: 0; + padding: 0; + display: inline; +} + +#dashboard_recent_comments #the-comment-list .trackback blockquote, +#dashboard_recent_comments #the-comment-list .pingback blockquote { + display: block; +} + +#the-comment-list .comment-item p.row-actions { + margin: 3px 0 0; + padding: 0; + font-size: 10px; +} + +/* QuickPress */ + +#dashboard_quick_press h4 { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + float: left; + width: 5.5em; + clear: both; + font-weight: normal; + text-align: right; + padding-top: 5px; + font-size: 12px; +} + +#dashboard_quick_press h4 label { + margin-right: 10px; +} + +#dashboard_quick_press { + min-height: 200px; +} + +#dashboard_quick_press.closed { + min-height: 0; +} + +#dashboard_quick_press .input-text-wrap, +#dashboard_quick_press .textarea-wrap { + margin: 0 0 1em 5em; +} + +#dashboard_quick_press #media-buttons { + margin: 0 0 .5em 5em; + padding: 0 0 0 10px; + font-size: 11px; +} + +#dashboard_quick_press #media-buttons a { + vertical-align: bottom; +} + +#dashboard-widgets #dashboard_quick_press form p.submit { + margin-left: 4.6em; +} + +#dashboard-widgets #dashboard_quick_press form p.submit input { + float: left; +} + +#dashboard-widgets #dashboard_quick_press form p.submit #save-post { + margin: 0 1em 0 10px; +} + +#dashboard-widgets #dashboard_quick_press form p.submit #publish { + float: right; +} + +#dashboard-widgets #dashboard_quick_press form p.submit img.waiting { + vertical-align: middle; + visibility: hidden; + margin: 4px 6px 0 0; +} + +/* Recent Drafts */ +#dashboard_recent_drafts ul { + margin: 0; + padding: 0; + list-style: none; +} + +#dashboard_recent_drafts ul li { + margin-bottom: 0.6em; +} + +#dashboard_recent_drafts h4 { + font-weight: normal; +} + +#dashboard_recent_drafts h4 abbr { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-size: 11px; + color: #999; + margin-left: 3px; +} + +#dashboard_recent_drafts p { + margin: 0; + padding: 0; +} + +/* Feeds */ + +.rss-widget ul { + margin: 0; + padding: 0; + list-style: none; +} + +a.rsswidget { + font-size: 13px; + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + line-height: 1.7em; +} + +.rss-widget ul li { + line-height: 1.5em; + margin-bottom: 12px; +} + +.rss-widget span.rss-date { + margin-left: 3px; +} + +.rss-widget cite { + display: block; + text-align: right; + margin: 0 0 1em; + padding: 0; +} + +.rss-widget cite:before { + content: '\2014'; +} + +/* Plugins */ + +#dashboard_plugins h4 { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; +} + +#dashboard_plugins h5 { + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-size: 13px !important; + margin: 0; + display: inline; + line-height: 1.4em; +} + +#dashboard_plugins h5 a { + font-weight: normal; + line-height: 1.7em; +} + +#dashboard_plugins p { + margin: 0 0 1.4em; + line-height: 1.4em; +} + +.dashboard-comment-wrap { + overflow: hidden; + word-wrap: break-word; +} diff --git a/src/wp-admin/css/farbtastic-rtl.css b/src/wp-admin/css/farbtastic-rtl.css new file mode 100644 index 00000000..7a8badb4 --- /dev/null +++ b/src/wp-admin/css/farbtastic-rtl.css @@ -0,0 +1,7 @@ +.farbtastic .color, .farbtastic .overlay { + left: 0; + right: 47px; +} +.farbtastic .marker { + margin: -8px -8px 0 0; +} diff --git a/src/wp-admin/css/farbtastic.css b/src/wp-admin/css/farbtastic.css new file mode 100644 index 00000000..71ad3c13 --- /dev/null +++ b/src/wp-admin/css/farbtastic.css @@ -0,0 +1,32 @@ +.farbtastic { + position: relative; +} +.farbtastic * { + position: absolute; + cursor: crosshair; +} +.farbtastic, .farbtastic .wheel { + width: 195px; + height: 195px; +} +.farbtastic .color, .farbtastic .overlay { + top: 47px; + left: 47px; + width: 101px; + height: 101px; +} +.farbtastic .wheel { + background: url(../images/wheel.png) no-repeat; + width: 195px; + height: 195px; +} +.farbtastic .overlay { + background: url(../images/mask.png) no-repeat; +} +.farbtastic .marker { + width: 17px; + height: 17px; + margin: -8px 0 0 -8px; + overflow: hidden; + background: url(../images/marker.png) no-repeat; +} \ No newline at end of file diff --git a/src/wp-admin/css/global-rtl.css b/src/wp-admin/css/global-rtl.css new file mode 100644 index 00000000..d7a34800 --- /dev/null +++ b/src/wp-admin/css/global-rtl.css @@ -0,0 +1 @@ +#adminmenu{float:right;clear:right;margin-right:-160px;margin-left:5px;}body.folded #adminmenu{margin-left:0;margin-right:-45px;}.inner-sidebar{float:left;clear:left;}.has-right-sidebar #post-body{clear:right;float:right;margin-right:0;margin-left:-340px;}.has-right-sidebar #post-body-content{margin-left:300px;margin-right:0;}#wpbody{margin-left:0;margin-right:175px;}.folded #wpbody{margin-left:0;margin-right:60px;}#wpbody-content{float:right;}#col-right{float:left;clear:left;}.wrap{margin:0 5px 0 15px;}body,td,textarea,input,select{font-family:Tahoma,arial;}.alignleft{float:right;}.alignright{float:left;}.subsubsub{float:right;}.widefat th{text-align:right;}.widefat th input{margin:0 8px 0 0;}.wrap h2{font-family:arial;padding:14px 0 3px 15px;font-style:normal;}.wrap h2.long-header{padding-left:0;}.updated,.error{clear:both;}.screen-reader-text,.screen-reader-text span{left:auto;text-indent:-1000em;} \ No newline at end of file diff --git a/src/wp-admin/css/global-rtl.dev.css b/src/wp-admin/css/global-rtl.dev.css new file mode 100644 index 00000000..85d21c32 --- /dev/null +++ b/src/wp-admin/css/global-rtl.dev.css @@ -0,0 +1,83 @@ +/* 2 column liquid layout */ +#adminmenu { + float: right; + clear: right; + margin-right:-160px; + margin-left: 5px; +} +body.folded #adminmenu { + margin-left: 0; + margin-right: -45px; +} +/* inner 2 column liquid layout */ +.inner-sidebar { + float: left; + clear: left; +} + +.has-right-sidebar #post-body { + clear:right; + float:right; + margin-right:0; + margin-left:-340px; +} + +.has-right-sidebar #post-body-content { + margin-left: 300px; + margin-right:0; +} + +#wpbody { + margin-left:0; + margin-right: 175px; +} +.folded #wpbody { + margin-left: 0; + margin-right: 60px; +} +#wpbody-content { + float: right; +} +/* 2 columns main area */ +#col-right { + float: left; + clear: left; +} +.wrap { + margin: 0 5px 0 15px; +} +/* styles for use by people extending the WordPress interface */ +body, td, textarea, input, select { + font-family: Tahoma, arial; +} +.alignleft { + float: right; +} +.alignright { + float: left; +} +.subsubsub { + float: right; +} +.widefat th { + text-align: right; +} +.widefat th input { + margin: 0 8px 0 0; +} +.wrap h2 { + font-family: arial; + padding: 14px 0 3px 15px; + font-style: normal; +} +.wrap h2.long-header { + padding-left: 0; +} +.updated, .error { + clear: both; +} + +.screen-reader-text, .screen-reader-text span { + left:auto; + text-indent:-1000em; +} \ No newline at end of file diff --git a/src/wp-admin/css/global.css b/src/wp-admin/css/global.css new file mode 100644 index 00000000..0fd0af03 --- /dev/null +++ b/src/wp-admin/css/global.css @@ -0,0 +1 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;background:transparent;}body{line-height:1;}ol,ul{list-style:none;}blockquote,q{quotes:none;}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;}ins{text-decoration:none;}del{text-decoration:line-through;}#wpwrap{height:auto;min-height:100%;width:100%;}#wpcontent{height:100%;padding-bottom:50px;}#wpbody{clear:both;margin-left:175px;}.folded #wpbody{margin-left:60px;}#wpbody-content{float:left;width:100%;}#adminmenu{float:left;clear:left;width:145px;margin-top:15px;margin-right:5px;margin-bottom:15px;margin-left:-160px;position:relative;padding:0;list-style:none;}.folded #adminmenu{margin-left:-45px;}.folded #adminmenu,.folded #adminmenu li.menu-top{width:28px;}#footer{clear:both;position:relative;width:100%;}.inner-sidebar{float:right;clear:right;display:none;width:281px;position:relative;}.inner-sidebar #side-sortables{width:280px;min-height:300px;}.has-right-sidebar .inner-sidebar{display:block;}.has-right-sidebar #post-body{float:left;clear:left;width:100%;margin-right:-340px;}.has-right-sidebar #post-body-content{margin-right:300px;}#col-container{overflow:hidden;padding:0;margin:0;}#col-left{padding:0;margin:0;overflow:hidden;width:39%;}#col-right{float:right;clear:right;overflow:hidden;padding:0;margin:0;width:59%;}.alignleft{float:left;}.alignright{float:right;}.textleft{text-align:left;}.textright{text-align:right;}.clear{clear:both;}.screen-reader-text,.screen-reader-text span{position:absolute;left:-1000em;height:1px;width:1px;overflow:hidden;}.hidden,.js .closed .inside,.js .hide-if-js,.no-js .hide-if-no-js{display:none;}input[type="text"],input[type="password"],textarea{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;}input[type="checkbox"],input[type="radio"]{vertical-align:middle;}html,body{height:100%;}body,td,textarea,input,select{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-size:13px;}body,textarea{line-height:1.4em;}input,select{line-height:15px;}p{margin:1em 0;}blockquote{margin:1em;}label{cursor:pointer;}li,dd{margin-bottom:6px;}p,li,dl,dd,dt{line-height:140%;}textarea,input,select{margin:1px;padding:3px;}h1{display:block;font-size:2em;font-weight:bold;margin:.67em 0;}h2{display:block;font-size:1.5em;font-weight:bold;margin:.83em 0;}h3{display:block;font-size:1.17em;font-weight:bold;margin:1em 0;}h4{display:block;font-size:1em;font-weight:bold;margin:1.33em 0;}h5{display:block;font-size:.83em;font-weight:bold;margin:1.67em 0;}h6{display:block;font-size:.67em;font-weight:bold;margin:2.33em 0;}ul.ul-disc{list-style:disc outside;}ul.ul-square{list-style:square outside;}ol.ol-decimal{list-style:decimal outside;}ul.ul-disc,ul.ul-square,ol.ol-decimal{margin-left:1.8em;}ul.ul-disc>li,ul.ul-square>li,ol.ol-decimal>li{margin:0 0 .5em;}.subsubsub{list-style:none;margin:8px 0 5px;padding:0;white-space:nowrap;font-size:11px;float:left;}.subsubsub a{line-height:2;padding:.2em;text-decoration:none;}.subsubsub a .count,.subsubsub a.current .count{color:#999;font-weight:normal;}.subsubsub a.current{font-weight:bold;background:none;border:none;}.subsubsub li{display:inline;margin:0;padding:0;}.widefat{border-width:1px;border-style:solid;border-spacing:0;width:100%;clear:both;margin:0;-moz-border-radius:4px;-khtml-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;}.widefat *{word-wrap:break-word;}.widefat a{text-decoration:none;}.widefat thead th:first-of-type{-moz-border-radius-topleft:3px;-khtml-border-top-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;}.widefat thead th:last-of-type{-moz-border-radius-topright:3px;-khtml-border-top-right-radius:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px;}.widefat tfoot th:first-of-type{-moz-border-radius-bottomleft:3px;-khtml-border-bottom-left-radius:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;}.widefat tfoot th:last-of-type{-moz-border-radius-bottomright:3px;-khtml-border-bottom-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;}.widefat td,.widefat th{border-bottom-width:1px;border-bottom-style:solid;font-size:11px;}.widefat .no-items td{border-bottom-width:0;}.widefat td{padding:3px 7px;vertical-align:top;}.widefat td p,.widefat td ol,.widefat td ul{font-size:11px;}.widefat th{padding:7px 7px 8px;text-align:left;line-height:1.3em;}.widefat th input{margin:0 0 0 8px;padding:0;vertical-align:text-top;}.widefat .check-column{width:2.2em;padding:0;}.widefat tbody th.check-column{padding:7px 0 22px;vertical-align:top;}.widefat .num,.column-comments,.column-links,.column-posts{text-align:center;}.widefat th#comments{vertical-align:middle;}.wrap{margin:0 15px 0 5px;}div.updated,div.error{border-width:1px;border-style:solid;padding:0 .6em;margin:5px 15px 2px;-moz-border-radius:3px;-khtml-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}div.updated p,div.error p{margin:.5em 0;padding:2px;}.wrap div.updated,.wrap div.error{margin:5px 0 15px;}.wrap h2{font:italic normal normal 24px/29px Georgia,"Times New Roman","Bitstream Charter",Times,serif;margin:0;padding:14px 15px 3px 0;line-height:35px;text-shadow:rgba(255,255,255,1) 0 1px 0;}.wrap h2.long-header{padding-right:0;} \ No newline at end of file diff --git a/src/wp-admin/css/global.dev.css b/src/wp-admin/css/global.dev.css new file mode 100644 index 00000000..10abf25f --- /dev/null +++ b/src/wp-admin/css/global.dev.css @@ -0,0 +1,514 @@ +/* http://meyerweb.com/eric/tools/css/reset/ */ +/* v1.0 | 20080212 */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; +/* font-size: 100%; + vertical-align: baseline; */ + background: transparent; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} + +/* remember to define focus styles! */ +/* +:focus { + outline: 0; +} +*/ +/* remember to highlight inserts somehow! */ +ins { + text-decoration: none; +} +del { + text-decoration: line-through; +} + +/* tables still need 'cellspacing="0"' in the markup */ +/* +table { + border-collapse: collapse; + border-spacing: 0; +} +*/ +/* end reset css */ + + +/* 2 column liquid layout */ +#wpwrap { + height: auto; + min-height: 100%; + width: 100%; +} + +#wpcontent { + height: 100%; + padding-bottom: 50px; +} + +#wpbody { + clear: both; + margin-left: 175px; +} + +.folded #wpbody { + margin-left: 60px; +} + +#wpbody-content { + float: left; + width: 100%; +} + +#adminmenu { + float: left; + clear: left; + width: 145px; + margin-top: 15px; + margin-right: 5px; + margin-bottom: 15px; + margin-left: -160px; + position: relative; + padding: 0; + list-style: none; +} + +.folded #adminmenu { + margin-left: -45px; +} + +.folded #adminmenu, +.folded #adminmenu li.menu-top { + width: 28px; +} + +#footer { + clear: both; + position: relative; + width: 100%; +} + +/* inner 2 column liquid layout */ +.inner-sidebar { + float: right; + clear: right; + display: none; + width: 281px; + position: relative; +} + +.inner-sidebar #side-sortables { + width: 280px; + min-height: 300px; +} + +.has-right-sidebar .inner-sidebar { + display: block; +} + +.has-right-sidebar #post-body { + float: left; + clear: left; + width: 100%; + margin-right: -340px; +} + +.has-right-sidebar #post-body-content { + margin-right: 300px; +} + +/* 2 columns main area */ + +#col-container { + overflow: hidden; + padding: 0; + margin: 0; +} + +#col-left { + padding: 0; + margin: 0; + overflow: hidden; + width: 39%; +} + +#col-right { + float: right; + clear: right; + overflow: hidden; + padding: 0; + margin: 0; + width: 59%; +} + +/* utility classes */ +.alignleft { + float: left; +} + +.alignright { + float: right; +} + +.textleft { + text-align: left; +} + +.textright { + text-align: right; +} + +.clear { + clear: both; +} + +/* Hide visually but not from screen readers */ +.screen-reader-text, +.screen-reader-text span { + position: absolute; + left: -1000em; + height: 1px; + width: 1px; + overflow: hidden; +} + +.hidden, +.js .closed .inside, +.js .hide-if-js, +.no-js .hide-if-no-js { + display: none; +} + +/* include margin and padding in the width calculation of input and textarea */ +input[type="text"], +input[type="password"], +textarea { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; /* ie8 only */ + box-sizing: border-box; +} + +input[type="checkbox"], +input[type="radio"] { + vertical-align: middle; +} + +/* styles for use by people extending the WordPress interface */ +html, +body { + height: 100%; +} + +body, +td, +textarea, +input, +select { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-size: 13px; +} + +body, +textarea { + line-height: 1.4em; +} + +input, +select { + line-height: 15px; +} + +p { + margin: 1em 0; +} + +blockquote { + margin: 1em; +} + +label { + cursor: pointer; +} + +li, +dd { + margin-bottom: 6px; +} + +p, +li, +dl, +dd, +dt { + line-height: 140%; +} + +textarea, +input, +select { + margin: 1px; + padding: 3px; +} + +h1 { + display: block; + font-size: 2em; + font-weight: bold; + margin: .67em 0; +} + +h2 { + display: block; + font-size: 1.5em; + font-weight: bold; + margin: .83em 0; +} + +h3 { + display: block; + font-size: 1.17em; + font-weight: bold; + margin: 1em 0; +} + +h4 { + display: block; + font-size: 1em; + font-weight: bold; + margin: 1.33em 0; +} + +h5 { + display: block; + font-size: 0.83em; + font-weight: bold; + margin: 1.67em 0; +} + +h6 { + display: block; + font-size: 0.67em; + font-weight: bold; + margin: 2.33em 0; +} + +ul.ul-disc { + list-style: disc outside; +} + +ul.ul-square { + list-style: square outside; +} + +ol.ol-decimal { + list-style: decimal outside; +} + +ul.ul-disc, +ul.ul-square, +ol.ol-decimal { + margin-left: 1.8em; +} + +ul.ul-disc > li, +ul.ul-square > li, +ol.ol-decimal > li { + margin: 0 0 0.5em; +} + +.subsubsub { + list-style: none; + margin: 8px 0 5px; + padding: 0; + white-space: nowrap; + font-size: 11px; + float: left; +} + +.subsubsub a { + line-height: 2; + padding: .2em; + text-decoration: none; +} + +.subsubsub a .count, .subsubsub a.current .count { + color: #999; + font-weight: normal; +} + +.subsubsub a.current { + font-weight: bold; + background: none; + border: none; +} + +.subsubsub li { + display: inline; + margin: 0; + padding: 0; +} + +.widefat { + border-width: 1px; + border-style: solid; + border-spacing: 0; + width: 100%; + clear: both; + margin: 0; + -moz-border-radius: 4px; + -khtml-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +.widefat * { + word-wrap: break-word; +} + +.widefat a { + text-decoration: none; +} + +.widefat thead th:first-of-type { + -moz-border-radius-topleft: 3px; + -khtml-border-top-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; +} +.widefat thead th:last-of-type { + -moz-border-radius-topright: 3px; + -khtml-border-top-right-radius: 3px; + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; +} +.widefat tfoot th:first-of-type { + -moz-border-radius-bottomleft: 3px; + -khtml-border-bottom-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.widefat tfoot th:last-of-type { + -moz-border-radius-bottomright: 3px; + -khtml-border-bottom-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +.widefat td, +.widefat th { + border-bottom-width: 1px; + border-bottom-style: solid; + font-size: 11px; +} + +.widefat .no-items td { + border-bottom-width: 0; +} + +.widefat td { + padding: 3px 7px; + vertical-align: top; +} + +.widefat td p, +.widefat td ol, +.widefat td ul { + font-size: 11px; +} + +.widefat th { + padding: 7px 7px 8px; + text-align: left; + line-height: 1.3em; +} + +.widefat th input { + margin: 0 0 0 8px; + padding: 0; + vertical-align: text-top; +} + +.widefat .check-column { + width: 2.2em; + padding: 0; + +} + +.widefat tbody th.check-column { + padding: 7px 0 22px; + vertical-align: top; +} + +.widefat .num, +.column-comments, +.column-links, +.column-posts { + text-align: center; +} + +.widefat th#comments { + vertical-align: middle; +} + +.wrap { + margin: 0 15px 0 5px; +} + +div.updated, +div.error { + border-width: 1px; + border-style: solid; + padding: 0 0.6em; + margin: 5px 15px 2px; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +div.updated p, +div.error p { + margin: 0.5em 0; + padding: 2px; +} + +.wrap div.updated, +.wrap div.error { + margin: 5px 0 15px; +} + +.wrap h2 { + font: italic normal normal 24px/29px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + margin: 0; + padding: 14px 15px 3px 0; + line-height: 35px; + text-shadow: rgba(255,255,255,1) 0 1px 0; +} + +.wrap h2.long-header { + padding-right: 0; +} diff --git a/src/wp-admin/css/ie-rtl.css b/src/wp-admin/css/ie-rtl.css new file mode 100644 index 00000000..40f5b76b --- /dev/null +++ b/src/wp-admin/css/ie-rtl.css @@ -0,0 +1 @@ +html{direction:ltr;}body{direction:rtl;}* html #wpcontent #adminmenu .wp-has-submenu .wp-menu-toggle{background:url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -109px;}* html #wpcontent #adminmenu li.wp-has-current-submenu .wp-menu-toggle{background:url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -206px;}* html #adminmenu{margin-left:0;margin-right:-80px;}* html div.folded #adminmenu{margin-left:0;margin-right:-22px;}#wpcontent #adminmenu .wp-submenu li.wp-submenu-head{padding:3px 10px 4px 4px;}.inline-edit-row fieldset label span.title{float:right;}.inline-edit-row fieldset label span.input-text-wrap{margin-right:0;}p.search-box{float:left;}* html #poststuff h2{margin-right:0;}#bh{margin:7px 10px 0 0;float:left;}#user_info+div#favorite-actions{right:auto;left:15px;}#wphead-info{float:left;}div#dashboard-widgets{padding-right:0;padding-left:1px;}.tagchecklist span a{margin:4px -9px 0 0;}.widefat th input{margin:0 5px 0 0;}#TB_window{width:670px;position:absolute;top:50%;left:50%;margin-right:335px!important;}#dashboard_plugins{direction:ltr;}#dashboard_plugins h3.hndle{direction:rtl;}#dashboard_incoming_links ul li,#dashboard_secondary ul li,#dashboard_primary ul li,p.row-actions{width:100%;}#favorite-inside{position:absolute;right:0;}#post-status-info{height:25px;}#screen-meta{position:static;}p.submit{height:22px;}.inner-sidebar{position:static;}form#widgets-filter{position:static;}* html .meta-box-sortables .postbox .handlediv{background:transparent url(../images/menu-bits-rtl-vs.gif) no-repeat scroll right -111px;}.menu-max-depth-0 #menu-management{width:460px;}.menu-max-depth-1 #menu-management{width:490px;}.menu-max-depth-2 #menu-management{width:520px;}.menu-max-depth-3 #menu-management{width:550px;}.menu-max-depth-4 #menu-management{width:580px;}.menu-max-depth-5 #menu-management{width:610px;}.menu-max-depth-6 #menu-management{width:640px;}.menu-max-depth-7 #menu-management{width:670px;}.menu-max-depth-8 #menu-management{width:700px;}.menu-max-depth-9 #menu-management{width:730px;}.menu-max-depth-10 #menu-management{width:760px;}.menu-max-depth-11 #menu-management{width:790px;}.menu-item-depth-0{margin-left:0;}.menu-item-depth-1{margin-left:-30px;}.menu-item-depth-2{margin-left:-60px;}.menu-item-depth-3{margin-left:-90px;}.menu-item-depth-4{margin-left:-120px;}.menu-item-depth-5{margin-left:-150px;}.menu-item-depth-6{margin-left:-180px;}.menu-item-depth-7{margin-left:-210px;}.menu-item-depth-8{margin-left:-240px;}.menu-item-depth-9{margin-left:-270px;}.menu-item-depth-10{margin-left:-300px;}.menu-item-depth-11{margin-left:-330px;}#menu-to-edit li dl{padding:0!important;margin:0!important;}.ui-sortable-helper .menu-item-transport{margin-top:13px;}.ui-sortable-helper .menu-item-transport .menu-item-transport{margin-top:0;}.sortable-placeholder{margin-top:0!important;margin-left:0!important;margin-bottom:13px!important;padding:0!important;}.auto-add-pages{clear:both;float:none;}#nav-menus-frame .open-label span{float:none;display:inline-block;}#nav-menus-frame .delete-action{float:none;} \ No newline at end of file diff --git a/src/wp-admin/css/ie-rtl.dev.css b/src/wp-admin/css/ie-rtl.dev.css new file mode 100644 index 00000000..c35fc894 --- /dev/null +++ b/src/wp-admin/css/ie-rtl.dev.css @@ -0,0 +1,156 @@ +html { + direction: ltr; +} +body { + direction: rtl; +} +* html #wpcontent #adminmenu .wp-has-submenu .wp-menu-toggle { + background: url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -109px; +} + +* html #wpcontent #adminmenu li.wp-has-current-submenu .wp-menu-toggle { + background: url(../images/menu-bits-rtl.gif?ver=20100531) no-repeat scroll right -206px; +} +* html #adminmenu { + margin-left:0; + margin-right: -80px; +} +* html div.folded #adminmenu { + margin-left: 0; + margin-right: -22px; +} +#wpcontent #adminmenu .wp-submenu li.wp-submenu-head { + padding: 3px 10px 4px 4px; +} +.inline-edit-row fieldset label span.title { + float: right; +} +.inline-edit-row fieldset label span.input-text-wrap { + margin-right: 0; +} +p.search-box { + float: left; +} +* html #poststuff h2 { + margin-right: 0; +} +#bh { + margin: 7px 10px 0 0; + float: left; +} +#user_info + div#favorite-actions { + right: auto; + left: 15px; +} +#wphead-info { + float: left; +} +/* without this dashboard widgets appear in one column for some screen widths */ +div#dashboard-widgets { + padding-right: 0; + padding-left: 1px; +} +.tagchecklist span a { + margin: 4px -9px 0 0; +} +.widefat th input { + margin: 0 5px 0 0; +} +/* ---------- add by navid */ +#TB_window { + width: 670px; + position: absolute; + top: 50%; + left: 50%; + margin-right: 335px !important; +} +#dashboard_plugins { + direction: ltr; +} +#dashboard_plugins h3.hndle { + direction: rtl; +} +#dashboard_incoming_links ul li, +#dashboard_secondary ul li, +#dashboard_primary ul li, +p.row-actions { + width: 100%; +} +#favorite-inside { + position: absolute; + right:0; +} +#post-status-info { + height: 25px; +} +#screen-meta { + position: static; +} +p.submit { /* quick edit and reply in edit-comments.php */ + height:22px; +} +.inner-sidebar { /* fix edit single comment */ + position: static; +} +form#widgets-filter { /* fix widget page */ + position: static; +} + +* html .meta-box-sortables .postbox .handlediv { + background: transparent url(../images/menu-bits-rtl-vs.gif) no-repeat scroll right -111px; +} + +/* nav menus */ +.menu-max-depth-0 #menu-management { width: 460px; } +.menu-max-depth-1 #menu-management { width: 490px; } +.menu-max-depth-2 #menu-management { width: 520px; } +.menu-max-depth-3 #menu-management { width: 550px; } +.menu-max-depth-4 #menu-management { width: 580px; } +.menu-max-depth-5 #menu-management { width: 610px; } +.menu-max-depth-6 #menu-management { width: 640px; } +.menu-max-depth-7 #menu-management { width: 670px; } +.menu-max-depth-8 #menu-management { width: 700px; } +.menu-max-depth-9 #menu-management { width: 730px; } +.menu-max-depth-10 #menu-management { width: 760px; } +.menu-max-depth-11 #menu-management { width: 790px; } + +.menu-item-depth-0 { margin-left: 0px; } +.menu-item-depth-1 { margin-left: -30px; } +.menu-item-depth-2 { margin-left: -60px; } +.menu-item-depth-3 { margin-left: -90px; } +.menu-item-depth-4 { margin-left: -120px; } +.menu-item-depth-5 { margin-left: -150px; } +.menu-item-depth-6 { margin-left: -180px; } +.menu-item-depth-7 { margin-left: -210px; } +.menu-item-depth-8 { margin-left: -240px; } +.menu-item-depth-9 { margin-left: -270px; } +.menu-item-depth-10 { margin-left: -300px; } +.menu-item-depth-11 { margin-left: -330px; } + +#menu-to-edit li dl { + padding: 0 !important; + margin: 0 !important; +} +.ui-sortable-helper .menu-item-transport { + margin-top: 13px; +} + .ui-sortable-helper .menu-item-transport .menu-item-transport { + margin-top: 0; + } +.sortable-placeholder { + margin-top: 0 !important; + margin-left: 0 !important; + margin-bottom: 13px !important; + padding: 0 !important; +} +.auto-add-pages { + clear: both; + float: none; +} +#nav-menus-frame .open-label span { + float: none; + display: inline-block; +} +#nav-menus-frame .delete-action { + float: none; +} diff --git a/src/wp-admin/css/ie.css b/src/wp-admin/css/ie.css new file mode 100644 index 00000000..ad96e070 --- /dev/null +++ b/src/wp-admin/css/ie.css @@ -0,0 +1 @@ +#wpbody-content input.button,#wpbody-content input.button-secondary,#wpbody-content input.button-highlighted{padding:2px 3px;}#minor-publishing-actions input,#major-publishing-actions input{min-width:auto;padding-left:0;padding-right:0;}#wpbody-content .postbox{border:1px solid #dfdfdf;}#wpbody-content .postbox h3{margin-bottom:-1px;}* html .meta-box-sortables .postbox .handlediv{background:transparent url(../images/menu-bits-vs.gif) no-repeat scroll left -111px;}* html .edit-box{display:inline;}* html .inner-sidebar #side-sortables,* html .postbox-container .meta-box-sortables{height:300px;}* html #wpbody-content #screen-options-link-wrap{display:inline-block;width:150px;text-align:center;}* html #wpbody-content #contextual-help-link-wrap{display:inline-block;width:100px;text-align:center;}* html #adminmenu{margin-left:-80px;}* html .folded #adminmenu{margin-left:-22px;}* html #wpcontent #adminmenu li.menu-top{display:inline;padding:0;margin:0;}* html #footer{margin:0;}.folded #adminmenu li.menu-top{display:block;zoom:100%;}ul#adminmenu{z-index:99;}#adminmenu li.menu-top a.menu-top{min-width:auto;width:auto;}#wpcontent #adminmenu li.wp-has-current-submenu a.wp-has-submenu{font-style:normal;}* html #wpcontent #adminmenu .wp-menu-open .wp-menu-toggle{background:none;}* html #wpcontent #adminmenu .wp-has-submenu .wp-menu-toggle{background:url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -109px;}* html #wpcontent #adminmenu li.wp-has-current-submenu .wp-menu-toggle{background:url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -206px;}* html #adminmenu div.wp-menu-image{height:29px;}#wpcontent #adminmenu .wp-submenu li{padding:0;}#adminmenu,.major-publishing-actions,.wp-submenu,.wp-submenu li,.wp-menu-toggle{zoom:100%;}.folded #adminmenu li.wp-menu-separator{width:28px;}#wpcontent #adminmenu .wp-submenu li.wp-submenu-head{padding:3px 4px 4px 10px;zoom:100%;}.folded #adminmenu .menu-top{height:30px;}.folded #adminmenu .wp-submenu{margin:-1px 0 0 0;}#template,#template div,#editcat,#addcat,* html .stuffbox h3{zoom:100%;}.submitbox{margin-top:10px;}#wpbody-content .quick-edit-row-post .inline-edit-col-left{width:39%;}#wpbody-content .inline-edit-row-post .inline-edit-col-center{width:19%;}#wpbody-content .quick-edit-row-page .inline-edit-col-left{width:49%;}#wpbody-content .bulk-edit-row .inline-edit-col-left{width:29%;}.inline-edit-row p.submit{zoom:100%;}.inline-edit-row fieldset label span.title{display:block;float:left;width:5em;}.inline-edit-row fieldset label span.input-text-wrap{margin-left:0;zoom:100%;}#wpbody-content .inline-edit-row fieldset label span.input-text-wrap input{line-height:130%;}#wpbody-content .inline-edit-row .input-text-wrap input{width:95%;}#wpbody-content .inline-edit-row .input-text-wrap input.inline-edit-password-input{width:8em;}input{line-height:1;}* html .row-actions{visibility:visible;}#dashboard-widgets h3 a{height:20px;line-height:20px;}#wphead-info{float:right;}#titlediv #title{width:98%;}a.button{line-height:1.4em;margin:1px;padding:2px 6px;}* html div.widget-liquid-left,* html div.widget-liquid-right{display:block;position:relative;}#screen-options-wrap{overflow:hidden;}#favorite-actions{z-index:12;}#favorite-inside,#favorite-inside a,.favorite-action{zoom:100%;}#the-comment-list .comment-item,#post-status-info,#wpwrap,#wpcontent,#wrap,#postdivrich,#postdiv,#poststuff,.metabox-holder,#titlediv,#post-body,#editorcontainer,.tablenav,.widget-liquid-left,.widget-liquid-right,#widgets-left,.widgets-sortables,#dragHelper,.widget .widget-top,.widget,.widget-control-actions,.tagchecklist,#col-container,#col-left,#col-right,.fileedit-sub{display:block;zoom:100%;}p.search-box{position:static;float:right;margin:-3px 0 4px;}* html #editorcontainer{padding:0;}#editorcontainer #content{overflow:auto;margin:auto;width:98%;}form#template div{width:100%;}#ed_toolbar input,#ed_reply_toolbar input{overflow:visible;padding:0 4px;}#poststuff h2{font-size:1.6em;}* html #poststuff h2{margin-left:0;}#bh{margin:7px 10px 0 0;float:right;}div#dashboard-widgets{padding-right:1px;}.tagchecklist span,.tagchecklist span a{display:inline-block;display:block;}.tagchecklist span a{margin:4px 0 0 -9px;}.tablenav .button-secondary,.nav .button-secondary{padding:0 1px;vertical-align:middle;}.tablenav select{font-size:13px;display:inline-block;vertical-align:top;margin-top:2px;}.tablenav .actions select{width:155px;}table.ie-fixed{table-layout:fixed;}.widefat tr,.widefat th{margin-bottom:0;border-spacing:0;}.widefat th input{margin:0 0 0 5px;}.widefat .check-column{padding:6px 0 2px;}.widefat tbody th.check-column{padding:4px 0 22px;}.widefat{empty-cells:show;border-collapse:collapse;}.tablenav a.button-secondary{display:inline-block;padding:2px 5px;}* html .stuffbox,* html .stuffbox input,* html .stuffbox textarea{border:1px solid #DFDFDF;}* html .feature-filter .feature-group li{width:145px;}* html .widget-top .widget-title-action a{background:url("../images/menu-bits.gif?ver=20100610") no-repeat scroll 0 -110px;}* html div.widget-liquid-left{width:99%;}#wp_inactive_widgets{padding-bottom:8px;}* html .widgets-sortables{height:50px;}* html a#content_resize{right:-2px;}* html .widget-title h4{width:205px;}* html #removing-widget .in-widget-title{display:none;}#available-widgets .widget-holder{padding-bottom:65px;}#widgets-left .inactive{padding-bottom:10px;}.widget-liquid-right .widget,#wp_inactive_widgets .widget{position:relative;}* html .media-item .pinkynail{height:32px;width:40px;}#wpcontent .button-primary-disabled{color:#9FD0D5;background:#298CBA;}#wpcontent #ajax-loading,#wpcontent .ajax-loading{vertical-align:baseline;}* html .describe .field input.text,* html .describe .field textarea{width:440px;}#the-comment-list .unapproved tr,#the-comment-list .unapproved td{background-color:#ffffe0;}.imgedit-submit{width:300px;}* html input{border:1px solid #dfdfdf;}#nav-menu-header,#nav-menus-frame,#wpbody,.menu li{zoom:100%;}#update-nav-menu #post-body{overflow:hidden;}.menu li{min-width:100%;}.menu li.sortable-placeholder{min-width:400px;} \ No newline at end of file diff --git a/src/wp-admin/css/ie.dev.css b/src/wp-admin/css/ie.dev.css new file mode 100644 index 00000000..5e919b45 --- /dev/null +++ b/src/wp-admin/css/ie.dev.css @@ -0,0 +1,465 @@ +/* Fixes for IE bugs */ + +#wpbody-content input.button, +#wpbody-content input.button-secondary, +#wpbody-content input.button-highlighted { + padding: 2px 3px; +} + +#minor-publishing-actions input, +#major-publishing-actions input { + min-width: auto; + padding-left: 0; + padding-right: 0; +} + +#wpbody-content .postbox { + border: 1px solid #dfdfdf; +} + +#wpbody-content .postbox h3 { + margin-bottom: -1px; +} + +* html .meta-box-sortables .postbox .handlediv { + background: transparent url(../images/menu-bits-vs.gif) no-repeat scroll left -111px; +} + +* html .edit-box { + display: inline; +} + +* html .inner-sidebar #side-sortables, +* html .postbox-container .meta-box-sortables { + height: 300px; +} + +* html #wpbody-content #screen-options-link-wrap { + display: inline-block; + width: 150px; + text-align: center; +} + +* html #wpbody-content #contextual-help-link-wrap { + display: inline-block; + width: 100px; + text-align: center; +} + +* html #adminmenu { + margin-left: -80px; +} + +* html .folded #adminmenu { + margin-left: -22px; +} + +* html #wpcontent #adminmenu li.menu-top { + display: inline; + padding: 0; + margin: 0; +} + +* html #footer { + margin: 0; +} + +.folded #adminmenu li.menu-top { + display: block; + zoom: 100%; +} + +ul#adminmenu { + z-index: 99; +} + +#adminmenu li.menu-top a.menu-top { + min-width: auto; + width: auto; +} + +#wpcontent #adminmenu li.wp-has-current-submenu a.wp-has-submenu { + font-style: normal; +} + +* html #wpcontent #adminmenu .wp-menu-open .wp-menu-toggle { + background: none; +} + +* html #wpcontent #adminmenu .wp-has-submenu .wp-menu-toggle { + background: url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -109px; +} + +* html #wpcontent #adminmenu li.wp-has-current-submenu .wp-menu-toggle { + background: url(../images/menu-bits.gif?ver=20100610) no-repeat scroll left -206px; +} + +* html #adminmenu div.wp-menu-image { + height: 29px; +} + +#wpcontent #adminmenu .wp-submenu li { + padding: 0; +} + +#adminmenu, +.major-publishing-actions, +.wp-submenu, +.wp-submenu li, +.wp-menu-toggle { + zoom: 100%; +} + +.folded #adminmenu li.wp-menu-separator { + width: 28px; +} + +#wpcontent #adminmenu .wp-submenu li.wp-submenu-head { + padding: 3px 4px 4px 10px; + zoom: 100%; +} + +.folded #adminmenu .menu-top { + height: 30px; +} + +.folded #adminmenu .wp-submenu { + margin: -1px 0 0 0; +} + +#template, +#template div, +#editcat, +#addcat, +* html .stuffbox h3 { + zoom: 100%; +} + +.submitbox { + margin-top: 10px; +} + +/* Inline Editor */ +#wpbody-content .quick-edit-row-post .inline-edit-col-left { + width: 39%; +} + +#wpbody-content .inline-edit-row-post .inline-edit-col-center { + width: 19%; +} + +#wpbody-content .quick-edit-row-page .inline-edit-col-left { + width: 49%; +} + +#wpbody-content .bulk-edit-row .inline-edit-col-left { + width: 29%; +} + +.inline-edit-row p.submit { + zoom: 100%; +} + +.inline-edit-row fieldset label span.title { + display: block; + float: left; + width: 5em; +} + +.inline-edit-row fieldset label span.input-text-wrap { + margin-left: 0; + zoom: 100%; +} + +#wpbody-content .inline-edit-row fieldset label span.input-text-wrap input { + line-height: 130%; +} + +#wpbody-content .inline-edit-row .input-text-wrap input { + width: 95%; +} + +#wpbody-content .inline-edit-row .input-text-wrap input.inline-edit-password-input { + width: 8em; +} +/* end Inline Editor */ + +input { + line-height: 1; +} + +* html .row-actions { + visibility: visible; +} + +#dashboard-widgets h3 a { + height: 20px; + line-height: 20px; +} + +#wphead-info { + float: right; +} + +#titlediv #title { + width: 98%; +} + +a.button { + line-height: 1.4em; + margin: 1px; + padding: 2px 6px; +} + +* html div.widget-liquid-left, +* html div.widget-liquid-right { + display: block; + position: relative; +} + +#screen-options-wrap { + overflow: hidden; +} + +#favorite-actions { + z-index: 12; +} + +#favorite-inside, +#favorite-inside a, +.favorite-action { + zoom: 100%; +} + +#the-comment-list .comment-item, +#post-status-info, +#wpwrap, +#wpcontent, +#wrap, +#postdivrich, +#postdiv, +#poststuff, +.metabox-holder, +#titlediv, +#post-body, +#editorcontainer, +.tablenav, +.widget-liquid-left, +.widget-liquid-right, +#widgets-left, +.widgets-sortables, +#dragHelper, +.widget .widget-top, +.widget, +.widget-control-actions, +.tagchecklist, +#col-container, +#col-left, +#col-right, +.fileedit-sub { + display: block; + zoom: 100%; +} + +p.search-box { + position: static; + float: right; + margin: -3px 0 4px; +} + +* html #editorcontainer { + padding: 0; +} + +#editorcontainer #content { + overflow: auto; + margin: auto; + width: 98%; +} + +form#template div { + width: 100%; +} + +#ed_toolbar input, +#ed_reply_toolbar input { + overflow: visible; + padding: 0 4px; +} + +#poststuff h2 { + font-size: 1.6em; +} + +* html #poststuff h2 { + margin-left: 0; +} + +#bh { + margin: 7px 10px 0 0; + float: right; +} + +/* without this dashboard widgets appear in one column for some screen widths */ +div#dashboard-widgets { + padding-right: 1px; +} + +.tagchecklist span, .tagchecklist span a { + display: inline-block; + display: block; +} + +.tagchecklist span a { + margin: 4px 0 0 -9px; +} + +.tablenav .button-secondary, .nav .button-secondary { + padding: 0 1px; + vertical-align: middle; +} + +.tablenav select { + font-size: 13px; + display: inline-block; + vertical-align: top; + margin-top: 2px; +} + +.tablenav .actions select { + width: 155px; +} + +table.ie-fixed { + table-layout: fixed; +} + +.widefat tr, .widefat th { + margin-bottom: 0; + border-spacing: 0; +} + +.widefat th input { + margin: 0 0 0 5px; +} + +.widefat .check-column { + padding: 6px 0 2px; +} + +.widefat tbody th.check-column { + padding: 4px 0 22px; +} + +.widefat { + empty-cells: show; + border-collapse: collapse; +} + +.tablenav a.button-secondary { + display: inline-block; + padding: 2px 5px; +} + +* html .stuffbox, +* html .stuffbox input, +* html .stuffbox textarea { + border: 1px solid #DFDFDF; +} + +* html .feature-filter .feature-group li { + width: 145px; +} + +* html .widget-top .widget-title-action a { + background: url("../images/menu-bits.gif?ver=20100610") no-repeat scroll 0 -110px; +} + +* html div.widget-liquid-left { + width: 99%; +} + +#wp_inactive_widgets { + padding-bottom: 8px; +} + +* html .widgets-sortables { + height: 50px; +} + +* html a#content_resize { + right: -2px; +} + +* html .widget-title h4 { + width: 205px; +} + +* html #removing-widget .in-widget-title { + display: none; +} + +#available-widgets .widget-holder { + padding-bottom: 65px; +} + +#widgets-left .inactive { + padding-bottom: 10px; +} + +.widget-liquid-right .widget, +#wp_inactive_widgets .widget { + position: relative; +} + +* html .media-item .pinkynail { + height: 32px; + width: 40px; +} + +#wpcontent .button-primary-disabled { + color: #9FD0D5; + background: #298CBA; +} + +#wpcontent #ajax-loading, +#wpcontent .ajax-loading { + vertical-align: baseline; +} + +* html .describe .field input.text, +* html .describe .field textarea { + width: 440px; +} + +#the-comment-list .unapproved tr, +#the-comment-list .unapproved td { + background-color: #ffffe0; +} + +.imgedit-submit { + width: 300px; +} + +* html input { + border: 1px solid #dfdfdf; +} + +#nav-menu-header, +#nav-menus-frame, +#wpbody, +.menu li { + zoom:100%; +} + +#update-nav-menu #post-body { + overflow:hidden; +} + +.menu li { + min-width:100%; +} + +.menu li.sortable-placeholder { + min-width:400px; +} diff --git a/src/wp-admin/css/install-rtl.css b/src/wp-admin/css/install-rtl.css new file mode 100644 index 00000000..e422eced --- /dev/null +++ b/src/wp-admin/css/install-rtl.css @@ -0,0 +1 @@ +body{font-family:Tahoma,arial;}h1{font-family:arial;margin:5px -4px 0 0;}ul,ol{padding:5px 22px 5px 5px;}.step,th{text-align:right;}.submit input,.button,.button-secondary{font-family:Tahoma,arial;margin-right:0;}.form-table th{text-align:right;}#user_login,#admin_email,#pass1,#pass2{direction:ltr;} \ No newline at end of file diff --git a/src/wp-admin/css/install-rtl.dev.css b/src/wp-admin/css/install-rtl.dev.css new file mode 100644 index 00000000..9e0be997 --- /dev/null +++ b/src/wp-admin/css/install-rtl.dev.css @@ -0,0 +1,23 @@ +body { + font-family: Tahoma, arial; +} +h1 { + font-family: arial; + margin: 5px -4px 0 0; +} +ul, ol { + padding: 5px 22px 5px 5px; +} +.step, th { + text-align: right; +} +.submit input, .button, .button-secondary { + font-family: Tahoma, arial; + margin-right: 0; +} +.form-table th { + text-align: right; +} +#user_login, #admin_email, #pass1, #pass2 { + direction: ltr; +} \ No newline at end of file diff --git a/src/wp-admin/css/install.css b/src/wp-admin/css/install.css new file mode 100644 index 00000000..ba9fb398 --- /dev/null +++ b/src/wp-admin/css/install.css @@ -0,0 +1 @@ +html{background:#f9f9f9;}body{background:#fff;color:#333;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;margin:2em auto;width:700px;padding:1em 2em;-moz-border-radius:11px;-khtml-border-radius:11px;-webkit-border-radius:11px;border-radius:11px;border:1px solid #dfdfdf;}a{color:#2583ad;text-decoration:none;}a:hover{color:#d54e21;}h1{border-bottom:1px solid #dadada;clear:both;color:#666;font:24px Georgia,"Times New Roman",Times,serif;margin:5px 0 0 -4px;padding:0;padding-bottom:7px;}h2{font-size:16px;}p,li,dd,dt{padding-bottom:2px;font-size:12px;line-height:18px;}code,.code{font-size:13px;}ul,ol,dl{padding:5px 5px 5px 22px;}a img{border:0;}abbr{border:0;font-variant:normal;}#logo{margin:6px 0 14px 0;border-bottom:none;text-align:center;}.step{margin:20px 0 15px;}.step,th{text-align:left;padding:0;}.submit input,.button,.button-secondary{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;text-decoration:none;font-size:14px!important;line-height:16px;padding:6px 12px;cursor:pointer;border:1px solid #bbb;color:#464646;-moz-border-radius:15px;-khtml-border-radius:15px;-webkit-border-radius:15px;border-radius:15px;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;-khtml-box-sizing:content-box;box-sizing:content-box;}.button:hover,.button-secondary:hover,.submit input:hover{color:#000;border-color:#666;}.button,.submit input,.button-secondary{background:#f2f2f2 url(../images/white-grad.png) repeat-x scroll left top;}.button:active,.submit input:active,.button-secondary:active{background:#eee url(../images/white-grad-active.png) repeat-x scroll left top;}textarea{border:1px solid #bbb;-moz-border-radius:4px;-khtml-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;}.form-table{border-collapse:collapse;margin-top:1em;width:100%;}.form-table td{margin-bottom:9px;padding:10px;border-bottom:8px solid #fff;font-size:12px;}.form-table th{font-size:13px;text-align:left;padding:16px 10px 10px 10px;border-bottom:8px solid #fff;width:130px;vertical-align:top;}.form-table tr{background:#f3f3f3;}.form-table code{line-height:18px;font-size:18px;}.form-table p{margin:4px 0 0 0;font-size:11px;}.form-table input{line-height:20px;font-size:15px;padding:2px;}.form-table th p{font-weight:normal;}#error-page{margin-top:50px;}#error-page p{font-size:12px;line-height:18px;margin:25px 0 20px;}#error-page code,.code{font-family:Consolas,Monaco,Courier,monospace;}#pass-strength-result{background-color:#eee;border-color:#ddd!important;border-style:solid;border-width:1px;margin:5px 5px 5px 1px;padding:5px;text-align:center;width:200px;display:none;}#pass-strength-result.bad{background-color:#ffb78c;border-color:#ff853c!important;}#pass-strength-result.good{background-color:#ffec8b;border-color:#fc0!important;}#pass-strength-result.short{background-color:#ffa0a0;border-color:#f04040!important;}#pass-strength-result.strong{background-color:#c3ff88;border-color:#8dff1c!important;}.message{border:1px solid #e6db55;padding:.3em .6em;margin:5px 0 15px;background-color:#ffffe0;} \ No newline at end of file diff --git a/src/wp-admin/css/install.dev.css b/src/wp-admin/css/install.dev.css new file mode 100644 index 00000000..ed334dfb --- /dev/null +++ b/src/wp-admin/css/install.dev.css @@ -0,0 +1,213 @@ +html { + background: #f9f9f9; +} + +body { + background: #fff; + color: #333; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + margin: 2em auto; + width: 700px; + padding: 1em 2em; + -moz-border-radius: 11px; + -khtml-border-radius: 11px; + -webkit-border-radius: 11px; + border-radius: 11px; + border: 1px solid #dfdfdf; +} + +a { + color: #2583ad; + text-decoration: none; +} + +a:hover { + color: #d54e21; +} + +h1 { + border-bottom: 1px solid #dadada; + clear: both; + color: #666; + font: 24px Georgia, "Times New Roman", Times, serif; + margin: 5px 0 0 -4px; + padding: 0; + padding-bottom: 7px; +} + +h2 { + font-size: 16px; +} + +p, li, dd, dt { + padding-bottom: 2px; + font-size: 12px; + line-height: 18px; +} + +code, .code { + font-size: 13px; +} + +ul, ol, dl { + padding: 5px 5px 5px 22px; +} + +a img { + border:0 +} +abbr { + border: 0; + font-variant: normal; +} +#logo { + margin: 6px 0 14px 0; + border-bottom: none; + text-align:center +} +.step { + margin: 20px 0 15px; +} +.step, th { + text-align: left; + padding: 0; +} + +.submit input, .button, .button-secondary { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + text-decoration: none; + font-size: 14px !important; + line-height: 16px; + padding: 6px 12px; + cursor: pointer; + border: 1px solid #bbb; + color: #464646; + -moz-border-radius: 15px; + -khtml-border-radius: 15px; + -webkit-border-radius: 15px; + border-radius: 15px; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + -khtml-box-sizing: content-box; + box-sizing: content-box; +} + +.button:hover, .button-secondary:hover, .submit input:hover { + color: #000; + border-color: #666; +} + +.button, .submit input, .button-secondary { + background: #f2f2f2 url(../images/white-grad.png) repeat-x scroll left top; +} + +.button:active, .submit input:active, .button-secondary:active { + background: #eee url(../images/white-grad-active.png) repeat-x scroll left top; +} + +textarea { + border: 1px solid #bbb; + -moz-border-radius: 4px; + -khtml-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +.form-table { + border-collapse: collapse; + margin-top: 1em; + width: 100%; +} + +.form-table td { + margin-bottom: 9px; + padding: 10px; + border-bottom: 8px solid #fff; + font-size: 12px; +} + +.form-table th { + font-size: 13px; + text-align: left; + padding: 16px 10px 10px 10px; + border-bottom: 8px solid #fff; + width: 130px; + vertical-align: top; +} + +.form-table tr { + background: #f3f3f3; +} + +.form-table code { + line-height: 18px; + font-size: 18px; +} + +.form-table p { + margin: 4px 0 0 0; + font-size: 11px; +} + +.form-table input { + line-height: 20px; + font-size: 15px; + padding: 2px; +} + +.form-table th p { + font-weight: normal; +} + +#error-page { + margin-top: 50px; +} + +#error-page p { + font-size: 12px; + line-height: 18px; + margin: 25px 0 20px; +} + +#error-page code, .code { + font-family: Consolas, Monaco, Courier, monospace; +} + +#pass-strength-result { + background-color: #eee; + border-color: #ddd !important; + border-style: solid; + border-width: 1px; + margin: 5px 5px 5px 1px; + padding: 5px; + text-align: center; + width: 200px; + display: none; +} + +#pass-strength-result.bad { + background-color: #ffb78c; + border-color: #ff853c !important; +} + +#pass-strength-result.good { + background-color: #ffec8b; + border-color: #ffcc00 !important; +} + +#pass-strength-result.short { + background-color: #ffa0a0; + border-color: #f04040 !important; +} + +#pass-strength-result.strong { + background-color: #c3ff88; + border-color: #8dff1c !important; +} + +.message { + border: 1px solid #e6db55; + padding: 0.3em 0.6em; + margin: 5px 0 15px; + background-color: #ffffe0; +} diff --git a/src/wp-admin/css/login-rtl.css b/src/wp-admin/css/login-rtl.css new file mode 100644 index 00000000..11040fae --- /dev/null +++ b/src/wp-admin/css/login-rtl.css @@ -0,0 +1 @@ +body{font-family:Tahoma,arial;}form{margin-right:8px;margin-left:0;}form .forgetmenot{float:right;}#login form .submit input{font-family:Tahoma,arial;}form .submit{float:left;}#backtoblog a{padding:8px 15px 0 0;}#login_error,.message{margin:0 8px 16px 0;}#nav{margin:0 8px 0 0;}#user_pass,#user_login,#user_email{margin-left:6px;margin-right:0;direction:ltr;}h1 a{text-decoration:none;} \ No newline at end of file diff --git a/src/wp-admin/css/login-rtl.dev.css b/src/wp-admin/css/login-rtl.dev.css new file mode 100644 index 00000000..954b320a --- /dev/null +++ b/src/wp-admin/css/login-rtl.dev.css @@ -0,0 +1,29 @@ +body { + font-family: Tahoma, arial; +} +form { + margin-right: 8px; + margin-left: 0; +} +form .forgetmenot { + float: right; +} +#login form .submit input { + font-family: Tahoma, arial; +} +form .submit { float: left; } +#backtoblog a { + padding: 8px 15px 0 0; +} +#login_error, .message { + margin: 0 8px 16px 0; +} +#nav { margin: 0 8px 0 0; } +#user_pass, #user_login, #user_email { + margin-left: 6px; + margin-right: 0; + direction:ltr; +} +h1 a { + text-decoration: none; +} diff --git a/src/wp-admin/css/login.css b/src/wp-admin/css/login.css new file mode 100644 index 00000000..12760316 --- /dev/null +++ b/src/wp-admin/css/login.css @@ -0,0 +1 @@ +*{margin:0;padding:0;}body{padding-top:30px;font:11px "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;}form{margin-left:8px;padding:16px 16px 40px 16px;font-weight:normal;-moz-border-radius:11px;-khtml-border-radius:11px;-webkit-border-radius:11px;border-radius:11px;background:#fff;border:1px solid #e5e5e5;-moz-box-shadow:rgba(200,200,200,1) 0 4px 18px;-webkit-box-shadow:rgba(200,200,200,1) 0 4px 18px;-khtml-box-shadow:rgba(200,200,200,1) 0 4px 18px;box-shadow:rgba(200,200,200,1) 0 4px 18px;}form .forgetmenot{font-weight:normal;float:left;margin-bottom:0;}.button-primary{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;padding:3px 10px;border:none;font-size:12px;border-width:1px;border-style:solid;-moz-border-radius:11px;-khtml-border-radius:11px;-webkit-border-radius:11px;border-radius:11px;cursor:pointer;text-decoration:none;margin-top:-3px;}#login form p{margin-bottom:0;}label{color:#777;font-size:13px;}form .forgetmenot label{font-size:11px;line-height:19px;}form .submit,.alignright{float:right;}form p{margin-bottom:24px;}h1 a{background:url(../images/logo-login.gif) no-repeat top center;width:326px;height:67px;text-indent:-9999px;overflow:hidden;padding-bottom:15px;display:block;}#nav{text-shadow:rgba(255,255,255,1) 0 1px 0;}#backtoblog{position:absolute;top:0;left:0;border-bottom:#c6c6c6 1px solid;background:#d9d9d9;background:-moz-linear-gradient(bottom,#d7d7d7,#e4e4e4);background:-webkit-gradient(linear,left bottom,left top,from(#d7d7d7),to(#e4e4e4));height:30px;width:100%;}#backtoblog a{text-decoration:none;display:block;padding:8px 0 0 15px;}#login{width:320px;margin:7em auto;}#login_error,.message{margin:0 0 16px 8px;border-width:1px;border-style:solid;padding:12px;-moz-border-radius:3px;-khtml-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}#nav{margin:0 0 0 8px;padding:16px;}body form .input{font-size:24px;width:97%;padding:3px;margin-top:2px;margin-right:6px;margin-bottom:16px;border:1px solid #e5e5e5;background:#fbfbfb;}input{color:#555;}.clear{clear:both;}#pass-strength-result{font-weight:bold;border-style:solid;border-width:1px;margin:12px 0 6px;padding:6px 5px;text-align:center;} \ No newline at end of file diff --git a/src/wp-admin/css/login.dev.css b/src/wp-admin/css/login.dev.css new file mode 100644 index 00000000..6124b877 --- /dev/null +++ b/src/wp-admin/css/login.dev.css @@ -0,0 +1,147 @@ +* { margin: 0; padding: 0; } + +body { + padding-top: 30px; + font: 11px "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; +} + +form { + margin-left: 8px; + padding: 16px 16px 40px 16px; + font-weight: normal; + -moz-border-radius: 11px; + -khtml-border-radius: 11px; + -webkit-border-radius: 11px; + border-radius: 11px; + background: #fff; + border: 1px solid #e5e5e5; + -moz-box-shadow: rgba(200,200,200,1) 0 4px 18px; + -webkit-box-shadow: rgba(200,200,200,1) 0 4px 18px; + -khtml-box-shadow: rgba(200,200,200,1) 0 4px 18px; + box-shadow: rgba(200,200,200,1) 0 4px 18px; +} + +form .forgetmenot { + font-weight: normal; + float: left; + margin-bottom: 0; +} + +.button-primary { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + padding: 3px 10px; + border: none; + font-size: 12px; + border-width: 1px; + border-style: solid; + -moz-border-radius: 11px; + -khtml-border-radius: 11px; + -webkit-border-radius: 11px; + border-radius: 11px; + cursor: pointer; + text-decoration: none; + margin-top: -3px; +} + +#login form p { + margin-bottom: 0; +} + +label { + color: #777; + font-size: 13px; +} + +form .forgetmenot label { + font-size: 11px; + line-height: 19px; +} + +form .submit, +.alignright { + float: right; +} + +form p { + margin-bottom: 24px; +} + +h1 a { + background: url(../images/logo-login.gif) no-repeat top center; + width: 326px; + height: 67px; + text-indent: -9999px; + overflow: hidden; + padding-bottom: 15px; + display: block; +} + +#nav { + text-shadow: rgba(255,255,255,1) 0 1px 0; +} + +#backtoblog { + position: absolute; + top: 0; + left: 0; + border-bottom: #c6c6c6 1px solid; + background: #d9d9d9; /* fallback color */ + background: -moz-linear-gradient(bottom, #d7d7d7, #e4e4e4); + background: -webkit-gradient(linear, left bottom, left top, from(#d7d7d7), to(#e4e4e4)); + height: 30px; + width: 100%; +} + +#backtoblog a { + text-decoration: none; + display: block; + padding: 8px 0 0 15px; +} + +#login { width: 320px; margin: 7em auto; } + +#login_error, +.message { + margin: 0 0 16px 8px; + border-width: 1px; + border-style: solid; + padding: 12px; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +#nav { + margin: 0 0 0 8px; + padding: 16px; +} + +body form .input { + font-size: 24px; + width: 97%; + padding: 3px; + margin-top: 2px; + margin-right: 6px; + margin-bottom: 16px; + border: 1px solid #e5e5e5; + background: #fbfbfb; +} + +input { + color: #555; +} + +.clear { + clear: both; +} + +#pass-strength-result { + font-weight: bold; + border-style: solid; + border-width: 1px; + margin: 12px 0 6px; + padding: 6px 5px; + text-align: center; +} + diff --git a/src/wp-admin/css/media-rtl.css b/src/wp-admin/css/media-rtl.css new file mode 100644 index 00000000..5b9e9414 --- /dev/null +++ b/src/wp-admin/css/media-rtl.css @@ -0,0 +1 @@ +body#media-upload ul#sidemenu{left:auto;right:0;}#search-filter{text-align:left;}.align .field label{padding:0 28px 0 0;margin:0 0 0 1em;}.image-align-none-label,.image-align-left-label,.image-align-center-label,.image-align-right-label{background-position:center right;}tr.image-size div.image-size-item{float:right;}tr.image-size label{margin:0 1em 0 0;}.filename.original{float:right;}.crunching{text-align:left;margin-right:0;margin-left:5px;}button.dismiss{right:auto;left:5px;}.file-error{margin:0 50px 5px 0;}.progress{left:auto;right:0;}.describe td{padding:0 0 0 5px;}.bar{border-right-width:0;border-left-width:3px;border-right-style:none;border-left-style:solid;}#media-upload .media-upload-form p{margin:0 0 1em 1em;}.filename{float:right;margin-left:0;margin-right:10px;}#media-upload .describe th.label{text-align:right;}.menu_order{float:left;}.media-upload-form label.form-help,td.help,#media-upload p.help,#media-upload label.help{font-family:Tahoma,Arial;}#gallery-settings #basic th.label{padding:5px 0 5px 5px;}#gallery-settings .title,h3.media-title{font-family:Tahoma,Arial;}#gallery-settings .describe th.label{text-align:right;}#gallery-settings label,#gallery-settings legend{margin-right:0;margin-left:15px;}#gallery-settings .align .field label{margin:0 0 0 1.5em;} \ No newline at end of file diff --git a/src/wp-admin/css/media-rtl.dev.css b/src/wp-admin/css/media-rtl.dev.css new file mode 100644 index 00000000..fed86444 --- /dev/null +++ b/src/wp-admin/css/media-rtl.dev.css @@ -0,0 +1,85 @@ +body#media-upload ul#sidemenu { + left: auto; + right: 0; +} +#search-filter { + text-align: left; +} +/* specific to the image upload form */ +.align .field label { + padding: 0 28px 0 0; + margin: 0 0 0 1em; +} +.image-align-none-label, .image-align-left-label, .image-align-center-label, .image-align-right-label { + background-position: center right; +} +tr.image-size div.image-size-item { + float: right; +} +tr.image-size label { + margin: 0 1em 0 0; +} +.filename.original { + float: right; +} +.crunching { + text-align: left; + margin-right: 0; + margin-left: 5px; +} +button.dismiss { + right: auto; + left: 5px; +} +.file-error { + margin: 0 50px 5px 0; +} +.progress { + left: auto; + right: 0; +} +.describe td { + padding: 0 0 0 5px; +} +.bar { + border-right-width: 0; + border-left-width: 3px; + border-right-style: none; + border-left-style: solid; +} + +/* Specific to Uploader */ +#media-upload .media-upload-form p { + margin: 0 0 1em 1em; +} +.filename { + float: right; + margin-left: 0; + margin-right: 10px; +} +#media-upload .describe th.label { + text-align: right; +} +.menu_order { + float: left; +} +.media-upload-form label.form-help, td.help, #media-upload p.help, #media-upload label.help { + font-family: Tahoma, Arial; +} +#gallery-settings #basic th.label { + padding: 5px 0 5px 5px; +} +#gallery-settings .title, h3.media-title { + font-family: Tahoma, Arial; +} +#gallery-settings .describe th.label { + text-align: right; +} +#gallery-settings label, +#gallery-settings legend { + margin-right: 0; + margin-left: 15px; +} +#gallery-settings .align .field label { + margin: 0 0 0 1.5em; +} diff --git a/src/wp-admin/css/media.css b/src/wp-admin/css/media.css new file mode 100644 index 00000000..7daea260 --- /dev/null +++ b/src/wp-admin/css/media.css @@ -0,0 +1 @@ +div#media-upload-header{margin:0;padding:0 5px;font-weight:bold;position:relative;border-bottom-width:1px;border-bottom-style:solid;}body#media-upload ul#sidemenu{font-weight:normal;margin:0 5px;left:0;bottom:-1px;float:none;overflow:hidden;}div#media-upload-error{margin:1em;font-weight:bold;}form{margin:1em;}#search-filter{text-align:right;}th{position:relative;}.media-upload-form label.form-help,td.help{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-style:italic;font-weight:normal;}.media-upload-form p.help{margin:0;padding:0;}.media-upload-form fieldset{width:100%;border:none;text-align:justify;margin:0 0 1em 0;padding:0;}.image-align-none-label{background:url(../images/align-none.png) no-repeat center left;}.image-align-left-label{background:url(../images/align-left.png) no-repeat center left;}.image-align-center-label{background:url(../images/align-center.png) no-repeat center left;}.image-align-right-label{background:url(../images/align-right.png) no-repeat center left;}tr.image-size td{width:460px;}tr.image-size div.image-size-item{float:left;width:25%;margin:0;}#library-form .progress,#gallery-form .progress,#flash-upload-ui,.insert-gallery,.describe.startopen,.describe.startclosed{display:none;}.media-item .thumbnail{max-width:128px;max-height:128px;}thead.media-item-info tr{background-color:transparent;}thead.media-item-info th,thead.media-item-info td{border:none;margin:0;}.form-table thead.media-item-info{border:8px solid #fff;}abbr.required{text-decoration:none;border:none;}.describe label{display:inline;}.describe td{vertical-align:middle;padding:0 5px 8px 0;}.describe td.error{padding:2px 8px;}.describe td.A1{width:132px;}.describe input[type="text"],.describe textarea{width:460px;border-width:1px;border-style:solid;}.hidden{height:0;width:0;overflow:hidden;border:none;}#media-upload p.ml-submit{padding:1em 0;}#media-upload p.help,#media-upload label.help{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-style:italic;font-weight:normal;}#media-upload tr.image-size td.field{text-align:center;}#media-upload #media-items{border-width:1px;border-style:solid;border-bottom:none;width:623px;}#media-upload .media-item{border-bottom-width:1px;border-bottom-style:solid;min-height:36px;width:100%;}#media-upload .ui-sortable .media-item{cursor:move;}.filename{line-height:36px;padding:0 10px;overflow:hidden;}#media-upload .describe{width:100%;clear:both;cursor:default;}#media-upload .slidetoggle{border-top-width:1px;border-top-style:solid;}#media-upload .describe th.label{padding-top:.2em;text-align:left;min-width:120px;}#media-upload tr.align td.field{text-align:center;}#media-upload tr.image-size{margin-bottom:1em;height:3em;}#media-upload #filter{width:623px;}#media-upload #filter .subsubsub{margin:8px 0;}#filter .tablenav select{border-style:solid;border-width:1px;padding:2px;vertical-align:top;width:auto;}#media-upload .del-attachment{display:none;margin:5px 0;}.menu_order{float:right;font-size:11px;margin:10px 10px 0;}.menu_order_input{border:1px solid #ddd;font-size:10px;padding:1px;width:23px;}.ui-sortable-helper{background-color:#fff;border:1px solid #aaa;opacity:.6;filter:alpha(opacity=60);}#media-upload th.order-head{width:20%;text-align:center;}#media-upload th.actions-head{width:25%;text-align:center;}#media-upload a.wp-post-thumbnail{margin:0 20px;}#media-items a.delete{display:block;float:right;}#media-upload .widefat{width:626px;border-style:solid solid none;}.sorthelper{height:37px;width:623px;display:block;}#gallery-settings th.label{width:160px;}#gallery-settings #basic th.label{padding:5px 5px 5px 0;}#gallery-settings .title{clear:both;padding:0 0 3px;font-size:1.6em;border-bottom:1px solid #DADADA;}h3.media-title{font-size:1.6em;}h4.media-sub-title{border-bottom:1px solid #DADADA;font-size:1.3em;margin:12px;padding:0 0 3px;}#gallery-settings .title,h3.media-title,h4.media-sub-title{font-family:Georgia,"Times New Roman",Times,serif;font-weight:normal;color:#5A5A5A;}#gallery-settings .describe td{vertical-align:middle;height:3em;}#gallery-settings .describe th.label{padding-top:.5em;text-align:left;}#gallery-settings .describe{padding:5px;width:615px;clear:both;cursor:default;}#gallery-settings .describe select{width:15em;}#gallery-settings .describe select option,#gallery-settings .describe td{padding:0;}#gallery-settings label,#gallery-settings legend{font-size:13px;color:#464646;margin-right:15px;}#gallery-settings .align .field label{margin:0 1.5em 0 0;}#gallery-settings p.ml-submit{border-top:1px solid #dfdfdf;}#gallery-settings select#columns{width:6em;}#sort-buttons{font-size:.8em;margin:3px 25px -8px 0;text-align:right;max-width:625px;}#sort-buttons a{text-decoration:none;}#sort-buttons #asc,#sort-buttons #showall{padding-left:5px;}#sort-buttons span{margin-right:25px;} \ No newline at end of file diff --git a/src/wp-admin/css/media.dev.css b/src/wp-admin/css/media.dev.css new file mode 100644 index 00000000..3c257728 --- /dev/null +++ b/src/wp-admin/css/media.dev.css @@ -0,0 +1,383 @@ +div#media-upload-header { + margin: 0; + padding: 0 5px; + font-weight: bold; + position: relative; + border-bottom-width: 1px; + border-bottom-style: solid; +} + +body#media-upload ul#sidemenu { + font-weight: normal; + margin: 0 5px; + left: 0; + bottom: -1px; + float: none; + overflow: hidden; +} + +div#media-upload-error { + margin: 1em; + font-weight: bold; +} + +form { + margin: 1em; +} + +#search-filter { + text-align: right; +} + +th { + position: relative; +} + +.media-upload-form label.form-help, td.help { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-style: italic; + font-weight: normal; +} + +.media-upload-form p.help { + margin: 0; + padding: 0; +} + +.media-upload-form fieldset { + width: 100%; + border: none; + text-align: justify; + margin: 0 0 1em 0; + padding: 0; +} + +/* specific to the image upload form */ + + +.image-align-none-label { + background: url(../images/align-none.png) no-repeat center left; +} + +.image-align-left-label { + background: url(../images/align-left.png) no-repeat center left; +} + +.image-align-center-label { + background: url(../images/align-center.png) no-repeat center left; +} + +.image-align-right-label { + background: url(../images/align-right.png) no-repeat center left; +} + +tr.image-size td { + width: 460px; +} + +tr.image-size div.image-size-item { + float: left; + width: 25%; + margin: 0; +} + +#library-form .progress, +#gallery-form .progress, +#flash-upload-ui, +.insert-gallery, +.describe.startopen, +.describe.startclosed { + display: none; +} + +.media-item .thumbnail { + max-width: 128px; + max-height: 128px; +} + +thead.media-item-info tr { + background-color: transparent; +} + +thead.media-item-info th, +thead.media-item-info td { + border: none; + margin: 0; +} + +.form-table thead.media-item-info { + border: 8px solid #fff; +} + +abbr.required { + text-decoration: none; + border: none; +} + +.describe label { + display: inline; +} + +.describe td { + vertical-align: middle; + padding: 0 5px 8px 0; +} + +.describe td.error { + padding: 2px 8px; +} + +.describe td.A1 { + width: 132px; +} + +.describe input[type="text"], +.describe textarea { + width: 460px; + border-width: 1px; + border-style: solid; +} + +.hidden { + height: 0; + width: 0; + overflow: hidden; + border: none; +} + +/* Specific to Uploader */ + +#media-upload p.ml-submit { + padding: 1em 0; +} + +#media-upload p.help, +#media-upload label.help { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-style: italic; + font-weight: normal; +} + +#media-upload tr.image-size td.field { + text-align: center; +} + +#media-upload #media-items { + border-width: 1px; + border-style: solid; + border-bottom: none; + width: 623px; +} + +#media-upload .media-item { + border-bottom-width: 1px; + border-bottom-style: solid; + min-height: 36px; + width: 100%; +} + +#media-upload .ui-sortable .media-item { + cursor: move; +} + +.filename { + line-height: 36px; + padding: 0 10px; + overflow: hidden; +} + +#media-upload .describe { + width: 100%; + clear: both; + cursor: default; +} + +#media-upload .slidetoggle { + border-top-width: 1px; + border-top-style: solid; +} + +#media-upload .describe th.label { + padding-top: .2em; + text-align: left; + min-width: 120px; +} + +#media-upload tr.align td.field { + text-align: center; +} + +#media-upload tr.image-size { + margin-bottom: 1em; + height: 3em; +} + +#media-upload #filter { + width: 623px; +} + +#media-upload #filter .subsubsub { + margin: 8px 0; +} + +#filter .tablenav select { + border-style: solid; + border-width: 1px; + padding: 2px; + vertical-align: top; + width: auto; +} + +#media-upload .del-attachment { + display: none; + margin: 5px 0; +} + +.menu_order { + float: right; + font-size: 11px; + margin: 10px 10px 0; +} + +.menu_order_input { + border: 1px solid #ddd; + font-size: 10px; + padding: 1px; + width: 23px; +} + +.ui-sortable-helper { + background-color: #fff; + border: 1px solid #aaa; + opacity: 0.6; + filter: alpha(opacity=60); +} + +#media-upload th.order-head { + width: 20%; + text-align: center; +} + +#media-upload th.actions-head { + width: 25%; + text-align: center; +} + +#media-upload a.wp-post-thumbnail { + margin: 0 20px; +} + +#media-items a.delete { + display: block; + float: right; +} + +#media-upload .widefat { + width: 626px; + border-style: solid solid none; +} + +.sorthelper { + height: 37px; + width: 623px; + display: block; +} + +#gallery-settings th.label { + width: 160px; +} + +#gallery-settings #basic th.label { + padding: 5px 5px 5px 0; +} + +#gallery-settings .title { + clear: both; + padding: 0 0 3px; + font-size: 1.6em; + border-bottom: 1px solid #DADADA; +} + +h3.media-title { + font-size: 1.6em; +} + +h4.media-sub-title { + border-bottom: 1px solid #DADADA; + font-size: 1.3em; + margin: 12px; + padding: 0 0 3px; +} + +#gallery-settings .title, +h3.media-title, +h4.media-sub-title { + font-family: Georgia,"Times New Roman",Times,serif; + font-weight: normal; + color: #5A5A5A; +} + +#gallery-settings .describe td { + vertical-align: middle; + height: 3em; +} + +#gallery-settings .describe th.label { + padding-top: .5em; + text-align: left; +} + +#gallery-settings .describe { + padding: 5px; + width: 615px; + clear: both; + cursor: default; +} + +#gallery-settings .describe select { + width: 15em; +} + +#gallery-settings .describe select option, +#gallery-settings .describe td { + padding: 0; +} + +#gallery-settings label, +#gallery-settings legend { + font-size: 13px; + color: #464646; + margin-right: 15px; +} + +#gallery-settings .align .field label { + margin: 0 1.5em 0 0; +} + +#gallery-settings p.ml-submit { + border-top: 1px solid #dfdfdf; +} + +#gallery-settings select#columns { + width: 6em; +} + +#sort-buttons { + font-size: 0.8em; + margin: 3px 25px -8px 0; + text-align: right; + max-width: 625px; +} + +#sort-buttons a { + text-decoration: none; +} + +#sort-buttons #asc, +#sort-buttons #showall { + padding-left: 5px; +} + +#sort-buttons span { + margin-right: 25px; +} diff --git a/src/wp-admin/css/ms.css b/src/wp-admin/css/ms.css new file mode 100644 index 00000000..a7e39823 --- /dev/null +++ b/src/wp-admin/css/ms.css @@ -0,0 +1 @@ +#dashboard_right_now p.musub{margin-top:12px;border-top:1px solid #ececec;padding-left:16px;position:static;}#dashboard_right_now td.b a.musublink{font-size:16px;}#dashboard_right_now div.musubtable{border-top:none;}#dashboard_right_now div.musubtable .t{white-space:normal;}.site-deleted{background:#ff8573;}.site-spammed{background:#faafaa;}.site-archived{background:#ffebe8;}.site-mature{background:#fecac2;} \ No newline at end of file diff --git a/src/wp-admin/css/ms.dev.css b/src/wp-admin/css/ms.dev.css new file mode 100644 index 00000000..0fb158a1 --- /dev/null +++ b/src/wp-admin/css/ms.dev.css @@ -0,0 +1,33 @@ +/* Dashboard: MS Specific Data */ +#dashboard_right_now p.musub { + margin-top: 12px; + border-top: 1px solid #ececec; + padding-left: 16px; + position: static; +} + +#dashboard_right_now td.b a.musublink { + font-size: 16px; +} + +#dashboard_right_now div.musubtable { + border-top: none; +} + +#dashboard_right_now div.musubtable .t { + white-space: normal; +} + +/* Background Color for Site Status */ +.site-deleted { + background: #ff8573; +} +.site-spammed { + background: #faafaa; +} +.site-archived { + background: #ffebe8; +} +.site-mature { + background: #fecac2; +} diff --git a/src/wp-admin/css/nav-menu-rtl.css b/src/wp-admin/css/nav-menu-rtl.css new file mode 100644 index 00000000..9d24ddda --- /dev/null +++ b/src/wp-admin/css/nav-menu-rtl.css @@ -0,0 +1 @@ +#nav-menus-frame{margin-right:300px;margin-left:0;}#wpbody-content #menu-settings-column{margin-right:-300px;margin-left:0;float:right;}#menu-management-liquid{float:right;}#menu-management{margin-left:20px;margin-right:0;}#post-body{padding:0 10px 10px 0;}.post-body-plain{padding:10px 0 0 10px;}#menu-management .nav-tabs-arrow-left{right:0;left:auto;}#menu-management .nav-tabs-arrow-right{left:0;right:auto;text-align:left;}#menu-management .nav-tabs{padding-right:20px;padding-left:10px;}.js #menu-management .nav-tabs{float:right;margin-right:0;margin-left:-400px;}#select-nav-menu-container{text-align:left;}#wpbody .open-label{float:right;}#wpbody .open-label span{padding-left:10px;padding-right:0;}.js .input-with-default-title{font-style:normal;font-weight:bold;}.postbox .howto input{float:left;}#nav-menu-theme-locations .button-controls{text-align:left;}.meta-sep,.submitdelete,.submitcancel{float:right;}#cancel-save{margin-right:20px;margin-left:0;}.list-controls{float:right;}.add-to-menu{float:left;}#add-custom-link label span{float:right;padding-left:5px;padding-right:0;}.howto span{float:right;}.list li .menu-item-title input{margin-left:3px;margin-right:0;}.menu-item-handle{padding-right:10px;padding-left:0;}.menu-item-edit-active .menu-item-handle{-moz-border-radius:6px 6px 0 0;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;-khtml-border-bottom-left-radius:0;-khtml-border-bottom-right-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0;}.menu-item-handle .item-title{margin-left:13em;margin-right:0;}.menu-item-depth-0{margin-right:0;margin-left:0;}.menu-item-depth-1{margin-right:30px;margin-left:0;}.menu-item-depth-2{margin-right:60px;margin-left:0;}.menu-item-depth-3{margin-right:90px;margin-left:0;}.menu-item-depth-4{margin-right:120px;margin-left:0;}.menu-item-depth-5{margin-right:150px;margin-left:0;}.menu-item-depth-6{margin-right:180px;margin-left:0;}.menu-item-depth-7{margin-right:210px;margin-left:0;}.menu-item-depth-8{margin-right:240px;margin-left:0;}.menu-item-depth-9{margin-right:270px;margin-left:0;}.menu-item-depth-10{margin-right:300px;margin-left:0;}.menu-item-depth-11{margin-right:330px;margin-left:0;}.menu-item-depth-0 .menu-item-transport{margin-right:0;margin-left:0;}.menu-item-depth-1 .menu-item-transport{margin-right:-30px;margin-left:0;}.menu-item-depth-2 .menu-item-transport{margin-right:-60px;margin-left:0;}.menu-item-depth-3 .menu-item-transport{margin-right:-90px;margin-left:0;}.menu-item-depth-4 .menu-item-transport{margin-right:-120px;margin-left:0;}.menu-item-depth-5 .menu-item-transport{margin-right:-150px;margin-left:0;}.menu-item-depth-6 .menu-item-transport{margin-right:-180px;margin-left:0;}.menu-item-depth-7 .menu-item-transport{margin-right:-210px;margin-left:0;}.menu-item-depth-8 .menu-item-transport{margin-right:-240px;margin-left:0;}.menu-item-depth-9 .menu-item-transport{margin-right:-270px;margin-left:0;}.menu-item-depth-10 .menu-item-transport{margin-right:-300px;margin-left:0;}.menu-item-depth-11 .menu-item-transport{margin-right:-330px;margin-left:0;}.item-type{padding-left:10px;padding-right:0;}.item-controls{left:20px;right:auto;}.item-controls .item-order{padding-left:10px;padding-right:0;}.item-edit{background-image:url("../images/menu-bits-rtl.gif?ver=20100531");background-position:100% -105px;left:-20px;right:auto;-moz-border-radius-bottomright:3px;-moz-border-radius-bottomleft:0;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:0;-khtml-border-bottom-right-radius:3px;-khtml-border-bottom-left-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:0;}.menu-item-settings{padding:10px 10px 10px 0;border-width:0 1px 1px 1px;}.link-to-original{font-style:normal;font-weight:bold;}.link-to-original a{padding-right:4px;padding-left:0;}.menu-item-settings .description-thin,.menu-item-settings .description-wide{margin-left:10px;margin-right:0;float:right;}.major-publishing-actions .publishing-action{text-align:left;float:left;}.major-publishing-actions .delete-action{text-align:right;float:right;padding-left:15px;padding-right:0;}.menu-name-label{margin-left:15px;margin-right:0;}.auto-add-pages{float:right;} \ No newline at end of file diff --git a/src/wp-admin/css/nav-menu-rtl.dev.css b/src/wp-admin/css/nav-menu-rtl.dev.css new file mode 100644 index 00000000..523e2165 --- /dev/null +++ b/src/wp-admin/css/nav-menu-rtl.dev.css @@ -0,0 +1,206 @@ +#nav-menus-frame { + margin-right: 300px; + margin-left: 0; +} + +#wpbody-content #menu-settings-column { + margin-right: -300px; + margin-left: 0; + float: right; +} + +/* Menu Container */ +#menu-management-liquid { + float: right; +} +#menu-management { + margin-left: 20px; + margin-right: 0; +} + + + #post-body { + padding:0 10px 10px 0; + } + + .post-body-plain { + padding: 10px 0 0 10px; + } + +/* Menu Tabs */ + + #menu-management .nav-tabs-arrow-left { + right: 0; + left:auto; + } + #menu-management .nav-tabs-arrow-right { + left: 0; + right:auto; + text-align: left; + } + +#menu-management .nav-tabs { + padding-right: 20px; + padding-left: 10px; +} +.js #menu-management .nav-tabs { + float: right; + margin-right: 0px; + margin-left: -400px; +} + +#select-nav-menu-container { + text-align: left; +} + +#wpbody .open-label { + float:right; +} + +#wpbody .open-label span { + padding-left: 10px; + padding-right:0; +} + + .js .input-with-default-title { + font-style: normal; + font-weight:bold; + } + +/* Add Menu Item Boxes */ +.postbox .howto input { + float: left; +} +#nav-menu-theme-locations .button-controls { + text-align: left; +} + +/* Button Primary Actions */ + +.meta-sep, +.submitdelete, +.submitcancel { + float:right; +} + +#cancel-save { margin-right: 20px; margin-left: 0; } + +/* Button Secondary Actions */ +.list-controls { float: right; } +.add-to-menu { + float: left; +} + +/* Custom Links */ +#add-custom-link label span { float: right; padding-left: 5px; padding-right:0;} +.howto span { float: right; } + +.list li .menu-item-title input { margin-left: 3px; margin-right: 0 } + +/* Nav Menu */ +.menu-item-handle { + padding-right: 10px; + padding-left: 0; +} +.menu-item-edit-active .menu-item-handle { + -moz-border-radius: 6px 6px 0 0; + -webkit-border-bottom-left-radius: 0; + -webkit-border-bottom-right-radius: 0; + -khtml-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +.menu-item-handle .item-title { + margin-left:13em; + margin-right:0; +} + + +/* WARNING: The factor of 30px is hardcoded into the nav-menus javascript. */ +.menu-item-depth-0 { margin-right: 0px; margin-left:0;} +.menu-item-depth-1 { margin-right: 30px; margin-left:0;} +.menu-item-depth-2 { margin-right: 60px; margin-left:0;} +.menu-item-depth-3 { margin-right: 90px; margin-left:0;} +.menu-item-depth-4 { margin-right: 120px; margin-left:0;} +.menu-item-depth-5 { margin-right: 150px; margin-left:0;} +.menu-item-depth-6 { margin-right: 180px; margin-left:0;} +.menu-item-depth-7 { margin-right: 210px; margin-left:0;} +.menu-item-depth-8 { margin-right: 240px; margin-left:0;} +.menu-item-depth-9 { margin-right: 270px; margin-left:0;} +.menu-item-depth-10 { margin-right: 300px; margin-left:0;} +.menu-item-depth-11 { margin-right: 330px; margin-left:0;} + +.menu-item-depth-0 .menu-item-transport { margin-right: 0px; margin-left:0;} +.menu-item-depth-1 .menu-item-transport { margin-right: -30px; margin-left:0;} +.menu-item-depth-2 .menu-item-transport { margin-right: -60px; margin-left:0;} +.menu-item-depth-3 .menu-item-transport { margin-right: -90px; margin-left:0;} +.menu-item-depth-4 .menu-item-transport { margin-right: -120px; margin-left:0;} +.menu-item-depth-5 .menu-item-transport { margin-right: -150px; margin-left:0;} +.menu-item-depth-6 .menu-item-transport { margin-right: -180px; margin-left:0;} +.menu-item-depth-7 .menu-item-transport { margin-right: -210px; margin-left:0;} +.menu-item-depth-8 .menu-item-transport { margin-right: -240px; margin-left:0;} +.menu-item-depth-9 .menu-item-transport { margin-right: -270px; margin-left:0;} +.menu-item-depth-10 .menu-item-transport { margin-right: -300px; margin-left:0;} +.menu-item-depth-11 .menu-item-transport { margin-right: -330px; margin-left:0;} + +/* Menu item controls */ +.item-type { padding-left: 10px; padding-right:0;} +.item-controls { left: 20px; right: auto;} +.item-controls .item-order { padding-left: 10px; padding-right: 0;} + +.item-edit { + background-image: url("../images/menu-bits-rtl.gif?ver=20100531"); + background-position: 100% -105px; + left: -20px; + right:auto; + -moz-border-radius-bottomright: 3px; + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-right-radius: 3px; + -webkit-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 3px; + -khtml-border-bottom-left-radius: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 0; +} + +/* Menu editing */ +.menu-item-settings { + padding: 10px 10px 10px 0; + border-width: 0 1px 1px 1px; +} + +.link-to-original { + font-style: normal; + font-weight: bold; +} + .link-to-original a { + padding-right: 4px; + padding-left:0; + } + +.menu-item-settings .description-thin, +.menu-item-settings .description-wide { + margin-left: 10px; + margin-right:0; + float: right; +} + +/* Major/minor publishing actions (classes) */ +.major-publishing-actions .publishing-action { + text-align: left; + float: left; +} +.major-publishing-actions .delete-action { + text-align: right; + float: right; + padding-left: 15px; + padding-right:0; +} +.menu-name-label { + margin-left: 15px; + margin-right:0; +} +.auto-add-pages { + float: right; +} \ No newline at end of file diff --git a/src/wp-admin/css/nav-menu.css b/src/wp-admin/css/nav-menu.css new file mode 100644 index 00000000..266145b5 --- /dev/null +++ b/src/wp-admin/css/nav-menu.css @@ -0,0 +1 @@ +html,body{min-width:950px;}#nav-menus-frame{margin-left:300px;}#wpbody-content #menu-settings-column{display:inline;width:281px;margin-left:-300px;clear:both;float:left;padding-top:24px;}.no-js #wpbody-content #menu-settings-column{padding-top:31px;}#menu-settings-column .inside{clear:both;padding:0 10px;}.metabox-holder-disabled .postbox{opacity:.5;filter:alpha(opacity=50);}.metabox-holder-disabled .button-controls .select-all{display:none;}#wpbody{position:relative;}#menu-management-liquid{float:left;min-width:100%;}#menu-management{position:relative;margin-right:20px;margin-top:-3px;width:100%;}#menu-management .menu-edit{margin-bottom:20px;}#nav-menu-header,#post-body,#nav-menu-footer{border-color:#ccc;border-style:solid;}#nav-menu-header{border-width:1px 1px 0 1px;-moz-border-radius-topleft:6px;-webkit-border-top-left-radius:6px;-khtml-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-topright:6px;-webkit-border-top-right-radius:6px;-khtml-border-top-right-radius:6px;border-top-right-radius:6px;}#post-body{background:#fff;padding:10px;border-width:0 1px;}#post-body div.updated{margin:0;}#post-body-content{position:relative;}#menu-management .menu-add-new abbr{font-weight:bold;}#nav-menu-footer{border-width:0 1px 1px 1px;-moz-border-radius-bottomleft:6px;-webkit-border-bottom-left-radius:6px;-khtml-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-moz-border-radius-bottomright:6px;-webkit-border-bottom-right-radius:6px;-khtml-border-bottom-right-radius:6px;border-bottom-right-radius:6px;}#menu-management .nav-tabs-nav{margin:0 20px;}#menu-management .nav-tabs-arrow{width:10px;padding:0 5px 4px;cursor:pointer;position:absolute;top:0;line-height:22px;font-size:18px;text-shadow:0 1px 0 #fff;}#menu-management .nav-tabs-arrow a{color:#C1C1C1;}#menu-management .nav-tabs-arrow a:hover{color:#D54E21;}#menu-management .nav-tabs-arrow a:active{color:#464646;}#menu-management .nav-tabs-arrow-left{left:0;}#menu-management .nav-tabs-arrow-right{right:0;text-align:right;}#menu-management .nav-tabs-wrapper{width:100%;height:28px;margin-bottom:-1px;overflow:hidden;}#menu-management .nav-tabs{padding-left:20px;padding-right:10px;}.js #menu-management .nav-tabs{float:left;margin-left:0;margin-right:-400px;}#menu-management .nav-tab{margin-bottom:0;background:#f4f4f4;font-weight:bold;border-color:#dfdfdf;}#menu-management .nav-tab-active{border-color:#ccc;}#select-nav-menu-container{text-align:right;padding:0 10px 3px 10px;margin-bottom:5px;}#select-nav-menu{width:100px;display:inline;}#menu-name-label{margin-top:-2px;}#wpbody .open-label{display:block;float:left;}#wpbody .open-label span{padding-right:10px;}.js .input-with-default-title{color:#aaa;font-style:italic;}#menu-management .inside{padding:0 10px;}.postbox .howto input{width:180px;float:right;}.customlinkdiv .howto input{width:210px;}#nav-menu-theme-locations .howto select{width:100%;}#nav-menu-theme-locations .button-controls{text-align:right;}.add-menu-item-view-all{height:400px;}#menu-container .submit{margin:0 0 10px;padding:0;}.meta-sep,.submitdelete,.submitcancel{display:block;float:left;font-size:11px;margin:4px 0;line-height:15px;}.meta-sep{padding:0 2px;}#cancel-save{color:#f00;text-decoration:underline;font-size:11px;margin-left:20px;margin-top:5px;}#cancel-save:hover{background-color:#F00;color:#fff;}.list-controls{float:left;margin-top:5px;}.add-to-menu{float:right;}.postbox img.waiting{display:none;vertical-align:middle;}.button-controls{clear:both;margin:10px 0;}.show-all,.hide-all{cursor:pointer;}.hide-all{display:none;}#menu-name{width:270px;}#manage-menu .inside{padding:0;}#available-links dt{display:block;}#add-custom-link .howto{font-size:11px;}#add-custom-link label span{display:block;float:left;margin-top:5px;padding-right:5px;}.menu-item-textbox{width:180px;}.howto span{margin-top:4px;display:block;float:left;}.quick-search{width:190px;}.list-wrap{display:none;clear:both;margin-bottom:10px;}.list-container{max-height:200px;overflow-y:auto;padding:10px 10px 5px;border:1px solid #DFDFDF;-moz-border-radius:4px;}.postbox p.submit{margin-bottom:0;}.list li{display:none;margin:0;margin-bottom:5px;}.list li .menu-item-title{cursor:pointer;display:block;}.list li .menu-item-title input{margin-right:3px;margin-top:-3px;}#menu-container .inside{padding-bottom:10px;}.menu{padding-top:1em;}#menu-to-edit{padding:1em 0;}.menu ul{width:100%;}.menu li{margin-bottom:0;position:relative;}.menu-item-bar{clear:both;line-height:1.5em;position:relative;margin-top:13px;}.menu-item-handle{border:1px solid #E6E6E6;position:relative;padding-left:10px;height:auto;width:400px;line-height:35px;text-shadow:0 1px 0 #FFF;font-weight:bold;overflow:hidden;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;-khtml-border-radius:6px;word-wrap:break-word;}.menu-item-edit-active .menu-item-handle{-moz-border-radius:6px 6px 0 0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-khtml-border-bottom-right-radius:0;-khtml-border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;}.no-js .menu-item-edit-active .item-edit{display:none;}.js .menu-item-handle{cursor:move;}.menu li.deleting .menu-item-handle{background-color:#f66;background-image:none;text-shadow:0 0 0 #ccc;}.menu-item-handle .item-title{padding:7px 0;line-height:20px;display:block;margin-right:13em;}li.menu-item.ui-sortable-helper dl{margin-top:0;}li.menu-item.ui-sortable-helper .menu-item-transport dl{margin-top:13px;}.menu .sortable-placeholder{height:35px;width:410px;margin-top:13px;}.menu-item-depth-0{margin-left:0;}.menu-item-depth-1{margin-left:30px;}.menu-item-depth-2{margin-left:60px;}.menu-item-depth-3{margin-left:90px;}.menu-item-depth-4{margin-left:120px;}.menu-item-depth-5{margin-left:150px;}.menu-item-depth-6{margin-left:180px;}.menu-item-depth-7{margin-left:210px;}.menu-item-depth-8{margin-left:240px;}.menu-item-depth-9{margin-left:270px;}.menu-item-depth-10{margin-left:300px;}.menu-item-depth-11{margin-left:330px;}.menu-item-depth-0 .menu-item-transport{margin-left:0;}.menu-item-depth-1 .menu-item-transport{margin-left:-30px;}.menu-item-depth-2 .menu-item-transport{margin-left:-60px;}.menu-item-depth-3 .menu-item-transport{margin-left:-90px;}.menu-item-depth-4 .menu-item-transport{margin-left:-120px;}.menu-item-depth-5 .menu-item-transport{margin-left:-150px;}.menu-item-depth-6 .menu-item-transport{margin-left:-180px;}.menu-item-depth-7 .menu-item-transport{margin-left:-210px;}.menu-item-depth-8 .menu-item-transport{margin-left:-240px;}.menu-item-depth-9 .menu-item-transport{margin-left:-270px;}.menu-item-depth-10 .menu-item-transport{margin-left:-300px;}.menu-item-depth-11 .menu-item-transport{margin-left:-330px;}body.menu-max-depth-0{min-width:950px!important;}body.menu-max-depth-1{min-width:980px!important;}body.menu-max-depth-2{min-width:1010px!important;}body.menu-max-depth-3{min-width:1040px!important;}body.menu-max-depth-4{min-width:1070px!important;}body.menu-max-depth-5{min-width:1100px!important;}body.menu-max-depth-6{min-width:1130px!important;}body.menu-max-depth-7{min-width:1160px!important;}body.menu-max-depth-8{min-width:1190px!important;}body.menu-max-depth-9{min-width:1220px!important;}body.menu-max-depth-10{min-width:1250px!important;}body.menu-max-depth-11{min-width:1280px!important;}.item-type{text-transform:uppercase;font-size:11px;color:#999;padding-right:10px;}.item-controls{font-size:11px;position:absolute;right:20px;top:-1px;}.item-controls a{text-decoration:none;}.item-controls a:hover{cursor:pointer;}.item-controls .item-order{padding-right:10px;}.item-controls .item-order a{font-weight:bold;}body.js .item-order{display:none;}.item-controls .menu-item-delete:hover{color:#f00;}.item-edit{background:url("../images/menu-bits.gif?ver=20100610") no-repeat scroll 0 -105px;position:absolute;right:-20px;top:0;display:block;width:23px;height:36px;overflow:hidden;text-indent:-999em;border-bottom:1px solid #eee;-moz-border-radius-bottomleft:3px;-webkit-border-bottom-left-radius:3px;-khtml-border-bottom-left-radius:3px;border-bottom-left-radius:3px;}.menu-instructions-inactive{display:none;}.menu-item-settings{background:#F9F9F9;display:block;width:400px;padding:10px 0 10px 10px;border:solid #E6E6E6;border-width:0 1px 1px 1px;-moz-border-radius:0 0 6px 6px;-webkit-border-bottom-right-radius:6px;-webkit-border-bottom-left-radius:6px;-khtml-border-bottom-right-radius:6px;-khtml-border-bottom-left-radius:6px;}.menu-item-edit-active .menu-item-settings{display:block;}.menu-item-edit-inactive .menu-item-settings{display:none;}.add-menu-item-pagelinks{margin:.5em auto;text-align:center;}.link-to-original{display:block;margin:0 0 10px;padding:3px 5px 5px;font-size:11px;color:#777;font-style:italic;border:1px solid #dfdfdf;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;-khtml-border-radius:6px;}.link-to-original a{padding-left:4px;font-style:normal;}.hidden-field{display:none;}.menu-item-settings .description-thin,.menu-item-settings .description-wide{margin-right:10px;float:left;}.description-thin{width:190px;height:40px;}.description-wide{width:390px;}.menu-item-actions{padding-top:15px;}#cancel-save{cursor:pointer;}#cancel-save:hover{color:#fff!important;}#update-menu-item{color:#fff!important;}#update-menu-item:hover,#update-menu-item:active,#update-menu-item:focus{color:#eaf2fa!important;border-color:#13455b!important;}.major-publishing-actions{clear:both;padding:5px 10px;}.major-publishing-actions .publishing-action{text-align:right;float:right;line-height:23px;margin:5px 0 1px;}.major-publishing-actions .delete-action{vertical-align:middle;text-align:left;float:left;padding-right:15px;margin-top:5px;}.menu-name-label span,.auto-add-pages label{font-size:11px;font-style:normal;}.menu-name-label{margin-right:15px;}.auto-add-pages input{margin-top:0;}.auto-add-pages{margin-top:4px;float:left;}.submitbox .submitcancel{color:#21759B;border-bottom:1px solid #21759B;padding:1px 2px;text-decoration:none;}.submitbox .submitcancel:hover{background:#21759B;color:#fff;}.major-publishing-actions .form-invalid{border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;-khtml-border-radius:4px;padding-left:4px;margin-left:-4px;}#menu-item-name-wrap:after,#menu-item-url-wrap:after,#menu-name-label:after,#menu-settings-column .inside:after,#nav-menus-frame:after,#post-body-content:after,.button-controls:after,.major-publishing-actions:after,.menu-item-settings:after{clear:both;content:".";display:block;height:0;visibility:hidden;}#nav-menus-frame,.button-controls,#menu-item-url-wrap,#menu-item-name-wrap{display:block;} \ No newline at end of file diff --git a/src/wp-admin/css/nav-menu.dev.css b/src/wp-admin/css/nav-menu.dev.css new file mode 100644 index 00000000..601b8bf5 --- /dev/null +++ b/src/wp-admin/css/nav-menu.dev.css @@ -0,0 +1,574 @@ +/** + * WordPress Administration Custom Navigation + * Interface CSS + * + * @version 2.0.0 + * + * @package WordPress + * @subpackage Administration + */ + +html, +body { + min-width: 950px; +} + +#nav-menus-frame { + margin-left: 300px; +} + +#wpbody-content #menu-settings-column { + display:inline; + width:281px; + margin-left: -300px; + clear: both; + float: left; + padding-top: 24px; +} + .no-js #wpbody-content #menu-settings-column { + padding-top: 31px; + } + +#menu-settings-column .inside { + clear: both; + padding:0 10px; +} + +.metabox-holder-disabled .postbox { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.metabox-holder-disabled .button-controls .select-all { + display: none; +} +#wpbody { + position: relative; +} + +/* Menu Container */ +#menu-management-liquid { + float: left; + min-width: 100%; +} +#menu-management { + position: relative; + margin-right: 20px; + margin-top: -3px; + width: 100%; +} + #menu-management .menu-edit { + margin-bottom: 20px; + } + + #nav-menu-header, #post-body, #nav-menu-footer { + border-color: #ccc; + border-style: solid; + } + + #nav-menu-header { + border-width: 1px 1px 0 1px; + -moz-border-radius-topleft: 6px; + -webkit-border-top-left-radius: 6px; + -khtml-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-topright: 6px; + -webkit-border-top-right-radius: 6px; + -khtml-border-top-right-radius: 6px; + border-top-right-radius: 6px; + } + + #post-body { + background: #fff; + padding: 10px; + border-width: 0 1px; + } + + #post-body div.updated { + margin: 0; + } + + #post-body-content { + position: relative; + } + + #menu-management .menu-add-new abbr { + font-weight:bold; + } + +#nav-menu-footer { + border-width: 0 1px 1px 1px; + -moz-border-radius-bottomleft: 6px; + -webkit-border-bottom-left-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +/* Menu Tabs */ + +#menu-management .nav-tabs-nav { + margin: 0 20px; +} + +#menu-management .nav-tabs-arrow { + width: 10px; + padding: 0 5px 4px; + cursor: pointer; + position: absolute; + top: 0; + line-height: 22px; + font-size: 18px; + text-shadow: 0 1px 0 #fff; +} + #menu-management .nav-tabs-arrow a { color: #C1C1C1; } + #menu-management .nav-tabs-arrow a:hover { color: #D54E21; } + #menu-management .nav-tabs-arrow a:active { color: #464646; } + #menu-management .nav-tabs-arrow-left { + left: 0; + } + #menu-management .nav-tabs-arrow-right { + right: 0; + text-align: right; + } + + +#menu-management .nav-tabs-wrapper { + width: 100%; + height: 28px; + margin-bottom: -1px; + overflow: hidden; +} + +#menu-management .nav-tabs { + padding-left: 20px; + padding-right: 10px; +} +.js #menu-management .nav-tabs { + float: left; + margin-left: 0px; + margin-right: -400px; +} + +#menu-management .nav-tab { + margin-bottom: 0; + background: #f4f4f4; + font-weight: bold; + border-color: #dfdfdf; +} + +#menu-management .nav-tab-active { + border-color:#ccc; +} + +#select-nav-menu-container { + text-align: right; + padding: 0 10px 3px 10px; + margin-bottom: 5px; +} + #select-nav-menu { + width: 100px; + display: inline; + } + +#menu-name-label { + margin-top: -2px; +} + +#wpbody .open-label { + display: block; + float:left; +} +#wpbody .open-label span { + padding-right: 10px; +} + + .js .input-with-default-title { + color: #aaa; + font-style: italic; + } + +#menu-management .inside { padding: 0 10px; } + +/* Add Menu Item Boxes */ +.postbox .howto input { + width: 180px; + float: right; +} +.customlinkdiv .howto input { + width: 210px; +} +#nav-menu-theme-locations .howto select { + width: 100%; +} +#nav-menu-theme-locations .button-controls { + text-align: right; +} +.add-menu-item-view-all { + height: 400px; +} + +/* Button Primary Actions */ +#menu-container .submit { margin: 0px 0px 10px; padding: 0px; } + +.meta-sep, +.submitdelete, +.submitcancel { + display:block; + float:left; + font-size: 11px; + margin: 4px 0; + line-height: 15px; +} +.meta-sep { + padding: 0 2px; +} + +#cancel-save { color: #ff0000; text-decoration: underline; font-size: 11px; margin-left: 20px; margin-top: 5px; } +#cancel-save:hover { background-color: #FF0000; color: #fff; } + +/* Button Secondary Actions */ +.list-controls { float: left; margin-top: 5px; } +.add-to-menu { + float: right; +} + +.postbox img.waiting { + display: none; + vertical-align: middle; +} + +.button-controls { + clear:both; + margin: 10px 0; +} +.show-all, .hide-all { cursor: pointer; } +.hide-all { display: none; } + +/* Create Menu */ +#menu-name { width: 270px; } +#manage-menu .inside { padding: 0px 0px; } + +/* Custom Links */ +#available-links dt { display: block; } +#add-custom-link .howto { font-size: 11px; } +#add-custom-link label span { display: block; float: left; margin-top: 5px; padding-right: 5px; } +.menu-item-textbox { width: 180px; } +.howto span { margin-top: 4px; display: block; float: left; } + +/* Menu item types */ +.quick-search { width: 190px; } +.list-wrap { display: none; clear: both; margin-bottom: 10px; } +.list-container { max-height: 200px; overflow-y: auto; padding: 10px 10px 5px; border: 1px solid #DFDFDF; -moz-border-radius: 4px; } +.postbox p.submit { margin-bottom: 0; } + +/* Listings */ +.list li { display: none; margin: 0; margin-bottom: 5px; } + +.list li .menu-item-title { cursor: pointer; display: block; } +.list li .menu-item-title input { margin-right: 3px; margin-top: -3px; } + +/* Nav Menu */ +#menu-container .inside { padding-bottom: 10px; } + +.menu { + padding-top:1em; +} + +#menu-to-edit { + padding: 1em 0; +} + +.menu ul { + width: 100%; +} +.menu ul.sub-menu { +} +.menu li { + margin-bottom: 0; + position:relative; +} +.menu-item-bar { + clear:both; + line-height:1.5em; + position:relative; + margin-top: 13px; +} +.menu-item-handle { + border: 1px solid #E6E6E6; + position: relative; + padding-left: 10px; + height: auto; + width: 400px; + line-height: 35px; + text-shadow: 0 1px 0 #FFFFFF; + font-weight:bold; + overflow: hidden; + border-radius: 6px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + word-wrap: break-word; +} +.menu-item-edit-active .menu-item-handle { + -moz-border-radius: 6px 6px 0 0; + -webkit-border-bottom-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 0; + -khtml-border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.no-js .menu-item-edit-active .item-edit { + display: none; +} +.js .menu-item-handle { + cursor: move; +} +.menu li.deleting .menu-item-handle { + background-color: #f66; + background-image: none; + text-shadow: 0 0 0 #ccc; +} + +.menu-item-handle .item-title { + padding: 7px 0; + line-height: 20px; + display:block; + margin-right:13em; +} + +/* Sortables */ +li.menu-item.ui-sortable-helper dl { + margin-top: 0; +} + li.menu-item.ui-sortable-helper .menu-item-transport dl { + margin-top: 13px; + } +.menu .sortable-placeholder { + height: 35px; + width: 410px; + margin-top: 13px; +} + +/* WARNING: The factor of 30px is hardcoded into the nav-menus javascript. */ +.menu-item-depth-0 { margin-left: 0px; } +.menu-item-depth-1 { margin-left: 30px; } +.menu-item-depth-2 { margin-left: 60px; } +.menu-item-depth-3 { margin-left: 90px; } +.menu-item-depth-4 { margin-left: 120px; } +.menu-item-depth-5 { margin-left: 150px; } +.menu-item-depth-6 { margin-left: 180px; } +.menu-item-depth-7 { margin-left: 210px; } +.menu-item-depth-8 { margin-left: 240px; } +.menu-item-depth-9 { margin-left: 270px; } +.menu-item-depth-10 { margin-left: 300px; } +.menu-item-depth-11 { margin-left: 330px; } + +.menu-item-depth-0 .menu-item-transport { margin-left: 0px; } +.menu-item-depth-1 .menu-item-transport { margin-left: -30px; } +.menu-item-depth-2 .menu-item-transport { margin-left: -60px; } +.menu-item-depth-3 .menu-item-transport { margin-left: -90px; } +.menu-item-depth-4 .menu-item-transport { margin-left: -120px; } +.menu-item-depth-5 .menu-item-transport { margin-left: -150px; } +.menu-item-depth-6 .menu-item-transport { margin-left: -180px; } +.menu-item-depth-7 .menu-item-transport { margin-left: -210px; } +.menu-item-depth-8 .menu-item-transport { margin-left: -240px; } +.menu-item-depth-9 .menu-item-transport { margin-left: -270px; } +.menu-item-depth-10 .menu-item-transport { margin-left: -300px; } +.menu-item-depth-11 .menu-item-transport { margin-left: -330px; } + +body.menu-max-depth-0 { min-width: 950px !important; } +body.menu-max-depth-1 { min-width: 980px !important; } +body.menu-max-depth-2 { min-width: 1010px !important; } +body.menu-max-depth-3 { min-width: 1040px !important; } +body.menu-max-depth-4 { min-width: 1070px !important; } +body.menu-max-depth-5 { min-width: 1100px !important; } +body.menu-max-depth-6 { min-width: 1130px !important; } +body.menu-max-depth-7 { min-width: 1160px !important; } +body.menu-max-depth-8 { min-width: 1190px !important; } +body.menu-max-depth-9 { min-width: 1220px !important; } +body.menu-max-depth-10 { min-width: 1250px !important; } +body.menu-max-depth-11 { min-width: 1280px !important; } + +/* Menu item controls */ +.item-type { text-transform: uppercase; font-size: 11px; color: #999999; padding-right: 10px; } +.item-controls { font-size: 11px; position: absolute; right: 20px; top: -1px; } +.item-controls a { text-decoration: none; } +.item-controls a:hover { cursor: pointer; } +.item-controls .item-order { padding-right: 10px;} +.item-controls .item-order a { + font-weight:bold; +} + +body.js .item-order { + display:none; +} + +.item-controls .menu-item-delete:hover { color: #ff0000; } + +.item-edit { + background: url("../images/menu-bits.gif?ver=20100610") no-repeat scroll 0 -105px; + position: absolute; + right: -20px; + top: 0; + display: block; + width: 23px; + height: 36px; + overflow: hidden; + text-indent:-999em; + border-bottom: 1px solid #eee; + -moz-border-radius-bottomleft: 3px; + -webkit-border-bottom-left-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +/* Menu editing */ +.menu-instructions-inactive { + display: none; +} +.menu-item-settings { + background: #F9F9F9; + display:block; + width: 400px; + padding: 10px 0 10px 10px; + border: solid #E6E6E6; + border-width: 0 1px 1px 1px; + -moz-border-radius: 0 0 6px 6px; + -webkit-border-bottom-right-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + -khtml-border-bottom-left-radius: 6px; +} +.menu-item-edit-active .menu-item-settings { + display:block; +} + +.menu-item-edit-inactive .menu-item-settings { + display:none; +} + +.add-menu-item-pagelinks { + margin:.5em auto; + text-align:center; +} + +.link-to-original { + display: block; + margin: 0 0 10px; + padding: 3px 5px 5px; + font-size: 11px; + color: #777; + font-style: italic; + border: 1px solid #dfdfdf; + border-radius: 6px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; +} + .link-to-original a { + padding-left: 4px; + font-style: normal; + } + +.hidden-field { + display: none; +} + +.menu-item-settings .description-thin, +.menu-item-settings .description-wide { + margin-right: 10px; + float: left; +} +.description-thin { + width: 190px; + height: 40px; +} +.description-wide { + width: 390px; +} + +.menu-item-actions { + padding-top: 15px; +} + +#cancel-save { cursor: pointer; } +#cancel-save:hover { color: #fff !important; } +#update-menu-item { color: #fff !important; } +#update-menu-item:hover, +#update-menu-item:active, +#update-menu-item:focus { color: #eaf2fa !important; border-color: #13455b !important; } + +/* Major/minor publishing actions (classes) */ +.major-publishing-actions { + clear:both; + padding: 5px 10px; +} +.major-publishing-actions .publishing-action { + text-align: right; + float: right; + line-height: 23px; + margin: 5px 0 1px; +} +.major-publishing-actions .delete-action { + vertical-align: middle; + text-align: left; + float: left; + padding-right: 15px; + margin-top: 5px; +} +.menu-name-label span, .auto-add-pages label { + font-size: 11px; + font-style: normal; +} +.menu-name-label { + margin-right: 15px; +} +.auto-add-pages input { + margin-top: 0; +} +.auto-add-pages { + margin-top: 4px; + float: left; +} +.submitbox .submitcancel { + color: #21759B; + border-bottom: 1px solid #21759B; + padding: 1px 2px; + text-decoration: none; +} +.submitbox .submitcancel:hover { + background: #21759B; + color: #fff; +} + +.major-publishing-actions .form-invalid { + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -khtml-border-radius: 4px; + padding-left: 4px; + margin-left: -4px; +} + +/* Clearfix */ +#menu-item-name-wrap:after, +#menu-item-url-wrap:after, +#menu-name-label:after, +#menu-settings-column .inside:after, +#nav-menus-frame:after, +#post-body-content:after, +.button-controls:after, +.major-publishing-actions:after, +.menu-item-settings:after { + clear: both; + content: "."; + display: block; + height: 0; + visibility: hidden; +} +#nav-menus-frame, .button-controls, #menu-item-url-wrap, #menu-item-name-wrap { display: block; } diff --git a/src/wp-admin/css/plugin-install-rtl.css b/src/wp-admin/css/plugin-install-rtl.css new file mode 100644 index 00000000..f1ade77e --- /dev/null +++ b/src/wp-admin/css/plugin-install-rtl.css @@ -0,0 +1 @@ +div.star{left:auto;right:0;letter-spacing:0;}.star img,div.star a,div.star a:hover,div.star a:visited{right:auto;left:0;}#plugin-information ul#sidemenu{left:auto;right:0;}#plugin-information h2{margin-right:0;margin-left:200px;}#plugin-information .fyi{margin-left:5px;margin-right:20px;}#plugin-information .fyi h2{margin-left:0;}#plugin-information .fyi ul{padding:10px 7px 10px 5px;}#plugin-information #section-screenshots li p{padding-left:0;padding-right:20px;}#plugin-information .updated,#plugin-information pre{margin-right:0;margin-left:215px;}#plugin-information .updated,#plugin-information .error{clear:none;direction:rtl;}#section-description{direction:ltr;} \ No newline at end of file diff --git a/src/wp-admin/css/plugin-install-rtl.dev.css b/src/wp-admin/css/plugin-install-rtl.dev.css new file mode 100644 index 00000000..9a6dd11d --- /dev/null +++ b/src/wp-admin/css/plugin-install-rtl.dev.css @@ -0,0 +1,43 @@ +div.star { + left: auto; + right: 0; + letter-spacing: 0; +} +.star img, div.star a, div.star a:hover, div.star a:visited { + right: auto; + left: 0; +} +#plugin-information ul#sidemenu { + left: auto; + right: 0; +} +#plugin-information h2 { + margin-right: 0; + margin-left: 200px; +} +#plugin-information .fyi { + margin-left: 5px; + margin-right: 20px; +} +#plugin-information .fyi h2 { + margin-left: 0; +} +#plugin-information .fyi ul { + padding: 10px 7px 10px 5px; +} +#plugin-information #section-screenshots li p { + padding-left: 0; + padding-right: 20px; +} +#plugin-information .updated, +#plugin-information pre { + margin-right: 0; + margin-left: 215px; +} +#plugin-information .updated, #plugin-information .error { + clear: none; + direction: rtl; +} +#section-description { + direction: ltr; +} diff --git a/src/wp-admin/css/plugin-install.css b/src/wp-admin/css/plugin-install.css new file mode 100644 index 00000000..50d3c038 --- /dev/null +++ b/src/wp-admin/css/plugin-install.css @@ -0,0 +1 @@ +div.star-holder{position:relative;height:19px;width:100px;font-size:19px;}div.action-links{font-weight:normal;margin:6px 0 0;}div.star{height:100%;position:absolute;top:0;left:0;background-color:transparent;letter-spacing:1ex;border:none;}.star1{width:20%;}.star2{width:40%;}.star3{width:60%;}.star4{width:80%;}.star5{width:100%;}.star img,div.star a,div.star a:hover,div.star a:visited{display:block;position:absolute;right:0;border:none;text-decoration:none;}div.star img{width:19px;height:19px;border-left:1px solid #fff;border-right:1px solid #fff;}#plugin-information-header{margin:0;padding:0 5px;font-weight:bold;position:relative;border-bottom-width:1px;border-bottom-style:solid;height:2.5em;}#plugin-information ul#sidemenu{font-weight:normal;margin:0 5px;position:absolute;left:0;bottom:-1px;}#plugin-information p.action-button{width:100%;padding-bottom:0;margin-bottom:0;margin-top:10px;-moz-border-radius:3px 0 0 3px;-webkit-border-top-left-radius:3px;-khtml-border-top-left-radius:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-khtml-border-bottom-left-radius:3px;border-bottom-left-radius:3px;}#plugin-information .action-button a{text-align:center;font-weight:bold;text-decoration:none;display:block;line-height:2em;}#plugin-information h2{clear:none!important;margin-right:200px;}#plugin-information .fyi{margin:0 10px 50px;width:210px;}#plugin-information .fyi h2{font-size:.9em;margin-bottom:0;margin-right:0;}#plugin-information .fyi h2.mainheader{padding:5px;-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;-khtml-border-top-left-radius:3px;border-top-left-radius:3px;}#plugin-information .fyi ul{padding:10px 5px 10px 7px;margin:0;list-style:none;-moz-border-radius-bottomleft:3px;-webkit-border-bottom-left-radius:3px;-khtml-border-bottom-left-radius:3px;border-bottom-left-radius:3px;}#plugin-information .fyi li{margin-right:0;}#plugin-information #section-holder{padding:10px;}#plugin-information .section ul,#plugin-information .section ol{margin-left:16px;list-style-type:square;list-style-image:none;}#plugin-information #section-screenshots li img{vertical-align:text-top;}#plugin-information #section-screenshots li p{font-style:italic;padding-left:20px;padding-bottom:2em;}#plugin-information .updated,#plugin-information pre{margin-right:215px;}#plugin-information pre{padding:7px;} \ No newline at end of file diff --git a/src/wp-admin/css/plugin-install.dev.css b/src/wp-admin/css/plugin-install.dev.css new file mode 100644 index 00000000..c9e98b84 --- /dev/null +++ b/src/wp-admin/css/plugin-install.dev.css @@ -0,0 +1,152 @@ +/* NOTE: the following CSS rules(.star*) are taken more or less straight from the bbPress rating plugin. */ +div.star-holder { + position: relative; + height: 19px; + width: 100px; + font-size: 19px; +} + +div.action-links { + font-weight: normal; + margin: 6px 0 0; +} + +div.star { + height: 100%; + position: absolute; + top: 0; + left: 0; + background-color: transparent; + letter-spacing: 1ex; + border: none; +} + +.star1 { width: 20%; } +.star2 { width: 40%; } +.star3 { width: 60%; } +.star4 { width: 80%; } +.star5 { width: 100%; } + +.star img, div.star a, div.star a:hover, div.star a:visited { + display: block; + position: absolute; + right: 0; + border: none; + text-decoration: none; +} + +div.star img { + width: 19px; + height: 19px; + border-left: 1px solid #fff; + border-right: 1px solid #fff; +} + +/* Header on thickbox */ +#plugin-information-header { + margin: 0; + padding: 0 5px; + font-weight: bold; + position: relative; + border-bottom-width: 1px; + border-bottom-style: solid; + height: 2.5em; +} +#plugin-information ul#sidemenu { + font-weight: normal; + margin: 0 5px; + position: absolute; + left: 0; + bottom: -1px; +} + +/* Install sidemenu */ +#plugin-information p.action-button { + width: 100%; + padding-bottom: 0; + margin-bottom: 0; + margin-top: 10px; + -moz-border-radius: 3px 0 0 3px; + -webkit-border-top-left-radius: 3px; + -khtml-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +#plugin-information .action-button a { + text-align: center; + font-weight: bold; + text-decoration: none; + display: block; + line-height: 2em; +} + +#plugin-information h2 { + clear: none !important; + margin-right: 200px; +} + +#plugin-information .fyi { + margin: 0 10px 50px; + width: 210px; +} + +#plugin-information .fyi h2 { + font-size: 0.9em; + margin-bottom: 0; + margin-right: 0; +} + +#plugin-information .fyi h2.mainheader { + padding: 5px; + -moz-border-radius-topleft: 3px; + -webkit-border-top-left-radius: 3px; + -khtml-border-top-left-radius: 3px; + border-top-left-radius: 3px; +} + +#plugin-information .fyi ul { + padding: 10px 5px 10px 7px; + margin: 0; + list-style: none; + -moz-border-radius-bottomleft: 3px; + -webkit-border-bottom-left-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +#plugin-information .fyi li { + margin-right: 0; +} + +#plugin-information #section-holder { + padding: 10px; +} + +#plugin-information .section ul, +#plugin-information .section ol { + margin-left: 16px; + list-style-type: square; + list-style-image: none; +} + +#plugin-information #section-screenshots li img { + vertical-align: text-top; +} + +#plugin-information #section-screenshots li p { + font-style: italic; + padding-left: 20px; + padding-bottom: 2em; +} + +#plugin-information .updated, +#plugin-information pre { + margin-right: 215px; +} + +#plugin-information pre { + padding: 7px; +} diff --git a/src/wp-admin/css/press-this-rtl.css b/src/wp-admin/css/press-this-rtl.css new file mode 100644 index 00000000..0f378c62 --- /dev/null +++ b/src/wp-admin/css/press-this-rtl.css @@ -0,0 +1 @@ +body{font-family:Tahoma,Arial;}#poststuff #edButtonPreview,#poststuff #edButtonHTML{margin:0 0 0 5px;float:right;}div#poststuff{padding-left:0;padding-right:10px;}.posting{margin-right:0;margin-left:228px;left:auto;right:0;}#side-info-column{float:left;right:auto;left:0;margin-right:0;margin-left:10px;}#side-info-column .sleeve{padding-left:0;padding-right:10px;}h3.tb{margin-left:0;margin-right:5px;}#actions{float:left;}#extra_fields #actions{right:auto;left:4px;}#actions li{float:right;margin-right:0;margin-left:10px;}#extra_fields .button{margin-right:0;margin-left:5px;}#img_container a{float:right;}#category-add input,#category-add select{font-family:Tahoma,Arial;}.inline-editor ul.cat-checklist ul,.categorydiv ul.categorychecklist ul,#linkcategorydiv ul.categorychecklist ul{margin-left:0;margin-right:18px;}#tagsdiv #newtag{margin-right:0;margin-left:5px;}#tagadd{margin-left:0;margin-right:3px;}#tagchecklist span{margin-left:.5em;margin-right:10px;float:right;}#tagchecklist span a{margin:6px -9px 0 0;float:right;}#content{margin-left:0;margin-right:1%;}.submit input,.button,.button-primary,.button-secondary,.button-highlighted,#postcustomstuff .submit input{font-family:Tahoma,Arial,sans-serif;}.ac_results li{text-align:right;}#TB_ajaxContent #options{right:auto;left:25px;}#post_status{margin-left:0;margin-right:10px;}#footer{padding:10px 60px 0 0;} \ No newline at end of file diff --git a/src/wp-admin/css/press-this-rtl.dev.css b/src/wp-admin/css/press-this-rtl.dev.css new file mode 100644 index 00000000..b056591c --- /dev/null +++ b/src/wp-admin/css/press-this-rtl.dev.css @@ -0,0 +1,130 @@ +body { + font-family: Tahoma, Arial; +} + +#poststuff #edButtonPreview, +#poststuff #edButtonHTML { + margin: 0 0 0 5px; + float: right; +} + +/* Editor/Main Column */ +div#poststuff { + padding-left: 0; + padding-right: 10px; +} + +.posting { + margin-right: 0; + margin-left: 228px; + left: auto; + right: 0; +} + +#side-info-column { + float: left; + right: auto; + left: 0; + margin-right: 0; + margin-left: 10px; +} + +#side-info-column .sleeve { + padding-left: 0; + padding-right: 10px; +} + +h3.tb { + margin-left: 0; + margin-right: 5px; +} + +#actions { + float: left; +} + +#extra_fields #actions { + right: auto; + left: 4px; +} + +#actions li { + float: right; + margin-right: 0; + margin-left: 10px; +} + +#extra_fields .button { + margin-right: 0; + margin-left: 5px; +} + +/* Photo Styles */ +#img_container a { + float: right; +} + +#category-add input, #category-add select { + font-family: Tahoma, Arial; +} + +.inline-editor ul.cat-checklist ul, +.categorydiv ul.categorychecklist ul, +#linkcategorydiv ul.categorychecklist ul { + margin-left: 0; + margin-right: 18px; +} + +/* Tags */ +#tagsdiv #newtag { + margin-right: 0; + margin-left: 5px; +} + +#tagadd { + margin-left: 0; + margin-right: 3px; +} + +#tagchecklist span { + margin-left: .5em; + margin-right: 10px; + float: right; +} +#tagchecklist span a { + margin: 6px -9px 0 0; + float: right; +} + +#content { + margin-left: 0; + margin-right: 1%; +} + +.submit input, +.button, +.button-primary, +.button-secondary, +.button-highlighted, +#postcustomstuff .submit input { + font-family: Tahoma, Arial, sans-serif; +} + +.ac_results li { + text-align: right; +} + +#TB_ajaxContent #options { + right: auto; + left: 25px; +} + +#post_status { + margin-left: 0; + margin-right: 10px; +} + +/* Footer */ +#footer { + padding: 10px 60px 0 0; +} diff --git a/src/wp-admin/css/press-this.css b/src/wp-admin/css/press-this.css new file mode 100644 index 00000000..c91f43b2 --- /dev/null +++ b/src/wp-admin/css/press-this.css @@ -0,0 +1 @@ +body{font:13px "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;color:#333;margin:0;padding:0;min-width:675px;min-height:400px;}img{border:none;}#wphead{border-top:none;padding-top:4px;background:#444!important;}.tagchecklist span a{background:transparent url(../images/xit.gif) no-repeat 0 0;}#poststuff #edButtonPreview,#poststuff #edButtonHTML{-moz-border-radius:3px 3px 0 0;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;-khtml-border-top-right-radius:3px;-khtml-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;border-style:solid;border-width:1px;cursor:pointer;display:block;height:18px;margin:0 5px 0 0;padding:0 5px 0;font-size:10px;line-height:18px;float:left;}.howto{margin-top:2px;margin-bottom:3px;font-size:11px;font-style:italic;display:block;}input.text{outline-color:-moz-use-text-color;outline-style:none;outline-width:medium;width:100%;}#message{-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}div#poststuff{margin:10px;}div.zerosize{border:0 none;height:0;margin:0;overflow:hidden;padding:0;width:0;}#poststuff #edButtonPreview.active,#poststuff #edButtonHTML.active{display:none;}.posting{margin-right:212px;position:relative;}#side-info-column{float:right;width:200px;position:relative;right:0;}#side-info-column .sleeve{padding-top:5px;}#poststuff .inside{font-size:11px;margin:8px;}#poststuff h2,#poststuff h3{font-size:12px;font-weight:bold;line-height:1;margin:0;padding:7px 9px;}#tagsdiv-post_tag h3,#categorydiv h3{cursor:pointer;}h3.tb{text-shadow:0 1px 0 #fff;font-weight:bold;font-size:12px;margin-left:5px;}#TB_window{border:1px solid #333;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.postbox,.stuffbox{margin-bottom:10px;border-width:1px;border-style:solid;line-height:1;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.postbox:hover .handlediv,.stuffbox:hover .handlediv{background:transparent url(../images/menu-bits.gif) no-repeat scroll left -111px;}.handlediv{float:right;height:26px;width:23px;}#title,.tbtitle{-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;border-style:solid;border-width:1px;font-size:1.7em;outline:none;padding:3px 4px;border-color:#dfdfdf;}.tbtitle{font-size:12px;padding:3px;}#title{width:97%;}.editor-container{-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;border:1px solid #dfdfdf;background-color:#fff;}.postdivrich{padding-top:25px;position:relative;}.actions{float:right;margin:-19px 0 0;}#extra-fields .actions{margin:-15px -5px 0 0;}.actions li{float:left;list-style:none;margin-right:10px;}#extra-fields .button{margin-right:5px;padding:3px 6px;border-radius:10px;-webkit-border-radius:10px;-khtml-border-radius:10px;-moz-border-radius:10px;}.photolist{margin-top:-10px;}#photo_saving{margin:0 8px 8px;vertical-align:middle;}#img_container{background-color:#fff;}#img_container_container{overflow:auto;}#extra-fields{margin-top:10px;position:relative;}#waiting{margin-top:10px;}#extra-fields .postbox{margin-bottom:5px;}#extra-fields .titlewrap{padding:0;overflow:auto;height:100px;}#img_container a{display:block;float:left;overflow:hidden;vertical-align:center;}#img_container img,#img_container a{width:68px;height:68px;}#img_container img{border:none;background-color:#f4f4f4;cursor:pointer;}#img_container a,#img_container a:link,#img_container a:visited{border:1px solid #ccc;display:block;position:relative;}#img_container a:hover,#img_container a:active{border-color:#000;z-index:1000;border-width:2px;margin:-1px;}#embed-code{width:100%;height:98px;}#viewsite{padding:0;margin:0 0 20px 5px;font-size:10px;clear:both;}.wp-hidden-children .wp-hidden-child{display:none;}.category-add input{width:94%;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-size:12px;margin:1px;}.category-add select{width:100%;-x-system-font:none;border-style:solid;border-width:1px;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-size:11px;height:2em;line-height:20px;padding:2px;margin:1px;vertical-align:top;}.category-add input.category-add-sumbit{width:auto;}.categorydiv div.tabs-panel,#linkcategorydiv div.tabs-panel{height:100px;overflow:auto;padding:.5em .9em;border-style:solid;border-width:1px;}.category-tabs li{display:inline;padding-right:8px;}.category-tabs a{text-decoration:none;}.categorydiv ul,#linkcategorydiv ul{list-style:none;padding:0;margin:0;}.inline-editor ul.cat-checklist ul,.categorydiv ul.categorychecklist ul,#linkcategorydiv ul.categorychecklist ul{margin-left:18px;}ul.categorychecklist li{margin:0;padding:0;line-height:19px;}.categorydiv .tabs-panel{border-width:3px;border-style:solid;}ul.category-tabs{margin-top:12px;margin-bottom:6px;}ul.category-tabs li.tabs{border-style:solid solid none;border-width:1px 1px 0;}ul.category-tabs li{padding:5px 8px;-moz-border-radius:3px 3px 0 0;-webkit-border-top-left-radius:3px;-webkit-border-top-right-radius:3px;-khtml-border-top-left-radius:3px;-khtml-border-top-right-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px;}.screen-reader-text{display:none;}.tagsdiv .newtag{margin-right:5px;}.jaxtag{clear:both;margin:0;}.tagadd{margin-left:3px;}.tagchecklist{margin-top:3px;margin-bottom:1em;font-size:12px;overflow:auto;}.tagchecklist strong{position:absolute;font-size:.75em;}.tagchecklist span{margin-right:.5em;margin-left:10px;display:block;float:left;font-size:11px;line-height:1.8em;white-space:nowrap;cursor:default;}.tagchecklist span a{margin:6px 0 0 -9px;cursor:pointer;width:10px;height:10px;display:block;float:left;text-indent:-9999px;overflow:hidden;position:absolute;}#content{margin:5px 0;padding:0 5px;border:0 none;height:365px;width:97%!important;}* html .postdivrich{zoom:1;}#saving{display:inline;vertical-align:middle;}.submit input,.button,.button-primary,.button-secondary,.button-highlighted,#postcustomstuff .submit input{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;text-decoration:none;font-size:11px!important;line-height:16px;padding:2px 8px;cursor:pointer;border-width:1px;border-style:solid;-moz-border-radius:11px;-khtml-border-radius:11px;-webkit-border-radius:11px;border-radius:11px;}.button-primary{background:#21759B url(../images/button-grad.png) repeat-x scroll left top;border-color:#21759B;color:#fff;}.ac_results{padding:0;margin:0;list-style:none;position:absolute;z-index:10000;display:none;border-width:1px;border-style:solid;}.ac_results li{padding:2px 5px;white-space:nowrap;text-align:left;}.ac_over{cursor:pointer;}.ac_match{text-decoration:underline;}#TB_ajaxContent #options{position:absolute;top:20px;right:25px;padding:5px;}#TB_ajaxContent h3{margin-bottom:.25em;}.updated{margin:10px 0;padding:0;border-width:1px;border-style:solid;width:99%;}.updated p,.error p{margin:.6em 0;padding:0 .6em;}.error a{text-decoration:underline;}.updated a{text-decoration:none;padding-bottom:2px;}#post_status{margin-left:10px;margin-bottom:1em;display:block;}#footer{height:65px;display:block;width:640px;padding:10px 0 0 60px;margin:0;position:absolute;bottom:0;font-size:12px;}#footer p{margin:0;padding:7px 0;}#footer p a{text-decoration:none;}#footer p a:hover{text-decoration:underline;}.centered{text-align:center;}.hidden{display:none;}.postbox input[type="text"],.postbox textarea,.stuffbox input[type="text"],.stuffbox textarea{border-width:1px;border-style:solid;}.taghint{color:#aaa;margin:-17px 0 0 7px;visibility:hidden;}input.newtag ~ div.taghint{visibility:visible;}input.newtag:focus ~ div.taghint{visibility:hidden;} \ No newline at end of file diff --git a/src/wp-admin/css/press-this.dev.css b/src/wp-admin/css/press-this.dev.css new file mode 100644 index 00000000..225512c6 --- /dev/null +++ b/src/wp-admin/css/press-this.dev.css @@ -0,0 +1,618 @@ +body { + font: 13px "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + color: #333; + margin: 0; + padding: 0; + min-width: 675px; + min-height: 400px; +} + +img { + border: none; +} + +/* Header */ +#wphead { + border-top: none; + padding-top: 4px; + background: #444 !important; +} + +.tagchecklist span a { + background: transparent url(../images/xit.gif) no-repeat 0 0; +} + +#poststuff #edButtonPreview, +#poststuff #edButtonHTML { + -moz-border-radius: 3px 3px 0 0; + -webkit-border-top-right-radius: 3px; + -webkit-border-top-left-radius: 3px; + -khtml-border-top-right-radius: 3px; + -khtml-border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-style: solid; + border-width: 1px; + cursor: pointer; + display: block; + height: 18px; + margin: 0 5px 0 0; + padding: 0 5px 0; + font-size: 10px; + line-height: 18px; + float: left; +} + +.howto { + margin-top: 2px; + margin-bottom: 3px; + font-size: 11px; + font-style: italic; + display: block; +} + +input.text { + outline-color: -moz-use-text-color; + outline-style: none; + outline-width: medium; + width: 100%; +} + +#message { + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +/* Editor/Main Column */ +div#poststuff { + margin: 10px; +} + +div.zerosize { + border: 0 none; + height: 0; + margin: 0; + overflow: hidden; + padding: 0; + width: 0; +} + +#poststuff #edButtonPreview.active, +#poststuff #edButtonHTML.active { + display: none; +} + +.posting { + margin-right: 212px; + position: relative; +} + +#side-info-column { + float: right; + width: 200px; + position: relative; + right: 0; +} + +#side-info-column .sleeve { + padding-top: 5px; +} + +#poststuff .inside { + font-size: 11px; + margin: 8px; +} + +#poststuff h2,#poststuff h3 { + font-size: 12px; + font-weight: bold; + line-height: 1; + margin: 0; + padding: 7px 9px; +} + +#tagsdiv-post_tag h3, +#categorydiv h3 { + cursor: pointer; +} + +h3.tb { + text-shadow: 0 1px 0 #fff; + font-weight: bold; + font-size: 12px; + margin-left: 5px; +} + +#TB_window { + border: 1px solid #333; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +.postbox, +.stuffbox { + margin-bottom: 10px; + border-width: 1px; + border-style: solid; + line-height: 1; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +.postbox:hover .handlediv, +.stuffbox:hover .handlediv { + background: transparent url(../images/menu-bits.gif) no-repeat scroll left -111px; +} + +.handlediv { + float: right; + height: 26px; + width: 23px; +} + +#title, +.tbtitle { + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; + border-style: solid; + border-width: 1px; + font-size: 1.7em; + outline: none; + padding: 3px 4px; + border-color: #dfdfdf; +} + +.tbtitle { + font-size: 12px; + padding: 3px; +} + +#title { + width: 97%; +} + +.editor-container { + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; + border: 1px solid #dfdfdf; + background-color: #fff; +} + +.postdivrich { + padding-top: 25px; + position: relative; +} + +.actions { + float: right; + margin: -19px 0 0; +} + +#extra-fields .actions { + margin: -15px -5px 0 0; +} + +.actions li { + float: left; + list-style: none; + margin-right: 10px; +} + +#extra-fields .button { + margin-right: 5px; + padding: 3px 6px; + border-radius: 10px; + -webkit-border-radius: 10px; + -khtml-border-radius: 10px; + -moz-border-radius: 10px; +} + +/* Photo Styles */ +.photolist { + margin-top: -10px; +} + +#photo_saving { + margin: 0 8px 8px; + vertical-align: middle; +} + +#img_container { + background-color: #fff; +} + +#img_container_container { + overflow: auto; +} + +#extra-fields { + margin-top: 10px; + position: relative; +} + +#waiting { + margin-top: 10px; +} + +#extra-fields .postbox { + margin-bottom: 5px; +} + +#extra-fields .titlewrap { + padding: 0; + overflow: auto; + height: 100px; +} + +#img_container a { + display: block; + float: left; + overflow: hidden; + vertical-align: center; +} + +#img_container img, +#img_container a { + width: 68px; + height: 68px; +} + +#img_container img { + border: none; + background-color: #f4f4f4; + cursor: pointer; +} + +#img_container a, +#img_container a:link, +#img_container a:visited { + border: 1px solid #ccc; + display: block; + position: relative; +} + +#img_container a:hover, +#img_container a:active { + border-color: #000; + z-index: 1000; + border-width: 2px; + margin: -1px; +} + +/* Video */ +#embed-code { + width: 100%; + height: 98px; +} + +/* Submit Column */ +#viewsite { + padding: 0; + margin: 0 0 20px 5px; + font-size: 10px; + clear: both; +} + +.wp-hidden-children +.wp-hidden-child { + display: none; +} + +/* Categories */ + +.category-add input { + width: 94%; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-size: 12px; + margin: 1px; +} + +.category-add select { + width: 100%; + -x-system-font: none; + border-style: solid; + border-width: 1px; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-size: 11px; + height: 2em; + line-height: 20px; + padding: 2px; + margin: 1px; + vertical-align: top; +} + +.category-add input.category-add-sumbit { + width: auto; +} + +.categorydiv div.tabs-panel, +#linkcategorydiv div.tabs-panel { + height: 100px; + overflow: auto; + padding: 0.5em 0.9em; + border-style: solid; + border-width: 1px; +} + +.category-tabs li { + display: inline; + padding-right: 8px; +} + +.category-tabs a { + text-decoration: none; +} + +.categorydiv ul, +#linkcategorydiv ul { + list-style: none; + padding: 0; + margin: 0; +} + +.inline-editor ul.cat-checklist ul, +.categorydiv ul.categorychecklist ul, +#linkcategorydiv ul.categorychecklist ul { + margin-left: 18px; +} + +ul.categorychecklist li { + margin: 0; + padding: 0; + line-height: 19px; +} + +.categorydiv .tabs-panel { + border-width: 3px; + border-style: solid; +} + +ul.category-tabs { + margin-top: 12px; + margin-bottom: 6px; +} + +ul.category-tabs li.tabs { + border-style: solid solid none; + border-width: 1px 1px 0; +} + +ul.category-tabs li { + padding: 5px 8px; + -moz-border-radius: 3px 3px 0 0; + -webkit-border-top-left-radius: 3px; + -webkit-border-top-right-radius: 3px; + -khtml-border-top-left-radius: 3px; + -khtml-border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +/* Tags */ +.screen-reader-text { + display: none; +} + +.tagsdiv .newtag { + margin-right: 5px; +} + +.jaxtag { + clear: both; + margin: 0; +} + +.tagadd { + margin-left: 3px; +} + +.tagchecklist { + margin-top: 3px; + margin-bottom: 1em; + font-size: 12px; + overflow: auto; +} + +.tagchecklist strong { + position: absolute; + font-size: .75em; +} + +.tagchecklist span { + margin-right: .5em; + margin-left: 10px; + display: block; + float: left; + font-size: 11px; + line-height: 1.8em; + white-space: nowrap; + cursor: default; +} + +.tagchecklist span a { + margin: 6px 0 0 -9px; + cursor: pointer; + width: 10px; + height: 10px; + display: block; + float: left; + text-indent: -9999px; + overflow: hidden; + position: absolute; +} + +#content { + margin: 5px 0; + padding: 0 5px; + border: 0 none; + height: 365px; + width: 97% !important; +} + +* html .postdivrich { + zoom: 1; +} + +/* Submit */ +#saving { + display: inline; + vertical-align: middle; +} + +.submit input, +.button, +.button-primary, +.button-secondary, +.button-highlighted, +#postcustomstuff .submit input { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + text-decoration: none; + font-size: 11px !important; + line-height: 16px; + padding: 2px 8px; + cursor: pointer; + border-width: 1px; + border-style: solid; + -moz-border-radius: 11px; + -khtml-border-radius: 11px; + -webkit-border-radius: 11px; + border-radius: 11px; +} + +.button-primary { + background: #21759B url(../images/button-grad.png) repeat-x scroll left top; + border-color: #21759B; + color: #fff; +} + +.ac_results { + padding: 0; + margin: 0; + list-style: none; + position: absolute; + z-index: 10000; + display: none; + border-width: 1px; + border-style: solid; +} + +.ac_results li { + padding: 2px 5px; + white-space: nowrap; + text-align: left; +} + +.ac_over { + cursor: pointer; +} + +.ac_match { + text-decoration: underline; +} + +#TB_ajaxContent #options { + position: absolute; + top: 20px; + right: 25px; + padding: 5px; +} + +#TB_ajaxContent h3 { + margin-bottom: .25em; +} + +.updated { + margin: 10px 0; + padding: 0; + border-width: 1px; + border-style: solid; + width: 99%; +} + +.updated p, +.error p { + margin: 0.6em 0; + padding: 0 0.6em; +} + +.error a { + text-decoration: underline; +} + +.updated a { + text-decoration: none; + padding-bottom: 2px; +} + +#post_status { + margin-left: 10px; + margin-bottom: 1em; + display: block; +} + +/* Footer */ +#footer { + height: 65px; + display: block; + width: 640px; + padding: 10px 0 0 60px; + margin: 0; + position: absolute; + bottom: 0; + font-size: 12px; +} + +#footer p { + margin: 0; + padding: 7px 0; +} + +#footer p a { + text-decoration: none; +} + +#footer p a:hover { + text-decoration: underline; +} + +/* Utility Classes */ +.centered { + text-align: center; +} + +.hidden { + display: none; +} + +.postbox input[type="text"], +.postbox textarea, +.stuffbox input[type="text"], +.stuffbox textarea { + border-width: 1px; + border-style: solid; +} + +/* tag hints */ +.taghint { + color: #aaa; + margin: -17px 0 0 7px; + visibility: hidden; +} + +input.newtag ~ div.taghint { + visibility: visible; +} + +input.newtag:focus ~ div.taghint { + visibility: hidden; +} diff --git a/src/wp-admin/css/theme-editor-rtl.css b/src/wp-admin/css/theme-editor-rtl.css new file mode 100644 index 00000000..23023dff --- /dev/null +++ b/src/wp-admin/css/theme-editor-rtl.css @@ -0,0 +1 @@ +#templateside{float: left;} diff --git a/src/wp-admin/css/theme-editor-rtl.dev.css b/src/wp-admin/css/theme-editor-rtl.dev.css new file mode 100644 index 00000000..a4dcb46e --- /dev/null +++ b/src/wp-admin/css/theme-editor-rtl.dev.css @@ -0,0 +1,3 @@ +#templateside { + float: left; +} diff --git a/src/wp-admin/css/theme-editor.css b/src/wp-admin/css/theme-editor.css new file mode 100644 index 00000000..f66a1ca2 --- /dev/null +++ b/src/wp-admin/css/theme-editor.css @@ -0,0 +1 @@ +.alignleft h3{margin:0;}h3 span{font-weight:normal;}#template textarea{font-family:Consolas,Monaco,Courier,monospace;font-size:12px;width:97%;}#template p{width:97%;}#templateside{float:right;width:190px;word-wrap:break-word;}#templateside h3,#postcustomstuff p.submit{margin:0;}#templateside h4{margin:1em 0 0;}#templateside ol,#templateside ul{margin:.5em;padding:0;}#templateside li{margin:4px 0;}#templateside ul li a span.highlight{display:block;}.nonessential{font-size:11px;font-style:italic;padding-left:12px;}.highlight{padding:3px 3px 3px 12px;margin-left:-12px;font-weight:bold;-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;}div.tablenav{margin-right:210px;}#documentation{margin-top:10px;}#documentation label{line-height:22px;vertical-align:top;font-weight:bold;}.fileedit-sub{padding:10px 0 8px;line-height:180%;} \ No newline at end of file diff --git a/src/wp-admin/css/theme-editor.dev.css b/src/wp-admin/css/theme-editor.dev.css new file mode 100644 index 00000000..d7effcea --- /dev/null +++ b/src/wp-admin/css/theme-editor.dev.css @@ -0,0 +1,80 @@ +.alignleft h3 { + margin: 0; +} + +h3 span { + font-weight: normal; +} + +#template textarea { + font-family: Consolas, Monaco, Courier, monospace; + font-size: 12px; + width: 97%; +} + +#template p { + width: 97%; +} + +#templateside { + float: right; + width: 190px; + word-wrap: break-word; +} + +#templateside h3, +#postcustomstuff p.submit { + margin: 0; +} + +#templateside h4 { + margin: 1em 0 0; +} + +#templateside ol, +#templateside ul { + margin: .5em; + padding: 0; +} + +#templateside li { + margin: 4px 0; +} + +#templateside ul li a span.highlight { + display:block; +} + +.nonessential { + font-size: 11px; + font-style: italic; + padding-left: 12px; +} + +.highlight { + padding: 3px 3px 3px 12px; + margin-left: -12px; + font-weight: bold; + -moz-border-radius: 8px; + -khtml-border-radius: 8px; + -webkit-border-radius: 8px; + border-radius: 8px; +} + +div.tablenav { + margin-right: 210px; +} + +#documentation { + margin-top: 10px; +} +#documentation label { + line-height: 22px; + vertical-align: top; + font-weight: bold; +} + +.fileedit-sub { + padding: 10px 0 8px; + line-height: 180%; +} diff --git a/src/wp-admin/css/theme-install-rtl.css b/src/wp-admin/css/theme-install-rtl.css new file mode 100644 index 00000000..3dd959c6 --- /dev/null +++ b/src/wp-admin/css/theme-install-rtl.css @@ -0,0 +1 @@ +div.star{left:auto;right:0;}.star img,div.star a,div.star a:hover,div.star a:visited{right:auto;left:0;}.theme-listing .theme-item h3{font-style:normal;}#theme-information .theme-preview-img{float:right;margin:5px 15px 10px 25px;}#theme-information .action-button #cancel{float:right;}#theme-information .action-button #install{float:left;}.feature-filter .feature-group{float:right;}.feature-filter .feature-name{float:right;text-align:left;}.feature-filter .feature-group li{float:right;padding-right:0;padding-left:25px;} \ No newline at end of file diff --git a/src/wp-admin/css/theme-install-rtl.dev.css b/src/wp-admin/css/theme-install-rtl.dev.css new file mode 100644 index 00000000..11946883 --- /dev/null +++ b/src/wp-admin/css/theme-install-rtl.dev.css @@ -0,0 +1,41 @@ +div.star { + left:auto; + right: 0; +} + +.star img, div.star a, div.star a:hover, div.star a:visited { + right: auto; + left: 0; +} + +.theme-listing .theme-item h3 { + font-style: normal; +} + +#theme-information .theme-preview-img { + float: right; + margin: 5px 15px 10px 25px; +} + +#theme-information .action-button #cancel { + float: right; +} + +#theme-information .action-button #install { + float: left; +} + +.feature-filter .feature-group { + float: right; +} + +.feature-filter .feature-name { + float: right; + text-align: left; +} + +.feature-filter .feature-group li { + float: right; + padding-right: 0; + padding-left: 25px; +} \ No newline at end of file diff --git a/src/wp-admin/css/theme-install.css b/src/wp-admin/css/theme-install.css new file mode 100644 index 00000000..cd8e31a7 --- /dev/null +++ b/src/wp-admin/css/theme-install.css @@ -0,0 +1 @@ +div.star-holder{position:relative;height:19px;width:100px;font-size:19px;}div.star{height:100%;position:absolute;top:0;left:0;background-color:transparent;letter-spacing:1ex;border:none;}.star1{width:20%;}.star2{width:40%;}.star3{width:60%;}.star4{width:80%;}.star5{width:100%;}.star img,div.star a,div.star a:hover,div.star a:visited{display:block;position:absolute;right:0;border:none;text-decoration:none;}div.star img{width:19px;height:19px;border-left:1px solid #fff;border-right:1px solid #fff;}.theme-listing .theme-item{display:inline-block;width:200px;border:thin solid #ccc;vertical-align:top;}.theme-listing .theme-item h3{text-align:center;font-size:14px;font-style:italic;margin:0;padding:0;}.theme-listing .theme-item img{max-width:150px;max-height:150px;}.theme-listing .theme-item-info span{display:none;}.theme-listing .theme-item:hover .theme-item-info span{display:inline;}.theme-listing .theme-item:hover .theme-item-info span.dots{display:none;}.theme-listing .theme-item-info span.action-links{font-weight:bold;text-align:center;}.theme-listing br.line{border-bottom-width:1px;border-bottom-style:solid;margin-bottom:3px;}.available-theme{padding:20px 15px;}#theme-information .theme-preview-img{float:left;margin:5px 25px 10px 15px;width:300px;}#theme-information .action-button{border-top-width:1px;border-top-style:solid;margin:10px 5px 0;}#theme-information .action-button #cancel{float:left;margin:10px 15px;}#theme-information .action-button #install{float:right;margin:10px 15px;}#theme-information .available-theme h3{margin:1em 0;}body#theme-information{height:auto;}.feature-filter{-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;border-width:1px;border-style:solid;padding:8px 12px 0;}.feature-filter .feature-group{float:left;margin-bottom:20px;width:725px;}.feature-filter .feature-name{float:left;text-align:right;width:95px;}.feature-filter .feature-group li{display:inline;float:left;list-style-type:none;padding-right:25px;min-width:145px;}.feature-container{width:100%;overflow:auto;margin-bottom:10px;}.feature-group{margin-bottom:0!important;} \ No newline at end of file diff --git a/src/wp-admin/css/theme-install.dev.css b/src/wp-admin/css/theme-install.dev.css new file mode 100644 index 00000000..3fce3587 --- /dev/null +++ b/src/wp-admin/css/theme-install.dev.css @@ -0,0 +1,155 @@ +/* NOTE: the following CSS rules(.star*) are taken more or less straight from the bbPress rating plugin. */ +div.star-holder { + position: relative; + height: 19px; + width: 100px; + font-size: 19px; +} + +div.star { + height: 100%; + position: absolute; + top: 0; + left: 0; + background-color: transparent; + letter-spacing: 1ex; + border: none; +} + +.star1 { width: 20%; } +.star2 { width: 40%; } +.star3 { width: 60%; } +.star4 { width: 80%; } +.star5 { width: 100%; } + +.star img, div.star a, div.star a:hover, div.star a:visited { + display: block; + position: absolute; + right: 0; + border: none; + text-decoration: none; +} + +div.star img { + width: 19px; + height: 19px; + border-left: 1px solid #fff; + border-right: 1px solid #fff; +} + +.theme-listing .theme-item { + display: inline-block; + width: 200px; + border: thin solid #ccc; + vertical-align: top; +} + +.theme-listing .theme-item h3 { + text-align: center; + font-size: 14px; + font-style: italic; + margin: 0; + padding: 0; +} + +.theme-listing .theme-item img { + max-width: 150px; + max-height: 150px; +} + +.theme-listing .theme-item-info span { + display: none; +} + +.theme-listing .theme-item:hover .theme-item-info span { + display: inline; +} + +.theme-listing .theme-item:hover .theme-item-info span.dots { + display: none; +} + +.theme-listing .theme-item-info span.action-links { + font-weight: bold; + text-align: center; +} + +.theme-listing br.line { + border-bottom-width: 1px; + border-bottom-style: solid; + margin-bottom: 3px; +} + +.available-theme { + padding: 20px 15px; +} + +#theme-information .theme-preview-img { + float: left; + margin: 5px 25px 10px 15px; + width: 300px; +} + +#theme-information .action-button { + border-top-width: 1px; + border-top-style: solid; + margin: 10px 5px 0; +} + +#theme-information .action-button #cancel { + float: left; + margin: 10px 15px; +} + +#theme-information .action-button #install { + float: right; + margin: 10px 15px; +} + +#theme-information .available-theme h3 { + margin: 1em 0; +} + +body#theme-information { + height: auto; +} + +.feature-filter { + -moz-border-radius: 8px; + -khtml-border-radius: 8px; + -webkit-border-radius: 8px; + border-radius: 8px; + border-width: 1px; + border-style: solid; + padding: 8px 12px 0; +} + +.feature-filter .feature-group { + float: left; + margin-bottom: 20px; + width: 725px; +} + +.feature-filter .feature-name { + float: left; + text-align: right; + width: 95px; +} + +.feature-filter .feature-group li { + display: inline; + float: left; + list-style-type: none; + padding-right: 25px; + min-width: 145px; +} + +.feature-container { +width: 100%; +overflow: auto; +margin-bottom: 10px; +} + +.feature-group { + margin-bottom: 0px !important; +} \ No newline at end of file diff --git a/src/wp-admin/css/widgets-rtl.css b/src/wp-admin/css/widgets-rtl.css new file mode 100644 index 00000000..417995c6 --- /dev/null +++ b/src/wp-admin/css/widgets-rtl.css @@ -0,0 +1 @@ +#widget-list .widget,#wp_inactive_widgets .widget{float:right;}ul#widget-list li.widget-list-item div.widget-description{margin:0 200px 0 0;padding:0 4em 0 0;}.widget-control-save,.widget-control-remove{margin-right:0;margin-left:8px;float:right;} \ No newline at end of file diff --git a/src/wp-admin/css/widgets-rtl.dev.css b/src/wp-admin/css/widgets-rtl.dev.css new file mode 100644 index 00000000..d2ccce59 --- /dev/null +++ b/src/wp-admin/css/widgets-rtl.dev.css @@ -0,0 +1,14 @@ +#widget-list .widget, +#wp_inactive_widgets .widget { + float: right; +} +ul#widget-list li.widget-list-item div.widget-description { + margin: 0 200px 0 0; + padding: 0 4em 0 0; +} +.widget-control-save, +.widget-control-remove { + margin-right: 0; + margin-left: 8px; + float: right; +} diff --git a/src/wp-admin/css/widgets.css b/src/wp-admin/css/widgets.css new file mode 100644 index 00000000..44eb420e --- /dev/null +++ b/src/wp-admin/css/widgets.css @@ -0,0 +1 @@ +html,body{min-width:950px;}div.widget-liquid-left{float:left;clear:left;width:100%;margin-right:-325px;}div#widgets-left{margin-left:5px;margin-right:325px;}div#widgets-right{width:285px;margin:0 auto;}div.widget-liquid-right{float:right;clear:right;width:300px;}.widget-liquid-right .widget,#wp_inactive_widgets .widget,.widget-liquid-right .sidebar-description{width:250px;margin:0 auto 20px;overflow:hidden;}.widget-liquid-right .sidebar-description{margin-bottom:10px;}#wp_inactive_widgets .widget{margin:0 10px 20px;float:left;}div.sidebar-name h3{margin:0;padding:5px 12px;font-size:13px;height:19px;overflow:hidden;white-space:nowrap;}div.sidebar-name{background-repeat:repeat-x;background-position:0 0;cursor:pointer;font-size:13px;border-width:1px;border-style:solid;-moz-border-radius-topleft:8px;-moz-border-radius-topright:8px;-webkit-border-top-right-radius:8px;-webkit-border-top-left-radius:8px;-khtml-border-top-right-radius:8px;-khtml-border-top-left-radius:8px;border-top-right-radius:8px;border-top-left-radius:8px;}.js .closed .sidebar-name{-moz-border-radius-bottomleft:8px;-moz-border-radius-bottomright:8px;-webkit-border-bottom-right-radius:8px;-webkit-border-bottom-left-radius:8px;-khtml-border-bottom-right-radius:8px;-khtml-border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-bottom-left-radius:8px;}.widget-liquid-right .widgets-sortables,#widgets-left .widget-holder{border-width:0 1px 1px;border-style:none solid solid;-moz-border-radius-bottomleft:8px;-moz-border-radius-bottomright:8px;-webkit-border-bottom-right-radius:8px;-webkit-border-bottom-left-radius:8px;-khtml-border-bottom-right-radius:8px;-khtml-border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-bottom-left-radius:8px;}.js .closed .widgets-sortables,.js .closed .widget-holder{display:none;}.widget-liquid-right .widgets-sortables{padding:15px 0 0;}#available-widgets .widget-holder{padding:7px 5px 0;}#wp_inactive_widgets{padding:5px 5px 0;}#widget-list .widget{width:250px;margin:0 10px 15px;border:0 none;float:left;}#widget-list .widget-description{padding:5px 8px;}#widget-list .widget-top{border-width:1px;border-style:solid;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.widget-placeholder{border-width:1px;border-style:dashed;margin:0 auto 20px;height:26px;width:250px;}#wp_inactive_widgets .widget-placeholder{margin:0 10px 20px;float:left;}div.widgets-holder-wrap{padding:0;margin:10px 0 20px;}#widgets-left #available-widgets{background-color:transparent;border:0 none;}ul#widget-list{list-style:none;margin:0;padding:0;min-height:100px;}.widget .widget-top{font-size:12px;font-weight:bold;height:26px;overflow:hidden;}.widget-top .widget-title{padding:5px 9px;}.widget-top .widget-title-action{float:right;}a.widget-action{display:block;width:24px;height:26px;}#available-widgets a.widget-action{display:none;}.widget-top a.widget-action{background:url("../images/menu-bits.gif?ver=20100610") no-repeat scroll 0 -110px;}.widget .widget-inside,.widget .widget-description{padding:12px 12px 10px;font-size:11px;line-height:16px;}.widget-inside,.widget-description{display:none;}#available-widgets .widget-description{display:block;}.widget .widget-inside p{margin:0 0 1em;padding:0;}.widget-title h4{margin:0;line-height:1.3;overflow:hidden;white-space:nowrap;}.widgets-sortables{min-height:90px;}.widget-control-actions{margin-top:8px;}.widget-control-actions a{text-decoration:none;}.widget-control-actions a:hover{text-decoration:underline;}.widget-control-actions .ajax-feedback{padding-bottom:3px;}.widget-control-actions div.alignleft{margin-top:6px;}div#sidebar-info{padding:0 1em;margin-bottom:1em;font-size:11px;}.widget-title a,.widget-title a:hover{text-decoration:none;border-bottom:none;}.widget-control-edit{display:block;font-size:11px;font-weight:normal;line-height:26px;padding:0 8px 0 0;}a.widget-control-edit{text-decoration:none;}.widget-control-edit .add,.widget-control-edit .edit{display:none;}#available-widgets .widget-control-edit .add,#widgets-right .widget-control-edit .edit,#wp_inactive_widgets .widget-control-edit .edit{display:inline;}.editwidget{margin:0 auto 15px;}.editwidget .widget-inside{display:block;border-width:1px;border-style:solid;padding:10px;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.inactive p.description{margin:5px 15px 8px;}#available-widgets p.description{margin:0 12px 12px;}.widget-position{margin-top:8px;}.inactive{padding-top:2px;}.sidebar-name-arrow{float:right;height:29px;width:26px;}.widget-title .in-widget-title{font-size:11px;white-space:nowrap;}#removing-widget{display:none;font-weight:normal;padding-left:15px;font-size:12px;}.widget-control-noform,#access-off,.widgets_access .widget-action,.widgets_access .sidebar-name-arrow,.widgets_access #access-on,.widgets_access .widget-holder .description{display:none;}.widgets_access .widget-holder,.widgets_access #widget-list{padding-top:10px;}.widgets_access #access-off{display:inline;}.widgets_access #wpbody-content .widget-title-action,.widgets_access #wpbody-content .widget-control-edit,.widgets_access .closed .widgets-sortables,.widgets_access .closed .widget-holder{display:block;}.widgets_access .closed .sidebar-name{-moz-border-radius-bottomleft:0;-moz-border-radius-bottomright:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-khtml-border-bottom-right-radius:0;-khtml-border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;}.widgets_access .sidebar-name,.widgets_access .widget .widget-top{cursor:default;} \ No newline at end of file diff --git a/src/wp-admin/css/widgets.dev.css b/src/wp-admin/css/widgets.dev.css new file mode 100644 index 00000000..0ce9fd3c --- /dev/null +++ b/src/wp-admin/css/widgets.dev.css @@ -0,0 +1,370 @@ +html, +body { + min-width: 950px; +} + +/* 2 column liquid layout */ +div.widget-liquid-left { + float: left; + clear: left; + width: 100%; + margin-right: -325px; +} + +div#widgets-left { + margin-left: 5px; + margin-right: 325px; +} + +div#widgets-right { + width: 285px; + margin: 0 auto; +} + +div.widget-liquid-right { + float: right; + clear: right; + width: 300px; +} + +.widget-liquid-right .widget, +#wp_inactive_widgets .widget, +.widget-liquid-right .sidebar-description { + width: 250px; + margin: 0 auto 20px; + overflow: hidden; +} + +.widget-liquid-right .sidebar-description { + margin-bottom: 10px; +} + +#wp_inactive_widgets .widget { + margin: 0 10px 20px; + float: left; +} + +div.sidebar-name h3 { + margin: 0; + padding: 5px 12px; + font-size: 13px; + height: 19px; + overflow: hidden; + white-space: nowrap; +} + +div.sidebar-name { + background-repeat: repeat-x; + background-position: 0 0; + cursor: pointer; + font-size: 13px; + border-width: 1px; + border-style: solid; + -moz-border-radius-topleft: 8px; + -moz-border-radius-topright: 8px; + -webkit-border-top-right-radius: 8px; + -webkit-border-top-left-radius: 8px; + -khtml-border-top-right-radius: 8px; + -khtml-border-top-left-radius: 8px; + border-top-right-radius: 8px; + border-top-left-radius: 8px; +} + +.js .closed .sidebar-name { + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-border-bottom-left-radius: 8px; + -khtml-border-bottom-right-radius: 8px; + -khtml-border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + border-bottom-left-radius: 8px; +} + +.widget-liquid-right .widgets-sortables, +#widgets-left .widget-holder { + border-width: 0 1px 1px; + border-style: none solid solid; + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-border-bottom-left-radius: 8px; + -khtml-border-bottom-right-radius: 8px; + -khtml-border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + border-bottom-left-radius: 8px; +} + +.js .closed .widgets-sortables, +.js .closed .widget-holder { + display: none; +} + +.widget-liquid-right .widgets-sortables { + padding: 15px 0 0; +} + +#available-widgets .widget-holder { + padding: 7px 5px 0; +} + +#wp_inactive_widgets { + padding: 5px 5px 0; +} + +#widget-list .widget { + width: 250px; + margin: 0 10px 15px; + border: 0 none; + float: left; +} + +#widget-list .widget-description { + padding: 5px 8px; +} + +#widget-list .widget-top { + border-width: 1px; + border-style: solid; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +.widget-placeholder { + border-width: 1px; + border-style: dashed; + margin: 0 auto 20px; + height: 26px; + width: 250px; +} + +#wp_inactive_widgets .widget-placeholder { + margin: 0 10px 20px; + float: left; +} + +div.widgets-holder-wrap { + padding: 0; + margin: 10px 0 20px; +} + +#widgets-left #available-widgets { + background-color: transparent; + border: 0 none; +} + +ul#widget-list { + list-style: none; + margin: 0; + padding: 0; + min-height: 100px; +} + +.widget .widget-top { + font-size: 12px; + font-weight: bold; + height: 26px; + overflow: hidden; +} + +.widget-top .widget-title { + padding: 5px 9px; +} + +.widget-top .widget-title-action { + float: right; +} + +a.widget-action { + display: block; + width: 24px; + height: 26px; +} + +#available-widgets a.widget-action { + display: none; +} + +.widget-top a.widget-action { + background: url("../images/menu-bits.gif?ver=20100610") no-repeat scroll 0 -110px; +} + +.widget .widget-inside, +.widget .widget-description { + padding: 12px 12px 10px; + font-size: 11px; + line-height: 16px; +} + +.widget-inside, +.widget-description { + display: none; +} + +#available-widgets .widget-description { + display: block; +} + +.widget .widget-inside p { + margin: 0 0 1em; + padding: 0; +} + +.widget-title h4 { + margin: 0; + line-height: 1.3; + overflow: hidden; + white-space: nowrap; +} + +.widgets-sortables { + min-height: 90px; +} + +.widget-control-actions { + margin-top: 8px; +} + +.widget-control-actions a { + text-decoration: none; +} + +.widget-control-actions a:hover { + text-decoration: underline; +} + +.widget-control-actions .ajax-feedback { + padding-bottom: 3px; +} + +.widget-control-actions div.alignleft { + margin-top: 6px; +} + +div#sidebar-info { + padding: 0 1em; + margin-bottom: 1em; + font-size: 11px; +} + +.widget-title a, +.widget-title a:hover { + text-decoration: none; + border-bottom: none; +} + +.widget-control-edit { + display: block; + font-size: 11px; + font-weight: normal; + line-height: 26px; + padding: 0 8px 0 0; +} + +a.widget-control-edit { + text-decoration: none; +} + +.widget-control-edit .add, +.widget-control-edit .edit { + display: none; +} + +#available-widgets .widget-control-edit .add, +#widgets-right .widget-control-edit .edit, +#wp_inactive_widgets .widget-control-edit .edit { + display: inline; +} + +.editwidget { + margin: 0 auto 15px; +} + +.editwidget .widget-inside { + display: block; + border-width: 1px; + border-style: solid; + padding: 10px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +.inactive p.description { + margin: 5px 15px 8px; +} + +#available-widgets p.description { + margin: 0 12px 12px; +} + +.widget-position { + margin-top: 8px; +} + +.inactive { + padding-top: 2px; +} + +.sidebar-name-arrow { + float: right; + height: 29px; + width: 26px; +} + +.widget-title .in-widget-title { + font-size: 11px; + white-space: nowrap; +} + +#removing-widget { + display: none; + font-weight: normal; + padding-left: 15px; + font-size: 12px; +} + +.widget-control-noform, +#access-off, +.widgets_access .widget-action, +.widgets_access .sidebar-name-arrow, +.widgets_access #access-on, +.widgets_access .widget-holder .description { + display: none; +} + +.widgets_access .widget-holder, +.widgets_access #widget-list { + padding-top: 10px; +} + +.widgets_access #access-off { + display: inline; +} + +.widgets_access #wpbody-content .widget-title-action, +.widgets_access #wpbody-content .widget-control-edit, +.widgets_access .closed .widgets-sortables, +.widgets_access .closed .widget-holder { + display: block; +} + +.widgets_access .closed .sidebar-name { + -moz-border-radius-bottomleft: 0; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 0; + -khtml-border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.widgets_access .sidebar-name, +.widgets_access .widget .widget-top { + cursor: default; +} + diff --git a/src/wp-admin/css/wp-admin-rtl.css b/src/wp-admin/css/wp-admin-rtl.css new file mode 100644 index 00000000..bf298827 --- /dev/null +++ b/src/wp-admin/css/wp-admin-rtl.css @@ -0,0 +1 @@ +td.available-theme{text-align:right;}#current-theme img{float:right;margin-right:0;margin-left:1em;}.quicktags,.search{font-family:Tahoma,Arial,sans-serif;}#doaction,#doaction2,#post-query-submit{margin-right:0;margin-left:8px;}#save-post{float:right;}#minor-publishing .ajax-loading{padding:3px 4px 0 0;float:right;}.preview{float:left;}#sticky-span{margin-left:0;margin-right:18px;}#post-body .misc-pub-section{border-right-width:0;border-left-width:1px;border-right-style:none;border-left-style:solid;float:right;}#post-body .misc-pub-section-last{border-left:0;}#delete-action{text-align:right;float:right;}#publishing-action{text-align:left;float:left;}.side-info ul{padding-left:0;padding-right:18px;}.submit input,.button,.button-primary,.button-secondary,.button-highlighted,#postcustomstuff .submit input{font-family:Tahoma,Arial,sans-serif;}#wpcontent select{font-family:Tahoma,Arial,sans-serif;}#quicktags{background-position:right top;}#template div{margin-right:0;margin-left:190px;}* html #template div{margin-left:0;}.list-ajax-loading{float:left;margin-right:0;margin-left:9px;}#your-profile legend{font-family:Tahoma,Arial,sans-serif;}#ajax-response.alignleft{margin-left:0;margin-right:2em;}.page-numbers{margin-right:0;margin-left:1px;}.column-author img,.column-username img{float:right;margin-right:0;margin-left:10px;}.tablenav a.button-secondary{margin-right:0;margin-left:8px;}.tablenav .actions{padding-right:0;padding-left:8px;}.tablenav .tablenav-pages{float:left;}.tablenav .displaying-num{margin-right:0;margin-left:10px;font-family:Tahoma,Arial,sans-serif;font-style:normal;}#postcustomstuff table input,#postcustomstuff table select,#postcustomstuff table textarea{margin:8px 8px 8px 0;}#pass-strength-result{float:right;margin:12px 1px 5px 5px;}#user_info{float:left;}#header-logo{float:right;margin:7px 15px 0 0;}#wphead h1{font-family:Tahoma,Arial,sans-serif;float:right;}#wphead h1.long-title{font-family:Tahoma,Arial,sans-serif;}#adminmenu .wp-submenu a{padding-left:0;padding-right:12px;border-width:0 0 0 1px;border-style:none none none solid;font-family:Tahoma,Arial,sans-serif;}#adminmenu a.menu-top,#adminmenu .wp-submenu-head{font-family:Tahoma,Arial,sans-serif;}#adminmenu img.wp-menu-image{float:right;}.folded #adminmenu img.wp-menu-image{padding:7px 6px 0 0;}#adminmenu a.separator{cursor:e-resize;}.folded #adminmenu a.separator{cursor:w-resize;}#adminmenu .wp-submenu .wp-submenu-head{padding:6px 10px 6px 4px;}.folded #adminmenu .wp-submenu{margin:-1px 28px 0 0;}.folded #adminmenu .wp-submenu a{padding-left:0;padding-right:10px;}.folded #adminmenu a.wp-has-submenu{margin-left:0;margin-right:40px;}#adminmenu .wp-menu-toggle{float:left;padding:1px 0 0 2px;clear:left;}#adminmenu div.wp-menu-image{float:right;}#wphead-info{margin:0 15px 0 0;padding-right:0;padding-left:15px;}#adminmenu #awaiting-mod,#adminmenu span.update-plugins,#sidemenu li a span.update-plugins{font-family:Tahoma,Arial,sans-serif;margin-left:0;margin-right:7px;}.post-com-count-wrapper{font-family:Tahoma,Arial,sans-serif;}.column-response .post-com-count{float:right;margin-right:0;margin-left:5px;}.form-table th{text-align:right;}.form-table input.tog{margin-right:0;margin-left:2px;float:right;}.form-table table.color-palette{float:right;}#profile-page .form-table #rich_editing{margin-right:0;margin-left:5px;}#normal-sortables .postbox .submit{float:left;}#post-body .tagsdiv #newtag{margin-right:0;margin-left:5px;}#post-status-info{padding:0 7px 0 15px;}#comment-status-radio input{margin:2px 0 5px 3px;}.tagchecklist{margin-left:0;margin-right:10px;}.tagchecklist strong{margin-left:0;margin-right:-8px;}.tagchecklist span{float:right;}.tagchecklist span a{margin:6px -9px 0 0;float:right;}.ac_results li{text-align:right;}#poststuff h2{clear:right;}.description,.form-wrap p{font-family:Tahoma,Arial,sans-serif;}.sorting-indicator{margin-left:0;margin-right:7px;}th.sortable a span,th.sorted a span{float:right;}.fixed .column-comments a{float:right;}.autosave-info{padding:2px 2px 2px 15px;text-align:left;}.meta-box-sortables .postbox .handlediv{float:left;}.howto{font-family:Tahoma,Arial,sans-serif;}.postarea h3 label{float:right;}.postarea #add-media-button{float:left;right:auto;left:10px;}.wp_themeSkin tr.mceFirst td.mceToolbar{background-position:right top;}#poststuff #edButtonPreview,#poststuff #edButtonHTML{margin:5px 0 0 5px;float:left;}#poststuff #edButtonHTML{margin-right:0;margin-left:15px;}#media-buttons a{padding:0 10px 5px 0;}.submitbox .submit{text-align:right;}.inside-submitbox #post_status{margin:2px -2px 2px 0;}.submitbox .submit input{margin-right:0;margin-left:4px;}.category-adder{margin-left:0;margin-right:120px;}#post-body ul.category-tabs li.tabs,#post-body ul.add-menu-item-tabs li.tabs{-moz-border-radius:0 3px 3px 0;-webkit-border-top-left-radius:0;-webkit-border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:3px;border-top-left-radius:0;border-top-right-radius:3px;border-bottom-left-radius:0;border-bottom-right-radius:3px;}#post-body ul.category-tabs,#post-body ul.add-menu-item-tabs{float:right;text-align:left;margin:0 0 0 -120px;}#post-body .categorydiv div.tabs-panel,#post-body .taxonomy div.tabs-panel,#post-body #linkcategorydiv div.tabs-panel{margin:0 120px 0 5px;}#front-page-warning,#front-static-pages ul,.inline-editor ul.cat-checklist ul,.categorydiv ul.categorychecklist ul,.customlinkdiv ul.categorychecklist ul,.posttypediv ul.categorychecklist ul,.taxonomydiv ul.categorychecklist ul,#linkcategorydiv ul.categorychecklist ul{margin-left:0;margin-right:18px;}p.search-box{float:left;}#posts-filter fieldset{float:right;margin:0 0 1em 1.5ex;}#posts-filter fieldset legend{padding:0 1px .2em 0;}.view-switch{float:left;}.filter{float:right;margin:-5px 10px 0 0;}#the-comment-list td.comment p.comment-author{margin-right:0;}#the-comment-list p.comment-author img{float:right;margin-right:0;margin-left:8px;}.tablenav .delete{margin-right:0;margin-left:20px;}td.action-links,th.action-links{text-align:left;}.filter .subsubsub{margin-left:0;margin-right:-10px;}#wp-word-count{margin-right:10px;}.tool-box .title{font-family:Tahoma,Arial,sans-serif;}.settings-toggle{text-align:left;margin:5px 0 15px 7px;}.curtime #timestamp{background-position:right top;padding-left:0;padding-right:18px;}#sidemenu{margin:-30px 315px 0 15px;float:left;padding-left:0;padding-right:10px;}#sidemenu a{float:right;}#replysubmit .button{margin-right:0;margin-left:5px;}#edithead .inside{float:right;margin:3px 5px 2px 0;}#replyrow #ed_reply_toolbar input{margin:1px 1px 1px 2px;}#screen-meta-links{margin:0 0 0 18px;}#screen-options-link-wrap,#contextual-help-link-wrap{float:left;font-family:Tahoma,Arial,sans-serif;margin:0 0 0 6px;}#contextual-help-wrap li{margin-left:0;margin-right:18px;}#screen-meta a.show-settings{padding:0 6px 0 16px;background-position:left top;}.metabox-prefs label{padding-right:0;padding-left:15px;}.metabox-prefs label input{margin:0 2px 0 5px;}.inline-editor .save,.inline-editor .cancel{margin-right:0;margin-left:5px;}#replysubmit img.waiting,.inline-edit-save img.waiting{float:left;}.trash-undo-inside,.spam-undo-inside,.spam-undo-inside .avatar,.trash-undo-inside .avatar{margin-right:0;margin-left:8px;}#bulk-titles div a{float:right;margin:3px -2px 0 3px;}#wpbody-content .filename{margin-left:0;margin-right:10px;}#wpbody-content .inline-edit-row fieldset{float:right;}#wpbody-content .quick-edit-row-page fieldset.inline-edit-col-right .inline-edit-col{border-left:0 none;border-right:1px solid;}#wpbody-content .bulk-edit-row .inline-edit-col-bottom{float:left;}.inline-edit-row fieldset label span.title{float:right;}.inline-edit-row fieldset label span.input-text-wrap{margin-left:0;margin-right:5em;}.quick-edit-row-post fieldset.inline-edit-col-right label span.title{padding-right:0;padding-left:.5em;}#wpbody-content .quick-edit-row fieldset .inline-edit-group label.alignleft:first-child{margin-right:0;margin-left:.5em;}.inline-edit-row fieldset span.title,.inline-edit-row fieldset span.checkbox-title{font-family:Tahoma,Arial,sans-serif;}.inline-edit-row fieldset .inline-edit-date{float:right;}.inline-edit-row fieldset ul.cat-checklist label,.inline-edit-row .catshow,.inline-edit-row .cathide,.inline-edit-row #bulk-titles div{font-family:Tahoma,Arial,sans-serif;}.quick-edit-row-post fieldset label.inline-edit-status{float:right;}.describe-toggle-on,.describe-toggle-off{float:left;margin-right:0;margin-left:20px;}#wpbody-content #media-items .filename{float:right;margin-left:0;margin-right:10px;}.media-item .pinkynail{float:right;}#find-posts-response .found-radio{padding:8px 8px 0 0;}.find-box-buttons{left:auto;right:12px;}.find-box-search label{padding-right:0;padding-left:6px;}#favorite-actions{float:left;}#favorite-first{padding:3px 12px 4px 30px;}#favorite-inside a{padding:3px 10px 3px 5px;}#favorite-toggle{right:auto;left:0;background:transparent url(../images/fav-arrow-rtl.gif?ver=20100531) no-repeat 10px -4px;}#utc-time,#local-time{padding-left:0;padding-right:25px;font-family:Tahoma,Arial;}.icon32{float:right;margin:14px 0 0 6px;}.subtitle{padding-left:0;padding-right:25px;}ol{list-style-type:decimal;margin-left:0;margin-right:2em;}.postbox-container{float:right;padding-left:.5%;padding-right:0;}#wpbody-content .describe th{text-align:right;}.describe .media-item-info .A1B1{padding:0 10px 0 0;}.media-upload-form td label{margin-left:6px;margin-right:2px;}.media-upload-form .align .field label{padding:0 22px 0 0;margin:0 0 0 1em;}.media-upload-form tr.image-size label{margin:0 3px 0 0;}#wpbody-content .describe p.help{padding:0 5px 0 0;}.media-item .error-div a.dismiss,.describe-toggle-on,.describe-toggle-off{float:left;margin-right:0;margin-left:20px;}.describe-toggle-on,.describe-toggle-off{float:left;margin-left:20px;margin-right:0;}.media-item .error-div{padding-left:0;padding-right:10px;}.media-item .pinkynail{float:right;}.crunching{text-align:left;margin-left:5px;margin-right:0;}.bar{border-left-width:3px;border-left-style:solid;border-right:none;}.clearlooks2 .mceTop .mceLeft{width:100%!important;}.taghint{margin:15px 12px -24px 0;}#poststuff .tagsdiv .howto{margin:0 8px 6px 0;}#broken-themes{text-align:right;}.describe .del-link{padding-right:5px;padding-left:0;}.comment-ays th{border-left-style:solid;border-left-width:1px;}.appearance_page_custom-header #available-headers .default-header{float:right;margin:0 0 20px 20px;}.appearance_page_custom-header #available-headers label input{margin-right:0;margin-left:10px;}#custom-background label{padding-right:0;padding-left:15px;}#author-email,#author-url,#rss-url-1,#edit-slug-box,#post_name,#trackback_url,#metakeyinput,#post_password,#slug,#category_nicename,#link_url,#link_image,#rss_uri,#menu_order,#email,#newcomment_author_url,#pages-exclude,#template textarea,#user_login,#url,#pass1,#pass2,#aim,#yim,#jabber,#siteurl,#home,#admin_email,#gmt_offset,#default_post_edit_rows,#mailserver_url,#mailserver_login,#mailserver_pass,#mailserver_port,#ping_sites,#posts_per_page,#posts_per_rss,#blog_charset,#close_comments_days_old,#comments_per_page,#comment_max_links,#moderation_keys,#blacklist_keys,#thumbnail_size_w,#thumbnail_size_h,#medium_size_w,#medium_size_h,#large_size_w,#large_size_h,#permalink_structure,#category_base,#tag_base,#upload_path,#upload_url_path,#rules{direction:ltr;}#quicktags #ed_em,#ed_reply_toolbar #ed_reply_em,.tablenav .displaying-num,#footer,#footer a,p.help,p.description,span.description,.form-wrap p,#side-sortables .comments-box thead th,#normal-sortables .comments-box thead th,.howto,.inline-edit-row fieldset span.title,.inline-edit-row fieldset span.checkbox-title,#utc-time,#local-time,form.upgrade .hint,p.install-help,.imgedit-help{font-style:normal;} \ No newline at end of file diff --git a/src/wp-admin/css/wp-admin-rtl.dev.css b/src/wp-admin/css/wp-admin-rtl.dev.css new file mode 100644 index 00000000..463be701 --- /dev/null +++ b/src/wp-admin/css/wp-admin-rtl.dev.css @@ -0,0 +1,728 @@ +/* 0 - 200 +=================================== */ +td.available-theme { + text-align: right; +} +#current-theme img { + float: right; + margin-right: 0; + margin-left: 1em; +} +.quicktags, .search { + font-family: Tahoma, Arial, sans-serif; +} +/* 200 - 500 +=================================== */ +#doaction, +#doaction2, +#post-query-submit { + margin-right: 0; + margin-left: 8px; +} +#save-post { + float: right; +} +#minor-publishing .ajax-loading { + padding: 3px 4px 0 0; + float: right; +} +.preview { + float: left; +} +#sticky-span { + margin-left: 0; + margin-right: 18px; +} +#post-body .misc-pub-section { + border-right-width: 0; + border-left-width: 1px; + border-right-style: none; + border-left-style: solid; + float: right; +} +#post-body .misc-pub-section-last { + border-left: 0; +} +#delete-action { + text-align: right; + float: right; +} +#publishing-action { + text-align: left; + float: left; +} +.side-info ul { + padding-left: 0; + padding-right: 18px; +} +.submit input, +.button, +.button-primary, +.button-secondary, +.button-highlighted, +#postcustomstuff .submit input { + font-family: Tahoma, Arial, sans-serif; +} +#wpcontent select { + font-family: Tahoma, Arial, sans-serif; +} +#quicktags { + background-position: right top; +} +/* 500 - 700 +=================================== */ +#template div { + margin-right: 0; + margin-left: 190px; +} +* html #template div { + margin-left: 0; +} + +.list-ajax-loading { + float: left; + margin-right: 0; + margin-left: 9px; +} + +#your-profile legend { + font-family: Tahoma, Arial, sans-serif; +} +#ajax-response.alignleft { + margin-left: 0; + margin-right: 2em; +} +.page-numbers { + margin-right: 0; + margin-left: 1px; +} +.column-author img, .column-username img { + float: right; + margin-right: 0; + margin-left: 10px; +} +.tablenav a.button-secondary { + margin-right: 0; + margin-left: 8px; +} +.tablenav .actions { + padding-right: 0; + padding-left: 8px; +} +.tablenav .tablenav-pages { + float: left; +} +.tablenav .displaying-num { + margin-right: 0; + margin-left: 10px; + font-family: Tahoma, Arial, sans-serif; + font-style: normal; +} +#postcustomstuff table input, +#postcustomstuff table select, +#postcustomstuff table textarea { + margin: 8px 8px 8px 0; +} +/* 700 - 1000 +=================================== */ +#pass-strength-result { + float: right; + margin: 12px 1px 5px 5px; +} +/* Admin Header */ +#user_info { + float: left; +} +#header-logo { + float: right; + margin: 7px 15px 0 0; +} +#wphead h1 { + font-family: Tahoma, Arial, sans-serif; + float: right; +} +#wphead h1.long-title { + font-family: Tahoma, Arial, sans-serif; +} +#adminmenu .wp-submenu a { + padding-left: 0; + padding-right: 12px; + border-width: 0 0 0 1px; + border-style: none none none solid; + font-family: Tahoma, Arial, sans-serif; +} +#adminmenu a.menu-top, +#adminmenu .wp-submenu-head { + font-family: Tahoma, Arial, sans-serif; +} +#adminmenu img.wp-menu-image { + float: right; +} +.folded #adminmenu img.wp-menu-image { + padding: 7px 6px 0 0; +} +#adminmenu a.separator { + cursor: e-resize; +} +.folded #adminmenu a.separator { + cursor: w-resize; +} +#adminmenu .wp-submenu .wp-submenu-head { + padding: 6px 10px 6px 4px; +} +.folded #adminmenu .wp-submenu { + margin: -1px 28px 0 0; +} +.folded #adminmenu .wp-submenu a { + padding-left: 0; + padding-right: 10px; +} +.folded #adminmenu a.wp-has-submenu { + margin-left: 0; + margin-right: 40px; +} +#adminmenu .wp-menu-toggle { + float: left; + padding: 1px 0 0 2px; + clear: left; +} +#adminmenu div.wp-menu-image { + float: right; +} +#wphead-info { + margin: 0 15px 0 0; + padding-right:0; + padding-left: 15px; +} +/* end side admin menu */ +/* 1000 - 1300 +=================================== */ +#adminmenu #awaiting-mod, +#adminmenu span.update-plugins, +#sidemenu li a span.update-plugins { + font-family: Tahoma, Arial, sans-serif; + margin-left: 0; + margin-right: 7px; +} +.post-com-count-wrapper { + font-family: Tahoma, Arial, sans-serif; +} +.column-response .post-com-count { + float: right; + margin-right: 0; + margin-left: 5px; +} +/* Tables used on comment.php and option/setting pages */ +.form-table th { + text-align: right; +} +.form-table input.tog { + margin-right: 0; + margin-left: 2px; + float: right; +} +.form-table table.color-palette { + float: right; +} +#profile-page .form-table #rich_editing { + margin-right: 0; + margin-left: 5px; +} +/* Post Screen */ +/* 1300 - 1500 +=================================== */ +#normal-sortables .postbox .submit { + float: left; +} +#post-body .tagsdiv #newtag { + margin-right: 0; + margin-left: 5px; +} +#post-status-info { + padding: 0 7px 0 15px; +} +#comment-status-radio input { + margin: 2px 0 5px 3px; +} +.tagchecklist { + margin-left: 0; + margin-right: 10px; +} +.tagchecklist strong { + margin-left: 0; + margin-right: -8px; +} +.tagchecklist span { + float: right; +} +.tagchecklist span a { + margin: 6px -9px 0 0; + float: right; +} +.ac_results li { + text-align: right; +} +#poststuff h2 { + clear: right; +} +.description, .form-wrap p { + font-family: Tahoma, Arial, sans-serif; +} +.sorting-indicator { + margin-left: 0; + margin-right: 7px; +} +th.sortable a span, +th.sorted a span { + float: right; +} +.fixed .column-comments a { + float: right; +} + +/* 1500 - 1800 +=================================== */ +.autosave-info { + padding: 2px 2px 2px 15px; + text-align: left; +} +.meta-box-sortables .postbox .handlediv { + float: left; +} +.howto { + font-family: Tahoma, Arial, sans-serif; +} +.postarea h3 label { + float: right; +} +.postarea #add-media-button { + float: left; + right: auto; + left: 10px; +} +.wp_themeSkin tr.mceFirst td.mceToolbar { + background-position: right top; +} +#poststuff #edButtonPreview, +#poststuff #edButtonHTML { + margin: 5px 0 0 5px; + float: left; +} +#poststuff #edButtonHTML { + margin-right: 0; + margin-left: 15px; +} +#media-buttons a { + padding: 0 10px 5px 0; +} +.submitbox .submit { + text-align: right; +} + +.inside-submitbox #post_status { + margin: 2px -2px 2px 0; +} +.submitbox .submit input { + margin-right: 0; + margin-left: 4px; +} +/* Categories */ +.category-adder { + margin-left: 0; + margin-right: 120px; +} +#post-body ul.category-tabs li.tabs, +#post-body ul.add-menu-item-tabs li.tabs { + -moz-border-radius: 0 3px 3px 0; + -webkit-border-top-left-radius: 0; + -webkit-border-top-right-radius: 3px; + -webkit-border-bottom-left-radius: 0; + -webkit-border-bottom-right-radius: 3px; + border-top-left-radius: 0; + border-top-right-radius: 3px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 3px; +} +#post-body ul.category-tabs, +#post-body ul.add-menu-item-tabs { + float: right; + text-align: left; + margin: 0 0 0 -120px; +} +#post-body .categorydiv div.tabs-panel, +#post-body .taxonomy div.tabs-panel, +#post-body #linkcategorydiv div.tabs-panel { + margin: 0 120px 0 5px; +} +/* 1800 - 2000 +=================================== */ +#front-page-warning, +#front-static-pages ul, +.inline-editor ul.cat-checklist ul, +.categorydiv ul.categorychecklist ul, +.customlinkdiv ul.categorychecklist ul, +.posttypediv ul.categorychecklist ul, +.taxonomydiv ul.categorychecklist ul, +#linkcategorydiv ul.categorychecklist ul{ + margin-left: 0; + margin-right: 18px; +} +/* positioning etc. */ +p.search-box { + float: left; +} +#posts-filter fieldset { + float: right; + margin: 0 0 1em 1.5ex; +} +#posts-filter fieldset legend { + padding: 0 1px .2em 0; +} +.view-switch { + float: left; +} +.filter { + float: right; + margin: -5px 10px 0 0; +} +#the-comment-list td.comment p.comment-author { + margin-right: 0; +} +#the-comment-list p.comment-author img { + float: right; + margin-right: 0; + margin-left: 8px; +} +.tablenav .delete { + margin-right: 0; + margin-left: 20px; +} +td.action-links, th.action-links { + text-align: left; +} +/* 2000 - 2300 +=================================== */ +.filter .subsubsub { + margin-left: 0; + margin-right: -10px; +} +#wp-word-count { + margin-right: 10px; +} +.tool-box .title { + font-family: Tahoma, Arial, sans-serif; +} +.settings-toggle { + text-align: left; + margin: 5px 0 15px 7px; +} +.curtime #timestamp { + background-position: right top; + padding-left: 0; + padding-right: 18px; +} +/* media popup 0819 */ +#sidemenu { + margin: -30px 315px 0 15px; + float: left; + padding-left: 0; + padding-right: 10px; +} +#sidemenu a { + float: right; +} +#replysubmit .button { + margin-right: 0; + margin-left: 5px; +} +/* 2300 - 2500 +=================================== */ +#edithead .inside { + float: right; + margin: 3px 5px 2px 0; +} +#replyrow #ed_reply_toolbar input { + margin: 1px 1px 1px 2px; +} +/* show/hide settings */ +#screen-meta-links { + margin: 0 0 0 18px; +} +#screen-options-link-wrap, +#contextual-help-link-wrap { + float: left; + font-family: Tahoma, Arial, sans-serif; + margin: 0 0 0 6px; +} +#contextual-help-wrap li { + margin-left: 0; + margin-right: 18px; +} +#screen-meta a.show-settings { + padding: 0 6px 0 16px; + background-position: left top; +} +.metabox-prefs label { + padding-right: 0; + padding-left: 15px; +} +.metabox-prefs label input { + margin: 0 2px 0 5px; +} +.inline-editor .save, +.inline-editor .cancel { + margin-right: 0; + margin-left: 5px; +} +#replysubmit img.waiting, +.inline-edit-save img.waiting { + float: left; +} +.trash-undo-inside, +.spam-undo-inside, +.spam-undo-inside .avatar, +.trash-undo-inside .avatar { + margin-right: 0; + margin-left: 8px; +} +/* 2500 - 2700 +=================================== */ +#bulk-titles div a { + float: right; + margin: 3px -2px 0 3px; +} +#wpbody-content .filename { + margin-left: 0; + margin-right: 10px; +} +#wpbody-content .inline-edit-row fieldset { + float: right; +} +#wpbody-content .quick-edit-row-page fieldset.inline-edit-col-right .inline-edit-col { + border-left: 0 none; + border-right: 1px solid; +} +#wpbody-content .bulk-edit-row .inline-edit-col-bottom { + float: left; +} +.inline-edit-row fieldset label span.title { + float: right; +} +.inline-edit-row fieldset label span.input-text-wrap { + margin-left: 0; + margin-right: 5em; +} +.quick-edit-row-post fieldset.inline-edit-col-right label span.title { + padding-right: 0; + padding-left: 0.5em; +} +#wpbody-content .quick-edit-row fieldset .inline-edit-group label.alignleft:first-child { + margin-right: 0; + margin-left: 0.5em; +} +/* 2700 - 3000 +=================================== */ +.inline-edit-row fieldset span.title, +.inline-edit-row fieldset span.checkbox-title { + font-family: Tahoma, Arial, sans-serif; +} +.inline-edit-row fieldset .inline-edit-date { + float: right; +} +.inline-edit-row fieldset ul.cat-checklist label, +.inline-edit-row .catshow, +.inline-edit-row .cathide, +.inline-edit-row #bulk-titles div { + font-family: Tahoma, Arial, sans-serif; +} +.quick-edit-row-post fieldset label.inline-edit-status { + float: right; +} +.describe-toggle-on, .describe-toggle-off { + float: left; + margin-right: 0; + margin-left: 20px; +} +#wpbody-content #media-items .filename { + float: right; + margin-left: 0; + margin-right: 10px; +} +.media-item .pinkynail { + float: right; +} +#find-posts-response .found-radio { + padding: 8px 8px 0 0; +} +.find-box-buttons { + left: auto; + right: 12px; +} +.find-box-search label { + padding-right: 0; + padding-left: 6px; +} +/* favorite-actions */ +#favorite-actions { + float: left; +} +#favorite-first { + padding: 3px 12px 4px 30px; +} +#favorite-inside { +} +#favorite-inside a { + padding: 3px 10px 3px 5px; +} +#favorite-toggle { + right: auto; + left: 0; + background:transparent url(../images/fav-arrow-rtl.gif?ver=20100531) no-repeat 10px -4px; +} +#utc-time, #local-time { + padding-left: 0; + padding-right: 25px; + font-family: Tahoma, Arial; +} +.icon32 { + float: right; + margin: 14px 0 0 6px; +} +.subtitle { + padding-left: 0; + padding-right: 25px; +} + +ol { + list-style-type:decimal; + margin-left:0; + margin-right:2em; +} + +.postbox-container { + float: right; + padding-left: 0.5%; + padding-right: 0; +} + +/* Media library */ +#wpbody-content .describe th { + text-align: right; +} + +.describe .media-item-info .A1B1 { + padding: 0 10px 0 0; +} + +.media-upload-form td label { + margin-left: 6px; + margin-right: 2px; +} + +.media-upload-form .align .field label { + padding: 0 22px 0 0; + margin: 0 0 0 1em; +} + +.media-upload-form tr.image-size label { + margin: 0 3px 0 0 ; +} + +#wpbody-content .describe p.help { + padding: 0 5px 0 0 ; +} + +.media-item .error-div a.dismiss, +.describe-toggle-on, +.describe-toggle-off { + float: left; + margin-right: 0; + margin-left: 20px; +} + +.describe-toggle-on, +.describe-toggle-off { + float: left; + margin-left: 20px; + margin-right: 0; +} + +.media-item .error-div { + padding-left: 0; + padding-right: 10px; +} + +.media-item .pinkynail { + float: right; +} + +.crunching { + text-align: left; + margin-left: 5px; + margin-right: 0; +} + +.bar { + border-left-width: 3px; + border-left-style: solid; + border-right: none; +} + + +/* TinyMCE +=================================== */ +.clearlooks2 .mceTop .mceLeft { + width:100% !important; +} + +/* tag hints */ +.taghint { + margin: 15px 12px -24px 0; +} + +#poststuff .tagsdiv .howto { + margin: 0 8px 6px 0; +} + +#broken-themes { + text-align: right; +} + +.describe .del-link { + padding-right: 5px; + padding-left: 0; +} + +.comment-ays th { + border-left-style: solid; + border-left-width: 1px; +} + +/* Custom Header */ +.appearance_page_custom-header #available-headers .default-header { + float: right; + margin: 0 0 20px 20px; +} +.appearance_page_custom-header #available-headers label input { + margin-right: 0; + margin-left: 10px; +} + +#custom-background label { + padding-right: 0; + padding-left: 15px; +} + +/* ltr +=================================== */ +#author-email, #author-url, #rss-url-1, #edit-slug-box, #post_name, #trackback_url, #metakeyinput, #post_password, #slug, #category_nicename, #link_url, #link_image, #rss_uri, #menu_order, #email, #newcomment_author_url, #pages-exclude, #template textarea, #user_login, #url, #pass1, #pass2, #aim, #yim, #jabber, #siteurl, #home, #admin_email, #gmt_offset, #default_post_edit_rows, #mailserver_url, #mailserver_login, #mailserver_pass, #mailserver_port, #ping_sites, #posts_per_page, #posts_per_rss, #blog_charset, #close_comments_days_old, #comments_per_page, #comment_max_links, #moderation_keys, #blacklist_keys, #thumbnail_size_w, #thumbnail_size_h, #medium_size_w, #medium_size_h, #large_size_w, #large_size_h, #permalink_structure, #category_base, #tag_base, #upload_path, #upload_url_path, #rules { + direction: ltr; +} + +/* no italic +=================================== */ + +#quicktags #ed_em, #ed_reply_toolbar #ed_reply_em, .tablenav .displaying-num, #footer, #footer a, p.help, p.description, span.description, .form-wrap p, #side-sortables .comments-box thead th, +#normal-sortables .comments-box thead th, .howto, .inline-edit-row fieldset span.title, .inline-edit-row fieldset span.checkbox-title, #utc-time, #local-time, form.upgrade .hint, p.install-help, .imgedit-help { + font-style: normal; +} diff --git a/src/wp-admin/css/wp-admin.css b/src/wp-admin/css/wp-admin.css new file mode 100644 index 00000000..731bfa3a --- /dev/null +++ b/src/wp-admin/css/wp-admin.css @@ -0,0 +1 @@ +p,ul,ol,blockquote,input,select{font-size:12px;}ol{list-style-type:decimal;margin-left:2em;}.code,code{font-family:Consolas,Monaco,Courier,monospace;}kbd,code{padding:1px 3px;margin:0 1px;font-size:11px;}.quicktags,.search{font:12px Georgia,"Times New Roman","Bitstream Charter",Times,serif;}.icon32{float:left;height:36px;margin:14px 6px 0 0;width:36px;}.key-labels label{line-height:24px;}.subtitle{font-size:.75em;line-height:1;padding-left:25px;}.pre{white-space:pre-wrap;white-space:-moz-pre-wrap!important;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;}.howto{font-style:italic;display:block;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;}p.install-help{margin:8px 0;font-style:italic;}textarea,input[type="text"],input[type="password"],input[type="file"],input[type="button"],input[type="submit"],input[type="reset"],select{border-width:1px;border-style:solid;-moz-border-radius:4px;-khtml-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;}select option{padding:2px;}.submit{padding:1.5em 0;margin:5px 0;-moz-border-radius:0 0 3px 3px;-webkit-border-bottom-left-radius:3px;-webkit-border-bottom-right-radius:3px;-khtml-border-bottom-left-radius:3px;-khtml-border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-bottom-right-radius:3px;}form p.submit a.cancel:hover{text-decoration:none;}.submit input,.button,input.button,.button-primary,input.button-primary,.button-secondary,input.button-secondary,.button-highlighted,input.button-highlighted,#postcustomstuff .submit input{text-decoration:none;font-size:11px!important;line-height:13px;padding:3px 8px;cursor:pointer;border-width:1px;border-style:solid;-moz-border-radius:11px;-khtml-border-radius:11px;-webkit-border-radius:11px;border-radius:11px;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;-khtml-box-sizing:content-box;box-sizing:content-box;}#minor-publishing-actions input,#major-publishing-actions input,#minor-publishing-actions .preview{min-width:80px;text-align:center;}textarea.all-options,input.all-options{width:250px;}input.large-text,textarea.large-text{width:99%;}input.regular-text,#adduser .form-field input{width:25em;}input.small-text{width:50px;}#doaction,#doaction2,#post-query-submit{margin-right:8px;}.tablenav select[name="action"],.tablenav select[name="action2"]{width:130px;}.tablenav select[name="m"]{width:155px;}.tablenav select#cat{width:170px;}#wpcontent select{padding:2px;height:2em;font-size:11px;}#wpcontent option{padding:2px;}#timezone_string option{margin-left:1em;}label,#your-profile label+a{vertical-align:middle;}#misc-publishing-actions label{vertical-align:baseline;}#pass-strength-result{border-style:solid;border-width:1px;float:left;margin:12px 5px 5px 1px;padding:3px 5px;text-align:center;width:200px;display:none;}.indicator-hint{padding-top:8px;}p.search-box{float:right;margin:-5px 0 0;}#major-publishing-actions{padding:6px;clear:both;border-top:none;}#delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left;}#publishing-action{text-align:right;float:right;line-height:23px;}#post-body #minor-publishing{padding-bottom:10px;}#post-body #misc-publishing-actions{padding:0;}#post-body .misc-pub-section{border-right-width:1px;border-right-style:solid;border-bottom:0 none;min-height:30px;float:left;max-width:32%;}#post-body .misc-pub-section-last{border-right:0;}#misc-publishing-actions{padding:6px 0 16px 0;}.misc-pub-section{padding:6px;border-bottom-width:1px;border-bottom-style:solid;}.misc-pub-section-last{border-bottom:0 none;}#minor-publishing-actions{padding:6px;text-align:right;}#minor-publishing{border-bottom-width:1px;border-bottom-style:solid;}#save-post{float:left;}#minor-publishing .ajax-loading{padding:3px 0 0 4px;float:left;}.preview{float:right;}#sticky-span{margin-left:18px;}#post-status-display,#post-visibility-display{font-weight:bold;}.side-info{margin:0;padding:4px;font-size:11px;}.side-info h5{padding-bottom:7px;font-size:14px;margin:12px 2px 5px;border-bottom-width:1px;border-bottom-style:solid;}.side-info ul{margin:0;padding-left:18px;list-style:square;}a.button,a.button-primary,a.button-secondary{line-height:15px;padding:3px 10px;white-space:nowrap;-webkit-border-radius:10px;}.approve{display:none;}.unapproved .approve,.spam .approve,.trash .approve{display:inline;}.unapproved .unapprove{display:none;}.add-new-h2{font-style:normal;margin:0 6px;position:relative;top:-3px;}td.action-links,th.action-links{text-align:right;}.describe .del-link{padding-left:5px;}#update-nag,.update-nag{line-height:19px;padding:5px 0;font-size:12px;text-align:center;margin:0 15px;border-width:1px;border-style:solid;border-top-width:0;border-top-style:none;-moz-border-radius:0 0 6px 6px;-webkit-border-bottom-right-radius:6px;-webkit-border-bottom-left-radius:6px;-khtml-border-bottom-right-radius:6px;-khtml-border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-bottom-left-radius:6px;}.plugins .plugin-update{padding:0;}.plugin-update .update-message{margin:0 10px 8px 31px;font-weight:bold;}ul#dismissed-updates{display:none;}form.upgrade{margin-top:8px;}form.upgrade .hint{font-style:italic;font-size:85%;margin:-0.5em 0 2em 0;}.ajax-feedback{visibility:hidden;vertical-align:bottom;}#ajax-response.alignleft{margin-left:2em;}#editorcontainer #content{padding:6px;line-height:150%;border:0 none;outline:none;resize:vertical;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-khtml-box-sizing:border-box;box-sizing:border-box;}#editorcontainer,#quicktags{border-style:solid;border-width:1px;border-collapse:separate;-moz-border-radius:6px 6px 0 0;-webkit-border-top-right-radius:6px;-webkit-border-top-left-radius:6px;-khtml-border-top-right-radius:6px;-khtml-border-top-left-radius:6px;border-top-right-radius:6px;border-top-left-radius:6px;}#quicktags{padding:0;margin-bottom:-3px;border-bottom-width:3px;background-image:url("../images/ed-bg.gif");background-position:left top;background-repeat:repeat-x;}#quicktags #ed_toolbar{padding:2px 4px 0;}#ed_toolbar input,#ed_reply_toolbar input{margin:3px 1px 4px;line-height:18px;display:inline-block;min-width:26px;padding:2px 4px;font-size:12px;}#ed_reply_toolbar input{margin:1px 2px 1px 1px;}#quicktags #ed_link,#ed_reply_toolbar #ed_reply_link{text-decoration:underline;}#quicktags #ed_del,#ed_reply_toolbar #ed_reply_del{text-decoration:line-through;}#quicktags #ed_em,#ed_reply_toolbar #ed_reply_em{font-style:italic;}#wp_editbtns,#wp_gallerybtns{padding:2px;position:absolute;display:none;z-index:999998;}#wp_editimgbtn,#wp_delimgbtn,#wp_editgallery,#wp_delgallery{margin:2px;padding:2px;border-width:1px;border-style:solid;-moz-border-radius:3px;-khtml-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}#wphead-info{margin:0 0 0 15px;padding-right:15px;}#user_info{float:right;font-size:12px;line-height:46px;height:46px;}#user_info p{margin:0;padding:0;line-height:46px;}#wphead{height:46px;}#wphead a,#adminmenu a,#sidemenu a,#taglist a,#catlist a,#show-settings a{text-decoration:none;}#header-logo{float:left;margin:7px 0 0 15px;}#wphead h1{font:normal 22px Georgia,"Times New Roman","Bitstream Charter",Times,serif;padding:10px 8px 5px;margin:0;float:left;}#wphead h1.long-title{font:normal 18px Georgia,"Times New Roman","Bitstream Charter",Times,serif;padding:12px 10px 5px;}#wphead #privacy-on-link{font-size:50%;font-style:normal;line-height:17px;padding:0 6px;vertical-align:middle;}#wphead h1 a:hover{text-decoration:none;}#wphead h1 a:hover #site-title,#wphead h1 a#privacy-on-link:hover{text-decoration:underline;}#favorite-actions{float:right;margin:11px 12px 0;min-width:130px;position:relative;}#favorite-first{-moz-border-radius:12px;-khtml-border-radius:12px;-webkit-border-radius:12px;border-radius:12px;line-height:15px;padding:3px 30px 4px 12px;border-width:1px;border-style:solid;}#favorite-inside{margin:0;padding:2px 1px;border-width:1px;border-style:solid;position:absolute;z-index:11;display:none;-moz-border-radius:0 0 12px 12px;-webkit-border-bottom-right-radius:12px;-webkit-border-bottom-left-radius:12px;-khtml-border-bottom-right-radius:12px;-khtml-border-bottom-left-radius:12px;border-bottom-right-radius:12px;border-bottom-left-radius:12px;}#favorite-actions a{display:block;text-decoration:none;font-size:11px;}#favorite-inside a{padding:3px 5px 3px 10px;}#favorite-toggle{height:22px;position:absolute;right:0;top:1px;width:28px;}#favorite-actions .slide-down{-moz-border-radius:12px 12px 0 0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-khtml-border-bottom-right-radius:0;-khtml-border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-bottom:none;}#screen-meta{position:relative;clear:both;}#screen-meta-links{margin:0 18px 0 0;}#screen-meta .screen-reader-text{visibility:hidden;}#screen-options-link-wrap,#contextual-help-link-wrap{float:right;height:22px;padding:0;margin:0 6px 0 0;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;background:#e3e3e3;-moz-border-radius-bottomleft:3px;-moz-border-radius-bottomright:3px;-webkit-border-bottom-left-radius:3px;-webkit-border-bottom-right-radius:3px;}#contextual-help-wrap li{list-style-type:disc;margin-left:18px;}.toggle-arrow{background-repeat:no-repeat;background-position:top left;background-color:transparent;height:22px;line-height:22px;display:block;}.toggle-arrow-active{background-position:bottom left;}#screen-meta a.show-settings{text-decoration:none;z-index:1;padding:0 16px 0 6px;height:22px;line-height:22px;font-size:10px;display:block;background-repeat:no-repeat;background-position:top right;background-color:transparent;text-shadow:rgba(255,255,255,0.7) 0 1px 0;}#screen-meta a.show-settings:hover{text-decoration:none;}#screen-options-wrap h5,#contextual-help-wrap h5{margin:8px 0;font-size:13px;}#screen-options-wrap,#contextual-help-wrap{border-style:none solid solid;border-top:0 none;border-width:0 1px 1px;margin:0 15px;padding:8px 12px 12px;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;-khtml-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.metabox-prefs label{display:inline-block;padding-right:15px;white-space:nowrap;line-height:30px;}.metabox-prefs label input{margin:0 5px 0 2px;}.metabox-prefs label a{display:none;}#adminmenu *{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;user-select:none;}#adminmenu .wp-submenu{display:none;list-style:none;padding:0;margin:0;position:relative;z-index:2;border-width:1px 0 0;border-style:solid none none;}#adminmenu .wp-submenu a{font:normal 11px/18px "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;}#adminmenu .wp-submenu li.current,#adminmenu .wp-submenu li.current a,#adminmenu .wp-submenu li.current a:hover{font-weight:bold;}#adminmenu a.menu-top,#adminmenu .wp-submenu-head{font:normal 13px/18px Georgia,"Times New Roman","Bitstream Charter",Times,serif;}#adminmenu div.wp-submenu-head{display:none;}.folded #adminmenu div.wp-submenu-head,.folded #adminmenu li.wp-has-submenu div.sub-open{display:block;}.folded #adminmenu a.menu-top,.folded #adminmenu .wp-submenu,.folded #adminmenu li.wp-menu-open .wp-submenu,.folded #adminmenu div.wp-menu-toggle{display:none;}#adminmenu li.wp-menu-open .wp-submenu,.no-js #adminmenu .open-if-no-js .wp-submenu{display:block;}#adminmenu div.wp-menu-image{float:left;width:28px;height:28px;}#adminmenu li{margin:0;padding:0;cursor:pointer;}#adminmenu a{display:block;line-height:18px;padding:1px 5px 3px;}#adminmenu li.menu-top{min-height:26px;}#adminmenu a.menu-top{line-height:18px;min-width:10em;padding:5px 5px;border-width:1px 1px 0;border-style:solid solid none;}#adminmenu .wp-submenu a{margin:0;padding-left:12px;border-width:0 1px 0 0;border-style:none solid none none;}#adminmenu .menu-top-last ul.wp-submenu{border-width:0 0 1px;border-style:none none solid;}#adminmenu .wp-submenu li{padding:0;margin:0;}.folded #adminmenu li.menu-top{width:28px;height:30px;overflow:hidden;border-width:1px 1px 0;border-style:solid solid none;}#adminmenu .menu-top-first a.menu-top,.folded #adminmenu li.menu-top-first,#adminmenu .wp-submenu .wp-submenu-head{border-width:1px 1px 0;border-style:solid solid none;-moz-border-radius-topleft:6px;-moz-border-radius-topright:6px;-webkit-border-top-right-radius:6px;-webkit-border-top-left-radius:6px;-khtml-border-top-right-radius:6px;-khtml-border-top-left-radius:6px;border-top-right-radius:6px;border-top-left-radius:6px;}#adminmenu .menu-top-last a.menu-top,.folded #adminmenu li.menu-top-last{border-width:1px;border-style:solid;-moz-border-radius-bottomleft:6px;-moz-border-radius-bottomright:6px;-webkit-border-bottom-right-radius:6px;-webkit-border-bottom-left-radius:6px;-khtml-border-bottom-right-radius:6px;-khtml-border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-bottom-left-radius:6px;}#adminmenu li.wp-menu-open a.menu-top-last{border-bottom:0 none;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-khtml-border-bottom-right-radius:0;-khtml-border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;}#adminmenu .wp-menu-image img{float:left;padding:8px 6px 0;opacity:.6;filter:alpha(opacity=60);}#adminmenu li.menu-top:hover .wp-menu-image img,#adminmenu li.wp-has-current-submenu .wp-menu-image img{opacity:1;filter:alpha(opacity=100);}#adminmenu li.wp-menu-separator{height:21px;padding:0;margin:0;}#adminmenu a.separator{cursor:w-resize;height:20px;padding:0;}.folded #adminmenu a.separator{cursor:e-resize;}#adminmenu .wp-menu-separator-last{height:10px;width:1px;}#adminmenu .wp-submenu .wp-submenu-head{border-width:1px;border-style:solid;padding:6px 4px 6px 10px;cursor:default;}.folded #adminmenu .wp-submenu{position:absolute;margin:-1px 0 0 28px;padding:0 8px 8px;z-index:999;border:0 none;}.folded #adminmenu .wp-submenu ul{width:140px;border-width:0 0 1px;border-style:none none solid;}.folded #adminmenu .wp-submenu li.wp-first-item{border-top:0 none;}.folded #adminmenu .wp-submenu a{padding-left:10px;}.folded #adminmenu a.wp-has-submenu{margin-left:40px;}#adminmenu li.menu-top-last .wp-submenu ul{border-width:0 0 1px;border-style:none none solid;}#adminmenu .wp-menu-toggle{width:22px;clear:right;float:right;margin:1px 0 0;height:27px;padding:1px 2px 0 0;cursor:default;}#adminmenu li.wp-has-current-submenu ul{border-bottom-width:1px;border-bottom-style:solid;}#adminmenu .wp-menu-image a{height:24px;}#adminmenu .wp-menu-image img{padding:6px 0 0 1px;}#adminmenu #awaiting-mod,#adminmenu span.update-plugins,#sidemenu li a span.update-plugins{position:absolute;font-family:Helvetica,Arial,sans-serif;font-size:9px;line-height:17px;font-weight:bold;margin-top:1px;margin-left:7px;-moz-border-radius:10px;-khtml-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;}#adminmenu li #awaiting-mod span,#adminmenu li span.update-plugins span,#sidemenu li a span.update-plugins span{display:block;padding:0 6px;}#adminmenu li span.count-0,#sidemenu li a .count-0{display:none;}.post-com-count-wrapper{min-width:22px;font-family:Helvetica,Arial,sans-serif;}.post-com-count{height:1.3em;line-height:1.1em;display:block;text-decoration:none;padding:0 0 6px;cursor:pointer;background-position:center -80px;background-repeat:no-repeat;}.post-com-count span{font-size:9px;font-weight:bold;height:1.7em;line-height:1.70em;min-width:.7em;padding:0 6px;display:inline-block;cursor:pointer;-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}strong .post-com-count{background-position:center -55px;}.post-com-count:hover{background-position:center -3px;}.column-response .post-com-count{float:left;margin-right:5px;text-align:center;}.response-links{float:left;}#the-comment-list .attachment-80x60{padding:4px 8px;}body.wp-admin{min-width:785px;}body.admin-bar #wphead{padding-top:28px;}.narrow{width:70%;margin-bottom:40px;}.narrow p{line-height:150%;}.widefat th,.widefat td{overflow:hidden;}.widefat td p{margin:2px 0 .8em;}.widefat .column-comment p{margin:.6em 0;}.widget .widget-top,.postbox h3{cursor:move;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;user-select:none;}.postbox-container{float:left;padding-right:.5%;}.postbox-container .meta-box-sortables{min-height:300px;}.postbox .hndle span{padding:6px 0;}.postbox .hndle{cursor:move;}.hndle a{font-size:11px;font-weight:normal;}.postbox .handlediv{float:right;width:23px;height:26px;}.sortable-placeholder{border-width:1px;border-style:dashed;margin-bottom:20px;}.widget,.postbox,.stuffbox{margin-bottom:20px;border-width:1px;border-style:solid;line-height:1;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.widget .widget-top,.postbox h3,.postbox h3,.stuffbox h3{-moz-border-radius:6px 6px 0 0;-webkit-border-top-right-radius:6px;-webkit-border-top-left-radius:6px;-khtml-border-top-right-radius:6px;-khtml-border-top-left-radius:6px;border-top-right-radius:6px;border-top-left-radius:6px;}.postbox.closed h3{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px;}.postbox table.form-table{margin-bottom:0;}.postbox input[type="text"],.postbox textarea,.stuffbox input[type="text"],.stuffbox textarea{border-width:1px;border-style:solid;}.temp-border{border:1px dotted #ccc;}.columns-prefs label{padding:0 5px;}#wpbody-content .metabox-holder{padding-top:10px;}#dashboard-widgets .meta-box-sortables{margin:0 5px;}#dashboard_recent_comments div.undo{border-top-style:solid;border-top-width:1px;margin:0 -10px;padding:3px 8px;font-size:11px;}#the-comment-list td.comment p.comment-author{margin-top:0;margin-left:0;}#the-comment-list p.comment-author img{float:left;margin-right:8px;}#the-comment-list p.comment-author strong a{border:none;}#the-comment-list td{vertical-align:top;}#the-comment-list td.comment{word-wrap:break-word;}#the-comment-list .check-column{padding-top:8px;}table.fixed{table-layout:fixed;}.fixed .column-rating,.fixed .column-visible{width:8%;}.fixed .column-date,.fixed .column-parent,.fixed .column-links{width:10%;}.fixed .column-response,.fixed .column-author,.fixed .column-categories,.fixed .column-tags,.fixed .column-rel,.fixed .column-role{width:15%;}.fixed .column-comments{width:4em;padding:8px 0;text-align:left;}.fixed .column-comments .vers{padding-left:3px;}.fixed .column-comments a{float:left;}.fixed .column-slug{width:25%;}.fixed .column-posts{width:10%;}.fixed .column-icon{width:80px;}#commentsdiv .fixed .column-author,#comments-form .fixed .column-author{width:20%;}#commentsdiv.postbox .inside{line-height:1.4em;margin:0;}#commentsdiv.postbox .inside .row-actions{line-height:18px;}#commentsdiv.postbox .inside td{padding:1em 10px;}#commentsdiv.postbox .inside .column-author{width:33%;}#commentsdiv.postbox .inside p{margin:6px 10px 8px;}#commentsdiv.postbox .column-comment p{margin:.6em 0;}#commentsdiv.postbox #replyrow td{padding:0;}.sorting-indicator{display:none;width:7px;height:4px;margin-top:5px;margin-left:7px;background-image:url(../images/sort.gif);background-repeat:no-repeat;}.fixed .column-comments .sorting-indicator{margin-top:3px;}.widefat th.sortable,.widefat th.sorted{padding:0;}th.sortable a,th.sorted a{display:block;overflow:hidden;padding:7px 7px 8px;}.fixed .column-comments.sortable a,.fixed .column-comments.sorted a{padding:8px 0;}th.sortable a span,th.sorted a span{float:left;cursor:pointer;}th.sorted.asc .sorting-indicator,th.desc:hover span.sorting-indicator{display:block;background-position:0 0;}th.sorted.desc .sorting-indicator,th.asc:hover span.sorting-indicator{display:block;background-position:-7px 0;}.tablenav-pages a{border-bottom-style:solid;border-bottom-width:2px;font-weight:bold;margin-right:1px;padding:0 2px;}.tablenav-pages .current-page{text-align:center;}.tablenav-pages .next-page{margin-left:2px;}.tablenav a.button-secondary{display:block;margin:3px 8px 0 0;}.tablenav{clear:both;height:30px;margin:6px 0 4px;vertical-align:middle;}.tablenav .tablenav-pages{float:right;display:block;cursor:default;height:30px;line-height:30px;font-size:11px;}.tablenav .one-page{display:none;}.tablenav .tablenav-pages a,.tablenav-pages span.current{text-decoration:none;border:none;padding:3px 6px;border-width:1px;border-style:solid;-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}.tablenav .tablenav-pages a.disabled:hover{cursor:default;}.tablenav .tablenav-pages a.disabled:active{cursor:default;}.tablenav .displaying-num{margin-right:10px;font-size:12px;font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-style:italic;}.tablenav .actions{padding:2px 8px 0 0;}.tablenav .delete{margin-right:20px;}.view-switch{float:right;margin:6px 8px 0;}.view-switch a{text-decoration:none;}.filter{float:left;margin:-5px 0 0 10px;}.filter .subsubsub{margin-left:-10px;margin-top:13px;}.screen-per-page{width:3em;}#posts-filter fieldset{float:left;margin:0 1.5ex 1em 0;padding:0;}#posts-filter fieldset legend{padding:0 0 .2em 1px;}span.post-state-format{font-weight:normal;}tr.inline-edit-row td{padding:0 .5em;}#wpbody-content .inline-edit-row fieldset{font-size:12px;float:left;margin:0;padding:0;width:100%;}#wpbody-content .inline-edit-row fieldset .inline-edit-col{padding:0 .5em;}#wpbody-content .quick-edit-row-page fieldset.inline-edit-col-right .inline-edit-col{border-width:0 0 0 1px;border-style:none none none solid;}#wpbody-content .quick-edit-row-post .inline-edit-col-left{width:40%;}#wpbody-content .quick-edit-row-post .inline-edit-col-right{width:39%;}#wpbody-content .inline-edit-row-post .inline-edit-col-center{width:20%;}#wpbody-content .quick-edit-row-page .inline-edit-col-left{width:50%;}#wpbody-content .quick-edit-row-page .inline-edit-col-right,#wpbody-content .bulk-edit-row-post .inline-edit-col-right{width:49%;}#wpbody-content .bulk-edit-row .inline-edit-col-left{width:30%;}#wpbody-content .bulk-edit-row-page .inline-edit-col-right{width:69%;}#wpbody-content .bulk-edit-row .inline-edit-col-bottom{float:right;width:69%;}#wpbody-content .inline-edit-row-page .inline-edit-col-right,#wpbody-content .bulk-edit-row-post .inline-edit-col-right{margin-top:27px;}.inline-edit-row fieldset .inline-edit-group{clear:both;}.inline-edit-row fieldset .inline-edit-group:after{content:".";display:block;height:0;clear:both;visibility:hidden;}.inline-edit-row p.submit{clear:both;padding:.5em;margin:.5em 0 0;}.inline-edit-row span.error{line-height:22px;margin:0 15px;padding:3px 5px;}.inline-edit-row h4{margin:.2em 0;padding:0;line-height:23px;}.inline-edit-row fieldset span.title,.inline-edit-row fieldset span.checkbox-title{margin:0;padding:0;line-height:27px;}.inline-edit-row fieldset label,.inline-edit-row fieldset span.inline-edit-categories-label{display:block;margin:.2em 0;}.inline-edit-row fieldset label.inline-edit-tags{margin-top:0;}.inline-edit-row fieldset label.inline-edit-tags span.title{margin:.2em 0;}.inline-edit-row fieldset label span.title{display:block;float:left;width:5em;}.inline-edit-row fieldset label span.input-text-wrap{display:block;margin-left:5em;}.quick-edit-row-post fieldset.inline-edit-col-right label span.title{width:auto;padding-right:.5em;}.inline-edit-row .input-text-wrap input[type=text]{width:100%;}.inline-edit-row fieldset label input[type=checkbox]{vertical-align:text-bottom;}.inline-edit-row fieldset label textarea{width:100%;height:4em;}#wpbody-content .bulk-edit-row fieldset .inline-edit-group label{max-width:50%;}#wpbody-content .quick-edit-row fieldset .inline-edit-group label.alignleft:first-child{margin-right:.5em;}.inline-edit-row h4{text-transform:uppercase;}.inline-edit-row fieldset span.title,.inline-edit-row fieldset span.checkbox-title{font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-style:italic;line-height:1.8em;}.inline-edit-row fieldset input[type="text"],.inline-edit-row fieldset textarea{border-style:solid;border-width:1px;}.inline-edit-row fieldset .inline-edit-date{float:left;}.inline-edit-row fieldset input[name=jj],.inline-edit-row fieldset input[name=hh],.inline-edit-row fieldset input[name=mn]{font-size:12px;width:2.1em;}.inline-edit-row fieldset input[name=aa]{font-size:12px;width:3.5em;}.inline-edit-row fieldset label input.inline-edit-password-input{width:8em;}.inline-edit-row .catshow,.inline-edit-row .cathide{cursor:pointer;}ul.cat-checklist{height:12em;border-style:solid;border-width:1px;overflow-y:scroll;padding:0 5px;margin:0;}#bulk-titles{display:block;height:12em;border-style:solid;border-width:1px;overflow-y:scroll;padding:0 5px;margin:0 0 5px;}.inline-edit-row fieldset ul.cat-checklist li,.inline-edit-row fieldset ul.cat-checklist input{margin:0;}.inline-edit-row fieldset ul.cat-checklist label,.inline-edit-row .catshow,.inline-edit-row .cathide,.inline-edit-row #bulk-titles div{font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;font-style:normal;font-size:11px;}table .inline-edit-row fieldset ul.cat-hover{height:auto;max-height:30em;overflow-y:auto;position:absolute;}.inline-edit-row fieldset label input.inline-edit-menu-order-input{width:3em;}.inline-edit-row fieldset label input.inline-edit-slug-input{width:75%;}.quick-edit-row-post fieldset label.inline-edit-status{float:left;}#bulk-titles{line-height:140%;}#bulk-titles div{margin:.2em .3em;}#bulk-titles div a{cursor:pointer;display:block;float:left;height:10px;margin:3px 3px 0 -2px;overflow:hidden;position:relative;text-indent:-9999px;width:10px;}#titlediv{position:relative;margin-bottom:20px;}#titlediv label{cursor:text;}#titlediv div.inside{margin:0;}#poststuff #titlewrap{border:0;padding:0;}#titlediv #title{padding:3px 4px;border-width:1px;border-style:solid;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;font-size:1.7em;line-height:100%;width:100%;outline:none;}#titlediv #title-prompt-text{color:#bbb;position:absolute;font-size:1.7em;padding:8px;}#poststuff .inside-submitbox,#side-sortables .inside-submitbox{margin:0 3px;font-size:11px;}input#link_description,input#link_url{width:98%;}#pending{background:0 none;border:0 none;padding:0;font-size:11px;margin-top:-1px;}#edit-slug-box{height:1em;margin-top:8px;padding:0 7px;}#editable-post-name-full{display:none;}#editable-post-name input{width:16em;}.postarea h3 label{float:left;}.postarea #add-media-button{float:right;margin:7px 0 0;position:relative;right:10px;}#poststuff #editor-toolbar{height:30px;}.wp_themeSkin tr.mceFirst td.mceToolbar{border-width:0 0 1px;border-style:none none solid;}#edButtonPreview,#edButtonHTML{height:18px;margin:5px 5px 0 0;padding:4px 5px 2px;float:right;cursor:pointer;border-width:1px;border-style:solid;-moz-border-radius:3px 3px 0 0;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;-khtml-border-top-right-radius:3px;-khtml-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;}.js .theEditor{color:white;}#poststuff #edButtonHTML{margin-right:15px;}#media-buttons{cursor:default;padding:8px 8px 0;}#media-buttons a{cursor:pointer;padding:0 0 5px 10px;}#media-buttons img,#submitpost #ajax-loading,#submitpost .ajax-loading{vertical-align:middle;}#wpcontent .ajax-loading{visibility:hidden;}.submitbox .submit{text-align:left;padding:12px 10px 10px;font-size:11px;}.submitbox .submitdelete{border-bottom-width:1px;border-bottom-style:solid;text-decoration:none;padding:1px 2px;}.inside-submitbox #post_status{margin:2px 0 2px -2px;}.submitbox .submit a:hover{border-bottom-width:1px;border-bottom-style:solid;}.submitbox .submit input{margin-bottom:8px;margin-right:4px;padding:6px;}#post-status-select,#post-format{line-height:2.5em;margin-top:3px;}#post-body #normal-sortables{min-height:50px;}#post-body #advanced-sortables{min-height:20px;}.postbox{position:relative;min-width:255px;width:99.5%;}#trackback_url{width:99%;}#normal-sortables .postbox .submit{background:transparent none;border:0 none;float:right;padding:0 12px;margin:0;}#side-sortables .category-add input{width:94%;}#side-sortables .category-add select{width:100%;}#side-sortables .category-add input.category-add-sumbit,#post-body .category-add input.category-add input.category-add-sumbit{width:auto;}#post-body ul.category-tabs,#post-body ul.add-menu-item-tabs{float:left;width:120px;text-align:right;margin:0 -120px 0 5px;padding:0;}#post-body ul.category-tabs li,#post-body ul.add-menu-item-tabs li{padding:8px;}#post-body ul.category-tabs li.tabs,#post-body ul.add-menu-item-tabs li.tabs{-moz-border-radius:3px 0 0 3px;-webkit-border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-khtml-border-top-left-radius:3px;-khtml-border-bottom-left-radius:3px;border-top-left-radius:3px;border-bottom-left-radius:3px;}#post-body ul.category-tabs li.tabs a,#post-body ul.add-menu-item-tabs li.tabs a{font-weight:bold;text-decoration:none;}.wp-tab-panel,.categorydiv div.tabs-panel,.customlinkdiv div.tabs-panel,.posttypediv div.tabs-panel,.taxonomydiv div.tabs-panel,#linkcategorydiv div.tabs-panel{height:200px;overflow:auto;padding:.5em .9em;border-style:solid;border-width:1px;}.nav-menus-php .customlinkdiv div.tabs-panel,.nav-menus-php .posttypediv div.tabs-panel,.nav-menus-php .taxonomydiv div.tabs-panel{height:auto;max-height:205px;}div.tabs-panel-active{display:block;}div.tabs-panel-inactive{display:none;}#post-body .categorydiv div.tabs-panel,.taxonomy div.tabs-panel,#post-body #linkcategorydiv div.tabs-panel{margin:0 5px 0 125px;}#side-sortables .category-tabs li,#side-sortables .add-menu-item-tabs li,.wp-tab-bar li{display:inline;}#side-sortables .category-tabs a,#side-sortables .add-menu-item-tabs a,.wp-tab-bar a{text-decoration:none;}#side-sortables .category-tabs,#side-sortables .add-menu-item-tabs,.wp-tab-bar{margin-bottom:3px;}.categorydiv ul,.customlinkdiv ul,.posttypediv ul,.taxonomydiv ul,#linkcategorydiv ul{list-style:none;padding:0;margin:0;}#normal-sortables .postbox #replyrow .submit{float:none;margin:0;padding:3px 7px;}#side-sortables .submitbox .submit input,#side-sortables .submitbox .submit .preview,#side-sortables .submitbox .submit a.preview:hover{border:0 none;}#side-sortables .inside-submitbox .insidebox,.stuffbox .insidebox{margin:11px 0;}#side-sortables .comments-box,#normal-sortables .comments-box{border:0 none;}ul.category-tabs,ul.add-menu-item-tabs,ul.wp-tab-bar{margin-top:12px;}#side-sortables .comments-box thead th,#normal-sortables .comments-box thead th{background:transparent;padding:0 7px 4px;font-style:italic;}ul.category-tabs li.tabs,ul.add-menu-item-tabs li.tabs,.wp-tab-active{border-style:solid solid none;border-width:1px 1px 0;}#commentsdiv img.waiting{padding-left:5px;}#post-body .category-tabs li.tabs,#post-body .add-menu-item-tabs li.tabs{border-style:solid none solid solid;border-width:1px 0 1px 1px;margin-right:-1px;}ul.category-tabs li,ul.add-menu-item-tabs li,ul.wp-tab-bar li{padding:5px;-moz-border-radius:3px 3px 0 0;-webkit-border-top-left-radius:3px;-webkit-border-top-right-radius:3px;-khtml-border-top-left-radius:3px;-khtml-border-top-right-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px;}form#tags-filter{position:relative;}p.search-box{float:right;margin:-5px 0 0;}.screen-per-page{width:3em;}#posts-filter fieldset{float:left;margin:0 1.5ex 1em 0;padding:0;}#posts-filter fieldset legend{padding:0 0 .2em 1px;}td.post-title strong,td.plugin-title strong{display:block;margin-bottom:.2em;}td.post-title p,td.plugin-title p{margin:6px 0;}.wp-hidden-children .wp-hidden-child,.ui-tabs-hide{display:none;}.commentlist .avatar{vertical-align:text-top;}#post-body .tagsdiv #newtag{margin-right:5px;width:16em;}#side-sortables input#post_password{width:94%;}#side-sortables .tagsdiv #newtag{width:68%;}#post-status-info{border-width:0 1px 1px;border-style:none solid solid;width:100%;-moz-border-radius:0 0 6px 6px;-webkit-border-bottom-left-radius:6px;-webkit-border-bottom-right-radius:6px;-khtml-border-bottom-left-radius:6px;-khtml-border-bottom-right-radius:6px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;}#post-status-info td{font-size:11px;}.autosave-info{padding:2px 15px 2px 2px;text-align:right;}#editorcontent #post-status-info{border:none;}#post-body .wp_themeSkin .mceStatusbar a.mceResize{display:block;background:transparent url(../images/resize.gif) no-repeat scroll right bottom;width:12px;cursor:se-resize;margin:0 2px;position:relative;top:22px;}#wp-word-count{display:block;padding:2px 7px;}#timestampdiv select{height:20px;line-height:14px;padding:0;vertical-align:top;}#jj,#hh,#mn{width:2em;padding:1px;font-size:12px;}#aa{width:3.4em;padding:1px;font-size:12px;}.curtime #timestamp{background-repeat:no-repeat;background-position:left top;padding-left:18px;}#timestampdiv{padding-top:5px;line-height:23px;}#timestampdiv p{margin:8px 0 6px;}#timestampdiv input{border-width:1px;border-style:solid;}#postcustomstuff table,#postcustomstuff input,#postcustomstuff textarea{border-width:1px;border-style:solid;-moz-border-radius:3px;-khtml-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}#postcustomstuff .updatemeta,#postcustomstuff .deletemeta{margin:auto;}#postcustomstuff thead th{padding:5px 8px 8px;}#postcustom #postcustomstuff .submit{border:0 none;float:none;padding:5px 8px;}#side-sortables #postcustom #postcustomstuff .submit{padding:0 5px;}#side-sortables #postcustom #postcustomstuff td.left input{margin:3px 3px 0;}#side-sortables #postcustom #postcustomstuff #the-list textarea{height:85px;margin:3px;}#postcustomstuff table{margin:0;width:100%;border-width:1px;border-style:solid;border-spacing:0;}#postcustomstuff table input,#postcustomstuff table select,#postcustomstuff table textarea{width:95%;margin:8px 0 8px 8px;}#postcustomstuff th.left,#postcustomstuff td.left{width:38%;}#postcustomstuff .submit input{width:auto;}#postcustomstuff #newmeta .submit{padding:0 8px;}#postcustomstuff table #addmetasub{width:auto;}#postcustomstuff #newmetaleft{vertical-align:top;}#postcustomstuff #newmetaleft a{padding:0 10px;text-decoration:none;}table.diff{width:100%;}table.diff col.content{width:50%;}table.diff tr{background-color:transparent;}table.diff td,table.diff th{padding:.5em;font-family:Consolas,Monaco,Courier,monospace;border:none;}table.diff .diff-deletedline del,table.diff .diff-addedline ins{text-decoration:none;}.category-adder{margin-left:120px;padding:4px 0;}.category-adder h4{margin:0 0 8px;}#side-sortables .category-adder{margin:0;}#post-body .category-add input,.category-add select{width:30%;}#side-sortables .category-add select{width:100%;}#side-sortables .category-add input.category-add-sumbit,#post-body .category-add input.category-add input.category-add-sumbit{width:auto;}#post-body ul.category-tabs,#post-body ul.add-menu-item-tabs{float:left;width:120px;text-align:right;margin:0 -120px 0 5px;padding:0;}#post-body ul.category-tabs li,#post-body ul.add-menu-item-tabs li{padding:8px;}#post-body ul.category-tabs li.tabs,#post-body ul.add-menu-item-tabs li.tabs{-moz-border-radius:3px 0 0 3px;-webkit-border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-khtml-border-top-left-radius:3px;-khtml-border-bottom-left-radius:3px;border-top-left-radius:3px;border-bottom-left-radius:3px;}#post-body ul.category-tabs li.tabs a,#post-body ul.add-menu-item-tabs li.tabs a{font-weight:bold;text-decoration:none;}.categorydiv div.tabs-panel,.customlinkdiv div.tabs-panel,.posttypediv div.tabs-panel,.taxonomydiv div.tabs-panel,#linkcategorydiv div.tabs-panel{height:200px;overflow:auto;padding:.5em .9em;border-style:solid;border-width:1px;}.nav-menus-php .customlinkdiv div.tabs-panel,.nav-menus-php .posttypediv div.tabs-panel,.nav-menus-php .taxonomydiv div.tabs-panel{height:auto;max-height:205px;}div.tabs-panel-active{display:block;}div.tabs-panel-inactive{display:none;}#post-body .categorydiv div.tabs-panel,.taxonomy div.tabs-panel,#post-body #linkcategorydiv div.tabs-panel{margin:0 5px 0 125px;}#side-sortables .category-tabs li,#side-sortables .add-menu-item-tabs li{display:inline;}#side-sortables .category-tabs a,#side-sortables .add-menu-item-tabs a{text-decoration:none;}#side-sortables .category-tabs,#side-sortables .add-menu-item-tabs{margin-bottom:3px;}.categorydiv ul,.customlinkdiv ul,.posttypediv ul,.taxonomydiv ul,#linkcategorydiv ul{list-style:none;padding:0;margin:0;}#front-page-warning,#front-static-pages ul,ul.export-filters,.inline-editor ul.cat-checklist ul,.categorydiv ul.categorychecklist ul,.customlinkdiv ul.categorychecklist ul,.posttypediv ul.categorychecklist ul,.taxonomydiv ul.categorychecklist ul,#linkcategorydiv ul.categorychecklist ul{margin-left:18px;}ul.categorychecklist li{margin:0;padding:0;line-height:19px;word-wrap:break-word;}.categorydiv .tabs-panel,.customlinkdiv .tabs-panel,.posttypediv .tabs-panel,.taxonomydiv .tabs-panel{border-width:3px;border-style:solid;}ul.category-tabs,ul.add-menu-item-tabs{margin-top:12px;}ul.category-tabs li.tabs,ul.add-menu-item-tabs li.tabs{border-style:solid solid none;border-width:1px 1px 0;}#post-body .category-tabs li.tabs,#post-body .add-menu-item-tabs li.tabs{border-style:solid none solid solid;border-width:1px 0 1px 1px;margin-right:-1px;}ul.category-tabs li,ul.add-menu-item-tabs li{padding:5px;-moz-border-radius:3px 3px 0 0;-webkit-border-top-left-radius:3px;-webkit-border-top-right-radius:3px;-khtml-border-top-left-radius:3px;-khtml-border-top-right-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px;}.form-wrap{margin:10px 0;width:97%;}.form-wrap p,.form-wrap label{font-size:11px;}.form-wrap label{display:block;padding:2px;font-size:12px;}.form-field input,.form-field textarea{border-style:solid;border-width:1px;width:95%;}p.description,.form-wrap p{margin:2px 0 5px;}p.help,p.description,span.description,.form-wrap p{font-size:12px;font-style:italic;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;}.form-wrap .form-field{margin:0 0 10px;padding:8px;}.col-wrap h3{margin:12px 0;font-size:1.1em;}.col-wrap p.submit{margin-top:-10px;}.taghint{color:#aaa;margin:15px 0 -24px 12px;}#poststuff .tagsdiv .howto{margin:0 0 6px 8px;}.ajaxtag .newtag{background:transparent;position:relative;}.tagsdiv .newtag{width:180px;}.tagsdiv .the-tags{display:block;height:60px;margin:0 auto;overflow:auto;width:260px;}#post-body-content .tagsdiv .the-tags{margin:0 5px;}p.popular-tags{-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;border-width:1px;border-style:solid;line-height:2em;padding:8px 12px 12px;text-align:justify;}p.popular-tags a{padding:0 3px;}.tagcloud{width:97%;margin:0 0 40px;text-align:justify;}.tagcloud h3{margin:2px 0 12px;}.ac_results{padding:0;margin:0;list-style:none;position:absolute;z-index:10000;display:none;border-width:1px;border-style:solid;}.ac_results li{padding:2px 5px;white-space:nowrap;text-align:left;}.ac_over{cursor:pointer;}.ac_match{text-decoration:underline;}#wpbody-content #media-items .describe{border-collapse:collapse;width:100%;border-top-style:solid;border-top-width:1px;clear:both;cursor:default;padding:5px;}#wpbody-content .describe th{vertical-align:top;text-align:left;padding:10px;width:140px;}#wpbody-content .describe .media-item-info tr{background-color:transparent;}#wpbody-content .describe .media-item-info td{padding:4px 10px 0;}.describe .media-item-info .A1B1{padding:0 0 0 10px;}#wpbody-content .filename{padding:0 10px;}#wpbody-content .media-item .thumbnail{max-height:128px;max-width:128px;}#wpbody-content #async-upload-wrap a{display:none;}.media-upload-form td label{margin-right:6px;margin-left:2px;}.media-upload-form .align .field label{display:inline;padding:0 0 0 22px;margin:0 1em 0 0;font-weight:bold;}.media-upload-form tr.image-size label{margin:0 0 0 3px;font-weight:bold;}.media-upload-form th.label label{font-weight:bold;margin:.5em;font-size:13px;}.media-upload-form th.label label span{padding:0 5px;}abbr.required{border:medium none;text-decoration:none;}#wpbody-content .describe input[type="text"],#wpbody-content .describe textarea{width:460px;}#wpbody-content .describe p.help{margin:0;padding:0 0 0 5px;}.media-item .error-div a.dismiss,.describe-toggle-on,.describe-toggle-off{display:block;line-height:36px;float:right;margin-right:20px;}.describe-toggle-off{display:none;}#wpbody-content .media-item{border-bottom-style:solid;border-bottom-width:1px;min-height:36px;position:relative;width:100%;}#wpbody-content .media-single .media-item{border-bottom-style:none;border-bottom-width:0;}#wpbody-content #media-items{border-style:solid solid none;border-width:1px;width:670px;}#wpbody-content #media-items .filename{line-height:36px;overflow:hidden;}.media-item .error-div{padding-left:10px;}.media-item .pinkynail{float:left;margin:2px;max-width:40px;max-height:32px;}.media-item .startopen,.media-item .startclosed{display:none;}.media-item .original{position:relative;height:34px;width:503px;}.media-item .percent{font-weight:bold;}.crunching{display:block;line-height:32px;text-align:right;margin-right:5px;}.progress{position:relative;margin-bottom:-36px;height:36px;}.bar{width:0;height:100%;border-right-width:3px;border-right-style:solid;}.upload-php .fixed .column-parent{width:25%;}.find-box{width:500px;height:300px;overflow:hidden;padding:33px 5px 40px;position:absolute;z-index:1000;}.find-box-head{cursor:move;font-weight:bold;height:2em;line-height:2em;padding:1px 12px;position:absolute;top:5px;width:100%;}.find-box-inside{overflow:auto;width:100%;height:100%;}.find-box-search{padding:12px;border-width:1px;border-style:none none solid;}#find-posts-response{margin:8px 0;padding:0 1px;}#find-posts-response table{width:100%;}#find-posts-response .found-radio{padding:5px 0 0 8px;width:15px;}.find-box-buttons{width:480px;margin:8px;}.find-box-search label{padding-right:6px;}.find-box #resize-se{position:absolute;right:1px;bottom:1px;}#favorite-actions{float:right;margin:11px 12px 0;min-width:130px;position:relative;}#favorite-first{-moz-border-radius:12px;-khtml-border-radius:12px;-webkit-border-radius:12px;border-radius:12px;line-height:15px;padding:3px 30px 4px 12px;border-width:1px;border-style:solid;}#favorite-inside{margin:0;padding:2px 1px;border-width:1px;border-style:solid;position:absolute;z-index:11;display:none;-moz-border-radius:0 0 12px 12px;-webkit-border-bottom-right-radius:12px;-webkit-border-bottom-left-radius:12px;-khtml-border-bottom-right-radius:12px;-khtml-border-bottom-left-radius:12px;border-bottom-right-radius:12px;border-bottom-left-radius:12px;}#favorite-actions a{display:block;text-decoration:none;font-size:11px;}#favorite-inside a{padding:3px 5px 3px 10px;}#favorite-toggle{height:22px;position:absolute;right:0;top:1px;width:28px;}#favorite-actions .slide-down{-moz-border-radius:12px 12px 0 0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-khtml-border-bottom-right-radius:0;-khtml-border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-bottom:none;}ul#dismissed-updates{display:none;}form.upgrade{margin-top:8px;}form.upgrade .hint{font-style:italic;font-size:85%;margin:-0.5em 0 2em 0;}#poststuff .inside .the-tagcloud{margin:5px 0 10px;padding:8px;border-width:1px;border-style:solid;line-height:1.8em;word-spacing:3px;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}br.clear{height:2px;line-height:2px;}.swfupload{margin:5px 10px;vertical-align:middle;}.describe .image-editor{vertical-align:top;}.imgedit-wrap{position:relative;}.imgedit-settings p{margin:8px 0;}.describe .imgedit-wrap table td{vertical-align:top;padding-top:0;}.imgedit-wrap p,.describe .imgedit-wrap table td{font-size:11px;line-height:18px;}.describe .imgedit-wrap table td.imgedit-settings{padding:0 5px;}td.imgedit-settings input{vertical-align:middle;}.imgedit-wait{position:absolute;top:0;background:#FFF url(../images/wpspin_light.gif) no-repeat scroll 22px 10px;opacity:.7;filter:alpha(opacity=70);width:100%;height:500px;display:none;}.media-disabled,.imgedit-settings .disabled{color:grey;}.imgedit-wait-spin{padding:0 4px 4px;vertical-align:bottom;visibility:hidden;}.imgedit-menu{margin:0 0 12px;min-width:300px;}.imgedit-menu div{float:left;width:32px;height:32px;-moz-border-radius:4px;-khtml-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;border-width:1px;border-style:solid;}.imgedit-crop-wrap{position:relative;}.imgedit-crop{background:transparent url(../images/imgedit-icons.png) no-repeat scroll -9px -31px;margin:0 8px 0 0;}.imgedit-crop.disabled:hover{background-position:-9px -31px;}.imgedit-crop:hover{background-position:-9px -1px;}.imgedit-rleft{background:transparent url(../images/imgedit-icons.png) no-repeat scroll -46px -31px;margin:0 3px;}.imgedit-rleft.disabled:hover{background-position:-46px -31px;}.imgedit-rleft:hover{background-position:-46px -1px;}.imgedit-rright{background:transparent url(../images/imgedit-icons.png) no-repeat scroll -77px -31px;margin:0 8px 0 3px;}.imgedit-rright.disabled:hover{background-position:-77px -31px;}.imgedit-rright:hover{background-position:-77px -1px;}.imgedit-flipv{background:transparent url(../images/imgedit-icons.png) no-repeat scroll -115px -31px;margin:0 3px;}.imgedit-flipv.disabled:hover{background-position:-115px -31px;}.imgedit-flipv:hover{background-position:-115px -1px;}.imgedit-fliph{background:transparent url(../images/imgedit-icons.png) no-repeat scroll -147px -31px;margin:0 8px 0 3px;}.imgedit-fliph.disabled:hover{background-position:-147px -31px;}.imgedit-fliph:hover{background-position:-147px -1px;}.imgedit-undo{background:transparent url(../images/imgedit-icons.png) no-repeat scroll -184px -31px;margin:0 3px;}.imgedit-undo.disabled:hover{background-position:-184px -31px;}.imgedit-undo:hover{background-position:-184px -1px;}.imgedit-redo{background:transparent url(../images/imgedit-icons.png) no-repeat scroll -215px -31px;margin:0 8px 0 3px;}.imgedit-redo.disabled:hover{background-position:-215px -31px;}.imgedit-redo:hover{background-position:-215px -1px;}.imgedit-applyto img{margin:0 8px 0 0;}.imgedit-group-top{margin:5px 0;}.imgedit-applyto .imgedit-label{padding:2px 0 0;display:block;}.imgedit-help{display:none;font-style:italic;margin-bottom:8px;}.imgedit-help ul li{font-size:11px;}a.imgedit-help-toggle{text-decoration:none;}#wpbody-content .imgedit-response div{width:600px;margin:8px;}.form-table td.imgedit-response{padding:0;}.imgedit-submit{margin:8px 0;}.imgedit-submit-btn{margin-left:20px;}.imgedit-wrap .nowrap{white-space:nowrap;}span.imgedit-scale-warn{color:red;font-size:20px;font-style:normal;visibility:hidden;vertical-align:middle;}.imgedit-group{border-width:1px;border-style:solid;-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;margin-bottom:8px;padding:2px 10px;}.form-table{border-collapse:collapse;margin-top:.5em;width:100%;margin-bottom:-8px;clear:both;}.form-table td{margin-bottom:9px;padding:8px 10px;line-height:20px;font-size:11px;}.form-table th,.form-wrap label{font-weight:normal;text-shadow:rgba(255,255,255,1) 0 1px 0;}.form-table th{vertical-align:top;text-align:left;padding:10px;width:200px;}.form-table th.th-full{width:auto;}.form-table div.color-option{display:block;clear:both;margin-top:12px;}.form-table input.tog{margin-top:2px;margin-right:2px;float:left;}.form-table td p{margin-top:4px;}.form-table table.color-palette{vertical-align:bottom;float:left;margin:-12px 3px 11px;}.form-table .color-palette td{border-width:1px 1px 0;border-style:solid solid none;height:10px;line-height:20px;width:10px;}.commentlist li{padding:1em 1em .2em;margin:0;border-bottom-width:1px;border-bottom-style:solid;}.commentlist li li{border-bottom:0;padding:0;}.commentlist p{padding:0;margin:0 0 .8em;}#replyrow{font-size:11px;}#replyrow input{border-width:1px;border-style:solid;}#replyrow td{padding:2px;}#replyrow #editorcontainer{border:0 none;}#replysubmit{margin:0;padding:3px 7px;text-align:center;}#replysubmit img.waiting,.inline-edit-save img.waiting{padding:4px 10px 0;vertical-align:top;float:right;}#replysubmit .button{margin-right:5px;}#replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center;}#replyrow #editor-toolbar{display:none;}#replyhead{font-size:12px;font-weight:bold;padding:2px 10px 4px;}#edithead .inside{float:left;padding:3px 0 2px 5px;margin:0;text-align:center;font-size:11px;}#edithead .inside input{width:180px;font-size:11px;}#edithead label{padding:2px 0;}#replycontainer{padding:5px;border:0 none;height:120px;overflow:hidden;position:relative;}#replycontent{resize:none;margin:0;width:100%;height:100%;padding:0;line-height:150%;border:0 none;outline:none;font-size:12px;}#replyrow #ed_reply_toolbar{margin:0;padding:2px 3px;}.comment-ays{margin-bottom:0;border-style:solid;border-width:1px;}.comment-ays th{border-right-style:solid;border-right-width:1px;}.trash-undo-inside,.spam-undo-inside{margin:1px 8px 1px 0;line-height:16px;}.spam-undo-inside .avatar,.trash-undo-inside .avatar{height:20px;width:20px;margin-right:8px;vertical-align:middle;}.stuffbox .editcomment{clear:none;}#comment-status-radio p{margin:3px 0 5px;}#comment-status-radio input{margin:2px 3px 5px 0;vertical-align:middle;}#comment-status-radio label{padding:5px 0;}.commentlist .avatar{vertical-align:text-top;}.theme-install-php .tablenav{height:auto;}table#availablethemes{border-spacing:0;border-width:1px 0;border-style:solid none;margin:10px auto;width:100%;}table#availablethemes .no-items td{border-width:0;padding:5px;}td.available-theme{vertical-align:top;width:240px;margin:0;padding:20px;text-align:left;}table#availablethemes td{border-width:0 1px 1px;border-style:none solid solid;}table#availablethemes td.right,table#availablethemes td.left{border-right:0 none;border-left:0 none;}table#availablethemes td.bottom{border-bottom:0 none;}.available-theme a.screenshot{width:240px;height:180px;display:block;border-width:1px;border-style:solid;margin-bottom:10px;overflow:hidden;}.available-theme img{width:240px;}.available-theme h3{margin:15px 0 5px;}#current-theme{margin:1em 0 1.5em;}#current-theme a{border-bottom:none;}#current-theme h3{font-size:17px;font-weight:normal;margin:0;}#current-theme .theme-description{margin-top:5px;}#current-theme img{float:left;border-width:1px;border-style:solid;margin-right:1em;margin-bottom:1.5em;width:150px;}.theme-options span{text-transform:uppercase;font-size:13px;}.theme-options a{font-size:15px;}#TB_window #TB_title a.tb-theme-preview-link,#TB_window #TB_title a.tb-theme-preview-link:visited{font-weight:bold;text-decoration:none;}#TB_window #TB_title{background-color:#222;color:#cfcfcf;}#broken-themes{text-align:left;width:50%;border-spacing:3px;padding:3px;}.theme-install-php h4{margin:2.5em 0 8px;}.appearance_page_custom-header #headimg{border:1px solid #DFDFDF;min-height:100px;width:100%;}.appearance_page_custom-header #upload-form p label{font-size:11px;}.appearance_page_custom-header #available-headers .default-header{float:left;margin:0 20px 20px 0;}.appearance_page_custom-header #available-headers label input{margin-right:10px;}.appearance_page_custom-header #available-headers label img{vertical-align:middle;}div#custom-background-image{min-height:100px;border:1px solid #dfdfdf;}div#custom-background-image img{max-width:400px;max-height:300px;}#custom-background label{padding-right:15px;}.nav-tab{border-style:solid;border-color:#ccc #ccc #f9f9f9;border-width:1px 1px 0;color:#c1c1c1;text-shadow:rgba(255,255,255,1) 0 1px 0;font-size:12px;line-height:16px;display:inline-block;padding:4px 14px 6px;text-decoration:none;margin:0 6px -1px 0;-moz-border-radius:5px 5px 0 0;-webkit-border-top-left-radius:5px;-webkit-border-top-right-radius:5px;-khtml-border-top-left-radius:5px;-khtml-border-top-right-radius:5px;border-top-left-radius:5px;border-top-right-radius:5px;}.nav-tab-active{border-width:1px;color:#464646;}h2.nav-tab-wrapper,h3.nav-tab-wrapper{border-bottom:1px solid #ccc;padding-bottom:0;}h2 .nav-tab{padding:4px 20px 6px;font:italic normal normal 24px/35px Georgia,"Times New Roman","Bitstream Charter",Times,serif;}.plugins .name,#pass-strength-result.strong,#pass-strength-result.short,.button-highlighted,input.button-highlighted,#quicktags #ed_strong,#ed_reply_toolbar #ed_reply_strong{font-weight:bold;}.plugins p{margin:0 4px;padding:0;}.plugins .desc p{margin:0 0 8px;}.plugins td.desc{line-height:1.5em;}.plugins .desc ul,.plugins .desc ol{margin:0 0 0 2em;}.plugins .desc ul{list-style-type:disc;}.plugins .row-actions-visible{padding:0;}.plugins tbody th.check-column{padding:7px 0;}.plugins td,.plugins th{border-bottom:0 none;}.plugins .inactive td,.plugins .inactive th,.plugins .active td,.plugins .active th{border-top-style:solid;border-top-width:1px;padding:5px 7px 0;}#wpbody-content .plugins .plugin-title,#wpbody-content .plugins .theme-title{padding-right:12px;white-space:nowrap;}.plugins .second,.plugins .row-actions-visible{padding:0 0 5px;}.plugins-php .widefat tfoot th,.plugins-php .widefat tfoot td{border-top-style:solid;border-top-width:1px;}.plugin-update-tr .update-message{margin:5px;padding:3px 5px;border-width:1px;border-style:solid;-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}.plugin-install-php h4{margin:2.5em 0 8px;}#profile-page .form-table textarea{width:500px;margin-bottom:6px;}#profile-page .form-table #rich_editing{margin-right:5px;}#your-profile legend{font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-size:22px;}#your-profile #rich_editing{border:none;}#display_name{width:15em;}#createuser .form-field input{width:25em;}#utc-time,#local-time{padding-left:25px;font-style:italic;font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;}.defaultavatarpicker .avatar{margin:2px 0;vertical-align:middle;}#footer{margin-top:-46px;border-top:1px;border-style:solid;}#footer,#footer a{font-size:12px;font-family:Georgia,"Times New Roman","Bitstream Charter",Times,serif;font-style:italic;}#footer p{margin:0;padding:15px;line-height:15px;}#footer a{text-decoration:none;}#footer a:hover{text-decoration:underline;}#excerpt,.attachmentlinks{margin:0;height:4em;width:98%;}#template div{margin-right:190px;}p.pagenav{margin:0;display:inline;}.pagenav span{font-weight:bold;margin:0 6px;}.row-title{font-size:12px!important;font-weight:bold;}.column-author img,.column-username img{float:left;margin-right:10px;margin-top:3px;}.row-actions{visibility:hidden;padding:2px 0 0;}tr:hover .row-actions,div.comment-item:hover .row-actions{visibility:visible;}.row-actions-visible{padding:2px 0 0;}.form-table .pre{padding:8px;margin:0;}table.form-table td .updated{font-size:13px;}.tagchecklist{margin-left:14px;font-size:12px;overflow:auto;}.tagchecklist strong{margin-left:-8px;position:absolute;}.tagchecklist span{margin-right:25px;display:block;float:left;font-size:11px;line-height:1.8em;white-space:nowrap;cursor:default;}.tagchecklist span a{margin:6px 0 0 -9px;cursor:pointer;width:10px;height:10px;display:block;float:left;text-indent:-9999px;overflow:hidden;position:absolute;}#poststuff h2{margin-top:20px;font-size:1.5em;margin-bottom:15px;padding:0 0 3px;clear:left;}#poststuff h3,.metabox-holder h3{font-size:12px;font-weight:bold;padding:7px 9px;margin:0;line-height:1;}#poststuff .inside,#poststuff .inside p{font-size:11px;margin:6px 6px 8px;}#poststuff .inside .submitbox p{margin:1em 0;}#post-visibility-select,#post-formats-select{line-height:1.5em;margin-top:3px;}#poststuff #submitdiv .inside{margin:0;}#titlediv,#poststuff .postarea{margin-bottom:20px;}td.post-title strong,td.plugin-title strong{display:block;margin-bottom:.2em;}td.post-title p,td.plugin-title p{margin:6px 0;}.wp-hidden-children .wp-hidden-child,.ui-tabs-hide{display:none;}#templateside ul li a{text-decoration:none;}.tool-box{margin:15px 0 35px;}.tool-box .buttons{margin:15px 0;}.tool-box .title{margin:8px 0;font:18px/24px Georgia,"Times New Roman","Bitstream Charter",Times,serif;}.pressthis a{font-size:1.2em;}#sidemenu{margin:-30px 15px 0 315px;list-style:none;position:relative;float:right;padding-left:10px;font-size:12px;}#sidemenu a{padding:0 7px;display:block;float:left;line-height:28px;border-top-width:1px;border-top-style:solid;border-bottom-width:1px;border-bottom-style:solid;}#sidemenu li{display:inline;line-height:200%;list-style:none;text-align:center;white-space:nowrap;margin:0;padding:0;}#sidemenu a.current{font-weight:normal;padding-left:6px;padding-right:6px;-moz-border-radius:4px 4px 0 0;-webkit-border-top-left-radius:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-left-radius:4px;-khtml-border-top-right-radius:4px;border-top-left-radius:4px;border-top-right-radius:4px;border-width:1px;border-style:solid;}#sidemenu li a .count-0{display:none;}#poststuff .inside .the-tagcloud{margin:5px 0 10px;padding:8px;border-width:1px;border-style:solid;line-height:1.8em;word-spacing:3px;-moz-border-radius:6px;-khtml-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.plugin-install #description,.plugin-install-network #description{width:60%;}table .vers,table .column-visible,table .column-rating{text-align:left;}body.iframe{height:98%;}.anchors{margin:10px 20px 10px 20px;}div.nav{height:2em;padding:7px 10px;vertical-align:text-top;margin:5px 0;}.nav .button-secondary{padding:2px 4px;}* html #themeselect{padding:0 3px;height:22px;}.settings-toggle{text-align:right;margin:5px 7px 15px 0;font-size:12px;}.settings-toggle h3{margin:0;}form#tags-filter{position:relative;}td.media-icon{text-align:center;width:80px;padding-top:8px;padding-bottom:8px;}td.media-icon img{max-width:80px;max-height:60px;}.screen-per-page{width:3em;}* html #template div{margin-right:0;}.list-ajax-loading{float:right;margin-right:9px;margin-top:-1px;}.tablenav .list-ajax-loading{margin-top:7px;}#howto{font-size:11px;margin:0 5px;display:block;}.import-system{font-size:16px;}#namediv table{width:100%;}#namediv td.first{width:10px;white-space:nowrap;}#namediv input{width:98%;}#namediv p{margin:10px 0;}#submitdiv h3{margin-bottom:0!important;}.zerosize{height:0;width:0;margin:0;border:0;padding:0;overflow:hidden;position:absolute;}br.clear{height:2px;line-height:2px;}.checkbox{border:none;margin:0;padding:0;}#content{margin:0;width:100%;}fieldset{border:0;padding:0;margin:0;}#linksubmitdiv div.inside,div.inside{padding:0;margin:0;}.post-categories{display:inline;margin:0;padding:0;}.post-categories li{display:inline;} \ No newline at end of file diff --git a/src/wp-admin/css/wp-admin.dev.css b/src/wp-admin/css/wp-admin.dev.css new file mode 100644 index 00000000..3165a5e0 --- /dev/null +++ b/src/wp-admin/css/wp-admin.dev.css @@ -0,0 +1,4316 @@ +/*------------------------------------------------------------------------------ + + +Hello, this is the main WordPress admin CSS file. +All the important stuff is in here. + + +TABLE OF CONTENTS: +------------------ + 1.0 - Text Elements + 2.0 - Forms + 3.0 - Actions + 4.0 - Notifications + 5.0 - TinyMCE + 6.0 - Admin Header + 6.1 - Favorites Menu + 6.2 - Screen Options Tabs + 7.0 - Main Navigation + 8.0 - Layout Blocks + 9.0 - Dashboard +10.0 - List Posts + 10.1 - Inline Editing +11.0 - Write/Edit Post Screen + 11.1 - Custom Fields + 11.2 - Post Revisions +12.0 - Categories +13.0 - Tags +14.0 - Media Screen + 14.1 - Media Uploader + 14.2 - Image Editor +15.0 - Comments Screen +16.0 - Themes + 16.1 - Custom Header + 16.2 - Custom Background + 16.3 - Tabbed Admin Screen Interface +17.0 - Plugins +18.0 - Users +19.0 - Tools +20.0 - Settings +21.0 - Admin Footer +22.0 - Misc +23.0 - Dead + + +------------------------------------------------------------------------------*/ + + + + +/*------------------------------------------------------------------------------ + 1.0 - Text Styles +------------------------------------------------------------------------------*/ + +p, +ul, +ol, +blockquote, +input, +select { + font-size: 12px; +} + +ol { + list-style-type: decimal; + margin-left: 2em; +} + +.code, code { + font-family: Consolas, Monaco, Courier, monospace; +} + +kbd, code { + padding: 1px 3px; + margin: 0 1px; + font-size: 11px; +} + +.quicktags, .search { + font: 12px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; +} + +.icon32 { + float: left; + height: 36px; + margin: 14px 6px 0 0; + width: 36px; +} + +.key-labels label { + line-height: 24px; +} + +.subtitle { + font-size: 0.75em; + line-height: 1; + padding-left: 25px; +} + +.pre { + /* http://www.longren.org/2006/09/27/wrapping-text-inside-pre-tags/ */ + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ +} + +.howto { + font-style: italic; + display: block; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; +} + +p.install-help { + margin: 8px 0; + font-style: italic; +} + + +/*------------------------------------------------------------------------------ + 2.0 - Forms +------------------------------------------------------------------------------*/ + +textarea, +input[type="text"], +input[type="password"], +input[type="file"], +input[type="button"], +input[type="submit"], +input[type="reset"], +select { + border-width: 1px; + border-style: solid; + -moz-border-radius: 4px; + -khtml-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +select option { + padding: 2px; +} + +.submit { + padding: 1.5em 0; + margin: 5px 0; + -moz-border-radius: 0 0 3px 3px; + -webkit-border-bottom-left-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + -khtml-border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} + +form p.submit a.cancel:hover { + text-decoration: none; +} + +.submit input, +.button, +input.button, +.button-primary, +input.button-primary, +.button-secondary, +input.button-secondary, +.button-highlighted, +input.button-highlighted, +#postcustomstuff .submit input { + text-decoration: none; + font-size: 11px !important; + line-height: 13px; + padding: 3px 8px; + cursor: pointer; + border-width: 1px; + border-style: solid; + -moz-border-radius: 11px; + -khtml-border-radius: 11px; + -webkit-border-radius: 11px; + border-radius: 11px; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + -khtml-box-sizing: content-box; + box-sizing: content-box; +} + +#minor-publishing-actions input, +#major-publishing-actions input, +#minor-publishing-actions .preview { + min-width: 80px; + text-align: center; +} + +textarea.all-options, input.all-options { + width: 250px; +} + +input.large-text, +textarea.large-text { + width: 99%; +} + +input.regular-text, +#adduser .form-field input { + width: 25em; +} + +input.small-text { + width: 50px; +} + +#doaction, +#doaction2, +#post-query-submit { + margin-right: 8px; +} + +.tablenav select[name="action"], +.tablenav select[name="action2"] { + width: 130px; +} + +.tablenav select[name="m"] { + width: 155px; +} + +.tablenav select#cat { + width: 170px; +} + +#wpcontent select { + padding: 2px; + height: 2em; + font-size: 11px; +} + +#wpcontent option { + padding: 2px; +} + +#timezone_string option { + margin-left: 1em; +} + +label, +#your-profile label + a { + vertical-align: middle; +} + +#misc-publishing-actions label { + vertical-align: baseline; +} + +#pass-strength-result { + border-style: solid; + border-width: 1px; + float: left; + margin: 12px 5px 5px 1px; + padding: 3px 5px; + text-align: center; + width: 200px; + display: none; +} +.indicator-hint { + padding-top: 8px; +} + +p.search-box { + float: right; + margin: -5px 0 0; +} + + +/*------------------------------------------------------------------------------ + 3.0 - Actions +------------------------------------------------------------------------------*/ + +#major-publishing-actions { + padding: 6px; + clear: both; + border-top: none; +} + + + +#delete-action { + line-height: 25px; + vertical-align: middle; + text-align: left; + float: left; +} + +#publishing-action { + text-align: right; + float: right; + line-height: 23px; +} + +#post-body #minor-publishing { + padding-bottom: 10px; +} + +#post-body #misc-publishing-actions { + padding: 0; +} + +#post-body .misc-pub-section { + border-right-width: 1px; + border-right-style: solid; + border-bottom: 0 none; + min-height: 30px; + float: left; + max-width: 32%; +} + +#post-body .misc-pub-section-last { + border-right: 0; +} + +#misc-publishing-actions { + padding: 6px 0 16px 0; +} + +.misc-pub-section { + padding: 6px; + border-bottom-width: 1px; + border-bottom-style: solid; +} + +.misc-pub-section-last { + border-bottom: 0 none; +} + +#minor-publishing-actions { + padding: 6px; + text-align: right; +} + +#minor-publishing { + border-bottom-width: 1px; + border-bottom-style: solid; +} + +#save-post { + float: left; +} + +#minor-publishing .ajax-loading { + padding: 3px 0 0 4px; + float: left; +} + +.preview { + float: right; +} + + + +#sticky-span { + margin-left: 18px; +} + +#post-status-display, +#post-visibility-display { + font-weight: bold; +} + +.side-info { + margin: 0; + padding: 4px; + font-size: 11px; +} + +.side-info h5 { + padding-bottom: 7px; + font-size: 14px; + margin: 12px 2px 5px; + border-bottom-width: 1px; + border-bottom-style: solid; +} + +.side-info ul { + margin: 0; + padding-left: 18px; + list-style: square; +} + +a.button, +a.button-primary, +a.button-secondary { + line-height: 15px; + padding: 3px 10px; + white-space: nowrap; + -webkit-border-radius: 10px; +} + +.approve { + display: none; +} + +.unapproved .approve, +.spam .approve, +.trash .approve { + display: inline; +} + +.unapproved .unapprove { + display: none; +} + +.add-new-h2 { + font-style: normal; + margin: 0 6px; + position: relative; + top: -3px; +} + +td.action-links, +th.action-links { + text-align: right; +} + +.describe .del-link { + padding-left: 5px; +} + + +/*------------------------------------------------------------------------------ + 4.0 - Notifications +------------------------------------------------------------------------------*/ + +#update-nag, .update-nag { + line-height: 19px; + padding: 5px 0; + font-size: 12px; + text-align: center; + margin: 0 15px; + border-width: 1px; + border-style: solid; + border-top-width: 0; + border-top-style: none; + -moz-border-radius: 0 0 6px 6px; + -webkit-border-bottom-right-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} + +.plugins .plugin-update { + padding: 0; +} + +.plugin-update .update-message { + margin: 0 10px 8px 31px; + font-weight: bold; +} + +ul#dismissed-updates { + display: none; +} +form.upgrade { + margin-top: 8px; +} + +form.upgrade .hint { + font-style: italic; + font-size: 85%; + margin: -0.5em 0 2em 0; +} + +.ajax-feedback { + visibility: hidden; + vertical-align: bottom; +} + +#ajax-response.alignleft { + margin-left: 2em; +} + + +/*------------------------------------------------------------------------------ + 5.0 - TinyMCE +------------------------------------------------------------------------------*/ + +#editorcontainer #content { + padding: 6px; + line-height: 150%; + border: 0 none; + outline: none; + resize: vertical; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -khtml-box-sizing: border-box; + box-sizing: border-box; +} + +#editorcontainer, +#quicktags { + border-style: solid; + border-width: 1px; + border-collapse: separate; + -moz-border-radius: 6px 6px 0 0; + -webkit-border-top-right-radius: 6px; + -webkit-border-top-left-radius: 6px; + -khtml-border-top-right-radius: 6px; + -khtml-border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} + +#quicktags { + padding: 0; + margin-bottom: -3px; + border-bottom-width: 3px; + background-image: url("../images/ed-bg.gif"); + background-position: left top; + background-repeat: repeat-x; +} + +#quicktags #ed_toolbar { + padding: 2px 4px 0; +} + +#ed_toolbar input, +#ed_reply_toolbar input { + margin: 3px 1px 4px; + line-height: 18px; + display: inline-block; + min-width: 26px; + padding: 2px 4px; + font-size: 12px; +} + +#ed_reply_toolbar input { + margin: 1px 2px 1px 1px; +} + +#quicktags #ed_link, +#ed_reply_toolbar #ed_reply_link { + text-decoration: underline; +} + +#quicktags #ed_del, +#ed_reply_toolbar #ed_reply_del { + text-decoration: line-through; +} + +#quicktags #ed_em, +#ed_reply_toolbar #ed_reply_em { + font-style: italic; +} + +#wp_editbtns, +#wp_gallerybtns { + padding: 2px; + position: absolute; + display: none; + z-index: 999998; +} + +#wp_editimgbtn, +#wp_delimgbtn, +#wp_editgallery, +#wp_delgallery { + margin: 2px; + padding: 2px; + border-width: 1px; + border-style: solid; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + + +/*------------------------------------------------------------------------------ + 6.0 - Admin Header +------------------------------------------------------------------------------*/ +#wphead-info { + margin: 0 0 0 15px; + padding-right: 15px; +} + +#user_info { + float: right; + font-size: 12px; + line-height: 46px; + height: 46px; +} + +#user_info p { + margin: 0; + padding: 0; + line-height: 46px; +} + +#wphead { + height: 46px; +} + +#wphead a, +#adminmenu a, +#sidemenu a, +#taglist a, +#catlist a, +#show-settings a { + text-decoration: none; +} + +#header-logo { + float: left; + margin: 7px 0 0 15px; +} + +#wphead h1 { + font: normal 22px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + padding: 10px 8px 5px; + margin: 0; + float: left; +} + +#wphead h1.long-title { + font: normal 18px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + padding: 12px 10px 5px; +} + +#wphead #privacy-on-link { + font-size: 50%; + font-style: normal; + line-height: 17px; + padding: 0 6px; + vertical-align: middle; +} + +#wphead h1 a:hover { + text-decoration:none; +} +#wphead h1 a:hover #site-title, +#wphead h1 a#privacy-on-link:hover { + text-decoration:underline; +} + + +/*------------------------------------------------------------------------------ + 6.1 - Favorites Menu +------------------------------------------------------------------------------*/ + +#favorite-actions { + float: right; + margin: 11px 12px 0; + min-width: 130px; + position: relative; +} + +#favorite-first { + -moz-border-radius: 12px; + -khtml-border-radius: 12px; + -webkit-border-radius: 12px; + border-radius: 12px; + line-height: 15px; + padding: 3px 30px 4px 12px; + border-width: 1px; + border-style: solid; +} + +#favorite-inside { + margin: 0 0 0 0px; + padding: 2px 1px; + border-width: 1px; + border-style: solid; + position: absolute; + z-index: 11; + display: none; + -moz-border-radius: 0 0 12px 12px; + -webkit-border-bottom-right-radius: 12px; + -webkit-border-bottom-left-radius: 12px; + -khtml-border-bottom-right-radius: 12px; + -khtml-border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; + border-bottom-left-radius: 12px; +} + +#favorite-actions a { + display: block; + text-decoration: none; + font-size: 11px; +} + +#favorite-inside a { + padding: 3px 5px 3px 10px; +} + +#favorite-toggle { + height: 22px; + position: absolute; + right: 0; + top: 1px; + width: 28px; +} + +#favorite-actions .slide-down { + -moz-border-radius: 12px 12px 0 0; + -webkit-border-bottom-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 0; + -khtml-border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-bottom: none; +} + + +/*------------------------------------------------------------------------------ + 6.2 - Screen Options Tabs +------------------------------------------------------------------------------*/ + +#screen-meta { + position: relative; + clear: both; +} + +#screen-meta-links { + margin: 0 18px 0 0; +} + +#screen-meta .screen-reader-text { + visibility: hidden; +} + +#screen-options-link-wrap, +#contextual-help-link-wrap { + float: right; + height: 22px; + padding: 0; + margin: 0 6px 0 0; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + background: #e3e3e3; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-bottomright: 3px; + -webkit-border-bottom-left-radius: 3px; + -webkit-border-bottom-right-radius: 3px; +} + +#contextual-help-wrap li { + list-style-type: disc; + margin-left: 18px; +} +.toggle-arrow { + background-repeat: no-repeat; + background-position: top left; + background-color: transparent; + height: 22px; + line-height: 22px; + display: block; +} +.toggle-arrow-active { + background-position: bottom left; +} +#screen-meta a.show-settings { + text-decoration: none; + z-index: 1; + padding: 0 16px 0 6px; + height: 22px; + line-height: 22px; + font-size: 10px; + display: block; + background-repeat: no-repeat; + background-position: top right; + background-color: transparent; + text-shadow: rgba(255,255,255,0.7) 0 1px 0; +} + +#screen-meta a.show-settings:hover { + text-decoration: none; +} + +#screen-options-wrap h5, +#contextual-help-wrap h5 { + margin: 8px 0; + font-size: 13px; +} + +#screen-options-wrap, +#contextual-help-wrap { + border-style: none solid solid; + border-top: 0 none; + border-width: 0 1px 1px; + margin: 0 15px; + padding: 8px 12px 12px; + -moz-border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px; + -khtml-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.metabox-prefs label { + display: inline-block; + padding-right: 15px; + white-space: nowrap; + line-height: 30px; +} + +.metabox-prefs label input { + margin: 0 5px 0 2px; +} + +.metabox-prefs label a { + display: none; +} + + +/*------------------------------------------------------------------------------ + 7.0 - Main Navigation (Left Menu) +------------------------------------------------------------------------------*/ + +/* side admin menu */ +#adminmenu * { + -webkit-user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + user-select: none; +} + +#adminmenu .wp-submenu { + display: none; + list-style: none; + padding: 0; + margin: 0; + position: relative; + z-index: 2; + border-width: 1px 0 0; + border-style: solid none none; +} + +#adminmenu .wp-submenu a { + font: normal 11px/18px "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; +} + +#adminmenu .wp-submenu li.current, +#adminmenu .wp-submenu li.current a, +#adminmenu .wp-submenu li.current a:hover { + font-weight: bold; +} + +#adminmenu a.menu-top, +#adminmenu .wp-submenu-head { + font: normal 13px/18px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; +} + +#adminmenu div.wp-submenu-head { + display: none; +} + +.folded #adminmenu div.wp-submenu-head, +.folded #adminmenu li.wp-has-submenu div.sub-open { + display: block; +} + +.folded #adminmenu a.menu-top, +.folded #adminmenu .wp-submenu, +.folded #adminmenu li.wp-menu-open .wp-submenu, +.folded #adminmenu div.wp-menu-toggle { + display: none; +} + +#adminmenu li.wp-menu-open .wp-submenu, +.no-js #adminmenu .open-if-no-js .wp-submenu { + display: block; +} + +#adminmenu div.wp-menu-image { + float: left; + width: 28px; + height: 28px; +} + +#adminmenu li { + margin: 0; + padding: 0; + cursor: pointer; +} + +#adminmenu a { + display: block; + line-height: 18px; + padding: 1px 5px 3px; +} + +#adminmenu li.menu-top { + min-height: 26px; +} + +#adminmenu a.menu-top { + line-height: 18px; + min-width: 10em; + padding: 5px 5px; + border-width: 1px 1px 0; + border-style: solid solid none; +} + +#adminmenu .wp-submenu a { + margin: 0; + padding-left: 12px; + border-width: 0 1px 0 0; + border-style: none solid none none; +} + +#adminmenu .menu-top-last ul.wp-submenu { + border-width: 0 0 1px; + border-style: none none solid; +} + +#adminmenu .wp-submenu li { + padding: 0; + margin: 0; +} + +.folded #adminmenu li.menu-top { + width: 28px; + height: 30px; + overflow: hidden; + border-width: 1px 1px 0; + border-style: solid solid none; +} + +#adminmenu .menu-top-first a.menu-top, +.folded #adminmenu li.menu-top-first, +#adminmenu .wp-submenu .wp-submenu-head { + border-width: 1px 1px 0; + border-style: solid solid none; + -moz-border-radius-topleft :6px; + -moz-border-radius-topright: 6px; + -webkit-border-top-right-radius: 6px; + -webkit-border-top-left-radius: 6px; + -khtml-border-top-right-radius: 6px; + -khtml-border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} + +#adminmenu .menu-top-last a.menu-top, +.folded #adminmenu li.menu-top-last { + border-width: 1px; + border-style: solid; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} + +#adminmenu li.wp-menu-open a.menu-top-last { + border-bottom: 0 none; + -moz-border-radius-bottomright: 0; + -moz-border-radius-bottomleft: 0; + -webkit-border-bottom-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 0; + -khtml-border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +#adminmenu .wp-menu-image img { + float: left; + padding: 8px 6px 0; + opacity: 0.6; + filter: alpha(opacity=60); +} + +#adminmenu li.menu-top:hover .wp-menu-image img, +#adminmenu li.wp-has-current-submenu .wp-menu-image img { + opacity: 1; + filter: alpha(opacity=100); +} + +#adminmenu li.wp-menu-separator { + height: 21px; + padding: 0; + margin: 0; +} + +#adminmenu a.separator { + cursor: w-resize; + height: 20px; + padding: 0; +} + +.folded #adminmenu a.separator { + cursor: e-resize; +} + +#adminmenu .wp-menu-separator-last { + height: 10px; + width: 1px; +} + +#adminmenu .wp-submenu .wp-submenu-head { + border-width: 1px; + border-style: solid; + padding: 6px 4px 6px 10px; + cursor: default; +} + +.folded #adminmenu .wp-submenu { + position: absolute; + margin: -1px 0 0 28px; + padding: 0 8px 8px; + z-index: 999; + border: 0 none; +} + +.folded #adminmenu .wp-submenu ul { + width: 140px; + border-width: 0 0 1px; + border-style: none none solid; +} + +.folded #adminmenu .wp-submenu li.wp-first-item { + border-top: 0 none; +} + +.folded #adminmenu .wp-submenu a { + padding-left: 10px; +} + +.folded #adminmenu a.wp-has-submenu { + margin-left: 40px; +} + +#adminmenu li.menu-top-last .wp-submenu ul { + border-width: 0 0 1px; + border-style: none none solid; +} + +#adminmenu .wp-menu-toggle { + width: 22px; + clear: right; + float: right; + margin: 1px 0 0; + height: 27px; + padding: 1px 2px 0 0; + cursor: default; +} + +#adminmenu li.wp-has-current-submenu ul { + border-bottom-width: 1px; + border-bottom-style: solid; +} + +#adminmenu .wp-menu-image a { + height: 24px; +} + +#adminmenu .wp-menu-image img { + padding: 6px 0 0 1px; +} + +#adminmenu #awaiting-mod, +#adminmenu span.update-plugins, +#sidemenu li a span.update-plugins { + position: absolute; + font-family: Helvetica, Arial, sans-serif; + font-size: 9px; + line-height: 17px; + font-weight: bold; + margin-top: 1px; + margin-left: 7px; + -moz-border-radius: 10px; + -khtml-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 10px; +} + +#adminmenu li #awaiting-mod span, +#adminmenu li span.update-plugins span, +#sidemenu li a span.update-plugins span { + display: block; + padding: 0 6px; +} + +#adminmenu li span.count-0, +#sidemenu li a .count-0 { + display: none; +} + +.post-com-count-wrapper { + min-width: 22px; + font-family: Helvetica, Arial, sans-serif; +} + +.post-com-count { + height: 1.3em; + line-height: 1.1em; + display: block; + text-decoration: none; + padding: 0 0 6px; + cursor: pointer; + background-position: center -80px; + background-repeat: no-repeat; +} + +.post-com-count span { + font-size: 9px; + font-weight: bold; + height: 1.7em; + line-height: 1.70em; + min-width: 0.7em; + padding: 0 6px; + display: inline-block; + cursor: pointer; + -moz-border-radius: 5px; + -khtml-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +strong .post-com-count { + background-position: center -55px; +} + +.post-com-count:hover { + background-position: center -3px; +} + +.column-response .post-com-count { + float: left; + margin-right: 5px; + text-align: center; +} + +.response-links { + float: left; +} + +#the-comment-list .attachment-80x60 { + padding: 4px 8px; +} + + +/*------------------------------------------------------------------------------ + 8.0 - Layout Blocks +------------------------------------------------------------------------------*/ + +body.wp-admin { + min-width: 785px; +} + +body.admin-bar #wphead { + padding-top: 28px; +} + +.narrow { + width: 70%; + margin-bottom: 40px; +} + +.narrow p { + line-height: 150%; +} + +.widefat th, +.widefat td { + overflow: hidden; +} + +.widefat td p { + margin: 2px 0 0.8em; +} + +.widefat .column-comment p { + margin: 0.6em 0; +} + +.widget .widget-top, +.postbox h3 { + cursor: move; + -webkit-user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + user-select: none; +} + +.postbox-container { + float: left; + padding-right: 0.5%; +} + +.postbox-container .meta-box-sortables { + min-height: 300px; +} + +.postbox .hndle span { + padding: 6px 0; +} + +.postbox .hndle { + cursor: move; +} + +.hndle a { + font-size: 11px; + font-weight: normal; +} + +.postbox .handlediv { + float: right; + width: 23px; + height: 26px; +} + +.sortable-placeholder { + border-width: 1px; + border-style: dashed; + margin-bottom: 20px; +} + +.widget, +.postbox, +.stuffbox { + margin-bottom: 20px; + border-width: 1px; + border-style: solid; + line-height: 1; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +.widget .widget-top, +.postbox h3, +.postbox h3, +.stuffbox h3 { + -moz-border-radius: 6px 6px 0 0; + -webkit-border-top-right-radius: 6px; + -webkit-border-top-left-radius: 6px; + -khtml-border-top-right-radius: 6px; + -khtml-border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-top-left-radius: 6px; +} + +.postbox.closed h3 { + -moz-border-radius-bottomleft: 4px; + -webkit-border-bottom-left-radius: 4px; + -khtml-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -webkit-border-bottom-right-radius: 4px; + -khtml-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.postbox table.form-table { + margin-bottom: 0; +} + +.postbox input[type="text"], +.postbox textarea, +.stuffbox input[type="text"], +.stuffbox textarea { + border-width: 1px; + border-style: solid; +} + +.temp-border { + border: 1px dotted #ccc; +} + +.columns-prefs label { + padding: 0 5px; +} + + +/*------------------------------------------------------------------------------ + 9.0 - Dashboard +------------------------------------------------------------------------------*/ + +#wpbody-content .metabox-holder { + padding-top: 10px; +} + +#dashboard-widgets .meta-box-sortables { + margin: 0 5px; +} + +#dashboard_recent_comments div.undo { + border-top-style: solid; + border-top-width: 1px; + margin: 0 -10px; + padding: 3px 8px; + font-size: 11px; +} + +#the-comment-list td.comment p.comment-author { + margin-top: 0; + margin-left: 0; +} + +#the-comment-list p.comment-author img { + float: left; + margin-right: 8px; +} + +#the-comment-list p.comment-author strong a { + border: none; +} + +#the-comment-list td { + vertical-align: top; +} + +#the-comment-list td.comment { + word-wrap: break-word; +} + +#the-comment-list .check-column { + padding-top: 8px; +} + + +/*------------------------------------------------------------------------------ + 10.0 - List Posts (/Pages/etc) +------------------------------------------------------------------------------*/ + +table.fixed { + table-layout: fixed; +} +.fixed .column-rating, +.fixed .column-visible { + width: 8%; +} +.fixed .column-date, +.fixed .column-parent, +.fixed .column-links { + width: 10%; +} +.fixed .column-response, +.fixed .column-author, +.fixed .column-categories, +.fixed .column-tags, +.fixed .column-rel, +.fixed .column-role { + width: 15%; +} +.fixed .column-comments { + width: 4em; + padding: 8px 0; + text-align: left; +} +.fixed .column-comments .vers { + padding-left: 3px; +} +.fixed .column-comments a { + float: left; +} +.fixed .column-slug { + width: 25%; +} +.fixed .column-posts { + width: 10%; +} +.fixed .column-icon { + width: 80px; +} +#commentsdiv .fixed .column-author, +#comments-form .fixed .column-author { + width: 20%; +} +#commentsdiv.postbox .inside { + line-height:1.4em; + margin:0; +} +#commentsdiv.postbox .inside .row-actions { + line-height:18px; +} +#commentsdiv.postbox .inside td { + padding:1em 10px; +} +#commentsdiv.postbox .inside .column-comment p { +} +#commentsdiv.postbox .inside .column-author { + width:33%; +} +#commentsdiv.postbox .inside p { + margin:6px 10px 8px; +} +#commentsdiv.postbox .column-comment p { + margin:0.6em 0; +} +#commentsdiv.postbox #replyrow td { + padding:0; +} +.sorting-indicator { + display: none; + width: 7px; + height: 4px; + margin-top: 5px; + margin-left: 7px; + background-image: url(../images/sort.gif); + background-repeat: no-repeat; +} +.fixed .column-comments .sorting-indicator { + margin-top: 3px; +} +.widefat th.sortable, +.widefat th.sorted { + padding: 0; +} +th.sortable a, +th.sorted a { + display: block; + overflow: hidden; + padding: 7px 7px 8px; +} +.fixed .column-comments.sortable a, +.fixed .column-comments.sorted a { + padding: 8px 0; +} +th.sortable a span, +th.sorted a span { + float: left; + cursor: pointer; +} +th.sorted.asc .sorting-indicator, +th.desc:hover span.sorting-indicator { + display: block; + background-position: 0 0; +} +th.sorted.desc .sorting-indicator, +th.asc:hover span.sorting-indicator { + display: block; + background-position: -7px 0; +} + +/* Bulk Actions */ + +.tablenav-pages a { + border-bottom-style: solid; + border-bottom-width: 2px; + font-weight: bold; + margin-right: 1px; + padding: 0 2px; +} +.tablenav-pages .current-page { + text-align: center; +} +.tablenav-pages .next-page { + margin-left: 2px; +} + +.tablenav a.button-secondary { + display: block; + margin: 3px 8px 0 0; +} + +.tablenav { + clear: both; + height: 30px; + margin: 6px 0 4px; + vertical-align: middle; +} + +.tablenav .tablenav-pages { + float: right; + display: block; + cursor: default; + height: 30px; + line-height: 30px; + font-size: 11px; +} + +.tablenav .one-page { + display: none; +} + +.tablenav .tablenav-pages a, +.tablenav-pages span.current { + text-decoration: none; + border: none; + padding: 3px 6px; + border-width: 1px; + border-style: solid; + -moz-border-radius: 5px; + -khtml-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +.tablenav .tablenav-pages a.disabled:hover { + cursor: default; +} + +.tablenav .tablenav-pages a.disabled:active { + cursor: default; +} + +.tablenav .displaying-num { + margin-right: 10px; + font-size: 12px; + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-style: italic; +} + +.tablenav .actions { + padding: 2px 8px 0 0; +} + +.tablenav .delete { + margin-right: 20px; +} + +.view-switch { + float: right; + margin: 6px 8px 0; +} + +.view-switch a { + text-decoration: none; +} + +.filter { + float: left; + margin: -5px 0 0 10px; +} + +.filter .subsubsub { + margin-left: -10px; + margin-top: 13px; +} +.screen-per-page { + width: 3em; +} + +#posts-filter fieldset { + float: left; + margin: 0 1.5ex 1em 0; + padding: 0; +} + +#posts-filter fieldset legend { + padding: 0 0 .2em 1px; +} + +span.post-state-format { + font-weight: normal; +} + + +/*------------------------------------------------------------------------------ + 10.1 - Inline Editing +------------------------------------------------------------------------------*/ + +/* +.quick-edit* is for Quick Edit +.bulk-edit* is for Bulk Edit +.inline-edit* is for everything +*/ + +/* Layout */ +tr.inline-edit-row td { + padding: 0 0.5em; +} + +#wpbody-content .inline-edit-row fieldset { + font-size: 12px; + float: left; + margin: 0; + padding: 0; + width: 100%; +} + +#wpbody-content .inline-edit-row fieldset .inline-edit-col { + padding: 0 0.5em; +} + +#wpbody-content .quick-edit-row-page fieldset.inline-edit-col-right .inline-edit-col { + border-width: 0 0 0 1px; + border-style: none none none solid; +} + +#wpbody-content .quick-edit-row-post .inline-edit-col-left { + width: 40%; +} + +#wpbody-content .quick-edit-row-post .inline-edit-col-right { + width: 39%; +} + +#wpbody-content .inline-edit-row-post .inline-edit-col-center { + width: 20%; +} + +#wpbody-content .quick-edit-row-page .inline-edit-col-left { + width: 50%; +} + +#wpbody-content .quick-edit-row-page .inline-edit-col-right, +#wpbody-content .bulk-edit-row-post .inline-edit-col-right { + width: 49%; +} + +#wpbody-content .bulk-edit-row .inline-edit-col-left { + width: 30%; +} + +#wpbody-content .bulk-edit-row-page .inline-edit-col-right { + width: 69%; +} + +#wpbody-content .bulk-edit-row .inline-edit-col-bottom { + float: right; + width: 69%; +} + +#wpbody-content .inline-edit-row-page .inline-edit-col-right, +#wpbody-content .bulk-edit-row-post .inline-edit-col-right { + margin-top: 27px; +} + +.inline-edit-row fieldset .inline-edit-group { + clear: both; +} + +.inline-edit-row fieldset .inline-edit-group:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +.inline-edit-row p.submit { + clear: both; + padding: 0.5em; + margin: 0.5em 0 0; +} + +.inline-edit-row span.error { + line-height: 22px; + margin: 0 15px; + padding: 3px 5px; +} + +/* Positioning */ +.inline-edit-row h4 { + margin: .2em 0; + padding: 0; + line-height: 23px; +} +.inline-edit-row fieldset span.title, +.inline-edit-row fieldset span.checkbox-title { + margin: 0; + padding: 0; + line-height: 27px; +} + +.inline-edit-row fieldset label, +.inline-edit-row fieldset span.inline-edit-categories-label { + display: block; + margin: .2em 0; +} + +.inline-edit-row fieldset label.inline-edit-tags { + margin-top: 0; +} + +.inline-edit-row fieldset label.inline-edit-tags span.title { + margin: .2em 0; +} + +.inline-edit-row fieldset label span.title { + display: block; + float: left; + width: 5em; +} + +.inline-edit-row fieldset label span.input-text-wrap { + display: block; + margin-left: 5em; +} + +.quick-edit-row-post fieldset.inline-edit-col-right label span.title { + width: auto; + padding-right: 0.5em; +} + +.inline-edit-row .input-text-wrap input[type=text] { + width: 100%; +} + +.inline-edit-row fieldset label input[type=checkbox] { + vertical-align: text-bottom; +} + +.inline-edit-row fieldset label textarea { + width: 100%; + height: 4em; +} + +#wpbody-content .bulk-edit-row fieldset .inline-edit-group label { + max-width: 50%; +} + +#wpbody-content .quick-edit-row fieldset .inline-edit-group label.alignleft:first-child { + margin-right: 0.5em +} + +/* Styling */ +.inline-edit-row h4 { + text-transform: uppercase; +} + +.inline-edit-row fieldset span.title, +.inline-edit-row fieldset span.checkbox-title { + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-style: italic; + line-height: 1.8em; +} + +/* Specific Elements */ +.inline-edit-row fieldset input[type="text"], +.inline-edit-row fieldset textarea { + border-style: solid; + border-width: 1px; +} + +.inline-edit-row fieldset .inline-edit-date { + float: left; +} + +.inline-edit-row fieldset input[name=jj], +.inline-edit-row fieldset input[name=hh], +.inline-edit-row fieldset input[name=mn] { + font-size: 12px; + width: 2.1em; +} + +.inline-edit-row fieldset input[name=aa] { + font-size: 12px; + width: 3.5em; +} + +.inline-edit-row fieldset label input.inline-edit-password-input { + width: 8em; +} + +.inline-edit-row .catshow, +.inline-edit-row .cathide { + cursor: pointer; +} + +ul.cat-checklist { + height: 12em; + border-style: solid; + border-width: 1px; + overflow-y: scroll; + padding: 0 5px; + margin: 0; +} + +#bulk-titles { + display: block; + height: 12em; + border-style: solid; + border-width: 1px; + overflow-y: scroll; + padding: 0 5px; + margin: 0 0 5px; +} + +.inline-edit-row fieldset ul.cat-checklist li, +.inline-edit-row fieldset ul.cat-checklist input { + margin: 0; +} + +.inline-edit-row fieldset ul.cat-checklist label, +.inline-edit-row .catshow, +.inline-edit-row .cathide, +.inline-edit-row #bulk-titles div { + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; + font-style: normal; + font-size: 11px; +} + +table .inline-edit-row fieldset ul.cat-hover { + height: auto; + max-height: 30em; + overflow-y: auto; + position: absolute; +} + +.inline-edit-row fieldset label input.inline-edit-menu-order-input { + width: 3em; +} + +.inline-edit-row fieldset label input.inline-edit-slug-input { + width: 75%; +} + +.quick-edit-row-post fieldset label.inline-edit-status { + float: left; +} + +#bulk-titles { + line-height: 140%; +} +#bulk-titles div { + margin: 0.2em 0.3em; +} + +#bulk-titles div a { + cursor: pointer; + display: block; + float: left; + height: 10px; + margin: 3px 3px 0 -2px; + overflow: hidden; + position: relative; + text-indent: -9999px; + width: 10px; +} + + +/*------------------------------------------------------------------------------ + 11.0 - Write/Edit Post Screen +------------------------------------------------------------------------------*/ + +#titlediv { + position: relative; + margin-bottom: 20px; +} +#titlediv label { cursor: text; } + +#titlediv div.inside { + margin: 0; +} + +#poststuff #titlewrap { + border: 0; + padding: 0; + +} + +#titlediv #title { + padding: 3px 4px; + border-width: 1px; + border-style: solid; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; + font-size: 1.7em; + line-height: 100%; + width: 100%; + outline: none; +} + +#titlediv #title-prompt-text { + color: #bbb; + position: absolute; + font-size: 1.7em; + padding: 8px; +} + +#poststuff .inside-submitbox, +#side-sortables .inside-submitbox { + margin: 0 3px; + font-size: 11px; +} + +input#link_description, +input#link_url { + width: 98%; +} + +#pending { + background: 0 none; + border: 0 none; + padding: 0; + font-size: 11px; + margin-top: -1px; +} + +#edit-slug-box { + height: 1em; + margin-top: 8px; + padding: 0 7px; +} + +#editable-post-name-full { + display: none; +} + +#editable-post-name input { + width: 16em; +} + +.postarea h3 label { + float: left; +} + +.postarea #add-media-button { + float: right; + margin: 7px 0pt 0pt; + position: relative; + right: 10px; +} + +#poststuff #editor-toolbar { + height: 30px; +} + +.wp_themeSkin tr.mceFirst td.mceToolbar { + border-width: 0 0 1px; + border-style: none none solid; +} + +#edButtonPreview, +#edButtonHTML { + height: 18px; + margin: 5px 5px 0 0; + padding: 4px 5px 2px; + float: right; + cursor: pointer; + border-width: 1px; + border-style: solid; + -moz-border-radius: 3px 3px 0 0; + -webkit-border-top-right-radius: 3px; + -webkit-border-top-left-radius: 3px; + -khtml-border-top-right-radius: 3px; + -khtml-border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} + +.js .theEditor { + color: white; +} + +#poststuff #edButtonHTML { + margin-right: 15px; +} + +#media-buttons { + cursor: default; + padding: 8px 8px 0; +} + +#media-buttons a { + cursor: pointer; + padding: 0 0 5px 10px; +} + +#media-buttons img, +#submitpost #ajax-loading, +#submitpost .ajax-loading { + vertical-align: middle; +} + +#wpcontent .ajax-loading { + visibility: hidden; +} + +.submitbox .submit { + text-align: left; + padding: 12px 10px 10px; + font-size: 11px; +} + +.submitbox .submitdelete { + border-bottom-width: 1px; + border-bottom-style: solid; + text-decoration: none; + padding: 1px 2px; +} + +.inside-submitbox #post_status { + margin: 2px 0 2px -2px; +} + +.submitbox .submit a:hover { + border-bottom-width: 1px; + border-bottom-style: solid; +} + +.submitbox .submit input { + margin-bottom: 8px; + margin-right: 4px; + padding: 6px; +} + +#post-status-select, #post-format { + line-height: 2.5em; + margin-top: 3px; +} + +/* Post Screen */ +#post-body #normal-sortables { + min-height: 50px; +} + +#post-body #advanced-sortables { + min-height: 20px; +} + +.postbox { + position: relative; + min-width: 255px; + width: 99.5%; +} + +#trackback_url { + width: 99%; +} + +#normal-sortables .postbox .submit { + background: transparent none; + border: 0 none; + float: right; + padding: 0 12px; + margin:0; +} + +#side-sortables .category-add input { + width: 94%; +} + +#side-sortables .category-add select { + width: 100%; +} + +#side-sortables .category-add input.category-add-sumbit, #post-body .category-add input.category-add input.category-add-sumbit { + width: auto; +} + +#post-body ul.category-tabs, +#post-body ul.add-menu-item-tabs { + float: left; + width: 120px; + text-align: right; + /* Negative margin for the sake of those without JS: all tabs display */ + margin: 0 -120px 0 5px; + padding: 0; +} + +#post-body ul.category-tabs li, +#post-body ul.add-menu-item-tabs li { + padding: 8px; +} + +#post-body ul.category-tabs li.tabs, +#post-body ul.add-menu-item-tabs li.tabs { + -moz-border-radius: 3px 0 0 3px; + -webkit-border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -khtml-border-top-left-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +#post-body ul.category-tabs li.tabs a, +#post-body ul.add-menu-item-tabs li.tabs a { + font-weight: bold; + text-decoration: none; +} + +.wp-tab-panel, +.categorydiv div.tabs-panel, +.customlinkdiv div.tabs-panel, +.posttypediv div.tabs-panel, +.taxonomydiv div.tabs-panel, +#linkcategorydiv div.tabs-panel { + height: 200px; + overflow: auto; + padding: 0.5em 0.9em; + border-style: solid; + border-width: 1px; +} + +.nav-menus-php .customlinkdiv div.tabs-panel, +.nav-menus-php .posttypediv div.tabs-panel, +.nav-menus-php .taxonomydiv div.tabs-panel { + height: auto; + max-height: 205px; +} + +div.tabs-panel-active { + display:block; +} + +div.tabs-panel-inactive { + display:none; +} + +#post-body .categorydiv div.tabs-panel, +.taxonomy div.tabs-panel, +#post-body #linkcategorydiv div.tabs-panel { + margin: 0 5px 0 125px; +} + +#side-sortables .category-tabs li, +#side-sortables .add-menu-item-tabs li, +.wp-tab-bar li { + display: inline; +} + +#side-sortables .category-tabs a, +#side-sortables .add-menu-item-tabs a, +.wp-tab-bar a { + text-decoration: none; +} + +#side-sortables .category-tabs, +#side-sortables .add-menu-item-tabs, +.wp-tab-bar { + margin-bottom: 3px; +} + +.categorydiv ul, +.customlinkdiv ul, +.posttypediv ul, +.taxonomydiv ul, +#linkcategorydiv ul { + list-style: none; + padding: 0; + margin: 0; +} + +#normal-sortables .postbox #replyrow .submit { + float: none; + margin: 0; + padding: 3px 7px; +} + +#side-sortables .submitbox .submit input, +#side-sortables .submitbox .submit .preview, +#side-sortables .submitbox .submit a.preview:hover { + border: 0 none; +} + +#side-sortables .inside-submitbox .insidebox, +.stuffbox .insidebox { + margin: 11px 0; +} + +#side-sortables .comments-box, +#normal-sortables .comments-box { + border: 0 none; +} +ul.category-tabs, +ul.add-menu-item-tabs, +ul.wp-tab-bar { + margin-top: 12px; +} + +#side-sortables .comments-box thead th, +#normal-sortables .comments-box thead th { + background: transparent; + padding: 0 7px 4px; + font-style: italic; +} + +ul.category-tabs li.tabs, +ul.add-menu-item-tabs li.tabs, +.wp-tab-active { + border-style: solid solid none; + border-width: 1px 1px 0; +} + +#commentsdiv img.waiting { + padding-left: 5px; +} + +#post-body .category-tabs li.tabs, +#post-body .add-menu-item-tabs li.tabs { + border-style: solid none solid solid; + border-width: 1px 0 1px 1px; + margin-right: -1px; +} + +ul.category-tabs li, +ul.add-menu-item-tabs li, +ul.wp-tab-bar li { + padding: 5px; + -moz-border-radius: 3px 3px 0 0; + -webkit-border-top-left-radius: 3px; + -webkit-border-top-right-radius: 3px; + -khtml-border-top-left-radius: 3px; + -khtml-border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +/* positioning etc. */ + +form#tags-filter { + position: relative; +} + +p.search-box { + float: right; + margin: -5px 0 0; +} + +.screen-per-page { + width: 3em; +} + +#posts-filter fieldset { + float: left; + margin: 0 1.5ex 1em 0; + padding: 0; +} + +#posts-filter fieldset legend { + padding: 0 0 .2em 1px; +} + +/* Edit posts */ + +td.post-title strong, td.plugin-title strong { + display: block; + margin-bottom: .2em; +} + +td.post-title p, td.plugin-title p { + margin: 6px 0; +} + +/* Global classes */ + +.wp-hidden-children .wp-hidden-child, +.ui-tabs-hide { + display: none; +} + +.commentlist .avatar { + vertical-align: text-top; +} + +#post-body .tagsdiv #newtag { + margin-right: 5px; + width: 16em; +} + +#side-sortables input#post_password { + width: 94% +} + +#side-sortables .tagsdiv #newtag { + width: 68%; +} + +#post-status-info { + border-width: 0 1px 1px; + border-style: none solid solid; + width: 100%; + -moz-border-radius: 0 0 6px 6px; + -webkit-border-bottom-left-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; +} + +#post-status-info td { + font-size: 11px; +} + +.autosave-info { + padding: 2px 15px 2px 2px; + text-align: right; +} + +#editorcontent #post-status-info { + border: none; +} + +#post-body .wp_themeSkin .mceStatusbar a.mceResize { + display: block; + background: transparent url(../images/resize.gif) no-repeat scroll right bottom; + width: 12px; + cursor: se-resize; + margin: 0 2px; + position: relative; + top: 22px; +} + +#wp-word-count { + display: block; + padding: 2px 7px; +} + +#timestampdiv select { + height: 20px; + line-height: 14px; + padding: 0; + vertical-align: top; +} + +#jj, #hh, #mn { + width: 2em; + padding: 1px; + font-size: 12px; +} + +#aa { + width: 3.4em; + padding: 1px; + font-size: 12px; +} + +.curtime #timestamp { + background-repeat: no-repeat; + background-position: left top; + padding-left: 18px; +} + +#timestampdiv { + padding-top: 5px; + line-height: 23px; +} + +#timestampdiv p { + margin: 8px 0 6px; +} + +#timestampdiv input { + border-width: 1px; + border-style: solid; +} + + +/*------------------------------------------------------------------------------ + 11.1 - Custom Fields +------------------------------------------------------------------------------*/ + +#postcustomstuff table, +#postcustomstuff input, +#postcustomstuff textarea { + border-width: 1px; + border-style: solid; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +#postcustomstuff .updatemeta, +#postcustomstuff .deletemeta { + margin: auto; +} + +#postcustomstuff thead th { + padding: 5px 8px 8px; +} + +#postcustom #postcustomstuff .submit { + border: 0 none; + float: none; + padding: 5px 8px; +} + +#side-sortables #postcustom #postcustomstuff .submit { + padding: 0 5px; +} + +#side-sortables #postcustom #postcustomstuff td.left input { + margin: 3px 3px 0; +} + +#side-sortables #postcustom #postcustomstuff #the-list textarea { + height: 85px; + margin: 3px; +} + +#postcustomstuff table { + margin: 0; + width: 100%; + border-width: 1px; + border-style: solid; + border-spacing: 0; +} + +#postcustomstuff table input, +#postcustomstuff table select, +#postcustomstuff table textarea { + width: 95%; + margin: 8px 0 8px 8px; +} + +#postcustomstuff th.left, +#postcustomstuff td.left { + width: 38%; +} + +#postcustomstuff .submit input { + width: auto; +} + +#postcustomstuff #newmeta .submit { + padding: 0 8px; +} + +#postcustomstuff table #addmetasub { + width: auto; +} + +#postcustomstuff #newmetaleft { + vertical-align: top; +} + +#postcustomstuff #newmetaleft a { + padding: 0 10px; + text-decoration: none; +} + + +/*------------------------------------------------------------------------------ + 11.2 - Post Revisions +------------------------------------------------------------------------------*/ + +table.diff { + width: 100%; +} + +table.diff col.content { + width: 50%; +} + +table.diff tr { + background-color: transparent; +} + +table.diff td, table.diff th { + padding: .5em; + font-family: Consolas, Monaco, Courier, monospace; + border: none; +} + +table.diff .diff-deletedline del, table.diff .diff-addedline ins { + text-decoration: none; +} + + +/*------------------------------------------------------------------------------ + 12.0 - Categories +------------------------------------------------------------------------------*/ + +.category-adder { + margin-left: 120px; + padding: 4px 0; +} + +.category-adder h4 { + margin: 0 0 8px; +} + +#side-sortables .category-adder { + margin: 0; +} + +#post-body .category-add input, .category-add select { + width: 30%; +} + +#side-sortables .category-add select { + width: 100%; +} + +#side-sortables .category-add input.category-add-sumbit, #post-body .category-add input.category-add input.category-add-sumbit { + width: auto; +} + +#post-body ul.category-tabs, +#post-body ul.add-menu-item-tabs { + float: left; + width: 120px; + text-align: right; + /* Negative margin for the sake of those without JS: all tabs display */ + margin: 0 -120px 0 5px; + padding: 0; +} + +#post-body ul.category-tabs li, +#post-body ul.add-menu-item-tabs li { + padding: 8px; +} + +#post-body ul.category-tabs li.tabs, +#post-body ul.add-menu-item-tabs li.tabs { + -moz-border-radius: 3px 0 0 3px; + -webkit-border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -khtml-border-top-left-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +#post-body ul.category-tabs li.tabs a, +#post-body ul.add-menu-item-tabs li.tabs a { + font-weight: bold; + text-decoration: none; +} + +.categorydiv div.tabs-panel, +.customlinkdiv div.tabs-panel, +.posttypediv div.tabs-panel, +.taxonomydiv div.tabs-panel, +#linkcategorydiv div.tabs-panel { + height: 200px; + overflow: auto; + padding: 0.5em 0.9em; + border-style: solid; + border-width: 1px; +} + +.nav-menus-php .customlinkdiv div.tabs-panel, +.nav-menus-php .posttypediv div.tabs-panel, +.nav-menus-php .taxonomydiv div.tabs-panel { + height: auto; + max-height: 205px; +} + +div.tabs-panel-active { + display:block; +} + +div.tabs-panel-inactive { + display:none; +} + +#post-body .categorydiv div.tabs-panel, +.taxonomy div.tabs-panel, +#post-body #linkcategorydiv div.tabs-panel { + margin: 0 5px 0 125px; +} + +#side-sortables .category-tabs li, +#side-sortables .add-menu-item-tabs li { + display: inline; +} + +#side-sortables .category-tabs a, +#side-sortables .add-menu-item-tabs a { + text-decoration: none; +} + +#side-sortables .category-tabs, +#side-sortables .add-menu-item-tabs { + margin-bottom: 3px; +} + +.categorydiv ul, +.customlinkdiv ul, +.posttypediv ul, +.taxonomydiv ul, +#linkcategorydiv ul { + list-style: none; + padding: 0; + margin: 0; +} + +#front-page-warning, +#front-static-pages ul, +ul.export-filters, +.inline-editor ul.cat-checklist ul, +.categorydiv ul.categorychecklist ul, +.customlinkdiv ul.categorychecklist ul, +.posttypediv ul.categorychecklist ul, +.taxonomydiv ul.categorychecklist ul, +#linkcategorydiv ul.categorychecklist ul { + margin-left: 18px; +} + +ul.categorychecklist li { + margin: 0; + padding: 0; + line-height: 19px; + word-wrap: break-word; +} + +.categorydiv .tabs-panel, +.customlinkdiv .tabs-panel, +.posttypediv .tabs-panel, +.taxonomydiv .tabs-panel { + border-width: 3px; + border-style: solid; +} + +ul.category-tabs, +ul.add-menu-item-tabs { + margin-top: 12px; +} + +ul.category-tabs li.tabs, +ul.add-menu-item-tabs li.tabs { + border-style: solid solid none; + border-width: 1px 1px 0; +} + +#post-body .category-tabs li.tabs, +#post-body .add-menu-item-tabs li.tabs { + border-style: solid none solid solid; + border-width: 1px 0 1px 1px; + margin-right: -1px; +} + +ul.category-tabs li, +ul.add-menu-item-tabs li { + padding: 5px; + -moz-border-radius: 3px 3px 0 0; + -webkit-border-top-left-radius: 3px; + -webkit-border-top-right-radius: 3px; + -khtml-border-top-left-radius: 3px; + -khtml-border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +.form-wrap { + margin: 10px 0; + width: 97%; +} + +.form-wrap p, +.form-wrap label { + font-size: 11px; +} + +.form-wrap label { + display: block; + padding: 2px; + font-size: 12px; +} + +.form-field input, +.form-field textarea { + border-style: solid; + border-width: 1px; + width: 95%; +} + +p.description, +.form-wrap p { + margin: 2px 0 5px; +} + +p.help, +p.description, +span.description, +.form-wrap p { + font-size: 12px; + font-style: italic; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; +} + +.form-wrap .form-field { + margin: 0 0 10px; + padding: 8px; +} + +.col-wrap h3 { + margin: 12px 0; + font-size: 1.1em; +} + +.col-wrap p.submit { + margin-top: -10px; +} + + +/*------------------------------------------------------------------------------ + 13.0 - Tags +------------------------------------------------------------------------------*/ + +.taghint { + color: #aaa; + margin: 15px 0 -24px 12px; +} + +#poststuff .tagsdiv .howto { + margin: 0 0 6px 8px; +} + +.ajaxtag .newtag { + background: transparent; + position: relative; +} + +.tagsdiv .newtag { + width: 180px; +} + +.tagsdiv .the-tags { + display: block; + height: 60px; + margin: 0 auto; + overflow: auto; + width: 260px; +} + +#post-body-content .tagsdiv .the-tags { + margin: 0 5px; +} + +p.popular-tags { + -moz-border-radius: 8px; + -khtml-border-radius: 8px; + -webkit-border-radius: 8px; + border-radius: 8px; + border-width: 1px; + border-style: solid; + line-height: 2em; + padding: 8px 12px 12px; + text-align: justify; +} + +p.popular-tags a { + padding: 0 3px; +} + +.tagcloud { + width: 97%; + margin: 0 0 40px; + text-align: justify; +} + +.tagcloud h3 { + margin: 2px 0 12px; +} + +.ac_results { + padding: 0; + margin: 0; + list-style: none; + position: absolute; + z-index: 10000; + display: none; + border-width: 1px; + border-style: solid; +} + +.ac_results li { + padding: 2px 5px; + white-space: nowrap; + text-align: left; +} + +.ac_over { + cursor: pointer; +} + +.ac_match { + text-decoration: underline; +} + + +/*------------------------------------------------------------------------------ + 14.0 - Media Screen +------------------------------------------------------------------------------*/ + +#wpbody-content #media-items .describe { + border-collapse: collapse; + width: 100%; + border-top-style: solid; + border-top-width: 1px; + clear: both; + cursor: default; + padding: 5px; +} + +#wpbody-content .describe th { + vertical-align: top; + text-align: left; + padding: 10px; + width: 140px; +} + +#wpbody-content .describe .media-item-info tr { + background-color: transparent; +} + +#wpbody-content .describe .media-item-info td { + padding: 4px 10px 0; +} + +.describe .media-item-info .A1B1 { + padding: 0 0 0 10px; +} + +#wpbody-content .filename { + padding: 0 10px; +} + +#wpbody-content .media-item .thumbnail { + max-height: 128px; + max-width: 128px; +} + +#wpbody-content #async-upload-wrap a { + display: none; +} + +.media-upload-form td label { + margin-right: 6px; + margin-left: 2px; +} + +.media-upload-form .align .field label { + display: inline; + padding: 0 0 0 22px; + margin: 0 1em 0 0; + font-weight: bold; +} + +.media-upload-form tr.image-size label { + margin: 0 0 0 3px; + font-weight: bold; +} + +.media-upload-form th.label label { + font-weight: bold; + margin: 0.5em; + font-size: 13px; +} + +.media-upload-form th.label label span { + padding: 0 5px; +} + +abbr.required { + border: medium none; + text-decoration: none; +} + +#wpbody-content .describe input[type="text"], +#wpbody-content .describe textarea { + width: 460px; +} + +#wpbody-content .describe p.help { + margin: 0; + padding: 0 0 0 5px; +} + +.media-item .error-div a.dismiss, +.describe-toggle-on, +.describe-toggle-off { + display: block; + line-height: 36px; + float: right; + margin-right: 20px; +} + +.describe-toggle-off { + display: none; +} + +#wpbody-content .media-item { + border-bottom-style: solid; + border-bottom-width: 1px; + min-height: 36px; + position: relative; + width: 100%; +} + +#wpbody-content .media-single .media-item { + border-bottom-style: none; + border-bottom-width: 0; +} + +#wpbody-content #media-items { + border-style: solid solid none; + border-width: 1px; + width: 670px; +} + +#wpbody-content #media-items .filename { + line-height: 36px; + overflow: hidden; +} + +.media-item .error-div { + padding-left: 10px; +} + +.media-item .pinkynail { + float: left; + margin: 2px; + max-width: 40px; + max-height: 32px; +} + +.media-item .startopen, +.media-item .startclosed { + display: none; +} + +.media-item .original { + position: relative; + height: 34px; + width: 503px; +} + +.media-item .percent { + font-weight: bold; +} + +.crunching { + display: block; + line-height: 32px; + text-align: right; + margin-right: 5px; +} + +.progress { + position: relative; + margin-bottom: -36px; + height: 36px; +} + +.bar { + width: 0; + height: 100%; + border-right-width: 3px; + border-right-style: solid; +} + +.upload-php .fixed .column-parent { + width: 25%; +} + + +/*------------------------------------------------------------------------------ + 14.1 - Media Uploader +------------------------------------------------------------------------------*/ + +.find-box { + width: 500px; + height: 300px; + overflow: hidden; + padding: 33px 5px 40px; + position: absolute; + z-index: 1000; +} + +.find-box-head { + cursor: move; + font-weight: bold; + height: 2em; + line-height: 2em; + padding: 1px 12px; + position: absolute; + top: 5px; + width: 100%; +} + +.find-box-inside { + overflow: auto; + width: 100%; + height: 100%; +} + +.find-box-search { + padding: 12px; + border-width: 1px; + border-style: none none solid; +} + +#find-posts-response { + margin: 8px 0; + padding: 0 1px; +} + +#find-posts-response table { + width: 100%; +} + +#find-posts-response .found-radio { + padding: 5px 0 0 8px; + width: 15px; +} + +.find-box-buttons { + width: 480px; + margin: 8px; +} + +.find-box-search label { + padding-right: 6px; +} + +.find-box #resize-se { + position: absolute; + right: 1px; + bottom: 1px; +} + +/* favorite-actions */ +#favorite-actions { + float: right; + margin: 11px 12px 0; + min-width: 130px; + position: relative; +} + +#favorite-first { + -moz-border-radius: 12px; + -khtml-border-radius: 12px; + -webkit-border-radius: 12px; + border-radius: 12px; + line-height: 15px; + padding: 3px 30px 4px 12px; + border-width: 1px; + border-style: solid; +} + +#favorite-inside { + margin: 0 0 0 0px; + padding: 2px 1px; + border-width: 1px; + border-style: solid; + position: absolute; + z-index: 11; + display: none; + -moz-border-radius: 0 0 12px 12px; + -webkit-border-bottom-right-radius: 12px; + -webkit-border-bottom-left-radius: 12px; + -khtml-border-bottom-right-radius: 12px; + -khtml-border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; + border-bottom-left-radius: 12px; +} + +#favorite-actions a { + display: block; + text-decoration: none; + font-size: 11px; +} + +#favorite-inside a { + padding: 3px 5px 3px 10px; +} + +#favorite-toggle { + height: 22px; + position: absolute; + right: 0; + top: 1px; + width: 28px; +} + +#favorite-actions .slide-down { + -moz-border-radius: 12px 12px 0 0; + -webkit-border-bottom-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 0; + -khtml-border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-bottom: none; +} + +ul#dismissed-updates { + display: none; +} + +form.upgrade { + margin-top: 8px; +} + +form.upgrade .hint { + font-style: italic; + font-size: 85%; + margin: -0.5em 0 2em 0; +} + +#poststuff .inside .the-tagcloud { + margin: 5px 0 10px; + padding: 8px; + border-width: 1px; + border-style: solid; + line-height: 1.8em; + word-spacing: 3px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +br.clear { + height: 2px; + line-height: 2px; +} + +.swfupload { + margin: 5px 10px; + vertical-align: middle; +} + + +/*------------------------------------------------------------------------------ + 14.2 - Image Editor +------------------------------------------------------------------------------*/ + +.describe .image-editor { + vertical-align: top; +} + +.imgedit-wrap { + position: relative; +} + +.imgedit-settings p { + margin: 8px 0; +} + +.describe .imgedit-wrap table td { + vertical-align: top; + padding-top: 0; +} + +.imgedit-wrap p, +.describe .imgedit-wrap table td { + font-size: 11px; + line-height: 18px; +} + +.describe .imgedit-wrap table td.imgedit-settings { + padding: 0 5px; +} + +td.imgedit-settings input { + vertical-align: middle; +} + +.imgedit-wait { + position: absolute; + top: 0; + background: #FFFFFF url(../images/wpspin_light.gif) no-repeat scroll 22px 10px; + opacity: 0.7; + filter: alpha(opacity=70); + width: 100%; + height: 500px; + display: none; +} + +.media-disabled, +.imgedit-settings .disabled { + color: grey; +} + +.imgedit-wait-spin { + padding: 0 4px 4px; + vertical-align: bottom; + visibility: hidden; +} + +.imgedit-menu { + margin: 0 0 12px; + min-width: 300px; +} + +.imgedit-menu div { + float: left; + width: 32px; + height: 32px; + -moz-border-radius: 4px; + -khtml-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + border-width: 1px; + border-style: solid; +} + +.imgedit-crop-wrap { + position: relative; +} + +.imgedit-crop { + background: transparent url(../images/imgedit-icons.png) no-repeat scroll -9px -31px; + margin: 0 8px 0 0; +} + +.imgedit-crop.disabled:hover { + background-position: -9px -31px; +} + +.imgedit-crop:hover { + background-position: -9px -1px; +} + +.imgedit-rleft { + background: transparent url(../images/imgedit-icons.png) no-repeat scroll -46px -31px; + margin: 0 3px; +} + +.imgedit-rleft.disabled:hover { + background-position: -46px -31px; +} + +.imgedit-rleft:hover { + background-position: -46px -1px; +} + +.imgedit-rright { + background: transparent url(../images/imgedit-icons.png) no-repeat scroll -77px -31px; + margin: 0 8px 0 3px; +} + +.imgedit-rright.disabled:hover { + background-position: -77px -31px; +} + +.imgedit-rright:hover { + background-position: -77px -1px; +} + +.imgedit-flipv { + background: transparent url(../images/imgedit-icons.png) no-repeat scroll -115px -31px; + margin: 0 3px; +} + +.imgedit-flipv.disabled:hover { + background-position: -115px -31px; +} + +.imgedit-flipv:hover { + background-position: -115px -1px; +} + +.imgedit-fliph { + background: transparent url(../images/imgedit-icons.png) no-repeat scroll -147px -31px; + margin: 0 8px 0 3px; +} + +.imgedit-fliph.disabled:hover { + background-position: -147px -31px; +} + +.imgedit-fliph:hover { + background-position: -147px -1px; +} + +.imgedit-undo { + background: transparent url(../images/imgedit-icons.png) no-repeat scroll -184px -31px; + margin: 0 3px; +} + +.imgedit-undo.disabled:hover { + background-position: -184px -31px; +} + +.imgedit-undo:hover { + background-position: -184px -1px; +} + +.imgedit-redo { + background: transparent url(../images/imgedit-icons.png) no-repeat scroll -215px -31px; + margin: 0 8px 0 3px; +} + +.imgedit-redo.disabled:hover { + background-position: -215px -31px; +} + +.imgedit-redo:hover { + background-position: -215px -1px; +} + +.imgedit-applyto img { + margin: 0 8px 0 0; +} + +.imgedit-group-top { + margin: 5px 0; +} + +.imgedit-applyto .imgedit-label { + padding: 2px 0 0; + display: block; +} + +.imgedit-help { + display: none; + font-style: italic; + margin-bottom: 8px; +} + +.imgedit-help ul li { + font-size: 11px; +} + +a.imgedit-help-toggle { + text-decoration: none; +} + +#wpbody-content .imgedit-response div { + width: 600px; + margin: 8px; +} + +.form-table td.imgedit-response { + padding: 0; +} + +.imgedit-submit { + margin: 8px 0; +} + +.imgedit-submit-btn { + margin-left: 20px; +} + +.imgedit-wrap .nowrap { + white-space: nowrap; +} + +span.imgedit-scale-warn { + color: red; + font-size: 20px; + font-style: normal; + visibility: hidden; + vertical-align: middle; +} + +.imgedit-group { + border-width: 1px; + border-style: solid; + -moz-border-radius: 8px; + -khtml-border-radius: 8px; + -webkit-border-radius: 8px; + border-radius: 8px; + margin-bottom: 8px; + padding: 2px 10px; +} + + +/*------------------------------------------------------------------------------ + 15.0 - Comments Screen +------------------------------------------------------------------------------*/ + +.form-table { + border-collapse: collapse; + margin-top: 0.5em; + width: 100%; + margin-bottom: -8px; + clear: both; +} + +.form-table td { + margin-bottom: 9px; + padding: 8px 10px; + line-height: 20px; + font-size: 11px; +} + +.form-table th, +.form-wrap label { + font-weight: normal; + text-shadow: rgba(255,255,255,1) 0 1px 0; +} + +.form-table th { + vertical-align: top; + text-align: left; + padding: 10px; + width: 200px; +} + +.form-table th.th-full { + width: auto; +} + +.form-table div.color-option { + display: block; + clear: both; + margin-top: 12px; +} + +.form-table input.tog { + margin-top: 2px; + margin-right: 2px; + float: left; +} + +.form-table td p { + margin-top: 4px; +} + +.form-table table.color-palette { + vertical-align: bottom; + float: left; + margin: -12px 3px 11px; +} + +.form-table .color-palette td { + border-width: 1px 1px 0; + border-style: solid solid none; + height: 10px; + line-height: 20px; + width: 10px; +} + +.commentlist li { + padding: 1em 1em .2em; + margin: 0; + border-bottom-width: 1px; + border-bottom-style: solid; +} + +.commentlist li li { + border-bottom: 0; + padding: 0; +} + +.commentlist p { + padding: 0; + margin: 0 0 .8em; +} + +/* reply to comments */ +#replyrow { + font-size: 11px; +} + +#replyrow input { + border-width: 1px; + border-style: solid; +} + +#replyrow td { + padding: 2px; +} + +#replyrow #editorcontainer { + border: 0 none; +} + +#replysubmit { + margin: 0; + padding: 3px 7px; + text-align:center; +} + +#replysubmit img.waiting, +.inline-edit-save img.waiting { + padding: 4px 10px 0; + vertical-align: top; + float: right; +} + +#replysubmit .button { + margin-right: 5px; +} + +#replysubmit .error { + color:red; + line-height:21px; + text-align:center; + vertical-align:center; +} + +#replyrow #editor-toolbar { + display: none; +} + +#replyhead { + font-size: 12px; + font-weight: bold; + padding: 2px 10px 4px; +} + +#edithead .inside { + float: left; + padding: 3px 0 2px 5px; + margin: 0; + text-align: center; + font-size: 11px; +} + +#edithead .inside input { + width: 180px; + font-size: 11px; +} + +#edithead label { + padding: 2px 0; +} + +#replycontainer { + padding: 5px; + border: 0 none; + height: 120px; + overflow: hidden; + position: relative; +} + +#replycontent { + resize: none; + margin: 0; + width: 100%; + height: 100%; + padding: 0; + line-height: 150%; + border: 0 none; + outline: none; + font-size: 12px; +} + +#replyrow #ed_reply_toolbar { + margin: 0; + padding: 2px 3px; +} + +.comment-ays { + margin-bottom: 0; + border-style: solid; + border-width: 1px; +} + +.comment-ays th { + border-right-style: solid; + border-right-width: 1px; +} + +.trash-undo-inside, +.spam-undo-inside { + margin: 1px 8px 1px 0; + line-height: 16px; +} + +.spam-undo-inside .avatar, +.trash-undo-inside .avatar { + height: 20px; + width: 20px; + margin-right: 8px; + vertical-align: middle; +} + +.stuffbox .editcomment { + clear: none; +} + +#comment-status-radio p { + margin: 3px 0 5px; +} + +#comment-status-radio input { + margin: 2px 3px 5px 0; + vertical-align: middle; +} + +#comment-status-radio label { + padding: 5px 0; +} + +.commentlist .avatar { + vertical-align: text-top; +} + + +/*------------------------------------------------------------------------------ + 16.0 - Themes +------------------------------------------------------------------------------*/ + +.theme-install-php .tablenav { + height:auto; +} + +table#availablethemes { + border-spacing: 0; + border-width: 1px 0; + border-style: solid none; + margin: 10px auto; + width: 100%; +} + +table#availablethemes .no-items td{ + border-width:0; + padding:5px; +} + +td.available-theme { + vertical-align: top; + width: 240px; + margin: 0; + padding: 20px; + text-align: left; +} + +table#availablethemes td { + border-width: 0 1px 1px; + border-style: none solid solid; +} + +table#availablethemes td.right, +table#availablethemes td.left { + border-right: 0 none; + border-left: 0 none; +} + +table#availablethemes td.bottom { + border-bottom: 0 none; +} + +.available-theme a.screenshot { + width: 240px; + height: 180px; + display: block; + border-width: 1px; + border-style: solid; + margin-bottom: 10px; + overflow: hidden; +} + +.available-theme img { + width: 240px; +} + +.available-theme h3 { + margin: 15px 0 5px; +} + +#current-theme { + margin: 1em 0 1.5em; +} + +#current-theme a { + border-bottom: none; +} + +#current-theme h3 { + font-size: 17px; + font-weight: normal; + margin: 0; +} + +#current-theme .theme-description { + margin-top: 5px; +} + +#current-theme img { + float: left; + border-width: 1px; + border-style: solid; + margin-right: 1em; + margin-bottom: 1.5em; + width: 150px; +} + +.theme-options span { + text-transform: uppercase; + font-size: 13px; +} + +.theme-options a { + font-size: 15px; +} + +#TB_window #TB_title a.tb-theme-preview-link, +#TB_window #TB_title a.tb-theme-preview-link:visited { + font-weight: bold; + text-decoration: none; +} + +#TB_window #TB_title { + background-color: #222; + color: #cfcfcf; +} + +#broken-themes { + text-align: left; + width: 50%; + border-spacing: 3px; + padding: 3px; +} + +.theme-install-php h4 { + margin: 2.5em 0 8px; +} + + +/*------------------------------------------------------------------------------ + 16.1 - Custom Header Screen +------------------------------------------------------------------------------*/ + +.appearance_page_custom-header #headimg { + border: 1px solid #DFDFDF; + min-height: 100px; + width: 100%; +} + +.appearance_page_custom-header #upload-form p label { + font-size: 11px; +} + +.appearance_page_custom-header #available-headers .default-header { + float: left; + margin: 0 20px 20px 0; +} + +.appearance_page_custom-header #available-headers label input { + margin-right: 10px; +} + +.appearance_page_custom-header #available-headers label img { + vertical-align: middle; +} + + +/*------------------------------------------------------------------------------ + 16.2 - Custom Background Screen +------------------------------------------------------------------------------*/ + +div#custom-background-image { + min-height: 100px; + border: 1px solid #dfdfdf; +} + +div#custom-background-image img { + max-width: 400px; + max-height: 300px; +} + +#custom-background label { + padding-right: 15px; +} + + +/*------------------------------------------------------------------------------ + 16.3 - Tabbed Admin Screen Interface (Experimental) +------------------------------------------------------------------------------*/ + +.nav-tab { + border-style: solid; + border-color: #ccc #ccc #f9f9f9; + border-width: 1px 1px 0; + color: #c1c1c1; + text-shadow: rgba(255,255,255,1) 0 1px 0; + font-size: 12px; + line-height: 16px; + display: inline-block; + padding: 4px 14px 6px; + text-decoration: none; + margin: 0 6px -1px 0; + -moz-border-radius: 5px 5px 0 0; + -webkit-border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + -khtml-border-top-left-radius: 5px; + -khtml-border-top-right-radius: 5px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.nav-tab-active { + border-width: 1px; + color: #464646; +} + +h2.nav-tab-wrapper, h3.nav-tab-wrapper { + border-bottom: 1px solid #ccc; + padding-bottom: 0; +} + +h2 .nav-tab { + padding: 4px 20px 6px; + font: italic normal normal 24px/35px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; +} + + +/*------------------------------------------------------------------------------ + 17.0 - Plugins +------------------------------------------------------------------------------*/ + +.plugins .name, +#pass-strength-result.strong, +#pass-strength-result.short, +.button-highlighted, +input.button-highlighted, +#quicktags #ed_strong, +#ed_reply_toolbar #ed_reply_strong { + font-weight: bold; +} + +.plugins p { + margin: 0 4px; + padding: 0; +} + +.plugins .desc p { + margin: 0 0 8px; +} + +.plugins td.desc { + line-height: 1.5em; +} + +.plugins .desc ul, +.plugins .desc ol { + margin: 0 0 0 2em; +} + +.plugins .desc ul { + list-style-type: disc; +} + +.plugins .row-actions-visible { + padding: 0; +} + +.plugins tbody th.check-column { + padding: 7px 0; +} + +.plugins td, .plugins th { + border-bottom: 0 none; +} + +.plugins .inactive td, +.plugins .inactive th, +.plugins .active td, +.plugins .active th { + border-top-style: solid; + border-top-width: 1px; + padding: 5px 7px 0; +} + +#wpbody-content .plugins .plugin-title, #wpbody-content .plugins .theme-title { + padding-right: 12px; + white-space:nowrap; +} + +.plugins .second, .plugins .row-actions-visible { + padding: 0 0 5px; +} + +.plugins-php .widefat tfoot th, +.plugins-php .widefat tfoot td { + border-top-style: solid; + border-top-width: 1px; +} + +.plugin-update-tr .update-message { + margin: 5px; + padding: 3px 5px; + border-width: 1px; + border-style: solid; + -moz-border-radius: 5px; + -khtml-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +.plugin-install-php h4 { + margin: 2.5em 0 8px; +} + + +/*------------------------------------------------------------------------------ + 18.0 - Users +------------------------------------------------------------------------------*/ + +#profile-page .form-table textarea { + width: 500px; + margin-bottom: 6px; +} + +#profile-page .form-table #rich_editing { + margin-right: 5px +} + +#your-profile legend { + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-size: 22px; +} + +#your-profile #rich_editing { + border: none; +} + +#display_name { + width: 15em; +} + +#createuser .form-field input { + width: 25em; +} + +/*------------------------------------------------------------------------------ + 19.0 - Tools +------------------------------------------------------------------------------*/ + + + + +/*------------------------------------------------------------------------------ + 20.0 - Settings +------------------------------------------------------------------------------*/ + +#utc-time, #local-time { + padding-left: 25px; + font-style: italic; + font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif; +} + +.defaultavatarpicker .avatar { + margin: 2px 0; + vertical-align: middle; +} + + +/*------------------------------------------------------------------------------ + 21.0 - Admin Footer +------------------------------------------------------------------------------*/ + +#footer { + margin-top: -46px; + border-top: 1px; + border-style: solid; +} + +#footer, +#footer a { + font-size: 12px; + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-style: italic; +} + +#footer p { + margin: 0; + padding: 15px; + line-height: 15px; +} + +#footer a { + text-decoration: none; +} + +#footer a:hover { + text-decoration: underline; +} + + +/*------------------------------------------------------------------------------ + 22.0 - Misc +------------------------------------------------------------------------------*/ + +#excerpt, .attachmentlinks { + margin: 0; + height: 4em; + width: 98%; +} + +#template div { + margin-right: 190px; +} + +p.pagenav { + margin: 0; + display: inline; +} + +.pagenav span { + font-weight: bold; + margin: 0 6px; +} + +.row-title { + font-size: 12px !important; + font-weight: bold; +} + +.column-author img, .column-username img { + float: left; + margin-right: 10px; + margin-top: 3px; +} + +.row-actions { + visibility: hidden; + padding: 2px 0 0; +} + +tr:hover .row-actions, +div.comment-item:hover .row-actions { + visibility: visible; +} + +.row-actions-visible { + padding: 2px 0 0; +} + +.form-table .pre { + padding: 8px; + margin: 0; +} + +table.form-table td .updated { + font-size: 13px; +} + + +.tagchecklist { + margin-left: 14px; + font-size: 12px; + overflow: auto; +} +.tagchecklist strong { + margin-left: -8px; + position: absolute; +} +.tagchecklist span { + margin-right: 25px; + display: block; + float: left; + font-size: 11px; + line-height: 1.8em; + white-space: nowrap; + cursor: default; +} +.tagchecklist span a { + margin: 6px 0pt 0pt -9px; + cursor: pointer; + width: 10px; + height: 10px; + display: block; + float: left; + text-indent: -9999px; + overflow: hidden; + position: absolute; +} + + +#poststuff h2 { + margin-top: 20px; + font-size: 1.5em; + margin-bottom: 15px; + padding: 0 0 3px; + clear: left; +} +#poststuff h3, +.metabox-holder h3 { + font-size: 12px; + font-weight: bold; + padding: 7px 9px; + margin: 0; + line-height: 1; +} +#poststuff .inside, +#poststuff .inside p { + font-size: 11px; + margin: 6px 6px 8px; +} +#poststuff .inside .submitbox p { + margin: 1em 0; +} +#post-visibility-select, #post-formats-select { + line-height: 1.5em; + margin-top: 3px; +} +#poststuff #submitdiv .inside { + margin: 0; +} +#titlediv, #poststuff .postarea { + margin-bottom: 20px; +} + + +td.post-title strong, td.plugin-title strong { + display: block; + margin-bottom: .2em; +} +td.post-title p, td.plugin-title p { + margin: 6px 0; +} + + +.wp-hidden-children .wp-hidden-child, +.ui-tabs-hide { + display: none; +} + +#templateside ul li a { + text-decoration: none; +} + + +.tool-box { + margin: 15px 0 35px; +} +.tool-box .buttons { + margin: 15px 0; +} +.tool-box .title { + margin: 8px 0; + font: 18px/24px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; +} + + +.pressthis a { + font-size: 1.2em; +} + + +#sidemenu { + margin: -30px 15px 0 315px; + list-style: none; + position: relative; + float: right; + padding-left: 10px; + font-size: 12px; +} +#sidemenu a { + padding: 0 7px; + display: block; + float: left; + line-height: 28px; + border-top-width: 1px; + border-top-style: solid; + border-bottom-width: 1px; + border-bottom-style: solid; +} +#sidemenu li { + display: inline; + line-height: 200%; + list-style: none; + text-align: center; + white-space: nowrap; + margin: 0; + padding: 0; +} +#sidemenu a.current { + font-weight: normal; + padding-left: 6px; + padding-right: 6px; + -moz-border-radius: 4px 4px 0 0; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -khtml-border-top-left-radius: 4px; + -khtml-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-width: 1px; + border-style: solid; +} +#sidemenu li a .count-0 { + display: none; +} + +#poststuff .inside .the-tagcloud { + margin: 5px 0 10px; + padding: 8px; + border-width: 1px; + border-style: solid; + line-height: 1.8em; + word-spacing: 3px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; +} + +.plugin-install #description, .plugin-install-network #description { + width: 60%; +} + +table .vers, +table .column-visible, +table .column-rating { + text-align: left; +} + + +/* Scrollbar fix for bulk upgrade iframe */ +body.iframe { + height: 98%; +} + + +/*------------------------------------------------------------------------------ + 23.0 - Dead +------------------------------------------------------------------------------*/ + +/* - Not used anywhere in WordPress - verify and then deprecate +------------------------------------------------------------------------------*/ +.anchors { + margin: 10px 20px 10px 20px; +} +div.nav { + height: 2em; + padding: 7px 10px; + vertical-align: text-top; + margin: 5px 0; +} +.nav .button-secondary { + padding: 2px 4px; +} +* html #themeselect { + padding: 0 3px; + height: 22px; +} +.settings-toggle { + text-align: right; + margin: 5px 7px 15px 0; + font-size: 12px; +} +.settings-toggle h3 { + margin: 0; +} +form#tags-filter { + position: relative; +} + +/* - Only used once or twice in all of WP - deprecate for global style +------------------------------------------------------------------------------*/ +td.media-icon { + text-align: center; + width: 80px; + padding-top: 8px; + padding-bottom: 8px; +} + +td.media-icon img { + max-width: 80px; + max-height: 60px; +} +.screen-per-page { + width: 3em; +} +* html #template div {margin-right: 0;} + +.list-ajax-loading { + float: right; + margin-right: 9px; + margin-top: -1px; +} +.tablenav .list-ajax-loading { + margin-top: 7px; +} +#howto { + font-size: 11px; + margin: 0 5px; + display: block; +} +.import-system {font-size: 16px;} +#namediv table { + width: 100%; +} +#namediv td.first { + width: 10px; + white-space: nowrap; +} +#namediv input { + width: 98%; +} +#namediv p { + margin: 10px 0; +} +#submitdiv h3 { + margin-bottom: 0 !important; +} + +/* - Used - but could/should be deprecated with a CSS reset +------------------------------------------------------------------------------*/ +.zerosize { + height: 0; + width: 0; + margin: 0; + border: 0; + padding: 0; + overflow: hidden; + position: absolute; +} +br.clear { + height: 2px; + line-height: 2px; +} +.checkbox { + border: none; + margin: 0; + padding: 0; +} +#content { + margin: 0; + width: 100%; +} +fieldset { + border: 0; + padding: 0; + margin: 0; +} +#linksubmitdiv div.inside, +div.inside { + padding: 0; + margin: 0; +} +.post-categories { + display: inline; + margin: 0; + padding: 0; +} +.post-categories li { + display: inline; +} diff --git a/src/wp-admin/custom-background.php b/src/wp-admin/custom-background.php new file mode 100644 index 00000000..530cb9e4 --- /dev/null +++ b/src/wp-admin/custom-background.php @@ -0,0 +1,360 @@ +admin_header_callback = $admin_header_callback; + $this->admin_image_div_callback = $admin_image_div_callback; + } + + /** + * Set up the hooks for the Custom Background admin page. + * + * @since 3.0.0 + */ + function init() { + if ( ! current_user_can('edit_theme_options') ) + return; + + $this->page = $page = add_theme_page(__('Background'), __('Background'), 'edit_theme_options', 'custom-background', array(&$this, 'admin_page')); + + add_action("load-$page", array(&$this, 'admin_load')); + add_action("load-$page", array(&$this, 'take_action'), 49); + add_action("load-$page", array(&$this, 'handle_upload'), 49); + + if ( $this->admin_header_callback ) + add_action("admin_head-$page", $this->admin_header_callback, 51); + } + + /** + * Set up the enqueue for the CSS & JavaScript files. + * + * @since 3.0.0 + */ + function admin_load() { + add_contextual_help( $this->page, '

' . __( 'You can customize the look of your site without touching any of your theme’s code by using a custom background. Your background can be an image or a color.' ) . '

' . + '

' . __( 'To use a background image, simply upload it, then choose your display options below. You can display a single instance of your image, or tile it to fill the screen. You can have your background fixed in place, so your site content moves on top of it, or you can have it scroll with your site.' ) . '

' . + '

' . __( 'You can also choose a background color. If you know the hexadecimal code for the color you want, enter it in the Color field. If not, click on the Select a Color link, and a color picker will allow you to choose the exact shade you want.' ) . '

' . + '

' . __( 'Don’t forget to click on the Save Changes button when you are finished.' ) . '

' . + '

' . __( 'For more information:' ) . '

' . + '

' . __( 'Documentation on Custom Background' ) . '

' . + '

' . __( 'Support Forums' ) . '

' ); + wp_enqueue_script('custom-background'); + wp_enqueue_style('farbtastic'); + } + + /** + * Execute custom background modification. + * + * @since 3.0.0 + */ + function take_action() { + + if ( empty($_POST) ) + return; + + if ( isset($_POST['reset-background']) ) { + check_admin_referer('custom-background-reset', '_wpnonce-custom-background-reset'); + remove_theme_mod('background_image'); + remove_theme_mod('background_image_thumb'); + $this->updated = true; + return; + } + + if ( isset($_POST['remove-background']) ) { + // @TODO: Uploaded files are not removed here. + check_admin_referer('custom-background-remove', '_wpnonce-custom-background-remove'); + set_theme_mod('background_image', ''); + set_theme_mod('background_image_thumb', ''); + $this->updated = true; + return; + } + + if ( isset($_POST['background-repeat']) ) { + check_admin_referer('custom-background'); + if ( in_array($_POST['background-repeat'], array('repeat', 'no-repeat', 'repeat-x', 'repeat-y')) ) + $repeat = $_POST['background-repeat']; + else + $repeat = 'repeat'; + set_theme_mod('background_repeat', $repeat); + } + + if ( isset($_POST['background-position-x']) ) { + check_admin_referer('custom-background'); + if ( in_array($_POST['background-position-x'], array('center', 'right', 'left')) ) + $position = $_POST['background-position-x']; + else + $position = 'left'; + set_theme_mod('background_position_x', $position); + } + + if ( isset($_POST['background-attachment']) ) { + check_admin_referer('custom-background'); + if ( in_array($_POST['background-attachment'], array('fixed', 'scroll')) ) + $attachment = $_POST['background-attachment']; + else + $attachment = 'fixed'; + set_theme_mod('background_attachment', $attachment); + } + + if ( isset($_POST['background-color']) ) { + check_admin_referer('custom-background'); + $color = preg_replace('/[^0-9a-fA-F]/', '', $_POST['background-color']); + if ( strlen($color) == 6 || strlen($color) == 3 ) + set_theme_mod('background_color', $color); + else + set_theme_mod('background_color', ''); + } + + $this->updated = true; + } + + /** + * Display the custom background page. + * + * @since 3.0.0 + */ + function admin_page() { +?> +
+ +

+updated) ) { ?> +
+

Visit your site to see how it looks.' ), home_url( '/' ) ); ?>

+
+admin_image_div_callback ) { + call_user_func($this->admin_image_div_callback); + } else { +?> +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + + +

+
+
+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + +
+ + +
+ + + +
+ + + +
+ +
+ false); + $file = wp_handle_upload($_FILES['import'], $overrides); + + if ( isset($file['error']) ) + wp_die( $file['error'] ); + + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $filename = basename($file); + + // Construct the object array + $object = array( + 'post_title' => $filename, + 'post_content' => $url, + 'post_mime_type' => $type, + 'guid' => $url, + 'context' => 'custom-background' + ); + + // Save the data + $id = wp_insert_attachment($object, $file); + + // Add the meta-data + wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); + + set_theme_mod('background_image', esc_url($url)); + + $thumbnail = wp_get_attachment_image_src( $id, 'thumbnail' ); + set_theme_mod('background_image_thumb', esc_url( $thumbnail[0] ) ); + + do_action('wp_create_file_in_uploads', $file, $id); // For replication + $this->updated = true; + } + +} +?> diff --git a/src/wp-admin/custom-header.php b/src/wp-admin/custom-header.php new file mode 100644 index 00000000..bf5f4157 --- /dev/null +++ b/src/wp-admin/custom-header.php @@ -0,0 +1,737 @@ +admin_header_callback = $admin_header_callback; + $this->admin_image_div_callback = $admin_image_div_callback; + } + + /** + * Set up the hooks for the Custom Header admin page. + * + * @since 2.1.0 + */ + function init() { + if ( ! current_user_can('edit_theme_options') ) + return; + + $this->page = $page = add_theme_page(__('Header'), __('Header'), 'edit_theme_options', 'custom-header', array(&$this, 'admin_page')); + + add_action("admin_print_scripts-$page", array(&$this, 'js_includes')); + add_action("admin_print_styles-$page", array(&$this, 'css_includes')); + add_action("admin_head-$page", array(&$this, 'help') ); + add_action("admin_head-$page", array(&$this, 'take_action'), 50); + add_action("admin_head-$page", array(&$this, 'js'), 50); + add_action("admin_head-$page", $this->admin_header_callback, 51); + } + + /** + * Adds contextual help. + * + * @since 3.0.0 + */ + function help() { + add_contextual_help( $this->page, '

' . __( 'You can set a custom image header for your site. Simply upload the image and crop it, and the new header will go live immediately.' ) . '

' . + '

' . __( 'If you want to discard your custom header and go back to the default included in your theme, click on the buttons to remove the custom image and restore the original header image.' ) . '

' . + '

' . __( 'Some themes come with additional header images bundled. If you see multiple images displayed, select the one you’d like and click the Save Changes button.' ) . '

' . + '

' . __( 'For more information:' ) . '

' . + '

' . __( 'Documentation on Custom Header' ) . '

' . + '

' . __( 'Support Forums' ) . '

' ); + } + + /** + * Get the current step. + * + * @since 2.6.0 + * + * @return int Current step + */ + function step() { + if ( ! isset( $_GET['step'] ) ) + return 1; + + $step = (int) $_GET['step']; + if ( $step < 1 || 3 < $step ) + $step = 1; + + return $step; + } + + /** + * Set up the enqueue for the JavaScript files. + * + * @since 2.1.0 + */ + function js_includes() { + $step = $this->step(); + + if ( ( 1 == $step || 3 == $step ) && $this->header_text() ) + wp_enqueue_script('farbtastic'); + elseif ( 2 == $step ) + wp_enqueue_script('imgareaselect'); + } + + /** + * Set up the enqueue for the CSS files + * + * @since 2.7 + */ + function css_includes() { + $step = $this->step(); + + if ( ( 1 == $step || 3 == $step ) && $this->header_text() ) + wp_enqueue_style('farbtastic'); + elseif ( 2 == $step ) + wp_enqueue_style('imgareaselect'); + } + + /** + * Check if header text is allowed + * + * @since 3.0.0 + */ + function header_text() { + if ( defined( 'NO_HEADER_TEXT' ) && NO_HEADER_TEXT ) + return false; + + return true; + } + + /** + * Execute custom header modification. + * + * @since 2.6.0 + */ + function take_action() { + if ( ! current_user_can('edit_theme_options') ) + return; + + if ( empty( $_POST ) ) + return; + + $this->updated = true; + + if ( isset( $_POST['resetheader'] ) ) { + check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); + remove_theme_mod( 'header_image' ); + return; + } + + if ( isset( $_POST['resettext'] ) ) { + check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); + remove_theme_mod('header_textcolor'); + return; + } + + if ( isset( $_POST['removeheader'] ) ) { + check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); + set_theme_mod( 'header_image', '' ); + return; + } + + if ( isset( $_POST['text-color'] ) ) { + check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); + $_POST['text-color'] = str_replace( '#', '', $_POST['text-color'] ); + if ( 'blank' == $_POST['text-color'] ) { + set_theme_mod( 'header_textcolor', 'blank' ); + } else { + $color = preg_replace('/[^0-9a-fA-F]/', '', $_POST['text-color']); + if ( strlen($color) == 6 || strlen($color) == 3 ) + set_theme_mod('header_textcolor', $color); + } + } + + if ( isset($_POST['default-header']) ) { + check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); + $this->process_default_headers(); + if ( isset($this->default_headers[$_POST['default-header']]) ) + set_theme_mod('header_image', esc_url($this->default_headers[$_POST['default-header']]['url'])); + } + } + + /** + * Process the default headers + * + * @since 3.0.0 + */ + function process_default_headers() { + global $_wp_default_headers; + + if ( !empty($this->headers) ) + return; + + if ( !isset($_wp_default_headers) ) + return; + + $this->default_headers = $_wp_default_headers; + foreach ( array_keys($this->default_headers) as $header ) { + $this->default_headers[$header]['url'] = sprintf( $this->default_headers[$header]['url'], get_template_directory_uri(), get_stylesheet_directory_uri() ); + $this->default_headers[$header]['thumbnail_url'] = sprintf( $this->default_headers[$header]['thumbnail_url'], get_template_directory_uri(), get_stylesheet_directory_uri() ); + } + } + + /** + * Display UI for selecting one of several default headers. + * + * @since 3.0.0 + */ + function show_default_header_selector() { + echo '
'; + foreach ( $this->default_headers as $header_key => $header ) { + $header_thumbnail = $header['thumbnail_url']; + $header_url = $header['url']; + $header_desc = $header['description']; + echo '
'; + echo ''; + echo '
'; + } + echo '
'; + } + + /** + * Execute Javascript depending on step. + * + * @since 2.1.0 + */ + function js() { + $step = $this->step(); + if ( ( 1 == $step || 3 == $step ) && $this->header_text() ) + $this->js_1(); + elseif ( 2 == $step ) + $this->js_2(); + } + + /** + * Display Javascript based on Step 1 and 3. + * + * @since 2.6.0 + */ + function js_1() { ?> + + + +process_default_headers(); +?> + +
+ +

+ +updated ) ) { ?> +
+

Visit your site to see how it looks.' ), home_url( '/' ) ); ?>

+
+ + +

+ + + + + + + + + + + + + + + +
+ admin_image_div_callback ) { + call_user_func( $this->admin_image_div_callback ); + } else { + ?> +
+ header_text() ) + $style = ' style="display:none;"'; + else + $style = ' style="color:#' . get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ) . ';"'; + ?> +

onclick="return false;" href="">

+
>
+
+ +
+


+ %1$d × %2$d pixels will be used as-is.' ), HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT ); ?>

+
+

+
+ + + + +

+
+
+ +
+ + + default_headers ) ) : ?> + + + + + + + + + + + + + + + + +
+ +

+ +

+ + show_default_header_selector(); + ?> +

+

+ +
+

+ +
+ + header_text() ) : ?> +

+ + + + + + + + + + + + + + + + + + + + +
+

+ + + +

+
+

+ + #blank as text color.' );?> + +

+ +
+

+ +
+ + + +
+
+ + false); + $file = wp_handle_upload($_FILES['import'], $overrides); + + if ( isset($file['error']) ) + wp_die( $file['error'], __( 'Image Upload Error' ) ); + + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $filename = basename($file); + + // Construct the object array + $object = array( + 'post_title' => $filename, + 'post_content' => $url, + 'post_mime_type' => $type, + 'guid' => $url, + 'context' => 'custom-header'); + + // Save the data + $id = wp_insert_attachment($object, $file); + + list($width, $height, $type, $attr) = getimagesize( $file ); + + if ( $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) { + // Add the meta-data + wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); + + set_theme_mod('header_image', esc_url($url)); + do_action('wp_create_file_in_uploads', $file, $id); // For replication + return $this->finished(); + } elseif ( $width > HEADER_IMAGE_WIDTH ) { + $oitar = $width / HEADER_IMAGE_WIDTH; + $image = wp_crop_image($file, 0, 0, $width, $height, HEADER_IMAGE_WIDTH, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file)); + if ( is_wp_error( $image ) ) + wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) ); + + $image = apply_filters('wp_create_file_in_uploads', $image, $id); // For replication + + $url = str_replace(basename($url), basename($image), $url); + $width = $width / $oitar; + $height = $height / $oitar; + } else { + $oitar = 1; + } + ?> + +
+ +

+ +
+

+

+ +
+ +
+ + + + + + + + + + +

+
+
+ 1 ) { + $_POST['x1'] = $_POST['x1'] * $_POST['oitar']; + $_POST['y1'] = $_POST['y1'] * $_POST['oitar']; + $_POST['width'] = $_POST['width'] * $_POST['oitar']; + $_POST['height'] = $_POST['height'] * $_POST['oitar']; + } + + $original = get_attached_file( $_POST['attachment_id'] ); + + $cropped = wp_crop_image($_POST['attachment_id'], $_POST['x1'], $_POST['y1'], $_POST['width'], $_POST['height'], HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT); + if ( is_wp_error( $cropped ) ) + wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) ); + + $cropped = apply_filters('wp_create_file_in_uploads', $cropped, $_POST['attachment_id']); // For replication + + $parent = get_post($_POST['attachment_id']); + $parent_url = $parent->guid; + $url = str_replace(basename($parent_url), basename($cropped), $parent_url); + + // Construct the object array + $object = array( + 'ID' => $_POST['attachment_id'], + 'post_title' => basename($cropped), + 'post_content' => $url, + 'post_mime_type' => 'image/jpeg', + 'guid' => $url, + 'context' => 'custom-header' + ); + + // Update the attachment + wp_insert_attachment($object, $cropped); + wp_update_attachment_metadata( $_POST['attachment_id'], wp_generate_attachment_metadata( $_POST['attachment_id'], $cropped ) ); + + set_theme_mod('header_image', $url); + + // cleanup + $medium = str_replace(basename($original), 'midsize-'.basename($original), $original); + @unlink( apply_filters( 'wp_delete_file', $medium ) ); + @unlink( apply_filters( 'wp_delete_file', $original ) ); + + return $this->finished(); + } + + /** + * Display last step of custom header image page. + * + * @since 2.1.0 + */ + function finished() { + $this->updated = true; + $this->step_1(); + } + + /** + * Display the page based on the current step. + * + * @since 2.1.0 + */ + function admin_page() { + if ( ! current_user_can('edit_theme_options') ) + wp_die(__('You do not have permission to customize headers.')); + $step = $this->step(); + if ( 1 == $step ) + $this->step_1(); + elseif ( 2 == $step ) + $this->step_2(); + elseif ( 3 == $step ) + $this->step_3(); + } + +} +?> diff --git a/src/wp-admin/edit-comments.php b/src/wp-admin/edit-comments.php new file mode 100644 index 00000000..40ef4a4d --- /dev/null +++ b/src/wp-admin/edit-comments.php @@ -0,0 +1,248 @@ +get_pagenum(); + +$doaction = $wp_list_table->current_action(); + +if ( $doaction ) { + check_admin_referer( 'bulk-comments' ); + + if ( 'delete_all' == $doaction && !empty( $_REQUEST['pagegen_timestamp'] ) ) { + $comment_status = $wpdb->escape( $_REQUEST['comment_status'] ); + $delete_time = $wpdb->escape( $_REQUEST['pagegen_timestamp'] ); + $comment_ids = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_approved = '$comment_status' AND '$delete_time' > comment_date_gmt" ); + $doaction = 'delete'; + } elseif ( isset( $_REQUEST['delete_comments'] ) ) { + $comment_ids = $_REQUEST['delete_comments']; + $doaction = ( $_REQUEST['action'] != -1 ) ? $_REQUEST['action'] : $_REQUEST['action2']; + } elseif ( isset( $_REQUEST['ids'] ) ) { + $comment_ids = array_map( 'absint', explode( ',', $_REQUEST['ids'] ) ); + } elseif ( wp_get_referer() ) { + wp_redirect( wp_get_referer() ); + exit; + } + + $approved = $unapproved = $spammed = $unspammed = $trashed = $untrashed = $deleted = 0; + + $redirect_to = remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'spammed', 'unspammed', 'approved', 'unapproved', 'ids' ), wp_get_referer() ); + $redirect_to = add_query_arg( 'paged', $pagenum, $redirect_to ); + + foreach ( $comment_ids as $comment_id ) { // Check the permissions on each + if ( !current_user_can( 'edit_comment', $comment_id ) ) + continue; + + switch ( $doaction ) { + case 'approve' : + wp_set_comment_status( $comment_id, 'approve' ); + $approved++; + break; + case 'unapprove' : + wp_set_comment_status( $comment_id, 'hold' ); + $unapproved++; + break; + case 'spam' : + wp_spam_comment( $comment_id ); + $spammed++; + break; + case 'unspam' : + wp_unspam_comment( $comment_id ); + $unspammed++; + break; + case 'trash' : + wp_trash_comment( $comment_id ); + $trashed++; + break; + case 'untrash' : + wp_untrash_comment( $comment_id ); + $untrashed++; + break; + case 'delete' : + wp_delete_comment( $comment_id ); + $deleted++; + break; + } + } + + if ( $approved ) + $redirect_to = add_query_arg( 'approved', $approved, $redirect_to ); + if ( $unapproved ) + $redirect_to = add_query_arg( 'unapproved', $unapproved, $redirect_to ); + if ( $spammed ) + $redirect_to = add_query_arg( 'spammed', $spammed, $redirect_to ); + if ( $unspammed ) + $redirect_to = add_query_arg( 'unspammed', $unspammed, $redirect_to ); + if ( $trashed ) + $redirect_to = add_query_arg( 'trashed', $trashed, $redirect_to ); + if ( $untrashed ) + $redirect_to = add_query_arg( 'untrashed', $untrashed, $redirect_to ); + if ( $deleted ) + $redirect_to = add_query_arg( 'deleted', $deleted, $redirect_to ); + if ( $trashed || $spammed ) + $redirect_to = add_query_arg( 'ids', join( ',', $comment_ids ), $redirect_to ); + + wp_redirect( $redirect_to ); + exit; +} elseif ( ! empty( $_GET['_wp_http_referer'] ) ) { + wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) ); + exit; +} + +$wp_list_table->prepare_items(); + +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +wp_enqueue_script('admin-comments'); +enqueue_comment_hotkeys_js(); + +if ( $post_id ) + $title = sprintf(__('Comments on “%s”'), wp_html_excerpt(_draft_or_post_title($post_id), 50)); +else + $title = __('Comments'); + +add_screen_option( 'per_page', array('label' => _x( 'Comments', 'comments per page (screen options)' )) ); + +add_contextual_help( $current_screen, '

' . __( 'You can manage comments made on your site similar to the way you manage Posts and other content. This screen is customizable in the same ways as other management screens, and you can act on comments using the on-hover action links or the Bulk Actions.' ) . '

' . + '

' . __( 'A yellow row means the comment is waiting for you to moderate it.' ) . '

' . + '

' . __( 'In the Author column, in addition to the author’s name, email address, and blog URL, the commenter’s IP address is shown. Clicking on this link will show you all the comments made from this IP address.' ) . '

' . + '

' . __( 'In the Comment column, above each comment it says “Submitted on,” followed by the date and time the comment was left on your site. Clicking on the date/time link will take you to that comment on your live site.' ) . '

' . + '

' . __( 'In the In Response To column, there are three elements. The text is the name of the post that inspired the comment, and links to the post editor for that entry. The “#” permalink symbol below leads to that post on your live site. The small bubble with the number in it shows how many comments that post has received. If the bubble is gray, you have moderated all comments for that post. If it is blue, there are pending comments. Clicking the bubble will filter the comments screen to show only comments on that post.' ) . '

' . + '

' . __( 'Many people take advantage of keyboard shortcuts to moderate their comments more quickly. Use the link below to learn more.' ) . '

' . + '

' . __( 'For more information:' ) . '

' . + '

' . __( 'Documentation on Comments' ) . '

' . + '

' . __( 'Documentation on Comment Spam' ) . '

' . + '

' . __( 'Documentation on Keyboard Shortcuts' ) . '

' . + '

' . __( 'Support Forums' ) . '

' +); +require_once('./admin-header.php'); +?> + +
+ +

%s', + get_edit_post_link($post_id), + wp_html_excerpt(_draft_or_post_title($post_id), 50) + ) + ); +else + echo __('Comments'); + +if ( isset($_REQUEST['s']) && $_REQUEST['s'] ) + printf( '' . sprintf( __( 'Search results for “%s”' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) ) . '' ); ?> +

+ +

' . $error_msg . '

'; +} + +if ( isset($_REQUEST['approved']) || isset($_REQUEST['deleted']) || isset($_REQUEST['trashed']) || isset($_REQUEST['untrashed']) || isset($_REQUEST['spammed']) || isset($_REQUEST['unspammed']) || isset($_REQUEST['same']) ) { + $approved = isset( $_REQUEST['approved'] ) ? (int) $_REQUEST['approved'] : 0; + $deleted = isset( $_REQUEST['deleted'] ) ? (int) $_REQUEST['deleted'] : 0; + $trashed = isset( $_REQUEST['trashed'] ) ? (int) $_REQUEST['trashed'] : 0; + $untrashed = isset( $_REQUEST['untrashed'] ) ? (int) $_REQUEST['untrashed'] : 0; + $spammed = isset( $_REQUEST['spammed'] ) ? (int) $_REQUEST['spammed'] : 0; + $unspammed = isset( $_REQUEST['unspammed'] ) ? (int) $_REQUEST['unspammed'] : 0; + $same = isset( $_REQUEST['same'] ) ? (int) $_REQUEST['same'] : 0; + + if ( $approved > 0 || $deleted > 0 || $trashed > 0 || $untrashed > 0 || $spammed > 0 || $unspammed > 0 || $same > 0 ) { + if ( $approved > 0 ) + $messages[] = sprintf( _n( '%s comment approved', '%s comments approved', $approved ), $approved ); + + if ( $spammed > 0 ) { + $ids = isset($_REQUEST['ids']) ? $_REQUEST['ids'] : 0; + $messages[] = sprintf( _n( '%s comment marked as spam.', '%s comments marked as spam.', $spammed ), $spammed ) . ' ' . __('Undo') . '
'; + } + + if ( $unspammed > 0 ) + $messages[] = sprintf( _n( '%s comment restored from the spam', '%s comments restored from the spam', $unspammed ), $unspammed ); + + if ( $trashed > 0 ) { + $ids = isset($_REQUEST['ids']) ? $_REQUEST['ids'] : 0; + $messages[] = sprintf( _n( '%s comment moved to the Trash.', '%s comments moved to the Trash.', $trashed ), $trashed ) . ' ' . __('Undo') . '
'; + } + + if ( $untrashed > 0 ) + $messages[] = sprintf( _n( '%s comment restored from the Trash', '%s comments restored from the Trash', $untrashed ), $untrashed ); + + if ( $deleted > 0 ) + $messages[] = sprintf( _n( '%s comment permanently deleted', '%s comments permanently deleted', $deleted ), $deleted ); + + if ( $same > 0 && $comment = get_comment( $same ) ) { + switch ( $comment->comment_approved ) { + case '1' : + $messages[] = __('This comment is already approved.') . ' ' . __( 'Edit comment' ) . ''; + break; + case 'trash' : + $messages[] = __( 'This comment is already in the Trash.' ) . ' ' . __( 'View Trash' ) . ''; + break; + case 'spam' : + $messages[] = __( 'This comment is already marked as spam.' ) . ' ' . __( 'Edit comment' ) . ''; + break; + } + } + + echo '

' . implode( "
\n", $messages ) . '

'; + } +} +?> + +views(); ?> + +
+ +search_box( __( 'Search Comments' ), 'comment' ); ?> + + + + + + + + + + + + + + + +display(); ?> +
+
+ +
+ + diff --git a/src/wp-admin/edit-form-advanced.php b/src/wp-admin/edit-form-advanced.php new file mode 100644 index 00000000..720e5104 --- /dev/null +++ b/src/wp-admin/edit-form-advanced.php @@ -0,0 +1,322 @@ + '', // Unused. Messages start at index 1. + 1 => sprintf( __('Post updated. View post'), esc_url( get_permalink($post_ID) ) ), + 2 => __('Custom field updated.'), + 3 => __('Custom field deleted.'), + 4 => __('Post updated.'), + /* translators: %s: date and time of the revision */ + 5 => isset($_GET['revision']) ? sprintf( __('Post restored to revision from %s'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, + 6 => sprintf( __('Post published. View post'), esc_url( get_permalink($post_ID) ) ), + 7 => __('Post saved.'), + 8 => sprintf( __('Post submitted. Preview post'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), + 9 => sprintf( __('Post scheduled for: %1$s. Preview post'), + // translators: Publish box date format, see http://php.net/date + date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ), + 10 => sprintf( __('Post draft updated. Preview post'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), +); +$messages['page'] = array( + 0 => '', // Unused. Messages start at index 1. + 1 => sprintf( __('Page updated. View page'), esc_url( get_permalink($post_ID) ) ), + 2 => __('Custom field updated.'), + 3 => __('Custom field deleted.'), + 4 => __('Page updated.'), + 5 => isset($_GET['revision']) ? sprintf( __('Page restored to revision from %s'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, + 6 => sprintf( __('Page published. View page'), esc_url( get_permalink($post_ID) ) ), + 7 => __('Page saved.'), + 8 => sprintf( __('Page submitted. Preview page'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), + 9 => sprintf( __('Page scheduled for: %1$s. Preview page'), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ), + 10 => sprintf( __('Page draft updated. Preview page'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), +); + +$messages = apply_filters( 'post_updated_messages', $messages ); + +$message = false; +if ( isset($_GET['message']) ) { + $_GET['message'] = absint( $_GET['message'] ); + if ( isset($messages[$post_type][$_GET['message']]) ) + $message = $messages[$post_type][$_GET['message']]; + elseif ( !isset($messages[$post_type]) && isset($messages['post'][$_GET['message']]) ) + $message = $messages['post'][$_GET['message']]; +} + +$notice = false; +$form_extra = ''; +if ( 'auto-draft' == $post->post_status ) { + if ( 'edit' == $action ) + $post->post_title = ''; + $autosave = false; + $form_extra .= ""; +} else { + $autosave = wp_get_post_autosave( $post_ID ); +} + +$form_action = 'editpost'; +$nonce_action = 'update-' . $post_type . '_' . $post_ID; +$form_extra .= ""; + +// Detect if there exists an autosave newer than the post and if that autosave is different than the post +if ( $autosave && mysql2date( 'U', $autosave->post_modified_gmt, false ) > mysql2date( 'U', $post->post_modified_gmt, false ) ) { + foreach ( _wp_post_revision_fields() as $autosave_field => $_autosave_field ) { + if ( normalize_whitespace( $autosave->$autosave_field ) != normalize_whitespace( $post->$autosave_field ) ) { + $notice = sprintf( __( 'There is an autosave of this post that is more recent than the version below. View the autosave' ), get_edit_post_link( $autosave->ID ) ); + break; + } + } + unset($autosave_field, $_autosave_field); +} + +$post_type_object = get_post_type_object($post_type); + +// All meta boxes should be defined and added before the first do_meta_boxes() call (or potentially during the do_meta_boxes action). +require_once('./includes/meta-boxes.php'); + +add_meta_box('submitdiv', __('Publish'), 'post_submit_meta_box', $post_type, 'side', 'core'); + +if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post_type, 'post-formats' ) ) + add_meta_box( 'formatdiv', _x( 'Format', 'post format' ), 'post_format_meta_box', $post_type, 'side', 'core' ); + +// all taxonomies +foreach ( get_object_taxonomies($post_type) as $tax_name ) { + $taxonomy = get_taxonomy($tax_name); + if ( ! $taxonomy->show_ui ) + continue; + + $label = $taxonomy->labels->name; + + if ( !is_taxonomy_hierarchical($tax_name) ) + add_meta_box('tagsdiv-' . $tax_name, $label, 'post_tags_meta_box', $post_type, 'side', 'core', array( 'taxonomy' => $tax_name )); + else + add_meta_box($tax_name . 'div', $label, 'post_categories_meta_box', $post_type, 'side', 'core', array( 'taxonomy' => $tax_name )); +} + +if ( post_type_supports($post_type, 'page-attributes') ) + add_meta_box('pageparentdiv', 'page' == $post_type ? __('Page Attributes') : __('Attributes'), 'page_attributes_meta_box', $post_type, 'side', 'core'); + +if ( current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ) + && ( ! is_multisite() || ( ( $mu_media_buttons = get_site_option( 'mu_media_buttons', array() ) ) && ! empty( $mu_media_buttons['image'] ) ) ) ) + add_meta_box('postimagediv', __('Featured Image'), 'post_thumbnail_meta_box', $post_type, 'side', 'low'); + +if ( post_type_supports($post_type, 'excerpt') ) + add_meta_box('postexcerpt', __('Excerpt'), 'post_excerpt_meta_box', $post_type, 'normal', 'core'); + +if ( post_type_supports($post_type, 'trackbacks') ) + add_meta_box('trackbacksdiv', __('Send Trackbacks'), 'post_trackback_meta_box', $post_type, 'normal', 'core'); + +if ( post_type_supports($post_type, 'custom-fields') ) + add_meta_box('postcustom', __('Custom Fields'), 'post_custom_meta_box', $post_type, 'normal', 'core'); + +do_action('dbx_post_advanced'); +if ( post_type_supports($post_type, 'comments') ) + add_meta_box('commentstatusdiv', __('Discussion'), 'post_comment_status_meta_box', $post_type, 'normal', 'core'); + +if ( ('publish' == $post->post_status || 'private' == $post->post_status) && post_type_supports($post_type, 'comments') ) + add_meta_box('commentsdiv', __('Comments'), 'post_comment_meta_box', $post_type, 'normal', 'core'); + +if ( !( 'pending' == $post->post_status && !current_user_can( $post_type_object->cap->publish_posts ) ) ) + add_meta_box('slugdiv', __('Slug'), 'post_slug_meta_box', $post_type, 'normal', 'core'); + +if ( post_type_supports($post_type, 'author') ) { + if ( is_super_admin() || current_user_can( $post_type_object->cap->edit_others_posts ) ) + add_meta_box('authordiv', __('Author'), 'post_author_meta_box', $post_type, 'normal', 'core'); +} + +if ( post_type_supports($post_type, 'revisions') && 0 < $post_ID && wp_get_post_revisions( $post_ID ) ) + add_meta_box('revisionsdiv', __('Revisions'), 'post_revisions_meta_box', $post_type, 'normal', 'core'); + +do_action('add_meta_boxes', $post_type, $post); +do_action('add_meta_boxes_' . $post_type, $post); + +do_action('do_meta_boxes', $post_type, 'normal', $post); +do_action('do_meta_boxes', $post_type, 'advanced', $post); +do_action('do_meta_boxes', $post_type, 'side', $post); + +add_screen_option('layout_columns', array('max' => 2) ); + +if ( 'post' == $post_type ) { + add_contextual_help($current_screen, + '

' . __('The title field and the big Post Editing Area are fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of the box. Use the Screen Options tab to unhide more boxes (Excerpt, Send Trackbacks, Custom Fields, Discussion, Slug, Author) or to choose a 1- or 2-column layout for this screen.') . '

' . + '

' . __('Title - Enter a title for your post. After you enter a title, you’ll see the permalink below, which you can edit.') . '

' . + '

' . __('Post editor - Enter the text for your post. There are two modes of editing: Visual and HTML. Choose the mode by clicking on the appropriate tab. Visual mode gives you a WYSIWYG editor. Click the last icon in the row to get a second row of controls. The screen icon just before that allows you to expand the edit box to full screen. The HTML mode allows you to enter raw HTML along with your post text. You can insert media files by clicking the icons above the post editor and following the directions.') . '

' . + '

' . __('Publish - You can set the terms of publishing your post in the Publish box. For Status, Visibility, and Publish (immediately), click on the Edit link to reveal more options. Visibility includes options for password-protecting a post or making it stay at the top of your blog indefinitely (sticky). Publish (immediately) allows you to set a future or past date and time, so you can schedule a post to be published in the future or backdate a post.') . '

' . + ( ( current_theme_supports( 'post-formats' ) && post_type_supports( 'post', 'post-formats' ) ) ? '

' . __( 'Post Format - This designates how your theme will display a specific post. For example, you could have a standard blog post with a title and paragraphs, or a short aside that omits the title and contains a short text blurb. Please refer to the Codex for descriptions of each post format.' ) . '

' : '' ) . + '

' . __('Featured Image - This allows you to associate an image with your post without inserting it. This is usually useful only if your theme makes use of the featured image as a post thumbnail on the home page, a custom header, etc.') . '

' . + '

' . __('Send Trackbacks - Trackbacks are a way to notify legacy blog systems that you’ve linked to them. Enter the URL(s) you want to send trackbacks. If you link to other WordPress sites they’ll be notified automatically using pingbacks, and this field is unnecessary.') . '

' . + '

' . __('Discussion - You can turn comments and pings on or off, and if there are comments on the post, you can see them here and moderate them.') . '

' . + '

' . sprintf(__('You can also create posts with the Press This bookmarklet.'), 'options-writing.php') . '

' . + '

' . __('For more information:') . '

' . + '

' . __('Documentation on Writing and Editing Posts') . '

' . + '

' . __('Support Forums') . '

' + ); +} elseif ( 'page' == $post_type ) { + add_contextual_help($current_screen, '

' . __('Pages are similar to Posts in that they have a title, body text, and associated metadata, but they are different in that they are not part of the chronological blog stream, kind of like permanent posts. Pages are not categorized or tagged, but can have a hierarchy. You can nest Pages under other Pages by making one the “Parent” of the other, creating a group of Pages.') . '

' . + '

' . __('Creating a Page is very similar to creating a Post, and the screens can be customized in the same way using drag and drop, the Screen Options tab, and expanding/collapsing boxes as you choose. The Page editor mostly works the same Post editor, but there are some Page-specific features in the Page Attributes box:') . '

' . + '

' . __('Parent - You can arrange your pages in hierarchies. For example, you could have an “About” page that has “Life Story” and “My Dog” pages under it. There are no limits to how many levels you can nest pages.') . '

' . + '

' . __('Template - Some themes have custom templates you can use for certain pages that might have additional features or custom layouts. If so, you’ll see them in this dropdown menu.') . '

' . + '

' . __('Order - Pages are usually ordered alphabetically, but you can choose your own order by entering a number (1 for first, etc.) in this field.') . '

' . + '

' . __('For more information:') . '

' . + '

' . __('Documentation on Adding New Pages') . '

' . + '

' . __('Documentation on Editing Pages') . '

' . + '

' . __('Support Forums') . '

' + ); +} + +require_once('./admin-header.php'); +?> + +
+ +

+ +

+ + +

+ +
> + + + + + + + + + +post_status ) + wp_original_referer_field(true, 'previous'); + +echo $form_extra; + +wp_nonce_field( 'autosave', 'autosavenonce', false ); +wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); +wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); +?> + +
+
+ + +
+ +
+
+ +
+
+ + +
+
+publicly_queryable ) ? get_sample_permalink_html($post->ID) : ''; +$shortlink = wp_get_shortlink($post->ID, 'post'); +if ( !empty($shortlink) ) + $sample_permalink_html .= '' . __('Get Shortlink') . ''; + +if ( ! empty( $post_type_object->publicly_queryable ) && ! ( 'pending' == $post->post_status && !current_user_can( $post_type_object->cap->publish_posts ) ) ) { ?> +
+ ID) && ! empty($sample_permalink_html) && 'auto-draft' != $post->post_status ) + echo $sample_permalink_html; + ?> +
+ +
+ +
+ + + +
+ +post_content); ?> + + + + +
+   +post_status ) { + echo ''; + if ( $last_id = get_post_meta($post_ID, '_edit_last', true) ) { + $last_user = get_userdata($last_id); + printf(__('Last edited by %1$s on %2$s at %3$s'), esc_html( $last_user->display_name ), mysql2date(get_option('date_format'), $post->post_modified), mysql2date(get_option('time_format'), $post->post_modified)); + } else { + printf(__('Last edited on %1$s at %2$s'), mysql2date(get_option('date_format'), $post->post_modified), mysql2date(get_option('time_format'), $post->post_modified)); + } + echo ''; + } ?> +
+ +
+ + + +
+
+
+
+
+
+ + + +post_title) && '' == $post->post_title) || (isset($_GET['message']) && 2 > $_GET['message'])) : ?> + + diff --git a/src/wp-admin/edit-form-comment.php b/src/wp-admin/edit-form-comment.php new file mode 100644 index 00000000..b3595366 --- /dev/null +++ b/src/wp-admin/edit-form-comment.php @@ -0,0 +1,147 @@ +comment_ID); +$form_action = 'editedcomment'; +$form_extra = "' />\n\ncomment_ID) ?> +
+ +

+ +
+ + + +
+
+

+
+
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+%1$s'); +$date = date_i18n( $datef, strtotime( $comment->comment_date ) ); +?> +  +
+
+
+
+
+ +
+
+comment_ID&_wp_original_http_referer=" . urlencode(wp_get_referer()), 'delete-comment_' . $comment->comment_ID) . "'>" . ( !EMPTY_TRASH_DAYS ? __('Delete Permanently') : __('Move to Trash') ) . "\n"; ?> +
+
+ '4' ) ); ?> +
+
+
+
+
+
+
+ +
+
+
+

+
+ + + + + + + + + + + + + + + +
+ comment_author_email ) { + printf( __( 'E-mail (%s):' ), get_comment_author_email_link( __( 'send e-mail' ), '', '' ) ); + } else { + _e( 'E-mail:' ); + } +?>
+ comment_author_url ) && 'http://' != $comment->comment_author_url ) { + $link = '' . __('visit site') . ''; + printf( __( 'URL (%s):' ), apply_filters('get_comment_author_link', $link ) ); + } else { + _e( 'URL:' ); + } ?>
+
+
+
+ +
+comment_content, 'content', 'newcomment_author_url', false, 4); ?> + +
+ + + + + + + + +
+
+
+
+ + + diff --git a/src/wp-admin/edit-link-form.php b/src/wp-admin/edit-link-form.php new file mode 100644 index 00000000..f5bc0304 --- /dev/null +++ b/src/wp-admin/edit-link-form.php @@ -0,0 +1,129 @@ +Links / Edit Link' ), 'link-manager.php' ); + $submit_text = __('Update Link'); + $form = ' diff --git a/src/wp-admin/edit-tag-form.php b/src/wp-admin/edit-tag-form.php new file mode 100644 index 00000000..daac9237 --- /dev/null +++ b/src/wp-admin/edit-tag-form.php @@ -0,0 +1,93 @@ + +

+ + +
+ +

labels->edit_item; ?>

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ 0, 'hide_if_empty' => false, 'name' => 'parent', 'orderby' => 'name', 'taxonomy' => $taxonomy, 'selected' => $tag->parent, 'exclude_tree' => $tag->term_id, 'hierarchical' => true, 'show_option_none' => __('None'))); ?>
+ + + +

+
+ +
+
diff --git a/src/wp-admin/edit-tags.php b/src/wp-admin/edit-tags.php new file mode 100644 index 00000000..0a82e29f --- /dev/null +++ b/src/wp-admin/edit-tags.php @@ -0,0 +1,394 @@ +cap->manage_terms ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + +$wp_list_table = _get_list_table('WP_Terms_List_Table'); +$pagenum = $wp_list_table->get_pagenum(); + +$title = $tax->labels->name; + +if ( 'post' != $post_type ) { + $parent_file = "edit.php?post_type=$post_type"; + $submenu_file = "edit-tags.php?taxonomy=$taxonomy&post_type=$post_type"; +} else if ( 'link_category' == $tax->name ) { + $parent_file = 'link-manager.php'; + $submenu_file = 'edit-tags.php?taxonomy=link_category'; +} else { + $parent_file = 'edit.php'; + $submenu_file = "edit-tags.php?taxonomy=$taxonomy"; +} + +add_screen_option( 'per_page', array('label' => $title, 'default' => 20, 'option' => 'edit_' . $tax->name . '_per_page') ); + +switch ( $wp_list_table->current_action() ) { + +case 'add-tag': + + check_admin_referer( 'add-tag' ); + + if ( !current_user_can( $tax->cap->edit_terms ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + + $ret = wp_insert_term( $_POST['tag-name'], $taxonomy, $_POST ); + $location = 'edit-tags.php?taxonomy=' . $taxonomy; + if ( 'post' != $post_type ) + $location .= '&post_type=' . $post_type; + + if ( $referer = wp_get_original_referer() ) { + if ( false !== strpos( $referer, 'edit-tags.php' ) ) + $location = $referer; + } + + if ( $ret && !is_wp_error( $ret ) ) + $location = add_query_arg( 'message', 1, $location ); + else + $location = add_query_arg( 'message', 4, $location ); + wp_redirect( $location ); + exit; +break; + +case 'delete': + $location = 'edit-tags.php?taxonomy=' . $taxonomy; + if ( 'post' != $post_type ) + $location .= '&post_type=' . $post_type; + if ( $referer = wp_get_referer() ) { + if ( false !== strpos( $referer, 'edit-tags.php' ) ) + $location = $referer; + } + + if ( !isset( $_REQUEST['tag_ID'] ) ) { + wp_redirect( $location ); + exit; + } + + $tag_ID = (int) $_REQUEST['tag_ID']; + check_admin_referer( 'delete-tag_' . $tag_ID ); + + if ( !current_user_can( $tax->cap->delete_terms ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + + wp_delete_term( $tag_ID, $taxonomy ); + + $location = add_query_arg( 'message', 2, $location ); + wp_redirect( $location ); + exit; + +break; + +case 'bulk-delete': + check_admin_referer( 'bulk-tags' ); + + if ( !current_user_can( $tax->cap->delete_terms ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + + $tags = (array) $_REQUEST['delete_tags']; + foreach ( $tags as $tag_ID ) { + wp_delete_term( $tag_ID, $taxonomy ); + } + + $location = 'edit-tags.php?taxonomy=' . $taxonomy; + if ( 'post' != $post_type ) + $location .= '&post_type=' . $post_type; + if ( $referer = wp_get_referer() ) { + if ( false !== strpos( $referer, 'edit-tags.php' ) ) + $location = $referer; + } + + $location = add_query_arg( 'message', 6, $location ); + wp_redirect( $location ); + exit; + +break; + +case 'edit': + $title = $tax->labels->edit_item; + + require_once ( 'admin-header.php' ); + $tag_ID = (int) $_REQUEST['tag_ID']; + + $tag = get_term( $tag_ID, $taxonomy, OBJECT, 'edit' ); + include( './edit-tag-form.php' ); + +break; + +case 'editedtag': + $tag_ID = (int) $_POST['tag_ID']; + check_admin_referer( 'update-tag_' . $tag_ID ); + + if ( !current_user_can( $tax->cap->edit_terms ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + + $ret = wp_update_term( $tag_ID, $taxonomy, $_POST ); + + $location = 'edit-tags.php?taxonomy=' . $taxonomy; + if ( 'post' != $post_type ) + $location .= '&post_type=' . $post_type; + + if ( $referer = wp_get_original_referer() ) { + if ( false !== strpos( $referer, 'edit-tags.php' ) ) + $location = $referer; + } + + if ( $ret && !is_wp_error( $ret ) ) + $location = add_query_arg( 'message', 3, $location ); + else + $location = add_query_arg( 'message', 5, $location ); + + wp_redirect( $location ); + exit; +break; + +default: +if ( ! empty($_REQUEST['_wp_http_referer']) ) { + $location = remove_query_arg( array('_wp_http_referer', '_wpnonce'), stripslashes($_SERVER['REQUEST_URI']) ); + + if ( ! empty( $_REQUEST['paged'] ) ) + $location = add_query_arg( 'paged', (int) $_REQUEST['paged'] ); + + wp_redirect( $location ); + exit; +} + +$wp_list_table->prepare_items(); +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); + +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +wp_enqueue_script('admin-tags'); +if ( current_user_can($tax->cap->edit_terms) ) + wp_enqueue_script('inline-edit-tax'); + +if ( 'category' == $taxonomy || 'link_category' == $taxonomy || 'post_tag' == $taxonomy ) { + $help =''; + if ( 'category' == $taxonomy ) + $help = '

' . sprintf(__( 'You can use categories to define sections of your site and group related posts. The default category is “Uncategorized” until you change it in your writing settings.' ) , 'options-writing.php' ) . '

'; + elseif ( 'link_category' == $taxonomy ) + $help = '

' . __( 'You can create groups of links by using link categories. Link category names must be unique and link categories are separate from the categories you use for posts.' ) . '

'; + else + $help = '

' . __( 'You can assign keywords to your posts using Post Tags. Unlike categories, tags have no hierarchy, meaning there’s no relationship from one tag to another.' ) . '

'; + + if ( 'link_category' == $taxonomy ) + $help .= '

' . __( 'You can delete link categories in the Bulk Action pulldown, but that action does not delete the links within the category. Instead, it moves them to the default link category.' ) . '

'; + else + $help .='

' . __( 'What’s the difference between categories and tags? Normally, tags are ad-hoc keywords that identify important information in your post (names, subjects, etc) that may or may not recur in other posts, while categories are pre-determined sections. If you think of your site like a book, the categories are like the Table of Contents and the tags are like the terms in the index.' ) . '

'; + + if ( 'category' == $taxonomy ) + $help .= '

' . __( 'When adding a new category on this screen, you’ll fill in the following fields:' ) . '

'; + elseif ( 'post_tag' == $taxonomy ) + $help .= '

' . __( 'When adding a new tag on this screen, you’ll fill in the following fields:' ) . '

'; + + if ( 'category' == $taxonomy || 'post_tag' == $taxonomy ) + + $help .= '
    ' . + '
  • ' . __( 'Name - The name is how it appears on your site.' ) . '
  • '; + + if ( ! global_terms_enabled() ) + if ( 'category' == $taxonomy || 'post_tag' == $taxonomy ) + $help .= '
  • ' . __( 'Slug - The “slug” is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens.' ) . '
  • '; + + if ( 'category' == $taxonomy ) + $help .= '
  • ' . __( 'Parent - Categories, unlike tags, can have a hierarchy. You might have a Jazz category, and under that have children categories for Bebop and Big Band. Totally optional. To create a subcategory, just choose another category from the Parent dropdown.' ) . '
  • '; + + if ( 'category' == $taxonomy || 'post_tag' == $taxonomy ) + $help .= '
  • ' . __( 'Description - The description is not prominent by default; however, some themes may display it.' ) . '
  • ' . + '
' . + '

' . __( 'You can change the display of this screen using the Screen Options tab to set how many items are displayed per screen and to display/hide columns in the table.' ) . '

' . + '

' . __( 'For more information:' ) . '

'; + + if ( 'category' == $taxonomy ) + $help .= '

' . __( 'Documentation on Categories' ) . '

'; + elseif ( 'link_category' == $taxonomy ) + $help .= '

' . __( 'Documentation on Link Categories' ) . '

'; + else + $help .= '

' . __( 'Documentation on Post Tags' ) . '

'; + + $help .= '

' . __('Support Forums') . '

'; + + add_contextual_help($current_screen, $help); + unset($help); +} + +require_once ('admin-header.php'); + +if ( !current_user_can($tax->cap->edit_terms) ) + wp_die( __('You are not allowed to edit this item.') ); + +$messages[1] = __('Item added.'); +$messages[2] = __('Item deleted.'); +$messages[3] = __('Item updated.'); +$messages[4] = __('Item not added.'); +$messages[5] = __('Item not updated.'); +$messages[6] = __('Items deleted.'); + +?> + +
+ +

' . __('Search results for “%s”') . '', esc_html( stripslashes($_REQUEST['s']) ) ); ?> +

+ + +

+ +
+ +
+ + + +search_box( $tax->labels->search_items, 'tag' ); ?> + +
+
+ +
+ +
+
+
+ + + +display(); ?> + +
+
+ + +
+

Note:
Deleting a category does not delete the posts in that category. Instead, posts that were only assigned to the deleted category are set to the category %s.'), apply_filters('the_category', get_cat_name(get_option('default_category')))) ?>

+ +

category to tag converter.'), 'import.php') ?>

+ +
+ +
+

tag to category converter'), 'import.php') ;?>.

+
+ + +
+
+ +
+
+ +labels->popular_items ) ) { + if ( current_user_can( $tax->cap->edit_terms ) ) + $tag_cloud = wp_tag_cloud( array( 'taxonomy' => $taxonomy, 'echo' => false, 'link' => 'edit' ) ); + else + $tag_cloud = wp_tag_cloud( array( 'taxonomy' => $taxonomy, 'echo' => false ) ); + + if ( $tag_cloud ) : + ?> +
+

labels->popular_items; ?>

+ +
+cap->edit_terms) ) { + // Back compat hooks. Deprecated in preference to {$taxonomy}_pre_add_form + if ( 'category' == $taxonomy ) + do_action('add_category_form_pre', (object)array('parent' => 0) ); + elseif ( 'link_category' == $taxonomy ) + do_action('add_link_category_form_pre', (object)array('parent' => 0) ); + else + do_action('add_tag_form_pre', $taxonomy); + + do_action($taxonomy . '_pre_add_form', $taxonomy); +?> + +
+

labels->add_new_item; ?>

+
+ + + + + + +
+ + +

+
+ +
+ + +

+
+ + +
+ + 0, 'hide_if_empty' => false, 'taxonomy' => $taxonomy, 'name' => 'parent', 'orderby' => 'name', 'hierarchical' => true, 'show_option_none' => __('None'))); ?> + +

+ +
+ +
+ + +

+
+ +labels->add_new_item, 'button' ); + +// Back compat hooks. Deprecated in preference to {$taxonomy}_add_form +if ( 'category' == $taxonomy ) + do_action('edit_category_form', (object)array('parent' => 0) ); +elseif ( 'link_category' == $taxonomy ) + do_action('edit_link_category_form', (object)array('parent' => 0) ); +else + do_action('add_tag_form', $taxonomy); + +do_action($taxonomy . '_add_form', $taxonomy); +?> +
+ + +
+
+ +
+
+ +inline_edit(); ?> + + diff --git a/src/wp-admin/edit.php b/src/wp-admin/edit.php new file mode 100644 index 00000000..39424ac9 --- /dev/null +++ b/src/wp-admin/edit.php @@ -0,0 +1,267 @@ + true ) ) ) ) + $post_type = $_GET['post_type']; +else + wp_die( __('Invalid post type') ); + +$_GET['post_type'] = $post_type; + +$post_type_object = get_post_type_object( $post_type ); + +if ( !current_user_can($post_type_object->cap->edit_posts) ) + wp_die(__('Cheatin’ uh?')); + +$wp_list_table = _get_list_table('WP_Posts_List_Table'); +$pagenum = $wp_list_table->get_pagenum(); + +// Back-compat for viewing comments of an entry +foreach ( array( 'p', 'attachment_id', 'page_id' ) as $_redirect ) { + if ( ! empty( $_REQUEST[ $_redirect ] ) ) { + wp_redirect( admin_url( 'edit-comments.php?p=' . absint( $_REQUEST[ $_redirect ] ) ) ); + exit; + } +} +unset( $_redirect ); + +if ( 'post' != $post_type ) { + $parent_file = "edit.php?post_type=$post_type"; + $submenu_file = "edit.php?post_type=$post_type"; + $post_new_file = "post-new.php?post_type=$post_type"; +} else { + $parent_file = 'edit.php'; + $submenu_file = 'edit.php'; + $post_new_file = 'post-new.php'; +} + +$doaction = $wp_list_table->current_action(); + +if ( $doaction ) { + check_admin_referer('bulk-posts'); + + $sendback = remove_query_arg( array('trashed', 'untrashed', 'deleted', 'ids'), wp_get_referer() ); + $sendback = add_query_arg( 'paged', $pagenum, $sendback ); + if ( strpos($sendback, 'post.php') !== false ) + $sendback = admin_url($post_new_file); + + if ( 'delete_all' == $doaction ) { + $post_status = preg_replace('/[^a-z0-9_-]+/i', '', $_REQUEST['post_status']); + if ( get_post_status_object($post_status) ) // Check the post status exists first + $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type=%s AND post_status = %s", $post_type, $post_status ) ); + $doaction = 'delete'; + } elseif ( isset( $_REQUEST['media'] ) ) { + $post_ids = $_REQUEST['media']; + } elseif ( isset( $_REQUEST['ids'] ) ) { + $post_ids = explode( ',', $_REQUEST['ids'] ); + } elseif ( !empty( $_REQUEST['post'] ) ) { + $post_ids = array_map('intval', $_REQUEST['post']); + } + + if ( !isset( $post_ids ) ) { + wp_redirect( $sendback ); + exit; + } + + switch ( $doaction ) { + case 'trash': + $trashed = 0; + foreach( (array) $post_ids as $post_id ) { + if ( !current_user_can($post_type_object->cap->delete_post, $post_id) ) + wp_die( __('You are not allowed to move this item to the Trash.') ); + + if ( !wp_trash_post($post_id) ) + wp_die( __('Error in moving to Trash.') ); + + $trashed++; + } + $sendback = add_query_arg( array('trashed' => $trashed, 'ids' => join(',', $post_ids) ), $sendback ); + break; + case 'untrash': + $untrashed = 0; + foreach( (array) $post_ids as $post_id ) { + if ( !current_user_can($post_type_object->cap->delete_post, $post_id) ) + wp_die( __('You are not allowed to restore this item from the Trash.') ); + + if ( !wp_untrash_post($post_id) ) + wp_die( __('Error in restoring from Trash.') ); + + $untrashed++; + } + $sendback = add_query_arg('untrashed', $untrashed, $sendback); + break; + case 'delete': + $deleted = 0; + foreach( (array) $post_ids as $post_id ) { + $post_del = & get_post($post_id); + + if ( !current_user_can($post_type_object->cap->delete_post, $post_id) ) + wp_die( __('You are not allowed to delete this item.') ); + + if ( $post_del->post_type == 'attachment' ) { + if ( ! wp_delete_attachment($post_id) ) + wp_die( __('Error in deleting...') ); + } else { + if ( !wp_delete_post($post_id) ) + wp_die( __('Error in deleting...') ); + } + $deleted++; + } + $sendback = add_query_arg('deleted', $deleted, $sendback); + break; + case 'edit': + $done = bulk_edit_posts($_REQUEST); + + if ( is_array($done) ) { + $done['updated'] = count( $done['updated'] ); + $done['skipped'] = count( $done['skipped'] ); + $done['locked'] = count( $done['locked'] ); + $sendback = add_query_arg( $done, $sendback ); + } + break; + } + + $sendback = remove_query_arg( array('action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view'), $sendback ); + + wp_redirect($sendback); + exit(); +} elseif ( ! empty($_REQUEST['_wp_http_referer']) ) { + wp_redirect( remove_query_arg( array('_wp_http_referer', '_wpnonce'), stripslashes($_SERVER['REQUEST_URI']) ) ); + exit; +} + +$wp_list_table->prepare_items(); + +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +wp_enqueue_script('inline-edit-post'); + +$title = $post_type_object->labels->name; + +if ( 'post' == $post_type ) { + add_contextual_help($current_screen, + '

' . __('You can customize the display of this screen in a number of ways:') . '

' . + '
    ' . + '
  • ' . __('You can hide/display columns based on your needs and decide how many posts to list per screen using the Screen Options tab.') . '
  • ' . + '
  • ' . __('You can filter the list of posts by post status using the text links in the upper left to show All, Published, Draft, or Trashed posts. The default view is to show all posts.') . '
  • ' . + '
  • ' . __('You can view posts in a simple title list or with an excerpt. Choose the view you prefer by clicking on the icons at the top of the list on the right.') . '
  • ' . + '
  • ' . __('You can refine the list to show only posts in a specific category or from a specific month by using the dropdown menus above the posts list. Click the Filter button after making your selection. You also can refine the list by clicking on the post author, category or tag in the posts list.') . '
  • ' . + '
' . + '

' . __('Hovering over a row in the posts list will display action links that allow you to manage your post. You can perform the following actions:') . '

' . + '
    ' . + '
  • ' . __('Edit takes you to the editing screen for that post. You can also reach that screen by clicking on the post title.') . '
  • ' . + '
  • ' . __('Quick Edit provides inline access to the metadata of your post, allowing you to update post details without leaving this screen.') . '
  • ' . + '
  • ' . __('Trash removes your post from this list and places it in the trash, from which you can permanently delete it.') . '
  • ' . + '
  • ' . __('Preview will show you what your draft post will look like if you publish it. View will take you to your live site to view the post. Which link is available depends on your post’s status.') . '
  • ' . + '
' . + '

' . __('You can also edit multiple posts at once. Select the posts you want to edit using the checkboxes, select Edit from the Bulk Actions menu and click Apply. You will be able to change the metadata (categories, author, etc.) for all selected posts at once. To remove a post from the grouping, just click the x next to its name in the Bulk Edit area that appears.') . '

' . + '

' . __('For more information:') . '

' . + '

' . __('Documentation on Managing Posts') . '

' . + '

' . __('Support Forums') . '

' + ); +} elseif ( 'page' == $post_type ) { + add_contextual_help($current_screen, + '

' . __('Pages are similar to Posts in that they have a title, body text, and associated metadata, but they are different in that they are not part of the chronological blog stream, kind of like permanent posts. Pages are not categorized or tagged, but can have a hierarchy. You can nest Pages under other Pages by making one the “Parent” of the other, creating a group of Pages.') . '

' . + '

' . __('Managing Pages is very similar to managing Posts, and the screens can be customized in the same way.') . '

' . + '

' . __('You can also perform the same types of actions, including narrowing the list by using the filters, acting on a Page using the action links that appear when you hover over a row, or using the Bulk Actions menu to edit the metadata for multiple Pages at once.') . '

' . + '

' . __('For more information:') . '

' . + '

' . __('Documentation on Managing Pages') . '

' . + '

' . __('Support Forums') . '

' + ); +} + +add_screen_option( 'per_page', array('label' => $title, 'default' => 20) ); + +require_once('./admin-header.php'); +?> +
+ +

labels->name ); ?> labels->add_new); ?> ' . __('Search results for “%s”') . '', get_search_query() ); ?> +

+ + +

|

+ + + +

+' . __('Undo') . '
'; + unset($_REQUEST['trashed']); +} + +if ( isset($_REQUEST['untrashed']) && (int) $_REQUEST['untrashed'] ) { + printf( _n( 'Item restored from the Trash.', '%s items restored from the Trash.', $_REQUEST['untrashed'] ), number_format_i18n( $_REQUEST['untrashed'] ) ); + unset($_REQUEST['undeleted']); +} + +$_SERVER['REQUEST_URI'] = remove_query_arg( array('locked', 'skipped', 'updated', 'deleted', 'trashed', 'untrashed'), $_SERVER['REQUEST_URI'] ); +?> +

+ + +views(); ?> + +
+ +search_box( $post_type_object->labels->search_items, 'post' ); ?> + + + + + + + +display(); ?> + +
+ +has_items() ) + $wp_list_table->inline_edit(); +?> + +
+
+
+ + + +' . __('You can export a file of your site’s content in order to import it into another installation or platform. The export file will be an XML file format called WXR. Posts, pages, comments, custom fields, categories, and tags can be included. You can choose for the WXR file to include only certain posts or pages by setting the dropdown filters to limit the export by category, author, date range by month, or publishing status.') . '

' . + '

' . __('Once generated, your WXR file can be imported by another WordPress site or by another blogging platform able to access this format.') . '

' . + '

' . __('For more information:') . '

' . + '

' . __('Documentation on Export') . '

' . + '

' . __('Support Forums') . '

' +); + +if ( isset( $_GET['download'] ) ) { + $args = array(); + + if ( ! isset( $_GET['content'] ) || 'all' == $_GET['content'] ) { + $args['content'] = 'all'; + } else if ( 'posts' == $_GET['content'] ) { + $args['content'] = 'post'; + + if ( $_GET['cat'] ) + $args['category'] = (int) $_GET['cat']; + + if ( $_GET['post_author'] ) + $args['author'] = (int) $_GET['post_author']; + + if ( $_GET['post_start_date'] || $_GET['post_end_date'] ) { + $args['start_date'] = $_GET['post_start_date']; + $args['end_date'] = $_GET['post_end_date']; + } + + if ( $_GET['post_status'] ) + $args['status'] = $_GET['post_status']; + } else if ( 'pages' == $_GET['content'] ) { + $args['content'] = 'page'; + + if ( $_GET['page_author'] ) + $args['author'] = (int) $_GET['page_author']; + + if ( $_GET['page_start_date'] || $_GET['page_end_date'] ) { + $args['start_date'] = $_GET['page_start_date']; + $args['end_date'] = $_GET['page_end_date']; + } + + if ( $_GET['page_status'] ) + $args['status'] = $_GET['page_status']; + } else { + $args['content'] = $_GET['content']; + } + + export_wp( $args ); + die(); +} + +require_once ('admin-header.php'); + +function export_date_options() { + global $wpdb, $wp_locale; + + $months = $wpdb->get_results( " + SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month + FROM $wpdb->posts + WHERE post_type = 'post' AND post_status != 'auto-draft' + ORDER BY post_date DESC + " ); + + $month_count = count( $months ); + if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) + return; + + foreach ( $months as $date ) { + if ( 0 == $date->year ) + continue; + + $month = zeroise( $date->month, 2 ); + echo ''; + } +} +?> + +
+ +

+ +

+

+

+ +

+
+ +

+

+ +

+
    +
  • + + __('All') ) ); ?> +
  • +
  • + +get_col( "SELECT DISTINCT post_author FROM {$wpdb->posts} WHERE post_type = 'post'" ); + wp_dropdown_users( array( 'include' => $authors, 'name' => 'post_author', 'multi' => true, 'show_option_all' => __('All') ) ); +?> +
  • +
  • + + + +
  • +
  • + + +
  • +
+ +

+
    +
  • + +get_col( "SELECT DISTINCT post_author FROM {$wpdb->posts} WHERE post_type = 'page'" ); + wp_dropdown_users( array( 'include' => $authors, 'name' => 'page_author', 'multi' => true, 'show_option_all' => __('All') ) ); +?> +
  • +
  • + + + +
  • +
  • + + +
  • +
+ + false, 'can_export' => true ), 'objects' ) as $post_type ) : ?> +

+ + + +
+
+ + diff --git a/src/wp-admin/gears-manifest.php b/src/wp-admin/gears-manifest.php new file mode 100644 index 00000000..8feb485f --- /dev/null +++ b/src/wp-admin/gears-manifest.php @@ -0,0 +1,51 @@ + +{ +"betaManifestVersion" : 1, +"version" : "", +"entries" : [ + + +]} diff --git a/src/wp-admin/images/align-center.png b/src/wp-admin/images/align-center.png new file mode 100644 index 00000000..a4122268 Binary files /dev/null and b/src/wp-admin/images/align-center.png differ diff --git a/src/wp-admin/images/align-left.png b/src/wp-admin/images/align-left.png new file mode 100644 index 00000000..2e433fc3 Binary files /dev/null and b/src/wp-admin/images/align-left.png differ diff --git a/src/wp-admin/images/align-none.png b/src/wp-admin/images/align-none.png new file mode 100644 index 00000000..5fb9af2e Binary files /dev/null and b/src/wp-admin/images/align-none.png differ diff --git a/src/wp-admin/images/align-right.png b/src/wp-admin/images/align-right.png new file mode 100644 index 00000000..9b92578f Binary files /dev/null and b/src/wp-admin/images/align-right.png differ diff --git a/src/wp-admin/images/archive-link.png b/src/wp-admin/images/archive-link.png new file mode 100644 index 00000000..4c708951 Binary files /dev/null and b/src/wp-admin/images/archive-link.png differ diff --git a/src/wp-admin/images/blue-grad.png b/src/wp-admin/images/blue-grad.png new file mode 100644 index 00000000..868a657c Binary files /dev/null and b/src/wp-admin/images/blue-grad.png differ diff --git a/src/wp-admin/images/bubble_bg-rtl.gif b/src/wp-admin/images/bubble_bg-rtl.gif new file mode 100644 index 00000000..5cfbefee Binary files /dev/null and b/src/wp-admin/images/bubble_bg-rtl.gif differ diff --git a/src/wp-admin/images/bubble_bg.gif b/src/wp-admin/images/bubble_bg.gif new file mode 100644 index 00000000..315ab527 Binary files /dev/null and b/src/wp-admin/images/bubble_bg.gif differ diff --git a/src/wp-admin/images/button-grad-active.png b/src/wp-admin/images/button-grad-active.png new file mode 100644 index 00000000..0177e5bf Binary files /dev/null and b/src/wp-admin/images/button-grad-active.png differ diff --git a/src/wp-admin/images/button-grad.png b/src/wp-admin/images/button-grad.png new file mode 100644 index 00000000..3f96366c Binary files /dev/null and b/src/wp-admin/images/button-grad.png differ diff --git a/src/wp-admin/images/comment-grey-bubble.png b/src/wp-admin/images/comment-grey-bubble.png new file mode 100644 index 00000000..6f1e765f Binary files /dev/null and b/src/wp-admin/images/comment-grey-bubble.png differ diff --git a/src/wp-admin/images/date-button.gif b/src/wp-admin/images/date-button.gif new file mode 100644 index 00000000..7ee32cb5 Binary files /dev/null and b/src/wp-admin/images/date-button.gif differ diff --git a/src/wp-admin/images/ed-bg-vs.gif b/src/wp-admin/images/ed-bg-vs.gif new file mode 100644 index 00000000..be41c6c8 Binary files /dev/null and b/src/wp-admin/images/ed-bg-vs.gif differ diff --git a/src/wp-admin/images/ed-bg.gif b/src/wp-admin/images/ed-bg.gif new file mode 100644 index 00000000..a00467c2 Binary files /dev/null and b/src/wp-admin/images/ed-bg.gif differ diff --git a/src/wp-admin/images/fade-butt.png b/src/wp-admin/images/fade-butt.png new file mode 100644 index 00000000..42f08b79 Binary files /dev/null and b/src/wp-admin/images/fade-butt.png differ diff --git a/src/wp-admin/images/fav-arrow-rtl.gif b/src/wp-admin/images/fav-arrow-rtl.gif new file mode 100644 index 00000000..e9aeba05 Binary files /dev/null and b/src/wp-admin/images/fav-arrow-rtl.gif differ diff --git a/src/wp-admin/images/fav-arrow.gif b/src/wp-admin/images/fav-arrow.gif new file mode 100644 index 00000000..28fc6bbe Binary files /dev/null and b/src/wp-admin/images/fav-arrow.gif differ diff --git a/src/wp-admin/images/fav-vs.png b/src/wp-admin/images/fav-vs.png new file mode 100644 index 00000000..51a2186f Binary files /dev/null and b/src/wp-admin/images/fav-vs.png differ diff --git a/src/wp-admin/images/fav.png b/src/wp-admin/images/fav.png new file mode 100644 index 00000000..f3cbe546 Binary files /dev/null and b/src/wp-admin/images/fav.png differ diff --git a/src/wp-admin/images/generic.png b/src/wp-admin/images/generic.png new file mode 100644 index 00000000..3bcbc04f Binary files /dev/null and b/src/wp-admin/images/generic.png differ diff --git a/src/wp-admin/images/gray-grad.png b/src/wp-admin/images/gray-grad.png new file mode 100644 index 00000000..99c45cef Binary files /dev/null and b/src/wp-admin/images/gray-grad.png differ diff --git a/src/wp-admin/images/icons32-vs.png b/src/wp-admin/images/icons32-vs.png new file mode 100644 index 00000000..d910bc1b Binary files /dev/null and b/src/wp-admin/images/icons32-vs.png differ diff --git a/src/wp-admin/images/icons32.png b/src/wp-admin/images/icons32.png new file mode 100644 index 00000000..d94e38af Binary files /dev/null and b/src/wp-admin/images/icons32.png differ diff --git a/src/wp-admin/images/imgedit-icons.png b/src/wp-admin/images/imgedit-icons.png new file mode 100644 index 00000000..5f1f5851 Binary files /dev/null and b/src/wp-admin/images/imgedit-icons.png differ diff --git a/src/wp-admin/images/list.png b/src/wp-admin/images/list.png new file mode 100644 index 00000000..827556ee Binary files /dev/null and b/src/wp-admin/images/list.png differ diff --git a/src/wp-admin/images/loading-publish.gif b/src/wp-admin/images/loading-publish.gif new file mode 100644 index 00000000..4282004f Binary files /dev/null and b/src/wp-admin/images/loading-publish.gif differ diff --git a/src/wp-admin/images/loading.gif b/src/wp-admin/images/loading.gif new file mode 100644 index 00000000..85b99d46 Binary files /dev/null and b/src/wp-admin/images/loading.gif differ diff --git a/src/wp-admin/images/logo-ghost.png b/src/wp-admin/images/logo-ghost.png new file mode 100644 index 00000000..58335f7f Binary files /dev/null and b/src/wp-admin/images/logo-ghost.png differ diff --git a/src/wp-admin/images/logo-login.gif b/src/wp-admin/images/logo-login.gif new file mode 100644 index 00000000..72422b20 Binary files /dev/null and b/src/wp-admin/images/logo-login.gif differ diff --git a/src/wp-admin/images/logo.gif b/src/wp-admin/images/logo.gif new file mode 100644 index 00000000..8024d480 Binary files /dev/null and b/src/wp-admin/images/logo.gif differ diff --git a/src/wp-admin/images/marker.png b/src/wp-admin/images/marker.png new file mode 100644 index 00000000..3929bbb5 Binary files /dev/null and b/src/wp-admin/images/marker.png differ diff --git a/src/wp-admin/images/mask.png b/src/wp-admin/images/mask.png new file mode 100644 index 00000000..b0a4d406 Binary files /dev/null and b/src/wp-admin/images/mask.png differ diff --git a/src/wp-admin/images/media-button-image.gif b/src/wp-admin/images/media-button-image.gif new file mode 100644 index 00000000..5e7e4265 Binary files /dev/null and b/src/wp-admin/images/media-button-image.gif differ diff --git a/src/wp-admin/images/media-button-music.gif b/src/wp-admin/images/media-button-music.gif new file mode 100644 index 00000000..0254a088 Binary files /dev/null and b/src/wp-admin/images/media-button-music.gif differ diff --git a/src/wp-admin/images/media-button-other.gif b/src/wp-admin/images/media-button-other.gif new file mode 100644 index 00000000..414a9578 Binary files /dev/null and b/src/wp-admin/images/media-button-other.gif differ diff --git a/src/wp-admin/images/media-button-video.gif b/src/wp-admin/images/media-button-video.gif new file mode 100644 index 00000000..50ac6e02 Binary files /dev/null and b/src/wp-admin/images/media-button-video.gif differ diff --git a/src/wp-admin/images/menu-arrows.gif b/src/wp-admin/images/menu-arrows.gif new file mode 100644 index 00000000..ec854c1f Binary files /dev/null and b/src/wp-admin/images/menu-arrows.gif differ diff --git a/src/wp-admin/images/menu-bits-rtl-vs.gif b/src/wp-admin/images/menu-bits-rtl-vs.gif new file mode 100644 index 00000000..422cc8df Binary files /dev/null and b/src/wp-admin/images/menu-bits-rtl-vs.gif differ diff --git a/src/wp-admin/images/menu-bits-rtl.gif b/src/wp-admin/images/menu-bits-rtl.gif new file mode 100644 index 00000000..b193af0d Binary files /dev/null and b/src/wp-admin/images/menu-bits-rtl.gif differ diff --git a/src/wp-admin/images/menu-bits-vs.gif b/src/wp-admin/images/menu-bits-vs.gif new file mode 100644 index 00000000..30f0bc83 Binary files /dev/null and b/src/wp-admin/images/menu-bits-vs.gif differ diff --git a/src/wp-admin/images/menu-bits.gif b/src/wp-admin/images/menu-bits.gif new file mode 100644 index 00000000..218e184d Binary files /dev/null and b/src/wp-admin/images/menu-bits.gif differ diff --git a/src/wp-admin/images/menu-dark-rtl-vs.gif b/src/wp-admin/images/menu-dark-rtl-vs.gif new file mode 100644 index 00000000..14ed2ab4 Binary files /dev/null and b/src/wp-admin/images/menu-dark-rtl-vs.gif differ diff --git a/src/wp-admin/images/menu-dark-rtl.gif b/src/wp-admin/images/menu-dark-rtl.gif new file mode 100644 index 00000000..7bfd25d5 Binary files /dev/null and b/src/wp-admin/images/menu-dark-rtl.gif differ diff --git a/src/wp-admin/images/menu-dark-vs.gif b/src/wp-admin/images/menu-dark-vs.gif new file mode 100644 index 00000000..0b448aa4 Binary files /dev/null and b/src/wp-admin/images/menu-dark-vs.gif differ diff --git a/src/wp-admin/images/menu-dark.gif b/src/wp-admin/images/menu-dark.gif new file mode 100644 index 00000000..739b888f Binary files /dev/null and b/src/wp-admin/images/menu-dark.gif differ diff --git a/src/wp-admin/images/menu-vs.png b/src/wp-admin/images/menu-vs.png new file mode 100644 index 00000000..76372bc3 Binary files /dev/null and b/src/wp-admin/images/menu-vs.png differ diff --git a/src/wp-admin/images/menu.png b/src/wp-admin/images/menu.png new file mode 100644 index 00000000..fa6ed84b Binary files /dev/null and b/src/wp-admin/images/menu.png differ diff --git a/src/wp-admin/images/no.png b/src/wp-admin/images/no.png new file mode 100644 index 00000000..e2db55f2 Binary files /dev/null and b/src/wp-admin/images/no.png differ diff --git a/src/wp-admin/images/required.gif b/src/wp-admin/images/required.gif new file mode 100644 index 00000000..119350fc Binary files /dev/null and b/src/wp-admin/images/required.gif differ diff --git a/src/wp-admin/images/resize.gif b/src/wp-admin/images/resize.gif new file mode 100644 index 00000000..6a1b41cd Binary files /dev/null and b/src/wp-admin/images/resize.gif differ diff --git a/src/wp-admin/images/screen-options-toggle-vs.gif b/src/wp-admin/images/screen-options-toggle-vs.gif new file mode 100644 index 00000000..3b9b8af3 Binary files /dev/null and b/src/wp-admin/images/screen-options-toggle-vs.gif differ diff --git a/src/wp-admin/images/screen-options-toggle.gif b/src/wp-admin/images/screen-options-toggle.gif new file mode 100644 index 00000000..ed0a5fd3 Binary files /dev/null and b/src/wp-admin/images/screen-options-toggle.gif differ diff --git a/src/wp-admin/images/se.png b/src/wp-admin/images/se.png new file mode 100644 index 00000000..c9d8fdd0 Binary files /dev/null and b/src/wp-admin/images/se.png differ diff --git a/src/wp-admin/images/sort.gif b/src/wp-admin/images/sort.gif new file mode 100644 index 00000000..2a5a6e8c Binary files /dev/null and b/src/wp-admin/images/sort.gif differ diff --git a/src/wp-admin/images/star.gif b/src/wp-admin/images/star.gif new file mode 100644 index 00000000..ff671f73 Binary files /dev/null and b/src/wp-admin/images/star.gif differ diff --git a/src/wp-admin/images/toggle-arrow-rtl.gif b/src/wp-admin/images/toggle-arrow-rtl.gif new file mode 100644 index 00000000..c96b9447 Binary files /dev/null and b/src/wp-admin/images/toggle-arrow-rtl.gif differ diff --git a/src/wp-admin/images/toggle-arrow.gif b/src/wp-admin/images/toggle-arrow.gif new file mode 100644 index 00000000..86cb448b Binary files /dev/null and b/src/wp-admin/images/toggle-arrow.gif differ diff --git a/src/wp-admin/images/upload-classic.png b/src/wp-admin/images/upload-classic.png new file mode 100644 index 00000000..beda3e43 Binary files /dev/null and b/src/wp-admin/images/upload-classic.png differ diff --git a/src/wp-admin/images/upload-fresh.png b/src/wp-admin/images/upload-fresh.png new file mode 100644 index 00000000..92fd355c Binary files /dev/null and b/src/wp-admin/images/upload-fresh.png differ diff --git a/src/wp-admin/images/wheel.png b/src/wp-admin/images/wheel.png new file mode 100644 index 00000000..97b343d9 Binary files /dev/null and b/src/wp-admin/images/wheel.png differ diff --git a/src/wp-admin/images/white-grad-active.png b/src/wp-admin/images/white-grad-active.png new file mode 100644 index 00000000..04780150 Binary files /dev/null and b/src/wp-admin/images/white-grad-active.png differ diff --git a/src/wp-admin/images/white-grad.png b/src/wp-admin/images/white-grad.png new file mode 100644 index 00000000..aaf57aa9 Binary files /dev/null and b/src/wp-admin/images/white-grad.png differ diff --git a/src/wp-admin/images/widgets-arrow-vs.gif b/src/wp-admin/images/widgets-arrow-vs.gif new file mode 100644 index 00000000..c6398e67 Binary files /dev/null and b/src/wp-admin/images/widgets-arrow-vs.gif differ diff --git a/src/wp-admin/images/widgets-arrow.gif b/src/wp-admin/images/widgets-arrow.gif new file mode 100644 index 00000000..69e03524 Binary files /dev/null and b/src/wp-admin/images/widgets-arrow.gif differ diff --git a/src/wp-admin/images/wordpress-logo.png b/src/wp-admin/images/wordpress-logo.png new file mode 100644 index 00000000..7421f219 Binary files /dev/null and b/src/wp-admin/images/wordpress-logo.png differ diff --git a/src/wp-admin/images/wp-logo-vs.png b/src/wp-admin/images/wp-logo-vs.png new file mode 100644 index 00000000..f364b266 Binary files /dev/null and b/src/wp-admin/images/wp-logo-vs.png differ diff --git a/src/wp-admin/images/wp-logo.png b/src/wp-admin/images/wp-logo.png new file mode 100644 index 00000000..81e7d599 Binary files /dev/null and b/src/wp-admin/images/wp-logo.png differ diff --git a/src/wp-admin/images/wpspin_dark.gif b/src/wp-admin/images/wpspin_dark.gif new file mode 100644 index 00000000..daebe0db Binary files /dev/null and b/src/wp-admin/images/wpspin_dark.gif differ diff --git a/src/wp-admin/images/wpspin_light.gif b/src/wp-admin/images/wpspin_light.gif new file mode 100644 index 00000000..e10b97ff Binary files /dev/null and b/src/wp-admin/images/wpspin_light.gif differ diff --git a/src/wp-admin/images/xit.gif b/src/wp-admin/images/xit.gif new file mode 100644 index 00000000..6f1cc4f4 Binary files /dev/null and b/src/wp-admin/images/xit.gif differ diff --git a/src/wp-admin/images/yes.png b/src/wp-admin/images/yes.png new file mode 100644 index 00000000..2f86f0ae Binary files /dev/null and b/src/wp-admin/images/yes.png differ diff --git a/src/wp-admin/import.php b/src/wp-admin/import.php new file mode 100644 index 00000000..f94f7047 --- /dev/null +++ b/src/wp-admin/import.php @@ -0,0 +1,147 @@ +' . __('This screen lists links to plugins to import data from blogging/content management platforms. Choose the platform you want to import from, and click Install Now when you are prompted in the popup window. If your platform is not listed, click the link to search the plugin directory for other importer plugins to see if there is one for your platform.') . '

' . + '

' . __('In previous versions of WordPress, all the importers were built-in, but they have been turned into plugins as of version 3.0 since most people only use them once or infrequently.') . '

' . + '

' . __('For more information:') . '

' . + '

' . __('Documentation on Import') . '

' . + '

' . __('Support Forums') . '

' +); + +$popular_importers = array(); +if ( current_user_can('install_plugins') ) + $popular_importers = array( + 'blogger' => array( __('Blogger'), __('Install the Blogger importer to import posts, comments, and users from a Blogger blog.'), 'install' ), + 'wpcat2tag' => array(__('Categories and Tags Converter'), __('Install the category/tag converter to convert existing categories to tags or tags to categories, selectively.'), 'install', 'wp-cat2tag' ), + 'livejournal' => array( __( 'LiveJournal' ), __( 'Install the LiveJournal importer to import posts from LiveJournal using their API.' ), 'install' ), + 'movabletype' => array( __('Movable Type and TypePad'), __('Install the Movable Type importer to import posts and comments from a Movable Type or TypePad blog.'), 'install', 'mt' ), + 'opml' => array( __('Blogroll'), __('Install the blogroll importer to import links in OPML format.'), 'install' ), + 'rss' => array( __('RSS'), __('Install the RSS importer to import posts from an RSS feed.'), 'install' ), + 'wordpress' => array( 'WordPress', __('Install the WordPress importer to import posts, pages, comments, custom fields, categories, and tags from a WordPress export file.'), 'install' ) + ); + +if ( ! empty( $_GET['invalid'] ) && !empty($popular_importers[$_GET['invalid']][3]) ) { + wp_redirect( admin_url('import.php?import=' . $popular_importers[$_GET['invalid']][3]) ); + exit; +} + +add_thickbox(); +wp_enqueue_script( 'plugin-install' ); +wp_admin_css( 'plugin-install' ); + +require_once ('admin-header.php'); +$parent_file = 'tools.php'; +?> + +
+ +

+ +

%s importer is invalid or is not installed.'), esc_html( $_GET['invalid'] ) ); ?>

+ +

+ + $pop_data ) { + if ( isset($importers[$pop_importer] ) ) + continue; + if ( isset( $pop_data[3] ) && isset( $importers[ $pop_data[3] ] ) ) + continue; + + $importers[$pop_importer] = $popular_importers[$pop_importer]; +} + +if (empty ($importers)) { + echo '

'.__('No importers are available.').'

'; // TODO: make more helpful +} else { + uasort($importers, create_function('$a, $b', 'return strcmp($a[0], $b[0]);')); +?> + + + $data) { + $style = ('class="alternate"' == $style || 'class="alternate active"' == $style) ? '' : 'alternate'; + $action = ''; + if ( 'install' == $data[2] ) { + $plugin_slug = $id . '-importer'; + if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_slug ) ) { + // Looks like Importer is installed, But not active + $plugins = get_plugins( '/' . $plugin_slug ); + if ( !empty($plugins) ) { + $keys = array_keys($plugins); + $plugin_file = $plugin_slug . '/' . $keys[0]; + $action = '' . $data[0] . ''; + } + } + if ( empty($action) ) + $action = '' . $data[0] . ''; + } else { + $action = "{$data[0]}"; + } + + if ($style != '') + $style = 'class="'.$style.'"'; + echo " + + + + "; + } +?> + +
$action{$data[1]}
+' . sprintf( __('If the importer you need is not listed, search the plugins directory to see if an importer is available.'), esc_url( network_admin_url( 'plugin-install.php?tab=search&type=tag&s=importer' ) ) ) . '

'; +?> + +
+ + diff --git a/src/wp-admin/includes/admin.php b/src/wp-admin/includes/admin.php new file mode 100644 index 00000000..37f5c8ec --- /dev/null +++ b/src/wp-admin/includes/admin.php @@ -0,0 +1,64 @@ + diff --git a/src/wp-admin/includes/bookmark.php b/src/wp-admin/includes/bookmark.php new file mode 100644 index 00000000..0ed560c1 --- /dev/null +++ b/src/wp-admin/includes/bookmark.php @@ -0,0 +1,269 @@ +link_url = esc_url( $_GET['linkurl'] ); + else + $link->link_url = ''; + + if ( isset( $_GET['name'] ) ) + $link->link_name = esc_attr( $_GET['name'] ); + else + $link->link_name = ''; + + $link->link_visible = 'Y'; + + return $link; +} + +/** + * Delete link specified from database + * + * @since 2.0.0 + * + * @param int $link_id ID of the link to delete + * @return bool True + */ +function wp_delete_link( $link_id ) { + global $wpdb; + + do_action( 'delete_link', $link_id ); + + wp_delete_object_term_relationships( $link_id, 'link_category' ); + + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->links WHERE link_id = %d", $link_id ) ); + + do_action( 'deleted_link', $link_id ); + + clean_bookmark_cache( $link_id ); + + return true; +} + +/** + * Retrieves the link categories associated with the link specified. + * + * @since 2.1.0 + * + * @param int $link_id Link ID to look up + * @return array The requested link's categories + */ +function wp_get_link_cats( $link_id = 0 ) { + + $cats = wp_get_object_terms( $link_id, 'link_category', array('fields' => 'ids') ); + + return array_unique( $cats ); +} + +/** + * Retrieve link data based on ID. + * + * @since 2.0.0 + * + * @param int $link_id ID of link to retrieve + * @return object Link for editing + */ +function get_link_to_edit( $link_id ) { + return get_bookmark( $link_id, OBJECT, 'edit' ); +} + +/** + * This function inserts/updates links into/in the database. + * + * @since 2.0.0 + * + * @param array $linkdata Elements that make up the link to insert. + * @param bool $wp_error Optional. If true return WP_Error object on failure. + * @return int|WP_Error Value 0 or WP_Error on failure. The link ID on success. + */ +function wp_insert_link( $linkdata, $wp_error = false ) { + global $wpdb; + + $defaults = array( 'link_id' => 0, 'link_name' => '', 'link_url' => '', 'link_rating' => 0 ); + + $linkdata = wp_parse_args( $linkdata, $defaults ); + $linkdata = sanitize_bookmark( $linkdata, 'db' ); + + extract( stripslashes_deep( $linkdata ), EXTR_SKIP ); + + $update = false; + + if ( !empty( $link_id ) ) + $update = true; + + if ( trim( $link_name ) == '' ) { + if ( trim( $link_url ) != '' ) { + $link_name = $link_url; + } else { + return 0; + } + } + + if ( trim( $link_url ) == '' ) + return 0; + + if ( empty( $link_rating ) ) + $link_rating = 0; + + if ( empty( $link_image ) ) + $link_image = ''; + + if ( empty( $link_target ) ) + $link_target = ''; + + if ( empty( $link_visible ) ) + $link_visible = 'Y'; + + if ( empty( $link_owner ) ) + $link_owner = get_current_user_id(); + + if ( empty( $link_notes ) ) + $link_notes = ''; + + if ( empty( $link_description ) ) + $link_description = ''; + + if ( empty( $link_rss ) ) + $link_rss = ''; + + if ( empty( $link_rel ) ) + $link_rel = ''; + + // Make sure we set a valid category + if ( ! isset( $link_category ) || 0 == count( $link_category ) || !is_array( $link_category ) ) { + $link_category = array( get_option( 'default_link_category' ) ); + } + + if ( $update ) { + if ( false === $wpdb->update( $wpdb->links, compact('link_url', 'link_name', 'link_image', 'link_target', 'link_description', 'link_visible', 'link_rating', 'link_rel', 'link_notes', 'link_rss'), compact('link_id') ) ) { + if ( $wp_error ) + return new WP_Error( 'db_update_error', __( 'Could not update link in the database' ), $wpdb->last_error ); + else + return 0; + } + } else { + if ( false === $wpdb->insert( $wpdb->links, compact('link_url', 'link_name', 'link_image', 'link_target', 'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_rel', 'link_notes', 'link_rss') ) ) { + if ( $wp_error ) + return new WP_Error( 'db_insert_error', __( 'Could not insert link into the database' ), $wpdb->last_error ); + else + return 0; + } + $link_id = (int) $wpdb->insert_id; + } + + wp_set_link_cats( $link_id, $link_category ); + + if ( $update ) + do_action( 'edit_link', $link_id ); + else + do_action( 'add_link', $link_id ); + + clean_bookmark_cache( $link_id ); + + return $link_id; +} + +/** + * Update link with the specified link categories. + * + * @since 2.1.0 + * + * @param int $link_id ID of link to update + * @param array $link_categories Array of categories to + */ +function wp_set_link_cats( $link_id = 0, $link_categories = array() ) { + // If $link_categories isn't already an array, make it one: + if ( !is_array( $link_categories ) || 0 == count( $link_categories ) ) + $link_categories = array( get_option( 'default_link_category' ) ); + + $link_categories = array_map( 'intval', $link_categories ); + $link_categories = array_unique( $link_categories ); + + wp_set_object_terms( $link_id, $link_categories, 'link_category' ); + + clean_bookmark_cache( $link_id ); +} + +/** + * Update a link in the database. + * + * @since 2.0.0 + * + * @param array $linkdata Link data to update. + * @return int|WP_Error Value 0 or WP_Error on failure. The updated link ID on success. + */ +function wp_update_link( $linkdata ) { + $link_id = (int) $linkdata['link_id']; + + $link = get_bookmark( $link_id, ARRAY_A ); + + // Escape data pulled from DB. + $link = add_magic_quotes( $link ); + + // Passed link category list overwrites existing category list if not empty. + if ( isset( $linkdata['link_category'] ) && is_array( $linkdata['link_category'] ) + && 0 != count( $linkdata['link_category'] ) ) + $link_cats = $linkdata['link_category']; + else + $link_cats = $link['link_category']; + + // Merge old and new fields with new fields overwriting old ones. + $linkdata = array_merge( $link, $linkdata ); + $linkdata['link_category'] = $link_cats; + + return wp_insert_link( $linkdata ); +} + +?> diff --git a/src/wp-admin/includes/class-ftp-pure.php b/src/wp-admin/includes/class-ftp-pure.php new file mode 100644 index 00000000..c947f448 --- /dev/null +++ b/src/wp-admin/includes/class-ftp-pure.php @@ -0,0 +1,190 @@ +__construct($verb, $le); + } + + function __construct($verb=FALSE, $le=FALSE) { + parent::__construct(false, $verb, $le); + } + +// +// +// + + function _settimeout($sock) { + if(!@stream_set_timeout($sock, $this->_timeout)) { + $this->PushError('_settimeout','socket set send timeout'); + $this->_quit(); + return FALSE; + } + return TRUE; + } + + function _connect($host, $port) { + $this->SendMSG("Creating socket"); + $sock = @fsockopen($host, $port, $errno, $errstr, $this->_timeout); + if (!$sock) { + $this->PushError('_connect','socket connect failed', $errstr." (".$errno.")"); + return FALSE; + } + $this->_connected=true; + return $sock; + } + + function _readmsg($fnction="_readmsg"){ + if(!$this->_connected) { + $this->PushError($fnction, 'Connect first'); + return FALSE; + } + $result=true; + $this->_message=""; + $this->_code=0; + $go=true; + do { + $tmp=@fgets($this->_ftp_control_sock, 512); + if($tmp===false) { + $go=$result=false; + $this->PushError($fnction,'Read failed'); + } else { + $this->_message.=$tmp; + if(preg_match("/^([0-9]{3})(-(.*[".CRLF."]{1,2})+\\1)? [^".CRLF."]+[".CRLF."]{1,2}$/", $this->_message, $regs)) $go=false; + } + } while($go); + if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF; + $this->_code=(int)$regs[1]; + return $result; + } + + function _exec($cmd, $fnction="_exec") { + if(!$this->_ready) { + $this->PushError($fnction,'Connect first'); + return FALSE; + } + if($this->LocalEcho) echo "PUT > ",$cmd,CRLF; + $status=@fputs($this->_ftp_control_sock, $cmd.CRLF); + if($status===false) { + $this->PushError($fnction,'socket write failed'); + return FALSE; + } + $this->_lastaction=time(); + if(!$this->_readmsg($fnction)) return FALSE; + return TRUE; + } + + function _data_prepare($mode=FTP_ASCII) { + if(!$this->_settype($mode)) return FALSE; + if($this->_passive) { + if(!$this->_exec("PASV", "pasv")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message)); + $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3]; + $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]); + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + $this->_ftp_data_sock=@fsockopen($this->_datahost, $this->_dataport, $errno, $errstr, $this->_timeout); + if(!$this->_ftp_data_sock) { + $this->PushError("_data_prepare","fsockopen fails", $errstr." (".$errno.")"); + $this->_data_close(); + return FALSE; + } + else $this->_ftp_data_sock; + } else { + $this->SendMSG("Only passive connections available!"); + return FALSE; + } + return TRUE; + } + + function _data_read($mode=FTP_ASCII, $fp=NULL) { + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Only passive connections available!"); + return FALSE; + } + while (!feof($this->_ftp_data_sock)) { + $block=fread($this->_ftp_data_sock, $this->_ftp_buff_size); + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block); + if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block)); + else $out.=$block; + } + return $out; + } + + function _data_write($mode=FTP_ASCII, $fp=NULL) { + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Only passive connections available!"); + return FALSE; + } + if(is_resource($fp)) { + while(!feof($fp)) { + $block=fread($fp, $this->_ftp_buff_size); + if(!$this->_data_write_block($mode, $block)) return false; + } + } elseif(!$this->_data_write_block($mode, $fp)) return false; + return TRUE; + } + + function _data_write_block($mode, $block) { + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block); + do { + if(($t=@fwrite($this->_ftp_data_sock, $block))===FALSE) { + $this->PushError("_data_write","Can't write to socket"); + return FALSE; + } + $block=substr($block, $t); + } while(!empty($block)); + return true; + } + + function _data_close() { + @fclose($this->_ftp_data_sock); + $this->SendMSG("Disconnected data from remote host"); + return TRUE; + } + + function _quit($force=FALSE) { + if($this->_connected or $force) { + @fclose($this->_ftp_control_sock); + $this->_connected=false; + $this->SendMSG("Socket closed"); + } + } +} + +?> diff --git a/src/wp-admin/includes/class-ftp-sockets.php b/src/wp-admin/includes/class-ftp-sockets.php new file mode 100644 index 00000000..4026dd0b --- /dev/null +++ b/src/wp-admin/includes/class-ftp-sockets.php @@ -0,0 +1,250 @@ +__construct($verb, $le); + } + + function __construct($verb=FALSE, $le=FALSE) { + parent::__construct(true, $verb, $le); + } + +// +// +// + + function _settimeout($sock) { + if(!@socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) { + $this->PushError('_connect','socket set receive timeout',socket_strerror(socket_last_error($sock))); + @socket_close($sock); + return FALSE; + } + if(!@socket_set_option($sock, SOL_SOCKET , SO_SNDTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) { + $this->PushError('_connect','socket set send timeout',socket_strerror(socket_last_error($sock))); + @socket_close($sock); + return FALSE; + } + return true; + } + + function _connect($host, $port) { + $this->SendMSG("Creating socket"); + if(!($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) { + $this->PushError('_connect','socket create failed',socket_strerror(socket_last_error($sock))); + return FALSE; + } + if(!$this->_settimeout($sock)) return FALSE; + $this->SendMSG("Connecting to \"".$host.":".$port."\""); + if (!($res = @socket_connect($sock, $host, $port))) { + $this->PushError('_connect','socket connect failed',socket_strerror(socket_last_error($sock))); + @socket_close($sock); + return FALSE; + } + $this->_connected=true; + return $sock; + } + + function _readmsg($fnction="_readmsg"){ + if(!$this->_connected) { + $this->PushError($fnction,'Connect first'); + return FALSE; + } + $result=true; + $this->_message=""; + $this->_code=0; + $go=true; + do { + $tmp=@socket_read($this->_ftp_control_sock, 4096, PHP_BINARY_READ); + if($tmp===false) { + $go=$result=false; + $this->PushError($fnction,'Read failed', socket_strerror(socket_last_error($this->_ftp_control_sock))); + } else { + $this->_message.=$tmp; + $go = !preg_match("/^([0-9]{3})(-.+\\1)? [^".CRLF."]+".CRLF."$/Us", $this->_message, $regs); + } + } while($go); + if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF; + $this->_code=(int)$regs[1]; + return $result; + } + + function _exec($cmd, $fnction="_exec") { + if(!$this->_ready) { + $this->PushError($fnction,'Connect first'); + return FALSE; + } + if($this->LocalEcho) echo "PUT > ",$cmd,CRLF; + $status=@socket_write($this->_ftp_control_sock, $cmd.CRLF); + if($status===false) { + $this->PushError($fnction,'socket write failed', socket_strerror(socket_last_error($this->stream))); + return FALSE; + } + $this->_lastaction=time(); + if(!$this->_readmsg($fnction)) return FALSE; + return TRUE; + } + + function _data_prepare($mode=FTP_ASCII) { + if(!$this->_settype($mode)) return FALSE; + $this->SendMSG("Creating data socket"); + $this->_ftp_data_sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + if ($this->_ftp_data_sock < 0) { + $this->PushError('_data_prepare','socket create failed',socket_strerror(socket_last_error($this->_ftp_data_sock))); + return FALSE; + } + if(!$this->_settimeout($this->_ftp_data_sock)) { + $this->_data_close(); + return FALSE; + } + if($this->_passive) { + if(!$this->_exec("PASV", "pasv")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message)); + $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3]; + $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]); + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + if(!@socket_connect($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) { + $this->PushError("_data_prepare","socket_connect", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + else $this->_ftp_temp_sock=$this->_ftp_data_sock; + } else { + if(!@socket_getsockname($this->_ftp_control_sock, $addr, $port)) { + $this->PushError("_data_prepare","can't get control socket information", socket_strerror(socket_last_error($this->_ftp_control_sock))); + $this->_data_close(); + return FALSE; + } + if(!@socket_bind($this->_ftp_data_sock,$addr)){ + $this->PushError("_data_prepare","can't bind data socket", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + if(!@socket_listen($this->_ftp_data_sock)) { + $this->PushError("_data_prepare","can't listen data socket", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + if(!@socket_getsockname($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) { + $this->PushError("_data_prepare","can't get data socket information", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + if(!$this->_exec('PORT '.str_replace('.',',',$this->_datahost.'.'.($this->_dataport>>8).'.'.($this->_dataport&0x00FF)), "_port")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + } + return TRUE; + } + + function _data_read($mode=FTP_ASCII, $fp=NULL) { + $NewLine=$this->_eol_code[$this->OS_local]; + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock); + if($this->_ftp_temp_sock===FALSE) { + $this->PushError("_data_read","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock))); + $this->_data_close(); + return FALSE; + } + } + + while(($block=@socket_read($this->_ftp_temp_sock, $this->_ftp_buff_size, PHP_BINARY_READ))!==false) { + if($block==="") break; + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block); + if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block)); + else $out.=$block; + } + return $out; + } + + function _data_write($mode=FTP_ASCII, $fp=NULL) { + $NewLine=$this->_eol_code[$this->OS_local]; + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock); + if($this->_ftp_temp_sock===FALSE) { + $this->PushError("_data_write","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock))); + $this->_data_close(); + return false; + } + } + if(is_resource($fp)) { + while(!feof($fp)) { + $block=fread($fp, $this->_ftp_buff_size); + if(!$this->_data_write_block($mode, $block)) return false; + } + } elseif(!$this->_data_write_block($mode, $fp)) return false; + return true; + } + + function _data_write_block($mode, $block) { + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block); + do { + if(($t=@socket_write($this->_ftp_temp_sock, $block))===FALSE) { + $this->PushError("_data_write","socket_write", socket_strerror(socket_last_error($this->_ftp_temp_sock))); + $this->_data_close(); + return FALSE; + } + $block=substr($block, $t); + } while(!empty($block)); + return true; + } + + function _data_close() { + @socket_close($this->_ftp_temp_sock); + @socket_close($this->_ftp_data_sock); + $this->SendMSG("Disconnected data from remote host"); + return TRUE; + } + + function _quit() { + if($this->_connected) { + @socket_close($this->_ftp_control_sock); + $this->_connected=false; + $this->SendMSG("Socket closed"); + } + } +} +?> diff --git a/src/wp-admin/includes/class-ftp.php b/src/wp-admin/includes/class-ftp.php new file mode 100644 index 00000000..1e35e745 --- /dev/null +++ b/src/wp-admin/includes/class-ftp.php @@ -0,0 +1,906 @@ +__construct($port_mode); + } + + function __construct($port_mode=FALSE, $verb=FALSE, $le=FALSE) { + $this->LocalEcho=$le; + $this->Verbose=$verb; + $this->_lastaction=NULL; + $this->_error_array=array(); + $this->_eol_code=array(FTP_OS_Unix=>"\n", FTP_OS_Mac=>"\r", FTP_OS_Windows=>"\r\n"); + $this->AuthorizedTransferMode=array(FTP_AUTOASCII, FTP_ASCII, FTP_BINARY); + $this->OS_FullName=array(FTP_OS_Unix => 'UNIX', FTP_OS_Windows => 'WINDOWS', FTP_OS_Mac => 'MACOS'); + $this->AutoAsciiExt=array("ASP","BAT","C","CPP","CSS","CSV","JS","H","HTM","HTML","SHTML","INI","LOG","PHP3","PHTML","PL","PERL","SH","SQL","TXT"); + $this->_port_available=($port_mode==TRUE); + $this->SendMSG("Staring FTP client class".($this->_port_available?"":" without PORT mode support")); + $this->_connected=FALSE; + $this->_ready=FALSE; + $this->_can_restore=FALSE; + $this->_code=0; + $this->_message=""; + $this->_ftp_buff_size=4096; + $this->_curtype=NULL; + $this->SetUmask(0022); + $this->SetType(FTP_AUTOASCII); + $this->SetTimeout(30); + $this->Passive(!$this->_port_available); + $this->_login="anonymous"; + $this->_password="anon@ftp.com"; + $this->_features=array(); + $this->OS_local=FTP_OS_Unix; + $this->OS_remote=FTP_OS_Unix; + $this->features=array(); + if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->OS_local=FTP_OS_Windows; + elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') $this->OS_local=FTP_OS_Mac; + } + +// +// +// + + function parselisting($line) { + $is_windows = ($this->OS_remote == FTP_OS_Windows); + if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|) +(.+)/",$line,$lucifer)) { + $b = array(); + if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix + $b['isdir'] = ($lucifer[7]==""); + if ( $b['isdir'] ) + $b['type'] = 'd'; + else + $b['type'] = 'f'; + $b['size'] = $lucifer[7]; + $b['month'] = $lucifer[1]; + $b['day'] = $lucifer[2]; + $b['year'] = $lucifer[3]; + $b['hour'] = $lucifer[4]; + $b['minute'] = $lucifer[5]; + $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]); + $b['am/pm'] = $lucifer[6]; + $b['name'] = $lucifer[8]; + } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) { + //echo $line."\n"; + $lcount=count($lucifer); + if ($lcount<8) return ''; + $b = array(); + $b['isdir'] = $lucifer[0]{0} === "d"; + $b['islink'] = $lucifer[0]{0} === "l"; + if ( $b['isdir'] ) + $b['type'] = 'd'; + elseif ( $b['islink'] ) + $b['type'] = 'l'; + else + $b['type'] = 'f'; + $b['perms'] = $lucifer[0]; + $b['number'] = $lucifer[1]; + $b['owner'] = $lucifer[2]; + $b['group'] = $lucifer[3]; + $b['size'] = $lucifer[4]; + if ($lcount==8) { + sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']); + sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']); + $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']); + $b['name'] = $lucifer[7]; + } else { + $b['month'] = $lucifer[5]; + $b['day'] = $lucifer[6]; + if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) { + $b['year'] = date("Y"); + $b['hour'] = $l2[1]; + $b['minute'] = $l2[2]; + } else { + $b['year'] = $lucifer[7]; + $b['hour'] = 0; + $b['minute'] = 0; + } + $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute'])); + $b['name'] = $lucifer[8]; + } + } + + return $b; + } + + function SendMSG($message = "", $crlf=true) { + if ($this->Verbose) { + echo $message.($crlf?CRLF:""); + flush(); + } + return TRUE; + } + + function SetType($mode=FTP_AUTOASCII) { + if(!in_array($mode, $this->AuthorizedTransferMode)) { + $this->SendMSG("Wrong type"); + return FALSE; + } + $this->_type=$mode; + $this->SendMSG("Transfer type: ".($this->_type==FTP_BINARY?"binary":($this->_type==FTP_ASCII?"ASCII":"auto ASCII") ) ); + return TRUE; + } + + function _settype($mode=FTP_ASCII) { + if($this->_ready) { + if($mode==FTP_BINARY) { + if($this->_curtype!=FTP_BINARY) { + if(!$this->_exec("TYPE I", "SetType")) return FALSE; + $this->_curtype=FTP_BINARY; + } + } elseif($this->_curtype!=FTP_ASCII) { + if(!$this->_exec("TYPE A", "SetType")) return FALSE; + $this->_curtype=FTP_ASCII; + } + } else return FALSE; + return TRUE; + } + + function Passive($pasv=NULL) { + if(is_null($pasv)) $this->_passive=!$this->_passive; + else $this->_passive=$pasv; + if(!$this->_port_available and !$this->_passive) { + $this->SendMSG("Only passive connections available!"); + $this->_passive=TRUE; + return FALSE; + } + $this->SendMSG("Passive mode ".($this->_passive?"on":"off")); + return TRUE; + } + + function SetServer($host, $port=21, $reconnect=true) { + if(!is_long($port)) { + $this->verbose=true; + $this->SendMSG("Incorrect port syntax"); + return FALSE; + } else { + $ip=@gethostbyname($host); + $dns=@gethostbyaddr($host); + if(!$ip) $ip=$host; + if(!$dns) $dns=$host; + // Validate the IPAddress PHP4 returns -1 for invalid, PHP5 false + // -1 === "255.255.255.255" which is the broadcast address which is also going to be invalid + $ipaslong = ip2long($ip); + if ( ($ipaslong == false) || ($ipaslong === -1) ) { + $this->SendMSG("Wrong host name/address \"".$host."\""); + return FALSE; + } + $this->_host=$ip; + $this->_fullhost=$dns; + $this->_port=$port; + $this->_dataport=$port-1; + } + $this->SendMSG("Host \"".$this->_fullhost."(".$this->_host."):".$this->_port."\""); + if($reconnect){ + if($this->_connected) { + $this->SendMSG("Reconnecting"); + if(!$this->quit(FTP_FORCE)) return FALSE; + if(!$this->connect()) return FALSE; + } + } + return TRUE; + } + + function SetUmask($umask=0022) { + $this->_umask=$umask; + umask($this->_umask); + $this->SendMSG("UMASK 0".decoct($this->_umask)); + return TRUE; + } + + function SetTimeout($timeout=30) { + $this->_timeout=$timeout; + $this->SendMSG("Timeout ".$this->_timeout); + if($this->_connected) + if(!$this->_settimeout($this->_ftp_control_sock)) return FALSE; + return TRUE; + } + + function connect($server=NULL) { + if(!empty($server)) { + if(!$this->SetServer($server)) return false; + } + if($this->_ready) return true; + $this->SendMsg('Local OS : '.$this->OS_FullName[$this->OS_local]); + if(!($this->_ftp_control_sock = $this->_connect($this->_host, $this->_port))) { + $this->SendMSG("Error : Cannot connect to remote host \"".$this->_fullhost." :".$this->_port."\""); + return FALSE; + } + $this->SendMSG("Connected to remote host \"".$this->_fullhost.":".$this->_port."\". Waiting for greeting."); + do { + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + $this->_lastaction=time(); + } while($this->_code<200); + $this->_ready=true; + $syst=$this->systype(); + if(!$syst) $this->SendMSG("Can't detect remote OS"); + else { + if(preg_match("/win|dos|novell/i", $syst[0])) $this->OS_remote=FTP_OS_Windows; + elseif(preg_match("/os/i", $syst[0])) $this->OS_remote=FTP_OS_Mac; + elseif(preg_match("/(li|u)nix/i", $syst[0])) $this->OS_remote=FTP_OS_Unix; + else $this->OS_remote=FTP_OS_Mac; + $this->SendMSG("Remote OS: ".$this->OS_FullName[$this->OS_remote]); + } + if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled"); + else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features))); + return TRUE; + } + + function quit($force=false) { + if($this->_ready) { + if(!$this->_exec("QUIT") and !$force) return FALSE; + if(!$this->_checkCode() and !$force) return FALSE; + $this->_ready=false; + $this->SendMSG("Session finished"); + } + $this->_quit(); + return TRUE; + } + + function login($user=NULL, $pass=NULL) { + if(!is_null($user)) $this->_login=$user; + else $this->_login="anonymous"; + if(!is_null($pass)) $this->_password=$pass; + else $this->_password="anon@anon.com"; + if(!$this->_exec("USER ".$this->_login, "login")) return FALSE; + if(!$this->_checkCode()) return FALSE; + if($this->_code!=230) { + if(!$this->_exec((($this->_code==331)?"PASS ":"ACCT ").$this->_password, "login")) return FALSE; + if(!$this->_checkCode()) return FALSE; + } + $this->SendMSG("Authentication succeeded"); + if(empty($this->_features)) { + if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled"); + else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features))); + } + return TRUE; + } + + function pwd() { + if(!$this->_exec("PWD", "pwd")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return ereg_replace("^[0-9]{3} \"(.+)\".+", "\\1", $this->_message); + } + + function cdup() { + if(!$this->_exec("CDUP", "cdup")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return true; + } + + function chdir($pathname) { + if(!$this->_exec("CWD ".$pathname, "chdir")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function rmdir($pathname) { + if(!$this->_exec("RMD ".$pathname, "rmdir")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function mkdir($pathname) { + if(!$this->_exec("MKD ".$pathname, "mkdir")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function rename($from, $to) { + if(!$this->_exec("RNFR ".$from, "rename")) return FALSE; + if(!$this->_checkCode()) return FALSE; + if($this->_code==350) { + if(!$this->_exec("RNTO ".$to, "rename")) return FALSE; + if(!$this->_checkCode()) return FALSE; + } else return FALSE; + return TRUE; + } + + function filesize($pathname) { + if(!isset($this->_features["SIZE"])) { + $this->PushError("filesize", "not supported by server"); + return FALSE; + } + if(!$this->_exec("SIZE ".$pathname, "filesize")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message); + } + + function abort() { + if(!$this->_exec("ABOR", "abort")) return FALSE; + if(!$this->_checkCode()) { + if($this->_code!=426) return FALSE; + if(!$this->_readmsg("abort")) return FALSE; + if(!$this->_checkCode()) return FALSE; + } + return true; + } + + function mdtm($pathname) { + if(!isset($this->_features["MDTM"])) { + $this->PushError("mdtm", "not supported by server"); + return FALSE; + } + if(!$this->_exec("MDTM ".$pathname, "mdtm")) return FALSE; + if(!$this->_checkCode()) return FALSE; + $mdtm = ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message); + $date = sscanf($mdtm, "%4d%2d%2d%2d%2d%2d"); + $timestamp = mktime($date[3], $date[4], $date[5], $date[1], $date[2], $date[0]); + return $timestamp; + } + + function systype() { + if(!$this->_exec("SYST", "systype")) return FALSE; + if(!$this->_checkCode()) return FALSE; + $DATA = explode(" ", $this->_message); + return array($DATA[1], $DATA[3]); + } + + function delete($pathname) { + if(!$this->_exec("DELE ".$pathname, "delete")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function site($command, $fnction="site") { + if(!$this->_exec("SITE ".$command, $fnction)) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function chmod($pathname, $mode) { + if(!$this->site( sprintf('CHMOD %o %s', $mode, $pathname), "chmod")) return FALSE; + return TRUE; + } + + function restore($from) { + if(!isset($this->_features["REST"])) { + $this->PushError("restore", "not supported by server"); + return FALSE; + } + if($this->_curtype!=FTP_BINARY) { + $this->PushError("restore", "can't restore in ASCII mode"); + return FALSE; + } + if(!$this->_exec("REST ".$from, "resore")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function features() { + if(!$this->_exec("FEAT", "features")) return FALSE; + if(!$this->_checkCode()) return FALSE; + $f=preg_split("/[".CRLF."]+/", preg_replace("/[0-9]{3}[ -].*[".CRLF."]+/", "", $this->_message), -1, PREG_SPLIT_NO_EMPTY); + $this->_features=array(); + foreach($f as $k=>$v) { + $v=explode(" ", trim($v)); + $this->_features[array_shift($v)]=$v; + } + return true; + } + + function rawlist($pathname="", $arg="") { + return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "LIST", "rawlist"); + } + + function nlist($pathname="") { + return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "NLST", "nlist"); + } + + function is_exists($pathname) { + return $this->file_exists($pathname); + } + + function file_exists($pathname) { + $exists=true; + if(!$this->_exec("RNFR ".$pathname, "rename")) $exists=FALSE; + else { + if(!$this->_checkCode()) $exists=FALSE; + $this->abort(); + } + if($exists) $this->SendMSG("Remote file ".$pathname." exists"); + else $this->SendMSG("Remote file ".$pathname." does not exist"); + return $exists; + } + + function fget($fp, $remotefile,$rest=0) { + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($remotefile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("RETR ".$remotefile, "get")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $out=$this->_data_read($mode, $fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $out; + } + + function get($remotefile, $localfile=NULL, $rest=0) { + if(is_null($localfile)) $localfile=$remotefile; + if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten"); + $fp = @fopen($localfile, "w"); + if (!$fp) { + $this->PushError("get","can't open local file", "Cannot create \"".$localfile."\""); + return FALSE; + } + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($remotefile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + fclose($fp); + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("RETR ".$remotefile, "get")) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + $out=$this->_data_read($mode, $fp); + fclose($fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $out; + } + + function fput($remotefile, $fp) { + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($remotefile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("STOR ".$remotefile, "put")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $ret=$this->_data_write($mode, $fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $ret; + } + + function put($localfile, $remotefile=NULL, $rest=0) { + if(is_null($remotefile)) $remotefile=$localfile; + if (!file_exists($localfile)) { + $this->PushError("put","can't open local file", "No such file or directory \"".$localfile."\""); + return FALSE; + } + $fp = @fopen($localfile, "r"); + + if (!$fp) { + $this->PushError("put","can't open local file", "Cannot read file \"".$localfile."\""); + return FALSE; + } + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($localfile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + fclose($fp); + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("STOR ".$remotefile, "put")) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + $ret=$this->_data_write($mode, $fp); + fclose($fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $ret; + } + + function mput($local=".", $remote=NULL, $continious=false) { + $local=realpath($local); + if(!@file_exists($local)) { + $this->PushError("mput","can't open local folder", "Cannot stat folder \"".$local."\""); + return FALSE; + } + if(!is_dir($local)) return $this->put($local, $remote); + if(empty($remote)) $remote="."; + elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE; + if($handle = opendir($local)) { + $list=array(); + while (false !== ($file = readdir($handle))) { + if ($file != "." && $file != "..") $list[]=$file; + } + closedir($handle); + } else { + $this->PushError("mput","can't open local folder", "Cannot read folder \"".$local."\""); + return FALSE; + } + if(empty($list)) return TRUE; + $ret=true; + foreach($list as $el) { + if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el); + else $t=$this->put($local."/".$el, $remote."/".$el); + if(!$t) { + $ret=FALSE; + if(!$continious) break; + } + } + return $ret; + + } + + function mget($remote, $local=".", $continious=false) { + $list=$this->rawlist($remote, "-lA"); + if($list===false) { + $this->PushError("mget","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); + return FALSE; + } + if(empty($list)) return true; + if(!@file_exists($local)) { + if(!@mkdir($local)) { + $this->PushError("mget","can't create local folder", "Cannot create folder \"".$local."\""); + return FALSE; + } + } + foreach($list as $k=>$v) { + $list[$k]=$this->parselisting($v); + if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]); + } + $ret=true; + foreach($list as $el) { + if($el["type"]=="d") { + if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) { + $this->PushError("mget", "can't copy folder", "Can't copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\""); + $ret=false; + if(!$continious) break; + } + } else { + if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) { + $this->PushError("mget", "can't copy file", "Can't copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\""); + $ret=false; + if(!$continious) break; + } + } + @chmod($local."/".$el["name"], $el["perms"]); + $t=strtotime($el["date"]); + if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t); + } + return $ret; + } + + function mdel($remote, $continious=false) { + $list=$this->rawlist($remote, "-la"); + if($list===false) { + $this->PushError("mdel","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); + return false; + } + + foreach($list as $k=>$v) { + $list[$k]=$this->parselisting($v); + if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]); + } + $ret=true; + + foreach($list as $el) { + if ( empty($el) ) + continue; + + if($el["type"]=="d") { + if(!$this->mdel($remote."/".$el["name"], $continious)) { + $ret=false; + if(!$continious) break; + } + } else { + if (!$this->delete($remote."/".$el["name"])) { + $this->PushError("mdel", "can't delete file", "Can't delete remote file \"".$remote."/".$el["name"]."\""); + $ret=false; + if(!$continious) break; + } + } + } + + if(!$this->rmdir($remote)) { + $this->PushError("mdel", "can't delete folder", "Can't delete remote folder \"".$remote."/".$el["name"]."\""); + $ret=false; + } + return $ret; + } + + function mmkdir($dir, $mode = 0777) { + if(empty($dir)) return FALSE; + if($this->is_exists($dir) or $dir == "/" ) return TRUE; + if(!$this->mmkdir(dirname($dir), $mode)) return false; + $r=$this->mkdir($dir, $mode); + $this->chmod($dir,$mode); + return $r; + } + + function glob($pattern, $handle=NULL) { + $path=$output=null; + if(PHP_OS=='WIN32') $slash='\\'; + else $slash='/'; + $lastpos=strrpos($pattern,$slash); + if(!($lastpos===false)) { + $path=substr($pattern,0,-$lastpos-1); + $pattern=substr($pattern,$lastpos); + } else $path=getcwd(); + if(is_array($handle) and !empty($handle)) { + while($dir=each($handle)) { + if($this->glob_pattern_match($pattern,$dir)) + $output[]=$dir; + } + } else { + $handle=@opendir($path); + if($handle===false) return false; + while($dir=readdir($handle)) { + if($this->glob_pattern_match($pattern,$dir)) + $output[]=$dir; + } + closedir($handle); + } + if(is_array($output)) return $output; + return false; + } + + function glob_pattern_match($pattern,$string) { + $out=null; + $chunks=explode(';',$pattern); + foreach($chunks as $pattern) { + $escape=array('$','^','.','{','}','(',')','[',']','|'); + while(strpos($pattern,'**')!==false) + $pattern=str_replace('**','*',$pattern); + foreach($escape as $probe) + $pattern=str_replace($probe,"\\$probe",$pattern); + $pattern=str_replace('?*','*', + str_replace('*?','*', + str_replace('*',".*", + str_replace('?','.{1,1}',$pattern)))); + $out[]=$pattern; + } + if(count($out)==1) return($this->glob_regexp("^$out[0]$",$string)); + else { + foreach($out as $tester) + if($this->my_regexp("^$tester$",$string)) return true; + } + return false; + } + + function glob_regexp($pattern,$probe) { + $sensitive=(PHP_OS!='WIN32'); + return ($sensitive? + ereg($pattern,$probe): + eregi($pattern,$probe) + ); + } + + function dirlist($remote) { + $list=$this->rawlist($remote, "-la"); + if($list===false) { + $this->PushError("dirlist","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); + return false; + } + + $dirlist = array(); + foreach($list as $k=>$v) { + $entry=$this->parselisting($v); + if ( empty($entry) ) + continue; + + if($entry["name"]=="." or $entry["name"]=="..") + continue; + + $dirlist[$entry['name']] = $entry; + } + + return $dirlist; + } +// +// +// + function _checkCode() { + return ($this->_code<400 and $this->_code>0); + } + + function _list($arg="", $cmd="LIST", $fnction="_list") { + if(!$this->_data_prepare()) return false; + if(!$this->_exec($cmd.$arg, $fnction)) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $out=""; + if($this->_code<200) { + $out=$this->_data_read(); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + if($out === FALSE ) return FALSE; + $out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY); +// $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out)); + } + return $out; + } + +// +// +// +// Gnre une erreur pour traitement externe la classe + function PushError($fctname,$msg,$desc=false){ + $error=array(); + $error['time']=time(); + $error['fctname']=$fctname; + $error['msg']=$msg; + $error['desc']=$desc; + if($desc) $tmp=' ('.$desc.')'; else $tmp=''; + $this->SendMSG($fctname.': '.$msg.$tmp); + return(array_push($this->_error_array,$error)); + } + +// Rcupre une erreur externe + function PopError(){ + if(count($this->_error_array)) return(array_pop($this->_error_array)); + else return(false); + } +} + +$mod_sockets=TRUE; +if (!extension_loaded('sockets')) { + $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : ''; + if(!@dl($prefix . 'sockets.' . PHP_SHLIB_SUFFIX)) $mod_sockets=FALSE; +} + +require_once "class-ftp-".($mod_sockets?"sockets":"pure").".php"; +?> diff --git a/src/wp-admin/includes/class-pclzip.php b/src/wp-admin/includes/class-pclzip.php new file mode 100644 index 00000000..5e6a619b --- /dev/null +++ b/src/wp-admin/includes/class-pclzip.php @@ -0,0 +1,5687 @@ +zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + else { + } + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) + { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Trace + + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + } + else { + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Trace + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->zipname)) + { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return 0; + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + { + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } + + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) + { + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + { + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) + { + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } + else { + return($this->error_code); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) + { + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } + else { + return($v_value); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); + } + else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } + else { + return($this->error_string." [code ".$this->error_code."]"); + } + } + } + // -------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) + { + $v_result = true; + + // ----- Reset the file system cache + clearstatcache(); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + $v_result=1; + + // ----- Read the options + $i=0; + while ($i<$p_size) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if ( is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + } + else { + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { + + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } + else if (is_integer($p_options_list[$i+1])) { + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_work_list = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + .$p_options_list[$i]."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Next options + $i++; + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + + // ----- Return + return PclZip::errorCode(); + } + } + } + } + + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result=1; + + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } + + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); + + if($last == 'g') + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit*1073741824; + if($last == 'm') + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit*1048576; + if($last == 'k') + $v_memory_limit = $v_memory_limit*1024; + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); + + + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + $v_result=1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + break; + + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['comment'] = $v_value; + break; + + case PCLZIP_ATT_FILE_MTIME : + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['mtime'] = $v_value; + break; + + case PCLZIP_ATT_FILE_CONTENT : + $p_filedescr['content'] = $v_value; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '".$v_key."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + return PclZip::errorCode(); + } + } + } + } + + // end foreach + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // This method look for each item of the list to see if its a file, a folder + // or a string to be added as file. For any other type of files (link, other) + // just ignore the item. + // Then prepare the information that will be stored for that file. + // When its a folder, expand the folder with all the files that are in that + // folder (recursively). + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + $v_result=1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i=0; $iprivCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } + else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } + } + + $v_dirlist_nb++; + } + + @closedir($v_folder_handler); + } + else { + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } + else { + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + + // ----- Close + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) + { + + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + + // ----- Return + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + $v_result=1; + + // ----- Look if already open + if ($this->zip_fd != 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + $v_result=1; + + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Create the Central Dir files header + for ($i=0,$v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + + // ----- Loop on the files + for ($j=0; ($jprivAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for regular file + if ($p_filedescr['type']=='file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for regular folder + else if ($p_filedescr['type']=='folder') { + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for virtual file + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); + } + + + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } + else { + $p_header['mtime'] = filemtime($p_filename); + } + + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } + else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } + + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Use "in memory" zip algo + else { + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Close the file + @fclose($v_file); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + + } + + } + + // ----- Look for a virtual file (a file from string) + else if ($p_filedescr['type'] == 'virtual_file') { + + $v_content = $p_filedescr['content']; + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } + + // ----- Look for a directory + else if ($p_filedescr['type'] == 'folder') { + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } + + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) + { + return $v_result; + } + } + } + + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=PCLZIP_ERR_NO_ERROR; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file); + @gzclose($v_file_compressed); + + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); + } + + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); + + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) + { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } + else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } + else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + else { + $p_remove_all_dir = 0; + } + + + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } + + // ----- Look for path and/or short name change + else { + + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + } + else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ( (substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ( (substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ( (substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + } + else { + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + $v_result=1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result=1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check the path + if ( ($p_path == "") + || ( (substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) + { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + + // ----- Check compression method + if ( ($v_extract) + && ( ($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); + + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); + + return PclZip::errorCode(); + } + } + + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + $v_extract = false; + } + + // ----- Look for real extraction + if ($v_extract) + { + + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + + $v_string = ''; + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for extraction in standard output + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } + + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { + + $p_entry['status'] = "filtered"; + + return $v_result; + } + + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + + // ----- Look for path to remove + else if ($p_remove_path != "") + { + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + } + } + + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } + + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { + + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + + return PclZip::errorCode(); + } + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); + + return PclZip::errorCode(); + } + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); + + return PclZip::errorCode(); + } + } + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + // ----- Change the file status + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + return PclZip::errorCode(); + } + } + } + else { + } + } + + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + + + } + else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } + + + // ----- Look for using temporary file to unzip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Look for extract in memory + else { + + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + } + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } + + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); + + // ----- Close the temporary file + @fclose($v_dest_file); + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; + } + + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); + + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + // ----- Trace + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { + + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } + else { + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + { + $v_result=1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } + + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + + // ----- Extract properties + + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + } + + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + $v_result=1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) + { + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } + + $v_pos = ftell($this->zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + } + else + $p_central_dir['comment'] = ''; + + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; + + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + + return $v_result; + } + + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + else { + $v_found = true; + } + + // ----- Look for deletion + if ($v_found) + { + unset($v_header_list[$v_nb_extracted]); + } + else + { + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Look which file need to be kept + for ($i=0; $izip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); + + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); + + // ----- Re-Create the Central Dir files header + for ($i=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Remove every files : reset the file + else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); + + if (($v_result = $this->privOpenFd('wb')) != 1) { + return $v_result; + } + + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + return $v_result; + } + + $this->privCloseFd(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) + { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) + { + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) + { + // ----- Look for parent directory + if ($p_parent_dir != "") + { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + return $v_result; + } + } + } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) + { + + // ----- Nothing to merge, so merge is a success + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Look if the archive exists + if (!is_file($this->zipname)) + { + + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) + { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + return $v_result; + } + + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) + { + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + { + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } + else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } + else { + $this->error_code = 0; + $this->error_string = ''; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); + + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + } + // End of class + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathReduction() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilPathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; + } + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // -------------------------------------------------------------------------------- + function PclZipUtilPathInclusion($p_dir, $p_path) + { + $v_result = 1; + + // ----- Look for path beginning by ./ + if ( ($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + } + if ( ($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + } + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilCopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) + { + $v_result = 1; + + if ($p_mode==0) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilRename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // -------------------------------------------------------------------------------- + function PclZipUtilRename($p_src, $p_dest) + { + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilOptionText() + // Description : + // Translate option value in text. Mainly for debug purpose. + // Parameters : + // $p_option : the option value. + // Return Values : + // The option text value. + // -------------------------------------------------------------------------------- + function PclZipUtilOptionText($p_option) + { + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if (( ($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; + } + } + + $v_result = 'Unknown'; + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilTranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // -------------------------------------------------------------------------------- + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // -------------------------------------------------------------------------------- + + +?> diff --git a/src/wp-admin/includes/class-wp-comments-list-table.php b/src/wp-admin/includes/class-wp-comments-list-table.php new file mode 100644 index 00000000..90c158fe --- /dev/null +++ b/src/wp-admin/includes/class-wp-comments-list-table.php @@ -0,0 +1,557 @@ + 'comments', + 'singular' => 'comment', + 'ajax' => true, + ) ); + } + + function ajax_user_can() { + return current_user_can('edit_posts'); + } + + function prepare_items() { + global $post_id, $comment_status, $search, $comment_type; + + $comment_status = isset( $_REQUEST['comment_status'] ) ? $_REQUEST['comment_status'] : 'all'; + if ( !in_array( $comment_status, array( 'all', 'moderated', 'approved', 'spam', 'trash' ) ) ) + $comment_status = 'all'; + + $comment_type = !empty( $_REQUEST['comment_type'] ) ? $_REQUEST['comment_type'] : ''; + + $search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : ''; + + $user_id = ( isset( $_REQUEST['user_id'] ) ) ? $_REQUEST['user_id'] : ''; + + $orderby = ( isset( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : ''; + $order = ( isset( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : ''; + + $comments_per_page = $this->get_per_page( $comment_status ); + + $doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX; + + if ( isset( $_REQUEST['number'] ) ) { + $number = (int) $_REQUEST['number']; + } + else { + $number = $comments_per_page + min( 8, $comments_per_page ); // Grab a few extra + } + + $page = $this->get_pagenum(); + + if ( isset( $_REQUEST['start'] ) ) { + $start = $_REQUEST['start']; + } else { + $start = ( $page - 1 ) * $comments_per_page; + } + + if ( $doing_ajax && isset( $_REQUEST['offset'] ) ) { + $start += $_REQUEST['offset']; + } + + $status_map = array( + 'moderated' => 'hold', + 'approved' => 'approve' + ); + + $args = array( + 'status' => isset( $status_map[$comment_status] ) ? $status_map[$comment_status] : $comment_status, + 'search' => $search, + 'user_id' => $user_id, + 'offset' => $start, + 'number' => $number, + 'post_id' => $post_id, + 'type' => $comment_type, + 'orderby' => $orderby, + 'order' => $order, + ); + + $_comments = get_comments( $args ); + + update_comment_cache( $_comments ); + + $this->items = array_slice( $_comments, 0, $comments_per_page ); + $this->extra_items = array_slice( $_comments, $comments_per_page ); + + $total_comments = get_comments( array_merge( $args, array('count' => true, 'offset' => 0, 'number' => 0) ) ); + + $_comment_post_ids = array(); + foreach ( $_comments as $_c ) { + $_comment_post_ids[] = $_c->comment_post_ID; + } + + $this->pending_count = get_pending_comments_num( $_comment_post_ids ); + + $this->set_pagination_args( array( + 'total_items' => $total_comments, + 'per_page' => $comments_per_page, + ) ); + } + + function get_per_page( $comment_status = 'all' ) { + $comments_per_page = $this->get_items_per_page( 'edit_comments_per_page' ); + $comments_per_page = apply_filters( 'comments_per_page', $comments_per_page, $comment_status ); + return $comments_per_page; + } + + function no_items() { + global $comment_status; + + if ( 'moderated' == $comment_status ) + _e( 'No comments awaiting moderation… yet.' ); + else + _e( 'No comments found.' ); + } + + function get_views() { + global $post_id, $comment_status; + + $status_links = array(); + $num_comments = ( $post_id ) ? wp_count_comments( $post_id ) : wp_count_comments(); + //, number_format_i18n($num_comments->moderated) ), "" . number_format_i18n($num_comments->moderated) . ""), + //, number_format_i18n($num_comments->spam) ), "" . number_format_i18n($num_comments->spam) . "") + $stati = array( + 'all' => _nx_noop('All', 'All', 'comments'), // singular not used + 'moderated' => _n_noop('Pending (%s)', 'Pending (%s)'), + 'approved' => _n_noop('Approved', 'Approved'), // singular not used + 'spam' => _n_noop('Spam (%s)', 'Spam (%s)'), + 'trash' => _n_noop('Trash (%s)', 'Trash (%s)') + ); + + if ( !EMPTY_TRASH_DAYS ) + unset($stati['trash']); + + $link = 'edit-comments.php'; + if ( !empty($comment_type) && 'all' != $comment_type ) + $link = add_query_arg( 'comment_type', $comment_type, $link ); + + foreach ( $stati as $status => $label ) { + $class = ( $status == $comment_status ) ? ' class="current"' : ''; + + if ( !isset( $num_comments->$status ) ) + $num_comments->$status = 10; + $link = add_query_arg( 'comment_status', $status, $link ); + if ( $post_id ) + $link = add_query_arg( 'p', absint( $post_id ), $link ); + /* + // I toyed with this, but decided against it. Leaving it in here in case anyone thinks it is a good idea. ~ Mark + if ( !empty( $_REQUEST['s'] ) ) + $link = add_query_arg( 's', esc_attr( stripslashes( $_REQUEST['s'] ) ), $link ); + */ + $status_links[$status] = "" . sprintf( + translate_nooped_plural( $label, $num_comments->$status ), + number_format_i18n( $num_comments->$status ) + ) . ''; + } + + $status_links = apply_filters( 'comment_status_links', $status_links ); + return $status_links; + } + + function get_bulk_actions() { + global $comment_status; + + $actions = array(); + if ( in_array( $comment_status, array( 'all', 'approved' ) ) ) + $actions['unapprove'] = __( 'Unapprove' ); + if ( in_array( $comment_status, array( 'all', 'moderated', 'spam' ) ) ) + $actions['approve'] = __( 'Approve' ); + if ( in_array( $comment_status, array( 'all', 'moderated', 'approved' ) ) ) + $actions['spam'] = _x( 'Mark as Spam', 'comment' ); + + if ( 'trash' == $comment_status ) + $actions['untrash'] = __( 'Restore' ); + elseif ( 'spam' == $comment_status ) + $actions['unspam'] = _x( 'Not Spam', 'comment' ); + + if ( in_array( $comment_status, array( 'trash', 'spam' ) ) || !EMPTY_TRASH_DAYS ) + $actions['delete'] = __( 'Delete Permanently' ); + else + $actions['trash'] = __( 'Move to Trash' ); + + return $actions; + } + + function extra_tablenav( $which ) { + global $comment_status, $comment_type; +?> +
+ + + 'post-query-submit' ) ); + } + + if ( ( 'spam' == $comment_status || 'trash' == $comment_status ) && current_user_can( 'moderate_comments' ) ) { + wp_nonce_field( 'bulk-destroy', '_destroy_nonce' ); + $title = ( 'spam' == $comment_status ) ? esc_attr__( 'Empty Spam' ) : esc_attr__( 'Empty Trash' ); + submit_button( $title, 'button-secondary apply', 'delete_all', false ); + } + do_action( 'manage_comments_nav', $comment_status ); + echo '
'; + } + + function current_action() { + if ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) ) + return 'delete_all'; + + return parent::current_action(); + } + + function get_columns() { + global $post_id; + + $columns = array(); + + if ( $this->checkbox ) + $columns['cb'] = ''; + + $columns['author'] = __( 'Author' ); + $columns['comment'] = _x( 'Comment', 'column name' ); + + if ( !$post_id ) + $columns['response'] = _x( 'In Response To', 'column name' ); + + return $columns; + } + + function get_sortable_columns() { + return array( + 'author' => 'comment_author', + 'response' => 'comment_post_ID' + ); + } + + function display() { + extract( $this->_args ); + + wp_nonce_field( "fetch-list-" . get_class( $this ), '_ajax_fetch_list_nonce' ); + + $this->display_tablenav( 'top' ); + +?> + + + + print_column_headers(); ?> + + + + + + print_column_headers( false ); ?> + + + + + display_rows_or_placeholder(); ?> + + + + items = $this->extra_items; $this->display_rows(); ?> + +
+display_tablenav( 'bottom' ); + } + + function single_row( $a_comment ) { + global $post, $comment, $the_comment_status; + + $comment = $a_comment; + $the_comment_status = wp_get_comment_status( $comment->comment_ID ); + + $post = get_post( $comment->comment_post_ID ); + + $this->user_can = current_user_can( 'edit_comment', $comment->comment_ID ); + + echo ""; + echo $this->single_row_columns( $comment ); + echo ""; + } + + function column_cb( $comment ) { + if ( $this->user_can ) + echo ""; + } + + function column_comment( $comment ) { + global $post, $comment_status, $the_comment_status; + + $user_can = $this->user_can; + + $comment_url = esc_url( get_comment_link( $comment->comment_ID ) ); + + $ptime = date( 'G', strtotime( $comment->comment_date ) ); + if ( ( abs( time() - $ptime ) ) < 86400 ) + $ptime = sprintf( __( '%s ago' ), human_time_diff( $ptime ) ); + else + $ptime = mysql2date( __( 'Y/m/d \a\t g:i A' ), $comment->comment_date ); + + if ( $user_can ) { + $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) ); + $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) ); + + $url = "comment.php?c=$comment->comment_ID"; + + $approve_url = esc_url( $url . "&action=approvecomment&$approve_nonce" ); + $unapprove_url = esc_url( $url . "&action=unapprovecomment&$approve_nonce" ); + $spam_url = esc_url( $url . "&action=spamcomment&$del_nonce" ); + $unspam_url = esc_url( $url . "&action=unspamcomment&$del_nonce" ); + $trash_url = esc_url( $url . "&action=trashcomment&$del_nonce" ); + $untrash_url = esc_url( $url . "&action=untrashcomment&$del_nonce" ); + $delete_url = esc_url( $url . "&action=deletecomment&$del_nonce" ); + } + + echo ''; + comment_text(); + if ( $user_can ) { ?> + + '', 'unapprove' => '', + 'reply' => '', + 'quickedit' => '', + 'edit' => '', + 'spam' => '', 'unspam' => '', + 'trash' => '', 'untrash' => '', 'delete' => '' + ); + + if ( $comment_status && 'all' != $comment_status ) { // not looking at all comments + if ( 'approved' == $the_comment_status ) + $actions['unapprove'] = "" . __( 'Unapprove' ) . ''; + else if ( 'unapproved' == $the_comment_status ) + $actions['approve'] = "" . __( 'Approve' ) . ''; + } else { + $actions['approve'] = "" . __( 'Approve' ) . ''; + $actions['unapprove'] = "" . __( 'Unapprove' ) . ''; + } + + if ( 'spam' != $the_comment_status && 'trash' != $the_comment_status ) { + $actions['spam'] = "" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . ''; + } elseif ( 'spam' == $the_comment_status ) { + $actions['unspam'] = "" . _x( 'Not Spam', 'comment' ) . ''; + } elseif ( 'trash' == $the_comment_status ) { + $actions['untrash'] = "" . __( 'Restore' ) . ''; + } + + if ( 'spam' == $the_comment_status || 'trash' == $the_comment_status || !EMPTY_TRASH_DAYS ) { + $actions['delete'] = "" . __( 'Delete Permanently' ) . ''; + } else { + $actions['trash'] = "" . _x( 'Trash', 'verb' ) . ''; + } + + if ( 'trash' != $the_comment_status ) { + $actions['edit'] = "". __( 'Edit' ) . ''; + $actions['quickedit'] = '' . __( 'Quick Edit' ) . ''; + if ( 'spam' != $the_comment_status ) + $actions['reply'] = '' . __( 'Reply' ) . ''; + } + + $actions = apply_filters( 'comment_row_actions', array_filter( $actions ), $comment ); + + $i = 0; + echo '
'; + foreach ( $actions as $action => $link ) { + ++$i; + ( ( ( 'approve' == $action || 'unapprove' == $action ) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | '; + + // Reply and quickedit need a hide-if-no-js span when not added with ajax + if ( ( 'reply' == $action || 'quickedit' == $action ) && ! defined('DOING_AJAX') ) + $action .= ' hide-if-no-js'; + elseif ( ( $action == 'untrash' && $the_comment_status == 'trash' ) || ( $action == 'unspam' && $the_comment_status == 'spam' ) ) { + if ( '1' == get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true ) ) + $action .= ' approve'; + else + $action .= ' unapprove'; + } + + echo "$sep$link"; + } + echo '
'; + } + } + + function column_author( $comment ) { + global $comment_status; + + $author_url = get_comment_author_url(); + if ( 'http://' == $author_url ) + $author_url = ''; + $author_url_display = preg_replace( '|http://(www\.)?|i', '', $author_url ); + if ( strlen( $author_url_display ) > 50 ) + $author_url_display = substr( $author_url_display, 0, 49 ) . '...'; + + echo ""; comment_author(); echo '
'; + if ( !empty( $author_url ) ) + echo "$author_url_display
"; + + if ( $this->user_can ) { + if ( !empty( $comment->comment_author_email ) ) { + comment_author_email_link(); + echo '
'; + } + echo ''; + comment_author_IP(); + echo ''; + } + } + + function column_date( $comment ) { + return get_comment_date( __( 'Y/m/d \a\t g:ia' ) ); + } + + function column_response( $comment ) { + global $post; + + if ( isset( $this->pending_count[$post->ID] ) ) { + $pending_comments = $this->pending_count[$post->ID]; + } else { + $_pending_count_temp = get_pending_comments_num( array( $post->ID ) ); + $pending_comments = $this->pending_count[$post->ID] = $_pending_count_temp[$post->ID]; + } + + if ( current_user_can( 'edit_post', $post->ID ) ) { + $post_link = ""; + $post_link .= get_the_title( $post->ID ) . ''; + } else { + $post_link = get_the_title( $post->ID ); + } + + echo ''; + if ( 'attachment' == $post->post_type && ( $thumb = wp_get_attachment_image( $post->ID, array( 80, 60 ), true ) ) ) + echo $thumb; + } + + function column_default( $comment, $column_name ) { + do_action( 'manage_comments_custom_column', $column_name, $comment->comment_ID ); + } +} + +/** + * Post Comments List Table class. + * + * @package WordPress + * @subpackage List_Table + * @since 3.1.0 + * @access private + * + * @see WP_Comments_Table + */ +class WP_Post_Comments_List_Table extends WP_Comments_List_Table { + + function get_column_info() { + $this->_column_headers = array( + array( + 'author' => __( 'Author' ), + 'comment' => _x( 'Comment', 'column name' ), + ), + array(), + array(), + ); + + return $this->_column_headers; + } + + function get_table_classes() { + $classes = parent::get_table_classes(); + $classes[] = 'comments-box'; + return $classes; + } + + function display( $output_empty = false ) { + extract( $this->_args ); + + wp_nonce_field( "fetch-list-" . get_class( $this ), '_ajax_fetch_list_nonce' ); +?> + + > + display_rows_or_placeholder(); ?> + + + diff --git a/src/wp-admin/includes/class-wp-filesystem-base.php b/src/wp-admin/includes/class-wp-filesystem-base.php new file mode 100644 index 00000000..0aaadeba --- /dev/null +++ b/src/wp-admin/includes/class-wp-filesystem-base.php @@ -0,0 +1,321 @@ +find_folder(ABSPATH); + //Perhaps the FTP folder is rooted at the WordPress install, Check for wp-includes folder in root, Could have some false positives, but rare. + if ( ! $folder && $this->is_dir('/wp-includes') ) + $folder = '/'; + return $folder; + } + /** + * Returns the path on the remote filesystem of WP_CONTENT_DIR + * + * @since 2.7 + * @access public + * @return string The location of the remote path. + */ + function wp_content_dir() { + return $this->find_folder(WP_CONTENT_DIR); + } + /** + * Returns the path on the remote filesystem of WP_PLUGIN_DIR + * + * @since 2.7 + * @access public + * + * @return string The location of the remote path. + */ + function wp_plugins_dir() { + return $this->find_folder(WP_PLUGIN_DIR); + } + /** + * Returns the path on the remote filesystem of the Themes Directory + * + * @since 2.7 + * @access public + * + * @return string The location of the remote path. + */ + function wp_themes_dir() { + return $this->wp_content_dir() . '/themes'; + } + + /** + * Locates a folder on the remote filesystem. + * + * Deprecated; use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() methods instead. + * + * @since 2.5 + * @deprecated 2.7 + * @access public + * + * @param string $base The folder to start searching from + * @param bool $echo True to display debug information + * @return string The location of the remote path. + */ + function find_base_dir($base = '.', $echo = false) { + _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' ); + $this->verbose = $echo; + return $this->abspath(); + } + /** + * Locates a folder on the remote filesystem. + * + * Deprecated; use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() methods instead. + * + * @since 2.5 + * @deprecated 2.7 + * @access public + * + * @param string $base The folder to start searching from + * @param bool $echo True to display debug information + * @return string The location of the remote path. + */ + function get_base_dir($base = '.', $echo = false) { + _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' ); + $this->verbose = $echo; + return $this->abspath(); + } + + /** + * Locates a folder on the remote filesystem. + * + * Assumes that on Windows systems, Stripping off the Drive letter is OK + * Sanitizes \\ to / in windows filepaths. + * + * @since 2.7 + * @access public + * + * @param string $folder the folder to locate + * @return string The location of the remote path. + */ + function find_folder($folder) { + + if ( strpos($this->method, 'ftp') !== false ) { + $constant_overrides = array( 'FTP_BASE' => ABSPATH, 'FTP_CONTENT_DIR' => WP_CONTENT_DIR, 'FTP_PLUGIN_DIR' => WP_PLUGIN_DIR ); + foreach ( $constant_overrides as $constant => $dir ) + if ( defined($constant) && $folder === $dir ) + return trailingslashit(constant($constant)); + } elseif ( 'direct' == $this->method ) { + $folder = str_replace('\\', '/', $folder); //Windows path sanitiation + return trailingslashit($folder); + } + + $folder = preg_replace('|^([a-z]{1}):|i', '', $folder); //Strip out windows driveletter if its there. + $folder = str_replace('\\', '/', $folder); //Windows path sanitiation + + if ( isset($this->cache[ $folder ] ) ) + return $this->cache[ $folder ]; + + if ( $this->exists($folder) ) { //Folder exists at that absolute path. + $folder = trailingslashit($folder); + $this->cache[ $folder ] = $folder; + return $folder; + } + if ( $return = $this->search_for_folder($folder) ) + $this->cache[ $folder ] = $return; + return $return; + } + + /** + * Locates a folder on the remote filesystem. + * + * Expects Windows sanitized path + * + * @since 2.7 + * @access private + * + * @param string $folder the folder to locate + * @param string $base the folder to start searching from + * @param bool $loop if the function has recursed, Internal use only + * @return string The location of the remote path. + */ + function search_for_folder($folder, $base = '.', $loop = false ) { + if ( empty( $base ) || '.' == $base ) + $base = trailingslashit($this->cwd()); + + $folder = untrailingslashit($folder); + + $folder_parts = explode('/', $folder); + $last_path = $folder_parts[ count($folder_parts) - 1 ]; + + $files = $this->dirlist( $base ); + + foreach ( $folder_parts as $key ) { + if ( $key == $last_path ) + continue; //We want this to be caught by the next code block. + + //Working from /home/ to /user/ to /wordpress/ see if that file exists within the current folder, + // If its found, change into it and follow through looking for it. + // If it cant find WordPress down that route, it'll continue onto the next folder level, and see if that matches, and so on. + // If it reaches the end, and still cant find it, it'll return false for the entire function. + if ( isset($files[ $key ]) ){ + //Lets try that folder: + $newdir = trailingslashit(path_join($base, $key)); + if ( $this->verbose ) + printf( __('Changing to %s') . '
', $newdir ); + if ( $ret = $this->search_for_folder( $folder, $newdir, $loop) ) + return $ret; + } + } + + //Only check this as a last resort, to prevent locating the incorrect install. All above proceeedures will fail quickly if this is the right branch to take. + if (isset( $files[ $last_path ] ) ) { + if ( $this->verbose ) + printf( __('Found %s') . '
', $base . $last_path ); + return trailingslashit($base . $last_path); + } + if ( $loop ) + return false; //Prevent tihs function looping again. + //As an extra last resort, Change back to / if the folder wasnt found. This comes into effect when the CWD is /home/user/ but WP is at /var/www/.... mainly dedicated setups. + return $this->search_for_folder($folder, '/', true); + + } + + /** + * Returns the *nix style file permissions for a file + * + * From the PHP documentation page for fileperms() + * + * @link http://docs.php.net/fileperms + * @since 2.5 + * @access public + * + * @param string $file string filename + * @return int octal representation of permissions + */ + function gethchmod($file){ + $perms = $this->getchmod($file); + if (($perms & 0xC000) == 0xC000) // Socket + $info = 's'; + elseif (($perms & 0xA000) == 0xA000) // Symbolic Link + $info = 'l'; + elseif (($perms & 0x8000) == 0x8000) // Regular + $info = '-'; + elseif (($perms & 0x6000) == 0x6000) // Block special + $info = 'b'; + elseif (($perms & 0x4000) == 0x4000) // Directory + $info = 'd'; + elseif (($perms & 0x2000) == 0x2000) // Character special + $info = 'c'; + elseif (($perms & 0x1000) == 0x1000) // FIFO pipe + $info = 'p'; + else // Unknown + $info = 'u'; + + // Owner + $info .= (($perms & 0x0100) ? 'r' : '-'); + $info .= (($perms & 0x0080) ? 'w' : '-'); + $info .= (($perms & 0x0040) ? + (($perms & 0x0800) ? 's' : 'x' ) : + (($perms & 0x0800) ? 'S' : '-')); + + // Group + $info .= (($perms & 0x0020) ? 'r' : '-'); + $info .= (($perms & 0x0010) ? 'w' : '-'); + $info .= (($perms & 0x0008) ? + (($perms & 0x0400) ? 's' : 'x' ) : + (($perms & 0x0400) ? 'S' : '-')); + + // World + $info .= (($perms & 0x0004) ? 'r' : '-'); + $info .= (($perms & 0x0002) ? 'w' : '-'); + $info .= (($perms & 0x0001) ? + (($perms & 0x0200) ? 't' : 'x' ) : + (($perms & 0x0200) ? 'T' : '-')); + return $info; + } + + /** + * Converts *nix style file permissions to a octal number. + * + * Converts '-rw-r--r--' to 0644 + * From "info at rvgate dot nl"'s comment on the PHP documentation for chmod() + * + * @link http://docs.php.net/manual/en/function.chmod.php#49614 + * @since 2.5 + * @access public + * + * @param string $mode string *nix style file permission + * @return int octal representation + */ + function getnumchmodfromh($mode) { + $realmode = ''; + $legal = array('', 'w', 'r', 'x', '-'); + $attarray = preg_split('//', $mode); + + for ($i=0; $i < count($attarray); $i++) + if ($key = array_search($attarray[$i], $legal)) + $realmode .= $legal[$key]; + + $mode = str_pad($realmode, 9, '-'); + $trans = array('-'=>'0', 'r'=>'4', 'w'=>'2', 'x'=>'1'); + $mode = strtr($mode,$trans); + + $newmode = ''; + $newmode .= $mode[0] + $mode[1] + $mode[2]; + $newmode .= $mode[3] + $mode[4] + $mode[5]; + $newmode .= $mode[6] + $mode[7] + $mode[8]; + return $newmode; + } + + /** + * Determines if the string provided contains binary characters. + * + * @since 2.7 + * @access private + * + * @param string $text String to test against + * @return bool true if string is binary, false otherwise + */ + function is_binary( $text ) { + return (bool) preg_match('|[^\x20-\x7E]|', $text); //chr(32)..chr(127) + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-filesystem-direct.php b/src/wp-admin/includes/class-wp-filesystem-direct.php new file mode 100644 index 00000000..94319bce --- /dev/null +++ b/src/wp-admin/includes/class-wp-filesystem-direct.php @@ -0,0 +1,361 @@ +method = 'direct'; + $this->errors = new WP_Error(); + } + /** + * connect filesystem. + * + * @return bool Returns true on success or false on failure (always true for WP_Filesystem_Direct). + */ + function connect() { + return true; + } + /** + * Reads entire file into a string + * + * @param string $file Name of the file to read. + * @return string|bool The function returns the read data or false on failure. + */ + function get_contents($file) { + return @file_get_contents($file); + } + /** + * Reads entire file into an array + * + * @param string $file Path to the file. + * @return array|bool the file contents in an array or false on failure. + */ + function get_contents_array($file) { + return @file($file); + } + /** + * Write a string to a file + * + * @param string $file Remote path to the file where to write the data. + * @param string $contents The data to write. + * @param int $mode (optional) The file permissions as octal number, usually 0644. + * @return bool False upon failure. + */ + function put_contents($file, $contents, $mode = false ) { + if ( ! ($fp = @fopen($file, 'w')) ) + return false; + @fwrite($fp, $contents); + @fclose($fp); + $this->chmod($file, $mode); + return true; + } + /** + * Gets the current working directory + * + * @return string|bool the current working directory on success, or false on failure. + */ + function cwd() { + return @getcwd(); + } + /** + * Change directory + * + * @param string $dir The new current directory. + * @return bool Returns true on success or false on failure. + */ + function chdir($dir) { + return @chdir($dir); + } + /** + * Changes file group + * + * @param string $file Path to the file. + * @param mixed $group A group name or number. + * @param bool $recursive (optional) If set True changes file group recursivly. Defaults to False. + * @return bool Returns true on success or false on failure. + */ + function chgrp($file, $group, $recursive = false) { + if ( ! $this->exists($file) ) + return false; + if ( ! $recursive ) + return @chgrp($file, $group); + if ( ! $this->is_dir($file) ) + return @chgrp($file, $group); + //Is a directory, and we want recursive + $file = trailingslashit($file); + $filelist = $this->dirlist($file); + foreach ($filelist as $filename) + $this->chgrp($file . $filename, $group, $recursive); + + return true; + } + /** + * Changes filesystem permissions + * + * @param string $file Path to the file. + * @param int $mode (optional) The permissions as octal number, usually 0644 for files, 0755 for dirs. + * @param bool $recursive (optional) If set True changes file group recursivly. Defaults to False. + * @return bool Returns true on success or false on failure. + */ + function chmod($file, $mode = false, $recursive = false) { + if ( ! $mode ) { + if ( $this->is_file($file) ) + $mode = FS_CHMOD_FILE; + elseif ( $this->is_dir($file) ) + $mode = FS_CHMOD_DIR; + else + return false; + } + + if ( ! $recursive || ! $this->is_dir($file) ) + return @chmod($file, $mode); + //Is a directory, and we want recursive + $file = trailingslashit($file); + $filelist = $this->dirlist($file); + foreach ( (array)$filelist as $filename => $filemeta) + $this->chmod($file . $filename, $mode, $recursive); + + return true; + } + /** + * Changes file owner + * + * @param string $file Path to the file. + * @param mixed $owner A user name or number. + * @param bool $recursive (optional) If set True changes file owner recursivly. Defaults to False. + * @return bool Returns true on success or false on failure. + */ + function chown($file, $owner, $recursive = false) { + if ( ! $this->exists($file) ) + return false; + if ( ! $recursive ) + return @chown($file, $owner); + if ( ! $this->is_dir($file) ) + return @chown($file, $owner); + //Is a directory, and we want recursive + $filelist = $this->dirlist($file); + foreach ($filelist as $filename) { + $this->chown($file . '/' . $filename, $owner, $recursive); + } + return true; + } + /** + * Gets file owner + * + * @param string $file Path to the file. + * @return string Username of the user. + */ + function owner($file) { + $owneruid = @fileowner($file); + if ( ! $owneruid ) + return false; + if ( ! function_exists('posix_getpwuid') ) + return $owneruid; + $ownerarray = posix_getpwuid($owneruid); + return $ownerarray['name']; + } + /** + * Gets file permissions + * + * FIXME does not handle errors in fileperms() + * + * @param string $file Path to the file. + * @return string Mode of the file (last 4 digits). + */ + function getchmod($file) { + return substr(decoct(@fileperms($file)),3); + } + function group($file) { + $gid = @filegroup($file); + if ( ! $gid ) + return false; + if ( ! function_exists('posix_getgrgid') ) + return $gid; + $grouparray = posix_getgrgid($gid); + return $grouparray['name']; + } + + function copy($source, $destination, $overwrite = false) { + if ( ! $overwrite && $this->exists($destination) ) + return false; + + return copy($source, $destination); + } + + function move($source, $destination, $overwrite = false) { + if ( ! $overwrite && $this->exists($destination) ) + return false; + + // try using rename first. if that fails (for example, source is read only) try copy + if ( @rename($source, $destination) ) + return true; + + if ( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ) { + $this->delete($source); + return true; + } else { + return false; + } + } + + function delete($file, $recursive = false) { + if ( empty($file) ) //Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem. + return false; + $file = str_replace('\\', '/', $file); //for win32, occasional problems deleteing files otherwise + + if ( $this->is_file($file) ) + return @unlink($file); + if ( ! $recursive && $this->is_dir($file) ) + return @rmdir($file); + + //At this point its a folder, and we're in recursive mode + $file = trailingslashit($file); + $filelist = $this->dirlist($file, true); + + $retval = true; + if ( is_array($filelist) ) //false if no files, So check first. + foreach ($filelist as $filename => $fileinfo) + if ( ! $this->delete($file . $filename, $recursive) ) + $retval = false; + + if ( file_exists($file) && ! @rmdir($file) ) + $retval = false; + return $retval; + } + + function exists($file) { + return @file_exists($file); + } + + function is_file($file) { + return @is_file($file); + } + + function is_dir($path) { + return @is_dir($path); + } + + function is_readable($file) { + return @is_readable($file); + } + + function is_writable($file) { + return @is_writable($file); + } + + function atime($file) { + return @fileatime($file); + } + + function mtime($file) { + return @filemtime($file); + } + function size($file) { + return @filesize($file); + } + + function touch($file, $time = 0, $atime = 0) { + if ($time == 0) + $time = time(); + if ($atime == 0) + $atime = time(); + return @touch($file, $time, $atime); + } + + function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { + // safe mode fails with a trailing slash under certain PHP versions. + $path = untrailingslashit($path); + if ( empty($path) ) + $path = '/'; + + if ( ! $chmod ) + $chmod = FS_CHMOD_DIR; + + if ( ! @mkdir($path) ) + return false; + $this->chmod($path, $chmod); + if ( $chown ) + $this->chown($path, $chown); + if ( $chgrp ) + $this->chgrp($path, $chgrp); + return true; + } + + function rmdir($path, $recursive = false) { + return $this->delete($path, $recursive); + } + + function dirlist($path, $include_hidden = true, $recursive = false) { + if ( $this->is_file($path) ) { + $limit_file = basename($path); + $path = dirname($path); + } else { + $limit_file = false; + } + + if ( ! $this->is_dir($path) ) + return false; + + $dir = @dir($path); + if ( ! $dir ) + return false; + + $ret = array(); + + while (false !== ($entry = $dir->read()) ) { + $struc = array(); + $struc['name'] = $entry; + + if ( '.' == $struc['name'] || '..' == $struc['name'] ) + continue; + + if ( ! $include_hidden && '.' == $struc['name'][0] ) + continue; + + if ( $limit_file && $struc['name'] != $limit_file) + continue; + + $struc['perms'] = $this->gethchmod($path.'/'.$entry); + $struc['permsn'] = $this->getnumchmodfromh($struc['perms']); + $struc['number'] = false; + $struc['owner'] = $this->owner($path.'/'.$entry); + $struc['group'] = $this->group($path.'/'.$entry); + $struc['size'] = $this->size($path.'/'.$entry); + $struc['lastmodunix']= $this->mtime($path.'/'.$entry); + $struc['lastmod'] = date('M j',$struc['lastmodunix']); + $struc['time'] = date('h:i:s',$struc['lastmodunix']); + $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f'; + + if ( 'd' == $struc['type'] ) { + if ( $recursive ) + $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive); + else + $struc['files'] = array(); + } + + $ret[ $struc['name'] ] = $struc; + } + $dir->close(); + unset($dir); + return $ret; + } +} +?> diff --git a/src/wp-admin/includes/class-wp-filesystem-ftpext.php b/src/wp-admin/includes/class-wp-filesystem-ftpext.php new file mode 100644 index 00000000..df4ce0ad --- /dev/null +++ b/src/wp-admin/includes/class-wp-filesystem-ftpext.php @@ -0,0 +1,387 @@ +method = 'ftpext'; + $this->errors = new WP_Error(); + + //Check if possible to use ftp functions. + if ( ! extension_loaded('ftp') ) { + $this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available')); + return false; + } + + // Set defaults: + //This Class uses the timeout on a per-connection basis, Others use it on a per-action basis. + + if ( ! defined('FS_TIMEOUT') ) + define('FS_TIMEOUT', 240); + + if ( empty($opt['port']) ) + $this->options['port'] = 21; + else + $this->options['port'] = $opt['port']; + + if ( empty($opt['hostname']) ) + $this->errors->add('empty_hostname', __('FTP hostname is required')); + else + $this->options['hostname'] = $opt['hostname']; + + if ( ! empty($opt['base']) ) + $this->wp_base = $opt['base']; + + // Check if the options provided are OK. + if ( empty($opt['username']) ) + $this->errors->add('empty_username', __('FTP username is required')); + else + $this->options['username'] = $opt['username']; + + if ( empty($opt['password']) ) + $this->errors->add('empty_password', __('FTP password is required')); + else + $this->options['password'] = $opt['password']; + + $this->options['ssl'] = false; + if ( isset($opt['connection_type']) && 'ftps' == $opt['connection_type'] ) + $this->options['ssl'] = true; + } + + function connect() { + if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') ) + $this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT); + else + $this->link = @ftp_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT); + + if ( ! $this->link ) { + $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port'])); + return false; + } + + if ( ! @ftp_login($this->link,$this->options['username'], $this->options['password']) ) { + $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username'])); + return false; + } + + //Set the Connection to use Passive FTP + @ftp_pasv( $this->link, true ); + if ( @ftp_get_option($this->link, FTP_TIMEOUT_SEC) < FS_TIMEOUT ) + @ftp_set_option($this->link, FTP_TIMEOUT_SEC, FS_TIMEOUT); + + return true; + } + + function get_contents($file, $type = '', $resumepos = 0 ) { + if ( empty($type) ) + $type = FTP_BINARY; + + $tempfile = wp_tempnam($file); + $temp = fopen($tempfile, 'w+'); + + if ( ! $temp ) + return false; + + if ( ! @ftp_fget($this->link, $temp, $file, $type, $resumepos) ) + return false; + + fseek($temp, 0); //Skip back to the start of the file being written to + $contents = ''; + + while ( ! feof($temp) ) + $contents .= fread($temp, 8192); + + fclose($temp); + unlink($tempfile); + return $contents; + } + function get_contents_array($file) { + return explode("\n", $this->get_contents($file)); + } + + function put_contents($file, $contents, $mode = false ) { + $tempfile = wp_tempnam($file); + $temp = fopen($tempfile, 'w+'); + if ( ! $temp ) + return false; + + fwrite($temp, $contents); + fseek($temp, 0); //Skip back to the start of the file being written to + + $type = $this->is_binary($contents) ? FTP_BINARY : FTP_ASCII; + $ret = @ftp_fput($this->link, $file, $temp, $type); + + fclose($temp); + unlink($tempfile); + + $this->chmod($file, $mode); + + return $ret; + } + function cwd() { + $cwd = @ftp_pwd($this->link); + if ( $cwd ) + $cwd = trailingslashit($cwd); + return $cwd; + } + function chdir($dir) { + return @ftp_chdir($this->link, $dir); + } + function chgrp($file, $group, $recursive = false ) { + return false; + } + function chmod($file, $mode = false, $recursive = false) { + if ( ! $mode ) { + if ( $this->is_file($file) ) + $mode = FS_CHMOD_FILE; + elseif ( $this->is_dir($file) ) + $mode = FS_CHMOD_DIR; + else + return false; + } + + // chmod any sub-objects if recursive. + if ( $recursive && $this->is_dir($file) ) { + $filelist = $this->dirlist($file); + foreach ( (array)$filelist as $filename => $filemeta ) + $this->chmod($file . '/' . $filename, $mode, $recursive); + } + + // chmod the file or directory + if ( ! function_exists('ftp_chmod') ) + return (bool)@ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file)); + return (bool)@ftp_chmod($this->link, $mode, $file); + } + function chown($file, $owner, $recursive = false ) { + return false; + } + function owner($file) { + $dir = $this->dirlist($file); + return $dir[$file]['owner']; + } + function getchmod($file) { + $dir = $this->dirlist($file); + return $dir[$file]['permsn']; + } + function group($file) { + $dir = $this->dirlist($file); + return $dir[$file]['group']; + } + function copy($source, $destination, $overwrite = false ) { + if ( ! $overwrite && $this->exists($destination) ) + return false; + $content = $this->get_contents($source); + if ( false === $content) + return false; + return $this->put_contents($destination, $content); + } + function move($source, $destination, $overwrite = false) { + return ftp_rename($this->link, $source, $destination); + } + + function delete($file, $recursive = false ) { + if ( empty($file) ) + return false; + if ( $this->is_file($file) ) + return @ftp_delete($this->link, $file); + if ( !$recursive ) + return @ftp_rmdir($this->link, $file); + + $filelist = $this->dirlist( trailingslashit($file) ); + if ( !empty($filelist) ) + foreach ( $filelist as $delete_file ) + $this->delete( trailingslashit($file) . $delete_file['name'], $recursive); + return @ftp_rmdir($this->link, $file); + } + + function exists($file) { + $list = @ftp_nlist($this->link, $file); + return !empty($list); //empty list = no file, so invert. + } + function is_file($file) { + return $this->exists($file) && !$this->is_dir($file); + } + function is_dir($path) { + $cwd = $this->cwd(); + $result = @ftp_chdir($this->link, trailingslashit($path) ); + if ( $result && $path == $this->cwd() || $this->cwd() != $cwd ) { + @ftp_chdir($this->link, $cwd); + return true; + } + return false; + } + function is_readable($file) { + //Get dir list, Check if the file is readable by the current user?? + return true; + } + function is_writable($file) { + //Get dir list, Check if the file is writable by the current user?? + return true; + } + function atime($file) { + return false; + } + function mtime($file) { + return ftp_mdtm($this->link, $file); + } + function size($file) { + return ftp_size($this->link, $file); + } + function touch($file, $time = 0, $atime = 0) { + return false; + } + function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { + if ( !@ftp_mkdir($this->link, $path) ) + return false; + $this->chmod($path, $chmod); + if ( $chown ) + $this->chown($path, $chown); + if ( $chgrp ) + $this->chgrp($path, $chgrp); + return true; + } + function rmdir($path, $recursive = false) { + return $this->delete($path, $recursive); + } + + function parselisting($line) { + static $is_windows; + if ( is_null($is_windows) ) + $is_windows = stripos( ftp_systype($this->link), 'win') !== false; + + if ( $is_windows && preg_match('/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|) +(.+)/', $line, $lucifer) ) { + $b = array(); + if ( $lucifer[3] < 70 ) + $lucifer[3] +=2000; + else + $lucifer[3] += 1900; // 4digit year fix + $b['isdir'] = ( $lucifer[7] == ''); + if ( $b['isdir'] ) + $b['type'] = 'd'; + else + $b['type'] = 'f'; + $b['size'] = $lucifer[7]; + $b['month'] = $lucifer[1]; + $b['day'] = $lucifer[2]; + $b['year'] = $lucifer[3]; + $b['hour'] = $lucifer[4]; + $b['minute'] = $lucifer[5]; + $b['time'] = @mktime($lucifer[4] + (strcasecmp($lucifer[6], "PM") == 0 ? 12 : 0), $lucifer[5], 0, $lucifer[1], $lucifer[2], $lucifer[3]); + $b['am/pm'] = $lucifer[6]; + $b['name'] = $lucifer[8]; + } elseif ( !$is_windows && $lucifer = preg_split('/[ ]/', $line, 9, PREG_SPLIT_NO_EMPTY)) { + //echo $line."\n"; + $lcount = count($lucifer); + if ( $lcount < 8 ) + return ''; + $b = array(); + $b['isdir'] = $lucifer[0]{0} === 'd'; + $b['islink'] = $lucifer[0]{0} === 'l'; + if ( $b['isdir'] ) + $b['type'] = 'd'; + elseif ( $b['islink'] ) + $b['type'] = 'l'; + else + $b['type'] = 'f'; + $b['perms'] = $lucifer[0]; + $b['number'] = $lucifer[1]; + $b['owner'] = $lucifer[2]; + $b['group'] = $lucifer[3]; + $b['size'] = $lucifer[4]; + if ( $lcount == 8 ) { + sscanf($lucifer[5], '%d-%d-%d', $b['year'], $b['month'], $b['day']); + sscanf($lucifer[6], '%d:%d', $b['hour'], $b['minute']); + $b['time'] = @mktime($b['hour'], $b['minute'], 0, $b['month'], $b['day'], $b['year']); + $b['name'] = $lucifer[7]; + } else { + $b['month'] = $lucifer[5]; + $b['day'] = $lucifer[6]; + if ( preg_match('/([0-9]{2}):([0-9]{2})/', $lucifer[7], $l2) ) { + $b['year'] = date("Y"); + $b['hour'] = $l2[1]; + $b['minute'] = $l2[2]; + } else { + $b['year'] = $lucifer[7]; + $b['hour'] = 0; + $b['minute'] = 0; + } + $b['time'] = strtotime( sprintf('%d %s %d %02d:%02d', $b['day'], $b['month'], $b['year'], $b['hour'], $b['minute']) ); + $b['name'] = $lucifer[8]; + } + } + + return $b; + } + + function dirlist($path = '.', $include_hidden = true, $recursive = false) { + if ( $this->is_file($path) ) { + $limit_file = basename($path); + $path = dirname($path) . '/'; + } else { + $limit_file = false; + } + + $pwd = @ftp_pwd($this->link); + if ( ! @ftp_chdir($this->link, $path) ) // Cant change to folder = folder doesnt exist + return false; + $list = @ftp_rawlist($this->link, '-a', false); + @ftp_chdir($this->link, $pwd); + + if ( empty($list) ) // Empty array = non-existent folder (real folder will show . at least) + return false; + + $dirlist = array(); + foreach ( $list as $k => $v ) { + $entry = $this->parselisting($v); + if ( empty($entry) ) + continue; + + if ( '.' == $entry['name'] || '..' == $entry['name'] ) + continue; + + if ( ! $include_hidden && '.' == $entry['name'][0] ) + continue; + + if ( $limit_file && $entry['name'] != $limit_file) + continue; + + $dirlist[ $entry['name'] ] = $entry; + } + + $ret = array(); + foreach ( (array)$dirlist as $struc ) { + if ( 'd' == $struc['type'] ) { + if ( $recursive ) + $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive); + else + $struc['files'] = array(); + } + + $ret[ $struc['name'] ] = $struc; + } + return $ret; + } + + function __destruct() { + if ( $this->link ) + ftp_close($this->link); + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-filesystem-ftpsockets.php b/src/wp-admin/includes/class-wp-filesystem-ftpsockets.php new file mode 100644 index 00000000..efd19d1f --- /dev/null +++ b/src/wp-admin/includes/class-wp-filesystem-ftpsockets.php @@ -0,0 +1,327 @@ +method = 'ftpsockets'; + $this->errors = new WP_Error(); + + //Check if possible to use ftp functions. + if ( ! @include_once ABSPATH . 'wp-admin/includes/class-ftp.php' ) + return false; + $this->ftp = new ftp(); + + //Set defaults: + if ( empty($opt['port']) ) + $this->options['port'] = 21; + else + $this->options['port'] = $opt['port']; + + if ( empty($opt['hostname']) ) + $this->errors->add('empty_hostname', __('FTP hostname is required')); + else + $this->options['hostname'] = $opt['hostname']; + + if ( ! empty($opt['base']) ) + $this->wp_base = $opt['base']; + + // Check if the options provided are OK. + if ( empty ($opt['username']) ) + $this->errors->add('empty_username', __('FTP username is required')); + else + $this->options['username'] = $opt['username']; + + if ( empty ($opt['password']) ) + $this->errors->add('empty_password', __('FTP password is required')); + else + $this->options['password'] = $opt['password']; + } + + function connect() { + if ( ! $this->ftp ) + return false; + + $this->ftp->setTimeout(FS_CONNECT_TIMEOUT); + + if ( ! $this->ftp->SetServer($this->options['hostname'], $this->options['port']) ) { + $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port'])); + return false; + } + + if ( ! $this->ftp->connect() ) { + $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port'])); + return false; + } + + if ( ! $this->ftp->login($this->options['username'], $this->options['password']) ) { + $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username'])); + return false; + } + + $this->ftp->SetType(FTP_AUTOASCII); + $this->ftp->Passive(true); + $this->ftp->setTimeout(FS_TIMEOUT); + return true; + } + + function get_contents($file, $type = '', $resumepos = 0) { + if ( ! $this->exists($file) ) + return false; + + if ( empty($type) ) + $type = FTP_AUTOASCII; + $this->ftp->SetType($type); + + $temp = wp_tempnam( $file ); + + if ( ! $temphandle = fopen($temp, 'w+') ) + return false; + + if ( ! $this->ftp->fget($temphandle, $file) ) { + fclose($temphandle); + unlink($temp); + return ''; //Blank document, File does exist, Its just blank. + } + + fseek($temphandle, 0); //Skip back to the start of the file being written to + $contents = ''; + + while ( ! feof($temphandle) ) + $contents .= fread($temphandle, 8192); + + fclose($temphandle); + unlink($temp); + return $contents; + } + + function get_contents_array($file) { + return explode("\n", $this->get_contents($file) ); + } + + function put_contents($file, $contents, $mode = false ) { + $temp = wp_tempnam( $file ); + if ( ! $temphandle = @fopen($temp, 'w+') ) { + unlink($temp); + return false; + } + + fwrite($temphandle, $contents); + fseek($temphandle, 0); //Skip back to the start of the file being written to + + $type = $this->is_binary($contents) ? FTP_BINARY : FTP_ASCII; + $this->ftp->SetType($type); + + $ret = $this->ftp->fput($file, $temphandle); + + fclose($temphandle); + unlink($temp); + + $this->chmod($file, $mode); + + return $ret; + } + + function cwd() { + $cwd = $this->ftp->pwd(); + if ( $cwd ) + $cwd = trailingslashit($cwd); + return $cwd; + } + + function chdir($file) { + return $this->ftp->chdir($file); + } + + function chgrp($file, $group, $recursive = false ) { + return false; + } + + function chmod($file, $mode = false, $recursive = false ) { + if ( ! $mode ) { + if ( $this->is_file($file) ) + $mode = FS_CHMOD_FILE; + elseif ( $this->is_dir($file) ) + $mode = FS_CHMOD_DIR; + else + return false; + } + + // chmod any sub-objects if recursive. + if ( $recursive && $this->is_dir($file) ) { + $filelist = $this->dirlist($file); + foreach ( (array)$filelist as $filename => $filemeta ) + $this->chmod($file . '/' . $filename, $mode, $recursive); + } + + // chmod the file or directory + return $this->ftp->chmod($file, $mode); + } + + function chown($file, $owner, $recursive = false ) { + return false; + } + + function owner($file) { + $dir = $this->dirlist($file); + return $dir[$file]['owner']; + } + + function getchmod($file) { + $dir = $this->dirlist($file); + return $dir[$file]['permsn']; + } + + function group($file) { + $dir = $this->dirlist($file); + return $dir[$file]['group']; + } + + function copy($source, $destination, $overwrite = false ) { + if ( ! $overwrite && $this->exists($destination) ) + return false; + + $content = $this->get_contents($source); + if ( false === $content ) + return false; + + return $this->put_contents($destination, $content); + } + + function move($source, $destination, $overwrite = false ) { + return $this->ftp->rename($source, $destination); + } + + function delete($file, $recursive = false ) { + if ( empty($file) ) + return false; + if ( $this->is_file($file) ) + return $this->ftp->delete($file); + if ( !$recursive ) + return $this->ftp->rmdir($file); + + return $this->ftp->mdel($file); + } + + function exists($file) { + return $this->ftp->is_exists($file); + } + + function is_file($file) { + if ( $this->is_dir($file) ) + return false; + if ( $this->exists($file) ) + return true; + return false; + } + + function is_dir($path) { + $cwd = $this->cwd(); + if ( $this->chdir($path) ) { + $this->chdir($cwd); + return true; + } + return false; + } + + function is_readable($file) { + //Get dir list, Check if the file is writable by the current user?? + return true; + } + + function is_writable($file) { + //Get dir list, Check if the file is writable by the current user?? + return true; + } + + function atime($file) { + return false; + } + + function mtime($file) { + return $this->ftp->mdtm($file); + } + + function size($file) { + return $this->ftp->filesize($file); + } + + function touch($file, $time = 0, $atime = 0 ) { + return false; + } + + function mkdir($path, $chmod = false, $chown = false, $chgrp = false ) { + if ( ! $this->ftp->mkdir($path) ) + return false; + if ( ! $chmod ) + $chmod = FS_CHMOD_DIR; + $this->chmod($path, $chmod); + if ( $chown ) + $this->chown($path, $chown); + if ( $chgrp ) + $this->chgrp($path, $chgrp); + return true; + } + + function rmdir($path, $recursive = false ) { + $this->delete($path, $recursive); + } + + function dirlist($path = '.', $include_hidden = true, $recursive = false ) { + if ( $this->is_file($path) ) { + $limit_file = basename($path); + $path = dirname($path) . '/'; + } else { + $limit_file = false; + } + + $list = $this->ftp->dirlist($path); + if ( empty($list) && !$this->exists($path) ) + return false; + + $ret = array(); + foreach ( $list as $struc ) { + + if ( '.' == $struc['name'] || '..' == $struc['name'] ) + continue; + + if ( ! $include_hidden && '.' == $struc['name'][0] ) + continue; + + if ( $limit_file && $struc['name'] != $limit_file ) + continue; + + if ( 'd' == $struc['type'] ) { + if ( $recursive ) + $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive); + else + $struc['files'] = array(); + } + + $ret[ $struc['name'] ] = $struc; + } + return $ret; + } + + function __destruct() { + $this->ftp->quit(); + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-filesystem-ssh2.php b/src/wp-admin/includes/class-wp-filesystem-ssh2.php new file mode 100644 index 00000000..f5a64021 --- /dev/null +++ b/src/wp-admin/includes/class-wp-filesystem-ssh2.php @@ -0,0 +1,383 @@ +method = 'ssh2'; + $this->errors = new WP_Error(); + + //Check if possible to use ssh2 functions. + if ( ! extension_loaded('ssh2') ) { + $this->errors->add('no_ssh2_ext', __('The ssh2 PHP extension is not available')); + return false; + } + if ( !function_exists('stream_get_contents') ) { + $this->errors->add('ssh2_php_requirement', __('The ssh2 PHP extension is available, however, we require the PHP5 function stream_get_contents()')); + return false; + } + + // Set defaults: + if ( empty($opt['port']) ) + $this->options['port'] = 22; + else + $this->options['port'] = $opt['port']; + + if ( empty($opt['hostname']) ) + $this->errors->add('empty_hostname', __('SSH2 hostname is required')); + else + $this->options['hostname'] = $opt['hostname']; + + if ( ! empty($opt['base']) ) + $this->wp_base = $opt['base']; + + // Check if the options provided are OK. + if ( !empty ($opt['public_key']) && !empty ($opt['private_key']) ) { + $this->options['public_key'] = $opt['public_key']; + $this->options['private_key'] = $opt['private_key']; + + $this->options['hostkey'] = array('hostkey' => 'ssh-rsa'); + + $this->keys = true; + } elseif ( empty ($opt['username']) ) { + $this->errors->add('empty_username', __('SSH2 username is required')); + } + + if ( !empty($opt['username']) ) + $this->options['username'] = $opt['username']; + + if ( empty ($opt['password']) ) { + if ( !$this->keys ) //password can be blank if we are using keys + $this->errors->add('empty_password', __('SSH2 password is required')); + } else { + $this->options['password'] = $opt['password']; + } + + } + + function connect() { + if ( ! $this->keys ) { + $this->link = @ssh2_connect($this->options['hostname'], $this->options['port']); + } else { + $this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']); + } + + if ( ! $this->link ) { + $this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port'])); + return false; + } + + if ( !$this->keys ) { + if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) { + $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username'])); + return false; + } + } else { + if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) { + $this->errors->add('auth', sprintf(__('Public and Private keys incorrect for %s'), $this->options['username'])); + return false; + } + } + + $this->sftp_link = ssh2_sftp($this->link); + + return true; + } + + function run_command( $command, $returnbool = false) { + + if ( ! $this->link ) + return false; + + if ( ! ($stream = ssh2_exec($this->link, $command)) ) { + $this->errors->add('command', sprintf(__('Unable to perform command: %s'), $command)); + } else { + stream_set_blocking( $stream, true ); + stream_set_timeout( $stream, FS_TIMEOUT ); + $data = stream_get_contents( $stream ); + fclose( $stream ); + + if ( $returnbool ) + return ( $data === false ) ? false : '' != trim($data); + else + return $data; + } + return false; + } + + function get_contents($file, $type = '', $resumepos = 0 ) { + $file = ltrim($file, '/'); + return file_get_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function get_contents_array($file) { + $file = ltrim($file, '/'); + return file('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function put_contents($file, $contents, $mode = false ) { + $file = ltrim($file, '/'); + $ret = file_put_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file, $contents); + + $this->chmod($file, $mode); + + return false !== $ret; + } + + function cwd() { + $cwd = $this->run_command('pwd'); + if ( $cwd ) + $cwd = trailingslashit($cwd); + return $cwd; + } + + function chdir($dir) { + return $this->run_command('cd ' . $dir, true); + } + + function chgrp($file, $group, $recursive = false ) { + if ( ! $this->exists($file) ) + return false; + if ( ! $recursive || ! $this->is_dir($file) ) + return $this->run_command(sprintf('chgrp %o %s', $mode, escapeshellarg($file)), true); + return $this->run_command(sprintf('chgrp -R %o %s', $mode, escapeshellarg($file)), true); + } + + function chmod($file, $mode = false, $recursive = false) { + if ( ! $this->exists($file) ) + return false; + + if ( ! $mode ) { + if ( $this->is_file($file) ) + $mode = FS_CHMOD_FILE; + elseif ( $this->is_dir($file) ) + $mode = FS_CHMOD_DIR; + else + return false; + } + + if ( ! $recursive || ! $this->is_dir($file) ) + return $this->run_command(sprintf('chmod %o %s', $mode, escapeshellarg($file)), true); + return $this->run_command(sprintf('chmod -R %o %s', $mode, escapeshellarg($file)), true); + } + + function chown($file, $owner, $recursive = false ) { + if ( ! $this->exists($file) ) + return false; + if ( ! $recursive || ! $this->is_dir($file) ) + return $this->run_command(sprintf('chown %o %s', $mode, escapeshellarg($file)), true); + return $this->run_command(sprintf('chown -R %o %s', $mode, escapeshellarg($file)), true); + } + + function owner($file) { + $owneruid = @fileowner('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/')); + if ( ! $owneruid ) + return false; + if ( ! function_exists('posix_getpwuid') ) + return $owneruid; + $ownerarray = posix_getpwuid($owneruid); + return $ownerarray['name']; + } + + function getchmod($file) { + return substr(decoct(@fileperms( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/') )),3); + } + + function group($file) { + $gid = @filegroup('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/')); + if ( ! $gid ) + return false; + if ( ! function_exists('posix_getgrgid') ) + return $gid; + $grouparray = posix_getgrgid($gid); + return $grouparray['name']; + } + + function copy($source, $destination, $overwrite = false ) { + if ( ! $overwrite && $this->exists($destination) ) + return false; + $content = $this->get_contents($source); + if ( false === $content) + return false; + return $this->put_contents($destination, $content); + } + + function move($source, $destination, $overwrite = false) { + return @ssh2_sftp_rename($this->link, $source, $destination); + } + + function delete($file, $recursive = false) { + if ( $this->is_file($file) ) + return ssh2_sftp_unlink($this->sftp_link, $file); + if ( ! $recursive ) + return ssh2_sftp_rmdir($this->sftp_link, $file); + $filelist = $this->dirlist($file); + if ( is_array($filelist) ) { + foreach ( $filelist as $filename => $fileinfo) { + $this->delete($file . '/' . $filename, $recursive); + } + } + return ssh2_sftp_rmdir($this->sftp_link, $file); + } + + function exists($file) { + $file = ltrim($file, '/'); + return file_exists('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function is_file($file) { + $file = ltrim($file, '/'); + return is_file('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function is_dir($path) { + $path = ltrim($path, '/'); + return is_dir('ssh2.sftp://' . $this->sftp_link . '/' . $path); + } + + function is_readable($file) { + $file = ltrim($file, '/'); + return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function is_writable($file) { + $file = ltrim($file, '/'); + return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function atime($file) { + $file = ltrim($file, '/'); + return fileatime('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function mtime($file) { + $file = ltrim($file, '/'); + return filemtime('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function size($file) { + $file = ltrim($file, '/'); + return filesize('ssh2.sftp://' . $this->sftp_link . '/' . $file); + } + + function touch($file, $time = 0, $atime = 0) { + //Not implmented. + } + + function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { + $path = untrailingslashit($path); + if ( ! $chmod ) + $chmod = FS_CHMOD_DIR; + if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) ) + return false; + if ( $chown ) + $this->chown($path, $chown); + if ( $chgrp ) + $this->chgrp($path, $chgrp); + return true; + } + + function rmdir($path, $recursive = false) { + return $this->delete($path, $recursive); + } + + function dirlist($path, $include_hidden = true, $recursive = false) { + if ( $this->is_file($path) ) { + $limit_file = basename($path); + $path = dirname($path); + } else { + $limit_file = false; + } + + if ( ! $this->is_dir($path) ) + return false; + + $ret = array(); + $dir = @dir('ssh2.sftp://' . $this->sftp_link .'/' . ltrim($path, '/') ); + + if ( ! $dir ) + return false; + + while (false !== ($entry = $dir->read()) ) { + $struc = array(); + $struc['name'] = $entry; + + if ( '.' == $struc['name'] || '..' == $struc['name'] ) + continue; //Do not care about these folders. + + if ( ! $include_hidden && '.' == $struc['name'][0] ) + continue; + + if ( $limit_file && $struc['name'] != $limit_file ) + continue; + + $struc['perms'] = $this->gethchmod($path.'/'.$entry); + $struc['permsn'] = $this->getnumchmodfromh($struc['perms']); + $struc['number'] = false; + $struc['owner'] = $this->owner($path.'/'.$entry); + $struc['group'] = $this->group($path.'/'.$entry); + $struc['size'] = $this->size($path.'/'.$entry); + $struc['lastmodunix']= $this->mtime($path.'/'.$entry); + $struc['lastmod'] = date('M j',$struc['lastmodunix']); + $struc['time'] = date('h:i:s',$struc['lastmodunix']); + $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f'; + + if ( 'd' == $struc['type'] ) { + if ( $recursive ) + $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive); + else + $struc['files'] = array(); + } + + $ret[ $struc['name'] ] = $struc; + } + $dir->close(); + unset($dir); + return $ret; + } +} diff --git a/src/wp-admin/includes/class-wp-importer.php b/src/wp-admin/includes/class-wp-importer.php new file mode 100644 index 00000000..8115ff2e --- /dev/null +++ b/src/wp-admin/includes/class-wp-importer.php @@ -0,0 +1,311 @@ +__construct(); + } + + /** + * Returns array with imported permalinks from WordPress database + * + * @param string $bid + * @return array + */ + function get_imported_posts( $importer_name, $bid ) { + global $wpdb; + + $hashtable = array(); + + $limit = 100; + $offset = 0; + + // Grab all posts in chunks + do { + $meta_key = $importer_name . '_' . $bid . '_permalink'; + $sql = $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '%s' LIMIT %d,%d", $meta_key, $offset, $limit ); + $results = $wpdb->get_results( $sql ); + + // Increment offset + $offset = ( $limit + $offset ); + + if ( !empty( $results ) ) { + foreach ( $results as $r ) { + // Set permalinks into array + $hashtable[$r->meta_value] = intval( $r->post_id ); + } + } + } while ( count( $results ) == $limit ); + + // unset to save memory + unset( $results, $r ); + + return $hashtable; + } + + /** + * Return count of imported permalinks from WordPress database + * + * @param string $bid + * @return int + */ + function count_imported_posts( $importer_name, $bid ) { + global $wpdb; + + $count = 0; + + // Get count of permalinks + $meta_key = $importer_name . '_' . $bid . '_permalink'; + $sql = $wpdb->prepare( "SELECT COUNT( post_id ) AS cnt FROM $wpdb->postmeta WHERE meta_key = '%s'", $meta_key ); + + $result = $wpdb->get_results( $sql ); + + if ( !empty( $result ) ) + $count = intval( $result[0]->cnt ); + + // unset to save memory + unset( $results ); + + return $count; + } + + /** + * Set array with imported comments from WordPress database + * + * @param string $bid + * @return array + */ + function get_imported_comments( $bid ) { + global $wpdb; + + $hashtable = array(); + + $limit = 100; + $offset = 0; + + // Grab all comments in chunks + do { + $sql = $wpdb->prepare( "SELECT comment_ID, comment_agent FROM $wpdb->comments LIMIT %d,%d", $offset, $limit ); + $results = $wpdb->get_results( $sql ); + + // Increment offset + $offset = ( $limit + $offset ); + + if ( !empty( $results ) ) { + foreach ( $results as $r ) { + // Explode comment_agent key + list ( $ca_bid, $source_comment_id ) = explode( '-', $r->comment_agent ); + $source_comment_id = intval( $source_comment_id ); + + // Check if this comment came from this blog + if ( $bid == $ca_bid ) { + $hashtable[$source_comment_id] = intval( $r->comment_ID ); + } + } + } + } while ( count( $results ) == $limit ); + + // unset to save memory + unset( $results, $r ); + + return $hashtable; + } + + function set_blog( $blog_id ) { + if ( is_numeric( $blog_id ) ) { + $blog_id = (int) $blog_id; + } else { + $blog = 'http://' . preg_replace( '#^https?://#', '', $blog_id ); + if ( ( !$parsed = parse_url( $blog ) ) || empty( $parsed['host'] ) ) { + fwrite( STDERR, "Error: can not determine blog_id from $blog_id\n" ); + exit(); + } + if ( empty( $parsed['path'] ) ) + $parsed['path'] = '/'; + $blog = get_blog_details( array( 'domain' => $parsed['host'], 'path' => $parsed['path'] ) ); + if ( !$blog ) { + fwrite( STDERR, "Error: Could not find blog\n" ); + exit(); + } + $blog_id = (int) $blog->blog_id; + // Restore global $current_blog + global $current_blog; + $current_blog = $blog; + } + + if ( function_exists( 'is_multisite' ) ) { + if ( is_multisite() ) + switch_to_blog( $blog_id ); + } + + return $blog_id; + } + + function set_user( $user_id ) { + if ( is_numeric( $user_id ) ) { + $user_id = (int) $user_id; + } else { + $user_id = (int) username_exists( $user_id ); + } + + if ( !$user_id || !wp_set_current_user( $user_id ) ) { + fwrite( STDERR, "Error: can not find user\n" ); + exit(); + } + + return $user_id; + } + + /** + * Sort by strlen, longest string first + * + * @param string $a + * @param string $b + * @return int + */ + function cmpr_strlen( $a, $b ) { + return strlen( $b ) - strlen( $a ); + } + + /** + * GET URL + * + * @param string $url + * @param string $username + * @param string $password + * @param bool $head + * @return array + */ + function get_page( $url, $username = '', $password = '', $head = false ) { + // Increase the timeout + add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) ); + + $headers = array(); + $args = array(); + if ( true === $head ) + $args['method'] = 'HEAD'; + if ( !empty( $username ) && !empty( $password ) ) + $headers['Authorization'] = 'Basic ' . base64_encode( "$username:$password" ); + + $args['headers'] = $headers; + + return wp_remote_request( $url, $args ); + } + + /** + * Bump up the request timeout for http requests + * + * @param int $val + * @return int + */ + function bump_request_timeout( $val ) { + return 60; + } + + /** + * Check if user has exceeded disk quota + * + * @return bool + */ + function is_user_over_quota() { + global $current_blog; + + if ( function_exists( 'upload_is_user_over_quota' ) ) { + if ( upload_is_user_over_quota( 1 ) ) { + echo "Sorry, you have used your upload quota.\n"; + return true; + } + } + + return false; + } + + /** + * Replace newlines, tabs, and multiple spaces with a single space + * + * @param string $string + * @return string + */ + function min_whitespace( $string ) { + return preg_replace( '|[\r\n\t ]+|', ' ', $string ); + } + + /** + * Reset global variables that grow out of control during imports + * + * @return void + */ + function stop_the_insanity() { + global $wpdb, $wp_actions; + // Or define( 'WP_IMPORTING', true ); + $wpdb->queries = array(); + // Reset $wp_actions to keep it from growing out of control + $wp_actions = array(); + } +} + +/** + * Returns value of command line params. + * Exits when a required param is not set. + * + * @param string $param + * @param bool $required + * @return mixed + */ +function get_cli_args( $param, $required = false ) { + $args = $_SERVER['argv']; + + $out = array(); + + $last_arg = null; + $return = null; + + $il = sizeof( $args ); + + for ( $i = 1, $il; $i < $il; $i++ ) { + if ( (bool) preg_match( "/^--(.+)/", $args[$i], $match ) ) { + $parts = explode( "=", $match[1] ); + $key = preg_replace( "/[^a-z0-9]+/", "", $parts[0] ); + + if ( isset( $parts[1] ) ) { + $out[$key] = $parts[1]; + } else { + $out[$key] = true; + } + + $last_arg = $key; + } else if ( (bool) preg_match( "/^-([a-zA-Z0-9]+)/", $args[$i], $match ) ) { + for ( $j = 0, $jl = strlen( $match[1] ); $j < $jl; $j++ ) { + $key = $match[1]{$j}; + $out[$key] = true; + } + + $last_arg = $key; + } else if ( $last_arg !== null ) { + $out[$last_arg] = $args[$i]; + } + } + + // Check array for specified param + if ( isset( $out[$param] ) ) { + // Set return value + $return = $out[$param]; + } + + // Check for missing required param + if ( !isset( $out[$param] ) && $required ) { + // Display message and exit + echo "\"$param\" parameter is required but was not specified\n"; + exit(); + } + + return $return; +} diff --git a/src/wp-admin/includes/class-wp-links-list-table.php b/src/wp-admin/includes/class-wp-links-list-table.php new file mode 100644 index 00000000..bf1c0bc6 --- /dev/null +++ b/src/wp-admin/includes/class-wp-links-list-table.php @@ -0,0 +1,186 @@ + 'bookmarks', + ) ); + } + + function ajax_user_can() { + return current_user_can( 'manage_links' ); + } + + function prepare_items() { + global $cat_id, $s, $orderby, $order; + + wp_reset_vars( array( 'action', 'cat_id', 'linkurl', 'name', 'image', 'description', 'visible', 'target', 'category', 'link_id', 'submit', 'orderby', 'order', 'links_show_cat_id', 'rating', 'rel', 'notes', 'linkcheck[]', 's' ) ); + + $args = array( 'hide_invisible' => 0, 'hide_empty' => 0 ); + + if ( 'all' != $cat_id ) + $args['category'] = $cat_id; + if ( !empty( $s ) ) + $args['search'] = $s; + if ( !empty( $orderby ) ) + $args['orderby'] = $orderby; + if ( !empty( $order ) ) + $args['order'] = $order; + + $this->items = get_bookmarks( $args ); + } + + function no_items() { + _e( 'No links found.' ); + } + + function get_bulk_actions() { + $actions = array(); + $actions['delete'] = __( 'Delete' ); + + return $actions; + } + + function extra_tablenav( $which ) { + global $cat_id; + + if ( 'top' != $which ) + return; +?> +
+ $cat_id, + 'name' => 'cat_id', + 'taxonomy' => 'link_category', + 'show_option_all' => __( 'View all categories' ), + 'hide_empty' => true, + 'hierarchical' => 1, + 'show_count' => 0, + 'orderby' => 'name', + ); + wp_dropdown_categories( $dropdown_options ); + submit_button( __( 'Filter' ), 'secondary', false, false, array( 'id' => 'post-query-submit' ) ); +?> +
+ '', + 'name' => __( 'Name' ), + 'url' => __( 'URL' ), + 'categories' => __( 'Categories' ), + 'rel' => __( 'Relationship' ), + 'visible' => __( 'Visible' ), + 'rating' => __( 'Rating' ) + ); + } + + function get_sortable_columns() { + return array( + 'name' => 'name', + 'url' => 'url', + 'visible' => 'visible', + 'rating' => 'rating' + ); + } + + function display_rows() { + global $cat_id; + + $alt = 0; + + foreach ( $this->items as $link ) { + $link = sanitize_bookmark( $link ); + $link->link_name = esc_attr( $link->link_name ); + $link->link_category = wp_get_link_cats( $link->link_id ); + + $short_url = url_shorten( $link->link_url ); + + $visible = ( $link->link_visible == 'Y' ) ? __( 'Yes' ) : __( 'No' ); + $rating = $link->link_rating; + $style = ( $alt++ % 2 ) ? '' : ' class="alternate"'; + + $edit_link = get_edit_bookmark_link( $link ); +?> + > +get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $class = "class='column-$column_name'"; + + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + $attributes = $class . $style; + + switch ( $column_name ) { + case 'cb': + echo ''; + break; + + case 'name': + echo "link_name ) ) . "'>$link->link_name
"; + + $actions = array(); + $actions['edit'] = '' . __( 'Edit' ) . ''; + $actions['delete'] = "link_id ) . "' onclick=\"if ( confirm( '" . esc_js( sprintf( __( "You are about to delete this link '%s'\n 'Cancel' to stop, 'OK' to delete." ), $link->link_name ) ) . "' ) ) { return true;}return false;\">" . __( 'Delete' ) . ""; + echo $this->row_actions( $actions ); + + echo ''; + break; + case 'url': + echo "link_name ) )."'>$short_url"; + break; + case 'categories': + ?>>link_category as $category ) { + $cat = get_term( $category, 'link_category', OBJECT, 'display' ); + if ( is_wp_error( $cat ) ) + echo $cat->get_error_message(); + $cat_name = $cat->name; + if ( $cat_id != $category ) + $cat_name = "$cat_name"; + $cat_names[] = $cat_name; + } + echo implode( ', ', $cat_names ); + ?>>link_rel ) ? '
' : $link->link_rel; ?>>> + >link_id ); ?> + + + diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php new file mode 100644 index 00000000..1d80a7ba --- /dev/null +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -0,0 +1,894 @@ + '', + 'singular' => '', + 'ajax' => false + ) ); + + $screen = get_current_screen(); + + add_filter( "manage_{$screen->id}_columns", array( &$this, 'get_columns' ), 0 ); + + if ( !$args['plural'] ) + $args['plural'] = $screen->base; + + $this->_args = $args; + + if ( $args['ajax'] ) { + // wp_enqueue_script( 'list-table' ); + add_action( 'admin_footer', array( &$this, '_js_vars' ) ); + } + } + + /** + * Checks the current user's permissions + * @uses wp_die() + * + * @since 3.1.0 + * @access public + * @abstract + */ + function ajax_user_can() { + die( 'function WP_List_Table::ajax_user_can() must be over-ridden in a sub-class.' ); + } + + /** + * Prepares the list of items for displaying. + * @uses WP_List_Table::set_pagination_args() + * + * @since 3.1.0 + * @access public + * @abstract + */ + function prepare_items() { + die( 'function WP_List_Table::prepare_items() must be over-ridden in a sub-class.' ); + } + + /** + * An internal method that sets all the necessary pagination arguments + * + * @param array $args An associative array with information about the pagination + * @access protected + */ + function set_pagination_args( $args ) { + $args = wp_parse_args( $args, array( + 'total_items' => 0, + 'total_pages' => 0, + 'per_page' => 0, + ) ); + + if ( !$args['total_pages'] && $args['per_page'] > 0 ) + $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] ); + + $this->_pagination_args = $args; + } + + /** + * Access the pagination args + * + * @since 3.1.0 + * @access public + * + * @param string $key + * @return array + */ + function get_pagination_arg( $key ) { + if ( 'page' == $key ) + return $this->get_pagenum(); + + if ( isset( $this->_pagination_args[$key] ) ) + return $this->_pagination_args[$key]; + } + + /** + * Whether the table has items to display or not + * + * @since 3.1.0 + * @access public + * + * @return bool + */ + function has_items() { + return !empty( $this->items ); + } + + /** + * Message to be displayed when there are no items + * + * @since 3.1.0 + * @access public + */ + function no_items() { + _e( 'No items found.' ); + } + + /** + * Display the search box. + * + * @since 3.1.0 + * @access public + * + * @param string $text The search button text + * @param string $input_id The search input id + */ + function search_box( $text, $input_id ) { + if ( empty( $_REQUEST['s'] ) && !$this->has_items() ) + return; + + $input_id = $input_id . '-search-input'; + + if ( ! empty( $_REQUEST['orderby'] ) ) + echo ''; + if ( ! empty( $_REQUEST['order'] ) ) + echo ''; +?> + + link ) with the list + * of views available on this table. + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_views() { + return array(); + } + + /** + * Display the bulk actions dropdown. + * + * @since 3.1.0 + * @access public + */ + function views() { + $screen = get_current_screen(); + + $views = $this->get_views(); + $views = apply_filters( 'views_' . $screen->id, $views ); + + if ( empty( $views ) ) + return; + + echo "
    \n"; + foreach ( $views as $class => $view ) { + $views[ $class ] = "\t
  • $view"; + } + echo implode( " |
  • \n", $views ) . "\n"; + echo "
"; + } + + /** + * Get an associative array ( option_name => option_title ) with the list + * of bulk actions available on this table. + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_bulk_actions() { + return array(); + } + + /** + * Display the bulk actions dropdown. + * + * @since 3.1.0 + * @access public + */ + function bulk_actions() { + $screen = get_current_screen(); + + if ( is_null( $this->_actions ) ) { + $no_new_actions = $this->_actions = $this->get_bulk_actions(); + // This filter can currently only be used to remove actions. + $this->_actions = apply_filters( 'bulk_actions-' . $screen->id, $this->_actions ); + $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions ); + $two = ''; + } else { + $two = '2'; + } + + if ( empty( $this->_actions ) ) + return; + + echo "\n"; + + submit_button( __( 'Apply' ), 'button-secondary action', false, false, array( 'id' => "doaction$two" ) ); + echo "\n"; + } + + /** + * Get the current action selected from the bulk actions dropdown. + * + * @since 3.1.0 + * @access public + * + * @return string|bool The action name or False if no action was selected + */ + function current_action() { + if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) + return $_REQUEST['action']; + + if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ) + return $_REQUEST['action2']; + + return false; + } + + /** + * Generate row actions div + * + * @since 3.1.0 + * @access protected + * + * @param array $actions The list of actions + * @param bool $always_visible Wether the actions should be always visible + * @return string + */ + function row_actions( $actions, $always_visible = false ) { + $action_count = count( $actions ); + $i = 0; + + if ( !$action_count ) + return ''; + + $out = '
'; + foreach ( $actions as $action => $link ) { + ++$i; + ( $i == $action_count ) ? $sep = '' : $sep = ' | '; + $out .= "$link$sep"; + } + $out .= '
'; + + return $out; + } + + /** + * Display a monthly dropdown for filtering items + * + * @since 3.1.0 + * @access protected + */ + function months_dropdown( $post_type ) { + global $wpdb, $wp_locale; + + $months = $wpdb->get_results( $wpdb->prepare( " + SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month + FROM $wpdb->posts + WHERE post_type = %s + ORDER BY post_date DESC + ", $post_type ) ); + + $month_count = count( $months ); + + if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) + return; + + $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0; +?> + + __( 'List View' ), + 'excerpt' => __( 'Excerpt View' ) + ); + +?> + +
+ $title ) { + $class = ( $current_mode == $mode ) ? 'class="current"' : ''; + echo "$title\n"; + } + ?> +
+'; + + echo "" . number_format_i18n( get_comments_number() ) . ""; + + if ( $pending_comments ) + echo ''; + } + + /** + * Get the current page number + * + * @since 3.1.0 + * @access protected + * + * @return int + */ + function get_pagenum() { + $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0; + + if( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] ) + $pagenum = $this->_pagination_args['total_pages']; + + return max( 1, $pagenum ); + } + + /** + * Get number of items to display on a single page + * + * @since 3.1.0 + * @access protected + * + * @return int + */ + function get_items_per_page( $option, $default = 20 ) { + $per_page = (int) get_user_option( $option ); + if ( empty( $per_page ) || $per_page < 1 ) + $per_page = $default; + + return (int) apply_filters( $option, $per_page ); + } + + /** + * Display the pagination. + * + * @since 3.1.0 + * @access protected + */ + function pagination( $which ) { + if ( empty( $this->_pagination_args ) ) + return; + + extract( $this->_pagination_args ); + + $output = '' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . ''; + + $current = $this->get_pagenum(); + + $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + + $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url ); + + $page_links = array(); + + $disable_first = $disable_last = ''; + if ( $current == 1 ) + $disable_first = ' disabled'; + if ( $current == $total_pages ) + $disable_last = ' disabled'; + + $page_links[] = sprintf( "%s", + 'first-page' . $disable_first, + esc_attr__( 'Go to the first page' ), + esc_url( remove_query_arg( 'paged', $current_url ) ), + '«' + ); + + $page_links[] = sprintf( "%s", + 'prev-page' . $disable_first, + esc_attr__( 'Go to the previous page' ), + esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ), + '‹' + ); + + if ( 'bottom' == $which ) + $html_current_page = $current; + else + $html_current_page = sprintf( "", + esc_attr__( 'Current page' ), + esc_attr( 'paged' ), + $current, + strlen( $total_pages ) + ); + + $html_total_pages = sprintf( "%s", number_format_i18n( $total_pages ) ); + $page_links[] = '' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . ''; + + $page_links[] = sprintf( "%s", + 'next-page' . $disable_last, + esc_attr__( 'Go to the next page' ), + esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ), + '›' + ); + + $page_links[] = sprintf( "%s", + 'last-page' . $disable_last, + esc_attr__( 'Go to the last page' ), + esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ), + '»' + ); + + $output .= "\n" . join( "\n", $page_links ); + + $page_class = $total_pages < 2 ? ' one-page' : ''; + + $this->_pagination = "
$output
"; + + echo $this->_pagination; + } + + /** + * Get a list of columns. The format is: + * 'internal-name' => 'Title' + * + * @since 3.1.0 + * @access protected + * @abstract + * + * @return array + */ + function get_columns() { + die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' ); + } + + /** + * Get a list of sortable columns. The format is: + * 'internal-name' => 'orderby' + * or + * 'internal-name' => array( 'orderby', true ) + * + * The second format will make the initial sorting order be descending + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_sortable_columns() { + return array(); + } + + /** + * Get a list of all, hidden and sortable columns, with filter applied + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_column_info() { + if ( isset( $this->_column_headers ) ) + return $this->_column_headers; + + $screen = get_current_screen(); + + $columns = get_column_headers( $screen ); + $hidden = get_hidden_columns( $screen ); + + $_sortable = apply_filters( "manage_{$screen->id}_sortable_columns", $this->get_sortable_columns() ); + + $sortable = array(); + foreach ( $_sortable as $id => $data ) { + if ( empty( $data ) ) + continue; + + $data = (array) $data; + if ( !isset( $data[1] ) ) + $data[1] = false; + + $sortable[$id] = $data; + } + + $this->_column_headers = array( $columns, $hidden, $sortable ); + + return $this->_column_headers; + } + + /** + * Return number of visible columns + * + * @since 3.1.0 + * @access public + * + * @return int + */ + function get_column_count() { + list ( $columns, $hidden ) = $this->get_column_info(); + $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) ); + return count( $columns ) - count( $hidden ); + } + + /** + * Print column headers, accounting for hidden and sortable columns. + * + * @since 3.1.0 + * @access protected + * + * @param bool $with_id Whether to set the id attribute or not + */ + function print_column_headers( $with_id = true ) { + $screen = get_current_screen(); + + list( $columns, $hidden, $sortable ) = $this->get_column_info(); + + $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $current_url = remove_query_arg( 'paged', $current_url ); + + if ( isset( $_GET['orderby'] ) ) + $current_orderby = $_GET['orderby']; + else + $current_orderby = ''; + + if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] ) + $current_order = 'desc'; + else + $current_order = 'asc'; + + foreach ( $columns as $column_key => $column_display_name ) { + $class = array( 'manage-column', "column-$column_key" ); + + $style = ''; + if ( in_array( $column_key, $hidden ) ) + $style = 'display:none;'; + + $style = ' style="' . $style . '"'; + + if ( 'cb' == $column_key ) + $class[] = 'check-column'; + elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) + $class[] = 'num'; + + if ( isset( $sortable[$column_key] ) ) { + list( $orderby, $desc_first ) = $sortable[$column_key]; + + if ( $current_orderby == $orderby ) { + $order = 'asc' == $current_order ? 'desc' : 'asc'; + $class[] = 'sorted'; + $class[] = $current_order; + } else { + $order = $desc_first ? 'desc' : 'asc'; + $class[] = 'sortable'; + $class[] = $desc_first ? 'asc' : 'desc'; + } + + $column_display_name = '' . $column_display_name . ''; + } + + $id = $with_id ? "id='$column_key'" : ''; + + if ( !empty( $class ) ) + $class = "class='" . join( ' ', $class ) . "'"; + + echo "$column_display_name"; + } + } + + /** + * Display the table + * + * @since 3.1.0 + * @access public + */ + function display() { + extract( $this->_args ); + + $this->display_tablenav( 'top' ); + +?> + + + + print_column_headers(); ?> + + + + + + print_column_headers( false ); ?> + + + + > + display_rows_or_placeholder(); ?> + +
+display_tablenav( 'bottom' ); + } + + /** + * Get a list of CSS classes for the tag + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_table_classes() { + return array( 'widefat', 'fixed', $this->_args['plural'] ); + } + + /** + * Generate the table navigation above or below the table + * + * @since 3.1.0 + * @access protected + */ + function display_tablenav( $which ) { + if ( 'top' == $which ) + wp_nonce_field( 'bulk-' . $this->_args['plural'] ); +?> +
+ +
+ bulk_actions( $which ); ?> +
+extra_tablenav( $which ); + $this->pagination( $which ); +?> + +
+
+ part of the table + * + * @since 3.1.0 + * @access protected + */ + function display_rows_or_placeholder() { + if ( $this->has_items() ) { + $this->display_rows(); + } else { + list( $columns, $hidden ) = $this->get_column_info(); + echo ''; + } + } + + /** + * Generate the table rows + * + * @since 3.1.0 + * @access protected + */ + function display_rows() { + foreach ( $this->items as $item ) + $this->single_row( $item ); + } + + /** + * Generates content for a single row of the table + * + * @since 3.1.0 + * @access protected + * + * @param object $item The current item + */ + function single_row( $item ) { + static $row_class = ''; + $row_class = ( $row_class == '' ? ' class="alternate"' : '' ); + + echo ''; + echo $this->single_row_columns( $item ); + echo ''; + } + + /** + * Generates the columns for a single row of the table + * + * @since 3.1.0 + * @access protected + * + * @param object $item The current item + */ + function single_row_columns( $item ) { + list( $columns, $hidden ) = $this->get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $class = "class='$column_name column-$column_name'"; + + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + $attributes = "$class$style"; + + if ( 'cb' == $column_name ) { + echo ''; + } + elseif ( method_exists( $this, 'column_' . $column_name ) ) { + echo ""; + } + else { + echo ""; + } + } + } + + /** + * Handle an incoming ajax request (called from admin-ajax.php) + * + * @since 3.1.0 + * @access public + */ + function ajax_response() { + $this->prepare_items(); + + extract( $this->_args ); + extract( $this->_pagination_args ); + + ob_start(); + if ( ! empty( $_REQUEST['no_placeholder'] ) ) + $this->display_rows(); + else + $this->display_rows_or_placeholder(); + + $rows = ob_get_clean(); + + $response = array( 'rows' => $rows ); + + if ( isset( $total_items ) ) + $response['total_items_i18n'] = sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ); + + if ( isset( $total_pages ) ) { + $response['total_pages'] = $total_pages; + $response['total_pages_i18n'] = number_format_i18n( $total_pages ); + } + + die( json_encode( $response ) ); + } + + /** + * Send required variables to JavaScript land + * + * @access private + */ + function _js_vars() { + $args = array( + 'class' => get_class( $this ), + 'screen' => get_current_screen() + ); + + printf( "\n", json_encode( $args ) ); + } +} +?> diff --git a/src/wp-admin/includes/class-wp-media-list-table.php b/src/wp-admin/includes/class-wp-media-list-table.php new file mode 100644 index 00000000..5e05f01e --- /dev/null +++ b/src/wp-admin/includes/class-wp-media-list-table.php @@ -0,0 +1,374 @@ +detached = isset( $_REQUEST['detached'] ) || isset( $_REQUEST['find_detached'] ); + + parent::WP_List_Table( array( + 'plural' => 'media' + ) ); + } + + function ajax_user_can() { + return current_user_can('upload_files'); + } + + function prepare_items() { + global $lost, $wpdb, $wp_query, $post_mime_types, $avail_post_mime_types; + + $q = $_REQUEST; + + if ( !empty( $lost ) ) + $q['post__in'] = implode( ',', $lost ); + + list( $post_mime_types, $avail_post_mime_types ) = wp_edit_attachments_query( $q ); + + $this->is_trash = isset( $_REQUEST['status'] ) && 'trash' == $_REQUEST['status']; + + $this->set_pagination_args( array( + 'total_items' => $wp_query->found_posts, + 'total_pages' => $wp_query->max_num_pages, + 'per_page' => $wp_query->query_vars['posts_per_page'], + ) ); + } + + function get_views() { + global $wpdb, $post_mime_types, $avail_post_mime_types; + + $type_links = array(); + $_num_posts = (array) wp_count_attachments(); + $_total_posts = array_sum($_num_posts) - $_num_posts['trash']; + if ( !isset( $total_orphans ) ) + $total_orphans = $wpdb->get_var( "SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' AND post_parent < 1" ); + $matches = wp_match_mime_types(array_keys($post_mime_types), array_keys($_num_posts)); + foreach ( $matches as $type => $reals ) + foreach ( $reals as $real ) + $num_posts[$type] = ( isset( $num_posts[$type] ) ) ? $num_posts[$type] + $_num_posts[$real] : $_num_posts[$real]; + + $class = ( empty($_GET['post_mime_type']) && !$this->detached && !isset($_GET['status']) ) ? ' class="current"' : ''; + $type_links['all'] = "" . sprintf( _nx( 'All (%s)', 'All (%s)', $_total_posts, 'uploaded files' ), number_format_i18n( $_total_posts ) ) . ''; + foreach ( $post_mime_types as $mime_type => $label ) { + $class = ''; + + if ( !wp_match_mime_types($mime_type, $avail_post_mime_types) ) + continue; + + if ( !empty($_GET['post_mime_type']) && wp_match_mime_types($mime_type, $_GET['post_mime_type']) ) + $class = ' class="current"'; + if ( !empty( $num_posts[$mime_type] ) ) + $type_links[$mime_type] = "" . sprintf( translate_nooped_plural( $label[2], $num_posts[$mime_type] ), number_format_i18n( $num_posts[$mime_type] )) . ''; + } + $type_links['detached'] = 'detached ? ' class="current"' : '' ) . '>' . sprintf( _nx( 'Unattached (%s)', 'Unattached (%s)', $total_orphans, 'detached files' ), number_format_i18n( $total_orphans ) ) . ''; + + if ( !empty($_num_posts['trash']) ) + $type_links['trash'] = '' . sprintf( _nx( 'Trash (%s)', 'Trash (%s)', $_num_posts['trash'], 'uploaded files' ), number_format_i18n( $_num_posts['trash'] ) ) . ''; + + return $type_links; + } + + function get_bulk_actions() { + $actions = array(); + $actions['delete'] = __( 'Delete Permanently' ); + if ( $this->detached ) + $actions['attach'] = __( 'Attach to a post' ); + + return $actions; + } + + function extra_tablenav( $which ) { + global $post_type; + $post_type_obj = get_post_type_object( $post_type ); +?> +
+detached && !$this->is_trash ) { + $this->months_dropdown( $post_type ); + + do_action( 'restrict_manage_posts' ); + submit_button( __( 'Filter' ), 'secondary', false, false, array( 'id' => 'post-query-submit' ) ); + } + + if ( $this->detached ) { + submit_button( __( 'Scan for lost attachments' ), 'secondary', 'find_detached', false ); + } elseif ( $this->is_trash && current_user_can( 'edit_others_posts' ) ) { + submit_button( __( 'Empty Trash' ), 'button-secondary apply', 'delete_all', false ); + } ?> +
+'; + $posts_columns['icon'] = ''; + /* translators: column name */ + $posts_columns['title'] = _x( 'File', 'column name' ); + $posts_columns['author'] = __( 'Author' ); + //$posts_columns['tags'] = _x( 'Tags', 'column name' ); + /* translators: column name */ + if ( !$this->detached ) { + $posts_columns['parent'] = _x( 'Attached to', 'column name' ); + $posts_columns['comments'] = '
Comments
'; + } + /* translators: column name */ + $posts_columns['date'] = _x( 'Date', 'column name' ); + $posts_columns = apply_filters( 'manage_media_columns', $posts_columns, $this->detached ); + + return $posts_columns; + } + + function get_sortable_columns() { + return array( + 'title' => 'title', + 'author' => 'author', + 'parent' => 'parent', + 'comments' => 'comment_count', + 'date' => array( 'date', true ), + ); + } + + function display_rows() { + global $post, $id; + + add_filter( 'the_title','esc_html' ); + $alt = ''; + + while ( have_posts() ) : the_post(); + + if ( $this->is_trash && $post->post_status != 'trash' + || !$this->is_trash && $post->post_status == 'trash' ) + continue; + + $alt = ( 'alternate' == $alt ) ? '' : 'alternate'; + $post_owner = ( get_current_user_id() == $post->post_author ) ? 'self' : 'other'; + $att_title = _draft_or_post_title(); +?> + post_status ); ?>' valign="top"> +get_column_info(); +foreach ( $columns as $column_name => $column_display_name ) { + $class = "class='$column_name column-$column_name'"; + + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + $attributes = $class . $style; + + switch ( $column_name ) { + + case 'cb': +?> + + + + + + + + + + + +post_date && 'date' == $column_name ) { + $t_time = $h_time = __( 'Unpublished' ); + } else { + $t_time = get_the_time( __( 'Y/m/d g:i:s A' ) ); + $m_time = $post->post_date; + $time = get_post_time( 'G', true, $post, false ); + if ( ( abs( $t_diff = time() - $time ) ) < 86400 ) { + if ( $t_diff < 0 ) + $h_time = sprintf( __( '%s from now' ), human_time_diff( $time ) ); + else + $h_time = sprintf( __( '%s ago' ), human_time_diff( $time ) ); + } else { + $h_time = mysql2date( __( 'Y/m/d' ), $m_time ); + } + } +?> + +post_parent > 0 ) { + if ( get_post( $post->post_parent ) ) { + $title =_draft_or_post_title( $post->post_parent ); + } +?> + + + + + + + + + +detached ) { + if ( current_user_can( 'edit_post', $post->ID ) ) + $actions['edit'] = '' . __( 'Edit' ) . ''; + if ( current_user_can( 'delete_post', $post->ID ) ) + if ( EMPTY_TRASH_DAYS && MEDIA_TRASH ) { + $actions['trash'] = "ID ) . "'>" . __( 'Trash' ) . ""; + } else { + $delete_ays = !MEDIA_TRASH ? " onclick='return showNotice.warn();'" : ''; + $actions['delete'] = "ID ) . "'>" . __( 'Delete Permanently' ) . ""; + } + $actions['view'] = '' . __( 'View' ) . ''; + if ( current_user_can( 'edit_post', $post->ID ) ) + $actions['attach'] = ''.__( 'Attach' ).''; + } + else { + if ( current_user_can( 'edit_post', $post->ID ) && !$this->is_trash ) + $actions['edit'] = '' . __( 'Edit' ) . ''; + if ( current_user_can( 'delete_post', $post->ID ) ) { + if ( $this->is_trash ) + $actions['untrash'] = "ID ) . "'>" . __( 'Restore' ) . ""; + elseif ( EMPTY_TRASH_DAYS && MEDIA_TRASH ) + $actions['trash'] = "ID ) . "'>" . __( 'Trash' ) . ""; + if ( $this->is_trash || !EMPTY_TRASH_DAYS || !MEDIA_TRASH ) { + $delete_ays = ( !$this->is_trash && !MEDIA_TRASH ) ? " onclick='return showNotice.warn();'" : ''; + $actions['delete'] = "ID ) . "'>" . __( 'Delete Permanently' ) . ""; + } + } + if ( !$this->is_trash ) { + $title =_draft_or_post_title( $post->post_parent ); + $actions['view'] = '' . __( 'View' ) . ''; + } + } + + $actions = apply_filters( 'media_row_actions', $actions, $post, $this->detached ); + + return $actions; + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-ms-sites-list-table.php b/src/wp-admin/includes/class-wp-ms-sites-list-table.php new file mode 100644 index 00000000..5414d2c0 --- /dev/null +++ b/src/wp-admin/includes/class-wp-ms-sites-list-table.php @@ -0,0 +1,340 @@ + 'sites', + ) ); + } + + function ajax_user_can() { + return current_user_can( 'manage_sites' ); + } + + function prepare_items() { + global $s, $mode, $wpdb, $current_site; + + $mode = ( empty( $_REQUEST['mode'] ) ) ? 'list' : $_REQUEST['mode']; + + $per_page = $this->get_items_per_page( 'sites_network_per_page' ); + + $pagenum = $this->get_pagenum(); + + $s = isset( $_REQUEST['s'] ) ? stripslashes( trim( $_REQUEST[ 's' ] ) ) : ''; + $wild = ''; + if ( false !== strpos($s, '*') ) { + $wild = '%'; + $s = trim($s, '*'); + } + + $like_s = esc_sql( like_escape( $s ) ); + + $large_network = false; + // If the network is large and a search is not being performed, show only the latest blogs with no paging in order + // to avoid expensive count queries. + if ( !$s && ( get_blog_count() >= 10000 ) ) { + if ( !isset($_REQUEST['orderby']) ) + $_GET['orderby'] = $_REQUEST['orderby'] = ''; + if ( !isset($_REQUEST['order']) ) + $_GET['order'] = $_REQUEST['order'] = 'DESC'; + $large_network = true; + } + + $query = "SELECT * FROM {$wpdb->blogs} WHERE site_id = '{$wpdb->siteid}' "; + + if ( empty($s) ) { + // Nothing to do. + } elseif ( preg_match('/^[0-9]+\./', $s) ) { + // IP address + $reg_blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->registration_log} WHERE {$wpdb->registration_log}.IP LIKE ( '{$like_s}$wild' )" ); + + if ( !$reg_blog_ids ) + $reg_blog_ids = array( 0 ); + + $query = "SELECT * + FROM {$wpdb->blogs} + WHERE site_id = '{$wpdb->siteid}' + AND {$wpdb->blogs}.blog_id IN (" . implode( ', ', $reg_blog_ids ) . ")"; + } else { + if ( is_numeric($s) ) { + $query .= " AND ( {$wpdb->blogs}.blog_id = '{$like_s}' )"; + } elseif ( is_subdomain_install() ) { + $blog_s = str_replace( '.' . $current_site->domain, '', $like_s ); + $blog_s .= $wild . '.' . $current_site->domain; + $query .= " AND ( {$wpdb->blogs}.domain LIKE '$blog_s' ) "; + } else { + if ( $like_s != trim('/', $current_site->path) ) + $blog_s = $current_site->path . $like_s . $wild . '/'; + else + $blog_s = $like_s; + $query .= " AND ( {$wpdb->blogs}.path LIKE '$blog_s' )"; + } + } + + $order_by = isset( $_REQUEST['orderby'] ) ? $_REQUEST['orderby'] : ''; + if ( $order_by == 'registered' ) { + $query .= ' ORDER BY registered '; + } elseif ( $order_by == 'lastupdated' ) { + $query .= ' ORDER BY last_updated '; + } elseif ( $order_by == 'blogname' ) { + if ( is_subdomain_install() ) + $query .= ' ORDER BY domain '; + else + $query .= ' ORDER BY path '; + } elseif ( $order_by == 'blog_id' ) { + $query .= ' ORDER BY blog_id '; + } else { + $order_by = null; + } + + if ( isset( $order_by ) ) { + $order = ( isset( $_REQUEST['order'] ) && 'DESC' == strtoupper( $_REQUEST['order'] ) ) ? "DESC" : "ASC"; + $query .= $order; + } + + // Don't do an unbounded count on large networks + if ( ! $large_network ) + $total = $wpdb->get_var( str_replace( 'SELECT *', 'SELECT COUNT( blog_id )', $query ) ); + + $query .= " LIMIT " . intval( ( $pagenum - 1 ) * $per_page ) . ", " . intval( $per_page ); + $this->items = $wpdb->get_results( $query, ARRAY_A ); + + if ( $large_network ) + $total = count($this->items); + + $this->set_pagination_args( array( + 'total_items' => $total, + 'per_page' => $per_page, + ) ); + } + + function no_items() { + _e( 'No sites found.' ); + } + + function get_bulk_actions() { + $actions = array(); + if ( current_user_can( 'delete_sites' ) ) + $actions['delete'] = __( 'Delete' ); + $actions['spam'] = _x( 'Mark as Spam', 'site' ); + $actions['notspam'] = _x( 'Not Spam', 'site' ); + + return $actions; + } + + function pagination( $which ) { + global $mode; + + parent::pagination( $which ); + + if ( 'top' == $which ) + $this->view_switcher( $mode ); + } + + function get_columns() { + $blogname_columns = ( is_subdomain_install() ) ? __( 'Domain' ) : __( 'Path' ); + $sites_columns = array( + 'cb' => '', + 'blogname' => $blogname_columns, + 'lastupdated' => __( 'Last Updated' ), + 'registered' => _x( 'Registered', 'site' ), + 'users' => __( 'Users' ) + ); + + if ( has_filter( 'wpmublogsaction' ) ) + $sites_columns['plugins'] = __( 'Actions' ); + + $sites_columns = apply_filters( 'wpmu_blogs_columns', $sites_columns ); + + return $sites_columns; + } + + function get_sortable_columns() { + return array( + 'blogname' => 'blogname', + 'lastupdated' => 'lastupdated', + 'registered' => 'blog_id', + ); + } + + function display_rows() { + global $current_site, $mode; + + $status_list = array( + 'archived' => array( 'site-archived', __( 'Archived' ) ), + 'spam' => array( 'site-spammed', _x( 'Spam', 'site' ) ), + 'deleted' => array( 'site-deleted', __( 'Deleted' ) ), + 'mature' => array( 'site-mature', __( 'Mature' ) ) + ); + + $class = ''; + foreach ( $this->items as $blog ) { + $class = ( 'alternate' == $class ) ? '' : 'alternate'; + reset( $status_list ); + + $blog_states = array(); + foreach ( $status_list as $status => $col ) { + if ( get_blog_status( $blog['blog_id'], $status ) == 1 ) { + $class = $col[0]; + $blog_states[] = $col[1]; + } + } + $blog_state = ''; + if ( ! empty( $blog_states ) ) { + $state_count = count( $blog_states ); + $i = 0; + $blog_state .= ' - '; + foreach ( $blog_states as $state ) { + ++$i; + ( $i == $state_count ) ? $sep = '' : $sep = ', '; + $blog_state .= "$state$sep"; + } + } + echo ""; + + $blogname = ( is_subdomain_install() ) ? str_replace( '.'.$current_site->domain, '', $blog['domain'] ) : $blog['path']; + + list( $columns, $hidden ) = $this->get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + switch ( $column_name ) { + case 'cb': ?> + + + + "; ?> + + ' . sprintf( _x( '%1$s – %2$s', '%1$s: site name. %2$s: site tagline.' ), get_blog_option( $blog['blog_id'], 'blogname' ), get_blog_option( $blog['blog_id'], 'blogdescription ' ) ) . '

'; + + // Preordered. + $actions = array( + 'edit' => '', 'backend' => '', + 'activate' => '', 'deactivate' => '', + 'archive' => '', 'unarchive' => '', + 'spam' => '', 'unspam' => '', + 'delete' => '', + 'visit' => '', + ); + + $actions['edit'] = '' . __( 'Edit' ) . ''; + $actions['backend'] = "" . __( 'Dashboard' ) . ''; + if ( $current_site->blog_id != $blog['blog_id'] ) { + if ( get_blog_status( $blog['blog_id'], 'deleted' ) == '1' ) + $actions['activate'] = '' . __( 'Activate' ) . ''; + else + $actions['deactivate'] = '' . __( 'Deactivate' ) . ''; + + if ( get_blog_status( $blog['blog_id'], 'archived' ) == '1' ) + $actions['unarchive'] = '' . __( 'Unarchive' ) . ''; + else + $actions['archive'] = '' . _x( 'Archive', 'verb; site' ) . ''; + + if ( get_blog_status( $blog['blog_id'], 'spam' ) == '1' ) + $actions['unspam'] = '' . _x( 'Not Spam', 'site' ) . ''; + else + $actions['spam'] = '' . _x( 'Spam', 'site' ) . ''; + + if ( current_user_can( 'delete_site', $blog['blog_id'] ) ) + $actions['delete'] = '' . __( 'Delete' ) . ''; + } + + $actions['visit'] = "" . __( 'Visit' ) . ''; + + $actions = apply_filters( 'manage_sites_action_links', array_filter( $actions ), $blog['blog_id'], $blogname ); + echo $this->row_actions( $actions ); + ?> + + "; + if ( 'list' == $mode ) + $date = 'Y/m/d'; + else + $date = 'Y/m/d \<\b\r \/\> g:i:s a'; + echo ( $blog['last_updated'] == '0000-00-00 00:00:00' ) ? __( 'Never' ) : mysql2date( $date, $blog['last_updated'] ); ?> + + "; + if ( $blog['registered'] == '0000-00-00 00:00:00' ) + echo '—'; + else + echo mysql2date( $date, $blog['registered'] ); + ?> + + "; + $blogusers = get_users( array( 'blog_id' => $blog['blog_id'], 'number' => 6) ); + if ( is_array( $blogusers ) ) { + $blogusers_warning = ''; + if ( count( $blogusers ) > 5 ) { + $blogusers = array_slice( $blogusers, 0, 5 ); + $blogusers_warning = __( 'Only showing first 5 users.' ) . ' ' . __( 'More' ) . ''; + } + foreach ( $blogusers as $user_object ) { + echo '' . esc_html( $user_object->user_login ) . ' '; + if ( 'list' != $mode ) + echo '( ' . $user_object->user_email . ' )'; + echo '
'; + } + if ( $blogusers_warning != '' ) + echo '' . $blogusers_warning . '
'; + } + ?> + + + "; + do_action( 'wpmublogsaction', $blog['blog_id'] ); ?> + + "; + do_action( 'manage_sites_custom_column', $column_name, $blog['blog_id'] ); + echo ""; + break; + } + } + ?> + + diff --git a/src/wp-admin/includes/class-wp-ms-themes-list-table.php b/src/wp-admin/includes/class-wp-ms-themes-list-table.php new file mode 100644 index 00000000..6e34a163 --- /dev/null +++ b/src/wp-admin/includes/class-wp-ms-themes-list-table.php @@ -0,0 +1,361 @@ +get_pagenum(); + + $screen = get_current_screen(); + $this->is_site_themes = ( 'site-themes-network' == $screen->id ) ? true : false; + + if ( $this->is_site_themes ) + $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; + + parent::WP_List_Table( array( + 'plural' => 'themes' + ) ); + } + + function get_table_classes() { + return array( 'widefat', 'plugins' ); // todo: remove and add CSS for .themes + } + + function ajax_user_can() { + $menu_perms = get_site_option( 'menu_items', array() ); + + if ( empty( $menu_perms['themes'] ) && ! is_super_admin() ) + return false; + + if ( $this->is_site_themes && !current_user_can('manage_sites') ) + return false; + elseif ( !$this->is_site_themes && !current_user_can('manage_network_themes') ) + return false; + return true; + } + + function prepare_items() { + global $status, $themes, $totals, $page, $orderby, $order, $s; + + wp_reset_vars( array( 'orderby', 'order', 's' ) ); + + $themes = array( + 'all' => apply_filters( 'all_themes', get_themes() ), + 'search' => array(), + 'enabled' => array(), + 'disabled' => array(), + 'upgrade' => array() + ); + + $site_allowed_themes = get_site_allowed_themes(); + if ( !$this->is_site_themes ) { + $allowed_themes = $site_allowed_themes; + $themes_per_page = $this->get_items_per_page( 'themes_network_per_page' ); + } else { + $allowed_themes = wpmu_get_blog_allowedthemes( $this->site_id ); + $themes_per_page = $this->get_items_per_page( 'site_themes_network_per_page' ); + } + + $current = get_site_transient( 'update_themes' ); + + foreach ( (array) $themes['all'] as $key => $theme ) { + $theme_key = $theme['Stylesheet']; + + if ( isset( $allowed_themes [ $theme_key ] ) ) { + $themes['all'][$key]['enabled'] = true; + $themes['enabled'][$key] = $themes['all'][$key]; + } + else { + $themes['all'][$key]['enabled'] = false; + $themes['disabled'][$key] = $themes['all'][$key]; + } + if ( isset( $current->response[ $theme['Template'] ] ) ) + $themes['upgrade'][$key] = $themes['all'][$key]; + + if ( $this->is_site_themes && isset( $site_allowed_themes[$theme_key] ) ) { + unset( $themes['all'][$key] ); + unset( $themes['enabled'][$key] ); + unset( $themes['disabled'][$key] ); + } + } + + if ( !current_user_can( 'update_themes' ) || $this->is_site_themes ) + $themes['upgrade'] = array(); + + if ( $s ) { + $status = 'search'; + $themes['search'] = array_filter( $themes['all'], array( &$this, '_search_callback' ) ); + } + + $totals = array(); + foreach ( $themes as $type => $list ) + $totals[ $type ] = count( $list ); + + if ( empty( $themes[ $status ] ) && !in_array( $status, array( 'all', 'search' ) ) ) + $status = 'all'; + + $this->items = $themes[ $status ]; + $total_this_page = $totals[ $status ]; + + if ( $orderby ) { + $orderby = ucfirst( $orderby ); + $order = strtoupper( $order ); + + uasort( $this->items, array( &$this, '_order_callback' ) ); + } + + $start = ( $page - 1 ) * $themes_per_page; + + if ( $total_this_page > $themes_per_page ) + $this->items = array_slice( $this->items, $start, $themes_per_page ); + + $this->set_pagination_args( array( + 'total_items' => $total_this_page, + 'per_page' => $themes_per_page, + ) ); + } + + function _search_callback( $theme ) { + static $term; + if ( is_null( $term ) ) + $term = stripslashes( $_REQUEST['s'] ); + + $search_fields = array( 'Name', 'Title', 'Description', 'Author', 'Author Name', 'Author URI', 'Template', 'Stylesheet' ); + foreach ( $search_fields as $field ) + if ( stripos( $theme[ $field ], $term ) !== false ) + return true; + + return false; + } + + function _order_callback( $theme_a, $theme_b ) { + global $orderby, $order; + + $a = $theme_a[$orderby]; + $b = $theme_b[$orderby]; + + if ( $a == $b ) + return 0; + + if ( 'DESC' == $order ) + return ( $a < $b ) ? 1 : -1; + else + return ( $a < $b ) ? -1 : 1; + } + + function no_items() { + global $themes; + + if ( !empty( $themes['all'] ) ) + _e( 'No themes found.' ); + else + _e( 'You do not appear to have any themes available at this time.' ); + } + + function get_columns() { + global $status; + + return array( + 'cb' => '', + 'name' => __( 'Theme' ), + 'description' => __( 'Description' ), + ); + } + + function get_sortable_columns() { + return array( + 'name' => 'name', + ); + } + + function get_views() { + global $totals, $status; + + $status_links = array(); + foreach ( $totals as $type => $count ) { + if ( !$count ) + continue; + + switch ( $type ) { + case 'all': + $text = _nx( 'All (%s)', 'All (%s)', $count, 'themes' ); + break; + case 'enabled': + $text = _n( 'Enabled (%s)', 'Enabled (%s)', $count ); + break; + case 'disabled': + $text = _n( 'Disabled (%s)', 'Disabled (%s)', $count ); + break; + case 'upgrade': + $text = _n( 'Update Available (%s)', 'Update Available (%s)', $count ); + break; + } + + if ( $this->is_site_themes ) + $url = 'site-themes.php?id=' . $this->site_id; + else + $url = 'themes.php'; + + if ( 'search' != $type ) { + $status_links[$type] = sprintf( "%s", + esc_url( add_query_arg('theme_status', $type, $url) ), + ( $type == $status ) ? ' class="current"' : '', + sprintf( $text, number_format_i18n( $count ) ) + ); + } + } + + return $status_links; + } + + function get_bulk_actions() { + global $status; + + $actions = array(); + if ( 'enabled' != $status ) + $actions['enable-selected'] = $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ); + if ( 'disabled' != $status ) + $actions['disable-selected'] = $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ); + if ( ! $this->is_site_themes ) { + if ( current_user_can( 'delete_themes' ) ) + $actions['delete-selected'] = __( 'Delete' ); + if ( current_user_can( 'update_themes' ) ) + $actions['update-selected'] = __( 'Update' ); + } + return $actions; + } + + function bulk_actions( $which ) { + global $status; + parent::bulk_actions( $which ); + } + + function current_action() { + return parent::current_action(); + } + + function display_rows() { + foreach ( $this->items as $key => $theme ) + $this->single_row( $key, $theme ); + } + + function single_row( $key, $theme ) { + global $status, $page, $s; + + $context = $status; + + if ( $this->is_site_themes ) + $url = "site-themes.php?id={$this->site_id}&"; + else + $url = 'themes.php?'; + + // preorder + $actions = array( + 'enable' => '', + 'disable' => '', + 'edit' => '', + 'delete' => '' + ); + + $theme_key = $theme['Stylesheet']; + + if ( empty( $theme['enabled'] ) ) + $actions['enable'] = '' . ( $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ) ) . ''; + else + $actions['disable'] = '' . ( $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ) ) . ''; + + if ( current_user_can('edit_themes') ) + $actions['edit'] = '' . __('Edit') . ''; + + if ( empty( $theme['enabled'] ) && current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $theme_key != get_option( 'stylesheet' ) && $theme_key != get_option( 'template' ) ) + $actions['delete'] = '' . __( 'Delete' ) . ''; + + $actions = apply_filters( 'theme_action_links', array_filter( $actions ), $theme_key, $theme, $context ); + $actions = apply_filters( "theme_action_links_$theme_key", $actions, $theme_key, $theme, $context ); + + $class = empty( $theme['enabled'] ) ? 'inactive' : 'active'; + $checkbox_id = "checkbox_" . md5($theme['Name']); + $checkbox = ""; + + $description = '

' . $theme['Description'] . '

'; + $theme_name = $theme['Name']; + + $id = sanitize_title( $theme_name ); + + echo ""; + + list( $columns, $hidden ) = $this->get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + switch ( $column_name ) { + case 'cb': + echo ""; + break; + case 'name': + echo ""; + break; + case 'description': + echo ""; + break; + + default: + echo ""; + } + } + + echo ""; + + if ( $this->is_site_themes ) + remove_action( "after_theme_row_$theme_key", 'wp_theme_update_row' ); + do_action( 'after_theme_row', $theme_key, $theme, $status ); + do_action( "after_theme_row_$theme_key", $theme_key, $theme, $status ); + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-ms-users-list-table.php b/src/wp-admin/includes/class-wp-ms-users-list-table.php new file mode 100644 index 00000000..36d55e1c --- /dev/null +++ b/src/wp-admin/includes/class-wp-ms-users-list-table.php @@ -0,0 +1,276 @@ +get_items_per_page( 'users_network_per_page' ); + + $role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : ''; + + $paged = $this->get_pagenum(); + + $args = array( + 'number' => $users_per_page, + 'offset' => ( $paged-1 ) * $users_per_page, + 'search' => $usersearch, + 'blog_id' => 0, + 'fields' => 'all_with_meta' + ); + + $args['search'] = ltrim($args['search'], '*'); + + if ( $role == 'super' ) { + $logins = implode( "', '", get_super_admins() ); + $args['include'] = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_login IN ('$logins')" ); + } + + // If the network is large and a search is not being performed, show only the latest users with no paging in order + // to avoid expensive count queries. + if ( !$usersearch && ( get_blog_count() >= 10000 ) ) { + if ( !isset($_REQUEST['orderby']) ) + $_GET['orderby'] = $_REQUEST['orderby'] = 'id'; + if ( !isset($_REQUEST['order']) ) + $_GET['order'] = $_REQUEST['order'] = 'DESC'; + $args['count_total'] = false; + } + + if ( isset( $_REQUEST['orderby'] ) ) + $args['orderby'] = $_REQUEST['orderby']; + + if ( isset( $_REQUEST['order'] ) ) + $args['order'] = $_REQUEST['order']; + + $mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode']; + + // Query the user IDs for this page + $wp_user_search = new WP_User_Query( $args ); + + $this->items = $wp_user_search->get_results(); + + $this->set_pagination_args( array( + 'total_items' => $wp_user_search->get_total(), + 'per_page' => $users_per_page, + ) ); + } + + function get_bulk_actions() { + $actions = array(); + if ( current_user_can( 'delete_users' ) ) + $actions['delete'] = __( 'Delete' ); + $actions['spam'] = _x( 'Mark as Spam', 'user' ); + $actions['notspam'] = _x( 'Not Spam', 'user' ); + + return $actions; + } + + function no_items() { + _e( 'No users found.' ); + } + + function get_views() { + global $wp_roles, $role; + + $total_users = get_user_count(); + $super_admins = get_super_admins(); + $total_admins = count( $super_admins ); + + $current_role = false; + $class = $role != 'super' ? ' class="current"' : ''; + $role_links = array(); + $role_links['all'] = "" . sprintf( _nx( 'All (%s)', 'All (%s)', $total_users, 'users' ), number_format_i18n( $total_users ) ) . ''; + $class = $role == 'super' ? ' class="current"' : ''; + $role_links['super'] = "" . sprintf( _n( 'Super Admin (%s)', 'Super Admins (%s)', $total_admins ), number_format_i18n( $total_admins ) ) . ''; + + return $role_links; + } + + function pagination( $which ) { + global $mode; + + parent::pagination ( $which ); + + if ( 'top' == $which ) + $this->view_switcher( $mode ); + } + + function get_columns() { + $users_columns = array( + 'cb' => '', + 'username' => __( 'Username' ), + 'name' => __( 'Name' ), + 'email' => __( 'E-mail' ), + 'registered' => _x( 'Registered', 'user' ), + 'blogs' => __( 'Sites' ) + ); + $users_columns = apply_filters( 'wpmu_users_columns', $users_columns ); + + return $users_columns; + } + + function get_sortable_columns() { + return array( + 'username' => 'login', + 'name' => 'name', + 'email' => 'email', + 'registered' => 'id', + ); + } + + function display_rows() { + global $current_site, $mode; + + $alt = ''; + $super_admins = get_super_admins(); + foreach ( $this->items as $user ) { + $alt = ( 'alternate' == $alt ) ? '' : 'alternate'; + + $status_list = array( 'spam' => 'site-spammed', 'deleted' => 'site-deleted' ); + + foreach ( $status_list as $status => $col ) { + if ( $user->$status ) + $alt .= " $col"; + } + + ?> + + get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) : + $class = "class='$column_name column-$column_name'"; + + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + $attributes = "$class$style"; + + + switch ( $column_name ) { + case 'cb': ?> + + user_email, 32 ); + if ( get_current_user_id() == $user->ID ) { + $edit_link = esc_url( network_admin_url( 'profile.php' ) ); + } else { + $edit_link = esc_url( network_admin_url( add_query_arg( 'wp_http_referer', urlencode( stripslashes( $_SERVER['REQUEST_URI'] ) ), 'user-edit.php?user_id=' . $user->ID ) ) ); + } + + echo " + $user->first_name $user->last_name"; + break; + + case 'email': + echo ""; + break; + + case 'registered': + if ( 'list' == $mode ) + $date = 'Y/m/d'; + else + $date = 'Y/m/d \<\b\r \/\> g:i:s a'; + + echo ""; + break; + + case 'blogs': + $blogs = get_blogs_of_user( $user->ID, true ); + echo " + "; + echo apply_filters( 'manage_users_custom_column', '', $column_name, $user->ID ); + echo ""; + break; + } + endforeach + ?> + + diff --git a/src/wp-admin/includes/class-wp-plugin-install-list-table.php b/src/wp-admin/includes/class-wp-plugin-install-list-table.php new file mode 100644 index 00000000..4893ae66 --- /dev/null +++ b/src/wp-admin/includes/class-wp-plugin-install-list-table.php @@ -0,0 +1,237 @@ +get_pagenum(); + + $per_page = 30; + + // These are the tabs which are shown on the page + $tabs = array(); + $tabs['dashboard'] = __( 'Search' ); + if ( 'search' == $tab ) + $tabs['search'] = __( 'Search Results' ); + $tabs['upload'] = __( 'Upload' ); + $tabs['featured'] = _x( 'Featured','Plugin Installer' ); + $tabs['popular'] = _x( 'Popular','Plugin Installer' ); + $tabs['new'] = _x( 'Newest','Plugin Installer' ); + $tabs['updated'] = _x( 'Recently Updated','Plugin Installer' ); + + $nonmenu_tabs = array( 'plugin-information' ); //Valid actions to perform which do not have a Menu item. + + $tabs = apply_filters( 'install_plugins_tabs', $tabs ); + $nonmenu_tabs = apply_filters( 'install_plugins_nonmenu_tabs', $nonmenu_tabs ); + + // If a non-valid menu tab has been selected, And its not a non-menu action. + if ( empty( $tab ) || ( !isset( $tabs[ $tab ] ) && !in_array( $tab, (array) $nonmenu_tabs ) ) ) + $tab = key( $tabs ); + + $args = array( 'page' => $paged, 'per_page' => $per_page ); + + switch ( $tab ) { + case 'search': + $type = isset( $_REQUEST['type'] ) ? stripslashes( $_REQUEST['type'] ) : ''; + $term = isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : ''; + + switch ( $type ) { + case 'tag': + $args['tag'] = sanitize_title_with_dashes( $term ); + break; + case 'term': + $args['search'] = $term; + break; + case 'author': + $args['author'] = $term; + break; + } + + add_action( 'install_plugins_table_header', 'install_search_form' ); + break; + + case 'featured': + case 'popular': + case 'new': + case 'updated': + $args['browse'] = $tab; + break; + + default: + $args = false; + } + + if ( !$args ) + return; + + $api = plugins_api( 'query_plugins', $args ); + + if ( is_wp_error( $api ) ) + wp_die( $api->get_error_message() . '

' . __( 'Try again' ) . '' ); + + $this->items = $api->plugins; + + $this->set_pagination_args( array( + 'total_items' => $api->info['results'], + 'per_page' => $per_page, + ) ); + } + + function no_items() { + _e( 'No plugins match your request.' ); + } + + function get_views() { + global $tabs, $tab; + + $display_tabs = array(); + foreach ( (array) $tabs as $action => $text ) { + $class = ( $action == $tab ) ? ' class="current"' : ''; + $href = self_admin_url('plugin-install.php?tab=' . $action); + $display_tabs['plugin-install-'.$action] = "$text"; + } + + return $display_tabs; + } + + function display_tablenav( $which ) { + if ( 'top' == $which ) { ?> +

+
+ +
+ pagination( $which ); ?> + +
+
+ +
+ pagination( $which ); ?> + +
+
+ _args ); + + return array( 'widefat', $plural ); + } + + function get_columns() { + return array( + 'name' => __( 'Name' ), + 'version' => __( 'Version' ), + 'rating' => __( 'Rating' ), + 'description' => __( 'Description' ), + ); + } + + function display_rows() { + $plugins_allowedtags = array( + 'a' => array( 'href' => array(),'title' => array(), 'target' => array() ), + 'abbr' => array( 'title' => array() ),'acronym' => array( 'title' => array() ), + 'code' => array(), 'pre' => array(), 'em' => array(),'strong' => array(), + 'ul' => array(), 'ol' => array(), 'li' => array(), 'p' => array(), 'br' => array() + ); + + list( $columns, $hidden ) = $this->get_column_info(); + + $style = array(); + foreach ( $columns as $column_name => $column_display_name ) { + $style[ $column_name ] = in_array( $column_name, $hidden ) ? 'style="display:none;"' : ''; + } + + foreach ( (array) $this->items as $plugin ) { + if ( is_object( $plugin ) ) + $plugin = (array) $plugin; + + $title = wp_kses( $plugin['name'], $plugins_allowedtags ); + //Limit description to 400char, and remove any HTML. + $description = strip_tags( $plugin['description'] ); + if ( strlen( $description ) > 400 ) + $description = mb_substr( $description, 0, 400 ) . '…'; + //remove any trailing entities + $description = preg_replace( '/&[^;\s]{0,6}$/', '', $description ); + //strip leading/trailing & multiple consecutive lines + $description = trim( $description ); + $description = preg_replace( "|(\r?\n)+|", "\n", $description ); + //\n =>
+ $description = nl2br( $description ); + $version = wp_kses( $plugin['version'], $plugins_allowedtags ); + + $name = strip_tags( $title . ' ' . $version ); + + $author = $plugin['author']; + if ( ! empty( $plugin['author'] ) ) + $author = ' ' . sprintf( __( 'By %s' ), $author ) . '.'; + + $author = wp_kses( $author, $plugins_allowedtags ); + + $action_links = array(); + $action_links[] = '' . __( 'Details' ) . ''; + + if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) { + $status = install_plugin_install_status( $plugin ); + + switch ( $status['status'] ) { + case 'install': + if ( $status['url'] ) + $action_links[] = '' . __( 'Install Now' ) . ''; + break; + case 'update_available': + if ( $status['url'] ) + $action_links[] = '' . sprintf( __( 'Update Now' ), $status['version'] ) . ''; + break; + case 'latest_installed': + case 'newer_installed': + $action_links[] = '' . __( 'Installed' ) . ''; + break; + } + } + + $action_links = apply_filters( 'plugin_install_action_links', $action_links, $plugin ); + ?> + + + + + + + diff --git a/src/wp-admin/includes/class-wp-plugins-list-table.php b/src/wp-admin/includes/class-wp-plugins-list-table.php new file mode 100644 index 00000000..b5ad6d48 --- /dev/null +++ b/src/wp-admin/includes/class-wp-plugins-list-table.php @@ -0,0 +1,454 @@ +get_pagenum(); + + parent::WP_List_Table( array( + 'plural' => 'plugins', + ) ); + } + + function get_table_classes() { + return array( 'widefat', $this->_args['plural'] ); + } + + function ajax_user_can() { + if ( is_multisite() ) { + $menu_perms = get_site_option( 'menu_items', array() ); + + if ( empty( $menu_perms['plugins'] ) && ! is_super_admin() ) + return false; + } + + return current_user_can('activate_plugins'); + } + + function prepare_items() { + global $status, $plugins, $totals, $page, $orderby, $order, $s; + + wp_reset_vars( array( 'orderby', 'order', 's' ) ); + + $plugins = array( + 'all' => apply_filters( 'all_plugins', get_plugins() ), + 'search' => array(), + 'active' => array(), + 'inactive' => array(), + 'recently_activated' => array(), + 'upgrade' => array(), + 'mustuse' => array(), + 'dropins' => array() + ); + + $screen = get_current_screen(); + + if ( ! is_multisite() || ( $screen->is_network && current_user_can('manage_network_plugins') ) ) { + if ( apply_filters( 'show_advanced_plugins', true, 'mustuse' ) ) + $plugins['mustuse'] = get_mu_plugins(); + if ( apply_filters( 'show_advanced_plugins', true, 'dropins' ) ) + $plugins['dropins'] = get_dropins(); + + $current = get_site_transient( 'update_plugins' ); + foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) { + if ( isset( $current->response[ $plugin_file ] ) ) + $plugins['upgrade'][ $plugin_file ] = $plugin_data; + } + } + + set_transient( 'plugin_slugs', array_keys( $plugins['all'] ), 86400 ); + + $recently_activated = get_option( 'recently_activated', array() ); + + $one_week = 7*24*60*60; + foreach ( $recently_activated as $key => $time ) + if ( $time + $one_week < time() ) + unset( $recently_activated[$key] ); + update_option( 'recently_activated', $recently_activated ); + + foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) { + // Filter into individual sections + if ( is_multisite() && is_network_only_plugin( $plugin_file ) && !$screen->is_network ) { + unset( $plugins['all'][ $plugin_file] ); + } elseif ( is_plugin_active_for_network($plugin_file) && !$screen->is_network ) { + unset( $plugins['all'][ $plugin_file ] ); + } elseif ( is_multisite() && is_network_only_plugin( $plugin_file ) && !current_user_can( 'manage_network_plugins' ) ) { + $plugins['network'][ $plugin_file ] = $plugin_data; + } elseif ( ( !$screen->is_network && is_plugin_active( $plugin_file ) ) + || ( $screen->is_network && is_plugin_active_for_network( $plugin_file ) ) ) { + $plugins['active'][ $plugin_file ] = $plugin_data; + } else { + if ( !$screen->is_network && isset( $recently_activated[ $plugin_file ] ) ) // Was the plugin recently activated? + $plugins['recently_activated'][ $plugin_file ] = $plugin_data; + $plugins['inactive'][ $plugin_file ] = $plugin_data; + } + } + + if ( !current_user_can( 'update_plugins' ) ) + $plugins['upgrade'] = array(); + + if ( $s ) { + $status = 'search'; + $plugins['search'] = array_filter( $plugins['all'], array( &$this, '_search_callback' ) ); + } + + $totals = array(); + foreach ( $plugins as $type => $list ) + $totals[ $type ] = count( $list ); + + if ( empty( $plugins[ $status ] ) && !in_array( $status, array( 'all', 'search' ) ) ) + $status = 'all'; + + $this->items = array(); + foreach ( $plugins[ $status ] as $plugin_file => $plugin_data ) { + // Translate, Don't Apply Markup, Sanitize HTML + $this->items[$plugin_file] = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, false, true ); + } + + $total_this_page = $totals[ $status ]; + + if ( $orderby ) { + $orderby = ucfirst( $orderby ); + $order = strtoupper( $order ); + + uasort( $this->items, array( &$this, '_order_callback' ) ); + } + + $plugins_per_page = $this->get_items_per_page( str_replace( '-', '_', $screen->id . '_per_page' ) ); + + $start = ( $page - 1 ) * $plugins_per_page; + + if ( $total_this_page > $plugins_per_page ) + $this->items = array_slice( $this->items, $start, $plugins_per_page ); + + $this->set_pagination_args( array( + 'total_items' => $total_this_page, + 'per_page' => $plugins_per_page, + ) ); + } + + function _search_callback( $plugin ) { + static $term; + if ( is_null( $term ) ) + $term = stripslashes( $_REQUEST['s'] ); + + foreach ( $plugin as $value ) + if ( stripos( $value, $term ) !== false ) + return true; + + return false; + } + + function _order_callback( $plugin_a, $plugin_b ) { + global $orderby, $order; + + $a = $plugin_a[$orderby]; + $b = $plugin_b[$orderby]; + + if ( $a == $b ) + return 0; + + if ( 'DESC' == $order ) + return ( $a < $b ) ? 1 : -1; + else + return ( $a < $b ) ? -1 : 1; + } + + function no_items() { + global $plugins; + + if ( !empty( $plugins['all'] ) ) + _e( 'No plugins found.' ); + else + _e( 'You do not appear to have any plugins available at this time.' ); + } + + function get_columns() { + global $status; + + return array( + 'cb' => !in_array( $status, array( 'mustuse', 'dropins' ) ) ? '' : '', + 'name' => __( 'Plugin' ), + 'description' => __( 'Description' ), + ); + } + + function get_sortable_columns() { + return array(); + } + + function get_views() { + global $totals, $status; + + $status_links = array(); + foreach ( $totals as $type => $count ) { + if ( !$count ) + continue; + + switch ( $type ) { + case 'all': + $text = _nx( 'All (%s)', 'All (%s)', $count, 'plugins' ); + break; + case 'active': + $text = _n( 'Active (%s)', 'Active (%s)', $count ); + break; + case 'recently_activated': + $text = _n( 'Recently Active (%s)', 'Recently Active (%s)', $count ); + break; + case 'inactive': + $text = _n( 'Inactive (%s)', 'Inactive (%s)', $count ); + break; + case 'network': + $text = _n( 'Network (%s)', 'Network (%s)', $count ); + break; + case 'mustuse': + $text = _n( 'Must-Use (%s)', 'Must-Use (%s)', $count ); + break; + case 'dropins': + $text = _n( 'Drop-ins (%s)', 'Drop-ins (%s)', $count ); + break; + case 'upgrade': + $text = _n( 'Update Available (%s)', 'Update Available (%s)', $count ); + break; + } + + if ( 'search' != $type ) { + $status_links[$type] = sprintf( "%s", + add_query_arg('plugin_status', $type, 'plugins.php'), + ( $type == $status ) ? ' class="current"' : '', + sprintf( $text, number_format_i18n( $count ) ) + ); + } + } + + return $status_links; + } + + function get_bulk_actions() { + global $status; + + $actions = array(); + + $screen = get_current_screen(); + + if ( 'active' != $status ) { + $action = $screen->is_network ? 'network-activate-selected' : 'activate-selected'; + $actions[ $action ] = __( 'Activate' ); + } + + if ( 'inactive' != $status && 'recent' != $status ) + $actions['deactivate-selected'] = __( 'Deactivate' ); + + if ( !is_multisite() || $screen->is_network ) { + if ( current_user_can( 'update_plugins' ) ) + $actions['update-selected'] = __( 'Update' ); + if ( current_user_can( 'delete_plugins' ) && ( 'active' != $status ) ) + $actions['delete-selected'] = __( 'Delete' ); + } + + return $actions; + } + + function bulk_actions( $which ) { + global $status; + + if ( in_array( $status, array( 'mustuse', 'dropins' ) ) ) + return; + + parent::bulk_actions( $which ); + } + + function extra_tablenav( $which ) { + global $status; + + if ( ! in_array($status, array('recently_activated', 'mustuse', 'dropins') ) ) + return; + + echo '
'; + + if ( 'recently_activated' == $status ) + submit_button( __( 'Clear List' ), 'secondary', 'clear-recent-list', false ); + elseif ( 'top' == $which && 'mustuse' == $status ) + echo '

' . __( 'Files in the /wp-content/mu-plugins directory are executed automatically.' ) . '

'; + elseif ( 'top' == $which && 'dropins' == $status ) + echo '

' . __( 'Drop-ins are advanced plugins in the /wp-content directory that replace WordPress functionality when present.' ) . '

'; + + echo '
'; + } + + function current_action() { + if ( isset($_POST['clear-recent-list']) ) + return 'clear-recent-list'; + + return parent::current_action(); + } + + function display_rows() { + global $status; + + $screen = get_current_screen(); + + if ( is_multisite() && !$screen->is_network && in_array( $status, array( 'mustuse', 'dropins' ) ) ) + return; + + foreach ( $this->items as $plugin_file => $plugin_data ) + $this->single_row( $plugin_file, $plugin_data ); + } + + function single_row( $plugin_file, $plugin_data ) { + global $status, $page, $s; + + $context = $status; + + $screen = get_current_screen(); + + // preorder + $actions = array( + 'network_deactivate' => '', 'deactivate' => '', + 'network_only' => '', 'activate' => '', + 'network_activate' => '', + 'edit' => '', + 'delete' => '', + ); + + if ( 'mustuse' == $context ) { + $is_active = true; + } elseif ( 'dropins' == $context ) { + $dropins = _get_dropins(); + $plugin_name = $plugin_file; + if ( $plugin_file != $plugin_data['Name'] ) + $plugin_name .= '
' . $plugin_data['Name']; + if ( true === ( $dropins[ $plugin_file ][1] ) ) { // Doesn't require a constant + $is_active = true; + $description = '

' . $dropins[ $plugin_file ][0] . '

'; + } elseif ( constant( $dropins[ $plugin_file ][1] ) ) { // Constant is true + $is_active = true; + $description = '

' . $dropins[ $plugin_file ][0] . '

'; + } else { + $is_active = false; + $description = '

' . $dropins[ $plugin_file ][0] . ' ' . __('Inactive:') . ' ' . sprintf( __( 'Requires %s in wp-config.php.' ), "define('" . $dropins[ $plugin_file ][1] . "', true);" ) . '

'; + } + if ( $plugin_data['Description'] ) + $description .= '

' . $plugin_data['Description'] . '

'; + } else { + $is_active_for_network = is_plugin_active_for_network($plugin_file); + if ( $screen->is_network ) + $is_active = $is_active_for_network; + else + $is_active = is_plugin_active( $plugin_file ); + + if ( $is_active_for_network && !is_super_admin() && !$screen->is_network ) + return; + + if ( $screen->is_network ) { + if ( $is_active_for_network ) { + if ( current_user_can( 'manage_network_plugins' ) ) + $actions['network_deactivate'] = '' . __('Network Deactivate') . ''; + } else { + if ( current_user_can( 'manage_network_plugins' ) ) + $actions['network_activate'] = '' . __('Network Activate') . ''; + if ( current_user_can( 'delete_plugins' ) && ! is_plugin_active( $plugin_file ) ) + $actions['delete'] = '' . __('Delete') . ''; + } + } else { + if ( $is_active ) { + $actions['deactivate'] = '' . __('Deactivate') . ''; + } else { + $actions['activate'] = '' . __('Activate') . ''; + + if ( ! is_multisite() && current_user_can('delete_plugins') ) + $actions['delete'] = '' . __('Delete') . ''; + } // end if $is_active + } // end if $screen->is_network + + if ( ( ! is_multisite() || $screen->is_network ) && current_user_can('edit_plugins') && is_writable(WP_PLUGIN_DIR . '/' . $plugin_file) ) + $actions['edit'] = '' . __('Edit') . ''; + } // end if $context + + $prefix = $screen->is_network ? 'network_admin_' : ''; + $actions = apply_filters( $prefix . 'plugin_action_links', array_filter( $actions ), $plugin_file, $plugin_data, $context ); + $actions = apply_filters( $prefix . "plugin_action_links_$plugin_file", $actions, $plugin_file, $plugin_data, $context ); + + $class = $is_active ? 'active' : 'inactive'; + $checkbox_id = "checkbox_" . md5($plugin_data['Name']); + $checkbox = in_array( $status, array( 'mustuse', 'dropins' ) ) ? '' : ""; + if ( 'dropins' != $context ) { + $description = '

' . ( $plugin_data['Description'] ? $plugin_data['Description'] : ' ' ) . '

'; + $plugin_name = $plugin_data['Name']; + } + + $id = sanitize_title( $plugin_name ); + + echo ""; + + list( $columns, $hidden ) = $this->get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + switch ( $column_name ) { + case 'cb': + echo ""; + break; + case 'name': + echo ""; + break; + case 'description': + echo ""; + break; + default: + echo ""; + } + } + + echo ""; + + do_action( 'after_plugin_row', $plugin_file, $plugin_data, $status ); + do_action( "after_plugin_row_$plugin_file", $plugin_file, $plugin_data, $status ); + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-posts-list-table.php b/src/wp-admin/includes/class-wp-posts-list-table.php new file mode 100644 index 00000000..c1b4c344 --- /dev/null +++ b/src/wp-admin/includes/class-wp-posts-list-table.php @@ -0,0 +1,1018 @@ + true ) ) ) ) + $post_type = $_REQUEST['post_type']; + else + wp_die( __( 'Invalid post type' ) ); + $_REQUEST['post_type'] = $post_type; + + $post_type_object = get_post_type_object( $post_type ); + + if ( !current_user_can( $post_type_object->cap->edit_others_posts ) ) { + $this->user_posts_count = $wpdb->get_var( $wpdb->prepare( " + SELECT COUNT( 1 ) FROM $wpdb->posts + WHERE post_type = %s AND post_status NOT IN ( 'trash', 'auto-draft' ) + AND post_author = %d + ", $post_type, get_current_user_id() ) ); + + if ( $this->user_posts_count && empty( $_REQUEST['post_status'] ) && empty( $_REQUEST['all_posts'] ) && empty( $_REQUEST['author'] ) && empty( $_REQUEST['show_sticky'] ) ) + $_GET['author'] = get_current_user_id(); + } + + if ( 'post' == $post_type && $sticky_posts = get_option( 'sticky_posts' ) ) { + $sticky_posts = implode( ', ', array_map( 'absint', (array) $sticky_posts ) ); + $this->sticky_posts_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( 1 ) FROM $wpdb->posts WHERE post_type = %s AND post_status != 'trash' AND ID IN ($sticky_posts)", $post_type ) ); + } + + parent::WP_List_Table( array( + 'plural' => 'posts', + ) ); + } + + function ajax_user_can() { + global $post_type_object; + + return current_user_can( $post_type_object->cap->edit_posts ); + } + + function prepare_items() { + global $post_type_object, $post_type, $avail_post_stati, $wp_query, $per_page, $mode; + + $avail_post_stati = wp_edit_posts_query(); + + $this->hierarchical_display = ( $post_type_object->hierarchical && 'menu_order title' == $wp_query->query['orderby'] ); + + $total_items = $this->hierarchical_display ? $wp_query->post_count : $wp_query->found_posts; + + $per_page = $this->get_items_per_page( 'edit_' . $post_type . '_per_page' ); + $per_page = apply_filters( 'edit_posts_per_page', $per_page, $post_type ); + + if ( $this->hierarchical_display ) + $total_pages = ceil( $total_items / $per_page ); + else + $total_pages = $wp_query->max_num_pages; + + $mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode']; + + $this->is_trash = isset( $_REQUEST['post_status'] ) && $_REQUEST['post_status'] == 'trash'; + + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'total_pages' => $total_pages, + 'per_page' => $per_page + ) ); + } + + function has_items() { + return have_posts(); + } + + function no_items() { + global $post_type_object; + + if ( isset( $_REQUEST['post_status'] ) && 'trash' == $_REQUEST['post_status'] ) + echo $post_type_object->labels->not_found_in_trash; + else + echo $post_type_object->labels->not_found; + } + + function get_views() { + global $post_type, $post_type_object, $locked_post_status, $avail_post_stati; + + if ( !empty($locked_post_status) ) + return array(); + + $status_links = array(); + $num_posts = wp_count_posts( $post_type, 'readable' ); + $class = ''; + $allposts = ''; + + $current_user_id = get_current_user_id(); + + if ( $this->user_posts_count ) { + if ( isset( $_GET['author'] ) && ( $_GET['author'] == $current_user_id ) ) + $class = ' class="current"'; + $status_links['mine'] = "" . sprintf( _nx( 'Mine (%s)', 'Mine (%s)', $this->user_posts_count, 'posts' ), number_format_i18n( $this->user_posts_count ) ) . ''; + $allposts = '&all_posts=1'; + } + + $total_posts = array_sum( (array) $num_posts ); + + // Subtract post types that are not included in the admin all list. + foreach ( get_post_stati( array('show_in_admin_all_list' => false) ) as $state ) + $total_posts -= $num_posts->$state; + + $class = empty( $class ) && empty( $_REQUEST['post_status'] ) && empty( $_REQUEST['show_sticky'] ) ? ' class="current"' : ''; + $status_links['all'] = "" . sprintf( _nx( 'All (%s)', 'All (%s)', $total_posts, 'posts' ), number_format_i18n( $total_posts ) ) . ''; + + foreach ( get_post_stati(array('show_in_admin_status_list' => true), 'objects') as $status ) { + $class = ''; + + $status_name = $status->name; + + if ( !in_array( $status_name, $avail_post_stati ) ) + continue; + + if ( empty( $num_posts->$status_name ) ) + continue; + + if ( isset($_REQUEST['post_status']) && $status_name == $_REQUEST['post_status'] ) + $class = ' class="current"'; + + $status_links[$status_name] = "" . sprintf( translate_nooped_plural( $status->label_count, $num_posts->$status_name ), number_format_i18n( $num_posts->$status_name ) ) . ''; + } + + if ( ! empty( $this->sticky_posts_count ) ) { + $class = ! empty( $_REQUEST['show_sticky'] ) ? ' class="current"' : ''; + + $sticky_link = array( 'sticky' => "" . sprintf( _nx( 'Sticky (%s)', 'Sticky (%s)', $this->sticky_posts_count, 'posts' ), number_format_i18n( $this->sticky_posts_count ) ) . '' ); + + // Sticky comes after Publish, or if not listed, after All. + $split = 1 + array_search( ( isset( $status_links['publish'] ) ? 'publish' : 'all' ), array_keys( $status_links ) ); + $status_links = array_merge( array_slice( $status_links, 0, $split ), $sticky_link, array_slice( $status_links, $split ) ); + } + + return $status_links; + } + + function get_bulk_actions() { + $actions = array(); + + if ( $this->is_trash ) + $actions['untrash'] = __( 'Restore' ); + else + $actions['edit'] = __( 'Edit' ); + + if ( $this->is_trash || !EMPTY_TRASH_DAYS ) + $actions['delete'] = __( 'Delete Permanently' ); + else + $actions['trash'] = __( 'Move to Trash' ); + + return $actions; + } + + function extra_tablenav( $which ) { + global $post_type, $post_type_object, $cat; +?> +
+months_dropdown( $post_type ); + + if ( is_object_in_taxonomy( $post_type, 'category' ) ) { + $dropdown_options = array( + 'show_option_all' => __( 'View all categories' ), + 'hide_empty' => 0, + 'hierarchical' => 1, + 'show_count' => 0, + 'orderby' => 'name', + 'selected' => $cat + ); + wp_dropdown_categories( $dropdown_options ); + } + do_action( 'restrict_manage_posts' ); + submit_button( __( 'Filter' ), 'secondary', false, false, array( 'id' => 'post-query-submit' ) ); + } + + if ( $this->is_trash && current_user_can( $post_type_object->cap->edit_others_posts ) ) { + submit_button( __( 'Empty Trash' ), 'button-secondary apply', 'delete_all', false ); + } +?> +
+hierarchical ) + $this->view_switcher( $mode ); + } + + function get_table_classes() { + global $post_type_object; + + return array( 'widefat', 'fixed', $post_type_object->hierarchical ? 'pages' : 'posts' ); + } + + function get_columns() { + $screen = get_current_screen(); + + if ( empty( $screen ) ) + $post_type = 'post'; + else + $post_type = $screen->post_type; + + $posts_columns = array(); + + $posts_columns['cb'] = ''; + + /* translators: manage posts column name */ + $posts_columns['title'] = _x( 'Title', 'column name' ); + + if ( post_type_supports( $post_type, 'author' ) ) + $posts_columns['author'] = __( 'Author' ); + + if ( empty( $post_type ) || is_object_in_taxonomy( $post_type, 'category' ) ) + $posts_columns['categories'] = __( 'Categories' ); + + if ( empty( $post_type ) || is_object_in_taxonomy( $post_type, 'post_tag' ) ) + $posts_columns['tags'] = __( 'Tags' ); + + $post_status = !empty( $_REQUEST['post_status'] ) ? $_REQUEST['post_status'] : 'all'; + if ( post_type_supports( $post_type, 'comments' ) && !in_array( $post_status, array( 'pending', 'draft', 'future' ) ) ) + $posts_columns['comments'] = '
' . esc_attr__( 'Comments' ) . '
'; + + $posts_columns['date'] = __( 'Date' ); + + if ( 'page' == $post_type ) + $posts_columns = apply_filters( 'manage_pages_columns', $posts_columns ); + else + $posts_columns = apply_filters( 'manage_posts_columns', $posts_columns, $post_type ); + $posts_columns = apply_filters( "manage_{$post_type}_posts_columns", $posts_columns ); + + return $posts_columns; + } + + function get_sortable_columns() { + return array( + 'title' => 'title', + 'author' => 'author', + 'parent' => 'parent', + 'comments' => 'comment_count', + 'date' => array( 'date', true ) + ); + } + + function display_rows( $posts = array() ) { + global $wp_query, $post_type_object, $per_page; + + if ( empty( $posts ) ) + $posts = $wp_query->posts; + + add_filter( 'the_title', 'esc_html' ); + + if ( $this->hierarchical_display ) { + $this->_display_rows_hierarchical( $posts, $this->get_pagenum(), $per_page ); + } else { + $this->_display_rows( $posts ); + } + } + + function _display_rows( $posts ) { + global $post, $mode; + + // Create array of post IDs. + $post_ids = array(); + + foreach ( $posts as $a_post ) + $post_ids[] = $a_post->ID; + + $this->comment_pending_count = get_pending_comments_num( $post_ids ); + + foreach ( $posts as $post ) + $this->single_row( $post ); + } + + function _display_rows_hierarchical( $pages, $pagenum = 1, $per_page = 20 ) { + global $wpdb; + + $level = 0; + + if ( ! $pages ) { + $pages = get_pages( array( 'sort_column' => 'menu_order' ) ); + + if ( ! $pages ) + return false; + } + + /* + * arrange pages into two parts: top level pages and children_pages + * children_pages is two dimensional array, eg. + * children_pages[10][] contains all sub-pages whose parent is 10. + * It only takes O( N ) to arrange this and it takes O( 1 ) for subsequent lookup operations + * If searching, ignore hierarchy and treat everything as top level + */ + if ( empty( $_REQUEST['s'] ) ) { + + $top_level_pages = array(); + $children_pages = array(); + + foreach ( $pages as $page ) { + + // catch and repair bad pages + if ( $page->post_parent == $page->ID ) { + $page->post_parent = 0; + $wpdb->update( $wpdb->posts, array( 'post_parent' => 0 ), array( 'ID' => $page->ID ) ); + clean_page_cache( $page->ID ); + } + + if ( 0 == $page->post_parent ) + $top_level_pages[] = $page; + else + $children_pages[ $page->post_parent ][] = $page; + } + + $pages = &$top_level_pages; + } + + $count = 0; + $start = ( $pagenum - 1 ) * $per_page; + $end = $start + $per_page; + + foreach ( $pages as $page ) { + if ( $count >= $end ) + break; + + if ( $count >= $start ) + echo "\t" . $this->single_row( $page, $level ); + + $count++; + + if ( isset( $children_pages ) ) + $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page ); + } + + // if it is the last pagenum and there are orphaned pages, display them with paging as well + if ( isset( $children_pages ) && $count < $end ){ + foreach ( $children_pages as $orphans ){ + foreach ( $orphans as $op ) { + if ( $count >= $end ) + break; + if ( $count >= $start ) + echo "\t" . $this->single_row( $op, 0 ); + $count++; + } + } + } + } + + /** + * Given a top level page ID, display the nested hierarchy of sub-pages + * together with paging support + * + * @since 3.1.0 (Standalone function exists since 2.6.0) + * + * @param unknown_type $children_pages + * @param unknown_type $count + * @param unknown_type $parent + * @param unknown_type $level + * @param unknown_type $pagenum + * @param unknown_type $per_page + */ + function _page_rows( &$children_pages, &$count, $parent, $level, $pagenum, $per_page ) { + + if ( ! isset( $children_pages[$parent] ) ) + return; + + $start = ( $pagenum - 1 ) * $per_page; + $end = $start + $per_page; + + foreach ( $children_pages[$parent] as $page ) { + + if ( $count >= $end ) + break; + + // If the page starts in a subtree, print the parents. + if ( $count == $start && $page->post_parent > 0 ) { + $my_parents = array(); + $my_parent = $page->post_parent; + while ( $my_parent ) { + $my_parent = get_post( $my_parent ); + $my_parents[] = $my_parent; + if ( !$my_parent->post_parent ) + break; + $my_parent = $my_parent->post_parent; + } + $num_parents = count( $my_parents ); + while ( $my_parent = array_pop( $my_parents ) ) { + echo "\t" . $this->single_row( $my_parent, $level - $num_parents ); + $num_parents--; + } + } + + if ( $count >= $start ) + echo "\t" . $this->single_row( $page, $level ); + + $count++; + + $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page ); + } + + unset( $children_pages[$parent] ); //required in order to keep track of orphans + } + + function single_row( $a_post, $level = 0 ) { + global $post, $current_screen, $mode; + static $rowclass; + + $global_post = $post; + $post = $a_post; + setup_postdata( $post ); + + $rowclass = 'alternate' == $rowclass ? '' : 'alternate'; + $post_owner = ( get_current_user_id() == $post->post_author ? 'self' : 'other' ); + $edit_link = get_edit_post_link( $post->ID ); + $title = _draft_or_post_title(); + $post_type_object = get_post_type_object( $post->post_type ); + $can_edit_post = current_user_can( $post_type_object->cap->edit_post, $post->ID ); + $post_format = get_post_format( $post->ID ); + $post_format_class = ( $post_format && !is_wp_error($post_format) ) ? 'format-' . sanitize_html_class( $post_format ) : 'format-default'; + ?> + post_status . ' ' . $post_format_class); ?> iedit' valign="top"> + get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $class = "class=\"$column_name column-$column_name\""; + + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + $attributes = "$class$style"; + + switch ( $column_name ) { + + case 'cb': + ?> + + hierarchical_display ) { + $attributes = 'class="post-title page-title column-title"' . $style; + + if ( 0 == $level && (int) $post->post_parent > 0 ) { + //sent level 0 by accident, by default, or because we don't know the actual level + $find_main_page = (int) $post->post_parent; + while ( $find_main_page > 0 ) { + $parent = get_page( $find_main_page ); + + if ( is_null( $parent ) ) + break; + + $level++; + $find_main_page = (int) $parent->post_parent; + + if ( !isset( $parent_name ) ) + $parent_name = apply_filters( 'the_title', $parent->post_title, $parent->ID ); + } + } + + $pad = str_repeat( '— ', $level ); +?> + '; + break; + + case 'date': + if ( '0000-00-00 00:00:00' == $post->post_date && 'date' == $column_name ) { + $t_time = $h_time = __( 'Unpublished' ); + $time_diff = 0; + } else { + $t_time = get_the_time( __( 'Y/m/d g:i:s A' ) ); + $m_time = $post->post_date; + $time = get_post_time( 'G', true, $post ); + + $time_diff = time() - $time; + + if ( $time_diff > 0 && $time_diff < 24*60*60 ) + $h_time = sprintf( __( '%s ago' ), human_time_diff( $time ) ); + else + $h_time = mysql2date( __( 'Y/m/d' ), $m_time ); + } + + echo ''; + break; + + case 'categories': + ?> + + + + + + + + + + + + post_type ); + $post_type_object = get_post_type_object( $screen->post_type ); + + $taxonomy_names = get_object_taxonomies( $screen->post_type ); + $hierarchical_taxonomies = array(); + $flat_taxonomies = array(); + foreach ( $taxonomy_names as $taxonomy_name ) { + $taxonomy = get_taxonomy( $taxonomy_name ); + + if ( !$taxonomy->show_ui ) + continue; + + if ( $taxonomy->hierarchical ) + $hierarchical_taxonomies[] = $taxonomy; + else + $flat_taxonomies[] = $taxonomy; + } + + $m = ( isset( $mode ) && 'excerpt' == $mode ) ? 'excerpt' : 'list'; + $can_publish = current_user_can( $post_type_object->cap->publish_posts ); + $core_columns = array( 'cb' => true, 'date' => true, 'title' => true, 'categories' => true, 'tags' => true, 'comments' => true, 'author' => true ); + + ?> + +
'; + $this->no_items(); + echo '
'; + echo $this->column_cb( $item ); + echo '"; + echo call_user_func( array( &$this, 'column_' . $column_name ), $item ); + echo ""; + echo $this->column_default( $item, $column_name ); + echo "
ID ) ) { ?>>ID, array( 80, 60 ), true ) ) { + if ( $this->is_trash ) { + echo $thumb; + } else { +?> + + + + + + >is_trash ) echo $att_title; else { ?> +

+ID ), $matches ) ) + echo esc_html( strtoupper( $matches[1] ) ); + else + echo strtoupper( str_replace( 'image/', '', get_post_mime_type() ) ); +?> +

+row_actions( $this->_get_row_actions( $post, $att_title ) ); +?> +
>>slug'> " . esc_html( sanitize_term_field( 'name', $c->name, $c->term_id, 'post_tag', 'display' ) ) . ""; + echo join( ', ', $out ); + } else { + _e( 'No Tags' ); + } +?> + >post_excerpt : ''; ?>>> + , + + >
+
> +
+ID ); + + $this->comments_bubble( $post->ID, $pending_comments ); +?> +
+
> + +
+ + + +
$checkbox$theme_name"; + echo $this->row_actions( $actions, true ); + echo " +
$description
+
"; + + $theme_meta = array(); + + if ( !empty( $theme['Version'] ) ) + $theme_meta[] = sprintf( __( 'Version %s' ), $theme['Version'] ); + + if ( !empty( $theme['Author'] ) ) + $theme_meta[] = sprintf( __( 'By %s' ), $theme['Author'] ); + + if ( !empty( $theme['Theme URI'] ) ) + $theme_meta[] = '' . __( 'Visit Theme Site' ) . ''; + + $theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $theme_key, $theme, $status ); + echo implode( ' | ', $theme_meta ); + + echo "
"; + do_action( 'manage_themes_custom_column', $column_name, $theme_key, $theme ); + echo "
+ + "; ?> + user_login ); ?>user_login, $super_admins ) ) + echo ' - ' . __( 'Super Admin' ); + ?> +
+ ' . __( 'Edit' ) . ''; + + if ( current_user_can( 'delete_user', $user->ID) && ! in_array( $user->user_login, $super_admins ) ) { + $actions['delete'] = '' . __( 'Delete' ) . ''; + } + + echo $this->row_actions( $actions ); + ?> +
$user->user_email" . mysql2date( $date, $user->user_registered ) . ""; + if ( is_array( $blogs ) ) { + foreach ( (array) $blogs as $key => $val ) { + if ( !can_edit_network( $val->site_id ) ) + continue; + + $path = ( $val->path == '/' ) ? '' : $val->path; + echo ''; + echo '' . str_replace( '.' . $current_site->domain, '', $val->domain . $path ) . ''; + echo ' '; + $actions = array(); + $actions['edit'] = '' . __( 'Edit' ) . ''; + + $class = ''; + if ( get_blog_status( $val->userblog_id, 'spam' ) == 1 ) + $class .= 'site-spammed '; + if ( get_blog_status( $val->userblog_id, 'mature' ) == 1 ) + $class .= 'site-mature '; + if ( get_blog_status( $val->userblog_id, 'deleted' ) == 1 ) + $class .= 'site-deleted '; + if ( get_blog_status( $val->userblog_id, 'archived' ) == 1 ) + $class .= 'site-archived '; + + $actions['view'] = '' . __( 'View' ) . ''; + + $actions = apply_filters('ms_user_list_site_actions', $actions, $val->userblog_id); + + $i=0; + $action_count = count( $actions ); + foreach ( $actions as $action => $link ) { + ++$i; + ( $i == $action_count ) ? $sep = '' : $sep = ' | '; + echo "$link$sep"; + } + echo '
'; + } + } + ?> +
> + + >> +
+
+
<?php _e( '5 stars' ) ?>
+
<?php _e( '4 stars' ) ?>
+
<?php _e( '3 stars' ) ?>
+
<?php _e( '2 stars' ) ?>
+
<?php _e( '1 star' ) ?>
+
+
>
$checkbox$plugin_name"; + echo $this->row_actions( $actions, true ); + echo " +
$description
+
"; + + $plugin_meta = array(); + if ( !empty( $plugin_data['Version'] ) ) + $plugin_meta[] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); + if ( !empty( $plugin_data['Author'] ) ) { + $author = $plugin_data['Author']; + if ( !empty( $plugin_data['AuthorURI'] ) ) + $author = '' . $plugin_data['Author'] . ''; + $plugin_meta[] = sprintf( __( 'By %s' ), $author ); + } + if ( ! empty( $plugin_data['PluginURI'] ) ) + $plugin_meta[] = '' . __( 'Visit plugin site' ) . ''; + + $plugin_meta = apply_filters( 'plugin_row_meta', $plugin_meta, $plugin_file, $plugin_data, $status ); + echo implode( ' | ', $plugin_meta ); + + echo "
"; + do_action( 'manage_plugins_custom_column', $column_name, $plugin_file, $plugin_data ); + echo "
>post_status != 'trash' ) { ?>labels->parent_item_colon . ' ' . esc_html( $parent_name ) : ''; ?> + + >post_status != 'trash' ) { ?> +post_status ) { + $actions['edit'] = '' . __( 'Edit' ) . ''; + $actions['inline hide-if-no-js'] = '' . __( 'Quick Edit' ) . ''; + } + if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) { + if ( 'trash' == $post->post_status ) + $actions['untrash'] = "ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID ) . "'>" . __( 'Restore' ) . ""; + elseif ( EMPTY_TRASH_DAYS ) + $actions['trash'] = "" . __( 'Trash' ) . ""; + if ( 'trash' == $post->post_status || !EMPTY_TRASH_DAYS ) + $actions['delete'] = "" . __( 'Delete Permanently' ) . ""; + } + if ( in_array( $post->post_status, array( 'pending', 'draft' ) ) ) { + if ( $can_edit_post ) + $actions['view'] = '' . __( 'Preview' ) . ''; + } elseif ( 'trash' != $post->post_status ) { + $actions['view'] = '' . __( 'View' ) . ''; + } + + $actions = apply_filters( is_post_type_hierarchical( $post->post_type ) ? 'page_row_actions' : 'post_row_actions', $actions, $post ); + echo $this->row_actions( $actions ); + + get_inline_data( $post ); + echo ''; + if ( 'excerpt' == $mode ) + echo apply_filters( 'post_date_column_time', $t_time, $post, $column_name, $mode ); + else + echo '' . apply_filters( 'post_date_column_time', $h_time, $post, $column_name, $mode ) . ''; + echo '
'; + if ( 'publish' == $post->post_status ) { + _e( 'Published' ); + } elseif ( 'future' == $post->post_status ) { + if ( $time_diff > 0 ) + echo '' . __( 'Missed schedule' ) . ''; + else + _e( 'Scheduled' ); + } else { + _e( 'Last Modified' ); + } + echo '
>%s', + esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'category_name' => $c->slug ), 'edit.php' ) ), + esc_html( sanitize_term_field( 'name', $c->name, $c->term_id, 'category', 'display' ) ) + ); + } + echo join( ', ', $out ); + } else { + _e( 'Uncategorized' ); + } + ?>>ID ); + if ( !empty( $tags ) ) { + $out = array(); + foreach ( $tags as $c ) { + $out[] = sprintf( '%s', + esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'tag' => $c->slug ), 'edit.php' ) ), + esc_html( sanitize_term_field( 'name', $c->name, $c->term_id, 'tag', 'display' ) ) + ); + } + echo join( ', ', $out ); + } else { + _e( 'No Tags' ); + } + ?>>
+ comment_pending_count[$post->ID] ) ? $this->comment_pending_count[$post->ID] : 0; + + $this->comments_bubble( $post->ID, $pending_comments ); + ?> +
>%s', + esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'author' => get_the_author_meta( 'ID' ) ), 'edit.php' )), + get_the_author() + ); + ?>>post_type ) ) + do_action( 'manage_pages_custom_column', $column_name, $post->ID ); + else + do_action( 'manage_posts_custom_column', $column_name, $post->ID ); + do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID ); + ?>
+ + + post_type "; + echo $bulk ? "bulk-edit-row bulk-edit-row-$hclass bulk-edit-$screen->post_type" : "quick-edit-row quick-edit-row-$hclass inline-edit-$screen->post_type"; + ?>" style="display: none"> + +
+ +
+

+ post_type, 'title' ) ) : + if ( $bulk ) : ?> +
+
+
+ + + + + + + + + + + +
+ +
+
+ post_type, 'author' ) ) : + $authors_dropdown = ''; + + if ( is_super_admin() || current_user_can( $post_type_object->cap->edit_others_posts ) ) : + $users_opt = array( + 'hide_if_only_one_author' => false, + 'who' => 'authors', + 'name' => 'post_author', + 'class'=> 'authors', + 'multi' => 1, + 'echo' => 0 + ); + if ( $bulk ) + $users_opt['show_option_none'] = __( '— No Change —' ); + + if ( $authors = wp_dropdown_users( $users_opt ) ) : + $authors_dropdown = ''; + endif; + endif; // authors + ?> + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + labels->name ) ?> + + + + +
    + $taxonomy->name ) ) ?> +
+ + + +
+ + + +
+ + post_type, 'author' ) && $bulk ) + echo $authors_dropdown; + ?> + + hierarchical ) : ?> + + + + post_type, 'page-attributes' ) ) : + if ( !$bulk ) : ?> + + + + + + + + hierarchical ?> + + + + + + + + + + + + post_type, 'comments' ) || post_type_supports( $screen->post_type, 'trackbacks' ) ) : + if ( $bulk ) : ?> + +
+ post_type, 'comments' ) ) : ?> + + post_type, 'trackbacks' ) ) : ?> + + +
+ + + +
+ post_type, 'comments' ) ) : ?> + + post_type, 'trackbacks' ) ) : ?> + + +
+ + + +
+ + + post_type && $can_publish && current_user_can( $post_type_object->cap->edit_others_posts ) ) : ?> + + + + + + + + + + + + + +
+ +
+ + get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + if ( isset( $core_columns[$column_name] ) ) + continue; + do_action( $bulk ? 'bulk_edit_custom_box' : 'quick_edit_custom_box', $column_name, $screen->post_type ); + } + ?> +

+ + + + + 's' ) ); + } ?> + + +
+

+
+ diff --git a/src/wp-admin/includes/class-wp-terms-list-table.php b/src/wp-admin/includes/class-wp-terms-list-table.php new file mode 100644 index 00000000..ac4d963c --- /dev/null +++ b/src/wp-admin/includes/class-wp-terms-list-table.php @@ -0,0 +1,379 @@ + true ) ) ) ) + $post_type = 'post'; + + parent::WP_List_Table( array( + 'plural' => 'tags', + 'singular' => 'tag', + ) ); + } + + function ajax_user_can() { + global $tax; + + return current_user_can( $tax->cap->manage_terms ); + } + + function prepare_items() { + global $taxonomy; + + $tags_per_page = $this->get_items_per_page( 'edit_' . $taxonomy . '_per_page' ); + + if ( 'post_tag' == $taxonomy ) { + $tags_per_page = apply_filters( 'edit_tags_per_page', $tags_per_page ); + $tags_per_page = apply_filters( 'tagsperpage', $tags_per_page ); // Old filter + } elseif ( 'category' == $taxonomy ) { + $tags_per_page = apply_filters( 'edit_categories_per_page', $tags_per_page ); // Old filter + } + + $search = !empty( $_REQUEST['s'] ) ? trim( stripslashes( $_REQUEST['s'] ) ) : ''; + + $args = array( + 'search' => $search, + 'page' => $this->get_pagenum(), + 'number' => $tags_per_page, + ); + + if ( !empty( $_REQUEST['orderby'] ) ) + $args['orderby'] = trim( stripslashes( $_REQUEST['orderby'] ) ); + + if ( !empty( $_REQUEST['order'] ) ) + $args['order'] = trim( stripslashes( $_REQUEST['order'] ) ); + + $this->callback_args = $args; + + $this->set_pagination_args( array( + 'total_items' => wp_count_terms( $taxonomy, compact( 'search' ) ), + 'per_page' => $tags_per_page, + ) ); + } + + function has_items() { + // todo: populate $this->items in prepare_items() + return true; + } + + function get_bulk_actions() { + $actions = array(); + $actions['delete'] = __( 'Delete' ); + + return $actions; + } + + function current_action() { + if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['delete_tags'] ) && ( 'delete' == $_REQUEST['action'] || 'delete' == $_REQUEST['action2'] ) ) + return 'bulk-delete'; + + return parent::current_action(); + } + + function get_columns() { + global $taxonomy, $typenow; + + $columns = array( + 'cb' => '', + 'name' => __( 'Name' ), + 'description' => __( 'Description' ), + 'slug' => __( 'Slug' ), + ); + + if ( 'link_category' == $taxonomy ) { + $columns['links'] = __( 'Links' ); + } else { + $post_type = empty( $typenow ) ? 'post' : $typenow; + $post_type_object = get_post_type_object( $post_type ); + $columns['posts'] = $post_type_object ? $post_type_object->labels->name : __( 'Posts' ); + } + + return $columns; + } + + function get_sortable_columns() { + return array( + 'name' => 'name', + 'description' => 'description', + 'slug' => 'slug', + 'posts' => 'count', + 'links' => 'count' + ); + } + + function display_rows_or_placeholder() { + global $taxonomy; + + $args = wp_parse_args( $this->callback_args, array( + 'page' => 1, + 'number' => 20, + 'search' => '', + 'hide_empty' => 0 + ) ); + + extract( $args, EXTR_SKIP ); + + $args['offset'] = $offset = ( $page - 1 ) * $number; + + // convert it to table rows + $out = ''; + $count = 0; + + $terms = array(); + + if ( is_taxonomy_hierarchical( $taxonomy ) && !isset( $orderby ) ) { + // We'll need the full set of terms then. + $args['number'] = $args['offset'] = 0; + + $terms = get_terms( $taxonomy, $args ); + if ( !empty( $search ) ) // Ignore children on searches. + $children = array(); + else + $children = _get_term_hierarchy( $taxonomy ); + + // Some funky recursion to get the job done( Paging & parents mainly ) is contained within, Skip it for non-hierarchical taxonomies for performance sake + $out .= $this->_rows( $taxonomy, $terms, $children, $offset, $number, $count ); + } else { + $terms = get_terms( $taxonomy, $args ); + foreach ( $terms as $term ) + $out .= $this->single_row( $term, 0, $taxonomy ); + $count = $number; // Only displaying a single page. + } + + if ( empty( $terms ) ) { + list( $columns, $hidden ) = $this->get_column_info(); + echo ''; + $this->no_items(); + echo ''; + } else { + echo $out; + } + } + + function _rows( $taxonomy, $terms, &$children, $start = 0, $per_page = 20, &$count, $parent = 0, $level = 0 ) { + + $end = $start + $per_page; + + $output = ''; + foreach ( $terms as $key => $term ) { + + if ( $count >= $end ) + break; + + if ( $term->parent != $parent && empty( $_REQUEST['s'] ) ) + continue; + + // If the page starts in a subtree, print the parents. + if ( $count == $start && $term->parent > 0 && empty( $_REQUEST['s'] ) ) { + $my_parents = $parent_ids = array(); + $p = $term->parent; + while ( $p ) { + $my_parent = get_term( $p, $taxonomy ); + $my_parents[] = $my_parent; + $p = $my_parent->parent; + if ( in_array( $p, $parent_ids ) ) // Prevent parent loops. + break; + $parent_ids[] = $p; + } + unset( $parent_ids ); + + $num_parents = count( $my_parents ); + while ( $my_parent = array_pop( $my_parents ) ) { + $output .= "\t" . $this->single_row( $my_parent, $level - $num_parents, $taxonomy ); + $num_parents--; + } + } + + if ( $count >= $start ) + $output .= "\t" . $this->single_row( $term, $level, $taxonomy ); + + ++$count; + + unset( $terms[$key] ); + + if ( isset( $children[$term->term_id] ) && empty( $_REQUEST['s'] ) ) + $output .= $this->_rows( $taxonomy, $terms, $children, $start, $per_page, $count, $term->term_id, $level + 1 ); + } + + return $output; + } + + function single_row( $tag, $level = 0 ) { + static $row_class = ''; + $row_class = ( $row_class == '' ? ' class="alternate"' : '' ); + + $this->level = $level; + + echo ''; + echo $this->single_row_columns( $tag ); + echo ''; + } + + function column_cb( $tag ) { + global $taxonomy, $tax; + + $default_term = get_option( 'default_' . $taxonomy ); + + if ( current_user_can( $tax->cap->delete_terms ) && $tag->term_id != $default_term ) + return ''; + else + return ' '; + } + + function column_name( $tag ) { + global $taxonomy, $tax, $post_type; + + $default_term = get_option( 'default_' . $taxonomy ); + + $pad = str_repeat( '— ', max( 0, $this->level ) ); + $name = apply_filters( 'term_name', $pad . ' ' . $tag->name, $tag ); + $qe_data = get_term( $tag->term_id, $taxonomy, OBJECT, 'edit' ); + $edit_link = get_edit_term_link( $tag->term_id, $taxonomy, $post_type ); + + $out = '' . $name . '
'; + + $actions = array(); + if ( current_user_can( $tax->cap->edit_terms ) ) { + $actions['edit'] = '' . __( 'Edit' ) . ''; + $actions['inline hide-if-no-js'] = '' . __( 'Quick Edit' ) . ''; + } + if ( current_user_can( $tax->cap->delete_terms ) && $tag->term_id != $default_term ) + $actions['delete'] = "term_id ) . "'>" . __( 'Delete' ) . ""; + + $actions = apply_filters( 'tag_row_actions', $actions, $tag ); + $actions = apply_filters( "{$taxonomy}_row_actions", $actions, $tag ); + + $out .= $this->row_actions( $actions ); + $out .= ''; + + return $out; + } + + function column_description( $tag ) { + return $tag->description; + } + + function column_slug( $tag ) { + return apply_filters( 'editable_slug', $tag->slug ); + } + + function column_posts( $tag ) { + global $taxonomy, $post_type; + + $count = number_format_i18n( $tag->count ); + + $tax = get_taxonomy( $taxonomy ); + + if ( ! $tax->public ) + return $count; + + if ( $tax->query_var ) { + $args = array( $tax->query_var => $tag->slug ); + } else { + $args = array( 'taxonomy' => $tax->name, 'term' => $tag->slug ); + } + + $args['post_type'] = $post_type; + + return "$count"; + } + + function column_links( $tag ) { + $count = number_format_i18n( $tag->count ); + if ( $count ) + $count = "$count"; + return $count; + } + + function column_default( $tag, $column_name ) { + $screen = get_current_screen(); + + return apply_filters( "manage_{$screen->taxonomy}_custom_column", '', $column_name, $tag->term_id ); + } + + /** + * Outputs the hidden row displayed when inline editing + * + * @since 3.1.0 + */ + function inline_edit() { + global $tax; + + if ( ! current_user_can( $tax->cap->edit_terms ) ) + return; +?> + +
+ +
+ diff --git a/src/wp-admin/includes/class-wp-theme-install-list-table.php b/src/wp-admin/includes/class-wp-theme-install-list-table.php new file mode 100644 index 00000000..7e44267c --- /dev/null +++ b/src/wp-admin/includes/class-wp-theme-install-list-table.php @@ -0,0 +1,185 @@ +get_pagenum(); + + $per_page = 30; + + // These are the tabs which are shown on the page, + $tabs = array(); + $tabs['dashboard'] = __( 'Search' ); + if ( 'search' == $tab ) + $tabs['search'] = __( 'Search Results' ); + $tabs['upload'] = __( 'Upload' ); + $tabs['featured'] = _x( 'Featured','Theme Installer' ); + //$tabs['popular'] = _x( 'Popular','Theme Installer' ); + $tabs['new'] = _x( 'Newest','Theme Installer' ); + $tabs['updated'] = _x( 'Recently Updated','Theme Installer' ); + + $nonmenu_tabs = array( 'theme-information' ); // Valid actions to perform which do not have a Menu item. + + $tabs = apply_filters( 'install_themes_tabs', $tabs ); + $nonmenu_tabs = apply_filters( 'install_themes_nonmenu_tabs', $nonmenu_tabs ); + + // If a non-valid menu tab has been selected, And its not a non-menu action. + if ( empty( $tab ) || ( ! isset( $tabs[ $tab ] ) && ! in_array( $tab, (array) $nonmenu_tabs ) ) ) + $tab = key( $tabs ); + + $args = array( 'page' => $paged, 'per_page' => $per_page, 'fields' => $theme_field_defaults ); + + switch ( $tab ) { + case 'search': + $type = isset( $_REQUEST['type'] ) ? stripslashes( $_REQUEST['type'] ) : ''; + $term = isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : ''; + + switch ( $type ) { + case 'tag': + $terms = explode( ',', $term ); + $terms = array_map( 'trim', $terms ); + $terms = array_map( 'sanitize_title_with_dashes', $terms ); + $args['tag'] = $terms; + break; + case 'term': + $args['search'] = $term; + break; + case 'author': + $args['author'] = $term; + break; + } + + if ( !empty( $_POST['features'] ) ) { + $terms = $_POST['features']; + $terms = array_map( 'trim', $terms ); + $terms = array_map( 'sanitize_title_with_dashes', $terms ); + $args['tag'] = $terms; + $_REQUEST['s'] = implode( ',', $terms ); + $_REQUEST['type'] = 'tag'; + } + + add_action( 'install_themes_table_header', 'install_theme_search_form' ); + break; + + case 'featured': + //case 'popular': + case 'new': + case 'updated': + $args['browse'] = $tab; + break; + + default: + $args = false; + } + + if ( !$args ) + return; + + $api = themes_api( 'query_themes', $args ); + + if ( is_wp_error( $api ) ) + wp_die( $api->get_error_message() . '

' . __( 'Try again' ) . '' ); + + $this->items = $api->themes; + + $this->set_pagination_args( array( + 'total_items' => $api->info['results'], + 'per_page' => $per_page, + ) ); + } + + function no_items() { + _e( 'No themes match your request.' ); + } + + function get_views() { + global $tabs, $tab; + + $display_tabs = array(); + foreach ( (array) $tabs as $action => $text ) { + $class = ( $action == $tab ) ? ' class="current"' : ''; + $href = self_admin_url('theme-install.php?tab=' . $action); + $display_tabs['theme-install-'.$action] = "$text"; + } + + return $display_tabs; + } + + function get_columns() { + return array(); + } + + function display() { + + // wp_nonce_field( "fetch-list-" . get_class( $this ), '_ajax_fetch_list_nonce' ); +?> +

+
+ +
+ pagination( 'top' ); ?> + +
+
+ + + + display_rows_or_placeholder(); ?> + +
+ +
+ pagination( 'bottom' ); ?> + +
+
+items; + + $rows = ceil( count( $themes ) / 3 ); + $table = array(); + $theme_keys = array_keys( $themes ); + for ( $row = 1; $row <= $rows; $row++ ) + for ( $col = 1; $col <= 3; $col++ ) + $table[$row][$col] = array_shift( $theme_keys ); + + foreach ( $table as $row => $cols ) { + echo "\t\n"; + foreach ( $cols as $col => $theme_index ) { + $class = array( 'available-theme' ); + if ( $row == 1 ) $class[] = 'top'; + if ( $col == 1 ) $class[] = 'left'; + if ( $row == $rows ) $class[] = 'bottom'; + if ( $col == 3 ) $class[] = 'right'; + ?> + + \n"; + } // end foreach $table + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-themes-list-table.php b/src/wp-admin/includes/class-wp-themes-list-table.php new file mode 100644 index 00000000..91e1d254 --- /dev/null +++ b/src/wp-admin/includes/class-wp-themes-list-table.php @@ -0,0 +1,241 @@ +search = array_merge( $this->search, array_filter( array_map( 'trim', explode( ',', $search ) ) ) ); + $this->search = array_unique( $this->search ); + } + + if ( !empty( $_REQUEST['features'] ) ) { + $this->features = $_REQUEST['features']; + $this->features = array_map( 'trim', $this->features ); + $this->features = array_map( 'sanitize_title_with_dashes', $this->features ); + $this->features = array_unique( $this->features ); + } + + if ( $this->search || $this->features ) { + foreach ( $themes as $key => $theme ) { + if ( !$this->search_theme( $theme ) ) + unset( $themes[ $key ] ); + } + } + + unset( $themes[$ct->name] ); + uksort( $themes, "strnatcasecmp" ); + + $per_page = 15; + $page = $this->get_pagenum(); + + $start = ( $page - 1 ) * $per_page; + + $this->items = array_slice( $themes, $start, $per_page ); + + $this->set_pagination_args( array( + 'total_items' => count( $themes ), + 'per_page' => $per_page, + ) ); + } + + function no_items() { + if ( $this->search || $this->features ) { + _e( 'No items found.' ); + return; + } + + if ( is_multisite() ) { + if ( current_user_can( 'install_themes' ) && current_user_can( 'manage_network_themes' ) ) { + printf( __( 'You only have one theme enabled for this site right now. Visit the Network Admin to enable or install more themes.' ), network_admin_url( 'site-themes.php?id=' . $GLOBALS['blog_id'] ), network_admin_url( 'theme-install.php' ) ); + + return; + } elseif ( current_user_can( 'manage_network_themes' ) ) { + printf( __( 'You only have one theme enabled for this site right now. Visit the Network Admin to enable more themes.' ), network_admin_url( 'site-themes.php?id=' . $GLOBALS['blog_id'] ) ); + + return; + } + // else, fallthrough. install_themes doesn't help if you can't enable it. + } else { + if ( current_user_can( 'install_themes' ) ) { + printf( __( 'You only have one theme installed right now. Live a little! You can choose from over 1,000 free themes in the WordPress.org Theme Directory at any time: just click on the Install Themes tab above.' ), admin_url( 'theme-install.php' ) ); + + return; + } + } + // Fallthrough. + printf( __( 'Only the current theme is available to you. Contact the %s administrator for information about accessing additional themes.' ), get_site_option( 'site_name' ) ); + } + + function tablenav( $which = 'top' ) { + if ( $this->get_pagination_arg( 'total_pages' ) <= 1 ) + return; + ?> +
+ pagination( $which ); ?> + +
+
+ + tablenav( 'top' ); ?> + + + + display_rows_or_placeholder(); ?> + +
+ + tablenav( 'bottom' ); ?> +items; + $theme_names = array_keys( $themes ); + natcasesort( $theme_names ); + + $table = array(); + $rows = ceil( count( $theme_names ) / 3 ); + for ( $row = 1; $row <= $rows; $row++ ) + for ( $col = 1; $col <= 3; $col++ ) + $table[$row][$col] = array_shift( $theme_names ); + + foreach ( $table as $row => $cols ) { +?> + + $theme_name ) { + $class = array( 'available-theme' ); + if ( $row == 1 ) $class[] = 'top'; + if ( $col == 1 ) $class[] = 'left'; + if ( $row == $rows ) $class[] = 'bottom'; + if ( $col == 3 ) $class[] = 'right'; +?> + + 1, 'template' => $template, 'stylesheet' => $stylesheet, 'preview_iframe' => true, 'TB_iframe' => 'true' ), $preview_link ) ); + $preview_text = esc_attr( sprintf( __( 'Preview of “%s”' ), $title ) ); + $tags = $themes[$theme_name]['Tags']; + $thickbox_class = 'thickbox thickbox-preview'; + $activate_link = wp_nonce_url( "themes.php?action=activate&template=".urlencode( $template )."&stylesheet=".urlencode( $stylesheet ), 'switch-theme_' . $template ); + $activate_text = esc_attr( sprintf( __( 'Activate “%s”' ), $title ) ); + $actions = array(); + $actions[] = '' . __( 'Activate' ) . ''; + $actions[] = '' . __( 'Preview' ) . ''; + if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) + $actions[] = '' . __( 'Delete' ) . ''; + $actions = apply_filters( 'theme_action_links', $actions, $themes[$theme_name] ); + + $actions = implode ( ' | ', $actions ); +?> + + + + + +

+

+ + +

%2$s. The stylesheet files are located in %3$s. %4$s uses templates from %5$s. Changes made to the templates will affect both themes.' ), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ), $title, $parent_theme ); ?>

+ +

%2$s.' ), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ) ); ?>

+ + +

+ + + + + + +search ) > 0 ) { + foreach ( $this->search as $word ) { + $matched = 0; + + // In a tag? + if ( in_array( $word, array_map( 'sanitize_title_with_dashes', $theme['Tags'] ) ) ) + $matched = 1; + + // In one of the fields? + foreach ( array( 'Name', 'Title', 'Description', 'Author', 'Template', 'Stylesheet' ) AS $field ) { + if ( stripos( $theme[$field], $word ) !== false ) + $matched++; + } + + if ( $matched == 0 ) + return false; + } + } + + // Now search the features + if ( count( $this->features ) > 0 ) { + foreach ( $this->features as $word ) { + // In a tag? + if ( !in_array( $word, array_map( 'sanitize_title_with_dashes', $theme['Tags'] ) ) ) + return false; + } + } + + // Only get here if each word exists in the tags or one of the fields + return true; + } +} + +?> diff --git a/src/wp-admin/includes/class-wp-upgrader.php b/src/wp-admin/includes/class-wp-upgrader.php new file mode 100644 index 00000000..d81b3056 --- /dev/null +++ b/src/wp-admin/includes/class-wp-upgrader.php @@ -0,0 +1,1468 @@ +__construct($skin); + } + function __construct($skin = null) { + if ( null == $skin ) + $this->skin = new WP_Upgrader_Skin(); + else + $this->skin = $skin; + } + + function init() { + $this->skin->set_upgrader($this); + $this->generic_strings(); + } + + function generic_strings() { + $this->strings['bad_request'] = __('Invalid Data provided.'); + $this->strings['fs_unavailable'] = __('Could not access filesystem.'); + $this->strings['fs_error'] = __('Filesystem error.'); + $this->strings['fs_no_root_dir'] = __('Unable to locate WordPress Root directory.'); + $this->strings['fs_no_content_dir'] = __('Unable to locate WordPress Content directory (wp-content).'); + $this->strings['fs_no_plugins_dir'] = __('Unable to locate WordPress Plugin directory.'); + $this->strings['fs_no_themes_dir'] = __('Unable to locate WordPress Theme directory.'); + /* translators: %s: directory name */ + $this->strings['fs_no_folder'] = __('Unable to locate needed folder (%s).'); + + $this->strings['download_failed'] = __('Download failed.'); + $this->strings['installing_package'] = __('Installing the latest version…'); + $this->strings['folder_exists'] = __('Destination folder already exists.'); + $this->strings['mkdir_failed'] = __('Could not create directory.'); + $this->strings['bad_package'] = __('Incompatible Archive.'); + + $this->strings['maintenance_start'] = __('Enabling Maintenance mode…'); + $this->strings['maintenance_end'] = __('Disabling Maintenance mode…'); + } + + function fs_connect( $directories = array() ) { + global $wp_filesystem; + + if ( false === ($credentials = $this->skin->request_filesystem_credentials()) ) + return false; + + if ( ! WP_Filesystem($credentials) ) { + $error = true; + if ( is_object($wp_filesystem) && $wp_filesystem->errors->get_error_code() ) + $error = $wp_filesystem->errors; + $this->skin->request_filesystem_credentials($error); //Failed to connect, Error and request again + return false; + } + + if ( ! is_object($wp_filesystem) ) + return new WP_Error('fs_unavailable', $this->strings['fs_unavailable'] ); + + if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() ) + return new WP_Error('fs_error', $this->strings['fs_error'], $wp_filesystem->errors); + + foreach ( (array)$directories as $dir ) { + switch ( $dir ) { + case ABSPATH: + if ( ! $wp_filesystem->abspath() ) + return new WP_Error('fs_no_root_dir', $this->strings['fs_no_root_dir']); + break; + case WP_CONTENT_DIR: + if ( ! $wp_filesystem->wp_content_dir() ) + return new WP_Error('fs_no_content_dir', $this->strings['fs_no_content_dir']); + break; + case WP_PLUGIN_DIR: + if ( ! $wp_filesystem->wp_plugins_dir() ) + return new WP_Error('fs_no_plugins_dir', $this->strings['fs_no_plugins_dir']); + break; + case WP_CONTENT_DIR . '/themes': + if ( ! $wp_filesystem->find_folder(WP_CONTENT_DIR . '/themes') ) + return new WP_Error('fs_no_themes_dir', $this->strings['fs_no_themes_dir']); + break; + default: + if ( ! $wp_filesystem->find_folder($dir) ) + return new WP_Error('fs_no_folder', sprintf($this->strings['fs_no_folder'], $dir)); + break; + } + } + return true; + } //end fs_connect(); + + function download_package($package) { + + if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote? + return $package; //must be a local file.. + + if ( empty($package) ) + return new WP_Error('no_package', $this->strings['no_package']); + + $this->skin->feedback('downloading_package', $package); + + $download_file = download_url($package); + + if ( is_wp_error($download_file) ) + return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message()); + + return $download_file; + } + + function unpack_package($package, $delete_package = true) { + global $wp_filesystem; + + $this->skin->feedback('unpack_package'); + + $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/'; + + //Clean up contents of upgrade directory beforehand. + $upgrade_files = $wp_filesystem->dirlist($upgrade_folder); + if ( !empty($upgrade_files) ) { + foreach ( $upgrade_files as $file ) + $wp_filesystem->delete($upgrade_folder . $file['name'], true); + } + + //We need a working directory + $working_dir = $upgrade_folder . basename($package, '.zip'); + + // Clean up working directory + if ( $wp_filesystem->is_dir($working_dir) ) + $wp_filesystem->delete($working_dir, true); + + // Unzip package to working directory + $result = unzip_file($package, $working_dir); //TODO optimizations, Copy when Move/Rename would suffice? + + // Once extracted, delete the package if required. + if ( $delete_package ) + unlink($package); + + if ( is_wp_error($result) ) { + $wp_filesystem->delete($working_dir, true); + return $result; + } + + return $working_dir; + } + + function install_package($args = array()) { + global $wp_filesystem; + $defaults = array( 'source' => '', 'destination' => '', //Please always pass these + 'clear_destination' => false, 'clear_working' => false, + 'hook_extra' => array()); + + $args = wp_parse_args($args, $defaults); + extract($args); + + @set_time_limit( 300 ); + + if ( empty($source) || empty($destination) ) + return new WP_Error('bad_request', $this->strings['bad_request']); + + $this->skin->feedback('installing_package'); + + $res = apply_filters('upgrader_pre_install', true, $hook_extra); + if ( is_wp_error($res) ) + return $res; + + //Retain the Original source and destinations + $remote_source = $source; + $local_destination = $destination; + + $source_files = array_keys( $wp_filesystem->dirlist($remote_source) ); + $remote_destination = $wp_filesystem->find_folder($local_destination); + + //Locate which directory to copy to the new folder, This is based on the actual folder holding the files. + if ( 1 == count($source_files) && $wp_filesystem->is_dir( trailingslashit($source) . $source_files[0] . '/') ) //Only one folder? Then we want its contents. + $source = trailingslashit($source) . trailingslashit($source_files[0]); + elseif ( count($source_files) == 0 ) + return new WP_Error('bad_package', $this->strings['bad_package']); //There are no files? + //else //Its only a single file, The upgrader will use the foldername of this file as the destination folder. foldername is based on zip filename. + + //Hook ability to change the source file location.. + $source = apply_filters('upgrader_source_selection', $source, $remote_source, $this); + if ( is_wp_error($source) ) + return $source; + + //Has the source location changed? If so, we need a new source_files list. + if ( $source !== $remote_source ) + $source_files = array_keys( $wp_filesystem->dirlist($source) ); + + //Protection against deleting files in any important base directories. + if ( in_array( $destination, array(ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes') ) ) { + $remote_destination = trailingslashit($remote_destination) . trailingslashit(basename($source)); + $destination = trailingslashit($destination) . trailingslashit(basename($source)); + } + + if ( $wp_filesystem->exists($remote_destination) ) { + if ( $clear_destination ) { + //We're going to clear the destination if theres something there + $this->skin->feedback('remove_old'); + $removed = $wp_filesystem->delete($remote_destination, true); + $removed = apply_filters('upgrader_clear_destination', $removed, $local_destination, $remote_destination, $hook_extra); + + if ( is_wp_error($removed) ) + return $removed; + else if ( ! $removed ) + return new WP_Error('remove_old_failed', $this->strings['remove_old_failed']); + } else { + //If we're not clearing the destination folder and something exists there allready, Bail. + //But first check to see if there are actually any files in the folder. + $_files = $wp_filesystem->dirlist($remote_destination); + if ( ! empty($_files) ) { + $wp_filesystem->delete($remote_source, true); //Clear out the source files. + return new WP_Error('folder_exists', $this->strings['folder_exists'], $remote_destination ); + } + } + } + + //Create destination if needed + if ( !$wp_filesystem->exists($remote_destination) ) + if ( !$wp_filesystem->mkdir($remote_destination, FS_CHMOD_DIR) ) + return new WP_Error('mkdir_failed', $this->strings['mkdir_failed'], $remote_destination); + + // Copy new version of item into place. + $result = copy_dir($source, $remote_destination); + if ( is_wp_error($result) ) { + if ( $clear_working ) + $wp_filesystem->delete($remote_source, true); + return $result; + } + + //Clear the Working folder? + if ( $clear_working ) + $wp_filesystem->delete($remote_source, true); + + $destination_name = basename( str_replace($local_destination, '', $destination) ); + if ( '.' == $destination_name ) + $destination_name = ''; + + $this->result = compact('local_source', 'source', 'source_name', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination', 'delete_source_dir'); + + $res = apply_filters('upgrader_post_install', true, $hook_extra, $this->result); + if ( is_wp_error($res) ) { + $this->result = $res; + return $res; + } + + //Bombard the calling function will all the info which we've just used. + return $this->result; + } + + function run($options) { + + $defaults = array( 'package' => '', //Please always pass this. + 'destination' => '', //And this + 'clear_destination' => false, + 'clear_working' => true, + 'is_multi' => false, + 'hook_extra' => array() //Pass any extra $hook_extra args here, this will be passed to any hooked filters. + ); + + $options = wp_parse_args($options, $defaults); + extract($options); + + //Connect to the Filesystem first. + $res = $this->fs_connect( array(WP_CONTENT_DIR, $destination) ); + if ( ! $res ) //Mainly for non-connected filesystem. + return false; + + if ( is_wp_error($res) ) { + $this->skin->error($res); + return $res; + } + + if ( !$is_multi ) // call $this->header separately if running multiple times + $this->skin->header(); + + $this->skin->before(); + + //Download the package (Note, This just returns the filename of the file if the package is a local file) + $download = $this->download_package( $package ); + if ( is_wp_error($download) ) { + $this->skin->error($download); + $this->skin->after(); + return $download; + } + + //Unzip's the file into a temporary directory + $working_dir = $this->unpack_package( $download ); + if ( is_wp_error($working_dir) ) { + $this->skin->error($working_dir); + $this->skin->after(); + return $working_dir; + } + + //With the given options, this installs it to the destination directory. + $result = $this->install_package( array( + 'source' => $working_dir, + 'destination' => $destination, + 'clear_destination' => $clear_destination, + 'clear_working' => $clear_working, + 'hook_extra' => $hook_extra + ) ); + $this->skin->set_result($result); + if ( is_wp_error($result) ) { + $this->skin->error($result); + $this->skin->feedback('process_failed'); + } else { + //Install Suceeded + $this->skin->feedback('process_success'); + } + $this->skin->after(); + + if ( !$is_multi ) + $this->skin->footer(); + + return $result; + } + + function maintenance_mode($enable = false) { + global $wp_filesystem; + $file = $wp_filesystem->abspath() . '.maintenance'; + if ( $enable ) { + $this->skin->feedback('maintenance_start'); + // Create maintenance file to signal that we are upgrading + $maintenance_string = ''; + $wp_filesystem->delete($file); + $wp_filesystem->put_contents($file, $maintenance_string, FS_CHMOD_FILE); + } else if ( !$enable && $wp_filesystem->exists($file) ) { + $this->skin->feedback('maintenance_end'); + $wp_filesystem->delete($file); + } + } + +} + +/** + * Plugin Upgrader class for WordPress Plugins, It is designed to upgrade/install plugins from a local zip, remote zip URL, or uploaded zip file. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class Plugin_Upgrader extends WP_Upgrader { + + var $result; + var $bulk = false; + var $show_before = ''; + + function upgrade_strings() { + $this->strings['up_to_date'] = __('The plugin is at the latest version.'); + $this->strings['no_package'] = __('Update package not available.'); + $this->strings['downloading_package'] = __('Downloading update from %s…'); + $this->strings['unpack_package'] = __('Unpacking the update…'); + $this->strings['deactivate_plugin'] = __('Deactivating the plugin…'); + $this->strings['remove_old'] = __('Removing the old version of the plugin…'); + $this->strings['remove_old_failed'] = __('Could not remove the old plugin.'); + $this->strings['process_failed'] = __('Plugin update failed.'); + $this->strings['process_success'] = __('Plugin updated successfully.'); + } + + function install_strings() { + $this->strings['no_package'] = __('Install package not available.'); + $this->strings['downloading_package'] = __('Downloading install package from %s…'); + $this->strings['unpack_package'] = __('Unpacking the package…'); + $this->strings['installing_package'] = __('Installing the plugin…'); + $this->strings['process_failed'] = __('Plugin install failed.'); + $this->strings['process_success'] = __('Plugin installed successfully.'); + } + + function install($package) { + + $this->init(); + $this->install_strings(); + + $this->run(array( + 'package' => $package, + 'destination' => WP_PLUGIN_DIR, + 'clear_destination' => false, //Do not overwrite files. + 'clear_working' => true, + 'hook_extra' => array() + )); + + // Force refresh of plugin update information + delete_site_transient('update_plugins'); + + } + + function upgrade($plugin) { + + $this->init(); + $this->upgrade_strings(); + + $current = get_site_transient( 'update_plugins' ); + if ( !isset( $current->response[ $plugin ] ) ) { + $this->skin->before(); + $this->skin->set_result(false); + $this->skin->error('up_to_date'); + $this->skin->after(); + return false; + } + + // Get the URL to the zip file + $r = $current->response[ $plugin ]; + + add_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade'), 10, 2); + add_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'), 10, 4); + //'source_selection' => array(&$this, 'source_selection'), //theres a track ticket to move up the directory for zip's which are made a bit differently, useful for non-.org plugins. + + $this->run(array( + 'package' => $r->package, + 'destination' => WP_PLUGIN_DIR, + 'clear_destination' => true, + 'clear_working' => true, + 'hook_extra' => array( + 'plugin' => $plugin + ) + )); + + // Cleanup our hooks, incase something else does a upgrade on this connection. + remove_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade')); + remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin')); + + if ( ! $this->result || is_wp_error($this->result) ) + return $this->result; + + // Force refresh of plugin update information + delete_site_transient('update_plugins'); + } + + function bulk_upgrade($plugins) { + + $this->init(); + $this->bulk = true; + $this->upgrade_strings(); + + $current = get_site_transient( 'update_plugins' ); + + add_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'), 10, 4); + + $this->skin->header(); + + // Connect to the Filesystem first. + $res = $this->fs_connect( array(WP_CONTENT_DIR, WP_PLUGIN_DIR) ); + if ( ! $res ) { + $this->skin->footer(); + return false; + } + + $this->skin->bulk_header(); + + // Only start maintenance mode if running in Multisite OR the plugin is in use + $maintenance = is_multisite(); // @TODO: This should only kick in for individual sites if at all possible. + foreach ( $plugins as $plugin ) + $maintenance = $maintenance || (is_plugin_active($plugin) && isset($current->response[ $plugin ]) ); // Only activate Maintenance mode if a plugin is active AND has an update available + if ( $maintenance ) + $this->maintenance_mode(true); + + $results = array(); + + $this->update_count = count($plugins); + $this->update_current = 0; + foreach ( $plugins as $plugin ) { + $this->update_current++; + $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true); + + if ( !isset( $current->response[ $plugin ] ) ) { + $this->skin->set_result(false); + $this->skin->before(); + $this->skin->error('up_to_date'); + $this->skin->after(); + $results[$plugin] = false; + continue; + } + + // Get the URL to the zip file + $r = $current->response[ $plugin ]; + + $this->skin->plugin_active = is_plugin_active($plugin); + + $result = $this->run(array( + 'package' => $r->package, + 'destination' => WP_PLUGIN_DIR, + 'clear_destination' => true, + 'clear_working' => true, + 'is_multi' => true, + 'hook_extra' => array( + 'plugin' => $plugin + ) + )); + + $results[$plugin] = $this->result; + + // Prevent credentials auth screen from displaying multiple times + if ( false === $result ) + break; + } //end foreach $plugins + + $this->maintenance_mode(false); + + $this->skin->bulk_footer(); + + $this->skin->footer(); + + // Cleanup our hooks, incase something else does a upgrade on this connection. + remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin')); + + // Force refresh of plugin update information + delete_site_transient('update_plugins'); + + return $results; + } + + //return plugin info. + function plugin_info() { + if ( ! is_array($this->result) ) + return false; + if ( empty($this->result['destination_name']) ) + return false; + + $plugin = get_plugins('/' . $this->result['destination_name']); //Ensure to pass with leading slash + if ( empty($plugin) ) + return false; + + $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list + + return $this->result['destination_name'] . '/' . $pluginfiles[0]; + } + + //Hooked to pre_install + function deactivate_plugin_before_upgrade($return, $plugin) { + + if ( is_wp_error($return) ) //Bypass. + return $return; + + $plugin = isset($plugin['plugin']) ? $plugin['plugin'] : ''; + if ( empty($plugin) ) + return new WP_Error('bad_request', $this->strings['bad_request']); + + if ( is_plugin_active($plugin) ) { + $this->skin->feedback('deactivate_plugin'); + //Deactivate the plugin silently, Prevent deactivation hooks from running. + deactivate_plugins($plugin, true); + } + } + + //Hooked to upgrade_clear_destination + function delete_old_plugin($removed, $local_destination, $remote_destination, $plugin) { + global $wp_filesystem; + + if ( is_wp_error($removed) ) + return $removed; //Pass errors through. + + $plugin = isset($plugin['plugin']) ? $plugin['plugin'] : ''; + if ( empty($plugin) ) + return new WP_Error('bad_request', $this->strings['bad_request']); + + $plugins_dir = $wp_filesystem->wp_plugins_dir(); + $this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin) ); + + if ( ! $wp_filesystem->exists($this_plugin_dir) ) //If its already vanished. + return $removed; + + // If plugin is in its own directory, recursively delete the directory. + if ( strpos($plugin, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder + $deleted = $wp_filesystem->delete($this_plugin_dir, true); + else + $deleted = $wp_filesystem->delete($plugins_dir . $plugin); + + if ( ! $deleted ) + return new WP_Error('remove_old_failed', $this->strings['remove_old_failed']); + + return $removed; + } +} + +/** + * Theme Upgrader class for WordPress Themes, It is designed to upgrade/install themes from a local zip, remote zip URL, or uploaded zip file. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class Theme_Upgrader extends WP_Upgrader { + + var $result; + + function upgrade_strings() { + $this->strings['up_to_date'] = __('The theme is at the latest version.'); + $this->strings['no_package'] = __('Update package not available.'); + $this->strings['downloading_package'] = __('Downloading update from %s…'); + $this->strings['unpack_package'] = __('Unpacking the update…'); + $this->strings['remove_old'] = __('Removing the old version of the theme…'); + $this->strings['remove_old_failed'] = __('Could not remove the old theme.'); + $this->strings['process_failed'] = __('Theme update failed.'); + $this->strings['process_success'] = __('Theme updated successfully.'); + } + + function install_strings() { + $this->strings['no_package'] = __('Install package not available.'); + $this->strings['downloading_package'] = __('Downloading install package from %s…'); + $this->strings['unpack_package'] = __('Unpacking the package…'); + $this->strings['installing_package'] = __('Installing the theme…'); + $this->strings['process_failed'] = __('Theme install failed.'); + $this->strings['process_success'] = __('Theme installed successfully.'); + } + + function install($package) { + + $this->init(); + $this->install_strings(); + + $options = array( + 'package' => $package, + 'destination' => WP_CONTENT_DIR . '/themes', + 'clear_destination' => false, //Do not overwrite files. + 'clear_working' => true + ); + + $this->run($options); + + if ( ! $this->result || is_wp_error($this->result) ) + return $this->result; + + // Force refresh of theme update information + delete_site_transient('update_themes'); + + if ( empty($result['destination_name']) ) + return false; + else + return $result['destination_name']; + } + + function upgrade($theme) { + + $this->init(); + $this->upgrade_strings(); + + // Is an update available? + $current = get_site_transient( 'update_themes' ); + if ( !isset( $current->response[ $theme ] ) ) { + $this->skin->before(); + $this->skin->set_result(false); + $this->skin->error('up_to_date'); + $this->skin->after(); + return false; + } + + $r = $current->response[ $theme ]; + + add_filter('upgrader_pre_install', array(&$this, 'current_before'), 10, 2); + add_filter('upgrader_post_install', array(&$this, 'current_after'), 10, 2); + add_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme'), 10, 4); + + $options = array( + 'package' => $r['package'], + 'destination' => WP_CONTENT_DIR . '/themes', + 'clear_destination' => true, + 'clear_working' => true, + 'hook_extra' => array( + 'theme' => $theme + ) + ); + + $this->run($options); + + if ( ! $this->result || is_wp_error($this->result) ) + return $this->result; + + // Force refresh of theme update information + delete_site_transient('update_themes'); + + return true; + } + + function bulk_upgrade($themes) { + + $this->init(); + $this->bulk = true; + $this->upgrade_strings(); + + $current = get_site_transient( 'update_themes' ); + + add_filter('upgrader_pre_install', array(&$this, 'current_before'), 10, 2); + add_filter('upgrader_post_install', array(&$this, 'current_after'), 10, 2); + add_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme'), 10, 4); + + $this->skin->header(); + + // Connect to the Filesystem first. + $res = $this->fs_connect( array(WP_CONTENT_DIR) ); + if ( ! $res ) { + $this->skin->footer(); + return false; + } + + $this->skin->bulk_header(); + + // Only start maintenance mode if running in Multisite OR the theme is in use + $maintenance = is_multisite(); // @TODO: This should only kick in for individual sites if at all possible. + foreach ( $themes as $theme ) + $maintenance = $maintenance || $theme == get_stylesheet() || $theme == get_template(); + if ( $maintenance ) + $this->maintenance_mode(true); + + $results = array(); + + $this->update_count = count($themes); + $this->update_current = 0; + foreach ( $themes as $theme ) { + $this->update_current++; + + if ( !isset( $current->response[ $theme ] ) ) { + $this->skin->set_result(false); + $this->skin->before(); + $this->skin->error('up_to_date'); + $this->skin->after(); + $results[$theme] = false; + continue; + } + + $this->skin->theme_info = $this->theme_info($theme); + + // Get the URL to the zip file + $r = $current->response[ $theme ]; + + $options = array( + 'package' => $r['package'], + 'destination' => WP_CONTENT_DIR . '/themes', + 'clear_destination' => true, + 'clear_working' => true, + 'hook_extra' => array( + 'theme' => $theme + ) + ); + + $result = $this->run($options); + + $results[$theme] = $this->result; + + // Prevent credentials auth screen from displaying multiple times + if ( false === $result ) + break; + } //end foreach $plugins + + $this->maintenance_mode(false); + + $this->skin->bulk_footer(); + + $this->skin->footer(); + + // Cleanup our hooks, incase something else does a upgrade on this connection. + remove_filter('upgrader_pre_install', array(&$this, 'current_before'), 10, 2); + remove_filter('upgrader_post_install', array(&$this, 'current_after'), 10, 2); + remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme'), 10, 4); + + // Force refresh of theme update information + delete_site_transient('update_themes'); + + return $results; + } + + function current_before($return, $theme) { + + if ( is_wp_error($return) ) + return $return; + + $theme = isset($theme['theme']) ? $theme['theme'] : ''; + + if ( $theme != get_stylesheet() ) //If not current + return $return; + //Change to maintenance mode now. + if ( ! $this->bulk ) + $this->maintenance_mode(true); + + return $return; + } + function current_after($return, $theme) { + if ( is_wp_error($return) ) + return $return; + + $theme = isset($theme['theme']) ? $theme['theme'] : ''; + + if ( $theme != get_stylesheet() ) //If not current + return $return; + + //Ensure stylesheet name hasnt changed after the upgrade: + // @TODO: Note, This doesnt handle the Template changing, or the Template name changing. + if ( $theme == get_stylesheet() && $theme != $this->result['destination_name'] ) { + $theme_info = $this->theme_info(); + $stylesheet = $this->result['destination_name']; + $template = !empty($theme_info['Template']) ? $theme_info['Template'] : $stylesheet; + switch_theme($template, $stylesheet, true); + } + + //Time to remove maintenance mode + if ( ! $this->bulk ) + $this->maintenance_mode(false); + return $return; + } + + function delete_old_theme($removed, $local_destination, $remote_destination, $theme) { + global $wp_filesystem; + + $theme = isset($theme['theme']) ? $theme['theme'] : ''; + + if ( is_wp_error($removed) || empty($theme) ) + return $removed; //Pass errors through. + + $themes_dir = $wp_filesystem->wp_themes_dir(); + if ( $wp_filesystem->exists( trailingslashit($themes_dir) . $theme ) ) + if ( ! $wp_filesystem->delete( trailingslashit($themes_dir) . $theme, true ) ) + return false; + return true; + } + + function theme_info($theme = null) { + + if ( empty($theme) ) { + if ( !empty($this->result['destination_name']) ) + $theme = $this->result['destination_name']; + else + return false; + } + return get_theme_data(WP_CONTENT_DIR . '/themes/' . $theme . '/style.css'); + } + +} + +/** + * Core Upgrader class for WordPress. It allows for WordPress to upgrade itself in combiantion with the wp-admin/includes/update-core.php file + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class Core_Upgrader extends WP_Upgrader { + + function upgrade_strings() { + $this->strings['up_to_date'] = __('WordPress is at the latest version.'); + $this->strings['no_package'] = __('Update package not available.'); + $this->strings['downloading_package'] = __('Downloading update from %s…'); + $this->strings['unpack_package'] = __('Unpacking the update…'); + $this->strings['copy_failed'] = __('Could not copy files.'); + } + + function upgrade($current) { + global $wp_filesystem; + + $this->init(); + $this->upgrade_strings(); + + if ( !empty($feedback) ) + add_filter('update_feedback', $feedback); + + // Is an update available? + if ( !isset( $current->response ) || $current->response == 'latest' ) + return new WP_Error('up_to_date', $this->strings['up_to_date']); + + $res = $this->fs_connect( array(ABSPATH, WP_CONTENT_DIR) ); + if ( is_wp_error($res) ) + return $res; + + $wp_dir = trailingslashit($wp_filesystem->abspath()); + + $download = $this->download_package( $current->package ); + if ( is_wp_error($download) ) + return $download; + + $working_dir = $this->unpack_package( $download ); + if ( is_wp_error($working_dir) ) + return $working_dir; + + // Copy update-core.php from the new version into place. + if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) { + $wp_filesystem->delete($working_dir, true); + return new WP_Error('copy_failed', $this->strings['copy_failed']); + } + $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE); + + require(ABSPATH . 'wp-admin/includes/update-core.php'); + + return update_core($working_dir, $wp_dir); + } + +} + +/** + * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class WP_Upgrader_Skin { + + var $upgrader; + var $done_header = false; + var $result = false; + + function WP_Upgrader_Skin($args = array()) { + return $this->__construct($args); + } + function __construct($args = array()) { + $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false ); + $this->options = wp_parse_args($args, $defaults); + } + + function set_upgrader(&$upgrader) { + if ( is_object($upgrader) ) + $this->upgrader =& $upgrader; + $this->add_strings(); + } + + function add_strings() { + } + + function set_result($result) { + $this->result = $result; + } + + function request_filesystem_credentials($error = false) { + $url = $this->options['url']; + $context = $this->options['context']; + if ( !empty($this->options['nonce']) ) + $url = wp_nonce_url($url, $this->options['nonce']); + return request_filesystem_credentials($url, '', $error, $context); //Possible to bring inline, Leaving as is for now. + } + + function header() { + if ( $this->done_header ) + return; + $this->done_header = true; + echo '
'; + echo screen_icon(); + echo '

' . $this->options['title'] . '

'; + } + function footer() { + echo '
'; + } + + function error($errors) { + if ( ! $this->done_header ) + $this->header(); + if ( is_string($errors) ) { + $this->feedback($errors); + } elseif ( is_wp_error($errors) && $errors->get_error_code() ) { + foreach ( $errors->get_error_messages() as $message ) { + if ( $errors->get_error_data() ) + $this->feedback($message . ' ' . $errors->get_error_data() ); + else + $this->feedback($message); + } + } + } + + function feedback($string) { + if ( isset( $this->upgrader->strings[$string] ) ) + $string = $this->upgrader->strings[$string]; + + if ( strpos($string, '%') !== false ) { + $args = func_get_args(); + $args = array_splice($args, 1); + if ( !empty($args) ) + $string = vsprintf($string, $args); + } + if ( empty($string) ) + return; + show_message($string); + } + function before() {} + function after() {} + +} + +/** + * Plugin Upgrader Skin for WordPress Plugin Upgrades. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class Plugin_Upgrader_Skin extends WP_Upgrader_Skin { + var $plugin = ''; + var $plugin_active = false; + var $plugin_network_active = false; + + function Plugin_Upgrader_Skin($args = array()) { + return $this->__construct($args); + } + + function __construct($args = array()) { + $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') ); + $args = wp_parse_args($args, $defaults); + + $this->plugin = $args['plugin']; + + $this->plugin_active = is_plugin_active( $this->plugin ); + $this->plugin_network_active = is_plugin_active_for_network( $this->plugin ); + + parent::__construct($args); + } + + function after() { + $this->plugin = $this->upgrader->plugin_info(); + if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){ + show_message(__('Reactivating the plugin…')); + echo ''; + } + + $update_actions = array( + 'activate_plugin' => '' . __('Activate Plugin') . '', + 'plugins_page' => '' . __('Return to Plugins page') . '' + ); + if ( $this->plugin_active ) + unset( $update_actions['activate_plugin'] ); + if ( ! $this->result || is_wp_error($this->result) ) + unset( $update_actions['activate_plugin'] ); + + $update_actions = apply_filters('update_plugin_complete_actions', $update_actions, $this->plugin); + if ( ! empty($update_actions) ) + $this->feedback(implode(' | ', (array)$update_actions)); + } + + function before() { + if ( $this->upgrader->show_before ) { + echo $this->upgrader->show_before; + $this->upgrader->show_before = ''; + } + } +} + +/** + * Plugin Upgrader Skin for WordPress Plugin Upgrades. + * + * @package WordPress + * @subpackage Upgrader + * @since 3.0.0 + */ +class Bulk_Upgrader_Skin extends WP_Upgrader_Skin { + var $in_loop = false; + var $error = false; + + function Bulk_Upgrader_Skin($args = array()) { + return $this->__construct($args); + } + + function __construct($args = array()) { + $defaults = array( 'url' => '', 'nonce' => '' ); + $args = wp_parse_args($args, $defaults); + + parent::__construct($args); + } + + function add_strings() { + $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.'); + $this->upgrader->strings['skin_update_failed_error'] = __('An error occurred while updating %1$s: %2$s.'); + $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.'); + $this->upgrader->strings['skin_update_successful'] = __('%1$s updated successfully.').' '.__('Show Details').'.'; + $this->upgrader->strings['skin_upgrade_end'] = __('All updates have been completed.'); + } + + function feedback($string) { + if ( isset( $this->upgrader->strings[$string] ) ) + $string = $this->upgrader->strings[$string]; + + if ( strpos($string, '%') !== false ) { + $args = func_get_args(); + $args = array_splice($args, 1); + if ( !empty($args) ) + $string = vsprintf($string, $args); + } + if ( empty($string) ) + return; + if ( $this->in_loop ) + echo "$string
\n"; + else + echo "

$string

\n"; + } + + function header() { + // Nothing, This will be displayed within a iframe. + } + + function footer() { + // Nothing, This will be displayed within a iframe. + } + function error($error) { + if ( is_string($error) && isset( $this->upgrader->strings[$error] ) ) + $this->error = $this->upgrader->strings[$error]; + + if ( is_wp_error($error) ) { + foreach ( $error->get_error_messages() as $emessage ) { + if ( $error->get_error_data() ) + $messages[] = $emessage . ' ' . $error->get_error_data(); + else + $messages[] = $emessage; + } + $this->error = implode(', ', $messages); + } + echo ''; + } + + function bulk_header() { + $this->feedback('skin_upgrade_start'); + } + + function bulk_footer() { + $this->feedback('skin_upgrade_end'); + } + + function before($title = '') { + $this->in_loop = true; + printf( '

' . $this->upgrader->strings['skin_before_update_header'] . '

', $title, $this->upgrader->update_current, $this->upgrader->update_count); + echo ''; + echo '

'; + $this->flush_output(); + } + + function after($title = '') { + echo '

'; + if ( $this->error || ! $this->result ) { + if ( $this->error ) + echo '

' . sprintf($this->upgrader->strings['skin_update_failed_error'], $title, $this->error) . '

'; + else + echo '

' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '

'; + + echo ''; + } + if ( !empty($this->result) && !is_wp_error($this->result) ) { + echo '

' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle();jQuery(\'span\', this).toggle(); return false;') . '

'; + echo ''; + } + + $this->reset(); + $this->flush_output(); + } + + function reset() { + $this->in_loop = false; + $this->error = false; + } + + function flush_output() { + wp_ob_end_flush_all(); + flush(); + } +} + +class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin { + var $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in. + function Plugin_Upgrader_Skin($args = array()) { + parent::__construct($args); + } + + function add_strings() { + parent::add_strings(); + $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)'); + } + + function before() { + parent::before($this->plugin_info['Title']); + } + + function after() { + parent::after($this->plugin_info['Title']); + } + function bulk_footer() { + parent::bulk_footer(); + $update_actions = array( + 'plugins_page' => '' . __('Return to Plugins page') . '', + 'updates_page' => '' . __('Return to WordPress Updates') . '' + ); + + $update_actions = apply_filters('update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info); + if ( ! empty($update_actions) ) + $this->feedback(implode(' | ', (array)$update_actions)); + } +} + +class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin { + var $theme_info = array(); // Theme_Upgrader::bulk() will fill this in. + function Theme_Upgrader_Skin($args = array()) { + parent::__construct($args); + } + + function add_strings() { + parent::add_strings(); + $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)'); + } + + function before() { + parent::before($this->theme_info['Name']); + } + + function after() { + parent::after($this->theme_info['Name']); + } + function bulk_footer() { + parent::bulk_footer(); + $update_actions = array( + 'themes_page' => '' . __('Return to Themes page') . '', + 'updates_page' => '' . __('Return to WordPress Updates') . '' + ); + + $update_actions = apply_filters('update_bulk_theme_complete_actions', $update_actions, $this->theme_info); + if ( ! empty($update_actions) ) + $this->feedback(implode(' | ', (array)$update_actions)); + } +} + +/** + * Plugin Installer Skin for WordPress Plugin Installer. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class Plugin_Installer_Skin extends WP_Upgrader_Skin { + var $api; + var $type; + + function Plugin_Installer_Skin($args = array()) { + return $this->__construct($args); + } + + function __construct($args = array()) { + $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' ); + $args = wp_parse_args($args, $defaults); + + $this->type = $args['type']; + $this->api = isset($args['api']) ? $args['api'] : array(); + + parent::__construct($args); + } + + function before() { + if ( !empty($this->api) ) + $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin %s %s.'), $this->api->name, $this->api->version); + } + + function after() { + + $plugin_file = $this->upgrader->plugin_info(); + + $install_actions = array(); + + $from = isset($_GET['from']) ? stripslashes($_GET['from']) : 'plugins'; + + if ( 'import' == $from ) + $install_actions['activate_plugin'] = '' . __('Activate Plugin & Run Importer') . ''; + else + $install_actions['activate_plugin'] = '' . __('Activate Plugin') . ''; + + if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) { + $install_actions['network_activate'] = '' . __('Network Activate') . ''; + unset( $install_actions['activate_plugin'] ); + } + + if ( 'import' == $from ) + $install_actions['importers_page'] = '' . __('Return to Importers') . ''; + else if ( $this->type == 'web' ) + $install_actions['plugins_page'] = '' . __('Return to Plugin Installer') . ''; + else + $install_actions['plugins_page'] = '' . __('Return to Plugins page') . ''; + + + if ( ! $this->result || is_wp_error($this->result) ) { + unset( $install_actions['activate_plugin'] ); + unset( $install_actions['network_activate'] ); + } + $install_actions = apply_filters('install_plugin_complete_actions', $install_actions, $this->api, $plugin_file); + if ( ! empty($install_actions) ) + $this->feedback(implode(' | ', (array)$install_actions)); + } +} + +/** + * Theme Installer Skin for the WordPress Theme Installer. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class Theme_Installer_Skin extends WP_Upgrader_Skin { + var $api; + var $type; + + function Theme_Installer_Skin($args = array()) { + return $this->__construct($args); + } + + function __construct($args = array()) { + $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' ); + $args = wp_parse_args($args, $defaults); + + $this->type = $args['type']; + $this->api = isset($args['api']) ? $args['api'] : array(); + + parent::__construct($args); + } + + function before() { + if ( !empty($this->api) ) { + /* translators: 1: theme name, 2: version */ + $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the theme %1$s %2$s.'), $this->api->name, $this->api->version); + } + } + + function after() { + if ( empty($this->upgrader->result['destination_name']) ) + return; + + $theme_info = $this->upgrader->theme_info(); + if ( empty($theme_info) ) + return; + $name = $theme_info['Name']; + $stylesheet = $this->upgrader->result['destination_name']; + $template = !empty($theme_info['Template']) ? $theme_info['Template'] : $stylesheet; + + $preview_link = htmlspecialchars( add_query_arg( array('preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'preview_iframe' => 1, 'TB_iframe' => 'true' ), trailingslashit(esc_url(get_option('home'))) ) ); + $activate_link = wp_nonce_url("themes.php?action=activate&template=" . urlencode($template) . "&stylesheet=" . urlencode($stylesheet), 'switch-theme_' . $template); + + $install_actions = array( + 'preview' => '' . __('Preview') . '', + 'activate' => '' . __('Activate') . '' + ); + + if ( $this->type == 'web' ) + $install_actions['themes_page'] = '' . __('Return to Theme Installer') . ''; + else + $install_actions['themes_page'] = '' . __('Return to Themes page') . ''; + + if ( ! $this->result || is_wp_error($this->result) || is_network_admin() ) + unset( $install_actions['activate'], $install_actions['preview'] ); + + $install_actions = apply_filters('install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info); + if ( ! empty($install_actions) ) + $this->feedback(implode(' | ', (array)$install_actions)); + } +} + +/** + * Theme Upgrader Skin for WordPress Theme Upgrades. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class Theme_Upgrader_Skin extends WP_Upgrader_Skin { + var $theme = ''; + + function Theme_Upgrader_Skin($args = array()) { + return $this->__construct($args); + } + + function __construct($args = array()) { + $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') ); + $args = wp_parse_args($args, $defaults); + + $this->theme = $args['theme']; + + parent::__construct($args); + } + + function after() { + + $update_actions = array(); + if ( !empty($this->upgrader->result['destination_name']) && + ($theme_info = $this->upgrader->theme_info()) && + !empty($theme_info) ) { + + $name = $theme_info['Name']; + $stylesheet = $this->upgrader->result['destination_name']; + $template = !empty($theme_info['Template']) ? $theme_info['Template'] : $stylesheet; + + $preview_link = htmlspecialchars( add_query_arg( array('preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'TB_iframe' => 'true' ), trailingslashit(esc_url(get_option('home'))) ) ); + $activate_link = wp_nonce_url("themes.php?action=activate&template=" . urlencode($template) . "&stylesheet=" . urlencode($stylesheet), 'switch-theme_' . $template); + + $update_actions['preview'] = '' . __('Preview') . ''; + $update_actions['activate'] = '' . __('Activate') . ''; + + if ( ( ! $this->result || is_wp_error($this->result) ) || $stylesheet == get_stylesheet() ) + unset($update_actions['preview'], $update_actions['activate']); + } + + $update_actions['themes_page'] = '' . __('Return to Themes page') . ''; + + $update_actions = apply_filters('update_theme_complete_actions', $update_actions, $this->theme); + if ( ! empty($update_actions) ) + $this->feedback(implode(' | ', (array)$update_actions)); + } +} + +/** + * Upgrade Skin helper for File uploads. This class handles the upload process and passes it as if its a local file to the Upgrade/Installer functions. + * + * @TODO More Detailed docs, for methods as well. + * + * @package WordPress + * @subpackage Upgrader + * @since 2.8.0 + */ +class File_Upload_Upgrader { + var $package; + var $filename; + + function File_Upload_Upgrader($form, $urlholder) { + return $this->__construct($form, $urlholder); + } + function __construct($form, $urlholder) { + if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) ) + wp_die($uploads['error']); + + if ( empty($_FILES[$form]['name']) && empty($_GET[$urlholder]) ) + wp_die(__('Please select a file')); + + if ( !empty($_FILES) ) + $this->filename = $_FILES[$form]['name']; + else if ( isset($_GET[$urlholder]) ) + $this->filename = $_GET[$urlholder]; + + //Handle a newly uploaded file, Else assume its already been uploaded + if ( !empty($_FILES) ) { + $this->filename = wp_unique_filename( $uploads['basedir'], $this->filename ); + $this->package = $uploads['basedir'] . '/' . $this->filename; + + // Move the file to the uploads dir + if ( false === @ move_uploaded_file( $_FILES[$form]['tmp_name'], $this->package) ) + wp_die( sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'])); + } else { + $this->package = $uploads['basedir'] . '/' . $this->filename; + } + } +} \ No newline at end of file diff --git a/src/wp-admin/includes/class-wp-users-list-table.php b/src/wp-admin/includes/class-wp-users-list-table.php new file mode 100644 index 00000000..d52d75f0 --- /dev/null +++ b/src/wp-admin/includes/class-wp-users-list-table.php @@ -0,0 +1,319 @@ +is_site_users = 'site-users-network' == $screen->id; + + if ( $this->is_site_users ) + $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; + + parent::WP_List_Table( array( + 'singular' => 'user', + 'plural' => 'users' + ) ); + } + + function ajax_user_can() { + if ( $this->is_site_users ) + return current_user_can( 'manage_sites' ); + else + return current_user_can( 'list_users' ); + } + + function prepare_items() { + global $role, $usersearch; + + $usersearch = isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : ''; + + $role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : ''; + + $per_page = ( $this->is_site_users ) ? 'site_users_network_per_page' : 'users_per_page'; + $users_per_page = $this->get_items_per_page( $per_page ); + + $paged = $this->get_pagenum(); + + $args = array( + 'number' => $users_per_page, + 'offset' => ( $paged-1 ) * $users_per_page, + 'role' => $role, + 'search' => $usersearch, + 'fields' => 'all_with_meta' + ); + + $args['search'] = '*' . $args['search'] . '*'; + + if ( $this->is_site_users ) + $args['blog_id'] = $this->site_id; + + if ( isset( $_REQUEST['orderby'] ) ) + $args['orderby'] = $_REQUEST['orderby']; + + if ( isset( $_REQUEST['order'] ) ) + $args['order'] = $_REQUEST['order']; + + // Query the user IDs for this page + $wp_user_search = new WP_User_Query( $args ); + + $this->items = $wp_user_search->get_results(); + + $this->set_pagination_args( array( + 'total_items' => $wp_user_search->get_total(), + 'per_page' => $users_per_page, + ) ); + } + + function no_items() { + _e( 'No matching users were found.' ); + } + + function get_views() { + global $wp_roles, $role; + + if ( $this->is_site_users ) { + $url = 'site-users.php?id=' . $this->site_id; + switch_to_blog( $this->site_id ); + $users_of_blog = count_users(); + restore_current_blog(); + } else { + $url = 'users.php'; + $users_of_blog = count_users(); + } + $total_users = $users_of_blog['total_users']; + $avail_roles =& $users_of_blog['avail_roles']; + unset($users_of_blog); + + $current_role = false; + $class = empty($role) ? ' class="current"' : ''; + $role_links = array(); + $role_links['all'] = "" . sprintf( _nx( 'All (%s)', 'All (%s)', $total_users, 'users' ), number_format_i18n( $total_users ) ) . ''; + foreach ( $wp_roles->get_names() as $this_role => $name ) { + if ( !isset($avail_roles[$this_role]) ) + continue; + + $class = ''; + + if ( $this_role == $role ) { + $current_role = $role; + $class = ' class="current"'; + } + + $name = translate_user_role( $name ); + /* translators: User role name with count */ + $name = sprintf( __('%1$s (%2$s)'), $name, $avail_roles[$this_role] ); + $role_links[$this_role] = "$name"; + } + + return $role_links; + } + + function get_bulk_actions() { + $actions = array(); + + if ( is_multisite() ) { + if ( current_user_can( 'remove_users' ) ) + $actions['remove'] = __( 'Remove' ); + } else { + if ( current_user_can( 'delete_users' ) ) + $actions['delete'] = __( 'Delete' ); + } + + return $actions; + } + + function extra_tablenav( $which ) { + if ( 'top' != $which ) + return; + if ( ! current_user_can( 'promote_users' ) ) + return; +?> +
+ + + +
+ '', + 'username' => __( 'Username' ), + 'name' => __( 'Name' ), + 'email' => __( 'E-mail' ), + 'role' => __( 'Role' ), + 'posts' => __( 'Posts' ) + ); + + if ( $this->is_site_users ) + unset( $c['posts'] ); + + return $c; + } + + function get_sortable_columns() { + $c = array( + 'username' => 'login', + 'name' => 'name', + 'email' => 'email', + ); + + if ( $this->is_site_users ) + unset( $c['posts'] ); + + return $c; + } + + function display_rows() { + // Query the post counts for this page + if ( ! $this->is_site_users ) + $post_counts = count_many_users_posts( array_keys( $this->items ) ); + + $style = ''; + foreach ( $this->items as $userid => $user_object ) { + $role = reset( $user_object->roles ); + + if ( is_multisite() && empty( $role ) ) + continue; + + $style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"'; + echo "\n\t", $this->single_row( $user_object, $style, $role, isset( $post_counts ) ? $post_counts[ $userid ] : 0 ); + } + } + + /** + * Generate HTML for a single row on the users.php admin panel. + * + * @since 2.1.0 + * + * @param object $user_object + * @param string $style Optional. Attributes added to the TR element. Must be sanitized. + * @param string $role Key for the $wp_roles array. + * @param int $numposts Optional. Post count to display for this user. Defaults to zero, as in, a new user has made zero posts. + * @return string + */ + function single_row( $user_object, $style = '', $role = '', $numposts = 0 ) { + global $wp_roles; + + if ( !( is_object( $user_object ) && is_a( $user_object, 'WP_User' ) ) ) + $user_object = new WP_User( (int) $user_object ); + $user_object = sanitize_user_object( $user_object, 'display' ); + $email = $user_object->user_email; + + if ( $this->is_site_users ) + $url = "site-users.php?id={$this->site_id}&"; + else + $url = 'users.php?'; + + $checkbox = ''; + // Check if the user for this row is editable + if ( current_user_can( 'list_users' ) ) { + // Set up the user editing link + // TODO: make profile/user-edit determination a separate function + if ( get_current_user_id() == $user_object->ID ) { + $edit_link = 'profile.php'; + } else { + $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( stripslashes( $_SERVER['REQUEST_URI'] ) ), "user-edit.php?user_id=$user_object->ID" ) ); + } + + // Set up the hover actions for this user + $actions = array(); + + if ( current_user_can( 'edit_user', $user_object->ID ) ) { + $edit = "$user_object->user_login
"; + $actions['edit'] = '' . __( 'Edit' ) . ''; + } else { + $edit = "$user_object->user_login
"; + } + + if ( !is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) ) + $actions['delete'] = "" . __( 'Delete' ) . ""; + if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) ) + $actions['remove'] = "" . __( 'Remove' ) . ""; + $actions = apply_filters( 'user_row_actions', $actions, $user_object ); + $edit .= $this->row_actions( $actions ); + + // Set up the checkbox ( because the user is editable, otherwise its empty ) + $checkbox = ""; + + } else { + $edit = '' . $user_object->user_login . ''; + } + $role_name = isset( $wp_roles->role_names[$role] ) ? translate_user_role( $wp_roles->role_names[$role] ) : __( 'None' ); + $avatar = get_avatar( $user_object->ID, 32 ); + + $r = ""; + + list( $columns, $hidden ) = $this->get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $class = "class=\"$column_name column-$column_name\""; + + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + $attributes = "$class$style"; + + switch ( $column_name ) { + case 'cb': + $r .= "$checkbox"; + break; + case 'username': + $r .= "$avatar $edit"; + break; + case 'name': + $r .= "$user_object->first_name $user_object->last_name"; + break; + case 'email': + $r .= "$email"; + break; + case 'role': + $r .= "$role_name"; + break; + case 'posts': + $attributes = 'class="posts column-posts num"' . $style; + $r .= ""; + if ( $numposts > 0 ) { + $r .= ""; + $r .= $numposts; + $r .= ''; + } else { + $r .= 0; + } + $r .= ""; + break; + default: + $r .= ""; + $r .= apply_filters( 'manage_users_custom_column', '', $column_name, $user_object->ID ); + $r .= ""; + } + } + $r .= ''; + + return $r; + } +} + +?> diff --git a/src/wp-admin/includes/comment.php b/src/wp-admin/includes/comment.php new file mode 100644 index 00000000..d731130a --- /dev/null +++ b/src/wp-admin/includes/comment.php @@ -0,0 +1,159 @@ +get_var( $wpdb->prepare("SELECT comment_post_ID FROM $wpdb->comments + WHERE comment_author = %s AND comment_date = %s", $comment_author, $comment_date) ); +} + +/** + * Update a comment with values provided in $_POST. + * + * @since 2.0.0 + */ +function edit_comment() { + + if ( ! current_user_can( 'edit_comment', (int) $_POST['comment_ID'] ) ) + wp_die ( __( 'You are not allowed to edit comments on this post.' ) ); + + $_POST['comment_author'] = $_POST['newcomment_author']; + $_POST['comment_author_email'] = $_POST['newcomment_author_email']; + $_POST['comment_author_url'] = $_POST['newcomment_author_url']; + $_POST['comment_approved'] = $_POST['comment_status']; + $_POST['comment_content'] = $_POST['content']; + $_POST['comment_ID'] = (int) $_POST['comment_ID']; + + foreach ( array ('aa', 'mm', 'jj', 'hh', 'mn') as $timeunit ) { + if ( !empty( $_POST['hidden_' . $timeunit] ) && $_POST['hidden_' . $timeunit] != $_POST[$timeunit] ) { + $_POST['edit_date'] = '1'; + break; + } + } + + if ( !empty ( $_POST['edit_date'] ) ) { + $aa = $_POST['aa']; + $mm = $_POST['mm']; + $jj = $_POST['jj']; + $hh = $_POST['hh']; + $mn = $_POST['mn']; + $ss = $_POST['ss']; + $jj = ($jj > 31 ) ? 31 : $jj; + $hh = ($hh > 23 ) ? $hh -24 : $hh; + $mn = ($mn > 59 ) ? $mn -60 : $mn; + $ss = ($ss > 59 ) ? $ss -60 : $ss; + $_POST['comment_date'] = "$aa-$mm-$jj $hh:$mn:$ss"; + } + + wp_update_comment( $_POST ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.0.0 + * + * @param int $id ID of comment to retrieve + * @return bool|object Comment if found. False on failure. + */ +function get_comment_to_edit( $id ) { + if ( !$comment = get_comment($id) ) + return false; + + $comment->comment_ID = (int) $comment->comment_ID; + $comment->comment_post_ID = (int) $comment->comment_post_ID; + + $comment->comment_content = format_to_edit( $comment->comment_content ); + $comment->comment_content = apply_filters( 'comment_edit_pre', $comment->comment_content); + + $comment->comment_author = format_to_edit( $comment->comment_author ); + $comment->comment_author_email = format_to_edit( $comment->comment_author_email ); + $comment->comment_author_url = format_to_edit( $comment->comment_author_url ); + $comment->comment_author_url = esc_url($comment->comment_author_url); + + return $comment; +} + +/** + * Get the number of pending comments on a post or posts + * + * @since 2.3.0 + * @uses $wpdb + * + * @param int|array $post_id Either a single Post ID or an array of Post IDs + * @return int|array Either a single Posts pending comments as an int or an array of ints keyed on the Post IDs + */ +function get_pending_comments_num( $post_id ) { + global $wpdb; + + $single = false; + if ( !is_array($post_id) ) { + $post_id_array = (array) $post_id; + $single = true; + } else { + $post_id_array = $post_id; + } + $post_id_array = array_map('intval', $post_id_array); + $post_id_in = "'" . implode("', '", $post_id_array) . "'"; + + $pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' GROUP BY comment_post_ID", ARRAY_A ); + + if ( $single ) { + if ( empty($pending) ) + return 0; + else + return absint($pending[0]['num_comments']); + } + + $pending_keyed = array(); + + // Default to zero pending for all posts in request + foreach ( $post_id_array as $id ) + $pending_keyed[$id] = 0; + + if ( !empty($pending) ) + foreach ( $pending as $pend ) + $pending_keyed[$pend['comment_post_ID']] = absint($pend['num_comments']); + + return $pending_keyed; +} + +/** + * Add avatars to relevant places in admin, or try to. + * + * @since 2.5.0 + * @uses $comment + * + * @param string $name User name. + * @return string Avatar with Admin name. + */ +function floated_admin_avatar( $name ) { + global $comment; + $avatar = get_avatar( $comment, 32 ); + return "$avatar $name"; +} + +function enqueue_comment_hotkeys_js() { + if ( 'true' == get_user_option( 'comment_shortcuts' ) ) + wp_enqueue_script( 'jquery-table-hotkeys' ); +} +?> diff --git a/src/wp-admin/includes/continents-cities.php b/src/wp-admin/includes/continents-cities.php new file mode 100644 index 00000000..0ebc4f3f --- /dev/null +++ b/src/wp-admin/includes/continents-cities.php @@ -0,0 +1,493 @@ + 5, + ); + } + $recent_comments_title = __( 'Recent Comments' ); + wp_add_dashboard_widget( 'dashboard_recent_comments', $recent_comments_title, 'wp_dashboard_recent_comments', 'wp_dashboard_recent_comments_control' ); + } + + // Incoming Links Widget + if ( is_blog_admin() && current_user_can('publish_posts') ) { + if ( !isset( $widget_options['dashboard_incoming_links'] ) || !isset( $widget_options['dashboard_incoming_links']['home'] ) || $widget_options['dashboard_incoming_links']['home'] != get_option('home') ) { + $update = true; + $num_items = isset($widget_options['dashboard_incoming_links']['items']) ? $widget_options['dashboard_incoming_links']['items'] : 10; + $widget_options['dashboard_incoming_links'] = array( + 'home' => get_option('home'), + 'link' => apply_filters( 'dashboard_incoming_links_link', 'http://blogsearch.google.com/blogsearch?scoring=d&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ), + 'url' => isset($widget_options['dashboard_incoming_links']['url']) ? apply_filters( 'dashboard_incoming_links_feed', $widget_options['dashboard_incoming_links']['url'] ) : apply_filters( 'dashboard_incoming_links_feed', 'http://blogsearch.google.com/blogsearch_feeds?scoring=d&ie=utf-8&num=' . $num_items . '&output=rss&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ), + 'items' => $num_items, + 'show_date' => isset($widget_options['dashboard_incoming_links']['show_date']) ? $widget_options['dashboard_incoming_links']['show_date'] : false + ); + } + wp_add_dashboard_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_incoming_links', 'wp_dashboard_incoming_links_control' ); + } + + // WP Plugins Widget + if ( ( ! is_multisite() && is_blog_admin() && current_user_can( 'install_plugins' ) ) || ( is_network_admin() && current_user_can( 'manage_network_plugins' ) && current_user_can( 'install_plugins' ) ) ) + wp_add_dashboard_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_plugins' ); + + // QuickPress Widget + if ( is_blog_admin() && current_user_can('edit_posts') ) + wp_add_dashboard_widget( 'dashboard_quick_press', __( 'QuickPress' ), 'wp_dashboard_quick_press' ); + + // Recent Drafts + if ( is_blog_admin() && current_user_can('edit_posts') ) + wp_add_dashboard_widget( 'dashboard_recent_drafts', __('Recent Drafts'), 'wp_dashboard_recent_drafts' ); + + // Primary feed (Dev Blog) Widget + if ( !isset( $widget_options['dashboard_primary'] ) ) { + $update = true; + $widget_options['dashboard_primary'] = array( + 'link' => apply_filters( 'dashboard_primary_link', __( 'http://wordpress.org/news/' ) ), + 'url' => apply_filters( 'dashboard_primary_feed', __( 'http://wordpress.org/news/feed/' ) ), + 'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ), + 'items' => 2, + 'show_summary' => 1, + 'show_author' => 0, + 'show_date' => 1, + ); + } + wp_add_dashboard_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_primary', 'wp_dashboard_primary_control' ); + + // Secondary Feed (Planet) Widget + if ( !isset( $widget_options['dashboard_secondary'] ) ) { + $update = true; + $widget_options['dashboard_secondary'] = array( + 'link' => apply_filters( 'dashboard_secondary_link', __( 'http://planet.wordpress.org/' ) ), + 'url' => apply_filters( 'dashboard_secondary_feed', __( 'http://planet.wordpress.org/feed/' ) ), + 'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ), + 'items' => 5, + 'show_summary' => 0, + 'show_author' => 0, + 'show_date' => 0, + ); + } + wp_add_dashboard_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_secondary', 'wp_dashboard_secondary_control' ); + + // Hook to register new widgets + // Filter widget order + if ( is_network_admin() ) { + do_action( 'wp_network_dashboard_setup' ); + $dashboard_widgets = apply_filters( 'wp_network_dashboard_widgets', array() ); + } elseif ( is_user_admin() ) { + do_action( 'wp_user_dashboard_setup' ); + $dashboard_widgets = apply_filters( 'wp_user_dashboard_widgets', array() ); + } else { + do_action( 'wp_dashboard_setup' ); + $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', array() ); + } + + foreach ( $dashboard_widgets as $widget_id ) { + $name = empty( $wp_registered_widgets[$widget_id]['all_link'] ) ? $wp_registered_widgets[$widget_id]['name'] : $wp_registered_widgets[$widget_id]['name'] . " " . __('View all') . ''; + wp_add_dashboard_widget( $widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback'] ); + } + + if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) { + ob_start(); // hack - but the same hack wp-admin/widgets.php uses + wp_dashboard_trigger_widget_control( $_POST['widget_id'] ); + ob_end_clean(); + wp_redirect( remove_query_arg( 'edit' ) ); + exit; + } + + if ( $update ) + update_option( 'dashboard_widget_options', $widget_options ); + + do_action('do_meta_boxes', $screen->id, 'normal', ''); + do_action('do_meta_boxes', $screen->id, 'side', ''); +} + +function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null ) { + $screen = get_current_screen(); + global $wp_dashboard_control_callbacks; + + if ( $control_callback && current_user_can( 'edit_dashboard' ) && is_callable( $control_callback ) ) { + $wp_dashboard_control_callbacks[$widget_id] = $control_callback; + if ( isset( $_GET['edit'] ) && $widget_id == $_GET['edit'] ) { + list($url) = explode( '#', add_query_arg( 'edit', false ), 2 ); + $widget_name .= ' ' . __( 'Cancel' ) . ''; + $callback = '_wp_dashboard_control_callback'; + } else { + list($url) = explode( '#', add_query_arg( 'edit', $widget_id ), 2 ); + $widget_name .= ' ' . __( 'Configure' ) . ''; + } + } + + if ( is_blog_admin () ) + $side_widgets = array('dashboard_quick_press', 'dashboard_recent_drafts', 'dashboard_primary', 'dashboard_secondary'); + else if (is_network_admin() ) + $side_widgets = array('dashboard_primary', 'dashboard_secondary'); + else + $side_widgets = array(); + + $location = 'normal'; + if ( in_array($widget_id, $side_widgets) ) + $location = 'side'; + add_meta_box( $widget_id, $widget_name , $callback, $screen->id, $location, 'core' ); +} + +function _wp_dashboard_control_callback( $dashboard, $meta_box ) { + echo '
'; + wp_dashboard_trigger_widget_control( $meta_box['id'] ); + echo ''; + submit_button( __('Submit') ); + echo '
'; +} + +/** + * Displays the dashboard. + * + * @since 2.5.0 + */ +function wp_dashboard() { + global $screen_layout_columns; + + $screen = get_current_screen(); + + $hide2 = $hide3 = $hide4 = ''; + switch ( $screen_layout_columns ) { + case 4: + $width = 'width:24.5%;'; + break; + case 3: + $width = 'width:32.67%;'; + $hide4 = 'display:none;'; + break; + case 2: + $width = 'width:49%;'; + $hide3 = $hide4 = 'display:none;'; + break; + default: + $width = 'width:98%;'; + $hide2 = $hide3 = $hide4 = 'display:none;'; + } +?> +
+\n"; + do_meta_boxes( $screen->id, 'normal', '' ); + + echo "\t
\n"; + do_meta_boxes( $screen->id, 'side', '' ); + + echo "\t
\n"; + do_meta_boxes( $screen->id, 'column3', '' ); + + echo "\t
\n"; + do_meta_boxes( $screen->id, 'column4', '' ); +?> +
+ +
+

+ +

+
+ +'; + echo "\n\t".'

' . __('Content') . '

'."\n\t".''; + echo "\n\t".''; + + // Posts + $num = number_format_i18n( $num_posts->publish ); + $text = _n( 'Post', 'Posts', intval($num_posts->publish) ); + if ( current_user_can( 'edit_posts' ) ) { + $num = "$num"; + $text = "$text"; + } + echo ''; + echo ''; + + echo ''; + /* TODO: Show status breakdown on hover + if ( $can_edit_pages && !empty($num_pages->publish) ) { // how many pages is not exposed in feeds. Don't show if !current_user_can + $post_type_texts[] = ''.sprintf( _n( '%s page', '%s pages', $num_pages->publish ), number_format_i18n( $num_pages->publish ) ).''; + } + if ( $can_edit_posts && !empty($num_posts->draft) ) { + $post_type_texts[] = ''.sprintf( _n( '%s draft', '%s drafts', $num_posts->draft ), number_format_i18n( $num_posts->draft ) ).''; + } + if ( $can_edit_posts && !empty($num_posts->future) ) { + $post_type_texts[] = ''.sprintf( _n( '%s scheduled post', '%s scheduled posts', $num_posts->future ), number_format_i18n( $num_posts->future ) ).''; + } + if ( current_user_can('publish_posts') && !empty($num_posts->pending) ) { + $pending_text = sprintf( _n( 'There is %2$s post pending your review.', 'There are %2$s posts pending your review.', $num_posts->pending ), 'edit.php?post_status=pending', number_format_i18n( $num_posts->pending ) ); + } else { + $pending_text = ''; + } + */ + + // Pages + $num = number_format_i18n( $num_pages->publish ); + $text = _n( 'Page', 'Pages', $num_pages->publish ); + if ( current_user_can( 'edit_pages' ) ) { + $num = "$num"; + $text = "$text"; + } + echo ''; + echo ''; + + echo ''; + + // Categories + $num = number_format_i18n( $num_cats ); + $text = _n( 'Category', 'Categories', $num_cats ); + if ( current_user_can( 'manage_categories' ) ) { + $num = "$num"; + $text = "$text"; + } + echo ''; + echo ''; + + echo ''; + + // Tags + $num = number_format_i18n( $num_tags ); + $text = _n( 'Tag', 'Tags', $num_tags ); + if ( current_user_can( 'manage_categories' ) ) { + $num = "$num"; + $text = "$text"; + } + echo ''; + echo ''; + + echo ""; + do_action('right_now_content_table_end'); + echo "\n\t
' . $num . '' . $text . '
' . $num . '' . $text . '
' . $num . '' . $text . '
' . $num . '' . $text . '
\n\t
"; + + + echo "\n\t".'
'; + echo "\n\t".'

' . __('Discussion') . '

'."\n\t".''; + echo "\n\t".''; + + // Total Comments + $num = '' . number_format_i18n($num_comm->total_comments) . ''; + $text = _n( 'Comment', 'Comments', $num_comm->total_comments ); + if ( current_user_can( 'moderate_comments' ) ) { + $num = '' . $num . ''; + $text = '' . $text . ''; + } + echo ''; + echo ''; + + echo ''; + + // Approved Comments + $num = '' . number_format_i18n($num_comm->approved) . ''; + $text = _nx( 'Approved', 'Approved', $num_comm->approved, 'Right Now' ); + if ( current_user_can( 'moderate_comments' ) ) { + $num = "$num"; + $text = "$text"; + } + echo ''; + echo ''; + + echo "\n\t"; + + // Pending Comments + $num = '' . number_format_i18n($num_comm->moderated) . ''; + $text = _n( 'Pending', 'Pending', $num_comm->moderated ); + if ( current_user_can( 'moderate_comments' ) ) { + $num = "$num"; + $text = "$text"; + } + echo ''; + echo ''; + + echo "\n\t"; + + // Spam Comments + $num = number_format_i18n($num_comm->spam); + $text = _nx( 'Spam', 'Spam', $num_comm->spam, 'comment' ); + if ( current_user_can( 'moderate_comments' ) ) { + $num = "$num"; + $text = "$text"; + } + echo ''; + echo ''; + + echo ""; + do_action('right_now_table_end'); + do_action('right_now_discussion_table_end'); + echo "\n\t
' . $num . '' . $text . '
' . $num . '' . $text . '
' . $num . '' . $text . '
' . $num . '' . $text . '
\n\t
"; + + echo "\n\t".'
'; + $ct = current_theme_info(); + + echo "\n\t

"; + if ( !empty($wp_registered_sidebars) ) { + $sidebars_widgets = wp_get_sidebars_widgets(); + $num_widgets = 0; + foreach ( (array) $sidebars_widgets as $k => $v ) { + if ( 'wp_inactive_widgets' == $k ) + continue; + if ( is_array($v) ) + $num_widgets = $num_widgets + count($v); + } + $num = number_format_i18n( $num_widgets ); + + $switch_themes = $ct->title; + if ( current_user_can( 'switch_themes') ) { + echo '' . __('Change Theme') . ''; + $switch_themes = '' . $switch_themes . ''; + } + if ( current_user_can( 'edit_theme_options' ) ) { + printf(_n('Theme %1$s with %2$s Widget', 'Theme %1$s with %2$s Widgets', $num_widgets), $switch_themes, $num); + } else { + printf(_n('Theme %1$s with %2$s Widget', 'Theme %1$s with %2$s Widgets', $num_widgets), $switch_themes, $num); + } + } else { + if ( current_user_can( 'switch_themes' ) ) { + echo '' . __('Change Theme') . ''; + printf( __('Theme %1$s'), $ct->title ); + } else { + printf( __('Theme %1$s'), $ct->title ); + } + } + echo '

'; + + update_right_now_message(); + + echo "\n\t".'
'; + do_action( 'rightnow_end' ); + do_action( 'activity_box_end' ); +} + +function wp_network_dashboard_right_now() { + $actions = array(); + if ( current_user_can('create_sites') ) + $actions['create-site'] = '' . __( 'Create a New Site' ) . ''; + if ( current_user_can('create_users') ) + $actions['create-user'] = '' . __( 'Create a New User' ) . ''; + + $c_users = get_user_count(); + $c_blogs = get_blog_count(); + + $user_text = sprintf( _n( '%s user', '%s users', $c_users ), number_format_i18n( $c_users ) ); + $blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs ), number_format_i18n( $c_blogs ) ); + + $sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text ); + + if ( $actions ) { + echo '
    '; + foreach ( $actions as $class => $action ) { + $actions[ $class ] = "\t
  • $action"; + } + echo implode( " |
  • \n", $actions ) . "\n"; + echo '
'; + } +?> +
+ +

+ + +
+

+ + 'submit_users' ) ); ?> +

+
+ +
+

+ + 'submit_sites' ) ); ?> +

+
+

' . __( 'Post published. View post | Edit post' ) . '

', esc_url( $view ), $edit ); + else + printf( '

' . __( 'Post submitted. Preview post | Edit post' ) . '

', esc_url( add_query_arg( 'preview', 1, $view ) ), $edit ); + } else { + printf( '

' . __( 'Draft saved. Preview post | Edit post' ) . '

', esc_url( add_query_arg( 'preview', 1, $view ) ), $edit ); + $drafts_query = new WP_Query( array( + 'post_type' => 'post', + 'post_status' => 'draft', + 'author' => $GLOBALS['current_user']->ID, + 'posts_per_page' => 1, + 'orderby' => 'modified', + 'order' => 'DESC' + ) ); + + if ( $drafts_query->posts ) + $drafts =& $drafts_query->posts; + } + printf('

' . __('You can also try %s, easy blogging from anywhere on the Web.') . '

', '' . __('Press This') . '' ); + $_REQUEST = array(); // hack for get_default_post_to_edit() + } + + /* Check if a new auto-draft (= no new post_ID) is needed or if the old can be used */ + $last_post_id = (int) get_user_option( 'dashboard_quick_press_last_post_id' ); // Get the last post_ID + if ( $last_post_id ) { + $post = get_post( $last_post_id ); + if ( empty( $post ) || $post->post_status != 'auto-draft' ) { // auto-draft doesn't exists anymore + $post = get_default_post_to_edit('post', true); + update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID + } else { + $post->post_title = ''; // Remove the auto draft title + } + } else { + $post = get_default_post_to_edit('post', true); + update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID + } + + $post_ID = (int) $post->ID; +?> + +
+

+
+ +
+ + +
+ +
+ + +

+
+ +
+ + + +

+
+ +
+ +

+ + + + + 'save-post', 'tabindex'=> 4 ) ); ?> + + + + + +
+

+ +
+ +' . __( 'Loading…' ) . '

' . __('This widget requires JavaScript.') . '

'; +} + +function wp_dashboard_recent_drafts( $drafts = false ) { + if ( !$drafts ) { + $drafts_query = new WP_Query( array( + 'post_type' => 'post', + 'post_status' => 'draft', + 'author' => $GLOBALS['current_user']->ID, + 'posts_per_page' => 5, + 'orderby' => 'modified', + 'order' => 'DESC' + ) ); + $drafts =& $drafts_query->posts; + } + + if ( $drafts && is_array( $drafts ) ) { + $list = array(); + foreach ( $drafts as $draft ) { + $url = get_edit_post_link( $draft->ID ); + $title = _draft_or_post_title( $draft->ID ); + $item = "

" . esc_html($title) . " " . get_the_time( get_option( 'date_format' ), $draft ) . '

'; + if ( $the_content = preg_split( '#\s#', strip_tags( $draft->post_content ), 11, PREG_SPLIT_NO_EMPTY ) ) + $item .= '

' . join( ' ', array_slice( $the_content, 0, 10 ) ) . ( 10 < count( $the_content ) ? '…' : '' ) . '

'; + $list[] = $item; + } +?> +
    +
  • \n
  • ", $list ); ?>
  • +
+

+get_results( "SELECT * FROM $wpdb->comments c LEFT JOIN $wpdb->posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT $start, 50" ) ) { + + foreach ( $possible as $comment ) { + if ( count( $comments ) >= $total_items ) + break; + if ( in_array( $comment->comment_approved, $allowed_states ) && current_user_can( 'read_post', $comment->comment_post_ID ) ) + $comments[] = $comment; + } + + $start = $start + 50; + } + + if ( $comments ) : +?> + +
+ + +
+ + +

+ + +

+ +comment_post_ID ); + $comment_post_title = strip_tags(get_the_title( $comment->comment_post_ID )); + $comment_post_link = "$comment_post_title"; + $comment_link = '#'; + + $actions_string = ''; + if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) { + // preorder it: Approve | Reply | Edit | Spam | Trash + $actions = array( + 'approve' => '', 'unapprove' => '', + 'reply' => '', + 'edit' => '', + 'spam' => '', + 'trash' => '', 'delete' => '' + ); + + $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) ); + $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) ); + + $approve_url = esc_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" ); + $unapprove_url = esc_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" ); + $spam_url = esc_url( "comment.php?action=spamcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" ); + $trash_url = esc_url( "comment.php?action=trashcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" ); + $delete_url = esc_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" ); + + $actions['approve'] = "" . __( 'Approve' ) . ''; + $actions['unapprove'] = "" . __( 'Unapprove' ) . ''; + $actions['edit'] = "". __('Edit') . ''; + $actions['reply'] = '' . __('Reply') . ''; + $actions['spam'] = "" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . ''; + if ( !EMPTY_TRASH_DAYS ) + $actions['delete'] = "" . __('Delete Permanently') . ''; + else + $actions['trash'] = "" . _x('Trash', 'verb') . ''; + + $actions = apply_filters( 'comment_row_actions', array_filter($actions), $comment ); + + $i = 0; + foreach ( $actions as $action => $link ) { + ++$i; + ( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | '; + + // Reply and quickedit need a hide-if-no-js span + if ( 'reply' == $action || 'quickedit' == $action ) + $action .= ' hide-if-no-js'; + + $actions_string .= "$sep$link"; + } + } + +?> + +
comment_ID) ) ); ?>> + comment_type || 'comment' == $comment->comment_type ) : ?> + + + +
+

+ ' . get_comment_author_link() . '', $comment_post_link.' '.$comment_link, ' ' . __( '[Pending]' ) . '' ); ?> +

+ + comment_type ) : + case 'pingback' : + $type = __( 'Pingback' ); + break; + case 'trackback' : + $type = __( 'Trackback' ); + break; + default : + $type = ucwords( $comment->comment_type ); + endswitch; + $type = esc_html( $type ); + ?> +
+ +

$type", $comment_post_link." ".$comment_link ); ?>

+

+ + +

+

+
+
+'; + echo '

'; +} + +function wp_dashboard_incoming_links() { + echo '

' . __( 'Loading…' ) . '

' . __('This widget requires JavaScript.') . '

'; +} + +/** + * Display incoming links dashboard widget content. + * + * @since 2.5.0 + */ +function wp_dashboard_incoming_links_output() { + $widgets = get_option( 'dashboard_widget_options' ); + @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP ); + $rss = fetch_feed( $url ); + + if ( is_wp_error($rss) ) { + if ( is_admin() || current_user_can('manage_options') ) { + echo '

'; + printf(__('RSS Error: %s'), $rss->get_error_message()); + echo '

'; + } + return; + } + + if ( !$rss->get_item_quantity() ) { + echo '

' . __('This dashboard widget queries Google Blog Search so that when another blog links to your site it will show up here. It has found no incoming links… yet. It’s okay — there is no rush.') . "

\n"; + $rss->__destruct(); + unset($rss); + return; + } + + echo "
    \n"; + + if ( !isset($items) ) + $items = 10; + + foreach ( $rss->get_items(0, $items) as $item ) { + $publisher = ''; + $site_link = ''; + $link = ''; + $content = ''; + $date = ''; + $link = esc_url( strip_tags( $item->get_link() ) ); + + $author = $item->get_author(); + if ( $author ) { + $site_link = esc_url( strip_tags( $author->get_link() ) ); + + if ( !$publisher = esc_html( strip_tags( $author->get_name() ) ) ) + $publisher = __( 'Somebody' ); + } else { + $publisher = __( 'Somebody' ); + } + if ( $site_link ) + $publisher = "$publisher"; + else + $publisher = "$publisher"; + + $content = $item->get_content(); + $content = wp_html_excerpt($content, 50) . ' ...'; + + if ( $link ) + /* translators: incoming links feed, %1$s is other person, %3$s is content */ + $text = __( '%1$s linked here saying, "%3$s"' ); + else + /* translators: incoming links feed, %1$s is other person, %3$s is content */ + $text = __( '%1$s linked here saying, "%3$s"' ); + + if ( !empty($show_date) ) { + if ( !empty($show_author) || !empty($show_summary) ) + /* translators: incoming links feed, %4$s is the date */ + $text .= ' ' . __( 'on %4$s' ); + $date = esc_html( strip_tags( $item->get_date() ) ); + $date = strtotime( $date ); + $date = gmdate( get_option( 'date_format' ), $date ); + } + + echo "\t
  • " . sprintf( $text, $publisher, $link, $content, $date ) . "
  • \n"; + } + + echo "
\n"; + $rss->__destruct(); + unset($rss); +} + +function wp_dashboard_incoming_links_control() { + wp_dashboard_rss_control( 'dashboard_incoming_links', array( 'title' => false, 'show_summary' => false, 'show_author' => false ) ); +} + +function wp_dashboard_primary() { + echo '

' . __( 'Loading…' ) . '

' . __('This widget requires JavaScript.') . '

'; +} + +function wp_dashboard_primary_control() { + wp_dashboard_rss_control( 'dashboard_primary' ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param string $widget_id + */ +function wp_dashboard_rss_output( $widget_id ) { + $widgets = get_option( 'dashboard_widget_options' ); + echo '
'; + wp_widget_rss_output( $widgets[$widget_id] ); + echo "
"; +} + +function wp_dashboard_secondary() { + echo '

' . __( 'Loading…' ) . '

' . __('This widget requires JavaScript.') . '

'; +} + +function wp_dashboard_secondary_control() { + wp_dashboard_rss_control( 'dashboard_secondary' ); +} + +/** + * Display secondary dashboard RSS widget feed. + * + * @since 2.5.0 + * + * @return unknown + */ +function wp_dashboard_secondary_output() { + $widgets = get_option( 'dashboard_widget_options' ); + @extract( @$widgets['dashboard_secondary'], EXTR_SKIP ); + $rss = @fetch_feed( $url ); + + if ( is_wp_error($rss) ) { + if ( is_admin() || current_user_can('manage_options') ) { + echo '

'; + printf(__('RSS Error: %s'), $rss->get_error_message()); + echo '

'; + } + } elseif ( !$rss->get_item_quantity() ) { + $rss->__destruct(); + unset($rss); + return false; + } else { + echo '
'; + wp_widget_rss_output( $rss, $widgets['dashboard_secondary'] ); + echo '
'; + $rss->__destruct(); + unset($rss); + } +} + +function wp_dashboard_plugins() { + echo '

' . __( 'Loading…' ) . '

' . __('This widget requires JavaScript.') . '

'; +} + +/** + * Display plugins most popular, newest plugins, and recently updated widget text. + * + * @since 2.5.0 + */ +function wp_dashboard_plugins_output() { + $popular = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/popular/' ); + $new = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/new/' ); + $updated = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/updated/' ); + + if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) { + $plugin_slugs = array_keys( get_plugins() ); + set_transient( 'plugin_slugs', $plugin_slugs, 86400 ); + } + + foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) { + if ( is_wp_error($$feed) || !$$feed->get_item_quantity() ) + continue; + + $items = $$feed->get_items(0, 5); + + // Pick a random, non-installed plugin + while ( true ) { + // Abort this foreach loop iteration if there's no plugins left of this type + if ( 0 == count($items) ) + continue 2; + + $item_key = array_rand($items); + $item = $items[$item_key]; + + list($link, $frag) = explode( '#', $item->get_link() ); + + $link = esc_url($link); + if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) ) + $slug = $matches[1]; + else { + unset( $items[$item_key] ); + continue; + } + + // Is this random plugin's slug already installed? If so, try again. + reset( $plugin_slugs ); + foreach ( $plugin_slugs as $plugin_slug ) { + if ( $slug == substr( $plugin_slug, 0, strlen( $slug ) ) ) { + unset( $items[$item_key] ); + continue 2; + } + } + + // If we get to this point, then the random plugin isn't installed and we can stop the while(). + break; + } + + // Eliminate some common badly formed plugin descriptions + while ( ( null !== $item_key = array_rand($items) ) && false !== strpos( $items[$item_key]->get_description(), 'Plugin Name:' ) ) + unset($items[$item_key]); + + if ( !isset($items[$item_key]) ) + continue; + + // current bbPress feed item titles are: user on "topic title" + if ( preg_match( '/"(.*)"/s', $item->get_title(), $matches ) ) + $title = $matches[1]; + else // but let's make it forward compatible if things change + $title = $item->get_title(); + $title = esc_html( $title ); + + $description = esc_html( strip_tags(@html_entity_decode($item->get_description(), ENT_QUOTES, get_option('blog_charset'))) ); + + $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) . + '&TB_iframe=true&width=600&height=800'; + + echo "

$label

\n"; + echo "
$title
 (" . __( 'Install' ) . ")\n"; + echo "

$description

\n"; + + $$feed->__destruct(); + unset($$feed); + } +} + +/** + * Checks to see if all of the feed url in $check_urls are cached. + * + * If $check_urls is empty, look for the rss feed url found in the dashboard + * widget optios of $widget_id. If cached, call $callback, a function that + * echoes out output for this widget. If not cache, echo a "Loading..." stub + * which is later replaced by AJAX call (see top of /wp-admin/index.php) + * + * @since 2.5.0 + * + * @param string $widget_id + * @param callback $callback + * @param array $check_urls RSS feeds + * @return bool False on failure. True on success. + */ +function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) { + $loading = '

' . __( 'Loading…' ) . '

'; + + if ( empty($check_urls) ) { + $widgets = get_option( 'dashboard_widget_options' ); + if ( empty($widgets[$widget_id]['url']) ) { + echo $loading; + return false; + } + $check_urls = array( $widgets[$widget_id]['url'] ); + } + + include_once ABSPATH . WPINC . '/class-feed.php'; + foreach ( $check_urls as $check_url ) { + $cache = new WP_Feed_Cache_Transient('', md5($check_url), ''); + if ( ! $cache->load() ) { + echo $loading; + return false; + } + } + + if ( $callback && is_callable( $callback ) ) { + $args = array_slice( func_get_args(), 2 ); + array_unshift( $args, $widget_id ); + call_user_func_array( $callback, $args ); + } + + return true; +} + +/* Dashboard Widgets Controls */ + +// Calls widget_control callback +/** + * Calls widget control callback. + * + * @since 2.5.0 + * + * @param int $widget_control_id Registered Widget ID. + */ +function wp_dashboard_trigger_widget_control( $widget_control_id = false ) { + global $wp_dashboard_control_callbacks; + + if ( is_scalar($widget_control_id) && $widget_control_id && isset($wp_dashboard_control_callbacks[$widget_control_id]) && is_callable($wp_dashboard_control_callbacks[$widget_control_id]) ) { + call_user_func( $wp_dashboard_control_callbacks[$widget_control_id], '', array( 'id' => $widget_control_id, 'callback' => $wp_dashboard_control_callbacks[$widget_control_id] ) ); + } +} + +/** + * The RSS dashboard widget control. + * + * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data + * from RSS-type widgets. + * + * @since 2.5.0 + * + * @param string $widget_id + * @param array $form_inputs + */ +function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) { + if ( !$widget_options = get_option( 'dashboard_widget_options' ) ) + $widget_options = array(); + + if ( !isset($widget_options[$widget_id]) ) + $widget_options[$widget_id] = array(); + + $number = 1; // Hack to use wp_widget_rss_form() + $widget_options[$widget_id]['number'] = $number; + + if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) { + $_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] ); + $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] ); + // title is optional. If black, fill it if possible + if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) { + $rss = fetch_feed($widget_options[$widget_id]['url']); + if ( is_wp_error($rss) ) { + $widget_options[$widget_id]['title'] = htmlentities(__('Unknown Feed')); + } else { + $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->get_title())); + $rss->__destruct(); + unset($rss); + } + } + update_option( 'dashboard_widget_options', $widget_options ); + } + + wp_widget_rss_form( $widget_options[$widget_id], $form_inputs ); +} + +// Display File upload quota on dashboard +function wp_dashboard_quota() { + if ( !is_multisite() || !current_user_can('edit_posts') || get_site_option( 'upload_space_check_disabled' ) ) + return true; + + $quota = get_space_allowed(); + $used = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024; + + if ( $used > $quota ) + $percentused = '100'; + else + $percentused = ( $used / $quota ) * 100; + $used_color = ( $percentused < 70 ) ? ( ( $percentused >= 40 ) ? 'waiting' : 'approved' ) : 'spam'; + $used = round( $used, 2 ); + $percentused = number_format( $percentused ); + + ?> +

+
+ + + + + +
%2$sMB' ), esc_url( admin_url( 'upload.php' ) ), $quota ); ?>
+
+
+ + + + + +
%2$sMB (%3$s%%)' ), esc_url( admin_url( 'upload.php' ) ), $used, $percentused ); ?>
+
+
+ diff --git a/src/wp-admin/includes/deprecated.php b/src/wp-admin/includes/deprecated.php new file mode 100644 index 00000000..b91c64fc --- /dev/null +++ b/src/wp-admin/includes/deprecated.php @@ -0,0 +1,690 @@ + 0) ); + + if ( $categories ) { + foreach ( $categories as $category ) { + if ( $currentcat != $category->term_id && $parent == $category->parent) { + $pad = str_repeat( '– ', $level ); + $category->name = esc_html( $category->name ); + echo "\n\t"; + wp_dropdown_cats( $currentcat, $currentparent, $category->term_id, $level +1, $categories ); + } + } + } else { + return false; + } +} + +/** + * Register a setting and its sanitization callback + * + * @since 2.7.0 + * @deprecated 3.0.0 + * @deprecated Use register_setting() + * @see register_setting() + * + * @param string $option_group A settings group name. Should correspond to a whitelisted option key name. + * Default whitelisted option key names include "general," "discussion," and "reading," among others. + * @param string $option_name The name of an option to sanitize and save. + * @param unknown_type $sanitize_callback A callback function that sanitizes the option's value. + * @return unknown + */ +function add_option_update_handler( $option_group, $option_name, $sanitize_callback = '' ) { + _deprecated_function( __FUNCTION__, '3.0', 'register_setting()' ); + return register_setting( $option_group, $option_name, $sanitize_callback ); +} + +/** + * Unregister a setting + * + * @since 2.7.0 + * @deprecated 3.0.0 + * @deprecated Use unregister_setting() + * @see unregister_setting() + * + * @param unknown_type $option_group + * @param unknown_type $option_name + * @param unknown_type $sanitize_callback + * @return unknown + */ +function remove_option_update_handler( $option_group, $option_name, $sanitize_callback = '' ) { + _deprecated_function( __FUNCTION__, '3.0', 'unregister_setting()' ); + return unregister_setting( $option_group, $option_name, $sanitize_callback ); +} + +/** + * Determines the language to use for CodePress syntax highlighting. + * + * @since 2.8.0 + * @deprecated 3.0.0 + * + * @param string $filename +**/ +function codepress_get_lang( $filename ) { + _deprecated_function( __FUNCTION__, '3.0' ); + return; +} + +/** + * Adds Javascript required to make CodePress work on the theme/plugin editors. + * + * @since 2.8.0 + * @deprecated 3.0.0 +**/ +function codepress_footer_js() { + _deprecated_function( __FUNCTION__, '3.0' ); + return; +} + +/** + * Determine whether to use CodePress. + * + * @since 2.8 + * @deprecated 3.0.0 +**/ +function use_codepress() { + _deprecated_function( __FUNCTION__, '3.0' ); + return; +} + + +/** + * @deprecated 3.1.0 + * + * @return array List of user IDs. + */ +function get_author_user_ids() { + _deprecated_function( __FUNCTION__, '3.1', 'get_users()' ); + + global $wpdb; + if ( !is_multisite() ) + $level_key = $wpdb->get_blog_prefix() . 'user_level'; + else + $level_key = $wpdb->get_blog_prefix() . 'capabilities'; // wpmu site admins don't have user_levels + + return $wpdb->get_col( $wpdb->prepare("SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s AND meta_value != '0'", $level_key) ); +} + +/** + * @deprecated 3.1.0 + * + * @param int $user_id User ID. + * @return array|bool List of editable authors. False if no editable users. + */ +function get_editable_authors( $user_id ) { + _deprecated_function( __FUNCTION__, '3.1', 'get_users()' ); + + global $wpdb; + + $editable = get_editable_user_ids( $user_id ); + + if ( !$editable ) { + return false; + } else { + $editable = join(',', $editable); + $authors = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE ID IN ($editable) ORDER BY display_name" ); + } + + return apply_filters('get_editable_authors', $authors); +} + +/** + * @deprecated 3.1.0 + * + * @param int $user_id User ID. + * @param bool $exclude_zeros Optional, default is true. Whether to exclude zeros. + * @return unknown + */ +function get_editable_user_ids( $user_id, $exclude_zeros = true, $post_type = 'post' ) { + _deprecated_function( __FUNCTION__, '3.1', 'get_users()' ); + + global $wpdb; + + $user = new WP_User( $user_id ); + $post_type_obj = get_post_type_object($post_type); + + if ( ! $user->has_cap($post_type_obj->cap->edit_others_posts) ) { + if ( $user->has_cap($post_type_obj->cap->edit_posts) || ! $exclude_zeros ) + return array($user->id); + else + return array(); + } + + if ( !is_multisite() ) + $level_key = $wpdb->get_blog_prefix() . 'user_level'; + else + $level_key = $wpdb->get_blog_prefix() . 'capabilities'; // wpmu site admins don't have user_levels + + $query = $wpdb->prepare("SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s", $level_key); + if ( $exclude_zeros ) + $query .= " AND meta_value != '0'"; + + return $wpdb->get_col( $query ); +} + +/** + * @deprecated 3.1.0 + */ +function get_nonauthor_user_ids() { + _deprecated_function( __FUNCTION__, '3.1', 'get_users()' ); + + global $wpdb; + + if ( !is_multisite() ) + $level_key = $wpdb->get_blog_prefix() . 'user_level'; + else + $level_key = $wpdb->get_blog_prefix() . 'capabilities'; // wpmu site admins don't have user_levels + + return $wpdb->get_col( $wpdb->prepare("SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s AND meta_value = '0'", $level_key) ); +} + +if ( !class_exists('WP_User_Search') ) : +/** + * WordPress User Search class. + * + * @since 2.1.0 + * @deprecated 3.1.0 + */ +class WP_User_Search { + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var unknown_type + */ + var $results; + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var unknown_type + */ + var $search_term; + + /** + * Page number. + * + * @since 2.1.0 + * @access private + * @var int + */ + var $page; + + /** + * Role name that users have. + * + * @since 2.5.0 + * @access private + * @var string + */ + var $role; + + /** + * Raw page number. + * + * @since 2.1.0 + * @access private + * @var int|bool + */ + var $raw_page; + + /** + * Amount of users to display per page. + * + * @since 2.1.0 + * @access public + * @var int + */ + var $users_per_page = 50; + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var unknown_type + */ + var $first_user; + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var int + */ + var $last_user; + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var string + */ + var $query_limit; + + /** + * {@internal Missing Description}} + * + * @since 3.0.0 + * @access private + * @var string + */ + var $query_orderby; + + /** + * {@internal Missing Description}} + * + * @since 3.0.0 + * @access private + * @var string + */ + var $query_from; + + /** + * {@internal Missing Description}} + * + * @since 3.0.0 + * @access private + * @var string + */ + var $query_where; + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var int + */ + var $total_users_for_query = 0; + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var bool + */ + var $too_many_total_users = false; + + /** + * {@internal Missing Description}} + * + * @since 2.1.0 + * @access private + * @var unknown_type + */ + var $search_errors; + + /** + * {@internal Missing Description}} + * + * @since 2.7.0 + * @access private + * @var unknown_type + */ + var $paging_text; + + /** + * PHP4 Constructor - Sets up the object properties. + * + * @since 2.1.0 + * + * @param string $search_term Search terms string. + * @param int $page Optional. Page ID. + * @param string $role Role name. + * @return WP_User_Search + */ + function WP_User_Search ($search_term = '', $page = '', $role = '') { + _deprecated_function( __FUNCTION__, '3.1', 'WP_User_Query' ); + + $this->search_term = $search_term; + $this->raw_page = ( '' == $page ) ? false : (int) $page; + $this->page = (int) ( '' == $page ) ? 1 : $page; + $this->role = $role; + + $this->prepare_query(); + $this->query(); + $this->prepare_vars_for_template_usage(); + $this->do_paging(); + } + + /** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * @access public + */ + function prepare_query() { + global $wpdb; + $this->first_user = ($this->page - 1) * $this->users_per_page; + + $this->query_limit = $wpdb->prepare(" LIMIT %d, %d", $this->first_user, $this->users_per_page); + $this->query_orderby = ' ORDER BY user_login'; + + $search_sql = ''; + if ( $this->search_term ) { + $searches = array(); + $search_sql = 'AND ('; + foreach ( array('user_login', 'user_nicename', 'user_email', 'user_url', 'display_name') as $col ) + $searches[] = $col . " LIKE '%$this->search_term%'"; + $search_sql .= implode(' OR ', $searches); + $search_sql .= ')'; + } + + $this->query_from = " FROM $wpdb->users"; + $this->query_where = " WHERE 1=1 $search_sql"; + + if ( $this->role ) { + $this->query_from .= " INNER JOIN $wpdb->usermeta ON $wpdb->users.ID = $wpdb->usermeta.user_id"; + $this->query_where .= $wpdb->prepare(" AND $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND $wpdb->usermeta.meta_value LIKE %s", '%' . $this->role . '%'); + } elseif ( is_multisite() ) { + $level_key = $wpdb->prefix . 'capabilities'; // wpmu site admins don't have user_levels + $this->query_from .= ", $wpdb->usermeta"; + $this->query_where .= " AND $wpdb->users.ID = $wpdb->usermeta.user_id AND meta_key = '{$level_key}'"; + } + + do_action_ref_array( 'pre_user_search', array( &$this ) ); + } + + /** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * @access public + */ + function query() { + global $wpdb; + + $this->results = $wpdb->get_col("SELECT DISTINCT($wpdb->users.ID)" . $this->query_from . $this->query_where . $this->query_orderby . $this->query_limit); + + if ( $this->results ) + $this->total_users_for_query = $wpdb->get_var("SELECT COUNT(DISTINCT($wpdb->users.ID))" . $this->query_from . $this->query_where); // no limit + else + $this->search_errors = new WP_Error('no_matching_users_found', __('No matching users were found!')); + } + + /** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * @access public + */ + function prepare_vars_for_template_usage() { + $this->search_term = stripslashes($this->search_term); // done with DB, from now on we want slashes gone + } + + /** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * @access public + */ + function do_paging() { + if ( $this->total_users_for_query > $this->users_per_page ) { // have to page the results + $args = array(); + if( ! empty($this->search_term) ) + $args['usersearch'] = urlencode($this->search_term); + if( ! empty($this->role) ) + $args['role'] = urlencode($this->role); + + $this->paging_text = paginate_links( array( + 'total' => ceil($this->total_users_for_query / $this->users_per_page), + 'current' => $this->page, + 'base' => 'users.php?%_%', + 'format' => 'userspage=%#%', + 'add_args' => $args + ) ); + if ( $this->paging_text ) { + $this->paging_text = sprintf( '' . __( 'Displaying %s–%s of %s' ) . '%s', + number_format_i18n( ( $this->page - 1 ) * $this->users_per_page + 1 ), + number_format_i18n( min( $this->page * $this->users_per_page, $this->total_users_for_query ) ), + number_format_i18n( $this->total_users_for_query ), + $this->paging_text + ); + } + } + } + + /** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * @access public + * + * @return unknown + */ + function get_results() { + return (array) $this->results; + } + + /** + * Displaying paging text. + * + * @see do_paging() Builds paging text. + * + * @since 2.1.0 + * @access public + */ + function page_links() { + echo $this->paging_text; + } + + /** + * Whether paging is enabled. + * + * @see do_paging() Builds paging text. + * + * @since 2.1.0 + * @access public + * + * @return bool + */ + function results_are_paged() { + if ( $this->paging_text ) + return true; + return false; + } + + /** + * Whether there are search terms. + * + * @since 2.1.0 + * @access public + * + * @return bool + */ + function is_search() { + if ( $this->search_term ) + return true; + return false; + } +} +endif; + +/** + * Retrieve editable posts from other users. + * + * @deprecated 3.1.0 + * + * @param int $user_id User ID to not retrieve posts from. + * @param string $type Optional, defaults to 'any'. Post type to retrieve, can be 'draft' or 'pending'. + * @return array List of posts from others. + */ +function get_others_unpublished_posts($user_id, $type='any') { + _deprecated_function( __FUNCTION__, '3.1' ); + + global $wpdb; + + $editable = get_editable_user_ids( $user_id ); + + if ( in_array($type, array('draft', 'pending')) ) + $type_sql = " post_status = '$type' "; + else + $type_sql = " ( post_status = 'draft' OR post_status = 'pending' ) "; + + $dir = ( 'pending' == $type ) ? 'ASC' : 'DESC'; + + if ( !$editable ) { + $other_unpubs = ''; + } else { + $editable = join(',', $editable); + $other_unpubs = $wpdb->get_results( $wpdb->prepare("SELECT ID, post_title, post_author FROM $wpdb->posts WHERE post_type = 'post' AND $type_sql AND post_author IN ($editable) AND post_author != %d ORDER BY post_modified $dir", $user_id) ); + } + + return apply_filters('get_others_drafts', $other_unpubs); +} + +/** + * Retrieve drafts from other users. + * + * @deprecated 3.1.0 + * + * @param int $user_id User ID. + * @return array List of drafts from other users. + */ +function get_others_drafts($user_id) { + _deprecated_function( __FUNCTION__, '3.1' ); + + return get_others_unpublished_posts($user_id, 'draft'); +} + +/** + * Retrieve pending review posts from other users. + * + * @deprecated 3.1.0 + * + * @param int $user_id User ID. + * @return array List of posts with pending review post type from other users. + */ +function get_others_pending($user_id) { + _deprecated_function( __FUNCTION__, '3.1' ); + + return get_others_unpublished_posts($user_id, 'pending'); +} diff --git a/src/wp-admin/includes/export.php b/src/wp-admin/includes/export.php new file mode 100644 index 00000000..2efd0405 --- /dev/null +++ b/src/wp-admin/includes/export.php @@ -0,0 +1,418 @@ + 'all', 'author' => false, 'category' => false, + 'start_date' => false, 'end_date' => false, 'status' => false, + ); + $args = wp_parse_args( $args, $defaults ); + + do_action( 'export_wp' ); + + $sitename = sanitize_key( get_bloginfo( 'name' ) ); + if ( ! empty($sitename) ) $sitename .= '.'; + $filename = $sitename . 'wordpress.' . date( 'Y-m-d' ) . '.xml'; + + header( 'Content-Description: File Transfer' ); + header( 'Content-Disposition: attachment; filename=' . $filename ); + header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true ); + + if ( 'all' != $args['content'] && post_type_exists( $args['content'] ) ) { + $ptype = get_post_type_object( $args['content'] ); + if ( ! $ptype->can_export ) + $args['content'] = 'post'; + + $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['content'] ); + } else { + $post_types = get_post_types( array( 'can_export' => true ) ); + $esses = array_fill( 0, count($post_types), '%s' ); + $where = $wpdb->prepare( "{$wpdb->posts}.post_type IN (". implode(',',$esses) .")", $post_types ); + } + + if ( $args['status'] && ( 'post' == $args['content'] || 'page' == $args['content'] ) ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status = %s", $args['status'] ); + else + $where .= " AND {$wpdb->posts}.post_status != 'auto-draft'"; + + $join = ''; + if ( $args['category'] && 'post' == $args['content'] ) { + if ( $term = term_exists( $args['category'], 'category' ) ) { + $join = "INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)"; + $where .= $wpdb->prepare( " AND {$wpdb->term_relationships}.term_taxonomy_id = %d", $term['term_taxonomy_id'] ); + } + } + + if ( 'post' == $args['content'] || 'page' == $args['content'] ) { + if ( $args['author'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); + + if ( $args['start_date'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime($args['start_date']) ) ); + + if ( $args['end_date'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime('+1 month', strtotime($args['end_date'])) ) ); + } + + // grab a snapshot of post IDs, just in case it changes during the export + $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" ); + + // get the requested terms ready, empty unless posts filtered by category or all content + $cats = $tags = $terms = array(); + if ( isset( $term ) && $term ) { + $cat = get_term( $term['term_id'], 'category' ); + $cats = array( $cat->term_id => $cat ); + unset( $term, $cat ); + } else if ( 'all' == $args['content'] ) { + $categories = (array) get_categories( array( 'get' => 'all' ) ); + $tags = (array) get_tags( array( 'get' => 'all' ) ); + + $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) ); + $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) ); + + // put categories in order with no child going before its parent + while ( $cat = array_shift( $categories ) ) { + if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) ) + $cats[$cat->term_id] = $cat; + else + $categories[] = $cat; + } + + // put terms in order with no child going before its parent + while ( $t = array_shift( $custom_terms ) ) { + if ( $t->parent == 0 || isset( $terms[$t->parent] ) ) + $terms[$t->term_id] = $t; + else + $custom_terms[] = $t; + } + + unset( $categories, $custom_taxonomies, $custom_terms ); + } + + /** + * Wrap given string in XML CDATA tag. + * + * @since 2.1.0 + * + * @param string $str String to wrap in XML CDATA tag. + */ + function wxr_cdata( $str ) { + if ( seems_utf8( $str ) == false ) + $str = utf8_encode( $str ); + + // $str = ent2ncr(esc_html($str)); + $str = ""; + + return $str; + } + + /** + * Return the URL of the site + * + * @since 2.5.0 + * + * @return string Site URL. + */ + function wxr_site_url() { + // ms: the base url + if ( is_multisite() ) + return network_home_url(); + // wp: the blog url + else + return get_bloginfo_rss( 'url' ); + } + + /** + * Output a cat_name XML tag from a given category object + * + * @since 2.1.0 + * + * @param object $category Category Object + */ + function wxr_cat_name( $category ) { + if ( empty( $category->name ) ) + return; + + echo '' . wxr_cdata( $category->name ) . ''; + } + + /** + * Output a category_description XML tag from a given category object + * + * @since 2.1.0 + * + * @param object $category Category Object + */ + function wxr_category_description( $category ) { + if ( empty( $category->description ) ) + return; + + echo '' . wxr_cdata( $category->description ) . ''; + } + + /** + * Output a tag_name XML tag from a given tag object + * + * @since 2.3.0 + * + * @param object $tag Tag Object + */ + function wxr_tag_name( $tag ) { + if ( empty( $tag->name ) ) + return; + + echo '' . wxr_cdata( $tag->name ) . ''; + } + + /** + * Output a tag_description XML tag from a given tag object + * + * @since 2.3.0 + * + * @param object $tag Tag Object + */ + function wxr_tag_description( $tag ) { + if ( empty( $tag->description ) ) + return; + + echo '' . wxr_cdata( $tag->description ) . ''; + } + + /** + * Output a term_name XML tag from a given term object + * + * @since 2.9.0 + * + * @param object $term Term Object + */ + function wxr_term_name( $term ) { + if ( empty( $term->name ) ) + return; + + echo '' . wxr_cdata( $term->name ) . ''; + } + + /** + * Output a term_description XML tag from a given term object + * + * @since 2.9.0 + * + * @param object $term Term Object + */ + function wxr_term_description( $term ) { + if ( empty( $term->description ) ) + return; + + echo '' . wxr_cdata( $term->description ) . ''; + } + + /** + * Output list of authors with posts + * + * @since 3.1.0 + */ + function wxr_authors_list() { + global $wpdb; + + $authors = array(); + $results = $wpdb->get_results( "SELECT DISTINCT post_author FROM $wpdb->posts" ); + foreach ( (array) $results as $result ) + $authors[] = get_userdata( $result->post_author ); + + $authors = array_filter( $authors ); + + foreach( $authors as $author ) { + echo "\t"; + echo '' . $author->ID . ''; + echo '' . $author->user_login . ''; + echo '' . $author->user_email . ''; + echo '' . wxr_cdata( $author->display_name ) . ''; + echo '' . wxr_cdata( $author->user_firstname ) . ''; + echo '' . wxr_cdata( $author->user_lastname ) . ''; + echo "\n"; + } + } + + /** + * Ouput all navigation menu terms + * + * @since 3.1.0 + */ + function wxr_nav_menu_terms() { + $nav_menus = wp_get_nav_menus(); + if ( empty( $nav_menus ) || ! is_array( $nav_menus ) ) + return; + + foreach ( $nav_menus as $menu ) { + echo "\t{$menu->term_id}nav_menu{$menu->slug}"; + wxr_term_name( $menu ); + echo "\n"; + } + } + + /** + * Output list of taxonomy terms, in XML tag format, associated with a post + * + * @since 2.3.0 + */ + function wxr_post_taxonomy() { + global $post; + + $taxonomies = get_object_taxonomies( $post->post_type ); + if ( empty( $taxonomies ) ) + return; + $terms = wp_get_object_terms( $post->ID, $taxonomies ); + + foreach ( (array) $terms as $term ) { + echo "\t\ttaxonomy}\" nicename=\"{$term->slug}\">" . wxr_cdata( $term->name ) . "\n"; + } + } + + echo '\n"; + + ?> + + + + + + + + + + + + + + + + + + + + + + <?php bloginfo_rss( 'name' ); ?> + + + + + + + + + + + + term_id ?>slug; ?>parent ? $cats[$c->parent]->slug : ''; ?> + + + term_id ?>slug; ?> + + + term_id ?>taxonomy; ?>slug; ?>parent ? $terms[$t->parent]->slug : ''; ?> + + + + + +in_the_loop = true; // Fake being in the loop. + + // fetch 20 posts at a time rather than loading the entire table into memory + while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) { + $where = "WHERE ID IN (" . join( ',', $next_posts ) . ")"; + $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" ); + + // Begin Loop + foreach ( $posts as $post ) { + setup_postdata( $post ); + $is_sticky = is_sticky( $post->ID ) ? 1 : 0; +?> + + <?php echo apply_filters( 'the_title_rss', $post->post_title ); ?> + + + + + + post_content ) ); ?> + post_excerpt ) ); ?> + ID; ?> + post_date; ?> + post_date_gmt; ?> + comment_status; ?> + ping_status; ?> + post_name; ?> + post_status; ?> + post_parent; ?> + menu_order; ?> + post_type; ?> + post_password; ?> + +post_type == 'attachment' ) : ?> + ID ); ?> + + +get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) ); + if ( $postmeta ) : foreach( $postmeta as $meta ) : if ( $meta->meta_key != '_edit_lock' ) : ?> + + meta_key; ?> + meta_value ); ?> + + +get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) ); + if ( $comments ) : foreach ( $comments as $c ) : ?> + + comment_ID; ?> + comment_author ); ?> + comment_author_email; ?> + comment_author_url ); ?> + comment_author_IP; ?> + comment_date; ?> + comment_date_gmt; ?> + comment_content ) ?> + comment_approved; ?> + comment_type; ?> + comment_parent; ?> + user_id; ?> + + + + + + + __( 'Main Index Template' ), + 'style.css' => __( 'Stylesheet' ), + 'editor-style.css' => __( 'Visual Editor Stylesheet' ), + 'editor-style-rtl.css' => __( 'Visual Editor RTL Stylesheet' ), + 'rtl.css' => __( 'RTL Stylesheet' ), + 'comments.php' => __( 'Comments' ), + 'comments-popup.php' => __( 'Popup Comments' ), + 'footer.php' => __( 'Footer' ), + 'header.php' => __( 'Header' ), + 'sidebar.php' => __( 'Sidebar' ), + 'archive.php' => __( 'Archives' ), + 'author.php' => __( 'Author Template' ), + 'tag.php' => __( 'Tag Template' ), + 'category.php' => __( 'Category Template' ), + 'page.php' => __( 'Page Template' ), + 'search.php' => __( 'Search Results' ), + 'searchform.php' => __( 'Search Form' ), + 'single.php' => __( 'Single Post' ), + '404.php' => __( '404 Template' ), + 'link.php' => __( 'Links Template' ), + 'functions.php' => __( 'Theme Functions' ), + 'attachment.php' => __( 'Attachment Template' ), + 'image.php' => __('Image Attachment Template'), + 'video.php' => __('Video Attachment Template'), + 'audio.php' => __('Audio Attachment Template'), + 'application.php' => __('Application Attachment Template'), + 'my-hacks.php' => __( 'my-hacks.php (legacy hacks support)' ), + '.htaccess' => __( '.htaccess (for rewrite rules )' ), + // Deprecated files + 'wp-layout.css' => __( 'Stylesheet' ), + 'wp-comments.php' => __( 'Comments Template' ), + 'wp-comments-popup.php' => __( 'Popup Comments Template' ), +); + +/** + * Get the description for standard WordPress theme files and other various standard + * WordPress files + * + * @since 1.5.0 + * + * @uses _cleanup_header_comment + * @uses $wp_file_descriptions + * @param string $file Filesystem path or filename + * @return string Description of file from $wp_file_descriptions or basename of $file if description doesn't exist + */ +function get_file_description( $file ) { + global $wp_file_descriptions; + + if ( isset( $wp_file_descriptions[basename( $file )] ) ) { + return $wp_file_descriptions[basename( $file )]; + } + elseif ( file_exists( $file ) && is_file( $file ) ) { + $template_data = implode( '', file( $file ) ); + if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name )) + return sprintf( __( '%s Page Template' ), _cleanup_header_comment($name[1]) ); + } + + return basename( $file ); +} + +/** + * Get the absolute filesystem path to the root of the WordPress installation + * + * @since 1.5.0 + * + * @uses get_option + * @return string Full filesystem path to the root of the WordPress installation + */ +function get_home_path() { + $home = get_option( 'home' ); + $siteurl = get_option( 'siteurl' ); + if ( $home != '' && $home != $siteurl ) { + $wp_path_rel_to_home = str_replace($home, '', $siteurl); /* $siteurl - $home */ + $pos = strpos($_SERVER["SCRIPT_FILENAME"], $wp_path_rel_to_home); + $home_path = substr($_SERVER["SCRIPT_FILENAME"], 0, $pos); + $home_path = trailingslashit( $home_path ); + } else { + $home_path = ABSPATH; + } + + return $home_path; +} + +/** + * Get the real file system path to a file to edit within the admin + * + * If the $file is index.php or .htaccess this function will assume it is relative + * to the install root, otherwise it is assumed the file is relative to the wp-content + * directory + * + * @since 1.5.0 + * + * @uses get_home_path + * @uses WP_CONTENT_DIR full filesystem path to the wp-content directory + * @param string $file filesystem path relative to the WordPress install directory or to the wp-content directory + * @return string full file system path to edit + */ +function get_real_file_to_edit( $file ) { + if ('index.php' == $file || '.htaccess' == $file ) { + $real_file = get_home_path() . $file; + } else { + $real_file = WP_CONTENT_DIR . $file; + } + + return $real_file; +} + +/** + * Returns a listing of all files in the specified folder and all subdirectories up to 100 levels deep. + * The depth of the recursiveness can be controlled by the $levels param. + * + * @since 2.6.0 + * + * @param string $folder Full path to folder + * @param int $levels (optional) Levels of folders to follow, Default: 100 (PHP Loop limit). + * @return bool|array False on failure, Else array of files + */ +function list_files( $folder = '', $levels = 100 ) { + if ( empty($folder) ) + return false; + + if ( ! $levels ) + return false; + + $files = array(); + if ( $dir = @opendir( $folder ) ) { + while (($file = readdir( $dir ) ) !== false ) { + if ( in_array($file, array('.', '..') ) ) + continue; + if ( is_dir( $folder . '/' . $file ) ) { + $files2 = list_files( $folder . '/' . $file, $levels - 1); + if ( $files2 ) + $files = array_merge($files, $files2 ); + else + $files[] = $folder . '/' . $file . '/'; + } else { + $files[] = $folder . '/' . $file; + } + } + } + @closedir( $dir ); + return $files; +} + +/** + * Determines a writable directory for temporary files. + * Function's preference is to WP_CONTENT_DIR followed by the return value of sys_get_temp_dir(), before finally defaulting to /tmp/ + * + * In the event that this function does not find a writable location, It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file. + * + * @since 2.5.0 + * + * @return string Writable temporary directory + */ +function get_temp_dir() { + static $temp; + if ( defined('WP_TEMP_DIR') ) + return trailingslashit(WP_TEMP_DIR); + + if ( $temp ) + return trailingslashit($temp); + + $temp = WP_CONTENT_DIR . '/'; + if ( is_dir($temp) && @is_writable($temp) ) + return $temp; + + if ( function_exists('sys_get_temp_dir') ) { + $temp = sys_get_temp_dir(); + if ( @is_writable($temp) ) + return trailingslashit($temp); + } + + $temp = ini_get('upload_tmp_dir'); + if ( is_dir($temp) && @is_writable($temp) ) + return trailingslashit($temp); + + $temp = '/tmp/'; + return $temp; +} + +/** + * Returns a filename of a Temporary unique file. + * Please note that the calling function must unlink() this itself. + * + * The filename is based off the passed parameter or defaults to the current unix timestamp, + * while the directory can either be passed as well, or by leaving it blank, default to a writable temporary directory. + * + * @since 2.6.0 + * + * @param string $filename (optional) Filename to base the Unique file off + * @param string $dir (optional) Directory to store the file in + * @return string a writable filename + */ +function wp_tempnam($filename = '', $dir = '') { + if ( empty($dir) ) + $dir = get_temp_dir(); + $filename = basename($filename); + if ( empty($filename) ) + $filename = time(); + + $filename = preg_replace('|\..*$|', '.tmp', $filename); + $filename = $dir . wp_unique_filename($dir, $filename); + touch($filename); + return $filename; +} + +/** + * Make sure that the file that was requested to edit, is allowed to be edited + * + * Function will die if if you are not allowed to edit the file + * + * @since 1.5.0 + * + * @uses wp_die + * @uses validate_file + * @param string $file file the users is attempting to edit + * @param array $allowed_files Array of allowed files to edit, $file must match an entry exactly + * @return null + */ +function validate_file_to_edit( $file, $allowed_files = '' ) { + $code = validate_file( $file, $allowed_files ); + + if (!$code ) + return $file; + + switch ( $code ) { + case 1 : + wp_die( __('Sorry, can’t edit files with “..” in the name. If you are trying to edit a file in your WordPress home directory, you can just type the name of the file in.' )); + + //case 2 : + // wp_die( __('Sorry, can’t call files with their real path.' )); + + case 3 : + wp_die( __('Sorry, that file cannot be edited.' )); + } +} + +/** + * Handle PHP uploads in WordPress, sanitizing file names, checking extensions for mime type, + * and moving the file to the appropriate directory within the uploads directory. + * + * @since 2.0 + * + * @uses wp_handle_upload_error + * @uses apply_filters + * @uses is_multisite + * @uses wp_check_filetype_and_ext + * @uses current_user_can + * @uses wp_upload_dir + * @uses wp_unique_filename + * @uses delete_transient + * @param array $file Reference to a single element of $_FILES. Call the function once for each uploaded file. + * @param array $overrides Optional. An associative array of names=>values to override default variables with extract( $overrides, EXTR_OVERWRITE ). + * @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). + */ +function wp_handle_upload( &$file, $overrides = false, $time = null ) { + // The default error handler. + if ( ! function_exists( 'wp_handle_upload_error' ) ) { + function wp_handle_upload_error( &$file, $message ) { + return array( 'error'=>$message ); + } + } + + $file = apply_filters( 'wp_handle_upload_prefilter', $file ); + + // You may define your own function and pass the name in $overrides['upload_error_handler'] + $upload_error_handler = 'wp_handle_upload_error'; + + // You may have had one or more 'wp_handle_upload_prefilter' functions error out the file. Handle that gracefully. + if ( isset( $file['error'] ) && !is_numeric( $file['error'] ) && $file['error'] ) + return $upload_error_handler( $file, $file['error'] ); + + // You may define your own function and pass the name in $overrides['unique_filename_callback'] + $unique_filename_callback = null; + + // $_POST['action'] must be set and its value must equal $overrides['action'] or this: + $action = 'wp_handle_upload'; + + // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error']. + $upload_error_strings = array( false, + __( "The uploaded file exceeds the upload_max_filesize directive in php.ini." ), + __( "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form." ), + __( "The uploaded file was only partially uploaded." ), + __( "No file was uploaded." ), + '', + __( "Missing a temporary folder." ), + __( "Failed to write file to disk." ), + __( "File upload stopped by extension." )); + + // All tests are on by default. Most can be turned off by $override[{test_name}] = false; + $test_form = true; + $test_size = true; + $test_upload = true; + + // If you override this, you must provide $ext and $type!!!! + $test_type = true; + $mimes = false; + + // Install user overrides. Did we mention that this voids your warranty? + if ( is_array( $overrides ) ) + extract( $overrides, EXTR_OVERWRITE ); + + // A correct form post will pass this test. + if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) ) + return call_user_func($upload_error_handler, $file, __( 'Invalid form submission.' )); + + // A successful upload will pass this test. It makes no sense to override this one. + if ( $file['error'] > 0 ) + return call_user_func($upload_error_handler, $file, $upload_error_strings[$file['error']] ); + + // A non-empty file will pass this test. + if ( $test_size && !($file['size'] > 0 ) ) { + if ( is_multisite() ) + $error_msg = __( 'File is empty. Please upload something more substantial.' ); + else + $error_msg = __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.' ); + return call_user_func($upload_error_handler, $file, $error_msg); + } + + // A properly uploaded file will pass this test. There should be no reason to override this one. + if ( $test_upload && ! @ is_uploaded_file( $file['tmp_name'] ) ) + return call_user_func($upload_error_handler, $file, __( 'Specified file failed upload test.' )); + + // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. + if ( $test_type ) { + $wp_filetype = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $mimes ); + + extract( $wp_filetype ); + + // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect + if ( $proper_filename ) + $file['name'] = $proper_filename; + + if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) ) + return call_user_func($upload_error_handler, $file, __( 'Sorry, this file type is not permitted for security reasons.' )); + + if ( !$ext ) + $ext = ltrim(strrchr($file['name'], '.'), '.'); + + if ( !$type ) + $type = $file['type']; + } else { + $type = ''; + } + + // A writable uploads dir will pass this test. Again, there's no point overriding this one. + if ( ! ( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ) ) + return call_user_func($upload_error_handler, $file, $uploads['error'] ); + + $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback ); + + // Move the file to the uploads dir + $new_file = $uploads['path'] . "/$filename"; + if ( false === @ move_uploaded_file( $file['tmp_name'], $new_file ) ) + return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) ); + + // Set correct file permissions + $stat = stat( dirname( $new_file )); + $perms = $stat['mode'] & 0000666; + @ chmod( $new_file, $perms ); + + // Compute the URL + $url = $uploads['url'] . "/$filename"; + + if ( is_multisite() ) + delete_transient( 'dirsize_cache' ); + + return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ), 'upload' ); +} + +/** + * Handle sideloads, which is the process of retriving a media item from another server instead of + * a traditional media upload. This process involves sanitizing the filename, checking extensions + * for mime type, and moving the file to the appropriate directory within the uploads directory. + * + * @since 2.6.0 + * + * @uses wp_handle_upload_error + * @uses apply_filters + * @uses wp_check_filetype_and_ext + * @uses current_user_can + * @uses wp_upload_dir + * @uses wp_unique_filename + * @param array $file an array similar to that of a PHP $_FILES POST array + * @param array $overrides Optional. An associative array of names=>values to override default variables with extract( $overrides, EXTR_OVERWRITE ). + * @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). + */ +function wp_handle_sideload( &$file, $overrides = false ) { + // The default error handler. + if (! function_exists( 'wp_handle_upload_error' ) ) { + function wp_handle_upload_error( &$file, $message ) { + return array( 'error'=>$message ); + } + } + + // You may define your own function and pass the name in $overrides['upload_error_handler'] + $upload_error_handler = 'wp_handle_upload_error'; + + // You may define your own function and pass the name in $overrides['unique_filename_callback'] + $unique_filename_callback = null; + + // $_POST['action'] must be set and its value must equal $overrides['action'] or this: + $action = 'wp_handle_sideload'; + + // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error']. + $upload_error_strings = array( false, + __( "The uploaded file exceeds the upload_max_filesize directive in php.ini." ), + __( "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form." ), + __( "The uploaded file was only partially uploaded." ), + __( "No file was uploaded." ), + '', + __( "Missing a temporary folder." ), + __( "Failed to write file to disk." ), + __( "File upload stopped by extension." )); + + // All tests are on by default. Most can be turned off by $override[{test_name}] = false; + $test_form = true; + $test_size = true; + + // If you override this, you must provide $ext and $type!!!! + $test_type = true; + $mimes = false; + + // Install user overrides. Did we mention that this voids your warranty? + if ( is_array( $overrides ) ) + extract( $overrides, EXTR_OVERWRITE ); + + // A correct form post will pass this test. + if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) ) + return $upload_error_handler( $file, __( 'Invalid form submission.' )); + + // A successful upload will pass this test. It makes no sense to override this one. + if ( ! empty( $file['error'] ) ) + return $upload_error_handler( $file, $upload_error_strings[$file['error']] ); + + // A non-empty file will pass this test. + if ( $test_size && !(filesize($file['tmp_name']) > 0 ) ) + return $upload_error_handler( $file, __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.' )); + + // A properly uploaded file will pass this test. There should be no reason to override this one. + if (! @ is_file( $file['tmp_name'] ) ) + return $upload_error_handler( $file, __( 'Specified file does not exist.' )); + + // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. + if ( $test_type ) { + $wp_filetype = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $mimes ); + + extract( $wp_filetype ); + + // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect + if ( $proper_filename ) + $file['name'] = $proper_filename; + + if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) ) + return $upload_error_handler( $file, __( 'Sorry, this file type is not permitted for security reasons.' )); + + if ( !$ext ) + $ext = ltrim(strrchr($file['name'], '.'), '.'); + + if ( !$type ) + $type = $file['type']; + } + + // A writable uploads dir will pass this test. Again, there's no point overriding this one. + if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) ) + return $upload_error_handler( $file, $uploads['error'] ); + + $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback ); + + // Strip the query strings. + $filename = str_replace('?','-', $filename); + $filename = str_replace('&','-', $filename); + + // Move the file to the uploads dir + $new_file = $uploads['path'] . "/$filename"; + if ( false === @ rename( $file['tmp_name'], $new_file ) ) { + return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) ); + } + + // Set correct file permissions + $stat = stat( dirname( $new_file )); + $perms = $stat['mode'] & 0000666; + @ chmod( $new_file, $perms ); + + // Compute the URL + $url = $uploads['url'] . "/$filename"; + + $return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ), 'sideload' ); + + return $return; +} + +/** + * Downloads a url to a local temporary file using the WordPress HTTP Class. + * Please note, That the calling function must unlink() the file. + * + * @since 2.5.0 + * + * @param string $url the URL of the file to download + * @param int $timeout The timeout for the request to download the file default 300 seconds + * @return mixed WP_Error on failure, string Filename on success. + */ +function download_url( $url, $timeout = 300 ) { + //WARNING: The file is not automatically deleted, The script must unlink() the file. + if ( ! $url ) + return new WP_Error('http_no_url', __('Invalid URL Provided.')); + + $tmpfname = wp_tempnam($url); + if ( ! $tmpfname ) + return new WP_Error('http_no_file', __('Could not create Temporary file.')); + + $handle = @fopen($tmpfname, 'wb'); + if ( ! $handle ) + return new WP_Error('http_no_file', __('Could not create Temporary file.')); + + $response = wp_remote_get($url, array('timeout' => $timeout)); + + if ( is_wp_error($response) ) { + fclose($handle); + unlink($tmpfname); + return $response; + } + + if ( $response['response']['code'] != '200' ){ + fclose($handle); + unlink($tmpfname); + return new WP_Error('http_404', trim($response['response']['message'])); + } + + fwrite($handle, $response['body']); + fclose($handle); + + return $tmpfname; +} + +/** + * Unzip's a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction. + * Assumes that WP_Filesystem() has already been called and set up. Does not extract a root-level __MACOSX directory, if present. + * + * Attempts to increase the PHP Memory limit to 256M before uncompressing, + * However, The most memory required shouldn't be much larger than the Archive itself. + * + * @since 2.5.0 + * + * @param string $file Full path and filename of zip archive + * @param string $to Full path on the filesystem to extract archive to + * @return mixed WP_Error on failure, True on success + */ +function unzip_file($file, $to) { + global $wp_filesystem; + + if ( ! $wp_filesystem || !is_object($wp_filesystem) ) + return new WP_Error('fs_unavailable', __('Could not access filesystem.')); + + // Unzip can use a lot of memory, but not this much hopefully + @ini_set('memory_limit', '256M'); + + $needed_dirs = array(); + $to = trailingslashit($to); + + // Determine any parent dir's needed (of the upgrade directory) + if ( ! $wp_filesystem->is_dir($to) ) { //Only do parents if no children exist + $path = preg_split('![/\\\]!', untrailingslashit($to)); + for ( $i = count($path); $i >= 0; $i-- ) { + if ( empty($path[$i]) ) + continue; + + $dir = implode('/', array_slice($path, 0, $i+1) ); + if ( preg_match('!^[a-z]:$!i', $dir) ) // Skip it if it looks like a Windows Drive letter. + continue; + + if ( ! $wp_filesystem->is_dir($dir) ) + $needed_dirs[] = $dir; + else + break; // A folder exists, therefor, we dont need the check the levels below this + } + } + + if ( class_exists('ZipArchive') && apply_filters('unzip_file_use_ziparchive', true ) ) { + $result = _unzip_file_ziparchive($file, $to, $needed_dirs); + if ( true === $result ) { + return $result; + } elseif ( is_wp_error($result) ) { + if ( 'incompatible_archive' != $result->get_error_code() ) + return $result; + } + } + // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file. + return _unzip_file_pclzip($file, $to, $needed_dirs); +} + +/** + * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the ZipArchive class. + * Assumes that WP_Filesystem() has already been called and set up. + * + * @since 3.0.0 + * @see unzip_file + * @access private + * + * @param string $file Full path and filename of zip archive + * @param string $to Full path on the filesystem to extract archive to + * @param array $needed_dirs A partial list of required folders needed to be created. + * @return mixed WP_Error on failure, True on success + */ +function _unzip_file_ziparchive($file, $to, $needed_dirs = array() ) { + global $wp_filesystem; + + $z = new ZipArchive(); + + // PHP4-compat - php4 classes can't contain constants + $zopen = $z->open($file, /* ZIPARCHIVE::CHECKCONS */ 4); + if ( true !== $zopen ) + return new WP_Error('incompatible_archive', __('Incompatible Archive.')); + + for ( $i = 0; $i < $z->numFiles; $i++ ) { + if ( ! $info = $z->statIndex($i) ) + return new WP_Error('stat_failed', __('Could not retrieve file from archive.')); + + if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Skip the OS X-created __MACOSX directory + continue; + + if ( '/' == substr($info['name'], -1) ) // directory + $needed_dirs[] = $to . untrailingslashit($info['name']); + else + $needed_dirs[] = $to . untrailingslashit(dirname($info['name'])); + } + + $needed_dirs = array_unique($needed_dirs); + foreach ( $needed_dirs as $dir ) { + // Check the parent folders of the folders all exist within the creation array. + if ( untrailingslashit($to) == $dir ) // Skip over the working directory, We know this exists (or will exist) + continue; + if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it + continue; + + $parent_folder = dirname($dir); + while ( !empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs) ) { + $needed_dirs[] = $parent_folder; + $parent_folder = dirname($parent_folder); + } + } + asort($needed_dirs); + + // Create those directories if need be: + foreach ( $needed_dirs as $_dir ) { + if ( ! $wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && ! $wp_filesystem->is_dir($_dir) ) // Only check to see if the Dir exists upon creation failure. Less I/O this way. + return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir); + } + unset($needed_dirs); + + for ( $i = 0; $i < $z->numFiles; $i++ ) { + if ( ! $info = $z->statIndex($i) ) + return new WP_Error('stat_failed', __('Could not retrieve file from archive.')); + + if ( '/' == substr($info['name'], -1) ) // directory + continue; + + if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files + continue; + + $contents = $z->getFromIndex($i); + if ( false === $contents ) + return new WP_Error('extract_failed', __('Could not extract file from archive.'), $info['name']); + + if ( ! $wp_filesystem->put_contents( $to . $info['name'], $contents, FS_CHMOD_FILE) ) + return new WP_Error('copy_failed', __('Could not copy file.'), $to . $info['filename']); + } + + $z->close(); + + return true; +} + +/** + * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the PclZip library. + * Assumes that WP_Filesystem() has already been called and set up. + * + * @since 3.0.0 + * @see unzip_file + * @access private + * + * @param string $file Full path and filename of zip archive + * @param string $to Full path on the filesystem to extract archive to + * @param array $needed_dirs A partial list of required folders needed to be created. + * @return mixed WP_Error on failure, True on success + */ +function _unzip_file_pclzip($file, $to, $needed_dirs = array()) { + global $wp_filesystem; + + require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php'); + + $archive = new PclZip($file); + + // Is the archive valid? + if ( false == ($archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING)) ) + return new WP_Error('incompatible_archive', __('Incompatible Archive.'), $archive->errorInfo(true)); + + if ( 0 == count($archive_files) ) + return new WP_Error('empty_archive', __('Empty archive.')); + + // Determine any children directories needed (From within the archive) + foreach ( $archive_files as $file ) { + if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Skip the OS X-created __MACOSX directory + continue; + + $needed_dirs[] = $to . untrailingslashit( $file['folder'] ? $file['filename'] : dirname($file['filename']) ); + } + + $needed_dirs = array_unique($needed_dirs); + foreach ( $needed_dirs as $dir ) { + // Check the parent folders of the folders all exist within the creation array. + if ( untrailingslashit($to) == $dir ) // Skip over the working directory, We know this exists (or will exist) + continue; + if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it + continue; + + $parent_folder = dirname($dir); + while ( !empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs) ) { + $needed_dirs[] = $parent_folder; + $parent_folder = dirname($parent_folder); + } + } + asort($needed_dirs); + + // Create those directories if need be: + foreach ( $needed_dirs as $_dir ) { + if ( ! $wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && ! $wp_filesystem->is_dir($_dir) ) // Only check to see if the dir exists upon creation failure. Less I/O this way. + return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir); + } + unset($needed_dirs); + + // Extract the files from the zip + foreach ( $archive_files as $file ) { + if ( $file['folder'] ) + continue; + + if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files + continue; + + if ( ! $wp_filesystem->put_contents( $to . $file['filename'], $file['content'], FS_CHMOD_FILE) ) + return new WP_Error('copy_failed', __('Could not copy file.'), $to . $file['filename']); + } + return true; +} + +/** + * Copies a directory from one location to another via the WordPress Filesystem Abstraction. + * Assumes that WP_Filesystem() has already been called and setup. + * + * @since 2.5.0 + * + * @param string $from source directory + * @param string $to destination directory + * @return mixed WP_Error on failure, True on success. + */ +function copy_dir($from, $to) { + global $wp_filesystem; + + $dirlist = $wp_filesystem->dirlist($from); + + $from = trailingslashit($from); + $to = trailingslashit($to); + + foreach ( (array) $dirlist as $filename => $fileinfo ) { + if ( 'f' == $fileinfo['type'] ) { + if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) ) { + // If copy failed, chmod file to 0644 and try again. + $wp_filesystem->chmod($to . $filename, 0644); + if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) ) + return new WP_Error('copy_failed', __('Could not copy file.'), $to . $filename); + } + $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE); + } elseif ( 'd' == $fileinfo['type'] ) { + if ( !$wp_filesystem->is_dir($to . $filename) ) { + if ( !$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR) ) + return new WP_Error('mkdir_failed', __('Could not create directory.'), $to . $filename); + } + $result = copy_dir($from . $filename, $to . $filename); + if ( is_wp_error($result) ) + return $result; + } + } + return true; +} + +/** + * Initialises and connects the WordPress Filesystem Abstraction classes. + * This function will include the chosen transport and attempt connecting. + * + * Plugins may add extra transports, And force WordPress to use them by returning the filename via the 'filesystem_method_file' filter. + * + * @since 2.5.0 + * + * @param array $args (optional) Connection args, These are passed directly to the WP_Filesystem_*() classes. + * @param string $context (optional) Context for get_filesystem_method(), See function declaration for more information. + * @return boolean false on failure, true on success + */ +function WP_Filesystem( $args = false, $context = false ) { + global $wp_filesystem; + + require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php'); + + $method = get_filesystem_method($args, $context); + + if ( ! $method ) + return false; + + if ( ! class_exists("WP_Filesystem_$method") ) { + $abstraction_file = apply_filters('filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method); + if ( ! file_exists($abstraction_file) ) + return; + + require_once($abstraction_file); + } + $method = "WP_Filesystem_$method"; + + $wp_filesystem = new $method($args); + + //Define the timeouts for the connections. Only available after the construct is called to allow for per-transport overriding of the default. + if ( ! defined('FS_CONNECT_TIMEOUT') ) + define('FS_CONNECT_TIMEOUT', 30); + if ( ! defined('FS_TIMEOUT') ) + define('FS_TIMEOUT', 30); + + if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() ) + return false; + + if ( !$wp_filesystem->connect() ) + return false; //There was an erorr connecting to the server. + + // Set the permission constants if not already set. + if ( ! defined('FS_CHMOD_DIR') ) + define('FS_CHMOD_DIR', 0755 ); + if ( ! defined('FS_CHMOD_FILE') ) + define('FS_CHMOD_FILE', 0644 ); + + return true; +} + +/** + * Determines which Filesystem Method to use. + * The priority of the Transports are: Direct, SSH2, FTP PHP Extension, FTP Sockets (Via Sockets class, or fsoxkopen()) + * + * Note that the return value of this function can be overridden in 2 ways + * - By defining FS_METHOD in your wp-config.php file + * - By using the filesystem_method filter + * Valid values for these are: 'direct', 'ssh', 'ftpext' or 'ftpsockets' + * Plugins may also define a custom transport handler, See the WP_Filesystem function for more information. + * + * @since 2.5.0 + * + * @param array $args Connection details. + * @param string $context Full path to the directory that is tested for being writable. + * @return string The transport to use, see description for valid return values. + */ +function get_filesystem_method($args = array(), $context = false) { + $method = defined('FS_METHOD') ? FS_METHOD : false; //Please ensure that this is either 'direct', 'ssh', 'ftpext' or 'ftpsockets' + + if ( ! $method && function_exists('getmyuid') && function_exists('fileowner') ){ + if ( !$context ) + $context = WP_CONTENT_DIR; + $context = trailingslashit($context); + $temp_file_name = $context . 'temp-write-test-' . time(); + $temp_handle = @fopen($temp_file_name, 'w'); + if ( $temp_handle ) { + if ( getmyuid() == @fileowner($temp_file_name) ) + $method = 'direct'; + @fclose($temp_handle); + @unlink($temp_file_name); + } + } + + if ( ! $method && isset($args['connection_type']) && 'ssh' == $args['connection_type'] && extension_loaded('ssh2') && function_exists('stream_get_contents') ) $method = 'ssh2'; + if ( ! $method && extension_loaded('ftp') ) $method = 'ftpext'; + if ( ! $method && ( extension_loaded('sockets') || function_exists('fsockopen') ) ) $method = 'ftpsockets'; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread + return apply_filters('filesystem_method', $method, $args); +} + +/** + * Displays a form to the user to request for their FTP/SSH details in order to connect to the filesystem. + * All chosen/entered details are saved, Excluding the Password. + * + * Hostnames may be in the form of hostname:portnumber (eg: wordpress.org:2467) to specify an alternate FTP/SSH port. + * + * Plugins may override this form by returning true|false via the request_filesystem_credentials filter. + * + * @since 2.5.0 + * + * @param string $form_post the URL to post the form to + * @param string $type the chosen Filesystem method in use + * @param boolean $error if the current request has failed to connect + * @param string $context The directory which is needed access to, The write-test will be performed on this directory by get_filesystem_method() + * @param string $extra_fields Extra POST fields which should be checked for to be included in the post. + * @return boolean False on failure. True on success. + */ +function request_filesystem_credentials($form_post, $type = '', $error = false, $context = false, $extra_fields = null) { + $req_cred = apply_filters( 'request_filesystem_credentials', '', $form_post, $type, $error, $context, $extra_fields ); + if ( '' !== $req_cred ) + return $req_cred; + + if ( empty($type) ) + $type = get_filesystem_method(array(), $context); + + if ( 'direct' == $type ) + return true; + + if ( is_null( $extra_fields ) ) + $extra_fields = array( 'version', 'locale' ); + + $credentials = get_option('ftp_credentials', array( 'hostname' => '', 'username' => '')); + + // If defined, set it to that, Else, If POST'd, set it to that, If not, Set it to whatever it previously was(saved details in option) + $credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : (!empty($_POST['hostname']) ? stripslashes($_POST['hostname']) : $credentials['hostname']); + $credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? stripslashes($_POST['username']) : $credentials['username']); + $credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? stripslashes($_POST['password']) : ''); + + // Check to see if we are setting the public/private keys for ssh + $credentials['public_key'] = defined('FTP_PUBKEY') ? FTP_PUBKEY : (!empty($_POST['public_key']) ? stripslashes($_POST['public_key']) : ''); + $credentials['private_key'] = defined('FTP_PRIKEY') ? FTP_PRIKEY : (!empty($_POST['private_key']) ? stripslashes($_POST['private_key']) : ''); + + //sanitize the hostname, Some people might pass in odd-data: + $credentials['hostname'] = preg_replace('|\w+://|', '', $credentials['hostname']); //Strip any schemes off + + if ( strpos($credentials['hostname'], ':') ) { + list( $credentials['hostname'], $credentials['port'] ) = explode(':', $credentials['hostname'], 2); + if ( ! is_numeric($credentials['port']) ) + unset($credentials['port']); + } else { + unset($credentials['port']); + } + + if ( (defined('FTP_SSH') && FTP_SSH) || (defined('FS_METHOD') && 'ssh' == FS_METHOD) ) + $credentials['connection_type'] = 'ssh'; + else if ( (defined('FTP_SSL') && FTP_SSL) && 'ftpext' == $type ) //Only the FTP Extension understands SSL + $credentials['connection_type'] = 'ftps'; + else if ( !empty($_POST['connection_type']) ) + $credentials['connection_type'] = stripslashes($_POST['connection_type']); + else if ( !isset($credentials['connection_type']) ) //All else fails (And its not defaulted to something else saved), Default to FTP + $credentials['connection_type'] = 'ftp'; + + if ( ! $error && + ( + ( !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) || + ( 'ssh' == $credentials['connection_type'] && !empty($credentials['public_key']) && !empty($credentials['private_key']) ) + ) ) { + $stored_credentials = $credentials; + if ( !empty($stored_credentials['port']) ) //save port as part of hostname to simplify above code. + $stored_credentials['hostname'] .= ':' . $stored_credentials['port']; + + unset($stored_credentials['password'], $stored_credentials['port'], $stored_credentials['private_key'], $stored_credentials['public_key']); + update_option('ftp_credentials', $stored_credentials); + return $credentials; + } + $hostname = ''; + $username = ''; + $password = ''; + $connection_type = ''; + if ( !empty($credentials) ) + extract($credentials, EXTR_OVERWRITE); + if ( $error ) { + $error_string = __('Error: There was an error connecting to the server, Please verify the settings are correct.'); + if ( is_wp_error($error) ) + $error_string = esc_html( $error->get_error_message() ); + echo '

' . $error_string . '

'; + } + + $types = array(); + if ( extension_loaded('ftp') || extension_loaded('sockets') || function_exists('fsockopen') ) + $types[ 'ftp' ] = __('FTP'); + if ( extension_loaded('ftp') ) //Only this supports FTPS + $types[ 'ftps' ] = __('FTPS (SSL)'); + if ( extension_loaded('ssh2') && function_exists('stream_get_contents') ) + $types[ 'ssh' ] = __('SSH2'); + + $types = apply_filters('fs_ftp_connection_types', $types, $credentials, $type, $error, $context); + +?> + +
+
+ +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
" size="40" />
size="40" />
size="40" />
+
+
+ +

size="40" />
size="40" /> +
+
+ $text ) : ?> + + +
+
+ +'; +} +submit_button( __( 'Proceed' ), 'button', 'upgrade' ); +?> +
+
+ diff --git a/src/wp-admin/includes/image-edit.php b/src/wp-admin/includes/image-edit.php new file mode 100644 index 00000000..03e7144a --- /dev/null +++ b/src/wp-admin/includes/image-edit.php @@ -0,0 +1,668 @@ + 400 ? 400 / $big : 1; + + $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); + $can_restore = !empty($backup_sizes) && isset($backup_sizes['full-orig']) + && $backup_sizes['full-orig']['file'] != basename($meta['file']); + + if ( $msg ) { + if ( isset($msg->error) ) + $note = "

$msg->error

"; + elseif ( isset($msg->msg) ) + $note = "

$msg->msg

"; + } + + ?> +
+ + + + + +
+
+
, this)" class="imgedit-crop disabled" title="">
+
, this)" title="">
+
, this)" title="">
+ +
+
+ + +
, this)" class="imgedit-flipv" title="">
+
, this)" class="imgedit-fliph" title="">
+ +
, this)" class="imgedit-undo disabled" title="">
+
, this)" class="imgedit-redo disabled" title="">
+
+
+ + + + + + + + + +
+ +
+ +
+ + )" disabled="disabled" class="button-primary imgedit-submit-btn" value="" /> +
+
+
+
+ +
+

+

+
+ × + ! + , 'scale')" class="button-primary" value="" /> +
+
+
+ + + +
+ +
+

+
+ , 'restore')" class="button-primary" value="" /> +
+
+
+ + + +
+ +
+
+ + +
+

+ +
    +
  • +
  • +
  • +
  • +
  • +
+ +


+

+ +


+

+
+
+ +

+ + + + : + + +

+ +

+ + + + : + + +

+
+ + + +
+
+ + +

+
+ +

+
+

+ +

+
+ + + + + + +

+
+ + + +
+
+ + +
+ 400 ? (400 / $max) : 1; +} + +function _rotate_image_resource($img, $angle) { + if ( function_exists('imagerotate') ) { + $rotated = imagerotate($img, $angle, 0); + if ( is_resource($rotated) ) { + imagedestroy($img); + $img = $rotated; + } + } + return $img; +} + + +function _flip_image_resource($img, $horz, $vert) { + $w = imagesx($img); + $h = imagesy($img); + $dst = wp_imagecreatetruecolor($w, $h); + if ( is_resource($dst) ) { + $sx = $vert ? ($w - 1) : 0; + $sy = $horz ? ($h - 1) : 0; + $sw = $vert ? -$w : $w; + $sh = $horz ? -$h : $h; + + if ( imagecopyresampled($dst, $img, 0, 0, $sx, $sy, $w, $h, $sw, $sh) ) { + imagedestroy($img); + $img = $dst; + } + } + return $img; +} + +function _crop_image_resource($img, $x, $y, $w, $h) { + $dst = wp_imagecreatetruecolor($w, $h); + if ( is_resource($dst) ) { + if ( imagecopy($dst, $img, 0, 0, $x, $y, $w, $h) ) { + imagedestroy($img); + $img = $dst; + } + } + return $img; +} + +function image_edit_apply_changes($img, $changes) { + + if ( !is_array($changes) ) + return $img; + + // expand change operations + foreach ( $changes as $key => $obj ) { + if ( isset($obj->r) ) { + $obj->type = 'rotate'; + $obj->angle = $obj->r; + unset($obj->r); + } elseif ( isset($obj->f) ) { + $obj->type = 'flip'; + $obj->axis = $obj->f; + unset($obj->f); + } elseif ( isset($obj->c) ) { + $obj->type = 'crop'; + $obj->sel = $obj->c; + unset($obj->c); + } + $changes[$key] = $obj; + } + + // combine operations + if ( count($changes) > 1 ) { + $filtered = array($changes[0]); + for ( $i = 0, $j = 1; $j < count($changes); $j++ ) { + $combined = false; + if ( $filtered[$i]->type == $changes[$j]->type ) { + switch ( $filtered[$i]->type ) { + case 'rotate': + $filtered[$i]->angle += $changes[$j]->angle; + $combined = true; + break; + case 'flip': + $filtered[$i]->axis ^= $changes[$j]->axis; + $combined = true; + break; + } + } + if ( !$combined ) + $filtered[++$i] = $changes[$j]; + } + $changes = $filtered; + unset($filtered); + } + + // image resource before applying the changes + $img = apply_filters('image_edit_before_change', $img, $changes); + + foreach ( $changes as $operation ) { + switch ( $operation->type ) { + case 'rotate': + if ( $operation->angle != 0 ) + $img = _rotate_image_resource($img, $operation->angle); + break; + case 'flip': + if ( $operation->axis != 0 ) + $img = _flip_image_resource($img, ($operation->axis & 1) != 0, ($operation->axis & 2) != 0); + break; + case 'crop': + $sel = $operation->sel; + $scale = 1 / _image_get_preview_ratio( imagesx($img), imagesy($img) ); // discard preview scaling + $img = _crop_image_resource($img, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale); + break; + } + } + + return $img; +} + +function stream_preview_image($post_id) { + $post = get_post($post_id); + @ini_set('memory_limit', '256M'); + $img = load_image_to_edit( $post_id, $post->post_mime_type, array(400, 400) ); + + if ( !is_resource($img) ) + return false; + + $changes = !empty($_REQUEST['history']) ? json_decode( stripslashes($_REQUEST['history']) ) : null; + if ( $changes ) + $img = image_edit_apply_changes($img, $changes); + + // scale the image + $w = imagesx($img); + $h = imagesy($img); + $ratio = _image_get_preview_ratio($w, $h); + $w2 = $w * $ratio; + $h2 = $h * $ratio; + + $preview = wp_imagecreatetruecolor($w2, $h2); + imagecopyresampled( $preview, $img, 0, 0, 0, 0, $w2, $h2, $w, $h ); + wp_stream_image($preview, $post->post_mime_type, $post_id); + + imagedestroy($preview); + imagedestroy($img); + return true; +} + +function wp_restore_image($post_id) { + $meta = wp_get_attachment_metadata($post_id); + $file = get_attached_file($post_id); + $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); + $restored = false; + $msg = new stdClass; + + if ( !is_array($backup_sizes) ) { + $msg->error = __('Cannot load image metadata.'); + return $msg; + } + + $parts = pathinfo($file); + $suffix = time() . rand(100, 999); + $default_sizes = apply_filters( 'intermediate_image_sizes', array('large', 'medium', 'thumbnail') ); + + if ( isset($backup_sizes['full-orig']) && is_array($backup_sizes['full-orig']) ) { + $data = $backup_sizes['full-orig']; + + if ( $parts['basename'] != $data['file'] ) { + if ( defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE ) { + // delete only if it's edited image + if ( preg_match('/-e[0-9]{13}\./', $parts['basename']) ) { + $delpath = apply_filters('wp_delete_file', $file); + @unlink($delpath); + } + } else { + $backup_sizes["full-$suffix"] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $parts['basename']); + } + } + + $restored_file = path_join($parts['dirname'], $data['file']); + $restored = update_attached_file($post_id, $restored_file); + + $meta['file'] = _wp_relative_upload_path( $restored_file ); + $meta['width'] = $data['width']; + $meta['height'] = $data['height']; + list ( $uwidth, $uheight ) = wp_constrain_dimensions($meta['width'], $meta['height'], 128, 96); + $meta['hwstring_small'] = "height='$uheight' width='$uwidth'"; + } + + foreach ( $default_sizes as $default_size ) { + if ( isset($backup_sizes["$default_size-orig"]) ) { + $data = $backup_sizes["$default_size-orig"]; + if ( isset($meta['sizes'][$default_size]) && $meta['sizes'][$default_size]['file'] != $data['file'] ) { + if ( defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE ) { + // delete only if it's edited image + if ( preg_match('/-e[0-9]{13}-/', $meta['sizes'][$default_size]['file']) ) { + $delpath = apply_filters( 'wp_delete_file', path_join($parts['dirname'], $meta['sizes'][$default_size]['file']) ); + @unlink($delpath); + } + } else { + $backup_sizes["$default_size-{$suffix}"] = $meta['sizes'][$default_size]; + } + } + + $meta['sizes'][$default_size] = $data; + } else { + unset($meta['sizes'][$default_size]); + } + } + + if ( !wp_update_attachment_metadata($post_id, $meta) || !update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes) ) { + $msg->error = __('Cannot save image metadata.'); + return $msg; + } + + if ( !$restored ) + $msg->error = __('Image metadata is inconsistent.'); + else + $msg->msg = __('Image restored successfully.'); + + return $msg; +} + +function wp_save_image($post_id) { + $return = new stdClass; + $success = $delete = $scaled = $nocrop = false; + $post = get_post($post_id); + @ini_set('memory_limit', '256M'); + $img = load_image_to_edit($post_id, $post->post_mime_type); + + if ( !is_resource($img) ) { + $return->error = esc_js( __('Unable to create new image.') ); + return $return; + } + + $fwidth = !empty($_REQUEST['fwidth']) ? intval($_REQUEST['fwidth']) : 0; + $fheight = !empty($_REQUEST['fheight']) ? intval($_REQUEST['fheight']) : 0; + $target = !empty($_REQUEST['target']) ? preg_replace('/[^a-z0-9_-]+/i', '', $_REQUEST['target']) : ''; + $scale = !empty($_REQUEST['do']) && 'scale' == $_REQUEST['do']; + + if ( $scale && $fwidth > 0 && $fheight > 0 ) { + $sX = imagesx($img); + $sY = imagesy($img); + + // check if it has roughly the same w / h ratio + $diff = round($sX / $sY, 2) - round($fwidth / $fheight, 2); + if ( -0.1 < $diff && $diff < 0.1 ) { + // scale the full size image + $dst = wp_imagecreatetruecolor($fwidth, $fheight); + if ( imagecopyresampled( $dst, $img, 0, 0, 0, 0, $fwidth, $fheight, $sX, $sY ) ) { + imagedestroy($img); + $img = $dst; + $scaled = true; + } + } + + if ( !$scaled ) { + $return->error = esc_js( __('Error while saving the scaled image. Please reload the page and try again.') ); + return $return; + } + } elseif ( !empty($_REQUEST['history']) ) { + $changes = json_decode( stripslashes($_REQUEST['history']) ); + if ( $changes ) + $img = image_edit_apply_changes($img, $changes); + } else { + $return->error = esc_js( __('Nothing to save, the image has not changed.') ); + return $return; + } + + $meta = wp_get_attachment_metadata($post_id); + $backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true ); + + if ( !is_array($meta) ) { + $return->error = esc_js( __('Image data does not exist. Please re-upload the image.') ); + return $return; + } + + if ( !is_array($backup_sizes) ) + $backup_sizes = array(); + + // generate new filename + $path = get_attached_file($post_id); + $path_parts = pathinfo52( $path ); + $filename = $path_parts['filename']; + $suffix = time() . rand(100, 999); + + if ( defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE && + isset($backup_sizes['full-orig']) && $backup_sizes['full-orig']['file'] != $path_parts['basename'] ) { + + if ( 'thumbnail' == $target ) + $new_path = "{$path_parts['dirname']}/{$filename}-temp.{$path_parts['extension']}"; + else + $new_path = $path; + } else { + while( true ) { + $filename = preg_replace( '/-e([0-9]+)$/', '', $filename ); + $filename .= "-e{$suffix}"; + $new_filename = "{$filename}.{$path_parts['extension']}"; + $new_path = "{$path_parts['dirname']}/$new_filename"; + if ( file_exists($new_path) ) + $suffix++; + else + break; + } + } + + // save the full-size file, also needed to create sub-sizes + if ( !wp_save_image_file($new_path, $img, $post->post_mime_type, $post_id) ) { + $return->error = esc_js( __('Unable to save the image.') ); + return $return; + } + + if ( 'nothumb' == $target || 'all' == $target || 'full' == $target || $scaled ) { + $tag = false; + if ( isset($backup_sizes['full-orig']) ) { + if ( ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE ) && $backup_sizes['full-orig']['file'] != $path_parts['basename'] ) + $tag = "full-$suffix"; + } else { + $tag = 'full-orig'; + } + + if ( $tag ) + $backup_sizes[$tag] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $path_parts['basename']); + + $success = update_attached_file($post_id, $new_path); + + $meta['file'] = _wp_relative_upload_path($new_path); + $meta['width'] = imagesx($img); + $meta['height'] = imagesy($img); + + list ( $uwidth, $uheight ) = wp_constrain_dimensions($meta['width'], $meta['height'], 128, 96); + $meta['hwstring_small'] = "height='$uheight' width='$uwidth'"; + + if ( $success && ('nothumb' == $target || 'all' == $target) ) { + $sizes = apply_filters( 'intermediate_image_sizes', array('large', 'medium', 'thumbnail') ); + if ( 'nothumb' == $target ) + $sizes = array_diff( $sizes, array('thumbnail') ); + } + + $return->fw = $meta['width']; + $return->fh = $meta['height']; + } elseif ( 'thumbnail' == $target ) { + $sizes = array( 'thumbnail' ); + $success = $delete = $nocrop = true; + } + + if ( isset($sizes) ) { + foreach ( $sizes as $size ) { + $tag = false; + if ( isset($meta['sizes'][$size]) ) { + if ( isset($backup_sizes["$size-orig"]) ) { + if ( ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE ) && $backup_sizes["$size-orig"]['file'] != $meta['sizes'][$size]['file'] ) + $tag = "$size-$suffix"; + } else { + $tag = "$size-orig"; + } + + if ( $tag ) + $backup_sizes[$tag] = $meta['sizes'][$size]; + } + + $crop = $nocrop ? false : get_option("{$size}_crop"); + $resized = image_make_intermediate_size($new_path, get_option("{$size}_size_w"), get_option("{$size}_size_h"), $crop ); + + if ( $resized ) + $meta['sizes'][$size] = $resized; + else + unset($meta['sizes'][$size]); + } + } + + if ( $success ) { + wp_update_attachment_metadata($post_id, $meta); + update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes); + + if ( $target == 'thumbnail' || $target == 'all' || $target == 'full' ) { + $file_url = wp_get_attachment_url($post_id); + if ( $thumb = $meta['sizes']['thumbnail'] ) + $return->thumbnail = path_join( dirname($file_url), $thumb['file'] ); + else + $return->thumbnail = "$file_url?w=128&h=128"; + } + } else { + $delete = true; + } + + if ( $delete ) { + $delpath = apply_filters('wp_delete_file', $new_path); + @unlink($delpath); + } + + imagedestroy($img); + + $return->msg = esc_js( __('Image saved') ); + return $return; +} + diff --git a/src/wp-admin/includes/image.php b/src/wp-admin/includes/image.php new file mode 100644 index 00000000..44329c01 --- /dev/null +++ b/src/wp-admin/includes/image.php @@ -0,0 +1,341 @@ + '', 'height' => '', 'crop' => FALSE ); + if ( isset( $_wp_additional_image_sizes[$s]['width'] ) ) + $sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes + else + $sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options + if ( isset( $_wp_additional_image_sizes[$s]['height'] ) ) + $sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes + else + $sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options + if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) ) + $sizes[$s]['crop'] = intval( $_wp_additional_image_sizes[$s]['crop'] ); // For theme-added sizes + else + $sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options + } + + $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes ); + + foreach ($sizes as $size => $size_data ) { + $resized = image_make_intermediate_size( $file, $size_data['width'], $size_data['height'], $size_data['crop'] ); + if ( $resized ) + $metadata['sizes'][$size] = $resized; + } + + // fetch additional metadata from exif/iptc + $image_meta = wp_read_image_metadata( $file ); + if ( $image_meta ) + $metadata['image_meta'] = $image_meta; + + } + + return apply_filters( 'wp_generate_attachment_metadata', $metadata, $attachment_id ); +} + +/** + * Calculated the new dimentions for a downsampled image. + * + * @since 2.0.0 + * @see wp_constrain_dimensions() + * + * @param int $width Current width of the image + * @param int $height Current height of the image + * @return mixed Array(height,width) of shrunk dimensions. + */ +function get_udims( $width, $height) { + return wp_constrain_dimensions( $width, $height, 128, 96 ); +} + +/** + * Convert a fraction string to a decimal. + * + * @since 2.5.0 + * + * @param string $str + * @return int|float + */ +function wp_exif_frac2dec($str) { + @list( $n, $d ) = explode( '/', $str ); + if ( !empty($d) ) + return $n / $d; + return $str; +} + +/** + * Convert the exif date format to a unix timestamp. + * + * @since 2.5.0 + * + * @param string $str + * @return int + */ +function wp_exif_date2ts($str) { + @list( $date, $time ) = explode( ' ', trim($str) ); + @list( $y, $m, $d ) = explode( ':', $date ); + + return strtotime( "{$y}-{$m}-{$d} {$time}" ); +} + +/** + * Get extended image metadata, exif or iptc as available. + * + * Retrieves the EXIF metadata aperture, credit, camera, caption, copyright, iso + * created_timestamp, focal_length, shutter_speed, and title. + * + * The IPTC metadata that is retrieved is APP13, credit, byline, created date + * and time, caption, copyright, and title. Also includes FNumber, Model, + * DateTimeDigitized, FocalLength, ISOSpeedRatings, and ExposureTime. + * + * @todo Try other exif libraries if available. + * @since 2.5.0 + * + * @param string $file + * @return bool|array False on failure. Image metadata array on success. + */ +function wp_read_image_metadata( $file ) { + if ( ! file_exists( $file ) ) + return false; + + list( , , $sourceImageType ) = getimagesize( $file ); + + // exif contains a bunch of data we'll probably never need formatted in ways + // that are difficult to use. We'll normalize it and just extract the fields + // that are likely to be useful. Fractions and numbers are converted to + // floats, dates to unix timestamps, and everything else to strings. + $meta = array( + 'aperture' => 0, + 'credit' => '', + 'camera' => '', + 'caption' => '', + 'created_timestamp' => 0, + 'copyright' => '', + 'focal_length' => 0, + 'iso' => 0, + 'shutter_speed' => 0, + 'title' => '', + ); + + // read iptc first, since it might contain data not available in exif such + // as caption, description etc + if ( is_callable( 'iptcparse' ) ) { + getimagesize( $file, $info ); + + if ( ! empty( $info['APP13'] ) ) { + $iptc = iptcparse( $info['APP13'] ); + + // headline, "A brief synopsis of the caption." + if ( ! empty( $iptc['2#105'][0] ) ) + $meta['title'] = utf8_encode( trim( $iptc['2#105'][0] ) ); + // title, "Many use the Title field to store the filename of the image, though the field may be used in many ways." + elseif ( ! empty( $iptc['2#005'][0] ) ) + $meta['title'] = utf8_encode( trim( $iptc['2#005'][0] ) ); + + if ( ! empty( $iptc['2#120'][0] ) ) { // description / legacy caption + $caption = utf8_encode( trim( $iptc['2#120'][0] ) ); + if ( empty( $meta['title'] ) ) { + // Assume the title is stored in 2:120 if it's short. + if ( strlen( $caption ) < 80 ) + $meta['title'] = $caption; + else + $meta['caption'] = $caption; + } elseif ( $caption != $meta['title'] ) { + $meta['caption'] = $caption; + } + } + + if ( ! empty( $iptc['2#110'][0] ) ) // credit + $meta['credit'] = utf8_encode(trim($iptc['2#110'][0])); + elseif ( ! empty( $iptc['2#080'][0] ) ) // creator / legacy byline + $meta['credit'] = utf8_encode(trim($iptc['2#080'][0])); + + if ( ! empty( $iptc['2#055'][0] ) and ! empty( $iptc['2#060'][0] ) ) // created date and time + $meta['created_timestamp'] = strtotime( $iptc['2#055'][0] . ' ' . $iptc['2#060'][0] ); + + if ( ! empty( $iptc['2#116'][0] ) ) // copyright + $meta['copyright'] = utf8_encode( trim( $iptc['2#116'][0] ) ); + } + } + + // fetch additional info from exif if available + if ( is_callable( 'exif_read_data' ) && in_array( $sourceImageType, apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) ) ) ) { + $exif = @exif_read_data( $file ); + + if ( !empty( $exif['Title'] ) ) + $meta['title'] = utf8_encode( trim( $exif['Title'] ) ); + + if ( ! empty( $exif['ImageDescription'] ) ) { + if ( empty( $meta['title'] ) && strlen( $exif['ImageDescription'] ) < 80 ) { + // Assume the title is stored in ImageDescription + $meta['title'] = utf8_encode( trim( $exif['ImageDescription'] ) ); + if ( ! empty( $exif['COMPUTED']['UserComment'] ) && trim( $exif['COMPUTED']['UserComment'] ) != $meta['title'] ) + $meta['caption'] = utf8_encode( trim( $exif['COMPUTED']['UserComment'] ) ); + } elseif ( trim( $exif['ImageDescription'] ) != $meta['title'] ) { + $meta['caption'] = utf8_encode( trim( $exif['ImageDescription'] ) ); + } + } elseif ( ! empty( $exif['Comments'] ) && trim( $exif['Comments'] ) != $meta['title'] ) { + $meta['caption'] = utf8_encode( trim( $exif['Comments'] ) ); + } + + if ( ! empty( $exif['Artist'] ) ) + $meta['credit'] = utf8_encode( trim( $exif['Artist'] ) ); + elseif ( ! empty($exif['Author'] ) ) + $meta['credit'] = utf8_encode( trim( $exif['Author'] ) ); + + if ( ! empty( $exif['Copyright'] ) ) + $meta['copyright'] = utf8_encode( trim( $exif['Copyright'] ) ); + if ( ! empty($exif['FNumber'] ) ) + $meta['aperture'] = round( wp_exif_frac2dec( $exif['FNumber'] ), 2 ); + if ( ! empty($exif['Model'] ) ) + $meta['camera'] = utf8_encode( trim( $exif['Model'] ) ); + if ( ! empty($exif['DateTimeDigitized'] ) ) + $meta['created_timestamp'] = wp_exif_date2ts($exif['DateTimeDigitized'] ); + if ( ! empty($exif['FocalLength'] ) ) + $meta['focal_length'] = wp_exif_frac2dec( $exif['FocalLength'] ); + if ( ! empty($exif['ISOSpeedRatings'] ) ) + $meta['iso'] = utf8_encode( trim( $exif['ISOSpeedRatings'] ) ); + if ( ! empty($exif['ExposureTime'] ) ) + $meta['shutter_speed'] = wp_exif_frac2dec( $exif['ExposureTime'] ); + } + + return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType ); + +} + +/** + * Validate that file is an image. + * + * @since 2.5.0 + * + * @param string $path File path to test if valid image. + * @return bool True if valid image, false if not valid image. + */ +function file_is_valid_image($path) { + $size = @getimagesize($path); + return !empty($size); +} + +/** + * Validate that file is suitable for displaying within a web page. + * + * @since 2.5.0 + * @uses apply_filters() Calls 'file_is_displayable_image' on $result and $path. + * + * @param string $path File path to test. + * @return bool True if suitable, false if not suitable. + */ +function file_is_displayable_image($path) { + $info = @getimagesize($path); + if ( empty($info) ) + $result = false; + elseif ( !in_array($info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)) ) // only gif, jpeg and png images can reliably be displayed + $result = false; + else + $result = true; + + return apply_filters('file_is_displayable_image', $result, $path); +} diff --git a/src/wp-admin/includes/import.php b/src/wp-admin/includes/import.php new file mode 100644 index 00000000..f57be766 --- /dev/null +++ b/src/wp-admin/includes/import.php @@ -0,0 +1,97 @@ + false, 'test_type' => false ); + $_FILES['import']['name'] .= '.txt'; + $file = wp_handle_upload( $_FILES['import'], $overrides ); + + if ( isset( $file['error'] ) ) + return $file; + + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $filename = basename( $file ); + + // Construct the object array + $object = array( 'post_title' => $filename, + 'post_content' => $url, + 'post_mime_type' => $type, + 'guid' => $url, + 'context' => 'import', + 'post_status' => 'private' + ); + + // Save the data + $id = wp_insert_attachment( $object, $file ); + + // schedule a cleanup for one day from now in case of failed import or missing wp_import_cleanup() call + wp_schedule_single_event( time() + 86400, 'importer_scheduled_cleanup', array( $id ) ); + + return array( 'file' => $file, 'id' => $id ); +} + +?> diff --git a/src/wp-admin/includes/internal-linking.php b/src/wp-admin/includes/internal-linking.php new file mode 100644 index 00000000..b2e60a20 --- /dev/null +++ b/src/wp-admin/includes/internal-linking.php @@ -0,0 +1,124 @@ + true ), 'objects' ); + $pt_names = array_keys( $pts ); + + $query = array( + 'post_type' => $pt_names, + 'suppress_filters' => true, + 'update_post_term_cache' => false, + 'update_post_meta_cache' => false, + 'post_status' => 'publish', + 'order' => 'DESC', + 'orderby' => 'post_date', + 'posts_per_page' => 20, + ); + + $args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1; + + if ( isset( $args['s'] ) ) + $query['s'] = $args['s']; + + $query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0; + + // Do main query. + $get_posts = new WP_Query; + $posts = $get_posts->query( $query ); + // Check if any posts were found. + if ( ! $get_posts->post_count ) + return false; + + // Build results. + $results = array(); + foreach ( $posts as $post ) { + if ( 'post' == $post->post_type ) + $info = mysql2date( __( 'Y/m/d' ), $post->post_date ); + else + $info = $pts[ $post->post_type ]->labels->singular_name; + + $results[] = array( + 'ID' => $post->ID, + 'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ), + 'permalink' => get_permalink( $post->ID ), + 'info' => $info, + ); + } + + return $results; +} + +/** + * Dialog for internal linking. + * + * @since 3.1.0 + */ +function wp_link_dialog() { +?> + + \ No newline at end of file diff --git a/src/wp-admin/includes/list-table.php b/src/wp-admin/includes/list-table.php new file mode 100644 index 00000000..716e80ac --- /dev/null +++ b/src/wp-admin/includes/list-table.php @@ -0,0 +1,104 @@ + 'posts', + 'WP_Media_List_Table' => 'media', + 'WP_Terms_List_Table' => 'terms', + 'WP_Users_List_Table' => 'users', + 'WP_Comments_List_Table' => 'comments', + 'WP_Post_Comments_List_Table' => 'comments', + 'WP_Links_List_Table' => 'links', + 'WP_Plugin_Install_List_Table' => 'plugin-install', + 'WP_Themes_List_Table' => 'themes', + 'WP_Theme_Install_List_Table' => 'theme-install', + 'WP_Plugins_List_Table' => 'plugins', + // Network Admin + 'WP_MS_Sites_List_Table' => 'ms-sites', + 'WP_MS_Users_List_Table' => 'ms-users', + 'WP_MS_Themes_List_Table' => 'ms-themes', + ); + + if ( isset( $core_classes[ $class ] ) ) { + require_once( ABSPATH . 'wp-admin/includes/class-wp-' . $core_classes[ $class ] . '-list-table.php' ); + return new $class; + } + + return false; +} + +/** + * Register column headers for a particular screen. + * + * @since 2.7.0 + * + * @param string $screen The handle for the screen to add help to. This is usually the hook name returned by the add_*_page() functions. + * @param array $columns An array of columns with column IDs as the keys and translated column names as the values + * @see get_column_headers(), print_column_headers(), get_hidden_columns() + */ +function register_column_headers($screen, $columns) { + $wp_list_table = new _WP_List_Table_Compat($screen, $columns); +} + +/** + * Prints column headers for a particular screen. + * + * @since 2.7.0 + */ +function print_column_headers($screen, $id = true) { + $wp_list_table = new _WP_List_Table_Compat($screen); + + $wp_list_table->print_column_headers($id); +} + +/** + * Helper class to be used only by back compat functions + * + * @since 3.1.0 + */ +class _WP_List_Table_Compat extends WP_List_Table { + var $_screen; + var $_columns; + + function _WP_List_Table_Compat( $screen, $columns = array() ) { + if ( is_string( $screen ) ) + $screen = convert_to_screen( $screen ); + + $this->_screen = $screen; + + if ( !empty( $columns ) ) { + $this->_columns = $columns; + add_filter( 'manage_' . $screen->id . '_columns', array( &$this, 'get_columns' ), 0 ); + } + } + + function get_column_info() { + $columns = get_column_headers( $this->_screen ); + $hidden = get_hidden_columns( $this->_screen ); + $sortable = array(); + + return array( $columns, $hidden, $sortable ); + } + + function get_columns() { + return $this->_columns; + } +} +?> \ No newline at end of file diff --git a/src/wp-admin/includes/manifest.php b/src/wp-admin/includes/manifest.php new file mode 100644 index 00000000..600b5dbd --- /dev/null +++ b/src/wp-admin/includes/manifest.php @@ -0,0 +1,203 @@ + __('From Computer'), // handler action suffix => tab text + 'type_url' => __('From URL'), + 'gallery' => __('Gallery'), + 'library' => __('Media Library') + ); + + return apply_filters('media_upload_tabs', $_default_tabs); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $tabs + * @return unknown + */ +function update_gallery_tab($tabs) { + global $wpdb; + + if ( !isset($_REQUEST['post_id']) ) { + unset($tabs['gallery']); + return $tabs; + } + + $post_id = intval($_REQUEST['post_id']); + + if ( $post_id ) + $attachments = intval( $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' AND post_parent = %d", $post_id ) ) ); + + if ( empty($attachments) ) { + unset($tabs['gallery']); + return $tabs; + } + + $tabs['gallery'] = sprintf(__('Gallery (%s)'), "$attachments"); + + return $tabs; +} +add_filter('media_upload_tabs', 'update_gallery_tab'); + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + */ +function the_media_upload_tabs() { + global $redir_tab; + $tabs = media_upload_tabs(); + + if ( !empty($tabs) ) { + echo "
    \n"; + if ( isset($redir_tab) && array_key_exists($redir_tab, $tabs) ) + $current = $redir_tab; + elseif ( isset($_GET['tab']) && array_key_exists($_GET['tab'], $tabs) ) + $current = $_GET['tab']; + else + $current = apply_filters('media_upload_default_tab', 'type'); + + foreach ( $tabs as $callback => $text ) { + $class = ''; + if ( $current == $callback ) + $class = " class='current'"; + $href = add_query_arg(array('tab'=>$callback, 's'=>false, 'paged'=>false, 'post_mime_type'=>false, 'm'=>false)); + $link = "$text"; + echo "\t
  • $link
  • \n"; + } + echo "
\n"; + } +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $id + * @param unknown_type $alt + * @param unknown_type $title + * @param unknown_type $align + * @param unknown_type $url + * @param unknown_type $rel + * @param unknown_type $size + * @return unknown + */ +function get_image_send_to_editor($id, $caption, $title, $align, $url='', $rel = false, $size='medium', $alt = '') { + + $html = get_image_tag($id, $alt, $title, $align, $size); + + $rel = $rel ? ' rel="attachment wp-att-' . esc_attr($id).'"' : ''; + + if ( $url ) + $html = '$html"; + + $html = apply_filters( 'image_send_to_editor', $html, $id, $caption, $title, $align, $url, $size, $alt ); + + return $html; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.6.0 + * + * @param unknown_type $html + * @param unknown_type $id + * @param unknown_type $alt + * @param unknown_type $title + * @param unknown_type $align + * @param unknown_type $url + * @param unknown_type $size + * @return unknown + */ +function image_add_caption( $html, $id, $caption, $title, $align, $url, $size, $alt = '' ) { + + if ( empty($caption) || apply_filters( 'disable_captions', '' ) ) + return $html; + + $id = ( 0 < (int) $id ) ? 'attachment_' . $id : ''; + + if ( ! preg_match( '/width="([0-9]+)/', $html, $matches ) ) + return $html; + + $width = $matches[1]; + + $caption = str_replace( array( '>', '<', '"', "'" ), + array( '>', '<', '"', ''' ), + $caption + ); + + $html = preg_replace( '/(class=["\'][^\'"]*)align(none|left|right|center)\s?/', '$1', $html ); + if ( empty($align) ) + $align = 'none'; + + $shcode = '[caption id="' . $id . '" align="align' . $align + . '" width="' . $width . '" caption="' . addslashes($caption) . '"]' . $html . '[/caption]'; + + return apply_filters( 'image_add_caption_shortcode', $shcode, $html ); +} +add_filter( 'image_send_to_editor', 'image_add_caption', 20, 8 ); + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $html + */ +function media_send_to_editor($html) { +?> + + false )) { + + $time = current_time('mysql'); + if ( $post = get_post($post_id) ) { + if ( substr( $post->post_date, 0, 4 ) > 0 ) + $time = $post->post_date; + } + + $name = $_FILES[$file_id]['name']; + $file = wp_handle_upload($_FILES[$file_id], $overrides, $time); + + if ( isset($file['error']) ) + return new WP_Error( 'upload_error', $file['error'] ); + + $name_parts = pathinfo($name); + $name = trim( substr( $name, 0, -(1 + strlen($name_parts['extension'])) ) ); + + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $title = $name; + $content = ''; + + // use image exif/iptc data for title and caption defaults if possible + if ( $image_meta = @wp_read_image_metadata($file) ) { + if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) + $title = $image_meta['title']; + if ( trim( $image_meta['caption'] ) ) + $content = $image_meta['caption']; + } + + // Construct the attachment array + $attachment = array_merge( array( + 'post_mime_type' => $type, + 'guid' => $url, + 'post_parent' => $post_id, + 'post_title' => $title, + 'post_content' => $content, + ), $post_data ); + + // Save the data + $id = wp_insert_attachment($attachment, $file, $post_id); + if ( !is_wp_error($id) ) { + wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); + } + + return $id; + +} + +/** + * This handles a sideloaded file in the same way as an uploaded file is handled by {@link media_handle_upload()} + * + * @since 2.6.0 + * + * @param array $file_array Array similar to a {@link $_FILES} upload array + * @param int $post_id The post ID the media is associated with + * @param string $desc Description of the sideloaded file + * @param array $post_data allows you to overwrite some of the attachment + * @return int|object The ID of the attachment or a WP_Error on failure + */ +function media_handle_sideload($file_array, $post_id, $desc = null, $post_data = array()) { + $overrides = array('test_form'=>false); + + $file = wp_handle_sideload($file_array, $overrides); + if ( isset($file['error']) ) + return new WP_Error( 'upload_error', $file['error'] ); + + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $title = preg_replace('/\.[^.]+$/', '', basename($file)); + $content = ''; + + // use image exif/iptc data for title and caption defaults if possible + if ( $image_meta = @wp_read_image_metadata($file) ) { + if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) + $title = $image_meta['title']; + if ( trim( $image_meta['caption'] ) ) + $content = $image_meta['caption']; + } + + $title = isset($desc) ? $desc : ''; + + // Construct the attachment array + $attachment = array_merge( array( + 'post_mime_type' => $type, + 'guid' => $url, + 'post_parent' => $post_id, + 'post_title' => $title, + 'post_content' => $content, + ), $post_data ); + + // Save the attachment metadata + $id = wp_insert_attachment($attachment, $file, $post_id); + if ( !is_wp_error($id) ) + wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); + + return $id; +} + +/** + * {@internal Missing Short Description}} + * + * Wrap iframe content (produced by $content_func) in a doctype, html head/body + * etc any additional function args will be passed to content_func. + * + * @since 2.5.0 + * + * @param unknown_type $content_func + */ +function wp_iframe($content_func /* ... */) { +?> + + > + + +<?php bloginfo('name') ?> › <?php _e('Uploads'); ?> — <?php _e('WordPress'); ?> + + + + +> + + + + +$title"; +} + +function get_upload_iframe_src($type) { + global $post_ID, $temp_ID; + $uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID); + $upload_iframe_src = add_query_arg('post_id', $uploading_iframe_ID, 'media-upload.php'); + + if ( 'media' != $type ) + $upload_iframe_src = add_query_arg('type', $type, $upload_iframe_src); + $upload_iframe_src = apply_filters($type . '_upload_iframe_src', $upload_iframe_src); + + return add_query_arg('TB_iframe', true, $upload_iframe_src); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function media_upload_form_handler() { + check_admin_referer('media-form'); + + $errors = null; + + if ( isset($_POST['send']) ) { + $keys = array_keys($_POST['send']); + $send_id = (int) array_shift($keys); + } + + if ( !empty($_POST['attachments']) ) foreach ( $_POST['attachments'] as $attachment_id => $attachment ) { + $post = $_post = get_post($attachment_id, ARRAY_A); + if ( isset($attachment['post_content']) ) + $post['post_content'] = $attachment['post_content']; + if ( isset($attachment['post_title']) ) + $post['post_title'] = $attachment['post_title']; + if ( isset($attachment['post_excerpt']) ) + $post['post_excerpt'] = $attachment['post_excerpt']; + if ( isset($attachment['menu_order']) ) + $post['menu_order'] = $attachment['menu_order']; + + if ( isset($send_id) && $attachment_id == $send_id ) { + if ( isset($attachment['post_parent']) ) + $post['post_parent'] = $attachment['post_parent']; + } + + $post = apply_filters('attachment_fields_to_save', $post, $attachment); + + if ( isset($attachment['image_alt']) ) { + $image_alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true); + if ( $image_alt != stripslashes($attachment['image_alt']) ) { + $image_alt = wp_strip_all_tags( stripslashes($attachment['image_alt']), true ); + // update_meta expects slashed + update_post_meta( $attachment_id, '_wp_attachment_image_alt', addslashes($image_alt) ); + } + } + + if ( isset($post['errors']) ) { + $errors[$attachment_id] = $post['errors']; + unset($post['errors']); + } + + if ( $post != $_post ) + wp_update_post($post); + + foreach ( get_attachment_taxonomies($post) as $t ) { + if ( isset($attachment[$t]) ) + wp_set_object_terms($attachment_id, array_map('trim', preg_split('/,+/', $attachment[$t])), $t, false); + } + } + + if ( isset($_POST['insert-gallery']) || isset($_POST['update-gallery']) ) { ?> + + $html"; + } + + $html = apply_filters('media_send_to_editor', $html, $send_id, $attachment); + return media_send_to_editor($html); + } + + return $errors; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function media_upload_image() { + $errors = array(); + $id = 0; + + if ( isset($_POST['html-upload']) && !empty($_FILES) ) { + check_admin_referer('media-form'); + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $alt = $align = ''; + + $src = $_POST['insertonly']['src']; + if ( !empty($src) && !strpos($src, '://') ) + $src = "http://$src"; + $alt = esc_attr($_POST['insertonly']['alt']); + if ( isset($_POST['insertonly']['align']) ) { + $align = esc_attr($_POST['insertonly']['align']); + $class = " class='align$align'"; + } + if ( !empty($src) ) + $html = "$alt"; + + $html = apply_filters('image_send_to_editor_url', $html, esc_url_raw($src), $alt, $align); + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + if ( isset($_POST['save']) ) { + $errors['upload_notice'] = __('Saved.'); + return media_upload_gallery(); + } + + if ( isset($_GET['tab']) && $_GET['tab'] == 'type_url' ) + return wp_iframe( 'media_upload_type_url_form', 'image', $errors, $id ); + + return wp_iframe( 'media_upload_type_form', 'image', $errors, $id ); +} + +/** + * Download an image from the specified URL and attach it to a post. + * + * @since 2.6.0 + * + * @param string $file The URL of the image to download + * @param int $post_id The post ID the media is to be associated with + * @param string $desc Optional. Description of the image + * @return string|WP_Error Populated HTML img tag on success + */ +function media_sideload_image($file, $post_id, $desc = null) { + if ( ! empty($file) ) { + // Download file to temp location + $tmp = download_url( $file ); + + // Set variables for storage + // fix file filename for query strings + preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $file, $matches); + $file_array['name'] = basename($matches[0]); + $file_array['tmp_name'] = $tmp; + + // If error storing temporarily, unlink + if ( is_wp_error( $tmp ) ) { + @unlink($file_array['tmp_name']); + $file_array['tmp_name'] = ''; + } + + // do the validation and storage stuff + $id = media_handle_sideload( $file_array, $post_id, $desc ); + // If error storing permanently, unlink + if ( is_wp_error($id) ) { + @unlink($file_array['tmp_name']); + return $id; + } + + $src = wp_get_attachment_url( $id ); + } + + // Finally check to make sure the file has been saved, then return the html + if ( ! empty($src) ) { + $alt = isset($desc) ? esc_attr($desc) : ''; + $html = "$alt"; + return $html; + } +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function media_upload_audio() { + $errors = array(); + $id = 0; + + if ( isset($_POST['html-upload']) && !empty($_FILES) ) { + check_admin_referer('media-form'); + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $href = $_POST['insertonly']['href']; + if ( !empty($href) && !strpos($href, '://') ) + $href = "http://$href"; + + $title = esc_attr($_POST['insertonly']['title']); + if ( empty($title) ) + $title = esc_attr( basename($href) ); + + if ( !empty($title) && !empty($href) ) + $html = "$title"; + + $html = apply_filters('audio_send_to_editor_url', $html, $href, $title); + + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + if ( isset($_POST['save']) ) { + $errors['upload_notice'] = __('Saved.'); + return media_upload_gallery(); + } + + if ( isset($_GET['tab']) && $_GET['tab'] == 'type_url' ) + return wp_iframe( 'media_upload_type_url_form', 'audio', $errors, $id ); + + return wp_iframe( 'media_upload_type_form', 'audio', $errors, $id ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function media_upload_video() { + $errors = array(); + $id = 0; + + if ( isset($_POST['html-upload']) && !empty($_FILES) ) { + check_admin_referer('media-form'); + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $href = $_POST['insertonly']['href']; + if ( !empty($href) && !strpos($href, '://') ) + $href = "http://$href"; + + $title = esc_attr($_POST['insertonly']['title']); + if ( empty($title) ) + $title = esc_attr( basename($href) ); + + if ( !empty($title) && !empty($href) ) + $html = "$title"; + + $html = apply_filters('video_send_to_editor_url', $html, $href, $title); + + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + if ( isset($_POST['save']) ) { + $errors['upload_notice'] = __('Saved.'); + return media_upload_gallery(); + } + + if ( isset($_GET['tab']) && $_GET['tab'] == 'type_url' ) + return wp_iframe( 'media_upload_type_url_form', 'video', $errors, $id ); + + return wp_iframe( 'media_upload_type_form', 'video', $errors, $id ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function media_upload_file() { + $errors = array(); + $id = 0; + + if ( isset($_POST['html-upload']) && !empty($_FILES) ) { + check_admin_referer('media-form'); + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $href = $_POST['insertonly']['href']; + if ( !empty($href) && !strpos($href, '://') ) + $href = "http://$href"; + + $title = esc_attr($_POST['insertonly']['title']); + if ( empty($title) ) + $title = basename($href); + if ( !empty($title) && !empty($href) ) + $html = "$title"; + $html = apply_filters('file_send_to_editor_url', $html, esc_url_raw($href), $title); + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + if ( isset($_POST['save']) ) { + $errors['upload_notice'] = __('Saved.'); + return media_upload_gallery(); + } + + if ( isset($_GET['tab']) && $_GET['tab'] == 'type_url' ) + return wp_iframe( 'media_upload_type_url_form', 'file', $errors, $id ); + + return wp_iframe( 'media_upload_type_form', 'file', $errors, $id ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function media_upload_gallery() { + $errors = array(); + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + wp_enqueue_script('admin-gallery'); + return wp_iframe( 'media_upload_gallery_form', $errors ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function media_upload_library() { + $errors = array(); + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + return wp_iframe( 'media_upload_library_form', $errors ); +} + +/** + * Retrieve HTML for the image alignment radio buttons with the specified one checked. + * + * @since 2.7.0 + * + * @param unknown_type $post + * @param unknown_type $checked + * @return unknown + */ +function image_align_input_fields( $post, $checked = '' ) { + + if ( empty($checked) ) + $checked = get_user_setting('align', 'none'); + + $alignments = array('none' => __('None'), 'left' => __('Left'), 'center' => __('Center'), 'right' => __('Right')); + if ( !array_key_exists( (string) $checked, $alignments ) ) + $checked = 'none'; + + $out = array(); + foreach ( $alignments as $name => $label ) { + $name = esc_attr($name); + $out[] = ""; + } + return join("\n", $out); +} + +/** + * Retrieve HTML for the size radio buttons with the specified one checked. + * + * @since 2.7.0 + * + * @param unknown_type $post + * @param unknown_type $check + * @return unknown + */ +function image_size_input_fields( $post, $check = '' ) { + + // get a list of the actual pixel dimensions of each possible intermediate version of this image + $size_names = array('thumbnail' => __('Thumbnail'), 'medium' => __('Medium'), 'large' => __('Large'), 'full' => __('Full Size')); + + if ( empty($check) ) + $check = get_user_setting('imgsize', 'medium'); + + foreach ( $size_names as $size => $label ) { + $downsize = image_downsize($post->ID, $size); + $checked = ''; + + // is this size selectable? + $enabled = ( $downsize[3] || 'full' == $size ); + $css_id = "image-size-{$size}-{$post->ID}"; + // if this size is the default but that's not available, don't select it + if ( $size == $check ) { + if ( $enabled ) + $checked = " checked='checked'"; + else + $check = ''; + } elseif ( !$check && $enabled && 'thumbnail' != $size ) { + // if $check is not enabled, default to the first available size that's bigger than a thumbnail + $check = $size; + $checked = " checked='checked'"; + } + + $html = "
"; + + $html .= ""; + // only show the dimensions if that choice is available + if ( $enabled ) + $html .= " "; + + $html .= '
'; + + $out[] = $html; + } + + return array( + 'label' => __('Size'), + 'input' => 'html', + 'html' => join("\n", $out), + ); +} + +/** + * Retrieve HTML for the Link URL buttons with the default link type as specified. + * + * @since 2.7.0 + * + * @param unknown_type $post + * @param unknown_type $url_type + * @return unknown + */ +function image_link_input_fields($post, $url_type = '') { + + $file = wp_get_attachment_url($post->ID); + $link = get_attachment_link($post->ID); + + if ( empty($url_type) ) + $url_type = get_user_setting('urlbutton', 'post'); + + $url = ''; + if ( $url_type == 'file' ) + $url = $file; + elseif ( $url_type == 'post' ) + $url = $link; + + return " +
+ + + +"; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $form_fields + * @param unknown_type $post + * @return unknown + */ +function image_attachment_fields_to_edit($form_fields, $post) { + if ( substr($post->post_mime_type, 0, 5) == 'image' ) { + $alt = get_post_meta($post->ID, '_wp_attachment_image_alt', true); + if ( empty($alt) ) + $alt = ''; + + $form_fields['post_title']['required'] = true; + + $form_fields['image_alt'] = array( + 'value' => $alt, + 'label' => __('Alternate Text'), + 'helps' => __('Alt text for the image, e.g. “The Mona Lisa”') + ); + + $form_fields['align'] = array( + 'label' => __('Alignment'), + 'input' => 'html', + 'html' => image_align_input_fields($post, get_option('image_default_align')), + ); + + $form_fields['image-size'] = image_size_input_fields( $post, get_option('image_default_size', 'medium') ); + + } else { + unset( $form_fields['image_alt'] ); + } + return $form_fields; +} + +add_filter('attachment_fields_to_edit', 'image_attachment_fields_to_edit', 10, 2); + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $form_fields + * @param unknown_type $post + * @return unknown + */ +function media_single_attachment_fields_to_edit( $form_fields, $post ) { + unset($form_fields['url'], $form_fields['align'], $form_fields['image-size']); + return $form_fields; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.8.0 + * + * @param unknown_type $form_fields + * @param unknown_type $post + * @return unknown + */ +function media_post_single_attachment_fields_to_edit( $form_fields, $post ) { + unset($form_fields['image_url']); + return $form_fields; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $post + * @param unknown_type $attachment + * @return unknown + */ +function image_attachment_fields_to_save($post, $attachment) { + if ( substr($post['post_mime_type'], 0, 5) == 'image' ) { + if ( strlen(trim($post['post_title'])) == 0 ) { + $post['post_title'] = preg_replace('/\.\w+$/', '', basename($post['guid'])); + $post['errors']['post_title']['errors'][] = __('Empty Title filled from filename.'); + } + } + + return $post; +} + +add_filter('attachment_fields_to_save', 'image_attachment_fields_to_save', 10, 2); + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $html + * @param unknown_type $attachment_id + * @param unknown_type $attachment + * @return unknown + */ +function image_media_send_to_editor($html, $attachment_id, $attachment) { + $post =& get_post($attachment_id); + if ( substr($post->post_mime_type, 0, 5) == 'image' ) { + $url = $attachment['url']; + $align = !empty($attachment['align']) ? $attachment['align'] : 'none'; + $size = !empty($attachment['image-size']) ? $attachment['image-size'] : 'medium'; + $alt = !empty($attachment['image_alt']) ? $attachment['image_alt'] : ''; + $rel = ( $url == get_attachment_link($attachment_id) ); + + return get_image_send_to_editor($attachment_id, $attachment['post_excerpt'], $attachment['post_title'], $align, $url, $rel, $size, $alt); + } + + return $html; +} + +add_filter('media_send_to_editor', 'image_media_send_to_editor', 10, 3); + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $post + * @param unknown_type $errors + * @return unknown + */ +function get_attachment_fields_to_edit($post, $errors = null) { + if ( is_int($post) ) + $post =& get_post($post); + if ( is_array($post) ) + $post = (object) $post; + + $image_url = wp_get_attachment_url($post->ID); + + $edit_post = sanitize_post($post, 'edit'); + + + + $form_fields = array( + 'post_title' => array( + 'label' => __('Title'), + 'value' => $edit_post->post_title + ), + 'image_alt' => array(), + 'post_excerpt' => array( + 'label' => __('Caption'), + 'value' => $edit_post->post_excerpt + ), + 'post_content' => array( + 'label' => __('Description'), + 'value' => $edit_post->post_content, + 'input' => 'textarea' + ), + 'url' => array( + 'label' => __('Link URL'), + 'input' => 'html', + 'html' => image_link_input_fields($post, get_option('image_default_link_type')), + 'helps' => __('Enter a link URL or click above for presets.') + ), + 'menu_order' => array( + 'label' => __('Order'), + 'value' => $edit_post->menu_order + ), + 'image_url' => array( + 'label' => __('File URL'), + 'input' => 'html', + 'html' => "
", + 'value' => wp_get_attachment_url($post->ID), + 'helps' => __('Location of the uploaded file.') + ) + ); + + foreach ( get_attachment_taxonomies($post) as $taxonomy ) { + $t = (array) get_taxonomy($taxonomy); + if ( ! $t['public'] ) + continue; + if ( empty($t['label']) ) + $t['label'] = $taxonomy; + if ( empty($t['args']) ) + $t['args'] = array(); + + $terms = get_object_term_cache($post->ID, $taxonomy); + if ( empty($terms) ) + $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']); + + $values = array(); + + foreach ( $terms as $term ) + $values[] = $term->name; + $t['value'] = join(', ', $values); + + $form_fields[$taxonomy] = $t; + } + + // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default + // The recursive merge is easily traversed with array casting: foreach( (array) $things as $thing ) + $form_fields = array_merge_recursive($form_fields, (array) $errors); + + $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post); + + return $form_fields; +} + +/** + * Retrieve HTML for media items of post gallery. + * + * The HTML markup retrieved will be created for the progress of SWF Upload + * component. Will also create link for showing and hiding the form to modify + * the image attachment. + * + * @since 2.5.0 + * + * @param int $post_id Optional. Post ID. + * @param array $errors Errors for attachment, if any. + * @return string + */ +function get_media_items( $post_id, $errors ) { + $attachments = array(); + if ( $post_id ) { + $post = get_post($post_id); + if ( $post && $post->post_type == 'attachment' ) + $attachments = array($post->ID => $post); + else + $attachments = get_children( array( 'post_parent' => $post_id, 'post_type' => 'attachment', 'orderby' => 'menu_order ASC, ID', 'order' => 'DESC') ); + } else { + if ( is_array($GLOBALS['wp_the_query']->posts) ) + foreach ( $GLOBALS['wp_the_query']->posts as $attachment ) + $attachments[$attachment->ID] = $attachment; + } + + $output = ''; + foreach ( (array) $attachments as $id => $attachment ) { + if ( $attachment->post_status == 'trash' ) + continue; + if ( $item = get_media_item( $id, array( 'errors' => isset($errors[$id]) ? $errors[$id] : null) ) ) + $output .= "\n
$item\n
"; + } + + return $output; +} + +/** + * Retrieve HTML form for modifying the image attachment. + * + * @since 2.5.0 + * + * @param int $attachment_id Attachment ID for modification. + * @param string|array $args Optional. Override defaults. + * @return string HTML form for attachment. + */ +function get_media_item( $attachment_id, $args = null ) { + global $redir_tab; + + if ( ( $attachment_id = intval( $attachment_id ) ) && $thumb_url = wp_get_attachment_image_src( $attachment_id, 'thumbnail', true ) ) + $thumb_url = $thumb_url[0]; + else + $thumb_url = false; + + $post = get_post( $attachment_id ); + + $default_args = array( 'errors' => null, 'send' => $post->post_parent ? post_type_supports( get_post_type( $post->post_parent ), 'editor' ) : true, 'delete' => true, 'toggle' => true, 'show_title' => true ); + $args = wp_parse_args( $args, $default_args ); + $args = apply_filters( 'get_media_item_args', $args ); + extract( $args, EXTR_SKIP ); + + $toggle_on = __( 'Show' ); + $toggle_off = __( 'Hide' ); + + $filename = esc_html( basename( $post->guid ) ); + $title = esc_attr( $post->post_title ); + + if ( $_tags = get_the_tags( $attachment_id ) ) { + foreach ( $_tags as $tag ) + $tags[] = $tag->name; + $tags = esc_attr( join( ', ', $tags ) ); + } + + $post_mime_types = get_post_mime_types(); + $keys = array_keys( wp_match_mime_types( array_keys( $post_mime_types ), $post->post_mime_type ) ); + $type = array_shift( $keys ); + $type_html = ""; + + $form_fields = get_attachment_fields_to_edit( $post, $errors ); + + if ( $toggle ) { + $class = empty( $errors ) ? 'startclosed' : 'startopen'; + $toggle_links = " + $toggle_on + $toggle_off"; + } else { + $class = 'form-table'; + $toggle_links = ''; + } + + $display_title = ( !empty( $title ) ) ? $title : $filename; // $title shouldn't ever be empty, but just in case + $display_title = $show_title ? "
" . wp_html_excerpt( $display_title, 60 ) . "
" : ''; + + $gallery = ( ( isset( $_REQUEST['tab'] ) && 'gallery' == $_REQUEST['tab'] ) || ( isset( $redir_tab ) && 'gallery' == $redir_tab ) ); + $order = ''; + + foreach ( $form_fields as $key => $val ) { + if ( 'menu_order' == $key ) { + if ( $gallery ) + $order = ""; + else + $order = ""; + + unset( $form_fields['menu_order'] ); + break; + } + } + + $media_dims = ''; + $meta = wp_get_attachment_metadata( $post->ID ); + if ( is_array( $meta ) && array_key_exists( 'width', $meta ) && array_key_exists( 'height', $meta ) ) + $media_dims .= "{$meta['width']} × {$meta['height']} "; + $media_dims = apply_filters( 'media_meta', $media_dims, $post ); + + $image_edit_button = ''; + if ( gd_edit_image_support( $post->post_mime_type ) ) { + $nonce = wp_create_nonce( "image_editor-$post->ID" ); + $image_edit_button = " "; + } + + $attachment_url = get_permalink( $attachment_id ); + + $item = " + $type_html + $toggle_links + $order + $display_title + + + + + \n"; + + + + $item .= " + + + + \n"; + + $defaults = array( + 'input' => 'text', + 'required' => false, + 'value' => '', + 'extra_rows' => array(), + ); + + if ( $send ) + $send = get_submit_button( __( 'Insert into Post' ), 'button', "send[$attachment_id]", false ); + if ( $delete && current_user_can( 'delete_post', $attachment_id ) ) { + if ( !EMPTY_TRASH_DAYS ) { + $delete = "" . __( 'Delete Permanently' ) . ''; + } elseif ( !MEDIA_TRASH ) { + $delete = "" . __( 'Delete' ) . " + "; + } else { + $delete = "" . __( 'Move to Trash' ) . " + "; + } + } else { + $delete = ''; + } + + $thumbnail = ''; + $calling_post_id = 0; + if ( isset( $_GET['post_id'] ) ) + $calling_post_id = absint( $_GET['post_id'] ); + elseif ( isset( $_POST ) && count( $_POST ) ) // Like for async-upload where $_GET['post_id'] isn't set + $calling_post_id = $post->post_parent; + if ( 'image' == $type && $calling_post_id && current_theme_supports( 'post-thumbnails', get_post_type( $calling_post_id ) ) && get_post_thumbnail_id( $calling_post_id ) != $attachment_id ) { + $ajax_nonce = wp_create_nonce( "set_post_thumbnail-$calling_post_id" ); + $thumbnail = "" . esc_html__( "Use as featured image" ) . ""; + } + + if ( ( $send || $thumbnail || $delete ) && !isset( $form_fields['buttons'] ) ) + $form_fields['buttons'] = array( 'tr' => "\t\t\n" ); + + $hidden_fields = array(); + + foreach ( $form_fields as $id => $field ) { + if ( $id[0] == '_' ) + continue; + + if ( !empty( $field['tr'] ) ) { + $item .= $field['tr']; + continue; + } + + $field = array_merge( $defaults, $field ); + $name = "attachments[$attachment_id][$id]"; + + if ( $field['input'] == 'hidden' ) { + $hidden_fields[$name] = $field['value']; + continue; + } + + $required = $field['required'] ? '*' : ''; + $aria_required = $field['required'] ? " aria-required='true' " : ''; + $class = $id; + $class .= $field['required'] ? ' form-required' : ''; + + $item .= "\t\t\n\t\t\t\n\t\t\t\n\t\t\n"; + + $extra_rows = array(); + + if ( !empty( $field['errors'] ) ) + foreach ( array_unique( (array) $field['errors'] ) as $error ) + $extra_rows['error'][] = $error; + + if ( !empty( $field['extra_rows'] ) ) + foreach ( $field['extra_rows'] as $class => $rows ) + foreach ( (array) $rows as $html ) + $extra_rows[$class][] = $html; + + foreach ( $extra_rows as $class => $rows ) + foreach ( $rows as $html ) + $item .= "\t\t\n"; + } + + if ( !empty( $form_fields['_final'] ) ) + $item .= "\t\t\n"; + $item .= "\t\n"; + $item .= "\t
+

+

$image_edit_button

+
+

" . __('File name:') . " $filename

+

" . __('File type:') . " $post->post_mime_type

+

" . __('Upload date:') . " " . mysql2date( get_option('date_format'), $post->post_date ). '

'; + if ( !empty( $media_dims ) ) + $item .= "

" . __('Dimensions:') . " $media_dims

\n"; + + $item .= "
$send $thumbnail $delete
"; + if ( !empty( $field[ $field['input'] ] ) ) + $item .= $field[ $field['input'] ]; + elseif ( $field['input'] == 'textarea' ) { + if ( user_can_richedit() ) { // textarea_escaped when user_can_richedit() = false + $field['value'] = esc_textarea( $field['value'] ); + } + $item .= "'; + } else { + $item .= ""; + } + if ( !empty( $field['helps'] ) ) + $item .= "

" . join( "

\n

", array_unique( (array) $field['helps'] ) ) . '

'; + $item .= "
$html
{$form_fields['_final']}
\n"; + + foreach ( $hidden_fields as $name => $value ) + $item .= "\t\n"; + + if ( $post->post_parent < 1 && isset( $_REQUEST['post_id'] ) ) { + $parent = (int) $_REQUEST['post_id']; + $parent_name = "attachments[$attachment_id][post_parent]"; + $item .= "\t\n"; + } + + return $item; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + */ +function media_upload_header() { + ?> + +
+ +
+ 1024 && $u < count( $sizes ) - 1; $u++ ) + $upload_size_unit /= 1024; + if ( $u < 0 ) { + $upload_size_unit = 0; + $u = 0; + } else { + $upload_size_unit = (int) $upload_size_unit; + } +?> + +
+ + + +
+
+ + get_error_message(); ?> + +
+' . sprintf( __( 'Sorry, you have filled your storage quota (%s MB).' ), get_space_allowed() ) . '

'; + return; +} + +do_action('pre-upload-ui'); + +if ( $flash ) : + +// Set the post params, which SWFUpload will post back with the file, and pass +// them through a filter. +$post_params = array( + "post_id" => $post_id, + "auth_cookie" => (is_ssl() ? $_COOKIE[SECURE_AUTH_COOKIE] : $_COOKIE[AUTH_COOKIE]), + "logged_in_cookie" => $_COOKIE[LOGGED_IN_COOKIE], + "_wpnonce" => wp_create_nonce('media-form'), + "type" => $type, + "tab" => $tab, + "short" => "1", +); +$post_params = apply_filters( 'swfupload_post_params', $post_params ); +$p = array(); +foreach ( $post_params as $param => $val ) + $p[] = "\t\t'$param' : '$val'"; +$post_params_str = implode( ", \n", $p ); + +// #8545. wmode=transparent cannot be used with SWFUpload +if ( 'media-new.php' == $pagenow ) { + $upload_image_path = get_user_option( 'admin_color' ); + if ( 'classic' != $upload_image_path ) + $upload_image_path = 'fresh'; + $upload_image_path = admin_url( 'images/upload-' . $upload_image_path . '.png?ver=20101205' ); +} else { + $upload_image_path = includes_url( 'images/upload.png?ver=20100531' ); +} + +?> + + +
+ + +
+ +
+ +
+

+ +

+
+ + +
+ +

+ + + + +

+
+

+ +

+ + +
+ + + +
+ + + + +

+ + + + +
+'.esc_html($id->get_error_message()).'
'; + exit; + } +} +?> +
+

+ +

+ + + +
+ + + + + +

+ + + +
+
+ +
+
+
+ + + +
+ + + + + + + | + | + +
+ + + +
+ + + + + + + +
    + $reals ) + foreach ( $reals as $real ) + if ( isset($num_posts[$_type]) ) + $num_posts[$_type] += $_num_posts[$real]; + else + $num_posts[$_type] = $_num_posts[$real]; +// If available type specified by media button clicked, filter by that type +if ( empty($_GET['post_mime_type']) && !empty($num_posts[$type]) ) { + $_GET['post_mime_type'] = $type; + list($post_mime_types, $avail_post_mime_types) = wp_edit_attachments_query(); +} +if ( empty($_GET['post_mime_type']) || $_GET['post_mime_type'] == 'all' ) + $class = ' class="current"'; +else + $class = ''; +$type_links[] = "
  • 'all', 'paged'=>false, 'm'=>false))) . "'$class>".__('All Types').""; +foreach ( $post_mime_types as $mime_type => $label ) { + $class = ''; + + if ( !wp_match_mime_types($mime_type, $avail_post_mime_types) ) + continue; + + if ( isset($_GET['post_mime_type']) && wp_match_mime_types($mime_type, $_GET['post_mime_type']) ) + $class = ' class="current"'; + + $type_links[] = "
  • $mime_type, 'paged'=>false))) . "'$class>" . sprintf( translate_nooped_plural( $label[2], $num_posts[$mime_type] ), "" . number_format_i18n( $num_posts[$mime_type] ) . '') . ''; +} +echo implode(' |
  • ', apply_filters( 'media_upload_mime_type_links', $type_links ) ) . ''; +unset($type_links); +?> +
+ +
+ + add_query_arg( 'paged', '%#%' ), + 'format' => '', + 'prev_text' => __('«'), + 'next_text' => __('»'), + 'total' => ceil($wp_query->found_posts / 10), + 'current' => $_GET['paged'] +)); + +if ( $page_links ) + echo "
$page_links
"; +?> + +
+posts WHERE post_type = 'attachment' ORDER BY post_date DESC"; + +$arc_result = $wpdb->get_results( $arc_query ); + +$month_count = count($arc_result); + +if ( $month_count && !( 1 == $month_count && 0 == $arc_result[0]->mmonth ) ) { ?> + + + + + +
+ +
+
+
+ +
+ + + + + + +
+ + +
+

+ + +

+
+ + + + + + +'; + } else { + $caption = ''; + } + + $default_align = get_option('image_default_align'); + if ( empty($default_align) ) + $default_align = 'none'; + + return ' +

' . __('Insert an image from another web site') . '

+ + + + + + + + + + + + + + + + ' . $caption . ' + + + + + + + + + + ' . _insert_into_post_button('image') . ' +
+ + * +
+ + * +
+ + +

' . __('Alt text for the image, e.g. “The Mona Lisa”') . '

+ + + + + + + + +
+ +
+ + + +

' . __('Enter a link URL or click above for presets.') . '

+'; + +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @return unknown + */ +function type_url_form_audio() { + return ' + + + + + + + + + + + ' . _insert_into_post_button('audio') . ' +
+ + * +
+ + * +
' . __('Link text, e.g. “Still Alive by Jonathan Coulton”') . '
+'; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @return unknown + */ +function type_url_form_video() { + return ' + + + + + + + + + + + ' . _insert_into_post_button('video') . ' +
+ + * +
+ + * +
' . __('Link text, e.g. “Lucy on YouTube”') . '
+'; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @return unknown + */ +function type_url_form_file() { + return ' + + + + + + + + + + + ' . _insert_into_post_button('file') . ' +
+ + * +
+ + * +
' . __('Link text, e.g. “Ransom Demands (PDF)”') . '
+'; +} + + +function _insert_into_post_button($type) { + if ( !post_type_supports(get_post_type($_GET['post_id']), 'editor') ) + return ''; + + if ( 'image' == $type ) + return ' + + + + + + + '; + + return ' + + + + ' . get_submit_button( __( 'Insert into Post' ), 'button', 'insertonlybutton', false ) . ' + + + '; +} + +/** + * {@internal Missing Short Description}} + * + * Support a GET parameter for disabling the flash uploader. + * + * @since 2.6.0 + * + * @param unknown_type $flash + * @return unknown + */ +function media_upload_use_flash($flash) { + if ( array_key_exists('flash', $_REQUEST) ) + $flash = !empty($_REQUEST['flash']); + return $flash; +} + +add_filter('flash_uploader', 'media_upload_use_flash'); + +/** + * {@internal Missing Short Description}} + * + * @since 2.6.0 + */ +function media_upload_flash_bypass() { + echo '

'; + printf( __('You are using the Flash uploader. Problems? Try the Browser uploader instead.'), esc_url(add_query_arg('flash', 0)) ); + echo '

'; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.6.0 + */ +function media_upload_html_bypass($flash = true) { + echo '

'; + _e('You are using the Browser uploader.'); + if ( $flash ) { + // the user manually selected the browser uploader, so let them switch back to Flash + echo ' '; + printf( __('Try the Flash uploader instead.'), esc_url(add_query_arg('flash', 1)) ); + } + echo "

\n"; +} + +add_action('post-flash-upload-ui', 'media_upload_flash_bypass'); +add_action('post-html-upload-ui', 'media_upload_html_bypass'); + +/** + * {@internal Missing Short Description}} + * + * Make sure the GET parameter sticks when we submit a form. + * + * @since 2.6.0 + * + * @param unknown_type $url + * @return unknown + */ +function media_upload_bypass_url($url) { + if ( array_key_exists('flash', $_REQUEST) ) + $url = add_query_arg('flash', intval($_REQUEST['flash'])); + return $url; +} + +add_filter('media_upload_form_url', 'media_upload_bypass_url'); + +add_filter('async_upload_image', 'get_media_item', 10, 2); +add_filter('async_upload_audio', 'get_media_item', 10, 2); +add_filter('async_upload_video', 'get_media_item', 10, 2); +add_filter('async_upload_file', 'get_media_item', 10, 2); + +add_action('media_upload_image', 'media_upload_image'); +add_action('media_upload_audio', 'media_upload_audio'); +add_action('media_upload_video', 'media_upload_video'); +add_action('media_upload_file', 'media_upload_file'); + +add_filter('media_upload_gallery', 'media_upload_gallery'); + +add_filter('media_upload_library', 'media_upload_library'); diff --git a/src/wp-admin/includes/menu.php b/src/wp-admin/includes/menu.php new file mode 100644 index 00000000..a0c2e588 --- /dev/null +++ b/src/wp-admin/includes/menu.php @@ -0,0 +1,215 @@ + $sub) { + foreach ($sub as $index => $data) { + if ( ! current_user_can($data[1]) ) { + unset(${$sub_loop}[$parent][$index]); + $_wp_submenu_nopriv[$parent][$data[2]] = true; + } + } + unset($index, $data); + + if ( empty(${$sub_loop}[$parent]) ) + unset(${$sub_loop}[$parent]); + } + unset($sub, $parent); +} +unset($sub_loop); + +// Loop over the top-level menu. +// Menus for which the original parent is not accessible due to lack of privs will have the next +// submenu in line be assigned as the new menu parent. +foreach ( $menu as $id => $data ) { + if ( empty($submenu[$data[2]]) ) + continue; + $subs = $submenu[$data[2]]; + $first_sub = array_shift($subs); + $old_parent = $data[2]; + $new_parent = $first_sub[2]; + // If the first submenu is not the same as the assigned parent, + // make the first submenu the new parent. + if ( $new_parent != $old_parent ) { + $_wp_real_parent_file[$old_parent] = $new_parent; + $menu[$id][2] = $new_parent; + + foreach ($submenu[$old_parent] as $index => $data) { + $submenu[$new_parent][$index] = $submenu[$old_parent][$index]; + unset($submenu[$old_parent][$index]); + } + unset($submenu[$old_parent], $index); + + if ( isset($_wp_submenu_nopriv[$old_parent]) ) + $_wp_submenu_nopriv[$new_parent] = $_wp_submenu_nopriv[$old_parent]; + } +} +unset($id, $data, $subs, $first_sub, $old_parent, $new_parent); + +if ( is_network_admin() ) + do_action('network_admin_menu', ''); +elseif ( is_user_admin() ) + do_action('user_admin_menu', ''); +else + do_action('admin_menu', ''); + +// Remove menus that have no accessible submenus and require privs that the user does not have. +// Run re-parent loop again. +foreach ( $menu as $id => $data ) { + if ( ! current_user_can($data[1]) ) + $_wp_menu_nopriv[$data[2]] = true; + + // If submenu is empty... + if ( empty($submenu[$data[2]]) ) { + // And user doesn't have privs, remove menu. + if ( isset( $_wp_menu_nopriv[$data[2]] ) ) { + unset($menu[$id]); + } + } +} +unset($id, $data); + +// Remove any duplicated seperators +$seperator_found = false; +foreach ( $menu as $id => $data ) { + if ( 0 == strcmp('wp-menu-separator', $data[4] ) ) { + if (false == $seperator_found) { + $seperator_found = true; + } else { + unset($menu[$id]); + $seperator_found = false; + } + } else { + $seperator_found = false; + } +} +unset($id, $data); + +function add_cssclass($add, $class) { + $class = empty($class) ? $add : $class .= ' ' . $add; + return $class; +} + +function add_menu_classes($menu) { + + $first = $lastorder = false; + $i = 0; + $mc = count($menu); + foreach ( $menu as $order => $top ) { + $i++; + + if ( 0 == $order ) { // dashboard is always shown/single + $menu[0][4] = add_cssclass('menu-top-first', $top[4]); + $lastorder = 0; + continue; + } + + if ( 0 === strpos($top[2], 'separator') ) { // if separator + $first = true; + $c = $menu[$lastorder][4]; + $menu[$lastorder][4] = add_cssclass('menu-top-last', $c); + continue; + } + + if ( $first ) { + $c = $menu[$order][4]; + $menu[$order][4] = add_cssclass('menu-top-first', $c); + $first = false; + } + + if ( $mc == $i ) { // last item + $c = $menu[$order][4]; + $menu[$order][4] = add_cssclass('menu-top-last', $c); + } + + $lastorder = $order; + } + + return apply_filters( 'add_menu_classes', $menu ); +} + +uksort($menu, "strnatcasecmp"); // make it all pretty + +if ( apply_filters('custom_menu_order', false) ) { + $menu_order = array(); + foreach ( $menu as $menu_item ) { + $menu_order[] = $menu_item[2]; + } + unset($menu_item); + $default_menu_order = $menu_order; + $menu_order = apply_filters('menu_order', $menu_order); + $menu_order = array_flip($menu_order); + $default_menu_order = array_flip($default_menu_order); + + function sort_menu($a, $b) { + global $menu_order, $default_menu_order; + $a = $a[2]; + $b = $b[2]; + if ( isset($menu_order[$a]) && !isset($menu_order[$b]) ) { + return -1; + } elseif ( !isset($menu_order[$a]) && isset($menu_order[$b]) ) { + return 1; + } elseif ( isset($menu_order[$a]) && isset($menu_order[$b]) ) { + if ( $menu_order[$a] == $menu_order[$b] ) + return 0; + return ($menu_order[$a] < $menu_order[$b]) ? -1 : 1; + } else { + return ($default_menu_order[$a] <= $default_menu_order[$b]) ? -1 : 1; + } + } + + usort($menu, 'sort_menu'); + unset($menu_order, $default_menu_order); +} + +if ( !user_can_access_admin_page() ) { + do_action('admin_page_access_denied'); + wp_die( __('You do not have sufficient permissions to access this page.') ); +} + +$menu = add_menu_classes($menu); + +?> \ No newline at end of file diff --git a/src/wp-admin/includes/meta-boxes.php b/src/wp-admin/includes/meta-boxes.php new file mode 100644 index 00000000..a84ac16f --- /dev/null +++ b/src/wp-admin/includes/meta-boxes.php @@ -0,0 +1,915 @@ +post_type; + $post_type_object = get_post_type_object($post_type); + $can_publish = current_user_can($post_type_object->cap->publish_posts); +?> +
+ +
+ + +
+ +
+ +
+
+post_status && 'future' != $post->post_status && 'pending' != $post->post_status ) { ?> +post_status ) { ?>style="display:none" type="submit" name="save" id="save-post" value="" tabindex="4" class="button button-highlighted" /> +post_status && $can_publish ) { ?> + + + +
+ +
+post_status ) { + $preview_link = esc_url( get_permalink( $post->ID ) ); + $preview_button = __( 'Preview Changes' ); +} else { + $preview_link = get_permalink( $post->ID ); + if ( is_ssl() ) + $preview_link = str_replace( 'http://', 'https://', $preview_link ); + $preview_link = esc_url( apply_filters( 'preview_post_link', add_query_arg( 'preview', 'true', $preview_link ) ) ); + $preview_button = __( 'Preview' ); +} +?> + + +
+ +
+
+ +
+ +
+ +post_status ) { + case 'private': + _e('Privately Published'); + break; + case 'publish': + _e('Published'); + break; + case 'future': + _e('Scheduled'); + break; + case 'pending': + _e('Pending Review'); + break; + case 'draft': + case 'auto-draft': + _e('Draft'); + break; +} +?> + +post_status || 'private' == $post->post_status || $can_publish ) { ?> +post_status ) { ?>style="display:none;" class="edit-post-status hide-if-no-js" tabindex='4'> + +
+ + + + +
+ + +
+ +
+ post_status ) { + $post->post_password = ''; + $visibility = 'private'; + $visibility_trans = __('Private'); +} elseif ( !empty( $post->post_password ) ) { + $visibility = 'password'; + $visibility_trans = __('Password protected'); +} elseif ( $post_type == 'post' && is_sticky( $post->ID ) ) { + $visibility = 'public'; + $visibility_trans = __('Public, Sticky'); +} else { + $visibility = 'public'; + $visibility_trans = __('Public'); +} + +echo esc_html( $visibility_trans ); ?> + + + +
+ + +ID)); ?> /> + + + + + />
+ +ID)); ?> tabindex="4" />
+ + />
+
+ />
+ +

+ + +

+
+ + +
+ +ID ) { + if ( 'future' == $post->post_status ) { // scheduled for publishing at a future date + $stamp = __('Scheduled for: %1$s'); + } else if ( 'publish' == $post->post_status || 'private' == $post->post_status ) { // already published + $stamp = __('Published on: %1$s'); + } else if ( '0000-00-00 00:00:00' == $post->post_date_gmt ) { // draft, 1 or more saves, no date specified + $stamp = __('Publish immediately'); + } else if ( time() < strtotime( $post->post_date_gmt . ' +0000' ) ) { // draft, 1 or more saves, future date specified + $stamp = __('Schedule for: %1$s'); + } else { // draft, 1 or more saves, date specified + $stamp = __('Publish on: %1$s'); + } + $date = date_i18n( $datef, strtotime( $post->post_date ) ); +} else { // draft (no saves, and thus no date specified) + $stamp = __('Publish immediately'); + $date = date_i18n( $datef, strtotime( current_time('mysql') ) ); +} + +if ( $can_publish ) : // Contributors don't get to choose the date of publish ?> +
+ + + +
+
+ + + +
+
+
+ +
+ +
+ID ) ) { + if ( !EMPTY_TRASH_DAYS ) + $delete_text = __('Delete Permanently'); + else + $delete_text = __('Move to Trash'); + ?> + +
+ +
+ +post_status, array('publish', 'future', 'private') ) || 0 == $post->ID ) { + if ( $can_publish ) : + if ( !empty($post->post_date_gmt) && time() < strtotime( $post->post_date_gmt . ' +0000' ) ) : ?> + + '5', 'accesskey' => 'p' ) ); ?> + + + '5', 'accesskey' => 'p' ) ); ?> + + + '5', 'accesskey' => 'p' ) ); ?> + + + + +
+
+
+
+ +post_type, 'post-formats' ) ) : + $post_formats = get_theme_support( 'post-formats' ); + + if ( is_array( $post_formats[0] ) ) : + $post_format = get_post_format( $post->ID ); + if ( !$post_format ) + $post_format = '0'; + $post_format_display = get_post_format_string( $post_format ); + // Add in the current one if it isn't there yet, in case the current theme doesn't support it + if ( $post_format && !in_array( $post_format, $post_formats[0] ) ) + $post_formats[0][] = $post_format; + ?> +
+ /> + +
/> +
+
+ 'post_tag'); + if ( !isset($box['args']) || !is_array($box['args']) ) + $args = array(); + else + $args = $box['args']; + extract( wp_parse_args($args, $defaults), EXTR_SKIP ); + $tax_name = esc_attr($taxonomy); + $taxonomy = get_taxonomy($taxonomy); + $disabled = !current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : ''; +?> +
+
+
+

labels->add_or_remove_items; ?>

+
+ cap->assign_terms) ) : ?> +
+ +
labels->add_new_item; ?>
+

+

+
+

labels->separate_items_with_commas ); ?>

+ +
+
+
+cap->assign_terms) ) : ?> +

labels->choose_from_most_used; ?>

+ + 'category'); + if ( !isset($box['args']) || !is_array($box['args']) ) + $args = array(); + else + $args = $box['args']; + extract( wp_parse_args($args, $defaults), EXTR_SKIP ); + $tax = get_taxonomy($taxonomy); + + ?> +
+ + + + +
+ "; // Allows for an empty term set to be sent. 0 is an invalid Term ID and will be ignored by empty() checks. + ?> +
    + ID, array( 'taxonomy' => $taxonomy, 'popular_cats' => $popular_ids ) ) ?> +
+
+ cap->edit_terms) ) : ?> +
+

+ + labels->add_new_item ); + ?> + +

+

+ + + + $taxonomy, 'hide_empty' => 0, 'name' => 'new'.$taxonomy.'_parent', 'orderby' => 'name', 'hierarchical' => 1, 'show_option_none' => '— ' . $tax->labels->parent_item . ' —', 'tab_index' => 3 ) ); ?> + + + +

+
+ +
+ + +

Learn more about manual excerpts.'); ?>

+to_ping) ) .'" />'; + if ('' != $post->pinged) { + $pings = '

'. __('Already pinged:') . '

    '; + $already_pinged = explode("\n", trim($post->pinged)); + foreach ($already_pinged as $pinged_url) { + $pings .= "\n\t
  • " . esc_html($pinged_url) . "
  • "; + } + $pings .= '
'; + } + +?> +


()

+

pingbacks, no other action necessary.'); ?>

+ +
+
+ID); +list_meta($metadata); +meta_form(); ?> +
+

use in your theme.'); ?>

+ + +

+
+ + +

+get_var($wpdb->prepare("SELECT count(1) FROM $wpdb->comments WHERE comment_post_ID = '%d' AND ( comment_approved = '0' OR comment_approved = '1')", $post_ID)); + + if ( 1 > $total ) { + echo '

' . __('No comments yet.') . '

'; + return; + } + + wp_nonce_field( 'get-comments', 'add_comment_nonce', false ); + + $wp_list_table = _get_list_table('WP_Post_Comments_List_Table'); + $wp_list_table->display( true ); +?> +

+ + + + + + + 'authors', + 'name' => 'post_author_override', + 'selected' => empty($post->ID) ? $user_ID : $post->post_author, + 'include_selected' => true + ) ); +} + + +/** + * Display list of revisions. + * + * @since 2.6.0 + * + * @param object $post + */ +function post_revisions_meta_box($post) { + wp_list_post_revisions(); +} + + +// -- Page related Meta Boxes + +/** + * Display page attributes form fields. + * + * @since 2.7.0 + * + * @param object $post + */ +function page_attributes_meta_box($post) { + $post_type_object = get_post_type_object($post->post_type); + if ( $post_type_object->hierarchical ) { + $pages = wp_dropdown_pages(array('post_type' => $post->post_type, 'exclude_tree' => $post->ID, 'selected' => $post->post_parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)'), 'sort_column'=> 'menu_order, post_title', 'echo' => 0)); + if ( ! empty($pages) ) { +?> +

+ + +post_type && 0 != count( get_page_templates() ) ) { + $template = !empty($post->page_template) ? $post->page_template : false; + ?> +

+ + +

+

+

post_type ) _e( 'Need help? Use the Help tab in the upper right of your screen.' ); ?>

+ + + +
    +
  • +
  • +
+ +
+
    + link_id) ) + wp_link_category_checklist($link->link_id); + else + wp_link_category_checklist(); + ?> +
+
+ + + +
+

+ +
+ +
+

+

+

+
+

+link_rel ) ? $link->link_rel : ''; // In PHP 5.3: $link_rel = $link->link_rel ?: ''; + $rels = preg_split('/\s+/', $link_rel); + + if ('' != $value && in_array($value, $rels) ) { + echo ' checked="checked"'; + } + + if ('' == $value) { + if ('family' == $class && strpos($link_rel, 'child') === false && strpos($link_rel, 'parent') === false && strpos($link_rel, 'sibling') === false && strpos($link_rel, 'spouse') === false && strpos($link_rel, 'kin') === false) echo ' checked="checked"'; + if ('friendship' == $class && strpos($link_rel, 'friend') === false && strpos($link_rel, 'acquaintance') === false && strpos($link_rel, 'contact') === false) echo ' checked="checked"'; + if ('geographical' == $class && strpos($link_rel, 'co-resident') === false && strpos($link_rel, 'neighbor') === false) echo ' checked="checked"'; + if ('identity' == $class && in_array('me', $rels) ) echo ' checked="checked"'; + } +} + + +/** + * Display xfn form fields. + * + * @since 2.6.0 + * + * @param object $link + */ +function link_xfn_meta_box($link) { +?> + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ +
+ + +
+ + + +
+ + + + + + +
+ + + + +
+
+

XFN.'); ?>

+ + + + + + + + + + + + + + + + + + +
  +
+ID, '_thumbnail_id', true ); + echo _wp_post_thumbnail_html( $thumbnail_id ); +} diff --git a/src/wp-admin/includes/misc.php b/src/wp-admin/includes/misc.php new file mode 100644 index 00000000..d8ab0fca --- /dev/null +++ b/src/wp-admin/includes/misc.php @@ -0,0 +1,596 @@ + $markerline ) { + if (strpos($markerline, '# BEGIN ' . $marker) !== false) + $state = false; + if ( $state ) { + if ( $n + 1 < count( $markerdata ) ) + fwrite( $f, "{$markerline}\n" ); + else + fwrite( $f, "{$markerline}" ); + } + if (strpos($markerline, '# END ' . $marker) !== false) { + fwrite( $f, "# BEGIN {$marker}\n" ); + if ( is_array( $insertion )) + foreach ( $insertion as $insertline ) + fwrite( $f, "{$insertline}\n" ); + fwrite( $f, "# END {$marker}\n" ); + $state = true; + $foundit = true; + } + } + } + if (!$foundit) { + fwrite( $f, "\n# BEGIN {$marker}\n" ); + foreach ( $insertion as $insertline ) + fwrite( $f, "{$insertline}\n" ); + fwrite( $f, "# END {$marker}\n" ); + } + fclose( $f ); + return true; + } else { + return false; + } +} + +/** + * Updates the htaccess file with the current rules if it is writable. + * + * Always writes to the file if it exists and is writable to ensure that we + * blank out old rules. + * + * @since 1.5.0 + */ +function save_mod_rewrite_rules() { + if ( is_multisite() ) + return; + + global $wp_rewrite; + + $home_path = get_home_path(); + $htaccess_file = $home_path.'.htaccess'; + + // If the file doesn't already exist check for write access to the directory and whether we have some rules. + // else check for write access to the file. + if ((!file_exists($htaccess_file) && is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks()) || is_writable($htaccess_file)) { + if ( got_mod_rewrite() ) { + $rules = explode( "\n", $wp_rewrite->mod_rewrite_rules() ); + return insert_with_markers( $htaccess_file, 'WordPress', $rules ); + } + } + + return false; +} + +/** + * Updates the IIS web.config file with the current rules if it is writable. + * If the permalinks do not require rewrite rules then the rules are deleted from the web.config file. + * + * @since 2.8.0 + * + * @return bool True if web.config was updated successfully + */ +function iis7_save_url_rewrite_rules(){ + if ( is_multisite() ) + return; + + global $wp_rewrite; + + $home_path = get_home_path(); + $web_config_file = $home_path . 'web.config'; + + // Using win_is_writable() instead of is_writable() because of a bug in Windows PHP + if ( iis7_supports_permalinks() && ( ( ! file_exists($web_config_file) && win_is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks() ) || win_is_writable($web_config_file) ) ) { + $rule = $wp_rewrite->iis7_url_rewrite_rules(false, '', ''); + if ( ! empty($rule) ) { + return iis7_add_rewrite_rule($web_config_file, $rule); + } else { + return iis7_delete_rewrite_rule($web_config_file); + } + } + return false; +} + +/** + * {@internal Missing Short Description}} + * + * @since 1.5.0 + * + * @param unknown_type $file + */ +function update_recently_edited( $file ) { + $oldfiles = (array ) get_option( 'recently_edited' ); + if ( $oldfiles ) { + $oldfiles = array_reverse( $oldfiles ); + $oldfiles[] = $file; + $oldfiles = array_reverse( $oldfiles ); + $oldfiles = array_unique( $oldfiles ); + if ( 5 < count( $oldfiles )) + array_pop( $oldfiles ); + } else { + $oldfiles[] = $file; + } + update_option( 'recently_edited', $oldfiles ); +} + +/** + * If siteurl or home changed, flush rewrite rules. + * + * @since 2.1.0 + * + * @param unknown_type $old_value + * @param unknown_type $value + */ +function update_home_siteurl( $old_value, $value ) { + global $wp_rewrite; + + if ( defined( "WP_INSTALLING" ) ) + return; + + // If home changed, write rewrite rules to new location. + $wp_rewrite->flush_rules(); +} + +add_action( 'update_option_home', 'update_home_siteurl', 10, 2 ); +add_action( 'update_option_siteurl', 'update_home_siteurl', 10, 2 ); + +/** + * Shorten an URL, to be used as link text + * + * @since 1.2.1 + * + * @param string $url + * @return string + */ +function url_shorten( $url ) { + $short_url = str_replace( 'http://', '', stripslashes( $url )); + $short_url = str_replace( 'www.', '', $short_url ); + if ('/' == substr( $short_url, -1 )) + $short_url = substr( $short_url, 0, -1 ); + if ( strlen( $short_url ) > 35 ) + $short_url = substr( $short_url, 0, 32 ).'...'; + return $short_url; +} + +/** + * Resets global variables based on $_GET and $_POST + * + * This function resets global variables based on the names passed + * in the $vars array to the value of $_POST[$var] or $_GET[$var] or '' + * if neither is defined. + * + * @since 2.0.0 + * + * @param array $vars An array of globals to reset. + */ +function wp_reset_vars( $vars ) { + for ( $i=0; $iget_error_data() ) + $message = $message->get_error_message() . ': ' . $message->get_error_data(); + else + $message = $message->get_error_message(); + } + echo "

$message

\n"; + wp_ob_end_flush_all(); + flush(); +} + +function wp_doc_link_parse( $content ) { + if ( !is_string( $content ) || empty( $content ) ) + return array(); + + if ( !function_exists('token_get_all') ) + return array(); + + $tokens = token_get_all( $content ); + $functions = array(); + $ignore_functions = array(); + for ( $t = 0, $count = count( $tokens ); $t < $count; $t++ ) { + if ( !is_array( $tokens[$t] ) ) continue; + if ( T_STRING == $tokens[$t][0] && ( '(' == $tokens[ $t + 1 ] || '(' == $tokens[ $t + 2 ] ) ) { + // If it's a function or class defined locally, there's not going to be any docs available + if ( ( isset( $tokens[ $t - 2 ][1] ) && in_array( $tokens[ $t - 2 ][1], array( 'function', 'class' ) ) ) || ( isset( $tokens[ $t - 2 ][0] ) && T_OBJECT_OPERATOR == $tokens[ $t - 1 ][0] ) ) { + $ignore_functions[] = $tokens[$t][1]; + } + // Add this to our stack of unique references + $functions[] = $tokens[$t][1]; + } + } + + $functions = array_unique( $functions ); + sort( $functions ); + $ignore_functions = apply_filters( 'documentation_ignore_functions', $ignore_functions ); + $ignore_functions = array_unique( $ignore_functions ); + + $out = array(); + foreach ( $functions as $function ) { + if ( in_array( $function, $ignore_functions ) ) + continue; + $out[] = $function; + } + + return $out; +} + +/** + * Saves option for number of rows when listing posts, pages, comments, etc. + * + * @since 2.8 +**/ +function set_screen_options() { + + if ( isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options']) ) { + check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' ); + + if ( !$user = wp_get_current_user() ) + return; + $option = $_POST['wp_screen_options']['option']; + $value = $_POST['wp_screen_options']['value']; + + if ( !preg_match( '/^[a-z_-]+$/', $option ) ) + return; + + $option = str_replace('-', '_', $option); + + $map_option = $option; + $type = str_replace('edit_', '', $map_option); + $type = str_replace('_per_page', '', $type); + if ( in_array($type, get_post_types()) ) + $map_option = 'edit_per_page'; + if ( in_array( $type, get_taxonomies()) ) + $map_option = 'edit_tags_per_page'; + + + switch ( $map_option ) { + case 'edit_per_page': + case 'users_per_page': + case 'edit_comments_per_page': + case 'upload_per_page': + case 'edit_tags_per_page': + case 'plugins_per_page': + // Network admin + case 'sites_network_per_page': + case 'users_network_per_page': + case 'site_users_network_per_page': + case 'plugins_network_per_page': + case 'themes_network_per_page': + case 'site_themes_network_per_page': + $value = (int) $value; + if ( $value < 1 || $value > 999 ) + return; + break; + default: + $value = apply_filters('set-screen-option', false, $option, $value); + if ( false === $value ) + return; + break; + } + + update_user_meta($user->ID, $option, $value); + wp_redirect( remove_query_arg( array('pagenum', 'apage', 'paged'), wp_get_referer() ) ); + exit; + } +} + +function wp_menu_unfold() { + if ( isset($_GET['unfoldmenu']) ) { + delete_user_setting('mfold'); + wp_redirect( remove_query_arg( 'unfoldmenu', stripslashes($_SERVER['REQUEST_URI']) ) ); + exit; + } +} + +/** + * Check if rewrite rule for WordPress already exists in the IIS 7 configuration file + * + * @since 2.8.0 + * + * @return bool + * @param string $filename The file path to the configuration file + */ +function iis7_rewrite_rule_exists($filename) { + if ( ! file_exists($filename) ) + return false; + if ( ! class_exists('DOMDocument') ) + return false; + + $doc = new DOMDocument(); + if ( $doc->load($filename) === false ) + return false; + $xpath = new DOMXPath($doc); + $rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')]'); + if ( $rules->length == 0 ) + return false; + else + return true; +} + +/** + * Delete WordPress rewrite rule from web.config file if it exists there + * + * @since 2.8.0 + * + * @param string $filename Name of the configuration file + * @return bool + */ +function iis7_delete_rewrite_rule($filename) { + // If configuration file does not exist then rules also do not exist so there is nothing to delete + if ( ! file_exists($filename) ) + return true; + + if ( ! class_exists('DOMDocument') ) + return false; + + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; + + if ( $doc -> load($filename) === false ) + return false; + $xpath = new DOMXPath($doc); + $rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')]'); + if ( $rules->length > 0 ) { + $child = $rules->item(0); + $parent = $child->parentNode; + $parent->removeChild($child); + $doc->formatOutput = true; + saveDomDocument($doc, $filename); + } + return true; +} + +/** + * Add WordPress rewrite rule to the IIS 7 configuration file. + * + * @since 2.8.0 + * + * @param string $filename The file path to the configuration file + * @param string $rewrite_rule The XML fragment with URL Rewrite rule + * @return bool + */ +function iis7_add_rewrite_rule($filename, $rewrite_rule) { + if ( ! class_exists('DOMDocument') ) + return false; + + // If configuration file does not exist then we create one. + if ( ! file_exists($filename) ) { + $fp = fopen( $filename, 'w'); + fwrite($fp, ''); + fclose($fp); + } + + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; + + if ( $doc->load($filename) === false ) + return false; + + $xpath = new DOMXPath($doc); + + // First check if the rule already exists as in that case there is no need to re-add it + $wordpress_rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')]'); + if ( $wordpress_rules->length > 0 ) + return true; + + // Check the XPath to the rewrite rule and create XML nodes if they do not exist + $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite/rules'); + if ( $xmlnodes->length > 0 ) { + $rules_node = $xmlnodes->item(0); + } else { + $rules_node = $doc->createElement('rules'); + + $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite'); + if ( $xmlnodes->length > 0 ) { + $rewrite_node = $xmlnodes->item(0); + $rewrite_node->appendChild($rules_node); + } else { + $rewrite_node = $doc->createElement('rewrite'); + $rewrite_node->appendChild($rules_node); + + $xmlnodes = $xpath->query('/configuration/system.webServer'); + if ( $xmlnodes->length > 0 ) { + $system_webServer_node = $xmlnodes->item(0); + $system_webServer_node->appendChild($rewrite_node); + } else { + $system_webServer_node = $doc->createElement('system.webServer'); + $system_webServer_node->appendChild($rewrite_node); + + $xmlnodes = $xpath->query('/configuration'); + if ( $xmlnodes->length > 0 ) { + $config_node = $xmlnodes->item(0); + $config_node->appendChild($system_webServer_node); + } else { + $config_node = $doc->createElement('configuration'); + $doc->appendChild($config_node); + $config_node->appendChild($system_webServer_node); + } + } + } + } + + $rule_fragment = $doc->createDocumentFragment(); + $rule_fragment->appendXML($rewrite_rule); + $rules_node->appendChild($rule_fragment); + + $doc->encoding = "UTF-8"; + $doc->formatOutput = true; + saveDomDocument($doc, $filename); + + return true; +} + +/** + * Saves the XML document into a file + * + * @since 2.8.0 + * + * @param DOMDocument $doc + * @param string $filename + */ +function saveDomDocument($doc, $filename) { + $config = $doc->saveXML(); + $config = preg_replace("/([^\r])\n/", "$1\r\n", $config); + $fp = fopen($filename, 'w'); + fwrite($fp, $config); + fclose($fp); +} + +/** + * Workaround for Windows bug in is_writable() function + * + * @since 2.8.0 + * + * @param string $path + * @return bool + */ +function win_is_writable( $path ) { + /* will work in despite of Windows ACLs bug + * NOTE: use a trailing slash for folders!!! + * see http://bugs.php.net/bug.php?id=27609 + * see http://bugs.php.net/bug.php?id=30931 + */ + + if ( $path[strlen( $path ) - 1] == '/' ) // recursively return a temporary file path + return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp'); + else if ( is_dir( $path ) ) + return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' ); + // check tmp file for read/write capabilities + $should_delete_tmp_file = !file_exists( $path ); + $f = @fopen( $path, 'a' ); + if ( $f === false ) + return false; + fclose( $f ); + if ( $should_delete_tmp_file ) + unlink( $path ); + return true; +} + +/** + * Display the default admin color scheme picker (Used in user-edit.php) + * + * @since 3.0.0 + */ +function admin_color_scheme_picker() { + global $_wp_admin_css_colors, $user_id; ?> +
+ $color_info ): ?> +
/> + + + colors as $html_color ): ?> + + + +
 
+ + +
+ +
+ diff --git a/src/wp-admin/includes/ms-deprecated.php b/src/wp-admin/includes/ms-deprecated.php new file mode 100644 index 00000000..e7b017be --- /dev/null +++ b/src/wp-admin/includes/ms-deprecated.php @@ -0,0 +1,68 @@ + \ No newline at end of file diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php new file mode 100644 index 00000000..84585264 --- /dev/null +++ b/src/wp-admin/includes/ms.php @@ -0,0 +1,763 @@ + ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) ) + $file['error'] = sprintf(__('This file is too big. Files must be less than %1$s KB in size.'), get_site_option( 'fileupload_maxk', 1500 ) ); + if ( upload_is_user_over_quota( false ) ) { + $file['error'] = __( 'You have used your space quota. Please delete files before uploading.' ); + } + if ( $file['error'] != '0' && !isset($_POST['html-upload']) ) + wp_die( $file['error'] . ' ' . __( 'Back' ) . '' ); + + return $file; +} +add_filter( 'wp_handle_upload_prefilter', 'check_upload_size' ); + +/** + * Delete a blog + * + * @since 3.0.0 + * + * @param int $blog_id Blog ID + * @param bool $drop True if blog's table should be dropped. Default is false. + * @return void + */ +function wpmu_delete_blog( $blog_id, $drop = false ) { + global $wpdb; + + $switch = false; + if ( $blog_id != $wpdb->blogid ) { + $switch = true; + switch_to_blog( $blog_id ); + } + + $blog_prefix = $wpdb->get_blog_prefix( $blog_id ); + + do_action( 'delete_blog', $blog_id, $drop ); + + $users = get_users( array( 'blog_id' => $blog_id, 'fields' => 'ids' ) ); + + // Remove users from this blog. + if ( ! empty( $users ) ) { + foreach ( $users as $user_id ) { + remove_user_from_blog( $user_id, $blog_id) ; + } + } + + update_blog_status( $blog_id, 'deleted', 1 ); + + if ( $drop ) { + if ( substr( $blog_prefix, -1 ) == '_' ) + $blog_prefix = substr( $blog_prefix, 0, -1 ) . '\_'; + + $drop_tables = $wpdb->get_results( "SHOW TABLES LIKE '{$blog_prefix}%'", ARRAY_A ); + $drop_tables = apply_filters( 'wpmu_drop_tables', $drop_tables ); + + reset( $drop_tables ); + foreach ( (array) $drop_tables as $drop_table) { + $wpdb->query( "DROP TABLE IF EXISTS ". current( $drop_table ) ."" ); + } + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->blogs WHERE blog_id = %d", $blog_id ) ); + $dir = apply_filters( 'wpmu_delete_blog_upload_dir', WP_CONTENT_DIR . "/blogs.dir/{$blog_id}/files/", $blog_id ); + $dir = rtrim( $dir, DIRECTORY_SEPARATOR ); + $top_dir = $dir; + $stack = array($dir); + $index = 0; + + while ( $index < count( $stack ) ) { + # Get indexed directory from stack + $dir = $stack[$index]; + + $dh = @opendir( $dir ); + if ( $dh ) { + while ( ( $file = @readdir( $dh ) ) !== false ) { + if ( $file == '.' || $file == '..' ) + continue; + + if ( @is_dir( $dir . DIRECTORY_SEPARATOR . $file ) ) + $stack[] = $dir . DIRECTORY_SEPARATOR . $file; + else if ( @is_file( $dir . DIRECTORY_SEPARATOR . $file ) ) + @unlink( $dir . DIRECTORY_SEPARATOR . $file ); + } + } + $index++; + } + + $stack = array_reverse( $stack ); // Last added dirs are deepest + foreach( (array) $stack as $dir ) { + if ( $dir != $top_dir) + @rmdir( $dir ); + } + } + + $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key = '{$blog_prefix}autosave_draft_ids'" ); + $blogs = get_site_option( 'blog_list' ); + if ( is_array( $blogs ) ) { + foreach ( $blogs as $n => $blog ) { + if ( $blog['blog_id'] == $blog_id ) + unset( $blogs[$n] ); + } + update_site_option( 'blog_list', $blogs ); + } + + if ( $switch === true ) + restore_current_blog(); +} + +// @todo Merge with wp_delete_user() ? +function wpmu_delete_user( $id ) { + global $wpdb; + + $id = (int) $id; + + do_action( 'wpmu_delete_user', $id ); + + $blogs = get_blogs_of_user( $id ); + + if ( ! empty( $blogs ) ) { + foreach ( $blogs as $blog ) { + switch_to_blog( $blog->userblog_id ); + remove_user_from_blog( $id, $blog->userblog_id ); + + $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) ); + foreach ( (array) $post_ids as $post_id ) { + wp_delete_post( $post_id ); + } + + // Clean links + $link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id ) ); + + if ( $link_ids ) { + foreach ( $link_ids as $link_id ) + wp_delete_link( $link_id ); + } + + restore_current_blog(); + } + } + + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->users WHERE ID = %d", $id ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->usermeta WHERE user_id = %d", $id ) ); + + clean_user_cache( $id ); + + // allow for commit transaction + do_action( 'deleted_user', $id ); + + return true; +} + +function wpmu_get_blog_allowedthemes( $blog_id = 0 ) { + $themes = get_themes(); + + if ( $blog_id != 0 ) + switch_to_blog( $blog_id ); + + $blog_allowed_themes = get_option( 'allowedthemes' ); + if ( !is_array( $blog_allowed_themes ) || empty( $blog_allowed_themes ) ) { // convert old allowed_themes to new allowedthemes + $blog_allowed_themes = get_option( 'allowed_themes' ); + + if ( is_array( $blog_allowed_themes ) ) { + foreach( (array) $themes as $key => $theme ) { + $theme_key = esc_html( $theme['Stylesheet'] ); + if ( isset( $blog_allowed_themes[$key] ) == true ) { + $blog_allowedthemes[$theme_key] = 1; + } + } + $blog_allowed_themes = $blog_allowedthemes; + add_option( 'allowedthemes', $blog_allowed_themes ); + delete_option( 'allowed_themes' ); + } + } + + if ( $blog_id != 0 ) + restore_current_blog(); + + return $blog_allowed_themes; +} + +function update_option_new_admin_email( $old_value, $value ) { + $email = get_option( 'admin_email' ); + if ( $value == get_option( 'admin_email' ) || !is_email( $value ) ) + return; + + $hash = md5( $value. time() .mt_rand() ); + $new_admin_email = array( + 'hash' => $hash, + 'newemail' => $value + ); + update_option( 'adminhash', $new_admin_email ); + + $content = apply_filters( 'new_admin_email_content', __( "Dear user, + +You recently requested to have the administration email address on +your site changed. +If this is correct, please click on the following link to change it: +###ADMIN_URL### + +You can safely ignore and delete this email if you do not want to +take this action. + +This email has been sent to ###EMAIL### + +Regards, +All at ###SITENAME### +###SITEURL### "), $new_admin_email ); + + $content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'options.php?adminhash='.$hash ) ), $content ); + $content = str_replace( '###EMAIL###', $value, $content ); + $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content ); + $content = str_replace( '###SITEURL###', network_home_url(), $content ); + + wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), get_option( 'blogname' ) ), $content ); +} +add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10, 2 ); +add_action( 'add_option_new_admin_email', 'update_option_new_admin_email', 10, 2 ); + +function send_confirmation_on_profile_email() { + global $errors, $wpdb; + $current_user = wp_get_current_user(); + if ( ! is_object($errors) ) + $errors = new WP_Error(); + + if ( $current_user->id != $_POST['user_id'] ) + return false; + + if ( $current_user->user_email != $_POST['email'] ) { + if ( !is_email( $_POST['email'] ) ) { + $errors->add( 'user_email', __( "ERROR: The e-mail address isn't correct." ), array( 'form-field' => 'email' ) ); + return; + } + + if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM {$wpdb->users} WHERE user_email=%s", $_POST['email'] ) ) ) { + $errors->add( 'user_email', __( "ERROR: The e-mail address is already used." ), array( 'form-field' => 'email' ) ); + delete_option( $current_user->ID . '_new_email' ); + return; + } + + $hash = md5( $_POST['email'] . time() . mt_rand() ); + $new_user_email = array( + 'hash' => $hash, + 'newemail' => $_POST['email'] + ); + update_option( $current_user->ID . '_new_email', $new_user_email ); + + $content = apply_filters( 'new_user_email_content', __( "Dear user, + +You recently requested to have the email address on your account changed. +If this is correct, please click on the following link to change it: +###ADMIN_URL### + +You can safely ignore and delete this email if you do not want to +take this action. + +This email has been sent to ###EMAIL### + +Regards, +All at ###SITENAME### +###SITEURL###" ), $new_user_email ); + + $content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail='.$hash ) ), $content ); + $content = str_replace( '###EMAIL###', $_POST['email'], $content); + $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content ); + $content = str_replace( '###SITEURL###', network_home_url(), $content ); + + wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), get_option( 'blogname' ) ), $content ); + $_POST['email'] = $current_user->user_email; + } +} +add_action( 'personal_options_update', 'send_confirmation_on_profile_email' ); + +function new_user_email_admin_notice() { + if ( strpos( $_SERVER['PHP_SELF'], 'profile.php' ) && isset( $_GET['updated'] ) && $email = get_option( get_current_user_id() . '_new_email' ) ) + echo "
" . sprintf( __( "Your email address has not been updated yet. Please check your inbox at %s for a confirmation email." ), $email['newemail'] ) . "
"; +} +add_action( 'admin_notices', 'new_user_email_admin_notice' ); + +function get_site_allowed_themes() { + $themes = get_themes(); + $allowed_themes = get_site_option( 'allowedthemes' ); + if ( !is_array( $allowed_themes ) || empty( $allowed_themes ) ) { + $allowed_themes = get_site_option( 'allowed_themes' ); // convert old allowed_themes format + if ( !is_array( $allowed_themes ) ) { + $allowed_themes = array(); + } else { + foreach( (array) $themes as $key => $theme ) { + $theme_key = esc_html( $theme['Stylesheet'] ); + if ( isset( $allowed_themes[ $key ] ) == true ) { + $allowedthemes[ $theme_key ] = 1; + } + } + $allowed_themes = $allowedthemes; + } + } + return $allowed_themes; +} + +/** + * Determines if there is any upload space left in the current blog's quota. + * + * @since 3.0.0 + * @return bool True if space is available, false otherwise. + */ +function is_upload_space_available() { + if ( get_site_option( 'upload_space_check_disabled' ) ) + return true; + + if ( !( $space_allowed = get_upload_space_available() ) ) + return false; + + return true; +} + +/** + * @since 3.0.0 + * + * @return int of upload size limit in bytes + */ +function upload_size_limit_filter( $size ) { + $fileupload_maxk = 1024 * get_site_option( 'fileupload_maxk', 1500 ); + if ( get_site_option( 'upload_space_check_disabled' ) ) + return min( $size, $fileupload_maxk ); + + return min( $size, $fileupload_maxk, get_upload_space_available() ); +} +/** + * Determines if there is any upload space left in the current blog's quota. + * + * @return int of upload space available in bytes + */ +function get_upload_space_available() { + $space_allowed = get_space_allowed() * 1024 * 1024; + if ( get_site_option( 'upload_space_check_disabled' ) ) + return $space_allowed; + + $dir_name = trailingslashit( BLOGUPLOADDIR ); + if ( !( is_dir( $dir_name) && is_readable( $dir_name ) ) ) + return $space_allowed; + + $dir = dir( $dir_name ); + $size = 0; + + while ( $file = $dir->read() ) { + if ( $file != '.' && $file != '..' ) { + if ( is_dir( $dir_name . $file) ) { + $size += get_dirsize( $dir_name . $file ); + } else { + $size += filesize( $dir_name . $file ); + } + } + } + $dir->close(); + + if ( ( $space_allowed - $size ) <= 0 ) + return 0; + + return $space_allowed - $size; +} + +/** + * Returns the upload quota for the current blog. + * + * @return int Quota + */ +function get_space_allowed() { + $space_allowed = get_option( 'blog_upload_space' ); + if ( $space_allowed == false ) + $space_allowed = get_site_option( 'blog_upload_space' ); + if ( empty( $space_allowed ) || !is_numeric( $space_allowed ) ) + $space_allowed = 50; + + return $space_allowed; +} + +function display_space_usage() { + $space = get_space_allowed(); + $used = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024; + + $percentused = ( $used / $space ) * 100; + + if ( $space > 1000 ) { + $space = number_format( $space / 1024 ); + /* translators: Gigabytes */ + $space .= __( 'GB' ); + } else { + /* translators: Megabytes */ + $space .= __( 'MB' ); + } + ?> + + + + + + + update( $wpdb->users, array( $pref => $value ), array( 'ID' => $id ) ); + + clean_user_cache( $id ); + + if ( $pref == 'spam' ) { + if ( $value == 1 ) + do_action( 'make_spam_user', $id ); + else + do_action( 'make_ham_user', $id ); + } + + return $value; +} + +function refresh_user_details( $id ) { + $id = (int) $id; + + if ( !$user = get_userdata( $id ) ) + return false; + + clean_user_cache( $id ); + + return $id; +} + +function format_code_lang( $code = '' ) { + $code = strtolower( substr( $code, 0, 2 ) ); + $lang_codes = array( + 'aa' => 'Afar', 'ab' => 'Abkhazian', 'af' => 'Afrikaans', 'ak' => 'Akan', 'sq' => 'Albanian', 'am' => 'Amharic', 'ar' => 'Arabic', 'an' => 'Aragonese', 'hy' => 'Armenian', 'as' => 'Assamese', 'av' => 'Avaric', 'ae' => 'Avestan', 'ay' => 'Aymara', 'az' => 'Azerbaijani', 'ba' => 'Bashkir', 'bm' => 'Bambara', 'eu' => 'Basque', 'be' => 'Belarusian', 'bn' => 'Bengali', + 'bh' => 'Bihari', 'bi' => 'Bislama', 'bs' => 'Bosnian', 'br' => 'Breton', 'bg' => 'Bulgarian', 'my' => 'Burmese', 'ca' => 'Catalan; Valencian', 'ch' => 'Chamorro', 'ce' => 'Chechen', 'zh' => 'Chinese', 'cu' => 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic', 'cv' => 'Chuvash', 'kw' => 'Cornish', 'co' => 'Corsican', 'cr' => 'Cree', + 'cs' => 'Czech', 'da' => 'Danish', 'dv' => 'Divehi; Dhivehi; Maldivian', 'nl' => 'Dutch; Flemish', 'dz' => 'Dzongkha', 'en' => 'English', 'eo' => 'Esperanto', 'et' => 'Estonian', 'ee' => 'Ewe', 'fo' => 'Faroese', 'fj' => 'Fijjian', 'fi' => 'Finnish', 'fr' => 'French', 'fy' => 'Western Frisian', 'ff' => 'Fulah', 'ka' => 'Georgian', 'de' => 'German', 'gd' => 'Gaelic; Scottish Gaelic', + 'ga' => 'Irish', 'gl' => 'Galician', 'gv' => 'Manx', 'el' => 'Greek, Modern', 'gn' => 'Guarani', 'gu' => 'Gujarati', 'ht' => 'Haitian; Haitian Creole', 'ha' => 'Hausa', 'he' => 'Hebrew', 'hz' => 'Herero', 'hi' => 'Hindi', 'ho' => 'Hiri Motu', 'hu' => 'Hungarian', 'ig' => 'Igbo', 'is' => 'Icelandic', 'io' => 'Ido', 'ii' => 'Sichuan Yi', 'iu' => 'Inuktitut', 'ie' => 'Interlingue', + 'ia' => 'Interlingua (International Auxiliary Language Association)', 'id' => 'Indonesian', 'ik' => 'Inupiaq', 'it' => 'Italian', 'jv' => 'Javanese', 'ja' => 'Japanese', 'kl' => 'Kalaallisut; Greenlandic', 'kn' => 'Kannada', 'ks' => 'Kashmiri', 'kr' => 'Kanuri', 'kk' => 'Kazakh', 'km' => 'Central Khmer', 'ki' => 'Kikuyu; Gikuyu', 'rw' => 'Kinyarwanda', 'ky' => 'Kirghiz; Kyrgyz', + 'kv' => 'Komi', 'kg' => 'Kongo', 'ko' => 'Korean', 'kj' => 'Kuanyama; Kwanyama', 'ku' => 'Kurdish', 'lo' => 'Lao', 'la' => 'Latin', 'lv' => 'Latvian', 'li' => 'Limburgan; Limburger; Limburgish', 'ln' => 'Lingala', 'lt' => 'Lithuanian', 'lb' => 'Luxembourgish; Letzeburgesch', 'lu' => 'Luba-Katanga', 'lg' => 'Ganda', 'mk' => 'Macedonian', 'mh' => 'Marshallese', 'ml' => 'Malayalam', + 'mi' => 'Maori', 'mr' => 'Marathi', 'ms' => 'Malay', 'mg' => 'Malagasy', 'mt' => 'Maltese', 'mo' => 'Moldavian', 'mn' => 'Mongolian', 'na' => 'Nauru', 'nv' => 'Navajo; Navaho', 'nr' => 'Ndebele, South; South Ndebele', 'nd' => 'Ndebele, North; North Ndebele', 'ng' => 'Ndonga', 'ne' => 'Nepali', 'nn' => 'Norwegian Nynorsk; Nynorsk, Norwegian', 'nb' => 'Bokmål, Norwegian, Norwegian Bokmål', + 'no' => 'Norwegian', 'ny' => 'Chichewa; Chewa; Nyanja', 'oc' => 'Occitan, Provençal', 'oj' => 'Ojibwa', 'or' => 'Oriya', 'om' => 'Oromo', 'os' => 'Ossetian; Ossetic', 'pa' => 'Panjabi; Punjabi', 'fa' => 'Persian', 'pi' => 'Pali', 'pl' => 'Polish', 'pt' => 'Portuguese', 'ps' => 'Pushto', 'qu' => 'Quechua', 'rm' => 'Romansh', 'ro' => 'Romanian', 'rn' => 'Rundi', 'ru' => 'Russian', + 'sg' => 'Sango', 'sa' => 'Sanskrit', 'sr' => 'Serbian', 'hr' => 'Croatian', 'si' => 'Sinhala; Sinhalese', 'sk' => 'Slovak', 'sl' => 'Slovenian', 'se' => 'Northern Sami', 'sm' => 'Samoan', 'sn' => 'Shona', 'sd' => 'Sindhi', 'so' => 'Somali', 'st' => 'Sotho, Southern', 'es' => 'Spanish; Castilian', 'sc' => 'Sardinian', 'ss' => 'Swati', 'su' => 'Sundanese', 'sw' => 'Swahili', + 'sv' => 'Swedish', 'ty' => 'Tahitian', 'ta' => 'Tamil', 'tt' => 'Tatar', 'te' => 'Telugu', 'tg' => 'Tajik', 'tl' => 'Tagalog', 'th' => 'Thai', 'bo' => 'Tibetan', 'ti' => 'Tigrinya', 'to' => 'Tonga (Tonga Islands)', 'tn' => 'Tswana', 'ts' => 'Tsonga', 'tk' => 'Turkmen', 'tr' => 'Turkish', 'tw' => 'Twi', 'ug' => 'Uighur; Uyghur', 'uk' => 'Ukrainian', 'ur' => 'Urdu', 'uz' => 'Uzbek', + 've' => 'Venda', 'vi' => 'Vietnamese', 'vo' => 'Volapük', 'cy' => 'Welsh','wa' => 'Walloon','wo' => 'Wolof', 'xh' => 'Xhosa', 'yi' => 'Yiddish', 'yo' => 'Yoruba', 'za' => 'Zhuang; Chuang', 'zu' => 'Zulu' ); + $lang_codes = apply_filters( 'lang_codes', $lang_codes, $code ); + return strtr( $code, $lang_codes ); +} + +function sync_category_tag_slugs( $term, $taxonomy ) { + if ( global_terms_enabled() && ( $taxonomy == 'category' || $taxonomy == 'post_tag' ) ) { + if ( is_object( $term ) ) { + $term->slug = sanitize_title( $term->name ); + } else { + $term['slug'] = sanitize_title( $term['name'] ); + } + } + return $term; +} +add_filter( 'get_term', 'sync_category_tag_slugs', 10, 2 ); + +function redirect_user_to_blog() { + $c = 0; + if ( isset( $_GET['c'] ) ) + $c = (int) $_GET['c']; + + if ( $c >= 5 ) { + wp_die( __( "You don’t have permission to view this site. Please contact the system administrator." ) ); + } + $c ++; + + $blog = get_active_blog_for_user( get_current_user_id() ); + + if ( is_object( $blog ) ) { + wp_redirect( get_admin_url( $blog->blog_id, '?c=' . $c ) ); // redirect and count to 5, "just in case" + } else { + wp_redirect( user_admin_url( '?c=' . $c ) ); // redirect and count to 5, "just in case" + } + exit; +} +add_action( 'admin_page_access_denied', 'redirect_user_to_blog', 99 ); + +function check_import_new_users( $permission ) { + if ( !is_super_admin() ) + return false; + return true; +} +add_filter( 'import_allow_create_users', 'check_import_new_users' ); +// See "import_allow_fetch_attachments" and "import_attachment_size_limit" filters too. + +function mu_dropdown_languages( $lang_files = array(), $current = '' ) { + $flag = false; + $output = array(); + + foreach ( (array) $lang_files as $val ) { + $code_lang = basename( $val, '.mo' ); + + if ( $code_lang == 'en_US' ) { // American English + $flag = true; + $ae = __( 'American English' ); + $output[$ae] = ''; + } elseif ( $code_lang == 'en_GB' ) { // British English + $flag = true; + $be = __( 'British English' ); + $output[$be] = ''; + } else { + $translated = format_code_lang( $code_lang ); + $output[$translated] = ''; + } + + } + + if ( $flag === false ) // WordPress english + $output[] = '"; + + // Order by name + uksort( $output, 'strnatcasecmp' ); + + $output = apply_filters( 'mu_dropdown_languages', $output, $lang_files, $current ); + echo implode( "\n\t", $output ); +} + +/* Warn the admin if SECRET SALT information is missing from wp-config.php */ +function secret_salt_warning() { + if ( !is_super_admin() ) + return; + $secret_keys = array( 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY', 'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT' ); + $out = ''; + foreach( $secret_keys as $key ) { + if ( ! defined( $key ) ) + $out .= "define( '$key', '" . esc_html( wp_generate_password( 64, true, true ) ) . "' );
"; + } + if ( $out != '' ) { + $msg = __( 'Warning! WordPress encrypts user cookies, but you must add the following lines to wp-config.php for it to be more secure.' ); + $msg .= '
' . __( "Before the line /* That's all, stop editing! Happy blogging. */ please add this code:" ); + $msg .= "

$out"; + + echo "
$msg
"; + } +} +add_action( 'network_admin_notices', 'secret_salt_warning' ); + +function site_admin_notice() { + global $wp_db_version; + if ( !is_super_admin() ) + return false; + if ( get_site_option( 'wpmu_upgrade_site' ) != $wp_db_version ) + echo "
" . sprintf( __( 'Thank you for Updating! Please visit the Update Network page to update all your sites.' ), esc_url( network_admin_url( 'upgrade.php' ) ) ) . "
"; +} +add_action( 'admin_notices', 'site_admin_notice' ); +add_action( 'network_admin_notices', 'site_admin_notice' ); + +function avoid_blog_page_permalink_collision( $data, $postarr ) { + if ( is_subdomain_install() ) + return $data; + if ( $data['post_type'] != 'page' ) + return $data; + if ( !isset( $data['post_name'] ) || $data['post_name'] == '' ) + return $data; + if ( !is_main_site() ) + return $data; + + $post_name = $data['post_name']; + $c = 0; + while( $c < 10 && get_id_from_blogname( $post_name ) ) { + $post_name .= mt_rand( 1, 10 ); + $c ++; + } + if ( $post_name != $data['post_name'] ) { + $data['post_name'] = $post_name; + } + return $data; +} +add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 ); + +function choose_primary_blog() { + ?> + + + + + + + + + + + +
+ 1 ) { + $found = false; + ?> + + userblog_id ); + } + } elseif ( count( $all_blogs ) == 1 ) { + $blog = array_shift( $all_blogs ); + echo $blog->domain; + if ( $primary_blog != $blog->userblog_id ) // Set the primary blog again if it's out of sync with blog list. + update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id ); + } else { + echo "N/A"; + } + ?> +
+ +
+ ' . sprintf( __( 'The %1$s file is deprecated. Please remove it and update your server rewrite rules to use %2$s instead.' ), 'wp-content/blogs.php', 'wp-includes/ms-files.php' ) . ''; +} +add_action( 'network_admin_notices', 'ms_deprecated_blogs_file' ); + +/** + * Grants super admin privileges. + * + * @since 3.0.0 + * @param int $user_id + */ +function grant_super_admin( $user_id ) { + global $super_admins; + + // If global super_admins override is defined, there is nothing to do here. + if ( isset($super_admins) ) + return false; + + do_action( 'grant_super_admin', $user_id ); + + // Directly fetch site_admins instead of using get_super_admins() + $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); + + $user = new WP_User( $user_id ); + if ( ! in_array( $user->user_login, $super_admins ) ) { + $super_admins[] = $user->user_login; + update_site_option( 'site_admins' , $super_admins ); + do_action( 'granted_super_admin', $user_id ); + return true; + } + return false; +} + +/** + * Revokes super admin privileges. + * + * @since 3.0.0 + * @param int $user_id + */ +function revoke_super_admin( $user_id ) { + global $super_admins; + + // If global super_admins override is defined, there is nothing to do here. + if ( isset($super_admins) ) + return false; + + do_action( 'revoke_super_admin', $user_id ); + + // Directly fetch site_admins instead of using get_super_admins() + $super_admins = get_site_option( 'site_admins', array( 'admin' ) ); + + $user = new WP_User( $user_id ); + if ( $user->user_email != get_site_option( 'admin_email' ) ) { + if ( false !== ( $key = array_search( $user->user_login, $super_admins ) ) ) { + unset( $super_admins[$key] ); + update_site_option( 'site_admins', $super_admins ); + do_action( 'revoked_super_admin', $user_id ); + return true; + } + } + return false; +} + +/** + * Whether or not we can edit this network from this page + * + * By default editing of network is restricted to the Network Admin for that site_id this allows for this to be overridden + * + * @since 3.1.0 + * @param integer $site_id The network/site id to check. + */ +function can_edit_network( $site_id ) { + global $wpdb; + + if ($site_id == $wpdb->siteid ) + $result = true; + else + $result = false; + + return apply_filters( 'can_edit_network', $result, $site_id ); +} + +/** + * Thickbox image paths for Network Admin. + * + * @since 3.1.0 + * @access private + */ +function _thickbox_path_admin_subfolder() { +?> + + diff --git a/src/wp-admin/includes/nav-menu.php b/src/wp-admin/includes/nav-menu.php new file mode 100644 index 00000000..6e929286 --- /dev/null +++ b/src/wp-admin/includes/nav-menu.php @@ -0,0 +1,1133 @@ + $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth; + + $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; + + ob_start(); + $item_id = esc_attr( $item->ID ); + $removed_args = array( + 'action', + 'customlink-tab', + 'edit-menu-item', + 'menu-item', + 'page-tab', + '_wpnonce', + ); + + $original_title = ''; + if ( 'taxonomy' == $item->type ) { + $original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' ); + } elseif ( 'post_type' == $item->type ) { + $original_object = get_post( $item->object_id ); + $original_title = $original_object->post_title; + } + + $classes = array( + 'menu-item menu-item-depth-' . $depth, + 'menu-item-' . esc_attr( $item->object ), + 'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'), + ); + + $title = $item->title; + + if ( isset( $item->post_status ) && 'draft' == $item->post_status ) { + $classes[] = 'pending'; + /* translators: %s: title of menu item in draft status */ + $title = sprintf( __('%s (Pending)'), $item->title ); + } + + $title = empty( $item->label ) ? $title : $item->label; + + ?> +
  • '; + $output .= ''; + + // Menu item hidden fields + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + } +} + +/** + * Prints the appropriate response to a menu quick search. + * + * @since 3.0.0 + * + * @param array $request The unsanitized request values. + */ +function _wp_ajax_menu_quick_search( $request = array() ) { + $args = array(); + $type = isset( $request['type'] ) ? $request['type'] : ''; + $object_type = isset( $request['object_type'] ) ? $request['object_type'] : ''; + $query = isset( $request['q'] ) ? $request['q'] : ''; + $response_format = isset( $request['response-format'] ) && in_array( $request['response-format'], array( 'json', 'markup' ) ) ? $request['response-format'] : 'json'; + + if ( 'markup' == $response_format ) { + $args['walker'] = new Walker_Nav_Menu_Checklist; + } + + if ( 'get-post-item' == $type ) { + if ( post_type_exists( $object_type ) ) { + if ( isset( $request['ID'] ) ) { + $object_id = (int) $request['ID']; + if ( 'markup' == $response_format ) { + echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $object_id ) ) ), 0, (object) $args ); + } elseif ( 'json' == $response_format ) { + $post_obj = get_post( $object_id ); + echo json_encode( + array( + 'ID' => $object_id, + 'post_title' => get_the_title( $object_id ), + 'post_type' => get_post_type( $object_id ), + ) + ); + echo "\n"; + } + } + } elseif ( taxonomy_exists( $object_type ) ) { + if ( isset( $request['ID'] ) ) { + $object_id = (int) $request['ID']; + if ( 'markup' == $response_format ) { + echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_term( $object_id, $object_type ) ) ), 0, (object) $args ); + } elseif ( 'json' == $response_format ) { + $post_obj = get_term( $object_id, $object_type ); + echo json_encode( + array( + 'ID' => $object_id, + 'post_title' => $post_obj->name, + 'post_type' => $object_type, + ) + ); + echo "\n"; + } + } + + } + + + } elseif ( preg_match('/quick-search-(posttype|taxonomy)-([a-zA-Z_-]*\b)/', $type, $matches) ) { + if ( 'posttype' == $matches[1] && get_post_type_object( $matches[2] ) ) { + query_posts(array( + 'posts_per_page' => 10, + 'post_type' => $matches[2], + 's' => $query, + )); + if ( ! have_posts() ) + return; + while ( have_posts() ) { + the_post(); + if ( 'markup' == $response_format ) { + echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $var_by_ref = get_the_ID() ) ) ), 0, (object) $args ); + } elseif ( 'json' == $response_format ) { + echo json_encode( + array( + 'ID' => get_the_ID(), + 'post_title' => get_the_title(), + 'post_type' => get_post_type(), + ) + ); + echo "\n"; + } + } + } elseif ( 'taxonomy' == $matches[1] ) { + $terms = get_terms( $matches[2], array( + 'name__like' => $query, + 'number' => 10, + )); + if ( empty( $terms ) || is_wp_error( $terms ) ) + return; + foreach( (array) $terms as $term ) { + if ( 'markup' == $response_format ) { + echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( $term ) ), 0, (object) $args ); + } elseif ( 'json' == $response_format ) { + echo json_encode( + array( + 'ID' => $term->term_id, + 'post_title' => $term->name, + 'post_type' => $matches[2], + ) + ); + echo "\n"; + } + } + } + } +} + +/** + * Register nav menu metaboxes and advanced menu items + * + * @since 3.0.0 + **/ +function wp_nav_menu_setup() { + // Register meta boxes + if ( wp_get_nav_menus() ) + add_meta_box( 'nav-menu-theme-locations', __( 'Theme Locations' ), 'wp_nav_menu_locations_meta_box' , 'nav-menus', 'side', 'default' ); + add_meta_box( 'add-custom-links', __('Custom Links'), 'wp_nav_menu_item_link_meta_box', 'nav-menus', 'side', 'default' ); + wp_nav_menu_post_type_meta_boxes(); + wp_nav_menu_taxonomy_meta_boxes(); + + // Register advanced menu items (columns) + add_filter( 'manage_nav-menus_columns', 'wp_nav_menu_manage_columns'); + + // If first time editing, disable advanced items by default. + if( false === get_user_option( 'managenav-menuscolumnshidden' ) ) { + $user = wp_get_current_user(); + update_user_option($user->ID, 'managenav-menuscolumnshidden', + array( 0 => 'link-target', 1 => 'css-classes', 2 => 'xfn', 3 => 'description', ), + true); + } +} + +/** + * Limit the amount of meta boxes to just links, pages and cats for first time users. + * + * @since 3.0.0 + **/ +function wp_initial_nav_menu_meta_boxes() { + global $wp_meta_boxes; + + if ( get_user_option( 'metaboxhidden_nav-menus' ) !== false || ! is_array($wp_meta_boxes) ) + return; + + $initial_meta_boxes = array( 'nav-menu-theme-locations', 'add-custom-links', 'add-page', 'add-category' ); + $hidden_meta_boxes = array(); + + foreach ( array_keys($wp_meta_boxes['nav-menus']) as $context ) { + foreach ( array_keys($wp_meta_boxes['nav-menus'][$context]) as $priority ) { + foreach ( $wp_meta_boxes['nav-menus'][$context][$priority] as $box ) { + if ( in_array( $box['id'], $initial_meta_boxes ) ) { + unset( $box['id'] ); + } else { + $hidden_meta_boxes[] = $box['id']; + } + } + } + } + + $user = wp_get_current_user(); + update_user_option( $user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true ); +} + +/** + * Creates metaboxes for any post type menu item. + * + * @since 3.0.0 + */ +function wp_nav_menu_post_type_meta_boxes() { + $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'object' ); + + if ( ! $post_types ) + return; + + foreach ( $post_types as $post_type ) { + $post_type = apply_filters( 'nav_menu_meta_box_object', $post_type ); + if ( $post_type ) { + $id = $post_type->name; + add_meta_box( "add-{$id}", $post_type->labels->name, 'wp_nav_menu_item_post_type_meta_box', 'nav-menus', 'side', 'default', $post_type ); + } + } +} + +/** + * Creates metaboxes for any taxonomy menu item. + * + * @since 3.0.0 + */ +function wp_nav_menu_taxonomy_meta_boxes() { + $taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'object' ); + + if ( !$taxonomies ) + return; + + foreach ( $taxonomies as $tax ) { + $tax = apply_filters( 'nav_menu_meta_box_object', $tax ); + if ( $tax ) { + $id = $tax->name; + add_meta_box( "add-{$id}", $tax->labels->name, 'wp_nav_menu_item_taxonomy_meta_box', 'nav-menus', 'side', 'default', $tax ); + } + } +} + +/** + * Displays a metabox for the nav menu theme locations. + * + * @since 3.0.0 + */ +function wp_nav_menu_locations_meta_box() { + global $nav_menu_selected_id; + + if ( ! current_theme_supports( 'menus' ) ) { + // We must only support widgets. Leave a message and bail. + echo '

    ' . __('The current theme does not natively support menus, but you can use the “Custom Menu” widget to add any menus you create here to the theme’s sidebar.') . '

    '; + return; + } + + $locations = get_registered_nav_menus(); + $menus = wp_get_nav_menus(); + $menu_locations = get_nav_menu_locations(); + $num_locations = count( array_keys($locations) ); + + echo '

    ' . sprintf( _n('Your theme supports %s menu. Select which menu you would like to use.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n($num_locations) ) . '

    '; + + foreach ( $locations as $location => $description ) { + ?> +

    + +

    + +

    + + +

    + $_nav_menu_placeholder ? $_nav_menu_placeholder - 1 : -1; + + $current_tab = 'create'; + if ( isset( $_REQUEST['customlink-tab'] ) && in_array( $_REQUEST['customlink-tab'], array('create', 'all') ) ) { + $current_tab = $_REQUEST['customlink-tab']; + } + + $removed_args = array( + 'action', + 'customlink-tab', + 'edit-menu-item', + 'menu-item', + 'page-tab', + '_wpnonce', + ); + + ?> +
    + + + + + + +

    + + + class="button-secondary submit-add-to-menu" value="" name="add-custom-menu-item" id="submit-customlinkdiv" /> + +

    + +
    + name; + + // paginate browsing for large numbers of post objects + $per_page = 50; + $pagenum = isset( $_REQUEST[$post_type_name . '-tab'] ) && isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1; + $offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0; + + $args = array( + 'offset' => $offset, + 'order' => 'ASC', + 'orderby' => 'title', + 'posts_per_page' => $per_page, + 'post_type' => $post_type_name, + 'suppress_filters' => true, + 'update_post_term_cache' => false, + 'update_post_meta_cache' => false + ); + + if ( isset( $post_type['args']->_default_query ) ) + $args = array_merge($args, (array) $post_type['args']->_default_query ); + + // @todo transient caching of these results with proper invalidation on updating of a post of this type + $get_posts = new WP_Query; + $posts = $get_posts->query( $args ); + if ( ! $get_posts->post_count ) { + echo '

    ' . __( 'No items.' ) . '

    '; + return; + } + + $post_type_object = get_post_type_object($post_type_name); + + $num_pages = $get_posts->max_num_pages; + + $page_links = paginate_links( array( + 'base' => add_query_arg( + array( + $post_type_name . '-tab' => 'all', + 'paged' => '%#%', + 'item-type' => 'post_type', + 'item-object' => $post_type_name, + ) + ), + 'format' => '', + 'prev_text' => __('«'), + 'next_text' => __('»'), + 'total' => $num_pages, + 'current' => $pagenum + )); + + if ( !$posts ) + $error = '
  • '. $post_type['args']->labels->not_found .'
  • '; + + $walker = new Walker_Nav_Menu_Checklist; + + $current_tab = 'most-recent'; + if ( isset( $_REQUEST[$post_type_name . '-tab'] ) && in_array( $_REQUEST[$post_type_name . '-tab'], array('all', 'search') ) ) { + $current_tab = $_REQUEST[$post_type_name . '-tab']; + } + + if ( ! empty( $_REQUEST['quick-search-posttype-' . $post_type_name] ) ) { + $current_tab = 'search'; + } + + $removed_args = array( + 'action', + 'customlink-tab', + 'edit-menu-item', + 'menu-item', + 'page-tab', + '_wpnonce', + ); + + ?> +
    +
      +
    • >
    • +
    • >
    • +
    • >
    • +
    + +
    +
      + 'post_date', 'order' => 'DESC', 'posts_per_page' => 15 ) ); + $most_recent = $get_posts->query( $recent_args ); + $args['walker'] = $walker; + echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $most_recent), 0, (object) $args ); + ?> +
    +
    + + + + +
    + + + +
      + _add_to_top = true; + $front_page_obj->label = sprintf( _x('Home: %s', 'nav menu front page title'), $front_page_obj->post_title ); + array_unshift( $posts, $front_page_obj ); + } else { + $_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval($_nav_menu_placeholder) - 1 : -1; + array_unshift( $posts, (object) array( + '_add_to_top' => true, + 'ID' => 0, + 'object_id' => $_nav_menu_placeholder, + 'post_content' => '', + 'post_excerpt' => '', + 'post_title' => _x('Home', 'nav menu home label'), + 'post_type' => 'nav_menu_item', + 'type' => 'custom', + 'url' => home_url('/'), + ) ); + } + } + + $checkbox_items = walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $posts), 0, (object) $args ); + + if ( 'all' == $current_tab && ! empty( $_REQUEST['selectall'] ) ) { + $checkbox_items = preg_replace('/(type=(.)checkbox(\2))/', '$1 checked=$2checked$2', $checkbox_items); + + } + + echo $checkbox_items; + ?> +
    + + + +
    + + +

    + + + + + + + class="button-secondary submit-add-to-menu" value="" name="add-post-type-menu-item" id="submit-posttype-" /> + +

    + +
    + name; + + // paginate browsing for large numbers of objects + $per_page = 50; + $pagenum = isset( $_REQUEST[$taxonomy_name . '-tab'] ) && isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1; + $offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0; + + $args = array( + 'child_of' => 0, + 'exclude' => '', + 'hide_empty' => false, + 'hierarchical' => 1, + 'include' => '', + 'include_last_update_time' => false, + 'number' => $per_page, + 'offset' => $offset, + 'order' => 'ASC', + 'orderby' => 'name', + 'pad_counts' => false, + ); + + $terms = get_terms( $taxonomy_name, $args ); + + if ( ! $terms || is_wp_error($terms) ) { + echo '

    ' . __( 'No items.' ) . '

    '; + return; + } + + $num_pages = ceil( wp_count_terms( $taxonomy_name , array_merge( $args, array('number' => '', 'offset' => '') ) ) / $per_page ); + + $page_links = paginate_links( array( + 'base' => add_query_arg( + array( + $taxonomy_name . '-tab' => 'all', + 'paged' => '%#%', + 'item-type' => 'taxonomy', + 'item-object' => $taxonomy_name, + ) + ), + 'format' => '', + 'prev_text' => __('«'), + 'next_text' => __('»'), + 'total' => $num_pages, + 'current' => $pagenum + )); + + $walker = new Walker_Nav_Menu_Checklist; + + $current_tab = 'most-used'; + if ( isset( $_REQUEST[$taxonomy_name . '-tab'] ) && in_array( $_REQUEST[$taxonomy_name . '-tab'], array('all', 'most-used', 'search') ) ) { + $current_tab = $_REQUEST[$taxonomy_name . '-tab']; + } + + if ( ! empty( $_REQUEST['quick-search-taxonomy-' . $taxonomy_name] ) ) { + $current_tab = 'search'; + } + + $removed_args = array( + 'action', + 'customlink-tab', + 'edit-menu-item', + 'menu-item', + 'page-tab', + '_wpnonce', + ); + + ?> +
    +
      +
    • >
    • +
    • >
    • +
    • >
    • +
    + +
    +
      + 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) ); + $args['walker'] = $walker; + echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $popular_terms), 0, (object) $args ); + ?> +
    +
    + +
    + + + +
      + +
    + + + +
    + +
    + $searched, 'fields' => 'all', 'orderby' => 'count', 'order' => 'DESC', 'hierarchical' => false ) ); + } else { + $searched = ''; + $search_results = array(); + } + ?> +

    + + + +

    + +
      + + + +
    • get_error_message(); ?>
    • + +
    • + +
    +
    + +

    + + + + + + + class="button-secondary submit-add-to-menu" value="" name="add-taxonomy-menu-item" id="submit-taxonomy-" /> + +

    + +
    + $_item_object_data ) { + if ( + empty( $_item_object_data['menu-item-object-id'] ) && // checkbox is not checked + ( + ! isset( $_item_object_data['menu-item-type'] ) || // and item type either isn't set + in_array( $_item_object_data['menu-item-url'], array( 'http://', '' ) ) || // or URL is the default + ! ( 'custom' == $_item_object_data['menu-item-type'] && ! isset( $_item_object_data['menu-item-db-id'] ) ) || // or it's not a custom menu item (but not the custom home page) + ! empty( $_item_object_data['menu-item-db-id'] ) // or it *is* a custom menu item that already exists + ) + ) { + continue; // then this potential menu item is not getting added to this menu + } + + // if this possible menu item doesn't actually have a menu database ID yet + if ( + empty( $_item_object_data['menu-item-db-id'] ) || + ( 0 > $_possible_db_id ) || + $_possible_db_id != $_item_object_data['menu-item-db-id'] + ) { + $_actual_db_id = 0; + } else { + $_actual_db_id = (int) $_item_object_data['menu-item-db-id']; + } + + $args = array( + 'menu-item-db-id' => ( isset( $_item_object_data['menu-item-db-id'] ) ? $_item_object_data['menu-item-db-id'] : '' ), + 'menu-item-object-id' => ( isset( $_item_object_data['menu-item-object-id'] ) ? $_item_object_data['menu-item-object-id'] : '' ), + 'menu-item-object' => ( isset( $_item_object_data['menu-item-object'] ) ? $_item_object_data['menu-item-object'] : '' ), + 'menu-item-parent-id' => ( isset( $_item_object_data['menu-item-parent-id'] ) ? $_item_object_data['menu-item-parent-id'] : '' ), + 'menu-item-position' => ( isset( $_item_object_data['menu-item-position'] ) ? $_item_object_data['menu-item-position'] : '' ), + 'menu-item-type' => ( isset( $_item_object_data['menu-item-type'] ) ? $_item_object_data['menu-item-type'] : '' ), + 'menu-item-title' => ( isset( $_item_object_data['menu-item-title'] ) ? $_item_object_data['menu-item-title'] : '' ), + 'menu-item-url' => ( isset( $_item_object_data['menu-item-url'] ) ? $_item_object_data['menu-item-url'] : '' ), + 'menu-item-description' => ( isset( $_item_object_data['menu-item-description'] ) ? $_item_object_data['menu-item-description'] : '' ), + 'menu-item-attr-title' => ( isset( $_item_object_data['menu-item-attr-title'] ) ? $_item_object_data['menu-item-attr-title'] : '' ), + 'menu-item-target' => ( isset( $_item_object_data['menu-item-target'] ) ? $_item_object_data['menu-item-target'] : '' ), + 'menu-item-classes' => ( isset( $_item_object_data['menu-item-classes'] ) ? $_item_object_data['menu-item-classes'] : '' ), + 'menu-item-xfn' => ( isset( $_item_object_data['menu-item-xfn'] ) ? $_item_object_data['menu-item-xfn'] : '' ), + ); + + $items_saved[] = wp_update_nav_menu_item( $menu_id, $_actual_db_id, $args ); + + } + } + return $items_saved; +} + +/** + * Adds custom arguments to some of the meta box object types. + * + * @since 3.0.0 + * + * @access private + * + * @param object $object The post type or taxonomy meta-object. + * @return object The post type of taxonomy object. + */ +function _wp_nav_menu_meta_box_object( $object = null ) { + if ( isset( $object->name ) ) { + + if ( 'page' == $object->name ) { + $object->_default_query = array( + 'orderby' => 'menu_order title', + 'post_status' => 'publish', + ); + + // posts should show only published items + } elseif ( 'post' == $object->name ) { + $object->_default_query = array( + 'post_status' => 'publish', + ); + + // cats should be in reverse chronological order + } elseif ( 'category' == $object->name ) { + $object->_default_query = array( + 'orderby' => 'id', + 'order' => 'DESC', + ); + + // custom post types should show only published items + } else { + $object->_default_query = array( + 'post_status' => 'publish', + ); + } + } + + return $object; +} + +/** + * Returns the menu formatted to edit. + * + * @since 3.0.0 + * + * @param string $menu_id The ID of the menu to format. + * @return string|WP_Error $output The menu formatted to edit or error object on failure. + */ +function wp_get_nav_menu_to_edit( $menu_id = 0 ) { + $menu = wp_get_nav_menu_object( $menu_id ); + + // If the menu exists, get its items. + if ( is_nav_menu( $menu ) ) { + $menu_items = wp_get_nav_menu_items( $menu->term_id, array('post_status' => 'any') ); + $result = '
    ' : '">'; + $result .= '

    ' . __('Select menu items (pages, categories, links) from the boxes at left to begin building your custom menu.') . '

    '; + $result .= '
    '; + + if( empty($menu_items) ) + return $result . ' '; + + $walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $menu_id ); + + if ( class_exists( $walker_class_name ) ) + $walker = new $walker_class_name; + else + return new WP_Error( 'menu_walker_not_exist', sprintf( __('The Walker class named %s does not exist.'), $walker_class_name ) ); + + $some_pending_menu_items = false; + foreach( (array) $menu_items as $menu_item ) { + if ( isset( $menu_item->post_status ) && 'draft' == $menu_item->post_status ) + $some_pending_menu_items = true; + } + + if ( $some_pending_menu_items ) + $result .= '

    ' . __('Click Save Menu to make pending menu items public.') . '

    '; + + $result .= ' '; + return $result; + } elseif ( is_wp_error( $menu ) ) { + return $menu; + } + + +} + +/** + * Returns the columns for the nav menus page. + * + * @since 3.0.0 + * + * @return string|WP_Error $output The menu formatted to edit or error object on failure. + */ +function wp_nav_menu_manage_columns() { + return array( + '_title' => __('Show advanced menu properties'), + 'cb' => '', + 'link-target' => __('Link Target'), + 'css-classes' => __('CSS Classes'), + 'xfn' => __('Link Relationship (XFN)'), + 'description' => __('Description'), + ); +} + +/** + * Deletes orphaned draft menu items + * + * @access private + * @since 3.0.0 + * + */ +function _wp_delete_orphaned_draft_menu_items() { + global $wpdb; + $delete_timestamp = time() - (60*60*24*EMPTY_TRASH_DAYS); + + // delete orphaned draft menu items + $menu_items_to_delete = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS m ON p.ID = m.post_id WHERE post_type = 'nav_menu_item' AND post_status = 'draft' AND meta_key = '_menu_item_orphaned' AND meta_value < '%d'", $delete_timestamp ) ); + + foreach( (array) $menu_items_to_delete as $menu_item_id ) + wp_delete_post( $menu_item_id, true ); +} + +add_action('admin_head-nav-menus.php', '_wp_delete_orphaned_draft_menu_items'); + +?> diff --git a/src/wp-admin/includes/plugin-install.php b/src/wp-admin/includes/plugin-install.php new file mode 100644 index 00000000..beb54676 --- /dev/null +++ b/src/wp-admin/includes/plugin-install.php @@ -0,0 +1,370 @@ +per_page) ) + $args->per_page = 24; + + // Allows a plugin to override the WordPress.org API entirely. + // Use the filter 'plugins_api_result' to mearly add results. + // Please ensure that a object is returned from the following filters. + $args = apply_filters('plugins_api_args', $args, $action); + $res = apply_filters('plugins_api', false, $action, $args); + + if ( false === $res ) { + $request = wp_remote_post('http://api.wordpress.org/plugins/info/1.0/', array( 'timeout' => 15, 'body' => array('action' => $action, 'request' => serialize($args))) ); + if ( is_wp_error($request) ) { + $res = new WP_Error('plugins_api_failed', __('An Unexpected HTTP Error occurred during the API request.'), $request->get_error_message() ); + } else { + $res = unserialize($request['body']); + if ( false === $res ) + $res = new WP_Error('plugins_api_failed', __('An unknown error occurred.'), $request['body']); + } + } elseif ( !is_wp_error($res) ) { + $res->external = true; + } + + return apply_filters('plugins_api_result', $res, $action, $args); +} + +/** + * Retrieve popular WordPress plugin tags. + * + * @since 2.7.0 + * + * @param array $args + * @return array + */ +function install_popular_tags( $args = array() ) { + $key = md5(serialize($args)); + if ( false !== ($tags = get_site_transient('poptags_' . $key) ) ) + return $tags; + + $tags = plugins_api('hot_tags', $args); + + if ( is_wp_error($tags) ) + return $tags; + + set_site_transient('poptags_' . $key, $tags, 10800); // 3 * 60 * 60 = 10800 + + return $tags; +} + +function install_dashboard() { + ?> +

    WordPress Plugin Directory or upload a plugin in .zip format via this page.') ?>

    + +

    +

    + + +

    +

    + '; + if ( is_wp_error($api_tags) ) { + echo $api_tags->get_error_message(); + } else { + //Set up the tags in a way which can be interprated by wp_generate_tag_cloud() + $tags = array(); + foreach ( (array)$api_tags as $tag ) + $tags[ $tag['name'] ] = (object) array( + 'link' => esc_url( self_admin_url('plugin-install.php?tab=search&type=tag&s=' . urlencode($tag['name'])) ), + 'name' => $tag['name'], + 'id' => sanitize_title_with_dashes($tag['name']), + 'count' => $tag['count'] ); + echo wp_generate_tag_cloud($tags, array( 'single_text' => __('%d plugin'), 'multiple_text' => __('%d plugins') ) ); + } + echo '


    '; +} +add_action('install_plugins_dashboard', 'install_dashboard'); + +/** + * Display search form for searching plugins. + * + * @since 2.7.0 + */ +function install_search_form(){ + $type = isset($_REQUEST['type']) ? stripslashes( $_REQUEST['type'] ) : ''; + $term = isset($_REQUEST['s']) ? stripslashes( $_REQUEST['s'] ) : ''; + + ?>
    + + + + + +
    +

    +

    +
    + + + + +
    +display(); +} +add_action('install_plugins_search', 'display_plugins_table'); +add_action('install_plugins_featured', 'display_plugins_table'); +add_action('install_plugins_popular', 'display_plugins_table'); +add_action('install_plugins_new', 'display_plugins_table'); +add_action('install_plugins_updated', 'display_plugins_table'); + +/** + * Determine the status we can perform on a plugin. + * + * @since 3.0.0 + */ +function install_plugin_install_status($api, $loop = false) { + // this function is called recursivly, $loop prevents futhur loops. + if ( is_array($api) ) + $api = (object) $api; + + //Default to a "new" plugin + $status = 'install'; + $url = false; + + //Check to see if this plugin is known to be installed, and has an update awaiting it. + $update_plugins = get_site_transient('update_plugins'); + if ( is_object( $update_plugins ) ) { + foreach ( (array)$update_plugins->response as $file => $plugin ) { + if ( $plugin->slug === $api->slug ) { + $status = 'update_available'; + $update_file = $file; + $version = $plugin->new_version; + if ( current_user_can('update_plugins') ) + $url = wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=' . $update_file), 'upgrade-plugin_' . $update_file); + break; + } + } + } + + if ( 'install' == $status ) { + if ( is_dir( WP_PLUGIN_DIR . '/' . $api->slug ) ) { + $installed_plugin = get_plugins('/' . $api->slug); + if ( empty($installed_plugin) ) { + if ( current_user_can('install_plugins') ) + $url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $api->slug), 'install-plugin_' . $api->slug); + } else { + $key = array_shift( $key = array_keys($installed_plugin) ); //Use the first plugin regardless of the name, Could have issues for multiple-plugins in one directory if they share different version numbers + if ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '=') ){ + $status = 'latest_installed'; + } elseif ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '<') ) { + $status = 'newer_installed'; + $version = $installed_plugin[ $key ]['Version']; + } else { + //If the above update check failed, Then that probably means that the update checker has out-of-date information, force a refresh + if ( ! $loop ) { + delete_site_transient('update_plugins'); + wp_update_plugins(); + return install_plugin_install_status($api, true); + } + } + } + } else { + // "install" & no directory with that slug + if ( current_user_can('install_plugins') ) + $url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $api->slug), 'install-plugin_' . $api->slug); + } + } + if ( isset($_GET['from']) ) + $url .= '&from=' . urlencode(stripslashes($_GET['from'])); + + return compact('status', 'url', 'version'); +} + +/** + * Display plugin information in dialog box form. + * + * @since 2.7.0 + */ +function install_plugin_information() { + global $tab; + + $api = plugins_api('plugin_information', array('slug' => stripslashes( $_REQUEST['plugin'] ) )); + + if ( is_wp_error($api) ) + wp_die($api); + + $plugins_allowedtags = array('a' => array('href' => array(), 'title' => array(), 'target' => array()), + 'abbr' => array('title' => array()), 'acronym' => array('title' => array()), + 'code' => array(), 'pre' => array(), 'em' => array(), 'strong' => array(), + 'div' => array(), 'p' => array(), 'ul' => array(), 'ol' => array(), 'li' => array(), + 'h1' => array(), 'h2' => array(), 'h3' => array(), 'h4' => array(), 'h5' => array(), 'h6' => array(), + 'img' => array('src' => array(), 'class' => array(), 'alt' => array())); + //Sanitize HTML + foreach ( (array)$api->sections as $section_name => $content ) + $api->sections[$section_name] = wp_kses($content, $plugins_allowedtags); + foreach ( array('version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug') as $key ) + $api->$key = wp_kses($api->$key, $plugins_allowedtags); + + $section = isset($_REQUEST['section']) ? stripslashes( $_REQUEST['section'] ) : 'description'; //Default to the Description tab, Do not translate, API returns English. + if ( empty($section) || ! isset($api->sections[ $section ]) ) + $section = array_shift( $section_titles = array_keys((array)$api->sections) ); + + iframe_header( __('Plugin Install') ); + echo "
    \n"; + echo "
      \n"; + foreach ( (array)$api->sections as $section_name => $content ) { + + $title = $section_name; + $title = ucwords(str_replace('_', ' ', $title)); + + $class = ( $section_name == $section ) ? ' class="current"' : ''; + $href = add_query_arg( array('tab' => $tab, 'section' => $section_name) ); + $href = esc_url($href); + $san_title = esc_attr(sanitize_title_with_dashes($title)); + echo "\t
    • $title
    • \n"; + } + echo "
    \n"; + echo "
    \n"; + ?> +
    + download_link) && ( current_user_can('install_plugins') || current_user_can('update_plugins') ) ) : ?> +

    + ' . __('Install Now') . ''; + break; + case 'update_available': + if ( $status['url'] ) + echo '' . __('Install Update Now') .''; + break; + case 'newer_installed': + echo '' . sprintf(__('Newer Version (%s) Installed'), $status['version']) . ''; + break; + case 'latest_installed': + echo '' . __('Latest Version Installed') . ''; + break; + } + ?> +

    + +

    +
      +version) ) : ?> +
    • version ?>
    • +author) ) : ?> +
    • author, '_blank') ?>
    • +last_updated) ) : ?> +
    • last_updated)) ) ?>
    • +requires) ) : ?> +
    • requires) ?>
    • +tested) ) : ?> +
    • tested ?>
    • +downloaded) ) : ?> +
    • downloaded), number_format_i18n($api->downloaded)) ?>
    • +slug) && empty($api->external) ) : ?> +
    • +homepage) ) : ?> +
    • + +
    + rating) ) : ?> +

    +
    +
    +
    <?php _e('5 stars') ?>
    +
    <?php _e('4 stars') ?>
    +
    <?php _e('3 stars') ?>
    +
    <?php _e('2 stars') ?>
    +
    <?php _e('1 star') ?>
    +
    + num_ratings), number_format_i18n($api->num_ratings)); ?> + +
    +
    + tested) && version_compare( substr($GLOBALS['wp_version'], 0, strlen($api->tested)), $api->tested, '>') ) + echo '

    ' . __('Warning: This plugin has not been tested with your current version of WordPress.') . '

    '; + + else if ( !empty($api->requires) && version_compare( substr($GLOBALS['wp_version'], 0, strlen($api->requires)), $api->requires, '<') ) + echo '

    ' . __('Warning: This plugin has not been marked as compatible with your version of WordPress.') . '

    '; + + foreach ( (array)$api->sections as $section_name => $content ) { + $title = $section_name; + $title[0] = strtoupper($title[0]); + $title = str_replace('_', ' ', $title); + + $content = links_add_base_url($content, 'http://wordpress.org/extend/plugins/' . $api->slug . '/'); + $content = links_add_target($content, '_blank'); + + $san_title = esc_attr(sanitize_title_with_dashes($title)); + + $display = ( $section_name == $section ) ? 'block' : 'none'; + + echo "\t
    \n"; + echo "\t\t

    $title

    "; + echo $content; + echo "\t
    \n"; + } + echo "
    \n"; + + iframe_footer(); + exit; +} +add_action('install_plugins_pre_plugin-information', 'install_plugin_information'); + diff --git a/src/wp-admin/includes/plugin.php b/src/wp-admin/includes/plugin.php new file mode 100644 index 00000000..d10c450b --- /dev/null +++ b/src/wp-admin/includes/plugin.php @@ -0,0 +1,1729 @@ + + * /* + * Plugin Name: Name of Plugin + * Plugin URI: Link to plugin information + * Description: Plugin Description + * Author: Plugin author's name + * Author URI: Link to the author's web site + * Version: Must be set in the plugin for WordPress 2.3+ + * Text Domain: Optional. Unique identifier, should be same as the one used in + * plugin_text_domain() + * Domain Path: Optional. Only useful if the translations are located in a + * folder above the plugin's base path. For example, if .mo files are + * located in the locale folder then Domain Path will be "/locale/" and + * must have the first slash. Defaults to the base folder the plugin is + * located in. + * Network: Optional. Specify "Network: true" to require that a plugin is activated + * across all sites in an installation. This will prevent a plugin from being + * activated on a single site when Multisite is enabled. + * * / # Remove the space to close comment + * + * + * Plugin data returned array contains the following: + * 'Name' - Name of the plugin, must be unique. + * 'Title' - Title of the plugin and the link to the plugin's web site. + * 'Description' - Description of what the plugin does and/or notes + * from the author. + * 'Author' - The author's name + * 'AuthorURI' - The authors web site address. + * 'Version' - The plugin version number. + * 'PluginURI' - Plugin web site address. + * 'TextDomain' - Plugin's text domain for localization. + * 'DomainPath' - Plugin's relative directory path to .mo files. + * 'Network' - Boolean. Whether the plugin can only be activated network wide. + * + * Some users have issues with opening large files and manipulating the contents + * for want is usually the first 1kiB or 2kiB. This function stops pulling in + * the plugin contents when it has all of the required plugin data. + * + * The first 8kiB of the file will be pulled in and if the plugin data is not + * within that first 8kiB, then the plugin author should correct their plugin + * and move the plugin data headers to the top. + * + * The plugin file is assumed to have permissions to allow for scripts to read + * the file. This is not checked however and the file is only opened for + * reading. + * + * @link http://trac.wordpress.org/ticket/5651 Previous Optimizations. + * @link http://trac.wordpress.org/ticket/7372 Further and better Optimizations. + * @since 1.5.0 + * + * @param string $plugin_file Path to the plugin file + * @param bool $markup If the returned data should have HTML markup applied + * @param bool $translate If the returned data should be translated + * @return array See above for description. + */ +function get_plugin_data( $plugin_file, $markup = true, $translate = true ) { + + $default_headers = array( + 'Name' => 'Plugin Name', + 'PluginURI' => 'Plugin URI', + 'Version' => 'Version', + 'Description' => 'Description', + 'Author' => 'Author', + 'AuthorURI' => 'Author URI', + 'TextDomain' => 'Text Domain', + 'DomainPath' => 'Domain Path', + 'Network' => 'Network', + // Site Wide Only is deprecated in favor of Network. + '_sitewide' => 'Site Wide Only', + ); + + $plugin_data = get_file_data( $plugin_file, $default_headers, 'plugin' ); + + // Site Wide Only is the old header for Network + if ( empty( $plugin_data['Network'] ) && ! empty( $plugin_data['_sitewide'] ) ) { + _deprecated_argument( __FUNCTION__, '3.0', sprintf( __( 'The %1$s plugin header is deprecated. Use %2$s instead.' ), 'Site Wide Only: true', 'Network: true' ) ); + $plugin_data['Network'] = $plugin_data['_sitewide']; + } + $plugin_data['Network'] = ( 'true' == strtolower( $plugin_data['Network'] ) ); + unset( $plugin_data['_sitewide'] ); + + //For backward compatibility by default Title is the same as Name. + $plugin_data['Title'] = $plugin_data['Name']; + + if ( $markup || $translate ) + $plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate ); + else + $plugin_data['AuthorName'] = $plugin_data['Author']; + + return $plugin_data; +} + +function _get_plugin_data_markup_translate($plugin_file, $plugin_data, $markup = true, $translate = true) { + + //Translate fields + if ( $translate && ! empty($plugin_data['TextDomain']) ) { + if ( ! empty( $plugin_data['DomainPath'] ) ) + load_plugin_textdomain($plugin_data['TextDomain'], false, dirname($plugin_file). $plugin_data['DomainPath']); + else + load_plugin_textdomain($plugin_data['TextDomain'], false, dirname($plugin_file)); + + foreach ( array('Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version') as $field ) + $plugin_data[ $field ] = translate($plugin_data[ $field ], $plugin_data['TextDomain']); + } + + $plugins_allowedtags = array( + 'a' => array( 'href' => array(), 'title' => array() ), + 'abbr' => array( 'title' => array() ), + 'acronym' => array( 'title' => array() ), + 'code' => array(), + 'em' => array(), + 'strong' => array(), + ); + + $plugin_data['AuthorName'] = $plugin_data['Author'] = wp_kses( $plugin_data['Author'], $plugins_allowedtags ); + + //Apply Markup + if ( $markup ) { + if ( ! empty($plugin_data['PluginURI']) && ! empty($plugin_data['Name']) ) + $plugin_data['Title'] = '' . $plugin_data['Name'] . ''; + else + $plugin_data['Title'] = $plugin_data['Name']; + + if ( ! empty($plugin_data['AuthorURI']) && ! empty($plugin_data['Author']) ) + $plugin_data['Author'] = '' . $plugin_data['Author'] . ''; + + $plugin_data['Description'] = wptexturize( $plugin_data['Description'] ); + if ( ! empty($plugin_data['Author']) ) + $plugin_data['Description'] .= ' ' . sprintf( __('By %s'), $plugin_data['Author'] ) . '.'; + } + + // Sanitize all displayed data. Author and AuthorName sanitized above. + $plugin_data['Title'] = wp_kses( $plugin_data['Title'], $plugins_allowedtags ); + $plugin_data['Version'] = wp_kses( $plugin_data['Version'], $plugins_allowedtags ); + $plugin_data['Description'] = wp_kses( $plugin_data['Description'], $plugins_allowedtags ); + $plugin_data['Name'] = wp_kses( $plugin_data['Name'], $plugins_allowedtags ); + + return $plugin_data; +} + +/** + * Get a list of a plugin's files. + * + * @since 2.8.0 + * + * @param string $plugin Plugin ID + * @return array List of files relative to the plugin root. + */ +function get_plugin_files($plugin) { + $plugin_file = WP_PLUGIN_DIR . '/' . $plugin; + $dir = dirname($plugin_file); + $plugin_files = array($plugin); + if ( is_dir($dir) && $dir != WP_PLUGIN_DIR ) { + $plugins_dir = @ opendir( $dir ); + if ( $plugins_dir ) { + while (($file = readdir( $plugins_dir ) ) !== false ) { + if ( substr($file, 0, 1) == '.' ) + continue; + if ( is_dir( $dir . '/' . $file ) ) { + $plugins_subdir = @ opendir( $dir . '/' . $file ); + if ( $plugins_subdir ) { + while (($subfile = readdir( $plugins_subdir ) ) !== false ) { + if ( substr($subfile, 0, 1) == '.' ) + continue; + $plugin_files[] = plugin_basename("$dir/$file/$subfile"); + } + @closedir( $plugins_subdir ); + } + } else { + if ( plugin_basename("$dir/$file") != $plugin ) + $plugin_files[] = plugin_basename("$dir/$file"); + } + } + @closedir( $plugins_dir ); + } + } + + return $plugin_files; +} + +/** + * Check the plugins directory and retrieve all plugin files with plugin data. + * + * WordPress only supports plugin files in the base plugins directory + * (wp-content/plugins) and in one directory above the plugins directory + * (wp-content/plugins/my-plugin). The file it looks for has the plugin data and + * must be found in those two locations. It is recommended that do keep your + * plugin files in directories. + * + * The file with the plugin data is the file that will be included and therefore + * needs to have the main execution for the plugin. This does not mean + * everything must be contained in the file and it is recommended that the file + * be split for maintainability. Keep everything in one file for extreme + * optimization purposes. + * + * @since 1.5.0 + * + * @param string $plugin_folder Optional. Relative path to single plugin folder. + * @return array Key is the plugin file path and the value is an array of the plugin data. + */ +function get_plugins($plugin_folder = '') { + + if ( ! $cache_plugins = wp_cache_get('plugins', 'plugins') ) + $cache_plugins = array(); + + if ( isset($cache_plugins[ $plugin_folder ]) ) + return $cache_plugins[ $plugin_folder ]; + + $wp_plugins = array (); + $plugin_root = WP_PLUGIN_DIR; + if ( !empty($plugin_folder) ) + $plugin_root .= $plugin_folder; + + // Files in wp-content/plugins directory + $plugins_dir = @ opendir( $plugin_root); + $plugin_files = array(); + if ( $plugins_dir ) { + while (($file = readdir( $plugins_dir ) ) !== false ) { + if ( substr($file, 0, 1) == '.' ) + continue; + if ( is_dir( $plugin_root.'/'.$file ) ) { + $plugins_subdir = @ opendir( $plugin_root.'/'.$file ); + if ( $plugins_subdir ) { + while (($subfile = readdir( $plugins_subdir ) ) !== false ) { + if ( substr($subfile, 0, 1) == '.' ) + continue; + if ( substr($subfile, -4) == '.php' ) + $plugin_files[] = "$file/$subfile"; + } + } + } else { + if ( substr($file, -4) == '.php' ) + $plugin_files[] = $file; + } + } + } else { + return $wp_plugins; + } + + @closedir( $plugins_dir ); + @closedir( $plugins_subdir ); + + if ( empty($plugin_files) ) + return $wp_plugins; + + foreach ( $plugin_files as $plugin_file ) { + if ( !is_readable( "$plugin_root/$plugin_file" ) ) + continue; + + $plugin_data = get_plugin_data( "$plugin_root/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached. + + if ( empty ( $plugin_data['Name'] ) ) + continue; + + $wp_plugins[plugin_basename( $plugin_file )] = $plugin_data; + } + + uasort( $wp_plugins, '_sort_uname_callback' ); + + $cache_plugins[ $plugin_folder ] = $wp_plugins; + wp_cache_set('plugins', $cache_plugins, 'plugins'); + + return $wp_plugins; +} + +/** + * Check the mu-plugins directory and retrieve all mu-plugin files with any plugin data. + * + * WordPress only includes mu-plugin files in the base mu-plugins directory (wp-content/mu-plugins). + * + * @since 3.0.0 + * @return array Key is the mu-plugin file path and the value is an array of the mu-plugin data. + */ +function get_mu_plugins() { + $wp_plugins = array(); + // Files in wp-content/mu-plugins directory + $plugin_files = array(); + + if ( ! is_dir( WPMU_PLUGIN_DIR ) ) + return $wp_plugins; + if ( $plugins_dir = @ opendir( WPMU_PLUGIN_DIR ) ) { + while ( ( $file = readdir( $plugins_dir ) ) !== false ) { + if ( substr( $file, -4 ) == '.php' ) + $plugin_files[] = $file; + } + } else { + return $wp_plugins; + } + + @closedir( $plugins_dir ); + + if ( empty($plugin_files) ) + return $wp_plugins; + + foreach ( $plugin_files as $plugin_file ) { + if ( !is_readable( WPMU_PLUGIN_DIR . "/$plugin_file" ) ) + continue; + + $plugin_data = get_plugin_data( WPMU_PLUGIN_DIR . "/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached. + + if ( empty ( $plugin_data['Name'] ) ) + $plugin_data['Name'] = $plugin_file; + + $wp_plugins[ $plugin_file ] = $plugin_data; + } + + if ( isset( $wp_plugins['index.php'] ) && filesize( WPMU_PLUGIN_DIR . '/index.php') <= 30 ) // silence is golden + unset( $wp_plugins['index.php'] ); + + uasort( $wp_plugins, '_sort_uname_callback' ); + + return $wp_plugins; +} + +/** + * Callback to sort array by a 'Name' key. + * + * @since 3.1.0 + * @access private + */ +function _sort_uname_callback( $a, $b ) { + return strnatcasecmp( $a['Name'], $b['Name'] ); +} + +/** + * Check the wp-content directory and retrieve all drop-ins with any plugin data. + * + * @since 3.0.0 + * @return array Key is the file path and the value is an array of the plugin data. + */ +function get_dropins() { + $dropins = array(); + $plugin_files = array(); + + $_dropins = _get_dropins(); + + // These exist in the wp-content directory + if ( $plugins_dir = @ opendir( WP_CONTENT_DIR ) ) { + while ( ( $file = readdir( $plugins_dir ) ) !== false ) { + if ( isset( $_dropins[ $file ] ) ) + $plugin_files[] = $file; + } + } else { + return $dropins; + } + + @closedir( $plugins_dir ); + + if ( empty($plugin_files) ) + return $dropins; + + foreach ( $plugin_files as $plugin_file ) { + if ( !is_readable( WP_CONTENT_DIR . "/$plugin_file" ) ) + continue; + $plugin_data = get_plugin_data( WP_CONTENT_DIR . "/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached. + if ( empty( $plugin_data['Name'] ) ) + $plugin_data['Name'] = $plugin_file; + $dropins[ $plugin_file ] = $plugin_data; + } + + uksort( $dropins, 'strnatcasecmp' ); + + return $dropins; +} + +/** + * Returns drop-ins that WordPress uses. + * + * Includes Multisite drop-ins only when is_multisite() + * + * @since 3.0.0 + * @return array Key is file name. The value is an array, with the first value the + * purpose of the drop-in and the second value the name of the constant that must be + * true for the drop-in to be used, or true if no constant is required. + */ +function _get_dropins() { + $dropins = array( + 'advanced-cache.php' => array( __( 'Advanced caching plugin.' ), 'WP_CACHE' ), // WP_CACHE + 'db.php' => array( __( 'Custom database class.' ), true ), // auto on load + 'db-error.php' => array( __( 'Custom database error message.' ), true ), // auto on error + 'install.php' => array( __( 'Custom install script.' ), true ), // auto on install + 'maintenance.php' => array( __( 'Custom maintenance message.' ), true ), // auto on maintenance + 'object-cache.php' => array( __( 'External object cache.' ), true ), // auto on load + ); + + if ( is_multisite() ) { + $dropins['sunrise.php' ] = array( __( 'Executed before Multisite is loaded.' ), 'SUNRISE' ); // SUNRISE + $dropins['blog-deleted.php' ] = array( __( 'Custom site deleted message.' ), true ); // auto on deleted blog + $dropins['blog-inactive.php' ] = array( __( 'Custom site inactive message.' ), true ); // auto on inactive blog + $dropins['blog-suspended.php'] = array( __( 'Custom site suspended message.' ), true ); // auto on archived or spammed blog + } + + return $dropins; +} + +/** + * Check whether the plugin is active by checking the active_plugins list. + * + * @since 2.5.0 + * + * @param string $plugin Base plugin path from plugins directory. + * @return bool True, if in the active plugins list. False, not in the list. + */ +function is_plugin_active( $plugin ) { + return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin ); +} + +/** + * Check whether the plugin is inactive. + * + * Reverse of is_plugin_active(). Used as a callback. + * + * @since 3.1.0 + * @see is_plugin_active() + * + * @param string $plugin Base plugin path from plugins directory. + * @return bool True if inactive. False if active. + */ +function is_plugin_inactive( $plugin ) { + return ! is_plugin_active( $plugin ); +} + +/** + * Check whether the plugin is active for the entire network. + * + * @since 3.0.0 + * + * @param string $plugin Base plugin path from plugins directory. + * @return bool True, if active for the network, otherwise false. + */ +function is_plugin_active_for_network( $plugin ) { + if ( !is_multisite() ) + return false; + + $plugins = get_site_option( 'active_sitewide_plugins'); + if ( isset($plugins[$plugin]) ) + return true; + + return false; +} + +/** + * Checks for "Network: true" in the plugin header to see if this should + * be activated only as a network wide plugin. The plugin would also work + * when Multisite is not enabled. + * + * Checks for "Site Wide Only: true" for backwards compatibility. + * + * @since 3.0.0 + * + * @param string $plugin Plugin to check + * @return bool True if plugin is network only, false otherwise. + */ +function is_network_only_plugin( $plugin ) { + $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + if ( $plugin_data ) + return $plugin_data['Network']; + return false; +} + +/** + * Attempts activation of plugin in a "sandbox" and redirects on success. + * + * A plugin that is already activated will not attempt to be activated again. + * + * The way it works is by setting the redirection to the error before trying to + * include the plugin file. If the plugin fails, then the redirection will not + * be overwritten with the success message. Also, the options will not be + * updated and the activation hook will not be called on plugin error. + * + * It should be noted that in no way the below code will actually prevent errors + * within the file. The code should not be used elsewhere to replicate the + * "sandbox", which uses redirection to work. + * {@source 13 1} + * + * If any errors are found or text is outputted, then it will be captured to + * ensure that the success redirection will update the error redirection. + * + * @since 2.5.0 + * + * @param string $plugin Plugin path to main plugin file with plugin data. + * @param string $redirect Optional. URL to redirect to. + * @param bool $network_wide Whether to enable the plugin for all sites in the + * network or just the current site. Multisite only. Default is false. + * @param bool $silent Prevent calling activation hooks. Optional, default is false. + * @return WP_Error|null WP_Error on invalid file or null on success. + */ +function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) { + $plugin = plugin_basename( trim( $plugin ) ); + + if ( is_multisite() && ( $network_wide || is_network_only_plugin($plugin) ) ) { + $network_wide = true; + $current = get_site_option( 'active_sitewide_plugins', array() ); + } else { + $current = get_option( 'active_plugins', array() ); + } + + $valid = validate_plugin($plugin); + if ( is_wp_error($valid) ) + return $valid; + + if ( !in_array($plugin, $current) ) { + if ( !empty($redirect) ) + wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect)); // we'll override this later if the plugin can be included without fatal error + ob_start(); + include_once(WP_PLUGIN_DIR . '/' . $plugin); + + if ( ! $silent ) { + do_action( 'activate_plugin', $plugin, $network_wide ); + do_action( 'activate_' . $plugin, $network_wide ); + } + + if ( $network_wide ) { + $current[$plugin] = time(); + update_site_option( 'active_sitewide_plugins', $current ); + } else { + $current[] = $plugin; + sort($current); + update_option('active_plugins', $current); + } + + if ( ! $silent ) { + do_action( 'activated_plugin', $plugin, $network_wide ); + } + + if ( ob_get_length() > 0 ) { + $output = ob_get_clean(); + return new WP_Error('unexpected_output', __('The plugin generated unexpected output.'), $output); + } + ob_end_clean(); + } + + return null; +} + +/** + * Deactivate a single plugin or multiple plugins. + * + * The deactivation hook is disabled by the plugin upgrader by using the $silent + * parameter. + * + * @since 2.5.0 + * + * @param string|array $plugins Single plugin or list of plugins to deactivate. + * @param bool $silent Prevent calling deactivation hooks. Default is false. + */ +function deactivate_plugins( $plugins, $silent = false ) { + if ( is_multisite() ) + $network_current = get_site_option( 'active_sitewide_plugins', array() ); + $current = get_option( 'active_plugins', array() ); + $do_blog = $do_network = false; + + foreach ( (array) $plugins as $plugin ) { + $plugin = plugin_basename( trim( $plugin ) ); + if ( ! is_plugin_active($plugin) ) + continue; + + $network_wide = is_plugin_active_for_network( $plugin ); + + if ( ! $silent ) + do_action( 'deactivate_plugin', $plugin, $network_wide ); + + if ( $network_wide ) { + $do_network = true; + unset( $network_current[ $plugin ] ); + } else { + $key = array_search( $plugin, $current ); + if ( false !== $key ) { + $do_blog = true; + array_splice( $current, $key, 1 ); + } + } + + if ( ! $silent ) { + do_action( 'deactivate_' . $plugin, $network_wide ); + do_action( 'deactivated_plugin', $plugin, $network_wide ); + } + } + + if ( $do_blog ) + update_option('active_plugins', $current); + if ( $do_network ) + update_site_option( 'active_sitewide_plugins', $network_current ); +} + +/** + * Activate multiple plugins. + * + * When WP_Error is returned, it does not mean that one of the plugins had + * errors. It means that one or more of the plugins file path was invalid. + * + * The execution will be halted as soon as one of the plugins has an error. + * + * @since 2.6.0 + * + * @param string|array $plugins + * @param string $redirect Redirect to page after successful activation. + * @param bool $network_wide Whether to enable the plugin for all sites in the network. + * @param bool $silent Prevent calling activation hooks. Default is false. + * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation. + */ +function activate_plugins( $plugins, $redirect = '', $network_wide = false, $silent = false ) { + if ( !is_array($plugins) ) + $plugins = array($plugins); + + $errors = array(); + foreach ( $plugins as $plugin ) { + if ( !empty($redirect) ) + $redirect = add_query_arg('plugin', $plugin, $redirect); + $result = activate_plugin($plugin, $redirect, $network_wide, $silent); + if ( is_wp_error($result) ) + $errors[$plugin] = $result; + } + + if ( !empty($errors) ) + return new WP_Error('plugins_invalid', __('One of the plugins is invalid.'), $errors); + + return true; +} + +/** + * Remove directory and files of a plugin for a single or list of plugin(s). + * + * If the plugins parameter list is empty, false will be returned. True when + * completed. + * + * @since 2.6.0 + * + * @param array $plugins List of plugin + * @param string $redirect Redirect to page when complete. + * @return mixed + */ +function delete_plugins($plugins, $redirect = '' ) { + global $wp_filesystem; + + if ( empty($plugins) ) + return false; + + $checked = array(); + foreach( $plugins as $plugin ) + $checked[] = 'checked[]=' . $plugin; + + ob_start(); + $url = wp_nonce_url('plugins.php?action=delete-selected&verify-delete=1&' . implode('&', $checked), 'bulk-plugins'); + if ( false === ($credentials = request_filesystem_credentials($url)) ) { + $data = ob_get_contents(); + ob_end_clean(); + if ( ! empty($data) ){ + include_once( ABSPATH . 'wp-admin/admin-header.php'); + echo $data; + include( ABSPATH . 'wp-admin/admin-footer.php'); + exit; + } + return; + } + + if ( ! WP_Filesystem($credentials) ) { + request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again + $data = ob_get_contents(); + ob_end_clean(); + if ( ! empty($data) ){ + include_once( ABSPATH . 'wp-admin/admin-header.php'); + echo $data; + include( ABSPATH . 'wp-admin/admin-footer.php'); + exit; + } + return; + } + + if ( ! is_object($wp_filesystem) ) + return new WP_Error('fs_unavailable', __('Could not access filesystem.')); + + if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() ) + return new WP_Error('fs_error', __('Filesystem error.'), $wp_filesystem->errors); + + //Get the base plugin folder + $plugins_dir = $wp_filesystem->wp_plugins_dir(); + if ( empty($plugins_dir) ) + return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.')); + + $plugins_dir = trailingslashit( $plugins_dir ); + + $errors = array(); + + foreach( $plugins as $plugin_file ) { + // Run Uninstall hook + if ( is_uninstallable_plugin( $plugin_file ) ) + uninstall_plugin($plugin_file); + + $this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin_file) ); + // If plugin is in its own directory, recursively delete the directory. + if ( strpos($plugin_file, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder + $deleted = $wp_filesystem->delete($this_plugin_dir, true); + else + $deleted = $wp_filesystem->delete($plugins_dir . $plugin_file); + + if ( ! $deleted ) + $errors[] = $plugin_file; + } + + if ( ! empty($errors) ) + return new WP_Error('could_not_remove_plugin', sprintf(__('Could not fully remove the plugin(s) %s.'), implode(', ', $errors)) ); + + // Force refresh of plugin update information + if ( $current = get_site_transient('update_plugins') ) { + unset( $current->response[ $plugin_file ] ); + set_site_transient('update_plugins', $current); + } + + return true; +} + +/** + * Validate active plugins + * + * Validate all active plugins, deactivates invalid and + * returns an array of deactivated ones. + * + * @since 2.5.0 + * @return array invalid plugins, plugin as key, error as value + */ +function validate_active_plugins() { + $plugins = get_option( 'active_plugins', array() ); + // validate vartype: array + if ( ! is_array( $plugins ) ) { + update_option( 'active_plugins', array() ); + $plugins = array(); + } + + if ( is_multisite() && is_super_admin() ) { + $network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() ); + $plugins = array_merge( $plugins, array_keys( $network_plugins ) ); + } + + if ( empty( $plugins ) ) + return; + + $invalid = array(); + + // invalid plugins get deactivated + foreach ( $plugins as $plugin ) { + $result = validate_plugin( $plugin ); + if ( is_wp_error( $result ) ) { + $invalid[$plugin] = $result; + deactivate_plugins( $plugin, true ); + } + } + return $invalid; +} + +/** + * Validate the plugin path. + * + * Checks that the file exists and {@link validate_file() is valid file}. + * + * @since 2.5.0 + * + * @param string $plugin Plugin Path + * @return WP_Error|int 0 on success, WP_Error on failure. + */ +function validate_plugin($plugin) { + if ( validate_file($plugin) ) + return new WP_Error('plugin_invalid', __('Invalid plugin path.')); + if ( ! file_exists(WP_PLUGIN_DIR . '/' . $plugin) ) + return new WP_Error('plugin_not_found', __('Plugin file does not exist.')); + + $installed_plugins = get_plugins(); + if ( ! isset($installed_plugins[$plugin]) ) + return new WP_Error('no_plugin_header', __('The plugin does not have a valid header.')); + return 0; +} + +/** + * Whether the plugin can be uninstalled. + * + * @since 2.7.0 + * + * @param string $plugin Plugin path to check. + * @return bool Whether plugin can be uninstalled. + */ +function is_uninstallable_plugin($plugin) { + $file = plugin_basename($plugin); + + $uninstallable_plugins = (array) get_option('uninstall_plugins'); + if ( isset( $uninstallable_plugins[$file] ) || file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) ) + return true; + + return false; +} + +/** + * Uninstall a single plugin. + * + * Calls the uninstall hook, if it is available. + * + * @since 2.7.0 + * + * @param string $plugin Relative plugin path from Plugin Directory. + */ +function uninstall_plugin($plugin) { + $file = plugin_basename($plugin); + + $uninstallable_plugins = (array) get_option('uninstall_plugins'); + if ( file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) ) { + if ( isset( $uninstallable_plugins[$file] ) ) { + unset($uninstallable_plugins[$file]); + update_option('uninstall_plugins', $uninstallable_plugins); + } + unset($uninstallable_plugins); + + define('WP_UNINSTALL_PLUGIN', $file); + include WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php'; + + return true; + } + + if ( isset( $uninstallable_plugins[$file] ) ) { + $callable = $uninstallable_plugins[$file]; + unset($uninstallable_plugins[$file]); + update_option('uninstall_plugins', $uninstallable_plugins); + unset($uninstallable_plugins); + + include WP_PLUGIN_DIR . '/' . $file; + + add_action( 'uninstall_' . $file, $callable ); + do_action( 'uninstall_' . $file ); + } +} + +// +// Menu +// + +/** + * Add a top level menu page + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * @param string $icon_url The url to the icon to be used for this menu + * @param int $position The position in the menu order this one should appear + * + * @return string The resulting page's hook_suffix + */ +function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '', $position = NULL ) { + global $menu, $admin_page_hooks, $_registered_pages, $_parent_pages; + + $menu_slug = plugin_basename( $menu_slug ); + + $admin_page_hooks[$menu_slug] = sanitize_title( $menu_title ); + + $hookname = get_plugin_page_hookname( $menu_slug, '' ); + + if ( !empty( $function ) && !empty( $hookname ) && current_user_can( $capability ) ) + add_action( $hookname, $function ); + + if ( empty($icon_url) ) + $icon_url = esc_url( admin_url( 'images/generic.png' ) ); + elseif ( is_ssl() && 0 === strpos($icon_url, 'http://') ) + $icon_url = 'https://' . substr($icon_url, 7); + + $new_menu = array( $menu_title, $capability, $menu_slug, $page_title, 'menu-top ' . $hookname, $hookname, $icon_url ); + + if ( null === $position ) + $menu[] = $new_menu; + else + $menu[$position] = $new_menu; + + $_registered_pages[$hookname] = true; + + // No parent as top level + $_parent_pages[$menu_slug] = false; + + return $hookname; +} + +/** + * Add a top level menu page in the 'objects' section + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * @param string $icon_url The url to the icon to be used for this menu + * + * @return string The resulting page's hook_suffix + */ +function add_object_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '') { + global $_wp_last_object_menu; + + $_wp_last_object_menu++; + + return add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $_wp_last_object_menu); +} + +/** + * Add a top level menu page in the 'utility' section + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * @param string $icon_url The url to the icon to be used for this menu + * + * @return string The resulting page's hook_suffix + */ +function add_utility_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '') { + global $_wp_last_utility_menu; + + $_wp_last_utility_menu++; + + return add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $_wp_last_utility_menu); +} + +/** + * Add a sub menu page + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $parent_slug The slug name for the parent menu (or the file name of a standard WordPress admin page) + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + global $submenu; + global $menu; + global $_wp_real_parent_file; + global $_wp_submenu_nopriv; + global $_registered_pages; + global $_parent_pages; + + $menu_slug = plugin_basename( $menu_slug ); + $parent_slug = plugin_basename( $parent_slug); + + if ( isset( $_wp_real_parent_file[$parent_slug] ) ) + $parent_slug = $_wp_real_parent_file[$parent_slug]; + + if ( !current_user_can( $capability ) ) { + $_wp_submenu_nopriv[$parent_slug][$menu_slug] = true; + return false; + } + + // If the parent doesn't already have a submenu, add a link to the parent + // as the first item in the submenu. If the submenu file is the same as the + // parent file someone is trying to link back to the parent manually. In + // this case, don't automatically add a link back to avoid duplication. + if (!isset( $submenu[$parent_slug] ) && $menu_slug != $parent_slug ) { + foreach ( (array)$menu as $parent_menu ) { + if ( $parent_menu[2] == $parent_slug && current_user_can( $parent_menu[1] ) ) + $submenu[$parent_slug][] = $parent_menu; + } + } + + $submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title ); + + $hookname = get_plugin_page_hookname( $menu_slug, $parent_slug); + if (!empty ( $function ) && !empty ( $hookname )) + add_action( $hookname, $function ); + + $_registered_pages[$hookname] = true; + // backwards-compatibility for plugins using add_management page. See wp-admin/admin.php for redirect from edit.php to tools.php + if ( 'tools.php' == $parent_slug ) + $_registered_pages[get_plugin_page_hookname( $menu_slug, 'edit.php')] = true; + + // No parent as top level + $_parent_pages[$menu_slug] = $parent_slug; + + return $hookname; +} + +/** + * Add sub menu page to the tools main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the options main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the themes main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the plugins main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the Users/Profile main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + if ( current_user_can('edit_users') ) + $parent = 'users.php'; + else + $parent = 'profile.php'; + return add_submenu_page( $parent, $page_title, $menu_title, $capability, $menu_slug, $function ); +} +/** + * Add sub menu page to the Dashboard main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the posts main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the media main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the links main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix + */ +function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the pages main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix +*/ +function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + +/** + * Add sub menu page to the comments main menu. + * + * This function takes a capability which will be used to determine whether + * or not a page is included in the menu. + * + * The function which is hooked in to handle the output of the page must check + * that the user has the required capability as well. + * + * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected + * @param string $menu_title The text to be used for the menu + * @param string $capability The capability required for this menu to be displayed to the user. + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param callback $function The function to be called to output the content for this page. + * + * @return string The resulting page's hook_suffix +*/ +function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { + return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $function ); +} + + +/** + * Remove a top level admin menu + * + * @since 3.1.0 + * + * @param string $menu_slug The slug of the menu + * @return array|bool The removed menu on success, False if not found + */ +function remove_menu_page( $menu_slug ) { + global $menu; + + foreach ( $menu as $i => $item ) { + if ( $menu_slug == $item[2] ) { + unset( $menu[$i] ); + return $item; + } + } + + return false; +} + +/** + * Remove an admin submenu + * + * @since 3.1.0 + * + * @param string $menu_slug The slug for the parent menu + * @param string $submenu_slug The slug of the submenu + * @return array|bool The removed submenu on success, False if not found + */ +function remove_submenu_page( $menu_slug, $submenu_slug ) { + global $submenu; + + if ( !isset( $submenu[$menu_slug] ) ) + return false; + + foreach ( $submenu[$menu_slug] as $i => $item ) { + if ( $submenu_slug == $item[2] ) { + unset( $submenu[$menu_slug][$i] ); + return $item; + } + } + + return false; +} + +/** + * Get the url to access a particular menu page based on the slug it was registered with. + * + * If the slug hasn't been registered properly no url will be returned + * + * @since 3.0 + * + * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu) + * @param bool $echo Whether or not to echo the url - default is true + * @return string the url + */ +function menu_page_url($menu_slug, $echo = true) { + global $_parent_pages; + + if ( isset( $_parent_pages[$menu_slug] ) ) { + $parent_slug = $_parent_pages[$menu_slug]; + if ( $parent_slug && ! isset( $_parent_pages[$parent_slug] ) ) { + $url = admin_url( add_query_arg( 'page', $menu_slug, $parent_slug ) ); + } else { + $url = admin_url( 'admin.php?page=' . $menu_slug ); + } + } else { + $url = ''; + } + + $url = esc_url($url); + + if ( $echo ) + echo $url; + + return $url; +} + +// +// Pluggable Menu Support -- Private +// + +function get_admin_page_parent( $parent = '' ) { + global $parent_file; + global $menu; + global $submenu; + global $pagenow; + global $typenow; + global $plugin_page; + global $_wp_real_parent_file; + global $_wp_menu_nopriv; + global $_wp_submenu_nopriv; + + if ( !empty ( $parent ) && 'admin.php' != $parent ) { + if ( isset( $_wp_real_parent_file[$parent] ) ) + $parent = $_wp_real_parent_file[$parent]; + return $parent; + } + + /* + if ( !empty ( $parent_file ) ) { + if ( isset( $_wp_real_parent_file[$parent_file] ) ) + $parent_file = $_wp_real_parent_file[$parent_file]; + + return $parent_file; + } + */ + + if ( $pagenow == 'admin.php' && isset( $plugin_page ) ) { + foreach ( (array)$menu as $parent_menu ) { + if ( $parent_menu[2] == $plugin_page ) { + $parent_file = $plugin_page; + if ( isset( $_wp_real_parent_file[$parent_file] ) ) + $parent_file = $_wp_real_parent_file[$parent_file]; + return $parent_file; + } + } + if ( isset( $_wp_menu_nopriv[$plugin_page] ) ) { + $parent_file = $plugin_page; + if ( isset( $_wp_real_parent_file[$parent_file] ) ) + $parent_file = $_wp_real_parent_file[$parent_file]; + return $parent_file; + } + } + + if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) ) { + $parent_file = $pagenow; + if ( isset( $_wp_real_parent_file[$parent_file] ) ) + $parent_file = $_wp_real_parent_file[$parent_file]; + return $parent_file; + } + + foreach (array_keys( (array)$submenu ) as $parent) { + foreach ( $submenu[$parent] as $submenu_array ) { + if ( isset( $_wp_real_parent_file[$parent] ) ) + $parent = $_wp_real_parent_file[$parent]; + if ( !empty($typenow) && ($submenu_array[2] == "$pagenow?post_type=$typenow") ) { + $parent_file = $parent; + return $parent; + } elseif ( $submenu_array[2] == $pagenow && empty($typenow) && ( empty($parent_file) || false === strpos($parent_file, '?') ) ) { + $parent_file = $parent; + return $parent; + } else + if ( isset( $plugin_page ) && ($plugin_page == $submenu_array[2] ) ) { + $parent_file = $parent; + return $parent; + } + } + } + + if ( empty($parent_file) ) + $parent_file = ''; + return ''; +} + +function get_admin_page_title() { + global $title; + global $menu; + global $submenu; + global $pagenow; + global $plugin_page; + global $typenow; + + if ( ! empty ( $title ) ) + return $title; + + $hook = get_plugin_page_hook( $plugin_page, $pagenow ); + + $parent = $parent1 = get_admin_page_parent(); + + if ( empty ( $parent) ) { + foreach ( (array)$menu as $menu_array ) { + if ( isset( $menu_array[3] ) ) { + if ( $menu_array[2] == $pagenow ) { + $title = $menu_array[3]; + return $menu_array[3]; + } else + if ( isset( $plugin_page ) && ($plugin_page == $menu_array[2] ) && ($hook == $menu_array[3] ) ) { + $title = $menu_array[3]; + return $menu_array[3]; + } + } else { + $title = $menu_array[0]; + return $title; + } + } + } else { + foreach ( array_keys( $submenu ) as $parent ) { + foreach ( $submenu[$parent] as $submenu_array ) { + if ( isset( $plugin_page ) && + ( $plugin_page == $submenu_array[2] ) && + ( + ( $parent == $pagenow ) || + ( $parent == $plugin_page ) || + ( $plugin_page == $hook ) || + ( $pagenow == 'admin.php' && $parent1 != $submenu_array[2] ) || + ( !empty($typenow) && $parent == $pagenow . '?post_type=' . $typenow) + ) + ) { + $title = $submenu_array[3]; + return $submenu_array[3]; + } + + if ( $submenu_array[2] != $pagenow || isset( $_GET['page'] ) ) // not the current page + continue; + + if ( isset( $submenu_array[3] ) ) { + $title = $submenu_array[3]; + return $submenu_array[3]; + } else { + $title = $submenu_array[0]; + return $title; + } + } + } + if ( empty ( $title ) ) { + foreach ( $menu as $menu_array ) { + if ( isset( $plugin_page ) && + ( $plugin_page == $menu_array[2] ) && + ( $pagenow == 'admin.php' ) && + ( $parent1 == $menu_array[2] ) ) + { + $title = $menu_array[3]; + return $menu_array[3]; + } + } + } + } + + return $title; +} + +function get_plugin_page_hook( $plugin_page, $parent_page ) { + $hook = get_plugin_page_hookname( $plugin_page, $parent_page ); + if ( has_action($hook) ) + return $hook; + else + return null; +} + +function get_plugin_page_hookname( $plugin_page, $parent_page ) { + global $admin_page_hooks; + + $parent = get_admin_page_parent( $parent_page ); + + $page_type = 'admin'; + if ( empty ( $parent_page ) || 'admin.php' == $parent_page || isset( $admin_page_hooks[$plugin_page] ) ) { + if ( isset( $admin_page_hooks[$plugin_page] ) ) + $page_type = 'toplevel'; + else + if ( isset( $admin_page_hooks[$parent] )) + $page_type = $admin_page_hooks[$parent]; + } else if ( isset( $admin_page_hooks[$parent] ) ) { + $page_type = $admin_page_hooks[$parent]; + } + + $plugin_name = preg_replace( '!\.php!', '', $plugin_page ); + + return $page_type . '_page_' . $plugin_name; +} + +function user_can_access_admin_page() { + global $pagenow; + global $menu; + global $submenu; + global $_wp_menu_nopriv; + global $_wp_submenu_nopriv; + global $plugin_page; + global $_registered_pages; + + $parent = get_admin_page_parent(); + + if ( !isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$parent][$pagenow] ) ) + return false; + + if ( isset( $plugin_page ) ) { + if ( isset( $_wp_submenu_nopriv[$parent][$plugin_page] ) ) + return false; + + $hookname = get_plugin_page_hookname($plugin_page, $parent); + + if ( !isset($_registered_pages[$hookname]) ) + return false; + } + + if ( empty( $parent) ) { + if ( isset( $_wp_menu_nopriv[$pagenow] ) ) + return false; + if ( isset( $_wp_submenu_nopriv[$pagenow][$pagenow] ) ) + return false; + if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) ) + return false; + if ( isset( $plugin_page ) && isset( $_wp_menu_nopriv[$plugin_page] ) ) + return false; + foreach (array_keys( $_wp_submenu_nopriv ) as $key ) { + if ( isset( $_wp_submenu_nopriv[$key][$pagenow] ) ) + return false; + if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$key][$plugin_page] ) ) + return false; + } + return true; + } + + if ( isset( $plugin_page ) && ( $plugin_page == $parent ) && isset( $_wp_menu_nopriv[$plugin_page] ) ) + return false; + + if ( isset( $submenu[$parent] ) ) { + foreach ( $submenu[$parent] as $submenu_array ) { + if ( isset( $plugin_page ) && ( $submenu_array[2] == $plugin_page ) ) { + if ( current_user_can( $submenu_array[1] )) + return true; + else + return false; + } else if ( $submenu_array[2] == $pagenow ) { + if ( current_user_can( $submenu_array[1] )) + return true; + else + return false; + } + } + } + + foreach ( $menu as $menu_array ) { + if ( $menu_array[2] == $parent) { + if ( current_user_can( $menu_array[1] )) + return true; + else + return false; + } + } + + return true; +} + +/* Whitelist functions */ + +/** + * Register a setting and its sanitization callback + * + * @since 2.7.0 + * + * @param string $option_group A settings group name. Should correspond to a whitelisted option key name. + * Default whitelisted option key names include "general," "discussion," and "reading," among others. + * @param string $option_name The name of an option to sanitize and save. + * @param unknown_type $sanitize_callback A callback function that sanitizes the option's value. + * @return unknown + */ +function register_setting( $option_group, $option_name, $sanitize_callback = '' ) { + global $new_whitelist_options; + + if ( 'misc' == $option_group ) { + _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) ); + $option_group = 'general'; + } + + $new_whitelist_options[ $option_group ][] = $option_name; + if ( $sanitize_callback != '' ) + add_filter( "sanitize_option_{$option_name}", $sanitize_callback ); +} + +/** + * Unregister a setting + * + * @since 2.7.0 + * + * @param unknown_type $option_group + * @param unknown_type $option_name + * @param unknown_type $sanitize_callback + * @return unknown + */ +function unregister_setting( $option_group, $option_name, $sanitize_callback = '' ) { + global $new_whitelist_options; + + if ( 'misc' == $option_group ) { + _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) ); + $option_group = 'general'; + } + + $pos = array_search( $option_name, (array) $new_whitelist_options ); + if ( $pos !== false ) + unset( $new_whitelist_options[ $option_group ][ $pos ] ); + if ( $sanitize_callback != '' ) + remove_filter( "sanitize_option_{$option_name}", $sanitize_callback ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @param unknown_type $options + * @return unknown + */ +function option_update_filter( $options ) { + global $new_whitelist_options; + + if ( is_array( $new_whitelist_options ) ) + $options = add_option_whitelist( $new_whitelist_options, $options ); + + return $options; +} +add_filter( 'whitelist_options', 'option_update_filter' ); + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @param unknown_type $new_options + * @param unknown_type $options + * @return unknown + */ +function add_option_whitelist( $new_options, $options = '' ) { + if ( $options == '' ) + global $whitelist_options; + else + $whitelist_options = $options; + + foreach ( $new_options as $page => $keys ) { + foreach ( $keys as $key ) { + if ( !isset($whitelist_options[ $page ]) || !is_array($whitelist_options[ $page ]) ) { + $whitelist_options[ $page ] = array(); + $whitelist_options[ $page ][] = $key; + } else { + $pos = array_search( $key, $whitelist_options[ $page ] ); + if ( $pos === false ) + $whitelist_options[ $page ][] = $key; + } + } + } + + return $whitelist_options; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @param unknown_type $del_options + * @param unknown_type $options + * @return unknown + */ +function remove_option_whitelist( $del_options, $options = '' ) { + if ( $options == '' ) + global $whitelist_options; + else + $whitelist_options = $options; + + foreach ( $del_options as $page => $keys ) { + foreach ( $keys as $key ) { + if ( isset($whitelist_options[ $page ]) && is_array($whitelist_options[ $page ]) ) { + $pos = array_search( $key, $whitelist_options[ $page ] ); + if ( $pos !== false ) + unset( $whitelist_options[ $page ][ $pos ] ); + } + } + } + + return $whitelist_options; +} + +/** + * Output nonce, action, and option_page fields for a settings page. + * + * @since 2.7.0 + * + * @param string $option_group A settings group name. This should match the group name used in register_setting(). + */ +function settings_fields($option_group) { + echo ""; + echo ''; + wp_nonce_field("$option_group-options"); +} + +?> diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php new file mode 100644 index 00000000..bb6f469f --- /dev/null +++ b/src/wp-admin/includes/post.php @@ -0,0 +1,1711 @@ +cap->edit_others_posts ) ) { + if ( 'page' == $post_data['post_type'] ) { + return new WP_Error( 'edit_others_pages', $update ? + __( 'You are not allowed to edit pages as this user.' ) : + __( 'You are not allowed to create pages as this user.' ) + ); + } else { + return new WP_Error( 'edit_others_posts', $update ? + __( 'You are not allowed to edit posts as this user.' ) : + __( 'You are not allowed to post as this user.' ) + ); + } + } + } + + // What to do based on which button they pressed + if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] ) + $post_data['post_status'] = 'draft'; + if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] ) + $post_data['post_status'] = 'private'; + if ( isset($post_data['publish']) && ( '' != $post_data['publish'] ) && ( !isset($post_data['post_status']) || $post_data['post_status'] != 'private' ) ) + $post_data['post_status'] = 'publish'; + if ( isset($post_data['advanced']) && '' != $post_data['advanced'] ) + $post_data['post_status'] = 'draft'; + if ( isset($post_data['pending']) && '' != $post_data['pending'] ) + $post_data['post_status'] = 'pending'; + + if ( isset( $post_data['ID'] ) ) + $post_id = $post_data['ID']; + else + $post_id = false; + $previous_status = $post_id ? get_post_field( 'post_status', $post_id ) : false; + + // Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published. + // Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts. + if ( isset($post_data['post_status']) && ('publish' == $post_data['post_status'] && !current_user_can( $ptype->cap->publish_posts )) ) + if ( $previous_status != 'publish' || !current_user_can( 'edit_post', $post_id ) ) + $post_data['post_status'] = 'pending'; + + if ( ! isset($post_data['post_status']) ) + $post_data['post_status'] = $previous_status; + + if (!isset( $post_data['comment_status'] )) + $post_data['comment_status'] = 'closed'; + + if (!isset( $post_data['ping_status'] )) + $post_data['ping_status'] = 'closed'; + + foreach ( array('aa', 'mm', 'jj', 'hh', 'mn') as $timeunit ) { + if ( !empty( $post_data['hidden_' . $timeunit] ) && $post_data['hidden_' . $timeunit] != $post_data[$timeunit] ) { + $post_data['edit_date'] = '1'; + break; + } + } + + if ( !empty( $post_data['edit_date'] ) ) { + $aa = $post_data['aa']; + $mm = $post_data['mm']; + $jj = $post_data['jj']; + $hh = $post_data['hh']; + $mn = $post_data['mn']; + $ss = $post_data['ss']; + $aa = ($aa <= 0 ) ? date('Y') : $aa; + $mm = ($mm <= 0 ) ? date('n') : $mm; + $jj = ($jj > 31 ) ? 31 : $jj; + $jj = ($jj <= 0 ) ? date('j') : $jj; + $hh = ($hh > 23 ) ? $hh -24 : $hh; + $mn = ($mn > 59 ) ? $mn -60 : $mn; + $ss = ($ss > 59 ) ? $ss -60 : $ss; + $post_data['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss ); + $post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] ); + } + + return $post_data; +} + +/** + * Update an existing post with values provided in $_POST. + * + * @since 1.5.0 + * + * @param array $post_data Optional. + * @return int Post ID. + */ +function edit_post( $post_data = null ) { + + if ( empty($post_data) ) + $post_data = &$_POST; + + $post_ID = (int) $post_data['post_ID']; + $post = get_post( $post_ID ); + $post_data['post_type'] = $post->post_type; + $post_data['post_mime_type'] = $post->post_mime_type; + + $ptype = get_post_type_object($post_data['post_type']); + if ( !current_user_can( $ptype->cap->edit_post, $post_ID ) ) { + if ( 'page' == $post_data['post_type'] ) + wp_die( __('You are not allowed to edit this page.' )); + else + wp_die( __('You are not allowed to edit this post.' )); + } + + // Autosave shouldn't save too soon after a real save + if ( 'autosave' == $post_data['action'] ) { + $post =& get_post( $post_ID ); + $now = time(); + $then = strtotime($post->post_date_gmt . ' +0000'); + $delta = AUTOSAVE_INTERVAL / 2; + if ( ($now - $then) < $delta ) + return $post_ID; + } + + $post_data = _wp_translate_postdata( true, $post_data ); + if ( is_wp_error($post_data) ) + wp_die( $post_data->get_error_message() ); + if ( 'autosave' != $post_data['action'] && 'auto-draft' == $post_data['post_status'] ) + $post_data['post_status'] = 'draft'; + + if ( isset($post_data['visibility']) ) { + switch ( $post_data['visibility'] ) { + case 'public' : + $post_data['post_password'] = ''; + break; + case 'password' : + unset( $post_data['sticky'] ); + break; + case 'private' : + $post_data['post_status'] = 'private'; + $post_data['post_password'] = ''; + unset( $post_data['sticky'] ); + break; + } + } + + // Post Formats + if ( current_theme_supports( 'post-formats' ) && isset( $post_data['post_format'] ) ) { + $formats = get_theme_support( 'post-formats' ); + if ( is_array( $formats ) ) { + $formats = $formats[0]; + if ( in_array( $post_data['post_format'], $formats ) ) { + set_post_format( $post_ID, $post_data['post_format'] ); + } elseif ( '0' == $post_data['post_format'] ) { + set_post_format( $post_ID, false ); + } + } + } + + // Meta Stuff + if ( isset($post_data['meta']) && $post_data['meta'] ) { + foreach ( $post_data['meta'] as $key => $value ) { + if ( !$meta = get_post_meta_by_id( $key ) ) + continue; + if ( $meta->post_id != $post_ID ) + continue; + if ( is_protected_meta( $value['key'] ) ) + continue; + update_meta( $key, $value['key'], $value['value'] ); + } + } + + if ( isset($post_data['deletemeta']) && $post_data['deletemeta'] ) { + foreach ( $post_data['deletemeta'] as $key => $value ) { + if ( !$meta = get_post_meta_by_id( $key ) ) + continue; + if ( $meta->post_id != $post_ID ) + continue; + if ( is_protected_meta( $meta->meta_key ) ) + continue; + delete_meta( $key ); + } + } + + add_meta( $post_ID ); + + update_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID ); + + wp_update_post( $post_data ); + + // Reunite any orphaned attachments with their parent + if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) ) + $draft_ids = array(); + if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) ) + _relocate_children( $draft_temp_id, $post_ID ); + + // Now that we have an ID we can fix any attachment anchor hrefs + _fix_attachment_links( $post_ID ); + + wp_set_post_lock( $post_ID, $GLOBALS['current_user']->ID ); + + if ( current_user_can( $ptype->cap->edit_others_posts ) ) { + if ( ! empty( $post_data['sticky'] ) ) + stick_post( $post_ID ); + else + unstick_post( $post_ID ); + } + + return $post_ID; +} + +/** + * Process the post data for the bulk editing of posts. + * + * Updates all bulk edited posts/pages, adding (but not removing) tags and + * categories. Skips pages when they would be their own parent or child. + * + * @since 2.7.0 + * + * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal. + * @return array + */ +function bulk_edit_posts( $post_data = null ) { + global $wpdb; + + if ( empty($post_data) ) + $post_data = &$_POST; + + if ( isset($post_data['post_type']) ) + $ptype = get_post_type_object($post_data['post_type']); + else + $ptype = get_post_type_object('post'); + + if ( !current_user_can( $ptype->cap->edit_posts ) ) { + if ( 'page' == $ptype->name ) + wp_die( __('You are not allowed to edit pages.')); + else + wp_die( __('You are not allowed to edit posts.')); + } + + if ( -1 == $post_data['_status'] ) { + $post_data['post_status'] = null; + unset($post_data['post_status']); + } else { + $post_data['post_status'] = $post_data['_status']; + } + unset($post_data['_status']); + + $post_IDs = array_map( 'intval', (array) $post_data['post'] ); + + $reset = array( 'post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky' ); + foreach ( $reset as $field ) { + if ( isset($post_data[$field]) && ( '' == $post_data[$field] || -1 == $post_data[$field] ) ) + unset($post_data[$field]); + } + + if ( isset($post_data['post_category']) ) { + if ( is_array($post_data['post_category']) && ! empty($post_data['post_category']) ) + $new_cats = array_map( 'absint', $post_data['post_category'] ); + else + unset($post_data['post_category']); + } + + $tax_input = array(); + if ( isset($post_data['tax_input'])) { + foreach ( $post_data['tax_input'] as $tax_name => $terms ) { + if ( empty($terms) ) + continue; + if ( is_taxonomy_hierarchical( $tax_name ) ) + $tax_input[$tax_name] = array_map( 'absint', $terms ); + else { + $tax_input[$tax_name] = preg_replace( '/\s*,\s*/', ',', rtrim( trim($terms), ' ,' ) ); + $tax_input[$tax_name] = explode(',', $tax_input[$tax_name]); + } + } + } + + if ( isset($post_data['post_parent']) && ($parent = (int) $post_data['post_parent']) ) { + $pages = $wpdb->get_results("SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'"); + $children = array(); + + for ( $i = 0; $i < 50 && $parent > 0; $i++ ) { + $children[] = $parent; + + foreach ( $pages as $page ) { + if ( $page->ID == $parent ) { + $parent = $page->post_parent; + break; + } + } + } + } + + $updated = $skipped = $locked = array(); + foreach ( $post_IDs as $post_ID ) { + $post_type_object = get_post_type_object( get_post_type( $post_ID ) ); + + if ( !isset( $post_type_object ) || ( isset($children) && in_array($post_ID, $children) ) || !current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) { + $skipped[] = $post_ID; + continue; + } + + if ( wp_check_post_lock( $post_ID ) ) { + $locked[] = $post_ID; + continue; + } + + $tax_names = get_object_taxonomies( get_post($post_ID) ); + foreach ( $tax_names as $tax_name ) { + $taxonomy_obj = get_taxonomy($tax_name); + if ( isset( $tax_input[$tax_name]) && current_user_can( $taxonomy_obj->cap->assign_terms ) ) + $new_terms = $tax_input[$tax_name]; + else + $new_terms = array(); + + if ( $taxonomy_obj->hierarchical ) + $current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'ids') ); + else + $current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'names') ); + + $post_data['tax_input'][$tax_name] = array_merge( $current_terms, $new_terms ); + } + + if ( isset($new_cats) && in_array( 'category', $tax_names ) ) { + $cats = (array) wp_get_post_categories($post_ID); + $post_data['post_category'] = array_unique( array_merge($cats, $new_cats) ); + unset( $post_data['tax_input']['category'] ); + } + + $post_data['ID'] = $post_ID; + $updated[] = wp_update_post( $post_data ); + + if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) { + if ( 'sticky' == $post_data['sticky'] ) + stick_post( $post_ID ); + else + unstick_post( $post_ID ); + } + + } + + return array( 'updated' => $updated, 'skipped' => $skipped, 'locked' => $locked ); +} + +/** + * Default post information to use when populating the "Write Post" form. + * + * @since 2.0.0 + * + * @param string $post_type A post type string, defaults to 'post'. + * @return object stdClass object containing all the default post data as attributes + */ +function get_default_post_to_edit( $post_type = 'post', $create_in_db = false ) { + global $wpdb; + + $post_title = ''; + if ( !empty( $_REQUEST['post_title'] ) ) + $post_title = esc_html( stripslashes( $_REQUEST['post_title'] )); + + $post_content = ''; + if ( !empty( $_REQUEST['content'] ) ) + $post_content = esc_html( stripslashes( $_REQUEST['content'] )); + + $post_excerpt = ''; + if ( !empty( $_REQUEST['excerpt'] ) ) + $post_excerpt = esc_html( stripslashes( $_REQUEST['excerpt'] )); + + if ( $create_in_db ) { + // Cleanup old auto-drafts more than 7 days old + $old_posts = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_status = 'auto-draft' AND DATE_SUB( NOW(), INTERVAL 7 DAY ) > post_date" ); + foreach ( (array) $old_posts as $delete ) + wp_delete_post( $delete, true ); // Force delete + $post_id = wp_insert_post( array( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type, 'post_status' => 'auto-draft' ) ); + $post = get_post( $post_id ); + if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) ) + set_post_format( $post, get_option( 'default_post_format' ) ); + } else { + $post->ID = 0; + $post->post_author = ''; + $post->post_date = ''; + $post->post_date_gmt = ''; + $post->post_password = ''; + $post->post_type = $post_type; + $post->post_status = 'draft'; + $post->to_ping = ''; + $post->pinged = ''; + $post->comment_status = get_option( 'default_comment_status' ); + $post->ping_status = get_option( 'default_ping_status' ); + $post->post_pingback = get_option( 'default_pingback_flag' ); + $post->post_category = get_option( 'default_category' ); + $post->page_template = 'default'; + $post->post_parent = 0; + $post->menu_order = 0; + } + + $post->post_content = apply_filters( 'default_content', $post_content, $post ); + $post->post_title = apply_filters( 'default_title', $post_title, $post ); + $post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt, $post ); + $post->post_name = ''; + + return $post; +} + +/** + * Get the default page information to use. + * + * @since 2.5.0 + * + * @return object stdClass object containing all the default post data as attributes + */ +function get_default_page_to_edit() { + $page = get_default_post_to_edit(); + $page->post_type = 'page'; + return $page; +} + +/** + * Get an existing post and format it for editing. + * + * @since 2.0.0 + * + * @param unknown_type $id + * @return unknown + */ +function get_post_to_edit( $id ) { + + $post = get_post( $id, OBJECT, 'edit' ); + + if ( $post->post_type == 'page' ) + $post->page_template = get_post_meta( $id, '_wp_page_template', true ); + + return $post; +} + +/** + * Determine if a post exists based on title, content, and date + * + * @since 2.0.0 + * + * @param string $title Post title + * @param string $content Optional post content + * @param string $date Optional post date + * @return int Post ID if post exists, 0 otherwise. + */ +function post_exists($title, $content = '', $date = '') { + global $wpdb; + + $post_title = stripslashes( sanitize_post_field( 'post_title', $title, 0, 'db' ) ); + $post_content = stripslashes( sanitize_post_field( 'post_content', $content, 0, 'db' ) ); + $post_date = stripslashes( sanitize_post_field( 'post_date', $date, 0, 'db' ) ); + + $query = "SELECT ID FROM $wpdb->posts WHERE 1=1"; + $args = array(); + + if ( !empty ( $date ) ) { + $query .= ' AND post_date = %s'; + $args[] = $post_date; + } + + if ( !empty ( $title ) ) { + $query .= ' AND post_title = %s'; + $args[] = $post_title; + } + + if ( !empty ( $content ) ) { + $query .= 'AND post_content = %s'; + $args[] = $post_content; + } + + if ( !empty ( $args ) ) + return $wpdb->get_var( $wpdb->prepare($query, $args) ); + + return 0; +} + +/** + * Creates a new post from the "Write Post" form using $_POST information. + * + * @since 2.1.0 + * + * @return unknown + */ +function wp_write_post() { + global $user_ID; + + + if ( isset($_POST['post_type']) ) + $ptype = get_post_type_object($_POST['post_type']); + else + $ptype = get_post_type_object('post'); + + if ( !current_user_can( $ptype->cap->edit_posts ) ) { + if ( 'page' == $ptype->name ) + return new WP_Error( 'edit_pages', __( 'You are not allowed to create pages on this site.' ) ); + else + return new WP_Error( 'edit_posts', __( 'You are not allowed to create posts or drafts on this site.' ) ); + } + + $_POST['post_mime_type'] = ''; + + // Check for autosave collisions + // Does this need to be updated? ~ Mark + $temp_id = false; + if ( isset($_POST['temp_ID']) ) { + $temp_id = (int) $_POST['temp_ID']; + if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) ) + $draft_ids = array(); + foreach ( $draft_ids as $temp => $real ) + if ( time() + $temp > 86400 ) // 1 day: $temp is equal to -1 * time( then ) + unset($draft_ids[$temp]); + + if ( isset($draft_ids[$temp_id]) ) { // Edit, don't write + $_POST['post_ID'] = $draft_ids[$temp_id]; + unset($_POST['temp_ID']); + update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids ); + return edit_post(); + } + } + + $translated = _wp_translate_postdata( false ); + if ( is_wp_error($translated) ) + return $translated; + + if ( isset($_POST['visibility']) ) { + switch ( $_POST['visibility'] ) { + case 'public' : + $_POST['post_password'] = ''; + break; + case 'password' : + unset( $_POST['sticky'] ); + break; + case 'private' : + $_POST['post_status'] = 'private'; + $_POST['post_password'] = ''; + unset( $_POST['sticky'] ); + break; + } + } + + // Create the post. + $post_ID = wp_insert_post( $_POST ); + if ( is_wp_error( $post_ID ) ) + return $post_ID; + + if ( empty($post_ID) ) + return 0; + + add_meta( $post_ID ); + + add_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID ); + + // Reunite any orphaned attachments with their parent + // Does this need to be udpated? ~ Mark + if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) ) + $draft_ids = array(); + if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) ) + _relocate_children( $draft_temp_id, $post_ID ); + if ( $temp_id && $temp_id != $draft_temp_id ) + _relocate_children( $temp_id, $post_ID ); + + // Update autosave collision detection + if ( $temp_id ) { + $draft_ids[$temp_id] = $post_ID; + update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids ); + } + + // Now that we have an ID we can fix any attachment anchor hrefs + _fix_attachment_links( $post_ID ); + + wp_set_post_lock( $post_ID, $GLOBALS['current_user']->ID ); + + return $post_ID; +} + +/** + * Calls wp_write_post() and handles the errors. + * + * @since 2.0.0 + * + * @return unknown + */ +function write_post() { + $result = wp_write_post(); + if ( is_wp_error( $result ) ) + wp_die( $result->get_error_message() ); + else + return $result; +} + +// +// Post Meta +// + +/** + * {@internal Missing Short Description}} + * + * @since 1.2.0 + * + * @param unknown_type $post_ID + * @return unknown + */ +function add_meta( $post_ID ) { + global $wpdb; + $post_ID = (int) $post_ID; + + $metakeyselect = isset($_POST['metakeyselect']) ? stripslashes( trim( $_POST['metakeyselect'] ) ) : ''; + $metakeyinput = isset($_POST['metakeyinput']) ? stripslashes( trim( $_POST['metakeyinput'] ) ) : ''; + $metavalue = isset($_POST['metavalue']) ? maybe_serialize( stripslashes_deep( $_POST['metavalue'] ) ) : ''; + if ( is_string($metavalue) ) + $metavalue = trim( $metavalue ); + + if ( ('0' === $metavalue || !empty ( $metavalue ) ) && ((('#NONE#' != $metakeyselect) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput) ) ) { + // We have a key/value pair. If both the select and the + // input for the key have data, the input takes precedence: + + if ('#NONE#' != $metakeyselect) + $metakey = $metakeyselect; + + if ( $metakeyinput) + $metakey = $metakeyinput; // default + + if ( is_protected_meta( $metakey ) ) + return false; + + wp_cache_delete($post_ID, 'post_meta'); + $wpdb->insert( $wpdb->postmeta, array( 'post_id' => $post_ID, 'meta_key' => $metakey, 'meta_value' => $metavalue ) ); + $meta_id = $wpdb->insert_id; + do_action( 'added_postmeta', $meta_id, $post_ID, $metakey, $metavalue ); + + return $meta_id; + } + return false; +} // add_meta + +/** + * {@internal Missing Short Description}} + * + * @since 1.2.0 + * + * @param unknown_type $mid + * @return unknown + */ +function delete_meta( $mid ) { + global $wpdb; + $mid = (int) $mid; + + $post_id = $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_id = %d", $mid) ); + + do_action( 'delete_postmeta', $mid ); + wp_cache_delete($post_id, 'post_meta'); + $rval = $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_id = %d", $mid) ); + do_action( 'deleted_postmeta', $mid ); + + return $rval; +} + +/** + * Get a list of previously defined keys. + * + * @since 1.2.0 + * + * @return unknown + */ +function get_meta_keys() { + global $wpdb; + + $keys = $wpdb->get_col( " + SELECT meta_key + FROM $wpdb->postmeta + GROUP BY meta_key + ORDER BY meta_key" ); + + return $keys; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.1.0 + * + * @param unknown_type $mid + * @return unknown + */ +function get_post_meta_by_id( $mid ) { + global $wpdb; + $mid = (int) $mid; + + $meta = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->postmeta WHERE meta_id = %d", $mid) ); + if ( empty($meta) ) + return false; + if ( is_serialized_string( $meta->meta_value ) ) + $meta->meta_value = maybe_unserialize( $meta->meta_value ); + return $meta; +} + +/** + * {@internal Missing Short Description}} + * + * Some postmeta stuff. + * + * @since 1.2.0 + * + * @param unknown_type $postid + * @return unknown + */ +function has_meta( $postid ) { + global $wpdb; + + return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, post_id + FROM $wpdb->postmeta WHERE post_id = %d + ORDER BY meta_key,meta_id", $postid), ARRAY_A ); + +} + +/** + * {@internal Missing Short Description}} + * + * @since 1.2.0 + * + * @param unknown_type $meta_id + * @param unknown_type $meta_key Expect Slashed + * @param unknown_type $meta_value Expect Slashed + * @return unknown + */ +function update_meta( $meta_id, $meta_key, $meta_value ) { + global $wpdb; + + $meta_key = stripslashes($meta_key); + + if ( is_protected_meta( $meta_key ) ) + return false; + + if ( '' === trim( $meta_value ) ) + return false; + + $post_id = $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_id = %d", $meta_id) ); + + $meta_value = maybe_serialize( stripslashes_deep( $meta_value ) ); + $meta_id = (int) $meta_id; + + $data = compact( 'meta_key', 'meta_value' ); + $where = compact( 'meta_id' ); + + do_action( 'update_postmeta', $meta_id, $post_id, $meta_key, $meta_value ); + $rval = $wpdb->update( $wpdb->postmeta, $data, $where ); + wp_cache_delete($post_id, 'post_meta'); + do_action( 'updated_postmeta', $meta_id, $post_id, $meta_key, $meta_value ); + + return $rval; +} + +// +// Private +// + +/** + * Replace hrefs of attachment anchors with up-to-date permalinks. + * + * @since 2.3.0 + * @access private + * + * @param unknown_type $post_ID + * @return unknown + */ +function _fix_attachment_links( $post_ID ) { + global $_fix_attachment_link_id; + + $post = & get_post( $post_ID, ARRAY_A ); + + $search = "#]+rel=('|\")[^'\"]*attachment[^>]*>#ie"; + + // See if we have any rel="attachment" links + if ( 0 == preg_match_all( $search, $post['post_content'], $anchor_matches, PREG_PATTERN_ORDER ) ) + return; + + $i = 0; + $search = "#[\s]+rel=(\"|')(.*?)wp-att-(\d+)\\1#i"; + foreach ( $anchor_matches[0] as $anchor ) { + if ( 0 == preg_match( $search, $anchor, $id_matches ) ) + continue; + + $id = (int) $id_matches[3]; + + // While we have the attachment ID, let's adopt any orphans. + $attachment = & get_post( $id, ARRAY_A ); + if ( ! empty( $attachment) && ! is_object( get_post( $attachment['post_parent'] ) ) ) { + $attachment['post_parent'] = $post_ID; + // Escape data pulled from DB. + $attachment = add_magic_quotes( $attachment ); + wp_update_post( $attachment ); + } + + $post_search[$i] = $anchor; + $_fix_attachment_link_id = $id; + $post_replace[$i] = preg_replace_callback( "#href=(\"|')[^'\"]*\\1#", '_fix_attachment_links_replace_cb', $anchor ); + ++$i; + } + + $post['post_content'] = str_replace( $post_search, $post_replace, $post['post_content'] ); + + // Escape data pulled from DB. + $post = add_magic_quotes( $post); + + return wp_update_post( $post); +} + +function _fix_attachment_links_replace_cb($match) { + global $_fix_attachment_link_id; + return stripslashes( 'href='.$match[1] ).get_attachment_link( $_fix_attachment_link_id ).stripslashes( $match[1] ); +} + +/** + * Move child posts to a new parent. + * + * @since 2.3.0 + * @access private + * + * @param unknown_type $old_ID + * @param unknown_type $new_ID + * @return unknown + */ +function _relocate_children( $old_ID, $new_ID ) { + global $wpdb; + $old_ID = (int) $old_ID; + $new_ID = (int) $new_ID; + + $children = $wpdb->get_col( $wpdb->prepare(" + SELECT post_id + FROM $wpdb->postmeta + WHERE meta_key = '_wp_attachment_temp_parent' + AND meta_value = %d", $old_ID) ); + + foreach ( $children as $child_id ) { + $wpdb->update($wpdb->posts, array('post_parent' => $new_ID), array('ID' => $child_id) ); + delete_post_meta($child_id, '_wp_attachment_temp_parent'); + } +} + +/** + * Get all the possible statuses for a post_type + * + * @since 2.5.0 + * + * @param string $type The post_type you want the statuses for + * @return array As array of all the statuses for the supplied post type + */ +function get_available_post_statuses($type = 'post') { + $stati = wp_count_posts($type); + + return array_keys(get_object_vars($stati)); +} + +/** + * Run the wp query to fetch the posts for listing on the edit posts page + * + * @since 2.5.0 + * + * @param array|bool $q Array of query variables to use to build the query or false to use $_GET superglobal. + * @return array + */ +function wp_edit_posts_query( $q = false ) { + if ( false === $q ) + $q = $_GET; + $q['m'] = isset($q['m']) ? (int) $q['m'] : 0; + $q['cat'] = isset($q['cat']) ? (int) $q['cat'] : 0; + $post_stati = get_post_stati(); + + if ( isset($q['post_type']) && in_array( $q['post_type'], get_post_types() ) ) + $post_type = $q['post_type']; + else + $post_type = 'post'; + + $avail_post_stati = get_available_post_statuses($post_type); + + if ( isset($q['post_status']) && in_array( $q['post_status'], $post_stati ) ) { + $post_status = $q['post_status']; + $perm = 'readable'; + } + + if ( isset($q['orderby']) ) + $orderby = $q['orderby']; + elseif ( isset($q['post_status']) && in_array($q['post_status'], array('pending', 'draft')) ) + $orderby = 'modified'; + + if ( isset($q['order']) ) + $order = $q['order']; + elseif ( isset($q['post_status']) && 'pending' == $q['post_status'] ) + $order = 'ASC'; + + $per_page = 'edit_' . $post_type . '_per_page'; + $posts_per_page = (int) get_user_option( $per_page ); + if ( empty( $posts_per_page ) || $posts_per_page < 1 ) + $posts_per_page = 20; + + $posts_per_page = apply_filters( $per_page, $posts_per_page ); + $posts_per_page = apply_filters( 'edit_posts_per_page', $posts_per_page, $post_type ); + + $query = compact('post_type', 'post_status', 'perm', 'order', 'orderby', 'posts_per_page'); + + // Hierarchical types require special args. + if ( is_post_type_hierarchical( $post_type ) && !isset($orderby) ) { + $query['orderby'] = 'menu_order title'; + $query['order'] = 'asc'; + $query['posts_per_page'] = -1; + $query['posts_per_archive_page'] = -1; + } + + if ( ! empty( $q['show_sticky'] ) ) + $query['post__in'] = (array) get_option( 'sticky_posts' ); + + wp( $query ); + + return $avail_post_stati; +} + +/** + * Get default post mime types + * + * @since 2.9.0 + * + * @return array + */ +function get_post_mime_types() { + $post_mime_types = array( // array( adj, noun ) + 'image' => array(__('Images'), __('Manage Images'), _n_noop('Image (%s)', 'Images (%s)')), + 'audio' => array(__('Audio'), __('Manage Audio'), _n_noop('Audio (%s)', 'Audio (%s)')), + 'video' => array(__('Video'), __('Manage Video'), _n_noop('Video (%s)', 'Video (%s)')), + ); + + return apply_filters('post_mime_types', $post_mime_types); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $type + * @return unknown + */ +function get_available_post_mime_types($type = 'attachment') { + global $wpdb; + + $types = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type)); + return $types; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $q + * @return unknown + */ +function wp_edit_attachments_query( $q = false ) { + if ( false === $q ) + $q = $_GET; + + $q['m'] = isset( $q['m'] ) ? (int) $q['m'] : 0; + $q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0; + $q['post_type'] = 'attachment'; + $post_type = get_post_type_object( 'attachment' ); + $states = array( 'inherit' ); + if ( current_user_can( $post_type->cap->read_private_posts ) ) + $states[] = 'private'; + + $q['post_status'] = isset( $q['status'] ) && 'trash' == $q['status'] ? 'trash' : $states; + $media_per_page = (int) get_user_option( 'upload_per_page' ); + if ( empty( $media_per_page ) || $media_per_page < 1 ) + $media_per_page = 20; + $q['posts_per_page'] = apply_filters( 'upload_per_page', $media_per_page ); + + $post_mime_types = get_post_mime_types(); + $avail_post_mime_types = get_available_post_mime_types('attachment'); + + if ( isset($q['post_mime_type']) && !array_intersect( (array) $q['post_mime_type'], array_keys($post_mime_types) ) ) + unset($q['post_mime_type']); + + if ( isset($q['detached']) ) + add_filter('posts_where', '_edit_attachments_query_helper'); + + wp( $q ); + + if ( isset($q['detached']) ) + remove_filter('posts_where', '_edit_attachments_query_helper'); + + return array($post_mime_types, $avail_post_mime_types); +} + +function _edit_attachments_query_helper($where) { + return $where .= ' AND post_parent < 1'; +} + +/** + * {@internal Missing Short Description}} + * + * @uses get_user_option() + * @since 2.5.0 + * + * @param unknown_type $id + * @param unknown_type $page + * @return unknown + */ +function postbox_classes( $id, $page ) { + if ( isset( $_GET['edit'] ) && $_GET['edit'] == $id ) + return ''; + + if ( $closed = get_user_option('closedpostboxes_'.$page ) ) { + if ( !is_array( $closed ) ) { + return ''; + } + return in_array( $id, $closed )? 'closed' : ''; + } else { + return ''; + } +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param int|object $id Post ID or post object. + * @param string $title (optional) Title + * @param string $name (optional) Name + * @return array With two entries of type string + */ +function get_sample_permalink($id, $title = null, $name = null) { + $post = &get_post($id); + if ( !$post->ID ) + return array('', ''); + + $ptype = get_post_type_object($post->post_type); + + $original_status = $post->post_status; + $original_date = $post->post_date; + $original_name = $post->post_name; + + // Hack: get_permalink would return ugly permalink for + // drafts, so we will fake, that our post is published + if ( in_array($post->post_status, array('draft', 'pending')) ) { + $post->post_status = 'publish'; + $post->post_name = sanitize_title($post->post_name ? $post->post_name : $post->post_title, $post->ID); + } + + // If the user wants to set a new name -- override the current one + // Note: if empty name is supplied -- use the title instead, see #6072 + if ( !is_null($name) ) + $post->post_name = sanitize_title($name ? $name : $title, $post->ID); + + $post->post_name = wp_unique_post_slug($post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent); + + $post->filter = 'sample'; + + $permalink = get_permalink($post, true); + + // Replace custom post_type Token with generic pagename token for ease of use. + $permalink = str_replace("%$post->post_type%", '%pagename%', $permalink); + + // Handle page hierarchy + if ( $ptype->hierarchical ) { + $uri = get_page_uri($post); + $uri = untrailingslashit($uri); + $uri = strrev( stristr( strrev( $uri ), '/' ) ); + $uri = untrailingslashit($uri); + if ( !empty($uri) ) + $uri .= '/'; + $permalink = str_replace('%pagename%', "{$uri}%pagename%", $permalink); + } + + $permalink = array($permalink, apply_filters('editable_slug', $post->post_name)); + $post->post_status = $original_status; + $post->post_date = $original_date; + $post->post_name = $original_name; + unset($post->filter); + + return $permalink; +} + +/** + * sample permalink html + * + * intended to be used for the inplace editor of the permalink post slug on in the post (and page?) editor. + * + * @since 2.5.0 + * + * @param int|object $id Post ID or post object. + * @param string $new_title (optional) New title + * @param string $new_slug (optional) New slug + * @return string intended to be used for the inplace editor of the permalink post slug on in the post (and page?) editor. + */ +function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) { + global $wpdb; + $post = &get_post($id); + + list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug); + + if ( 'publish' == $post->post_status ) { + $ptype = get_post_type_object($post->post_type); + $view_post = $ptype->labels->view_item; + $title = __('Click to edit this part of the permalink'); + } else { + $title = __('Temporary permalink. Click to edit this part.'); + } + + if ( false === strpos($permalink, '%postname%') && false === strpos($permalink, '%pagename%') ) { + $return = '' . __('Permalink:') . "\n" . '' . $permalink . "\n"; + if ( '' == get_option( 'permalink_structure' ) && current_user_can( 'manage_options' ) && !( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') ) ) + $return .= '' . __('Change Permalinks') . "\n"; + if ( isset($view_post) ) + $return .= "$view_post\n"; + + $return = apply_filters('get_sample_permalink_html', $return, $id, $new_title, $new_slug); + + return $return; + } + + if ( function_exists('mb_strlen') ) { + if ( mb_strlen($post_name) > 30 ) { + $post_name_abridged = mb_substr($post_name, 0, 14). '…' . mb_substr($post_name, -14); + } else { + $post_name_abridged = $post_name; + } + } else { + if ( strlen($post_name) > 30 ) { + $post_name_abridged = substr($post_name, 0, 14). '…' . substr($post_name, -14); + } else { + $post_name_abridged = $post_name; + } + } + + $post_name_html = '' . $post_name_abridged . ''; + $display_link = str_replace(array('%pagename%','%postname%'), $post_name_html, $permalink); + $view_link = str_replace(array('%pagename%','%postname%'), $post_name, $permalink); + $return = '' . __('Permalink:') . "\n"; + $return .= '' . $display_link . "\n"; + $return .= '‎'; // Fix bi-directional text display defect in RTL languages. + $return .= '' . __('Edit') . "\n"; + $return .= '' . $post_name . "\n"; + if ( isset($view_post) ) + $return .= "$view_post\n"; + + $return = apply_filters('get_sample_permalink_html', $return, $id, $new_title, $new_slug); + + return $return; +} + +/** + * Output HTML for the post thumbnail meta-box. + * + * @since 2.9.0 + * + * @param int $thumbnail_id ID of the attachment used for thumbnail + * @return string html + */ +function _wp_post_thumbnail_html( $thumbnail_id = NULL ) { + global $content_width, $_wp_additional_image_sizes, $post_ID; + $set_thumbnail_link = '

    %s

    '; + $content = sprintf($set_thumbnail_link, esc_html__( 'Set featured image' )); + + if ( $thumbnail_id && get_post( $thumbnail_id ) ) { + $old_content_width = $content_width; + $content_width = 266; + if ( !isset( $_wp_additional_image_sizes['post-thumbnail'] ) ) + $thumbnail_html = wp_get_attachment_image( $thumbnail_id, array( $content_width, $content_width ) ); + else + $thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'post-thumbnail' ); + if ( !empty( $thumbnail_html ) ) { + $ajax_nonce = wp_create_nonce( "set_post_thumbnail-$post_ID" ); + $content = sprintf($set_thumbnail_link, $thumbnail_html); + $content .= '

    ' . esc_html__( 'Remove featured image' ) . '

    '; + } + $content_width = $old_content_width; + } + + return apply_filters( 'admin_post_thumbnail_html', $content ); +} + +/** + * Check to see if the post is currently being edited by another user. + * + * @since 2.5.0 + * + * @param int $post_id ID of the post to check for editing + * @return bool|int False: not locked or locked by current user. Int: user ID of user with lock. + */ +function wp_check_post_lock( $post_id ) { + if ( !$post = get_post( $post_id ) ) + return false; + + if ( !$lock = get_post_meta( $post->ID, '_edit_lock', true ) ) + return false; + + $lock = explode( ':', $lock ); + $time = $lock[0]; + $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true ); + + $time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 ); + + if ( $time && $time > time() - $time_window && $user != get_current_user_id() ) + return $user; + return false; +} + +/** + * Mark the post as currently being edited by the current user + * + * @since 2.5.0 + * + * @param int $post_id ID of the post to being edited + * @return bool Returns false if the post doesn't exist of there is no current user + */ +function wp_set_post_lock( $post_id ) { + if ( !$post = get_post( $post_id ) ) + return false; + if ( 0 == ($user_id = get_current_user_id()) ) + return false; + + $now = time(); + $lock = "$now:$user_id"; + + update_post_meta( $post->ID, '_edit_lock', $lock ); +} + +/** + * Outputs the notice message to say that someone else is editing this post at the moment. + * + * @since 2.8.5 + * @return none + */ +function _admin_notice_post_locked() { + global $post; + + $lock = explode( ':', get_post_meta( $post->ID, '_edit_lock', true ) ); + $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true ); + $last_user = get_userdata( $user ); + $last_user_name = $last_user ? $last_user->display_name : __('Somebody'); + + switch ($post->post_type) { + case 'post': + $message = __( 'Warning: %s is currently editing this post' ); + break; + case 'page': + $message = __( 'Warning: %s is currently editing this page' ); + break; + default: + $message = __( 'Warning: %s is currently editing this.' ); + } + + $message = sprintf( $message, esc_html( $last_user_name ) ); + echo "

    $message

    "; +} + +/** + * Creates autosave data for the specified post from $_POST data. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses _wp_translate_postdata() + * @uses _wp_post_revision_fields() + * + * @return unknown + */ +function wp_create_post_autosave( $post_id ) { + $translated = _wp_translate_postdata( true ); + if ( is_wp_error( $translated ) ) + return $translated; + + // Only store one autosave. If there is already an autosave, overwrite it. + if ( $old_autosave = wp_get_post_autosave( $post_id ) ) { + $new_autosave = _wp_post_revision_fields( $_POST, true ); + $new_autosave['ID'] = $old_autosave->ID; + $new_autosave['post_author'] = get_current_user_id(); + return wp_update_post( $new_autosave ); + } + + // _wp_put_post_revision() expects unescaped. + $_POST = stripslashes_deep($_POST); + + // Otherwise create the new autosave as a special post revision + return _wp_put_post_revision( $_POST, true ); +} + +/** + * Save draft or manually autosave for showing preview. + * + * @package WordPress + * @since 2.7.0 + * + * @uses wp_write_post() + * @uses edit_post() + * @uses get_post() + * @uses current_user_can() + * @uses wp_create_post_autosave() + * + * @return str URL to redirect to show the preview + */ +function post_preview() { + + $post_ID = (int) $_POST['post_ID']; + $status = get_post_status( $post_ID ); + if ( 'auto-draft' == $status ) + wp_die( __('Preview not available. Please save as a draft first.') ); + + if ( isset($_POST['catslist']) ) + $_POST['post_category'] = explode(",", $_POST['catslist']); + + if ( isset($_POST['tags_input']) ) + $_POST['tags_input'] = explode(",", $_POST['tags_input']); + + if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) ) + unset($_POST['post_category']); + + $_POST['ID'] = $post_ID; + $post = get_post($post_ID); + + if ( 'page' == $post->post_type ) { + if ( !current_user_can('edit_page', $post_ID) ) + wp_die(__('You are not allowed to edit this page.')); + } else { + if ( !current_user_can('edit_post', $post_ID) ) + wp_die(__('You are not allowed to edit this post.')); + } + + if ( 'draft' == $post->post_status ) { + $id = edit_post(); + } else { // Non drafts are not overwritten. The autosave is stored in a special post revision. + $id = wp_create_post_autosave( $post->ID ); + if ( ! is_wp_error($id) ) + $id = $post->ID; + } + + if ( is_wp_error($id) ) + wp_die( $id->get_error_message() ); + + if ( $_POST['post_status'] == 'draft' ) { + $url = add_query_arg( 'preview', 'true', get_permalink($id) ); + } else { + $nonce = wp_create_nonce('post_preview_' . $id); + $url = add_query_arg( array( 'preview' => 'true', 'preview_id' => $id, 'preview_nonce' => $nonce ), get_permalink($id) ); + } + + return $url; +} + +/** + * Adds the TinyMCE editor used on the Write and Edit screens. + * + * @package WordPress + * @since 2.7.0 + * + * TinyMCE is loaded separately from other Javascript by using wp-tinymce.php. It outputs concatenated + * and optionaly pre-compressed version of the core and all default plugins. Additional plugins are loaded + * directly by TinyMCE using non-blocking method. Custom plugins can be refreshed by adding a query string + * to the URL when queueing them with the mce_external_plugins filter. + * + * @param bool $teeny optional Output a trimmed down version used in Press This. + * @param mixed $settings optional An array that can add to or overwrite the default TinyMCE settings. + */ +function wp_tiny_mce( $teeny = false, $settings = false ) { + global $concatenate_scripts, $compress_scripts, $tinymce_version, $editor_styles; + + if ( ! user_can_richedit() ) + return; + + $baseurl = includes_url('js/tinymce'); + + $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1 + + /* + The following filter allows localization scripts to change the languages displayed in the spellchecker's drop-down menu. + By default it uses Google's spellchecker API, but can be configured to use PSpell/ASpell if installed on the server. + The + sign marks the default language. More information: + http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker + */ + $mce_spellchecker_languages = apply_filters('mce_spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv'); + + if ( $teeny ) { + $plugins = apply_filters( 'teeny_mce_plugins', array('inlinepopups', 'fullscreen', 'wordpress', 'wplink', 'wpdialogs') ); + $ext_plugins = ''; + } else { + $plugins = array( 'inlinepopups', 'spellchecker', 'paste', 'wordpress', 'fullscreen', 'wpeditimage', 'wpgallery', 'tabfocus', 'wplink', 'wpdialogs' ); + + /* + The following filter takes an associative array of external plugins for TinyMCE in the form 'plugin_name' => 'url'. + It adds the plugin's name to TinyMCE's plugins init and the call to PluginManager to load the plugin. + The url should be absolute and should include the js file name to be loaded. Example: + array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' ) + If the plugin uses a button, it should be added with one of the "$mce_buttons" filters. + */ + $mce_external_plugins = apply_filters('mce_external_plugins', array()); + + $ext_plugins = ''; + if ( ! empty($mce_external_plugins) ) { + + /* + The following filter loads external language files for TinyMCE plugins. + It takes an associative array 'plugin_name' => 'path', where path is the + include path to the file. The language file should follow the same format as + /tinymce/langs/wp-langs.php and should define a variable $strings that + holds all translated strings. + When this filter is not used, the function will try to load {mce_locale}.js. + If that is not found, en.js will be tried next. + */ + $mce_external_languages = apply_filters('mce_external_languages', array()); + + $loaded_langs = array(); + $strings = ''; + + if ( ! empty($mce_external_languages) ) { + foreach ( $mce_external_languages as $name => $path ) { + if ( @is_file($path) && @is_readable($path) ) { + include_once($path); + $ext_plugins .= $strings . "\n"; + $loaded_langs[] = $name; + } + } + } + + foreach ( $mce_external_plugins as $name => $url ) { + + if ( is_ssl() ) $url = str_replace('http://', 'https://', $url); + + $plugins[] = '-' . $name; + + $plugurl = dirname($url); + $strings = $str1 = $str2 = ''; + if ( ! in_array($name, $loaded_langs) ) { + $path = str_replace( WP_PLUGIN_URL, '', $plugurl ); + $path = WP_PLUGIN_DIR . $path . '/langs/'; + + if ( function_exists('realpath') ) + $path = trailingslashit( realpath($path) ); + + if ( @is_file($path . $mce_locale . '.js') ) + $strings .= @file_get_contents($path . $mce_locale . '.js') . "\n"; + + if ( @is_file($path . $mce_locale . '_dlg.js') ) + $strings .= @file_get_contents($path . $mce_locale . '_dlg.js') . "\n"; + + if ( 'en' != $mce_locale && empty($strings) ) { + if ( @is_file($path . 'en.js') ) { + $str1 = @file_get_contents($path . 'en.js'); + $strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str1, 1 ) . "\n"; + } + + if ( @is_file($path . 'en_dlg.js') ) { + $str2 = @file_get_contents($path . 'en_dlg.js'); + $strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str2, 1 ) . "\n"; + } + } + + if ( ! empty($strings) ) + $ext_plugins .= "\n" . $strings . "\n"; + } + + $ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n"; + $ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n"; + } + } + } + + if ( $teeny ) { + $mce_buttons = apply_filters( 'teeny_mce_buttons', array('bold, italic, underline, blockquote, separator, strikethrough, bullist, numlist,justifyleft, justifycenter, justifyright, undo, redo, link, unlink, fullscreen') ); + $mce_buttons = implode($mce_buttons, ','); + $mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = ''; + } else { + $mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', '|', 'bullist', 'numlist', 'blockquote', '|', 'justifyleft', 'justifycenter', 'justifyright', '|', 'link', 'unlink', 'wp_more', '|', 'spellchecker', 'fullscreen', 'wp_adv' )); + $mce_buttons = implode($mce_buttons, ','); + + $mce_buttons_2 = array( 'formatselect', 'underline', 'justifyfull', 'forecolor', '|', 'pastetext', 'pasteword', 'removeformat', '|', 'charmap', '|', 'outdent', 'indent', '|', 'undo', 'redo', 'wp_help' ); + $mce_buttons_2 = apply_filters('mce_buttons_2', $mce_buttons_2); + $mce_buttons_2 = implode($mce_buttons_2, ','); + + $mce_buttons_3 = apply_filters('mce_buttons_3', array()); + $mce_buttons_3 = implode($mce_buttons_3, ','); + + $mce_buttons_4 = apply_filters('mce_buttons_4', array()); + $mce_buttons_4 = implode($mce_buttons_4, ','); + } + $no_captions = (bool) apply_filters( 'disable_captions', '' ); + + // TinyMCE init settings + $initArray = array ( + 'mode' => 'specific_textareas', + 'editor_selector' => 'theEditor', + 'width' => '100%', + 'theme' => 'advanced', + 'skin' => 'wp_theme', + 'theme_advanced_buttons1' => $mce_buttons, + 'theme_advanced_buttons2' => $mce_buttons_2, + 'theme_advanced_buttons3' => $mce_buttons_3, + 'theme_advanced_buttons4' => $mce_buttons_4, + 'language' => $mce_locale, + 'spellchecker_languages' => $mce_spellchecker_languages, + 'theme_advanced_toolbar_location' => 'top', + 'theme_advanced_toolbar_align' => 'left', + 'theme_advanced_statusbar_location' => 'bottom', + 'theme_advanced_resizing' => true, + 'theme_advanced_resize_horizontal' => false, + 'dialog_type' => 'modal', + 'formats' => "{ + alignleft : [ + {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}}, + {selector : 'img,table', classes : 'alignleft'} + ], + aligncenter : [ + {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}}, + {selector : 'img,table', classes : 'aligncenter'} + ], + alignright : [ + {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}}, + {selector : 'img,table', classes : 'alignright'} + ], + strikethrough : {inline : 'del'} + }", + 'relative_urls' => false, + 'remove_script_host' => false, + 'convert_urls' => false, + 'apply_source_formatting' => false, + 'remove_linebreaks' => true, + 'gecko_spellcheck' => true, + 'entities' => '38,amp,60,lt,62,gt', + 'accessibility_focus' => true, + 'tabfocus_elements' => 'major-publishing-actions', + 'media_strict' => false, + 'paste_remove_styles' => true, + 'paste_remove_spans' => true, + 'paste_strip_class_attributes' => 'all', + 'paste_text_use_dialog' => true, + 'wpeditimage_disable_captions' => $no_captions, + 'plugins' => implode( ',', $plugins ), + ); + + if ( ! empty( $editor_styles ) && is_array( $editor_styles ) ) { + $mce_css = array(); + $style_uri = get_stylesheet_directory_uri(); + if ( ! is_child_theme() ) { + foreach ( $editor_styles as $file ) + $mce_css[] = "$style_uri/$file"; + } else { + $style_dir = get_stylesheet_directory(); + $template_uri = get_template_directory_uri(); + $template_dir = get_template_directory(); + foreach ( $editor_styles as $file ) { + if ( file_exists( "$template_dir/$file" ) ) + $mce_css[] = "$template_uri/$file"; + if ( file_exists( "$style_dir/$file" ) ) + $mce_css[] = "$style_uri/$file"; + } + } + $mce_css = implode( ',', $mce_css ); + } else { + $mce_css = ''; + } + + $mce_css = trim( apply_filters( 'mce_css', $mce_css ), ' ,' ); + + if ( ! empty($mce_css) ) + $initArray['content_css'] = $mce_css; + + if ( is_array($settings) ) + $initArray = array_merge($initArray, $settings); + + // For people who really REALLY know what they're doing with TinyMCE + // You can modify initArray to add, remove, change elements of the config before tinyMCE.init + // Setting "valid_elements", "invalid_elements" and "extended_valid_elements" can be done through "tiny_mce_before_init". + // Best is to use the default cleanup by not specifying valid_elements, as TinyMCE contains full set of XHTML 1.0. + if ( $teeny ) { + $initArray = apply_filters('teeny_mce_before_init', $initArray); + } else { + $initArray = apply_filters('tiny_mce_before_init', $initArray); + } + + if ( empty($initArray['theme_advanced_buttons3']) && !empty($initArray['theme_advanced_buttons4']) ) { + $initArray['theme_advanced_buttons3'] = $initArray['theme_advanced_buttons4']; + $initArray['theme_advanced_buttons4'] = ''; + } + + if ( ! isset($concatenate_scripts) ) + script_concat_settings(); + + $language = $initArray['language']; + + $compressed = $compress_scripts && $concatenate_scripts && isset($_SERVER['HTTP_ACCEPT_ENCODING']) + && false !== strpos( strtolower($_SERVER['HTTP_ACCEPT_ENCODING']), 'gzip'); + + /** + * Deprecated + * + * The tiny_mce_version filter is not needed since external plugins are loaded directly by TinyMCE. + * These plugins can be refreshed by appending query string to the URL passed to mce_external_plugins filter. + * If the plugin has a popup dialog, a query string can be added to the button action that opens it (in the plugin's code). + */ + $version = apply_filters('tiny_mce_version', ''); + $version = 'ver=' . $tinymce_version . $version; + + if ( 'en' != $language ) + include_once(ABSPATH . WPINC . '/js/tinymce/langs/wp-langs.php'); + + $mce_options = ''; + foreach ( $initArray as $k => $v ) { + if ( is_bool($v) ) { + $val = $v ? 'true' : 'false'; + $mce_options .= $k . ':' . $val . ', '; + continue; + } elseif ( !empty($v) && is_string($v) && ( '{' == $v{0} || '[' == $v{0} ) ) { + $mce_options .= $k . ':' . $v . ', '; + continue; + } + + $mce_options .= $k . ':"' . $v . '", '; + } + + $mce_options = rtrim( trim($mce_options), '\n\r,' ); ?> + + + +\n"; + else + echo "\n"; + + if ( 'en' != $language && isset($lang) ) + echo "\n"; + else + echo "\n"; +?> + + + + +charset) ) + $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; +if ( ! empty($wpdb->collate) ) + $charset_collate .= " COLLATE $wpdb->collate"; + +/** Create WordPress database tables SQL */ +$wp_queries = "CREATE TABLE $wpdb->terms ( + term_id bigint(20) unsigned NOT NULL auto_increment, + name varchar(200) NOT NULL default '', + slug varchar(200) NOT NULL default '', + term_group bigint(10) NOT NULL default 0, + PRIMARY KEY (term_id), + UNIQUE KEY slug (slug), + KEY name (name) +) $charset_collate; +CREATE TABLE $wpdb->term_taxonomy ( + term_taxonomy_id bigint(20) unsigned NOT NULL auto_increment, + term_id bigint(20) unsigned NOT NULL default 0, + taxonomy varchar(32) NOT NULL default '', + description longtext NOT NULL, + parent bigint(20) unsigned NOT NULL default 0, + count bigint(20) NOT NULL default 0, + PRIMARY KEY (term_taxonomy_id), + UNIQUE KEY term_id_taxonomy (term_id,taxonomy), + KEY taxonomy (taxonomy) +) $charset_collate; +CREATE TABLE $wpdb->term_relationships ( + object_id bigint(20) unsigned NOT NULL default 0, + term_taxonomy_id bigint(20) unsigned NOT NULL default 0, + term_order int(11) NOT NULL default 0, + PRIMARY KEY (object_id,term_taxonomy_id), + KEY term_taxonomy_id (term_taxonomy_id) +) $charset_collate; +CREATE TABLE $wpdb->commentmeta ( + meta_id bigint(20) unsigned NOT NULL auto_increment, + comment_id bigint(20) unsigned NOT NULL default '0', + meta_key varchar(255) default NULL, + meta_value longtext, + PRIMARY KEY (meta_id), + KEY comment_id (comment_id), + KEY meta_key (meta_key) +) $charset_collate; +CREATE TABLE $wpdb->comments ( + comment_ID bigint(20) unsigned NOT NULL auto_increment, + comment_post_ID bigint(20) unsigned NOT NULL default '0', + comment_author tinytext NOT NULL, + comment_author_email varchar(100) NOT NULL default '', + comment_author_url varchar(200) NOT NULL default '', + comment_author_IP varchar(100) NOT NULL default '', + comment_date datetime NOT NULL default '0000-00-00 00:00:00', + comment_date_gmt datetime NOT NULL default '0000-00-00 00:00:00', + comment_content text NOT NULL, + comment_karma int(11) NOT NULL default '0', + comment_approved varchar(20) NOT NULL default '1', + comment_agent varchar(255) NOT NULL default '', + comment_type varchar(20) NOT NULL default '', + comment_parent bigint(20) unsigned NOT NULL default '0', + user_id bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (comment_ID), + KEY comment_approved (comment_approved), + KEY comment_post_ID (comment_post_ID), + KEY comment_approved_date_gmt (comment_approved,comment_date_gmt), + KEY comment_date_gmt (comment_date_gmt), + KEY comment_parent (comment_parent) +) $charset_collate; +CREATE TABLE $wpdb->links ( + link_id bigint(20) unsigned NOT NULL auto_increment, + link_url varchar(255) NOT NULL default '', + link_name varchar(255) NOT NULL default '', + link_image varchar(255) NOT NULL default '', + link_target varchar(25) NOT NULL default '', + link_description varchar(255) NOT NULL default '', + link_visible varchar(20) NOT NULL default 'Y', + link_owner bigint(20) unsigned NOT NULL default '1', + link_rating int(11) NOT NULL default '0', + link_updated datetime NOT NULL default '0000-00-00 00:00:00', + link_rel varchar(255) NOT NULL default '', + link_notes mediumtext NOT NULL, + link_rss varchar(255) NOT NULL default '', + PRIMARY KEY (link_id), + KEY link_visible (link_visible) +) $charset_collate; +CREATE TABLE $wpdb->options ( + option_id bigint(20) unsigned NOT NULL auto_increment, + blog_id int(11) NOT NULL default '0', + option_name varchar(64) NOT NULL default '', + option_value longtext NOT NULL, + autoload varchar(20) NOT NULL default 'yes', + PRIMARY KEY (option_id), + UNIQUE KEY option_name (option_name) +) $charset_collate; +CREATE TABLE $wpdb->postmeta ( + meta_id bigint(20) unsigned NOT NULL auto_increment, + post_id bigint(20) unsigned NOT NULL default '0', + meta_key varchar(255) default NULL, + meta_value longtext, + PRIMARY KEY (meta_id), + KEY post_id (post_id), + KEY meta_key (meta_key) +) $charset_collate; +CREATE TABLE $wpdb->posts ( + ID bigint(20) unsigned NOT NULL auto_increment, + post_author bigint(20) unsigned NOT NULL default '0', + post_date datetime NOT NULL default '0000-00-00 00:00:00', + post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00', + post_content longtext NOT NULL, + post_title text NOT NULL, + post_excerpt text NOT NULL, + post_status varchar(20) NOT NULL default 'publish', + comment_status varchar(20) NOT NULL default 'open', + ping_status varchar(20) NOT NULL default 'open', + post_password varchar(20) NOT NULL default '', + post_name varchar(200) NOT NULL default '', + to_ping text NOT NULL, + pinged text NOT NULL, + post_modified datetime NOT NULL default '0000-00-00 00:00:00', + post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00', + post_content_filtered text NOT NULL, + post_parent bigint(20) unsigned NOT NULL default '0', + guid varchar(255) NOT NULL default '', + menu_order int(11) NOT NULL default '0', + post_type varchar(20) NOT NULL default 'post', + post_mime_type varchar(100) NOT NULL default '', + comment_count bigint(20) NOT NULL default '0', + PRIMARY KEY (ID), + KEY post_name (post_name), + KEY type_status_date (post_type,post_status,post_date,ID), + KEY post_parent (post_parent), + KEY post_author (post_author) +) $charset_collate; +CREATE TABLE $wpdb->users ( + ID bigint(20) unsigned NOT NULL auto_increment, + user_login varchar(60) NOT NULL default '', + user_pass varchar(64) NOT NULL default '', + user_nicename varchar(50) NOT NULL default '', + user_email varchar(100) NOT NULL default '', + user_url varchar(100) NOT NULL default '', + user_registered datetime NOT NULL default '0000-00-00 00:00:00', + user_activation_key varchar(60) NOT NULL default '', + user_status int(11) NOT NULL default '0', + display_name varchar(250) NOT NULL default '', + PRIMARY KEY (ID), + KEY user_login_key (user_login), + KEY user_nicename (user_nicename) +) $charset_collate; +CREATE TABLE $wpdb->usermeta ( + umeta_id bigint(20) unsigned NOT NULL auto_increment, + user_id bigint(20) unsigned NOT NULL default '0', + meta_key varchar(255) default NULL, + meta_value longtext, + PRIMARY KEY (umeta_id), + KEY user_id (user_id), + KEY meta_key (meta_key) +) $charset_collate;"; + +/** + * Create WordPress options and set the default values. + * + * @since 1.5.0 + * @uses $wpdb + * @uses $wp_db_version + */ +function populate_options() { + global $wpdb, $wp_db_version, $current_site; + + $guessurl = wp_guess_url(); + + do_action('populate_options'); + + if ( ini_get('safe_mode') ) { + // Safe mode can break mkdir() so use a flat structure by default. + $uploads_use_yearmonth_folders = 0; + } else { + $uploads_use_yearmonth_folders = 1; + } + + $options = array( + 'siteurl' => $guessurl, + 'blogname' => __('My Site'), + /* translators: blog tagline */ + 'blogdescription' => __('Just another WordPress site'), + 'users_can_register' => 0, + 'admin_email' => 'you@example.com', + 'start_of_week' => 1, + 'use_balanceTags' => 0, + 'use_smilies' => 1, + 'require_name_email' => 1, + 'comments_notify' => 1, + 'posts_per_rss' => 10, + 'rss_use_excerpt' => 0, + 'mailserver_url' => 'mail.example.com', + 'mailserver_login' => 'login@example.com', + 'mailserver_pass' => 'password', + 'mailserver_port' => 110, + 'default_category' => 1, + 'default_comment_status' => 'open', + 'default_ping_status' => 'open', + 'default_pingback_flag' => 1, + 'default_post_edit_rows' => 20, + 'posts_per_page' => 10, + /* translators: default date format, see http://php.net/date */ + 'date_format' => __('F j, Y'), + /* translators: default time format, see http://php.net/date */ + 'time_format' => __('g:i a'), + /* translators: links last updated date format, see http://php.net/date */ + 'links_updated_date_format' => __('F j, Y g:i a'), + 'links_recently_updated_prepend' => '', + 'links_recently_updated_append' => '', + 'links_recently_updated_time' => 120, + 'comment_moderation' => 0, + 'moderation_notify' => 1, + 'permalink_structure' => '', + 'gzipcompression' => 0, + 'hack_file' => 0, + 'blog_charset' => 'UTF-8', + 'moderation_keys' => '', + 'active_plugins' => array(), + 'home' => $guessurl, + 'category_base' => '', + 'ping_sites' => 'http://rpc.pingomatic.com/', + 'advanced_edit' => 0, + 'comment_max_links' => 2, + 'gmt_offset' => date('Z') / 3600, + + // 1.5 + 'default_email_category' => 1, + 'recently_edited' => '', + 'template' => WP_DEFAULT_THEME, + 'stylesheet' => WP_DEFAULT_THEME, + 'comment_whitelist' => 1, + 'blacklist_keys' => '', + 'comment_registration' => 0, + 'rss_language' => 'en', + 'html_type' => 'text/html', + + // 1.5.1 + 'use_trackback' => 0, + + // 2.0 + 'default_role' => 'subscriber', + 'db_version' => $wp_db_version, + + // 2.0.1 + 'uploads_use_yearmonth_folders' => $uploads_use_yearmonth_folders, + 'upload_path' => '', + + // 2.1 + 'blog_public' => '1', + 'default_link_category' => 2, + 'show_on_front' => 'posts', + + // 2.2 + 'tag_base' => '', + + // 2.5 + 'show_avatars' => '1', + 'avatar_rating' => 'G', + 'upload_url_path' => '', + 'thumbnail_size_w' => 150, + 'thumbnail_size_h' => 150, + 'thumbnail_crop' => 1, + 'medium_size_w' => 300, + 'medium_size_h' => 300, + + // 2.6 + 'avatar_default' => 'mystery', + 'enable_app' => 0, + 'enable_xmlrpc' => 0, + + // 2.7 + 'large_size_w' => 1024, + 'large_size_h' => 1024, + 'image_default_link_type' => 'file', + 'image_default_size' => '', + 'image_default_align' => '', + 'close_comments_for_old_posts' => 0, + 'close_comments_days_old' => 14, + 'thread_comments' => 1, + 'thread_comments_depth' => 5, + 'page_comments' => 0, + 'comments_per_page' => 50, + 'default_comments_page' => 'newest', + 'comment_order' => 'asc', + 'sticky_posts' => array(), + 'widget_categories' => array(), + 'widget_text' => array(), + 'widget_rss' => array(), + + // 2.8 + 'timezone_string' => '', + + // 2.9 + 'embed_autourls' => 1, + 'embed_size_w' => '', + 'embed_size_h' => 600, + + // 3.0 + 'page_for_posts' => 0, + 'page_on_front' => 0, + + // 3.1 + 'default_post_format' => 0, + ); + + // 3.0 multisite + if ( is_multisite() ) { + /* translators: blog tagline */ + $options[ 'blogdescription' ] = sprintf(__('Just another %s site'), $current_site->site_name ); + $options[ 'permalink_structure' ] = '/%year%/%monthnum%/%day%/%postname%/'; + } + + // Set autoload to no for these options + $fat_options = array( 'moderation_keys', 'recently_edited', 'blacklist_keys' ); + + $existing_options = $wpdb->get_col("SELECT option_name FROM $wpdb->options"); + + $insert = ''; + foreach ( $options as $option => $value ) { + if ( in_array($option, $existing_options) ) + continue; + if ( in_array($option, $fat_options) ) + $autoload = 'no'; + else + $autoload = 'yes'; + + $option = $wpdb->escape($option); + if ( is_array($value) ) + $value = serialize($value); + $value = $wpdb->escape($value); + if ( !empty($insert) ) + $insert .= ', '; + $insert .= "('$option', '$value', '$autoload')"; + } + + if ( !empty($insert) ) + $wpdb->query("INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES " . $insert); + + // in case it is set, but blank, update "home" + if ( !__get_option('home') ) update_option('home', $guessurl); + + // Delete unused options + $unusedoptions = array ('blodotgsping_url', 'bodyterminator', 'emailtestonly', 'phoneemail_separator', 'smilies_directory', 'subjectprefix', 'use_bbcode', 'use_blodotgsping', 'use_phoneemail', 'use_quicktags', 'use_weblogsping', 'weblogs_cache_file', 'use_preview', 'use_htmltrans', 'smilies_directory', 'fileupload_allowedusers', 'use_phoneemail', 'default_post_status', 'default_post_category', 'archive_mode', 'time_difference', 'links_minadminlevel', 'links_use_adminlevels', 'links_rating_type', 'links_rating_char', 'links_rating_ignore_zero', 'links_rating_single_image', 'links_rating_image0', 'links_rating_image1', 'links_rating_image2', 'links_rating_image3', 'links_rating_image4', 'links_rating_image5', 'links_rating_image6', 'links_rating_image7', 'links_rating_image8', 'links_rating_image9', 'weblogs_cacheminutes', 'comment_allowed_tags', 'search_engine_friendly_urls', 'default_geourl_lat', 'default_geourl_lon', 'use_default_geourl', 'weblogs_xml_url', 'new_users_can_blog', '_wpnonce', '_wp_http_referer', 'Update', 'action', 'rich_editing', 'autosave_interval', 'deactivated_plugins', 'can_compress_scripts', 'page_uris', 'update_core', 'update_plugins', 'update_themes', 'doing_cron', 'random_seed', 'rss_excerpt_length', 'secret', 'use_linksupdate', 'default_comment_status_page', 'wporg_popular_tags', 'what_to_show'); + foreach ( $unusedoptions as $option ) + delete_option($option); + + // delete obsolete magpie stuff + $wpdb->query("DELETE FROM $wpdb->options WHERE option_name REGEXP '^rss_[0-9a-f]{32}(_ts)?$'"); +} + +/** + * Execute WordPress role creation for the various WordPress versions. + * + * @since 2.0.0 + */ +function populate_roles() { + populate_roles_160(); + populate_roles_210(); + populate_roles_230(); + populate_roles_250(); + populate_roles_260(); + populate_roles_270(); + populate_roles_280(); + populate_roles_300(); +} + +/** + * Create the roles for WordPress 2.0 + * + * @since 2.0.0 + */ +function populate_roles_160() { + // Add roles + + // Dummy gettext calls to get strings in the catalog. + /* translators: user role */ + _x('Administrator', 'User role'); + /* translators: user role */ + _x('Editor', 'User role'); + /* translators: user role */ + _x('Author', 'User role'); + /* translators: user role */ + _x('Contributor', 'User role'); + /* translators: user role */ + _x('Subscriber', 'User role'); + + add_role('administrator', 'Administrator'); + add_role('editor', 'Editor'); + add_role('author', 'Author'); + add_role('contributor', 'Contributor'); + add_role('subscriber', 'Subscriber'); + + // Add caps for Administrator role + $role =& get_role('administrator'); + $role->add_cap('switch_themes'); + $role->add_cap('edit_themes'); + $role->add_cap('activate_plugins'); + $role->add_cap('edit_plugins'); + $role->add_cap('edit_users'); + $role->add_cap('edit_files'); + $role->add_cap('manage_options'); + $role->add_cap('moderate_comments'); + $role->add_cap('manage_categories'); + $role->add_cap('manage_links'); + $role->add_cap('upload_files'); + $role->add_cap('import'); + $role->add_cap('unfiltered_html'); + $role->add_cap('edit_posts'); + $role->add_cap('edit_others_posts'); + $role->add_cap('edit_published_posts'); + $role->add_cap('publish_posts'); + $role->add_cap('edit_pages'); + $role->add_cap('read'); + $role->add_cap('level_10'); + $role->add_cap('level_9'); + $role->add_cap('level_8'); + $role->add_cap('level_7'); + $role->add_cap('level_6'); + $role->add_cap('level_5'); + $role->add_cap('level_4'); + $role->add_cap('level_3'); + $role->add_cap('level_2'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + + // Add caps for Editor role + $role =& get_role('editor'); + $role->add_cap('moderate_comments'); + $role->add_cap('manage_categories'); + $role->add_cap('manage_links'); + $role->add_cap('upload_files'); + $role->add_cap('unfiltered_html'); + $role->add_cap('edit_posts'); + $role->add_cap('edit_others_posts'); + $role->add_cap('edit_published_posts'); + $role->add_cap('publish_posts'); + $role->add_cap('edit_pages'); + $role->add_cap('read'); + $role->add_cap('level_7'); + $role->add_cap('level_6'); + $role->add_cap('level_5'); + $role->add_cap('level_4'); + $role->add_cap('level_3'); + $role->add_cap('level_2'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + + // Add caps for Author role + $role =& get_role('author'); + $role->add_cap('upload_files'); + $role->add_cap('edit_posts'); + $role->add_cap('edit_published_posts'); + $role->add_cap('publish_posts'); + $role->add_cap('read'); + $role->add_cap('level_2'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + + // Add caps for Contributor role + $role =& get_role('contributor'); + $role->add_cap('edit_posts'); + $role->add_cap('read'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + + // Add caps for Subscriber role + $role =& get_role('subscriber'); + $role->add_cap('read'); + $role->add_cap('level_0'); +} + +/** + * Create and modify WordPress roles for WordPress 2.1. + * + * @since 2.1.0 + */ +function populate_roles_210() { + $roles = array('administrator', 'editor'); + foreach ($roles as $role) { + $role =& get_role($role); + if ( empty($role) ) + continue; + + $role->add_cap('edit_others_pages'); + $role->add_cap('edit_published_pages'); + $role->add_cap('publish_pages'); + $role->add_cap('delete_pages'); + $role->add_cap('delete_others_pages'); + $role->add_cap('delete_published_pages'); + $role->add_cap('delete_posts'); + $role->add_cap('delete_others_posts'); + $role->add_cap('delete_published_posts'); + $role->add_cap('delete_private_posts'); + $role->add_cap('edit_private_posts'); + $role->add_cap('read_private_posts'); + $role->add_cap('delete_private_pages'); + $role->add_cap('edit_private_pages'); + $role->add_cap('read_private_pages'); + } + + $role =& get_role('administrator'); + if ( ! empty($role) ) { + $role->add_cap('delete_users'); + $role->add_cap('create_users'); + } + + $role =& get_role('author'); + if ( ! empty($role) ) { + $role->add_cap('delete_posts'); + $role->add_cap('delete_published_posts'); + } + + $role =& get_role('contributor'); + if ( ! empty($role) ) { + $role->add_cap('delete_posts'); + } +} + +/** + * Create and modify WordPress roles for WordPress 2.3. + * + * @since 2.3.0 + */ +function populate_roles_230() { + $role =& get_role( 'administrator' ); + + if ( !empty( $role ) ) { + $role->add_cap( 'unfiltered_upload' ); + } +} + +/** + * Create and modify WordPress roles for WordPress 2.5. + * + * @since 2.5.0 + */ +function populate_roles_250() { + $role =& get_role( 'administrator' ); + + if ( !empty( $role ) ) { + $role->add_cap( 'edit_dashboard' ); + } +} + +/** + * Create and modify WordPress roles for WordPress 2.6. + * + * @since 2.6.0 + */ +function populate_roles_260() { + $role =& get_role( 'administrator' ); + + if ( !empty( $role ) ) { + $role->add_cap( 'update_plugins' ); + $role->add_cap( 'delete_plugins' ); + } +} + +/** + * Create and modify WordPress roles for WordPress 2.7. + * + * @since 2.7.0 + */ +function populate_roles_270() { + $role =& get_role( 'administrator' ); + + if ( !empty( $role ) ) { + $role->add_cap( 'install_plugins' ); + $role->add_cap( 'update_themes' ); + } +} + +/** + * Create and modify WordPress roles for WordPress 2.8. + * + * @since 2.8.0 + */ +function populate_roles_280() { + $role =& get_role( 'administrator' ); + + if ( !empty( $role ) ) { + $role->add_cap( 'install_themes' ); + } +} + +/** + * Create and modify WordPress roles for WordPress 3.0. + * + * @since 3.0.0 + */ +function populate_roles_300() { + $role =& get_role( 'administrator' ); + + if ( !empty( $role ) ) { + $role->add_cap( 'update_core' ); + $role->add_cap( 'list_users' ); + $role->add_cap( 'remove_users' ); + $role->add_cap( 'add_users' ); + $role->add_cap( 'promote_users' ); + $role->add_cap( 'edit_theme_options' ); + $role->add_cap( 'delete_themes' ); + $role->add_cap( 'export' ); + } +} + +/** + * populate network settings + * + * @since 3.0.0 + * + * @param int $network_id id of network to populate + * @return bool|WP_Error True on success, or WP_Error on warning (with the install otherwise successful, + * so the error code must be checked) or failure. + */ +function populate_network( $network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false ) { + global $wpdb, $current_site, $wp_db_version, $wp_rewrite; + + $errors = new WP_Error(); + if ( '' == $domain ) + $errors->add( 'empty_domain', __( 'You must provide a domain name.' ) ); + if ( '' == $site_name ) + $errors->add( 'empty_sitename', __( 'You must provide a name for your network of sites.' ) ); + + // check for network collision + if ( $network_id == $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE id = %d", $network_id ) ) ) + $errors->add( 'siteid_exists', __( 'The network already exists.' ) ); + + $site_user = get_user_by_email( $email ); + if ( ! is_email( $email ) ) + $errors->add( 'invalid_email', __( 'You must provide a valid e-mail address.' ) ); + + if ( $errors->get_error_code() ) + return $errors; + + // set up site tables + $template = get_option( 'template' ); + $stylesheet = get_option( 'stylesheet' ); + $allowed_themes = array( $stylesheet => true ); + if ( $template != $stylesheet ) + $allowed_themes[ $template ] = true; + if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template ) + $allowed_themes[ WP_DEFAULT_THEME ] = true; + + if ( 1 == $network_id ) { + $wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path ) ); + $network_id = $wpdb->insert_id; + } else { + $wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path, 'id' => $network_id ) ); + } + + if ( !is_multisite() ) { + $site_admins = array( $site_user->user_login ); + $users = get_users( array( 'fields' => array( 'ID', 'user_login' ) ) ); + if ( $users ) { + foreach ( $users as $user ) { + if ( is_super_admin( $user->ID ) && !in_array( $user->user_login, $site_admins ) ) + $site_admins[] = $user->user_login; + } + } + } else { + $site_admins = get_site_option( 'site_admins' ); + } + + $welcome_email = __( 'Dear User, + +Your new SITE_NAME site has been successfully set up at: +BLOG_URL + +You can log in to the administrator account with the following information: +Username: USERNAME +Password: PASSWORD +Login Here: BLOG_URLwp-login.php + +We hope you enjoy your new site. +Thanks! + +--The Team @ SITE_NAME' ); + + $sitemeta = array( + 'site_name' => $site_name, + 'admin_email' => $site_user->user_email, + 'admin_user_id' => $site_user->ID, + 'registration' => 'none', + 'upload_filetypes' => 'jpg jpeg png gif mp3 mov avi wmv midi mid pdf', + 'blog_upload_space' => 10, + 'fileupload_maxk' => 1500, + 'site_admins' => $site_admins, + 'allowedthemes' => $allowed_themes, + 'illegal_names' => array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files' ), + 'wpmu_upgrade_site' => $wp_db_version, + 'welcome_email' => $welcome_email, + 'first_post' => __( 'Welcome to SITE_NAME. This is your first post. Edit or delete it, then start blogging!' ), + // @todo - network admins should have a method of editing the network siteurl (used for cookie hash) + 'siteurl' => get_option( 'siteurl' ) . '/', + 'add_new_users' => '0', + 'upload_space_check_disabled' => '0', + 'subdomain_install' => intval( $subdomain_install ), + 'global_terms_enabled' => global_terms_enabled() ? '1' : '0' + ); + if ( ! $subdomain_install ) + $sitemeta['illegal_names'][] = 'blog'; + + $insert = ''; + foreach ( $sitemeta as $meta_key => $meta_value ) { + $meta_key = $wpdb->escape( $meta_key ); + if ( is_array( $meta_value ) ) + $meta_value = serialize( $meta_value ); + $meta_value = $wpdb->escape( $meta_value ); + if ( !empty( $insert ) ) + $insert .= ', '; + $insert .= "( $network_id, '$meta_key', '$meta_value')"; + } + $wpdb->query( "INSERT INTO $wpdb->sitemeta ( site_id, meta_key, meta_value ) VALUES " . $insert ); + + $current_site->domain = $domain; + $current_site->path = $path; + $current_site->site_name = ucfirst( $domain ); + + if ( !is_multisite() ) { + $wpdb->insert( $wpdb->blogs, array( 'site_id' => $network_id, 'domain' => $domain, 'path' => $path, 'registered' => current_time( 'mysql' ) ) ); + $blog_id = $wpdb->insert_id; + update_user_meta( $site_user->ID, 'source_domain', $domain ); + update_user_meta( $site_user->ID, 'primary_blog', $blog_id ); + if ( !$upload_path = get_option( 'upload_path' ) ) { + $upload_path = substr( WP_CONTENT_DIR, strlen( ABSPATH ) ) . '/uploads'; + update_option( 'upload_path', $upload_path ); + } + update_option( 'fileupload_url', get_option( 'siteurl' ) . '/' . $upload_path ); + } + + if ( $subdomain_install ) + update_option( 'permalink_structure', '/%year%/%monthnum%/%day%/%postname%/'); + else + update_option( 'permalink_structure', '/blog/%year%/%monthnum%/%day%/%postname%/'); + + $wp_rewrite->flush_rules(); + + if ( $subdomain_install ) { + $vhost_ok = false; + $errstr = ''; + $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname! + $page = wp_remote_get( 'http://' . $hostname, array( 'timeout' => 5, 'httpversion' => '1.1' ) ); + if ( is_wp_error( $page ) ) + $errstr = $page->get_error_message(); + elseif ( 200 == $page['response']['code'] ) + $vhost_ok = true; + + if ( ! $vhost_ok ) { + $msg = '

    ' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '

    '; + $msg .= '

    ' . sprintf( __( 'The installer attempted to contact a random hostname (%1$s) on your domain.' ), $hostname ); + if ( ! empty ( $errstr ) ) + $msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '' . $errstr . '' ); + $msg .= '

    '; + $msg .= '

    ' . __( 'To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a * hostname record pointing at your web server in your DNS configuration tool.' ) . '

    '; + $msg .= '

    ' . __( 'You can still use your site but any subdomain you create may not be accessible. If you know your DNS is correct, ignore this message.' ) . '

    '; + return new WP_Error( 'no_wildcard_dns', $msg ); + } + } + + return true; +} + +?> diff --git a/src/wp-admin/includes/taxonomy.php b/src/wp-admin/includes/taxonomy.php new file mode 100644 index 00000000..12e231a8 --- /dev/null +++ b/src/wp-admin/includes/taxonomy.php @@ -0,0 +1,252 @@ + $cat_name, 'category_parent' => $parent) ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.0.0 + * + * @param unknown_type $categories + * @param unknown_type $post_id + * @return unknown + */ +function wp_create_categories($categories, $post_id = '') { + $cat_ids = array (); + foreach ($categories as $category) { + if ($id = category_exists($category)) + $cat_ids[] = $id; + else + if ($id = wp_create_category($category)) + $cat_ids[] = $id; + } + + if ( $post_id ) + wp_set_post_categories($post_id, $cat_ids); + + return $cat_ids; +} + +/** + * Updates an existing Category or creates a new Category. + * + * @since 2.0.0 + * + * @param mixed $catarr See defaults below. Set 'cat_ID' to a non-zero value to update an existing category. The 'taxonomy' key was added in 3.0.0. + * @param bool $wp_error Optional, since 2.5.0. Set this to true if the caller handles WP_Error return values. + * @return int|object The ID number of the new or updated Category on success. Zero or a WP_Error on failure, depending on param $wp_error. + */ +function wp_insert_category($catarr, $wp_error = false) { + $cat_defaults = array('cat_ID' => 0, 'taxonomy' => 'category', 'cat_name' => '', 'category_description' => '', 'category_nicename' => '', 'category_parent' => ''); + $catarr = wp_parse_args($catarr, $cat_defaults); + extract($catarr, EXTR_SKIP); + + if ( trim( $cat_name ) == '' ) { + if ( ! $wp_error ) + return 0; + else + return new WP_Error( 'cat_name', __('You did not enter a category name.') ); + } + + $cat_ID = (int) $cat_ID; + + // Are we updating or creating? + if ( !empty ($cat_ID) ) + $update = true; + else + $update = false; + + $name = $cat_name; + $description = $category_description; + $slug = $category_nicename; + $parent = $category_parent; + + $parent = (int) $parent; + if ( $parent < 0 ) + $parent = 0; + + if ( empty($parent) || !category_exists( $parent ) || ($cat_ID && cat_is_ancestor_of($cat_ID, $parent) ) ) + $parent = 0; + + $args = compact('name', 'slug', 'parent', 'description'); + + if ( $update ) + $cat_ID = wp_update_term($cat_ID, $taxonomy, $args); + else + $cat_ID = wp_insert_term($cat_name, $taxonomy, $args); + + if ( is_wp_error($cat_ID) ) { + if ( $wp_error ) + return $cat_ID; + else + return 0; + } + + return $cat_ID['term_id']; +} + +/** + * Aliases wp_insert_category() with minimal args. + * + * If you want to update only some fields of an existing category, call this + * function with only the new values set inside $catarr. + * + * @since 2.0.0 + * + * @param array $catarr The 'cat_ID' value is required. All other keys are optional. + * @return int|bool The ID number of the new or updated Category on success. Zero or FALSE on failure. + */ +function wp_update_category($catarr) { + $cat_ID = (int) $catarr['cat_ID']; + + if ( isset($catarr['category_parent']) && ($cat_ID == $catarr['category_parent']) ) + return false; + + // First, get all of the original fields + $category = get_category($cat_ID, ARRAY_A); + + // Escape data pulled from DB. + $category = add_magic_quotes($category); + + // Merge old and new fields with new fields overwriting old ones. + $catarr = array_merge($category, $catarr); + + return wp_insert_category($catarr); +} + +// +// Tags +// + +/** + * {@internal Missing Short Description}} + * + * @since 2.3.0 + * + * @param unknown_type $tag_name + * @return unknown + */ +function tag_exists($tag_name) { + return term_exists($tag_name, 'post_tag'); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.3.0 + * + * @param unknown_type $tag_name + * @return unknown + */ +function wp_create_tag($tag_name) { + return wp_create_term( $tag_name, 'post_tag'); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.3.0 + * + * @param unknown_type $post_id + * @return unknown + */ +function get_tags_to_edit( $post_id, $taxonomy = 'post_tag' ) { + return get_terms_to_edit( $post_id, $taxonomy); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.8.0 + * + * @param unknown_type $post_id + * @return unknown + */ +function get_terms_to_edit( $post_id, $taxonomy = 'post_tag' ) { + $post_id = (int) $post_id; + if ( !$post_id ) + return false; + + $tags = wp_get_post_terms($post_id, $taxonomy, array()); + + if ( !$tags ) + return false; + + if ( is_wp_error($tags) ) + return $tags; + + foreach ( $tags as $tag ) + $tag_names[] = $tag->name; + $tags_to_edit = join( ',', $tag_names ); + $tags_to_edit = esc_attr( $tags_to_edit ); + $tags_to_edit = apply_filters( 'terms_to_edit', $tags_to_edit, $taxonomy ); + + return $tags_to_edit; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.8.0 + * + * @param unknown_type $tag_name + * @return unknown + */ +function wp_create_term($tag_name, $taxonomy = 'post_tag') { + if ( $id = term_exists($tag_name, $taxonomy) ) + return $id; + + return wp_insert_term($tag_name, $taxonomy); +} diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php new file mode 100644 index 00000000..2f16b3c1 --- /dev/null +++ b/src/wp-admin/includes/template.php @@ -0,0 +1,2192 @@ + 'parent', 'id' => 'term_id'); //TODO: decouple this + + function start_lvl(&$output, $depth, $args) { + $indent = str_repeat("\t", $depth); + $output .= "$indent
      \n"; + } + + function end_lvl(&$output, $depth, $args) { + $indent = str_repeat("\t", $depth); + $output .= "$indent
    \n"; + } + + function start_el(&$output, $category, $depth, $args) { + extract($args); + if ( empty($taxonomy) ) + $taxonomy = 'category'; + + if ( $taxonomy == 'category' ) + $name = 'post_category'; + else + $name = 'tax_input['.$taxonomy.']'; + + $class = in_array( $category->term_id, $popular_cats ) ? ' class="popular-category"' : ''; + $output .= "\n
  • " . ''; + } + + function end_el(&$output, $category, $depth, $args) { + $output .= "
  • \n"; + } +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.1 + * + * @param unknown_type $post_id + * @param unknown_type $descendants_and_self + * @param unknown_type $selected_cats + * @param unknown_type $popular_cats + */ +function wp_category_checklist( $post_id = 0, $descendants_and_self = 0, $selected_cats = false, $popular_cats = false, $walker = null, $checked_ontop = true ) { + wp_terms_checklist($post_id, + array( + 'taxonomy' => 'category', + 'descendants_and_self' => $descendants_and_self, + 'selected_cats' => $selected_cats, + 'popular_cats' => $popular_cats, + 'walker' => $walker, + 'checked_ontop' => $checked_ontop + )); +} + +/** + * Taxonomy independent version of wp_category_checklist + * + * @since 3.0.0 + * + * @param int $post_id + * @param array $args + */ +function wp_terms_checklist($post_id = 0, $args = array()) { + $defaults = array( + 'descendants_and_self' => 0, + 'selected_cats' => false, + 'popular_cats' => false, + 'walker' => null, + 'taxonomy' => 'category', + 'checked_ontop' => true + ); + extract( wp_parse_args($args, $defaults), EXTR_SKIP ); + + if ( empty($walker) || !is_a($walker, 'Walker') ) + $walker = new Walker_Category_Checklist; + + $descendants_and_self = (int) $descendants_and_self; + + $args = array('taxonomy' => $taxonomy); + + $tax = get_taxonomy($taxonomy); + $args['disabled'] = !current_user_can($tax->cap->assign_terms); + + if ( is_array( $selected_cats ) ) + $args['selected_cats'] = $selected_cats; + elseif ( $post_id ) + $args['selected_cats'] = wp_get_object_terms($post_id, $taxonomy, array_merge($args, array('fields' => 'ids'))); + else + $args['selected_cats'] = array(); + + if ( is_array( $popular_cats ) ) + $args['popular_cats'] = $popular_cats; + else + $args['popular_cats'] = get_terms( $taxonomy, array( 'fields' => 'ids', 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) ); + + if ( $descendants_and_self ) { + $categories = (array) get_terms($taxonomy, array( 'child_of' => $descendants_and_self, 'hierarchical' => 0, 'hide_empty' => 0 ) ); + $self = get_term( $descendants_and_self, $taxonomy ); + array_unshift( $categories, $self ); + } else { + $categories = (array) get_terms($taxonomy, array('get' => 'all')); + } + + if ( $checked_ontop ) { + // Post process $categories rather than adding an exclude to the get_terms() query to keep the query the same across all posts (for any query cache) + $checked_categories = array(); + $keys = array_keys( $categories ); + + foreach( $keys as $k ) { + if ( in_array( $categories[$k]->term_id, $args['selected_cats'] ) ) { + $checked_categories[] = $categories[$k]; + unset( $categories[$k] ); + } + } + + // Put checked cats on top + echo call_user_func_array(array(&$walker, 'walk'), array($checked_categories, 0, $args)); + } + // Then the rest of them + echo call_user_func_array(array(&$walker, 'walk'), array($categories, 0, $args)); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param unknown_type $taxonomy + * @param unknown_type $default + * @param unknown_type $number + * @param unknown_type $echo + * @return unknown + */ +function wp_popular_terms_checklist( $taxonomy, $default = 0, $number = 10, $echo = true ) { + global $post_ID; + + if ( $post_ID ) + $checked_terms = wp_get_object_terms($post_ID, $taxonomy, array('fields'=>'ids')); + else + $checked_terms = array(); + + $terms = get_terms( $taxonomy, array( 'orderby' => 'count', 'order' => 'DESC', 'number' => $number, 'hierarchical' => false ) ); + + $tax = get_taxonomy($taxonomy); + if ( ! current_user_can($tax->cap->assign_terms) ) + $disabled = 'disabled="disabled"'; + else + $disabled = ''; + + $popular_ids = array(); + foreach ( (array) $terms as $term ) { + $popular_ids[] = $term->term_id; + if ( !$echo ) // hack for AJAX use + continue; + $id = "popular-$taxonomy-$term->term_id"; + $checked = in_array( $term->term_id, $checked_terms ) ? 'checked="checked"' : ''; + ?> + + + + 'name', 'hide_empty' => 0 ) ); + + if ( empty( $categories ) ) + return; + + foreach ( $categories as $category ) { + $cat_id = $category->term_id; + $name = esc_html( apply_filters( 'the_category', $category->name ) ); + $checked = in_array( $cat_id, $checked_categories ) ? ' checked="checked"' : ''; + echo '"; + } +} + +/** + * Get the column headers for a screen + * + * @since 2.7.0 + * + * @param string|object $screen The screen you want the headers for + * @return array Containing the headers in the format id => UI String + */ +function get_column_headers( $screen ) { + if ( is_string( $screen ) ) + $screen = convert_to_screen( $screen ); + + global $_wp_column_headers; + + if ( !isset( $_wp_column_headers[ $screen->id ] ) ) { + $_wp_column_headers[ $screen->id ] = apply_filters( 'manage_' . $screen->id . '_columns', array() ); + } + + return $_wp_column_headers[ $screen->id ]; +} + +/** + * Get a list of hidden columns. + * + * @since 2.7.0 + * + * @param string|object $screen The screen you want the hidden columns for + * @return array + */ +function get_hidden_columns( $screen ) { + if ( is_string( $screen ) ) + $screen = convert_to_screen( $screen ); + + return (array) get_user_option( 'manage' . $screen->id . 'columnshidden' ); +} + +// adds hidden fields with the data for use in the inline editor for posts and pages +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @param unknown_type $post + */ +function get_inline_data($post) { + $post_type_object = get_post_type_object($post->post_type); + if ( ! current_user_can($post_type_object->cap->edit_post, $post->ID) ) + return; + + $title = esc_textarea( trim( $post->post_title ) ); + + echo ' +'; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @param unknown_type $position + * @param unknown_type $checkbox + * @param unknown_type $mode + */ +function wp_comment_reply($position = '1', $checkbox = false, $mode = 'single', $table_row = true) { + // allow plugin to replace the popup content + $content = apply_filters( 'wp_comment_reply', '', array('position' => $position, 'checkbox' => $checkbox, 'mode' => $mode) ); + + if ( ! empty($content) ) { + echo $content; + return; + } + + if ( $mode == 'single' ) { + $wp_list_table = _get_list_table('WP_Post_Comments_List_Table'); + } else { + $wp_list_table = _get_list_table('WP_Comments_List_Table'); + } + +?> +
    + +
    + + + +
    + + + + + + + ' . __( 'Name' ) . ' + ' . __( 'Value' ) . ' + + + + + +'; //TBODY needed for list-manipulation JS + return; + } + $count = 0; +?> + + + + + + + + + + +
    + + $entry['meta_id'] = (int) $entry['meta_id']; + + $delete_nonce = wp_create_nonce( 'delete-meta_' . $entry['meta_id'] ); + + $r .= "\n\t"; + $r .= "\n\t\t"; + + $r .= "\n\t\t
    "; + $r .= get_submit_button( __( 'Delete' ), "delete:the-list:meta-{$entry['meta_id']}::_ajax_nonce=$delete_nonce deletemeta", "deletemeta[{$entry['meta_id']}]", false, array( 'tabindex' => '6' ) ); + $r .= "\n\t\t"; + $r .= get_submit_button( __( 'Update' ), "add:the-list:meta-{$entry['meta_id']}::_ajax_nonce-add-meta=$update_nonce updatemeta" , 'updatemeta', false, array( 'tabindex' => '6' ) ); + $r .= "
    "; + $r .= wp_nonce_field( 'change-meta', '_ajax_nonce', false, false ); + $r .= ""; + + $r .= "\n\t\t\n\t"; + return $r; +} + +/** + * {@internal Missing Short Description}} + * + * @since 1.2.0 + */ +function meta_form() { + global $wpdb; + $limit = (int) apply_filters( 'postmeta_form_limit', 30 ); + $keys = $wpdb->get_col( " + SELECT meta_key + FROM $wpdb->postmeta + GROUP BY meta_key + HAVING meta_key NOT LIKE '\_%' + ORDER BY meta_key + LIMIT $limit" ); + if ( $keys ) + natcasesort($keys); +?> +

    + + + + + + + + + + + + + + + + +
    + + + + + + + + + +
    + 'addmetasub', 'tabindex' => '9' ) ); ?> + +
    +post_status, array('draft', 'pending') ) && (!$post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt ) ); + + $tab_index_attribute = ''; + if ( (int) $tab_index > 0 ) + $tab_index_attribute = " tabindex=\"$tab_index\""; + + // echo '
    '; + + $time_adj = current_time('timestamp'); + $post_date = ($for_post) ? $post->post_date : $comment->comment_date; + $jj = ($edit) ? mysql2date( 'd', $post_date, false ) : gmdate( 'd', $time_adj ); + $mm = ($edit) ? mysql2date( 'm', $post_date, false ) : gmdate( 'm', $time_adj ); + $aa = ($edit) ? mysql2date( 'Y', $post_date, false ) : gmdate( 'Y', $time_adj ); + $hh = ($edit) ? mysql2date( 'H', $post_date, false ) : gmdate( 'H', $time_adj ); + $mn = ($edit) ? mysql2date( 'i', $post_date, false ) : gmdate( 'i', $time_adj ); + $ss = ($edit) ? mysql2date( 's', $post_date, false ) : gmdate( 's', $time_adj ); + + $cur_jj = gmdate( 'd', $time_adj ); + $cur_mm = gmdate( 'm', $time_adj ); + $cur_aa = gmdate( 'Y', $time_adj ); + $cur_hh = gmdate( 'H', $time_adj ); + $cur_mn = gmdate( 'i', $time_adj ); + + $month = "'; + + $day = ''; + $year = ''; + $hour = ''; + $minute = ''; + + echo '
    '; + /* translators: 1: month input, 2: day input, 3: year input, 4: hour input, 5: minute input */ + printf(__('%1$s%2$s, %3$s @ %4$s : %5$s'), $month, $day, $year, $hour, $minute); + + echo '
    '; + + if ( $multi ) return; + + echo "\n\n"; + foreach ( array('mm', 'jj', 'aa', 'hh', 'mn') as $timeunit ) { + echo '' . "\n"; + $cur_timeunit = 'cur_' . $timeunit; + echo '' . "\n"; + } +?> + +

    + + +

    +$template"; + endforeach; +} + +/** + * {@internal Missing Short Description}} + * + * @since 1.5.0 + * + * @param unknown_type $default + * @param unknown_type $parent + * @param unknown_type $level + * @return unknown + */ +function parent_dropdown( $default = 0, $parent = 0, $level = 0 ) { + global $wpdb, $post_ID; + $items = $wpdb->get_results( $wpdb->prepare("SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' ORDER BY menu_order", $parent) ); + + if ( $items ) { + foreach ( $items as $item ) { + // A page cannot be its own parent. + if (!empty ( $post_ID ) ) { + if ( $item->ID == $post_ID ) { + continue; + } + } + $pad = str_repeat( ' ', $level * 3 ); + if ( $item->ID == $default) + $current = ' selected="selected"'; + else + $current = ''; + + echo "\n\t"; + parent_dropdown( $default, $item->ID, $level +1 ); + } + } else { + return false; + } +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.0.0 + * + * @param unknown_type $id + * @return unknown + */ +function the_attachment_links( $id = false ) { + $id = (int) $id; + $post = & get_post( $id ); + + if ( $post->post_type != 'attachment' ) + return false; + + $icon = wp_get_attachment_image( $post->ID, 'thumbnail', true ); + $attachment_data = wp_get_attachment_metadata( $id ); + $thumb = isset( $attachment_data['thumb'] ); +?> + + html elements for role selectors + * + * @since 2.1.0 + * + * @param string $selected slug for the role that should be already selected + */ +function wp_dropdown_roles( $selected = false ) { + $p = ''; + $r = ''; + + $editable_roles = get_editable_roles(); + + foreach ( $editable_roles as $role => $details ) { + $name = translate_user_role($details['name'] ); + if ( $selected == $role ) // preselect specified role + $p = "\n\t"; + else + $r .= "\n\t"; + } + echo $p . $r; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.3.0 + * + * @param unknown_type $size + * @return unknown + */ +function wp_convert_hr_to_bytes( $size ) { + $size = strtolower($size); + $bytes = (int) $size; + if ( strpos($size, 'k') !== false ) + $bytes = intval($size) * 1024; + elseif ( strpos($size, 'm') !== false ) + $bytes = intval($size) * 1024 * 1024; + elseif ( strpos($size, 'g') !== false ) + $bytes = intval($size) * 1024 * 1024 * 1024; + return $bytes; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.3.0 + * + * @param unknown_type $bytes + * @return unknown + */ +function wp_convert_bytes_to_hr( $bytes ) { + $units = array( 0 => 'B', 1 => 'kB', 2 => 'MB', 3 => 'GB' ); + $log = log( $bytes, 1024 ); + $power = (int) $log; + $size = pow(1024, $log - $power); + return $size . $units[$power]; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function wp_max_upload_size() { + $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); + $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) ); + $bytes = apply_filters( 'upload_size_limit', min($u_bytes, $p_bytes), $u_bytes, $p_bytes ); + return $bytes; +} + +/** + * Outputs the form used by the importers to accept the data to be imported + * + * @since 2.0.0 + * + * @param string $action The action attribute for the form. + */ +function wp_import_upload_form( $action ) { + $bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() ); + $size = wp_convert_bytes_to_hr( $bytes ); + $upload_dir = wp_upload_dir(); + if ( ! empty( $upload_dir['error'] ) ) : + ?>

    +

    +
    +

    + () + + + +

    + +
    + $id, 'title' => $title, 'callback' => $callback, 'args' => $callback_args); +} + +/** + * Meta-Box template function + * + * @since 2.5.0 + * + * @param string $page page identifier, also known as screen identifier + * @param string $context box context + * @param mixed $object gets passed to the box callback function as first parameter + * @return int number of meta_boxes + */ +function do_meta_boxes($page, $context, $object) { + global $wp_meta_boxes; + static $already_sorted = false; + + $hidden = get_hidden_meta_boxes($page); + + printf('
    ', htmlspecialchars($context)); + + $i = 0; + do { + // Grab the ones the user has manually sorted. Pull them out of their previous context/priority and into the one the user chose + if ( !$already_sorted && $sorted = get_user_option( "meta-box-order_$page" ) ) { + foreach ( $sorted as $box_context => $ids ) + foreach ( explode(',', $ids) as $id ) + if ( $id ) + add_meta_box( $id, null, null, $page, $box_context, 'sorted' ); + } + $already_sorted = true; + + if ( !isset($wp_meta_boxes) || !isset($wp_meta_boxes[$page]) || !isset($wp_meta_boxes[$page][$context]) ) + break; + + foreach ( array('high', 'sorted', 'core', 'default', 'low') as $priority ) { + if ( isset($wp_meta_boxes[$page][$context][$priority]) ) { + foreach ( (array) $wp_meta_boxes[$page][$context][$priority] as $box ) { + if ( false == $box || ! $box['title'] ) + continue; + $i++; + $style = ''; + $hidden_class = in_array($box['id'], $hidden) ? ' hide-if-js' : ''; + echo '
    ' . "\n"; + echo '

    '; + echo "

    {$box['title']}

    \n"; + echo '
    ' . "\n"; + call_user_func($box['callback'], $object, $box); + echo "
    \n"; + echo "
    \n"; + } + } + } + } while(0); + + echo "
    "; + + return $i; + +} + +/** + * Remove a meta box from an edit form. + * + * @since 2.6.0 + * + * @param string $id String for use in the 'id' attribute of tags. + * @param string $page The type of edit page on which to show the box (post, page, link). + * @param string $context The context within the page where the boxes should show ('normal', 'advanced'). + */ +function remove_meta_box($id, $page, $context) { + global $wp_meta_boxes; + + if ( !isset($wp_meta_boxes) ) + $wp_meta_boxes = array(); + if ( !isset($wp_meta_boxes[$page]) ) + $wp_meta_boxes[$page] = array(); + if ( !isset($wp_meta_boxes[$page][$context]) ) + $wp_meta_boxes[$page][$context] = array(); + + foreach ( array('high', 'core', 'default', 'low') as $priority ) + $wp_meta_boxes[$page][$context][$priority][$id] = false; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @param unknown_type $screen + */ +function meta_box_prefs($screen) { + global $wp_meta_boxes; + + if ( is_string($screen) ) + $screen = convert_to_screen($screen); + + if ( empty($wp_meta_boxes[$screen->id]) ) + return; + + $hidden = get_hidden_meta_boxes($screen); + + foreach ( array_keys($wp_meta_boxes[$screen->id]) as $context ) { + foreach ( array_keys($wp_meta_boxes[$screen->id][$context]) as $priority ) { + foreach ( $wp_meta_boxes[$screen->id][$context][$priority] as $box ) { + if ( false == $box || ! $box['title'] ) + continue; + // Submit box cannot be hidden + if ( 'submitdiv' == $box['id'] || 'linksubmitdiv' == $box['id'] ) + continue; + $box_id = $box['id']; + echo '\n"; + } + } + } +} + +/** + * Get Hidden Meta Boxes + * + * @since 2.7.0 + * + * @param string|object $screen Screen identifier + * @return array Hidden Meta Boxes + */ +function get_hidden_meta_boxes( $screen ) { + if ( is_string( $screen ) ) + $screen = convert_to_screen( $screen ); + + $hidden = get_user_option( "metaboxhidden_{$screen->id}" ); + + // Hide slug boxes by default + if ( !is_array( $hidden ) ) { + if ( 'post' == $screen->base || 'page' == $screen->base ) + $hidden = array('slugdiv', 'trackbacksdiv', 'postcustom', 'postexcerpt', 'commentstatusdiv', 'commentsdiv', 'authordiv', 'revisionsdiv'); + else + $hidden = array( 'slugdiv' ); + $hidden = apply_filters('default_hidden_meta_boxes', $hidden, $screen); + } + + return $hidden; +} + +/** + * Add a new section to a settings page. + * + * Part of the Settings API. Use this to define new settings sections for an admin page. + * Show settings sections in your admin page callback function with do_settings_sections(). + * Add settings fields to your section with add_settings_field() + * + * The $callback argument should be the name of a function that echoes out any + * content you want to show at the top of the settings section before the actual + * fields. It can output nothing if you want. + * + * @since 2.7.0 + * + * @global $wp_settings_sections Storage array of all settings sections added to admin pages + * + * @param string $id Slug-name to identify the section. Used in the 'id' attribute of tags. + * @param string $title Formatted title of the section. Shown as the heading for the section. + * @param string $callback Function that echos out any content at the top of the section (between heading and fields). + * @param string $page The slug-name of the settings page on which to show the section. Built-in pages include 'general', 'reading', 'writing', 'discussion', 'media', etc. Create your own using add_options_page(); + */ +function add_settings_section($id, $title, $callback, $page) { + global $wp_settings_sections; + + if ( 'misc' == $page ) { + _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) ); + $page = 'general'; + } + + if ( !isset($wp_settings_sections) ) + $wp_settings_sections = array(); + if ( !isset($wp_settings_sections[$page]) ) + $wp_settings_sections[$page] = array(); + if ( !isset($wp_settings_sections[$page][$id]) ) + $wp_settings_sections[$page][$id] = array(); + + $wp_settings_sections[$page][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback); +} + +/** + * Add a new field to a section of a settings page + * + * Part of the Settings API. Use this to define a settings field that will show + * as part of a settings section inside a settings page. The fields are shown using + * do_settings_fields() in do_settings-sections() + * + * The $callback argument should be the name of a function that echoes out the + * html input tags for this setting field. Use get_option() to retrive existing + * values to show. + * + * @since 2.7.0 + * + * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections + * + * @param string $id Slug-name to identify the field. Used in the 'id' attribute of tags. + * @param string $title Formatted title of the field. Shown as the label for the field during output. + * @param string $callback Function that fills the field with the desired form inputs. The function should echo its output. + * @param string $page The slug-name of the settings page on which to show the section (general, reading, writing, ...). + * @param string $section The slug-name of the section of the settingss page in which to show the box (default, ...). + * @param array $args Additional arguments + */ +function add_settings_field($id, $title, $callback, $page, $section = 'default', $args = array()) { + global $wp_settings_fields; + + if ( 'misc' == $page ) { + _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) ); + $page = 'general'; + } + + if ( !isset($wp_settings_fields) ) + $wp_settings_fields = array(); + if ( !isset($wp_settings_fields[$page]) ) + $wp_settings_fields[$page] = array(); + if ( !isset($wp_settings_fields[$page][$section]) ) + $wp_settings_fields[$page][$section] = array(); + + $wp_settings_fields[$page][$section][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $args); +} + +/** + * Prints out all settings sections added to a particular settings page + * + * Part of the Settings API. Use this in a settings page callback function + * to output all the sections and fields that were added to that $page with + * add_settings_section() and add_settings_field() + * + * @global $wp_settings_sections Storage array of all settings sections added to admin pages + * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections + * @since 2.7.0 + * + * @param string $page The slug name of the page whos settings sections you want to output + */ +function do_settings_sections($page) { + global $wp_settings_sections, $wp_settings_fields; + + if ( !isset($wp_settings_sections) || !isset($wp_settings_sections[$page]) ) + return; + + foreach ( (array) $wp_settings_sections[$page] as $section ) { + echo "

    {$section['title']}

    \n"; + call_user_func($section['callback'], $section); + if ( !isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section['id']]) ) + continue; + echo ''; + do_settings_fields($page, $section['id']); + echo '
    '; + } +} + +/** + * Print out the settings fields for a particular settings section + * + * Part of the Settings API. Use this in a settings page to output + * a specific section. Should normally be called by do_settings_sections() + * rather than directly. + * + * @global $wp_settings_fields Storage array of settings fields and their pages/sections + * + * @since 2.7.0 + * + * @param string $page Slug title of the admin page who's settings fields you want to show. + * @param section $section Slug title of the settings section who's fields you want to show. + */ +function do_settings_fields($page, $section) { + global $wp_settings_fields; + + if ( !isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section]) ) + return; + + foreach ( (array) $wp_settings_fields[$page][$section] as $field ) { + echo ''; + if ( !empty($field['args']['label_for']) ) + echo ''; + else + echo '' . $field['title'] . ''; + echo ''; + call_user_func($field['callback'], $field['args']); + echo ''; + echo ''; + } +} + +/** + * Register a settings error to be displayed to the user + * + * Part of the Settings API. Use this to show messages to users about settings validation + * problems, missing settings or anything else. + * + * Settings errors should be added inside the $sanitize_callback function defined in + * register_setting() for a given setting to give feedback about the submission. + * + * By default messages will show immediately after the submission that generated the error. + * Additional calls to settings_errors() can be used to show errors even when the settings + * page is first accessed. + * + * @since 3.0.0 + * + * @global array $wp_settings_errors Storage array of errors registered during this pageload + * + * @param string $setting Slug title of the setting to which this error applies + * @param string $code Slug-name to identify the error. Used as part of 'id' attribute in HTML output. + * @param string $message The formatted message text to display to the user (will be shown inside styled
    and

    ) + * @param string $type The type of message it is, controls HTML class. Use 'error' or 'updated'. + */ +function add_settings_error( $setting, $code, $message, $type = 'error' ) { + global $wp_settings_errors; + + if ( !isset($wp_settings_errors) ) + $wp_settings_errors = array(); + + $new_error = array( + 'setting' => $setting, + 'code' => $code, + 'message' => $message, + 'type' => $type + ); + $wp_settings_errors[] = $new_error; +} + +/** + * Fetch settings errors registered by add_settings_error() + * + * Checks the $wp_settings_errors array for any errors declared during the current + * pageload and returns them. + * + * If changes were just submitted ($_GET['settings-updated']) and settings errors were saved + * to the 'settings_errors' transient then those errors will be returned instead. This + * is used to pass errors back across pageloads. + * + * Use the $sanitize argument to manually re-sanitize the option before returning errors. + * This is useful if you have errors or notices you want to show even when the user + * hasn't submitted data (i.e. when they first load an options page, or in admin_notices action hook) + * + * @since 3.0.0 + * + * @global array $wp_settings_errors Storage array of errors registered during this pageload + * + * @param string $setting Optional slug title of a specific setting who's errors you want. + * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors. + * @return array Array of settings errors + */ +function get_settings_errors( $setting = '', $sanitize = FALSE ) { + global $wp_settings_errors; + + // If $sanitize is true, manually re-run the sanitizisation for this option + // This allows the $sanitize_callback from register_setting() to run, adding + // any settings errors you want to show by default. + if ( $sanitize ) + sanitize_option( $setting, get_option($setting)); + + // If settings were passed back from options.php then use them + // Ignore transients if $sanitize is true, we dont' want the old values anyway + if ( isset($_GET['settings-updated']) && $_GET['settings-updated'] && get_transient('settings_errors') ) { + $settings_errors = get_transient('settings_errors'); + delete_transient('settings_errors'); + // Otherwise check global in case validation has been run on this pageload + } elseif ( count( $wp_settings_errors ) ) { + $settings_errors = $wp_settings_errors; + } else { + return; + } + + // Filter the results to those of a specific setting if one was set + if ( $setting ) { + foreach ( (array) $settings_errors as $key => $details ) + if ( $setting != $details['setting'] ) + unset( $settings_errors[$key] ); + } + return $settings_errors; +} + +/** + * Display settings errors registered by add_settings_error() + * + * Part of the Settings API. Outputs a

    for each error retrieved by get_settings_errors(). + * + * This is called automatically after a settings page based on the Settings API is submitted. + * Errors should be added during the validation callback function for a setting defined in register_setting() + * + * The $sanitize option is passed into get_settings_errors() and will re-run the setting sanitization + * on its current value. + * + * The $hide_on_update option will cause errors to only show when the settings page is first loaded. + * if the user has already saved new values it will be hidden to avoid repeating messages already + * shown in the default error reporting after submission. This is useful to show general errors like missing + * settings when the user arrives at the settings page. + * + * @since 3.0.0 + * + * @param string $setting Optional slug title of a specific setting who's errors you want. + * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors. + * @param boolean $hide_on_update If set to true errors will not be shown if the settings page has already been submitted. + */ +function settings_errors( $setting = '', $sanitize = FALSE, $hide_on_update = FALSE ) { + + if ($hide_on_update AND $_GET['settings-updated']) return; + + $settings_errors = get_settings_errors( $setting, $sanitize ); + + if ( !is_array($settings_errors) ) return; + + $output = ''; + foreach ( $settings_errors as $key => $details ) { + $css_id = 'setting-error-' . $details['code']; + $css_class = $details['type'] . ' settings-error'; + $output .= "
    \n"; + $output .= "

    {$details['message']}

    "; + $output .= "
    \n"; + } + echo $output; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + * + * @param unknown_type $found_action + */ +function find_posts_div($found_action = '') { +?> + +post_password ) ) echo esc_attr( $post->post_password ); +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.7.0 + */ +function favorite_actions( $screen = null ) { + $default_action = false; + + if ( is_string($screen) ) + $screen = convert_to_screen($screen); + + if ( $screen->is_user ) + return; + + if ( isset($screen->post_type) ) { + $post_type_object = get_post_type_object($screen->post_type); + if ( 'add' != $screen->action ) + $default_action = array('post-new.php?post_type=' . $post_type_object->name => array($post_type_object->labels->new_item, $post_type_object->cap->edit_posts)); + else + $default_action = array('edit.php?post_type=' . $post_type_object->name => array($post_type_object->labels->name, $post_type_object->cap->edit_posts)); + } + + if ( !$default_action ) { + if ( $screen->is_network ) { + $default_action = array('sites.php' => array( __('Sites'), 'manage_sites')); + } else { + switch ( $screen->id ) { + case 'upload': + $default_action = array('media-new.php' => array(__('New Media'), 'upload_files')); + break; + case 'media': + $default_action = array('upload.php' => array(__('Edit Media'), 'upload_files')); + break; + case 'link-manager': + case 'link': + if ( 'add' != $screen->action ) + $default_action = array('link-add.php' => array(__('New Link'), 'manage_links')); + else + $default_action = array('link-manager.php' => array(__('Edit Links'), 'manage_links')); + break; + case 'users': + $default_action = array('user-new.php' => array(__('New User'), 'create_users')); + break; + case 'user': + $default_action = array('users.php' => array(__('Edit Users'), 'edit_users')); + break; + case 'plugins': + $default_action = array('plugin-install.php' => array(__('Install Plugins'), 'install_plugins')); + break; + case 'plugin-install': + $default_action = array('plugins.php' => array(__('Manage Plugins'), 'activate_plugins')); + break; + case 'themes': + $default_action = array('theme-install.php' => array(__('Install Themes'), 'install_themes')); + break; + case 'theme-install': + $default_action = array('themes.php' => array(__('Manage Themes'), 'switch_themes')); + break; + default: + $default_action = array('post-new.php' => array(__('New Post'), 'edit_posts')); + break; + } + } + } + + if ( !$screen->is_network ) { + $actions = array( + 'post-new.php' => array(__('New Post'), 'edit_posts'), + 'edit.php?post_status=draft' => array(__('Drafts'), 'edit_posts'), + 'post-new.php?post_type=page' => array(__('New Page'), 'edit_pages'), + 'media-new.php' => array(__('Upload'), 'upload_files'), + 'edit-comments.php' => array(__('Comments'), 'moderate_comments') + ); + } else { + $actions = array( + 'sites.php' => array( __('Sites'), 'manage_sites'), + 'users.php' => array( __('Users'), 'manage_network_users') + ); + } + + $default_key = array_keys($default_action); + $default_key = $default_key[0]; + if ( isset($actions[$default_key]) ) + unset($actions[$default_key]); + $actions = array_merge($default_action, $actions); + $actions = apply_filters( 'favorite_actions', $actions, $screen ); + + $allowed_actions = array(); + foreach ( $actions as $action => $data ) { + if ( current_user_can($data[1]) ) + $allowed_actions[$action] = $data[0]; + } + + if ( empty($allowed_actions) ) + return; + + $first = array_keys($allowed_actions); + $first = $first[0]; + echo '
    '; + echo '

    '; + echo '
    '; + + array_shift($allowed_actions); + + foreach ( $allowed_actions as $action => $label) { + echo "\n"; + } + echo "
    \n"; +} + +/** + * Get the post title. + * + * The post title is fetched and if it is blank then a default string is + * returned. + * + * @since 2.7.0 + * @param int $post_id The post id. If not supplied the global $post is used. + * @return string The post title if set + */ +function _draft_or_post_title( $post_id = 0 ) { + $title = get_the_title($post_id); + if ( empty($title) ) + $title = __('(no title)'); + return $title; +} + +/** + * Display the search query. + * + * A simple wrapper to display the "s" parameter in a GET URI. This function + * should only be used when {@link the_search_query()} cannot. + * + * @uses attr + * @since 2.7.0 + * + */ +function _admin_search_query() { + echo isset($_REQUEST['s']) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : ''; +} + +/** + * Generic Iframe header for use with Thickbox + * + * @since 2.7.0 + * @param string $title Title of the Iframe page. + * @param bool $limit_styles Limit styles to colour-related styles only (unless others are enqueued). + * + */ +function iframe_header( $title = '', $limit_styles = false ) { + show_admin_bar( false ); + global $hook_suffix, $current_screen, $current_user, $admin_body_class, $wp_locale; + $admin_body_class = preg_replace('/[^a-z0-9_-]+/i', '-', $hook_suffix); + $admin_body_class .= ' iframe'; + +?> + > + + +<?php bloginfo('name') ?> › <?php echo $title ?> — <?php _e('WordPress'); ?> + + + + + class="no-js "> + + + + + + +post_password) ) + $post_states[] = __('Password protected'); + if ( 'private' == $post->post_status && 'private' != $post_status ) + $post_states[] = __('Private'); + if ( 'draft' == $post->post_status && 'draft' != $post_status ) + $post_states[] = __('Draft'); + if ( 'pending' == $post->post_status && 'pending' != $post_status ) + /* translators: post state */ + $post_states[] = _x('Pending', 'post state'); + if ( is_sticky($post->ID) ) + $post_states[] = __('Sticky'); + + $post_states = apply_filters( 'display_post_states', $post_states ); + + if ( ! empty($post_states) ) { + $state_count = count($post_states); + $i = 0; + echo ' - '; + foreach ( $post_states as $state ) { + ++$i; + ( $i == $state_count ) ? $sep = '' : $sep = ', '; + echo "$state$sep"; + } + } + + if ( get_post_format( $post->ID ) ) + echo ' - ' . get_post_format_string( get_post_format( $post->ID ) ) . ''; +} + +/** + * Convert a screen string to a screen object + * + * @since 3.0.0 + * + * @param string $screen The name of the screen + * @return object An object containing the safe screen name and id + */ +function convert_to_screen( $screen ) { + $screen = str_replace( array('.php', '-new', '-add', '-network', '-user' ), '', $screen); + + if ( is_network_admin() ) + $screen .= '-network'; + elseif ( is_user_admin() ) + $screen .= '-user'; + + $screen = (string) apply_filters( 'screen_meta_screen', $screen ); + $screen = (object) array('id' => $screen, 'base' => $screen); + return $screen; +} + +function screen_meta($screen) { + global $wp_meta_boxes, $_wp_contextual_help, $wp_list_table, $wp_current_screen_options; + + if ( is_string($screen) ) + $screen = convert_to_screen($screen); + + $columns = get_column_headers( $screen ); + $hidden = get_hidden_columns( $screen ); + + $meta_screens = array('index' => 'dashboard'); + + if ( isset($meta_screens[$screen->id]) ) { + $screen->id = $meta_screens[$screen->id]; + $screen->base = $screen->id; + } + + $show_screen = false; + if ( !empty($wp_meta_boxes[$screen->id]) || !empty($columns) ) + $show_screen = true; + + $screen_options = screen_options($screen); + if ( $screen_options ) + $show_screen = true; + + if ( !isset($_wp_contextual_help) ) + $_wp_contextual_help = array(); + + $settings = apply_filters('screen_settings', '', $screen); + + switch ( $screen->id ) { + case 'widgets': + $settings = '

    ' . __('Enable accessibility mode') . '' . __('Disable accessibility mode') . "

    \n"; + $show_screen = true; + break; + } + if ( ! empty( $settings ) ) + $show_screen = true; + + if ( !empty($wp_current_screen_options) ) + $show_screen = true; + +?> +
    + + + + + + + +
    +id] = $help; +} + +function screen_layout($screen) { + global $screen_layout_columns, $wp_current_screen_options; + + if ( is_string($screen) ) + $screen = convert_to_screen($screen); + + // Back compat for plugins using the filter instead of add_screen_option() + $columns = apply_filters('screen_layout_columns', array(), $screen->id, $screen); + if ( !empty($columns) && isset($columns[$screen->id]) ) + add_screen_option('layout_columns', array('max' => $columns[$screen->id]) ); + + if ( !isset($wp_current_screen_options['layout_columns']) ) { + $screen_layout_columns = 0; + return ''; + } + + $screen_layout_columns = get_user_option("screen_layout_$screen->id"); + $num = $wp_current_screen_options['layout_columns']['max']; + + if ( ! $screen_layout_columns ) { + if ( isset($wp_current_screen_options['layout_columns']['default']) ) + $screen_layout_columns = $wp_current_screen_options['layout_columns']['default']; + else + $screen_layout_columns = 2; + } + + $i = 1; + $return = '
    ' . __('Screen Layout') . "
    \n
    " . __('Number of Columns:') . "\n"; + while ( $i <= $num ) { + $return .= "\n"; + ++$i; + } + $return .= "
    \n"; + return $return; +} + +/** + * Register and configure an admin screen option + * + * @since 3.1.0 + * + * @param string $option An option name. + * @param mixed $args Option dependent arguments + * @return void + */ +function add_screen_option( $option, $args = array() ) { + global $wp_current_screen_options; + + if ( !isset($wp_current_screen_options) ) + $wp_current_screen_options = array(); + + $wp_current_screen_options[$option] = $args; +} + +function screen_options($screen) { + global $wp_current_screen_options; + + if ( is_string($screen) ) + $screen = convert_to_screen($screen); + + if ( !isset($wp_current_screen_options['per_page']) ) + return ''; + + $per_page_label = $wp_current_screen_options['per_page']['label']; + + if ( empty($wp_current_screen_options['per_page']['option']) ) { + $option = str_replace( '-', '_', "{$screen->id}_per_page" ); + } else { + $option = $wp_current_screen_options['per_page']['option']; + } + + $per_page = (int) get_user_option( $option ); + if ( empty( $per_page ) || $per_page < 1 ) { + if ( isset($wp_current_screen_options['per_page']['default']) ) + $per_page = $wp_current_screen_options['per_page']['default']; + else + $per_page = 20; + } + + if ( 'edit_comments_per_page' == $option ) + $per_page = apply_filters( 'comments_per_page', $per_page, isset($_REQUEST['comment_status']) ? $_REQUEST['comment_status'] : 'all' ); + elseif ( 'categories_per_page' == $option ) + $per_page = apply_filters( 'edit_categories_per_page', $per_page ); + else + $per_page = apply_filters( $option, $per_page ); + + // Back compat + if ( isset( $screen->post_type ) ) + $per_page = apply_filters( 'edit_posts_per_page', $per_page, $screen->post_type ); + + $return = "
    \n"; + if ( !empty($per_page_label) ) + $return .= " \n"; + $return .= get_submit_button( __( 'Apply' ), 'button', 'screen-options-apply', false ); + $return .= ""; + $return .= "
    \n"; + return $return; +} + +function screen_icon($screen = '') { + global $current_screen, $typenow; + + if ( empty($screen) ) + $screen = $current_screen; + elseif ( is_string($screen) ) + $name = $screen; + + $class = 'icon32'; + + if ( empty($name) ) { + if ( !empty($screen->parent_base) ) + $name = $screen->parent_base; + else + $name = $screen->base; + + if ( 'edit' == $name && isset($screen->post_type) && 'page' == $screen->post_type ) + $name = 'edit-pages'; + + $post_type = ''; + if ( isset( $screen->post_type ) ) + $post_type = $screen->post_type; + elseif ( $current_screen == $screen ) + $post_type = $typenow; + if ( $post_type ) + $class .= ' ' . sanitize_html_class( 'icon32-posts-' . $post_type ); + } + +?> +

    + + + $current_screen, 'base' => $current_screen); + } else { + $id = sanitize_key($id); + if ( false !== strpos($id, '-') ) { + list( $id, $typenow ) = explode('-', $id, 2); + if ( taxonomy_exists( $typenow ) ) { + $id = 'edit-tags'; + $taxnow = $typenow; + $typenow = ''; + } + } + $current_screen = array('id' => $id, 'base' => $id); + } + + $current_screen = (object) $current_screen; + + $current_screen->action = $action; + + // Map index to dashboard + if ( 'index' == $current_screen->base ) + $current_screen->base = 'dashboard'; + if ( 'index' == $current_screen->id ) + $current_screen->id = 'dashboard'; + + if ( 'edit' == $current_screen->id ) { + if ( empty($typenow) ) + $typenow = 'post'; + $current_screen->id .= '-' . $typenow; + $current_screen->post_type = $typenow; + } elseif ( 'post' == $current_screen->id ) { + if ( empty($typenow) ) + $typenow = 'post'; + $current_screen->id = $typenow; + $current_screen->post_type = $typenow; + } elseif ( 'edit-tags' == $current_screen->id ) { + if ( empty($taxnow) ) + $taxnow = 'post_tag'; + $current_screen->id = 'edit-' . $taxnow; + $current_screen->taxonomy = $taxnow; + } + + $current_screen->is_network = is_network_admin(); + $current_screen->is_user = is_user_admin(); + + if ( $current_screen->is_network ) { + $current_screen->base .= '-network'; + $current_screen->id .= '-network'; + } elseif ( $current_screen->is_user ) { + $current_screen->base .= '-user'; + $current_screen->id .= '-user'; + } + + $current_screen = apply_filters('current_screen', $current_screen); +} + +/** + * Echos a submit button, with provided text and appropriate class + * + * @since 3.1.0 + * + * @param string $text The text of the button (defaults to 'Save Changes') + * @param string $type The type of button. One of: primary, secondary, delete + * @param string $name The HTML name of the submit button. Defaults to "submit". If no id attribute + * is given in $other_attributes below, $name will be used as the button's id. + * @param bool $wrap True if the output button should be wrapped in a paragraph tag, + * false otherwise. Defaults to true + * @param array|string $other_attributes Other attributes that should be output with the button, + * mapping attributes to their values, such as array( 'tabindex' => '1' ). + * These attributes will be ouput as attribute="value", such as tabindex="1". + * Defaults to no other attributes. Other attributes can also be provided as a + * string such as 'tabindex="1"', though the array format is typically cleaner. + */ +function submit_button( $text = NULL, $type = 'primary', $name = 'submit', $wrap = true, $other_attributes = NULL ) { + echo get_submit_button( $text, $type, $name, $wrap, $other_attributes ); +} + +/** + * Returns a submit button, with provided text and appropriate class + * + * @since 3.1.0 + * + * @param string $text The text of the button (defaults to 'Save Changes') + * @param string $type The type of button. One of: primary, secondary, delete + * @param string $name The HTML name of the submit button. Defaults to "submit". If no id attribute + * is given in $other_attributes below, $name will be used as the button's id. + * @param bool $wrap True if the output button should be wrapped in a paragraph tag, + * false otherwise. Defaults to true + * @param array|string $other_attributes Other attributes that should be output with the button, + * mapping attributes to their values, such as array( 'tabindex' => '1' ). + * These attributes will be ouput as attribute="value", such as tabindex="1". + * Defaults to no other attributes. Other attributes can also be provided as a + * string such as 'tabindex="1"', though the array format is typically cleaner. + */ +function get_submit_button( $text = NULL, $type = 'primary', $name = 'submit', $wrap = true, $other_attributes = NULL ) { + switch ( $type ) : + case 'primary' : + case 'secondary' : + $class = 'button-' . $type; + break; + case 'delete' : + $class = 'button-secondary delete'; + break; + default : + $class = $type; // Custom cases can just pass in the classes they want to be used + endswitch; + $text = ( NULL == $text ) ? __( 'Save Changes' ) : $text; + + // Default the id attribute to $name unless an id was specifically provided in $other_attributes + $id = $name; + if ( is_array( $other_attributes ) && isset( $other_attributes['id'] ) ) { + $id = $other_attributes['id']; + unset( $other_attributes['id'] ); + } + + $attributes = ''; + if ( is_array( $other_attributes ) ) { + foreach ( $other_attributes as $attribute => $value ) { + $attributes .= $attribute . '="' . esc_attr( $value ) . '" '; // Trailing space is important + } + } else if ( !empty( $other_attributes ) ) { // Attributes provided as a string + $attributes = $other_attributes; + } + + $button = ''; + + if ( $wrap ) { + $button = '

    ' . $button . '

    '; + } + + return $button; +} + diff --git a/src/wp-admin/includes/theme-install.php b/src/wp-admin/includes/theme-install.php new file mode 100644 index 00000000..da7c069e --- /dev/null +++ b/src/wp-admin/includes/theme-install.php @@ -0,0 +1,323 @@ + array('href' => array(), 'title' => array(), 'target' => array()), + 'abbr' => array('title' => array()), 'acronym' => array('title' => array()), + 'code' => array(), 'pre' => array(), 'em' => array(), 'strong' => array(), + 'div' => array(), 'p' => array(), 'ul' => array(), 'ol' => array(), 'li' => array(), + 'h1' => array(), 'h2' => array(), 'h3' => array(), 'h4' => array(), 'h5' => array(), 'h6' => array(), + 'img' => array('src' => array(), 'class' => array(), 'alt' => array()) +); + +$theme_field_defaults = array( 'description' => true, 'sections' => false, 'tested' => true, 'requires' => true, + 'rating' => true, 'downloaded' => true, 'downloadlink' => true, 'last_updated' => true, 'homepage' => true, + 'tags' => true, 'num_ratings' => true +); + +/** + * Retrieve list of WordPress theme features (aka theme tags) + * + * @since 2.8.0 + * + * @deprecated since 3.1.0 Use get_theme_feature_list() instead. + * + * @return array + */ +function install_themes_feature_list( ) { + if ( !$cache = get_transient( 'wporg_theme_feature_list' ) ) + set_transient( 'wporg_theme_feature_list', array( ), 10800); + + if ( $cache ) + return $cache; + + $feature_list = themes_api( 'feature_list', array( ) ); + if ( is_wp_error( $feature_list ) ) + return $features; + + set_transient( 'wporg_theme_feature_list', $feature_list, 10800 ); + + return $feature_list; +} + +/** + * Display search form for searching themes. + * + * @since 2.8.0 + */ +function install_theme_search_form() { + $type = isset( $_REQUEST['type'] ) ? stripslashes( $_REQUEST['type'] ) : ''; + $term = isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : ''; + ?> +

    + +
    + + + + +
    + +

    +
    +

    + '; + + foreach ( (array) $feature_list as $feature_name => $features ) { + $feature_name = esc_html( $feature_name ); + echo '
    ' . $feature_name . '
    '; + + echo '
      '; + foreach ( $features as $feature => $feature_name ) { + $feature_name = esc_html( $feature_name ); + $feature = esc_attr($feature); +?> + +
    1. + + +
    2. + + +
    +
    + + +
    +
    + + + +

    +

    +
    + + + +
    + name, $themes_allowedtags); + $desc = wp_kses($theme->description, $themes_allowedtags); + //if ( strlen($desc) > 30 ) + // $desc = substr($desc, 0, 15) . '...' . substr($desc, -15) . ''; + + $preview_link = $theme->preview_url . '?TB_iframe=true&width=600&height=400'; + if ( !is_array($actions) ) { + $actions = array(); + $actions[] = '' . __('Install') . ''; + if ( !is_network_admin() ) + $actions[] = '' . __('Preview') . ''; + $actions = apply_filters('theme_install_action_links', $actions, $theme); + } + + $actions = implode ( ' | ', $actions ); + ?> +'> + + +

    + +

    + + +
    +

    version, $themes_allowedtags) ?>

    +

    author, $themes_allowedtags) ?>

    +last_updated) ) : ?> +

    last_updated)) ) ?>

    +requires) ) : ?> +

    requires) ?>

    +tested) ) : ?> +

    tested ?>

    +downloaded) ) : ?> +

    downloaded), number_format_i18n($theme->downloaded)) ?>

    + +
    +
    +
    <?php _e('5 stars') ?>
    +
    <?php _e('4 stars') ?>
    +
    <?php _e('3 stars') ?>
    +
    <?php _e('2 stars') ?>
    +
    <?php _e('1 star') ?>
    +
    +
    + string 'Magazine Basic' (length=14) + public 'slug' => string 'magazine-basic' (length=14) + public 'version' => string '1.1' (length=3) + public 'author' => string 'tinkerpriest' (length=12) + public 'preview_url' => string 'http://wp-themes.com/?magazine-basic' (length=36) + public 'screenshot_url' => string 'http://wp-themes.com/wp-content/themes/magazine-basic/screenshot.png' (length=68) + public 'rating' => float 80 + public 'num_ratings' => int 1 + public 'homepage' => string 'http://wordpress.org/extend/themes/magazine-basic' (length=49) + public 'description' => string 'A basic magazine style layout with a fully customizable layout through a backend interface. Designed by c.bavota of Tinker Priest Media.' (length=214) + public 'download_link' => string 'http://wordpress.org/extend/themes/download/magazine-basic.1.1.zip' (length=66) + */ +} + +/** + * Display theme content based on theme list. + * + * @since 2.8.0 + */ +function display_themes() { + global $wp_list_table; + + $wp_list_table->display(); +} +add_action('install_themes_search', 'display_themes'); +add_action('install_themes_featured', 'display_themes'); +add_action('install_themes_new', 'display_themes'); +add_action('install_themes_updated', 'display_themes'); + +/** + * Display theme information in dialog box form. + * + * @since 2.8.0 + */ +function install_theme_information() { + //TODO: This function needs a LOT of UI work :) + global $tab, $themes_allowedtags; + + $api = themes_api('theme_information', array('slug' => stripslashes( $_REQUEST['theme'] ) )); + + if ( is_wp_error($api) ) + wp_die($api); + + // Sanitize HTML + foreach ( (array)$api->sections as $section_name => $content ) + $api->sections[$section_name] = wp_kses($content, $themes_allowedtags); + + foreach ( array('version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug') as $key ) { + if ( isset($api->$key) ) + $api->$key = wp_kses($api->$key, $themes_allowedtags); + } + + iframe_header( __('Theme Install') ); + + if ( empty($api->download_link) ) { + echo '

    ' . __('Error: This theme is currently not available. Please try again later.') . '

    '; + iframe_footer(); + exit; + } + + if ( !empty($api->tested) && version_compare($GLOBALS['wp_version'], $api->tested, '>') ) + echo '

    ' . __('Warning: This theme has not been tested with your current version of WordPress.') . '

    '; + else if ( !empty($api->requires) && version_compare($GLOBALS['wp_version'], $api->requires, '<') ) + echo '

    ' . __('Warning: This theme has not been marked as compatible with your version of WordPress.') . '

    '; + + // Default to a "new" theme + $type = 'install'; + // Check to see if this theme is known to be installed, and has an update awaiting it. + $update_themes = get_site_transient('update_themes'); + if ( is_object($update_themes) && isset($update_themes->response) ) { + foreach ( (array)$update_themes->response as $theme_slug => $theme_info ) { + if ( $theme_slug === $api->slug ) { + $type = 'update_available'; + $update_file = $theme_slug; + break; + } + } + } + + $themes = get_themes(); + foreach ( $themes as $this_theme ) { + if ( is_array($this_theme) && $this_theme['Stylesheet'] == $api->slug ) { + if ( $this_theme['Version'] == $api->version ) { + $type = 'latest_installed'; + } elseif ( $this_theme['Version'] > $api->version ) { + $type = 'newer_installed'; + $newer_version = $this_theme['Version']; + } + break; + } + } +?> + +
    + +

    name; ?>

    +

    author); ?>

    +

    version); ?>

    + +' . __('Cancel') . ' '; + +switch ( $type ) { +default: +case 'install': + if ( current_user_can('install_themes') ) : + $buttons .= '' . __('Install Now') . ''; + endif; + break; +case 'update_available': + if ( current_user_can('update_themes') ) : + $buttons .= '' . __('Install Update Now') . ''; + endif; + break; +case 'newer_installed': + if ( current_user_can('install_themes') || current_user_can('update_themes') ) : + ?>

    +
    +
    + +

    + +
    +

    + +name = $current_theme; + $ct->title = $themes[$current_theme]['Title']; + $ct->version = $themes[$current_theme]['Version']; + $ct->parent_theme = $themes[$current_theme]['Parent Theme']; + $ct->template_dir = $themes[$current_theme]['Template Dir']; + $ct->stylesheet_dir = $themes[$current_theme]['Stylesheet Dir']; + $ct->template = $themes[$current_theme]['Template']; + $ct->stylesheet = $themes[$current_theme]['Stylesheet']; + $ct->screenshot = $themes[$current_theme]['Screenshot']; + $ct->description = $themes[$current_theme]['Description']; + $ct->author = $themes[$current_theme]['Author']; + $ct->tags = $themes[$current_theme]['Tags']; + $ct->theme_root = $themes[$current_theme]['Theme Root']; + $ct->theme_root_uri = $themes[$current_theme]['Theme Root URI']; + return $ct; +} + +/** + * Remove a theme + * + * @since 2.8.0 + * + * @param string $template Template directory of the theme to delete + * @param string $redirect Redirect to page when complete. + * @return mixed + */ +function delete_theme($template, $redirect = '') { + global $wp_filesystem; + + if ( empty($template) ) + return false; + + ob_start(); + if ( empty( $redirect ) ) + $redirect = wp_nonce_url('themes.php?action=delete&template=' . $template, 'delete-theme_' . $template); + if ( false === ($credentials = request_filesystem_credentials($redirect)) ) { + $data = ob_get_contents(); + ob_end_clean(); + if ( ! empty($data) ){ + include_once( ABSPATH . 'wp-admin/admin-header.php'); + echo $data; + include( ABSPATH . 'wp-admin/admin-footer.php'); + exit; + } + return; + } + + if ( ! WP_Filesystem($credentials) ) { + request_filesystem_credentials($url, '', true); // Failed to connect, Error and request again + $data = ob_get_contents(); + ob_end_clean(); + if ( ! empty($data) ) { + include_once( ABSPATH . 'wp-admin/admin-header.php'); + echo $data; + include( ABSPATH . 'wp-admin/admin-footer.php'); + exit; + } + return; + } + + + if ( ! is_object($wp_filesystem) ) + return new WP_Error('fs_unavailable', __('Could not access filesystem.')); + + if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() ) + return new WP_Error('fs_error', __('Filesystem error.'), $wp_filesystem->errors); + + //Get the base plugin folder + $themes_dir = $wp_filesystem->wp_themes_dir(); + if ( empty($themes_dir) ) + return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress theme directory.')); + + $themes_dir = trailingslashit( $themes_dir ); + $theme_dir = trailingslashit($themes_dir . $template); + $deleted = $wp_filesystem->delete($theme_dir, true); + + if ( ! $deleted ) + return new WP_Error('could_not_remove_theme', sprintf(__('Could not fully remove the theme %s.'), $template) ); + + // Force refresh of theme update information + delete_site_transient('update_themes'); + + return true; +} + +/** + * {@internal Missing Short Description}} + * + * @since 1.5.0 + * + * @return unknown + */ +function get_broken_themes() { + global $wp_broken_themes; + + get_themes(); + return $wp_broken_themes; +} + +/** + * Get the allowed themes for the current blog. + * + * @since 3.0.0 + * + * @uses get_themes() + * @uses current_theme_info() + * @uses get_site_allowed_themes() + * @uses wpmu_get_blog_allowedthemes + * + * @return array $themes Array of allowed themes. + */ +function get_allowed_themes() { + if ( !is_multisite() ) + return get_themes(); + + $themes = get_themes(); + $ct = current_theme_info(); + $allowed_themes = apply_filters("allowed_themes", get_site_allowed_themes() ); + if ( $allowed_themes == false ) + $allowed_themes = array(); + + $blog_allowed_themes = wpmu_get_blog_allowedthemes(); + if ( is_array( $blog_allowed_themes ) ) + $allowed_themes = array_merge( $allowed_themes, $blog_allowed_themes ); + + if ( isset( $allowed_themes[ esc_html( $ct->stylesheet ) ] ) == false ) + $allowed_themes[ esc_html( $ct->stylesheet ) ] = true; + + reset( $themes ); + foreach ( $themes as $key => $theme ) { + if ( isset( $allowed_themes[ esc_html( $theme[ 'Stylesheet' ] ) ] ) == false ) + unset( $themes[ $key ] ); + } + reset( $themes ); + + return $themes; +} + +/** + * Get the Page Templates available in this theme + * + * @since 1.5.0 + * + * @return array Key is template name, Value is template name + */ +function get_page_templates() { + $themes = get_themes(); + $theme = get_current_theme(); + $templates = $themes[$theme]['Template Files']; + $page_templates = array(); + + if ( is_array( $templates ) ) { + $base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) ); + + foreach ( $templates as $template ) { + $basename = str_replace($base, '', $template); + + // don't allow template files in subdirectories + if ( false !== strpos($basename, '/') ) + continue; + + $template_data = implode( '', file( $template )); + + $name = ''; + if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ) ) + $name = _cleanup_header_comment($name[1]); + + if ( !empty( $name ) ) { + $page_templates[trim( $name )] = $basename; + } + } + } + + return $page_templates; +} + +/** + * Tidies a filename for url display by the theme editor. + * + * @since 2.9.0 + * @access private + * + * @param string $fullpath Full path to the theme file + * @param string $containingfolder Path of the theme parent folder + * @return string + */ +function _get_template_edit_filename($fullpath, $containingfolder) { + return str_replace(dirname(dirname( $containingfolder )) , '', $fullpath); +} + +/** + * Check if there is an update for a theme available. + * + * Will display link, if there is an update available. + * + * @since 2.7.0 + * + * @param object $theme Theme data object. + * @return bool False if no valid info was passed. + */ +function theme_update_available( $theme ) { + static $themes_update; + + if ( !current_user_can('update_themes' ) ) + return; + + if ( !isset($themes_update) ) + $themes_update = get_site_transient('update_themes'); + + if ( is_object($theme) && isset($theme->stylesheet) ) + $stylesheet = $theme->stylesheet; + elseif ( is_array($theme) && isset($theme['Stylesheet']) ) + $stylesheet = $theme['Stylesheet']; + else + return false; //No valid info passed. + + if ( isset($themes_update->response[ $stylesheet ]) ) { + $update = $themes_update->response[ $stylesheet ]; + $theme_name = is_object($theme) ? $theme->name : (is_array($theme) ? $theme['Name'] : ''); + $details_url = add_query_arg(array('TB_iframe' => 'true', 'width' => 1024, 'height' => 800), $update['url']); //Theme browser inside WP? replace this, Also, theme preview JS will override this on the available list. + $update_url = wp_nonce_url('update.php?action=upgrade-theme&theme=' . urlencode($stylesheet), 'upgrade-theme_' . $stylesheet); + $update_onclick = 'onclick="if ( confirm(\'' . esc_js( __("Updating this theme will lose any customizations you have made. 'Cancel' to stop, 'OK' to update.") ) . '\') ) {return true;}return false;"'; + + if ( !is_multisite() ) { + if ( ! current_user_can('update_themes') ) + printf( '

    ' . __('There is a new version of %1$s available. View version %3$s details.') . '

    ', $theme_name, $details_url, $update['new_version']); + else if ( empty($update['package']) ) + printf( '

    ' . __('There is a new version of %1$s available. View version %3$s details. Automatic update is unavailable for this theme.') . '

    ', $theme_name, $details_url, $update['new_version']); + else + printf( '

    ' . __('There is a new version of %1$s available. View version %3$s details or update automatically.') . '

    ', $theme_name, $details_url, $update['new_version'], $update_url, $update_onclick ); + } + } +} + +/** + * Retrieve list of WordPress theme features (aka theme tags) + * + * @since 3.1.0 + * + * @return array Array of features keyed by category with translations keyed by slug. + */ +function get_theme_feature_list() { + // Hard-coded list is used if api not accessible. + $features = array( + __('Colors') => array( + 'black' => __( 'Black' ), + 'blue' => __( 'Blue' ), + 'brown' => __( 'Brown' ), + 'green' => __( 'Green' ), + 'orange' => __( 'Orange' ), + 'pink' => __( 'Pink' ), + 'purple' => __( 'Purple' ), + 'red' => __( 'Red' ), + 'silver' => __( 'Silver' ), + 'tan' => __( 'Tan' ), + 'white' => __( 'White' ), + 'yellow' => __( 'Yellow' ), + 'dark' => __( 'Dark' ), + 'light' => __( 'Light ') + ), + + __('Columns') => array( + 'one-column' => __( 'One Column' ), + 'two-columns' => __( 'Two Columns' ), + 'three-columns' => __( 'Three Columns' ), + 'four-columns' => __( 'Four Columns' ), + 'left-sidebar' => __( 'Left Sidebar' ), + 'right-sidebar' => __( 'Right Sidebar' ) + ), + + __('Width') => array( + 'fixed-width' => __( 'Fixed Width' ), + 'flexible-width' => __( 'Flexible Width' ) + ), + + __( 'Features' ) => array( + 'blavatar' => __( 'Blavatar' ), + 'buddypress' => __( 'BuddyPress' ), + 'custom-background' => __( 'Custom Background' ), + 'custom-colors' => __( 'Custom Colors' ), + 'custom-header' => __( 'Custom Header' ), + 'custom-menu' => __( 'Custom Menu' ), + 'editor-style' => __( 'Editor Style' ), + 'front-page-post-form' => __( 'Front Page Posting' ), + 'microformats' => __( 'Microformats' ), + 'sticky-post' => __( 'Sticky Post' ), + 'theme-options' => __( 'Theme Options' ), + 'threaded-comments' => __( 'Threaded Comments' ), + 'translation-ready' => __( 'Translation Ready' ), + 'rtl-language-support' => __( 'RTL Language Support' ) + ), + + __( 'Subject' ) => array( + 'holiday' => __( 'Holiday' ), + 'photoblogging' => __( 'Photoblogging' ), + 'seasonal' => __( 'Seasonal' ) + ) + ); + + if ( !current_user_can('install_themes') ) + return $features; + + if ( !$feature_list = get_site_transient( 'wporg_theme_feature_list' ) ) + set_site_transient( 'wporg_theme_feature_list', array( ), 10800); + + if ( !$feature_list ) { + $feature_list = themes_api( 'feature_list', array( ) ); + if ( is_wp_error( $feature_list ) ) + return $features; + } + + if ( !$feature_list ) + return $features; + + set_site_transient( 'wporg_theme_feature_list', $feature_list, 10800 ); + + $category_translations = array( 'Colors' => __('Colors'), 'Columns' => __('Columns'), 'Width' => __('Width'), + 'Features' => __('Features'), 'Subject' => __('Subject') ); + + // Loop over the wporg canonical list and apply translations + $wporg_features = array(); + foreach ( (array) $feature_list as $feature_category => $feature_items ) { + if ( isset($category_translations[$feature_category]) ) + $feature_category = $category_translations[$feature_category]; + $wporg_features[$feature_category] = array(); + + foreach ( $feature_items as $feature ) { + if ( isset($features[$feature_category][$feature]) ) + $wporg_features[$feature_category][$feature] = $features[$feature_category][$feature]; + else + $wporg_features[$feature_category][$feature] = $feature; + } + } + + return $wporg_features; +} + +/** + * Retrieve theme installer pages from WordPress Themes API. + * + * It is possible for a theme to override the Themes API result with three + * filters. Assume this is for themes, which can extend on the Theme Info to + * offer more choices. This is very powerful and must be used with care, when + * overridding the filters. + * + * The first filter, 'themes_api_args', is for the args and gives the action as + * the second parameter. The hook for 'themes_api_args' must ensure that an + * object is returned. + * + * The second filter, 'themes_api', is the result that would be returned. + * + * @since 2.8.0 + * + * @param string $action + * @param array|object $args Optional. Arguments to serialize for the Theme Info API. + * @return mixed + */ +function themes_api($action, $args = null) { + + if ( is_array($args) ) + $args = (object)$args; + + if ( !isset($args->per_page) ) + $args->per_page = 24; + + $args = apply_filters('themes_api_args', $args, $action); //NOTE: Ensure that an object is returned via this filter. + $res = apply_filters('themes_api', false, $action, $args); //NOTE: Allows a theme to completely override the builtin WordPress.org API. + + if ( ! $res ) { + $request = wp_remote_post('http://api.wordpress.org/themes/info/1.0/', array( 'body' => array('action' => $action, 'request' => serialize($args))) ); + if ( is_wp_error($request) ) { + $res = new WP_Error('themes_api_failed', __('An Unexpected HTTP Error occurred during the API request.'), $request->get_error_message() ); + } else { + $res = unserialize($request['body']); + if ( ! $res ) + $res = new WP_Error('themes_api_failed', __('An unknown error occurred.'), $request['body']); + } + } + //var_dump(array($args, $res)); + return apply_filters('themes_api_result', $res, $action, $args); +} + +?> diff --git a/src/wp-admin/includes/update-core.php b/src/wp-admin/includes/update-core.php new file mode 100644 index 00000000..0673363b --- /dev/null +++ b/src/wp-admin/includes/update-core.php @@ -0,0 +1,369 @@ +db_version(); + $required_php_version = '4.3'; + $required_mysql_version = '4.1.2'; + $wp_version = '3.1.3'; + $php_compat = version_compare( $php_version, $required_php_version, '>=' ); + $mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' ) || file_exists( WP_CONTENT_DIR . '/db.php' ); + + if ( !$mysql_compat || !$php_compat ) + $wp_filesystem->delete($from, true); + + if ( !$mysql_compat && !$php_compat ) + return new WP_Error( 'php_mysql_not_compatible', sprintf( __('The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.'), $wp_version, $required_php_version, $required_mysql_version, $php_version, $mysql_version ) ); + elseif ( !$php_compat ) + return new WP_Error( 'php_not_compatible', sprintf( __('The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.'), $wp_version, $required_php_version, $php_version ) ); + elseif ( !$mysql_compat ) + return new WP_Error( 'mysql_not_compatible', sprintf( __('The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.'), $wp_version, $required_mysql_version, $mysql_version ) ); + + // Sanity check the unzipped distribution + apply_filters('update_feedback', __('Verifying the unpacked files…')); + $distro = ''; + $roots = array( '/wordpress', '/wordpress-mu' ); + foreach( $roots as $root ) { + if ( $wp_filesystem->exists($from . $root . '/wp-settings.php') && $wp_filesystem->exists($from . $root . '/wp-admin/admin.php') && + $wp_filesystem->exists($from . $root . '/wp-includes/functions.php') ) { + $distro = $root; + break; + } + } + if ( !$distro ) { + $wp_filesystem->delete($from, true); + return new WP_Error('insane_distro', __('The update could not be unpacked') ); + } + + apply_filters('update_feedback', __('Installing the latest version…')); + + // Create maintenance file to signal that we are upgrading + $maintenance_string = ''; + $maintenance_file = $to . '.maintenance'; + $wp_filesystem->delete($maintenance_file); + $wp_filesystem->put_contents($maintenance_file, $maintenance_string, FS_CHMOD_FILE); + + // Copy new versions of WP files into place. + $result = copy_dir($from . $distro, $to); + if ( is_wp_error($result) ) { + $wp_filesystem->delete($maintenance_file); + $wp_filesystem->delete($from, true); + return $result; + } + + // Remove old files + foreach ( $_old_files as $old_file ) { + $old_file = $to . $old_file; + if ( !$wp_filesystem->exists($old_file) ) + continue; + $wp_filesystem->delete($old_file, true); + } + + // Upgrade DB with separate request + apply_filters('update_feedback', __('Upgrading database…')); + $db_upgrade_url = admin_url('upgrade.php?step=upgrade_db'); + wp_remote_post($db_upgrade_url, array('timeout' => 60)); + + // Remove working directory + $wp_filesystem->delete($from, true); + + // Force refresh of update information + if ( function_exists('delete_site_transient') ) + delete_site_transient('update_core'); + else + delete_option('update_core'); + + // Remove maintenance file, we're done. + $wp_filesystem->delete($maintenance_file); +} + +?> diff --git a/src/wp-admin/includes/update.php b/src/wp-admin/includes/update.php new file mode 100644 index 00000000..06e06c24 --- /dev/null +++ b/src/wp-admin/includes/update.php @@ -0,0 +1,312 @@ + 'latest'); + return $updates[0]; +} + +/** + * Get available core updates + * + * @param array $options Set $options['dismissed'] to true to show dismissed upgrades too, + * set $options['available'] to false to skip not-dimissed updates. + * @return array Array of the update objects + */ +function get_core_updates( $options = array() ) { + $options = array_merge( array('available' => true, 'dismissed' => false ), $options ); + $dismissed = get_site_option( 'dismissed_update_core' ); + if ( !is_array( $dismissed ) ) $dismissed = array(); + $from_api = get_site_transient( 'update_core' ); + if ( empty($from_api) ) + return false; + if ( !isset( $from_api->updates ) || !is_array( $from_api->updates ) ) return false; + $updates = $from_api->updates; + if ( !is_array( $updates ) ) return false; + $result = array(); + foreach($updates as $update) { + if ( array_key_exists( $update->current.'|'.$update->locale, $dismissed ) ) { + if ( $options['dismissed'] ) { + $update->dismissed = true; + $result[]= $update; + } + } else { + if ( $options['available'] ) { + $update->dismissed = false; + $result[]= $update; + } + } + } + return $result; +} + +function dismiss_core_update( $update ) { + $dismissed = get_site_option( 'dismissed_update_core' ); + $dismissed[ $update->current.'|'.$update->locale ] = true; + return update_site_option( 'dismissed_update_core', $dismissed ); +} + +function undismiss_core_update( $version, $locale ) { + $dismissed = get_site_option( 'dismissed_update_core' ); + $key = $version.'|'.$locale; + if ( !isset( $dismissed[$key] ) ) return false; + unset( $dismissed[$key] ); + return update_site_option( 'dismissed_update_core', $dismissed ); +} + +function find_core_update( $version, $locale ) { + $from_api = get_site_transient( 'update_core' ); + if ( !is_array( $from_api->updates ) ) return false; + $updates = $from_api->updates; + foreach($updates as $update) { + if ( $update->current == $version && $update->locale == $locale ) + return $update; + } + return false; +} + +function core_update_footer( $msg = '' ) { + if ( is_multisite() && !current_user_can('update_core') ) + return false; + + if ( !current_user_can('update_core') ) + return sprintf( __( 'Version %s' ), $GLOBALS['wp_version'] ); + + $cur = get_preferred_from_update_core(); + if ( ! isset( $cur->current ) ) + $cur->current = ''; + + if ( ! isset( $cur->url ) ) + $cur->url = ''; + + if ( ! isset( $cur->response ) ) + $cur->response = ''; + + switch ( $cur->response ) { + case 'development' : + return sprintf( __( 'You are using a development version (%1$s). Cool! Please stay updated.' ), $GLOBALS['wp_version'], network_admin_url( 'update-core.php' ) ); + break; + + case 'upgrade' : + return sprintf( ''.__( 'Get Version %2$s' ).'', network_admin_url( 'update-core.php' ), $cur->current); + break; + + case 'latest' : + default : + return sprintf( __( 'Version %s' ), $GLOBALS['wp_version'] ); + break; + } +} +add_filter( 'update_footer', 'core_update_footer' ); + +function update_nag() { + if ( is_multisite() && !current_user_can('update_core') ) + return false; + + global $pagenow; + + if ( 'update-core.php' == $pagenow ) + return; + + $cur = get_preferred_from_update_core(); + + if ( ! isset( $cur->response ) || $cur->response != 'upgrade' ) + return false; + + if ( current_user_can('update_core') ) { + $msg = sprintf( __('WordPress %1$s is available! Please update now.'), $cur->current, network_admin_url( 'update-core.php' ) ); + } else { + $msg = sprintf( __('WordPress %1$s is available! Please notify the site administrator.'), $cur->current ); + } + echo "
    $msg
    "; +} +add_action( 'admin_notices', 'update_nag', 3 ); + +// Called directly from dashboard +function update_right_now_message() { + if ( is_multisite() && !current_user_can('update_core') ) + return false; + + $cur = get_preferred_from_update_core(); + + $msg = sprintf( __('You are using WordPress %s.'), $GLOBALS['wp_version'] ); + + if ( isset( $cur->response ) && $cur->response == 'upgrade' && current_user_can('update_core') ) { + $msg .= " " . sprintf( __('Update to %s'), $cur->current ? $cur->current : __( 'Latest' ) ) . ''; + } + + echo "$msg"; +} + +function get_plugin_updates() { + $all_plugins = get_plugins(); + $upgrade_plugins = array(); + $current = get_site_transient( 'update_plugins' ); + foreach ( (array)$all_plugins as $plugin_file => $plugin_data) { + if ( isset( $current->response[ $plugin_file ] ) ) { + $upgrade_plugins[ $plugin_file ] = (object) $plugin_data; + $upgrade_plugins[ $plugin_file ]->update = $current->response[ $plugin_file ]; + } + } + + return $upgrade_plugins; +} + +function wp_plugin_update_rows() { + if ( !current_user_can('update_plugins' ) ) + return; + + $plugins = get_site_transient( 'update_plugins' ); + if ( isset($plugins->response) && is_array($plugins->response) ) { + $plugins = array_keys( $plugins->response ); + foreach( $plugins as $plugin_file ) { + add_action( "after_plugin_row_$plugin_file", 'wp_plugin_update_row', 10, 2 ); + } + } +} +add_action( 'admin_init', 'wp_plugin_update_rows' ); + +function wp_plugin_update_row( $file, $plugin_data ) { + $current = get_site_transient( 'update_plugins' ); + if ( !isset( $current->response[ $file ] ) ) + return false; + + $r = $current->response[ $file ]; + + $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array()); + $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags ); + + $details_url = self_admin_url('plugin-install.php?tab=plugin-information&plugin=' . $r->slug . '&TB_iframe=true&width=600&height=800'); + + $wp_list_table = _get_list_table('WP_Plugins_List_Table'); + + if ( is_network_admin() || !is_multisite() ) { + echo '
    '; + if ( ! current_user_can('update_plugins') ) + printf( __('There is a new version of %1$s available. View version %4$s details.'), $plugin_name, esc_url($details_url), esc_attr($plugin_name), $r->new_version ); + else if ( empty($r->package) ) + printf( __('There is a new version of %1$s available. View version %4$s details. Automatic update is unavailable for this plugin.'), $plugin_name, esc_url($details_url), esc_attr($plugin_name), $r->new_version ); + else + printf( __('There is a new version of %1$s available. View version %4$s details or update automatically.'), $plugin_name, esc_url($details_url), esc_attr($plugin_name), $r->new_version, wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin=') . $file, 'upgrade-plugin_' . $file) ); + } + + do_action( "in_plugin_update_message-$file", $plugin_data, $r ); + + echo '
    '; +} + +function wp_update_plugin($plugin, $feedback = '') { + if ( !empty($feedback) ) + add_filter('update_feedback', $feedback); + + include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + $upgrader = new Plugin_Upgrader(); + return $upgrader->upgrade($plugin); +} + +function get_theme_updates() { + $themes = get_themes(); + $current = get_site_transient('update_themes'); + $update_themes = array(); + + foreach ( $themes as $theme ) { + $theme = (object) $theme; + if ( isset($current->response[ $theme->Stylesheet ]) ) { + $update_themes[$theme->Stylesheet] = $theme; + $update_themes[$theme->Stylesheet]->update = $current->response[ $theme->Stylesheet ]; + } + } + + return $update_themes; +} + +function wp_update_theme($theme, $feedback = '') { + if ( !empty($feedback) ) + add_filter('update_feedback', $feedback); + + include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + $upgrader = new Theme_Upgrader(); + return $upgrader->upgrade($theme); +} + +function wp_theme_update_rows() { + if ( !current_user_can('update_themes' ) ) + return; + + $themes = get_site_transient( 'update_themes' ); + if ( isset($themes->response) && is_array($themes->response) ) { + $themes = array_keys( $themes->response ); + + foreach( $themes as $theme ) { + add_action( "after_theme_row_$theme", 'wp_theme_update_row', 10, 2 ); + } + } +} +add_action( 'admin_init', 'wp_theme_update_rows' ); + +function wp_theme_update_row( $theme_key, $theme ) { + $current = get_site_transient( 'update_themes' ); + if ( !isset( $current->response[ $theme_key ] ) ) + return false; + $r = $current->response[ $theme_key ]; + $themes_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array()); + $theme_name = wp_kses( $theme['Name'], $themes_allowedtags ); + + $details_url = self_admin_url("theme-install.php?tab=theme-information&theme=$theme_key&TB_iframe=true&width=600&height=400"); + + $wp_list_table = _get_list_table('WP_MS_Themes_List_Table'); + + echo '
    '; + if ( ! current_user_can('update_themes') ) + printf( __('There is a new version of %1$s available. View version %4$s details.'), $theme['Name'], esc_url($details_url), esc_attr($theme['Name']), $r->new_version ); + else if ( empty( $r['package'] ) ) + printf( __('There is a new version of %1$s available. View version %4$s details. Automatic update is unavailable for this plugin.'), $theme['Name'], esc_url($details_url), esc_attr($theme['Name']), $r['new_version'] ); + else + printf( __('There is a new version of %1$s available. View version %4$s details or update automatically.'), $theme['Name'], esc_url($details_url), esc_attr($theme['Name']), $r['new_version'], wp_nonce_url( self_admin_url('update.php?action=upgrade-theme&theme=') . $theme_key, 'upgrade-theme_' . $theme_key) ); + + do_action( "in_theme_update_message-$theme_key", $theme, $r ); + + echo '
    '; +} + +function wp_update_core($current, $feedback = '') { + if ( !empty($feedback) ) + add_filter('update_feedback', $feedback); + + include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + $upgrader = new Core_Upgrader(); + return $upgrader->upgrade($current); + +} + +function maintenance_nag() { + global $upgrading; + if ( ! isset( $upgrading ) ) + return false; + + if ( current_user_can('update_core') ) + $msg = sprintf( __('An automated WordPress update has failed to complete - please attempt the update again now.'), 'update-core.php' ); + else + $msg = __('An automated WordPress update has failed to complete! Please notify the site administrator.'); + + echo "
    $msg
    "; +} +add_action( 'admin_notices', 'maintenance_nag' ); + +?> diff --git a/src/wp-admin/includes/upgrade.php b/src/wp-admin/includes/upgrade.php new file mode 100644 index 00000000..f29f594e --- /dev/null +++ b/src/wp-admin/includes/upgrade.php @@ -0,0 +1,2001 @@ +Note that password carefully! It is a random password that was generated just for you.'); + $user_id = wp_create_user($user_name, $user_password, $user_email); + update_user_option($user_id, 'default_password_nag', true, true); + $email_password = true; + } else if ( !$user_id ) { + // Password has been provided + $message = ''.__('Your chosen password.').''; + $user_id = wp_create_user($user_name, $user_password, $user_email); + } else { + $message = __('User already exists. Password inherited.'); + } + + $user = new WP_User($user_id); + $user->set_role('administrator'); + + wp_install_defaults($user_id); + + $wp_rewrite->flush_rules(); + + wp_new_blog_notification($blog_title, $guessurl, $user_id, ($email_password ? $user_password : __('The password you chose during the install.') ) ); + + wp_cache_flush(); + + return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message); +} +endif; + +if ( !function_exists('wp_install_defaults') ) : +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * + * @param int $user_id User ID. + */ +function wp_install_defaults($user_id) { + global $wpdb, $wp_rewrite, $current_site, $table_prefix; + + // Default category + $cat_name = __('Uncategorized'); + /* translators: Default category slug */ + $cat_slug = sanitize_title(_x('Uncategorized', 'Default category slug')); + + if ( global_terms_enabled() ) { + $cat_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) ); + if ( $cat_id == null ) { + $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) ); + $cat_id = $wpdb->insert_id; + } + update_option('default_category', $cat_id); + } else { + $cat_id = 1; + } + + $wpdb->insert( $wpdb->terms, array('term_id' => $cat_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) ); + $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $cat_id, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1)); + $cat_tt_id = $wpdb->insert_id; + + // Default link category + $cat_name = __('Blogroll'); + /* translators: Default link category slug */ + $cat_slug = sanitize_title(_x('Blogroll', 'Default link category slug')); + + if ( global_terms_enabled() ) { + $blogroll_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) ); + if ( $blogroll_id == null ) { + $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) ); + $blogroll_id = $wpdb->insert_id; + } + update_option('default_link_category', $blogroll_id); + } else { + $blogroll_id = 2; + } + + $wpdb->insert( $wpdb->terms, array('term_id' => $blogroll_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) ); + $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $blogroll_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 7)); + $blogroll_tt_id = $wpdb->insert_id; + + // Now drop in some default links + $default_links = array(); + $default_links[] = array( 'link_url' => 'http://codex.wordpress.org/', + 'link_name' => 'Documentation', + 'link_rss' => '', + 'link_notes' => ''); + + $default_links[] = array( 'link_url' => 'http://wordpress.org/news/', + 'link_name' => 'WordPress Blog', + 'link_rss' => 'http://wordpress.org/news/feed/', + 'link_notes' => ''); + + $default_links[] = array( 'link_url' => 'http://wordpress.org/extend/ideas/', + 'link_name' => 'Suggest Ideas', + 'link_rss' => '', + 'link_notes' =>''); + + $default_links[] = array( 'link_url' => 'http://wordpress.org/support/', + 'link_name' => 'Support Forum', + 'link_rss' => '', + 'link_notes' =>''); + + $default_links[] = array( 'link_url' => 'http://wordpress.org/extend/plugins/', + 'link_name' => 'Plugins', + 'link_rss' => '', + 'link_notes' =>''); + + $default_links[] = array( 'link_url' => 'http://wordpress.org/extend/themes/', + 'link_name' => 'Themes', + 'link_rss' => '', + 'link_notes' =>''); + + $default_links[] = array( 'link_url' => 'http://planet.wordpress.org/', + 'link_name' => 'WordPress Planet', + 'link_rss' => '', + 'link_notes' =>''); + + foreach ( $default_links as $link ) { + $wpdb->insert( $wpdb->links, $link); + $wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $blogroll_tt_id, 'object_id' => $wpdb->insert_id) ); + } + + // First post + $now = date('Y-m-d H:i:s'); + $now_gmt = gmdate('Y-m-d H:i:s'); + $first_post_guid = get_option('home') . '/?p=1'; + + if ( is_multisite() ) { + $first_post = get_site_option( 'first_post' ); + + if ( empty($first_post) ) + $first_post = stripslashes( __( 'Welcome to SITE_NAME. This is your first post. Edit or delete it, then start blogging!' ) ); + + $first_post = str_replace( "SITE_URL", esc_url( network_home_url() ), $first_post ); + $first_post = str_replace( "SITE_NAME", $current_site->site_name, $first_post ); + } else { + $first_post = __('Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!'); + } + + $wpdb->insert( $wpdb->posts, array( + 'post_author' => $user_id, + 'post_date' => $now, + 'post_date_gmt' => $now_gmt, + 'post_content' => $first_post, + 'post_excerpt' => '', + 'post_title' => __('Hello world!'), + /* translators: Default post slug */ + 'post_name' => sanitize_title( _x('hello-world', 'Default post slug') ), + 'post_modified' => $now, + 'post_modified_gmt' => $now_gmt, + 'guid' => $first_post_guid, + 'comment_count' => 1, + 'to_ping' => '', + 'pinged' => '', + 'post_content_filtered' => '' + )); + $wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $cat_tt_id, 'object_id' => 1) ); + + // Default comment + $first_comment_author = __('Mr WordPress'); + $first_comment_url = 'http://wordpress.org/'; + $first_comment = __('Hi, this is a comment.
    To delete a comment, just log in and view the post's comments. There you will have the option to edit or delete them.'); + if ( is_multisite() ) { + $first_comment_author = get_site_option( 'first_comment_author', $first_comment_author ); + $first_comment_url = get_site_option( 'first_comment_url', network_home_url() ); + $first_comment = get_site_option( 'first_comment', $first_comment ); + } + $wpdb->insert( $wpdb->comments, array( + 'comment_post_ID' => 1, + 'comment_author' => $first_comment_author, + 'comment_author_email' => '', + 'comment_author_url' => $first_comment_url, + 'comment_date' => $now, + 'comment_date_gmt' => $now_gmt, + 'comment_content' => $first_comment + )); + + // First Page + $first_page = sprintf( __( "This is an example page. It's different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this: + +
    Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my blog. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.)
    + +...or something like this: + +
    The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickies to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.
    + +As a new WordPress user, you should go to your dashboard to delete this page and create new pages for your content. Have fun!" ), admin_url() ); + if ( is_multisite() ) + $first_page = get_site_option( 'first_page', $first_page ); + $first_post_guid = get_option('home') . '/?page_id=2'; + $wpdb->insert( $wpdb->posts, array( + 'post_author' => $user_id, + 'post_date' => $now, + 'post_date_gmt' => $now_gmt, + 'post_content' => $first_page, + 'post_excerpt' => '', + 'post_title' => __( 'Sample Page' ), + /* translators: Default page slug */ + 'post_name' => __( 'sample-page' ), + 'post_modified' => $now, + 'post_modified_gmt' => $now_gmt, + 'guid' => $first_post_guid, + 'post_type' => 'page', + 'to_ping' => '', + 'pinged' => '', + 'post_content_filtered' => '' + )); + $wpdb->insert( $wpdb->postmeta, array( 'post_id' => 2, 'meta_key' => '_wp_page_template', 'meta_value' => 'default' ) ); + + // Set up default widgets for default theme. + update_option( 'widget_search', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) ); + update_option( 'widget_recent-posts', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) ); + update_option( 'widget_recent-comments', array ( 2 => array ( 'title' => '', 'number' => 5 ), '_multiwidget' => 1 ) ); + update_option( 'widget_archives', array ( 2 => array ( 'title' => '', 'count' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) ); + update_option( 'widget_categories', array ( 2 => array ( 'title' => '', 'count' => 0, 'hierarchical' => 0, 'dropdown' => 0 ), '_multiwidget' => 1 ) ); + update_option( 'widget_meta', array ( 2 => array ( 'title' => '' ), '_multiwidget' => 1 ) ); + update_option( 'sidebars_widgets', array ( 'wp_inactive_widgets' => array ( ), 'primary-widget-area' => array ( 0 => 'search-2', 1 => 'recent-posts-2', 2 => 'recent-comments-2', 3 => 'archives-2', 4 => 'categories-2', 5 => 'meta-2', ), 'secondary-widget-area' => array ( ), 'first-footer-widget-area' => array ( ), 'second-footer-widget-area' => array ( ), 'third-footer-widget-area' => array ( ), 'fourth-footer-widget-area' => array ( ), 'array_version' => 3 ) ); + + if ( is_multisite() ) { + // Flush rules to pick up the new page. + $wp_rewrite->init(); + $wp_rewrite->flush_rules(); + + $user = new WP_User($user_id); + $wpdb->update( $wpdb->options, array('option_value' => $user->user_email), array('option_name' => 'admin_email') ); + + // Remove all perms except for the login user. + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'user_level') ); + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'capabilities') ); + + // Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id. + if ( !is_super_admin( $user_id ) && $user_id != 1 ) + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $wpdb->base_prefix.'1_capabilities') ); + } +} +endif; + +if ( !function_exists('wp_new_blog_notification') ) : +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * + * @param string $blog_title Blog title. + * @param string $blog_url Blog url. + * @param int $user_id User ID. + * @param string $password User's Password. + */ +function wp_new_blog_notification($blog_title, $blog_url, $user_id, $password) { + $user = new WP_User($user_id); + $email = $user->user_email; + $name = $user->user_login; + $message = sprintf(__("Your new WordPress site has been successfully set up at: + +%1\$s + +You can log in to the administrator account with the following information: + +Username: %2\$s +Password: %3\$s + +We hope you enjoy your new site. Thanks! + +--The WordPress Team +http://wordpress.org/ +"), $blog_url, $name, $password); + + @wp_mail($email, __('New WordPress Site'), $message); +} +endif; + +if ( !function_exists('wp_upgrade') ) : +/** + * Run WordPress Upgrade functions. + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + * + * @return null + */ +function wp_upgrade() { + global $wp_current_db_version, $wp_db_version, $wpdb; + + $wp_current_db_version = __get_option('db_version'); + + // We are up-to-date. Nothing to do. + if ( $wp_db_version == $wp_current_db_version ) + return; + + if ( ! is_blog_installed() ) + return; + + wp_check_mysql_version(); + wp_cache_flush(); + pre_schema_upgrade(); + make_db_current_silent(); + upgrade_all(); + if ( is_multisite() && is_main_site() ) + upgrade_network(); + wp_cache_flush(); + + if ( is_multisite() ) { + if ( $wpdb->get_row( "SELECT blog_id FROM {$wpdb->blog_versions} WHERE blog_id = '{$wpdb->blogid}'" ) ) + $wpdb->query( "UPDATE {$wpdb->blog_versions} SET db_version = '{$wp_db_version}' WHERE blog_id = '{$wpdb->blogid}'" ); + else + $wpdb->query( "INSERT INTO {$wpdb->blog_versions} ( `blog_id` , `db_version` , `last_updated` ) VALUES ( '{$wpdb->blogid}', '{$wp_db_version}', NOW());" ); + } +} +endif; + +/** + * Functions to be called in install and upgrade scripts. + * + * {@internal Missing Long Description}} + * + * @since 1.0.1 + */ +function upgrade_all() { + global $wp_current_db_version, $wp_db_version, $wp_rewrite; + $wp_current_db_version = __get_option('db_version'); + + // We are up-to-date. Nothing to do. + if ( $wp_db_version == $wp_current_db_version ) + return; + + // If the version is not set in the DB, try to guess the version. + if ( empty($wp_current_db_version) ) { + $wp_current_db_version = 0; + + // If the template option exists, we have 1.5. + $template = __get_option('template'); + if ( !empty($template) ) + $wp_current_db_version = 2541; + } + + if ( $wp_current_db_version < 6039 ) + upgrade_230_options_table(); + + populate_options(); + + if ( $wp_current_db_version < 2541 ) { + upgrade_100(); + upgrade_101(); + upgrade_110(); + upgrade_130(); + } + + if ( $wp_current_db_version < 3308 ) + upgrade_160(); + + if ( $wp_current_db_version < 4772 ) + upgrade_210(); + + if ( $wp_current_db_version < 4351 ) + upgrade_old_slugs(); + + if ( $wp_current_db_version < 5539 ) + upgrade_230(); + + if ( $wp_current_db_version < 6124 ) + upgrade_230_old_tables(); + + if ( $wp_current_db_version < 7499 ) + upgrade_250(); + + if ( $wp_current_db_version < 7935 ) + upgrade_252(); + + if ( $wp_current_db_version < 8201 ) + upgrade_260(); + + if ( $wp_current_db_version < 8989 ) + upgrade_270(); + + if ( $wp_current_db_version < 10360 ) + upgrade_280(); + + if ( $wp_current_db_version < 11958 ) + upgrade_290(); + + if ( $wp_current_db_version < 15260 ) + upgrade_300(); + + maybe_disable_automattic_widgets(); + + update_option( 'db_version', $wp_db_version ); + update_option( 'db_upgraded', true ); +} + +/** + * Execute changes made in WordPress 1.0. + * + * @since 1.0.0 + */ +function upgrade_100() { + global $wpdb; + + // Get the title and ID of every post, post_name to check if it already has a value + $posts = $wpdb->get_results("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''"); + if ($posts) { + foreach($posts as $post) { + if ('' == $post->post_name) { + $newtitle = sanitize_title($post->post_title); + $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_name = %s WHERE ID = %d", $newtitle, $post->ID) ); + } + } + } + + $categories = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories"); + foreach ($categories as $category) { + if ('' == $category->category_nicename) { + $newtitle = sanitize_title($category->cat_name); + $wpdb>update( $wpdb->categories, array('category_nicename' => $newtitle), array('cat_ID' => $category->cat_ID) ); + } + } + + $wpdb->query("UPDATE $wpdb->options SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/') + WHERE option_name LIKE 'links_rating_image%' + AND option_value LIKE 'wp-links/links-images/%'"); + + $done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat"); + if ($done_ids) : + foreach ($done_ids as $done_id) : + $done_posts[] = $done_id->post_id; + endforeach; + $catwhere = ' AND ID NOT IN (' . implode(',', $done_posts) . ')'; + else: + $catwhere = ''; + endif; + + $allposts = $wpdb->get_results("SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere"); + if ($allposts) : + foreach ($allposts as $post) { + // Check to see if it's already been imported + $cat = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->post2cat WHERE post_id = %d AND category_id = %d", $post->ID, $post->post_category) ); + if (!$cat && 0 != $post->post_category) { // If there's no result + $wpdb->insert( $wpdb->post2cat, array('post_id' => $post->ID, 'category_id' => $post->post_category) ); + } + } + endif; +} + +/** + * Execute changes made in WordPress 1.0.1. + * + * @since 1.0.1 + */ +function upgrade_101() { + global $wpdb; + + // Clean up indices, add a few + add_clean_index($wpdb->posts, 'post_name'); + add_clean_index($wpdb->posts, 'post_status'); + add_clean_index($wpdb->categories, 'category_nicename'); + add_clean_index($wpdb->comments, 'comment_approved'); + add_clean_index($wpdb->comments, 'comment_post_ID'); + add_clean_index($wpdb->links , 'link_category'); + add_clean_index($wpdb->links , 'link_visible'); +} + +/** + * Execute changes made in WordPress 1.2. + * + * @since 1.2.0 + */ +function upgrade_110() { + global $wpdb; + + // Set user_nicename. + $users = $wpdb->get_results("SELECT ID, user_nickname, user_nicename FROM $wpdb->users"); + foreach ($users as $user) { + if ('' == $user->user_nicename) { + $newname = sanitize_title($user->user_nickname); + $wpdb->update( $wpdb->users, array('user_nicename' => $newname), array('ID' => $user->ID) ); + } + } + + $users = $wpdb->get_results("SELECT ID, user_pass from $wpdb->users"); + foreach ($users as $row) { + if (!preg_match('/^[A-Fa-f0-9]{32}$/', $row->user_pass)) { + $wpdb->update( $wpdb->users, array('user_pass' => md5($row->user_pass)), array('ID' => $row->ID) ); + } + } + + // Get the GMT offset, we'll use that later on + $all_options = get_alloptions_110(); + + $time_difference = $all_options->time_difference; + + $server_time = time()+date('Z'); + $weblogger_time = $server_time + $time_difference*3600; + $gmt_time = time(); + + $diff_gmt_server = ($gmt_time - $server_time) / 3600; + $diff_weblogger_server = ($weblogger_time - $server_time) / 3600; + $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server; + $gmt_offset = -$diff_gmt_weblogger; + + // Add a gmt_offset option, with value $gmt_offset + add_option('gmt_offset', $gmt_offset); + + // Check if we already set the GMT fields (if we did, then + // MAX(post_date_gmt) can't be '0000-00-00 00:00:00' + // I just slapped myself silly for not thinking about it earlier + $got_gmt_fields = ! ($wpdb->get_var("SELECT MAX(post_date_gmt) FROM $wpdb->posts") == '0000-00-00 00:00:00'); + + if (!$got_gmt_fields) { + + // Add or substract time to all dates, to get GMT dates + $add_hours = intval($diff_gmt_weblogger); + $add_minutes = intval(60 * ($diff_gmt_weblogger - $add_hours)); + $wpdb->query("UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)"); + $wpdb->query("UPDATE $wpdb->posts SET post_modified = post_date"); + $wpdb->query("UPDATE $wpdb->posts SET post_modified_gmt = DATE_ADD(post_modified, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE) WHERE post_modified != '0000-00-00 00:00:00'"); + $wpdb->query("UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)"); + $wpdb->query("UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)"); + } + +} + +/** + * Execute changes made in WordPress 1.5. + * + * @since 1.5.0 + */ +function upgrade_130() { + global $wpdb; + + // Remove extraneous backslashes. + $posts = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts"); + if ($posts) { + foreach($posts as $post) { + $post_content = addslashes(deslash($post->post_content)); + $post_title = addslashes(deslash($post->post_title)); + $post_excerpt = addslashes(deslash($post->post_excerpt)); + if ( empty($post->guid) ) + $guid = get_permalink($post->ID); + else + $guid = $post->guid; + + $wpdb->update( $wpdb->posts, compact('post_title', 'post_content', 'post_excerpt', 'guid'), array('ID' => $post->ID) ); + + } + } + + // Remove extraneous backslashes. + $comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments"); + if ($comments) { + foreach($comments as $comment) { + $comment_content = deslash($comment->comment_content); + $comment_author = deslash($comment->comment_author); + + $wpdb->update($wpdb->comments, compact('comment_content', 'comment_author'), array('comment_ID' => $comment->comment_ID) ); + } + } + + // Remove extraneous backslashes. + $links = $wpdb->get_results("SELECT link_id, link_name, link_description FROM $wpdb->links"); + if ($links) { + foreach($links as $link) { + $link_name = deslash($link->link_name); + $link_description = deslash($link->link_description); + + $wpdb->update( $wpdb->links, compact('link_name', 'link_description'), array('link_id' => $link->link_id) ); + } + } + + $active_plugins = __get_option('active_plugins'); + + // If plugins are not stored in an array, they're stored in the old + // newline separated format. Convert to new format. + if ( !is_array( $active_plugins ) ) { + $active_plugins = explode("\n", trim($active_plugins)); + update_option('active_plugins', $active_plugins); + } + + // Obsolete tables + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues'); + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes'); + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups'); + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options'); + + // Update comments table to use comment_type + $wpdb->query("UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '', '') WHERE comment_content LIKE '%'"); + $wpdb->query("UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '', '') WHERE comment_content LIKE '%'"); + + // Some versions have multiple duplicate option_name rows with the same values + $options = $wpdb->get_results("SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name"); + foreach ( $options as $option ) { + if ( 1 != $option->dupes ) { // Could this be done in the query? + $limit = $option->dupes - 1; + $dupe_ids = $wpdb->get_col( $wpdb->prepare("SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT %d", $option->option_name, $limit) ); + if ( $dupe_ids ) { + $dupe_ids = join($dupe_ids, ','); + $wpdb->query("DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)"); + } + } + } + + make_site_theme(); +} + +/** + * Execute changes made in WordPress 2.0. + * + * @since 2.0.0 + */ +function upgrade_160() { + global $wpdb, $wp_current_db_version; + + populate_roles_160(); + + $users = $wpdb->get_results("SELECT * FROM $wpdb->users"); + foreach ( $users as $user ) : + if ( !empty( $user->user_firstname ) ) + update_user_meta( $user->ID, 'first_name', $wpdb->escape($user->user_firstname) ); + if ( !empty( $user->user_lastname ) ) + update_user_meta( $user->ID, 'last_name', $wpdb->escape($user->user_lastname) ); + if ( !empty( $user->user_nickname ) ) + update_user_meta( $user->ID, 'nickname', $wpdb->escape($user->user_nickname) ); + if ( !empty( $user->user_level ) ) + update_user_meta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level ); + if ( !empty( $user->user_icq ) ) + update_user_meta( $user->ID, 'icq', $wpdb->escape($user->user_icq) ); + if ( !empty( $user->user_aim ) ) + update_user_meta( $user->ID, 'aim', $wpdb->escape($user->user_aim) ); + if ( !empty( $user->user_msn ) ) + update_user_meta( $user->ID, 'msn', $wpdb->escape($user->user_msn) ); + if ( !empty( $user->user_yim ) ) + update_user_meta( $user->ID, 'yim', $wpdb->escape($user->user_icq) ); + if ( !empty( $user->user_description ) ) + update_user_meta( $user->ID, 'description', $wpdb->escape($user->user_description) ); + + if ( isset( $user->user_idmode ) ): + $idmode = $user->user_idmode; + if ($idmode == 'nickname') $id = $user->user_nickname; + if ($idmode == 'login') $id = $user->user_login; + if ($idmode == 'firstname') $id = $user->user_firstname; + if ($idmode == 'lastname') $id = $user->user_lastname; + if ($idmode == 'namefl') $id = $user->user_firstname.' '.$user->user_lastname; + if ($idmode == 'namelf') $id = $user->user_lastname.' '.$user->user_firstname; + if (!$idmode) $id = $user->user_nickname; + $wpdb->update( $wpdb->users, array('display_name' => $id), array('ID' => $user->ID) ); + endif; + + // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set. + $caps = get_user_meta( $user->ID, $wpdb->prefix . 'capabilities'); + if ( empty($caps) || defined('RESET_CAPS') ) { + $level = get_user_meta($user->ID, $wpdb->prefix . 'user_level', true); + $role = translate_level_to_role($level); + update_user_meta( $user->ID, $wpdb->prefix . 'capabilities', array($role => true) ); + } + + endforeach; + $old_user_fields = array( 'user_firstname', 'user_lastname', 'user_icq', 'user_aim', 'user_msn', 'user_yim', 'user_idmode', 'user_ip', 'user_domain', 'user_browser', 'user_description', 'user_nickname', 'user_level' ); + $wpdb->hide_errors(); + foreach ( $old_user_fields as $old ) + $wpdb->query("ALTER TABLE $wpdb->users DROP $old"); + $wpdb->show_errors(); + + // populate comment_count field of posts table + $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" ); + if ( is_array( $comments ) ) + foreach ($comments as $comment) + $wpdb->update( $wpdb->posts, array('comment_count' => $comment->c), array('ID' => $comment->comment_post_ID) ); + + // Some alpha versions used a post status of object instead of attachment and put + // the mime type in post_type instead of post_mime_type. + if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) { + $objects = $wpdb->get_results("SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'"); + foreach ($objects as $object) { + $wpdb->update( $wpdb->posts, array( 'post_status' => 'attachment', + 'post_mime_type' => $object->post_type, + 'post_type' => ''), + array( 'ID' => $object->ID ) ); + + $meta = get_post_meta($object->ID, 'imagedata', true); + if ( ! empty($meta['file']) ) + update_attached_file( $object->ID, $meta['file'] ); + } + } +} + +/** + * Execute changes made in WordPress 2.1. + * + * @since 2.1.0 + */ +function upgrade_210() { + global $wpdb, $wp_current_db_version; + + if ( $wp_current_db_version < 3506 ) { + // Update status and type. + $posts = $wpdb->get_results("SELECT ID, post_status FROM $wpdb->posts"); + + if ( ! empty($posts) ) foreach ($posts as $post) { + $status = $post->post_status; + $type = 'post'; + + if ( 'static' == $status ) { + $status = 'publish'; + $type = 'page'; + } else if ( 'attachment' == $status ) { + $status = 'inherit'; + $type = 'attachment'; + } + + $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_status = %s, post_type = %s WHERE ID = %d", $status, $type, $post->ID) ); + } + } + + if ( $wp_current_db_version < 3845 ) { + populate_roles_210(); + } + + if ( $wp_current_db_version < 3531 ) { + // Give future posts a post_status of future. + $now = gmdate('Y-m-d H:i:59'); + $wpdb->query ("UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'"); + + $posts = $wpdb->get_results("SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'"); + if ( !empty($posts) ) + foreach ( $posts as $post ) + wp_schedule_single_event(mysql2date('U', $post->post_date, false), 'publish_future_post', array($post->ID)); + } +} + +/** + * Execute changes made in WordPress 2.3. + * + * @since 2.3.0 + */ +function upgrade_230() { + global $wp_current_db_version, $wpdb; + + if ( $wp_current_db_version < 5200 ) { + populate_roles_230(); + } + + // Convert categories to terms. + $tt_ids = array(); + $have_tags = false; + $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_ID"); + foreach ($categories as $category) { + $term_id = (int) $category->cat_ID; + $name = $category->cat_name; + $description = $category->category_description; + $slug = $category->category_nicename; + $parent = $category->category_parent; + $term_group = 0; + + // Associate terms with the same slug in a term group and make slugs unique. + if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) { + $term_group = $exists[0]->term_group; + $id = $exists[0]->term_id; + $num = 2; + do { + $alt_slug = $slug . "-$num"; + $num++; + $slug_check = $wpdb->get_var( $wpdb->prepare("SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug) ); + } while ( $slug_check ); + + $slug = $alt_slug; + + if ( empty( $term_group ) ) { + $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group") + 1; + $wpdb->query( $wpdb->prepare("UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $id) ); + } + } + + $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES + (%d, %s, %s, %d)", $term_id, $name, $slug, $term_group) ); + + $count = 0; + if ( !empty($category->category_count) ) { + $count = (int) $category->category_count; + $taxonomy = 'category'; + $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy, description, parent, count) VALUES ( %d, %s, %s, %d, %d)", $term_id, $taxonomy, $description, $parent, $count) ); + $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id; + } + + if ( !empty($category->link_count) ) { + $count = (int) $category->link_count; + $taxonomy = 'link_category'; + $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy, description, parent, count) VALUES ( %d, %s, %s, %d, %d)", $term_id, $taxonomy, $description, $parent, $count) ); + $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id; + } + + if ( !empty($category->tag_count) ) { + $have_tags = true; + $count = (int) $category->tag_count; + $taxonomy = 'post_tag'; + $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') ); + $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id; + } + + if ( empty($count) ) { + $count = 0; + $taxonomy = 'category'; + $wpdb->insert( $wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent', 'count') ); + $tt_ids[$term_id][$taxonomy] = (int) $wpdb->insert_id; + } + } + + $select = 'post_id, category_id'; + if ( $have_tags ) + $select .= ', rel_type'; + + $posts = $wpdb->get_results("SELECT $select FROM $wpdb->post2cat GROUP BY post_id, category_id"); + foreach ( $posts as $post ) { + $post_id = (int) $post->post_id; + $term_id = (int) $post->category_id; + $taxonomy = 'category'; + if ( !empty($post->rel_type) && 'tag' == $post->rel_type) + $taxonomy = 'tag'; + $tt_id = $tt_ids[$term_id][$taxonomy]; + if ( empty($tt_id) ) + continue; + + $wpdb->insert( $wpdb->term_relationships, array('object_id' => $post_id, 'term_taxonomy_id' => $tt_id) ); + } + + // < 3570 we used linkcategories. >= 3570 we used categories and link2cat. + if ( $wp_current_db_version < 3570 ) { + // Create link_category terms for link categories. Create a map of link cat IDs + // to link_category terms. + $link_cat_id_map = array(); + $default_link_cat = 0; + $tt_ids = array(); + $link_cats = $wpdb->get_results("SELECT cat_id, cat_name FROM " . $wpdb->prefix . 'linkcategories'); + foreach ( $link_cats as $category) { + $cat_id = (int) $category->cat_id; + $term_id = 0; + $name = $wpdb->escape($category->cat_name); + $slug = sanitize_title($name); + $term_group = 0; + + // Associate terms with the same slug in a term group and make slugs unique. + if ( $exists = $wpdb->get_results( $wpdb->prepare("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug) ) ) { + $term_group = $exists[0]->term_group; + $term_id = $exists[0]->term_id; + } + + if ( empty($term_id) ) { + $wpdb->insert( $wpdb->terms, compact('name', 'slug', 'term_group') ); + $term_id = (int) $wpdb->insert_id; + } + + $link_cat_id_map[$cat_id] = $term_id; + $default_link_cat = $term_id; + + $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $term_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 0) ); + $tt_ids[$term_id] = (int) $wpdb->insert_id; + } + + // Associate links to cats. + $links = $wpdb->get_results("SELECT link_id, link_category FROM $wpdb->links"); + if ( !empty($links) ) foreach ( $links as $link ) { + if ( 0 == $link->link_category ) + continue; + if ( ! isset($link_cat_id_map[$link->link_category]) ) + continue; + $term_id = $link_cat_id_map[$link->link_category]; + $tt_id = $tt_ids[$term_id]; + if ( empty($tt_id) ) + continue; + + $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link->link_id, 'term_taxonomy_id' => $tt_id) ); + } + + // Set default to the last category we grabbed during the upgrade loop. + update_option('default_link_category', $default_link_cat); + } else { + $links = $wpdb->get_results("SELECT link_id, category_id FROM $wpdb->link2cat GROUP BY link_id, category_id"); + foreach ( $links as $link ) { + $link_id = (int) $link->link_id; + $term_id = (int) $link->category_id; + $taxonomy = 'link_category'; + $tt_id = $tt_ids[$term_id][$taxonomy]; + if ( empty($tt_id) ) + continue; + $wpdb->insert( $wpdb->term_relationships, array('object_id' => $link_id, 'term_taxonomy_id' => $tt_id) ); + } + } + + if ( $wp_current_db_version < 4772 ) { + // Obsolete linkcategories table + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories'); + } + + // Recalculate all counts + $terms = $wpdb->get_results("SELECT term_taxonomy_id, taxonomy FROM $wpdb->term_taxonomy"); + foreach ( (array) $terms as $term ) { + if ( ('post_tag' == $term->taxonomy) || ('category' == $term->taxonomy) ) + $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type = 'post' AND term_taxonomy_id = %d", $term->term_taxonomy_id) ); + else + $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term->term_taxonomy_id) ); + $wpdb->update( $wpdb->term_taxonomy, array('count' => $count), array('term_taxonomy_id' => $term->term_taxonomy_id) ); + } +} + +/** + * Remove old options from the database. + * + * @since 2.3.0 + */ +function upgrade_230_options_table() { + global $wpdb; + $old_options_fields = array( 'option_can_override', 'option_type', 'option_width', 'option_height', 'option_description', 'option_admin_level' ); + $wpdb->hide_errors(); + foreach ( $old_options_fields as $old ) + $wpdb->query("ALTER TABLE $wpdb->options DROP $old"); + $wpdb->show_errors(); +} + +/** + * Remove old categories, link2cat, and post2cat database tables. + * + * @since 2.3.0 + */ +function upgrade_230_old_tables() { + global $wpdb; + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'categories'); + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'link2cat'); + $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post2cat'); +} + +/** + * Upgrade old slugs made in version 2.2. + * + * @since 2.2.0 + */ +function upgrade_old_slugs() { + // upgrade people who were using the Redirect Old Slugs plugin + global $wpdb; + $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'"); +} + +/** + * Execute changes made in WordPress 2.5.0. + * + * @since 2.5.0 + */ +function upgrade_250() { + global $wp_current_db_version; + + if ( $wp_current_db_version < 6689 ) { + populate_roles_250(); + } + +} + +/** + * Execute changes made in WordPress 2.5.2. + * + * @since 2.5.2 + */ +function upgrade_252() { + global $wpdb; + + $wpdb->query("UPDATE $wpdb->users SET user_activation_key = ''"); +} + +/** + * Execute changes made in WordPress 2.6. + * + * @since 2.6.0 + */ +function upgrade_260() { + global $wp_current_db_version; + + if ( $wp_current_db_version < 8000 ) + populate_roles_260(); + + if ( $wp_current_db_version < 8201 ) { + update_option('enable_app', 1); + update_option('enable_xmlrpc', 1); + } +} + +/** + * Execute changes made in WordPress 2.7. + * + * @since 2.7.0 + */ +function upgrade_270() { + global $wpdb, $wp_current_db_version; + + if ( $wp_current_db_version < 8980 ) + populate_roles_270(); + + // Update post_date for unpublished posts with empty timestamp + if ( $wp_current_db_version < 8921 ) + $wpdb->query( "UPDATE $wpdb->posts SET post_date = post_modified WHERE post_date = '0000-00-00 00:00:00'" ); +} + +/** + * Execute changes made in WordPress 2.8. + * + * @since 2.8.0 + */ +function upgrade_280() { + global $wp_current_db_version, $wpdb; + + if ( $wp_current_db_version < 10360 ) + populate_roles_280(); + if ( is_multisite() ) { + $start = 0; + while( $rows = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options ORDER BY option_id LIMIT $start, 20" ) ) { + foreach( $rows as $row ) { + $value = $row->option_value; + if ( !@unserialize( $value ) ) + $value = stripslashes( $value ); + if ( $value !== $row->option_value ) { + update_option( $row->option_name, $value ); + } + } + $start += 20; + } + refresh_blog_details( $wpdb->blogid ); + } +} + +/** + * Execute changes made in WordPress 2.9. + * + * @since 2.9.0 + */ +function upgrade_290() { + global $wp_current_db_version; + + if ( $wp_current_db_version < 11958 ) { + // Previously, setting depth to 1 would redundantly disable threading, but now 2 is the minimum depth to avoid confusion + if ( get_option( 'thread_comments_depth' ) == '1' ) { + update_option( 'thread_comments_depth', 2 ); + update_option( 'thread_comments', 0 ); + } + } +} + +/** + * Execute changes made in WordPress 3.0. + * + * @since 3.0.0 + */ +function upgrade_300() { + global $wp_current_db_version, $wpdb; + + if ( $wp_current_db_version < 15093 ) + populate_roles_300(); + + if ( $wp_current_db_version < 14139 && is_multisite() && is_main_site() && ! defined( 'MULTISITE' ) && get_site_option( 'siteurl' ) === false ) + add_site_option( 'siteurl', '' ); + + // 3.0-alpha nav menu postmeta changes. can be removed before release. // r13802 + if ( $wp_current_db_version >= 13226 && $wp_current_db_version < 13974 ) + $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key IN( 'menu_type', 'object_id', 'menu_new_window', 'menu_link', '_menu_item_append', 'menu_item_append', 'menu_item_type', 'menu_item_object_id', 'menu_item_target', 'menu_item_classes', 'menu_item_xfn', 'menu_item_url' )" ); + + // 3.0-beta1 remove_user primitive->meta cap. can be removed before release. r13956 + if ( $wp_current_db_version >= 12751 && $wp_current_db_version < 13974 ) { + $role =& get_role( 'administrator' ); + if ( ! empty( $role ) ) + $role->remove_cap( 'remove_user' ); + } + + // 3.0-beta1 nav menu postmeta changes. can be removed before release. r13974 + if ( $wp_current_db_version >= 13802 && $wp_current_db_version < 13974 ) + $wpdb->update( $wpdb->postmeta, array( 'meta_value' => '' ), array( 'meta_key' => '_menu_item_target', 'meta_value' => '_self' ) ); + + // 3.0 screen options key name changes. + if ( is_main_site() && !defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) { + $prefix = like_escape($wpdb->base_prefix); + $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key LIKE '{$prefix}%meta-box-hidden%' OR meta_key LIKE '{$prefix}%closedpostboxes%' OR meta_key LIKE '{$prefix}%manage-%-columns-hidden%' OR meta_key LIKE '{$prefix}%meta-box-order%' OR meta_key LIKE '{$prefix}%metaboxorder%' OR meta_key LIKE '{$prefix}%screen_layout%' + OR meta_key = 'manageedittagscolumnshidden' OR meta_key='managecategoriescolumnshidden' OR meta_key = 'manageedit-tagscolumnshidden' OR meta_key = 'manageeditcolumnshidden' OR meta_key = 'categories_per_page' OR meta_key = 'edit_tags_per_page'" ); + } + +} + +/** + * Execute network level changes + * + * @since 3.0.0 + */ +function upgrade_network() { + global $wp_current_db_version, $wpdb; + // 2.8 + if ( $wp_current_db_version < 11549 ) { + $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' ); + $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' ); + if ( $wpmu_sitewide_plugins ) { + if ( !$active_sitewide_plugins ) + $sitewide_plugins = (array) $wpmu_sitewide_plugins; + else + $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins ); + + update_site_option( 'active_sitewide_plugins', $sitewide_plugins ); + } + delete_site_option( 'wpmu_sitewide_plugins' ); + delete_site_option( 'deactivated_sitewide_plugins' ); + + $start = 0; + while( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) { + foreach( $rows as $row ) { + $value = $row->meta_value; + if ( !@unserialize( $value ) ) + $value = stripslashes( $value ); + if ( $value !== $row->meta_value ) { + update_site_option( $row->meta_key, $value ); + } + } + $start += 20; + } + } + // 3.0 + if ( $wp_current_db_version < 13576 ) + update_site_option( 'global_terms_enabled', '1' ); +} + +// The functions we use to actually do stuff + +// General + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.0.0 + * + * @param string $table_name Database table name to create. + * @param string $create_ddl SQL statement to create table. + * @return bool If table already exists or was created by function. + */ +function maybe_create_table($table_name, $create_ddl) { + global $wpdb; + if ( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name ) + return true; + //didn't find it try to create it. + $q = $wpdb->query($create_ddl); + // we cannot directly tell that whether this succeeded! + if ( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name ) + return true; + return false; +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.0.1 + * + * @param string $table Database table name. + * @param string $index Index name to drop. + * @return bool True, when finished. + */ +function drop_index($table, $index) { + global $wpdb; + $wpdb->hide_errors(); + $wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`"); + // Now we need to take out all the extra ones we may have created + for ($i = 0; $i < 25; $i++) { + $wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`"); + } + $wpdb->show_errors(); + return true; +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.0.1 + * + * @param string $table Database table name. + * @param string $index Database table index column. + * @return bool True, when done with execution. + */ +function add_clean_index($table, $index) { + global $wpdb; + drop_index($table, $index); + $wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )"); + return true; +} + +/** + ** maybe_add_column() + ** Add column to db table if it doesn't exist. + ** Returns: true if already exists or on successful completion + ** false on error + */ +function maybe_add_column($table_name, $column_name, $create_ddl) { + global $wpdb, $debug; + foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) { + if ($debug) echo("checking $column == $column_name
    "); + if ($column == $column_name) { + return true; + } + } + //didn't find it try to create it. + $q = $wpdb->query($create_ddl); + // we cannot directly tell that whether this succeeded! + foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) { + if ($column == $column_name) { + return true; + } + } + return false; +} + +/** + * Retrieve all options as it was for 1.2. + * + * @since 1.2.0 + * + * @return array List of options. + */ +function get_alloptions_110() { + global $wpdb; + if ($options = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options")) { + foreach ($options as $option) { + // "When trying to design a foolproof system, + // never underestimate the ingenuity of the fools :)" -- Dougal + if ('siteurl' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value); + if ('home' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value); + if ('category_base' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value); + $all_options->{$option->option_name} = stripslashes($option->option_value); + } + } + return $all_options; +} + +/** + * Version of get_option that is private to install/upgrade. + * + * @since 1.5.1 + * @access private + * + * @param string $setting Option name. + * @return mixed + */ +function __get_option($setting) { + global $wpdb; + + if ( $setting == 'home' && defined( 'WP_HOME' ) ) { + return preg_replace( '|/+$|', '', WP_HOME ); + } + + if ( $setting == 'siteurl' && defined( 'WP_SITEURL' ) ) { + return preg_replace( '|/+$|', '', WP_SITEURL ); + } + + $option = $wpdb->get_var( $wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting) ); + + if ( 'home' == $setting && '' == $option ) + return __get_option('siteurl'); + + if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting ) + $option = preg_replace('|/+$|', '', $option); + + @ $kellogs = unserialize($option); + if ($kellogs !== FALSE) + return $kellogs; + else + return $option; +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.5.0 + * + * @param string $content + * @return string + */ +function deslash($content) { + // Note: \\\ inside a regex denotes a single backslash. + + // Replace one or more backslashes followed by a single quote with + // a single quote. + $content = preg_replace("/\\\+'/", "'", $content); + + // Replace one or more backslashes followed by a double quote with + // a double quote. + $content = preg_replace('/\\\+"/', '"', $content); + + // Replace one or more backslashes with one backslash. + $content = preg_replace("/\\\+/", "\\", $content); + + return $content; +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.5.0 + * + * @param unknown_type $queries + * @param unknown_type $execute + * @return unknown + */ +function dbDelta($queries, $execute = true) { + global $wpdb; + + // Separate individual queries into an array + if ( !is_array($queries) ) { + $queries = explode( ';', $queries ); + if ('' == $queries[count($queries) - 1]) array_pop($queries); + } + + $cqueries = array(); // Creation Queries + $iqueries = array(); // Insertion Queries + $for_update = array(); + + // Create a tablename index for an array ($cqueries) of queries + foreach($queries as $qry) { + if (preg_match("|CREATE TABLE ([^ ]*)|", $qry, $matches)) { + $cqueries[trim( strtolower($matches[1]), '`' )] = $qry; + $for_update[$matches[1]] = 'Created table '.$matches[1]; + } else if (preg_match("|CREATE DATABASE ([^ ]*)|", $qry, $matches)) { + array_unshift($cqueries, $qry); + } else if (preg_match("|INSERT INTO ([^ ]*)|", $qry, $matches)) { + $iqueries[] = $qry; + } else if (preg_match("|UPDATE ([^ ]*)|", $qry, $matches)) { + $iqueries[] = $qry; + } else { + // Unrecognized query type + } + } + + // Check to see which tables and fields exist + if ($tables = $wpdb->get_col('SHOW TABLES;')) { + // For every table in the database + foreach ($tables as $table) { + // Upgrade global tables only for the main site. Don't upgrade at all if DO_NOT_UPGRADE_GLOBAL_TABLES is defined. + if ( in_array($table, $wpdb->tables('global')) && ( !is_main_site() || defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) ) + continue; + + // If a table query exists for the database table... + if ( array_key_exists(strtolower($table), $cqueries) ) { + // Clear the field and index arrays + $cfields = $indices = array(); + // Get all of the field names in the query from between the parens + preg_match("|\((.*)\)|ms", $cqueries[strtolower($table)], $match2); + $qryline = trim($match2[1]); + + // Separate field lines into an array + $flds = explode("\n", $qryline); + + //echo "
    \n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."

    "; + + // For every field line specified in the query + foreach ($flds as $fld) { + // Extract the field name + preg_match("|^([^ ]*)|", trim($fld), $fvals); + $fieldname = trim( $fvals[1], '`' ); + + // Verify the found field name + $validfield = true; + switch (strtolower($fieldname)) { + case '': + case 'primary': + case 'index': + case 'fulltext': + case 'unique': + case 'key': + $validfield = false; + $indices[] = trim(trim($fld), ", \n"); + break; + } + $fld = trim($fld); + + // If it's a valid field, add it to the field array + if ($validfield) { + $cfields[strtolower($fieldname)] = trim($fld, ", \n"); + } + } + + // Fetch the table column structure from the database + $tablefields = $wpdb->get_results("DESCRIBE {$table};"); + + // For every field in the table + foreach ($tablefields as $tablefield) { + // If the table field exists in the field array... + if (array_key_exists(strtolower($tablefield->Field), $cfields)) { + // Get the field type from the query + preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches); + $fieldtype = $matches[1]; + + // Is actual field type different from the field type in query? + if ($tablefield->Type != $fieldtype) { + // Add a query to change the column type + $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)]; + $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}"; + } + + // Get the default value from the array + //echo "{$cfields[strtolower($tablefield->Field)]}
    "; + if (preg_match("| DEFAULT '(.*)'|i", $cfields[strtolower($tablefield->Field)], $matches)) { + $default_value = $matches[1]; + if ($tablefield->Default != $default_value) { + // Add a query to change the column's default value + $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'"; + $for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}"; + } + } + + // Remove the field from the array (so it's not added) + unset($cfields[strtolower($tablefield->Field)]); + } else { + // This field exists in the table, but not in the creation queries? + } + } + + // For every remaining field specified for the table + foreach ($cfields as $fieldname => $fielddef) { + // Push a query line into $cqueries that adds the field to that table + $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef"; + $for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname; + } + + // Index stuff goes here + // Fetch the table index structure from the database + $tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};"); + + if ($tableindices) { + // Clear the index array + unset($index_ary); + + // For every index in the table + foreach ($tableindices as $tableindex) { + // Add the index to the index data array + $keyname = $tableindex->Key_name; + $index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part); + $index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false; + } + + // For each actual index in the index array + foreach ($index_ary as $index_name => $index_data) { + // Build a create string to compare to the query + $index_string = ''; + if ($index_name == 'PRIMARY') { + $index_string .= 'PRIMARY '; + } else if($index_data['unique']) { + $index_string .= 'UNIQUE '; + } + $index_string .= 'KEY '; + if ($index_name != 'PRIMARY') { + $index_string .= $index_name; + } + $index_columns = ''; + // For each column in the index + foreach ($index_data['columns'] as $column_data) { + if ($index_columns != '') $index_columns .= ','; + // Add the field to the column list string + $index_columns .= $column_data['fieldname']; + if ($column_data['subpart'] != '') { + $index_columns .= '('.$column_data['subpart'].')'; + } + } + // Add the column list to the index create string + $index_string .= ' ('.$index_columns.')'; + if (!(($aindex = array_search($index_string, $indices)) === false)) { + unset($indices[$aindex]); + //echo "
    {$table}:
    Found index:".$index_string."
    \n"; + } + //else echo "
    {$table}:
    Did not find index:".$index_string."
    ".print_r($indices, true)."
    \n"; + } + } + + // For every remaining index specified for the table + foreach ( (array) $indices as $index ) { + // Push a query line into $cqueries that adds the index to that table + $cqueries[] = "ALTER TABLE {$table} ADD $index"; + $for_update[$table.'.'.$fieldname] = 'Added index '.$table.' '.$index; + } + + // Remove the original table creation query from processing + unset($cqueries[strtolower($table)]); + unset($for_update[strtolower($table)]); + } else { + // This table exists in the database, but not in the creation queries? + } + } + } + + $allqueries = array_merge($cqueries, $iqueries); + if ($execute) { + foreach ($allqueries as $query) { + //echo "
    ".print_r($query, true)."
    \n"; + $wpdb->query($query); + } + } + + return $for_update; +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.5.0 + */ +function make_db_current() { + global $wp_queries; + + $alterations = dbDelta($wp_queries); + echo "
      \n"; + foreach($alterations as $alteration) echo "
    1. $alteration
    2. \n"; + echo "
    \n"; +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.5.0 + */ +function make_db_current_silent() { + global $wp_queries; + + $alterations = dbDelta($wp_queries); +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.5.0 + * + * @param unknown_type $theme_name + * @param unknown_type $template + * @return unknown + */ +function make_site_theme_from_oldschool($theme_name, $template) { + $home_path = get_home_path(); + $site_dir = WP_CONTENT_DIR . "/themes/$template"; + + if (! file_exists("$home_path/index.php")) + return false; + + // Copy files from the old locations to the site theme. + // TODO: This does not copy arbitarary include dependencies. Only the + // standard WP files are copied. + $files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php'); + + foreach ($files as $oldfile => $newfile) { + if ($oldfile == 'index.php') + $oldpath = $home_path; + else + $oldpath = ABSPATH; + + if ($oldfile == 'index.php') { // Check to make sure it's not a new index + $index = implode('', file("$oldpath/$oldfile")); + if (strpos($index, 'WP_USE_THEMES') !== false) { + if (! @copy(WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME . '/index.php', "$site_dir/$newfile")) + return false; + continue; // Don't copy anything + } + } + + if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile")) + return false; + + chmod("$site_dir/$newfile", 0777); + + // Update the blog header include in each file. + $lines = explode("\n", implode('', file("$site_dir/$newfile"))); + if ($lines) { + $f = fopen("$site_dir/$newfile", 'w'); + + foreach ($lines as $line) { + if (preg_match('/require.*wp-blog-header/', $line)) + $line = '//' . $line; + + // Update stylesheet references. + $line = str_replace("/wp-layout.css", "", $line); + + // Update comments template inclusion. + $line = str_replace("", "", $line); + + fwrite($f, "{$line}\n"); + } + fclose($f); + } + } + + // Add a theme header. + $header = "/*\nTheme Name: $theme_name\nTheme URI: " . __get_option('siteurl') . "\nDescription: A theme automatically created by the update.\nVersion: 1.0\nAuthor: Moi\n*/\n"; + + $stylelines = file_get_contents("$site_dir/style.css"); + if ($stylelines) { + $f = fopen("$site_dir/style.css", 'w'); + + fwrite($f, $header); + fwrite($f, $stylelines); + fclose($f); + } + + return true; +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.5.0 + * + * @param unknown_type $theme_name + * @param unknown_type $template + * @return unknown + */ +function make_site_theme_from_default($theme_name, $template) { + $site_dir = WP_CONTENT_DIR . "/themes/$template"; + $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME; + + // Copy files from the default theme to the site theme. + //$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css'); + + $theme_dir = @ opendir($default_dir); + if ($theme_dir) { + while(($theme_file = readdir( $theme_dir )) !== false) { + if (is_dir("$default_dir/$theme_file")) + continue; + if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file")) + return; + chmod("$site_dir/$theme_file", 0777); + } + } + @closedir($theme_dir); + + // Rewrite the theme header. + $stylelines = explode("\n", implode('', file("$site_dir/style.css"))); + if ($stylelines) { + $f = fopen("$site_dir/style.css", 'w'); + + foreach ($stylelines as $line) { + if (strpos($line, 'Theme Name:') !== false) $line = 'Theme Name: ' . $theme_name; + elseif (strpos($line, 'Theme URI:') !== false) $line = 'Theme URI: ' . __get_option('url'); + elseif (strpos($line, 'Description:') !== false) $line = 'Description: Your theme.'; + elseif (strpos($line, 'Version:') !== false) $line = 'Version: 1'; + elseif (strpos($line, 'Author:') !== false) $line = 'Author: You'; + fwrite($f, $line . "\n"); + } + fclose($f); + } + + // Copy the images. + umask(0); + if (! mkdir("$site_dir/images", 0777)) { + return false; + } + + $images_dir = @ opendir("$default_dir/images"); + if ($images_dir) { + while(($image = readdir($images_dir)) !== false) { + if (is_dir("$default_dir/images/$image")) + continue; + if (! @copy("$default_dir/images/$image", "$site_dir/images/$image")) + return; + chmod("$site_dir/images/$image", 0777); + } + } + @closedir($images_dir); +} + +// Create a site theme from the default theme. +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 1.5.0 + * + * @return unknown + */ +function make_site_theme() { + // Name the theme after the blog. + $theme_name = __get_option('blogname'); + $template = sanitize_title($theme_name); + $site_dir = WP_CONTENT_DIR . "/themes/$template"; + + // If the theme already exists, nothing to do. + if ( is_dir($site_dir)) { + return false; + } + + // We must be able to write to the themes dir. + if (! is_writable(WP_CONTENT_DIR . "/themes")) { + return false; + } + + umask(0); + if (! mkdir($site_dir, 0777)) { + return false; + } + + if (file_exists(ABSPATH . 'wp-layout.css')) { + if (! make_site_theme_from_oldschool($theme_name, $template)) { + // TODO: rm -rf the site theme directory. + return false; + } + } else { + if (! make_site_theme_from_default($theme_name, $template)) + // TODO: rm -rf the site theme directory. + return false; + } + + // Make the new site theme active. + $current_template = __get_option('template'); + if ($current_template == WP_DEFAULT_THEME) { + update_option('template', $template); + update_option('stylesheet', $template); + } + return $template; +} + +/** + * Translate user level to user role name. + * + * @since 2.0.0 + * + * @param int $level User level. + * @return string User role name. + */ +function translate_level_to_role($level) { + switch ($level) { + case 10: + case 9: + case 8: + return 'administrator'; + case 7: + case 6: + case 5: + return 'editor'; + case 4: + case 3: + case 2: + return 'author'; + case 1: + return 'contributor'; + case 0: + return 'subscriber'; + } +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.1.0 + */ +function wp_check_mysql_version() { + global $wpdb; + $result = $wpdb->check_database_version(); + if ( is_wp_error( $result ) ) + die( $result->get_error_message() ); +} + +/** + * {@internal Missing Short Description}} + * + * {@internal Missing Long Description}} + * + * @since 2.2.0 + */ +function maybe_disable_automattic_widgets() { + $plugins = __get_option( 'active_plugins' ); + + foreach ( (array) $plugins as $plugin ) { + if ( basename( $plugin ) == 'widgets.php' ) { + array_splice( $plugins, array_search( $plugin, $plugins ), 1 ); + update_option( 'active_plugins', $plugins ); + break; + } + } +} + +/** + * Runs before the schema is upgraded. + * + * @since 2.9.0 + */ +function pre_schema_upgrade() { + global $wp_current_db_version, $wp_db_version, $wpdb; + + // Upgrade versions prior to 2.9 + if ( $wp_current_db_version < 11557 ) { + // Delete duplicate options. Keep the option with the highest option_id. + $wpdb->query("DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id"); + + // Drop the old primary key and add the new. + $wpdb->query("ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)"); + + // Drop the old option_name index. dbDelta() doesn't do the drop. + $wpdb->query("ALTER TABLE $wpdb->options DROP INDEX option_name"); + } + +} + +/** + * Install Network. + * + * @since 3.0.0 + * + */ +if ( !function_exists( 'install_network' ) ) : +function install_network() { + global $wpdb, $charset_collate; + $ms_queries = " +CREATE TABLE $wpdb->users ( + ID bigint(20) unsigned NOT NULL auto_increment, + user_login varchar(60) NOT NULL default '', + user_pass varchar(64) NOT NULL default '', + user_nicename varchar(50) NOT NULL default '', + user_email varchar(100) NOT NULL default '', + user_url varchar(100) NOT NULL default '', + user_registered datetime NOT NULL default '0000-00-00 00:00:00', + user_activation_key varchar(60) NOT NULL default '', + user_status int(11) NOT NULL default '0', + display_name varchar(250) NOT NULL default '', + spam tinyint(2) NOT NULL default '0', + deleted tinyint(2) NOT NULL default '0', + PRIMARY KEY (ID), + KEY user_login_key (user_login), + KEY user_nicename (user_nicename) +) $charset_collate; +CREATE TABLE $wpdb->blogs ( + blog_id bigint(20) NOT NULL auto_increment, + site_id bigint(20) NOT NULL default '0', + domain varchar(200) NOT NULL default '', + path varchar(100) NOT NULL default '', + registered datetime NOT NULL default '0000-00-00 00:00:00', + last_updated datetime NOT NULL default '0000-00-00 00:00:00', + public tinyint(2) NOT NULL default '1', + archived enum('0','1') NOT NULL default '0', + mature tinyint(2) NOT NULL default '0', + spam tinyint(2) NOT NULL default '0', + deleted tinyint(2) NOT NULL default '0', + lang_id int(11) NOT NULL default '0', + PRIMARY KEY (blog_id), + KEY domain (domain(50),path(5)), + KEY lang_id (lang_id) +) $charset_collate; +CREATE TABLE $wpdb->blog_versions ( + blog_id bigint(20) NOT NULL default '0', + db_version varchar(20) NOT NULL default '', + last_updated datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (blog_id), + KEY db_version (db_version) +) $charset_collate; +CREATE TABLE $wpdb->registration_log ( + ID bigint(20) NOT NULL auto_increment, + email varchar(255) NOT NULL default '', + IP varchar(30) NOT NULL default '', + blog_id bigint(20) NOT NULL default '0', + date_registered datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (ID), + KEY IP (IP) +) $charset_collate; +CREATE TABLE $wpdb->site ( + id bigint(20) NOT NULL auto_increment, + domain varchar(200) NOT NULL default '', + path varchar(100) NOT NULL default '', + PRIMARY KEY (id), + KEY domain (domain,path) +) $charset_collate; +CREATE TABLE $wpdb->sitemeta ( + meta_id bigint(20) NOT NULL auto_increment, + site_id bigint(20) NOT NULL default '0', + meta_key varchar(255) default NULL, + meta_value longtext, + PRIMARY KEY (meta_id), + KEY meta_key (meta_key), + KEY site_id (site_id) +) $charset_collate; +CREATE TABLE $wpdb->signups ( + domain varchar(200) NOT NULL default '', + path varchar(100) NOT NULL default '', + title longtext NOT NULL, + user_login varchar(60) NOT NULL default '', + user_email varchar(100) NOT NULL default '', + registered datetime NOT NULL default '0000-00-00 00:00:00', + activated datetime NOT NULL default '0000-00-00 00:00:00', + active tinyint(1) NOT NULL default '0', + activation_key varchar(50) NOT NULL default '', + meta longtext, + KEY activation_key (activation_key), + KEY domain (domain) +) $charset_collate; +"; +// now create tables + dbDelta( $ms_queries ); +} +endif; + +/** + * Install global terms. + * + * @since 3.0.0 + * + */ +if ( !function_exists( 'install_global_terms' ) ) : +function install_global_terms() { + global $wpdb, $charset_collate; + $ms_queries = " +CREATE TABLE $wpdb->sitecategories ( + cat_ID bigint(20) NOT NULL auto_increment, + cat_name varchar(55) NOT NULL default '', + category_nicename varchar(200) NOT NULL default '', + last_updated timestamp NOT NULL, + PRIMARY KEY (cat_ID), + KEY category_nicename (category_nicename), + KEY last_updated (last_updated) +) $charset_collate; +"; +// now create tables + dbDelta( $ms_queries ); +} +endif; +?> diff --git a/src/wp-admin/includes/user.php b/src/wp-admin/includes/user.php new file mode 100644 index 00000000..758c065a --- /dev/null +++ b/src/wp-admin/includes/user.php @@ -0,0 +1,383 @@ +role_objects[$new_role]->has_cap( 'edit_users' ) ) { + // If the new role isn't editable by the logged-in user die with error + $editable_roles = get_editable_roles(); + if ( empty( $editable_roles[$new_role] ) ) + wp_die(__('You can’t give users that role.')); + + $user = new WP_User( $user_id ); + $user->set_role( $new_role ); + } + } + } else { + add_action( 'user_register', 'add_user' ); // See above + return edit_user(); + } +} + +/** + * Edit user settings based on contents of $_POST + * + * Used on user-edit.php and profile.php to manage and process user options, passwords etc. + * + * @since 2.0 + * + * @param int $user_id Optional. User ID. + * @return int user id of the updated user + */ +function edit_user( $user_id = 0 ) { + global $wp_roles, $wpdb; + $user = new stdClass; + if ( $user_id ) { + $update = true; + $user->ID = (int) $user_id; + $userdata = get_userdata( $user_id ); + $user->user_login = $wpdb->escape( $userdata->user_login ); + } else { + $update = false; + } + + if ( !$update && isset( $_POST['user_login'] ) ) + $user->user_login = sanitize_user($_POST['user_login'], true); + + $pass1 = $pass2 = ''; + if ( isset( $_POST['pass1'] )) + $pass1 = $_POST['pass1']; + if ( isset( $_POST['pass2'] )) + $pass2 = $_POST['pass2']; + + if ( isset( $_POST['role'] ) && current_user_can( 'edit_users' ) ) { + $new_role = sanitize_text_field( $_POST['role'] ); + $potential_role = isset($wp_roles->role_objects[$new_role]) ? $wp_roles->role_objects[$new_role] : false; + // Don't let anyone with 'edit_users' (admins) edit their own role to something without it. + // Multisite super admins can freely edit their blog roles -- they possess all caps. + if ( ( is_multisite() && current_user_can( 'manage_sites' ) ) || $user_id != get_current_user_id() || ($potential_role && $potential_role->has_cap( 'edit_users' ) ) ) + $user->role = $new_role; + + // If the new role isn't editable by the logged-in user die with error + $editable_roles = get_editable_roles(); + if ( ! empty( $new_role ) && empty( $editable_roles[$new_role] ) ) + wp_die(__('You can’t give users that role.')); + } + + if ( isset( $_POST['email'] )) + $user->user_email = sanitize_text_field( $_POST['email'] ); + if ( isset( $_POST['url'] ) ) { + if ( empty ( $_POST['url'] ) || $_POST['url'] == 'http://' ) { + $user->user_url = ''; + } else { + $user->user_url = esc_url_raw( $_POST['url'] ); + $user->user_url = preg_match('/^(https?|ftps?|mailto|news|irc|gopher|nntp|feed|telnet):/is', $user->user_url) ? $user->user_url : 'http://'.$user->user_url; + } + } + if ( isset( $_POST['first_name'] ) ) + $user->first_name = sanitize_text_field( $_POST['first_name'] ); + if ( isset( $_POST['last_name'] ) ) + $user->last_name = sanitize_text_field( $_POST['last_name'] ); + if ( isset( $_POST['nickname'] ) ) + $user->nickname = sanitize_text_field( $_POST['nickname'] ); + if ( isset( $_POST['display_name'] ) ) + $user->display_name = sanitize_text_field( $_POST['display_name'] ); + + if ( isset( $_POST['description'] ) ) + $user->description = trim( $_POST['description'] ); + + foreach ( _wp_get_user_contactmethods( $user ) as $method => $name ) { + if ( isset( $_POST[$method] )) + $user->$method = sanitize_text_field( $_POST[$method] ); + } + + if ( $update ) { + $user->rich_editing = isset( $_POST['rich_editing'] ) && 'false' == $_POST['rich_editing'] ? 'false' : 'true'; + $user->admin_color = isset( $_POST['admin_color'] ) ? sanitize_text_field( $_POST['admin_color'] ) : 'fresh'; + $user->show_admin_bar_front = isset( $_POST['admin_bar_front'] ) ? 'true' : 'false'; + $user->show_admin_bar_admin = isset( $_POST['admin_bar_admin'] ) ? 'true' : 'false'; + } + + $user->comment_shortcuts = isset( $_POST['comment_shortcuts'] ) && 'true' == $_POST['comment_shortcuts'] ? 'true' : ''; + + $user->use_ssl = 0; + if ( !empty($_POST['use_ssl']) ) + $user->use_ssl = 1; + + $errors = new WP_Error(); + + /* checking that username has been typed */ + if ( $user->user_login == '' ) + $errors->add( 'user_login', __( 'ERROR: Please enter a username.' )); + + /* checking the password has been typed twice */ + do_action_ref_array( 'check_passwords', array ( $user->user_login, & $pass1, & $pass2 )); + + if ( $update ) { + if ( empty($pass1) && !empty($pass2) ) + $errors->add( 'pass', __( 'ERROR: You entered your new password only once.' ), array( 'form-field' => 'pass1' ) ); + elseif ( !empty($pass1) && empty($pass2) ) + $errors->add( 'pass', __( 'ERROR: You entered your new password only once.' ), array( 'form-field' => 'pass2' ) ); + } else { + if ( empty($pass1) ) + $errors->add( 'pass', __( 'ERROR: Please enter your password.' ), array( 'form-field' => 'pass1' ) ); + elseif ( empty($pass2) ) + $errors->add( 'pass', __( 'ERROR: Please enter your password twice.' ), array( 'form-field' => 'pass2' ) ); + } + + /* Check for "\" in password */ + if ( false !== strpos( stripslashes($pass1), "\\" ) ) + $errors->add( 'pass', __( 'ERROR: Passwords may not contain the character "\\".' ), array( 'form-field' => 'pass1' ) ); + + /* checking the password has been typed twice the same */ + if ( $pass1 != $pass2 ) + $errors->add( 'pass', __( 'ERROR: Please enter the same password in the two password fields.' ), array( 'form-field' => 'pass1' ) ); + + if ( !empty( $pass1 ) ) + $user->user_pass = $pass1; + + if ( !$update && isset( $_POST['user_login'] ) && !validate_username( $_POST['user_login'] ) ) + $errors->add( 'user_login', __( 'ERROR: This username is invalid because it uses illegal characters. Please enter a valid username.' )); + + if ( !$update && username_exists( $user->user_login ) ) + $errors->add( 'user_login', __( 'ERROR: This username is already registered. Please choose another one.' )); + + /* checking e-mail address */ + if ( empty( $user->user_email ) ) { + $errors->add( 'empty_email', __( 'ERROR: Please enter an e-mail address.' ), array( 'form-field' => 'email' ) ); + } elseif ( !is_email( $user->user_email ) ) { + $errors->add( 'invalid_email', __( 'ERROR: The e-mail address isn’t correct.' ), array( 'form-field' => 'email' ) ); + } elseif ( ( $owner_id = email_exists($user->user_email) ) && ( !$update || ( $owner_id != $user->ID ) ) ) { + $errors->add( 'email_exists', __('ERROR: This email is already registered, please choose another one.'), array( 'form-field' => 'email' ) ); + } + + // Allow plugins to return their own errors. + do_action_ref_array('user_profile_update_errors', array ( &$errors, $update, &$user ) ); + + if ( $errors->get_error_codes() ) + return $errors; + + if ( $update ) { + $user_id = wp_update_user( get_object_vars( $user ) ); + } else { + $user_id = wp_insert_user( get_object_vars( $user ) ); + wp_new_user_notification( $user_id, isset($_POST['send_password']) ? $pass1 : '' ); + } + return $user_id; +} + +/** + * Fetch a filtered list of user roles that the current user is + * allowed to edit. + * + * Simple function who's main purpose is to allow filtering of the + * list of roles in the $wp_roles object so that plugins can remove + * innappropriate ones depending on the situation or user making edits. + * Specifically because without filtering anyone with the edit_users + * capability can edit others to be administrators, even if they are + * only editors or authors. This filter allows admins to delegate + * user management. + * + * @since 2.8 + * + * @return unknown + */ +function get_editable_roles() { + global $wp_roles; + + $all_roles = $wp_roles->roles; + $editable_roles = apply_filters('editable_roles', $all_roles); + + return $editable_roles; +} + +/** + * Retrieve user data and filter it. + * + * @since 2.0.5 + * + * @param int $user_id User ID. + * @return object WP_User object with user data. + */ +function get_user_to_edit( $user_id ) { + $user = new WP_User( $user_id ); + + $user_contactmethods = _wp_get_user_contactmethods( $user ); + foreach ($user_contactmethods as $method => $name) { + if ( empty( $user->{$method} ) ) + $user->{$method} = ''; + } + + if ( empty($user->description) ) + $user->description = ''; + + $user = sanitize_user_object($user, 'edit'); + + return $user; +} + +/** + * Retrieve the user's drafts. + * + * @since 2.0.0 + * + * @param int $user_id User ID. + * @return array + */ +function get_users_drafts( $user_id ) { + global $wpdb; + $query = $wpdb->prepare("SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'draft' AND post_author = %d ORDER BY post_modified DESC", $user_id); + $query = apply_filters('get_users_drafts', $query); + return $wpdb->get_results( $query ); +} + +/** + * Remove user and optionally reassign posts and links to another user. + * + * If the $reassign parameter is not assigned to an User ID, then all posts will + * be deleted of that user. The action 'delete_user' that is passed the User ID + * being deleted will be run after the posts are either reassigned or deleted. + * The user meta will also be deleted that are for that User ID. + * + * @since 2.0.0 + * + * @param int $id User ID. + * @param int $reassign Optional. Reassign posts and links to new User ID. + * @return bool True when finished. + */ +function wp_delete_user( $id, $reassign = 'novalue' ) { + global $wpdb; + + $id = (int) $id; + + // allow for transaction statement + do_action('delete_user', $id); + + if ( 'novalue' === $reassign || null === $reassign ) { + $post_ids = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id) ); + + if ( $post_ids ) { + foreach ( $post_ids as $post_id ) + wp_delete_post($post_id); + } + + // Clean links + $link_ids = $wpdb->get_col( $wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id) ); + + if ( $link_ids ) { + foreach ( $link_ids as $link_id ) + wp_delete_link($link_id); + } + } else { + $reassign = (int) $reassign; + $wpdb->update( $wpdb->posts, array('post_author' => $reassign), array('post_author' => $id) ); + $wpdb->update( $wpdb->links, array('link_owner' => $reassign), array('link_owner' => $id) ); + } + + clean_user_cache($id); + + // FINALLY, delete user + if ( !is_multisite() ) { + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d", $id) ); + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->users WHERE ID = %d", $id) ); + } else { + $level_key = $wpdb->get_blog_prefix() . 'capabilities'; // wpmu site admins don't have user_levels + $wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = $id AND meta_key = '{$level_key}'"); + } + + // allow for commit transaction + do_action('deleted_user', $id); + + return true; +} + +/** + * Remove all capabilities from user. + * + * @since 2.1.0 + * + * @param int $id User ID. + */ +function wp_revoke_user($id) { + $id = (int) $id; + + $user = new WP_User($id); + $user->remove_all_caps(); +} + +add_action('admin_init', 'default_password_nag_handler'); +/** + * @since 2.8.0 + */ +function default_password_nag_handler($errors = false) { + global $user_ID; + if ( ! get_user_option('default_password_nag') ) //Short circuit it. + return; + + //get_user_setting = JS saved UI setting. else no-js-falback code. + if ( 'hide' == get_user_setting('default_password_nag') || isset($_GET['default_password_nag']) && '0' == $_GET['default_password_nag'] ) { + delete_user_setting('default_password_nag'); + update_user_option($user_ID, 'default_password_nag', false, true); + } +} + +add_action('profile_update', 'default_password_nag_edit_user', 10, 2); +/** + * @since 2.8.0 + */ +function default_password_nag_edit_user($user_ID, $old_data) { + if ( ! get_user_option('default_password_nag', $user_ID) ) //Short circuit it. + return; + + $new_data = get_userdata($user_ID); + + if ( $new_data->user_pass != $old_data->user_pass ) { //Remove the nag if the password has been changed. + delete_user_setting('default_password_nag', $user_ID); + update_user_option($user_ID, 'default_password_nag', false, true); + } +} + +add_action('admin_notices', 'default_password_nag'); +/** + * @since 2.8.0 + */ +function default_password_nag() { + global $pagenow; + if ( 'profile.php' == $pagenow || ! get_user_option('default_password_nag') ) //Short circuit it. + return; + + echo '
    '; + echo '

    '; + echo '' . __('Notice:') . ' '; + _e('You’re using the auto-generated password for your account. Would you like to change it to something easier to remember?'); + echo '

    '; + printf( '' . __('Yes, take me to my profile page') . ' | ', admin_url('profile.php') . '#password' ); + printf( '' . __('No thanks, do not remind me again') . '', '?default_password_nag=0' ); + echo '

    '; +} + +?> diff --git a/src/wp-admin/includes/widgets.php b/src/wp-admin/includes/widgets.php new file mode 100644 index 00000000..a591c60d --- /dev/null +++ b/src/wp-admin/includes/widgets.php @@ -0,0 +1,225 @@ + $widget['id'], 'widget_name' => $widget['name'], '_display' => 'template' ); + + if ( isset($wp_registered_widget_controls[$widget['id']]['id_base']) && isset($widget['params'][0]['number']) ) { + $id_base = $wp_registered_widget_controls[$widget['id']]['id_base']; + $args['_temp_id'] = "$id_base-__i__"; + $args['_multi_num'] = next_widget_id_number($id_base); + $args['_add'] = 'multi'; + } else { + $args['_add'] = 'single'; + if ( $sidebar ) + $args['_hide'] = '1'; + } + + $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); + call_user_func_array( 'wp_widget_control', $args ); + } +} + +/** + * Callback to sort array by a 'name' key. + * + * @since 3.1.0 + * @access private + */ +function _sort_name_callback( $a, $b ) { + return strnatcasecmp( $a['name'], $b['name'] ); +} + +/** + * Show the widgets and their settings for a sidebar. + * Used in the the admin widget config screen. + * + * @since 2.5.0 + * + * @param string $sidebar id slug of the sidebar + */ +function wp_list_widget_controls( $sidebar ) { + add_filter( 'dynamic_sidebar_params', 'wp_list_widget_controls_dynamic_sidebar' ); + + echo "
    \n"; + + $description = wp_sidebar_description( $sidebar ); + + if ( !empty( $description ) ) { + echo "\n"; + } + + dynamic_sidebar( $sidebar ); + echo "
    \n"; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @param array $params + * @return array + */ +function wp_list_widget_controls_dynamic_sidebar( $params ) { + global $wp_registered_widgets; + static $i = 0; + $i++; + + $widget_id = $params[0]['widget_id']; + $id = isset($params[0]['_temp_id']) ? $params[0]['_temp_id'] : $widget_id; + $hidden = isset($params[0]['_hide']) ? ' style="display:none;"' : ''; + + $params[0]['before_widget'] = "
    "; + $params[0]['after_widget'] = "
    "; + $params[0]['before_title'] = "%BEG_OF_TITLE%"; // deprecated + $params[0]['after_title'] = "%END_OF_TITLE%"; // deprecated + if ( is_callable( $wp_registered_widgets[$widget_id]['callback'] ) ) { + $wp_registered_widgets[$widget_id]['_callback'] = $wp_registered_widgets[$widget_id]['callback']; + $wp_registered_widgets[$widget_id]['callback'] = 'wp_widget_control'; + } + + return $params; +} + +function next_widget_id_number($id_base) { + global $wp_registered_widgets; + $number = 1; + + foreach ( $wp_registered_widgets as $widget_id => $widget ) { + if ( preg_match( '/' . $id_base . '-([0-9]+)$/', $widget_id, $matches ) ) + $number = max($number, $matches[1]); + } + $number++; + + return $number; +} + +/** + * Meta widget used to display the control form for a widget. + * + * Called from dynamic_sidebar(). + * + * @since 2.5.0 + * + * @param array $sidebar_args + * @return array + */ +function wp_widget_control( $sidebar_args ) { + global $wp_registered_widgets, $wp_registered_widget_controls, $sidebars_widgets; + + $widget_id = $sidebar_args['widget_id']; + $sidebar_id = isset($sidebar_args['id']) ? $sidebar_args['id'] : false; + $key = $sidebar_id ? array_search( $widget_id, $sidebars_widgets[$sidebar_id] ) : '-1'; // position of widget in sidebar + $control = isset($wp_registered_widget_controls[$widget_id]) ? $wp_registered_widget_controls[$widget_id] : array(); + $widget = $wp_registered_widgets[$widget_id]; + + $id_format = $widget['id']; + $widget_number = isset($control['params'][0]['number']) ? $control['params'][0]['number'] : ''; + $id_base = isset($control['id_base']) ? $control['id_base'] : $widget_id; + $multi_number = isset($sidebar_args['_multi_num']) ? $sidebar_args['_multi_num'] : ''; + $add_new = isset($sidebar_args['_add']) ? $sidebar_args['_add'] : ''; + + $query_arg = array( 'editwidget' => $widget['id'] ); + if ( $add_new ) { + $query_arg['addnew'] = 1; + if ( $multi_number ) { + $query_arg['num'] = $multi_number; + $query_arg['base'] = $id_base; + } + } else { + $query_arg['sidebar'] = $sidebar_id; + $query_arg['key'] = $key; + } + + // We aren't showing a widget control, we're outputing a template for a mult-widget control + if ( isset($sidebar_args['_display']) && 'template' == $sidebar_args['_display'] && $widget_number ) { + // number == -1 implies a template where id numbers are replaced by a generic '__i__' + $control['params'][0]['number'] = -1; + // with id_base widget id's are constructed like {$id_base}-{$id_number} + if ( isset($control['id_base']) ) + $id_format = $control['id_base'] . '-__i__'; + } + + $wp_registered_widgets[$widget_id]['callback'] = $wp_registered_widgets[$widget_id]['_callback']; + unset($wp_registered_widgets[$widget_id]['_callback']); + + $widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) ); + $has_form = 'noform'; + + echo $sidebar_args['before_widget']; ?> +
    +
    + + +
    +

    +
    + +
    +
    +
    +" . __('There are no options for this widget.') . "

    \n"; ?> +
    + + + + + + + + +
    +
    + | + +
    +
    + + +
    +
    +
    +
    +
    + +
    + +
    + \ No newline at end of file diff --git a/src/wp-admin/index.php b/src/wp-admin/index.php new file mode 100644 index 00000000..748141e0 --- /dev/null +++ b/src/wp-admin/index.php @@ -0,0 +1,70 @@ + 4, 'default' => 1) ); +else + add_screen_option('layout_columns', array('max' => 4, 'default' => 2) ); + +add_contextual_help($current_screen, + + '

    ' . __( 'Welcome to your WordPress Dashboard! You will find helpful tips in the Help tab of each screen to assist you as you get to know the application.' ) . '

    ' . + '

    ' . __( 'The Admin Bar at the top, new in 3.1, provides quick access to common tasks when you are viewing your site.' ) . '

    ' . + '

    ' . __( 'The left-hand navigation menu provides links to the administration screens in your WordPress application. You can expand or collapse navigation sections by clicking on the arrow that appears on the right side of each navigation item when you hover over it. You can also minimize the navigation menu to a narrow icon strip by clicking on the faint separator lines between the Dashboard and Posts sections, or between Comments and Appearance; when minimized, the submenu items will be displayed on hover.' ) . '

    ' . + '

    ' . __( 'You can configure your dashboard by choosing which boxes, or modules, to display in the work area, how many columns to display them in, and where each box should be placed. You can hide/show boxes and select the number of columns in the Screen Options tab. To rearrange the boxes, drag and drop by clicking on the title bar of the selected box and releasing when you see a gray dotted-line rectangle appear in the location you want to place the box. You can also expand or collapse each box by clicking once on the title bar of the box. In addition, some boxes are configurable, and will show a “Configure” link in the title bar when you hover over it.' ) . '

    ' . + '

    ' . __( 'The boxes on your Dashboard screen are:' ) . '

    ' . + '

    ' . __( 'Right Now - Displays a summary of the content on your site and identifies which theme and version of WordPress you are using.' ) . '

    ' . + '

    ' . __( 'Recent Comments - Shows the most recent comments on your posts (configurable, up to 30) and allows you to moderate them.' ) . '

    ' . + '

    ' . __( 'Incoming Links - Shows links to your site found by Google Blog Search.' ) . '

    ' . + '

    ' . __( 'QuickPress - Allows you to create a new post and either publish it or save it as a draft.' ) . '

    ' . + '

    ' . __( 'Recent Drafts - Displays links to the 5 most recent draft posts you’ve started.' ) . '

    ' . + '

    ' . __( 'WordPress Development Blog - Come here for the latest scoop.' ) . '

    ' . + '

    ' . __( 'Other WordPress News - Shows the feed from WordPress Planet. You can configure it to show a different feed of your choosing.' ) . '

    ' . + '

    ' . __( 'Plugins - Features the most popular, newest, and recently updated plugins from the WordPress.org Plugin Directory.' ) . '

    ' . + '

    ' . __( 'For more information:' ) . '

    ' . + '

    ' . __( 'Documentation on Dashboard' ) . '

    ' . + '

    ' . __( 'Support Forums' ) . '

    ' +); + +include (ABSPATH . 'wp-admin/admin-header.php'); + +$today = current_time('mysql', 1); +?> + +
    + +

    + +
    + + + +
    +
    + +
    + + diff --git a/src/wp-admin/install-helper.php b/src/wp-admin/install-helper.php new file mode 100644 index 00000000..2970b7cb --- /dev/null +++ b/src/wp-admin/install-helper.php @@ -0,0 +1,217 @@ + + * check_column('wp_links', 'link_description', 'mediumtext'); + * if (check_column($wpdb->comments, 'comment_author', 'tinytext')) + * echo "ok\n"; + * + * $error_count = 0; + * $tablename = $wpdb->links; + * // check the column + * if (!check_column($wpdb->links, 'link_description', 'varchar(255)')) { + * $ddl = "ALTER TABLE $wpdb->links MODIFY COLUMN link_description varchar(255) NOT NULL DEFAULT '' "; + * $q = $wpdb->query($ddl); + * } + * + * if (check_column($wpdb->links, 'link_description', 'varchar(255)')) { + * $res .= $tablename . ' - ok
    '; + * } else { + * $res .= 'There was a problem with ' . $tablename . '
    '; + * ++$error_count; + * } + * + * + * @package WordPress + * @subpackage Plugin + */ + +/** Load WordPress Bootstrap */ +require_once(dirname(dirname(__FILE__)).'/wp-load.php'); + +/** + * Turn debugging on or off. + * @global bool|int $debug + * @name $debug + * @var bool|int + * @since 1.0.0 + */ +$debug = 0; + +if ( ! function_exists('maybe_create_table') ) : +/** + * Create database table, if it doesn't already exist. + * + * @since 1.0.0 + * @package WordPress + * @subpackage Plugin + * @uses $wpdb + * + * @param string $table_name Database table name. + * @param string $create_ddl Create database table SQL. + * @return bool False on error, true if already exists or success. + */ +function maybe_create_table($table_name, $create_ddl) { + global $wpdb; + foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) { + if ($table == $table_name) { + return true; + } + } + //didn't find it try to create it. + $wpdb->query($create_ddl); + // we cannot directly tell that whether this succeeded! + foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) { + if ($table == $table_name) { + return true; + } + } + return false; +} +endif; + +if ( ! function_exists('maybe_add_column') ) : +/** + * Add column to database table, if column doesn't already exist in table. + * + * @since 1.0.0 + * @package WordPress + * @subpackage Plugin + * @uses $wpdb + * @uses $debug + * + * @param string $table_name Database table name + * @param string $column_name Table column name + * @param string $create_ddl SQL to add column to table. + * @return bool False on failure. True, if already exists or was successful. + */ +function maybe_add_column($table_name, $column_name, $create_ddl) { + global $wpdb, $debug; + foreach ($wpdb->get_col("DESC $table_name",0) as $column ) { + if ($debug) echo("checking $column == $column_name
    "); + + if ($column == $column_name) { + return true; + } + } + //didn't find it try to create it. + $wpdb->query($create_ddl); + // we cannot directly tell that whether this succeeded! + foreach ($wpdb->get_col("DESC $table_name",0) as $column ) { + if ($column == $column_name) { + return true; + } + } + return false; +} +endif; + +/** + * Drop column from database table, if it exists. + * + * @since 1.0.0 + * @package WordPress + * @subpackage Plugin + * @uses $wpdb + * + * @param string $table_name Table name + * @param string $column_name Column name + * @param string $drop_ddl SQL statement to drop column. + * @return bool False on failure, true on success or doesn't exist. + */ +function maybe_drop_column($table_name, $column_name, $drop_ddl) { + global $wpdb; + foreach ($wpdb->get_col("DESC $table_name",0) as $column ) { + if ($column == $column_name) { + //found it try to drop it. + $wpdb->query($drop_ddl); + // we cannot directly tell that whether this succeeded! + foreach ($wpdb->get_col("DESC $table_name",0) as $column ) { + if ($column == $column_name) { + return false; + } + } + } + } + // else didn't find it + return true; +} + +/** + * Check column matches criteria. + * + * Uses the SQL DESC for retrieving the table info for the column. It will help + * understand the parameters, if you do more research on what column information + * is returned by the SQL statement. Pass in null to skip checking that + * criteria. + * + * Column names returned from DESC table are case sensitive and are listed: + * Field + * Type + * Null + * Key + * Default + * Extra + * + * @since 1.0.0 + * @package WordPress + * @subpackage Plugin + * + * @param string $table_name Table name + * @param string $col_name Column name + * @param string $col_type Column type + * @param bool $is_null Optional. Check is null. + * @param mixed $key Optional. Key info. + * @param mixed $default Optional. Default value. + * @param mixed $extra Optional. Extra value. + * @return bool True, if matches. False, if not matching. + */ +function check_column($table_name, $col_name, $col_type, $is_null = null, $key = null, $default = null, $extra = null) { + global $wpdb, $debug; + $diffs = 0; + $results = $wpdb->get_results("DESC $table_name"); + + foreach ($results as $row ) { + if ($debug > 1) print_r($row); + + if ($row->Field == $col_name) { + // got our column, check the params + if ($debug) echo ("checking $row->Type against $col_type\n"); + if (($col_type != null) && ($row->Type != $col_type)) { + ++$diffs; + } + if (($is_null != null) && ($row->Null != $is_null)) { + ++$diffs; + } + if (($key != null) && ($row->Key != $key)) { + ++$diffs; + } + if (($default != null) && ($row->Default != $default)) { + ++$diffs; + } + if (($extra != null) && ($row->Extra != $extra)) { + ++$diffs; + } + if ($diffs > 0) { + if ($debug) echo ("diffs = $diffs returning false\n"); + return false; + } + return true; + } // end if found our column + } + return false; +} + +?> \ No newline at end of file diff --git a/src/wp-admin/install.php b/src/wp-admin/install.php new file mode 100644 index 00000000..0b65f523 --- /dev/null +++ b/src/wp-admin/install.php @@ -0,0 +1,264 @@ + + + + + + Error: PHP is not running + + +

    WordPress

    +

    Error: PHP is not running

    +

    WordPress requires that your web server is running PHP. Your server does not have PHP installed, or PHP is turned off.

    + + + + +> + + + <?php _e( 'WordPress › Installation' ); ?> + + + +

    WordPress

    + +get_var("SHOW TABLES LIKE '$wpdb->users'") != null ); + + // Ensure that Blogs appear in search engines by default + $blog_public = 1; + if ( ! empty( $_POST ) ) + $blog_public = isset( $_POST['blog_public'] ); + + $weblog_title = isset( $_POST['weblog_title'] ) ? trim( stripslashes( $_POST['weblog_title'] ) ) : ''; + $user_name = isset($_POST['user_name']) ? trim( stripslashes( $_POST['user_name'] ) ) : 'admin'; + $admin_password = isset($_POST['admin_password']) ? trim( stripslashes( $_POST['admin_password'] ) ) : ''; + $admin_email = isset( $_POST['admin_email'] ) ? trim( stripslashes( $_POST['admin_email'] ) ) : ''; + + if ( ! is_null( $error ) ) { +?> +

    ERROR: %s' ), $error ); ?>

    + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +

    + +
    + +

    +
    + +

    +
    +

    +
    +

    +

    +
    +' . __( 'Already Installed' ) . '

    ' . __( 'You appear to have already installed WordPress. To reinstall please clear your old database tables first.' ) . '

    ' . __('Log In') . '

    ' ); +} + +$php_version = phpversion(); +$mysql_version = $wpdb->db_version(); +$php_compat = version_compare( $php_version, $required_php_version, '>=' ); +$mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' ) || file_exists( WP_CONTENT_DIR . '/db.php' ); + +if ( !$mysql_compat && !$php_compat ) + $compat = sprintf( __('You cannot install because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.'), $wp_version, $required_php_version, $required_mysql_version, $php_version, $mysql_version ); +elseif ( !$php_compat ) + $compat = sprintf( __('You cannot install because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.'), $wp_version, $required_php_version, $php_version ); +elseif ( !$mysql_compat ) + $compat = sprintf( __('You cannot install because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.'), $wp_version, $required_mysql_version, $mysql_version ); + +if ( !$mysql_compat || !$php_compat ) { + display_header(); + die('

    ' . __('Insufficient Requirements') . '

    ' . $compat . '

    '); +} + +switch($step) { + case 0: // Step 1 + case 1: // Step 1, direct link. + display_header(); +?> +

    +

    ReadMe documentation at your leisure. Otherwise, just fill in the information below and you’ll be on your way to using the most extendable and powerful personal publishing platform in the world.' ), '../readme.html' ); ?>

    + +

    +

    + +error ) ) + wp_die( $wpdb->error->get_error_message() ); + + display_header(); + // Fill in the data we gathered + $weblog_title = isset( $_POST['weblog_title'] ) ? trim( stripslashes( $_POST['weblog_title'] ) ) : ''; + $user_name = isset($_POST['user_name']) ? trim( stripslashes( $_POST['user_name'] ) ) : 'admin'; + $admin_password = isset($_POST['admin_password']) ? $_POST['admin_password'] : ''; + $admin_password_check = isset($_POST['admin_password2']) ? $_POST['admin_password2'] : ''; + $admin_email = isset( $_POST['admin_email'] ) ?trim( stripslashes( $_POST['admin_email'] ) ) : ''; + $public = isset( $_POST['blog_public'] ) ? (int) $_POST['blog_public'] : 0; + // check e-mail address + $error = false; + if ( empty( $user_name ) ) { + // TODO: poka-yoke + display_setup_form( __('you must provide a valid username.') ); + $error = true; + } elseif ( $user_name != sanitize_user( $user_name, true ) ) { + display_setup_form( __('the username you provided has invalid characters.') ); + $error = true; + } elseif ( $admin_password != $admin_password_check ) { + // TODO: poka-yoke + display_setup_form( __( 'your passwords do not match. Please try again' ) ); + $error = true; + } else if ( empty( $admin_email ) ) { + // TODO: poka-yoke + display_setup_form( __( 'you must provide an e-mail address.' ) ); + $error = true; + } elseif ( ! is_email( $admin_email ) ) { + // TODO: poka-yoke + display_setup_form( __( 'that isn’t a valid e-mail address. E-mail addresses look like: username@example.com' ) ); + $error = true; + } + + if ( $error === false ) { + $wpdb->show_errors(); + $result = wp_install($weblog_title, $user_name, $admin_email, $public, '', $admin_password); + extract( $result, EXTR_SKIP ); +?> + +

    + +

    + + + + + + + + + + +
    '. esc_html($password) .'
    '; + echo "

    $password_message

    "; ?> +
    + +

    + + + + + + + + + + diff --git a/src/wp-admin/js/cat.dev.js b/src/wp-admin/js/cat.dev.js new file mode 100644 index 00000000..cbc29007 --- /dev/null +++ b/src/wp-admin/js/cat.dev.js @@ -0,0 +1,5 @@ +jQuery(document).ready( function($) { + var myConfirm = function() { return '' !== $('#newcat').val(); }; + $('#jaxcat').prepend('' + catL10n.how + ''); + $('#categorychecklist').wpList( { alt: '', response: 'cat-ajax-response', confirm: myConfirm } ); +} ); diff --git a/src/wp-admin/js/cat.js b/src/wp-admin/js/cat.js new file mode 100644 index 00000000..deee8c47 --- /dev/null +++ b/src/wp-admin/js/cat.js @@ -0,0 +1 @@ +jQuery(document).ready(function(b){var a=function(){return""!==b("#newcat").val()};b("#jaxcat").prepend(''+catL10n.how+'');b("#categorychecklist").wpList({alt:"",response:"cat-ajax-response",confirm:a})}); \ No newline at end of file diff --git a/src/wp-admin/js/categories.dev.js b/src/wp-admin/js/categories.dev.js new file mode 100644 index 00000000..cc58eb4a --- /dev/null +++ b/src/wp-admin/js/categories.dev.js @@ -0,0 +1,34 @@ +jQuery(document).ready(function($) { + var options = false, addAfter, delBefore, delAfter; + if ( document.forms['addcat'].category_parent ) + options = document.forms['addcat'].category_parent.options; + + addAfter = function( r, settings ) { + var name, id; + + name = $("" + $('name', r).text() + "").text(); + id = $('cat', r).attr('id'); + options[options.length] = new Option(name, id); + } + + delAfter = function( r, settings ) { + var id = $('cat', r).attr('id'), o; + for ( o = 0; o < options.length; o++ ) + if ( id == options[o].value ) + options[o] = null; + } + + delBefore = function(s) { + if ( 'undefined' != showNotice ) + return showNotice.warn() ? s : false; + + return s; + } + + if ( options ) + $('#the-list').wpList( { addAfter: addAfter, delBefore: delBefore, delAfter: delAfter } ); + else + $('#the-list').wpList({ delBefore: delBefore }); + + $('.delete a[class^="delete"]').live('click', function(){return false;}); +}); diff --git a/src/wp-admin/js/categories.js b/src/wp-admin/js/categories.js new file mode 100644 index 00000000..45c2358a --- /dev/null +++ b/src/wp-admin/js/categories.js @@ -0,0 +1 @@ +jQuery(document).ready(function(d){var b=false,e,c,a;if(document.forms.addcat.category_parent){b=document.forms.addcat.category_parent.options}e=function(h,g){var f,i;f=d(""+d("name",h).text()+"").text();i=d("cat",h).attr("id");b[b.length]=new Option(f,i)};a=function(g,f){var i=d("cat",g).attr("id"),h;for(h=0;h' + + $( '#mm option[value=' + mm + ']' ).text() + ' ' + + jj + ', ' + + aa + ' @ ' + + hh + ':' + + mn + '
    ' + ); + return false; + }); +}); \ No newline at end of file diff --git a/src/wp-admin/js/comment.js b/src/wp-admin/js/comment.js new file mode 100644 index 00000000..c05cb608 --- /dev/null +++ b/src/wp-admin/js/comment.js @@ -0,0 +1 @@ +jQuery(document).ready(function(b){var a=b("#timestamp").html();b(".edit-timestamp").click(function(){if(b("#timestampdiv").is(":hidden")){b("#timestampdiv").slideDown("normal");b(".edit-timestamp").hide()}return false});b(".cancel-timestamp").click(function(){b("#timestampdiv").slideUp("normal");b("#mm").val(b("#hidden_mm").val());b("#jj").val(b("#hidden_jj").val());b("#aa").val(b("#hidden_aa").val());b("#hh").val(b("#hidden_hh").val());b("#mn").val(b("#hidden_mn").val());b("#timestamp").html(a);b(".edit-timestamp").show();return false});b(".save-timestamp").click(function(){var g=b("#aa").val(),h=b("#mm").val(),d=b("#jj").val(),c=b("#hh").val(),f=b("#mn").val(),e=new Date(g,h-1,d,c,f);if(e.getFullYear()!=g||(1+e.getMonth())!=h||e.getDate()!=d||e.getMinutes()!=f){b(".timestamp-wrap","#timestampdiv").addClass("form-invalid");return false}else{b(".timestamp-wrap","#timestampdiv").removeClass("form-invalid")}b("#timestampdiv").slideUp("normal");b(".edit-timestamp").show();b("#timestamp").html(commentL10n.submittedOn+" "+b("#mm option[value="+h+"]").text()+" "+d+", "+g+" @ "+c+":"+f+" ");return false})}); \ No newline at end of file diff --git a/src/wp-admin/js/common.dev.js b/src/wp-admin/js/common.dev.js new file mode 100644 index 00000000..46b4b247 --- /dev/null +++ b/src/wp-admin/js/common.dev.js @@ -0,0 +1,334 @@ +var showNotice, adminMenu, columns, validateForm; +(function($){ +// sidebar admin menu +adminMenu = { + init : function() { + var menu = $('#adminmenu'); + + $('.wp-menu-toggle', menu).each( function() { + var t = $(this), sub = t.siblings('.wp-submenu'); + if ( sub.length ) + t.click(function(){ adminMenu.toggle( sub ); }); + else + t.hide(); + }); + + this.favorites(); + + $('.separator', menu).click(function(){ + if ( $('body').hasClass('folded') ) { + adminMenu.fold(1); + deleteUserSetting( 'mfold' ); + } else { + adminMenu.fold(); + setUserSetting( 'mfold', 'f' ); + } + return false; + }); + + if ( $('body').hasClass('folded') ) + this.fold(); + + this.restoreMenuState(); + }, + + restoreMenuState : function() { + $('li.wp-has-submenu', '#adminmenu').each(function(i, e) { + var v = getUserSetting( 'm'+i ); + if ( $(e).hasClass('wp-has-current-submenu') ) + return true; // leave the current parent open + + if ( 'o' == v ) + $(e).addClass('wp-menu-open'); + else if ( 'c' == v ) + $(e).removeClass('wp-menu-open'); + }); + }, + + toggle : function(el) { + el.slideToggle(150, function() { + var id = el.parent().toggleClass( 'wp-menu-open' ).attr('id'); + if ( id ) { + $('li.wp-has-submenu', '#adminmenu').each(function(i, e) { + if ( id == e.id ) { + var v = $(e).hasClass('wp-menu-open') ? 'o' : 'c'; + setUserSetting( 'm'+i, v ); + } + }); + } + }); + + return false; + }, + + fold : function(off) { + if (off) { + $('body').removeClass('folded'); + $('#adminmenu li.wp-has-submenu').unbind(); + } else { + $('body').addClass('folded'); + $('#adminmenu li.wp-has-submenu').hoverIntent({ + over: function(e){ + var m, b, h, o, f; + m = $(this).find('.wp-submenu'); + b = $(this).offset().top + m.height() + 1; // Bottom offset of the menu + h = $('#wpwrap').height(); // Height of the entire page + o = 60 + b - h; + f = $(window).height() + $(window).scrollTop() - 15; // The fold + if ( f < (b - o) ) { + o = b - f; + } + if ( o > 1 ) { + m.css({'marginTop':'-'+o+'px'}); + } else if ( m.css('marginTop') ) { + m.css({'marginTop':''}); + } + m.addClass('sub-open'); + }, + out: function(){ $(this).find('.wp-submenu').removeClass('sub-open').css({'marginTop':''}); }, + timeout: 220, + sensitivity: 8, + interval: 100 + }); + + } + }, + + favorites : function() { + $('#favorite-inside').width( $('#favorite-actions').width() - 4 ); + $('#favorite-toggle, #favorite-inside').bind('mouseenter', function() { + $('#favorite-inside').removeClass('slideUp').addClass('slideDown'); + setTimeout(function() { + if ( $('#favorite-inside').hasClass('slideDown') ) { + $('#favorite-inside').slideDown(100); + $('#favorite-first').addClass('slide-down'); + } + }, 200); + }).bind('mouseleave', function() { + $('#favorite-inside').removeClass('slideDown').addClass('slideUp'); + setTimeout(function() { + if ( $('#favorite-inside').hasClass('slideUp') ) { + $('#favorite-inside').slideUp(100, function() { + $('#favorite-first').removeClass('slide-down'); + }); + } + }, 300); + }); + } +}; + +$(document).ready(function(){ adminMenu.init(); }); + +// show/hide/save table columns +columns = { + init : function() { + var that = this; + $('.hide-column-tog', '#adv-settings').click( function() { + var $t = $(this), column = $t.val(); + if ( $t.attr('checked') ) + that.checked(column); + else + that.unchecked(column); + + columns.saveManageColumnsState(); + }); + }, + + saveManageColumnsState : function() { + var hidden = this.hidden(); + $.post(ajaxurl, { + action: 'hidden-columns', + hidden: hidden, + screenoptionnonce: $('#screenoptionnonce').val(), + page: pagenow + }); + }, + + checked : function(column) { + $('.column-' + column).show(); + this.colSpanChange(+1); + }, + + unchecked : function(column) { + $('.column-' + column).hide(); + this.colSpanChange(-1); + }, + + hidden : function() { + return $('.manage-column').filter(':hidden').map(function() { return this.id; }).get().join(','); + }, + + useCheckboxesForHidden : function() { + this.hidden = function(){ + return $('.hide-column-tog').not(':checked').map(function() { + var id = this.id; + return id.substring( id, id.length - 5 ); + }).get().join(','); + }; + }, + + colSpanChange : function(diff) { + var $t = $('table').find('.colspanchange'), n; + if ( !$t.length ) + return; + n = parseInt( $t.attr('colspan'), 10 ) + diff; + $t.attr('colspan', n.toString()); + } +} + +$(document).ready(function(){columns.init();}); + +validateForm = function( form ) { + return !$( form ).find('.form-required').filter( function() { return $('input:visible', this).val() == ''; } ).addClass( 'form-invalid' ).find('input:visible').change( function() { $(this).closest('.form-invalid').removeClass( 'form-invalid' ); } ).size(); +} + +})(jQuery); + +// stub for doing better warnings +showNotice = { + warn : function() { + var msg = commonL10n.warnDelete || ''; + if ( confirm(msg) ) { + return true; + } + + return false; + }, + + note : function(text) { + alert(text); + } +}; + +jQuery(document).ready( function($) { + var lastClicked = false, checks, first, last, checked, bgx = ( isRtl ? 'left' : 'right' ); + + // Move .updated and .error alert boxes. Don't move boxes designed to be inline. + $('div.wrap h2:first').nextAll('div.updated, div.error').addClass('below-h2'); + $('div.updated, div.error').not('.below-h2, .inline').insertAfter( $('div.wrap h2:first') ); + + // screen settings tab + $('#show-settings-link').click(function () { + if ( ! $('#screen-options-wrap').hasClass('screen-options-open') ) + $('#contextual-help-link-wrap').css('visibility', 'hidden'); + + $('#screen-options-wrap').slideToggle('fast', function(){ + if ( $(this).hasClass('screen-options-open') ) { + $('#show-settings-link').css({'backgroundPosition':'top '+bgx}); + $('#contextual-help-link-wrap').css('visibility', ''); + $(this).removeClass('screen-options-open'); + } else { + $('#show-settings-link').css({'backgroundPosition':'bottom '+bgx}); + $(this).addClass('screen-options-open'); + } + }); + return false; + }); + + // help tab + $('#contextual-help-link').click(function () { + if ( ! $('#contextual-help-wrap').hasClass('contextual-help-open') ) + $('#screen-options-link-wrap').css('visibility', 'hidden'); + + $('#contextual-help-wrap').slideToggle('fast', function() { + if ( $(this).hasClass('contextual-help-open') ) { + $('#contextual-help-link').css({'backgroundPosition':'top '+bgx}); + $('#screen-options-link-wrap').css('visibility', ''); + $(this).removeClass('contextual-help-open'); + } else { + $('#contextual-help-link').css({'backgroundPosition':'bottom '+bgx}); + $(this).addClass('contextual-help-open'); + } + }); + return false; + }); + + // check all checkboxes + $('tbody').children().children('.check-column').find(':checkbox').click( function(e) { + if ( 'undefined' == e.shiftKey ) { return true; } + if ( e.shiftKey ) { + if ( !lastClicked ) { return true; } + checks = $( lastClicked ).closest( 'form' ).find( ':checkbox' ); + first = checks.index( lastClicked ); + last = checks.index( this ); + checked = $(this).attr('checked'); + if ( 0 < first && 0 < last && first != last ) { + checks.slice( first, last ).attr( 'checked', function(){ + if ( $(this).closest('tr').is(':visible') ) + return checked ? 'checked' : ''; + + return ''; + }); + } + } + lastClicked = this; + return true; + }); + + $('thead, tfoot').find('.check-column :checkbox').click( function(e) { + var c = $(this).attr('checked'), + kbtoggle = 'undefined' == typeof toggleWithKeyboard ? false : toggleWithKeyboard, + toggle = e.shiftKey || kbtoggle; + + $(this).closest( 'table' ).children( 'tbody' ).filter(':visible') + .children().children('.check-column').find(':checkbox') + .attr('checked', function() { + if ( $(this).closest('tr').is(':hidden') ) + return ''; + if ( toggle ) + return $(this).attr( 'checked' ) ? '' : 'checked'; + else if (c) + return 'checked'; + return ''; + }); + + $(this).closest('table').children('thead, tfoot').filter(':visible') + .children().children('.check-column').find(':checkbox') + .attr('checked', function() { + if ( toggle ) + return ''; + else if (c) + return 'checked'; + return ''; + }); + }); + + $('#default-password-nag-no').click( function() { + setUserSetting('default_password_nag', 'hide'); + $('div.default-password-nag').hide(); + return false; + }); + + // tab in textareas + $('#newcontent').keydown(function(e) { + if ( e.keyCode != 9 ) + return true; + + var el = e.target, selStart = el.selectionStart, selEnd = el.selectionEnd, val = el.value, scroll, sel; + + try { + this.lastKey = 9; // not a standard DOM property, lastKey is to help stop Opera tab event. See blur handler below. + } catch(err) {} + + if ( document.selection ) { + el.focus(); + sel = document.selection.createRange(); + sel.text = '\t'; + } else if ( selStart >= 0 ) { + scroll = this.scrollTop; + el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) ); + el.selectionStart = el.selectionEnd = selStart + 1; + this.scrollTop = scroll; + } + + if ( e.stopPropagation ) + e.stopPropagation(); + if ( e.preventDefault ) + e.preventDefault(); + }); + + $('#newcontent').blur(function(e) { + if ( this.lastKey && 9 == this.lastKey ) + this.focus(); + }); +}); diff --git a/src/wp-admin/js/common.js b/src/wp-admin/js/common.js new file mode 100644 index 00000000..559b9f7f --- /dev/null +++ b/src/wp-admin/js/common.js @@ -0,0 +1 @@ +var showNotice,adminMenu,columns,validateForm;(function(a){adminMenu={init:function(){var b=a("#adminmenu");a(".wp-menu-toggle",b).each(function(){var c=a(this),d=c.siblings(".wp-submenu");if(d.length){c.click(function(){adminMenu.toggle(d)})}else{c.hide()}});this.favorites();a(".separator",b).click(function(){if(a("body").hasClass("folded")){adminMenu.fold(1);deleteUserSetting("mfold")}else{adminMenu.fold();setUserSetting("mfold","f")}return false});if(a("body").hasClass("folded")){this.fold()}this.restoreMenuState()},restoreMenuState:function(){a("li.wp-has-submenu","#adminmenu").each(function(c,d){var b=getUserSetting("m"+c);if(a(d).hasClass("wp-has-current-submenu")){return true}if("o"==b){a(d).addClass("wp-menu-open")}else{if("c"==b){a(d).removeClass("wp-menu-open")}}})},toggle:function(b){b.slideToggle(150,function(){var c=b.parent().toggleClass("wp-menu-open").attr("id");if(c){a("li.wp-has-submenu","#adminmenu").each(function(f,g){if(c==g.id){var d=a(g).hasClass("wp-menu-open")?"o":"c";setUserSetting("m"+f,d)}})}});return false},fold:function(b){if(b){a("body").removeClass("folded");a("#adminmenu li.wp-has-submenu").unbind()}else{a("body").addClass("folded");a("#adminmenu li.wp-has-submenu").hoverIntent({over:function(j){var d,c,g,k,i;d=a(this).find(".wp-submenu");c=a(this).offset().top+d.height()+1;g=a("#wpwrap").height();k=60+c-g;i=a(window).height()+a(window).scrollTop()-15;if(i<(c-k)){k=c-i}if(k>1){d.css({marginTop:"-"+k+"px"})}else{if(d.css("marginTop")){d.css({marginTop:""})}}d.addClass("sub-open")},out:function(){a(this).find(".wp-submenu").removeClass("sub-open").css({marginTop:""})},timeout:220,sensitivity:8,interval:100})}},favorites:function(){a("#favorite-inside").width(a("#favorite-actions").width()-4);a("#favorite-toggle, #favorite-inside").bind("mouseenter",function(){a("#favorite-inside").removeClass("slideUp").addClass("slideDown");setTimeout(function(){if(a("#favorite-inside").hasClass("slideDown")){a("#favorite-inside").slideDown(100);a("#favorite-first").addClass("slide-down")}},200)}).bind("mouseleave",function(){a("#favorite-inside").removeClass("slideDown").addClass("slideUp");setTimeout(function(){if(a("#favorite-inside").hasClass("slideUp")){a("#favorite-inside").slideUp(100,function(){a("#favorite-first").removeClass("slide-down")})}},300)})}};a(document).ready(function(){adminMenu.init()});columns={init:function(){var b=this;a(".hide-column-tog","#adv-settings").click(function(){var d=a(this),c=d.val();if(d.attr("checked")){b.checked(c)}else{b.unchecked(c)}columns.saveManageColumnsState()})},saveManageColumnsState:function(){var b=this.hidden();a.post(ajaxurl,{action:"hidden-columns",hidden:b,screenoptionnonce:a("#screenoptionnonce").val(),page:pagenow})},checked:function(b){a(".column-"+b).show();this.colSpanChange(+1)},unchecked:function(b){a(".column-"+b).hide();this.colSpanChange(-1)},hidden:function(){return a(".manage-column").filter(":hidden").map(function(){return this.id}).get().join(",")},useCheckboxesForHidden:function(){this.hidden=function(){return a(".hide-column-tog").not(":checked").map(function(){var b=this.id;return b.substring(b,b.length-5)}).get().join(",")}},colSpanChange:function(b){var d=a("table").find(".colspanchange"),c;if(!d.length){return}c=parseInt(d.attr("colspan"),10)+b;d.attr("colspan",c.toString())}};a(document).ready(function(){columns.init()});validateForm=function(b){return !a(b).find(".form-required").filter(function(){return a("input:visible",this).val()==""}).addClass("form-invalid").find("input:visible").change(function(){a(this).closest(".form-invalid").removeClass("form-invalid")}).size()}})(jQuery);showNotice={warn:function(){var a=commonL10n.warnDelete||"";if(confirm(a)){return true}return false},note:function(a){alert(a)}};jQuery(document).ready(function(e){var g=false,b,f,d,c,a=(isRtl?"left":"right");e("div.wrap h2:first").nextAll("div.updated, div.error").addClass("below-h2");e("div.updated, div.error").not(".below-h2, .inline").insertAfter(e("div.wrap h2:first"));e("#show-settings-link").click(function(){if(!e("#screen-options-wrap").hasClass("screen-options-open")){e("#contextual-help-link-wrap").css("visibility","hidden")}e("#screen-options-wrap").slideToggle("fast",function(){if(e(this).hasClass("screen-options-open")){e("#show-settings-link").css({backgroundPosition:"top "+a});e("#contextual-help-link-wrap").css("visibility","");e(this).removeClass("screen-options-open")}else{e("#show-settings-link").css({backgroundPosition:"bottom "+a});e(this).addClass("screen-options-open")}});return false});e("#contextual-help-link").click(function(){if(!e("#contextual-help-wrap").hasClass("contextual-help-open")){e("#screen-options-link-wrap").css("visibility","hidden")}e("#contextual-help-wrap").slideToggle("fast",function(){if(e(this).hasClass("contextual-help-open")){e("#contextual-help-link").css({backgroundPosition:"top "+a});e("#screen-options-link-wrap").css("visibility","");e(this).removeClass("contextual-help-open")}else{e("#contextual-help-link").css({backgroundPosition:"bottom "+a});e(this).addClass("contextual-help-open")}});return false});e("tbody").children().children(".check-column").find(":checkbox").click(function(h){if("undefined"==h.shiftKey){return true}if(h.shiftKey){if(!g){return true}b=e(g).closest("form").find(":checkbox");f=b.index(g);d=b.index(this);c=e(this).attr("checked");if(0=0){h=this.scrollTop;j.value=n.substring(0,o).concat("\t",n.substring(i));j.selectionStart=j.selectionEnd=o+1;this.scrollTop=h}}if(m.stopPropagation){m.stopPropagation()}if(m.preventDefault){m.preventDefault()}});e("#newcontent").blur(function(h){if(this.lastKey&&9==this.lastKey){this.focus()}})}); \ No newline at end of file diff --git a/src/wp-admin/js/custom-background.dev.js b/src/wp-admin/js/custom-background.dev.js new file mode 100644 index 00000000..1a46d55d --- /dev/null +++ b/src/wp-admin/js/custom-background.dev.js @@ -0,0 +1,46 @@ +var farbtastic; + +function pickColor(color) { + farbtastic.setColor(color); + jQuery('#background-color').val(color); + jQuery('#custom-background-image').css('background-color', color); +} + +jQuery(document).ready(function() { + jQuery('#pickcolor').click(function() { + jQuery('#colorPickerDiv').show(); + return false; + }); + + jQuery('#background-color').keyup(function() { + var _hex = jQuery('#background-color').val(), hex = _hex; + if ( hex.charAt(0) != '#' ) + hex = '#' + hex; + hex = hex.replace(/[^#a-fA-F0-9]+/, ''); + if ( hex != _hex ) + jQuery('#background-color').val(hex); + if ( hex.length == 4 || hex.length == 7 ) + pickColor( hex ); + }); + + jQuery('input[name="background-position-x"]').change(function() { + jQuery('#custom-background-image').css('background-position', jQuery(this).val() + ' top'); + }); + + jQuery('input[name="background-repeat"]').change(function() { + jQuery('#custom-background-image').css('background-repeat', jQuery(this).val()); + }); + + farbtastic = jQuery.farbtastic('#colorPickerDiv', function(color) { + pickColor(color); + }); + pickColor(jQuery('#background-color').val()); + + jQuery(document).mousedown(function(){ + jQuery('#colorPickerDiv').each(function(){ + var display = jQuery(this).css('display'); + if ( display == 'block' ) + jQuery(this).fadeOut(2); + }); + }); +}); diff --git a/src/wp-admin/js/custom-background.js b/src/wp-admin/js/custom-background.js new file mode 100644 index 00000000..d7aecbcd --- /dev/null +++ b/src/wp-admin/js/custom-background.js @@ -0,0 +1 @@ +var farbtastic;function pickColor(a){farbtastic.setColor(a);jQuery("#background-color").val(a);jQuery("#custom-background-image").css("background-color",a)}jQuery(document).ready(function(){jQuery("#pickcolor").click(function(){jQuery("#colorPickerDiv").show();return false});jQuery("#background-color").keyup(function(){var b=jQuery("#background-color").val(),a=b;if(a.charAt(0)!="#"){a="#"+a}a=a.replace(/[^#a-fA-F0-9]+/,"");if(a!=b){jQuery("#background-color").val(a)}if(a.length==4||a.length==7){pickColor(a)}});jQuery('input[name="background-position-x"]').change(function(){jQuery("#custom-background-image").css("background-position",jQuery(this).val()+" top")});jQuery('input[name="background-repeat"]').change(function(){jQuery("#custom-background-image").css("background-repeat",jQuery(this).val())});farbtastic=jQuery.farbtastic("#colorPickerDiv",function(a){pickColor(a)});pickColor(jQuery("#background-color").val());jQuery(document).mousedown(function(){jQuery("#colorPickerDiv").each(function(){var a=jQuery(this).css("display");if(a=="block"){jQuery(this).fadeOut(2)}})})}); \ No newline at end of file diff --git a/src/wp-admin/js/custom-fields.dev.js b/src/wp-admin/js/custom-fields.dev.js new file mode 100644 index 00000000..70be83a8 --- /dev/null +++ b/src/wp-admin/js/custom-fields.dev.js @@ -0,0 +1,34 @@ +jQuery(document).ready( function($) { + var before, addBefore, addAfter, delBefore; + + before = function() { + var nonce = $('#newmeta [name=_ajax_nonce]').val(), postId = $('#post_ID').val(); + if ( !nonce || !postId ) { return false; } + return [nonce,postId]; + } + + addBefore = function( s ) { + var b = before(); + if ( !b ) { return false; } + s.data = s.data.replace(/_ajax_nonce=[a-f0-9]+/, '_ajax_nonce=' + b[0]) + '&post_id=' + b[1]; + return s; + }; + + addAfter = function( r, s ) { + var postId = $('postid', r).text(), h; + if ( !postId ) { return; } + $('#post_ID').attr( 'name', 'post_ID' ).val( postId ); + h = $('#hiddenaction'); + if ( 'post' == h.val() ) { h.val( 'postajaxpost' ); } + }; + + delBefore = function( s ) { + var b = before(); if ( !b ) return false; + s.data._ajax_nonce = b[0]; s.data.post_id = b[1]; + return s; + } + + $('#the-list') + .wpList( { addBefore: addBefore, addAfter: addAfter, delBefore: delBefore } ) + .find('.updatemeta, .deletemeta').attr( 'type', 'button' ); +} ); diff --git a/src/wp-admin/js/custom-fields.js b/src/wp-admin/js/custom-fields.js new file mode 100644 index 00000000..48dad1e3 --- /dev/null +++ b/src/wp-admin/js/custom-fields.js @@ -0,0 +1 @@ +jQuery(document).ready(function(d){var c,b,e,a;c=function(){var g=d("#newmeta [name=_ajax_nonce]").val(),f=d("#post_ID").val();if(!g||!f){return false}return[g,f]};b=function(g){var f=c();if(!f){return false}g.data=g.data.replace(/_ajax_nonce=[a-f0-9]+/,"_ajax_nonce="+f[0])+"&post_id="+f[1];return g};e=function(j,i){var f=d("postid",j).text(),g;if(!f){return}d("#post_ID").attr("name","post_ID").val(f);g=d("#hiddenaction");if("post"==g.val()){g.val("postajaxpost")}};a=function(g){var f=c();if(!f){return false}g.data._ajax_nonce=f[0];g.data.post_id=f[1];return g};d("#the-list").wpList({addBefore:b,addAfter:e,delBefore:a}).find(".updatemeta, .deletemeta").attr("type","button")}); \ No newline at end of file diff --git a/src/wp-admin/js/dashboard.dev.js b/src/wp-admin/js/dashboard.dev.js new file mode 100644 index 00000000..a43ffe86 --- /dev/null +++ b/src/wp-admin/js/dashboard.dev.js @@ -0,0 +1,70 @@ +var ajaxWidgets, ajaxPopulateWidgets, quickPressLoad; + +jQuery(document).ready( function($) { + // These widgets are sometimes populated via ajax + ajaxWidgets = [ + 'dashboard_incoming_links', + 'dashboard_primary', + 'dashboard_secondary', + 'dashboard_plugins', + 'dashboard_quick_press' + ]; + + ajaxPopulateWidgets = function(el) { + show = function(id, i) { + var p, e = $('#' + id + ' div.inside:visible').find('.widget-loading'); + if ( e.length ) { + p = e.parent(); + setTimeout( function(){ + p.load( ajaxurl.replace( '/admin-ajax.php', '' ) + '/index-extra.php?jax=' + id, '', function() { + p.hide().slideDown('normal', function(){ + $(this).css('display', ''); + if ( 'dashboard_quick_press' == id ) + quickPressLoad(); + }); + }); + }, i * 500 ); + } + } + if ( el ) { + el = el.toString(); + if ( $.inArray(el, ajaxWidgets) != -1 ) + show(el, 0); + } else { + $.each( ajaxWidgets, function(i) { + show(this, i); + }); + } + }; + ajaxPopulateWidgets(); + + postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } ); + + /* QuickPress */ + quickPressLoad = function() { + var act = $('#quickpost-action'), t; + t = $('#quick-press').submit( function() { + $('#dashboard_quick_press #publishing-action img.waiting').css('visibility', 'visible'); + $('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').attr('disabled','disabled'); + + if ( 'post' == act.val() ) { + act.val( 'post-quickpress-publish' ); + } + + $('#dashboard_quick_press div.inside').load( t.attr( 'action' ), t.serializeArray(), function() { + $('#dashboard_quick_press #publishing-action img.waiting').css('visibility', 'hidden'); + $('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').attr('disabled',''); + $('#dashboard_quick_press ul').next('p').remove(); + $('#dashboard_quick_press ul').find('li').each( function() { + $('#dashboard_recent_drafts ul').prepend( this ); + } ).end().remove(); + quickPressLoad(); + } ); + return false; + } ); + + $('#publish').click( function() { act.val( 'post-quickpress-publish' ); } ); + + }; + +} ); diff --git a/src/wp-admin/js/dashboard.js b/src/wp-admin/js/dashboard.js new file mode 100644 index 00000000..922d083e --- /dev/null +++ b/src/wp-admin/js/dashboard.js @@ -0,0 +1 @@ +var ajaxWidgets,ajaxPopulateWidgets,quickPressLoad;jQuery(document).ready(function(a){ajaxWidgets=["dashboard_incoming_links","dashboard_primary","dashboard_secondary","dashboard_plugins","dashboard_quick_press"];ajaxPopulateWidgets=function(b){show=function(g,c){var f,d=a("#"+g+" div.inside:visible").find(".widget-loading");if(d.length){f=d.parent();setTimeout(function(){f.load(ajaxurl.replace("/admin-ajax.php","")+"/index-extra.php?jax="+g,"",function(){f.hide().slideDown("normal",function(){a(this).css("display","");if("dashboard_quick_press"==g){quickPressLoad()}})})},c*500)}};if(b){b=b.toString();if(a.inArray(b,ajaxWidgets)!=-1){show(b,0)}}else{a.each(ajaxWidgets,function(c){show(this,c)})}};ajaxPopulateWidgets();postboxes.add_postbox_toggles(pagenow,{pbshow:ajaxPopulateWidgets});quickPressLoad=function(){var b=a("#quickpost-action"),c;c=a("#quick-press").submit(function(){a("#dashboard_quick_press #publishing-action img.waiting").css("visibility","visible");a('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').attr("disabled","disabled");if("post"==b.val()){b.val("post-quickpress-publish")}a("#dashboard_quick_press div.inside").load(c.attr("action"),c.serializeArray(),function(){a("#dashboard_quick_press #publishing-action img.waiting").css("visibility","hidden");a('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').attr("disabled","");a("#dashboard_quick_press ul").next("p").remove();a("#dashboard_quick_press ul").find("li").each(function(){a("#dashboard_recent_drafts ul").prepend(this)}).end().remove();quickPressLoad()});return false});a("#publish").click(function(){b.val("post-quickpress-publish")})}}); \ No newline at end of file diff --git a/src/wp-admin/js/edit-comments.dev.js b/src/wp-admin/js/edit-comments.dev.js new file mode 100644 index 00000000..b81b3979 --- /dev/null +++ b/src/wp-admin/js/edit-comments.dev.js @@ -0,0 +1,555 @@ +var theList, theExtraList, toggleWithKeyboard = false; +(function($) { + +setCommentsList = function() { + var totalInput, perPageInput, pageInput, lastConfidentTime = 0, dimAfter, delBefore, updateTotalCount, delAfter; + + totalInput = $('input[name="_total"]', '#comments-form'); + perPageInput = $('input[name="_per_page"]', '#comments-form'); + pageInput = $('input[name="_page"]', '#comments-form'); + + dimAfter = function( r, settings ) { + var c = $('#' + settings.element); + + if ( c.is('.unapproved') ) + c.find('div.comment_status').html('0') + else + c.find('div.comment_status').html('1') + + $('span.pending-count').each( function() { + var a = $(this), n, dif; + n = a.html().replace(/[^0-9]+/g, ''); + n = parseInt(n,10); + if ( isNaN(n) ) return; + dif = $('#' + settings.element).is('.' + settings.dimClass) ? 1 : -1; + n = n + dif; + if ( n < 0 ) { n = 0; } + a.closest('#awaiting-mod')[ 0 == n ? 'addClass' : 'removeClass' ]('count-0'); + updateCount(a, n); + dashboardTotals(); + }); + }; + + // Send current total, page, per_page and url + delBefore = function( settings, list ) { + var cl = $(settings.target).attr('className'), id, el, n, h, a, author, action = false; + + settings.data._total = totalInput.val() || 0; + settings.data._per_page = perPageInput.val() || 0; + settings.data._page = pageInput.val() || 0; + settings.data._url = document.location.href; + settings.data.comment_status = $('input[name=comment_status]', '#comments-form').val(); + + if ( cl.indexOf(':trash=1') != -1 ) + action = 'trash'; + else if ( cl.indexOf(':spam=1') != -1 ) + action = 'spam'; + + if ( action ) { + id = cl.replace(/.*?comment-([0-9]+).*/, '$1'); + el = $('#comment-' + id); + note = $('#' + action + '-undo-holder').html(); + + el.find('.check-column :checkbox').attr('checked', ''); // Uncheck the row so as not to be affected by Bulk Edits. + + if ( el.siblings('#replyrow').length && commentReply.cid == id ) + commentReply.close(); + + if ( el.is('tr') ) { + n = el.children(':visible').length; + author = $('.author strong', el).text(); + h = $('' + note + ''); + } else { + author = $('.comment-author', el).text(); + h = $(''); + } + + el.before(h); + + $('strong', '#undo-' + id).text(author + ' '); + a = $('.undo a', '#undo-' + id); + a.attr('href', 'comment.php?action=un' + action + 'comment&c=' + id + '&_wpnonce=' + settings.data._ajax_nonce); + a.attr('className', 'delete:the-comment-list:comment-' + id + '::un' + action + '=1 vim-z vim-destructive'); + $('.avatar', el).clone().prependTo('#undo-' + id + ' .' + action + '-undo-inside'); + + a.click(function(){ + list.wpList.del(this); + $('#undo-' + id).css( {backgroundColor:'#ceb'} ).fadeOut(350, function(){ + $(this).remove(); + $('#comment-' + id).css('backgroundColor', '').fadeIn(300, function(){ $(this).show() }); + }); + return false; + }); + } + + return settings; + }; + + // Updates the current total (as displayed visibly) + updateTotalCount = function( total, time, setConfidentTime ) { + if ( time < lastConfidentTime ) + return; + + if ( setConfidentTime ) + lastConfidentTime = time; + + totalInput.val( total.toString() ); + $('span.total-type-count').each( function() { + updateCount( $(this), total ); + }); + }; + + function dashboardTotals(n) { + var dash = $('#dashboard_right_now'), total, appr, totalN, apprN; + + n = n || 0; + if ( isNaN(n) || !dash.length ) + return; + + total = $('span.total-count', dash); + appr = $('span.approved-count', dash); + totalN = getCount(total); + + totalN = totalN + n; + apprN = totalN - getCount( $('span.pending-count', dash) ) - getCount( $('span.spam-count', dash) ); + updateCount(total, totalN); + updateCount(appr, apprN); + + } + + function getCount(el) { + var n = parseInt( el.html().replace(/[^0-9]+/g, ''), 10 ); + if ( isNaN(n) ) + return 0; + return n; + } + + function updateCount(el, n) { + var n1 = ''; + if ( isNaN(n) ) + return; + n = n < 1 ? '0' : n.toString(); + if ( n.length > 3 ) { + while ( n.length > 3 ) { + n1 = thousandsSeparator + n.substr(n.length - 3) + n1; + n = n.substr(0, n.length - 3); + } + n = n + n1; + } + el.html(n); + } + + // In admin-ajax.php, we send back the unix time stamp instead of 1 on success + delAfter = function( r, settings ) { + var total, pageLinks, N, untrash = $(settings.target).parent().is('span.untrash'), unspam = $(settings.target).parent().is('span.unspam'), spam, trash; + + function getUpdate(s) { + if ( $(settings.target).parent().is('span.' + s) ) + return 1; + else if ( $('#' + settings.element).is('.' + s) ) + return -1; + + return 0; + } + spam = getUpdate('spam'); + trash = getUpdate('trash'); + + if ( untrash ) + trash = -1; + if ( unspam ) + spam = -1; + + $('span.pending-count').each( function() { + var a = $(this), n = getCount(a), unapproved = $('#' + settings.element).is('.unapproved'); + + if ( $(settings.target).parent().is('span.unapprove') || ( ( untrash || unspam ) && unapproved ) ) { // we "deleted" an approved comment from the approved list by clicking "Unapprove" + n = n + 1; + } else if ( unapproved ) { // we deleted a formerly unapproved comment + n = n - 1; + } + if ( n < 0 ) { n = 0; } + a.closest('#awaiting-mod')[ 0 == n ? 'addClass' : 'removeClass' ]('count-0'); + updateCount(a, n); + dashboardTotals(); + }); + + $('span.spam-count').each( function() { + var a = $(this), n = getCount(a) + spam; + updateCount(a, n); + }); + + $('span.trash-count').each( function() { + var a = $(this), n = getCount(a) + trash; + updateCount(a, n); + }); + + if ( $('#dashboard_right_now').length ) { + N = trash ? -1 * trash : 0; + dashboardTotals(N); + } else { + total = totalInput.val() ? parseInt( totalInput.val(), 10 ) : 0; + total = total - spam - trash; + if ( total < 0 ) + total = 0; + + if ( ( 'object' == typeof r ) && lastConfidentTime < settings.parsed.responses[0].supplemental.time ) { + total_items_i18n = settings.parsed.responses[0].supplemental.total_items_i18n || ''; + if ( total_items_i18n ) { + $('.displaying-num').text( total_items_i18n ); + $('.total-pages').text( settings.parsed.responses[0].supplemental.total_pages_i18n ); + $('.tablenav-pages').find('.next-page, .last-page').toggleClass('disabled', settings.parsed.responses[0].supplemental.total_pages == $('.current-page').val()); + } + updateTotalCount( total, settings.parsed.responses[0].supplemental.time, true ); + } else { + updateTotalCount( total, r, false ); + } + } + + + if ( ! theExtraList || theExtraList.size() == 0 || theExtraList.children().size() == 0 || untrash || unspam ) { + return; + } + + theList.get(0).wpList.add( theExtraList.children(':eq(0)').remove().clone() ); + + refillTheExtraList(); + }; + + var refillTheExtraList = function(ev) { + // var args = $.query.get(), total_pages = listTable.get_total_pages(), per_page = $('input[name=_per_page]', '#comments-form').val(), r; + var args = $.query.get(), total_pages = $('.total-pages').text(), per_page = $('input[name=_per_page]', '#comments-form').val(), r; + + if (! args.paged) + args.paged = 1; + + if (args.paged > total_pages) { + return; + } + + if (ev) { + theExtraList.empty(); + args.number = Math.min(8, per_page); // see WP_Comments_List_Table::prepare_items() @ class-wp-comments-list-table.php + } else { + args.number = 1; + args.offset = Math.min(8, per_page) - 1; // fetch only the next item on the extra list + } + + args.no_placeholder = true; + + args.paged ++; + + // $.query.get() needs some correction to be sent into an ajax request + if ( true === args.comment_type ) + args.comment_type = ''; + + args = $.extend(args, { + 'action': 'fetch-list', + 'list_args': list_args, + '_ajax_fetch_list_nonce': $('#_ajax_fetch_list_nonce').val() + }); + + $.ajax({ + url: ajaxurl, + global: false, + dataType: 'json', + data: args, + success: function(response) { + theExtraList.get(0).wpList.add( response.rows ); + } + }); + }; + + theExtraList = $('#the-extra-comment-list').wpList( { alt: '', delColor: 'none', addColor: 'none' } ); + theList = $('#the-comment-list').wpList( { alt: '', delBefore: delBefore, dimAfter: dimAfter, delAfter: delAfter, addColor: 'none' } ) + .bind('wpListDelEnd', function(e, s){ + var id = s.element.replace(/[^0-9]+/g, ''); + + if ( s.target.className.indexOf(':trash=1') != -1 || s.target.className.indexOf(':spam=1') != -1 ) + $('#undo-' + id).fadeIn(300, function(){ $(this).show() }); + }); + // $(listTable).bind('changePage', refillTheExtraList); +}; + +commentReply = { + cid : '', + act : '', + + init : function() { + var row = $('#replyrow'); + + $('a.cancel', row).click(function() { return commentReply.revert(); }); + $('a.save', row).click(function() { return commentReply.send(); }); + $('input#author, input#author-email, input#author-url', row).keypress(function(e){ + if ( e.which == 13 ) { + commentReply.send(); + e.preventDefault(); + return false; + } + }); + + // add events + $('#the-comment-list .column-comment > p').dblclick(function(){ + commentReply.toggle($(this).parent()); + }); + + $('#doaction, #doaction2, #post-query-submit').click(function(e){ + if ( $('#the-comment-list #replyrow').length > 0 ) + commentReply.close(); + }); + + this.comments_listing = $('#comments-form > input[name="comment_status"]').val() || ''; + + /* $(listTable).bind('beforeChangePage', function(){ + commentReply.close(); + }); */ + }, + + addEvents : function(r) { + r.each(function() { + $(this).find('.column-comment > p').dblclick(function(){ + commentReply.toggle($(this).parent()); + }); + }); + }, + + toggle : function(el) { + if ( $(el).css('display') != 'none' ) + $(el).find('a.vim-q').click(); + }, + + revert : function() { + + if ( $('#the-comment-list #replyrow').length < 1 ) + return false; + + $('#replyrow').fadeOut('fast', function(){ + commentReply.close(); + }); + + return false; + }, + + close : function() { + var c; + + if ( this.cid ) { + c = $('#comment-' + this.cid); + + if ( this.act == 'edit-comment' ) + c.fadeIn(300, function(){ c.show() }).css('backgroundColor', ''); + + $('#replyrow').hide(); + $('#com-reply').append( $('#replyrow') ); + $('#replycontent').val(''); + $('input', '#edithead').val(''); + $('.error', '#replysubmit').html('').hide(); + $('.waiting', '#replysubmit').hide(); + + if ( $.browser.msie ) + $('#replycontainer, #replycontent').css('height', '120px'); + else + $('#replycontainer').resizable('destroy').css('height', '120px'); + + this.cid = ''; + } + }, + + open : function(id, p, a) { + var t = this, editRow, rowData, act, h, c = $('#comment-' + id); + t.close(); + t.cid = id; + + editRow = $('#replyrow'); + rowData = $('#inline-'+id); + act = t.act = (a == 'edit') ? 'edit-comment' : 'replyto-comment'; + + $('#action', editRow).val(act); + $('#comment_post_ID', editRow).val(p); + $('#comment_ID', editRow).val(id); + + if ( a == 'edit' ) { + $('#author', editRow).val( $('div.author', rowData).text() ); + $('#author-email', editRow).val( $('div.author-email', rowData).text() ); + $('#author-url', editRow).val( $('div.author-url', rowData).text() ); + $('#status', editRow).val( $('div.comment_status', rowData).text() ); + $('#replycontent', editRow).val( $('textarea.comment', rowData).val() ); + $('#edithead, #savebtn', editRow).show(); + $('#replyhead, #replybtn', editRow).hide(); + + h = c.height(); + if ( h > 220 ) + if ( $.browser.msie ) + $('#replycontainer, #replycontent', editRow).height(h-105); + else + $('#replycontainer', editRow).height(h-105); + + c.after( editRow ).fadeOut('fast', function(){ + $('#replyrow').fadeIn(300, function(){ $(this).show() }); + }); + } else { + $('#edithead, #savebtn', editRow).hide(); + $('#replyhead, #replybtn', editRow).show(); + c.after(editRow); + $('#replyrow').fadeIn(300, function(){ $(this).show() }); + } + + if ( ! $.browser.msie ) + $('#replycontainer').resizable({ + handles : 's', + axis : 'y', + minHeight : 80, + stop : function() { + $('#replycontainer').width('auto'); + } + }); + + setTimeout(function() { + var rtop, rbottom, scrollTop, vp, scrollBottom; + + rtop = $('#replyrow').offset().top; + rbottom = rtop + $('#replyrow').height(); + scrollTop = window.pageYOffset || document.documentElement.scrollTop; + vp = document.documentElement.clientHeight || self.innerHeight || 0; + scrollBottom = scrollTop + vp; + + if ( scrollBottom - 20 < rbottom ) + window.scroll(0, rbottom - vp + 35); + else if ( rtop - 20 < scrollTop ) + window.scroll(0, rtop - 35); + + $('#replycontent').focus().keyup(function(e){ + if ( e.which == 27 ) + commentReply.revert(); // close on Escape + }); + }, 600); + + return false; + }, + + send : function() { + var post = {}; + + $('#replysubmit .error').hide(); + $('#replysubmit .waiting').show(); + + $('#replyrow input').each(function() { + post[ $(this).attr('name') ] = $(this).val(); + }); + + post.content = $('#replycontent').val(); + post.id = post.comment_post_ID; + post.comments_listing = this.comments_listing; + post.p = $('[name=p]').val(); + + $.ajax({ + type : 'POST', + url : ajaxurl, + data : post, + success : function(x) { commentReply.show(x); }, + error : function(r) { commentReply.error(r); } + }); + + return false; + }, + + show : function(xml) { + var r, c, id, bg; + + if ( typeof(xml) == 'string' ) { + this.error({'responseText': xml}); + return false; + } + + r = wpAjax.parseAjaxResponse(xml); + if ( r.errors ) { + this.error({'responseText': wpAjax.broken}); + return false; + } + + r = r.responses[0]; + c = r.data; + id = '#comment-' + r.id; + if ( 'edit-comment' == this.act ) + $(id).remove(); + + $(c).hide() + $('#replyrow').after(c); + + this.revert(); + this.addEvents($(id)); + bg = $(id).hasClass('unapproved') ? '#ffffe0' : '#fff'; + + $(id) + .animate( { 'backgroundColor':'#CCEEBB' }, 600 ) + .animate( { 'backgroundColor': bg }, 600 ); + + // $.fn.wpList.process($(id)); + }, + + error : function(r) { + var er = r.statusText; + + $('#replysubmit .waiting').hide(); + + if ( r.responseText ) + er = r.responseText.replace( /<.[^<>]*?>/g, '' ); + + if ( er ) + $('#replysubmit .error').html(er).show(); + + } +}; + +$(document).ready(function(){ + var make_hotkeys_redirect, edit_comment, toggle_all, make_bulk; + + setCommentsList(); + commentReply.init(); + $(document).delegate('span.delete a.delete', 'click', function(){return false;}); + + if ( typeof QTags != 'undefined' ) + ed_reply = new QTags('ed_reply', 'replycontent', 'replycontainer', 'more'); + + if ( typeof $.table_hotkeys != 'undefined' ) { + make_hotkeys_redirect = function(which) { + return function() { + var first_last, l; + + first_last = 'next' == which? 'first' : 'last'; + l = $('.tablenav-pages .'+which+'-page:not(.disabled)'); + if (l.length) + window.location = l[0].href.replace(/\&hotkeys_highlight_(first|last)=1/g, '')+'&hotkeys_highlight_'+first_last+'=1'; + } + }; + + edit_comment = function(event, current_row) { + window.location = $('span.edit a', current_row).attr('href'); + }; + + toggle_all = function() { + toggleWithKeyboard = true; + $('input:checkbox', '#cb').click().attr('checked', ''); + toggleWithKeyboard = false; + }; + + make_bulk = function(value) { + return function() { + var scope = $('select[name="action"]'); + $('option[value='+value+']', scope).attr('selected', 'selected'); + $('#doaction').click(); + } + }; + + $.table_hotkeys( + $('table.widefat'), + ['a', 'u', 's', 'd', 'r', 'q', 'z', ['e', edit_comment], ['shift+x', toggle_all], + ['shift+a', make_bulk('approve')], ['shift+s', make_bulk('spam')], + ['shift+d', make_bulk('delete')], ['shift+t', make_bulk('trash')], + ['shift+z', make_bulk('untrash')], ['shift+u', make_bulk('unapprove')]], + { highlight_first: adminCommentsL10n.hotkeys_highlight_first, highlight_last: adminCommentsL10n.hotkeys_highlight_last, + prev_page_link_cb: make_hotkeys_redirect('prev'), next_page_link_cb: make_hotkeys_redirect('next') } + ); + } +}); + +})(jQuery); diff --git a/src/wp-admin/js/edit-comments.js b/src/wp-admin/js/edit-comments.js new file mode 100644 index 00000000..36576855 --- /dev/null +++ b/src/wp-admin/js/edit-comments.js @@ -0,0 +1 @@ +var theList,theExtraList,toggleWithKeyboard=false;(function(a){setCommentsList=function(){var d,f,i,m=0,h,j,e,l;d=a('input[name="_total"]',"#comments-form");f=a('input[name="_per_page"]',"#comments-form");i=a('input[name="_page"]',"#comments-form");h=function(o,n){var p=a("#"+n.element);if(p.is(".unapproved")){p.find("div.comment_status").html("0")}else{p.find("div.comment_status").html("1")}a("span.pending-count").each(function(){var q=a(this),s,r;s=q.html().replace(/[^0-9]+/g,"");s=parseInt(s,10);if(isNaN(s)){return}r=a("#"+n.element).is("."+n.dimClass)?1:-1;s=s+r;if(s<0){s=0}q.closest("#awaiting-mod")[0==s?"addClass":"removeClass"]("count-0");g(q,s);k()})};j=function(r,v){var x=a(r.target).attr("className"),o,p,q,u,w,t,s=false;r.data._total=d.val()||0;r.data._per_page=f.val()||0;r.data._page=i.val()||0;r.data._url=document.location.href;r.data.comment_status=a("input[name=comment_status]","#comments-form").val();if(x.indexOf(":trash=1")!=-1){s="trash"}else{if(x.indexOf(":spam=1")!=-1){s="spam"}}if(s){o=x.replace(/.*?comment-([0-9]+).*/,"$1");p=a("#comment-"+o);note=a("#"+s+"-undo-holder").html();p.find(".check-column :checkbox").attr("checked","");if(p.siblings("#replyrow").length&&commentReply.cid==o){commentReply.close()}if(p.is("tr")){q=p.children(":visible").length;t=a(".author strong",p).text();u=a(''+note+"")}else{t=a(".comment-author",p).text();u=a('")}p.before(u);a("strong","#undo-"+o).text(t+" ");w=a(".undo a","#undo-"+o);w.attr("href","comment.php?action=un"+s+"comment&c="+o+"&_wpnonce="+r.data._ajax_nonce);w.attr("className","delete:the-comment-list:comment-"+o+"::un"+s+"=1 vim-z vim-destructive");a(".avatar",p).clone().prependTo("#undo-"+o+" ."+s+"-undo-inside");w.click(function(){v.wpList.del(this);a("#undo-"+o).css({backgroundColor:"#ceb"}).fadeOut(350,function(){a(this).remove();a("#comment-"+o).css("backgroundColor","").fadeIn(300,function(){a(this).show()})});return false})}return r};e=function(n,o,p){if(o3){while(q.length>3){o=thousandsSeparator+q.substr(q.length-3)+o;q=q.substr(0,q.length-3)}q=q+o}p.html(q)}l=function(n,p){var u,q,s,w=a(p.target).parent().is("span.untrash"),o=a(p.target).parent().is("span.unspam"),v,t;function x(r){if(a(p.target).parent().is("span."+r)){return 1}else{if(a("#"+p.element).is("."+r)){return -1}}return 0}v=x("spam");t=x("trash");if(w){t=-1}if(o){v=-1}a("span.pending-count").each(function(){var r=a(this),z=c(r),y=a("#"+p.element).is(".unapproved");if(a(p.target).parent().is("span.unapprove")||((w||o)&&y)){z=z+1}else{if(y){z=z-1}}if(z<0){z=0}r.closest("#awaiting-mod")[0==z?"addClass":"removeClass"]("count-0");g(r,z);k()});a("span.spam-count").each(function(){var r=a(this),y=c(r)+v;g(r,y)});a("span.trash-count").each(function(){var r=a(this),y=c(r)+t;g(r,y)});if(a("#dashboard_right_now").length){s=t?-1*t:0;k(s)}else{u=d.val()?parseInt(d.val(),10):0;u=u-v-t;if(u<0){u=0}if(("object"==typeof n)&&mn){return}if(s){theExtraList.empty();o.number=Math.min(8,p)}else{o.number=1;o.offset=Math.min(8,p)-1}o.no_placeholder=true;o.paged++;if(true===o.comment_type){o.comment_type=""}o=a.extend(o,{action:"fetch-list",list_args:list_args,_ajax_fetch_list_nonce:a("#_ajax_fetch_list_nonce").val()});a.ajax({url:ajaxurl,global:false,dataType:"json",data:o,success:function(r){theExtraList.get(0).wpList.add(r.rows)}})};theExtraList=a("#the-extra-comment-list").wpList({alt:"",delColor:"none",addColor:"none"});theList=a("#the-comment-list").wpList({alt:"",delBefore:j,dimAfter:h,delAfter:l,addColor:"none"}).bind("wpListDelEnd",function(o,n){var p=n.element.replace(/[^0-9]+/g,"");if(n.target.className.indexOf(":trash=1")!=-1||n.target.className.indexOf(":spam=1")!=-1){a("#undo-"+p).fadeIn(300,function(){a(this).show()})}})};commentReply={cid:"",act:"",init:function(){var b=a("#replyrow");a("a.cancel",b).click(function(){return commentReply.revert()});a("a.save",b).click(function(){return commentReply.send()});a("input#author, input#author-email, input#author-url",b).keypress(function(c){if(c.which==13){commentReply.send();c.preventDefault();return false}});a("#the-comment-list .column-comment > p").dblclick(function(){commentReply.toggle(a(this).parent())});a("#doaction, #doaction2, #post-query-submit").click(function(c){if(a("#the-comment-list #replyrow").length>0){commentReply.close()}});this.comments_listing=a('#comments-form > input[name="comment_status"]').val()||""},addEvents:function(b){b.each(function(){a(this).find(".column-comment > p").dblclick(function(){commentReply.toggle(a(this).parent())})})},toggle:function(b){if(a(b).css("display")!="none"){a(b).find("a.vim-q").click()}},revert:function(){if(a("#the-comment-list #replyrow").length<1){return false}a("#replyrow").fadeOut("fast",function(){commentReply.close()});return false},close:function(){var b;if(this.cid){b=a("#comment-"+this.cid);if(this.act=="edit-comment"){b.fadeIn(300,function(){b.show()}).css("backgroundColor","")}a("#replyrow").hide();a("#com-reply").append(a("#replyrow"));a("#replycontent").val("");a("input","#edithead").val("");a(".error","#replysubmit").html("").hide();a(".waiting","#replysubmit").hide();if(a.browser.msie){a("#replycontainer, #replycontent").css("height","120px")}else{a("#replycontainer").resizable("destroy").css("height","120px")}this.cid=""}},open:function(b,d,k){var l=this,e,f,i,g,j=a("#comment-"+b);l.close();l.cid=b;e=a("#replyrow");f=a("#inline-"+b);i=l.act=(k=="edit")?"edit-comment":"replyto-comment";a("#action",e).val(i);a("#comment_post_ID",e).val(d);a("#comment_ID",e).val(b);if(k=="edit"){a("#author",e).val(a("div.author",f).text());a("#author-email",e).val(a("div.author-email",f).text());a("#author-url",e).val(a("div.author-url",f).text());a("#status",e).val(a("div.comment_status",f).text());a("#replycontent",e).val(a("textarea.comment",f).val());a("#edithead, #savebtn",e).show();a("#replyhead, #replybtn",e).hide();g=j.height();if(g>220){if(a.browser.msie){a("#replycontainer, #replycontent",e).height(g-105)}else{a("#replycontainer",e).height(g-105)}}j.after(e).fadeOut("fast",function(){a("#replyrow").fadeIn(300,function(){a(this).show()})})}else{a("#edithead, #savebtn",e).hide();a("#replyhead, #replybtn",e).show();j.after(e);a("#replyrow").fadeIn(300,function(){a(this).show()})}if(!a.browser.msie){a("#replycontainer").resizable({handles:"s",axis:"y",minHeight:80,stop:function(){a("#replycontainer").width("auto")}})}setTimeout(function(){var n,h,o,c,m;n=a("#replyrow").offset().top;h=n+a("#replyrow").height();o=window.pageYOffset||document.documentElement.scrollTop;c=document.documentElement.clientHeight||self.innerHeight||0;m=o+c;if(m-20]*?>/g,"")}if(c){a("#replysubmit .error").html(c).show()}}};a(document).ready(function(){var e,b,c,d;setCommentsList();commentReply.init();a(document).delegate("span.delete a.delete","click",function(){return false});if(typeof QTags!="undefined"){ed_reply=new QTags("ed_reply","replycontent","replycontainer","more")}if(typeof a.table_hotkeys!="undefined"){e=function(f){return function(){var h,g;h="next"==f?"first":"last";g=a(".tablenav-pages ."+f+"-page:not(.disabled)");if(g.length){window.location=g[0].href.replace(/\&hotkeys_highlight_(first|last)=1/g,"")+"&hotkeys_highlight_"+h+"=1"}}};b=function(g,f){window.location=a("span.edit a",f).attr("href")};c=function(){toggleWithKeyboard=true;a("input:checkbox","#cb").click().attr("checked","");toggleWithKeyboard=false};d=function(f){return function(){var g=a('select[name="action"]');a("option[value="+f+"]",g).attr("selected","selected");a("#doaction").click()}};a.table_hotkeys(a("table.widefat"),["a","u","s","d","r","q","z",["e",b],["shift+x",c],["shift+a",d("approve")],["shift+s",d("spam")],["shift+d",d("delete")],["shift+t",d("trash")],["shift+z",d("untrash")],["shift+u",d("unapprove")]],{highlight_first:adminCommentsL10n.hotkeys_highlight_first,highlight_last:adminCommentsL10n.hotkeys_highlight_last,prev_page_link_cb:e("prev"),next_page_link_cb:e("next")})}})})(jQuery); \ No newline at end of file diff --git a/src/wp-admin/js/editor.dev.js b/src/wp-admin/js/editor.dev.js new file mode 100644 index 00000000..cf582792 --- /dev/null +++ b/src/wp-admin/js/editor.dev.js @@ -0,0 +1,207 @@ + +jQuery(document).ready(function($){ + var h = wpCookies.getHash('TinyMCE_content_size'); + + if ( getUserSetting( 'editor' ) == 'html' ) { + if ( h ) + $('#content').css('height', h.ch - 15 + 'px'); + } else { + if ( typeof tinyMCE != 'object' ) { + $('#content').css('color', '#000'); + } else { + $('#quicktags').hide(); + } + } +}); + +var switchEditors = { + + mode : '', + + I : function(e) { + return document.getElementById(e); + }, + + _wp_Nop : function(content) { + var blocklist1, blocklist2; + + // Protect pre|script tags + if ( content.indexOf(']*>[\s\S]+?<\/\1>/g, function(a) { + a = a.replace(/
    (\r\n|\n)?/g, ''); + return a.replace(/<\/?p( [^>]*)?>(\r\n|\n)?/g, ''); + }); + } + + // Pretty it up for the source editor + blocklist1 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|div|h[1-6]|p|fieldset'; + content = content.replace(new RegExp('\\s*\\s*', 'g'), '\n'); + content = content.replace(new RegExp('\\s*<((?:'+blocklist1+')(?: [^>]*)?)>', 'g'), '\n<$1>'); + + // Mark

    if it has any attributes. + content = content.replace(/(

    ]+>.*?)<\/p>/g, '$1'); + + // Sepatate

    containing

    + content = content.replace(/]*)?>\s*

    /gi, '\n\n'); + + // Remove

    and
    + content = content.replace(/\s*

    /gi, ''); + content = content.replace(/\s*<\/p>\s*/gi, '\n\n'); + content = content.replace(/\n[\s\u00a0]+\n/g, '\n\n'); + content = content.replace(/\s*
    \s*/gi, '\n'); + + // Fix some block element newline issues + content = content.replace(/\s*

    \s*/g, '
    \n'); + content = content.replace(/\s*\[caption([^\[]+)\[\/caption\]\s*/gi, '\n\n[caption$1[/caption]\n\n'); + content = content.replace(/caption\]\n\n+\[caption/g, 'caption]\n\n[caption'); + + blocklist2 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|h[1-6]|pre|fieldset'; + content = content.replace(new RegExp('\\s*<((?:'+blocklist2+')(?: [^>]*)?)\\s*>', 'g'), '\n<$1>'); + content = content.replace(new RegExp('\\s*\\s*', 'g'), '\n'); + content = content.replace(/]*)>/g, '\t'); + + if ( content.indexOf(']*)?>\s*/g, '\n\n\n\n'); + } + + if ( content.indexOf('/g, function(a){ + return a.replace(/[\r\n]+/g, ''); + }); + } + + // Unmark special paragraph closing tags + content = content.replace(/<\/p#>/g, '

    \n'); + content = content.replace(/\s*(

    ]+>[\s\S]*?<\/p>)/g, '\n$1'); + + // Trim whitespace + content = content.replace(/^\s+/, ''); + content = content.replace(/[\s\u00a0]+$/, ''); + + // put back the line breaks in pre|script + content = content.replace(//g, '\n'); + + return content; + }, + + go : function(id, mode) { + id = id || 'content'; + mode = mode || this.mode || ''; + + var ed, qt = this.I('quicktags'), H = this.I('edButtonHTML'), P = this.I('edButtonPreview'), ta = this.I(id); + + try { ed = tinyMCE.get(id); } + catch(e) { ed = false; } + + if ( 'tinymce' == mode ) { + if ( ed && ! ed.isHidden() ) + return false; + + setUserSetting( 'editor', 'tinymce' ); + this.mode = 'html'; + + P.className = 'active'; + H.className = ''; + edCloseAllTags(); // :-( + qt.style.display = 'none'; + + ta.style.color = '#FFF'; + ta.value = this.wpautop(ta.value); + + try { + if ( ed ) + ed.show(); + else + tinyMCE.execCommand("mceAddControl", false, id); + } catch(e) {} + + ta.style.color = '#000'; + } else { + setUserSetting( 'editor', 'html' ); + ta.style.color = '#000'; + this.mode = 'tinymce'; + H.className = 'active'; + P.className = ''; + + if ( ed && !ed.isHidden() ) { + ta.style.height = ed.getContentAreaContainer().offsetHeight + 24 + 'px'; + ed.hide(); + } + + qt.style.display = 'block'; + } + return false; + }, + + _wp_Autop : function(pee) { + var blocklist = 'table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6]|fieldset|legend|hr'; + + if ( pee.indexOf('/g, function(a){ + return a.replace(/[\r\n]+/g, ''); + }); + } + + pee = pee.replace(/<[^<>]+>/g, function(a){ + return a.replace(/[\r\n]+/g, ' '); + }); + + // Protect pre|script tags + if ( pee.indexOf(']*>[\s\S]+?<\/\1>/g, function(a) { + return a.replace(/(\r\n|\n)/g, ''); + }); + } + + pee = pee + '\n\n'; + pee = pee.replace(/
    \s*
    /gi, '\n\n'); + pee = pee.replace(new RegExp('(<(?:'+blocklist+')(?: [^>]*)?>)', 'gi'), '\n$1'); + pee = pee.replace(new RegExp('()', 'gi'), '$1\n\n'); + pee = pee.replace(/]*)?>/gi, '\n\n'); // hr is self closing block element + pee = pee.replace(/\r\n|\r/g, '\n'); + pee = pee.replace(/\n\s*\n+/g, '\n\n'); + pee = pee.replace(/([\s\S]+?)\n\n/g, '

    $1

    \n'); + pee = pee.replace(/

    \s*?<\/p>/gi, ''); + pee = pee.replace(new RegExp('

    \\s*(]*)?>)\\s*

    ', 'gi'), "$1"); + pee = pee.replace(/

    (/gi, '$1'); + pee = pee.replace(/

    \s*]*)>/gi, '

    '); + pee = pee.replace(/<\/blockquote>\s*<\/p>/gi, '

    '); + pee = pee.replace(new RegExp('

    \\s*(]*)?>)', 'gi'), "$1"); + pee = pee.replace(new RegExp('(]*)?>)\\s*

    ', 'gi'), "$1"); + pee = pee.replace(/\s*\n/gi, '
    \n'); + pee = pee.replace(new RegExp('(]*>)\\s*
    ', 'gi'), "$1"); + pee = pee.replace(/
    (\s*<\/?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)/gi, '$1'); + pee = pee.replace(/(?:

    |
    )*\s*\[caption([^\[]+)\[\/caption\]\s*(?:<\/p>|
    )*/gi, '[caption$1[/caption]'); + + pee = pee.replace(/(<(?:div|th|td|form|fieldset|dd)[^>]*>)(.*?)<\/p>/g, function(a, b, c) { + if ( c.match(/]*)?>/) ) + return a; + + return b + '

    ' + c + '

    '; + }); + + // put back the line breaks in pre|script + pee = pee.replace(//g, '\n'); + + return pee; + }, + + pre_wpautop : function(content) { + var t = this, o = { o: t, data: content, unfiltered: content }; + + jQuery('body').trigger('beforePreWpautop', [o]); + o.data = t._wp_Nop(o.data); + jQuery('body').trigger('afterPreWpautop', [o]); + return o.data; + }, + + wpautop : function(pee) { + var t = this, o = { o: t, data: pee, unfiltered: pee }; + + jQuery('body').trigger('beforeWpautop', [o]); + o.data = t._wp_Autop(o.data); + jQuery('body').trigger('afterWpautop', [o]); + return o.data; + } +}; diff --git a/src/wp-admin/js/editor.js b/src/wp-admin/js/editor.js new file mode 100644 index 00000000..a37f6052 --- /dev/null +++ b/src/wp-admin/js/editor.js @@ -0,0 +1 @@ +jQuery(document).ready(function(b){var a=wpCookies.getHash("TinyMCE_content_size");if(getUserSetting("editor")=="html"){if(a){b("#content").css("height",a.ch-15+"px")}}else{if(typeof tinyMCE!="object"){b("#content").css("color","#000")}else{b("#quicktags").hide()}}});var switchEditors={mode:"",I:function(a){return document.getElementById(a)},_wp_Nop:function(b){var c,a;if(b.indexOf("]*>[\s\S]+?<\/\1>/g,function(d){d=d.replace(/
    (\r\n|\n)?/g,"");return d.replace(/<\/?p( [^>]*)?>(\r\n|\n)?/g,"")})}c="blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|div|h[1-6]|p|fieldset";b=b.replace(new RegExp("\\s*\\s*","g"),"\n");b=b.replace(new RegExp("\\s*<((?:"+c+")(?: [^>]*)?)>","g"),"\n<$1>");b=b.replace(/(

    ]+>.*?)<\/p>/g,"$1");b=b.replace(/]*)?>\s*

    /gi,"\n\n");b=b.replace(/\s*

    /gi,"");b=b.replace(/\s*<\/p>\s*/gi,"\n\n");b=b.replace(/\n[\s\u00a0]+\n/g,"\n\n");b=b.replace(/\s*
    \s*/gi,"\n");b=b.replace(/\s*

    \s*/g,"
    \n");b=b.replace(/\s*\[caption([^\[]+)\[\/caption\]\s*/gi,"\n\n[caption$1[/caption]\n\n");b=b.replace(/caption\]\n\n+\[caption/g,"caption]\n\n[caption");a="blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|h[1-6]|pre|fieldset";b=b.replace(new RegExp("\\s*<((?:"+a+")(?: [^>]*)?)\\s*>","g"),"\n<$1>");b=b.replace(new RegExp("\\s*\\s*","g"),"\n");b=b.replace(/]*)>/g,"\t");if(b.indexOf("]*)?>\s*/g,"\n\n\n\n")}if(b.indexOf("/g,function(d){return d.replace(/[\r\n]+/g,"")})}b=b.replace(/<\/p#>/g,"

    \n");b=b.replace(/\s*(

    ]+>[\s\S]*?<\/p>)/g,"\n$1");b=b.replace(/^\s+/,"");b=b.replace(/[\s\u00a0]+$/,"");b=b.replace(//g,"\n");return b},go:function(i,g){i=i||"content";g=g||this.mode||"";var b,h=this.I("quicktags"),c=this.I("edButtonHTML"),d=this.I("edButtonPreview"),a=this.I(i);try{b=tinyMCE.get(i)}catch(f){b=false}if("tinymce"==g){if(b&&!b.isHidden()){return false}setUserSetting("editor","tinymce");this.mode="html";d.className="active";c.className="";edCloseAllTags();h.style.display="none";a.style.color="#FFF";a.value=this.wpautop(a.value);try{if(b){b.show()}else{tinyMCE.execCommand("mceAddControl",false,i)}}catch(f){}a.style.color="#000"}else{setUserSetting("editor","html");a.style.color="#000";this.mode="tinymce";c.className="active";d.className="";if(b&&!b.isHidden()){a.style.height=b.getContentAreaContainer().offsetHeight+24+"px";b.hide()}h.style.display="block"}return false},_wp_Autop:function(a){var b="table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6]|fieldset|legend|hr";if(a.indexOf("/g,function(c){return c.replace(/[\r\n]+/g,"")})}a=a.replace(/<[^<>]+>/g,function(c){return c.replace(/[\r\n]+/g," ")});if(a.indexOf("]*>[\s\S]+?<\/\1>/g,function(c){return c.replace(/(\r\n|\n)/g,"")})}a=a+"\n\n";a=a.replace(/
    \s*
    /gi,"\n\n");a=a.replace(new RegExp("(<(?:"+b+")(?: [^>]*)?>)","gi"),"\n$1");a=a.replace(new RegExp("()","gi"),"$1\n\n");a=a.replace(/]*)?>/gi,"\n\n");a=a.replace(/\r\n|\r/g,"\n");a=a.replace(/\n\s*\n+/g,"\n\n");a=a.replace(/([\s\S]+?)\n\n/g,"

    $1

    \n");a=a.replace(/

    \s*?<\/p>/gi,"");a=a.replace(new RegExp("

    \\s*(]*)?>)\\s*

    ","gi"),"$1");a=a.replace(/

    (/gi,"$1");a=a.replace(/

    \s*]*)>/gi,"

    ");a=a.replace(/<\/blockquote>\s*<\/p>/gi,"

    ");a=a.replace(new RegExp("

    \\s*(]*)?>)","gi"),"$1");a=a.replace(new RegExp("(]*)?>)\\s*

    ","gi"),"$1");a=a.replace(/\s*\n/gi,"
    \n");a=a.replace(new RegExp("(]*>)\\s*
    ","gi"),"$1");a=a.replace(/
    (\s*<\/?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)/gi,"$1");a=a.replace(/(?:

    |
    )*\s*\[caption([^\[]+)\[\/caption\]\s*(?:<\/p>|
    )*/gi,"[caption$1[/caption]");a=a.replace(/(<(?:div|th|td|form|fieldset|dd)[^>]*>)(.*?)<\/p>/g,function(e,d,f){if(f.match(/]*)?>/)){return e}return d+"

    "+f+"

    "});a=a.replace(//g,"\n");return a},pre_wpautop:function(b){var a=this,c={o:a,data:b,unfiltered:b};jQuery("body").trigger("beforePreWpautop",[c]);c.data=a._wp_Nop(c.data);jQuery("body").trigger("afterPreWpautop",[c]);return c.data},wpautop:function(b){var a=this,c={o:a,data:b,unfiltered:b};jQuery("body").trigger("beforeWpautop",[c]);c.data=a._wp_Autop(c.data);jQuery("body").trigger("afterWpautop",[c]);return c.data}}; \ No newline at end of file diff --git a/src/wp-admin/js/farbtastic.js b/src/wp-admin/js/farbtastic.js new file mode 100644 index 00000000..5404fb6e --- /dev/null +++ b/src/wp-admin/js/farbtastic.js @@ -0,0 +1,276 @@ +/*! + * Farbtastic: jQuery color picker plug-in v1.3u + * + * Licensed under the GPL license: + * http://www.gnu.org/licenses/gpl.html + */ +(function($) { + +$.fn.farbtastic = function (options) { + $.farbtastic(this, options); + return this; +}; + +$.farbtastic = function (container, callback) { + var container = $(container).get(0); + return container.farbtastic || (container.farbtastic = new $._farbtastic(container, callback)); +}; + +$._farbtastic = function (container, callback) { + // Store farbtastic object + var fb = this; + + // Insert markup + $(container).html('
    '); + var e = $('.farbtastic', container); + fb.wheel = $('.wheel', container).get(0); + // Dimensions + fb.radius = 84; + fb.square = 100; + fb.width = 194; + + // Fix background PNGs in IE6 + if (navigator.appVersion.match(/MSIE [0-6]\./)) { + $('*', e).each(function () { + if (this.currentStyle.backgroundImage != 'none') { + var image = this.currentStyle.backgroundImage; + image = this.currentStyle.backgroundImage.substring(5, image.length - 2); + $(this).css({ + 'backgroundImage': 'none', + 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')" + }); + } + }); + } + + /** + * Link to the given element(s) or callback. + */ + fb.linkTo = function (callback) { + // Unbind previous nodes + if (typeof fb.callback == 'object') { + $(fb.callback).unbind('keyup', fb.updateValue); + } + + // Reset color + fb.color = null; + + // Bind callback or elements + if (typeof callback == 'function') { + fb.callback = callback; + } + else if (typeof callback == 'object' || typeof callback == 'string') { + fb.callback = $(callback); + fb.callback.bind('keyup', fb.updateValue); + if (fb.callback.get(0).value) { + fb.setColor(fb.callback.get(0).value); + } + } + return this; + }; + fb.updateValue = function (event) { + if (this.value && this.value != fb.color) { + fb.setColor(this.value); + } + }; + + /** + * Change color with HTML syntax #123456 + */ + fb.setColor = function (color) { + var unpack = fb.unpack(color); + if (fb.color != color && unpack) { + fb.color = color; + fb.rgb = unpack; + fb.hsl = fb.RGBToHSL(fb.rgb); + fb.updateDisplay(); + } + return this; + }; + + /** + * Change color with HSL triplet [0..1, 0..1, 0..1] + */ + fb.setHSL = function (hsl) { + fb.hsl = hsl; + fb.rgb = fb.HSLToRGB(hsl); + fb.color = fb.pack(fb.rgb); + fb.updateDisplay(); + return this; + }; + + ///////////////////////////////////////////////////// + + /** + * Retrieve the coordinates of the given event relative to the center + * of the widget. + */ + fb.widgetCoords = function (event) { + var offset = $(fb.wheel).offset(); + return { x: (event.pageX - offset.left) - fb.width / 2, y: (event.pageY - offset.top) - fb.width / 2 }; + }; + + /** + * Mousedown handler + */ + fb.mousedown = function (event) { + // Capture mouse + if (!document.dragging) { + $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup); + document.dragging = true; + } + + // Check which area is being dragged + var pos = fb.widgetCoords(event); + fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square; + + // Process + fb.mousemove(event); + return false; + }; + + /** + * Mousemove handler + */ + fb.mousemove = function (event) { + // Get coordinates relative to color picker center + var pos = fb.widgetCoords(event); + + // Set new HSL parameters + if (fb.circleDrag) { + var hue = Math.atan2(pos.x, -pos.y) / 6.28; + if (hue < 0) hue += 1; + fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]); + } + else { + var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5)); + var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5)); + fb.setHSL([fb.hsl[0], sat, lum]); + } + return false; + }; + + /** + * Mouseup handler + */ + fb.mouseup = function () { + // Uncapture mouse + $(document).unbind('mousemove', fb.mousemove); + $(document).unbind('mouseup', fb.mouseup); + document.dragging = false; + }; + + /** + * Update the markers and styles + */ + fb.updateDisplay = function () { + // Markers + var angle = fb.hsl[0] * 6.28; + $('.h-marker', e).css({ + left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px', + top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px' + }); + + $('.sl-marker', e).css({ + left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px', + top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px' + }); + + // Saturation/Luminance gradient + $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5]))); + + // Linked elements or callback + if (typeof fb.callback == 'object') { + // Set background/foreground color + $(fb.callback).css({ + backgroundColor: fb.color, + color: fb.hsl[2] > 0.5 ? '#000' : '#fff' + }); + + // Change linked value + $(fb.callback).each(function() { + if (this.value && this.value != fb.color) { + this.value = fb.color; + } + }); + } + else if (typeof fb.callback == 'function') { + fb.callback.call(fb, fb.color); + } + }; + + /* Various color utility functions */ + fb.pack = function (rgb) { + var r = Math.round(rgb[0] * 255); + var g = Math.round(rgb[1] * 255); + var b = Math.round(rgb[2] * 255); + return '#' + (r < 16 ? '0' : '') + r.toString(16) + + (g < 16 ? '0' : '') + g.toString(16) + + (b < 16 ? '0' : '') + b.toString(16); + }; + + fb.unpack = function (color) { + if (color.length == 7) { + return [parseInt('0x' + color.substring(1, 3)) / 255, + parseInt('0x' + color.substring(3, 5)) / 255, + parseInt('0x' + color.substring(5, 7)) / 255]; + } + else if (color.length == 4) { + return [parseInt('0x' + color.substring(1, 2)) / 15, + parseInt('0x' + color.substring(2, 3)) / 15, + parseInt('0x' + color.substring(3, 4)) / 15]; + } + }; + + fb.HSLToRGB = function (hsl) { + var m1, m2, r, g, b; + var h = hsl[0], s = hsl[1], l = hsl[2]; + m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s; + m1 = l * 2 - m2; + return [this.hueToRGB(m1, m2, h+0.33333), + this.hueToRGB(m1, m2, h), + this.hueToRGB(m1, m2, h-0.33333)]; + }; + + fb.hueToRGB = function (m1, m2, h) { + h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); + if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; + if (h * 2 < 1) return m2; + if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; + return m1; + }; + + fb.RGBToHSL = function (rgb) { + var min, max, delta, h, s, l; + var r = rgb[0], g = rgb[1], b = rgb[2]; + min = Math.min(r, Math.min(g, b)); + max = Math.max(r, Math.max(g, b)); + delta = max - min; + l = (min + max) / 2; + s = 0; + if (l > 0 && l < 1) { + s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); + } + h = 0; + if (delta > 0) { + if (max == r && max != g) h += (g - b) / delta; + if (max == g && max != b) h += (2 + (b - r) / delta); + if (max == b && max != r) h += (4 + (r - g) / delta); + h /= 6; + } + return [h, s, l]; + }; + + // Install mousedown handler (the others are set on the document on-demand) + $('*', e).mousedown(fb.mousedown); + + // Init color + fb.setColor('#000000'); + + // Set linked elements/callback + if (callback) { + fb.linkTo(callback); + } +}; + +})(jQuery); \ No newline at end of file diff --git a/src/wp-admin/js/gallery.dev.js b/src/wp-admin/js/gallery.dev.js new file mode 100644 index 00000000..4f3ce461 --- /dev/null +++ b/src/wp-admin/js/gallery.dev.js @@ -0,0 +1,205 @@ +jQuery(document).ready(function($) { + var gallerySortable, gallerySortableInit, w, desc = false; + + gallerySortableInit = function() { + gallerySortable = $('#media-items').sortable( { + items: 'div.media-item', + placeholder: 'sorthelper', + axis: 'y', + distance: 2, + handle: 'div.filename', + stop: function(e, ui) { + // When an update has occurred, adjust the order for each item + var all = $('#media-items').sortable('toArray'), len = all.length; + $.each(all, function(i, id) { + var order = desc ? (len - i) : (1 + i); + $('#' + id + ' .menu_order input').val(order); + }); + } + } ); + } + + sortIt = function() { + var all = $('.menu_order_input'), len = all.length; + all.each(function(i){ + var order = desc ? (len - i) : (1 + i); + $(this).val(order); + }); + } + + clearAll = function(c) { + c = c || 0; + $('.menu_order_input').each(function(){ + if ( this.value == '0' || c ) this.value = ''; + }); + } + + $('#asc').click(function(){desc = false; sortIt(); return false;}); + $('#desc').click(function(){desc = true; sortIt(); return false;}); + $('#clear').click(function(){clearAll(1); return false;}); + $('#showall').click(function(){ + $('#sort-buttons span a').toggle(); + $('a.describe-toggle-on').hide(); + $('a.describe-toggle-off, table.slidetoggle').show(); + return false; + }); + $('#hideall').click(function(){ + $('#sort-buttons span a').toggle(); + $('a.describe-toggle-on').show(); + $('a.describe-toggle-off, table.slidetoggle').hide(); + return false; + }); + + // initialize sortable + gallerySortableInit(); + clearAll(); + + if ( $('#media-items>*').length > 1 ) { + w = wpgallery.getWin(); + + $('#save-all, #gallery-settings').show(); + if ( typeof w.tinyMCE != 'undefined' && w.tinyMCE.activeEditor && ! w.tinyMCE.activeEditor.isHidden() ) { + wpgallery.mcemode = true; + wpgallery.init(); + } else { + $('#insert-gallery').show(); + } + } +}); + +jQuery(window).unload( function () { tinymce = tinyMCE = wpgallery = null; } ); // Cleanup + +/* gallery settings */ +var tinymce = null, tinyMCE, wpgallery; + +wpgallery = { + mcemode : false, + editor : {}, + dom : {}, + is_update : false, + el : {}, + + I : function(e) { + return document.getElementById(e); + }, + + init: function() { + var t = this, li, q, i, it, w = t.getWin(); + + if ( ! t.mcemode ) return; + + li = ('' + document.location.search).replace(/^\?/, '').split('&'); + q = {}; + for (i=0; i*").length>1){a=wpgallery.getWin();c("#save-all, #gallery-settings").show();if(typeof a.tinyMCE!="undefined"&&a.tinyMCE.activeEditor&&!a.tinyMCE.activeEditor.isHidden()){wpgallery.mcemode=true;wpgallery.init()}else{c("#insert-gallery").show()}}});jQuery(window).unload(function(){tinymce=tinyMCE=wpgallery=null});var tinymce=null,tinyMCE,wpgallery;wpgallery={mcemode:false,editor:{},dom:{},is_update:false,el:{},I:function(a){return document.getElementById(a)},init:function(){var d=this,a,f,c,e,b=d.getWin();if(!d.mcemode){return}a=(""+document.location.search).replace(/^\?/,"").split("&");f={};for(c=0;c this.hold['oh'] ) || ( w1 && w1 > this.hold['ow'] ) ) + warn.css('visibility', 'visible'); + else + warn.css('visibility', 'hidden'); + }, + + getSelRatio : function(postid) { + var x = this.hold['w'], y = this.hold['h'], + X = this.intval( $('#imgedit-crop-width-' + postid).val() ), + Y = this.intval( $('#imgedit-crop-height-' + postid).val() ); + + if ( X && Y ) + return X + ':' + Y; + + if ( x && y ) + return x + ':' + y; + + return '1:1'; + }, + + filterHistory : function(postid, setSize) { + // apply undo state to history + var history = $('#imgedit-history-' + postid).val(), pop, n, o, i, op = []; + + if ( history != '' ) { + history = JSON.parse(history); + pop = this.intval( $('#imgedit-undone-' + postid).val() ); + if ( pop > 0 ) { + while ( pop > 0 ) { + history.pop(); + pop--; + } + } + + if ( setSize ) { + if ( !history.length ) { + this.hold['w'] = this.hold['ow']; + this.hold['h'] = this.hold['oh']; + return ''; + } + + // restore + o = history[history.length - 1]; + o = o.c || o.r || o.f || false; + + if ( o ) { + this.hold['w'] = o.fw; + this.hold['h'] = o.fh; + } + } + + // filter the values + for ( n in history ) { + i = history[n]; + if ( i.hasOwnProperty('c') ) { + op[n] = { 'c': { 'x': i.c.x, 'y': i.c.y, 'w': i.c.w, 'h': i.c.h } }; + } else if ( i.hasOwnProperty('r') ) { + op[n] = { 'r': i.r.r }; + } else if ( i.hasOwnProperty('f') ) { + op[n] = { 'f': i.f.f }; + } + } + return JSON.stringify(op); + } + return ''; + }, + + refreshEditor : function(postid, nonce, callback) { + var t = this, data, img; + + t.toggleEditor(postid, 1); + data = { + 'action': 'imgedit-preview', + '_ajax_nonce': nonce, + 'postid': postid, + 'history': t.filterHistory(postid, 1), + 'rand': t.intval(Math.random() * 1000000) + }; + + img = $(''); + img.load( function() { + var max1, max2, parent = $('#imgedit-crop-' + postid), t = imageEdit; + + parent.empty().append(img); + + // w, h are the new full size dims + max1 = Math.max( t.hold.w, t.hold.h ); + max2 = Math.max( $(img).width(), $(img).height() ); + t.hold['sizer'] = max1 > max2 ? max2 / max1 : 1; + + t.initCrop(postid, img, parent); + t.setCropSelection(postid, 0); + + if ( (typeof callback != "unknown") && callback != null ) + callback(); + + if ( $('#imgedit-history-' + postid).val() && $('#imgedit-undone-' + postid).val() == 0 ) + $('input.imgedit-submit-btn', '#imgedit-panel-' + postid).removeAttr('disabled'); + else + $('input.imgedit-submit-btn', '#imgedit-panel-' + postid).attr('disabled', 'disabled'); + + t.toggleEditor(postid, 0); + }).attr('src', ajaxurl + '?' + $.param(data)); + }, + + action : function(postid, nonce, action) { + var t = this, data, w, h, fw, fh; + + if ( t.notsaved(postid) ) + return false; + + data = { + 'action': 'image-editor', + '_ajax_nonce': nonce, + 'postid': postid + }; + + if ( 'scale' == action ) { + w = $('#imgedit-scale-width-' + postid), + h = $('#imgedit-scale-height-' + postid), + fw = t.intval(w.val()), + fh = t.intval(h.val()); + + if ( fw < 1 ) { + w.focus(); + return false; + } else if ( fh < 1 ) { + h.focus(); + return false; + } + + if ( fw == t.hold.ow || fh == t.hold.oh ) + return false; + + data['do'] = 'scale'; + data['fwidth'] = fw; + data['fheight'] = fh; + } else if ( 'restore' == action ) { + data['do'] = 'restore'; + } else { + return false; + } + + t.toggleEditor(postid, 1); + $.post(ajaxurl, data, function(r) { + $('#image-editor-' + postid).empty().append(r); + t.toggleEditor(postid, 0); + }); + }, + + save : function(postid, nonce) { + var data, target = this.getTarget(postid), history = this.filterHistory(postid, 0); + + if ( '' == history ) + return false; + + this.toggleEditor(postid, 1); + data = { + 'action': 'image-editor', + '_ajax_nonce': nonce, + 'postid': postid, + 'history': history, + 'target': target, + 'do': 'save' + }; + + $.post(ajaxurl, data, function(r) { + var ret = JSON.parse(r); + + if ( ret.error ) { + $('#imgedit-response-' + postid).html('

    ' + ret.error + '

    '); + imageEdit.close(postid); + return; + } + + if ( ret.fw && ret.fh ) + $('#media-dims-' + postid).html( ret.fw + ' × ' + ret.fh ); + + if ( ret.thumbnail ) + $('.thumbnail', '#thumbnail-head-' + postid).attr('src', ''+ret.thumbnail); + + if ( ret.msg ) + $('#imgedit-response-' + postid).html('

    ' + ret.msg + '

    '); + + imageEdit.close(postid); + }); + }, + + open : function(postid, nonce) { + var data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid), + btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('img'); + + btn.attr('disabled', 'disabled'); + spin.css('visibility', 'visible'); + + data = { + 'action': 'image-editor', + '_ajax_nonce': nonce, + 'postid': postid, + 'do': 'open' + }; + + elem.load(ajaxurl, data, function() { + elem.fadeIn('fast'); + head.fadeOut('fast', function(){ + btn.removeAttr('disabled'); + spin.css('visibility', 'hidden'); + }); + }); + }, + + imgLoaded : function(postid) { + var img = $('#image-preview-' + postid), parent = $('#imgedit-crop-' + postid); + + this.initCrop(postid, img, parent); + this.setCropSelection(postid, 0); + this.toggleEditor(postid, 0); + }, + + initCrop : function(postid, image, parent) { + var t = this, selW = $('#imgedit-sel-width-' + postid), + selH = $('#imgedit-sel-height-' + postid); + + t.iasapi = $(image).imgAreaSelect({ + parent: parent, + instance: true, + handles: true, + keys: true, + minWidth: 3, + minHeight: 3, + + onInit: function(img, c) { + parent.children().mousedown(function(e){ + var ratio = false, sel, defRatio; + + if ( e.shiftKey ) { + sel = t.iasapi.getSelection(); + defRatio = t.getSelRatio(postid); + ratio = ( sel && sel.width && sel.height ) ? sel.width + ':' + sel.height : defRatio; + } + + t.iasapi.setOptions({ + aspectRatio: ratio + }); + }); + }, + + onSelectStart: function(img, c) { + imageEdit.setDisabled($('#imgedit-crop-sel-' + postid), 1); + }, + + onSelectEnd: function(img, c) { + imageEdit.setCropSelection(postid, c); + }, + + onSelectChange: function(img, c) { + var sizer = imageEdit.hold.sizer; + selW.val( imageEdit.round(c.width / sizer) ); + selH.val( imageEdit.round(c.height / sizer) ); + } + }); + }, + + setCropSelection : function(postid, c) { + var sel, min = $('#imgedit-minthumb-' + postid).val() || '128:128', + sizer = this.hold['sizer']; + min = min.split(':'); + c = c || 0; + + if ( !c || ( c.width < 3 && c.height < 3 ) ) { + this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 0); + this.setDisabled($('#imgedit-crop-sel-' + postid), 0); + $('#imgedit-sel-width-' + postid).val(''); + $('#imgedit-sel-height-' + postid).val(''); + $('#imgedit-selection-' + postid).val(''); + return false; + } + + if ( c.width < (min[0] * sizer) && c.height < (min[1] * sizer) ) { + this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 0); + $('#imgedit-selection-' + postid).val(''); + return false; + } + + sel = { 'x': c.x1, 'y': c.y1, 'w': c.width, 'h': c.height }; + this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 1); + $('#imgedit-selection-' + postid).val( JSON.stringify(sel) ); + }, + + close : function(postid, warn) { + warn = warn || false; + + if ( warn && this.notsaved(postid) ) + return false; + + this.iasapi = {}; + this.hold = {}; + $('#image-editor-' + postid).fadeOut('fast', function() { + $('#media-head-' + postid).fadeIn('fast'); + $(this).empty(); + }); + }, + + notsaved : function(postid) { + var h = $('#imgedit-history-' + postid).val(), + history = (h != '') ? JSON.parse(h) : new Array(), + pop = this.intval( $('#imgedit-undone-' + postid).val() ); + + if ( pop < history.length ) { + if ( confirm( $('#imgedit-leaving-' + postid).html() ) ) + return false; + return true; + } + return false; + }, + + addStep : function(op, postid, nonce) { + var t = this, elem = $('#imgedit-history-' + postid), + history = (elem.val() != '') ? JSON.parse(elem.val()) : new Array(), + undone = $('#imgedit-undone-' + postid), + pop = t.intval(undone.val()); + + while ( pop > 0 ) { + history.pop(); + pop--; + } + undone.val(0); // reset + + history.push(op); + elem.val( JSON.stringify(history) ); + + t.refreshEditor(postid, nonce, function() { + t.setDisabled($('#image-undo-' + postid), true); + t.setDisabled($('#image-redo-' + postid), false); + }); + }, + + rotate : function(angle, postid, nonce, t) { + if ( $(t).hasClass('disabled') ) + return false; + + this.addStep({ 'r': { 'r': angle, 'fw': this.hold['h'], 'fh': this.hold['w'] }}, postid, nonce); + }, + + flip : function (axis, postid, nonce, t) { + if ( $(t).hasClass('disabled') ) + return false; + + this.addStep({ 'f': { 'f': axis, 'fw': this.hold['w'], 'fh': this.hold['h'] }}, postid, nonce); + }, + + crop : function (postid, nonce, t) { + var sel = $('#imgedit-selection-' + postid).val(), + w = this.intval( $('#imgedit-sel-width-' + postid).val() ), + h = this.intval( $('#imgedit-sel-height-' + postid).val() ); + + if ( $(t).hasClass('disabled') || sel == '' ) + return false; + + sel = JSON.parse(sel); + if ( sel.w > 0 && sel.h > 0 && w > 0 && h > 0 ) { + sel['fw'] = w; + sel['fh'] = h; + this.addStep({ 'c': sel }, postid, nonce); + } + }, + + undo : function (postid, nonce) { + var t = this, button = $('#image-undo-' + postid), elem = $('#imgedit-undone-' + postid), + pop = t.intval( elem.val() ) + 1; + + if ( button.hasClass('disabled') ) + return; + + elem.val(pop); + t.refreshEditor(postid, nonce, function() { + var elem = $('#imgedit-history-' + postid), + history = (elem.val() != '') ? JSON.parse(elem.val()) : new Array(); + + t.setDisabled($('#image-redo-' + postid), true); + t.setDisabled(button, pop < history.length); + }); + }, + + redo : function(postid, nonce) { + var t = this, button = $('#image-redo-' + postid), elem = $('#imgedit-undone-' + postid), + pop = t.intval( elem.val() ) - 1; + + if ( button.hasClass('disabled') ) + return; + + elem.val(pop); + t.refreshEditor(postid, nonce, function() { + t.setDisabled($('#image-undo-' + postid), true); + t.setDisabled(button, pop > 0); + }); + }, + + setNumSelection : function(postid) { + var sel, elX = $('#imgedit-sel-width-' + postid), elY = $('#imgedit-sel-height-' + postid), + x = this.intval( elX.val() ), y = this.intval( elY.val() ), + img = $('#image-preview-' + postid), imgh = img.height(), imgw = img.width(), + sizer = this.hold['sizer'], x1, y1, x2, y2, ias = this.iasapi; + + if ( x < 1 ) { + elX.val(''); + return false; + } + + if ( y < 1 ) { + elY.val(''); + return false; + } + + if ( x && y && ( sel = ias.getSelection() ) ) { + x2 = sel.x1 + Math.round( x * sizer ); + y2 = sel.y1 + Math.round( y * sizer ); + x1 = sel.x1; + y1 = sel.y1; + + if ( x2 > imgw ) { + x1 = 0; + x2 = imgw; + elX.val( Math.round( x2 / sizer ) ); + } + + if ( y2 > imgh ) { + y1 = 0; + y2 = imgh; + elY.val( Math.round( y2 / sizer ) ); + } + + ias.setSelection( x1, y1, x2, y2 ); + ias.update(); + this.setCropSelection(postid, ias.getSelection()); + } + }, + + round : function(num) { + var s; + num = Math.round(num); + + if ( this.hold.sizer > 0.6 ) + return num; + + s = num.toString().slice(-1); + + if ( '1' == s ) + return num - 1; + else if ( '9' == s ) + return num + 1; + + return num; + }, + + setRatioSelection : function(postid, n, el) { + var sel, r, x = this.intval( $('#imgedit-crop-width-' + postid).val() ), + y = this.intval( $('#imgedit-crop-height-' + postid).val() ), + h = $('#image-preview-' + postid).height(); + + if ( !this.intval( $(el).val() ) ) { + $(el).val(''); + return; + } + + if ( x && y ) { + this.iasapi.setOptions({ + aspectRatio: x + ':' + y + }); + + if ( sel = this.iasapi.getSelection(true) ) { + r = Math.ceil( sel.y1 + ((sel.x2 - sel.x1) / (x / y)) ); + + if ( r > h ) { + r = h; + if ( n ) + $('#imgedit-crop-height-' + postid).val(''); + else + $('#imgedit-crop-width-' + postid).val(''); + } + + this.iasapi.setSelection( sel.x1, sel.y1, sel.x2, r ); + this.iasapi.update(); + } + } + } +} +})(jQuery); diff --git a/src/wp-admin/js/image-edit.js b/src/wp-admin/js/image-edit.js new file mode 100644 index 00000000..af3f5038 --- /dev/null +++ b/src/wp-admin/js/image-edit.js @@ -0,0 +1 @@ +var imageEdit;(function(a){imageEdit={iasapi:{},hold:{},postid:"",intval:function(b){return b|0},setDisabled:function(c,b){if(b){c.removeClass("disabled");a("input",c).removeAttr("disabled")}else{c.addClass("disabled");a("input",c).attr("disabled","disabled")}},init:function(g,e){var d=this,c=a("#image-editor-"+d.postid),b=d.intval(a("#imgedit-x-"+g).val()),f=d.intval(a("#imgedit-y-"+g).val());if(d.postid!=g&&c.length){d.close(d.postid)}d.hold.w=d.hold.ow=b;d.hold.h=d.hold.oh=f;d.hold.xy_ratio=b/f;d.hold.sizer=parseFloat(a("#imgedit-sizer-"+g).val());d.postid=g;a("#imgedit-response-"+g).empty();a('input[type="text"]',"#imgedit-panel-"+g).keypress(function(i){var h=i.keyCode;if(36this.hold.oh)||(c&&c>this.hold.ow)){g.css("visibility","visible")}else{g.css("visibility","hidden")}},getSelRatio:function(f){var b=this.hold.w,e=this.hold.h,d=this.intval(a("#imgedit-crop-width-"+f).val()),c=this.intval(a("#imgedit-crop-height-"+f).val());if(d&&c){return d+":"+c}if(b&&e){return b+":"+e}return"1:1"},filterHistory:function(j,f){var d=a("#imgedit-history-"+j).val(),b,h,e,c,g=[];if(d!=""){d=JSON.parse(d);b=this.intval(a("#imgedit-undone-"+j).val());if(b>0){while(b>0){d.pop();b--}}if(f){if(!d.length){this.hold.w=this.hold.ow;this.hold.h=this.hold.oh;return""}e=d[d.length-1];e=e.c||e.r||e.f||false;if(e){this.hold.w=e.fw;this.hold.h=e.fh}}for(h in d){c=d[h];if(c.hasOwnProperty("c")){g[h]={c:{x:c.c.x,y:c.c.y,w:c.c.w,h:c.c.h}}}else{if(c.hasOwnProperty("r")){g[h]={r:c.r.r}}else{if(c.hasOwnProperty("f")){g[h]={f:c.f.f}}}}}return JSON.stringify(g)}return""},refreshEditor:function(g,d,f){var c=this,e,b;c.toggleEditor(g,1);e={action:"imgedit-preview",_ajax_nonce:d,postid:g,history:c.filterHistory(g,1),rand:c.intval(Math.random()*1000000)};b=a('');b.load(function(){var i,h,k=a("#imgedit-crop-"+g),j=imageEdit;k.empty().append(b);i=Math.max(j.hold.w,j.hold.h);h=Math.max(a(b).width(),a(b).height());j.hold.sizer=i>h?h/i:1;j.initCrop(g,b,k);j.setCropSelection(g,0);if((typeof f!="unknown")&&f!=null){f()}if(a("#imgedit-history-"+g).val()&&a("#imgedit-undone-"+g).val()==0){a("input.imgedit-submit-btn","#imgedit-panel-"+g).removeAttr("disabled")}else{a("input.imgedit-submit-btn","#imgedit-panel-"+g).attr("disabled","disabled")}j.toggleEditor(g,0)}).attr("src",ajaxurl+"?"+a.param(e))},action:function(b,g,c){var j=this,e,i,f,d,k;if(j.notsaved(b)){return false}e={action:"image-editor",_ajax_nonce:g,postid:b};if("scale"==c){i=a("#imgedit-scale-width-"+b),f=a("#imgedit-scale-height-"+b),d=j.intval(i.val()),k=j.intval(f.val());if(d<1){i.focus();return false}else{if(k<1){f.focus();return false}}if(d==j.hold.ow||k==j.hold.oh){return false}e["do"]="scale";e.fwidth=d;e.fheight=k}else{if("restore"==c){e["do"]="restore"}else{return false}}j.toggleEditor(b,1);a.post(ajaxurl,e,function(h){a("#image-editor-"+b).empty().append(h);j.toggleEditor(b,0)})},save:function(f,b){var c,e=this.getTarget(f),d=this.filterHistory(f,0);if(""==d){return false}this.toggleEditor(f,1);c={action:"image-editor",_ajax_nonce:b,postid:f,history:d,target:e,"do":"save"};a.post(ajaxurl,c,function(h){var g=JSON.parse(h);if(g.error){a("#imgedit-response-"+f).html('

    '+g.error+"

    ");imageEdit.close(f);return}if(g.fw&&g.fh){a("#media-dims-"+f).html(g.fw+" × "+g.fh)}if(g.thumbnail){a(".thumbnail","#thumbnail-head-"+f).attr("src",""+g.thumbnail)}if(g.msg){a("#imgedit-response-"+f).html('

    '+g.msg+"

    ")}imageEdit.close(f)})},open:function(h,d){var f,e=a("#image-editor-"+h),c=a("#media-head-"+h),b=a("#imgedit-open-btn-"+h),g=b.siblings("img");b.attr("disabled","disabled");g.css("visibility","visible");f={action:"image-editor",_ajax_nonce:d,postid:h,"do":"open"};e.load(ajaxurl,f,function(){e.fadeIn("fast");c.fadeOut("fast",function(){b.removeAttr("disabled");g.css("visibility","hidden")})})},imgLoaded:function(d){var b=a("#image-preview-"+d),c=a("#imgedit-crop-"+d);this.initCrop(d,b,c);this.setCropSelection(d,0);this.toggleEditor(d,0)},initCrop:function(g,e,c){var b=this,d=a("#imgedit-sel-width-"+g),f=a("#imgedit-sel-height-"+g);b.iasapi=a(e).imgAreaSelect({parent:c,instance:true,handles:true,keys:true,minWidth:3,minHeight:3,onInit:function(h,i){c.children().mousedown(function(m){var k=false,l,j;if(m.shiftKey){l=b.iasapi.getSelection();j=b.getSelRatio(g);k=(l&&l.width&&l.height)?l.width+":"+l.height:j}b.iasapi.setOptions({aspectRatio:k})})},onSelectStart:function(h,i){imageEdit.setDisabled(a("#imgedit-crop-sel-"+g),1)},onSelectEnd:function(h,i){imageEdit.setCropSelection(g,i)},onSelectChange:function(h,j){var i=imageEdit.hold.sizer;d.val(imageEdit.round(j.width/i));f.val(imageEdit.round(j.height/i))}})},setCropSelection:function(g,f){var e,b=a("#imgedit-minthumb-"+g).val()||"128:128",d=this.hold.sizer;b=b.split(":");f=f||0;if(!f||(f.width<3&&f.height<3)){this.setDisabled(a(".imgedit-crop","#imgedit-panel-"+g),0);this.setDisabled(a("#imgedit-crop-sel-"+g),0);a("#imgedit-sel-width-"+g).val("");a("#imgedit-sel-height-"+g).val("");a("#imgedit-selection-"+g).val("");return false}if(f.width<(b[0]*d)&&f.height<(b[1]*d)){this.setDisabled(a(".imgedit-crop","#imgedit-panel-"+g),0);a("#imgedit-selection-"+g).val("");return false}e={x:f.x1,y:f.y1,w:f.width,h:f.height};this.setDisabled(a(".imgedit-crop","#imgedit-panel-"+g),1);a("#imgedit-selection-"+g).val(JSON.stringify(e))},close:function(c,b){b=b||false;if(b&&this.notsaved(c)){return false}this.iasapi={};this.hold={};a("#image-editor-"+c).fadeOut("fast",function(){a("#media-head-"+c).fadeIn("fast");a(this).empty()})},notsaved:function(e){var c=a("#imgedit-history-"+e).val(),d=(c!="")?JSON.parse(c):new Array(),b=this.intval(a("#imgedit-undone-"+e).val());if(b0){g.pop();b--}f.val(0);g.push(i);e.val(JSON.stringify(g));c.refreshEditor(h,d,function(){c.setDisabled(a("#image-undo-"+h),true);c.setDisabled(a("#image-redo-"+h),false)})},rotate:function(d,e,c,b){if(a(b).hasClass("disabled")){return false}this.addStep({r:{r:d,fw:this.hold.h,fh:this.hold.w}},e,c)},flip:function(d,e,c,b){if(a(b).hasClass("disabled")){return false}this.addStep({f:{f:d,fw:this.hold.w,fh:this.hold.h}},e,c)},crop:function(g,e,c){var f=a("#imgedit-selection-"+g).val(),b=this.intval(a("#imgedit-sel-width-"+g).val()),d=this.intval(a("#imgedit-sel-height-"+g).val());if(a(c).hasClass("disabled")||f==""){return false}f=JSON.parse(f);if(f.w>0&&f.h>0&&b>0&&d>0){f.fw=b;f.fh=d;this.addStep({c:f},g,e)}},undo:function(g,e){var d=this,c=a("#image-undo-"+g),f=a("#imgedit-undone-"+g),b=d.intval(f.val())+1;if(c.hasClass("disabled")){return}f.val(b);d.refreshEditor(g,e,function(){var h=a("#imgedit-history-"+g),i=(h.val()!="")?JSON.parse(h.val()):new Array();d.setDisabled(a("#image-redo-"+g),true);d.setDisabled(c,b0)})},setNumSelection:function(c){var g,k=a("#imgedit-sel-width-"+c),j=a("#imgedit-sel-height-"+c),o=this.intval(k.val()),m=this.intval(j.val()),i=a("#image-preview-"+c),p=i.height(),h=i.width(),b=this.hold.sizer,f,n,e,l,d=this.iasapi;if(o<1){k.val("");return false}if(m<1){j.val("");return false}if(o&&m&&(g=d.getSelection())){e=g.x1+Math.round(o*b);l=g.y1+Math.round(m*b);f=g.x1;n=g.y1;if(e>h){f=0;e=h;k.val(Math.round(e/b))}if(l>p){n=0;l=p;j.val(Math.round(l/b))}d.setSelection(f,n,e,l);d.update();this.setCropSelection(c,d.getSelection())}},round:function(b){var c;b=Math.round(b);if(this.hold.sizer>0.6){return b}c=b.toString().slice(-1);if("1"==c){return b-1}else{if("9"==c){return b+1}}return b},setRatioSelection:function(j,i,d){var f,e,b=this.intval(a("#imgedit-crop-width-"+j).val()),g=this.intval(a("#imgedit-crop-height-"+j).val()),c=a("#image-preview-"+j).height();if(!this.intval(a(d).val())){a(d).val("");return}if(b&&g){this.iasapi.setOptions({aspectRatio:b+":"+g});if(f=this.iasapi.getSelection(true)){e=Math.ceil(f.y1+((f.x2-f.x1)/(b/g)));if(e>c){e=c;if(i){a("#imgedit-crop-height-"+j).val("")}else{a("#imgedit-crop-width-"+j).val("")}}this.iasapi.setSelection(f.x1,f.y1,f.x2,e);this.iasapi.update()}}}}})(jQuery); \ No newline at end of file diff --git a/src/wp-admin/js/inline-edit-post.dev.js b/src/wp-admin/js/inline-edit-post.dev.js new file mode 100644 index 00000000..96b36fed --- /dev/null +++ b/src/wp-admin/js/inline-edit-post.dev.js @@ -0,0 +1,289 @@ +(function($) { +inlineEditPost = { + + init : function(){ + var t = this, qeRow = $('#inline-edit'), bulkRow = $('#bulk-edit'); + + t.type = $('table.widefat').hasClass('pages') ? 'page' : 'post'; + t.what = '#post-'; + + // prepare the edit rows + qeRow.keyup(function(e){ + if (e.which == 27) + return inlineEditPost.revert(); + }); + bulkRow.keyup(function(e){ + if (e.which == 27) + return inlineEditPost.revert(); + }); + + $('a.cancel', qeRow).click(function(){ + return inlineEditPost.revert(); + }); + $('a.save', qeRow).click(function(){ + return inlineEditPost.save(this); + }); + $('td', qeRow).keydown(function(e){ + if ( e.which == 13 ) + return inlineEditPost.save(this); + }); + + $('a.cancel', bulkRow).click(function(){ + return inlineEditPost.revert(); + }); + + $('#inline-edit .inline-edit-private input[value=private]').click( function(){ + var pw = $('input.inline-edit-password-input'); + if ( $(this).attr('checked') ) { + pw.val('').attr('disabled', 'disabled'); + } else { + pw.attr('disabled', ''); + } + }); + + // add events + $('a.editinline').live('click', function(){ + inlineEditPost.edit(this); + return false; + }); + + $('#bulk-title-div').parents('fieldset').after( + $('#inline-edit fieldset.inline-edit-categories').clone() + ).siblings( 'fieldset:last' ).prepend( + $('#inline-edit label.inline-edit-tags').clone() + ); + + // hiearchical taxonomies expandable? + $('span.catshow').click(function(){ + $(this).hide().next().show().parent().next().addClass("cat-hover"); + }); + + $('span.cathide').click(function(){ + $(this).hide().prev().show().parent().next().removeClass("cat-hover"); + }); + + $('select[name="_status"] option[value="future"]', bulkRow).remove(); + + $('#doaction, #doaction2').click(function(e){ + var n = $(this).attr('id').substr(2); + if ( $('select[name="'+n+'"]').val() == 'edit' ) { + e.preventDefault(); + t.setBulk(); + } else if ( $('form#posts-filter tr.inline-editor').length > 0 ) { + t.revert(); + } + }); + + $('#post-query-submit').click(function(e){ + if ( $('form#posts-filter tr.inline-editor').length > 0 ) + t.revert(); + }); + }, + + toggle : function(el){ + var t = this; + $(t.what+t.getId(el)).css('display') == 'none' ? t.revert() : t.edit(el); + }, + + setBulk : function(){ + var te = '', type = this.type, tax, c = true; + this.revert(); + + $('#bulk-edit td').attr('colspan', $('.widefat:first thead th:visible').length); + $('table.widefat tbody').prepend( $('#bulk-edit') ); + $('#bulk-edit').addClass('inline-editor').show(); + + $('tbody th.check-column input[type="checkbox"]').each(function(i){ + if ( $(this).attr('checked') ) { + c = false; + var id = $(this).val(), theTitle; + theTitle = $('#inline_'+id+' .post_title').text() || inlineEditL10n.notitle; + te += '
    X'+theTitle+'
    '; + } + }); + + if ( c ) + return this.revert(); + + $('#bulk-titles').html(te); + $('#bulk-titles a').click(function(){ + var id = $(this).attr('id').substr(1); + + $('table.widefat input[value="'+id+'"]').attr('checked', ''); + $('#ttle'+id).remove(); + }); + + // enable autocomplete for tags + if ( 'post' == type ) { + // support multi taxonomies? + tax = 'post_tag'; + $('tr.inline-editor textarea[name="tags_input"]').suggest( 'admin-ajax.php?action=ajax-tag-search&tax='+tax, { delay: 500, minchars: 2, multiple: true, multipleSep: ", " } ); + } + }, + + edit : function(id) { + var t = this, fields, editRow, rowData, cats, status, pageOpt, pageLevel, nextPage, pageLoop = true, nextLevel, tax; + t.revert(); + + if ( typeof(id) == 'object' ) + id = t.getId(id); + + fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password']; + if ( t.type == 'page' ) + fields.push('post_parent', 'menu_order', 'page_template'); + + // add the new blank row + editRow = $('#inline-edit').clone(true); + $('td', editRow).attr('colspan', $('.widefat:first thead th:visible').length); + + if ( $(t.what+id).hasClass('alternate') ) + $(editRow).addClass('alternate'); + $(t.what+id).hide().after(editRow); + + // populate the data + rowData = $('#inline_'+id); + if ( !$(':input[name="post_author"] option[value=' + $('.post_author', rowData).text() + ']', editRow).val() ) { + // author no longer has edit caps, so we need to add them to the list of authors + $(':input[name="post_author"]', editRow).prepend(''); + } + if ( $(':input[name="post_author"] option', editRow).length == 1 ) { + $('label.inline-edit-author', editRow).hide(); + } + + for ( var f = 0; f < fields.length; f++ ) { + $(':input[name="'+fields[f]+'"]', editRow).val( $('.'+fields[f], rowData).text() ); + } + + if ( $('.comment_status', rowData).text() == 'open' ) + $('input[name="comment_status"]', editRow).attr("checked", "checked"); + if ( $('.ping_status', rowData).text() == 'open' ) + $('input[name="ping_status"]', editRow).attr("checked", "checked"); + if ( $('.sticky', rowData).text() == 'sticky' ) + $('input[name="sticky"]', editRow).attr("checked", "checked"); + + // hierarchical taxonomies + $('.post_category', rowData).each(function(){ + var term_ids = $(this).text(); + + if ( term_ids ) { + taxname = $(this).attr('id').replace('_'+id, ''); + $('ul.'+taxname+'-checklist :checkbox', editRow).val(term_ids.split(',')); + } + }); + //flat taxonomies + $('.tags_input', rowData).each(function(){ + var terms = $(this).text(); + + if ( terms ) { + taxname = $(this).attr('id').replace('_'+id, ''); + $('textarea.tax_input_'+taxname, editRow).val(terms); + $('textarea.tax_input_'+taxname, editRow).suggest( 'admin-ajax.php?action=ajax-tag-search&tax='+taxname, { delay: 500, minchars: 2, multiple: true, multipleSep: ", " } ); + } + }); + + + // handle the post status + status = $('._status', rowData).text(); + if ( 'future' != status ) + $('select[name="_status"] option[value="future"]', editRow).remove(); + + if ( 'private' == status ) { + $('input[name="keep_private"]', editRow).attr("checked", "checked"); + $('input.inline-edit-password-input').val('').attr('disabled', 'disabled'); + } + + // remove the current page and children from the parent dropdown + pageOpt = $('select[name="post_parent"] option[value="'+id+'"]', editRow); + if ( pageOpt.length > 0 ) { + pageLevel = pageOpt[0].className.split('-')[1]; + nextPage = pageOpt; + while ( pageLoop ) { + nextPage = nextPage.next('option'); + if (nextPage.length == 0) break; + nextLevel = nextPage[0].className.split('-')[1]; + if ( nextLevel <= pageLevel ) { + pageLoop = false; + } else { + nextPage.remove(); + nextPage = pageOpt; + } + } + pageOpt.remove(); + } + + $(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show(); + $('.ptitle', editRow).focus(); + + return false; + }, + + save : function(id) { + var params, fields, page = $('.post_status_page').val() || ''; + + if ( typeof(id) == 'object' ) + id = this.getId(id); + + $('table.widefat .inline-edit-save .waiting').show(); + + params = { + action: 'inline-save', + post_type: typenow, + post_ID: id, + edit_date: 'true', + post_status: page + }; + + fields = $('#edit-'+id+' :input').serialize(); + params = fields + '&' + $.param(params); + + // make ajax request + $.post('admin-ajax.php', params, + function(r) { + $('table.widefat .inline-edit-save .waiting').hide(); + + if (r) { + if ( -1 != r.indexOf(']*?>/g, '' ); + $('#edit-'+id+' .inline-edit-save').append(''+r+''); + } + } else { + $('#edit-'+id+' .inline-edit-save').append(''+inlineEditL10n.error+''); + } + } + , 'html'); + return false; + }, + + revert : function(){ + var id = $('table.widefat tr.inline-editor').attr('id'); + + if ( id ) { + $('table.widefat .inline-edit-save .waiting').hide(); + + if ( 'bulk-edit' == id ) { + $('table.widefat #bulk-edit').removeClass('inline-editor').hide(); + $('#bulk-titles').html(''); + $('#inlineedit').append( $('#bulk-edit') ); + } else { + $('#'+id).remove(); + id = id.substr( id.lastIndexOf('-') + 1 ); + $(this.what+id).show(); + } + } + + return false; + }, + + getId : function(o) { + var id = $(o).closest('tr').attr('id'), + parts = id.split('-'); + return parts[parts.length - 1]; + } +}; + +$(document).ready(function(){inlineEditPost.init();}); +})(jQuery); diff --git a/src/wp-admin/js/inline-edit-post.js b/src/wp-admin/js/inline-edit-post.js new file mode 100644 index 00000000..e8a7750c --- /dev/null +++ b/src/wp-admin/js/inline-edit-post.js @@ -0,0 +1 @@ +(function(a){inlineEditPost={init:function(){var c=this,d=a("#inline-edit"),b=a("#bulk-edit");c.type=a("table.widefat").hasClass("pages")?"page":"post";c.what="#post-";d.keyup(function(f){if(f.which==27){return inlineEditPost.revert()}});b.keyup(function(f){if(f.which==27){return inlineEditPost.revert()}});a("a.cancel",d).click(function(){return inlineEditPost.revert()});a("a.save",d).click(function(){return inlineEditPost.save(this)});a("td",d).keydown(function(f){if(f.which==13){return inlineEditPost.save(this)}});a("a.cancel",b).click(function(){return inlineEditPost.revert()});a("#inline-edit .inline-edit-private input[value=private]").click(function(){var e=a("input.inline-edit-password-input");if(a(this).attr("checked")){e.val("").attr("disabled","disabled")}else{e.attr("disabled","")}});a("a.editinline").live("click",function(){inlineEditPost.edit(this);return false});a("#bulk-title-div").parents("fieldset").after(a("#inline-edit fieldset.inline-edit-categories").clone()).siblings("fieldset:last").prepend(a("#inline-edit label.inline-edit-tags").clone());a("span.catshow").click(function(){a(this).hide().next().show().parent().next().addClass("cat-hover")});a("span.cathide").click(function(){a(this).hide().prev().show().parent().next().removeClass("cat-hover")});a('select[name="_status"] option[value="future"]',b).remove();a("#doaction, #doaction2").click(function(f){var g=a(this).attr("id").substr(2);if(a('select[name="'+g+'"]').val()=="edit"){f.preventDefault();c.setBulk()}else{if(a("form#posts-filter tr.inline-editor").length>0){c.revert()}}});a("#post-query-submit").click(function(f){if(a("form#posts-filter tr.inline-editor").length>0){c.revert()}})},toggle:function(c){var b=this;a(b.what+b.getId(c)).css("display")=="none"?b.revert():b.edit(c)},setBulk:function(){var e="",d=this.type,b,f=true;this.revert();a("#bulk-edit td").attr("colspan",a(".widefat:first thead th:visible").length);a("table.widefat tbody").prepend(a("#bulk-edit"));a("#bulk-edit").addClass("inline-editor").show();a('tbody th.check-column input[type="checkbox"]').each(function(g){if(a(this).attr("checked")){f=false;var h=a(this).val(),c;c=a("#inline_"+h+" .post_title").text()||inlineEditL10n.notitle;e+='
    X'+c+"
    "}});if(f){return this.revert()}a("#bulk-titles").html(e);a("#bulk-titles a").click(function(){var c=a(this).attr("id").substr(1);a('table.widefat input[value="'+c+'"]').attr("checked","");a("#ttle"+c).remove()});if("post"==d){b="post_tag";a('tr.inline-editor textarea[name="tags_input"]').suggest("admin-ajax.php?action=ajax-tag-search&tax="+b,{delay:500,minchars:2,multiple:true,multipleSep:", "})}},edit:function(b){var o=this,j,d,g,n,i,h,m,l,c=true,p,e;o.revert();if(typeof(b)=="object"){b=o.getId(b)}j=["post_title","post_name","post_author","_status","jj","mm","aa","hh","mn","ss","post_password"];if(o.type=="page"){j.push("post_parent","menu_order","page_template")}d=a("#inline-edit").clone(true);a("td",d).attr("colspan",a(".widefat:first thead th:visible").length);if(a(o.what+b).hasClass("alternate")){a(d).addClass("alternate")}a(o.what+b).hide().after(d);g=a("#inline_"+b);if(!a(':input[name="post_author"] option[value='+a(".post_author",g).text()+"]",d).val()){a(':input[name="post_author"]',d).prepend('")}if(a(':input[name="post_author"] option',d).length==1){a("label.inline-edit-author",d).hide()}for(var k=0;k0){m=h[0].className.split("-")[1];l=h;while(c){l=l.next("option");if(l.length==0){break}p=l[0].className.split("-")[1];if(p<=m){c=false}else{l.remove();l=h}}h.remove()}a(d).attr("id","edit-"+b).addClass("inline-editor").show();a(".ptitle",d).focus();return false},save:function(e){var d,b,c=a(".post_status_page").val()||"";if(typeof(e)=="object"){e=this.getId(e)}a("table.widefat .inline-edit-save .waiting").show();d={action:"inline-save",post_type:typenow,post_ID:e,edit_date:"true",post_status:c};b=a("#edit-"+e+" :input").serialize();d=b+"&"+a.param(d);a.post("admin-ajax.php",d,function(f){a("table.widefat .inline-edit-save .waiting").hide();if(f){if(-1!=f.indexOf("]*?>/g,"");a("#edit-"+e+" .inline-edit-save").append(''+f+"")}}else{a("#edit-"+e+" .inline-edit-save").append(''+inlineEditL10n.error+"")}},"html");return false},revert:function(){var b=a("table.widefat tr.inline-editor").attr("id");if(b){a("table.widefat .inline-edit-save .waiting").hide();if("bulk-edit"==b){a("table.widefat #bulk-edit").removeClass("inline-editor").hide();a("#bulk-titles").html("");a("#inlineedit").append(a("#bulk-edit"))}else{a("#"+b).remove();b=b.substr(b.lastIndexOf("-")+1);a(this.what+b).show()}}return false},getId:function(c){var d=a(c).closest("tr").attr("id"),b=d.split("-");return b[b.length-1]}};a(document).ready(function(){inlineEditPost.init()})})(jQuery); \ No newline at end of file diff --git a/src/wp-admin/js/inline-edit-tax.dev.js b/src/wp-admin/js/inline-edit-tax.dev.js new file mode 100644 index 00000000..a6c228a7 --- /dev/null +++ b/src/wp-admin/js/inline-edit-tax.dev.js @@ -0,0 +1,119 @@ + +(function($) { +inlineEditTax = { + + init : function() { + var t = this, row = $('#inline-edit'); + + t.type = $('#the-list').attr('className').substr(5); + t.what = '#'+t.type+'-'; + + $('.editinline').live('click', function(){ + inlineEditTax.edit(this); + return false; + }); + + // prepare the edit row + row.keyup(function(e) { if(e.which == 27) return inlineEditTax.revert(); }); + + $('a.cancel', row).click(function() { return inlineEditTax.revert(); }); + $('a.save', row).click(function() { return inlineEditTax.save(this); }); + $('input, select', row).keydown(function(e) { if(e.which == 13) return inlineEditTax.save(this); }); + + $('#posts-filter input[type="submit"]').click(function(e){ + if ( $('form#posts-filter tr.inline-editor').length > 0 ) + t.revert(); + }); + }, + + toggle : function(el) { + var t = this; + $(t.what+t.getId(el)).css('display') == 'none' ? t.revert() : t.edit(el); + }, + + edit : function(id) { + var t = this, editRow; + t.revert(); + + if ( typeof(id) == 'object' ) + id = t.getId(id); + + editRow = $('#inline-edit').clone(true), rowData = $('#inline_'+id); + $('td', editRow).attr('colspan', $('.widefat:first thead th:visible').length); + + if ( $(t.what+id).hasClass('alternate') ) + $(editRow).addClass('alternate'); + + $(t.what+id).hide().after(editRow); + + $(':input[name="name"]', editRow).val( $('.name', rowData).text() ); + $(':input[name="slug"]', editRow).val( $('.slug', rowData).text() ); + + $(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show(); + $('.ptitle', editRow).eq(0).focus(); + + return false; + }, + + save : function(id) { + var params, fields, tax = $('input[name="taxonomy"]').val() || ''; + + if( typeof(id) == 'object' ) + id = this.getId(id); + + $('table.widefat .inline-edit-save .waiting').show(); + + params = { + action: 'inline-save-tax', + tax_type: this.type, + tax_ID: id, + taxonomy: tax + }; + + fields = $('#edit-'+id+' :input').serialize(); + params = fields + '&' + $.param(params); + + // make ajax request + $.post('admin-ajax.php', params, + function(r) { + var row, new_id; + $('table.widefat .inline-edit-save .waiting').hide(); + + if (r) { + if ( -1 != r.indexOf('0){b.revert()}})},toggle:function(c){var b=this;a(b.what+b.getId(c)).css("display")=="none"?b.revert():b.edit(c)},edit:function(d){var c=this,b;c.revert();if(typeof(d)=="object"){d=c.getId(d)}b=a("#inline-edit").clone(true),rowData=a("#inline_"+d);a("td",b).attr("colspan",a(".widefat:first thead th:visible").length);if(a(c.what+d).hasClass("alternate")){a(b).addClass("alternate")}a(c.what+d).hide().after(b);a(':input[name="name"]',b).val(a(".name",rowData).text());a(':input[name="slug"]',b).val(a(".slug",rowData).text());a(b).attr("id","edit-"+d).addClass("inline-editor").show();a(".ptitle",b).eq(0).focus();return false},save:function(e){var d,b,c=a('input[name="taxonomy"]').val()||"";if(typeof(e)=="object"){e=this.getId(e)}a("table.widefat .inline-edit-save .waiting").show();d={action:"inline-save-tax",tax_type:this.type,tax_ID:e,taxonomy:c};b=a("#edit-"+e+" :input").serialize();d=b+"&"+a.param(d);a.post("admin-ajax.php",d,function(g){var h,f;a("table.widefat .inline-edit-save .waiting").hide();if(g){if(-1!=g.indexOf("' ).text( name ); + } ); + } ); + }; + + $('#categorychecklist').wpList( { + alt: '', + what: 'link-category', + response: 'category-ajax-response', + addAfter: catAddAfter + } ); + + $('a[href="#categories-all"]').click(function(){deleteUserSetting('cats');}); + $('a[href="#categories-pop"]').click(function(){setUserSetting('cats','pop');}); + if ( 'pop' == getUserSetting('cats') ) + $('a[href="#categories-pop"]').click(); + + $('#category-add-toggle').click( function() { + $(this).parents('div:first').toggleClass( 'wp-hidden-children' ); + $('#category-tabs a[href="#categories-all"]').click(); + $('#newcategory').focus(); + return false; + } ); + + $('.categorychecklist :checkbox').change( syncChecks ).filter( ':checked' ).change(); +}); diff --git a/src/wp-admin/js/link.js b/src/wp-admin/js/link.js new file mode 100644 index 00000000..e394d7d1 --- /dev/null +++ b/src/wp-admin/js/link.js @@ -0,0 +1 @@ +jQuery(document).ready(function(c){var b,a=false,d,e;c("#link_name").focus();postboxes.add_postbox_toggles("link");c("#category-tabs a").click(function(){var f=c(this).attr("href");c(this).parent().addClass("tabs").siblings("li").removeClass("tabs");c(".tabs-panel").hide();c(f).show();if("#categories-all"==f){deleteUserSetting("cats")}else{setUserSetting("cats","pop")}return false});if(getUserSetting("cats")){c('#category-tabs a[href="#categories-pop"]').click()}b=c("#newcat").one("focus",function(){c(this).val("").removeClass("form-input-tip")});c("#category-add-submit").click(function(){b.focus()});d=function(){if(a){return}a=true;var f=c(this),h=f.is(":checked"),g=f.val().toString();c("#in-link-category-"+g+", #in-popular-category-"+g).attr("checked",h);a=false};e=function(g,f){c(f.what+" response_data",g).each(function(){var h=c(c(this).text());h.find("label").each(function(){var j=c(this),l=j.find("input").val(),m=j.find("input")[0].id,i=c.trim(j.text()),k;c("#"+m).change(d);k=c('').text(i)})})};c("#categorychecklist").wpList({alt:"",what:"link-category",response:"category-ajax-response",addAfter:e});c('a[href="#categories-all"]').click(function(){deleteUserSetting("cats")});c('a[href="#categories-pop"]').click(function(){setUserSetting("cats","pop")});if("pop"==getUserSetting("cats")){c('a[href="#categories-pop"]').click()}c("#category-add-toggle").click(function(){c(this).parents("div:first").toggleClass("wp-hidden-children");c('#category-tabs a[href="#categories-all"]').click();c("#newcategory").focus();return false});c(".categorychecklist :checkbox").change(d).filter(":checked").change()}); \ No newline at end of file diff --git a/src/wp-admin/js/list-table.dev.js b/src/wp-admin/js/list-table.dev.js new file mode 100644 index 00000000..134005dd --- /dev/null +++ b/src/wp-admin/js/list-table.dev.js @@ -0,0 +1,337 @@ +jQuery(document).ready(function($) { + +window.listTable = { + + init: function() { + this.loading = false; + + this.reset( '.tablenav, .search-box, .wp-list-table' ); + + if ( '' == $.query.GET('paged') ) + $.query.SET('paged', 1); + this.set_total_pages(); + + this.$tbody = $('#the-list, #the-comment-list'); + }, + + /** + * Simulates form.reset() for all input, select, and textarea elements + * within a provided context. + */ + reset: function( context ) { + context = $(context); + + $('input', context).each( function(){ + this.value = this.defaultValue; + this.checked = this.defaultChecked; + }); + + $('select', context).each( function(){ + var options = $('option', this), + anySelected = false; + + options.each( function(){ + this.selected = this.defaultSelected; + anySelected = anySelected || this.defaultSelected; + }); + + // If no options are selected within a single-select dropdown, + // select the first element by default. + if ( ! this.multiple && ! anySelected ) + options[0].selected = true; + }); + + $('textarea', context).each( function(){ + this.value = this.defaultValue; + }); + }, + + // paging + set_total_pages: function(num) { + var last_page_url = $('.last-page').attr('href'); + + if ( last_page_url ) + this.total_pages = num || $.query.load( last_page_url ).get('paged'); + }, + + get_total_pages: function() { + return this.total_pages; + }, + + htmlencode: function(value) { + return $('
    ').text(value).html(); + }, + + update_rows: function(args, reset_paging, callback) { + if ( this.loading ) + return false; + + var different = false, data = {}; + + $.each(args, function(key, val) { + if ( val != $.query.GET(key) ) { + $.query.SET(key, val); + different = true; + } + }); + + if ( !different ) + return false; + + this.start_loading(); + + if ( reset_paging ) + $.query.SET('paged', 1); + + $.each( $.query.get(), function(key, value) { + if ( true === value ) + data[key] = ''; + else + data[key] = value; + }); + + this._callback = callback; + + this.fetch_list( + data, + $.proxy(this, 'handle_success'), + $.proxy(this, 'handle_error') + ); + + return true; + }, + + fetch_list: function(data, success_callback, error_callback) { + data = $.extend(data, { + 'action': 'fetch-list', + 'list_args': list_args, + '_ajax_fetch_list_nonce': $('#_ajax_fetch_list_nonce').val() + }); + + $.ajax({ + url: ajaxurl, + global: false, + dataType: 'json', + data: data, + success: success_callback, + error: error_callback + }); + }, + + handle_success: function(response) { + if ( 'object' != typeof response ) { + this.handle_error(); + } else { + var tablenav = $('.tablenav-pages'); + + this.stop_loading(); + + $('div.updated, div.error').not('.persistent, .inline').remove(); + + this.$tbody.html(response.rows); + + $('.displaying-num').html(response.total_items_i18n); + $('.total-pages').html(response.total_pages_i18n); + + this.set_total_pages(response.total_pages); + + if ( response.total_pages > 1 ) + tablenav.removeClass('one-page'); + + $('.current-page').val($.query.GET('paged')); + + // Disable buttons that should noop. + tablenav.find('.first-page, .prev-page').toggleClass('disabled', 1 == $.query.GET('paged')); + tablenav.find('.next-page, .last-page').toggleClass('disabled', response.total_pages == $.query.GET('paged')); + + $('th.column-cb :input').attr('checked', false); + + if ( history.replaceState ) { + history.replaceState({}, '', location.pathname + $.query); + } + + if ( this._callback ) + this._callback(); + } + }, + + handle_error: function() { + this.stop_loading(); + + $('h2').after('

    ' + listTableL10n.error + '

    '); + }, + + start_loading: function() { + this.loading = true; + + $('.error.ajax').remove(); + + $('.list-ajax-loading').css('visibility', 'visible'); + }, + + stop_loading: function() { + this.loading = false; + + $('.list-ajax-loading').css('visibility', 'hidden'); + } +} + +listTable.init(); + +// Ajaxify various UI elements + + function change_page(paged, $el) { + if ( paged < 1 ) + paged = 1; + + if ( paged > listTable.get_total_pages() ) + paged = listTable.get_total_pages(); + + $(listTable).trigger('beforeChangePage'); + listTable.update_rows({'paged': paged}, false, function() { + if ( $el.parents('.tablenav.bottom').length ) + scrollTo(0, 0); + + $(listTable).trigger('changePage'); + }); + } + + // pagination + $('.tablenav-pages a').click(function() { + var $el = $(this), + paged = $.query.GET('paged'); + + switch ( $el.attr('class') ) { + case 'first-page': + paged = 1; + break; + case 'prev-page': + paged -= 1; + break; + case 'next-page': + paged += 1; + break; + case 'last-page': + paged = listTable.get_total_pages(); + break; + } + + change_page(paged, $el); + + return false; + }); + + $('.current-page').keypress(function(e) { + if ( 13 != e.keyCode ) + return; + + var $el = $(this); + + change_page(parseInt($el.val()) || 1, $el); + + return false; + }); + + // sortable columns + $('th.sortable a, th.sorted a').click(function() { + + function get_initial_order($el) { + return $.query.load( $el.find('a').attr('href') ).get('order'); + } + + var $link = $(this), + $th = $link.parent('th'), + thIndex = $th.index(), + orderby = $.query.load( $link.attr('href') ).get('orderby'), + order; + + // th should include both headers in thead and tfoot + $th = $th.closest('table').find('thead th:eq(' + thIndex + '), tfoot th:eq(' + thIndex + ')'); + + if ( orderby == $.query.get('orderby') ) { + // changing the direction + order = ( 'asc' == $.query.get('order') ) ? 'desc' : 'asc'; + } else { + // changing the parameter + order = get_initial_order($th); + + var $old_th = $('th.sorted'); + if ( $old_th.length ) { + $old_th.removeClass('sorted').addClass('sortable'); + $old_th.removeClass('desc').removeClass('asc').addClass( + 'asc' == get_initial_order( $old_th ) ? 'desc' : 'asc' + ); + } + + $th.removeClass('sortable').addClass('sorted'); + } + + $th.removeClass('desc').removeClass('asc').addClass(order); + + listTable.update_rows({'orderby': orderby, 'order': order}, true); + + return false; + }); + + // searchbox + function change_search(ev) { + if ( 'keypress' == ev.type && 13 != ev.keyCode ) + return; + + ev.preventDefault(); + ev.stopImmediatePropagation(); + + var data = $(this).parent('.search-box').find(':input').serializeObject(); + + listTable.update_rows(data, true, function() { + if ( $('h2.nav-tab-wrapper').length ) + return; + + if ( 'site-users-network' == pagenow || 'site-themes-network' == pagenow ) { + $('h4.search-text').remove(); + + if ( data.s ) + $('ul.subsubsub').after($('

    ').html( + listTableL10n.search.replace('%s', this.htmlencode(data.s)) + )); + } else { + $('h2 .subtitle').remove(); + + if ( data.s ) + $('h2').append($('').html( + listTableL10n.search.replace('%s', this.htmlencode(data.s)) + )); + } + }); + } + $('.search-box :submit').click(change_search); + $('.search-box :text').keypress(change_search); + + // tablenav dropdowns + $('#post-query-submit').click(function() { + var args = {}; + + $(this).parents('.actions').find('select[name!="action"]').each(function() { + var $el = $(this); + + args[$el.attr('name')] = $el.val(); + }); + + listTable.update_rows(args, true); + + return false; + }); + + // view switch + $('.view-switch a').click(function() { + var $this = $(this); + + listTable.update_rows({'mode': $.query.load($this.attr('href')).get('mode')}, false, function() { + $('.view-switch .current').removeClass('current'); + $this.addClass('current'); + }); + + return false; + }); +}); + diff --git a/src/wp-admin/js/list-table.js b/src/wp-admin/js/list-table.js new file mode 100644 index 00000000..ab87daa7 --- /dev/null +++ b/src/wp-admin/js/list-table.js @@ -0,0 +1 @@ +jQuery(document).ready(function(a){window.listTable={init:function(){this.loading=false;this.reset(".tablenav, .search-box, .wp-list-table");if(""==a.query.GET("paged")){a.query.SET("paged",1)}this.set_total_pages();this.$tbody=a("#the-list, #the-comment-list")},reset:function(d){d=a(d);a("input",d).each(function(){this.value=this.defaultValue;this.checked=this.defaultChecked});a("select",d).each(function(){var e=a("option",this),f=false;e.each(function(){this.selected=this.defaultSelected;f=f||this.defaultSelected});if(!this.multiple&&!f){e[0].selected=true}});a("textarea",d).each(function(){this.value=this.defaultValue})},set_total_pages:function(e){var d=a(".last-page").attr("href");if(d){this.total_pages=e||a.query.load(d).get("paged")}},get_total_pages:function(){return this.total_pages},htmlencode:function(d){return a("
    ").text(d).html()},update_rows:function(e,d,h){if(this.loading){return false}var g=false,f={};a.each(e,function(i,j){if(j!=a.query.GET(i)){a.query.SET(i,j);g=true}});if(!g){return false}this.start_loading();if(d){a.query.SET("paged",1)}a.each(a.query.get(),function(i,j){if(true===j){f[i]=""}else{f[i]=j}});this._callback=h;this.fetch_list(f,a.proxy(this,"handle_success"),a.proxy(this,"handle_error"));return true},fetch_list:function(e,f,d){e=a.extend(e,{action:"fetch-list",list_args:list_args,_ajax_fetch_list_nonce:a("#_ajax_fetch_list_nonce").val()});a.ajax({url:ajaxurl,global:false,dataType:"json",data:e,success:f,error:d})},handle_success:function(d){if("object"!=typeof d){this.handle_error()}else{var e=a(".tablenav-pages");this.stop_loading();a("div.updated, div.error").not(".persistent, .inline").remove();this.$tbody.html(d.rows);a(".displaying-num").html(d.total_items_i18n);a(".total-pages").html(d.total_pages_i18n);this.set_total_pages(d.total_pages);if(d.total_pages>1){e.removeClass("one-page")}a(".current-page").val(a.query.GET("paged"));e.find(".first-page, .prev-page").toggleClass("disabled",1==a.query.GET("paged"));e.find(".next-page, .last-page").toggleClass("disabled",d.total_pages==a.query.GET("paged"));a("th.column-cb :input").attr("checked",false);if(history.replaceState){history.replaceState({},"",location.pathname+a.query)}if(this._callback){this._callback()}}},handle_error:function(){this.stop_loading();a("h2").after('

    '+listTableL10n.error+"

    ")},start_loading:function(){this.loading=true;a(".error.ajax").remove();a(".list-ajax-loading").css("visibility","visible")},stop_loading:function(){this.loading=false;a(".list-ajax-loading").css("visibility","hidden")}};listTable.init();function b(e,d){if(e<1){e=1}if(e>listTable.get_total_pages()){e=listTable.get_total_pages()}a(listTable).trigger("beforeChangePage");listTable.update_rows({paged:e},false,function(){if(d.parents(".tablenav.bottom").length){scrollTo(0,0)}a(listTable).trigger("changePage")})}a(".tablenav-pages a").click(function(){var e=a(this),d=a.query.GET("paged");switch(e.attr("class")){case"first-page":d=1;break;case"prev-page":d-=1;break;case"next-page":d+=1;break;case"last-page":d=listTable.get_total_pages();break}b(d,e);return false});a(".current-page").keypress(function(f){if(13!=f.keyCode){return}var d=a(this);b(parseInt(d.val())||1,d);return false});a("th.sortable a, th.sorted a").click(function(){function i(k){return a.query.load(k.find("a").attr("href")).get("order")}var f=a(this),h=f.parent("th"),g=h.index(),j=a.query.load(f.attr("href")).get("orderby"),e;h=h.closest("table").find("thead th:eq("+g+"), tfoot th:eq("+g+")");if(j==a.query.get("orderby")){e=("asc"==a.query.get("order"))?"desc":"asc"}else{e=i(h);var d=a("th.sorted");if(d.length){d.removeClass("sorted").addClass("sortable");d.removeClass("desc").removeClass("asc").addClass("asc"==i(d)?"desc":"asc")}h.removeClass("sortable").addClass("sorted")}h.removeClass("desc").removeClass("asc").addClass(e);listTable.update_rows({orderby:j,order:e},true);return false});function c(d){if("keypress"==d.type&&13!=d.keyCode){return}d.preventDefault();d.stopImmediatePropagation();var e=a(this).parent(".search-box").find(":input").serializeObject();listTable.update_rows(e,true,function(){if(a("h2.nav-tab-wrapper").length){return}if("site-users-network"==pagenow||"site-themes-network"==pagenow){a("h4.search-text").remove();if(e.s){a("ul.subsubsub").after(a('

    ').html(listTableL10n.search.replace("%s",this.htmlencode(e.s))))}}else{a("h2 .subtitle").remove();if(e.s){a("h2").append(a('').html(listTableL10n.search.replace("%s",this.htmlencode(e.s))))}}})}a(".search-box :submit").click(c);a(".search-box :text").keypress(c);a("#post-query-submit").click(function(){var d={};a(this).parents(".actions").find('select[name!="action"]').each(function(){var e=a(this);d[e.attr("name")]=e.val()});listTable.update_rows(d,true);return false});a(".view-switch a").click(function(){var d=a(this);listTable.update_rows({mode:a.query.load(d.attr("href")).get("mode")},false,function(){a(".view-switch .current").removeClass("current");d.addClass("current")});return false})}); \ No newline at end of file diff --git a/src/wp-admin/js/media-upload.dev.js b/src/wp-admin/js/media-upload.dev.js new file mode 100644 index 00000000..7d2565c7 --- /dev/null +++ b/src/wp-admin/js/media-upload.dev.js @@ -0,0 +1,69 @@ +// send html to the post editor +function send_to_editor(h) { + var ed; + + if ( typeof tinyMCE != 'undefined' && ( ed = tinyMCE.activeEditor ) && !ed.isHidden() ) { + ed.focus(); + if ( tinymce.isIE ) + ed.selection.moveToBookmark(tinymce.EditorManager.activeEditor.windowManager.bookmark); + + if ( h.indexOf('[caption') === 0 ) { + if ( ed.plugins.wpeditimage ) + h = ed.plugins.wpeditimage._do_shcode(h); + } else if ( h.indexOf('[gallery') === 0 ) { + if ( ed.plugins.wpgallery ) + h = ed.plugins.wpgallery._do_gallery(h); + } else if ( h.indexOf('[embed') === 0 ) { + if ( ed.plugins.wordpress ) + h = ed.plugins.wordpress._setEmbed(h); + } + + ed.execCommand('mceInsertContent', false, h); + + } else if ( typeof edInsertContent == 'function' ) { + edInsertContent(edCanvas, h); + } else { + jQuery( edCanvas ).val( jQuery( edCanvas ).val() + h ); + } + + tb_remove(); +} + +// thickbox settings +var tb_position; +(function($) { + tb_position = function() { + var tbWindow = $('#TB_window'), width = $(window).width(), H = $(window).height(), W = ( 720 < width ) ? 720 : width, adminbar_height = 0; + + if ( $('body.admin-bar').length ) + adminbar_height = 28; + + if ( tbWindow.size() ) { + tbWindow.width( W - 50 ).height( H - 45 - adminbar_height ); + $('#TB_iframeContent').width( W - 50 ).height( H - 75 - adminbar_height ); + tbWindow.css({'margin-left': '-' + parseInt((( W - 50 ) / 2),10) + 'px'}); + if ( typeof document.body.style.maxWidth != 'undefined' ) + tbWindow.css({'top': 20 + adminbar_height + 'px','margin-top':'0'}); + }; + + return $('a.thickbox').each( function() { + var href = $(this).attr('href'); + if ( ! href ) return; + href = href.replace(/&width=[0-9]+/g, ''); + href = href.replace(/&height=[0-9]+/g, ''); + $(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 - adminbar_height ) ); + }); + }; + + $(window).resize(function(){ tb_position(); }); + +})(jQuery); + +jQuery(document).ready(function($){ + $('a.thickbox').click(function(){ + if ( typeof tinyMCE != 'undefined' && tinyMCE.activeEditor ) { + tinyMCE.get('content').focus(); + tinyMCE.activeEditor.windowManager.bookmark = tinyMCE.activeEditor.selection.getBookmark('simple'); + } + }); +}); diff --git a/src/wp-admin/js/media-upload.js b/src/wp-admin/js/media-upload.js new file mode 100644 index 00000000..a1184f34 --- /dev/null +++ b/src/wp-admin/js/media-upload.js @@ -0,0 +1 @@ +function send_to_editor(b){var a;if(typeof tinyMCE!="undefined"&&(a=tinyMCE.activeEditor)&&!a.isHidden()){a.focus();if(tinymce.isIE){a.selection.moveToBookmark(tinymce.EditorManager.activeEditor.windowManager.bookmark)}if(b.indexOf("[caption")===0){if(a.plugins.wpeditimage){b=a.plugins.wpeditimage._do_shcode(b)}}else{if(b.indexOf("[gallery")===0){if(a.plugins.wpgallery){b=a.plugins.wpgallery._do_gallery(b)}}else{if(b.indexOf("[embed")===0){if(a.plugins.wordpress){b=a.plugins.wordpress._setEmbed(b)}}}}a.execCommand("mceInsertContent",false,b)}else{if(typeof edInsertContent=="function"){edInsertContent(edCanvas,b)}else{jQuery(edCanvas).val(jQuery(edCanvas).val()+b)}}tb_remove()}var tb_position;(function(a){tb_position=function(){var f=a("#TB_window"),e=a(window).width(),d=a(window).height(),c=(720]*?>/g, '' ); + } + if ( er ) { + $('#find-posts-response').html(er); + } + } + }; + + $(document).ready(function() { + $('#find-posts-submit').click(function(e) { + if ( '' == $('#find-posts-response').html() ) + e.preventDefault(); + }); + $( '#find-posts .find-box-search :input' ).keypress( function( event ) { + if ( 13 == event.which ) { + findPosts.send(); + return false; + } + } ); + $( '#find-posts-search' ).click( findPosts.send ); + $( '#find-posts-close' ).click( findPosts.close ); + $('#doaction, #doaction2').click(function(e){ + $('select[name^="action"]').each(function(){ + if ( $(this).val() == 'attach' ) { + e.preventDefault(); + findPosts.open(); + } + }); + }); + }); +})(jQuery); diff --git a/src/wp-admin/js/media.js b/src/wp-admin/js/media.js new file mode 100644 index 00000000..d5bd85b9 --- /dev/null +++ b/src/wp-admin/js/media.js @@ -0,0 +1 @@ +var findPosts;(function(a){findPosts={open:function(d,c){var b=document.documentElement.scrollTop||a(document).scrollTop();if(d&&c){a("#affected").attr("name",d).val(c)}a("#find-posts").show().draggable({handle:"#find-posts-head"}).css({top:b+50+"px",left:"50%",marginLeft:"-250px"});a("#find-posts-input").focus().keyup(function(f){if(f.which==27){findPosts.close()}});return false},close:function(){a("#find-posts-response").html("");a("#find-posts").draggable("destroy").hide()},send:function(){var b={ps:a("#find-posts-input").val(),action:"find_posts",_ajax_nonce:a("#_ajax_nonce").val()};var c;a("input[@name='itemSelect[]']:checked").each(function(){c=a(this).val()});b.post_type=c;a.ajax({type:"POST",url:ajaxurl,data:b,success:function(d){findPosts.show(d)},error:function(d){findPosts.error(d)}})},show:function(b){if(typeof(b)=="string"){this.error({responseText:b});return}var c=wpAjax.parseAjaxResponse(b);if(c.errors){this.error({responseText:wpAjax.broken})}c=c.responses[0];a("#find-posts-response").html(c.data)},error:function(b){var c=b.statusText;if(b.responseText){c=b.responseText.replace(/<.[^<>]*?>/g,"")}if(c){a("#find-posts-response").html(c)}}};a(document).ready(function(){a("#find-posts-submit").click(function(b){if(""==a("#find-posts-response").html()){b.preventDefault()}});a("#find-posts .find-box-search :input").keypress(function(b){if(13==b.which){findPosts.send();return false}});a("#find-posts-search").click(findPosts.send);a("#find-posts-close").click(findPosts.close);a("#doaction, #doaction2").click(function(b){a('select[name^="action"]').each(function(){if(a(this).val()=="attach"){b.preventDefault();findPosts.open()}})})})})(jQuery); \ No newline at end of file diff --git a/src/wp-admin/js/nav-menu.dev.js b/src/wp-admin/js/nav-menu.dev.js new file mode 100644 index 00000000..d58d6b27 --- /dev/null +++ b/src/wp-admin/js/nav-menu.dev.js @@ -0,0 +1,959 @@ +/** + * WordPress Administration Navigation Menu + * Interface JS functions + * + * @version 2.0.0 + * + * @package WordPress + * @subpackage Administration + */ + +var wpNavMenu; + +(function($) { + + var api = wpNavMenu = { + + options : { + menuItemDepthPerLevel : 30, // Do not use directly. Use depthToPx and pxToDepth instead. + globalMaxDepth : 11 + }, + + menuList : undefined, // Set in init. + targetList : undefined, // Set in init. + menusChanged : false, + isRTL: !! ( 'undefined' != typeof isRtl && isRtl ), + negateIfRTL: ( 'undefined' != typeof isRtl && isRtl ) ? -1 : 1, + + // Functions that run on init. + init : function() { + api.menuList = $('#menu-to-edit'); + api.targetList = api.menuList; + + this.jQueryExtensions(); + + this.attachMenuEditListeners(); + + this.setupInputWithDefaultTitle(); + this.attachQuickSearchListeners(); + this.attachThemeLocationsListeners(); + + this.attachTabsPanelListeners(); + + this.attachUnsavedChangesListener(); + + if( api.menuList.length ) // If no menu, we're in the + tab. + this.initSortables(); + + this.initToggles(); + + this.initTabManager(); + }, + + jQueryExtensions : function() { + // jQuery extensions + $.fn.extend({ + menuItemDepth : function() { + var margin = api.isRTL ? this.eq(0).css('margin-right') : this.eq(0).css('margin-left'); + return api.pxToDepth( margin && -1 != margin.indexOf('px') ? margin.slice(0, -2) : 0 ); + }, + updateDepthClass : function(current, prev) { + return this.each(function(){ + var t = $(this); + prev = prev || t.menuItemDepth(); + $(this).removeClass('menu-item-depth-'+ prev ) + .addClass('menu-item-depth-'+ current ); + }); + }, + shiftDepthClass : function(change) { + return this.each(function(){ + var t = $(this), + depth = t.menuItemDepth(); + $(this).removeClass('menu-item-depth-'+ depth ) + .addClass('menu-item-depth-'+ (depth + change) ); + }); + }, + childMenuItems : function() { + var result = $(); + this.each(function(){ + var t = $(this), depth = t.menuItemDepth(), next = t.next(); + while( next.length && next.menuItemDepth() > depth ) { + result = result.add( next ); + next = next.next(); + } + }); + return result; + }, + updateParentMenuItemDBId : function() { + return this.each(function(){ + var item = $(this), + input = item.find('.menu-item-data-parent-id'), + depth = item.menuItemDepth(), + parent = item.prev(); + + if( depth == 0 ) { // Item is on the top level, has no parent + input.val(0); + } else { // Find the parent item, and retrieve its object id. + while( ! parent[0] || ! parent[0].className || -1 == parent[0].className.indexOf('menu-item') || ( parent.menuItemDepth() != depth - 1 ) ) + parent = parent.prev(); + input.val( parent.find('.menu-item-data-db-id').val() ); + } + }); + }, + hideAdvancedMenuItemFields : function() { + return this.each(function(){ + var that = $(this); + $('.hide-column-tog').not(':checked').each(function(){ + that.find('.field-' + $(this).val() ).addClass('hidden-field'); + }); + }); + }, + /** + * Adds selected menu items to the menu. + * + * @param jQuery metabox The metabox jQuery object. + */ + addSelectedToMenu : function(processMethod) { + if ( 0 == $('#menu-to-edit').length ) { + return false; + } + + return this.each(function() { + var t = $(this), menuItems = {}, + checkboxes = t.find('.tabs-panel-active .categorychecklist li input:checked'), + re = new RegExp('menu-item\\[(\[^\\]\]*)'); + + processMethod = processMethod || api.addMenuItemToBottom; + + // If no items are checked, bail. + if ( !checkboxes.length ) + return false; + + // Show the ajax spinner + t.find('img.waiting').show(); + + // Retrieve menu item data + $(checkboxes).each(function(){ + var t = $(this), + listItemDBIDMatch = re.exec( t.attr('name') ), + listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10); + if ( this.className && -1 != this.className.indexOf('add-to-top') ) + processMethod = api.addMenuItemToTop; + menuItems[listItemDBID] = t.closest('li').getItemData( 'add-menu-item', listItemDBID ); + }); + + // Add the items + api.addItemToMenu(menuItems, processMethod, function(){ + // Deselect the items and hide the ajax spinner + checkboxes.removeAttr('checked'); + t.find('img.waiting').hide(); + }); + }); + }, + getItemData : function( itemType, id ) { + itemType = itemType || 'menu-item'; + + var itemData = {}, i, + fields = [ + 'menu-item-db-id', + 'menu-item-object-id', + 'menu-item-object', + 'menu-item-parent-id', + 'menu-item-position', + 'menu-item-type', + 'menu-item-title', + 'menu-item-url', + 'menu-item-description', + 'menu-item-attr-title', + 'menu-item-target', + 'menu-item-classes', + 'menu-item-xfn' + ]; + + if( !id && itemType == 'menu-item' ) { + id = this.find('.menu-item-data-db-id').val(); + } + + if( !id ) return itemData; + + this.find('input').each(function() { + var field; + i = fields.length; + while ( i-- ) { + if( itemType == 'menu-item' ) + field = fields[i] + '[' + id + ']'; + else if( itemType == 'add-menu-item' ) + field = 'menu-item[' + id + '][' + fields[i] + ']'; + + if ( + this.name && + field == this.name + ) { + itemData[fields[i]] = this.value; + } + } + }); + + return itemData; + }, + setItemData : function( itemData, itemType, id ) { // Can take a type, such as 'menu-item', or an id. + itemType = itemType || 'menu-item'; + + if( !id && itemType == 'menu-item' ) { + id = $('.menu-item-data-db-id', this).val(); + } + + if( !id ) return this; + + this.find('input').each(function() { + var t = $(this), field; + $.each( itemData, function( attr, val ) { + if( itemType == 'menu-item' ) + field = attr + '[' + id + ']'; + else if( itemType == 'add-menu-item' ) + field = 'menu-item[' + id + '][' + attr + ']'; + + if ( field == t.attr('name') ) { + t.val( val ); + } + }); + }); + return this; + } + }); + }, + + initToggles : function() { + // init postboxes + postboxes.add_postbox_toggles('nav-menus'); + + // adjust columns functions for menus UI + columns.useCheckboxesForHidden(); + columns.checked = function(field) { + $('.field-' + field).removeClass('hidden-field'); + } + columns.unchecked = function(field) { + $('.field-' + field).addClass('hidden-field'); + } + // hide fields + api.menuList.hideAdvancedMenuItemFields(); + }, + + initSortables : function() { + var currentDepth = 0, originalDepth, minDepth, maxDepth, + prev, next, prevBottom, nextThreshold, helperHeight, transport, + menuEdge = api.menuList.offset().left, + body = $('body'), maxChildDepth, + menuMaxDepth = initialMenuMaxDepth(); + + // Use the right edge if RTL. + menuEdge += api.isRTL ? api.menuList.width() : 0; + + api.menuList.sortable({ + handle: '.menu-item-handle', + placeholder: 'sortable-placeholder', + start: function(e, ui) { + var height, width, parent, children, tempHolder; + + // handle placement for rtl orientation + if ( api.isRTL ) + ui.item[0].style.right = 'auto'; + + transport = ui.item.children('.menu-item-transport'); + + // Set depths. currentDepth must be set before children are located. + originalDepth = ui.item.menuItemDepth(); + updateCurrentDepth(ui, originalDepth); + + // Attach child elements to parent + // Skip the placeholder + parent = ( ui.item.next()[0] == ui.placeholder[0] ) ? ui.item.next() : ui.item; + children = parent.childMenuItems(); + transport.append( children ); + + // Update the height of the placeholder to match the moving item. + height = transport.outerHeight(); + // If there are children, account for distance between top of children and parent + height += ( height > 0 ) ? (ui.placeholder.css('margin-top').slice(0, -2) * 1) : 0; + height += ui.helper.outerHeight(); + helperHeight = height; + height -= 2; // Subtract 2 for borders + ui.placeholder.height(height); + + // Update the width of the placeholder to match the moving item. + maxChildDepth = originalDepth; + children.each(function(){ + var depth = $(this).menuItemDepth(); + maxChildDepth = (depth > maxChildDepth) ? depth : maxChildDepth; + }); + width = ui.helper.find('.menu-item-handle').outerWidth(); // Get original width + width += api.depthToPx(maxChildDepth - originalDepth); // Account for children + width -= 2; // Subtract 2 for borders + ui.placeholder.width(width); + + // Update the list of menu items. + tempHolder = ui.placeholder.next(); + tempHolder.css( 'margin-top', helperHeight + 'px' ); // Set the margin to absorb the placeholder + ui.placeholder.detach(); // detach or jQuery UI will think the placeholder is a menu item + $(this).sortable( "refresh" ); // The children aren't sortable. We should let jQ UI know. + ui.item.after( ui.placeholder ); // reattach the placeholder. + tempHolder.css('margin-top', 0); // reset the margin + + // Now that the element is complete, we can update... + updateSharedVars(ui); + }, + stop: function(e, ui) { + var children, depthChange = currentDepth - originalDepth; + + // Return child elements to the list + children = transport.children().insertAfter(ui.item); + + // Update depth classes + if( depthChange != 0 ) { + ui.item.updateDepthClass( currentDepth ); + children.shiftDepthClass( depthChange ); + updateMenuMaxDepth( depthChange ); + } + // Register a change + api.registerChange(); + // Update the item data. + ui.item.updateParentMenuItemDBId(); + + // address sortable's incorrectly-calculated top in opera + ui.item[0].style.top = 0; + + // handle drop placement for rtl orientation + if ( api.isRTL ) { + ui.item[0].style.left = 'auto'; + ui.item[0].style.right = 0; + } + + // The width of the tab bar might have changed. Just in case. + api.refreshMenuTabs( true ); + }, + change: function(e, ui) { + // Make sure the placeholder is inside the menu. + // Otherwise fix it, or we're in trouble. + if( ! ui.placeholder.parent().hasClass('menu') ) + (prev.length) ? prev.after( ui.placeholder ) : api.menuList.prepend( ui.placeholder ); + + updateSharedVars(ui); + }, + sort: function(e, ui) { + var offset = ui.helper.offset(), + edge = api.isRTL ? offset.left + ui.helper.width() : offset.left, + depth = api.negateIfRTL * api.pxToDepth( edge - menuEdge ); + // Check and correct if depth is not within range. + // Also, if the dragged element is dragged upwards over + // an item, shift the placeholder to a child position. + if ( depth > maxDepth || offset.top < prevBottom ) depth = maxDepth; + else if ( depth < minDepth ) depth = minDepth; + + if( depth != currentDepth ) + updateCurrentDepth(ui, depth); + + // If we overlap the next element, manually shift downwards + if( nextThreshold && offset.top + helperHeight > nextThreshold ) { + next.after( ui.placeholder ); + updateSharedVars( ui ); + $(this).sortable( "refreshPositions" ); + } + } + }); + + function updateSharedVars(ui) { + var depth; + + prev = ui.placeholder.prev(); + next = ui.placeholder.next(); + + // Make sure we don't select the moving item. + if( prev[0] == ui.item[0] ) prev = prev.prev(); + if( next[0] == ui.item[0] ) next = next.next(); + + prevBottom = (prev.length) ? prev.offset().top + prev.height() : 0; + nextThreshold = (next.length) ? next.offset().top + next.height() / 3 : 0; + minDepth = (next.length) ? next.menuItemDepth() : 0; + + if( prev.length ) + maxDepth = ( (depth = prev.menuItemDepth() + 1) > api.options.globalMaxDepth ) ? api.options.globalMaxDepth : depth; + else + maxDepth = 0; + } + + function updateCurrentDepth(ui, depth) { + ui.placeholder.updateDepthClass( depth, currentDepth ); + currentDepth = depth; + } + + function initialMenuMaxDepth() { + if( ! body[0].className ) return 0; + var match = body[0].className.match(/menu-max-depth-(\d+)/); + return match && match[1] ? parseInt(match[1]) : 0; + } + + function updateMenuMaxDepth( depthChange ) { + var depth, newDepth = menuMaxDepth; + if ( depthChange === 0 ) { + return; + } else if ( depthChange > 0 ) { + depth = maxChildDepth + depthChange; + if( depth > menuMaxDepth ) + newDepth = depth; + } else if ( depthChange < 0 && maxChildDepth == menuMaxDepth ) { + while( ! $('.menu-item-depth-' + newDepth, api.menuList).length && newDepth > 0 ) + newDepth--; + } + // Update the depth class. + body.removeClass( 'menu-max-depth-' + menuMaxDepth ).addClass( 'menu-max-depth-' + newDepth ); + menuMaxDepth = newDepth; + } + }, + + attachMenuEditListeners : function() { + var that = this; + $('#update-nav-menu').bind('click', function(e) { + if ( e.target && e.target.className ) { + if ( -1 != e.target.className.indexOf('item-edit') ) { + return that.eventOnClickEditLink(e.target); + } else if ( -1 != e.target.className.indexOf('menu-save') ) { + return that.eventOnClickMenuSave(e.target); + } else if ( -1 != e.target.className.indexOf('menu-delete') ) { + return that.eventOnClickMenuDelete(e.target); + } else if ( -1 != e.target.className.indexOf('item-delete') ) { + return that.eventOnClickMenuItemDelete(e.target); + } else if ( -1 != e.target.className.indexOf('item-cancel') ) { + return that.eventOnClickCancelLink(e.target); + } + } + }); + }, + + /** + * An interface for managing default values for input elements + * that is both JS and accessibility-friendly. + * + * Input elements that add the class 'input-with-default-title' + * will have their values set to the provided HTML title when empty. + */ + setupInputWithDefaultTitle : function() { + var name = 'input-with-default-title'; + + $('.' + name).each( function(){ + var $t = $(this), title = $t.attr('title'), val = $t.val(); + $t.data( name, title ); + + if( '' == val ) $t.val( title ); + else if ( title == val ) return; + else $t.removeClass( name ); + }).focus( function(){ + var $t = $(this); + if( $t.val() == $t.data(name) ) + $t.val('').removeClass( name ); + }).blur( function(){ + var $t = $(this); + if( '' == $t.val() ) + $t.addClass( name ).val( $t.data(name) ); + }); + }, + + attachThemeLocationsListeners : function() { + var loc = $('#nav-menu-theme-locations'), params = {}; + params['action'] = 'menu-locations-save'; + params['menu-settings-column-nonce'] = $('#menu-settings-column-nonce').val(); + loc.find('input[type=submit]').click(function() { + loc.find('select').each(function() { + params[this.name] = $(this).val(); + }); + loc.find('.waiting').show(); + $.post( ajaxurl, params, function(r) { + loc.find('.waiting').hide(); + }); + return false; + }); + }, + + attachQuickSearchListeners : function() { + var searchTimer; + + $('.quick-search').keypress(function(e){ + var t = $(this); + + if( 13 == e.which ) { + api.updateQuickSearchResults( t ); + return false; + } + + if( searchTimer ) clearTimeout(searchTimer); + + searchTimer = setTimeout(function(){ + api.updateQuickSearchResults( t ); + }, 400); + }).attr('autocomplete','off'); + }, + + updateQuickSearchResults : function(input) { + var panel, params, + minSearchLength = 2, + q = input.val(); + + if( q.length < minSearchLength ) return; + + panel = input.parents('.tabs-panel'); + params = { + 'action': 'menu-quick-search', + 'response-format': 'markup', + 'menu': $('#menu').val(), + 'menu-settings-column-nonce': $('#menu-settings-column-nonce').val(), + 'q': q, + 'type': input.attr('name') + }; + + $('img.waiting', panel).show(); + + $.post( ajaxurl, params, function(menuMarkup) { + api.processQuickSearchQueryResponse(menuMarkup, params, panel); + }); + }, + + addCustomLink : function( processMethod ) { + var url = $('#custom-menu-item-url').val(), + label = $('#custom-menu-item-name').val(); + + processMethod = processMethod || api.addMenuItemToBottom; + + if ( '' == url || 'http://' == url ) + return false; + + // Show the ajax spinner + $('.customlinkdiv img.waiting').show(); + this.addLinkToMenu( url, label, processMethod, function() { + // Remove the ajax spinner + $('.customlinkdiv img.waiting').hide(); + // Set custom link form back to defaults + $('#custom-menu-item-name').val('').blur(); + $('#custom-menu-item-url').val('http://'); + }); + }, + + addLinkToMenu : function(url, label, processMethod, callback) { + processMethod = processMethod || api.addMenuItemToBottom; + callback = callback || function(){}; + + api.addItemToMenu({ + '-1': { + 'menu-item-type': 'custom', + 'menu-item-url': url, + 'menu-item-title': label + } + }, processMethod, callback); + }, + + addItemToMenu : function(menuItem, processMethod, callback) { + var menu = $('#menu').val(), + nonce = $('#menu-settings-column-nonce').val(); + + processMethod = processMethod || function(){}; + callback = callback || function(){}; + + params = { + 'action': 'add-menu-item', + 'menu': menu, + 'menu-settings-column-nonce': nonce, + 'menu-item': menuItem + }; + + $.post( ajaxurl, params, function(menuMarkup) { + var ins = $('#menu-instructions'); + processMethod(menuMarkup, params); + if( ! ins.hasClass('menu-instructions-inactive') && ins.siblings().length ) + ins.addClass('menu-instructions-inactive'); + callback(); + }); + }, + + /** + * Process the add menu item request response into menu list item. + * + * @param string menuMarkup The text server response of menu item markup. + * @param object req The request arguments. + */ + addMenuItemToBottom : function( menuMarkup, req ) { + $(menuMarkup).hideAdvancedMenuItemFields().appendTo( api.targetList ); + }, + + addMenuItemToTop : function( menuMarkup, req ) { + $(menuMarkup).hideAdvancedMenuItemFields().prependTo( api.targetList ); + }, + + attachUnsavedChangesListener : function() { + $('#menu-management input, #menu-management select, #menu-management, #menu-management textarea').change(function(){ + api.registerChange(); + }); + + if ( 0 != $('#menu-to-edit').length ) { + window.onbeforeunload = function(){ + if ( api.menusChanged ) + return navMenuL10n.saveAlert; + }; + } else { + // Make the post boxes read-only, as they can't be used yet + $('#menu-settings-column').find('input,select').attr('disabled', 'disabled').end().find('a').attr('href', '#').unbind('click'); + } + }, + + registerChange : function() { + api.menusChanged = true; + }, + + attachTabsPanelListeners : function() { + $('#menu-settings-column').bind('click', function(e) { + var selectAreaMatch, panelId, wrapper, items, + target = $(e.target); + + if ( target.hasClass('nav-tab-link') ) { + panelId = /#(.*)$/.exec(e.target.href); + if ( panelId && panelId[1] ) + panelId = panelId[1] + else + return false; + + wrapper = target.parents('.inside').first(); + + // upon changing tabs, we want to uncheck all checkboxes + $('input', wrapper).removeAttr('checked'); + + $('.tabs-panel-active', wrapper).removeClass('tabs-panel-active').addClass('tabs-panel-inactive'); + $('#' + panelId, wrapper).removeClass('tabs-panel-inactive').addClass('tabs-panel-active'); + + $('.tabs', wrapper).removeClass('tabs'); + target.parent().addClass('tabs'); + + // select the search bar + $('.quick-search', wrapper).focus(); + + return false; + } else if ( target.hasClass('select-all') ) { + selectAreaMatch = /#(.*)$/.exec(e.target.href); + if ( selectAreaMatch && selectAreaMatch[1] ) { + items = $('#' + selectAreaMatch[1] + ' .tabs-panel-active .menu-item-title input'); + if( items.length === items.filter(':checked').length ) + items.removeAttr('checked'); + else + items.attr('checked', 'checked'); + return false; + } + } else if ( target.hasClass('submit-add-to-menu') ) { + api.registerChange(); + + if ( e.target.id && 'submit-customlinkdiv' == e.target.id ) + api.addCustomLink( api.addMenuItemToBottom ); + else if ( e.target.id && -1 != e.target.id.indexOf('submit-') ) + $('#' + e.target.id.replace(/submit-/, '')).addSelectedToMenu( api.addMenuItemToBottom ); + return false; + } else if ( target.hasClass('page-numbers') ) { + $.post( ajaxurl, e.target.href.replace(/.*\?/, '').replace(/action=([^&]*)/, '') + '&action=menu-get-metabox', + function( resp ) { + if ( -1 == resp.indexOf('replace-id') ) + return; + + var metaBoxData = $.parseJSON(resp), + toReplace = document.getElementById(metaBoxData['replace-id']), + placeholder = document.createElement('div'), + wrap = document.createElement('div'); + + if ( ! metaBoxData['markup'] || ! toReplace ) + return; + + wrap.innerHTML = metaBoxData['markup'] ? metaBoxData['markup'] : ''; + + toReplace.parentNode.insertBefore( placeholder, toReplace ); + placeholder.parentNode.removeChild( toReplace ); + + placeholder.parentNode.insertBefore( wrap, placeholder ); + + placeholder.parentNode.removeChild( placeholder ); + + } + ); + + return false; + } + }); + }, + + initTabManager : function() { + var fixed = $('.nav-tabs-wrapper'), + fluid = fixed.children('.nav-tabs'), + active = fluid.children('.nav-tab-active'), + tabs = fluid.children('.nav-tab'), + tabsWidth = 0, + fixedRight, fixedLeft, + arrowLeft, arrowRight, resizeTimer, css = {}, + marginFluid = api.isRTL ? 'margin-right' : 'margin-left', + marginFixed = api.isRTL ? 'margin-left' : 'margin-right', + msPerPx = 2; + + /** + * Refreshes the menu tabs. + * Will show and hide arrows where necessary. + * Scrolls to the active tab by default. + * + * @param savePosition {boolean} Optional. Prevents scrolling so + * that the current position is maintained. Default false. + **/ + api.refreshMenuTabs = function( savePosition ) { + var fixedWidth = fixed.width(), + margin = 0, css = {}; + fixedLeft = fixed.offset().left; + fixedRight = fixedLeft + fixedWidth; + + if( !savePosition ) + active.makeTabVisible(); + + // Prevent space from building up next to the last tab if there's more to show + if( tabs.last().isTabVisible() ) { + margin = fixed.width() - tabsWidth; + margin = margin > 0 ? 0 : margin; + css[marginFluid] = margin + 'px'; + fluid.animate( css, 100, "linear" ); + } + + // Show the arrows only when necessary + if( fixedWidth > tabsWidth ) + arrowLeft.add( arrowRight ).hide(); + else + arrowLeft.add( arrowRight ).show(); + } + + $.fn.extend({ + makeTabVisible : function() { + var t = this.eq(0), left, right, css = {}, shift = 0; + + if( ! t.length ) return this; + + left = t.offset().left; + right = left + t.outerWidth(); + + if( right > fixedRight ) + shift = fixedRight - right; + else if ( left < fixedLeft ) + shift = fixedLeft - left; + + if( ! shift ) return this; + + css[marginFluid] = "+=" + api.negateIfRTL * shift + 'px'; + fluid.animate( css, Math.abs( shift ) * msPerPx, "linear" ); + return this; + }, + isTabVisible : function() { + var t = this.eq(0), + left = t.offset().left, + right = left + t.outerWidth(); + return ( right <= fixedRight && left >= fixedLeft ) ? true : false; + } + }); + + // Find the width of all tabs + tabs.each(function(){ + tabsWidth += $(this).outerWidth(true); + }); + + // Set up fixed margin for overflow, unset padding + css['padding'] = 0; + css[marginFixed] = (-1 * tabsWidth) + 'px'; + fluid.css( css ); + + // Build tab navigation + arrowLeft = $(''); + arrowRight = $(''); + // Attach to the document + fixed.wrap(''; + include( ABSPATH . 'wp-admin/admin-footer.php' ); + die(); + } + + echo '
    '; + + wp_nonce_field( 'install-network-1' ); + + $error_codes = array(); + if ( is_wp_error( $errors ) ) { + echo '

    ' . __( 'ERROR: The network could not be created.' ) . '

    '; + foreach ( $errors->get_error_messages() as $error ) + echo "

    $error

    "; + echo '
    '; + $error_codes = $errors->get_error_codes(); + } + + if ( WP_CONTENT_DIR != ABSPATH . 'wp-content' ) + echo '

    ' . __('Warning!') . ' ' . __( 'Networks may not be fully compatible with custom wp-content directories.' ) . '

    '; + + $site_name = ( ! empty( $_POST['sitename'] ) && ! in_array( 'empty_sitename', $error_codes ) ) ? $_POST['sitename'] : sprintf( _x('%s Sites', 'Default network name' ), get_option( 'blogname' ) ); + $admin_email = ( ! empty( $_POST['email'] ) && ! in_array( 'invalid_email', $error_codes ) ) ? $_POST['email'] : get_option( 'admin_email' ); + ?> +

    +

    +

    ' . __( 'Note:' ) . ' ' . __( 'Please make sure the Apache mod_rewrite module is installed as it will be used at the end of this installation.' ) . '

    '; + elseif ( $is_apache ) + echo '

    ' . __( 'Warning!' ) . ' ' . __( 'It looks like the Apache mod_rewrite module is not installed.' ) . '

    '; + if ( $got_mod_rewrite || $is_apache ) // Protect against mod_rewrite mimicry (but ! Apache) + echo '

    ' . __( 'If mod_rewrite is disabled, ask your administrator to enable that module, or look at the Apache documentation or elsewhere for help setting it up.' ) . '

    '; + } + + if ( allow_subdomain_install() && allow_subdirectory_install() ) : ?> +

    +

    You cannot change this later.' ); ?>

    +

    + + + + + + + + + + +
    site1.%1$s and site2.%1$s', 'subdomain examples' ), $hostname ); ?>
    %1$s/site1 and %1$s/site2', 'subdirectory examples' ), $hostname ); ?>
    + + +

    +

    %1$s before enabling the network feature. It will still be possible to visit your site using the www prefix with an address like %2$s but any links will not have the www prefix.' ), substr( $hostname, 4 ), $hostname ); ?>

    + + + + + +
    + %s.' ), $hostname ); ?> +
    + + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    localhost, the sites in your WordPress network must use sub-directories. Consider using localhost.localdomain if you wish to use sub-domains.' ); + // Uh oh: + if ( !allow_subdirectory_install() ) + echo ' ' . __( 'Warning!' ) . ' ' . __( 'The main site in a sub-directory install will need to use a modified permalink structure, potentially breaking existing links.' ) . ''; + ?>
    ' . __( 'Warning!' ) . ' ' . __( 'The main site in a sub-directory install will need to use a modified permalink structure, potentially breaking existing links.' ) . ''; + ?>
    ' . __( 'The main site in a sub-directory install will need to use a modified permalink structure, potentially breaking existing links.' ) . ''; + ?>
    + %s.' ), $hostname ); ?> +
    + +
    +
    + +
    +
    + + + ' . $errors->get_error_message() . '
    '; + + if ( $_POST ) { + if ( allow_subdomain_install() ) + $subdomain_install = allow_subdirectory_install() ? ! empty( $_POST['subdomain_install'] ) : true; + else + $subdomain_install = false; + } else { + if ( is_multisite() ) { + $subdomain_install = is_subdomain_install(); +?> +

    +get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" ); +?> +

    +

    + +

    +

    +

    Caution: We recommend you back up your existing wp-config.php and %s files.' ), '.htaccess' ); + elseif ( file_exists( ABSPATH . 'web.config' ) ) + printf( __( 'Caution: We recommend you back up your existing wp-config.php and %s files.' ), 'web.config' ); + else + _e( 'Caution: We recommend you back up your existing wp-config.php file.' ); + ?>

    + +
      +
    1. blogs.dir directory at %s/blogs.dir. This directory is used to store uploaded media for your additional sites and must be writeable by the web server.' ), WP_CONTENT_DIR ); + if ( WP_CONTENT_DIR != ABSPATH . 'wp-content' ) + echo ' ' . __('Warning:') . ' ' . __( 'Networks may not be fully compatible with custom wp-content directories.' ) . '

    2. +
    3. wp-config.php file in %s above the line reading /* That’s all, stop editing! Happy blogging. */:' ), ABSPATH ); ?>

      + + '', 'SECURE_AUTH_KEY' => '', 'LOGGED_IN_KEY' => '', 'NONCE_KEY' => '', 'AUTH_SALT' => '', 'SECURE_AUTH_SALT' => '', 'LOGGED_IN_SALT' => '', 'NONCE_SALT' => '' ); + foreach ( $keys_salts as $c => $v ) { + if ( defined( $c ) ) + unset( $keys_salts[ $c ] ); + } + if ( ! empty( $keys_salts ) ) { + $keys_salts_str = ''; + $from_api = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' ); + if ( is_wp_error( $from_api ) ) { + foreach ( $keys_salts as $c => $v ) { + $keys_salts_str .= "\ndefine( '$c', '" . wp_generate_password( 64, true, true ) . "' );"; + } + } else { + $from_api = explode( "\n", wp_remote_retrieve_body( $from_api ) ); + foreach ( $keys_salts as $c => $v ) { + $keys_salts_str .= "\ndefine( '$c', '" . substr( array_shift( $from_api ), 28, 64 ) . "' );"; + } + } + $num_keys_salts = count( $keys_salts ); +?> +

      wp-config.php file.', 'These unique authentication keys are also missing from your wp-config.php file.', $num_keys_salts ); ?>

      + + +
    4. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'; + } else { + $web_config_file = +' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'; + } + ?> +
    5. web.config file in %s, replacing other WordPress rules:' ), ABSPATH ); ?>

      +
    6. +
    + + +
  • .htaccess file in %s, replacing other WordPress rules:' ), ABSPATH ); ?>

    +
  • + + + +

    +get_error_codes() ) && 'no_wildcard_dns' == $result->get_error_code() ) + network_step2( $result ); + else + network_step1( $result ); + } else { + network_step2(); + } + } else { + network_step2(); + } +} elseif ( is_multisite() || network_domain_check() ) { + network_step2(); +} else { + network_step1(); +} +?> +

    + + diff --git a/src/wp-admin/network/admin.php b/src/wp-admin/network/admin.php new file mode 100644 index 00000000..145c25d1 --- /dev/null +++ b/src/wp-admin/network/admin.php @@ -0,0 +1,22 @@ +domain != $current_site->domain ) || ( $current_blog->path != $current_site->path ) ) { + wp_redirect( network_admin_url() ); + exit; +} +?> diff --git a/src/wp-admin/network/edit.php b/src/wp-admin/network/edit.php new file mode 100644 index 00000000..2d3f9522 --- /dev/null +++ b/src/wp-admin/network/edit.php @@ -0,0 +1,482 @@ + +

    +

    +
    + + ID'>$current_user->user_login"; + + foreach ( ( $allusers = (array) $_POST['allusers'] ) as $key => $val ) { + if ( $val != '' && $val != '0' ) { + $delete_user = new WP_User( $val ); + + if ( ! current_user_can( 'delete_user', $delete_user->ID ) ) + wp_die( sprintf( __( 'Warning! User %s cannot be deleted.' ), $delete_user->user_login ) ); + + if ( in_array( $delete_user->user_login, $site_admins ) ) + wp_die( sprintf( __( 'Warning! User cannot be deleted. The user %s is a network admnistrator.' ), $delete_user->user_login ) ); + + echo "\n"; + $blogs = get_blogs_of_user( $val, true ); + + if ( !empty( $blogs ) ) { + ?> +

    %s?" ), $delete_user->user_login ); ?>

    + $details ) { + $blog_users = get_users( array( 'blog_id' => $details->userblog_id ) ); + if ( is_array( $blog_users ) && !empty( $blog_users ) ) { + $user_site = "{$details->blogname}"; + $user_dropdown = "\n"; + ?> +
      +
    • +
    • +
    • +
    + "; + } + } + } + + submit_button( __('Confirm Deletion'), 'delete' ); + ?> + + options page.' ), esc_url( admin_url( 'settings.php' ) ) ) ); + + if ( isset($_POST['WPLANG']) && ( '' === $_POST['WPLANG'] || in_array( $_POST['WPLANG'], get_available_languages() ) ) ) + update_site_option( 'WPLANG', $_POST['WPLANG'] ); + + if ( is_email( $_POST['admin_email'] ) ) + update_site_option( 'admin_email', $_POST['admin_email'] ); + + $illegal_names = split( ' ', $_POST['illegal_names'] ); + foreach ( (array) $illegal_names as $name ) { + $name = trim( $name ); + if ( $name != '' ) + $names[] = trim( $name ); + } + update_site_option( 'illegal_names', $names ); + + if ( $_POST['limited_email_domains'] != '' ) { + $limited_email_domains = str_replace( ' ', "\n", $_POST['limited_email_domains'] ); + $limited_email_domains = split( "\n", stripslashes( $limited_email_domains ) ); + $limited_email = array(); + foreach ( (array) $limited_email_domains as $domain ) { + $domain = trim( $domain ); + if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) ) + $limited_email[] = trim( $domain ); + } + update_site_option( 'limited_email_domains', $limited_email ); + } else { + update_site_option( 'limited_email_domains', '' ); + } + + if ( $_POST['banned_email_domains'] != '' ) { + $banned_email_domains = split( "\n", stripslashes( $_POST['banned_email_domains'] ) ); + $banned = array(); + foreach ( (array) $banned_email_domains as $domain ) { + $domain = trim( $domain ); + if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) ) + $banned[] = trim( $domain ); + } + update_site_option( 'banned_email_domains', $banned ); + } else { + update_site_option( 'banned_email_domains', '' ); + } + + $options = array( 'registrationnotification', 'registration', 'add_new_users', 'menu_items', 'mu_media_buttons', 'upload_space_check_disabled', 'blog_upload_space', 'upload_filetypes', 'site_name', 'first_post', 'first_page', 'first_comment', 'first_comment_url', 'first_comment_author', 'welcome_email', 'welcome_user_email', 'fileupload_maxk', 'global_terms_enabled' ); + $checked_options = array( 'mu_media_buttons' => array(), 'menu_items' => array(), 'registrationnotification' => 'no', 'upload_space_check_disabled' => 1, 'add_new_users' => 0 ); + foreach ( $checked_options as $option_name => $option_unchecked_value ) { + if ( ! isset( $_POST[$option_name] ) ) + $_POST[$option_name] = $option_unchecked_value; + } + foreach ( $options as $option_name ) { + if ( ! isset($_POST[$option_name]) ) + continue; + $value = stripslashes_deep( $_POST[$option_name] ); + update_site_option( $option_name, $value ); + } + + // Update more options here + do_action( 'update_wpmu_options' ); + + wp_redirect( add_query_arg( 'updated', 'true', network_admin_url( 'settings.php' ) ) ); + exit(); + break; + + case 'updateblog': + // No longer used. + break; + + case 'deleteblog': + check_admin_referer('deleteblog'); + if ( ! ( current_user_can( 'manage_sites' ) && current_user_can( 'delete_sites' ) ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + if ( $id != '0' && $id != $current_site->blog_id && current_user_can( 'delete_site', $id ) ) { + wpmu_delete_blog( $id, true ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'delete' ), wp_get_referer() ) ); + } else { + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'not_deleted' ), wp_get_referer() ) ); + } + + exit(); + break; + + case 'allblogs': + if ( ( isset( $_POST['action'] ) || isset( $_POST['action2'] ) ) && isset( $_POST['allblogs'] ) ) { + check_admin_referer( 'bulk-sites' ); + + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + if ( $_GET['action'] != -1 || $_POST['action2'] != -1 ) + $doaction = $_POST['action'] != -1 ? $_POST['action'] : $_POST['action2']; + + $blogfunction = ''; + + foreach ( (array) $_POST['allblogs'] as $key => $val ) { + if ( $val != '0' && $val != $current_site->blog_id ) { + switch ( $doaction ) { + case 'delete': + if ( ! current_user_can( 'delete_site', $val ) ) + wp_die( __( 'You are not allowed to delete the site.' ) ); + $blogfunction = 'all_delete'; + wpmu_delete_blog( $val, true ); + break; + + case 'spam': + $blogfunction = 'all_spam'; + update_blog_status( $val, 'spam', '1' ); + set_time_limit( 60 ); + break; + + case 'notspam': + $blogfunction = 'all_notspam'; + update_blog_status( $val, 'spam', '0' ); + set_time_limit( 60 ); + break; + } + } else { + wp_die( __( 'You are not allowed to change the current site.' ) ); + } + } + + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => $blogfunction ), wp_get_referer() ) ); + } else { + wp_redirect( network_admin_url( 'sites.php' ) ); + } + exit(); + break; + + case 'archiveblog': + check_admin_referer( 'archiveblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + update_blog_status( $id, 'archived', '1' ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'archive' ), wp_get_referer() ) ); + exit(); + break; + + case 'unarchiveblog': + check_admin_referer( 'unarchiveblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + update_blog_status( $id, 'archived', '0' ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'unarchive' ), wp_get_referer() ) ); + exit(); + break; + + case 'activateblog': + check_admin_referer( 'activateblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + update_blog_status( $id, 'deleted', '0' ); + do_action( 'activate_blog', $id ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'activate' ), wp_get_referer() ) ); + exit(); + break; + + case 'deactivateblog': + check_admin_referer( 'deactivateblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + do_action( 'deactivate_blog', $id ); + update_blog_status( $id, 'deleted', '1' ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'deactivate' ), wp_get_referer() ) ); + exit(); + break; + + case 'unspamblog': + check_admin_referer( 'unspamblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + update_blog_status( $id, 'spam', '0' ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'unspam' ), wp_get_referer() ) ); + exit(); + break; + + case 'spamblog': + check_admin_referer( 'spamblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + update_blog_status( $id, 'spam', '1' ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'spam' ), wp_get_referer() ) ); + exit(); + break; + + case 'unmatureblog': + check_admin_referer( 'unmatureblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + update_blog_status( $id, 'mature', '0' ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'unmature' ), wp_get_referer() ) ); + exit(); + break; + + case 'matureblog': + check_admin_referer( 'matureblog' ); + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + update_blog_status( $id, 'mature', '1' ); + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => 'mature' ), wp_get_referer() ) ); + exit(); + break; + + // Common + case 'confirm': + check_admin_referer( 'confirm' ); + if ( !headers_sent() ) { + nocache_headers(); + header( 'Content-Type: text/html; charset=utf-8' ); + } + if ( $current_site->blog_id == $id ) + wp_die( __( 'You are not allowed to change the current site.' ) ); + ?> + + > + + <?php _e( 'WordPress › Confirm your action' ); ?> + + + + + +

    WordPress

    +
    + + + + +

    + +
    + + + '; + confirm_delete_users( $_POST['allusers'] ); + echo '
    '; + require_once( '../admin-footer.php' ); + } else { + wp_redirect( network_admin_url( 'users.php' ) ); + } + exit(); + break; + + case 'allusers': + if ( !current_user_can( 'manage_network_users' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + if ( ( isset( $_POST['action']) || isset($_POST['action2'] ) ) && isset( $_POST['allusers'] ) ) { + check_admin_referer( 'bulk-users-network' ); + + if ( $_GET['action'] != -1 || $_POST['action2'] != -1 ) + $doaction = $_POST['action'] != -1 ? $_POST['action'] : $_POST['action2']; + + $userfunction = ''; + + foreach ( (array) $_POST['allusers'] as $key => $val ) { + if ( !empty( $val ) ) { + switch ( $doaction ) { + case 'delete': + if ( ! current_user_can( 'delete_users' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + $title = __( 'Users' ); + $parent_file = 'users.php'; + require_once( '../admin-header.php' ); + echo '
    '; + confirm_delete_users( $_POST['allusers'] ); + echo '
    '; + require_once( '../admin-footer.php' ); + exit(); + break; + + case 'spam': + $user = new WP_User( $val ); + if ( in_array( $user->user_login, get_super_admins() ) ) + wp_die( sprintf( __( 'Warning! User cannot be modified. The user %s is a network administrator.' ), esc_html( $user->user_login ) ) ); + + $userfunction = 'all_spam'; + $blogs = get_blogs_of_user( $val, true ); + foreach ( (array) $blogs as $key => $details ) { + if ( $details->userblog_id != $current_site->blog_id ) // main blog not a spam ! + update_blog_status( $details->userblog_id, 'spam', '1' ); + } + update_user_status( $val, 'spam', '1' ); + break; + + case 'notspam': + $userfunction = 'all_notspam'; + $blogs = get_blogs_of_user( $val, true ); + foreach ( (array) $blogs as $key => $details ) + update_blog_status( $details->userblog_id, 'spam', '0' ); + + update_user_status( $val, 'spam', '0' ); + break; + } + } + } + + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => $userfunction ), wp_get_referer() ) ); + } else { + $location = network_admin_url( 'users.php' ); + + if ( ! empty( $_REQUEST['paged'] ) ) + $location = add_query_arg( 'paged', (int) $_REQUEST['paged'], $location ); + wp_redirect( $location ); + } + exit(); + break; + + case 'dodelete': + check_admin_referer( 'ms-users-delete' ); + if ( ! ( current_user_can( 'manage_network_users' ) && current_user_can( 'delete_users' ) ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + if ( ! empty( $_POST['blog'] ) && is_array( $_POST['blog'] ) ) { + foreach ( $_POST['blog'] as $id => $users ) { + foreach ( $users as $blogid => $user_id ) { + if ( ! current_user_can( 'delete_user', $id ) ) + continue; + + if ( ! empty( $_POST['delete'] ) && 'reassign' == $_POST['delete'][$blogid][$id] ) + remove_user_from_blog( $id, $blogid, $user_id ); + else + remove_user_from_blog( $id, $blogid ); + } + } + } + $i = 0; + if ( is_array( $_POST['user'] ) && ! empty( $_POST['user'] ) ) + foreach( $_POST['user'] as $id ) { + if ( ! current_user_can( 'delete_user', $id ) ) + continue; + wpmu_delete_user( $id ); + $i++; + } + + if ( $i == 1 ) + $deletefunction = 'delete'; + else + $deletefunction = 'all_delete'; + + wp_redirect( add_query_arg( array( 'updated' => 'true', 'action' => $deletefunction ), network_admin_url( 'users.php' ) ) ); + exit(); + break; + + default: + // Let plugins use us as a post handler easily + do_action( 'network_admin_edit_' . $_GET['action'] ); + wp_redirect( network_admin_url( 'index.php' ) ); + exit(); + break; +} +?> diff --git a/src/wp-admin/network/index-extra.php b/src/wp-admin/network/index-extra.php new file mode 100644 index 00000000..17ead786 --- /dev/null +++ b/src/wp-admin/network/index-extra.php @@ -0,0 +1,13 @@ +' . __('Until WordPress 3.0, running multiple sites required using WordPress MU instead of regular WordPress. In version 3.0, these applications have merged. If you are a former MU user, you should be aware of the following changes:') . '

    ' . + '
    • ' . __('Site Admin is now Super Admin (we highly encourage you to get yourself a cape!).') . '
    • ' . + '
    • ' . __('Blogs are now called Sites; Site is now called Network.') . '
    ' . + '

    ' . __('This screen provides the network administrator with links to the screens for Sites and Users to either create a new site or user, or to search existing users and sites, as well as Dashboard widgets. Those screens are also accessible through the left-hand navigation in the Network Admin section.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on the Network Admin') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +wp_dashboard_setup(); + +wp_enqueue_script( 'dashboard' ); +wp_enqueue_script( 'plugin-install' ); +wp_admin_css( 'dashboard' ); +wp_admin_css( 'plugin-install' ); +add_thickbox(); + +add_screen_option('layout_columns', array('max' => 4, 'default' => 2) ); + +require_once( '../admin-header.php' ); + +?> + +
    + +

    + +
    + + + +
    +
    + +
    + + diff --git a/src/wp-admin/network/menu.php b/src/wp-admin/network/menu.php new file mode 100644 index 00000000..7fbfb995 --- /dev/null +++ b/src/wp-admin/network/menu.php @@ -0,0 +1,73 @@ +response) ) + $theme_update_count = count( $update_themes->response ); +$menu[15] = array(sprintf(__('Themes %s'), "" . number_format_i18n($theme_update_count) . "" ), 'manage_network_themes', 'themes.php', '', 'menu-top menu-icon-appearance', 'menu-appearance', 'div'); +$submenu['themes.php'][5] = array( __('Themes'), 'manage_network_themes', 'themes.php' ); +$submenu['themes.php'][10] = array( _x('Add New', 'theme'), 'install_themes', 'theme-install.php' ); +$submenu['themes.php'][15] = array( _x('Editor', 'theme editor'), 'edit_themes', 'theme-editor.php' ); + +$update_plugins = get_site_transient( 'update_plugins' ); +if ( !empty($update_plugins->response) ) + $plugin_update_count = count( $update_plugins->response ); +$menu[20] = array(sprintf( __('Plugins %s'), "" . number_format_i18n($plugin_update_count) . "" ), 'manage_network_plugins', 'plugins.php', '', 'menu-top menu-icon-plugins', 'menu-plugins', 'div'); +$submenu['plugins.php'][5] = array( __('Plugins'), 'manage_network_plugins', 'plugins.php' ); +$submenu['plugins.php'][10] = array( _x('Add New', 'plugin editor'), 'install_plugins', 'plugin-install.php' ); +$submenu['plugins.php'][15] = array( _x('Editor', 'plugin editor'), 'edit_plugins', 'plugin-editor.php' ); + + +$menu[25] = array(__('Settings'), 'manage_network_options', 'settings.php', '', 'menu-top menu-icon-settings', 'menu-settings', 'div'); +if ( defined( 'MULTISITE' ) && defined( 'WP_ALLOW_MULTISITE' ) && WP_ALLOW_MULTISITE ) { + $submenu['settings.php'][5] = array( __('Settings'), 'manage_network_options', 'settings.php' ); + $submenu['settings.php'][10] = array( __('Network Setup'), 'manage_network_options', 'setup.php' ); +} + +$update_wordpress = get_core_updates( array('dismissed' => false) ); +if ( !empty($update_wordpress) && !in_array( $update_wordpress[0]->response, array('development', 'latest') ) ) + $wordpress_update_count = 1; + +$update_count = $plugin_update_count + $theme_update_count + $wordpress_update_count; +$update_title = array(); +if ( $wordpress_update_count ) + $update_title[] = sprintf(__('%d WordPress Update'), $wordpress_update_count); +if ( $plugin_update_count ) + $update_title[] = sprintf(_n('%d Plugin Update', '%d Plugin Updates', $plugin_update_count), $plugin_update_count); +if ( $theme_update_count ) + $update_title[] = sprintf(_n('%d Theme Update', '%d Themes Updates', $theme_update_count), $theme_update_count); + +$update_title = !empty($update_title) ? esc_attr(implode(', ', $update_title)) : ''; + +$menu[30] = array(sprintf( __('Updates %s'), "" . number_format_i18n($update_count) . "" ), 'manage_network', 'upgrade.php', '', 'menu-top menu-icon-tools', 'menu-update', 'div'); +$submenu[ 'upgrade.php' ][10] = array( __( 'Updates' ), 'update_core', 'update-core.php' ); +$submenu[ 'upgrade.php' ][15] = array( __( 'Update Network' ), 'manage_network', 'upgrade.php' ); +unset($plugin_update_count, $theme_update_count, $wordpress_update_count, $update_count, $update_title, $update_themes, $update_plugins, $update_wordpress); + + +$menu[99] = array( '', 'read', 'separator-last', '', 'wp-menu-separator-last' ); + +require_once(ABSPATH . 'wp-admin/includes/menu.php'); + +?> \ No newline at end of file diff --git a/src/wp-admin/network/plugin-editor.php b/src/wp-admin/network/plugin-editor.php new file mode 100644 index 00000000..8850aa8f --- /dev/null +++ b/src/wp-admin/network/plugin-editor.php @@ -0,0 +1,16 @@ +' . __('This screen sets and changes options for the network as a whole. The first site is the main site in the network and network options are pulled from that original site’s options.') . '

    ' . + '

    ' . __('Operational settings has fields for the network’s name and admin email.') . '

    ' . + '

    ' . __('Dashboard Site is an option to give a site to users who do not have a site on the system. Their default role is Subscriber, but that default can be changed. The Admin Notice Feed can provide a notice on all dashboards of the latest post via RSS or Atom, or provide no such notice if left blank.') . '

    ' . + '

    ' . __('Registration settings can disable/enable public signups. If you let others sign up for a site, install spam plugins. Spaces, not commas, should separate names banned as sites for this network.') . '

    ' . + '

    ' . __('New site settings are defaults applied when a new site is created in the network. These include welcome email for when a new site or user account is registered, and what᾿s put in the first post, page, comment, comment author, and comment URL.') . '

    ' . + '

    ' . __('Upload settings control the size of the uploaded files and the amount of available upload space for each site. You can change the default value for specific sites when you edit a particular site. Allowed file types are also listed (space separated only).') . '

    ' . + '

    ' . __('Checkboxes for media upload buttons set which are shown in the visual editor. If unchecked, a generic upload button is still visible; other media types can still be uploaded if on the allowed file types list.') . '

    ' . + '

    ' . __('Menu setting enables/disables the plugin menus from appearing for non super admins, so that only super admins, not site admins, have access to activate plugins.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Network Settings') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include( '../admin-header.php' ); + +if (isset($_GET['updated'])) { + ?> +

    + + +
    + +

    +
    + +

    + + + + + + + + + + +
    + +
    + +
    + +
    + support@%s is recommended.' ), $current_site->domain ); ?> +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    + NOBLOGREDIRECT in wp-config.php to a URL you will redirect visitors to if they visit a non-existent site.' ); + ?> +
    + +
    + +
    + " size="45" /> +
    + +
    + + +
    + +
    + +
    + +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + + + + + + + + + + + + + + + + + + + + + +

    +
    +
    +
    +
    ' ); ?>
    + + +

    + + + + + +
    + +
    + + +

    + + + + + + + + + + +
    +
    + + diff --git a/src/wp-admin/network/setup.php b/src/wp-admin/network/setup.php new file mode 100644 index 00000000..e5d5880f --- /dev/null +++ b/src/wp-admin/network/setup.php @@ -0,0 +1,16 @@ +' . __('The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.') . '

    ' . + '

    ' . __('Info - The domain and path are rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.') . '

    ' . + '

    ' . __('Users - This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.') . '

    ' . + '

    ' . sprintf( __('Themes - This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site’s Appearance menu. To enable a theme for the entire network, see the Network Themes screen.' ), network_admin_url( 'themes.php' ) ) . '

    ' . + '

    ' . __('Settings - This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Site Management') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; + +if ( ! $id ) + wp_die( __('Invalid site ID.') ); + +$details = get_blog_details( $id ); +if ( !can_edit_network( $details->site_id ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + +$is_main_site = is_main_site( $id ); + +if ( isset($_REQUEST['action']) && 'update-site' == $_REQUEST['action'] ) { + check_admin_referer( 'edit-site' ); + + switch_to_blog( $id ); + + if ( isset( $_POST['update_home_url'] ) && $_POST['update_home_url'] == 'update' ) { + $blog_address = get_blogaddress_by_domain( $_POST['blog']['domain'], $_POST['blog']['path'] ); + if ( get_option( 'siteurl' ) != $blog_address ) + update_option( 'siteurl', $blog_address ); + + if ( get_option( 'home' ) != $blog_address ) + update_option( 'home', $blog_address ); + } + + // rewrite rules can't be flushed during switch to blog + delete_option( 'rewrite_rules' ); + + // update blogs table + $blog_data = stripslashes_deep( $_POST['blog'] ); + $existing_details = get_blog_details( $id, false ); + $blog_data_checkboxes = array( 'public', 'archived', 'spam', 'mature', 'deleted' ); + foreach ( $blog_data_checkboxes as $c ) { + if ( ! in_array( $existing_details->$c, array( 0, 1 ) ) ) + $blog_data[ $c ] = $existing_details->$c; + else + $blog_data[ $c ] = isset( $_POST['blog'][ $c ] ) ? 1 : 0; + } + update_blog_details( $id, $blog_data ); + + restore_current_blog(); + wp_redirect( add_query_arg( array( 'update' => 'updated', 'id' => $id ), 'site-info.php') ); + exit; +} + +if ( isset($_GET['update']) ) { + $messages = array(); + if ( 'updated' == $_GET['update'] ) + $messages[] = __('Site info updated.'); +} + +$title = sprintf( __('Edit Site: %s'), get_blogaddress_by_id($id)); +$parent_file = 'sites.php'; +$submenu_file = 'sites.php'; + +require('../admin-header.php'); + +?> + +
    + +

    + +

    ' . $msg . '

    '; +} ?> +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + __( 'Public' ) ); + if ( ! $is_main_site ) { + $attribute_fields['archived'] = __( 'Archived' ); + $attribute_fields['spam'] = _x( 'Spam', 'site' ); + $attribute_fields['deleted'] = __( 'Deleted' ); + } + $attribute_fields['mature'] = __( 'Mature' ); + ?> + + + + +
    domain ) ?>
    path ) ?> +
    /> siteurl and home as well.' ); ?>
    + $field_label ) : ?> +
    + +
    + +
    + +
    +' . __('This screen is for Super Admins to add new sites to the network. This is not affected by the registration settings.') . '

    ' . + '

    ' . __('If the admin email for the new site does not exist in the database, a new user will also be created.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Site Management') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +if ( isset($_REQUEST['action']) && 'add-site' == $_REQUEST['action'] ) { + check_admin_referer( 'add-blog', '_wpnonce_add-blog' ); + + if ( ! current_user_can( 'manage_sites' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + if ( ! is_array( $_POST['blog'] ) ) + wp_die( __( 'Can’t create an empty site.' ) ); + $blog = $_POST['blog']; + $domain = ''; + if ( ! preg_match( '/(--)/', $blog['domain'] ) && preg_match( '|^([a-zA-Z0-9-])+$|', $blog['domain'] ) ) + $domain = strtolower( $blog['domain'] ); + + // If not a subdomain install, make sure the domain isn't a reserved word + if ( ! is_subdomain_install() ) { + $subdirectory_reserved_names = apply_filters( 'subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' ) ); + if ( in_array( $domain, $subdirectory_reserved_names ) ) + wp_die( sprintf( __('The following words are reserved for use by WordPress functions and cannot be used as blog names: %s' ), implode( ', ', $subdirectory_reserved_names ) ) ); + } + + $email = sanitize_email( $blog['email'] ); + $title = $blog['title']; + + if ( empty( $domain ) ) + wp_die( __( 'Missing or invalid site address.' ) ); + if ( empty( $email ) ) + wp_die( __( 'Missing email address.' ) ); + if ( !is_email( $email ) ) + wp_die( __( 'Invalid email address.' ) ); + + if ( is_subdomain_install() ) { + $newdomain = $domain . '.' . preg_replace( '|^www\.|', '', $current_site->domain ); + $path = $base; + } else { + $newdomain = $current_site->domain; + $path = $base . $domain . '/'; + } + + $password = 'N/A'; + $user_id = email_exists($email); + if ( !$user_id ) { // Create a new user with a random password + $password = wp_generate_password( 12, false ); + $user_id = wpmu_create_user( $domain, $password, $email ); + if ( false == $user_id ) + wp_die( __( 'There was an error creating the user.' ) ); + else + wp_new_user_notification( $user_id, $password ); + } + + $wpdb->hide_errors(); + $id = wpmu_create_blog( $newdomain, $path, $title, $user_id , array( 'public' => 1 ), $current_site->id ); + $wpdb->show_errors(); + if ( !is_wp_error( $id ) ) { + if ( !is_super_admin( $user_id ) && !get_user_option( 'primary_blog', $user_id ) ) + update_user_option( $user_id, 'primary_blog', $id, true ); + $content_mail = sprintf( __( "New site created by %1s\n\nAddress: http://%2s\nName: %3s"), $current_user->user_login , $newdomain . $path, stripslashes( $title ) ); + wp_mail( get_site_option('admin_email'), sprintf( __( '[%s] New Site Created' ), $current_site->site_name ), $content_mail, 'From: "Site Admin" <' . get_site_option( 'admin_email' ) . '>' ); + wpmu_welcome_notification( $id, $user_id, $password, $title, array( 'public' => 1 ) ); + wp_redirect( add_query_arg( array('update' => 'added'), 'site-new.php' ) ); + exit; + } else { + wp_die( $id->get_error_message() ); + } +} + +if ( isset($_GET['update']) ) { + $messages = array(); + if ( 'added' == $_GET['update'] ) + $messages[] = __('Site added.'); +} + +$title = __('Add New Site'); +$parent_file = 'sites.php'; + +require('../admin-header.php'); + +?> + +
    + +

    +

    ' . $msg . '

    '; +} ?> +
    + + + + + + + + + + + + + + + + + +
    + + .domain );?> + domain . $current_site->path ?> + ' . __( 'Only the characters a-z and 0-9 recommended.' ) . '

    '; + ?> +

    + +
    +
    + diff --git a/src/wp-admin/network/site-settings.php b/src/wp-admin/network/site-settings.php new file mode 100644 index 00000000..b90bb76d --- /dev/null +++ b/src/wp-admin/network/site-settings.php @@ -0,0 +1,150 @@ +' . __('The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.') . '

    ' . + '

    ' . __('Info - The domain and path are rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.') . '

    ' . + '

    ' . __('Users - This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.') . '

    ' . + '

    ' . sprintf( __('Themes - This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site’s Appearance menu. To enable a theme for the entire network, see the Network Themes screen.' ), network_admin_url( 'themes.php' ) ) . '

    ' . + '

    ' . __('Settings - This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Site Management') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; + +if ( ! $id ) + wp_die( __('Invalid site ID.') ); + +$details = get_blog_details( $id ); +if ( !can_edit_network( $details->site_id ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + +$is_main_site = is_main_site( $id ); + +if ( isset($_REQUEST['action']) && 'update-site' == $_REQUEST['action'] && is_array( $_POST['option'] ) ) { + check_admin_referer( 'edit-site' ); + + switch_to_blog( $id ); + + $c = 1; + $count = count( $_POST['option'] ); + $skip_options = array( 'allowedthemes' ); // Don't update these options since they are handled elsewhere in the form. + foreach ( (array) $_POST['option'] as $key => $val ) { + if ( $key === 0 || is_array( $val ) || in_array($key, $skip_options) ) + continue; // Avoids "0 is a protected WP option and may not be modified" error when edit blog options + if ( $c == $count ) + update_option( $key, stripslashes( $val ) ); + else + update_option( $key, stripslashes( $val ), false ); // no need to refresh blog details yet + $c++; + } + + do_action( 'wpmu_update_blog_options' ); + restore_current_blog(); + wp_redirect( add_query_arg( array( 'update' => 'updated', 'id' => $id ), 'site-settings.php') ); + exit; +} + +if ( isset($_GET['update']) ) { + $messages = array(); + if ( 'updated' == $_GET['update'] ) + $messages[] = __('Site options updated.'); +} + +$title = sprintf( __('Edit Site: %s'), get_blogaddress_by_id($id)); +$parent_file = 'sites.php'; +$submenu_file = 'sites.php'; + +require('../admin-header.php'); + +?> + +
    + +

    + +

    ' . $msg . '

    '; +} ?> +
    + + + + get_blog_prefix( $id ); + $options = $wpdb->get_results( "SELECT * FROM {$blog_prefix}options WHERE option_name NOT LIKE '\_%' AND option_name NOT LIKE '%user_roles'" ); + foreach ( $options as $option ) { + if ( $option->option_name == 'default_role' ) + $editblog_default_role = $option->option_value; + $disabled = false; + $class = 'all-options'; + if ( is_serialized( $option->option_value ) ) { + if ( is_serialized_string( $option->option_value ) ) { + $option->option_value = esc_html( maybe_unserialize( $option->option_value ), 'single' ); + } else { + $option->option_value = 'SERIALIZED DATA'; + $disabled = true; + $class = 'all-options disabled'; + } + } + if ( strpos( $option->option_value, "\n" ) !== false ) { + ?> + + + + + + + + option_name, array( 'siteurl', 'home' ) ) ) { ?> + + + + + + +
    option_name ) ) ?>
    option_name ) ) ); ?>option_value ) ?> />
    + +
    + +
    +' . __('The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.') . '

    ' . + '

    ' . __('Info - The domain and path are rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.') . '

    ' . + '

    ' . __('Users - This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.') . '

    ' . + '

    ' . sprintf( __('Themes - This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site’s Appearance menu. To enable a theme for the entire network, see the Network Themes screen.' ), network_admin_url( 'themes.php' ) ) . '

    ' . + '

    ' . __('Settings - This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Site Management') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +$wp_list_table = _get_list_table('WP_MS_Themes_List_Table'); + +$action = $wp_list_table->current_action(); + +$s = isset($_REQUEST['s']) ? $_REQUEST['s'] : ''; + +// Clean up request URI from temporary args for screen options/paging uri's to work as expected. +$temp_args = array( 'enabled', 'disabled', 'error' ); +$_SERVER['REQUEST_URI'] = remove_query_arg( $temp_args, $_SERVER['REQUEST_URI'] ); +$referer = remove_query_arg( $temp_args, wp_get_referer() ); + +$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; + +if ( ! $id ) + wp_die( __('Invalid site ID.') ); + +$wp_list_table->prepare_items(); + +$details = get_blog_details( $id ); +if ( !can_edit_network( $details->site_id ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + +$is_main_site = is_main_site( $id ); + +if ( $action ) { + switch_to_blog( $id ); + $allowed_themes = get_option( 'allowedthemes' ); + + switch ( $action ) { + case 'enable': + check_admin_referer( 'enable-theme_' . $_GET['theme'] ); + $theme = $_GET['theme']; + $action = 'enabled'; + $n = 1; + if ( !$allowed_themes ) + $allowed_themes = array( $theme => true ); + else + $allowed_themes[$theme] = true; + break; + case 'disable': + check_admin_referer( 'disable-theme_' . $_GET['theme'] ); + $theme = $_GET['theme']; + $action = 'disabled'; + $n = 1; + if ( !$allowed_themes ) + $allowed_themes = array(); + else + unset( $allowed_themes[$theme] ); + break; + case 'enable-selected': + check_admin_referer( 'bulk-themes' ); + if ( isset( $_POST['checked'] ) ) { + $themes = (array) $_POST['checked']; + $action = 'enabled'; + $n = count( $themes ); + foreach( (array) $themes as $theme ) + $allowed_themes[ $theme ] = true; + } else { + $action = 'error'; + $n = 'none'; + } + break; + case 'disable-selected': + check_admin_referer( 'bulk-themes' ); + if ( isset( $_POST['checked'] ) ) { + $themes = (array) $_POST['checked']; + $action = 'disabled'; + $n = count( $themes ); + foreach( (array) $themes as $theme ) + unset( $allowed_themes[ $theme ] ); + } else { + $action = 'error'; + $n = 'none'; + } + break; + } + + update_option( 'allowedthemes', $allowed_themes ); + restore_current_blog(); + + wp_redirect( add_query_arg( $action, $n, $referer ) ); + exit; +} + +if ( isset( $_GET['action'] ) && 'update-site' == $_GET['action'] ) { + wp_redirect( $referer ); + exit(); +} + +add_thickbox(); +add_screen_option( 'per_page', array( 'label' => _x( 'Themes', 'themes per page (screen options)' ) ) ); + +$title = sprintf( __('Edit Site: %s'), get_blogaddress_by_id($id)); +$parent_file = 'sites.php'; +$submenu_file = 'sites.php'; + +require('../admin-header.php'); ?> + +
    + +

    +

    ' . sprintf( _n( 'Theme enabled.', '%s themes enabled.', $_GET['enabled'] ), number_format_i18n( $_GET['enabled'] ) ) . '

    '; +} elseif ( isset( $_GET['disabled'] ) ) { + $_GET['disabled'] = absint( $_GET['disabled'] ); + echo '

    ' . sprintf( _n( 'Theme disabled.', '%s themes disabled.', $_GET['disabled'] ), number_format_i18n( $_GET['disabled'] ) ) . '

    '; +} elseif ( isset( $_GET['error'] ) && 'none' == $_GET['error'] ) { + echo '

    ' . __( 'No theme selected.' ) . '

    '; +} ?> + +

    + +
    +search_box( __( 'Search Installed Themes' ), 'theme' ); ?> + +
    + +views(); ?> + +
    + + + +display(); ?> + +
    + +
    + diff --git a/src/wp-admin/network/site-users.php b/src/wp-admin/network/site-users.php new file mode 100644 index 00000000..9366cb93 --- /dev/null +++ b/src/wp-admin/network/site-users.php @@ -0,0 +1,308 @@ +prepare_items(); + +$action = $wp_list_table->current_action(); + +add_contextual_help($current_screen, + '

    ' . __('The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.') . '

    ' . + '

    ' . __('Info - The domain and path are rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.') . '

    ' . + '

    ' . __('Users - This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.') . '

    ' . + '

    ' . sprintf( __('Themes - This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site’s Appearance menu. To enable a theme for the entire network, see the Network Themes screen.' ), network_admin_url( 'themes.php' ) ) . '

    ' . + '

    ' . __('Settings - This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Site Management') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; + +if ( ! $id ) + wp_die( __('Invalid site ID.') ); + +$details = get_blog_details( $id ); +if ( !can_edit_network( $details->site_id ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + +$is_main_site = is_main_site( $id ); + +// get blog prefix +$blog_prefix = $wpdb->get_blog_prefix( $id ); + +// @todo This is a hack. Eventually, add API to WP_Roles allowing retrieval of roles for a particular blog. +if ( ! empty($wp_roles->use_db) ) { + $editblog_roles = get_blog_option( $id, "{$blog_prefix}user_roles" ); +} else { + // Roles are stored in memory, not the DB. + $editblog_roles = $wp_roles->roles; +} +$default_role = get_blog_option( $id, 'default_role' ); + +$action = $wp_list_table->current_action(); + +if ( $action ) { + switch_to_blog( $id ); + + switch ( $action ) { + case 'newuser': + check_admin_referer( 'add-user', '_wpnonce_add-new-user' ); + $user = $_POST['user']; + if ( !is_array( $_POST['user'] ) || empty( $user['username'] ) || empty( $user['email'] ) ) { + $update = 'err_new'; + } else { + $password = wp_generate_password( 12, false); + $user_id = wpmu_create_user( esc_html( strtolower( $user['username'] ) ), $password, esc_html( $user['email'] ) ); + + if ( false == $user_id ) { + $update = 'err_new_dup'; + } else { + wp_new_user_notification( $user_id, $password ); + add_user_to_blog( $id, $user_id, $_POST['new_role'] ); + $update = 'newuser'; + } + } + break; + + case 'adduser': + check_admin_referer( 'add-user', '_wpnonce_add-user' ); + if ( !empty( $_POST['newuser'] ) ) { + $update = 'adduser'; + $newuser = $_POST['newuser']; + $userid = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM " . $wpdb->users . " WHERE user_login = %s", $newuser ) ); + if ( $userid ) { + $user = $wpdb->get_var( "SELECT user_id FROM " . $wpdb->usermeta . " WHERE user_id='$userid' AND meta_key='{$blog_prefix}capabilities'" ); + if ( $user == false ) + add_user_to_blog( $id, $userid, $_POST['new_role'] ); + else + $update = 'err_add_member'; + } else { + $update = 'err_add_notfound'; + } + } else { + $update = 'err_add_notfound'; + } + break; + + case 'remove': + if ( !current_user_can('remove_users') ) + die(__('You can’t remove users.')); + check_admin_referer( 'bulk-users' ); + + $update = 'remove'; + if ( isset( $_REQUEST['users'] ) ) { + $userids = $_REQUEST['users']; + + foreach ( $userids as $user_id ) { + $user_id = (int) $user_id; + remove_user_from_blog( $user_id, $id ); + } + } elseif ( isset( $_GET['user'] ) ) { + remove_user_from_blog( $_GET['user'] ); + } else { + $update = 'err_remove'; + } + break; + + case 'promote': + check_admin_referer( 'bulk-users' ); + $editable_roles = get_editable_roles(); + if ( empty( $editable_roles[$_REQUEST['new_role']] ) ) + wp_die(__('You can’t give users that role.')); + + if ( isset( $_REQUEST['users'] ) ) { + $userids = $_REQUEST['users']; + $update = 'promote'; + foreach ( $userids as $user_id ) { + $user_id = (int) $user_id; + + // If the user doesn't already belong to the blog, bail. + if ( !is_user_member_of_blog( $user_id ) ) + wp_die(__('Cheatin’ uh?')); + + $user = new WP_User( $user_id ); + $user->set_role( $_REQUEST['new_role'] ); + } + } else { + $update = 'err_promote'; + } + break; + } + + restore_current_blog(); + wp_redirect( add_query_arg( 'update', $update, wp_get_referer() ) ); + exit(); +} + +if ( isset( $_GET['action'] ) && 'update-site' == $_GET['action'] ) { + wp_redirect( wp_get_referer() ); + exit(); +} + +add_screen_option( 'per_page', array( 'label' => _x( 'Users', 'users per page (screen options)' ) ) ); + +$title = sprintf( __('Edit Site: %s'), get_blogaddress_by_id($id)); +$parent_file = 'sites.php'; +$submenu_file = 'sites.php'; + +require('../admin-header.php'); ?> + +
    + +

    +

    ' . __( 'User added.' ) . '

    '; + break; + case 'err_add_member': + echo '

    ' . __( 'User is already a member of this site.' ) . '

    '; + break; + case 'err_add_notfound': + echo '

    ' . __( 'Enter the username of an existing user.' ) . '

    '; + break; + case 'promote': + echo '

    ' . __( 'Changed roles.' ) . '

    '; + break; + case 'err_promote': + echo '

    ' . __( 'Select a user to change role.' ) . '

    '; + break; + case 'remove': + echo '

    ' . __( 'User removed from this site.' ) . '

    '; + break; + case 'err_remove': + echo '

    ' . __( 'Select a user to remove.' ) . '

    '; + break; + case 'newuser': + echo '

    ' . __( 'User created.' ) . '

    '; + break; + case 'err_new': + echo '

    ' . __( 'Enter the username and email.' ) . '

    '; + break; + case 'err_new_dup': + echo '

    ' . __( 'Duplicated username or email address.' ) . '

    '; + break; + } +endif; ?> + +
    +search_box( __( 'Search Users' ), 'user' ); ?> + +
    + +views(); ?> + +
    + + + +display(); ?> + +
    + + + + +

    + +

    + +

    + +
    +
    + + + + + + + + + + + +
    + + +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +get_pagenum(); + +$title = __( 'Sites' ); +$parent_file = 'sites.php'; + +add_screen_option( 'per_page', array('label' => _x( 'Sites', 'sites per page (screen options)' )) ); + +add_contextual_help($current_screen, + '

    ' . __('Add New takes you to the Add New Site screen. You can search for a site by Name, ID number, or IP address. Screen Options allows you to choose how many sites to display on one page.') . '

    ' . + '

    ' . __('This is the main table of all sites on this network. Switch between list and excerpt views by using the icons above the right side of the table.') . '

    ' . + '

    ' . __('Hovering over each site reveals seven options (three for the primary site):') . '

    ' . + '
    • ' . __('An Edit link to a separate Edit Site screen.') . '
    • ' . + '
    • ' . __('Dashboard leads to the Dashboard for that site.') . '
    • ' . + '
    • ' . __('Deactivate, Archive, and Spam which lead to confirmation screens. These actions can be reversed later.') . '
    • ' . + '
    • ' . __('Delete which is a permanent action after the confirmation screens.') . '
    • ' . + '
    • ' . __('Visit to go to the frontend site live.') . '
    ' . + '

    ' . __('The site ID is used internally, and is not shown on the front end of the site or to users/viewers.') . '

    ' . + '

    ' . __('Clicking on bold settings can re-sort this table. The upper right icons switch between list and excerpt views.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Site Management') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; + +$msg = ''; +if ( isset( $_REQUEST['updated'] ) && $_REQUEST['updated'] == 'true' && ! empty( $_REQUEST['action'] ) ) { + switch ( $_REQUEST['action'] ) { + case 'all_notspam': + $msg = __( 'Sites removed from spam.' ); + break; + case 'all_spam': + $msg = __( 'Sites marked as spam.' ); + break; + case 'all_delete': + $msg = __( 'Sites deleted.' ); + break; + case 'delete': + $msg = __( 'Site deleted.' ); + break; + case 'not_deleted': + $msg = __( 'You do not have permission to delete that site.' ); + break; + case 'archive': + $msg = __( 'Site archived.' ); + break; + case 'unarchive': + $msg = __( 'Site unarchived.' ); + break; + case 'activate': + $msg = __( 'Site activated.' ); + break; + case 'deactivate': + $msg = __( 'Site deactivated.' ); + break; + case 'unspam': + $msg = __( 'Site removed from spam.' ); + break; + case 'spam': + $msg = __( 'Site marked as spam.' ); + break; + default: + $msg = apply_filters( 'network_sites_updated_message_' . $_REQUEST['action'] , __( 'Settings saved.' ) ); + break; + } + if ( $msg ) + $msg = '

    ' . $msg . '

    '; +} + +$wp_list_table->prepare_items(); + +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +require_once( '../admin-header.php' ); +?> + +
    + +

    + + + + + +' . __( 'Search results for “%s”' ) . '', esc_html( $s ) ); +} ?> +

    + + + +
    + display(); ?> +
    +
    + diff --git a/src/wp-admin/network/theme-editor.php b/src/wp-admin/network/theme-editor.php new file mode 100644 index 00000000..f6ac9c2e --- /dev/null +++ b/src/wp-admin/network/theme-editor.php @@ -0,0 +1,16 @@ +get_pagenum(); + +$action = $wp_list_table->current_action(); + +$s = isset($_REQUEST['s']) ? $_REQUEST['s'] : ''; + +// Clean up request URI from temporary args for screen options/paging uri's to work as expected. +$temp_args = array( 'enabled', 'disabled', 'deleted', 'error' ); +$_SERVER['REQUEST_URI'] = remove_query_arg( $temp_args, $_SERVER['REQUEST_URI'] ); +$referer = remove_query_arg( $temp_args, wp_get_referer() ); + +if ( $action ) { + $allowed_themes = get_site_option( 'allowedthemes' ); + switch ( $action ) { + case 'enable': + check_admin_referer('enable-theme_' . $_GET['theme']); + $allowed_themes[ $_GET['theme'] ] = true; + update_site_option( 'allowedthemes', $allowed_themes ); + wp_redirect( add_query_arg( 'enabled', '1', $referer ) ); + exit; + break; + case 'disable': + check_admin_referer('disable-theme_' . $_GET['theme']); + unset( $allowed_themes[ $_GET['theme'] ] ); + update_site_option( 'allowedthemes', $allowed_themes ); + wp_redirect( add_query_arg( 'disabled', '1', $referer ) ); + exit; + break; + case 'enable-selected': + check_admin_referer('bulk-themes'); + $themes = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array(); + if ( empty($themes) ) { + wp_redirect( add_query_arg( 'error', 'none', $referer ) ); + exit; + } + foreach( (array) $themes as $theme ) + $allowed_themes[ $theme ] = true; + update_site_option( 'allowedthemes', $allowed_themes ); + wp_redirect( add_query_arg( 'enabled', count( $themes ), $referer ) ); + exit; + break; + case 'disable-selected': + check_admin_referer('bulk-themes'); + $themes = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array(); + if ( empty($themes) ) { + wp_redirect( add_query_arg( 'error', 'none', $referer ) ); + exit; + } + foreach( (array) $themes as $theme ) + unset( $allowed_themes[ $theme ] ); + update_site_option( 'allowedthemes', $allowed_themes ); + wp_redirect( add_query_arg( 'disabled', count( $themes ), $referer ) ); + exit; + break; + case 'delete-selected': + if ( ! current_user_can( 'delete_themes' ) ) + wp_die( __('You do not have sufficient permissions to delete themes for this site.') ); + check_admin_referer( 'bulk-themes' ); + + $themes = isset( $_REQUEST['checked'] ) ? (array) $_REQUEST['checked'] : array(); + + if ( isset( $themes[ get_option( 'template' ) ] ) ) + unset( $themes[ get_option( 'template' ) ] ); + if ( isset( $themes[ get_option( 'stylesheet' ) ] ) ) + unset( $themes[ get_option( 'stylesheet' ) ] ); + + if ( empty( $themes ) ) { + wp_redirect( add_query_arg( 'error', 'none', $referer ) ); + exit; + } + + $main_theme = get_current_theme(); + $files_to_delete = $theme_info = array(); + foreach ( $themes as $key => $theme ) { + $data = get_theme_data( WP_CONTENT_DIR . '/themes/' . $theme . '/style.css' ); + if ( $data['Name'] == $main_theme ) { + unset( $themes[$key] ); + } else { + $files_to_delete = array_merge( $files_to_delete, list_files( WP_CONTENT_DIR . "/themes/$theme" ) ); + $theme_info[ $theme ] = $data; + } + } + + if ( empty( $themes ) ) { + wp_redirect( add_query_arg( 'error', 'main', $referer ) ); + exit; + } + + include(ABSPATH . 'wp-admin/update.php'); + + $parent_file = 'themes.php'; + + if ( ! isset( $_REQUEST['verify-delete'] ) ) { + wp_enqueue_script( 'jquery' ); + require_once( ABSPATH . 'wp-admin/admin-header.php' ); + ?> +
    + ' . _n( 'Delete Theme', 'Delete Themes', $themes_to_delete ) . ''; + ?> +

    +

    +
      + ', sprintf( __('%1$s by %2$s' ), esc_html( $theme['Name'] ), esc_html( $theme['AuthorName'] ) ), ''; /* translators: 1: theme name, 2: theme author */ ?> +
    +

    +
    + + + '; + ?> + + +
    +
    + +
    + +

    + +
    + 1), $_SERVER['REQUEST_URI'] ) ) ); + $paged = ( $_REQUEST['paged'] ) ? $_REQUEST['paged'] : 1; + wp_redirect( network_admin_url( "themes.php?deleted=".count( $themes )."&paged=$paged&s=$s" ) ); + exit; + break; + } +} + +$wp_list_table->prepare_items(); + +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +add_thickbox(); + +add_screen_option( 'per_page', array('label' => _x( 'Themes', 'themes per page (screen options)' )) ); + +add_contextual_help($current_screen, + '

    ' . __('This screen enables and disables the inclusion of themes available to choose in the Appearance menu for each site. It does not activate or deactivate which theme a site is currently using.') . '

    ' . + '

    ' . __('If the network admin disables a theme that is in use, it can still remain selected on that site. If another theme is chosen, the disabled theme will not appear in the site’s Appearance > Themes screen.') . '

    ' . + '

    ' . __('Themes can be enabled on a site by site basis by the network admin on the Edit Site screen you go to via the Edit action link on the Sites screen. Only network admins are able to install or edit themes.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Network Themes') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +$title = __('Themes'); +$parent_file = 'themes.php'; + +require_once(ABSPATH . 'wp-admin/admin-header.php'); + +?> + +
    + +

    ' . __('Search results for “%s”') . '', esc_html( $s ) ); ?> +

    + +

    ' . sprintf( _n( 'Theme enabled.', '%s themes enabled.', $_GET['enabled'] ), number_format_i18n( $_GET['enabled'] ) ) . '

    '; +} elseif ( isset( $_GET['disabled'] ) ) { + $_GET['disabled'] = absint( $_GET['disabled'] ); + echo '

    ' . sprintf( _n( 'Theme disabled.', '%s themes disabled.', $_GET['disabled'] ), number_format_i18n( $_GET['disabled'] ) ) . '

    '; +} elseif ( isset( $_GET['deleted'] ) ) { + $_GET['deleted'] = absint( $_GET['deleted'] ); + echo '

    ' . sprintf( _nx( 'Theme deleted.', '%s themes deleted.', $_GET['deleted'], 'network' ), number_format_i18n( $_GET['deleted'] ) ) . '

    '; +} elseif ( isset( $_GET['error'] ) && 'none' == $_GET['error'] ) { + echo '

    ' . __( 'No theme selected.' ) . '

    '; +} elseif ( isset( $_GET['error'] ) && 'main' == $_GET['error'] ) { + echo '

    ' . __( 'You cannot delete a theme while it is active on the main site.' ) . '

    '; +} + +?> + +
    +search_box( __( 'Search Installed Themes' ), 'theme' ); ?> +
    + +views(); ?> + +
    + + + +display(); ?> +
    + + + +' . __('Only use this screen once you have updated to a new version of WordPress through Dashboard > Updates. Clicking the Update Network button will step through each site in the network, five at a time, and make sure any database updates are applied.') . '

    ' . + '

    ' . __('If a version update to core has not happened, clicking this button won’t affect anything.') . '

    ' . + '

    ' . __('If this process fails for any reason, users logging in to their sites will force the same update.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Update Network') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +require_once('../admin-header.php'); + +if ( ! current_user_can( 'manage_network' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + +echo '
    '; +screen_icon('tools'); +echo '

    ' . __( 'Update Network' ) . '

    '; + +$action = isset($_GET['action']) ? $_GET['action'] : 'show'; + +switch ( $action ) { + case "upgrade": + $n = ( isset($_GET['n']) ) ? intval($_GET['n']) : 0; + + if ( $n < 5 ) { + global $wp_db_version; + update_site_option( 'wpmu_upgrade_site', $wp_db_version ); + } + + $blogs = $wpdb->get_results( "SELECT * FROM {$wpdb->blogs} WHERE site_id = '{$wpdb->siteid}' AND spam = '0' AND deleted = '0' AND archived = '0' ORDER BY registered DESC LIMIT {$n}, 5", ARRAY_A ); + if ( empty( $blogs ) ) { + echo '

    ' . __( 'All done!' ) . '

    '; + break; + } + echo "
      "; + foreach ( (array) $blogs as $details ) { + $siteurl = get_blog_option( $details['blog_id'], 'siteurl' ); + echo "
    • $siteurl
    • "; + $response = wp_remote_get( trailingslashit( $siteurl ) . "wp-admin/upgrade.php?step=upgrade_db", array( 'timeout' => 120, 'httpversion' => '1.1' ) ); + if ( is_wp_error( $response ) ) + wp_die( sprintf( __( 'Warning! Problem updating %1$s. Your server may not be able to connect to sites running on it. Error message: %2$s' ), $siteurl, $response->get_error_message() ) ); + do_action( 'after_mu_upgrade', $response ); + do_action( 'wpmu_upgrade_site', $details[ 'blog_id' ] ); + } + echo "
    "; + ?>

    +

    +

    +
    + + diff --git a/src/wp-admin/network/user-edit.php b/src/wp-admin/network/user-edit.php new file mode 100644 index 00000000..0b2cfd26 --- /dev/null +++ b/src/wp-admin/network/user-edit.php @@ -0,0 +1,16 @@ +' . __('Add User will set up a new user account on the network and send them an email with their username and password.') . '

    ' . + '

    ' . __('Users who are signed up to the network without a site are added as subscribers to the main or primary dashboard site, giving them profile pages to manage their accounts. These users will only see Dashboard and My Sites in the main navigation until a site is created for them.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Network Users') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +if ( isset($_REQUEST['action']) && 'add-user' == $_REQUEST['action'] ) { + check_admin_referer( 'add-user', '_wpnonce_add-user' ); + if ( ! current_user_can( 'manage_network_users' ) ) + wp_die( __( 'You do not have permission to access this page.' ) ); + + if ( is_array( $_POST['user'] ) == false ) + wp_die( __( 'Cannot create an empty user.' ) ); + $user = $_POST['user']; + if ( empty($user['username']) && empty($user['email']) ) + wp_die( __( 'Missing username and email.' ) ); + elseif ( empty($user['username']) ) + wp_die( __( 'Missing username.' ) ); + elseif ( empty($user['email']) ) + wp_die( __( 'Missing email.' ) ); + + $password = wp_generate_password( 12, false); + $user_id = wpmu_create_user( esc_html( strtolower( $user['username'] ) ), $password, esc_html( $user['email'] ) ); + + if ( false == $user_id ) + wp_die( __( 'Duplicated username or email address.' ) ); + else + wp_new_user_notification( $user_id, $password ); + + wp_redirect( add_query_arg( array('update' => 'added'), 'user-new.php' ) ); + exit; +} + +if ( isset($_GET['update']) ) { + $messages = array(); + if ( 'added' == $_GET['update'] ) + $messages[] = __('User added.'); +} + +$title = __('Add New User'); +$parent_file = 'users.php'; + +require('../admin-header.php'); ?> + +
    + +

    +

    ' . $msg . '

    '; +} ?> +
    + + + + + + + + + + + + +
    + + +
    + + \ No newline at end of file diff --git a/src/wp-admin/network/users.php b/src/wp-admin/network/users.php new file mode 100644 index 00000000..6523c989 --- /dev/null +++ b/src/wp-admin/network/users.php @@ -0,0 +1,96 @@ +get_pagenum(); +$wp_list_table->prepare_items(); +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); + +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} +$title = __( 'Users' ); +$parent_file = 'users.php'; + +add_screen_option( 'per_page', array('label' => _x( 'Users', 'users per page (screen options)' )) ); + +add_contextual_help($current_screen, + '

    ' . __('This table shows all users across the network and the sites to which they are assigned.') . '

    ' . + '

    ' . __('Hover over any user on the list to make the edit links appear. The Edit link on the left will take you to his or her Edit User profile page; the Edit link on the right by any site name goes to an Edit Site screen for that site.') . '

    ' . + '

    ' . __('You can also go to the user’s profile page by clicking on the individual username.') . '

    ' . + '

    ' . __('You can sort the table by clicking on any of the bold headings and switch between list and excerpt views by using the icons in the upper right.') . '

    ' . + '

    ' . __('The bulk action will permanently delete selected users, or mark/unmark those selected as spam. Spam users will have posts removed and will be unable to sign up again with the same email addresses.') . '

    ' . + '

    ' . __('You can make an existing user an additional super admin by going to the Edit User profile page and checking the box to grant that privilege.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Network Users') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +require_once( '../admin-header.php' ); + +if ( isset( $_REQUEST['updated'] ) && $_REQUEST['updated'] == 'true' && ! empty( $_REQUEST['action'] ) ) { + ?> +

    + +

    + +
    + +

    + ' . __( 'Search results for “%s”' ) . '', esc_html( $usersearch ) ); + ?> +

    + + views(); ?> + +
    + search_box( __( 'Search Users' ), 'user' ); ?> +
    + +
    + display(); ?> +
    +
    + + diff --git a/src/wp-admin/options-discussion.php b/src/wp-admin/options-discussion.php new file mode 100644 index 00000000..e9bb1a67 --- /dev/null +++ b/src/wp-admin/options-discussion.php @@ -0,0 +1,248 @@ +' . __('This screen provides many options for controlling the management and display of comments and links to your posts/pages. So many, in fact, they won’t all fit here! :) Use the documentation link below to get information on what each discussion setting does.') . '

    ' . + '

    ' . __('You must click the Save Changes button at the bottom of the screen for new settings to take effect.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Discussion Settings') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include('./admin-header.php'); +?> + +
    + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    + +

    +

    + +

    +
    +

    +

    + +

    +
    + +

    + +

    + + + + + + + + + + + + + + + + + +
    + __( 'Don’t show Avatars' ), 1 => __( 'Show Avatars' ) ); + foreach ( $yesorno as $key => $value) { + $selected = (get_option('show_avatars') == $key) ? 'checked="checked"' : ''; + echo "\n\t
    "; + } +?> +
    + + __('G — Suitable for all audiences'), + /* translators: Content suitability rating: http://bit.ly/89QxZA */ + 'PG' => __('PG — Possibly offensive, usually for audiences 13 and above'), + /* translators: Content suitability rating: http://bit.ly/89QxZA */ + 'R' => __('R — Intended for adult audiences above 17'), + /* translators: Content suitability rating: http://bit.ly/89QxZA */ + 'X' => __('X — Even more mature than above') +); +foreach ($ratings as $key => $rating) : + $selected = (get_option('avatar_rating') == $key) ? 'checked="checked"' : ''; + echo "\n\t
    "; +endforeach; +?> + +
    + +
    + + __('Mystery Man'), + 'blank' => __('Blank'), + 'gravatar_default' => __('Gravatar Logo'), + 'identicon' => __('Identicon (Generated)'), + 'wavatar' => __('Wavatar (Generated)'), + 'monsterid' => __('MonsterID (Generated)'), + 'retro' => __('Retro (Generated)') +); +$avatar_defaults = apply_filters('avatar_defaults', $avatar_defaults); +$default = get_option('avatar_default'); +if ( empty($default) ) + $default = 'mystery'; +$size = 32; +$avatar_list = ''; +foreach ( $avatar_defaults as $default_key => $default_name ) { + $selected = ($default == $default_key) ? 'checked="checked" ' : ''; + $avatar_list .= "\n\t'; + $avatar_list .= '
    '; +} +echo apply_filters('default_avatar_select', $avatar_list); +?> + +
    + + + + +
    +
    + + diff --git a/src/wp-admin/options-general.php b/src/wp-admin/options-general.php new file mode 100644 index 00000000..57a1b149 --- /dev/null +++ b/src/wp-admin/options-general.php @@ -0,0 +1,355 @@ + + +' . __('The fields on this screen determine some of the basics of your site setup.') . '

    ' . + '

    ' . __('Most themes display the site title at the top of every page, in the title bar of the browser, and as the identifying name for syndicated feeds. The tagline is also displayed by many themes.') . '

    ' . + '

    ' . __('The WordPress URL and the Site URL can be the same (example.com) or different; for example, having the WordPress core files (example.com/wordpress) in a subdirectory instead of the root directory.') . '

    ' . + '

    ' . __('If you want site visitors to be able to register themselves, as opposed to being registered by the site administrator, check the membership box. A default user role can be set for all new users, whether self-registered or registered by the site administrator.') . '

    ' . + '

    ' . __('UTC means Coordinated Universal Time.') . '

    ' . + '

    ' . __('Remember to click the Save Changes button at the bottom of the screen for new settings to take effect.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on General Settings') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include('./admin-header.php'); +?> + +
    + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    class="regular-text code" />
    class="regular-text code" /> +to be different from the directory you installed WordPress.'); ?>
    +
    +
    + +
    +The new address will not become active until confirmed.') ?> + +
    +

    %1$s. Cancel'), $new_admin_email, esc_url( admin_url( 'options.php?dismiss=new_admin_email' ) ) ); ?>

    +
    + +
    + + +UTC time is %s'), date_i18n( $time_format, false, 'gmt')); ?> + + %2$s'), $current_offset_name, date_i18n($time_format)); ?> + +
    + +
    + + + + UTC time is %s'), date_i18n($timezone_format, false, 'gmt')); ?> + + %1$s'), date_i18n($timezone_format)); ?> + +
    + + +
    + + +
    + $right_now ) { + $found = true; + break; + } + } + + if ( $found ) { + echo ' '; + $message = $tr['isdst'] ? + __('Daylight saving time begins on: %s.') : + __('Standard time begins on: %s.'); + // Add the difference between the current offset and the new offset to ts to get the correct transition time from date_i18n(). + printf( $message, date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $tr['ts'] + ($tz_offset - $tr['offset']) ) ); + } else { + _e('This timezone does not observe daylight saving time.'); + } + } + // Set back to UTC. + date_default_timezone_set('UTC'); + ?> +
    + +
    +
    + ' . date_i18n( $format ) . "
    \n"; + } + + echo ' ' . date_i18n( get_option('date_format') ) . " \n"; + + echo "\t

    " . __('Documentation on date and time formatting.') . "

    \n"; +?> +
    +
    +
    + ' . date_i18n( $format ) . "
    \n"; + } + + echo ' ' . date_i18n( get_option('time_format') ) . " \n"; + ; +?> +
    +
    + +
    + + + + +
    + +
    + + diff --git a/src/wp-admin/options-head.php b/src/wp-admin/options-head.php new file mode 100644 index 00000000..7f2cc74d --- /dev/null +++ b/src/wp-admin/options-head.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/src/wp-admin/options-media.php b/src/wp-admin/options-media.php new file mode 100644 index 00000000..67c30ad4 --- /dev/null +++ b/src/wp-admin/options-media.php @@ -0,0 +1,141 @@ +' . __('You can set maximum sizes for images inserted into your written content; you can also insert an image as Full Size.') . '

    ' . + '

    ' . __('The Embed option allows you embed a video, image, or other media content into your content automatically by typing the URL (of the web page where the file lives) on its own line when you create your content.') . '

    ' . + ( is_multisite() ? '' : '

    ' . __('Uploading Options gives you folder and path choices for storing your files in your installation’s directory.') . '

    ' ) . + '

    ' . __('You must click the Save Changes button at the bottom of the screen for new settings to take effect.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Media Settings') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include('./admin-header.php'); + +?> + +
    + +

    + +
    + + +

    +

    + + + + + + + + + + + + + + + + + + +
    + + + +
    +/> + +
    + + + + +
    + + + + +
    + +

    + + + + + + + + + + + + + + +
    + +
    + + + + +' . __("If the width value is left blank, embeds will default to the max width of your theme."); ?> +
    + + +

    + + + + + + + + + + + + + + + + +
    +wp-content/uploads'); ?> +
    + +
    + +
    + + + + + + +
    + +
    + + diff --git a/src/wp-admin/options-permalink.php b/src/wp-admin/options-permalink.php new file mode 100644 index 00000000..e5f9a751 --- /dev/null +++ b/src/wp-admin/options-permalink.php @@ -0,0 +1,260 @@ +' . __('This screen provides some common options for your default permalinks URL structure.') . '

    ' . + '

    ' . __('If you pick an option other than Default, your general URL path with structure tags, terms surrounded by %, will also appear in the custom structure field and your path can be further modified there.') . '

    ' . + '

    ' . __('When you assign multiple categories or tags to a post, only one can show up in the permalink: the lowest numbered category. This applies if your custom structure includes %category% or %tag%.') . '

    ' . + '

    ' . __('Note that permalinks beginning with the category, tag, author or postname structure tags require more advanced server resources. Double-check your hosting details to make sure those are in place or start your permalinks with other structure tags.') . '

    ' . + '

    ' . __('The Optional fields let you customize the “category” and “tag” base names that will appear in archive URLs. For example, the page listing all posts in the “Uncategorized” category could be /topics/uncategorized instead of /category/uncategorized.') . '

    ' . + '

    ' . __('You must click the Save Changes button at the bottom of the screen for new settings to take effect.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Permalinks Settings') . '

    ' . + '

    ' . __('Documentation on Using Permalinks') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +/** + * Display JavaScript on the page. + * + * @package WordPress + * @subpackage Permalink_Settings_Panel + */ +function add_js() { + ?> + +set_permalink_structure( $permalink_structure ); + } + + if ( isset( $_POST['category_base'] ) ) { + $category_base = $_POST['category_base']; + if ( ! empty( $category_base ) ) + $category_base = $blog_prefix . preg_replace('#/+#', '/', '/' . str_replace( '#', '', $category_base ) ); + $wp_rewrite->set_category_base( $category_base ); + } + + if ( isset( $_POST['tag_base'] ) ) { + $tag_base = $_POST['tag_base']; + if ( ! empty( $tag_base ) ) + $tag_base = $blog_prefix . preg_replace('#/+#', '/', '/' . str_replace( '#', '', $tag_base ) ); + $wp_rewrite->set_tag_base( $tag_base ); + } + + create_initial_taxonomies(); +} + +$permalink_structure = get_option('permalink_structure'); +$category_base = get_option('category_base'); +$tag_base = get_option( 'tag_base' ); + +if ( $iis7_permalinks ) { + if ( ( ! file_exists($home_path . 'web.config') && win_is_writable($home_path) ) || win_is_writable($home_path . 'web.config') ) + $writable = true; + else + $writable = false; +} else { + if ( ( ! file_exists($home_path . '.htaccess') && is_writable($home_path) ) || is_writable($home_path . '.htaccess') ) + $writable = true; + else + $writable = false; +} + +if ( $wp_rewrite->using_index_permalinks() ) + $usingpi = true; +else + $usingpi = false; + +$wp_rewrite->flush_rules(); + + +if (isset($_POST['submit'])) : ?> +

    +

    + + +
    + +

    + +
    + + +

    URLs which have question marks and lots of numbers in them, however WordPress offers you the ability to create a custom URL structure for your permalinks and archives. This can improve the aesthetics, usability, and forward-compatibility of your links. A number of tags are available, and here are some examples to get you started.'); ?>

    + + +

    + + + + + + + + + + + + + + + + + + + + + +
    /?p=123
    /archives/123
    + + + + +
    + +

    + +

    URLs here. For example, using topics as your category base would make your category links like http://example.org/topics/uncategorized/. If you leave these blank the defaults will be used.') ?>

    + +

    URLs here. For example, using topics as your category base would make your category links like http://example.org/index.php/topics/uncategorized/. If you leave these blank the defaults will be used.') ?>

    + + + + + + + + + + + + +
    + + + + +
    + + +

    web.config file were writable, we could do this automatically, but it isn’t so this is the url rewrite rule you should have in your web.config file. Click in the field and press CTRL + a to select all. Then insert this rule inside of the /<configuration>/<system.webServer>/<rewrite>/<rules> element in web.config file.') ?>

    +
    + +

    +
    +

    web.config file writable for us to generate rewrite rules automatically, do not forget to revert the permissions after rule has been saved.') ?>

    + +

    writable, we could do this automatically, but it isn’t so this is the url rewrite rule you should have in your web.config file. Create a new file, called web.config in the root directory of your site. Click in the field and press CTRL + a to select all. Then insert this code into the web.config file.') ?>

    +
    + +

    +
    +

    web.config file automatically, do not forget to revert the permissions after the file has been created.') ?>

    + + + +

    .htaccess file were writable, we could do this automatically, but it isn’t so these are the mod_rewrite rules you should have in your .htaccess file. Click in the field and press CTRL + a to select all.') ?>

    +
    + +

    +
    + + + + +
    + + diff --git a/src/wp-admin/options-privacy.php b/src/wp-admin/options-privacy.php new file mode 100644 index 00000000..5f70b9e8 --- /dev/null +++ b/src/wp-admin/options-privacy.php @@ -0,0 +1,58 @@ +' . __('You can choose whether or not your site will be crawled by robots, ping services, and spiders. If you want those services to ignore your site, click the second option here. Note that your privacy is not complete; your site is still visible on the web.') . '

    ' . + '

    ' . __('When this setting is in effect a reminder is shown in the header of these administration screens that says, “Search Engines Blocked,” to remind you that your site is not being crawled.') . '

    ' . + '

    ' . __('You must click the Save Changes button at the bottom of the screen for new settings to take effect.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Privacy Settings') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include('./admin-header.php'); +?> + +
    + +

    + +
    + + + + + + + + +
    + /> +
    + /> + + +
    + + + + +
    + +
    + + diff --git a/src/wp-admin/options-reading.php b/src/wp-admin/options-reading.php new file mode 100644 index 00000000..7c8e1545 --- /dev/null +++ b/src/wp-admin/options-reading.php @@ -0,0 +1,131 @@ + + +' . __('This screen contains the settings that affect the display of your content.') . '

    ' . + '

    ' . sprintf(__('You can choose what’s displayed on the front page of your site. It can be posts in reverse chronological order (classic blog), or a fixed/static page. To set a static home page, you first need to create two Pages. One will become the front page, and the other will be where your posts are displayed.'), 'post-new.php?post_type=page') . '

    ' . + '

    ' . __('You can also control the display of your content in RSS feeds, including the maximum numbers of posts to display, whether to show full text or a summary, and the character set encoding.') . '

    ' . + '

    ' . __('You must click the Save Changes button at the bottom of the screen for new settings to take effect.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Reading Settings') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include( './admin-header.php' ); +?> + +
    + +

    + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    +

    +

    +

    +
      +
    • +
    • +
    + +

    Warning: these pages should not be the same!' ); ?>

    + +
    + +
    +


    +

    +
    +character encoding of your site (UTF-8 is recommended, if you are adventurous there are some other encodings)' ); ?>
    + + + + +
    +
    + diff --git a/src/wp-admin/options-writing.php b/src/wp-admin/options-writing.php new file mode 100644 index 00000000..a2c55dca --- /dev/null +++ b/src/wp-admin/options-writing.php @@ -0,0 +1,172 @@ +' . __('You can submit content in several different ways; this screen holds the settings for all of them. The top section controls the editor within these administration screens, while the rest control external publishing methods. For more information on any of these methods, use the documentation links below.') . '

    ' . + '

    ' . __('You must click the Save Changes button at the bottom of the screen for new settings to take effect.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Writing Settings') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include('./admin-header.php'); +?> + +
    + +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + 0, 'name' => 'default_category', 'orderby' => 'name', 'selected' => get_option('default_category'), 'hierarchical' => true)); +?> +
    + +
    + 0, 'name' => 'default_link_category', 'orderby' => 'name', 'selected' => get_option('default_link_category'), 'hierarchical' => true, 'taxonomy' => 'link_category')); +?> +
    + + +

    +

    +

    +

    +

    + + +

    +

    %s, %s, %s.'), wp_generate_password(8, false), wp_generate_password(8, false), wp_generate_password(8, false)) ?>

    + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    + 0, 'name' => 'default_email_category', 'orderby' => 'name', 'selected' => get_option('default_email_category'), 'hierarchical' => true)); +?> +
    + + +

    +

    + + + + + + + + + + +
    +
    +
    +
    +
    + + +

    + + + +

    + + + + + +

    Update Services because of your site’s privacy settings.'), 'options-privacy.php'); ?>

    + + + + + + + +
    +
    + + diff --git a/src/wp-admin/options.php b/src/wp-admin/options.php new file mode 100644 index 00000000..d802057f --- /dev/null +++ b/src/wp-admin/options.php @@ -0,0 +1,223 @@ + array( 'blogname', 'blogdescription', 'gmt_offset', 'date_format', 'time_format', 'start_of_week', 'timezone_string' ), + 'discussion' => array( 'default_pingback_flag', 'default_ping_status', 'default_comment_status', 'comments_notify', 'moderation_notify', 'comment_moderation', 'require_name_email', 'comment_whitelist', 'comment_max_links', 'moderation_keys', 'blacklist_keys', 'show_avatars', 'avatar_rating', 'avatar_default', 'close_comments_for_old_posts', 'close_comments_days_old', 'thread_comments', 'thread_comments_depth', 'page_comments', 'comments_per_page', 'default_comments_page', 'comment_order', 'comment_registration' ), + 'media' => array( 'thumbnail_size_w', 'thumbnail_size_h', 'thumbnail_crop', 'medium_size_w', 'medium_size_h', 'large_size_w', 'large_size_h', 'image_default_size', 'image_default_align', 'image_default_link_type', 'embed_autourls', 'embed_size_w', 'embed_size_h' ), + 'privacy' => array( 'blog_public' ), + 'reading' => array( 'posts_per_page', 'posts_per_rss', 'rss_use_excerpt', 'blog_charset', 'show_on_front', 'page_on_front', 'page_for_posts' ), + 'writing' => array( 'default_post_edit_rows', 'use_smilies', 'default_category', 'default_email_category', 'use_balanceTags', 'default_link_category', 'default_post_format', 'enable_app', 'enable_xmlrpc' ), + 'options' => array( '' ) ); + +$mail_options = array('mailserver_url', 'mailserver_port', 'mailserver_login', 'mailserver_pass'); +$uploads_options = array('uploads_use_yearmonth_folders', 'upload_path', 'upload_url_path'); + +if ( !is_multisite() ) { + if ( !defined( 'WP_SITEURL' ) ) + $whitelist_options['general'][] = 'siteurl'; + if ( !defined( 'WP_HOME' ) ) + $whitelist_options['general'][] = 'home'; + + $whitelist_options['general'][] = 'admin_email'; + $whitelist_options['general'][] = 'users_can_register'; + $whitelist_options['general'][] = 'default_role'; + + $whitelist_options['writing'] = array_merge($whitelist_options['writing'], $mail_options); + $whitelist_options['writing'][] = 'ping_sites'; + + $whitelist_options['media'] = array_merge($whitelist_options['media'], $uploads_options); +} else { + $whitelist_options['general'][] = 'new_admin_email'; + $whitelist_options['general'][] = 'WPLANG'; + $whitelist_options['general'][] = 'language'; + + if ( apply_filters( 'enable_post_by_email_configuration', true ) ) + $whitelist_options['writing'] = array_merge($whitelist_options['writing'], $mail_options); + + $whitelist_options[ 'misc' ] = array(); +} + +$whitelist_options = apply_filters( 'whitelist_options', $whitelist_options ); + +/* + * If $_GET['action'] == 'update' we are saving settings sent from a settings page + */ +if ( 'update' == $action ) { + if ( 'options' == $option_page && !isset( $_POST['option_page'] ) ) { // This is for back compat and will eventually be removed. + $unregistered = true; + check_admin_referer( 'update-options' ); + } else { + $unregistered = false; + check_admin_referer( $option_page . '-options' ); + } + + if ( !isset( $whitelist_options[ $option_page ] ) ) + wp_die( __( 'Error: options page not found.' ) ); + + if ( 'options' == $option_page ) { + if ( is_multisite() && ! is_super_admin() ) + wp_die( __( 'You do not have sufficient permissions to modify unregistered settings for this site.' ) ); + $options = explode( ',', stripslashes( $_POST[ 'page_options' ] ) ); + } else { + $options = $whitelist_options[ $option_page ]; + } + + // Handle custom date/time formats + if ( 'general' == $option_page ) { + if ( !empty($_POST['date_format']) && isset($_POST['date_format_custom']) && '\c\u\s\t\o\m' == stripslashes( $_POST['date_format'] ) ) + $_POST['date_format'] = $_POST['date_format_custom']; + if ( !empty($_POST['time_format']) && isset($_POST['time_format_custom']) && '\c\u\s\t\o\m' == stripslashes( $_POST['time_format'] ) ) + $_POST['time_format'] = $_POST['time_format_custom']; + // Map UTC+- timezones to gmt_offsets and set timezone_string to empty. + if ( !empty($_POST['timezone_string']) && preg_match('/^UTC[+-]/', $_POST['timezone_string']) ) { + $_POST['gmt_offset'] = $_POST['timezone_string']; + $_POST['gmt_offset'] = preg_replace('/UTC\+?/', '', $_POST['gmt_offset']); + $_POST['timezone_string'] = ''; + } + } + + if ( $options ) { + foreach ( $options as $option ) { + if ( $unregistered ) + _deprecated_argument( 'options.php', '2.7', sprintf( __( 'The %1$s setting is unregistered. Unregistered settings are deprecated. See http://codex.wordpress.org/Settings_API' ), $option, $option_page ) ); + + $option = trim($option); + $value = null; + if ( isset($_POST[$option]) ) + $value = $_POST[$option]; + if ( !is_array($value) ) + $value = trim($value); + $value = stripslashes_deep($value); + update_option($option, $value); + } + } + + /** + * Handle settings errors and return to options page + */ + // If no settings errors were registered add a general 'updated' message. + if ( !count( get_settings_errors() ) ) + add_settings_error('general', 'settings_updated', __('Settings saved.'), 'updated'); + set_transient('settings_errors', get_settings_errors(), 30); + + /** + * Redirect back to the settings page that was submitted + */ + $goback = add_query_arg( 'settings-updated', 'true', wp_get_referer() ); + wp_redirect( $goback ); + exit; +} + +include('./admin-header.php'); ?> + +
    + +

    +
    + + + + +get_results( "SELECT * FROM $wpdb->options ORDER BY option_name" ); + +foreach ( (array) $options as $option ) : + $disabled = false; + if ( $option->option_name == '' ) + continue; + if ( is_serialized( $option->option_value ) ) { + if ( is_serialized_string( $option->option_value ) ) { + // this is a serialized string, so we should display it + $value = maybe_unserialize( $option->option_value ); + $options_to_update[] = $option->option_name; + $class = 'all-options'; + } else { + $value = 'SERIALIZED DATA'; + $disabled = true; + $class = 'all-options disabled'; + } + } else { + $value = $option->option_value; + $options_to_update[] = $option->option_name; + $class = 'all-options'; + } + $name = esc_attr( $option->option_name ); + echo " + + + +"; +endforeach; +?> +
    "; + if ( strpos( $value, "\n" ) !== false ) + echo ""; + else + echo ""; + echo "
    + + + + + +
    +
    + + + diff --git a/src/wp-admin/plugin-editor.php b/src/wp-admin/plugin-editor.php new file mode 100644 index 00000000..7efcecd3 --- /dev/null +++ b/src/wp-admin/plugin-editor.php @@ -0,0 +1,264 @@ + time()) + (array)get_option('recently_activated')); + + wp_redirect(add_query_arg('_wpnonce', wp_create_nonce('edit-plugin-test_' . $file), "plugin-editor.php?file=$file&liveupdate=1&scrollto=$scrollto&networkwide=" . $network_wide)); + exit; + } + wp_redirect( self_admin_url("plugin-editor.php?file=$file&a=te&scrollto=$scrollto") ); + } else { + wp_redirect( self_admin_url("plugin-editor.php?file=$file&scrollto=$scrollto") ); + } + exit; + +break; + +default: + + if ( isset($_GET['liveupdate']) ) { + check_admin_referer('edit-plugin-test_' . $file); + + $error = validate_plugin($file); + if ( is_wp_error($error) ) + wp_die( $error ); + + if ( ( ! empty( $_GET['networkwide'] ) && ! is_plugin_active_for_network($file) ) || ! is_plugin_active($file) ) + activate_plugin($file, "plugin-editor.php?file=$file&phperror=1", ! empty( $_GET['networkwide'] ) ); // we'll override this later if the plugin can be included without fatal error + + wp_redirect( self_admin_url("plugin-editor.php?file=$file&a=te&scrollto=$scrollto") ); + exit; + } + + // List of allowable extensions + $editable_extensions = array('php', 'txt', 'text', 'js', 'css', 'html', 'htm', 'xml', 'inc', 'include'); + $editable_extensions = (array) apply_filters('editable_extensions', $editable_extensions); + + if ( ! is_file($real_file) ) { + wp_die(sprintf('

    %s

    ', __('No such file exists! Double check the name and try again.'))); + } else { + // Get the extension of the file + if ( preg_match('/\.([^.]+)$/', $real_file, $matches) ) { + $ext = strtolower($matches[1]); + // If extension is not in the acceptable list, skip it + if ( !in_array( $ext, $editable_extensions) ) + wp_die(sprintf('

    %s

    ', __('Files of this type are not editable.'))); + } + } + + add_contextual_help($current_screen, + '

    ' . __('You can use the editor to make changes to any of your plugins’ individual PHP files. Be aware that if you make changes, plugins updates will overwrite your customizations.') . '

    ' . + '

    ' . __('Choose a plugin to edit from the menu in the upper right and click the Select button. Click once on any file name to load it in the editor, and make your changes. Don’t forget to save your changes (Update File) when you’re finished.') . '

    ' . + '

    ' . __('The Documentation menu below the editor lists the PHP functions recognized in the plugin file. Clicking Lookup takes you to a web page about that particular function.') . '

    ' . + '

    ' . __('If you want to make changes but don’t want them to be overwritten when the plugin is updated, you may be ready to think about writing your own plugin. For information on how to edit plugins, write your own from scratch, or just better understand their anatomy, check out the links below.') . '

    ' . + ( is_network_admin() ? '

    ' . __('Any edits to files from this screen will be reflected on all sites in the network.') . '

    ' : '' ) . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Editing Plugins') . '

    ' . + '

    ' . __('Documentation on Writing Plugins') . '

    ' . + '

    ' . __('Support Forums') . '

    ' + ); + + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + update_recently_edited(WP_PLUGIN_DIR . '/' . $file); + + $content = file_get_contents( $real_file ); + + if ( '.php' == substr( $real_file, strrpos( $real_file, '.' ) ) ) { + $functions = wp_doc_link_parse( $content ); + + if ( !empty($functions) ) { + $docs_select = ''; + } + } + + $content = esc_textarea( $content ); + ?> + +

    + +

    fatal error.') ?>

    + + + +
    + +
    + +

    + +
    +
    +%s (active)'), $file); + else + echo sprintf(__('Browsing %s (active)'), $file); + } else { + if ( is_writeable($real_file) ) + echo sprintf(__('Editing %s (inactive)'), $file); + else + echo sprintf(__('Browsing %s (inactive)'), $file); + } + ?> +
    +
    +
    + + + +
    +
    +
    +
    + +
    +

    + +
      + + > + +
    +
    +
    + +
    + + + + +
    + +
    + + + +

    Warning: Making changes to active plugins is not recommended. If your changes cause a fatal error, the plugin will be automatically deactivated.'); ?>

    + +

    + "; + submit_button( __( 'Update File and Attempt to Reactivate' ), 'primary', 'submit', false, array( 'tabindex' => '2' ) ); + } else { + submit_button( __( 'Update File' ), 'primary', 'submit', false, array( 'tabindex' => '2' ) ); + } + ?> +

    + +

    the Codex for more information.'); ?>

    + +
    +
    +
    + +get_pagenum(); +$wp_list_table->prepare_items(); +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +$title = __('Install Plugins'); +$parent_file = 'plugins.php'; + +wp_enqueue_style( 'plugin-install' ); +wp_enqueue_script( 'plugin-install' ); +if ( 'plugin-information' != $tab ) + add_thickbox(); + +$body_id = $tab; + +do_action('install_plugins_pre_' . $tab); //Used to override the general interface, Eg, install or plugin information. + +add_contextual_help($current_screen, + '

    ' . sprintf(__('Plugins hook into WordPress to extend its functionality with custom features. Plugins are developed independently from WordPress core by thousands of developers all over the world. All plugins in the official WordPress.org Plugin Directory are compatible with the WordPress GPL v2 license. You can find new plugins to install by searching or browsing the Directory right here in your own Plugins section.'), 'http://wordpress.org/extend/plugins/') . '

    ' . + '

    ' . __('If you know what you’re looking for, Search is your best bet. The Search screen has options to search the WordPress.org Plugin Directory for a particular Term, Author, or Tag. You can also search the directory by selecting a popular tags. Tags in larger type mean more plugins have been labeled with that tag.') . '

    ' . + '

    ' . __('If you just want to get an idea of what’s available, you can browse Featured, Popular, Newest, and Recently Updated plugins by using the links in the upper left of the screen. These sections rotate regularly.') . '

    ' . + '

    ' . __('If you want to install a plugin that you’ve downloaded elsewhere, click Upload in the upper left. You will be prompted to upload the .zip package, and once uploaded, you can activate the new plugin.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Installing Plugins') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +include(ABSPATH . 'wp-admin/admin-header.php'); +?> +
    + +

    + +views(); ?> + +
    + +
    +get_pagenum(); + +$action = $wp_list_table->current_action(); + +$plugin = isset($_REQUEST['plugin']) ? $_REQUEST['plugin'] : ''; +$s = isset($_REQUEST['s']) ? $_REQUEST['s'] : ''; + +// Clean up request URI from temporary args for screen options/paging uri's to work as expected. +$_SERVER['REQUEST_URI'] = remove_query_arg(array('error', 'deleted', 'activate', 'activate-multi', 'deactivate', 'deactivate-multi', '_error_nonce'), $_SERVER['REQUEST_URI']); + +if ( $action ) { + $network_wide = false; + if ( ( isset( $_GET['networkwide'] ) || 'network-activate-selected' == $action ) && is_multisite() && current_user_can( 'manage_network_plugins' ) ) + $network_wide = true; + + switch ( $action ) { + case 'activate': + if ( ! current_user_can('activate_plugins') ) + wp_die(__('You do not have sufficient permissions to activate plugins for this site.')); + + check_admin_referer('activate-plugin_' . $plugin); + + $result = activate_plugin($plugin, self_admin_url('plugins.php?error=true&plugin=' . $plugin), $network_wide); + if ( is_wp_error( $result ) ) { + if ( 'unexpected_output' == $result->get_error_code() ) { + $redirect = self_admin_url('plugins.php?error=true&charsout=' . strlen($result->get_error_data()) . '&plugin=' . $plugin . "&plugin_status=$status&paged=$page&s=$s"); + wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect)); + exit; + } else { + wp_die($result); + } + } + + $recent = (array)get_option('recently_activated'); + if ( isset($recent[ $plugin ]) ) { + unset($recent[ $plugin ]); + update_option('recently_activated', $recent); + } + if ( isset($_GET['from']) && 'import' == $_GET['from'] ) { + wp_redirect( self_admin_url("import.php?import=" . str_replace('-importer', '', dirname($plugin))) ); // overrides the ?error=true one above and redirects to the Imports page, striping the -importer suffix + } else { + wp_redirect( self_admin_url("plugins.php?activate=true&plugin_status=$status&paged=$page&s=$s") ); // overrides the ?error=true one above + } + exit; + break; + case 'activate-selected': + case 'network-activate-selected': + if ( ! current_user_can('activate_plugins') ) + wp_die(__('You do not have sufficient permissions to activate plugins for this site.')); + + check_admin_referer('bulk-plugins'); + + $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array(); + + // Only activate plugins which are not already active. + $check = $network_wide ? 'is_plugin_active_for_network' : 'is_plugin_active'; + foreach ( $plugins as $i => $plugin ) + if ( $check( $plugin ) ) + unset( $plugins[ $i ] ); + + if ( empty($plugins) ) { + wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") ); + exit; + } + + activate_plugins($plugins, self_admin_url('plugins.php?error=true'), $network_wide); + + $recent = (array)get_option('recently_activated'); + foreach ( $plugins as $plugin => $time) + if ( isset($recent[ $plugin ]) ) + unset($recent[ $plugin ]); + + update_option('recently_activated', $recent); + + wp_redirect( self_admin_url("plugins.php?activate-multi=true&plugin_status=$status&paged=$page&s=$s") ); + exit; + break; + case 'update-selected' : + + check_admin_referer( 'bulk-plugins' ); + + if ( isset( $_GET['plugins'] ) ) + $plugins = explode( ',', $_GET['plugins'] ); + elseif ( isset( $_POST['checked'] ) ) + $plugins = (array) $_POST['checked']; + else + $plugins = array(); + + $title = __( 'Update Plugins' ); + $parent_file = 'plugins.php'; + + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + echo '
    '; + screen_icon(); + echo '

    ' . esc_html( $title ) . '

    '; + + + $url = self_admin_url('update.php?action=update-selected&plugins=' . urlencode( join(',', $plugins) )); + $url = wp_nonce_url($url, 'bulk-update-plugins'); + + echo ""; + echo '
    '; + require_once(ABSPATH . 'wp-admin/admin-footer.php'); + exit; + break; + case 'error_scrape': + if ( ! current_user_can('activate_plugins') ) + wp_die(__('You do not have sufficient permissions to activate plugins for this site.')); + + check_admin_referer('plugin-activation-error_' . $plugin); + + $valid = validate_plugin($plugin); + if ( is_wp_error($valid) ) + wp_die($valid); + + if ( ! WP_DEBUG ) { + if ( defined('E_RECOVERABLE_ERROR') ) + error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR); + else + error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING); + } + + @ini_set('display_errors', true); //Ensure that Fatal errors are displayed. + // Go back to "sandbox" scope so we get the same errors as before + function plugin_sandbox_scrape( $plugin ) { + include( WP_PLUGIN_DIR . '/' . $plugin ); + } + plugin_sandbox_scrape( $plugin ); + do_action('activate_' . $plugin); + exit; + break; + case 'deactivate': + if ( ! current_user_can('activate_plugins') ) + wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.')); + + check_admin_referer('deactivate-plugin_' . $plugin); + deactivate_plugins($plugin); + update_option('recently_activated', array($plugin => time()) + (array)get_option('recently_activated')); + if ( headers_sent() ) + echo ""; + else + wp_redirect( self_admin_url("plugins.php?deactivate=true&plugin_status=$status&paged=$page&s=$s") ); + exit; + break; + case 'deactivate-selected': + if ( ! current_user_can('activate_plugins') ) + wp_die(__('You do not have sufficient permissions to deactivate plugins for this site.')); + + check_admin_referer('bulk-plugins'); + + $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array(); + $plugins = array_filter($plugins, 'is_plugin_active'); //Do not deactivate plugins which are already deactivated. + if ( empty($plugins) ) { + wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") ); + exit; + } + + deactivate_plugins($plugins); + + $deactivated = array(); + foreach ( $plugins as $plugin ) + $deactivated[ $plugin ] = time(); + + update_option('recently_activated', $deactivated + (array)get_option('recently_activated')); + wp_redirect( self_admin_url("plugins.php?deactivate-multi=true&plugin_status=$status&paged=$page&s=$s") ); + exit; + break; + case 'delete-selected': + if ( ! current_user_can('delete_plugins') ) + wp_die(__('You do not have sufficient permissions to delete plugins for this site.')); + + check_admin_referer('bulk-plugins'); + + //$_POST = from the plugin form; $_GET = from the FTP details screen. + $plugins = isset( $_REQUEST['checked'] ) ? (array) $_REQUEST['checked'] : array(); + if ( empty( $plugins ) ) { + wp_redirect( self_admin_url("plugins.php?plugin_status=$status&paged=$page&s=$s") ); + exit; + } + + $plugins = array_filter($plugins, 'is_plugin_inactive'); // Do not allow to delete Activated plugins. + if ( empty( $plugins ) ) { + wp_redirect( self_admin_url( "plugins.php?error=true&main=true&plugin_status=$status&paged=$page&s=$s" ) ); + exit; + } + + include(ABSPATH . 'wp-admin/update.php'); + + $parent_file = 'plugins.php'; + + if ( ! isset($_REQUEST['verify-delete']) ) { + wp_enqueue_script('jquery'); + require_once(ABSPATH . 'wp-admin/admin-header.php'); + ?> +
    + $data ) { + $plugin_info[ $plugin_file ] = _get_plugin_data_markup_translate( $plugin_file, $data ); + $plugin_info[ $plugin_file ]['is_uninstallable'] = is_uninstallable_plugin( $plugin ); + if ( ! $plugin_info[ $plugin_file ]['Network'] ) + $have_non_network_plugins = true; + } + } + } + } + screen_icon(); + $plugins_to_delete = count( $plugin_info ); + echo '

    ' . _n( 'Delete Plugin', 'Delete Plugins', $plugins_to_delete ) . '

    '; + ?> + +

    + +

    +
      + ', sprintf( __( '%1$s by %2$s (will also delete its data)' ), esc_html($plugin['Name']), esc_html($plugin['AuthorName']) ), ''; + $data_to_delete = true; + } else { + /* translators: 1: plugin name, 2: plugin author */ + echo '
    • ', sprintf( __('%1$s by %2$s' ), esc_html($plugin['Name']), esc_html($plugin['AuthorName']) ), '
    • '; + } + } + ?> +
    +

    +
    + + + '; + ?> + + +
    +
    + +
    + +

    + +
    + prepare_items(); + +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +wp_enqueue_script('plugin-install'); +add_thickbox(); + +add_screen_option( 'per_page', array('label' => _x( 'Plugins', 'plugins per page (screen options)' )) ); + +add_contextual_help($current_screen, + '

    ' . __('Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.') . '

    ' . + '

    ' . sprintf(__('You can find additional plugins for your site by using the Plugin Browser/Installer functionality or by browsing the WordPress Plugin Directory directly and installing new plugins manually. To manually install a plugin you generally just need to upload the plugin file into your /wp-content/plugins directory. Once a plugin has been installed, you can activate it here.'), 'plugin-install.php', 'http://wordpress.org/extend/plugins/') . '

    ' . + '

    ' . __('Most of the time, plugins play nicely with the core of WordPress and with other plugins. Sometimes, though, a plugin’s code will get in the way of another plugin, causing compatibility issues. If your site starts doing strange things, this may be the problem. Try deactivating all your plugins and re-activating them in various combinations until you isolate which one(s) caused the issue.') . '

    ' . + '

    ' . sprintf( __('If something goes wrong with a plugin and you can’t use WordPress, delete or rename that file in the %s directory and it will be automatically deactivated.'), WP_PLUGIN_DIR) . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Managing Plugins') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +$title = __('Plugins'); +$parent_file = 'plugins.php'; + +require_once(ABSPATH . 'wp-admin/admin-header.php'); + +$invalid = validate_active_plugins(); +if ( !empty($invalid) ) + foreach ( $invalid as $plugin_file => $error ) + echo '

    ' . sprintf(__('The plugin %s has been deactivated due to an error: %s'), esc_html($plugin_file), $error->get_error_message()) . '

    '; +?> + +unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.'), $_GET['charsout']); + else + $errmsg = __('Plugin could not be activated because it triggered a fatal error.'); + ?> +

    + + + +
    + +

    get_error_message() ); ?>

    + +

    deleted.'); ?>

    + + +

    activated.') ?>

    + +

    activated.'); ?>

    + +

    deactivated.') ?>

    + +

    deactivated.'); ?>

    + +

    + + +
    + +

    + +' . __('Search results for “%s”') . '', esc_html( $s ) ); ?> +

    + + + +views(); ?> + +
    + +search_box( __( 'Search Plugins' ), 'plugin' ); ?> + + + + +display(); ?> +
    + +
    + + true ) ) ) ) + $post_type = $_GET['post_type']; +else + wp_die( __('Invalid post type') ); + +if ( 'post' != $post_type ) { + $parent_file = "edit.php?post_type=$post_type"; + $submenu_file = "post-new.php?post_type=$post_type"; +} else { + $parent_file = 'edit.php'; + $submenu_file = 'post-new.php'; +} + +$post_type_object = get_post_type_object($post_type); + +$title = $post_type_object->labels->add_new_item; + +$editing = true; + +if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + +wp_enqueue_script('autosave'); + +// Show post form. +$post = get_default_post_to_edit( $post_type, true ); +$post_ID = $post->ID; +include('edit-form-advanced.php'); +include('./admin-footer.php'); +?> diff --git a/src/wp-admin/post.php b/src/wp-admin/post.php new file mode 100644 index 00000000..0dae46dd --- /dev/null +++ b/src/wp-admin/post.php @@ -0,0 +1,277 @@ +post_type); + if ( $post_type_object ) { + $post_type = $post->post_type; + $current_screen->post_type = $post->post_type; + $current_screen->id = $current_screen->post_type; + } + } +} elseif ( isset($_POST['post_type']) ) { + $post_type_object = get_post_type_object($_POST['post_type']); + if ( $post_type_object ) { + $post_type = $post_type_object->name; + $current_screen->post_type = $post_type; + $current_screen->id = $current_screen->post_type; + } +} + +/** + * Redirect to previous page. + * + * @param int $post_id Optional. Post ID. + */ +function redirect_post($post_id = '') { + if ( isset($_POST['save']) || isset($_POST['publish']) ) { + $status = get_post_status( $post_id ); + + if ( isset( $_POST['publish'] ) ) { + switch ( $status ) { + case 'pending': + $message = 8; + break; + case 'future': + $message = 9; + break; + default: + $message = 6; + } + } else { + $message = 'draft' == $status ? 10 : 1; + } + + $location = add_query_arg( 'message', $message, get_edit_post_link( $post_id, 'url' ) ); + } elseif ( isset($_POST['addmeta']) && $_POST['addmeta'] ) { + $location = add_query_arg( 'message', 2, wp_get_referer() ); + $location = explode('#', $location); + $location = $location[0] . '#postcustom'; + } elseif ( isset($_POST['deletemeta']) && $_POST['deletemeta'] ) { + $location = add_query_arg( 'message', 3, wp_get_referer() ); + $location = explode('#', $location); + $location = $location[0] . '#postcustom'; + } elseif ( 'post-quickpress-save-cont' == $_POST['action'] ) { + $location = "post.php?action=edit&post=$post_id&message=7"; + } else { + $location = add_query_arg( 'message', 4, get_edit_post_link( $post_id, 'url' ) ); + } + + wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) ); + exit; +} + +if ( isset( $_POST['deletepost'] ) ) + $action = 'delete'; +elseif ( isset($_POST['wp-preview']) && 'dopreview' == $_POST['wp-preview'] ) + $action = 'preview'; + +$sendback = wp_get_referer(); +if ( strpos($sendback, 'post.php') !== false || strpos($sendback, 'post-new.php') !== false ) { + $sendback = admin_url('edit.php'); + $sendback .= ( !empty( $post_type ) ) ? '?post_type=' . $post_type : ''; +} else { + $sendback = remove_query_arg( array('trashed', 'untrashed', 'deleted', 'ids'), $sendback ); +} + +switch($action) { +case 'postajaxpost': +case 'post': +case 'post-quickpress-publish': +case 'post-quickpress-save': + check_admin_referer('add-' . $post_type); + + if ( 'post-quickpress-publish' == $action ) + $_POST['publish'] = 'publish'; // tell write_post() to publish + + if ( 'post-quickpress-publish' == $action || 'post-quickpress-save' == $action ) { + $_POST['comment_status'] = get_option('default_comment_status'); + $_POST['ping_status'] = get_option('default_ping_status'); + } + + if ( !empty( $_POST['quickpress_post_ID'] ) ) { + $_POST['post_ID'] = (int) $_POST['quickpress_post_ID']; + $post_id = edit_post(); + } else { + $post_id = 'postajaxpost' == $action ? edit_post() : write_post(); + } + + if ( 0 === strpos( $action, 'post-quickpress' ) ) { + $_POST['post_ID'] = $post_id; + // output the quickpress dashboard widget + require_once(ABSPATH . 'wp-admin/includes/dashboard.php'); + wp_dashboard_quick_press_output(); + exit; + } + + redirect_post($post_id); + exit(); + break; + +case 'edit': + $editing = true; + + if ( empty( $post_id ) ) { + wp_redirect( admin_url('post.php') ); + exit(); + } + + $p = $post_id; + + if ( empty($post->ID) ) + wp_die( __('You attempted to edit an item that doesn’t exist. Perhaps it was deleted?') ); + + if ( !current_user_can($post_type_object->cap->edit_post, $post_id) ) + wp_die( __('You are not allowed to edit this item.') ); + + if ( 'trash' == $post->post_status ) + wp_die( __('You can’t edit this item because it is in the Trash. Please restore it and try again.') ); + + if ( null == $post_type_object ) + wp_die( __('Unknown post type.') ); + + $post_type = $post->post_type; + if ( 'post' == $post_type ) { + $parent_file = "edit.php"; + $submenu_file = "edit.php"; + } else { + if ( isset( $post_type_object ) && $post_type_object->show_in_menu && $post_type_object->show_in_menu !== true ) + $parent_file = $post_type_object->show_in_menu; + else + $parent_file = "edit.php?post_type=$post_type"; + $submenu_file = "edit.php?post_type=$post_type"; + } + + if ( $last = wp_check_post_lock( $post->ID ) ) { + add_action('admin_notices', '_admin_notice_post_locked' ); + } else { + wp_set_post_lock( $post->ID ); + wp_enqueue_script('autosave'); + } + + $title = $post_type_object->labels->edit_item; + $post = get_post_to_edit($post_id); + + if ( post_type_supports($post_type, 'comments') ) { + wp_enqueue_script('admin-comments'); + enqueue_comment_hotkeys_js(); + } + + include('./edit-form-advanced.php'); + + break; + +case 'editattachment': + check_admin_referer('update-attachment_' . $post_id); + + // Don't let these be changed + unset($_POST['guid']); + $_POST['post_type'] = 'attachment'; + + // Update the thumbnail filename + $newmeta = wp_get_attachment_metadata( $post_id, true ); + $newmeta['thumb'] = $_POST['thumb']; + + wp_update_attachment_metadata( $post_id, $newmeta ); + +case 'editpost': + check_admin_referer('update-' . $post_type . '_' . $post_id); + + $post_id = edit_post(); + + redirect_post($post_id); // Send user on their way while we keep working + + exit(); + break; + +case 'trash': + check_admin_referer('trash-' . $post_type . '_' . $post_id); + + $post = & get_post($post_id); + + if ( !current_user_can($post_type_object->cap->delete_post, $post_id) ) + wp_die( __('You are not allowed to move this item to the Trash.') ); + + if ( ! wp_trash_post($post_id) ) + wp_die( __('Error in moving to Trash.') ); + + wp_redirect( add_query_arg( array('trashed' => 1, 'ids' => $post_id), $sendback ) ); + exit(); + break; + +case 'untrash': + check_admin_referer('untrash-' . $post_type . '_' . $post_id); + + if ( !current_user_can($post_type_object->cap->delete_post, $post_id) ) + wp_die( __('You are not allowed to move this item out of the Trash.') ); + + if ( ! wp_untrash_post($post_id) ) + wp_die( __('Error in restoring from Trash.') ); + + wp_redirect( add_query_arg('untrashed', 1, $sendback) ); + exit(); + break; + +case 'delete': + check_admin_referer('delete-' . $post_type . '_' . $post_id); + + if ( !current_user_can($post_type_object->cap->delete_post, $post_id) ) + wp_die( __('You are not allowed to delete this item.') ); + + $force = !EMPTY_TRASH_DAYS; + if ( $post->post_type == 'attachment' ) { + $force = ( $force || !MEDIA_TRASH ); + if ( ! wp_delete_attachment($post_id, $force) ) + wp_die( __('Error in deleting.') ); + } else { + if ( !wp_delete_post($post_id, $force) ) + wp_die( __('Error in deleting.') ); + } + + wp_redirect( add_query_arg('deleted', 1, $sendback) ); + exit(); + break; + +case 'preview': + check_admin_referer( 'autosave', 'autosavenonce' ); + + $url = post_preview(); + + wp_redirect($url); + exit(); + break; + +default: + wp_redirect( admin_url('edit.php') ); + exit(); + break; +} // end switch +include('./admin-footer.php'); +?> diff --git a/src/wp-admin/press-this.php b/src/wp-admin/press-this.php new file mode 100644 index 00000000..1f7b418e --- /dev/null +++ b/src/wp-admin/press-this.php @@ -0,0 +1,646 @@ + $image) { + // see if files exist in content - we don't want to upload non-used selected files. + if ( strpos($_POST['content'], htmlspecialchars($image)) !== false ) { + $desc = isset($_POST['photo_description'][$key]) ? $_POST['photo_description'][$key] : ''; + $upload = media_sideload_image($image, $post_ID, $desc); + + // Replace the POSTED content with correct uploaded ones. Regex contains fix for Magic Quotes + if ( !is_wp_error($upload) ) + $content = preg_replace('/]*)src=\\\?(\"|\')'.preg_quote(htmlspecialchars($image), '/').'\\\?(\2)([^>\/]*)\/*>/is', $upload, $content); + } + } + } + // set the post_content and status + if ( isset( $_POST['publish'] ) && current_user_can( 'publish_posts' ) ) + $quick['post_status'] = 'publish'; + elseif ( isset( $_POST['review'] ) ) + $quick['post_status'] = 'pending'; + else + $quick['post_status'] = 'draft'; + $quick['post_content'] = $content; + // error handling for media_sideload + if ( is_wp_error($upload) ) { + wp_delete_post($post_ID); + wp_die($upload); + } else { + // Post formats + if ( current_theme_supports( 'post-formats' ) && isset( $_POST['post_format'] ) ) { + $post_formats = get_theme_support( 'post-formats' ); + if ( is_array( $post_formats ) ) { + $post_formats = $post_formats[0]; + if ( in_array( $_POST['post_format'], $post_formats ) ) + set_post_format( $post_ID, $_POST['post_format'] ); + elseif ( '0' == $_POST['post_format'] ) + set_post_format( $post_ID, false ); + } + } + + $quick['ID'] = $post_ID; + wp_update_post($quick); + } + return $post_ID; +} + +// For submitted posts. +if ( isset($_REQUEST['action']) && 'post' == $_REQUEST['action'] ) { + check_admin_referer('press-this'); + $post_ID = press_it(); + $posted = $post_ID; +} else { + $post_ID = 0; +} + +// Set Variables +$title = isset( $_GET['t'] ) ? trim( strip_tags( html_entity_decode( stripslashes( $_GET['t'] ) , ENT_QUOTES) ) ) : ''; + +$selection = ''; +if ( !empty($_GET['s']) ) { + $selection = str_replace(''', "'", stripslashes($_GET['s'])); + $selection = trim( htmlspecialchars( html_entity_decode($selection, ENT_QUOTES) ) ); +} + +if ( ! empty($selection) ) { + $selection = preg_replace('/(\r?\n|\r)/', '

    ', $selection); + $selection = '

    ' . str_replace('

    ', '', $selection) . '

    '; +} + +$url = isset($_GET['u']) ? esc_url($_GET['u']) : ''; +$image = isset($_GET['i']) ? $_GET['i'] : ''; + +if ( !empty($_REQUEST['ajax']) ) { + switch ($_REQUEST['ajax']) { + case 'video': ?> + +
    +

    +
    + +

    +
    +
    + + +

    +
    +
    + +
    +
    + +

    + + + <?php echo esc_attr(__('Click to insert.')); ?> + +

    + +

    + + +

    +
    +
    + +
    +
    +

    +
    +
    + +
    +
    + +

    |

    + ]*)src=(\"|\')([^<>\'\"]+)(\2)([^>]*)\/*>/i'; + $content = str_replace(array("\n","\t","\r"), '', $content); + preg_match_all($pattern, $content, $matches); + if ( empty($matches[0]) ) + return ''; + $sources = array(); + foreach ($matches[3] as $src) { + // if no http in url + if (strpos($src, 'http') === false) + // if it doesn't have a relative uri + if ( strpos($src, '../') === false && strpos($src, './') === false && strpos($src, '/') === 0) + $src = 'http://'.str_replace('//','/', $host['host'].'/'.$src); + else + $src = 'http://'.str_replace('//','/', $host['host'].'/'.dirname($host['path']).'/'.$src); + $sources[] = esc_url($src); + } + return "'" . implode("','", $sources) . "'"; + } + $url = wp_kses(urldecode($url), null); + echo 'new Array('.get_images_from_uri($url).')'; + break; + + case 'photo_js': ?> + // gather images and load some default JS + var last = null + var img, img_tag, aspect, w, h, skip, i, strtoappend = ""; + if(photostorage == false) { + var my_src = eval( + jQuery.ajax({ + type: "GET", + url: "", + cache : false, + async : false, + data: "ajax=photo_images&u=", + dataType : "script" + }).responseText + ); + if(my_src.length == 0) { + var my_src = eval( + jQuery.ajax({ + type: "GET", + url: "", + cache : false, + async : false, + data: "ajax=photo_images&u=", + dataType : "script" + }).responseText + ); + if(my_src.length == 0) { + strtoappend = ''; + } + } + } + for (i = 0; i < my_src.length; i++) { + img = new Image(); + img.src = my_src[i]; + img_attr = 'id="img' + i + '"'; + skip = false; + + maybeappend = ''; + + if (img.width && img.height) { + if (img.width >= 30 && img.height >= 30) { + aspect = img.width / img.height; + scale = (aspect > 1) ? (71 / img.width) : (71 / img.height); + + w = img.width; + h = img.height; + + if (scale < 1) { + w = parseInt(img.width * scale); + h = parseInt(img.height * scale); + } + img_attr += ' style="width: ' + w + 'px; height: ' + h + 'px;"'; + strtoappend += maybeappend; + } + } else { + strtoappend += maybeappend; + } + } + + function pick(img, desc) { + if (img) { + if('object' == typeof jQuery('.photolist input') && jQuery('.photolist input').length != 0) length = jQuery('.photolist input').length; + if(length == 0) length = 1; + jQuery('.photolist').append(''); + jQuery('.photolist').append(''); + insert_editor( "\n\n" + encodeURI('

    ' + desc + '

    ')); + } + return false; + } + + function image_selector() { + tb_remove(); + desc = jQuery('#this_photo_description').val(); + src = jQuery('#this_photo').val(); + pick(src, desc); + jQuery('#extra-fields').hide(); + jQuery('#extra-fields').html(''); + return false; + } + jQuery('#extra-fields').html('

    Add Photos ()

    '); + jQuery('#img_container').html(strtoappend); + + + > + + + <?php _e('Press This') ?> + + + + + '370' ) ); + add_action( 'admin_print_footer_scripts', 'wp_tiny_mce_preload_dialogs', 30 ); + } +?> + + + + +
    +
    +
    +
    +

    + + + + + + + + +
    + +
    +
    +

    + 'save' ) ); + if ( current_user_can('publish_posts') ) { + submit_button( __( 'Publish' ), 'primary', 'publish', false ); + } else { + echo '

    '; + submit_button( __( 'Submit for Review' ), 'primary', 'review', false ); + } ?> + +

    + +

    + +

    + +
    +
    + + +
    +

    +

    +
    +
    + + + + + +
    +
      + 'category', 'popular_cats' => $popular_ids ) ) ?> +
    +
    + + cap->assign_terms) ) : ?> +

    + + cap->edit_terms) ) : ?> +
    +

    + + labels->add_new_item ); ?> + +

    +

    + + + + 'category', 'hide_empty' => 0, 'name' => 'newcategory_parent', 'orderby' => 'name', 'hierarchical' => 1, 'show_option_none' => '— ' . $tax->labels->parent_item . ' —', 'tab_index' => 3 ) ); ?> + + + +

    +
    + +
    +
    +
    + +
    +
    +
    +
    +

    +
    +
    +

    + + +

    + + +
    +

    +
    +
    + +
    +
    +
    +
    +
    + +

    | |

    + + +
    +
    + +
    +
    + + + +
    +
      + +
    • + Add: +<?php _e('Insert an Image'); ?> + +
    • +
    • + <?php _e('Embed a Video'); ?> +
    • + +
    • + + + + +
      +
    • + +
    +
    +
    + +
    +
    +
    +
    +
    + + + + diff --git a/src/wp-admin/profile.php b/src/wp-admin/profile.php new file mode 100644 index 00000000..67dde0c0 --- /dev/null +++ b/src/wp-admin/profile.php @@ -0,0 +1,19 @@ + diff --git a/src/wp-admin/revision.php b/src/wp-admin/revision.php new file mode 100644 index 00000000..dd20c127 --- /dev/null +++ b/src/wp-admin/revision.php @@ -0,0 +1,223 @@ +post_parent ) ) + break; + if ( !$post = get_post( $revision->post_parent ) ) + break; + + // Revisions disabled and we're not looking at an autosave + if ( ( ! WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions') ) && !wp_is_post_autosave( $revision ) ) { + $redirect = 'edit.php?post_type=' . $post->post_type; + break; + } + + check_admin_referer( "restore-post_$post->ID|$revision->ID" ); + + wp_restore_post_revision( $revision->ID ); + $redirect = add_query_arg( array( 'message' => 5, 'revision' => $revision->ID ), get_edit_post_link( $post->ID, 'url' ) ); + break; +case 'diff' : + if ( !$left_revision = get_post( $left ) ) + break; + if ( !$right_revision = get_post( $right ) ) + break; + + if ( !current_user_can( 'read_post', $left_revision->ID ) || !current_user_can( 'read_post', $right_revision->ID ) ) + break; + + // If we're comparing a revision to itself, redirect to the 'view' page for that revision or the edit page for that post + if ( $left_revision->ID == $right_revision->ID ) { + $redirect = get_edit_post_link( $left_revision->ID ); + include( './js/revisions-js.php' ); + break; + } + + // Don't allow reverse diffs? + if ( strtotime($right_revision->post_modified_gmt) < strtotime($left_revision->post_modified_gmt) ) { + $redirect = add_query_arg( array( 'left' => $right, 'right' => $left ) ); + break; + } + + if ( $left_revision->ID == $right_revision->post_parent ) // right is a revision of left + $post =& $left_revision; + elseif ( $left_revision->post_parent == $right_revision->ID ) // left is a revision of right + $post =& $right_revision; + elseif ( $left_revision->post_parent == $right_revision->post_parent ) // both are revisions of common parent + $post = get_post( $left_revision->post_parent ); + else + break; // Don't diff two unrelated revisions + + if ( ! WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions') ) { // Revisions disabled + if ( + // we're not looking at an autosave + ( !wp_is_post_autosave( $left_revision ) && !wp_is_post_autosave( $right_revision ) ) + || + // we're not comparing an autosave to the current post + ( $post->ID !== $left_revision->ID && $post->ID !== $right_revision->ID ) + ) { + $redirect = 'edit.php?post_type=' . $post->post_type; + break; + } + } + + if ( + // They're the same + $left_revision->ID == $right_revision->ID + || + // Neither is a revision + ( !wp_get_post_revision( $left_revision->ID ) && !wp_get_post_revision( $right_revision->ID ) ) + ) + break; + + $post_title = '' . get_the_title() . ''; + $h2 = sprintf( __( 'Compare Revisions of “%1$s”' ), $post_title ); + $title = __( 'Revisions' ); + + $left = $left_revision->ID; + $right = $right_revision->ID; + + $redirect = false; + break; +case 'view' : +default : + if ( !$revision = wp_get_post_revision( $revision_id ) ) + break; + if ( !$post = get_post( $revision->post_parent ) ) + break; + + if ( !current_user_can( 'read_post', $revision->ID ) || !current_user_can( 'read_post', $post->ID ) ) + break; + + // Revisions disabled and we're not looking at an autosave + if ( ( ! WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions') ) && !wp_is_post_autosave( $revision ) ) { + $redirect = 'edit.php?post_type=' . $post->post_type; + break; + } + + $post_title = '' . get_the_title() . ''; + $revision_title = wp_post_revision_title( $revision, false ); + $h2 = sprintf( __( 'Revision for “%1$s” created on %2$s' ), $post_title, $revision_title ); + $title = __( 'Revisions' ); + + // Sets up the diff radio buttons + $left = $revision->ID; + $right = $post->ID; + + $redirect = false; + break; +endswitch; + +// Empty post_type means either malformed object found, or no valid parent was found. +if ( !$redirect && empty($post->post_type) ) + $redirect = 'edit.php'; + +if ( !empty($redirect) ) { + wp_redirect( $redirect ); + exit; +} + +// This is so that the correct "Edit" menu item is selected. +if ( !empty($post->post_type) && 'post' != $post->post_type ) + $parent_file = $submenu_file = 'edit.php?post_type=' . $post->post_type; +else + $parent_file = $submenu_file = 'edit.php'; + +require_once( './admin-header.php' ); + +?> + +
    + +

    + + + + + + + + + $field_title ) : + if ( 'diff' == $action ) { + $left_content = apply_filters( "_wp_post_revision_field_$field", $left_revision->$field, $field ); + $right_content = apply_filters( "_wp_post_revision_field_$field", $right_revision->$field, $field ); + if ( !$content = wp_text_diff( $left_content, $right_content ) ) + continue; // There is no difference between left and right + $identical = false; + } else { + add_filter( "_wp_post_revision_field_$field", 'htmlspecialchars' ); + $content = apply_filters( "_wp_post_revision_field_$field", $revision->$field, $field ); + } + ?> + + + + + + + + + + + + +
    + + +

    + +
    + +

    + + 'form-table', 'parent' => true, 'right' => $right, 'left' => $left ); +if ( ! WP_POST_REVISIONS || !post_type_supports($post->post_type, 'revisions') ) + $args['type'] = 'autosave'; + +wp_list_post_revisions( $post, $args ); + +?> + +
    + +El archivo 'wp-config.php' ya existe. Si necesitas reiniciar alguno de los elementos de la configuración de este archivo bórralo primero. Puedes tratar de instalar ahora.

    "); + +// Comprobamos si existe un wp-config.php por encima del directorio raiz pero que no sea parte de otra instalación +if (file_exists(ABSPATH . '../wp-config.php') && ! file_exists(ABSPATH . '../wp-settings.php')) + wp_die("

    El archivo 'wp-config.php' ya existe un nivel por encima de tu instalación de WordPress. Si necesitas reiniciar alguno de los elementos de la configuración de este archivo bórralo primero. Puedes tratar de instalar ahora.

    "); + +if ( version_compare( $required_php_version, phpversion(), '>' ) ) + wp_die( sprintf( /*WP_I18N_OLD_PHP*/'Tu servidor está usando la versión de PHP %1$s pero WordPress requiere al menos la %2$s.'/*/WP_I18N_OLD_PHP*/, phpversion(), $required_php_version ) ); + +if ( !extension_loaded('mysql') && !file_exists(ABSPATH . 'wp-content/db.php') ) + wp_die( /*WP_I18N_OLD_MYSQL*/'Tu instalación de PHP parece que no dispone de la extensión MySQL requerida por WordPress.'/*/WP_I18N_OLD_MYSQL*/ ); + +if (isset($_GET['step'])) + $step = $_GET['step']; +else + $step = 0; + +/** + * Muestra la cabecera de configuración del fichero wp-config.php. + * + * @ignore + * @since 2.3.0 + * @package WordPress + * @subpackage Installer_WP_Config + */ +function display_header() { + header( 'Content-Type: text/html; charset=utf-8' ); +?> + + + + +Archivo de configuración de WordPress + + + + +

    WordPress

    + + +

    Bienvenid@ a WordPress. Antes de empezar necesitamos algo de información de la base de datos. Necesitas conocer la siguiente información antes de seguir.

    +
      +
    1. Nombre de la base de datos
    2. +
    3. Nombre de usuario de la base de datos
    4. +
    5. Contraseña de la base de datos
    6. +
    7. Host de la base de datos
    8. +
    9. Prefijo de tabla (si quieres ejecutar más de un WordPress en una sola base de datos
    10. +
    +

    Si por alguna razón no funciona la creación automática de este archivo no te preocupes. Todo lo que hace es rellenar un fichero de configuración con la información de la base de datos. También puedes simplemente abrir el fichero wp-config-sample.php en un editor de texto, rellenar la información y guardarlo como wp-config.php.

    +

    En la mayoría de las ocasiones esta información te la facilita tu proveedor de alojamiento. Si no tienes esta información tendrás que contactar con ellos antes de poder continuar. Si ya estás listo …

    + +

    ¡Vamos a ello!

    + +
    +

    A continuación deberás introducir los detalles de conexión con tu base de datos. Si no estás seguro de cuales son contacta con tu proveedor de alojamiento.

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    El nombre de la base de datos en la que quieres que se ejecute WP.
    Tu nombre de usuario de MySQL
    …y la contraseña de MySQL.
    Si no funciona localhost tendrás que contactar con tu proveedor de alojamiento para que te diga cual es.
    Si quieres ejecutar varias instalaciones de WordPress en una sola base de datos cambia esto.
    + +

    +
    +ERROR: "Prefijo de tabla" solo puede contener números, letras y guión bajo.'/*/WP_I18N_BAD_PREFIX*/ ); + + // Probamos la conexión con la base de datos. + /**#@+ + * @ignore + */ + define('DB_NAME', $dbname); + define('DB_USER', $uname); + define('DB_PASSWORD', $passwrd); + define('DB_HOST', $dbhost); + /**#@-*/ + + // Fallará si los valores son incorrectos. + require_wp_db(); + if ( !empty($wpdb->error) ) + wp_die($wpdb->error->get_error_message()); + + // Carga o generación de las claves y salts. + $no_api = isset( $_POST['noapi'] ); + require_once( ABSPATH . WPINC . '/plugin.php' ); + require_once( ABSPATH . WPINC . '/l10n.php' ); + require_once( ABSPATH . WPINC . '/pomo/translations.php' ); + if ( ! $no_api ) { + require_once( ABSPATH . WPINC . '/class-http.php' ); + require_once( ABSPATH . WPINC . '/http.php' ); + wp_fix_server_vars(); + /**#@+ + * @ignore + */ + function get_bloginfo() { + return ( ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . str_replace( $_SERVER['PHP_SELF'], '/wp-admin/setup-config.php', '' ) ); + } + /**#@-*/ + $secret_keys = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' ); + } + + if ( $no_api || is_wp_error( $secret_keys ) ) { + $secret_keys = array(); + require_once( ABSPATH . WPINC . '/pluggable.php' ); + for ( $i = 0; $i < 8; $i++ ) { + $secret_keys[] = wp_generate_password( 64, true, true ); + } + } else { + $secret_keys = explode( "\n", wp_remote_retrieve_body( $secret_keys ) ); + foreach ( $secret_keys as $k => $v ) { + $secret_keys[$k] = substr( $v, 28, 64 ); + } + } + $key = 0; + + foreach ($configFile as $line_num => $line) { + switch (substr($line,0,16)) { + case "define('DB_NAME'": + $configFile[$line_num] = str_replace("nombredetubasededatos", $dbname, $line); + break; + case "define('DB_USER'": + $configFile[$line_num] = str_replace("'nombredeusuario'", "'$uname'", $line); + break; + case "define('DB_PASSW": + $configFile[$line_num] = str_replace("'contraseña'", "'$passwrd'", $line); + break; + case "define('DB_HOST'": + $configFile[$line_num] = str_replace("localhost", $dbhost, $line); + break; + case '$table_prefix =': + $configFile[$line_num] = str_replace('wp_', $prefix, $line); + break; + case "define('AUTH_KEY": + case "define('SECURE_A": + case "define('LOGGED_I": + case "define('NONCE_KE": + case "define('AUTH_SAL": + case "define('SECURE_A": + case "define('LOGGED_I": + case "define('NONCE_SA": + $configFile[$line_num] = str_replace('pon aquí tu frase aleatoria', $secret_keys[$key++], $line ); + break; + } + } + if ( ! is_writable(ABSPATH) ) : + display_header(); +?> +

    Lo siento pero no se ha podido escribir en el fichero wp-config.php.

    +

    Puedes crear mahualmente el archivo wp-config.php y pegar dentro el siguiente texto.

    + +

    Una vez hayas hecho esto haz clic en "Iniciar la instalación."

    +

    Iniciar la instalación

    + +

    ¡Todo correcto! Ya has terminado esta parte de la instalación. Ahora WordPress puede comunicarse con tu base de datos. Si estás preparado es momento de …

    + +

    Iniciar la instalación

    + + + diff --git a/src/wp-admin/theme-editor.php b/src/wp-admin/theme-editor.php new file mode 100644 index 00000000..7760d507 --- /dev/null +++ b/src/wp-admin/theme-editor.php @@ -0,0 +1,271 @@ +'.__('You do not have sufficient permissions to edit templates for this site.').'

    '); + +$title = __("Edit Themes"); +$parent_file = 'themes.php'; + +$help = '

    ' . __('You can use the Theme Editor to edit the individual CSS and PHP files which make up your theme.') . '

    '; +$help .= '

    ' . __('Begin by choosing a theme to edit from the dropdown menu and clicking Select. A list then appears of all the template files. Clicking once on any file name causes the file to appear in the large Editor box.') . '

    '; +$help .= '

    ' . __('For PHP files, you can use the Documentation dropdown to select from functions recognized in that file. Lookup takes you to a web page with reference material about that particular function.') . '

    '; +$help .= '

    ' . __('After typing in your edits, click Update File.') . '

    '; +$help .= '

    ' . __('Advice: think very carefully about your site crashing if you are live-editing the theme currently in use.') . '

    '; +$help .= '

    ' . __('Upgrading to a newer version of the same theme will override changes made here. To avoid this, consider creating a child theme instead.') . '

    '; +if ( is_network_admin() ) + $help .= '

    ' . __('Any edits to files from this screen will be reflected on all sites in the network.') . '

    '; +$help .= '

    ' . __('For more information:') . '

    '; +$help .= '

    ' . __('Documentation on Theme Development') . '

    '; +$help .= '

    ' . __('Documentation on Using Themes') . '

    '; +$help .= '

    ' . __('Documentation on Editing Files') . '

    '; +$help .= '

    ' . __('Documentation on Template Tags') . '

    '; +$help .= '

    ' . __('Support Forums') . '

    '; +add_contextual_help($current_screen, $help); + +wp_reset_vars(array('action', 'redirect', 'profile', 'error', 'warning', 'a', 'file', 'theme', 'dir')); + +wp_admin_css( 'theme-editor' ); + +$themes = get_themes(); + +if (empty($theme)) { + $theme = get_current_theme(); +} else { + $theme = stripslashes($theme); +} + +if ( ! isset($themes[$theme]) ) + wp_die(__('The requested theme does not exist.')); + +$allowed_files = array_merge( $themes[$theme]['Stylesheet Files'], $themes[$theme]['Template Files'] ); + +if ( empty( $file ) ) { + if ( false !== array_search( $themes[$theme]['Stylesheet Dir'] . '/style.css', $allowed_files ) ) + $file = $themes[$theme]['Stylesheet Dir'] . '/style.css'; + else + $file = $allowed_files[0]; +} else { + $file = stripslashes($file); + if ( 'theme' == $dir ) { + $file = dirname(dirname($themes[$theme]['Template Dir'])) . $file ; + } else if ( 'style' == $dir) { + $file = dirname(dirname($themes[$theme]['Stylesheet Dir'])) . $file ; + } +} + +validate_file_to_edit($file, $allowed_files); +$scrollto = isset($_REQUEST['scrollto']) ? (int) $_REQUEST['scrollto'] : 0; +$file_show = basename( $file ); + +switch($action) { + +case 'update': + + check_admin_referer('edit-theme_' . $file . $theme); + + $newcontent = stripslashes($_POST['newcontent']); + $theme = urlencode($theme); + if (is_writeable($file)) { + //is_writable() not always reliable, check return value. see comments @ http://uk.php.net/is_writable + $f = fopen($file, 'w+'); + if ($f !== FALSE) { + fwrite($f, $newcontent); + fclose($f); + $location = "theme-editor.php?file=$file&theme=$theme&a=te&scrollto=$scrollto"; + } else { + $location = "theme-editor.php?file=$file&theme=$theme&scrollto=$scrollto"; + } + } else { + $location = "theme-editor.php?file=$file&theme=$theme&scrollto=$scrollto"; + } + + $location = wp_kses_no_null($location); + $strip = array('%0d', '%0a', '%0D', '%0A'); + $location = _deep_replace($strip, $location); + header("Location: $location"); + exit(); + +break; + +default: + + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + update_recently_edited($file); + + if ( !is_file($file) ) + $error = 1; + + $content = ''; + if ( !$error && filesize($file) > 0 ) { + $f = fopen($file, 'r'); + $content = fread($f, filesize($file)); + + if ( '.php' == substr( $file, strrpos( $file, '.' ) ) ) { + $functions = wp_doc_link_parse( $content ); + + $docs_select = ''; + } + + $content = esc_textarea( $content ); + } + + ?> + +

    +($file_show)" : $file_show; + +$is_child_theme = $themes[$theme]['Template'] != $themes[$theme]['Stylesheet']; +?> +
    + +

    + +
    +
    +

    +
    +
    +
    + + + +
    +
    +
    +
    +
    + +

    + +

    + +
      +($template_show)" : "$description"; + $filedesc = ( $template_file == $file ) ? "$description
      ($template_show)
      " : $filedesc; + $template_mapping[ $description ] = array( _get_template_edit_filename($template_file, $template_dir), $filedesc ); + } + ksort( $template_mapping ); + while ( list( $template_sorted_key, list( $template_file, $filedesc ) ) = each( $template_mapping ) ) : + ?> +
    • &theme=&dir=theme">
    • + +
    +

    +
      +($style_show)" : "$description"; + $filedesc = ( $style_file == $file ) ? "$description
      ($style_show)
      " : $filedesc; + $template_mapping[ $description ] = array( _get_template_edit_filename($style_file, $stylesheet_dir), $filedesc ); + } + ksort( $template_mapping ); + while ( list( $template_sorted_key, list( $style_file, $filedesc ) ) = each( $template_mapping ) ) : + ?> +
    • &theme=&dir=style">
    • + +
    + +
    + +
    + +
    + + + + +
    + +
    + + + +
    + + +
    + +

    +

    + + '2' ) ); + else : ?> +

    the Codex for more information.'); ?>

    + +
    +
    +

    ' . __('Oops, no such file exists! Double check the name and try again, merci.') . '

    '; + } +?> +
    +
    + +get_pagenum(); +$wp_list_table->prepare_items(); +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +$title = __('Install Themes'); +$parent_file = 'themes.php'; +if ( !is_network_admin() ) + $submenu_file = 'themes.php'; + +wp_enqueue_style( 'theme-install' ); +wp_enqueue_script( 'theme-install' ); + +add_thickbox(); +wp_enqueue_script( 'theme-preview' ); + +$body_id = $tab; + +do_action('install_themes_pre_' . $tab); //Used to override the general interface, Eg, install or theme information. + +$help = '

    ' . sprintf(__('You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the WordPress.org Theme Directory. These themes are designed and developed by third parties, are available free of charge, and are licensed under the GNU General Public License, version 2, just like WordPress.'), 'http://wordpress.org/extend/themes/') . '

    '; +$help .= '

    ' . __('You can Search for themes by keyword, author, or tag, or can get more specific and search by criteria listed in the feature filter. Alternately, you can browse the themes that are Featured, Newest, or Recently Updated. When you find a theme you like, you can preview it or install it.') . '

    '; +$help .= '

    ' . __('You can Upload a theme manually if you have already downloaded its ZIP archive onto your computer (make sure it is from a trusted and original source). You can also do it the old-fashioned way and copy a downloaded theme’s folder via FTP into your /wp-content/themes directory.') . '

    '; +$help .= '

    ' . __('For more information:') . '

    '; +$help .= '

    ' . __('Documentation on Adding New Themes') . '

    '; +$help .= '

    ' . __('Support Forums') . '

    '; +add_contextual_help($current_screen, $help); + +include(ABSPATH . 'wp-admin/admin-header.php'); +?> +
    + +

    + + + +views(); ?> + +
    + +
    +prepare_items(); + +$title = __('Manage Themes'); +$parent_file = 'themes.php'; + +if ( current_user_can( 'switch_themes' ) ) : + +$help = '

    ' . __('Aside from the default theme included with your WordPress installation, themes are designed and developed by third parties.') . '

    '; +$help .= '

    ' . __('You can see your active theme at the top of the screen. Below are the other themes you have installed that are not currently in use. You can see what your site would look like with one of these themes by clicking the Preview link. To change themes, click the Activate link.') . '

    '; +if ( current_user_can('install_themes') ) + $help .= '

    ' . sprintf(__('If you would like to see more themes to choose from, click on the “Install Themes” tab and you will be able to browse or search for additional themes from the WordPress.org Theme Directory. Themes in the WordPress.org Theme Directory are designed and developed by third parties, and are licensed under the GNU General Public License, version 2, just like WordPress. Oh, and they’re free!'), 'http://wordpress.org/extend/themes/') . '

    '; + +$help .= '

    ' . __('For more information:') . '

    '; +$help .= '

    ' . __('Documentation on Using Themes') . '

    '; +$help .= '

    ' . __('Support Forums') . '

    '; +add_contextual_help($current_screen, $help); + +add_thickbox(); +wp_enqueue_script( 'theme-preview' ); +wp_enqueue_script( 'theme' ); +wp_enqueue_style( 'theme-install' ); + +endif; + +require_once('./admin-header.php'); +?> + + +

    + +

    widgets settings screen to configure them.'), admin_url( 'widgets.php' ) ); ?>

    +

    Visit site' ), home_url( '/' ) ); ?>

    +

    + + +
    +

    + + +

    + +

    +
    +screenshot ) : ?> +<?php _e('Current theme preview'); ?> + +

    title, $ct->version, $ct->author) ; ?>

    +

    description; ?>

    +
    + + {$item[0]}"; + else + $options[] = "{$item[0]}"; + } else if ( current_user_can($item[1]) ) { + if ( file_exists(ABSPATH . 'wp-admin/' . $item[2]) ) { + $options[] = "{$item[0]}"; + } else { + $options[] = "{$item[0]}"; + } + } + } + } + echo implode ( ' | ', $options ); + + if ( $ct->tags ) : ?> +

    tags); ?>

    + +
    + + +
    + +
    +'; + require( './admin-footer.php' ); + exit; +} +?> + +

    + +has_items() ) : ?> + +
    + + + +
    + +
    + +
    +

    + + + + $features ) : + $feature_name = esc_html( $feature_name ); ?> + +
    +
    + +
      + $feature ) : + $feature_name = $feature; + $feature_name = esc_html( $feature_name ); + $feature = esc_attr( $feature ); + ?> +
    1. + features ) ); ?>/> + +
    2. + +
    +
    + + +
    + 'margin-left: 120px' ) ); ?> +   + +
    +
    +
    +
    +
    + +
    + + + +display(); ?> + +
    +
    + + + +

    +

    + + + + + + + + + + "; + } +?> +
    $title$description
    + +
    + + diff --git a/src/wp-admin/tools.php b/src/wp-admin/tools.php new file mode 100644 index 00000000..33078957 --- /dev/null +++ b/src/wp-admin/tools.php @@ -0,0 +1,59 @@ +' . __('Press This is a bookmarklet that makes it easy to blog about something you come across on the web. You can use it to just grab a link, or to post an excerpt. Press This will even allow you to choose from images included on the page and use them in your post. Just drag the Press This link on this screen to your bookmarks bar in your browser, and you’ll be on your way to easier content creation. Clicking on it while on another website opens a popup window with all these options.') . '

    ' . + '

    ' . __('The Use This link for the Categories and Tags Converter will take you to the Import page, where that Converter is one of the plugins you can download. Once installed, the link on this page takes you to a screen where you can choose conversion either way.') . '

    ' . + '

    ' . __('Note: Turbo/Gears is no longer promoted on this screen as it was in previous versions due to the fact that Google has discontinued support for it.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Tools') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +require_once('./admin-header.php'); + +?> +
    + +

    + + +
    +

    +

    + +

    +

    +

    +
    +cap->manage_terms) || current_user_can($tags->cap->manage_terms) ) : ?> +
    +

    +

    Use this to convert categories to tags or tags to categories.'), 'import.php' ); ?>

    +
    + +
    + diff --git a/src/wp-admin/update-core.php b/src/wp-admin/update-core.php new file mode 100644 index 00000000..3671915d --- /dev/null +++ b/src/wp-admin/update-core.php @@ -0,0 +1,492 @@ +locale && 'en_US' == get_locale() ) ? + $update->current : sprintf("%s–%s", $update->current, $update->locale); + $current = false; + if ( !isset($update->response) || 'latest' == $update->response ) + $current = true; + $submit = __('Update Automatically'); + $form_action = 'update-core.php?action=do-core-upgrade'; + $php_version = phpversion(); + $mysql_version = $wpdb->db_version(); + $show_buttons = true; + if ( 'development' == $update->response ) { + $message = __('You are using a development version of WordPress. You can update to the latest nightly build automatically or download the nightly build and install it manually:'); + $download = __('Download nightly build'); + } else { + if ( $current ) { + $message = sprintf(__('You have the latest version of WordPress. You do not need to update. However, if you want to re-install version %s, you can do so automatically or download the package and re-install manually:'), $version_string); + $submit = __('Re-install Automatically'); + $form_action = 'update-core.php?action=do-core-reinstall'; + } else { + $php_compat = version_compare( $php_version, $update->php_version, '>=' ); + $mysql_compat = version_compare( $mysql_version, $update->mysql_version, '>=' ) || file_exists( WP_CONTENT_DIR . '/db.php' ); + if ( !$mysql_compat && !$php_compat ) + $message = sprintf( __('You cannot update because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.'), $update->current, $update->php_version, $update->mysql_version, $php_version, $mysql_version ); + elseif ( !$php_compat ) + $message = sprintf( __('You cannot update because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.'), $update->current, $update->php_version, $php_version ); + elseif ( !$mysql_compat ) + $message = sprintf( __('You cannot update because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.'), $update->current, $update->mysql_version, $mysql_version ); + else + $message = sprintf(__('You can update to WordPress %2$s automatically or download the package and install it manually:'), $update->current, $version_string); + if ( !$mysql_compat || !$php_compat ) + $show_buttons = false; + } + $download = sprintf(__('Download %s'), $version_string); + } + + echo '

    '; + echo $message; + echo '

    '; + echo '
    '; + wp_nonce_field('upgrade-core'); + echo '

    '; + echo ''; + echo ''; + if ( $show_buttons ) { + submit_button( $submit, 'button', 'upgrade', false ); + echo ' ' . $download . ' '; + } + if ( 'en_US' != $update->locale ) + if ( !isset( $update->dismissed ) || !$update->dismissed ) + submit_button( __('Hide this update'), 'button', 'dismiss', false ); + else + submit_button( __('Bring back this update'), 'button', 'undismiss', false ); + echo '

    '; + if ( 'en_US' != $update->locale && ( !isset($wp_local_package) || $wp_local_package != $update->locale ) ) + echo '

    '.__('This localized version contains both the translation and various other localization fixes. You can skip upgrading if you want to keep your current translation.').'

    '; + else if ( 'en_US' == $update->locale && get_locale() != 'en_US' ) { + echo '

    '.sprintf( __('You are about to install WordPress %s in English (US). There is a chance this update will break your translation. You may prefer to wait for the localized version to be released.'), $update->current ).'

    '; + } + echo '
    '; + +} + +function dismissed_updates() { + $dismissed = get_core_updates( array( 'dismissed' => true, 'available' => false ) ); + if ( $dismissed ) { + + $show_text = esc_js(__('Show hidden updates')); + $hide_text = esc_js(__('Hide hidden updates')); + ?> + + '.__('Show hidden updates').'

    '; + echo '
      '; + foreach( (array) $dismissed as $update) { + echo '
    • '; + list_core_update( $update ); + echo '
    • '; + } + echo '
    '; + } +} + +/** + * Display upgrade WordPress for downloading latest or upgrading automatically form. + * + * @since 2.7 + * + * @return null + */ +function core_upgrade_preamble() { + global $upgrade_error; + + $updates = get_core_updates(); +?> +
    + +

    +

    '; + if ( $upgrade_error == 'themes' ) + _e('Please select one or more themes to update.'); + else + _e('Please select one or more plugins to update.'); + echo '

    '; + } + + echo '

    '; + /* translators: %1 date, %2 time. */ + printf( __('Last checked on %1$s at %2$s.'), date_i18n( get_option( 'date_format' ) ), date_i18n( get_option( 'time_format' ) ) ); + echo '   ' . __( 'Check Again' ) . ''; + echo '

    '; + + if ( !isset($updates[0]->response) || 'latest' == $updates[0]->response ) { + echo '

    '; + _e('You have the latest version of WordPress.'); + echo '

    '; + } else { + echo '

    '; + _e('Important: before updating, please back up your database and files. For help with updates, visit the Updating WordPress Codex page.'); + echo '

    '; + + echo '

    '; + _e( 'An updated version of WordPress is available.' ); + echo '

    '; + } + + echo '
      '; + $alternate = true; + foreach( (array) $updates as $update ) { + echo '
    • '; + list_core_update( $update ); + echo '
    • '; + } + echo '
    '; + echo '

    ' . __( 'While your site is being updated, it will be in maintenance mode. As soon as your updates are complete, your site will return to normal.' ) . '

    '; + dismissed_updates(); + + if ( current_user_can( 'update_plugins' ) ) + list_plugin_updates(); + if ( current_user_can( 'update_themes' ) ) + list_theme_updates(); + do_action('core_upgrade_preamble'); + echo ''; +} + +function list_plugin_updates() { + global $wp_version; + + $cur_wp_version = preg_replace('/-.*$/', '', $wp_version); + + require_once(ABSPATH . 'wp-admin/includes/plugin-install.php'); + $plugins = get_plugin_updates(); + if ( empty( $plugins ) ) { + echo '

    ' . __( 'Plugins' ) . '

    '; + echo '

    ' . __( 'Your plugins are all up to date.' ) . '

    '; + return; + } + $form_action = 'update-core.php?action=do-plugin-upgrade'; + + $core_updates = get_core_updates(); + if ( !isset($core_updates[0]->response) || 'latest' == $core_updates[0]->response || 'development' == $core_updates[0]->response || version_compare( $core_updates[0]->current, $cur_wp_version, '=') ) + $core_update_version = false; + else + $core_update_version = $core_updates[0]->current; + ?> +

    +

    +
    + +

    + + + + + + + + + + + + + + + + $plugin_data) { + $info = plugins_api('plugin_information', array('slug' => $plugin_data->update->slug )); + // Get plugin compat for running version of WordPress. + if ( isset($info->tested) && version_compare($info->tested, $cur_wp_version, '>=') ) { + $compat = '
    ' . sprintf(__('Compatibility with WordPress %1$s: 100%% (according to its author)'), $cur_wp_version); + } elseif ( isset($info->compatibility[$cur_wp_version][$plugin_data->update->new_version]) ) { + $compat = $info->compatibility[$cur_wp_version][$plugin_data->update->new_version]; + $compat = '
    ' . sprintf(__('Compatibility with WordPress %1$s: %2$d%% (%3$d "works" votes out of %4$d total)'), $cur_wp_version, $compat[0], $compat[2], $compat[1]); + } else { + $compat = '
    ' . sprintf(__('Compatibility with WordPress %1$s: Unknown'), $cur_wp_version); + } + // Get plugin compat for updated version of WordPress. + if ( $core_update_version ) { + if ( isset($info->compatibility[$core_update_version][$plugin_data->update->new_version]) ) { + $update_compat = $info->compatibility[$core_update_version][$plugin_data->update->new_version]; + $compat .= '
    ' . sprintf(__('Compatibility with WordPress %1$s: %2$d%% (%3$d "works" votes out of %4$d total)'), $core_update_version, $update_compat[0], $update_compat[2], $update_compat[1]); + } else { + $compat .= '
    ' . sprintf(__('Compatibility with WordPress %1$s: Unknown'), $core_update_version); + } + } + // Get the upgrade notice for the new plugin version. + if ( isset($plugin_data->update->upgrade_notice) ) { + $upgrade_notice = '
    ' . strip_tags($plugin_data->update->upgrade_notice); + } else { + $upgrade_notice = ''; + } + echo " + + + + "; + } +?> + +
    {$plugin_data->Name}
    " . sprintf(__('You have version %1$s installed. Update to %2$s.'), $plugin_data->Version, $plugin_data->update->new_version) . $compat . $upgrade_notice . "
    +

    +
    +' . __( 'Themes' ) . ''; + echo '

    ' . __( 'Your themes are all up to date.' ) . '

    '; + return; + } + + $form_action = 'update-core.php?action=do-theme-upgrade'; + +?> +

    +

    +

    Please Note: Any customizations you have made to theme files will be lost. Please consider using child themes for modifications.'), _x('http://codex.wordpress.org/Child_Themes', 'Link used in suggestion to use child themes in GUU') ); ?>

    +
    + +

    + + + + + + + + + + + + + + + + $theme_data) { + $screenshot = $theme_data->{'Theme Root URI'} . '/' . $stylesheet . '/' . $theme_data->Screenshot; + + echo " + + + + "; + } +?> + +
    {$theme_data->Name}" . sprintf(__('You have version %1$s installed. Update to %2$s.'), $theme_data->Version, $theme_data->update['new_version']) . "
    +

    +
    + +
    + +

    +errors->get_error_code() ) { + foreach ( $wp_filesystem->errors->get_error_messages() as $message ) + show_message($message); + echo '
    '; + return; + } + + if ( $reinstall ) + $update->response = 'reinstall'; + + $result = wp_update_core($update, 'show_message'); + + if ( is_wp_error($result) ) { + show_message($result); + if ('up_to_date' != $result->get_error_code() ) + show_message( __('Installation Failed') ); + } else { + show_message( __('WordPress updated successfully') ); + show_message( '' . __('Go to Dashboard') . '' ); + } + echo ''; +} + +function do_dismiss_core_update() { + $version = isset( $_POST['version'] )? $_POST['version'] : false; + $locale = isset( $_POST['locale'] )? $_POST['locale'] : 'en_US'; + $update = find_core_update( $version, $locale ); + if ( !$update ) + return; + dismiss_core_update( $update ); + wp_redirect( wp_nonce_url('update-core.php?action=upgrade-core', 'upgrade-core') ); + exit; +} + +function do_undismiss_core_update() { + $version = isset( $_POST['version'] )? $_POST['version'] : false; + $locale = isset( $_POST['locale'] )? $_POST['locale'] : 'en_US'; + $update = find_core_update( $version, $locale ); + if ( !$update ) + return; + undismiss_core_update( $version, $locale ); + wp_redirect( wp_nonce_url('update-core.php?action=upgrade-core', 'upgrade-core') ); + exit; +} + +function no_update_actions($actions) { + return ''; +} + +$action = isset($_GET['action']) ? $_GET['action'] : 'upgrade-core'; + +$upgrade_error = false; +if ( ( 'do-theme-upgrade' == $action || ( 'do-plugin-upgrade' == $action && ! isset( $_GET['plugins'] ) ) ) + && ! isset( $_POST['checked'] ) ) { + $upgrade_error = $action == 'do-theme-upgrade' ? 'themes' : 'plugins'; + $action = 'upgrade-core'; +} + +$title = __('WordPress Updates'); +$parent_file = 'tools.php'; + +add_contextual_help($current_screen, + '

    ' . __('This screen lets you update to the latest version of WordPress as well as update your themes and plugins from the WordPress.org repository. When updates are available, the number of available updates will appear in a bubble on the left hand menu as a notification. It is very important to keep your WordPress installation up to date for security reasons, so when you see a number appear, make sure you take the time to update, which is an easy process.') . '

    ' . + '

    ' . __('Updating your WordPress installation is a simple one-click procedure; just click on the Update button when it says a new version is available.') . '

    ' . + '

    ' . __('To update themes or plugins from this screen, use the checkboxes to make your selection and click on the appropriate Update button. Check the box at the top of the Themes or Plugins section to select all and update them all at once.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Updating WordPress') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +if ( 'upgrade-core' == $action ) { + + wp_version_check(); + require_once(ABSPATH . 'wp-admin/admin-header.php'); + core_upgrade_preamble(); + +} elseif ( 'do-core-upgrade' == $action || 'do-core-reinstall' == $action ) { + check_admin_referer('upgrade-core'); + + // do the (un)dismiss actions before headers, + // so that they can redirect + if ( isset( $_POST['dismiss'] ) ) + do_dismiss_core_update(); + elseif ( isset( $_POST['undismiss'] ) ) + do_undismiss_core_update(); + + require_once(ABSPATH . 'wp-admin/admin-header.php'); + if ( 'do-core-reinstall' == $action ) + $reinstall = true; + else + $reinstall = false; + + if ( isset( $_POST['upgrade'] ) ) + do_core_upgrade($reinstall); + +} elseif ( 'do-plugin-upgrade' == $action ) { + + if ( ! current_user_can( 'update_plugins' ) ) + wp_die( __( 'You do not have sufficient permissions to update this site.' ) ); + + check_admin_referer('upgrade-core'); + + if ( isset( $_GET['plugins'] ) ) { + $plugins = explode( ',', $_GET['plugins'] ); + } elseif ( isset( $_POST['checked'] ) ) { + $plugins = (array) $_POST['checked']; + } else { + wp_redirect( admin_url('update-core.php') ); + exit; + } + + $url = 'update.php?action=update-selected&plugins=' . urlencode(implode(',', $plugins)); + $url = wp_nonce_url($url, 'bulk-update-plugins'); + + $title = __('Update Plugins'); + + require_once(ABSPATH . 'wp-admin/admin-header.php'); + echo '
    '; + screen_icon('plugins'); + echo '

    ' . esc_html__('Update Plugins') . '

    '; + echo ""; + echo '
    '; + +} elseif ( 'do-theme-upgrade' == $action ) { + + if ( ! current_user_can( 'update_themes' ) ) + wp_die( __( 'You do not have sufficient permissions to update this site.' ) ); + + check_admin_referer('upgrade-core'); + + if ( isset( $_GET['themes'] ) ) { + $themes = explode( ',', $_GET['themes'] ); + } elseif ( isset( $_POST['checked'] ) ) { + $themes = (array) $_POST['checked']; + } else { + wp_redirect( admin_url('update-core.php') ); + exit; + } + + $url = 'update.php?action=update-selected-themes&themes=' . urlencode(implode(',', $themes)); + $url = wp_nonce_url($url, 'bulk-update-themes'); + + $title = __('Update Themes'); + + require_once(ABSPATH . 'wp-admin/admin-header.php'); + echo '
    '; + screen_icon('themes'); + echo '

    ' . esc_html__('Update Themes') . '

    '; + echo ""; + echo '
    '; +} + +include(ABSPATH . 'wp-admin/admin-footer.php'); diff --git a/src/wp-admin/update.php b/src/wp-admin/update.php new file mode 100644 index 00000000..8dd8a89b --- /dev/null +++ b/src/wp-admin/update.php @@ -0,0 +1,254 @@ +bulk_upgrade( $plugins ); + + iframe_footer(); + + } elseif ( 'upgrade-plugin' == $action ) { + if ( ! current_user_can('update_plugins') ) + wp_die(__('You do not have sufficient permissions to update plugins for this site.')); + + check_admin_referer('upgrade-plugin_' . $plugin); + + $title = __('Update Plugin'); + $parent_file = 'plugins.php'; + $submenu_file = 'plugins.php'; + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + $nonce = 'upgrade-plugin_' . $plugin; + $url = 'update.php?action=upgrade-plugin&plugin=' . $plugin; + + $upgrader = new Plugin_Upgrader( new Plugin_Upgrader_Skin( compact('title', 'nonce', 'url', 'plugin') ) ); + $upgrader->upgrade($plugin); + + include(ABSPATH . 'wp-admin/admin-footer.php'); + + } elseif ('activate-plugin' == $action ) { + if ( ! current_user_can('update_plugins') ) + wp_die(__('You do not have sufficient permissions to update plugins for this site.')); + + check_admin_referer('activate-plugin_' . $plugin); + if ( ! isset($_GET['failure']) && ! isset($_GET['success']) ) { + wp_redirect( admin_url('update.php?action=activate-plugin&failure=true&plugin=' . $plugin . '&_wpnonce=' . $_GET['_wpnonce']) ); + activate_plugin( $plugin, '', ! empty( $_GET['networkwide'] ), true ); + wp_redirect( admin_url('update.php?action=activate-plugin&success=true&plugin=' . $plugin . '&_wpnonce=' . $_GET['_wpnonce']) ); + die(); + } + iframe_header( __('Plugin Reactivation'), true ); + if ( isset($_GET['success']) ) + echo '

    ' . __('Plugin reactivated successfully.') . '

    '; + + if ( isset($_GET['failure']) ){ + echo '

    ' . __('Plugin failed to reactivate due to a fatal error.') . '

    '; + + if ( defined('E_RECOVERABLE_ERROR') ) + error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR); + else + error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING); + + @ini_set('display_errors', true); //Ensure that Fatal errors are displayed. + include(WP_PLUGIN_DIR . '/' . $plugin); + } + iframe_footer(); + } elseif ( 'install-plugin' == $action ) { + + if ( ! current_user_can('install_plugins') ) + wp_die(__('You do not have sufficient permissions to install plugins for this site.')); + + include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; //for plugins_api.. + + check_admin_referer('install-plugin_' . $plugin); + $api = plugins_api('plugin_information', array('slug' => $plugin, 'fields' => array('sections' => false) ) ); //Save on a bit of bandwidth. + + if ( is_wp_error($api) ) + wp_die($api); + + $title = __('Plugin Install'); + $parent_file = 'plugins.php'; + $submenu_file = 'plugin-install.php'; + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + $title = sprintf( __('Installing Plugin: %s'), $api->name . ' ' . $api->version ); + $nonce = 'install-plugin_' . $plugin; + $url = 'update.php?action=install-plugin&plugin=' . $plugin; + if ( isset($_GET['from']) ) + $url .= '&from=' . urlencode(stripslashes($_GET['from'])); + + $type = 'web'; //Install plugin type, From Web or an Upload. + + $upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin( compact('title', 'url', 'nonce', 'plugin', 'api') ) ); + $upgrader->install($api->download_link); + + include(ABSPATH . 'wp-admin/admin-footer.php'); + + } elseif ( 'upload-plugin' == $action ) { + + if ( ! current_user_can('install_plugins') ) + wp_die(__('You do not have sufficient permissions to install plugins for this site.')); + + check_admin_referer('plugin-upload'); + + $file_upload = new File_Upload_Upgrader('pluginzip', 'package'); + + $title = __('Upload Plugin'); + $parent_file = 'plugins.php'; + $submenu_file = 'plugin-install.php'; + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + $title = sprintf( __('Installing Plugin from uploaded file: %s'), basename( $file_upload->filename ) ); + $nonce = 'plugin-upload'; + $url = add_query_arg(array('package' => $file_upload->filename ), 'update.php?action=upload-plugin'); + $type = 'upload'; //Install plugin type, From Web or an Upload. + + $upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin( compact('type', 'title', 'nonce', 'url') ) ); + $upgrader->install( $file_upload->package ); + + include(ABSPATH . 'wp-admin/admin-footer.php'); + + } elseif ( 'upgrade-theme' == $action ) { + + if ( ! current_user_can('update_themes') ) + wp_die(__('You do not have sufficient permissions to update themes for this site.')); + + check_admin_referer('upgrade-theme_' . $theme); + + add_thickbox(); + wp_enqueue_script('theme-preview'); + $title = __('Update Theme'); + $parent_file = 'themes.php'; + $submenu_file = 'themes.php'; + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + $nonce = 'upgrade-theme_' . $theme; + $url = 'update.php?action=upgrade-theme&theme=' . $theme; + + $upgrader = new Theme_Upgrader( new Theme_Upgrader_Skin( compact('title', 'nonce', 'url', 'theme') ) ); + $upgrader->upgrade($theme); + + include(ABSPATH . 'wp-admin/admin-footer.php'); + } elseif ( 'update-selected-themes' == $action ) { + if ( ! current_user_can( 'update_themes' ) ) + wp_die( __( 'You do not have sufficient permissions to update themes for this site.' ) ); + + check_admin_referer( 'bulk-update-themes' ); + + if ( isset( $_GET['themes'] ) ) + $themes = explode( ',', stripslashes($_GET['themes']) ); + elseif ( isset( $_POST['checked'] ) ) + $themes = (array) $_POST['checked']; + else + $themes = array(); + + $themes = array_map('urldecode', $themes); + + $url = 'update.php?action=update-selected-themes&themes=' . urlencode(implode(',', $themes)); + $nonce = 'bulk-update-themes'; + + wp_enqueue_script('jquery'); + iframe_header(); + + $upgrader = new Theme_Upgrader( new Bulk_Theme_Upgrader_Skin( compact( 'nonce', 'url' ) ) ); + $upgrader->bulk_upgrade( $themes ); + + iframe_footer(); + } elseif ( 'install-theme' == $action ) { + + if ( ! current_user_can('install_themes') ) + wp_die(__('You do not have sufficient permissions to install themes for this site.')); + + include_once ABSPATH . 'wp-admin/includes/theme-install.php'; //for themes_api.. + + check_admin_referer('install-theme_' . $theme); + $api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false) ) ); //Save on a bit of bandwidth. + + if ( is_wp_error($api) ) + wp_die($api); + + add_thickbox(); + wp_enqueue_script('theme-preview'); + $title = __('Install Themes'); + $parent_file = 'themes.php'; + $submenu_file = 'themes.php'; + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + $title = sprintf( __('Installing Theme: %s'), $api->name . ' ' . $api->version ); + $nonce = 'install-theme_' . $theme; + $url = 'update.php?action=install-theme&theme=' . $theme; + $type = 'web'; //Install theme type, From Web or an Upload. + + $upgrader = new Theme_Upgrader( new Theme_Installer_Skin( compact('title', 'url', 'nonce', 'plugin', 'api') ) ); + $upgrader->install($api->download_link); + + include(ABSPATH . 'wp-admin/admin-footer.php'); + + } elseif ( 'upload-theme' == $action ) { + + if ( ! current_user_can('install_themes') ) + wp_die(__('You do not have sufficient permissions to install themes for this site.')); + + check_admin_referer('theme-upload'); + + $file_upload = new File_Upload_Upgrader('themezip', 'package'); + + $title = __('Upload Theme'); + $parent_file = 'themes.php'; + $submenu_file = 'theme-install.php'; + add_thickbox(); + wp_enqueue_script('theme-preview'); + require_once(ABSPATH . 'wp-admin/admin-header.php'); + + $title = sprintf( __('Installing Theme from uploaded file: %s'), basename( $file_upload->filename ) ); + $nonce = 'theme-upload'; + $url = add_query_arg(array('package' => $file_upload->filename), 'update.php?action=upload-theme'); + $type = 'upload'; //Install plugin type, From Web or an Upload. + + $upgrader = new Theme_Upgrader( new Theme_Installer_Skin( compact('type', 'title', 'nonce', 'url') ) ); + $upgrader->install( $file_upload->package ); + + include(ABSPATH . 'wp-admin/admin-footer.php'); + + } else { + do_action('update-custom_' . $action); + } +} diff --git a/src/wp-admin/upgrade-functions.php b/src/wp-admin/upgrade-functions.php new file mode 100644 index 00000000..ca14a59c --- /dev/null +++ b/src/wp-admin/upgrade-functions.php @@ -0,0 +1,13 @@ + diff --git a/src/wp-admin/upgrade.php b/src/wp-admin/upgrade.php new file mode 100644 index 00000000..794b55b6 --- /dev/null +++ b/src/wp-admin/upgrade.php @@ -0,0 +1,110 @@ +db_version(); +$php_compat = version_compare( $php_version, $required_php_version, '>=' ); +$mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' ) || file_exists( WP_CONTENT_DIR . '/db.php' ); + +@header( 'Content-Type: ' . get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ) ); +?> + +> + + + <?php _e( 'WordPress › Update' ); ?> + + + +

    WordPress

    + + + +

    +

    +

    + +WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.'), $wp_version, $required_php_version, $required_mysql_version, $php_version, $mysql_version ); + elseif ( !$php_compat ) + printf( __('You cannot update because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.'), $wp_version, $required_php_version, $php_version ); + elseif ( !$mysql_compat ) + printf( __('You cannot update because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.'), $wp_version, $required_mysql_version, $mysql_version ); +?> + +

    +

    +

    +

    + +

    +

    +

    + + + + + + diff --git a/src/wp-admin/upload.php b/src/wp-admin/upload.php new file mode 100644 index 00000000..6a1d9b40 --- /dev/null +++ b/src/wp-admin/upload.php @@ -0,0 +1,228 @@ +get_pagenum(); + +// Handle bulk actions +$doaction = $wp_list_table->current_action(); + +if ( $doaction ) { + check_admin_referer('bulk-media'); + + if ( 'delete_all' == $doaction ) { + $post_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_type='attachment' AND post_status = 'trash'" ); + $doaction = 'delete'; + } elseif ( isset( $_REQUEST['media'] ) ) { + $post_ids = $_REQUEST['media']; + } elseif ( isset( $_REQUEST['ids'] ) ) { + $post_ids = explode( ',', $_REQUEST['ids'] ); + } + + $location = 'upload.php'; + if ( $referer = wp_get_referer() ) { + if ( false !== strpos( $referer, 'upload.php' ) ) + $location = remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'message', 'ids', 'posted' ), $referer ); + } + + switch ( $doaction ) { + case 'find_detached': + if ( !current_user_can('edit_posts') ) + wp_die( __('You are not allowed to scan for lost attachments.') ); + + $lost = $wpdb->get_col( " + SELECT ID FROM $wpdb->posts + WHERE post_type = 'attachment' AND post_parent > '0' + AND post_parent NOT IN ( + SELECT ID FROM $wpdb->posts + WHERE post_type NOT IN ( 'attachment', '" . join( "', '", get_post_types( array( 'public' => false ) ) ) . "' ) + ) + " ); + + $_REQUEST['detached'] = 1; + break; + case 'attach': + $parent_id = (int) $_REQUEST['found_post_id']; + if ( !$parent_id ) + return; + + $parent = &get_post( $parent_id ); + if ( !current_user_can( 'edit_post', $parent_id ) ) + wp_die( __( 'You are not allowed to edit this post.' ) ); + + $attach = array(); + foreach ( (array) $_REQUEST['media'] as $att_id ) { + $att_id = (int) $att_id; + + if ( !current_user_can( 'edit_post', $att_id ) ) + continue; + + $attach[] = $att_id; + clean_attachment_cache( $att_id ); + } + + if ( ! empty( $attach ) ) { + $attach = implode( ',', $attach ); + $attached = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $attach )", $parent_id ) ); + } + + if ( isset( $attached ) ) { + $location = 'upload.php'; + if ( $referer = wp_get_referer() ) { + if ( false !== strpos( $referer, 'upload.php' ) ) + $location = $referer; + } + + $location = add_query_arg( array( 'attached' => $attached ) , $location ); + wp_redirect( $location ); + exit; + } + break; + case 'trash': + foreach ( (array) $post_ids as $post_id ) { + if ( !current_user_can( 'delete_post', $post_id ) ) + wp_die( __( 'You are not allowed to move this post to the trash.' ) ); + + if ( !wp_trash_post( $post_id ) ) + wp_die( __( 'Error in moving to trash...' ) ); + } + $location = add_query_arg( array( 'trashed' => count( $post_ids ), 'ids' => join( ',', $post_ids ) ), $location ); + break; + case 'untrash': + foreach ( (array) $post_ids as $post_id ) { + if ( !current_user_can( 'delete_post', $post_id ) ) + wp_die( __( 'You are not allowed to move this post out of the trash.' ) ); + + if ( !wp_untrash_post( $post_id ) ) + wp_die( __( 'Error in restoring from trash...' ) ); + } + $location = add_query_arg( 'untrashed', count( $post_ids ), $location ); + break; + case 'delete': + foreach ( (array) $post_ids as $post_id_del ) { + if ( !current_user_can( 'delete_post', $post_id_del ) ) + wp_die( __( 'You are not allowed to delete this post.' ) ); + + if ( !wp_delete_attachment( $post_id_del ) ) + wp_die( __( 'Error in deleting...' ) ); + } + $location = add_query_arg( 'deleted', count( $post_ids ), $location ); + break; + } + + wp_redirect( $location ); + exit; +} elseif ( ! empty( $_GET['_wp_http_referer'] ) ) { + wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) ); + exit; +} + +$wp_list_table->prepare_items(); + +$total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); +if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; +} + +$title = __('Media Library'); +$parent_file = 'upload.php'; + +wp_enqueue_script( 'wp-ajax-response' ); +wp_enqueue_script( 'jquery-ui-draggable' ); +wp_enqueue_script( 'media' ); + +add_screen_option( 'per_page', array('label' => _x( 'Media items', 'items per page (screen options)' )) ); + +add_contextual_help( $current_screen, + '

    ' . __( 'All the files you’ve uploaded are listed in the Media Library, with the most recent uploads listed first. You can use the Screen Options tab to customize the display of this screen.' ) . '

    ' . + '

    ' . __( 'You can narrow the list by file type/status using the text link filters at the top of the screen. You also can refine the list by date using the dropdown menu above the media table.' ) . '

    ' . + '

    ' . __( 'Hovering over a row reveals action links: Edit, Delete Permanently, and View. Clicking Edit or on the media file’s name displays a simple screen to edit that individual file’s metadata. Clicking Delete Permanently will delete the file from the media library (as well as from any posts to which it is currently attached). View will take you to the display page for that file.' ) . '

    ' . + '

    ' . __( 'If a media file has not been attached to any post, you will see that in the Attached To column, and can click on Attach File to launch a small popup that will allow you to search for a post and attach the file.' ) . '

    ' . + '

    ' . __( 'For more information:' ) . '

    ' . + '

    ' . __( 'Documentation on Media Library' ) . '

    ' . + '

    ' . __( 'Support Forums' ) . '

    ' +); + +require_once('./admin-header.php'); +?> + +
    + +

    ' . __('Search results for “%s”') . '', get_search_query() ); ?> +

    + +' . __('Undo') . ''; + $_SERVER['REQUEST_URI'] = remove_query_arg(array('trashed'), $_SERVER['REQUEST_URI']); +} + +if ( isset($_GET['untrashed']) && (int) $_GET['untrashed'] ) { + $message = sprintf( _n( 'Media attachment restored from the trash.', '%d media attachments restored from the trash.', $_GET['untrashed'] ), number_format_i18n( $_GET['untrashed'] ) ); + $_SERVER['REQUEST_URI'] = remove_query_arg(array('untrashed'), $_SERVER['REQUEST_URI']); +} + +$messages[1] = __('Media attachment updated.'); +$messages[2] = __('Media permanently deleted.'); +$messages[3] = __('Error saving media attachment.'); +$messages[4] = __('Media moved to the trash.') . ' ' . __('Undo') . ''; +$messages[5] = __('Media restored from the trash.'); + +if ( isset($_GET['message']) && (int) $_GET['message'] ) { + $message = $messages[$_GET['message']]; + $_SERVER['REQUEST_URI'] = remove_query_arg(array('message'), $_SERVER['REQUEST_URI']); +} + +if ( !empty($message) ) { ?> +

    + + +views(); ?> + +
    + +search_box( __( 'Search Media' ), 'media' ); ?> + +display(); ?> + +
    + +
    + +
    +
    + +ID ) ); + +if ( ! $user_id && IS_PROFILE_PAGE ) + $user_id = $current_user->ID; +elseif ( ! $user_id && ! IS_PROFILE_PAGE ) + wp_die(__( 'Invalid user ID.' ) ); +elseif ( ! get_userdata( $user_id ) ) + wp_die( __('Invalid user ID.') ); + +wp_enqueue_script('user-profile'); + +$title = IS_PROFILE_PAGE ? __('Profile') : __('Edit User'); +if ( current_user_can('edit_users') && !IS_PROFILE_PAGE ) + $submenu_file = 'users.php'; +else + $submenu_file = 'profile.php'; + +if ( current_user_can('edit_users') && !is_user_admin() ) + $parent_file = 'users.php'; +else + $parent_file = 'profile.php'; + +// contextual help - choose Help on the top right of admin panel to preview this. +add_contextual_help($current_screen, + '

    ' . __('Your profile contains information about you (your “account”) as well as some personal options related to using WordPress.') . '

    ' . + '

    ' . __('You can change your password, turn on keyboard shortcuts, change the color scheme of your WordPress administration screens, and turn off the WYSIWYG (Visual) editor, among other things.') . '

    ' . + '

    ' . __('Your username cannot be changed, but you can use other fields to enter your real name or a nickname, and change which name to display on your posts.') . '

    ' . + '

    ' . __('Required fields are indicated; the rest are optional. Profile information will only be displayed if your theme is set up to do so.') . '

    ' . + '

    ' . __('Remember to click the Update Profile button when you are finished.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on User Profiles') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + + +$wp_http_referer = remove_query_arg(array('update', 'delete_count'), stripslashes($wp_http_referer)); + +$all_post_caps = array('posts', 'pages'); +$user_can_edit = false; +foreach ( $all_post_caps as $post_cap ) + $user_can_edit |= current_user_can("edit_$post_cap"); + +/** + * Optional SSL preference that can be turned on by hooking to the 'personal_options' action. + * + * @since 2.7.0 + * + * @param object $user User data object + */ +function use_ssl_preference($user) { +?> + + + + +ID && ! apply_filters( 'enable_edit_any_user_configuration', true ) ) + wp_die( __( 'You do not have permission to edit this user.' ) ); + +// Execute confirmed email change. See send_confirmation_on_profile_email(). +if ( is_multisite() && IS_PROFILE_PAGE && isset( $_GET[ 'newuseremail' ] ) && $current_user->ID ) { + $new_email = get_option( $current_user->ID . '_new_email' ); + if ( $new_email[ 'hash' ] == $_GET[ 'newuseremail' ] ) { + $user->ID = $current_user->ID; + $user->user_email = esc_html( trim( $new_email[ 'newemail' ] ) ); + if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", $current_user->user_login ) ) ) + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, $current_user->user_login ) ); + wp_update_user( get_object_vars( $user ) ); + delete_option( $current_user->ID . '_new_email' ); + wp_redirect( add_query_arg( array('updated' => 'true'), self_admin_url( 'profile.php' ) ) ); + die(); + } +} elseif ( is_multisite() && IS_PROFILE_PAGE && !empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' == $_GET['dismiss'] ) { + delete_option( $current_user->ID . '_new_email' ); + wp_redirect( add_query_arg( array('updated' => 'true'), self_admin_url( 'profile.php' ) ) ); + die(); +} + +switch ($action) { +case 'update': + +check_admin_referer('update-user_' . $user_id); + +if ( !current_user_can('edit_user', $user_id) ) + wp_die(__('You do not have permission to edit this user.')); + +if ( IS_PROFILE_PAGE ) + do_action('personal_options_update', $user_id); +else + do_action('edit_user_profile_update', $user_id); + +if ( !is_multisite() ) { + $errors = edit_user($user_id); +} else { + $user = get_userdata( $user_id ); + + // Update the email address in signups, if present. + if ( $user->user_login && isset( $_POST[ 'email' ] ) && is_email( $_POST[ 'email' ] ) && $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", $user->user_login ) ) ) + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $_POST[ 'email' ], $user_login ) ); + + // WPMU must delete the user from the current blog if WP added him after editing. + $delete_role = false; + $blog_prefix = $wpdb->get_blog_prefix(); + if ( $user_id != $current_user->ID ) { + $cap = $wpdb->get_var( "SELECT meta_value FROM {$wpdb->usermeta} WHERE user_id = '{$user_id}' AND meta_key = '{$blog_prefix}capabilities' AND meta_value = 'a:0:{}'" ); + if ( !is_network_admin() && null == $cap && $_POST[ 'role' ] == '' ) { + $_POST[ 'role' ] = 'contributor'; + $delete_role = true; + } + } + if ( !isset( $errors ) || ( isset( $errors ) && is_object( $errors ) && false == $errors->get_error_codes() ) ) + $errors = edit_user($user_id); + if ( $delete_role ) // stops users being added to current blog when they are edited + delete_user_meta( $user_id, $blog_prefix . 'capabilities' ); + + if ( is_multisite() && is_network_admin() && !IS_PROFILE_PAGE && current_user_can( 'manage_network_options' ) && !isset($super_admins) && empty( $_POST['super_admin'] ) == is_super_admin( $user_id ) ) + empty( $_POST['super_admin'] ) ? revoke_super_admin( $user_id ) : grant_super_admin( $user_id ); +} + +if ( !is_wp_error( $errors ) ) { + $redirect = (IS_PROFILE_PAGE ? "profile.php?" : "user-edit.php?user_id=$user_id&"). "updated=true"; + if ( $wp_http_referer ) + $redirect = add_query_arg('wp_http_referer', urlencode($wp_http_referer), $redirect); + wp_redirect($redirect); + exit; +} + +default: +$profileuser = get_user_to_edit($user_id); + +if ( !current_user_can('edit_user', $user_id) ) + wp_die(__('You do not have permission to edit this user.')); + +include (ABSPATH . 'wp-admin/admin-header.php'); +?> + +ID ) && current_user_can( 'manage_network_options' ) ) { ?> +

    + + +
    +

    + +

    + +
    + + +

    \n

    ", $errors->get_error_messages() ); ?>

    + + +
    + +

    + +
    > + + + + +

    + + +

    + +

    + + + + + + + + + 1 && has_action('admin_color_scheme_picker') ) : ?> + + + + + + + + + + + + + + + +
    More information'); ?>
    +
    + +
    + + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +user_email != get_site_option( 'admin_email' ) ) : ?> +

    + +

    + +
    + +
    + +

    + + + + + + + + + + + + + $desc) { +?> + + + + + +
    + ID . '_new_email' ); + if ( $new_email && $new_email != $current_user->user_email ) : ?> +
    +

    %1$s. Cancel'), $new_email['newemail'], esc_url( self_admin_url( 'profile.php?dismiss=' . $current_user->ID . '_new_email' ) ) ); ?>

    +
    + +
    + +

    + + + + + + + + + + + + + +

    +

    +
    +
    +

    +
    + + + +caps) > count($profileuser->roles) && apply_filters('additional_capabilities_display', true, $profileuser) ) { ?> +
    + + + + + +
    caps as $cap => $value ) { + if ( !$wp_roles->is_role($cap) ) { + if ( $output != '' ) + $output .= ', '; + $output .= $value ? $cap : "Denied: {$cap}"; + } + } + echo $output; + ?>
    + + + + + + + +
    +
    + + + diff --git a/src/wp-admin/user-new.php b/src/wp-admin/user-new.php new file mode 100644 index 00000000..b9d87256 --- /dev/null +++ b/src/wp-admin/user-new.php @@ -0,0 +1,350 @@ + 'enter_email'), 'user-new.php' ) ); + die(); + } + } + + if ( !$user_details ) { + wp_redirect( add_query_arg( array('update' => 'does_not_exist'), 'user-new.php' ) ); + die(); + } + + if ( ! current_user_can('promote_user', $user_details->ID) ) + wp_die(__('Cheatin’ uh?')); + + // Adding an existing user to this blog + $new_user_email = esc_html(trim($_REQUEST['email'])); + $redirect = 'user-new.php'; + $username = $user_details->user_login; + $user_id = $user_details->ID; + if ( ( $username != null && !is_super_admin( $user_id ) ) && ( array_key_exists($blog_id, get_blogs_of_user($user_id)) ) ) { + $redirect = add_query_arg( array('update' => 'addexisting'), 'user-new.php' ); + } else { + if ( isset( $_POST[ 'noconfirmation' ] ) && is_super_admin() ) { + add_existing_user_to_blog( array( 'user_id' => $user_id, 'role' => $_REQUEST[ 'role' ] ) ); + $redirect = add_query_arg( array('update' => 'addnoconfirmation'), 'user-new.php' ); + } else { + $newuser_key = substr( md5( $user_id ), 0, 5 ); + add_option( 'new_user_' . $newuser_key, array( 'user_id' => $user_id, 'email' => $user_details->user_email, 'role' => $_REQUEST[ 'role' ] ) ); + $message = __("Hi,\n\nYou have been invited to join '%s' at\n%s as a %s.\nPlease click the following link to confirm the invite:\n%s\n"); + wp_mail( $new_user_email, sprintf( __( '[%s] Joining confirmation' ), get_option( 'blogname' ) ), sprintf($message, get_option('blogname'), site_url(), $_REQUEST[ 'role' ], site_url("/newbloguser/$newuser_key/"))); + $redirect = add_query_arg( array('update' => 'add'), 'user-new.php' ); + } + } + wp_redirect( $redirect ); + die(); +} elseif ( isset($_REQUEST['action']) && 'createuser' == $_REQUEST['action'] ) { + check_admin_referer( 'create-user', '_wpnonce_create-user' ); + + if ( ! current_user_can('create_users') ) + wp_die(__('Cheatin’ uh?')); + + if ( !is_multisite() ) { + $user_id = add_user(); + + if ( is_wp_error( $user_id ) ) { + $add_user_errors = $user_id; + } else { + if ( current_user_can('edit_users') ) { + $new_user_login = apply_filters('pre_user_login', sanitize_user(stripslashes($_REQUEST['user_login']), true)); + $redirect = 'users.php?usersearch='. urlencode($new_user_login) . '&update=add' . '#user-' . $user_id; + } else { + $redirect = add_query_arg( 'update', 'add', 'user-new.php' ); + } + wp_redirect( $redirect ); + die(); + } + } else { + // Adding a new user to this blog + $user_details = wpmu_validate_user_signup( $_REQUEST[ 'user_login' ], $_REQUEST[ 'email' ] ); + unset( $user_details[ 'errors' ]->errors[ 'user_email_used' ] ); + if ( is_wp_error( $user_details[ 'errors' ] ) && !empty( $user_details[ 'errors' ]->errors ) ) { + $add_user_errors = $user_details[ 'errors' ]; + } else { + $new_user_login = apply_filters('pre_user_login', sanitize_user(stripslashes($_REQUEST['user_login']), true)); + if ( isset( $_POST[ 'noconfirmation' ] ) && is_super_admin() ) { + add_filter( 'wpmu_signup_user_notification', '__return_false' ); // Disable confirmation email + } + wpmu_signup_user( $new_user_login, $_REQUEST[ 'email' ], array( 'add_to_blog' => $wpdb->blogid, 'new_role' => $_REQUEST[ 'role' ] ) ); + if ( isset( $_POST[ 'noconfirmation' ] ) && is_super_admin() ) { + $key = $wpdb->get_var( $wpdb->prepare( "SELECT activation_key FROM {$wpdb->signups} WHERE user_login = %s AND user_email = %s", $new_user_login, $_REQUEST[ 'email' ] ) ); + wpmu_activate_signup( $key ); + $redirect = add_query_arg( array('update' => 'addnoconfirmation'), 'user-new.php' ); + } else { + $redirect = add_query_arg( array('update' => 'newuserconfimation'), 'user-new.php' ); + } + wp_redirect( $redirect ); + die(); + } + } +} + + +$title = __('Add New User'); +$parent_file = 'users.php'; + +$do_both = false; +if ( is_multisite() && current_user_can('promote_users') && current_user_can('create_users') ) + $do_both = true; + +add_contextual_help($current_screen, + '

    ' . __('To add a new user to your site, fill in the form on this screen. If you’re not sure which role to assign, you can use the link below to review the different roles and their capabilities. Here is a basic overview of roles:') . '

    ' . + '
      ' . + '
    • ' . __('Administrators have access to all the administration features.') . '
    • ' . + '
    • ' . __('Editors can publish posts, manage posts as well as manage other people’s posts, etc.') . '
    • ' . + '
    • ' . __('Authors can publish and manage their own posts.') . '
    • ' . + '
    • ' . __('Contributors can write and manage their posts but not publish posts or upload media files.') . '
    • ' . + '
    • ' . __('Subscribers can read comments/comment/receive newsletters, etc.') . '
    • ' . + '
    ' . + '

    ' . __('You must assign a password to the new user, but don’t worry; when they log in for the first time they will be prompted to change it. The username, however, cannot be changed.') . '

    ' . + '

    ' . __('New users will receive an email letting them know they’ve been added as a user for your site. By default, this email will also contain their password. Uncheck the box if you don’t want the password to be included in the welcome email.') . '

    ' . + '

    ' . __('Remember to click the Add User button at the bottom of this screen when you are finished.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Adding New Users') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +wp_enqueue_script('wp-ajax-response'); +wp_enqueue_script('user-profile'); + +require_once ('admin-header.php'); + +if ( isset($_GET['update']) ) { + $messages = array(); + if ( is_multisite() ) { + switch ( $_GET['update'] ) { + case "newuserconfimation": + $messages[] = __('Invitation email sent to new user. A confirmation link must be clicked before their account is created.'); + break; + case "add": + $messages[] = __('Invitation email sent to user. A confirmation link must be clicked for them to be added to your site.'); + break; + case "addnoconfirmation": + $messages[] = __('User has been added to your site.'); + break; + case "addexisting": + $messages[] = __('That user is already a member of this site.'); + break; + case "does_not_exist": + $messages[] = __('The requested user does not exist.'); + break; + case "does_not_exist": + $messages[] = __('Please enter a valid email address.'); + break; + } + } else { + if ( 'add' == $_GET['update'] ) + $messages[] = __('User added.'); + } +} +?> +
    + +

    +

    + + +
    +
      + get_error_messages() as $err ) + echo "
    • $err
    • \n"; + ?> +
    +
    +

    ' . $msg . '

    '; +} ?> + + +
    + get_error_messages() as $message ) + echo "

    $message

    "; + ?> +
    + +
    + +' . __('Add Existing User') . ''; + if ( !is_super_admin() ) { + _e( 'Enter the email address of an existing user on this network to invite them to this site. That person will be sent an email asking them to confirm the invite.' ); + $label = __('E-mail'); + } else { + _e( 'Enter the email address or username of an existing user on this network to invite them to this site. That person will be sent an email asking them to confirm the invite.' ); + $label = __('E-mail or Username'); + } +?> +
    > + + + + + + + + + + + + + + + + + + +
    +
    + 'addusersub' ) ); ?> +
    +' . __( 'Add New User' ) . ''; +?> +

    +
    > + + + 'login', 'first_name' => 'firstname', 'last_name' => 'lastname', + 'email' => 'email', 'url' => 'uri', 'role' => 'role', 'send_password' => 'send_password', 'noconfirmation' => 'ignore_pass' ) as $post_field => $var ) { + $var = "new_user_$var"; + if( isset( $_POST['createuser'] ) ) { + if ( ! isset($$var) ) + $$var = isset( $_POST[$post_field] ) ? stripslashes( $_POST[$post_field] ) : ''; + } else { + $$var = false; + } +} + +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    +

    +
    +
    + + 'createusersub' ) ); ?> + +
    + + + diff --git a/src/wp-admin/user/admin.php b/src/wp-admin/user/admin.php new file mode 100644 index 00000000..42850f4b --- /dev/null +++ b/src/wp-admin/user/admin.php @@ -0,0 +1,23 @@ +domain != $current_site->domain ) || ( $current_blog->path != $current_site->path ) ) { + wp_redirect( user_admin_url() ); + exit; +} +?> diff --git a/src/wp-admin/user/index-extra.php b/src/wp-admin/user/index-extra.php new file mode 100644 index 00000000..48812635 --- /dev/null +++ b/src/wp-admin/user/index-extra.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/src/wp-admin/user/profile.php b/src/wp-admin/user/profile.php new file mode 100644 index 00000000..4857a508 --- /dev/null +++ b/src/wp-admin/user/profile.php @@ -0,0 +1,12 @@ +get_pagenum(); +$title = __('Users'); +$parent_file = 'users.php'; + +add_screen_option( 'per_page', array('label' => _x( 'Users', 'users per page (screen options)' )) ); + +// contextual help - choose Help on the top right of admin panel to preview this. +add_contextual_help($current_screen, + '

    ' . __('This screen lists all the existing users for your site. Each user has one of five defined roles as set by the site admin: Site Administrator, Editor, Author, Contributor, or Subscriber. Users with roles other than Administrator will see fewer options in the dashboard navigation when they are logged in, based on their role.') . '

    ' . + '

    ' . __('You can customize the display of information on this screen as you can on other screens, by using the Screen Options tab and the on-screen filters.') . '

    ' . + '

    ' . __('To add a new user for your site, click the Add New button at the top of the screen or Add New in the Users menu section.') . '

    ' . + '

    ' . __('For more information:') . '

    ' . + '

    ' . __('Documentation on Managing Users') . '

    ' . + '

    ' . __('Descriptions of Roles and Capabilities') . '

    ' . + '

    ' . __('Support Forums') . '

    ' +); + +if ( empty($_REQUEST) ) { + $referer = ''; +} elseif ( isset($_REQUEST['wp_http_referer']) ) { + $redirect = remove_query_arg(array('wp_http_referer', 'updated', 'delete_count'), stripslashes($_REQUEST['wp_http_referer'])); + $referer = ''; +} else { + $redirect = 'users.php'; + $referer = ''; +} + +$update = ''; + +switch ( $wp_list_table->current_action() ) { + +/* Bulk Dropdown menu Role changes */ +case 'promote': + check_admin_referer('bulk-users'); + + if ( ! current_user_can( 'promote_users' ) ) + wp_die( __( 'You can’t edit that user.' ) ); + + if ( empty($_REQUEST['users']) ) { + wp_redirect($redirect); + exit(); + } + + $editable_roles = get_editable_roles(); + if ( empty( $editable_roles[$_REQUEST['new_role']] ) ) + wp_die(__('You can’t give users that role.')); + + $userids = $_REQUEST['users']; + $update = 'promote'; + foreach ( $userids as $id ) { + $id = (int) $id; + + if ( ! current_user_can('promote_user', $id) ) + wp_die(__('You can’t edit that user.')); + // The new role of the current user must also have promote_users caps + if ( $id == $current_user->ID && !$wp_roles->role_objects[$_REQUEST['new_role']]->has_cap('promote_users') ) { + $update = 'err_admin_role'; + continue; + } + + // If the user doesn't already belong to the blog, bail. + if ( is_multisite() && !is_user_member_of_blog( $id ) ) + wp_die(__('Cheatin’ uh?')); + + $user = new WP_User($id); + $user->set_role($_REQUEST['new_role']); + } + + wp_redirect(add_query_arg('update', $update, $redirect)); + exit(); + +break; + +case 'dodelete': + if ( is_multisite() ) + wp_die( __('User deletion is not allowed from this screen.') ); + + check_admin_referer('delete-users'); + + if ( empty($_REQUEST['users']) ) { + wp_redirect($redirect); + exit(); + } + + if ( ! current_user_can( 'delete_users' ) ) + wp_die(__('You can’t delete users.')); + + $userids = $_REQUEST['users']; + $update = 'del'; + $delete_count = 0; + + foreach ( (array) $userids as $id) { + $id = (int) $id; + + if ( ! current_user_can( 'delete_user', $id ) ) + wp_die(__( 'You can’t delete that user.' ) ); + + if ( $id == $current_user->ID ) { + $update = 'err_admin_del'; + continue; + } + switch ( $_REQUEST['delete_option'] ) { + case 'delete': + if ( current_user_can('delete_user', $id) ) + wp_delete_user($id); + break; + case 'reassign': + if ( current_user_can('delete_user', $id) ) + wp_delete_user($id, $_REQUEST['reassign_user']); + break; + } + ++$delete_count; + } + + $redirect = add_query_arg( array('delete_count' => $delete_count, 'update' => $update), $redirect); + wp_redirect($redirect); + exit(); + +break; + +case 'delete': + if ( is_multisite() ) + wp_die( __('User deletion is not allowed from this screen.') ); + + check_admin_referer('bulk-users'); + + if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) { + wp_redirect($redirect); + exit(); + } + + if ( ! current_user_can( 'delete_users' ) ) + $errors = new WP_Error( 'edit_users', __( 'You can’t delete users.' ) ); + + if ( empty($_REQUEST['users']) ) + $userids = array(intval($_REQUEST['user'])); + else + $userids = $_REQUEST['users']; + + include ('admin-header.php'); +?> +
    + + + +
    + +

    +

    +
      +ID ) { + echo "
    • " . sprintf(__('ID #%1s: %2s The current user will not be deleted.'), $id, $user->user_login) . "
    • \n"; + } else { + echo "
    • " . sprintf(__('ID #%1s: %2s'), $id, $user->user_login) . "
    • \n"; + $go_delete = true; + } + } + ?> +
    + +

    +
      +
    • +
    • + '.__('Attribute all posts and links to:').''; + wp_dropdown_users( array( 'name' => 'reassign_user', 'exclude' => array_diff( $userids, array($current_user->ID) ) ) ); ?>
    • +
    + + + +

    + +
    +
    +id && !is_super_admin() ) { + $update = 'err_admin_remove'; + continue; + } + if ( !current_user_can('remove_user', $id) ) { + $update = 'err_admin_remove'; + continue; + } + remove_user_from_blog($id, $blog_id); + } + + $redirect = add_query_arg( array('update' => $update), $redirect); + wp_redirect($redirect); + exit; + +break; + +case 'remove': + + check_admin_referer('bulk-users'); + + if ( ! is_multisite() ) + wp_die( __( 'You can’t remove users.' ) ); + + if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) { + wp_redirect($redirect); + exit(); + } + + if ( !current_user_can('remove_users') ) + $error = new WP_Error('edit_users', __('You can’t remove users.')); + + if ( empty($_REQUEST['users']) ) + $userids = array(intval($_REQUEST['user'])); + else + $userids = $_REQUEST['users']; + + include ('admin-header.php'); +?> +
    + + + +
    + +

    +

    +
      +id && !is_super_admin() ) { + echo "
    • " . sprintf(__('ID #%1s: %2s The current user will not be removed.'), $id, $user->user_login) . "
    • \n"; + } elseif ( !current_user_can('remove_user', $id) ) { + echo "
    • " . sprintf(__('ID #%1s: %2s You don\'t have permission to remove this user.'), $id, $user->user_login) . "
    • \n"; + } else { + echo "
    • " . sprintf(__('ID #%1s: %2s'), $id, $user->user_login) . "
    • \n"; + $go_remove = true; + } + } + ?> + + + + +

      + +
    +
    +prepare_items(); + $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' ); + if ( $pagenum > $total_pages && $total_pages > 0 ) { + wp_redirect( add_query_arg( 'paged', $total_pages ) ); + exit; + } + include('./admin-header.php'); + + $messages = array(); + if ( isset($_GET['update']) ) : + switch($_GET['update']) { + case 'del': + case 'del_many': + $delete_count = isset($_GET['delete_count']) ? (int) $_GET['delete_count'] : 0; + $messages[] = '

    ' . sprintf(_n('%s user deleted', '%s users deleted', $delete_count), $delete_count) . '

    '; + break; + case 'add': + $messages[] = '

    ' . __('New user created.') . '

    '; + break; + case 'promote': + $messages[] = '

    ' . __('Changed roles.') . '

    '; + break; + case 'err_admin_role': + $messages[] = '

    ' . __('The current user’s role must have user editing capabilities.') . '

    '; + $messages[] = '

    ' . __('Other user roles have been changed.') . '

    '; + break; + case 'err_admin_del': + $messages[] = '

    ' . __('You can’t delete the current user.') . '

    '; + $messages[] = '

    ' . __('Other users have been deleted.') . '

    '; + break; + case 'remove': + $messages[] = '

    ' . __('User removed from this site.') . '

    '; + break; + case 'err_admin_remove': + $messages[] = '

    ' . __("You can't remove the current user.") . '

    '; + $messages[] = '

    ' . __('Other users have been removed.') . '

    '; + break; + } + endif; ?> + + +
    +
      + get_error_messages() as $err ) + echo "
    • $err
    • \n"; + ?> +
    +
    + + +
    + +

    + + + + +' . __('Search results for “%s”') . '', esc_html( $usersearch ) ); ?> +

    + +views(); ?> + +
    + +search_box( __( 'Search Users' ), 'user' ); ?> + +display(); ?> +
    + + 'user_login', 'first_name' => 'user_firstname', 'last_name' => 'user_lastname', 'email' => 'user_email', 'url' => 'user_uri', 'role' => 'user_role') as $formpost => $var ) { + $var = 'new_' . $var; + $$var = isset($_REQUEST[$formpost]) ? esc_attr(stripslashes($_REQUEST[$formpost])) : ''; + } + unset($name); +} +?> + +
    +
    +' . __('Widgets are independent sections of content that can be placed into any widgetized area provided by your theme (commonly called sidebars). To populate your sidebars/widget areas with individual widgets, drag and drop the title bars into the desired area. By default, only the first widget area is expanded. To populate additional widget areas, click on their title bars to expand them.') . '

    +

    ' . __('The Available Widgets section contains all the widgets you can choose from. Once you drag a widget into a sidebar, it will open to allow you to configure its settings. When you are happy with the widget settings, click the Save button and the widget will go live on your site. If you click Delete, it will remove the widget.') . '

    +

    ' . __('If you want to remove the widget but save its setting for possible future use, just drag it into the Inactive Widgets area. You can add them back anytime from there. This is especially helpful when you switch to a theme with fewer or different widget areas.') . '

    +

    ' . __('Widgets may be used multiple times. You can give each widget a title, to display on your site, but it’s not required.') . '

    +

    ' . __('Enabling Accessibility Mode, via Screen Options, allows you to use Add and Edit buttons instead of using drag and drop.') . '

    +

    ' . __('Many themes show some sidebar widgets by default until you edit your sidebars, but they are not automatically displayed in your sidebar management tool. After you make your first widget change, you can re-add the default widgets by adding them from the Available Widgets area.') . '

    +'; +$help .= '

    ' . __('For more information:') . '

    '; +$help .= '

    ' . __('Documentation on Widgets') . '

    '; +$help .= '

    ' . __('Support Forums') . '

    '; +add_contextual_help($current_screen, $help); + +// register the inactive_widgets area as sidebar +register_sidebar(array( + 'name' => __('Inactive Widgets'), + 'id' => 'wp_inactive_widgets', + 'description' => '', + 'before_widget' => '', + 'after_widget' => '', + 'before_title' => '', + 'after_title' => '', +)); + +// These are the widgets grouped by sidebar +$sidebars_widgets = wp_get_sidebars_widgets(); +if ( empty( $sidebars_widgets ) ) + $sidebars_widgets = wp_get_widget_defaults(); + +// look for "lost" widgets, this has to run at least on each theme change +function retrieve_widgets() { + global $wp_registered_widget_updates, $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets; + + $_sidebars_widgets = array(); + $sidebars = array_keys($wp_registered_sidebars); + + unset( $sidebars_widgets['array_version'] ); + + $old = array_keys($sidebars_widgets); + sort($old); + sort($sidebars); + + if ( $old == $sidebars ) + return; + + // Move the known-good ones first + foreach ( $sidebars as $id ) { + if ( array_key_exists( $id, $sidebars_widgets ) ) { + $_sidebars_widgets[$id] = $sidebars_widgets[$id]; + unset($sidebars_widgets[$id], $sidebars[$id]); + } + } + + // if new theme has less sidebars than the old theme + if ( !empty($sidebars_widgets) ) { + foreach ( $sidebars_widgets as $lost => $val ) { + if ( is_array($val) ) + $_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $val ); + } + } + + // discard invalid, theme-specific widgets from sidebars + $shown_widgets = array(); + foreach ( $_sidebars_widgets as $sidebar => $widgets ) { + if ( !is_array($widgets) ) + continue; + + $_widgets = array(); + foreach ( $widgets as $widget ) { + if ( isset($wp_registered_widgets[$widget]) ) + $_widgets[] = $widget; + } + $_sidebars_widgets[$sidebar] = $_widgets; + $shown_widgets = array_merge($shown_widgets, $_widgets); + } + + $sidebars_widgets = $_sidebars_widgets; + unset($_sidebars_widgets, $_widgets); + + // find hidden/lost multi-widget instances + $lost_widgets = array(); + foreach ( $wp_registered_widgets as $key => $val ) { + if ( in_array($key, $shown_widgets, true) ) + continue; + + $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key); + + if ( 2 > (int) $number ) + continue; + + $lost_widgets[] = $key; + } + + $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']); + wp_set_sidebars_widgets($sidebars_widgets); +} +retrieve_widgets(); + +if ( count($wp_registered_sidebars) == 1 ) { + // If only "wp_inactive_widgets" is defined the theme has no sidebars, die. + require_once( './admin-header.php' ); +?> + +
    + +

    +
    +

    +
    +

    follow these instructions.' ); ?>

    +
    + + $val ) { + if ( is_array($val) && preg_match('/__i__|%i%/', key($val)) ) { + $_POST[$key] = array( $number => array_shift($val) ); + break; + } + } + } + + $sidebar_id = $_POST['sidebar']; + $position = isset($_POST[$sidebar_id . '_position']) ? (int) $_POST[$sidebar_id . '_position'] - 1 : 0; + + $id_base = $_POST['id_base']; + $sidebar = isset($sidebars_widgets[$sidebar_id]) ? $sidebars_widgets[$sidebar_id] : array(); + + // delete + if ( isset($_POST['removewidget']) && $_POST['removewidget'] ) { + + if ( !in_array($widget_id, $sidebar, true) ) { + wp_redirect( admin_url('widgets.php?error=0') ); + exit; + } + + $sidebar = array_diff( $sidebar, array($widget_id) ); + $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1'); + } + + $_POST['widget-id'] = $sidebar; + + foreach ( (array) $wp_registered_widget_updates as $name => $control ) { + if ( $name != $id_base || !is_callable($control['callback']) ) + continue; + + ob_start(); + call_user_func_array( $control['callback'], $control['params'] ); + ob_end_clean(); + + break; + } + + $sidebars_widgets[$sidebar_id] = $sidebar; + + // remove old position + if ( !isset($_POST['delete_widget']) ) { + foreach ( $sidebars_widgets as $key => $sb ) { + if ( is_array($sb) ) + $sidebars_widgets[$key] = array_diff( $sb, array($widget_id) ); + } + array_splice( $sidebars_widgets[$sidebar_id], $position, 0, $widget_id ); + } + + wp_set_sidebars_widgets($sidebars_widgets); + wp_redirect( admin_url('widgets.php?message=0') ); + exit; +} + +// Output the widget form without js +if ( isset($_GET['editwidget']) && $_GET['editwidget'] ) { + $widget_id = $_GET['editwidget']; + + if ( isset($_GET['addnew']) ) { + // Default to the first sidebar + $sidebar = array_shift( $keys = array_keys($wp_registered_sidebars) ); + + if ( isset($_GET['base']) && isset($_GET['num']) ) { // multi-widget + // Copy minimal info from an existing instance of this widget to a new instance + foreach ( $wp_registered_widget_controls as $control ) { + if ( $_GET['base'] === $control['id_base'] ) { + $control_callback = $control['callback']; + $multi_number = (int) $_GET['num']; + $control['params'][0]['number'] = -1; + $widget_id = $control['id'] = $control['id_base'] . '-' . $multi_number; + $wp_registered_widget_controls[$control['id']] = $control; + break; + } + } + } + } + + if ( isset($wp_registered_widget_controls[$widget_id]) && !isset($control) ) { + $control = $wp_registered_widget_controls[$widget_id]; + $control_callback = $control['callback']; + } elseif ( !isset($wp_registered_widget_controls[$widget_id]) && isset($wp_registered_widgets[$widget_id]) ) { + $name = esc_html( strip_tags($wp_registered_widgets[$widget_id]['name']) ); + } + + if ( !isset($name) ) + $name = esc_html( strip_tags($control['name']) ); + + if ( !isset($sidebar) ) + $sidebar = isset($_GET['sidebar']) ? $_GET['sidebar'] : 'wp_inactive_widgets'; + + if ( !isset($multi_number) ) + $multi_number = isset($control['params'][0]['number']) ? $control['params'][0]['number'] : ''; + + $id_base = isset($control['id_base']) ? $control['id_base'] : $control['id']; + + // show the widget form + $width = ' style="width:' . max($control['width'], 350) . 'px"'; + $key = isset($_GET['key']) ? (int) $_GET['key'] : 0; + + require_once( './admin-header.php' ); ?> +
    + +

    +
    > +

    + +
    +
    +' . __('There are no options for this widget.') . "

    \n"; ?> +
    + +

    +
    + + $sbvalue ) { + echo "\t\t\n"; + } ?> +
    "; + if ( 'wp_inactive_widgets' == $sbname ) { + echo ' '; + } else { + if ( !isset($sidebars_widgets[$sbname]) || !is_array($sidebars_widgets[$sbname]) ) { + $j = 1; + $sidebars_widgets[$sbname] = array(); + } else { + $j = count($sidebars_widgets[$sbname]); + if ( isset($_GET['addnew']) || !in_array($widget_id, $sidebars_widgets[$sbname], true) ) + $j++; + } + $selected = ''; + echo "\t\t\n"; + } + echo "
    +
    + +
    + + + + + + + +
    +
    +
    +
    +
    + + +
    + +

    + + +

    + + +

    + + + + +
    +
    +
    + +
    +

    +
    + +
    +
    +
    +
    +
    + +
    + +
    +

    + +
    +
    +
    +
    +
    + +
    +
    + $registered_sidebar ) { + if ( 'wp_inactive_widgets' == $sidebar ) + continue; + $closed = $i ? ' closed' : ''; ?> +
    + + +
    + +
    +
    +
    + +
    +
    +
    + +script_name = array_pop( $var_by_ref = explode( '/', $_SERVER['SCRIPT_NAME'] ) ); + $this->app_base = site_url( $this->script_name . '/' ); + + $this->selectors = array( + '@/service$@' => + array('GET' => 'get_service'), + '@/categories$@' => + array('GET' => 'get_categories_xml'), + '@/post/(\d+)$@' => + array('GET' => 'get_post', + 'PUT' => 'put_post', + 'DELETE' => 'delete_post'), + '@/posts/?(\d+)?$@' => + array('GET' => 'get_posts', + 'POST' => 'create_post'), + '@/attachments/?(\d+)?$@' => + array('GET' => 'get_attachment', + 'POST' => 'create_attachment'), + '@/attachment/file/(\d+)$@' => + array('GET' => 'get_file', + 'PUT' => 'put_file', + 'DELETE' => 'delete_file'), + '@/attachment/(\d+)$@' => + array('GET' => 'get_attachment', + 'PUT' => 'put_attachment', + 'DELETE' => 'delete_attachment'), + ); + } + + /** + * Handle ATOMPUB request. + * + * @since 2.2.0 + */ + function handle_request() { + global $always_authenticate; + + if ( !empty( $_SERVER['ORIG_PATH_INFO'] ) ) + $path = $_SERVER['ORIG_PATH_INFO']; + else + $path = $_SERVER['PATH_INFO']; + + $method = $_SERVER['REQUEST_METHOD']; + + log_app('REQUEST',"$method $path\n================"); + + $this->process_conditionals(); + //$this->process_conditionals(); + + // exception case for HEAD (treat exactly as GET, but don't output) + if ($method == 'HEAD') { + $this->do_output = false; + $method = 'GET'; + } + + // redirect to /service in case no path is found. + if (strlen($path) == 0 || $path == '/') + $this->redirect($this->get_service_url()); + + // check to see if AtomPub is enabled + if ( !get_option( 'enable_app' ) ) + $this->forbidden( sprintf( __( 'AtomPub services are disabled on this site. An admin user can enable them at %s' ), admin_url('options-writing.php') ) ); + + // dispatch + foreach ( $this->selectors as $regex => $funcs ) { + if ( preg_match($regex, $path, $matches) ) { + if ( isset($funcs[$method]) ) { + + // authenticate regardless of the operation and set the current + // user. each handler will decide if auth is required or not. + if ( !$this->authenticate() ) { + if ( $always_authenticate ) + $this->auth_required('Credentials required.'); + } + + array_shift($matches); + call_user_func_array(array(&$this,$funcs[$method]), $matches); + exit(); + } else { + // only allow what we have handlers for... + $this->not_allowed(array_keys($funcs)); + } + } + } + + // oops, nothing found + $this->not_found(); + } + + /** + * Retrieve XML for ATOMPUB service. + * + * @since 2.2.0 + */ + function get_service() { + log_app('function','get_service()'); + + if ( !current_user_can( 'edit_posts' ) ) + $this->auth_required( __( 'Sorry, you do not have the right to access this site.' ) ); + + $entries_url = esc_attr($this->get_entries_url()); + $categories_url = esc_attr($this->get_categories_url()); + $media_url = esc_attr($this->get_attachments_url()); + $accepted_media_types = ''; + foreach ($this->media_content_types as $med) { + $accepted_media_types = $accepted_media_types . "" . $med . ""; + } + $atom_prefix="atom"; + $atom_blogname = get_bloginfo('name'); + $service_doc = << + + <$atom_prefix:title>$atom_blogname Workspace + + <$atom_prefix:title>$atom_blogname Posts + $this->ATOM_CONTENT_TYPE;type=entry + + + + <$atom_prefix:title>$atom_blogname Media + $accepted_media_types + + + + +EOD; + + $this->output($service_doc, $this->SERVICE_CONTENT_TYPE); + } + + /** + * Retrieve categories list in XML format. + * + * @since 2.2.0 + */ + function get_categories_xml() { + log_app('function','get_categories_xml()'); + + if ( !current_user_can( 'edit_posts' ) ) + $this->auth_required( __( 'Sorry, you do not have the right to access this site.' ) ); + + $home = esc_attr(get_bloginfo_rss('url')); + + $categories = ""; + $cats = get_categories(array('hierarchical' => 0, 'hide_empty' => 0)); + foreach ( (array) $cats as $cat ) { + $categories .= " name) . "\" />\n"; + } + $output = << + $categories + +EOD; + $this->output($output, $this->CATEGORIES_CONTENT_TYPE); + } + + /** + * Create new post. + * + * @since 2.2.0 + */ + function create_post() { + global $user_ID; + $this->get_accepted_content_type($this->atom_content_types); + + $parser = new AtomParser(); + if ( !$parser->parse() ) + $this->client_error(); + + $entry = array_pop($parser->feed->entries); + + log_app('Received entry:', print_r($entry,true)); + + $catnames = array(); + foreach ( $entry->categories as $cat ) { + array_push($catnames, $cat["term"]); + } + + $wp_cats = get_categories(array('hide_empty' => false)); + + $post_category = array(); + + foreach ( $wp_cats as $cat ) { + if ( in_array($cat->name, $catnames) ) + array_push($post_category, $cat->term_id); + } + + $publish = ! ( isset( $entry->draft ) && 'yes' == trim( $entry->draft ) ); + + $cap = ($publish) ? 'publish_posts' : 'edit_posts'; + + if ( !current_user_can($cap) ) + $this->auth_required(__('Sorry, you do not have the right to edit/publish new posts.')); + + $blog_ID = get_current_blog_id(); + $post_status = ($publish) ? 'publish' : 'draft'; + $post_author = (int) $user_ID; + $post_title = $entry->title[1]; + $post_content = $entry->content[1]; + $post_excerpt = $entry->summary[1]; + $pubtimes = $this->get_publish_time($entry->published); + $post_date = $pubtimes[0]; + $post_date_gmt = $pubtimes[1]; + + if ( isset( $_SERVER['HTTP_SLUG'] ) ) + $post_name = $_SERVER['HTTP_SLUG']; + + $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_name'); + + $this->escape($post_data); + log_app('Inserting Post. Data:', print_r($post_data,true)); + + $postID = wp_insert_post($post_data); + if ( is_wp_error( $postID ) ) + $this->internal_error($postID->get_error_message()); + + if ( !$postID ) + $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.')); + + // getting warning here about unable to set headers + // because something in the cache is printing to the buffer + // could we clean up wp_set_post_categories or cache to not print + // this could affect our ability to send back the right headers + @wp_set_post_categories($postID, $post_category); + + do_action( 'atompub_create_post', $postID, $entry ); + + $output = $this->get_entry($postID); + + log_app('function',"create_post($postID)"); + $this->created($postID, $output); + } + + /** + * Retrieve post. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function get_post($postID) { + global $entry; + + if ( !current_user_can( 'edit_post', $postID ) ) + $this->auth_required( __( 'Sorry, you do not have the right to access this post.' ) ); + + $this->set_current_entry($postID); + $output = $this->get_entry($postID); + log_app('function',"get_post($postID)"); + $this->output($output); + + } + + /** + * Update post. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function put_post($postID) { + // checked for valid content-types (atom+xml) + // quick check and exit + $this->get_accepted_content_type($this->atom_content_types); + + $parser = new AtomParser(); + if ( !$parser->parse() ) + $this->bad_request(); + + $parsed = array_pop($parser->feed->entries); + + log_app('Received UPDATED entry:', print_r($parsed,true)); + + // check for not found + global $entry; + $this->set_current_entry($postID); + + if ( !current_user_can('edit_post', $entry['ID']) ) + $this->auth_required(__('Sorry, you do not have the right to edit this post.')); + + $publish = ! ( isset($parsed->draft) && 'yes' == trim($parsed->draft) ); + $post_status = ($publish) ? 'publish' : 'draft'; + + extract($entry); + + $post_title = $parsed->title[1]; + $post_content = $parsed->content[1]; + $post_excerpt = $parsed->summary[1]; + $pubtimes = $this->get_publish_time($entry->published); + $post_date = $pubtimes[0]; + $post_date_gmt = $pubtimes[1]; + $pubtimes = $this->get_publish_time($parsed->updated); + $post_modified = $pubtimes[0]; + $post_modified_gmt = $pubtimes[1]; + + $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt'); + $this->escape($postdata); + + $result = wp_update_post($postdata); + + if ( !$result ) + $this->internal_error(__('For some strange yet very annoying reason, this post could not be edited.')); + + do_action( 'atompub_put_post', $ID, $parsed ); + + log_app('function',"put_post($postID)"); + $this->ok(); + } + + /** + * Remove post. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function delete_post($postID) { + + // check for not found + global $entry; + $this->set_current_entry($postID); + + if ( !current_user_can('edit_post', $postID) ) + $this->auth_required(__('Sorry, you do not have the right to delete this post.')); + + if ( $entry['post_type'] == 'attachment' ) { + $this->delete_attachment($postID); + } else { + $result = wp_delete_post($postID); + + if ( !$result ) { + $this->internal_error(__('For some strange yet very annoying reason, this post could not be deleted.')); + } + + log_app('function',"delete_post($postID)"); + $this->ok(); + } + + } + + /** + * Retrieve attachment. + * + * @since 2.2.0 + * + * @param int $postID Optional. Post ID. + */ + function get_attachment($postID = null) { + if ( !current_user_can( 'upload_files' ) ) + $this->auth_required( __( 'Sorry, you do not have permission to upload files.' ) ); + + if ( !isset($postID) ) { + $this->get_attachments(); + } else { + $this->set_current_entry($postID); + $output = $this->get_entry($postID, 'attachment'); + log_app('function',"get_attachment($postID)"); + $this->output($output); + } + } + + /** + * Create new attachment. + * + * @since 2.2.0 + */ + function create_attachment() { + + $type = $this->get_accepted_content_type(); + + if ( !current_user_can('upload_files') ) + $this->auth_required(__('You do not have permission to upload files.')); + + $fp = fopen("php://input", "rb"); + $bits = null; + while ( !feof($fp) ) { + $bits .= fread($fp, 4096); + } + fclose($fp); + + $slug = ''; + if ( isset( $_SERVER['HTTP_SLUG'] ) ) + $slug = $_SERVER['HTTP_SLUG']; + elseif ( isset( $_SERVER['HTTP_TITLE'] ) ) + $slug = $_SERVER['HTTP_TITLE']; + elseif ( empty( $slug ) ) // just make a random name + $slug = substr( md5( uniqid( microtime() ) ), 0, 7); + $ext = preg_replace( '|.*/([a-z0-9]+)|', '$1', $_SERVER['CONTENT_TYPE'] ); + $slug = sanitize_file_name( "$slug.$ext" ); + $file = wp_upload_bits( $slug, NULL, $bits); + + log_app('wp_upload_bits returns:',print_r($file,true)); + + $url = $file['url']; + $file = $file['file']; + + do_action('wp_create_file_in_uploads', $file); // replicate + + // Construct the attachment array + $attachment = array( + 'post_title' => $slug, + 'post_content' => $slug, + 'post_status' => 'attachment', + 'post_parent' => 0, + 'post_mime_type' => $type, + 'guid' => $url + ); + + // Save the data + $postID = wp_insert_attachment($attachment, $file); + + if (!$postID) + $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.')); + + $output = $this->get_entry($postID, 'attachment'); + + $this->created($postID, $output, 'attachment'); + log_app('function',"create_attachment($postID)"); + } + + /** + * Update attachment. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function put_attachment($postID) { + // checked for valid content-types (atom+xml) + // quick check and exit + $this->get_accepted_content_type($this->atom_content_types); + + $parser = new AtomParser(); + if (!$parser->parse()) { + $this->bad_request(); + } + + $parsed = array_pop($parser->feed->entries); + + // check for not found + global $entry; + $this->set_current_entry($postID); + + if ( !current_user_can('edit_post', $entry['ID']) ) + $this->auth_required(__('Sorry, you do not have the right to edit this post.')); + + extract($entry); + + $post_title = $parsed->title[1]; + $post_content = $parsed->summary[1]; + $pubtimes = $this->get_publish_time($parsed->updated); + $post_modified = $pubtimes[0]; + $post_modified_gmt = $pubtimes[1]; + + $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_modified', 'post_modified_gmt'); + $this->escape($postdata); + + $result = wp_update_post($postdata); + + if ( !$result ) + $this->internal_error(__('For some strange yet very annoying reason, this post could not be edited.')); + + log_app('function',"put_attachment($postID)"); + $this->ok(); + } + + /** + * Remove attachment. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function delete_attachment($postID) { + log_app('function',"delete_attachment($postID). File '$location' deleted."); + + // check for not found + global $entry; + $this->set_current_entry($postID); + + if ( !current_user_can('edit_post', $postID) ) + $this->auth_required(__('Sorry, you do not have the right to delete this post.')); + + $location = get_post_meta($entry['ID'], '_wp_attached_file', true); + $filetype = wp_check_filetype($location); + + if ( !isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext']) ) + $this->internal_error(__('Error occurred while accessing post metadata for file location.')); + + // delete file + @unlink($location); + + // delete attachment + $result = wp_delete_post($postID); + + if ( !$result ) + $this->internal_error(__('For some strange yet very annoying reason, this post could not be deleted.')); + + log_app('function',"delete_attachment($postID). File '$location' deleted."); + $this->ok(); + } + + /** + * Retrieve attachment from post. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function get_file($postID) { + + // check for not found + global $entry; + $this->set_current_entry($postID); + + // then whether user can edit the specific post + if ( !current_user_can('edit_post', $postID) ) + $this->auth_required(__('Sorry, you do not have the right to edit this post.')); + + $location = get_post_meta($entry['ID'], '_wp_attached_file', true); + $location = get_option ('upload_path') . '/' . $location; + $filetype = wp_check_filetype($location); + + if ( !isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext']) ) + $this->internal_error(__('Error occurred while accessing post metadata for file location.')); + + status_header('200'); + header('Content-Type: ' . $entry['post_mime_type']); + header('Connection: close'); + + if ( $fp = fopen($location, "rb") ) { + status_header('200'); + header('Content-Type: ' . $entry['post_mime_type']); + header('Connection: close'); + + while ( !feof($fp) ) { + echo fread($fp, 4096); + } + + fclose($fp); + } else { + status_header ('404'); + } + + log_app('function',"get_file($postID)"); + exit; + } + + /** + * Upload file to blog and add attachment to post. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function put_file($postID) { + + // first check if user can upload + if ( !current_user_can('upload_files') ) + $this->auth_required(__('You do not have permission to upload files.')); + + // check for not found + global $entry; + $this->set_current_entry($postID); + + // then whether user can edit the specific post + if ( !current_user_can('edit_post', $postID) ) + $this->auth_required(__('Sorry, you do not have the right to edit this post.')); + + $upload_dir = wp_upload_dir( ); + $location = get_post_meta($entry['ID'], '_wp_attached_file', true); + $filetype = wp_check_filetype($location); + + $location = "{$upload_dir['basedir']}/{$location}"; + + if (!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext'])) + $this->internal_error(__('Error occurred while accessing post metadata for file location.')); + + $fp = fopen("php://input", "rb"); + $localfp = fopen($location, "w+"); + while ( !feof($fp) ) { + fwrite($localfp,fread($fp, 4096)); + } + fclose($fp); + fclose($localfp); + + $ID = $entry['ID']; + $pubtimes = $this->get_publish_time($entry->published); + $post_date = $pubtimes[0]; + $post_date_gmt = $pubtimes[1]; + $pubtimes = $this->get_publish_time($parsed->updated); + $post_modified = $pubtimes[0]; + $post_modified_gmt = $pubtimes[1]; + + $post_data = compact('ID', 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt'); + $result = wp_update_post($post_data); + + if ( !$result ) + $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.')); + + wp_update_attachment_metadata( $postID, wp_generate_attachment_metadata( $postID, $location ) ); + + log_app('function',"put_file($postID)"); + $this->ok(); + } + + /** + * Retrieve entries URL. + * + * @since 2.2.0 + * + * @param int $page Page ID. + * @return string + */ + function get_entries_url($page = null) { + if ( isset($GLOBALS['post_type']) && ( $GLOBALS['post_type'] == 'attachment' ) ) + $path = $this->MEDIA_PATH; + else + $path = $this->ENTRIES_PATH; + $url = $this->app_base . $path; + if ( isset($page) && is_int($page) ) + $url .= "/$page"; + return $url; + } + + /** + * Display entries URL. + * + * @since 2.2.0 + * + * @param int $page Page ID. + */ + function the_entries_url($page = null) { + echo $this->get_entries_url($page); + } + + /** + * Retrieve categories URL. + * + * @since 2.2.0 + * + * @param mixed $deprecated Not used. + * @return string + */ + function get_categories_url($deprecated = '') { + if ( !empty( $deprecated ) ) + _deprecated_argument( __FUNCTION__, '2.5' ); + return $this->app_base . $this->CATEGORIES_PATH; + } + + /** + * Display category URL. + * + * @since 2.2.0 + */ + function the_categories_url() { + echo $this->get_categories_url(); + } + + /** + * Retrieve attachment URL. + * + * @since 2.2.0 + * + * @param int $page Page ID. + * @return string + */ + function get_attachments_url($page = null) { + $url = $this->app_base . $this->MEDIA_PATH; + if (isset($page) && is_int($page)) { + $url .= "/$page"; + } + return $url; + } + + /** + * Display attachment URL. + * + * @since 2.2.0 + * + * @param int $page Page ID. + */ + function the_attachments_url($page = null) { + echo $this->get_attachments_url($page); + } + + /** + * Retrieve service URL. + * + * @since 2.3.0 + * + * @return string + */ + function get_service_url() { + return $this->app_base . $this->SERVICE_PATH; + } + + /** + * Retrieve entry URL. + * + * @since 2.7.0 + * + * @param int $postID Post ID. + * @return string + */ + function get_entry_url($postID = null) { + if (!isset($postID)) { + global $post; + $postID = (int) $post->ID; + } + + $url = $this->app_base . $this->ENTRY_PATH . "/$postID"; + + log_app('function',"get_entry_url() = $url"); + return $url; + } + + /** + * Display entry URL. + * + * @since 2.7.0 + * + * @param int $postID Post ID. + */ + function the_entry_url($postID = null) { + echo $this->get_entry_url($postID); + } + + /** + * Retrieve media URL. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + * @return string + */ + function get_media_url($postID = null) { + if (!isset($postID)) { + global $post; + $postID = (int) $post->ID; + } + + $url = $this->app_base . $this->MEDIA_SINGLE_PATH ."/file/$postID"; + + log_app('function',"get_media_url() = $url"); + return $url; + } + + /** + * Display the media URL. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function the_media_url($postID = null) { + echo $this->get_media_url($postID); + } + + /** + * Set the current entry to post ID. + * + * @since 2.2.0 + * + * @param int $postID Post ID. + */ + function set_current_entry($postID) { + global $entry; + log_app('function',"set_current_entry($postID)"); + + if (!isset($postID)) { + // $this->bad_request(); + $this->not_found(); + } + + $entry = wp_get_single_post($postID,ARRAY_A); + + if (!isset($entry) || !isset($entry['ID'])) + $this->not_found(); + + return; + } + + /** + * Display posts XML. + * + * @since 2.2.0 + * + * @param int $page Optional. Page ID. + * @param string $post_type Optional, default is 'post'. Post Type. + */ + function get_posts($page = 1, $post_type = 'post') { + log_app('function',"get_posts($page, '$post_type')"); + $feed = $this->get_feed($page, $post_type); + $this->output($feed); + } + + /** + * Display attachment XML. + * + * @since 2.2.0 + * + * @param int $page Page ID. + * @param string $post_type Optional, default is 'attachment'. Post type. + */ + function get_attachments($page = 1, $post_type = 'attachment') { + log_app('function',"get_attachments($page, '$post_type')"); + $GLOBALS['post_type'] = $post_type; + $feed = $this->get_feed($page, $post_type); + $this->output($feed); + } + + /** + * Retrieve feed XML. + * + * @since 2.2.0 + * + * @param int $page Page ID. + * @param string $post_type Optional, default is post. Post type. + * @return string + */ + function get_feed($page = 1, $post_type = 'post') { + global $post, $wp, $wp_query, $posts, $wpdb, $blog_id; + log_app('function',"get_feed($page, '$post_type')"); + ob_start(); + + $this->ENTRY_PATH = $post_type; + + if (!isset($page)) { + $page = 1; + } + $page = (int) $page; + + $count = get_option('posts_per_rss'); + + wp('posts_per_page=' . $count . '&offset=' . ($count * ($page-1) . '&orderby=modified')); + + $post = $GLOBALS['post']; + $posts = $GLOBALS['posts']; + $wp = $GLOBALS['wp']; + $wp_query = $GLOBALS['wp_query']; + $wpdb = $GLOBALS['wpdb']; + $blog_id = (int) $GLOBALS['blog_id']; + log_app('function',"query_posts(# " . print_r($wp_query, true) . "#)"); + + log_app('function',"total_count(# $wp_query->max_num_pages #)"); + $last_page = $wp_query->max_num_pages; + $next_page = (($page + 1) > $last_page) ? NULL : $page + 1; + $prev_page = ($page - 1) < 1 ? NULL : $page - 1; + $last_page = ((int)$last_page == 1 || (int)$last_page == 0) ? NULL : (int) $last_page; + $self_page = $page > 1 ? $page : NULL; +?> > +the_entries_url() ?> + +<?php bloginfo_rss('name') ?> + + + + + + + + + + +Copyright + +echo_entry(); + } + } +?> +ENTRY_PATH = 'attachment'; + $varname = 'attachment_id'; + break; + } + query_posts($varname . '=' . $postID); + if ( have_posts() ) { + while ( have_posts() ) { + the_post(); + $this->echo_entry(); + log_app('$post',print_r($GLOBALS['post'],true)); + $entry = ob_get_contents(); + break; + } + } + ob_end_clean(); + + log_app('get_entry returning:',$entry); + return $entry; + } + + /** + * Display post content XML. + * + * @since 2.3.0 + */ + function echo_entry() { ?> + + ID ); ?> + + <?php echo $content ?> + + + + + post_status == 'draft' ? 'yes' : 'no') ?> + + + + + + + +post_type == 'attachment') { ?> + + + + +post_content ) ) : +list($content_type, $content) = prep_atom_text_construct(get_the_content()); ?> + + + + + + + + + + + + + 302 Found + + +

    Found

    +

    The document has moved here.

    + + + +EOD; + header('HTTP/1.1 302 Moved'); + header('Content-Type: text/html'); + header('Location: ' . $url); + echo $content; + exit; + + } + + /** + * Set 'Client Error' (400) status header. + * + * @since 2.2.0 + */ + function client_error($msg = 'Client Error') { + log_app('Status','400: Client Error'); + header('Content-Type: text/plain'); + status_header('400'); + exit; + } + + /** + * Set created status headers (201). + * + * Sets the 'content-type', 'content-location', and 'location'. + * + * @since 2.2.0 + */ + function created($post_ID, $content, $post_type = 'post') { + log_app('created()::$post_ID',"$post_ID, $post_type"); + $edit = $this->get_entry_url($post_ID); + switch($post_type) { + case 'post': + $ctloc = $this->get_entry_url($post_ID); + break; + case 'attachment': + $edit = $this->app_base . "attachments/$post_ID"; + break; + } + header("Content-Type: $this->ATOM_CONTENT_TYPE"); + if (isset($ctloc)) + header('Content-Location: ' . $ctloc); + header('Location: ' . $edit); + status_header('201'); + echo $content; + exit; + } + + /** + * Set 'Auth Required' (401) headers. + * + * @since 2.2.0 + * + * @param string $msg Status header content and HTML content. + */ + function auth_required($msg) { + log_app('Status','401: Auth Required'); + nocache_headers(); + header('WWW-Authenticate: Basic realm="WordPress Atom Protocol"'); + header("HTTP/1.1 401 $msg"); + header('Status: 401 ' . $msg); + header('Content-Type: text/html'); + $content = << + + + 401 Unauthorized + + +

    401 Unauthorized

    +

    $msg

    + + + +EOD; + echo $content; + exit; + } + + /** + * Display XML and set headers with content type. + * + * @since 2.2.0 + * + * @param string $xml Display feed content. + * @param string $ctype Optional, default is 'atom+xml'. Feed content type. + */ + function output($xml, $ctype = 'application/atom+xml') { + status_header('200'); + $xml = ''."\n".$xml; + header('Connection: close'); + header('Content-Length: '. strlen($xml)); + header('Content-Type: ' . $ctype); + header('Content-Disposition: attachment; filename=atom.xml'); + header('Date: '. date('r')); + if ($this->do_output) + echo $xml; + log_app('function', "output:\n$xml"); + exit; + } + + /** + * Sanitize content for database usage. + * + * @since 2.2.0 + * + * @param array $array Sanitize array and multi-dimension array. + */ + function escape(&$array) { + global $wpdb; + + foreach ($array as $k => $v) { + if (is_array($v)) { + $this->escape($array[$k]); + } else if (is_object($v)) { + //skip + } else { + $array[$k] = $wpdb->escape($v); + } + } + } + + /** + * Access credential through various methods and perform login. + * + * @since 2.2.0 + * + * @return bool + */ + function authenticate() { + log_app("authenticate()",print_r($_ENV, true)); + + // if using mod_rewrite/ENV hack + // http://www.besthostratings.com/articles/http-auth-php-cgi.html + if (isset($_SERVER['HTTP_AUTHORIZATION'])) { + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = + explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); + } else if (isset($_SERVER['REDIRECT_REMOTE_USER'])) { + // Workaround for setups that do not forward HTTP_AUTHORIZATION + // See http://trac.wordpress.org/ticket/7361 + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = + explode(':', base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6))); + } + + // If Basic Auth is working... + if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { + log_app("Basic Auth",$_SERVER['PHP_AUTH_USER']); + + $user = wp_authenticate($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + if ( $user && !is_wp_error($user) ) { + wp_set_current_user($user->ID); + log_app("authenticate()", $user->user_login); + return true; + } + } + + return false; + } + + /** + * Retrieve accepted content types. + * + * @since 2.2.0 + * + * @param array $types Optional. Content Types. + * @return string + */ + function get_accepted_content_type($types = null) { + + if (!isset($types)) { + $types = $this->media_content_types; + } + + if (!isset($_SERVER['CONTENT_LENGTH']) || !isset($_SERVER['CONTENT_TYPE'])) { + $this->length_required(); + } + + $type = $_SERVER['CONTENT_TYPE']; + list($type,$subtype) = explode('/',$type); + list($subtype) = explode(";",$subtype); // strip MIME parameters + log_app("get_accepted_content_type", "type=$type, subtype=$subtype"); + + foreach($types as $t) { + list($acceptedType,$acceptedSubtype) = explode('/',$t); + if ($acceptedType == '*' || $acceptedType == $type) { + if ($acceptedSubtype == '*' || $acceptedSubtype == $subtype) + return $type . "/" . $subtype; + } + } + + $this->invalid_media(); + } + + /** + * Process conditionals for posts. + * + * @since 2.2.0 + */ + function process_conditionals() { + + if (empty($this->params)) return; + if ($_SERVER['REQUEST_METHOD'] == 'DELETE') return; + + switch($this->params[0]) { + case $this->ENTRY_PATH: + global $post; + $post = wp_get_single_post($this->params[1]); + $wp_last_modified = get_post_modified_time('D, d M Y H:i:s', true); + $post = NULL; + break; + case $this->ENTRIES_PATH: + $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT'; + break; + default: + return; + } + $wp_etag = md5($wp_last_modified); + @header("Last-Modified: $wp_last_modified"); + @header("ETag: $wp_etag"); + + // Support for Conditional GET + if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) + $client_etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']); + else + $client_etag = false; + + $client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE']); + // If string is empty, return 0. If not, attempt to parse into a timestamp + $client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0; + + // Make a timestamp for our most recent modification... + $wp_modified_timestamp = strtotime($wp_last_modified); + + if ( ($client_last_modified && $client_etag) ? + (($client_modified_timestamp >= $wp_modified_timestamp) && ($client_etag == $wp_etag)) : + (($client_modified_timestamp >= $wp_modified_timestamp) || ($client_etag == $wp_etag)) ) { + status_header( 304 ); + exit; + } + } + + /** + * Convert RFC3339 time string to timestamp. + * + * @since 2.3.0 + * + * @param string $str String to time. + * @return bool|int false if format is incorrect. + */ + function rfc3339_str2time($str) { + + $match = false; + if (!preg_match("/(\d{4}-\d{2}-\d{2})T(\d{2}\:\d{2}\:\d{2})\.?\d{0,3}(Z|[+-]+\d{2}\:\d{2})/", $str, $match)) + return false; + + if ($match[3] == 'Z') + $match[3] = '+0000'; + + return strtotime($match[1] . " " . $match[2] . " " . $match[3]); + } + + /** + * Retrieve published time to display in XML. + * + * @since 2.3.0 + * + * @param string $published Time string. + * @return string + */ + function get_publish_time($published) { + + $pubtime = $this->rfc3339_str2time($published); + + if (!$pubtime) { + return array(current_time('mysql'),current_time('mysql',1)); + } else { + return array(date("Y-m-d H:i:s", $pubtime), gmdate("Y-m-d H:i:s", $pubtime)); + } + } + +} + +/** + * AtomServer + * @var AtomServer + * @global object $server + */ +$server = new AtomServer(); +$server->handle_request(); + +?> diff --git a/src/wp-atom.php b/src/wp-atom.php new file mode 100644 index 00000000..a83ac7db --- /dev/null +++ b/src/wp-atom.php @@ -0,0 +1,12 @@ + diff --git a/src/wp-blog-header.php b/src/wp-blog-header.php new file mode 100644 index 00000000..0f7118f3 --- /dev/null +++ b/src/wp-blog-header.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/src/wp-comments-post.php b/src/wp-comments-post.php new file mode 100644 index 00000000..9c17a355 --- /dev/null +++ b/src/wp-comments-post.php @@ -0,0 +1,105 @@ +comment_status) ) { + do_action('comment_id_not_found', $comment_post_ID); + exit; +} + +// get_post_status() will get the parent status for attachments. +$status = get_post_status($post); + +$status_obj = get_post_status_object($status); + +if ( !comments_open($comment_post_ID) ) { + do_action('comment_closed', $comment_post_ID); + wp_die( __('Sorry, comments are closed for this item.') ); +} elseif ( 'trash' == $status ) { + do_action('comment_on_trash', $comment_post_ID); + exit; +} elseif ( !$status_obj->public && !$status_obj->private ) { + do_action('comment_on_draft', $comment_post_ID); + exit; +} elseif ( post_password_required($comment_post_ID) ) { + do_action('comment_on_password_protected', $comment_post_ID); + exit; +} else { + do_action('pre_comment_on_post', $comment_post_ID); +} + +$comment_author = ( isset($_POST['author']) ) ? trim(strip_tags($_POST['author'])) : null; +$comment_author_email = ( isset($_POST['email']) ) ? trim($_POST['email']) : null; +$comment_author_url = ( isset($_POST['url']) ) ? trim($_POST['url']) : null; +$comment_content = ( isset($_POST['comment']) ) ? trim($_POST['comment']) : null; + +// If the user is logged in +$user = wp_get_current_user(); +if ( $user->ID ) { + if ( empty( $user->display_name ) ) + $user->display_name=$user->user_login; + $comment_author = $wpdb->escape($user->display_name); + $comment_author_email = $wpdb->escape($user->user_email); + $comment_author_url = $wpdb->escape($user->user_url); + if ( current_user_can('unfiltered_html') ) { + if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) { + kses_remove_filters(); // start with a clean slate + kses_init_filters(); // set up the filters + } + } +} else { + if ( get_option('comment_registration') || 'private' == $status ) + wp_die( __('Sorry, you must be logged in to post a comment.') ); +} + +$comment_type = ''; + +if ( get_option('require_name_email') && !$user->ID ) { + if ( 6 > strlen($comment_author_email) || '' == $comment_author ) + wp_die( __('Error: please fill the required fields (name, email).') ); + elseif ( !is_email($comment_author_email)) + wp_die( __('Error: please enter a valid email address.') ); +} + +if ( '' == $comment_content ) + wp_die( __('Error: please type a comment.') ); + +$comment_parent = isset($_POST['comment_parent']) ? absint($_POST['comment_parent']) : 0; + +$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID'); + +$comment_id = wp_new_comment( $commentdata ); + +$comment = get_comment($comment_id); +if ( !$user->ID ) { + $comment_cookie_lifetime = apply_filters('comment_cookie_lifetime', 30000000); + setcookie('comment_author_' . COOKIEHASH, $comment->comment_author, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); + setcookie('comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); + setcookie('comment_author_url_' . COOKIEHASH, esc_url($comment->comment_author_url), time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); +} + +$location = empty($_POST['redirect_to']) ? get_comment_link($comment_id) : $_POST['redirect_to'] . '#comment-' . $comment_id; +$location = apply_filters('comment_post_redirect', $location, $comment); + +wp_redirect($location); +exit; +?> diff --git a/src/wp-commentsrss2.php b/src/wp-commentsrss2.php new file mode 100644 index 00000000..280766ed --- /dev/null +++ b/src/wp-commentsrss2.php @@ -0,0 +1,12 @@ + diff --git a/src/wp-config-sample.php b/src/wp-config-sample.php new file mode 100644 index 00000000..d1cea2cd --- /dev/null +++ b/src/wp-config-sample.php @@ -0,0 +1,89 @@ + diff --git a/src/wp-config.php b/src/wp-config.php new file mode 100644 index 00000000..167109ef --- /dev/null +++ b/src/wp-config.php @@ -0,0 +1,89 @@ +q-8@NU:)A]fkgP$=X9`fEJ`*9apv$)MfVIom'); // Cambia esto por tu frase aleatoria. +define('LOGGED_IN_KEY', 'y{%hur59RTvu`J2C# DWttr9Nw}%!Q6V[U`NdI 2g%sV*kf3j=s]5z@GCT<>E) e'); // Cambia esto por tu frase aleatoria. +define('NONCE_KEY', 'z*5@v0}JQnOhe/laI-j9t}m5xle.)hU+ymgGmnJ^0~s3gUbzcdhYO*XC5Yf=rfc*'); // Cambia esto por tu frase aleatoria. +define('AUTH_SALT', 'F5a|uVPGZN{wMWQ:#u,0^1hp9D,.4E3nVQ@K1g@?bL[$5iLuxW5|HiV+c#4FQfL-'); // Cambia esto por tu frase aleatoria. +define('SECURE_AUTH_SALT', '-p([(F/_ZLk&S(`7FC,+Xt,}Kn3>;3#4;lS`w1SD_,7kCWHj[lN5=O,jt1m60w&r'); // Cambia esto por tu frase aleatoria. +define('LOGGED_IN_SALT', '+Uek5]*(SK6guW+k#VZSs[FZ=%2I(!]Ee2`6#ip;2zsiLap}WQ.}[boBOY[I@+4]'); // Cambia esto por tu frase aleatoria. +define('NONCE_SALT', '!VHTa^.ANo}];+mLT587VqJ?S+XLR]QvKy-2UaEz#q-U(d5V&,u43?Qi_w<-S4#a'); // Cambia esto por tu frase aleatoria. +/**#@-*/ + +/** + * Prefijo de la base de datos de WordPress. + * + * Cambia el prefijo si deseas instalar multiples blogs en una sola base de datos. + * Emplea solo números, letras y guión bajo. + */ +$table_prefix = 'wp_'; + +/** + * Idioma de WordPress. + * + * Cambia lo siguiente para tener WordPress en tu idioma. El correspondiente archivo MO + * del lenguaje elegido debe encontrarse en wp-content/languages. + * Por ejemplo, instala ca_ES.mo copiándolo a wp-content/languages y define WPLANG como 'ca_ES' + * para traducir WordPress al catalán. + */ +define ('WPLANG', 'es_ES'); + +/** + * Para desarrolladores: modo debug de WordPress. + * + * Cambia esto a true para activar la muestra de avisos durante el desarrollo. + * Se recomienda encarecidamente a los desarrolladores de temas y plugins que usen WP_DEBUG + * en sus entornos de desarrollo. + */ +define('WP_DEBUG', false); + +/* ¡Eso es todo, deja de editar! Feliz blogging */ + +/** WordPress absolute path to the Wordpress directory. */ +if ( !defined('ABSPATH') ) + define('ABSPATH', dirname(__FILE__) . '/'); + +/** Sets up WordPress vars and included files. */ +require_once(ABSPATH . 'wp-settings.php'); +?> diff --git a/src/wp-content/index.php b/src/wp-content/index.php new file mode 100644 index 00000000..4e6c07c7 --- /dev/null +++ b/src/wp-content/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/wp-content/languages/es_ES.mo b/src/wp-content/languages/es_ES.mo new file mode 100644 index 00000000..cb669910 Binary files /dev/null and b/src/wp-content/languages/es_ES.mo differ diff --git a/src/wp-content/languages/es_ES.po b/src/wp-content/languages/es_ES.po new file mode 100644 index 00000000..f36a2aa4 --- /dev/null +++ b/src/wp-content/languages/es_ES.po @@ -0,0 +1,13890 @@ +# Translation of 3.1.x in Spanish (Spain) +# This file is distributed under the same license as the 3.1.x package. +msgid "" +msgstr "" +"PO-Revision-Date: 2011-05-25 19:11:07+0000\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: GlotPress/0.1\n" +"Project-Id-Version: 3.1.x\n" + +#: wp-admin/includes/nav-menu.php:136 +msgid "Title Attribute" +msgstr "Atributos del título" + +#: wp-admin/includes/nav-menu.php:142 wp-admin/includes/nav-menu.php:1106 +msgid "Link Target" +msgstr "Destino del enlace" + +#: wp-admin/includes/nav-menu.php:144 +msgid "Same window or tab" +msgstr "Misma ventana o pestaña" + +#: wp-admin/includes/nav-menu.php:145 +msgid "New window or tab" +msgstr "Nueva ventana o pestaña" + +#: wp-admin/includes/nav-menu.php:151 +msgid "CSS Classes (optional)" +msgstr "Clases CSS (opcional)" + +#: wp-admin/includes/nav-menu.php:165 +msgid "The description will be displayed in the menu if the current theme supports it." +msgstr "La descripción se mostrará en los menús si el tema actual lo soporta." + +#: wp-admin/includes/nav-menu.php:172 +msgid "Original: %s" +msgstr "Original: %s" + +#: wp-admin/includes/nav-menu.php:367 +msgid "Theme Locations" +msgstr "Ubicación del tema" + +#: wp-admin/includes/nav-menu.php:368 +msgid "Custom Links" +msgstr "Enlaces personalizados" + +#: wp-admin/includes/nav-menu.php:464 wp-admin/nav-menus.php:450 +msgid "The current theme does not natively support menus, but you can use the “Custom Menu” widget to add any menus you create here to the theme’s sidebar." +msgstr "El tema actual no soporta menús de forma nativa, pero puedes usar el widget “Menús personalizados” para añadir los menús que has creado a la barra lateral de tu tema." + +#: wp-admin/includes/nav-menu.php:473 +msgid "Your theme supports %s menu. Select which menu you would like to use." +msgid_plural "Your theme supports %s menus. Select which menu appears in each location." +msgstr[0] "Tu tema soporta %s menú. Selecciona qué menú quieres utilizar." +msgstr[1] "Tu tema soporta %s menús. Selecciona qué menú quieres utilizar en cada posición." + +#: wp-admin/includes/nav-menu.php:538 +msgid "Label" +msgstr "Etiqueta" + +#: wp-admin/includes/nav-menu.php:539 +msgid "Menu Item" +msgstr "Elemento del menú" + +#: wp-admin/includes/nav-menu.php:546 wp-admin/includes/nav-menu.php:760 +#: wp-admin/includes/nav-menu.php:932 +msgid "Add to Menu" +msgstr "Añadir al menú" + +#: wp-admin/includes/nav-menu.php:590 wp-admin/includes/nav-menu.php:802 +msgid "No items." +msgstr "Sin elementos." + +#: wp-admin/includes/nav-menu.php:640 +msgid "Most Recent" +msgstr "Más reciente" + +#: wp-admin/includes/nav-menu.php:641 wp-admin/includes/nav-menu.php:848 +msgid "View All" +msgstr "Ver todo" + +#: wp-admin/includes/nav-menu.php:685 wp-admin/includes/nav-menu.php:912 +#: wp-content/plugins/akismet/legacy.php:340 +msgid "No results found." +msgstr "Sin resultados." + +#: wp-admin/includes/nav-menu.php:709 +msgctxt "nav menu front page title" +msgid "Home: %s" +msgstr "Inicio: %s" + +#: wp-admin/includes/nav-menu.php:719 +msgctxt "nav menu home label" +msgid "Home" +msgstr "Inicio" + +#: wp-admin/includes/nav-menu.php:847 wp-admin/includes/meta-boxes.php:328 +#: wp-admin/includes/meta-boxes.php:658 wp-admin/press-this.php:528 +msgid "Most Used" +msgstr "Más utilizadas" + +#: wp-admin/includes/nav-menu.php:1062 +msgid "Select menu items (pages, categories, links) from the boxes at left to begin building your custom menu." +msgstr "Selecciona elementos de menú (páginas, categorías, enlaces) de la caja de la izquierda para comenzar a construir tu propio menú." + +#: wp-admin/includes/nav-menu.php:1073 +msgid "The Walker class named %s does not exist." +msgstr "La clase Walker para el nombre %s no existe." + +#: wp-admin/includes/nav-menu.php:1082 +msgid "Click Save Menu to make pending menu items public." +msgstr "Haz click en Guardar menú para hacer públicos los elementos de menú pendientes." + +#: wp-admin/includes/nav-menu.php:1104 +msgid "Show advanced menu properties" +msgstr "Mostrar propiedades avanzadas de menú" + +#: wp-admin/includes/nav-menu.php:1107 +msgid "CSS Classes" +msgstr "Clases CSS" + +#: wp-admin/includes/plugin.php:92 +msgid "The %1$s plugin header is deprecated. Use %2$s instead." +msgstr "La cabecera del plugin %1$s es obsoleta. Usa %2$s en su lugar." + +#: wp-admin/includes/plugin.php:136 +msgid "Visit plugin homepage" +msgstr "Visitar la web del plugin" + +#: wp-admin/includes/plugin.php:394 +msgid "Advanced caching plugin." +msgstr "Plugin avanzado de caché." + +#: wp-admin/includes/plugin.php:395 +msgid "Custom database class." +msgstr "Clase de base datos personalizada." + +#: wp-admin/includes/plugin.php:396 +msgid "Custom database error message." +msgstr "Mensaje de error de base de datos personalizado." + +#: wp-admin/includes/plugin.php:397 +msgid "Custom install script." +msgstr "Script personalizado de instalación." + +#: wp-admin/includes/plugin.php:398 +msgid "Custom maintenance message." +msgstr "Mensaje personalizado de mantenimiento." + +#: wp-admin/includes/plugin.php:399 +msgid "External object cache." +msgstr "Caché de objetos externos." + +#: wp-admin/includes/plugin.php:403 +msgid "Executed before Multisite is loaded." +msgstr "Ejecutado antes de cargar el Multisitio." + +#: wp-admin/includes/plugin.php:404 +msgid "Custom site deleted message." +msgstr "Mensaje personalizado para sitios eliminados." + +#: wp-admin/includes/plugin.php:405 +msgid "Custom site inactive message." +msgstr "Mensaje personalizado para sitios inactivos." + +#: wp-admin/includes/plugin.php:406 +msgid "Custom site suspended message." +msgstr "Mensaje personalizado para sitios suspendidos." + +#: wp-admin/includes/plugin.php:544 +msgid "The plugin generated unexpected output." +msgstr "El plugin ha generado una respuesta insesperada." + +#: wp-admin/includes/plugin.php:632 +msgid "One of the plugins is invalid." +msgstr "Uno de los plugins no es válido." + +#: wp-admin/includes/plugin.php:718 +msgid "Could not fully remove the plugin(s) %s." +msgstr "No se pudo/ieron eliminar completamente el/los plugin/s %s." + +#: wp-admin/includes/plugin.php:779 +msgid "Invalid plugin path." +msgstr "La ruta del plugin no es válida." + +#: wp-admin/includes/plugin.php:781 +msgid "Plugin file does not exist." +msgstr "El archivo del plugin no existe." + +#: wp-admin/includes/plugin.php:785 +msgid "The plugin does not have a valid header." +msgstr "El plugin no tiene una cabecera válida." + +#: wp-admin/includes/class-wp-filesystem-ftpext.php:28 +msgid "The ftp PHP extension is not available" +msgstr "La extensión PHP de FTP no está disponible." + +#: wp-admin/includes/class-wp-media-list-table.php:57 +msgctxt "uploaded files" +msgid "All (%s)" +msgid_plural "All (%s)" +msgstr[0] "Todo (%s)" +msgstr[1] "Todos (%s)" + +#: wp-admin/includes/class-wp-media-list-table.php:69 +msgctxt "detached files" +msgid "Unattached (%s)" +msgid_plural "Unattached (%s)" +msgstr[0] "Sin adjuntar (%s)" +msgstr[1] "Sin adjuntar (%s)" + +#: wp-admin/includes/class-wp-media-list-table.php:72 +msgctxt "uploaded files" +msgid "Trash (%s)" +msgid_plural "Trash (%s)" +msgstr[0] "Papelera (%s)" +msgstr[1] "Papelera (%s)" + +#: wp-admin/includes/class-wp-media-list-table.php:81 +msgid "Attach to a post" +msgstr "Adjuntar a una entrada" + +#: wp-admin/includes/class-wp-media-list-table.php:100 +msgid "Scan for lost attachments" +msgstr "Buscar adjuntos perdidos" + +#: wp-admin/includes/class-wp-media-list-table.php:126 +msgid "No media attachments found." +msgstr "No se han encontrado adjuntos." + +#: wp-admin/includes/class-wp-media-list-table.php:134 +msgctxt "column name" +msgid "File" +msgstr "Archivo" + +#: wp-admin/includes/class-wp-media-list-table.php:139 +msgctxt "column name" +msgid "Attached to" +msgstr "Adjunto a" + +#: wp-admin/includes/class-wp-media-list-table.php:143 +msgctxt "column name" +msgid "Date" +msgstr "Fecha" + +#: wp-admin/includes/class-wp-media-list-table.php:272 +msgid "%s from now" +msgstr "%s desde ahora" + +#: wp-admin/includes/class-wp-media-list-table.php:297 +msgid "(Unattached)" +msgstr "(Sin adjuntar)" + +#: wp-admin/includes/class-wp-media-list-table.php:298 +#: wp-admin/includes/class-wp-media-list-table.php:347 +msgid "Attach" +msgstr "Adjuntar" + +#: wp-admin/includes/post.php:52 +msgid "You are not allowed to edit pages as this user." +msgstr "No tienes autorización para editar páginas con este nombre de usuario." + +#: wp-admin/includes/post.php:53 +msgid "You are not allowed to create pages as this user." +msgstr "No tienes autorización para crear páginas con ese nombre de usuario." + +#: wp-admin/includes/post.php:57 +msgid "You are not allowed to edit posts as this user." +msgstr "No tienes autorización para editar entradas con este nombre de usuario." + +#: wp-admin/includes/post.php:58 +msgid "You are not allowed to post as this user." +msgstr "No tienes autorización para publicar con este nombre de usuario." + +#: wp-admin/includes/post.php:272 +msgid "You are not allowed to edit pages." +msgstr "No tienes autorización para editar páginas." + +#: wp-admin/includes/post.php:274 +msgid "You are not allowed to edit posts." +msgstr "No tienes autorización para editar entradas." + +#: wp-admin/includes/post.php:409 +msgid "Auto Draft" +msgstr "Borrador automático" + +#: wp-admin/includes/post.php:530 +msgid "You are not allowed to create pages on this site." +msgstr "No tienes autorización para crear páginas en este sitio." + +#: wp-admin/includes/post.php:532 +msgid "You are not allowed to create posts or drafts on this site." +msgstr "No tienes autorización para crear entradas o borradores en este sitio." + +#: wp-admin/includes/post.php:961 +msgid "Images" +msgstr "Imágenes" + +#: wp-admin/includes/post.php:961 +msgid "Manage Images" +msgstr "Administrar imágenes" + +#: wp-admin/includes/post.php:961 +msgid "Image (%s)" +msgid_plural "Images (%s)" +msgstr[0] "Imagen (%s)" +msgstr[1] "Imágenes (%s)" + +#: wp-admin/includes/post.php:962 +msgid "Audio" +msgstr "Audio" + +#: wp-admin/includes/post.php:962 +msgid "Manage Audio" +msgstr "Administrar audio" + +#: wp-admin/includes/post.php:962 +msgid "Audio (%s)" +msgid_plural "Audio (%s)" +msgstr[0] "Audio (%s)" +msgstr[1] "Audio (%s)" + +#: wp-admin/includes/post.php:963 +msgid "Video" +msgstr "Vídeo" + +#: wp-admin/includes/post.php:963 +msgid "Manage Video" +msgstr "Administrar vídeo" + +#: wp-admin/includes/post.php:963 +msgid "Video (%s)" +msgid_plural "Video (%s)" +msgstr[0] "Vídeo (%s)" +msgstr[1] "Vídeos (%s)" + +#: wp-admin/includes/post.php:1138 +msgid "Click to edit this part of the permalink" +msgstr "Haz clic para editar esta parte del enlace permanente" + +#: wp-admin/includes/post.php:1140 +msgid "Temporary permalink. Click to edit this part." +msgstr "Enlace permanente temporal. Haz clic para editar esta parte." + +#: wp-admin/includes/post.php:1144 wp-admin/includes/post.php:1172 +msgid "Permalink:" +msgstr "Enlace permanente:" + +#: wp-admin/includes/post.php:1146 +msgid "Change Permalinks" +msgstr "Enlaces permanentes" + +#: wp-admin/includes/post.php:1195 wp-admin/includes/post.php:1196 +msgid "Set featured image" +msgstr "Establecer la imagen destacada" + +#: wp-admin/includes/post.php:1208 +msgid "Remove featured image" +msgstr "Quitar la imagen destacada" + +#: wp-admin/includes/post.php:1278 +msgid "Warning: %s is currently editing this post" +msgstr "Atención: %s está editando actualmente esta entrada" + +#: wp-admin/includes/post.php:1281 +msgid "Warning: %s is currently editing this page" +msgstr "Atención: %s está editando actualmente esta página" + +#: wp-admin/includes/post.php:1284 +msgid "Warning: %s is currently editing this." +msgstr "Atención: %s está editando actualmente esto." + +#: wp-admin/includes/post.php:1342 +msgid "Preview not available. Please save as a draft first." +msgstr "Vista previa no disponible. Por favor, guarda antes el borrador." + +#: wp-admin/includes/schema.php:200 +msgid "My Site" +msgstr "Mi sitio" + +#: wp-admin/includes/schema.php:202 +msgid "Just another WordPress site" +msgstr "Otro sitio realizado con WordPress" + +#: wp-admin/includes/schema.php:227 +msgid "F j, Y g:i a" +msgstr "j F, Y G:i" + +#: wp-admin/includes/schema.php:329 +msgid "Just another %s site" +msgstr "Otro sitio más de %s" + +#: wp-admin/includes/schema.php:397 +msgctxt "User role" +msgid "Administrator" +msgstr "Administrador" + +#: wp-admin/includes/schema.php:399 +msgctxt "User role" +msgid "Editor" +msgstr "Editor" + +#: wp-admin/includes/schema.php:401 +msgctxt "User role" +msgid "Author" +msgstr "Autor" + +#: wp-admin/includes/schema.php:403 +msgctxt "User role" +msgid "Contributor" +msgstr "Colaborador" + +#: wp-admin/includes/schema.php:405 +msgctxt "User role" +msgid "Subscriber" +msgstr "Suscriptor" + +#: wp-admin/includes/schema.php:640 +msgid "You must provide a domain name." +msgstr "Debes facilitarnos un nombre de dominio." + +#: wp-admin/includes/schema.php:642 +msgid "You must provide a name for your network of sites." +msgstr "Debes facilitarnos un nombre para tu red de sitios." + +#: wp-admin/includes/schema.php:646 +msgid "The network already exists." +msgstr "La red ya existe." + +#: wp-admin/includes/schema.php:650 +msgid "You must provide a valid e-mail address." +msgstr "Debes facilitarnos una dirección de correo electrónico válida." + +#: wp-admin/includes/schema.php:684 +msgid "" +"Dear User,\n" +"\n" +"Your new SITE_NAME site has been successfully set up at:\n" +"BLOG_URL\n" +"\n" +"You can log in to the administrator account with the following information:\n" +"Username: USERNAME\n" +"Password: PASSWORD\n" +"Login Here: BLOG_URLwp-login.php\n" +"\n" +"We hope you enjoy your new site.\n" +"Thanks!\n" +"\n" +"--The Team @ SITE_NAME" +msgstr "" +"Apreciado Usuario,\n" +"\n" +"Tu nuevo sitio en SITE_NAME ha sido configurado correctamente en:\n" +"BLOG_URL\n" +"\n" +"Puedes identificarte con tu cuenta de administrador con la siguiente información:\n" +"Nombre Usuario: USERNAME\n" +"Contraseña: PASSWORD\n" +"Accede aquí: BLOG_URLwp-login.php\n" +"\n" +"Esperamos que disfrutes de tu nuevo sitio.\n" +"¡Gracias!\n" +"\n" +"--El equipo de SITE_NAME" + +#: wp-admin/includes/schema.php:769 +msgid "Warning! Wildcard DNS may not be configured correctly!" +msgstr "¡Atención! ¡Puede que las DNS no estén configuradas correctamente." + +#: wp-admin/includes/schema.php:770 +msgid "The installer attempted to contact a random hostname (%1$s) on your domain." +msgstr "El instalador ha tratado de contactar con un servidor aleatorio (%1$s) en tu dominio." + +#: wp-admin/includes/schema.php:772 +msgid "This resulted in an error message: %s" +msgstr "Esto ha dado como resultado un mensaje de error: %s" + +#: wp-admin/includes/schema.php:774 +msgid "To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a * hostname record pointing at your web server in your DNS configuration tool." +msgstr "Para hacer uso de la configuración en subdominios debes tener una entrada de registro wildcard en tu DNS. Normalmente esto se consigue añadiendo el registro * en tu nombre de servidor, apuntando a tu servidor o dominio en las herramientas de configuración de tu servidor o dominio." + +#: wp-admin/includes/schema.php:775 +msgid "You can still use your site but any subdomain you create may not be accessible. If you know your DNS is correct, ignore this message." +msgstr "Puedes continuar usando tu sitio, pero ningún subdominio que crees será accesible. Si sabes que tu configuración de DNS es correcta, ignora este mensaje." + +#: wp-admin/includes/class-wp-links-list-table.php:42 +msgid "No links found." +msgstr "No se encontraron enlaces." + +#: wp-admin/includes/class-wp-links-list-table.php:83 +msgid "Relationship" +msgstr "Relación con el enlace (XFN)" + +#: wp-admin/includes/class-wp-links-list-table.php:84 +msgid "Visible" +msgstr "Visible" + +#: wp-admin/includes/class-wp-links-list-table.php:85 +#: wp-admin/includes/meta-boxes.php:890 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:143 +msgid "Rating" +msgstr "Valoración" + +#: wp-admin/includes/class-wp-links-list-table.php:140 +#: wp-admin/includes/meta-boxes.php:628 +msgid "" +"You are about to delete this link '%s'\n" +" 'Cancel' to stop, 'OK' to delete." +msgstr "" +"Estás a punto de borrar este enlace '%s'\n" +" 'Cancelar' para borrar, 'Aceptar' para borrarlo." + +#: wp-admin/includes/class-wp-links-list-table.php:146 +msgid "Visit %s" +msgstr "Visitar %s" + +#: wp-admin/includes/theme.php:93 +msgid "Unable to locate WordPress theme directory." +msgstr "Ha sido imposible localizar el directorio de temas de WordPress." + +#: wp-admin/includes/theme.php:100 +msgid "Could not fully remove the theme %s." +msgstr "No se pudo eliminar completamente el tema %s." + +#: wp-admin/includes/theme.php:244 +msgid "Updating this theme will lose any customizations you have made. 'Cancel' to stop, 'OK' to update." +msgstr "Al actualizar este tema se perderán todas las personalizaciones que hayas hecho. 'Cancelar' para parar, 'OK' para actualizar." + +#: wp-admin/includes/theme.php:248 +msgid "There is a new version of %1$s available. View version %3$s details." +msgstr "Hay una nueva versión de %1$s disponible. Ver detalles de la versión %3$s." + +#: wp-admin/includes/theme.php:250 +msgid "There is a new version of %1$s available. View version %3$s details. Automatic update is unavailable for this theme." +msgstr "Hay una nueva versión de %1$s disponible. Ver detalles de la versión %3$s. La actualización automática no está disponible para este tema." + +#: wp-admin/includes/theme.php:252 +msgid "There is a new version of %1$s available. View version %3$s details or update automatically." +msgstr "Hay una nueva versión de %1$s disponible. Ver detalles de la versión %3$s o actualizar automáticamente." + +#: wp-admin/includes/theme.php:267 wp-admin/includes/theme.php:339 +msgid "Colors" +msgstr "Colores" + +#: wp-admin/includes/theme.php:268 +msgid "Black" +msgstr "Negro" + +#: wp-admin/includes/theme.php:270 +msgid "Brown" +msgstr "Marrón" + +#: wp-admin/includes/theme.php:271 +msgid "Green" +msgstr "Verde" + +#: wp-admin/includes/theme.php:272 +msgid "Orange" +msgstr "Naranja" + +#: wp-admin/includes/theme.php:273 +msgid "Pink" +msgstr "Rosa" + +#: wp-admin/includes/theme.php:274 +msgid "Purple" +msgstr "Púrpura" + +#: wp-admin/includes/theme.php:275 +msgid "Red" +msgstr "Rojo" + +#: wp-admin/includes/theme.php:276 +msgid "Silver" +msgstr "Gris" + +#: wp-admin/includes/theme.php:277 +msgid "Tan" +msgstr "Café" + +#: wp-admin/includes/theme.php:278 +msgid "White" +msgstr "Blanco" + +#: wp-admin/includes/theme.php:279 +msgid "Yellow" +msgstr "Amarillo" + +#: wp-admin/includes/theme.php:280 +msgid "Dark" +msgstr "Negro" + +#: wp-admin/includes/theme.php:281 +msgid "Light " +msgstr "Brillante" + +#: wp-admin/includes/theme.php:284 wp-admin/includes/theme.php:339 +msgid "Columns" +msgstr "Columnas" + +#: wp-admin/includes/theme.php:285 +msgid "One Column" +msgstr "Una columna" + +#: wp-admin/includes/theme.php:286 +msgid "Two Columns" +msgstr "Dos columnas" + +#: wp-admin/includes/theme.php:287 +msgid "Three Columns" +msgstr "Tres columnas" + +#: wp-admin/includes/theme.php:288 +msgid "Four Columns" +msgstr "Cuatro columnas" + +#: wp-admin/includes/theme.php:289 +msgid "Left Sidebar" +msgstr "Barra lateral izquierda" + +#: wp-admin/includes/theme.php:290 +msgid "Right Sidebar" +msgstr "Barra lateral derecha" + +#: wp-admin/includes/theme.php:294 +msgid "Fixed Width" +msgstr "Ancho fijo" + +#: wp-admin/includes/theme.php:295 +msgid "Flexible Width" +msgstr "Ancho flexible" + +#: wp-admin/includes/theme.php:298 wp-admin/includes/theme.php:340 +msgid "Features" +msgstr "Características" + +#: wp-admin/includes/theme.php:300 +msgid "BuddyPress" +msgstr "BuddyPress" + +#: wp-admin/includes/theme.php:302 +msgid "Custom Colors" +msgstr "Colores personalizados" + +#: wp-admin/includes/theme.php:305 +msgid "Editor Style" +msgstr "Estilo del editor" + +#: wp-admin/includes/theme.php:306 +msgid "Front Page Posting" +msgstr "Escritura en la página principal" + +#: wp-admin/includes/theme.php:307 +msgid "Microformats" +msgstr "Microformatos" + +#: wp-admin/includes/theme.php:308 +msgid "Sticky Post" +msgstr "Entrada fija" + +#: wp-admin/includes/theme.php:309 +msgid "Theme Options" +msgstr "Opciones del tema" + +#: wp-admin/includes/theme.php:310 +msgid "Threaded Comments" +msgstr "Comentarios anidados" + +#: wp-admin/includes/theme.php:311 +msgid "Translation Ready" +msgstr "Traducción lista" + +#: wp-admin/includes/theme.php:312 +msgid "RTL Language Support" +msgstr "Soporte del lenguaje RTL" + +#: wp-admin/includes/theme.php:315 wp-admin/includes/theme.php:340 +msgid "Subject" +msgstr "Asunto" + +#: wp-admin/includes/theme.php:316 +msgid "Holiday" +msgstr "Vacaciones" + +#: wp-admin/includes/theme.php:317 +msgid "Photoblogging" +msgstr "Fotoblogging" + +#: wp-admin/includes/theme.php:318 +msgid "Seasonal" +msgstr "Estacional" + +#: wp-admin/includes/meta-boxes.php:42 +msgid "Preview Changes" +msgstr "Vista previa de los cambios" + +#: wp-admin/includes/meta-boxes.php:111 +msgid "Visibility:" +msgstr "Visibilidad:" + +#: wp-admin/includes/meta-boxes.php:142 +msgid "Stick this post to the front page" +msgstr "Fijar esta entrada en la página principal" + +#: wp-admin/includes/meta-boxes.php:162 +msgid "Scheduled for: %1$s" +msgstr "Programada para:%1$s" + +#: wp-admin/includes/meta-boxes.php:164 +msgid "Published on: %1$s" +msgstr "Publicada el: %1$s" + +#: wp-admin/includes/meta-boxes.php:166 wp-admin/includes/meta-boxes.php:174 +msgid "Publish immediately" +msgstr "Publicar inmediatamente" + +#: wp-admin/includes/meta-boxes.php:168 +msgid "Schedule for: %1$s" +msgstr "Programar para:%1$s" + +#: wp-admin/includes/meta-boxes.php:170 +msgid "Publish on: %1$s" +msgstr "Publicar el: %1$s" + +#: wp-admin/includes/meta-boxes.php:352 wp-admin/press-this.php:550 +msgid "+ %s" +msgstr "+ %s" + +#: wp-admin/includes/meta-boxes.php:384 +msgid "Excerpts are optional hand-crafted summaries of your content that can be used in your theme. Learn more about manual excerpts." +msgstr "Los extractos son resúmenes opcionales de tu contenido hechos \"ex-profeso\" que puedes usar en tu tema. Aprende algo acerca de los extractos manuales." + +#: wp-admin/includes/meta-boxes.php:399 +msgid "Already pinged:" +msgstr "Pingbacks enviados:" + +#: wp-admin/includes/meta-boxes.php:408 +msgid "Send trackbacks to:" +msgstr "Enviar trackbacks a:" + +#: wp-admin/includes/meta-boxes.php:408 +msgid "Separate multiple URLs with spaces" +msgstr "Separar varias URLs con espacios" + +#: wp-admin/includes/meta-boxes.php:409 +msgid "Trackbacks are a way to notify legacy blog systems that you’ve linked to them. If you link other WordPress sites they’ll be notified automatically using pingbacks, no other action necessary." +msgstr "Los trackbacks son un modo de avisar a sistemas antiguos de que les has enlazado. Si enlazas a otros sitios creados con WordPress recibirán un aviso automático gracias a los pingbacks, sin tener que hacer nada." + +#: wp-admin/includes/meta-boxes.php:432 +msgid "Custom fields can be used to add extra metadata to a post that you can use in your theme." +msgstr "Los campos personalizados se pueden usar para añadir metadatos adicionales a una entrada y luego mostrarlos en tu tema. ." + +#: wp-admin/includes/meta-boxes.php:448 +msgid "Allow comments." +msgstr "Permitir comentarios." + +#: wp-admin/includes/meta-boxes.php:449 +msgid "Allow trackbacks and pingbacks on this page." +msgstr "Permitir trackbacks y pingbacks en esta página." + +#: wp-admin/includes/meta-boxes.php:449 +msgid "http://codex.wordpress.org/Introduction_to_Blogging#Managing_Comments" +msgstr "http://codex.wordpress.org/Introduction_to_Blogging#Managing_Comments" + +#: wp-admin/includes/meta-boxes.php:490 +msgid "Show comments" +msgstr "Mostrar comentarios" + +#: wp-admin/includes/meta-boxes.php:560 +msgid "(no parent)" +msgstr "(sin superior)" + +#: wp-admin/includes/meta-boxes.php:581 +msgid "Need help? Use the Help tab in the upper right of your screen." +msgstr "¿Necesitas ayuda? Usa la pestaña Ayuda en la parte superior derecha de la pantalla." + +#: wp-admin/includes/meta-boxes.php:609 +msgid "Visit Link" +msgstr "Visitar enlace" + +#: wp-admin/includes/meta-boxes.php:617 +msgid "Keep this link private" +msgstr "Mantener este enlace como privado" + +#: wp-admin/includes/meta-boxes.php:679 wp-admin/includes/meta-boxes.php:681 +msgid "+ Add New Category" +msgstr "+ Añadir categoría nueva " + +#: wp-admin/includes/meta-boxes.php:682 +msgid "New category name" +msgstr "Nombre nueva categoría" + +#: wp-admin/includes/meta-boxes.php:703 +msgid "_blank — new window or tab." +msgstr "_blank — nueva ventana o pestaña." + +#: wp-admin/includes/meta-boxes.php:706 +msgid "_top — current window or tab, with no frames." +msgstr "_top — ventana o pestaña actual, sin marcos." + +#: wp-admin/includes/meta-boxes.php:709 +msgid "_none — same window or tab." +msgstr "_none — misma ventana o pestaña." + +#: wp-admin/includes/meta-boxes.php:711 +msgid "Choose the target frame for your link." +msgstr "Ellige el marco de destino para tu enlace." + +#: wp-admin/includes/meta-boxes.php:758 +msgid "rel:" +msgstr "rel:" + +#: wp-admin/includes/meta-boxes.php:765 wp-admin/includes/meta-boxes.php:766 +msgid "identity" +msgstr "identidad" + +#: wp-admin/includes/meta-boxes.php:769 +msgid "another web address of mine" +msgstr "otra dirección web mía" + +#: wp-admin/includes/meta-boxes.php:773 wp-admin/includes/meta-boxes.php:774 +msgid "friendship" +msgstr "amistad" + +#: wp-admin/includes/meta-boxes.php:776 +msgid "contact" +msgstr "contacto" + +#: wp-admin/includes/meta-boxes.php:778 +msgid "acquaintance" +msgstr "conocido" + +#: wp-admin/includes/meta-boxes.php:780 +msgid "friend" +msgstr "amigo" + +#: wp-admin/includes/meta-boxes.php:782 wp-admin/includes/meta-boxes.php:815 +#: wp-admin/includes/meta-boxes.php:838 +msgid "none" +msgstr "ninguno" + +#: wp-admin/includes/meta-boxes.php:786 wp-admin/includes/meta-boxes.php:787 +msgid "physical" +msgstr "físico" + +#: wp-admin/includes/meta-boxes.php:790 +msgid "met" +msgstr "conocido en persona" + +#: wp-admin/includes/meta-boxes.php:794 wp-admin/includes/meta-boxes.php:795 +msgid "professional" +msgstr "profesional" + +#: wp-admin/includes/meta-boxes.php:798 +msgid "co-worker" +msgstr "compañero de trabajo" + +#: wp-admin/includes/meta-boxes.php:801 +msgid "colleague" +msgstr "colega" + +#: wp-admin/includes/meta-boxes.php:805 wp-admin/includes/meta-boxes.php:806 +msgid "geographical" +msgstr "geográfico" + +#: wp-admin/includes/meta-boxes.php:809 +msgid "co-resident" +msgstr "co-residente" + +#: wp-admin/includes/meta-boxes.php:812 +msgid "neighbor" +msgstr "vecino" + +#: wp-admin/includes/meta-boxes.php:819 wp-admin/includes/meta-boxes.php:820 +msgid "family" +msgstr "familia" + +#: wp-admin/includes/meta-boxes.php:823 +msgid "child" +msgstr "hija/o" + +#: wp-admin/includes/meta-boxes.php:826 +msgid "kin" +msgstr "pariente" + +#: wp-admin/includes/meta-boxes.php:829 +msgid "parent" +msgstr "padre/madre" + +#: wp-admin/includes/meta-boxes.php:832 +msgid "sibling" +msgstr "hermano/a" + +#: wp-admin/includes/meta-boxes.php:835 +msgid "spouse" +msgstr "cónyuge" + +#: wp-admin/includes/meta-boxes.php:842 wp-admin/includes/meta-boxes.php:843 +msgid "romantic" +msgstr "romántica" + +#: wp-admin/includes/meta-boxes.php:846 +msgid "muse" +msgstr "inspiración" + +#: wp-admin/includes/meta-boxes.php:849 +msgid "crush" +msgstr "flechazo" + +#: wp-admin/includes/meta-boxes.php:852 +msgid "date" +msgstr "fecha" + +#: wp-admin/includes/meta-boxes.php:855 +msgid "sweetheart" +msgstr "pareja" + +#: wp-admin/includes/meta-boxes.php:862 +msgid "If the link is to a person, you can specify your relationship with them using the above form. If you would like to learn more about the idea check out XFN." +msgstr "Si el enlace es a una persona, puedes especificar tu relación con ella utilizando el formulario de arriba. Si deseas aprender más acerca de cómo funciona esto revisa el XFN." + +#: wp-admin/includes/meta-boxes.php:878 +msgid "Image Address" +msgstr "Dirección de la imagen" + +#: wp-admin/includes/meta-boxes.php:882 +msgid "RSS Address" +msgstr "Dirección RSS" + +#: wp-admin/includes/meta-boxes.php:886 +msgid "Notes" +msgstr "Notas" + +#: wp-admin/includes/meta-boxes.php:899 +msgid "(Leave at 0 for no rating.)" +msgstr "(Dejalo en 0 para no valorar.)" + +#: wp-admin/includes/menu.php:210 +msgid "You do not have sufficient permissions to access this page." +msgstr "No tienes suficientes permisos para acceder a esta página" + +#: wp-admin/includes/update.php:103 +msgid "You are using a development version (%1$s). Cool! Please stay updated." +msgstr "Estás usando una versión en desarrollo (%1$s). ¡Mola! Por favor, mantente actualizado." + +#: wp-admin/includes/update.php:107 +msgid "Get Version %2$s" +msgstr "Descargar versión %2$s" + +#: wp-admin/includes/update.php:133 +msgid "WordPress %1$s is available! Please update now." +msgstr "¡WordPress %1$s está disponible! Por favor, actualiza ahora." + +#: wp-admin/includes/update.php:135 +msgid "WordPress %1$s is available! Please notify the site administrator." +msgstr "¡WordPress %1$s está disponible! Por favor, avisa al administrador del sitio." + +#: wp-admin/includes/update.php:148 +msgid "You are using WordPress %s." +msgstr "Estás usando WordPress %s." + +#: wp-admin/includes/update.php:151 +msgid "Update to %s" +msgstr "Actualizar a %s" + +#: wp-admin/includes/update.php:151 +msgid "Latest" +msgstr "Última" + +#: wp-admin/includes/update.php:202 wp-admin/includes/update.php:277 +msgid "There is a new version of %1$s available. View version %4$s details." +msgstr "Hay una nueva versión de %1$s disponible. Ver detalles de la versión %4$s. " + +#: wp-admin/includes/update.php:204 wp-admin/includes/update.php:279 +msgid "There is a new version of %1$s available. View version %4$s details. Automatic update is unavailable for this plugin." +msgstr "Hay una nueva versión de %1$s disponible. Ver detalles de la versión %4$s. La actualización automática no está disponible para este plugin." + +#: wp-admin/includes/update.php:206 wp-admin/includes/update.php:281 +msgid "There is a new version of %1$s available. View version %4$s details or update automatically." +msgstr "Hay una versión nueva de %1$s disponible. Ver los detalles de la versión %4$s o actualizar automáticamente." + +#: wp-admin/includes/update.php:304 +msgid "An automated WordPress update has failed to complete - please attempt the update again now." +msgstr "No se ha podido completar la actualización automática de WordPress. Por favor, vuelve a intentarlo." + +#: wp-admin/includes/update.php:306 +msgid "An automated WordPress update has failed to complete! Please notify the site administrator." +msgstr "¡No se ha podido completar la actualización automática de WordPress! Por favor, avisa al administrador." + +#: wp-admin/includes/bookmark.php:192 +msgid "Could not update link in the database" +msgstr "No ha sido posible actualizar el enlace en la base de datos." + +#: wp-admin/includes/bookmark.php:199 +msgid "Could not insert link into the database" +msgstr "No ha sido posible insertar el enlace en la base de datos." + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:33 +msgctxt "Plugin Installer" +msgid "Featured" +msgstr "Destacados" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:34 +msgctxt "Plugin Installer" +msgid "Popular" +msgstr "Populares" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:35 +msgctxt "Plugin Installer" +msgid "Newest" +msgstr "Recientes" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:36 +msgctxt "Plugin Installer" +msgid "Recently Updated" +msgstr "Actualizados recientemente" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:97 +msgid "No plugins match your request." +msgstr "No hay plugins que mostrar." + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:192 +msgid "More information about %s" +msgstr "Más información sobre %s" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:200 +msgid "Install %s" +msgstr "Instalar %s" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:204 +msgid "Update to version %s" +msgstr "Actualizar a la versión %s" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:204 +msgid "Update Now" +msgstr "Actualizar ahora" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:208 +msgid "This plugin is already installed and is up to date" +msgstr "Este plugin ya está instalado y actualizado" + +#: wp-admin/includes/class-wp-plugin-install-list-table.php:208 +msgid "Installed" +msgstr "Instalados" + +#: wp-admin/press-this.php:132 +msgid "Embed Code" +msgstr "Incrustar código" + +#: wp-admin/press-this.php:135 +msgid "Insert Video" +msgstr "Insertar vídeo" + +#: wp-admin/press-this.php:161 +msgid "Click to insert." +msgstr "Clic para insertar." + +#: wp-admin/press-this.php:263 +msgid "Unable to retrieve images or no images on page." +msgstr "No se pueden extraer imágenes o no hay imágenes en la página." + +#: wp-admin/press-this.php:315 +msgid "click images to select" +msgstr "haz clic en las imágenes para seleccionar" + +#: wp-admin/press-this.php:315 +msgid "Add from URL" +msgstr "Añadir desde URL" + +#: wp-admin/press-this.php:315 +msgid "Refresh" +msgstr "Actualizar" + +#: wp-admin/press-this.php:425 +msgid "Loading..." +msgstr "Cargando..." + +#: wp-admin/press-this.php:507 +msgid "Post Format:" +msgstr "Formato de entrada:" + +#: wp-admin/press-this.php:544 +msgid "You cannot modify this Taxonomy." +msgstr "No puedes modificar esta taxonomía." + +#: wp-admin/press-this.php:574 wp-admin/press-this.php:578 +msgid "Post Tags" +msgstr "Etiquetas de las entradas" + +#: wp-admin/press-this.php:587 +msgid "Choose from the most used tags in Post Tags" +msgstr "Elige entre las etiquetas más populares" + +#: wp-admin/press-this.php:594 +msgid "Your post has been saved." +msgstr "Tu entrada ha sido guardada correctamente." + +#: wp-admin/press-this.php:594 +msgid "View post" +msgstr "Ver entrada" + +#: wp-admin/press-this.php:594 +msgid "Close Window" +msgstr "Cerrar ventana" + +#: wp-admin/press-this.php:609 wp-admin/press-this.php:610 +msgid "Insert an Image" +msgstr "Insertar imagen" + +#: wp-admin/press-this.php:614 +msgid "Embed a Video" +msgstr "Insertar vídeo" + +#: wp-admin/press-this.php:634 +msgid "via " +msgstr "vía " + +#: wp-admin/user/menu.php:14 wp-admin/user-edit.php:28 wp-admin/menu.php:189 +msgid "Profile" +msgstr "Perfil" + +#: wp-admin/link-add.php:13 +msgid "You do not have sufficient permissions to add links to this site." +msgstr "No tienes suficientes permisos para añadir enlaces a este sitio." + +#: wp-admin/link-add.php:15 +msgid "Add New Link" +msgstr "Añadir enlace" + +#: wp-admin/post.php:149 +msgid "You attempted to edit an item that doesn’t exist. Perhaps it was deleted?" +msgstr "Lo que intentas editar no existe. ¿Habrá sido borrado?" + +#: wp-admin/post.php:155 +msgid "You can’t edit this item because it is in the Trash. Please restore it and try again." +msgstr "No puedes editar esto ya que está en la Papelera. Sácala de la Papelera e inténtalo de nuevo." + +#: wp-admin/post.php:233 +msgid "You are not allowed to move this item out of the Trash." +msgstr "No te está permitido mover este elemento fuera de la Papelera." + +#: wp-admin/post.php:252 wp-admin/post.php:255 +msgid "Error in deleting." +msgstr "Error al eliminar." + +#: wp-admin/options-permalink.php:15 +msgid "Permalink Settings" +msgstr "Ajustes de los enlaces permanentes" + +#: wp-admin/options-permalink.php:19 +msgid "This screen provides some common options for your default permalinks URL structure." +msgstr "Esta pantalla facilita unas opciones comunes para la estructura por defecto de la URL estructural de los enlaces permanentes." + +#: wp-admin/options-permalink.php:20 +msgid "If you pick an option other than Default, your general URL path with structure tags, terms surrounded by %, will also appear in the custom structure field and your path can be further modified there." +msgstr "Si eliges una opción distinta de la que está por defecto tu ruta general de URL con etiquetas de estructura, los términos rodeados por %, también aparecerán en el campo de estructura personalizada y podrás cambiar aquí tu ruta en otro momento." + +#: wp-admin/options-permalink.php:21 +msgid "When you assign multiple categories or tags to a post, only one can show up in the permalink: the lowest numbered category. This applies if your custom structure includes %category% or %tag%." +msgstr "Cuando asignas varias categorías o etiquetas a una entrada sólo se puede mostrar una en el enlace permanente: la categoría con el número más bajo. Esto es así si tu estructura personalizada contiene %category% o %tag%." + +#: wp-admin/options-permalink.php:22 +msgid "Note that permalinks beginning with the category, tag, author or postname structure tags require more advanced server resources. Double-check your hosting details to make sure those are in place or start your permalinks with other structure tags." +msgstr "Date cuenta de que los enlaces permanentes con etiquetas estructurales que llaman a categoría, etiqueta, autor o nombre de la entrada requieren recursos de servidor más avanzados. Revisa de nuevo los detalles del alojamiento para asegurarte de que que están en su lugar o empieza tus enlaces permanentes con otras etiquetas estructurales." + +#: wp-admin/options-permalink.php:23 +msgid "The Optional fields let you customize the “category” and “tag” base names that will appear in archive URLs. For example, the page listing all posts in the “Uncategorized” category could be /topics/uncategorized instead of /category/uncategorized." +msgstr "Los campos opcionales te permiten personalizar los nombres base de “categoría” y “etiqueta” que aparecerán en las URLs del archivo. Por ejemplo, la página con el listado de todas las entradas de la categoría “Sin categoría” podrían ser como /temas/sin-categoria en vez de /category/sin-categoria." + +#: wp-admin/options-permalink.php:26 +msgid "Documentation on Permalinks Settings" +msgstr " Documentación sobre configuración de enlaces permanentes" + +#: wp-admin/options-permalink.php:27 +msgid "Documentation on Using Permalinks" +msgstr "Documentación sobre el uso de enlaces permanentes" + +#: wp-admin/options-permalink.php:133 +msgid "You should update your web.config now" +msgstr "Ahora debes actualizar tu web.config" + +#: wp-admin/options-permalink.php:135 +msgid "Permalink structure updated. Remove write access on web.config file now!" +msgstr "La estructura de enlaces permanentes se ha actualizado. Elimina el acceso de escritura en el archivo web.config ahora mismo." + +#: wp-admin/options-permalink.php:137 +msgid "Permalink structure updated" +msgstr "Estructura de enlaces permanentes actualizada" + +#: wp-admin/options-permalink.php:140 +msgid "You should update your .htaccess now." +msgstr "Ahora debes actualizar tu .htaccess" + +#: wp-admin/options-permalink.php:142 wp-admin/options-permalink.php:145 +msgid "Permalink structure updated." +msgstr "Estructura de enlaces permanentes actualizada." + +#: wp-admin/options-permalink.php:158 +msgid "By default WordPress uses web URLs which have question marks and lots of numbers in them, however WordPress offers you the ability to create a custom URL structure for your permalinks and archives. This can improve the aesthetics, usability, and forward-compatibility of your links. A number of tags are available, and here are some examples to get you started." +msgstr "Por defecto, WordPress usa URLs que tengan signos de interrogación y un montón de números. Sin embargo, WordPress ofrece la posibilidad de crear una estructura de URL para tus enlaces permanentes y archivos. Esto puede mejorar la estética, usabilidad y compatibilidad de tus enlaces. Hay disponibles ciertas etiquetas, y aquí hay algunos ejemplos para comenzar." + +#: wp-admin/options-permalink.php:174 +msgid "Common settings" +msgstr "Ajustes habituales" + +#: wp-admin/options-permalink.php:177 +msgid "Default" +msgstr "Predeterminado" + +#: wp-admin/options-permalink.php:181 +msgid "Day and name" +msgstr "Día y nombre" + +#: wp-admin/options-permalink.php:185 +msgid "Month and name" +msgstr "Mes y nombre" + +#: wp-admin/options-permalink.php:189 +msgid "Numeric" +msgstr "Numérico" + +#: wp-admin/options-permalink.php:195 +msgid "Custom Structure" +msgstr "Estructura personalizada" + +#: wp-admin/options-permalink.php:205 +msgid "Optional" +msgstr "Opcional" + +#: wp-admin/options-permalink.php:207 +msgid "If you like, you may enter custom structures for your category and tag URLs here. For example, using topics as your category base would make your category links like http://example.org/topics/uncategorized/. If you leave these blank the defaults will be used." +msgstr "Si quieres, puedes introducir estructuras personalizadas para las URLs de las categorías y etiquetas. Por ejemplo, usar secciones como categoría base mostraría tus enlaces de categoría como http://ejemplo.org/index.php/secciones/general/. Si dejas esto en blanco se usará la opción predeterminada." + +#: wp-admin/options-permalink.php:209 +msgid "If you like, you may enter custom structures for your category and tag URLs here. For example, using topics as your category base would make your category links like http://example.org/index.php/topics/uncategorized/. If you leave these blank the defaults will be used." +msgstr "Si quieres, puedes introducir estructuras personalizadas para las URLs de las categorías y etiquetas. Por ejemplo, usar secciones como categoría base haría tus enlaces de categoría como http://ejemplo.org/index.php/secciones/general/. Si dejas esto en blanco se usará la opción predeterminada." + +#: wp-admin/options-permalink.php:214 +msgid "Category base" +msgstr "Categoría base" + +#: wp-admin/options-permalink.php:218 +msgid "Tag base" +msgstr "Etiqueta base" + +#: wp-admin/options-permalink.php:232 +msgid "If your web.config file were writable, we could do this automatically, but it isn’t so this is the url rewrite rule you should have in your web.config file. Click in the field and press CTRL + a to select all. Then insert this rule inside of the /<configuration>/<system.webServer>/<rewrite>/<rules> element in web.config file." +msgstr "Si tu archivo web.config tuviera permisos de escritura los cambios se harían automáticamente. Al no ser así, a continuación tienes las reglas de mod_rewrite que debes agregar manualmente a tu archivo web.config que se encuentra en el directorio raíz de WordPress. Haz clic en el área de texto y pulsa CTRL + a para seleccionar todo el texto. Después copia y pega las reglas de la configuración /<configuration>/<system.webServer>/<rewrite>/<rules> en tu archivo web.config." + +#: wp-admin/options-permalink.php:237 +msgid "If you temporarily make your web.config file writable for us to generate rewrite rules automatically, do not forget to revert the permissions after rule has been saved." +msgstr "Si temporalmente tienes que hacer el web.config editable para que podamos generar automaticamente las reglas de reescritura, no te olvides de volverlo a poner como estaba." + +#: wp-admin/options-permalink.php:239 +msgid "If the root directory of your site were writable, we could do this automatically, but it isn’t so this is the url rewrite rule you should have in your web.config file. Create a new file, called web.config in the root directory of your site. Click in the field and press CTRL + a to select all. Then insert this code into the web.config file." +msgstr "Si la carpeta raíz de tu sitio tuviera permisos de escritura, podríamos hacer este cambio automáticamente. Al no tener permisos de escritura, deberás editar tu web.config y añadirla a mano. Crea un nuevo archivo en la carpeta raíz de tu sitio y llámalo web.config. Haz clic en el siguiente campo y teclea CTRL + a para seleccionarlo todo. Luego pega este código en el fichero web.config." + +#: wp-admin/options-permalink.php:244 +msgid "If you temporarily make your site’s root directory writable for us to generate the web.config file automatically, do not forget to revert the permissions after the file has been created." +msgstr "Si das permisos temporales de escritura a la carpeta raíz de tu sitio para que se genere el archivo web.config automáticamente, no olvides revertir los permisos después de que se cree el archivo." + +#: wp-admin/options-permalink.php:249 +msgid "If your .htaccess file were writable, we could do this automatically, but it isn’t so these are the mod_rewrite rules you should have in your .htaccess file. Click in the field and press CTRL + a to select all." +msgstr "Si tu archivo .htaccess tuviera permisos de escritura los cambios se harían automáticamente, pero si no fuera así, aquí tienes las reglas de mod_rewrite que debes agregar manualmente a tu archivo .htaccess. Haz clic en el área de texto y pulsa CTRL + a o COMANDO + a para seleccionarlo todo." + +#: wp-admin/user-edit.php:22 wp-admin/user-edit.php:24 +msgid "Invalid user ID." +msgstr "El ID del usuario no es válido." + +#: wp-admin/user-edit.php:28 +msgid "Edit User" +msgstr "Editar usuario" + +#: wp-admin/user-edit.php:41 +msgid "Your profile contains information about you (your “account”) as well as some personal options related to using WordPress." +msgstr "Tu perfil contiene infomación sobre ti (tu “cuenta”) así como algunas opciones personales relacionadas con el uso de WordPress." + +#: wp-admin/user-edit.php:42 +msgid "You can change your password, turn on keyboard shortcuts, change the color scheme of your WordPress administration screens, and turn off the WYSIWYG (Visual) editor, among other things." +msgstr "Puedes cambiar tu contraseña, activar los atajos de teclado, cambiar el esquema de colores de la pantalla de administración de WordPress y desactivar el editor (visual) WYSIWYG entre de otras cosas." + +#: wp-admin/user-edit.php:43 +msgid "Your username cannot be changed, but you can use other fields to enter your real name or a nickname, and change which name to display on your posts." +msgstr "Tu nombre de usuario no puede cambiarse, pero puedes usar los otros campos para introducir tu nombre real o tu alias y utilizarlo para que se muestre en tus entradas." + +#: wp-admin/user-edit.php:44 +msgid "Required fields are indicated; the rest are optional. Profile information will only be displayed if your theme is set up to do so." +msgstr "Los campos necesarios están marcados. El resto son opcionales. El perfil sólo será mostrado si tu tema está configurado para ello." + +#: wp-admin/user-edit.php:45 +msgid "Remember to click the Update Profile button when you are finished." +msgstr "Recuerda hacer click en el botón actualizar Perfil cuando acabes." + +#: wp-admin/user-edit.php:47 +msgid "Documentation on User Profiles" +msgstr "Documentación sobre los perfiles de usuario" + +#: wp-admin/user-edit.php:69 +msgid "Use https" +msgstr "Usar https" + +#: wp-admin/user-edit.php:70 +msgid "Always use https when visiting the admin" +msgstr "Usar siempre https para visitar la administración" + +#: wp-admin/user-edit.php:78 wp-admin/user-edit.php:105 +#: wp-admin/user-edit.php:152 +msgid "You do not have permission to edit this user." +msgstr "No tienes autorización para editar este usuario." + +#: wp-admin/user-edit.php:158 +msgid "Important:" +msgstr "Importante:" + +#: wp-admin/user-edit.php:158 +msgid "This user has super admin privileges." +msgstr "Este usuario tiene privilegios de super admin." + +#: wp-admin/user-edit.php:162 +msgid "User updated." +msgstr "El usuario ha sido actualizado." + +#: wp-admin/user-edit.php:164 +msgid "← Back to Authors and Users" +msgstr "← Volver a autores y usuarios" + +#: wp-admin/user-edit.php:186 +msgid "Personal Options" +msgstr "Opciones personales" + +#: wp-admin/user-edit.php:191 +msgid "Visual Editor" +msgstr "Editor visual" + +#: wp-admin/user-edit.php:192 +msgid "Disable the visual editor when writing" +msgstr "Desactivar el editor visual al escribir" + +#: wp-admin/user-edit.php:205 +msgid "Enable keyboard shortcuts for comment moderation." +msgstr "Activar los atajos del teclado para la moderación de comentarios." + +#: wp-admin/user-edit.php:205 +msgid "More information" +msgstr "Más información" + +#: wp-admin/user-edit.php:209 wp-admin/user-edit.php:210 +msgid "Show Admin Bar" +msgstr "Mostrar la barra de administración" + +#: wp-admin/user-edit.php:213 +msgid "when viewing site" +msgstr "cuando se esté viendo el sitio" + +#: wp-admin/user-edit.php:216 +msgid "in dashboard" +msgstr "en el escritorio" + +#: wp-admin/user-edit.php:231 +msgid "Usernames cannot be changed." +msgstr "El nombre de usuario no puede cambiarse." + +#: wp-admin/user-edit.php:235 +msgid "Role:" +msgstr "Perfil:" + +#: wp-admin/user-edit.php:248 wp-admin/user-edit.php:250 +msgid "— No role for this site —" +msgstr "— No hay perfil para este sitio —" + +#: wp-admin/user-edit.php:256 +msgid "Super Admin" +msgstr "Súper Admin" + +#: wp-admin/user-edit.php:259 +msgid "Grant this user super admin privileges for the Network." +msgstr "Dar permisos de super admin en la red a este usuario." + +#: wp-admin/user-edit.php:261 +msgid "Super admin privileges cannot be removed because this user has the network admin email." +msgstr "Los privilegios del Super admin no se pueden eliminar porque este usuario tiene el correo electrónico de administrador de la red." + +#: wp-admin/user-edit.php:277 +msgid "Nickname" +msgstr "Alias" + +#: wp-admin/user-edit.php:282 +msgid "Display name publicly as" +msgstr "Mostrar este nombre públicamente" + +#: wp-admin/user-edit.php:312 +msgid "Contact Info" +msgstr "Información de contacto" + +#: wp-admin/user-edit.php:322 +msgid "There is a pending change of your e-mail to %1$s. Cancel" +msgstr "Hay un cambio pendiente en tu correo electrónico a %1$s. Cancelar" + +#: wp-admin/user-edit.php:345 +msgid "About Yourself" +msgstr "Acerca de ti" + +#: wp-admin/user-edit.php:345 +msgid "About the user" +msgstr "Acerca del usuario" + +#: wp-admin/user-edit.php:349 +msgid "Biographical Info" +msgstr "Información biográfica" + +#: wp-admin/user-edit.php:351 +msgid "Share a little biographical information to fill out your profile. This may be shown publicly." +msgstr "Incluye alguna información biográfica en tu perfil. Podrá mostrarse públicamente." + +#: wp-admin/user-edit.php:359 +msgid "New Password" +msgstr "Nueva contraseña" + +#: wp-admin/user-edit.php:360 +msgid "If you would like to change the password type a new one. Otherwise leave this blank." +msgstr "Si deseas cambiar la contraseña del usuario, escribe aquí dos veces la nueva. En caso contrario, deja las casillas en blanco." + +#: wp-admin/user-edit.php:361 +msgid "Type your new password again." +msgstr "Teclea tu nueva contraseña otra vez." + +#: wp-admin/user-edit.php:380 +msgid "Additional Capabilities" +msgstr "Capacidades adicionales" + +#: wp-admin/user-edit.php:399 +msgid "Update Profile" +msgstr "Actualizar perfil" + +#: wp-admin/user-edit.php:399 +msgid "Update User" +msgstr "Actualizar usuario" + +#: wp-admin/widgets.php:37 +msgid "Widgets are independent sections of content that can be placed into any widgetized area provided by your theme (commonly called sidebars). To populate your sidebars/widget areas with individual widgets, drag and drop the title bars into the desired area. By default, only the first widget area is expanded. To populate additional widget areas, click on their title bars to expand them." +msgstr "Los Widgets son secciones independientes de contenido que pueden ser colocados en cualquier parte de tu tema que esté preparado para ello (comúnmente llamados sidebars). Para colocar en tus áreas sidebar/widget con widgets de forma individual, arrastra y suelta la barra del título del widget al área deseada. Por defecto, sólo la primera área está desplegada. Para poner widgets en otras aéreas haz clic en el barra del título para desplegarlas." + +#: wp-admin/widgets.php:38 +msgid "The Available Widgets section contains all the widgets you can choose from. Once you drag a widget into a sidebar, it will open to allow you to configure its settings. When you are happy with the widget settings, click the Save button and the widget will go live on your site. If you click Delete, it will remove the widget." +msgstr "La sección de widgets disponibles contiene todos los widgets que puedes elegir. Cuando arrastres el widget al lateral, se abrirá para que puedas configurar sus opciones. Cuando las tengas a tu gusto, haz clic en botón de guardar y el widget se pondrá a funcionar en tu sitio. Si pulsas borrar, se quitará el widget." + +#: wp-admin/widgets.php:39 +msgid "If you want to remove the widget but save its setting for possible future use, just drag it into the Inactive Widgets area. You can add them back anytime from there. This is especially helpful when you switch to a theme with fewer or different widget areas." +msgstr "Si quieres quitar el widget, pero también guardar los ajustes por si los necesitaras en el futuro, simplemente arrástralo al área de widgets inactivos. Puedes añadirlos de nuevo en cualquier otro momento desde ahí. Esto es especialmente útil cuando cambias a un tema con pocas o distintas áreas de widgets." + +#: wp-admin/widgets.php:40 +msgid "Widgets may be used multiple times. You can give each widget a title, to display on your site, but it’s not required." +msgstr "Los widgets pueden usarse varias veces. Puedes proporcionar a cada widget un título para ser mostrado en tu sitio, pero no es necesario." + +#: wp-admin/widgets.php:41 +msgid "Enabling Accessibility Mode, via Screen Options, allows you to use Add and Edit buttons instead of using drag and drop." +msgstr "Activar el modo de accesibilidad, vía Opciones de Pantalla, te permite usar botones de Añadir y Editar en vez de arrastrar y soltar." + +#: wp-admin/widgets.php:42 +msgid "Many themes show some sidebar widgets by default until you edit your sidebars, but they are not automatically displayed in your sidebar management tool. After you make your first widget change, you can re-add the default widgets by adding them from the Available Widgets area." +msgstr "Muchos temas muestran varios widgets de barra lateral por defecto hasta que editas tus barras laterales, pero no se muestran automáticamente en tu herramienta de gestión de barras laterales. Una vez hagas tu primer cambio en un widget puedes volver a añadirlo desde el área de widgets disponibles." + +#: wp-admin/widgets.php:45 +msgid "Documentation on Widgets" +msgstr "Documentación sobre Widgets" + +#: wp-admin/widgets.php:51 wp-admin/widgets.php:374 +msgid "Inactive Widgets" +msgstr "Widgets inactivos" + +#: wp-admin/widgets.php:143 +msgid "No Sidebars Defined" +msgstr "No hay barras laterales definidas" + +#: wp-admin/widgets.php:145 +msgid "The theme you are currently using isn’t widget-aware, meaning that it has no sidebars that you are able to change. For information on making your theme widget-aware, please follow these instructions." +msgstr "Estás viendo este mensaje porque el tema que estás usando actualmente no está preparado para widgets. Esto significa que no tiene barras laterales que puedas cambiar. Para información de cómo preparar tu tema para widgets, por favor sigue estas instrucciones." + +#: wp-admin/widgets.php:265 +msgid "Widget %s" +msgstr "Widget %s" + +#: wp-admin/widgets.php:276 +msgid "Select both the sidebar for this widget and the position of the widget in that sidebar." +msgstr "Selecciona la barra lateral y la posición en la que irá el widget." + +#: wp-admin/widgets.php:316 +msgid "Save Widget" +msgstr "Guardar Widget" + +#: wp-admin/widgets.php:332 +msgid "Changes saved." +msgstr "Cambios guardados." + +#: wp-admin/widgets.php:336 +msgid "Error while saving." +msgstr "Error al guardar los cambios." + +#: wp-admin/widgets.php:337 +msgid "Error in displaying the widget settings form." +msgstr "Error al mostrar el formulario con las opciones del widget." + +#: wp-admin/widgets.php:360 +msgid "Available Widgets" +msgstr "Widgets disponibles" + +#: wp-admin/widgets.php:362 +msgid "Drag widgets from here to a sidebar on the right to activate them. Drag widgets back here to deactivate them and delete their settings." +msgstr "Arrastra los widgets de aquí a la barra de la derecha para activarlos. Arrastra los widgets aquí desde la barra de la derecha para desactivarlos y eliminar su configuración." + +#: wp-admin/widgets.php:377 +msgid "Drag widgets here to remove them from the sidebar but keep their settings." +msgstr "Arrastra los widgets aquí para eliminarlos de la barra lateral pero manteniendo su configuración." + +#: wp-admin/admin-header.php:17 wp-admin/admin-header.php:154 +msgid "Network Admin" +msgstr "Administrador de la red" + +#: wp-admin/admin-header.php:19 +msgid "Global Dashboard" +msgstr "Escritorio global" + +#: wp-admin/admin-header.php:24 +msgid "%1$s — WordPress" +msgstr "%1$s — WordPress" + +#: wp-admin/admin-header.php:26 +msgid "%1$s ‹ %2$s — WordPress" +msgstr "%1$s ‹ %2$s — WordPress" + +#: wp-admin/admin-header.php:111 +msgid "%s Network Admin" +msgstr "%s Administrador de la red" + +#: wp-admin/admin-header.php:113 +msgid "%s Global Dashboard" +msgstr "%s Escritorio global" + +#: wp-admin/admin-header.php:141 +msgid "Your site is asking search engines not to index its content" +msgstr "Tu sitio le está diciendo a los buscadores que no indexen su contenido." + +#: wp-admin/admin-header.php:141 +msgid "Search Engines Blocked" +msgstr "Buscadores bloqueados" + +#: wp-admin/admin-header.php:151 +msgid "Howdy, %2$s" +msgstr "Hola, %2$s" + +#: wp-admin/plugins.php:20 +msgid "You do not have sufficient permissions to manage plugins for this site." +msgstr "No tienes suficientes permisos para administrar los plugins de este sitio." + +#: wp-admin/plugins.php:41 wp-admin/plugins.php:71 wp-admin/plugins.php:131 +msgid "You do not have sufficient permissions to activate plugins for this site." +msgstr "No tienes suficientes permisos para activar plugins en este sitio." + +#: wp-admin/plugins.php:157 wp-admin/plugins.php:170 +msgid "You do not have sufficient permissions to deactivate plugins for this site." +msgstr "No tienes suficientes permisos para desactivar plugins en este sitio." + +#: wp-admin/plugins.php:193 +msgid "You do not have sufficient permissions to delete plugins for this site." +msgstr "No tienes suficientes permisos para eliminar plugins en este sitio." + +#: wp-admin/plugins.php:250 +msgid "Delete Plugin" +msgid_plural "Delete Plugins" +msgstr[0] "Eliminar Plugin" +msgstr[1] "Eliminar Plugins" + +#: wp-admin/plugins.php:253 +msgid "This plugin may be active on other sites in the network." +msgid_plural "These plugins may be active on other sites in the network." +msgstr[0] "Este plugin puede estar activado para otros sitios de la red." +msgstr[1] "Estos plugins pueden estar activos para otros sitios de la red." + +#: wp-admin/plugins.php:255 +msgid "You are about to remove the following plugin:" +msgid_plural "You are about to remove the following plugins:" +msgstr[0] "Estás a punto de eliminar el siguiente plugin:" +msgstr[1] "Estás a punto de eliminar los siguientes plugins:" + +#: wp-admin/plugins.php:262 +msgid "%1$s by %2$s (will also delete its data)" +msgstr "%1$s por %2$s (también elimina sus propios datos)" + +#: wp-admin/plugins.php:266 +msgid "%1$s by %2$s" +msgstr "%1$s por %2$s" + +#: wp-admin/plugins.php:273 +msgid "Are you sure you wish to delete these files and data?" +msgstr "¿Estás seguro de que deseas eliminar estos archivos y datos?" + +#: wp-admin/plugins.php:275 +msgid "Are you sure you wish to delete these files?" +msgstr "¿Estás seguro de que deseas eliminar estos archivos?" + +#: wp-admin/plugins.php:285 +msgid "Yes, Delete these files and data" +msgstr "Sí, quiero borrar estos archivos y datos" + +#: wp-admin/plugins.php:285 +msgid "Yes, Delete these files" +msgstr "Sí, quiero borrar estos archivos" + +#: wp-admin/plugins.php:288 +msgid "No, Return me to the plugin list" +msgstr "No, quiero volver a la lista de plugins" + +#: wp-admin/plugins.php:291 +msgid "Click to view entire list of files which will be deleted" +msgstr "Pulsa aquí para ver la lista completa de archivos que serán eliminados" + +#: wp-admin/plugins.php:328 +msgctxt "plugins per page (screen options)" +msgid "Plugins" +msgstr "Plugins" + +#: wp-admin/plugins.php:331 +msgid "Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here." +msgstr "Los plugins amplían las funcionalidades de WordPress. Una vez instalados, puedes activarlos o desactivarlos desde aquí." + +#: wp-admin/plugins.php:332 +msgid "You can find additional plugins for your site by using the Plugin Browser/Installer functionality or by browsing the WordPress Plugin Directory directly and installing new plugins manually. To manually install a plugin you generally just need to upload the plugin file into your /wp-content/plugins directory. Once a plugin has been installed, you can activate it here." +msgstr "Puedes encontrar plugins adicionales para tu sitio usando la funcionalidad Instalador/navegador de plugins o navegando por el directorio de plugins de WordPress directamente e instalando manualmente nuevos plugins. Para instalar manualmente un plugin normalmente necesitarás subir el fichero del plugin a tu directorio /wp-content/plugins. Una vez se haya instalado el plugin puedes activarlo aquí." + +#: wp-admin/plugins.php:333 +msgid "Most of the time, plugins play nicely with the core of WordPress and with other plugins. Sometimes, though, a plugin’s code will get in the way of another plugin, causing compatibility issues. If your site starts doing strange things, this may be the problem. Try deactivating all your plugins and re-activating them in various combinations until you isolate which one(s) caused the issue." +msgstr "La mayoría de las veces los plugins funcionan perfectamente con el núcleo de WordPress y con los otros plugins. Algunas veces, puede haber incompatibilidades entre algunos plugins produciendo problemas. Tu sitio podría comenzar a hacer cosas raras, esto podría ser un problema. Prueba a desactivar tus plugin e ir activándolos uno a uno y comprobando que el problema no reaparezca. Es la forma de detectar el plugin problemático o la combinación de plugins problemáticos." + +#: wp-admin/plugins.php:334 +msgid "If something goes wrong with a plugin and you can’t use WordPress, delete or rename that file in the %s directory and it will be automatically deactivated." +msgstr "Si algo va mal con un plugin y no puedes utilizar tu WordPress, borra o renombra ese archivo en el directorio %s y se desactivará automáticamente." + +#: wp-admin/plugins.php:336 +msgid "Documentation on Managing Plugins" +msgstr "Documentación sobre cómo gestionar plugins" + +#: wp-admin/plugins.php:348 +msgid "The plugin %s has been deactivated due to an error: %s" +msgstr "El plugin %s se ha desactivado debido a un error: %s" + +#: wp-admin/plugins.php:354 +msgid "You cannot delete a plugin while it is active on the main site." +msgstr "No puedes borrar un plugin si está activado para el sitio principal." + +#: wp-admin/plugins.php:356 +msgid "The plugin generated %d characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin." +msgstr "El plugin ha generado %d caracteres de salida inesperada durante la activación. Si te sale el mensaje de advertencia “headers already sent” (cabeceras ya enviadas), problemas con las feeds u otros problemas, prueba a desactivar o eliminar este plugin." + +#: wp-admin/plugins.php:358 +msgid "Plugin could not be activated because it triggered a fatal error." +msgstr "El plugin no ha podido activarse porque ha provocado un error fatal." + +#: wp-admin/plugins.php:373 +msgid "Plugin could not be deleted due to an error: %s" +msgstr "El plugin no se ha podido eliminar debido a un error: %s" + +#: wp-admin/plugins.php:375 +msgid "The selected plugins have been deleted." +msgstr "Los plugins elegidos han sido eliminados." + +#: wp-admin/plugins.php:378 +msgid "Plugin activated." +msgstr "El plugin ha sido activado." + +#: wp-admin/plugins.php:380 +msgid "Selected plugins activated." +msgstr "Los plugins elegidos han sido activados." + +#: wp-admin/plugins.php:382 +msgid "Plugin deactivated." +msgstr "El plugin ha sido desactivado." + +#: wp-admin/plugins.php:384 +msgid "Selected plugins deactivated." +msgstr "Los plugins elegidos han sido desactivados." + +#: wp-admin/plugins.php:386 +msgid "No out of date plugins were selected." +msgstr "Ningún plugin actualizable elegido." + +#: wp-admin/plugins.php:393 wp-admin/menu.php:180 +msgctxt "plugin" +msgid "Add New" +msgstr "Añadir nuevo" + +#: wp-admin/includes/class-wp-plugins-list-table.php:290 +msgid "Files in the /wp-content/mu-plugins directory are executed automatically." +msgstr "Los archivos del directorio /wp-content/mu-plugins se ejecutan automáticamente." + +#: wp-admin/includes/class-wp-plugins-list-table.php:292 +msgid "Drop-ins are advanced plugins in the /wp-content directory that replace WordPress functionality when present." +msgstr "Los infiltrados son plugins avanzados del directorio /wp-content que reemplazan, cuando están presentes, funcionalidades de WordPress." + +#: wp-admin/edit-tags.php:177 +msgid "You can use categories to define sections of your site and group related posts. The default category is “Uncategorized” until you change it in your writing settings." +msgstr "Puedes usar categorías para definir secciones para las entradas de tu sitio y grupo. La categoría por defecto es “Sin categoría” hasta que la cambies en tus ajustes de escritura." + +#: wp-admin/edit-tags.php:179 +msgid "You can create groups of links by using link categories. Link category names must be unique and link categories are separate from the categories you use for posts." +msgstr "Puedes crear grupos de enlaces usando las categorías de enlaces. Los nombres de las categorías de enlaces deben ser únicos y diferentes a las categorías que usas para las entradas." + +#: wp-admin/edit-tags.php:181 +msgid "You can assign keywords to your posts using Post Tags. Unlike categories, tags have no hierarchy, meaning there’s no relationship from one tag to another." +msgstr "Puedes asignar palabras clave a tus entradas usando las etiquetas de entradas. A diferencia de las categorías, las etiquetas no tienen jerarquías, lo que quiere decir que no están relacionadas entre sí." + +#: wp-admin/edit-tags.php:184 +msgid "You can delete link categories in the Bulk Action pulldown, but that action does not delete the links within the category. Instead, it moves them to the default link category." +msgstr "Puedes borrar categorías de enlaces con la opción del desplegable Acciones en lote, pero eso no borrará los enlaces de la categoría. En su lugar, lo que hace en enviarlas a la categoría de enlaces por defecto." + +#: wp-admin/edit-tags.php:186 +msgid "What’s the difference between categories and tags? Normally, tags are ad-hoc keywords that identify important information in your post (names, subjects, etc) that may or may not recur in other posts, while categories are pre-determined sections. If you think of your site like a book, the categories are like the Table of Contents and the tags are like the terms in the index." +msgstr "¿Cuál es la diferencia entre categorías y etiquetas? Normalmente, las etiquetas son palabras clave que identifican información importante en tus entradas (nombres, asuntos, etc...) que pueden ser recurrentes o no en otras entradas, mientras que las categorías son secciones predeterminadas. Si piensas en tu sitio como en un libro, las categorías sería la tabla de contenidos mientras que las etiquetas serían como los términos en el índice." + +#: wp-admin/edit-tags.php:189 +msgid "When adding a new category on this screen, you’ll fill in the following fields:" +msgstr "Cuando añades una nueva categoría en esta pantalla, rellenas los siguientes campos." + +#: wp-admin/edit-tags.php:191 +msgid "When adding a new tag on this screen, you’ll fill in the following fields:" +msgstr "Cuando añadas una nueva etiqueta en esta pantalla, rellenarás los siguientes campos:" + +#: wp-admin/edit-tags.php:196 +msgid "Name - The name is how it appears on your site." +msgstr "Nombre - El nombre es como aparece en tu sitio" + +#: wp-admin/edit-tags.php:200 +msgid "Slug - The “slug” is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens." +msgstr "Slug - La “slug ” es la versión amigable de la URL. Normalmente, son todo minúsculas y contiene sólo letras, números y guiones." + +#: wp-admin/edit-tags.php:203 +msgid "Parent - Categories, unlike tags, can have a hierarchy. You might have a Jazz category, and under that have children categories for Bebop and Big Band. Totally optional. To create a subcategory, just choose another category from the Parent dropdown." +msgstr "Categorías - Superiores, a diferencia de las etiquetas, pueden tener jerarquías. Puedes tener la categoría Jazz y bajo esta, tener unas categorías hijas para Bebop y Big Band. Totalmente Opcional. Para crear una subcategoría, tan solo selecciona otra categoría del menú desplegable de Superiores." + +#: wp-admin/edit-tags.php:206 +msgid "Description - The description is not prominent by default; however, some themes may display it." +msgstr "Descripción - La descripción no se muestra por defecto, pero algunos temas la podrían mostrar." + +#: wp-admin/edit-tags.php:208 +msgid "You can change the display of this screen using the Screen Options tab to set how many items are displayed per screen and to display/hide columns in the table." +msgstr "Puedes cambiar la forma de visualización de esta pantalla usando la pestaña Opciones de pantalla para marcar cuántos elementos se muestran por pantalla y mostrar/esconder columnas." + +#: wp-admin/edit-tags.php:212 +msgid "Documentation on Categories" +msgstr "Documentación sobre categorías" + +#: wp-admin/edit-tags.php:214 +msgid "Documentation on Link Categories" +msgstr "Documentación sobre categorías de enlaces" + +#: wp-admin/edit-tags.php:216 +msgid "Documentation on Post Tags" +msgstr "Documentación sobre etiquetas de entradas" + +#: wp-admin/edit-tags.php:229 +msgid "Item added." +msgstr "Añadido." + +#: wp-admin/edit-tags.php:230 +msgid "Item deleted." +msgstr "Eliminado." + +#: wp-admin/edit-tags.php:231 +msgid "Item updated." +msgstr "Actualizado." + +#: wp-admin/edit-tags.php:232 +msgid "Item not added." +msgstr "No añadido." + +#: wp-admin/edit-tags.php:234 +msgid "Items deleted." +msgstr "Eliminados." + +#: wp-admin/edit-tags.php:275 +msgid "Note:
    Deleting a category does not delete the posts in that category. Instead, posts that were only assigned to the deleted category are set to the category %s." +msgstr "Nota:
    Al borrar una categoría no borrarás las entradas que hay en ella. En su lugar, las entradas que sólo estén asignadas a esa categoría se asignarán a la categoría %s." + +#: wp-admin/edit-tags.php:277 +msgid "Categories can be selectively converted to tags using the category to tag converter." +msgstr "Las categorías se pueden convertir a voluntad en etiquetas usando el conversor de categorías a etiquetas." + +#: wp-admin/edit-tags.php:282 +msgid "Tags can be selectively converted to categories using the tag to category converter" +msgstr "Las etiquetas se pueden convertir a voluntad a categorías usando el conversor de etiquetas a categorías" + +#: wp-admin/edit-tags.php:334 wp-admin/edit-tag-form.php:40 +msgctxt "Taxonomy Name" +msgid "Name" +msgstr "Nombre" + +#: wp-admin/edit-tags.php:336 wp-admin/edit-tag-form.php:42 +msgid "The name is how it appears on your site." +msgstr "El nombre es cómo aparecerá en tu sitio." + +#: wp-admin/edit-tags.php:340 wp-admin/edit-tag-form.php:46 +msgctxt "Taxonomy Slug" +msgid "Slug" +msgstr "Slug" + +#: wp-admin/edit-tags.php:342 wp-admin/edit-tag-form.php:48 +msgid "The “slug” is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens." +msgstr "El “slug” es la versión amigable de la URL del nombre. Suele estar en minúsculas y contiene sólo letras, números y guiones." + +#: wp-admin/edit-tags.php:347 wp-admin/edit-tag-form.php:53 +msgctxt "Taxonomy Parent" +msgid "Parent" +msgstr "Superior" + +#: wp-admin/edit-tags.php:350 wp-admin/edit-tag-form.php:57 +msgid "Categories, unlike tags, can have a hierarchy. You might have a Jazz category, and under that have children categories for Bebop and Big Band. Totally optional." +msgstr "Las categorías, a diferencia de las etiquetas, pueden tener jerarquías. Podrías tener una categoría de Jazz, y por debajo las categorías Bebop y Big Band. Totalmente opcional." + +#: wp-admin/edit-tags.php:355 wp-admin/edit-tag-form.php:63 +msgctxt "Taxonomy Description" +msgid "Description" +msgstr "Descripción" + +#: wp-admin/edit-tags.php:357 +msgid "The description is not prominent by default; however, some themes may show it." +msgstr "La descripción no suele mostrarse por defecto, sin embargo hay algunos temas que puede que la muestren." + +#: wp-admin/media-upload.php:35 +msgid "You are not allowed to be here" +msgstr "No tienes autorización para estar aquí." + +#: wp-admin/media-upload.php:62 +msgid "Upload New Media" +msgstr "Subir nuevo medio" + +#: wp-admin/media-upload.php:66 +msgid "You can upload media files here without creating a post first. This allows you to upload files to use with posts and pages later and/or to get a web link for a particular file that you can share." +msgstr "Desde aquí puedes subir archivos multimedia sin tener que crear primero una entrada. Esto te permite subir archivos para usarlos en tus entradas y páginas y/o conseguir un enlace al archivo en particular que puedes compartir" + +#: wp-admin/media-upload.php:67 +msgid "There are two options for uploading files: Select Files will open the Flash-based uploader (multiple file upload allowed), or you can use the Browser Uploader. Clicking Select Files opens a navigation window showing you files in your operating system. Selecting Open after clicking on the file you want activates a progress bar on the uploader screen. Basic image editing is available after upload is complete. Make sure you click Save before leaving this screen." +msgstr "Hay dos opciones para subir archivos: Elegir archivos abrirá el cargador basado en Flash (permite subir varios archivos), o puedes usar el Cargador del navegador. Haciendo clic en Elegir archivos, se abre una ventana de navegación que muestra los archivos de tu sistema operativo. Eligiendo Abrir, después de hacer clic en el archivo que quieres, activa una barra de progreso en la pantalla del cargador. Hay disponible una edición básica de imágenes después de que la subida esté completa. Asegúrate de hacer clic en Guardar antes de salir de esta pantalla." + +#: wp-admin/media-upload.php:69 +msgid "Documentation on Uploading Media Files" +msgstr "Documentación sobre la subida de archivos de medios" + +#: wp-admin/edit-form-comment.php:17 +msgid "Editing Comment # %s" +msgstr "Editando comentario # %s" + +#: wp-admin/edit-form-comment.php:42 +msgid "View Comment" +msgstr "Ver comentario" + +#: wp-admin/edit-form-comment.php:51 +msgctxt "adjective" +msgid "Pending" +msgstr "Pendiente" + +#: wp-admin/edit-form-comment.php:59 +msgid "Submitted on: %1$s" +msgstr "Enviado el: %1$s" + +#: wp-admin/edit-form-comment.php:98 +msgid "E-mail (%s):" +msgstr "Correo electrónico (%s):" + +#: wp-admin/edit-form-comment.php:98 +msgid "send e-mail" +msgstr "enviar correo electrónico" + +#: wp-admin/edit-form-comment.php:100 +msgid "E-mail:" +msgstr "Correo electrónico:" + +#: wp-admin/edit-form-comment.php:109 +msgid "visit site" +msgstr "visitar sitio" + +#: wp-admin/edit-form-comment.php:110 +msgid "URL (%s):" +msgstr "URL (%s):" + +#: wp-admin/edit-form-comment.php:112 +msgid "URL:" +msgstr "URL:" + +#: wp-admin/edit-tag-form.php:14 +msgid "You did not select an item for editing." +msgstr "No has elegido un elemento para editar." + +#: wp-admin/edit-tag-form.php:65 +msgid "The description is not prominent by default, however some themes may show it." +msgstr "La descripción no suele mostrarse por defecto, sin embargo hay algunas plantillas que puede que la muestren." + +#: wp-admin/menu.php:80 +msgid "Library" +msgstr "Librería multimedia" + +#: wp-admin/menu.php:163 +msgctxt "theme editor" +msgid "Editor" +msgstr "Editor" + +#: wp-admin/menu.php:176 +msgid "Plugins %s" +msgstr "Plugins %s" + +#: wp-admin/menu.php:181 +msgctxt "plugin editor" +msgid "Editor" +msgstr "Editor" + +#: wp-admin/menu.php:199 wp-admin/menu.php:202 +msgid "Your Profile" +msgstr "Tu perfil" + +#: wp-admin/menu.php:214 +msgid "Delete Site" +msgstr "Eliminar sitio" + +#: wp-admin/menu.php:216 +msgid "Network" +msgstr "Red" + +#: wp-admin/menu.php:218 wp-admin/options.php:21 +#: wp-content/plugins/akismet/admin.php:45 +msgid "Settings" +msgstr "Ajustes" + +#: wp-admin/menu.php:219 +msgctxt "settings screen" +msgid "General" +msgstr "Generales" + +#: wp-admin/menu.php:220 +msgid "Writing" +msgstr "Escritura" + +#: wp-admin/menu.php:221 +msgid "Reading" +msgstr "Lectura" + +#: wp-admin/menu.php:224 +msgid "Privacy" +msgstr "Privacidad" + +#: wp-admin/menu.php:225 +msgid "Permalinks" +msgstr "Enlaces permanentes" + +#: wp-admin/update.php:24 wp-admin/update.php:50 wp-admin/update.php:69 +msgid "You do not have sufficient permissions to update plugins for this site." +msgstr "No tienes suficientes permisos para actualizar plugins en este sitio." + +#: wp-admin/update.php:78 +msgid "Plugin Reactivation" +msgstr "Reactivación del plugin" + +#: wp-admin/update.php:80 +msgid "Plugin reactivated successfully." +msgstr "El plugin ha sido reactivado." + +#: wp-admin/update.php:83 +msgid "Plugin failed to reactivate due to a fatal error." +msgstr "El plugin no ha sido reactivado debido a un error fatal." + +#: wp-admin/update.php:97 wp-admin/update.php:128 +msgid "You do not have sufficient permissions to install plugins for this site." +msgstr "No tienes suficientes permisos para instalar plugins en este sitio." + +#: wp-admin/update.php:112 +msgid "Installing Plugin: %s" +msgstr "Instalando plugin: %s" + +#: wp-admin/update.php:134 +msgid "Upload Plugin" +msgstr "Subir plugin" + +#: wp-admin/update.php:139 +msgid "Installing Plugin from uploaded file: %s" +msgstr "Instalando plugin desde el archivo: %s" + +#: wp-admin/update.php:152 wp-admin/update.php:172 +msgid "You do not have sufficient permissions to update themes for this site." +msgstr "No tienes suficientes permisos para actualizar temas en este sitio." + +#: wp-admin/update.php:198 wp-admin/update.php:228 +msgid "You do not have sufficient permissions to install themes for this site." +msgstr "No tienes suficientes permisos para instalar temas en este sitio." + +#: wp-admin/update.php:215 +msgid "Installing Theme: %s" +msgstr "Instalando tema: %s" + +#: wp-admin/update.php:234 +msgid "Upload Theme" +msgstr "Subir tema" + +#: wp-admin/update.php:241 +msgid "Installing Theme from uploaded file: %s" +msgstr "Instalando tema desde el archivo: %s" + +#: wp-admin/admin.php:154 +msgid "Invalid plugin page" +msgstr "Página de plugin no válida" + +#: wp-admin/admin.php:158 +msgid "Cannot load %s." +msgstr "No se pudo cargar %s." + +#: wp-admin/admin.php:179 +msgid "You are not allowed to import." +msgstr "No tienes autorización para importar." + +#: wp-admin/nav-menus.php:19 +msgid "Your theme does not support navigation menus or widgets." +msgstr "El tema actual no soporta menús de navegación o widgets." + +#: wp-admin/nav-menus.php:237 +msgid "The menu item has been successfully deleted." +msgstr "La opción del menú se ha eliminado correctamente." + +#: wp-admin/nav-menus.php:256 +msgid "The menu has been successfully deleted." +msgstr "El menú se ha borrado con éxito." + +#: wp-admin/nav-menus.php:296 +msgid "The %s menu has been successfully created." +msgstr "El menú %s se ha creado correctamente." + +#: wp-admin/nav-menus.php:299 wp-admin/nav-menus.php:309 +msgid "Please enter a valid menu name." +msgstr "Por favor, introduce un nombre de menú válido." + +#: wp-admin/nav-menus.php:385 +msgid "The %s menu has been updated." +msgstr "El menú %s se ha actualizado." + +#: wp-admin/nav-menus.php:452 +msgid "This feature, introduced in version 3.0, allows you to use a custom menu in place of your theme’s default menus. If your theme does not support the custom menus feature yet (the default theme, Twenty Ten, does), you can learn about adding this support by following the Documentation link in this tab. You can still use the “Custom Menu” widget to add menus to a sidebar." +msgstr "Esta función, introducida en la versión 3.0, permite utilizar un menú personalizado en lugar de los menús predeterminados de tu tema. Si tu tema no es compatible todavía con la función de menús personalizados (el tema por defecto, Twenty Ten, lo es), puedes aprender cómo añadirlo en el enlace de Documentación de esta pestaña. Puedes seguir utilizando el widget \"menú personalizado\" para añadir menús a una barra lateral." + +#: wp-admin/nav-menus.php:453 +msgid "You can create custom menus for your site. These menus may contain links to pages, categories, custom links or other content types (use the Screen Options tab to decide which ones to show on the screen). You can specify a different navigation label for a menu item as well as other attributes. You can create multiple menus. If your theme includes more than one menu, you can choose which custom menu to associate with each. You can also use custom menus in conjunction with the Custom Menus widget." +msgstr "Puedes crear menús personalizados para tu sitio. Estos menús pueden contener enlaces a páginas, categorías y enlaces personalizados o otro tipo de contenido (usa la pestaña Opciones de pantalla para decidir cuales se muestran en esta pantalla). Puedes especificar diferentes niveles de navegación para un elemento del menú como para otros atributos. Puedes crear múltiples menús. Si tu tema incluye más de un menú, puedes elegir qué menú personalizado asociarás a cada espacio. También puedes usar los menús personalizados conjuntamente con el widget Menús personalizados." + +#: wp-admin/nav-menus.php:454 +msgid "To create a new custom menu, click on the + tab, give the menu a name, and click Create Menu. Next, add menu items from the appropriate boxes. You’ll be able to edit the information for each menu item, and can drag and drop to put them in order. You can also drag a menu item a little to the right to make it a submenu, to create menus with hierarchy. Drop the item into its new nested placement when the dotted rectangle target shifts over, also a little to the right. Don’t forget to click Save when you’re finished." +msgstr "Si quieres crear un nuevo menú personalizado, pulsa la pestaña +, ponle un nombre y haz clic en Crear menú. A continuación, añade al menú los elementos en las cajas correspondientes. Podrás editar la información de cada elemento del menú, y arrastrar y soltar para ponerlas en el orden que quieras. También puedes arrastrar el menú un poco a la derecha para hacerlo submenú, es decir, para crear menús jerárquicos. Suelta en la parte derecha el elemento en éste nuevo lugar anidado cuando aparezca el rectángulo con línea de puntos. No te olvides hacer clic en Guardar cuando hayas terminado." + +#: wp-admin/nav-menus.php:456 +msgid "Documentation on Menus" +msgstr " Documentación sobre los menús " + +#: wp-admin/nav-menus.php:494 +msgid "Add New Menu" +msgstr "Añadir nuevo menú" + +#: wp-admin/nav-menus.php:519 wp-admin/nav-menus.php:529 +msgid "Add menu" +msgstr "Añadir menú" + +#: wp-admin/nav-menus.php:539 +msgid "Menu Name" +msgstr "Nombre del menú" + +#: wp-admin/nav-menus.php:540 +msgid "Enter menu name here" +msgstr "Introduce el nombre del menú aquí." + +#: wp-admin/nav-menus.php:554 +msgid "Automatically add new top-level pages" +msgstr "Añadir automáticamente las páginas de nivel superior" + +#: wp-admin/nav-menus.php:559 wp-admin/nav-menus.php:596 +msgid "Create Menu" +msgstr "Crear menú" + +#: wp-admin/nav-menus.php:559 wp-admin/nav-menus.php:596 +msgid "Save Menu" +msgstr "Guardar menú" + +#: wp-admin/nav-menus.php:564 +msgid "Delete Menu" +msgstr "Eliminar menú" + +#: wp-admin/nav-menus.php:585 +msgid "To create a custom menu, give it a name above and click Create Menu. Then choose items like pages, categories or custom links from the left column to add to this menu." +msgstr "Para crear un menú personalizado dale un nombre y haz clic en Crear menú. Después elige objetos como páginas, categorías o enlaces personalizados de la columna izquierda para añadirlos a este menú." + +#: wp-admin/nav-menus.php:586 +msgid "After you have added your items, drag and drop to put them in the order you want. You can also click each item to reveal additional configuration options." +msgstr "Después de añadir tus objetos, arrastra y suéltalos en el orden que desees. También puedes hacer clic en cada objeto para ver opciones de configuración avanzadas." + +#: wp-admin/nav-menus.php:587 +msgid "When you have finished building your custom menu, make sure you click the Save Menu button." +msgstr "Cuando hayas terminado de crear tu menú personalizado, asegúrate de hacer clic en el botón Guardar menú." + +#: wp-admin/options.php:109 +msgid "Error: options page not found." +msgstr "Error: no se encuentra la página de opciones." + +#: wp-admin/options.php:113 +msgid "You do not have sufficient permissions to modify unregistered settings for this site." +msgstr "No tienes suficientes permisos para modificar ajustes no registrados para este sitio." + +#: wp-admin/options.php:136 +msgid "The %1$s setting is unregistered. Unregistered settings are deprecated. See http://codex.wordpress.org/Settings_API" +msgstr "La configuración %1$s no está registrada. Las configuraciones sin registrar son obsoletas. Visita http://codex.wordpress.org/Settings_API" + +#: wp-admin/options.php:169 +msgid "All Settings" +msgstr "Todos los ajustes" + +#: wp-app.php:287 +msgid "AtomPub services are disabled on this site. An admin user can enable them at %s" +msgstr "En este sitio están desactivados los servicios AtomPub. Un administrador puede activarlos visitando %s." + +#: wp-app.php:324 wp-app.php:365 +msgid "Sorry, you do not have the right to access this site." +msgstr "Lo sentimos, no tienes autorización para acceder a este sitio." + +#: wp-app.php:420 +msgid "Sorry, you do not have the right to edit/publish new posts." +msgstr "Lo sentimos, no tienes autorización para editar/publicar nuevas entradas." + +#: wp-app.php:472 +msgid "Sorry, you do not have the right to access this post." +msgstr "Lo sentimos, no tienes autorización para acceder a esta entrada." + +#: wp-app.php:577 +msgid "Sorry, you do not have permission to upload files." +msgstr "Lo sentimos, no tienes autorización para subir archivos." + +#: wp-app.php:715 wp-app.php:752 wp-app.php:804 +msgid "Error occurred while accessing post metadata for file location." +msgstr "Ha ocurrido un error mientras se accedía a los metadatos de la entrada para la localización del archivo." + +#: wp-mail.php:14 +msgid "This action has been disabled by the administrator." +msgstr "Esta acción ha sido deshabilitada por el administrador." + +#: wp-mail.php:29 +msgid "Slow down cowboy, no need to check for new mails so often!" +msgstr "¡Tranquilo, campeón! ¡No hace falta comprobar el correo tan a menudo!" + +#: wp-mail.php:49 +msgid "There doesn’t seem to be any new mail." +msgstr "Parece que no hay ningún correo electrónico nuevo." + +#: wp-mail.php:115 +msgid "Author is %s" +msgstr "El autor es %s" + +#: wp-mail.php:221 +msgid "Author: %s" +msgstr "Autor: %s" + +#: wp-mail.php:222 +msgid "Posted title: %s" +msgstr "Título publicado: %s" + +#: wp-mail.php:225 +msgid "Oops: %s" +msgstr "Oops: %s" + +#: wp-mail.php:229 +msgid "Mission complete. Message %s deleted." +msgstr "Misión cumplida. Mensaje %s borrado." + +#: wp-comments-post.php:36 +msgid "Sorry, comments are closed for this item." +msgstr "Disculpa, los comentarios están cerrados." + +#: wp-comments-post.php:71 +msgid "Sorry, you must be logged in to post a comment." +msgstr "Disculpa, debes identificarte para escribir un comentario." + +#: wp-comments-post.php:78 +msgid "Error: please fill the required fields (name, email)." +msgstr "Error: por favor, completa los campos requeridos (nombre, correo electrónico)." + +#: wp-comments-post.php:80 +msgid "Error: please enter a valid email address." +msgstr "Error: por favor, escribe un correo electrónico válido." + +#: wp-content/plugins/akismet/akismet.php:266 +msgid "Akismet caught this comment as spam" +msgstr "Akismet considera que este comentario es spam" + +#: wp-content/plugins/akismet/akismet.php:268 +#: wp-content/plugins/akismet/akismet.php:276 +msgid "Comment status was changed to %s" +msgstr "El estado del comentario se cambió a %s" + +#: wp-content/plugins/akismet/akismet.php:271 +msgid "Akismet cleared this comment" +msgstr "Akismet borró este comentario" + +#: wp-content/plugins/akismet/akismet.php:274 +msgid "Comment was caught by wp_blacklist_check" +msgstr "Comentario pillado por wp_blacklist_check" + +#: wp-content/plugins/akismet/akismet.php:281 +msgid "Akismet was unable to check this comment (response: %s), will automatically retry again later." +msgstr "Akismet fue incapaz de revisar este comentario (respuesta: %s), se volverá a intentar más tarde." + +#: wp-content/plugins/akismet/akismet.php:459 +msgid "Akismet caught this comment as spam during an automatic retry." +msgstr "Akismet ha realizado una revisión auntomática y considera que este comentario es spam" + +#: wp-content/plugins/akismet/akismet.php:461 +msgid "Akismet cleared this comment during an automatic retry." +msgstr "Akismet borró este comentario durante una revisión automática." + +#: wp-content/plugins/akismet/widget.php:15 +msgid "%1$s%2$s%3$s %4$sspam comment%5$s %6$sblocked by%7$s
    %8$sAkismet%9$s" +msgid_plural "%1$s%2$s%3$s %4$sspam comments%5$s %6$sblocked by%7$s
    %8$sAkismet%9$s" +msgstr[0] "%1$s%2$s%3$s %4$scomentario de spam%5$s %6$sbloqueado por%7$s
    %8$sAkismet%9$s" +msgstr[1] "%1$s%2$s%3$s %4$scomentarios de spam%5$s %6$sbloqueados por%7$s
    %8$sAkismet%9$s" + +#: wp-content/plugins/akismet/widget.php:43 +msgid "Spam Blocked" +msgstr "Spam bloqueado" + +#: wp-content/plugins/akismet/widget.php:89 +msgid "" +msgid_plural "" +msgstr[0] "" +msgstr[1] "" + +#: wp-content/plugins/akismet/admin.php:14 +msgid "Akismet %s requires WordPress 3.0 or higher." +msgstr "Akismet %s necesita WordPress 3.0 o superior para funcionar." + +#: wp-content/plugins/akismet/admin.php:14 +msgid "Please upgrade WordPress to a current version, or downgrade to version 2.4 of the Akismet plugin." +msgstr "Por favor, actualiza WordPress a la versión actual, o vuelve a la version 2.4 el plugin de Akismet" + +#: wp-content/plugins/akismet/admin.php:27 +msgid "Comment History" +msgstr "Historial de comentarios" + +#: wp-content/plugins/akismet/admin.php:40 +#: wp-content/plugins/akismet/admin.php:137 +msgid "Akismet Configuration" +msgstr "Configuración de Akismet" + +#: wp-content/plugins/akismet/admin.php:122 +msgid "Your key has been cleared." +msgstr "Tu clave ha sido eliminada." + +#: wp-content/plugins/akismet/admin.php:123 +msgid "Your key has been verified. Happy blogging!" +msgstr "Tu clave ha sido verificada. ¡Disfruta tu sitio!" + +#: wp-content/plugins/akismet/admin.php:124 +msgid "The key you entered is invalid. Please double-check it." +msgstr "La clave que has introducido no es válida. Por favor compruébala." + +#: wp-content/plugins/akismet/admin.php:125 +msgid "The key you entered could not be verified because a connection to akismet.com could not be established. Please check your server configuration." +msgstr "La clave que has introducido no se ha podido verificar porque no se ha podido realizar la conexión con akismet.com. Por favor, comprueba la configuración de tu servidor." + +#: wp-content/plugins/akismet/admin.php:126 +msgid "There was a problem connecting to the Akismet server. Please check your server configuration." +msgstr "Hubo un problema al conectar con el servidor de Akismet. Por favor, comprueba la configuración de tu servidor." + +#: wp-content/plugins/akismet/admin.php:127 +msgid "Please enter an API key. (Get your key.)" +msgstr "Por favor introduce una clave de API. (Consigue tu clave.)" + +#: wp-content/plugins/akismet/admin.php:128 +msgid "This key is valid." +msgstr "La clave es válida." + +#: wp-content/plugins/akismet/admin.php:129 +msgid "The key below was previously validated but a connection to akismet.com can not be established at this time. Please check your server configuration." +msgstr "La clave mostrada fue validada anteriormente pero no se puede realizar una conexión con akismet.com en este momento. Por favor, comprueba la configuración de tu servidor." + +#: wp-content/plugins/akismet/admin.php:130 +msgid "Your WordPress home URL %s is invalid. Please fix the home option." +msgstr "La URL de la página de inicio de tu WordPress %s no es válida. Por favor, arregla la opción de página de inicio." + +#: wp-content/plugins/akismet/admin.php:134 +msgid "Options saved." +msgstr "Opciones guardadas." + +#: wp-content/plugins/akismet/admin.php:139 +msgid "Sign up success! Please check your email for your Akismet API Key and enter it below." +msgstr "¡Regístro completado! Por favor, consulta en tu correo electrónico tu clave de API de Akismet y añádela debajo." + +#: wp-content/plugins/akismet/admin.php:144 +msgid "For many people, Akismet will greatly reduce or even completely eliminate the comment and trackback spam you get on your site. If one does happen to get through, simply mark it as \"spam\" on the moderation screen and Akismet will learn from the mistakes. If you don't have an API key yet, you can get one at Akismet.com." +msgstr "En la mayoría de los casos, Akismet reduce enormemente (o incluso elimina) el spam en los comentarios y trackbacks de tu sitio. Si se cuela alguno simplemente debes marcar como spam en la pantalla de moderación y Akismet aprenderá de sus errores. SI todavía no tienes una clave de API puedes obtener una en Akismet.com." + +#: wp-content/plugins/akismet/admin.php:146 +msgid "Akismet API Key" +msgstr "Clave de API de Akismet" + +#: wp-content/plugins/akismet/admin.php:150 +msgid "What is this?" +msgstr "¿Qué es esto?" + +#: wp-content/plugins/akismet/admin.php:152 +msgid "Why might my key be invalid?" +msgstr "¿Por qué no es válida mi clave?" + +#: wp-content/plugins/akismet/admin.php:153 +msgid "This can mean one of two things, either you copied the key wrong or that the plugin is unable to reach the Akismet servers, which is most often caused by an issue with your web host around firewalls or similar." +msgstr "Esto puede significar una de estas dos cosas: que has copiado mal la clave o que el plugin no es capaz de encontrar los servidores de Akismet, que a menudo suele ocurrir por un problema con tu alojamiento web con los cortafuegos o algo similar." + +#: wp-content/plugins/akismet/admin.php:157 +msgid "Auto-delete spam submitted on posts more than a month old." +msgstr "Autoborrado de spam realizado para entradas con más de un mes de antiguedad." + +#: wp-content/plugins/akismet/admin.php:158 +msgid "Show the number of comments you've approved beside each comment author." +msgstr "Mostrar el número de comentarios que has aprobado junto al autor de cada comentario." + +#: wp-content/plugins/akismet/admin.php:159 +msgid "Update options »" +msgstr "Actualizar opciones »" + +#: wp-content/plugins/akismet/admin.php:164 +msgid "Server Connectivity" +msgstr "Conectividad del servidor" + +#: wp-content/plugins/akismet/admin.php:168 +msgid "Network functions are disabled." +msgstr "Las funciones de red están desactivadas." + +#: wp-content/plugins/akismet/admin.php:169 +msgid "Your web host or server administrator has disabled PHP's fsockopen or gethostbynamel functions. Akismet cannot work correctly until this is fixed. Please contact your web host or firewall administrator and give them this information about Akismet's system requirements." +msgstr "Tu servidor tiene desactivada la función fsockopen o la función gethostbynamel de PHP. Akismet no puede funcionar correctamente si esto está desactivado. Por favor, ponte en contacto con tu proveedor e infórmales sobre los requisitos de Akismet." + +#: wp-content/plugins/akismet/admin.php:177 +msgid "Unable to reach some Akismet servers." +msgstr "No se puede acceder a ningún servidor de Akismet." + +#: wp-content/plugins/akismet/admin.php:178 +msgid "A network problem or firewall is blocking some connections from your web server to Akismet.com. Akismet is working but this may cause problems during times of network congestion. Please contact your web host or firewall administrator and give them this information about Akismet and firewalls." +msgstr "Un problema en la red o en el firewall está bloqueando algunas conexiones de su servidor web para Akismet.com. Akismet está funcionando pero esto te puede causar problemas cuando la red esté saturada. Por favor, ponte en contacto con tuproveedor e infórmales sobre este problema." + +#: wp-content/plugins/akismet/admin.php:182 +msgid "Unable to reach any Akismet servers." +msgstr "No se puede acceder a ningún servidor de Akismet." + +#: wp-content/plugins/akismet/admin.php:183 +msgid "A network problem or firewall is blocking all connections from your web server to Akismet.com. Akismet cannot work correctly until this is fixed. Please contact your web host or firewall administrator and give them this information about Akismet and firewalls." +msgstr "Un problema en la red o en el firewall está bloqueando algunas conexiones de tu servidor web para Akismet.com. Akismet no está funcionando correctamente. Por favor, ponte en contacto con tu proveedor e infórmales sobre este problema." + +#: wp-content/plugins/akismet/admin.php:187 +msgid "All Akismet servers are available." +msgstr "Todos los servidores Akismet están disponibles." + +#: wp-content/plugins/akismet/admin.php:188 +msgid "Akismet is working correctly. All servers are accessible." +msgstr "Akismet está funcionando correctamente. Se puede acceder a todos los servidores." + +#: wp-content/plugins/akismet/admin.php:193 +msgid "Unable to find Akismet servers." +msgstr "No se pudieron encontrar los servidores de Akismet." + +#: wp-content/plugins/akismet/admin.php:194 +msgid "A DNS problem or firewall is preventing all access from your web server to Akismet.com. Akismet cannot work correctly until this is fixed. Please contact your web host or firewall administrator and give them this information about Akismet and firewalls." +msgstr "Un problema de DNS o en el firewall impide el acceso de su servidor a Akismet.com. Akismet no puede funcionar correctamente con este problema. Por favor, ponte en contacto con tu proveedor e infórmales sobre este problema." + +#: wp-content/plugins/akismet/admin.php:202 +msgid "Akismet server" +msgstr "Servidor Akismet" + +#: wp-content/plugins/akismet/admin.php:202 +msgid "Network Status" +msgstr "Estado de la red" + +#: wp-content/plugins/akismet/admin.php:211 +msgid "Accessible" +msgstr "Accesible" + +#: wp-content/plugins/akismet/admin.php:211 +msgid "Re-trying" +msgstr "Intentándolo de nuevo" + +#: wp-content/plugins/akismet/admin.php:219 +msgid "Last checked %s ago." +msgstr "Última consulta hace %s." + +#: wp-content/plugins/akismet/admin.php:220 +msgid "Check network status »" +msgstr "Comprueba el estado de la red »" + +#: wp-content/plugins/akismet/admin.php:221 +msgid "Click here to confirm that Akismet.com is up." +msgstr "Haz click aquí para confirmar que Akismet.com está funcionando." + +#: wp-content/plugins/akismet/admin.php:231 +msgid "Akismet Stats" +msgstr "Estadísticas de Akismet" + +#: wp-content/plugins/akismet/admin.php:275 +msgctxt "comments" +msgid "Spam" +msgstr "Spam" + +#: wp-content/plugins/akismet/admin.php:281 +msgid "Akismet has protected your site from %3$s spam comments." +msgid_plural "Akismet has protected your site from %3$s spam comments." +msgstr[0] "Akismet ha protegido tu sitio de %3$s comentarios de spam." +msgstr[1] "Akismet ha protegido tu sitio de %3$s comentarios de spam." + +#: wp-content/plugins/akismet/admin.php:290 +msgid "Akismet is almost ready." +msgstr "Akismet casi está preparado." + +#: wp-content/plugins/akismet/admin.php:290 +msgid "You must enter your Akismet API key for it to work." +msgstr "Debes introducir tu clave de API de Akismet para que funcione." + +#: wp-content/plugins/akismet/admin.php:302 +msgid "Akismet has detected a problem." +msgstr "Akismet ha detectado un problema." + +#: wp-content/plugins/akismet/admin.php:302 +msgid "A server or network problem prevented Akismet from checking %d comment. It has been temporarily held for moderation and will be automatically re-checked in %s." +msgid_plural "A server or network problem prevented Akismet from checking %d comments. They have been temporarily held for moderation and will be automatically re-checked in %s." +msgstr[0] "Un problema del servidor o de la red impidió a Akismet revisar el comentario %d. Ha sido temporalmente puesto en moderación y se volverá a revisar en %s." +msgstr[1] "Un problema del servidor o de la red impidió a Akismet revisar los comentarios %d. Han sido temporalmente puestos en moderación y se volverán a revisar en %s." + +#: wp-content/plugins/akismet/admin.php:325 +msgid "Flagged as spam by Akismet" +msgstr "Marcado como spam por Akismet" + +#: wp-content/plugins/akismet/admin.php:327 +msgid "Cleared by Akismet" +msgstr "Borrado por Akismet" + +#: wp-content/plugins/akismet/admin.php:331 +msgid "Flagged as spam by %s" +msgstr "Marcado como spam por %s" + +#: wp-content/plugins/akismet/admin.php:333 +msgid "Un-spammed by %s" +msgstr "Desmarcado como spam por %s" + +#: wp-content/plugins/akismet/admin.php:342 +#: wp-content/plugins/akismet/admin.php:349 +msgid "View comment history" +msgstr "Ver histórico de comentarios" + +#: wp-content/plugins/akismet/admin.php:342 +msgid "History" +msgstr "Historial" + +#: wp-content/plugins/akismet/admin.php:354 +msgid "%s approved" +msgid_plural "%s approved" +msgstr[0] "%s aprobado" +msgstr[1] "%s aprobados" + +#: wp-content/plugins/akismet/admin.php:381 +msgid "Akismet" +msgstr "Akismet" + +#: wp-content/plugins/akismet/admin.php:444 +msgid "Akismet has protected your site from %2$s spam comment already. " +msgid_plural "Akismet has protected your site from %2$s spam comments already. " +msgstr[0] "Akismet ha protegido su sitio de %2$s comentario de spam hasta ahora." +msgstr[1] "Akismet ha protegido su sitio de %2$s comentarios de spam hasta ahora." + +#: wp-content/plugins/akismet/admin.php:450 +msgid "Akismet blocks spam from getting to your blog. " +msgstr "Akismet bloquea el spam que llegue a tu sitio." + +#: wp-content/plugins/akismet/admin.php:454 +msgid "There's %1$s comment in your spam queue right now." +msgid_plural "There are %1$s comments in your spam queue right now." +msgstr[0] "Hay %1$s comentario en la cola de spam en este momento." +msgstr[1] "Hay %1$s comentarios en la cola de spam en este momento." + +#: wp-content/plugins/akismet/admin.php:460 +msgid "There's nothing in your spam queue at the moment." +msgstr "En este momento no tienes nada en la cola de spam. " + +#: wp-content/plugins/akismet/admin.php:478 +msgid "Check for Spam" +msgstr "Comprobar la lista de spam" + +#: wp-content/plugins/akismet/admin.php:521 +msgid "%s reported this comment as not spam" +msgstr "%s no considera este comentario como spam" + +#: wp-content/plugins/akismet/admin.php:570 +msgid "%s reported this comment as spam" +msgstr "%s considera que este comentario es spam" + +#: wp-content/plugins/akismet/admin.php:615 +msgid "%s changed the comment status to %s" +msgstr "%s cambió el estado del comentario a %s" + +#: wp-content/plugins/akismet/admin.php:680 +msgid "Akismet re-checked and caught this comment as spam" +msgstr "Akismet ha revisado de nuevo el comentario y lo considera spam" + +#: wp-content/plugins/akismet/admin.php:684 +msgid "Akismet re-checked and cleared this comment" +msgstr "Akismet revisó de nuevo este comentario y lo ha marcado como bueno" + +#: wp-content/plugins/akismet/admin.php:688 +msgid "Akismet was unable to re-check this comment (response: %s)" +msgstr "Akismet ha sido incapaz de revisar de nuevo el comentario (respuesta: %s)" + +#: wp-content/plugins/akismet/legacy.php:47 +msgid "Akismet Spam (%s)" +msgstr "Spam en Akismet (%s)" + +#: wp-content/plugins/akismet/legacy.php:49 +#: wp-content/plugins/akismet/legacy.php:51 +msgid "Akismet Spam" +msgstr "Spam en Akismet" + +#: wp-content/plugins/akismet/legacy.php:61 +#: wp-content/plugins/akismet/legacy.php:80 +msgid "You do not have sufficient permission to moderate comments." +msgstr "No tienes autorización para moderar comentarios." + +#: wp-content/plugins/akismet/legacy.php:96 +msgid "%1$s comments recovered." +msgstr "%1$s comentario ha sido recuperado." + +#: wp-content/plugins/akismet/legacy.php:100 +msgid "All spam deleted." +msgstr "Todo el spam ha sido borrado." + +#: wp-content/plugins/akismet/legacy.php:148 +msgid "Caught Spam" +msgstr "Spam capturado" + +#: wp-content/plugins/akismet/legacy.php:153 +msgid "Akismet has caught %1$s spam for you since you first installed it." +msgstr "Akismet ha capturado %1$s spam desde la primera vez que lo instalaste." + +#: wp-content/plugins/akismet/legacy.php:160 +msgid "You have no spam currently in the queue. Must be your lucky day. :)" +msgstr "En este momento no tienes spam en cola. Debe ser tu día de suerte. :)" + +#: wp-content/plugins/akismet/legacy.php:163 +msgid "You can delete all of the spam from your database with a single click. This operation cannot be undone, so you may wish to check to ensure that no legitimate comments got through first. Spam is automatically deleted after 15 days, so don’t sweat it." +msgstr "Puedes borrar todo el spam de tu base de datos con un solo clic. Esta operación no es reversible así que puede que quieras antes comprobar si hay comentarios legítimos. El spam se borra automáticamente a los 15 días, así que no te agobies." + +#: wp-content/plugins/akismet/legacy.php:169 +#: wp-content/plugins/akismet/legacy.php:347 +msgid "There are currently %1$s comments identified as spam." +msgstr "En este momento hay %1$s comentarios identificados como spam." + +#: wp-content/plugins/akismet/legacy.php:169 +#: wp-content/plugins/akismet/legacy.php:347 +msgid "Delete all" +msgstr "Borrar todos" + +#: wp-content/plugins/akismet/legacy.php:178 +msgid "These are the latest comments identified as spam by Akismet. If you see any mistakes, simply mark the comment as \"not spam\" and Akismet will learn from the submission. If you wish to recover a comment from spam, simply select the comment, and click Not Spam. After 15 days we clean out the junk for you." +msgstr "Estos son los últimos comentarios identificados como spam por Akismet. Si encuentras algún error, sólo tienes que marcarlo como \"No es spam\" y Akismet aprenderá al recibirlo. Si deseas recuperar un comentario, selecciónalo y haz clic en \"No es spam\". Tras 15 días, la basura desaparecerá sola." + +#: wp-content/plugins/akismet/legacy.php:232 +msgid "Search Spam »" +msgstr "Buscar spam »" + +#: wp-content/plugins/akismet/legacy.php:282 +msgid "IP:" +msgstr "IP:" + +#: wp-content/plugins/akismet/legacy.php:288 +msgid "Not Spam" +msgstr "No es spam" + +#: wp-content/plugins/akismet/legacy.php:333 +msgid "De-spam marked comments »" +msgstr "Quitar marca de spam »" + +#: wp-content/plugins/akismet/legacy.php:335 +msgid "Comments you de-spam will be submitted to Akismet as mistakes so it can learn and get better." +msgstr "Los comentarios a los que quites la marca de \"spam\" se enviarán a Akismet como errores para que vaya aprendiendo y mejorando." + +#: wp-content/plugins/akismet/legacy.php:385 +msgid "Recheck Queue for Spam" +msgstr "Volver a comprobar cola de spam" + +#: wp-includes/load.php:20 +msgid "GLOBALS overwrite attempt detected" +msgstr "Detectado intento GLOBAL de sobrescritura." + +#: wp-includes/load.php:107 +msgid "Your server is running PHP version %1$s but WordPress %2$s requires at least %3$s." +msgstr "Tu servidor está ejecutando la versión %1$s de PHP, pero WordPess %2$s necesita, al menos, la versión %3$s." + +#: wp-includes/load.php:110 +msgid "Your PHP installation appears to be missing the MySQL extension which is required by WordPress." +msgstr "Parece que tu instalación de PHP no cuenta con la extensión de MySQL, necesaria para hacer funcionar WordPress." + +#: wp-includes/load.php:168 +msgid "Maintenance" +msgstr "Mantenimiento" + +#: wp-includes/load.php:172 +msgid "Briefly unavailable for scheduled maintenance. Check back in a minute." +msgstr "No disponible por mantenimiento programado. Vuelve a comprobar el sitio en unos minutos." + +#: wp-includes/load.php:365 +msgid "ERROR: $table_prefix in wp-config.php can only contain numbers, letters, and underscores." +msgstr "ERROR: $table_prefix en wp-config.php sólo puede contener números, letras y guiones bajos." + +#: wp-includes/functions.php:1879 +msgid "One or more database tables are unavailable. The database may need to be repaired." +msgstr "Una tabla o más de la base de dato no están disponibles. La base de datos debe ser reparada." + +#: wp-includes/wp-db.php:581 +msgid "Invalid database prefix" +msgstr "Prefijo de la base de datos no válido" + +#: wp-includes/wp-db.php:759 +msgid "" +"

    Can’t select database

    \n" +"

    We were able to connect to the database server (which means your username and password is okay) but not able to select the %1$s database.

    \n" +"
      \n" +"
    • Are you sure it exists?
    • \n" +"
    • Does the user %2$s have permission to use the %1$s database?
    • \n" +"
    • On some systems the name of your database is prefixed with your username, so it would be like username_%1$s. Could that be the problem?
    • \n" +"
    \n" +"

    If you don't know how to set up a database you should contact your host. If all else fails you may find help at the WordPress Support Forums.

    " +msgstr "" +"

    No se pudo elegir base de datos

    \n" +"

    Hemos podido conectar con el servidor de la bases de datos (lo que significa que tu nombre de usuario y la contraseña están correctos) pero no se pudo elegir la base de datos %1$s.

    \n" +"
      \n" +"
    • ¿Estás seguro que existe?
    • \n" +"
    • ¿El usuario %2$s tiene permiso para utilizar la base de datos %1$?
    • \n" +"
    • En algunos sistemas el nombre de la base de datos es el prefijo con el nombre de usuario, que sería como username_%1$s. ¿Podría ser ésto el problema?
    • \n" +"
    \n" +"

    Si no sabes cómo configurar una base de datos debes ponerte en contacto con el administrador de su hosting. Si todo lo demás falla puedes encontrar ayuda en los Foros de Soporte de WordPress.

    " + +#: wp-includes/wp-db.php:930 +msgid "WordPress database error %1$s for query %2$s made by %3$s" +msgstr "Error %1$s de la base de datos de WordPress para la consulta %2$s realizada por %3$s" + +#: wp-includes/wp-db.php:932 +msgid "WordPress database error %1$s for query %2$s" +msgstr "Error %1$s de la base de datos de WordPress para la consulta %2$s" + +#: wp-includes/wp-db.php:1051 +msgid "" +"\n" +"

    Error establishing a database connection

    \n" +"

    This either means that the username and password information in your wp-config.php file is incorrect or we can't contact the database server at %s. This could mean your host's database server is down.

    \n" +"
      \n" +"\t
    • Are you sure you have the correct username and password?
    • \n" +"\t
    • Are you sure that you have typed the correct hostname?
    • \n" +"\t
    • Are you sure that the database server is running?
    • \n" +"
    \n" +"

    If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the WordPress Support Forums.

    \n" +msgstr "" +"\n" +"

    Error de conexión con la base de datos

    \n" +"

    Esto puede deberse a que los datos de usuario y contraseña de tu wp-config.php son incorrectos o a que no es posible contactar con el servidor de base de datos en %s, lo que podría significar que el servidor de bases de datos de tu host está inactivo.

    \n" +"
      \n" +"\t
    • ¿Estás seguro de que el nombre de usuario y la contraseña son correctos?
    • \n" +"\t
    • ¿Estás seguro de que el nombre del host es correcto?
    • \n" +"\t
    • ¿Estás seguro de que el servidor de bases de datos está activo?
    • \n" +"
    \n" +"

    Si no tienes muy claro lo que significan los términos anteriores, ponte en contacto con tu proveedor de alojamiento. Si necesitas más ayuda, puedes visitar los Foros de ayuda de WordPress.

    \n" + +#: wp-includes/wp-db.php:1328 +msgid " $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" +msgstr " $db->get_row(string query, output type, int offset) -- El tipo de salida (output) debe ser uno de estos: OBJECT, ARRAY_A, ARRAY_N" + +#: wp-admin/setup-config.php:62 +msgid "Your server is running PHP version %1$s but WordPress requires at least %2$s." +msgstr "Tu servidor funciona con la versión %1$s de PHP, pero WordPress requiere como mínimo la %2$s." + +#: wp-admin/setup-config.php:165 +msgid "ERROR: \"Table Prefix\" can only contain numbers, letters, and underscores." +msgstr "ERROR: El \"Prefijo Tabla\" sólo puede contener números, letras y guiones bajos." + +#: wp-load.php:51 +msgid "ltr" +msgstr "ltr" + +#: wp-load.php:52 +msgid "There doesn't seem to be a wp-config.php file. I need this before we can get started. Need more help? We got it. You can create a wp-config.php file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file.

    Create a Configuration File" +msgstr "Aparentemente falta el archivo wp-config.php. Este archivo es necesario para empezar. ¿Necesitas ayuda? La encontrarás aquí (en inglés). Puedes crear un archivo wp-config.php a través de la web, pero esto no funciona en algunos servidores. Lo más seguro es crear el archivo manualmente.

    Crear un archivo de configuración" + +#: wp-admin/options-media.php:107 +msgid "Store uploads in this folder" +msgstr "Guardar los archivos subidos en esta carpeta" + +#: wp-admin/options-media.php:109 +msgid "Default is wp-content/uploads" +msgstr "El predeterminado es wp-content/uploads" + +#: wp-admin/options-media.php:114 +msgid "Full URL path to files" +msgstr "Ruta URL completa a los archivos" + +#: wp-admin/options-media.php:116 +msgid "Configuring this is optional. By default, it should be blank." +msgstr "Esta configuración es opcional. Por defecto debería estar en blanco." + +#: wp-admin/options-media.php:124 +msgid "Organize my uploads into month- and year-based folders" +msgstr "Organizar mis archivos subidos en carpetas basadas en mes y año" + +#: wp-admin/edit.php:17 wp-admin/post-new.php:17 +#: wp-admin/includes/class-wp-posts-list-table.php:56 +msgid "Invalid post type" +msgstr "Tipo de entrada no válido." + +#: wp-admin/edit.php:81 wp-admin/post.php:220 +msgid "You are not allowed to move this item to the Trash." +msgstr "No te está permitido mover este elemento a la papelera." + +#: wp-admin/edit.php:84 wp-admin/post.php:223 +msgid "Error in moving to Trash." +msgstr "Error moviendo a la papelera." + +#: wp-admin/edit.php:94 +msgid "You are not allowed to restore this item from the Trash." +msgstr "No estás autorizado para restaurar este elemento de la papelera." + +#: wp-admin/edit.php:97 wp-admin/post.php:236 +msgid "Error in restoring from Trash." +msgstr "Error al restaurar de la papelera." + +#: wp-admin/edit.php:109 wp-admin/post.php:246 +msgid "You are not allowed to delete this item." +msgstr "No tienes autorización para borrar este elemento." + +#: wp-admin/edit.php:113 wp-admin/edit.php:116 wp-admin/upload.php:118 +msgid "Error in deleting..." +msgstr "Error al borrar..." + +#: wp-admin/edit.php:157 +msgid "You can customize the display of this screen in a number of ways:" +msgstr "Puedes personalizar cómo se muestra esta pantalla de diferentes formas:" + +#: wp-admin/edit.php:159 +msgid "You can hide/display columns based on your needs and decide how many posts to list per screen using the Screen Options tab." +msgstr "Puedes esconder/mostrar columnas basándote en tus necesidades y decidir cuántas entradas se mostrarán por pantalla utilizando la pestaña Opciones de pantalla." + +#: wp-admin/edit.php:160 +msgid "You can filter the list of posts by post status using the text links in the upper left to show All, Published, Draft, or Trashed posts. The default view is to show all posts." +msgstr "Puedes filtrar la lista de entradas por estados usando los enlaces que aparecen en la parte superior izquierda para mostrar Todas, Publicado, Borrador o entradas en Papelera. La vista por defecto es mostrar todas las entradas." + +#: wp-admin/edit.php:161 +msgid "You can view posts in a simple title list or with an excerpt. Choose the view you prefer by clicking on the icons at the top of the list on the right." +msgstr "Puedes ver las entradas en un listado que muestre sólo los títulos o un fragmento del contenido. Selecciona la vista que prefieras realizando un clic en los iconos que encontrarás en la parte superior derecha del listado." + +#: wp-admin/edit.php:162 +msgid "You can refine the list to show only posts in a specific category or from a specific month by using the dropdown menus above the posts list. Click the Filter button after making your selection. You also can refine the list by clicking on the post author, category or tag in the posts list." +msgstr "Puedes refinar lo que muestra el listado de entradas haciendo que sólo se muestren las de una categoría específica o de un mes determinado usando el menú desplegable que encontrarás sobre el listado de entradas. Realiza un clic sobre el botón Filtro después de realizar tu selección. También puedes refinar el listado haciendo clic sobre el autor de una entrada, categoría o etiqueta del listado de entradas." + +#: wp-admin/edit.php:164 +msgid "Hovering over a row in the posts list will display action links that allow you to manage your post. You can perform the following actions:" +msgstr "Pasando sobre la línea de la entrada, mostrará los enlaces de las acciones, permitiéndote gestionar la entrada. Puedes realizar las siguientes acciones:" + +#: wp-admin/edit.php:166 +msgid "Edit takes you to the editing screen for that post. You can also reach that screen by clicking on the post title." +msgstr "Editar te lleva a la pantalla de edición de entradas. También puedes acceder a esta pantalla haciendo clic sobre el título de cada entrada." + +#: wp-admin/edit.php:167 +msgid "Quick Edit provides inline access to the metadata of your post, allowing you to update post details without leaving this screen." +msgstr "Edición rápida te da acceso en línea a los metadatos de tu entrada, permitiéndote actualizar los detalles de tu entrada sin abandonar la pantalla." + +#: wp-admin/edit.php:168 +msgid "Trash removes your post from this list and places it in the trash, from which you can permanently delete it." +msgstr "Papelera elimina la entrada de esta lista y la coloca en la papelera. Desde ahí la podrás eliminar de forma permanente." + +#: wp-admin/edit.php:169 +msgid "Preview will show you what your draft post will look like if you publish it. View will take you to your live site to view the post. Which link is available depends on your post’s status." +msgstr "Previsualizar te mostrará cómo se verá la entrada antes de publicarla. Ver te llevará a tu sitio público para ver tu entrada publicada. Cada uno de los enlaces está disponible dependiendo del estado de tu entrada." + +#: wp-admin/edit.php:171 +msgid "You can also edit multiple posts at once. Select the posts you want to edit using the checkboxes, select Edit from the Bulk Actions menu and click Apply. You will be able to change the metadata (categories, author, etc.) for all selected posts at once. To remove a post from the grouping, just click the x next to its name in the Bulk Edit area that appears." +msgstr "También puedes editar múltiples entradas de una sola vez. Elige las entradas marcando en sus casillas de verificación, elige Editar en el menú Acciones en lote y haz clic en Aplicar. Esto te permitirá cambiar los metadatos (categorías, autor, etc) de todas las entradas elegidas a la vez. Para eliminar una entrada del grupo, simplemente haz click en la x que está junto a su nombre en el área de Edición en lote." + +#: wp-admin/edit.php:173 +msgid "Documentation on Managing Posts" +msgstr "Documentación sobre gestionar entradas" + +#: wp-admin/edit.php:179 +msgid "Managing Pages is very similar to managing Posts, and the screens can be customized in the same way." +msgstr "Gestionar páginas es muy similar a gestionar entradas y la pantalla se puede personalizar de la misma forma." + +#: wp-admin/edit.php:180 +msgid "You can also perform the same types of actions, including narrowing the list by using the filters, acting on a Page using the action links that appear when you hover over a row, or using the Bulk Actions menu to edit the metadata for multiple Pages at once." +msgstr "También puedes realizar el mismo tipo que acciones, incluyendo reducir el listado usando filtros, acciones en una página usando las acciones que aparecen cuando te pones sobre ellas o usar el menú Acciones en lote para editar los metadatos de múltiples páginas de una sola vez." + +#: wp-admin/edit.php:182 +msgid "Documentation on Managing Pages" +msgstr "Documentación sobre gestión de páginas" + +#: wp-admin/edit.php:200 +msgid "This has been saved." +msgstr "Se ha guardado." + +#: wp-admin/edit.php:207 +msgid "%s post updated." +msgid_plural "%s posts updated." +msgstr[0] "%s entrada actualizada." +msgstr[1] "%s entradas actualizadas." + +#: wp-admin/edit.php:215 +msgid "%s item not updated, somebody is editing it." +msgid_plural "%s items not updated, somebody is editing them." +msgstr[0] "%s no se ha actualizado, alguien lo está editando." +msgstr[1] "%s no se han actualizado, alguien los está editando." + +#: wp-admin/edit.php:220 +msgid "Item permanently deleted." +msgid_plural "%s items permanently deleted." +msgstr[0] "Borrado permanentemente." +msgstr[1] "%s borrados permanentemente." + +#: wp-admin/edit.php:225 +msgid "Item moved to the Trash." +msgid_plural "%s items moved to the Trash." +msgstr[0] "Movido a la papelera" +msgstr[1] "%s movidos a la papelera." + +#: wp-admin/edit.php:232 +msgid "Item restored from the Trash." +msgid_plural "%s items restored from the Trash." +msgstr[0] "Elemento restaurado de la papelera." +msgstr[1] "%s elementos restaurados de la papelera." + +#: wp-admin/upload.php:42 +msgid "You are not allowed to scan for lost attachments." +msgstr "No tienes autorización para buscar adjuntos perdidos." + +#: wp-admin/upload.php:62 wp-admin/admin-ajax.php:957 +#: wp-admin/admin-ajax.php:1168 wp-admin/includes/post.php:148 +#: wp-admin/includes/post.php:1361 +msgid "You are not allowed to edit this post." +msgstr "No tienes autorización para editar esta entrada." + +#: wp-admin/upload.php:95 +msgid "You are not allowed to move this post to the trash." +msgstr "No tienes autorización para mover esta entrada a la papelera." + +#: wp-admin/upload.php:98 +msgid "Error in moving to trash..." +msgstr "Error al mover a la papelera..." + +#: wp-admin/upload.php:105 +msgid "You are not allowed to move this post out of the trash." +msgstr "No tienes autorización para sacar esta entrada de la papelera." + +#: wp-admin/upload.php:108 +msgid "Error in restoring from trash..." +msgstr "Error al restaurar de la papelera..." + +#: wp-admin/upload.php:115 +msgid "You are not allowed to delete this post." +msgstr "No tienes autorización para borrar esta entrada." + +#: wp-admin/upload.php:139 wp-admin/includes/media.php:21 +msgid "Media Library" +msgstr "Librería multimedia" + +#: wp-admin/upload.php:146 +msgctxt "items per page (screen options)" +msgid "Media items" +msgstr "Elementos multimedia" + +#: wp-admin/upload.php:149 +msgid "All the files you’ve uploaded are listed in the Media Library, with the most recent uploads listed first. You can use the Screen Options tab to customize the display of this screen." +msgstr "Todos los archivos que has subido están listados en la Librería multimedia, con las subidas más recientes listadas al principio. Puedes usar la pestaña Opciones de pantalla para personalizar cómo se muestra esta pantalla. " + +#: wp-admin/upload.php:150 +msgid "You can narrow the list by file type/status using the text link filters at the top of the screen. You also can refine the list by date using the dropdown menu above the media table." +msgstr "Puedes reducir el listado por tipo/estado usando los filtros en la parte superior de la pantalla. También puedes refinar la búsqueda por fecha usando el menú desplegable junto a la tabla de multimedia." + +#: wp-admin/upload.php:151 +msgid "Hovering over a row reveals action links: Edit, Delete Permanently, and View. Clicking Edit or on the media file’s name displays a simple screen to edit that individual file’s metadata. Clicking Delete Permanently will delete the file from the media library (as well as from any posts to which it is currently attached). View will take you to the display page for that file." +msgstr "Pasando por encima de la fila revela los enlaces de acción: Editar, Eliminar permanentemente, y Ver. Haciendo clic sobre Editar o sobre el nombre del archivo multimedia mostrará una pantalla simple para poder editar metadatos. Haciendo click en Eliminar permanentemente eliminará el archivo de la librería multimedia (como de las entradas que la estén usando). Ver te llevará a la pantalla de visualizado para el archivo." + +#: wp-admin/upload.php:152 +msgid "If a media file has not been attached to any post, you will see that in the Attached To column, and can click on Attach File to launch a small popup that will allow you to search for a post and attach the file." +msgstr "Si un archivo multimedia no se ha adjuntado a ninguna entrada, lo verás que en la columna Adjunto a y haciendo click en Adjuntar archivo te desplegará una pequeña ventana emergente que te permitirá buscar una entrada y adjuntarle el archivo." + +#: wp-admin/upload.php:154 +msgid "Documentation on Media Library" +msgstr "Documentación sobre la biblioteca multimedia" + +#: wp-admin/upload.php:163 wp-admin/menu.php:82 +msgctxt "file" +msgid "Add New" +msgstr "Añadir nuevo" + +#: wp-admin/upload.php:177 +msgid "Reattached %d attachment." +msgid_plural "Reattached %d attachments." +msgstr[0] "Se ha vuelto a adjuntar %d adjunto." +msgstr[1] "Se han vuelto a adjuntar %d adjuntos." + +#: wp-admin/upload.php:182 +msgid "Media attachment permanently deleted." +msgid_plural "%d media attachments permanently deleted." +msgstr[0] "Medio adjunto borrado permanentemente." +msgstr[1] "%d medios adjuntos borrados permanentemente." + +#: wp-admin/upload.php:187 +msgid "Media attachment moved to the trash." +msgid_plural "%d media attachments moved to the trash." +msgstr[0] "Medio adjunto movido a la papelera." +msgstr[1] "%d medios adjuntos movidos a la papelera." + +#: wp-admin/upload.php:193 +msgid "Media attachment restored from the trash." +msgid_plural "%d media attachments restored from the trash." +msgstr[0] "Medio adjunto restaurado de la papelera." +msgstr[1] "%d medios adjuntos restaurados de la papelera." + +#: wp-admin/upload.php:198 +msgid "Media permanently deleted." +msgstr "Medio borrado permanentemente." + +#: wp-admin/upload.php:199 +msgid "Error saving media attachment." +msgstr "Error al guardar el archivo." + +#: wp-admin/upload.php:200 +msgid "Media moved to the trash." +msgstr "Medios movidos a la papelera." + +#: wp-admin/upload.php:201 +msgid "Media restored from the trash." +msgstr "Medios restaurados de la papelera." + +#: wp-admin/upload.php:216 wp-admin/includes/media.php:1927 +#: wp-admin/includes/media.php:1929 +msgid "Search Media" +msgstr "Buscar medios" + +#: wp-admin/admin-footer.php:23 +msgid "Thank you for creating with WordPress." +msgstr "Gracias por crear con WordPress." + +#: wp-admin/admin-footer.php:23 +msgid "Documentation" +msgstr "Documentación" + +#: wp-admin/admin-footer.php:23 +msgid "Feedback" +msgstr "Feedback" + +#: wp-admin/options-head.php:16 wp-admin/options.php:154 +msgid "Settings saved." +msgstr "Ajustes guardados." + +#: wp-admin/admin-ajax.php:36 +msgid "ALERT: You are logged out! Could not save draft. Please log in again." +msgstr "ATENCIÓN: ¡No has iniciado la sesión! No se pudo guardar el borrador. Vuelve a iniciar la sesión." + +#: wp-admin/admin-ajax.php:231 wp-admin/includes/class-wp-list-table.php:474 +#: wp-admin/includes/class-wp-list-table.php:870 +msgid "1 item" +msgid_plural "%s items" +msgstr[0] "1 elemento" +msgstr[1] "%s elementos" + +#: wp-admin/admin-ajax.php:455 +msgid "Comment %d does not exist" +msgstr "El comentario %d no existe" + +#: wp-admin/admin-ajax.php:524 wp-admin/admin-ajax.php:1372 +msgid "An error has occurred. Please reload the page and try again." +msgstr "Ha ocurrido un error. Por favor, recarga la página e inténtalo de nuevo." + +#: wp-admin/admin-ajax.php:577 +msgid "No tags found!" +msgstr "¡No se han encontrado etiquetas!" + +#: wp-admin/admin-ajax.php:641 +msgid "Error: you are replying to a comment on a draft post." +msgstr "Error: estás respondiendo a un comentario de una entrada en borrador." + +#: wp-admin/admin-ajax.php:656 +msgid "Sorry, you must be logged in to reply to a comment." +msgstr "Lo siento, tienes que iniciar sesión para responder a un comentario." + +#: wp-admin/admin-ajax.php:660 wp-admin/admin-ajax.php:707 +#: wp-comments-post.php:84 +msgid "Error: please type a comment." +msgstr "Error: por favor, escribe un comentario." + +#: wp-admin/admin-ajax.php:828 wp-admin/admin-ajax.php:833 +#: wp-admin/admin-ajax.php:853 +msgid "Please provide a custom field value." +msgstr "Por favor, pon algún valor en el campo personalizado." + +#: wp-admin/admin-ajax.php:851 +msgid "Please provide a custom field name." +msgstr "Por favor, proporciona un nombre al campo personalizado." + +#: wp-admin/admin-ajax.php:903 +msgid "User %s added" +msgstr "Usuario %s añadido" + +#: wp-admin/admin-ajax.php:923 +msgid "g:i:s a" +msgstr "G:i:s" + +#: wp-admin/admin-ajax.php:925 +msgid "Draft saved at %s." +msgstr "Borrador guardado a las %s." + +#: wp-admin/admin-ajax.php:943 wp-admin/admin-ajax.php:1175 +msgid "Someone" +msgstr "Alguien" + +#: wp-admin/admin-ajax.php:945 +msgid "Autosave disabled: %s is currently editing this page." +msgstr "Guardado automático desactivado: %s está ahora mismo editando esta página." + +#: wp-admin/admin-ajax.php:945 +msgid "Autosave disabled: %s is currently editing this post." +msgstr "Guardado automático desactivado: %s está ahora mismo editando esta entrada." + +#: wp-admin/admin-ajax.php:954 wp-admin/admin-ajax.php:1165 +#: wp-admin/includes/post.php:146 wp-admin/includes/post.php:1358 +msgid "You are not allowed to edit this page." +msgstr "No tienes autorización para editar esta página." + +#: wp-admin/admin-ajax.php:1176 +msgid "Saving is disabled: %s is currently editing this page." +msgstr "Guardar está desactivado: %s está ahora mismo editando esta página." + +#: wp-admin/admin-ajax.php:1176 +msgid "Saving is disabled: %s is currently editing this post." +msgstr "Guardar está desactivado: %s está ahora mismo editando esta entrada." + +#: wp-admin/admin-ajax.php:1242 wp-admin/admin-ajax.php:1249 +#: wp-admin/edit-tags.php:233 +msgid "Item not updated." +msgstr "No actualizado." + +#: wp-admin/admin-ajax.php:1286 +#: wp-admin/includes/class-wp-posts-list-table.php:286 +#: wp-admin/includes/class-wp-posts-list-table.php:755 +msgid "Date" +msgstr "Fecha" + +#: wp-admin/admin-ajax.php:1286 +#: wp-admin/includes/class-wp-posts-list-table.php:939 +#: wp-admin/edit-form-comment.php:35 +msgid "Status" +msgstr "Estado" + +#: wp-admin/admin-ajax.php:1295 +#: wp-admin/includes/class-wp-posts-list-table.php:596 +#: wp-admin/includes/class-wp-posts-list-table.php:946 +#: wp-admin/includes/meta-boxes.php:71 wp-admin/includes/meta-boxes.php:94 +msgid "Scheduled" +msgstr "Programada" + +#: wp-admin/admin-ajax.php:1309 +#: wp-admin/includes/class-wp-posts-list-table.php:581 +#: wp-admin/includes/class-wp-comments-list-table.php:353 +#: wp-admin/includes/internal-linking.php:51 +#: wp-admin/includes/class-wp-media-list-table.php:276 +#: wp-admin/includes/class-wp-media-list-table.php:292 +msgid "Y/m/d" +msgstr "d/m/Y" + +#: wp-admin/export.php:13 +msgid "You do not have sufficient permissions to export the content of this site." +msgstr "No tienes suficientes permisos para exportar el contenido de este sitio." + +#: wp-admin/export.php:17 wp-admin/menu.php:212 +msgid "Export" +msgstr "Exportar" + +#: wp-admin/export.php:42 +msgid "You can export a file of your site’s content in order to import it into another installation or platform. The export file will be an XML file format called WXR. Posts, pages, comments, custom fields, categories, and tags can be included. You can choose for the WXR file to include only certain posts or pages by setting the dropdown filters to limit the export by category, author, date range by month, or publishing status." +msgstr "Puedes exportar el contenido de tu sitio’s a un archivo para ser importado en otra instalación o plataforma. El archivo de importación es un archivo XML llamado WXR. Entradas, páginas, comentarios, campos personalizados, categorías y etiquetas se incluirán en él. Puedes elegir sólo algunas entradas o páginas, basta con limitar la exportación a determinadas categorías, autor, rango de fechas por meses o estatus de publicación en los filtros de descarte." + +#: wp-admin/export.php:43 +msgid "Once generated, your WXR file can be imported by another WordPress site or by another blogging platform able to access this format." +msgstr "Una vez generado, tu archivo WXR puede ser importado por otro sitio WordPress o por otra plataforma de blogs que pueda acceder a este formato." + +#: wp-admin/export.php:45 +msgid "Documentation on Export" +msgstr "Documentación sobre exportaciones" + +#: wp-admin/export.php:121 +msgid "When you click the button below WordPress will create an XML file for you to save to your computer." +msgstr "Cuando hagas clic en el botón de abajo, WordPress creará un archivo XML para que lo guardes en tu ordenador." + +#: wp-admin/export.php:122 +msgid "This format, which we call WordPress eXtended RSS or WXR, will contain your posts, pages, comments, custom fields, categories, and tags." +msgstr "Este formato, que llamamos WordPress eXtended RSS (RSS ampliado de WordPress) o WXR, contendrá todas tus entradas, comentarios, campos personalizados, categorías y etiquetas." + +#: wp-admin/export.php:123 +msgid "Once you’ve saved the download file, you can use the Import function in another WordPress installation to import this site." +msgstr "Una vez que hayas guardado el archivo de descarga, puedes utilizar la función importar en otra instalación de WordPress para importar este sitio." + +#: wp-admin/export.php:125 +msgid "Choose what to export" +msgstr "Elige qué exportar" + +#: wp-admin/export.php:128 +msgid "All content" +msgstr "Todo el contenido" + +#: wp-admin/export.php:129 +msgid "This will contain all of your posts, pages, comments, custom fields, terms, navigation menus and custom posts." +msgstr "Esto contendrá todas tus entradas, páginas, comentarios, campos personalizados, menús de navegación y entradas personalizadas." + +#: wp-admin/export.php:131 wp-admin/includes/class-wp-users-list-table.php:166 +#: wp-admin/includes/class-wp-terms-list-table.php:110 wp-admin/menu.php:65 +#: wp-admin/menu.php:66 +msgid "Posts" +msgstr "Entradas" + +#: wp-admin/export.php:134 +msgid "Categories:" +msgstr "Categorías:" + +#: wp-admin/export.php:135 wp-admin/export.php:141 wp-admin/export.php:158 +#: wp-admin/export.php:173 wp-admin/export.php:190 +#: wp-content/plugins/akismet/legacy.php:209 +msgid "All" +msgstr "Todo" + +#: wp-admin/export.php:138 wp-admin/export.php:170 +msgid "Authors:" +msgstr "Autores:" + +#: wp-admin/export.php:145 wp-admin/export.php:177 +msgid "Date range:" +msgstr "Rango de fechas:" + +#: wp-admin/export.php:147 wp-admin/export.php:179 +msgid "Start Date" +msgstr "Fecha de inicio" + +#: wp-admin/export.php:151 wp-admin/export.php:183 +msgid "End Date" +msgstr "Fecha de finalización" + +#: wp-admin/export.php:156 wp-admin/export.php:188 +#: wp-admin/includes/meta-boxes.php:60 +msgid "Status:" +msgstr "Estado:" + +#: wp-admin/export.php:202 +msgid "Download Export File" +msgstr "Descargar el archivo de exportación" + +#: wp-admin/theme-install.php:16 +msgid "You do not have sufficient permissions to install themes on this site." +msgstr "No tienes suficientes permisos para instalar temas en este sitio." + +#: wp-admin/theme-install.php:32 wp-admin/includes/template.php:1447 +#: wp-admin/update.php:210 +msgid "Install Themes" +msgstr "Instalar temas" + +#: wp-admin/theme-install.php:47 +msgid "You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the WordPress.org Theme Directory. These themes are designed and developed by third parties, are available free of charge, and are licensed under the GNU General Public License, version 2, just like WordPress." +msgstr "Puedes encontrar temas adicionales para tu sitio usando el Instalador/Navegador de temas de esta pantalla, que te mostrará temas del directorio de temas de WordPress.org. Estos temas están diseñados y desarrollados por terceros, y todos están bajo la licencia pública general GNU versión 2, al igual que WordPress." + +#: wp-admin/theme-install.php:48 +msgid "You can Search for themes by keyword, author, or tag, or can get more specific and search by criteria listed in the feature filter. Alternately, you can browse the themes that are Featured, Newest, or Recently Updated. When you find a theme you like, you can preview it or install it." +msgstr "Puedes buscar temas por palabras clave, autor o etiquetas o puedes ser más específico y buscar por criterios utilizando los filtros. De forma alternativa, puedes ver los temas Destacados, Nuevos o Actualizados Recientemente. Cuando encuentres el tema que te guste, puedes realizar una previsualización o instalarlo." + +#: wp-admin/theme-install.php:49 +msgid "You can Upload a theme manually if you have already downloaded its ZIP archive onto your computer (make sure it is from a trusted and original source). You can also do it the old-fashioned way and copy a downloaded theme’s folder via FTP into your /wp-content/themes directory." +msgstr "Pudes subir manualmente un tema si ya has descargado su archivo ZIP en tu ordenador (asegúrate de que sea de una fuente fiable y original). También puedes hacerlo al viejo estilo y copiar un tema descargado a través de FTP en tu directorio /wp-content/themes." + +#: wp-admin/theme-install.php:51 +msgid "Documentation on Adding New Themes" +msgstr "Documentación sobre Añadir nuevos temas" + +#: wp-admin/theme-install.php:64 +msgctxt "theme" +msgid "Manage Themes" +msgstr "Administrar temas" + +#: wp-admin/users.php:17 wp-admin/includes/template.php:1470 +#: wp-admin/menu.php:187 wp-admin/menu.php:193 +msgid "Users" +msgstr "Usuarios" + +#: wp-admin/users.php:20 +msgctxt "users per page (screen options)" +msgid "Users" +msgstr "Usuarios" + +#: wp-admin/users.php:24 +msgid "This screen lists all the existing users for your site. Each user has one of five defined roles as set by the site admin: Site Administrator, Editor, Author, Contributor, or Subscriber. Users with roles other than Administrator will see fewer options in the dashboard navigation when they are logged in, based on their role." +msgstr "Esta pantalla muestra todos los usuarios existentes para tu sitio. Cada usuario dispone de uno de los cinco perfiles definidos según lo establecido por el administrador del sitio: Administrador del sitio, editor, autor, colaborador o suscriptor. Los usuarios con perfiles que no sean de administrador verán menos opciones en el panel de navegación cuando se hayan identificado, en base a su perfil." + +#: wp-admin/users.php:25 +msgid "You can customize the display of information on this screen as you can on other screens, by using the Screen Options tab and the on-screen filters." +msgstr "Puedes personalizar la información de esta pantalla al igual que en las otras, usando la pestaña Opciones de Pantalla y los filtros en pantalla." + +#: wp-admin/users.php:26 +msgid "To add a new user for your site, click the Add New button at the top of the screen or Add New in the Users menu section." +msgstr "Para añadir un usuario nuevo a tu sitio haz clic en el botón Añadir nuevo en la parte superior de la pantalla o en la sección Añadir nuevo del menú Usuarios." + +#: wp-admin/users.php:28 +msgid "Documentation on Managing Users" +msgstr "Documentación sobre la gestión de usuarios" + +#: wp-admin/users.php:29 +msgid "Descriptions of Roles and Capabilities" +msgstr "Descripción de los perfiles y capacidades" + +#: wp-admin/users.php:52 wp-admin/users.php:69 +msgid "You can’t edit that user." +msgstr "No puedes editar ese usuario." + +#: wp-admin/users.php:61 wp-admin/includes/user.php:34 +#: wp-admin/includes/user.php:88 +msgid "You can’t give users that role." +msgstr "No puedes dar este perfil a los usuarios." + +#: wp-admin/users.php:91 wp-admin/users.php:138 +msgid "User deletion is not allowed from this screen." +msgstr "No está permitido eliminar usuarios desde esta pantalla." + +#: wp-admin/users.php:101 wp-admin/users.php:148 +msgid "You can’t delete users." +msgstr "No puedes borrar usuarios." + +#: wp-admin/users.php:111 +msgid "You can’t delete that user." +msgstr "No puedes eliminar este usuario." + +#: wp-admin/users.php:163 +msgid "Delete Users" +msgstr "Borrar usuarios" + +#: wp-admin/users.php:164 +msgid "You have specified these users for deletion:" +msgstr "Has escogido borrar estos usuarios:" + +#: wp-admin/users.php:172 +msgid "ID #%1s: %2s The current user will not be deleted." +msgstr "ID #%1s: %2s El usuario actual no se borrará." + +#: wp-admin/users.php:174 wp-admin/users.php:277 +msgid "ID #%1s: %2s" +msgstr "ID #%1s: %2s" + +#: wp-admin/users.php:181 +msgid "What should be done with posts and links owned by this user?" +msgstr "¿Qué debe hacerse con los enlaces y entradas que le pertenecen?" + +#: wp-admin/users.php:184 +msgid "Delete all posts and links." +msgstr "Borrar todas las entradas y enlaces." + +#: wp-admin/users.php:186 +msgid "Attribute all posts and links to:" +msgstr "Atribuir todas las entradas y enlaces a:" + +#: wp-admin/users.php:190 +msgid "Confirm Deletion" +msgstr "Confirmar borrado" + +#: wp-admin/users.php:192 +msgid "There are no valid users selected for deletion." +msgstr "No se han seleccionado usuarios válidos para borrar." + +#: wp-admin/users.php:204 wp-admin/users.php:212 wp-admin/users.php:241 +#: wp-admin/users.php:249 +msgid "You can’t remove users." +msgstr "No puedes eliminar usuarios." + +#: wp-admin/users.php:264 +msgid "Remove Users from Site" +msgstr "Eliminar usuarios del sitio" + +#: wp-admin/users.php:265 +msgid "You have specified these users for removal:" +msgstr "Has especificado estos usuarios para ser eliminados:" + +#: wp-admin/users.php:273 +msgid "ID #%1s: %2s The current user will not be removed." +msgstr "ID #%1s: %2s El usuario actual no será eliminado." + +#: wp-admin/users.php:275 +msgid "ID #%1s: %2s You don't have permission to remove this user." +msgstr "ID #%1s: %2s No tienes permisos para eliminar este usuario." + +#: wp-admin/users.php:284 +msgid "Confirm Removal" +msgstr "Confirmar Eliminación" + +#: wp-admin/users.php:286 +msgid "There are no valid users selected for removal." +msgstr "No hay usuarios válidos seleccionados para su eliminación." + +#: wp-admin/users.php:315 +msgid "%s user deleted" +msgid_plural "%s users deleted" +msgstr[0] "%s usuario borrado" +msgstr[1] "%s usuarios borrados" + +#: wp-admin/users.php:318 +msgid "New user created." +msgstr "Nuevo usuario creado." + +#: wp-admin/users.php:321 +msgid "Changed roles." +msgstr "Cambiar perfil." + +#: wp-admin/users.php:324 +msgid "The current user’s role must have user editing capabilities." +msgstr "El perfil del usuario actual debería poder editar usuarios." + +#: wp-admin/users.php:325 +msgid "Other user roles have been changed." +msgstr "Se han cambiado los perfiles de los otros usuarios." + +#: wp-admin/users.php:328 +msgid "You can’t delete the current user." +msgstr "No puedes borrar el usuario actual." + +#: wp-admin/users.php:329 +msgid "Other users have been deleted." +msgstr "Se han eliminado los otros usuarios." + +#: wp-admin/users.php:332 +msgid "User removed from this site." +msgstr "Usuario eliminado de este sitio." + +#: wp-admin/users.php:335 +msgid "You can't remove the current user." +msgstr "No puedes eliminar el usuario actual." + +#: wp-admin/users.php:336 +msgid "Other users have been removed." +msgstr "Otros usuarios han sido eliminados." + +#: wp-admin/users.php:363 wp-admin/menu.php:195 wp-admin/menu.php:197 +msgctxt "user" +msgid "Add New" +msgstr "Añadir nuevo" + +#: wp-admin/users.php:365 +msgctxt "user" +msgid "Add Existing" +msgstr "Añadir usuario existente" + +#: wp-admin/users.php:376 wp-admin/includes/dashboard.php:445 +msgid "Search Users" +msgstr "Buscar usuarios" + +#: wp-admin/upgrade.php:49 +msgid "WordPress › Update" +msgstr "Actualización de WordPress" + +#: wp-admin/upgrade.php:60 +msgid "No Update Required" +msgstr "No es necesaria la actualización" + +#: wp-admin/upgrade.php:61 +msgid "Your WordPress database is already up-to-date!" +msgstr "¡Tu base de datos de WordPress ya está actualizada!" + +#: wp-admin/upgrade.php:62 wp-admin/upgrade.php:94 +#: wp-admin/includes/media.php:1297 +msgid "Continue" +msgstr "Continuar" + +#: wp-admin/upgrade.php:66 wp-admin/update-core.php:44 +msgid "You cannot update because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s." +msgstr "No puedes instalar a causa de que WordPress %1$s requiere la versión %2$s o superior de PHP y la versión %3$s o superior de MySQL. Estás usando la versión %4$s de PHP y la versión %5$s de MySQL." + +#: wp-admin/upgrade.php:68 wp-admin/update-core.php:46 +msgid "You cannot update because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s." +msgstr "La actualización no puede instalarse ya que WordPress %1$s requiere la versión %2$s o superior de PHP. Estás usando la versión %3$s." + +#: wp-admin/upgrade.php:70 wp-admin/update-core.php:48 +msgid "You cannot update because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s." +msgstr "La actualización no puede instalarse porque WordPress %1$s requiere la versión %2$s o superior de MySQL. Estás usando la versión %3$s." + +#: wp-admin/upgrade.php:79 +msgid "Database Update Required" +msgstr "Es necesaria una actualización de la base de datos" + +#: wp-admin/upgrade.php:80 +msgid "WordPress has been updated! Before we send you on your way, we have to update your database to the newest version." +msgstr "¡WordPress se ha actualizado! Antes de continuar, tenemos que actualizar tu base de datos a la última versión." + +#: wp-admin/upgrade.php:81 +msgid "The update process may take a little while, so please be patient." +msgstr "La actualización puede tardar un poco, así que sé paciente, por favor." + +#: wp-admin/upgrade.php:82 +msgid "Update WordPress Database" +msgstr "Actualizar la base de datos de WordPress" + +#: wp-admin/upgrade.php:92 +msgid "Update Complete" +msgstr "Actualización completada" + +#: wp-admin/upgrade.php:93 +msgid "Your WordPress database has been successfully updated!" +msgstr "¡La base de datos de WordPress se ha actualizado con éxito!" + +#: wp-admin/upgrade.php:98 +msgid "%s queries" +msgstr "%s consultas" + +#: wp-admin/upgrade.php:100 +msgid "%s seconds" +msgstr "%s segundos" + +#: wp-admin/options-writing.php:15 +msgid "Writing Settings" +msgstr "Ajustes de escritura" + +#: wp-admin/options-writing.php:19 +msgid "You can submit content in several different ways; this screen holds the settings for all of them. The top section controls the editor within these administration screens, while the rest control external publishing methods. For more information on any of these methods, use the documentation links below." +msgstr "Puedes enviar contenido de varias formas; en esta pantalla encontrarás los ajustes para todas ellas. La sección superior controla el editor que hay en esta pantalla de administración, mientras que el resto controla métodos externos de publicación. Para más información de cualquiera de estos métodos, usa la documentación que encontrarás en los siguientes enlaces." + +#: wp-admin/options-writing.php:22 +msgid "Documentation on Writing Settings" +msgstr " Documentación sobre Configuración de Escritura " + +#: wp-admin/options-writing.php:38 +msgid "Size of the post box" +msgstr "Tamaño de la caja de texto" + +#: wp-admin/options-writing.php:40 +msgid "lines" +msgstr "líneas" + +#: wp-admin/options-writing.php:43 wp-admin/options-writing.php:44 +msgid "Formatting" +msgstr "Formato" + +#: wp-admin/options-writing.php:47 +msgid "Convert emoticons like :-) and :-P to graphics on display" +msgstr "Convertir emoticonos como :-) y :-P a gráficos en pantalla" + +#: wp-admin/options-writing.php:48 +msgid "WordPress should correct invalidly nested XHTML automatically" +msgstr "WordPress corregirá de forma automática el XHTML incorrectamente anidado" + +#: wp-admin/options-writing.php:52 +msgid "Default Post Category" +msgstr "Categoría predeterminada para las entradas" + +#: wp-admin/options-writing.php:65 +msgid "Default Post Format" +msgstr "Formato de entrada por defecto" + +#: wp-admin/options-writing.php:68 wp-admin/includes/meta-boxes.php:257 +#: wp-admin/press-this.php:509 +msgid "Standard" +msgstr "Estándar" + +#: wp-admin/options-writing.php:77 +msgid "Default Link Category" +msgstr "Categoría predeterminada para enlaces" + +#: wp-admin/options-writing.php:95 +msgid "Post via e-mail" +msgstr "Publicar por correo electrónico" + +#: wp-admin/options-writing.php:96 +msgid "To post to WordPress by e-mail you must set up a secret e-mail account with POP3 access. Any mail received at this address will be posted, so it’s a good idea to keep this address very secret. Here are three random strings you could use: %s, %s, %s." +msgstr "Para publicar en WordPress por correo electrónico debes crear una cuenta de correo electrónico secreta con acceso POP3. Todo correo recibido en esta dirección será publicado, por ello es buena idea que mantengas esa dirección totalmente secreta. Aquí tienes tres cadenas aleatorias que puedes usar como nombre de cuenta: %s, %s, %s." + +#: wp-admin/options-writing.php:100 +msgid "Mail Server" +msgstr "Servidor de correo" + +#: wp-admin/options-writing.php:102 +msgid "Port" +msgstr "Puerto" + +#: wp-admin/options-writing.php:107 +msgid "Login Name" +msgstr "Nombre de acceso" + +#: wp-admin/options-writing.php:117 +msgid "Default Mail Category" +msgstr "Categoría predeterminada para publicar por correo electrónico" + +#: wp-admin/options-writing.php:128 +msgid "Remote Publishing" +msgstr "Publicación remota" + +#: wp-admin/options-writing.php:129 +msgid "To post to WordPress from a desktop blogging client or remote website that uses the Atom Publishing Protocol or one of the XML-RPC publishing interfaces you must enable them below." +msgstr "Para enviar una entrada a WordPress desde un cliente de escritorio o sitio web que utilice el protocolo de publicación Atom o uno de los interfaces de publicación XML-RPC, debes autorizarlos antes." + +#: wp-admin/options-writing.php:132 wp-admin/options-writing.php:133 +msgid "Atom Publishing Protocol" +msgstr "Protocolo de publicación Atom" + +#: wp-admin/options-writing.php:136 +msgid "Enable the Atom Publishing Protocol." +msgstr "Activar el protocolo de publicación Atom." + +#: wp-admin/options-writing.php:140 wp-admin/options-writing.php:141 +msgid "XML-RPC" +msgstr "XML-RPC" + +#: wp-admin/options-writing.php:144 +msgid "Enable the WordPress, Movable Type, MetaWeblog and Blogger XML-RPC publishing protocols." +msgstr "Activar los protocolos de publicación XML-RPC para WordPress, Movable Type, MetaWeblog y Blogger." + +#: wp-admin/options-writing.php:151 +msgid "Update Services" +msgstr "Servicios de actualización" + +#: wp-admin/options-writing.php:155 +msgid "When you publish a new post, WordPress automatically notifies the following site update services. For more about this, see Update Services on the Codex. Separate multiple service URLs with line breaks." +msgstr "Cuando publicas una entrada nueva, WordPress lo notifica automáticamente a los siguientes servicios de actualización. Para más información, visita Update Services en el Codex. Separa las URL de distintos servicios con saltos de línea." + +#: wp-admin/options-writing.php:161 +msgid "WordPress is not notifying any Update Services because of your site’s privacy settings." +msgstr "WordPress no está notificando a ningún Servicio de Actualizaciones por la configuración de privacidad." + +#: wp-admin/update-core.php:18 wp-admin/update-core.php:438 +#: wp-admin/update-core.php:466 +msgid "You do not have sufficient permissions to update this site." +msgstr "No tienes los permisos adecuados para actualizar este sitio." + +#: wp-admin/update-core.php:27 +msgid "Update Automatically" +msgstr "Actualizar automáticamente" + +#: wp-admin/update-core.php:33 +msgid "You are using a development version of WordPress. You can update to the latest nightly build automatically or download the nightly build and install it manually:" +msgstr "Estás utilizando una versión en desarrollo de WordPress. Puedes actualizar a la última versión de desarrollo automáticamente o descargarla para instalarla manualmente:" + +#: wp-admin/update-core.php:34 +msgid "Download nightly build" +msgstr "Descargando la última versión de desarrollo" + +#: wp-admin/update-core.php:37 +msgid "You have the latest version of WordPress. You do not need to update. However, if you want to re-install version %s, you can do so automatically or download the package and re-install manually:" +msgstr "Tienes la última versión de WordPress. No necesitas actualizar. No obstante, si quieres reinstalar la versión %s, puedes hacerlo automáticamente o descargarla para reinstalarla manualmente:" + +#: wp-admin/update-core.php:38 +msgid "Re-install Automatically" +msgstr "Re-instalación automática" + +#: wp-admin/update-core.php:50 +msgid "You can update to WordPress %2$s automatically or download the package and install it manually:" +msgstr "Puedes actualizar a WordPress %2$s automáticamente o descargar el paquete e instalarlo manualmente:" + +#: wp-admin/update-core.php:54 +msgid "Download %s" +msgstr "Descargar %s" + +#: wp-admin/update-core.php:71 +msgid "Hide this update" +msgstr "Ocultar esta actualización" + +#: wp-admin/update-core.php:73 +msgid "Bring back this update" +msgstr "Volver a mostrar esta actualización" + +#: wp-admin/update-core.php:76 +msgid "This localized version contains both the translation and various other localization fixes. You can skip upgrading if you want to keep your current translation." +msgstr "Esta versión traducida contiene tanto la traducción como otros ajustes de traducción. Puedes saltarte la actualización si quieres mantener la traducción actual." + +#: wp-admin/update-core.php:78 +msgid "You are about to install WordPress %s in English (US). There is a chance this update will break your translation. You may prefer to wait for the localized version to be released." +msgstr "Se va a instalar WordPress %s en inglés (US). Existe la posibilidad de que esta actualización rompa tu traducción. Puede que prefieras esperar a que salga la versión local." + +#: wp-admin/update-core.php:88 wp-admin/update-core.php:100 +msgid "Show hidden updates" +msgstr "Mostrar actualizaciones ocultas" + +#: wp-admin/update-core.php:89 +msgid "Hide hidden updates" +msgstr "Ocultar actualizaciones ocultas" + +#: wp-admin/update-core.php:125 wp-admin/update-core.php:398 +msgid "WordPress Updates" +msgstr "Actualizaciones de WordPress" + +#: wp-admin/update-core.php:130 +msgid "Please select one or more themes to update." +msgstr "Por favor, elige uno o más temas para actualizarlos." + +#: wp-admin/update-core.php:132 +msgid "Please select one or more plugins to update." +msgstr "Por favor, elige uno o más plugins a actualizar." + +#: wp-admin/update-core.php:138 +msgid "Last checked on %1$s at %2$s." +msgstr "Última revisión el %1$s a las %2$s." + +#: wp-admin/update-core.php:139 +msgid "Check Again" +msgstr "Comprobar de nuevo" + +#: wp-admin/update-core.php:144 +msgid "You have the latest version of WordPress." +msgstr "Tienes la última versión de WordPress. No es necesario actualizarla." + +#: wp-admin/update-core.php:148 +msgid "Important: before updating, please back up your database and files. For help with updates, visit the Updating WordPress Codex page." +msgstr "Importante: antes de la actualización, por favor, realiza un respaldo de la base de datos y ficheros. Si necesitas ayuda para la actualización, visita la página del Codex: Actualización de WordPress." + +#: wp-admin/update-core.php:152 +msgid "An updated version of WordPress is available." +msgstr "Hay disponible una nueva versión actualizada de WordPress." + +#: wp-admin/update-core.php:164 +msgid "While your site is being updated, it will be in maintenance mode. As soon as your updates are complete, your site will return to normal." +msgstr "Mientras se actualiza tu sitio, éste permanecerá en modo mantenimiento. Tan pronto como finalice la actualización, tu sitio volverá a estar activo." + +#: wp-admin/update-core.php:184 +msgid "Your plugins are all up to date." +msgstr "Tus plugins están todos actualizados." + +#: wp-admin/update-core.php:196 +msgid "The following plugins have new versions available. Check the ones you want to update and then click “Update Plugins”." +msgstr "Hay nuevas versiones de los siguientes plugins. Marca aquellos que quieras actualizar y haz clic en “Actualizar plugins”." + +#: wp-admin/update-core.php:199 wp-admin/update-core.php:251 +#: wp-admin/update-core.php:454 wp-admin/update-core.php:459 +#: wp-admin/plugins.php:111 +msgid "Update Plugins" +msgstr "Actualizar plugins" + +#: wp-admin/update-core.php:220 +msgid "Compatibility with WordPress %1$s: 100%% (according to its author)" +msgstr "Compatibilidad con WordPress %1$s: 100%% (según su autor)" + +#: wp-admin/update-core.php:223 wp-admin/update-core.php:231 +msgid "Compatibility with WordPress %1$s: %2$d%% (%3$d \"works\" votes out of %4$d total)" +msgstr "Compatibilidad con WordPress %1$s: %2$d%% (%3$d votos de \"funciona\" de un total de %4$d)" + +#: wp-admin/update-core.php:225 wp-admin/update-core.php:233 +msgid "Compatibility with WordPress %1$s: Unknown" +msgstr "Compatibilidad con WordPress %1$s: Desconocida" + +#: wp-admin/update-core.php:245 wp-admin/update-core.php:295 +msgid "You have version %1$s installed. Update to %2$s." +msgstr "Estás usando la versión %1$s. Actualiza a %2$s." + +#: wp-admin/update-core.php:259 wp-admin/update-core.php:267 +#: wp-admin/menu.php:148 wp-admin/menu.php:153 +msgid "Themes" +msgstr "Temas" + +#: wp-admin/update-core.php:260 +msgid "Your themes are all up to date." +msgstr "Tus temas están actualizados." + +#: wp-admin/update-core.php:268 +msgid "The following themes have new versions available. Check the ones you want to update and then click “Update Themes”." +msgstr "Los siguientes temas tienen versiones nuevas disponibles. Marca aquellas que quieras actualizar y haz clic en “Actualizar Temas”." + +#: wp-admin/update-core.php:269 +msgid "Please Note: Any customizations you have made to theme files will be lost. Please consider using child themes for modifications." +msgstr "Atención: Se perderá cualquier personalización que hayas hecho a los archivos del tema. Por favor, considere el uso de temas hijos para mantener cambios." + +#: wp-admin/update-core.php:269 +msgctxt "Link used in suggestion to use child themes in GUU" +msgid "http://codex.wordpress.org/Child_Themes" +msgstr "http://codex.wordpress.org/Child_Themes" + +#: wp-admin/update-core.php:272 wp-admin/update-core.php:301 +#: wp-admin/update-core.php:482 wp-admin/update-core.php:487 +msgid "Update Themes" +msgstr "Actualizar temas" + +#: wp-admin/update-core.php:338 +msgid "Update WordPress" +msgstr "Actualizar WordPress" + +#: wp-admin/update-core.php:355 +msgid "Installation Failed" +msgstr "Instalación fallida" + +#: wp-admin/update-core.php:357 +msgid "WordPress updated successfully" +msgstr "WordPress ha sido actualizado correctamente" + +#: wp-admin/update-core.php:358 +msgid "Go to Dashboard" +msgstr "Ir al Escritorio" + +#: wp-admin/update-core.php:402 +msgid "This screen lets you update to the latest version of WordPress as well as update your themes and plugins from the WordPress.org repository. When updates are available, the number of available updates will appear in a bubble on the left hand menu as a notification. It is very important to keep your WordPress installation up to date for security reasons, so when you see a number appear, make sure you take the time to update, which is an easy process." +msgstr "Esta pantalla te permite actualizar a la última versión de WordPress, así como actualizar tu temas y plugins desde el repositorio de WordPress.org. Cuando hay actualizaciones disponibles, el número de actualizaciones disponibles aparecerá en una burbuja en el menú de la izquierda como una notificación. Es muy importante mantener tu instalación de WordPress al día por razones de seguridad, así que cuando veas que aparece un número, asegúrate de que realizas las actualizaciones, que es un proceso muy fácil." + +#: wp-admin/update-core.php:403 +msgid "Updating your WordPress installation is a simple one-click procedure; just click on the Update button when it says a new version is available." +msgstr "Actualizar tu instalación de Wordpress es un proceso tan simple como realizar un solo clic; simplemente haz clic en el botón Actualizar cuando te muestre el mensaje de que hay una nueva actualización." + +#: wp-admin/update-core.php:404 +msgid "To update themes or plugins from this screen, use the checkboxes to make your selection and click on the appropriate Update button. Check the box at the top of the Themes or Plugins section to select all and update them all at once." +msgstr "Para actualizar temas o plugins en esta pantalla usa las casillas de verificación para hacer tu selección y haz clic en el botón de actualizar correspondiente. Marca la casilla superior en la sección de temas o plugins para seleccionarlas todas y actualizarlas de una vez." + +#: wp-admin/update-core.php:406 +msgid "Documentation on Updating WordPress" +msgstr "Documentación sobre actualizar WordPress" + +#: wp-admin/options-reading.php:15 +msgid "Reading Settings" +msgstr "Ajustes de lectura" + +#: wp-admin/options-reading.php:45 +msgid "This screen contains the settings that affect the display of your content." +msgstr "Esta pantalla contiene los ajustes que afectarán a cómo se muestran tus contenidos." + +#: wp-admin/options-reading.php:46 +msgid "You can choose what’s displayed on the front page of your site. It can be posts in reverse chronological order (classic blog), or a fixed/static page. To set a static home page, you first need to create two Pages. One will become the front page, and the other will be where your posts are displayed." +msgstr "Puedes elegir lo que se muestra en la página principal de tu sitio. Pueden ser entradas en orden cronológico inverso (blog clásico) o una página fija/estática. Para definir una página de inicio estática primero tienes que crear dos páginas. Una será la página principal y la otra donde se mostrarán tus entradas." + +#: wp-admin/options-reading.php:47 +msgid "You can also control the display of your content in RSS feeds, including the maximum numbers of posts to display, whether to show full text or a summary, and the character set encoding." +msgstr "También puedes controlar la forma de mostrar tus contenidos en el canal RSS, incluyendo el número máximo de entradas a mostrar, si mostrar el texto íntegro o una fracción de éste y la codificación de caracteres." + +#: wp-admin/options-reading.php:50 +msgid "Documentation on Reading Settings" +msgstr "Documentación sobre opciones de lectura" + +#: wp-admin/options-reading.php:78 wp-admin/options-reading.php:79 +msgid "Front page displays" +msgstr "La página inicial mostrará" + +#: wp-admin/options-reading.php:82 +msgid "Your latest posts" +msgstr "Tus últimas entradas" + +#: wp-admin/options-reading.php:87 +msgid "A static page (select below)" +msgstr "Una página estática (seleccionar abajo)" + +#: wp-admin/options-reading.php:91 +msgid "Front page: %s" +msgstr "Página inicial: %s" + +#: wp-admin/options-reading.php:91 wp-admin/options-reading.php:92 +#: wp-admin/includes/template.php:548 wp-admin/widgets.php:295 +msgid "— Select —" +msgstr "— Seleccionar —" + +#: wp-admin/options-reading.php:92 +msgid "Posts page: %s" +msgstr "Página de entradas: %s" + +#: wp-admin/options-reading.php:95 +msgid "Warning: these pages should not be the same!" +msgstr "Atención: estas páginas no pueden ser las mismas." + +#: wp-admin/options-reading.php:101 +msgid "Blog pages show at most" +msgstr "Número máximo de entradas a mostrar en el sitio" + +#: wp-admin/options-reading.php:103 +msgid "posts" +msgstr "entradas" + +#: wp-admin/options-reading.php:107 +msgid "Syndication feeds show the most recent" +msgstr "Número máximo de entradas a mostrar en el feed" + +#: wp-admin/options-reading.php:108 +msgid "items" +msgstr "elementos" + +#: wp-admin/options-reading.php:111 wp-admin/options-reading.php:112 +msgid "For each article in a feed, show" +msgstr "Mostrar, para cada entrada en el feed," + +#: wp-admin/options-reading.php:113 +msgid "Full text" +msgstr "Texto completo" + +#: wp-admin/options-reading.php:114 +msgid "Summary" +msgstr "Resumen" + +#: wp-admin/options-reading.php:119 +msgid "Encoding for pages and feeds" +msgstr "Codificación para páginas y feeds" + +#: wp-admin/options-reading.php:121 +msgid "The character encoding of your site (UTF-8 is recommended, if you are adventurous there are some other encodings)" +msgstr "La codificación de caracteres de tu sitio (recomendamos UTF-8, pero si eres un aventurero, tienes otras codificaciones)" + +#: wp-admin/link.php:109 +msgid "Link not found." +msgstr "No se encontró el enlace." + +#: wp-admin/includes/dashboard.php:30 wp-admin/includes/dashboard.php:33 +msgid "Right Now" +msgstr "Ahora mismo" + +#: wp-admin/includes/dashboard.php:60 +msgid "Incoming Links" +msgstr "Enlaces entrantes" + +#: wp-admin/includes/dashboard.php:69 +msgid "QuickPress" +msgstr "Publicación rápida" + +#: wp-admin/includes/dashboard.php:73 +msgid "Recent Drafts" +msgstr "Últimos borradores" + +#: wp-admin/includes/dashboard.php:79 +msgid "http://wordpress.org/news/" +msgstr "http://wordpress.org/news/" + +#: wp-admin/includes/dashboard.php:80 +msgid "http://wordpress.org/news/feed/" +msgstr "http://wordpress.org/news/feed/" + +#: wp-admin/includes/dashboard.php:81 +msgid "WordPress Blog" +msgstr "Blog oficial WordPress" + +#: wp-admin/includes/dashboard.php:94 +msgid "http://planet.wordpress.org/" +msgstr "http://planet.wordpress.org/" + +#: wp-admin/includes/dashboard.php:95 +msgid "http://planet.wordpress.org/feed/" +msgstr "http://planet.wordpress.org/feed/" + +#: wp-admin/includes/dashboard.php:96 +msgid "Other WordPress News" +msgstr "Otras noticias sobre WordPress" + +#: wp-admin/includes/dashboard.php:119 wp-admin/includes/dashboard.php:584 +#: wp-admin/includes/dashboard.php:637 +msgid "View all" +msgstr "Ver todo" + +#: wp-admin/includes/dashboard.php:150 +msgid "Configure" +msgstr "Configurar" + +#: wp-admin/includes/dashboard.php:251 +msgid "Post" +msgid_plural "Posts" +msgstr[0] "Entrada" +msgstr[1] "Entradas" + +#: wp-admin/includes/dashboard.php:279 +msgid "Page" +msgid_plural "Pages" +msgstr[0] "Página" +msgstr[1] "Páginas" + +#: wp-admin/includes/dashboard.php:291 +msgid "Category" +msgid_plural "Categories" +msgstr[0] "Categoría" +msgstr[1] "Categorías" + +#: wp-admin/includes/dashboard.php:303 +msgid "Tag" +msgid_plural "Tags" +msgstr[0] "Etiqueta" +msgstr[1] "Etiquetas" + +#: wp-admin/includes/dashboard.php:322 +msgid "Comment" +msgid_plural "Comments" +msgstr[0] "Comentario" +msgstr[1] "Comentarios" + +#: wp-admin/includes/dashboard.php:334 +msgctxt "Right Now" +msgid "Approved" +msgid_plural "Approved" +msgstr[0] "Aprobado" +msgstr[1] "Aprobados" + +#: wp-admin/includes/dashboard.php:346 +msgid "Pending" +msgid_plural "Pending" +msgstr[0] "Pendiente" +msgstr[1] "Pendientes" + +#: wp-admin/includes/dashboard.php:358 +msgctxt "comment" +msgid "Spam" +msgid_plural "Spam" +msgstr[0] "Spam" +msgstr[1] "Spam" + +#: wp-admin/includes/dashboard.php:388 wp-admin/includes/dashboard.php:398 +msgid "Change Theme" +msgstr "Cambiar tema" + +#: wp-admin/includes/dashboard.php:392 +msgid "Theme %1$s with %2$s Widget" +msgid_plural "Theme %1$s with %2$s Widgets" +msgstr[0] "Tema %1$s con %2$s widget" +msgstr[1] "Tema %1$s con %2$s widgets" + +#: wp-admin/includes/dashboard.php:394 +msgid "Theme %1$s with %2$s Widget" +msgid_plural "Theme %1$s with %2$s Widgets" +msgstr[0] "Tema %1$s con %2$s widget" +msgstr[1] "Tema %1$s con %2$s widgets" + +#: wp-admin/includes/dashboard.php:399 +msgid "Theme %1$s" +msgstr "Tema %1$s" + +#: wp-admin/includes/dashboard.php:401 +msgid "Theme %1$s" +msgstr "Tema %1$s" + +#: wp-admin/includes/dashboard.php:416 +msgid "Create a New Site" +msgstr "Crear nuevo sitio" + +#: wp-admin/includes/dashboard.php:418 +msgid "Create a New User" +msgstr "Crear un nuevo usuario" + +#: wp-admin/includes/dashboard.php:423 +msgid "%s user" +msgid_plural "%s users" +msgstr[0] "%s usuario" +msgstr[1] "%s usuarios" + +#: wp-admin/includes/dashboard.php:424 +msgid "%s site" +msgid_plural "%s sites" +msgstr[0] "%s sitio" +msgstr[1] "%s sitios" + +#: wp-admin/includes/dashboard.php:426 +msgid "You have %1$s and %2$s." +msgstr "Tienes %1$s y %2$s." + +#: wp-admin/includes/dashboard.php:452 +msgid "Search Sites" +msgstr "Buscar sitios" + +#: wp-admin/includes/dashboard.php:469 +msgid "Post published. View post | Edit post" +msgstr "Entrada publicada. Ver entrada | Editar entrada" + +#: wp-admin/includes/dashboard.php:471 +msgid "Post submitted. Preview post | Edit post" +msgstr "Entrada enviada. Previsualizar entrada | Editar entrada" + +#: wp-admin/includes/dashboard.php:473 +msgid "Draft saved. Preview post | Edit post" +msgstr "Borrador guardado. Previsualizar entrada | Editar entrada" + +#: wp-admin/includes/dashboard.php:486 +msgid "You can also try %s, easy blogging from anywhere on the Web." +msgstr "También puedes probar %s para crear fácilmente entradas desde cualquier web." + +#: wp-admin/includes/dashboard.php:538 +msgid "Reset" +msgstr "Reiniciar" + +#: wp-admin/includes/dashboard.php:540 wp-admin/includes/meta-boxes.php:219 +#: wp-admin/includes/meta-boxes.php:220 wp-admin/press-this.php:497 +msgid "Submit for Review" +msgstr "Enviar para revisión" + +#: wp-admin/includes/dashboard.php:554 wp-admin/includes/dashboard.php:770 +#: wp-admin/includes/dashboard.php:858 wp-admin/includes/dashboard.php:880 +#: wp-admin/includes/dashboard.php:919 wp-admin/includes/dashboard.php:1019 +msgid "Loading…" +msgstr "Cargando…" + +#: wp-admin/includes/dashboard.php:554 wp-admin/includes/dashboard.php:770 +#: wp-admin/includes/dashboard.php:858 wp-admin/includes/dashboard.php:880 +#: wp-admin/includes/dashboard.php:919 +msgid "This widget requires JavaScript." +msgstr "Este widget requiere Javascript." + +#: wp-admin/includes/dashboard.php:575 +#: wp-admin/includes/class-wp-posts-list-table.php:527 +#: wp-admin/includes/class-wp-posts-list-table.php:533 +#: wp-admin/includes/class-wp-terms-list-table.php:255 +#: wp-admin/includes/class-wp-media-list-table.php:205 +#: wp-admin/includes/class-wp-media-list-table.php:218 +#: wp-admin/includes/class-wp-links-list-table.php:136 +msgid "Edit “%s”" +msgstr "Editar “%s”" + +#: wp-admin/includes/dashboard.php:575 +#: wp-admin/includes/class-wp-posts-list-table.php:572 +#: wp-admin/includes/class-wp-media-list-table.php:267 +msgid "Y/m/d g:i:s A" +msgstr "d/m/Y G:i" + +#: wp-admin/includes/dashboard.php:587 +msgid "There are no drafts at the moment" +msgstr "En este momento no hay borradores" + +#: wp-admin/includes/dashboard.php:680 +#: wp-admin/includes/class-wp-comments-list-table.php:391 +#: wp-admin/includes/class-wp-comments-list-table.php:393 +msgid "Approve this comment" +msgstr "Aprobar este comentario" + +#: wp-admin/includes/dashboard.php:680 +#: wp-admin/includes/class-wp-comments-list-table.php:188 +#: wp-admin/includes/class-wp-comments-list-table.php:391 +#: wp-admin/includes/class-wp-comments-list-table.php:393 +msgid "Approve" +msgstr "Aprobar" + +#: wp-admin/includes/dashboard.php:681 +#: wp-admin/includes/class-wp-comments-list-table.php:389 +#: wp-admin/includes/class-wp-comments-list-table.php:394 +msgid "Unapprove this comment" +msgstr "Rechazar este comentario" + +#: wp-admin/includes/dashboard.php:681 +#: wp-admin/includes/class-wp-comments-list-table.php:186 +#: wp-admin/includes/class-wp-comments-list-table.php:389 +#: wp-admin/includes/class-wp-comments-list-table.php:394 +msgid "Unapprove" +msgstr "Rechazar" + +#: wp-admin/includes/dashboard.php:683 +#: wp-admin/includes/class-wp-comments-list-table.php:415 +msgid "Reply to this comment" +msgstr "Responder a este comentario" + +#: wp-admin/includes/dashboard.php:684 +#: wp-admin/includes/class-wp-comments-list-table.php:398 +msgid "Mark this comment as spam" +msgstr "Marcar este comentario como spam" + +#: wp-admin/includes/dashboard.php:684 +#: wp-admin/includes/class-wp-comments-list-table.php:398 +msgctxt "verb" +msgid "Spam" +msgstr "Spam" + +#: wp-admin/includes/dashboard.php:686 +#: wp-admin/includes/class-wp-posts-list-table.php:197 +#: wp-admin/includes/class-wp-posts-list-table.php:551 +#: wp-admin/includes/media.php:1293 +#: wp-admin/includes/class-wp-comments-list-table.php:198 +#: wp-admin/includes/class-wp-comments-list-table.php:406 +#: wp-admin/includes/class-wp-media-list-table.php:79 +#: wp-admin/includes/class-wp-media-list-table.php:343 +#: wp-admin/includes/class-wp-media-list-table.php:359 +#: wp-admin/includes/meta-boxes.php:198 wp-admin/edit-form-comment.php:71 +msgid "Delete Permanently" +msgstr "Borrar permanentemente" + +#: wp-admin/includes/dashboard.php:688 +#: wp-admin/includes/class-wp-comments-list-table.php:408 +msgid "Move this comment to the trash" +msgstr "Mover este comentario a la papelera" + +#: wp-admin/includes/dashboard.php:688 +#: wp-admin/includes/class-wp-comments-list-table.php:408 +msgctxt "verb" +msgid "Trash" +msgstr "Enviar a la Papelera" + +#: wp-admin/includes/dashboard.php:714 +msgid "From %1$s on %2$s%3$s" +msgstr "De %1$s en %2$s%3$s" + +#: wp-admin/includes/dashboard.php:715 +msgid "[Pending]" +msgstr "[Pendiente]" + +#: wp-admin/includes/dashboard.php:734 +msgctxt "dashboard" +msgid "%1$s on %2$s" +msgstr "%1$s en %2$s" + +#: wp-admin/includes/dashboard.php:793 +msgid "This dashboard widget queries Google Blog Search so that when another blog links to your site it will show up here. It has found no incoming links… yet. It’s okay — there is no rush." +msgstr "Este widget de escritorio consulta a la Búsqueda de blogs de Google de modo que cuando otro blog enlace a su sitio se mostrará aquí. No se ha encontrado ningún enlace entrante… aún. Está bien, no hay prisa." + +#: wp-admin/includes/dashboard.php:817 wp-admin/includes/dashboard.php:819 +#: wp-admin/includes/post.php:1274 +msgid "Somebody" +msgstr "Alguien" + +#: wp-admin/includes/dashboard.php:831 +msgid "%1$s linked here saying, \"%3$s\"" +msgstr "%1$s enlazó aquí diciendo, \"%3$s\"" + +#: wp-admin/includes/dashboard.php:834 +msgid "%1$s linked here saying, \"%3$s\"" +msgstr "%1$s enlazó aquí diciendo, \"%3$s\"" + +#: wp-admin/includes/dashboard.php:839 +msgid "on %4$s" +msgstr "en %4$s" + +#: wp-admin/includes/dashboard.php:937 +msgid "Most Popular" +msgstr "Más populares" + +#: wp-admin/includes/dashboard.php:937 +msgid "Newest Plugins" +msgstr "Plugins recientes" + +#: wp-admin/includes/dashboard.php:937 +msgid "Recently Updated" +msgstr "Actualizados recientemente" + +#: wp-admin/includes/dashboard.php:995 wp-admin/includes/theme-install.php:143 +msgid "Install" +msgstr "Instalar" + +#: wp-admin/includes/dashboard.php:1124 +msgid "Storage Space" +msgstr "Espacio de almacenamiento" + +#: wp-admin/includes/dashboard.php:1128 +msgid "%2$sMB" +msgstr "%2$sMB" + +#: wp-admin/includes/dashboard.php:1129 +msgid "Space Allowed" +msgstr "Espacio permitido" + +#: wp-admin/includes/dashboard.php:1136 +msgid "%2$sMB (%3$s%%)" +msgstr "%2$sMB (%3$s%%)" + +#: wp-admin/includes/dashboard.php:1137 +msgid "Space Used" +msgstr "Espacio utilizado" + +#: wp-admin/includes/class-wp-filesystem-base.php:201 +msgid "Changing to %s" +msgstr "Cambiando a %s" + +#: wp-admin/includes/class-wp-filesystem-base.php:210 +msgid "Found %s" +msgstr "Encontrado %s" + +#: wp-admin/includes/class-wp-posts-list-table.php:145 +msgctxt "posts" +msgid "Mine (%s)" +msgid_plural "Mine (%s)" +msgstr[0] "Mío (%s)" +msgstr[1] "Míos (%s)" + +#: wp-admin/includes/class-wp-posts-list-table.php:156 +msgctxt "posts" +msgid "All (%s)" +msgid_plural "All (%s)" +msgstr[0] "Todo (%s)" +msgstr[1] "Todos (%s)" + +#: wp-admin/includes/class-wp-posts-list-table.php:178 +msgctxt "posts" +msgid "Sticky (%s)" +msgid_plural "Sticky (%s)" +msgstr[0] "(%s) fija" +msgstr[1] "(%s) fijas" + +#: wp-admin/includes/class-wp-posts-list-table.php:199 +#: wp-admin/includes/media.php:1301 +#: wp-admin/includes/class-wp-comments-list-table.php:200 +#: wp-admin/includes/meta-boxes.php:200 wp-admin/edit-form-comment.php:71 +msgid "Move to Trash" +msgstr "Mover a la papelera" + +#: wp-admin/includes/class-wp-posts-list-table.php:215 +#: wp-admin/includes/class-wp-links-list-table.php:64 +msgid "View all categories" +msgstr "Ver todas las categorías" + +#: wp-admin/includes/class-wp-posts-list-table.php:225 +#: wp-admin/includes/class-wp-comments-list-table.php:225 +#: wp-admin/includes/class-wp-media-list-table.php:96 +#: wp-admin/includes/class-wp-links-list-table.php:71 +msgid "Filter" +msgstr "Filtrar" + +#: wp-admin/includes/class-wp-posts-list-table.php:229 +#: wp-admin/includes/class-wp-comments-list-table.php:230 +#: wp-admin/includes/class-wp-media-list-table.php:102 +msgid "Empty Trash" +msgstr "Vaciar papelera" + +#: wp-admin/includes/class-wp-posts-list-table.php:271 +msgctxt "column name" +msgid "Title" +msgstr "Título" + +#: wp-admin/includes/class-wp-posts-list-table.php:542 +msgid "Edit this item" +msgstr "Editar este elemento" + +#: wp-admin/includes/class-wp-posts-list-table.php:543 +msgid "Edit this item inline" +msgstr "Editar este elemento en línea" + +#: wp-admin/includes/class-wp-posts-list-table.php:543 +#: wp-admin/includes/class-wp-comments-list-table.php:413 +#: wp-admin/includes/class-wp-terms-list-table.php:260 +msgid "Quick Edit" +msgstr "Edición rápida" + +#: wp-admin/includes/class-wp-posts-list-table.php:547 +msgid "Restore this item from the Trash" +msgstr "Restaurar este elemento desde la papelera" + +#: wp-admin/includes/class-wp-posts-list-table.php:549 +msgid "Move this item to the Trash" +msgstr "Mover este elemento a la papelera" + +#: wp-admin/includes/class-wp-posts-list-table.php:549 +#: wp-admin/includes/class-wp-media-list-table.php:340 +#: wp-admin/includes/class-wp-media-list-table.php:356 +msgid "Trash" +msgstr "Papelera" + +#: wp-admin/includes/class-wp-posts-list-table.php:551 +msgid "Delete this item permanently" +msgstr "Borrar este elemento permanentemente" + +#: wp-admin/includes/class-wp-posts-list-table.php:555 +#: wp-admin/includes/class-wp-themes-list-table.php:170 +#: wp-admin/includes/class-wp-upgrader.php:1356 +#: wp-admin/includes/class-wp-upgrader.php:1413 +#: wp-admin/includes/theme-install.php:145 +#: wp-admin/includes/theme-install.php:153 +msgid "Preview “%s”" +msgstr "Vista previa “%s”" + +#: wp-admin/includes/class-wp-posts-list-table.php:557 +#: wp-admin/includes/class-wp-media-list-table.php:345 +#: wp-admin/includes/class-wp-media-list-table.php:364 +msgid "View “%s”" +msgstr "Ver “%s”" + +#: wp-admin/includes/class-wp-posts-list-table.php:557 +#: wp-admin/includes/class-wp-media-list-table.php:345 +#: wp-admin/includes/class-wp-media-list-table.php:364 +msgid "View" +msgstr "Ver" + +#: wp-admin/includes/class-wp-posts-list-table.php:569 +#: wp-admin/includes/class-wp-media-list-table.php:265 +msgid "Unpublished" +msgstr "Sin publicar" + +#: wp-admin/includes/class-wp-posts-list-table.php:579 +#: wp-admin/includes/plugin-install.php:313 +#: wp-admin/includes/class-wp-comments-list-table.php:331 +#: wp-admin/includes/theme-install.php:165 +#: wp-admin/includes/class-wp-media-list-table.php:274 +#: wp-content/plugins/akismet/admin.php:369 +#: wp-content/plugins/akismet/admin.php:397 +msgid "%s ago" +msgstr "hace %s" + +#: wp-admin/includes/class-wp-posts-list-table.php:594 +msgid "Missed schedule" +msgstr "Programación perdida" + +#: wp-admin/includes/class-wp-posts-list-table.php:598 +msgid "Last Modified" +msgstr "Última modificación" + +#: wp-admin/includes/class-wp-posts-list-table.php:637 +#: wp-admin/includes/class-wp-media-list-table.php:250 +msgid "No Tags" +msgstr "Sin etiquetas" + +#: wp-admin/includes/class-wp-posts-list-table.php:730 +msgid "Bulk Edit" +msgstr "Edición masiva" + +#: wp-admin/includes/class-wp-posts-list-table.php:730 +#: wp-admin/includes/class-wp-comments-list-table.php:413 +#: wp-admin/includes/class-wp-terms-list-table.php:335 +msgid "Quick Edit" +msgstr "Edición rápida" + +#: wp-admin/includes/class-wp-posts-list-table.php:775 +#: wp-admin/includes/class-wp-posts-list-table.php:849 +#: wp-admin/includes/class-wp-posts-list-table.php:869 +#: wp-admin/includes/class-wp-posts-list-table.php:901 +#: wp-admin/includes/class-wp-posts-list-table.php:910 +#: wp-admin/includes/class-wp-posts-list-table.php:942 +#: wp-admin/includes/class-wp-posts-list-table.php:963 +msgid "— No Change —" +msgstr "— Sin cambios —" + +#: wp-admin/includes/class-wp-posts-list-table.php:801 +msgid "–OR–" +msgstr "–O–" + +#: wp-admin/includes/class-wp-posts-list-table.php:821 +msgid "[more]" +msgstr "[más]" + +#: wp-admin/includes/class-wp-posts-list-table.php:822 +msgid "[less]" +msgstr "[menos]" + +#: wp-admin/includes/class-wp-posts-list-table.php:845 +#: wp-admin/includes/meta-boxes.php:563 wp-admin/includes/meta-boxes.php:564 +msgid "Parent" +msgstr "Superior" + +#: wp-admin/includes/class-wp-posts-list-table.php:847 +msgid "Main Page (no parent)" +msgstr "Página principal (sin superior)" + +#: wp-admin/includes/class-wp-posts-list-table.php:859 +#: wp-admin/includes/media.php:1087 wp-admin/includes/media.php:1795 +#: wp-admin/includes/meta-boxes.php:579 wp-admin/includes/meta-boxes.php:580 +msgid "Order" +msgstr "Orden" + +#: wp-admin/includes/class-wp-posts-list-table.php:866 +#: wp-admin/includes/meta-boxes.php:572 +msgid "Template" +msgstr "Plantilla" + +#: wp-admin/includes/class-wp-posts-list-table.php:871 +#: wp-admin/includes/meta-boxes.php:574 +msgid "Default Template" +msgstr "Plantilla predeterminada" + +#: wp-admin/includes/class-wp-posts-list-table.php:902 +#: wp-admin/includes/class-wp-posts-list-table.php:911 +msgid "Allow" +msgstr "Permitir" + +#: wp-admin/includes/class-wp-posts-list-table.php:903 +#: wp-admin/includes/class-wp-posts-list-table.php:912 +msgid "Do not allow" +msgstr "No permitir" + +#: wp-admin/includes/class-wp-posts-list-table.php:908 +#: wp-admin/includes/class-wp-comments-list-table.php:217 +msgid "Pings" +msgstr "Pings" + +#: wp-admin/includes/class-wp-posts-list-table.php:924 +msgid "Allow Comments" +msgstr "Permitir comentarios" + +#: wp-admin/includes/class-wp-posts-list-table.php:929 +msgid "Allow Pings" +msgstr "Permitir pings" + +#: wp-admin/includes/class-wp-posts-list-table.php:961 +#: wp-admin/includes/class-wp-posts-list-table.php:964 +#: wp-admin/includes/template.php:1639 +msgid "Sticky" +msgstr "Fija" + +#: wp-admin/includes/class-wp-posts-list-table.php:965 +msgid "Not Sticky" +msgstr "No es fija" + +#: wp-admin/includes/class-wp-posts-list-table.php:973 +msgid "Make this post sticky" +msgstr "Marcar esta entrada como fija" + +#: wp-admin/includes/image-edit.php:19 wp-admin/includes/image-edit.php:545 +msgid "Image data does not exist. Please re-upload the image." +msgstr "No existen datos de la imagen. Por favor, vuelve a subir la imagen." + +#: wp-admin/includes/image-edit.php:40 +msgid "Crop" +msgstr "Recortar" + +#: wp-admin/includes/image-edit.php:44 +msgid "Rotate counter-clockwise" +msgstr "Rotar en sentido contrario a las agujas del reloj." + +#: wp-admin/includes/image-edit.php:45 +msgid "Rotate clockwise" +msgstr "Rotar en el sentido de las agujas del reloj." + +#: wp-admin/includes/image-edit.php:47 +msgid "Image rotation is not supported by your web host (function imagerotate() is missing)" +msgstr "Tu hosting no soporta la rotación de imágenes (no tiene la función imagerotate())" + +#: wp-admin/includes/image-edit.php:53 +msgid "Flip vertically" +msgstr "Voltear verticalmente" + +#: wp-admin/includes/image-edit.php:54 +msgid "Flip horizontally" +msgstr "Voltear horizontalmente" + +#: wp-admin/includes/image-edit.php:82 +msgid "Scale Image" +msgstr "Escalar imagen" + +#: wp-admin/includes/image-edit.php:84 +msgid "You can proportionally scale the original image. For best results the scaling should be done before performing any other operations on it like crop, rotate, etc. Note that if you make the image larger it may become fuzzy." +msgstr "Puedes escalar proporcionalmente la imagen original. Para obtener los mejores resultados es mejor escalar la imagen antes de realizar otras operaciones como recortar, rotar, etc. Date cuenta de que si haces más grande la imagen puede verse borrosa." + +#: wp-admin/includes/image-edit.php:85 +msgid "Original dimensions %s" +msgstr "Dimensiones originales %s" + +#: wp-admin/includes/image-edit.php:99 +msgid "Discard any changes and restore the original image." +msgstr "Descartar todos los cambios y restaurar la imagen original." + +#: wp-admin/includes/image-edit.php:102 +msgid "Previously edited copies of the image will not be deleted." +msgstr "Las copias de la imagen editadas previamente no se borrarán." + +#: wp-admin/includes/image-edit.php:106 +msgid "Restore image" +msgstr "Restaurar imagen" + +#: wp-admin/includes/image-edit.php:117 +msgid "Image Crop" +msgstr "Recortar imagen" + +#: wp-admin/includes/image-edit.php:118 wp-admin/includes/image-edit.php:164 +msgid "(help)" +msgstr "(ayuda)" + +#: wp-admin/includes/image-edit.php:120 +msgid "The image can be cropped by clicking on it and dragging to select the desired part. While dragging the dimensions of the selection are displayed below." +msgstr "Puedes recortar la imagen haciendo clic en ella y arrastrando la parte deseada. Mientras arrastras, abajo se muestran las dimensiones." + +#: wp-admin/includes/image-edit.php:121 wp-admin/user-edit.php:204 +msgid "Keyboard Shortcuts" +msgstr "Atajos de teclado" + +#: wp-admin/includes/image-edit.php:123 +msgid "Arrow: move by 10px" +msgstr "Flecha: mover 10px" + +#: wp-admin/includes/image-edit.php:124 +msgid "Shift + arrow: move by 1px" +msgstr "May + flecha: mover 1px" + +#: wp-admin/includes/image-edit.php:125 +msgid "Ctrl + arrow: resize by 10px" +msgstr "Control + flecha: redimensiona en 10px" + +#: wp-admin/includes/image-edit.php:126 +msgid "Ctrl + Shift + arrow: resize by 1px" +msgstr "Control + May + flecha: redimensiona en 1 px" + +#: wp-admin/includes/image-edit.php:127 +msgid "Shift + drag: lock aspect ratio" +msgstr "May + arrastrar: bloquea relación de aspecto" + +#: wp-admin/includes/image-edit.php:130 +msgid "Crop Aspect Ratio" +msgstr "Relación de aspecto de la zona a recortar" + +#: wp-admin/includes/image-edit.php:131 +msgid "You can specify the crop selection aspect ratio then hold down the Shift key while dragging to lock it. The values can be 1:1 (square), 4:3, 16:9, etc. If there is a selection, specifying aspect ratio will set it immediately." +msgstr "Puedes especificar la relación de aspecto de la zona seleccionada para recortar y luego mantener la tecla mayúsculas mientras arrastras para bloquearlo. Los valores pueden ser 1:1 (cuadrado), 4:3, 16:9, etc. Si hay una selección, al especificar la relación de aspecto se establece al instante." + +#: wp-admin/includes/image-edit.php:133 +msgid "Crop Selection" +msgstr "Selección de recorte" + +#: wp-admin/includes/image-edit.php:134 +msgid "Once started, the selection can be adjusted by entering new values (in pixels). Note that these values are scaled to approximately match the original image dimensions. The minimum selection size equals the thumbnail size as set in the Media settings." +msgstr "Una vez comiences, la selección puede ajustarse introduciendo nuevos valores (en pixels). Date cuenta que estos valores se escalan para que se ajusten, aproximadamente, a las dimensiones de la imagen original. El tamaño de selección mínimo se iguala al tamaño de miniatura establecido en las opciones de Multimedia." + +#: wp-admin/includes/image-edit.php:139 +msgid "Aspect ratio:" +msgstr "Relación de aspecto:" + +#: wp-admin/includes/image-edit.php:148 +msgid "Selection:" +msgstr "Selección:" + +#: wp-admin/includes/image-edit.php:163 +msgid "Thumbnail Settings" +msgstr "Opciones de miniatura" + +#: wp-admin/includes/image-edit.php:165 +msgid "The thumbnail image can be cropped differently. For example it can be square or contain only a portion of the original image to showcase it better. Here you can select whether to apply changes to all image sizes or make the thumbnail different." +msgstr "La imagen de miniatura puede recortarse de manera diferente. Por ejemplo, puede ser cuadrada, o contener sólo una parte de la imagen original para que se ajuste mejor. Aquí puedes elegir si aplicar los cambios a todos los tamaños de imagen o hacer una miniatura diferente." + +#: wp-admin/includes/image-edit.php:169 +msgid "Current thumbnail" +msgstr "Miniatura actual" + +#: wp-admin/includes/image-edit.php:173 +msgid "Apply changes to:" +msgstr "Aplicar cambios a:" + +#: wp-admin/includes/image-edit.php:177 +msgid "All image sizes" +msgstr "Todos los tamaños de imagen" + +#: wp-admin/includes/image-edit.php:185 +msgid "All sizes except thumbnail" +msgstr "Todos los tamaños excepto la miniatura" + +#: wp-admin/includes/image-edit.php:195 +msgid "There are unsaved changes that will be lost. 'OK' to continue, 'Cancel' to return to the Image Editor." +msgstr "Hay cambios sin guardar que se perderán. 'Aceptar' para continuar, 'Cancelar' para volver al Editor de imágenes." + +#: wp-admin/includes/image-edit.php:428 +msgid "Cannot load image metadata." +msgstr "No se pudieron cargar los metadatos de la imagen." + +#: wp-admin/includes/image-edit.php:483 +msgid "Cannot save image metadata." +msgstr "No se pudieron guardar los metadatos de la imagen." + +#: wp-admin/includes/image-edit.php:488 +msgid "Image metadata is inconsistent." +msgstr "Los metadatos de la imagen son inconsistentes." + +#: wp-admin/includes/image-edit.php:490 +msgid "Image restored successfully." +msgstr "Imagen restaurada con éxito." + +#: wp-admin/includes/image-edit.php:503 +msgid "Unable to create new image." +msgstr "No se pudo crear una imagen nueva." + +#: wp-admin/includes/image-edit.php:529 +msgid "Error while saving the scaled image. Please reload the page and try again." +msgstr "Error al tratar de guardar la imagen escalada. Vuelve a cargar la página e inténtalo de nuevo." + +#: wp-admin/includes/image-edit.php:537 +msgid "Nothing to save, the image has not changed." +msgstr "Nada que guardar, la imagen no ha cambiado." + +#: wp-admin/includes/image-edit.php:580 +msgid "Unable to save the image." +msgstr "No se pudo guardar la imagen." + +#: wp-admin/includes/image-edit.php:665 +msgid "Image saved" +msgstr "Imagen guardada" + +#: wp-admin/includes/misc.php:575 wp-admin/user-edit.php:197 +msgid "Admin Color Scheme" +msgstr "Esquema de color de administración" + +#: wp-admin/includes/class-wp-themes-list-table.php:66 +#: wp-admin/includes/class-wp-list-table.php:181 +msgid "No items found." +msgstr "No se ha encontrado nada." + +#: wp-admin/includes/class-wp-themes-list-table.php:72 +msgid "You only have one theme enabled for this site right now. Visit the Network Admin to enable or install more themes." +msgstr "Sólo tienes un tema activado para este sitio. Ve a la administración de la red para activar or instalar más temas." + +#: wp-admin/includes/class-wp-themes-list-table.php:76 +msgid "You only have one theme enabled for this site right now. Visit the Network Admin to enable more themes." +msgstr "Sólo tienes un tema activado para este sitio. Ve a la administración de la red para activar más temas." + +#: wp-admin/includes/class-wp-themes-list-table.php:83 +msgid "You only have one theme installed right now. Live a little! You can choose from over 1,000 free themes in the WordPress.org Theme Directory at any time: just click on the Install Themes tab above." +msgstr "Tienes sólo un tema instalado. ¡Disfruta de la vida! Puedes elegir entre más de 1.000 temas gratuitos en el directorio de temas de WordPress.org cuando quieras: sólo tienes que hacer clic en la pestaña Instalar tema de arriba." + +#: wp-admin/includes/class-wp-themes-list-table.php:89 +msgid "Only the current theme is available to you. Contact the %s administrator for information about accessing additional themes." +msgstr "Para ti sólo está disponible el tema actual. Contacta con el administrador de %s para obtener información sobre cómo acceder a temas adicionales." + +#: wp-admin/includes/class-wp-themes-list-table.php:163 +msgid "Preview of “%s”" +msgstr "Vista previa de “%s”" + +#: wp-admin/includes/class-wp-themes-list-table.php:167 +#: wp-admin/includes/class-wp-upgrader.php:1357 +#: wp-admin/includes/class-wp-upgrader.php:1414 +msgid "Activate “%s”" +msgstr "Activar “%s”" + +#: wp-admin/includes/class-wp-themes-list-table.php:169 +#: wp-admin/includes/class-wp-upgrader.php:1357 +#: wp-admin/includes/class-wp-upgrader.php:1414 +#: wp-admin/includes/class-wp-plugins-list-table.php:254 +#: wp-admin/includes/class-wp-plugins-list-table.php:375 +msgid "Activate" +msgstr "Activar" + +#: wp-admin/includes/class-wp-themes-list-table.php:172 +msgid "" +"You are about to delete this theme '%s'\n" +" 'Cancel' to stop, 'OK' to delete." +msgstr "" +"Estás a punto de borrar este tema '%s'\n" +" 'Aceptar' para borrar, 'Cancelar' para salir." + +#: wp-admin/includes/class-wp-themes-list-table.php:172 +#: wp-admin/includes/media.php:1295 +#: wp-admin/includes/class-wp-users-list-table.php:129 +#: wp-admin/includes/class-wp-users-list-table.php:251 +#: wp-admin/includes/template.php:505 +#: wp-admin/includes/class-wp-plugins-list-table.php:264 +#: wp-admin/includes/class-wp-plugins-list-table.php:369 +#: wp-admin/includes/class-wp-plugins-list-table.php:378 +#: wp-admin/includes/class-wp-terms-list-table.php:83 +#: wp-admin/includes/class-wp-terms-list-table.php:263 +#: wp-admin/includes/class-wp-links-list-table.php:47 +#: wp-admin/includes/class-wp-links-list-table.php:140 +#: wp-admin/includes/widgets.php:206 wp-admin/includes/meta-boxes.php:628 +#: wp-admin/widgets.php:314 +msgid "Delete" +msgstr "Borrar" + +#: wp-admin/includes/class-wp-themes-list-table.php:189 +msgid "The template files are located in %2$s. The stylesheet files are located in %3$s. %4$s uses templates from %5$s. Changes made to the templates will affect both themes." +msgstr "Los archivos de la plantilla están situados en %2$s. Los archivos de la hoja de estilos están situados en %3$s. %4$s utiliza plantillas de %5$s. Los cambios que se hagan a las plantillas afectarán a ambos temas." + +#: wp-admin/includes/class-wp-themes-list-table.php:191 +msgid "All of this theme’s files are located in %2$s." +msgstr "Todos los archivos de este tema se encuentran en %2$s." + +#: wp-admin/includes/media.php:18 +msgid "From Computer" +msgstr "Desde el ordenador" + +#: wp-admin/includes/media.php:19 +msgid "From URL" +msgstr "Desde una URL" + +#: wp-admin/includes/media.php:20 +msgid "Gallery" +msgstr "Galería" + +#: wp-admin/includes/media.php:53 +msgid "Gallery (%s)" +msgstr "Galería (%s)" + +#: wp-admin/includes/media.php:308 +msgid "Uploads" +msgstr "Archivos subidos" + +#: wp-admin/includes/media.php:308 wp-admin/includes/template.php:1555 +msgid "WordPress" +msgstr "WordPress" + +#: wp-admin/includes/media.php:381 +msgid "Upload/Insert %s" +msgstr "Subir/Insertar %s" + +#: wp-admin/includes/media.php:540 wp-admin/includes/media.php:645 +#: wp-admin/includes/media.php:704 wp-admin/includes/media.php:760 +msgid "Saved." +msgstr "Guardado." + +#: wp-admin/includes/media.php:854 +msgid "Large" +msgstr "Grande" + +#: wp-admin/includes/media.php:923 wp-admin/includes/media.php:1091 +msgid "File URL" +msgstr "URL del archivo" + +#: wp-admin/includes/media.php:924 +msgid "Post URL" +msgstr "URL de la entrada" + +#: wp-admin/includes/media.php:948 wp-admin/includes/media.php:2102 +msgid "Alt text for the image, e.g. “The Mona Lisa”" +msgstr "Texto alternativo (alt) de la imagen, por ejemplo “La Mona Lisa”" + +#: wp-admin/includes/media.php:1008 +msgid "Empty Title filled from filename." +msgstr "Título vacío rellenado desde el nombre de fichero." + +#: wp-admin/includes/media.php:1095 +msgid "Location of the uploaded file." +msgstr "Ubicación del archivo subido." + +#: wp-admin/includes/media.php:1192 wp-admin/includes/media.php:1781 +msgid "Show" +msgstr "Mostrar" + +#: wp-admin/includes/media.php:1193 wp-admin/includes/media.php:1782 +msgid "Hide" +msgstr "Ocultar" + +#: wp-admin/includes/media.php:1266 +msgid "File name:" +msgstr "Nombre de archivo:" + +#: wp-admin/includes/media.php:1267 +msgid "File type:" +msgstr "Tipo de archivo:" + +#: wp-admin/includes/media.php:1268 +msgid "Upload date:" +msgstr "Fecha de subida:" + +#: wp-admin/includes/media.php:1270 +msgid "Dimensions:" +msgstr "Dimensiones:" + +#: wp-admin/includes/media.php:1290 wp-admin/includes/media.php:2235 +#: wp-admin/includes/media.php:2244 +msgid "Insert into Post" +msgstr "Insertar en la entrada" + +#: wp-admin/includes/media.php:1296 +msgid "You are about to delete %s." +msgstr "Estás a punto de eliminar %s." + +#: wp-admin/includes/media.php:1462 +msgid "Sorry, you have filled your storage quota (%s MB)." +msgstr "Lo sentimos, usted ha ocupado su cuota de almacenamiento (%s MB)." + +#: wp-admin/includes/media.php:1503 +msgid "Select Files" +msgstr "Elegir archivos" + +#: wp-admin/includes/media.php:1544 +msgid "Choose files to upload" +msgstr "Elige los archivos a subir" + +#: wp-admin/includes/media.php:1546 +msgid "Cancel Upload" +msgstr "Cancelar la subida" + +#: wp-admin/includes/media.php:1548 wp-admin/includes/media.php:1563 +msgid "Maximum upload file size: %d%s" +msgstr "Tamaño máximo de subida de archivos: %d%s" + +#: wp-admin/includes/media.php:1550 +msgid "After a file has been uploaded, you can add titles and descriptions." +msgstr "Después de subir un archivo, puedes agregar el título y la descripcion." + +#: wp-admin/includes/media.php:1565 +msgid "If you want to use all capabilities of the uploader, like uploading multiple files at once, please update to lighttpd 1.5." +msgstr "Si quieres usar todas las funciones del cargador, como subir varios archivos al mismo tiempo, por favor, actualiza a Lighttpd 1.5" + +#: wp-admin/includes/media.php:1596 +msgid "Add media files from your computer" +msgstr "Añadir archivos desde tu ordenador" + +#: wp-admin/includes/media.php:1625 wp-admin/includes/media.php:1805 +#: wp-admin/includes/media.php:2046 wp-admin/media-upload.php:96 +msgid "Save all changes" +msgstr "Guardar todos los cambios" + +#: wp-admin/includes/media.php:1657 +msgid "Add media file from URL" +msgstr "Añadir archivo desde una URL" + +#: wp-admin/includes/media.php:1780 +msgid "All Tabs:" +msgstr "Todas las pestañas:" + +#: wp-admin/includes/media.php:1784 +msgid "Sort Order:" +msgstr "Ordenar:" + +#: wp-admin/includes/media.php:1785 wp-admin/includes/media.php:1853 +msgid "Ascending" +msgstr "Ascendente" + +#: wp-admin/includes/media.php:1786 wp-admin/includes/media.php:1856 +msgid "Descending" +msgstr "Descendente" + +#: wp-admin/includes/media.php:1787 +msgctxt "verb" +msgid "Clear" +msgstr "Limpiar" + +#: wp-admin/includes/media.php:1812 +msgid "Gallery Settings" +msgstr "Opciones de la galería" + +#: wp-admin/includes/media.php:1817 +msgid "Link thumbnails to:" +msgstr "Enlazar miniaturas a:" + +#: wp-admin/includes/media.php:1822 +msgid "Image File" +msgstr "Archivo de imagen" + +#: wp-admin/includes/media.php:1825 +msgid "Attachment Page" +msgstr "Página de adjuntos" + +#: wp-admin/includes/media.php:1832 +msgid "Order images by:" +msgstr "Ordenar imágenes por:" + +#: wp-admin/includes/media.php:1837 +msgid "Menu order" +msgstr "Orden del menú" + +#: wp-admin/includes/media.php:1839 +msgid "Date/Time" +msgstr "Fecha/Hora" + +#: wp-admin/includes/media.php:1840 +msgid "Random" +msgstr "Aleatorio" + +#: wp-admin/includes/media.php:1848 +msgid "Order:" +msgstr "Orden:" + +#: wp-admin/includes/media.php:1863 +msgid "Gallery columns:" +msgstr "Columnas de la galería" + +#: wp-admin/includes/media.php:1883 +msgid "Insert gallery" +msgstr "Insertar galería" + +#: wp-admin/includes/media.php:1884 +msgid "Update gallery settings" +msgstr "Actualizar ajustes de la galería" + +#: wp-admin/includes/media.php:1952 +msgid "All Types" +msgstr "Todos los tipos" + +#: wp-admin/includes/media.php:1975 wp-admin/includes/nav-menu.php:608 +#: wp-admin/includes/nav-menu.php:818 +msgid "«" +msgstr "«" + +#: wp-admin/includes/media.php:1976 wp-admin/includes/nav-menu.php:609 +#: wp-admin/includes/nav-menu.php:819 +msgid "»" +msgstr "»" + +#: wp-admin/includes/media.php:1996 +#: wp-admin/includes/class-wp-list-table.php:363 +msgid "Show all dates" +msgstr "Mostrar todas las fechas" + +#: wp-admin/includes/media.php:2016 +msgid "Filter »" +msgstr "Filtrar »" + +#: wp-admin/includes/media.php:2065 +msgid "Image Caption" +msgstr "Leyenda de la imagen" + +#: wp-admin/includes/media.php:2079 +msgid "Insert an image from another web site" +msgstr "Insertar una imagen desde otra web" + +#: wp-admin/includes/media.php:2091 +msgid "Image Title" +msgstr "Título de la imagen" + +#: wp-admin/includes/media.php:2121 +msgid "Link Image To:" +msgstr "Enlazar la imagen a:" + +#: wp-admin/includes/media.php:2126 +msgid "Link to image" +msgstr "Enlace a la imagen" + +#: wp-admin/includes/media.php:2147 +msgid "Audio File URL" +msgstr "URL del archivo de audio" + +#: wp-admin/includes/media.php:2159 +msgid "Link text, e.g. “Still Alive by Jonathan Coulton”" +msgstr "Texto del enlace, por ejemplo “Still Alive por Jonathan Coulton”" + +#: wp-admin/includes/media.php:2177 +msgid "Video URL" +msgstr "URL del vídeo" + +#: wp-admin/includes/media.php:2189 +msgid "Link text, e.g. “Lucy on YouTube”" +msgstr "Texto del enlace, p.e. “Lucy en YouTube”" + +#: wp-admin/includes/media.php:2219 +msgid "Link text, e.g. “Ransom Demands (PDF)”" +msgstr "Texto del enlace, por ejemplo \"Peticiones de rescate (PDF)\"" + +#: wp-admin/includes/media.php:2275 +msgid "You are using the Flash uploader. Problems? Try the Browser uploader instead." +msgstr "Estás usando la subida de archivos mediante Flash. ¿Tienes problemas?, prueba el cargador del navegador." + +#: wp-admin/includes/media.php:2286 +msgid "You are using the Browser uploader." +msgstr "Estás usando el cargador del navegador." + +#: wp-admin/includes/media.php:2290 +msgid "Try the Flash uploader instead." +msgstr "Prueba el cargador Flash en su lugar." + +#: wp-admin/includes/plugin-install.php:46 wp-admin/includes/theme.php:394 +msgid "An Unexpected HTTP Error occurred during the API request." +msgstr "Hubo un error HTTP inesperado durante la petición API." + +#: wp-admin/includes/plugin-install.php:50 wp-admin/includes/theme.php:398 +msgid "An unknown error occurred." +msgstr "Ha ocurrido un error desconocido." + +#: wp-admin/includes/plugin-install.php:84 +msgid "Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the WordPress Plugin Directory or upload a plugin in .zip format via this page." +msgstr "Los plugins amplían las funciones de WordPress. Puedes instalarlos automáticamente desde el directorio de plugins de WordPress o subir un plugin en formato .zip desde esta página." + +#: wp-admin/includes/plugin-install.php:87 +msgid "Search for plugins by keyword, author, or tag." +msgstr "Búsqueda de plugins por palabra clave, autor o etiqueta." + +#: wp-admin/includes/plugin-install.php:90 +msgid "Popular tags" +msgstr "Etiquetas populares" + +#: wp-admin/includes/plugin-install.php:91 +msgid "You may also browse based on the most popular tags in the Plugin Directory:" +msgstr "También puedes ver las etiquetas más populares del directorio de plugins:" + +#: wp-admin/includes/plugin-install.php:108 +msgid "%d plugin" +msgstr "%d plugin" + +#: wp-admin/includes/plugin-install.php:108 +msgid "%d plugins" +msgstr "%d plugins" + +#: wp-admin/includes/plugin-install.php:126 +#: wp-admin/includes/theme-install.php:61 +msgid "Term" +msgstr "Término" + +#: wp-admin/includes/plugin-install.php:128 +msgctxt "Plugin Installer" +msgid "Tag" +msgstr "Etiqueta" + +#: wp-admin/includes/plugin-install.php:131 +#: wp-admin/includes/plugin-install.php:132 wp-admin/plugins.php:405 +msgid "Search Plugins" +msgstr "Buscar plugins" + +#: wp-admin/includes/plugin-install.php:144 +msgid "Install a plugin in .zip format" +msgstr "Instalar un plugin en formato .zip" + +#: wp-admin/includes/plugin-install.php:145 +msgid "If you have a plugin in a .zip format, you may install it by uploading it here." +msgstr "Si tienes un plugin en un archivo .zip, puedes subirlo e instalarlo desde aquí." + +#: wp-admin/includes/plugin-install.php:148 +msgid "Plugin zip file" +msgstr "Archivo .zip del plugin" + +#: wp-admin/includes/plugin-install.php:150 +#: wp-admin/includes/plugin-install.php:289 +#: wp-admin/includes/theme-install.php:122 +#: wp-admin/includes/theme-install.php:291 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:200 +msgid "Install Now" +msgstr "Instalar ahora" + +#: wp-admin/includes/plugin-install.php:264 wp-admin/update.php:107 +msgid "Plugin Install" +msgstr "Instalar plugin" + +#: wp-admin/includes/plugin-install.php:293 +#: wp-admin/includes/theme-install.php:296 +msgid "Install Update Now" +msgstr "Instalar actualización ahora" + +#: wp-admin/includes/plugin-install.php:296 +msgid "Newer Version (%s) Installed" +msgstr "Instalada la última versión (%s)" + +#: wp-admin/includes/plugin-install.php:299 +msgid "Latest Version Installed" +msgstr "Instalada la última versión" + +#: wp-admin/includes/plugin-install.php:305 +msgid "FYI" +msgstr "FYI" + +#: wp-admin/includes/plugin-install.php:310 +#: wp-admin/includes/theme-install.php:163 +msgid "Author:" +msgstr "Autor:" + +#: wp-admin/includes/plugin-install.php:312 +#: wp-admin/includes/theme-install.php:165 +msgid "Last Updated:" +msgstr "Última actualización:" + +#: wp-admin/includes/plugin-install.php:315 +#: wp-admin/includes/theme-install.php:167 +msgid "Requires WordPress Version:" +msgstr "Requiere la versión de WordPress:" + +#: wp-admin/includes/plugin-install.php:315 +#: wp-admin/includes/theme-install.php:167 +msgid "%s or higher" +msgstr "%s o superior" + +#: wp-admin/includes/plugin-install.php:317 +#: wp-admin/includes/theme-install.php:169 +msgid "Compatible up to:" +msgstr "Compatible con:" + +#: wp-admin/includes/plugin-install.php:319 +#: wp-admin/includes/theme-install.php:171 +msgid "Downloaded:" +msgstr "Descargado:" + +#: wp-admin/includes/plugin-install.php:319 +#: wp-admin/includes/theme-install.php:171 +msgid "%s time" +msgid_plural "%s times" +msgstr[0] "%s vez" +msgstr[1] "%s veces" + +#: wp-admin/includes/plugin-install.php:321 +msgid "WordPress.org Plugin Page »" +msgstr "Página de plugins de WordPress.org »" + +#: wp-admin/includes/plugin-install.php:323 +msgid "Plugin Homepage »" +msgstr "Página del plugin »" + +#: wp-admin/includes/plugin-install.php:327 +msgid "Average Rating" +msgstr "Puntuación promedio" + +#: wp-admin/includes/plugin-install.php:328 +#: wp-admin/includes/plugin-install.php:336 +#: wp-admin/includes/theme-install.php:173 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:221 +msgid "(based on %s rating)" +msgid_plural "(based on %s ratings)" +msgstr[0] "(basado en %s voto)" +msgstr[1] "(basado en %s votos)" + +#: wp-admin/includes/plugin-install.php:330 +#: wp-admin/includes/theme-install.php:175 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:223 +msgid "5 stars" +msgstr "5 estrellas" + +#: wp-admin/includes/plugin-install.php:331 +#: wp-admin/includes/theme-install.php:176 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:224 +msgid "4 stars" +msgstr "4 estrellas" + +#: wp-admin/includes/plugin-install.php:332 +#: wp-admin/includes/theme-install.php:177 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:225 +msgid "3 stars" +msgstr "3 estrellas" + +#: wp-admin/includes/plugin-install.php:333 +#: wp-admin/includes/theme-install.php:178 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:226 +msgid "2 stars" +msgstr "2 estrellas" + +#: wp-admin/includes/plugin-install.php:334 +#: wp-admin/includes/theme-install.php:179 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:227 +msgid "1 star" +msgstr "1 estrella" + +#: wp-admin/includes/plugin-install.php:342 +msgid "Warning: This plugin has not been tested with your current version of WordPress." +msgstr "Atención: Este plugin no ha sido probado en esta versión de WordPress." + +#: wp-admin/includes/plugin-install.php:345 +msgid "Warning: This plugin has not been marked as compatible with your version of WordPress." +msgstr "Atención: Este plugin no es compatible con esta versión de WordPress." + +#: wp-admin/includes/class-wp-theme-install-list-table.php:31 +#: wp-admin/includes/file.php:26 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:31 +msgid "Search Results" +msgstr "Resultados de la búsqueda" + +#: wp-admin/includes/class-wp-theme-install-list-table.php:33 +msgctxt "Theme Installer" +msgid "Featured" +msgstr "Destacados" + +#: wp-admin/includes/class-wp-theme-install-list-table.php:35 +msgctxt "Theme Installer" +msgid "Newest" +msgstr "Recientes" + +#: wp-admin/includes/class-wp-theme-install-list-table.php:36 +msgctxt "Theme Installer" +msgid "Recently Updated" +msgstr "Actualizados recientemente" + +#: wp-admin/includes/class-wp-theme-install-list-table.php:98 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:86 +msgid "Try again" +msgstr "Inténtalo de nuevo" + +#: wp-admin/includes/class-wp-theme-install-list-table.php:109 +msgid "No themes match your request." +msgstr "Ningún tema se ajusta a lo que buscas." + +#: wp-admin/includes/deprecated.php:524 +msgid "No matching users were found!" +msgstr "¡No se encontraron usuarios!" + +#: wp-admin/includes/deprecated.php:563 +msgid "Displaying %s–%s of %s" +msgstr "Mostrando %s–%s de %s" + +#: wp-admin/includes/class-wp-comments-list-table.php:131 +msgid "No comments awaiting moderation… yet." +msgstr "No hay comentarios pendientes de moderación." + +#: wp-admin/includes/class-wp-comments-list-table.php:133 +msgid "No comments found." +msgstr "Sin comentarios." + +#: wp-admin/includes/class-wp-comments-list-table.php:144 +msgctxt "comments" +msgid "All" +msgid_plural "All" +msgstr[0] "Todo" +msgstr[1] "Todos" + +#: wp-admin/includes/class-wp-comments-list-table.php:145 +msgid "Pending (%s)" +msgid_plural "Pending (%s)" +msgstr[0] "Pendiente (%s)" +msgstr[1] "Pendientes (%s)" + +#: wp-admin/includes/class-wp-comments-list-table.php:146 +msgid "Approved" +msgid_plural "Approved" +msgstr[0] "Aprobado" +msgstr[1] "Aprobados" + +#: wp-admin/includes/class-wp-comments-list-table.php:147 +msgid "Spam (%s)" +msgid_plural "Spam (%s)" +msgstr[0] "Spam (%s)" +msgstr[1] "Spam (%s)" + +#: wp-admin/includes/class-wp-comments-list-table.php:148 +msgid "Trash (%s)" +msgid_plural "Trash (%s)" +msgstr[0] "Papelera (%s)" +msgstr[1] "Papelera (%s)" + +#: wp-admin/includes/class-wp-comments-list-table.php:190 +msgctxt "comment" +msgid "Mark as Spam" +msgstr "Marcar como spam" + +#: wp-admin/includes/class-wp-comments-list-table.php:195 +#: wp-admin/includes/class-wp-comments-list-table.php:400 +msgctxt "comment" +msgid "Not Spam" +msgstr "No es spam" + +#: wp-admin/includes/class-wp-comments-list-table.php:213 +msgid "Show all comment types" +msgstr "Mostrar todos los comentarios" + +#: wp-admin/includes/class-wp-comments-list-table.php:230 +msgid "Empty Spam" +msgstr "Vaciar spam" + +#: wp-admin/includes/class-wp-comments-list-table.php:253 +#: wp-admin/includes/class-wp-comments-list-table.php:524 +msgctxt "column name" +msgid "Comment" +msgstr "Comentario" + +#: wp-admin/includes/class-wp-comments-list-table.php:256 +msgctxt "column name" +msgid "In Response To" +msgstr "En respuesta a" + +#: wp-admin/includes/class-wp-comments-list-table.php:333 +msgid "Y/m/d \\a\\t g:i A" +msgstr "d/m/Y \\a\\t G:i" + +#: wp-admin/includes/class-wp-comments-list-table.php:352 +msgid "Submitted on %2$s at %3$s" +msgstr "Enviado el %2$s a las %3$s" + +#: wp-admin/includes/class-wp-comments-list-table.php:360 +msgid "In reply to %2$s." +msgstr "En respuesta a %2$s." + +#: wp-admin/includes/class-wp-comments-list-table.php:473 +msgid "Y/m/d \\a\\t g:ia" +msgstr "d/m/Y \\a\\t G:i" + +#: wp-admin/includes/file.php:11 +msgid "Main Index Template" +msgstr "Plantilla de la página principal" + +#: wp-admin/includes/file.php:12 wp-admin/includes/file.php:40 +msgid "Stylesheet" +msgstr "Hoja de estilos" + +#: wp-admin/includes/file.php:13 +msgid "Visual Editor Stylesheet" +msgstr "Hoja de estilos del editor visual" + +#: wp-admin/includes/file.php:14 +msgid "Visual Editor RTL Stylesheet" +msgstr "Editor visual de estilos RTL" + +#: wp-admin/includes/file.php:15 +msgid "RTL Stylesheet" +msgstr "Hoja de estilos RTL" + +#: wp-admin/includes/file.php:17 +msgid "Popup Comments" +msgstr "Comentarios emergentes" + +#: wp-admin/includes/file.php:18 +msgid "Footer" +msgstr "Pie de página" + +#: wp-admin/includes/file.php:22 +msgid "Author Template" +msgstr "Plantilla de autor" + +#: wp-admin/includes/file.php:23 +msgid "Tag Template" +msgstr "Plantilla de etiqueta" + +#: wp-admin/includes/file.php:24 +msgid "Category Template" +msgstr "Plantilla de categoría" + +#: wp-admin/includes/file.php:25 wp-admin/includes/meta-boxes.php:573 +msgid "Page Template" +msgstr "Plantilla de página" + +#: wp-admin/includes/file.php:27 +msgid "Search Form" +msgstr "Formulario de búsqueda" + +#: wp-admin/includes/file.php:28 +msgid "Single Post" +msgstr "Entrada individual" + +#: wp-admin/includes/file.php:29 +msgid "404 Template" +msgstr "Error 404 (página no encontrada)" + +#: wp-admin/includes/file.php:30 +msgid "Links Template" +msgstr "Plantilla de enlaces" + +#: wp-admin/includes/file.php:31 +msgid "Theme Functions" +msgstr "Funciones del tema" + +#: wp-admin/includes/file.php:32 +msgid "Attachment Template" +msgstr "Plantilla de archivos adjuntos" + +#: wp-admin/includes/file.php:33 +msgid "Image Attachment Template" +msgstr "Plantilla de imagen adjunta" + +#: wp-admin/includes/file.php:34 +msgid "Video Attachment Template" +msgstr "Plantilla de vídeo adjunto" + +#: wp-admin/includes/file.php:35 +msgid "Audio Attachment Template" +msgstr "Plantilla de audio adjunto" + +#: wp-admin/includes/file.php:36 +msgid "Application Attachment Template" +msgstr "Plantilla de aplicación adjunta" + +#: wp-admin/includes/file.php:37 +msgid "my-hacks.php (legacy hacks support)" +msgstr "my-hacks.php (soporte para hacks)" + +#: wp-admin/includes/file.php:38 +msgid ".htaccess (for rewrite rules )" +msgstr ".htaccess (para reglas de reescritura)" + +#: wp-admin/includes/file.php:41 +msgid "Comments Template" +msgstr "Plantilla de comentarios" + +#: wp-admin/includes/file.php:42 +msgid "Popup Comments Template" +msgstr "Plantilla de comentarios emergentes" + +#: wp-admin/includes/file.php:65 +msgid "%s Page Template" +msgstr "%s Plantilla de Página" + +#: wp-admin/includes/file.php:238 +msgid "Sorry, can’t edit files with “..” in the name. If you are trying to edit a file in your WordPress home directory, you can just type the name of the file in." +msgstr "Disculpa, no puedes editar archivos con \"..\" en el nombre. Si estás intentando editar un archivo en tu directorio raíz de WordPress, simplemente escribe el nombre del archivo." + +#: wp-admin/includes/file.php:244 +msgid "Sorry, that file cannot be edited." +msgstr "Disculpa, ese archivo no puede editarse." + +#: wp-admin/includes/file.php:291 wp-admin/includes/file.php:417 +msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini." +msgstr "El archivo a subir sobrepasa la directiva upload_max_filesize (tamaño máximo de subida) en php.ini." + +#: wp-admin/includes/file.php:292 wp-admin/includes/file.php:418 +msgid "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form." +msgstr "El archivo a subir sobrepasa la directiva MAX_FILE_SIZE (tamaño máximo de archivo) especificada en el formulario HTML." + +#: wp-admin/includes/file.php:293 wp-admin/includes/file.php:419 +msgid "The uploaded file was only partially uploaded." +msgstr "Sólo se ha podido subir una parte del archivo." + +#: wp-admin/includes/file.php:294 wp-admin/includes/file.php:420 +msgid "No file was uploaded." +msgstr "No se ha subido ningún archivo." + +#: wp-admin/includes/file.php:296 wp-admin/includes/file.php:422 +msgid "Missing a temporary folder." +msgstr "Falta un directorio temporal." + +#: wp-admin/includes/file.php:297 wp-admin/includes/file.php:423 +msgid "Failed to write file to disk." +msgstr "El archivo no se ha podido grabar en el disco." + +#: wp-admin/includes/file.php:298 wp-admin/includes/file.php:424 +msgid "File upload stopped by extension." +msgstr "Subida de archivo detenida a causa de la extensión." + +#: wp-admin/includes/file.php:315 wp-admin/includes/file.php:440 +msgid "Invalid form submission." +msgstr "Se envió un formulario erróneo." + +#: wp-admin/includes/file.php:324 +msgid "File is empty. Please upload something more substantial." +msgstr "El archivo está vacío. Por favor, sube algo con más sustancia." + +#: wp-admin/includes/file.php:326 wp-admin/includes/import.php:63 +msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini." +msgstr "El archivo está vacío. Por favor, sube algo con más sustancia. Este error puede que lo provoque que tu fichero php.ini tenga inhabilitadas las subidas o porque post_max_size esté definido más pequeño que el upload_max_filesize en php.ini." + +#: wp-admin/includes/file.php:332 +msgid "Specified file failed upload test." +msgstr "El archivo indicado no cumple los requisitos de subida." + +#: wp-admin/includes/file.php:345 wp-admin/includes/file.php:465 +msgid "Sorry, this file type is not permitted for security reasons." +msgstr "Perdona, por razones de seguridad, este tipo de archivos no está permitido." + +#: wp-admin/includes/file.php:365 wp-admin/includes/file.php:487 +#: wp-admin/includes/class-wp-upgrader.php:1463 +msgid "The uploaded file could not be moved to %s." +msgstr "El archivo subido no se ha podido mover a %s." + +#: wp-admin/includes/file.php:448 +msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini." +msgstr "El archivo está vacío. Por favor, sube algo con más sustancia. Este error podría ser causado porque las subidas está desactivadas en tu php.ini." + +#: wp-admin/includes/file.php:452 +msgid "Specified file does not exist." +msgstr "El archivo especificado no existe." + +#: wp-admin/includes/file.php:516 +msgid "Invalid URL Provided." +msgstr "La URL especificada no es válido." + +#: wp-admin/includes/file.php:520 wp-admin/includes/file.php:524 +msgid "Could not create Temporary file." +msgstr "No ha sido posible crear el archivo temporal." + +#: wp-admin/includes/file.php:563 wp-admin/includes/class-wp-upgrader.php:45 +#: wp-admin/includes/plugin.php:687 wp-admin/includes/theme.php:85 +msgid "Could not access filesystem." +msgstr "No ha sido posible acceder al sistema de archivos." + +#: wp-admin/includes/file.php:623 wp-admin/includes/file.php:706 +#: wp-admin/includes/class-wp-upgrader.php:58 +msgid "Incompatible Archive." +msgstr "Archivo incompatible." + +#: wp-admin/includes/file.php:627 wp-admin/includes/file.php:663 +msgid "Could not retrieve file from archive." +msgstr "No se puede recuperar el archivo." + +#: wp-admin/includes/file.php:657 wp-admin/includes/file.php:738 +#: wp-admin/includes/file.php:786 wp-admin/includes/class-wp-upgrader.php:57 +msgid "Could not create directory." +msgstr "No ha sido posible crear el directorio" + +#: wp-admin/includes/file.php:673 +msgid "Could not extract file from archive." +msgstr "No podemos descomprimir el archivo." + +#: wp-admin/includes/file.php:676 wp-admin/includes/file.php:751 +#: wp-admin/includes/file.php:780 +msgid "Could not copy file." +msgstr "No ha sido posible copiar el archivo." + +#: wp-admin/includes/file.php:709 +msgid "Empty archive." +msgstr "Archivo vacío." + +#: wp-admin/includes/file.php:971 +msgid "Error: There was an error connecting to the server, Please verify the settings are correct." +msgstr "Error: Se ha producido un error en la conexión con el servidor. Por favor, verifica que la configuración es correcta." + +#: wp-admin/includes/file.php:979 +msgid "FTP" +msgstr "FTP" + +#: wp-admin/includes/file.php:981 +msgid "FTPS (SSL)" +msgstr "FTPS (SSL)" + +#: wp-admin/includes/file.php:983 +msgid "SSH2" +msgstr "SSH2" + +#: wp-admin/includes/file.php:1004 +msgid "Connection Information" +msgstr "Datos de conexión" + +#: wp-admin/includes/file.php:1008 +msgid "To perform the requested action, WordPress needs to access your web server." +msgstr "Para realizar la operación que has solicitado WordPress necesita tener acceso a tu servidor web." + +#: wp-admin/includes/file.php:1012 +msgid "Please enter your FTP or SSH credentials to proceed." +msgstr "Por favor, introduce tus datos de acceso FTP o SSH para proceder." + +#: wp-admin/includes/file.php:1013 +msgid "FTP/SSH Username" +msgstr "Usuario FTP/SSH" + +#: wp-admin/includes/file.php:1014 +msgid "FTP/SSH Password" +msgstr "Contraseña FTP/SSH" + +#: wp-admin/includes/file.php:1016 +msgid "Please enter your FTP credentials to proceed." +msgstr "Por favor, introduce tus datos de acceso FTP para proceder." + +#: wp-admin/includes/file.php:1017 +msgid "FTP Username" +msgstr "Usuario FTP" + +#: wp-admin/includes/file.php:1018 +msgid "FTP Password" +msgstr "Contraseña FTP" + +#: wp-admin/includes/file.php:1022 +msgid "If you do not remember your credentials, you should contact your web host." +msgstr "Si no recuerdas tus datos de acceso deberías contactar con tu proveedor de alojamiento." + +#: wp-admin/includes/file.php:1026 +msgid "Hostname" +msgstr "Servidor" + +#: wp-admin/includes/file.php:1042 +msgid "Authentication Keys" +msgstr "Claves de autentificación" + +#: wp-admin/includes/file.php:1044 +msgid "Public Key:" +msgstr "Clave pública:" + +#: wp-admin/includes/file.php:1045 +msgid "Private Key:" +msgstr "Clave privada:" + +#: wp-admin/includes/file.php:1048 +msgid "Enter the location on the server where the keys are located. If a passphrase is needed, enter that in the password field above." +msgstr "Introduce la dirección del servidor en el que se encuentran las claves. Si es necesaria una contraseña, introdúcela en el campo de contraseña." + +#: wp-admin/includes/file.php:1053 wp-admin/includes/file.php:1055 +msgid "Connection Type" +msgstr "Tipo de conexión" + +#: wp-admin/includes/file.php:1074 +msgid "Proceed" +msgstr "Ejecutar" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:57 +msgid "The ssh2 PHP extension is not available" +msgstr "La extesión PHP de SSH2 no está disponible" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:61 +msgid "The ssh2 PHP extension is available, however, we require the PHP5 function stream_get_contents()" +msgstr "La extensión ssh2 de PHP está disponible, no obstante es necesaria la función de PHP5 stream_get_contents()" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:72 +msgid "SSH2 hostname is required" +msgstr "El nombre del servidor del SSH2 es necesario" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:88 +msgid "SSH2 username is required" +msgstr "El nombre de usuario del SSH2 es necesario" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:96 +msgid "SSH2 password is required" +msgstr "La contraseña del SSH2 es necesaria" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:111 +msgid "Failed to connect to SSH2 Server %1$s:%2$s" +msgstr "Ha sido imposible conectar con el SSH2 %1$s:%2$s" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:117 +#: wp-admin/includes/class-wp-filesystem-ftpsockets.php:74 +#: wp-admin/includes/class-wp-filesystem-ftpext.php:79 +msgid "Username/Password incorrect for %s" +msgstr "Nombre de usuario y/o contraseña incorrecto/s para %s" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:122 +msgid "Public and Private keys incorrect for %s" +msgstr "Claves públicas y privadas incorrectas para %s" + +#: wp-admin/includes/class-wp-filesystem-ssh2.php:138 +msgid "Unable to perform command: %s" +msgstr "No se pudo realizar el comando: %s" + +#: wp-admin/includes/class-wp-users-list-table.php:78 +msgid "No matching users were found." +msgstr "No se han encontrado usuarios que se ajusten a lo que buscas." + +#: wp-admin/includes/class-wp-users-list-table.php:100 +msgctxt "users" +msgid "All (%s)" +msgid_plural "All (%s)" +msgstr[0] "Todo (%s)" +msgstr[1] "Todos (%s)" + +#: wp-admin/includes/class-wp-users-list-table.php:114 +msgid "%1$s (%2$s)" +msgstr "%1$s (%2$s)" + +#: wp-admin/includes/class-wp-users-list-table.php:126 +#: wp-admin/includes/class-wp-users-list-table.php:253 +#: wp-admin/includes/nav-menu.php:185 +msgid "Remove" +msgstr "Eliminar" + +#: wp-admin/includes/class-wp-users-list-table.php:142 +#: wp-admin/includes/class-wp-users-list-table.php:144 +msgid "Change role to…" +msgstr "Cambiar perfil a…" + +#: wp-admin/includes/class-wp-users-list-table.php:147 +msgid "Change" +msgstr "Cambiar" + +#: wp-admin/includes/class-wp-users-list-table.php:299 +msgid "View posts by this author" +msgstr "Ver las entradas de este autor" + +#: wp-admin/includes/internal-linking.php:77 +msgid "Enter the destination URL" +msgstr "Introduce la URL de destino" + +#: wp-admin/includes/internal-linking.php:85 +msgid "Open link in a new window/tab" +msgstr "Abrir enlace en una nueva ventana/pestaña" + +#: wp-admin/includes/internal-linking.php:89 +msgid "Or link to existing content" +msgstr "O enlaza a contenido ya existente" + +#: wp-admin/includes/internal-linking.php:105 +msgid "No search term specified. Showing recent items." +msgstr "" +"No se ha indicado ningún término de búsqueda. Se mostrarán\n" +" los objetos más recientes." + +#: wp-admin/includes/user.php:142 wp-admin/includes/user.php:144 +msgid "ERROR: You entered your new password only once." +msgstr "ERROR: Has escrito tu nueva contraseña sólo una vez." + +#: wp-admin/includes/user.php:147 +msgid "ERROR: Please enter your password." +msgstr "ERROR: Por favor, escribe tu contraseña." + +#: wp-admin/includes/user.php:149 +msgid "ERROR: Please enter your password twice." +msgstr "ERROR: Por favor, escribe tu contraseña dos veces." + +#: wp-admin/includes/user.php:154 +msgid "ERROR: Passwords may not contain the character \"\\\"." +msgstr "ERROR: La contraseña no puede contener el carácter \"\\\"." + +#: wp-admin/includes/user.php:158 +msgid "ERROR: Please enter the same password in the two password fields." +msgstr "ERROR: Por favor, introduce la misma contraseña en los dos campos." + +#: wp-admin/includes/user.php:167 +msgid "ERROR: This username is already registered. Please choose another one." +msgstr "ERROR: Ese usuario ya existe. Por favor, elige otro." + +#: wp-admin/includes/user.php:171 +msgid "ERROR: Please enter an e-mail address." +msgstr "ERROR: Por favor, introduce un correo electrónico" + +#: wp-admin/includes/user.php:173 +msgid "ERROR: The e-mail address isn’t correct." +msgstr "ERROR: La dirección de correo electrónico no es correcta." + +#: wp-admin/includes/user.php:375 +msgid "Notice:" +msgstr "Aviso:" + +#: wp-admin/includes/user.php:376 +msgid "You’re using the auto-generated password for your account. Would you like to change it to something easier to remember?" +msgstr "Estás utilizando la contraseña generada automáticamente para tu cuenta. ¿Quieres cambiarla por otra más fácil de recordar?" + +#: wp-admin/includes/user.php:378 +msgid "Yes, take me to my profile page" +msgstr "Sí, llévame a mi página de perfil" + +#: wp-admin/includes/user.php:379 +msgid "No thanks, do not remind me again" +msgstr "No gracias, no me lo recuerdes de nuevo" + +#: wp-admin/includes/template.php:347 +msgid "Reply to Comment" +msgstr "Responder al comentarío" + +#: wp-admin/includes/template.php:372 wp-admin/edit-form-comment.php:74 +msgid "Update Comment" +msgstr "Actualizar comentario" + +#: wp-admin/includes/template.php:373 +msgid "Submit Reply" +msgstr "Enviar respuesta" + +#: wp-admin/includes/template.php:406 +msgid "Comment by %s moved to the trash." +msgstr "Comentario de %s movido a la papelera." + +#: wp-admin/includes/template.php:409 +msgid "Comment by %s marked as spam." +msgstr "El comentario de %s se ha marcado como spam." + +#: wp-admin/includes/template.php:429 wp-admin/includes/template.php:444 +#: wp-admin/includes/template.php:512 wp-admin/includes/template.php:539 +msgid "Value" +msgstr "Valor" + +#: wp-admin/includes/template.php:502 +msgid "Key" +msgstr "Clave" + +#: wp-admin/includes/template.php:534 +msgid "Add New Custom Field:" +msgstr "Añadir nuevo campo personalizado:" + +#: wp-admin/includes/template.php:558 +msgid "Enter new" +msgstr "Nuevo" + +#: wp-admin/includes/template.php:568 +msgid "Add Custom Field" +msgstr "Añadir un campo personalizado" + +#: wp-admin/includes/template.php:630 +msgid "%1$s%2$s, %3$s @ %4$s : %5$s" +msgstr "%1$s%2$s, %3$s @ %4$s : %5$s" + +#: wp-admin/includes/template.php:735 +msgid "Thumbnail linked to file" +msgstr "Miniatura enlazada al archivo" + +#: wp-admin/includes/template.php:735 +msgid "Image linked to file" +msgstr "Imagen enlazada al archivo" + +#: wp-admin/includes/template.php:739 +msgid "Thumbnail linked to page" +msgstr "Miniatura enlazada a la página" + +#: wp-admin/includes/template.php:739 +msgid "Image linked to page" +msgstr "Imagen enlazada a la página" + +#: wp-admin/includes/template.php:744 +msgid "Link to file" +msgstr "Enlace al archivo" + +#: wp-admin/includes/template.php:748 +msgid "Link to page" +msgstr "Enlace a la página" + +#: wp-admin/includes/template.php:843 +msgid "Before you can upload your import file, you will need to fix the following error:" +msgstr "Antes de poder subir el fichero de importación, debes resolver el siguiente error:" + +#: wp-admin/includes/template.php:849 +msgid "Choose a file from your computer:" +msgstr "Elige un archivo de tu ordenador:" + +#: wp-admin/includes/template.php:849 +msgid "Maximum size: %s" +msgstr "Tamaño máximo: %s" + +#: wp-admin/includes/template.php:854 +msgid "Upload file and import" +msgstr "Subir archivo e importar" + +#: wp-admin/includes/template.php:964 wp-admin/press-this.php:521 +#: wp-admin/press-this.php:571 +msgid "Click to toggle" +msgstr "Haz clic para cambiar" + +#: wp-admin/includes/template.php:1089 wp-admin/includes/template.php:1129 +#: wp-admin/includes/plugin.php:1605 wp-admin/includes/plugin.php:1628 +msgid "The miscellaneous options group has been removed. Use another settings group." +msgstr "Las opciones misceláneas de grupo se han eliminado. Usa otros ajustes de grupo." + +#: wp-admin/includes/template.php:1346 +msgid "Find Posts or Pages" +msgstr "Buscar entradas o páginas" + +#: wp-admin/includes/template.php:1418 wp-admin/includes/template.php:1469 +msgid "Sites" +msgstr "Sitios" + +#: wp-admin/includes/template.php:1422 +msgid "New Media" +msgstr "Añadir medio" + +#: wp-admin/includes/template.php:1430 +msgid "New Link" +msgstr "Añadir enlace" + +#: wp-admin/includes/template.php:1432 +msgid "Edit Links" +msgstr "Editar enlaces" + +#: wp-admin/includes/template.php:1435 +msgid "New User" +msgstr "Añadir usuario" + +#: wp-admin/includes/template.php:1438 +msgid "Edit Users" +msgstr "Editar usuarios" + +#: wp-admin/includes/template.php:1444 +msgid "Manage Plugins" +msgstr "Administrar plugins" + +#: wp-admin/includes/template.php:1462 +msgid "Drafts" +msgstr "Borradores" + +#: wp-admin/includes/template.php:1630 wp-admin/includes/meta-boxes.php:119 +#: wp-admin/includes/meta-boxes.php:144 +msgid "Password protected" +msgstr "Protegida con contraseña" + +#: wp-admin/includes/template.php:1637 +msgctxt "post state" +msgid "Pending" +msgstr "Pendiente" + +#: wp-admin/includes/template.php:1710 +msgid "Enable accessibility mode" +msgstr "Activar modo de accesibilidad" + +#: wp-admin/includes/template.php:1710 +msgid "Disable accessibility mode" +msgstr "Desactivar modo de accesibilidad" + +#: wp-admin/includes/template.php:1726 +msgctxt "Metaboxes" +msgid "Show on screen" +msgstr "Mostrar en pantalla " + +#: wp-admin/includes/template.php:1733 +msgctxt "Columns" +msgid "Show on screen" +msgstr "Mostrar en pantalla" + +#: wp-admin/includes/template.php:1760 +msgctxt "Screen Options" +msgid "Show on screen" +msgstr "Mostrar en pantalla" + +#: wp-admin/includes/template.php:1781 +msgid "Documentation" +msgstr "Documentación" + +#: wp-admin/includes/template.php:1798 +msgid "Screen Options" +msgstr "Opciones de pantalla" + +#: wp-admin/includes/template.php:1853 +msgid "Screen Layout" +msgstr "Diseño de pantalla" + +#: wp-admin/includes/template.php:1853 +msgid "Number of Columns:" +msgstr "Número de columnas:" + +#: wp-admin/includes/template.php:2165 wp-admin/options.php:215 +msgid "Save Changes" +msgstr "Guardar cambios" + +#: wp-admin/includes/taxonomy.php:100 +msgid "You did not enter a category name." +msgstr "No has introducido un nombre de categoría." + +#: wp-admin/includes/class-wp-upgrader.php:44 +msgid "Invalid Data provided." +msgstr "Datos facilitado no válidos." + +#: wp-admin/includes/class-wp-upgrader.php:46 wp-admin/includes/plugin.php:690 +#: wp-admin/includes/theme.php:88 +msgid "Filesystem error." +msgstr "Error del sistema de archivos." + +#: wp-admin/includes/class-wp-upgrader.php:47 +msgid "Unable to locate WordPress Root directory." +msgstr "Ha sido imposible localizar el directorio de WordPress." + +#: wp-admin/includes/class-wp-upgrader.php:48 +msgid "Unable to locate WordPress Content directory (wp-content)." +msgstr "Ha sido imposible localizar el directorio de contenidos de WordPress (wp-content)." + +#: wp-admin/includes/class-wp-upgrader.php:49 wp-admin/includes/plugin.php:695 +msgid "Unable to locate WordPress Plugin directory." +msgstr "Ha sido imposible localizar el directorio de plugins de WordPress." + +#: wp-admin/includes/class-wp-upgrader.php:50 +msgid "Unable to locate WordPress Theme directory." +msgstr "Ha sido imposible localizar el directorio de temas de WordPress." + +#: wp-admin/includes/class-wp-upgrader.php:52 +msgid "Unable to locate needed folder (%s)." +msgstr "Ha sido imposible localizar la carpeta %s." + +#: wp-admin/includes/class-wp-upgrader.php:54 +msgid "Download failed." +msgstr "Descarga fallida." + +#: wp-admin/includes/class-wp-upgrader.php:55 +#: wp-admin/includes/update-core.php:327 +msgid "Installing the latest version…" +msgstr "Instalando última versión…" + +#: wp-admin/includes/class-wp-upgrader.php:56 +msgid "Destination folder already exists." +msgstr "La carpeta ya existe." + +#: wp-admin/includes/class-wp-upgrader.php:60 +msgid "Enabling Maintenance mode…" +msgstr "Activando el modo mantenimiento…" + +#: wp-admin/includes/class-wp-upgrader.php:61 +msgid "Disabling Maintenance mode…" +msgstr "Desactivando el modo de mantenimiento…" + +#: wp-admin/includes/class-wp-upgrader.php:370 +msgid "The plugin is at the latest version." +msgstr "Tienes la última versión del plugin." + +#: wp-admin/includes/class-wp-upgrader.php:371 +#: wp-admin/includes/class-wp-upgrader.php:611 +#: wp-admin/includes/class-wp-upgrader.php:864 +msgid "Update package not available." +msgstr "Paquete de actualización no disponible." + +#: wp-admin/includes/class-wp-upgrader.php:372 +#: wp-admin/includes/class-wp-upgrader.php:612 +#: wp-admin/includes/class-wp-upgrader.php:865 +msgid "Downloading update from %s…" +msgstr "Descargando paquete de instalación desde %s…" + +#: wp-admin/includes/class-wp-upgrader.php:373 +#: wp-admin/includes/class-wp-upgrader.php:613 +#: wp-admin/includes/class-wp-upgrader.php:866 +msgid "Unpacking the update…" +msgstr "Descomprimiendo actualización…" + +#: wp-admin/includes/class-wp-upgrader.php:374 +msgid "Deactivating the plugin…" +msgstr "Desactivando el plugin…" + +#: wp-admin/includes/class-wp-upgrader.php:375 +msgid "Removing the old version of the plugin…" +msgstr "Eliminando la antigua versión del plugin…" + +#: wp-admin/includes/class-wp-upgrader.php:376 +msgid "Could not remove the old plugin." +msgstr "No ha sido posible eliminar la versión anterior del plugin." + +#: wp-admin/includes/class-wp-upgrader.php:377 +msgid "Plugin update failed." +msgstr "Actualización de plugin fallida." + +#: wp-admin/includes/class-wp-upgrader.php:378 +msgid "Plugin updated successfully." +msgstr "El plugin se ha actualizado con éxito." + +#: wp-admin/includes/class-wp-upgrader.php:382 +#: wp-admin/includes/class-wp-upgrader.php:621 +msgid "Install package not available." +msgstr "El paquete de instalación no está disponible." + +#: wp-admin/includes/class-wp-upgrader.php:383 +#: wp-admin/includes/class-wp-upgrader.php:622 +msgid "Downloading install package from %s…" +msgstr "Descargando el archivo de instalación de %s…" + +#: wp-admin/includes/class-wp-upgrader.php:384 +#: wp-admin/includes/class-wp-upgrader.php:623 +msgid "Unpacking the package…" +msgstr "Descomprimiendo…" + +#: wp-admin/includes/class-wp-upgrader.php:385 +msgid "Installing the plugin…" +msgstr "Instalando el plugin…" + +#: wp-admin/includes/class-wp-upgrader.php:386 +msgid "Plugin install failed." +msgstr "Fallo en la instalación del plugin." + +#: wp-admin/includes/class-wp-upgrader.php:387 +msgid "Plugin installed successfully." +msgstr "Plugin instalado correctamente." + +#: wp-admin/includes/class-wp-upgrader.php:610 +msgid "The theme is at the latest version." +msgstr "Tienes la última versión del tema." + +#: wp-admin/includes/class-wp-upgrader.php:614 +msgid "Removing the old version of the theme…" +msgstr "Eliminando la antigua versión del tema…" + +#: wp-admin/includes/class-wp-upgrader.php:615 +msgid "Could not remove the old theme." +msgstr "No ha sido posible eliminar la versión anterior del tema." + +#: wp-admin/includes/class-wp-upgrader.php:616 +msgid "Theme update failed." +msgstr "Actualización del tema fallida." + +#: wp-admin/includes/class-wp-upgrader.php:617 +msgid "Theme updated successfully." +msgstr "Tema actualizado correctamente." + +#: wp-admin/includes/class-wp-upgrader.php:624 +msgid "Installing the theme…" +msgstr "Instalando el tema…" + +#: wp-admin/includes/class-wp-upgrader.php:625 +msgid "Theme install failed." +msgstr "Fallo en la instalación del tema." + +#: wp-admin/includes/class-wp-upgrader.php:626 +msgid "Theme installed successfully." +msgstr "El tema se ha instalado correctamente." + +#: wp-admin/includes/class-wp-upgrader.php:863 +msgid "WordPress is at the latest version." +msgstr "Tienes la última versión de WordPress." + +#: wp-admin/includes/class-wp-upgrader.php:867 +msgid "Could not copy files." +msgstr "No ha sido posible copiar los archivos." + +#: wp-admin/includes/class-wp-upgrader.php:1020 wp-admin/update.php:54 +msgid "Update Plugin" +msgstr "Actualizar plugin" + +#: wp-admin/includes/class-wp-upgrader.php:1034 +msgid "Reactivating the plugin…" +msgstr "Reactivando el plugin…" + +#: wp-admin/includes/class-wp-upgrader.php:1039 +#: wp-admin/includes/class-wp-upgrader.php:1280 +#: wp-admin/includes/class-wp-upgrader.php:1282 +#: wp-admin/includes/class-wp-plugins-list-table.php:375 +msgid "Activate this plugin" +msgstr "Activar este plugin" + +#: wp-admin/includes/class-wp-upgrader.php:1039 +#: wp-admin/includes/class-wp-upgrader.php:1282 +msgid "Activate Plugin" +msgstr "Activar plugin" + +#: wp-admin/includes/class-wp-upgrader.php:1040 +#: wp-admin/includes/class-wp-upgrader.php:1198 +msgid "Go to plugins page" +msgstr "Ir a la página de plugins" + +#: wp-admin/includes/class-wp-upgrader.php:1040 +#: wp-admin/includes/class-wp-upgrader.php:1198 +#: wp-admin/includes/class-wp-upgrader.php:1294 +msgid "Return to Plugins page" +msgstr "Volver a la página de plugins" + +#: wp-admin/includes/class-wp-upgrader.php:1083 +msgid "The update process is starting. This process may take a while on some hosts, so please be patient." +msgstr "El proceso de actualización ha empezado. Puede llevar un rato en algunos servidores, ten paciencia, por favor." + +#: wp-admin/includes/class-wp-upgrader.php:1084 +msgid "An error occurred while updating %1$s: %2$s." +msgstr "Ha ocurrido un error cuando se actualizaba %1$s: %2$s." + +#: wp-admin/includes/class-wp-upgrader.php:1085 +msgid "The update of %1$s failed." +msgstr "La actualización de %1$s ha fallado." + +#: wp-admin/includes/class-wp-upgrader.php:1086 +msgid "%1$s updated successfully." +msgstr "%1$s actualizado correctamente." + +#: wp-admin/includes/class-wp-upgrader.php:1086 +msgid "Show Details" +msgstr "Mostrar detalles" + +#: wp-admin/includes/class-wp-upgrader.php:1086 +msgid "Hide Details" +msgstr "Ocultar detalles" + +#: wp-admin/includes/class-wp-upgrader.php:1087 +msgid "All updates have been completed." +msgstr "Todas las actualizaciones han sido completadas." + +#: wp-admin/includes/class-wp-upgrader.php:1185 +msgid "Updating Plugin %1$s (%2$d/%3$d)" +msgstr "Actualizando plugin %1$s (%2$d/%3$d)" + +#: wp-admin/includes/class-wp-upgrader.php:1199 +#: wp-admin/includes/class-wp-upgrader.php:1230 +msgid "Go to WordPress Updates page" +msgstr "Ir a la página de actualizaciones de WordPress" + +#: wp-admin/includes/class-wp-upgrader.php:1199 +#: wp-admin/includes/class-wp-upgrader.php:1230 +msgid "Return to WordPress Updates" +msgstr "Volver a las actualizaciones de WordPress" + +#: wp-admin/includes/class-wp-upgrader.php:1216 +msgid "Updating Theme %1$s (%2$d/%3$d)" +msgstr "Actualizando tema %1$s (%2$d/%3$d)" + +#: wp-admin/includes/class-wp-upgrader.php:1229 +msgid "Go to themes page" +msgstr "Ir a la página de temas" + +#: wp-admin/includes/class-wp-upgrader.php:1229 +#: wp-admin/includes/class-wp-upgrader.php:1363 +#: wp-admin/includes/class-wp-upgrader.php:1420 +msgid "Return to Themes page" +msgstr "Volver a la página de temas" + +#: wp-admin/includes/class-wp-upgrader.php:1268 +msgid "Successfully installed the plugin %s %s." +msgstr "El plugin %s %s se ha instalado correctamente." + +#: wp-admin/includes/class-wp-upgrader.php:1280 +msgid "Activate Plugin & Run Importer" +msgstr "Activar plugin y Comenzar Importación" + +#: wp-admin/includes/class-wp-upgrader.php:1285 +#: wp-admin/includes/class-wp-plugins-list-table.php:367 +msgid "Activate this plugin for all sites in this network" +msgstr "Activar este plugin para todos los sitios en esta red" + +#: wp-admin/includes/class-wp-upgrader.php:1285 +#: wp-admin/includes/class-wp-plugins-list-table.php:367 +msgid "Network Activate" +msgstr "Activar para la red" + +#: wp-admin/includes/class-wp-upgrader.php:1290 +msgid "Return to Importers" +msgstr "Volver a los importadores" + +#: wp-admin/includes/class-wp-upgrader.php:1292 +msgid "Return to Plugin Installer" +msgstr "Volver al instalador de plugins" + +#: wp-admin/includes/class-wp-upgrader.php:1337 +msgid "Successfully installed the theme %1$s %2$s." +msgstr "El tema %1$s %2$s se ha instalado correctamente." + +#: wp-admin/includes/class-wp-upgrader.php:1361 +msgid "Return to Theme Installer" +msgstr "Volver al instalador de temas" + +#: wp-admin/includes/class-wp-upgrader.php:1363 +msgid "Themes page" +msgstr "Página de temas" + +#: wp-admin/includes/class-wp-upgrader.php:1391 wp-admin/update.php:158 +msgid "Update Theme" +msgstr "Actualizar tema" + +#: wp-admin/includes/class-wp-upgrader.php:1449 +msgid "Please select a file" +msgstr "Por favor elige un archivo" + +#: wp-admin/includes/class-wp-list-table.php:284 +msgid "Bulk Actions" +msgstr "Acciones en lote" + +#: wp-admin/includes/class-wp-list-table.php:391 +msgid "List View" +msgstr "Ver lista" + +#: wp-admin/includes/class-wp-list-table.php:392 +msgid "Excerpt View" +msgstr "Ver extracto" + +#: wp-admin/includes/class-wp-list-table.php:418 +msgid "%s pending" +msgstr "%s pendientes" + +#: wp-admin/includes/class-wp-list-table.php:492 +msgid "Go to the first page" +msgstr "Ir a la primera página" + +#: wp-admin/includes/class-wp-list-table.php:499 +msgid "Go to the previous page" +msgstr "Ir a la página anterior" + +#: wp-admin/includes/class-wp-list-table.php:508 +msgid "Current page" +msgstr "Página actual" + +#: wp-admin/includes/class-wp-list-table.php:515 +msgctxt "paging" +msgid "%1$s of %2$s" +msgstr "%1$s de %2$s" + +#: wp-admin/includes/class-wp-list-table.php:519 +msgid "Go to the next page" +msgstr "Ir a la página siguiente" + +#: wp-admin/includes/class-wp-list-table.php:526 +msgid "Go to the last page" +msgstr "Ir a la última página" + +#: wp-admin/includes/class-wp-filesystem-ftpsockets.php:38 +#: wp-admin/includes/class-wp-filesystem-ftpext.php:44 +msgid "FTP hostname is required" +msgstr "El nombre del servidor del FTP es necesario" + +#: wp-admin/includes/class-wp-filesystem-ftpsockets.php:47 +#: wp-admin/includes/class-wp-filesystem-ftpext.php:53 +msgid "FTP username is required" +msgstr "El nombre de usuario del FTP es necesario" + +#: wp-admin/includes/class-wp-filesystem-ftpsockets.php:52 +#: wp-admin/includes/class-wp-filesystem-ftpext.php:58 +msgid "FTP password is required" +msgstr "La contraseña del FTP es necesaria" + +#: wp-admin/includes/class-wp-filesystem-ftpsockets.php:64 +#: wp-admin/includes/class-wp-filesystem-ftpsockets.php:69 +#: wp-admin/includes/class-wp-filesystem-ftpext.php:74 +msgid "Failed to connect to FTP Server %1$s:%2$s" +msgstr "Ha sido imposible conectar con el servidor FTP %1$s:%2$s" + +#: wp-admin/includes/theme-install.php:56 +msgid "Search for themes by keyword, author, or tag." +msgstr "Buscar temas por palabra clave, autor o etiqueta." + +#: wp-admin/includes/theme-install.php:63 +msgctxt "Theme Installer" +msgid "Tag" +msgstr "Etiqueta" + +#: wp-admin/includes/theme-install.php:81 +msgid "Find a theme based on specific features" +msgstr "Buscar un tema basándote en determinadas características" + +#: wp-admin/includes/theme-install.php:109 +msgid "Find Themes" +msgstr "Buscar temas" + +#: wp-admin/includes/theme-install.php:117 +msgid "Install a theme in .zip format" +msgstr "Instalar un tema desde un archivo .zip" + +#: wp-admin/includes/theme-install.php:118 +msgid "If you have a theme in a .zip format, you may install it by uploading it here." +msgstr "Si tienes un tema en un archivo .zip, puedes instalarlo subiendo el archivo desde aquí." + +#: wp-admin/includes/theme-install.php:143 +msgid "Install “%s”" +msgstr "Instalar “%s”" + +#: wp-admin/includes/theme-install.php:160 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:192 +msgid "Details" +msgstr "Detalles" + +#: wp-admin/includes/theme-install.php:237 +msgid "Theme Install" +msgstr "Instalar" + +#: wp-admin/includes/theme-install.php:240 +msgid "Error: This theme is currently not available. Please try again later." +msgstr "ERROR: Este tema no está disponible actualmente. Por favor vuelve a intentarlo más tarde." + +#: wp-admin/includes/theme-install.php:246 +msgid "Warning: This theme has not been tested with your current version of WordPress." +msgstr "Atención: Este tema no ha sido probado en esta versión de WordPress." + +#: wp-admin/includes/theme-install.php:248 +msgid "Warning: This theme has not been marked as compatible with your version of WordPress." +msgstr "Atención: Este tema no es compatible con esta versión de WordPress." + +#: wp-admin/includes/theme-install.php:281 +msgid "by %s" +msgstr "por %s" + +#: wp-admin/includes/theme-install.php:282 +msgid "Version: %s" +msgstr "Versión: %s" + +#: wp-admin/includes/theme-install.php:301 +msgid "Newer version (%s) is installed." +msgstr "La última versión (%s) ya está instalada." + +#: wp-admin/includes/theme-install.php:306 +msgid "This version is already installed." +msgstr "Esta versión ya está instalada." + +#: wp-admin/includes/class-wp-plugins-list-table.php:179 +msgid "No plugins found." +msgstr "No se encontraron plugins." + +#: wp-admin/includes/class-wp-plugins-list-table.php:181 +msgid "You do not appear to have any plugins available at this time." +msgstr "No parece que tengas plugins disponibles en este momento." + +#: wp-admin/includes/class-wp-plugins-list-table.php:208 +msgctxt "plugins" +msgid "All (%s)" +msgid_plural "All (%s)" +msgstr[0] "Todo (%s)" +msgstr[1] "Todos (%s)" + +#: wp-admin/includes/class-wp-plugins-list-table.php:211 +msgid "Active (%s)" +msgid_plural "Active (%s)" +msgstr[0] "Activo (%s)" +msgstr[1] "Activos (%s)" + +#: wp-admin/includes/class-wp-plugins-list-table.php:214 +msgid "Recently Active (%s)" +msgid_plural "Recently Active (%s)" +msgstr[0] "Activo recientemente (%s)" +msgstr[1] "Activos recientemente (%s)" + +#: wp-admin/includes/class-wp-plugins-list-table.php:217 +msgid "Inactive (%s)" +msgid_plural "Inactive (%s)" +msgstr[0] "Inactivo (%s)" +msgstr[1] "Inactivos (%s)" + +#: wp-admin/includes/class-wp-plugins-list-table.php:220 +msgid "Network (%s)" +msgid_plural "Network (%s)" +msgstr[0] "Red (%s)" +msgstr[1] "Red (%s)" + +#: wp-admin/includes/class-wp-plugins-list-table.php:223 +msgid "Must-Use (%s)" +msgid_plural "Must-Use (%s)" +msgstr[0] "Debes Usar (%s)" +msgstr[1] "Debes Usar (%s)" + +#: wp-admin/includes/class-wp-plugins-list-table.php:226 +msgid "Drop-ins (%s)" +msgid_plural "Drop-ins (%s)" +msgstr[0] "Infiltrado (%s)" +msgstr[1] "Infiltrados (%s)" + +#: wp-admin/includes/class-wp-plugins-list-table.php:229 +msgid "Update Available (%s)" +msgid_plural "Update Available (%s)" +msgstr[0] "(%s) actualización disponible" +msgstr[1] "(%s) actualizaciones disponibles" + +#: wp-admin/includes/class-wp-plugins-list-table.php:258 +#: wp-admin/includes/class-wp-plugins-list-table.php:373 +#: wp-admin/widgets.php:360 +msgid "Deactivate" +msgstr "Desactivar" + +#: wp-admin/includes/class-wp-plugins-list-table.php:288 +msgid "Clear List" +msgstr "Limpiar lista" + +#: wp-admin/includes/class-wp-plugins-list-table.php:347 +msgid "Inactive:" +msgstr "Inactivo:" + +#: wp-admin/includes/class-wp-plugins-list-table.php:347 +msgid "Requires %s in wp-config.php." +msgstr "Requiere %s en wp-config.php." + +#: wp-admin/includes/class-wp-plugins-list-table.php:364 +#: wp-admin/includes/class-wp-plugins-list-table.php:373 +msgid "Deactivate this plugin" +msgstr "Desactivar este plugin" + +#: wp-admin/includes/class-wp-plugins-list-table.php:364 +msgid "Network Deactivate" +msgstr "Desactivar para la red" + +#: wp-admin/includes/class-wp-plugins-list-table.php:369 +#: wp-admin/includes/class-wp-plugins-list-table.php:378 +msgid "Delete this plugin" +msgstr "Borrar este plugin" + +#: wp-admin/includes/class-wp-plugins-list-table.php:383 +msgid "Open this file in the Plugin Editor" +msgstr "Abrir este archivo en el editor de plugins" + +#: wp-admin/includes/class-wp-plugins-list-table.php:425 +#: wp-admin/includes/update.php:89 wp-admin/includes/update.php:112 +msgid "Version %s" +msgstr "Versión %s" + +#: wp-admin/includes/class-wp-plugins-list-table.php:430 +#: wp-admin/includes/plugin.php:145 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:185 +msgid "By %s" +msgstr "Por %s" + +#: wp-admin/includes/class-wp-plugins-list-table.php:433 +msgid "Visit plugin site" +msgstr "Visitar la web del plugin" + +#: wp-admin/includes/upgrade.php:68 +msgid "Note that password carefully! It is a random password that was generated just for you." +msgstr "¡Anota la contraseña cuidadosamente! Es una contraseña aleatoria que ha sido generada sólo para ti." + +#: wp-admin/includes/upgrade.php:74 +msgid "Your chosen password." +msgstr "Tu contraseña elegida." + +#: wp-admin/includes/upgrade.php:77 +msgid "User already exists. Password inherited." +msgstr "El usuario ya existe. No se ha modificado la contraseña." + +#: wp-admin/includes/upgrade.php:87 +msgid "The password you chose during the install." +msgstr "La contraseña que has elegido durante la instalación." + +#: wp-admin/includes/upgrade.php:111 +msgctxt "Default category slug" +msgid "Uncategorized" +msgstr "Sin categoría" + +#: wp-admin/includes/upgrade.php:131 +msgctxt "Default link category slug" +msgid "Blogroll" +msgstr "Sitios de interés" + +#: wp-admin/includes/upgrade.php:199 wp-admin/includes/schema.php:712 +msgid "Welcome to SITE_NAME. This is your first post. Edit or delete it, then start blogging!" +msgstr "Te damos la bienvenida a SITE_NAME. Este es tu primer artículo. Edítalo o bórralo... ¡y comienza a publicar!" + +#: wp-admin/includes/upgrade.php:204 +msgid "Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!" +msgstr "Bienvenido a WordPress. Esta es tu primera entrada. Edítala o bórrala, ¡y comienza a publicar!." + +#: wp-admin/includes/upgrade.php:213 +msgid "Hello world!" +msgstr "¡Hola mundo!" + +#: wp-admin/includes/upgrade.php:215 +msgctxt "Default post slug" +msgid "hello-world" +msgstr "hola-mundo" + +#: wp-admin/includes/upgrade.php:227 +msgid "Mr WordPress" +msgstr "Sr WordPress" + +#: wp-admin/includes/upgrade.php:229 +msgid "Hi, this is a comment.
    To delete a comment, just log in and view the post's comments. There you will have the option to edit or delete them." +msgstr "Hola, esto es un comentario.
    Para borrar un comentario sólo tienes que entrar y ver los comentarios de la entrada. Entonces tendrás la opción de editar o borrar." + +#: wp-admin/includes/upgrade.php:246 +msgid "" +"This is an example page. It's different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:\n" +"\n" +"

    Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my blog. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.)
    \n" +"\n" +"...or something like this:\n" +"\n" +"
    The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickies to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.
    \n" +"\n" +"As a new WordPress user, you should go to your dashboard to delete this page and create new pages for your content. Have fun!" +msgstr "" +"Esta es una página de ejemplo, Es diferente a una entrada de un blog porque se mantiene estática y, en la mayoría de temas, se mostrará en la barra de navegación. Casi todo el mundo comienza con una página Sobre mí para presentarse a los potenciales visitantes. Puede decir algo así:\n" +"\n" +"
    ¡Hola!: Soy físico durante el día, lector de manga por las noches y este es mi blog. Vivo en Albacete y tengo un gato llamado Alex. Me encantan los mojitos (y mirar a la gente corriendo en los parques)
    \n" +"\n" +"O algo así:\n" +"\n" +"
    La empresa Calcetines XYC se fundó en 1973, y ha estado produciendo calcetines de calidad para sus clientes desde entonces. Se encuentra en Vetusta, tiene unos 2.000 empleados e intenta ayudar en lo que puede para mejorar la vida en Vestusta
    \n" +"\n" +"Deberías ir a tu escritorio, borrar esta página y crear algunas nuevas con tu contenido. ¡A divertirse!" + +#: wp-admin/includes/upgrade.php:264 +msgid "Sample Page" +msgstr "Página de ejemplo" + +#: wp-admin/includes/upgrade.php:266 +msgid "sample-page" +msgstr "pagina-ejemplo" + +#: wp-admin/includes/upgrade.php:322 +msgid "" +"Your new WordPress site has been successfully set up at:\n" +"\n" +"%1$s\n" +"\n" +"You can log in to the administrator account with the following information:\n" +"\n" +"Username: %2$s\n" +"Password: %3$s\n" +"\n" +"We hope you enjoy your new site. Thanks!\n" +"\n" +"--The WordPress Team\n" +"http://wordpress.org/\n" +msgstr "" +"Se ha configurado correctamente tu nuevo sitio de WordPress en:\n" +"\n" +"%1$s\n" +"\n" +"Puedes identificarte como administrador con la siguiente información:\n" +"\n" +"Nombre de usuario: %2$s\n" +"Contraseña: %3$s\n" +"\n" +"Esperamos que disfrutes de tu nuevo sitio. ¡Gracias!\n" +"\n" +"--El equipo de WordPress\n" +"http://es.wordpress.org/\n" + +#: wp-admin/includes/upgrade.php:337 +msgid "New WordPress Site" +msgstr "Nuevo sitio de WordPress" + +#: wp-admin/includes/update-core.php:305 +msgid "The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s." +msgstr "La actualización no se pudo instalar a causa de que WordPress %1$s requiere la versión %2$s o superior de PHP y la versión %3$s o superior de MySQL. Estás usando la versión %4$s de PHP y la versión %5$s de MySQL." + +#: wp-admin/includes/update-core.php:307 +msgid "The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s." +msgstr "La actualización no puede instalarse ya que WordPress %1$s requiere la versión %2$s o superior de PHP. Estás usando la versión %3$s." + +#: wp-admin/includes/update-core.php:309 +msgid "The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s." +msgstr "La actualización no puede instalarse porque WordPress %1$s requiere la versión %2$s o superior de MySQL. Estás usando la versión %3$s." + +#: wp-admin/includes/update-core.php:312 +msgid "Verifying the unpacked files…" +msgstr "Verificando los archivos descomprimidos…" + +#: wp-admin/includes/update-core.php:324 +msgid "The update could not be unpacked" +msgstr "No se ha podido descomprimir la actualización." + +#: wp-admin/includes/update-core.php:352 +msgid "Upgrading database…" +msgstr "Actualizado la base de datos…" + +#: wp-admin/includes/nav-menu.php:73 +msgid "%s (Pending)" +msgstr "%s (Pendiente)" + +#: wp-admin/includes/nav-menu.php:97 +msgid "Move up" +msgstr "Mover arriba" + +#: wp-admin/includes/nav-menu.php:110 +msgid "Move down" +msgstr "Mover abajo" + +#: wp-admin/includes/nav-menu.php:112 wp-admin/includes/nav-menu.php:114 +msgid "Edit Menu Item" +msgstr "Editar elemento del menú" + +#: wp-admin/includes/nav-menu.php:130 +msgid "Navigation Label" +msgstr "Etiqueta de navegación" + +#: wp-includes/js/tinymce/langs/wp-langs.php:231 +msgid "Toggle guidelines/invisible elements" +msgstr "Mostrar/Ocultar guías y otros elementos" + +#: wp-includes/js/tinymce/langs/wp-langs.php:232 +#: wp-includes/js/tinymce/langs/wp-langs.php:259 +msgid "Insert/edit anchor" +msgstr "Insertar/Editar anclaje" + +#: wp-includes/js/tinymce/langs/wp-langs.php:233 +#: wp-includes/js/tinymce/wp-mce-help.php:208 +msgid "Cut" +msgstr "Cortar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:234 +#: wp-includes/js/tinymce/wp-mce-help.php:207 +msgid "Copy" +msgstr "Copiar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:235 +#: wp-includes/js/tinymce/wp-mce-help.php:207 +msgid "Paste" +msgstr "Pegar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:236 +msgid "Image properties" +msgstr "Propiedades de la imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:237 +msgid "New document" +msgstr "Nuevo documento" + +#: wp-includes/js/tinymce/langs/wp-langs.php:238 +#: wp-includes/js/tinymce/langs/wp-langs.php:252 +#: wp-includes/js/tinymce/langs/wp-langs.php:409 +#: wp-includes/js/tinymce/wp-mce-help.php:234 +#: wp-admin/includes/template.php:1794 +msgid "Help" +msgstr "Ayuda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:241 +msgid "Path" +msgstr "Ruta" + +#: wp-includes/js/tinymce/langs/wp-langs.php:242 +msgid "Are you sure you want to clear all contents?" +msgstr "¿Seguro que quieres borrar todo el contenido?" + +#: wp-includes/js/tinymce/langs/wp-langs.php:243 +msgid "Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X" +msgstr "Ir a la herramienta de los botones - Alt + Q, Ir al editor - Alt-Z, Ir al elemento de la ruta - Alt-X" + +#: wp-includes/js/tinymce/langs/wp-langs.php:245 +msgctxt "colorpicker popup width" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:246 +msgctxt "colorpicker popup height" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:250 +#: wp-includes/js/tinymce/wp-mce-help.php:240 +msgid "About TinyMCE" +msgstr "Acerca de TinyMCE" + +#: wp-includes/js/tinymce/langs/wp-langs.php:251 +#: wp-includes/js/tinymce/wp-mce-help.php:177 +msgid "About" +msgstr "Acerca de" + +#: wp-includes/js/tinymce/langs/wp-langs.php:253 +msgid "License" +msgstr "Licencia" + +#: wp-includes/js/tinymce/langs/wp-langs.php:254 wp-admin/update-core.php:183 +#: wp-admin/update-core.php:195 wp-admin/includes/dashboard.php:65 +#: wp-admin/plugins.php:340 wp-admin/menu.php:179 +msgid "Plugins" +msgstr "Plugins" + +#: wp-includes/js/tinymce/langs/wp-langs.php:255 +#: wp-admin/includes/class-wp-plugins-list-table.php:189 +msgid "Plugin" +msgstr "Plugin" + +#: wp-includes/js/tinymce/langs/wp-langs.php:257 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:142 +msgid "Version" +msgstr "Versión" + +#: wp-includes/js/tinymce/langs/wp-langs.php:258 +msgid "Loaded plugins" +msgstr "Plugins cargados" + +#: wp-includes/js/tinymce/langs/wp-langs.php:260 +msgid "Anchor name" +msgstr "Nombre del ancla" + +#: wp-includes/js/tinymce/langs/wp-langs.php:261 +msgid "HTML Source Editor" +msgstr "Editor HTML" + +#: wp-includes/js/tinymce/langs/wp-langs.php:262 +msgid "Word wrap" +msgstr "Ajuste de palabras" + +#: wp-includes/js/tinymce/langs/wp-langs.php:263 +msgid "Select a color" +msgstr "Elige un color" + +#: wp-includes/js/tinymce/langs/wp-langs.php:264 +msgid "Picker" +msgstr "Selector" + +#: wp-includes/js/tinymce/langs/wp-langs.php:265 +msgid "Color picker" +msgstr "Selector de color" + +#: wp-includes/js/tinymce/langs/wp-langs.php:266 +msgid "Palette" +msgstr "Paleta" + +#: wp-includes/js/tinymce/langs/wp-langs.php:267 +msgid "Palette colors" +msgstr "Paleta de colores" + +#: wp-includes/js/tinymce/langs/wp-langs.php:268 +msgid "Named" +msgstr "Nombrado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:269 +msgid "Named colors" +msgstr "Nombre de los colores" + +#: wp-includes/js/tinymce/langs/wp-langs.php:270 +msgid "Color:" +msgstr "Color:" + +#: wp-includes/js/tinymce/langs/wp-langs.php:271 +#: wp-admin/edit-form-comment.php:91 +msgid "Name:" +msgstr "Nombre:" + +#: wp-includes/js/tinymce/langs/wp-langs.php:272 +msgid "Select custom character" +msgstr "Elegir un carácter especial" + +#: wp-includes/js/tinymce/langs/wp-langs.php:274 +#: wp-admin/includes/media.php:2083 +msgid "Image URL" +msgstr "URL de la imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:275 +msgid "Image description" +msgstr "Descripción de la imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:276 +msgid "Image list" +msgstr "Lista de imágenes" + +#: wp-includes/js/tinymce/langs/wp-langs.php:277 +msgid "Border" +msgstr "Borde" + +#: wp-includes/js/tinymce/langs/wp-langs.php:278 +#: wp-includes/js/tinymce/langs/wp-langs.php:307 +msgid "Dimensions" +msgstr "Dimensiones" + +#: wp-includes/js/tinymce/langs/wp-langs.php:279 +msgid "Vertical space" +msgstr "Espacio vertical" + +#: wp-includes/js/tinymce/langs/wp-langs.php:280 +msgid "Horizontal space" +msgstr "Espacio horizontal" + +#: wp-includes/js/tinymce/langs/wp-langs.php:282 +msgid "Baseline" +msgstr "Linea base" + +#: wp-includes/js/tinymce/langs/wp-langs.php:283 +#: wp-includes/js/tinymce/langs/wp-langs.php:382 +msgid "Top" +msgstr "Arriba" + +#: wp-includes/js/tinymce/langs/wp-langs.php:284 +msgid "Middle" +msgstr "Intermedio" + +#: wp-includes/js/tinymce/langs/wp-langs.php:285 +#: wp-includes/js/tinymce/langs/wp-langs.php:384 +msgid "Bottom" +msgstr "Abajo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:286 +msgid "Text top" +msgstr "Texto superior" + +#: wp-includes/js/tinymce/langs/wp-langs.php:287 +msgid "Text bottom" +msgstr "Texto inferior" + +#: wp-includes/js/tinymce/langs/wp-langs.php:291 +#: wp-admin/includes/media.php:1081 +msgid "Link URL" +msgstr "URL del enlace" + +#: wp-includes/js/tinymce/langs/wp-langs.php:292 +#: wp-includes/js/tinymce/langs/wp-langs.php:341 wp-admin/edit-link-form.php:29 +#: wp-admin/includes/meta-boxes.php:700 +msgid "Target" +msgstr "Destino" + +#: wp-includes/js/tinymce/langs/wp-langs.php:293 +msgid "Open link in the same window" +msgstr "Abrir el enlace en la misma ventana" + +#: wp-includes/js/tinymce/langs/wp-langs.php:294 +msgid "Open link in a new window" +msgstr "Abrir el enlace en una nueva ventana" + +#: wp-includes/js/tinymce/langs/wp-langs.php:296 +msgid "The URL you entered seems to be an email address, do you want to add the required mailto: prefix?" +msgstr "La URL que has introducido parece ser un correo electrónico, ¿quieres añadir el prefijo mailto:?" + +#: wp-includes/js/tinymce/langs/wp-langs.php:297 +msgid "The URL you entered seems to external link, do you want to add the required http:// prefix?" +msgstr "La URL especificada parece ser un enlace externo, ¿quieres añadir el prefijo http://?" + +#: wp-includes/js/tinymce/langs/wp-langs.php:298 +msgid "Link list" +msgstr "Lista de enlaces" + +#: wp-includes/js/tinymce/langs/wp-langs.php:303 +msgid "General" +msgstr "Generales" + +#: wp-includes/js/tinymce/langs/wp-langs.php:304 +#: wp-includes/js/tinymce/wp-mce-help.php:175 wp-admin/edit-link-form.php:31 +msgid "Advanced" +msgstr "Avanzado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:305 +msgid "File/URL" +msgstr "Archivo/URL" + +#: wp-includes/js/tinymce/langs/wp-langs.php:306 +#: wp-includes/js/tinymce/wp-mce-help.php:230 +#: wp-includes/js/tinymce/wp-mce-help.php:231 +msgid "List" +msgstr "Lista" + +#: wp-includes/js/tinymce/langs/wp-langs.php:309 +msgid "Constrain proportions" +msgstr "Mantener proporciones" + +#: wp-includes/js/tinymce/langs/wp-langs.php:310 +msgid "Type" +msgstr "Tipo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:311 +msgid "Id" +msgstr "Id" + +#: wp-includes/js/tinymce/langs/wp-langs.php:314 +msgid "V-Space" +msgstr "Espacio vertical" + +#: wp-includes/js/tinymce/langs/wp-langs.php:315 +msgid "H-Space" +msgstr "Espacio horizontal" + +#: wp-includes/js/tinymce/langs/wp-langs.php:316 +msgid "Auto play" +msgstr "Reproducción automática" + +#: wp-includes/js/tinymce/langs/wp-langs.php:317 +#: wp-includes/js/tinymce/langs/wp-langs.php:399 +msgid "Loop" +msgstr "Repetir" + +#: wp-includes/js/tinymce/langs/wp-langs.php:318 +msgid "Show menu" +msgstr "Mostrar menú" + +#: wp-includes/js/tinymce/langs/wp-langs.php:319 +msgid "Quality" +msgstr "Calidad" + +#: wp-includes/js/tinymce/langs/wp-langs.php:320 +#: wp-admin/includes/image-edit.php:89 +msgid "Scale" +msgstr "Escala" + +#: wp-includes/js/tinymce/langs/wp-langs.php:321 +msgid "Align" +msgstr "Alineación" + +#: wp-includes/js/tinymce/langs/wp-langs.php:322 +msgid "SAlign" +msgstr "SAlign" + +#: wp-includes/js/tinymce/langs/wp-langs.php:323 +msgid "WMode" +msgstr "Modo de ventana" + +#: wp-includes/js/tinymce/langs/wp-langs.php:324 +#: wp-admin/custom-background.php:67 +msgid "Background" +msgstr "Fondo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:325 +msgid "Base" +msgstr "Base" + +#: wp-includes/js/tinymce/langs/wp-langs.php:326 +msgid "Flashvars" +msgstr "Flashvars" + +#: wp-includes/js/tinymce/langs/wp-langs.php:327 +msgid "SWLiveConnect" +msgstr "SWLiveConnect" + +#: wp-includes/js/tinymce/langs/wp-langs.php:328 +msgid "AutoHREF" +msgstr "AutoHREF" + +#: wp-includes/js/tinymce/langs/wp-langs.php:329 +msgid "Cache" +msgstr "Caché" + +#: wp-includes/js/tinymce/langs/wp-langs.php:330 +msgid "Hidden" +msgstr "Oculto" + +#: wp-includes/js/tinymce/langs/wp-langs.php:331 +msgid "Controller" +msgstr "Controlador" + +#: wp-includes/js/tinymce/langs/wp-langs.php:332 +msgid "Kiosk mode" +msgstr "Modo quiosco" + +#: wp-includes/js/tinymce/langs/wp-langs.php:333 +msgid "Play every frame" +msgstr "Reproducir todos los cuadros" + +#: wp-includes/js/tinymce/langs/wp-langs.php:334 +msgid "Target cache" +msgstr "Caché destino" + +#: wp-includes/js/tinymce/langs/wp-langs.php:335 +msgid "No correction" +msgstr "Sin corrección" + +#: wp-includes/js/tinymce/langs/wp-langs.php:336 +msgid "Enable JavaScript" +msgstr "Activar JavaScript" + +#: wp-includes/js/tinymce/langs/wp-langs.php:337 +#: wp-includes/js/tinymce/langs/wp-langs.php:395 +msgid "Start time" +msgstr "Hora de inicio" + +#: wp-includes/js/tinymce/langs/wp-langs.php:338 +msgid "End time" +msgstr "Hora de finalización" + +#: wp-includes/js/tinymce/langs/wp-langs.php:339 +msgid "href" +msgstr "href" + +#: wp-includes/js/tinymce/langs/wp-langs.php:340 +msgid "Choke speed" +msgstr "Velocidad de obstrucción" + +#: wp-includes/js/tinymce/langs/wp-langs.php:342 +msgid "Volume" +msgstr "Volumen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:343 +#: wp-includes/js/tinymce/langs/wp-langs.php:398 +msgid "Auto start" +msgstr "Inicio automático" + +#: wp-includes/js/tinymce/langs/wp-langs.php:344 +msgid "Enabled" +msgstr "Activado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:345 +msgid "Fullscreen" +msgstr "Pantalla completa" + +#: wp-includes/js/tinymce/langs/wp-langs.php:346 +msgid "Invoke URLs" +msgstr "Invocar URLs" + +#: wp-includes/js/tinymce/langs/wp-langs.php:347 +msgid "Mute" +msgstr "Silenciar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:348 +msgid "Stretch to fit" +msgstr "Estrechar para ajustar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:349 +msgid "Windowless video" +msgstr "Vídeo sin ventana" + +#: wp-includes/js/tinymce/langs/wp-langs.php:350 +msgid "Balance" +msgstr "Balance" + +#: wp-includes/js/tinymce/langs/wp-langs.php:351 +msgid "Base URL" +msgstr "URL base" + +#: wp-includes/js/tinymce/langs/wp-langs.php:352 +msgid "Captioning id" +msgstr "ID de captura" + +#: wp-includes/js/tinymce/langs/wp-langs.php:353 +msgid "Current marker" +msgstr "Marcador actual" + +#: wp-includes/js/tinymce/langs/wp-langs.php:354 +msgid "Current position" +msgstr "Posición actual" + +#: wp-includes/js/tinymce/langs/wp-langs.php:355 +msgid "Default frame" +msgstr "Marco por defecto" + +#: wp-includes/js/tinymce/langs/wp-langs.php:356 +msgid "Play count" +msgstr "Contador de reproducción" + +#: wp-includes/js/tinymce/langs/wp-langs.php:357 +msgid "Rate" +msgstr "Puntuar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:358 +msgid "UI Mode" +msgstr "Modo UI" + +#: wp-includes/js/tinymce/langs/wp-langs.php:359 +msgid "Flash options" +msgstr "Opciones del Flash" + +#: wp-includes/js/tinymce/langs/wp-langs.php:360 +msgid "Quicktime options" +msgstr "Opciones de Quicktime" + +#: wp-includes/js/tinymce/langs/wp-langs.php:361 +msgid "Windows media player options" +msgstr "Opciones de Windows Media Player" + +#: wp-includes/js/tinymce/langs/wp-langs.php:362 +msgid "Real media player options" +msgstr "Opciones de Real Media Player" + +#: wp-includes/js/tinymce/langs/wp-langs.php:363 +msgid "Shockwave options" +msgstr "Opciones de Shockwave" + +#: wp-includes/js/tinymce/langs/wp-langs.php:364 +msgid "Auto goto URL" +msgstr "Ir automáticamente a la URL" + +#: wp-includes/js/tinymce/langs/wp-langs.php:366 +msgid "Image status" +msgstr "Estado de la Imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:367 +msgid "Maintain aspect" +msgstr "Mantener aspecto" + +#: wp-includes/js/tinymce/langs/wp-langs.php:368 +msgid "No java" +msgstr "Sin java" + +#: wp-includes/js/tinymce/langs/wp-langs.php:369 +msgid "Prefetch" +msgstr "Prelectura" + +#: wp-includes/js/tinymce/langs/wp-langs.php:370 +msgid "Shuffle" +msgstr "Aleatorio" + +#: wp-includes/js/tinymce/langs/wp-langs.php:371 +msgid "Console" +msgstr "Consola" + +#: wp-includes/js/tinymce/langs/wp-langs.php:372 +msgid "Num loops" +msgstr "Bucles numéricos" + +#: wp-includes/js/tinymce/langs/wp-langs.php:373 +msgid "Controls" +msgstr "Controles" + +#: wp-includes/js/tinymce/langs/wp-langs.php:374 +msgid "Script callbacks" +msgstr "Llamadas de Script" + +#: wp-includes/js/tinymce/langs/wp-langs.php:375 +msgid "Stretch style" +msgstr "Estilo estirado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:376 +msgid "Stretch H-Align" +msgstr "Estirar alineación horizontal" + +#: wp-includes/js/tinymce/langs/wp-langs.php:377 +msgid "Stretch V-Align" +msgstr "Estirar alineación vertical" + +#: wp-includes/js/tinymce/langs/wp-langs.php:378 +msgid "Sound" +msgstr "Sonido" + +#: wp-includes/js/tinymce/langs/wp-langs.php:379 +msgid "Progress" +msgstr "Progreso" + +#: wp-includes/js/tinymce/langs/wp-langs.php:380 +msgid "QT Src" +msgstr "Origen de QT" + +#: wp-includes/js/tinymce/langs/wp-langs.php:381 +msgid "Streamed rtsp resources should be added to the QT Src field under the advanced tab." +msgstr "Los recursos Rtsp deben añadirse en el campo Origen de QT en la pestaña de Ajustes avanzados." + +#: wp-includes/js/tinymce/langs/wp-langs.php:387 +msgid "Top left" +msgstr "Arriba izq." + +#: wp-includes/js/tinymce/langs/wp-langs.php:388 +msgid "Top right" +msgstr "Arriba dcha." + +#: wp-includes/js/tinymce/langs/wp-langs.php:389 +msgid "Bottom left" +msgstr "Abajo izq." + +#: wp-includes/js/tinymce/langs/wp-langs.php:390 +msgid "Bottom right" +msgstr "Abajo dcha." + +#: wp-includes/js/tinymce/langs/wp-langs.php:391 +msgid "Flash video options" +msgstr "Opciones del video Flash" + +#: wp-includes/js/tinymce/langs/wp-langs.php:392 +msgid "Scale mode" +msgstr "Modo de escala" + +#: wp-includes/js/tinymce/langs/wp-langs.php:393 +msgid "Buffer" +msgstr "Buffer" + +#: wp-includes/js/tinymce/langs/wp-langs.php:394 +msgid "Start image" +msgstr "Imagen de inicio" + +#: wp-includes/js/tinymce/langs/wp-langs.php:396 +msgid "Default volume" +msgstr "Volumen predeterminado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:397 +msgid "Hidden GUI" +msgstr "Ocultar GUI" + +#: wp-includes/js/tinymce/langs/wp-langs.php:400 +msgid "Show scale modes" +msgstr "Mostrar modos de escala" + +#: wp-includes/js/tinymce/langs/wp-langs.php:401 +msgid "Smooth video" +msgstr "Suavizar vídeo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:402 +msgid "JS Callback" +msgstr "Llamada JS" + +#: wp-includes/js/tinymce/langs/wp-langs.php:406 +msgid "Show/Hide Kitchen Sink" +msgstr "Ver/Ocultar botones adicionales" + +#: wp-includes/js/tinymce/langs/wp-langs.php:407 +#: wp-includes/js/tinymce/wp-mce-help.php:233 +msgid "Insert More Tag" +msgstr "Insertar etiqueta Más" + +#: wp-includes/js/tinymce/langs/wp-langs.php:408 +msgid "Insert Page break" +msgstr "Insertar salto de página" + +#: wp-includes/js/tinymce/langs/wp-langs.php:410 +msgid "More..." +msgstr "Más..." + +#: wp-includes/js/tinymce/langs/wp-langs.php:411 +msgid "Next page..." +msgstr "Siguiente página..." + +#: wp-includes/js/tinymce/langs/wp-langs.php:412 +#: wp-admin/includes/media.php:379 +msgid "Add Media" +msgstr "Añadir objeto" + +#: wp-includes/js/tinymce/langs/wp-langs.php:413 +#: wp-admin/includes/media.php:373 +msgid "Add an Image" +msgstr "Añadir una imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:414 +#: wp-admin/includes/media.php:375 +msgid "Add Video" +msgstr "Añadir un vídeo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:415 +#: wp-admin/includes/media.php:377 +msgid "Add Audio" +msgstr "Añadir un archivo de audio" + +#: wp-includes/js/tinymce/langs/wp-langs.php:416 +msgid "Edit Gallery" +msgstr "Editar galería" + +#: wp-includes/js/tinymce/langs/wp-langs.php:417 +msgid "Delete Gallery" +msgstr "Eliminar galería" + +#: wp-includes/js/tinymce/langs/wp-langs.php:421 +#: wp-admin/includes/media.php:1248 +msgid "Edit Image" +msgstr "Editar imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:422 +msgid "Delete Image" +msgstr "Eliminar imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:423 +msgid "Advanced Settings" +msgstr "Ajustes avanzados" + +#: wp-includes/js/tinymce/langs/wp-langs.php:425 +#: wp-admin/includes/media.php:891 +msgid "Size" +msgstr "Tamaño" + +#: wp-includes/js/tinymce/langs/wp-langs.php:426 +#: wp-admin/includes/image-edit.php:181 wp-admin/includes/media.php:854 +msgid "Thumbnail" +msgstr "Miniatura" + +#: wp-includes/js/tinymce/langs/wp-langs.php:427 +#: wp-admin/includes/media.php:854 +msgid "Medium" +msgstr "Medio" + +#: wp-includes/js/tinymce/langs/wp-langs.php:428 +#: wp-admin/includes/media.php:854 +msgid "Full Size" +msgstr "Tamaño completo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:429 +msgid "Current Link" +msgstr "Enlace actual" + +#: wp-includes/js/tinymce/langs/wp-langs.php:430 +msgid "Link to Image" +msgstr "Enlazar a imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:431 +#: wp-admin/includes/media.php:1084 wp-admin/includes/media.php:2127 +msgid "Enter a link URL or click above for presets." +msgstr "Introduce una URL para el enlace o clic sobre el actual." + +#: wp-includes/js/tinymce/langs/wp-langs.php:432 +msgid "Advanced Image Settings" +msgstr "Ajustes avanzados de imágenes" + +#: wp-includes/js/tinymce/langs/wp-langs.php:433 +msgid "Source" +msgstr "Fuente" + +#: wp-includes/js/tinymce/langs/wp-langs.php:434 wp-admin/options-media.php:46 +#: wp-admin/options-media.php:92 wp-admin/includes/theme.php:293 +#: wp-admin/includes/theme.php:339 +msgid "Width" +msgstr "Ancho" + +#: wp-includes/js/tinymce/langs/wp-langs.php:435 +#: wp-includes/js/tinymce/langs/wp-langs.php:440 wp-admin/options-media.php:48 +#: wp-admin/options-media.php:94 +msgid "Height" +msgstr "Altura" + +#: wp-includes/js/tinymce/langs/wp-langs.php:436 +#: wp-includes/js/tinymce/langs/wp-langs.php:441 +msgid "Original Size" +msgstr "Tamaño original" + +#: wp-includes/js/tinymce/langs/wp-langs.php:437 +#: wp-includes/js/tinymce/langs/wp-langs.php:442 +msgid "CSS Class" +msgstr "Clase CSS" + +#: wp-includes/js/tinymce/langs/wp-langs.php:438 +msgid "Advanced Link Settings" +msgstr "Ajustes avanzados de enlaces" + +#: wp-includes/js/tinymce/langs/wp-langs.php:439 +msgid "Link Rel" +msgstr "Relación del enlace" + +#: wp-includes/js/tinymce/langs/wp-langs.php:443 +msgid "60%" +msgstr "60%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:444 +msgid "70%" +msgstr "70%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:445 +msgid "80%" +msgstr "80%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:446 +msgid "90%" +msgstr "90%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:447 +msgid "100%" +msgstr "100%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:448 +msgid "110%" +msgstr "110%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:449 +msgid "120%" +msgstr "120%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:450 +msgid "130%" +msgstr "130%" + +#: wp-includes/js/tinymce/langs/wp-langs.php:452 +#: wp-admin/includes/media.php:1072 +msgid "Caption" +msgstr "Leyenda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:453 +#: wp-admin/includes/media.php:947 wp-admin/includes/media.php:2099 +msgid "Alternate Text" +msgstr "Texto alternativo" + +#: wp-includes/js/tinymce/wp-mce-help.php:16 +msgid "Rich Editor Help" +msgstr "Ayuda del editor visual" + +#: wp-includes/js/tinymce/wp-mce-help.php:174 +msgid "Basics of Rich Editing" +msgstr "Uso básico del editor visual" + +#: wp-includes/js/tinymce/wp-mce-help.php:174 +msgid "Basics" +msgstr "Básico" + +#: wp-includes/js/tinymce/wp-mce-help.php:175 +msgid "Advanced use of the Rich Editor" +msgstr "Uso avanzado del Editor visual" + +#: wp-includes/js/tinymce/wp-mce-help.php:176 +msgid "Hotkeys" +msgstr "Atajos de teclado" + +#: wp-includes/js/tinymce/wp-mce-help.php:177 +msgid "About the software" +msgstr "Acerca del programa" + +#: wp-includes/js/tinymce/wp-mce-help.php:183 +msgid "Rich Editing Basics" +msgstr "Edición visual básica" + +#: wp-includes/js/tinymce/wp-mce-help.php:184 +msgid "Rich editing, also called WYSIWYG for What You See Is What You Get, means your text is formatted as you type. The rich editor creates HTML code behind the scenes while you concentrate on writing. Font styles, links and images all appear approximately as they will on the internet." +msgstr "La edición visual, también llamada WYSIWYG por What You See Is What You Get (en inglés, Lo Que Ves Es Lo Que Obtendrás), consiste en dar formato al texto a medida que lo escribes. El editor visual va creando el código HTML tras las bambalinas mientras tú te centras en escribir. Tipos de letra, enlaces e imágenes se ven tal y como aparecerán en Internet." + +#: wp-includes/js/tinymce/wp-mce-help.php:185 +msgid "WordPress includes a rich HTML editor that works well in all major web browsers used today. However editing HTML is not the same as typing text. Each web page has two major components: the structure, which is the actual HTML code and is produced by the editor as you type, and the display, that is applied to it by the currently selected WordPress theme and is defined in style.css. WordPress is producing valid XHTML 1.0 which means that inserting multiple line breaks (BR tags) after a paragraph would not produce white space on the web page. The BR tags will be removed as invalid by the internal HTML correcting functions." +msgstr "WordPress incluye un editor HTML que suele funcionar bien en los principales navegadores utilizados en la actualidad. Sin embargo, la edición de HTML no es tan fiable como escribir texto. Cada página Web tiene dos componentes principales: la estructura, que es el actual código HTML y es producido por el editor a partir de los que estás escribiendo, y el diseño, que se aplica a ella por el tema seleccionado WordPress y se define en el style.css. Además WordPress válida XHTML 1.0, lo que significa que no se puede mostrar el control de los elementos estructurales. Por lo tanto, la inserción de varios saltos de línea (BR etiquetas) después de un párrafo no da lugar a espacios en blanco en la página web final. La etiquetas BR serán eliminadas como incorrectas por las funciones de corrección." + +#: wp-includes/js/tinymce/wp-mce-help.php:186 +msgid "While using the editor, most basic keyboard shortcuts work like in any other text editor. For example: Shift+Enter inserts line break, Ctrl+C = copy, Ctrl+X = cut, Ctrl+Z = undo, Ctrl+Y = redo, Ctrl+A = select all, etc. (on Mac use the Command key instead of Ctrl). See the Hotkeys tab for all available keyboard shortcuts." +msgstr "Si sueles usar el editor, la mayoría de las combinaciones de teclas básicas funcionan como en cualquier otro editor de texto. Por ejemplo: Shift + Enter inserta un salto de línea, Ctrl + C = copiar, Ctrl + X = cortar, Ctrl + Z = deshacer, Ctrl + Y = rehacer, Ctrl + A = seleccionar todo, etc (en Mac usar la tecla Comando en lugar de Ctrl). Puedes ver la lista de teclas rápidas para todos los atajos de teclado." + +#: wp-includes/js/tinymce/wp-mce-help.php:187 +msgid "If you do not like the way the rich editor works, you may turn it off from Your Profile submenu, under Users in the admin menu." +msgstr "Si no te gusta la forma en que trabaja el editor visual, podrás desactivarlo desde el submenu de tu perfil, en el menú usuario en la administración." + +#: wp-includes/js/tinymce/wp-mce-help.php:191 +msgid "Advanced Rich Editing" +msgstr "Edición visual avanzada" + +#: wp-includes/js/tinymce/wp-mce-help.php:192 +msgid "Images and Attachments" +msgstr "Imágenes y archivos" + +#: wp-includes/js/tinymce/wp-mce-help.php:193 +msgid "There is a button in the editor toolbar for inserting images that are already hosted somewhere on the internet. If you have a URL for an image, click this button and enter the URL in the box which appears." +msgstr "En la barra de herramientas del editor hay un botón para insertar imágenes hospedadas en cualquier sitio de Internet. Si tienes el URL de una imagen, haz clic en ese botón y escríbelo en la ventana que aparecerá." + +#: wp-includes/js/tinymce/wp-mce-help.php:194 +msgid "If you need to upload an image or another media file from your computer, you can use the Media Library buttons above the editor. The media library will attempt to create a thumbnail-sized copy from each uploaded image. To insert your image into the post, first click on the thumbnail to reveal a menu of options. When you have selected the options you like, click \"Send to Editor\" and your image or file will appear in the post you are editing. If you are inserting a movie, there are additional options in the \"Media\" dialog that can be opened from the second toolbar row." +msgstr "Si necesitas subir una imagen o cualquier archivo multimedia de tu ordenador, puedes utilizar los botones de la Librería Multimedia sobre el editor. Esta herramienta tratará de crear una miniatura de la imagen cuando la subas. Para insertar la imagen en la entrada, primero haz clic en la miniatura y aparecerá un menú de opciones. Para insertar la imagen en el editor, primero haz clic en la miniatura y se mostrará un menú de opciones. Selecciona \"Enviar al editor\" y tu imagen o archivo aparecerá en la entrada que estás editando. Si estás insertando un video, aparecen opciones adicionales en el menú a las que se puede acceder desde la segunda fila de botones de la barra de tareas." + +#: wp-includes/js/tinymce/wp-mce-help.php:195 +msgid "HTML in the Rich Editor" +msgstr "HTML en el editor visual" + +#: wp-includes/js/tinymce/wp-mce-help.php:196 +msgid "Any HTML entered directly into the rich editor will show up as text when the post is viewed. What you see is what you get. When you want to include HTML elements that cannot be generated with the toolbar buttons, you must enter it by hand in the HTML editor. Examples are tables and <code>. To do this, click the HTML tab and edit the code, then switch back to Visual mode. If the code is valid and understood by the editor, you should see it rendered immediately." +msgstr "Cualquier etiqueta HTML que escribas en el editor se mostrará como texto al visualizar la entrada. Lo que ves es lo que obtendrás. Si quieres incluir elementos HTML distintos de los generados por los botones de la barra de herramientas, como tablas o <code>, deberás hacerlo a mano en el editor HTML. Para ello, haz clic en el botón HTML, edita el código y haz clic en Actualizar. Si el código es válido y el editor lo entiende, lo verás procesado inmediatamente." + +#: wp-includes/js/tinymce/wp-mce-help.php:197 +msgid "Pasting in the Rich Editor" +msgstr "Pegando en el editor visual" + +#: wp-includes/js/tinymce/wp-mce-help.php:198 +msgid "When pasting content from another web page the results can be inconsistent and depend on your browser and on the web page you are pasting from. The editor tries to correct any invalid HTML code that was pasted, but for best results try using the HTML tab or one of the paste buttons that are on the second row. Alternatively try pasting paragraph by paragraph. In most browsers to select one paragraph at a time, triple-click on it." +msgstr "Cuando se pegan los contenidos de otra página web los resultados pueden ser incompatibles entre sí y dependen de tu navegador y de la página web desde donde estás pegando. El editor intenta corregir cualquier código HTML no válido que se pega, pero para obtener los mejores resultados, prueba a utilizar la pestaña HTML o pegar con uno de los botones que se encuentran en la segunda fila. Alternativamente intenta pegar párrafo por párrafo. En la mayoría de los navegadores, para seleccionar un párrafo a la vez, haz triple clic sobre él." + +#: wp-includes/js/tinymce/wp-mce-help.php:199 +msgid "Pasting content from another application, like Word or Excel, is best done with the Paste from Word button on the second row, or in HTML mode." +msgstr "Al pegar contenido desde otra aplicación, como Word o Excel, se hace mejor con el botón de la segunda fila Pegar desde Word, o en modo HTML." + +#: wp-includes/js/tinymce/wp-mce-help.php:203 +msgid "Writing at Full Speed" +msgstr "Escribir a toda velocidad" + +#: wp-includes/js/tinymce/wp-mce-help.php:204 +msgid "Rather than reaching for your mouse to click on the toolbar, use these access keys. Windows and Linux use Ctrl + letter. Macintosh uses Command + letter." +msgstr "En lugar de mover el ratón para hacer clic en la barra de herramientas, usa estas teclas de acceso rápido. En Windows y Linux usa Ctrl+letra. En Macintosh usa Comando+letra." + +#: wp-includes/js/tinymce/wp-mce-help.php:206 +#: wp-includes/js/tinymce/wp-mce-help.php:222 +msgid "Letter" +msgstr "Letra" + +#: wp-includes/js/tinymce/wp-mce-help.php:206 +#: wp-includes/js/tinymce/wp-mce-help.php:222 +msgid "Action" +msgstr "Acción" + +#: wp-includes/js/tinymce/wp-mce-help.php:208 +msgid "Select all" +msgstr "Seleccionar todos" + +#: wp-includes/js/tinymce/wp-mce-help.php:220 +msgid "The following shortcuts use different access keys: Alt + Shift + letter." +msgstr "Los siguientes atajos utilizan claves de acceso diferentes: Alt + Shift + letra." + +#: wp-includes/js/tinymce/wp-mce-help.php:227 +msgid "Check Spelling" +msgstr "Comprobar ortografía" + +#: wp-includes/js/tinymce/wp-mce-help.php:228 +msgid "Justify Text" +msgstr "Justificar texto" + +#: wp-includes/js/tinymce/wp-mce-help.php:230 +msgid "Insert link" +msgstr "Insertar enlace" + +#: wp-includes/js/tinymce/wp-mce-help.php:231 +msgid "Remove link" +msgstr "Borrar enlace" + +#: wp-includes/js/tinymce/wp-mce-help.php:232 +msgid "Quote" +msgstr "Cita" + +#: wp-includes/js/tinymce/wp-mce-help.php:232 wp-admin/press-this.php:165 +#: wp-admin/press-this.php:193 +msgid "Insert Image" +msgstr "Insertar imagen" + +#: wp-includes/js/tinymce/wp-mce-help.php:233 +msgid "Full Screen" +msgstr "Pantalla completa" + +#: wp-includes/js/tinymce/wp-mce-help.php:234 +msgid "Insert Page Break tag" +msgstr "Insertar etiqueta de salto de página" + +#: wp-includes/js/tinymce/wp-mce-help.php:235 +msgid "Switch to HTML mode" +msgstr "Cambiar a modo HTML" + +#: wp-includes/js/tinymce/wp-mce-help.php:242 +#: wp-admin/includes/plugin-install.php:308 +#: wp-admin/includes/theme-install.php:162 +msgid "Version:" +msgstr "Versión:" + +#: wp-includes/js/tinymce/wp-mce-help.php:243 +msgid "TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under %sLGPL\tby Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances." +msgstr "TinyMCE es un editor WYSIWYG de HTML para webs basado en Javascript e independiente de plataformas, publicado como Código Abierto bajo la %sLGPL\tpor Moxiecode Systems AB. Tiene la característica de convertir los campos TEXTAREA de HTML y otros elementos HTML en instancias del editor." + +#: wp-includes/js/tinymce/wp-mce-help.php:243 +msgid "GNU Library General Public Licence" +msgstr "Licencia Pública General de Librería GNU (GPL)" + +#: wp-includes/js/tinymce/wp-mce-help.php:244 +msgid "Copyright © 2003-2007, Moxiecode Systems AB, All rights reserved." +msgstr "Copyright © 2003-2007, Moxiecode Systems AB, reservados todos los derechos." + +#: wp-includes/js/tinymce/wp-mce-help.php:245 +msgid "For more information about this software visit the TinyMCE website." +msgstr "Para más información sobre este software, visita el sitio de TinyMCE." + +#: wp-includes/js/tinymce/wp-mce-help.php:248 +msgid "Got Moxie?" +msgstr "¿Tienes Moxie?" + +#: wp-includes/js/tinymce/wp-mce-help.php:249 +msgid "Hosted By Sourceforge" +msgstr "Alojado en Sourceforge" + +#: wp-includes/js/tinymce/wp-mce-help.php:250 +msgid "Also on freshmeat" +msgstr "También en freshmeat" + +#: wp-includes/wp-db.php:1496 +msgid "ERROR: WordPress %1$s requires MySQL %2$s or higher" +msgstr "ERROR: WordPress %1$s necesita MySQL %2$s o superior." + +#: wp-includes/class-wp-xmlrpc-server.php:159 +#: wp-includes/class-wp-xmlrpc-server.php:181 +msgid "XML-RPC services are disabled on this site. An admin user can enable them at %s" +msgstr "El servicio XML-RPC está desactivado en este sitio. Un administrador puede activarlo en %s" + +#: wp-includes/class-wp-xmlrpc-server.php:164 +#: wp-includes/class-wp-xmlrpc-server.php:188 +msgid "Bad login/pass combination." +msgstr "Combinación de usuario/contraseña errónea." + +#: wp-includes/class-wp-xmlrpc-server.php:294 +msgid "Software Name" +msgstr "Nombre de la aplicación" + +#: wp-includes/class-wp-xmlrpc-server.php:299 +msgid "Software Version" +msgstr "Versión de la aplicación" + +#: wp-includes/class-wp-xmlrpc-server.php:304 +msgid "Site URL" +msgstr "URL del sitio" + +#: wp-includes/class-wp-xmlrpc-server.php:311 +msgid "Time Zone" +msgstr "Zona horaria" + +#: wp-includes/class-wp-xmlrpc-server.php:316 wp-admin/options-general.php:85 +#: wp-admin/install.php:97 +msgid "Site Title" +msgstr "Título del sitio" + +#: wp-includes/class-wp-xmlrpc-server.php:321 +msgid "Site Tagline" +msgstr "Descripción corta" + +#: wp-includes/class-wp-xmlrpc-server.php:326 wp-admin/options-general.php:256 +#: wp-admin/options-general.php:258 +msgid "Date Format" +msgstr "Formato de fecha" + +#: wp-includes/class-wp-xmlrpc-server.php:331 wp-admin/options-general.php:289 +#: wp-admin/options-general.php:291 +msgid "Time Format" +msgstr "Formato de hora" + +#: wp-includes/class-wp-xmlrpc-server.php:336 +msgid "Allow new users to sign up" +msgstr "Permitir el registro de nuevos usuarios" + +#: wp-includes/class-wp-xmlrpc-server.php:341 +msgid "Thumbnail Width" +msgstr "Anchura de la miniatura" + +#: wp-includes/class-wp-xmlrpc-server.php:346 +msgid "Thumbnail Height" +msgstr "Altura de la miniatura" + +#: wp-includes/class-wp-xmlrpc-server.php:351 +msgid "Crop thumbnail to exact dimensions" +msgstr "Recortar la miniatura a sus dimensiones exactas" + +#: wp-includes/class-wp-xmlrpc-server.php:356 +msgid "Medium size image width" +msgstr "Achura de la imagen de tamaño medio" + +#: wp-includes/class-wp-xmlrpc-server.php:361 +msgid "Medium size image height" +msgstr "Altura de la imagen de tamaño medio" + +#: wp-includes/class-wp-xmlrpc-server.php:366 +msgid "Large size image width" +msgstr "Tamaño grande de la imagen" + +#: wp-includes/class-wp-xmlrpc-server.php:371 +msgid "Large size image height" +msgstr "Altura de la imagen de tamaño grande" + +#: wp-includes/class-wp-xmlrpc-server.php:454 +msgid "Sorry, you cannot edit this page." +msgstr "Disculpa, no puedes editar esta página." + +#: wp-includes/class-wp-xmlrpc-server.php:530 +#: wp-includes/class-wp-xmlrpc-server.php:636 +#: wp-includes/class-wp-xmlrpc-server.php:675 +msgid "Sorry, no such page." +msgstr "Disculpa, no existe esa página." + +#: wp-includes/class-wp-xmlrpc-server.php:554 +#: wp-includes/class-wp-xmlrpc-server.php:718 +msgid "Sorry, you cannot edit pages." +msgstr "Disculpa, no puedes editar páginas." + +#: wp-includes/class-wp-xmlrpc-server.php:602 +msgid "Sorry, you cannot add new pages." +msgstr "Disculpa, no puedes añadir nuevas páginas." + +#: wp-includes/class-wp-xmlrpc-server.php:640 +msgid "Sorry, you do not have the right to delete this page." +msgstr "Disculpa, no tienes autorización para borrar esta página." + +#: wp-includes/class-wp-xmlrpc-server.php:645 +msgid "Failed to delete the page." +msgstr "No se logró borrar la página." + +#: wp-includes/class-wp-xmlrpc-server.php:679 +msgid "Sorry, you do not have the right to edit this page." +msgstr "Disculpa, no tienes autorización para editar esta página." + +#: wp-includes/class-wp-xmlrpc-server.php:778 +msgid "Sorry, you cannot edit posts on this site." +msgstr "Disculpa, no puedes editar entradas en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:813 +msgid "Sorry, you must be able to edit posts on this site in order to view tags." +msgstr "Disculpa, para ver las etiquetas tienes que estar autorizado para editar entradas en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:858 +msgid "Sorry, you do not have the right to add a category." +msgstr "Disculpa, no tienes autorización para añadir categorías." + +#: wp-includes/class-wp-xmlrpc-server.php:886 +#: wp-includes/class-wp-xmlrpc-server.php:888 +msgid "Sorry, the new category failed." +msgstr "Disculpa, la creación de la nueva categoría falló." + +#: wp-includes/class-wp-xmlrpc-server.php:916 +msgid "Sorry, you do not have the right to delete a category." +msgstr "Disculpa, no tienes autorización para borrar categorías." + +#: wp-includes/class-wp-xmlrpc-server.php:942 +msgid "Sorry, you must be able to edit posts to this site in order to view categories." +msgstr "Disculpa, para ver las categorías tienes que estar autorizado para editar entradas en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:978 +#: wp-includes/class-wp-xmlrpc-server.php:1100 +#: wp-includes/class-wp-xmlrpc-server.php:1103 +#: wp-includes/class-wp-xmlrpc-server.php:1134 +#: wp-includes/class-wp-xmlrpc-server.php:1137 +msgid "You are not allowed to moderate comments on this site." +msgstr "No tienes autorización para moderar comentarios en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:983 +#: wp-includes/class-wp-xmlrpc-server.php:1108 +#: wp-includes/class-wp-xmlrpc-server.php:1142 +msgid "Invalid comment ID." +msgstr "El ID del comentario no es válido." + +#: wp-includes/class-wp-xmlrpc-server.php:1041 +msgid "Sorry, you cannot edit comments." +msgstr "Disculpa, no puedes editar comentarios." + +#: wp-includes/class-wp-xmlrpc-server.php:1149 +msgid "Invalid comment status." +msgstr "El estado del comentario no es válido." + +#: wp-includes/class-wp-xmlrpc-server.php:1180 +msgid "Sorry, the comment could not be edited. Something wrong happened." +msgstr "Disculpa, no se ha podido editar el comentario. Se ha producido un error." + +#: wp-includes/class-wp-xmlrpc-server.php:1211 +msgid "You must be registered to comment" +msgstr "Los usuarios deben registrarse e identificarse para comentar" + +#: wp-includes/class-wp-xmlrpc-server.php:1224 +#: wp-includes/class-wp-xmlrpc-server.php:1227 +#: wp-includes/class-wp-xmlrpc-server.php:2459 +msgid "Invalid post ID." +msgstr "El ID de la entrada no es válido." + +#: wp-includes/class-wp-xmlrpc-server.php:1253 +msgid "Comment author name and email are required" +msgstr "El nombre y correo electrónico del autor del comentario son campos necesarios" + +#: wp-includes/class-wp-xmlrpc-server.php:1255 +msgid "A valid email address is required" +msgstr "Se necesita un correo electrónico válido" + +#: wp-includes/class-wp-xmlrpc-server.php:1287 +#: wp-includes/class-wp-xmlrpc-server.php:1346 +#: wp-includes/class-wp-xmlrpc-server.php:1372 +#: wp-includes/class-wp-xmlrpc-server.php:1398 +msgid "You are not allowed access to details about this site." +msgstr "No tienes autorización para ver los detalles de este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:1314 +msgid "You are not allowed access to details about comments." +msgstr "No tienes autorización para ver los detalles de los comentarios." + +#: wp-includes/class-wp-xmlrpc-server.php:1476 +msgid "You are not allowed to update options." +msgstr "No tienes autorización para actualizar las opciones." + +#: wp-includes/class-wp-xmlrpc-server.php:1525 +msgid "You are not allowed to upload files on this site." +msgstr "No tienes permisos para subir achivos en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:1530 +msgid "Invalid attachment ID." +msgstr "ID de adjunto no válido." + +#: wp-includes/class-wp-xmlrpc-server.php:1589 +msgid "Sorry, you cannot upload files." +msgstr "Perdona, pero no puedes subir archivos." + +#: wp-includes/class-wp-xmlrpc-server.php:1728 +msgid "Sorry, you do not have access to user data on this site." +msgstr "Disculpa, no tienes acceso a los datos de los usuarios de este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:1763 +#: wp-includes/class-wp-xmlrpc-server.php:2683 +#: wp-includes/class-wp-xmlrpc-server.php:3185 +msgid "Sorry, you cannot edit this post." +msgstr "Disculpa, no puedes editar esta entrada." + +#: wp-includes/class-wp-xmlrpc-server.php:1814 +#: wp-includes/class-wp-xmlrpc-server.php:3051 +msgid "Either there are no posts, or something went wrong." +msgstr "Una de dos, o no hay entradas o algo fue mal." + +#: wp-includes/class-wp-xmlrpc-server.php:1869 +msgid "Sorry, this user can not edit the template." +msgstr "Disculpa, este usuario no puede editar la plantilla." + +#: wp-includes/class-wp-xmlrpc-server.php:1909 +msgid "Sorry, this user cannot edit the template." +msgstr "Disculpa, este usuario no puede editar la plantilla." + +#: wp-includes/class-wp-xmlrpc-server.php:1919 +msgid "Either the file is not writable, or something wrong happened. The file has not been updated." +msgstr "Una de dos, o el archivo no tiene permisos de escritura, o ha ocurrido algún error. El archivo no ha sido actualizado." + +#: wp-includes/class-wp-xmlrpc-server.php:1950 +msgid "Sorry, you are not allowed to post on this site." +msgstr "Disculpa, no tienes autorización para publicar en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:1970 +#: wp-includes/class-wp-xmlrpc-server.php:2315 wp-app.php:445 wp-app.php:640 +#: wp-app.php:826 +msgid "Sorry, your entry could not be posted. Something wrong happened." +msgstr "Disculpa, ha sido imposible publicar la entrada. Algo ha ocurrido." + +#: wp-includes/class-wp-xmlrpc-server.php:2005 +#: wp-includes/class-wp-xmlrpc-server.php:2057 +#: wp-includes/class-wp-xmlrpc-server.php:2778 +#: wp-includes/class-wp-xmlrpc-server.php:3247 +msgid "Sorry, no such post." +msgstr "Disculpa, no existe la entrada." + +#: wp-includes/class-wp-xmlrpc-server.php:2010 wp-app.php:506 wp-app.php:672 +#: wp-app.php:745 wp-app.php:795 +msgid "Sorry, you do not have the right to edit this post." +msgstr "Lo sentimos, no tienes autorización para editar esta entrada." + +#: wp-includes/class-wp-xmlrpc-server.php:2015 +#: wp-includes/class-wp-xmlrpc-server.php:2599 +msgid "Sorry, you do not have the right to publish this post." +msgstr "Disculpa, no tienes autorización para publicar esta entrada." + +#: wp-includes/class-wp-xmlrpc-server.php:2026 wp-app.php:529 wp-app.php:688 +msgid "For some strange yet very annoying reason, this post could not be edited." +msgstr "Por alguna extraña razón esta entrada no puede editarse." + +#: wp-includes/class-wp-xmlrpc-server.php:2060 wp-app.php:551 wp-app.php:709 +msgid "Sorry, you do not have the right to delete this post." +msgstr "Lo sentimos, no tienes autorización para borrar esta entrada." + +#: wp-includes/class-wp-xmlrpc-server.php:2065 wp-app.php:559 wp-app.php:724 +msgid "For some strange yet very annoying reason, this post could not be deleted." +msgstr "Por alguna extraña y desagradable razón esta entrada no puede borrarse." + +#: wp-includes/class-wp-xmlrpc-server.php:2105 +#: wp-includes/class-wp-xmlrpc-server.php:2418 +msgid "Sorry, you are not allowed to publish pages on this site." +msgstr "Disculpa, no tienes autorización para publicar páginas en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:2116 +#: wp-includes/class-wp-xmlrpc-server.php:2129 +#: wp-includes/class-wp-xmlrpc-server.php:2409 +#: wp-includes/class-wp-xmlrpc-server.php:2427 +#: wp-includes/class-wp-xmlrpc-server.php:2438 +msgid "Sorry, you are not allowed to publish posts on this site." +msgstr "Disculpa, no tienes autorización para publicar entradas en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:2120 +#: wp-includes/class-wp-xmlrpc-server.php:2176 +#: wp-includes/class-wp-xmlrpc-server.php:2431 +#: wp-includes/class-wp-xmlrpc-server.php:2495 +msgid "Invalid post type." +msgstr "Tipo de entrada no válido." + +#: wp-includes/class-wp-xmlrpc-server.php:2140 +#: wp-includes/class-wp-xmlrpc-server.php:2449 +msgid "Invalid post format" +msgstr "Formato de entrada no válido" + +#: wp-includes/class-wp-xmlrpc-server.php:2169 +msgid "You are not allowed to post as this user" +msgstr "No tienes autorización para publicar entradas con este nombre de usuario." + +#: wp-includes/class-wp-xmlrpc-server.php:2173 +msgid "You are not allowed to create pages as this user" +msgstr "No tienes autorización para crear páginas con este nombre de usuario." + +#: wp-includes/class-wp-xmlrpc-server.php:2488 +msgid "You are not allowed to change the post author as this user." +msgstr "No tienes autorización para cambiar el autor de la entrada identificado con este nombre de usuario." + +#: wp-includes/class-wp-xmlrpc-server.php:2492 +msgid "You are not allowed to change the page author as this user." +msgstr "No tienes autorización para cambiar el autor de la página identificado con este nombre de usuario." + +#: wp-includes/class-wp-xmlrpc-server.php:2597 +msgid "Sorry, you do not have the right to publish this page." +msgstr "Disculpa, no tienes autorización para publicar esta página." + +#: wp-includes/class-wp-xmlrpc-server.php:2634 +msgid "Sorry, your entry could not be edited. Something wrong happened." +msgstr "Disculpa, no se pudo editar tu entrada. Ocurrió algún error." + +#: wp-includes/class-wp-xmlrpc-server.php:2913 +#: wp-includes/class-wp-xmlrpc-server.php:3104 +msgid "Sorry, you must be able to edit posts on this site in order to view categories." +msgstr "Disculpa, para ver las categorías tienes que estar autorizado para editar entradas en este sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:2969 +msgid "You are not allowed to upload files to this site." +msgstr "No tienes autorización para subir archivos al sitio." + +#: wp-includes/class-wp-xmlrpc-server.php:2996 +msgid "Could not write file %1$s (%2$s)" +msgstr "No se pudo escribir el archivo %1$s (%2$s)" + +#: wp-includes/class-wp-xmlrpc-server.php:3142 +msgid "Sorry, you can not edit this post." +msgstr "Disculpa, no puedes editar esta entrada." + +#: wp-includes/class-wp-xmlrpc-server.php:3292 +msgid "Sorry, you cannot publish this post." +msgstr "Perdona, pero no puedes publicar esta entrada." + +#: wp-includes/class-wp-xmlrpc-server.php:3339 +msgid "Is there no link to us?" +msgstr "¿No hay enlace hacia nosotros?" + +#: wp-includes/class-wp-xmlrpc-server.php:3379 +#: wp-includes/class-wp-xmlrpc-server.php:3389 +#: wp-includes/class-wp-xmlrpc-server.php:3396 +#: wp-includes/class-wp-xmlrpc-server.php:3503 +msgid "The specified target URL cannot be used as a target. It either doesn’t exist, or it is not a pingback-enabled resource." +msgstr "La URL especificada no puede utilizarse como destino. O bien no existe o no está habilitado para pingbacks." + +#: wp-includes/class-wp-xmlrpc-server.php:3392 +msgid "The source URL and the target URL cannot both point to the same resource." +msgstr "La URL de origen y la URL de destino no pueden apuntar ambas al mismo recurso." + +#: wp-includes/class-wp-xmlrpc-server.php:3400 +msgid "The pingback has already been registered." +msgstr "El pingback ya ha sido registrado." + +#: wp-includes/class-wp-xmlrpc-server.php:3408 +msgid "The source URL does not exist." +msgstr "La URL de origen no existe." + +#: wp-includes/class-wp-xmlrpc-server.php:3420 +msgid "We cannot find a title on that page." +msgstr "No podemos encontrar un título en esa página." + +#: wp-includes/class-wp-xmlrpc-server.php:3456 +msgid "The source URL does not contain a link to the target URL, and so cannot be used as a source." +msgstr "La URL de origen no contiene un enlace a la URL de destino, así que no puede ser usada como origen." + +#: wp-includes/class-wp-xmlrpc-server.php:3477 +msgid "Pingback from %1$s to %2$s registered. Keep the web talking! :-)" +msgstr "Pingback desde %1$s a %2$s registrado. ¡Haz que la web hable! :-)" + +#: wp-includes/class-wp-xmlrpc-server.php:3510 +msgid "The specified target URL does not exist." +msgstr "La URL de destino especificada no existe." + +#: wp-links-opml.php:29 +msgid "Links for %s" +msgstr "Enlaces para %s" + +#: wp-login.php:87 +msgid "Powered by WordPress" +msgstr "Funciona gracias a WordPress" + +#: wp-login.php:137 wp-login.php:668 +msgid "Are you lost?" +msgstr "¿Te has perdido?" + +#: wp-login.php:137 wp-login.php:668 +msgid "← Back to %s" +msgstr "« Volver a %s" + +#: wp-login.php:172 +msgid "ERROR: Enter a username or e-mail address." +msgstr "ERROR: escribe un nombre de usuario o correo electrónico." + +#: wp-login.php:177 +msgid "ERROR: There is no user registered with that email address." +msgstr "ERROR: no hay ningún usuario registrado con esa dirección de correo electrónico." + +#: wp-login.php:189 +msgid "ERROR: Invalid username or e-mail." +msgstr "ERROR: el nombre de usuario o el correo electrónico no son correctos." + +#: wp-login.php:203 +msgid "Password reset is not allowed for this user" +msgstr "El restablecimiento de contraseña no está permitido para este usuario" + +#: wp-login.php:215 +msgid "Someone requested that the password be reset for the following account:" +msgstr "Alguien ha solicitado que sea restaurada la contraseña de la siguiente cuenta:" + +#: wp-login.php:218 +msgid "If this was a mistake, just ignore this email and nothing will happen." +msgstr "Si ha sido un error, ignora este correo y no pasará nada." + +#: wp-login.php:219 +msgid "To reset your password, visit the following address:" +msgstr "Para restaurar la contraseña, visita la siguiente dirección:" + +#: wp-login.php:229 +msgid "[%s] Password Reset" +msgstr "[%s] Restablecer contraseña" + +#: wp-login.php:235 +msgid "The e-mail could not be sent." +msgstr "No se pudo enviar el correo electrónico" + +#: wp-login.php:235 +msgid "Possible reason: your host may have disabled the mail() function..." +msgstr "Posible razón: el servidor puede tener deshabilitada la función mail()..." + +#: wp-login.php:256 wp-login.php:259 wp-login.php:264 +msgid "Invalid key" +msgstr "Clave no válida." + +#: wp-login.php:299 wp-admin/includes/user.php:135 +msgid "ERROR: Please enter a username." +msgstr "ERROR: Por favor, introduce un nombre de usuario." + +#: wp-login.php:301 wp-admin/includes/user.php:164 +msgid "ERROR: This username is invalid because it uses illegal characters. Please enter a valid username." +msgstr "ERROR: Este nombre de usuario no es válido, ya que usa caracteres no permitidos. Por favor, introduce un nombre de usuario válido." + +#: wp-login.php:304 +msgid "ERROR: This username is already registered, please choose another one." +msgstr "ERROR: Ese usuario ya existe. Por favor, elige otro." + +#: wp-login.php:309 +msgid "ERROR: Please type your e-mail address." +msgstr "ERROR: Por favor, escribe tu correo electrónico." + +#: wp-login.php:311 +msgid "ERROR: The email address isn’t correct." +msgstr "ERROR: La dirección de correo electrónico no es correcta." + +#: wp-login.php:314 wp-admin/includes/user.php:175 +msgid "ERROR: This email is already registered, please choose another one." +msgstr "ERROR: Esa dirección de correo electrónico ya está registrada. Por favor, elige otra." + +#: wp-login.php:327 +msgid "ERROR: Couldn’t register you... please contact the webmaster !" +msgstr "ERROR: No es posible registrarte... por favor, ponte en contacto con el administrador" + +#: wp-login.php:399 +msgid "Sorry, that key does not appear to be valid." +msgstr "Disculpa, la contraseña no es válida." + +#: wp-login.php:403 +msgid "Lost Password" +msgstr "Contraseña perdida" + +#: wp-login.php:403 +msgid "Please enter your username or email address. You will receive a link to create a new password via email." +msgstr "Por favor, escribe tu nombre de usuario o tu correo electrónico. Recibirás un enlace para crear la contraseña nueva por correo electrónico." + +#: wp-login.php:411 +msgid "Username or E-mail:" +msgstr "Nombre de usuario o correo electrónico:" + +#: wp-login.php:416 +msgid "Get New Password" +msgstr "Obtener una contraseña nueva" + +#: wp-login.php:442 +msgid "The passwords do not match." +msgstr "Las contraseñas no coinciden." + +#: wp-login.php:445 +msgid "Password Reset" +msgstr "Contraseña restaurada" + +#: wp-login.php:445 +msgid "Your password has been reset." +msgstr "Tu contraseña ha sido restaurada." + +#: wp-login.php:453 wp-login.php:472 +msgid "Reset Password" +msgstr "Restaurar contraseña" + +#: wp-login.php:453 +msgid "Enter your new password below." +msgstr "Introduce tu nueva contraseña abajo." + +#: wp-login.php:460 +msgid "New password" +msgstr "Nueva contraseña" + +#: wp-login.php:464 +msgid "Confirm new password" +msgstr "Confirma la nueva contraseña" + +#: wp-login.php:469 wp-admin/user-new.php:315 wp-admin/install.php:123 +#: wp-admin/user-edit.php:363 +msgid "Hint: The password should be at least seven characters long. To make it stronger, use upper and lower case letters, numbers and symbols like ! \" ? $ % ^ & )." +msgstr "Tu contraseña debe tener al menos siete caracteres. Para que tu contraseña sea segura, usa mayúsculas, minúsculas, números y símbolos como ! \" ? $ % ^ & )." + +#: wp-login.php:512 +msgid "Registration Form" +msgstr "Formulario de registro" + +#: wp-login.php:512 +msgid "Register For This Site" +msgstr "Registrarte en este sitio" + +#: wp-login.php:525 +msgid "A password will be e-mailed to you." +msgstr "Recibirás una contraseña en este correo electrónico." + +#: wp-login.php:533 wp-login.php:662 wp-login.php:664 +msgid "Password Lost and Found" +msgstr "Recupera tu contraseña perdida" + +#: wp-login.php:533 wp-login.php:662 wp-login.php:664 +msgid "Lost your password?" +msgstr "¿Has perdido tu contraseña?" + +#: wp-login.php:579 +msgid "You have logged in successfully." +msgstr "Te has conectado con éxito." + +#: wp-login.php:608 +msgid "ERROR: Cookies are blocked or not supported by your browser. You must enable cookies to use WordPress." +msgstr "ERROR: Las Cookies están bloqueadas o no las soporta tu navegador. Debes habilitar las cookies para usar WordPress." + +#: wp-login.php:612 +msgid "You are now logged out." +msgstr "Ahora estás desconectado." + +#: wp-login.php:614 +msgid "User registration is currently not allowed." +msgstr "No se permite el registro de nuevos usuarios." + +#: wp-login.php:616 +msgid "Check your e-mail for the confirmation link." +msgstr "Revisa tu correo electrónico para obtener el enlace de confirmación." + +#: wp-login.php:618 +msgid "Check your e-mail for your new password." +msgstr "Revisa tu correo electrónico para obtener la contraseña nueva." + +#: wp-login.php:620 +msgid "Registration complete. Please check your e-mail." +msgstr "Registro completo. Por favor, revisa tu correo electrónico." + +#: wp-login.php:622 +msgid "Your session has expired. Please log-in again." +msgstr "Tu sesión ha expirado. Vuelve a acceder." + +#: wp-admin/revision.php:96 +msgid "Compare Revisions of “%1$s”" +msgstr "Comparar revisiones de “%s”" + +#: wp-admin/revision.php:122 +msgid "Revision for “%1$s” created on %2$s" +msgstr "Revisión para “%1$s” creada el %2$s" + +#: wp-admin/revision.php:162 +msgid "Older: %s" +msgstr "Anteriores: %s" + +#: wp-admin/revision.php:163 +msgid "Newer: %s" +msgstr "Recientes: %s" + +#: wp-admin/revision.php:196 +msgid "These revisions are identical." +msgstr "Estas revisiones son idénticas." + +#: wp-admin/link-manager.php:12 wp-admin/link-manager.php:56 +#: wp-admin/link.php:18 +msgid "You do not have sufficient permissions to edit the links for this site." +msgstr "No tienes suficientes permisos para editar los enlaces en este sitio." + +#: wp-admin/link-manager.php:44 +msgid "You can add links here to be displayed on your site, usually using Widgets. By default, links to several sites in the WordPress community are included as examples." +msgstr "Aquí puedes añadir enlaces a mostrar en tu sitio, generalmente usando Widgets. Por defecto, los enlaces son a varios sitios de la comunidad de WordPress. Son incluidos como ejemplo." + +#: wp-admin/link-manager.php:45 +msgid "Links may be separated into categories; these are different than the categories used on your posts." +msgstr "Los enlaces deben ser separados en categorías. Estas son diferentes de las que utilizas en tus entradas." + +#: wp-admin/link-manager.php:46 +msgid "You can customize the display of this screen using the Screen Options tab and/or the dropdown filters above the links table." +msgstr "Puedes personalizar cómo se muestra esta pantalla usando la pestaña Opciones de pantalla y/o el menú desplegable de filtros encima de la tabla de enlaces." + +#: wp-admin/link-manager.php:47 +msgid "If you delete a link, it will be removed permanently, as Links do not have a Trash function yet." +msgstr "Si eliminas un enlace, será eliminado de forma permanente. Aún no existe una Papelera para los enlaces." + +#: wp-admin/link-manager.php:48 wp-admin/user-new.php:148 wp-admin/index.php:47 +#: wp-admin/edit-link-form.php:46 wp-admin/options-general.php:68 +#: wp-admin/themes.php:45 wp-admin/media.php:75 wp-admin/custom-header.php:95 +#: wp-admin/options-discussion.php:21 wp-admin/plugin-editor.php:121 +#: wp-admin/plugin-install.php:49 wp-admin/options-privacy.php:22 +#: wp-admin/theme-editor.php:31 wp-admin/tools.php:18 +#: wp-admin/edit-form-advanced.php:182 wp-admin/edit-form-advanced.php:192 +#: wp-admin/comment.php:50 wp-admin/edit-comments.php:126 +#: wp-admin/import.php:22 wp-admin/custom-background.php:87 +#: wp-admin/options-media.php:23 wp-admin/edit.php:172 wp-admin/edit.php:181 +#: wp-admin/upload.php:153 wp-admin/export.php:44 wp-admin/theme-install.php:50 +#: wp-admin/users.php:27 wp-admin/options-writing.php:21 +#: wp-admin/update-core.php:405 wp-admin/options-reading.php:49 +#: wp-admin/options-permalink.php:25 wp-admin/user-edit.php:46 +#: wp-admin/widgets.php:44 wp-admin/plugins.php:335 wp-admin/edit-tags.php:209 +#: wp-admin/media-upload.php:68 wp-admin/nav-menus.php:455 +msgid "For more information:" +msgstr "Para más información:" + +#: wp-admin/link-manager.php:49 +msgid "Documentation on Managing Links" +msgstr "Documentación sobre la gestión de Enlaces" + +#: wp-admin/link-manager.php:50 wp-admin/user-new.php:150 wp-admin/index.php:49 +#: wp-admin/edit-link-form.php:48 wp-admin/options-general.php:70 +#: wp-admin/themes.php:47 wp-admin/media.php:77 wp-admin/custom-header.php:97 +#: wp-admin/options-discussion.php:23 wp-admin/plugin-editor.php:124 +#: wp-admin/plugin-install.php:51 wp-admin/options-privacy.php:24 +#: wp-admin/theme-editor.php:36 wp-admin/tools.php:20 +#: wp-admin/edit-form-advanced.php:184 wp-admin/edit-form-advanced.php:195 +#: wp-admin/edit-comments.php:130 wp-admin/import.php:24 +#: wp-admin/custom-background.php:89 wp-admin/options-media.php:25 +#: wp-admin/edit.php:174 wp-admin/edit.php:183 wp-admin/upload.php:155 +#: wp-admin/export.php:46 wp-admin/theme-install.php:52 wp-admin/users.php:30 +#: wp-admin/options-writing.php:23 wp-admin/update-core.php:407 +#: wp-admin/options-reading.php:51 wp-admin/includes/template.php:1783 +#: wp-admin/options-permalink.php:28 wp-admin/user-edit.php:48 +#: wp-admin/widgets.php:46 wp-admin/plugins.php:337 wp-admin/edit-tags.php:218 +#: wp-admin/media-upload.php:70 wp-admin/nav-menus.php:457 +msgid "Support Forums" +msgstr "Foros de soporte (en inglés)" + +#: wp-admin/link-manager.php:62 wp-admin/menu.php:87 +msgctxt "link" +msgid "Add New" +msgstr "Añadir nuevo" + +#: wp-admin/link-manager.php:64 wp-admin/edit-comments.php:149 +#: wp-admin/edit.php:195 wp-admin/upload.php:165 wp-admin/users.php:369 +#: wp-admin/plugins.php:396 wp-admin/edit-tags.php:242 +msgid "Search results for “%s”" +msgstr "Resultados de búsqueda para “%s”" + +#: wp-admin/link-manager.php:71 +msgid "%s link deleted." +msgid_plural "%s links deleted" +msgstr[0] "%s enlace eliminado." +msgstr[1] "%s enlaces eliminados." + +#: wp-admin/link-manager.php:79 +msgid "Search Links" +msgstr "Buscar enlaces" + +#: wp-admin/user-new.php:14 wp-admin/user-new.php:16 wp-admin/user-new.php:59 +#: wp-admin/user-new.php:86 wp-admin/themes.php:13 wp-admin/themes.php:26 +#: wp-admin/edit-comments.php:12 wp-admin/edit.php:24 wp-admin/post-new.php:34 +#: wp-admin/users.php:13 wp-admin/users.php:78 +#: wp-admin/includes/bookmark.php:30 wp-admin/press-this.php:17 +#: wp-admin/widgets.php:16 wp-admin/plugins.php:16 wp-admin/edit-tags.php:13 +#: wp-admin/edit-tags.php:40 wp-admin/edit-tags.php:78 +#: wp-admin/edit-tags.php:92 wp-admin/edit-tags.php:129 +#: wp-admin/nav-menus.php:23 wp-admin/options.php:31 wp-admin/options.php:55 +#: wp-content/plugins/akismet/admin.php:58 +msgid "Cheatin’ uh?" +msgstr "¡Haciendo trampas! ¿eh?" + +#: wp-admin/user-new.php:22 +msgid "" +"Hi,\n" +"You've been invited to join '%1$s' at\n" +"%2$s as a %3$s.\n" +"If you do not want to join this site please ignore\n" +"this email. This invitation will expire in a few days.\n" +"\n" +"Please click the following link to activate your user account:\n" +"%%s" +msgstr "" +"Hola,\n" +"Has sido invitado a unirte a '%1$s' en\n" +"%2$s como %3$s.\n" +"Si no quieres unirte a este sitio, por favor ignora este correo electrónico\n" +"Esta invitación caducará en unos días.\n" +"\n" +"Por favor, haga click en el siguiente enlace para activar su cuenta de usuario:\n" +"%%s" + +#: wp-admin/user-new.php:75 +msgid "" +"Hi,\n" +"\n" +"You have been invited to join '%s' at\n" +"%s as a %s.\n" +"Please click the following link to confirm the invite:\n" +"%s\n" +msgstr "" +"Hola,\n" +"\n" +"Has sido invitado a participar de '%s' en\n" +"%s como %s.\n" +"Por favor, haz clic en el enlace para aceptar la invitación:\n" +"%s\n" + +#: wp-admin/user-new.php:76 +msgid "[%s] Joining confirmation" +msgstr "[%s] Esperando confirmación" + +#: wp-admin/user-new.php:129 wp-admin/user-new.php:265 wp-admin/menu.php:204 +#: wp-admin/menu.php:206 +msgid "Add New User" +msgstr "Añadir nuevo usuario" + +#: wp-admin/user-new.php:137 +msgid "To add a new user to your site, fill in the form on this screen. If you’re not sure which role to assign, you can use the link below to review the different roles and their capabilities. Here is a basic overview of roles:" +msgstr "Para añadir un nuevo usuario a tu sitio, rellena el cuestionario siguiente. Si no estás seguro de qué perfil debes asignarle, puedes utilizar el enlace siguiente para ver las diferentes capacidades de los diferentes perfiles. Aquí tienes una breve explicación de los perfiles:" + +#: wp-admin/user-new.php:139 +msgid "Administrators have access to all the administration features." +msgstr "Los Administradores tienen acceso a todas las funciones de administración." + +#: wp-admin/user-new.php:140 +msgid "Editors can publish posts, manage posts as well as manage other people’s posts, etc." +msgstr "Los Editores pueden publicar entradas, gestionar sus entradas y entradas de otras personas, etc." + +#: wp-admin/user-new.php:141 +msgid "Authors can publish and manage their own posts." +msgstr "Los Autores pueden publicar y gestionar sus entradas." + +#: wp-admin/user-new.php:142 +msgid "Contributors can write and manage their posts but not publish posts or upload media files." +msgstr "Los Colaboradores pueden escribir y gestionar sus entradas, pero no pueden publicar entradas o subir archivos multimedia." + +#: wp-admin/user-new.php:143 +msgid "Subscribers can read comments/comment/receive newsletters, etc." +msgstr "Los Suscriptores pueden leer comentarios/comentar/recibir noticias, etc." + +#: wp-admin/user-new.php:145 +msgid "You must assign a password to the new user, but don’t worry; when they log in for the first time they will be prompted to change it. The username, however, cannot be changed." +msgstr "Debes asignar una contraseña al nuevo usuario, pero no te preocupes, cuando se identifique por primera vez se le preguntará si quiere cambiarla. El nombre de usuario no se puede cambiar." + +#: wp-admin/user-new.php:146 +msgid "New users will receive an email letting them know they’ve been added as a user for your site. By default, this email will also contain their password. Uncheck the box if you don’t want the password to be included in the welcome email." +msgstr "Los usuarios nuevos recibirán un correo electrónico haciéndoles saber que han sido añadidos como usuarios de tu sitio. De forma predeterminada, este correo electrónico también contendrá su contraseña. Desmarca la casilla si no quieres que la contraseña se incluya en el correo electrónico de bienvenida." + +#: wp-admin/user-new.php:147 +msgid "Remember to click the Add User button at the bottom of this screen when you are finished." +msgstr "Acuérdate de hacer clic en el botón Añadir usuario en la parte inferior de la pantalla cuando finalices." + +#: wp-admin/user-new.php:149 +msgid "Documentation on Adding New Users" +msgstr "Documentación sobre cómo añadir nuevos usuarios" + +#: wp-admin/user-new.php:163 +msgid "Invitation email sent to new user. A confirmation link must be clicked before their account is created." +msgstr "La invitación ha sido enviada al nuevo usuario por correo electrónico. Deberá hacer clic en el enlace de confirmación para que su cuenta sea creada." + +#: wp-admin/user-new.php:166 +msgid "Invitation email sent to user. A confirmation link must be clicked for them to be added to your site." +msgstr "Invitación enviada por correo electrónico al usuario. Debe hacer clic en un enlace de confirmación para que se añada a tu sitio." + +#: wp-admin/user-new.php:169 +msgid "User has been added to your site." +msgstr "El usuario ha sido añadido a tu sitio." + +#: wp-admin/user-new.php:172 +msgid "That user is already a member of this site." +msgstr "Este usuario ya es miembro de este sitio." + +#: wp-admin/user-new.php:175 +msgid "The requested user does not exist." +msgstr "El usuario solicitado no existe" + +#: wp-admin/user-new.php:178 +msgid "Please enter a valid email address." +msgstr "Por favor, escribe un correo electrónico válido." + +#: wp-admin/user-new.php:183 +msgid "User added." +msgstr "Usuario añadido." + +#: wp-admin/user-new.php:191 +msgctxt "user" +msgid "Add New User" +msgstr "Añadir nuevo usuario " + +#: wp-admin/user-new.php:193 +msgctxt "user" +msgid "Add Existing User" +msgstr "Añadir usuario existente" + +#: wp-admin/user-new.php:226 +msgid "Add Existing User" +msgstr "Añadir usuario ya existente" + +#: wp-admin/user-new.php:228 +msgid "Enter the email address of an existing user on this network to invite them to this site. That person will be sent an email asking them to confirm the invite." +msgstr "Escribe el correo electrónico de un usuario de esta red para invitarlo a este sitio. A esa persona se le enviará uno correo electrónico para que confirme la invitación." + +#: wp-admin/user-new.php:231 +msgid "Enter the email address or username of an existing user on this network to invite them to this site. That person will be sent an email asking them to confirm the invite." +msgstr "Escribe el correo electrónico o el nombre de usuario de un miembro de esta red para invitarlo a este sitio. A esa persona se le enviará uno correo electrónico para que confirme la invitación." + +#: wp-admin/user-new.php:232 +msgid "E-mail or Username" +msgstr "Correo electrónico o nombre usuario" + +#: wp-admin/user-new.php:245 wp-admin/user-new.php:325 +#: wp-admin/includes/class-wp-users-list-table.php:165 +msgid "Role" +msgstr "Perfil" + +#: wp-admin/user-new.php:253 wp-admin/user-new.php:337 +msgid "Skip Confirmation Email" +msgstr "No enviar el correo electrónico de confirmación" + +#: wp-admin/user-new.php:254 wp-admin/user-new.php:338 +msgid "Add the user without sending them a confirmation email." +msgstr "Añadir el usuario sin enviarle un email de confirmación." + +#: wp-admin/user-new.php:258 +msgid "Add Existing User " +msgstr "Añadir usuario existente" + +#: wp-admin/user-new.php:267 +msgid "Create a brand new user and add it to this site." +msgstr "Crear un nuevo usuario y añadirlo a este sitio." + +#: wp-admin/user-new.php:296 wp-admin/user-edit.php:267 +msgid "First Name" +msgstr "Nombre" + +#: wp-admin/user-new.php:300 wp-admin/user-edit.php:272 +msgid "Last Name" +msgstr "Apellidos" + +#: wp-admin/user-new.php:309 +msgid "(twice, required)" +msgstr "(dos veces, requerido)" + +#: wp-admin/user-new.php:319 +msgid "Send Password?" +msgstr "¿Enviar Contraseña?" + +#: wp-admin/user-new.php:320 +msgid "Send this password to the new user by email." +msgstr "Enviar esta contraseña al nuevo usuario por correo electrónico." + +#: wp-admin/user-new.php:343 +msgid "Add New User " +msgstr "Añadir nuevo usuario" + +#: wp-admin/index.php:34 +msgid "Welcome to your WordPress Dashboard! You will find helpful tips in the Help tab of each screen to assist you as you get to know the application." +msgstr "Bienvenido a tu escritorio de WordPress. Encontrarás consejos en la pestaña Ayuda de cada pantalla que te ayudarán a conocer la aplicación." + +#: wp-admin/index.php:35 +msgid "The Admin Bar at the top, new in 3.1, provides quick access to common tasks when you are viewing your site." +msgstr "La barra de administración en la parte superior, nueva en 3.1, proporciona acceso rápido a las tareas más comunes cuando se está viendo el sitio." + +#: wp-admin/index.php:36 +msgid "The left-hand navigation menu provides links to the administration screens in your WordPress application. You can expand or collapse navigation sections by clicking on the arrow that appears on the right side of each navigation item when you hover over it. You can also minimize the navigation menu to a narrow icon strip by clicking on the faint separator lines between the Dashboard and Posts sections, or between Comments and Appearance; when minimized, the submenu items will be displayed on hover." +msgstr "El menú de navegación de la izquierda muestra enlaces a las pantallas de administración de tu WordPress. Puedes expandir o contraer secciones de navegación haciendo clic en la flecha que aparece en la parte derecha de cada elemento de navegación al pasar el cursor por encima. Puedes, además, reducir el menú de navegación a una tira de iconos haciendo clic en la línea fina que separa el escritorio de la sección de entradas, o entre comentarios y aspecto; cuando se minimiza, los elementos del submenú se mostrarán al pasar el cursor por encima." + +#: wp-admin/index.php:37 +msgid "You can configure your dashboard by choosing which boxes, or modules, to display in the work area, how many columns to display them in, and where each box should be placed. You can hide/show boxes and select the number of columns in the Screen Options tab. To rearrange the boxes, drag and drop by clicking on the title bar of the selected box and releasing when you see a gray dotted-line rectangle appear in the location you want to place the box. You can also expand or collapse each box by clicking once on the title bar of the box. In addition, some boxes are configurable, and will show a “Configure” link in the title bar when you hover over it." +msgstr "Puedes configurar tu escritorio eligiendo qué cajas o módulos se muestran en el área de trabajo, cuántas columnas se muestran en ellas y dónde deben estar las cajas. Puedes mostrar/ocultar cajas y elegir el número de columnas en la pestaña de opciones de pantalla. Puedes reajustar las cajas seleccionándolas en el barra del título y arrastrándolas a la zona donde quieras, dejándola caer cuando veas un rectángulo de puntos grises en la zona deseada. Puedes expandir o contraer cada caja haciendo clic en la barra de título de la caja. Algunas cajas son configurables, lo verás porque al pasar el cursor por encima de la barra de título ya que mostrará un enlace de “Configurar”" + +#: wp-admin/index.php:38 +msgid "The boxes on your Dashboard screen are:" +msgstr "Las cajas en tu Escritorio son:" + +#: wp-admin/index.php:39 +msgid "Right Now - Displays a summary of the content on your site and identifies which theme and version of WordPress you are using." +msgstr "Ahora mismo - Muestra un resumen de tu sitio e identifica qué tema y versión estás usando." + +#: wp-admin/index.php:40 +msgid "Recent Comments - Shows the most recent comments on your posts (configurable, up to 30) and allows you to moderate them." +msgstr "Comentario recientes - Muestra los comentarios más recientes en tus entradas (es configurable, hasta 30 comentarios) y te permite moderarlos." + +#: wp-admin/index.php:41 +msgid "Incoming Links - Shows links to your site found by Google Blog Search." +msgstr "Enlaces entrantes - Muestra enlaces que apuntan a tu sitio encontrados por la búsqueda de blogs de Google." + +#: wp-admin/index.php:42 +msgid "QuickPress - Allows you to create a new post and either publish it or save it as a draft." +msgstr "Publicación rápida - Te permite crear entradas nuevas y publicarlas o guardarlas como borradores." + +#: wp-admin/index.php:43 +msgid "Recent Drafts - Displays links to the 5 most recent draft posts you’ve started." +msgstr "Borradores recientes - Muestra un enlace a los últimos 5 borradores de entradas que hayas comenzado." + +#: wp-admin/index.php:44 +msgid "WordPress Development Blog - Come here for the latest scoop." +msgstr "Blog de desarrollo de WordPress - Aquí podrás ver la últimas noticias." + +#: wp-admin/index.php:45 +msgid "Other WordPress News - Shows the feed from WordPress Planet. You can configure it to show a different feed of your choosing." +msgstr "Otras noticias sobre WordPress - Muestra el feed de WordPress Planet. Puedes configurarlo para que muestre un feed diferente, a tu elección." + +#: wp-admin/index.php:46 +msgid "Plugins - Features the most popular, newest, and recently updated plugins from the WordPress.org Plugin Directory." +msgstr "Plugins - Muestra los plugins más populares, más nuevos y los recientemente actualizados del directorio de plugins de WordPress.org." + +#: wp-admin/index.php:48 +msgid "Documentation on Dashboard" +msgstr "Documentación sobre el escritorio" + +#: wp-admin/edit-link-form.php:14 +msgid "Links / Edit Link" +msgstr "Enlaces / Editar enlace" + +#: wp-admin/edit-link-form.php:15 wp-admin/includes/meta-boxes.php:634 +msgid "Update Link" +msgstr "Actualizar enlace" + +#: wp-admin/edit-link-form.php:19 +msgid "Links / Add New Link" +msgstr "Enlaces / Añadir nuevo enlace" + +#: wp-admin/edit-link-form.php:30 wp-admin/includes/nav-menu.php:157 +#: wp-admin/includes/nav-menu.php:1108 +msgid "Link Relationship (XFN)" +msgstr "Relación con el enlace (XFN)" + +#: wp-admin/edit-link-form.php:43 +msgid "You can add or edit links on this screen by entering information in each of the boxes. Only the link’s web address and name (the text you want to display on your site as the link) are required fields." +msgstr "Puede añadir o editar enlaces desde esta pantalla introduciendo la información en cada caja. Sólo son necesarios el enlace a la web y el nombre (el texto que quieres mostrar en el enlace en tu sitio)." + +#: wp-admin/edit-link-form.php:44 +msgid "The boxes for link name, web address, and description have fixed positions, while the others may be repositioned using drag and drop. You can also hide boxes you don’t use in the Screen Options tab, or minimize boxes by clicking on the title bar of the box." +msgstr "Las cajas para el nombre del enlace, dirección web y descripción tienen una posición fija. Las otras las puedes mover y colocar mediante arrastrar y soltar. Puedes esconder cajas que no quieras usar en la pestaña Opciones de pantalla o minimizar las cajas haciendo clic en la barra del título de la caja." + +#: wp-admin/edit-link-form.php:45 +msgid "XFN stands for XHTML Friends Network, which is optional. WordPress allows the generation of XFN attributes to show how you are related to the authors/owners of the site to which you are linking." +msgstr "XFN se refiere a red de amigos XHTML (XHTML Friends Network), y es opcional. WordPress permite generar atributos XFN que muestran tu relación con los autores/propietarios del sitio al que estés enlazando." + +#: wp-admin/edit-link-form.php:47 +msgid "Documentation on Creating Links" +msgstr "Documentación sobre la creación de enlaces" + +#: wp-admin/edit-link-form.php:59 +msgid "Link added." +msgstr "Enlace añadido." + +#: wp-admin/edit-link-form.php:89 +msgid "Example: Nifty blogging software" +msgstr "Ejemplo: Estupendo software de publicación" + +#: wp-admin/edit-link-form.php:94 +msgid "Web Address" +msgstr "Dirección web" + +#: wp-admin/edit-link-form.php:97 +msgid "Example: http://wordpress.org/ — don’t forget the http://" +msgstr "Ejemplo: http://wordpress.org/ —no olvides poner http://" + +#: wp-admin/edit-link-form.php:102 wp-admin/themes.php:217 +#: wp-admin/includes/media.php:1076 +#: wp-admin/includes/class-wp-plugins-list-table.php:190 +#: wp-admin/includes/nav-menu.php:163 wp-admin/includes/nav-menu.php:1109 +#: wp-admin/includes/class-wp-terms-list-table.php:101 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:144 +#: wp-admin/press-this.php:151 wp-admin/press-this.php:186 +msgid "Description" +msgstr "Descripción" + +#: wp-admin/edit-link-form.php:105 +msgid "This will be shown when someone hovers over the link in the blogroll, or optionally below the link." +msgstr "Esto se mostrará cuando alguien pase el cursor sobre el enlace en los sitios de interés, u opcionalmente a debajo del enlace." + +#: wp-admin/maint/repair.php:13 +msgid "WordPress › Database Repair" +msgstr "WordPress › Reparación de la base de datos" + +#: wp-admin/maint/repair.php:22 +msgid "To allow use of this page to automatically repair database problems, please add the following line to your wp-config.php file. Once this line is added to your config, reload this page." +msgstr "Para permitir el uso de esta página y así reparar automáticamente problemas en la base de datos, añade la línea siguiente a tu fichero wp-config.php. Una vez hayas añadido esta línea a tu configuración vuelve a cargar esta página." + +#: wp-admin/maint/repair.php:71 +msgid "Some database problems could not be repaired. Please copy-and-paste the following list of errors to the WordPress support forums to get additional assistance." +msgstr "Algunos problemas de la base de datos no se han podido reparar. Por favor, copia y pega la siguiente lista de errores en los foros de soporte de WordPress para conseguir ayuda." + +#: wp-admin/maint/repair.php:77 +msgid "Repairs complete. Please remove the following line from wp-config.php to prevent this page from being used by unauthorized users." +msgstr "Reparación completa. Quita la siguiente línea del archivo wp-config.php para evitar que esta página la utilicen usuarios sin autorización." + +#: wp-admin/maint/repair.php:81 +msgid "One or more database tables are unavailable. To allow WordPress to attempt to repair these tables, press the “Repair Database” button. Repairing can take a while, so please be patient." +msgstr "Una o más tablas no están disponibles. Para permitir a WordPress que intente repararlas, pulse el botón “Reparar bases de datos”. La reparación puede llevar un rato, ten paciencia, por favor." + +#: wp-admin/maint/repair.php:83 +msgid "WordPress can automatically look for some common database problems and repair them. Repairing can take a while, so please be patient." +msgstr "WordPress puede revisar automáticamente algunos problemas habituales de bases de datos. Repararlos puede llevar un rato, ten paciencia, por favor." + +#: wp-admin/maint/repair.php:85 +msgid "Repair Database" +msgstr "Reparar base de datos" + +#: wp-admin/maint/repair.php:86 +msgid "WordPress can also attempt to optimize the database. This improves performance in some situations. Repairing and optimizing the database can take a long time and the database will be locked while optimizing." +msgstr "WordPress puede también tratar de optimizar la base de datos. Esto mejora el rendimiento en algunas situaciones. Reparar y optimizar la base de datos puede llevar bastante tiempo y la base de datos se bloqueará durante la optimización." + +#: wp-admin/maint/repair.php:87 +msgid "Repair and Optimize Database" +msgstr "Reparar y optimizar la base de datos" + +#: wp-admin/options-general.php:13 wp-admin/options-discussion.php:13 +#: wp-admin/options-privacy.php:13 wp-admin/options-media.php:13 +#: wp-admin/options-writing.php:13 wp-admin/options-reading.php:13 +#: wp-admin/options-permalink.php:13 +msgid "You do not have sufficient permissions to manage options for this site." +msgstr "No tienes suficientes permisos para administrar las opciones de este sitio." + +#: wp-admin/options-general.php:15 +msgid "General Settings" +msgstr "Ajustes generales" + +#: wp-admin/options-general.php:18 +msgctxt "timezone date format" +msgid "Y-m-d G:i:s" +msgstr "d-m-Y G:i" + +#: wp-admin/options-general.php:62 +msgid "The fields on this screen determine some of the basics of your site setup." +msgstr "Los campos en esta pantalla determinan algunas configuraciones básicas de tu sitio." + +#: wp-admin/options-general.php:63 +msgid "Most themes display the site title at the top of every page, in the title bar of the browser, and as the identifying name for syndicated feeds. The tagline is also displayed by many themes." +msgstr "La mayoría de los temas muestran el título del sitio en la parte superior de cada página, en la barra de título del navegador, y como nombre identificativo para los feeds. La descripción corta también se muestra en muchos temas." + +#: wp-admin/options-general.php:64 +msgid "The WordPress URL and the Site URL can be the same (example.com) or different; for example, having the WordPress core files (example.com/wordpress) in a subdirectory instead of the root directory." +msgstr "La URL de WordPress y la URL del sitio pueden ser las mismas (ejemplo.com) o diferentes; por ejemplo, puedes tener los archivos del core de WordPress en un subdirectorio (ejemplo.com/wordpress) en vez de en el directorio raíz." + +#: wp-admin/options-general.php:65 +msgid "If you want site visitors to be able to register themselves, as opposed to being registered by the site administrator, check the membership box. A default user role can be set for all new users, whether self-registered or registered by the site administrator." +msgstr "Si deseas que los visitantes se puedan registrar en tu sitio, en vez de que el administrador del sitio deba registrarlos, marca la casilla de miembros. Se otorgará un perfil predeterminado a cada nuevo usuario. Da igual que se registren ellos mismos o que les registre el administrador del sitio." + +#: wp-admin/options-general.php:66 +msgid "UTC means Coordinated Universal Time." +msgstr "UTC quiere decir Hora universal coordinada (Coordinated Universal Time)" + +#: wp-admin/options-general.php:67 +msgid "Remember to click the Save Changes button at the bottom of the screen for new settings to take effect." +msgstr "Recuerda hacer clic en la parte inferior de la pantalla sobre el botón Guardar cambios para que los nuevos ajustes surtan efecto." + +#: wp-admin/options-general.php:69 +msgid "Documentation on General Settings" +msgstr "Documentación sobre los ajustes generales" + +#: wp-admin/options-general.php:89 +msgid "Tagline" +msgstr "Descripción corta" + +#: wp-admin/options-general.php:91 +msgid "In a few words, explain what this site is about." +msgstr "En pocas palabras, explica de qué va este sitio." + +#: wp-admin/options-general.php:95 +msgid "WordPress address (URL)" +msgstr "Dirección de WordPress (URL)" + +#: wp-admin/options-general.php:99 +msgid "Site address (URL)" +msgstr "Dirección del sitio (URL)" + +#: wp-admin/options-general.php:101 +msgid "Enter the address here if you want your site homepage to be different from the directory you installed WordPress." +msgstr "Introduce la dirección de tu página de inicio si es diferente al directorio donde está instalado WordPress." + +#: wp-admin/options-general.php:104 wp-admin/options-general.php:123 +msgid "E-mail address" +msgstr "Dirección de correo electrónico" + +#: wp-admin/options-general.php:106 +msgid "This address is used for admin purposes, like new user notification." +msgstr "Esta dirección se usa sólo con fines administrativos, como para la notificación de nuevos usuarios." + +#: wp-admin/options-general.php:109 wp-admin/options-general.php:110 +msgid "Membership" +msgstr "Miembros" + +#: wp-admin/options-general.php:112 +msgid "Anyone can register" +msgstr "Cualquiera puede registrarse" + +#: wp-admin/options-general.php:116 +msgid "New User Default Role" +msgstr "Perfil predeterminado para nuevos usuarios" + +#: wp-admin/options-general.php:125 +msgid "This address is used for admin purposes. If you change this we will send you an e-mail at your new address to confirm it. The new address will not become active until confirmed." +msgstr "Esta dirección de correo electrónico se usa para propósitos administrativos. Si la cambias, te enviaremos un correo electrónico a tu nueva dirección para confirmarla. La nueva dirección no se activará hasta ser confirmada." + +#: wp-admin/options-general.php:130 +msgid "There is a pending change of the admin e-mail to %1$s. Cancel" +msgstr "Hay un cambio pendiente del correo electrónico del administrador a %1$s. Cancelar" + +#: wp-admin/options-general.php:140 wp-admin/options-general.php:196 +msgid "Timezone" +msgstr "Zona horaria" + +#: wp-admin/options-general.php:162 +msgid "UTC %s" +msgstr "UTC %s" + +#: wp-admin/options-general.php:166 +msgid "hours" +msgstr "horas" + +#: wp-admin/options-general.php:167 wp-admin/options-general.php:203 +msgid "UTC time is %s" +msgstr "La hora UTC es %s" + +#: wp-admin/options-general.php:169 +msgid "UTC %1$s is %2$s" +msgstr "UTC %1$s es %2$s" + +#: wp-admin/options-general.php:172 +msgid "Unfortunately, you have to manually update this for daylight saving time. The PHP Date/Time library is not supported by your web host." +msgstr "Desafortunadamente deberás cambiar de forma manual el horario de verano. La librería Fecha/Hora de PHP no está soportada por tu alojamiento web." + +#: wp-admin/options-general.php:205 +msgid "Local time is %1$s" +msgstr "La hora local es %1$s" + +#: wp-admin/options-general.php:208 +msgid "Choose a city in the same timezone as you." +msgstr "Elige una ciudad que esté en la misma zona horaria que la tuya." + +#: wp-admin/options-general.php:217 +msgid "This timezone is currently in daylight saving time." +msgstr "Esta zona horaria se encuentra actualmente en el horario de verano." + +#: wp-admin/options-general.php:219 +msgid "This timezone is currently in standard time." +msgstr "Esta zona horaria se encuentra actualmente en horario de invierno." + +#: wp-admin/options-general.php:238 +msgid "Daylight saving time begins on: %s." +msgstr "El horario de verano comienza el: %s." + +#: wp-admin/options-general.php:239 +msgid "Standard time begins on: %s." +msgstr "El horario de invierno comienza el: %s." + +#: wp-admin/options-general.php:243 +msgid "This timezone does not observe daylight saving time." +msgstr "Esta zona horaria no tiene en cuenta el horario de verano." + +#: wp-admin/options-general.php:262 wp-admin/includes/schema.php:223 +msgid "F j, Y" +msgstr "j F, Y" + +#: wp-admin/options-general.php:281 wp-admin/options-general.php:313 +msgid "Custom:" +msgstr "Personalizado:" + +#: wp-admin/options-general.php:283 +msgid "Documentation on date and time formatting." +msgstr "Documentación sobre formatos de fecha y hora." + +#: wp-admin/options-general.php:295 wp-admin/includes/schema.php:225 +msgid "g:i a" +msgstr "G:i" + +#: wp-admin/options-general.php:320 +msgid "Week Starts On" +msgstr "La semana comienza el" + +#: wp-admin/options-general.php:336 +msgid "Site language:" +msgstr "Idioma del sitio:" + +#: wp-admin/themes.php:35 wp-admin/includes/template.php:1450 +msgid "Manage Themes" +msgstr "Administrar temas" + +#: wp-admin/themes.php:40 +msgid "Aside from the default theme included with your WordPress installation, themes are designed and developed by third parties." +msgstr "Aparte del tema por defecto incluido en su instalación de WordPress, los temas han sido diseñados y desarrollados por terceros." + +#: wp-admin/themes.php:41 +msgid "You can see your active theme at the top of the screen. Below are the other themes you have installed that are not currently in use. You can see what your site would look like with one of these themes by clicking the Preview link. To change themes, click the Activate link." +msgstr "Puedes ver tu tema activo en la parte superior de la pantalla. Debajo están los otros temas que tienes instalados pero que no están actualmente en uso. Puedes ver cómo quedaría tu sitio con uno de estos temas haciendo clic en el enlace Previsualizar. Para cambiar de tema, haz clic en Activar." + +#: wp-admin/themes.php:43 +msgid "If you would like to see more themes to choose from, click on the “Install Themes” tab and you will be able to browse or search for additional themes from the WordPress.org Theme Directory. Themes in the WordPress.org Theme Directory are designed and developed by third parties, and are licensed under the GNU General Public License, version 2, just like WordPress. Oh, and they’re free!" +msgstr "Si quieres ver más temas entre los que elegir haz clic en la pestaña “Instalar temas” y podrás navegar o buscar temas adicionales en el directorio de temas de WordPress.org. Los temas del directorio de temas de WordPress.org están diseñados y desarrollados por terceros, y todos están bajo la licencia pública general GNU versión 2, al igual que WordPress. ¡Ah, y son gratuitos!" + +#: wp-admin/themes.php:46 wp-admin/theme-editor.php:33 +msgid "Documentation on Using Themes" +msgstr "Documentación sobre el uso de temas" + +#: wp-admin/themes.php:61 +msgid "The active theme is broken. Reverting to the default theme." +msgstr "El tema activo está dañado. Volviendo al tema por defecto." + +#: wp-admin/themes.php:64 +msgid "New theme activated. This theme supports widgets, please visit the widgets settings screen to configure them." +msgstr "Nuevo tema activado. Este tema soporta widgets, por favor, visita la pantalla configuración de widgets para configurarlos." + +#: wp-admin/themes.php:66 +msgid "New theme activated. Visit site" +msgstr "Nuevo tema activado. Visitar sitio" + +#: wp-admin/themes.php:69 +msgid "Theme deleted." +msgstr "El tema ha sido eliminado." + +#: wp-admin/themes.php:78 +msgctxt "theme" +msgid "Install Themes" +msgstr "Instalar temas" + +#: wp-admin/themes.php:86 +msgid "Current Theme" +msgstr "Tema actual" + +#: wp-admin/themes.php:89 +msgid "Current theme preview" +msgstr "Vista previa del tema actual" + +#: wp-admin/themes.php:93 wp-admin/includes/class-wp-themes-list-table.php:184 +msgid "%1$s %2$s by %3$s" +msgstr "%1$s %2$s por %3$s" + +#: wp-admin/themes.php:96 +msgid "Options:" +msgstr "Opciones:" + +#: wp-admin/themes.php:127 wp-admin/includes/class-wp-themes-list-table.php:194 +msgid "Tags:" +msgstr "Etiquetas:" + +#: wp-admin/themes.php:143 +msgid "Available Themes" +msgstr "Temas disponibles" + +#: wp-admin/themes.php:150 wp-admin/themes.php:152 +msgid "Search Themes" +msgstr "Buscar temas" + +#: wp-admin/themes.php:153 wp-admin/includes/theme-install.php:79 +msgid "Feature Filter" +msgstr "Filtrar por características" + +#: wp-admin/themes.php:161 +msgid "Theme filters" +msgstr "Filtros de temas" + +#: wp-admin/themes.php:187 +msgid "Apply Filters" +msgstr "Aplicar filtros" + +#: wp-admin/themes.php:189 +msgid "Close filters" +msgstr "Cerrar filtros" + +#: wp-admin/themes.php:211 +msgid "Broken Themes" +msgstr "Temas dañados" + +#: wp-admin/themes.php:212 +msgid "The following themes are installed but incomplete. Themes must have a stylesheet and a template." +msgstr "Los siguientes temas están instalados pero incompletos. Los temas deben tener una hoja de estilos y una plantilla." + +#: wp-admin/media.php:23 wp-admin/media.php:57 +msgid "You are not allowed to edit this attachment." +msgstr "No tienes autorización para editar este archivo adjunto." + +#: wp-admin/media.php:45 wp-admin/media.php:100 +#: wp-admin/includes/template.php:1425 +msgid "Edit Media" +msgstr "Editar multimedia" + +#: wp-admin/media.php:61 +msgid "You attempted to edit an attachment that doesn’t exist. Perhaps it was deleted?" +msgstr "Estás intentando editar un adjunto que no existe. ¿Lo has borrado?" + +#: wp-admin/media.php:62 +msgid "You can’t edit this attachment because it is in the Trash. Please move it out of the Trash and try again." +msgstr "No puedes editar este adjunto ya que está en la Papelera. Sácalo de la Papelera e inténtalo de nuevo." + +#: wp-admin/media.php:71 +msgid "This screen allows you to edit five fields for metadata in a file within the media library." +msgstr "Esta pantalla te permite editar cinco campos para metadatos de un archivo en la biblioteca multimedia." + +#: wp-admin/media.php:72 +msgid "For images only, you can click on Edit Image under the thumbnail to expand out an inline image editor with icons for cropping, rotating, or flipping the image as well as for undoing and redoing. The boxes on the right give you more options for scaling the image, for cropping it, and for cropping the thumbnail in a different way than you crop the original image. You can click on Help in those boxes to get more information." +msgstr "(Sólo para imágenes) Puedes hacer clic en editar imágenes, debajo de la miniatura, para obtener el menú de edición de imágenes y recortar, rotar o invertir la imagen, así como deshacer y rehacer. Las cajas de la derecha te dan más opciones para escalar y recortar la imagen; y para recortar la miniatura de forma diferente de la imagen original. Puedes hacer clic en la ayuda en esas cajas para obtener más información." + +#: wp-admin/media.php:73 +msgid "Note that you crop the image by clicking on it (the Crop icon is already selected) and dragging the cropping frame to select the desired part. Then click Save to retain the cropping." +msgstr "Se recorta la imagen haciendo clic en la misma (el icono de recorte ya estará seleccionado) y arrastrando el marcho de recorte hasta donde se desee. Para fijarla, haz clic en guardar." + +#: wp-admin/media.php:74 +msgid "Remember to click Update Media to save metadata entered or changed." +msgstr "Recuerda hacer clic en Actualizar archivos multimedia para guardar los metadatos que hayas introducido o cambiado." + +#: wp-admin/media.php:76 +msgid "Documentation on Edit Media" +msgstr "Documentación sobre editar archivos multimedia" + +#: wp-admin/media.php:88 wp-admin/upload.php:171 wp-admin/upload.php:197 +msgid "Media attachment updated." +msgstr "El archivo ha sido actualizado." + +#: wp-admin/media.php:104 wp-admin/media.php:113 +msgid "Update Media" +msgstr "Actualizar medio" + +#: wp-admin/custom-header.php:76 wp-admin/includes/file.php:19 +msgid "Header" +msgstr "Cabecera" + +#: wp-admin/custom-header.php:92 +msgid "You can set a custom image header for your site. Simply upload the image and crop it, and the new header will go live immediately." +msgstr "Puedes poner una imagen de cabecera personalizada en tu sitio. Simplemente sube una imagen, recórtala/ajústala y la nueva cabecera aparecerá inmediatamente en tu sitio." + +#: wp-admin/custom-header.php:93 +msgid "If you want to discard your custom header and go back to the default included in your theme, click on the buttons to remove the custom image and restore the original header image." +msgstr "Si quieres descartar tu cabecera personalizada y volver a las por defecto de tu tema, haz clic en la parte inferior para eliminar la imagen personalizada y restaurar la imagen original." + +#: wp-admin/custom-header.php:94 +msgid "Some themes come with additional header images bundled. If you see multiple images displayed, select the one you’d like and click the Save Changes button." +msgstr "Algunos temas llevan incluidas imágenes de cabecera adicionales. Si ves que se muestran varias imágenes elige la que te guste y haz clic en el botón Guardar cambios." + +#: wp-admin/custom-header.php:96 +msgid "Documentation on Custom Header" +msgstr "Documentación sobre cabecera personalizada" + +#: wp-admin/custom-header.php:426 wp-admin/includes/theme.php:303 +msgid "Custom Header" +msgstr "Cabecera personalizada" + +#: wp-admin/custom-header.php:430 +msgid "Header updated. Visit your site to see how it looks." +msgstr "Cabezera actualizada. Visita tu sitio para ver los cambios." + +#: wp-admin/custom-header.php:434 +msgid "Header Image" +msgstr "Imagen de cabecera" + +#: wp-admin/custom-header.php:461 wp-admin/custom-background.php:234 +msgid "Upload Image" +msgstr "Subir imagen" + +#: wp-admin/custom-header.php:463 +msgid "You can upload a custom header image to be shown at the top of your site instead of the default one. On the next screen you will be able to crop the image." +msgstr "Puedes subir una imagen de cabecera personalizada para que se vea en tu sitio web en vez de la que viene por defecto. En la siguiente pantalla podrás recortar la imagen." + +#: wp-admin/custom-header.php:464 +msgid "Images of exactly %1$d × %2$d pixels will be used as-is." +msgstr "Las imágenes de exactamente %1$d x %2$d pixels se utilizarán tal cual." + +#: wp-admin/custom-header.php:467 wp-admin/custom-background.php:236 +msgid "Choose an image from your computer:" +msgstr "Elige una imagen desde tu ordenador:" + +#: wp-admin/custom-header.php:471 wp-admin/custom-background.php:239 +#: wp-admin/includes/media.php:1557 wp-admin/includes/media.php:1559 +#: wp-admin/includes/class-wp-theme-install-list-table.php:32 +#: wp-admin/includes/template.php:1464 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:32 +msgid "Upload" +msgstr "Subir" + +#: wp-admin/custom-header.php:485 +msgid "Default Images" +msgstr "Imágenes por defecto" + +#: wp-admin/custom-header.php:488 +msgid "If you don‘t want to upload your own image, you can use one of these cool headers." +msgstr "Si no quieres subir tu propia imagen, puedes usar una de estas cabeceras tan chulas." + +#: wp-admin/custom-header.php:490 +msgid "You can use one of these cool headers." +msgstr "Puedes usar estas cabeceras tan chulas." + +#: wp-admin/custom-header.php:501 wp-admin/custom-background.php:209 +msgid "Remove Image" +msgstr "Eliminar Imagen" + +#: wp-admin/custom-header.php:503 +msgid "This will remove the header image. You will not be able to restore any customizations." +msgstr "Esto eliminará la imagen de cabecera. No podrás restaurar ninguna personalización." + +#: wp-admin/custom-header.php:504 +msgid "Remove Header Image" +msgstr "Eliminar imagen de cabecera" + +#: wp-admin/custom-header.php:511 +msgid "Reset Image" +msgstr "Restaurar imagen" + +#: wp-admin/custom-header.php:513 +msgid "This will restore the original header image. You will not be able to restore any customizations." +msgstr "Esto restaurará la imagen de cabecera original. No te será posible restaurar ninguna personalización." + +#: wp-admin/custom-header.php:514 +msgid "Restore Original Header Image" +msgstr "Restaurar imagen de cabecera original" + +#: wp-admin/custom-header.php:522 +msgid "Header Text" +msgstr "Texto de cabecera" + +#: wp-admin/custom-header.php:526 +msgid "Display Text" +msgstr "Visualización de texto" + +#: wp-admin/custom-header.php:530 wp-admin/comment.php:182 +#: wp-admin/includes/class-wp-links-list-table.php:110 +msgid "No" +msgstr "No" + +#: wp-admin/custom-header.php:531 +#: wp-admin/includes/class-wp-links-list-table.php:110 +msgid "Yes" +msgstr "Sí" + +#: wp-admin/custom-header.php:537 +msgid "Text Color" +msgstr "Color de texto" + +#: wp-admin/custom-header.php:541 +msgid "If you want to hide header text, add #blank as text color." +msgstr "Si quieres ocultar el texto de la cabecera, añade #blank como color de texto." + +#: wp-admin/custom-header.php:542 wp-admin/custom-background.php:298 +msgid "Select a Color" +msgstr "Elige un color" + +#: wp-admin/custom-header.php:550 +msgid "Reset Text Color" +msgstr "Restaurar color de texto" + +#: wp-admin/custom-header.php:552 +msgid "This will restore the original header text. You will not be able to restore any customizations." +msgstr "Esto restaurará el texto original de la cabecera. No te será posible restaurar ninguna personalización." + +#: wp-admin/custom-header.php:553 +msgid "Restore Original Header Text" +msgstr "Restaurar texto original de la cabecera" + +#: wp-admin/custom-header.php:586 +msgid "Image Upload Error" +msgstr "Error al subir la imagen" + +#: wp-admin/custom-header.php:617 wp-admin/custom-header.php:677 +msgid "Image could not be processed. Please go back and try again." +msgstr "La imagen no se pudo procesar. Por favor, prueba de nuevo." + +#: wp-admin/custom-header.php:617 wp-admin/custom-header.php:677 +msgid "Image Processing Error" +msgstr "Error en el procesado de la imagen" + +#: wp-admin/custom-header.php:631 +msgid "Crop Header Image" +msgstr "Recortar imagen de cabecera" + +#: wp-admin/custom-header.php:634 +msgid "Choose the part of the image you want to use as your header." +msgstr "Elige la parte de la imagen que quieras usar como cabecera." + +#: wp-admin/custom-header.php:635 +msgid "You need Javascript to choose a part of the image." +msgstr "Necesitas Javascript para elegir una parte de la imagen." + +#: wp-admin/custom-header.php:649 +msgid "Crop and Publish" +msgstr "Recortar y publicar" + +#: wp-admin/custom-header.php:726 +msgid "You do not have permission to customize headers." +msgstr "No tienes autorización para personalizar cabeceras." + +#: wp-admin/options-discussion.php:15 +msgid "Discussion Settings" +msgstr "Ajustes de comentarios" + +#: wp-admin/options-discussion.php:19 +msgid "This screen provides many options for controlling the management and display of comments and links to your posts/pages. So many, in fact, they won’t all fit here! :) Use the documentation link below to get information on what each discussion setting does." +msgstr "Esta pantalla proporciona muchas opciones para mostrar y gestionar los comentarios y enlaces en tus entradas/páginas. Son muchas, pero no caben todas aquí :) Usa el enlace a la documentación para conseguir más información y saber qué hace cada ajuste." + +#: wp-admin/options-discussion.php:20 wp-admin/options-privacy.php:21 +#: wp-admin/options-media.php:22 wp-admin/options-writing.php:20 +#: wp-admin/options-reading.php:48 wp-admin/options-permalink.php:24 +msgid "You must click the Save Changes button at the bottom of the screen for new settings to take effect." +msgstr "Debes hacer clic en el botón Guardar cambios en la parte inferior de la pantalla para que los nuevos ajustes tengan efecto." + +#: wp-admin/options-discussion.php:22 +msgid "Documentation on Discussion Settings" +msgstr "Documentación sobre la configuración de comentarios" + +#: wp-admin/options-discussion.php:38 wp-admin/options-discussion.php:39 +msgid "Default article settings" +msgstr "Ajustes por defecto de las entradas" + +#: wp-admin/options-discussion.php:42 +msgid "Attempt to notify any blogs linked to from the article." +msgstr "Tratar de avisar a los sitios enlazados desde el artículo." + +#: wp-admin/options-discussion.php:46 +msgid "Allow link notifications from other blogs (pingbacks and trackbacks.)" +msgstr "Permitir notificaciones de enlace desde otros sitios (pingbacks y trackbacks)" + +#: wp-admin/options-discussion.php:50 +msgid "Allow people to post comments on new articles" +msgstr "Permitir comentarios en las nuevas entradas" + +#: wp-admin/options-discussion.php:52 +msgid "These settings may be overridden for individual articles." +msgstr "Estos ajustes pueden modificarse para cada entrada en particular." + +#: wp-admin/options-discussion.php:56 wp-admin/options-discussion.php:57 +msgid "Other comment settings" +msgstr "Otros ajustes de comentarios" + +#: wp-admin/options-discussion.php:58 +msgid "Comment author must fill out name and e-mail" +msgstr "El autor del comentario debe rellenar el nombre y el correo electrónico" + +#: wp-admin/options-discussion.php:62 +msgid "Users must be registered and logged in to comment" +msgstr "Los usuarios deben registrarse e identificarse para comentar" + +#: wp-admin/options-discussion.php:63 +msgid "(Signup has been disabled. Only members of this site can comment.)" +msgstr "(El registro ha sido deshabilitado. Sólo los miembros de este sitio pueden comentar.)" + +#: wp-admin/options-discussion.php:69 +msgid "Automatically close comments on articles older than %s days" +msgstr "Cerrar automáticamente los comentarios en las entradas con más de %s días" + +#: wp-admin/options-discussion.php:85 +msgid "Enable threaded (nested) comments %s levels deep" +msgstr "Activar los comentarios anidados hasta %s niveles" + +#: wp-admin/options-discussion.php:94 +msgid "last" +msgstr "última" + +#: wp-admin/options-discussion.php:96 +msgid "first" +msgstr "primera" + +#: wp-admin/options-discussion.php:98 +msgid "Break comments into pages with %1$s top level comments per page and the %2$s page displayed by default" +msgstr "Separa los comentarios en páginas de %1$s comentarios por página y se muestra la %2$s página por defecto" + +#: wp-admin/options-discussion.php:106 +msgid "older" +msgstr "más antiguos" + +#: wp-admin/options-discussion.php:108 +msgid "newer" +msgstr "más recientes" + +#: wp-admin/options-discussion.php:110 +msgid "Comments should be displayed with the %s comments at the top of each page" +msgstr "Los comentarios se ordenarán con los %s al principio" + +#: wp-admin/options-discussion.php:116 wp-admin/options-discussion.php:117 +msgid "E-mail me whenever" +msgstr "Enviarme un correo electrónico cuando" + +#: wp-admin/options-discussion.php:120 +msgid "Anyone posts a comment" +msgstr "Alguien envía un comentario" + +#: wp-admin/options-discussion.php:124 +msgid "A comment is held for moderation" +msgstr "Se ha recibido un comentario para moderar" + +#: wp-admin/options-discussion.php:128 wp-admin/options-discussion.php:129 +msgid "Before a comment appears" +msgstr "Para que un comentario aparezca" + +#: wp-admin/options-discussion.php:132 +msgid "An administrator must always approve the comment" +msgstr "Un administrador debe aprobar el comentario" + +#: wp-admin/options-discussion.php:134 +msgid "Comment author must have a previously approved comment" +msgstr "El autor del comentario debe tener un comentario previamente aprobado" + +#: wp-admin/options-discussion.php:138 wp-admin/options-discussion.php:139 +msgid "Comment Moderation" +msgstr "Moderación de comentarios" + +#: wp-admin/options-discussion.php:140 +msgid "Hold a comment in the queue if it contains %s or more links. (A common characteristic of comment spam is a large number of hyperlinks.)" +msgstr "Mantener un comentario en espera si contiene más de %s enlaces (una característica común del spam en comentarios es el gran número de enlaces)." + +#: wp-admin/options-discussion.php:142 +msgid "When a comment contains any of these words in its content, name, URL, e-mail, or IP, it will be held in the moderation queue. One word or IP per line. It will match inside words, so “press” will match “WordPress”." +msgstr "Mantener en la cola de moderación todo comentario que incluya cualquiera de las siguientes palabras en su contenido, nombre, URL, e-mail o IP. Una palabra o IP por línea. Atención a las coincidencias en el interior de palabras: “press” coincidirá con “WordPress”." + +#: wp-admin/options-discussion.php:149 wp-admin/options-discussion.php:150 +msgid "Comment Blacklist" +msgstr "Lista negra de comentarios" + +#: wp-admin/options-discussion.php:151 +msgid "When a comment contains any of these words in its content, name, URL, e-mail, or IP, it will be marked as spam. One word or IP per line. It will match inside words, so “press” will match “WordPress”." +msgstr "Cuando un comentario contenga cualquiera de estas palabras en su contenido, nombre, URL, correo electrónico, o IP, será marcado como spam. Una palabra o IP por línea. Tendrá en cuenta las coincidencias parciales, así que “press” coincidirá con “WordPress”." + +#: wp-admin/options-discussion.php:160 +msgid "Avatars" +msgstr "Avatares" + +#: wp-admin/options-discussion.php:162 +msgid "An avatar is an image that follows you from weblog to weblog appearing beside your name when you comment on avatar enabled sites. Here you can enable the display of avatars for people who comment on your site." +msgstr "Un avatar es una imagen que te sigue de sitio en sitio, apareciendo junto a tu nombre cuando comentas en una entrada si están activados los avatares en el sitio. Aquí puedes activar que se muestren los avatares de la gente que comente en tu sitio." + +#: wp-admin/options-discussion.php:168 wp-admin/options-discussion.php:169 +msgid "Avatar Display" +msgstr "Visibilidad" + +#: wp-admin/options-discussion.php:171 +msgid "Don’t show Avatars" +msgstr "No mostrar avatares" + +#: wp-admin/options-discussion.php:171 +msgid "Show Avatars" +msgstr "Mostrar avatares" + +#: wp-admin/options-discussion.php:180 wp-admin/options-discussion.php:181 +msgid "Maximum Rating" +msgstr "Calificación máxima" + +#: wp-admin/options-discussion.php:186 +msgid "G — Suitable for all audiences" +msgstr "G — Para todos los públicos" + +#: wp-admin/options-discussion.php:188 +msgid "PG — Possibly offensive, usually for audiences 13 and above" +msgstr "PG — Posiblemente ofensivo, normalmente para mayores de 13 años" + +#: wp-admin/options-discussion.php:190 +msgid "R — Intended for adult audiences above 17" +msgstr "R — Destinado a un público adulto mayor de 17" + +#: wp-admin/options-discussion.php:192 +msgid "X — Even more mature than above" +msgstr "X — Contenido más adulto que los anteriores." + +#: wp-admin/options-discussion.php:203 wp-admin/options-discussion.php:204 +msgid "Default Avatar" +msgstr "Avatar por defecto" + +#: wp-admin/options-discussion.php:206 +msgid "For users without a custom avatar of their own, you can either display a generic logo or a generated one based on their e-mail address." +msgstr "Para usuarios que no tengan un avatar personalizado podemos mostrar uno genérico o uno basado en su dirección de correo electrónico." + +#: wp-admin/options-discussion.php:210 +msgid "Mystery Man" +msgstr "Hombre misterioso" + +#: wp-admin/options-discussion.php:211 +msgid "Blank" +msgstr "Sin avatar" + +#: wp-admin/options-discussion.php:212 +msgid "Gravatar Logo" +msgstr "Logo de Gravatar" + +#: wp-admin/options-discussion.php:213 +msgid "Identicon (Generated)" +msgstr "Identicon (autogenerado)" + +#: wp-admin/options-discussion.php:214 +msgid "Wavatar (Generated)" +msgstr "Wavatar (autogenerado)" + +#: wp-admin/options-discussion.php:215 +msgid "MonsterID (Generated)" +msgstr "MonsterID (autogenerado)" + +#: wp-admin/options-discussion.php:216 +msgid "Retro (Generated)" +msgstr "Retro (generado)" + +#: wp-admin/plugin-editor.php:18 +msgid "You do not have sufficient permissions to edit plugins for this site." +msgstr "No tienes suficientes permisos para editar los plugins de este sitio." + +#: wp-admin/plugin-editor.php:20 +msgid "Edit Plugins" +msgstr "Editar plugins" + +#: wp-admin/plugin-editor.php:30 +msgid "There are no plugins installed on this site." +msgstr "No hay plugins instalados en este sitio." + +#: wp-admin/plugin-editor.php:104 +msgid "No such file exists! Double check the name and try again." +msgstr "¡El archivo no existe! Comprueba el nombre e inténtalo de nuevo." + +#: wp-admin/plugin-editor.php:111 +msgid "Files of this type are not editable." +msgstr "Los archivos de este tipo no son editables." + +#: wp-admin/plugin-editor.php:116 +msgid "You can use the editor to make changes to any of your plugins’ individual PHP files. Be aware that if you make changes, plugins updates will overwrite your customizations." +msgstr "Puedes usar el editor para realizar cambios a cualquier archivo php de tus plugins. Cuidado si realizas cambios, la actualización de los plugins producirá que tus modificaciones sean sobrescritas y se pierdan." + +#: wp-admin/plugin-editor.php:117 +msgid "Choose a plugin to edit from the menu in the upper right and click the Select button. Click once on any file name to load it in the editor, and make your changes. Don’t forget to save your changes (Update File) when you’re finished." +msgstr "Elige un plugin a editar en el menú superior derecha y haz clic en el botón Seleccionar. Haz clic una vez sobre cualquier nombre de archivo para cargarlo en el editor. No olvides guardar tus cambios (Actualizar archivo) cuando acabes." + +#: wp-admin/plugin-editor.php:118 +msgid "The Documentation menu below the editor lists the PHP functions recognized in the plugin file. Clicking Lookup takes you to a web page about that particular function." +msgstr "El menú Documentación bajo el editor enumera las funciones PHP reconocidas en los archivos del plugin. Haciendo clic en Buscar te lleva a una página que habla de esa función en particular." + +#: wp-admin/plugin-editor.php:119 +msgid "If you want to make changes but don’t want them to be overwritten when the plugin is updated, you may be ready to think about writing your own plugin. For information on how to edit plugins, write your own from scratch, or just better understand their anatomy, check out the links below." +msgstr "Si quieres hacer cambios pero no quieres que se sobreescriban cuando se actualice el plugin, deberías pensar en escribir tu propio plugin. Para obtener información acerca de cómo editar plugins, escribir desde cero el tuyo, o simplemente entender mejor su anatomía, echa un vistazo a los enlaces de aquí abajo." + +#: wp-admin/plugin-editor.php:120 wp-admin/theme-editor.php:30 +msgid "Any edits to files from this screen will be reflected on all sites in the network." +msgstr "Cualquier modificación de los archivos se verá reflejada en todos los sitios de la red." + +#: wp-admin/plugin-editor.php:122 +msgid "Documentation on Editing Plugins" +msgstr "Documentación sobre cómo editar plugins" + +#: wp-admin/plugin-editor.php:123 +msgid "Documentation on Writing Plugins" +msgstr "Documentación sobre cómo escribir plugins" + +#: wp-admin/plugin-editor.php:138 +msgid "Function Name…" +msgstr "Nombre de la función…" + +#: wp-admin/plugin-editor.php:149 wp-admin/theme-editor.php:134 +msgid "File edited successfully." +msgstr "El archivo ha sido editado correctamente." + +#: wp-admin/plugin-editor.php:151 +msgid "This plugin has been deactivated because your changes resulted in a fatal error." +msgstr "El plugin ha sido desactivado porque tus cambios han provocado un error fatal." + +#: wp-admin/plugin-editor.php:167 +msgid "Editing %s (active)" +msgstr "Editando %s (activo)" + +#: wp-admin/plugin-editor.php:169 +msgid "Browsing %s (active)" +msgstr "Examinando %s (activo)" + +#: wp-admin/plugin-editor.php:172 +msgid "Editing %s (inactive)" +msgstr "Editando %s (inactivo)" + +#: wp-admin/plugin-editor.php:174 +msgid "Browsing %s (inactive)" +msgstr "Examinando %s (inactivo)" + +#: wp-admin/plugin-editor.php:180 +msgid "Select plugin to edit:" +msgstr "Elige el plugin a editar:" + +#: wp-admin/plugin-editor.php:195 wp-admin/theme-editor.php:164 +#: wp-admin/includes/template.php:1374 +#: wp-admin/includes/class-wp-plugins-list-table.php:392 +#: wp-admin/nav-menus.php:497 +msgid "Select" +msgstr "Elegir" + +#: wp-admin/plugin-editor.php:202 +msgid "Plugin Files" +msgstr "Archivos del plugin" + +#: wp-admin/plugin-editor.php:231 wp-admin/theme-editor.php:233 +msgid "Documentation:" +msgstr "Documentación:" + +#: wp-admin/plugin-editor.php:231 wp-admin/theme-editor.php:235 +msgid "Lookup" +msgstr "Buscar" + +#: wp-admin/plugin-editor.php:235 +msgid "Warning: Making changes to active plugins is not recommended. If your changes cause a fatal error, the plugin will be automatically deactivated." +msgstr "Atención: No es recomendable realizar cambios en plugins activos. Si tus cambios provocan un error fatal, el plugin se desactivará automáticamente." + +#: wp-admin/plugin-editor.php:241 +msgid "Update File and Attempt to Reactivate" +msgstr "Actualizar archivo e intentar reactivarlo" + +#: wp-admin/plugin-editor.php:243 wp-admin/theme-editor.php:246 +msgid "Update File" +msgstr "Actualizar archivo" + +#: wp-admin/plugin-editor.php:248 wp-admin/theme-editor.php:248 +msgid "You need to make this file writable before you can save your changes. See the Codex for more information." +msgstr "Para guardar los cambios, es necesario que el archivo tenga permisos de escritura. Visita el codex para obtener más información." + +#: wp-admin/plugin-install.php:16 +msgid "You do not have sufficient permissions to install plugins on this site." +msgstr "No tienes suficientes permisos para instalar plugins en este sitio." + +#: wp-admin/plugin-install.php:32 wp-admin/includes/template.php:1441 +msgid "Install Plugins" +msgstr "Instalar plugins" + +#: wp-admin/plugin-install.php:45 +msgid "Plugins hook into WordPress to extend its functionality with custom features. Plugins are developed independently from WordPress core by thousands of developers all over the world. All plugins in the official WordPress.org Plugin Directory are compatible with the WordPress GPL v2 license. You can find new plugins to install by searching or browsing the Directory right here in your own Plugins section." +msgstr "Los plugins se integran en WordPress para ampliar su funcionalidad con características personalizadas. Los plugins los desarrollan independientemente miles de desarrolladores de todo el mundo a partir del núcleo de WordPress. Todos los plugins del directorio oficial de plugins de WordPress.org son compatibles con la licencia GPL v2. Puedes encontrar nuevos plugins que instalar buscando o navegando por el directorio desde aquí mismo, en la sección de plugins." + +#: wp-admin/plugin-install.php:46 +msgid "If you know what you’re looking for, Search is your best bet. The Search screen has options to search the WordPress.org Plugin Directory for a particular Term, Author, or Tag. You can also search the directory by selecting a popular tags. Tags in larger type mean more plugins have been labeled with that tag." +msgstr "Si ya sabes lo que estás buscando la Búsqueda es tu mejor apuesta. La pantalla Buscar tiene opciones para buscar en el directorio de de plugins de WordPress.org un término concreto, por autor o por etiquetas. También puedes buscar en el directorio eligiendo entre las etiquetas populares. Las etiquetas de mayor tamaño significan que hay más plugins etiquetados con esa etiqueta." + +#: wp-admin/plugin-install.php:47 +msgid "If you just want to get an idea of what’s available, you can browse Featured, Popular, Newest, and Recently Updated plugins by using the links in the upper left of the screen. These sections rotate regularly." +msgstr "Si quieres hacerte una idea de lo que está disponible, puedes navegar por Destacados, Populares, Nuevos y Actualizados recientemente, usando los enlaces en la parte superior izquierda de la pantalla. Esta sección rota regularmente." + +#: wp-admin/plugin-install.php:48 +msgid "If you want to install a plugin that you’ve downloaded elsewhere, click Upload in the upper left. You will be prompted to upload the .zip package, and once uploaded, you can activate the new plugin." +msgstr "Si deseas instalar un plugin que has descargado de cualquier sitio, haz click en la parte superior izquierda. Se te preguntará por un archivo comprimido en .zip y, una vez subido, podrás activarlo." + +#: wp-admin/plugin-install.php:50 +msgid "Documentation on Installing Plugins" +msgstr "Documentación sobre cómo instalar plugins" + +#: wp-admin/link-parse-opml.php:90 +msgid "XML error: %1$s at line %2$s" +msgstr "Error de XML: %1$s en la línea %2$s" + +#: wp-admin/options-privacy.php:15 +msgid "Privacy Settings" +msgstr "Ajustes de privacidad" + +#: wp-admin/options-privacy.php:19 +msgid "You can choose whether or not your site will be crawled by robots, ping services, and spiders. If you want those services to ignore your site, click the second option here. Note that your privacy is not complete; your site is still visible on the web." +msgstr "Puedes decidir si tu sitio debe o no ser rastreado por robots, servicios de ping y arañas. Si deseas que todos esos servicios ignoren tu sitio, haz clic en la segunda opción. Atención, tu privacidad no es completa, tu sitio seguirá siendo visible en la web." + +#: wp-admin/options-privacy.php:20 +msgid "When this setting is in effect a reminder is shown in the header of these administration screens that says, “Search Engines Blocked,” to remind you that your site is not being crawled." +msgstr "Cuando este ajuste está activado se muestra un recordatorio en la cabecera de estas pantallas de administración que dice “Motores de búsqueda bloqueados,”, para recordarte que tu sitio no se está difundiendo." + +#: wp-admin/options-privacy.php:23 +msgid "Documentation on Privacy Settings" +msgstr "Documentación sobre Configuración de privacidad" + +#: wp-admin/options-privacy.php:39 wp-admin/options-privacy.php:40 +msgid "Site Visibility" +msgstr "Visibilidad del sitio" + +#: wp-admin/options-privacy.php:42 +msgid "I would like my site to be visible to everyone, including search engines (like Google, Bing, Technorati) and archivers" +msgstr "Quiero que mi sitio sea visible para todo el mundo, incluyendo buscadores (como Google, Bing, Technorati) y archivadores" + +#: wp-admin/options-privacy.php:44 +msgid "I would like to block search engines, but allow normal visitors" +msgstr "Quiero bloquear los motores de búsqueda, pero permitir visitantes normales." + +#: wp-admin/theme-editor.php:18 +msgid "You do not have sufficient permissions to edit templates for this site." +msgstr "No tienes suficientes permisos para editar las plantillas de este sitio." + +#: wp-admin/theme-editor.php:20 +msgid "Edit Themes" +msgstr "Editar temas" + +#: wp-admin/theme-editor.php:23 +msgid "You can use the Theme Editor to edit the individual CSS and PHP files which make up your theme." +msgstr "Puedes usar el Editor de temas para editar de forma individual los archivos css y php que crean la apariencia de tu sitio." + +#: wp-admin/theme-editor.php:24 +msgid "Begin by choosing a theme to edit from the dropdown menu and clicking Select. A list then appears of all the template files. Clicking once on any file name causes the file to appear in the large Editor box." +msgstr "Comienza seleccionando qué tema quieres editar en el menú desplegable y haz clic en Elegir. Una lista de todas las plantillas aparecerá. Apretando una vez sobre el nombre de un archivo, éste aparecerá en la gran caja de edición." + +#: wp-admin/theme-editor.php:25 +msgid "For PHP files, you can use the Documentation dropdown to select from functions recognized in that file. Lookup takes you to a web page with reference material about that particular function." +msgstr "Para los archivos PHP, puedes usar el menú desplegable de Documentación para elegir las funciones reconocidas que son usadas en ese archivo. Buscar te lleva a una página con material de referencia de esa función en particular." + +#: wp-admin/theme-editor.php:26 +msgid "After typing in your edits, click Update File." +msgstr "Después de introducir tus modificaciones, haz click en Actualizar archivo." + +#: wp-admin/theme-editor.php:27 +msgid "Advice: think very carefully about your site crashing if you are live-editing the theme currently in use." +msgstr "Advertencia: piensa detenidamente en la posibilidad de que tu sitio produzca errores y sea inaccesible si estás editando el tema en uso y cometes algún error." + +#: wp-admin/theme-editor.php:28 +msgid "Upgrading to a newer version of the same theme will override changes made here. To avoid this, consider creating a child theme instead." +msgstr "Si actualizas a una versión más reciente del mismo tema sobreescribirá los cambios realizados aquí. Para evitar esto plantéate crear un tema hijo (child theme) en su lugar." + +#: wp-admin/theme-editor.php:32 +msgid "Documentation on Theme Development" +msgstr "Documentación sobre el desarrollo de temas" + +#: wp-admin/theme-editor.php:34 +msgid "Documentation on Editing Files" +msgstr "Documentación sobre cómo editar archivos" + +#: wp-admin/theme-editor.php:35 +msgid "Documentation on Template Tags" +msgstr "Documentación sobre etiquetas de plantilla" + +#: wp-admin/theme-editor.php:52 +msgid "The requested theme does not exist." +msgstr "El tema solicitado no existe." + +#: wp-admin/theme-editor.php:122 +msgid "Function Name..." +msgstr "Nombre de la función..." + +#: wp-admin/theme-editor.php:152 +msgid "Select theme to edit:" +msgstr "Elige el tema a editar:" + +#: wp-admin/theme-editor.php:173 +msgid "Templates" +msgstr "Plantillas" + +#: wp-admin/theme-editor.php:175 +msgid "This child theme inherits templates from a parent theme, %s." +msgstr "Este tema hijo hereda plantillas de un tema padre, %s." + +#: wp-admin/theme-editor.php:198 +msgctxt "Theme stylesheets in theme editor" +msgid "Styles" +msgstr "Estilos" + +#: wp-admin/theme-editor.php:241 wp-admin/comment.php:151 +#: wp-admin/plugins.php:253 +msgid "Caution:" +msgstr "Atención:" + +#: wp-admin/theme-editor.php:242 +msgid "This is a file in your current parent theme." +msgstr "Este es un archivo del tema padre actual." + +#: wp-admin/theme-editor.php:254 +msgid "Oops, no such file exists! Double check the name and try again, merci." +msgstr "¡El archivo no existe! Comprueba el nombre e inténtalo de nuevo, gracias." + +#: wp-admin/install.php:60 +msgid "WordPress › Installation" +msgstr "Instalación de WordPress" + +#: wp-admin/install.php:92 +msgid "ERROR: %s" +msgstr "ERROR: %s" + +#: wp-admin/install.php:105 +msgid "User(s) already exists." +msgstr "El (los) usuario(s) ya existe(n)." + +#: wp-admin/install.php:108 +msgid "Usernames can have only alphanumeric characters, spaces, underscores, hyphens, periods and the @ symbol." +msgstr "Los nombres de usuario sólo pueden tener caracteres alfanuméricos, espacios, guiones bajos, guiones, puntos y el símbolo @." + +#: wp-admin/install.php:116 +msgid "Password, twice" +msgstr "Password, dos veces" + +#: wp-admin/install.php:117 +msgid "A password will be automatically generated for you if you leave this blank." +msgstr "Se generará un password automático si lo dejas en blanco. " + +#: wp-admin/install.php:128 +msgid "Your E-mail" +msgstr "Tu correo electrónico" + +#: wp-admin/install.php:130 +msgid "Double-check your email address before continuing." +msgstr "Comprueba bien tu dirección de correo electrónico antes de continuar." + +#: wp-admin/install.php:133 +msgid "Allow my site to appear in search engines like Google and Technorati." +msgstr "Permitir que mi sitio aparezca en motores de búsqueda como Google y Technorati." + +#: wp-admin/install.php:136 +msgid "Install WordPress" +msgstr "Instalar WordPress" + +#: wp-admin/install.php:144 +msgid "Already Installed" +msgstr "Ya está instalado" + +#: wp-admin/install.php:144 +msgid "You appear to have already installed WordPress. To reinstall please clear your old database tables first." +msgstr "WordPress parece estar ya instalado. Si deseas reinstalar, por favor, borra las tablas de la base de datos." + +#: wp-admin/install.php:153 +msgid "You cannot install because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s." +msgstr "No puedes instalar ya que WordPress %1$s requiere la versión %2$s o superior de PHP y la versión %3$s o superior de MySQL. Estás usando la versión %4$s de PHP y la versión %5$s de MySQL." + +#: wp-admin/install.php:155 +msgid "You cannot install because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s." +msgstr "No puedes instalar porque WordPress %1$s requiere la versión %2$s o superior de PHP. Estás usando la versión %3$s." + +#: wp-admin/install.php:157 +msgid "You cannot install because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s." +msgstr "No puedes instalar porque WordPress %1$s requiere la versión %2$s o superior de MySQL. Estás usando la versión %3$s." + +#: wp-admin/install.php:161 +msgid "Insufficient Requirements" +msgstr "Requisitos Insuficientes" + +#: wp-admin/install.php:169 +msgid "Welcome" +msgstr "Bienvenido" + +#: wp-admin/install.php:170 +msgid "Welcome to the famous five minute WordPress installation process! You may want to browse the ReadMe documentation at your leisure. Otherwise, just fill in the information below and you’ll be on your way to using the most extendable and powerful personal publishing platform in the world." +msgstr "¡Bienvenido al famoso proceso de instalación de WordPress de cinco minutos! Tal vez quieras leer tranquilamente la Documentación del archivo Léeme. En caso contrario, rellena los datos más abajo y en seguida estarás utilizando la plataforma de publicación personal más potente y extensible del mundo." + +#: wp-admin/install.php:172 +msgid "Information needed" +msgstr "Información necesaria" + +#: wp-admin/install.php:173 +msgid "Please provide the following information. Don’t worry, you can always change these settings later." +msgstr "Por favor, debes facilitarnos los siguientes datos. No te preocupes, siempre podrás cambiar estos ajustes más tarde." + +#: wp-admin/install.php:194 +msgid "you must provide a valid username." +msgstr "debes proporcionar un nombre de usuario válido." + +#: wp-admin/install.php:197 +msgid "the username you provided has invalid characters." +msgstr "el nombre de usuario proporcionado tiene caracteres inválidos." + +#: wp-admin/install.php:201 +msgid "your passwords do not match. Please try again" +msgstr "Las contraseñas introducidas no coinciden. Por favor, prueba de nuevo" + +#: wp-admin/install.php:205 +msgid "you must provide an e-mail address." +msgstr "debes proporcionar un correo electrónico." + +#: wp-admin/install.php:209 +msgid "that isn’t a valid e-mail address. E-mail addresses look like: username@example.com" +msgstr "esa no es una dirección de correo electrónico válido. Una dirección bien formada tiene este aspecto: usuario@ejemplo.com" + +#: wp-admin/install.php:219 +msgid "Success!" +msgstr "¡Lo lograste!" + +#: wp-admin/install.php:221 +msgid "WordPress has been installed. Were you expecting more steps? Sorry to disappoint." +msgstr "Wordpress se ha instalado correctamente. ¿Esperabas más pasos? Sentimos decepcionarte. :)" + +#: wp-admin/tools.php:12 wp-admin/menu.php:209 wp-admin/menu.php:210 +msgid "Tools" +msgstr "Herramientas" + +#: wp-admin/tools.php:15 +msgid "Press This is a bookmarklet that makes it easy to blog about something you come across on the web. You can use it to just grab a link, or to post an excerpt. Press This will even allow you to choose from images included on the page and use them in your post. Just drag the Press This link on this screen to your bookmarks bar in your browser, and you’ll be on your way to easier content creation. Clicking on it while on another website opens a popup window with all these options." +msgstr "" +"Publicar esto es un marcador de enlaces que hace fácil bloguear sobre algo con lo que te hayas topado en la web. Puedes usarlo para guardar un enlace, para publicar un resumen del mismo. Publicar esto te permite elegir de entre las imágenes de esa página cuál se utilizará para tu entrada. \n" +"Sólo tienes que arrastrar el enlace de Publicar esto de esta pantalla a la barra de enlaces favoritos de tu navegador y tendrás la forma más fácil de crear contenido. Haciendo clic en él mientras estés visitando cualquier sitio web se abre una ventana emergente con las opciones mencionadas. " + +#: wp-admin/tools.php:16 +msgid "The Use This link for the Categories and Tags Converter will take you to the Import page, where that Converter is one of the plugins you can download. Once installed, the link on this page takes you to a screen where you can choose conversion either way." +msgstr "El usar este vínculo para el conversor de categorías y etiquetas te llevará a la página de importación, donde dicho conversor es uno de los plugins que puedes descargar. Una vez instalado, el enlace en esta página te llevará a una pantalla donde se puede elegir la conversión en cualquier sentido." + +#: wp-admin/tools.php:17 +msgid "Note: Turbo/Gears is no longer promoted on this screen as it was in previous versions due to the fact that Google has discontinued support for it." +msgstr "Nota: Turbo/Gears ya no está disponible en esta pantalla como en versiones anteriores ya que Google ha dejado de darle soporte." + +#: wp-admin/tools.php:19 +msgid "Documentation on Tools" +msgstr "Documentación sobre Herramientas" + +#: wp-admin/tools.php:32 wp-admin/tools.php:37 wp-admin/options-writing.php:88 +#: wp-admin/options-writing.php:92 wp-admin/includes/dashboard.php:486 +#: wp-admin/press-this.php:327 wp-admin/press-this.php:477 +msgid "Press This" +msgstr "Publicar esto" + +#: wp-admin/tools.php:33 wp-admin/options-writing.php:89 +msgid "Press This is a bookmarklet: a little app that runs in your browser and lets you grab bits of the web." +msgstr "Publicar esto es un marcador: una pequeña aplicación que se ejecuta en el navegador y permite coger secciones de la web." + +#: wp-admin/tools.php:35 wp-admin/options-writing.php:90 +msgid "Use Press This to clip text, images and videos from any web page. Then edit and add more straight from Press This before you save or publish it in a post on your site." +msgstr "Utiliza Publicar esto para copiar texto, imágenes y vídeos de cualquier página Web. Después corrige y añade más directamente desde Publicar esto antes de guardarlo o publicarlo en una entrada del sitio." + +#: wp-admin/tools.php:36 wp-admin/options-writing.php:91 +msgid "Drag-and-drop the following link to your bookmarks bar or right click it and add it to your favorites for a posting shortcut." +msgstr "Arrastra el siguente enlace y colócalo en tu barra de marcadores o haz clic con el botón derecho para añadirlo en tu lista de favoritos como un atajo de publicación de entradas." + +#: wp-admin/tools.php:47 wp-admin/import.php:31 +msgid "Categories and Tags Converter" +msgstr "Conversor de etiquetas y categorías" + +#: wp-admin/tools.php:48 +msgid "Use this to convert categories to tags or tags to categories." +msgstr "Usa esto para convertir categorías en etiquetas o etiquetas en categorías." + +#: wp-admin/edit-form-advanced.php:39 +msgid "Post updated. View post" +msgstr "Entrada actualizada. Vista previa" + +#: wp-admin/edit-form-advanced.php:40 wp-admin/edit-form-advanced.php:56 +msgid "Custom field updated." +msgstr "Campo personalizado actualizado." + +#: wp-admin/edit-form-advanced.php:41 wp-admin/edit-form-advanced.php:57 +msgid "Custom field deleted." +msgstr "Campo personalizado borrado." + +#: wp-admin/edit-form-advanced.php:42 +msgid "Post updated." +msgstr "Entrada actualizada." + +#: wp-admin/edit-form-advanced.php:44 +msgid "Post restored to revision from %s" +msgstr "Entrada restaurada a la revisión %s" + +#: wp-admin/edit-form-advanced.php:45 +msgid "Post published. View post" +msgstr "Entrada publicada. Ver entrada" + +#: wp-admin/edit-form-advanced.php:46 +msgid "Post saved." +msgstr "Entrada guardada." + +#: wp-admin/edit-form-advanced.php:47 +msgid "Post submitted. Preview post" +msgstr "Entrada enviada. Vista previa" + +#: wp-admin/edit-form-advanced.php:48 +msgid "Post scheduled for: %1$s. Preview post" +msgstr "Entrada programada el: %1$s. Vista previa" + +#: wp-admin/edit-form-advanced.php:50 wp-admin/edit-form-advanced.php:63 +#: wp-admin/includes/meta-boxes.php:159 wp-admin/edit-form-comment.php:58 +msgid "M j, Y @ G:i" +msgstr "j F Y G:i a" + +#: wp-admin/edit-form-advanced.php:51 +msgid "Post draft updated. Preview post" +msgstr "Entrada actualizada. Vista previa" + +#: wp-admin/edit-form-advanced.php:55 +msgid "Page updated. View page" +msgstr "Página actualizada. Vista previa" + +#: wp-admin/edit-form-advanced.php:58 +msgid "Page updated." +msgstr "Página actualizada." + +#: wp-admin/edit-form-advanced.php:59 +msgid "Page restored to revision from %s" +msgstr "Página restaurada desde la revisión %s" + +#: wp-admin/edit-form-advanced.php:60 +msgid "Page published. View page" +msgstr "Página publicada. Vista previa" + +#: wp-admin/edit-form-advanced.php:61 +msgid "Page saved." +msgstr "Página guardada." + +#: wp-admin/edit-form-advanced.php:62 +msgid "Page submitted. Preview page" +msgstr "Página enviada. Vista previa" + +#: wp-admin/edit-form-advanced.php:63 +msgid "Page scheduled for: %1$s. Preview page" +msgstr "Página programada para: %1$s. Vista previa" + +#: wp-admin/edit-form-advanced.php:64 +msgid "Page draft updated. Preview page" +msgstr "Borrador de página actualizado. Vista previa" + +#: wp-admin/edit-form-advanced.php:97 +msgid "There is an autosave of this post that is more recent than the version below. View the autosave" +msgstr "Hay una copia automática de esta entrada con fecha más reciente que la de la versión mostrada. Ver la copia automática" + +#: wp-admin/edit-form-advanced.php:129 +msgid "Page Attributes" +msgstr "Atributos de página" + +#: wp-admin/edit-form-advanced.php:129 +msgid "Attributes" +msgstr "Atributos" + +#: wp-admin/edit-form-advanced.php:133 +msgid "Featured Image" +msgstr "Imagen destacada" + +#: wp-admin/edit-form-advanced.php:139 +msgid "Send Trackbacks" +msgstr "Enviar trackbacks" + +#: wp-admin/edit-form-advanced.php:142 +msgid "Custom Fields" +msgstr "Campos personalizados" + +#: wp-admin/edit-form-advanced.php:146 wp-admin/includes/dashboard.php:317 +#: wp-admin/menu.php:222 +msgid "Discussion" +msgstr "Comentarios" + +#: wp-admin/edit-form-advanced.php:152 +#: wp-admin/includes/class-wp-posts-list-table.php:747 +#: wp-admin/includes/class-wp-terms-list-table.php:102 +#: wp-admin/includes/class-wp-terms-list-table.php:343 +#: wp-admin/includes/meta-boxes.php:510 +msgid "Slug" +msgstr "Slug" + +#: wp-admin/edit-form-advanced.php:173 +msgid "The title field and the big Post Editing Area are fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of the box. Use the Screen Options tab to unhide more boxes (Excerpt, Send Trackbacks, Custom Fields, Discussion, Slug, Author) or to choose a 1- or 2-column layout for this screen." +msgstr "El campo de título y el área de edición de entradas son fijas, pero puedes cambiar de sitio todas demás cajas cogiéndolas y arrastrándolas, además de minimizarlas o expandirlas haciendo clic en el barra del título de la caja. Utiliza la pestaña de la pantalla de opciones para mostrar más cajas (Extracto, Enviar trackbacks, Campos personalizados, Discusión, Slug y Autor) o para elegir una presentación de 1 ó 2 columnas." + +#: wp-admin/edit-form-advanced.php:174 +msgid "Title - Enter a title for your post. After you enter a title, you’ll see the permalink below, which you can edit." +msgstr "Título - Introduce el título de tu entrada. Después de introducir el título, podrás ver el enlace permanente el cual podrás editar." + +#: wp-admin/edit-form-advanced.php:175 +msgid "Post editor - Enter the text for your post. There are two modes of editing: Visual and HTML. Choose the mode by clicking on the appropriate tab. Visual mode gives you a WYSIWYG editor. Click the last icon in the row to get a second row of controls. The screen icon just before that allows you to expand the edit box to full screen. The HTML mode allows you to enter raw HTML along with your post text. You can insert media files by clicking the icons above the post editor and following the directions." +msgstr "Editor de entradas - Escribe el texto para tu entrada. Hay dos maneras de editar: Visual y HTML. Elige la manera que prefieras haciendo clic en la pestaña correspondiente. La manera visual te ofrece un editor WYSIWYG (denominado así por What You See Is What You Get. en inglés, Lo Que Ves Es Lo Que Obtendrás). Haz clic en el último icono para ver una segunda línea de botones. El icono que parece una pantalla que hay justo antes te muestra a pantalla completa el editor. El manera HTML te permite poner código HTML directamente, además del texto de tu entrada. Puede poner archivos multimedia haciendo clic en los iconos que hay en la parte superior del editor, siguiendo las instrucciones que te aparecerán tras hacerlo." + +#: wp-admin/edit-form-advanced.php:176 +msgid "Publish - You can set the terms of publishing your post in the Publish box. For Status, Visibility, and Publish (immediately), click on the Edit link to reveal more options. Visibility includes options for password-protecting a post or making it stay at the top of your blog indefinitely (sticky). Publish (immediately) allows you to set a future or past date and time, so you can schedule a post to be published in the future or backdate a post." +msgstr "Publicar - Puedes fijar las características de publicación en la caja de publicación. Para el estado, visibilidad y publicar (inmediatamente), haz clic en el enlace \"editar\" para ver más opciones. La visibilidad incluye opciones para proteger una entrada con contraseña o para hacer que se quede en la parte superior de tu sitio indefinidamente (entrada fija). Publicar (inmediatamente) te permite fijar una fecha de publicación pasada o futura, con lo que puedes programar una entrada para publicarse después o atrasar la fecha de una entrada." + +#: wp-admin/edit-form-advanced.php:177 +msgid "Post Format - This designates how your theme will display a specific post. For example, you could have a standard blog post with a title and paragraphs, or a short aside that omits the title and contains a short text blurb. Please refer to the Codex for descriptions of each post format." +msgstr "Formatos de entrada - Indica cómo tu tema mostrará una entrada concreta. Por ejemplo, podrías tener una entrada estándar con un título y párrafos, o una mera cita, omitiendo el título y que contuviera una pequeña viñeta con el texto. Por favor, consulta en el Codex lasdescripciones de cada formato de entrada." + +#: wp-admin/edit-form-advanced.php:178 +msgid "Featured Image - This allows you to associate an image with your post without inserting it. This is usually useful only if your theme makes use of the featured image as a post thumbnail on the home page, a custom header, etc." +msgstr "Imagen destacada - Esto te permite asociar una imagen con su entrada sin tener que insertarla, Es útil sólo si tu tema usa la imagen destacada para mostrar una miniatura en la página de inicio, en una cabecera personalizada, etc." + +#: wp-admin/edit-form-advanced.php:179 +msgid "Send Trackbacks - Trackbacks are a way to notify legacy blog systems that you’ve linked to them. Enter the URL(s) you want to send trackbacks. If you link to other WordPress sites they’ll be notified automatically using pingbacks, and this field is unnecessary." +msgstr "Enviar trackbacks - Los trackbacks son un modo de avisar a los sistemas antiguos de blogs que les has enlazado. Introduce la(s) URL(s) a la(s) que quieres enviar trackbacks. Si enlazas a otro sitio creado con WordPress recibirán aviso automáticamente por medio de los pingbacks, y este campo no sería necesario." + +#: wp-admin/edit-form-advanced.php:180 +msgid "Discussion - You can turn comments and pings on or off, and if there are comments on the post, you can see them here and moderate them." +msgstr "Comentarios - Puedes activar o desactivar los comentarios y pings, y si hay comentario en las entradas, puedes verlos aquí y moderarlos." + +#: wp-admin/edit-form-advanced.php:181 +msgid "You can also create posts with the Press This bookmarklet." +msgstr "También puedes crear entradas con el marcador Publicar esto." + +#: wp-admin/edit-form-advanced.php:183 +msgid "Documentation on Writing and Editing Posts" +msgstr "Documentación sobre escribir y editar entradas" + +#: wp-admin/edit-form-advanced.php:187 wp-admin/edit.php:178 +msgid "Pages are similar to Posts in that they have a title, body text, and associated metadata, but they are different in that they are not part of the chronological blog stream, kind of like permanent posts. Pages are not categorized or tagged, but can have a hierarchy. You can nest Pages under other Pages by making one the “Parent” of the other, creating a group of Pages." +msgstr "Las páginas son similares a las entradas y tienen título, cuerpo de texto y metadatos asociados, pero son diferentes en que no forman parte de la secuencia cronológica tipo blog, son una especie de entradas permanentes. Las páginas no tienen categorías ni etiquetas, pero pueden tener una jerarquía. Puedes anidar páginas bajo otras páginas haciendo a una “Superior” de otra, creando así un grupo de páginas." + +#: wp-admin/edit-form-advanced.php:188 +msgid "Creating a Page is very similar to creating a Post, and the screens can be customized in the same way using drag and drop, the Screen Options tab, and expanding/collapsing boxes as you choose. The Page editor mostly works the same Post editor, but there are some Page-specific features in the Page Attributes box:" +msgstr "Crear una página es muy similar a crear una entrada y la pantalla puede personalizarse de la misma forma, usando arrastrar y soltar, mediante la pestaña Opciones de pantalla, desplegando/cerrando cajas. La edición de páginas funciona prácticamente igual que la edición de entradas, pero hay una serie de características específicas en la caja de Atributos:" + +#: wp-admin/edit-form-advanced.php:189 +msgid "Parent - You can arrange your pages in hierarchies. For example, you could have an “About” page that has “Life Story” and “My Dog” pages under it. There are no limits to how many levels you can nest pages." +msgstr "Superiores - Puedes ordenar tus páginas en jerarquías. Por ejemplo, podrías tener una página “Sobre” que bajo ella las páginas “Historia de mi vida” y “Mi perro”. No hay límites en cuántos niveles puedes anidar páginas." + +#: wp-admin/edit-form-advanced.php:190 +msgid "Template - Some themes have custom templates you can use for certain pages that might have additional features or custom layouts. If so, you’ll see them in this dropdown menu." +msgstr "Plantilla - Algunos temas tienen plantillas personalizadas que pueden usarse para añadir algunas características adicionales o diseños personalizados. Si las hay, las encontrarás en el menú desplegable." + +#: wp-admin/edit-form-advanced.php:191 +msgid "Order - Pages are usually ordered alphabetically, but you can choose your own order by entering a number (1 for first, etc.) in this field." +msgstr "Orden - Normalmente las páginas se ordenan alfabéticamente, pero puedes elegir tu propio orden introduciendo un número (1 para la primera, etc) en este campo." + +#: wp-admin/edit-form-advanced.php:193 +msgid "Documentation on Adding New Pages" +msgstr "Documentación sobre añadir nuevas páginas" + +#: wp-admin/edit-form-advanced.php:194 +msgid "Documentation on Editing Pages" +msgstr "Documentación sobre editar páginas" + +#: wp-admin/edit-form-advanced.php:246 +msgid "Enter title here" +msgstr "Introduce el título aquí" + +#: wp-admin/edit-form-advanced.php:254 +msgid "Get Shortlink" +msgstr "Obtener enlace corto" + +#: wp-admin/edit-form-advanced.php:287 +msgid "Last edited by %1$s on %2$s at %3$s" +msgstr "Última edición por %1$s el %2$s a las %3$s" + +#: wp-admin/edit-form-advanced.php:289 +msgid "Last edited on %1$s at %2$s" +msgstr "Última edición el %1$s a las %2$s" + +#: wp-admin/async-upload.php:29 wp-admin/upload.php:13 +#: wp-admin/media-upload.php:19 wp-app.php:599 wp-app.php:787 +msgid "You do not have permission to upload files." +msgstr "No tienes autorización para subir archivos." + +#: wp-admin/async-upload.php:35 wp-admin/post.php:158 +msgid "Unknown post type." +msgstr "Tipo de entrada desconocida." + +#: wp-admin/async-upload.php:38 wp-admin/post.php:152 +#: wp-admin/edit-tags.php:227 +msgid "You are not allowed to edit this item." +msgstr "No tienes autorización para editar esto." + +#: wp-admin/comment.php:46 wp-admin/edit-form-comment.php:16 +#: wp-admin/edit-form-comment.php:27 +msgid "Edit Comment" +msgstr "Editar comentario" + +#: wp-admin/comment.php:48 +msgid "You can edit the information left in a comment if needed. This is often useful when you notice that a commenter has made a typographical error." +msgstr "Si te es necesario puedes editar la información que falta en un comentario. Esto es muy útil si te advierten que un usuario ha cometido un error tipográfico al realizar un comentario." + +#: wp-admin/comment.php:49 +msgid "You can also moderate the comment from this screen using the Status box, where you can also change the timestamp of the comment." +msgstr "También puedes moderar los comentarios desde esta pantalla usando la caja de estado, donde puedes cambiar el día/hora del comentario." + +#: wp-admin/comment.php:51 wp-admin/edit-comments.php:127 +msgid "Documentation on Comments" +msgstr "Documentación sobre comentarios" + +#: wp-admin/comment.php:52 +msgid "Support Forums" +msgstr "Foros de soporte (en inglés)" + +#: wp-admin/comment.php:61 wp-admin/comment.php:215 +#: wp-admin/edit-comments.php:158 +msgid "Oops, no comment with this ID." +msgstr "Vaya, no hay comentarios con ese ID." + +#: wp-admin/comment.php:61 wp-admin/comment.php:215 +msgid "Go back" +msgstr "Volver atrás" + +#: wp-admin/comment.php:64 +msgid "You are not allowed to edit this comment." +msgstr "No tienes permiso para editar este comentario." + +#: wp-admin/comment.php:67 +msgid "This comment is in the Trash. Please move it out of the Trash if you want to edit it." +msgstr "Este comentario está en la papelera. Por favor, sácalo de la papelera si quieres editarlo." + +#: wp-admin/comment.php:80 +msgid "Moderate Comment" +msgstr "Comentario moderado" + +#: wp-admin/comment.php:117 +msgid "You are about to mark the following comment as spam:" +msgstr "Estás a punto de marcar el siguiente comentario como spam:" + +#: wp-admin/comment.php:118 +msgid "Spam Comment" +msgstr "Comentario spam" + +#: wp-admin/comment.php:121 +msgid "You are about to move the following comment to the Trash:" +msgstr "Estás a punto de mover el siguiente comentario a la basura:" + +#: wp-admin/comment.php:122 +msgid "Trash Comment" +msgstr "Enviar comentario a la papelera" + +#: wp-admin/comment.php:125 +msgid "You are about to delete the following comment:" +msgstr "Estás a punto de borrar el siguiente comentario:" + +#: wp-admin/comment.php:126 +msgid "Permanently Delete Comment" +msgstr "Borrar comentario permanentemente" + +#: wp-admin/comment.php:129 +msgid "You are about to approve the following comment:" +msgstr "Estás a punto de aprobar el siguiente comentario:" + +#: wp-admin/comment.php:130 +msgid "Approve Comment" +msgstr "Aprobar comentario" + +#: wp-admin/comment.php:138 +msgid "This comment is currently approved." +msgstr "Este comentario está aprobado." + +#: wp-admin/comment.php:141 +msgid "This comment is currently marked as spam." +msgstr "Este comentario está marcado como spam." + +#: wp-admin/comment.php:144 +msgid "This comment is currently in the Trash." +msgstr "Este comentario está actualmente en la papelera." + +#: wp-admin/comment.php:166 wp-admin/includes/media.php:2207 +#: wp-admin/includes/internal-linking.php:79 wp-admin/includes/template.php:361 +#: wp-admin/includes/template.php:730 wp-admin/includes/nav-menu.php:123 +#: wp-admin/includes/nav-menu.php:531 +#: wp-admin/includes/class-wp-links-list-table.php:81 +#: wp-admin/press-this.php:180 +msgid "URL" +msgstr "URL" + +#: wp-admin/comment.php:217 wp-admin/edit-comments.php:161 +#: wp-admin/includes/comment.php:37 +msgid "You are not allowed to edit comments on this post." +msgstr "No tienes autorización para editar comentarios en esta entrada." + +#: wp-admin/comment.php:282 wp-admin/includes/media.php:1745 +msgid "Unknown action." +msgstr "Acción desconocida." + +#: wp-admin/edit-comments.php:114 wp-admin/edit-comments.php:139 +msgid "Comments on “%s”" +msgstr "Comentarios en “%s”" + +#: wp-admin/edit-comments.php:118 +msgctxt "comments per page (screen options)" +msgid "Comments" +msgstr "Comentarios" + +#: wp-admin/edit-comments.php:120 +msgid "You can manage comments made on your site similar to the way you manage Posts and other content. This screen is customizable in the same ways as other management screens, and you can act on comments using the on-hover action links or the Bulk Actions." +msgstr "Puedes gestionar los comentarios realizados en tu sitio de forma similar a la que gestionas las Entradas y otros contenidos. Esta pantalla es personalizable, de la misma forma que las otras pantallas de gestión. Puedes actuar sobre cada comentario usando los enlaces de acción que aparecerán al ponerte sobre ellos o utilizando la Acción en lote." + +#: wp-admin/edit-comments.php:121 +msgid "A yellow row means the comment is waiting for you to moderate it." +msgstr "Una fila amarilla significa que el comentario está esperando a que lo moderes." + +#: wp-admin/edit-comments.php:122 +msgid "In the Author column, in addition to the author’s name, email address, and blog URL, the commenter’s IP address is shown. Clicking on this link will show you all the comments made from this IP address." +msgstr "En la columna Autor, además del nombre del autor, la dirección de correo electrónico y la url del sitio se muestra la dirección IP del que ha realizado el comentario. Haciendo clic en este enlace te mostrará todos los comentarios realizados desde esa dirección IP." + +#: wp-admin/edit-comments.php:123 +msgid "In the Comment column, above each comment it says “Submitted on,” followed by the date and time the comment was left on your site. Clicking on the date/time link will take you to that comment on your live site." +msgstr "En la columna Comentario, encima de cada comentario, dice “Enviado el,” seguido de la fecha y hora en que se dejó el comentario en tu sitio. Haciendo clic en el enlace de la fecha/hora te llevará a ese comentario en tu sitio." + +#: wp-admin/edit-comments.php:124 +msgid "In the In Response To column, there are three elements. The text is the name of the post that inspired the comment, and links to the post editor for that entry. The “#” permalink symbol below leads to that post on your live site. The small bubble with the number in it shows how many comments that post has received. If the bubble is gray, you have moderated all comments for that post. If it is blue, there are pending comments. Clicking the bubble will filter the comments screen to show only comments on that post." +msgstr "En la columna En respuesta a hay tres elementos. El texto es el nombre de la entrada que inspiró el comentario, y está enlazado al editor de entradas de esa entrada. El enlace permanente del símbolo “#” lleva a esa entrada en tu sitio. La pequeña burbuja con número muestra cuántos comentarios ha recibido esa entrada. Si la burbuja es gris es que ya has moderado todos los comentarios de esa entrada. Si es azul es que hay comentarios pendientes. Haciendo clic en la burbuja se filtra la pantalla de comentarios para que muestre sólo los comentarios de esa entrada." + +#: wp-admin/edit-comments.php:125 +msgid "Many people take advantage of keyboard shortcuts to moderate their comments more quickly. Use the link below to learn more." +msgstr "Mucha gente saca partido a los atajos de teclado para moderar comentarios de forma rápida. Utiliza el siguiente enlace para aprender más." + +#: wp-admin/edit-comments.php:128 +msgid "Documentation on Comment Spam" +msgstr "Documentación sobre los comentarios de spam" + +#: wp-admin/edit-comments.php:129 +msgid "Documentation on Keyboard Shortcuts" +msgstr "Documentación sobre atajos de teclado" + +#: wp-admin/edit-comments.php:179 +msgid "%s comment approved" +msgid_plural "%s comments approved" +msgstr[0] "%s comentario aprobado" +msgstr[1] "%s comentarios aprobados" + +#: wp-admin/edit-comments.php:183 +msgid "%s comment marked as spam." +msgid_plural "%s comments marked as spam." +msgstr[0] "%s comentario marcado como spam." +msgstr[1] "%s comentarios marcados como spam." + +#: wp-admin/edit-comments.php:187 +msgid "%s comment restored from the spam" +msgid_plural "%s comments restored from the spam" +msgstr[0] "%s comentario recuperado de spam" +msgstr[1] "%s comentarios recuperados de spam" + +#: wp-admin/edit-comments.php:191 +msgid "%s comment moved to the Trash." +msgid_plural "%s comments moved to the Trash." +msgstr[0] "%s comentario movido a la papelera." +msgstr[1] "%s comentarios movidos a la papelera." + +#: wp-admin/edit-comments.php:195 +msgid "%s comment restored from the Trash" +msgid_plural "%s comments restored from the Trash" +msgstr[0] "%s comentario restaurado de la papelera" +msgstr[1] "%s comentarios restaurados de la papelera" + +#: wp-admin/edit-comments.php:198 +msgid "%s comment permanently deleted" +msgid_plural "%s comments permanently deleted" +msgstr[0] "%s comentario borrado permanentemente" +msgstr[1] "%s comentarios borrados permanentemente" + +#: wp-admin/edit-comments.php:203 +msgid "This comment is already approved." +msgstr "Este comentario ya está aprobado." + +#: wp-admin/edit-comments.php:206 +msgid "This comment is already in the Trash." +msgstr "Este comentario ya está en la papelera." + +#: wp-admin/edit-comments.php:206 +msgid "View Trash" +msgstr "Ver papelera" + +#: wp-admin/edit-comments.php:209 +msgid "This comment is already marked as spam." +msgstr "Este comentario ya ha sido marcado como spam." + +#: wp-admin/edit-comments.php:223 +msgid "Search Comments" +msgstr "Buscar comentarios" + +#: wp-admin/import.php:15 +msgid "You do not have sufficient permissions to import content in this site." +msgstr "No tienes suficientes permisos para importar contenidos en este sitio." + +#: wp-admin/import.php:17 wp-admin/menu.php:211 wp-admin/admin.php:197 +msgid "Import" +msgstr "Importar" + +#: wp-admin/import.php:20 +msgid "This screen lists links to plugins to import data from blogging/content management platforms. Choose the platform you want to import from, and click Install Now when you are prompted in the popup window. If your platform is not listed, click the link to search the plugin directory for other importer plugins to see if there is one for your platform." +msgstr "Esta pantalla lista los enlaces a los plugins de importación de datos de blogs/contenido de diferentes plataformas. Elige la plataforma desde la que quieres importar datos y haz clic en Instalar ahora cuando seas preguntado en la ventana emergente. Si tu plataforma no está en la lista, haz clic en el enlace de buscar en el directorio de plugins para ver si hay uno para tu plataforma." + +#: wp-admin/import.php:21 +msgid "In previous versions of WordPress, all the importers were built-in, but they have been turned into plugins as of version 3.0 since most people only use them once or infrequently." +msgstr "En versiones anteriores de WordPress, todos los importadores estaban incluidos. Ahora han sido convertidos en plugins para la versión 3.0. Mucha gente sólo lo utilizaba una vez o ni eso." + +#: wp-admin/import.php:23 +msgid "Documentation on Import" +msgstr "Documentación sobre importación" + +#: wp-admin/import.php:30 +msgid "Blogger" +msgstr "Blogger" + +#: wp-admin/import.php:30 +msgid "Install the Blogger importer to import posts, comments, and users from a Blogger blog." +msgstr "Instala el importador de Blogger para importar entradas, comentarios y usuarios de un blog de Blogger." + +#: wp-admin/import.php:31 +msgid "Install the category/tag converter to convert existing categories to tags or tags to categories, selectively." +msgstr "Instala el conversor de categorías existentes en etiquetas o las etiquetas en categorías, de forma selectiva." + +#: wp-admin/import.php:32 +msgid "LiveJournal" +msgstr "LiveJournal" + +#: wp-admin/import.php:32 +msgid "Install the LiveJournal importer to import posts from LiveJournal using their API." +msgstr "Instala el importador de LiveJournal para importar entradas usando su API" + +#: wp-admin/import.php:33 +msgid "Movable Type and TypePad" +msgstr "Movable Type y TypePad" + +#: wp-admin/import.php:33 +msgid "Install the Movable Type importer to import posts and comments from a Movable Type or TypePad blog." +msgstr "Instala el importador de Movable Type para importar entradas y comentarios de un blog de Movable Type o TypePad." + +#: wp-admin/import.php:34 wp-admin/includes/upgrade.php:129 +msgid "Blogroll" +msgstr "Sitios de interés" + +#: wp-admin/import.php:34 +msgid "Install the blogroll importer to import links in OPML format." +msgstr "Instala el importador de sitios de interés para importar enlaces en formato OPML." + +#: wp-admin/import.php:35 +msgid "Install the RSS importer to import posts from an RSS feed." +msgstr "Instala el importador RSS para Importar entradas de una fuente RSS." + +#: wp-admin/import.php:36 +msgid "Install the WordPress importer to import posts, pages, comments, custom fields, categories, and tags from a WordPress export file." +msgstr "Instala el importador de WordPress para importar entradas, páginas, comentarios, campos personalizados, categorías y etiquetas de un archivo de exportación de WordPress." + +#: wp-admin/import.php:56 +msgid "ERROR:" +msgstr "ERROR:" + +#: wp-admin/import.php:56 +msgid "The %s importer is invalid or is not installed." +msgstr "El importador %s no es válido o no está instalado." + +#: wp-admin/import.php:58 +msgid "If you have posts or comments in another system, WordPress can import those into this site. To get started, choose a system to import from below:" +msgstr "Si tienes entradas o comentarios en otro sistema, WordPress los puede importar a este sitio. Para comenzar, elige el sistema desde el que los importarás:" + +#: wp-admin/import.php:93 +msgid "No importers are available." +msgstr "No hay importadores disponibles." + +#: wp-admin/import.php:113 +msgid "Activate importer" +msgstr "Activar importador" + +#: wp-admin/import.php:119 +msgid "Install importer" +msgstr "Instalar importador" + +#: wp-admin/import.php:139 +msgid "If the importer you need is not listed, search the plugins directory to see if an importer is available." +msgstr "Si el importador que necesitas no está en la lista, busca en el directorio de plugins para ver si está disponible." + +#: wp-admin/custom-background.php:83 +msgid "You can customize the look of your site without touching any of your theme’s code by using a custom background. Your background can be an image or a color." +msgstr "Puedes personalizar la imagen de tu sitio sin tocar nada del código del tema usando un fondo personalizado. Tu fondo puede ser una imagen o un color." + +#: wp-admin/custom-background.php:84 +msgid "To use a background image, simply upload it, then choose your display options below. You can display a single instance of your image, or tile it to fill the screen. You can have your background fixed in place, so your site content moves on top of it, or you can have it scroll with your site." +msgstr "Para usar una imagen de fondo, simplemente súbela y después selecciona las opciones de visualización. Puedes mostrar la imagen una sola vez o ponerla en mosaico para que rellene la pantalla. Puedes fijar tu fondo, tu sitio pasará por encima de ella o puedes hacer que se mueva con tu sitio (cuando subas o bajes la barra del navegador)." + +#: wp-admin/custom-background.php:85 +msgid "You can also choose a background color. If you know the hexadecimal code for the color you want, enter it in the Color field. If not, click on the Select a Color link, and a color picker will allow you to choose the exact shade you want." +msgstr "También puedes elegir un color de fondo. Si sabes el código hexadecimal que quieres introdúcelo en el campo Color. Si no lo sabes, haz click en el enlace de elegir un color y un selector de colores te permitirá escoger el color exacto que quieras." + +#: wp-admin/custom-background.php:86 +msgid "Don’t forget to click on the Save Changes button when you are finished." +msgstr "No olvides hacer clic en el botón Guardar cambios cuando acabes." + +#: wp-admin/custom-background.php:88 +msgid "Documentation on Custom Background" +msgstr "Documentación sobre fondo personalizado" + +#: wp-admin/custom-background.php:169 wp-admin/includes/theme.php:301 +msgid "Custom Background" +msgstr "Fondo personalizado" + +#: wp-admin/custom-background.php:172 +msgid "Background updated. Visit your site to see how it looks." +msgstr "Fondo actualizado. Visita tu sitio para ver cómo queda." + +#: wp-admin/custom-background.php:180 +msgid "Background Image" +msgstr "Imagen de fondo" + +#: wp-admin/custom-background.php:213 +msgid "Remove Background Image" +msgstr "Quitar imagen de fondo" + +#: wp-admin/custom-background.php:214 +msgid "This will remove the background image. You will not be able to restore any customizations." +msgstr "Esto eliminará la imagen de fondo. No podrás restaurar ninguna personalización." + +#: wp-admin/custom-background.php:222 wp-admin/custom-background.php:226 +#: wp-admin/includes/image-edit.php:97 +msgid "Restore Original Image" +msgstr "Restaurar imagen original" + +#: wp-admin/custom-background.php:227 +msgid "This will restore the original background image. You will not be able to restore any customizations." +msgstr "Esto restaurará la imagen de fondo original. No te será posible restaurar ninguna personalización." + +#: wp-admin/custom-background.php:247 +msgid "Display Options" +msgstr "Opciones de visualización" + +#: wp-admin/custom-background.php:253 wp-admin/widgets.php:278 +msgid "Position" +msgstr "Posición" + +#: wp-admin/custom-background.php:254 +msgid "Background Position" +msgstr "Posición del fondo" + +#: wp-admin/custom-background.php:271 +msgid "Repeat" +msgstr "Repetir" + +#: wp-admin/custom-background.php:272 +msgid "Background Repeat" +msgstr "Repetir fondo" + +#: wp-admin/custom-background.php:273 +msgid "No Repeat" +msgstr "No repetir" + +#: wp-admin/custom-background.php:274 +msgid "Tile" +msgstr "Mosaico" + +#: wp-admin/custom-background.php:275 +msgid "Tile Horizontally" +msgstr "Mosaico Horizontal" + +#: wp-admin/custom-background.php:276 +msgid "Tile Vertically" +msgstr "Mosaico Vertical" + +#: wp-admin/custom-background.php:281 +msgid "Attachment" +msgstr "Adjunto" + +#: wp-admin/custom-background.php:282 +msgid "Background Attachment" +msgstr "Adjunto del fondo" + +#: wp-admin/custom-background.php:285 +msgid "Scroll" +msgstr "Desplazar" + +#: wp-admin/custom-background.php:289 +msgid "Fixed" +msgstr "Fijo" + +#: wp-admin/custom-background.php:295 +msgid "Color" +msgstr "Color" + +#: wp-admin/custom-background.php:296 +msgid "Background Color" +msgstr "Color de fondo" + +#: wp-admin/options-media.php:15 +msgid "Media Settings" +msgstr "Ajustes de medios" + +#: wp-admin/options-media.php:19 +msgid "You can set maximum sizes for images inserted into your written content; you can also insert an image as Full Size." +msgstr "Puedes establecer los tamaños máximos para las imágenes insertadas en tu contenido; también puedes insertar una imagen a tamaño completo." + +#: wp-admin/options-media.php:20 +msgid "The Embed option allows you embed a video, image, or other media content into your content automatically by typing the URL (of the web page where the file lives) on its own line when you create your content." +msgstr "La opción de Incrustar te permite incrustar un vídeo, imagen u otro contenido multimedia automáticamente en tu contenido tecleando la URL (de la página web donde está el archivo) en su propia línea cuando creas tu contenido." + +#: wp-admin/options-media.php:21 +msgid "Uploading Options gives you folder and path choices for storing your files in your installation’s directory." +msgstr "Las opciones de subida te dan a escoger en qué directorio y ruta almacenar tus archivos." + +#: wp-admin/options-media.php:24 +msgid "Documentation on Media Settings" +msgstr "Documentción sobre los ajustes multimedia" + +#: wp-admin/options-media.php:39 +msgid "Image sizes" +msgstr "Tamaño de las imágenes" + +#: wp-admin/options-media.php:40 +msgid "The sizes listed below determine the maximum dimensions in pixels to use when inserting an image into the body of a post." +msgstr "Los tamaños que se listan a continuación indican las dimensiones máximas a utilizar para insertar una imagen en el contenido de una entrada." + +#: wp-admin/options-media.php:44 +msgid "Thumbnail size" +msgstr "Tamaño de la miniatura" + +#: wp-admin/options-media.php:51 +msgid "Crop thumbnail to exact dimensions (normally thumbnails are proportional)" +msgstr "Recortar las miniaturas en las dimensiones exactas (normalmente, las miniaturas son proporcionales)" + +#: wp-admin/options-media.php:56 wp-admin/options-media.php:57 +msgid "Medium size" +msgstr "Tamaño medio" + +#: wp-admin/options-media.php:58 wp-admin/options-media.php:68 +msgid "Max Width" +msgstr "Anchura máxima" + +#: wp-admin/options-media.php:60 wp-admin/options-media.php:70 +msgid "Max Height" +msgstr "Altura máxima" + +#: wp-admin/options-media.php:66 wp-admin/options-media.php:67 +msgid "Large size" +msgstr "Tamaño grande" + +#: wp-admin/options-media.php:78 +msgid "Embeds" +msgstr "Incrustados" + +#: wp-admin/options-media.php:83 +msgid "Auto-embeds" +msgstr "Auto-incrustados" + +#: wp-admin/options-media.php:84 wp-admin/options-media.php:85 +msgid "When possible, embed the media content from a URL directly onto the page. For example: links to Flickr and YouTube." +msgstr "Siempre que sea posible, incrusta el contenido multimedia pegando la URL directamente en la página. Por ejemplo: pegando los enlaces de Flickr y YouTube. " + +#: wp-admin/options-media.php:90 +msgid "Maximum embed size" +msgstr "Tamaño máximo de incrustación" + +#: wp-admin/options-media.php:96 +msgid "If the width value is left blank, embeds will default to the max width of your theme." +msgstr "Si el valor del ancho se deja vacío, lo que incrustes se verá al valor máximo de ancho de tu tema." + +#: wp-admin/options-media.php:104 +msgid "Uploading Files" +msgstr "Subida de archivos" + +#: wp-includes/script-loader.php:237 +msgid "moved to the trash." +msgstr "movidos a la papelera." + +#: wp-includes/script-loader.php:238 wp-admin/async-upload.php:56 +msgid "“%s” has failed to upload due to an error" +msgstr "Ha habido un error al subir “%s”" + +#: wp-includes/pluggable.php:1223 +msgid "New user registration on your site %s:" +msgstr "Registrado un nuevo usuario en tu sitio %s:" + +#: wp-includes/category-template.php:1030 +msgid "Tags: " +msgstr "Etiquetas: " + +#: wp-includes/script-loader.php:102 wp-includes/script-loader.php:295 +msgid "An unidentified error has occurred." +msgstr "Ha ocurrido un error no identificado." + +#: wp-includes/media.php:250 +msgid "The GD image library is not installed." +msgstr "La librería de imágenes GD no está instalada." + +#: wp-includes/media.php:247 +msgid "File “%s” doesn’t exist?" +msgstr "¿El archivo “%s” no existe?" + +#: wp-includes/pluggable.php:1195 +msgid "Password Lost and Changed for user: %s" +msgstr "Contraseña perdida y cambiada para el usuario: %s" + +#: wp-includes/script-loader.php:253 wp-admin/install.php:254 +msgid "Very weak" +msgstr "Muy débil" + +#: wp-includes/script-loader.php:430 +msgctxt "search results" +msgid "No results found." +msgstr "No se han encontrado resultados." + +#: wp-includes/script-loader.php:423 +msgid "Done" +msgstr "Hecho" + +#: wp-includes/script-loader.php:421 +msgid "Saving..." +msgstr "Guardando..." + +#: wp-includes/script-loader.php:420 wp-admin/includes/media.php:1316 +msgid "Use as featured image" +msgstr "Usar como imagen destacada" + +#: wp-includes/script-loader.php:397 +msgid "Are you sure you want to install this plugin?" +msgstr "¿Estás seguro de querer instalar este plugin?" + +#: wp-includes/script-loader.php:330 wp-admin/edit-form-advanced.php:109 +#: wp-admin/includes/dashboard.php:540 wp-admin/includes/meta-boxes.php:215 +#: wp-admin/includes/meta-boxes.php:216 wp-admin/press-this.php:494 +msgid "Publish" +msgstr "Publicar" + +#: wp-includes/script-loader.php:339 wp-admin/includes/meta-boxes.php:65 +#: wp-admin/includes/meta-boxes.php:92 +msgid "Privately Published" +msgstr "Publicada como privada" + +#: wp-includes/theme-compat/comments-popup.php:71 +msgid "Logged in as %2$s. Log out »" +msgstr "Identificado como %2$s. Salir »" + +#: wp-includes/theme-compat/comments-popup.php:80 wp-login.php:521 +#: wp-admin/user-new.php:229 wp-admin/user-new.php:291 wp-admin/comment.php:160 +#: wp-admin/includes/class-wp-users-list-table.php:164 +#: wp-admin/includes/template.php:356 wp-admin/user-edit.php:316 +msgid "E-mail" +msgstr "Correo electrónico" + +#: wp-includes/theme-compat/comments-popup.php:85 +msgid "URL" +msgstr "URL" + +#: wp-includes/script-loader.php:87 +msgid "Enter the URL of the image" +msgstr "Introduce la URL de la imagen" + +#: wp-includes/pluggable.php:1069 wp-includes/pluggable.php:1162 +msgid "Delete it: %s" +msgstr "Borrarlo: %s" + +#: wp-includes/pluggable.php:1067 wp-includes/pluggable.php:1160 +msgid "Trash it: %s" +msgstr "Enviar a la papelera: %s" + +#: wp-includes/pluggable.php:1145 +msgid "Pingback excerpt: " +msgstr "Extracto del pingback:" + +#: wp-includes/script-loader.php:219 +msgid "not configured" +msgstr "sin configurar" + +#: wp-includes/script-loader.php:336 wp-admin/includes/meta-boxes.php:125 +#: wp-admin/includes/meta-boxes.php:140 +msgid "Public" +msgstr "Público" + +#: wp-includes/class-pop3.php:170 +msgid "No login ID submitted" +msgstr "No se ha enviado el ID de usuario" + +#: wp-includes/script-loader.php:338 +msgid "Password Protected" +msgstr "Protegida con contraseña" + +#: wp-includes/theme-compat/sidebar.php:32 +msgid "You are currently browsing the archives for the %s category." +msgstr "Actualmente estás navegando por el archivo de la categoría %s" + +#: wp-includes/theme-compat/sidebar.php:69 wp-includes/default-widgets.php:283 +#: wp-includes/default-widgets.php:288 +msgid "Meta" +msgstr "Meta" + +#: wp-includes/script-loader.php:256 wp-admin/install.php:256 +msgctxt "password strength" +msgid "Medium" +msgstr "Medio" + +#: wp-includes/script-loader.php:432 wp-includes/script-loader.php:556 +#: wp-includes/js/tinymce/langs/wp-langs.php:146 +msgid "The changes you made will be lost if you navigate away from this page." +msgstr "Los cambios realizados se perderán si abres otra página." + +#: wp-includes/pluggable.php:1053 +msgid "[%1$s] Trackback: \"%2$s\"" +msgstr "[%1$s] Trackback: \"%2$s\"" + +#: wp-includes/pluggable.php:1055 +msgid "New pingback on your post \"%s\"" +msgstr "Nuevo pingback en tu entrada \"%s\"" + +#: wp-includes/post-template.php:1212 +msgid "This post is password protected. To view it please enter your password below:" +msgstr "Esta entrada está protegida. Para verla escribe la contraseña:" + +#: wp-includes/script-loader.php:553 +msgid "Preview this Post" +msgstr "Previsualizar esta entrada" + +#: wp-includes/class-pop3.php:178 +msgid "No server banner" +msgstr "No hay identificación del servidor" + +#: wp-includes/theme-compat/footer.php:19 +msgid "Entries (RSS)" +msgstr "Artículos (RSS)" + +#: wp-includes/theme-compat/footer.php:19 +msgid "%1$s and %2$s." +msgstr "%1$s y %2$s." + +#: wp-includes/script-loader.php:324 wp-includes/script-loader.php:351 +#: wp-admin/includes/dashboard.php:682 +#: wp-admin/includes/class-wp-posts-list-table.php:194 +#: wp-admin/includes/class-wp-posts-list-table.php:542 +#: wp-admin/includes/class-wp-comments-list-table.php:412 +#: wp-admin/includes/class-wp-users-list-table.php:245 +#: wp-admin/includes/class-wp-plugins-list-table.php:383 +#: wp-admin/includes/class-wp-terms-list-table.php:259 +#: wp-admin/includes/class-wp-media-list-table.php:337 +#: wp-admin/includes/class-wp-media-list-table.php:351 +#: wp-admin/includes/post.php:1175 +#: wp-admin/includes/class-wp-links-list-table.php:139 +#: wp-admin/includes/widgets.php:182 wp-admin/includes/meta-boxes.php:84 +#: wp-admin/includes/meta-boxes.php:130 wp-admin/includes/meta-boxes.php:182 +#: wp-admin/edit-form-comment.php:62 +msgid "Edit" +msgstr "Editar" + +#: wp-includes/pluggable.php:1042 +msgid "You can see all comments on this post here: " +msgstr "Puedes ver todos los comentarios de esta entrada aquí:" + +#: wp-includes/script-loader.php:226 +msgid "An error occurred in the upload. Please try again later." +msgstr "Ha habido un error en la subida. Por favor inténtalo más tarde." + +#: wp-includes/script-loader.php:225 +msgid "This file type is not allowed. Please try another." +msgstr "Este tipo de archivo no está permitido. Por favor, prueba con otro." + +#: wp-includes/script-loader.php:224 +msgid "This file is empty. Please try another." +msgstr "Este archivo está vacio. Por favor, prueba con otro." + +#: wp-includes/pluggable.php:1199 +msgid "[%s] Password Lost/Changed" +msgstr "[%s] Contraseña Perdida/Cambiada" + +#: wp-includes/pluggable.php:1169 +msgid "[%1$s] Please moderate: \"%2$s\"" +msgstr "[%1$s] Pendientes de moderación: \"%2$s\"" + +#: wp-includes/theme-compat/footer.php:20 +msgid "%d queries. %s seconds." +msgstr "%d consultas. %s segundos." + +#: wp-includes/theme-compat/sidebar.php:21 wp-includes/post-template.php:1415 +#: wp-includes/js/tinymce/langs/wp-langs.php:256 +#: wp-admin/edit-form-advanced.php:156 wp-admin/comment.php:155 +#: wp-admin/includes/class-wp-posts-list-table.php:274 +#: wp-admin/includes/class-wp-posts-list-table.php:779 +#: wp-admin/includes/plugin-install.php:127 +#: wp-admin/includes/class-wp-comments-list-table.php:252 +#: wp-admin/includes/class-wp-comments-list-table.php:523 +#: wp-admin/includes/theme-install.php:62 +#: wp-admin/includes/class-wp-media-list-table.php:135 +#: wp-admin/includes/meta-boxes.php:525 wp-admin/edit-form-comment.php:86 +msgid "Author" +msgstr "Autor" + +#: wp-includes/script-loader.php:331 wp-admin/includes/meta-boxes.php:212 +#: wp-admin/includes/meta-boxes.php:213 +msgid "Schedule" +msgstr "Programar" + +#: wp-includes/media.php:448 wp-includes/media.php:451 +#: wp-includes/media.php:456 +msgid "Resize path invalid" +msgstr "Ruta de redimensionado no válida" + +#: wp-includes/pluggable.php:1233 +msgid "Password: %s" +msgstr "Contraseña: %s" + +#: wp-includes/pluggable.php:1158 +msgid "Approve it: %s" +msgstr "Aprobarlo: %s" + +#: wp-includes/pluggable.php:1148 +msgid "A new comment on the post \"%s\" is waiting for your approval" +msgstr "Un nuevo comentario a la entrada \"%s\" está esperando tu aprobación" + +#: wp-includes/media.php:414 +msgid "Could not read image size" +msgstr "No se pudo leer el tamaño de imagen" + +#: wp-includes/media.php:257 +msgid "File “%s” is not an image." +msgstr "El archivo “%s” no es una imagen." + +#: wp-includes/pluggable.php:1037 wp-includes/pluggable.php:1150 +msgid "Author : %1$s (IP: %2$s , %3$s)" +msgstr "Autor : %1$s (IP: %2$s , %3$s)" + +#: wp-includes/pluggable.php:1035 +msgid "New comment on your post \"%s\"" +msgstr "Nuevo comentario a tu entrada \"%s\"" + +#: wp-includes/pluggable.php:490 +msgid "ERROR: Invalid username or incorrect password." +msgstr "ERROR: El nombre de usuario y/o la contraseña no son correctos." + +#: wp-includes/class-wp-admin-bar.php:104 wp-includes/default-widgets.php:175 +#: wp-includes/general-template.php:163 wp-admin/includes/plugin-install.php:86 +#: wp-admin/includes/class-wp-theme-install-list-table.php:29 +#: wp-admin/includes/internal-linking.php:93 +#: wp-admin/includes/template.php:1355 wp-admin/includes/template.php:1357 +#: wp-admin/includes/theme-install.php:66 wp-admin/includes/nav-menu.php:642 +#: wp-admin/includes/nav-menu.php:671 wp-admin/includes/nav-menu.php:673 +#: wp-admin/includes/nav-menu.php:849 wp-admin/includes/nav-menu.php:898 +#: wp-admin/includes/nav-menu.php:900 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:29 +#: wp-content/plugins/akismet/legacy.php:176 +msgid "Search" +msgstr "Buscar" + +#: wp-includes/script-loader.php:422 +msgid "Could not set that as the thumbnail image. Try a different attachment." +msgstr "No se pudo establecer como imagen de miniatura. Prueba con otro adjunto." + +#: wp-includes/pluggable.php:1060 +msgid "You can see all pingbacks on this post here: " +msgstr "Puede ver todos los pingback de esta entrada aquí:" + +#: wp-includes/pluggable.php:1227 +msgid "[%s] New User Registration" +msgstr "[%s] Registro de nuevo usuario" + +#: wp-includes/theme-compat/comments.php:78 +#: wp-includes/theme-compat/comments.php:81 wp-admin/user-new.php:287 +#: wp-admin/user-new.php:291 wp-admin/user-edit.php:277 +#: wp-admin/user-edit.php:316 +msgid "(required)" +msgstr "(requerido)" + +#: wp-includes/class-pop3.php:325 +msgid "Premature end of list" +msgstr "Fin de la lista prematuro" + +#: wp-includes/class-pop3.php:188 +msgid "apop authentication failed" +msgstr "Falló la autenticación apop" + +#: wp-includes/post-template.php:1278 +msgid "%1$s [Autosave]" +msgstr "%s [Autoguardado]" + +#: wp-includes/script-loader.php:272 wp-includes/script-loader.php:382 +#: wp-admin/includes/template.php:1519 +msgid "(no title)" +msgstr "(sin título)" + +#: wp-includes/script-loader.php:270 wp-includes/script-loader.php:332 +#: wp-includes/js/tinymce/langs/wp-langs.php:29 +#: wp-admin/includes/class-wp-posts-list-table.php:997 +#: wp-admin/includes/class-wp-posts-list-table.php:999 +#: wp-admin/includes/class-wp-posts-list-table.php:1002 +#: wp-admin/includes/internal-linking.php:118 +#: wp-admin/includes/template.php:507 +#: wp-admin/includes/class-wp-plugins-list-table.php:262 +#: wp-admin/includes/meta-boxes.php:224 wp-admin/includes/meta-boxes.php:225 +#: wp-admin/edit-tag-form.php:90 +msgid "Update" +msgstr "Actualizar" + +#: wp-includes/pluggable.php:1070 wp-includes/pluggable.php:1163 +msgid "Spam it: %s" +msgstr "Marcarlo como spam: %s" + +#: wp-includes/script-loader.php:252 wp-login.php:468 wp-admin/user-new.php:314 +#: wp-admin/install.php:122 wp-admin/install.php:253 wp-admin/user-edit.php:362 +msgid "Strength indicator" +msgstr "Seguridad de la contraseña" + +#: wp-includes/pluggable.php:1062 +msgid "[%1$s] Pingback: \"%2$s\"" +msgstr "[%1$s] Pingback: \"%2$s\"" + +#: wp-includes/script-loader.php:190 +msgid "Next >" +msgstr "Siguiente >" + +#: wp-includes/pluggable.php:1048 wp-includes/pluggable.php:1057 +msgid "Website: %1$s (IP: %2$s , %3$s)" +msgstr "Sitio web: %1$s (IP: %2$s , %3$s)" + +#: wp-includes/pluggable.php:1046 +msgid "New trackback on your post \"%s\"" +msgstr "Nuevo trackback a tu entrada \"%s\"" + +#: wp-includes/pluggable.php:1044 +msgid "[%1$s] Comment: \"%2$s\"" +msgstr "[%1$s] Comentario: \"%2$s\"" + +#: wp-includes/script-loader.php:234 +msgid "Upload stopped." +msgstr "Subida detenida." + +#: wp-includes/script-loader.php:233 +msgid "File canceled." +msgstr "Archivo cancelado." + +#: wp-includes/script-loader.php:232 +msgid "Security error." +msgstr "Error de seguridad." + +#: wp-includes/script-loader.php:231 +msgid "IO error." +msgstr "Error de entrada/salida." + +#: wp-includes/script-loader.php:230 +msgid "Upload failed." +msgstr "Falló la subida." + +#: wp-includes/script-loader.php:229 +msgid "HTTP error." +msgstr "Error HTTP." + +#: wp-includes/script-loader.php:228 +msgid "You may only upload 1 file." +msgstr "Sólo puedes subir 1 archivo." + +#: wp-includes/script-loader.php:227 +msgid "There was a configuration error. Please contact the server administrator." +msgstr "Ha habido un problema con la configuración. Por favor, contacta con el administrador del servidor." + +#: wp-includes/script-loader.php:258 wp-admin/install.php:258 +msgid "Mismatch" +msgstr "No coinciden" + +#: wp-includes/script-loader.php:257 wp-admin/install.php:257 +msgid "Strong" +msgstr "Fuerte" + +#: wp-includes/pluggable.php:1236 +msgid "[%s] Your username and password" +msgstr "[%s] Tu nombre de usuario y contraseña" + +#: wp-includes/theme-compat/footer.php:10 +#: wp-includes/theme-compat/sidebar.php:10 +#: wp-includes/theme-compat/comments.php:10 +#: wp-includes/theme-compat/header.php:10 +#: wp-includes/theme-compat/comments-popup.php:10 +msgid "Theme without %1$s" +msgstr "Tema sin %1$s" + +#: wp-includes/theme-compat/footer.php:10 +#: wp-includes/theme-compat/sidebar.php:10 +#: wp-includes/theme-compat/comments.php:10 +#: wp-includes/theme-compat/header.php:10 +#: wp-includes/theme-compat/comments-popup.php:10 +msgid "Please include a %1$s template in your theme." +msgstr "Por favor, incluye la plantilla %1$s en tu tema" + +#: wp-includes/script-loader.php:552 +msgid "Preview this Page" +msgstr "Previsualizar esta página" + +#: wp-includes/theme-compat/comments.php:73 +msgid "Log out of this account" +msgstr "Salir de esta cuenta" + +#: wp-includes/theme-compat/comments.php:73 +msgid "Logged in as %2$s." +msgstr "Identificado como %2$s." + +#: wp-includes/theme-compat/comments.php:66 +#: wp-includes/comment-template.php:1534 +msgid "You must be logged in to post a comment." +msgstr "Disculpa, debes iniciar sesión para escribir un comentario." + +#: wp-includes/theme-compat/comments.php:59 +#: wp-includes/comment-template.php:1197 wp-includes/comment-template.php:1541 +msgid "Leave a Reply to %s" +msgstr "Responder a %s" + +#: wp-includes/theme-compat/comments.php:78 +#: wp-includes/theme-compat/comments-popup.php:75 +#: wp-includes/comment-template.php:1522 +#: wp-includes/js/tinymce/langs/wp-langs.php:312 wp-admin/edit-link-form.php:86 +#: wp-admin/themes.php:216 wp-admin/includes/class-wp-users-list-table.php:163 +#: wp-admin/includes/template.php:351 wp-admin/includes/template.php:428 +#: wp-admin/includes/template.php:443 wp-admin/includes/template.php:538 +#: wp-admin/includes/class-wp-terms-list-table.php:100 +#: wp-admin/includes/class-wp-terms-list-table.php:338 +#: wp-admin/includes/class-wp-links-list-table.php:80 +#: wp-admin/includes/class-wp-plugin-install-list-table.php:141 +#: wp-admin/user-edit.php:226 +msgid "Name" +msgstr "Nombre" + +#: wp-includes/media.php:419 +msgid "Could not calculate resized image dimensions" +msgstr "No se han podido recalcular las dimensiones de la imagen redimensionada" + +#: wp-includes/pluggable.php:1050 wp-includes/pluggable.php:1059 +msgid "Excerpt: " +msgstr "Extracto:" + +#: wp-includes/pluggable.php:1051 +msgid "You can see all trackbacks on this post here: " +msgstr "Puedes ver todos los trackbacks de esta entrada aquí:" + +#: wp-includes/theme-compat/comments-popup.php:14 +msgid "%1$s - Comments on %2$s" +msgstr "%1$s - Comentarios en %2$s" + +#: wp-includes/theme-compat/comments.php:92 +msgid "Submit Comment" +msgstr "Enviar comentario" + +#: wp-includes/theme-compat/sidebar.php:47 +msgid "You are currently browsing the %2$s blog archives." +msgstr "Estás navegando por el archivo de %2$s." + +#: wp-includes/post-template.php:1213 wp-admin/includes/meta-boxes.php:145 +msgid "Password:" +msgstr "Contraseña:" + +#: wp-includes/theme-compat/sidebar.php:63 +#: wp-includes/category-template.php:427 wp-includes/default-widgets.php:422 +#: wp-includes/default-widgets.php:428 wp-admin/edit-link-form.php:28 +#: wp-admin/includes/class-wp-posts-list-table.php:277 +#: wp-admin/includes/class-wp-links-list-table.php:82 +#: wp-admin/press-this.php:522 +msgid "Categories" +msgstr "Categorías" + +#: wp-includes/theme-compat/comments-popup.php:62 +#: wp-admin/includes/dashboard.php:646 wp-admin/includes/meta-boxes.php:481 +msgid "No comments yet." +msgstr "Aún no hay comentarios." + +#: wp-includes/theme-compat/comments-popup.php:56 +msgid "by %1$s — %2$s @ %4$s" +msgstr "por %1$s — %2$s @ %4$s" + +#: wp-includes/script-loader.php:236 +msgid "Crunching…" +msgstr "Calculando…" + +#: wp-includes/deprecated.php:707 wp-includes/js/tinymce/langs/wp-langs.php:424 +#: wp-admin/includes/media.php:828 wp-admin/includes/media.php:922 +#: wp-admin/includes/media.php:2109 wp-admin/includes/media.php:2125 +#: wp-admin/includes/class-wp-users-list-table.php:263 +#: wp-admin/edit-tags.php:348 wp-admin/edit-tag-form.php:55 +msgid "None" +msgstr "Ninguna" + +#: wp-includes/script-loader.php:85 +msgid "close tags" +msgstr "cerrar etiquetas" + +#: wp-includes/script-loader.php:84 +msgid "Close all open tags" +msgstr "Cerrar todas las etiquetas abiertas" + +#: wp-includes/script-loader.php:86 +msgid "Enter the URL" +msgstr "Introduce la URL" + +#: wp-includes/script-loader.php:335 wp-includes/post.php:590 +#: wp-includes/post.php:610 wp-admin/includes/class-wp-posts-list-table.php:806 +#: wp-admin/includes/class-wp-posts-list-table.php:948 +#: wp-admin/includes/template.php:1632 wp-admin/includes/meta-boxes.php:116 +#: wp-admin/includes/meta-boxes.php:146 +msgid "Private" +msgstr "Privada" + +#: wp-includes/pluggable.php:1138 +msgid "Trackback excerpt: " +msgstr "Extracto del trackback:" + +#: wp-includes/script-loader.php:318 +msgid "Tags used on this post:" +msgstr "Etiquetas utilizadas en esta entrada:" + +#: wp-includes/theme-compat/footer.php:17 +msgid "%1$s is proudly powered by %2$s" +msgstr "%1$s funciona gracias a %2$s" + +#: wp-includes/script-loader.php:321 wp-includes/taxonomy.php:410 +msgid "Separate tags with commas" +msgstr "Separa las etiquetas con comas." + +#: wp-includes/script-loader.php:271 wp-admin/edit-link-form.php:20 +#: wp-admin/includes/meta-boxes.php:636 +msgid "Add Link" +msgstr "Añadir enlace" + +#: wp-includes/pluggable.php:1225 +#: wp-admin/includes/class-wp-users-list-table.php:290 +msgid "E-mail: %s" +msgstr "Correo electrónico: %s" + +#: wp-includes/script-loader.php:325 +msgid "Publish on:" +msgstr "Publicar el:" + +#: wp-includes/script-loader.php:223 +msgid "This file exceeds the maximum upload size for this site." +msgstr "El tamaño del archivo excede el tamaño permitido en este sitio." + +#: wp-includes/class-pop3.php:137 wp-includes/class-pop3.php:173 +msgid "No password submitted" +msgstr "No se envió la contraseña" + +#: wp-includes/theme-compat/sidebar.php:35 +msgid "You are currently browsing the %2$s blog archives for the day %3$s." +msgstr "Actualmente estás navegando por el archivo del sitio %2$s del día %3$s." + +#: wp-includes/pluggable.php:1041 wp-includes/pluggable.php:1154 +msgid "Comment: " +msgstr "Comentario:" + +#: wp-includes/script-loader.php:191 +msgid "< Prev" +msgstr "< Anterior" + +#: wp-includes/post-template.php:622 +msgid "Pages:" +msgstr "Páginas:" + +#: wp-includes/post-template.php:268 +msgid "There is no excerpt because this is a protected post." +msgstr "No hay extracto porque es una entrada protegida." + +#: wp-includes/post-template.php:185 +msgid "(more...)" +msgstr "(más...)" + +#: wp-includes/script-loader.php:101 wp-includes/script-loader.php:294 +msgid "You do not have permission to do that." +msgstr "No tienes autorización para hacer eso." + +#: wp-includes/category-template.php:59 wp-includes/category-template.php:174 +#: wp-includes/category-template.php:177 wp-includes/category-template.php:184 +#: wp-includes/category-template.php:197 wp-includes/category-template.php:200 +#: wp-includes/category-template.php:207 +msgid "View all posts in %s" +msgstr "Ver todas las entradas en %s" + +#: wp-includes/script-loader.php:83 +msgid "lookup" +msgstr "buscar" + +#: wp-includes/script-loader.php:82 +msgid "Dictionary lookup" +msgstr "Buscar en el diccionario" + +#: wp-includes/script-loader.php:81 +msgid "Enter a word to look up:" +msgstr "Introduce una palabra a buscar:" + +#: wp-includes/script-loader.php:80 +msgid "(Quick Links)" +msgstr "(Enlaces rápidos)" + +#: wp-includes/class-pop3.php:594 +msgid "Command failed " +msgstr "Comando fallido" + +#: wp-includes/theme-compat/comments-popup.php:90 +msgid "Your Comment" +msgstr "Tu comentario" + +#: wp-includes/class-pop3.php:164 wp-includes/class-pop3.php:207 +#: wp-includes/class-pop3.php:232 wp-includes/class-pop3.php:274 +#: wp-includes/class-pop3.php:348 wp-includes/class-pop3.php:388 +#: wp-includes/class-pop3.php:418 wp-includes/class-pop3.php:452 +#: wp-includes/class-pop3.php:515 wp-includes/class-pop3.php:583 +msgid "No connection to server" +msgstr "No hay conexión con el servidor." + +#: wp-includes/post-template.php:115 +msgid "Private: %s" +msgstr "Privado: %s" + +#: wp-includes/pluggable.php:1224 wp-includes/pluggable.php:1232 +#: wp-login.php:217 +msgid "Username: %s" +msgstr "Nombre de usuario: %s" + +#: wp-includes/theme-compat/comments-popup.php:67 +msgid "Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: %s" +msgstr "Las líneas y párrafos saltan automáticamente, nunca se mostrarán los correos electrónicos. HTMLpermitido: %s" + +#: wp-includes/theme-compat/comments-popup.php:66 +msgid "Leave a comment" +msgstr "Deja un comentario" + +#: wp-includes/theme-compat/sidebar.php:38 +msgid "F, Y" +msgstr "j F Y" + +#: wp-includes/theme-compat/sidebar.php:38 +msgid "You are currently browsing the %2$s blog archives for %3$s." +msgstr "Actualmente estás viendo el archivo del sitio %2$s de %3$s." + +#: wp-includes/theme-compat/sidebar.php:35 +msgid "l, F jS, Y" +msgstr "j F Y" + +#: wp-includes/theme-compat/comments.php:59 +#: wp-includes/comment-template.php:1196 wp-includes/comment-template.php:1540 +msgid "Leave a Reply" +msgstr "Deja un comentario" + +#: wp-includes/script-loader.php:337 wp-admin/includes/meta-boxes.php:122 +msgid "Public, Sticky" +msgstr "Pública, Fija" + +#: wp-includes/script-loader.php:88 +msgid "Enter a description of the image" +msgstr "Introduce una descripción de la imagen" + +#: wp-includes/class-pop3.php:120 wp-includes/class-pop3.php:140 +msgid "connection not established" +msgstr "no se estableció la conexión" + +#: wp-includes/theme-compat/footer.php:19 +msgid "Comments (RSS)" +msgstr "Comentarios (RSS)" + +#: wp-includes/category-template.php:837 +msgid "View all posts filed under %s" +msgstr "Ver todas las entradas archivadas en %s" + +#: wp-includes/category-template.php:568 +msgid "%s topic" +msgid_plural "%s topics" +msgstr[0] "%s tema" +msgstr[1] "%s temas" + +#: wp-includes/category-template.php:419 +msgid "No categories" +msgstr "No hay categorías" + +#: wp-includes/class-pop3.php:458 +msgid "Empty command string" +msgstr "Cadena de comandos vacía" + +#: wp-includes/script-loader.php:254 wp-admin/install.php:255 +msgid "Weak" +msgstr "Débil" + +#: wp-includes/class-pop3.php:145 +msgid "Authentication failed" +msgstr "Autentificación fallida" + +#: wp-includes/class-pop3.php:92 wp-includes/class-pop3.php:104 +#: wp-includes/class-pop3.php:125 wp-includes/class-pop3.php:248 +#: wp-includes/class-pop3.php:302 wp-includes/class-pop3.php:313 +#: wp-includes/class-pop3.php:361 wp-includes/class-pop3.php:395 +#: wp-includes/class-pop3.php:428 wp-includes/class-pop3.php:527 +#: wp-includes/class-pop3.php:550 +msgid "Error " +msgstr "Error " + +#: wp-includes/class-pop3.php:84 +msgid "No server specified" +msgstr "Servidor no especificado" + +#: wp-includes/script-loader.php:334 wp-admin/includes/dashboard.php:537 +#: wp-admin/includes/meta-boxes.php:31 wp-admin/press-this.php:492 +msgid "Save Draft" +msgstr "Guardar borrador" + +#: wp-includes/script-loader.php:333 wp-admin/includes/meta-boxes.php:33 +msgid "Save as Pending" +msgstr "Guardar como pendiente" + +#: wp-includes/script-loader.php:431 +msgid "" +"You are about to permanently delete this menu. \n" +" 'Cancel' to stop, 'OK' to delete." +msgstr "" +"Estás a punto de eliminar permanentemente este menú. \n" +"'Cancelar' para parar, 'OK' para eliminar." + +#: wp-includes/post-template.php:625 +msgid "Previous page" +msgstr "Página anterior" + +#: wp-includes/post-template.php:624 +msgid "Next page" +msgstr "Página siguiente" + +#: wp-includes/script-loader.php:326 +msgid "Schedule for:" +msgstr "Programar para el:" + +#: wp-includes/class-pop3.php:178 wp-includes/class-pop3.php:188 +msgid "abort" +msgstr "cancelar" + +#: wp-includes/script-loader.php:284 +msgid "Separate multiple categories with commas." +msgstr "Separa múltiples categorías con comas." + +#: wp-includes/script-loader.php:322 wp-admin/includes/template.php:645 +#: wp-admin/includes/meta-boxes.php:103 wp-admin/includes/meta-boxes.php:149 +msgid "OK" +msgstr "Aceptar" + +#: wp-includes/script-loader.php:340 wp-includes/post.php:591 +#: wp-includes/post.php:611 wp-admin/admin-ajax.php:1292 +#: wp-admin/includes/class-wp-posts-list-table.php:591 +#: wp-admin/includes/class-wp-posts-list-table.php:945 +#: wp-admin/includes/meta-boxes.php:68 wp-admin/includes/meta-boxes.php:90 +msgid "Published" +msgstr "Publicada" + +#: wp-includes/script-loader.php:367 +msgid "Word count: %d" +msgstr "Contador de palabras: %d" + +#: wp-includes/script-loader.php:352 +msgid "Submitted on:" +msgstr "Enviado el:" + +#: wp-includes/script-loader.php:222 +msgid "You have attempted to queue too many files." +msgstr "Has intentado poner en cola demasiados archivos." + +#: wp-includes/pluggable.php:1134 +msgid "A new trackback on the post \"%s\" is waiting for your approval" +msgstr "Un nuevo trackback a la entrada \"%s\" está esperando tu aprobación" + +#: wp-includes/pluggable.php:1065 +msgid "Permalink: %s" +msgstr "Enlace permanente: %s" + +#: wp-includes/pluggable.php:1141 +msgid "A new pingback on the post \"%s\" is waiting for your approval" +msgstr "Un nuevo pingback a la entada \"%s\" está esperando tu aprobación" + +#: wp-includes/script-loader.php:283 wp-includes/script-loader.php:319 +#: wp-admin/includes/widgets.php:182 wp-admin/includes/meta-boxes.php:294 +#: wp-admin/includes/meta-boxes.php:683 wp-admin/press-this.php:582 +msgid "Add" +msgstr "Añadir" + +#: wp-includes/pluggable.php:1038 wp-includes/pluggable.php:1151 +msgid "E-mail : %s" +msgstr "Correo electrónico : %s" + +#: wp-includes/theme-compat/sidebar.php:55 wp-includes/post-template.php:807 +#: wp-includes/default-widgets.php:18 wp-includes/default-widgets.php:24 +#: wp-admin/export.php:167 wp-admin/menu.php:90 wp-admin/menu.php:91 +msgid "Pages" +msgstr "Páginas" + +#: wp-includes/theme-compat/sidebar.php:57 wp-includes/default-widgets.php:218 +#: wp-includes/default-widgets.php:225 wp-admin/includes/file.php:21 +msgid "Archives" +msgstr "Archivos" + +#: wp-includes/pluggable.php:1136 wp-includes/pluggable.php:1143 +msgid "Website : %1$s (IP: %2$s , %3$s)" +msgstr "Sitio web : %1$s (IP: %2$s , %3$s)" + +#: wp-includes/category-template.php:161 +#: wp-admin/includes/class-wp-posts-list-table.php:617 +#: wp-admin/includes/upgrade.php:109 +msgid "Uncategorized" +msgstr "Sin categoría" + +#: wp-includes/class-pop3.php:117 +msgid "no login ID submitted" +msgstr "no se ha enviado el ID de usuario" + +#: wp-includes/class-pop3.php:588 +msgid "No msg number submitted" +msgstr "No se envió ningún número de mensaje" + +#: wp-includes/class-pop3.php:478 +msgid "connection does not exist" +msgstr "conexión inexistente" + +#: wp-includes/script-loader.php:70 +msgid "" +"You are about to permanently delete the selected items.\n" +" 'Cancel' to stop, 'OK' to delete." +msgstr "" +"Estás a punto de borrar permanentemente los elementos seleccionados. \n" +" 'Aceptar' para borrar, 'Cancelar' para salir." + +#: wp-includes/script-loader.php:320 +msgid "Add new Tag" +msgstr "Añadir nueva etiqueta" + +#: wp-includes/script-loader.php:380 wp-includes/script-loader.php:389 +msgid "Error while saving the changes." +msgstr "Error al guardar los cambios." + +#: wp-includes/script-loader.php:327 +msgid "Published on:" +msgstr "Publicada el:" + +#: wp-includes/script-loader.php:328 +msgid "Show more comments" +msgstr "Mostrar más comentarios" + +#: wp-includes/script-loader.php:329 +msgid "No more comments found." +msgstr "No hay más comentarios." + +#: wp-includes/pluggable.php:1165 +msgid "Currently %s comment is waiting for approval. Please visit the moderation panel:" +msgid_plural "Currently %s comments are waiting for approval. Please visit the moderation panel:" +msgstr[0] "Actualmente hay %s comentario en espera de aprobación. Por favor visita el panel de moderación:" +msgstr[1] "Actualmente hay %s comentarios en espera de aprobación. Por favor visita el panel de moderación:" + +#: wp-includes/post-template.php:887 +msgid "Home" +msgstr "Inicio" + +#: wp-includes/post-template.php:1373 +#: wp-admin/includes/class-wp-posts-list-table.php:192 +#: wp-admin/includes/class-wp-posts-list-table.php:547 +#: wp-admin/includes/class-wp-comments-list-table.php:193 +#: wp-admin/includes/class-wp-comments-list-table.php:402 +#: wp-admin/includes/class-wp-media-list-table.php:354 +msgid "Restore" +msgstr "Restaurar" + +#: wp-includes/deprecated.php:1898 wp-includes/post-template.php:1151 +msgid "Missing Attachment" +msgstr "Falta el archivo" + +#: wp-includes/script-loader.php:195 +msgid "This feature requires inline frames. You have iframes disabled or your browser does not support them." +msgstr "Esta función requiere de frames insertados. Tienes los iframes desactivados o tu navegador no los soporta." + +#: wp-includes/script-loader.php:323 wp-includes/script-loader.php:350 +#: wp-includes/js/tinymce/langs/wp-langs.php:30 +#: wp-admin/includes/dashboard.php:146 +#: wp-admin/includes/class-wp-posts-list-table.php:994 +#: wp-admin/includes/image-edit.php:74 wp-admin/includes/media.php:1298 +#: wp-admin/includes/media.php:1560 wp-admin/includes/internal-linking.php:115 +#: wp-admin/includes/template.php:370 wp-admin/includes/template.php:559 +#: wp-admin/includes/template.php:646 wp-admin/includes/theme-install.php:285 +#: wp-admin/includes/nav-menu.php:186 +#: wp-admin/includes/class-wp-terms-list-table.php:364 +#: wp-admin/includes/meta-boxes.php:104 wp-admin/includes/meta-boxes.php:150 +#: wp-admin/press-this.php:135 wp-admin/press-this.php:165 +#: wp-admin/press-this.php:193 wp-admin/press-this.php:315 +#: wp-admin/widgets.php:311 +msgid "Cancel" +msgstr "Cancelar" + +#: wp-includes/theme-compat/sidebar.php:74 +msgid "XFN" +msgstr "XFN" + +#: wp-includes/theme-compat/sidebar.php:74 +msgid "XHTML Friends Network" +msgstr "Red de amigos de XHTML" + +#: wp-includes/theme-compat/sidebar.php:41 +msgid "You are currently browsing the %2$s blog archives for the year %3$s." +msgstr "Actualmente estás viendo el archivo del sitio %2$s del año %3$s." + +#: wp-includes/theme-compat/sidebar.php:73 +msgid "This page validates as XHTML 1.0 Transitional" +msgstr "Esta página valida como XHTML 1.0 transicional" + +#: wp-includes/theme-compat/sidebar.php:73 +msgid "Valid XHTML" +msgstr "Valida XHTML" + +#: wp-includes/theme-compat/comments.php:88 +msgid "XHTML: You can use these tags: %s" +msgstr "XHTML: Puedes usar estas etiquetas: %s" + +#: wp-includes/script-loader.php:194 +#: wp-includes/js/tinymce/langs/wp-langs.php:31 +#: wp-includes/js/tinymce/wp-mce-help.php:258 wp-login.php:583 +#: wp-admin/includes/template.php:1373 wp-admin/includes/widgets.php:207 +msgid "Close" +msgstr "Cerrar" + +#: wp-includes/script-loader.php:193 +msgid "of" +msgstr "de" + +#: wp-includes/script-loader.php:192 +msgid "Image" +msgstr "Imagen" + +#: wp-includes/theme-compat/sidebar.php:44 +msgid "You have searched the %2$s blog archives for ‘%3$s’. If you are unable to find anything in these search results, you can try one of these links." +msgstr "Has buscado en el archivo del sitio %2$s el término ‘%3$s’. Si no te es posible encontrar nada en los resultados, puedes probar uno de estos enlaces." + +#: wp-includes/theme-compat/comments.php:84 +#: wp-includes/comment-template.php:1526 wp-admin/user-new.php:304 +#: wp-admin/user-edit.php:329 +msgid "Website" +msgstr "Web" + +#: wp-includes/theme-compat/comments.php:81 +msgid "Mail (will not be published)" +msgstr "Correo electrónico (no será publicado)" + +#: wp-includes/theme-compat/sidebar.php:75 wp-includes/default-widgets.php:299 +msgid "Powered by WordPress, state-of-the-art semantic personal publishing platform." +msgstr "Gestionado con WordPress, una avanzada plataforma semántica de publicación personal." + +#: wp-includes/theme-compat/comments.php:73 +msgid "Log out »" +msgstr "Salir »" + +#: wp-includes/theme-compat/comments.php:49 +msgid "Comments are closed." +msgstr "Los comentarios están cerrados." + +#: wp-includes/theme-compat/comments.php:26 +msgid "One Response to %2$s" +msgid_plural "%1$s Responses to %2$s" +msgstr[0] "Una Respuesta a %2$s" +msgstr[1] "%1$s Respuestas a %2$s" + +#: wp-includes/theme-compat/comments.php:17 +msgid "This post is password protected. Enter the password to view comments." +msgstr "Esta entrada está protegida. Para verla, escribe la contraseña:" + +#: wp-includes/theme-compat/comments-popup.php:38 +msgid "The URL to TrackBack this entry is: %s" +msgstr "La URL para realizar un TrackBack a esta entrada es: %s" + +#: wp-includes/theme-compat/comments-popup.php:35 +msgid "RSS feed for comments on this post." +msgstr "RSS feed para los comentarios de esta entrada." + +#: wp-includes/theme-compat/comments-popup.php:33 +#: wp-admin/edit-form-advanced.php:149 wp-admin/edit-comments.php:116 +#: wp-admin/edit-comments.php:146 +#: wp-admin/includes/class-wp-posts-list-table.php:284 +#: wp-admin/includes/class-wp-posts-list-table.php:899 +#: wp-admin/includes/class-wp-comments-list-table.php:216 +#: wp-admin/includes/file.php:16 wp-admin/includes/template.php:1465 +#: wp-admin/includes/template.php:1746 +#: wp-content/plugins/akismet/legacy.php:214 +msgid "Comments" +msgstr "Comentarios" + +#: wp-includes/theme-compat/comments-popup.php:118 +msgid "Powered by WordPress" +msgstr "Gestionado con WordPress" + +#: wp-includes/theme-compat/comments-popup.php:114 +msgid "Sorry, no posts matched your criteria." +msgstr "Lo siento, no hay nada que se ajuste a lo que buscas." + +#: wp-includes/theme-compat/comments-popup.php:98 +msgid "Say It!" +msgstr "Enviar" + +#: wp-includes/theme-compat/comments-popup.php:103 +msgid "Sorry, the comment form is closed at this time." +msgstr "Lo siento, el formulario de comentarios está cerrado en este momento." + +#: wp-includes/theme-compat/comments-popup.php:108 +msgid "Close this window." +msgstr "Cerrar esta ventana." + +#: wp-includes/script-loader.php:235 wp-admin/async-upload.php:55 +msgid "Dismiss" +msgstr "Omitir" + +#: wp-includes/category-template.php:852 +msgid "Feed for all posts filed under %s" +msgstr "Feed para todas las entradas archivadas en %s" + +#: wp-includes/deprecated.php:987 +msgid "Last updated" +msgstr "Última actualización" + +#: wp-includes/deprecated.php:62 +msgid "new WordPress Loop" +msgstr "nuevo Loop de WordPress" + +#: wp-includes/post-template.php:1413 +msgctxt "revisions column name" +msgid "New" +msgstr "Nuevo" + +#: wp-includes/post-template.php:1412 +msgctxt "revisions column name" +msgid "Old" +msgstr "Antiguo" + +#: wp-includes/post-template.php:1396 +msgid "Compare Revisions" +msgstr "Comparar revisiones" + +#: wp-includes/post-template.php:1213 wp-admin/includes/dashboard.php:171 +msgid "Submit" +msgstr "Enviar" + +#: wp-includes/script-loader.php:396 +msgid "Plugin Information:" +msgstr "Información del plugin:" + +#: wp-includes/post-template.php:1346 +msgctxt "post revision" +msgid "%1$s by %2$s" +msgstr "%1$s por %2$s" + +#: wp-includes/post-template.php:1280 +msgid "%1$s [Current Revision]" +msgstr "%s [Revisión Actual]" + +#: wp-includes/post-template.php:1276 +msgctxt "revision date format" +msgid "j F, Y @ G:i" +msgstr "j F, Y @ G:i" + +#: wp-includes/post-template.php:112 +msgid "Protected: %s" +msgstr "Protegido: %s" + +#: wp-includes/script-loader.php:555 +msgid "Saving Draft…" +msgstr "Guardando borrador…" + +#: wp-includes/script-loader.php:381 +msgid "Remove From Bulk Edit" +msgstr "Borrar desde la edición en bloque" + +#: wp-includes/script-loader.php:273 +msgid "No matches found." +msgstr "No se han encontrado coincidencias." + +#: wp-includes/pluggable.php:1039 wp-includes/pluggable.php:1049 +#: wp-includes/pluggable.php:1058 wp-includes/pluggable.php:1137 +#: wp-includes/pluggable.php:1144 wp-includes/pluggable.php:1152 +msgid "URL : %s" +msgstr "URL : %s" + +#: wp-includes/pluggable.php:1040 wp-includes/pluggable.php:1153 +msgid "Whois : http://whois.arin.net/rest/ip/%s" +msgstr "Whois : http://whois.arin.net/rest/ip/%s" + +#: wp-includes/capabilities.php:727 +msgid "Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead." +msgstr "El uso de niveles de usuarios por plugins y temas está obsoleto. Usa los perfiles y capacidades en su lugar." + +#: wp-includes/post-template.php:1414 +msgctxt "revisions column name" +msgid "Date Created" +msgstr "Fecha de creación" + +#: wp-includes/post-template.php:1416 wp-admin/includes/media.php:1796 +msgid "Actions" +msgstr "Acciones" + +#: wp-includes/author-template.php:55 +msgid "Use get_the_author() instead if you do not want the value echoed." +msgstr "Utiliza get_the_author() en su lugar si no quieres un valor vacío." + +#: wp-includes/author-template.php:143 +msgid "Visit %s’s website" +msgstr "Visitar el sitio de %s" + +#: wp-includes/author-template.php:209 wp-includes/author-template.php:323 +msgid "Posts by %s" +msgstr "Entradas de %s" + +#: wp-includes/comment-template.php:30 wp-includes/theme.php:236 +msgid "Anonymous" +msgstr "Anónimo" + +#: wp-includes/comment-template.php:580 wp-includes/comment-template.php:976 +msgid "% Comments" +msgstr "% comentarios" + +#: wp-includes/comment-template.php:582 wp-includes/comment-template.php:974 +msgid "No Comments" +msgstr "No hay comentarios" + +#: wp-includes/comment-template.php:584 wp-includes/comment-template.php:975 +msgid "1 Comment" +msgstr "1 comentario" + +#: wp-includes/comment-template.php:678 wp-includes/comment-template.php:1533 +#: wp-admin/comment.php:171 +msgctxt "noun" +msgid "Comment" +msgstr "Comentario" + +#: wp-includes/comment-template.php:679 wp-admin/includes/dashboard.php:725 +msgid "Trackback" +msgstr "Trackback" + +#: wp-includes/comment-template.php:680 wp-admin/includes/dashboard.php:722 +msgid "Pingback" +msgstr "Pingback" + +#: wp-includes/comment-template.php:726 +msgid "Use get_trackback_url() instead if you do not want the value echoed." +msgstr "Utiliza get_trackback_url() en su lugar si no quieres un valor vacío." + +#: wp-includes/comment-template.php:977 +msgid "Comments Off" +msgstr "Comentarios desactivados" + +#: wp-includes/comment-template.php:987 +msgid "Enter your password to view comments." +msgstr "Escribe tu contraseña para ver los comentarios." + +#: wp-includes/comment-template.php:1014 +msgid "Comment on %s" +msgstr "Comentarios en %s" + +#: wp-includes/comment-template.php:1039 wp-admin/includes/dashboard.php:683 +#: wp-admin/includes/class-wp-comments-list-table.php:415 +msgid "Reply" +msgstr "Responder" + +#: wp-includes/comment-template.php:1040 +msgid "Log in to Reply" +msgstr "Inicia sesión para responder" + +#: wp-includes/comment-template.php:1100 +msgid "Leave a Comment" +msgstr "Dejar un comentario" + +#: wp-includes/comment-template.php:1101 +msgid "Log in to leave a Comment" +msgstr "Inicia sesión para dejar un comentario" + +#: wp-includes/comment-template.php:1140 +msgid "Click here to cancel reply." +msgstr "Clic para cancelar respuesta." + +#: wp-includes/comment-template.php:1354 +msgid "%s says:" +msgstr "%s dice:" + +#: wp-includes/comment-template.php:1357 +msgid "Your comment is awaiting moderation." +msgstr "Tu comentario está pendiente de moderación" + +#: wp-includes/comment-template.php:1364 +msgid "%1$s at %2$s" +msgstr "%1$s a las %2$s" + +#: wp-includes/comment-template.php:1364 +msgid "(Edit)" +msgstr "(Editar)" + +#: wp-includes/comment-template.php:1524 +msgid "Email" +msgstr "Correo electrónico" + +#: wp-includes/comment-template.php:1530 +msgid "Required fields are marked %s" +msgstr "Los campos necesarios están marcados %s" + +#: wp-includes/comment-template.php:1535 +msgid "Logged in as %2$s. Log out?" +msgstr "Conectado como %2$s. ¿Quieres salir?" + +#: wp-includes/comment-template.php:1536 +msgid "Your email address will not be published." +msgstr "Tu dirección de correo electrónico no será publicada." + +#: wp-includes/comment-template.php:1537 +msgid "You may use these HTML tags and attributes: %s" +msgstr "Puedes usar las siguientes etiquetas y atributos HTML: %s" + +#: wp-includes/comment-template.php:1542 +msgid "Cancel reply" +msgstr "Cancelar respuesta" + +#: wp-includes/comment-template.php:1543 +msgid "Post Comment" +msgstr "Publicar comentario" + +#: wp-includes/comment.php:375 +msgid "Unapproved" +msgstr "Rechazado" + +#: wp-includes/comment.php:377 wp-admin/edit-form-comment.php:50 +msgctxt "adjective" +msgid "Approved" +msgstr "Aprobado" + +#: wp-includes/comment.php:379 wp-admin/edit-form-comment.php:52 +msgctxt "adjective" +msgid "Spam" +msgstr "Spam" + +#: wp-includes/comment.php:616 wp-includes/comment.php:618 +msgid "Duplicate comment detected; it looks as though you’ve already said that!" +msgstr "Comentario duplicado: ¡parece que ya había sido enviado antes!" + +#: wp-includes/comment.php:676 wp-includes/comment.php:678 +msgid "You are posting comments too quickly. Slow down." +msgstr "Estás enviando comentarios a demasiada velocidad. Un poco de calma." + +#: wp-includes/comment.php:1401 +msgid "Could not update comment status" +msgstr "No ha sido posible actualizar el estado del comentario" + +#: wp-includes/class-http.php:244 +msgid "A valid URL was not provided." +msgstr "No se ha facilitado una URL válida." + +#: wp-includes/class-http.php:247 +msgid "User has blocked requests through HTTP." +msgstr "El usuario ha bloqueado las peticiones a través de HTTP." + +#: wp-includes/class-http.php:771 wp-includes/class-http.php:1438 +#: wp-includes/class-http.php:1455 +msgid "Too many redirects." +msgstr "Demasiadas redirecciones." + +#: wp-includes/class-http.php:851 wp-includes/class-http.php:1005 +msgid "Malformed URL: %s" +msgstr "La URL %s está mal formada" + +#: wp-includes/class-http.php:881 wp-includes/class-http.php:1066 +msgid "Could not open handle for fopen() to %s" +msgstr "No se pudo utilizar la función fopen() para %s." + +#: wp-includes/user.php:80 +msgid "ERROR: The username field is empty." +msgstr "ERROR: El campo Nombre de usuario está vacío." + +#: wp-includes/user.php:83 +msgid "ERROR: The password field is empty." +msgstr "ERROR: El campo contraseña está vacío." + +#: wp-includes/user.php:91 +msgid "ERROR: Invalid username. Lost your password?" +msgstr "ERROR: El usuario es incorrecto. ¿La has olvidado?" + +#: wp-includes/user.php:96 +msgid "ERROR: Your account has been marked as a spammer." +msgstr "ERROR: Tu cuenta ha sido marcada como spammer." + +#: wp-includes/user.php:102 +msgid "Site Suspended." +msgstr "Sitio suspendido." + +#: wp-includes/user.php:111 +msgid "ERROR: The password you entered for the username %1$s is incorrect. Lost your password?" +msgstr "ERROR: La contraseña que introdujo para el usuario %1$s no es correcta. Has perdido tu contraseña?" + +#: wp-includes/user.php:137 +msgid "Please log in again." +msgstr "Por favor, accede de nuevo." + +#: wp-includes/user.php:1405 +msgid "Cannot create a user with an empty login name." +msgstr "No se puede crear un usuario con el nombre de identificación vacio." + +#: wp-includes/user.php:1408 +msgid "This username is already registered." +msgstr "Este usuario ya está registrado." + +#: wp-includes/user.php:1423 +msgid "This email address is already registered." +msgstr "Esta dirección de correo electrónico ya está registrada." + +#: wp-includes/user.php:1613 +msgid "AIM" +msgstr "AIM" + +#: wp-includes/user.php:1614 +msgid "Yahoo IM" +msgstr "Yahoo IM" + +#: wp-includes/user.php:1615 +msgid "Jabber / Google Talk" +msgstr "Jabber / Google Talk" + +#: wp-includes/load.php:422 +msgid "The site you have requested is not installed properly. Please contact the system administrator." +msgstr "El sitio que has solicitado no está instalado correctamente. Por favor, ponte en contacto con el administrador del sistema." + +#: wp-includes/registration-functions.php:7 wp-includes/registration.php:7 +msgid "This file no longer needs to be included." +msgstr "Ya no es necesario incluir este archivo." + +#: wp-includes/functions.php:396 +msgid "%s is a protected WP option and may not be modified" +msgstr "%s es una opción protegida de WP y no puede modificarse" + +#: wp-includes/functions.php:1740 +msgid "ERROR: %s is not a valid feed template." +msgstr "ERROR: %s no es una plantilla de feed válida." + +#: wp-includes/functions.php:2202 wp-includes/functions.php:2320 +msgid "Unable to create directory %s. Is its parent directory writable by the server?" +msgstr "No se pudo crear el directorio %s. Asegúrate de que el servidor tiene permisos de escritura para el directorio superior." + +#: wp-includes/functions.php:2299 +msgid "Empty filename" +msgstr "El nombre de archivo está vacío." + +#: wp-includes/functions.php:2303 +msgid "Invalid file type" +msgstr "Tipo de archivo no válido" + +#: wp-includes/functions.php:2326 +msgid "Could not write file %s" +msgstr "No se pudo escribir el archivo %s." + +#: wp-includes/functions.php:2574 +msgid "Your attempt to edit this attachment: “%s” has failed." +msgstr "Tu intento de editar este archivo: “%s” ha fallado." + +#: wp-includes/functions.php:2576 +msgid "Your attempt to add this category has failed." +msgstr "Tu intento de añadir esta categoría ha fallado." + +#: wp-includes/functions.php:2577 +msgid "Your attempt to delete this category: “%s” has failed." +msgstr "Tu intento de eliminar esta categoría: “%s” ha fallado." + +#: wp-includes/functions.php:2578 +msgid "Your attempt to edit this category: “%s” has failed." +msgstr "Tu intento de editar esta categoría: “%s” ha fallado." + +#: wp-includes/functions.php:2580 +msgid "Your attempt to delete this comment: “%s” has failed." +msgstr "Tu intento de borrar este comentario: “%s” ha fallado." + +#: wp-includes/functions.php:2581 +msgid "Your attempt to unapprove this comment: “%s” has failed." +msgstr "Tu intento de rechazar este comentario: “%s” ha fallado." + +#: wp-includes/functions.php:2582 +msgid "Your attempt to approve this comment: “%s” has failed." +msgstr "Tu intento de aprobar este comentario: “%s” ha fallado." + +#: wp-includes/functions.php:2583 +msgid "Your attempt to edit this comment: “%s” has failed." +msgstr "Tu intento de editar este comentario: “%s” ha fallado." + +#: wp-includes/functions.php:2584 +msgid "Your attempt to bulk modify comments has failed." +msgstr "Tu intento de modificar en bloque los comentarios ha fallado." + +#: wp-includes/functions.php:2585 +msgid "Your attempt to moderate comments has failed." +msgstr "Tu intento de moderar comentarios ha fallado." + +#: wp-includes/functions.php:2587 +msgid "Your attempt to add this link has failed." +msgstr "Tu intento de añadir este enlace ha fallado." + +#: wp-includes/functions.php:2588 +msgid "Your attempt to delete this link: “%s” has failed." +msgstr "Tu intento de borrar este enlace: “%s” ha fallado." + +#: wp-includes/functions.php:2589 +msgid "Your attempt to edit this link: “%s” has failed." +msgstr "Tu intento de editar este enlace: “%s” ha fallado." + +#: wp-includes/functions.php:2590 +msgid "Your attempt to bulk modify links has failed." +msgstr "Tu intento de modificar en bloque los enlaces ha fallado." + +#: wp-includes/functions.php:2592 +msgid "Your attempt to add this page has failed." +msgstr "Tu intento de añadir esta página ha fallado." + +#: wp-includes/functions.php:2593 +msgid "Your attempt to delete this page: “%s” has failed." +msgstr "Tu intento de borrar esta página: “%s” ha fallado." + +#: wp-includes/functions.php:2594 +msgid "Your attempt to edit this page: “%s” has failed." +msgstr "Tu intento de editar esta página: “%s” ha fallado." + +#: wp-includes/functions.php:2596 +msgid "Your attempt to edit this plugin file: “%s” has failed." +msgstr "Tu intento de editar este archivo de un plugin: “%s” ha fallado." + +#: wp-includes/functions.php:2597 +msgid "Your attempt to activate this plugin: “%s” has failed." +msgstr "Tu intento de activar este plugin: “%s” ha fallado." + +#: wp-includes/functions.php:2598 +msgid "Your attempt to deactivate this plugin: “%s” has failed." +msgstr "Tu intento de desactivar este plugin: “%s” ha fallado." + +#: wp-includes/functions.php:2599 +msgid "Your attempt to update this plugin: “%s” has failed." +msgstr "Su intento de actualizar este plugin: \"%s\" ha fallado." + +#: wp-includes/functions.php:2601 +msgid "Your attempt to add this post has failed." +msgstr "Tu intento de añadir esta entrada ha fallado." + +#: wp-includes/functions.php:2602 +msgid "Your attempt to delete this post: “%s” has failed." +msgstr "Tu intento de borrar esta entrada: “%s” ha fallado" + +#: wp-includes/functions.php:2603 +msgid "Your attempt to edit this post: “%s” has failed." +msgstr "Tu intento de editar esta entrada: “%s” ha fallado." + +#: wp-includes/functions.php:2605 +msgid "Your attempt to add this user has failed." +msgstr "Tu intento de añadir este usuario ha fallado." + +#: wp-includes/functions.php:2606 +msgid "Your attempt to delete users has failed." +msgstr "Tu intento de borrar estos usuarios ha fallado." + +#: wp-includes/functions.php:2607 +msgid "Your attempt to bulk modify users has failed." +msgstr "Tu intento de modificar en bloque usuarios ha fallado." + +#: wp-includes/functions.php:2608 +msgid "Your attempt to edit this user: “%s” has failed." +msgstr "Tu intento por editar este usuario: “%s” ha fallado." + +#: wp-includes/functions.php:2609 +msgid "Your attempt to modify the profile for: “%s” has failed." +msgstr "Tu intento de modificar el perfil de: “%s” ha fallado." + +#: wp-includes/functions.php:2611 +msgid "Your attempt to edit your settings has failed." +msgstr "Tu intento de editar tu configuración ha fallado." + +#: wp-includes/functions.php:2612 +msgid "Your attempt to change your permalink structure to: %s has failed." +msgstr "Tu intento de cambiar la estructura de enlaces permanentes a %s no ha tenido éxito." + +#: wp-includes/functions.php:2613 +msgid "Your attempt to edit this file: “%s” has failed." +msgstr "Tu intento de editar este fichero: “%s” ha fallado." + +#: wp-includes/functions.php:2614 +msgid "Your attempt to edit this theme file: “%s” has failed." +msgstr "Tu intento de editar este archivo del tema: “%s” ha fallado." + +#: wp-includes/functions.php:2615 +msgid "Your attempt to switch to this theme: “%s” has failed." +msgstr "Tu intento de cambiar este tema: “%s” ha fallado." + +#: wp-includes/functions.php:2617 +msgid "You are attempting to log out of %s" +msgstr "Estás intentando cerrar tu sesión en %s." + +#: wp-includes/functions.php:2637 wp-includes/functions.php:2639 +#: wp-admin/comment.php:176 +msgid "Are you sure you want to do this?" +msgstr "¿Seguro que quieres hacer esto?" + +#: wp-includes/functions.php:2656 +msgid "WordPress Failure Notice" +msgstr "Aviso de fallo de WordPress" + +#: wp-includes/functions.php:2659 +msgid "Do you really want to log out?" +msgstr "¿Estás seguro de que quieres desconectarte?" + +#: wp-includes/functions.php:2661 +msgid "Please try again." +msgstr "Por favor, inténtalo de nuevo." + +#: wp-includes/functions.php:2737 +msgid "« Back" +msgstr "« Volver" + +#: wp-includes/functions.php:2758 +msgid "WordPress › Error" +msgstr "WordPress › Error" + +#: wp-includes/functions.php:3141 wp-includes/admin-bar.php:240 +#: wp-admin/widgets.php:33 +msgid "Widgets" +msgstr "Widgets" + +#: wp-includes/functions.php:3303 wp-includes/functions.php:3343 +msgid "%1$s is deprecated since version %2$s! Use %3$s instead." +msgstr "%1$s está obsoleto desde la versión %2$s. Utiliza %3$s en su lugar." + +#: wp-includes/functions.php:3305 wp-includes/functions.php:3345 +msgid "%1$s is deprecated since version %2$s with no alternative available." +msgstr "%1$s está obsoleto desde la versión %2$s y no hay alternativas disponibles." + +#: wp-includes/functions.php:3387 +msgid "%1$s was called with an argument that is deprecated since version %2$s! %3$s" +msgstr "%1$s fue llamado con un argumento que está obsoleto desde la versión %2$s! %3$s" + +#: wp-includes/functions.php:3389 +msgid "%1$s was called with an argument that is deprecated since version %2$s with no alternative available." +msgstr "%1$s fue llamado con un argumento que está obsoleto desde la versión %2$s y no hay alternativas disponibles." + +#: wp-includes/functions.php:3421 +msgid "(This message was added in version %s.)" +msgstr "(Este mensaje se añadió en la versión %s.)" + +#: wp-includes/functions.php:3422 +msgid "%1$s was called incorrectly. %2$s %3$s" +msgstr "%1$s se llamó incorrectamente. %2$s %3$s" + +#: wp-includes/functions.php:4130 +msgid "Select a city" +msgstr "Selecciona una ciudad" + +#: wp-includes/functions.php:4175 wp-includes/functions.php:4179 +msgid "UTC" +msgstr "UTC" + +#: wp-includes/functions.php:4183 +msgid "Manual Offsets" +msgstr "Desplazamientos manuales" + +#: wp-includes/bookmark-template.php:82 +msgid "Last updated: %s" +msgstr "Última actualización: %s" + +#: wp-includes/bookmark-template.php:206 +msgid "Bookmarks" +msgstr "Marcadores" + +#: wp-includes/rss.php:900 +msgid "An error has occurred, which probably means the feed is down. Try again later." +msgstr "Ha ocurrido un error, probablemente el feed esté caído. Inténtalo de nuevo más tarde." + +#: wp-includes/cron.php:159 +msgid "This argument has changed to an array to match the behavior of the other cron functions." +msgstr "Este argumento ha cambiado a un array para que coincida con el comportamiento de otras funciones de cron." + +#: wp-includes/cron.php:314 +msgid "Once Hourly" +msgstr "Cada hora" + +#: wp-includes/cron.php:315 +msgid "Twice Daily" +msgstr "Dos veces al día" + +#: wp-includes/cron.php:316 +msgid "Once Daily" +msgstr "Cada día" + +#: wp-includes/taxonomy.php:49 +msgid "Navigation Menus" +msgstr "Menús de navegación" + +#: wp-includes/taxonomy.php:50 +msgid "Navigation Menu" +msgstr "Menú de Navegación" + +#: wp-includes/taxonomy.php:62 wp-admin/menu.php:88 +msgid "Link Categories" +msgstr "Categorías de enlaces" + +#: wp-includes/taxonomy.php:63 +msgid "Link Category" +msgstr "Categoría de enlaces" + +#: wp-includes/taxonomy.php:64 +msgid "Search Link Categories" +msgstr "Buscar categorías de enlaces" + +#: wp-includes/taxonomy.php:66 +msgid "All Link Categories" +msgstr "Todas las categorías de enlaces" + +#: wp-includes/taxonomy.php:67 +msgid "Edit Link Category" +msgstr "Editar categoría del enlace" + +#: wp-includes/taxonomy.php:68 +msgid "Update Link Category" +msgstr "Actualizar categoría de enlaces" + +#: wp-includes/taxonomy.php:69 +msgid "Add New Link Category" +msgstr "Añadir nueva categoría de enlaces" + +#: wp-includes/taxonomy.php:70 +msgid "New Link Category Name" +msgstr "Nuevo nombre de categoría de enlaces" + +#: wp-includes/taxonomy.php:92 wp-includes/taxonomy.php:93 +#: wp-admin/edit-form-advanced.php:112 +msgctxt "post format" +msgid "Format" +msgstr "Formato" + +#: wp-includes/taxonomy.php:399 +msgctxt "taxonomy general name" +msgid "Post Tags" +msgstr "Etiquetas de las entradas" + +#: wp-includes/taxonomy.php:399 +msgctxt "taxonomy general name" +msgid "Categories" +msgstr "Categorías" + +#: wp-includes/taxonomy.php:400 +msgctxt "taxonomy singular name" +msgid "Post Tag" +msgstr "Etiqueta de la entrada" + +#: wp-includes/taxonomy.php:400 +msgctxt "taxonomy singular name" +msgid "Category" +msgstr "Categoría" + +#: wp-includes/taxonomy.php:401 +msgid "Search Tags" +msgstr "Buscar etiquetas" + +#: wp-includes/taxonomy.php:401 +msgid "Search Categories" +msgstr "Buscar categorías" + +#: wp-includes/taxonomy.php:402 +msgid "Popular Tags" +msgstr "Etiquetas populares" + +#: wp-includes/taxonomy.php:403 +msgid "All Tags" +msgstr "Todas las etiquetas" + +#: wp-includes/taxonomy.php:403 wp-admin/includes/meta-boxes.php:657 +msgid "All Categories" +msgstr "Todas las categorías" + +#: wp-includes/taxonomy.php:404 +msgid "Parent Category" +msgstr "Categoría superior" + +#: wp-includes/taxonomy.php:405 +msgid "Parent Category:" +msgstr "Categoría superior:" + +#: wp-includes/taxonomy.php:406 +msgid "Edit Tag" +msgstr "Editar etiqueta" + +#: wp-includes/taxonomy.php:406 +msgid "Edit Category" +msgstr "Editar Categoría" + +#: wp-includes/taxonomy.php:407 +msgid "Update Tag" +msgstr "Etiqueta actualizada" + +#: wp-includes/taxonomy.php:407 +msgid "Update Category" +msgstr "Actualizar categoría" + +#: wp-includes/taxonomy.php:408 +msgid "Add New Tag" +msgstr "Añadir nueva etiqueta" + +#: wp-includes/taxonomy.php:408 +msgid "Add New Category" +msgstr "Añadir nueva categoría" + +#: wp-includes/taxonomy.php:409 +msgid "New Tag Name" +msgstr "Nombre de la nueva etiqueta" + +#: wp-includes/taxonomy.php:409 +msgid "New Category Name" +msgstr "Nombre de la nueva categoría" + +#: wp-includes/taxonomy.php:411 +msgid "Add or remove tags" +msgstr "Añadir o quitar etiquetas" + +#: wp-includes/taxonomy.php:412 +msgid "Choose from the most used tags" +msgstr "Elige entre las etiquetas más utilizadas" + +#: wp-includes/taxonomy.php:488 wp-includes/taxonomy.php:813 +#: wp-includes/taxonomy.php:941 wp-includes/taxonomy.php:1126 +#: wp-includes/taxonomy.php:1793 wp-includes/taxonomy.php:2062 +msgid "Invalid Taxonomy" +msgstr "Taxonomía no válida" + +#: wp-includes/taxonomy.php:808 wp-includes/taxonomy.php:2839 +msgid "Empty Term" +msgstr "Término vacío" + +#: wp-includes/taxonomy.php:1931 wp-includes/taxonomy.php:2233 +#: wp-admin/includes/class-wp-terms-list-table.php:23 +msgid "Invalid taxonomy" +msgstr "Taxonomia no válida" + +#: wp-includes/taxonomy.php:1938 +msgid "Invalid term ID" +msgstr "ID del término no válido" + +#: wp-includes/taxonomy.php:1941 wp-includes/taxonomy.php:2259 +msgid "A name is required for this term" +msgstr "Este término necesita un nombre." + +#: wp-includes/taxonomy.php:1979 +msgid "A term with the name provided already exists with this parent." +msgstr "Un término con el nombre dado ya existe en este nivel." + +#: wp-includes/taxonomy.php:1983 wp-includes/taxonomy.php:1990 +#: wp-includes/taxonomy.php:2000 +msgid "Could not insert term into the database" +msgstr "No ha sido posible insertar el término en la base de datos." + +#: wp-includes/taxonomy.php:1994 +msgid "A term with the name provided already exists." +msgstr "Ya existe un término igual al facilitado." + +#: wp-includes/taxonomy.php:2292 +msgid "The slug “%s” is already in use by another term" +msgstr "El slug “%s” lo está utilizando ya otro término." + +#: wp-includes/taxonomy.php:3003 +msgid "Invalid object ID" +msgstr "El ID del objeto no es válido" + +#: wp-includes/default-widgets.php:17 +msgid "Your site’s WordPress Pages" +msgstr "Las Páginas de tu sitio de WordPress" + +#: wp-includes/default-widgets.php:66 wp-includes/default-widgets.php:196 +#: wp-includes/default-widgets.php:262 wp-includes/default-widgets.php:317 +#: wp-includes/default-widgets.php:357 wp-includes/default-widgets.php:403 +#: wp-includes/default-widgets.php:489 wp-includes/default-widgets.php:582 +#: wp-includes/default-widgets.php:679 wp-includes/default-widgets.php:1026 +#: wp-includes/default-widgets.php:1099 +#: wp-content/plugins/akismet/widget.php:51 +msgid "Title:" +msgstr "Título:" + +#: wp-includes/default-widgets.php:68 +msgid "Sort by:" +msgstr "Ordenar por:" + +#: wp-includes/default-widgets.php:70 +msgid "Page title" +msgstr "Título de la página" + +#: wp-includes/default-widgets.php:71 +msgid "Page order" +msgstr "Orden de la página" + +#: wp-includes/default-widgets.php:72 +msgid "Page ID" +msgstr "ID de la página" + +#: wp-includes/default-widgets.php:76 +msgid "Exclude:" +msgstr "Excluir:" + +#: wp-includes/default-widgets.php:78 +msgid "Page IDs, separated by commas." +msgstr "IDs de página, separados por comas." + +#: wp-includes/default-widgets.php:93 +msgid "Your blogroll" +msgstr "Tus sitios de interés" + +#: wp-includes/default-widgets.php:94 wp-admin/link-manager.php:40 +#: wp-admin/includes/class-wp-terms-list-table.php:106 wp-admin/menu.php:84 +#: wp-admin/menu.php:85 +msgid "Links" +msgstr "Enlaces" + +#: wp-includes/default-widgets.php:108 wp-includes/default-widgets.php:143 +msgid "All Links" +msgstr "Todos los enlaces" + +#: wp-includes/default-widgets.php:141 +msgid "Select Link Category" +msgstr "Elige la categoría del enlace" + +#: wp-includes/default-widgets.php:154 +msgid "Show Link Image" +msgstr "Mostrar la imagen del enlace" + +#: wp-includes/default-widgets.php:156 +msgid "Show Link Name" +msgstr "Mostrar el nombre del enlace" + +#: wp-includes/default-widgets.php:158 +msgid "Show Link Description" +msgstr "Mostrar la descripción del enlace" + +#: wp-includes/default-widgets.php:160 +msgid "Show Link Rating" +msgstr "Mostrar la clasificación del enlace" + +#: wp-includes/default-widgets.php:174 +msgid "A search form for your site" +msgstr "Un formulario de búsqueda para tu sitio" + +#: wp-includes/default-widgets.php:217 +msgid "A monthly archive of your site’s posts" +msgstr "Un archivo mensual de las entradas de tu sitio" + +#: wp-includes/default-widgets.php:233 +msgid "Select Month" +msgstr "Elegir mes" + +#: wp-includes/default-widgets.php:264 wp-includes/default-widgets.php:493 +msgid "Display as dropdown" +msgstr "Mostrar como desplegable" + +#: wp-includes/default-widgets.php:266 wp-includes/default-widgets.php:496 +msgid "Show post counts" +msgstr "Mostrar la cantidad de entradas" + +#: wp-includes/default-widgets.php:282 +msgid "Log in/out, admin, feed and WordPress links" +msgstr "Inicio/Cierre de sesión, administración, RSS y enlaces de WordPress" + +#: wp-includes/default-widgets.php:297 +msgid "Syndicate this site using RSS 2.0" +msgstr "Suscribirse a este sitio usando RSS 2.0" + +#: wp-includes/default-widgets.php:297 +msgid "Entries RSS" +msgstr "RSS de las entradas" + +#: wp-includes/default-widgets.php:298 +msgid "The latest comments to all posts in RSS" +msgstr "Últimos comentarios a todas las entradas en RSS" + +#: wp-includes/default-widgets.php:298 +msgid "Comments RSS" +msgstr "RSS de los comentarios" + +#: wp-includes/default-widgets.php:330 +msgid "A calendar of your site’s posts" +msgstr "Un calendario de las entradas de tu sitio" + +#: wp-includes/default-widgets.php:331 wp-includes/general-template.php:1149 +msgid "Calendar" +msgstr "Calendario" + +#: wp-includes/default-widgets.php:371 +msgid "Arbitrary text or HTML" +msgstr "Texto o HTML arbitrario" + +#: wp-includes/default-widgets.php:373 +msgid "Text" +msgstr "Texto" + +#: wp-includes/default-widgets.php:408 +msgid "Automatically add paragraphs" +msgstr "Añadir automáticamente parágrafos" + +#: wp-includes/default-widgets.php:421 +msgid "A list or dropdown of categories" +msgstr "Una lista o desplegable de categorías" + +#: wp-includes/default-widgets.php:440 +msgid "Select Category" +msgstr "Elegir categoría" + +#: wp-includes/default-widgets.php:499 +msgid "Show hierarchy" +msgstr "Mostrar jerarquía" + +#: wp-includes/default-widgets.php:513 +msgid "The most recent posts on your site" +msgstr "Las entradas más recientes de tu sitio" + +#: wp-includes/default-widgets.php:514 wp-includes/default-widgets.php:536 +msgid "Recent Posts" +msgstr "Entradas recientes" + +#: wp-includes/default-widgets.php:585 +msgid "Number of posts to show:" +msgstr "Número de entradas a mostrar:" + +#: wp-includes/default-widgets.php:599 +msgid "The most recent comments" +msgstr "Los comentarios más recientes" + +#: wp-includes/default-widgets.php:600 wp-includes/default-widgets.php:638 +#: wp-admin/includes/dashboard.php:43 +msgid "Recent Comments" +msgstr "Comentarios recientes" + +#: wp-includes/default-widgets.php:651 +msgctxt "widgets" +msgid "%1$s on %2$s" +msgstr "%1$s en %2$s" + +#: wp-includes/default-widgets.php:682 wp-admin/includes/dashboard.php:765 +msgid "Number of comments to show:" +msgstr "Número de comentarios a mostrar:" + +#: wp-includes/default-widgets.php:696 +msgid "Entries from any RSS or Atom feed" +msgstr "Entradas desde cualquier feed RSS o Atom" + +#: wp-includes/default-widgets.php:698 wp-admin/import.php:35 +msgid "RSS" +msgstr "RSS" + +#: wp-includes/default-widgets.php:734 wp-admin/includes/dashboard.php:1094 +msgid "Unknown Feed" +msgstr "Feed desconocido" + +#: wp-includes/default-widgets.php:740 +msgid "Syndicate this content" +msgstr "Sindicar este contenido" + +#: wp-includes/default-widgets.php:788 wp-admin/includes/dashboard.php:786 +#: wp-admin/includes/dashboard.php:902 +msgid "RSS Error: %s" +msgstr "Error en el RSS: %s" + +#: wp-includes/default-widgets.php:804 +msgid "An error has occurred; the feed is probably down. Try again later." +msgstr "Ha ocurrido un error; probablemente el feed está caído. Inténtalo de nuevo más tarde." + +#: wp-includes/default-widgets.php:818 +msgid "Untitled" +msgstr "Sin título" + +#: wp-includes/default-widgets.php:898 +msgid "RSS Error: %s" +msgstr "RSS Error: %s" + +#: wp-includes/default-widgets.php:902 +msgid "Enter the RSS feed URL here:" +msgstr "Introduce la URL del feed RSS aquí:" + +#: wp-includes/default-widgets.php:905 +msgid "Give the feed a title (optional):" +msgstr "Dale un título al feed (opcional):" + +#: wp-includes/default-widgets.php:908 +msgid "How many items would you like to display?" +msgstr "¿Cuantos elementos te gustaría mostrar?" + +#: wp-includes/default-widgets.php:917 +msgid "Display item content?" +msgstr "¿Mostrar el contenido?" + +#: wp-includes/default-widgets.php:920 +msgid "Display item author if available?" +msgstr "¿Mostrar el autor si está disponible?" + +#: wp-includes/default-widgets.php:923 +msgid "Display item date?" +msgstr "¿Mostrar la fecha?" + +#: wp-includes/default-widgets.php:989 +msgid "Your most used tags in cloud format" +msgstr "Las etiquetas más utilizadas en formato de nube" + +#: wp-includes/default-widgets.php:990 +msgid "Tag Cloud" +msgstr "Nube de etiquetas" + +#: wp-includes/default-widgets.php:1000 wp-admin/includes/dashboard.php:527 +#: wp-admin/includes/class-wp-posts-list-table.php:280 +msgid "Tags" +msgstr "Etiquetas" + +#: wp-includes/default-widgets.php:1028 +msgid "Taxonomy:" +msgstr "Taxonomía:" + +#: wp-includes/default-widgets.php:1056 +msgid "Use this widget to add one of your custom menus as a widget." +msgstr "Usa este widget para añadir uno de tus menús de navegación como widget." + +#: wp-includes/default-widgets.php:1057 wp-admin/includes/theme.php:304 +msgid "Custom Menu" +msgstr "Menú personalizado" + +#: wp-includes/default-widgets.php:1094 +msgid "No menus have been created yet. Create some." +msgstr "Aún no se han creado menús. Crea alguno." + +#: wp-includes/default-widgets.php:1103 wp-admin/nav-menus.php:487 +msgid "Select Menu:" +msgstr "Elegir menú:" + +#: wp-includes/feed-rss2-comments.php:22 +msgid "Comments on: %s" +msgstr "Comentarios en: %s" + +#: wp-includes/feed-rss2-comments.php:24 +msgid "Comments for %s searching on %s" +msgstr "Comentarios para %s buscando en %s" + +#: wp-includes/feed-rss2-comments.php:26 wp-includes/feed-atom-comments.php:23 +msgid "Comments for %s" +msgstr "Comentarios para %s" + +#: wp-includes/feed-rss2-comments.php:45 wp-includes/feed-atom-comments.php:53 +msgid "Comment on %1$s by %2$s" +msgstr "Comentario en %1$s por %2$s" + +#: wp-includes/feed-rss2-comments.php:47 wp-includes/feed-atom-comments.php:55 +msgid "By: %s" +msgstr "Por: %s" + +#: wp-includes/feed-rss2-comments.php:55 +msgid "Protected Comments: Please enter your password to view comments." +msgstr "Comentarios protegidos: Por favor, escribe tu contraseña para ver los comentarios." + +#: wp-includes/feed-atom-comments.php:19 +msgid "Comments on %s" +msgstr "Comentarios en %s" + +#: wp-includes/feed-atom-comments.php:21 +msgid "Comments for %1$s searching on %2$s" +msgstr "Comentarios para %1$s buscando en %2$s" + +#: wp-includes/nav-menu.php:226 wp-includes/nav-menu.php:233 +msgid "The menu name %s conflicts with another menu name. Please try another." +msgstr "El nombre de menú %s está creando un conflicto con otro nombre de menú. Por favor, selecciona otro nombre." + +#: wp-includes/nav-menu.php:275 +msgid "The given object ID is not that of a menu item." +msgstr "El ID de objeto dado no es de un objeto de menú." + +#: wp-includes/nav-menu.php:580 +msgid "Custom" +msgstr "Personalizado" + +#: wp-includes/query.php:146 wp-includes/query.php:167 +#: wp-includes/query.php:187 wp-includes/query.php:211 +#: wp-includes/query.php:235 wp-includes/query.php:259 +#: wp-includes/query.php:288 wp-includes/query.php:308 +#: wp-includes/query.php:328 wp-includes/query.php:348 +#: wp-includes/query.php:369 wp-includes/query.php:389 +#: wp-includes/query.php:419 wp-includes/query.php:448 +#: wp-includes/query.php:468 wp-includes/query.php:495 +#: wp-includes/query.php:515 wp-includes/query.php:535 +#: wp-includes/query.php:555 wp-includes/query.php:575 +#: wp-includes/query.php:604 wp-includes/query.php:631 +#: wp-includes/query.php:651 wp-includes/query.php:671 +#: wp-includes/query.php:691 wp-includes/query.php:711 +msgid "Conditional query tags do not work before the query is run. Before then, they always return false." +msgstr "Las etiquetas de las consultas condicionales no funcionan antes de ejecutar la consulta. Haciéndolo antes, siempre devuelven falso." + +#: wp-includes/query.php:1921 +msgid "\"caller_get_posts\" is deprecated. Use \"ignore_sticky_posts\" instead." +msgstr "\"caller_get_posts\" está obsoleto. Utilice \"ignore_sticky_posts\" en su lugar." + +#: wp-includes/formatting.php:40 wp-includes/formatting.php:2898 +msgctxt "opening curly quote" +msgid "“" +msgstr "“" + +#: wp-includes/formatting.php:42 +msgctxt "closing curly quote" +msgid "”" +msgstr "”" + +#: wp-includes/formatting.php:1827 +msgid "%s min" +msgid_plural "%s mins" +msgstr[0] "%s min" +msgstr[1] "%s mins" + +#: wp-includes/formatting.php:1833 +msgid "%s hour" +msgid_plural "%s hours" +msgstr[0] "%s hora" +msgstr[1] "%s horas" + +#: wp-includes/formatting.php:1839 +msgid "%s day" +msgid_plural "%s days" +msgstr[0] "%s día" +msgstr[1] "%s días" + +#: wp-includes/formatting.php:2440 +msgid "The email address entered did not appear to be a valid email address. Please enter a valid email address." +msgstr "La dirección de correo electrónico parece que no es válida. Por favor, introduce una válida." + +#: wp-includes/formatting.php:2524 +msgid "The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL." +msgstr "La dirección de WordPress parece no ser una URL válida. Por favor, introduce una válida." + +#: wp-includes/formatting.php:2534 +msgid "The Site address you entered did not appear to be a valid URL. Please enter a valid URL." +msgstr "La dirección del sitio no parece ser una URL válida. Por favor, introduce una válida." + +#: wp-includes/formatting.php:2682 +msgid ", " +msgstr ", " + +#: wp-includes/formatting.php:2684 +msgid ", and " +msgstr ", y" + +#: wp-includes/formatting.php:2686 +msgid " and " +msgstr "y" + +#: wp-includes/general-template.php:161 +msgid "Search for:" +msgstr "Buscar por:" + +#: wp-includes/general-template.php:187 wp-login.php:420 wp-login.php:445 +#: wp-login.php:476 wp-login.php:532 +msgid "Log in" +msgstr "Acceder" + +#: wp-includes/general-template.php:189 +msgid "Log out" +msgstr "Desconectar" + +#: wp-includes/general-template.php:258 wp-login.php:517 wp-login.php:637 +#: wp-admin/user-new.php:287 wp-admin/install.php:101 wp-admin/install.php:225 +#: wp-admin/includes/file.php:1006 +#: wp-admin/includes/class-wp-users-list-table.php:162 +#: wp-admin/user-edit.php:230 +msgid "Username" +msgstr "Nombre de usuario" + +#: wp-includes/general-template.php:259 wp-login.php:641 +#: wp-admin/user-new.php:309 wp-admin/install.php:229 +#: wp-admin/options-writing.php:111 +#: wp-admin/includes/class-wp-posts-list-table.php:794 +#: wp-admin/includes/file.php:1007 +msgid "Password" +msgstr "Contraseña" + +#: wp-includes/general-template.php:260 wp-login.php:645 +msgid "Remember Me" +msgstr "Recuérdame" + +#: wp-includes/general-template.php:261 wp-login.php:628 wp-login.php:647 +#: wp-admin/install.php:144 wp-admin/install.php:238 +msgid "Log In" +msgstr "Acceder" + +#: wp-includes/general-template.php:336 wp-login.php:422 wp-login.php:478 +#: wp-login.php:528 wp-login.php:661 +msgid "Register" +msgstr "Registrarse" + +#: wp-includes/general-template.php:340 wp-admin/admin-header.php:156 +msgid "Site Admin" +msgstr "Administrador del sitio" + +#: wp-includes/general-template.php:405 +msgid "The %s option is deprecated for the family of bloginfo() functions." +msgstr "La opción %s es obsoleta, ya no se utiliza en la familia de funciones bloginfo()." + +#: wp-includes/general-template.php:405 +msgid "Use the %s option instead." +msgstr "Usa la opción %s en su lugar." + +#: wp-includes/general-template.php:587 +msgid "Search Results %1$s %2$s" +msgstr "Resultados de la búsqueda %1$s %2$s" + +#: wp-includes/general-template.php:592 +msgid "Page not found" +msgstr "No se encontró la página" + +#: wp-includes/general-template.php:939 +msgid "%1$s %2$d" +msgstr "%1$s %2$d" + +#: wp-includes/general-template.php:1148 +msgctxt "calendar caption" +msgid "%1$s %2$s" +msgstr "%1$s %2$s" + +#: wp-includes/general-template.php:1174 wp-includes/general-template.php:1182 +msgid "View posts for %1$s %2$s" +msgstr "Ver todas las entradas para %1$s %2$s" + +#: wp-includes/general-template.php:1604 wp-includes/general-template.php:1627 +msgctxt "feed link" +msgid "»" +msgstr "»" + +#: wp-includes/general-template.php:1606 +msgid "%1$s %2$s Feed" +msgstr "%1$s %2$s Feed" + +#: wp-includes/general-template.php:1608 +msgid "%1$s %2$s Comments Feed" +msgstr "%1$s %2$s RSS de los comentarios" + +#: wp-includes/general-template.php:1629 +msgid "%1$s %2$s %3$s Comments Feed" +msgstr "%1$s %2$s %3$s RSS de los comentarios" + +#: wp-includes/general-template.php:1631 +msgid "%1$s %2$s %3$s Category Feed" +msgstr "%1$s %2$s %3$s RSS de la categoría" + +#: wp-includes/general-template.php:1633 +msgid "%1$s %2$s %3$s Tag Feed" +msgstr "%1$s %2$s %3$s RSS de la etiqueta" + +#: wp-includes/general-template.php:1635 +msgid "%1$s %2$s Posts by %3$s Feed" +msgstr "%1$s %2$s RSS de las entradas de %3$s" + +#: wp-includes/general-template.php:1637 +msgid "%1$s %2$s Search Results for “%3$s” Feed" +msgstr "%1$s %2$s Resultados de búsqueda para “%3$s” RSS" + +#: wp-includes/general-template.php:1808 wp-includes/general-template.php:1813 +#: wp-admin/press-this.php:620 +msgid "HTML" +msgstr "HTML" + +#: wp-includes/general-template.php:1809 wp-includes/general-template.php:1814 +#: wp-admin/press-this.php:621 +msgid "Visual" +msgstr "Visual" + +#: wp-includes/general-template.php:1962 +msgid "« Previous" +msgstr "« Anterior" + +#: wp-includes/general-template.php:1963 +msgid "Next »" +msgstr "Siguiente »" + +#: wp-includes/general-template.php:2070 wp-admin/includes/theme.php:269 +msgid "Blue" +msgstr "Azul" + +#: wp-includes/general-template.php:2072 +msgid "Gray" +msgstr "Gris" + +#: wp-includes/atomlib.php:133 +msgid "XML error: %s at line %d" +msgstr "Error de XML: %s en la línea %d" + +#: wp-includes/plugin.php:663 +msgid "Only a static class method or function can be used in an uninstall hook." +msgstr "Sólo una función o método de la clase estática pueden ser usados en un gancho de desinstalación." + +#: wp-includes/post.php:46 wp-admin/includes/media.php:1794 +#: wp-admin/menu.php:79 wp-admin/menu.php:223 +msgid "Media" +msgstr "Multimedia" + +#: wp-includes/post.php:62 wp-admin/revision.php:97 wp-admin/revision.php:123 +#: wp-admin/edit-form-advanced.php:160 +msgid "Revisions" +msgstr "Revisiones" + +#: wp-includes/post.php:63 +msgid "Revision" +msgstr "Revisión" + +#: wp-includes/post.php:78 +msgid "Navigation Menu Items" +msgstr "Elementos del menú de navegación" + +#: wp-includes/post.php:79 +msgid "Navigation Menu Item" +msgstr "Elemento del menú de navegación" + +#: wp-includes/post.php:89 +msgctxt "post" +msgid "Published" +msgstr "Publicada" + +#: wp-includes/post.php:92 +msgid "Published (%s)" +msgid_plural "Published (%s)" +msgstr[0] "Publicada (%s)" +msgstr[1] "Publicadas (%s)" + +#: wp-includes/post.php:96 +msgctxt "post" +msgid "Scheduled" +msgstr "Programada" + +#: wp-includes/post.php:99 +msgid "Scheduled (%s)" +msgid_plural "Scheduled (%s)" +msgstr[0] "Programada (%s)" +msgstr[1] "Programadas (%s)" + +#: wp-includes/post.php:103 +msgctxt "post" +msgid "Draft" +msgstr "Borrador" + +#: wp-includes/post.php:106 +msgid "Draft (%s)" +msgid_plural "Drafts (%s)" +msgstr[0] "Borrador (%s)" +msgstr[1] "Borradores (%s)" + +#: wp-includes/post.php:110 +msgctxt "post" +msgid "Pending" +msgstr "Pendiente" + +#: wp-includes/post.php:113 +msgid "Pending (%s)" +msgid_plural "Pending (%s)" +msgstr[0] "Pendiente (%s)" +msgstr[1] "Pendientes (%s)" + +#: wp-includes/post.php:117 +msgctxt "post" +msgid "Private" +msgstr "Privada" + +#: wp-includes/post.php:120 +msgid "Private (%s)" +msgid_plural "Private (%s)" +msgstr[0] "Privada (%s)" +msgstr[1] "Privadas (%s)" + +#: wp-includes/post.php:124 +msgctxt "post" +msgid "Trash" +msgstr "Papelera" + +#: wp-includes/post.php:127 +msgid "Trash (%s)" +msgid_plural "Trash (%s)" +msgstr[0] "Papelera (%s)" +msgstr[1] "Papelera (%s)" + +#: wp-includes/post.php:530 +msgid "Invalid post" +msgstr "Entrada no válida" + +#: wp-includes/post.php:588 wp-includes/post.php:609 +#: wp-admin/admin-ajax.php:1301 +#: wp-admin/includes/class-wp-posts-list-table.php:952 +#: wp-admin/includes/template.php:1634 wp-admin/includes/meta-boxes.php:78 +#: wp-admin/includes/meta-boxes.php:98 wp-admin/includes/meta-boxes.php:100 +msgid "Draft" +msgstr "Borrador" + +#: wp-includes/post.php:589 wp-admin/admin-ajax.php:1298 +#: wp-admin/includes/class-wp-posts-list-table.php:951 +#: wp-admin/includes/meta-boxes.php:74 wp-admin/includes/meta-boxes.php:96 +msgid "Pending Review" +msgstr "Pendiente de revisión" + +#: wp-includes/post.php:925 +msgid "Post types cannot exceed 20 characters in length" +msgstr "Los tipos de entradas no pueden exceder de 20 caracteres de longitud" + +#: wp-includes/post.php:1164 +msgctxt "post type general name" +msgid "Posts" +msgstr "Entradas" + +#: wp-includes/post.php:1164 +msgctxt "post type general name" +msgid "Pages" +msgstr "Páginas" + +#: wp-includes/post.php:1165 +msgctxt "post type singular name" +msgid "Post" +msgstr "Entrada" + +#: wp-includes/post.php:1165 +msgctxt "post type singular name" +msgid "Page" +msgstr "Página" + +#: wp-includes/post.php:1166 wp-admin/menu.php:68 +msgctxt "post" +msgid "Add New" +msgstr "Añadir nueva" + +#: wp-includes/post.php:1166 wp-admin/menu.php:93 +msgctxt "page" +msgid "Add New" +msgstr "Añadir nueva" + +#: wp-includes/post.php:1167 +msgid "Add New Post" +msgstr "Añadir nueva entrada" + +#: wp-includes/post.php:1167 +msgid "Add New Page" +msgstr "Añadir nueva página" + +#: wp-includes/post.php:1168 wp-admin/edit.php:200 wp-admin/press-this.php:594 +msgid "Edit Post" +msgstr "Editar entrada" + +#: wp-includes/post.php:1168 +msgid "Edit Page" +msgstr "Editar página" + +#: wp-includes/post.php:1169 wp-includes/admin-bar.php:127 +#: wp-admin/includes/template.php:1453 wp-admin/includes/template.php:1461 +msgid "New Post" +msgstr "Nueva entrada" + +#: wp-includes/post.php:1169 wp-admin/includes/template.php:1463 +msgid "New Page" +msgstr "Nueva página" + +#: wp-includes/post.php:1170 wp-admin/edit.php:200 +#: wp-content/plugins/akismet/legacy.php:294 +msgid "View Post" +msgstr "Ver entrada" + +#: wp-includes/post.php:1170 +msgid "View Page" +msgstr "Ver página" + +#: wp-includes/post.php:1171 +msgid "Search Posts" +msgstr "Buscar entradas" + +#: wp-includes/post.php:1171 +msgid "Search Pages" +msgstr "Buscar páginas" + +#: wp-includes/post.php:1172 +msgid "No posts found." +msgstr "No se encontraron entradas." + +#: wp-includes/post.php:1172 +msgid "No pages found." +msgstr "No se encontraron páginas." + +#: wp-includes/post.php:1173 +msgid "No posts found in Trash." +msgstr "Ningún post encontrado en la papelera." + +#: wp-includes/post.php:1173 +msgid "No pages found in Trash." +msgstr "Ninguna página encontrada en la papelera." + +#: wp-includes/post.php:1174 +msgid "Parent Page:" +msgstr "Página superior:" + +#: wp-includes/post.php:2292 +msgid "Passing an integer number of posts is deprecated. Pass an array of arguments instead." +msgstr "Pasar un número entero de entradas es obsoleto. Pasa una matriz de argumentos en su lugar." + +#: wp-includes/post.php:2429 +msgid "Content, title, and excerpt are empty." +msgstr "Contenido, título y extracto están vacios." + +#: wp-includes/post.php:2553 +msgid "Could not update post in the database" +msgstr "No ha sido posible actualizar la entrada en la base de datos" + +#: wp-includes/post.php:2569 +msgid "Could not insert post into the database" +msgstr "No ha sido posible insertar la entrada en la base de datos" + +#: wp-includes/post.php:2619 +msgid "The page template is invalid." +msgstr "La plantilla de la página no es válida." + +#: wp-includes/post.php:4632 wp-includes/js/tinymce/langs/wp-langs.php:295 +#: wp-includes/js/tinymce/langs/wp-langs.php:451 wp-admin/admin-ajax.php:1286 +#: wp-admin/includes/dashboard.php:509 +#: wp-admin/includes/class-wp-posts-list-table.php:742 +#: wp-admin/includes/media.php:1067 wp-admin/includes/media.php:1838 +#: wp-admin/includes/media.php:2154 wp-admin/includes/media.php:2184 +#: wp-admin/includes/media.php:2214 wp-admin/includes/internal-linking.php:82 +msgid "Title" +msgstr "Título" + +#: wp-includes/post.php:4633 wp-admin/includes/dashboard.php:246 +#: wp-admin/includes/dashboard.php:520 +msgid "Content" +msgstr "Contenido" + +#: wp-includes/post.php:4634 wp-admin/edit-form-advanced.php:136 +#: wp-admin/includes/meta-boxes.php:383 +msgid "Excerpt" +msgstr "Extracto" + +#: wp-includes/post.php:4824 +msgid "Cannot create a revision of a revision" +msgstr "No se puede crear una revisión de una revisión" + +#: wp-includes/post.php:4999 +msgid "You do not have permission to preview drafts." +msgstr "No tienes autorización para previsualizar borradores." + +#: wp-includes/post.php:5073 +msgctxt "Post format" +msgid "Standard" +msgstr "Estándar" + +#: wp-includes/post.php:5074 +msgctxt "Post format" +msgid "Aside" +msgstr "Minientrada" + +#: wp-includes/post.php:5075 +msgctxt "Post format" +msgid "Chat" +msgstr "Chat" + +#: wp-includes/post.php:5076 +msgctxt "Post format" +msgid "Gallery" +msgstr "Galería" + +#: wp-includes/post.php:5077 +msgctxt "Post format" +msgid "Link" +msgstr "Enlace" + +#: wp-includes/post.php:5078 +msgctxt "Post format" +msgid "Image" +msgstr "Imagen" + +#: wp-includes/post.php:5079 +msgctxt "Post format" +msgid "Quote" +msgstr "Cita" + +#: wp-includes/post.php:5080 +msgctxt "Post format" +msgid "Status" +msgstr "Estado" + +#: wp-includes/post.php:5081 +msgctxt "Post format" +msgid "Video" +msgstr "Vídeo" + +#: wp-includes/post.php:5082 +msgctxt "Post format" +msgid "Audio" +msgstr "Audio" + +#: wp-includes/widgets.php:67 wp-admin/includes/widgets.php:194 +#: wp-admin/widgets.php:273 +msgid "There are no options for this widget." +msgstr "No hay opciones para este widget." + +#: wp-includes/widgets.php:488 wp-includes/widgets.php:547 +msgid "Sidebar %d" +msgstr "Barra lateral %d" + +#: wp-includes/widgets.php:490 wp-admin/includes/file.php:20 +#: wp-admin/widgets.php:278 +msgid "Sidebar" +msgstr "Barra lateral" + +#: wp-includes/theme.php:242 +#: wp-admin/includes/class-wp-plugins-list-table.php:429 +#: wp-admin/includes/plugin.php:141 +msgid "Visit author homepage" +msgstr "Visitar la web del autor" + +#: wp-includes/theme.php:282 +msgid "File not readable." +msgstr "Archivo no legible." + +#: wp-includes/theme.php:334 +msgid "Template is missing." +msgstr "Falta la plantilla." + +#: wp-includes/theme.php:336 +msgid "The parent theme is missing. Please install the \"%s\" parent theme." +msgstr "No encontramos el tema principal. Por favor, instala el tema principal \"%s\"." + +#: wp-includes/theme.php:639 +msgid "Stylesheet is missing." +msgstr "Falta la hoja de estilo." + +#: wp-includes/admin-bar.php:91 +msgid "Edit My Profile" +msgstr "Editar mi perfil" + +#: wp-includes/admin-bar.php:93 wp-includes/admin-bar.php:95 +#: wp-includes/admin-bar.php:124 wp-admin/index.php:24 +#: wp-admin/user/menu.php:10 wp-admin/menu.php:25 wp-admin/menu.php:27 +msgid "Dashboard" +msgstr "Escritorio" + +#: wp-includes/admin-bar.php:96 wp-admin/admin-header.php:158 +msgid "Log Out" +msgstr "Cerrar sesión" + +#: wp-includes/admin-bar.php:112 wp-admin/menu.php:30 +msgid "My Sites" +msgstr "Mis sitios" + +#: wp-includes/admin-bar.php:119 wp-admin/includes/theme.php:299 +msgid "Blavatar" +msgstr "Blavatar" + +#: wp-includes/admin-bar.php:128 +msgid "Manage Comments" +msgstr "Gestionar comentarios" + +#: wp-includes/admin-bar.php:131 wp-admin/admin-header.php:117 +#: wp-admin/admin-header.php:137 +msgid "Visit Site" +msgstr "Visitar sitio" + +#: wp-includes/admin-bar.php:153 +msgid "Shortlink" +msgstr "Enlace corto" + +#: wp-includes/admin-bar.php:198 +msgctxt "admin bar menu group label" +msgid "Add New" +msgstr "Añadir nueva" + +#: wp-includes/admin-bar.php:220 wp-admin/menu.php:105 +msgid "Comments %s" +msgstr "Comentarios %s" + +#: wp-includes/admin-bar.php:234 wp-admin/menu.php:147 wp-admin/menu.php:152 +msgid "Appearance" +msgstr "Apariencia" + +#: wp-includes/admin-bar.php:243 wp-admin/menu.php:150 wp-admin/menu.php:155 +#: wp-admin/nav-menus.php:466 +msgid "Menus" +msgstr "Menús" + +#: wp-includes/admin-bar.php:277 wp-admin/menu.php:48 +msgid "%d WordPress Update" +msgstr "%d Actualización WordPress" + +#: wp-includes/admin-bar.php:279 wp-admin/menu.php:50 +msgid "%d Plugin Update" +msgid_plural "%d Plugin Updates" +msgstr[0] "%d Actualización plugin" +msgstr[1] "%d Actualizaciones plugins" + +#: wp-includes/admin-bar.php:281 wp-admin/menu.php:52 +msgid "%d Theme Update" +msgid_plural "%d Themes Updates" +msgstr[0] "%d Actualización tema" +msgstr[1] "%d Actualizaciones temas" + +#: wp-includes/admin-bar.php:286 wp-admin/menu.php:58 +msgid "Updates %s" +msgstr "Actualizar %s" + +#: wp-includes/link-template.php:517 +msgid "Comments Feed" +msgstr "Feed de comentarios" + +#: wp-includes/link-template.php:731 wp-includes/link-template.php:938 +#: wp-includes/link-template.php:1013 wp-includes/link-template.php:1054 +msgid "Edit This" +msgstr "Editar Esto" + +#: wp-includes/link-template.php:1015 wp-admin/edit-comments.php:203 +#: wp-admin/edit-comments.php:209 wp-admin/includes/dashboard.php:682 +#: wp-admin/includes/class-wp-comments-list-table.php:412 +msgid "Edit comment" +msgstr "Editar comentario" + +#: wp-includes/link-template.php:1056 wp-admin/link.php:104 +msgid "Edit Link" +msgstr "Editar enlace" + +#: wp-includes/link-template.php:1177 wp-includes/link-template.php:1455 +msgid "Previous Post" +msgstr "Entrada anterior" + +#: wp-includes/link-template.php:1177 wp-includes/link-template.php:1455 +msgid "Next Post" +msgstr "Entrada siguiente" + +#: wp-includes/link-template.php:1315 +msgid "First Post" +msgstr "Primera entrada" + +#: wp-includes/link-template.php:1315 +msgid "Last Post" +msgstr "Última entrada" + +#: wp-includes/link-template.php:1695 wp-content/plugins/akismet/legacy.php:239 +#: wp-content/plugins/akismet/legacy.php:306 +msgid "« Previous Page" +msgstr "« Página anterior" + +#: wp-includes/link-template.php:1696 wp-content/plugins/akismet/legacy.php:260 +#: wp-content/plugins/akismet/legacy.php:327 +msgid "Next Page »" +msgstr "Página siguiente »" + +#: wp-includes/link-template.php:1797 +msgid "Newer Comments »" +msgstr "Últimos comentarios »" + +#: wp-includes/link-template.php:1834 +msgid "« Older Comments" +msgstr "« Comentarios más viejos" + +#: wp-includes/link-template.php:2458 +msgid "This is the short link." +msgstr "Este es el enlace corto." + +#: wp-includes/locale.php:108 wp-includes/locale.php:118 +#: wp-includes/locale.php:131 wp-includes/js/tinymce/langs/wp-langs.php:55 +msgid "Sunday" +msgstr "Domingo" + +#: wp-includes/locale.php:109 wp-includes/locale.php:119 +#: wp-includes/locale.php:132 wp-includes/js/tinymce/langs/wp-langs.php:55 +msgid "Monday" +msgstr "Lunes" + +#: wp-includes/locale.php:110 wp-includes/locale.php:120 +#: wp-includes/locale.php:133 wp-includes/js/tinymce/langs/wp-langs.php:55 +msgid "Tuesday" +msgstr "Martes" + +#: wp-includes/locale.php:111 wp-includes/locale.php:121 +#: wp-includes/locale.php:134 wp-includes/js/tinymce/langs/wp-langs.php:55 +msgid "Wednesday" +msgstr "Miércoles" + +#: wp-includes/locale.php:112 wp-includes/locale.php:122 +#: wp-includes/locale.php:135 wp-includes/js/tinymce/langs/wp-langs.php:55 +msgid "Thursday" +msgstr "Jueves" + +#: wp-includes/locale.php:113 wp-includes/locale.php:123 +#: wp-includes/locale.php:136 wp-includes/js/tinymce/langs/wp-langs.php:55 +msgid "Friday" +msgstr "Viernes" + +#: wp-includes/locale.php:114 wp-includes/locale.php:124 +#: wp-includes/locale.php:137 wp-includes/js/tinymce/langs/wp-langs.php:55 +msgid "Saturday" +msgstr "Sábado" + +#: wp-includes/locale.php:118 +msgid "S_Sunday_initial" +msgstr "D" + +#: wp-includes/locale.php:119 +msgid "M_Monday_initial" +msgstr "L" + +#: wp-includes/locale.php:120 +msgid "T_Tuesday_initial" +msgstr "M" + +#: wp-includes/locale.php:121 +msgid "W_Wednesday_initial" +msgstr "X" + +#: wp-includes/locale.php:122 +msgid "T_Thursday_initial" +msgstr "J" + +#: wp-includes/locale.php:123 +msgid "F_Friday_initial" +msgstr "V" + +#: wp-includes/locale.php:124 +msgid "S_Saturday_initial" +msgstr "S" + +#: wp-includes/locale.php:131 wp-includes/js/tinymce/langs/wp-langs.php:56 +msgid "Sun" +msgstr "Dom" + +#: wp-includes/locale.php:132 wp-includes/js/tinymce/langs/wp-langs.php:56 +msgid "Mon" +msgstr "Lun" + +#: wp-includes/locale.php:133 wp-includes/js/tinymce/langs/wp-langs.php:56 +msgid "Tue" +msgstr "Mar" + +#: wp-includes/locale.php:134 wp-includes/js/tinymce/langs/wp-langs.php:56 +msgid "Wed" +msgstr "Mie" + +#: wp-includes/locale.php:135 wp-includes/js/tinymce/langs/wp-langs.php:56 +msgid "Thu" +msgstr "Jue" + +#: wp-includes/locale.php:136 wp-includes/js/tinymce/langs/wp-langs.php:56 +msgid "Fri" +msgstr "Vie" + +#: wp-includes/locale.php:137 wp-includes/js/tinymce/langs/wp-langs.php:56 +msgid "Sat" +msgstr "Sab" + +#: wp-includes/locale.php:140 wp-includes/locale.php:155 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "January" +msgstr "enero" + +#: wp-includes/locale.php:141 wp-includes/locale.php:156 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "February" +msgstr "febrero" + +#: wp-includes/locale.php:142 wp-includes/locale.php:157 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "March" +msgstr "marzo" + +#: wp-includes/locale.php:143 wp-includes/locale.php:158 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "April" +msgstr "abril" + +#: wp-includes/locale.php:144 wp-includes/locale.php:159 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "May" +msgstr "mayo" + +#: wp-includes/locale.php:145 wp-includes/locale.php:160 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "June" +msgstr "junio" + +#: wp-includes/locale.php:146 wp-includes/locale.php:161 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "July" +msgstr "julio" + +#: wp-includes/locale.php:147 wp-includes/locale.php:162 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "August" +msgstr "agosto" + +#: wp-includes/locale.php:148 wp-includes/locale.php:163 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "September" +msgstr "septiembre" + +#: wp-includes/locale.php:149 wp-includes/locale.php:164 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "October" +msgstr "octubre" + +#: wp-includes/locale.php:150 wp-includes/locale.php:165 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "November" +msgstr "noviembre" + +#: wp-includes/locale.php:151 wp-includes/locale.php:166 +#: wp-includes/js/tinymce/langs/wp-langs.php:53 +msgid "December" +msgstr "diciembre" + +#: wp-includes/locale.php:155 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Jan_January_abbreviation" +msgstr "ene" + +#: wp-includes/locale.php:156 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Feb_February_abbreviation" +msgstr "feb" + +#: wp-includes/locale.php:157 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Mar_March_abbreviation" +msgstr "mar" + +#: wp-includes/locale.php:158 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Apr_April_abbreviation" +msgstr "abr" + +#: wp-includes/locale.php:159 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "May_May_abbreviation" +msgstr "may" + +#: wp-includes/locale.php:160 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Jun_June_abbreviation" +msgstr "jun" + +#: wp-includes/locale.php:161 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Jul_July_abbreviation" +msgstr "jul" + +#: wp-includes/locale.php:162 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Aug_August_abbreviation" +msgstr "ago" + +#: wp-includes/locale.php:163 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Sep_September_abbreviation" +msgstr "sep" + +#: wp-includes/locale.php:164 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Oct_October_abbreviation" +msgstr "oct" + +#: wp-includes/locale.php:165 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Nov_November_abbreviation" +msgstr "nov" + +#: wp-includes/locale.php:166 wp-includes/js/tinymce/langs/wp-langs.php:54 +msgid "Dec_December_abbreviation" +msgstr "dic" + +#: wp-includes/locale.php:173 +msgid "am" +msgstr "am" + +#: wp-includes/locale.php:174 +msgid "pm" +msgstr "pm" + +#: wp-includes/locale.php:175 +msgid "AM" +msgstr "AM" + +#: wp-includes/locale.php:176 +msgid "PM" +msgstr "PM" + +#: wp-includes/locale.php:182 +msgid "number_format_thousands_sep" +msgstr "." + +#: wp-includes/locale.php:186 +msgid "number_format_decimal_point" +msgstr "," + +#: wp-includes/js/tinymce/langs/wp-langs.php:26 +msgid "Do you want to use the WYSIWYG mode for this textarea?" +msgstr "¿Quieres usar el editor visual en este área de texto?" + +#: wp-includes/js/tinymce/langs/wp-langs.php:27 +#: wp-admin/includes/template.php:1919 +#: wp-admin/includes/class-wp-list-table.php:289 +msgid "Apply" +msgstr "Aplicar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:28 +msgid "Insert" +msgstr "Insertar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:32 +msgid "Browse" +msgstr "Examinar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:33 +#: wp-includes/js/tinymce/langs/wp-langs.php:313 +msgid "Class" +msgstr "Clase" + +#: wp-includes/js/tinymce/langs/wp-langs.php:34 +msgid "-- Not set --" +msgstr "-- Sin configurar --" + +#: wp-includes/js/tinymce/langs/wp-langs.php:35 +#: wp-includes/js/tinymce/langs/wp-langs.php:240 +msgid "Copy/Cut/Paste is not available in Mozilla and Firefox." +msgstr "Copiar/Cortar/Pegar no está disponible en Mozilla y Firefox" + +#: wp-includes/js/tinymce/langs/wp-langs.php:36 +msgid "Currently not supported by your browser, use keyboard shortcuts instead." +msgstr "Actualmente no es compatible con tu navegador, en su lugar puedes utilizar los atajos de teclado." + +#: wp-includes/js/tinymce/langs/wp-langs.php:37 +msgid "Sorry, but we have noticed that your popup-blocker has disabled a window that provides application functionality. You will need to disable popup blocking on this site in order to fully utilize this tool." +msgstr "Disculpa, parece que tu bloqueador de ventanas emergentes ha bloqueado una ventana que proporciona funciones de la aplicación. Tendrás que desactivar el bloqueador si quieres usar esta herramienta." + +#: wp-includes/js/tinymce/langs/wp-langs.php:38 +msgid "Error: Invalid values entered, these are marked in red." +msgstr "Error: Se han introducido valores incorrectos que han sido marcados en rojo." + +#: wp-includes/js/tinymce/langs/wp-langs.php:39 +#: wp-includes/js/tinymce/langs/wp-langs.php:244 +msgid "More colors" +msgstr "Más colores" + +#: wp-includes/js/tinymce/langs/wp-langs.php:42 +#: wp-includes/js/tinymce/langs/wp-langs.php:281 +#: wp-admin/includes/media.php:952 wp-admin/includes/media.php:2106 +msgid "Alignment" +msgstr "Alineación" + +#: wp-includes/js/tinymce/langs/wp-langs.php:43 +#: wp-includes/js/tinymce/langs/wp-langs.php:288 +#: wp-includes/js/tinymce/langs/wp-langs.php:385 +#: wp-admin/custom-background.php:257 wp-admin/includes/media.php:828 +#: wp-admin/includes/media.php:2111 +msgid "Left" +msgstr "Izquierda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:44 +#: wp-includes/js/tinymce/langs/wp-langs.php:365 +#: wp-includes/js/tinymce/langs/wp-langs.php:386 +#: wp-admin/custom-background.php:261 wp-admin/includes/media.php:828 +#: wp-admin/includes/media.php:2113 +msgid "Center" +msgstr "Centrar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:45 +#: wp-includes/js/tinymce/langs/wp-langs.php:289 +#: wp-includes/js/tinymce/langs/wp-langs.php:383 +#: wp-admin/custom-background.php:265 wp-admin/includes/media.php:828 +#: wp-admin/includes/media.php:2115 +msgid "Right" +msgstr "Derecha" + +#: wp-includes/js/tinymce/langs/wp-langs.php:46 +msgid "Full" +msgstr "Completo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:49 +msgid "%Y-%m-%d" +msgstr "%d-%m-%Y" + +#: wp-includes/js/tinymce/langs/wp-langs.php:50 +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#: wp-includes/js/tinymce/langs/wp-langs.php:51 +msgid "Insert date" +msgstr "Insertar fecha" + +#: wp-includes/js/tinymce/langs/wp-langs.php:52 +msgid "Insert time" +msgstr "Insertar hora" + +#: wp-includes/js/tinymce/langs/wp-langs.php:59 +msgid "Print" +msgstr "Imprimir" + +#: wp-includes/js/tinymce/langs/wp-langs.php:62 +#: wp-includes/js/tinymce/langs/wp-langs.php:308 wp-admin/custom-header.php:440 +#: wp-admin/custom-background.php:184 +#: wp-admin/includes/class-wp-posts-list-table.php:555 +#: wp-admin/includes/class-wp-themes-list-table.php:170 +#: wp-admin/includes/class-wp-upgrader.php:1356 +#: wp-admin/includes/class-wp-upgrader.php:1413 +#: wp-admin/includes/theme-install.php:145 wp-admin/includes/meta-boxes.php:48 +msgid "Preview" +msgstr "Vista previa" + +#: wp-includes/js/tinymce/langs/wp-langs.php:65 +msgid "Direction left to right" +msgstr "Dirección de izquierda a derecha" + +#: wp-includes/js/tinymce/langs/wp-langs.php:66 +msgid "Direction right to left" +msgstr "Dirección de derecha a izquierda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:69 +msgid "Insert new layer" +msgstr "Insertar nueva capa" + +#: wp-includes/js/tinymce/langs/wp-langs.php:70 +msgid "Move forward" +msgstr "Avanzar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:71 +msgid "Move backward" +msgstr "Retroceder" + +#: wp-includes/js/tinymce/langs/wp-langs.php:72 +msgid "Toggle absolute positioning" +msgstr "Cambiar la posición absoluta" + +#: wp-includes/js/tinymce/langs/wp-langs.php:73 +msgid "New layer..." +msgstr "Nueva capa..." + +#: wp-includes/js/tinymce/langs/wp-langs.php:76 wp-admin/edit-link-form.php:27 +#: wp-admin/includes/image-edit.php:75 wp-admin/includes/nav-menu.php:497 +#: wp-admin/includes/widgets.php:211 wp-admin/includes/meta-boxes.php:25 +#: wp-admin/includes/meta-boxes.php:603 +msgid "Save" +msgstr "Guardar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:77 +msgid "Cancel all changes" +msgstr "Cancelar todos los cambios" + +#: wp-includes/js/tinymce/langs/wp-langs.php:80 +msgid "Insert non-breaking space character" +msgstr "Insertar un caracter de espacio" + +#: wp-includes/js/tinymce/langs/wp-langs.php:83 +msgid "Run spell checking" +msgstr "Iniciar el corrector ortográfico" + +#: wp-includes/js/tinymce/langs/wp-langs.php:84 +msgid "ieSpell not detected. Do you want to install it now?" +msgstr "No se ha detectado ieSpell. ¿Quieres instalarlo ahora?" + +#: wp-includes/js/tinymce/langs/wp-langs.php:87 +msgid "Horizontale rule" +msgstr "Regla horizontal" + +#: wp-includes/js/tinymce/langs/wp-langs.php:90 +msgid "Emotions" +msgstr "Emoticonos" + +#: wp-includes/js/tinymce/langs/wp-langs.php:93 +msgid "Find" +msgstr "Buscar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:94 +msgid "Find/Replace" +msgstr "Buscar/Remplazar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:97 +#: wp-includes/js/tinymce/langs/wp-langs.php:219 +#: wp-includes/js/tinymce/langs/wp-langs.php:273 +msgid "Insert/edit image" +msgstr "Insertar/Editar imagen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:100 +#: wp-includes/js/tinymce/langs/wp-langs.php:215 +#: wp-includes/js/tinymce/langs/wp-langs.php:290 +msgid "Insert/edit link" +msgstr "Insertar/Editar enlace" + +#: wp-includes/js/tinymce/langs/wp-langs.php:103 +msgid "Citation" +msgstr "Cita" + +#: wp-includes/js/tinymce/langs/wp-langs.php:104 +msgid "Abbreviation" +msgstr "Abreviatura" + +#: wp-includes/js/tinymce/langs/wp-langs.php:105 +msgid "Acronym" +msgstr "Acrónimo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:106 +msgid "Deletion" +msgstr "Borrado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:107 +msgid "Insertion" +msgstr "Insertar" + +#: wp-includes/js/tinymce/langs/wp-langs.php:108 +msgid "Insert/Edit Attributes" +msgstr "Insertar/Editar atributos" + +#: wp-includes/js/tinymce/langs/wp-langs.php:111 +msgid "Edit CSS Style" +msgstr "Editar la hoja de estilos CSS" + +#: wp-includes/js/tinymce/langs/wp-langs.php:114 +msgid "Paste as Plain Text" +msgstr "Pegar como texto plano" + +#: wp-includes/js/tinymce/langs/wp-langs.php:115 +msgid "Paste from Word" +msgstr "Pegar desde Word" + +#: wp-includes/js/tinymce/langs/wp-langs.php:116 wp-admin/update-core.php:204 +#: wp-admin/update-core.php:211 wp-admin/update-core.php:277 +#: wp-admin/update-core.php:284 wp-admin/includes/nav-menu.php:755 +#: wp-admin/includes/nav-menu.php:927 +msgid "Select All" +msgstr "Elegir todo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:119 +#: wp-includes/js/tinymce/langs/wp-langs.php:121 +msgid "Use CTRL+V on your keyboard to paste the text into the window." +msgstr "Usa CTRL+V en tu teclado para pegar el texto en la ventana." + +#: wp-includes/js/tinymce/langs/wp-langs.php:120 +msgid "Keep linebreaks" +msgstr "Conservar los saltos de línea" + +#: wp-includes/js/tinymce/langs/wp-langs.php:124 +msgid "Inserts a new table" +msgstr "Insertar una nueva tabla" + +#: wp-includes/js/tinymce/langs/wp-langs.php:125 +msgid "Insert row before" +msgstr "Insertar fila encima" + +#: wp-includes/js/tinymce/langs/wp-langs.php:126 +msgid "Insert row after" +msgstr "Insertar fila debajo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:127 +msgid "Delete row" +msgstr "Borrar fila" + +#: wp-includes/js/tinymce/langs/wp-langs.php:128 +msgid "Insert column before" +msgstr "Insertar columna a la izquierda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:129 +msgid "Insert column after" +msgstr "Insertar columna a la derecha" + +#: wp-includes/js/tinymce/langs/wp-langs.php:130 +msgid "Remove column" +msgstr "Borrar columna" + +#: wp-includes/js/tinymce/langs/wp-langs.php:131 +msgid "Split merged table cells" +msgstr "Dividir celdas combinadas" + +#: wp-includes/js/tinymce/langs/wp-langs.php:132 +msgid "Merge table cells" +msgstr "Combinar celdas" + +#: wp-includes/js/tinymce/langs/wp-langs.php:133 +msgid "Table row properties" +msgstr "Propiedades de fila" + +#: wp-includes/js/tinymce/langs/wp-langs.php:134 +msgid "Table cell properties" +msgstr "Propiedades de celda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:135 +msgid "Table properties" +msgstr "Propiedades de tabla" + +#: wp-includes/js/tinymce/langs/wp-langs.php:136 +msgid "Paste table row before" +msgstr "Pegar fila encima" + +#: wp-includes/js/tinymce/langs/wp-langs.php:137 +msgid "Paste table row after" +msgstr "Pegar fila debajo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:138 +msgid "Cut table row" +msgstr "Cortar fila" + +#: wp-includes/js/tinymce/langs/wp-langs.php:139 +msgid "Copy table row" +msgstr "Copiar fila" + +#: wp-includes/js/tinymce/langs/wp-langs.php:140 +msgid "Delete table" +msgstr "Borrar tabla" + +#: wp-includes/js/tinymce/langs/wp-langs.php:141 +msgid "Row" +msgstr "Fila" + +#: wp-includes/js/tinymce/langs/wp-langs.php:142 +msgid "Column" +msgstr "Columna" + +#: wp-includes/js/tinymce/langs/wp-langs.php:143 +msgid "Cell" +msgstr "Celda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:149 +msgid "Toggle fullscreen mode" +msgstr "Cambiar a modo pantalla completa" + +#: wp-includes/js/tinymce/langs/wp-langs.php:152 +#: wp-includes/js/tinymce/langs/wp-langs.php:302 +msgid "Insert / edit embedded media" +msgstr "Insertar / editar inserción de archivos" + +#: wp-includes/js/tinymce/langs/wp-langs.php:153 +msgctxt "media popup width" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:154 +msgctxt "media popup height" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:155 +msgid "Edit embedded media" +msgstr "Editar medios incrustados" + +#: wp-includes/js/tinymce/langs/wp-langs.php:158 +msgid "Document properties" +msgstr "Propiedades del documento" + +#: wp-includes/js/tinymce/langs/wp-langs.php:161 +msgid "Insert predefined template content" +msgstr "Insertar la plantilla predefinida de contenido" + +#: wp-includes/js/tinymce/langs/wp-langs.php:164 +msgid "Visual control characters on/off." +msgstr "Control visual de los caracteres on/off." + +#: wp-includes/js/tinymce/langs/wp-langs.php:167 +msgid "Toggle spellchecker" +msgstr "Activar/desactivar el corrector ortográfico" + +#: wp-includes/js/tinymce/langs/wp-langs.php:168 +msgid "Spellchecker settings" +msgstr "Opciones del corrector ortográfico" + +#: wp-includes/js/tinymce/langs/wp-langs.php:169 +msgid "Ignore word" +msgstr "Ignorar palabra" + +#: wp-includes/js/tinymce/langs/wp-langs.php:170 +msgid "Ignore all" +msgstr "Ignorar todo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:171 +msgid "Languages" +msgstr "Idiomas" + +#: wp-includes/js/tinymce/langs/wp-langs.php:172 +msgid "Please wait..." +msgstr "Un momento..." + +#: wp-includes/js/tinymce/langs/wp-langs.php:173 +msgid "Suggestions" +msgstr "Sugerencias" + +#: wp-includes/js/tinymce/langs/wp-langs.php:174 +msgid "No suggestions" +msgstr "No hay sugerencias" + +#: wp-includes/js/tinymce/langs/wp-langs.php:175 +msgid "No misspellings found." +msgstr "No hay errores ortográficos." + +#: wp-includes/js/tinymce/langs/wp-langs.php:178 +msgid "Insert Page Break" +msgstr "Insertar salto de página" + +#: wp-includes/js/tinymce/langs/wp-langs.php:182 +msgctxt "TinyMCE font styles" +msgid "Styles" +msgstr "Estilos" + +#: wp-includes/js/tinymce/langs/wp-langs.php:183 +msgid "Font size" +msgstr "Tamaño de la fuente" + +#: wp-includes/js/tinymce/langs/wp-langs.php:184 +msgid "Font family" +msgstr "Familia de la fuente" + +#: wp-includes/js/tinymce/langs/wp-langs.php:185 +msgid "Format" +msgstr "Formato" + +#: wp-includes/js/tinymce/langs/wp-langs.php:186 +msgid "Paragraph" +msgstr "Párrafo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:187 +msgid "Div" +msgstr "Div" + +#: wp-includes/js/tinymce/langs/wp-langs.php:188 +#: wp-includes/js/tinymce/wp-mce-help.php:216 +msgid "Address" +msgstr "Dirección" + +#: wp-includes/js/tinymce/langs/wp-langs.php:189 +msgid "Preformatted" +msgstr "Preformateado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:190 +#: wp-includes/js/tinymce/wp-mce-help.php:213 +msgid "Heading 1" +msgstr "Título 1" + +#: wp-includes/js/tinymce/langs/wp-langs.php:191 +#: wp-includes/js/tinymce/wp-mce-help.php:214 +msgid "Heading 2" +msgstr "Título 2" + +#: wp-includes/js/tinymce/langs/wp-langs.php:192 +#: wp-includes/js/tinymce/wp-mce-help.php:214 +msgid "Heading 3" +msgstr "Título 3" + +#: wp-includes/js/tinymce/langs/wp-langs.php:193 +#: wp-includes/js/tinymce/wp-mce-help.php:215 +msgid "Heading 4" +msgstr "Título 4" + +#: wp-includes/js/tinymce/langs/wp-langs.php:194 +#: wp-includes/js/tinymce/wp-mce-help.php:215 +msgid "Heading 5" +msgstr "Título 5" + +#: wp-includes/js/tinymce/langs/wp-langs.php:195 +#: wp-includes/js/tinymce/wp-mce-help.php:216 +msgid "Heading 6" +msgstr "Título 6" + +#: wp-includes/js/tinymce/langs/wp-langs.php:196 +#: wp-includes/js/tinymce/langs/wp-langs.php:239 +msgid "Blockquote" +msgstr "Cita" + +#: wp-includes/js/tinymce/langs/wp-langs.php:197 +msgid "Code" +msgstr "Código" + +#: wp-includes/js/tinymce/langs/wp-langs.php:198 +msgid "Code sample" +msgstr "Código de ejemplo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:199 +msgid "Definition term " +msgstr "Definición del término" + +#: wp-includes/js/tinymce/langs/wp-langs.php:200 +msgid "Definition description" +msgstr "Definición de descripción" + +#: wp-includes/js/tinymce/langs/wp-langs.php:201 +#: wp-includes/js/tinymce/wp-mce-help.php:212 +#: wp-includes/js/tinymce/wp-mce-help.php:225 +msgid "Bold" +msgstr "Negrita" + +#: wp-includes/js/tinymce/langs/wp-langs.php:202 +#: wp-includes/js/tinymce/wp-mce-help.php:212 +#: wp-includes/js/tinymce/wp-mce-help.php:225 +msgid "Italic" +msgstr "Cursiva" + +#: wp-includes/js/tinymce/langs/wp-langs.php:203 +#: wp-includes/js/tinymce/wp-mce-help.php:213 +msgid "Underline" +msgstr "Subrayado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:204 +#: wp-includes/js/tinymce/wp-mce-help.php:229 +msgid "Strikethrough" +msgstr "Tachado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:205 +#: wp-includes/js/tinymce/wp-mce-help.php:227 +msgid "Align Left" +msgstr "Alinear a la izquierda" + +#: wp-includes/js/tinymce/langs/wp-langs.php:206 +#: wp-includes/js/tinymce/wp-mce-help.php:228 +msgid "Align Center" +msgstr "Alinear al centro" + +#: wp-includes/js/tinymce/langs/wp-langs.php:207 +#: wp-includes/js/tinymce/wp-mce-help.php:229 +msgid "Align Right" +msgstr "Alinear a la derecha" + +#: wp-includes/js/tinymce/langs/wp-langs.php:208 +msgid "Align Full" +msgstr "Alineación completa" + +#: wp-includes/js/tinymce/langs/wp-langs.php:209 +msgid "Unordered list" +msgstr "Lista desordenada" + +#: wp-includes/js/tinymce/langs/wp-langs.php:210 +msgid "Ordered list" +msgstr "Lista ordenada" + +#: wp-includes/js/tinymce/langs/wp-langs.php:211 +msgid "Outdent" +msgstr "Disminuir margen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:212 +msgid "Indent" +msgstr "Aumentar margen" + +#: wp-includes/js/tinymce/langs/wp-langs.php:213 +#: wp-includes/js/tinymce/wp-mce-help.php:209 wp-admin/edit-comments.php:183 +#: wp-admin/edit-comments.php:191 wp-admin/edit.php:227 wp-admin/upload.php:188 +#: wp-admin/upload.php:200 wp-admin/includes/image-edit.php:56 +#: wp-admin/includes/media.php:1302 wp-admin/includes/template.php:406 +#: wp-admin/includes/template.php:409 +msgid "Undo" +msgstr "Deshacer" + +#: wp-includes/js/tinymce/langs/wp-langs.php:214 +#: wp-includes/js/tinymce/wp-mce-help.php:209 +#: wp-admin/includes/image-edit.php:57 +msgid "Redo" +msgstr "Rehacer" + +#: wp-includes/js/tinymce/langs/wp-langs.php:216 +msgctxt "link popup width" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:217 +msgctxt "link popup height" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:218 +msgid "Unlink" +msgstr "Quitar enlace" + +#: wp-includes/js/tinymce/langs/wp-langs.php:220 +msgctxt "image popup width" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:221 +msgctxt "image popup height" +msgid "0" +msgstr "0" + +#: wp-includes/js/tinymce/langs/wp-langs.php:222 +msgid "Cleanup messy code" +msgstr "Limpiar el código desordenado" + +#: wp-includes/js/tinymce/langs/wp-langs.php:223 +msgid "Edit HTML Source" +msgstr "Editar HTML" + +#: wp-includes/js/tinymce/langs/wp-langs.php:224 +msgid "Subscript" +msgstr "Subíndice" + +#: wp-includes/js/tinymce/langs/wp-langs.php:225 +msgid "Superscript" +msgstr "Superíndice" + +#: wp-includes/js/tinymce/langs/wp-langs.php:226 +msgid "Insert horizontal ruler" +msgstr "Insertar línea horizontal" + +#: wp-includes/js/tinymce/langs/wp-langs.php:227 +msgid "Remove formatting" +msgstr "Eliminar formato" + +#: wp-includes/js/tinymce/langs/wp-langs.php:228 +msgid "Select text color" +msgstr "Elegir color de texto" + +#: wp-includes/js/tinymce/langs/wp-langs.php:229 +msgid "Select background color" +msgstr "Elegir color de fondo" + +#: wp-includes/js/tinymce/langs/wp-langs.php:230 +msgid "Insert custom character" +msgstr "Insertar carácter especial" \ No newline at end of file diff --git a/src/wp-content/languages/ms-es_ES.mo b/src/wp-content/languages/ms-es_ES.mo new file mode 100644 index 00000000..115619ed Binary files /dev/null and b/src/wp-content/languages/ms-es_ES.mo differ diff --git a/src/wp-content/languages/ms-es_ES.po b/src/wp-content/languages/ms-es_ES.po new file mode 100644 index 00000000..0f8cc994 --- /dev/null +++ b/src/wp-content/languages/ms-es_ES.po @@ -0,0 +1,2203 @@ +# Translation of Multisite in Spanish (Spain) +# This file is distributed under the same license as the Multisite package. +msgid "" +msgstr "" +"PO-Revision-Date: 2011-05-25 19:11:08+0000\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: GlotPress/0.1\n" +"Project-Id-Version: Multisite\n" + +#: wp-includes/ms-functions.php:324 +msgid "Error: problem creating site entry." +msgstr "Error: problema al crear entrada el el sitio." + +#: wp-includes/ms-functions.php:527 +msgid "Only lowercase letters (a-z) and numbers are allowed." +msgstr "Sólo se permiten minúsculas (a-z) y números." + +#: wp-includes/ms-functions.php:534 +msgid "Please enter a username" +msgstr "Por favor, introduce un nombre de usuario." + +#: wp-includes/ms-functions.php:542 +msgid "That username is not allowed" +msgstr "Este nombre de usuario no está permitido" + +#: wp-includes/ms-functions.php:545 +msgid "You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider." +msgstr "No puedes usar este correo electrónico para registrarte. Estamos teniendo problemas con él, bloquea nuestros correos electrónicos. Por favor, usa otro proveedor." + +#: wp-includes/ms-functions.php:548 +msgid "Username must be at least 4 characters" +msgstr "El nombre de usuario debe tener una extensión mínima de 4 caracteres." + +#: wp-activate.php:92 +msgid "Your account is now activated. Login or go back to the homepage." +msgstr "Tu cuenta ya está activada. Identifícate o vuelve a la página de inicio." + +#: wp-activate.php:68 +msgid "Your site at %2$s is active. You may now log in to your site using your chosen username of “%3$s”. Please check your email inbox at %4$s for your password and login instructions. If you do not receive an email, please check your junk or spam folder. If you still do not receive an email within an hour, you can reset your password." +msgstr "Tu sitio en %2$s está activo. Ahora puedes acceder a tu sitio usando el nombre de usuario elegido de “%3$s”. Por favor, revisa la bandeja de entrada de %4$s para ver tu contraseña e instrucciones de acceso. Si no recibes un correo electrónico revisa la bandeja de spam. Si ni aún así recibieras un correo electrónico en una hora puedes reiniciar tu contraseña." + +#: wp-includes/ms-functions.php:587 +msgid "That username is currently reserved but may be available in a couple of days." +msgstr "Este nombre de usuario está reservado, pero podría estar libre en un par de días" + +#: wp-includes/ms-functions.php:571 +msgid "Sorry, that username already exists!" +msgstr "Disculpa, este usuario ya existe." + +#: wp-includes/ms-functions.php:600 +msgid "That email address has already been used. Please check your inbox for an activation email. It will become available in a couple of days if you do nothing." +msgstr "Este correo electrónico ya ha sido usado. Por favor, comprueba tu bandeja de entrada. Podría estar libre en un par de días si no haces nada." + +#: wp-includes/ms-functions.php:590 +msgid "username and email used" +msgstr "nombre de usuario y correo electrónico en uso" + +#: wp-includes/ms-functions.php:214 wp-includes/ms-functions.php:276 +msgid "That user does not exist." +msgstr "Este usuario no existe" + +#: wp-includes/ms-functions.php:660 +msgid "Site name must be at least 4 characters" +msgstr "El nombre del sitio debe tener una extensión mínima de 4 caracteres." + +#: wp-includes/ms-functions.php:566 +msgid "Sorry, that email address is not allowed!" +msgstr "Disculpa, este correo electrónico no está permitido" + +#: wp-activate.php:90 +msgid "Your account is now activated. View your site or Login" +msgstr "Tu cuenta ahora está activada. Visita tu sitio o Identifícate" + +#: wp-activate.php:85 wp-signup.php:129 +msgid "Username:" +msgstr "Nombre de usuario:" + +#: wp-activate.php:73 +msgid "An error occurred during the activation" +msgstr "Ha habido un error en la activación" + +#: wp-includes/ms-functions.php:575 +msgid "Sorry, that email address is already used!" +msgstr "Disculpa, este correo electrónico ya está en uso." + +#: wp-includes/ms-functions.php:317 +msgid "Error: Site URL already taken." +msgstr "Error: URL del sitio ya escogida." + +#: wp-includes/ms-functions.php:649 +msgid "Please enter a site name" +msgstr "Por favor, introduce un nombre de sitio" + +#: wp-includes/ms-functions.php:560 +msgid "Please enter a correct email address" +msgstr "Por favor, introduce un correo electrónico válido" + +#: wp-includes/ms-functions.php:557 +msgid "Sorry, usernames must have letters too!" +msgstr "Disculpa, el nombre de usuario, también debe contener letras." + +#: wp-includes/ms-functions.php:551 +msgid "Sorry, usernames may not contain the character “_”!" +msgstr "¡Lo sentimos, nombres de usuario no puede contener el caracter “_”!" + +#: wp-includes/ms-functions.php:657 +msgid "That name is not allowed" +msgstr "Este nombre no está permitido" + +#: wp-includes/ms-functions.php:654 +msgid "Only lowercase letters and numbers allowed" +msgstr "Solo se permiten minúsculas y números" + +#: wp-activate.php:66 +msgid "Your account has been activated. You may now log in to the site using your chosen username of “%2$s”. Please check your email inbox at %3$s for your password and login instructions. If you do not receive an email, please check your junk or spam folder. If you still do not receive an email within an hour, you can reset your password." +msgstr "Se ha activado tu cuenta. Ahora puedes acceder al sitio usando el nombre de usuario que elegiste de “%2$s”. Por favor, revisa tu bandeja de entrada del correo electrónico %3$s para obtener tu contraseña e instrucciones de acceso. Si no recibes un correo electrónico revisa la carpeta de spam. Si aún así no recibes un correo electrónico en una hora puedes reiniciar tu contraseña aquí." + +#: wp-activate.php:62 wp-activate.php:82 +msgid "Your account is now active!" +msgstr "¡Tu cuenta ahora está activada!" + +#: wp-activate.php:46 +msgid "Activation Key:" +msgstr "Clave de activación:" + +#: wp-activate.php:43 +msgid "Activation Key Required" +msgstr "Requiere clave de activación" + +#: wp-includes/ms-functions.php:663 +msgid "Sorry, site names may not contain the character “_”!" +msgstr "¡Lo sentimos, el nombre del sitio no puede contener el caracter “_”!" + +#: wp-includes/ms-functions.php:667 +msgid "Sorry, you may not use that site name." +msgstr "Lo sentimos, no puedes utilizar este nombre para el sitio." + +#: wp-includes/ms-functions.php:673 +msgid "Sorry, site names must have letters too!" +msgstr "Disculpa, el nombre del sitio, también debe contener letras." + +#: wp-includes/ms-functions.php:680 +msgid "Please enter a site title" +msgstr "Por favor, introduce un título para el sitio" + +#: wp-includes/ms-functions.php:691 +msgid "Sorry, that site already exists!" +msgstr "Disculpa, este sitio ya existe." + +#: wp-includes/ms-functions.php:695 +msgid "Sorry, that site is reserved!" +msgstr "Disculpa, este nombre de sitio está reservado" + +#: wp-includes/ms-functions.php:706 +msgid "That site is currently reserved but may be available in a couple days." +msgstr "Este nombre de sitio está reservado, pero puede estar libre en un par de días." + +#: wp-includes/ms-functions.php:829 +msgid "" +"To activate your blog, please click the following link:\n" +"\n" +"%s\n" +"\n" +"After you activate, you will receive *another email* with your login.\n" +"\n" +"After you activate, you can visit your site here:\n" +"\n" +"%s" +msgstr "" +"Para activar tu sitio haz clic en el siguiente enlace:\n" +"\n" +"%s\n" +"\n" +"Después de activarlo recibirás *otro correo electrónico* con tus datos de acceso.\n" +"\n" +"Después de activarlo, podrás visitar tu sitio aquí:\n" +"\n" +"%s" + +#: wp-includes/ms-functions.php:839 wp-includes/ms-functions.php:891 +msgid "[%1$s] Activate %2$s" +msgstr "[%1$s] Activar %2$s" + +#: wp-includes/ms-functions.php:882 +msgid "" +"To activate your user, please click the following link:\n" +"\n" +"%s\n" +"\n" +"After you activate, you will receive *another email* with your login.\n" +"\n" +msgstr "" +"Para activar tu usuario, por favor, sigue el siguiente enlace:\n" +"\n" +"%s\n" +"\n" +"Después de la activación, recibirás *otro correo electrónico* con tu identificación.\n" +"\n" + +#: wp-includes/ms-functions.php:927 +msgid "Invalid activation key." +msgstr "Clave de activación inválida" + +#: wp-includes/ms-functions.php:931 +msgid "The user is already active." +msgstr "El usuario ya esta activo." + +#: wp-includes/ms-functions.php:933 +msgid "The site is already active." +msgstr "El sitio ya está activado." + +#: wp-includes/ms-functions.php:949 +msgid "Could not create user" +msgstr "No podemos crear el usuario" + +#: wp-includes/ms-functions.php:957 +msgid "That username is already activated." +msgstr "Este usuario, ya está activado." + +#: wp-includes/ms-functions.php:1058 +msgid "Site already exists." +msgstr "El sitio ya existe." + +#: wp-includes/ms-functions.php:1064 +msgid "Could not create site." +msgstr "No se pudo crear el sitio." + +#: wp-includes/ms-functions.php:1117 +msgid "" +"New Site: %1s\n" +"URL: %2s\n" +"Remote IP: %3s\n" +"\n" +"Disable these notifications: %4s" +msgstr "" +"Nuevo sitio: %1s\n" +"URL: %2s\n" +"IP Remota: %3s\n" +"\n" +"Desactivar estas notificaciones: %4s" + +#: wp-includes/ms-functions.php:1124 +msgid "New Site Registration: %s" +msgstr "Nuevo sitio registrado: %s" + +#: wp-includes/ms-functions.php:1151 +msgid "" +"New User: %1s\n" +"Remote IP: %2s\n" +"\n" +"Disable these notifications: %3s" +msgstr "" +"Nuevo usuario: %1s\n" +"IP Remota: %2s\n" +"\n" +"Desactivar estas notificaciones: %3s" + +#: wp-includes/ms-functions.php:1157 +msgid "New User Registration: %s" +msgstr "Nuevo registro de usuario: %s" + +#: wp-includes/ms-functions.php:1230 +msgid "

    Already Installed

    You appear to have already installed WordPress. To reinstall please clear your old database tables first.

    " +msgstr "

    Ya instalado

    WordPress parece estar instalado. Si deseas reinstalar, por favor, borra las tablas de la base de datos.

    " + +#: wp-includes/ms-functions.php:1345 +msgid "New %1$s Site: %2$s" +msgstr "Nuevo sitio en %1$s: %2$s" + +#: wp-includes/ms-functions.php:1393 +msgid "New %1$s User: %2$s" +msgstr "Nuevo %1$s usuario: %2$s" + +#: wp-includes/ms-functions.php:1574 +msgid "Sorry, you have used your space allocation. Please delete some files to upload more files." +msgstr "Disculpa. Has usado todo tu espacio. Por favor, borra algunos archivos para poder subir nuevos." + +#: wp-includes/ms-functions.php:1753 +msgid "This file is too big. Files must be less than %d KB in size." +msgstr "Este archivo es demasiado grande. Los archivos deben tener un tamaño inferior a %d KB." + +#: wp-includes/ms-functions.php:1784 +msgid "Please try again!" +msgstr "Por favor, vuelve a intentarlo." + +#: wp-includes/ms-functions.php:1829 +msgid "An error occurred adding you to this site. Back to the homepage." +msgstr "Hubo un error añadiéndote a este sitio. Volver a la página de inicio." + +#: wp-includes/ms-functions.php:1831 +msgid "You have been added to this site. Please visit the homepage or login using your username and password." +msgstr "Has sido añadido a este sitio. Por favor, visita la página de Inicio o Identifícate usando tu nombre de usuario y contraseña." + +#: wp-includes/ms-functions.php:1831 +msgid "Success" +msgstr "¡Lo lograste!" + +#: wp-includes/ms-functions.php:1991 +msgid "" +"Dear User,\n" +"\n" +"Your new account is set up.\n" +"\n" +"You can log in with the following information:\n" +"Username: USERNAME\n" +"Password: PASSWORD\n" +"LOGINLINK\n" +"\n" +"Thanks!\n" +"\n" +"--The Team @ SITE_NAME" +msgstr "" +"Apreciado usuario,\n" +"\n" +"Tu nueva cuenta está configurada.\n" +"\n" +"Puedes identificarte con la siguiente información:\n" +"Usuario: USERNAME\n" +"Clave: PASSWORD\n" +"LOGINLINK\n" +"\n" +"¡Gracias!\n" +"\n" +"--El equipo de SITE_NAME" + +#: wp-includes/ms-load.php:87 +msgid "This user has elected to delete their account and the content is no longer available." +msgstr "Este usuario ha decidido eliminar su cuenta y ya no están los contenidos." + +#: wp-includes/ms-load.php:94 +msgid "This site has not been activated yet. If you are having problems activating your site, please contact %1$s." +msgstr "Este sitio aún no ha sido activado. Si estas teniendo problemas en el proceso de activación, por favor contacta con %1$s." + +#: wp-includes/ms-load.php:101 +msgid "This site has been archived or suspended." +msgstr "Este sitio ha sido archivado o suspendido." + +#: wp-includes/ms-default-constants.php:113 +msgid "The constant VHOST is deprecated. Use the boolean constant SUBDOMAIN_INSTALL in wp-config.php to enable a subdomain configuration. Use is_subdomain_install() to check whether a subdomain configuration is enabled." +msgstr "La constante VHOST está obsoleta. Usa la constante booleana/lógica SUBDOMAIN_INSTALL en wp-config.php para habilitar la configuración de subdominios. Usa is_subdomain_install() para comprobar si la configuración de subdominios está activada." + +#: wp-includes/ms-default-constants.php:115 +msgid "Conflicting values for the constants VHOST and SUBDOMAIN_INSTALL. The value of SUBDOMAIN_INSTALL will be assumed to be your subdomain configuration setting." +msgstr "Hay valores en conflicto para las constantes VHOST y SUBDOMAIN_INSTALL. Se asumirá que el valor de la configuración de subdominio es SUBDOMAIN_INSTALL." + +#: wp-admin/my-sites.php:13 wp-admin/ms-delete-site.php:13 +#: wp-admin/network/user-new.php:14 wp-admin/network/index.php:17 +#: wp-admin/network/themes.php:14 wp-admin/network/plugin-editor.php:14 +#: wp-admin/network/plugin-install.php:17 wp-admin/network/site-users.php:14 +#: wp-admin/network/theme-editor.php:14 wp-admin/network/setup.php:14 +#: wp-admin/network/site-settings.php:14 wp-admin/network/site-new.php:14 +#: wp-admin/network/edit.php:14 wp-admin/network/theme-install.php:17 +#: wp-admin/network/users.php:14 wp-admin/network/upgrade.php:14 +#: wp-admin/network/update-core.php:14 wp-admin/network/sites.php:14 +#: wp-admin/network/settings.php:14 wp-admin/network/user-edit.php:14 +#: wp-admin/network/site-info.php:14 wp-admin/network/plugins.php:14 +#: wp-admin/network/profile.php:14 wp-admin/network/update.php:17 +#: wp-admin/network/site-themes.php:14 wp-admin/network/admin.php:16 +msgid "Multisite support is not enabled." +msgstr "El soporte multisitio no está activado." + +#: wp-admin/my-sites.php:16 +msgid "You do not have sufficient permissions to view this page." +msgstr "No tienes permisos suficientes para ver esta página" + +#: wp-admin/my-sites.php:23 +msgid "You must be a member of at least one site to use this page." +msgstr "Debes ser miembro de, al menos, un sitio para usar esta página." + +#: wp-admin/my-sites.php:34 +msgid "The primary site you chose does not exist." +msgstr "El sitio principal que has elegido no existe." + +#: wp-admin/my-sites.php:42 +msgid "This screen shows an individual user all of their sites in this network, and also allows that user to set a primary site. He or she can use the links under each site to visit either the frontend or the dashboard for that site." +msgstr "Esta pantalla muestra los usuarios de forma individual con todos sus sitios en la red y también permite al usuario marcar un sitio como principal. Él o ella pueden usar los enlaces bajo cada sitio para visitar la portada o el escritorio de cada sitio." + +#: wp-admin/my-sites.php:43 +msgid "Up until WordPress version 3.0, what is now called a Multi-site Network had to be installed separately as WordPress MU (multi-user)." +msgstr "Hasta la versión 3.0 de WordPress, lo que ahora se le llama red multisitio tenía que instalarse aparte como WordPress MU (multiusuario)." + +#: wp-admin/my-sites.php:45 +msgid "Documentation on My Sites" +msgstr "Documentación sobre Mis sitios" + +#: wp-admin/my-sites.php:68 +msgid "Global Settings" +msgstr "Ajustes globales" + +#: wp-admin/my-sites.php:95 +#: wp-admin/includes/class-wp-ms-sites-list-table.php:266 +msgid "Visit" +msgstr "Visitar" + +#: wp-admin/network.php:27 +msgid "The Network creation panel is not for WordPress MU networks." +msgstr "El panel de creación de la Red no es para redes de WordPress MU." + +#: wp-admin/network.php:96 +msgid "You must define the WP_ALLOW_MULTISITE constant as true in your wp-config.php file to allow creation of a Network." +msgstr "Debes definir la constante WP_ALLOW_MULTISITE como true en tu archivo wp-config.php para permitir la creación de una red." + +#: wp-admin/network.php:99 wp-admin/network/menu.php:45 +msgid "Network Setup" +msgstr "Configurar red" + +#: wp-admin/network.php:102 +msgid "Create a Network of WordPress Sites" +msgstr "Crear una red de sitios de WordPress" + +#: wp-admin/network.php:107 +msgid "This screen allows you to configure a network as having subdomains (site1.example.com) or subdirectories (example.com/site1). Subdomains require wildcard subdomains to be enabled in Apache and DNS records, if your host allows it." +msgstr "Esta pantalla te permite configurar una red que contenga subdominios (site1.example.com) or subdirectories (example.com/site1). Los subdominios requieren registros DNS y activar los comodines (wildcards) en Apache, si tu alojamiento lo permite." + +#: wp-admin/network.php:108 +msgid "Choose subdomains or subdirectories; this can only be switched afterwards by reconfiguring your install. Fill out the network details, and click install. If this does not work, you may have to add a wildcard DNS record (for subdomains) or change to another setting in Permalinks (for subdirectories)." +msgstr "Elige subdominios o subdirectorios. Esto solo puede cambiarse reconfigurando tu instalación. Rellena los detalles de la red y haz clic en instalar. Si no funciona, deberás añadir un registro DNS (para los subdominios) o cambiar a otro ajuste de enlaces permanentes (para los subdirectorios)." + +#: wp-admin/network.php:109 +msgid "The next screen for Network will give you individually-generated lines of code to add to your wp-config.php and .htaccess files. Make sure the settings of your FTP client make files starting with a dot visible, so that you can find .htaccess; you may have to create this file if it really is not there. Make backup copies of those two files." +msgstr "La siguiente pantalla de la Red te dará unas líneas de código generadas individualmente para que las añadas al archivo wp-config.php y a .htaccess. Asegúrate que los ajustes de tu cliente FTP hacen visibles los archivos que comiencen por un punto para que puedas encontrar el archivo .htaccess. Deberás crear este archivo si no existe. Realiza una copia de seguridad de ambos archivos." + +#: wp-admin/network.php:110 +msgid "Add a blogs.dir directory under /wp-content and add the designated lines of code to wp-config.php (just before /*...stop editing...*/) and .htaccess (replacing the existing WordPress rules)." +msgstr "Crea un directorio blogs.dir bajo /wp-content y añade las líneas de código definidas a wp-config.php (justo antes de /*...deja de editar...*/) y a .htaccess (reemplazando las reglas existentes de WordPress)." + +#: wp-admin/network.php:111 +msgid "The choice of subdirectory sites is disabled if this setup is more than a month old because of permalink problems with “/blog/” from the main site. This disabling will be addressed soon in a future version." +msgstr "La posibilidad de sitios en subdirectorios está desactivada si el sitio tiene más de un mes ya que hay un problema con los enlaces permanentes que incluyen “/blog/” en el sitio principal. Esta desactivación se resolverá pronto en futuras versiones." + +#: wp-admin/network.php:113 +msgid "Documentation on Creating a Network" +msgstr "Documentación sobre Crear una red" + +#: wp-admin/network.php:114 +msgid "Documentation on the Network Screen" +msgstr "Documentación sobre la pantalla de red" + +#: wp-admin/network.php:137 wp-admin/network.php:144 wp-admin/network.php:161 +msgid "Error:" +msgstr "Error:" + +#: wp-admin/network.php:137 +msgid "Your WordPress address must match your Site address before creating a Network. See General Settings." +msgstr "Tu dirección de WordPress debe coincidir con la dirección de tu sitio antes de crear una red. Mira en Ajustes generales." + +#: wp-admin/network.php:144 +msgid "The constant DO_NOT_UPGRADE_GLOBAL_TABLES cannot be defined when creating a network." +msgstr "La constante DO_NOT_UPGRADE_GLOBAL_TABLES no puede definirse al crear una red." + +#: wp-admin/network.php:152 wp-admin/network.php:330 wp-admin/network.php:355 +msgid "Warning:" +msgstr "Advertencia:" + +#: wp-admin/network.php:152 +msgid "Please deactivate your plugins before enabling the Network feature." +msgstr "Por favor, desactiva tus plugins antes de activar la función de red." + +#: wp-admin/network.php:152 +msgid "Once the network is created, you may reactivate your plugins." +msgstr "Una vez que se cree la red podrás reactivar tus plugins." + +#: wp-admin/network.php:161 +msgid "You cannot install a network of sites with your server address." +msgstr "No puedes instalar una red de sitios con tu dirección de servidor." + +#: wp-admin/network.php:162 +msgid "You cannot use port numbers such as %s." +msgstr "No puedes usar números de puerto como %s." + +#: wp-admin/network.php:163 +msgid "Return to Dashboard" +msgstr "Volver al escritorio" + +#: wp-admin/network.php:175 +msgid "ERROR: The network could not be created." +msgstr "ERROR: La red no ha podido crearse." + +#: wp-admin/network.php:183 wp-admin/network.php:203 wp-admin/network.php:251 +#: wp-admin/network.php:261 +msgid "Warning!" +msgstr "¡Aviso!" + +#: wp-admin/network.php:183 wp-admin/network.php:355 +msgid "Networks may not be fully compatible with custom wp-content directories." +msgstr "Las redes puede que no sean totalmente compatibles con directorios wp-content personalizados" + +#: wp-admin/network.php:185 +msgctxt "Default network name" +msgid "%s Sites" +msgstr "%s sitios" + +#: wp-admin/network.php:188 +msgid "Welcome to the Network installation process!" +msgstr "¡Bienvenido al proceso de instalación de la red!" + +#: wp-admin/network.php:189 +msgid "Fill in the information below and you’ll be on your way to creating a network of WordPress sites. We will create configuration files in the next step." +msgstr "Completa la información siguiente y estarás en el camino de crear una red de sitios con WordPress. Crearemos los archivos de configuración en el siguiente paso." + +#: wp-admin/network.php:201 +msgid "Note:" +msgstr "Nota:" + +#: wp-admin/network.php:201 +msgid "Please make sure the Apache mod_rewrite module is installed as it will be used at the end of this installation." +msgstr "Por favor, asegúrate de que el módulo Apache mod_rewrite está instalado, ya que será utilizado al finalizar la instalación." + +#: wp-admin/network.php:203 +msgid "It looks like the Apache mod_rewrite module is not installed." +msgstr "Parece que el módulo mod_rewrite de Apache no está instalado." + +#: wp-admin/network.php:205 +msgid "If mod_rewrite is disabled, ask your administrator to enable that module, or look at the Apache documentation or elsewhere for help setting it up." +msgstr "Si mod_rewrite está deshabilitado, pide a su administrador que active ese módulo, o revise la documentación de Apache o en otros sitios para conseguir ayuda para su configuración." + +#: wp-admin/network.php:209 +msgid "Addresses of Sites in your Network" +msgstr "Direcciones de los sitios en tu red" + +#: wp-admin/network.php:210 +msgid "Please choose whether you would like sites in your WordPress network to use sub-domains or sub-directories. You cannot change this later." +msgstr "Por favor, elige como quieres que estén los sitios en tu red de WordPress, subdominios o subdirectorios. No podrás cambiarlo más tarde." + +#: wp-admin/network.php:211 +msgid "You will need a wildcard DNS record if you are going to use the virtual host (sub-domain) functionality." +msgstr "Necesitarás crear un registro DNS si vas a utilizar la funcionalidad de servidor vitual (sub-dominios)." + +#: wp-admin/network.php:215 +msgid "Sub-domains" +msgstr "Subdominios" + +#: wp-admin/network.php:216 +msgctxt "subdomain examples" +msgid "like site1.%1$s and site2.%1$s" +msgstr "cómo sitio1.%1$s y sitio2.%1$s" + +#: wp-admin/network.php:219 +msgid "Sub-directories" +msgstr "Subdirectorios" + +#: wp-admin/network.php:220 +msgctxt "subdirectory examples" +msgid "like %1$s/site1 and %1$s/site2" +msgstr "cómo %1$s/sitio1 and %1$s/sitio2" + +#: wp-admin/network.php:230 wp-admin/network.php:234 wp-admin/network.php:274 +msgid "Server Address" +msgstr "Dirección del servidor" + +#: wp-admin/network.php:231 +msgid "We recommend you change your siteurl to %1$s before enabling the network feature. It will still be possible to visit your site using the www prefix with an address like %2$s but any links will not have the www prefix." +msgstr "Te recomendamos que cambies la URL de tu sitio a %1$s antes de activar la función de red. Seguirá siendo posible visitar tu sitio con el prefijo www con una dirección como %2$s, pero ningún enlace tendrá el prefijo www." + +#: wp-admin/network.php:236 wp-admin/network.php:276 +msgid "The internet address of your network will be %s." +msgstr "La dirección en internet de tu red será %s." + +#: wp-admin/network.php:242 +msgid "Network Details" +msgstr "Detalles de la red" + +#: wp-admin/network.php:246 wp-admin/network.php:256 +msgid "Sub-directory Install" +msgstr "Instalación en subdirectorio" + +#: wp-admin/network.php:248 +msgid "Because you are using localhost, the sites in your WordPress network must use sub-directories. Consider using localhost.localdomain if you wish to use sub-domains." +msgstr "Cómo estás usando localhost los sitios en tu red de WordPress deben estar en subdirectorios. Considera usar localhost.localdomain si deseas usar subdominios." + +#: wp-admin/network.php:251 wp-admin/network.php:261 wp-admin/network.php:268 +msgid "The main site in a sub-directory install will need to use a modified permalink structure, potentially breaking existing links." +msgstr "El sitio principal en un subdirectorio de instalación tendrá que utilizar una estructura de enlaces permanentes modificada, lo que podría romper los vínculos existentes." + +#: wp-admin/network.php:258 +msgid "Because your install is in a directory, the sites in your WordPress network must use sub-directories." +msgstr "Cómo lo has instalado en un subdirectorio, los sitios en tu red de WordPress, deben usar subdirectorios." + +#: wp-admin/network.php:266 +msgid "Sub-domain Install" +msgstr "Instalación en subdominio" + +#: wp-admin/network.php:267 +msgid "Because your install is not new, the sites in your WordPress network must use sub-domains." +msgstr "Cómo como tu instalación no es nueva, los sitios de tu red deberán utilizar subdominios." + +#: wp-admin/network.php:281 +msgid "Network Title" +msgstr "Título de la red" + +#: wp-admin/network.php:284 +msgid "What would you like to call your network?" +msgstr "¿Cómo quieres llamar a tu red?" + +#: wp-admin/network.php:288 +msgid "Admin E-mail Address" +msgstr "Dirección de correo electrónico del Administrador" + +#: wp-admin/network.php:291 +msgid "Your email address." +msgstr "Tu dirección de correo electrónico." + +#: wp-admin/network.php:325 +msgid "The original configuration steps are shown here for reference." +msgstr "Los pasos de configuración originales se muestran aquí para tenerlos como referencia." + +#: wp-admin/network.php:330 +msgid "An existing WordPress network was detected." +msgstr "Se ha detectado una red de WordPress existente." + +#: wp-admin/network.php:331 +msgid "Please complete the configuration steps. To create a new network, you will need to empty or remove the network database tables." +msgstr "Por favor, completa los pasos de configuración. Para crear una nueva red necesitarás vaciar o eliminar las tablas de la red en la base de datos." + +#: wp-admin/network.php:338 +msgid "Enabling the Network" +msgstr "Activando la red" + +#: wp-admin/network.php:339 +msgid "Complete the following steps to enable the features for creating a network of sites." +msgstr "Completa los siguientes pasos para activar la función de creación de red de sitios." + +#: wp-admin/network.php:342 wp-admin/network.php:344 +msgid "Caution: We recommend you back up your existing wp-config.php and %s files." +msgstr "Cuidado: Te recomendamos que hagas copia de seguridad de tus archivos wp-config.php y %s." + +#: wp-admin/network.php:346 +msgid "Caution: We recommend you back up your existing wp-config.php file." +msgstr "Atención: Recomendamos realizar una copia de seguridad de tu archivo wp-config.php." + +#: wp-admin/network.php:353 +msgid "Create a blogs.dir directory at %s/blogs.dir. This directory is used to store uploaded media for your additional sites and must be writeable by the web server." +msgstr "Crea un directorio blogs.dir en %s/blogs.dir. Este directorio se utiliza para almacenar los archivos de medios subidos en tus sitios adicionales y el servidor web debe tener permisos de escritura." + +#: wp-admin/network.php:357 +msgid "Add the following to your wp-config.php file in %s above the line reading /* That’s all, stop editing! Happy blogging. */:" +msgstr "Añade lo siguiente a tu archivo wp-config.php en %s sobre la línea que dice /* ¡Eso es todo, no hay que editar nada más! Feliz blogging. */:" + +#: wp-admin/network.php:388 +msgid "This unique authentication key is also missing from your wp-config.php file." +msgid_plural "These unique authentication keys are also missing from your wp-config.php file." +msgstr[0] "Esta clave de autentificación tampoco se encuentra en tu archivo wp-config.php" +msgstr[1] "Estas claves de autentificación tampoco se encuentran en tu archivo wp-config.php" + +#: wp-admin/network.php:388 +msgid "To make your installation more secure, you should also add:" +msgstr "Para hacer tu instalación más segura debes añadir lo siguiente:" + +#: wp-admin/network.php:473 +msgid "Add the following to your web.config file in %s, replacing other WordPress rules:" +msgstr "Añade lo siguiente a tu archivo web.config en %s, remplazando las reglas existentes de WordPress:" + +#: wp-admin/network.php:502 +msgid "Add the following to your .htaccess file in %s, replacing other WordPress rules:" +msgstr "Añade lo siguiente a tu archivo .htaccess en %s, remplazando las reglas existentes de WordPress:" + +#: wp-admin/network.php:510 +msgid "Once you complete these steps, your network is enabled and configured. You will have to log in again." +msgstr "Una vez que completes estos pasos tu red estará activa y configurada. Deberás acceder de nuevo." + +#: wp-admin/ms-delete-site.php:17 +msgid "You do not have sufficient permissions to delete this site." +msgstr "No tienes suficientes permisos para eliminar este sitio." + +#: wp-admin/ms-delete-site.php:22 +msgid "Thank you for using %s, your site has been deleted. Happy trails to you until we meet again." +msgstr "Gracias por usar %s, tu sitio ha sido eliminado. Seremos muy felices si volvemos a saber de ti." + +#: wp-admin/ms-delete-site.php:24 +msgid "I'm sorry, the link you clicked is stale. Please select another option." +msgstr "Lo sentimos, el enlace pulsado está caducado. Por favor, elige otra opción." + +#: wp-admin/ms-delete-site.php:44 +msgid "" +"Dear User,\n" +"You recently clicked the 'Delete Site' link on your site and filled in a\n" +"form on that page.\n" +"If you really want to delete your site, click the link below. You will not\n" +"be asked to confirm again so only click this link if you are absolutely certain:\n" +"###URL_DELETE###\n" +"\n" +"If you delete your site, please consider opening a new site here\n" +"some time in the future! (But remember your current site and username\n" +"are gone forever.)\n" +"\n" +"Thanks for using the site,\n" +"Webmaster\n" +"###SITE_NAME###" +msgstr "" +"Apreciado usuario,\n" +"Recientemente has hecho clic en el enlace \"Eliminar sitio\" de tu sitio, y has completado\n" +"un formulario en esa página.\n" +"Si realmente quieres eliminar tu sitio, sigue el enlace siguiente. No serás\n" +"preguntado de nuevo para confirmar esta acción, es decir, haz clic si estás totalmente seguro:\n" +"###URL_DELETE###\n" +"\n" +"Si eliminas tu sitio, por favor, considera crear uno nuevo aquí mismo\n" +"en el futuro. (Pero recuerda que tu nombre de usuario y tu sitio\n" +"desaparecerán para siempre.)\n" +"\n" +"Gracias por usar nuestro sitio,\n" +"Webmaster\n" +"###SITE_NAME###" + +#: wp-admin/ms-delete-site.php:62 +msgid "Delete My Site" +msgstr "Eliminar mi sitio" + +#: wp-admin/ms-delete-site.php:65 +msgid "Thank you. Please check your email for a link to confirm your action. Your site will not be deleted until this link is clicked. " +msgstr "Gracias. Por favor, comprueba tu correo electrónico para seguir el enlace. Tu sitio no será eliminado hasta que hagas clic en ese enlace." + +#: wp-admin/ms-delete-site.php:69 +msgid "If you do not want to use your %s site any more, you can delete it using the form below. When you click Delete My Site Permanently you will be sent an email with a link in it. Click on this link to delete your site." +msgstr "Si no quieres usar más tu sitio %s, puedes eliminarlo mediante el formulario siguiente. Cuando hagas clic en Eliminar mi sitio de forma permanente enviarás un correo electrónico con un enlace en él. Siguiendo ese enlace, tu sitio será eliminado." + +#: wp-admin/ms-delete-site.php:70 +msgid "Remember, once deleted your site cannot be restored." +msgstr "Recuerda, una vez que elimines tu sitio, no se podrá recuperar." + +#: wp-admin/ms-delete-site.php:75 +msgid "I'm sure I want to permanently disable my site, and I am aware I can never get it back or use %s again." +msgstr "Estoy seguro que quiero desactivar mi sitio de forma permanente y estoy avisado que NUNCA MÁS podré usar de nuevo %s." + +#: wp-admin/ms-delete-site.php:76 +msgid "Delete My Site Permanently" +msgstr "Eliminar mi sitio de forma permanente" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:120 +msgid "No sites found." +msgstr "No se encontraron sitios." + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:127 +msgctxt "site" +msgid "Mark as Spam" +msgstr "Marcar como spam" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:128 +#: wp-admin/includes/class-wp-ms-sites-list-table.php:258 +msgctxt "site" +msgid "Not Spam" +msgstr "No es Spam" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:143 +#: wp-admin/network/site-new.php:120 wp-admin/network/site-new.php:122 +#: wp-admin/network/site-info.php:116 +msgid "Domain" +msgstr "Dominio" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:147 +#: wp-admin/network/site-info.php:139 +msgid "Last Updated" +msgstr "Última actualización" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:148 +#: wp-admin/network/site-info.php:135 +msgctxt "site" +msgid "Registered" +msgstr "Registrado" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:172 +#: wp-admin/network/site-info.php:145 +msgid "Archived" +msgstr "Archivado" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:173 +#: wp-admin/includes/class-wp-ms-sites-list-table.php:260 +#: wp-admin/network/site-info.php:146 +msgctxt "site" +msgid "Spam" +msgstr "Spam" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:174 +#: wp-admin/network/site-info.php:147 +msgid "Deleted" +msgstr "Borrado" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:175 +#: wp-admin/network/site-info.php:149 +msgid "Mature" +msgstr "Adulto" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:232 +msgctxt "%1$s: site name. %2$s: site tagline." +msgid "%1$s – %2$s" +msgstr "%1$s – %2$s" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:248 +msgid "You are about to activate the site %s" +msgstr "Estás a punto de activar el sitio %s" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:250 +msgid "You are about to deactivate the site %s" +msgstr "Estás a punto desactivar el sitio %s" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:253 +msgid "You are about to unarchive the site %s." +msgstr "Estás a punto de desarchiva el sitio %s." + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:253 +msgid "Unarchive" +msgstr "Desarchivar" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:255 +msgid "You are about to archive the site %s." +msgstr "Estás apunto de archivar el sitio %s." + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:255 +msgctxt "verb; site" +msgid "Archive" +msgstr "Archivar" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:258 +msgid "You are about to unspam the site %s." +msgstr "Estás a punto de sacar el sitio %s de spam." + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:260 +msgid "You are about to mark the site %s as spam." +msgstr "Estás a punto de marcar el sitio %s como spam." + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:263 +msgid "You are about to delete the site %s." +msgstr "Estás a punto de eliminar el sitio %s." + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:281 +msgid "Never" +msgstr "Nunca" + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:302 +msgid "Only showing first 5 users." +msgstr "Mostrando solo los 5 primeros usuarios." + +#: wp-admin/includes/class-wp-ms-sites-list-table.php:302 +msgid "More" +msgstr "Más" + +#: wp-admin/includes/ms-deprecated.php:30 +msgid "Sorry, you must delete files before you can upload any more." +msgstr "Disculpa, debes borrar archivos antes de subir nuevos." + +#: wp-admin/includes/ms.php:33 +msgid "Not enough space to upload. %1$s KB needed." +msgstr "No hay espacio suficiente para subir. Se necesitan %1$s KB." + +#: wp-admin/includes/ms.php:35 +msgid "This file is too big. Files must be less than %1$s KB in size." +msgstr "Este archivo es demasiado grande. Los archivos deben ser de un tamaño menor a %1$s KB." + +#: wp-admin/includes/ms.php:37 +msgid "You have used your space quota. Please delete files before uploading." +msgstr "Has usado tu cuota de espacio asignada. Por favor, borra archivos antes de subir alguno más." + +#: wp-admin/includes/ms.php:40 +msgid "Back" +msgstr "Atrás" + +#: wp-admin/includes/ms.php:221 +msgid "" +"Dear user,\n" +"\n" +"You recently requested to have the administration email address on\n" +"your site changed.\n" +"If this is correct, please click on the following link to change it:\n" +"###ADMIN_URL###\n" +"\n" +"You can safely ignore and delete this email if you do not want to\n" +"take this action.\n" +"\n" +"This email has been sent to ###EMAIL###\n" +"\n" +"Regards,\n" +"All at ###SITENAME###\n" +"###SITEURL### " +msgstr "" +"Estimado usuario,\n" +"\n" +"Has solicitado recientemente el cambio de la \n" +"dirección de correo electrónico de administración de tu sitio.\n" +"Si es correcto, haz clic en el siguiente enlace para cambiarla:\n" +"###ADMIN_URL###\n" +"\n" +"Si no quieres hacerlo, puedes ignorar el correo y borrarlo tranquilamente.\n" +"\n" +"Este correo ha sido enviado a ###EMAIL###\n" +"\n" +"Saludos,\n" +"La gente de ###SITENAME###\n" +"###SITEURL### " + +#: wp-admin/includes/ms.php:242 +msgid "[%s] New Admin Email Address" +msgstr "[%s] Nueva dirección de correo electrónico del administrador." + +#: wp-admin/includes/ms.php:258 +msgid "ERROR: The e-mail address isn't correct." +msgstr "ERROR: La dirección de correo electrónico no es correcta." + +#: wp-admin/includes/ms.php:263 +msgid "ERROR: The e-mail address is already used." +msgstr "ERROR: Esa dirección de correo electrónico ya está siendo utilizada." + +#: wp-admin/includes/ms.php:275 +msgid "" +"Dear user,\n" +"\n" +"You recently requested to have the email address on your account changed.\n" +"If this is correct, please click on the following link to change it:\n" +"###ADMIN_URL###\n" +"\n" +"You can safely ignore and delete this email if you do not want to\n" +"take this action.\n" +"\n" +"This email has been sent to ###EMAIL###\n" +"\n" +"Regards,\n" +"All at ###SITENAME###\n" +"###SITEURL###" +msgstr "" +"Estimado usuario,\n" +"\n" +"Recientemente has solicitado el cambio de dirección de correo electrónico de tu cuenta..\n" +"Si es así haz clic en el siguiente enlace para cambiarla:\n" +"###ADMIN_URL###\n" +"\n" +"Si no quieres hacerlo puedes ignorar y borrar este correo electrónico con tranquilidad.\n" +"\n" +"Este correo electrónico se ha enviado a ###EMAIL###\n" +"\n" +"Atentamente,\n" +"El equipo de ###SITENAME###\n" +"###SITEURL###" + +#: wp-admin/includes/ms.php:295 +msgid "[%s] New Email Address" +msgstr "[%s] Nuevo correo electrónico" + +#: wp-admin/includes/ms.php:303 +msgid "Your email address has not been updated yet. Please check your inbox at %s for a confirmation email." +msgstr "Tu correo electrónico no ha sido actualizado todavía. Por favor, revisa tu bandeja de entrada de %s para ver el correo electrónico de confirmación." + +#: wp-admin/includes/ms.php:413 +msgid "GB" +msgstr "GB" + +#: wp-admin/includes/ms.php:416 +msgid "MB" +msgstr "MB" + +#: wp-admin/includes/ms.php:419 +msgid "Used: %1s%% of %2s" +msgstr "Utilizado: %1s%% de %2s" + +#: wp-admin/includes/ms.php:431 +msgid "Site Upload Space Quota " +msgstr "Cuota de espacio de subida del sitio" + +#: wp-admin/includes/ms.php:432 +msgid "MB (Leave blank for network default)" +msgstr "MB (Déjalo en blanco para dejar la cuota de la red por defecto)" + +#: wp-admin/includes/ms.php:505 +msgid "You don’t have permission to view this site. Please contact the system administrator." +msgstr "No tienes permiso para ver este sitio. Por favor, contacta con el administrador del sistema." + +#: wp-admin/includes/ms.php:537 +msgid "American English" +msgstr "Inglés americano" + +#: wp-admin/includes/ms.php:541 +msgid "British English" +msgstr "Inglés británico" + +#: wp-admin/includes/ms.php:551 +msgid "English" +msgstr "Inglés" + +#: wp-admin/includes/ms.php:571 +msgid "Warning! WordPress encrypts user cookies, but you must add the following lines to wp-config.php for it to be more secure." +msgstr "¡Atención! WordPress encripta las cookies de los usuarios, pero debes añadir las siguientes líneas a wp-config.php para que sea más seguro." + +#: wp-admin/includes/ms.php:572 +msgid "Before the line /* That's all, stop editing! Happy blogging. */ please add this code:" +msgstr "Antes de la línea /* ¡Eso es todo, deja de editar! ¡Feliz blogging!. */ por favor, añade el siguiente código:" + +#: wp-admin/includes/ms.php:585 +msgid "Thank you for Updating! Please visit the Update Network page to update all your sites." +msgstr "¡Gracias por actualizar!. Por favor, visita Actualizar red para actualizar todos tus sitios." + +#: wp-admin/includes/ms.php:618 +msgid "Primary Site" +msgstr "Sitio principal" + +#: wp-admin/includes/ms.php:665 +msgid "The %1$s file is deprecated. Please remove it and update your server rewrite rules to use %2$s instead." +msgstr "El archivo %1$s es obsoleto. Por favor, elimínalo y actualiza las reglas de re-escritura de tu servidor para usar %2$s en su lugar." + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:170 +msgid "No themes found." +msgstr "No se han encontrado temas." + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:172 +msgid "You do not appear to have any themes available at this time." +msgstr "Parece ser que no hay temas disponibles en este momento." + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:180 +msgid "Theme" +msgstr "Tema" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:201 +msgctxt "themes" +msgid "All (%s)" +msgid_plural "All (%s)" +msgstr[0] "(%s)" +msgstr[1] "Todos (%s)" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:204 +msgid "Enabled (%s)" +msgid_plural "Enabled (%s)" +msgstr[0] "(%s) activo" +msgstr[1] "(%s) activos" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:207 +msgid "Disabled (%s)" +msgid_plural "Disabled (%s)" +msgstr[0] "(%s) desactivado" +msgstr[1] "(%s) desactivados" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:236 +#: wp-admin/includes/class-wp-ms-themes-list-table.php:283 +msgid "Enable" +msgstr "Activar" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:236 +#: wp-admin/includes/class-wp-ms-themes-list-table.php:283 +msgid "Network Enable" +msgstr "Activar para la red" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:238 +#: wp-admin/includes/class-wp-ms-themes-list-table.php:285 +msgid "Disable" +msgstr "Desactivar" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:238 +#: wp-admin/includes/class-wp-ms-themes-list-table.php:285 +msgid "Network Disable" +msgstr "Desactivar para la red" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:283 +msgid "Enable this theme" +msgstr "Activa este tema" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:285 +msgid "Disable this theme" +msgstr "Desactiva este tema" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:288 +msgid "Open this theme in the Theme Editor" +msgstr "Abre este tema en el editor de temas" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:291 +msgid "Delete this theme" +msgstr "Borrar este tema" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:337 +msgid "Visit theme homepage" +msgstr "Visita el sitio del tema" + +#: wp-admin/includes/class-wp-ms-themes-list-table.php:337 +msgid "Visit Theme Site" +msgstr "Visitar el sitio del tema" + +#: wp-admin/includes/class-wp-ms-users-list-table.php:75 +msgctxt "user" +msgid "Mark as Spam" +msgstr "Marcar como spam" + +#: wp-admin/includes/class-wp-ms-users-list-table.php:76 +msgctxt "user" +msgid "Not Spam" +msgstr "No es spam" + +#: wp-admin/includes/class-wp-ms-users-list-table.php:82 +msgid "No users found." +msgstr "No se encontraron usuarios." + +#: wp-admin/includes/class-wp-ms-users-list-table.php:97 +msgid "Super Admin (%s)" +msgid_plural "Super Admins (%s)" +msgstr[0] "(%s) Super administrador" +msgstr[1] "(%s) Super administradores" + +#: wp-admin/includes/class-wp-ms-users-list-table.php:117 +msgctxt "user" +msgid "Registered" +msgstr "Registrado" + +#: wp-admin/network/user-new.php:17 +msgid "You do not have sufficient permissions to add users to this network." +msgstr "No tienes suficientes permisos para añadir usuarios a esta red." + +#: wp-admin/network/user-new.php:21 +msgid "Add User will set up a new user account on the network and send them an email with their username and password." +msgstr "Añadir usuario configurará una nueva cuenta de usuario en la red y le mandará un email con su usuario y contraseña." + +#: wp-admin/network/user-new.php:22 +msgid "Users who are signed up to the network without a site are added as subscribers to the main or primary dashboard site, giving them profile pages to manage their accounts. These users will only see Dashboard and My Sites in the main navigation until a site is created for them." +msgstr "Los usuarios que se registran en la red sin crear un sitio son añadidos al escritorio del sitio principal, dándoles unas páginas de perfil para gestionar sus cuentas. Estos usuarios solo verán el escritorio y Mis sitios en la navegación principal hasta que creen su propio sitio." + +#: wp-admin/network/user-new.php:24 wp-admin/network/users.php:41 +msgid "Documentation on Network Users" +msgstr "Documentación sobre Usuarios de la red" + +#: wp-admin/network/user-new.php:25 wp-admin/network/index.php:32 +#: wp-admin/network/site-users.php:32 wp-admin/network/site-settings.php:27 +#: wp-admin/network/site-new.php:24 wp-admin/network/users.php:42 +#: wp-admin/network/sites.php:40 wp-admin/network/site-info.php:27 +#: wp-admin/network/site-themes.php:32 +msgid "Support Forums" +msgstr "Foros de soporte" + +#: wp-admin/network/user-new.php:31 wp-admin/network/index.php:20 +#: wp-admin/network/site-users.php:42 wp-admin/network/site-settings.php:37 +#: wp-admin/network/site-new.php:31 wp-admin/network/edit.php:102 +#: wp-admin/network/edit.php:175 wp-admin/network/edit.php:192 +#: wp-admin/network/edit.php:236 wp-admin/network/edit.php:246 +#: wp-admin/network/edit.php:256 wp-admin/network/edit.php:267 +#: wp-admin/network/edit.php:278 wp-admin/network/edit.php:288 +#: wp-admin/network/edit.php:298 wp-admin/network/edit.php:308 +#: wp-admin/network/edit.php:355 wp-admin/network/edit.php:376 +#: wp-admin/network/edit.php:391 wp-admin/network/edit.php:442 +#: wp-admin/network/users.php:17 wp-admin/network/upgrade.php:33 +#: wp-admin/network/sites.php:17 wp-admin/network/settings.php:17 +#: wp-admin/network/site-info.php:37 wp-admin/network/site-themes.php:55 +msgid "You do not have permission to access this page." +msgstr "No tienes autorización para acceder a esta página" + +#: wp-admin/network/user-new.php:34 +msgid "Cannot create an empty user." +msgstr "No se puede crear un usuario vacio" + +#: wp-admin/network/user-new.php:37 +msgid "Missing username and email." +msgstr "Falta nombre de usuario y correo electrónico." + +#: wp-admin/network/user-new.php:39 +msgid "Missing username." +msgstr "Falta el nombre de usuario." + +#: wp-admin/network/user-new.php:41 +msgid "Missing email." +msgstr "Falta correo electrónico." + +#: wp-admin/network/user-new.php:47 wp-admin/network/site-users.php:214 +msgid "Duplicated username or email address." +msgstr "Nombre de usuario o correo electrónico duplicado." + +#: wp-admin/network/user-new.php:85 wp-admin/network/site-users.php:299 +msgid "Username and password will be mailed to the above email address." +msgstr "Se enviarán el nombre de usuario y la contraseña a esta dirección de correo electrónico." + +#: wp-admin/network/user-new.php:89 wp-admin/network/site-users.php:267 +msgid "Add User" +msgstr "Añadir usuario" + +#: wp-admin/network/index.php:26 +msgid "Until WordPress 3.0, running multiple sites required using WordPress MU instead of regular WordPress. In version 3.0, these applications have merged. If you are a former MU user, you should be aware of the following changes:" +msgstr "Antes de WordPress 3.0, para hacer funcionar múltiples sitios se requería usar WordPress MU en vez de WordPress normal. En la versión 3.0, estas aplicaciones se han fusionado. Si eres usuario o conocedor de MU debes ser consciente de los siguientes cambios:" + +#: wp-admin/network/index.php:27 +msgid "Site Admin is now Super Admin (we highly encourage you to get yourself a cape!)." +msgstr "El administrador del sitio es ahora Super administrador (te recomendamos encarecidamente que te protejas)" + +#: wp-admin/network/index.php:28 +msgid "Blogs are now called Sites; Site is now called Network." +msgstr "Los blogs se llaman ahora sitios; al sitio ahora se le llama red." + +#: wp-admin/network/index.php:29 +msgid "This screen provides the network administrator with links to the screens for Sites and Users to either create a new site or user, or to search existing users and sites, as well as Dashboard widgets. Those screens are also accessible through the left-hand navigation in the Network Admin section." +msgstr "Esta pantalla ofrece al administrador de la red enlaces a las pantallas de los sitios y usuarios para crear un nuevo sitio o usuario, o para buscar usuarios y sitios existentes, y también widgets de Escritorio. También se puede acceder a esas pantallas mediante la navegación de la izquierda de la sección de Administrador de la red." + +#: wp-admin/network/index.php:31 +msgid "Documentation on the Network Admin" +msgstr "Documentación sobre Administrador de la red" + +#: wp-admin/network/themes.php:22 +msgid "You do not have sufficient permissions to manage network themes." +msgstr "No tienes suficientes permisos para administrar temas de la red." + +#: wp-admin/network/themes.php:81 +msgid "You do not have sufficient permissions to delete themes for this site." +msgstr "No tienes suficientes permisos para borrar temas en este sitio." + +#: wp-admin/network/themes.php:125 +msgid "Delete Theme" +msgid_plural "Delete Themes" +msgstr[0] "Borrar tema" +msgstr[1] "Borrar temas" + +#: wp-admin/network/themes.php:127 +msgid "This theme may be active on other sites in the network." +msgid_plural "These themes may be active on other sites in the network." +msgstr[0] "Este tema podría estar activo en otros sitios de la red." +msgstr[1] "Estos temas podrían estar activos en otros sitios de la red." + +#: wp-admin/network/themes.php:128 +msgid "You are about to remove the following theme:" +msgid_plural "You are about to remove the following themes:" +msgstr[0] "Estás a punto de borrar el siguiente tema:" +msgstr[1] "Estás a punto de borrar los siguientes temas:" + +#: wp-admin/network/themes.php:133 +msgid "Are you sure you wish to delete these themes?" +msgstr "¿Estás seguro de que quieres borrar estos temas?" + +#: wp-admin/network/themes.php:142 +msgid "Yes, Delete this theme" +msgid_plural "Yes, Delete these themes" +msgstr[0] "Sí, borrar este tema" +msgstr[1] "Sí, borrar estos temas" + +#: wp-admin/network/themes.php:145 +msgid "No, Return me to the theme list" +msgstr "No, devuélveme a la lista de temas" + +#: wp-admin/network/themes.php:182 wp-admin/network/site-themes.php:125 +msgctxt "themes per page (screen options)" +msgid "Themes" +msgstr "Temas" + +#: wp-admin/network/themes.php:185 +msgid "This screen enables and disables the inclusion of themes available to choose in the Appearance menu for each site. It does not activate or deactivate which theme a site is currently using." +msgstr "Esta pantalla activa o desactiva la inclusión en la disponibilidad de Temas para los sitios en el menú Apariencia de cada sitio. No activa o desactiva que temas se están usando en cada sitio." + +#: wp-admin/network/themes.php:186 +msgid "If the network admin disables a theme that is in use, it can still remain selected on that site. If another theme is chosen, the disabled theme will not appear in the site’s Appearance > Themes screen." +msgstr "Si el administrador de la red desactiva un tema que está en uso, podrá continuar seleccionado en el sitio que lo tenga en uso. Si en el sitio selecciona otro tema, el tema ya no le aparecerá en la pantalla Apariencia > Temas." + +#: wp-admin/network/themes.php:187 +msgid "Themes can be enabled on a site by site basis by the network admin on the Edit Site screen you go to via the Edit action link on the Sites screen. Only network admins are able to install or edit themes." +msgstr "Los temas pueden activarse sitio a sitio por el administrador de la red en la pantalla Editar sitio a la que te lleva el enlace Editar en la pantalla de sitios. Solo los administradores de red pueden instalar o editar temas." + +#: wp-admin/network/themes.php:189 +msgid "Documentation on Network Themes" +msgstr "Documentación sobre Temas de la red" + +#: wp-admin/network/themes.php:202 wp-admin/network/menu.php:30 +msgctxt "theme" +msgid "Add New" +msgstr "Añadir nuevo" + +#: wp-admin/network/themes.php:210 wp-admin/network/site-themes.php:153 +msgid "Theme enabled." +msgid_plural "%s themes enabled." +msgstr[0] "Tema activado" +msgstr[1] "%s temas activados." + +#: wp-admin/network/themes.php:213 wp-admin/network/site-themes.php:156 +msgid "Theme disabled." +msgid_plural "%s themes disabled." +msgstr[0] "Tema desactivado." +msgstr[1] "%s temas desactivados." + +#: wp-admin/network/themes.php:216 +msgctxt "network" +msgid "Theme deleted." +msgid_plural "%s themes deleted." +msgstr[0] "Tema borrado." +msgstr[1] "%s temas borrados." + +#: wp-admin/network/themes.php:218 wp-admin/network/site-themes.php:158 +msgid "No theme selected." +msgstr "Ningún tema seleccionado." + +#: wp-admin/network/themes.php:220 +msgid "You cannot delete a theme while it is active on the main site." +msgstr "No puedes borrar un tema si está activo en el sitio principal." + +#: wp-admin/network/themes.php:226 wp-admin/network/site-themes.php:164 +msgid "Search Installed Themes" +msgstr "Buscar temas instalados" + +#: wp-admin/network/site-users.php:17 wp-admin/network/site-settings.php:17 +#: wp-admin/network/site-info.php:17 +msgid "You do not have sufficient permissions to edit this site." +msgstr "No tienes suficientes permisos para editar este sitio." + +#: wp-admin/network/site-users.php:25 wp-admin/network/site-settings.php:20 +#: wp-admin/network/site-info.php:20 wp-admin/network/site-themes.php:25 +msgid "The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable." +msgstr "El meno es para editar información específica de sitios individuadles, especialmente si el área de administrador de un sitio no está disponible." + +#: wp-admin/network/site-users.php:26 wp-admin/network/site-settings.php:21 +#: wp-admin/network/site-info.php:21 wp-admin/network/site-themes.php:26 +msgid "Info - The domain and path are rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable." +msgstr "Información: El dominio y la ruta raramente se editan porque podría provocar que el sistema no funcionase correctamente. Se muestran las fechas de registro y de la última actualización. Los administradores de red puede marcar un sitio como guardado, spam, borrado y de contenido pata adultos, para borrarlo de las listas públicas o desactivado." + +#: wp-admin/network/site-users.php:27 wp-admin/network/site-settings.php:22 +#: wp-admin/network/site-info.php:22 wp-admin/network/site-themes.php:27 +msgid "Users - This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network." +msgstr "Usuarios - Esto muestra los usuarios asociados a este sitio. También puedes cambiar su perfil, reiniciar su contraseña o borrarlos del sitio. Borrar un usuario del sitio no borra al usuario de la red." + +#: wp-admin/network/site-users.php:28 wp-admin/network/site-settings.php:23 +#: wp-admin/network/site-info.php:23 wp-admin/network/site-themes.php:28 +msgid "Themes - This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site’s Appearance menu. To enable a theme for the entire network, see the Network Themes screen." +msgstr "Temas - Esta área muestra temas que yo no están activos en la red. Activando un tema en este menú hará que esté disponible para este sitio. No activa el tema pero permite que se muestre en el menú de Aspecto del sitio. Para activar un tema para toda la red ve a la pantalla de Temas de la red." + +#: wp-admin/network/site-users.php:29 wp-admin/network/site-settings.php:24 +#: wp-admin/network/site-info.php:24 wp-admin/network/site-themes.php:29 +msgid "Settings - This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database." +msgstr "Ajustes - Esta página muestra una lista de todos los ajustes asociados a este sitio. Algunos han sido creados por WordPerss y otros los crean los plugins que activas. Observa que algunos campos están oscurecidos y muestran Serialized data. No puedes modificar estos valores por el modo en que el ajuste está almacenado en la base de datos." + +#: wp-admin/network/site-users.php:31 wp-admin/network/site-settings.php:26 +#: wp-admin/network/site-new.php:23 wp-admin/network/sites.php:39 +#: wp-admin/network/site-info.php:26 wp-admin/network/site-themes.php:31 +msgid "Documentation on Site Management" +msgstr "Documentación sobre Gestión del sitio" + +#: wp-admin/network/site-users.php:38 wp-admin/network/site-settings.php:33 +#: wp-admin/network/site-info.php:33 wp-admin/network/site-themes.php:49 +msgid "Invalid site ID." +msgstr "ID de sitio no válido." + +#: wp-admin/network/site-users.php:160 wp-admin/network/site-settings.php:71 +#: wp-admin/network/site-info.php:81 wp-admin/network/site-themes.php:127 +msgid "Edit Site: %s" +msgstr "Editar sitio: %s" + +#: wp-admin/network/site-users.php:172 wp-admin/network/site-settings.php:85 +#: wp-admin/network/site-info.php:95 wp-admin/network/site-themes.php:139 +msgid "Info" +msgstr "Información" + +#: wp-admin/network/site-users.php:190 +msgid "User is already a member of this site." +msgstr "El usuario ya es miembro de este sitio." + +#: wp-admin/network/site-users.php:193 +msgid "Enter the username of an existing user." +msgstr "Introduce el nombre de usuario de un usuario existente." + +#: wp-admin/network/site-users.php:199 +msgid "Select a user to change role." +msgstr "Elige un usuario para cambiar su perfil." + +#: wp-admin/network/site-users.php:205 +msgid "Select a user to remove." +msgstr "Elige un usuario para borrarlo." + +#: wp-admin/network/site-users.php:208 +msgid "User created." +msgstr "Usuario creado." + +#: wp-admin/network/site-users.php:211 +msgid "Enter the username and email." +msgstr "Introduce el nombre de usuario y email." + +#: wp-admin/network/site-users.php:237 +msgid "Add User to This Site" +msgstr "Añadir un usuario a este sitio" + +#: wp-admin/network/site-users.php:239 +msgid "You may add from existing network users, or set up a new user to add to this site." +msgstr "Puedes añadir usuarios que ya sean de la red, o añadir uno nuevo para incorporarlo a este sitio." + +#: wp-admin/network/site-users.php:241 +msgid "You may add from existing network users to this site." +msgstr "Puedes añadir usuarios que ya sean de la red a este sitio." + +#: wp-admin/network/site-settings.php:68 +msgid "Site options updated." +msgstr "Opciones del sitio actualizadas." + +#: wp-admin/network/site-new.php:17 +msgid "You do not have sufficient permissions to add sites to this network." +msgstr "No tienes suficientes permisos para añadir sitios a esta red." + +#: wp-admin/network/site-new.php:20 +msgid "This screen is for Super Admins to add new sites to the network. This is not affected by the registration settings." +msgstr "Esta pantalla es para que los Super administradores añadan nuevos sitios a la red. No le afectan los ajustes de registro." + +#: wp-admin/network/site-new.php:21 +msgid "If the admin email for the new site does not exist in the database, a new user will also be created." +msgstr "Si el correo electrónico del administrador para el nuevo sitio no existe en la base de datos también se creará un nuevo usuario." + +#: wp-admin/network/site-new.php:34 +msgid "Can’t create an empty site." +msgstr "No se puede crear un sitio vacío." + +#: wp-admin/network/site-new.php:44 +msgid "The following words are reserved for use by WordPress functions and cannot be used as blog names: %s" +msgstr "Las siguientes palabras están reservadas para el uso en las funciones de WordPress y no pueden ser usadas como nombre del sitio: %s" + +#: wp-admin/network/site-new.php:51 +msgid "Missing or invalid site address." +msgstr "La dirección del sitio no está o no es válida." + +#: wp-admin/network/site-new.php:53 +msgid "Missing email address." +msgstr "Falta la dirección de correo electrónico." + +#: wp-admin/network/site-new.php:55 +msgid "Invalid email address." +msgstr "Dirección de correo electrónico no válida." + +#: wp-admin/network/site-new.php:71 +msgid "There was an error creating the user." +msgstr "Hubo un error al crear el usuario." + +#: wp-admin/network/site-new.php:82 +msgid "" +"New site created by %1s\n" +"\n" +"Address: http://%2s\n" +"Name: %3s" +msgstr "" +"Nuevo sitio creado por %1s\n" +"\n" +"Dirección: http://%2s\n" +"Nombre: %3s" + +#: wp-admin/network/site-new.php:83 +msgid "[%s] New Site Created" +msgstr "[%s] Nuevo sitio creado" + +#: wp-admin/network/site-new.php:95 +msgid "Site added." +msgstr "Sitio añadido." + +#: wp-admin/network/site-new.php:98 wp-admin/network/site-new.php:107 +msgid "Add New Site" +msgstr "Añadir nuevo sitio" + +#: wp-admin/network/site-new.php:117 +msgid "Site Address" +msgstr "Dirección del sitio" + +#: wp-admin/network/site-new.php:124 +msgid "Only the characters a-z and 0-9 recommended." +msgstr "Solo se recomiendan los caracters a-z y 0-9." + +#: wp-admin/network/site-new.php:133 +msgid "Admin Email" +msgstr "Correo electrónico del administrador" + +#: wp-admin/network/site-new.php:137 +msgid "A new user will be created if the above email address is not in the database." +msgstr "Se creará un usuario nuevo si el correo electrónico no está en la base de datos" + +#: wp-admin/network/site-new.php:137 +msgid "The username and password will be mailed to this email address." +msgstr "El nombre de usuario y la contraseña se enviarán a este correo electrónico." + +#: wp-admin/network/site-new.php:140 +msgid "Add Site" +msgstr "Añadir sitio" + +#: wp-admin/network/edit.php:29 +msgid "Transfer or delete posts and links before deleting users." +msgstr "Transfiere o borra las entradas y enlaces antes de borrar usuarios." + +#: wp-admin/network/edit.php:42 +msgid "Warning! User %s cannot be deleted." +msgstr "¡Aviso! El usuario %s no puede borrarse." + +#: wp-admin/network/edit.php:45 +msgid "Warning! User cannot be deleted. The user %s is a network admnistrator." +msgstr "¡Atención! Este usuario no puede borrarse. El usuario %s es el administrador de la red." + +#: wp-admin/network/edit.php:52 +msgid "What should be done with posts and links owned by %s?" +msgstr "¿Qué debe hacerse con las entradas y enlaces de %s?" + +#: wp-admin/network/edit.php:70 +msgid "Site: %s" +msgstr "Sitio: %s" + +#: wp-admin/network/edit.php:105 +msgid "You probably need to go back to the options page." +msgstr "Probablemente debes volver a opciones de página." + +#: wp-admin/network/edit.php:204 +msgid "You are not allowed to delete the site." +msgstr "No tienes permisos para borrar este sitio." + +#: wp-admin/network/edit.php:222 wp-admin/network/edit.php:323 +msgid "You are not allowed to change the current site." +msgstr "No estás autorizado a cambiar el sitio actual." + +#: wp-admin/network/edit.php:328 +msgid "WordPress › Confirm your action" +msgstr "WordPress › Confirma tu acción" + +#: wp-admin/network/edit.php:344 +msgid "Confirm" +msgstr "Confirmar" + +#: wp-admin/network/edit.php:405 +msgid "Warning! User cannot be modified. The user %s is a network administrator." +msgstr "¡Atención! El usuario no puede modificarse. El usuario %s es el administrador de la red." + +#: wp-admin/network/users.php:34 +msgid "This table shows all users across the network and the sites to which they are assigned." +msgstr "Esta tabla muestra todos los usuarios de la red y los sitios que tienen asignados." + +#: wp-admin/network/users.php:35 +msgid "Hover over any user on the list to make the edit links appear. The Edit link on the left will take you to his or her Edit User profile page; the Edit link on the right by any site name goes to an Edit Site screen for that site." +msgstr "Pasa el cursor por encima de cualquiera de los usuarios de este listado para que aparezcan los enlaces de edición. El enlace Editar de la izquierda te llevará a su página de perfil Editar Usuario. El enlace Editar de la derecha de cualquiera de los nombre de los sitios te lleva a la pantalla del sitio Editar Sitio." + +#: wp-admin/network/users.php:36 +msgid "You can also go to the user’s profile page by clicking on the individual username." +msgstr "También puedes ir a la página de perfil del usuario haciendo clic en el nombre de usuario concreto." + +#: wp-admin/network/users.php:37 +msgid "You can sort the table by clicking on any of the bold headings and switch between list and excerpt views by using the icons in the upper right." +msgstr "Puedes ordenar la tabla haciendo clic en cualquiera de las cabeceras en negritas y cambiando entre listado y extracto haciendo clic en los iconos de arriba a la derecha." + +#: wp-admin/network/users.php:38 +msgid "The bulk action will permanently delete selected users, or mark/unmark those selected as spam. Spam users will have posts removed and will be unable to sign up again with the same email addresses." +msgstr "La acción en lote borrará permanentemente los usuarios seleccionados, o marca/desmarca los seleccionados como spam. Se borrarán las entradas de los usuarios spam y no podrán acceder de nuevo con la misma dirección de correo electrónico. " + +#: wp-admin/network/users.php:39 +msgid "You can make an existing user an additional super admin by going to the Edit User profile page and checking the box to grant that privilege." +msgstr "Puedes hacer a un usuario existente Super Admin. Ve a la página del perfil Editar usuario y marca la casilla para darle este privilegio." + +#: wp-admin/network/users.php:53 +msgid "User deleted." +msgstr "Usuario eliminado." + +#: wp-admin/network/users.php:56 +msgid "Users marked as spam." +msgstr "Usuario marcado como spam." + +#: wp-admin/network/users.php:59 +msgid "Users removed from spam." +msgstr "Usuarios eliminados de spam." + +#: wp-admin/network/users.php:62 +msgid "Users deleted." +msgstr "Usuarios eliminados." + +#: wp-admin/network/upgrade.php:18 wp-admin/network/upgrade.php:37 +#: wp-admin/network/upgrade.php:79 wp-admin/network/menu.php:65 +msgid "Update Network" +msgstr "Actualizar red" + +#: wp-admin/network/upgrade.php:22 +msgid "Only use this screen once you have updated to a new version of WordPress through Dashboard > Updates. Clicking the Update Network button will step through each site in the network, five at a time, and make sure any database updates are applied." +msgstr "Usa solo esta pantalla una vez hayas actualizado a una nueva versión de WordPress desde Escritorio > Actualizar. Al hacer clic en el botón Actualizar red se iniciará en cada sitio de la red, de cinco en cinco, y debes asegurarte de que se aplican las actualizaciones de cada base de datos." + +#: wp-admin/network/upgrade.php:23 +msgid "If a version update to core has not happened, clicking this button won’t affect anything." +msgstr "Si no se ha actualizado el núcleo, hacer clic en este botón no afectará en nada." + +#: wp-admin/network/upgrade.php:24 +msgid "If this process fails for any reason, users logging in to their sites will force the same update." +msgstr "Si este proceso falla por cualquier circunstancia, cuando los usuarios accedan a su sitio forzaran esta misma actualización." + +#: wp-admin/network/upgrade.php:26 +msgid "Documentation on Update Network" +msgstr "Documentación sobre Actualizar red" + +#: wp-admin/network/upgrade.php:52 +msgid "All done!" +msgstr "¡Todo hecho!" + +#: wp-admin/network/upgrade.php:61 +msgid "Warning! Problem updating %1$s. Your server may not be able to connect to sites running on it. Error message: %2$s" +msgstr "¡Atención! Problema al actualizar %1$s. Tu servidor no puede conectar con el sitio que está funcionando en él. Mensaje de Error: %2$s" + +#: wp-admin/network/upgrade.php:66 +msgid "If your browser doesn’t start loading the next page automatically, click this link:" +msgstr "Si tu navegador no carga la siguiente página de forma automática haz clic en este enlace:" + +#: wp-admin/network/upgrade.php:66 +msgid "Next Sites" +msgstr "Sitios siguientes" + +#: wp-admin/network/upgrade.php:78 +msgid "You can update all the sites on your network through this page. It works by calling the update script of each site automatically. Hit the link below to update." +msgstr "Puedes actualizar todos los sitios de tu red mediante esta página. Funciona haciendo una llamada al script de actualización de forma automatizada. Haz clic en el enlace siguiente para actualizarlos." + +#: wp-admin/network/sites.php:25 +msgctxt "sites per page (screen options)" +msgid "Sites" +msgstr "Sitios" + +#: wp-admin/network/sites.php:28 +msgid "Add New takes you to the Add New Site screen. You can search for a site by Name, ID number, or IP address. Screen Options allows you to choose how many sites to display on one page." +msgstr "Añadir nuevo te lleva a la pantalla de Añadir nuevo sitiio. Puedes buscar un sitio por nombre, número de ID o dirección IP. Las Opciones de pantalla te permiten elegir cuantos sitios mostrar por página." + +#: wp-admin/network/sites.php:29 +msgid "This is the main table of all sites on this network. Switch between list and excerpt views by using the icons above the right side of the table." +msgstr "Esta es la tabla principal de todos los sitios de la red. Cambia de vista listado o fragmento usando los iconos de la parte superior derecha de la tabla." + +#: wp-admin/network/sites.php:30 +msgid "Hovering over each site reveals seven options (three for the primary site):" +msgstr "Al pasar el cursor sobre cada sitio se muestran siete opciones (tres para el sitio primario):" + +#: wp-admin/network/sites.php:31 +msgid "An Edit link to a separate Edit Site screen." +msgstr "Un enlace de Editar que lleva a otra pantalla de Editar sitio." + +#: wp-admin/network/sites.php:32 +msgid "Dashboard leads to the Dashboard for that site." +msgstr "Escritorio te lleva al escritorio de ese sitio." + +#: wp-admin/network/sites.php:33 +msgid "Deactivate, Archive, and Spam which lead to confirmation screens. These actions can be reversed later." +msgstr "Desactivar, Archivar y Spam te llevan a pantallas de confirmación. Estas acciones pueden revertirse más tarde." + +#: wp-admin/network/sites.php:34 +msgid "Delete which is a permanent action after the confirmation screens." +msgstr "Borrar es una acción permanente tras las pantallas de confirmación." + +#: wp-admin/network/sites.php:35 +msgid "Visit to go to the frontend site live." +msgstr "Visitar para ir a la portada del sitio público." + +#: wp-admin/network/sites.php:36 +msgid "The site ID is used internally, and is not shown on the front end of the site or to users/viewers." +msgstr "El ID de sitio se usa internamente, y no se muestra en la parte visible del sitio o a los usuarios/visitantes." + +#: wp-admin/network/sites.php:37 +msgid "Clicking on bold settings can re-sort this table. The upper right icons switch between list and excerpt views." +msgstr "Haciendo clic en los ajustes en negrita puedes reordenar esta tabla. Los iconos de arriba a la derecha cambian entre la vista listado y extracto." + +#: wp-admin/network/sites.php:49 +msgid "Sites removed from spam." +msgstr "Sitios eliminados de spam." + +#: wp-admin/network/sites.php:52 +msgid "Sites marked as spam." +msgstr "Sitios marcados como spam." + +#: wp-admin/network/sites.php:55 +msgid "Sites deleted." +msgstr "Sitios eliminados." + +#: wp-admin/network/sites.php:58 +msgid "Site deleted." +msgstr "Sitio eliminado." + +#: wp-admin/network/sites.php:61 +msgid "You do not have permission to delete that site." +msgstr "No tienes permisos para borrar ese sitio." + +#: wp-admin/network/sites.php:64 +msgid "Site archived." +msgstr "Sitio archivado." + +#: wp-admin/network/sites.php:67 +msgid "Site unarchived." +msgstr "Sitio desarchivado." + +#: wp-admin/network/sites.php:70 +msgid "Site activated." +msgstr "Sitio activado." + +#: wp-admin/network/sites.php:73 +msgid "Site deactivated." +msgstr "Sitio desactivado." + +#: wp-admin/network/sites.php:76 +msgid "Site removed from spam." +msgstr "Sitio eliminado de spam." + +#: wp-admin/network/sites.php:79 +msgid "Site marked as spam." +msgstr "Sitio marcado como spam." + +#: wp-admin/network/sites.php:105 wp-admin/network/menu.php:18 +msgctxt "site" +msgid "Add New" +msgstr "Añadir nuevo" + +#: wp-admin/network/settings.php:23 +msgid "This screen sets and changes options for the network as a whole. The first site is the main site in the network and network options are pulled from that original site’s options." +msgstr "Esta pantalla establece y cambia las opciones para toda la red. El primer sitio es el sitio principal de la red y las opciones de red serán pasadas desde las opciones del sitio original." + +#: wp-admin/network/settings.php:24 +msgid "Operational settings has fields for the network’s name and admin email." +msgstr "Los ajustes operacionales tienen campos para el nombre de red y el correo electrónico del administrador." + +#: wp-admin/network/settings.php:25 +msgid "Dashboard Site is an option to give a site to users who do not have a site on the system. Their default role is Subscriber, but that default can be changed. The Admin Notice Feed can provide a notice on all dashboards of the latest post via RSS or Atom, or provide no such notice if left blank." +msgstr "El escritorio del sitio es una opción para dar un sitio a usuarios que no tienen uno en el sistema. Su perfil por defecto es suscriptor, pero puede cambiarse. El feed de avisos del administrador puede, a través de RSS o Atom, ofrecer avisos de las últimas entradas en todos los escritorios o, si lo dejas en blanco, no mostrar aviso alguno." + +#: wp-admin/network/settings.php:26 +msgid "Registration settings can disable/enable public signups. If you let others sign up for a site, install spam plugins. Spaces, not commas, should separate names banned as sites for this network." +msgstr "Los ajustes de registro pueden activar/desactivar el registro público. Si permites que la gente registre un sitio, instala un plugins de spam. Espacio, sin comas, debes separar los nombres para sitios no permitidos para esta red." + +#: wp-admin/network/settings.php:27 +msgid "New site settings are defaults applied when a new site is created in the network. These include welcome email for when a new site or user account is registered, and what᾿s put in the first post, page, comment, comment author, and comment URL." +msgstr "Los ajustes para nuevos sitios se aplican cuando se crea un nuevo sitio en la red. Esto incluye correo electrónico de bienvenida cuando se registra un nuevo sitio o cuenta de usuario y que poner en la primera entrada, página, comentario, autor del comentario y la URL del comentario." + +#: wp-admin/network/settings.php:28 +msgid "Upload settings control the size of the uploaded files and the amount of available upload space for each site. You can change the default value for specific sites when you edit a particular site. Allowed file types are also listed (space separated only)." +msgstr "Los ajustes de subida controlan el tamaño para la subida de archivos y la cantidad de espacio de subida disponible para cada sitio. Puedes cambiar el valor por defecto para sitios específicos cuando edites un sitio en concreto. También se listan los tipos de archivo permitidos (separados solo por espacios)." + +#: wp-admin/network/settings.php:29 +msgid "Checkboxes for media upload buttons set which are shown in the visual editor. If unchecked, a generic upload button is still visible; other media types can still be uploaded if on the allowed file types list." +msgstr "Las casillas seleccionables para los botones de subida de multimedia hacen que se muestren en el editor visual. Si está desmarcado, un botón genérico se mantendrá visible. Otros tipos de archivos multimedia pueden continuar subiéndose." + +#: wp-admin/network/settings.php:30 +msgid "Menu setting enables/disables the plugin menus from appearing for non super admins, so that only super admins, not site admins, have access to activate plugins." +msgstr "En ajustes de menú se activa o desactiva que aparezca o no el menú plugins para los usuarios que no son Super Admin. Es decir, solo los Super Admins, no los Admin, tienen acceso a los plugins." + +#: wp-admin/network/settings.php:32 +msgid "Documentation on Network Settings" +msgstr "Documentación sobre Ajustes de la red" + +#: wp-admin/network/settings.php:50 +msgid "Operational Settings" +msgstr "Ajustes operacionales" + +#: wp-admin/network/settings.php:53 +msgid "Network Name" +msgstr "Nombre de la red" + +#: wp-admin/network/settings.php:57 +msgid "What you would like to call this website." +msgstr "Como quieres llamar a este sitio." + +#: wp-admin/network/settings.php:62 +msgid "Network Admin Email" +msgstr "Correo electrónico del administrador de la red" + +#: wp-admin/network/settings.php:66 +msgid "Registration and support emails will come from this address. An address such as support@%s is recommended." +msgstr "Los correo electrónicos de registro y de soporte vendrán de esta dirección. Se recomienda un correo electrónico del tipo soporte@%s." + +#: wp-admin/network/settings.php:70 +msgid "Registration Settings" +msgstr "Ajustes de registro" + +#: wp-admin/network/settings.php:73 +msgid "Allow new registrations" +msgstr "Permitir nuevos registros" + +#: wp-admin/network/settings.php:80 +msgid "Registration is disabled." +msgstr "Los registros están deshabilitados." + +#: wp-admin/network/settings.php:81 +msgid "User accounts may be registered." +msgstr "Solo las cuentas de usuario pueden ser creadas." + +#: wp-admin/network/settings.php:82 +msgid "Logged in users may register new sites." +msgstr "Solo los usuarios identificados, pueden crear sitios." + +#: wp-admin/network/settings.php:83 +msgid "Both sites and user accounts can be registered." +msgstr "Pueden ser creados sitios y usuarios." + +#: wp-admin/network/settings.php:85 +msgid "If registration is disabled, please set NOBLOGREDIRECT in wp-config.php to a URL you will redirect visitors to if they visit a non-existent site." +msgstr "Si el registro está deshabilitado, por favor, define NOBLOGREDIRECT en wp-config.php con la URL que quieres que se redirija a los visitantes que visitan un sitio inexistente." + +#: wp-admin/network/settings.php:91 +msgid "Registration notification" +msgstr "Notificación de registro" + +#: wp-admin/network/settings.php:97 +msgid "Send the network admin an email notification every time someone registers a site or user account." +msgstr "Enviar al administrador un correo electrónico cada vez que alguien se registre o registre un sitio." + +#: wp-admin/network/settings.php:102 +msgid "Add New Users" +msgstr "Añadir nuevo usuario" + +#: wp-admin/network/settings.php:104 +msgid "Allow site administrators to add new users to their site via the \"Users → Add New\" page." +msgstr "Permite a los administradores de sitio añadir nuevos usuarios a su sitio a través de la página \"Usuarios → Añadir nuevo\"." + +#: wp-admin/network/settings.php:109 +msgid "Banned Names" +msgstr "Nombre no permitidos" + +#: wp-admin/network/settings.php:113 +msgid "Users are not allowed to register these sites. Separate names by spaces." +msgstr "Los usuarios no tienes permiso para crear estos sitios. Separa los nombres mediante espacios." + +#: wp-admin/network/settings.php:118 +msgid "Limited Email Registrations" +msgstr "Limitar el registro de correo electrónico a" + +#: wp-admin/network/settings.php:125 +msgid "If you want to limit site registrations to certain domains. One domain per line." +msgstr "Si quieres limitar el registro de sitios a determinados dominios. Un dominio por línea." + +#: wp-admin/network/settings.php:130 +msgid "Banned Email Domains" +msgstr "Dominios de correo electrónico no permitidos" + +#: wp-admin/network/settings.php:135 +msgid "If you want to ban domains from site registrations. One domain per line." +msgstr "Si quieres banear dominios del registro de sitios. Un dominio por línea." + +#: wp-admin/network/settings.php:140 +msgid "New Site Settings" +msgstr "Ajustes para sitios nuevos" + +#: wp-admin/network/settings.php:144 +msgid "Welcome Email" +msgstr "Correo electrónico de bienvenida" + +#: wp-admin/network/settings.php:149 +msgid "The welcome email sent to new site owners." +msgstr "El correo electrónico de bienvenida enviado a los dueños de sitios nuevos." + +#: wp-admin/network/settings.php:153 +msgid "Welcome User Email" +msgstr "Correo electrónico de bienvenida al usuario" + +#: wp-admin/network/settings.php:158 +msgid "The welcome email sent to new users." +msgstr "El correo electrónico de bienvenida enviado a los nuevos usuarios." + +#: wp-admin/network/settings.php:167 +msgid "The first post on a new site." +msgstr "La primera entrada en un sitio nuevo." + +#: wp-admin/network/settings.php:171 +msgid "First Page" +msgstr "Primera página" + +#: wp-admin/network/settings.php:176 +msgid "The first page on a new site." +msgstr "La primera página en un sitio nuevo." + +#: wp-admin/network/settings.php:180 +msgid "First Comment" +msgstr "Primer comentario" + +#: wp-admin/network/settings.php:185 +msgid "The first comment on a new site." +msgstr "El primer comentario en un sitio nuevo." + +#: wp-admin/network/settings.php:189 +msgid "First Comment Author" +msgstr "Autor del primer comentario" + +#: wp-admin/network/settings.php:193 +msgid "The author of the first comment on a new site." +msgstr "El autor del primer comentario en un sitio nuevo." + +#: wp-admin/network/settings.php:197 +msgid "First Comment URL" +msgstr "URL del primer comentario" + +#: wp-admin/network/settings.php:201 +msgid "The URL for the first comment on a new site." +msgstr "La URL para el primer comentario en un nuevo sitio." + +#: wp-admin/network/settings.php:205 +msgid "Upload Settings" +msgstr "Ajustes de subidas" + +#: wp-admin/network/settings.php:208 +msgid "Media upload buttons" +msgstr "Botones de subida de archivos" + +#: wp-admin/network/settings.php:211 +msgid "Videos" +msgstr "Vídeos" + +#: wp-admin/network/settings.php:212 +msgid "Music" +msgstr "Música" + +#: wp-admin/network/settings.php:213 +msgid "The media upload buttons to display on the “Write Post” page. Make sure you update the allowed upload file types below as well." +msgstr "Los botones de subida de archivos a mostrar en la página de “Nueva entrada”. Asegúrate de actualizar también los tipos de archivo permitidos." + +#: wp-admin/network/settings.php:217 +msgid "Site upload space" +msgstr "Espacio de subidas para el sitio" + +#: wp-admin/network/settings.php:219 +msgid "Limit total size of files uploaded to %s MB" +msgstr "Tamaño máximo de espacio para archivos subidos %s MB" + +#: wp-admin/network/settings.php:224 +msgid "Upload file types" +msgstr "Tipos de archivo permitidos" + +#: wp-admin/network/settings.php:229 +msgid "Max upload file size" +msgstr "Tamaño máximo de archivo" + +#: wp-admin/network/settings.php:230 +msgctxt "File size in kilobytes" +msgid "%s KB" +msgstr "%s KB" + +#: wp-admin/network/settings.php:239 +msgid "Language Settings" +msgstr "Ajustes de idioma" + +#: wp-admin/network/settings.php:242 +msgid "Default Language" +msgstr "Idioma prederterminado." + +#: wp-admin/network/settings.php:254 +msgid "Menu Settings" +msgstr "Ajustes de menú" + +#: wp-admin/network/settings.php:257 +msgid "Enable administration menus" +msgstr "Activar menús de administración" + +#: wp-admin/network/site-info.php:78 +msgid "Site info updated." +msgstr "Información del sitio actualizada." + +#: wp-admin/network/site-info.php:131 +msgid "Update siteurl and home as well." +msgstr "Actualizar siteurl y portada" + +#: wp-admin/network/menu.php:28 +msgid "Themes %s" +msgstr "Temas %s" + +#: wp-admin/network/menu.php:38 +msgctxt "plugin editor" +msgid "Add New" +msgstr "Añadir nuevo" + +#: wp-admin/network/menu.php:64 +msgid "Updates" +msgstr "Actualizar" + +#: wp-admin/network/site-themes.php:22 +msgid "You do not have sufficient permissions to manage themes for this site." +msgstr "No tienes suficentes permisos para administrar temas en este sitio." + +#: wp-admin/network/site-themes.php:161 +msgid "Network enabled themes are not shown on this screen." +msgstr "Los temas activos de la red no se muestran en esta pantalla." + +#: wp-signup.php:69 +msgid "Site Name:" +msgstr "Nombre del sitio:" + +#: wp-signup.php:71 +msgid "Site Domain:" +msgstr "Dominio del sitio:" + +#: wp-signup.php:84 +msgid "sitename" +msgstr "nombresitio" + +#: wp-signup.php:86 +msgid "domain" +msgstr "dominio" + +#: wp-signup.php:87 +msgid "Your address will be %s." +msgstr "Tu dirección será %s." + +#: wp-signup.php:87 +msgid "Must be at least 4 characters, letters and numbers only. It cannot be changed, so choose carefully!" +msgstr "Debe tener al menos 4 caracteres, letras y números solamente. ¡No se puede cambiar, así que elige con cuidado!" + +#: wp-signup.php:92 +msgid "Site Title:" +msgstr "Título del sitio:" + +#: wp-signup.php:101 +msgid "Privacy:" +msgstr "Privacidad:" + +#: wp-signup.php:102 +msgid "Allow my site to appear in search engines like Google, Technorati, and in public listings around this network." +msgstr "Permitir que mi sitio aparezca en motores de búsqueda como Google y Technorati y en los listados públicos de esta red." + +#: wp-signup.php:134 +msgid "(Must be at least 4 characters, letters and numbers only.)" +msgstr "(Deben tener como mínimo 4 caracteres, solo letras y números.)" + +#: wp-signup.php:137 +msgid "Email Address:" +msgstr "Dirección de correo electrónico:" + +#: wp-signup.php:141 +msgid "We send your registration email to this address. (Double-check your email address before continuing.)" +msgstr "Enviaremos los datos de registro a esta dirección de correo electrónico. Comprueba bien esta dirección antes de continuar." + +#: wp-signup.php:167 +msgid "Get another %s site in seconds" +msgstr "Consigue otro sitio en %s en segundos" + +#: wp-signup.php:170 +msgid "There was a problem, please correct the form below and try again." +msgstr "Hubo un problema, revisa el formulario y prueba de nuevo." + +#: wp-signup.php:173 +msgid "Welcome back, %s. By filling out the form below, you can add another site to your account. There is no limit to the number of sites you can have, so create to your heart’s content, but write responsibly!" +msgstr "Bienvenido de nuevo %s. Rellenando el siguiente formulario, puedes añadir otro sitio a tu cuenta. No hay límite en el número de sitios que puedas tener, por tanto, crea los que necesites, pero escribe con responsabilidad." + +#: wp-signup.php:179 +msgid "Sites you are already a member of:" +msgstr "Eres miembro de los siguientes sitios:" + +#: wp-signup.php:188 +msgid "If you’re not going to use a great site domain, leave it for a new user. Now have at it!" +msgstr "Si no vas a usar un dominio de un sitio, por favor, libéralo para que otro lo pueda usar. Ahora ¡consigue uno!" + +#: wp-signup.php:193 +msgid "Create Site" +msgstr "Crear sitio" + +#: wp-signup.php:223 +msgid "The site %s is yours." +msgstr "El sitio %s es tuyo." + +#: wp-signup.php:225 +msgid "http://%2$s is your new site. Log in as “%4$s” using your existing password." +msgstr "http://%2$s es tu nuevo sitio. Accede como “%4$s” usando tu contraseña actual." + +#: wp-signup.php:252 +msgid "Get your own %s account in seconds" +msgstr "Consigue tu propia cuenta %s en segundos." + +#: wp-signup.php:265 +msgid "Gimme a site!" +msgstr "¡Dame un sitio!" + +#: wp-signup.php:268 +msgid "Just a username, please." +msgstr "Solo el nombre de usuario, gracias." + +#: wp-signup.php:272 +msgid "Next" +msgstr "Siguiente" + +#: wp-signup.php:299 +msgid "%s is your new username" +msgstr "%s es tu nuevo nombre de usuario" + +#: wp-signup.php:300 +msgid "But, before you can start using your new username, you must activate it." +msgstr "Pero, antes de poder comenzar a usar tu nuevo nombre de usuario, debes activarlo." + +#: wp-signup.php:301 +msgid "Check your inbox at %1$s and click the link given." +msgstr "Comprueba la bandeja de entrada de %1$s y haz clic en el enlace que encontrarás." + +#: wp-signup.php:302 +msgid "If you do not activate your username within two days, you will have to sign up again." +msgstr "Si no activas tu nombre de usuario en dos días, deberás registrarte de nuevo." + +#: wp-signup.php:328 +msgid "Signup" +msgstr "Registrarse" + +#: wp-signup.php:362 +msgid "Congratulations! Your new site, %s, is almost ready." +msgstr "¡Felicidades! Tu nuevo sitio , %s, ya está listo." + +#: wp-signup.php:364 +msgid "But, before you can start using your site, you must activate it." +msgstr "Pero, antes de que puedas comenzar a usar tu sitio, debes activarlo." + +#: wp-signup.php:365 +msgid "Check your inbox at %s and click the link given." +msgstr "Comprueba la bandeja de entrada de %s y haz clic en el enlace que encontrarás." + +#: wp-signup.php:366 +msgid "If you do not activate your site within two days, you will have to sign up again." +msgstr "Si no activas tu sitio en dos días, deberás registrarte de nuevo." + +#: wp-signup.php:367 +msgid "Still waiting for your email?" +msgstr "¿Continúas esperando el correo electrónico?" + +#: wp-signup.php:369 +msgid "If you haven’t received your email yet, there are a number of things you can do:" +msgstr "Si todavía no has recibido el correo electrónico, hay una serie de acciones que puedes realizar:" + +#: wp-signup.php:371 +msgid "Wait a little longer. Sometimes delivery of email can be delayed by processes outside of our control." +msgstr "Espera un poco más. Hay veces, que el correo electrónico puede tardar en salir, por razones que escapan a nuestro control." + +#: wp-signup.php:372 +msgid "Check the junk or spam folder of your email client. Sometime emails wind up there by mistake." +msgstr "Comprueba la carpeta de correo basura, correo no deseado o spam de tu cliente de correo electrónico o correo web. A veces los correos electrónicos acaban ahí por equivocación." + +#: wp-signup.php:373 +msgid "Have you entered your email correctly? You have entered %s, if it’s incorrect, you will not receive your email." +msgstr "¿Has introducido tu correo electrónico correctamente? Has introducido %s, si es incorrecto no lo recibirás." + +#: wp-signup.php:388 +msgctxt "Multisite active signup type" +msgid "all" +msgstr "todo" + +#: wp-signup.php:389 +msgctxt "Multisite active signup type" +msgid "none" +msgstr "ninguno" + +#: wp-signup.php:390 +msgctxt "Multisite active signup type" +msgid "blog" +msgstr "blog" + +#: wp-signup.php:391 +msgctxt "Multisite active signup type" +msgid "user" +msgstr "usuario" + +#: wp-signup.php:394 +msgid "Greetings Site Administrator! You are currently allowing “%s” registrations. To change or disable registration go to your Options page." +msgstr "¡Felicidades administrador del sitio! Ahora ya permites registros de “%s”. Para cambiarlo o desactivar los registros ve a tu página de opciones." + +#: wp-signup.php:400 +msgid "Registration has been disabled." +msgstr "Los registros están deshabilitados." + +#: wp-signup.php:407 +msgid "You must first log in, and then you can create a new site." +msgstr "Primero debes iniciar sesión, después podrás crear un sitio nuevo." + +#: wp-signup.php:415 +msgid "User registration has been disabled." +msgstr "No se permite el registro de nuevos usuarios." + +#: wp-signup.php:421 +msgid "Site registration has been disabled." +msgstr "No se permiten nuevos registros de sitios." + +#: wp-signup.php:435 +msgid "Sorry, new registrations are not allowed at this time." +msgstr "Disculpa, los nuevos registros están deshabilitados." + +#: wp-signup.php:437 +msgid "You are logged in already. No need to register again!" +msgstr "Ya te has identificado. ¡No necesitas registrarte de nuevo!" + +#: wp-signup.php:443 +msgid "

    The site you were looking for, %s does not exist, but you can create it now!

    " +msgstr "

    El sitio que estás buscando, %s no existe pero puedes crearlo ahora.

    " + +#: wp-signup.php:445 +msgid "

    The site you were looking for, %s, does not exist.

    " +msgstr "

    El sitio que has estado buscando, %s, no existe.

    " + +#: wp-includes/ms-load.php:211 +msgid "That site does not exist. Please try %s." +msgstr "Este sitio no existe. Por favor, prueba %s." + +#: wp-includes/ms-load.php:213 +msgid "No site defined on this host. If you are the owner of this site, please check Debugging a WordPress Network for help." +msgstr "No se ha definido un sitio para este servidor. Si eres el propietario de este sitio, por favor, consulta Arreglando una red de WordPress para tener ayuda." + +#: wp-includes/ms-load.php:227 +msgid "Error establishing database connection" +msgstr "Error estableciendo conexión con la base de datos" + +#: wp-includes/ms-load.php:231 +msgid "If your site does not display, please contact the owner of this network." +msgstr "Si tu sitio no se muestra contacta con el propietario de esta red." + +#: wp-includes/ms-load.php:232 +msgid "If you are the owner of this network please check that MySQL is running properly and all tables are error free." +msgstr "Si eres el propietario de esta red comprueba que MySQL se está ejecutando adecuadamente y que niguna de las tablas tiene errores." + +#: wp-includes/ms-load.php:234 +msgid "Database tables are missing. This means that MySQL is not running, WordPress was not installed properly, or someone deleted %s. You really should look at your database now." +msgstr "Se han perdido las tablas de la base de datos. Esto quiere decir que MySQL no está funcionando, WordPress no ha sido instalado correctamente, o alguien ha eliminado %s. Realmente, debes revisar tu base de datos ahora mismo." + +#: wp-includes/ms-load.php:236 +msgid "Could not find site %1$s. Searched for table %2$s in database %3$s. Is that right?" +msgstr "No podemos encontrar el sitio %1$s. Buscamos la tabla %2$sen la base de datos %3$s. ¿Es correcto?" + +#: wp-includes/ms-load.php:238 +msgid "Read the bug report page. Some of the guidelines there may help you figure out what went wrong." +msgstr "Lee la página de errores. Algunas de las guías que hay ahí pueden ayudarte a hacerte una idea sobre qué ha ido mal." + +#: wp-includes/ms-load.php:239 +msgid "If you’re still stuck with this message, then check that your database contains the following tables:" +msgstr "Si todavía estás atascado con este mensaje, comprueba que tu base de datos contiene las siguientes tablas:" + +#: wp-includes/ms-settings.php:15 +msgid "Configuration error in wp-config.php. $base is set to BASE when it should be like / or /blogs/." +msgstr "Error de configuración en wp-config.php. $base está definido como BASE cuando debería ser parecido a / o /sitios/." + +#: wp-includes/ms-settings.php:38 +msgid "Multisite only works without the port number in the URL." +msgstr "El multisitio sólo funciona sin el número del puerto en la URL." + +#: wp-includes/ms-settings.php:123 +msgid "Database tables are missing." +msgstr "No se encuentran tablas de la base de datos." + +#: wp-includes/ms-settings.php:124 +msgid "No site by that name on this system." +msgstr "No existe ningún sitio en el sistema con este nombre." \ No newline at end of file diff --git a/src/wp-content/plugins/akismet/admin.php b/src/wp-content/plugins/akismet/admin.php new file mode 100644 index 00000000..91cedb29 --- /dev/null +++ b/src/wp-content/plugins/akismet/admin.php @@ -0,0 +1,750 @@ +

    ".sprintf(__('Akismet %s requires WordPress 3.0 or higher.'), AKISMET_VERSION) ." ".sprintf(__('Please upgrade WordPress to a current version, or downgrade to version 2.4 of the Akismet plugin.'), 'http://codex.wordpress.org/Upgrading_WordPress', 'http://wordpress.org/extend/plugins/akismet/download/'). "

    + "; + } + add_action('admin_notices', 'akismet_version_warning'); + + return; + } + + if ( function_exists( 'get_plugin_page_hook' ) ) + $hook = get_plugin_page_hook( 'akismet-stats-display', 'index.php' ); + else + $hook = 'dashboard_page_akismet-stats-display'; + add_action('admin_head-'.$hook, 'akismet_stats_script'); + add_meta_box('akismet-status', __('Comment History'), 'akismet_comment_status_meta_box', 'comment', 'normal'); + wp_register_style('akismet.css', AKISMET_PLUGIN_URL . 'akismet.css'); + wp_enqueue_style('akismet.css'); + wp_register_script('akismet.js', AKISMET_PLUGIN_URL . 'akismet.js', array('jquery')); + wp_enqueue_script('akismet.js'); +} +add_action('admin_init', 'akismet_admin_init'); + +function akismet_nonce_field($action = -1) { return wp_nonce_field($action); } +$akismet_nonce = 'akismet-update-key'; + +function akismet_config_page() { + if ( function_exists('add_submenu_page') ) + add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf'); +} + +function akismet_plugin_action_links( $links, $file ) { + if ( $file == plugin_basename( dirname(__FILE__).'/akismet.php' ) ) { + $links[] = ''.__('Settings').''; + } + + return $links; +} + +add_filter( 'plugin_action_links', 'akismet_plugin_action_links', 10, 2 ); + +function akismet_conf() { + global $akismet_nonce, $wpcom_api_key; + + if ( isset($_POST['submit']) ) { + if ( function_exists('current_user_can') && !current_user_can('manage_options') ) + die(__('Cheatin’ uh?')); + + check_admin_referer( $akismet_nonce ); + $key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] ); + $home_url = parse_url( get_bloginfo('url') ); + + if ( empty($key) ) { + $key_status = 'empty'; + $ms[] = 'new_key_empty'; + delete_option('wordpress_api_key'); + } elseif ( empty($home_url['host']) ) { + $key_status = 'empty'; + $ms[] = 'bad_home_url'; + } else { + $key_status = akismet_verify_key( $key ); + } + + if ( $key_status == 'valid' ) { + update_option('wordpress_api_key', $key); + $ms[] = 'new_key_valid'; + } else if ( $key_status == 'invalid' ) { + $ms[] = 'new_key_invalid'; + } else if ( $key_status == 'failed' ) { + $ms[] = 'new_key_failed'; + } + + if ( isset( $_POST['akismet_discard_month'] ) ) + update_option( 'akismet_discard_month', 'true' ); + else + update_option( 'akismet_discard_month', 'false' ); + + if ( isset( $_POST['akismet_show_user_comments_approved'] ) ) + update_option( 'akismet_show_user_comments_approved', 'true' ); + else + update_option( 'akismet_show_user_comments_approved', 'false' ); + + } elseif ( isset($_POST['check']) ) { + akismet_get_server_connectivity(0); + } + + if ( empty( $key_status) || $key_status != 'valid' ) { + $key = get_option('wordpress_api_key'); + if ( empty( $key ) ) { + if ( empty( $key_status ) || $key_status != 'failed' ) { + if ( akismet_verify_key( '1234567890ab' ) == 'failed' ) + $ms[] = 'no_connection'; + else + $ms[] = 'key_empty'; + } + $key_status = 'empty'; + } else { + $key_status = akismet_verify_key( $key ); + } + if ( $key_status == 'valid' ) { + $ms[] = 'key_valid'; + } else if ( $key_status == 'invalid' ) { + delete_option('wordpress_api_key'); + $ms[] = 'key_empty'; + } else if ( !empty($key) && $key_status == 'failed' ) { + $ms[] = 'key_failed'; + } + } + + $messages = array( + 'new_key_empty' => array('color' => 'aa0', 'text' => __('Your key has been cleared.')), + 'new_key_valid' => array('color' => '4AB915', 'text' => __('Your key has been verified. Happy blogging!')), + 'new_key_invalid' => array('color' => '888', 'text' => __('The key you entered is invalid. Please double-check it.')), + 'new_key_failed' => array('color' => '888', 'text' => __('The key you entered could not be verified because a connection to akismet.com could not be established. Please check your server configuration.')), + 'no_connection' => array('color' => '888', 'text' => __('There was a problem connecting to the Akismet server. Please check your server configuration.')), + 'key_empty' => array('color' => 'aa0', 'text' => sprintf(__('Please enter an API key. (Get your key.)'), 'http://akismet.com/get/')), + 'key_valid' => array('color' => '4AB915', 'text' => __('This key is valid.')), + 'key_failed' => array('color' => 'aa0', 'text' => __('The key below was previously validated but a connection to akismet.com can not be established at this time. Please check your server configuration.')), + 'bad_home_url' => array('color' => '888', 'text' => sprintf( __('Your WordPress home URL %s is invalid. Please fix the home option.'), esc_html( get_bloginfo('url') ), admin_url('options.php#home') ) ), + ); +?> + +

    + +
    +

    + +

    Sign up success! Please check your email for your Akismet API Key and enter it below.' ); ?>

    + +
    +
    + +

    Akismet will greatly reduce or even completely eliminate the comment and trackback spam you get on your site. If one does happen to get through, simply mark it as "spam" on the moderation screen and Akismet will learn from the mistakes. If you don\'t have an API key yet, you can get one at Akismet.com.'), 'http://akismet.com/', 'http://akismet.com/get/'); ?>

    + +

    + +

    + +

    (What is this?'); ?>)

    + +

    +

    + + + +

    +

    +

    +
    + +
    + +

    + +

    +

    fsockopen or gethostbynamel functions. Akismet cannot work correctly until this is fixed. Please contact your web host or firewall administrator and give them this information about Akismet\'s system requirements.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?>

    + 0 ) { + // some connections work, some fail + if ( $fail_count > 0 && $fail_count < count($servers) ) { ?> +

    +

    this information about Akismet and firewalls.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?>

    + 0 ) { ?> +

    +

    Akismet cannot work correctly until this is fixed. Please contact your web host or firewall administrator and give them this information about Akismet and firewalls.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?>

    + +

    +

    + +

    +

    Akismet cannot work correctly until this is fixed. Please contact your web host or firewall administrator and give them this information about Akismet and firewalls.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?>

    + + + + + $status ) { + $color = ( $status ? '#4AB915' : '#888'); + ?> + + + + + + +
    +

    +

    +

    Click here to confirm that Akismet.com is up.'), 'http://status.automattic.com/9931/136079/Akismet-API', 'http://status.automattic.com/9931/136079/Akismet-API' ); ?>

    +
    + +
    +
    + + +
    + +
    + ' . _x( 'Spam', 'comments' ) . ''; + global $submenu; + if ( isset( $submenu['edit-comments.php'] ) ) + $link = 'edit-comments.php'; + else + $link = 'edit.php'; + echo '

    '.sprintf( _n( 'Akismet has protected your site from %3$s spam comments.', 'Akismet has protected your site from %3$s spam comments.', $count ), 'http://akismet.com/', clean_url("$link?page=akismet-admin"), number_format_i18n($count) ).'

    '; +} +add_action('activity_box_end', 'akismet_stats'); + +function akismet_admin_warnings() { + global $wpcom_api_key; + if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) { + function akismet_warning() { + echo " +

    ".__('Akismet is almost ready.')." ".sprintf(__('You must enter your Akismet API key for it to work.'), "plugins.php?page=akismet-key-config")."

    + "; + } + add_action('admin_notices', 'akismet_warning'); + return; + } elseif ( ( empty($_SERVER['SCRIPT_FILENAME']) || basename($_SERVER['SCRIPT_FILENAME']) == 'edit-comments.php' ) && wp_next_scheduled('akismet_schedule_cron_recheck') ) { + function akismet_warning() { + global $wpdb; + $waiting = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) ); + $next_check = human_time_diff( wp_next_scheduled('akismet_schedule_cron_recheck') ); + if ( $waiting > 0 ) + echo " +

    ".__('Akismet has detected a problem.')." ".sprintf(_n('A server or network problem prevented Akismet from checking %d comment. It has been temporarily held for moderation and will be automatically re-checked in %s.', 'A server or network problem prevented Akismet from checking %d comments. They have been temporarily held for moderation and will be automatically re-checked in %s.', $waiting), number_format_i18n( $waiting ), $next_check)."

    + "; + } + add_action('admin_notices', 'akismet_warning'); + return; + } +} + +// FIXME placeholder + +function akismet_comment_row_action( $a, $comment ) { + + // failsafe for old WP versions + if ( !function_exists('add_comment_meta') ) + return $a; + + $akismet_result = get_comment_meta( $comment->comment_ID, 'akismet_result', true ); + $user_result = get_comment_meta( $comment->comment_ID, 'akismet_user_result', true); + $comment_status = wp_get_comment_status( $comment->comment_ID ); + $desc = null; + if ( !$user_result || $user_result == $akismet_result ) { + // Show the original Akismet result if the user hasn't overridden it, or if their decision was the same + if ( $akismet_result == 'true' && $comment_status != 'spam' && $comment_status != 'trash' ) + $desc = __( 'Flagged as spam by Akismet' ); + elseif ( $akismet_result == 'false' && $comment_status == 'spam' ) + $desc = __( 'Cleared by Akismet' ); + } else { + $who = get_comment_meta( $comment->comment_ID, 'akismet_user', true ); + if ( $user_result == 'true' ) + $desc = sprintf( __('Flagged as spam by %s'), $who ); + else + $desc = sprintf( __('Un-spammed by %s'), $who ); + } + + // add a History item to the hover links, just after Edit + if ( $akismet_result ) { + $b = array(); + foreach ( $a as $k => $item ) { + $b[ $k ] = $item; + if ( $k == 'edit' ) + $b['history'] = ' '. __('History') . ''; + } + + $a = $b; + } + + if ( $desc ) + echo ''.htmlspecialchars($desc).''; + + if ( apply_filters( 'akismet_show_user_comments_approved', get_option('akismet_show_user_comments_approved') ) == 'true' ) { + $comment_count = akismet_get_user_comments_approved( $comment->user_id, $comment->comment_author_email, $comment->comment_author, $comment->comment_author_url ); + $comment_count = intval( $comment_count ); + echo ''; + } + + return $a; +} + +add_filter( 'comment_row_actions', 'akismet_comment_row_action', 10, 2 ); + +function akismet_comment_status_meta_box($comment) { + $history = akismet_get_comment_history( $comment->comment_ID ); + + if ( $history ) { + echo '
    '; + foreach ( $history as $row ) { + $time = date( 'D d M Y @ h:i:m a', $row['time'] ) . ' GMT'; + echo '
    ' . sprintf( __('%s ago'), human_time_diff( $row['time'] ) ) . ' - '; + echo htmlspecialchars( $row['message'] ) . '
    '; + } + + echo '
    '; + + } +} + + +// add an extra column header to the comments screen +function akismet_comments_columns( $columns ) { + $columns[ 'akismet' ] = __( 'Akismet' ); + return $columns; +} + +#add_filter( 'manage_edit-comments_columns', 'akismet_comments_columns' ); + +// Show stuff in the extra column +function akismet_comment_column_row( $column, $comment_id ) { + if ( $column != 'akismet' ) + return; + + $history = akismet_get_comment_history( $comment_id ); + + if ( $history ) { + echo '
    '; + foreach ( $history as $row ) { + echo '
    ' . sprintf( __('%s ago'), human_time_diff( $row['time'] ) ) . '
    '; + echo '
    ' . htmlspecialchars( $row['message'] ) . '
    '; + } + + echo '
    '; + } +} + +#add_action( 'manage_comments_custom_column', 'akismet_comment_column_row', 10, 2 ); + +// END FIXME + +// call out URLS in comments +function akismet_text_add_link_callback( $m ) { + + // bare link? + if ( $m[4] == $m[2] ) + return ''.$m[4].''; + else + return ''.$m[4].''; +} + +function akismet_text_add_link_class( $comment_text ) { + + return preg_replace_callback( '#]*)href="([^"]+)"([^>]*)>(.*?)#i', 'akismet_text_add_link_callback', $comment_text ); +} + +add_filter('comment_text', 'akismet_text_add_link_class'); + + +// WP 2.5+ +function akismet_rightnow() { + global $submenu, $wp_db_version; + + // clean_url was deprecated in WP 3.0 + $esc_url = 'clean_url'; + if ( function_exists( 'esc_url' ) ) + $esc_url = 'esc_url'; + + if ( 8645 < $wp_db_version ) // 2.7 + $link = 'edit-comments.php?comment_status=spam'; + elseif ( isset( $submenu['edit-comments.php'] ) ) + $link = 'edit-comments.php?page=akismet-admin'; + else + $link = 'edit.php?page=akismet-admin'; + + if ( $count = get_option('akismet_spam_count') ) { + $intro = sprintf( _n( + 'Akismet has protected your site from %2$s spam comment already. ', + 'Akismet has protected your site from %2$s spam comments already. ', + $count + ), 'http://akismet.com/', number_format_i18n( $count ) ); + } else { + $intro = sprintf( __('Akismet blocks spam from getting to your blog. '), 'http://akismet.com/' ); + } + + if ( $queue_count = akismet_spam_count() ) { + $queue_text = sprintf( _n( + 'There\'s %1$s comment in your spam queue right now.', + 'There are %1$s comments in your spam queue right now.', + $queue_count + ), number_format_i18n( $queue_count ), $esc_url($link) ); + } else { + $queue_text = sprintf( __( "There's nothing in your spam queue at the moment." ), $esc_url($link) ); + } + + $text = $intro . '
    ' . $queue_text; + echo "

    $text

    \n"; +} + +add_action('rightnow_end', 'akismet_rightnow'); + + +// For WP >= 2.5 +function akismet_check_for_spam_button($comment_status) { + if ( 'approved' == $comment_status ) + return; + if ( function_exists('plugins_url') ) + $link = 'admin.php?action=akismet_recheck_queue'; + else + $link = 'edit-comments.php?page=akismet-admin&recheckqueue=true&noheader=true'; + echo "
    " . __('Check for Spam') . ""; +} +add_action('manage_comments_nav', 'akismet_check_for_spam_button'); + +function akismet_submit_nonspam_comment ( $comment_id ) { + global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site; + $comment_id = (int) $comment_id; + + $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'"); + if ( !$comment ) // it was deleted + return; + + // use the original version stored in comment_meta if available + $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true); + if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) ) { + $comment = (object) array_merge( (array)$comment, $as_submitted ); + } + + $comment->blog = get_bloginfo('url'); + $comment->blog_lang = get_locale(); + $comment->blog_charset = get_option('blog_charset'); + $comment->permalink = get_permalink($comment->comment_post_ID); + $comment->reporter_ip = $_SERVER['REMOTE_ADDR']; + if ( is_object($current_user) ) { + $comment->reporter = $current_user->user_login; + } + if ( is_object($current_site) ) { + $comment->site_domain = $current_site->domain; + } + + $comment->user_role = ''; + if ( isset( $comment->user_ID ) ) + $comment->user_role = akismet_get_user_roles($comment->user_ID); + + if ( akismet_test_mode() ) + $comment->is_test = 'true'; + + $query_string = ''; + foreach ( $comment as $key => $data ) + $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&'; + + $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port); + if ( $comment->reporter ) { + akismet_update_comment_history( $comment_id, sprintf( __('%s reported this comment as not spam'), $comment->reporter ), 'report-ham' ); + update_comment_meta( $comment_id, 'akismet_user_result', 'false' ); + update_comment_meta( $comment_id, 'akismet_user', $comment->reporter ); + } + + do_action('akismet_submit_nonspam_comment', $comment_id, $response[1]); +} + +function akismet_submit_spam_comment ( $comment_id ) { + global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site; + $comment_id = (int) $comment_id; + + $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'"); + if ( !$comment ) // it was deleted + return; + if ( 'spam' != $comment->comment_approved ) + return; + + // use the original version stored in comment_meta if available + $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true); + if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) ) { + $comment = (object) array_merge( (array)$comment, $as_submitted ); + } + + $comment->blog = get_bloginfo('url'); + $comment->blog_lang = get_locale(); + $comment->blog_charset = get_option('blog_charset'); + $comment->permalink = get_permalink($comment->comment_post_ID); + $comment->reporter_ip = $_SERVER['REMOTE_ADDR']; + if ( is_object($current_user) ) { + $comment->reporter = $current_user->user_login; + } + if ( is_object($current_site) ) { + $comment->site_domain = $current_site->domain; + } + + $comment->user_role = ''; + if ( isset( $comment->user_ID ) ) + $comment->user_role = akismet_get_user_roles($comment->user_ID); + + if ( akismet_test_mode() ) + $comment->is_test = 'true'; + + $query_string = ''; + foreach ( $comment as $key => $data ) + $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&'; + + $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port); + if ( $comment->reporter ) { + akismet_update_comment_history( $comment_id, sprintf( __('%s reported this comment as spam'), $comment->reporter ), 'report-spam' ); + update_comment_meta( $comment_id, 'akismet_user_result', 'true' ); + update_comment_meta( $comment_id, 'akismet_user', $comment->reporter ); + } + do_action('akismet_submit_spam_comment', $comment_id, $response[1]); +} + +// For WP 2.7+ +function akismet_transition_comment_status( $new_status, $old_status, $comment ) { + if ( $new_status == $old_status ) + return; + + # we don't need to record a history item for deleted comments + if ( $new_status == 'delete' ) + return; + + if ( !is_admin() ) + return; + + if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) ) + return; + + if ( defined('WP_IMPORTING') && WP_IMPORTING == true ) + return; + + global $current_user; + $reporter = ''; + if ( is_object( $current_user ) ) + $reporter = $current_user->user_login; + + // Assumption alert: + // We want to submit comments to Akismet only when a moderator explicitly spams or approves it - not if the status + // is changed automatically by another plugin. Unfortunately WordPress doesn't provide an unambiguous way to + // determine why the transition_comment_status action was triggered. And there are several different ways by which + // to spam and unspam comments: bulk actions, ajax, links in moderation emails, the dashboard, and perhaps others. + // We'll assume that this is an explicit user action if POST or GET has an 'action' key. + if ( isset($_POST['action']) || isset($_GET['action']) ) { + if ( $new_status == 'spam' && ( $old_status == 'approved' || $old_status == 'unapproved' || !$old_status ) ) { + return akismet_submit_spam_comment( $comment->comment_ID ); + } elseif ( $old_status == 'spam' && ( $new_status == 'approved' || $new_status == 'unapproved' ) ) { + return akismet_submit_nonspam_comment( $comment->comment_ID ); + } + } + + if ( !get_comment_meta( $comment->comment_ID, 'akismet_rechecking' ) ) + akismet_update_comment_history( $comment->comment_ID, sprintf( __('%s changed the comment status to %s'), $reporter, $new_status ), 'status-' . $new_status ); +} + +add_action( 'transition_comment_status', 'akismet_transition_comment_status', 10, 3 ); + +// Total spam in queue +// get_option( 'akismet_spam_count' ) is the total caught ever +function akismet_spam_count( $type = false ) { + global $wpdb; + + if ( !$type ) { // total + $count = wp_cache_get( 'akismet_spam_count', 'widget' ); + if ( false === $count ) { + if ( function_exists('wp_count_comments') ) { + $count = wp_count_comments(); + $count = $count->spam; + } else { + $count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'"); + } + wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 ); + } + return $count; + } elseif ( 'comments' == $type || 'comment' == $type ) { // comments + $type = ''; + } else { // pingback, trackback, ... + $type = $wpdb->escape( $type ); + } + + return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'"); +} + + +function akismet_recheck_queue() { + global $wpdb, $akismet_api_host, $akismet_api_port; + + if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) ) + return; + + $moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A ); + foreach ( (array) $moderation as $c ) { + $c['user_ip'] = $c['comment_author_IP']; + $c['user_agent'] = $c['comment_agent']; + $c['referrer'] = ''; + $c['blog'] = get_bloginfo('url'); + $c['blog_lang'] = get_locale(); + $c['blog_charset'] = get_option('blog_charset'); + $c['permalink'] = get_permalink($c['comment_post_ID']); + + $c['user_role'] = ''; + if ( isset( $c['user_ID'] ) ) + $c['user_role'] = akismet_get_user_roles($c['user_ID']); + + if ( akismet_test_mode() ) + $c['is_test'] = 'true'; + + $id = (int) $c['comment_ID']; + + $query_string = ''; + foreach ( $c as $key => $data ) + $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&'; + + $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port); + if ( 'true' == $response[1] ) { + wp_set_comment_status($c['comment_ID'], 'spam'); + update_comment_meta( $c['comment_ID'], 'akismet_result', 'true' ); + akismet_update_comment_history( $c['comment_ID'], __('Akismet re-checked and caught this comment as spam'), 'check-spam' ); + + } elseif ( 'false' == $response[1] ) { + update_comment_meta( $c['comment_ID'], 'akismet_result', 'false' ); + akismet_update_comment_history( $c['comment_ID'], __('Akismet re-checked and cleared this comment'), 'check-ham' ); + // abnormal result: error + } else { + update_comment_meta( $c['comment_ID'], 'akismet_result', 'error' ); + akismet_update_comment_history( $c['comment_ID'], sprintf( __('Akismet was unable to re-check this comment (response: %s)'), $response[1]), 'check-error' ); + } + + } + wp_redirect( $_SERVER['HTTP_REFERER'] ); + exit; +} + +add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue'); + +// Check connectivity between the WordPress blog and Akismet's servers. +// Returns an associative array of server IP addresses, where the key is the IP address, and value is true (available) or false (unable to connect). +function akismet_check_server_connectivity() { + global $akismet_api_host, $akismet_api_port, $wpcom_api_key; + + $test_host = 'rest.akismet.com'; + + // Some web hosts may disable one or both functions + if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') ) + return array(); + + $ips = gethostbynamel($test_host); + if ( !$ips || !is_array($ips) || !count($ips) ) + return array(); + + $servers = array(); + foreach ( $ips as $ip ) { + $response = akismet_verify_key( akismet_get_key(), $ip ); + // even if the key is invalid, at least we know we have connectivity + if ( $response == 'valid' || $response == 'invalid' ) + $servers[$ip] = true; + else + $servers[$ip] = false; + } + + return $servers; +} + +// Check the server connectivity and store the results in an option. +// Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update. +// Returns the same associative array as akismet_check_server_connectivity() +function akismet_get_server_connectivity( $cache_timeout = 86400 ) { + $servers = get_option('akismet_available_servers'); + if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false ) + return $servers; + + // There's a race condition here but the effect is harmless. + $servers = akismet_check_server_connectivity(); + update_option('akismet_available_servers', $servers); + update_option('akismet_connectivity_time', time()); + return $servers; +} + +// Returns true if server connectivity was OK at the last check, false if there was a problem that needs to be fixed. +function akismet_server_connectivity_ok() { + // skip the check on WPMU because the status page is hidden + global $wpcom_api_key; + if ( $wpcom_api_key ) + return true; + $servers = akismet_get_server_connectivity(); + return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) ); +} + diff --git a/src/wp-content/plugins/akismet/akismet.css b/src/wp-content/plugins/akismet/akismet.css new file mode 100644 index 00000000..6bc84587 --- /dev/null +++ b/src/wp-content/plugins/akismet/akismet.css @@ -0,0 +1,7 @@ +#submitted-on { position: relative; } +#the-comment-list .author .akismet-user-comment-count { display: inline; } +#dashboard_recent_comments .akismet-status { display: none; } /* never show the flagged by text on the dashboard */ +.akismet-status { float: right; } +.akismet-status a { color: #AAA; font-style: italic; } +span.comment-link a { text-decoration: underline; } +span.comment-link:after { content: " " attr(title) " "; color: #aaa; text-decoration: none; } diff --git a/src/wp-content/plugins/akismet/akismet.gif b/src/wp-content/plugins/akismet/akismet.gif new file mode 100644 index 00000000..0b93a89b Binary files /dev/null and b/src/wp-content/plugins/akismet/akismet.gif differ diff --git a/src/wp-content/plugins/akismet/akismet.js b/src/wp-content/plugins/akismet/akismet.js new file mode 100644 index 00000000..39089351 --- /dev/null +++ b/src/wp-content/plugins/akismet/akismet.js @@ -0,0 +1,10 @@ +jQuery(document).ready(function () { + jQuery('.akismet-status').each(function () { + var thisId = jQuery(this).attr('commentid'); + jQuery(this).prependTo('#comment-' + thisId + ' .column-comment div:first-child'); + }); + jQuery('.akismet-user-comment-count').each(function () { + var thisId = jQuery(this).attr('commentid'); + jQuery(this).insertAfter('#comment-' + thisId + ' .author strong:first').show(); + }); +}); diff --git a/src/wp-content/plugins/akismet/akismet.php b/src/wp-content/plugins/akismet/akismet.php new file mode 100644 index 00000000..f4537450 --- /dev/null +++ b/src/wp-content/plugins/akismet/akismet.php @@ -0,0 +1,512 @@ +protect your blog from comment and trackback spam. It keeps your site protected from spam even while you sleep. To get started: 1) Click the "Activate" link to the left of this description, 2) Sign up for an Akismet API key, and 3) Go to your Akismet configuration page, and save your API key. +Version: 2.5.3 +Author: Automattic +Author URI: http://automattic.com/wordpress-plugins/ +License: GPLv2 or later +*/ + +/* +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +define('AKISMET_VERSION', '2.5.3'); +define('AKISMET_PLUGIN_URL', plugin_dir_url( __FILE__ )); + +/** If you hardcode a WP.com API key here, all key config screens will be hidden */ +if ( defined('WPCOM_API_KEY') ) + $wpcom_api_key = constant('WPCOM_API_KEY'); +else + $wpcom_api_key = ''; + +// Make sure we don't expose any info if called directly +if ( !function_exists( 'add_action' ) ) { + echo "Hi there! I'm just a plugin, not much I can do when called directly."; + exit; +} + +if ( isset($wp_db_version) && $wp_db_version <= 9872 ) + include_once dirname( __FILE__ ) . '/legacy.php'; + +include_once dirname( __FILE__ ) . '/widget.php'; + +if ( is_admin() ) + require_once dirname( __FILE__ ) . '/admin.php'; + +function akismet_init() { + global $wpcom_api_key, $akismet_api_host, $akismet_api_port; + + if ( $wpcom_api_key ) + $akismet_api_host = $wpcom_api_key . '.rest.akismet.com'; + else + $akismet_api_host = get_option('wordpress_api_key') . '.rest.akismet.com'; + + $akismet_api_port = 80; +} +add_action('init', 'akismet_init'); + +function akismet_get_key() { + global $wpcom_api_key; + if ( !empty($wpcom_api_key) ) + return $wpcom_api_key; + return get_option('wordpress_api_key'); +} + +function akismet_verify_key( $key, $ip = null ) { + global $akismet_api_host, $akismet_api_port, $wpcom_api_key; + $blog = urlencode( get_option('home') ); + if ( $wpcom_api_key ) + $key = $wpcom_api_key; + $response = akismet_http_post("key=$key&blog=$blog", 'rest.akismet.com', '/1.1/verify-key', $akismet_api_port, $ip); + if ( !is_array($response) || !isset($response[1]) || $response[1] != 'valid' && $response[1] != 'invalid' ) + return 'failed'; + return $response[1]; +} + +// if we're in debug or test modes, use a reduced service level so as not to polute training or stats data +function akismet_test_mode() { + if ( defined('AKISMET_TEST_MODE') && AKISMET_TEST_MODE ) + return true; + return false; +} + +// return a comma-separated list of role names for the given user +function akismet_get_user_roles($user_id ) { + $roles = false; + + if ( !class_exists('WP_User') ) + return false; + + if ( $user_id > 0 ) { + $comment_user = new WP_User($user_id); + if ( isset($comment_user->roles) ) + $roles = join(',', $comment_user->roles); + } + + if ( is_multisite() && is_super_admin( $user_id ) ) { + if ( empty( $roles ) ) { + $roles = 'super_admin'; + } else { + $comment_user->roles[] = 'super_admin'; + $roles = join( ',', $comment_user->roles ); + } + } + + return $roles; +} + +// Returns array with headers in $response[0] and body in $response[1] +function akismet_http_post($request, $host, $path, $port = 80, $ip=null) { + global $wp_version; + + $akismet_ua = "WordPress/{$wp_version} | "; + $akismet_ua .= 'Akismet/' . constant( 'AKISMET_VERSION' ); + + $content_length = strlen( $request ); + + $http_host = $host; + // use a specific IP if provided + // needed by akismet_check_server_connectivity() + if ( $ip && long2ip( ip2long( $ip ) ) ) { + $http_host = $ip; + } else { + $http_host = $host; + } + + // use the WP HTTP class if it is available + if ( function_exists( 'wp_remote_post' ) ) { + $http_args = array( + 'body' => $request, + 'headers' => array( + 'Content-Type' => 'application/x-www-form-urlencoded; ' . + 'charset=' . get_option( 'blog_charset' ), + 'Host' => $host, + 'User-Agent' => $akismet_ua + ), + 'httpversion' => '1.0', + 'timeout' => 15 + ); + $akismet_url = "http://{$http_host}{$path}"; + $response = wp_remote_post( $akismet_url, $http_args ); + if ( is_wp_error( $response ) ) + return ''; + + return array( $response['headers'], $response['body'] ); + } else { + $http_request = "POST $path HTTP/1.0\r\n"; + $http_request .= "Host: $host\r\n"; + $http_request .= 'Content-Type: application/x-www-form-urlencoded; charset=' . get_option('blog_charset') . "\r\n"; + $http_request .= "Content-Length: {$content_length}\r\n"; + $http_request .= "User-Agent: {$akismet_ua}\r\n"; + $http_request .= "\r\n"; + $http_request .= $request; + + $response = ''; + if( false != ( $fs = @fsockopen( $http_host, $port, $errno, $errstr, 10 ) ) ) { + fwrite( $fs, $http_request ); + + while ( !feof( $fs ) ) + $response .= fgets( $fs, 1160 ); // One TCP-IP packet + fclose( $fs ); + $response = explode( "\r\n\r\n", $response, 2 ); + } + return $response; + } +} + +// filter handler used to return a spam result to pre_comment_approved +function akismet_result_spam( $approved ) { + // bump the counter here instead of when the filter is added to reduce the possibility of overcounting + if ( $incr = apply_filters('akismet_spam_count_incr', 1) ) + update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr ); + // this is a one-shot deal + remove_filter( 'pre_comment_approved', 'akismet_result_spam' ); + return 'spam'; +} + +function akismet_result_hold( $approved ) { + // once only + remove_filter( 'pre_comment_approved', 'akismet_result_hold' ); + return '0'; +} + +// how many approved comments does this author have? +function akismet_get_user_comments_approved( $user_id, $comment_author_email, $comment_author, $comment_author_url ) { + global $wpdb; + + if ( !empty($user_id) ) + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE user_id = %d AND comment_approved = 1", $user_id ) ); + + if ( !empty($comment_author_email) ) + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_author_email = %s AND comment_author = %s AND comment_author_url = %s AND comment_approved = 1", $comment_author_email, $comment_author, $comment_author_url ) ); + + return 0; +} + +function akismet_microtime() { + $mtime = explode( ' ', microtime() ); + return $mtime[1] + $mtime[0]; +} + +// log an event for a given comment, storing it in comment_meta +function akismet_update_comment_history( $comment_id, $message, $event=null ) { + global $current_user; + + // failsafe for old WP versions + if ( !function_exists('add_comment_meta') ) + return false; + + $user = ''; + if ( is_object($current_user) && isset($current_user->user_login) ) + $user = $current_user->user_login; + + $event = array( + 'time' => akismet_microtime(), + 'message' => $message, + 'event' => $event, + 'user' => $user, + ); + + // $unique = false so as to allow multiple values per comment + $r = add_comment_meta( $comment_id, 'akismet_history', $event, false ); +} + +// get the full comment history for a given comment, as an array in reverse chronological order +function akismet_get_comment_history( $comment_id ) { + + // failsafe for old WP versions + if ( !function_exists('add_comment_meta') ) + return false; + + $history = get_comment_meta( $comment_id, 'akismet_history', false ); + usort( $history, 'akismet_cmp_time' ); + return $history; +} + +function akismet_cmp_time( $a, $b ) { + return $a['time'] > $b['time'] ? -1 : 1; +} + +// this fires on wp_insert_comment. we can't update comment_meta when akismet_auto_check_comment() runs +// because we don't know the comment ID at that point. +function akismet_auto_check_update_meta( $id, $comment ) { + global $akismet_last_comment; + + // failsafe for old WP versions + if ( !function_exists('add_comment_meta') ) + return false; + + // wp_insert_comment() might be called in other contexts, so make sure this is the same comment + // as was checked by akismet_auto_check_comment + if ( is_object($comment) && !empty($akismet_last_comment) && is_array($akismet_last_comment) ) { + if ( intval($akismet_last_comment['comment_post_ID']) == intval($comment->comment_post_ID) + && $akismet_last_comment['comment_author'] == $comment->comment_author + && $akismet_last_comment['comment_author_email'] == $comment->comment_author_email ) { + // normal result: true or false + if ( $akismet_last_comment['akismet_result'] == 'true' ) { + update_comment_meta( $comment->comment_ID, 'akismet_result', 'true' ); + akismet_update_comment_history( $comment->comment_ID, __('Akismet caught this comment as spam'), 'check-spam' ); + if ( $comment->comment_approved != 'spam' ) + akismet_update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s'), $comment->comment_approved), 'status-changed'.$comment->comment_approved ); + } elseif ( $akismet_last_comment['akismet_result'] == 'false' ) { + update_comment_meta( $comment->comment_ID, 'akismet_result', 'false' ); + akismet_update_comment_history( $comment->comment_ID, __('Akismet cleared this comment'), 'check-ham' ); + if ( $comment->comment_approved == 'spam' ) { + if ( wp_blacklist_check($comment->comment_author, $comment->comment_author_email, $comment->comment_author_url, $comment->comment_content, $comment->comment_author_IP, $comment->comment_agent) ) + akismet_update_comment_history( $comment->comment_ID, __('Comment was caught by wp_blacklist_check'), 'wp-blacklisted' ); + else + akismet_update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s'), $comment->comment_approved), 'status-changed-'.$comment->comment_approved ); + } + // abnormal result: error + } else { + update_comment_meta( $comment->comment_ID, 'akismet_error', time() ); + akismet_update_comment_history( $comment->comment_ID, sprintf( __('Akismet was unable to check this comment (response: %s), will automatically retry again later.'), $akismet_last_comment['akismet_result']), 'check-error' ); + } + + // record the complete original data as submitted for checking + if ( isset($akismet_last_comment['comment_as_submitted']) ) + update_comment_meta( $comment->comment_ID, 'akismet_as_submitted', $akismet_last_comment['comment_as_submitted'] ); + } + } +} + +add_action( 'wp_insert_comment', 'akismet_auto_check_update_meta', 10, 2 ); + + +function akismet_auto_check_comment( $commentdata ) { + global $akismet_api_host, $akismet_api_port, $akismet_last_comment; + + $comment = $commentdata; + $comment['user_ip'] = $_SERVER['REMOTE_ADDR']; + $comment['user_agent'] = $_SERVER['HTTP_USER_AGENT']; + $comment['referrer'] = $_SERVER['HTTP_REFERER']; + $comment['blog'] = get_option('home'); + $comment['blog_lang'] = get_locale(); + $comment['blog_charset'] = get_option('blog_charset'); + $comment['permalink'] = get_permalink($comment['comment_post_ID']); + + $comment['user_role'] = akismet_get_user_roles($comment['user_ID']); + + $akismet_nonce_option = apply_filters( 'akismet_comment_nonce', get_option( 'akismet_comment_nonce' ) ); + $comment['akismet_comment_nonce'] = 'inactive'; + if ( $akismet_nonce_option == 'true' || $akismet_nonce_option == '' ) { + $comment['akismet_comment_nonce'] = 'failed'; + if ( isset( $_POST['akismet_comment_nonce'] ) && wp_verify_nonce( $_POST['akismet_comment_nonce'], 'akismet_comment_nonce_' . $comment['comment_post_ID'] ) ) + $comment['akismet_comment_nonce'] = 'passed'; + + // comment reply in wp-admin + if ( isset( $_POST['_ajax_nonce-replyto-comment'] ) && check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' ) ) + $comment['akismet_comment_nonce'] = 'passed'; + + } + + if ( akismet_test_mode() ) + $comment['is_test'] = 'true'; + + foreach ($_POST as $key => $value ) { + if ( is_string($value) ) + $comment["POST_{$key}"] = $value; + } + + $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' ); + + foreach ( $_SERVER as $key => $value ) { + if ( !in_array( $key, $ignore ) && is_string($value) ) + $comment["$key"] = $value; + else + $comment["$key"] = ''; + } + + $query_string = ''; + foreach ( $comment as $key => $data ) + $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&'; + + $commentdata['comment_as_submitted'] = $comment; + + $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port); + $commentdata['akismet_result'] = $response[1]; + if ( 'true' == $response[1] ) { + // akismet_spam_count will be incremented later by akismet_result_spam() + add_filter('pre_comment_approved', 'akismet_result_spam'); + + do_action( 'akismet_spam_caught' ); + + $post = get_post( $comment['comment_post_ID'] ); + $last_updated = strtotime( $post->post_modified_gmt ); + $diff = time() - $last_updated; + $diff = $diff / 86400; + + if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' && empty($comment['user_ID']) ) { + // akismet_result_spam() won't be called so bump the counter here + if ( $incr = apply_filters('akismet_spam_count_incr', 1) ) + update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr ); + wp_redirect( $_SERVER['HTTP_REFERER'] ); + die(); + } + } + + // if the response is neither true nor false, hold the comment for moderation and schedule a recheck + if ( 'true' != $response[1] && 'false' != $response[1] ) { + add_filter('pre_comment_approved', 'akismet_result_hold'); + wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' ); + } + + if ( function_exists('wp_next_scheduled') && function_exists('wp_schedule_event') ) { + // WP 2.1+: delete old comments daily + if ( !wp_next_scheduled('akismet_scheduled_delete') ) + wp_schedule_event(time(), 'daily', 'akismet_scheduled_delete'); + } elseif ( (mt_rand(1, 10) == 3) ) { + // WP 2.0: run this one time in ten + akismet_delete_old(); + } + $akismet_last_comment = $commentdata; + return $commentdata; +} + +add_action('preprocess_comment', 'akismet_auto_check_comment', 1); + +function akismet_delete_old() { + global $wpdb; + $now_gmt = current_time('mysql', 1); + $comment_ids = $wpdb->get_col("SELECT comment_id FROM $wpdb->comments WHERE DATE_SUB('$now_gmt', INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam'"); + if ( empty( $comment_ids ) ) + return; + + $comma_comment_ids = implode( ', ', array_map('intval', $comment_ids) ); + + do_action( 'delete_comment', $comment_ids ); + $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_id IN ( $comma_comment_ids )"); + $wpdb->query("DELETE FROM $wpdb->commentmeta WHERE comment_id IN ( $comma_comment_ids )"); + clean_comment_cache( $comment_ids ); + $n = mt_rand(1, 5000); + if ( apply_filters('akismet_optimize_table', ($n == 11)) ) // lucky number + $wpdb->query("OPTIMIZE TABLE $wpdb->comments"); + +} + +add_action('akismet_scheduled_delete', 'akismet_delete_old'); + +function akismet_check_db_comment( $id, $recheck_reason = 'recheck_queue' ) { + global $wpdb, $akismet_api_host, $akismet_api_port; + + $id = (int) $id; + $c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A ); + if ( !$c ) + return; + + $c['user_ip'] = $c['comment_author_IP']; + $c['user_agent'] = $c['comment_agent']; + $c['referrer'] = ''; + $c['blog'] = get_option('home'); + $c['blog_lang'] = get_locale(); + $c['blog_charset'] = get_option('blog_charset'); + $c['permalink'] = get_permalink($c['comment_post_ID']); + $id = $c['comment_ID']; + if ( akismet_test_mode() ) + $c['is_test'] = 'true'; + $c['recheck_reason'] = $recheck_reason; + + $query_string = ''; + foreach ( $c as $key => $data ) + $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&'; + + $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port); + return $response[1]; +} + +function akismet_cron_recheck() { + global $wpdb; + + delete_option('akismet_available_servers'); + + $comment_errors = $wpdb->get_col( " + SELECT comment_id + FROM {$wpdb->prefix}commentmeta + WHERE meta_key = 'akismet_error' + LIMIT 100 + " ); + + foreach ( (array) $comment_errors as $comment_id ) { + // if the comment no longer exists, remove the meta entry from the queue to avoid getting stuck + if ( !get_comment( $comment_id ) ) { + delete_comment_meta( $comment_id, 'akismet_error' ); + continue; + } + + add_comment_meta( $comment_id, 'akismet_rechecking', true ); + $status = akismet_check_db_comment( $comment_id, 'retry' ); + + $msg = ''; + if ( $status == 'true' ) { + $msg = __( 'Akismet caught this comment as spam during an automatic retry.' ); + } elseif ( $status == 'false' ) { + $msg = __( 'Akismet cleared this comment during an automatic retry.' ); + } + + // If we got back a legit response then update the comment history + // other wise just bail now and try again later. No point in + // re-trying all the comments once we hit one failure. + if ( !empty( $msg ) ) { + delete_comment_meta( $comment_id, 'akismet_error' ); + akismet_update_comment_history( $comment_id, $msg, 'cron-retry' ); + update_comment_meta( $comment_id, 'akismet_result', $status ); + // make sure the comment status is still pending. if it isn't, that means the user has already moved it elsewhere. + $comment = get_comment( $comment_id ); + if ( $comment && 'unapproved' == wp_get_comment_status( $comment_id ) ) { + if ( $status == 'true' ) { + wp_spam_comment( $comment_id ); + } elseif ( $status == 'false' ) { + // comment is good, but it's still in the pending queue. depending on the moderation settings + // we may need to change it to approved. + if ( check_comment($comment->comment_author, $comment->comment_author_email, $comment->comment_author_url, $comment->comment_content, $comment->comment_author_IP, $comment->comment_agent, $comment->comment_type) ) + wp_set_comment_status( $comment_id, 1 ); + } + } + } else { + delete_comment_meta( $comment_id, 'akismet_rechecking' ); + wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' ); + return; + } + } + + $remaining = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) ); + if ( $remaining && !wp_next_scheduled('akismet_schedule_cron_recheck') ) { + wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' ); + } +} +add_action( 'akismet_schedule_cron_recheck', 'akismet_cron_recheck' ); + +function akismet_add_comment_nonce( $post_id ) { + echo '

    '; + wp_nonce_field( 'akismet_comment_nonce_' . $post_id, 'akismet_comment_nonce', FALSE ); + echo '

    '; +} + +$akismet_comment_nonce_option = apply_filters( 'akismet_comment_nonce', get_option( 'akismet_comment_nonce' ) ); + +if ( $akismet_comment_nonce_option == 'true' || $akismet_comment_nonce_option == '' ) + add_action( 'comment_form', 'akismet_add_comment_nonce' ); + +if ( '3.0.5' == $wp_version ) { + remove_filter( 'comment_text', 'wp_kses_data' ); + if ( is_admin() ) + add_filter( 'comment_text', 'wp_kses_post' ); +} diff --git a/src/wp-content/plugins/akismet/legacy.php b/src/wp-content/plugins/akismet/legacy.php new file mode 100644 index 00000000..d5d53b08 --- /dev/null +++ b/src/wp-content/plugins/akismet/legacy.php @@ -0,0 +1,396 @@ +escape( $type ); + return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type' ORDER BY comment_date DESC LIMIT $start, $end"); + } + + // All + return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end"); +} + +// Totals for each comment type +// returns array( type => count, ... ) +function akismet_spam_totals() { + global $wpdb; + $totals = $wpdb->get_results( "SELECT comment_type, COUNT(*) AS cc FROM $wpdb->comments WHERE comment_approved = 'spam' GROUP BY comment_type" ); + $return = array(); + foreach ( $totals as $total ) + $return[$total->comment_type ? $total->comment_type : 'comment'] = $total->cc; + return $return; +} + +function akismet_manage_page() { + global $wpdb, $submenu, $wp_db_version; + + // WP 2.7 has its own spam management page + if ( 8645 <= $wp_db_version ) + return; + + $count = sprintf(__('Akismet Spam (%s)'), akismet_spam_count()); + if ( isset( $submenu['edit-comments.php'] ) ) + add_submenu_page('edit-comments.php', __('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught' ); + elseif ( function_exists('add_management_page') ) + add_management_page(__('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught'); +} + +function akismet_caught() { + global $wpdb, $comment, $akismet_caught, $akismet_nonce; + + akismet_recheck_queue(); + if (isset($_POST['submit']) && 'recover' == $_POST['action'] && ! empty($_POST['not_spam'])) { + check_admin_referer( $akismet_nonce ); + if ( function_exists('current_user_can') && !current_user_can('moderate_comments') ) + die(__('You do not have sufficient permission to moderate comments.')); + + $i = 0; + foreach ($_POST['not_spam'] as $comment): + $comment = (int) $comment; + if ( function_exists('wp_set_comment_status') ) + wp_set_comment_status($comment, 'approve'); + else + $wpdb->query("UPDATE $wpdb->comments SET comment_approved = '1' WHERE comment_ID = '$comment'"); + akismet_submit_nonspam_comment($comment); + ++$i; + endforeach; + $to = add_query_arg( 'recovered', $i, $_SERVER['HTTP_REFERER'] ); + wp_redirect( $to ); + exit; + } + if ('delete' == $_POST['action']) { + check_admin_referer( $akismet_nonce ); + if ( function_exists('current_user_can') && !current_user_can('moderate_comments') ) + die(__('You do not have sufficient permission to moderate comments.')); + + $delete_time = $wpdb->escape( $_POST['display_time'] ); + $comment_ids = $wpdb->get_col( "SELECT comment_id FROM $wpdb->comments WHERE comment_approved = 'spam' AND '$delete_time' > comment_date_gmt" ); + if ( !empty( $comment_ids ) ) { + do_action( 'delete_comment', $comment_ids ); + $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_id IN ( " . implode( ', ', $comment_ids ) . " )"); + wp_cache_delete( 'akismet_spam_count', 'widget' ); + } + $to = add_query_arg( 'deleted', 'all', $_SERVER['HTTP_REFERER'] ); + wp_redirect( $to ); + exit; + } + +if ( isset( $_GET['recovered'] ) ) { + $i = (int) $_GET['recovered']; + echo '

    ' . sprintf(__('%1$s comments recovered.'), $i) . "

    "; +} + +if (isset( $_GET['deleted'] ) ) + echo '

    ' . __('All spam deleted.') . '

    '; + +if ( isset( $GLOBALS['submenu']['edit-comments.php'] ) ) + $link = 'edit-comments.php'; +else + $link = 'edit.php'; +?> + +
    +

    + +

    %1$s spam for you since you first installed it.'), number_format_i18n($count) ); ?>

    +'.__('You have no spam currently in the queue. Must be your lucky day. :)').'

    '; + echo '
    '; +} else { + echo '

    '.__('You can delete all of the spam from your database with a single click. This operation cannot be undone, so you may wish to check to ensure that no legitimate comments got through first. Spam is automatically deleted after 15 days, so don’t sweat it.').'

    '; +?> + +
    + + +    + +
    + +
    +
    + +

    + +'.__('These are the latest comments identified as spam by Akismet. If you see any mistakes, simply mark the comment as "not spam" and Akismet will learn from the submission. If you wish to recover a comment from spam, simply select the comment, and click Not Spam. After 15 days we clean out the junk for you.').'

    '; ?> + +escape($_POST['s']); + $comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE + (comment_author LIKE '%$s%' OR + comment_author_email LIKE '%$s%' OR + comment_author_url LIKE ('%$s%') OR + comment_author_IP LIKE ('%$s%') OR + comment_content LIKE ('%$s%') ) AND + comment_approved = 'spam' + ORDER BY comment_date DESC"); +} else { + if ( isset( $_GET['apage'] ) ) + $page = (int) $_GET['apage']; + else + $page = 1; + + if ( $page < 2 ) + $page = 1; + + $current_type = false; + if ( isset( $_GET['ctype'] ) ) + $current_type = preg_replace( '|[^a-z]|', '', $_GET['ctype'] ); + + $comments = akismet_spam_comments( $current_type, $page ); + $total = akismet_spam_count( $current_type ); + $totals = akismet_spam_totals(); +?> +
      +
    • >
    • + $type_count ) { + if ( 'comment' == $type ) { + $type = 'comments'; + $show = __('Comments'); + } else { + $show = ucwords( $type ); + } + $type_count = number_format_i18n( $type_count ); + $extra = $current_type === $type ? ' class="active"' : ''; + echo "
    • $show ($type_count)
    • "; +} +do_action( 'akismet_tabs' ); // so plugins can add more tabs easily +?> +
    + +
    " id="akismetsearch"> +

    +

    +
    + 50 ) { +$total_pages = ceil( $total / 50 ); +$r = ''; +if ( 1 < $page ) { + $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1; + $r .= '' . "\n"; +} +if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) { + for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) : + if ( $page == $page_num ) : + $r .= "$page_num\n"; + else : + $p = false; + if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) : + $args['apage'] = ( 1 == $page_num ) ? '' : $page_num; + $r .= '' . ( $page_num ) . "\n"; + $in = true; + elseif ( $in == true ) : + $r .= "...\n"; + $in = false; + endif; + endif; + endfor; +} +if ( ( $page ) * 50 < $total || -1 == $total ) { + $args['apage'] = $page + 1; + $r .= '' . "\n"; +} +echo "

    $r

    "; +?> + + +
    + + +
      +comment_date); + $post = get_post($comment->comment_post_ID); + $post_title = $post->post_title; + if ($i % 2) $class = 'class="alternate"'; + else $class = ''; + echo "\n\t
    • "; + ?> + +

      comment_author_email) { ?>| comment_author_url && 'http://' != $comment->comment_author_url) { ?> | |

      + + + +

      — [ +comment_post_ID); +$post_title = wp_specialchars( $post->post_title, 'double' ); +$post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title; +?> + ]

      + + + +
    + 50 ) { +$total_pages = ceil( $total / 50 ); +$r = ''; +if ( 1 < $page ) { + $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1; + $r .= '' . "\n"; +} +if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) { + for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) : + if ( $page == $page_num ) : + $r .= "$page_num\n"; + else : + $p = false; + if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) : + $args['apage'] = ( 1 == $page_num ) ? '' : $page_num; + $r .= '' . ( $page_num ) . "\n"; + $in = true; + elseif ( $in == true ) : + $r .= "...\n"; + $in = false; + endif; + endif; + endfor; +} +if ( ( $page ) * 50 < $total || -1 == $total ) { + $args['apage'] = $page + 1; + $r .= '' . "\n"; +} +echo "

    $r

    "; +} +?> +

    + +

    +

    +
    + +

    + + + +
    + +

    +    +

    +
    + +
    +" . __('Recheck Queue for Spam') . ""; + $page = str_replace( '
    ', '
    ' . $button, $page ); + return $page; + } + + if ( $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" ) ) + ob_start( 'akismet_recheck_button' ); +} + +// This option causes tons of FPs, was removed in 2.1 +function akismet_kill_proxy_check( $option ) { return 0; } +add_filter('option_open_proxy_check', 'akismet_kill_proxy_check'); diff --git a/src/wp-content/plugins/akismet/readme.txt b/src/wp-content/plugins/akismet/readme.txt new file mode 100644 index 00000000..fbd3513b --- /dev/null +++ b/src/wp-content/plugins/akismet/readme.txt @@ -0,0 +1,130 @@ +=== Akismet === +Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, automattic +Tags: akismet, comments, spam +Requires at least: 3.0 +Tested up to: 3.1 +Stable tag: 2.5.3 +License: GPLv2 or later + +Akismet checks your comments against the Akismet web service to see if they look like spam or not. + +== Description == + +Akismet checks your comments against the Akismet web service to see if they look like spam or not and lets you +review the spam it catches under your blog's "Comments" admin screen. + +Major new features in Akismet 2.5 include: + +* A comment status history, so you can easily see which comments were caught or cleared by Akismet, and which were spammed or unspammed by a moderator +* Links are highlighted in the comment body, to reveal hidden or misleading links +* If your web host is unable to reach Akismet's servers, the plugin will automatically retry when your connection is back up +* Moderators can see the number of approved comments for each user +* Spam and Unspam reports now include more information, to help improve accuracy + +PS: You'll need an [Akismet.com API key](http://akismet.com/get/) to use it. Keys are free for personal blogs, with paid subscriptions available for businesses and commercial sites. + +== Installation == + +Upload the Akismet plugin to your blog, Activate it, then enter your [Akismet.com API key](http://akismet.com/get/). + +1, 2, 3: You're done! + +== Changelog == + += 2.5.3 = +* Specify the license is GPL v2 or later +* Fix a bug that could result in orphaned commentmeta entries +* Include hotfix for WordPress 3.0.5 filter issue + += 2.5.2 = + +* Properly format the comment count for author counts +* Look for super admins on multisite installs when looking up user roles +* Increase the HTTP request timeout +* Removed padding for author approved count +* Fix typo in function name +* Set Akismet stats iframe height to fixed 2500px. Better to have one tall scroll bar than two side by side. + += 2.5.1 = + +* Fix a bug that caused the "Auto delete" option to fail to discard comments correctly +* Remove the comment nonce form field from the 'Akismet Configuration' page in favor of using a filter, akismet_comment_nonce +* Fixed padding bug in "author" column of posts screen +* Added margin-top to "cleared by ..." badges on dashboard +* Fix possible error when calling akismet_cron_recheck() +* Fix more PHP warnings +* Clean up XHTML warnings for comment nonce +* Fix for possible condition where scheduled comment re-checks could get stuck +* Clean up the comment meta details after deleting a comment +* Only show the status badge if the comment status has been changed by someone/something other than Akismet +* Show a 'History' link in the row-actions +* Translation fixes +* Reduced font-size on author name +* Moved "flagged by..." notification to top right corner of comment container and removed heavy styling +* Hid "flagged by..." notification while on dashboard + += 2.5.0 = + +* Track comment actions under 'Akismet Status' on the edit comment screen +* Fix a few remaining deprecated function calls ( props Mike Glendinning ) +* Use HTTPS for the stats IFRAME when wp-admin is using HTTPS +* Use the WordPress HTTP class if available +* Move the admin UI code to a separate file, only loaded when needed +* Add cron retry feature, to replace the old connectivity check +* Display Akismet status badge beside each comment +* Record history for each comment, and display it on the edit page +* Record the complete comment as originally submitted in comment_meta, to use when reporting spam and ham +* Highlight links in comment content +* New option, "Show the number of comments you've approved beside each comment author." +* New option, "Use a nonce on the comment form." + += 2.4.0 = + +* Spell out that the license is GPLv2 +* Fix PHP warnings +* Fix WordPress deprecated function calls +* Fire the delete_comment action when deleting comments +* Move code specific for older WP versions to legacy.php +* General code clean up + += 2.3.0 = + +* Fix "Are you sure" nonce message on config screen in WPMU +* Fix XHTML compliance issue in sidebar widget +* Change author link; remove some old references to WordPress.com accounts +* Localize the widget title (core ticket #13879) + += 2.2.9 = + +* Eliminate a potential conflict with some plugins that may cause spurious reports + += 2.2.8 = + +* Fix bug in initial comment check for ipv6 addresses +* Report comments as ham when they are moved from spam to moderation +* Report comments as ham when clicking undo after spam +* Use transition_comment_status action when available instead of older actions for spam/ham submissions +* Better diagnostic messages when PHP network functions are unavailable +* Better handling of comments by logged-in users + += 2.2.7 = + +* Add a new AKISMET_VERSION constant +* Reduce the possibility of over-counting spam when another spam filter plugin is in use +* Disable the connectivity check when the API key is hard-coded for WPMU + += 2.2.6 = + +* Fix a global warning introduced in 2.2.5 +* Add changelog and additional readme.txt tags +* Fix an array conversion warning in some versions of PHP +* Support a new WPCOM_API_KEY constant for easier use with WordPress MU + += 2.2.5 = + +* Include a new Server Connectivity diagnostic check, to detect problems caused by firewalls + += 2.2.4 = + +* Fixed a key problem affecting the stats feature in WordPress MU +* Provide additional blog information in Akismet API calls diff --git a/src/wp-content/plugins/akismet/widget.php b/src/wp-content/plugins/akismet/widget.php new file mode 100644 index 00000000..e9a3f626 --- /dev/null +++ b/src/wp-content/plugins/akismet/widget.php @@ -0,0 +1,90 @@ + + + + + + + + +

    + + + +
    ', '', $count ), number_format_i18n( $count ) ); +} diff --git a/src/wp-content/plugins/hello.php b/src/wp-content/plugins/hello.php new file mode 100644 index 00000000..d2287e24 --- /dev/null +++ b/src/wp-content/plugins/hello.php @@ -0,0 +1,82 @@ +Hello, Dolly in the upper right of your admin screen on every page. +Author: Matt Mullenweg +Version: 1.6 +Author URI: http://ma.tt/ +*/ + +function hello_dolly_get_lyric() { + /** These are the lyrics to Hello Dolly */ + $lyrics = "Hello, Dolly +Well, hello, Dolly +It's so nice to have you back where you belong +You're lookin' swell, Dolly +I can tell, Dolly +You're still glowin', you're still crowin' +You're still goin' strong +We feel the room swayin' +While the band's playin' +One of your old favourite songs from way back when +So, take her wrap, fellas +Find her an empty lap, fellas +Dolly'll never go away again +Hello, Dolly +Well, hello, Dolly +It's so nice to have you back where you belong +You're lookin' swell, Dolly +I can tell, Dolly +You're still glowin', you're still crowin' +You're still goin' strong +We feel the room swayin' +While the band's playin' +One of your old favourite songs from way back when +Golly, gee, fellas +Find her a vacant knee, fellas +Dolly'll never go away +Dolly'll never go away +Dolly'll never go away again"; + + // Here we split it into lines + $lyrics = explode( "\n", $lyrics ); + + // And then randomly choose a line + return wptexturize( $lyrics[ mt_rand( 0, count( $lyrics ) - 1 ) ] ); +} + +// This just echoes the chosen line, we'll position it later +function hello_dolly() { + $chosen = hello_dolly_get_lyric(); + echo "

    $chosen

    "; +} + +// Now we set that function up to execute when the admin_notices action is called +add_action( 'admin_notices', 'hello_dolly' ); + +// We need some CSS to position the paragraph +function dolly_css() { + // This makes sure that the positioning is also good for right-to-left languages + $x = is_rtl() ? 'left' : 'right'; + + echo " + + "; +} + +add_action( 'admin_head', 'dolly_css' ); + +?> diff --git a/src/wp-content/plugins/index.php b/src/wp-content/plugins/index.php new file mode 100644 index 00000000..4e6c07c7 --- /dev/null +++ b/src/wp-content/plugins/index.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/ads/content_ad.php b/src/wp-content/themes/bloggingstream/ads/content_ad.php new file mode 100644 index 00000000..b1171793 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/ads/content_ad.php @@ -0,0 +1,13 @@ + + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/archive.php b/src/wp-content/themes/bloggingstream/archive.php new file mode 100644 index 00000000..0abc7e4f --- /dev/null +++ b/src/wp-content/themes/bloggingstream/archive.php @@ -0,0 +1,62 @@ + + +
    + +
    + + + '' + + + + + + + + + + + +
    + + + +

    + + + | + | + | + + + +
    + + + +
    + +
    + + + + + +
    + + + +
    + +
    + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/changelog.txt b/src/wp-content/themes/bloggingstream/changelog.txt new file mode 100644 index 00000000..fc60d55f --- /dev/null +++ b/src/wp-content/themes/bloggingstream/changelog.txt @@ -0,0 +1,131 @@ +*** Bloggingstream Changelog *** + +2011.05.24 - version 2.6 + * includes/sidebar-init.php - register new sidebars to work with SBM + * index.php + sidebar.php - changed ID in woo_sidebar() + +2010.05.19 - version 2.5.2 + * content_ad.php - changed adspace setting from disable to enable + * single.php added the content adspace + * theme-options.php - changed adspace setting from disable to enable + +2010.06.28 - version 2.5.1 + * style.css - Fixed Gravity forms styling bug + +2010.06.21 - version 2.5.0 + * header.php - Added theme support for WordPress 3.0 Menu Management + * /includes/theme-functions.php - Added theme support for WordPress 3.0 Menu Management + +2010.06.14 - version 2.4.2 + * style.css - Added styling for Gravity forms + +2010.05.17 - version 2.4.1 + * header.php - modified depth to be 6 + +2010.04.28 - version 2.4 + * header.php - added support for WooNav + +2010.04.21 - version 2.3 + * /functions/* - MAJOR UPDATE - Framework V.2.7.0 + * header.php - Added SEO tags, woo_title(); & woo_meta(); + * functions.php - Changed layout for loading required files. + * /includes/theme-widgets.php - Corrected video widget Tag input title + +2010.02.18 - version 2.2.1 + * /includes/theme-widgets.php - Made the video widget work from a TAG category and not a category. + +2010.01.23 - version 2.2 + * comments.php - fixed comments + * includes/theme-comments.php - fixed comments + * style.css - added new comment styling (bottom of file) + +2009.11.02 - version 2.1.1 + * header.php - fixed some minor validation errors + index.php + featured-layouts/large_no_ad.php + +2009.09.09 - version 2.1 + * /functions/* - Core Framework 1.0.9 + * /lang/bloggingstream.po - Added language file. See: http://www.woothemes.com/2009/08/how-to-translate-a-theme/ + * Added gettext functions to template php files to support localization. + +2009.08.10 - version 2.0.2 + * /functions/ - New WooThemes Framework (V1.0.5) + +2009.08.05 - version 2.0.1 + * single.php - Fixed syntax error + +2009.08.05 - version 2.0.0 + * /functions/ - New WooThemes Framework (V1.0.4) (core theme functions) + functions.php + * includes/theme-comments.php - Moved from /functions/ + includes/theme-functions.php + includes/theme-js.php + includes/theme-options.php + includes/theme-widgets.php + includes/sidebar-init.php + * includes/theme-options.php - Added new general & dynamic images options + * header.php - Fixed checkbox options ( $var == 'true' instead of just $var ) + /ads/content_ad.php + archive.php + /featured-layouts/large_no_ad.php + /featured-layouts/small_with_ad.php + index.php + sidebar.php + single.php + +2009.04.25 - version 1.0.5 + * header.php - Include pngfix.js, re-code logo + * style.css - Re-code logo + * /img/ - Added logo.png + * /functions/admin-setup.php - Remove 'custom_logo' function + * /includes/js/ - Added pngfix.js + * /styles/baby_blue/ - Deleted logo.jpg + * /styles/blue/ - Deleted logo.jpg + * /styles/chocolate/ - Deleted logo.jpg + * /styles/default/ - Deleted logo.jpg + * /styles/green/ - Deleted logo.jpg + * /styles/grey/ - Deleted logo.jpg + * /styles/purple/ - Deleted logo.jpg + * /styles/red/ - Deleted logo.jpg + * /styles/rust/ - Deleted logo.jpg + * /styles/baby_blue.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/blue.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/chocolate.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/default.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/green.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/grey.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/purple.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/red.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + * /styles/rust.css - Removed '#header h1 a:link, #header h1 a:visited' selector. + +2009.04.20 - version 1.0.4 + * functions/admin-setup.php - Updated WP-PageNavi code + * style.css - Updated WP-Pagenavi styling + * styles/chocolate.css - Updated WP-Pagenavi styling + * styles/default.css - Updated WP-Pagenavi styling + * styles/green.css - Updated WP-Pagenavi styling + * styles/grey.css - Updated WP-Pagenavi styling + * styles/purple.css - Updated WP-Pagenavi styling + * styles/red.css - Updated WP-Pagenavi styling + * styles/rust.css - Updated WP-Pagenavi styling + * styles/baby_blue.css - Updated WP-Pagenavi styling + * styles/blue.css - Updated WP-Pagenavi styling + +2009.04.15 - version 1.0.3 + * includes/js/general.js - Changed all '$' to 'jQuery' + * style.css - Restructured drop-downs + * ie7.css - Removed drop-down hacks + * ie6.css - Removed drop-down hacks + +2009.04.15 - version 1.0.2 + * ie7.css - added styles to fix IE7 drop-down bug + +2009.04.15 - version 1.0.1 + * functions.php - added function to load default.css if no stylesheet has been set + * custom.css - added custom.css + * style.css - added @import for custom.css + +2009.04.14 - version 1.0.0 + * First release! \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/comments-legacy.php b/src/wp-content/themes/bloggingstream/comments-legacy.php new file mode 100644 index 00000000..51ffe8fc --- /dev/null +++ b/src/wp-content/themes/bloggingstream/comments-legacy.php @@ -0,0 +1,138 @@ +post_password)) { // if there's a password + if ($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) { // and it doesn't match the cookie + ?> + +

    + + + + + + + +

    + + + +
      + + + +
    1. + +
      + + comment_approved == '0') : ?> +

      + +
      +
      + <?php //_e('Gravatar'); ?> +
      +
      +


      +
      + +
    2. + + + + + +
    + +
    + + + + comment_status) : ?> + + + + + + + + + + +comment_status) : ?> + +
    +
    + + + + +

    .

    + + +
    + + + +

    .

    + +
    + +
    + +
    +

    +
    + + +
    + +
    + +
    + +

    + + +

    + +

    + + +

    + +

    + + +

    + +

    + +
    + + + + + +ID); ?> + +
    + + + + + +
    +
    +
    \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/comments.php b/src/wp-content/themes/bloggingstream/comments.php new file mode 100644 index 00000000..0871230f --- /dev/null +++ b/src/wp-content/themes/bloggingstream/comments.php @@ -0,0 +1,123 @@ + +

    + + + + + + + +
    + + + + + + + +
      + + + +
    + + + + + + +

    + +
      + +
    + + + + + + comment_status) : ?> + +

    + + + +

    + + + + + +
    + +comment_status) : ?> + +
    + + + +
    + +
    + + + +

    + + + +
    + + + +

    . »

    + + + +

    + + +

    + +

    + + +

    + +

    + + +

    + + + + + +

    + + + + + + ID); ?> + +
    + + + +
    + +
    + + diff --git a/src/wp-content/themes/bloggingstream/css/960.css b/src/wp-content/themes/bloggingstream/css/960.css new file mode 100644 index 00000000..6db1bd34 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/css/960.css @@ -0,0 +1,491 @@ +/* + 960 Grid System ~ Core CSS. + Learn more ~ http://960.gs/ + + Licensed under GPL and MIT. +*/ + +/* =Containers +--------------------------------------------------------------------------------*/ + +.container_12, +.container_16 +{ + margin-left: auto; + margin-right: auto; + width: 960px; +} + +/* =Grid >> Global +--------------------------------------------------------------------------------*/ + +.grid_1, +.grid_2, +.grid_3, +.grid_4, +.grid_5, +.grid_6, +.grid_7, +.grid_8, +.grid_9, +.grid_10, +.grid_11, +.grid_12, +.grid_13, +.grid_14, +.grid_15, +.grid_16 +{ + display: inline; + float: left; + margin-left: 10px; + margin-right: 10px; +} + +.container_12 .grid_3, +.container_16 .grid_4 +{ + width: 220px; +} + +.container_12 .grid_6, +.container_16 .grid_8 +{ + width: 460px; +} + +.container_12 .grid_9, +.container_16 .grid_12 +{ + width: 700px; +} + +.container_12 .grid_12, +.container_16 .grid_16 +{ + width: 940px; +} + +/* =Grid >> Children (Alpha ~ First, Omega ~ Last) +--------------------------------------------------------------------------------*/ + +.alpha +{ + margin-left: 0; +} + +.omega +{ + margin-right: 0; +} + +/* =Grid >> 12 Columns +--------------------------------------------------------------------------------*/ + +.container_12 .grid_1 +{ + width: 60px; +} + +.container_12 .grid_2 +{ + width: 140px; +} + +.container_12 .grid_4 +{ + width: 300px; +} + +.container_12 .grid_5 +{ + width: 380px; +} + +.container_12 .grid_7 +{ + width: 540px; +} + +.container_12 .grid_8 +{ + width: 620px; +} + +.container_12 .grid_10 +{ + width: 780px; +} + +.container_12 .grid_11 +{ + width: 860px; +} + +/* =Grid >> 16 Columns +--------------------------------------------------------------------------------*/ + +.container_16 .grid_1 +{ + width: 40px; +} + +.container_16 .grid_2 +{ + width: 100px; +} + +.container_16 .grid_3 +{ + width: 160px; +} + +.container_16 .grid_5 +{ + width: 280px; +} + +.container_16 .grid_6 +{ + width: 340px; +} + +.container_16 .grid_7 +{ + width: 400px; +} + +.container_16 .grid_9 +{ + width: 520px; +} + +.container_16 .grid_10 +{ + width: 580px; +} + +.container_16 .grid_11 +{ + width: 640px; +} + +.container_16 .grid_13 +{ + width: 760px; +} + +.container_16 .grid_14 +{ + width: 820px; +} + +.container_16 .grid_15 +{ + width: 880px; +} + +/* =Prefix Extra Space >> Global +--------------------------------------------------------------------------------*/ + +.container_12 .prefix_3, +.container_16 .prefix_4 +{ + padding-left: 240px; +} + +.container_12 .prefix_6, +.container_16 .prefix_8 +{ + padding-left: 480px; +} + +.container_12 .prefix_9, +.container_16 .prefix_12 +{ + padding-left: 720px; +} + +/* =Prefix Extra Space >> 12 Columns +--------------------------------------------------------------------------------*/ + +.container_12 .prefix_1 +{ + padding-left: 80px; +} + +.container_12 .prefix_2 +{ + padding-left: 160px; +} + +.container_12 .prefix_4 +{ + padding-left: 320px; +} + +.container_12 .prefix_5 +{ + padding-left: 400px; +} + +.container_12 .prefix_7 +{ + padding-left: 560px; +} + +.container_12 .prefix_8 +{ + padding-left: 640px; +} + +.container_12 .prefix_10 +{ + padding-left: 800px; +} + +.container_12 .prefix_11 +{ + padding-left: 880px; +} + +/* =Prefix Extra Space >> 16 Columns +--------------------------------------------------------------------------------*/ + +.container_16 .prefix_1 +{ + padding-left: 60px; +} + +.container_16 .prefix_2 +{ + padding-left: 120px; +} + +.container_16 .prefix_3 +{ + padding-left: 180px; +} + +.container_16 .prefix_5 +{ + padding-left: 300px; +} + +.container_16 .prefix_6 +{ + padding-left: 360px; +} + +.container_16 .prefix_7 +{ + padding-left: 420px; +} + +.container_16 .prefix_9 +{ + padding-left: 540px; +} + +.container_16 .prefix_10 +{ + padding-left: 600px; +} + +.container_16 .prefix_11 +{ + padding-left: 660px; +} + +.container_16 .prefix_13 +{ + padding-left: 780px; +} + +.container_16 .prefix_14 +{ + padding-left: 840px; +} + +.container_16 .prefix_15 +{ + padding-left: 900px; +} + +/* =Suffix Extra Space >> Global +--------------------------------------------------------------------------------*/ + +.container_12 .suffix_3, +.container_16 .suffix_4 +{ + padding-right: 240px; +} + +.container_12 .suffix_6, +.container_16 .suffix_8 +{ + padding-right: 480px; +} + +.container_12 .suffix_9, +.container_16 .suffix_12 +{ + padding-right: 720px; +} + +/* =Suffix Extra Space >> 12 Columns +--------------------------------------------------------------------------------*/ + +.container_12 .suffix_1 +{ + padding-right: 80px; +} + +.container_12 .suffix_2 +{ + padding-right: 160px; +} + +.container_12 .suffix_4 +{ + padding-right: 320px; +} + +.container_12 .suffix_5 +{ + padding-right: 400px; +} + +.container_12 .suffix_7 +{ + padding-right: 560px; +} + +.container_12 .suffix_8 +{ + padding-right: 640px; +} + +.container_12 .suffix_10 +{ + padding-right: 800px; +} + +.container_12 .suffix_11 +{ + padding-right: 880px; +} + +/* =Suffix Extra Space >> 16 Columns +--------------------------------------------------------------------------------*/ + +.container_16 .suffix_1 +{ + padding-right: 60px; +} + +.container_16 .suffix_2 +{ + padding-right: 120px; +} + +.container_16 .suffix_3 +{ + padding-right: 180px; +} + +.container_16 .suffix_5 +{ + padding-right: 300px; +} + +.container_16 .suffix_6 +{ + padding-right: 360px; +} + +.container_16 .suffix_7 +{ + padding-right: 420px; +} + +.container_16 .suffix_9 +{ + padding-right: 540px; +} + +.container_16 .suffix_10 +{ + padding-right: 600px; +} + +.container_16 .suffix_11 +{ + padding-right: 660px; +} + +.container_16 .suffix_13 +{ + padding-right: 780px; +} + +.container_16 .suffix_14 +{ + padding-right: 840px; +} + +.container_16 .suffix_15 +{ + padding-right: 900px; +} + +/* =Clear Floated Elements +--------------------------------------------------------------------------------*/ + +/* http://sonspring.com/journal/clearing-floats */ + +html body * span.clear, +html body * div.clear, +html body * li.clear, +html body * dd.clear +{ + background: none; + border: 0; + clear: both; + display: block; + float: none; + font-size: 0; + list-style: none; + margin: 0; + padding: 0; + overflow: hidden; + visibility: hidden; + width: 0; + height: 0; +} + +/* http://www.positioniseverything.net/easyclearing.html */ + +.clearfix:after +{ + clear: both; + content: '.'; + display: block; + visibility: hidden; + height: 0; +} + +.clearfix +{ + display: inline-block; +} + +* html .clearfix +{ + height: 1%; +} + +.clearfix +{ + display: block; +} \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/css/reset.css b/src/wp-content/themes/bloggingstream/css/reset.css new file mode 100644 index 00000000..13f8e0a1 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/css/reset.css @@ -0,0 +1,53 @@ +/* http://meyerweb.com/eric/tools/css/reset/ */ +/* v1.0 | 20080212 */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} + +/* remember to define focus styles! */ +:focus { + outline: 0; +} + +/* remember to highlight inserts somehow! */ +ins { + text-decoration: none; +} +del { + text-decoration: line-through; +} + +/* tables still need 'cellspacing="0"' in the markup */ +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/custom.css b/src/wp-content/themes/bloggingstream/custom.css new file mode 100644 index 00000000..945ec201 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/custom.css @@ -0,0 +1,13 @@ +/* +WOO CUSTOM STYLESHEET +--------------------- + +Instructions: + +Add your custom styles here instead of style.css so it +is easier to update the theme. Simply copy an existing +style from style.css to this file, and modify it to +your liking. + +*/ + diff --git a/src/wp-content/themes/bloggingstream/featured-layouts/large_no_ad.php b/src/wp-content/themes/bloggingstream/featured-layouts/large_no_ad.php new file mode 100644 index 00000000..cecf25f8 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/featured-layouts/large_no_ad.php @@ -0,0 +1,14 @@ +
    + +
    + +
    + +
    +

    + Posted | + + Read more → +
    + +
    \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/featured-layouts/small_with_ad.php b/src/wp-content/themes/bloggingstream/featured-layouts/small_with_ad.php new file mode 100644 index 00000000..15086986 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/featured-layouts/small_with_ad.php @@ -0,0 +1,28 @@ +
    + +
    +

    + Posted
    +
    + + + +
    + +
    + +
    + +
    + + "") { echo stripslashes(get_option('woo_ad_block_adsense')); ?> + + + + advert + + + +
    \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/footer.php b/src/wp-content/themes/bloggingstream/footer.php new file mode 100644 index 00000000..c354eb2d --- /dev/null +++ b/src/wp-content/themes/bloggingstream/footer.php @@ -0,0 +1,19 @@ + + +
    + + + + + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions.php b/src/wp-content/themes/bloggingstream/functions.php new file mode 100644 index 00000000..647f3503 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions.php @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-custom-nav.php b/src/wp-content/themes/bloggingstream/functions/admin-custom-nav.php new file mode 100644 index 00000000..fcc0b59a --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-custom-nav.php @@ -0,0 +1,2430 @@ + '') { + $nav_version_in_db = get_option( 'woo_settings_custom_nav_version' ); + } + else { + $nav_version_in_db = '0'; + } + + //Override for menu descriptions + update_option( 'woo_settings_custom_nav_advanced_options','yes' ); + + if (isset($_GET['page'])) { + $page_var = $_GET['page']; + } + else { + $page_var = ''; + } + + if ($page_var == 'custom_navigation') + { + + //CREATE Custom Menu tables + global $wpdb; + $table_name = $wpdb->prefix . "woo_custom_nav_records"; + $charset_collate = ''; + if ( ! empty($wpdb->charset) ) { + $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; + } + if ( ! empty($wpdb->collate) ) { + $charset_collate .= " COLLATE $wpdb->collate"; + } + + if(($wpdb->get_var( "show tables like '$table_name'") != $table_name) || ($nav_version_in_db <> $nav_version)) + { + + $sql = "CREATE TABLE " . $table_name . " ( + id mediumint(9) NOT NULL AUTO_INCREMENT, + position bigint(11) NOT NULL, + post_id bigint(11) NOT NULL, + parent_id bigint(11) NOT NULL, + custom_title text NOT NULL, + custom_link text NOT NULL, + custom_description text NOT NULL, + menu_icon text NOT NULL, + link_type varchar(55) NOT NULL default 'custom', + menu_id bigint(11) NOT NULL, + custom_anchor_title text NOT NULL, + new_window bigint(11) NOT NULL default 0, + UNIQUE KEY id (id) + ) ".$charset_collate.";"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php' ); + dbDelta($sql); + + update_option( 'woo_settings_custom_nav_version',$nav_version); + + } + + $table_name_menus = $wpdb->prefix . "woo_custom_nav_menus"; + + if(($wpdb->get_var( "show tables like '$table_name_menus'") != $table_name_menus) || ($nav_version_in_db <> $nav_version)) + { + $data_insert = false; + //CHECK if tables exist + if ($wpdb->get_var( "show tables like '$table_name_menus'") != $table_name_menus) { + $data_insert = true; + } + $sql = "CREATE TABLE " . $table_name_menus . " ( + id mediumint(9) NOT NULL AUTO_INCREMENT, + menu_name text NOT NULL, + UNIQUE KEY id (id) + ) ".$charset_collate.";"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php' ); + dbDelta($sql); + + //ADD data to tables + if ($data_insert) { + + //POPULATE with first menu + $insert = "INSERT INTO ".$table_name_menus." (menu_name) "."VALUES ( 'Woo Menu 1')"; + $results = $wpdb->query( $insert ); + + //POPULATE with first menu content + //Pages + $table_name = $wpdb->prefix . "woo_custom_nav_records"; + + //GET all current pages + $pages_args = array( + 'child_of' => 0, + 'sort_order' => 'ASC', + 'sort_column' => 'post_title', + 'hierarchical' => 1, + 'exclude' => '', + 'include' => '', + 'meta_key' => '', + 'meta_value' => '', + 'authors' => '', + 'parent' => 0, + 'exclude_tree' => '', + 'number' => '', + 'offset' => 0 ); + + $pages_array = get_pages($pages_args); + $counter = 1; + + //INSERT Loop + foreach ($pages_array as $post) + { + //CHECK if is top level element + if ($post->post_parent == 0) + { + //CHECK for existing page records + $table_name_parent = $wpdb->prefix . "woo_custom_nav_records"; + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name_parent." WHERE post_id='".$post->post_parent."' AND link_type='page' AND menu_id='1'" ); + + if ($woo_result > 0 && isset($woo_result[0]->id)) { + $parent_id = $woo_result[0]->id; + } + else { + $parent_id = 0; + } + + //INSERT page + //Convert string to UTF-8 + $str_converted = stripslashes($post->post_title); + //$insert_title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + //$insert = "INSERT INTO ".$table_name." (position,post_id,parent_id,custom_title,custom_link,custom_description,menu_icon,link_type,menu_id,custom_anchor_title) "."VALUES ( '".$counter."','".$post->ID."','".$parent_id."','".$insert_title."','".get_permalink($post->ID)."','','','page','1','".$insert_title."')"; + //$results = $wpdb->query( $insert ); + $results = $wpdb->insert( $table_name, array( 'position' => $counter, 'post_id' => $post->ID, 'parent_id' => $parent_id, 'custom_title' => $str_converted, 'custom_link' => get_permalink($post->ID), 'custom_description' => '', 'menu_icon' => '', 'link_type' => 'page', 'menu_id' => '1', 'custom_anchor_title' => $str_converted )); + + $counter++; + + //$counter = get_children_menu_elements($post->ID, $counter, $post->ID, 'pages',1,$table_name); + $counter = get_children_menu_elements($post->ID, $counter, $post->post_parent, 'pages',1,$table_name); + } + //Do nothing + else + { + + } + } + + //GET all current categories + $category_args = array( + 'type' => 'post', + 'child_of' => 0, + 'orderby' => 'name', + 'order' => 'ASC', + 'hide_empty' => false, + 'include_last_update_time' => false, + 'hierarchical' => 0, + 'parent' => 0, + 'depth' => 1, + 'exclude' => '', + 'include' => '', + 'number' => '', + 'pad_counts' => false ); + + + $categories_array = get_categories($category_args); + + //POPULATE with second menu + $insert = "INSERT INTO ".$table_name_menus." (menu_name) "."VALUES ( 'Woo Menu 2')"; + $results = $wpdb->query( $insert ); + + //POPULATE with second menu content + //GET all current pages + + $counter = 1; + + //GET all current categories + + //INSERT Loop + foreach ($categories_array as $cat_item) { + + //CHECK if is top level element + if ($cat_item->parent == 0) + { + //CHECK for existing category records + $table_name_parent = $wpdb->prefix . "woo_custom_nav_records"; + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name_parent." WHERE post_id='".$cat_item->parent."' AND link_type='category' AND menu_id='2'" ); + + if ($woo_result > 0 && isset($woo_result[0]->id)) { + $parent_id = $woo_result[0]->id; + } + else { + $parent_id = 0; + } + + //INSERT category + //Convert string to UTF-8 + $str_converted = stripslashes($cat_item->cat_name); + //$insert_title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + //$insert = "INSERT INTO ".$table_name." (position,post_id,parent_id,custom_title,custom_link,custom_description,menu_icon,link_type,menu_id) "."VALUES ( '".$counter."','".$cat_item->cat_ID."','".$parent_id."','".$insert_title."','".get_category_link($cat_item->cat_ID)."','','','category','2')"; + //$results = $wpdb->query( $insert ); + $results = $wpdb->insert( $table_name, array( 'position' => $counter, 'post_id' => $cat_item->cat_ID, 'parent_id' => $parent_id, 'custom_title' => $str_converted, 'custom_link' => get_category_link($cat_item->cat_ID), 'custom_description' => '', 'menu_icon' => '', 'link_type' => 'category', 'menu_id' => '2', 'custom_anchor_title' => $str_converted )); + + $counter++; + + $counter = get_children_menu_elements($cat_item->cat_ID, $counter, $cat_item->parent, 'categories',2,$table_name); + } + //Do nothing + else { + + } + } + } + + + + + } + + + + } + +} + +function woo_custom_nav_reset() { + + global $wpdb; + + $table_name = $wpdb->prefix . "woo_custom_nav_records"; + //DROP existing tables + $wpdb->query( "DROP TABLE ".$table_name); + + $table_name_menus = $wpdb->prefix . "woo_custom_nav_menus"; + //DELETE existing menus + $wpdb->query( "DROP TABLE ".$table_name_menus); + + woo_custom_navigation_setup(); + + return true; + +} + +function woo_custom_navigation_menu() { + + //Woothemes Custom Navigation Menu + $woopage = add_submenu_page( 'woothemes', 'Custom Navigation', 'Custom Navigation', 8, 'custom_navigation', 'woo_custom_navigation' ); + + add_action( "admin_print_scripts-$woopage", 'woo_custom_nav_scripts' ); + +} + +function woo_custom_nav_scripts() { + + //STYLES AND JAVASCRIPT + wp_enqueue_script( 'jquery' ); + wp_enqueue_script( 'jquery-ui-core' ); + wp_enqueue_script( 'jquery-ui-draggable' ); + wp_enqueue_script( 'jquery-ui-droppable' ); + wp_enqueue_script( 'jquery-ui-sortable' ); + wp_enqueue_script( 'jquery-ui-dialog' ); + wp_register_script( 'woo-nav-dynamic', get_template_directory_uri() . '/functions/js/custom_menu_dynamic_items.js', array( 'jquery-ui-dialog' )); + wp_enqueue_script( 'woo-nav-dynamic' ); + wp_register_script( 'woo-nav-initial', get_template_directory_uri() . '/functions/js/custom_menu_initial_items.js', array( 'jquery-ui-dialog' )); + wp_enqueue_script( 'woo-nav-initial' ); + wp_register_script( 'woo-nav-autocomplete', get_template_directory_uri() . '/functions/js/jquery.autocomplete.js', array( 'jquery' )); + wp_enqueue_script( 'woo-nav-autocomplete' ); + //Default Style + echo ''; + +} + + + +/*-----------------------------------------------------------------------------------*/ +/* Woothemes Custom Navigation Menu Interface +/* woo_custom_navigation() is the main function for the Custom Navigation +/* See functions in admin-functions.php +/*-----------------------------------------------------------------------------------*/ + +function woo_custom_navigation() { + global $wpdb; + ?> + +
    +

    You do not have JavaScript enabled in your browser. Please enabled it to access the Custom Menu functionality.

    + + prefix . "woo_custom_nav_menus"; + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name_menus." ORDER BY id ASC LIMIT 1" ); + if ($woo_result > 0 && isset($woo_result[0]->id)) { + $menu_selected_id = $woo_result[0]->id; + } + else { + $menu_selected_id = 1; + } + + + //CHECK which menu is selected and if menu is in edit already + if (isset($_POST['switch_menu'])) { + //echo $_POST['menu_select']; + $menu_selected_id = $_POST['menu_select']; + } + elseif (isset($_POST['menu_id_in_edit'])){ + $menu_selected_id = $_POST['menu_id_in_edit']; + } + else { + + } + + + if (isset($_POST['set_woo_menu'])) + { + update_option( 'woo_custom_nav_menu', $_POST['enable_woo_menu']); + $messagesdiv = '

    '.$themename.'\'s Custom Menu has been updated!

    '; + } + + + //CHECK for existing woo custom menu + $table_name = $wpdb->prefix . "woo_custom_nav_records"; + $custom_nav_exists = $wpdb->query( "SELECT id FROM ".$table_name." WHERE menu_id='".$menu_selected_id."'" ); + + if (isset($_POST['licount'])) { + $postCounter = $_POST['licount']; + } + else { + $postCounter = 0; + } + + if (isset($_POST['add_menu'])) { + + $table_name_custom_menu = $wpdb->prefix . "woo_custom_nav_menus"; + $insert_menu_name = $_POST['add_menu_name']; + + //CHECK for existing woo custom menu + $existing_records = $wpdb->query( "SELECT id FROM ".$table_name_custom_menu." WHERE menu_name='".$insert_menu_name."'" ); + + if ($insert_menu_name <> '') { + if ($existing_records > 0) + { + $messagesdiv = '

    '.$insert_menu_name.' Menu has already created - please try another name

    '; + //GET reset menu id + $table_name_menus = $wpdb->prefix . "woo_custom_nav_menus"; + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name_menus." ORDER BY id ASC LIMIT 1" ); + if ($woo_result > 0) { + $menu_selected_id = $woo_result[0]->id; + $menu_id_in_edit = $menu_selected_id; + } + else { + $menu_selected_id = 0; + $menu_selected_id = 0; + } + } + else + { + $wpdb->insert( $table_name_custom_menu, array( 'menu_name' => $insert_menu_name )); + $menu_selected_id = $wpdb->insert_id; + $menu_id_in_edit = $menu_selected_id; + $messagesdiv = '

    '.$insert_menu_name.' Menu has been created!

    '; + + $custom_nav_exists = $wpdb->query( "SELECT id FROM ".$table_name." WHERE menu_id='".$menu_selected_id."'" ); + $postCounter = 0; + } + } + else + { + $messagesdiv = '

    Please enter a valid Menu name

    '; + } + + + } + + if ($postCounter > 0) + { + + if (isset($_POST['switch_menu'])) { + + } + elseif (isset($_POST['add_menu'])) { + + } + elseif (isset($_POST['reset_woo_menu'])) { + $success = woo_custom_nav_reset(); + if ($success) { + //DISPLAY SUCCESS MESSAGE IF Menu Reset Correctly + $messagesdiv = '

    '.$themename.'\'s Custom Menu has been RESET!

    '; + //GET reset menu id + $table_name_menus = $wpdb->prefix . "woo_custom_nav_menus"; + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name_menus." ORDER BY id ASC LIMIT 1" ); + if ($woo_result > 0 && isset($woo_result[0]->id)) { + $menu_selected_id = $woo_result[0]->id; + } + else { + $menu_selected_id = 0; + } + } + else { + //DISPLAY SUCCESS MESSAGE IF Menu Reset Correctly + $messagesdiv = '

    '.$themename.'\'s Custom Menu could not be RESET. Please try again.

    '; + } + } + else { + + $menu_id_in_edit = $_POST['menu_id_in_edit']; + //After POST delete existing records in prep for Insert + $wpdb->query( "DELETE FROM ".$table_name." WHERE menu_id='".$menu_id_in_edit."'" ); + + //Loop through all POST variables + for ($k = 1;$k<= $postCounter; $k++) { + + if (isset($_POST['dbid'.$k])) { $db_id = $_POST['dbid'.$k]; } else { $db_id = 0; } + if (isset($_POST['postmenu'.$k])) { $post_id = $_POST['postmenu'.$k]; } else { $post_id = 0; } + if (isset($_POST['parent'.$k])) { $parent_id = $_POST['parent'.$k]; } else { $parent_id = 0; } + if (isset($_POST['title'.$k])) { $custom_title = stripslashes($_POST['title'.$k]); } else { $custom_title = ''; } + if (isset($_POST['linkurl'.$k])) { $custom_linkurl = $_POST['linkurl'.$k]; } else { $custom_linkurl = ''; } + if (isset($_POST['description'.$k])) { $custom_description = stripslashes($_POST['description'.$k]); } else { $custom_description = ''; } + if (isset($_POST['icon'.$k])) { $icon = $_POST['icon'.$k]; } else { $icon = 0; } + if (isset($_POST['position'.$k])) { $position = $_POST['position'.$k]; } else { $position = 0; } + if (isset($_POST['linktype'.$k])) { $linktype = $_POST['linktype'.$k]; } else { $linktype = 'custom'; } + if (isset($_POST['anchortitle'.$k])) { $custom_anchor_title = stripslashes($_POST['anchortitle'.$k]); } else { $custom_anchor_title = $custom_title; } + if (isset($_POST['newwindow'.$k])) { $new_window = $_POST['newwindow'.$k]; } else { $new_window = 0; } + + if ($linktype == '') + { + + } + else + { + //If top level menu item + if ($parent_id == 0) + { + //INSERT menu item record + $wpdb->insert( $table_name, array( 'position' => $position, 'post_id' => $post_id, 'parent_id' => $parent_id, 'custom_title' => $custom_title, 'custom_link' => $custom_linkurl, 'custom_description' => $custom_description, 'menu_icon' => $icon, 'link_type' => $linktype, 'menu_id' => $menu_id_in_edit, 'custom_anchor_title' => $custom_anchor_title, 'new_window' => $new_window )); + } + //If not top level menu item + else + { + //INSERT menu item record + $wpdb->insert( $table_name, array( 'position' => $position, 'post_id' => $post_id, 'parent_id' => '8000', 'custom_title' => $custom_title, 'custom_link' => $custom_linkurl, 'custom_description' => $custom_description, 'menu_icon' => $icon, 'link_type' => $linktype, 'menu_id' => $menu_id_in_edit, 'custom_anchor_title' => $custom_anchor_title, 'new_window' => $new_window )); + $lastid = $wpdb->insert_id; + + //GET the correct parent record + $parentrecords = $wpdb->get_results( "SELECT id FROM ".$table_name." WHERE position='".($parent_id)."' AND menu_id='".$menu_id_in_edit."'" ); + + if ($parentrecords > 0) + { + foreach ($parentrecords as $parentrecord) + { + $parent_id_update = $parentrecord->id; + } + } + //UPDATE menu item record with correct parent + $wpdb->update( $table_name, array( 'parent_id' => $parent_id_update ), array( 'id' => $lastid, 'menu_id' => $menu_id_in_edit )); + } + } + } + //DISPLAY SUCCESS MESSAGE IF POST CORRECT + $messagesdiv = '

    '.$themename.'\'s Custom Menu has been updated!

    '; + + } + } + else { + if (isset($_POST['reset_woo_menu'])) { + $success = woo_custom_nav_reset(); + if ($success) { + //DISPLAY SUCCESS MESSAGE IF Menu Reset Correctly + $messagesdiv = '

    '.$themename.'\'s Custom Menu has been RESET!

    '; + //GET reset menu id + $table_name_menus = $wpdb->prefix . "woo_custom_nav_menus"; + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name_menus." ORDER BY id ASC LIMIT 1" ); + if ($woo_result > 0 && isset($woo_result[0]->id)) { + $menu_selected_id = $woo_result[0]->id; + } + else { + $menu_selected_id = 0; + } + } + else { + //DISPLAY SUCCESS MESSAGE IF Menu Reset Correctly + $messagesdiv = '

    '.$themename.'\'s Custom Menu could not be RESET. Please try again.

    '; + } + } + } + + //DISPLAY Custom Navigation + ?> +
    +
    +

    Custom Navigation

    +

    The Custom Menu has not been Enabled yet. Please enable it in order to use it -------->

    '; + } + //Notify users that they can use 3.0 Menus instead + if ( function_exists( 'wp_nav_menu') ) { + echo '

    You have WordPress 3.0.x installed!

    We suggest that you use the WordPress Menu Management system instead of the Custom Navigation.

    '; + } + + ?> + +
    + + + + + + + + +

    + + + +

    +
    +
    + + + + + + +
    +
    +
    +
    + + style="display:none;" />
    +
    + + tag +/* after_title - html after title is outputted in tag +/*-----------------------------------------------------------------------------------*/ +function woo_custom_navigation_output($args = array()) { + + //DEFAULT ARGS + $type = 'frontend'; + $name = 'Woo Menu 1'; + $id = 0; + $desc = 2; + $before_title = ''; + $after_title = ''; + $depth = 0; + + if (isset($args)) { + + if ( !is_array($args) ) + parse_str( $args, $args ); + + extract($args); + } + + global $wpdb; + $woo_custom_nav_menu_id = 0; + $table_name = $wpdb->prefix . "woo_custom_nav_records"; + + //Override for menu descriptions + $advanced_option_descriptions = get_option( 'woo_settings_custom_nav_advanced_options' ); + if ($advanced_option_descriptions == 'no') + { + $desc = 2; + } + + //GET Menu Items + //FRONTEND + if ($type == "frontend") + { + $table_name_menus = $wpdb->prefix . "woo_custom_nav_menus"; + if ($id > 0) { + $woo_custom_nav_menu_id = $id; + } + else { + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name_menus." WHERE menu_name='".$name."'" ); + $woo_custom_nav_menu_id = $woo_result[0]->id; + } + + $woo_custom_nav_menu = $wpdb->get_results( "SELECT id,post_id,parent_id,position,custom_title,custom_link,custom_description,menu_icon,link_type,custom_anchor_title,new_window FROM ".$table_name." WHERE parent_id = '0' AND menu_id='".$woo_custom_nav_menu_id."' ORDER BY position ASC" ); + } + //BACKEND + else { + $woo_custom_nav_menu = $wpdb->get_results( "SELECT id,post_id,parent_id,position,custom_title,custom_link,custom_description,menu_icon,link_type,custom_anchor_title,new_window FROM ".$table_name." WHERE parent_id = '0' AND menu_id='".$id."' ORDER BY position ASC" ); + } + $queried_id = 0; + $type_settings = 'custom'; + global $wp_query; + if (is_page()) { + $queried_id = $wp_query->post->ID; + $type_settings = 'page'; + } + elseif (is_category()) { + $queried_id = $wp_query->query_vars['cat']; + $type_settings = 'category'; + } + else { + } + //DISPLAY Loop + foreach ($woo_custom_nav_menu as $woo_custom_nav_menu_items) { + + //PREPARE Menu Data + //Page Menu Item + if ($woo_custom_nav_menu_items->link_type == 'page') + { + if ($woo_custom_nav_menu_items->custom_link == '') { + $link = get_permalink($woo_custom_nav_menu_items->post_id); + } + else { + $link = $woo_custom_nav_menu_items->custom_link; + } + + if ($woo_custom_nav_menu_items->custom_title == '') { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert(get_the_title($woo_custom_nav_menu_items->post_id)); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + else { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($woo_custom_nav_menu_items->custom_title); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + + if ($woo_custom_nav_menu_items->custom_description == '') { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert(get_post_meta($woo_custom_nav_menu_items->post_id, 'page-description', true)); + $description = htmlspecialchars(trim($str_converted), ENT_QUOTES, 'UTF-8' ); + } + else { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($woo_custom_nav_menu_items->custom_description); + $description = htmlspecialchars(trim($str_converted), ENT_QUOTES, 'UTF-8' ); + } + $target = ''; + } + //Category Menu Item + elseif ($woo_custom_nav_menu_items->link_type == 'category') + { + + if ($woo_custom_nav_menu_items->custom_link == '') { + $link = get_category_link($woo_custom_nav_menu_items->post_id); + } + else { + $link = $woo_custom_nav_menu_items->custom_link; + } + + if ($woo_custom_nav_menu_items->custom_title == '') { + $title_raw = get_categories( 'include='.$woo_custom_nav_menu_items->post_id); + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($title_raw[0]->cat_name); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + else { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($woo_custom_nav_menu_items->custom_title); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + + if ($woo_custom_nav_menu_items->custom_description == '') { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert(category_description($woo_custom_nav_menu_items->post_id)); + $description = htmlspecialchars(strip_tags(trim($str_converted)), ENT_QUOTES, 'UTF-8' ); + } + else { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($woo_custom_nav_menu_items->custom_description); + $description = htmlspecialchars(trim($str_converted), ENT_QUOTES, 'UTF-8' ); + } + $target = ''; + + } + //Custom Menu Item + else + { + $link = $woo_custom_nav_menu_items->custom_link; + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($woo_custom_nav_menu_items->custom_title); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($woo_custom_nav_menu_items->custom_description); + $description = htmlspecialchars(trim($str_converted), ENT_QUOTES, 'UTF-8' ); + $target = 'target="_blank"'; + } + + //SET anchor title + if (isset($woo_custom_nav_menu_items->custom_anchor_title)) { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($woo_custom_nav_menu_items->custom_anchor_title); + $anchor_title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + else { + $anchor_title = $title; + } + + //SET URL protocol + if (isset($_SERVER['HTTPS'])) { + if ($_SERVER['HTTPS'] == 'on') { + $protocol = 'https'; + } + else { + $protocol = 'http'; + } + } + else { + $protocol = 'http'; + } + $full_web_address = $protocol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; + + if (($queried_id == $woo_custom_nav_menu_items->post_id) && ($queried_id != 0) && ($type_settings == $woo_custom_nav_menu_items->link_type) ) { + $li_class = 'class="current_page_item"'; + } + else if (($woo_custom_nav_menu_items->custom_link == $full_web_address) && ($queried_id == 0) && ($type_settings == $woo_custom_nav_menu_items->link_type) ) { + $li_class = 'class="current_page_item"'; + } + else if (woo_child_is_current($woo_custom_nav_menu_items->id, $woo_custom_nav_menu_id, $table_name, $queried_id, $type_settings, $full_web_address)) { + $li_class = 'class="current_page_parent"'; + } + else { + $li_class = ''; + } + + if (isset($woo_custom_nav_menu_items->new_window)) { + if ($woo_custom_nav_menu_items->new_window > 0) { + $target = 'target="_blank"'; + } + else { + $target = ''; + } + } + + //List Items + ?>
  • >> +
  • + get_results( "SELECT id,post_id,parent_id,position,custom_title,custom_link,custom_description,menu_icon,link_type,custom_anchor_title,new_window FROM ".$table_name." WHERE parent_id = '".$post_id."' AND menu_id='".$menu_id."' ORDER BY position ASC" ); + + if (empty($woo_custom_nav_menu)) + { + + } + else + { + ?>
      id="sub-custom-nav" > + post->ID; + $type_settings = 'page'; + } + elseif (is_category()) { + $queried_id = $wp_query->query_vars['cat']; + $type_settings = 'category'; + } + else { + + } + //DISPLAY Loop + foreach ($woo_custom_nav_menu as $sub_item) + { + //Figure out where the menu item sits + $counter=$sub_item->position; + + //Prepare Menu Data + //Category Menu Item + if ($sub_item->link_type == 'category') + { + + $parent_id = $sub_item->parent_id; + $post_id = $sub_item->post_id; + + if ($sub_item->custom_link == '') { + $link = get_category_link($sub_item->post_id); + } + else { + $link = $sub_item->custom_link; + } + + if ($sub_item->custom_title == '') { + $title_raw = get_categories( 'include='.$sub_item->post_id); + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($title_raw[0]->cat_name); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + else { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($sub_item->custom_title); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + + if ($sub_item->custom_description == '') { + $description = strip_tags(trim(category_description($sub_item->post_id))); + } + else { + $description = trim($sub_item->custom_description); + } + $target = ''; + } + //Page Menu Item + elseif ($sub_item->link_type == 'page') + { + + $parent_id = $sub_item->parent_id; + $post_id = $sub_item->post_id; + + if ($sub_item->custom_link == '') { + $link = get_permalink($sub_item->post_id); + } + else { + $link = $sub_item->custom_link; + } + + if ($sub_item->custom_title == '') { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert(get_the_title($sub_item->post_id)); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + else { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($sub_item->custom_title); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + + if ($sub_item->custom_description == '') { + $description = trim(get_post_meta($sub_item->post_id, 'page-description', true)); + } + else { + $description = trim($sub_item->custom_description); + } + $target = ''; + + } + //Custom Menu Item + else + { + $link = $sub_item->custom_link; + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($sub_item->custom_title); + $title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + $parent_id = $sub_item->parent_id; + $post_id = $sub_item->post_id; + $description = trim($sub_item->custom_description); + $target = 'target="_blank"'; + } + + //SET URL protocol + if (isset($_SERVER['HTTPS'])) { + if ($_SERVER['HTTPS'] == 'on') { + $protocol = 'https'; + } + else { + $protocol = 'http'; + } + } + else { + $protocol = 'http'; + } + $full_web_address = $protocol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; + + if (($queried_id == $sub_item->post_id) && ($queried_id != 0) && ($type_settings == $sub_item->link_type)) { + $li_class = 'class="current_page_item"'; + } + else if (($sub_item->custom_link == $full_web_address) && ($queried_id == 0) && ($type_settings == $sub_item->link_type) ) { + $li_class = 'class="current_page_item"'; + } + else if (woo_child_is_current($sub_item->id, $menu_id, $table_name, $queried_id, $type_settings, $full_web_address)) { + $li_class = 'class="current_page_parent"'; + } + else { + $li_class = ''; + } + + //SET anchor title + if (isset($sub_item->custom_anchor_title)) { + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($sub_item->custom_anchor_title); + $anchor_title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + } + else { + $anchor_title = $title; + } + + if (isset($sub_item->new_window)) { + if ($sub_item->new_window > 0) { + $target = 'target="_blank"'; + } + else { + $target = ''; + } + } + + //List Items + ?>
    • >> +
    • +
    + get_results( "SELECT id,post_id,parent_id,position,custom_title,custom_link,custom_description,menu_icon,link_type,custom_anchor_title,new_window FROM ".$table_name." WHERE parent_id = '".$parent_id."' AND menu_id='".$menu_id."' ORDER BY position ASC" ); + + //If more than 0 child elements + if (empty($woo_parent_children)) + { + + } + else + { + //Children Loop + foreach ($woo_parent_children as $woo_parent_child) + { + //Check if meets criteria + if (($queried_id == $woo_parent_child->post_id) && ($queried_id != 0) && ($type_settings == $woo_parent_child->link_type) ) { + $success = true; + } + else if (($woo_parent_child->custom_link == $full_web_address) && ($queried_id == 0) && ($type_settings == $woo_parent_child->link_type) ) { + $success = true; + } + } + } + + return $success; + +} + +//Outputs All Pages and Sub Items +function woo_get_pages($counter,$type) { + + $pages_args = array( + 'child_of' => 0, + 'sort_order' => 'ASC', + 'sort_column' => 'post_title', + 'hierarchical' => 1, + 'exclude' => '', + 'include' => '', + 'meta_key' => '', + 'meta_value' => '', + 'authors' => '', + 'parent' => -1, + 'exclude_tree' => '', + 'number' => '', + 'offset' => 0 ); + + //GET all pages + $pages_array = get_pages($pages_args); + + $intCounter = $counter; + $parentli = $intCounter; + + if ($pages_array) + { + //DISPLAY Loop + foreach ($pages_array as $post) + { + + if ($post->post_parent == 0) + { + //Custom Menu + if ($type == 'menu') + { + $description = trim(get_post_meta($post->ID, 'page-description', true)); + ?> + + + + + +
  • +
    +
    + post_title); + $post_text = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + $post_url = get_permalink($post->ID); + $post_id = $post->ID; + $post_parent_id = $post->post_parent; + //Convert string to UTF-8 + $str_converted = woo_encoding_convert(get_post_meta($post_id, 'page-description', true)); + $description = htmlspecialchars(trim($str_converted), ENT_QUOTES, 'UTF-8' ); + + ?> + + + post_title; ?> Add to Custom Menu
    +
    + ID; ?> + + + +
  • + + 'post', + 'child_of' => 0, + 'orderby' => 'name', + 'order' => 'ASC', + 'hide_empty' => false, + 'include_last_update_time' => false, + 'hierarchical' => 1, + 'exclude' => '', + 'include' => '', + 'number' => '', + 'pad_counts' => false ); + + + + $intCounter = $counter; + + //GET all categories + $categories_array = get_categories($category_args); + + if ($categories_array) + { + //DISPLAY Loop + foreach ($categories_array as $cat_item) + { + + if ($cat_item->parent == 0) + { + //Custom Menu + if ($type == 'menu') + { + ?> + + + + +
  • +
    +
    + cat_name); + $post_text = htmlspecialchars(addslashes($str_converted), ENT_QUOTES, 'UTF-8' ); + $post_url = get_category_link($cat_item->cat_ID); + $post_id = $cat_item->cat_ID; + $post_parent_id = $cat_item->parent; + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($cat_item->description); + $description = htmlspecialchars(addslashes(strip_tags(trim($str_converted))), ENT_QUOTES, 'UTF-8' ); + ?> + + cat_name; ?> Add to Custom Menu
    +
    + cat_ID; ?> + + cat_ID, $intCounter, $parentli, 'categories','default' ); + ?> + +
  • + + $childof, + 'hide_empty' => false, + 'parent' => $childof); + } + //Sidebar Menu + elseif ($output_type == 'default') + { + $sub_args = array( + 'child_of' => $childof, + 'hide_empty' => false, + 'parent' => $childof); + } + else + { + + } + + //Get Sub Category Items + if ($type == 'categories') + { + $sub_array = get_categories($sub_args); + } + //Get Sub Page Items + elseif ($type == 'pages') + { + $sub_array = get_pages($sub_args); + } + + + if ($sub_array) + { + ?> + +
      + + cat_ID); + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($sub_item->cat_name); + //$title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + $title = htmlspecialchars(addslashes($str_converted), ENT_QUOTES, 'UTF-8' ); + $parent_id = $sub_item->cat_ID; + $itemid = $sub_item->cat_ID; + $linktype = 'category'; + $appendtype = 'Category'; + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($sub_item->description); + //$description = htmlspecialchars(strip_tags(trim($str_converted)), ENT_QUOTES, 'UTF-8' ); + $description = htmlspecialchars(addslashes(strip_tags(trim($str_converted))), ENT_QUOTES, 'UTF-8' ); + } + //Page Menu Item + elseif ($type == 'pages') + { + $link = get_permalink($sub_item->ID); + //Convert string to UTF-8 + $str_converted = woo_encoding_convert($sub_item->post_title); + //$title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + $title = htmlspecialchars(addslashes($str_converted), ENT_QUOTES, 'UTF-8' ); + $parent_id = $sub_item->ID; + $linktype = 'page'; + $itemid = $sub_item->ID; + $appendtype = 'Page'; + //Convert string to UTF-8 + $str_converted = woo_encoding_convert(get_post_meta($itemid, 'page-description', true)); + //$description = htmlspecialchars(trim($str_converted), ENT_QUOTES, 'UTF-8' ); + $description = htmlspecialchars(addslashes(strip_tags(trim($str_converted))), ENT_QUOTES, 'UTF-8' ); + } + //Custom Menu Item + else + { + $title = ''; + $linktype = 'custom'; + $appendtype= 'Custom'; + } + + //Custom Menu + if ($output_type == 'menu') + { + ?> + + +
    • +
      +
      + + + Add to Custom Menu
      +
      + +
    • + + + +
    + + $childof, + 'hide_empty' => false, + 'parent' => $childof); + $sub_array = get_categories($sub_args); + } + //Get Sub Page Items + elseif ($type == 'pages') + { + $sub_args = array( + 'child_of' => $childof, + 'parent' => $childof); + + $sub_array = get_pages($sub_args); + + } + else { + + } + + if ($sub_array) + { + //DISPLAY Loop + foreach ($sub_array as $sub_item) + { + if (isset($sub_item->parent)) { + $sub_item_parent = $sub_item->parent; + } + elseif (isset($sub_item->post_parent)) { + $sub_item_parent = $sub_item->post_parent; + } + else { + } + //Is child + if ($sub_item_parent == $childof) + { + //Prepare Menu Data + //Category Menu Item + if ($type == 'categories') + { + $link = get_category_link($sub_item->cat_ID); + //Convert string to UTF-8 + //$str_converted = woo_encoding_convert($sub_item->cat_name); + //$title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + $title = $sub_item->cat_name; + $parent_id = $sub_item->category_parent; + $itemid = $sub_item->cat_ID; + $linktype = 'category'; + $appendtype= 'Category'; + } + //Page Menu Item + elseif ($type == 'pages') + { + $link = get_permalink($sub_item->ID); + //Convert string to UTF-8 + //$str_converted = woo_encoding_convert($sub_item->post_title); + //$title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + $title = $sub_item->post_title; + $parent_id = $sub_item->post_parent; + $linktype = 'page'; + $itemid = $sub_item->ID; + $appendtype= 'Page'; + } + //Custom Menu Item + else + { + $title = ''; + $linktype = 'custom'; + $appendtype= 'Custom'; + } + + //CHECK for existing parent records + //echo $parent_id; + $woo_result = $wpdb->get_results( "SELECT id FROM ".$table_name." WHERE post_id='".$parent_id."' AND link_type='".$linktype."' AND menu_id='".$menu_id."'" ); + if ($woo_result > 0 && isset($woo_result[0]->id)) { + $parent_id = $woo_result[0]->id; + } + else { + //$parent_id = 0; + } + + //INSERT item + //Convert string to UTF-8 + $str_converted = stripslashes($title); + //$insert_title = htmlspecialchars($str_converted, ENT_QUOTES, 'UTF-8' ); + //$insert = "INSERT INTO ".$table_name." (position,post_id,parent_id,custom_title,custom_link,custom_description,menu_icon,link_type,menu_id,custom_anchor_title) "."VALUES ( '".$counter."','".$itemid."','".$parent_id."','".$title."','".$link."','','','".$linktype."','".$menu_id."','".$title."')"; + //$results = $wpdb->query( $insert ); + $results = $wpdb->insert( $table_name, array( 'position' => $counter, 'post_id' => $itemid, 'parent_id' => $parent_id, 'custom_title' => $str_converted, 'custom_link' => $link, 'custom_description' => '', 'menu_icon' => '', 'link_type' => $linktype, 'menu_id' => $menu_id, 'custom_anchor_title' => $str_converted )); + + $counter++; + $counter = get_children_menu_elements($itemid, $counter, $parent_id, $type, $menu_id, $table_name); + } + //Do nothing + else { + + } + } + } + return $counter; +} + +/*---------------------------------------------------------------------------------*/ +/* Woothemes Custom Navigation Menu Widget */ +/*---------------------------------------------------------------------------------*/ + +class Woo_NavWidget extends WP_Widget { + + function Woo_NavWidget() { + $widget_ops = array( 'description' => 'Use this widget to add one of your Woo Custom Navigation Menus as a widget.' ); + parent::WP_Widget(false, __( 'Woo - Custom Nav Menu', 'woothemes' ),$widget_ops); + } + + function widget($args, $instance) { + $navmenu = $instance['navmenu']; + $navtitle = $instance['navtitle']; + $navdeveloper = strtolower($instance['navdeveloper']); + if (isset($instance['navdiv'])) { $navdiv = strtolower($instance['navdiv']); } else { $navdiv = 'no';} + if (isset($instance['navul'])) { $navul = strtolower($instance['navul']); } else { $navul = 'no';} + if (isset($instance['navwidgetdescription'])) { $navwidgetdescription = strtolower($instance['navwidgetdescription']); } else { $navwidgetdescription = '2';} + + $menuexists = false; + + global $wpdb; + + //GET menu name + if ($navmenu > 0) + { + $table_name_menus = $wpdb->prefix . "woo_custom_nav_menus"; + $woo_result = $wpdb->get_results( "SELECT menu_name FROM ".$table_name_menus." WHERE id='".$navmenu."'" ); + $woo_custom_nav_menu_name = $woo_result[0]->menu_name; + $menuexists = true; + } + //Do nothing + else + { + $menuexists = false; + } + ?> + + +
    + +
    + + +

    + + +
      + +
        + + + + + +
      + +
    + + + +
    + +
    + + + prefix . "woo_custom_nav_menus"; + $custom_menu_records = $wpdb->get_results( "SELECT id,menu_name FROM ".$table_name_custom_menus); + + //CHECK if menus exist + if ($custom_menu_records > 0) + { + + ?> + +

    + + + + +

    + +

    + + + +

    + +

    + + +
    + + /> + /> + + +

    + + + +

    + + +
    + + /> + /> + + +

    + +

    + + +
    + + /> + /> + + +

    + + +

    style="display:none;"> + + + +
    + + /> + /> + +

    + +

    + +

    + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-custom.php b/src/wp-content/themes/bloggingstream/functions/admin-custom.php new file mode 100644 index 00000000..0cb1f114 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-custom.php @@ -0,0 +1,647 @@ +'."\n"; + foreach ($woo_metaboxes as $woo_metabox) { + $woo_id = "woothemes_" . $woo_metabox["name"]; + $woo_name = $woo_metabox["name"]; + + if ($template_to_show == 'seo') { + $metabox_post_type_restriction = 'undefined'; + } elseif (function_exists( 'woothemes_content_builder_menu')) { + $metabox_post_type_restriction = $woo_metabox['cpt'][$post->post_type]; + } else { + $metabox_post_type_restriction = 'undefined'; + } + + if ( ($metabox_post_type_restriction != '') && ($metabox_post_type_restriction == 'true') ) { + $type_selector = true; + } elseif ($metabox_post_type_restriction == 'undefined') { + $type_selector = true; + } else { + $type_selector = false; + } + + $woo_metaboxvalue = ''; + + if ($type_selector) { + + if( + $woo_metabox['type'] == 'text' + OR $woo_metabox['type'] == 'select' + OR $woo_metabox['type'] == 'select2' + OR $woo_metabox['type'] == 'checkbox' + OR $woo_metabox['type'] == 'textarea' + OR $woo_metabox['type'] == 'calendar' + OR $woo_metabox['type'] == 'time' + OR $woo_metabox['type'] == 'radio' + OR $woo_metabox['type'] == 'images') { + + $woo_metaboxvalue = get_post_meta($post->ID,$woo_name,true); + + } + + if ( $woo_metaboxvalue == '' && isset( $woo_metabox['std'] ) ) { + + $woo_metaboxvalue = $woo_metabox['std']; + } + if($woo_metabox['type'] == 'info'){ + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''.$woo_metabox['desc'].''."\n"; + $output .= "\t".''."\n"; + + } + elseif($woo_metabox['type'] == 'text'){ + + $add_class = ''; $add_counter = ''; + if($template_to_show == 'seo'){$add_class = 'word-count'; $add_counter = '0 characters, 0 words';} + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''; + $output .= ''.$woo_metabox['desc'] .' '. $add_counter .''."\n"; + $output .= "\t".''."\n"; + + } + + elseif ($woo_metabox['type'] == 'textarea'){ + + $add_class = ''; $add_counter = ''; + if($template_to_show == 'seo'){$add_class = 'word-count'; $add_counter = '0 characters, 0 words';} + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''; + $output .= ''.$woo_metabox['desc'] .' '. $add_counter.''."\n"; + $output .= "\t".''."\n"; + + } + + elseif ($woo_metabox['type'] == 'calendar'){ + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''; + $output .= ''.$woo_metabox['desc'].''."\n"; + $output .= "\t".''."\n"; + + } + + elseif ($woo_metabox['type'] == 'time'){ + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''; + $output .= ''.$woo_metabox['desc'].''."\n"; + $output .= "\t".''."\n"; + + } + + elseif ($woo_metabox['type'] == 'select'){ + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''.$woo_metabox['desc'].''."\n"; + $output .= "\t".''."\n"; + } + elseif ($woo_metabox['type'] == 'select2'){ + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''.$woo_metabox['desc'].''."\n"; + $output .= "\t".''."\n"; + } + + elseif ($woo_metabox['type'] == 'checkbox'){ + + if($woo_metaboxvalue == 'true') { $checked = ' checked="checked"';} else {$checked='';} + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''; + $output .= ''.$woo_metabox['desc'].''."\n"; + $output .= "\t".''."\n"; + } + + elseif ($woo_metabox['type'] == 'radio'){ + + $array = $woo_metabox['options']; + + if($array){ + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''; + + foreach ( $array as $id => $option ) { + + if($woo_metaboxvalue == $id) { $checked = ' checked';} else {$checked='';} + + $output .= ''; + $output .= ''. $option .'
    '; + } + $output .= "\t".''."\n"; + } + } + elseif ($woo_metabox['type'] == 'images') + { + + $i = 0; + $select_value = ''; + $layout = ''; + + foreach ($woo_metabox['options'] as $key => $option) + { + $i++; + + $checked = ''; + $selected = ''; + if($woo_metaboxvalue != '') { + if ($woo_metaboxvalue == $key) { $checked = ' checked'; $selected = 'woo-meta-radio-img-selected'; } + } + else { + if ($option['std'] == $key) { $checked = ' checked'; } + elseif ($i == 1) { $checked = ' checked'; $selected = 'woo-meta-radio-img-selected'; } + else { $checked=''; } + + } + + $layout .= '
    '; + $layout .= ''; + $layout .= ' ' . $key .'
    '; + $layout .= ''; + } + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''; + $output .= $layout; + $output .= ''.$woo_metabox['desc'].''."\n"; + $output .= "\t".''."\n"; + + } + + elseif($woo_metabox['type'] == 'upload') + { + if(isset($woo_metabox["default"])) $default = $woo_metabox["default"]; + else $default = ''; + + // Add support for the WooThemes Media Library-driven Uploader Module // 2010-11-09. + if ( function_exists( 'woothemes_medialibrary_uploader' ) ) { + + $_value = $default; + + $_value = get_post_meta( $post->ID, $woo_metabox["name"], true ); + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''. woothemes_medialibrary_uploader( $woo_metabox["name"], $_value, 'postmeta', $woo_metabox["desc"], $post->ID ); + $output .= ''."\n"; + $output .= "\t".''."\n"; + + } else { + + $output .= "\t".''; + $output .= "\t\t".''."\n"; + $output .= "\t\t".''. woothemes_uploader_custom_fields($post->ID,$woo_name,$default,$woo_metabox["desc"]); + $output .= ''."\n"; + $output .= "\t".''."\n"; + + } // End IF Statement + + } + } // End IF Statement + } + + $output .= ''."\n\n"; + echo $output; +} + + + +/*-----------------------------------------------------------------------------------*/ +// woothemes_uploader_custom_fields +/*-----------------------------------------------------------------------------------*/ + +function woothemes_uploader_custom_fields($pID,$id,$std,$desc){ + + // Start Uploader + $upload = get_post_meta( $pID, $id, true); + $href = cleanSource($upload); + $uploader = ''; + $uploader .= ''; + $uploader .= '
    '."\n"; + $uploader .= ''; + $uploader .= ''; + if ( $href ) + $uploader .= ''.$desc.''."\n".''; + +return $uploader; +} + + + +/*-----------------------------------------------------------------------------------*/ +// woothemes_metabox_handle +/*-----------------------------------------------------------------------------------*/ + +function woothemes_metabox_handle(){ + + $pID = ''; + global $globals, $post; + + $woo_metaboxes = get_option( 'woo_custom_template' ); + + $seo_metaboxes = get_option( 'woo_custom_seo_template' ); + + if(!empty($seo_metaboxes) AND get_option( 'seo_woo_hide_fields') != 'true'){ + $woo_metaboxes = array_merge($woo_metaboxes,$seo_metaboxes); + } + + // Sanitize post ID. + + if( isset( $_POST['post_ID'] ) ) { + + $pID = intval( $_POST['post_ID'] ); + + } // End IF Statement + + // Don't continue if we don't have a valid post ID. + + if ( $pID == 0 ) { + + return; + + } // End IF Statement + + $upload_tracking = array(); + + if ( isset( $_POST['action'] ) && $_POST['action'] == 'editpost' ) { + + foreach ($woo_metaboxes as $woo_metabox) { // On Save.. this gets looped in the header response and saves the values submitted + if($woo_metabox['type'] == 'text' + OR $woo_metabox['type'] == 'calendar' + OR $woo_metabox['type'] == 'time' + OR $woo_metabox['type'] == 'select' + OR $woo_metabox['type'] == 'select2' + OR $woo_metabox['type'] == 'radio' + OR $woo_metabox['type'] == 'checkbox' + OR $woo_metabox['type'] == 'textarea' + OR $woo_metabox['type'] == 'images' ) // Normal Type Things... + { + + $var = $woo_metabox["name"]; + + if ( isset( $_POST[$var] ) ) { + + // Sanitize the input. + $posted_value = ''; + $posted_value = $_POST[$var]; + + // Get the current value for checking in the script. + $current_value = ''; + $current_value = get_post_meta( $pID, $var, true ); + + // If it doesn't exist, add the post meta. + if(get_post_meta( $pID, $var ) == "") { + + add_post_meta( $pID, $var, $posted_value, true ); + + } + // Otherwise, if it's different, update the post meta. + elseif( $posted_value != get_post_meta( $pID, $var, true ) ) { + + update_post_meta( $pID, $var, $posted_value ); + + } + // Otherwise, if no value is set, delete the post meta. + elseif($posted_value == "") { + + delete_post_meta( $pID, $var, get_post_meta( $pID, $var, true ) ); + + } // End IF Statement + + /* + // If it doesn't exist, add the post meta. + if ( $current_value == "" && $posted_value != '' ) { + + update_post_meta( $pID, $var, $posted_value ); + + // Otherwise, if it's different, update the post meta. + } elseif ( ( $posted_value != '' ) && ( $posted_value != $current_value ) ) { + + update_post_meta( $pID, $var, $posted_value ); + + // Otherwise, if no value is set, delete the post meta. + } elseif ( $posted_value == "" && $current_value != '' ) { + + delete_post_meta($pID, $var, $current_value ); + + } // End IF Statement + */ + + } elseif ( ! isset( $_POST[$var] ) && $woo_metabox['type'] == 'checkbox' ) { + + update_post_meta( $pID, $var, 'false' ); + + } else { + + delete_post_meta( $pID, $var, $current_value ); // Deletes check boxes OR no $_POST + + } // End IF Statement + + } elseif( $woo_metabox['type'] == 'upload' ) { // So, the upload inputs will do this rather + + $id = $woo_metabox['name']; + $override['action'] = 'editpost'; + + if(!empty($_FILES['attachement_'.$id]['name'])){ //New upload + $_FILES['attachement_'.$id]['name'] = preg_replace( '/[^a-zA-Z0-9._\-]/', '', $_FILES['attachement_'.$id]['name']); + $uploaded_file = wp_handle_upload($_FILES['attachement_' . $id ],$override); + $uploaded_file['option_name'] = $woo_metabox['label']; + $upload_tracking[] = $uploaded_file; + update_post_meta( $pID, $id, $uploaded_file['url'] ); + + } elseif ( empty( $_FILES['attachement_'.$id]['name'] ) && isset( $_POST[ $id ] ) ) { + + // Sanitize the input. + $posted_value = ''; + $posted_value = $_POST[$id]; + + update_post_meta($pID, $id, $posted_value); + + } elseif ( $_POST[ $id ] == '' ) { + + delete_post_meta( $pID, $id, get_post_meta( $pID, $id, true ) ); + + } // End IF Statement + + } // End IF Statement + + // Error Tracking - File upload was not an Image + update_option( 'woo_custom_upload_tracking', $upload_tracking ); + + } // End FOREACH Loop + + } // End IF Statement + +} // End woothemes_metabox_handle() + +/*-----------------------------------------------------------------------------------*/ +// woothemes_metabox_add +/*-----------------------------------------------------------------------------------*/ + +function woothemes_metabox_add() { + $seo_metaboxes = get_option( 'woo_custom_seo_template' ); + $seo_post_types = array( 'post','page' ); + if(defined( 'SEOPOSTTYPES')){ + $seo_post_types_update = unserialize( constant( 'SEOPOSTTYPES') ); + } + + if(!empty($seo_post_types_update)){ + $seo_post_types = $seo_post_types_update; + } + + $woo_metaboxes = get_option( 'woo_custom_template' ); + + if ( function_exists( 'add_meta_box') ) { + + if ( function_exists( 'get_post_types') ) { + $custom_post_list = get_post_types(); + foreach ($custom_post_list as $type){ + + //if(!empty($woo_metaboxes)) Temporarily Removed + add_meta_box( 'woothemes-settings', get_option( 'woo_themename').' Custom Settings','woothemes_metabox_create',$type,'normal' ); + + if(array_search($type, $seo_post_types) !== false){ + if(get_option( 'seo_woo_hide_fields') != 'true'){ + add_meta_box( 'woothemes-seo',get_option( 'woo_themename').' SEO Settings','woothemes_metabox_create',$type,'normal','high','seo' ); + } + } + } + } else { + add_meta_box( 'woothemes-settings',get_option( 'woo_themename').' Custom Settings','woothemes_metabox_create','post','normal' ); + add_meta_box( 'woothemes-settings',get_option( 'woo_themename').' Custom Settings','woothemes_metabox_create','page','normal' ); + if(get_option( 'seo_woo_hide_fields') != 'true'){ + add_meta_box( 'woothemes-seo',get_option( 'woo_themename').' SEO Settings','woothemes_metabox_create','post','normal','high','seo' ); + add_meta_box( 'woothemes-seo',get_option( 'woo_themename').' SEO Settings','woothemes_metabox_create','page','normal','high','seo' ); + } + } + + } +} + +/*-----------------------------------------------------------------------------------*/ +// woothemes_metabox_header +/*-----------------------------------------------------------------------------------*/ + +function woothemes_metabox_header(){ +?> + + +'; +} + + +function woo_custom_enqueue($hook) { + if ($hook == 'post.php' OR $hook == 'post-new.php' OR $hook == 'page-new.php' OR $hook == 'page.php') { + add_action( 'admin_head', 'woothemes_metabox_header' ); + wp_enqueue_script( 'jquery-ui-core' ); + wp_register_script( 'jquery-ui-datepicker', get_template_directory_uri() . '/functions/js/ui.datepicker.js', array( 'jquery-ui-core' )); + wp_enqueue_script( 'jquery-ui-datepicker' ); + wp_register_script( 'jquery-input-mask', get_template_directory_uri() . '/functions/js/jquery.maskedinput-1.2.2.js', array( 'jquery' )); + wp_enqueue_script( 'jquery-input-mask' ); + } +} + +add_action( 'admin_enqueue_scripts','woo_custom_enqueue',10,1); +add_action( 'edit_post', 'woothemes_metabox_handle' ); +add_action( 'admin_menu', 'woothemes_metabox_add' ); // Triggers Woothemes_metabox_create + +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-express-functions-deprecated.php b/src/wp-content/themes/bloggingstream/functions/admin-express-functions-deprecated.php new file mode 100644 index 00000000..82ce4f84 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-express-functions-deprecated.php @@ -0,0 +1,385 @@ + '', 'taxonomy' => '' ) + */ +function set_new_taxonomy_tag($post_id, $fields) { + $post_id = (int) $post_id; + + foreach ( (array) $fields as $tax ) { + if ( isset($tax['id']) ) { + $tax['id'] = (int) $tax['id']; + + if ( isset($tax['taxonomy']) ) { + wp_set_post_terms($tax['id'], $tax['tags'], $tax['taxonomy']); + } + } + elseif ($post_id != '') { + if ( isset($tax['taxonomy']) ) { + wp_set_post_terms($post_id, $tax['tags'], $tax['taxonomy']); + } + } + } +} + + +/* + * Express version + * + * Returns the API version number for future compatibility consideration + * + */ + +function express_version() { + return "1.0"; +} + + +/* + * Get Posts With Offset + * + * Returns in a specific range to enable paging. + * + */ + +function express_getPostsWithOffset($args){ + global $wpdb; + global $wp_xmlrpc_server; + + $wp_xmlrpc_server->escape($args); + + $blog_ID = (int) $args[0]; + $username = $args[1]; + $password = $args[2]; + $num_posts = (int) $args[3]; + $offset = (int) $args[4]; + $status = $args[5]; + + if ( !$user = $wp_xmlrpc_server->login($username, $password) ) + return $wp_xmlrpc_server->error; + + do_action( 'xmlrpc_call', 'metaWeblog.getRecentPosts' ); + + // -- Added code + if ($status == '') $statuses = "'draft', 'publish', 'future', 'pending', 'private'"; + else { + $status_array = explode( ",", $status); + $statuses = "'".implode( "','",$status_array)."'"; + } + + $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'post' AND post_status IN ( $statuses ) ORDER BY post_date DESC LIMIT $offset,$num_posts"; + $result = $wpdb->get_results($sql, ARRAY_A); + $posts_list = $result ? $result : array(); + // End added code -- + + if (!$posts_list) { + return array( ); + } + + foreach ($posts_list as $entry) { + if( !current_user_can( 'edit_post', $entry['ID'] ) ) + continue; + + $post_date = mysql2date( 'Ymd\TH:i:s', $entry['post_date'], false); + $post_date_gmt = mysql2date( 'Ymd\TH:i:s', $entry['post_date_gmt'], false); + + // For drafts use the GMT version of the date + if ( $entry['post_status'] == 'draft' ) { + $post_date_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $entry['post_date'] ), 'Ymd\TH:i:s' ); + } + + $categories = array(); + $catids = wp_get_post_categories($entry['ID']); + foreach($catids as $catid) { + $categories[] = get_cat_name($catid); + } + + $tagnames = array(); + $tags = wp_get_post_tags( $entry['ID'] ); + if ( !empty( $tags ) ) { + foreach ( $tags as $tag ) { + $tagnames[] = $tag->name; + } + $tagnames = implode( ', ', $tagnames ); + } else { + $tagnames = ''; + } + + $post = get_extended($entry['post_content']); + $link = post_permalink($entry['ID']); + + // Get the post author info. + $author = get_userdata($entry['post_author']); + + $allow_comments = ( 'open' == $entry['comment_status']) ? 1 : 0; + $allow_pings = ( 'open' == $entry['ping_status']) ? 1 : 0; + + // Consider future posts as published + if( $entry['post_status'] === 'future' ) { + $entry['post_status'] = 'publish'; + } + + $struct[] = array( + 'dateCreated' => new IXR_Date($post_date), + 'userid' => $entry['post_author'], + 'postid' => $entry['ID'], + 'description' => $post['main'], + 'title' => $entry['post_title'], + 'link' => $link, + 'permaLink' => $link, + // commented out because no other tool seems to use this + // 'content' => $entry['post_content'], + 'categories' => $categories, + 'mt_excerpt' => $entry['post_excerpt'], + 'mt_text_more' => $post['extended'], + 'mt_allow_comments' => $allow_comments, + 'mt_allow_pings' => $allow_pings, + 'mt_keywords' => $tagnames, + 'wp_slug' => $entry['post_name'], + 'wp_password' => $entry['post_password'], + 'wp_author_id' => $author->ID, + 'wp_author_display_name' => $author->display_name, + 'date_created_gmt' => new IXR_Date($post_date_gmt), + 'post_status' => $entry['post_status'], + 'custom_fields' => $wp_xmlrpc_server->get_custom_fields($entry['ID']) + ); + + } + + $recent_posts = array(); + for ($j=0; $jescape($args[1]); + $password = $wpdb->escape($args[2]); + $data = $args[3]; + + $name = sanitize_file_name( $data['name'] ); + $type = $data['type']; + $bits = $data['bits']; + + logIO( 'O', '(MW) Received '.strlen($bits).' bytes' ); + + if ( !$user = $wp_xmlrpc_server->login($username, $password) ) + return $wp_xmlrpc_server->error; + + do_action( 'xmlrpc_call', 'metaWeblog.newMediaObject' ); + + if ( !current_user_can( 'upload_files') ) { + logIO( 'O', '(MW) User does not have upload_files capability' ); + return new IXR_Error(401, __( 'You are not allowed to upload files to this site.')); + } + + if ( $upload_err = apply_filters( "pre_upload_error", false ) ) + return new IXR_Error(500, $upload_err); + + if(!empty($data["overwrite"]) && ($data["overwrite"] == true)) { + // Get postmeta info on the object. + $old_file = $wpdb->get_row( " + SELECT ID + FROM {$wpdb->posts} + WHERE post_title = '{$name}' + AND post_type = 'attachment' + " ); + + // Delete previous file. + wp_delete_attachment($old_file->ID); + + // Make sure the new name is different by pre-pending the + // previous post id. + $filename = preg_replace( "/^wpid\d+-/", "", $name); + $name = "wpid{$old_file->ID}-{$filename}"; + } + + $upload = wp_upload_bits($name, $type, $bits); + if ( ! empty($upload['error']) ) { + $errorString = sprintf(__( 'Could not write file %1$s (%2$s)'), $name, $upload['error']); + logIO( 'O', '(MW) ' . $errorString); + return new IXR_Error(500, $errorString); + } + // Construct the attachment array + // attach to post_id 0 + $post_id = 0; + $attachment = array( + 'post_title' => $name, + 'post_content' => '', + 'post_type' => 'attachment', + 'post_parent' => $post_id, + 'post_mime_type' => $type, + 'guid' => $upload[ 'url' ] + ); + + // Save the data + $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id ); + wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) ); + + return apply_filters( 'wp_handle_upload', array( 'file' => $name, 'url' => $upload[ 'url' ], 'type' => $type , 'id' => $id ) ); +} + + +/* + * Woo taxonomy + * + * Set the proper taxonomy + * + */ + +function express_woo_taxonomy($args) { + $content_struct = $args[3]; + + // Re-assign the taxonomies so they are compatible with WooThemes themes + $taxonomies = $content_struct['taxonomy']; + if (is_array($taxonomies)) { + $new_taxonomy = array(); + $woo_tags = array(); + foreach ($taxonomies as $taxonomy) { + if ($taxonomy['taxonomy'] == 'tumblog') { + foreach ($taxonomy['tags'] as $tag) { + switch (strtolower($tag)) { + case 'note': + $woo_tags[] = get_option( 'woo_articles_term_id' ); + break; + case 'link': + $woo_tags[] = get_option( 'woo_links_term_id' ); + break; + case 'quote': + $woo_tags[] = get_option( 'woo_quotes_term_id' ); + break; + case 'image': + $woo_tags[] = get_option( 'woo_images_term_id' ); + break; + default: + $woo_tags[] = $tag; + break; + } + } + $taxonomy['tags'] = implode( ',', $woo_tags); + } + $new_taxonomy[] = $taxonomy; + } + $content_struct['taxonomy'] = $new_taxonomy; + $args[3] = $content_struct; + } + + return $args; +} + + +/* + * New post + * + * Sets post attachements if specified + * Sets post custom taxonomy + * + */ + +function express_newPost($args) { + global $wp_xmlrpc_server; + + $args = express_woo_taxonomy($args); + + $result = $wp_xmlrpc_server->mw_newPost($args); + $post_ID = intval($result); + if ($post_ID == 0) return $result; + + $content_struct = $args[3]; + + // Insert taxonomies + if ( isset($content_struct['taxonomy']) ) { + set_new_taxonomy_tag($post_ID, $content_struct['taxonomy']); + } + + // Add new attachments + $attachments = $content_struct['attachments']; + if (is_array($attachments)) { + foreach ($attachments as $attachment_ID) { + $attachment_post = wp_get_single_post($attachment_ID,ARRAY_A); + extract($attachment_post, EXTR_SKIP); + $post_parent = $post_ID; + $postdata = compact( 'ID', 'post_parent', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt' ); + wp_update_post($postdata); + } + } + + return $result; +} + + +/* + * Edit post + * + * Sets post attachements if specified + * Sets post custom taxonomy + * + */ + +function express_editPost($args) { + global $wp_xmlrpc_server; + + $args = express_woo_taxonomy($args); + + $result = $wp_xmlrpc_server->mw_editPost($args); + if ($result == false) return false; + + // Insert taxonomies + if ( isset($content_struct['taxonomy']) ) { + set_new_taxonomy_tag($post_ID, $content_struct['taxonomy']); + } + + // TODO: Remove old attachments + + + // Add new attachments + $post_ID = (int)$args[0]; + $content_struct = $args[3]; + $attachments = $content_struct['attachments']; + if (is_array($attachments)) { + foreach ($attachments as $attachment_ID) { + $attachment_post = wp_get_single_post($attachment_ID,ARRAY_A); + extract($attachment_post, EXTR_SKIP); + $post_parent = $post_ID; + $postdata = compact( 'ID', 'post_parent', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt' ); + wp_update_post($postdata); + } + } + + return true; +} + + +add_filter( 'xmlrpc_methods', 'attach_express_methods' ); + +function attach_express_methods($methods) { + $methods['express.version'] = 'express_version'; + $methods['express.getPostsWithOffset'] = 'express_getPostsWithOffset'; + $methods['express.uploadFile'] = 'express_uploadFile'; + $methods['express.newPost'] = 'express_newPost'; + $methods['express.editPost'] = 'express_editPost'; + return $methods; +} + +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-express-functions.php b/src/wp-content/themes/bloggingstream/functions/admin-express-functions.php new file mode 100644 index 00000000..64e6eab0 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-express-functions.php @@ -0,0 +1,461 @@ + '', 'taxonomy' => '' ) + */ +function set_new_taxonomy_tag($post_id, $fields) { + $post_id = (int) $post_id; + + foreach ( (array) $fields as $tax ) { + if ( isset($tax['id']) ) { + $tax['id'] = (int) $tax['id']; + + if ( isset($tax['taxonomy']) ) { + wp_set_post_terms($tax['id'], $tax['tags'], $tax['taxonomy']); + } + } + elseif ($post_id != '') { + if ( isset($tax['taxonomy']) ) { + wp_set_post_terms($post_id, $tax['tags'], $tax['taxonomy']); + } + } + } +} + + +/* + * Express version + * + * Returns the API version number for future compatibility consideration + * + */ + +function express_version() { + return "1.0"; +} + + +/* + * Get Posts With Offset + * + * Returns in a specific range to enable paging. + * + */ + +function express_getPostsWithOffset($args){ + global $wpdb; + global $wp_xmlrpc_server; + + $wp_xmlrpc_server->escape($args); + + $blog_ID = (int) $args[0]; + $username = $args[1]; + $password = $args[2]; + $num_posts = (int) $args[3]; + $offset = (int) $args[4]; + $status = $args[5]; + + if ( !$user = $wp_xmlrpc_server->login($username, $password) ) + return $wp_xmlrpc_server->error; + + do_action('xmlrpc_call', 'metaWeblog.getRecentPosts'); + + // -- Added code + if ($status == '') $statuses = "'draft', 'publish', 'future', 'pending', 'private'"; + else { + $status_array = explode(",", $status); + $statuses = "'".implode("','",$status_array)."'"; + } + + $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'post' AND post_status IN ( $statuses ) ORDER BY post_date DESC LIMIT $offset,$num_posts"; + $result = $wpdb->get_results($sql, ARRAY_A); + $posts_list = $result ? $result : array(); + // End added code -- + + if (!$posts_list) { + return array( ); + } + + foreach ($posts_list as $entry) { + if( !current_user_can( 'edit_post', $entry['ID'] ) ) + continue; + + $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date'], false); + $post_date_gmt = mysql2date('Ymd\TH:i:s', $entry['post_date_gmt'], false); + + // For drafts use the GMT version of the date + if ( $entry['post_status'] == 'draft' ) { + $post_date_gmt = get_gmt_from_date( mysql2date( 'Y-m-d H:i:s', $entry['post_date'] ), 'Ymd\TH:i:s' ); + } + + $categories = array(); + $catids = wp_get_post_categories($entry['ID']); + foreach($catids as $catid) { + $categories[] = get_cat_name($catid); + } + + $tagnames = array(); + $tags = wp_get_post_tags( $entry['ID'] ); + if ( !empty( $tags ) ) { + foreach ( $tags as $tag ) { + $tagnames[] = $tag->name; + } + $tagnames = implode( ', ', $tagnames ); + } else { + $tagnames = ''; + } + + $post = get_extended($entry['post_content']); + $link = post_permalink($entry['ID']); + + // Get the post author info. + $author = get_userdata($entry['post_author']); + + $allow_comments = ('open' == $entry['comment_status']) ? 1 : 0; + $allow_pings = ('open' == $entry['ping_status']) ? 1 : 0; + + // Consider future posts as published + if( $entry['post_status'] === 'future' ) { + $entry['post_status'] = 'publish'; + } + + $struct[] = array( + 'dateCreated' => new IXR_Date($post_date), + 'userid' => $entry['post_author'], + 'postid' => $entry['ID'], + 'description' => $post['main'], + 'title' => $entry['post_title'], + 'link' => $link, + 'permaLink' => $link, + // commented out because no other tool seems to use this + // 'content' => $entry['post_content'], + 'categories' => $categories, + 'mt_excerpt' => $entry['post_excerpt'], + 'mt_text_more' => $post['extended'], + 'mt_allow_comments' => $allow_comments, + 'mt_allow_pings' => $allow_pings, + 'mt_keywords' => $tagnames, + 'wp_slug' => $entry['post_name'], + 'wp_password' => $entry['post_password'], + 'wp_author_id' => $author->ID, + 'wp_author_display_name' => $author->display_name, + 'date_created_gmt' => new IXR_Date($post_date_gmt), + 'post_status' => $entry['post_status'], + 'custom_fields' => $wp_xmlrpc_server->get_custom_fields($entry['ID']) + ); + + } + + $recent_posts = array(); + for ($j=0; $jescape($args[1]); + $password = $wpdb->escape($args[2]); + $data = $args[3]; + + $name = sanitize_file_name( $data['name'] ); + $type = $data['type']; + $bits = $data['bits']; + + logIO('O', '(MW) Received '.strlen($bits).' bytes'); + + if ( !$user = $wp_xmlrpc_server->login($username, $password) ) + return $wp_xmlrpc_server->error; + + do_action('xmlrpc_call', 'metaWeblog.newMediaObject'); + + if ( !current_user_can('upload_files') ) { + logIO('O', '(MW) User does not have upload_files capability'); + return new IXR_Error(401, __('You are not allowed to upload files to this site.')); + } + + if ( $upload_err = apply_filters( "pre_upload_error", false ) ) + return new IXR_Error(500, $upload_err); + + if(!empty($data["overwrite"]) && ($data["overwrite"] == true)) { + // Get postmeta info on the object. + $old_file = $wpdb->get_row(" + SELECT ID + FROM {$wpdb->posts} + WHERE post_title = '{$name}' + AND post_type = 'attachment' + "); + + // Delete previous file. + wp_delete_attachment($old_file->ID); + + // Make sure the new name is different by pre-pending the + // previous post id. + $filename = preg_replace("/^wpid\d+-/", "", $name); + $name = "wpid{$old_file->ID}-{$filename}"; + } + + $upload = wp_upload_bits($name, $type, $bits); + if ( ! empty($upload['error']) ) { + $errorString = sprintf(__('Could not write file %1$s (%2$s)'), $name, $upload['error']); + logIO('O', '(MW) ' . $errorString); + return new IXR_Error(500, $errorString); + } + // Construct the attachment array + // attach to post_id 0 + $post_id = 0; + $attachment = array( + 'post_title' => $name, + 'post_content' => '', + 'post_type' => 'attachment', + 'post_parent' => $post_id, + 'post_mime_type' => $type, + 'guid' => $upload[ 'url' ] + ); + + // Save the data + $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id ); + wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) ); + + return apply_filters( 'wp_handle_upload', array( 'file' => $name, 'url' => $upload[ 'url' ], 'type' => $type , 'id' => $id ) ); +} + + +/* + * Woo taxonomy + * + * Set the proper taxonomy + * + */ + +function express_woo_taxonomy($args) { + $content_struct = $args[3]; + + // Re-assign the taxonomies so they are compatible with WooThemes themes + $taxonomies = $content_struct['taxonomy']; + if (is_array($taxonomies)) { + $new_taxonomy = array(); + $woo_tags = array(); + foreach ($taxonomies as $taxonomy) { + if ($taxonomy['taxonomy'] == 'tumblog') { + foreach ($taxonomy['tags'] as $tag) { + switch (strtolower($tag)) { + case 'note': + $woo_tags[] = get_option('woo_articles_term_id'); + break; + case 'link': + $woo_tags[] = get_option('woo_links_term_id'); + break; + case 'quote': + $woo_tags[] = get_option('woo_quotes_term_id'); + break; + case 'image': + $woo_tags[] = get_option('woo_images_term_id'); + break; + default: + $woo_tags[] = $tag; + break; + } + } + $taxonomy['tags'] = implode(',', $woo_tags); + } + $new_taxonomy[] = $taxonomy; + } + $content_struct['taxonomy'] = $new_taxonomy; + $args[3] = $content_struct; + } + + return $args; +} + + +/* + * Woo Post Formats + * + * Set the proper post format + * + */ + +function express_woo_post_format($args) { + $content_struct = $args[3]; + + // Convert the taxonomies to post formats + $taxonomies = $content_struct['taxonomy']; + if (is_array($taxonomies)) { + $post_format = ''; + foreach ($taxonomies as $taxonomy) { + if ($taxonomy['taxonomy'] == 'tumblog') { + foreach ($taxonomy['tags'] as $tag) { + switch (strtolower($tag)) { + case 'note': + $post_format = 'aside'; + break; + case 'link': + $post_format = 'link'; + break; + case 'quote': + $post_format = 'quote'; + break; + case 'image': + $post_format = 'image'; + break; + default: + $post_format = 'default'; + break; + } + } + } + } + $content_struct['taxonomy'] = ''; + $content_struct['wp_post_format'] = $post_format; + $args[3] = $content_struct; + } + + return $args; +} + + +/* + * New post + * + * Sets post attachements if specified + * Sets post custom taxonomy or post format + * + */ + +function express_newPost($args) { + global $wp_xmlrpc_server; + + if (get_option('woo_tumblog_content_method') == 'post_format') { + $args = express_woo_post_format($args); + } + else { + $args = express_woo_taxonomy($args); + } + + $result = $wp_xmlrpc_server->mw_newPost($args); + $post_ID = intval($result); + if ($post_ID == 0) return $result; + + $content_struct = $args[3]; + + // Insert taxonomies + if (get_option('woo_tumblog_content_method') != 'post_format') { + if ( isset($content_struct['taxonomy']) ) { + set_new_taxonomy_tag($post_ID, $content_struct['taxonomy']); + } + } + + // Add new attachments + $attachments = $content_struct['attachments']; + if (is_array($attachments)) { + foreach ($attachments as $attachment_ID) { + $attachment_post = wp_get_single_post($attachment_ID,ARRAY_A); + extract($attachment_post, EXTR_SKIP); + $post_parent = $post_ID; + $postdata = compact('ID', 'post_parent', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); + wp_update_post($postdata); + } + } + + return $result; +} + + +/* + * Edit post + * + * Sets post attachements if specified + * Sets post custom taxonomy or post format + * + */ + +function express_editPost($args) { + global $wp_xmlrpc_server; + + if (get_option('woo_tumblog_content_method') == 'post_format') { + $args = express_woo_post_format($args); + } + else { + $args = express_woo_taxonomy($args); + } + + $result = $wp_xmlrpc_server->mw_editPost($args); + if ($result == false) return false; + + // Insert taxonomies + if (get_option('woo_tumblog_content_method') != 'post_format') { + if ( isset($content_struct['taxonomy']) ) { + set_new_taxonomy_tag($post_ID, $content_struct['taxonomy']); + } + } + + // TODO: Remove old attachments + + + // Add new attachments + $post_ID = (int)$args[0]; + $content_struct = $args[3]; + $attachments = $content_struct['attachments']; + if (is_array($attachments)) { + foreach ($attachments as $attachment_ID) { + $attachment_post = wp_get_single_post($attachment_ID,ARRAY_A); + extract($attachment_post, EXTR_SKIP); + $post_parent = $post_ID; + $postdata = compact('ID', 'post_parent', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); + wp_update_post($postdata); + } + } + + return true; +} + + +add_filter('xmlrpc_methods', 'attach_express_methods'); + +function attach_express_methods($methods) { + $methods['express.version'] = 'express_version'; + $methods['express.getPostsWithOffset'] = 'express_getPostsWithOffset'; + $methods['express.uploadFile'] = 'express_uploadFile'; + $methods['express.newPost'] = 'express_newPost'; + $methods['express.editPost'] = 'express_editPost'; + return $methods; +} + +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-framework-settings.php b/src/wp-content/themes/bloggingstream/functions/admin-framework-settings.php new file mode 100644 index 00000000..30ec7169 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-framework-settings.php @@ -0,0 +1,306 @@ + "Framework Settings", + "icon" => "general", + "type" => "heading" ); + + $framework_options[] = array( "name" => "Super User (username)", + "desc" => "Enter your username to hide the Framework Settings and Update Framework from other users. Can be reset from the WP options page under framework_woo_super_user.", + "id" => $shortname."_super_user", + "std" => "", + "class" => "text", + "type" => "text" ); + + $framework_options[] = array( "name" => "Disable SEO Menu Item", + "desc" => "Disable the SEO menu item in the theme menu.", + "id" => $shortname."_seo_disable", + "std" => "", + "type" => "checkbox" ); + + $framework_options[] = array( "name" => "Disable Sidebar Manager Menu Item", + "desc" => "Disable the Sidebar Manager menu item in the theme menu.", + "id" => $shortname."_sbm_disable", + "std" => "", + "type" => "checkbox" ); + + $framework_options[] = array( "name" => "Disable Buy Themes Menu Item", + "desc" => "Disable the Buy Themes menu item in the theme menu.", + "id" => $shortname."_buy_themes_disable", + "std" => "", + "type" => "checkbox" ); + + $framework_options[] = array( "name" => "Enable Custom Navigation", + "desc" => "Enable the old Custom Navigation menu item. Try to use WP Menus instead, as this function is outdated.", + "id" => $shortname."_woonav", + "std" => "", + "type" => "checkbox" ); + + $framework_options[] = array( "name" => "Theme Update Notification", + "desc" => "This will enable notices on your theme options page that there is an update available for your theme.", + "id" => $shortname."_theme_version_checker", + "std" => "", + "type" => "checkbox" ); + + $framework_options[] = array( "name" => "Disable Shortcodes Stylesheet", + "desc" => "This disables the output of shortcodes.css in the HEAD section of your site.", + "id" => $shortname."_disable_shortcodes", + "std" => "", + "type" => "checkbox" ); + + $framework_options[] = array( "name" => "Remove Generator Meta Tags", + "desc" => "This disables the output of generator meta tags in the HEAD section of your site.", + "id" => $shortname."_disable_generator", + "std" => "", + "type" => "checkbox" ); + + + $framework_options[] = array( "name" => "Image Placeholder", + "desc" => "Set a default image placeholder for your thumbnails. Use this if you want a default image to be shown if you haven't added a custom image to your post.", + "id" => $shortname."_default_image", + "std" => "", + "type" => "upload" ); + + $framework_options[] = array( "name" => "Branding", + "icon" => "misc", + "type" => "heading" ); + + $framework_options[] = array( "name" => "Options panel header", + "desc" => "Change the header image for the WooThemes Backend.", + "id" => $shortname."_backend_header_image", + "std" => "", + "type" => "upload" ); + + $framework_options[] = array( "name" => "Options panel icon", + "desc" => "Change the icon image for the WordPress backend sidebar.", + "id" => $shortname."_backend_icon", + "std" => "", + "type" => "upload" ); + + $framework_options[] = array( "name" => "WordPress login logo", + "desc" => "Change the logo image for the WordPress login page.", + "id" => $shortname."_custom_login_logo", + "std" => "", + "type" => "upload" ); + + $framework_options[] = array( "name" => "Import / Export", + "icon" => "misc", + "type" => "heading" ); + + $framework_options[] = array( "name" => "Import Options", + "desc" => "Import the options from another installation of this theme.", + "id" => $shortname."_import_options", + "std" => "", + "type" => "textarea" ); + + //Create, Encrypt and Update the Saved Settings + global $wpdb; + delete_option( 'framework_woo_export_options' ); + $options = get_option( 'woo_template' ); + $query_inner = ''; + $count = 0; + foreach( $options as $option ) { + + if(isset($option['id'])){ + $count++; + $option_id = $option['id']; + + if($count > 1){ $query_inner .= ' OR '; } + $query_inner .= "option_name = '$option_id'"; + + if ( is_array( $option['type'] ) ) { + foreach ( $option['type'] as $o ) { + if($count > 1){ $query_inner .= ' OR '; } + if ( isset( $o['id'] ) ) { + $option_id = $o['id']; + $query_inner .= "option_name = '$option_id'"; + } + } + } + + } + + } + + // Add Sidebar Manager data to the WooFramework exporter. + $query_inner .= " OR option_name = 'sbm_woo_sbm_options'"; + + // Allow child themes/plugins to add their own data to the exporter. + $query_inner = apply_filters( 'wooframework_export_query_inner', $query_inner ); + + $query = "SELECT * FROM $wpdb->options WHERE $query_inner"; + + $results = $wpdb->get_results($query); + + foreach ($results as $result){ + + $output[$result->option_name] = $result->option_value; + + } // End FOREACH Loop + + $output = serialize($output); + + $framework_options[] = array( "name" => "Export Options", + "desc" => "Export the options to another installation of this theme, or to keep a backup of your options.", + "id" => $shortname."_export_options", + "std" => base64_encode($output), + "type" => "textarea" ); + +/* + $framework_options[] = array( "name" => "Font Stacks (Beta)", + "icon" => "typography", + "type" => "heading" ); + + $framework_options[] = array( "name" => "Font Stack Builder", + "desc" => "Use the font stack builder to add your own custom font stacks to your theme. + To create a new stack, fill in the name and a CSS ready font stack. + Once you have added a stack you can select it from the font menu on any of the + Typography settings in your theme options.", + "id" => $shortname."_font_stack", + "std" => "Added Font Stacks", + "type" => "string_builder" ); +*/ + + global $wp_version; + + if ( $wp_version >= '3.1' ) { + + $framework_options[] = array( "name" => "Admin Bar", + "icon" => "header", + "type" => "heading" ); + + $framework_options[] = array( "name" => "Disable WordPress Admin Bar", + "desc" => "Disable the WordPress Admin Bar.", + "id" => $shortname."_admin_bar_disable", + "std" => "", + "type" => "checkbox" ); + + $framework_options[] = array( "name" => "Enable the WooFramework Admin Bar enhancements", + "desc" => "Enable several WooFramework-specific enhancements to the WordPress Admin Bar, such as custom navigation items for 'Theme Options'.", + "id" => $shortname."_admin_bar_enhancements", + "std" => "", + "type" => "checkbox" ); + + } + + update_option( 'woo_framework_template', $framework_options ); + + ?> + +
    +
    Options Updated
    +
    Options Reset
    +
    + + + + + + +
    +
    +
      + +
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + +
    + + +
    + +
    +
    + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-functions.php b/src/wp-content/themes/bloggingstream/functions/admin-functions.php new file mode 100644 index 00000000..ca768e65 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-functions.php @@ -0,0 +1,2956 @@ +ID; + } + + $thumb_id = get_post_meta($id,'_thumbnail_id',true); + + // Set alignment + if ( $alignment == '') + $alignment = get_post_meta($id, '_image_alignment', true); + + // Get standard sizes + if ( !$width && !$height ) { + $width = '100'; + $height = '100'; + } + + /* ------------------------------------------------------------------------- */ + /* FIND IMAGE TO USE */ + /* ------------------------------------------------------------------------- */ + + // When a custom image is sent through + if ( $src != '' ) { + $custom_field = $src; + $link = 'img'; + + // WP 2.9 Post Thumbnail support + } elseif ( get_option( 'woo_post_image_support') == 'true' AND !empty($thumb_id) ) { + + if ( get_option( 'woo_pis_resize') == "true") { + + // Dynamically resize the post thumbnail + $vt_crop = get_option( 'woo_pis_hard_crop' ); + if ($vt_crop == "true") $vt_crop = true; else $vt_crop = false; + $vt_image = vt_resize( $thumb_id, '', $width, $height, $vt_crop ); + + // Set fields for output + $custom_field = $vt_image['url']; + $width = $vt_image['width']; + $height = $vt_image['height']; + + } else { + // Use predefined size string + if ( $size ) + $thumb_size = $size; + else + $thumb_size = array($width,$height); + + $img_link = get_the_post_thumbnail($id,$thumb_size,array( 'class' => 'woo-image ' . $class)); + } + + // Grab the image from custom field + } else { + $custom_field = get_post_meta($id, $key, true); + } + + // Automatic Image Thumbs - get first image from post attachment + if ( empty($custom_field) && get_option( 'woo_auto_img') == 'true' && empty($img_link) && !(is_singular() AND in_the_loop() AND $link == "src") ) { + + if( $offset >= 1 ) + $repeat = $repeat + $offset; + + $attachments = get_children( array( 'post_parent' => $id, + 'numberposts' => $repeat, + 'post_type' => 'attachment', + 'post_mime_type' => 'image', + 'order' => 'DESC', + 'orderby' => 'menu_order date') + ); + + // Search for and get the post attachment + if ( !empty($attachments) ) { + + $counter = -1; + $size = 'large'; + foreach ( $attachments as $att_id => $attachment ) { + $counter++; + if ( $counter < $offset ) + continue; + + if ( get_option( 'woo_post_image_support' ) == "true" AND get_option( 'woo_pis_resize') == "true" ) { + + // Dynamically resize the post thumbnail + $vt_crop = get_option( 'woo_pis_hard_crop' ); + if ($vt_crop == "true") $vt_crop = true; else $vt_crop = false; + $vt_image = vt_resize( $att_id, '', $width, $height, $vt_crop ); + + // Set fields for output + $custom_field = $vt_image['url']; + $width = $vt_image['width']; + $height = $vt_image['height']; + + } else { + + $src = wp_get_attachment_image_src($att_id, $size, true); + $custom_field = $src[0]; + $attachment_id[] = $att_id; + $src_arr[] = $custom_field; + + } + $thumb_id = $att_id; + $is_auto_image = true; + } + + // Get the first img tag from content + } else { + + $first_img = ''; + $post = get_post($id); + ob_start(); + ob_end_clean(); + $output = preg_match_all( '//i', $post->post_content, $matches); + if ( !empty($matches[1][0]) ) { + + // Save Image URL + $custom_field = $matches[1][0]; + + // Search for ALT tag + $output = preg_match_all( '//i', $post->post_content, $matches); + if ( !empty($matches[1][0]) ) { + $alt = $matches[1][0]; + } + } + + } + + } + + // Check if there is YouTube embed + if ( empty($custom_field) && empty($img_link) ) { + $embed = get_post_meta($id, "embed", true); + if ( $embed ) + $custom_field = woo_get_video_image($embed); + } + + // Return if there is no attachment or custom field set + if ( empty($custom_field) && empty($img_link) ) { + + // Check if default placeholder image is uploaded + $placeholder = get_option( 'framework_woo_default_image' ); + if ( $placeholder && !(is_singular() AND in_the_loop()) ) { + $custom_field = $placeholder; + + // Resize the placeholder if + if ( get_option( 'woo_post_image_support' ) == "true" AND get_option( 'woo_pis_resize') == "true") { + + // Dynamically resize the post thumbnail + $vt_crop = get_option( 'woo_pis_hard_crop' ); + if ($vt_crop == "true") $vt_crop = true; else $vt_crop = false; + $vt_image = vt_resize( '', $placeholder, $width, $height, $vt_crop ); + + // Set fields for output + $custom_field = $vt_image['url']; + $width = $vt_image['width']; + $height = $vt_image['height']; + + } + + } else { + return; + } + + } + + if(empty($src_arr) && empty($img_link)){ $src_arr[] = $custom_field; } + + /* ------------------------------------------------------------------------- */ + /* BEGIN OUTPUT */ + /* ------------------------------------------------------------------------- */ + + $output = ''; + + // Set output height and width + $set_width = ' width="' . $width .'" '; + $set_height = ' height="' . $height .'" '; + if($height == null OR $height == '') $set_height = ''; + + // Set standard class + if ( $class ) $class = 'woo-image ' . $class; else $class = 'woo-image'; + + // Do check to verify if images are smaller then specified. + if($force == true){ $set_width = ''; $set_height = ''; } + + // WP Post Thumbnail + if(!empty($img_link) ){ + + if( $link == 'img' ) { // Output the image without anchors + $output .= $before; + $output .= $img_link; + $output .= $after; + + } elseif( $link == 'url' ) { // Output the large image + + $src = wp_get_attachment_image_src($thumb_id, 'large', true); + $custom_field = $src[0]; + $output .= $custom_field; + + } else { // Default - output with link + + if ( ( is_single() OR is_page() ) AND $single == false ) { + $rel = 'rel="lightbox"'; + $href = false; + } else { + $href = get_permalink($id); + $rel = ''; + } + + $title = 'title="' . get_the_title($id) .'"'; + + $output .= $before; + if($href == false){ + $output .= $img_link; + } else { + $output .= '' . $img_link . ''; + } + + $output .= $after; + } + } + + // Use thumb.php to resize. Skip if image has been natively resized with vt_resize. + elseif ( get_option( 'woo_resize') == 'true' && empty($vt_image['url']) ) { + + foreach($src_arr as $key => $custom_field){ + + // Clean the image URL + $href = $custom_field; + $custom_field = cleanSource( $custom_field ); + + // Check if WPMU and set correct path AND that image isn't external + if ( function_exists( 'get_current_site') && strpos($custom_field,"http://") !== 0 ) { + get_current_site(); + //global $blog_id; Breaks with WP3 MS + if ( !$blog_id ) { + global $current_blog; + $blog_id = $current_blog->blog_id; + } + if ( isset($blog_id) && $blog_id > 0 ) { + $imageParts = explode( 'files/', $custom_field ); + if ( isset($imageParts[1]) ) + $custom_field = '/blogs.dir/' . $blog_id . '/files/' . $imageParts[1]; + } + } + + //Set the ID to the Attachment's ID if it is an attachment + if($is_auto_image == true){ + $quick_id = $attachment_id[$key]; + } else { + $quick_id = $id; + } + + //Set custom meta + if ($meta) { + $alt = $meta; + $title = 'title="'. $meta .'"'; + } else { + if ($alt == '' AND get_post_meta($thumb_id, '_wp_attachment_image_alt', true) ) + $alt = get_post_meta($thumb_id, '_wp_attachment_image_alt', true); + else + $alt = get_the_title($quick_id); + $title = 'title="'. get_the_title($quick_id) .'"'; + } + + // Set alignment parameter + if ($alignment <> '') + $alignment = '&a='.$alignment; + + $img_link = ''.$alt.''; + + if( $link == 'img' ) { // Just output the image + $output .= $before; + $output .= $img_link; + $output .= $after; + + } elseif( $link == 'url' ) { // Output the image without anchors + + if($is_auto_image == true){ + $src = wp_get_attachment_image_src($thumb_id, 'large', true); + $custom_field = $src[0]; + } + $output .= $custom_field; + + } else { // Default - output with link + + if ( ( is_single() OR is_page() ) AND $single == false ) { + $rel = 'rel="lightbox"'; + } else { + $href = get_permalink($id); + $rel = ''; + } + + $output .= $before; + $output .= '' . $img_link . ''; + $output .= $after; + } + } + + // No dynamic resizing + } else { + + foreach($src_arr as $key => $custom_field){ + + //Set the ID to the Attachment's ID if it is an attachment + if($is_auto_image == true AND isset($attachment_id[$key])){ + $quick_id = $attachment_id[$key]; + } else { + $quick_id = $id; + } + + //Set custom meta + if ($meta) { + $alt = $meta; + $title = 'title="'. $meta .'"'; + } else { + if ($alt == '') $alt = get_post_meta($thumb_id, '_wp_attachment_image_alt', true); + $title = 'title="'. get_the_title($quick_id) .'"'; + } + + $img_link = ''. $alt .''; + + if ( $link == 'img' ) { // Just output the image + $output .= $before; + $output .= $img_link; + $output .= $after; + + } elseif( $link == 'url' ) { // Output the URL to original image + if ( $vt_image['url'] || $is_auto_image ) { + $src = wp_get_attachment_image_src($thumb_id, 'full', true); + $custom_field = $src[0]; + } + $output .= $custom_field; + + } else { // Default - output with link + + if ( ( is_single() OR is_page() ) AND $single == false ) { + + // Link to the large image if single post + if ( $vt_image['url'] || $is_auto_image ) { + $src = wp_get_attachment_image_src($thumb_id, 'full', true); + $custom_field = $src[0]; + } + + $href = $custom_field; + $rel = 'rel="lightbox"'; + } else { + $href = get_permalink($id); + $rel = ''; + } + + $output .= $before; + $output .= '' . $img_link . ''; + $output .= $after; + } + } + } + + // Return or echo the output + if ( $return == TRUE ) + return $output; + else + echo $output; // Done + +} + +/* Get thumbnail from Video Embed code */ + +if (!function_exists( 'woo_get_video_image')) { + function woo_get_video_image($embed) { + + // YouTube - get the video code if this is an embed code (old embed) + preg_match( '/youtube\.com\/v\/([\w\-]+)/', $embed, $match); + + // YouTube - if old embed returned an empty ID, try capuring the ID from the new iframe embed + if($match[1] == '') + preg_match( '/youtube\.com\/embed\/([\w\-]+)/', $embed, $match); + + // YouTube - if it is not an embed code, get the video code from the youtube URL + if($match[1] == '') + preg_match( '/v\=(.+)&/',$embed ,$match); + + // YouTube - get the corresponding thumbnail images + if($match[1] != '') + $video_thumb = "http://img.youtube.com/vi/".$match[1]."/0.jpg"; + + // return whichever thumbnail image you would like to retrieve + return $video_thumb; + } +} + + +/*-----------------------------------------------------------------------------------*/ +/* vt_resize - Resize images dynamically using wp built in functions +/*-----------------------------------------------------------------------------------*/ +/* + * Resize images dynamically using wp built in functions + * Victor Teixeira + * + * php 5.2+ + * + * Exemplo de uso: + * + * + * + * + * @param int $attach_id + * @param string $img_url + * @param int $width + * @param int $height + * @param bool $crop + * @return array + */ +if ( !function_exists( 'vt_resize') ) { + function vt_resize( $attach_id = null, $img_url = null, $width, $height, $crop = false ) { + + // this is an attachment, so we have the ID + if ( $attach_id ) { + + $image_src = wp_get_attachment_image_src( $attach_id, 'full' ); + $file_path = get_attached_file( $attach_id ); + + // this is not an attachment, let's use the image url + } else if ( $img_url ) { + + $file_path = parse_url( $img_url ); + $file_path = $_SERVER['DOCUMENT_ROOT'] . $file_path['path']; + + //$file_path = ltrim( $file_path['path'], '/' ); + //$file_path = rtrim( ABSPATH, '/' ).$file_path['path']; + + $orig_size = getimagesize( $file_path ); + + $image_src[0] = $img_url; + $image_src[1] = $orig_size[0]; + $image_src[2] = $orig_size[1]; + } + + $file_info = pathinfo( $file_path ); + + // check if file exists + $base_file = $file_info['dirname'].'/'.$file_info['filename'].'.'.$file_info['extension']; + if ( !file_exists($base_file) ) + return; + + $extension = '.'. $file_info['extension']; + + // the image path without the extension + $no_ext_path = $file_info['dirname'].'/'.$file_info['filename']; + + $cropped_img_path = $no_ext_path.'-'.$width.'x'.$height.$extension; + + // checking if the file size is larger than the target size + // if it is smaller or the same size, stop right here and return + if ( $image_src[1] > $width ) { + + // the file is larger, check if the resized version already exists (for $crop = true but will also work for $crop = false if the sizes match) + if ( file_exists( $cropped_img_path ) ) { + + $cropped_img_url = str_replace( basename( $image_src[0] ), basename( $cropped_img_path ), $image_src[0] ); + + $vt_image = array ( + 'url' => $cropped_img_url, + 'width' => $width, + 'height' => $height + ); + + return $vt_image; + } + + // $crop = false + if ( $crop == false ) { + + // calculate the size proportionaly + $proportional_size = wp_constrain_dimensions( $image_src[1], $image_src[2], $width, $height ); + $resized_img_path = $no_ext_path.'-'.$proportional_size[0].'x'.$proportional_size[1].$extension; + + // checking if the file already exists + if ( file_exists( $resized_img_path ) ) { + + $resized_img_url = str_replace( basename( $image_src[0] ), basename( $resized_img_path ), $image_src[0] ); + + $vt_image = array ( + 'url' => $resized_img_url, + 'width' => $proportional_size[0], + 'height' => $proportional_size[1] + ); + + return $vt_image; + } + } + + // check if image width is smaller than set width + $img_size = getimagesize( $file_path ); + if ( $img_size[0] <= $width ) $width = $img_size[0]; + + // no cache files - let's finally resize it + $new_img_path = image_resize( $file_path, $width, $height, $crop ); + $new_img_size = getimagesize( $new_img_path ); + $new_img = str_replace( basename( $image_src[0] ), basename( $new_img_path ), $image_src[0] ); + + // resized output + $vt_image = array ( + 'url' => $new_img, + 'width' => $new_img_size[0], + 'height' => $new_img_size[1] + ); + + return $vt_image; + } + + // default output - without resizing + $vt_image = array ( + 'url' => $image_src[0], + 'width' => $width, + 'height' => $height + ); + + return $vt_image; + } +} + + +/*-----------------------------------------------------------------------------------*/ +/* Depreciated - woo_get_image - Get Image from custom field */ +/*-----------------------------------------------------------------------------------*/ + +// Depreciated +function woo_get_image($key = 'image', $width = null, $height = null, $class = "thumbnail", $quality = 90,$id = null,$link = 'src',$repeat = 1,$offset = 0,$before = '', $after = '',$single = false, $force = false, $return = false) { + // Run new function + woo_image( 'key='.$key.'&width='.$width.'&height='.$height.'&class='.$class.'&quality='.$quality.'&id='.$id.'&link='.$link.'&repeat='.$repeat.'&offset='.$offset.'&before='.$before.'&after='.$after.'&single='.$single.'&fore='.$force.'&return='.$return ); + return; + +} + + + +/*-----------------------------------------------------------------------------------*/ +/* woo_embed - Get Video embed code from custom field */ +/*-----------------------------------------------------------------------------------*/ + +/* +Get Video +This function gets the embed code from the custom field +Parameters: + $key = Custom field key eg. "embed" + $width = Set width manually without using $type + $height = Set height manually without using $type + $class = Custom class to apply to wrapping div + $id = ID from post to pull custom field from +*/ + +function woo_embed($args) { + + //Defaults + $key = 'embed'; + $width = null; + $height = null; + $class = 'video'; + $id = null; + + if ( !is_array($args) ) + parse_str( $args, $args ); + + extract($args); + + if(empty($id)) + { + global $post; + $id = $post->ID; + } + + +$custom_field = get_post_meta($id, $key, true); + +if ($custom_field) : + + $custom_field = html_entity_decode( $custom_field ); // Decode HTML entities. + + $org_width = $width; + $org_height = $height; + $calculated_height = ''; + + // Get custom width and height + $custom_width = get_post_meta($id, 'width', true); + $custom_height = get_post_meta($id, 'height', true); + + //Dynamic Height Calculation + if ($org_height == '' && $org_width != '') { + $raw_values = explode( " ", $custom_field); + + foreach ($raw_values as $raw) { + $embed_params = explode( "=",$raw); + if ($embed_params[0] == 'width') { + $embed_width = ereg_replace( "[^0-9]", "", $embed_params[1]); + } + elseif ($embed_params[0] == 'height') { + $embed_height = ereg_replace( "[^0-9]", "", $embed_params[1]); + } + } + + $float_width = floatval($embed_width); + $float_height = floatval($embed_height); + @$float_ratio = $float_height / $float_width; + $calculated_height = intval($float_ratio * $width); + } + + // Set values: width="XXX", height="XXX" + if ( !$custom_width ) $width = 'width="'.$width.'"'; else $width = 'width="'.$custom_width.'"'; + if ( $height == '' ) { $height = 'height="'.$calculated_height.'"'; } else { if ( !$custom_height ) { $height = 'height="'.$height.'"'; } else { $height = 'height="'.$custom_height.'"'; } } + $custom_field = stripslashes($custom_field); + $custom_field = preg_replace( '/width="([0-9]*)"/' , $width , $custom_field ); + $custom_field = preg_replace( '/height="([0-9]*)"/' , $height , $custom_field ); + + // Set values: width:XXXpx, height:XXXpx + if ( !$custom_width ) $width = 'width:'.$org_width.'px'; else $width = 'width:'.$custom_width.'px'; + if ( $height == '' ) { $height = 'height:'.$calculated_height.'px'; } else { if ( !$custom_height ) { $height = 'height:'.$org_height.'px'; } else { $height = 'height:'.$custom_height.'px'; } } + $custom_field = stripslashes($custom_field); + $custom_field = preg_replace( '/width:([0-9]*)px/' , $width , $custom_field ); + $custom_field = preg_replace( '/height:([0-9]*)px/' , $height , $custom_field ); + + // Suckerfish menu hack + $custom_field = str_replace( '' . $custom_field . ''; + + return $output; + +else : + + return false; + +endif; + +} + +/*-----------------------------------------------------------------------------------*/ +/* Depreciated - woo_get_embed - Get Video embed code from custom field */ +/*-----------------------------------------------------------------------------------*/ + +// Depreciated +function woo_get_embed($key = 'embed', $width, $height, $class = 'video', $id = null) { + // Run new function + return woo_embed( 'key='.$key.'&width='.$width.'&height='.$height.'&class='.$class.'&id='.$id ); + +} + + + +/*-----------------------------------------------------------------------------------*/ +/* Woo Show Page Menu */ +/*-----------------------------------------------------------------------------------*/ + +// Show menu in header.php +// Exlude the pages from the slider +function woo_show_pagemenu( $exclude="" ) { + // Split the featured pages from the options, and put in an array + if ( get_option( 'woo_ex_featpages') ) { + $menupages = get_option( 'woo_featpages' ); + $exclude = $menupages . ',' . $exclude; + } + + $pages = wp_list_pages( 'sort_column=menu_order&title_li=&echo=0&depth=1&exclude='.$exclude); + $pages = preg_replace( '%]+)>%U','', $pages); + $pages = str_replace( '','', $pages); + echo $pages; +} + + + +/*-----------------------------------------------------------------------------------*/ +/* Get the style path currently selected */ +/*-----------------------------------------------------------------------------------*/ + +function woo_style_path() { + + $return = ''; + + $style = $_REQUEST['style']; + + // Sanitize request input. + $style = strtolower( trim( strip_tags( $style ) ) ); + + if ( $style != '' ) { + + $style_path = $style; + + } else { + + $stylesheet = get_option( 'woo_alt_stylesheet' ); + + // Prevent against an empty return to $stylesheet. + + if ( $stylesheet == '' ) { + + $stylesheet = 'default.css'; + + } // End IF Statement + + $style_path = str_replace( '.css', '', $stylesheet ); + + } // End IF Statement + + if ( $style_path == 'default' ) { + + $return = 'images'; + + } else { + + $return = 'styles/' . $style_path; + + } // End IF Statement + + echo $return; + +} // End woo_style_path() + + +/*-----------------------------------------------------------------------------------*/ +/* Get page ID */ +/*-----------------------------------------------------------------------------------*/ +function get_page_id($page_slug){ + $page_id = get_page_by_path($page_slug); + if ($page_id) { + return $page_id->ID; + } else { + return null; + } + +} + +/*-----------------------------------------------------------------------------------*/ +/* Tidy up the image source url */ +/*-----------------------------------------------------------------------------------*/ +function cleanSource($src) { + + // remove slash from start of string + if(strpos($src, "/") == 0) { + $src = substr($src, -(strlen($src) - 1)); + } + + // Check if same domain so it doesn't strip external sites + $host = str_replace( 'www.', '', $_SERVER['HTTP_HOST']); + if ( !strpos($src,$host) ) + return $src; + + + $regex = "/^((ht|f)tp(s|):\/\/)(www\.|)" . $host . "/i"; + $src = preg_replace ($regex, '', $src); + $src = htmlentities ($src); + + // remove slash from start of string + if (strpos($src, '/') === 0) { + $src = substr ($src, -(strlen($src) - 1)); + } + + return $src; +} + + + +/*-----------------------------------------------------------------------------------*/ +/* Show image in RSS feed */ +/* Original code by Justin Tadlock http://justintadlock.com */ +/*-----------------------------------------------------------------------------------*/ +if (get_option( 'woo_rss_thumb') == "true") + add_filter( 'the_content', 'add_image_RSS' ); + +function add_image_RSS( $content ) { + + global $post, $id; + $blog_key = substr( md5( home_url( '/' ) ), 0, 16 ); + if ( ! is_feed() ) return $content; + + // Get the "image" from custom field + $image = get_post_meta($post->ID, 'image', $single = true); + $image_width = '240'; + + // If there's an image, display the image with the content + if($image !== '') { + $content = '

    + +

    ' . $content; + return $content; + } + + // If there's not an image, just display the content + else { + $content = $content; + return $content; + } +} + + + +/*-----------------------------------------------------------------------------------*/ +/* Show analytics code in footer */ +/*-----------------------------------------------------------------------------------*/ +function woo_analytics(){ + $output = get_option( 'woo_google_analytics' ); + if ( $output <> "" ) + echo stripslashes($output) . "\n"; +} +add_action( 'wp_footer','woo_analytics' ); + + + +/*-----------------------------------------------------------------------------------*/ +/* Browser detection body_class() output */ +/*-----------------------------------------------------------------------------------*/ +add_filter( 'body_class','browser_body_class' ); +function browser_body_class($classes) { + global $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone; + + if($is_lynx) $classes[] = 'lynx'; + elseif($is_gecko) $classes[] = 'gecko'; + elseif($is_opera) $classes[] = 'opera'; + elseif($is_NS4) $classes[] = 'ns4'; + elseif($is_safari) $classes[] = 'safari'; + elseif($is_chrome) $classes[] = 'chrome'; + elseif($is_IE) { + $browser = $_SERVER['HTTP_USER_AGENT']; + $browser = substr( "$browser", 25, 8); + if ($browser == "MSIE 7.0" ) { + $classes[] = 'ie7'; + $classes[] = 'ie'; + } elseif ($browser == "MSIE 6.0" ) { + $classes[] = 'ie6'; + $classes[] = 'ie'; + } elseif ($browser == "MSIE 8.0" ) { + $classes[] = 'ie8'; + $classes[] = 'ie'; + } elseif ($browser == "MSIE 9.0" ) { + $classes[] = 'ie8'; + $classes[] = 'ie'; + } else { + $classes[] = 'ie'; + } + } + else $classes[] = 'unknown'; + + if($is_iphone) $classes[] = 'iphone'; + return $classes; +} + +/*-----------------------------------------------------------------------------------*/ +/* Twitter's Blogger.js output for Twitter widgets */ +/*-----------------------------------------------------------------------------------*/ + +if ( !function_exists( 'woo_twitter_script') ) { + function woo_twitter_script($unique_id,$username,$limit) { + ?> + + + postmeta WHERE meta_key = '_wp_page_template' AND meta_value = '$filename' GROUP BY meta_value"; + $results = $wpdb->get_row($wpdb->prepare($query),'ARRAY_A' ); // Select thrid coloumn accross + + if(empty($results)) + return false; + + $post_id = $results['post_id']; + $trash = get_post_status($post_id); // Check for trash + + if($trash != 'trash') + return true; + else + return false; + + } else { + return false; // No $filename argument was set + } + +} +/*-----------------------------------------------------------------------------------*/ +/* WooFramework Update Page */ +/*-----------------------------------------------------------------------------------*/ + +function woothemes_framework_update_page(){ + $method = get_filesystem_method(); + $to = ABSPATH . 'wp-content/themes/' . get_option( 'template') . "/functions/"; + if(isset($_POST['password'])){ + + $cred = $_POST; + $filesystem = WP_Filesystem($cred); + + } + elseif(isset($_POST['woo_ftp_cred'])){ + + $cred = unserialize(base64_decode($_POST['woo_ftp_cred'])); + $filesystem = WP_Filesystem($cred); + + } else { + + $filesystem = WP_Filesystem(); + + }; + $url = admin_url( 'admin.php?page=woothemes_framework_update' ); + ?> +
    + + + + +

    +

    Framework Update

    + +
    + + + +

    A new version of WooFramework is available.

    +

    This updater will collect a file from the WooThemes.com server. It will download and extract the files to your current theme's functions folder.

    +

    We recommend backing up your theme files before updating. Only upgrade the WooFramework if necessary.

    +

    Your version:

    + +

    Current Version:

    + + + +

    You have the latest version of WooFramework

    +

    Your version:

    + + + + +
    + +
    +

    Failed: Filesystem preventing downloads. ( ". $method .")

    "; + } + add_action( 'admin_notices', 'woothemes_framework_update_filesystem_warning' ); + return; + } + if(isset($_REQUEST['woo_update_save'])){ + + // Sanitize action being requested. + $_action = strtolower( trim( strip_tags( $_REQUEST['woo_update_save'] ) ) ); + + if( $_action == 'save' ){ + + $temp_file_addr = download_url( 'http://www.woothemes.com/updates/framework.zip' ); + + if ( is_wp_error($temp_file_addr) ) { + + $error = $temp_file_addr->get_error_code(); + + if($error == 'http_no_url') { + //The source file was not found or is invalid + function woothemes_framework_update_missing_source_warning() { + echo "

    Failed: Invalid URL Provided

    "; + } + add_action( 'admin_notices', 'woothemes_framework_update_missing_source_warning' ); + } else { + function woothemes_framework_update_other_upload_warning() { + echo "

    Failed: Upload - $error

    "; + } + add_action( 'admin_notices', 'woothemes_framework_update_other_upload_warning' ); + + } + + return; + + } + //Unzipp it + global $wp_filesystem; + $to = $wp_filesystem->wp_content_dir() . "/themes/" . get_option( 'template') . "/functions/"; + + $dounzip = unzip_file($temp_file_addr, $to); + + unlink($temp_file_addr); // Delete Temp File + + if ( is_wp_error($dounzip) ) { + + //DEBUG + $error = $dounzip->get_error_code(); + $data = $dounzip->get_error_data($error); + //echo $error. ' - '; + //print_r($data); + + if($error == 'incompatible_archive') { + //The source file was not found or is invalid + function woothemes_framework_update_no_archive_warning() { + echo "

    Failed: Incompatible archive

    "; + } + add_action( 'admin_notices', 'woothemes_framework_update_no_archive_warning' ); + } + if($error == 'empty_archive') { + function woothemes_framework_update_empty_archive_warning() { + echo "

    Failed: Empty Archive

    "; + } + add_action( 'admin_notices', 'woothemes_framework_update_empty_archive_warning' ); + } + if($error == 'mkdir_failed') { + function woothemes_framework_update_mkdir_warning() { + echo "

    Failed: mkdir Failure

    "; + } + add_action( 'admin_notices', 'woothemes_framework_update_mkdir_warning' ); + } + if($error == 'copy_failed') { + function woothemes_framework_update_copy_fail_warning() { + echo "

    Failed: Copy Failed

    "; + } + add_action( 'admin_notices', 'woothemes_framework_update_copy_fail_warning' ); + } + + return; + + } + + function woothemes_framework_updated_success() { + echo "

    New framework successfully downloaded, extracted and updated.

    "; + } + add_action( 'admin_notices', 'woothemes_framework_updated_success' ); + + } + } + } //End user input save part of the update + } +} + +add_action( 'admin_head','woothemes_framework_update_head' ); + +/*-----------------------------------------------------------------------------------*/ +/* WooFramework Version Getter */ +/*-----------------------------------------------------------------------------------*/ + +function woo_get_fw_version($url = ''){ + + if(!empty($url)){ + $fw_url = $url; + } else { + $fw_url = 'http://www.woothemes.com/updates/functions-changelog.txt'; + } + + $temp_file_addr = download_url($fw_url); + if(!is_wp_error($temp_file_addr) && $file_contents = file($temp_file_addr)) { + foreach ($file_contents as $line_num => $line) { + + $current_line = $line; + + if($line_num > 1){ // Not the first or second... dodgy :P + + if (preg_match( '/^[0-9]/', $line)) { + + $current_line = stristr($current_line,"version" ); + $current_line = preg_replace( '~[^0-9,.]~','',$current_line); + $output = $current_line; + break; + } + } + } + unlink($temp_file_addr); + return $output; + + + } else { + return 'Currently Unavailable'; + } + +} + +/*-----------------------------------------------------------------------------------*/ +/* Woo URL shortener */ +/*-----------------------------------------------------------------------------------*/ + +function woo_short_url($url) { + $service = get_option( 'woo_url_shorten' ); + $bitlyapilogin = get_option( 'woo_bitly_api_login' );; + $bitlyapikey = get_option( 'woo_bitly_api_key' );; + if (isset($service)) { + switch ($service) + { + case 'TinyURL': + $shorturl = getTinyUrl($url); + break; + case 'Bit.ly': + if (isset($bitlyapilogin) && isset($bitlyapikey) && ($bitlyapilogin != '') && ($bitlyapikey != '')) { + $shorturl = make_bitly_url($url,$bitlyapilogin,$bitlyapikey,'json' ); + } + else { + $shorturl = getTinyUrl($url); + } + break; + case 'Off': + $shorturl = $url; + break; + default: + $shorturl = $url; + break; + } + } + else { + $shorturl = $url; + } + return $shorturl; +} + +//TinyURL +function getTinyUrl($url) { + $tinyurl = file_get_contents_curl( "http://tinyurl.com/api-create.php?url=".$url); + return $tinyurl; +} + +//Bit.ly +function make_bitly_url($url,$login,$appkey,$format = 'xml',$version = '2.0.1') +{ + //create the URL + $bitly = 'http://api.bit.ly/shorten?version='.$version.'&longUrl='.urlencode($url).'&login='.$login.'&apiKey='.$appkey.'&format='.$format; + + //get the url + //could also use cURL here + $response = file_get_contents_curl($bitly); + + //parse depending on desired format + if(strtolower($format) == 'json') + { + $json = @json_decode($response,true); + return $json['results'][$url]['shortUrl']; + } + else //xml + { + $xml = simplexml_load_string($response); + return 'http://bit.ly/'.$xml->results->nodeKeyVal->hash; + } +} + +//Alternative CURL function +function file_get_contents_curl($url) { + if (_iscurlinstalled()) { + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Set curl to return the data instead of printing it to the browser. + curl_setopt($ch, CURLOPT_URL, $url); + + $data = curl_exec($ch); + + if ($data === FALSE) { + $data = "cURL Error: " . curl_error($ch); + } + + curl_close($ch); + } else { + $data = $url; + } + return $data; +} + +// Checks for presence of the cURL extension. +function _iscurlinstalled() { + if (in_array ( 'curl', get_loaded_extensions())) { + if (function_exists( 'curl_init')) { + return true; + } else { + return false; + } + } + else{ + if (function_exists( 'curl_init')) { + return true; + } else { + return false; + } + } +} + +/*-----------------------------------------------------------------------------------*/ +/* woo_title() */ +/*-----------------------------------------------------------------------------------*/ + +function woo_title(){ + + global $post; + $layout = ''; + + // Setup the variable that will, ultimately, hold the title value. + $title = ''; + + //Taxonomy Details WP 3.0 only + if ( function_exists( 'get_taxonomies') ) : + global $wp_query; + $taxonomy_obj = $wp_query->get_queried_object(); + if ( ! empty( $taxonomy_obj->name ) && function_exists( 'is_post_type_archive' ) && ! is_post_type_archive() ) : + $taxonomy_nice_name = $taxonomy_obj->name; + $term_id = $taxonomy_obj->term_taxonomy_id; + $taxonomy_short_name = $taxonomy_obj->taxonomy; + $taxonomy_top_level_items = get_taxonomies(array( 'name' => $taxonomy_short_name), 'objects' ); + $taxonomy_top_level_item = $taxonomy_top_level_items[$taxonomy_short_name]->label; + elseif ( ! empty( $taxonomy_obj->name ) && function_exists( 'is_post_type_archive' ) && is_post_type_archive() ) : + $archive_name = $taxonomy_obj->label; + endif; + endif; + + //3rd Party Plugins + $use_third_party_data = false; + if(get_option( 'seo_woo_use_third_party_data') == 'true'){ + $use_third_party_data = true; + } + + if( + ( + class_exists( 'All_in_One_SEO_Pack') || + class_exists( 'Headspace_Plugin') || + class_exists( 'WPSEO_Admin' ) || + class_exists( 'WPSEO_Frontend' ) + ) + && + ( $use_third_party_data != true ) ) { wp_title(); return; } + + $sep = get_option( 'seo_woo_seperator' ); + if(empty($sep)) { $sep = " | ";} else { $sep = ' ' . $sep . ' ';} + $use_wp_title = get_option( 'seo_woo_wp_title' ); + $home_layout = get_option( 'seo_woo_home_layout' ); + $single_layout = get_option( 'seo_woo_single_layout' ); + $page_layout = get_option( 'seo_woo_page_layout' ); + $archive_layout = get_option( 'seo_woo_archive_layout' ); + + + $output = ''; + if($use_wp_title == 'true'){ + + if(is_home() OR is_front_page()){ + switch ($home_layout){ + case 'a': $output = get_bloginfo( 'name') . $sep . get_bloginfo( 'description' ); + break; + case 'b': $output = get_bloginfo( 'name' ); + break; + case 'c': $output = get_bloginfo( 'description' ); + break; + } + if(is_paged()){ + $paged_var = get_query_var( 'paged' ); + if(get_option( 'seo_woo_paged_var_pos') == 'after'){ + + $output .= $sep . get_option( 'seo_woo_paged_var') . ' ' . $paged_var; + + } else { + + $output = get_option( 'seo_woo_paged_var') . ' ' . $paged_var . $sep . $output; + + } + + } + $output = stripslashes($output); + echo $output; + } + else { + if (is_single()) { $layout = $single_layout; } + elseif (is_page()) { $layout = $page_layout; } + elseif (is_archive()) { $layout = $archive_layout; } + elseif (is_tax()) { $layout = $archive_layout; } + elseif (is_search()) { $layout = 'search'; } + elseif (is_404()) { $layout = $single_layout; } + + + + //Check if there is a custom value added to post meta + $wooseo_title = get_post_meta($post->ID,'seo_title',true); // WooSEO + $aio_title = get_post_meta($post->ID,'_aioseop_title',true); // All-in-One SEO Pack + $headspace_title = get_post_meta($post->ID,'_headspace_page_title',true); // Headspace SEO + $wpseo_title = get_post_meta( $post->ID,'_yoast_wpseo_title', true ); // WordPress SEO + + if( get_option( 'seo_woo_wp_custom_field_title') != 'true' && is_singular() ) { + if( ! empty($wooseo_title ) ){ + $layout = 'wooseo'; + } elseif(!empty($aio_title) AND $use_third_party_data) { + $layout = 'aioseo'; + } elseif(!empty($headspace_title) AND $use_third_party_data) { + $layout = 'headspace'; + } elseif(!empty($wpseo_title) AND $use_third_party_data) { + $layout = 'wpseo'; + } + } + switch ( $layout ) { + case 'a': $output = wp_title($sep,false,true) . get_bloginfo( 'name' ); + break; + case 'b': $output = wp_title( '',false,false); + break; + case 'c': $output = get_bloginfo( 'name') . wp_title($sep,false,false); + break; + case 'd': $output = wp_title($sep,false,true) . get_bloginfo( 'description' ); + break; + case 'e': $output = get_bloginfo( 'name') . $sep . wp_title($sep,false,true) . get_bloginfo( 'description' ); + break; + case 'search': $output = get_bloginfo( 'name') . wp_title($sep,false,false); // Search is hardcoded + break; + case 'wooseo': $output = $wooseo_title; // WooSEO Title + break; + case 'aioseo': $output = $aio_title; // All-in-One SEO Pack Title + break; + case 'headspace': $output = $headspace_title; // Headspace Title + break; + case 'wpseo': $output = $wpseo_title; // WordPress SEO Title + break; + } + if(is_paged()){ + $paged_var = get_query_var( 'paged' ); + if(get_option( 'seo_woo_paged_var_pos') == 'after'){ + $output .= $sep . get_option( 'seo_woo_paged_var') . ' ' . $paged_var; + } else { + $output = get_option( 'seo_woo_paged_var') . ' ' . $paged_var . $sep . $output; + } + } + $output = stripslashes($output); + + if(empty($output)) { + $title = wp_title( '»', false ); + } else { + $title = $output; + } + + } + } + else { + + if ( is_home() ) { $title = get_bloginfo( 'name') . $sep . get_bloginfo( 'description' ); } + elseif ( is_search() ) { $title = get_bloginfo( 'name') . $sep . __( 'Search Results', 'woothemes' ); } + elseif ( is_author() ) { $title = get_bloginfo( 'name') . $sep . __( 'Author Archives', 'woothemes' ); } + elseif ( is_single() ) { $title = wp_title( $sep, false, true ) . get_bloginfo( 'name' ); } + elseif ( is_page() ) { $title = get_bloginfo( 'name' ) . wp_title( $sep, false, 'none' ); } + elseif ( is_category() ) { $title = get_bloginfo( 'name') . $sep . __( 'Category Archive', 'woothemes' ) . $sep . single_cat_title( '',false ); } + elseif ( is_tax() ) { $title = get_bloginfo( 'name') . $sep . $taxonomy_top_level_item . __( ' Archive', 'woothemes' ) . $sep . $taxonomy_nice_name; } + elseif ( is_day() ) { $title = get_bloginfo( 'name') . $sep . __( 'Daily Archive', 'woothemes' ) . $sep . get_the_time( 'jS F, Y' ); } + elseif ( is_month() ) { $title = get_bloginfo( 'name') . $sep . __( 'Monthly Archive', 'woothemes' ) . $sep . get_the_time( 'F' ); } + elseif ( is_year() ) { $title = get_bloginfo( 'name') . $sep . __( 'Yearly Archive', 'woothemes' ) . $sep . get_the_time( 'Y' ); } + elseif ( is_tag() ) { $title = get_bloginfo( 'name') . $sep . __( 'Tag Archive', 'woothemes' ) . $sep . single_tag_title( '',false); } + elseif ( function_exists( 'is_post_type_archive' ) && is_post_type_archive() ) { $title = get_bloginfo( 'name') . $sep . $archive_name . __( ' Archive', 'woothemes' ); } + } + + // Allow child themes/plugins to filter the title value. + $title = apply_filters( 'woo_title', $title, $sep ); + + // Display the formatted title. + echo $title; +} + +/*-----------------------------------------------------------------------------------*/ +/* SEO - Strip slashes from the display of the website/page title */ +/*-----------------------------------------------------------------------------------*/ + +add_filter( 'woo_title', 'stripslashes', 10 ); +add_filter( 'wp_title', 'stripslashes', 10 ); +add_filter( 'admin_title', 'stripslashes', 10 ); + +/*-----------------------------------------------------------------------------------*/ +/* woo_meta() */ +/*-----------------------------------------------------------------------------------*/ + + +function woo_meta(){ + global $post; + global $wpdb; + if(!empty($post)){ + $post_id = $post->ID; + } + + // Basic Output + echo '' . "\n"; + + // Under SETTIGNS > PRIVACY in the WordPress backend + if ( get_option( 'blog_public') == 0 ) { return; } + + //3rd Party Plugins + $use_third_party_data = false; + if(get_option( 'seo_woo_use_third_party_data') == 'true'){ + $use_third_party_data = true; + } + + if( + ( + class_exists( 'All_in_One_SEO_Pack') || + class_exists( 'Headspace_Plugin') || + class_exists( 'WPSEO_Admin' ) || + class_exists( 'WPSEO_Frontend' ) + ) + && ( $use_third_party_data == true ) ) { return; } + + // Robots + if ( + ! class_exists( 'All_in_One_SEO_Pack') && + ! class_exists( 'Headspace_Plugin') && + ! class_exists( 'WPSEO_Admin' ) && + ! class_exists( 'WPSEO_Frontend' ) + ) { + $index = 'index'; + $follow = 'nofollow'; + + if ( is_category() && get_option( 'seo_woo_meta_indexing_category') != 'true' ) { $index = 'noindex'; } + elseif ( is_tag() && get_option( 'seo_woo_meta_indexing_tag') != 'true') { $index = 'noindex'; } + elseif ( is_search() && get_option( 'seo_woo_meta_indexing_search') != 'true' ) { $index = 'noindex'; } + elseif ( is_author() && get_option( 'seo_woo_meta_indexing_author') != 'true') { $index = 'noindex'; } + elseif ( is_date() && get_option( 'seo_woo_meta_indexing_date') != 'true') { $index = 'noindex'; } + + // Set default to follow + if ( get_option( 'seo_woo_meta_single_follow') == 'true' ) + $follow = 'follow'; + + // Set individual post/page to follow/unfollow + if ( is_singular() ) { + if ( $follow == 'follow' AND get_post_meta($post->ID,'seo_follow',true) == 'true') + $follow = 'nofollow'; + elseif ( $follow == 'nofollow' AND get_post_meta($post->ID,'seo_follow',true) == 'true') + $follow = 'follow'; + } + + if(is_singular() && get_post_meta($post->ID,'seo_noindex',true) == 'true') { $index = 'noindex'; } + + echo '' . "\n"; + } + + /* Description */ + $description = ''; + + $home_desc_option = get_option( 'seo_woo_meta_home_desc' ); + $singular_desc_option = get_option( 'seo_woo_meta_single_desc' ); + + //Check if there is a custom value added to post meta + $wooseo_desc = get_post_meta($post->ID,'seo_description',true); // WooSEO + $aio_desc = get_post_meta($post->ID,'_aioseop_description',true); // All-in-One SEO Pack + $headspace_desc = get_post_meta($post->ID,'_headspace_description',true); // Headspace SEO + $wpseo_desc = get_post_meta($post->ID,'_yoast_wpseo_metadesc',true); // WordPress SEO + + //Singular setup + if(!empty($aio_desc) AND $use_third_party_data) { + $singular_desc_option = 'aioseo'; + } elseif(!empty($headspace_desc) AND $use_third_party_data) { + $singular_desc_option = 'headspace'; + } elseif( ! empty( $wpseo_desc ) AND $use_third_party_data) { + $singular_desc_option = 'wpseo'; + } + + + if(is_home() OR is_front_page()){ + switch($home_desc_option){ + case 'a': $description = ''; + break; + case 'b': $description = get_bloginfo( 'description' ); + break; + case 'c': $description = get_option( 'seo_woo_meta_home_desc_custom' ); + break; + } + } + elseif(is_singular()){ + + switch($singular_desc_option){ + case 'a': $description = ''; + break; + case 'b': $description = trim(strip_tags($wooseo_desc)); + break; + case 'c': + + if(is_single()){ + $posts = get_posts( "p=$post_id" ); + } + if(is_page()){ + $posts = get_posts( "page_id=$post_id&post_type=page" ); + } + foreach($posts as $post){ + setup_postdata($post); + $post_content = get_the_excerpt(); + if(empty($post_content)){ + $post_content = get_the_content(); + } + } + // $post_content = htmlentities(trim(strip_tags(strip_shortcodes($post_content))), ENT_QUOTES, 'UTF-8' ); // Replaced with line below to accommodate special characters. // 2010-11-15. + // $post_content = html_entity_decode(trim(strip_tags(strip_shortcodes($post_content))), ENT_QUOTES, 'UTF-8' ); // Replaced to fix PHP4 compatibility issue. // 2010-12-09. + // $post_content = utf8_decode( trim( strip_tags( strip_shortcodes( $post_content ) ) ) ); + // $post_content = html_entity_decode( trim( strip_tags( strip_shortcodes( $post_content ) ) ) ); + // $post_content = esc_html( htmlspecialchars ( strip_shortcodes( $post_content ) ) ); + + $post_content = esc_attr( strip_tags( strip_shortcodes( $post_content ) ) ); + + $description = woo_text_trim($post_content,30); + + break; + case 'aioseo': $description = $aio_desc; // All-in-One Description + break; + case 'headspace': $description = $headspace_desc; // Headspace Description + break; + case 'wpseo': $description = $wpseo_desc; // WordPress SEO Description + break; + + } + } + + if(empty($description) AND get_option( 'seo_woo_meta_single_desc_sitewide') == 'true'){ + $description = get_option( 'seo_woo_meta_single_desc_custom' ); + } + + + // $description = htmlspecialchars($description, ENT_QUOTES, 'UTF-8' ); // Replaced with line below to accommodate special characters. // 2010-11-15. + $description = esc_attr( $description ); + $description = stripslashes($description); + + // Faux-htmlentities using an array of key => value pairs. + // TO DO: Clean-up and move to a re-usable function. + $faux_htmlentities = array( + '& ' => '& ', + '<' => '<', + '>' => '>' + ); + + foreach ( $faux_htmlentities as $old => $new ) { + + $description = str_replace( $old, $new, $description ); + + } // End FOREACH Loop + + if(!empty($description)){ + echo '' . "\n"; + } + + /* Keywords */ + $keywords = ''; + + $home_key_option = get_option( 'seo_woo_meta_home_key' ); + $singular_key_option = get_option( 'seo_woo_meta_single_key' ); + + //Check if there is a custom value added to post meta + $wooseo_keywords = get_post_meta($post->ID,'seo_keywords',true); // WooSEO + $aio_keywords = get_post_meta($post->ID,'_aioseop_keywords',true); // All-in-One SEO Pack + $headspace_keywords = get_post_meta($post->ID,'_headspace_keywords',true); // Headspace SEO + $wpseo_keywords = get_post_meta($post->ID,'_yoast_wpseo_focuskw',true); // WordPress SEO + + //Singular setup + + if(!empty($aio_keywords) AND $use_third_party_data) { + $singular_key_option = 'aioseo'; + } elseif(!empty($headspace_keywords) AND $use_third_party_data) { + $singular_key_option = 'headspace'; + } elseif( ! empty( $wpseo_keywords ) AND $use_third_party_data) { + $singular_key_option = 'wpseo'; + } + + if(is_home() OR is_front_page()){ + switch($home_key_option){ + case 'a': $keywords = ''; + break; + case 'c': $keywords = get_option( 'seo_woo_meta_home_key_custom' ); + break; + } + } + elseif(is_singular()){ + + switch($singular_key_option){ + case 'a': $keywords = ''; + break; + case 'b': $keywords = $wooseo_keywords; + break; + case 'c': + + $the_keywords = array(); + //Tags + if(get_the_tags($post->ID)){ + foreach(get_the_tags($post->ID) as $tag) { + $tag_name = $tag->name; + $the_keywords[] = strtolower($tag_name); + } + } + //Cats + if(get_the_category($post->ID)){ + foreach(get_the_category($post->ID) as $cat) { + $cat_name = $cat->name; + $the_keywords[] = strtolower($cat_name); + } + } + //Other Taxonomies + $all_taxonomies = get_taxonomies(); + $addon_taxonomies = array(); + if(!empty($all_taxonomies)){ + foreach($all_taxonomies as $key => $taxonomies){ + if( $taxonomies != 'category' AND + $taxonomies != 'post_tag' AND + $taxonomies != 'nav_menu' AND + $taxonomies != 'link_category'){ + $addon_taxonomies[] = $taxonomies; + } + } + } + $addon_terms = array(); + if(!empty($addon_taxonomies)){ + foreach($addon_taxonomies as $taxonomies){ + $addon_terms[] = get_the_terms($post->ID, $taxonomies); + } + } + if(!empty($addon_terms)){ + foreach($addon_terms as $addon){ + if(!empty($addon)){ + foreach($addon as $term){ + $the_keywords[] = strtolower($term->name); + } + } + } + } + $keywords = implode( ",",$the_keywords); + break; + case 'aioseo': $keywords = $aio_keywords; // All-in-One Title + break; + case 'headspace': $keywords = $headspace_keywords; // Headspace Title + break; + case 'wpseo': $keywords = $wpseo_keywords; // Headspace Title + break; + } + } + + if(empty($keywords) AND get_option( 'seo_woo_meta_single_key_sitewide') == 'true'){ + $keywords = get_option( 'seo_woo_meta_single_key_custom' ); + } + + $keywords = htmlspecialchars($keywords, ENT_QUOTES, 'UTF-8' ); + $keywords = stripslashes($keywords); + + + if(!empty($keywords)){ + echo '' . "\n"; + } + +} + + +//Add Post Custom Settings +add_action( 'admin_head','seo_add_custom' ); + +function seo_add_custom() { + + $seo_template = array(); + + $seo_woo_wp_title = get_option( 'seo_woo_wp_title' ); + $seo_woo_meta_single_desc = get_option( 'seo_woo_meta_single_desc' ); + $seo_woo_meta_single_key = get_option( 'seo_woo_meta_single_key' ); + + // a = off + if( $seo_woo_wp_title != 'true' OR $seo_woo_meta_single_desc == 'a' OR $seo_woo_meta_single_key == 'a') { + + $output = ""; + if ( $seo_woo_wp_title != 'true' ) + $output .= "Custom Page Titles, "; + if ( $seo_woo_meta_single_desc == 'a' ) + $output .= "Custom Descriptions, "; + if ( $seo_woo_meta_single_key == 'a' ) + $output .= "Custom Keywords"; + + $output = rtrim($output, ", " ); + + $desc = 'Additional SEO custom fields available: '.$output.'. Go to SEO Settings page to activate.'; + + } else { + $desc = 'Go to SEO Settings page for more SEO options.'; + } + + $seo_template[] = array ( "name" => "seo_info_1", + "std" => "", + "label" => "SEO ", + "type" => "info", + "desc" => $desc); + + // Change checkbox depending on "Add meta for Posts & Pages to 'follow' by default" checkbox value. + + $followstatus = get_option( 'seo_woo_meta_single_follow' ); + + if ( $followstatus != "true" ) { + + $seo_template[] = array ( "name" => "seo_follow", + "std" => 'false', + "label" => "SEO - Set follow", + "type" => "checkbox", + "desc" => "Make links from this post/page followable by search engines." ); + + } else { + + $seo_template[] = array ( "name" => "seo_follow", + "std" => 'false', + "label" => "SEO - Set nofollow", + "type" => "checkbox", + "desc" => "Make links from this post/page not followable by search engines." ); + + } // End IF Statement + + $seo_template[] = array ( "name" => "seo_noindex", + "std" => "false", + "label" => "SEO - Noindex", + "type" => "checkbox", + "desc" => "Set the Page/Post to not be indexed by a search engines." ); + + if( get_option( 'seo_woo_wp_title') == 'true'){ + $seo_template[] = array ( "name" => "seo_title", + "std" => "", + "label" => "SEO - Custom Page Title", + "type" => "text", + "desc" => "Add a custom title for this post/page." ); + } + + if( get_option( 'seo_woo_meta_single_desc') == 'b'){ + $seo_template[] = array ( "name" => "seo_description", + "std" => "", + "label" => "SEO - Custom Description", + "type" => "textarea", + "desc" => "Add a custom meta description for this post/page." ); + } + + if( get_option( 'seo_woo_meta_single_key') == 'b'){ + $seo_template[] = array ( "name" => "seo_keywords", + "std" => "", + "label" => "SEO - Custom Keywords", + "type" => "text", + "desc" => "Add a custom meta keywords for this post/page. (comma seperated)" ); + } + + //3rd Party Plugins + if(get_option( 'seo_woo_use_third_party_data') == 'true'){ + $use_third_party_data = true; + } else { + $use_third_party_data = false; + } + + if( ( + class_exists( 'All_in_One_SEO_Pack') || + class_exists( 'Headspace_Plugin') || + class_exists( 'WPSEO_Admin' ) || + class_exists( 'WPSEO_Frontend' ) + ) AND + ( $use_third_party_data == true )) { + delete_option( 'woo_custom_seo_template' ); + } + else { + + update_option( 'woo_custom_seo_template',$seo_template); + + } + +} + +/*-----------------------------------------------------------------------------------*/ +/* Woo Text Trimmer */ +/*-----------------------------------------------------------------------------------*/ + +if ( !function_exists( 'woo_text_trim') ) { + function woo_text_trim($text, $words = 50) + { + $matches = preg_split( "/\s+/", $text, $words + 1); + $sz = count($matches); + if ($sz > $words) + { + unset($matches[$sz-1]); + return implode( ' ',$matches)." ..."; + } + return $text; + } +} + +/*-----------------------------------------------------------------------------------*/ +/* Google Webfonts Array */ +/* Documentation: +/* +/* name: The name of the Google Font. +/* variant: The Google Font API variants available for the font. +/*-----------------------------------------------------------------------------------*/ + +// Available Google webfont names +$google_fonts = array( array( 'name' => "Cantarell", 'variant' => ':r,b,i,bi'), + array( 'name' => "Cardo", 'variant' => ''), + array( 'name' => "Crimson Text", 'variant' => ''), + array( 'name' => "Droid Sans", 'variant' => ':r,b'), + array( 'name' => "Droid Sans Mono", 'variant' => ''), + array( 'name' => "Droid Serif", 'variant' => ':r,b,i,bi'), + array( 'name' => "IM Fell DW Pica", 'variant' => ':r,i'), + array( 'name' => "Inconsolata", 'variant' => ''), + array( 'name' => "Josefin Sans Std Light", 'variant' => ''), + array( 'name' => "Josefin Slab", 'variant' => ':r,b,i,bi'), + array( 'name' => "Lobster", 'variant' => ''), + array( 'name' => "Molengo", 'variant' => ''), + array( 'name' => "Nobile", 'variant' => ':r,b,i,bi'), + array( 'name' => "OFL Sorts Mill Goudy TT", 'variant' => ':r,i'), + array( 'name' => "Old Standard TT", 'variant' => ':r,b,i'), + array( 'name' => "Reenie Beanie", 'variant' => ''), + array( 'name' => "Tangerine", 'variant' => ':r,b'), + array( 'name' => "Vollkorn", 'variant' => ':r,b'), + array( 'name' => "Yanone Kaffeesatz", 'variant' => ':r,b'), + array( 'name' => "Cuprum", 'variant' => ''), + array( 'name' => "Neucha", 'variant' => ''), + array( 'name' => "Neuton", 'variant' => ''), + array( 'name' => "PT Sans", 'variant' => ':r,b,i,bi'), + array( 'name' => "PT Sans Caption", 'variant' => ':r,b'), + array( 'name' => "PT Sans Narrow", 'variant' => ':r,b'), + array( 'name' => "Philosopher", 'variant' => ''), + array( 'name' => "Allerta", 'variant' => ''), + array( 'name' => "Allerta Stencil", 'variant' => ''), + array( 'name' => "Arimo", 'variant' => ':r,b,i,bi'), + array( 'name' => "Arvo", 'variant' => ':r,b,i,bi'), + array( 'name' => "Bentham", 'variant' => ''), + array( 'name' => "Coda", 'variant' => ':800'), + array( 'name' => "Cousine", 'variant' => ''), + array( 'name' => "Covered By Your Grace", 'variant' => ''), + array( 'name' => "Geo", 'variant' => ''), + array( 'name' => "Just Me Again Down Here", 'variant' => ''), + array( 'name' => "Puritan", 'variant' => ':r,b,i,bi'), + array( 'name' => "Raleway", 'variant' => ':100'), + array( 'name' => "Tinos", 'variant' => ':r,b,i,bi'), + array( 'name' => "UnifrakturCook", 'variant' => ':bold'), + array( 'name' => "UnifrakturMaguntia", 'variant' => ''), + array( 'name' => "Mountains of Christmas", 'variant' => ''), + array( 'name' => "Lato", 'variant' => ''), + array( 'name' => "Orbitron", 'variant' => ':r,b,i,bi'), + array( 'name' => "Allan", 'variant' => ':bold'), + array( 'name' => "Anonymous Pro", 'variant' => ':r,b,i,bi'), + array( 'name' => "Copse", 'variant' => ''), + array( 'name' => "Kenia", 'variant' => ''), + array( 'name' => "Ubuntu", 'variant' => ':r,b,i,bi'), + array( 'name' => "Vibur", 'variant' => ''), + array( 'name' => "Sniglet", 'variant' => ':800'), + array( 'name' => "Syncopate", 'variant' => ''), + array( 'name' => "Cabin", 'variant' => ':b'), + array( 'name' => "Merriweather", 'variant' => ''), + array( 'name' => "Maiden Orange", 'variant' => ''), + array( 'name' => "Just Another Hand", 'variant' => ''), + array( 'name' => "Kristi", 'variant' => ''), + array( 'name' => "Corben", 'variant' => ':b'), + array( 'name' => "Gruppo", 'variant' => ''), + array( 'name' => "Buda", 'variant' => ':light'), + array( 'name' => "Lekton", 'variant' => ''), + array( 'name' => "Luckiest Guy", 'variant' => ''), + array( 'name' => "Crushed", 'variant' => ''), + array( 'name' => "Chewy", 'variant' => ''), + array( 'name' => "Coming Soon", 'variant' => ''), + array( 'name' => "Crafty Girls", 'variant' => ''), + array( 'name' => "Fontdiner Swanky", 'variant' => ''), + array( 'name' => "Permanent Marker", 'variant' => ''), + array( 'name' => "Rock Salt", 'variant' => ''), + array( 'name' => "Sunshiney", 'variant' => ''), + array( 'name' => "Unkempt", 'variant' => ''), + array( 'name' => "Calligraffitti", 'variant' => ''), + array( 'name' => "Cherry Cream Soda", 'variant' => ''), + array( 'name' => "Homemade Apple", 'variant' => ''), + array( 'name' => "Irish Growler", 'variant' => ''), + array( 'name' => "Kranky", 'variant' => ''), + array( 'name' => "Schoolbell", 'variant' => ''), + array( 'name' => "Slackey", 'variant' => ''), + array( 'name' => "Walter Turncoat", 'variant' => ''), + array( 'name' => "Radley", 'variant' => ''), + array( 'name' => "Meddon", 'variant' => ''), + array( 'name' => "Kreon", 'variant' => ':r,b'), + array( 'name' => "Dancing Script", 'variant' => ''), + array( 'name' => "Goudy Bookletter 1911", 'variant' => ''), + array( 'name' => "PT Serif Caption", 'variant' => ':r,i'), + array( 'name' => "PT Serif", 'variant' => ':r,b,i,bi'), + array( 'name' => "Astloch", 'variant' => ':b'), + array( 'name' => "Bevan", 'variant' => ''), + array( 'name' => "Anton", 'variant' => ''), + array( 'name' => "Expletus Sans", 'variant' => ':b'), + array( 'name' => "VT323", 'variant' => ''), + array( 'name' => "Pacifico", 'variant' => ''), + array( 'name' => "Candal", 'variant' => ''), + array( 'name' => "Architects Daughter", 'variant' => ''), + array( 'name' => "Indie Flower", 'variant' => ''), + array( 'name' => "League Script", 'variant' => ''), + array( 'name' => "Cabin Sketch", 'variant' => ':b'), + array( 'name' => "Quattrocento", 'variant' => ''), + array( 'name' => "Amaranth", 'variant' => ''), + array( 'name' => "Irish Grover", 'variant' => ''), + array( 'name' => "Oswald", 'variant' => ''), + array( 'name' => "EB Garamond", 'variant' => ''), + array( 'name' => "Nova Round", 'variant' => ''), + array( 'name' => "Nova Slim", 'variant' => ''), + array( 'name' => "Nova Script", 'variant' => ''), + array( 'name' => "Nova Cut", 'variant' => ''), + array( 'name' => "Nova Mono", 'variant' => ''), + array( 'name' => "Nova Oval", 'variant' => ''), + array( 'name' => "Nova Flat", 'variant' => ''), + array( 'name' => "Terminal Dosis Light", 'variant' => ''), + array( 'name' => "Michroma", 'variant' => ''), + array( 'name' => "Miltonian", 'variant' => ''), + array( 'name' => "Miltonian Tattoo", 'variant' => ''), + array( 'name' => "Annie Use Your Telescope", 'variant' => ''), + array( 'name' => "Dawning of a New Day", 'variant' => ''), + array( 'name' => "Sue Ellen Francisco", 'variant' => ''), + array( 'name' => "Waiting for the Sunrise", 'variant' => ''), + array( 'name' => "Special Elite", 'variant' => ''), + array( 'name' => "Quattrocento Sans", 'variant' => ''), + array( 'name' => "Smythe", 'variant' => ''), + array( 'name' => "The Girl Next Door", 'variant' => ''), + array( 'name' => "Aclonica", 'variant' => ''), + array( 'name' => "News Cycle", 'variant' => ''), + array( 'name' => "Damion", 'variant' => ''), + array( 'name' => "Wallpoet", 'variant' => ''), + array( 'name' => "Over the Rainbow", 'variant' => ''), + array( 'name' => "MedievalSharp", 'variant' => ''), + array( 'name' => "Six Caps", 'variant' => ''), + array( 'name' => "Swanky and Moo Moo", 'variant' => ''), + array( 'name' => "Bigshot One", 'variant' => ''), + array( 'name' => "Francois One", 'variant' => ''), + array( 'name' => "Sigmar One", 'variant' => ''), + array( 'name' => "Carter One", 'variant' => ''), + array( 'name' => "Holtwood One SC", 'variant' => ''), + array( 'name' => "Paytone One", 'variant' => ''), + array( 'name' => "Monofett", 'variant' => ''), + array( 'name' => "Rokkitt", 'variant' => ''), + array( 'name' => "Megrim", 'variant' => ''), + array( 'name' => "Judson", 'variant' => ':r,ri,b'), + array( 'name' => "Didact Gothic", 'variant' => ''), + array( 'name' => "Play", 'variant' => ':r,b'), + array( 'name' => "Ultra", 'variant' => ''), + array( 'name' => "Metrophobic", 'variant' => ''), + array( 'name' => "Mako", 'variant' => ''), + array( 'name' => "Shanti", 'variant' => ''), + array( 'name' => "Caudex", 'variant' => ':r,b,i,bi'), + array( 'name' => "Jura", 'variant' => ''), + array( 'name' => "Ruslan Display", 'variant' => ''), + array( 'name' => "Brawler", 'variant' => ''), + array( 'name' => "Nunito", 'variant' => ''), + array( 'name' => "Wire One", 'variant' => ''), + array( 'name' => "Podkova", 'variant' => '') + +); + + +/*-----------------------------------------------------------------------------------*/ +/* Google Webfonts Stylesheet Generator */ +/*-----------------------------------------------------------------------------------*/ +/* +INSTRUCTIONS: Needs to be loaded for the Google Fonts options to work for font options. Add this to +the specific themes includes/theme-actions.php or functions.php: + +add_action( 'wp_head', 'woo_google_webfonts' ); +*/ + +if (!function_exists( "woo_google_webfonts")) { + function woo_google_webfonts() { + + global $google_fonts; + $fonts = ''; + $output = ''; + + // Setup Woo Options array + global $woo_options; + + // Go through the options + if ( !empty($woo_options) ) { + + foreach ( $woo_options as $option ) { + + // Check if option has "face" in array + if ( is_array($option) && isset($option['face']) ) { + + // Go through the google font array + foreach ($google_fonts as $font) { + + // Check if the google font name exists in the current "face" option + if ( $option['face'] == $font['name'] AND !strstr($fonts, $font['name'])) + + // Add google font to output + $fonts .= $font['name'].$font['variant']."|"; + } + } + + } + + // Output google font css in header + if ( $fonts ) { + $fonts = str_replace( " ","+",$fonts); + $output .= "\n\n"; + $output .= ''."\n\n"; + $output = str_replace( '|"','"',$output); + + echo $output; + } + } + + } +} + + +/*-----------------------------------------------------------------------------------*/ +/* Enable Home link in WP Menus +/*-----------------------------------------------------------------------------------*/ +if ( !function_exists( 'woo_home_page_menu_args') ) { + function woo_home_page_menu_args( $args ) { + $args['show_home'] = true; + return $args; + } + add_filter( 'wp_page_menu_args', 'woo_home_page_menu_args' ); +} + +/*-----------------------------------------------------------------------------------*/ +/* Buy Themes page +/*-----------------------------------------------------------------------------------*/ +if ( !function_exists( 'woothemes_more_themes_page') ) { + function woothemes_more_themes_page(){ + ?> +
    +

    More WooThemes

    + + get_error_code(); + if($error == 'simplepie-error') { + //Simplepie Error + echo "

    An error has occured with the RSS feed. (". $error .")

    "; + } + return; + } + ?> + + + get_item_quantity(30); + $items = $rss->get_items(0, 30); + + ?> +
      + No items'; + else + foreach ( $items as $item ) : ?> +
    • + get_description();?> +
    • + +
    +
    + + h1 a { background-image:url( '.$logo.' ); height: '.$dimensions[1].'px ; }'; + } + if ( get_option( 'framework_woo_custom_login_logo') ) + add_action( 'login_head', 'woo_custom_login_logo' ); +} + +/*-----------------------------------------------------------------------------------*/ +/* woo_pagination() - Custom loop pagination function */ +/*-----------------------------------------------------------------------------------*/ +/* +/* Additional documentation: http://codex.wordpress.org/Function_Reference/paginate_links +/* +/* Params: +/* +/* Arguments Array: +/* +/* 'base' (optional) - The query argument on which to determine the pagination (for advanced users) +/* 'format' (optional) - The format in which the query argument is formatted in it's raw format (for advanced users) +/* 'total' (optional) - The total amount of pages +/* 'current' (optional) - The current page number +/* 'prev_next' (optional) - Whether to include the previous and next links in the list or not. +/* 'prev_text' (optional) - The previous page text. Works only if 'prev_next' argument is set to true. +/* 'next_text' (optional) - The next page text. Works only if 'prev_next' argument is set to true. +/* 'show_all' (optional) - If set to True, then it will show all of the pages instead of a short list of the pages near the current page. By default, the 'show_all' is set to false and controlled by the 'end_size' and 'mid_size' arguments. +/* 'end_size' (optional) - How many numbers on either the start and the end list edges. +/* 'mid_size' (optional) - How many numbers to either side of current page, but not including current page. +/* 'add_fragment' (optional) - An array of query args to add using add_query_arg(). +/* 'type' (optional) - Controls format of the returned value. Possible values are: + 'plain' - A string with the links separated by a newline character. + 'array' - An array of the paginated link list to offer full control of display. + 'list' - Unordered HTML list. +/* 'before' (optional) - The HTML to display before the paginated links. +/* 'after' (optional) - The HTML to display after the paginated links. +/* 'echo' (optional) - Whether or not to display the paginated links (alternative is to "return"). +/* +/* Query Parameter (optional) - Specify a custom query which you'd like to paginate. +/* +/*-----------------------------------------------------------------------------------*/ +/** + * woo_pagination() is used for paginating the various archive pages created by WordPress. This is not + * to be used on single.php or other single view pages. + * + * @since 3.7.0 + * @uses paginate_links() Creates a string of paginated links based on the arguments given. + * @param array $args Arguments to customize how the page links are output. + * @param object $query An optional custom query to paginate. + */ + +if ( ! function_exists( 'woo_pagination' ) ) { + + function woo_pagination( $args = array(), $query = '' ) { + global $wp_rewrite, $wp_query; + + do_action( 'woo_pagination_start' ); + + if ( $query ) { + + $wp_query = $query; + + } // End IF Statement + + /* If there's not more than one page, return nothing. */ + if ( 1 >= $wp_query->max_num_pages ) + return; + + /* Get the current page. */ + $current = ( get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1 ); + + /* Get the max number of pages. */ + $max_num_pages = intval( $wp_query->max_num_pages ); + + /* Set up some default arguments for the paginate_links() function. */ + $defaults = array( + 'base' => add_query_arg( 'paged', '%#%' ), + 'format' => '', + 'total' => $max_num_pages, + 'current' => $current, + 'prev_next' => true, + 'prev_text' => __( '« Previous', 'woothemes' ), // Translate in WordPress. This is the default. + 'next_text' => __( 'Next »', 'woothemes' ), // Translate in WordPress. This is the default. + 'show_all' => false, + 'end_size' => 1, + 'mid_size' => 1, + 'add_fragment' => '', + 'type' => 'plain', + 'before' => '', + 'echo' => true, + ); + + /* Add the $base argument to the array if the user is using permalinks. */ + if( $wp_rewrite->using_permalinks() ) + $defaults['base'] = user_trailingslashit( trailingslashit( get_pagenum_link() ) . 'page/%#%' ); + + /* If we're on a search results page, we need to change this up a bit. */ + if ( is_search() ) { + /* If we're in BuddyPress, use the default "unpretty" URL structure. */ + if ( class_exists( 'BP_Core_User' ) ) { + + $search_query = get_query_var( 's' ); + $paged = get_query_var( 'paged' ); + + $base = user_trailingslashit( home_url() ) . '?s=' . $search_query . '&paged=%#%'; + + $defaults['base'] = $base; + } else { + $search_permastruct = $wp_rewrite->get_search_permastruct(); + if ( !empty( $search_permastruct ) ) + $defaults['base'] = user_trailingslashit( trailingslashit( get_search_link() ) . 'page/%#%' ); + } + } + + /* Merge the arguments input with the defaults. */ + $args = wp_parse_args( $args, $defaults ); + + /* Allow developers to overwrite the arguments with a filter. */ + $args = apply_filters( 'woo_pagination_args', $args ); + + /* Don't allow the user to set this to an array. */ + if ( 'array' == $args['type'] ) + $args['type'] = 'plain'; + + /* Make sure raw querystrings are displayed at the end of the URL, if using pretty permalinks. */ + $pattern = '/\?(.*?)\//i'; + + preg_match( $pattern, $args['base'], $raw_querystring ); + + if( $wp_rewrite->using_permalinks() && $raw_querystring ) + $raw_querystring[0] = str_replace( '', '', $raw_querystring[0] ); + @$args['base'] = str_replace( $raw_querystring[0], '', $args['base'] ); + @$args['base'] .= substr( $raw_querystring[0], 0, -1 ); + + /* Get the paginated links. */ + $page_links = paginate_links( $args ); + + /* Remove 'page/1' from the entire output since it's not needed. */ + $page_links = str_replace( array( '&paged=1\'', '/page/1\'' ), '\'', $page_links ); + + /* Wrap the paginated links with the $before and $after elements. */ + $page_links = $args['before'] . $page_links . $args['after']; + + /* Allow devs to completely overwrite the output. */ + $page_links = apply_filters( 'woo_pagination', $page_links ); + + do_action( 'woo_pagination_end' ); + + /* Return the paginated links for use in themes. */ + if ( $args['echo'] ) + echo $page_links; + else + return $page_links; + + } // End woo_pagination() + +} // End IF Statement + +/*-----------------------------------------------------------------------------------*/ +/* woo_breadcrumbs() - Custom breadcrumb generator function */ +/* +/* Params: +/* +/* Arguments Array: +/* +/* 'separator' - The character to display between the breadcrumbs. +/* 'before' - HTML to display before the breadcrumbs. +/* 'after' - HTML to display after the breadcrumbs. +/* 'front_page' - Include the front page at the beginning of the breadcrumbs. +/* 'show_home' - If $show_home is set and we're not on the front page of the site, link to the home page. +/* 'echo' - Specify whether or not to echo the breadcrumbs. Alternative is "return". +/* +/*-----------------------------------------------------------------------------------*/ +/** + * The code below is inspired by Justin Tadlock's Hybrid Core. + * + * woo_breadcrumbs() shows a breadcrumb for all types of pages. Themes and plugins can filter $args or input directly. + * Allow filtering of only the $args using get_the_breadcrumb_args. + * + * @since 3.7.0 + * @param array $args Mixed arguments for the menu. + * @return string Output of the breadcrumb menu. + */ +function woo_breadcrumbs( $args = array() ) { + global $wp_query, $wp_rewrite; + + /* Get the textdomain. */ + $textdomain = 'woothemes'; + + /* Create an empty variable for the breadcrumb. */ + $breadcrumb = ''; + + /* Create an empty array for the trail. */ + $trail = array(); + $path = ''; + + /* Set up the default arguments for the breadcrumb. */ + $defaults = array( + 'separator' => '»', + 'before' => '' . __( 'You are here:', $textdomain ) . '', + 'after' => false, + 'front_page' => true, + 'show_home' => __( 'Home', $textdomain ), + 'echo' => true + ); + + /* Allow singular post views to have a taxonomy's terms prefixing the trail. */ + if ( is_singular() ) + $defaults["singular_{$wp_query->post->post_type}_taxonomy"] = false; + + /* Apply filters to the arguments. */ + $args = apply_filters( 'woo_breadcrumbs_args', $args ); + + /* Parse the arguments and extract them for easy variable naming. */ + extract( wp_parse_args( $args, $defaults ) ); + + /* If $show_home is set and we're not on the front page of the site, link to the home page. */ + if ( !is_front_page() && $show_home ) + $trail[] = '' . $show_home . ''; + + /* If viewing the front page of the site. */ + if ( is_front_page() ) { + if ( !$front_page ) + $trail = false; + elseif ( $show_home ) + $trail['trail_end'] = "{$show_home}"; + } + + /* If viewing the "home"/posts page. */ + elseif ( is_home() ) { + $home_page = get_page( $wp_query->get_queried_object_id() ); + $trail = array_merge( $trail, woo_breadcrumbs_get_parents( $home_page->post_parent, '' ) ); + $trail['trail_end'] = get_the_title( $home_page->ID ); + } + + /* If viewing a singular post (page, attachment, etc.). */ + elseif ( is_singular() ) { + + /* Get singular post variables needed. */ + $post = $wp_query->get_queried_object(); + $post_id = absint( $wp_query->get_queried_object_id() ); + $post_type = $post->post_type; + $parent = $post->post_parent; + + /* If a custom post type, check if there are any pages in its hierarchy based on the slug. */ + if ( 'page' !== $post_type ) { + + $post_type_object = get_post_type_object( $post_type ); + + /* If $front has been set, add it to the $path. */ + if ( 'post' == $post_type || 'attachment' == $post_type || ( $post_type_object->rewrite['with_front'] && $wp_rewrite->front ) ) + $path .= trailingslashit( $wp_rewrite->front ); + + /* If there's a slug, add it to the $path. */ + if ( !empty( $post_type_object->rewrite['slug'] ) ) + $path .= $post_type_object->rewrite['slug']; + + /* If there's a path, check for parents. */ + if ( !empty( $path ) ) + $trail = array_merge( $trail, woo_breadcrumbs_get_parents( '', $path ) ); + + /* If there's an archive page, add it to the trail. */ + if ( !empty( $post_type_object->rewrite['archive'] ) && function_exists( 'get_post_type_archive_link' ) ) + $trail[] = '' . $post_type_object->labels->name . ''; + } + + /* If the post type path returns nothing and there is a parent, get its parents. */ + if ( empty( $path ) && 0 !== $parent || 'attachment' == $post_type ) + $trail = array_merge( $trail, woo_breadcrumbs_get_parents( $parent, '' ) ); + + /* Display terms for specific post type taxonomy if requested. */ + if ( isset( $args["singular_{$post_type}_taxonomy"] ) && $terms = get_the_term_list( $post_id, $args["singular_{$post_type}_taxonomy"], '', ', ', '' ) ) + $trail[] = $terms; + + /* End with the post title. */ + $post_title = get_the_title( $post_id ); // Force the post_id to make sure we get the correct page title. + if ( !empty( $post_title ) ) + $trail['trail_end'] = $post_title; + } + + /* If we're viewing any type of archive. */ + elseif ( is_archive() ) { + + /* If viewing a taxonomy term archive. */ + if ( is_tax() || is_category() || is_tag() ) { + + /* Get some taxonomy and term variables. */ + $term = $wp_query->get_queried_object(); + $taxonomy = get_taxonomy( $term->taxonomy ); + + /* Get the path to the term archive. Use this to determine if a page is present with it. */ + if ( is_category() ) + $path = get_option( 'category_base' ); + elseif ( is_tag() ) + $path = get_option( 'tag_base' ); + else { + if ( $taxonomy->rewrite['with_front'] && $wp_rewrite->front ) + $path = trailingslashit( $wp_rewrite->front ); + $path .= $taxonomy->rewrite['slug']; + } + + /* Get parent pages by path if they exist. */ + if ( $path ) + $trail = array_merge( $trail, woo_breadcrumbs_get_parents( '', $path ) ); + + /* If the taxonomy is hierarchical, list its parent terms. */ + if ( is_taxonomy_hierarchical( $term->taxonomy ) && $term->parent ) + $trail = array_merge( $trail, woo_breadcrumbs_get_term_parents( $term->parent, $term->taxonomy ) ); + + /* Add the term name to the trail end. */ + $trail['trail_end'] = $term->name; + } + + /* If viewing a post type archive. */ + elseif ( function_exists( 'is_post_type_archive' ) && is_post_type_archive() ) { + + /* Get the post type object. */ + $post_type_object = get_post_type_object( get_query_var( 'post_type' ) ); + + /* If $front has been set, add it to the $path. */ + if ( $post_type_object->rewrite['with_front'] && $wp_rewrite->front ) + $path .= trailingslashit( $wp_rewrite->front ); + + /* If there's a slug, add it to the $path. */ + if ( !empty( $post_type_object->rewrite['archive'] ) ) + $path .= $post_type_object->rewrite['archive']; + + /* If there's a path, check for parents. */ + if ( !empty( $path ) ) + $trail = array_merge( $trail, woo_breadcrumbs_get_parents( '', $path ) ); + + /* Add the post type [plural] name to the trail end. */ + $trail['trail_end'] = $post_type_object->labels->name; + } + + /* If viewing an author archive. */ + elseif ( is_author() ) { + + /* If $front has been set, add it to $path. */ + if ( !empty( $wp_rewrite->front ) ) + $path .= trailingslashit( $wp_rewrite->front ); + + /* If an $author_base exists, add it to $path. */ + if ( !empty( $wp_rewrite->author_base ) ) + $path .= $wp_rewrite->author_base; + + /* If $path exists, check for parent pages. */ + if ( !empty( $path ) ) + $trail = array_merge( $trail, woo_breadcrumbs_get_parents( '', $path ) ); + + /* Add the author's display name to the trail end. */ + $trail['trail_end'] = get_the_author_meta( 'display_name', get_query_var( 'author' ) ); + } + + /* If viewing a time-based archive. */ + elseif ( is_time() ) { + + if ( get_query_var( 'minute' ) && get_query_var( 'hour' ) ) + $trail['trail_end'] = get_the_time( __( 'g:i a', $textdomain ) ); + + elseif ( get_query_var( 'minute' ) ) + $trail['trail_end'] = sprintf( __( 'Minute %1$s', $textdomain ), get_the_time( __( 'i', $textdomain ) ) ); + + elseif ( get_query_var( 'hour' ) ) + $trail['trail_end'] = get_the_time( __( 'g a', $textdomain ) ); + } + + /* If viewing a date-based archive. */ + elseif ( is_date() ) { + + /* If $front has been set, check for parent pages. */ + if ( $wp_rewrite->front ) + $trail = array_merge( $trail, woo_breadcrumbs_get_parents( '', $wp_rewrite->front ) ); + + if ( is_day() ) { + $trail[] = '' . get_the_time( __( 'Y', $textdomain ) ) . ''; + $trail[] = '' . get_the_time( __( 'F', $textdomain ) ) . ''; + $trail['trail_end'] = get_the_time( __( 'j', $textdomain ) ); + } + + elseif ( get_query_var( 'w' ) ) { + $trail[] = '' . get_the_time( __( 'Y', $textdomain ) ) . ''; + $trail['trail_end'] = sprintf( __( 'Week %1$s', $textdomain ), get_the_time( esc_attr__( 'W', $textdomain ) ) ); + } + + elseif ( is_month() ) { + $trail[] = '' . get_the_time( __( 'Y', $textdomain ) ) . ''; + $trail['trail_end'] = get_the_time( __( 'F', $textdomain ) ); + } + + elseif ( is_year() ) { + $trail['trail_end'] = get_the_time( __( 'Y', $textdomain ) ); + } + } + } + + /* If viewing search results. */ + elseif ( is_search() ) + $trail['trail_end'] = sprintf( __( 'Search results for "%1$s"', $textdomain ), esc_attr( get_search_query() ) ); + + /* If viewing a 404 error page. */ + elseif ( is_404() ) + $trail['trail_end'] = __( '404 Not Found', $textdomain ); + + /* Connect the breadcrumb trail if there are items in the trail. */ + if ( is_array( $trail ) ) { + + /* Open the breadcrumb trail containers. */ + $breadcrumb = ''; + } + + /* Allow developers to filter the breadcrumb trail HTML. */ + $breadcrumb = apply_filters( 'woo_breadcrumbs', $breadcrumb ); + + /* Output the breadcrumb. */ + if ( $echo ) + echo $breadcrumb; + else + return $breadcrumb; + +} // End woo_breadcrumbs() + +/*-----------------------------------------------------------------------------------*/ +/* woo_breadcrumbs_get_parents() - Retrieve the parents of the current page/post */ +/*-----------------------------------------------------------------------------------*/ +/** + * Gets parent pages of any post type or taxonomy by the ID or Path. The goal of this function is to create + * a clear path back to home given what would normally be a "ghost" directory. If any page matches the given + * path, it'll be added. But, it's also just a way to check for a hierarchy with hierarchical post types. + * + * @since 3.7.0 + * @param int $post_id ID of the post whose parents we want. + * @param string $path Path of a potential parent page. + * @return array $trail Array of parent page links. + */ +function woo_breadcrumbs_get_parents( $post_id = '', $path = '' ) { + + /* Set up an empty trail array. */ + $trail = array(); + + /* If neither a post ID nor path set, return an empty array. */ + if ( empty( $post_id ) && empty( $path ) ) + return $trail; + + /* If the post ID is empty, use the path to get the ID. */ + if ( empty( $post_id ) ) { + + /* Get parent post by the path. */ + $parent_page = get_page_by_path( $path ); + + /* If a parent post is found, set the $post_id variable to it. */ + if ( !empty( $parent_page ) ) + $post_id = $parent_page->ID; + } + + /* If a post ID and path is set, search for a post by the given path. */ + if ( $post_id == 0 && !empty( $path ) ) { + + /* Separate post names into separate paths by '/'. */ + $path = trim( $path, '/' ); + preg_match_all( "/\/.*?\z/", $path, $matches ); + + /* If matches are found for the path. */ + if ( isset( $matches ) ) { + + /* Reverse the array of matches to search for posts in the proper order. */ + $matches = array_reverse( $matches ); + + /* Loop through each of the path matches. */ + foreach ( $matches as $match ) { + + /* If a match is found. */ + if ( isset( $match[0] ) ) { + + /* Get the parent post by the given path. */ + $path = str_replace( $match[0], '', $path ); + $parent_page = get_page_by_path( trim( $path, '/' ) ); + + /* If a parent post is found, set the $post_id and break out of the loop. */ + if ( !empty( $parent_page ) && $parent_page->ID > 0 ) { + $post_id = $parent_page->ID; + break; + } + } + } + } + } + + /* While there's a post ID, add the post link to the $parents array. */ + while ( $post_id ) { + + /* Get the post by ID. */ + $page = get_page( $post_id ); + + /* Add the formatted post link to the array of parents. */ + $parents[] = '' . get_the_title( $post_id ) . ''; + + /* Set the parent post's parent to the post ID. */ + $post_id = $page->post_parent; + } + + /* If we have parent posts, reverse the array to put them in the proper order for the trail. */ + if ( isset( $parents ) ) + $trail = array_reverse( $parents ); + + /* Return the trail of parent posts. */ + return $trail; + +} // End woo_breadcrumbs_get_parents() + +/*-----------------------------------------------------------------------------------*/ +/* woo_breadcrumbs_get_term_parents() - Retrieve the parents of the current term */ +/*-----------------------------------------------------------------------------------*/ +/** + * Searches for term parents of hierarchical taxonomies. This function is similar to the WordPress + * function get_category_parents() but handles any type of taxonomy. + * + * @since 3.7.0 + * @param int $parent_id The ID of the first parent. + * @param object|string $taxonomy The taxonomy of the term whose parents we want. + * @return array $trail Array of links to parent terms. + */ +function woo_breadcrumbs_get_term_parents( $parent_id = '', $taxonomy = '' ) { + + /* Set up some default arrays. */ + $trail = array(); + $parents = array(); + + /* If no term parent ID or taxonomy is given, return an empty array. */ + if ( empty( $parent_id ) || empty( $taxonomy ) ) + return $trail; + + /* While there is a parent ID, add the parent term link to the $parents array. */ + while ( $parent_id ) { + + /* Get the parent term. */ + $parent = get_term( $parent_id, $taxonomy ); + + /* Add the formatted term link to the array of parent terms. */ + $parents[] = '' . $parent->name . ''; + + /* Set the parent term's parent as the parent ID. */ + $parent_id = $parent->parent; + } + + /* If we have parent terms, reverse the array to put them in the proper order for the trail. */ + if ( !empty( $parents ) ) + $trail = array_reverse( $parents ); + + /* Return the trail of parent terms. */ + return $trail; + +} // End woo_breadcrumbs_get_term_parents() + +/*-----------------------------------------------------------------------------------*/ +/* WordPress Admin Bar-related */ +/*-----------------------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------------------*/ +/* Disable WordPress Admin Bar */ +/*-----------------------------------------------------------------------------------*/ + +$woo_admin_bar_disable = get_option( 'framework_woo_admin_bar_disable' ); + +if ( $woo_admin_bar_disable == 'true' ) { + add_filter( 'show_admin_bar', '__return_false' ); + + add_action( 'admin_print_scripts-profile.php', 'woo_hide_admin_bar_prefs' ); + + function woo_hide_admin_bar_prefs () { ?> + + user_login; + $super_user = get_option( 'framework_woo_super_user' ); + + $theme_data = get_theme_data( get_template_directory() . '/style.css' ); + + $menu_label = __( 'WooThemes', 'woothemes' ); + + // Customise menu label to the child theme's name. + if ( is_array( $theme_data ) && array_key_exists( 'Name', $theme_data ) ) { + $menu_label = $theme_data['Name']; + } + + // Main WooThemes Menu Item + $wp_admin_bar->add_menu( array( 'id' => 'woothemes', 'title' => $menu_label, 'href' => admin_url('admin.php?page=woothemes') ) ); + + // Theme Options + $wp_admin_bar->add_menu( array( 'parent' => 'woothemes', 'id' => 'woothemes-theme-options', 'title' => __( 'Theme Options', 'woothemes' ), 'href' => admin_url( 'admin.php?page=woothemes' ) ) ); + + // Sidebar Manager + if ( get_option( 'framework_woo_sbm_disable') != 'true' ) { + $wp_admin_bar->add_menu( array( 'parent' => 'woothemes', 'id' => 'woothemes-sbm', 'title' => __( 'Sidebar Manager', 'woothemes' ), 'href' => admin_url( 'admin.php?page=woothemes_sbm' ) ) ); + } + + if ( ( $super_user == $current_user_id ) || empty( $super_user ) ) { + + // Framework Settings + $wp_admin_bar->add_menu( array( 'parent' => 'woothemes', 'id' => 'woothemes-framework-settings', 'title' => __( 'Framework Settings', 'woothemes' ), 'href' => admin_url( 'admin.php?page=woothemes_framework_settings' ) ) ); + + // Update Framework + $wp_admin_bar->add_menu( array( 'parent' => 'woothemes', 'id' => 'woothemes-update-framework', 'title' => __( 'Update Framework', 'woothemes' ), 'href' => admin_url( 'admin.php?page=woothemes_framework_update' ) ) ); + + } // End IF Statement + +} // End woo_admin_bar_menu() + +/*-----------------------------------------------------------------------------------*/ +/* THE END */ +/*-----------------------------------------------------------------------------------*/ +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-hooks.php b/src/wp-content/themes/bloggingstream/functions/admin-hooks.php new file mode 100644 index 00000000..6d924417 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-hooks.php @@ -0,0 +1,255 @@ +context has been set, don't run through the conditionals again. Just return the variable. */ + if ( isset( $query_context->context ) && is_array( $query_context->context ) ) { + + return $query_context->context; + + } // End IF Statement + + $query_context->context = array(); + + /* Front page of the site. */ + if ( is_front_page() ) { + + $query_context->context[] = 'home'; + + } // End IF Statement + + /* Blog page. */ + if ( is_home() && ! is_front_page() ) { + + $query_context->context[] = 'blog'; + + /* Singular views. */ + } elseif ( is_singular() ) { + + $query_context->context[] = 'singular'; + $query_context->context[] = "singular-{$wp_query->post->post_type}"; + + /* Page Templates. */ + if ( is_page_template() ) { + + $to_skip = array( 'page', 'post' ); + + $page_template = basename( get_page_template() ); + $page_template = str_replace( '.php', '', $page_template ); + $page_template = str_replace( '.', '-', $page_template ); + + if ( $page_template && ! in_array( $page_template, $to_skip ) ) { + + $query_context->context[] = $page_template; + + } // End IF Statement + + } // End IF Statement + + $query_context->context[] = "singular-{$wp_query->post->post_type}-{$wp_query->post->ID}"; + } + + /* Archive views. */ + elseif ( is_archive() ) { + $query_context->context[] = 'archive'; + + /* Taxonomy archives. */ + if ( is_tax() || is_category() || is_tag() ) { + $term = $wp_query->get_queried_object(); + $query_context->context[] = 'taxonomy'; + $query_context->context[] = $term->taxonomy; + $query_context->context[] = "{$term->taxonomy}-" . sanitize_html_class( $term->slug, $term->term_id ); + } + + /* User/author archives. */ + elseif ( is_author() ) { + $query_context->context[] = 'user'; + $query_context->context[] = 'user-' . sanitize_html_class( get_the_author_meta( 'user_nicename', get_query_var( 'author' ) ), $wp_query->get_queried_object_id() ); + } + + /* Time/Date archives. */ + else { + if ( is_date() ) { + $query_context->context[] = 'date'; + if ( is_year() ) + $query_context->context[] = 'year'; + if ( is_month() ) + $query_context->context[] = 'month'; + if ( get_query_var( 'w' ) ) + $query_context->context[] = 'week'; + if ( is_day() ) + $query_context->context[] = 'day'; + } + if ( is_time() ) { + $query_context->context[] = 'time'; + if ( get_query_var( 'hour' ) ) + $query_context->context[] = 'hour'; + if ( get_query_var( 'minute' ) ) + $query_context->context[] = 'minute'; + } + } + } + + /* Search results. */ + elseif ( is_search() ) { + $query_context->context[] = 'search'; + + /* Error 404 pages. */ + } elseif ( is_404() ) { + $query_context->context[] = 'error-404'; + + } // End IF Statement + + return $query_context->context; + + } // End woo_get_query_context() +} // End IF Statement +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-init.php b/src/wp-content/themes/bloggingstream/functions/admin-init.php new file mode 100644 index 00000000..e77a0464 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-init.php @@ -0,0 +1,52 @@ + $woo_framework_version ) + update_option( 'woo_framework_version', $woo_framework_version); + +} +add_action( 'init', 'woo_version_init' ); + +function woo_version(){ + + $theme_data = get_theme_data( get_template_directory() . '/style.css' ); + $theme_version = $theme_data['Version']; + $woo_framework_version = get_option( 'woo_framework_version' ); + + echo "\n\n"; + echo '' ."\n"; + echo '' ."\n"; + +} +// Add or remove Generator meta tags +if ( get_option( 'framework_woo_disable_generator') == "true" ) + remove_action( 'wp_head', 'wp_generator' ); +else + add_action( 'wp_head', 'woo_version' ); + +/*-----------------------------------------------------------------------------------*/ +/* Load the required Framework Files */ +/*-----------------------------------------------------------------------------------*/ + +$functions_path = get_template_directory() . '/functions/'; + +require_once ( $functions_path . 'admin-functions.php' ); // Custom functions and plugins +require_once ( $functions_path . 'admin-setup.php' ); // Options panel variables and functions +require_once ( $functions_path . 'admin-custom.php' ); // Custom fields +require_once ( $functions_path . 'admin-interface.php' ); // Admin Interfaces (options,framework, seo) +require_once ( $functions_path . 'admin-framework-settings.php' ); // Framework Settings +require_once ( $functions_path . 'admin-seo.php' ); // Framework SEO controls +require_once ( $functions_path . 'admin-sbm.php' ); // Framework Sidebar Manager +require_once ( $functions_path . 'admin-medialibrary-uploader.php' ); // Framework Media Library Uploader Functions // 2010-11-05. +require_once ( $functions_path . 'admin-hooks.php' ); // Definition of WooHooks +if (get_option( 'framework_woo_woonav') == "true") + require_once ($functions_path . 'admin-custom-nav.php' ); // Woo Custom Navigation +require_once ( $functions_path . 'admin-shortcodes.php' ); // Woo Shortcodes +require_once ( $functions_path . 'admin-shortcode-generator.php' ); // Framework Shortcode generator // 2011-01-21. +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-interface.php b/src/wp-content/themes/bloggingstream/functions/admin-interface.php new file mode 100644 index 00000000..8b4f8d09 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-interface.php @@ -0,0 +1,1752 @@ +user_login; + $super_user = get_option( 'framework_woo_super_user' ); + + $themename = get_option( 'woo_themename' ); + $shortname = get_option( 'woo_shortname' ); + + // Reset the settings, sanitizing the various requests made. + // Use a SWITCH to determine which settings to update. + + /* Make sure we're making a request. + ------------------------------------------------------------*/ + + if ( isset( $_REQUEST['page'] ) ) { + + // Sanitize page being requested. + $_page = ''; + + $_page = mysql_real_escape_string( strtolower( trim( strip_tags( $_REQUEST['page'] ) ) ) ); + + // Sanitize action being requested. + $_action = ''; + + if ( isset( $_REQUEST['woo_save'] ) ) { + + $_action = mysql_real_escape_string( strtolower( trim( strip_tags( $_REQUEST['woo_save'] ) ) ) ); + + } // End IF Statement + + // If the action is "reset", run the SWITCH. + + /* Perform settings reset. + ------------------------------------------------------------*/ + + if ( $_action == 'reset' ) { + + // Add nonce security check. + if ( function_exists( 'check_ajax_referer' ) ) { check_ajax_referer( 'wooframework-theme-options-reset', '_ajax_nonce' ); } // End IF Statement + + switch ( $_page ) { + + case 'woothemes': + + $options = get_option( 'woo_template' ); + woo_reset_options($options,'woothemes' ); + header( "Location: admin.php?page=woothemes&reset=true" ); + die; + + break; + + case 'woothemes_framework_settings': + + $options = get_option( 'woo_framework_template' ); + woo_reset_options($options); + header( "Location: admin.php?page=woothemes_framework_settings&reset=true" ); + die; + + break; + + case 'woothemes_seo': + + $options = get_option( 'woo_seo_template' ); + woo_reset_options($options); + header( "Location: admin.php?page=woothemes_seo&reset=true" ); + die; + + break; + + case 'woothemes_sbm': + + delete_option( 'sbm_woo_sbm_options' ); + header( "Location: admin.php?page=woothemes_sbm&reset=true" ); + die; + + break; + + } // End SWITCH Statement + + } // End IF Statement + + } // End IF Statement + + // Check all the Options, then if the no options are created for a relative sub-page... it's not created. + if(get_option( 'framework_woo_backend_icon')) { $icon = get_option( 'framework_woo_backend_icon' ); } + else { $icon = get_template_directory_uri() . '/functions/images/woo-icon.png'; } + + if(function_exists( 'add_object_page')) + { + add_object_page ( 'Page Title', $themename, 'manage_options','woothemes', 'woothemes_options_page', $icon); + } + else + { + add_menu_page ( 'Page Title', $themename, 'manage_options','woothemes_home', 'woothemes_options_page', $icon); + } + $woopage = add_submenu_page( 'woothemes', $themename, 'Theme Options', 'manage_options', 'woothemes','woothemes_options_page' ); // Default + + // Framework Settings Menu Item + $wooframeworksettings = ''; + if($super_user == $current_user_id || empty($super_user)) { + $wooframeworksettings = add_submenu_page( 'woothemes', 'Framework Settings', 'Framework Settings', 'manage_options', 'woothemes_framework_settings', 'woothemes_framework_settings_page' ); + } + + // Add SEO Menu Item + $wooseo = ''; + if ( get_option( 'framework_woo_seo_disable') != 'true' ) + $wooseo = add_submenu_page( 'woothemes', 'SEO', 'SEO', 'manage_options', 'woothemes_seo', 'woothemes_seo_page' ); + + // Add Sidebar Manager Menu Item + $woosbm = ''; + if ( get_option( 'framework_woo_sbm_disable') != 'true' ) + $woosbm = add_submenu_page( 'woothemes', 'Sidebar Manager', 'Sidebar Manager', 'manage_options', 'woothemes_sbm', 'woothemes_sbm_page' ); + + // Woothemes Content Builder + if (function_exists( 'woothemes_content_builder_menu')) { + woothemes_content_builder_menu(); + } + + // Custom Navigation Menu Item + if (function_exists( 'woo_custom_navigation_menu')) { + woo_custom_navigation_menu(); + } + + // Update Framework Menu Item + if($super_user == $current_user_id || empty($super_user)) { + $woothemepage = add_submenu_page( 'woothemes', 'WooFramework Update', 'Update Framework', 'manage_options', 'woothemes_framework_update', 'woothemes_framework_update_page' ); + } + + // Buy Themes Menu Item + if(get_option( 'framework_woo_buy_themes_disable') != 'true') { + $woothemepage = add_submenu_page( 'woothemes', 'Available WooThemes', 'Buy Themes', 'manage_options', 'woothemes_themes', 'woothemes_more_themes_page' ); + add_action( "admin_print_scripts-$woothemepage", 'woo_load_only' ); + } + + // Add framework functionaily to the head individually + add_action( "admin_print_scripts-$woopage", 'woo_load_only' ); + add_action( "admin_print_scripts-$wooframeworksettings", 'woo_load_only' ); + add_action( "admin_print_scripts-$wooseo", 'woo_load_only' ); + add_action( "admin_print_scripts-$woosbm", 'woo_load_only' ); + +} +} + +add_action( 'admin_menu', 'woothemes_add_admin' ); + +/*-----------------------------------------------------------------------------------*/ +/* WooThemes Reset Function - woo_reset_options */ +/*-----------------------------------------------------------------------------------*/ + +if (!function_exists( 'woo_reset_options')) { +function woo_reset_options($options,$page = ''){ + + $excludes = array( 'blogname' , 'blogdescription' ); + + foreach($options as $option){ + + if(isset($option['id'])){ + $option_id = $option['id']; + $option_type = $option['type']; + + //Skip assigned id's + if(in_array($option_id,$excludes)) { continue; } + + if($option_type == 'multicheck'){ + foreach($option['options'] as $option_key => $option_option){ + $del = $option_id . "_" . $option_key; + delete_option($del); + } + } else if(is_array($option_type)) { + foreach($option_type as $inner_option){ + $option_id = $inner_option['id']; + $del = $option_id; + delete_option($option_id); + } + } else { + delete_option($option_id); + } + } + } + //When Theme Options page is reset - Add the woo_options option + if($page == 'woothemes'){ + delete_option( 'woo_options' ); + } +} +} + +/*-----------------------------------------------------------------------------------*/ +/* Framework options panel - woothemes_options_page */ +/*-----------------------------------------------------------------------------------*/ + +if (!function_exists( 'woothemes_options_page')) { +function woothemes_options_page(){ + + $options = get_option( 'woo_template' ); + $themename = get_option( 'woo_themename' ); + $shortname = get_option( 'woo_shortname' ); + $manualurl = get_option( 'woo_manual' ); + + //Framework Version in Backend Header + $woo_framework_version = get_option( 'woo_framework_version' ); + + //Version in Backend Header + $theme_data = get_theme_data( get_template_directory() . '/style.css' ); + $local_version = $theme_data['Version']; + + + //GET themes update RSS feed and do magic + include_once(ABSPATH . WPINC . '/feed.php' ); + + $pos = strpos($manualurl, 'documentation' ); + $theme_slug = str_replace( "/", "", substr($manualurl, ($pos + 13))); //13 for the word documentation + + //add filter to make the rss read cache clear every 4 hours + //add_filter( 'wp_feed_cache_transient_lifetime', create_function( '$a', 'return 14400;' ) ); + + //Check for latest version of the theme + $update_message = ''; + if(get_option( 'framework_woo_theme_version_checker') == 'true') { + $update_message = woothemes_version_checker($local_version); + } + +?> +
    +
    Options Updated
    +
    Options Reset
    +
    + + + + + + +
    +
    +
      + +
    +
    +
    + +
    +
    + +
    +
    + + + + +
    + + + + + + + +
    + +
    + + +
    +
    + + '; + echo '' + + // COLOR Picker ?> + + + + + + + + + '; + //print_r($new_import); + //echo ''; + if(!empty($new_import)) { + foreach($new_import as $id2 => $value2){ + if(is_serialized($value2)) { + update_option($id2,unserialize($value2)); + } else { + update_option($id2,$value2); + } + } + } + + } else { + + $type = $option_array['type']; + + if ( is_array($type)){ + foreach($type as $array){ + if($array['type'] == 'text'){ + $id = $array['id']; + $std = $array['std']; + $new_value = $output[$id]; + if($new_value == ''){ $new_value = $std; } + + update_option( $id, stripslashes($new_value)); + } + } + } + elseif ( $type == 'text' && $save_type == 'seo' ) { // Text Save + + $new_value = $output[$id]; + if( $new_value == '' && $std != '' ){ $new_value = $std; } + + $new_value = stripslashes( stripslashes( $new_value ) ); + + update_option( $id, $new_value ); + } + elseif($new_value == '' && $type == 'checkbox'){ // Checkbox Save + + update_option($id,'false' ); + } + elseif ($new_value == 'true' && $type == 'checkbox'){ // Checkbox Save + + update_option($id,'true' ); + } + elseif($type == 'multicheck'){ // Multi Check Save + + $option_options = $option_array['options']; + + foreach ($option_options as $options_id => $options_value){ + + $multicheck_id = $id . "_" . $options_id; + + if(!isset($output[$multicheck_id])){ + update_option($multicheck_id,'false' ); + } + else{ + update_option($multicheck_id,'true' ); + } + } + } + elseif($type == 'typography'){ + + $typography_array = array(); + + $typography_array['size'] = $output[$option_array['id'] . '_size']; + + $typography_array['unit'] = $output[$option_array['id'] . '_unit']; + + $typography_array['face'] = stripslashes($output[$option_array['id'] . '_face']); + + $typography_array['style'] = $output[$option_array['id'] . '_style']; + + $typography_array['color'] = $output[$option_array['id'] . '_color']; + + update_option($id,$typography_array); + + } + elseif($type == 'border'){ + + $border_array = array(); + + $border_array['width'] = $output[$option_array['id'] . '_width']; + + $border_array['style'] = $output[$option_array['id'] . '_style']; + + $border_array['color'] = $output[$option_array['id'] . '_color']; + + update_option($id,$border_array); + + } + elseif($type != 'upload_min'){ + + update_option($id,stripslashes($new_value)); + } + } + } + } + } + + + if( $save_type == 'options' OR $save_type == 'framework' ){ + /* Create, Encrypt and Update the Saved Settings */ + $woo_options = array(); + $data = array(); + if($save_type == 'framework' ){ + $options = get_option( 'woo_template' ); + } + foreach($options as $option){ + + if(isset($option['id'])){ + $count++; + $option_id = $option['id']; + $option_type = $option['type']; + + if(is_array($option_type)) { + $type_array_count = 0; + foreach($option_type as $inner_option){ + $option_id = $inner_option['id']; + $data[$option_id] .= get_option($option_id); + } + } + else { + $data[$option_id] = get_option($option_id); + } + } + } + + $output = "
      "; + + foreach ($data as $name => $value){ + + if(is_serialized($value)) { + + $value = unserialize($value); + $woo_array_option = $value; + $temp_options = ''; + foreach($value as $v){ + if(isset($v)) + $temp_options .= $v . ','; + + } + $value = $temp_options; + $woo_array[$name] = $woo_array_option; + } else { + $woo_array[$name] = $value; + } + + $output .= '
    • ' . $name . ' - ' . $value . '
    • '; + } + $output .= "
    "; + $output = base64_encode($output); + + update_option( 'woo_options',$woo_array); + update_option( 'woo_settings_encode',$output); + + } + + die(); + +} +} + + +/*-----------------------------------------------------------------------------------*/ +/* Generates The Options - woothemes_machine */ +/*-----------------------------------------------------------------------------------*/ + +if (!function_exists( 'woothemes_machine')) { +function woothemes_machine($options) { + + $counter = 0; + $menu = ''; + $output = ''; + foreach ($options as $value) { + + $counter++; + $val = ''; + //Start Heading + if ( $value['type'] != "heading" ) + { + $class = ''; if(isset( $value['class'] )) { $class = $value['class']; } + //$output .= '
    '."\n".'
    '."\n"; + $output .= '
    '."\n"; + $output .= '

    '. $value['name'] .'

    '."\n"; + $output .= '
    '."\n" . '
    '."\n"; + + } + //End Heading + $select_value = ''; + switch ( $value['type'] ) { + + case 'text': + $val = $value['std']; + $std = get_option($value['id']); + if ( $std != "") { $val = $std; } + $val = stripslashes( $val ); // Strip out unwanted slashes. + $output .= ''; + break; + + case 'select': + + $output .= '
    '; + + + break; + case 'select2': + + $output .= '
    '; + + + break; + case 'calendar': + + $val = $value['std']; + $std = get_option($value['id']); + if ( $std != "") { $val = $std; } + $output .= ''; + + break; + case 'time': + $val = $value['std']; + $std = get_option($value['id']); + if ( $std != "") { $val = $std; } + $output .= ''; + break; + case 'textarea': + + $cols = '8'; + $ta_value = ''; + + if(isset($value['std'])) { + + $ta_value = $value['std']; + + if(isset($value['options'])){ + $ta_options = $value['options']; + if(isset($ta_options['cols'])){ + $cols = $ta_options['cols']; + } else { $cols = '8'; } + } + + } + $std = get_option($value['id']); + if( $std != "") { $ta_value = stripslashes( $std ); } + $output .= ''; + + + break; + case "radio": + + $select_value = get_option( $value['id']); + + foreach ($value['options'] as $key => $option) + { + + $checked = ''; + if($select_value != '') { + if ( $select_value == $key) { $checked = ' checked'; } + } else { + if ($value['std'] == $key) { $checked = ' checked'; } + } + $output .= '' . $option .'
    '; + + } + + break; + case "checkbox": + + $std = $value['std']; + + $saved_std = get_option($value['id']); + + $checked = ''; + + if(!empty($saved_std)) { + if($saved_std == 'true') { + $checked = 'checked="checked"'; + } + else{ + $checked = ''; + } + } + elseif( $std == 'true') { + $checked = 'checked="checked"'; + } + else { + $checked = ''; + } + $output .= ''; + + break; + case "multicheck": + + $std = $value['std']; + + foreach ($value['options'] as $key => $option) { + + $woo_key = $value['id'] . '_' . $key; + $saved_std = get_option($woo_key); + + if(!empty($saved_std)) + { + if($saved_std == 'true'){ + $checked = 'checked="checked"'; + } + else{ + $checked = ''; + } + } + elseif( $std == $key) { + $checked = 'checked="checked"'; + } + else { + $checked = ''; } + $output .= '
    '; + + } + break; + case "multicheck2": + + $std = explode( ',',$value['std']); + + foreach ($value['options'] as $key => $option) { + + $woo_key = $value['id'] . '_' . $key; + $saved_std = get_option($woo_key); + + if(!empty($saved_std)) + { + if($saved_std == 'true'){ + $checked = 'checked="checked"'; + } + else{ + $checked = ''; + } + } + elseif( in_array($key,$std)) { + $checked = 'checked="checked"'; + } + else { + $checked = ''; } + $output .= '
    '; + + } + break; + case "upload": + + if ( function_exists( 'woothemes_medialibrary_uploader' ) ) { + + $output .= woothemes_medialibrary_uploader( $value['id'], $value['std'], null ); // New AJAX Uploader using Media Library + + } else { + + $output .= woothemes_uploader_function($value['id'],$value['std'],null); // Original AJAX Uploader + + } // End IF Statement + + break; + case "upload_min": + + if ( function_exists( 'woothemes_medialibrary_uploader' ) ) { + + $output .= woothemes_medialibrary_uploader( $value['id'], $value['std'], 'min' ); // New AJAX Uploader using Media Library + + } else { + + $output .= woothemes_uploader_function($value['id'],$value['std'],'min' ); // Original AJAX Uploader + + } // End IF Statement + + // $output .= woothemes_uploader_function($value['id'],$value['std'],'min' ); + + break; + case "color": + $val = $value['std']; + $stored = get_option( $value['id'] ); + if ( $stored != "") { $val = $stored; } + $output .= '
    '; + $output .= ''; + break; + + case "typography": + + $default = $value['std']; + $typography_stored = get_option($value['id']); + + /* Font Size */ + $val = $default['size']; + if ( $typography_stored['size'] != "") { $val = $typography_stored['size']; } + if ( $typography_stored['unit'] == 'px'){ $show_px = ''; $show_em = ' style="display:none" '; $name_px = ' name="'. $value['id'].'_size" '; $name_em = ''; } + else if ( $typography_stored['unit'] == 'em'){ $show_em = ''; $show_px = 'style="display:none"'; $name_em = ' name="'. $value['id'].'_size" '; $name_px = ''; } + else { $show_px = ''; $show_em = ' style="display:none" '; $name_px = ' name="'. $value['id'].'_size" '; $name_em = ''; } + $output .= ''; + + $output .= ''; + + /* Font Unit */ + $val = $default['unit']; + if ( $typography_stored['unit'] != "") { $val = $typography_stored['unit']; } + $em = ''; $px = ''; + if($val == 'em'){ $em = 'selected="selected"'; } + if($val == 'px'){ $px = 'selected="selected"'; } + $output .= ''; + + /* Font Face */ + $val = $default['face']; + if ( $typography_stored['face'] != "") + $val = $typography_stored['face']; + + $font01 = ''; + $font02 = ''; + $font03 = ''; + $font04 = ''; + $font05 = ''; + $font06 = ''; + $font07 = ''; + $font08 = ''; + $font09 = ''; + $font10 = ''; + $font11 = ''; + $font12 = ''; + $font13 = ''; + $font14 = ''; + $font15 = ''; + + if (strpos($val, 'Arial, sans-serif') !== false){ $font01 = 'selected="selected"'; } + if (strpos($val, 'Verdana, Geneva') !== false){ $font02 = 'selected="selected"'; } + if (strpos($val, 'Trebuchet') !== false){ $font03 = 'selected="selected"'; } + if (strpos($val, 'Georgia') !== false){ $font04 = 'selected="selected"'; } + if (strpos($val, 'Times New Roman') !== false){ $font05 = 'selected="selected"'; } + if (strpos($val, 'Tahoma, Geneva') !== false){ $font06 = 'selected="selected"'; } + if (strpos($val, 'Palatino') !== false){ $font07 = 'selected="selected"'; } + if (strpos($val, 'Helvetica') !== false){ $font08 = 'selected="selected"'; } + if (strpos($val, 'Calibri') !== false){ $font09 = 'selected="selected"'; } + if (strpos($val, 'Myriad') !== false){ $font10 = 'selected="selected"'; } + if (strpos($val, 'Lucida') !== false){ $font11 = 'selected="selected"'; } + if (strpos($val, 'Arial Black') !== false){ $font12 = 'selected="selected"'; } + if (strpos($val, 'Gill') !== false){ $font13 = 'selected="selected"'; } + if (strpos($val, 'Geneva, Tahoma') !== false){ $font14 = 'selected="selected"'; } + if (strpos($val, 'Impact') !== false){ $font15 = 'selected="selected"'; } + + $output .= ''; + + /* Font Weight */ + $val = $default['style']; + if ( $typography_stored['style'] != "") { $val = $typography_stored['style']; } + $normal = ''; $italic = ''; $bold = ''; $bolditalic = ''; + if($val == 'normal'){ $normal = 'selected="selected"'; } + if($val == 'italic'){ $italic = 'selected="selected"'; } + if($val == 'bold'){ $bold = 'selected="selected"'; } + if($val == 'bold italic'){ $bolditalic = 'selected="selected"'; } + + $output .= ''; + + /* Font Color */ + $val = $default['color']; + if ( $typography_stored['color'] != "") { $val = $typography_stored['color']; } + $output .= '
    '; + $output .= ''; + + break; + + case "border": + + $default = $value['std']; + $border_stored = get_option( $value['id'] ); + + /* Border Width */ + $val = $default['width']; + if ( $border_stored['width'] != "") { $val = $border_stored['width']; } + $output .= ''; + + /* Border Style */ + $val = $default['style']; + if ( $border_stored['style'] != "") { $val = $border_stored['style']; } + $solid = ''; $dashed = ''; $dotted = ''; + if($val == 'solid'){ $solid = 'selected="selected"'; } + if($val == 'dashed'){ $dashed = 'selected="selected"'; } + if($val == 'dotted'){ $dotted = 'selected="selected"'; } + + $output .= ''; + + /* Border Color */ + $val = $default['color']; + if ( $border_stored['color'] != "") { $val = $border_stored['color']; } + $output .= '
    '; + $output .= ''; + + break; + + case "images": + $i = 0; + $select_value = get_option( $value['id']); + + foreach ($value['options'] as $key => $option) + { + $i++; + + $checked = ''; + $selected = ''; + if($select_value != '') { + if ( $select_value == $key) { $checked = ' checked'; $selected = 'woo-radio-img-selected'; } + } else { + if ($value['std'] == $key) { $checked = ' checked'; $selected = 'woo-radio-img-selected'; } + elseif ($i == 1 && !isset($select_value)) { $checked = ' checked'; $selected = 'woo-radio-img-selected'; } + elseif ($i == 1 && $value['std'] == '') { $checked = ' checked'; $selected = 'woo-radio-img-selected'; } + else { $checked = ''; } + } + + $output .= ''; + $output .= ''; + $output .= '
    '. $key .'
    '; + $output .= ''; + $output .= '
    '; + + } + + break; + + case "info": + $default = $value['std']; + $output .= $default; + break; + + case "string_builder": + $desc = $value['std']; + $output .= '
    '; + $output .= 'Name'; + $output .= 'Font Stack'; + $output .= ''; + + $output .= '
    '; + $output .= '

    '.$desc.'

    '; + $saved_data = get_option($value['id']); + if(!empty($saved_data)){ + foreach($saved_data as $name => $data){ + $data = stripslashes($data); + $output .= '
    '.str_replace( '_',' ',$name) .': '. $data .'
    '; + } + } + $output .= ''; + $output .= '
    '; + $output .= '
    '; + + break; + + case "heading": + + if($counter >= 2){ + $output .= '
    '."\n"; + } + $jquery_click_hook = ereg_replace( "[^A-Za-z0-9]", "", strtolower($value['name']) ); + $jquery_click_hook = "woo-option-" . $jquery_click_hook; +// $jquery_click_hook = "woo-option-" . str_replace( "&","",str_replace( "/","",str_replace( ".","",str_replace( ")","",str_replace( "( ","",str_replace( " ","",strtolower($value['name']))))))); + $menu .= '
  • '. $value['name'] .'
  • '; + $output .= '

    '.$value['name'].'

    '."\n"; + break; + } + + // if TYPE is an array, formatted into smaller inputs... ie smaller values + if ( is_array($value['type'])) { + foreach($value['type'] as $array){ + + $id = $array['id']; + $std = $array['std']; + $saved_std = get_option($id); + if($saved_std != $std){$std = $saved_std;} + $meta = $array['meta']; + + if($array['type'] == 'text') { // Only text at this point + + $output .= ''; + $output .= ''.$meta.''; + } + } + } + if ( $value['type'] != "heading" ) { + if ( $value['type'] != "checkbox" ) + { + $output .= '
    '; + } + if(!isset($value['desc'])){ $explain_value = ''; } else{ $explain_value = $value['desc']; } + $output .= '
    '. $explain_value .'
    '."\n"; + $output .= '
    '."\n"; + } + + } + + //Checks if is not the Content Builder page + if ( isset($_REQUEST['page']) && $_REQUEST['page'] != 'woothemes_content_builder' ) { + $output .= '
    '; + } + + return array($output,$menu); + +} +} + +/*-----------------------------------------------------------------------------------*/ +/* WooThemes Uploader - woothemes_uploader_function */ +/*-----------------------------------------------------------------------------------*/ + +if (!function_exists( 'woothemes_uploader_function')) { +function woothemes_uploader_function($id,$std,$mod){ + + //$uploader .= ''; + //$uploader .= ''; + + $uploader = ''; + $upload = get_option($id); + + if($mod != 'min') { + $val = $std; + if ( get_option( $id ) != "") { $val = get_option($id); } + $uploader .= ''; + } + + $uploader .= '
    Upload Image'; + + if(!empty($upload)) {$hide = '';} else { $hide = 'hide';} + + $uploader .= 'Remove'; + $uploader .='
    ' . "\n"; + $uploader .= '
    ' . "\n"; + if(!empty($upload)){ + //$upload = cleanSource($upload); // Removed since V.2.3.7 it's not showing up + $uploader .= ''; + $uploader .= ''; + $uploader .= ''; + } + $uploader .= '
    ' . "\n"; + + +return $uploader; +} +} + + +/*-----------------------------------------------------------------------------------*/ +/* Woothemes Theme Version Checker - woothemes_version_checker */ +/* @local_version is the installed theme version number */ +/*-----------------------------------------------------------------------------------*/ + +if (!function_exists( 'woothemes_version_checker')) { + function woothemes_version_checker ($local_version) { + + function do_not_cache_feeds(&$feed) { + $feed->enable_cache(false); + } + add_action( 'wp_feed_options', 'do_not_cache_feeds' ); + + // Get a SimplePie feed object from the specified feed source. + $theme_name = str_replace( "-","",strtolower(get_option( 'woo_themename'))); + $feed_url = 'http://www.woothemes.com/?feed=updates&theme=' . $theme_name; + + $rss = fetch_feed($feed_url); + + // Of the RSS is failed somehow. + if ( is_wp_error($rss) ) { + + /* + $error = $rss->get_error_code(); + $update_message = '
    Update notifier failed ('.$error.')
    '; + return $update_message; + */ + // Return without notification + return; + + } + + //Figure out how many total items there are, but limit it to 5. + $maxitems = $rss->get_item_quantity(100); + + // Build an array of all the items, starting with element 0 (first element). + $rss_items = $rss->get_items(0, $maxitems); + if ($maxitems == 0) { $latest_version_via_rss = 0; } + else { + // Loop through each feed item and display each item as a hyperlink. + foreach ( $rss_items as $item ) : + $latest_version_via_rss = $item->get_title(); + endforeach; + } + //Check if version is the latest - assume standard structure x.x.x + $pieces_rss = explode( ".", $latest_version_via_rss); + $pieces_local = explode( ".", $local_version); + //account for null values in second position x.2.x + + if(isset($pieces_rss[0]) && $pieces_rss[0] != 0) { + + if (!isset($pieces_rss[1])) + $pieces_rss[1] = '0'; + + if (!isset($pieces_local[1])) + $pieces_local[1] = '0'; + + //account for null values in third position x.x.3 + if (!isset($pieces_rss[2])) + $pieces_rss[2] = '0'; + + + if (!isset($pieces_local[2])) + $pieces_local[2] = '0'; + + + //do the comparisons + $version_sentinel = false; + + if ($pieces_rss[0] > $pieces_local[0]) { + $version_sentinel = true; + } + if (($pieces_rss[1] > $pieces_local[1]) AND ($version_sentinel == false) AND ($pieces_rss[0] == $pieces_local[0])) { + $version_sentinel = true; + } + if (($pieces_rss[2] > $pieces_local[2]) AND ($version_sentinel == false) AND ($pieces_rss[0] == $pieces_local[0]) AND ($pieces_rss[1] == $pieces_local[1])) { + $version_sentinel = true; + } + + //set version checker message + if ($version_sentinel == true) { + $update_message = '
    Theme update is available (v.' . $latest_version_via_rss . ') - Get the new version.
    '; + } + else { + $update_message = ''; + } + } else { + $update_message = ''; + } + + return $update_message; + + } +} + +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-medialibrary-uploader.php b/src/wp-content/themes/bloggingstream/functions/admin-medialibrary-uploader.php new file mode 100644 index 00000000..a10f296f --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-medialibrary-uploader.php @@ -0,0 +1,421 @@ + array( + 'name' => __( 'WooFramework Internal Container' ), + ), + 'public' => true, + 'show_ui' => false, + 'capability_type' => 'post', + 'hierarchical' => false, + 'rewrite' => false, + 'supports' => array( 'title', 'editor' ), + 'query_var' => false, + 'can_export' => true, + 'show_in_nav_menus' => false + ) ); + + } // End woothemes_mlu_init() + +} // End IF Statement + +/*-----------------------------------------------------------------------------------*/ +/* woothemes_mlu_css */ +/* +/* Add the Thickbox CSS file and specific loading and button images to the header +/* on the pages where this function is called. +/*-----------------------------------------------------------------------------------*/ + +if ( ! function_exists( 'woothemes_mlu_css' ) ) { + + function woothemes_mlu_css () { + + $_html = ''; + + $_html .= '' . "\n"; + $_html .= '' . "\n"; + + echo $_html; + + } // End woothemes_mlu_css() + +} // End IF Statement + +/*-----------------------------------------------------------------------------------*/ +/* woothemes_mlu_js */ +/* +/* Register and enqueue (load) the necessary JavaScript file for working with the +/* Media Library-driven AJAX File Uploader Module. +/*-----------------------------------------------------------------------------------*/ + +if ( ! function_exists( 'woothemes_mlu_js' ) ) { + + function woothemes_mlu_js () { + + // Register custom scripts for the Media Library AJAX uploader. + wp_register_script( 'woo-medialibrary-uploader', get_template_directory_uri() . '/functions/js/woo-medialibrary-uploader.js', array( 'jquery', 'thickbox' ) ); + wp_enqueue_script( 'woo-medialibrary-uploader' ); + wp_enqueue_script( 'media-upload' ); + + } // End woothemes_mlu_js() + +} // End IF Statement + +/*-----------------------------------------------------------------------------------*/ +/* woothemes_medialibrary_uploader */ +/* +/* WooThemes Uploader Using the WordPress Media Library. +/* +/* Parameters: +/* - string $_id - A token to identify this field (the name). +/* - string $_value - The value of the field, if present. +/* - string $_mode - The display mode of the field. +/* - string $_desc - An optional description of the field. +/* - int $_postid - An optional post id (used in the meta boxes). +/* +/* Dependencies: +/* - woothemes_mlu_get_silentpost() +/*-----------------------------------------------------------------------------------*/ + +if ( ! function_exists( 'woothemes_medialibrary_uploader' ) ) { + + function woothemes_medialibrary_uploader ( $_id, $_value, $_mode = 'full', $_desc = '', $_postid = 0 ) { + + $output = ''; + + $id = ''; + $class = ''; + $int = ''; + $value = ''; + + $id = strip_tags( strtolower( $_id ) ); + + // If a post id is present, use it. Otherwise, search for one based on the $_id. + if ( $_postid != 0 ) { + + $int = $_postid; + + } else { + + $int = woothemes_mlu_get_silentpost( $id ); // Change for each field, using a "silent" post. If no post is present, one will be created. + + } // End IF Statement + + + // If we're on a post add/edit screen, call the post meta value. + if ( $_mode == 'postmeta' ) { + + $value = get_post_meta( $_postid, $id, true ); + + } else { + + $value = get_option( $id ); + + } // End IF Statement + + // If a value is passed and we don't have a stored value, use the value that's passed through. + if ( $_value != '' && $value == '' ) { + + $value = $_value; + + } // End IF Statement + + if ( $value ) { $class = ' has-file'; } // End IF Statement + + // $output .= '' . "\n"; + + $output .= '' . "\n"; + $output .= '' . "\n"; + + if ( $_desc != '' ) { + + $output .= '' . $_desc . '' . "\n"; + + } // End IF Statement + + // $output .= '' . __( 'Upload' ) . ''; + $output .= '
    ' . "\n"; + + if ( $value != '' ) { + + $remove = 'Remove'; + + $image = preg_match( '/(^.*\.jpg|jpeg|png|gif|ico*)/i', $value ); + + if ( $image ) { + + $output .= ''.$remove.''; + + } else { + + $parts = explode( "/", $value ); + + for( $i = 0; $i < sizeof( $parts ); ++$i ) { + + $title = $parts[$i]; + + } // End FOR Loop + + // No output preview if it's not an image. + + $output .= ''; + + // Standard generic output if it's not an image. + + $title = __( 'View File', 'woothemes' ); + + $output .= '
    '.$title.'' . $remove . '
    '; + + } // End IF Statement + + } // End IF Statement + + $output .= '
    ' . "\n"; + + return $output; + + } // End woothemes_medialibrary_uploader() + +} // End IF Statement + +/*-----------------------------------------------------------------------------------*/ +/* woothemes_mlu_get_silentpost */ +/* +/* Use "silent" posts in the database to store relationships for images. +/* This also creates the facility to collect galleries of, for example, logo images. +/* +/* Return: $_postid. +/* +/* If no "silent" post is present, one will be created with the type "wooframework" +/* and the post_name of "woo-wf-$_token". +/* +/* Example Usage: +/* woothemes_mlu_get_silentpost ( 'woo_logo' ); +/*-----------------------------------------------------------------------------------*/ + +if ( ! function_exists( 'woothemes_mlu_get_silentpost' ) ) { + + function woothemes_mlu_get_silentpost ( $_token ) { + + global $wpdb; + + $_id = 0; + + // Check if the token is valid against a whitelist. + + // $_whitelist = array( 'woo_logo', 'woo_custom_favicon', 'woo_body_img', 'woo_ad_top_image' ); + + // Sanitise the token. + + $_token = strtolower( str_replace( ' ', '_', $_token ) ); + + // if ( in_array( $_token, $_whitelist ) ) { + + if ( $_token ) { + + // Tell the function what to look for in a post. + + $_args = array( 'post_type' => 'wooframework', 'post_name' => 'woo-wf-' . $_token, 'post_status' => 'draft', 'comment_status' => 'closed', 'ping_status' => 'closed' ); + + // Look in the database for a "silent" post that meets our criteria. + + $query = 'SELECT ID FROM ' . $wpdb->posts . ' WHERE post_parent = 0'; + + foreach ( $_args as $k => $v ) { + + $query .= ' AND ' . $k . ' = "' . $v . '"'; + + } // End FOREACH Loop + + $query .= ' LIMIT 1'; + + $_posts = $wpdb->get_row( $query ); + + // If we've got a post, loop through and get it's ID. + + if ( count( $_posts ) ) { + + $_id = $_posts->ID; + + } else { + + // If no post is present, insert one. + + // Prepare some additional data to go with the post insertion. + + $_words = explode( '_', $_token ); + + $_title = join( ' ', $_words ); + + $_title = ucwords( $_title ); + + $_post_data = array( 'post_title' => $_title ); + + $_post_data = array_merge( $_post_data, $_args ); + + $_id = wp_insert_post( $_post_data ); + + } // End IF Statement + + } // End IF Statement + + // echo 'POST - ' . $_token . ' ' . $_id; + + return $_id; + + } // End woothemes_mlu_get_silentpost() + +} // End IF Statement + +/*-----------------------------------------------------------------------------------*/ +/* woothemes_mlu_insidepopup */ +/* +/* Trigger code inside the Media Library popup. +/*-----------------------------------------------------------------------------------*/ + +if ( ! function_exists( 'woothemes_mlu_insidepopup' ) ) { + + function woothemes_mlu_insidepopup () { + + if ( isset( $_REQUEST['is_woothemes'] ) && $_REQUEST['is_woothemes'] == 'yes' ) { + + add_action( 'admin_head', 'woothemes_mlu_js_popup' ); + add_filter( 'media_upload_tabs', 'woothemes_mlu_modify_tabs' ); + + } // End IF Statement + + } // End woothemes_mlu_insidepopup() + +} // End IF Statement + +if ( ! function_exists( 'woothemes_mlu_js_popup' ) ) { + + function woothemes_mlu_js_popup () { + + $_woo_title = $_REQUEST['woo_title']; + + if ( ! $_woo_title ) { $_woo_title = 'file'; } // End IF Statement + +?> + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-sbm.php b/src/wp-content/themes/bloggingstream/functions/admin-sbm.php new file mode 100644 index 00000000..018e20b0 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-sbm.php @@ -0,0 +1,1401 @@ += '3.0' ) { + + $_args = array( + 'show_ui' => true, + 'public' => true, + 'publicly_queryable' => true, + '_builtin' => false + ); + + $_post_types = get_post_types( $_args, 'object' ); + + // Set certain post types that aren't allowed to have custom sidebars. + + $_disallowed_types = array( 'slide' ); + + // Make the array pluggable. + + $_disallowed_types = apply_filters( 'wooframework_sbm_disallowed_posttypes', $_disallowed_types ); + + if ( count( $_post_types ) ) { + + foreach ( $_post_types as $k => $v ) { + + if ( in_array( $k, $_disallowed_types ) ) { + + unset( $_post_types[$k] ); + + } // End IF Statement + + } // End FOREACH Loop + + } // End IF Statement + + } // End IF Statement + + if ( ( $type == 'custom_post_type' || $id == 'singular' ) && in_array( $post->post_type, array_keys( $_post_types ) ) ) { + + if( $post->post_type == $id && $sidebar_id == 'woo_sbm_custom_post_type_' . $id . '_' . $current_sidebar_id ) { + + if($sidebar_to_replace == $current_sidebar_id) { + + $current_sidebar_id = $sidebar_id; + + // Set this to prevent the system from conflicting with the template hierarchy. + $_is_replaced = true; + + } // End IF Statement + + } else { + + if ( is_singular() && $sidebar_id == 'woo_sbm_hierarchy_singular_' . $current_sidebar_id ) { + + $current_sidebar_id = $sidebar_id; + + // Set this to prevent the system from conflicting with the template hierarchy. + $_is_replaced = true; + + } // End IF Statement + + } // End IF Statement + + } else { + + //Find conditionals return required sidebar + if( $type == 'page' && $id == $post->ID ){ + + if( is_page( $post->ID ) && ! is_archive() && ! is_home() ) + + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + + // Set this to prevent the system from conflicting with the template hierarchy. + $_is_replaced = true; + + } // End IF Statement + + if( $type == 'category'/* && ! is_home() && ! $_is_replaced && ! is_singular()*/ ) { + + if( is_category($id) || ( is_single() && in_category( $id ) ) ) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + + // Set this to prevent the system from conflicting with the template hierarchy. + $_is_replaced = true; + + } // End IF Statement + + if( $type == 'post_tag'/* && ! is_home() && ! $_is_replaced*/ ) { + $tag_data = get_tag($id); + if(is_tag($tag_data->slug)) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + + // Set this to prevent the system from conflicting with the template hierarchy. + $_is_replaced = true; + + } // End IF Statement + + if( $type == 'page_template'/* && ! is_home() && ! $_is_replaced*/ ) { + if(is_page_template($id)) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + + // Set this to prevent the system from conflicting with the template hierarchy. + $_is_replaced = true; + + } // End IF Statement + + if( $type == 'hierarchy'/* && ! $_is_replaced*/ ) { + + if($id == 'front_page') + if(is_front_page()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'home') + if(is_home()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'single') + if(is_single()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'page') + if(is_page()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'singular') + if(is_singular()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'date') + if(is_date()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'archive') + if(is_archive()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'category') + if(is_category()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'tag') + if(is_tag()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'tax') + if(is_tax()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'author') + if(is_author()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'search') + if(is_search()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'paged') + if(is_paged()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == 'attach') + if(is_attach()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + if($id == '404') + if(is_404()) + if($sidebar_to_replace == $current_sidebar_id) + $current_sidebar_id = $sidebar_id; + + } // End IF Statement + + if ($type == '') { + $type_tax = $sidebar['conditionals']['type']; + if ($type_tax != '') { + + // Get taxonomy query object + global $wp_query; + + $taxonomy_archive_query_obj = $wp_query->get_queried_object(); + + if ( (is_tax( $taxonomy_archive_query_obj->name, $taxonomy_archive_query_obj->slug ) ) && ( $id == $taxonomy_archive_query_obj->term_id ) ) { $sentinel = true; } // End IF Statement + + if ( ! $sentinel ) { + + // CUSTOM TAXONOMIES + $wp_custom_taxonomy_args = array( '_builtin' => false ); + $woo_wp_custom_taxonomies = array(); + $woo_wp_custom_taxonomies = get_taxonomies($wp_custom_taxonomy_args,'objects' ); + $sentinel = false; + foreach ($woo_wp_custom_taxonomies as $woo_wp_custom_taxonomy) { + // checks for match to taxonomy + if ($type_tax == $woo_wp_custom_taxonomy->name) { + $term_list = get_the_terms( 0, $woo_wp_custom_taxonomy->name ); + $term_results = ''; + if ($term_list) { + foreach ($term_list as $term_item) { + if ( (is_tax($woo_wp_custom_taxonomy->name, $term_item->slug)) && ($id == $term_item->term_id) ) { $sentinel = true; } // End IF Statement + } // End FOREACH Loop + } // End IF Statement + } // End IF Statement + } // End FOREACH Loop + + } // End IF Statement + + if ($sentinel) { + if($sidebar_to_replace == $current_sidebar_id) { + $current_sidebar_id = $sidebar_id; + } // End IF Statement + } // End IF Statement + } // End IF Statement + } // End IF Statement + + } // End Custom Post Type IF Statement + + } // End FOREACH Loop + } // End IF Statement + + return $current_sidebar_id; + +} // End woo_sbm_sidebar() + +//Adding the filter that injects the right sidebar ID back into the woo_sidebar function. +add_filter( 'woo_inject_sidebar','woo_sbm_sidebar' ); + +// Register new widgetized areas via plugin +if (!function_exists( 'woo_sbm_widgets_init')) { + function woo_sbm_widgets_init() { + if ( !function_exists( 'register_sidebars') ) + return; + + $woo_sbm_options = get_option( 'sbm_woo_sbm_options' ); + if(!empty($woo_sbm_options['sidebars'])){ + foreach($woo_sbm_options['sidebars'] as $sidebars){ + if(empty($sidebars['conditionals']['piggy'])) + register_sidebar($sidebars['setup']); + } + } + } +} + +add_action( 'init', 'woo_sbm_widgets_init' ); + +/* Sidebar Manager - Reset Function +--------------------------------------------------*/ + +function woothemes_sbm_reset () { + + $default_data = array( 'sidebars' => array() ); + + update_option( 'sbm_woo_sbm_options', $default_data ); + +} // End woothemes_sbm_reset() + +function woothemes_sbm_page(){ + + global $wp_registered_sidebars; + + // If the user wants to reset the script, we reset the script. + if ( isset( $_POST['woo_save'] ) && $_POST['woo_save'] == 'sbm_reset' ) { + + woothemes_sbm_reset(); + + } // End IF Statement + + //Load SBM settings + $init_array = array( 'sidebars' => array(),'settings' => array( 'infobox' => 'show')); + add_option( 'sbm_woo_sbm_options',$init_array); + $woo_sbm_options = get_option( 'sbm_woo_sbm_options' ); + + //Error checking + if(!empty($woo_sbm_options['sidebars'])){ + foreach($woo_sbm_options['sidebars'] as $key => $options){ + if(empty($key)){ unset($woo_sbm_options['sidebars'][$key]); } + } + + } + + //delete_option( 'sbm_woo_sbm_options' ); + $themename = get_option( 'woo_themename' ); + $manualurl = get_option( 'woo_manual' ); + + //Framework Version in Backend Head + $woo_framework_version = get_option( 'woo_framework_version' ); + + //Version in Backend Head + $theme_data = get_theme_data( get_template_directory() . '/style.css' ); + $local_version = $theme_data['Version']; + + //Outout for original sidebars, and new sidebars + $init_sidebars = ''; + $init_sidebar = ''; + $new_sidebars = ''; + $counter = 0; + foreach($wp_registered_sidebars as $sidebar){ + if(!strstr($sidebar['id'],'woo_sbm_')){ + $counter++; + if($counter == 1) { $init_sidebar = $sidebar['name']; } + $init_sidebars .= ''; + } else { + $new_sidebars .= ''; + } + }; + + //Start script output + ?> + + +
    + + +
    +
    + +
    + +

    WooThemes Sidebar Manager

    + +

    You're one step closer to having total control over your theme. This Sidebar Manager is available only to themes running + version 3.0.0 of the WooFramework. If you can see this message you're framework is up-to-date. Good Job!

    + +

    If you have not downloaded the latest version of this theme, but rather updated it from the theme options backend, you will need to upgrade + your theme manually if you're want to make use of this Sidebar Manager feature. Please take note of the following:

    + +

    Manual Installation: Replace all the dynamic_sidebar functions with the new + woo_sidebar and replace all is_active_sidebar with the new woo_active_sidebar. These are typically found in the + sidebar.php & footer.php files.

    + + Close + +
    + + +
    + +
    +

    Choose a Template

    +
      + 'ASC')); ?> + +
    • Pages [-] +
        + ID,$woo_sbm_options['sidebars'])){ continue; } + echo '
      • ' . $page->post_title . 'type=page&name='. urlencode( $page->post_title ) .'&slug='.$page->post_name.'&id='. $page->ID.'&other=null
      • '; + } ?> +
      +
    • + +
    • Page Templates [+] +
        + $template){ + //$template = str_replace( '.','',$template); + //if(array_key_exists( 'woo_sbm_page_template_'.$template,$woo_sbm_options['sidebars'])){ continue; } + echo '
      • ' . $name .'type=page_template&name='. urlencode( $name ) .'&slug='.$template.'&id=null&other=null
      • '; + }; ?> +
      +
    • + +
    • [+] +
        term_id,$woo_sbm_options['sidebars'])){ continue; } + echo '
      • ' . $term->name . 'type='. $taxonomy .'&name='. urlencode( $term->name ) .'&slug='.$term->slug.'&id='.$term->term_id.'&other='.$taxonomy.'
      • '; + }?> +
      +
    • + + +
    • Template Hierarchy [+] +
        + 'front_page', + 'Home' => 'home', + 'Posts (single.php)' => 'single', + 'Pages' => 'page', + 'Singular (posts and pages)' => 'singular', + 'All Archives' => 'archive', + 'Category Archive' => 'category', + 'Tag Archive' => 'tag', + 'Taxonomy Archive' => 'tax', + 'Author Archive' => 'author', + 'Date Archive' => 'date', + 'Search Results' => 'search', + 'Paged' => 'paged', + 'Attachment' => 'attach', + '404' => '404' + ); + foreach($heirarchy as $name => $item){ + //if(array_key_exists ( 'woo_sbm_hierarchy_' . $item,$woo_sbm_options['sidebars'])){ continue; } + echo '
      • '.$name.'type=hierarchy&name='.$name.'&slug='.$item.'&id=null&other=null&other=null
      • '; + } + ?> +
      +
    • + = '3.0' ) { + + $_args = array( + 'show_ui' => true, + 'public' => true, + 'publicly_queryable' => true, + '_builtin' => false + ); + + $_post_types = get_post_types( $_args, 'object' ); + + // Set certain post types that aren't allowed to have custom sidebars. + + $_disallowed_types = array( 'slide' ); + + // Make the array pluggable. + + $_disallowed_types = apply_filters( 'wooframework_sbm_disallowed_posttypes', $_disallowed_types ); + + if ( count( $_post_types ) ) { + + foreach ( $_post_types as $k => $v ) { + + if ( in_array( $k, $_disallowed_types ) ) { + + unset( $_post_types[$k] ); + + } // End IF Statement + + } // End FOREACH Loop + + } // End IF Statement + + if ( count( $_post_types ) ) { + ?> +
    • + Custom Post Type[+] + ' . "\n"; + + foreach ( $_post_types as $k => $v ) { + + $_html .= '
    • ' . $v->labels->name . 'type=custom_post_type&name=' . urlencode( $v->labels->name ) . '&slug=' . urlencode( $k ) . '&id=' . urlencode( $k ) . '&other=' . urlencode( $k ) . '
    • ' . "\n"; + + } // End FOREACH Loop + + $_html .= '
    ' . "\n"; + + echo $_html; + + ?> + + + +
    + +
    + +
    + +
    + + Start by selecting a template from the menu on the left for your new sidebar. The new sidebar will be available on the Widgets page.
    Please note that, if custom sidebars are created for categories, the sidebar of the posts in that category will use the first custom sidebar created for categories assigned to that post (eg: if "Category 1" and "Category 2" are assigned to the post and the "Category 2" custom sidebar is created first, that sidebar will be displayed on the single post template).*/ ?>
    + + +
    + +
    + +

    Custom Sidebars Newly created sidebars

    + + + +
    No sidebars added yet.
    + +
    + +
    + +
    +
    +
    +
    + +
    + + + + +
    +
    +
    +
    +    
    +    
    +
    + + $value ) { + if ( sanitize_title($value['name']) == $index ) { + $index = $key; + break; + } + } + } + + $sidebar_data = $wp_registered_sidebars[$index]; + + $woo_sbm_new_set = array( "setup" => array( 'name' => $sidebar_title, + 'id' => $new_id, + 'description' => $sidebar_description, + 'before_widget' => $sidebar_data['before_widget'], + 'after_widget' => $sidebar_data['after_widget'], + 'before_title' => $sidebar_data['before_title'], + 'after_title' => $sidebar_data['after_title'] + ), + "conditionals" => array( 'name' => $sidebar_title, + 'type' => $type, + 'id' => $id, + 'conditional' => $conditional, + 'sidebar_id' => $new_id, + 'other' => $other, + 'sidebar_to_replace' => $sidebar_to_replace, + 'piggy' => $sidebar_piggyback + ) + ); + + $woo_sbm_options['sidebars'][$new_id] = $woo_sbm_new_set; + + update_option( 'sbm_woo_sbm_options',$woo_sbm_options); + + if(!empty($sidebar_piggyback)){ + $piggy = '1'; + } else { $piggy = '0';} + + echo "$type|$name|$slug|$id|$other|$conditional|$stage|$sidebar_title|$new_id|$piggy"; + } + + if($save_type == 'woo_sbm_delete-sidebar'){ + $id = $_POST['data']; + $ids = array(); + $woo_sbm_options_temp = $woo_sbm_options; + if(!empty($woo_sbm_options['sidebars'])){ + $pos = ''; + foreach($woo_sbm_options['sidebars'] as $top_id => $sidebar){ + $sidebar_piggy = $sidebar['conditionals']['piggy']; + + if($id == $top_id OR $id == $sidebar_piggy){ + unset($woo_sbm_options_temp['sidebars'][$top_id]); + $ids[] = $top_id; + } + + if($id == $top_id){ $pos = $id; } + } + } + update_option( 'sbm_woo_sbm_options',$woo_sbm_options_temp); + if(is_array($ids)){ + $id = implode( ',#',$ids); + } + echo "#$id|$pos"; + } + + if($save_type == 'woo_sbm_save-sidebar'){ + + $data = $_POST['data']; + + parse_str($data,$data_array); + + $id = $data_array['sidebar_id']; + $sidebar_to_replace = $data_array['sidebar_to_replace']; + $name = $data_array['sidebar_name']; + $desc = $data_array['sidebar_description']; + + + $woo_sbm_options['sidebars'][$id]['conditionals']['sidebar_to_replace'] = $sidebar_to_replace; + $woo_sbm_options['sidebars'][$id]['setup']['name'] = $name; + $woo_sbm_options['sidebars'][$id]['conditionals']['name'] = $name; + $woo_sbm_options['sidebars'][$id]['setup']['description'] = $desc; + + $sidebar_to_replace_nice = $wp_registered_sidebars[$sidebar_to_replace]['name']; + echo "$name|$sidebar_to_replace_nice"; + + update_option( 'sbm_woo_sbm_options',$woo_sbm_options); + + } + + if($save_type == 'woo_sbm_dismiss_intro'){ + + //$data = $_POST['data']; + $temp_options = get_option( 'sbm_woo_sbm_options' ); + $temp_options['settings']['infobox'] = 'hide'; + + update_option( 'sbm_woo_sbm_options',$temp_options); + + + } + die(); + +} + + + +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-seo.php b/src/wp-content/themes/bloggingstream/functions/admin-seo.php new file mode 100644 index 00000000..d0b1efdd --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-seo.php @@ -0,0 +1,377 @@ + 'Page title; Blog title', + 'b' => 'Page title;', + 'c' => 'Blog title; Page title;', + 'd' => 'Page title; Blog description', + 'e' => 'Blog title; Page title; Blog description' + ); + + $seo_options = array(); + + $seo_options[] = array( "name" => "General Settings", + "icon" => "general", + "type" => "heading" ); + + $seo_options[] = array( "name" => "Please Read", + "type" => "info", + "std" => "Welcome to the WooSEO feature.
    Here we help you take control of your search engine readiness with some in-built theme options. Our themes do however support some of WordPress.org's most commonly used SEO plugins - All-in-One SEO Pack, Headspace 2 and WordPress SEO By Yoast. Use the checkbox below to use 3rd party plugin data." ); + + $seo_options[] = array( "name" => "Use 3rd Party Plugin Data", + "desc" => "Meta data added to custom fields in posts and pages will be extracted and used where applicable. This typically does not include Homepages and Archives, and only Singular templates.", + "id" => $shortname."_use_third_party_data", + "std" => "false", + "type" => "checkbox" ); + + $seo_options[] = array( "name" => "Hide SEO custom fields", + "desc" => "Check this box to hide the input fields created in the post and page edit screens.", + "id" => $shortname."_hide_fields", + "std" => "false", + "type" => "checkbox" ); + + $seo_options[] = array( "name" => "Page Title", + "icon" => "misc", + "type" => "heading" ); + + $seo_options[] = array( "name" => "Separator", + "desc" => "Define a new separator character for your page titles.", + "id" => $shortname."_seperator", + "std" => "|", + "type" => "text" ); + + $seo_options[] = array( "name" => "Blog Title", + "desc" => "NOTE: This is the same setting as per the SETTINGS > GENERAL tab in the WordPress backend.", + "id" => "blogname", + "std" => "", + "type" => "text" ); + + $seo_options[] = array( "name" => "Blog Description", + "desc" => "NOTE: This is the same setting as per the SETTINGS > GENERAL tab in the WordPress backend.", + "id" => "blogdescription", + "std" => "", + "type" => "text" ); + + $seo_options[] = array( "name" => "Enable woo_title()", + "desc" => "woo_title() makes use of WordPress's built in wp_title() function to control the output for your page titles. It's also recommended for use with plugins.", + "id" => $shortname."_wp_title", + "std" => "false", + "class" => "collapsed", + "type" => "checkbox" ); + + $seo_options[] = array( "name" => "Disable Custom Titles", + "desc" => "If you prefer to have uniform titles across you theme. Alternatively they will be generated from custom fields and/or plugin data.", + "id" => $shortname."_wp_custom_field_title", + "std" => "false", + "class" => "hidden", + "type" => "checkbox" ); + + $seo_options[] = array( "name" => "Paged Variable", + "desc" => "The name variable that will appear then paging through archives.", + "id" => $shortname."_paged_var", + "std" => "Page", + "class" => "hidden", + "type" => "text" ); + + $seo_options[] = array( "name" => "Paged Variable Position", + "desc" => "Change the position where the paged variable will appear.", + "id" => $shortname."_paged_var_pos", + "std" => "before", + "class" => "hidden", + "options" => array( 'before' => 'Before', + 'after' => 'After'), + "type" => "select2" ); + + $seo_options[] = array( "name" => "Homepage Title Layout", + "desc" => "Define the order the title, description and meta data appears in.", + "id" => $shortname."_home_layout", + "std" => "", + "class" => "hidden", + "options" => array( 'a' => 'Blog title; blog description', + 'b' => 'Blog title', + 'c' => 'Blog description'), + "type" => "select2" ); + + $seo_options[] = array( "name" => "Single Title Layout", + "desc" => "Define the order the title, description and meta data appears in.", + "id" => $shortname."_single_layout", + "std" => "", + "class" => "hidden", + "options" => $inner_pages, + "type" => "select2" ); + + $seo_options[] = array( "name" => "Page Title Layout", + "desc" => "Define the order the title, description and meta data appears in.", + "id" => $shortname."_page_layout", + "std" => "", + "class" => "hidden", + "options" => $inner_pages, + "type" => "select2" ); + + $seo_options[] = array( "name" => "Archive Title Layout", + "desc" => "Define the order the title, description and meta data appears in.", + "id" => $shortname."_archive_layout", + "std" => "", + "class" => "hidden", + "options" => $inner_pages, + "type" => "select2" ); + + $seo_options[] = array( "name" => "Indexing Meta", + "icon" => "misc", + "type" => "heading" ); + + /*$seo_options[] = array( "name" => "Add Indexing Meta", + "desc" => "Add links to the header telling the search engine what the start, next, previous and home urls are.", + "id" => $shortname."_meta_basics", + "std" => "false", + "type" => "checkbox" ); */ + + $seo_options[] = array( "name" => "Archive Indexing", + "desc" => "Select which archives to index on your site. Aids in removing duplicate content from being indexed, preventing content dilution.", + "id" => $shortname."_meta_indexing", + "std" => "category", + "type" => "multicheck", + "options" => array( 'category' => 'Category Archives', + 'tag' => 'Tag Archives', + 'author' => 'Author Pages', + 'search' => 'Search Results', + 'date' => 'Date Archives')); + + $seo_options[] = array( "name" => "Set meta for Posts & Pages to 'follow' by default", + "desc" => "By default the woo_meta(); adds a 'nofollow' meta to post and pages, meaning search engines will not index pages leading away from these pages.", + "id" => $shortname."_meta_single_follow", + "std" => "", + "type" => "checkbox" ); + + + $seo_options[] = array( "name" => "Description Meta", + "icon" => "misc", + "type" => "heading" ); + + $seo_options[] = array( "name" => "Homepage Description", + "desc" => "Choose where to populate your Homepage meta description from.", + "id" => $shortname."_meta_home_desc", + "std" => "a", + "options" => array( "a" => "Off", + "b" => "From WP Site Description", + "c" => "From Custom Homepage Description"), + "type" => "radio" ); + + $seo_options[] = array( "name" => "Custom Homepage Description", + "desc" => "Add a custom meta description to your homepage.", + "id" => $shortname."_meta_home_desc_custom", + "std" => "", + "type" => "textarea" ); + + $seo_options[] = array( "name" => "Single Page/Post Description", + "desc" => "Add your post/page description from custom fields. * See below", + "id" => $shortname."_meta_single_desc", + "std" => "a", + "options" => array( "a" => "Off *", + "b" => "From Customs Field and/or Plugins", + "c" => "Automatically from Post/Page Content", + ), + "type" => "radio" ); + + $seo_options[] = array( "name" => "Global Post/Page Descriptions", + "desc" => "Add a custom meta description to your posts and pages. This will only show if no other data is available from the selection above. Will still be added even if setting above is set to \"Off\".", + "id" => $shortname."_meta_single_desc_sitewide", + "std" => "", + "class" => "collapsed", + "type" => "checkbox" ); + + $seo_options[] = array( "name" => "Add Global Description", + "desc" => "Add your global decription.", + "id" => $shortname."_meta_single_desc_custom", + "std" => "", + "class" => "hidden", + "type" => "textarea" ); + + $seo_options[] = array( "name" => "Keyword Meta", + "icon" => "misc", + "type" => "heading" ); + + $seo_options[] = array( "name" => "Homepage Keywords", + "desc" => "Choose where to populate your Homepage meta description from.", + "id" => $shortname."_meta_home_key", + "std" => "a", + "options" => array( "a" => "Off", + "c" => "From Custom Homepage Keywords"), + "type" => "radio" ); + + $seo_options[] = array( "name" => "Custom Homepage Keywords", + "desc" => "Add a (comma separated) list of keywords to your homepage.", + "id" => $shortname."_meta_home_key_custom", + "std" => "", + "type" => "textarea" ); + + $seo_options[] = array( "name" => "Single Page/Post Keywords", + "desc" => "Add your post/page keywords from custom field. * See below", + "id" => $shortname."_meta_single_key", + "std" => "a", + "options" => array( "a" => "Off *", + "b" => "From Custom Fields and/or Plugins", + "c" => "Automatically from Post Tags & Categories"), + "type" => "radio" ); + + $seo_options[] = array( "name" => "Custom Post/Page Keywords", + "desc" => "Add custom meta keywords to your posts and pages. This will only show if no other data is available from the options above. Even if the option above is set to 'Off', this will still be added to your site.", + "id" => $shortname."_meta_single_key_sitewide", + "std" => "", + "class" => "collapsed", + "type" => "checkbox" ); + + $seo_options[] = array( "name" => "Custom Post/Page Keywords", + "desc" => "Add a (comma separated) list of keywords to your posts and pages.", + "id" => $shortname."_meta_single_key_custom", + "std" => "", + "class" => "hidden", + "type" => "textarea" ); + + + update_option( 'woo_seo_template',$seo_options); + + + ?> + +
    +

    3rd Party SEO Plugin(s) Detected - Some WooTheme SEO functionality has been disabled.

    "; + + } + + ?> +

    This site is set to Private - SEO is disabled, change settings here.

    "; + + } + + ?> +
    Options Updated
    +
    Options Reset
    +
    + + + + + + +
    +
    +
      + +
    +
    +
    + +
    +
    + +
    +
    + + + + +
    + + + + + + + +
    + + +
    + + + +
    + + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-setup.php b/src/wp-content/themes/bloggingstream/functions/admin-setup.php new file mode 100644 index 00000000..a43cb61c --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-setup.php @@ -0,0 +1,275 @@ +\n"; + if ($style != '') { + echo ''."\n\n"; + } else { + $style = get_option( 'woo_alt_stylesheet' ); + if( $style != '' ) { + // Sanitize value. + $style = strtolower( strip_tags( trim( $style ) ) ); + echo ''."\n\n"; + } else { + echo ''."\n\n"; + } + } + + } +} + +/*-----------------------------------------------------------------------------------*/ +/* Output favicon link - woo_custom_favicon() */ +/*-----------------------------------------------------------------------------------*/ +if ( ! function_exists( 'woo_output_custom_favicon' ) ) { + function woo_output_custom_favicon() { + // Favicon + if(get_option( 'woo_custom_favicon') != '') { + echo "\n"; + echo ''."\n\n"; + } + + } +} + +/*-----------------------------------------------------------------------------------*/ +/* Load textdomain - woo_load_textdomain() */ +/*-----------------------------------------------------------------------------------*/ +if ( ! function_exists( 'woo_load_textdomain' ) ) { + function woo_load_textdomain() { + + load_theme_textdomain( 'woothemes' ); + load_theme_textdomain( 'woothemes', get_template_directory() . '/lang' ); + if ( function_exists( 'load_child_theme_textdomain' ) ) + load_child_theme_textdomain( 'woothemes' ); + + } +} + +add_action( 'init', 'woo_load_textdomain' ); + +/*-----------------------------------------------------------------------------------*/ +/* Output CSS from standarized options */ +/*-----------------------------------------------------------------------------------*/ +if ( ! function_exists( 'woo_head_css' ) ) { + function woo_head_css() { + + $output = ''; + $text_title = get_option( 'woo_texttitle' ); + $tagline = get_option( 'woo_tagline' ); + $custom_css = get_option( 'woo_custom_css' ); + + $template = get_option( 'woo_template' ); + if (is_array($template)) { + foreach($template as $option){ + if(isset($option['id'])){ + if($option['id'] == 'woo_texttitle') { + // Add CSS to output + if ( $text_title == "true" ) { + $output .= '#logo img { display:none; } #logo .site-title { display:block; }' . "\n"; + if ( $tagline == "false" ) + $output .= '#logo .site-description { display:none; }' . "\n"; + else + $output .= '#logo .site-description { display:block; }' . "\n"; + } + } + } + } + } + + if ($custom_css <> '') { + $output .= $custom_css . "\n"; + } + + // Output styles + if ($output <> '') { + $output = strip_tags($output); + echo "\n"; + $output = "\n\n"; + echo $output; + } + + } +} + + + +/*-----------------------------------------------------------------------------------*/ +/* Output custom.css - woo_custom_css() */ +/*-----------------------------------------------------------------------------------*/ +if (!function_exists( 'woo_output_custom_css')) { + function woo_output_custom_css() { + + // Custom.css insert + echo "\n"; + echo ''."\n"; + + } +} + +/*-----------------------------------------------------------------------------------*/ +/* Post Images from WP2.9+ integration /* +/*-----------------------------------------------------------------------------------*/ +if(function_exists( 'add_theme_support')){ + if(get_option( 'woo_post_image_support') == 'true'){ + add_theme_support( 'post-thumbnails' ); + // set height, width and crop if dynamic resize functionality isn't enabled + if ( get_option( 'woo_pis_resize') != 'true' ) { + $thumb_width = get_option( 'woo_thumb_w' ); + $thumb_height = get_option( 'woo_thumb_h' ); + $single_width = get_option( 'woo_single_w' ); + $single_height = get_option( 'woo_single_h' ); + $hard_crop = get_option( 'woo_pis_hard_crop' ); + if($hard_crop == 'true') {$hard_crop = true; } else { $hard_crop = false;} + set_post_thumbnail_size($thumb_width,$thumb_height, $hard_crop); // Normal post thumbnails + add_image_size( 'single-post-thumbnail', $single_width, $single_height, $hard_crop ); + } + } +} + + +/*-----------------------------------------------------------------------------------*/ +/* Enqueue comment reply script */ +/*-----------------------------------------------------------------------------------*/ +if (!function_exists( 'woo_comment_reply')) { + function woo_comment_reply() { + if ( is_singular() ) wp_enqueue_script( 'comment-reply' ); + } +} +add_action( 'get_header', 'woo_comment_reply' ); + + +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-shortcode-generator.php b/src/wp-content/themes/bloggingstream/functions/admin-shortcode-generator.php new file mode 100644 index 00000000..93aab141 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-shortcode-generator.php @@ -0,0 +1,183 @@ +framework_url() . 'js/colorpicker.js', array( 'jquery' ), '3.6', true ); // Loaded into the footer. + wp_enqueue_script( 'woo-colourpicker' ); + + // Register the colourpicker CSS. + wp_register_style( 'woo-colourpicker', $this->framework_url() . 'css/colorpicker.css' ); + wp_enqueue_style( 'woo-colourpicker' ); + + // Register the custom CSS styles. + wp_register_style( 'woo-shortcode-generator', $this->framework_url() . 'css/shortcode-generator.css' ); + wp_enqueue_style( 'woo-shortcode-generator' ); + + } // End IF Statement + + } // End init() + +/*----------------------------------------------------------------------------------- + filter_mce_buttons() + + * Add our new button to the tinyMCE editor. +-----------------------------------------------------------------------------------*/ + + function filter_mce_buttons( $buttons ) { + + array_push( $buttons, '|', 'woothemes_shortcodes_button' ); + + return $buttons; + + } // End filter_mce_buttons() + +/*----------------------------------------------------------------------------------- + filter_mce_external_plugins() + + * Add functionality to the tinyMCE editor as an external plugin. +-----------------------------------------------------------------------------------*/ + + function filter_mce_external_plugins( $plugins ) { + + $plugins['WooThemesShortcodes'] = $this->framework_url() . 'js/shortcode-generator/editor_plugin.js'; + + return $plugins; + + } // End filter_mce_external_plugins() + +/*----------------------------------------------------------------------------------- + Utility Functions + + * Helper functions for this class. +-----------------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------------- + framework_url() + + * Returns the full URL of the WooFramework, including trailing slash. +-----------------------------------------------------------------------------------*/ + +function framework_url() { + + return trailingslashit( get_template_directory_uri() . '/' . basename( dirname( __FILE__ ) ) ); + +} // End framework_url() + +/*----------------------------------------------------------------------------------- + ajax_action_check_url() + + * Checks if a given url (via GET or POST) exists. + * Returns JSON. + * + * NOTE: For users that are not logged in this is not called. + * The client recieves -1 in that case. +-----------------------------------------------------------------------------------*/ + +function ajax_action_check_url() { + + $hadError = true; + + $url = isset( $_REQUEST['url'] ) ? $_REQUEST['url'] : ''; + + if ( strlen( $url ) > 0 && function_exists( 'get_headers' ) ) { + + $file_headers = @get_headers( $url ); + $exists = $file_headers && $file_headers[0] != 'HTTP/1.1 404 Not Found'; + $hadError = false; + } + + echo '{ "exists": '. ($exists ? '1' : '0') . ($hadError ? ', "error" : 1 ' : '') . ' }'; + + die(); + +} // End ajax_action_check_url() + +/*----------------------------------------------------------------------------------- + shortcode_testing() + + * Used for testing that the shortcodes are functioning. +-----------------------------------------------------------------------------------*/ + +function shortcode_testing( $atts, $content = null ) { + + if ($content === null) return ''; + + return 'Working: ' . $content . '' . "\n"; + +} // End shortcode_testing() + +} // End Class + +/*----------------------------------------------------------------------------------- + INSTANTIATE CLASS +-----------------------------------------------------------------------------------*/ + +$woo_shortcode_generator = new WooThemes_Shortcode_Generator(); +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-shortcodes.php b/src/wp-content/themes/bloggingstream/functions/admin-shortcodes.php new file mode 100644 index 00000000..de70badb --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-shortcodes.php @@ -0,0 +1,2100 @@ +\n"; + echo ''."\n\n"; + } +} + +// Replace WP autop formatting +if (!function_exists( "woo_remove_wpautop")) { + function woo_remove_wpautop($content) { + $content = do_shortcode( shortcode_unautop( $content ) ); + $content = preg_replace( '#^<\/p>|^
    |

    $#', '', $content); + return $content; + } +} + +/*-----------------------------------------------------------------------------------*/ +/* 1.1 Output shortcode JS in footer */ +/*-----------------------------------------------------------------------------------*/ + +// Enqueue shortcode JS file. + +add_action( 'init', 'woo_enqueue_shortcode_js' ); + +function woo_enqueue_shortcode_js () { + + if ( is_admin() ) {} else { + + wp_enqueue_script( 'woo-shortcodes', get_template_directory_uri() . '/functions/js/shortcodes.js', array( 'jquery', 'jquery-ui-tabs' ), true ); + + } // End IF Statement + +} // End woo_enqueue_shortcode_js() + +// Check if option to output shortcode JS is active +if (!function_exists( "woo_check_shortcode_js")) { + function woo_check_shortcode_js($shortcode) { + $js = get_option( "woo_sc_js" ); + if ( !$js ) + woo_add_shortcode_js($shortcode); + else { + if ( !in_array($shortcode, $js) ) { + $js[] = $shortcode; + update_option( "woo_sc_js", $js); + } + } + } +} + +// Add option to handle JS output +if (!function_exists( "woo_add_shortcode_js")) { + function woo_add_shortcode_js($shortcode) { + $update = array(); + $update[] = $shortcode; + update_option( "woo_sc_js", $update); + } +} + +// Output queued shortcode JS in footer +if (!function_exists( "woo_output_shortcode_js")) { + function woo_output_shortcode_js() { + $option = get_option( 'woo_sc_js' ); + if ( $option ) { + + // Toggle JS output + if ( in_array( 'toggle', $option) ) { + + $output = ' + +'; + echo $output; + } + + // Reset option + delete_option( 'woo_sc_js' ); + } + } +} +add_action( 'wp_footer', 'woo_output_shortcode_js' ); + +/*-----------------------------------------------------------------------------------*/ +/* 2. Boxes - box +/*-----------------------------------------------------------------------------------*/ +/* + +Optional arguments: + - type: info, alert, tick, download, note + - size: medium, large + - style: rounded + - border: none, full + - icon: none OR full URL to a custom icon + +*/ +function woo_shortcode_box($atts, $content = null) { + extract(shortcode_atts(array( 'type' => 'normal', + 'size' => '', + 'style' => '', + 'border' => '', + 'icon' => ''), $atts)); + + $custom = ''; + if ( $icon == "none" ) + $custom = ' style="padding-left:15px;background-image:none;"'; + elseif ( $icon ) + $custom = ' style="padding-left:50px;background-image:url( '.$icon.' ); background-repeat:no-repeat; background-position:20px 45%;"'; + + + return '

    ' . do_shortcode( woo_remove_wpautop($content) ) . '
    '; +} +add_shortcode( 'box', 'woo_shortcode_box' ); + +/*-----------------------------------------------------------------------------------*/ +/* 3. Buttons - button +/*-----------------------------------------------------------------------------------*/ +/* + +Optional arguments: + - size: small, large + - style: info, alert, tick, download, note + - color: red, green, black, grey OR custom hex color (e.g #000000) + - border: border color (e.g. red or #000000) + - text: black (for light color background on button) + - class: custom class + - link: button link (e.g http://www.woothemes.com) + - window: true/false + +*/ +function woo_shortcode_button($atts, $content = null) { + extract(shortcode_atts(array( 'size' => '', + 'style' => '', + 'bg_color' => '', + 'color' => '', + 'border' => '', + 'text' => '', + 'class' => '', + 'link' => '#', + 'window' => ''), $atts)); + + + // Set custom background and border color + $color_output = ''; + if ( $color ) { + + if ( $color == "red" OR + $color == "orange" OR + $color == "green" OR + $color == "aqua" OR + $color == "teal" OR + $color == "purple" OR + $color == "pink" OR + $color == "silver" + ) { + $class .= " ".$color; + + } else { + if ( $border ) + $border_out = $border; + else + $border_out = $color; + + $color_output = 'style="background:'.$color.';border-color:'.$border_out.'"'; + + // add custom class + $class .= " custom"; + } + + } else { + + if ( $border ) + $border_out = $border; + else + $border_out = $bg_color; + + $color_output = 'style="background:'.$bg_color.';border-color:'.$border_out.'"'; + + // add custom class + $class .= " custom"; + + } // End IF Statement + + $class_output = ''; + + // Set text color + if ( $text ) + $class_output .= ' dark'; + + // Set class + if ( $class ) + $class_output .= ' '.$class; + + // Set Size + if ( $size ) + $class_output .= ' '.$size; + + if ( $window ) + $window = 'target="_blank" '; + + + $output = '' . woo_remove_wpautop($content) . ''; + return $output; +} +add_shortcode( 'button', 'woo_shortcode_button' ); + + +/*-----------------------------------------------------------------------------------*/ +/* 4. Related Posts - related_posts +/*-----------------------------------------------------------------------------------*/ +/* + +Optional arguments: + - limit: number of posts to show (default: 5) + - image: thumbnail size, 0 = off (default: 0) +*/ + +function woo_shortcode_related_posts( $atts ) { + + extract(shortcode_atts(array( + 'limit' => '5', + 'image' => '', + ), $atts)); + + global $wpdb, $post, $table_prefix; + + if ($post->ID) { + + $retval = ' + +'; + return $retval; + } + return; +} +add_shortcode( 'related_posts', 'woo_shortcode_related_posts' ); + + +/*-----------------------------------------------------------------------------------*/ +/* 5. Tweetmeme button - tweetmeme +/*-----------------------------------------------------------------------------------*/ +/* + +Source: http://help.tweetmeme.com/2009/04/06/tweetmeme-button/ + +Optional arguments: + - link: specify URL directly + - style: compact + - source: username + - float: none, left, right (default: left) + +*/ +function woo_shortcode_tweetmeme($atts, $content = null) { + extract(shortcode_atts(array( 'link' => '', + 'style' => '', + 'source' => '', + 'float' => 'left'), $atts)); + $output = ''; + + if ( $link ) + $output .= "tweetmeme_url = '".$link."';"; + + if ( $style ) + $output .= "tweetmeme_style = 'compact';"; + + if ( $source ) + $output .= "tweetmeme_source = '".$source."';"; + + if ( $link OR $style ) + $output = ''; + + $output .= '
    '; + return $output; + +} +add_shortcode( 'tweetmeme', 'woo_shortcode_tweetmeme' ); + +/*-----------------------------------------------------------------------------------*/ +/* 6. Twitter button - twitter +/*-----------------------------------------------------------------------------------*/ +/* + +Source: http://twitter.com/goodies/tweetbutton + +Optional arguments: + - style: vertical, horizontal, none ( default: vertical ) + - url: specify URL directly + - source: username to mention in tweet + - related: related account + - text: optional tweet text (default: title of page) + - float: none, left, right (default: left) + - lang: fr, de, es, js (default: english) +*/ +function woo_shortcode_twitter($atts, $content = null) { + extract(shortcode_atts(array( 'url' => '', + 'style' => 'vertical', + 'source' => '', + 'text' => '', + 'related' => '', + 'lang' => '', + 'float' => 'left'), $atts)); + $output = ''; + + if ( $url ) + $output .= ' data-url="'.$url.'"'; + + if ( $source ) + $output .= ' data-via="'.$source.'"'; + + if ( $text ) + $output .= ' data-text="'.$text.'"'; + + if ( $related ) + $output .= ' data-related="'.$related.'"'; + + if ( $lang ) + $output .= ' data-lang="'.$lang.'"'; + + $output = ''; + return $output; + +} +add_shortcode( 'twitter', 'woo_shortcode_twitter' ); + +/*-----------------------------------------------------------------------------------*/ +/* 7. Digg Button - digg +/*-----------------------------------------------------------------------------------*/ +/* + +Source: http://about.digg.com/button + +Optional arguments: + - link: specify URL directly + - title: specify a title (must add link also) + - style: medium, large, compact, icon (default: medium) + - float: none, left, right (default: left) + +*/ +function woo_shortcode_digg($atts, $content = null) { + extract(shortcode_atts(array( 'link' => '', + 'title' => '', + 'style' => 'medium', + 'float' => 'left'), $atts)); + $output = " + + "; + + // Add custom URL + if ( $link ) { + // Add custom title + if ( $title ) + $title = '&title='.urlencode( $title ); + + $link = ' href="http://digg.com/submit?url='.urlencode( $link ).$title.'"'; + } + + if ( $style == "large" ) + $style = "Large"; + elseif ( $style == "compact" ) + $style = "Compact"; + elseif ( $style == "icon" ) + $style = "Icon"; + else + $style = "Medium"; + + $output .= '
    '; + return $output; + +} +add_shortcode( 'digg', 'woo_shortcode_digg' ); + + +/*-----------------------------------------------------------------------------------*/ +/* 8. Facebook Like Button - fblike +/*-----------------------------------------------------------------------------------*/ +/* + +Source: http://developers.facebook.com/docs/reference/plugins/like + +Optional arguments: + - float: none (default), left, right + - url: link you want to share (default: current post ID) + - style: standard (default), button + - showfaces: true or false (default) + - width: 450 + - verb: like (default) or recommend + - colorscheme: light (default), dark + - font: arial (default), lucida grande, segoe ui, tahoma, trebuchet ms, verdana + +*/ +function woo_shortcode_fblike($atts, $content = null) { + extract(shortcode_atts(array( 'float' => 'none', + 'url' => '', + 'style' => 'standard', + 'showfaces' => 'false', + 'width' => '450', + 'verb' => 'like', + 'colorscheme' => 'light', + 'font' => 'arial'), $atts)); + + global $post; + + if ( ! $post ) { + + $post = new stdClass(); + $post->ID = 0; + + } // End IF Statement + + $allowed_styles = array( 'standard', 'button_count', 'box_count' ); + + if ( ! in_array( $style, $allowed_styles ) ) { $style = 'standard'; } // End IF Statement + + if ( !$url ) + $url = get_permalink($post->ID); + + $height = '60'; + if ( $showfaces == 'true') + $height = '100'; + + if ( ! $width || ! is_numeric( $width ) ) { $width = 450; } // End IF Statement + + switch ( $float ) { + + case 'left': + + $float = 'fl'; + + break; + + case 'right': + + $float = 'fr'; + + break; + + default: + break; + + } // End SWITCH Statement + + $output = ' +
    + +
    + '; + return $output; + +} +add_shortcode( 'fblike', 'woo_shortcode_fblike' ); + + +/*-----------------------------------------------------------------------------------*/ +/* 9. Columns +/*-----------------------------------------------------------------------------------*/ +/* + +Description: + +Columns are named with this convention Xcol_Y where X is the total number of columns and Y is +the number of columns you want this column to span. Add _last behind the shortcode if it is the +last column. + +*/ + +/* ============= Two Columns ============= */ + +function woo_shortcode_twocol_one($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'twocol_one', 'woo_shortcode_twocol_one' ); + +function woo_shortcode_twocol_one_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'twocol_one_last', 'woo_shortcode_twocol_one_last' ); + + +/* ============= Three Columns ============= */ + +function woo_shortcode_threecol_one($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'threecol_one', 'woo_shortcode_threecol_one' ); + +function woo_shortcode_threecol_one_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'threecol_one_last', 'woo_shortcode_threecol_one_last' ); + +function woo_shortcode_threecol_two($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'threecol_two', 'woo_shortcode_threecol_two' ); + +function woo_shortcode_threecol_two_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'threecol_two_last', 'woo_shortcode_threecol_two_last' ); + +/* ============= Four Columns ============= */ + +function woo_shortcode_fourcol_one($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fourcol_one', 'woo_shortcode_fourcol_one' ); + +function woo_shortcode_fourcol_one_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fourcol_one_last', 'woo_shortcode_fourcol_one_last' ); + +function woo_shortcode_fourcol_two($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fourcol_two', 'woo_shortcode_fourcol_two' ); + +function woo_shortcode_fourcol_two_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fourcol_two_last', 'woo_shortcode_fourcol_two_last' ); + +function woo_shortcode_fourcol_three($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fourcol_three', 'woo_shortcode_fourcol_three' ); + +function woo_shortcode_fourcol_three_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fourcol_three_last', 'woo_shortcode_fourcol_three_last' ); + +/* ============= Five Columns ============= */ + +function woo_shortcode_fivecol_one($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_one', 'woo_shortcode_fivecol_one' ); + +function woo_shortcode_fivecol_one_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_one_last', 'woo_shortcode_fivecol_one_last' ); + +function woo_shortcode_fivecol_two($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_two', 'woo_shortcode_fivecol_two' ); + +function woo_shortcode_fivecol_two_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_two_last', 'woo_shortcode_fivecol_two_last' ); + +function woo_shortcode_fivecol_three($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_three', 'woo_shortcode_fivecol_three' ); + +function woo_shortcode_fivecol_three_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_three_last', 'woo_shortcode_fivecol_three_last' ); + +function woo_shortcode_fivecol_four($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_four', 'woo_shortcode_fivecol_four' ); + +function woo_shortcode_fivecol_four_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'fivecol_four_last', 'woo_shortcode_fivecol_four_last' ); + + +/* ============= Six Columns ============= */ + +function woo_shortcode_sixcol_one($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_one', 'woo_shortcode_sixcol_one' ); + +function woo_shortcode_sixcol_one_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_one_last', 'woo_shortcode_sixcol_one_last' ); + +function woo_shortcode_sixcol_two($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_two', 'woo_shortcode_sixcol_two' ); + +function woo_shortcode_sixcol_two_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_two_last', 'woo_shortcode_sixcol_two_last' ); + +function woo_shortcode_sixcol_three($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_three', 'woo_shortcode_sixcol_three' ); + +function woo_shortcode_sixcol_three_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_three_last', 'woo_shortcode_sixcol_three_last' ); + +function woo_shortcode_sixcol_four($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_four', 'woo_shortcode_sixcol_four' ); + +function woo_shortcode_sixcol_four_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_four_last', 'woo_shortcode_sixcol_four_last' ); + +function woo_shortcode_sixcol_five($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_five', 'woo_shortcode_sixcol_five' ); + +function woo_shortcode_sixcol_five_last($atts, $content = null) { + return '
    ' . woo_remove_wpautop($content) . '
    '; +} +add_shortcode( 'sixcol_five_last', 'woo_shortcode_sixcol_five_last' ); + + +/*-----------------------------------------------------------------------------------*/ +/* 10. Horizontal Rule / Divider - hr - divider +/*-----------------------------------------------------------------------------------*/ +/* + +Description: Use to separate text. + +*/ +function woo_shortcode_hr($atts, $content = null) { + return '
    '; +} +add_shortcode( 'hr', 'woo_shortcode_hr' ); + +function woo_shortcode_divider($atts, $content = null) { + return '
    '; +} +add_shortcode( 'divider', 'woo_shortcode_divider' ); + +function woo_shortcode_divider_flat($atts, $content = null) { + return '
    '; +} +add_shortcode( 'divider_flat', 'woo_shortcode_divider_flat' ); + + +/*-----------------------------------------------------------------------------------*/ +/* 11. Quote - quote +/*-----------------------------------------------------------------------------------*/ +/* + +Optional arguments: + - style: boxed + - float: left, right + +*/ +function woo_shortcode_quote($atts, $content = null) { + extract(shortcode_atts(array( 'style' => '', + 'float' => ''), $atts)); + $class = ''; + if ( $style ) + $class .= ' '.$style; + if ( $float ) + $class .= ' '.$float; + + return '

    ' . woo_remove_wpautop($content) . '

    '; +} +add_shortcode( 'quote', 'woo_shortcode_quote' ); + +/*-----------------------------------------------------------------------------------*/ +/* 12. Icon links - ilink +/*-----------------------------------------------------------------------------------*/ +/* + +Optional arguments: + - style: download, note, tick, info, alert + - url: the url for your link + - icon: add an url to a custom icon + +*/ +function woo_shortcode_ilink($atts, $content = null) { + extract(shortcode_atts(array( 'style' => 'info', 'url' => '', 'icon' => ''), $atts)); + + $custom_icon = ''; + if ( $icon ) + $custom_icon = 'style="background:url( '.$icon.') no-repeat left 40%;"'; + + return '' . woo_remove_wpautop($content) . ''; +} +add_shortcode( 'ilink', 'woo_shortcode_ilink' ); + +/*-----------------------------------------------------------------------------------*/ +/* 13. jQuery Toggle +/*-----------------------------------------------------------------------------------*/ +/* + +} + +Optional arguments: + - title: The text in the main trigger + - hide: Hide the toggle box on load + - display_main_trigger: Display the main trigger on the toggle + +*/ +function woo_shortcode_toggle ( $atts, $content = null ) { + + $defaults = array( + 'title_open' => __( 'Hide the Content', 'woothemes' ), + 'title_closed' => __( 'Show the Content', 'woothemes' ), + 'hide' => 'yes', + 'display_main_trigger' => 'yes', + 'style' => 'default', + 'border' => 'yes', + 'excerpt_length' => '0', + 'include_excerpt_html' => 'no', + 'read_more_text' => __( 'Read More', 'woothemes' ), + 'read_less_text' => __( 'Read Less', 'woothemes' ) + ); + + extract( shortcode_atts( $defaults, $atts ) ); + + $title = ''; + $class = ''; + + $class_open = ' toggle-' . sanitize_title( $title_open ); + + $class_closed = ' toggle-' . sanitize_title( $title_closed ); + + if ( $hide == 'yes' ) { + $class .= $class_closed . ' closed'; $title = $title_closed; + } else { + $class .= $class_open . ' open'; $title = $title_open; + } // End IF Statement + + $main_trigger = ''; + + if ( $display_main_trigger == 'yes' ) { + + $main_trigger = '

    ' . $title . '

    ' . "\n"; + + } // End IF Statement + + // Add the alternate style to the CSS class. + $class .= ' ' . $style; + + // Add the border class, if necessary. + if ( $border == 'yes' ) { $class .= ' border'; } // End IF Statement + + // If the excerpt length is greater than 0, apply the excerpt logic. + $excerpt_length = intval( $excerpt_length ); + + if ( $excerpt_length > 0 ) { + $orig_content = $content; + + if ( $include_excerpt_html == 'no' ) { + $content = strip_tags( $content ); + } + + $excerpt = substr( $content, 0, $excerpt_length ); + + $more_link = '' . $read_more_text . ''; + + $content = '' . $excerpt . '' . "\n" . $more_link . "\n" . '' . substr( $content, $excerpt_length, strlen( $content ) ) . '' . "\n"; + } + + return '
    ' . $main_trigger . '
    ' . do_shortcode( $content ) . '
    ' . "\n" . '' . '
    '; + +} // End woo_shortcode_toggle() + +add_shortcode( 'toggle', 'woo_shortcode_toggle', 99 ); + +/*-----------------------------------------------------------------------------------*/ +/* 14. Facebook Share Button - fbshare +/*-----------------------------------------------------------------------------------*/ +/* + +Source: http://developers.facebook.com/docs/share + +Optional arguments: + - type: box_count, button_count, button (default), icon_link, or icon + - float: none, left, right (default: left) + +*/ +function woo_shortcode_fbshare($atts, $content = null) { + extract(shortcode_atts(array( 'url' => '', 'type' => 'button', 'float' => 'left' ), $atts)); + + global $post; + + if ( $url == '' ) { $url = get_permalink($post->ID); } // End IF Statement + + $output = ' + + '; + return $output; + +} +add_shortcode( 'fbshare', 'woo_shortcode_fbshare' ); + + +/*-----------------------------------------------------------------------------------*/ +/* 15. Advanced Contact Form - contact_form +/*-----------------------------------------------------------------------------------*/ +/* + +Optional arguments: + - email: The e-mail address to which the form will send (defaults to woo_contactform_email). + - subject: The subject of the e-mail (defaults to "Message via the contact form". + - button_text: Optionally change the text of the "submit" button. + + - Advanced form fields functionality, for creating dynamic form fields: + --- Text Input: text_fieldname="Text Field Label|Optional Default Text" + --- Select Box: select_fieldname="Select Box Label|key=value,key=value,key=value" + --- Textarea Input: textarea_fieldname="Textarea Field Label|Optional Default Text|Optional Number of Rows|Optional Number of Columns" + --- Checkbox Input: checkbox_fieldname="Checkbox Field Label|Value of the Checkbox|Checked By Default" + --- Radio Button Input: radio_fieldname="Radio Field Label|key=value,key=value,key=value|Optional Default Value" + +*/ + +function woo_shortcode_contactform ( $atts, $content = null ) { + + $defaults = array( + 'email' => get_option( 'woo_contactform_email'), + 'subject' => __( 'Message via the contact form', 'woothemes' ), + 'button_text' => apply_filters( 'woo_contact_form_button_text', __( 'Submit', 'woothemes' ) ) + ); + + extract( shortcode_atts( $defaults, $atts ) ); + + // Extract the dynamic fields as well, if they don't have a value in $defaults. + + $html = ''; + $dynamic_atts = array(); + $formatted_dynamic_atts = array(); + $error_messages = array(); + + if ( is_array( $atts ) ) { + + foreach ( $atts as $k => $v ) { + + ${$k} = $v; + + $dynamic_atts[$k] = ${$k}; + + } // End FOREACH Loop + + } // End IF Statement + + // Parse dynamic fields. + + if ( count( $dynamic_atts ) ) { + + foreach ( $dynamic_atts as $k => $v ) { + + /* Parse the radio buttons. + --------------------------------------------------*/ + + if ( substr( $k, 0, 6 ) == 'radio_' ) { + + // Separate the parameters. + $params = explode( '|', $v ); + + // The title. + if ( array_key_exists( 0, $params ) ) { $label = $params[0]; } else { $label = $k; } // End IF Statement + + // The options. + if ( array_key_exists( 1, $params ) ) { $options_string = $params[1]; } else { $options_string = ''; } // End IF Statement + + // The default value. + if ( array_key_exists( 2, $params ) ) { $default_value = $params[2]; } else { $default_value = ''; } // End IF Statement + + // Format the options. + $options = array(); + + if ( $options_string ) { + + $options_raw = explode( ',', $options_string ); + + if ( count( $options_raw ) ) { + + foreach ( $options_raw as $o ) { + + $o = trim( $o ); + + $is_formatted = strpos( $o, '=' ); + + // It's not formatted how we'd like it, so just add the value is both the value and label. + if ( $is_formatted === false ) { + + $options[$o] = $o; + + // That's more like it. A separate value and label. + } else { + + $option_data = explode( '=', $o ); + + $options[$option_data[0]] = $option_data[1]; + + } // End IF Statement + + } // End FOREACH Loop + + } // End IF Statement + + } // End IF Statement + + // Remove this field from the array, as we're done with it. + unset( $dynamic_atts[$k] ); + + $formatted_dynamic_atts[$k] = array( 'label' => $label, 'options' => $options, 'default_value' => $default_value ); + + } // End IF Statement + + /* Parse the radio buttons. + --------------------------------------------------*/ + + if ( substr( $k, 0, 6 ) == 'radio_' ) { + + // Separate the parameters. + $params = explode( '|', $v ); + + // The title. + if ( array_key_exists( 0, $params ) ) { $label = $params[0]; } else { $label = $k; } // End IF Statement + + // The options. + if ( array_key_exists( 1, $params ) ) { $options_string = $params[1]; } else { $options_string = ''; } // End IF Statement + + // The default value. + if ( array_key_exists( 2, $params ) ) { $default_value = $params[2]; } else { $default_value = ''; } // End IF Statement + + // Format the options. + $options = array(); + + if ( $options_string ) { + + $options_raw = explode( ',', $options_string ); + + if ( count( $options_raw ) ) { + + foreach ( $options_raw as $o ) { + + $o = trim( $o ); + + $is_formatted = strpos( $o, '=' ); + + // It's not formatted how we'd like it, so just add the value is both the value and label. + if ( $is_formatted === false ) { + + $options[$o] = $o; + + // That's more like it. A separate value and label. + } else { + + $option_data = explode( '=', $o ); + + $options[$option_data[0]] = $option_data[1]; + + } // End IF Statement + + } // End FOREACH Loop + + } // End IF Statement + + } // End IF Statement + + // Remove this field from the array, as we're done with it. + unset( $dynamic_atts[$k] ); + + $formatted_dynamic_atts[$k] = array( 'label' => $label, 'options' => $options, 'default_value' => $default_value ); + + } // End IF Statement + + /* Parse the checkbox inputs. + --------------------------------------------------*/ + + if ( substr( $k, 0, 9 ) == 'checkbox_' ) { + + // Separate the parameters. + $params = explode( '|', $v ); + + // The title. + if ( array_key_exists( 0, $params ) ) { $label = $params[0]; } else { $label = $k; } // End IF Statement + + // The value of the checkbox. + if ( array_key_exists( 1, $params ) ) { $value = $params[1]; } else { $value = ''; } // End IF Statement + + // Checked by default? + if ( array_key_exists( 1, $params ) ) { $checked = $params[2]; } else { $checked = ''; } // End IF Statement + + // Remove this field from the array, as we're done with it. + unset( $dynamic_atts[$k] ); + + $formatted_dynamic_atts[$k] = array( 'label' => $label, 'value' => $value, 'checked' => $checked ); + + } // End IF Statement + + /* Parse the text inputs. + --------------------------------------------------*/ + + if ( substr( $k, 0, 5 ) == 'text_' ) { + + // Separate the parameters. + $params = explode( '|', $v ); + + // The title. + if ( array_key_exists( 0, $params ) ) { $label = $params[0]; } else { $label = $k; } // End IF Statement + + // The default text. + if ( array_key_exists( 1, $params ) ) { $default_text = $params[1]; } else { $default_text = ''; } // End IF Statement + + // Remove this field from the array, as we're done with it. + unset( $dynamic_atts[$k] ); + + $formatted_dynamic_atts[$k] = array( 'label' => $label, 'default_text' => $default_text ); + + } // End IF Statement + + /* Parse the select boxes. + --------------------------------------------------*/ + + if ( substr( $k, 0, 7 ) == 'select_' ) { + + // Separate the parameters. + $params = explode( '|', $v ); + + // The title. + if ( array_key_exists( 0, $params ) ) { $label = $params[0]; } else { $label = $k; } // End IF Statement + + // The options. + if ( array_key_exists( 1, $params ) ) { $options_string = $params[1]; } else { $options_string = ''; } // End IF Statement + + // Format the options. + $options = array(); + + if ( $options_string ) { + + $options_raw = explode( ',', $options_string ); + + if ( count( $options_raw ) ) { + + foreach ( $options_raw as $o ) { + + $o = trim( $o ); + + $is_formatted = strpos( $o, '=' ); + + // It's not formatted how we'd like it, so just add the value is both the value and label. + if ( $is_formatted === false ) { + + $options[$o] = $o; + + // That's more like it. A separate value and label. + } else { + + $option_data = explode( '=', $o ); + + $options[$option_data[0]] = $option_data[1]; + + } // End IF Statement + + } // End FOREACH Loop + + } // End IF Statement + + } // End IF Statement + + // Remove this field from the array, as we're done with it. + unset( $dynamic_atts[$k] ); + + $formatted_dynamic_atts[$k] = array( 'label' => $label, 'options' => $options ); + + } // End IF Statement + + /* Parse the textarea inputs. + --------------------------------------------------*/ + + if ( substr( $k, 0, 9 ) == 'textarea_' ) { + + // Separate the parameters. + $params = explode( '|', $v ); + + // The title. + if ( array_key_exists( 0, $params ) ) { $label = $params[0]; } else { $label = $k; } // End IF Statement + + // The default text. + if ( array_key_exists( 1, $params ) ) { $default_text = $params[1]; } else { $default_text = ''; } // End IF Statement + + // The number of rows. + if ( array_key_exists( 2, $params ) ) { $number_of_rows = $params[2]; } else { $number_of_rows = 10; } // End IF Statement + + // The number of columns. + if ( array_key_exists( 3, $params ) ) { $number_of_columns = $params[3]; } else { $number_of_columns = 10; } // End IF Statement + + // Remove this field from the array, as we're done with it. + unset( $dynamic_atts[$k] ); + + $formatted_dynamic_atts[$k] = array( 'label' => $label, 'default_text' => $default_text, 'number_of_rows' => $number_of_rows, 'number_of_columns' => $number_of_columns ); + + } // End IF Statement + + } // End FOREACH Loop + + } // End IF Statement + + /*-------------------------------------------------- + * Form Processing. + * + * Here is where we validate the POST'ed data and + * format it for sending in an e-mail. + * + * We then send the e-mail and notify the user. + --------------------------------------------------*/ + + $emailSent = false; + + if ( ( count( $_POST ) > 3 ) && isset( $_POST['submitted'] ) ) { + + $fields_to_skip = array( 'checking', 'submitted', 'sendCopy' ); + $default_fields = array( 'contactName' => '', 'contactEmail' => '', 'contactMessage' => '' ); + $error_responses = array( + 'contactName' => __( 'Please enter your name', 'woothemes' ), + 'contactEmail' => __( 'Please enter your email address (and please make sure it\'s valid)', 'woothemes' ), + 'contactMessage' => __( 'Please enter your message', 'woothemes' ) + ); + + $posted_data = $_POST; + + // Check for errors. + foreach ( array_keys( $default_fields ) as $d ) { + + if ( !isset ( $_POST[$d] ) || $_POST[$d] == '' || ( $d == 'contactEmail' && ! is_email( $_POST[$d] ) ) ) { + + $error_messages[$d] = $error_responses[$d]; + + } // End IF Statement + + } // End FOREACH Loop + + // If we have errors, don't do anything. Otherwise, run the processing code. + + if ( count( $error_messages ) ) {} else { + + // Setup e-mail variables. + $message_fromname = $default_fields['contactName']; + $message_fromemail = strtolower( $default_fields['contactEmail'] ); + $message_subject = $subject; + $message_body = $default_fields['contactMessage'] . "\n\r\n\r"; + + // Filter out skipped fields and assign default fields. + foreach ( $posted_data as $k => $v ) { + + if ( in_array( $k, $fields_to_skip ) ) { + + unset( $posted_data[$k] ); + + } // End IF Statement + + if ( in_array( $k, array_keys( $default_fields ) ) ) { + + $default_fields[$k] = $v; + + unset( $posted_data[$k] ); + + } // End IF Statement + + } // End FOREACH Loop + + // Okay, so now we're left with only the dynamic fields. Assign to a fresh variable. + $dynamic_fields = $posted_data; + + // Format the default fields into the $message_body. + + foreach ( $default_fields as $k => $v ) { + + if ( $v == '' ) {} else { + + $message_body .= str_replace( 'contact', '', $k ) . ': ' . $v . "\n\r"; + + } // End IF Statement + + } // End FOREACH Loop + + // Format the dynamic fields into the $message_body. + + foreach ( $dynamic_fields as $k => $v ) { + + if ( $v == '' ) {} else { + + $value = ''; + + if ( substr( $k, 0, 7 ) == 'select_' || substr( $k, 0, 6 ) == 'radio_' ) { + + $message_body .= $formatted_dynamic_atts[$k]['label'] . ': ' . $formatted_dynamic_atts[$k]['options'][$v] . "\n\r"; + + } else { + + $message_body .= $formatted_dynamic_atts[$k]['label'] . ': ' . $v . "\n\r"; + + } // End IF Statement + + } // End IF Statement + + } // End FOREACH Loop + + // Send the e-mail. + $headers = __( 'From: ', 'woothemes') . $default_fields['contactName'] . ' <' . $default_fields['contactEmail'] . '>' . "\r\n" . __( 'Reply-To: ', 'woothemes' ) . $default_fields['contactEmail']; + + $emailSent = wp_mail($email, $subject, $message_body, $headers); + + // Send a copy of the e-mail to the sender, if specified. + + if ( isset( $_POST['sendCopy'] ) && $_POST['sendCopy'] == 'true' ) { + + $headers = __( 'From: ', 'woothemes') . $default_fields['contactName'] . ' <' . $default_fields['contactEmail'] . '>' . "\r\n" . __( 'Reply-To: ', 'woothemes' ) . $default_fields['contactEmail']; + + $emailSent = wp_mail($default_fields['contactEmail'], $subject, $message_body, $headers); + + } // End IF Statement + + } // End IF Statement ( count( $error_messages ) ) + + } // End IF Statement + + /* Generate the form HTML. + --------------------------------------------------*/ + + $html .= '
    ' . "\n"; + + /* Display message HTML if necessary. + --------------------------------------------------*/ + + // Success message. + + if( isset( $emailSent ) && $emailSent == true ) { + + $html .= do_shortcode( '[box type="tick"]' . __( 'Your email was successfully sent.', 'woothemes' ) . '[/box]' ); + $html .= '' . "\n"; + + } // End IF Statement + + // Error messages. + + if( count( $error_messages ) ) { + + $html .= do_shortcode( '[box type="alert"]' . __( 'There were one or more errors while submitting the form.', 'woothemes' ) . '[/box]' ); + + } // End IF Statement + + // No e-mail address supplied. + + if( $email == '' ) { + + $html .= do_shortcode( '[box type="alert"]' . __( 'E-mail has not been setup properly. Please add your contact e-mail!', 'woothemes' ) . '[/box]' ); + + } // End IF Statement + + if ( $email == '' ) {} else { + + $html .= '
    ' . "\n"; + + $html .= '
    ' . "\n"; + + /* Parse the "static" form fields. + --------------------------------------------------*/ + + $contactName = ''; + if( isset( $_POST['contactName'] ) ) { $contactName = $_POST['contactName']; } // End IF Statement + + $contactEmail = ''; + if( isset( $_POST['contactEmail'] ) ) { $contactEmail = $_POST['contactEmail']; } // End IF Statement + + $contactMessage = ''; + if( isset( $_POST['contactMessage'] ) ) { $contactMessage = stripslashes( $_POST['contactMessage'] ); } // End IF Statement + + $html .= '

    ' . "\n"; + $html .= '' . "\n"; + + if( array_key_exists( 'contactName', $error_messages ) ) { + + $html .= '' . $error_messages['contactName'] . '' . "\n"; + + } // End IF Statement + + $html .= '

    ' . "\n"; + + $html .= '

    ' . "\n"; + $html .= '' . "\n"; + + if( array_key_exists( 'contactEmail', $error_messages ) ) { + + $html .= '' . $error_messages['contactEmail'] . '' . "\n"; + + } // End IF Statement + + $html .= '

    ' . "\n"; + + $html .= '

    ' . "\n"; + $html .= '' . "\n"; + + if( array_key_exists( 'contactMessage', $error_messages ) ) { + + $html .= '' . $error_messages['contactMessage'] . '' . "\n"; + + } // End IF Statement + + $html .= '

    ' . "\n"; + + /* Parse dynamic fields into HTML. + --------------------------------------------------*/ + + if ( count( $formatted_dynamic_atts ) ) { + + foreach ( $formatted_dynamic_atts as $k => $v ) { + + /* Parse the radio buttons. + --------------------------------------------------*/ + + if ( substr( $k, 0, 6 ) == 'radio_' ) { + + /* Generate Select Box Field HTML. + ----------------------------------------------*/ + + ${$k} = $v['default_value']; + if ( isset( $_POST[$k] ) ) { ${$k} = trim( strip_tags( $_POST[$k] ) ); } // End IF Statement + + $html .= '

    ' . "\n"; + + $html .= '' . "\n"; + + foreach ( $v['options'] as $value => $label ) { + + $html .= ' ' . $label . '
    ' . "\n"; + + } // End FOREACH Loop + + $html .= '
    ' . "\n"; + + } // End IF Statement + + /* Parse the checkbox inputs. + --------------------------------------------------*/ + + if ( substr( $k, 0, 9 ) == 'checkbox_' ) { + + /* Generate Checkbox Input Field HTML. + ----------------------------------------------*/ + + ${$k} = $v['value']; + if ( isset( $_POST[$k] ) ) { ${$k} = trim( strip_tags( $_POST[$k] ) ); } // End IF Statement + + $checked = 0; + if ( array_key_exists( 'checked', $v ) && $v['checked'] == 'yes' ) { $checked = ${$k}; } + + $html .= '

    ' . "\n"; + $html .= '' . "\n"; + $html .= '

    ' . "\n"; + + } // End IF Statement + + /* Parse the text inputs. + --------------------------------------------------*/ + + if ( substr( $k, 0, 5 ) == 'text_' ) { + + /* Generate Text Input Field HTML. + ----------------------------------------------*/ + + ${$k} = $v['default_text']; + if ( isset( $_POST[$k] ) ) { ${$k} = trim( strip_tags( $_POST[$k] ) ); } // End IF Statement + + $html .= '

    ' . "\n"; + $html .= '

    ' . "\n"; + + } // End IF Statement + + /* Parse the select boxes. + --------------------------------------------------*/ + + if ( substr( $k, 0, 7 ) == 'select_' ) { + + /* Generate Select Box Field HTML. + ----------------------------------------------*/ + + ${$k} = ''; + if ( isset( $_POST[$k] ) ) { ${$k} = trim( strip_tags( $_POST[$k] ) ); } // End IF Statement + + $html .= '

    ' . "\n"; + $html .= '

    ' . "\n"; + + } // End IF Statement + + /* Parse the textarea inputs. + --------------------------------------------------*/ + + if ( substr( $k, 0, 9 ) == 'textarea_' ) { + + /* Generate Textarea Input Field HTML. + ----------------------------------------------*/ + + ${$k} = $v['default_text']; + if ( isset( $_POST[$k] ) ) { ${$k} = trim( strip_tags( $_POST[$k] ) ); } // End IF Statement + + $html .= '

    ' . "\n"; + $html .= '

    ' . "\n"; + + } // End IF Statement + + } // End FOREACH Loop + + } // End IF Statement + + /* The end of the form. + ----------------------------------------------*/ + + $sendCopy = ''; + if(isset($_POST['sendCopy']) && $_POST['sendCopy'] == true) { + + $sendCopy = ' checked="checked"'; + + } // End IF Statement + + $html .= '

    ' . "\n"; + + $checking = ''; + if(isset($_POST['checking'])) { + + $checking = $_POST['checking']; + + } // End IF Statement + + $html .= '

    ' . "\n"; + + $html .= '

    '; + + $html .= '
    ' . "\n"; + + $html .= '
    ' . "\n"; + + $html .= '
    ' . "\n"; + + $html .= '
    ' . "\n"; + + } // End IF Statement ( $email == '' ) + + return $html; + +} // End woo_shortcode_contactform() + +add_shortcode( 'contact_form', 'woo_shortcode_contactform' ); + +/*-----------------------------------------------------------------------------------*/ +/* 16. Tabs - [tabs][/tabs] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_tabs ( $atts, $content = null ) { + + $defaults = array( 'style' => 'default', 'title' => '', 'css' => '' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + if ( $css != '' ) { $css = ' ' . $css; } + + // Extract the tab titles for use in the tabber widget. + preg_match_all( '/tab title="([^\"]+)"/i', $content, $matches, PREG_OFFSET_CAPTURE ); + + $tab_titles = array(); + $tabs_class = 'tab_titles'; + + if ( isset( $matches[1] ) ) { $tab_titles = $matches[1]; } // End IF Statement + + $titles_html = ''; + + if ( count( $tab_titles ) ) { + + if ( $title ) { $titles_html .= '

    ' . esc_html( $title ) . '

    '; $tabs_class .= ' has_title'; } // End IF Statement + + $titles_html .= '
      ' . "\n"; + + $counter = 1; + + foreach ( $tab_titles as $t ) { + + $titles_html .= '' . "\n"; + + $counter++; + + } // End FOREACH Loop + + $titles_html .= '
    ' . "\n"; + + } // End IF Statement + + return '
    ' . $titles_html . do_shortcode( $content ) . "\n" . '
    ' . "\n" . '
    '; + +} // End woo_shortcode_tabs() + +add_shortcode( 'tabs', 'woo_shortcode_tabs', 90 ); + +/*-----------------------------------------------------------------------------------*/ +/* 16.1 A Single Tab - [tab title="The title goes here"][/tab] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_tab_single ( $atts, $content = null ) { + + $defaults = array( 'title' => 'Tab' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + $class = ''; + + if ( $title != 'Tab' ) { + + $class = ' tab-' . sanitize_title( $title ); + + } // End IF Statement + + return '
    ' . do_shortcode( $content ) . '
    '; + +} // End woo_shortcode_tab_single() + +add_shortcode( 'tab', 'woo_shortcode_tab_single', 99 ); + +/*-----------------------------------------------------------------------------------*/ +/* 17. Dropcap - [dropcap][/dropcap] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_dropcap ( $atts, $content = null ) { + + $defaults = array(); + + extract( shortcode_atts( $defaults, $atts ) ); + + return '' . $content . ''; + +} // End woo_shortcode_dropcap() + +add_shortcode( 'dropcap', 'woo_shortcode_dropcap' ); + +/*-----------------------------------------------------------------------------------*/ +/* 18. Highlight - [highlight][/highlight] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_highlight ( $atts, $content = null ) { + + $defaults = array(); + + extract( shortcode_atts( $defaults, $atts ) ); + + return '' . $content . ''; + +} // End woo_shortcode_highlight() + +add_shortcode( 'highlight', 'woo_shortcode_highlight' ); + +/*-----------------------------------------------------------------------------------*/ +/* 19. Abbreviation - [abbr][/abbr] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_abbreviation ( $atts, $content = null ) { + + $defaults = array( 'title' => '' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + return '' . $content . ''; + +} // End woo_shortcode_abbreviation() + +add_shortcode( 'abbr', 'woo_shortcode_abbreviation' ); + +/*-----------------------------------------------------------------------------------*/ +/* 20. Typography - [typography font="" size="" color=""][/typography] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_typography ( $atts, $content = null ) { + + global $google_fonts; + + // Get just the names of the Google fonts. + $google_font_names = array(); + + if ( count( $google_fonts ) ) { + + foreach ( $google_fonts as $g ) { + + $google_font_names[] = $g['name']; + + } // End FOREACH Loop + + } // End IF Statement + + // Build array of usable typefaces. + $fonts_whitelist = array( + 'Arial, Helvetica, sans-serif', + 'Verdana, Geneva, sans-serif', + '|Trebuchet MS|, Tahoma, sans-serif', + 'Georgia, |Times New Roman|, serif', + 'Tahoma, Geneva, Verdana, sans-serif', + 'Palatino, |Palatino Linotype|, serif', + '|Helvetica Neue|, Helvetica, sans-serif', + 'Calibri, Candara, Segoe, Optima, sans-serif', + '|Myriad Pro|, Myriad, sans-serif', + '|Lucida Grande|, |Lucida Sans Unicode|, |Lucida Sans|, sans-serif', + '|Arial Black|, sans-serif', + '|Gill Sans|, |Gill Sans MT|, Calibri, sans-serif', + 'Geneva, Tahoma, Verdana, sans-serif', + 'Impact, Charcoal, sans-serif' + ); + + $fonts_whitelist = array(); // Temporarily remove the default fonts. + + $defaults = array( 'font' => 'Arial, Helvetica, sans-serif', 'size' => '12', 'color' => '#000000', 'size_format' => 'px' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + // Run checks to make sure it's an allowed font stack. + if ( in_array( $font, $fonts_whitelist ) || in_array( $font, $google_font_names ) ) { + + if ( in_array( $font, $google_font_names ) ) { + + $font = "'" . $font . "'"; + + } // End IF Statement + + } else { + + $font = 'Arial, Helvetica, sans-serif'; + + } // End IF Statement + + // $font = str_replace( '|', '"', $font ); + + return '' . do_shortcode( $content ) . ''; + +} // End woo_shortcode_typography() + +add_shortcode( 'typography', 'woo_shortcode_typography' ); + +add_action( 'wp_head', 'woo_shortcode_typography_loadgooglefonts', 0 ); + +function woo_shortcode_typography_loadgooglefonts ( $font = '' ) { + + // If a specific font is requested, just enqueue that font. + $variations = array( + 'Raleway' => ':100', + 'Coda' => ':800', + 'UnifrakturCook' => ':bold', + 'Allan' => ':bold', + 'Sniglet' => ':800', + 'Cabin' => ':bold', + 'Corben' => ':bold', + 'Buda' => ':light' + ); + + if ( $font ) { + + $f = $font; + + $f = str_replace( ' ', '+', $f ); + + $f_include = $f; + + if ( in_array( $f, array_keys( $variations ) ) ) { + + $f_include = $f . $variations[$f]; + + } // End IF Statement + + echo "" . "\n"; + + } else { + + global $google_fonts, $post; + + // Add variations for specific fonts that need variation on inclusion. + + // Get just the names of the Google fonts. + $google_font_names = array(); + + if ( count( $google_fonts ) ) { + + foreach ( $google_fonts as $g ) { + + $google_font_names[] = $g['name']; + + } // End FOREACH Loop + + } // End IF Statement + + $_pattern = '/\[typography font="(.*?)" size="(.*?)" size_format="(.*?)"(.*?)\](.*?)\[\/typography\]/i'; // 1. font, 2, size, 3, color. + $_string = ''; + if ( $post ) { $_string = $post->post_content; } // End IF Statement + + preg_match_all($_pattern, $_string, $_matches ); + + $used_google_fonts = array(); + + foreach ( $_matches[1] as $f ) { + + if ( in_array( $f, $google_font_names ) && ! in_array( $f, $used_google_fonts ) ) { + + $used_google_fonts[] = $f; + + } // End IF Statement + + } // End FOREACH Loop + + if ( count( $used_google_fonts ) ) { + + foreach ( $used_google_fonts as $f ) { + + $f = str_replace( ' ', '+', $f ); + + $f_include = $f; + + if ( in_array( $f, array_keys( $variations ) ) ) { + + $f_include = $f . $variations[$f]; + + } // End IF Statement + + wp_enqueue_style( 'woo-googlefont-' . sanitize_title( $f ), 'http://fonts.googleapis.com/css?family=' . $f_include . '', array(), '3.6', 'screen' ); + + } // End FOREACH Loop + + } // End IF Statement + + } // End IF Statement + +} // End woo_shortcode_typography_loadgooglefonts() + +/*-----------------------------------------------------------------------------------*/ +/* 21. List Styles - Unordered List - [unordered_list style=""][/unordered_list] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_unorderedlist ( $atts, $content = null ) { + + $defaults = array( 'style' => 'default' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + return '
    ' . do_shortcode( $content ) . '
    ' . "\n"; + +} // End woo_shortcode_unorderedlist() + +add_shortcode( 'unordered_list', 'woo_shortcode_unorderedlist' ); + +/*-----------------------------------------------------------------------------------*/ +/* 22. List Styles - Ordered List - [ordered_list style=""][/ordered_list] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_orderedlist ( $atts, $content = null ) { + + $defaults = array( 'style' => 'default' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + return '
    ' . do_shortcode( $content ) . '
    ' . "\n"; + +} // End woo_shortcode_orderedlist() + +add_shortcode( 'ordered_list', 'woo_shortcode_orderedlist' ); + +/*-----------------------------------------------------------------------------------*/ +/* 23. Social Icon - [social_icon url="" float="" icon_url="" title="" profile_type="" window=""] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_socialicon ( $atts, $content = null ) { + + $defaults = array( 'url' => '', 'float' => 'none', 'icon_url' => '', 'title' => '', 'profile_type' => '', 'window' => 'no', 'rel' => '' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + if ( ! $url ) { return; } // End IF Statement - Don't run the shortcode if no URL has been supplied. + + // Attempt to determine the location of the social profile. + // If no location is found, a default icon will be used. + + $_default_icon = ''; + + $_supported_profiles = array( + 'facebook' => 'facebook.com', + 'twitter' => 'twitter.com', + 'youtube' => 'youtube.com', + 'delicious' => 'delicious.com', + 'flickr' => 'flickr.com', + 'linkedin' => 'linkedin.com' + ); + + $_profile_to_display = ''; + $_alt_text = ''; + $_classes = 'social-icon'; + + $_profile_match = false; + + // If they've specified an icon, skip the automation. + + if ( $profile_type != '' ) { + + $_profile_match = true; + $_profile_to_display = $profile_type; + if ( $title ) { $_alt_text = $title; } else { $_alt_text = ucwords( $_profile_to_display ); $_alt_text = sprintf( __( 'My %s Profile', 'woothemes' ), $_alt_text ); } // End IF Statement + $_profile_class = ' social-icon-' . $_profile_to_display; + + if ( $icon_url ) { + + $_img_url = $icon_url; + + } else { + + $_img_url = trailingslashit( get_template_directory_uri() ) . 'functions/images/ico-social-' . $_profile_to_display . '.png'; + + } // End IF Statement + + } // End IF Statement + + // Create a special scenario for use with the RSS feed for this website. + + if ( $url == 'feed' ) { + + $_profile_match = true; + $_profile_to_display = 'rss'; + if ( $title ) { $_alt_text = $title; } else { $_alt_text = __( 'Subscribe to our RSS feed', 'woothemes' ); } // End IF Statement + $_classes .= ' social-icon-subscribe'; + $url = get_bloginfo( 'rss2_url' ); + + if ( $icon_url ) { + + $_img_url = $icon_url; + + } else { + + $_img_url = trailingslashit( get_template_directory_uri() ) . 'functions/images/ico-social-' . $_profile_to_display . '.png'; + + } // End IF Statement + + } else { + + foreach ( $_supported_profiles as $k => $v ) { + + if ( $_profile_match == true ) { break; } // End IF Statement - Break out of the loop if we already have a match. + + // Get host name from URL + + preg_match( '@^(?:http://)?([^/]+)@i', $url, $matches ); + $host = $matches[1]; + + if ( $host == $v ) { + + $_profile_match = true; + $_profile_to_display = $k; + if ( $title ) { $_alt_text = $title; } else { $_alt_text = ucwords( $_profile_to_display ); $_alt_text = sprintf( __( 'My %s Profile', 'woothemes' ), $_alt_text ); } // End IF Statement + $_profile_class = ' social-icon-' . $_profile_to_display; + + if ( $icon_url ) { + + $_img_url = $icon_url; + + } else { + + $_img_url = trailingslashit( get_template_directory_uri() ) . 'functions/images/ico-social-' . $_profile_to_display . '.png'; + + } // End IF Statement + + } else { + + $_profile_to_display = 'default'; + if ( $title ) { $_alt_text = $title; } else { $_alt_text = ucwords( $matches[1] ); $_alt_text = sprintf( __( 'My %s Profile', 'woothemes' ), $_alt_text ); } // End IF Statement + + $_host_bits = explode( '.', $matches[1] ); + $_profile_class = ' social-icon-' . $_host_bits[0]; + + if ( $icon_url ) { + + $_img_url = $icon_url; + + } else { + + $_img_url = trailingslashit( get_template_directory_uri() ) . 'functions/images/ico-social-' . $_profile_to_display . '.png'; + + // Check if an image has been added for this social icon. + + if ( file_exists( trailingslashit( get_stylesheet_directory() ) . 'images/ico-social-' . $_host_bits[0] . '.png' ) ) { + + $_img_url = trailingslashit( get_stylesheet_directory_uri() ) . 'images/ico-social-' . $_host_bits[0] . '.png'; + + } // End IF Statement + + } // End IF Statement + + } // End IF Statement + + } // End FOREACH Loop + + $_classes .= $_profile_class; + + // Determine the floating CSS class to be used. + + switch ( $float ) { + + case 'left': + + $_classes .= ' fl'; + + break; + + case 'right': + + $_classes .= ' fr'; + + break; + + default: + + break; + + } // End SWITCH Statement + + } // End IF Statement + + $target = ''; + if ( $window == 'yes' ) { $target = ' target="_blank"'; } // End IF Statement + + if ( $rel != '' ) { $rel = ' rel="' . $rel . '"'; } + + return '' . $_alt_text . '' . "\n"; + +} // End woo_shortcode_socialicon() + +add_shortcode( 'social_icon', 'woo_shortcode_socialicon' ); + +/*-----------------------------------------------------------------------------------*/ +/* 24. LinkedIn Button - [linkedin_share url="" style=""] +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_linkedin_share ( $atts, $content = null ) { + + $defaults = array( 'url' => '', 'style' => 'none', 'float' => 'none' ); + + extract( shortcode_atts( $defaults, $atts ) ); + + $allowed_floats = array( 'left' => 'fl', 'right' => 'fr', 'none' => '' ); + $allowed_styles = array( 'top' => ' data-counter="top"', 'right' => ' data-counter="right"', 'none' => '' ); + + if ( ! in_array( $float, array_keys( $allowed_floats ) ) ) { $float = 'none'; } + if ( ! in_array( $style, array_keys( $allowed_styles ) ) ) { $style = 'none'; } + + if ( $url ) { $url = ' data-url="' . esc_url( $url ) . '"'; } + + $output = ''; + + if ( $float == 'none' ) {} else { $output .= '
    ' . "\n"; } + + $output .= '' . "\n"; + + if ( $float == 'none' ) {} else { $output .= '
    ' . "\n"; } + + // Enqueue the LinkedIn button JavaScript from their API. + add_action( 'wp_footer', 'woo_shortcode_linkedin_js' ); + add_action( 'woo_shortcode_generator_preview_footer', 'woo_shortcode_linkedin_js' ); + + return $output . "\n"; + +} // End woo_shortcode_linkedin_share() + +add_shortcode( 'linkedin_share', 'woo_shortcode_linkedin_share' ); + +/*-----------------------------------------------------------------------------------*/ +/* 24.1 Load Javascript for LinkedIn Button +/*-----------------------------------------------------------------------------------*/ + +function woo_shortcode_linkedin_js () { + echo '' . "\n"; +} // End woo_shortcode_linkedin_js() + +/*-----------------------------------------------------------------------------------*/ +/* THE END */ +/*-----------------------------------------------------------------------------------*/ +?> \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-style.css b/src/wp-content/themes/bloggingstream/functions/admin-style.css new file mode 100644 index 00000000..1edab422 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-style.css @@ -0,0 +1,692 @@ +/*-------------------------------------------------------------------------------------------*/ +/* WooThemes admin styles */ +/*-------------------------------------------------------------------------------------------*/ + +.updated, .error {display:none!important} /* disable the admin notices */ + +#woo_container { margin: 15px; width: 827px; position:relative; z-index: 0 } + +#woo_container #header { height: 80px; background: url(images/headertile.jpg) repeat-x left top; border: 1px solid #a4bbcd; border-top-left-radius: 15px; -moz-border-radius-topleft: 15px; -webkit-border-top-left-radius: 15px; -webkit-border-top-right-radius: 15px; border-top-right-radius: 15px; -moz-border-radius-topright: 15px; +/*INSET SHADOW*/ +-webkit-box-shadow: inset 1px 1px 0 rgba(255,255,255,.2), inset -1px -1px 0 rgba(255,255,255,.2); +-moz-box-shadow: inset 1px 1px 0 rgba(255,255,255,.2), inset -1px -1px 0 rgba(255,255,255,.2); +box-shadow: inset 1px 1px 0 rgba(255,255,255,.2), inset -1px -1px 0 rgba(255,255,255,.2); +} + +#woo_container #header .logo { float: left; margin: 24px 0 0 25px; height: 35px; } +#woo_container #header .theme-info { float: right; margin: 26px 25px 0 0; } +#woo_container #header .theme-info span { display: block; line-height: 15px; text-transform: uppercase; text-align: right; color: #4e4e4e; text-shadow: 1px 1px 0 #fff; } +#woo_container #header .theme-info .theme { font-size: 15px; font-weight: bold; } +#woo_container #header .theme-info .framework { font-size: 12px; } +#woo_container #header .theme-info b { font-size: 11px; text-transform: none; color: #444; font-weight: 100; } + +#woo_container #support-links { height: 32px; padding: 0 0 0 15px; background-color: #d7e6f2; border-top: 1px solid #f1f6fa; border-bottom: 1px solid #a4bbcd; border-left: 1px solid #d8d8d8; border-right: 1px solid #d8d8d8; } +#woo_container #support-links ul li { display: inline; margin: 0 6px 0 0; } +#woo_container #support-links ul li a:link, #support-links ul li a:visited { line-height: 32px; font-size: 10px; font-weight: bold; text-transform: uppercase; text-decoration: none; color: #21759b; text-shadow: 1px 1px 0 #fff; } +#woo_container #support-links ul li a:hover { color: #155876; } +#woo_container #support-links ul li.changelog { padding: 2px 0 2px 20px; background: url(images/ico-changelog.png) no-repeat left center; } +#woo_container #support-links ul li.docs { padding: 1px 0 1px 20px; background: url(images/ico-docs.png) no-repeat left top; } +#woo_container #support-links ul li.forum { padding: 1px 0 1px 20px; background: url(images/ico-forum.png) no-repeat left top; } +#woo_container #support-links ul li.right { float:right; margin-right:15px} + +#woo_container #main { background-color: #f1f1f1; border-left: 1px solid #d8d8d8; border-right: 1px solid #d8d8d8; border-bottom: 1px solid #d8d8d8; } + +#woo_container #woo-nav { float: left; position: relative; z-index: 9999; width: 190px; } +#woo_container #woo-nav li { margin-bottom:0} +#woo_container #woo-nav ul li a:link, #woo-nav ul li a:visited { display: block; padding: 10px 10px 10px 15px; font:bold 12px/18px sans-serif; text-decoration: none; color: #797979; border-bottom: 1px solid #d8d8d8; border-top:1px solid #fff; text-shadow: 0 1px 0 #fff; } +#woo_container #woo-nav ul li.current a, #woo-nav ul li a:hover { color: #21759b; background-color: #fff; } + +#woo_container #content { float: left; min-height: 650px; width: 595px; margin-left: -1px; padding: 0 20px; font-family: "Lucida Grande", Verdana, sans-serif; background-color: #fff; border-left: 1px solid #d8d8d8; } + +#woo_container #content .section { margin-bottom: 10px;} +#woo_container #content .section h3.heading { font-size:1.1em; margin: 10px 0 10px 0; padding: 7px 0px; /* background: #f1f1f1 url(images/headingtop.jpg) repeat-x left top; */ border-bottom: 1px solid #e7e7e7; } +#woo_container #content .section .controls { float: left; width: 345px; margin: 0 15px 0 0; } +#woo_container #content .section .explain { float: left; width: 225px; padding: 0 10px 0 0; font-size: 11px; color: #999999; font-family: sans-serif; } + +#woo_container #content .section-checkbox .controls { width:25px} +#woo_container #content .section-checkbox .explain { width:540px} + +#woo_container #content .section-color .controls { width:125px} +#woo_container #content .section-color .explain { width:440px} + +#woo_container #content .section-info h3.heading { + font-size: 12px; font-weight: 100; border: 0; margin-top: 20px; letter-spacing: 1px; border-top: 1px solid #FFF298; margin-bottom: 0; background:#EFE186; padding: 10px 20px; } +#woo_container #content .section-info .controls { margin: 0 0 20px; padding: 15px 20px; width: auto; line-height: 1.5em; font-size: 14px; font-style: italic; font-family: Georgia,arial; background: #FFF298; border:1px solid #ECD852; color:#424242;} +#woo_container #content .section-info .controls small { font-size: 12px} + +#woo_container #content .section-info h3.heading { + -moz-border-radius-topleft:4px; + -moz-border-radius-topright:4px; +} +#woo_container #content .section-info .controls{ + -moz-border-radius-bottomleft:4px; + -moz-border-radius-bottomright:4px; +} + +#woo_container textarea, #woo_container input, #woo_container select { + -moz-border-radius:4px; + -webkit-border-radius:4px; + -border-radius:4px; + border-style:solid; + border-width:1px; +} + +#woo_container .controls input,#woo_container .controls select,#woo_container .controls textarea { + margin-bottom: 9px !important; + background-color: #fafafa; + border: 1px solid; + border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC; + width: 340px; + padding: 5px; + font-family: "Lucida Grande", Verdana, sans-serif; + font-size: 12px; + color:#555; +} +#woo_container .controls input:hover,#woo_container .controls select:hover,#woo_container .controls textarea:hover { color:#333; background: #fff;} + +#woo_container .controls input.upload { width:280px; padding-bottom:6px; } +#woo_container .controls input.upload_button{ float:right; width:45px; border-color:#BBBBBB; cursor:pointer; height:16px; } +#woo_container .controls input.upload_button:hover { border-color:#666666; color:#000; } + +#woo_container .screenshot { + float:left; + margin-left:1px; + position:relative; + width:344px; + margin-top:3px; + z-index: 1; +} + +#woo_container .screenshot img { + -moz-border-radius:4px; + -webkit-border-radius:4px; + -border-radius:4px; + background:#FAFAFA; + border-color:#CCCCCC #EEEEEE #EEEEEE #CCCCCC; + border-style:solid; + border-width:1px; + float:left; + max-width:334px; + padding:4px; +} + +#woo_container .screenshot .mlu_remove { + + background:url( "images/ico-delete.png") no-repeat; + border:medium none; + bottom:-4px; + display:block; + float:left; + height:16px; + padding:0; + position:absolute; + left:-4px; + text-indent:-9999px; + width:16px; +} + +#woo_container .screenshot .no_image .file_link { + margin-left: 20px; +} + +#woo_container .screenshot .no_image .mlu_remove { + bottom: 0px; +} + + +/* SELECT DROPDOWN */ +#woo_container #content select.woo-input { + cursor:pointer; + height:28px; + margin:0; + opacity:0; + padding:0; + position:relative; + width:inherit; + z-index:4; +} + +#woo_container #content .select_wrapper { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + font-family: "Lucida Grande","Lucida Sans Unicode",Arial,Verdana,sans-serif; + font-size: 12px; + background: #fafafa url(images/select.png) no-repeat right center; + border-color: #ccc #eee #eee #ccc; + border-style: solid; + border-width: 1px; + float: left; + height: 26px; + width: 344px; + margin: 0; + margin-bottom: 9px !important; + width: 344px; + display: block; + color: #555; +} +#woo_container #content .option-type .select_wrapper { + background-color: #fff; +} +#woo_container #content .select_wrapper:hover { + background-color: #fff; + border-color: #bbb #eee #eee #bbb; + color: #333; +} +#woo_container #content .select_wrapper span { + height: 26px; + line-height: 26px; + position: absolute; + z-index: 2; + padding-left: 6px; +} + + +#woo_container .colorSelector { margin-top:1px; } +#woo_container .colorSelector:hover { cursor:pointer; } +#woo_container .controls select { padding: 4px; width: 340px } +#woo_container .controls select:hover { cursor: pointer;} +#woo_container .controls textarea {width: 345px; } + +#woo_container input[type=text], #woo_container select { height:28px; } +#woo_container input[type=text] { width: 340px; } + +#woo_container input.woo-input-calendar { width: 320px; } + +#woo_container input.checkbox { width: 30px; } +#woo_container input.woo-radio { width: 30px; } + +#woo_container .controls .input-text-small { width: 60px; margin-right:10px} +#woo_container .meta-two { margin-right:10px} + +#woo_container .controls .woo-color {float:left; width: 80px; margin-left:5px; /* font-size:20px; height:34px;*/} + +#woo_container #content .section-typography .controls { width:425px } +#woo_container #content .section-typography .explain { width:140px } + +#woo_container .controls .woo-typography-size { width:50px; float:left} +#woo_container .controls .woo-typography-unit { width:50px; float:left} +#woo_container .controls .woo-typography-face { width:120px; float:left} +#woo_container .controls .woo-typography-style { width:80px; float:left} + +#woo_container .controls .woo-radio-img-img { border:3px solid #dedede; margin:0 5px 10px 0; display:none; cursor:pointer; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } +#woo_container .controls .woo-radio-img-selected { border:3px solid #aaa; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px;} + +#woo_container .controls .woo-border-width { width:80px; float:left} +#woo_container .controls .woo-border-style { width:120px; float:left} + + +#woo_container .group { padding-bottom:20px} +#woo_container .group h2 { display:none; border-bottom:3px solid #e7e7e7} + +#woo_container input:focus,#woo_container select:focus, #woo_container textarea:focus { background:#fff;} + +#woo_container .happy { + background: #DBF6BE no-repeat 10px center; + border: solid #9BBF65; + border-width: 0px 1px 1px 1px; + color: #060; + font-weight: bold; + padding: 10px; + text-align: center; +} + +#woo_container .warning { + background: #ffeeee no-repeat 10px center;; + border: solid #dfbfbf; + border-width: 0px 1px 1px 1px; + color: #333; + font-weight: bold; + padding: 10px; + text-align: center; +} +#woo_container .update_available { + + background: #FFFEEB no-repeat 10px center;; + border: solid #CCCCCC; + border-width: 0px 1px 1px 1px; + color: #333; + font-weight: bold; + padding: 10px; + text-align: center; + + + +} + +/* +#woo_container .woo-uploaded-image { border:2px solid #dedede; -moz-border-radius: 3px; display:block;} +#woo_container .woo-uploaded-image img {margin:5px;display:block} +*/ + +#woo_container .woo-save-popup { position:absolute; -moz-border-radius:12px; background:rgba(0,0,0,0.4); color:#fff; font-size:24px; text-align:center; display:none; z-index: 10; } + +#woo_container .woo-save-save { background:url(images/happy.png) 20px 50% no-repeat; padding:30px 30px 30px 70px} +#woo_container .woo-save-reset { background:url(images/warning.png) 20px 50% no-repeat; padding:30px 30px 30px 70px} + +.upload_button_div { margin-bottom: 10px;} +.upload_button_div .button { padding:4px 14px; +} +.upload_button_div .image_reset_button { margin-left:10px} + +.upload-error { float:left;color:#666; font-size:10px; font-weight:bold; text-decoration:none; text-shadow:1px 1px 0 #FFFFFF; + margin: 0 10px 0 0; padding:3px 10px; background:#FFDFEC; -moz-border-radius:4px} + +.reset-button { color:#c77!important;text-shadow:0 1px 0 #fff !important;} +.reset-button:hover { border-color:#c77!important;} +.save_bar_top { background: #f3f3f3; border:solid #ccc; border-width:0px 1px 1px 1px; padding: 10px 20px 0px 20px; height: 35px; text-align: right; +/*INSET SHADOW*/ +-webkit-box-shadow: inset 1px 1px 0 rgba(255,255,255,.2), inset -1px -1px 0 rgba(255,255,255,.2); +-moz-box-shadow: inset 1px 1px 0 rgba(255,255,255,.2), inset -1px -1px 0 rgba(255,255,255,.2); +box-shadow: inset 1px 1px 0 rgba(255,255,255,.2), inset -1px -1px 0 rgba(255,255,255,.2); +} +#wooform-reset { float:left; } + +.hide {display:none} + +.ajax-loading-img-top { margin: 8px 4px 0; float:left} +.ajax-loading-img-bottom {} + +.woo-option-image { max-width:340px; } + +#woo_container .mini .controls select, #woo_container #content .section .mini .controls {width: 70px; } +#woo_container .mini .controls input, #woo_container #content .mini .controls {width: 70px; } + +#woo_container #content .mini .explain { width:500px; } + +.woo-notice { background: #ffd1d1 ; border:1px solid #DFA8A7; -moz-border-radius:8px; text-align: center; margin-bottom: 15px } + +/*-------------------------------------------------------------------------------------------*/ +/* FEEDS PAGE */ +/*-------------------------------------------------------------------------------------------*/ + + .themes-page div.info { height:30px;} + .themes-page div.info a { float:left; margin: 0 10px 0 0; padding:3px 10px; background:#D7E6F2; -moz-border-radius:4px} + .themes-page div.info a:link, + .themes-page div.info a:visited { color:#21759B; font-size:10px; font-weight:bold; text-decoration:none; text-shadow:1px 1px 0 #FFFFFF;} + .themes-page div.info a:active, + .themes-page div.info a:hover{color:#155876;} + + ul.themes li.theme {border-bottom: 1px #ddd solid; padding: 20px 0; height:230px} + ul.themes li.theme span{ display:block; float: left} + ul.themes li.theme span img{ } + ul.themes li.theme div {margin-left: 310px; } + ul.themes li.theme div h2 { font-size: 20px; background: #eee; padding: 0px 10px; margin-bottom: 10px; border-bottom:1px #ddd solid; border-top:1px #e1e1e1 solid} + ul.themes li.theme div h2 a:link, + ul.themes li.theme div h2 a:visited { color: #555; text-decoration: none; font-style: normal;} + + ul.themes li.theme div p { width: 450px; padding-left: 5px;} + ul.themes li.theme div p{ font-size: 12px!important; margin: 10px 10px 10px 10px; } + ul.themes li.theme div ul {padding-left: 0px; color: #ccc; float:left; border-top:#eee 1px solid; padding-top: 10px;margin-left:20px } + ul.themes li.theme div ul li { list-style: disc; list-style-position:inside; } + ul.themes li.theme div ul li a:link, + ul.themes li.theme div ul li a:visited { font-size: 12px!important; text-decoration: none;} + ul.themes li.theme div ul li a:hover, + ul.themes li.theme div ul li a:active { text-decoration: underline ;} + +/*-------------------------------------------------------------------------------------------*/ +/* SIDEBAR MANAGER */ +/*-------------------------------------------------------------------------------------------*/ + +#woo_container #content.sbm-content { width: 785px; padding-top:20px } + +#woo_container #content.sbm-content .info-box { position: relative; margin: 0px 0 20px 0; padding: 0 12px; background: #fff298; border: 1px solid #ecd852; } +#woo_container #content.sbm-content .info-box h2 { font: bold 14px Helvetica, Arial, sans-serif; text-transform: uppercase; } +#woo_container #content.sbm-content .info-box p { margin: 5px 0 10px; font-family: Helvetica, Arial, sans-serif; } +#woo_container #content.sbm-content .info-box .btn-close { position: absolute; top: 7px; left: 730px; } + +#sbm-sidebar { float: left; width: 230px; margin: 0 20px 0 0; } +#sbm-main { float: left; width: 505px; } + +#woo_container #woo-sbm-menu { min-width: 230px; } +#woo_container #woo-sbm-menu h3 { padding: 7px 9px; font-size: 12px; cursor: default; } +#woo_container #woo-sbm-menu ul { margin: 0 0 0 10px; } +#woo_container #woo-sbm-menu ul ul{ margin: 5px 0 0 5px; } +#woo_container #woo-sbm-menu ul li { cursor: pointer} +#woo_container #woo-sbm-menu ul li a { display: block; font-size: 12px; font-weight: bold; text-transform: uppercase; color: #333; text-decoration: none; } +#woo_container #woo-sbm-menu ul li a:hover, #woo_container #woo-sbm-menu ul li li:hover { color: #757575; } +#woo_container #woo-sbm-menu ul ul li { margin-bottom: 4px; } +#woo_container #woo-sbm-menu ul ul li span { display: none} +ul#woo-sbm-menu_ul li a span { color: #999; } + +#woo_container h3 { margin: 0 0 10px 0} +#woo_container h3 span { font-size: 10px; color: #ccc} +#woo_container .woo-sbm-tip { display:block; padding: 15px 15px 15px 15px; margin-bottom: 10px; background: #EDFCD5; text-shadow: 0 1px 0 #FFFFFF; border: 1px solid #D4EBAF; font: italic 13px/1.5em Georgia, serif; +} + +#woo_container #woo-sbm-get-links { display: none; } + +#woo-sbm-toggle-info { float: right; margin: 3px 5px 0 0; text-decoration: none; text-transform: uppercase; font-size: 11px; } +#woo-sbm-toggle-info img { vertical-align: top; padding: 0 0 0 5px; } + +#woo_container .woo-sbm-builder { position: relative} +#woo_container .woo-sbm-builder .nav-tabs-nav { margin: 0 0 0 10px; } +#woo_container .woo-sbm-builder .nav-tab { background: #F4F4F4; font-size: 11px; border-bottom: 1px solid #ccc; } +#woo_container .woo-sbm-builder .nav-tab-active { font-weight: bold; background: #ececec; border-bottom: 1px solid #ececec; } +#woo_container .woo-sbm-builder .builder-header {padding: 10px; border: 1px solid #ccc; border-width: 1px 1px 0; background: url( "images/gray-grad.png") repeat-x scroll left top #DFDFDF; border-top-right-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; } +#woo_container .woo-sbm-builder label { display: block; margin-bottom: 0px; padding: 5px 0; font-size: 12px} +#woo_container .woo-sbm-builder label span { float:left; width: 130px; font-weight: 700; text-align: right; margin-right: 10px} +#woo_container .woo-sbm-builder #woo-sbm-label-sb-name span { padding-top: 5px; } +#woo_container .woo-sbm-builder #woo-sbm-builder-body label span { font-size: 13px; color: #333; padding-top: 3px; } +#woo_container .woo-sbm-builder #woo-sbm-builder-body select { width: 330px; } +#woo_container .woo-sbm-builder #sidebar-description { width: 330px!important; height: 80px; } +#woo_container .woo-sbm-builder #sidebar-title { width: 330px; padding: 5px 0 6px 5px; } +#woo_container .woo-sbm-builder .woo-sbm-controls .button { width: 90px!important; margin-right: 23px; } +#woo_container .woo-sbm-builder #woo-sbm-more-info { text-align: center; display: block; font-size: 11px; text-transform: uppercase } +#woo_container .woo-sbm-builder-edit { float:none; width: auto; margin:0; padding: 10px 0 0; border: 0; background: transparent none;} +#woo_container .woo-sbm-builder-edit input { width: 230px; } + +#woo_container #woo-sbm-response-builder input { font-size: 12px; padding: 3px; width: 280px} + +#woo_container #woo-sbm-sidebars {margin-top: 20px; padding-top: 20px; border-top: 1px solid #eee } +#woo_container #woo-sbm-sidebars #menu-to-edit { padding: 0 0 30px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li dt { width: 492px; cursor: default; } +#woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings .description-thin { width: 236px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings .description-wide { width: 481px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings p label input, #woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings p label select, #woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings p label textarea { margin-top: 5px;} +#woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings p { margin-bottom: 20px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings .menu-item-actions { padding: 0; margin-top: -8px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li.menu-item-depth-1 { margin-left: 15px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li.menu-item-depth-1 dt { width: 477px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li.menu-item-depth-1 .menu-item-settings { width: 477px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li.menu-item-depth-1 .menu-item-settings .description-thin { width: 336px; } +#woo_container #woo-sbm-sidebars #menu-to-edit li .menu-item-settings p label { z-index: 9999; position: relative; } + + +#woo_container .menu-item-depth-1 { margin-left: 30px; } + + +#woo_container #woo-sbm-builder-meta { display: none; font-size: 11px; padding: 0px; background: #fff; color: #555; border: 1px solid #ccc; width: 320px; position: absolute; top:-185px; right:0; + box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); + -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); + border-radius: 6px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; +} +#woo_container #woo-sbm-builder-meta label { font-size: 11px; border-bottom: #ccc 1px solid; padding: 5px 10px } +#woo_container #woo-sbm-builder-meta label span { text-transform: uppercase; width: 40px; text-align: right; padding-right: 5px;} +#woo_container #woo-sbm-builder-meta label.last { overflow:hidden; height:18px} + +#woo_container #woo-sbm-builder-body { padding: 10px; background: #f3f3f3;border: 1px solid; border-color: #fff #e3e3e3 #e3e3e3 #ddd;} +#woo_container #woo-sbm-builder-body label { border:0px;} +#woo_container #woo-sbm-builder-body label span { color:#999; font-family: georgia,arial; font-size: 1.2em; font-weight: 100; font-style:italic} +#woo_container .woo-sbm-builder label span { position: relative; z-index: 9999; } + + + +#woo_container #woo-sbm-builder-meta-top { padding: 5px 10px; background: #ccc; color: #000; font-size: 14px; text-transform: uppercase } +#woo_container #woo-sbm-builder-meta-bottom {} + +#woo_container #woo-sbm-builder-part-assign { display: none} +#woo_container #woo-sbm-builder-message { display:block; font-size: 11px; padding: 10px 0; cursor: pointer; text-decoration: underline; color:green; font-weight: 700;} +#woo_container #woo-sbm-builder-message:hover { text-decoration: none;} +#woo_container .last { border-bottom: 0px!important;} +#woo_container .woo-sbm-controls {height:20px; margin-top: 15px} +#woo_container .woo-sbm-controls .button { float:right} + +#woo_container .saved_sidebar { background: #D7E6F2; border:1px solid #C2CFDF; font-size: 13px; margin-bottom: 3px; padding: 5px 10px} +#woo_container .piggy { margin-left: 6px; background: #C9D9E6; padding: 0px 10px;font-size: 11px} +#woo_container .delete-sidebar { float:right; font-size: 9px; color: red; margin-left: 15px} +#woo_container .edit-sidebar { float:right; font-size: 9px; color: green} + +/* Nav Menu - From wordpress */ +#menu-container .inside { padding-bottom: 10px; } + +.menu { + padding-top:1em; +} + +#menu-to-edit { + padding: 1em 0; +} + +.menu ul { + width: 100%; +} +.menu ul.sub-menu { +} +.menu li { + margin-bottom: 0; + position:relative; +} +.menu-item-bar { + clear:both; + line-height:1.5em; + position:relative; + margin-top: 13px; +} +.menu-item-handle { + border: 1px solid #E6E6E6; + position: relative; + padding-left: 10px; + height: auto; + width: 400px; + line-height: 35px; + text-shadow: 0 1px 0 #FFFFFF; + font-weight:bold; + overflow: hidden; + border-radius: 6px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; + word-wrap: break-word; +} +.menu-item-edit-active .menu-item-handle { + -moz-border-radius: 6px 6px 0 0; + -webkit-border-bottom-right-radius: 0; + -webkit-border-bottom-left-radius: 0; + -khtml-border-bottom-right-radius: 0; + -khtml-border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.no-js .menu-item-edit-active .item-edit { + display: none; +} +.js .menu-item-handle { + cursor: move; +} +.menu li.deleting .menu-item-handle { + background-color: #f66; + background-image: none; + text-shadow: 0 0 0 #ccc; +} + +.menu-item-handle .item-title { + padding: 7px 0; + line-height: 20px; + display:block; + margin-right:13em; +} + +.item-type { text-transform: uppercase; font-size: 11px; color: #999999; padding-right: 10px; } +.item-controls { font-size: 11px; position: absolute; right: 20px; top: -1px; } +.item-controls a { text-decoration: none; } +.item-controls a:hover { cursor: pointer; } +.item-controls .item-order { padding-right: 10px;} +.item-controls .item-order a { + font-weight:bold; +} + +body.js .item-order { + display:none; +} + +.item-controls .menu-item-delete:hover { color: #ff0000; } + +.item-edit { + background: url( "../../../../wp-admin/images/menu-bits.gif?ver=20100610") no-repeat scroll 0 -105px; + position: absolute; + right: -20px; + top: 0; + display: block; + width: 23px; + height: 36px; + overflow: hidden; + text-indent:-999em; + border-bottom: 1px solid #eee; + -moz-border-radius-bottomleft: 3px; + -webkit-border-bottom-left-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; +} + +/* Menu editing */ +.menu-instructions-inactive { + display: none; +} +.menu-item-settings { + background: #F9F9F9; + display:block; + width: 492px; + padding: 10px 0 10px 10px; + border: solid #E6E6E6; + border-width: 0 1px 1px 1px; + -moz-border-radius: 0 0 6px 6px; + -webkit-border-bottom-right-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + -khtml-border-bottom-left-radius: 6px; +} + + +.menu-item-settings:after { + clear: both; + content: '.'; + display: block; + height: 0px; + visibility: hidden; +} +.menu-item-settings input { width: 100%!important} + +.menu-item-edit-active .menu-item-settings { + display:block; +} + +.menu-item-edit-inactive .menu-item-settings { + display:none; +} + +.add-menu-item-pagelinks { + margin:.5em auto; + text-align:center; +} + +.link-to-original { + display: block; + margin: 0 0 10px; + padding: 3px 5px 5px; + font-size: 11px; + color: #777; + font-style: italic; + border: 1px solid #dfdfdf; + border-radius: 6px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; +} + .link-to-original a { + padding-left: 4px; + font-style: normal; + } + +.hidden-field { + display: none; +} + +.menu-item-settings .description-thin, +.menu-item-settings .description-wide { + margin-right: 10px; + float: left; +} +.description-thin { + width: 190px; + height: 40px; +} +.description-wide { + width: 390px; +} + +.menu-item-actions { + padding-top: 15px; +} + +#cancel-save { cursor: pointer; } +#cancel-save:hover { color: #fff !important; } +#update-menu-item { color: #fff !important; } +#update-menu-item:hover, +#update-menu-item:active, +#update-menu-item:focus { color: #eaf2fa !important; border-color: #13455b !important; } + +/* String Builder */ +.add_button { height: 50px;} +.string_option { margin-bottom: 5px; padding: 7px 12px; font-size: 12px; background: #f7f7f7; + border: 1px solid #dfdfdf; + border-radius: 6px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + -khtml-border-radius: 6px; +} +.string_option span { font-weight: 700;} +.string_option .delete { text-transform: uppercase; font-size:10px; float: right; color: red} + +/*-------------------------------------------------------------------------------------------*/ +/* Icons Option panel */ +/*-------------------------------------------------------------------------------------------*/ + +#woo_container #woo-nav ul li.general a { background-image:url(images/option-icon-general.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.styling a { background-image:url(images/option-icon-styling.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.typography a { background-image:url(images/option-icon-typography.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.image a { background-image:url(images/option-icon-image.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.ads a { background-image:url(images/option-icon-ads.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.homepage a { background-image:url(images/option-icon-homepage.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.media a { background-image:url(images/option-icon-media.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.calendar a { background-image:url(images/option-icon-calendar.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.slider a { background-image:url(images/option-icon-slider.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.box a { background-image:url(images/option-icon-box.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.layout a { background-image:url(images/option-icon-layout.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.header a { background-image:url(images/option-icon-header.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.featured a { background-image:url(images/option-icon-featured.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.main a { background-image:url(images/option-icon-main.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.sidebar a { background-image:url(images/option-icon-sidebar.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.footer a { background-image:url(images/option-icon-footer.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.portfolio a { background-image:url(images/option-icon-portfolio.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.tumblog a { background-image:url(images/option-icon-tumblog.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.nav a { background-image:url(images/option-icon-nav.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.audio a { background-image:url(images/option-icon-audio.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.misc a { background-image:url(images/option-icon-misc.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.maps a { background-image:url(images/option-icon-maps.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.searchoption a { background-image:url(images/option-icon-search.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.upload a { background-image:url(images/option-icon-upload.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.favorite a { background-image:url(images/option-icon-favorite.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.listing a { background-image:url(images/option-icon-listing.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.post a { background-image:url(images/option-icon-post.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } +#woo_container #woo-nav ul li.connect a { background-image:url(images/option-icon-connect.png); background-repeat: no-repeat; background-position: 15px center; padding-left:40px; } + +/*-------------------------------------------------------------------------------------------*/ +/* GENERAL STYLES */ +/*-------------------------------------------------------------------------------------------*/ + +/* http://sonspring.com/journal/clearing-floats */ + +html body * span.clear, +html body * div.clear, +html body * li.clear, +html body * dd.clear +{ + background: none; + border: 0; + clear: both; + display: block; + float: none; + font-size: 0; + list-style: none; + margin: 0; + padding: 0; + overflow: hidden; + visibility: hidden; + width: 0; + height: 0; +} diff --git a/src/wp-content/themes/bloggingstream/functions/admin-theme-page.php b/src/wp-content/themes/bloggingstream/functions/admin-theme-page.php new file mode 100644 index 00000000..3dfb2a35 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-theme-page.php @@ -0,0 +1,67 @@ + +
    +

    More WooThemes

    + + get_error_code(); + + if($error == 'simplepie-error') { + + //Simplepie Error + echo "

    An error has occured with the RSS feed. (". $error .")

    "; + + } + + return; + + } + ?> + + + get_item_quantity(30); + $items = $rss->get_items(0, 30); + + ?> +
      + No items'; + else + foreach ( $items as $item ) : ?> +
    • + get_description();?> +
    • + +
    + +
    + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/admin-tumblog-quickpress.php b/src/wp-content/themes/bloggingstream/functions/admin-tumblog-quickpress.php new file mode 100644 index 00000000..abbb2887 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/admin-tumblog-quickpress.php @@ -0,0 +1,1465 @@ + $normal_dashboard['woo_tumblog_dashboard_widget']); + unset($normal_dashboard['woo_tumblog_dashboard_widget']); + // Merge the two arrays together so tumblog widget is at the beginning + $sorted_dashboard = array_merge($woo_tumblog_widget_backup, $normal_dashboard); + // Save the sorted array back into the original metaboxes + $wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard; +} + +//Loads Tumblog javascript and php js functions +function woo_load_tumblog_libraries() { + wp_enqueue_script( 'newscript', get_template_directory_uri() . '/functions/js/tumblog-ajax.js', array( 'jquery', 'jquery-form')); + wp_enqueue_script( 'nicedit', get_template_directory_uri() . '/functions/js/nicEdit.js' ); + wp_enqueue_script( 'phpjs', get_template_directory_uri() . '/functions/js/php.js' ); + wp_enqueue_script( 'datepicker', get_template_directory_uri() . '/functions/js/ui.datepicker.js',array( 'jquery')); +} + +//Load Tumblog CSS +function woo_load_tumblog_css($hook) { + if ($hook == 'post.php' OR $hook == 'post-new.php' OR $hook == 'page-new.php' OR $hook == 'page.php') { + } + else { + echo ""; + echo ""; + } + +} + +/*-----------------------------------------------------------------------------------*/ +/* AJAX Callback Functions +/*-----------------------------------------------------------------------------------*/ + +//Handles AJAX Form Post from Woo QuickPress +function woo_tumblog_ajax_post() { + //Publish Article + if ($_POST['tumblog-type'] == 'article') + { + $data = $_POST; + $type = 'note'; + woo_tumblog_publish($type, $data); + die ( 'OK' ); + } + //Publish Video + elseif ($_POST['tumblog-type'] == 'video') + { + $data = $_POST; + $type = 'video'; + woo_tumblog_publish($type, $data); + die ( 'OK' ); + } + //Publish Image + elseif ($_POST['tumblog-type'] == 'image') + { + $data = $_POST; + $type = 'image'; + woo_tumblog_publish($type, $data); + die ( 'OK' ); + } + //Publish Link + elseif ($_POST['tumblog-type'] == 'link') + { + $data = $_POST; + $type = 'link'; + woo_tumblog_publish($type, $data); + die ( 'OK' ); + } + //Publish Quote + elseif ($_POST['tumblog-type'] == 'quote') + { + $data = $_POST; + $type = 'quote'; + woo_tumblog_publish($type, $data); + die ( 'OK' ); + } + //Publish Audio + elseif ($_POST['tumblog-type'] == 'audio') + { + $data = $_POST; + $type = 'audio'; + woo_tumblog_publish($type, $data); + die ( 'OK' ); + } + //Default + else { + die ( 'OK' ); + } +} + +//Publishes the Tumblog Item +function woo_tumblog_publish($type, $data) { + global $current_user; + //Gets the current user's info + get_currentuserinfo(); + + $content_method = get_option( 'woo_tumblog_content_method' ); + + //Set custom fields + $tumblog_custom_fields = array( 'video-embed' => 'video-embed', + 'quote-copy' => 'quote-copy', + 'quote-author' => 'quote-author', + 'quote-url' => 'quote-url', + 'link-url' => 'link-url', + 'image-url' => 'image', + 'audio-url' => 'audio' + ); + //get term ids + $tumblog_items = array( 'articles' => get_option( 'woo_articles_term_id'), + 'images' => get_option( 'woo_images_term_id'), + 'audio' => get_option( 'woo_audio_term_id'), + 'video' => get_option( 'woo_video_term_id'), + 'quotes' => get_option( 'woo_quotes_term_id'), + 'links' => get_option( 'woo_links_term_id') + ); + //Set date formatting + $php_formatting = "Y-m-d H:i:s"; + //default post settings + $tumbl_note = array(); + $tumbl_note['post_status'] = 'publish'; + $browser = $_SERVER['HTTP_USER_AGENT'] . "\n\n"; + $safari_check = substr_count( strtolower( $browser ) , strtolower( 'safari' ) ); + if ($safari_check > 0) { + $data['tumblog-content'] = str_ireplace(array( '
    ','
    '),array( '','
    '),$data['tumblog-content']); + $data['tumblog-content'] = str_ireplace(array( '


    '),array( '

    '),$data['tumblog-content']); + $data['tumblog-content'] = str_ireplace(array( ' '), array( ' '),$data['tumblog-content']); + } + //Handle Tumblog Types + switch ($type) + { + case 'note': + //Create post object + $tumbl_note['post_title'] = $data['note-title']; + $tumbl_note['post_content'] = $data['tumblog-content']; + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + if ($data['tumblog-status'] != '') { + $tumbl_note['post_status'] = $data['tumblog-status']; + } + //Hours and Mins + $original_hours = (int)$data['original-tumblog-hours']; + $original_mins = (int)$data['original-tumblog-mins']; + $original_date = strtotime($data['original-tumblog-date']); + $posted_date = strtotime($data['tumblog-date']); + $note_hours = (int)$data['tumblog-hours']; + if ($note_hours == 0) { $note_hours = 12; } + elseif ($note_hours >= 24) { $note_hours = 0; } + $note_mins = (int)$data['tumblog-mins']; + if ($note_mins == 0) { $note_mins = 0; } + elseif ($note_mins >= 60) { $note_mins = 0; } + //Convert to Y-m-d H:i:s + //if everything is unchanged + if ( ($note_hours == $original_hours) && ($note_mins == $original_mins) && ($posted_date == $original_date) ) { + $time_now_hours = date_i18n( "H" ); + $time_now_mins = date_i18n( "i" ); + $date_raw = date( "Y").'-'.date( "m").'-'.date( "d").' '.$time_now_hours.':'.$time_now_mins.':00'; + } else { + $date_raw = date( "Y",strtotime($data['tumblog-date'])).'-'.date( "m",strtotime($data['tumblog-date'])).'-'.date( "d",strtotime($data['tumblog-date'])).' '.$note_hours.':'.$note_mins.':00'; + } + $date_formatted = date($php_formatting, strtotime($date_raw)); + $tumbl_note['post_date'] = $date_formatted; + // DEPRECATED + // } + $tumbl_note['post_author'] = $current_user->ID; + $tumbl_note['tags_input'] = $data['tumblog-tags']; + + // DEPRECATED + // Get Category from Theme Options + /* + if (get_option( 'tumblog_woo_tumblog_upgraded') != 'true') { + $category_id = get_cat_ID( get_option( 'woo_articles_category') ); + $categories = array($category_id); + } else { + $categories = array(); + } + */ + + $categories = array(); + + $post_cat_array = $data['post_category']; + if(empty($post_cat_array)) + { + //Do nothing + } else { + $N = count($post_cat_array); + for($i=0; $i < $N; $i++) { + array_push($categories, $post_cat_array[$i]); + } + } + $tumbl_note['post_category'] = $categories; + //Insert the note into the database + $post_id = wp_insert_post($tumbl_note); + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + + if ($content_method == 'post_format') { + set_post_format( $post_id, 'aside' ); + } else { + //update posts taxonomies + $taxonomy_data = $data['tax_input']; + if ( !empty($taxonomy_data) ) { + foreach ( $taxonomy_data as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + array_push($tags, $tumblog_items['articles']); + } + } else { + $tags[0] = $tumblog_items['articles']; + } + wp_set_post_terms( $post_id, $tags, 'tumblog' ); + } + + // DEPRECATED + // } + + break; + case 'video': + //Create post object + $tumbl_note['post_title'] = $data['video-title']; + $tumbl_note['post_content'] = $data['tumblog-content']; + // DEPRECATED + //if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + if ($data['tumblog-status'] != '') { + $tumbl_note['post_status'] = $data['tumblog-status']; + } + //Hours and Mins + $original_hours = (int)$data['original-tumblog-hours']; + $original_mins = (int)$data['original-tumblog-mins']; + $original_date = strtotime($data['original-tumblog-date']); + $posted_date = strtotime($data['tumblog-date']); + $note_hours = (int)$data['tumblog-hours']; + if ($note_hours == 0) { $note_hours = 12; } + elseif ($note_hours >= 24) { $note_hours = 0; } + $note_mins = (int)$data['tumblog-mins']; + if ($note_mins == 0) { $note_mins = 0; } + elseif ($note_mins >= 60) { $note_mins = 0; } + //Convert to Y-m-d H:i:s + //if everything is unchanged + if ( ($note_hours == $original_hours) && ($note_mins == $original_mins) && ($posted_date == $original_date) ) { + $time_now_hours = date_i18n( "H" ); + $time_now_mins = date_i18n( "i" ); + $date_raw = date( "Y").'-'.date( "m").'-'.date( "d").' '.$time_now_hours.':'.$time_now_mins.':00'; + } else { + $date_raw = date( "Y",strtotime($data['tumblog-date'])).'-'.date( "m",strtotime($data['tumblog-date'])).'-'.date( "d",strtotime($data['tumblog-date'])).' '.$note_hours.':'.$note_mins.':00'; + } + $date_formatted = date($php_formatting, strtotime($date_raw)); + $tumbl_note['post_date'] = $date_formatted; + // DEPRECATED + // } + $tumbl_note['post_author'] = $current_user->ID; + $tumbl_note['tags_input'] = $data['tumblog-tags']; + + // DEPRECATED + //Get Category from Theme Options + /* + if (get_option( 'tumblog_woo_tumblog_upgraded') != 'true') { + $category_id = get_cat_ID( get_option( 'woo_videos_category') ); + $categories = array($category_id); + } else { + $categories = array(); + } + */ + + $categories = array(); + + $post_cat_array = $data['post_category']; + if(empty($post_cat_array)) + { + //Do nothing + } else { + $N = count($post_cat_array); + for($i=0; $i < $N; $i++) { + array_push($categories, $post_cat_array[$i]); + } + } + $tumbl_note['post_category'] = $categories; + //Insert the note into the database + $post_id = wp_insert_post($tumbl_note); + //Add Custom Field Data to the Post + add_post_meta($post_id, $tumblog_custom_fields['video-embed'], $data['video-embed'], true); + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + + if ($content_method == 'post_format') { + set_post_format( $post_id, 'video' ); + } else { + //update posts taxonomies + $taxonomy_data = $data['tax_input']; + if ( !empty($taxonomy_data) ) { + foreach ( $taxonomy_data as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + array_push($tags, $tumblog_items['video']); + } + } else { + $tags[0] = $tumblog_items['video']; + } + wp_set_post_terms( $post_id, $tags, 'tumblog' ); + } + + // DEPRECATED + // } + + break; + case 'image': + //Create post object + $tumbl_note['post_title'] = $data['image-title']; + $tumbl_note['post_content'] = $data['tumblog-content']; + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + if ($data['tumblog-status'] != '') { + $tumbl_note['post_status'] = $data['tumblog-status']; + } + //Hours and Mins + $original_hours = (int)$data['original-tumblog-hours']; + $original_mins = (int)$data['original-tumblog-mins']; + $original_date = strtotime($data['original-tumblog-date']); + $posted_date = strtotime($data['tumblog-date']); + $note_hours = (int)$data['tumblog-hours']; + if ($note_hours == 0) { $note_hours = 12; } + elseif ($note_hours >= 24) { $note_hours = 0; } + $note_mins = (int)$data['tumblog-mins']; + if ($note_mins == 0) { $note_mins = 0; } + elseif ($note_mins >= 60) { $note_mins = 0; } + //Convert to Y-m-d H:i:s + //if everything is unchanged + if ( ($note_hours == $original_hours) && ($note_mins == $original_mins) && ($posted_date == $original_date) ) { + $time_now_hours = date_i18n( "H" ); + $time_now_mins = date_i18n( "i" ); + $date_raw = date( "Y").'-'.date( "m").'-'.date( "d").' '.$time_now_hours.':'.$time_now_mins.':00'; + } else { + $date_raw = date( "Y",strtotime($data['tumblog-date'])).'-'.date( "m",strtotime($data['tumblog-date'])).'-'.date( "d",strtotime($data['tumblog-date'])).' '.$note_hours.':'.$note_mins.':00'; + } + $date_formatted = date($php_formatting, strtotime($date_raw)); + $tumbl_note['post_date'] = $date_formatted; + + // DEPRECATED + // } + $tumbl_note['post_author'] = $current_user->ID; + $tumbl_note['tags_input'] = $data['tumblog-tags']; + + // DEPRECATED + //Get Category from Theme Options + /* + if (get_option( 'tumblog_woo_tumblog_upgraded') != 'true') { + $category_id = get_cat_ID( get_option( 'woo_images_category') ); + $categories = array($category_id); + } else { + $categories = array(); + } + */ + + $categories = array(); + + $post_cat_array = $data['post_category']; + if(empty($post_cat_array)) + { + //Do nothing + } else { + $N = count($post_cat_array); + for($i=0; $i < $N; $i++) { + array_push($categories, $post_cat_array[$i]); + } + } + $tumbl_note['post_category'] = $categories; + //Insert the note into the database + $post_id = wp_insert_post($tumbl_note); + //Add Custom Field Data to the Post + if ($data['image-id'] > 0) { + $my_post = array(); + $my_post['ID'] = $data['image-id']; + $my_post['post_parent'] = $post_id; + //Update the post into the database + wp_update_post( $my_post ); + add_post_meta($post_id, $tumblog_custom_fields['image-url'], $data['image-upload'], true); + } + else { + add_post_meta($post_id, $tumblog_custom_fields['image-url'], $data['image-url'], true); + } + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + + if ($content_method == 'post_format') { + set_post_format( $post_id, 'image' ); + } else { + //update posts taxonomies + $taxonomy_data = $data['tax_input']; + if ( !empty($taxonomy_data) ) { + foreach ( $taxonomy_data as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + array_push($tags, $tumblog_items['images']); + } + } else { + $tags[0] = $tumblog_items['images']; + } + wp_set_post_terms( $post_id, $tags, 'tumblog' ); + } + + // DEPRECATED + // } + + break; + case 'link': + //Create post object + $tumbl_note['post_title'] = $data['link-title']; + $tumbl_note['post_content'] = $data['tumblog-content']; + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + if ($data['tumblog-status'] != '') { + $tumbl_note['post_status'] = $data['tumblog-status']; + } + //Hours and Mins + $original_hours = (int)$data['original-tumblog-hours']; + $original_mins = (int)$data['original-tumblog-mins']; + $original_date = strtotime($data['original-tumblog-date']); + $posted_date = strtotime($data['tumblog-date']); + $note_hours = (int)$data['tumblog-hours']; + if ($note_hours == 0) { $note_hours = 12; } + elseif ($note_hours >= 24) { $note_hours = 0; } + $note_mins = (int)$data['tumblog-mins']; + if ($note_mins == 0) { $note_mins = 0; } + elseif ($note_mins >= 60) { $note_mins = 0; } + //Convert to Y-m-d H:i:s + //if everything is unchanged + if ( ($note_hours == $original_hours) && ($note_mins == $original_mins) && ($posted_date == $original_date) ) { + $time_now_hours = date_i18n( "H" ); + $time_now_mins = date_i18n( "i" ); + $date_raw = date( "Y").'-'.date( "m").'-'.date( "d").' '.$time_now_hours.':'.$time_now_mins.':00'; + } else { + $date_raw = date( "Y",strtotime($data['tumblog-date'])).'-'.date( "m",strtotime($data['tumblog-date'])).'-'.date( "d",strtotime($data['tumblog-date'])).' '.$note_hours.':'.$note_mins.':00'; + } + $date_formatted = date($php_formatting, strtotime($date_raw)); + $tumbl_note['post_date'] = $date_formatted; + // DEPRECATED + // } + $tumbl_note['post_author'] = $current_user->ID; + $tumbl_note['tags_input'] = $data['tumblog-tags']; + + // DEPRECATED + //Get Category from Theme Options + /* + if (get_option( 'tumblog_woo_tumblog_upgraded') != 'true') { + $category_id = get_cat_ID( get_option( 'woo_links_category') ); + $categories = array($category_id); + } else { + $categories = array(); + } + */ + + $categories = array(); + + $post_cat_array = $data['post_category']; + if(empty($post_cat_array)) + { + //Do nothing + } else { + $N = count($post_cat_array); + for($i=0; $i < $N; $i++) { + array_push($categories, $post_cat_array[$i]); + } + } + $tumbl_note['post_category'] = $categories; + //Insert the note into the database + $post_id = wp_insert_post($tumbl_note); + //Add Custom Field Data to the Post + add_post_meta($post_id, $tumblog_custom_fields['link-url'], $data['link-url'], true); + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + + if ($content_method == 'post_format') { + set_post_format( $post_id, 'link' ); + } else { + //update posts taxonomies + $taxonomy_data = $data['tax_input']; + if ( !empty($taxonomy_data) ) { + foreach ( $taxonomy_data as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + array_push($tags, $tumblog_items['links']); + } + } else { + $tags[0] = $tumblog_items['links']; + } + wp_set_post_terms( $post_id, $tags, 'tumblog' ); + } + // DEPRECATED + // } + + break; + case 'quote': + //Create post object + $tumbl_note['post_title'] = $data['quote-title']; + $tumbl_note['post_content'] = $data['tumblog-content']; + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + if ($data['tumblog-status'] != '') { + $tumbl_note['post_status'] = $data['tumblog-status']; + } + //Hours and Mins + $original_hours = (int)$data['original-tumblog-hours']; + $original_mins = (int)$data['original-tumblog-mins']; + $original_date = strtotime($data['original-tumblog-date']); + $posted_date = strtotime($data['tumblog-date']); + $note_hours = (int)$data['tumblog-hours']; + if ($note_hours == 0) { $note_hours = 12; } + elseif ($note_hours >= 24) { $note_hours = 0; } + $note_mins = (int)$data['tumblog-mins']; + if ($note_mins == 0) { $note_mins = 0; } + elseif ($note_mins >= 60) { $note_mins = 0; } + //Convert to Y-m-d H:i:s + //if everything is unchanged + if ( ($note_hours == $original_hours) && ($note_mins == $original_mins) && ($posted_date == $original_date) ) { + $time_now_hours = date_i18n( "H" ); + $time_now_mins = date_i18n( "i" ); + $date_raw = date( "Y").'-'.date( "m").'-'.date( "d").' '.$time_now_hours.':'.$time_now_mins.':00'; + } else { + $date_raw = date( "Y",strtotime($data['tumblog-date'])).'-'.date( "m",strtotime($data['tumblog-date'])).'-'.date( "d",strtotime($data['tumblog-date'])).' '.$note_hours.':'.$note_mins.':00'; + } + $date_formatted = date($php_formatting, strtotime($date_raw)); + $tumbl_note['post_date'] = $date_formatted; + // DEPRECATED + // } + $tumbl_note['post_author'] = $current_user->ID; + $tumbl_note['tags_input'] = $data['tumblog-tags']; + + // DEPRECATED + //Get Category from Theme Options + /* + if (get_option( 'tumblog_woo_tumblog_upgraded') != 'true') { + $category_id = get_cat_ID( get_option( 'woo_quotes_category') ); + $categories = array($category_id); + } else { + $categories = array(); + } + */ + + $categories = array(); + + $post_cat_array = $data['post_category']; + if(empty($post_cat_array)) + { + //Do nothing + } else { + $N = count($post_cat_array); + for($i=0; $i < $N; $i++) { + array_push($categories, $post_cat_array[$i]); + } + } + $tumbl_note['post_category'] = $categories; + //Insert the note into the database + $post_id = wp_insert_post($tumbl_note); + //Add Custom Field Data to the Post + add_post_meta($post_id, $tumblog_custom_fields['quote-copy'], $data['quote-copy'], true); + add_post_meta($post_id, $tumblog_custom_fields['quote-author'], $data['quote-author'], true); + add_post_meta($post_id, $tumblog_custom_fields['quote-url'], $data['quote-url'], true); + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + + if ($content_method == 'post_format') { + set_post_format( $post_id, 'quote' ); + } else { + //update posts taxonomies + $taxonomy_data = $data['tax_input']; + if ( !empty($taxonomy_data) ) { + foreach ( $taxonomy_data as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + array_push($tags, $tumblog_items['quotes']); + } + } else { + $tags[0] = $tumblog_items['quotes']; + } + wp_set_post_terms( $post_id, $tags, 'tumblog' ); + } + // DEPRECATED + // } + + break; + case 'audio': + //Create post object + $tumbl_note['post_title'] = $data['audio-title']; + $tumbl_note['post_content'] = $data['tumblog-content']; + + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + if ($data['tumblog-status'] != '') { + $tumbl_note['post_status'] = $data['tumblog-status']; + } + //Hours and Mins + $original_hours = (int)$data['original-tumblog-hours']; + $original_mins = (int)$data['original-tumblog-mins']; + $original_date = strtotime($data['original-tumblog-date']); + $posted_date = strtotime($data['tumblog-date']); + $note_hours = (int)$data['tumblog-hours']; + if ($note_hours == 0) { $note_hours = 12; } + elseif ($note_hours >= 24) { $note_hours = 0; } + $note_mins = (int)$data['tumblog-mins']; + if ($note_mins == 0) { $note_mins = 0; } + elseif ($note_mins >= 60) { $note_mins = 0; } + //Convert to Y-m-d H:i:s + //if everything is unchanged + if ( ($note_hours == $original_hours) && ($note_mins == $original_mins) && ($posted_date == $original_date) ) { + $time_now_hours = date_i18n( "H" ); + $time_now_mins = date_i18n( "i" ); + $date_raw = date( "Y").'-'.date( "m").'-'.date( "d").' '.$time_now_hours.':'.$time_now_mins.':00'; + } else { + $date_raw = date( "Y",strtotime($data['tumblog-date'])).'-'.date( "m",strtotime($data['tumblog-date'])).'-'.date( "d",strtotime($data['tumblog-date'])).' '.$note_hours.':'.$note_mins.':00'; + } + $date_formatted = date($php_formatting, strtotime($date_raw)); + $tumbl_note['post_date'] = $date_formatted; + + // DEPRECATED + // } + $tumbl_note['post_author'] = $current_user->ID; + $tumbl_note['tags_input'] = $data['tumblog-tags']; + + // DEPRECATED + //Get Category from Theme Options + /* + if (get_option( 'tumblog_woo_tumblog_upgraded') != 'true') { + $category_id = get_cat_ID( get_option( 'woo_audio_category') ); + $categories = array($category_id); + } else { + $categories = array(); + } + */ + + $categories = array(); + + $post_cat_array = $data['post_category']; + if(empty($post_cat_array)) + { + //Do nothing + } else { + $N = count($post_cat_array); + for($i=0; $i < $N; $i++) { + array_push($categories, $post_cat_array[$i]); + } + } + $tumbl_note['post_category'] = $categories; + //Insert the note into the database + $post_id = wp_insert_post($tumbl_note); + //Add Custom Field Data to the Post + if ($data['audio-id'] > 0) { + $my_post = array(); + $my_post['ID'] = $data['audio-id']; + $my_post['post_parent'] = $post_id; + //Update the post into the database + wp_update_post( $my_post ); + add_post_meta($post_id, $tumblog_custom_fields['audio-url'], $data['audio-upload'], true); + } + else { + add_post_meta($post_id, $tumblog_custom_fields['audio-url'], $data['audio-url'], true); + } + // DEPRECATED + // if (get_option( 'tumblog_woo_tumblog_upgraded') == 'true') { + if ($content_method == 'post_format') { + set_post_format( $post_id, 'audio' ); + } else { + //update posts taxonomies + $taxonomy_data = $data['tax_input']; + if ( !empty($taxonomy_data) ) { + foreach ( $taxonomy_data as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + array_push($tags, $tumblog_items['audio']); + } + } else { + $tags[0] = $tumblog_items['audio']; + } + wp_set_post_terms( $post_id, $tags, 'tumblog' ); + } + // DEPRECATED + // } + + break; + default: + break; + } +} + +//Handles AJAX Post +function woo_tumblog_file_upload() { + global $wpdb; + //Upload overrides + $filename = $_FILES['userfile']; // [name] [tmp_name] + $override['test_form'] = false; + $override['action'] = 'wp_handle_upload'; + //Handle Uploaded File + $uploaded_file = wp_handle_upload($filename, $override); // [file] [url] [type] + //Create Attachment Object + $attachment['post_title'] = $filename['name']; //post_title, post_content (the value for this key should be the empty string), post_status and post_mime_type + $attachment['post_content'] = ''; + $attachment['post_status'] = 'inherit'; + $attachment['post_mime_type'] = $uploaded_file['type']; + $attachment['guid'] = $uploaded_file['url']; + //Prepare file attachment + $wud = wp_upload_dir(); // [path] [url] [subdir] [basedir] [baseurl] [error] + $filename_attach = $wud['basedir'].$uploaded_file['file']; + //Insert Attachment + $attach_id = wp_insert_attachment( $attachment, $filename_attach, 0 ); + $attach_data = wp_generate_attachment_metadata( $attach_id, $filename_attach ); + wp_update_attachment_metadata( $attach_id, $attach_data ); + //Handle Errors and Response + if(!empty($uploaded_file['error'])) {echo 'Upload Error: ' . $uploaded_file['error']; } + else { echo $uploaded_file['url'].'|'.$attach_id.'|'; } // Is the Response +} + +/*-----------------------------------------------------------------------------------*/ +/* Dashboard Widget +/*-----------------------------------------------------------------------------------*/ + +// Tumblog Dashboard Widget Output +function woo_tumblog_dashboard_widget_output() { + //security check + if (current_user_can( 'publish_posts')) { + $tumblog_items = array( 'articles' => get_option( 'woo_articles_term_id'), + 'images' => get_option( 'woo_images_term_id'), + 'audio' => get_option( 'woo_audio_term_id'), + 'video' => get_option( 'woo_video_term_id'), + 'quotes' => get_option( 'woo_quotes_term_id'), + 'links' => get_option( 'woo_links_term_id') + ); + ?> + + +
    + +
    "> + + + +
    + +
    + Article + Image + Link + Audio + Video + Quote +
    + +
    +

    +
    + +
    +
    + +
    +

    +
    + +
    +

    + +
    + +
    +

    +
    + +
    + +
    +

    |

    +
    + +
    +
    + +
    + + + +
    +

    +
    + +
    +

    + +

    +
    + +
    +

    +
    + +
    +
    + +
    +

    +
    + +
    + +
    +

    |

    +
    + +
    +
    + +
    + +
    + + + + + + +

    View Advanced Options

    +
    + +
    +

    + + +

    +

    + + + + + @ : + +

    +
    +
    + + + +
    + +
      + $taxonomy ) ); ?> + +
    + +
    +
    + +
    + + + +
    + +
      + $taxonomy ) ); ?> + +
    + +
    +
    + +
    + +
    +

    +
    + +
    +
    + +
    + + +
    + +
    + +
    + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/css/colorpicker.css b/src/wp-content/themes/bloggingstream/functions/css/colorpicker.css new file mode 100644 index 00000000..8f66acc7 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/css/colorpicker.css @@ -0,0 +1,177 @@ +.colorpicker { + width: 356px; + height: 176px; + overflow: hidden; + position: absolute; + background: url(../images/colorpicker/colorpicker_background.png); + font-family: Arial, Helvetica, sans-serif; + display: none; +} +.colorpicker_color { + width: 150px; + height: 150px; + left: 14px; + top: 13px; + position: absolute; + background: #f00; + overflow: hidden; + cursor: crosshair; +} +.colorpicker_color div { + position: absolute; + top: 0; + left: 0; + width: 150px; + height: 150px; + background: url(../images/colorpicker/colorpicker_overlay.png); +} +.colorpicker_color div div { + position: absolute; + top: 0; + left: 0; + width: 11px; + height: 11px; + overflow: hidden; + background: url(../images/colorpicker/colorpicker_select.gif); + margin: -5px 0 0 -5px; +} +.colorpicker_hue { + position: absolute; + top: 13px; + left: 171px; + width: 35px; + height: 150px; + cursor: n-resize; +} +.colorpicker_hue div { + position: absolute; + width: 35px; + height: 9px; + overflow: hidden; + background: url(../images/colorpicker/colorpicker_indic.gif) left top; + margin: -4px 0 0 0; + left: 0px; +} +.colorpicker_new_color { + position: absolute; + width: 60px; + height: 30px; + left: 213px; + top: 13px; + background: #f00; +} +.colorpicker_current_color { + position: absolute; + width: 60px; + height: 30px; + left: 283px; + top: 13px; + background: #f00; +} +.colorpicker input { + background-color: transparent; + border: 1px solid transparent; + position: absolute; + font-size: 10px; + font-family: Arial, Helvetica, sans-serif; + color: #898989; + top: 4px; + right: 11px; + text-align: right; + margin: 0; + padding: 0; + height: 12px; +} +.colorpicker_hex { + position: absolute; + width: 72px; + height: 22px; + background: url(../images/colorpicker/colorpicker_hex.png) top; + left: 212px; + top: 142px; +} +.colorpicker_hex input { + right: 6px; +} +.colorpicker_field { + height: 22px; + width: 62px; + background-position: top; + position: absolute; +} +.colorpicker_field span { + position: absolute; + width: 12px; + height: 22px; + overflow: hidden; + top: 0; + right: 0; + cursor: n-resize; +} +.colorpicker_rgb_r { + background-image: url(../images/colorpicker/colorpicker_rgb_r.png); + top: 52px; + left: 212px; +} +.colorpicker_rgb_g { + background-image: url(../images/colorpicker/colorpicker_rgb_g.png); + top: 82px; + left: 212px; +} +.colorpicker_rgb_b { + background-image: url(../images/colorpicker/colorpicker_rgb_b.png); + top: 112px; + left: 212px; +} +.colorpicker_hsb_h { + background-image: url(../images/colorpicker/colorpicker_hsb_h.png); + top: 52px; + left: 282px; +} +.colorpicker_hsb_s { + background-image: url(../images/colorpicker/colorpicker_hsb_s.png); + top: 82px; + left: 282px; +} +.colorpicker_hsb_b { + background-image: url(../images/colorpicker/colorpicker_hsb_b.png); + top: 112px; + left: 282px; +} +.colorpicker_submit { + position: absolute; + width: 22px; + height: 22px; + background: url(../images/colorpicker/colorpicker_submit.png) top; + left: 322px; + top: 142px; + overflow: hidden; +} +.colorpicker_focus { + background-position: center; +} +.colorpicker_hex.colorpicker_focus { + background-position: bottom; +} +.colorpicker_submit.colorpicker_focus { + background-position: bottom; +} +.colorpicker_slider { + background-position: bottom; +} + +.colorSelector { + position: relative; + width: 27px; + height: 27px; + background: url(../images/colorpicker/select.png); + float:left; +} +.colorSelector div { + position: absolute; + top: 4px; + left: 3px; + width: 21px; + height: 19px; + background: url(../images/colorpicker/select.png) center; +} \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/css/custom_menu.css b/src/wp-content/themes/bloggingstream/functions/css/custom_menu.css new file mode 100644 index 00000000..88fbdb41 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/css/custom_menu.css @@ -0,0 +1,160 @@ +.fix{clear: both;height: 1px;margin: -1px 0 0;overflow: hidden;} + + +#no-js {display:block;} + +.maintitle { margin: 0 0 20px 0!important;} + +.logo { vertical-align: middle; margin: 0 10px 0 0; } + +#pages-left { min-width:650px;max-width:1100px;width: 100%; float:left; clear: left; margin-right: -315px; } +#pages-left .inside {margin-top: 20px; margin-right: 315px; } +#nav-container { margin-top: -3px; } + +.sidebar-name { background-color:#AAAAAA; +background-image:url(../../../../../wp-admin/images/ed-bg.gif); +border-color:#DFDFDF; +text-shadow:0 1px 0 #FFFFFF;-moz-border-radius-topleft:8px; +-moz-border-radius-topright:8px; +background-position:0 0; +background-repeat:repeat-x; +border-style:solid; +border-width:1px; +cursor:pointer; +font-size:13px; } + + +.sidebar-name h3 { +font-size:13px; +height:19px; +margin:0; +overflow:hidden; +padding:5px 12px; +white-space:nowrap; +} + +.sidebar-name-arrow { +background:transparent url(../../../../../wp-admin/images/menu-bits.gif) no-repeat scroll left -109px; +float:right; +height:29px; +width:26px; +} + +#menu-right { width: 285px; margin-right: 10px; margin-left: 20px; float:left; clear: right;} +h2.heading { margin: 32px 0 10px 0; } + +.widgets-holder-wrap { margin: 0 0 20px 0; } +.widget-holder { +padding:15px 10px; +-moz-border-radius-bottomleft:8px; +-moz-border-radius-bottomright:8px; +border-style:none solid solid; +border-width:0 1px 1px; +background-color:#F1F1F1; +border-color:#DDDDDD; +} + +.checkboxes { float: right; margin: 10px 12px 0 0; } + +.addtomenu { +display: block; +float: right; +margin: 10px 0 0 0; +text-shadow:0 -1px 0 rgba(0, 0, 0, 0.3); +background:#21759B url(../../../../../wp-admin/images/button-grad.png) repeat-x scroll left top; +border-color:#298CBA !important; +color:#FFFFFF !important; +font-weight:bold; +-moz-border-radius-bottomleft:11px; +-moz-border-radius-bottomright:11px; +-moz-border-radius-topleft:11px; +-moz-border-radius-topright:11px; +border-style:solid; +border-width:1px; +cursor:pointer; +font-size:11px !important; +line-height:16px; +padding:2px 8px; +text-decoration:none; +} + +.list { zoom: 1; } +.list li { margin: 0; } +.list dt { display:none; float: left; width: 260px; margin: 0; padding: 0 0 0 5px; line-height: 30px; border-bottom: 1px solid #e3e3e3; } +.list dt span { float: left; } +.list dt img { cursor: pointer; float: right; margin: 7px 5px 0 0 } + +#nav-container { padding: 0 10px 10px 10px; background-color: #fff; border: 1px solid #DFDFDF; border-top: none; -moz-border-radius-bottomleft:8px; -moz-border-radius-bottomright:8px; } + +#custom-nav ul { width: 100%; } +#custom-nav li { margin: 0; } +.ui-draggable-dragging { width: 500px; } +#custom-nav li dl dt { -webkit-border-bottom-left-radius:6px;-webkit-border-bottom-right-radius:6px;-webkit-border-top-left-radius:6px;-webkit-border-top-right-radius:6px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top-left-radius:6px;border-top-right-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-bottomright:6px;-moz-border-radius-topleft:6px;-moz-border-radius-topright:6px; +border:1px solid #E6E6E6;position: relative; padding-left:10px;background-color: #f1f1f1; height: 35px; line-height: 35px; } +#custom-nav li dl dt:hover { cursor: move; } +#custom-nav li dl dt .controls { position: absolute; right: 15px; top: -1px; } +#custom-nav li dl dt img { vertical-align: middle; } +#custom-nav li dl dt a {} +#custom-nav li .title { background:url(../images/ico-arrow.png) no-repeat 4px 5px; padding-left:15px; } +#custom-nav li ul li { margin-left:20px; opacity:.7;} +#custom-nav li ul li ul li { opacity: .9;} +#custom-nav li ul li ul li ul li { opacity: .9;} +#custom-nav li ul li ul li ul li ul li { opacity: .95; } + +#existing-pages li .title { background:url(../images/ico-arrow.png) no-repeat 4px 13px; padding-left:15px; } +#existing-pages li ul li .title { margin-left:10px; } +#existing-pages li ul li ul li .title { margin-left:20px; } +#existing-pages li ul li ul li ul li .title { margin-left:30px; } +#existing-pages li ul li ul li ul li ul li .title { margin-left:40px; } +#existing-pages li ul li ul li ul li ul li ul li .title { margin-left:50px; } +#existing-pages li ul li ul li ul li ul li ul li ul li .title { margin-left:60px; } +#existing-pages li ul li ul li ul li ul li ul li ul li ul li .title { margin-left:70px; } +#existing-pages li ul li ul li ul li ul li ul li ul li ul li ul li .title { margin-left:80px; } + +#existing-categories li .title { background:url(../images/ico-arrow.png) no-repeat 4px 13px; padding-left:15px; } +#existing-categories li ul li .title { margin-left:10px; } +#existing-categories li ul li ul li .title { margin-left:20px; } +#existing-categories li ul li ul li ul li .title { margin-left:30px; } +#existing-categories li ul li ul li ul li ul li .title { margin-left:40px; } +#existing-categories li ul li ul li ul li ul li ul li .title { margin-left:50px; } +#existing-categories li ul li ul li ul li ul li ul li ul li .title { margin-left:60px; } +#existing-categories li ul li ul li ul li ul li ul li ul li ul li .title { margin-left:70px; } +#existing-categories li ul li ul li ul li ul li ul li ul li ul li ul li .title { margin-left:80px; } + + +img.remove, img.edit { cursor: pointer; margin: 0 5px 0 0; } + +.dropzone {height:7px;margin: 3px 0 3px 0;} + +#custom-nav li dl {} + +.hide {display:none;} + +.type { text-transform: uppercase; font-size: 11px; color: #999999; padding-right:10px; } + +#menu_select { width: 170px; } + +#dialog-confirm label { padding-left: 10px; } + +/* EDIT LINK BOX */ +.ui-dialog { background: #fff; border: 1px solid #555555; -moz-box-shadow:0 4px 30px #000000; } +.ui-dialog-titlebar { color: #CFCFCF;font-family:"Lucida Grande",Verdana,Arial,sans-serif; padding: 6px 10px 6px; background-color: #222222!important; border: none!important; -moz-border-radius: none!important; } +#dialog-confirm { height: 168px !important; padding: 20px 10px 10px; } +#dialog-confirm input { margin: 0 0 15px 0; width: 280px; } +#dialog-confirm select { margin: 0 0 15px 0; } +.ui-dialog-buttonpane { padding: 10px; } +.ui-dialog-buttonpane button { margin: 0 10px 0 0; background:#F2F2F2; text-shadow:0 1px 0 #FFFFFF; border-color:#BBBBBB; color:#464646; -moz-border-radius-bottomleft:11px; -moz-border-radius-bottomright:11px; -moz-border-radius-topleft:11px; -moz-border-radius-topright:11px; border-style:solid; border-width:1px; cursor:pointer; font-size:11px !important; line-height:14px; padding:2px 8px; text-decoration:none; } + +.ui-dialog-buttonpane button:hover {color:#000;border-color:#666;} + + + +.ui-icon { display: none; } + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 8px; -webkit-border-radius: 8px; } + + +#reset_woo_menu { background:#c77 none !important;color:white!important;text-shadow:0 1px 0 #555 !important;} diff --git a/src/wp-content/themes/bloggingstream/functions/css/jquery-ui-datepicker.css b/src/wp-content/themes/bloggingstream/functions/css/jquery-ui-datepicker.css new file mode 100644 index 00000000..cdca7888 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/css/jquery-ui-datepicker.css @@ -0,0 +1,347 @@ +/* +* jQuery UI CSS Framework +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +*/ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + + +/* +* jQuery UI CSS Framework +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +*/ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(../images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(../images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(../images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; outline: none; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; outline: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #dadada url(../images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; outline: none; } +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(../images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; outline: none; text-decoration: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(../images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(../images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(../images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(../images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(../images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(../images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(../images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(../images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(../images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(../images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(../images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Datepicker +----------------------------------*/ +.ui-datepicker { width: 17em; padding: .2em .2em 0; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; } +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +} + +/* Icon Cursor Mouseover */ +img.ui-datepicker-trigger { cursor:pointer; } \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/css/shortcode-generator.css b/src/wp-content/themes/bloggingstream/functions/css/shortcode-generator.css new file mode 100644 index 00000000..d621a596 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/css/shortcode-generator.css @@ -0,0 +1,94 @@ +/*----------------------------------------------------------------------------------- + +FILE INFORMATION + +Description: WooThemes shortcode generator CSS. +Date Created: 2011-01-21. +Author: Based on the work of the Shortcode Ninja plugin by VisualShortcodes.com. +Integration and Addons: Matty. +Since: 3.5.0 +Copyright 2010 (c) VisualShortcodes.com + + +TABLE OF CONTENTS + +1. Layout +2. Attributes Table +3. Validation +4. Column Control +5. Form Elements +-5.1 Colour Picker + +-----------------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------------- + 1. Layout +-----------------------------------------------------------------------------------*/ + +#woo-options-buttons { margin: -3px -15px 0; background: #EDEDED; padding: 12px 20px 8px; border-bottom: 1px solid #ddd; } +#woo-options {float: left; width: 380px; margin-right: 20px; position: relative; z-index: 2; } +#woo-options.shortcode-related, #woo-options.shortcode-column, #woo-options.shortcode-tab { width: 100%; } +#woo-options h3, #woo-preview h3, #woo-options-error h3 { border-bottom: 1px solid #E7E7E7; font-size: 13px; margin: 10px 0; padding: 7px 0; } +#woo-preview { width: 225px; position: relative; z-index: 2; } +#woo-preloader { position: absolute; } +.woo-loading { background: url( "../images/loading-bottom.gif") no-repeat scroll right center transparent; padding-right: 15px; } +#woo-options.shortcode-contactform { width: 100%; display: block; } +#woo-preview.shortcode-contactform { width: 100%; margin-top: -20px; display: block; } +#woo-preview.shortcode-contactform iframe { height: 530px!important; } + +/*----------------------------------------------------------------------------------- + 2. Attributes Table +-----------------------------------------------------------------------------------*/ + +#woo-options-table { border: 0px solid #DFDFDF; width: 100%; margin-bottom: 8px; } +#woo-options-table th { padding-top: 0.2em; } +#woo-options.shortcode-column th, #woo-options.shortcode-tab th { width: 20px; vertical-align: top; } +#woo-options-table td { vertical-align: middle; padding: 0 5px 10px 0; } +.woo-input-help { font-size: 11px; color: #999; font-style: italic; font-family: sans-serif; display: block; clear: both; } +.woo-input-help p { margin: 0; color: #888; font-size: 11px; } +abbr.woo-required { color: #FF0000; } + +/*----------------------------------------------------------------------------------- + 3. Validation +-----------------------------------------------------------------------------------*/ + +#woo-options-error p { margin: 0; } +#woo-options-error h4 { margin: 1.33em 0 0.8em 0; } +input.woo-required {} +.woo-validating { background: url( "../images/loading-bottom.gif") no-repeat scroll right center transparent; padding-right: 18px; } +.woo-validated { background: url( "../images/happy.png") no-repeat scroll right center transparent; padding-right: 15px; } +.woo-validation-error { background: url( "../images/ico-alert.png") no-repeat scroll right center transparent; padding-right: 15px; } + +/*----------------------------------------------------------------------------------- + 4. Column Control +-----------------------------------------------------------------------------------*/ + +div.column-button { border: 1px solid #333333; width: 100px; margin: 4px 0; text-align: center; } +input.column-button[disabled], input.column-button[disabled]:hover { background-color: #fff !important; color: #aaa; border: 1px solid #eee; } +input.column-button { float: left; clear: left; margin-top: 2px; border: 1px solid #777777; background-color: #EEEEEE !important; } +.rounded5p { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } +#woo-column-text { border: 1px solid #AAAAAA; font-size: 22px; font-family: Sans-serif; padding: 5px 40px 5px 5px; } + +/*----------------------------------------------------------------------------------- + 5. Form Elements +-----------------------------------------------------------------------------------*/ + +#woo-options input[type=text], #woo-options select { margin-bottom: 4px; border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC; border-style: solid; border-width: 1px; background-color: #FAFAFA; font-family: "Lucida Grande",Verdana,sans-serif;height: 28px; width: 280px; color: #555555; font-size: 12px; } +#woo-options.shortcode-related input[type=text] { width: 560px; } +#woo-options.shortcode-contactform label { width: 130px; } +#woo-options.shortcode-column label {} +#woo-options.shortcode-contactform input[type=text] { width: 483px; } +#woo-options input[type=text] { padding: 5px; -moz-border-radius: 4px 4px 4px 4px; } +#woo-options select { cursor: pointer; opacity: 0; padding: 0; position: relative; z-index: 4; padding: 5px; } +#woo-options-table label { width: 89px; text-align: right; padding: 6px 6px 0 0; font-weight: bold; font-size: 11px; line-height: 12px; color: #333333; display: block; } +label.woo-required span.required {padding: 0 0 0 2px; margin-top: -4px; font-size: smaller; color: #FF0000; } +#woo-options .select_wrapper { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; font-family: "Lucida Grande","Lucida Sans Unicode",Arial,Verdana,sans-serif; font-size: 12px; background: #fafafa url(../images/select.png) no-repeat right center; border-color: #ccc #eee #eee #ccc; border-style: solid; border-width: 1px; float: left; height: 26px; width: 280px; margin: 0 0 4px; display: block; } +#woo-options .select_wrapper span { height: 26px; line-height: 26px; padding-left: 6px; position: absolute; z-index: 2; } + +/*----------------------------------------------------------------------------------- + -5.1 Colour Picker +-----------------------------------------------------------------------------------*/ + +#woo-options .woo-marker-colourpicker-control .colorSelector { margin-top: 1px; } +#woo-options .woo-marker-colourpicker-control input.input-colourpicker { float: right; width: 248px; } +#woo-options .woo-marker-colourpicker-control br { clear: both; } \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/css/shortcodes.css b/src/wp-content/themes/bloggingstream/functions/css/shortcodes.css new file mode 100644 index 00000000..42f02619 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/css/shortcodes.css @@ -0,0 +1,548 @@ +/*----------------------------------------------------------------------------------- + +TABLE OF CONTENTS: + +1. Info Boxes +2. Buttons +3. Columns +4. Tweetmeme +5. Twitter +6. Digg +7. Related Posts +8. Horizontal Rule +9. Quote +10. Icon Links +11. Facebook +12. Contact Form +13. Tabber +-13.1 Tabber Alternate Style - Boxed +-13.2 Tabber Alternate Style - Vertical +14. Dropcap +15. Content Toggle +-15.1 Toggle Alternate Style - White +16. Highlight and Abbreviation +17. List Styles - Unordered List +18. List Styles - Ordered List +19. Social Icon + +-----------------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------------------------*/ +/* 1. Info Boxes */ +/*-------------------------------------------------------------------------------------------*/ +p.woo-sc-box, div.woo-sc-box {margin:1em 0 1.5em 0; padding:9px 10px 9px 50px; border-width:1px 0 1px 0; border-style:solid;color:#555;text-shadow:none;} +.woo-sc-box.none {border-width:0;} +.woo-sc-box.full {border-width:1px;} +.woo-sc-box.medium {padding:18px 20px 18px 50px; font-size:1.1em;} +.woo-sc-box.large {padding:25px 27px 25px 50px; font-size:1.2em; } +.woo-sc-box.rounded { -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } +.woo-sc-box.alert { border-color:#f0baa2; background:#ffd9c8 url(../images/ico-alert.png) no-repeat 20px 45%; } +.woo-sc-box.download { border-color:#d4ebaf; background:#edfcd5 url(../images/ico-download.png) no-repeat 20px 45%; } +.woo-sc-box.tick { border-color:#d4ebaf; background:#edfcd5 url(../images/ico-tick.png) no-repeat 20px 45%; } +.woo-sc-box.info { border-color:#ccc; background:#eee url(../images/ico-info.png) no-repeat 20px 45%; } +.woo-sc-box.note { border-color:#efe3ae; background:#fef6d2 url(../images/ico-note.png) no-repeat 20px 45%; } +.woo-sc-box.normal { border-color:#ccc; background:#eee; padding:9px 15px;} + + +/*-------------------------------------------------------------------------------------------*/ +/* 2. Buttons */ +/*-------------------------------------------------------------------------------------------*/ +a.woo-sc-button { + font-family: sans-serif; + display: inline-block; + line-height: 1em; + padding: 6px 13px; + margin:0 .6em 1.5em 0; + border: 1px solid #4081af; + border-bottom-color: #20559a; + color: white !important; + text-align: center; + text-shadow: 0 -1px 0 hsla(0,0%,0%,.3); + text-decoration: none !important; + + /*Border radius*/ + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; + + /*Background*/ + background-color: #237fd7; /*Fallback*/ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(.2, #52a8e8), + color-stop(1, #2e76cf) + ); + background: -moz-linear-gradient( + center top, + #52a8e8 20%, + #2e76cf 100% + ); + + /*Box shadow*/ + -webkit-box-shadow: inset 0 1px 0 hsla(0,100%,100%,.3) /*Top*/, + inset 0 0 2px hsla(0,100%,100%,.3) /*Shine*/, + 0 1px 2px hsla(0, 0%, 0%, .29) /*Shadow*/; + -moz-box-shadow: inset 0 1px 0 hsla(0,100%,100%,.3) /*Top*/, + inset 0 0 2px hsla(0,100%,100%,.3) /*Shine*/, + 0 1px 2px hsla(0, 0%, 0%, .29) /*Shadow*/; + box-shadow: inset 0 1px 0 hsla(0,100%,100%,.3) /*Top*/, + inset 0 0 2px hsla(0,100%,100%,.3) /*Shine*/, + 0 1px 2px hsla(0, 0%, 0%, .29) /*Shadow*/; +} + +a.woo-sc-button.small { padding:2px 10px; font-size:0.9em;} +a.woo-sc-button.large { padding:7px 16px; font-size:1.4em;} +a.woo-sc-button.xl { padding:9px 20px; font-size:1.8em;} + +a.woo-sc-button:hover, +a.woo-sc-button.hover, +a.woo-sc-button.active { + text-decoration: none !important; + /*Background*/ + background: #0073d2; /*Fallback*/ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(.2, #3e9ee5), + color-stop(1, #1666ca) + ); + background: -moz-linear-gradient( + center top, + #3e9ee5 20%, + #1666ca 100% + ); +} + +a.woo-sc-button:active, +a.woo-sc-button.active { + border-color: #20559a; + + /*Box shadow*/ + -webkit-box-shadow: inset 0 0 7px hsla(0,0%,0%,.3) /*Shine*/, + 0 1px 0 hsla(0, 100%, 100%, 1) /*Shadow*/; + -moz-box-shadow: inset 0 0 7px hsla(0,0%,0%,.3) /*Shine*/, + 0 1px 0 hsla(0, 100%, 100%, 1) /*Shadow*/; + box-shadow: inset 0 0 7px hsla(0,0%,0%,.3) /*Shine*/, + 0 1px 0 hsla(0, 100%, 100%, 1) /*Shadow*/; +} + +a.woo-sc-button.dark span { color:#555; text-shadow:0 1px #fff;} +a.woo-sc-button.custom:hover { opacity:0.85; } + +a.woo-sc-button span { line-height:1.2em; min-height: 16px; } +a.woo-sc-button span.woo-info { background:url( "../images/ico-info.png") no-repeat 0 45%; padding-left:25px; display:block; } +a.woo-sc-button span.woo-download { background:url( "../images/ico-download.png") no-repeat 0 45%; padding-left:25px; display:block; } +a.woo-sc-button span.woo-tick { background:url( "../images/ico-tick.png") no-repeat 0 45%; padding-left:25px; display:block; } +a.woo-sc-button span.woo-note { background:url( "../images/ico-note.png") no-repeat 0 45%; padding-left:25px; display:block; } +a.woo-sc-button span.woo-alert { background:url( "../images/ico-alert.png") no-repeat 0 45%; padding-left:25px; display:block; } + +a.woo-sc-button.red { + border-color: #af4040; border-bottom-color: #9a2020; background-color: #d72323; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #e85252),color-stop(1, #cf2e2e)); + background: -moz-linear-gradient(center top,#e85252 20%,#cf2e2e 100%); +} +a.woo-sc-button.red:hover { + background: #d20000; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #e53e3e),color-stop(1, #ca1616)); + background: -moz-linear-gradient(center top,#e53e3e 20%,#ca1616 100%); +} + +a.woo-sc-button.orange { + border-color: #af7440; border-bottom-color: #9a5420; background-color: #d76b23; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #e88e52),color-stop(1, #cf6e2e)); + background: -moz-linear-gradient(center top,#e88e52 20%,#cf6e2e 100%); +} +a.woo-sc-button.orange:hover { + background: #d25e00; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #e57d3e),color-stop(1, #ca5116)); + background: -moz-linear-gradient(center top,#e57d3e 20%,#ca5116 100%); +} + +a.woo-sc-button.green { + border-color: #87bf00; border-bottom-color: #7ca122; background-color: #8dc11e; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #ace53e),color-stop(1, #8dca16)); + background: -moz-linear-gradient(center top,#ace53e 20%,#6bca16 100%); +} +a.woo-sc-button.green:hover { + background: #87c000; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #a0d53a),color-stop(1, #60b513)); + background: -moz-linear-gradient(center top,#a0d53a 20%,#60b513 100%); +} + +a.woo-sc-button.aqua { + border-color: #40af96; border-bottom-color: #209a82; background-color: #23d7af; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #52e8c6),color-stop(1, #2ecfab)); + background: -moz-linear-gradient(center top,#52e8c6 20%,#2ecfab 100%); +} +a.woo-sc-button.aqua:hover { + background: #00d2a8; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #3ee5c0),color-stop(1, #16ca9e)); + background: -moz-linear-gradient(center top,#3ee5c0 20%,#16ca9e 100%); +} + +a.woo-sc-button.teal { + border-color: #23a6d6; border-bottom-color: #20799a; background-color: #23abd7; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #52c3e8),color-stop(1, #2eabcf)); + background: -moz-linear-gradient(center top,#52c3e8 20%,#2eabcf 100%); +} +a.woo-sc-button.teal:hover { + background: #009ed2; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #3ebce5),color-stop(1, #16a2ca)); + background: -moz-linear-gradient(center top,#3ebce5 20%,#16a2ca 100%); +} + +a.woo-sc-button.purple { + border-color: #234dd6; border-bottom-color: #20489a; background-color: #2356d7; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #526ee8),color-stop(1, #2e58cf)); + background: -moz-linear-gradient(center top,#526ee8 20%,#2e58cf 100%); +} +a.woo-sc-button.purple:hover { + background: #0036d2; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #3e5ae5),color-stop(1, #1638ca)); + background: -moz-linear-gradient(center top,#3e5ae5 20%,#1638ca 100%); +} + +a.woo-sc-button.pink { + border-color: #d623cb; border-bottom-color: #9a2096; background-color: #d723d5; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #e852e6),color-stop(1, #cd2ecf)); + background: -moz-linear-gradient(center top,#e852e6 20%,#cd2ecf 100%); +} +a.woo-sc-button.pink:hover { + background: #bc00d2; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #c83ee5),color-stop(1, #ae16ca)); + background: -moz-linear-gradient(center top,#c83ee5 20%,#ae16ca 100%); +} + +a.woo-sc-button.silver { + color: #444 !important; + text-shadow:0 1px #fff; + border-color: #bbb; border-bottom-color: #999; background-color: #d8d8d8; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #e9e9e9),color-stop(1, #ccc)); + background: -moz-linear-gradient(center top,#e9e9e9 20%,#ccc 100%); +} +a.woo-sc-button.silver:hover { + background: #ccc; + background: -webkit-gradient(linear,left top,left bottom,color-stop(.2, #e0e0e0),color-stop(1, #bebebe)); + background: -moz-linear-gradient(center top,#e0e0e0 20%,#bebebe 100%); +} + + +/*-------------------------------------------------------------------------------------------*/ +/* 3. Columns */ +/*-------------------------------------------------------------------------------------------*/ +.twocol-one{width:48%;} +.threecol-one{width:30.66%;} +.threecol-two{width:65.33%;} +.fourcol-one{width:22%;} +.fourcol-two{width:48%;} +.fourcol-three{width:74%;} +.fivecol-one{width:16.8%;} +.fivecol-two{width:37.6%;} +.fivecol-three{width:58.4%;} +.fivecol-four{width:67.2%;} +.sixcol-one{width:13.33%;} +.sixcol-two{width:30.66%;} +.sixcol-three{width:47.99%;} +.sixcol-four{width:65.33%;} +.sixcol-five{width:82.67%;} +.twocol-one,.threecol-one,.threecol-two,.fourcol-one,.fourcol-two,.fourcol-three,.fivecol-one,.fivecol-two,.fivecol-three,.fivecol-four,.sixcol-one,.sixcol-two,.sixcol-three,.sixcol-four,.sixcol-five{float:left;margin-right:4%;position:relative;} +.last{clear:right;margin-right:0 !important;} + + +/*-------------------------------------------------------------------------------------------*/ +/* 4. Tweetmeme */ +/*-------------------------------------------------------------------------------------------*/ +.woo-tweetmeme.left { margin:0 1.5em 1.5em 0; float:left; } +.woo-tweetmeme.none { margin:0 0 1.5em 0; } +.woo-tweetmeme.right { margin:0 0 1.5em 1.5em; float:right; } + +/*-------------------------------------------------------------------------------------------*/ +/* 5. Twitter */ +/*-------------------------------------------------------------------------------------------*/ +.woo-sc-twitter.left { margin:0 1.5em 1.5em 0; float:left; } +.woo-sc-twitter.none { margin:0 0 1.5em 0; } +.woo-sc-twitter.right { margin:0 0 1.5em 1.5em; float:right; } + +/*-------------------------------------------------------------------------------------------*/ +/* 6. Digg */ +/*-------------------------------------------------------------------------------------------*/ +.woo-digg.left { margin:0 1.5em 1.5em 0; float:left; } +.woo-digg.none { margin:0 0 1.5em 0; } +.woo-digg.right { margin:0 0 1.5em 1.5em; float:right; } + +/*-------------------------------------------------------------------------------------------*/ +/* 7. Related posts */ +/*-------------------------------------------------------------------------------------------*/ +.woo-sc-related-posts .thumbnail { float:left; margin:0 1em 1em 0;} +.woo-sc-related-posts li { clear:both; } + +/*-------------------------------------------------------------------------------------------*/ +/* 8. Horizontal Rule */ +/*-------------------------------------------------------------------------------------------*/ +.woo-sc-hr { border-bottom:1px solid #e6e6e6; } +.woo-sc-hr, .woo-sc-divider { clear:both; display:block; margin-bottom:20px; padding-top:20px; width:100%; } +.woo-sc-divider.flat { padding:0; margin:0; } + +/*-------------------------------------------------------------------------------------------*/ +/* 9. Quote */ +/*-------------------------------------------------------------------------------------------*/ +.woo-sc-quote p { margin: 1em 20px; padding: 0 0 0 55px; background: url(../images/quote.png) no-repeat 0 3px; font-family: serif; font-size: 1.2em; font-style: italic; color:#777; min-height: 32px; } +.woo-sc-quote.left { float:left; width:30%;} +.woo-sc-quote.right { float:right; width:30%;} +.woo-sc-quote.boxed { background: #f5f5f5; border-radius:6px;-moz-border-radius:6px;-webkit-border-radius:6px;} +.woo-sc-quote.boxed.left { margin: 0 1.5em 1em 0;} +.woo-sc-quote.boxed.right { margin: 0 0 1em 1.5em;} + +/*-------------------------------------------------------------------------------------------*/ +/* 10. Icon Links */ +/*-------------------------------------------------------------------------------------------*/ +.woo-sc-ilink { padding:0 0.3em; } +.woo-sc-ilink a { padding-left:20px; text-decoration: underline; display: inline-block; } +.woo-sc-ilink a:hover { text-decoration: none; } +.woo-sc-ilink .download { background: url(../images/ico-download.png) no-repeat left 40%; } +.woo-sc-ilink .tick { background: url(../images/ico-tick.png) no-repeat left 40%; } +.woo-sc-ilink .info { background: url(../images/ico-info.png) no-repeat left 40%; } +.woo-sc-ilink .note { background: url(../images/ico-note.png) no-repeat left 40%; } +.woo-sc-ilink .alert { background: url(../images/ico-alert.png) no-repeat left 40%; } + +/*-------------------------------------------------------------------------------------------*/ +/* 11. Facebook */ +/*-------------------------------------------------------------------------------------------*/ +.woo-fbshare.left { margin:0 1.5em 1.5em 0; float:left; } +.woo-fbshare.none { margin:0 0 1.5em 0; } +.woo-fbshare.right { margin:0 0 1.5em 1.5em; float:right; } + +.woo-fblike.left { margin:0 1.5em 1.5em 0; float:left; } +.woo-fblike.none { margin:0 0 1.5em 0; } +.woo-fblike.right { margin:0 0 1.5em 1.5em; float:right; } + +/*-------------------------------------------------------------------------------------------*/ +/* 12. Contact Form */ +/*-------------------------------------------------------------------------------------------*/ + +.contact-form .screenReader { left: -9999px; position: absolute; top: -9999px; } +.contact-form .forms {float:left;list-style:none;width:100%;margin:10px 0 0;} +.contact-form .forms p {clear:both;float:left;margin-bottom:18px;position:relative;width:100%} +.contact-form .forms label{cursor:pointer;display:block;float:left;font-weight:700;padding-right:20px;width:100px;} +.contact-form .forms input.txt{width:214px;} +.contact-form .forms input#sendCopy{border:none;} +.contact-form .forms textarea{height:300px;width:400px;} +.contact-form .forms .error{font-size:12px;display:block;margin-left:120px;color:red;} +.contact-form .forms .textarea .error{display:block; margin-left:120px} +.contact-form .forms .screenReader{margin-bottom:0;} +.contact-form .forms .buttons .submit{margin: 15px 0 0 120px; cursor:pointer; } +.contact-form .forms .inline input{width:auto;margin-left:120px;} +.contact-form .forms .inline label{display:inline;float:none;width:auto;} +.entry .contact-form ol.forms li { list-style: none; } /* Added to accomodate the contact form shortcode */ + +.contact-form .submit { + display: inline-block; + margin: 5px; + padding: 3px 13px; + border: 1px solid #4081af; + border-bottom-color: #20559a; + color: white !important; + text-align: center; + text-shadow: 0 -1px 0 hsla(0,0%,0%,.3); + text-decoration: none; + + /*Border radius*/ + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; + + /*Background*/ + background: #237fd7; /*Fallback*/ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(.2, #52a8e8), + color-stop(1, #2e76cf) + ); + background: -moz-linear-gradient( + center top, + #52a8e8 20%, + #2e76cf 100% + ); + + /*Box shadow*/ + -webkit-box-shadow: inset 0 1px 0 hsla(0,100%,100%,.3) /*Top*/, + inset 0 0 2px hsla(0,100%,100%,.3) /*Shine*/, + 0 1px 2px hsla(0, 0%, 0%, .29) /*Shadow*/; + -moz-box-shadow: inset 0 1px 0 hsla(0,100%,100%,.3) /*Top*/, + inset 0 0 2px hsla(0,100%,100%,.3) /*Shine*/, + 0 1px 2px hsla(0, 0%, 0%, .29) /*Shadow*/; + box-shadow: inset 0 1px 0 hsla(0,100%,100%,.3) /*Top*/, + inset 0 0 2px hsla(0,100%,100%,.3) /*Shine*/, + 0 1px 2px hsla(0, 0%, 0%, .29) /*Shadow*/; +} + +.contact-form .submit:hover { + text-decoration: none !important; + /*Background*/ + background: #0073d2; /*Fallback*/ + background: -webkit-gradient( + linear, + left top, + left bottom, + color-stop(.2, #3e9ee5), + color-stop(1, #1666ca) + ); + background: -moz-linear-gradient( + center top, + #3e9ee5 20%, + #1666ca 100% + ); +} + +/*-------------------------------------------------------------------------------------------*/ +/* 13. Tabber */ +/*-------------------------------------------------------------------------------------------*/ + +.shortcode-tabs { background:#f0f0f0; background:rgba(0,0,0,.05); clear: both; height:auto; display: block; padding:5px; margin-bottom:30px; -moz-border-radius:3px; -webkit-border-radius:3px; border-radius:3px; } +.shortcode-tabs ul.tab_titles { padding:0px; background:none; border:none; margin:0;} +.shortcode-tabs ul.tab_titles li.nav-tab { background:none; padding:0; float: left; display:inline; color: #ffffff; margin:0px; cursor: pointer; } +.shortcode-tabs ul.tab_titles li.nav-tab.ui-tabs-selected a, .shortcode-tabs ul.tab_titles li.nav-tab a:hover { background:#fff; text-decoration:none; } +.shortcode-tabs ul.tab_titles li.nav-tab a { color:#777; display: block;float: left;padding: 8px; text-transform:uppercase; font:11px/18px sans-serif; } +.shortcode-tabs ul.tab_titles li.nav-tab.ui-tabs-selected a, .shortcode-tabs ul.tab_titles li.nav-tab a:hover { -moz-border-radius-topright:3px; -moz-border-radius-topleft:3px;-webkit-border-top-right-radius: 3px; -webkit-border-top-left-radius:3px; border-top-right-radius:3px; border-top-left-radius:3px; } +.shortcode-tabs .tab { background:#fff; padding:10px; text-align: left; clear: both; } +.shortcode-tabs .tab li.nav-tab { background:#fff; } +.shortcode-tabs .tab ul.tab_titles { margin:0; border: 1px solid #e6e6e6; border-width:1px 0 1px 0; } +.shortcode-tabs .tab li.nav-tab { border:1px solid #e6e6e6; border-width:0 1px 1px 1px; padding:10px; } +.shortcode-tabs .tab li.nav-tab a { color:#555; font:bold 12px/18px sans-serif; } +.shortcode-tabs .tab a:hover {} +.shortcode-tabs .ui-tabs-hide { display: none; } + +/*-------------------------------------------------------------------------------------------*/ +/* -13.1 Tabber Alternate Style - Boxed */ +/*-------------------------------------------------------------------------------------------*/ + +.shortcode-tabs.boxed { background: #FFFFFF; } + .shortcode-tabs.boxed ul.tab_titles { clear: both; float: left; background:none; border:none; border-left: 1px solid #EBEBEB; margin-bottom: 0px; position: relative; z-index: 2; } + .shortcode-tabs.boxed ul.tab_titles li { background:none; padding:0; border-top: 1px solid #EBEBEB; border-right: 1px solid #EBEBEB; } + .shortcode-tabs.boxed ul.tab_titles li.ui-state-active { border-bottom: 1px solid #FFFFFF; } + .shortcode-tabs.boxed .tab { border: 1px solid #EBEBEB; top: -2px; position: relative; z-index: 1; } + +/*-------------------------------------------------------------------------------------------*/ +/* -13.2 Tabber Alternate Style - Vertical */ +/*-------------------------------------------------------------------------------------------*/ + +.shortcode-tabs.vertical { background: #FFFFFF; } + .shortcode-tabs.vertical .tab_header { border: 1px solid #F0F0F0; border-bottom: 0px; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; width: 25%; float: left; margin-bottom: -5px; color:#555; font:bold 12px/18px sans-serif; } + .shortcode-tabs.vertical .tab_header { + + /* Gradient Background */ + background: #f5f5f5; + background: -moz-linear-gradient(100% 100% 90deg, #f5f5f5, #fff); + background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#f5f5f5)); + + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + -moz-border-radius-bottomright: 0px; + -moz-border-radius-bottomleft: 0px; + -webkit-border-bottom-left-radius: 0px; + -webkit-border-bottom-right-radius: 0px; + + } + .shortcode-tabs.vertical .tab_header span { display: block; padding: 8px 8px 12px 8px; border: 1px solid #EBEBEB; } + .shortcode-tabs.vertical ul.tab_titles { clear: left; float: left; background:none; border: 1px solid #F0F0F0; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; margin-bottom: 0px; position: relative; z-index: 2; width: 25%; } + .shortcode-tabs.vertical ul.tab_titles.has_title { border-top: 0px !important; margin-top: 5px; } + .shortcode-tabs.vertical ul.tab_titles.has_title { + + border-top-left-radius: 0px; + border-top-right-radius: 0px; + -moz-border-radius-topright: 0px; + -moz-border-radius-topkeft: 0px; + -webkit-border-top-left-radius: 0px; + -webkit-border-top-right-radius: 0px; + + } + .shortcode-tabs.vertical ul.tab_titles li { clear: both; background:none; padding:0; border-bottom: 1px solid #EBEBEB; border-left: 1px solid #EBEBEB; border-right: 1px solid #EBEBEB; display: block !important; float: none !important; } + .shortcode-tabs.vertical ul.tab_titles li.ui-state-active {} + .shortcode-tabs.vertical ul.tab_titles li.ui-state-active a { background: #F0F0F0; background: rgba(0,0,0,.05); } + .shortcode-tabs.vertical ul.tab_titles li a:link { display: block; float: none !important; } + .shortcode-tabs.vertical ul.tab_titles li a:hover { background: #F0F0F0; background: rgba(0,0,0,.05); } + .shortcode-tabs.vertical .tab { clear: right !important; top: 5px; position: relative; z-index: 1; margin-left: 30%; padding: 0px; } + +/*-------------------------------------------------------------------------------------------*/ +/* 14. Dropcap */ +/*-------------------------------------------------------------------------------------------*/ + +span.dropcap { font-size: 300%; font-weight: bold; float: left; position: relative; margin:5px 7px 0 0; line-height: 0.7em; } + +/*-------------------------------------------------------------------------------------------*/ +/* 15. Content Toggle */ +/*-------------------------------------------------------------------------------------------*/ + +.shortcode-toggle { margin: 0 0 1.2em;} +.shortcode-toggle h4 {margin: 0;} +.shortcode-toggle h4 a { display: block; padding: 3px 0 3px 10px; background: #f3f3f3 url(../images/shortcode-toggle-close.png) no-repeat 99% center; } +.shortcode-toggle.closed h4 a { background-image: url(../images/shortcode-toggle-open.png); } +.shortcode-toggle .toggle-content { padding: 10px 10px; background: #f9f9f9; } +.shortcode-toggle.closed .toggle-content, .shortcode-toggle .more-text.closed { display: none; } +.shortcode-toggle .more-text.open { display: block; } +.shortcode-toggle.border { border: 1px solid #EBEBEB; } + +/*-------------------------------------------------------------------------------------------*/ +/* -15.1 Content Toggle Alternate Style - White */ +/*-------------------------------------------------------------------------------------------*/ + +.shortcode-toggle.white h4 a { background-color: #FFFFFF; } +.shortcode-toggle.white .toggle-content { background-color: #FFFFFF; } + +/*-------------------------------------------------------------------------------------------*/ +/* 16. Highlight and Abbreviation */ +/*-------------------------------------------------------------------------------------------*/ + +span.shortcode-highlight { background: #FFFFAA; padding: 3px 3px 1px; } + +abbr { border-bottom: 1px dashed #999999; cursor: help; } + +/*-------------------------------------------------------------------------------------------*/ +/* 17. List Styles - Unordered List */ +/*-------------------------------------------------------------------------------------------*/ + +.entry .shortcode-unorderedlist ul li, .shortcode-unorderedlist ul li, .entry .shortcode-unorderedlist ul li ul, .shortcode-unorderedlist ul li ul { + list-style-type: none; + padding-left:25px; + background: url() no-repeat scroll left top; +} + +.entry .shortcode-unorderedlist.tick ul li, .shortcode-unorderedlist.tick ul li { background: url(../images/shortcode-tick.png) no-repeat left top; } +.entry .shortcode-unorderedlist.red-x ul li, .shortcode-unorderedlist.red-x ul li { background: url(../images/shortcode-red-x.png) no-repeat left top; } +.entry .shortcode-unorderedlist.bullet ul li, .shortcode-unorderedlist.bullet ul li { background: url(../images/shortcode-bullet.png) no-repeat left top; } +.entry .shortcode-unorderedlist.green-dot ul li, .shortcode-unorderedlist.green-dot ul li { background: url(../images/shortcode-green-dot.png) no-repeat left top; } +.entry .shortcode-unorderedlist.arrow ul li, .shortcode-unorderedlist.arrow ul li { background: url(../images/shortcode-arrow.png) no-repeat left top; } +.entry .shortcode-unorderedlist.star ul li, .shortcode-unorderedlist.star ul li { background: url(../images/shortcode-star.png) no-repeat left top; } + +/*-------------------------------------------------------------------------------------------*/ +/* 18. List Styles - Ordered List */ +/*-------------------------------------------------------------------------------------------*/ + +.entry .shortcode-orderedlist ol li, .entry .shortcode-orderedlist ol li ol, .shortcode-orderedlist ol li { + list-style-type: none; + margin-left: 25px; + background: url() no-repeat scroll left top; +} + +.entry .shortcode-orderedlist.armenian ol li, .shortcode-orderedlist.armenian ol li { list-style-type: armenian; } +.entry .shortcode-orderedlist.decimal ol li, .shortcode-orderedlist.decimal ol li { list-style-type: decimal; } +.entry .shortcode-orderedlist.decimal-leading-zero ol li, .shortcode-orderedlist.decimal-leading-zero ol li { list-style-type: decimal-leading-zero; } +.entry .shortcode-orderedlist.georgian ol li, .shortcode-orderedlist.georgian ol li { list-style-type: georgian; } +.entry .shortcode-orderedlist.lower-alpha ol li, .shortcode-orderedlist.lower-alpha ol li { list-style-type: lower-alpha; } +.entry .shortcode-orderedlist.lower-greek ol li, .shortcode-orderedlist.lower-greek ol li { list-style-type: lower-greek; } +.entry .shortcode-orderedlist.lower-latin ol li, .shortcode-orderedlist.lower-latin ol li { list-style-type: lower-latin; } +.entry .shortcode-orderedlist.lower-roman ol li, .shortcode-orderedlist.lower-roman ol li { list-style-type: lower-roman; } +.entry .shortcode-orderedlist.upper-alpha ol li, .shortcode-orderedlist.upper-alpha ol li { list-style-type: upper-alpha; } +.entry .shortcode-orderedlist.upper-latin ol li, .shortcode-orderedlist.upper-latin ol li { list-style-type: upper-latin; } +.entry .shortcode-orderedlist.upper-roman ol li, .shortcode-orderedlist.upper-roman ol li { list-style-type: upper-roman; } + +/*-------------------------------------------------------------------------------------------*/ +/* 19. Social Icon */ +/*-------------------------------------------------------------------------------------------*/ + +img.social-icon { border: none; } \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/css/tumblog.css b/src/wp-content/themes/bloggingstream/functions/css/tumblog.css new file mode 100644 index 00000000..9a25114b --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/css/tumblog.css @@ -0,0 +1,146 @@ +/* +* Tumblog CSS +*/ + +/* Editor Styling +----------------------------------*/ + +#tumblog-menu { margin: 10px 0 0; padding: 0 0 0 0; } +#tumblog-menu a { margin: 0 5px 5px 0; background-color: #f1f1f1!important; border:1px solid #dcdcdc; line-height: 40px; padding: 6px 10px 6px 0; -moz-border-radius-bottomleft:4px; -moz-border-radius-bottomright:4px; -moz-border-radius-topleft:4px; -moz-border-radius-topright:4px; } +#tumblog-menu a:hover { background-color: #e7e7e7!important; } +#tumblog-menu #articles-menu-button { padding-left: 33px; background: url(../images/btn-tumblog-note.png) no-repeat 10px center; } +#tumblog-menu #images-menu-button { padding-left: 39px; background: url(../images/btn-tumblog-image.png) no-repeat 10px center; } +#tumblog-menu #links-menu-button { padding-left: 44px; background: url(../images/btn-tumblog-link.png) no-repeat 10px center; } +#tumblog-menu #audio-menu-button { padding-left: 28px; background: url(../images/btn-tumblog-audio.png) no-repeat 10px center; } +#tumblog-menu #videos-menu-button { padding-left: 36px; background: url(../images/btn-tumblog-video.png) no-repeat 10px center; } +#tumblog-menu #quotes-menu-button { padding-left: 41px; background: url(../images/btn-tumblog-quote.png) no-repeat 10px center; } +#tumblog-menu #chat-menu-button { padding-left: 26px; display: none; } + +#tumblog-post { position: relative; } +#tumblog-post h4 { font-family: "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif; font-weight: bold; } +#article-fields, #video-fields, #image-fields, #link-fields, #audio-fields, #quote-fields, #tag-fields { margin: 15px 0 0 0; } +#article-fields input, #video-fields input, #image-fields input, #link-fields input, #audio-fields input, #quote-fields input, +#article-fields textarea, #video-fields textarea, #image-fields textarea, #link-fields textarea, #audio-fields textarea, #quote-fields textarea, #tag-fields input { +margin: 4px 0 13px 0; cursor: pointer; +-moz-border-radius-bottomleft:4px; +-moz-border-radius-bottomright:4px; +-moz-border-radius-topleft:4px; +-moz-border-radius-topright:4px; border: 1px solid #DFDFDF!important; +width: 100%; } + +#article-fields input, #video-fields input, #image-fields input, #link-fields input, #audio-fields input, #quote-fields input, #tag-fields input { padding-top: 6px; padding-bottom: 3px; } + +#tumblog-post h4 label { padding: 0 20px 0 0; } +#tumblog-post h4 #image-url-button, #tumblog-post h4 #image-upload-button, #tumblog-post h4 #audio-url-button, #tumblog-post h4 #audio-upload-button { padding: 0 0 0 20px; font-family: Georgia, serif; font-style: italic; font-weight: normal;} + +#ajax-loader { position: absolute; top: 10px; right: 10px; } +#tumblog-post .error { display: block; padding-top: 8px; padding-bottom: 8px; font-weight: bold; } +#tumblog-post .success { -moz-border-radius-bottomleft:3px; +-moz-border-radius-bottomright:3px; +-moz-border-radius-topleft:3px; +-moz-border-radius-topright:3px; background-color: #c5f0bf; border: 1px solid #2b931d; display: block; padding-left: 10px; padding-top: 8px; padding-bottom: 8px; font-weight: bold; } + +#content-fields { margin: 0 0 10px 0; } + +#image_upload_button, #audio_upload_button { +cursor: pointer!important; width: 200px!important; +} + +.hide-fields { +display: none; +} + +#quicktags { +background-color:#DFDFDF; +border-color:#DFDFDF; +} +#ed_toolbar input { +border-color:#C3C3C3; +} +#ed_toolbar input:hover { +-moz-background-clip:border; +-moz-background-inline-policy:continuous; +-moz-background-origin:padding; +background:#DDDDDD none repeat scroll 0 0; +border-color:#AAAAAA; +} +#content-fields .wp_themeSkin .mceStatusbar { +border-color:#EDEDED; +} +#content-fields #edButtonPreview, #content-fields #edButtonHTML { +background-color:#F1F1F1; +border-color:#DFDFDF; +color:#999999; +} +#content-fields #editor-toolbar .active { +background-color:#E9E9E9; +border-bottom-color:#E9E9E9; +color:#333333; +} + +#content-fields #add-media-button { +float:right; +margin:7px 0 0; +position:relative; +right:10px; +} +#content-fields #editor-toolbar { +height:30px; +} +.wp_themeSkin tr.mceFirst td.mceToolbar { +border-style:none none solid; +border-width:0 0 1px; +} +#edButtonPreview, #edButtonHTML { +-moz-border-radius-bottomleft:0; +-moz-border-radius-bottomright:0; +-moz-border-radius-topleft:3px; +-moz-border-radius-topright:3px; +border-style:solid; +border-width:1px; +cursor:pointer; +float:right; +height:18px; +margin:5px 5px 0 0; +padding:4px 5px 2px; +} +.js .theEditor { +color:white; +} +#content-fields #edButtonHTML { +margin-right:15px; +} +#media-buttons { +cursor:default; +padding:8px 8px 0; +} +#media-buttons a { +cursor:pointer; +padding:0 0 5px 10px; +} +#media-buttons img, #submitpost #ajax-loading { +vertical-align:middle; +} + +.tumblog-title { +-moz-border-radius-bottomleft:6px; +-moz-border-radius-bottomright:6px; +-moz-border-radius-topleft:6px; +-moz-border-radius-topright:6px; +border-style:solid; +border-width:1px; +font-size:1.7em; +outline-color:-moz-use-text-color; +outline-style:none; +outline-width:medium; +padding:3px 4px; +width:100%; +} + +.editorwidth { width:100% !important; } + +.hide-cat { display:none; } + +#advanced-options-toggle { float:right; cursor:pointer; } + +.tumblog-time { width:30px; } \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/functions-changelog.txt b/src/wp-content/themes/bloggingstream/functions/functions-changelog.txt new file mode 100644 index 00000000..0725fa88 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/functions-changelog.txt @@ -0,0 +1,1044 @@ +*** WooThemes Framework Changelog ** + +2011.05.21 - version 4.1.0 + * admin-functions.php - Added new Google Fonts. + * admin-interface.php - Solved bug where typography options were being set to 9px on all typography options. + * admin-functions.php - tweaked woo_image auto image tests, and vt_resize width checks + * admin-setup.php - changed $woo_options to get_option to work with older themes that don't load $woo_options + +2011.05.20 - version 4.0.9 + * admin-setup.php - removed notices from texttitle and tagline options if not set + +2011.05.12 - version 4.0.8 + * admin-functions.php - fixed get_theme_data() in woo_admin_bar_menu() + +2011.05.11 - version 4.0.7 + * admin-functions.php - added new google fonts + +2011.05.10 - version 4.0.6 + * admin-sbm.php - Fixed bug with taxonomy terms that have children not displaying the correct sidebar widgets. + +2011.05.09 - version 4.0.5 + * admin-shortcodes.php - Fixed warning message if no attributes are set in the contact form shortcode, as well as adding support for checkbox and radio button field types. + +2011.05.05 - version 4.0.4 + * admin-setup.php - Moved woo_load_textdomain() call to fire on "init". + * admin-custom-nav.php, + admin-custom.php, + admin-framework-settings.php, + admin-functions.php, + admin-interface.php, + admin-medialibrary-uploader.php, + admin-sbm.php, + admin-seo.php, + admin-setup.php, + admin-shortcodes.php, + admin-tumblog-quickpress.php - Code clean-up and consistency checks. Replaced calls to bloginfo( 'template_directory' ) and bloginfo( 'template_url' ) with get_template_directory_uri(). + +2011.05.04 - version 4.0.3 + * admin-interface.php - Fixed bug in save logic where arbitrary integers were being inserted into "Subscribe and Connect" text input fields. + * admin-setup.php - fixed bug where site description wasn't showing on older themes that don't have the new site description option. + +2011.05.03 - version 4.0.2 + * admin-interface.php - Make sure slashes are stripped from "text" field type values on save. + * admin-functions.php - Make sure slashes are stripped from all instances of the page title output (woo_title, wp_title and admin_title). + * admin-functions.php - Added generic "ie" body class to all Internet Explorer body classes, as well as an "ie9" body class for use with Internet Explorer 9. + * admin-shortcodes.php - Added optional CSS class field ("css") to the "tabs" shortcode. + * /shortcode-generator/shortcodes/tab.js - Updated "tab" shortcode generator with the new "css" field. + * admin-framework-settings.php - Added support to the exporter for values in "type" fields that are setup as arrays. + * admin-functions.php - vt_resize: Use set width from woo_image when returning image that hasn't been resized. Image will be stretched to fit. Fixes issues where image uploaded is smaller than width of slider etc. + +2011.05.02 - version 4.0.1 + * admin-functions.php - Added new Google webfonts. + +2011.04.25 - version 4.0.0 + * admin-init.php - Version bump. + * admin-setup.php - added option for tagline CSS output from options + +2011.04.25 - version 3.10.1 + * css/tumblog.css - Removed redundant Tumblog style. + +2011.04.20 - version 3.10.0 + * admin-shortcodes.php - Added optional excerpt length, with "read more" link options, to the content toggle shortcode. Added "Share via LinkedIn" shortcode. + * /js/shortcodes.js - Added logic for the excerpt "read more" link in the content toggle shortcode. + * /js/shortcode-generator/shortcodes/toggle.js - Added new shortcode attributes to content toggle shortcode generator screen. + * /js/shortcode-generator/js/dialog-js.php - Added defaultValue logic for text input fields on shortcode generator screens. + * /css/shortcodes.css - Added base CSS styles for the "more text" used if using the optional excerpt in the content toggle shortcode. + * /js/shortcode-generator/js/editor_plugin.js - Added "Share via LinkedIn" shortcode to the Generator menu. + * /js/shortcode-generator/preview-shortcode-external.php - Added custom action hook in the footer, to enable the loading of custom scripts without requiring wp_footer(). + +2011.04.18 - version 3.9.0 + * admin-seo.php - Added support for WordPress SEO by Yoast to WooSEO. + * admin-functions.php - Added support for WordPress SEO by Yoast to WooSEO. + * admin-hooks.php - Added context function and woo_*_atomic() functions for use in hooks, as well as implemented woo_do_atomic() in the various woo hooks. + * admin-functions.php - added new Google fonts + +2011.04.09 - version 3.8.2 + * admin-functions.php - added new google fonts + +2011.04.07 - version 3.8.1 + * admin-functions.php - Added filtering mechanism to woo_title() and adjusted woo_pagination() to always move the raw query string to the end of the pagination links. + +2011.03.30 - version 3.8.0 + * admin-framework-settings.php - Added options to disable WordPress Admin Bar and enable WooFramework admin bar enhancements. + * admin-functions.php - Logic to either disable the WordPress Admin Bar or add WooFramework enhanced navigation menu items. + +2011.03.28 - version 3.7.14 + * admin-shortcodes.php - Corrected new line characters in contact form shortcode. Added "rel" option to social icon shortcode. + * /js/shortcode-generator/shortcodes/social_icon.js - Added field for the "rel" option to the social icon shortcode generator. + +2011.03.18 - version 3.7.13 + * admin-init.php, admin-setup.php, admin-shortcodes.php - made all HEAD output neat + * admin-functions.php - added more google fonts + +2011.03.17 - version 3.7.12 + * admin-functions.php - modified vt_resize to not resize if the width and height of original image are smaller than resized area. + +2011.03.16 - version 3.7.11 + * admin-functions.php - added @ to omit PHP warning message in woo_custom_login_logo() + +2011.03.14 - version 3.7.10 + * admin-express-functions.php - upgraded to use post formats functionality + +2011.03.09 - version 3.7.09 + * admin-interface.php - changed wording on Reset Options button + +2011.03.05 - version 3.7.08 + * admin-shortcodes.php - Allow shortcodes to be added inside the "info box" shortcode. + * admin-sbm.php - Fixed "array_key_exists" warning message after resetting the Sidebar Manager. + +2011.03.02 - version 3.7.07 + * admin-functions.php - Added support for BuddyPress search to woo_pagination(). + * admin-tumblog-quickpress.php - Only load tumblog styles on dashboard + +2011.03.01 - version 3.7.06 + * admin-tumblog-quickpress.php - added additional editor handling + +2011.02.28 - version 3.7.05 + * admin-tumblog-quickpress.php - added safari editor fix + +2011.02.27 - version 3.7.04 + * admin-setup.php - moved woothemes_wp_head() content into seperate pluggable functions + +2011.02.26 - version 3.7.03 + * admin-sbm.php - Fixed conflict between custom page template-based and category-based sidebars. + * admin-sbm.php - Fixed Sidebar Manager reset functionality. + +2011.02.24 - version 3.7.02 + * admin-interface.php - removed deprecated tumblog functions + * admin-tumblog-quickpress.php - upgraded tumblog functions to use post formats functionality + * admin-express-functions-deprecated.php - created deprecated functions file + * admin-express-functions.php - upgraded to use post formats functionality + * /js/shortcode-generator/editor_plugin.js - Changed the method by which we detect the editor button icon. + * /js/shortcode-generator/js/dialog-js.php - Added fixes for supporting Windows-based web servers. + * admin-shortcodes.php - Added code to prevent the warning message in the shortcode preview for the custom typography shortcode. + +2011.02.23 - version 3.7.01 + * admin-functions.php - woo_image(): Added alt tag to custom field images (the_title) + +2011.02.22 - version 3.7.00 + * admin-functions.php - Added woo_pagination() and woo_breadcrumbs() functions. + * admin-shortcodes.php - Added optional tabber title to the tabber shortcode. + * /js/shortcode-generator/shortcodes/tab.js - Added "vertical" alternate style. + * /js/shortcode-generator/js/dialog-js.php - Increased total allowed tabs to 10 in the tabber controller in the shortcode generator. + * /css/shortcodes.css - Added "vertical" alternate style to the tabber shortcode. + + +2011.02.19 - version 3.6.09 + * admin-functions.php - fixed vt_resize() to not remove 1px if the image width is same as resize width + +2011.02.19 - version 3.6.08 + * admin-shortcodes.php - Changed "info box" shortcode to use DIV tag instead of P tag. Removed trailing slash on URLs in the "social icon" shortcode. + * css/shortcodes.css - Updated "info box" style to use DIV tag instead of P tag. + +2011.02.18 - version 3.6.07 + * admin-shortcodes.php - Added "nav-tab" class to tab navigation items in the tabber shortcode. + * js/shortcodes.js - Refined tabber JavaScript. + * css/shortcodes.css - Cleaned up tabber shortcode CSS to support nested unordered and ordered lists. + +2011.02.18 - version 3.6.06 + * admin-functions.php - Fixed bug where Twitter widget was intermittently generating incorrect links to tweets. + * admin-functions.php - added some more Google Fonts + +2011.02.17 - version 3.6.05 + * admin-sbm.php - Added functionality to display the category custom sidebar on single posts in that category in the Sidebar Manager. + * admin-sbm.php - Added a note explaining how the new "category sidebar on single posts" functionality works. + +2011.02.16 - version 3.6.04 + * admin-functions.php - Added fix for using custom post ID in woo_image(). + * admin-shortcodes.php - Added option to use pre-defined colour scheme in button shortcode, open in new window in social icon shortcode and tweaked options in fblike shortcode. + * /js/shortcode-generator/shortcodes/button.js - Added pre-defined colour scheme selection option. + * /js/shortcode-generator/shortcodes/fblike.js - Tweaked options to make sure all options display correctly. + * /js/shortcode-generator/shortcodes/social_icon.js - Added option to open the link in a new window. + * admin-framework-settings.php - Added Sidebar Manager data to the import/export function. + +2011.02.15 - version 3.6.03 + * admin-functions.php - vt_resize() added file_exists check + * admin-functions.php - fixed image placeholder to not show in_the_loop on singular pages + +2011.02.14 - version 3.6.02 + * admin-shortcodes.php - Added social_icon shortcode and restructured contact form shortcode to work within tabber. + * /js/shortcode-generator/shortcodes/social_icon.js - Generator controller for social_icon shortcode. + * /js/shortcode-generator/editor_plugin.js - Added link on the shortcode generator menu for the social_icon. + * /css/shortcodes.css - Adjusted contact form shortcode CSS to accommodate the new code structure. + * admin-functions.php - Tested Google Fonts and fixed several that weren't displaying. + +2011.02.11 - version 3.6.01 + * admin-functions.php - Fixed woo_twitter_script to include retweets + +2011.02.08 - version 3.6.00 + * admin-functions.php - Added support in woo_embed() for html_entity_decode. Fixed spelling mistake on "Kristi" Google Webfont. Fixed seo_follow meta custom field to switch depending on the default option. + * admin-shortcodes.php - New shortcodes ( Dropcap, Text highlight, Abbreviated text, Custom Typography (using Google Fonts), Alt-style support for the tabber, Content Toggle, Ordered and Unordered List Generators, with various alt styles for the bullets). + * admin-shortcode-generator.php - Enqueued colorpicker CSS and JavaScript files for use in the generator. + * admin-style.css - Fixed z-index issue in options screen. + * /css/shortcode-generator.css - Updated styling for shortcode generator. + * /css/shortcodes.css - Added CSS for new shortcodes. + * /images/shortcode-*.png - New images for unordered list style shortcode. + * /js/shortcode-generator/editor-plugin.js - Added additional shortcodes to menu, and new "skip lightbox" functionality for simple shortcodes. + * /js/shortcode-generator/preview-shortcode-external.php - Updated preview to include call to Google Fonts. + * /js/shortcode-generator/shortcodes/* - Added control files for new shortcodes. + * /js/shortcode-generator/js/dialog-js.php - Added additional form field controls. Integrated setup function for the colorpicker. + * /js/shortcodes.js - Added JavaScript for content toggle shortcode. + * admin-shortcodes.php - Refined and tested custom typography shortcode and font loader. + * /js/shortcode-generator/shortcodes/unordered_list.js - Refined functionality to remove list items textarea. + * /js/shortcode-generator/shortcodes/ordered_list.js - Refined functionality to remove list items textarea. + * /js/shortcode-generator/shortcodes/typography.js - Integrated colorpicker. + * /js/shortcode-generator/shortcodes/button.js - Integrated colorpicker. + +2011.02.07 - version 3.5.7 + * admin-shortcode-generator.php - Made shortcode icon available to Authors + +2011.02.05 - version 3.5.6 + * admin-functions.php - Added new google fonts. Fixed issue with auto image thumbnails in related posts shortcode on single post page + +2011.02.02 - version 3.5.5 + * admin-functions.php - fixed woo_image using wrong image in WooTabs on single posts + +2011.02.02 - version 3.5.4 + * admin-framework-settings - commented out Font Stack Beta since not functioning properly and Google Fonts better alternative than non-websafe fonts. + * admin-functions.php - fixed woo_image using wrong image in WooTabs on single posts + * admin-interface.php - fixed SBM hide option + +2011.02.01 - version 3.5.3 + * admin-custom.php - SEO fix for Content Builder. + * admin-tumblog-quickpress.php - Safari dashboard widget editor bugfix. + +2011.01.31 - version 3.5.2 + * admin-functions.php - added new function woo_get_youtube_video_image() to work with new YouTube iframe embed code + * css/admin-shortcodes.css - fixed sixcol_four width + +2011.01.28 - version 3.5.1 + * admin-functions.php - woo_image() added native resizing to placeholder image if it is enabled. Made sure auto thumbs don't show on single posts. + * admin-framework-settings.php - removed reset button as it doesn't work. + * admin-shortcodes.php - Updated tabber shortcode CSS class to "shortcode-tabs". Added optional "URL" field to fbshare shortcode. + * /includes/css/shortcodes.css - Updated tabber CSS class. Added "clear" to tabber container CSS. + * /includes/js/shortcodes.js - Updated tabber JavaScript to reflect new CSS class. + * /includes/js/shortcode-generator/shortcodes/fbshare.js - Controller for the "fbshare" shortcode in the generator. + * /includes/js/shortcode-generator/editor_plugin.js - Added menu item for the "fbshare" shortcode to the generator menu. + +2011.01.21 - version 3.5.0 + * /admin-shortcode-generator.php - Functionality for the shortcode generator. + * /admin-init.php - Require functionality for the shortcode generator. + * /js/shortcode-generator/* - JavaScript and related functionality for the shortcode generator. + * /css/shortcode-generator.css - CSS styles for the shortcode generator dialog box. + * /images/shortcode-icon.png - Icon for the shortcode button on the tinyMCE editor. + * admin-tumblog-quickpress.php - fix to make JS used for tumblog only load in admin area, not in theme. + * admin-shortcodes.php - Added tabber shortcode and enqueue function for shortcodes.js file. + * includes/js/shortcodes.js - Added JavaScript for use in shortcodes. + * includes/css/shortcodes.css - Added styling for contact form shortcode. + +2011.01.20 - version 3.4.14 + * admin-functions.php - output proper alt tag woo_image() + +2011.01.18 - version 3.4.13 + * /js/woo-medialibrary-uploader.js - The "Link URL" field is no longer required to have a value (prevent white screen error). + * admin-custom.php - Removed "mysql_real_escape_string()" calls in order to debug and resolve several issues with custom field data on save. + +2011.01.13 - version 3.4.12 + * admin-functions.php - Added framework settings function for setting custom logo on WP login page. Added function_exists to a few functions. + * admin-framework-settings.php, admin-seo.php - Cleaned up options and added a few more disable menu item options. Added icons. + +2011.01.11 - version 3.4.11 + * admin-functions.php - SEO: Added custom setting in post/page for setting robots to "noindex" + +2011.01.11 - version 3.4.10 + * admin-functions.php - added new google fonts http://code.google.com/webfonts?subset=latin&sort=added + * admin-shortcodes.php - added option to open button shortcode link in new window + +2011.01.10 - version 3.4.09 + * admin-framework-settings.php - Fixed bug in export code generator. + +2011.01.08 - version 3.4.08 + * admin-interface.php - Fixed nonce bug with Font Stacks (beta). + +2011.01.07 - version 3.4.07 + * admin-functions.php - Fixed Coda Google Font + +2011.01.03 - version 3.4.06 + * admin-functions.php - Added woo_encoding_convert() + * admin-custom-nav.php - Removed woo_encoding_convert() + +2010.12.31 - version 3.4.05 + * admin-functions.php - Added 1 new google font + +2010.12.30 - version 3.4.04 + * admin-custom.php - added stripslashes to textarea custom field + +2010.12.28 - version 3.4.03 + * admin-shortcodes.php - added extra height to fblike button with showfaces set to true + +2010.12.26 - version 3.4.02 + * admin-functions.php - Added support for encoding certain HTML entities in SEO META description field, for successful W3C validation. + +2010.12.23 - version 3.4.01 + * admin-init.php - check if WooNav option is enabled in framework settings + * admin-interface.php - removed old WooNav check + +2010.12.20 - version 3.4.00 + * admin-init.php - added content builder support + * admin-custom.php - added content builder support + * admin-interface.php - added content builder support + * admin-style.css - added content builder support + * /images/option-icon-search.png - added image icon + * /images/option-icon-favorite.png - added image icon + * /images/option-icon-upload.png - added image icon + * /images/option-icon-listing.png - added image icon + +2010.12.18 - version 3.3.08 + * admin-functions.php, admin-interface.php - Improved Google Fonts functions. Added more fonts. + +2010.12.15 - version 3.3.07 + * admin-custom.php - Resolved issue with saving of custom meta fields on existing posts. + +2010.12.11 - version 3.3.06 + * admin-functions.php, admin-interface.php - Added new google fonts + +2010.12.11 - version 3.3.05 + * admin-medialibrary-uploader.php - Fixed bug in Media Library uploader on post admin pages. + +2010.12.10 - version 3.3.04 + * admin-functions.php - updated framework updater page styling and copy. + +2010.12.10 - version 3.3.03 + * admin-setup.php - fixed alt stylesheet bug + +2010.12.09 - version 3.3.02 + * admin-functions.php - Fixed issue with html_entity_decode() function in PHP4. + +2010.12.08 - version 3.3.01 + * admin-custom.php - Sanitised $_REQUESTs. + * admin-framework-settings.php - Sanitised $_REQUESTs. Added nonce (carries over through other options pages). + * admin-functions.php - Sanitised $_REQUESTs. Sanitised woo_style_path() GET/POST variables. + * admin-interface.php - Sanitised $_REQUESTs. Added nonce to save and reset functions. + * admin-medialibrary-uploader.php - Sanitised $_REQUESTs. + * admin-sbm.php - Sanitised $_REQUESTs and $_POST'ed values. + * admin-seo.php - Sanitised $_REQUESTs. + * admin-setup.php - Sanitised $_REQUESTs. + * js/woo-scripts.js - Resolved JavaScript selector issue, causing label on image width/height fields to hide on save. + +2010.12.06 - version 3.3.00 + * admin-interface.php - removed Custom Navigation menu item, and added option to enable it in Framework Settings + * admin-framework-settings.php - removed Custom Navigation menu item, and added option to enable it in Framework Settings + * admin-functions.php - fix in woo_image for WPBundle post thumbnails + +2010.12.06 - version 3.2.13 + * admin-functions.php - woo_image links to full image if single post instead of natively resized WP Thumbnail + +2010.12.01 - version 3.2.12 + * js/woo-medialibrary-uploader.js - Added additional support for non-image files. + * admin-setup.php - added if function_exists to load_child_theme_textdomain + +2010.11.30 - version 3.2.11 + * admin-functions.php - fixed bug with native image resizer image width equal to specified width + +2010.11.29 - version 3.2.10 + * admin-sbm.php - Fixed bug in sidebar generation for post tags (test case: "video" tag). + * admin-shortcodes.php, css/shortcodes.css - added alert icon link + +2010.11.25 - version 3.2.09 + * admin-sbm.php - Added support for custom post types in the Sidebar Manager. + * admin-functions.php - added ie7 and ie6 classes to browser_body_class + +2010.11.23 - version 3.2.08 + * admin-functions.php - woo_image() native resize check and set width of image before resize to avoid error + +2010.11.22 - version 3.2.07 + * admin-sbm.php - Fixed bug in sidebar determination logic with archives and static posts page. Added logic to pull sidebar data from parent sidebar, instead of as static XHTML tags. + * admin-setup.php - added load_textdomain to look in /lang folder of parent theme and child theme + +2010.11.19 - version 3.2.06 + * admin-medialibrary-uploader.php - Fixed bug with standard values (std) logic. Removed preview if the file isn't an image. + * js/woo-medialibrary-uploader.js - Neatened up call to Media Library thickbox. Removed preview if the file isn't an image. + * admin-functions.php - Changed to using html_entity_decode() function on meta description to allow special characters (user request). + +2010.11.16 - version 3.2.05 + * admin-sbm.php - Resolved conflict between specific category and template hierarchy sidebars. + +2010.11.15 - version 3.2.04 + * admin-interface.php - made functions pluggable + * admin-functions.php - removed unused function (debug output) + * admin-framework-settings.php - removed unused function (debug output) + * admin-style.css - fixed position of screenshot + +2010.11.13 - version 3.2.03 + * admin-setup - added check for non-existing array in woo_head_css() + +2010.11.12 - version 3.2.02 + * admin-setup.php - improved/cleaned up code + * admin-theme-page.php - REMOVED FILE + * admin-functions.php - added Buy Themes page function + * admin-init.php - removed admin-theme-page.php require + * admin-init.php - Bumped to new version + * js/woo-medialibrary-uploader.js - Fixed bug with send_to_editor + +2010.11.10 - version 3.2.01 + * admin-functions.php - fixed update version checker + * admin-interface.php - added select box styling + * admin-style.css - added select box styling + * includes/js/woo-scripts.php - added select box styling + +2010.11.10 - version 3.2.00 + * admin-init.php - Updated framework version. Require the Media Library-driven uploader functions. + * admin-interface.php - Added support for the Media Library-driven uploader. + * admin-medialibrary-uploader.php - The functions for the Media Library-driven uploader. + * admin-style.css - Updated styles for Media Library-driven uploader. + * admin-custom.php - Updated styles for Media Library-driven uploader. + * js/woo-medialibrary-uploader.js - JavaScript code for the Media Library-driven uploader. + * admin-functions.php - updated woo_image 'url' function + +2010.11.09 - version 3.1.11 + * admin-functions.php - Improved logic with new native resize. Added option for Post URL ( 'url') to the link parameter + +2010.11.08 - version 3.1.10 + * admin-style.css - styling updates for options panel + * admin-shortcodes.php - Fixed fbshare url, added more params to fblike + * admin-functions.php - Added support for native resize of WP post thumbnails + * admin-setup.php - modified WP post thumbnail setup + +2010.11.04 - version 3.1.09 + * admin-tumblog-quickpress.php - Added handler for ajax date and time posting to allow correct values. + +2010.11.03 - version 3.1.08 + * admin-sbm.php - Added fix for custom taxonomies sbm frontend output. + +2010.11.02 - version 3.1.07 + * admin-functions.php - fixed html_entities in woo_meta (line 1529) + * admin-shortcodes.php - added facebook share button. added fourcol_two columns. + * css/shortcodes.css - column shortcode + +2010.11.01 - version 3.1.06 + * admin-style.css - Fixed SBM IE styling bugs + +2010.10.28 - version 3.1.05 + * admin-sbm.php - Added patch to jQuery for IE .live( 'submit') issue. + +2010.10.27 - version 3.1.04 + * admin-functions.php - updated the woo_get_fw_version() function with a new mothod + +2010.10.25 - version 3.1.03 + * admin-functions.php - added fallback to woo_title() if output is empty (CPT fallback) + * admin-functions.php - added "-" in search for youtube thumbnail video ID + * admin-functions.php - updated logic in woothemes_framework_update_page() + +2010.10.24 - version 3.1.02 + * admin-functions.php - added classes to woo_twitter_script() + +2010.10.21 - version 3.1.01 + * admin-functions.php - fix on YouTube thumbnail generation logic in woo_image() + +2010.10.21 - version 3.1.00 + * admin-interface.php - Added icon option to headings in option panel. + * admin-style.css - Added basic options icons. Tweaked options styling. + * /images/ - Added new basic options icons + +2010.10.21 - version 3.0.13 + * admin-functions.php - added automatic youtube thumbnails to woo_image + +2010.10.20 - version 3.0.12 + * admin-interface.php - added unit option to typography. + * admin-style.css - updated styling for typography. + +2010.10.18 - version 3.0.11 + * admin-custom.php - Removed code segment that check for empty fields for Custom Settings boxes + +2010.10.18 - version 3.0.10 + * admin-interface.php, admin-functions.php - Added new google fonts + +2010.10.12 - version 3.0.09 + * admin-sbm.php - Fixed a syntax error in the woo_active_sidebar() function. + +2010.10.11 - version 3.0.08 + * admin-functions.php - Removed Robots when third party SEO plugins are activated + +2010.10.08 - version 3.0.07 + * admin-interface.php - Removed all wpdb queries and replaced with alternative functions. + * admin-functions.php - Removed all wpdb queries and replaced with alternative functions. Removed "insert page" shortcode. + +2010.10.07 - version 3.0.06 + * admin-sbm.php - Bug fix regarding some categories and not returning data for creating sidebars. + * admin-functions.php - woo_image: removed force get_options + +2010.10.06 - version 3.0.05 + * admin-sbm.php - Added check for sidebars only being called with integers. + +2010.10.06 - version 3.0.04 + * admin-functions.php - fixed bug in woo_image where $single was always true + +2010.10.05 - version 3.0.03 + * admin-sbm.php - Added default parameter to the woo_sidebar() function. + +2010.10.04 - version 3.0.02 + * admin-interface.php - Added string builder logic. + * admin-style.css - Added styles for string builder + * admin-framework-settings.php - Added new Font Stack Builder option, + +2010.09.30 - version 3.0.01 + * admin-interface.php - Added reset function for SBM. + * admin-sbm.php - Added reset and error checking functions. + +2010.09.17 - version 3.0.00 + * admin-sbm.php - Added new files for Sidebar Manager + * admin-interface.php - Enabled the Sidebar Manager in the backend + * admin-style.css - Added CSS for new Sidebar Manager + * Added preliminary stack builder source. + +2010.09.14 - version 2.9.28 + * admin-functions.php - Added fix in woo_image to not apply WM Multisite url fix if external image url is sent through. Added crop alignment option to woo_image + +2010.09.14 - version 2.9.27 + * admin-functions.php - added alternative taxonomies to be added to the SEO keyword output. + +2010.09.13 - version 2.9.26 + * admin-interface.php - fixed time input masking + +2010.09.12 - version 2.9.25 + * css/shortcodes.css - revised boxes + * admin-shortcodes - revised boxes + +2010.09.10 - version 2.9.24 + * css/shortcodes.css - revised buttons + * admin-functions.php - bug fix: removed alt tag from anchor from woo_image if resizer off + +2010.09.10 - version 2.9.23 + * admin-shortcodes.php - Revised buttons, started with JS toggle + * css/shortcodes.css - revised buttons + +2010.09.09 - version 2.9.22 + * admin-functions.php - fixed woo_image to not show duplicate image in single post when grabbing image from post + +2010.09.07 - version 2.9.21 + * admin-setup.php - Fixed some logic with loading complex options from previously saved options. + * admin-express-functions.php - fixed iphone function bug for tumblog themes + * admin-interface.php - added handling for apostrophes in theme option drop downs + * admin-functions.php - removed "beta" warning from Update Framwork page + +2010.09.06 - version 2.9.20 + * admin-interface.php - added manual off for SBM until it's ready for realease. + * admin-custom.php - Added fix to constants with correct php syntax. + * admin-sbm.php - ADDED new functionality + +2010.09.03 - version 2.9.19 + * admin-interface.php - Fixed a undefined index php error. + +2010.09.01 - version 2.9.18 + * admin-shortcodes.php - Removed function to remove shortcodes from RSS feeds, as it strips WP shortcodes too. Fixed ilink icon parameter. + * admin-functions.php - changed str_ireplace to str_replace (php4) + +2010.09.01 - version 2.9.17 + * admin-shortcodes.php - added function to remove excessive paragraphs and linebreaks from shortcodes + +2010.08.31 - version 2.9.16 + * css/shortcodes.css - fixed styling for box shortcode to work properly on some older themes. New ilink styling + * admin-shortcodes.php - added new ilink shortcode + * admin-framework-settings.php - made the options panel output disabled by default + * admin-functions.php - made the options panel output disabled by default + +2010.08.30 = version 2.9.15 + * admin-interface.php - Added extra markup for SEO Character Counters + * admin-custom.php - Added Character counter script, and removed td tags outputs. Fixed some SEO show/hide functionality. + +2010.08.25 - version 2.9.14 + * admin-tumblog-quickpress.php - Checks for (and includes) iPhone app functionality for tumblog themes + * admin-express-functions.php - iPhone app functionality file added + +2010.08.24 - version 2.9.13 + * admin-tumblog-quickpress.php - Bug fix for tumblog dashboard widget + +2010.08.21 - version 2.9.12 + * admin-shortcodes.php - added icon links shortcode. Fixed box shortcode to take more input. Removed wpautop(). Remove Shortcode from RSS feed. + * css/shortcodes.css - new shortcode styling + +2010.08.21 - version 2.9.11 + * admin-shortcodes.php - added missing sixcol shortcodes + * css/shortcodes.css - added missing sixcol shortcodes + +2010.08.20 - version 2.9.10 + * admin-shortcodes.php - added quote shortcode + * css/shortcodes.css - added quote shortcode css + * images/quote.png - added quote.png + +2010.08.20 - version 2.9.09 + * admin-init.php - added require admin-shortcodes.php + * admin-shortcodes.php - ADDED - new file to hold shortcodes. Added HR/Divider and Columns shortcodes. + * admin-functions.php - removed shortcodes. Added ' to $_REQUEST[style] + * admin-setup.php - removed decode option function + +2010.08.18 - version 2.9.08 + * admin-framework-settings.php - Added remove generator meta tags option + * admin-init.php - Added remove generator meta tags option + +2010.08.17 - version 2.9.07 + * admin-setup.php - Enclosed string arguments. Bug Fix + * admin-functions.php - Added check for valid Taxonomy archive outputs in woo_title(); + * admin-interface.php - Removed unused tumbleblog upgrade code. + +2010.08.16 - version 2.9.06 + * admin-custom-nav.php - Added notice to users that they should use the WordPress 3.0.x Menu Management instead of WooNav. + +2010.08.15 - version 2.9.05 + * admin-functions.php - Fixed shortcodes.css to be included from parent theme, not child theme. + +2010.08.13 - version 2.9.04 + * admin-functions.php - Added syntax to be selective about SEO custom options and post types. + +2010.08.13 - version 2.9.03 + * admin-functions.php - Added twitter button shortcode + * /css/shortcodes.css - Added shortcodes CSS + +2010.08.12 - version 2.9.02 + * admin-functions.php - Added image to related posts shortcode + * /css/shortcodes.css - Added shortcodes CSS + +2010.08.12 - version 2.9.01 + * admin-interface.php - Added handling for Tumblog Upgrade function + * admin-tumblog-quickpress.php - Added Tumblog 2.0.0 functionality + * /css/tumblog.css - Added styling for Tumblog 2.0.0 functionality + * /js/tumblog-ajax.js - Added js for Tumblog 2.0.0 functionality + +2010.08.11 - version 2.9.00 + * admin-functions.php - Added shortcodes + * /css/shortcodes.css - Added shortcodes CSS + * /images/ - Added icons for shortcodes + +2010.08.06 - version 2.8.13 + * admin-functions.php - Added default image placeholder + * adimin-framework-settings.php - Added default image placeholder + +2010.08.06 - version 2.8.12 + * admin-functins.php - Fix so woo_title works on older versions of WP (pre 3.0) + +2010.08.06 - version 2.8.11 + * admin-functins.php - Added info box for SEO custom fields + * admin-custom.php - Added info box for SEO custom fields + * admin-seo.php - Added info box for SEO custom fields + +2010.08.05 - version 2.8.10 + * admin-functions.php - woo_title() fixed bug to show custom page title on pages + +2010.08.02 - version 2.8.09 + * admin-functions.php - Google Fonts: removed add_action. Must be loaded in includes/theme-actions.php or functions.php in the theme to use. + +2010.08.01 - version 2.8.08 + * admin-functions.php - Google Fonts: Fixed PHP warning if $woo_options not set + +2010.08.01 - version 2.8.07 + * admin-functions.php - Added Google Fonts stylesheet generator + * admin-interface.php - Added Google Fonts options + +2010.07.26 - version 2.8.06 + * admin-interface.php - Added fix for secondary inputs resetting on zero values + +2010.07.26 - version 2.8.05 + * admin-tumblog-quickpress + +2010.07.26 - version 2.8.04 + * admin-tumblog-quickpress.php - User Permissions fix: does not allow any user without publish_posts capability to see the dashboard widget. + +2010.07.19 - version 2.8.03 + * admin-functions.php - SEO upgrades and fixes to archive indexing and outputs. + +2010.07.14 - version 2.8.02 + * admin-functions.php - added Taxonomy Archive title information to SEO function woo_title() + +2010.07.12 - version 2.8.01 + * admin-custom.php - wpmu fix for versions prior to 3.0 - get_post_types() not supported in 2.9.x wpmu + +2010.07.08 - version 2.8.00 + * BUMP VERSION + +2010.07.08 - version 2.7.29 + * admin-setup.php - Added woo_comment_reply() (moved out from header.php), added function_exists to some functions + +2010.07.07 - version 2.7.28 + * admin-framework-settings.php - removed the framework beta option, now permanently enabled. + * admin-functions.php - Fixed and added SEO keyword output for new options + * admin-interface.php - Changed loading credentials for framework update page. + * admin-seo.php - Added new options for adding site wide keywords and descriptions. + +2010.07.06 - version 2.7.27 + * admin-seo.php - Added SEO option to disable the custom fields. + * admin-custom.php - Added functionality to disable the SEO custom fields. + * admin-functions.php - Changes some Special character encoding in the Keyword and Description meta output + +2010.07.02 - version 2.7.26 + * admin-custom.php - Made WooThemes Custom Fields/Custom Settings appear on custom post types automatically. + +2010.06.30 - version 2.7.25 + * admin-seo.php - Updated wording for SEO options. + +2010.06.28 - version 2.7.24 + * admin-functions.php - Adjusted woo_meta(); and other SEO functions due to third party plugin queries. + +2010.06.25 - version 2.7.23 + * admin-functions.php - added fix for possible WordPress 3 Multisite on blog.dir issues. (Commented out globals $blog_id;) + +2010.06.15 - version 2.7.22 + * admin-seo.php - Added notice for WordPress sites set to private. + +2010.06.15 - version 2.7.21 + * admin-functions.php - Uniformly sanatized SEO description outputs. + +2010.06.01 - version 2.7.20 + * admin-function.php - Fixed some possible issues with get_the_post_image in woo_image. Also fixed SEO keywords issues. + * admin-interface.php - Changed JS to iterate throughout hidden classes/options more accurately. + * admin-setup.php - Cleared up some php notice errors. + +2010.06.01 - version 2.7.19 + * admin-custom.php - Modified the output to store relative ID's into the page markup for custom fields. + +2010.05.27 - version 2.7.18 + * admin-functions.php - Formalized the the_post_thumbnail to work with rest of the woo_image structure. Post linking and WPMU safe. + +2010.05.27 - version 2.7.17 + * admin-custom-nav.php - Backend fix for 2nd+ level category descriptions in the Add an Existing Category box. + +2010.05.26 - version 2.7.16 + * admin-function - Added fix for images used elsewhere in a theme with custom width atributes (html resizing) + +2010.05.26 - version 2.7.15 + * admin-custom-nav.php - added error trapping for function mb_detect_encoding() which checks charset type. + * admin-setup.php - fixed index check on texttitle, Adjusted save on activate + + +2010.05.24 - version 2.7.14 + * admin-interface.php - Rectified problems with $woo_options not resetting and repopulating on import. + +2010.05.18 - version 2.7.13 + * admin-setup.php - fixed output of custom css from options + +2010.05.12 - version 2.7.12 + * admin-interface.php - Added jQuery for collapsable functionality in option page. + * admin-functions.php - Modified woo_image() to handle WordPress image. + * admin-setup.php - Added thumbnail setup + +2010.05.10 - version 2.7.11 + * admin-setup.php - added check for textitle from old theme options. + +2010.05.03 - version 2.7.10 + * admin-custom-nav.php - added stripslashes to handle escape chars for before_title and after_title params, russian chars now supported, current_page_parent class added, 2nd + level apostrophe fix + * admin-init.php - Versioned up to 2.7.10 + * admin-functions.php - Modified woo_image to support gallery functionality, modified woo_title() and woo_meta() to use plugin data and display paging details. + * admin-style.css - Added new classes for 'info' options + * admin-seo.php - Added more options to Options Page + * admin-interface.php - Added 'info' option. + +2010.04.29 - version 2.7.09 + * admin-custom-nav.php - added depth arg to frontend output + * admin-setup.php - Modified theme activate save function to retain non-common options. + +2010.04.23 - version 2.7.08 + * admin-interface.php - Adjust image upload return class to match corresponding CSS class for resizing. + * admin-init.php - Versioned up to 2.7.8 + +2010.04.19 - version 2.7.07 + * admin-funtions.php - Added support for removing special from file uploads. + * admin-custom.php - Added support for removing special from file uploads. + * style.css - Added z-index to options wrapper + +2010.04.14 - version 2.7.06 + * admin-tumblog-quickpress.php - Swopped out default WP editor for simpler nicEdit. + * /js/nicEdit.js - added nicEdit wysiwyg editor compressed source js. + * /js/tumblog-ajax.js - modified to support nicEdit. + * /images/nicEditorIcons.gif - added editor icons file. + * admin-init.php - Versioned up to 2.7.6 + +2010.04.12 - version 2.7.05 + * admin-framework-settings.php - Changed wording for Framework Core Updater option. + * admin-interface.php - Modified version checker, avoids possible user theme rename. + * admin-functions.php - Updated Framework Updater to ignore lesser versions. + * admin-init.php - Versioned up to 2.7.5 + +2010.04.12 - version 2.7.04 + * admin-init.php - Versioned up to 2.7.4 + * admin-functions.php - Fixed SEO and 404 page functionality + +2010.04.12 - version 2.7.03 + * admin-init.php - Versioned up to 2.7.3 + * admin-tumblog-quickpress.php - removed reference to old validation css + +2010.04.09 - version 2.7.02 + * admin-init.php - Versioned up to 2.7.2 + * admin-interface.php - Added Datepicker and time controls + * admin-custom.php - Added Datepicker and time controls + +2010.04.08 - version 2.7.01 + * admin-init.php - Versioned up to 2.7.1 + * admin-interface.php - Fixed error with default values for textareas + +2010.03.29 - version 2.7.00 + * MAJOR UPDATE! + * Added admin-seo.php & admin-init.php + * Changed base theme loading structure to admin-init.php, to resolve pressure from themes functions.php + * Converted all alternative options pages (SEO & Framework Settings) to The Machine and the AJAX save action. + * Added resets to main options areas. + * Added branding and super user support. + * Added SEO support. + * WooNav fixes for edit error, js error, changeover to wordpress default scripts - admin-custom-nav.php & custom_menu_dynamic_items.js & custom_menu_initial_items.js + * Tumblog functionality fixes for dashboard widget and cURL error - admin-tumblog-quickpress.php & admin-functions.php + * JS minified - jquery.autocomplete.js & ui.datepicker.js + +2010.03.25 - version 2.6.05 + * admin-custom-nav.php - bug fix for special chars and the sidebar widget - added block class to nav widget, updated db links field to use text instead of varchar + * /js/custom_menu_dynamic_items.js - bug fix for special chars + +2010.03.22 - version 2.6.04 + * admin-functions.php - Updated WPMU test in woo_image + +2010.03.18 - version 2.6.03 + * admin-functions.php - Comleted first version of WooFramework Updater with Direct and FTPext support + +2010.03.18 - version 2.6.02 + * admin-custom.php - improved calendar control for multiple calendars + * admin-interface.php - improved calendar control for multiple calendars + +2010.03.18 - version 2.6.01 + * admin-custom-nav.php - bug fix for custom menu items current page item class if using static home page + +2010.03.17 - version 2.6.00 + * admin-custom.php - added handler for post/page metabox for calendar + * admin-interface.php - added handler for theme option type=calendar and JS, CSS scripts + * /js/ui.datepicker.js - Added datepicker JS + * /css/datepicker/* - Added css and images for datepicker + +2010.03.16 - version 2.5.07 + * admin-custom-nav.php - bug fix for custom menu items current page item class + * admin-setup.php - added define( 'THEME_FRAMEWORK','woothemes' ); + +2010.03.15 - version 2.5.06 + * admin-custom-nav.php - added support for umlauts and other special chars + +2010.03.15 - version 2.5.05 + * admin-functions.php - added 'Off' functionality to the url shortener + +2010.03.04 - version 2.5.04 + * admin-functions.php - fixed a bug with getting first inline image in post in woo_image + +2010.03.04 - version 2.5.03 + * admin-custom-nav.php - bug on opening external links in new window + +2010.03.04 - version 2.5.02 + * admin-function.php - switched file_get_contents for curl + +2010.03.03 - version 2.5.01 + * admin-tumblog-quickpress.php - added tag support for Tumblog Dashboard Widget + +2010.03.03 - version 2.5.00 + * admin-functions.php - Made Generic woo_short_url($url) function that uses bit.ly or tinyurl + +2010.03.03 - version 2.4.09 + * admin-functions.php - Added TinyUrl shortener function getTinyUrl($url). + +2010.03.03 - version 2.4.08 + * admin-functions.php - Fixed a missing character in the woo_image function regarding non resized images. + +2010.03.03 - version 2.4.07 + * admin-functions.php - added double check for WPMU $blog_id + +2010.03.02 - version 2.4.06 + * admin-functions.php - line 153, removed the extra [0] from the $first_img = $matches[1][0]. Was giving an error. + +2010.03.02 - version 2.4.05 + * admin-custom-nav.php - removed id's from menu items so that menu can validate + +2010.03.02 - version 2.4.04 + * admin-tumblog-quickpress.php - fixed Audio and Image upload so that they now attach to the post when using Woo Quickpress widget + +2010.03.01 - version 2.4.03 + * admin-functions.php - Converted woo_get_embed into woo_embed (like woo_image), and created a working depreciation of woo_get_image. + +2010.02.25 - version 2.4.02 + * admin-interface.php - fixed bug with Tahoma font selection + +2010.02.25 - version 2.4.01 + * admin-functions.php - woo_image is upgraded with 'src' to accept image url's for dynamic resizing, and 'meta' for title and alt text. + +2010.02.24 - version 2.4.00 + * admin-functions - Added Dynamic Height calculation to woo_get_embed. + * admin-tumblog-quickpress and associated files - added tumblog files + +2010.02.23 - version 2.3.08 + * admin-interface.php - Fixed bug with saving mechanism. + +2010.02.16 - version 2.3.07 + * admin-interface.php - Fixed ajax callback NOTICE errors, fixed color box bug, removed cleanSource() from image uploader in the machine. + * admin-framework-settings.php - Fixed XML markup error. + +2010.02.15 - version 2.3.06 + * admin-framework-settings - Modified SQL queries for possible compatibility issues. + * admin-interface.php - Modified SQL queries for possible compatibility issues. + +2010.02.10 - version 2.3.05 + * admin-framework-settings.php - ADDED - put most of the Framework settings HTML interface in a seperate file. + * admin-framework-update.php - ADDED - New file that will act as the template for framework updates. (BETA) + * admin-interface.php - Wrote new checks for update messages. Along with save functions for new framework settings. + * admin-themes-page.php - Modified with WP_Error checks. + +2010.02.10 - version 2.3.04 + * admin-functions.php - Added woo_active_template() function for checking if a template is in use. + +2010.02.07 - version 2.3.03 + * admin-interface.php - added more fonts / stacks + +2010.02.07 - version 2.3.02 + * admin-setup.php - custom css wasn't outputted if text title option enabled + +2010.02.05 - version 2.3.01 + * admin-custom.php - Don't show thumb.php in image custom field if there isn't any image + * admin-functions.php - Added a double check for WPMU files path + +2010.02.03 - version 2.3.00 + * admin-interface.php - Added code to compile all options into one database row, woo_options. + +2010.02.03 - version 2.2.08 + * css/custom_nav.css - fixed child item margin + * admin-functions.php - defined $_REQUEST['options'] + * admin-interface.php - $update_message was undefined variable echo only if isset + * admin-interface.php - fixed line 880 to check if variable isset + * admin-custom-nav.php - implemented custom nav fixes and upgrades (upgrading made easier, version added, max width, anchor titles, reset confirmation, optional open link in new window) + +2010.02.02 - version 2.2.07 + * admin-custom-nav.php - fixed current_page_item bug which occurs when pretty permalinks are on + +2010.02.02 - version 2.2.06 + * admin-functions.php - Modified typography option + * admin-style.css - Modified typography option + * admin-interface.php - Removed usage of thumb.php to display uploaded image. + +2010.02.01 - version 2.2.06 + * admin-setup.php - Added functionality for editing menu items, updated menu add, current-page-item class, added reset button + +2010.02.01 - version 2.2.05 + * admin-hooks.php - Updated with new hook definitions + +2010.01.29 - version 2.2.04 + * admin-setup.php - Automatically show Options Panel on activate + +2010.01.27 - version 2.2.03 + * admin-setup.php - Cleared some PHP Notice warnings. + * css/custom_nav.css - added ico-arrow to WooNav + * images/ico-arrow.png - added ico-arrow to WooNav + +2010.01.27 - version 2.2.02 + * admin-custom.php - Fixed a file upload handle error + +2010.01.27 - version 2.2.01 + * admin-functions.php - fixed parameter link in woo_get_image + +2010.01.26 - version 2.2.00 + * admin-interface.php - Added custom navigation menu optional functionality. + * admin-setup.php - Added custom navigation menu optional functionality. + * admin-custom-nav.php - added to repository - all custom navigation menu functionality. + * admin-functions.php - Added function to show options on html page + * admin-inteface.php - Added new framework setting to disable output of options page + +2010.01.26 - version 2.1.02 + * admin-functions.php - Cleaned woo_image function and added functionality to get first image in post (not attached). + +2010.01.25 - version 2.1.01 + * admin-functions.php - Depreceated woo_get_image and forwarded it to woo_image. cleaned up and fixed cleansource function to work properly. + * admin-style.css - removed import reset.css + +2010.01.12 - version 2.1.00 + * admin-hooks.php - Definition of hooks that can be used in theme + * admin-functions.php - Added function for analytics and IE output in head + * admin-setup.php - Added function to output css in head. Removed legacy comments function. + +2009.12.23 - version 2.0.00 + * MAJOR Update (Beta) + * Temporary check built in to prevent 2.9 from bombing out on the RSS functions + +2009.12.18 - version 1.2.03 + * admin-functions.php - Fixed WPMU in woo_get_image when resizer disabled + +2009.11.02 - version 1.2.02 + * admin-functions.php - Set thumb.php parameters to have width first instead of height. + +2009.10.12 - version 1.2.01 + * admin-functions.php - Added support for WPMU in woo_get_image() + +2009.09.24 - version 1.2.00 + * admin-interface.php - Added icons to titles + * admin-interface.php - Rewritten jquery slider animation to work with new icons + * admin-style.css - New styling for icons + * /images/plus.png - ADDED + * /images/down.png - ADDED + * /images/up.png - ADDED + +2009.09.23 - version 1.1.01 + * admin-setup.php - Load default.css if options panel has not been saved yet. + * admin-interface.php - Fixed 'reset' not working properly. + * admin-interface.php - Replaced Woo-icon in back-end to reference local file. + * /images/woo-icon.png - ADDED + +2009.09.15 - version 1.1.00 + * admin-functions.php - Added sort order for "auto image" + * admin-functions.php - Only add rel="lightbox" when linking directly to images, and not permalinks. + +2009.09.07 - version 1.0.09 + * admin-functions.php - Added suckerfish hack to woo_get_embed + * admin-functions.php - Added $class to img tag when no resizer used + +2009.08.31 - Version 1.0.08 + * admin-interface.php - Converted file uploads to wp_handle_upload() + * admin-custom.php - Converted file uploads to wp_handle_upload() + * admin-functions.php - Added IE7 fix of empty height on woo_get_image + * admin-functions.php - Removed "permanent link to" from woo_get_image + * admin-functions.php - Added rel="lightbox" to woo_get_image + +2009.08.26 - Version 1.0.07 + * admin-setup.php - Added localization + * admin-setup.php - Added custom.css stylesheet link insert into the header + * admin-interface.php - Changed ABSPATH to get_template_directory() when assigning the get_theme_data argument. + * admin-functions.php - Changed ABSPATH to get_template_directory() when assigning the get_theme_data argument. + * admin-functions.php - Reworked woo_get_image to be less dependent on php function and added, 'woo_force_all' and 'woo_force_single' options for image sizing issues. + * admin-interface.php - Reworked the file uploader to catch permission errors. + * admin-costom.php - Reworked the file uploader to catch permission errors. + * admin-style.css - Added new style for error popup + * /images/error.png - Added icon for .errors class in CSS + +2009.08.13 - Version 1.0.06 + * admin-setup.php - Removed permanent woo_option_output() from wp_footer. Added as parameter. + * admin-interface.php - Uploads rewritten with Content Directories Constants. http://codex.wordpress.org/Determining_Plugin_and_Content_Directories + +2009.08.05 - Version 1.0.05 + * admin-interface.php - Fixed but with Abolute path on Theme version checker. + +2009.08.03 - Version 1.0.04a + * admin-interface.php - Removed Update notifier. Added support for '&' in select boxes. + +2009.07.27 - Version 1.0.04 + * admin-functions.php - Modified woo_get_image(), added get_page_id() function, added post [insert] shortcode. + * admin-interface.php - Added Update Notifier, + * admin-setup.php - Added custom CSS header insert, added encrypted footer woo_ options output (debugging). + +2009.07.16 - Version 1.0.03 + * admin-functions.php - Fixed woo_get_image syntax. + +2009.07.07 - Version 1.0.02 + * admin-custom.php - Added alternative method. Javascript
    hack for IE7. ie. Custom field uploading IE7 fix. + +2009.07.07 - Version 1.0.01 + * admin-functions.php - Added extra "$force" argument to the woo_get_image function. Adds ability to force woo_get_images to be set to given dimention when GD library is not available. (small image forced resize bug + img load missing height bug) + +2009.07.06 - Version 1.0.00 + * First Logged release \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/images/1c.png b/src/wp-content/themes/bloggingstream/functions/images/1c.png new file mode 100644 index 00000000..6bbb1c31 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/1c.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/2cl.png b/src/wp-content/themes/bloggingstream/functions/images/2cl.png new file mode 100644 index 00000000..fb1db09c Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/2cl.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/2cr.png b/src/wp-content/themes/bloggingstream/functions/images/2cr.png new file mode 100644 index 00000000..a832f28f Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/2cr.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/3cl.png b/src/wp-content/themes/bloggingstream/functions/images/3cl.png new file mode 100644 index 00000000..212851df Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/3cl.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/3cm.png b/src/wp-content/themes/bloggingstream/functions/images/3cm.png new file mode 100644 index 00000000..bad52c3e Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/3cm.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/3cr.png b/src/wp-content/themes/bloggingstream/functions/images/3cr.png new file mode 100644 index 00000000..fabfd66a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/3cr.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-audio.png b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-audio.png new file mode 100644 index 00000000..574ad5cb Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-audio.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-image.png b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-image.png new file mode 100644 index 00000000..551d1a1e Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-image.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-link.png b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-link.png new file mode 100644 index 00000000..da2dfc08 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-link.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-note.png b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-note.png new file mode 100644 index 00000000..4645eec5 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-note.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-quote.png b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-quote.png new file mode 100644 index 00000000..3dfb3301 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-quote.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-video.png b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-video.png new file mode 100644 index 00000000..3074ff4f Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/btn-tumblog-video.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/calendar.gif b/src/wp-content/themes/bloggingstream/functions/images/calendar.gif new file mode 100644 index 00000000..d0abaa7c Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/calendar.gif differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/blank.gif b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/blank.gif new file mode 100644 index 00000000..75b945d2 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/blank.gif differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_background.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_background.png new file mode 100644 index 00000000..8401572f Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_background.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hex.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hex.png new file mode 100644 index 00000000..4e532d7c Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hex.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_b.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_b.png new file mode 100644 index 00000000..dfac595d Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_b.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_h.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_h.png new file mode 100644 index 00000000..3977ed9f Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_h.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_s.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_s.png new file mode 100644 index 00000000..a2a69973 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_hsb_s.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_indic.gif b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_indic.gif new file mode 100644 index 00000000..f9fa95e2 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_indic.gif differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_overlay.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_overlay.png new file mode 100644 index 00000000..561cdd9c Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_overlay.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_b.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_b.png new file mode 100644 index 00000000..dfac595d Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_b.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_g.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_g.png new file mode 100644 index 00000000..72b32760 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_g.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_r.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_r.png new file mode 100644 index 00000000..4855fe03 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_rgb_r.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_select.gif b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_select.gif new file mode 100644 index 00000000..599f7f13 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_select.gif differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_submit.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_submit.png new file mode 100644 index 00000000..7f4c0825 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/colorpicker_submit.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/colorpicker/select.png b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/select.png new file mode 100644 index 00000000..bfc46dce Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/colorpicker/select.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-0.png b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-0.png new file mode 100644 index 00000000..6bbb1c31 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-0.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-1.png b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-1.png new file mode 100644 index 00000000..b8a5c29c Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-1.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-2.png b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-2.png new file mode 100644 index 00000000..a63d3bea Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-2.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-3.png b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-3.png new file mode 100644 index 00000000..30536982 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-3.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-4.png b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-4.png new file mode 100644 index 00000000..dbecf9bf Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/footer-widgets-4.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/gray-grad.png b/src/wp-content/themes/bloggingstream/functions/images/gray-grad.png new file mode 100644 index 00000000..5ac3e02b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/gray-grad.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/happy.png b/src/wp-content/themes/bloggingstream/functions/images/happy.png new file mode 100644 index 00000000..e463fa82 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/happy.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/headertile.jpg b/src/wp-content/themes/bloggingstream/functions/images/headertile.jpg new file mode 100644 index 00000000..97e23a04 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/headertile.jpg differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/headingtop.jpg b/src/wp-content/themes/bloggingstream/functions/images/headingtop.jpg new file mode 100644 index 00000000..16893dcb Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/headingtop.jpg differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-add.png b/src/wp-content/themes/bloggingstream/functions/images/ico-add.png new file mode 100644 index 00000000..21adda4b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-add.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-alert.png b/src/wp-content/themes/bloggingstream/functions/images/ico-alert.png new file mode 100644 index 00000000..f985243a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-alert.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-arrow.png b/src/wp-content/themes/bloggingstream/functions/images/ico-arrow.png new file mode 100644 index 00000000..c931088e Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-arrow.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-changelog.png b/src/wp-content/themes/bloggingstream/functions/images/ico-changelog.png new file mode 100644 index 00000000..e1649f53 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-changelog.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-close.png b/src/wp-content/themes/bloggingstream/functions/images/ico-close.png new file mode 100644 index 00000000..f985243a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-close.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-delete.png b/src/wp-content/themes/bloggingstream/functions/images/ico-delete.png new file mode 100644 index 00000000..d9bc51b1 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-delete.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-docs.png b/src/wp-content/themes/bloggingstream/functions/images/ico-docs.png new file mode 100644 index 00000000..ed73f204 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-docs.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-download.png b/src/wp-content/themes/bloggingstream/functions/images/ico-download.png new file mode 100644 index 00000000..a5643dee Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-download.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-edit.png b/src/wp-content/themes/bloggingstream/functions/images/ico-edit.png new file mode 100644 index 00000000..061c7f0b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-edit.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-forum.png b/src/wp-content/themes/bloggingstream/functions/images/ico-forum.png new file mode 100644 index 00000000..deec4534 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-forum.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-info.png b/src/wp-content/themes/bloggingstream/functions/images/ico-info.png new file mode 100644 index 00000000..eb228bdb Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-info.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-note.png b/src/wp-content/themes/bloggingstream/functions/images/ico-note.png new file mode 100644 index 00000000..4f2bd659 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-note.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-social-delicious.png b/src/wp-content/themes/bloggingstream/functions/images/ico-social-delicious.png new file mode 100644 index 00000000..d8e563ab Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-social-delicious.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-social-facebook.png b/src/wp-content/themes/bloggingstream/functions/images/ico-social-facebook.png new file mode 100644 index 00000000..8ff36919 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-social-facebook.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-social-flickr.png b/src/wp-content/themes/bloggingstream/functions/images/ico-social-flickr.png new file mode 100644 index 00000000..54e1c025 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-social-flickr.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-social-linkedin.png b/src/wp-content/themes/bloggingstream/functions/images/ico-social-linkedin.png new file mode 100644 index 00000000..ecf0a1c6 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-social-linkedin.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-social-rss.png b/src/wp-content/themes/bloggingstream/functions/images/ico-social-rss.png new file mode 100644 index 00000000..ccd92f3d Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-social-rss.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-social-twitter.png b/src/wp-content/themes/bloggingstream/functions/images/ico-social-twitter.png new file mode 100644 index 00000000..dac33d34 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-social-twitter.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-social-youtube.png b/src/wp-content/themes/bloggingstream/functions/images/ico-social-youtube.png new file mode 100644 index 00000000..8cd302cd Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-social-youtube.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-tick.png b/src/wp-content/themes/bloggingstream/functions/images/ico-tick.png new file mode 100644 index 00000000..964e9dd0 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-tick.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ico-viewpage.png b/src/wp-content/themes/bloggingstream/functions/images/ico-viewpage.png new file mode 100644 index 00000000..e1649f53 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ico-viewpage.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/icon-32.png b/src/wp-content/themes/bloggingstream/functions/images/icon-32.png new file mode 100644 index 00000000..6a20ad57 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/icon-32.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/info.png b/src/wp-content/themes/bloggingstream/functions/images/info.png new file mode 100644 index 00000000..4224de59 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/info.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/layout-off.png b/src/wp-content/themes/bloggingstream/functions/images/layout-off.png new file mode 100644 index 00000000..6f1417d9 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/layout-off.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/loading-bottom.gif b/src/wp-content/themes/bloggingstream/functions/images/loading-bottom.gif new file mode 100644 index 00000000..1528fec0 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/loading-bottom.gif differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/loading-top.gif b/src/wp-content/themes/bloggingstream/functions/images/loading-top.gif new file mode 100644 index 00000000..690da655 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/loading-top.gif differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/logo.png b/src/wp-content/themes/bloggingstream/functions/images/logo.png new file mode 100644 index 00000000..c12353ec Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/logo.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/nicEditorIcons.gif b/src/wp-content/themes/bloggingstream/functions/images/nicEditorIcons.gif new file mode 100644 index 00000000..a0fdc7e4 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/nicEditorIcons.gif differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-ads.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-ads.png new file mode 100644 index 00000000..463e64b6 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-ads.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-audio.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-audio.png new file mode 100644 index 00000000..e8b4d57d Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-audio.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-box.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-box.png new file mode 100644 index 00000000..8ec13815 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-box.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-calendar.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-calendar.png new file mode 100644 index 00000000..197359c8 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-calendar.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-connect.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-connect.png new file mode 100644 index 00000000..586833eb Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-connect.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-favorite.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-favorite.png new file mode 100644 index 00000000..33b2afe3 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-favorite.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-featured.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-featured.png new file mode 100644 index 00000000..3968357d Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-featured.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-footer.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-footer.png new file mode 100644 index 00000000..ba241710 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-footer.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-general.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-general.png new file mode 100644 index 00000000..b74083e3 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-general.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-header.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-header.png new file mode 100644 index 00000000..fe6a448f Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-header.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-homepage.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-homepage.png new file mode 100644 index 00000000..ecbc7c5a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-homepage.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-image.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-image.png new file mode 100644 index 00000000..f0378b68 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-image.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-layout.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-layout.png new file mode 100644 index 00000000..8e19f7c7 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-layout.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-listing.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-listing.png new file mode 100644 index 00000000..65d3cc1e Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-listing.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-main.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-main.png new file mode 100644 index 00000000..cd472b99 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-main.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-maps.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-maps.png new file mode 100644 index 00000000..d6a77689 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-maps.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-media.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-media.png new file mode 100644 index 00000000..e57308cc Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-media.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-misc.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-misc.png new file mode 100644 index 00000000..3e3c1245 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-misc.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-nav.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-nav.png new file mode 100644 index 00000000..4858f2ec Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-nav.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-portfolio.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-portfolio.png new file mode 100644 index 00000000..6fba2866 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-portfolio.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-post.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-post.png new file mode 100644 index 00000000..0679cb4e Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-post.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-search.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-search.png new file mode 100644 index 00000000..e1649f53 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-search.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-sidebar.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-sidebar.png new file mode 100644 index 00000000..f24ee244 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-sidebar.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-slider.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-slider.png new file mode 100644 index 00000000..9a2d4d16 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-slider.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-styling.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-styling.png new file mode 100644 index 00000000..612ea984 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-styling.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-tumblog.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-tumblog.png new file mode 100644 index 00000000..5d0512b2 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-tumblog.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-typography.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-typography.png new file mode 100644 index 00000000..d191038c Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-typography.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/option-icon-upload.png b/src/wp-content/themes/bloggingstream/functions/images/option-icon-upload.png new file mode 100644 index 00000000..a655321e Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/option-icon-upload.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/quote.png b/src/wp-content/themes/bloggingstream/functions/images/quote.png new file mode 100644 index 00000000..a15efb9a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/quote.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/select.png b/src/wp-content/themes/bloggingstream/functions/images/select.png new file mode 100644 index 00000000..8be5ec97 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/select.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-arrow.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-arrow.png new file mode 100644 index 00000000..c724754b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-arrow.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-bullet.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-bullet.png new file mode 100644 index 00000000..a2bf71ff Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-bullet.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-green-dot.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-green-dot.png new file mode 100644 index 00000000..92cb0f90 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-green-dot.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-icon.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-icon.png new file mode 100644 index 00000000..e3cbc08a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-icon.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-red-x.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-red-x.png new file mode 100644 index 00000000..3286033a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-red-x.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-star.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-star.png new file mode 100644 index 00000000..33b2afe3 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-star.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-tick.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-tick.png new file mode 100644 index 00000000..386dc90e Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-tick.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-toggle-close.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-toggle-close.png new file mode 100644 index 00000000..2bd976fd Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-toggle-close.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/shortcode-toggle-open.png b/src/wp-content/themes/bloggingstream/functions/images/shortcode-toggle-open.png new file mode 100644 index 00000000..ca2d1fd4 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/shortcode-toggle-open.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_flat_0_aaaaaa_40x100.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 00000000..99be896b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_flat_75_ffffff_40x100.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 00000000..e77a5354 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_55_fbf9ee_1x400.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 00000000..6352348b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_65_ffffff_1x400.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 00000000..54b5d352 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_75_dadada_1x400.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 00000000..20055b8b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_75_e6e6e6_1x400.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 00000000..efe693be Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_95_fef1ec_1x400.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 00000000..c3e50c11 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 00000000..7c9fa6c6 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-icons_222222_256x240.png b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_222222_256x240.png new file mode 100644 index 00000000..dcfc3e9a Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_222222_256x240.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-icons_2e83ff_256x240.png b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 00000000..e0df77f0 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_2e83ff_256x240.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-icons_454545_256x240.png b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_454545_256x240.png new file mode 100644 index 00000000..568ec49b Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_454545_256x240.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-icons_888888_256x240.png b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_888888_256x240.png new file mode 100644 index 00000000..a7bafd63 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_888888_256x240.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/ui-icons_cd0a0a_256x240.png b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 00000000..fa7a9bbd Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/ui-icons_cd0a0a_256x240.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/warning.png b/src/wp-content/themes/bloggingstream/functions/images/warning.png new file mode 100644 index 00000000..9a1dd845 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/warning.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/images/woo-icon.png b/src/wp-content/themes/bloggingstream/functions/images/woo-icon.png new file mode 100644 index 00000000..7628ce37 Binary files /dev/null and b/src/wp-content/themes/bloggingstream/functions/images/woo-icon.png differ diff --git a/src/wp-content/themes/bloggingstream/functions/js/ajaxupload.js b/src/wp-content/themes/bloggingstream/functions/js/ajaxupload.js new file mode 100644 index 00000000..5b4e44d1 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/js/ajaxupload.js @@ -0,0 +1,606 @@ +/** + * AJAX Upload + * Project page - http://valums.com/ajax-upload/ + * Copyright (c) 2008 Andris Valums, http://valums.com + * Licensed under the MIT license (http://valums.com/mit-license/) + */ +(function(){ + +var d = document, w = window; + +/** + * Get element by id + */ +function get(element){ + if (typeof element == "string") + element = d.getElementById(element); + return element; +} + +/** + * Attaches event to a dom element + */ +function addEvent(el, type, fn){ + if (w.addEventListener){ + el.addEventListener(type, fn, false); + } else if (w.attachEvent){ + var f = function(){ + fn.call(el, w.event); + }; + el.attachEvent( 'on' + type, f) + } +} + + +/** + * Creates and returns element from html chunk + */ +var toElement = function(){ + var div = d.createElement( 'div' ); + return function(html){ + div.innerHTML = html; + var el = div.childNodes[0]; + div.removeChild(el); + return el; + } +}(); + +function hasClass(ele,cls){ + return ele.className.match(new RegExp( '(\\s|^)'+cls+'(\\s|$)')); +} +function addClass(ele,cls) { + if (!hasClass(ele,cls)) ele.className += " "+cls; +} +function removeClass(ele,cls) { + var reg = new RegExp( '(\\s|^)'+cls+'(\\s|$)' ); + ele.className=ele.className.replace(reg,' ' ); +} + +// getOffset function copied from jQuery lib (http://jquery.com/) +if (document.documentElement["getBoundingClientRect"]){ + // Get Offset using getBoundingClientRect + // http://ejohn.org/blog/getboundingclientrect-is-awesome/ + var getOffset = function(el){ + var box = el.getBoundingClientRect(), + doc = el.ownerDocument, + body = doc.body, + docElem = doc.documentElement, + + // for ie + clientTop = docElem.clientTop || body.clientTop || 0, + clientLeft = docElem.clientLeft || body.clientLeft || 0, + + // In Internet Explorer 7 getBoundingClientRect property is treated as physical, + // while others are logical. Make all logical, like in IE8. + + zoom = 1; + + if (body.getBoundingClientRect) { + var bound = body.getBoundingClientRect(); + zoom = (bound.right - bound.left)/body.clientWidth; + } + + if (zoom > 1){ + clientTop = 0; + clientLeft = 0; + } + + var top = box.top/zoom + (window.pageYOffset || docElem && docElem.scrollTop/zoom || body.scrollTop/zoom) - clientTop, + left = box.left/zoom + (window.pageXOffset|| docElem && docElem.scrollLeft/zoom || body.scrollLeft/zoom) - clientLeft; + + return { + top: top, + left: left + }; + } + +} else { + // Get offset adding all offsets + var getOffset = function(el){ + if (w.jQuery){ + return jQuery(el).offset(); + } + + var top = 0, left = 0; + do { + top += el.offsetTop || 0; + left += el.offsetLeft || 0; + } + while (el = el.offsetParent); + + return { + left: left, + top: top + }; + } +} + +function getBox(el){ + var left, right, top, bottom; + var offset = getOffset(el); + left = offset.left; + top = offset.top; + + right = left + el.offsetWidth; + bottom = top + el.offsetHeight; + + return { + left: left, + right: right, + top: top, + bottom: bottom + }; +} + +/** + * Crossbrowser mouse coordinates + */ +function getMouseCoords(e){ + // pageX/Y is not supported in IE + // http://www.quirksmode.org/dom/w3c_cssom.html + if (!e.pageX && e.clientX){ + // In Internet Explorer 7 some properties (mouse coordinates) are treated as physical, + // while others are logical (offset). + var zoom = 1; + var body = document.body; + + if (body.getBoundingClientRect) { + var bound = body.getBoundingClientRect(); + zoom = (bound.right - bound.left)/body.clientWidth; + } + + return { + x: e.clientX / zoom + d.body.scrollLeft + d.documentElement.scrollLeft, + y: e.clientY / zoom + d.body.scrollTop + d.documentElement.scrollTop + }; + } + + return { + x: e.pageX, + y: e.pageY + }; + +} +/** + * Function generates unique id + */ +var getUID = function(){ + var id = 0; + return function(){ + return 'ValumsAjaxUpload' + id++; + } +}(); + +function fileFromPath(file){ + return file.replace(/.*(\/|\\)/, "" ); +} + +function getExt(file){ + return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : ''; +} + +/** + * Cross-browser way to get xhr object + */ +var getXhr = function(){ + var xhr; + + return function(){ + if (xhr) return xhr; + + if (typeof XMLHttpRequest !== 'undefined') { + xhr = new XMLHttpRequest(); + } else { + var v = [ + "Microsoft.XmlHttp", + "MSXML2.XmlHttp.5.0", + "MSXML2.XmlHttp.4.0", + "MSXML2.XmlHttp.3.0", + "MSXML2.XmlHttp.2.0" + ]; + + for (var i=0; i < v.length; i++){ + try { + xhr = new ActiveXObject(v[i]); + break; + } catch (e){} + } + } + + return xhr; + } +}(); + +// Please use AjaxUpload , Ajax_upload will be removed in the next version +Ajax_upload = AjaxUpload = function(button, options){ + if (button.jquery){ + // jquery object was passed + button = button[0]; + } else if (typeof button == "string" && /^#.*/.test(button)){ + button = button.slice(1); + } + button = get(button); + + this._input = null; + this._button = button; + this._disabled = false; + this._submitting = false; + // Variable changes to true if the button was clicked + // 3 seconds ago (requred to fix Safari on Mac error) + this._justClicked = false; + this._parentDialog = d.body; + + if (window.jQuery && jQuery.ui && jQuery.ui.dialog){ + var parentDialog = jQuery(this._button).parents( '.ui-dialog' ); + if (parentDialog.length){ + this._parentDialog = parentDialog[0]; + } + } + + this._settings = { + // Location of the server-side upload script + action: 'upload.php', + // File upload name + name: 'userfile', + // Additional data to send + data: {}, + // Submit file as soon as it's selected + autoSubmit: true, + // The type of data that you're expecting back from the server. + // Html and xml are detected automatically. + // Only useful when you are using json data as a response. + // Set to "json" in that case. + responseType: false, + // Location of the server-side script that fixes Safari + // hanging problem returning "Connection: close" header + closeConnection: '', + // Class applied to button when mouse is hovered + hoverClass: 'hover', + // When user selects a file, useful with autoSubmit disabled + onChange: function(file, extension){}, + // Callback to fire before file is uploaded + // You can return false to cancel upload + onSubmit: function(file, extension){}, + // Fired when file upload is completed + // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE! + onComplete: function(file, response) {} + }; + + // Merge the users options with our defaults + for (var i in options) { + this._settings[i] = options[i]; + } + + this._createInput(); + this._rerouteClicks(); +} + +// assigning methods to our class +AjaxUpload.prototype = { + setData : function(data){ + this._settings.data = data; + }, + disable : function(){ + this._disabled = true; + }, + enable : function(){ + this._disabled = false; + }, + // removes instance + destroy : function(){ + if(this._input){ + if(this._input.parentNode){ + this._input.parentNode.removeChild(this._input); + } + this._input = null; + } + }, + /** + * Creates invisible file input above the button + */ + _createInput : function(){ + var self = this; + var input = d.createElement( "input" ); + input.setAttribute( 'type', 'file' ); + input.setAttribute( 'name', this._settings.name); + var styles = { + 'position' : 'absolute' + ,'margin': '-5px 0 0 -175px' + ,'padding': 0 + ,'width': '220px' + ,'height': '30px' + ,'fontSize': '14px' + ,'opacity': 0 + ,'cursor': 'pointer' + ,'display' : 'none' + ,'zIndex' : 2147483583 //Max zIndex supported by Opera 9.0-9.2x + // Strange, I expected 2147483647 + // Doesn't work in IE :( + //,'direction' : 'ltr' + }; + for (var i in styles){ + input.style[i] = styles[i]; + } + + // Make sure that element opacity exists + // (IE uses filter instead) + if ( ! (input.style.opacity === "0")){ + input.style.filter = "alpha(opacity=0)"; + } + + this._parentDialog.appendChild(input); + + addEvent(input, 'change', function(){ + // get filename from input + var file = fileFromPath(this.value); + if(self._settings.onChange.call(self, file, getExt(file)) == false ){ + return; + } + // Submit form when value is changed + if (self._settings.autoSubmit){ + self.submit(); + } + }); + + // Fixing problem with Safari + // The problem is that if you leave input before the file select dialog opens + // it does not upload the file. + // As dialog opens slowly (it is a sheet dialog which takes some time to open) + // there is some time while you can leave the button. + // So we should not change display to none immediately + addEvent(input, 'click', function(){ + self.justClicked = true; + setTimeout(function(){ + // we will wait 3 seconds for dialog to open + self.justClicked = false; + }, 2500); + }); + + this._input = input; + }, + _rerouteClicks : function (){ + var self = this; + + // IE displays 'access denied' error when using this method + // other browsers just ignore click() + // addEvent(this._button, 'click', function(e){ + // self._input.click(); + // }); + + var box, dialogOffset = {top:0, left:0}, over = false; + + addEvent(self._button, 'mouseover', function(e){ + if (!self._input || over) return; + + over = true; + box = getBox(self._button); + + if (self._parentDialog != d.body){ + dialogOffset = getOffset(self._parentDialog); + } + }); + + + // We can't use mouseout on the button, + // because invisible input is over it + addEvent(document, 'mousemove', function(e){ + var input = self._input; + if (!input || !over) return; + + if (self._disabled){ + removeClass(self._button, self._settings.hoverClass); + input.style.display = 'none'; + return; + } + + var c = getMouseCoords(e); + + if ((c.x >= box.left) && (c.x <= box.right) && + (c.y >= box.top) && (c.y <= box.bottom)){ + + input.style.top = c.y - dialogOffset.top + 'px'; + input.style.left = c.x - dialogOffset.left + 'px'; + input.style.display = 'block'; + addClass(self._button, self._settings.hoverClass); + + } else { + // mouse left the button + over = false; + + var check = setInterval(function(){ + // if input was just clicked do not hide it + // to prevent safari bug + + if (self.justClicked){ + return; + } + + if ( !over ){ + input.style.display = 'none'; + } + + clearInterval(check); + + }, 25); + + + removeClass(self._button, self._settings.hoverClass); + } + }); + + }, + /** + * Creates iframe with unique name + */ + _createIframe : function(){ + // unique name + // We cannot use getTime, because it sometimes return + // same value in safari :( + var id = getUID(); + + // Remove ie6 "This page contains both secure and nonsecure items" prompt + // http://tinyurl.com/77w9wh + var iframe = toElement( ' + + +
    + + + + + + +
    + +

    + + +

    + +

    + +

    + +

    /functions/' ); ?>

    + +

    ', '' ); ?>

    + +

    Remember: Every Ninja has a backup plan. Safe or not, always backup your theme before you update it or make changes to it.', 'woothemes' ); ?>

    + + + +

    + +

    + +

    WooThemes Gallery and get one.', 'woothemes' ); ?>

    + + + +
    +
    + + + + + + + + + \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/editor_plugin.js b/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/editor_plugin.js new file mode 100644 index 00000000..b78a6598 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/editor_plugin.js @@ -0,0 +1,191 @@ +function woo_js_querystring(ji) { + + hu = window.location.search.substring(1); + gy = hu.split( "&" ); + for (i=0;i 0 ) { + + selectedText = d.selection.getContent(); + + } // End IF Statement + + wooSelectedShortcodeType = c.identifier; + wooSelectedShortcodeTitle = c.title; + + + jQuery.get(e+"/dialog.php",function(b){ + + jQuery( '#woo-options').addClass( 'shortcode-' + wooSelectedShortcodeType ); + jQuery( '#woo-preview').addClass( 'shortcode-' + wooSelectedShortcodeType ); + + // Skip the popup on certain shortcodes. + + switch ( wooSelectedShortcodeType ) { + + // Highlight + + case 'highlight': + + var a = '[highlight]'+selectedText+'[/highlight]'; + + tinyMCE.activeEditor.execCommand( "mceInsertContent", false, a); + + break; + + // Dropcap + + case 'dropcap': + + var a = '[dropcap]'+selectedText+'[/dropcap]'; + + tinyMCE.activeEditor.execCommand( "mceInsertContent", false, a); + + break; + + default: + + jQuery( "#woo-dialog").remove(); + jQuery( "body").append(b); + jQuery( "#woo-dialog").hide(); + var f=jQuery(window).width(); + b=jQuery(window).height(); + f=7200 ) } ) // Disables the button if text is highlighted in the editor. + }, + + createControl:function(d,e){ + + if(d=="woothemes_shortcodes_button"){ + + d=e.createMenuButton( "woothemes_shortcodes_button",{ + title:"Insert WooThemes Shortcode", + image:icon_url, + icons:false + }); + + var a=this;d.onRenderMenu.add(function(c,b){ + + a.addWithDialog(b,"Button","button" ); + a.addWithDialog(b,"Icon Link","ilink" );b.addSeparator(); + a.addWithDialog(b,"Info Box","box" ); + c=b.addMenu({title:"Typography"}); + a.addWithDialog(c,"Dropcap","dropcap" ); + a.addWithDialog(c,"Quote","quote" ); + a.addWithDialog(c,"Highlight","highlight" ); + a.addWithDialog(c,"Custom Typography","typography" ); + a.addWithDialog(c,"Abbreviation","abbr" ); + a.addWithDialog(b,"Content Toggle","toggle" ); + a.addWithDialog(b,"Related Posts","related" ); + a.addWithDialog(b,"Contact Form","contactform" ); + b.addSeparator(); + a.addWithDialog(b,"Column Layout","column" ); + a.addWithDialog(b,"Tab Layout","tab" ); + b.addSeparator(); + c=b.addMenu({title:"List Generator"}); + a.addWithDialog(c,"Unordered List","unordered_list" ); + a.addWithDialog(c,"Ordered List","ordered_list" ); + c=b.addMenu({title:"Dividers"}); + a.addImmediate(c,"Horizontal Rule","[hr] " ); + a.addImmediate(c,"Divider","[divider] " ); + a.addImmediate(c,"Flat Divider","[divider_flat] " ); + c=b.addMenu({title:"Social Buttons"}); + a.addWithDialog(c,"Social Profile Icon","social_icon" ); + c.addSeparator(); + a.addWithDialog(c,"Twitter","twitter" ); + a.addWithDialog(c,"Tweetmeme","tweetmeme" ); + a.addWithDialog(c,"Digg","digg" ); + a.addWithDialog(c,"Like on Facebook","fblike" ); + a.addWithDialog(c,"Share on Facebook","fbshare" ); + a.addWithDialog(c,"Share on LinkedIn","linkedin_share" ); + /*b.add({title:"Visit WooThemes.com","class":"woo-woolink",onclick:function(){tinyMCE.activeEditor.execCommand( "wooVisitWooThemes",false,"")}})*/ }); + return d + + } // End IF Statement + + return null + }, + + addImmediate:function(d,e,a){d.add({title:e,onclick:function(){tinyMCE.activeEditor.execCommand( "mceInsertContent",false,a)}})}, + + addWithDialog:function(d,e,a){d.add({title:e,onclick:function(){tinyMCE.activeEditor.execCommand( "wooOpenDialog",false,{title:e,identifier:a})}})}, + + getInfo:function(){ return{longname:"WooThemes Shortcode Generator",author:"VisualShortcodes.com",authorurl:"http://visualshortcodes.com",infourl:"http://visualshortcodes.com/shortcode-ninja",version:"1.0"} } + } + ); + + tinymce.PluginManager.add( "WooThemesShortcodes",tinymce.plugins.WooThemesShortcodes) + } +)(); diff --git a/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/js/column-control.js b/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/js/column-control.js new file mode 100644 index 00000000..6781d119 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/js/column-control.js @@ -0,0 +1,95 @@ +function wooColumnMaker(h, i, f) { + this.parentControl = h; + var d = this; + this.width = 250; + this.maxColumns = i; + this.buttonsControl = this.textControl = this.selectControl = null; + this.init = function () { + this.buildSelectControl(); + this.buildColumnButtons(0); + this.buildTextControl() + }; + this.getTotalColumns = function () { + return Number(d.selectControl.find( "option:selected").val()) + }; + this.buildSelectControl = function () { + // .attr( "style", "width:" + this.width + "px") + this.selectControl = jQuery( "").attr( "id", "woo-column-select").addClass(f ? f : "" ); + var a = jQuery( "").attr( "value", "select").attr( "selected", "selected").text( "Number of columns..." ); + a.appendTo(this.selectControl); + for (var b = 2; b <= this.maxColumns; b++) { + a = jQuery( "").attr( "value", b).text(b + " columns" ); + a.appendTo(this.selectControl) + } + this.selectControl.change(function (c) { + (c = d.getTotalColumns()) && d.buildColumnButtons(c) + + // Update the text in the appropriate span tag. + var newText = jQuery(this).children( 'option:selected').text(); + + jQuery(this).parents( '.select_wrapper').find( 'span').text( newText ); + }); + this.parentControl.append(this.selectControl) + }; + this.buildTextControl = function () { + var a = jQuery( "
    ").attr( "style", "position: relative;margin-top: 5px; width: " + this.width + "px;" ); + a.appendTo(this.parentControl); + this.textControl = jQuery( "
     
    ").attr( "id", "woo-column-text").attr( "style", "width: " + (this.width - 50) + "px" ); + a.append(this.textControl); + var b = jQuery( "").attr( "type", "button").attr( "style", "width: 40px;position:absolute;right: 0px;bottom: -2px;font-size: 22px; border:none;background:none;").attr( "value", "\u232b" ); + a.append(b); + b.click(function () { + d.deleteColumnButtonClicked() + }) + }; + this.buildColumnButtons = function (a) { + if (this.buttonsControl) { + this.buttonsControl.html( "" ); + this.textControl.html( " ") + } else { + this.buttonsControl = jQuery( "
    ").attr( "id", "woo-column-buttons" ); + this.parentControl.append(this.buttonsControl); + jQuery( '
    ').appendTo(this.parentControl) + } + for (var b = 1; b < a; b++) { + var c = jQuery( "").attr( "type", "button").attr( "value", b + "/" + a).attr( "name", b).attr( "style", "width:" + Math.floor(this.width * (b / a)) + "px").addClass( "column-button").addClass( "rounded5p" ); + c.click(function (e) { + d.columnButtonClicked(e) + }); + this.buttonsControl.append(c) + } + }; + this.deleteColumnButtonClicked = function () { + var a = jQuery.trim(this.textControl.text()), + b = a.lastIndexOf( "|" ); + a = b != -1 ? jQuery.trim(a.substring(0, b)) : " "; + this.textControl.html(a); + this.updateColumnButtonsState() + }; + this.columnButtonClicked = function (a) { + var b = Number(a.target.name); + if (b) { + a = ""; + for (var c = 0; c < b; c++) a += "x"; + b = jQuery.trim(this.textControl.text()); + if (b.length > 0) a = " | " + a; + this.textControl.text(b + a); + this.updateColumnButtonsState() + } + }; + this.updateColumnButtonsState = function () { + var a = this.getTotalColumns(); + if (a) { + var b = this.countCurrentColumns(), + c = a - b; + this.buttonsControl.find( "input").each(function (e, g) { + e >= c ? jQuery(g).attr( "disabled", "disabled") : jQuery(g).removeAttr( "disabled") + }) + } + }; + this.countCurrentColumns = function () { + for (var a = this.textControl.text(), b = 0, c = 0; c < a.length; c++) a.charAt(c) == "x" && b++; + return b + }; + this.init() +}; \ No newline at end of file diff --git a/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/js/dialog-js.php b/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/js/dialog-js.php new file mode 100644 index 00000000..c0431394 --- /dev/null +++ b/src/wp-content/themes/bloggingstream/functions/js/shortcode-generator/js/dialog-js.php @@ -0,0 +1,753 @@ + $v ) { + + $fonts_whitelist[$k] = str_replace( '|', '\"', $v ); + + } // End FOREACH Loop + + $fonts = join( '|', $fonts_whitelist ); +?> + +var framework_url = ''; + +var shortcode_generator_path = ''; +var shortcode_generator_url = '' + 'js/shortcode-generator/'; + +var wooDialogHelper = { + + needsPreview: false, + setUpButtons: function () { + var a = this; + jQuery( "#woo-btn-cancel").click(function () { + a.closeDialog() + }); + jQuery( "#woo-btn-insert").click(function () { + a.insertAction() + }); + jQuery( "#woo-btn-preview").click(function () { + a.previewAction() + }) + }, + + setUpColourPicker: function () { + + var startingColour = '000000'; + + jQuery( '.woo-marker-colourpicker-control div.colorSelector').each ( function () { + + var colourPicker = jQuery(this).ColorPicker({ + + color: startingColour, + onShow: function (colpkr) { + jQuery(colpkr).fadeIn(500); + return false; + }, + onHide: function (colpkr) { + jQuery(colpkr).fadeOut(500); + + wooDialogHelper.previewAction(); + + return false; + }, + onChange: function (hsb, hex, rgb) { + jQuery(colourPicker).children( 'div').css( 'backgroundColor', '#' + hex); + jQuery(colourPicker).next( 'input').attr( 'value','#' + hex); + } + + }); + + // jQuery(colourPicker).children( 'div').css( 'backgroundColor', '#' + startingColour); + // jQuery(colourPicker).next( 'input').attr( 'value','#' + startingColour); + + + }); + + jQuery( '.colorpicker').css( 'position', 'absolute').css( 'z-index', '9999' ); + + }, + + loadShortcodeDetails: function () { + if (wooSelectedShortcodeType) { + + var a = this; + jQuery.getScript(shortcode_generator_url + "shortcodes/" + wooSelectedShortcodeType + ".js", function () { + a.initializeDialog(); + + // Set the default content to the highlighted text, for certain shortcode types. + switch ( wooSelectedShortcodeType ) { + + case 'box': + case 'ilink': + case 'quote': + case 'button': + case 'abbr': + case 'unordered_list': + case 'ordered_list': + case 'typography': + + jQuery( 'input#woo-value-content').val( selectedText ); + + case 'toggle': + + jQuery( 'textarea#woo-value-content').val( selectedText ); + + break; + + } // End SWITCH Statement + + // Automatic preview generation on load. + a.previewAction(); + }) + + } + + }, + initializeDialog: function () { + + if (typeof wooShortcodeMeta == "undefined") { + jQuery( "#woo-options").append( "

    Error loading details for shortcode: " + wooSelectedShortcodeType + "

    " ); + } else { + if (wooShortcodeMeta.disablePreview) { + jQuery( "#woo-preview").remove(); + jQuery( "#woo-btn-preview").remove() + } + var a = wooShortcodeMeta.attributes, + b = jQuery( "#woo-options-table" ); + + for (var c in a) { + var f = "woo-value-" + a[c].id, + d = a[c].isRequired ? "woo-required" : "", + g = jQuery( '' ); + + var requiredSpan = ''; + + if (a[c].isRequired) { + + requiredSpan = '*'; + + } // End IF Statement + jQuery( "
    \n"); + $the_editor_content = apply_filters('the_editor_content', $content); + + printf($the_editor, $the_editor_content); + +?> + + '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below) + 'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number + 'total' => 1, + 'current' => 0, + 'show_all' => false, + 'prev_next' => true, + 'prev_text' => __('« Previous'), + 'next_text' => __('Next »'), + 'end_size' => 1, + 'mid_size' => 2, + 'type' => 'plain', + 'add_args' => false, // array of query args to add + 'add_fragment' => '' + ); + + $args = wp_parse_args( $args, $defaults ); + extract($args, EXTR_SKIP); + + // Who knows what else people pass in $args + $total = (int) $total; + if ( $total < 2 ) + return; + $current = (int) $current; + $end_size = 0 < (int) $end_size ? (int) $end_size : 1; // Out of bounds? Make it the default. + $mid_size = 0 <= (int) $mid_size ? (int) $mid_size : 2; + $add_args = is_array($add_args) ? $add_args : false; + $r = ''; + $page_links = array(); + $n = 0; + $dots = false; + + if ( $prev_next && $current && 1 < $current ) : + $link = str_replace('%_%', 2 == $current ? '' : $format, $base); + $link = str_replace('%#%', $current - 1, $link); + if ( $add_args ) + $link = add_query_arg( $add_args, $link ); + $link .= $add_fragment; + $page_links[] = ""; + endif; + for ( $n = 1; $n <= $total; $n++ ) : + $n_display = number_format_i18n($n); + if ( $n == $current ) : + $page_links[] = "$n_display"; + $dots = true; + else : + if ( $show_all || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) : + $link = str_replace('%_%', 1 == $n ? '' : $format, $base); + $link = str_replace('%#%', $n, $link); + if ( $add_args ) + $link = add_query_arg( $add_args, $link ); + $link .= $add_fragment; + $page_links[] = "$n_display"; + $dots = true; + elseif ( $dots && !$show_all ) : + $page_links[] = "..."; + $dots = false; + endif; + endif; + endfor; + if ( $prev_next && $current && ( $current < $total || -1 == $total ) ) : + $link = str_replace('%_%', $format, $base); + $link = str_replace('%#%', $current + 1, $link); + if ( $add_args ) + $link = add_query_arg( $add_args, $link ); + $link .= $add_fragment; + $page_links[] = ""; + endif; + switch ( $type ) : + case 'array' : + return $page_links; + break; + case 'list' : + $r .= "
      \n\t
    • "; + $r .= join("
    • \n\t
    • ", $page_links); + $r .= "
    • \n
    \n"; + break; + default : + $r = join("\n", $page_links); + break; + endswitch; + return $r; +} + +/** + * Registers an admin colour scheme css file. + * + * Allows a plugin to register a new admin colour scheme. For example: + * + * wp_admin_css_color('classic', __('Classic'), admin_url("css/colors-classic.css"), + * array('#07273E', '#14568A', '#D54E21', '#2683AE')); + * + * + * @since 2.5.0 + * + * @param string $key The unique key for this theme. + * @param string $name The name of the theme. + * @param string $url The url of the css file containing the colour scheme. + * @param array $colors Optional An array of CSS color definitions which are used to give the user a feel for the theme. + */ +function wp_admin_css_color($key, $name, $url, $colors = array()) { + global $_wp_admin_css_colors; + + if ( !isset($_wp_admin_css_colors) ) + $_wp_admin_css_colors = array(); + + $_wp_admin_css_colors[$key] = (object) array('name' => $name, 'url' => $url, 'colors' => $colors); +} + +/** + * Registers the default Admin color schemes + * + * @since 3.0.0 + */ +function register_admin_color_schemes() { + wp_admin_css_color( 'classic', __( 'Blue' ), admin_url( 'css/colors-classic.css' ), + array( '#5589aa', '#cfdfe9', '#d1e5ee', '#eff8ff' ) ); + wp_admin_css_color( 'fresh', __( 'Gray' ), admin_url( 'css/colors-fresh.css' ), + array( '#7c7976', '#c6c6c6', '#e0e0e0', '#f1f1f1' ) ); +} + +/** + * Display the URL of a WordPress admin CSS file. + * + * @see WP_Styles::_css_href and its style_loader_src filter. + * + * @since 2.3.0 + * + * @param string $file file relative to wp-admin/ without its ".css" extension. + */ +function wp_admin_css_uri( $file = 'wp-admin' ) { + if ( defined('WP_INSTALLING') ) { + $_file = "./$file.css"; + } else { + $_file = admin_url("$file.css"); + } + $_file = add_query_arg( 'version', get_bloginfo( 'version' ), $_file ); + + return apply_filters( 'wp_admin_css_uri', $_file, $file ); +} + +/** + * Enqueues or directly prints a stylesheet link to the specified CSS file. + * + * "Intelligently" decides to enqueue or to print the CSS file. If the + * 'wp_print_styles' action has *not* yet been called, the CSS file will be + * enqueued. If the wp_print_styles action *has* been called, the CSS link will + * be printed. Printing may be forced by passing TRUE as the $force_echo + * (second) parameter. + * + * For backward compatibility with WordPress 2.3 calling method: If the $file + * (first) parameter does not correspond to a registered CSS file, we assume + * $file is a file relative to wp-admin/ without its ".css" extension. A + * stylesheet link to that generated URL is printed. + * + * @package WordPress + * @since 2.3.0 + * @uses $wp_styles WordPress Styles Object + * + * @param string $file Optional. Style handle name or file name (without ".css" extension) relative + * to wp-admin/. Defaults to 'wp-admin'. + * @param bool $force_echo Optional. Force the stylesheet link to be printed rather than enqueued. + */ +function wp_admin_css( $file = 'wp-admin', $force_echo = false ) { + global $wp_styles; + if ( !is_a($wp_styles, 'WP_Styles') ) + $wp_styles = new WP_Styles(); + + // For backward compatibility + $handle = 0 === strpos( $file, 'css/' ) ? substr( $file, 4 ) : $file; + + if ( $wp_styles->query( $handle ) ) { + if ( $force_echo || did_action( 'wp_print_styles' ) ) // we already printed the style queue. Print this one immediately + wp_print_styles( $handle ); + else // Add to style queue + wp_enqueue_style( $handle ); + return; + } + + echo apply_filters( 'wp_admin_css', "\n", $file ); + if ( is_rtl() ) + echo apply_filters( 'wp_admin_css', "\n", "$file-rtl" ); +} + +/** + * Enqueues the default ThickBox js and css. + * + * If any of the settings need to be changed, this can be done with another js + * file similar to media-upload.js and theme-preview.js. That file should + * require array('thickbox') to ensure it is loaded after. + * + * @since 2.5.0 + */ +function add_thickbox() { + wp_enqueue_script( 'thickbox' ); + wp_enqueue_style( 'thickbox' ); + + if ( is_network_admin() ) + add_action( 'admin_head', '_thickbox_path_admin_subfolder' ); +} + +/** + * Display the XHTML generator that is generated on the wp_head hook. + * + * @since 2.5.0 + */ +function wp_generator() { + the_generator( apply_filters( 'wp_generator_type', 'xhtml' ) ); +} + +/** + * Display the generator XML or Comment for RSS, ATOM, etc. + * + * Returns the correct generator type for the requested output format. Allows + * for a plugin to filter generators overall the the_generator filter. + * + * @since 2.5.0 + * @uses apply_filters() Calls 'the_generator' hook. + * + * @param string $type The type of generator to output - (html|xhtml|atom|rss2|rdf|comment|export). + */ +function the_generator( $type ) { + echo apply_filters('the_generator', get_the_generator($type), $type) . "\n"; +} + +/** + * Creates the generator XML or Comment for RSS, ATOM, etc. + * + * Returns the correct generator type for the requested output format. Allows + * for a plugin to filter generators on an individual basis using the + * 'get_the_generator_{$type}' filter. + * + * @since 2.5.0 + * @uses apply_filters() Calls 'get_the_generator_$type' hook. + * + * @param string $type The type of generator to return - (html|xhtml|atom|rss2|rdf|comment|export). + * @return string The HTML content for the generator. + */ +function get_the_generator( $type = '' ) { + if ( empty( $type ) ) { + + $current_filter = current_filter(); + if ( empty( $current_filter ) ) + return; + + switch ( $current_filter ) { + case 'rss2_head' : + case 'commentsrss2_head' : + $type = 'rss2'; + break; + case 'rss_head' : + case 'opml_head' : + $type = 'comment'; + break; + case 'rdf_header' : + $type = 'rdf'; + break; + case 'atom_head' : + case 'comments_atom_head' : + case 'app_head' : + $type = 'atom'; + break; + } + } + + switch ( $type ) { + case 'html': + $gen = ''; + break; + case 'xhtml': + $gen = ''; + break; + case 'atom': + $gen = 'WordPress'; + break; + case 'rss2': + $gen = 'http://wordpress.org/?v=' . get_bloginfo_rss( 'version' ) . ''; + break; + case 'rdf': + $gen = ''; + break; + case 'comment': + $gen = ''; + break; + case 'export': + $gen = ''; + break; + } + return apply_filters( "get_the_generator_{$type}", $gen, $type ); +} + +/** + * Outputs the html checked attribute. + * + * Compares the first two arguments and if identical marks as checked + * + * @since 1.0.0 + * + * @param mixed $checked One of the values to compare + * @param mixed $current (true) The other value to compare if not just true + * @param bool $echo Whether to echo or just return the string + * @return string html attribute or empty string + */ +function checked( $checked, $current = true, $echo = true ) { + return __checked_selected_helper( $checked, $current, $echo, 'checked' ); +} + +/** + * Outputs the html selected attribute. + * + * Compares the first two arguments and if identical marks as selected + * + * @since 1.0.0 + * + * @param mixed $selected One of the values to compare + * @param mixed $current (true) The other value to compare if not just true + * @param bool $echo Whether to echo or just return the string + * @return string html attribute or empty string + */ +function selected( $selected, $current = true, $echo = true ) { + return __checked_selected_helper( $selected, $current, $echo, 'selected' ); +} + +/** + * Outputs the html disabled attribute. + * + * Compares the first two arguments and if identical marks as disabled + * + * @since 3.0.0 + * + * @param mixed $disabled One of the values to compare + * @param mixed $current (true) The other value to compare if not just true + * @param bool $echo Whether to echo or just return the string + * @return string html attribute or empty string + */ +function disabled( $disabled, $current = true, $echo = true ) { + return __checked_selected_helper( $disabled, $current, $echo, 'disabled' ); +} + +/** + * Private helper function for checked, selected, and disabled. + * + * Compares the first two arguments and if identical marks as $type + * + * @since 2.8.0 + * @access private + * + * @param any $helper One of the values to compare + * @param any $current (true) The other value to compare if not just true + * @param bool $echo Whether to echo or just return the string + * @param string $type The type of checked|selected|disabled we are doing + * @return string html attribute or empty string + */ +function __checked_selected_helper( $helper, $current, $echo, $type ) { + if ( (string) $helper === (string) $current ) + $result = " $type='$type'"; + else + $result = ''; + + if ( $echo ) + echo $result; + + return $result; +} + +?> diff --git a/src/wp-includes/http.php b/src/wp-includes/http.php new file mode 100644 index 00000000..63cf97d1 --- /dev/null +++ b/src/wp-includes/http.php @@ -0,0 +1,194 @@ + + * $res = array( 'headers' => array(), 'response' => array('code' => int, 'message' => string) ); + * + * + * All of the headers in $res['headers'] are with the name as the key and the + * value as the value. So to get the User-Agent, you would do the following. + * + * + * $user_agent = $res['headers']['user-agent']; + * + * + * The body is the raw response content and can be retrieved from $res['body']. + * + * This function is called first to make the request and there are other API + * functions to abstract out the above convoluted setup. + * + * @since 2.7.0 + * + * @param string $url Site URL to retrieve. + * @param array $args Optional. Override the defaults. + * @return WP_Error|array The response or WP_Error on failure. + */ +function wp_remote_request($url, $args = array()) { + $objFetchSite = _wp_http_get_object(); + return $objFetchSite->request($url, $args); +} + +/** + * Retrieve the raw response from the HTTP request using the GET method. + * + * @see wp_remote_request() For more information on the response array format. + * + * @since 2.7.0 + * + * @param string $url Site URL to retrieve. + * @param array $args Optional. Override the defaults. + * @return WP_Error|array The response or WP_Error on failure. + */ +function wp_remote_get($url, $args = array()) { + $objFetchSite = _wp_http_get_object(); + return $objFetchSite->get($url, $args); +} + +/** + * Retrieve the raw response from the HTTP request using the POST method. + * + * @see wp_remote_request() For more information on the response array format. + * + * @since 2.7.0 + * + * @param string $url Site URL to retrieve. + * @param array $args Optional. Override the defaults. + * @return WP_Error|array The response or WP_Error on failure. + */ +function wp_remote_post($url, $args = array()) { + $objFetchSite = _wp_http_get_object(); + return $objFetchSite->post($url, $args); +} + +/** + * Retrieve the raw response from the HTTP request using the HEAD method. + * + * @see wp_remote_request() For more information on the response array format. + * + * @since 2.7.0 + * + * @param string $url Site URL to retrieve. + * @param array $args Optional. Override the defaults. + * @return WP_Error|array The response or WP_Error on failure. + */ +function wp_remote_head($url, $args = array()) { + $objFetchSite = _wp_http_get_object(); + return $objFetchSite->head($url, $args); +} + +/** + * Retrieve only the headers from the raw response. + * + * @since 2.7.0 + * + * @param array $response HTTP response. + * @return array The headers of the response. Empty array if incorrect parameter given. + */ +function wp_remote_retrieve_headers(&$response) { + if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers'])) + return array(); + + return $response['headers']; +} + +/** + * Retrieve a single header by name from the raw response. + * + * @since 2.7.0 + * + * @param array $response + * @param string $header Header name to retrieve value from. + * @return string The header value. Empty string on if incorrect parameter given, or if the header doesnt exist. + */ +function wp_remote_retrieve_header(&$response, $header) { + if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers'])) + return ''; + + if ( array_key_exists($header, $response['headers']) ) + return $response['headers'][$header]; + + return ''; +} + +/** + * Retrieve only the response code from the raw response. + * + * Will return an empty array if incorrect parameter value is given. + * + * @since 2.7.0 + * + * @param array $response HTTP response. + * @return string the response code. Empty string on incorrect parameter given. + */ +function wp_remote_retrieve_response_code(&$response) { + if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response'])) + return ''; + + return $response['response']['code']; +} + +/** + * Retrieve only the response message from the raw response. + * + * Will return an empty array if incorrect parameter value is given. + * + * @since 2.7.0 + * + * @param array $response HTTP response. + * @return string The response message. Empty string on incorrect parameter given. + */ +function wp_remote_retrieve_response_message(&$response) { + if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response'])) + return ''; + + return $response['response']['message']; +} + +/** + * Retrieve only the body from the raw response. + * + * @since 2.7.0 + * + * @param array $response HTTP response. + * @return string The body of the response. Empty string if no body or incorrect parameter given. + */ +function wp_remote_retrieve_body(&$response) { + if ( is_wp_error($response) || ! isset($response['body']) ) + return ''; + + return $response['body']; +} + +?> \ No newline at end of file diff --git a/src/wp-includes/images/admin-bar-sprite-rtl.png b/src/wp-includes/images/admin-bar-sprite-rtl.png new file mode 100644 index 00000000..f49aae7a Binary files /dev/null and b/src/wp-includes/images/admin-bar-sprite-rtl.png differ diff --git a/src/wp-includes/images/admin-bar-sprite.png b/src/wp-includes/images/admin-bar-sprite.png new file mode 100644 index 00000000..8eb1c085 Binary files /dev/null and b/src/wp-includes/images/admin-bar-sprite.png differ diff --git a/src/wp-includes/images/blank.gif b/src/wp-includes/images/blank.gif new file mode 100644 index 00000000..e565824a Binary files /dev/null and b/src/wp-includes/images/blank.gif differ diff --git a/src/wp-includes/images/crystal/archive.png b/src/wp-includes/images/crystal/archive.png new file mode 100644 index 00000000..670648a2 Binary files /dev/null and b/src/wp-includes/images/crystal/archive.png differ diff --git a/src/wp-includes/images/crystal/audio.png b/src/wp-includes/images/crystal/audio.png new file mode 100644 index 00000000..5a3d4d3a Binary files /dev/null and b/src/wp-includes/images/crystal/audio.png differ diff --git a/src/wp-includes/images/crystal/code.png b/src/wp-includes/images/crystal/code.png new file mode 100644 index 00000000..b67c6005 Binary files /dev/null and b/src/wp-includes/images/crystal/code.png differ diff --git a/src/wp-includes/images/crystal/default.png b/src/wp-includes/images/crystal/default.png new file mode 100644 index 00000000..b1bbbc7b Binary files /dev/null and b/src/wp-includes/images/crystal/default.png differ diff --git a/src/wp-includes/images/crystal/document.png b/src/wp-includes/images/crystal/document.png new file mode 100644 index 00000000..3295ccd3 Binary files /dev/null and b/src/wp-includes/images/crystal/document.png differ diff --git a/src/wp-includes/images/crystal/interactive.png b/src/wp-includes/images/crystal/interactive.png new file mode 100644 index 00000000..fd6de7d7 Binary files /dev/null and b/src/wp-includes/images/crystal/interactive.png differ diff --git a/src/wp-includes/images/crystal/license.txt b/src/wp-includes/images/crystal/license.txt new file mode 100644 index 00000000..cdabd2fd --- /dev/null +++ b/src/wp-includes/images/crystal/license.txt @@ -0,0 +1,9 @@ +Crystal Project Icons +by Everaldo Coelho +http://everaldo.com + +Released under LGPL + +Modified February 2008 +for WordPress +http://wordpress.org \ No newline at end of file diff --git a/src/wp-includes/images/crystal/spreadsheet.png b/src/wp-includes/images/crystal/spreadsheet.png new file mode 100644 index 00000000..f2c4d309 Binary files /dev/null and b/src/wp-includes/images/crystal/spreadsheet.png differ diff --git a/src/wp-includes/images/crystal/text.png b/src/wp-includes/images/crystal/text.png new file mode 100644 index 00000000..feaed5b4 Binary files /dev/null and b/src/wp-includes/images/crystal/text.png differ diff --git a/src/wp-includes/images/crystal/video.png b/src/wp-includes/images/crystal/video.png new file mode 100644 index 00000000..e1b879d6 Binary files /dev/null and b/src/wp-includes/images/crystal/video.png differ diff --git a/src/wp-includes/images/rss.png b/src/wp-includes/images/rss.png new file mode 100644 index 00000000..6e7b676b Binary files /dev/null and b/src/wp-includes/images/rss.png differ diff --git a/src/wp-includes/images/smilies/icon_arrow.gif b/src/wp-includes/images/smilies/icon_arrow.gif new file mode 100644 index 00000000..2880055c Binary files /dev/null and b/src/wp-includes/images/smilies/icon_arrow.gif differ diff --git a/src/wp-includes/images/smilies/icon_biggrin.gif b/src/wp-includes/images/smilies/icon_biggrin.gif new file mode 100644 index 00000000..d3527723 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_biggrin.gif differ diff --git a/src/wp-includes/images/smilies/icon_confused.gif b/src/wp-includes/images/smilies/icon_confused.gif new file mode 100644 index 00000000..0c49e069 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_confused.gif differ diff --git a/src/wp-includes/images/smilies/icon_cool.gif b/src/wp-includes/images/smilies/icon_cool.gif new file mode 100644 index 00000000..cead0306 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_cool.gif differ diff --git a/src/wp-includes/images/smilies/icon_cry.gif b/src/wp-includes/images/smilies/icon_cry.gif new file mode 100644 index 00000000..7d54b1f9 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_cry.gif differ diff --git a/src/wp-includes/images/smilies/icon_eek.gif b/src/wp-includes/images/smilies/icon_eek.gif new file mode 100644 index 00000000..5d397810 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_eek.gif differ diff --git a/src/wp-includes/images/smilies/icon_evil.gif b/src/wp-includes/images/smilies/icon_evil.gif new file mode 100644 index 00000000..ab1aa8e1 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_evil.gif differ diff --git a/src/wp-includes/images/smilies/icon_exclaim.gif b/src/wp-includes/images/smilies/icon_exclaim.gif new file mode 100644 index 00000000..6e50e2ee Binary files /dev/null and b/src/wp-includes/images/smilies/icon_exclaim.gif differ diff --git a/src/wp-includes/images/smilies/icon_idea.gif b/src/wp-includes/images/smilies/icon_idea.gif new file mode 100644 index 00000000..a40ae0d7 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_idea.gif differ diff --git a/src/wp-includes/images/smilies/icon_lol.gif b/src/wp-includes/images/smilies/icon_lol.gif new file mode 100644 index 00000000..374ba150 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_lol.gif differ diff --git a/src/wp-includes/images/smilies/icon_mad.gif b/src/wp-includes/images/smilies/icon_mad.gif new file mode 100644 index 00000000..1f6c3c2f Binary files /dev/null and b/src/wp-includes/images/smilies/icon_mad.gif differ diff --git a/src/wp-includes/images/smilies/icon_mrgreen.gif b/src/wp-includes/images/smilies/icon_mrgreen.gif new file mode 100644 index 00000000..b54cd0f9 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_mrgreen.gif differ diff --git a/src/wp-includes/images/smilies/icon_neutral.gif b/src/wp-includes/images/smilies/icon_neutral.gif new file mode 100644 index 00000000..4f311567 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_neutral.gif differ diff --git a/src/wp-includes/images/smilies/icon_question.gif b/src/wp-includes/images/smilies/icon_question.gif new file mode 100644 index 00000000..9d072265 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_question.gif differ diff --git a/src/wp-includes/images/smilies/icon_razz.gif b/src/wp-includes/images/smilies/icon_razz.gif new file mode 100644 index 00000000..29da2a2f Binary files /dev/null and b/src/wp-includes/images/smilies/icon_razz.gif differ diff --git a/src/wp-includes/images/smilies/icon_redface.gif b/src/wp-includes/images/smilies/icon_redface.gif new file mode 100644 index 00000000..ad762832 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_redface.gif differ diff --git a/src/wp-includes/images/smilies/icon_rolleyes.gif b/src/wp-includes/images/smilies/icon_rolleyes.gif new file mode 100644 index 00000000..d7f5f2f4 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_rolleyes.gif differ diff --git a/src/wp-includes/images/smilies/icon_sad.gif b/src/wp-includes/images/smilies/icon_sad.gif new file mode 100644 index 00000000..d2ac78c0 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_sad.gif differ diff --git a/src/wp-includes/images/smilies/icon_smile.gif b/src/wp-includes/images/smilies/icon_smile.gif new file mode 100644 index 00000000..7b1f6d30 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_smile.gif differ diff --git a/src/wp-includes/images/smilies/icon_surprised.gif b/src/wp-includes/images/smilies/icon_surprised.gif new file mode 100644 index 00000000..cb214243 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_surprised.gif differ diff --git a/src/wp-includes/images/smilies/icon_twisted.gif b/src/wp-includes/images/smilies/icon_twisted.gif new file mode 100644 index 00000000..502fe247 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_twisted.gif differ diff --git a/src/wp-includes/images/smilies/icon_wink.gif b/src/wp-includes/images/smilies/icon_wink.gif new file mode 100644 index 00000000..d1482880 Binary files /dev/null and b/src/wp-includes/images/smilies/icon_wink.gif differ diff --git a/src/wp-includes/images/upload.png b/src/wp-includes/images/upload.png new file mode 100644 index 00000000..8ca02d7c Binary files /dev/null and b/src/wp-includes/images/upload.png differ diff --git a/src/wp-includes/images/wlw/wp-comments.png b/src/wp-includes/images/wlw/wp-comments.png new file mode 100644 index 00000000..981b1af5 Binary files /dev/null and b/src/wp-includes/images/wlw/wp-comments.png differ diff --git a/src/wp-includes/images/wlw/wp-icon.png b/src/wp-includes/images/wlw/wp-icon.png new file mode 100644 index 00000000..cd94ee3b Binary files /dev/null and b/src/wp-includes/images/wlw/wp-icon.png differ diff --git a/src/wp-includes/images/wlw/wp-watermark.png b/src/wp-includes/images/wlw/wp-watermark.png new file mode 100644 index 00000000..c312a725 Binary files /dev/null and b/src/wp-includes/images/wlw/wp-watermark.png differ diff --git a/src/wp-includes/images/wpmini-blue.png b/src/wp-includes/images/wpmini-blue.png new file mode 100644 index 00000000..13f3fa64 Binary files /dev/null and b/src/wp-includes/images/wpmini-blue.png differ diff --git a/src/wp-includes/js/admin-bar.dev.js b/src/wp-includes/js/admin-bar.dev.js new file mode 100644 index 00000000..cf13ca72 --- /dev/null +++ b/src/wp-includes/js/admin-bar.dev.js @@ -0,0 +1,140 @@ +(function(d, w) { + var addEvent = function( obj, type, fn ) { + if (obj.addEventListener) + obj.addEventListener(type, fn, false); + else if (obj.attachEvent) + obj.attachEvent('on' + type, function() { return fn.call(obj, window.event);}); + }, + + aB, hc = new RegExp('\\bhover\\b', 'g'), q = [], + rselected = new RegExp('\\bselected\\b', 'g'), + + /** + * Get the timeout ID of the given element + */ + getTOID = function(el) { + var i = q.length; + while( i-- ) + if ( q[i] && el == q[i][1] ) + return q[i][0]; + return false; + }, + + addHoverClass = function(t) { + var i, id, inA, hovering, ul, li, + ancestors = [], + ancestorLength = 0; + + while ( t && t != aB && t != d ) { + if( 'LI' == t.nodeName.toUpperCase() ) { + ancestors[ ancestors.length ] = t; + id = getTOID(t); + if ( id ) + clearTimeout( id ); + t.className = t.className ? ( t.className.replace(hc, '') + ' hover' ) : 'hover'; + hovering = t; + } + t = t.parentNode; + } + + // Remove any selected classes. + if ( hovering && hovering.parentNode ) { + ul = hovering.parentNode; + if ( ul && 'UL' == ul.nodeName.toUpperCase() ) { + i = ul.childNodes.length; + while ( i-- ) { + li = ul.childNodes[i]; + if ( li != hovering ) + li.className = li.className ? li.className.replace( rselected, '' ) : ''; + } + } + } + + /* remove the hover class for any objects not in the immediate element's ancestry */ + i = q.length; + while ( i-- ) { + inA = false; + ancestorLength = ancestors.length; + while( ancestorLength-- ) { + if ( ancestors[ ancestorLength ] == q[i][1] ) + inA = true; + } + + if ( ! inA ) + q[i][1].className = q[i][1].className ? q[i][1].className.replace(hc, '') : ''; + } + }, + + removeHoverClass = function(t) { + while ( t && t != aB && t != d ) { + if( 'LI' == t.nodeName.toUpperCase() ) { + (function(t) { + var to = setTimeout(function() { + t.className = t.className ? t.className.replace(hc, '') : ''; + }, 500); + q[q.length] = [to, t]; + })(t); + } + t = t.parentNode; + } + }, + + clickShortlink = function(e) { + var i, l, node, + t = e.target || e.srcElement; + + // Make t the shortlink menu item, or return. + while ( true ) { + // Check if we've gone past the shortlink node, + // or if the user is clicking on the input. + if ( ! t || t == d || t == aB ) + return; + // Check if we've found the shortlink node. + if ( t.id && t.id == 'wp-admin-bar-get-shortlink' ) + break; + t = t.parentNode; + } + + // IE doesn't support preventDefault, and does support returnValue + if ( e.preventDefault ) + e.preventDefault(); + e.returnValue = false; + + if ( -1 == t.className.indexOf('selected') ) + t.className += ' selected'; + + for ( i = 0, l = t.childNodes.length; i < l; i++ ) { + node = t.childNodes[i]; + if ( node.className && -1 != node.className.indexOf('shortlink-input') ) { + node.focus(); + node.select(); + node.onblur = function() { + t.className = t.className ? t.className.replace( rselected, '' ) : ''; + }; + break; + } + } + return false; + }; + + addEvent(w, 'load', function() { + aB = d.getElementById('wpadminbar'); + + if ( d.body && aB ) { + d.body.appendChild( aB ); + + addEvent(aB, 'mouseover', function(e) { + addHoverClass( e.target || e.srcElement ); + }); + + addEvent(aB, 'mouseout', function(e) { + removeHoverClass( e.target || e.srcElement ); + }); + + addEvent(aB, 'click', clickShortlink ); + } + + if ( w.location.hash ) + w.scrollBy(0,-32); + }); +})(document, window); diff --git a/src/wp-includes/js/admin-bar.js b/src/wp-includes/js/admin-bar.js new file mode 100644 index 00000000..ea90a69f --- /dev/null +++ b/src/wp-includes/js/admin-bar.js @@ -0,0 +1 @@ +(function(i,k){var c=function(n,m,d){if(n.addEventListener){n.addEventListener(m,d,false)}else{if(n.attachEvent){n.attachEvent("on"+m,function(){return d.call(n,window.event)})}}},e,f=new RegExp("\\bhover\\b","g"),a=[],j=new RegExp("\\bselected\\b","g"),g=function(m){var d=a.length;while(d--){if(a[d]&&m==a[d][1]){return a[d][0]}}return false},h=function(s){var n,d,q,m,p,r,u=[],o=0;while(s&&s!=e&&s!=i){if("LI"==s.nodeName.toUpperCase()){u[u.length]=s;d=g(s);if(d){clearTimeout(d)}s.className=s.className?(s.className.replace(f,"")+" hover"):"hover";m=s}s=s.parentNode}if(m&&m.parentNode){p=m.parentNode;if(p&&"UL"==p.nodeName.toUpperCase()){n=p.childNodes.length;while(n--){r=p.childNodes[n];if(r!=m){r.className=r.className?r.className.replace(j,""):""}}}}n=a.length;while(n--){q=false;o=u.length;while(o--){if(u[o]==a[n][1]){q=true}}if(!q){a[n][1].className=a[n][1].className?a[n][1].className.replace(f,""):""}}},l=function(d){while(d&&d!=e&&d!=i){if("LI"==d.nodeName.toUpperCase()){(function(m){var n=setTimeout(function(){m.className=m.className?m.className.replace(f,""):""},500);a[a.length]=[n,m]})(d)}d=d.parentNode}},b=function(p){var n,d,o,m=p.target||p.srcElement;while(true){if(!m||m==i||m==e){return}if(m.id&&m.id=="wp-admin-bar-get-shortlink"){break}m=m.parentNode}if(p.preventDefault){p.preventDefault()}p.returnValue=false;if(-1==m.className.indexOf("selected")){m.className+=" selected"}for(n=0,d=m.childNodes.length;n 0) ) { autosave(); } + if ( tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() && dotabkey ) { + e.preventDefault(); + dotabkey = false; + tinyMCE.activeEditor.focus(); + return false; + } + } + }); + } + + // autosave new posts after a title is typed but not if Publish or Save Draft is clicked + if ( '1' == $('#auto_draft').val() ) { + $('#title').blur( function() { + if ( !this.value || $('#auto_draft').val() != '1' ) + return; + delayed_autosave(); + }); + } +}); + +function autosave_parse_response(response) { + var res = wpAjax.parseAjaxResponse(response, 'autosave'), message = '', postID, sup, url; + + if ( res && res.responses && res.responses.length ) { + message = res.responses[0].data; // The saved message or error. + // someone else is editing: disable autosave, set errors + if ( res.responses[0].supplemental ) { + sup = res.responses[0].supplemental; + if ( 'disable' == sup['disable_autosave'] ) { + autosave = function() {}; + res = { errors: true }; + } + if ( sup['session_expired'] && (url = sup['session_expired']) ) { + if ( !interimLogin || interimLogin.closed ) { + interimLogin = window.open(url, 'login', 'width=600,height=450,resizable=yes,scrollbars=yes,status=yes'); + interimLogin.focus(); + } + delete sup['session_expired']; + } + jQuery.each(sup, function(selector, value) { + if ( selector.match(/^replace-/) ) { + jQuery('#'+selector.replace('replace-', '')).val(value); + } + }); + } + + // if no errors: add slug UI + if ( !res.errors ) { + postID = parseInt( res.responses[0].id, 10 ); + if ( !isNaN(postID) && postID > 0 ) { + autosave_update_slug(postID); + } + } + } + if ( message ) { jQuery('#autosave').html(message); } // update autosave message + else if ( autosaveOldMessage && res ) { jQuery('#autosave').html( autosaveOldMessage ); } + return res; +} + +// called when autosaving pre-existing post +function autosave_saved(response) { + blockSave = false; + autosave_parse_response(response); // parse the ajax response + autosave_enable_buttons(); // re-enable disabled form buttons +} + +// called when autosaving new post +function autosave_saved_new(response) { + blockSave = false; + var res = autosave_parse_response(response), tempID, postID; + if ( res && res.responses.length && !res.errors ) { + // An ID is sent only for real auto-saves, not for autosave=0 "keepalive" saves + postID = parseInt( res.responses[0].id, 10 ); + if ( !isNaN(postID) && postID > 0 ) { + notSaved = false; + jQuery('#auto_draft').val('0'); // No longer an auto-draft + } + autosave_enable_buttons(); + if ( autosaveDelayPreview ) { + autosaveDelayPreview = false; + doPreview(); + } + } else { + autosave_enable_buttons(); // re-enable disabled form buttons + } +} + +function autosave_update_slug(post_id) { + // create slug area only if not already there + if ( 'undefined' != makeSlugeditClickable && jQuery.isFunction(makeSlugeditClickable) && !jQuery('#edit-slug-box > *').size() ) { + jQuery.post( + ajaxurl, + { + action: 'sample-permalink', + post_id: post_id, + new_title: jQuery('#title').val(), + samplepermalinknonce: jQuery('#samplepermalinknonce').val() + }, + function(data) { + jQuery('#edit-slug-box').html(data); + makeSlugeditClickable(); + } + ); + } +} + +function autosave_loading() { + jQuery('#autosave').html(autosaveL10n.savingText); +} + +function autosave_enable_buttons() { + // delay that a bit to avoid some rare collisions while the DOM is being updated. + setTimeout(function(){ + jQuery(':button, :submit', '#submitpost').removeAttr('disabled'); + jQuery('.ajax-loading').css('visibility', 'hidden'); + }, 500); +} + +function autosave_disable_buttons() { + jQuery(':button, :submit', '#submitpost').attr('disabled', 'disabled'); + // Re-enable 5 sec later. Just gives autosave a head start to avoid collisions. + setTimeout(autosave_enable_buttons, 5000); +} + +function delayed_autosave() { + setTimeout(function(){ + if ( blockSave ) + return; + autosave(); + }, 200); +} + +autosave = function() { + // (bool) is rich editor enabled and active + blockSave = true; + var rich = (typeof tinyMCE != "undefined") && tinyMCE.activeEditor && !tinyMCE.activeEditor.isHidden(), post_data, doAutoSave, ed, origStatus, successCallback; + + autosave_disable_buttons(); + + post_data = { + action: "autosave", + post_ID: jQuery("#post_ID").val() || 0, + post_title: jQuery("#title").val() || "", + autosavenonce: jQuery('#autosavenonce').val(), + post_type: jQuery('#post_type').val() || "", + autosave: 1 + }; + + jQuery('.tags-input').each( function() { + post_data[this.name] = this.value; + } ); + + // We always send the ajax request in order to keep the post lock fresh. + // This (bool) tells whether or not to write the post to the DB during the ajax request. + doAutoSave = true; + + // No autosave while thickbox is open (media buttons) + if ( jQuery("#TB_window").css('display') == 'block' ) + doAutoSave = false; + + /* Gotta do this up here so we can check the length when tinyMCE is in use */ + if ( rich && doAutoSave ) { + ed = tinyMCE.activeEditor; + // Don't run while the TinyMCE spellcheck is on. It resets all found words. + if ( ed.plugins.spellchecker && ed.plugins.spellchecker.active ) { + doAutoSave = false; + } else { + if ( 'mce_fullscreen' == ed.id ) + tinyMCE.get('content').setContent(ed.getContent({format : 'raw'}), {format : 'raw'}); + tinyMCE.get('content').save(); + } + } + + post_data["content"] = jQuery("#content").val(); + if ( jQuery('#post_name').val() ) + post_data["post_name"] = jQuery('#post_name').val(); + + // Nothing to save or no change. + if ( ( post_data["post_title"].length == 0 && post_data["content"].length == 0 ) || post_data["post_title"] + post_data["content"] == autosaveLast ) { + doAutoSave = false; + } + + origStatus = jQuery('#original_post_status').val(); + + goodcats = ([]); + jQuery("[name='post_category[]']:checked").each( function(i) { + goodcats.push(this.value); + } ); + post_data["catslist"] = goodcats.join(","); + + if ( jQuery("#comment_status").attr("checked") ) + post_data["comment_status"] = 'open'; + if ( jQuery("#ping_status").attr("checked") ) + post_data["ping_status"] = 'open'; + if ( jQuery("#excerpt").size() ) + post_data["excerpt"] = jQuery("#excerpt").val(); + if ( jQuery("#post_author").size() ) + post_data["post_author"] = jQuery("#post_author").val(); + if ( jQuery("#parent_id").val() ) + post_data["parent_id"] = jQuery("#parent_id").val(); + post_data["user_ID"] = jQuery("#user-id").val(); + if ( jQuery('#auto_draft').val() == '1' ) + post_data["auto_draft"] = '1'; + + if ( doAutoSave ) { + autosaveLast = jQuery("#title").val() + jQuery("#content").val(); + } else { + post_data['autosave'] = 0; + } + + if ( post_data["auto_draft"] == '1' ) { + successCallback = autosave_saved_new; // new post + } else { + successCallback = autosave_saved; // pre-existing post + } + + autosaveOldMessage = jQuery('#autosave').html(); + jQuery.ajax({ + data: post_data, + beforeSend: doAutoSave ? autosave_loading : null, + type: "POST", + url: autosaveL10n.requestFile, + success: successCallback + }); +} diff --git a/src/wp-includes/js/autosave.js b/src/wp-includes/js/autosave.js new file mode 100644 index 00000000..14529d9d --- /dev/null +++ b/src/wp-includes/js/autosave.js @@ -0,0 +1 @@ +var autosave,autosaveLast="",autosavePeriodical,autosaveOldMessage="",autosaveDelayPreview=false,notSaved=true,blockSave=false,interimLogin=false;jQuery(document).ready(function(b){var a=true;autosaveLast=b("#post #title").val()+b("#post #content").val();autosavePeriodical=b.schedule({time:autosaveL10n.autosaveInterval*1000,func:function(){autosave()},repeat:true,protect:true});b("#post").submit(function(){b.cancel(autosavePeriodical)});b('input[type="submit"], a.submitdelete',"#submitpost").click(function(){blockSave=true;window.onbeforeunload=null;b(":button, :submit","#submitpost").each(function(){var c=b(this);if(c.hasClass("button-primary")){c.addClass("button-primary-disabled")}else{c.addClass("button-disabled")}});if(b(this).attr("id")=="publish"){b("#ajax-loading").css("visibility","visible")}else{b("#draft-ajax-loading").css("visibility","visible")}});window.onbeforeunload=function(){var c=typeof(tinyMCE)!="undefined"?tinyMCE.activeEditor:false,e,d;if(c&&!c.isHidden()){if(c.isDirty()){return autosaveL10n.saveAlert}}else{e=b("#post #title").val(),d=b("#post #content").val();if((e||d)&&e+d!=autosaveLast){return autosaveL10n.saveAlert}}};b("#post-preview").click(function(){if(b("#auto_draft").val()=="1"&¬Saved){autosaveDelayPreview=true;autosave();return false}doPreview();return false});doPreview=function(){b("input#wp-preview").val("dopreview");b("form#post").attr("target","wp-preview").submit().attr("target","");b("input#wp-preview").val("")};if(typeof tinyMCE!="undefined"){b("#title")[b.browser.opera?"keypress":"keydown"](function(c){if(c.which==9&&!c.shiftKey&&!c.controlKey&&!c.altKey){if((b("#auto_draft").val()=="1")&&(b("#title").val().length>0)){autosave()}if(tinyMCE.activeEditor&&!tinyMCE.activeEditor.isHidden()&&a){c.preventDefault();a=false;tinyMCE.activeEditor.focus();return false}}})}if("1"==b("#auto_draft").val()){b("#title").blur(function(){if(!this.value||b("#auto_draft").val()!="1"){return}delayed_autosave()})}});function autosave_parse_response(c){var e=wpAjax.parseAjaxResponse(c,"autosave"),f="",a,b,d;if(e&&e.responses&&e.responses.length){f=e.responses[0].data;if(e.responses[0].supplemental){b=e.responses[0].supplemental;if("disable"==b.disable_autosave){autosave=function(){};e={errors:true}}if(b.session_expired&&(d=b.session_expired)){if(!interimLogin||interimLogin.closed){interimLogin=window.open(d,"login","width=600,height=450,resizable=yes,scrollbars=yes,status=yes");interimLogin.focus()}delete b.session_expired}jQuery.each(b,function(g,h){if(g.match(/^replace-/)){jQuery("#"+g.replace("replace-","")).val(h)}})}if(!e.errors){a=parseInt(e.responses[0].id,10);if(!isNaN(a)&&a>0){autosave_update_slug(a)}}}if(f){jQuery("#autosave").html(f)}else{if(autosaveOldMessage&&e){jQuery("#autosave").html(autosaveOldMessage)}}return e}function autosave_saved(a){blockSave=false;autosave_parse_response(a);autosave_enable_buttons()}function autosave_saved_new(b){blockSave=false;var d=autosave_parse_response(b),c,a;if(d&&d.responses.length&&!d.errors){a=parseInt(d.responses[0].id,10);if(!isNaN(a)&&a>0){notSaved=false;jQuery("#auto_draft").val("0")}autosave_enable_buttons();if(autosaveDelayPreview){autosaveDelayPreview=false;doPreview()}}else{autosave_enable_buttons()}}function autosave_update_slug(a){if("undefined"!=makeSlugeditClickable&&jQuery.isFunction(makeSlugeditClickable)&&!jQuery("#edit-slug-box > *").size()){jQuery.post(ajaxurl,{action:"sample-permalink",post_id:a,new_title:jQuery("#title").val(),samplepermalinknonce:jQuery("#samplepermalinknonce").val()},function(b){jQuery("#edit-slug-box").html(b);makeSlugeditClickable()})}}function autosave_loading(){jQuery("#autosave").html(autosaveL10n.savingText)}function autosave_enable_buttons(){setTimeout(function(){jQuery(":button, :submit","#submitpost").removeAttr("disabled");jQuery(".ajax-loading").css("visibility","hidden")},500)}function autosave_disable_buttons(){jQuery(":button, :submit","#submitpost").attr("disabled","disabled");setTimeout(autosave_enable_buttons,5000)}function delayed_autosave(){setTimeout(function(){if(blockSave){return}autosave()},200)}autosave=function(){blockSave=true;var c=(typeof tinyMCE!="undefined")&&tinyMCE.activeEditor&&!tinyMCE.activeEditor.isHidden(),d,f,b,e,a;autosave_disable_buttons();d={action:"autosave",post_ID:jQuery("#post_ID").val()||0,post_title:jQuery("#title").val()||"",autosavenonce:jQuery("#autosavenonce").val(),post_type:jQuery("#post_type").val()||"",autosave:1};jQuery(".tags-input").each(function(){d[this.name]=this.value});f=true;if(jQuery("#TB_window").css("display")=="block"){f=false}if(c&&f){b=tinyMCE.activeEditor;if(b.plugins.spellchecker&&b.plugins.spellchecker.active){f=false}else{if("mce_fullscreen"==b.id){tinyMCE.get("content").setContent(b.getContent({format:"raw"}),{format:"raw"})}tinyMCE.get("content").save()}}d.content=jQuery("#content").val();if(jQuery("#post_name").val()){d.post_name=jQuery("#post_name").val()}if((d.post_title.length==0&&d.content.length==0)||d.post_title+d.content==autosaveLast){f=false}e=jQuery("#original_post_status").val();goodcats=([]);jQuery("[name='post_category[]']:checked").each(function(g){goodcats.push(this.value)});d.catslist=goodcats.join(",");if(jQuery("#comment_status").attr("checked")){d.comment_status="open"}if(jQuery("#ping_status").attr("checked")){d.ping_status="open"}if(jQuery("#excerpt").size()){d.excerpt=jQuery("#excerpt").val()}if(jQuery("#post_author").size()){d.post_author=jQuery("#post_author").val()}if(jQuery("#parent_id").val()){d.parent_id=jQuery("#parent_id").val()}d.user_ID=jQuery("#user-id").val();if(jQuery("#auto_draft").val()=="1"){d.auto_draft="1"}if(f){autosaveLast=jQuery("#title").val()+jQuery("#content").val()}else{d.autosave=0}if(d.auto_draft=="1"){a=autosave_saved_new}else{a=autosave_saved}autosaveOldMessage=jQuery("#autosave").html();jQuery.ajax({data:d,beforeSend:f?autosave_loading:null,type:"POST",url:autosaveL10n.requestFile,success:a})}; \ No newline at end of file diff --git a/src/wp-includes/js/colorpicker.dev.js b/src/wp-includes/js/colorpicker.dev.js new file mode 100644 index 00000000..1fc32cf2 --- /dev/null +++ b/src/wp-includes/js/colorpicker.dev.js @@ -0,0 +1,707 @@ +// =================================================================== +// Author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + + +/* SOURCE FILE: AnchorPosition.js */ + +/* +AnchorPosition.js +Author: Matt Kruse +Last modified: 10/11/02 + +DESCRIPTION: These functions find the position of an tag in a document, +so other elements can be positioned relative to it. + +COMPATABILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small +positioning errors - usually with Window positioning - occur on the +Macintosh platform. + +FUNCTIONS: +getAnchorPosition(anchorname) + Returns an Object() having .x and .y properties of the pixel coordinates + of the upper-left corner of the anchor. Position is relative to the PAGE. + +getAnchorWindowPosition(anchorname) + Returns an Object() having .x and .y properties of the pixel coordinates + of the upper-left corner of the anchor, relative to the WHOLE SCREEN. + +NOTES: + +1) For popping up separate browser windows, use getAnchorWindowPosition. + Otherwise, use getAnchorPosition + +2) Your anchor tag MUST contain both NAME and ID attributes which are the + same. For example: + + +3) There must be at least a space between for IE5.5 to see the + anchor tag correctly. Do not do with no space. +*/ + +// getAnchorPosition(anchorname) +// This function returns an object having .x and .y properties which are the coordinates +// of the named anchor, relative to the page. +function getAnchorPosition(anchorname) { + // This function will return an Object with x and y properties + var useWindow=false; + var coordinates=new Object(); + var x=0,y=0; + // Browser capability sniffing + var use_gebi=false, use_css=false, use_layers=false; + if (document.getElementById) { use_gebi=true; } + else if (document.all) { use_css=true; } + else if (document.layers) { use_layers=true; } + // Logic to find position + if (use_gebi && document.all) { + x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]); + y=AnchorPosition_getPageOffsetTop(document.all[anchorname]); + } + else if (use_gebi) { + var o=document.getElementById(anchorname); + x=AnchorPosition_getPageOffsetLeft(o); + y=AnchorPosition_getPageOffsetTop(o); + } + else if (use_css) { + x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]); + y=AnchorPosition_getPageOffsetTop(document.all[anchorname]); + } + else if (use_layers) { + var found=0; + for (var i=0; i tags may cause errors. + +USAGE: +// Create an object for a WINDOW popup +var win = new PopupWindow(); + +// Create an object for a DIV window using the DIV named 'mydiv' +var win = new PopupWindow('mydiv'); + +// Set the window to automatically hide itself when the user clicks +// anywhere else on the page except the popup +win.autoHide(); + +// Show the window relative to the anchor name passed in +win.showPopup(anchorname); + +// Hide the popup +win.hidePopup(); + +// Set the size of the popup window (only applies to WINDOW popups +win.setSize(width,height); + +// Populate the contents of the popup window that will be shown. If you +// change the contents while it is displayed, you will need to refresh() +win.populate(string); + +// set the URL of the window, rather than populating its contents +// manually +win.setUrl("http://www.site.com/"); + +// Refresh the contents of the popup +win.refresh(); + +// Specify how many pixels to the right of the anchor the popup will appear +win.offsetX = 50; + +// Specify how many pixels below the anchor the popup will appear +win.offsetY = 100; + +NOTES: +1) Requires the functions in AnchorPosition.js + +2) Your anchor tag MUST contain both NAME and ID attributes which are the + same. For example: + + +3) There must be at least a space between for IE5.5 to see the + anchor tag correctly. Do not do with no space. + +4) When a PopupWindow object is created, a handler for 'onmouseup' is + attached to any event handler you may have already defined. Do NOT define + an event handler for 'onmouseup' after you define a PopupWindow object or + the autoHide() will not work correctly. +*/ + +// Set the position of the popup window based on the anchor +function PopupWindow_getXYPosition(anchorname) { + var coordinates; + if (this.type == "WINDOW") { + coordinates = getAnchorWindowPosition(anchorname); + } + else { + coordinates = getAnchorPosition(anchorname); + } + this.x = coordinates.x; + this.y = coordinates.y; + } +// Set width/height of DIV/popup window +function PopupWindow_setSize(width,height) { + this.width = width; + this.height = height; + } +// Fill the window with contents +function PopupWindow_populate(contents) { + this.contents = contents; + this.populated = false; + } +// Set the URL to go to +function PopupWindow_setUrl(url) { + this.url = url; + } +// Set the window popup properties +function PopupWindow_setWindowProperties(props) { + this.windowProperties = props; + } +// Refresh the displayed contents of the popup +function PopupWindow_refresh() { + if (this.divName != null) { + // refresh the DIV object + if (this.use_gebi) { + document.getElementById(this.divName).innerHTML = this.contents; + } + else if (this.use_css) { + document.all[this.divName].innerHTML = this.contents; + } + else if (this.use_layers) { + var d = document.layers[this.divName]; + d.document.open(); + d.document.writeln(this.contents); + d.document.close(); + } + } + else { + if (this.popupWindow != null && !this.popupWindow.closed) { + if (this.url!="") { + this.popupWindow.location.href=this.url; + } + else { + this.popupWindow.document.open(); + this.popupWindow.document.writeln(this.contents); + this.popupWindow.document.close(); + } + this.popupWindow.focus(); + } + } + } +// Position and show the popup, relative to an anchor object +function PopupWindow_showPopup(anchorname) { + this.getXYPosition(anchorname); + this.x += this.offsetX; + this.y += this.offsetY; + if (!this.populated && (this.contents != "")) { + this.populated = true; + this.refresh(); + } + if (this.divName != null) { + // Show the DIV object + if (this.use_gebi) { + document.getElementById(this.divName).style.left = this.x + "px"; + document.getElementById(this.divName).style.top = this.y; + document.getElementById(this.divName).style.visibility = "visible"; + } + else if (this.use_css) { + document.all[this.divName].style.left = this.x; + document.all[this.divName].style.top = this.y; + document.all[this.divName].style.visibility = "visible"; + } + else if (this.use_layers) { + document.layers[this.divName].left = this.x; + document.layers[this.divName].top = this.y; + document.layers[this.divName].visibility = "visible"; + } + } + else { + if (this.popupWindow == null || this.popupWindow.closed) { + // If the popup window will go off-screen, move it so it doesn't + if (this.x<0) { this.x=0; } + if (this.y<0) { this.y=0; } + if (screen && screen.availHeight) { + if ((this.y + this.height) > screen.availHeight) { + this.y = screen.availHeight - this.height; + } + } + if (screen && screen.availWidth) { + if ((this.x + this.width) > screen.availWidth) { + this.x = screen.availWidth - this.width; + } + } + var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ); + this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+""); + } + this.refresh(); + } + } +// Hide the popup +function PopupWindow_hidePopup() { + if (this.divName != null) { + if (this.use_gebi) { + document.getElementById(this.divName).style.visibility = "hidden"; + } + else if (this.use_css) { + document.all[this.divName].style.visibility = "hidden"; + } + else if (this.use_layers) { + document.layers[this.divName].visibility = "hidden"; + } + } + else { + if (this.popupWindow && !this.popupWindow.closed) { + this.popupWindow.close(); + this.popupWindow = null; + } + } + } +// Pass an event and return whether or not it was the popup DIV that was clicked +function PopupWindow_isClicked(e) { + if (this.divName != null) { + if (this.use_layers) { + var clickX = e.pageX; + var clickY = e.pageY; + var t = document.layers[this.divName]; + if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) { + return true; + } + else { return false; } + } + else if (document.all) { // Need to hard-code this to trap IE for error-handling + var t = window.event.srcElement; + while (t.parentElement != null) { + if (t.id==this.divName) { + return true; + } + t = t.parentElement; + } + return false; + } + else if (this.use_gebi && e) { + var t = e.originalTarget; + while (t.parentNode != null) { + if (t.id==this.divName) { + return true; + } + t = t.parentNode; + } + return false; + } + return false; + } + return false; + } + +// Check an onMouseDown event to see if we should hide +function PopupWindow_hideIfNotClicked(e) { + if (this.autoHideEnabled && !this.isClicked(e)) { + this.hidePopup(); + } + } +// Call this to make the DIV disable automatically when mouse is clicked outside it +function PopupWindow_autoHide() { + this.autoHideEnabled = true; + } +// This global function checks all PopupWindow objects onmouseup to see if they should be hidden +function PopupWindow_hidePopupWindows(e) { + for (var i=0; i0) { + this.type="DIV"; + this.divName = arguments[0]; + } + else { + this.type="WINDOW"; + } + this.use_gebi = false; + this.use_css = false; + this.use_layers = false; + if (document.getElementById) { this.use_gebi = true; } + else if (document.all) { this.use_css = true; } + else if (document.layers) { this.use_layers = true; } + else { this.type = "WINDOW"; } + this.offsetX = 0; + this.offsetY = 0; + // Method mappings + this.getXYPosition = PopupWindow_getXYPosition; + this.populate = PopupWindow_populate; + this.setUrl = PopupWindow_setUrl; + this.setWindowProperties = PopupWindow_setWindowProperties; + this.refresh = PopupWindow_refresh; + this.showPopup = PopupWindow_showPopup; + this.hidePopup = PopupWindow_hidePopup; + this.setSize = PopupWindow_setSize; + this.isClicked = PopupWindow_isClicked; + this.autoHide = PopupWindow_autoHide; + this.hideIfNotClicked = PopupWindow_hideIfNotClicked; + } + +/* SOURCE FILE: ColorPicker2.js */ + +/* +Last modified: 02/24/2003 + +DESCRIPTION: This widget is used to select a color, in hexadecimal #RRGGBB +form. It uses a color "swatch" to display the standard 216-color web-safe +palette. The user can then click on a color to select it. + +COMPATABILITY: See notes in AnchorPosition.js and PopupWindow.js. +Only the latest DHTML-capable browsers will show the color and hex values +at the bottom as your mouse goes over them. + +USAGE: +// Create a new ColorPicker object using DHTML popup +var cp = new ColorPicker(); + +// Create a new ColorPicker object using Window Popup +var cp = new ColorPicker('window'); + +// Add a link in your page to trigger the popup. For example: +Pick + +// Or use the built-in "select" function to do the dirty work for you: +Pick + +// If using DHTML popup, write out the required DIV tag near the bottom +// of your page. + + +// Write the 'pickColor' function that will be called when the user clicks +// a color and do something with the value. This is only required if you +// want to do something other than simply populate a form field, which is +// what the 'select' function will give you. +function pickColor(color) { + field.value = color; + } + +NOTES: +1) Requires the functions in AnchorPosition.js and PopupWindow.js + +2) Your anchor tag MUST contain both NAME and ID attributes which are the + same. For example: + + +3) There must be at least a space between for IE5.5 to see the + anchor tag correctly. Do not do with no space. + +4) When a ColorPicker object is created, a handler for 'onmouseup' is + attached to any event handler you may have already defined. Do NOT define + an event handler for 'onmouseup' after you define a ColorPicker object or + the color picker will not hide itself correctly. +*/ +ColorPicker_targetInput = null; +function ColorPicker_writeDiv() { + document.writeln(""); + } + +function ColorPicker_show(anchorname) { + this.showPopup(anchorname); + } + +function ColorPicker_pickColor(color,obj) { + obj.hidePopup(); + pickColor(color); + } + +// A Default "pickColor" function to accept the color passed back from popup. +// User can over-ride this with their own function. +function pickColor(color) { + if (ColorPicker_targetInput==null) { + alert("Target Input is null, which means you either didn't use the 'select' function or you have no defined your own 'pickColor' function to handle the picked color!"); + return; + } + ColorPicker_targetInput.value = color; + } + +// This function is the easiest way to popup the window, select a color, and +// have the value populate a form field, which is what most people want to do. +function ColorPicker_select(inputobj,linkname) { + if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") { + alert("colorpicker.select: Input object passed is not a valid form input object"); + window.ColorPicker_targetInput=null; + return; + } + window.ColorPicker_targetInput = inputobj; + this.show(linkname); + } + +// This function runs when you move your mouse over a color block, if you have a newer browser +function ColorPicker_highlightColor(c) { + var thedoc = (arguments.length>1)?arguments[1]:window.document; + var d = thedoc.getElementById("colorPickerSelectedColor"); + d.style.backgroundColor = c; + d = thedoc.getElementById("colorPickerSelectedColorValue"); + d.innerHTML = c; + } + +function ColorPicker() { + var windowMode = false; + // Create a new PopupWindow object + if (arguments.length==0) { + var divname = "colorPickerDiv"; + } + else if (arguments[0] == "window") { + var divname = ''; + windowMode = true; + } + else { + var divname = arguments[0]; + } + + if (divname != "") { + var cp = new PopupWindow(divname); + } + else { + var cp = new PopupWindow(); + cp.setSize(225,250); + } + + // Object variables + cp.currentValue = "#FFFFFF"; + + // Method Mappings + cp.writeDiv = ColorPicker_writeDiv; + cp.highlightColor = ColorPicker_highlightColor; + cp.show = ColorPicker_show; + cp.select = ColorPicker_select; + + // Code to populate color picker window + var colors = new Array( "#4180B6","#69AEE7","#000000","#000033","#000066","#000099","#0000CC","#0000FF","#330000","#330033","#330066","#330099", + "#3300CC","#3300FF","#660000","#660033","#660066","#660099","#6600CC","#6600FF","#990000","#990033","#990066","#990099", + "#9900CC","#9900FF","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#FF0000","#FF0033","#FF0066","#FF0099", + "#FF00CC","#FF00FF","#7FFFFF","#7FFFFF","#7FF7F7","#7FEFEF","#7FE7E7","#7FDFDF","#7FD7D7","#7FCFCF","#7FC7C7","#7FBFBF", + "#7FB7B7","#7FAFAF","#7FA7A7","#7F9F9F","#7F9797","#7F8F8F","#7F8787","#7F7F7F","#7F7777","#7F6F6F","#7F6767","#7F5F5F", + "#7F5757","#7F4F4F","#7F4747","#7F3F3F","#7F3737","#7F2F2F","#7F2727","#7F1F1F","#7F1717","#7F0F0F","#7F0707","#7F0000", + + "#4180B6","#69AEE7","#003300","#003333","#003366","#003399","#0033CC","#0033FF","#333300","#333333","#333366","#333399", + "#3333CC","#3333FF","#663300","#663333","#663366","#663399","#6633CC","#6633FF","#993300","#993333","#993366","#993399", + "#9933CC","#9933FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#FF3300","#FF3333","#FF3366","#FF3399", + "#FF33CC","#FF33FF","#FF7FFF","#FF7FFF","#F77FF7","#EF7FEF","#E77FE7","#DF7FDF","#D77FD7","#CF7FCF","#C77FC7","#BF7FBF", + "#B77FB7","#AF7FAF","#A77FA7","#9F7F9F","#977F97","#8F7F8F","#877F87","#7F7F7F","#777F77","#6F7F6F","#677F67","#5F7F5F", + "#577F57","#4F7F4F","#477F47","#3F7F3F","#377F37","#2F7F2F","#277F27","#1F7F1F","#177F17","#0F7F0F","#077F07","#007F00", + + "#4180B6","#69AEE7","#006600","#006633","#006666","#006699","#0066CC","#0066FF","#336600","#336633","#336666","#336699", + "#3366CC","#3366FF","#666600","#666633","#666666","#666699","#6666CC","#6666FF","#996600","#996633","#996666","#996699", + "#9966CC","#9966FF","#CC6600","#CC6633","#CC6666","#CC6699","#CC66CC","#CC66FF","#FF6600","#FF6633","#FF6666","#FF6699", + "#FF66CC","#FF66FF","#FFFF7F","#FFFF7F","#F7F77F","#EFEF7F","#E7E77F","#DFDF7F","#D7D77F","#CFCF7F","#C7C77F","#BFBF7F", + "#B7B77F","#AFAF7F","#A7A77F","#9F9F7F","#97977F","#8F8F7F","#87877F","#7F7F7F","#77777F","#6F6F7F","#67677F","#5F5F7F", + "#57577F","#4F4F7F","#47477F","#3F3F7F","#37377F","#2F2F7F","#27277F","#1F1F7F","#17177F","#0F0F7F","#07077F","#00007F", + + "#4180B6","#69AEE7","#009900","#009933","#009966","#009999","#0099CC","#0099FF","#339900","#339933","#339966","#339999", + "#3399CC","#3399FF","#669900","#669933","#669966","#669999","#6699CC","#6699FF","#999900","#999933","#999966","#999999", + "#9999CC","#9999FF","#CC9900","#CC9933","#CC9966","#CC9999","#CC99CC","#CC99FF","#FF9900","#FF9933","#FF9966","#FF9999", + "#FF99CC","#FF99FF","#3FFFFF","#3FFFFF","#3FF7F7","#3FEFEF","#3FE7E7","#3FDFDF","#3FD7D7","#3FCFCF","#3FC7C7","#3FBFBF", + "#3FB7B7","#3FAFAF","#3FA7A7","#3F9F9F","#3F9797","#3F8F8F","#3F8787","#3F7F7F","#3F7777","#3F6F6F","#3F6767","#3F5F5F", + "#3F5757","#3F4F4F","#3F4747","#3F3F3F","#3F3737","#3F2F2F","#3F2727","#3F1F1F","#3F1717","#3F0F0F","#3F0707","#3F0000", + + "#4180B6","#69AEE7","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#33CC00","#33CC33","#33CC66","#33CC99", + "#33CCCC","#33CCFF","#66CC00","#66CC33","#66CC66","#66CC99","#66CCCC","#66CCFF","#99CC00","#99CC33","#99CC66","#99CC99", + "#99CCCC","#99CCFF","#CCCC00","#CCCC33","#CCCC66","#CCCC99","#CCCCCC","#CCCCFF","#FFCC00","#FFCC33","#FFCC66","#FFCC99", + "#FFCCCC","#FFCCFF","#FF3FFF","#FF3FFF","#F73FF7","#EF3FEF","#E73FE7","#DF3FDF","#D73FD7","#CF3FCF","#C73FC7","#BF3FBF", + "#B73FB7","#AF3FAF","#A73FA7","#9F3F9F","#973F97","#8F3F8F","#873F87","#7F3F7F","#773F77","#6F3F6F","#673F67","#5F3F5F", + "#573F57","#4F3F4F","#473F47","#3F3F3F","#373F37","#2F3F2F","#273F27","#1F3F1F","#173F17","#0F3F0F","#073F07","#003F00", + + "#4180B6","#69AEE7","#00FF00","#00FF33","#00FF66","#00FF99","#00FFCC","#00FFFF","#33FF00","#33FF33","#33FF66","#33FF99", + "#33FFCC","#33FFFF","#66FF00","#66FF33","#66FF66","#66FF99","#66FFCC","#66FFFF","#99FF00","#99FF33","#99FF66","#99FF99", + "#99FFCC","#99FFFF","#CCFF00","#CCFF33","#CCFF66","#CCFF99","#CCFFCC","#CCFFFF","#FFFF00","#FFFF33","#FFFF66","#FFFF99", + "#FFFFCC","#FFFFFF","#FFFF3F","#FFFF3F","#F7F73F","#EFEF3F","#E7E73F","#DFDF3F","#D7D73F","#CFCF3F","#C7C73F","#BFBF3F", + "#B7B73F","#AFAF3F","#A7A73F","#9F9F3F","#97973F","#8F8F3F","#87873F","#7F7F3F","#77773F","#6F6F3F","#67673F","#5F5F3F", + "#57573F","#4F4F3F","#47473F","#3F3F3F","#37373F","#2F2F3F","#27273F","#1F1F3F","#17173F","#0F0F3F","#07073F","#00003F", + + "#4180B6","#69AEE7","#FFFFFF","#FFEEEE","#FFDDDD","#FFCCCC","#FFBBBB","#FFAAAA","#FF9999","#FF8888","#FF7777","#FF6666", + "#FF5555","#FF4444","#FF3333","#FF2222","#FF1111","#FF0000","#FF0000","#FF0000","#FF0000","#EE0000","#DD0000","#CC0000", + "#BB0000","#AA0000","#990000","#880000","#770000","#660000","#550000","#440000","#330000","#220000","#110000","#000000", + "#000000","#000000","#000000","#001111","#002222","#003333","#004444","#005555","#006666","#007777","#008888","#009999", + "#00AAAA","#00BBBB","#00CCCC","#00DDDD","#00EEEE","#00FFFF","#00FFFF","#00FFFF","#00FFFF","#11FFFF","#22FFFF","#33FFFF", + "#44FFFF","#55FFFF","#66FFFF","#77FFFF","#88FFFF","#99FFFF","#AAFFFF","#BBFFFF","#CCFFFF","#DDFFFF","#EEFFFF","#FFFFFF", + + "#4180B6","#69AEE7","#FFFFFF","#EEFFEE","#DDFFDD","#CCFFCC","#BBFFBB","#AAFFAA","#99FF99","#88FF88","#77FF77","#66FF66", + "#55FF55","#44FF44","#33FF33","#22FF22","#11FF11","#00FF00","#00FF00","#00FF00","#00FF00","#00EE00","#00DD00","#00CC00", + "#00BB00","#00AA00","#009900","#008800","#007700","#006600","#005500","#004400","#003300","#002200","#001100","#000000", + "#000000","#000000","#000000","#110011","#220022","#330033","#440044","#550055","#660066","#770077","#880088","#990099", + "#AA00AA","#BB00BB","#CC00CC","#DD00DD","#EE00EE","#FF00FF","#FF00FF","#FF00FF","#FF00FF","#FF11FF","#FF22FF","#FF33FF", + "#FF44FF","#FF55FF","#FF66FF","#FF77FF","#FF88FF","#FF99FF","#FFAAFF","#FFBBFF","#FFCCFF","#FFDDFF","#FFEEFF","#FFFFFF", + + "#4180B6","#69AEE7","#FFFFFF","#EEEEFF","#DDDDFF","#CCCCFF","#BBBBFF","#AAAAFF","#9999FF","#8888FF","#7777FF","#6666FF", + "#5555FF","#4444FF","#3333FF","#2222FF","#1111FF","#0000FF","#0000FF","#0000FF","#0000FF","#0000EE","#0000DD","#0000CC", + "#0000BB","#0000AA","#000099","#000088","#000077","#000066","#000055","#000044","#000033","#000022","#000011","#000000", + "#000000","#000000","#000000","#111100","#222200","#333300","#444400","#555500","#666600","#777700","#888800","#999900", + "#AAAA00","#BBBB00","#CCCC00","#DDDD00","#EEEE00","#FFFF00","#FFFF00","#FFFF00","#FFFF00","#FFFF11","#FFFF22","#FFFF33", + "#FFFF44","#FFFF55","#FFFF66","#FFFF77","#FFFF88","#FFFF99","#FFFFAA","#FFFFBB","#FFFFCC","#FFFFDD","#FFFFEE","#FFFFFF", + + "#4180B6","#69AEE7","#FFFFFF","#FFFFFF","#FBFBFB","#F7F7F7","#F3F3F3","#EFEFEF","#EBEBEB","#E7E7E7","#E3E3E3","#DFDFDF", + "#DBDBDB","#D7D7D7","#D3D3D3","#CFCFCF","#CBCBCB","#C7C7C7","#C3C3C3","#BFBFBF","#BBBBBB","#B7B7B7","#B3B3B3","#AFAFAF", + "#ABABAB","#A7A7A7","#A3A3A3","#9F9F9F","#9B9B9B","#979797","#939393","#8F8F8F","#8B8B8B","#878787","#838383","#7F7F7F", + "#7B7B7B","#777777","#737373","#6F6F6F","#6B6B6B","#676767","#636363","#5F5F5F","#5B5B5B","#575757","#535353","#4F4F4F", + "#4B4B4B","#474747","#434343","#3F3F3F","#3B3B3B","#373737","#333333","#2F2F2F","#2B2B2B","#272727","#232323","#1F1F1F", + "#1B1B1B","#171717","#131313","#0F0F0F","#0B0B0B","#070707","#030303","#000000","#000000","#000000","#000000","#000000"); + var total = colors.length; + var width = 72; + var cp_contents = ""; + var windowRef = (windowMode)?"window.opener.":""; + if (windowMode) { + cp_contents += "Select Color"; + cp_contents += ""; + } + cp_contents += ""; + var use_highlight = (document.getElementById || document.all)?true:false; + for (var i=0; i '; + if ( ((i+1)>=total) || (((i+1) % width) == 0)) { + cp_contents += ""; + } + } + // If the browser supports dynamically changing TD cells, add the fancy stuff + if (document.getElementById) { + var width1 = Math.floor(width/2); + var width2 = width = width1; + cp_contents += ""; + } + cp_contents += "
     #FFFFFF
    "; + if (windowMode) { + cp_contents += "
    "; + } + // end populate code + + // Write the contents to the popup object + cp.populate(cp_contents+"\n"); + // Move the table down a bit so you can see it + cp.offsetY = 25; + cp.autoHide(); + return cp; + } diff --git a/src/wp-includes/js/colorpicker.js b/src/wp-includes/js/colorpicker.js new file mode 100644 index 00000000..acd88a33 --- /dev/null +++ b/src/wp-includes/js/colorpicker.js @@ -0,0 +1 @@ +function getAnchorPosition(b){var e=false;var k=new Object();var j=0,g=0;var d=false,f=false,h=false;if(document.getElementById){d=true}else{if(document.all){f=true}else{if(document.layers){h=true}}}if(d&&document.all){j=AnchorPosition_getPageOffsetLeft(document.all[b]);g=AnchorPosition_getPageOffsetTop(document.all[b])}else{if(d){var a=document.getElementById(b);j=AnchorPosition_getPageOffsetLeft(a);g=AnchorPosition_getPageOffsetTop(a)}else{if(f){j=AnchorPosition_getPageOffsetLeft(document.all[b]);g=AnchorPosition_getPageOffsetTop(document.all[b])}else{if(h){var l=0;for(var c=0;cscreen.availHeight){this.y=screen.availHeight-this.height}}if(screen&&screen.availWidth){if((this.x+this.width)>screen.availWidth){this.x=screen.availWidth-this.width}}var b=window.opera||(document.layers&&!navigator.mimeTypes["*"])||navigator.vendor=="KDE"||(document.childNodes&&!document.all&&!navigator.taintEnabled);this.popupWindow=window.open(b?"":"about:blank","window_"+a,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"")}this.refresh()}}function PopupWindow_hidePopup(){if(this.divName!=null){if(this.use_gebi){document.getElementById(this.divName).style.visibility="hidden"}else{if(this.use_css){document.all[this.divName].style.visibility="hidden"}else{if(this.use_layers){document.layers[this.divName].visibility="hidden"}}}}else{if(this.popupWindow&&!this.popupWindow.closed){this.popupWindow.close();this.popupWindow=null}}}function PopupWindow_isClicked(c){if(this.divName!=null){if(this.use_layers){var d=c.pageX;var b=c.pageY;var a=document.layers[this.divName];if((d>a.left)&&(da.top)&&(b0){this.type="DIV";this.divName=arguments[0]}else{this.type="WINDOW"}this.use_gebi=false;this.use_css=false;this.use_layers=false;if(document.getElementById){this.use_gebi=true}else{if(document.all){this.use_css=true}else{if(document.layers){this.use_layers=true}else{this.type="WINDOW"}}}this.offsetX=0;this.offsetY=0;this.getXYPosition=PopupWindow_getXYPosition;this.populate=PopupWindow_populate;this.setUrl=PopupWindow_setUrl;this.setWindowProperties=PopupWindow_setWindowProperties;this.refresh=PopupWindow_refresh;this.showPopup=PopupWindow_showPopup;this.hidePopup=PopupWindow_hidePopup;this.setSize=PopupWindow_setSize;this.isClicked=PopupWindow_isClicked;this.autoHide=PopupWindow_autoHide;this.hideIfNotClicked=PopupWindow_hideIfNotClicked}ColorPicker_targetInput=null;function ColorPicker_writeDiv(){document.writeln('')}function ColorPicker_show(a){this.showPopup(a)}function ColorPicker_pickColor(a,b){b.hidePopup();pickColor(a)}function pickColor(a){if(ColorPicker_targetInput==null){alert("Target Input is null, which means you either didn't use the 'select' function or you have no defined your own 'pickColor' function to handle the picked color!");return}ColorPicker_targetInput.value=a}function ColorPicker_select(b,a){if(b.type!="text"&&b.type!="hidden"&&b.type!="textarea"){alert("colorpicker.select: Input object passed is not a valid form input object");window.ColorPicker_targetInput=null;return}window.ColorPicker_targetInput=b;this.show(a)}function ColorPicker_highlightColor(e){var a=(arguments.length>1)?arguments[1]:window.document;var b=a.getElementById("colorPickerSelectedColor");b.style.backgroundColor=e;b=a.getElementById("colorPickerSelectedColorValue");b.innerHTML=e}function ColorPicker(){var g=false;if(arguments.length==0){var e="colorPickerDiv"}else{if(arguments[0]=="window"){var e="";g=true}else{var e=arguments[0]}}if(e!=""){var m=new PopupWindow(e)}else{var m=new PopupWindow();m.setSize(225,250)}m.currentValue="#FFFFFF";m.writeDiv=ColorPicker_writeDiv;m.highlightColor=ColorPicker_highlightColor;m.show=ColorPicker_show;m.select=ColorPicker_select;var a=new Array("#4180B6","#69AEE7","#000000","#000033","#000066","#000099","#0000CC","#0000FF","#330000","#330033","#330066","#330099","#3300CC","#3300FF","#660000","#660033","#660066","#660099","#6600CC","#6600FF","#990000","#990033","#990066","#990099","#9900CC","#9900FF","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#7FFFFF","#7FFFFF","#7FF7F7","#7FEFEF","#7FE7E7","#7FDFDF","#7FD7D7","#7FCFCF","#7FC7C7","#7FBFBF","#7FB7B7","#7FAFAF","#7FA7A7","#7F9F9F","#7F9797","#7F8F8F","#7F8787","#7F7F7F","#7F7777","#7F6F6F","#7F6767","#7F5F5F","#7F5757","#7F4F4F","#7F4747","#7F3F3F","#7F3737","#7F2F2F","#7F2727","#7F1F1F","#7F1717","#7F0F0F","#7F0707","#7F0000","#4180B6","#69AEE7","#003300","#003333","#003366","#003399","#0033CC","#0033FF","#333300","#333333","#333366","#333399","#3333CC","#3333FF","#663300","#663333","#663366","#663399","#6633CC","#6633FF","#993300","#993333","#993366","#993399","#9933CC","#9933FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF7FFF","#FF7FFF","#F77FF7","#EF7FEF","#E77FE7","#DF7FDF","#D77FD7","#CF7FCF","#C77FC7","#BF7FBF","#B77FB7","#AF7FAF","#A77FA7","#9F7F9F","#977F97","#8F7F8F","#877F87","#7F7F7F","#777F77","#6F7F6F","#677F67","#5F7F5F","#577F57","#4F7F4F","#477F47","#3F7F3F","#377F37","#2F7F2F","#277F27","#1F7F1F","#177F17","#0F7F0F","#077F07","#007F00","#4180B6","#69AEE7","#006600","#006633","#006666","#006699","#0066CC","#0066FF","#336600","#336633","#336666","#336699","#3366CC","#3366FF","#666600","#666633","#666666","#666699","#6666CC","#6666FF","#996600","#996633","#996666","#996699","#9966CC","#9966FF","#CC6600","#CC6633","#CC6666","#CC6699","#CC66CC","#CC66FF","#FF6600","#FF6633","#FF6666","#FF6699","#FF66CC","#FF66FF","#FFFF7F","#FFFF7F","#F7F77F","#EFEF7F","#E7E77F","#DFDF7F","#D7D77F","#CFCF7F","#C7C77F","#BFBF7F","#B7B77F","#AFAF7F","#A7A77F","#9F9F7F","#97977F","#8F8F7F","#87877F","#7F7F7F","#77777F","#6F6F7F","#67677F","#5F5F7F","#57577F","#4F4F7F","#47477F","#3F3F7F","#37377F","#2F2F7F","#27277F","#1F1F7F","#17177F","#0F0F7F","#07077F","#00007F","#4180B6","#69AEE7","#009900","#009933","#009966","#009999","#0099CC","#0099FF","#339900","#339933","#339966","#339999","#3399CC","#3399FF","#669900","#669933","#669966","#669999","#6699CC","#6699FF","#999900","#999933","#999966","#999999","#9999CC","#9999FF","#CC9900","#CC9933","#CC9966","#CC9999","#CC99CC","#CC99FF","#FF9900","#FF9933","#FF9966","#FF9999","#FF99CC","#FF99FF","#3FFFFF","#3FFFFF","#3FF7F7","#3FEFEF","#3FE7E7","#3FDFDF","#3FD7D7","#3FCFCF","#3FC7C7","#3FBFBF","#3FB7B7","#3FAFAF","#3FA7A7","#3F9F9F","#3F9797","#3F8F8F","#3F8787","#3F7F7F","#3F7777","#3F6F6F","#3F6767","#3F5F5F","#3F5757","#3F4F4F","#3F4747","#3F3F3F","#3F3737","#3F2F2F","#3F2727","#3F1F1F","#3F1717","#3F0F0F","#3F0707","#3F0000","#4180B6","#69AEE7","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#66CC00","#66CC33","#66CC66","#66CC99","#66CCCC","#66CCFF","#99CC00","#99CC33","#99CC66","#99CC99","#99CCCC","#99CCFF","#CCCC00","#CCCC33","#CCCC66","#CCCC99","#CCCCCC","#CCCCFF","#FFCC00","#FFCC33","#FFCC66","#FFCC99","#FFCCCC","#FFCCFF","#FF3FFF","#FF3FFF","#F73FF7","#EF3FEF","#E73FE7","#DF3FDF","#D73FD7","#CF3FCF","#C73FC7","#BF3FBF","#B73FB7","#AF3FAF","#A73FA7","#9F3F9F","#973F97","#8F3F8F","#873F87","#7F3F7F","#773F77","#6F3F6F","#673F67","#5F3F5F","#573F57","#4F3F4F","#473F47","#3F3F3F","#373F37","#2F3F2F","#273F27","#1F3F1F","#173F17","#0F3F0F","#073F07","#003F00","#4180B6","#69AEE7","#00FF00","#00FF33","#00FF66","#00FF99","#00FFCC","#00FFFF","#33FF00","#33FF33","#33FF66","#33FF99","#33FFCC","#33FFFF","#66FF00","#66FF33","#66FF66","#66FF99","#66FFCC","#66FFFF","#99FF00","#99FF33","#99FF66","#99FF99","#99FFCC","#99FFFF","#CCFF00","#CCFF33","#CCFF66","#CCFF99","#CCFFCC","#CCFFFF","#FFFF00","#FFFF33","#FFFF66","#FFFF99","#FFFFCC","#FFFFFF","#FFFF3F","#FFFF3F","#F7F73F","#EFEF3F","#E7E73F","#DFDF3F","#D7D73F","#CFCF3F","#C7C73F","#BFBF3F","#B7B73F","#AFAF3F","#A7A73F","#9F9F3F","#97973F","#8F8F3F","#87873F","#7F7F3F","#77773F","#6F6F3F","#67673F","#5F5F3F","#57573F","#4F4F3F","#47473F","#3F3F3F","#37373F","#2F2F3F","#27273F","#1F1F3F","#17173F","#0F0F3F","#07073F","#00003F","#4180B6","#69AEE7","#FFFFFF","#FFEEEE","#FFDDDD","#FFCCCC","#FFBBBB","#FFAAAA","#FF9999","#FF8888","#FF7777","#FF6666","#FF5555","#FF4444","#FF3333","#FF2222","#FF1111","#FF0000","#FF0000","#FF0000","#FF0000","#EE0000","#DD0000","#CC0000","#BB0000","#AA0000","#990000","#880000","#770000","#660000","#550000","#440000","#330000","#220000","#110000","#000000","#000000","#000000","#000000","#001111","#002222","#003333","#004444","#005555","#006666","#007777","#008888","#009999","#00AAAA","#00BBBB","#00CCCC","#00DDDD","#00EEEE","#00FFFF","#00FFFF","#00FFFF","#00FFFF","#11FFFF","#22FFFF","#33FFFF","#44FFFF","#55FFFF","#66FFFF","#77FFFF","#88FFFF","#99FFFF","#AAFFFF","#BBFFFF","#CCFFFF","#DDFFFF","#EEFFFF","#FFFFFF","#4180B6","#69AEE7","#FFFFFF","#EEFFEE","#DDFFDD","#CCFFCC","#BBFFBB","#AAFFAA","#99FF99","#88FF88","#77FF77","#66FF66","#55FF55","#44FF44","#33FF33","#22FF22","#11FF11","#00FF00","#00FF00","#00FF00","#00FF00","#00EE00","#00DD00","#00CC00","#00BB00","#00AA00","#009900","#008800","#007700","#006600","#005500","#004400","#003300","#002200","#001100","#000000","#000000","#000000","#000000","#110011","#220022","#330033","#440044","#550055","#660066","#770077","#880088","#990099","#AA00AA","#BB00BB","#CC00CC","#DD00DD","#EE00EE","#FF00FF","#FF00FF","#FF00FF","#FF00FF","#FF11FF","#FF22FF","#FF33FF","#FF44FF","#FF55FF","#FF66FF","#FF77FF","#FF88FF","#FF99FF","#FFAAFF","#FFBBFF","#FFCCFF","#FFDDFF","#FFEEFF","#FFFFFF","#4180B6","#69AEE7","#FFFFFF","#EEEEFF","#DDDDFF","#CCCCFF","#BBBBFF","#AAAAFF","#9999FF","#8888FF","#7777FF","#6666FF","#5555FF","#4444FF","#3333FF","#2222FF","#1111FF","#0000FF","#0000FF","#0000FF","#0000FF","#0000EE","#0000DD","#0000CC","#0000BB","#0000AA","#000099","#000088","#000077","#000066","#000055","#000044","#000033","#000022","#000011","#000000","#000000","#000000","#000000","#111100","#222200","#333300","#444400","#555500","#666600","#777700","#888800","#999900","#AAAA00","#BBBB00","#CCCC00","#DDDD00","#EEEE00","#FFFF00","#FFFF00","#FFFF00","#FFFF00","#FFFF11","#FFFF22","#FFFF33","#FFFF44","#FFFF55","#FFFF66","#FFFF77","#FFFF88","#FFFF99","#FFFFAA","#FFFFBB","#FFFFCC","#FFFFDD","#FFFFEE","#FFFFFF","#4180B6","#69AEE7","#FFFFFF","#FFFFFF","#FBFBFB","#F7F7F7","#F3F3F3","#EFEFEF","#EBEBEB","#E7E7E7","#E3E3E3","#DFDFDF","#DBDBDB","#D7D7D7","#D3D3D3","#CFCFCF","#CBCBCB","#C7C7C7","#C3C3C3","#BFBFBF","#BBBBBB","#B7B7B7","#B3B3B3","#AFAFAF","#ABABAB","#A7A7A7","#A3A3A3","#9F9F9F","#9B9B9B","#979797","#939393","#8F8F8F","#8B8B8B","#878787","#838383","#7F7F7F","#7B7B7B","#777777","#737373","#6F6F6F","#6B6B6B","#676767","#636363","#5F5F5F","#5B5B5B","#575757","#535353","#4F4F4F","#4B4B4B","#474747","#434343","#3F3F3F","#3B3B3B","#373737","#333333","#2F2F2F","#2B2B2B","#272727","#232323","#1F1F1F","#1B1B1B","#171717","#131313","#0F0F0F","#0B0B0B","#070707","#030303","#000000","#000000","#000000","#000000","#000000");var n=a.length;var c=72;var k="";var j=(g)?"window.opener.":"";if(g){k+="Select Color";k+=""}k+="";var l=(document.getElementById||document.all)?true:false;for(var h=0;h"}if(l){var f='onMouseOver="'+j+"ColorPicker_highlightColor('"+a[h]+"',window.document)\""}else{f=""}k+='";if(((h+1)>=n)||(((h+1)%c)==0)){k+=""}}if(document.getElementById){var d=Math.floor(c/2);var b=c=d;k+=""}k+="
     
     #FFFFFF
    ";if(g){k+="
    "}m.populate(k+"\n");m.offsetY=25;m.autoHide();return m}; \ No newline at end of file diff --git a/src/wp-includes/js/comment-reply.dev.js b/src/wp-includes/js/comment-reply.dev.js new file mode 100644 index 00000000..20154253 --- /dev/null +++ b/src/wp-includes/js/comment-reply.dev.js @@ -0,0 +1,48 @@ + +addComment = { + moveForm : function(commId, parentId, respondId, postId) { + var t = this, div, comm = t.I(commId), respond = t.I(respondId), cancel = t.I('cancel-comment-reply-link'), parent = t.I('comment_parent'), post = t.I('comment_post_ID'); + + if ( ! comm || ! respond || ! cancel || ! parent ) + return; + + t.respondId = respondId; + postId = postId || false; + + if ( ! t.I('wp-temp-form-div') ) { + div = document.createElement('div'); + div.id = 'wp-temp-form-div'; + div.style.display = 'none'; + respond.parentNode.insertBefore(div, respond); + } + + comm.parentNode.insertBefore(respond, comm.nextSibling); + if ( post && postId ) + post.value = postId; + parent.value = parentId; + cancel.style.display = ''; + + cancel.onclick = function() { + var t = addComment, temp = t.I('wp-temp-form-div'), respond = t.I(t.respondId); + + if ( ! temp || ! respond ) + return; + + t.I('comment_parent').value = '0'; + temp.parentNode.insertBefore(respond, temp); + temp.parentNode.removeChild(temp); + this.style.display = 'none'; + this.onclick = null; + return false; + } + + try { t.I('comment').focus(); } + catch(e) {} + + return false; + }, + + I : function(e) { + return document.getElementById(e); + } +} diff --git a/src/wp-includes/js/comment-reply.js b/src/wp-includes/js/comment-reply.js new file mode 100644 index 00000000..524f2ede --- /dev/null +++ b/src/wp-includes/js/comment-reply.js @@ -0,0 +1 @@ +addComment={moveForm:function(d,f,i,c){var m=this,a,h=m.I(d),b=m.I(i),l=m.I("cancel-comment-reply-link"),j=m.I("comment_parent"),k=m.I("comment_post_ID");if(!h||!b||!l||!j){return}m.respondId=i;c=c||false;if(!m.I("wp-temp-form-div")){a=document.createElement("div");a.id="wp-temp-form-div";a.style.display="none";b.parentNode.insertBefore(a,b)}h.parentNode.insertBefore(b,h.nextSibling);if(k&&c){k.value=c}j.value=f;l.style.display="";l.onclick=function(){var n=addComment,e=n.I("wp-temp-form-div"),o=n.I(n.respondId);if(!e||!o){return}n.I("comment_parent").value="0";e.parentNode.insertBefore(o,e);e.parentNode.removeChild(e);this.style.display="none";this.onclick=null;return false};try{m.I("comment").focus()}catch(g){}return false},I:function(a){return document.getElementById(a)}}; \ No newline at end of file diff --git a/src/wp-includes/js/crop/cropper.css b/src/wp-includes/js/crop/cropper.css new file mode 100644 index 00000000..973f1784 --- /dev/null +++ b/src/wp-includes/js/crop/cropper.css @@ -0,0 +1,165 @@ +.imgCrop_wrap { + /* width: 500px; @done_in_js */ + /* height: 375px; @done_in_js */ + position: relative; + cursor: crosshair; +} + +/* an extra classname is applied for Opera < 9.0 to fix it's lack of opacity support */ +.imgCrop_wrap.opera8 .imgCrop_overlay, +.imgCrop_wrap.opera8 .imgCrop_clickArea { + background-color: transparent; +} + +/* fix for IE displaying all boxes at line-height by default, although they are still 1 pixel high until we combine them with the pointless span */ +.imgCrop_wrap, +.imgCrop_wrap * { + font-size: 0; +} + +.imgCrop_overlay { + background-color: #000; + opacity: 0.5; + filter:alpha(opacity=50); + position: absolute; + width: 100%; + height: 100%; +} + +.imgCrop_selArea { + position: absolute; + /* @done_in_js + top: 20px; + left: 20px; + width: 200px; + height: 200px; + background: transparent url(castle.jpg) no-repeat -210px -110px; + */ + cursor: move; + z-index: 2; +} + +/* clickArea is all a fix for IE 5.5 & 6 to allow the user to click on the given area */ +.imgCrop_clickArea { + width: 100%; + height: 100%; + background-color: #FFF; + opacity: 0.01; + filter:alpha(opacity=01); +} + +.imgCrop_marqueeHoriz { + position: absolute; + width: 100%; + height: 1px; + background: transparent url(marqueeHoriz.gif) repeat-x 0 0; + z-index: 3; +} + +.imgCrop_marqueeVert { + position: absolute; + height: 100%; + width: 1px; + background: transparent url(marqueeVert.gif) repeat-y 0 0; + z-index: 3; +} + +.imgCrop_marqueeNorth { top: 0; left: 0; } +.imgCrop_marqueeEast { top: 0; right: 0; } +.imgCrop_marqueeSouth { bottom: 0px; left: 0; } +.imgCrop_marqueeWest { top: 0; left: 0; } + + +.imgCrop_handle { + position: absolute; + border: 1px solid #333; + width: 6px; + height: 6px; + background: #FFF; + opacity: 0.5; + filter:alpha(opacity=50); + z-index: 4; +} + +/* fix IE 5 box model */ +* html .imgCrop_handle { + width: 8px; + height: 8px; + wid\th: 6px; + hei\ght: 6px; +} + +.imgCrop_handleN { + top: -3px; + left: 0; + /* margin-left: 49%; @done_in_js */ + cursor: n-resize; +} + +.imgCrop_handleNE { + top: -3px; + right: -3px; + cursor: ne-resize; +} + +.imgCrop_handleE { + top: 0; + right: -3px; + /* margin-top: 49%; @done_in_js */ + cursor: e-resize; +} + +.imgCrop_handleSE { + right: -3px; + bottom: -3px; + cursor: se-resize; +} + +.imgCrop_handleS { + right: 0; + bottom: -3px; + /* margin-right: 49%; @done_in_js */ + cursor: s-resize; +} + +.imgCrop_handleSW { + left: -3px; + bottom: -3px; + cursor: sw-resize; +} + +.imgCrop_handleW { + top: 0; + left: -3px; + /* margin-top: 49%; @done_in_js */ + cursor: e-resize; +} + +.imgCrop_handleNW { + top: -3px; + left: -3px; + cursor: nw-resize; +} + +/** + * Create an area to click & drag around on as the default browser behaviour is to let you drag the image + */ +.imgCrop_dragArea { + width: 100%; + height: 100%; + z-index: 200; + position: absolute; + top: 0; + left: 0; +} + +.imgCrop_previewWrap { + /* width: 200px; @done_in_js */ + /* height: 200px; @done_in_js */ + overflow: hidden; + position: relative; +} + +.imgCrop_previewWrap img { + position: absolute; +} \ No newline at end of file diff --git a/src/wp-includes/js/crop/cropper.js b/src/wp-includes/js/crop/cropper.js new file mode 100644 index 00000000..d0cb8e4c --- /dev/null +++ b/src/wp-includes/js/crop/cropper.js @@ -0,0 +1,516 @@ +/** + * Copyright (c) 2006, David Spurr (http://www.defusion.org.uk/) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://www.opensource.org/licenses/bsd-license.php + * + * See scriptaculous.js for full scriptaculous licence + */ + +var CropDraggable=Class.create(); +Object.extend(Object.extend(CropDraggable.prototype,Draggable.prototype),{initialize:function(_1){ +this.options=Object.extend({drawMethod:function(){ +}},arguments[1]||{}); +this.element=$(_1); +this.handle=this.element; +this.delta=this.currentDelta(); +this.dragging=false; +this.eventMouseDown=this.initDrag.bindAsEventListener(this); +Event.observe(this.handle,"mousedown",this.eventMouseDown); +Draggables.register(this); +},draw:function(_2){ +var _3=Position.cumulativeOffset(this.element); +var d=this.currentDelta(); +_3[0]-=d[0]; +_3[1]-=d[1]; +var p=[0,1].map(function(i){ +return (_2[i]-_3[i]-this.offset[i]); +}.bind(this)); +this.options.drawMethod(p); +}}); +var Cropper={}; +Cropper.Img=Class.create(); +Cropper.Img.prototype={initialize:function(_7,_8){ +this.options=Object.extend({ratioDim:{x:0,y:0},minWidth:0,minHeight:0,displayOnInit:false,onEndCrop:Prototype.emptyFunction,captureKeys:true},_8||{}); +if(this.options.minWidth>0&&this.options.minHeight>0){ +this.options.ratioDim.x=this.options.minWidth; +this.options.ratioDim.y=this.options.minHeight; +} +this.img=$(_7); +this.clickCoords={x:0,y:0}; +this.dragging=false; +this.resizing=false; +this.isWebKit=/Konqueror|Safari|KHTML/.test(navigator.userAgent); +this.isIE=/MSIE/.test(navigator.userAgent); +this.isOpera8=/Opera\s[1-8]/.test(navigator.userAgent); +this.ratioX=0; +this.ratioY=0; +this.attached=false; +$A(document.getElementsByTagName("script")).each(function(s){ +if(s.src.match(/cropper\.js/)){ +var _a=s.src.replace(/cropper\.js(.*)?/,""); +var _b=document.createElement("link"); +_b.rel="stylesheet"; +_b.type="text/css"; +_b.href=_a+"cropper.css"; +_b.media="screen"; +document.getElementsByTagName("head")[0].appendChild(_b); +} +}); +if(this.options.ratioDim.x>0&&this.options.ratioDim.y>0){ +var _c=this.getGCD(this.options.ratioDim.x,this.options.ratioDim.y); +this.ratioX=this.options.ratioDim.x/_c; +this.ratioY=this.options.ratioDim.y/_c; +} +this.subInitialize(); +if(this.img.complete||this.isWebKit){ +this.onLoad(); +}else{ +Event.observe(this.img,"load",this.onLoad.bindAsEventListener(this)); +} +},getGCD:function(a,b){return 1; +if(b==0){ +return a; +} +return this.getGCD(b,a%b); +},onLoad:function(){ +var _f="imgCrop_"; +var _10=this.img.parentNode; +var _11=""; +if(this.isOpera8){ +_11=" opera8"; +} +this.imgWrap=Builder.node("div",{"class":_f+"wrap"+_11}); +if(this.isIE){ +this.north=Builder.node("div",{"class":_f+"overlay "+_f+"north"},[Builder.node("span")]); +this.east=Builder.node("div",{"class":_f+"overlay "+_f+"east"},[Builder.node("span")]); +this.south=Builder.node("div",{"class":_f+"overlay "+_f+"south"},[Builder.node("span")]); +this.west=Builder.node("div",{"class":_f+"overlay "+_f+"west"},[Builder.node("span")]); +var _12=[this.north,this.east,this.south,this.west]; +}else{ +this.overlay=Builder.node("div",{"class":_f+"overlay"}); +var _12=[this.overlay]; +} +this.dragArea=Builder.node("div",{"class":_f+"dragArea"},_12); +this.handleN=Builder.node("div",{"class":_f+"handle "+_f+"handleN"}); +this.handleNE=Builder.node("div",{"class":_f+"handle "+_f+"handleNE"}); +this.handleE=Builder.node("div",{"class":_f+"handle "+_f+"handleE"}); +this.handleSE=Builder.node("div",{"class":_f+"handle "+_f+"handleSE"}); +this.handleS=Builder.node("div",{"class":_f+"handle "+_f+"handleS"}); +this.handleSW=Builder.node("div",{"class":_f+"handle "+_f+"handleSW"}); +this.handleW=Builder.node("div",{"class":_f+"handle "+_f+"handleW"}); +this.handleNW=Builder.node("div",{"class":_f+"handle "+_f+"handleNW"}); +this.selArea=Builder.node("div",{"class":_f+"selArea"},[Builder.node("div",{"class":_f+"marqueeHoriz "+_f+"marqueeNorth"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeVert "+_f+"marqueeEast"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeHoriz "+_f+"marqueeSouth"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeVert "+_f+"marqueeWest"},[Builder.node("span")]),this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW,Builder.node("div",{"class":_f+"clickArea"})]); +Element.setStyle($(this.selArea),{backgroundColor:"transparent",backgroundRepeat:"no-repeat",backgroundPosition:"0 0"}); +this.imgWrap.appendChild(this.img); +this.imgWrap.appendChild(this.dragArea); +this.dragArea.appendChild(this.selArea); +this.dragArea.appendChild(Builder.node("div",{"class":_f+"clickArea"})); +_10.appendChild(this.imgWrap); +Event.observe(this.dragArea,"mousedown",this.startDrag.bindAsEventListener(this)); +Event.observe(document,"mousemove",this.onDrag.bindAsEventListener(this)); +Event.observe(document,"mouseup",this.endCrop.bindAsEventListener(this)); +var _13=[this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW]; +for(var i=0;i<_13.length;i++){ +Event.observe(_13[i],"mousedown",this.startResize.bindAsEventListener(this)); +} +if(this.options.captureKeys){ +Event.observe(document,"keydown",this.handleKeys.bindAsEventListener(this)); +} +new CropDraggable(this.selArea,{drawMethod:this.moveArea.bindAsEventListener(this)}); +this.setParams(); +},setParams:function(){ +this.imgW=this.img.width; +this.imgH=this.img.height; +if(!this.isIE){ +Element.setStyle($(this.overlay),{width:this.imgW+"px",height:this.imgH+"px"}); +Element.hide($(this.overlay)); +Element.setStyle($(this.selArea),{backgroundImage:"url("+this.img.src+")"}); +}else{ +Element.setStyle($(this.north),{height:0}); +Element.setStyle($(this.east),{width:0,height:0}); +Element.setStyle($(this.south),{height:0}); +Element.setStyle($(this.west),{width:0,height:0}); +} +Element.setStyle($(this.imgWrap),{"width":this.imgW+"px","height":this.imgH+"px"}); +Element.hide($(this.selArea)); +var _15=Position.positionedOffset(this.imgWrap); +this.wrapOffsets={"top":_15[1],"left":_15[0]}; +var _16={x1:0,y1:0,x2:0,y2:0}; +this.setAreaCoords(_16); +if(this.options.ratioDim.x>0&&this.options.ratioDim.y>0&&this.options.displayOnInit){ +_16.x1=Math.ceil((this.imgW-this.options.ratioDim.x)/2); +_16.y1=Math.ceil((this.imgH-this.options.ratioDim.y)/2); +_16.x2=_16.x1+this.options.ratioDim.x; +_16.y2=_16.y1+this.options.ratioDim.y; +Element.show(this.selArea); +this.drawArea(); +this.endCrop(); +} +this.attached=true; +},remove:function(){ +this.attached=false; +this.imgWrap.parentNode.insertBefore(this.img,this.imgWrap); +this.imgWrap.parentNode.removeChild(this.imgWrap); +Event.stopObserving(this.dragArea,"mousedown",this.startDrag.bindAsEventListener(this)); +Event.stopObserving(document,"mousemove",this.onDrag.bindAsEventListener(this)); +Event.stopObserving(document,"mouseup",this.endCrop.bindAsEventListener(this)); +var _17=[this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW]; +for(var i=0;i<_17.length;i++){ +Event.stopObserving(_17[i],"mousedown",this.startResize.bindAsEventListener(this)); +} +if(this.options.captureKeys){ +Event.stopObserving(document,"keydown",this.handleKeys.bindAsEventListener(this)); +} +},reset:function(){ +if(!this.attached){ +this.onLoad(); +}else{ +this.setParams(); +} +this.endCrop(); +},handleKeys:function(e){ +var dir={x:0,y:0}; +if(!this.dragging){ +switch(e.keyCode){ +case (37): +dir.x=-1; +break; +case (38): +dir.y=-1; +break; +case (39): +dir.x=1; +break; +case (40): +dir.y=1; +break; +} +if(dir.x!=0||dir.y!=0){ +if(e.shiftKey){ +dir.x*=10; +dir.y*=10; +} +this.moveArea([this.areaCoords.x1+dir.x,this.areaCoords.y1+dir.y]); +Event.stop(e); +} +} +},calcW:function(){ +return (this.areaCoords.x2-this.areaCoords.x1); +},calcH:function(){ +return (this.areaCoords.y2-this.areaCoords.y1); +},moveArea:function(_1b){ +this.setAreaCoords({x1:_1b[0],y1:_1b[1],x2:_1b[0]+this.calcW(),y2:_1b[1]+this.calcH()},true); +this.drawArea(); +},cloneCoords:function(_1c){ +return {x1:_1c.x1,y1:_1c.y1,x2:_1c.x2,y2:_1c.y2}; +},setAreaCoords:function(_1d,_1e,_1f,_20,_21){ +var _22=typeof _1e!="undefined"?_1e:false; +var _23=typeof _1f!="undefined"?_1f:false; +if(_1e){ +var _24=_1d.x2-_1d.x1; +var _25=_1d.y2-_1d.y1; +if(_1d.x1<0){ +_1d.x1=0; +_1d.x2=_24; +} +if(_1d.y1<0){ +_1d.y1=0; +_1d.y2=_25; +} +if(_1d.x2>this.imgW){ +_1d.x2=this.imgW; +_1d.x1=this.imgW-_24; +} +if(_1d.y2>this.imgH){ +_1d.y2=this.imgH; +_1d.y1=this.imgH-_25; +} +}else{ +if(_1d.x1<0){ +_1d.x1=0; +} +if(_1d.y1<0){ +_1d.y1=0; +} +if(_1d.x2>this.imgW){ +_1d.x2=this.imgW; +} +if(_1d.y2>this.imgH){ +_1d.y2=this.imgH; +} +if(typeof (_20)!="undefined"){ +if(this.ratioX>0){ +this.applyRatio(_1d,{x:this.ratioX,y:this.ratioY},_20,_21); +}else{ +if(_23){ +this.applyRatio(_1d,{x:1,y:1},_20,_21); +} +} +var _26={a1:_1d.x1,a2:_1d.x2}; +var _27={a1:_1d.y1,a2:_1d.y2}; +var _28=this.options.minWidth; +var _29=this.options.minHeight; +if((_28==0||_29==0)&&_23){ +if(_28>0){ +_29=_28; +}else{ +if(_29>0){ +_28=_29; +} +} +} +this.applyMinDimension(_26,_28,_20.x,{min:0,max:this.imgW}); +this.applyMinDimension(_27,_29,_20.y,{min:0,max:this.imgH}); +_1d={x1:_26.a1,y1:_27.a1,x2:_26.a2,y2:_27.a2}; +} +} +this.areaCoords=_1d; +},applyMinDimension:function(_2a,_2b,_2c,_2d){ +if((_2a.a2-_2a.a1)<_2b){ +if(_2c==1){ +_2a.a2=_2a.a1+_2b; +}else{ +_2a.a1=_2a.a2-_2b; +} +if(_2a.a1<_2d.min){ +_2a.a1=_2d.min; +_2a.a2=_2b; +}else{ +if(_2a.a2>_2d.max){ +_2a.a1=_2d.max-_2b; +_2a.a2=_2d.max; +} +} +} +},applyRatio:function(_2e,_2f,_30,_31){ +var _32; +if(_31=="N"||_31=="S"){ +_32=this.applyRatioToAxis({a1:_2e.y1,b1:_2e.x1,a2:_2e.y2,b2:_2e.x2},{a:_2f.y,b:_2f.x},{a:_30.y,b:_30.x},{min:0,max:this.imgW}); +_2e.x1=_32.b1; +_2e.y1=_32.a1; +_2e.x2=_32.b2; +_2e.y2=_32.a2; +}else{ +_32=this.applyRatioToAxis({a1:_2e.x1,b1:_2e.y1,a2:_2e.x2,b2:_2e.y2},{a:_2f.x,b:_2f.y},{a:_30.x,b:_30.y},{min:0,max:this.imgH}); +_2e.x1=_32.a1; +_2e.y1=_32.b1; +_2e.x2=_32.a2; +_2e.y2=_32.b2; +} +},applyRatioToAxis:function(_33,_34,_35,_36){ +var _37=Object.extend(_33,{}); +var _38=_37.a2-_37.a1; +var _3a=Math.floor(_38*_34.b/_34.a); +var _3b; +var _3c; +var _3d=null; +if(_35.b==1){ +_3b=_37.b1+_3a; +if(_3b>_36.max){ +_3b=_36.max; +_3d=_3b-_37.b1; +} +_37.b2=_3b; +}else{ +_3b=_37.b2-_3a; +if(_3b<_36.min){ +_3b=_36.min; +_3d=_3b+_37.b2; +} +_37.b1=_3b; +} +if(_3d!=null){ +_3c=Math.floor(_3d*_34.a/_34.b); +if(_35.a==1){ +_37.a2=_37.a1+_3c; +}else{ +_37.a1=_37.a1=_37.a2-_3c; +} +} +return _37; +},drawArea:function(){ +if(!this.isIE){ +Element.show($(this.overlay)); +} +var _3e=this.calcW(); +var _3f=this.calcH(); +var _40=this.areaCoords.x2; +var _41=this.areaCoords.y2; +var _42=this.selArea.style; +_42.left=this.areaCoords.x1+"px"; +_42.top=this.areaCoords.y1+"px"; +_42.width=_3e+"px"; +_42.height=_3f+"px"; +var _43=Math.ceil((_3e-6)/2)+"px"; +var _44=Math.ceil((_3f-6)/2)+"px"; +this.handleN.style.left=_43; +this.handleE.style.top=_44; +this.handleS.style.left=_43; +this.handleW.style.top=_44; +if(this.isIE){ +this.north.style.height=this.areaCoords.y1+"px"; +var _45=this.east.style; +_45.top=this.areaCoords.y1+"px"; +_45.height=_3f+"px"; +_45.left=_40+"px"; +_45.width=(this.img.width-_40)+"px"; +var _46=this.south.style; +_46.top=_41+"px"; +_46.height=(this.img.height-_41)+"px"; +var _47=this.west.style; +_47.top=this.areaCoords.y1+"px"; +_47.height=_3f+"px"; +_47.width=this.areaCoords.x1+"px"; +}else{ +_42.backgroundPosition="-"+this.areaCoords.x1+"px "+"-"+this.areaCoords.y1+"px"; +} +this.subDrawArea(); +this.forceReRender(); +},forceReRender:function(){ +if(this.isIE||this.isWebKit){ +var n=document.createTextNode(" "); +var d,el,fixEL,i; +if(this.isIE){ +fixEl=this.selArea; +}else{ +if(this.isWebKit){ +fixEl=document.getElementsByClassName("imgCrop_marqueeSouth",this.imgWrap)[0]; +d=Builder.node("div",""); +d.style.visibility="hidden"; +var _4a=["SE","S","SW"]; +for(i=0;i<_4a.length;i++){ +el=document.getElementsByClassName("imgCrop_handle"+_4a[i],this.selArea)[0]; +if(el.childNodes.length){ +el.removeChild(el.childNodes[0]); +} +el.appendChild(d); +} +} +} +fixEl.appendChild(n); +fixEl.removeChild(n); +} +},startResize:function(e){ +this.startCoords=this.cloneCoords(this.areaCoords); +this.resizing=true; +this.resizeHandle=Element.classNames(Event.element(e)).toString().replace(/([^N|NE|E|SE|S|SW|W|NW])+/,""); +Event.stop(e); +},startDrag:function(e){ +Element.show(this.selArea); +this.clickCoords=this.getCurPos(e); +this.setAreaCoords({x1:this.clickCoords.x,y1:this.clickCoords.y,x2:this.clickCoords.x,y2:this.clickCoords.y}); +this.dragging=true; +this.onDrag(e); +Event.stop(e); +},getCurPos:function(e){ +return curPos={x:Event.pointerX(e)-this.wrapOffsets.left,y:Event.pointerY(e)-this.wrapOffsets.top}; +},onDrag:function(e){ +var _4f=null; +if(this.dragging||this.resizing){ +var _50=this.getCurPos(e); +var _51=this.cloneCoords(this.areaCoords); +var _52={x:1,y:1}; +} +if(this.dragging){ +if(_50.x0&&this.options.minHeight>0){ +this.previewWrap=$(this.options.previewWrap); +this.previewImg=this.img.cloneNode(false); +this.options.displayOnInit=true; +this.hasPreviewImg=true; +Element.addClassName(this.previewWrap,"imgCrop_previewWrap"); +Element.setStyle(this.previewWrap,{width:this.options.minWidth+"px",height:this.options.minHeight+"px"}); +this.previewWrap.appendChild(this.previewImg); +} +},subDrawArea:function(){ +if(this.hasPreviewImg){ +var _58=this.calcW(); +var _59=this.calcH(); +var _5a={x:this.imgW/_58,y:this.imgH/_59}; +var _5b={x:_58/this.options.minWidth,y:_59/this.options.minHeight}; +var _5c={w:Math.ceil(this.options.minWidth*_5a.x)+"px",h:Math.ceil(this.options.minHeight*_5a.y)+"px",x:"-"+Math.ceil(this.areaCoords.x1/_5b.x)+"px",y:"-"+Math.ceil(this.areaCoords.y1/_5b.y)+"px"}; +var _5d=this.previewImg.style; +_5d.width=_5c.w; +_5d.height=_5c.h; +_5d.left=_5c.x; +_5d.top=_5c.y; +} +}}); diff --git a/src/wp-includes/js/crop/marqueeHoriz.gif b/src/wp-includes/js/crop/marqueeHoriz.gif new file mode 100644 index 00000000..25317e57 Binary files /dev/null and b/src/wp-includes/js/crop/marqueeHoriz.gif differ diff --git a/src/wp-includes/js/crop/marqueeVert.gif b/src/wp-includes/js/crop/marqueeVert.gif new file mode 100644 index 00000000..354070bb Binary files /dev/null and b/src/wp-includes/js/crop/marqueeVert.gif differ diff --git a/src/wp-includes/js/hoverIntent.dev.js b/src/wp-includes/js/hoverIntent.dev.js new file mode 100644 index 00000000..5cbf9782 --- /dev/null +++ b/src/wp-includes/js/hoverIntent.dev.js @@ -0,0 +1,128 @@ +/** +* hoverIntent is similar to jQuery's built-in "hover" function except that +* instead of firing the onMouseOver event immediately, hoverIntent checks +* to see if the user's mouse has slowed down (beneath the sensitivity +* threshold) before firing the onMouseOver event. +* +* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+ +* +* +* hoverIntent is currently available for use in all personal or commercial +* projects under both MIT and GPL licenses. This means that you can choose +* the license that best suits your project, and use it accordingly. +* +* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions +* $("ul li").hoverIntent( showNav , hideNav ); +* +* // advanced usage receives configuration object only +* $("ul li").hoverIntent({ +* sensitivity: 7, // number = sensitivity threshold (must be 1 or higher) +* interval: 100, // number = milliseconds of polling interval +* over: showNav, // function = onMouseOver callback (required) +* timeout: 0, // number = milliseconds delay before onMouseOut function call +* out: hideNav // function = onMouseOut callback (required) +* }); +* +* @param f onMouseOver function || An object with configuration options +* @param g onMouseOut function || Nothing (use configuration options object) +* @author Brian Cherne +*/ +(function($) { + $.fn.hoverIntent = function(f,g) { + // default configuration options + var cfg = { + sensitivity: 7, + interval: 100, + timeout: 0 + }; + // override configuration options with user supplied object + cfg = $.extend(cfg, g ? { over: f, out: g } : f ); + + // instantiate variables + // cX, cY = current X and Y position of mouse, updated by mousemove event + // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval + var cX, cY, pX, pY; + + // A private function for getting mouse position + var track = function(ev) { + cX = ev.pageX; + cY = ev.pageY; + }; + + // A private function for comparing current and previous mouse position + var compare = function(ev,ob) { + ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); + // compare mouse positions to see if they've crossed the threshold + if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { + $(ob).unbind("mousemove",track); + // set hoverIntent state to true (so mouseOut can be called) + ob.hoverIntent_s = 1; + return cfg.over.apply(ob,[ev]); + } else { + // set previous coordinates for next time + pX = cX; pY = cY; + // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) + ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); + } + }; + + // A private function for delaying the mouseOut function + var delay = function(ev,ob) { + ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); + ob.hoverIntent_s = 0; + return cfg.out.apply(ob,[ev]); + }; + + // workaround for Mozilla bug: not firing mouseout/mouseleave on absolute positioned elements over textareas and input type="text" + var handleHover = function(e) { + var t = this; + + // next two lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut + var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget; + while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } } + if ( p == this ) { + if ( $.browser.mozilla ) { + if ( e.type == "mouseout" ) { + t.mtout = setTimeout( function(){doHover(e,t);}, 30 ); + } else { + if (t.mtout) { t.mtout = clearTimeout(t.mtout); } + } + } + return; + } else { + if (t.mtout) { t.mtout = clearTimeout(t.mtout); } + doHover(e,t); + } + }; + + // A private function for handling mouse 'hovering' + var doHover = function(e,ob) { + + // copy objects to be passed into t (required for event object to be passed in IE) + var ev = jQuery.extend({},e); + + // cancel hoverIntent timer if it exists + if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } + + // else e.type == "onmouseover" + if (e.type == "mouseover") { + // set "previous" X and Y position based on initial entry point + pX = ev.pageX; pY = ev.pageY; + // update "current" X and Y position based on mousemove + $(ob).bind("mousemove",track); + // start polling interval (self-calling timeout) to compare mouse coordinates over time + if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} + + // else e.type == "onmouseout" + } else { + // unbind expensive mousemove event + $(ob).unbind("mousemove",track); + // if hoverIntent state is true, then call the mouseOut function after the specified delay + if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} + } + }; + + // bind the function to the two event listeners + return this.mouseover(handleHover).mouseout(handleHover); + }; +})(jQuery); \ No newline at end of file diff --git a/src/wp-includes/js/hoverIntent.js b/src/wp-includes/js/hoverIntent.js new file mode 100644 index 00000000..bed4129c --- /dev/null +++ b/src/wp-includes/js/hoverIntent.js @@ -0,0 +1 @@ +(function(a){a.fn.hoverIntent=function(l,j){var m={sensitivity:7,interval:100,timeout:0};m=a.extend(m,j?{over:l,out:j}:l);var o,n,h,d;var e=function(f){o=f.pageX;n=f.pageY};var c=function(g,f){f.hoverIntent_t=clearTimeout(f.hoverIntent_t);if((Math.abs(h-o)+Math.abs(d-n))'); +} + +$.imgAreaSelect = function (img, options) { + var + + $img = $(img), + + imgLoaded, + + $box = div(), + $area = div(), + $border = div().add(div()).add(div()).add(div()), + $outer = div().add(div()).add(div()).add(div()), + $handles = $([]), + + $areaOpera, + + left, top, + + imgOfs, + + imgWidth, imgHeight, + + $parent, + + parOfs, + + zIndex = 0, + + position = 'absolute', + + startX, startY, + + scaleX, scaleY, + + resizeMargin = 10, + + resize, + + aspectRatio, + + shown, + + x1, y1, x2, y2, + + selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 }, + + $p, d, i, o, w, h, adjusted; + + function viewX(x) { + return x + imgOfs.left - parOfs.left; + } + + function viewY(y) { + return y + imgOfs.top - parOfs.top; + } + + function selX(x) { + return x - imgOfs.left + parOfs.left; + } + + function selY(y) { + return y - imgOfs.top + parOfs.top; + } + + function evX(event) { + return event.pageX - parOfs.left; + } + + function evY(event) { + return event.pageY - parOfs.top; + } + + function getSelection(noScale) { + var sx = noScale || scaleX, sy = noScale || scaleY; + + return { x1: round(selection.x1 * sx), + y1: round(selection.y1 * sy), + x2: round(selection.x2 * sx), + y2: round(selection.y2 * sy), + width: round(selection.x2 * sx) - round(selection.x1 * sx), + height: round(selection.y2 * sy) - round(selection.y1 * sy) }; + } + + function setSelection(x1, y1, x2, y2, noScale) { + var sx = noScale || scaleX, sy = noScale || scaleY; + + selection = { + x1: round(x1 / sx), + y1: round(y1 / sy), + x2: round(x2 / sx), + y2: round(y2 / sy) + }; + + selection.width = (x2 = viewX(selection.x2)) - (x1 = viewX(selection.x1)); + selection.height = (y2 = viewX(selection.y2)) - (y1 = viewX(selection.y1)); + } + + function adjust() { + if (!$img.width()) + return; + + imgOfs = { left: round($img.offset().left), top: round($img.offset().top) }; + + imgWidth = $img.width(); + imgHeight = $img.height(); + + if ($().jquery == '1.3.2' && $.browser.safari && position == 'fixed') { + imgOfs.top += max(document.documentElement.scrollTop, $('body').scrollTop()); + + imgOfs.left += max(document.documentElement.scrollLeft, $('body').scrollLeft()); + } + + parOfs = $.inArray($parent.css('position'), ['absolute', 'relative']) + 1 ? + { left: round($parent.offset().left) - $parent.scrollLeft(), + top: round($parent.offset().top) - $parent.scrollTop() } : + position == 'fixed' ? + { left: $(document).scrollLeft(), top: $(document).scrollTop() } : + { left: 0, top: 0 }; + + left = viewX(0); + top = viewY(0); + } + + function update(resetKeyPress) { + if (!shown) return; + + $box.css({ left: viewX(selection.x1), top: viewY(selection.y1) }) + .add($area).width(w = selection.width).height(h = selection.height); + + $area.add($border).add($handles).css({ left: 0, top: 0 }); + + $border + .width(max(w - $border.outerWidth() + $border.innerWidth(), 0)) + .height(max(h - $border.outerHeight() + $border.innerHeight(), 0)); + + $($outer[0]).css({ left: left, top: top, + width: selection.x1, height: imgHeight }); + $($outer[1]).css({ left: left + selection.x1, top: top, + width: w, height: selection.y1 }); + $($outer[2]).css({ left: left + selection.x2, top: top, + width: imgWidth - selection.x2, height: imgHeight }); + $($outer[3]).css({ left: left + selection.x1, top: top + selection.y2, + width: w, height: imgHeight - selection.y2 }); + + w -= $handles.outerWidth(); + h -= $handles.outerHeight(); + + switch ($handles.length) { + case 8: + $($handles[4]).css({ left: w / 2 }); + $($handles[5]).css({ left: w, top: h / 2 }); + $($handles[6]).css({ left: w / 2, top: h }); + $($handles[7]).css({ top: h / 2 }); + case 4: + $handles.slice(1,3).css({ left: w }); + $handles.slice(2,4).css({ top: h }); + } + + if (resetKeyPress !== false) { + if ($.imgAreaSelect.keyPress != docKeyPress) + $(document).unbind($.imgAreaSelect.keyPress, + $.imgAreaSelect.onKeyPress); + + if (options.keys) + $(document)[$.imgAreaSelect.keyPress]( + $.imgAreaSelect.onKeyPress = docKeyPress); + } + + if ($.browser.msie && $border.outerWidth() - $border.innerWidth() == 2) { + $border.css('margin', 0); + setTimeout(function () { $border.css('margin', 'auto'); }, 0); + } + } + + function doUpdate(resetKeyPress) { + adjust(); + update(resetKeyPress); + x1 = viewX(selection.x1); y1 = viewY(selection.y1); + x2 = viewX(selection.x2); y2 = viewY(selection.y2); + } + + function hide($elem, fn) { + options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide(); + + } + + function areaMouseMove(event) { + var x = selX(evX(event)) - selection.x1, + y = selY(evY(event)) - selection.y1; + + if (!adjusted) { + adjust(); + adjusted = true; + + $box.one('mouseout', function () { adjusted = false; }); + } + + resize = ''; + + if (options.resizable) { + if (y <= resizeMargin) + resize = 'n'; + else if (y >= selection.height - resizeMargin) + resize = 's'; + if (x <= resizeMargin) + resize += 'w'; + else if (x >= selection.width - resizeMargin) + resize += 'e'; + } + + $box.css('cursor', resize ? resize + '-resize' : + options.movable ? 'move' : ''); + if ($areaOpera) + $areaOpera.toggle(); + } + + function docMouseUp(event) { + $('body').css('cursor', ''); + + if (options.autoHide || selection.width * selection.height == 0) + hide($box.add($outer), function () { $(this).hide(); }); + + options.onSelectEnd(img, getSelection()); + + $(document).unbind('mousemove', selectingMouseMove); + $box.mousemove(areaMouseMove); + } + + function areaMouseDown(event) { + if (event.which != 1) return false; + + adjust(); + + if (resize) { + $('body').css('cursor', resize + '-resize'); + + x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); + y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); + + $(document).mousemove(selectingMouseMove) + .one('mouseup', docMouseUp); + $box.unbind('mousemove', areaMouseMove); + } + else if (options.movable) { + startX = left + selection.x1 - evX(event); + startY = top + selection.y1 - evY(event); + + $box.unbind('mousemove', areaMouseMove); + + $(document).mousemove(movingMouseMove) + .one('mouseup', function () { + options.onSelectEnd(img, getSelection()); + + $(document).unbind('mousemove', movingMouseMove); + $box.mousemove(areaMouseMove); + }); + } + else + $img.mousedown(event); + + return false; + } + + function aspectRatioXY() { + x2 = max(left, min(left + imgWidth, + x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); + + y2 = round(max(top, min(top + imgHeight, + y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)))); + x2 = round(x2); + } + + function aspectRatioYX() { + y2 = max(top, min(top + imgHeight, + y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1))); + x2 = round(max(left, min(left + imgWidth, + x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)))); + y2 = round(y2); + } + + function doResize() { + if (abs(x2 - x1) < options.minWidth) { + x2 = x1 - options.minWidth * (x2 < x1 || -1); + + if (x2 < left) + x1 = left + options.minWidth; + else if (x2 > left + imgWidth) + x1 = left + imgWidth - options.minWidth; + } + + if (abs(y2 - y1) < options.minHeight) { + y2 = y1 - options.minHeight * (y2 < y1 || -1); + + if (y2 < top) + y1 = top + options.minHeight; + else if (y2 > top + imgHeight) + y1 = top + imgHeight - options.minHeight; + } + + x2 = max(left, min(x2, left + imgWidth)); + y2 = max(top, min(y2, top + imgHeight)); + + if (aspectRatio) + if (abs(x2 - x1) / aspectRatio > abs(y2 - y1)) + aspectRatioYX(); + else + aspectRatioXY(); + + if (abs(x2 - x1) > options.maxWidth) { + x2 = x1 - options.maxWidth * (x2 < x1 || -1); + if (aspectRatio) aspectRatioYX(); + } + + if (abs(y2 - y1) > options.maxHeight) { + y2 = y1 - options.maxHeight * (y2 < y1 || -1); + if (aspectRatio) aspectRatioXY(); + } + + selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)), + y1: selY(min(y1, y2)), y2: selY(max(y1, y2)), + width: abs(x2 - x1), height: abs(y2 - y1) }; + + update(); + + options.onSelectChange(img, getSelection()); + } + + function selectingMouseMove(event) { + x2 = resize == '' || /w|e/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2); + y2 = resize == '' || /n|s/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2); + + doResize(); + + return false; + + } + + function doMove(newX1, newY1) { + x2 = (x1 = newX1) + selection.width; + y2 = (y1 = newY1) + selection.height; + + selection = $.extend(selection, { x1: selX(x1), y1: selY(y1), + x2: selX(x2), y2: selY(y2) }); + + update(); + + options.onSelectChange(img, getSelection()); + } + + function movingMouseMove(event) { + x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width)); + y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height)); + + doMove(x1, y1); + + event.preventDefault(); + + return false; + } + + function startSelection() { + adjust(); + + x2 = x1; + y2 = y1; + + doResize(); + + resize = ''; + + if ($outer.is(':not(:visible)')) + $box.add($outer).hide().fadeIn(options.fadeSpeed||0); + + shown = true; + + $(document).unbind('mouseup', cancelSelection) + .mousemove(selectingMouseMove).one('mouseup', docMouseUp); + $box.unbind('mousemove', areaMouseMove); + + options.onSelectStart(img, getSelection()); + } + + function cancelSelection() { + $(document).unbind('mousemove', startSelection); + hide($box.add($outer)); + + selection = { x1: selX(x1), y1: selY(y1), x2: selX(x1), y2: selY(y1), + width: 0, height: 0 }; + + options.onSelectChange(img, getSelection()); + options.onSelectEnd(img, getSelection()); + } + + function imgMouseDown(event) { + if (event.which != 1 || $outer.is(':animated')) return false; + + adjust(); + startX = x1 = evX(event); + startY = y1 = evY(event); + + $(document).one('mousemove', startSelection) + .one('mouseup', cancelSelection); + + return false; + } + + function parentScroll() { + doUpdate(false); + } + + function imgLoad() { + imgLoaded = true; + + setOptions(options = $.extend({ + classPrefix: 'imgareaselect', + movable: true, + resizable: true, + parent: 'body', + onInit: function () {}, + onSelectStart: function () {}, + onSelectChange: function () {}, + onSelectEnd: function () {} + }, options)); + + $box.add($outer).css({ visibility: '' }); + + if (options.show) { + shown = true; + adjust(); + update(); + $box.add($outer).hide().fadeIn(options.fadeSpeed||0); + } + + setTimeout(function () { options.onInit(img, getSelection()); }, 0); + } + + var docKeyPress = function(event) { + var k = options.keys, d, t, key = event.keyCode || event.which; + + d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt : + !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl : + !isNaN(k.shift) && event.shiftKey ? k.shift : + !isNaN(k.arrows) ? k.arrows : 10; + + if (k.arrows == 'resize' || (k.shift == 'resize' && event.shiftKey) || + (k.ctrl == 'resize' && event.ctrlKey) || + (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey))) + { + switch (key) { + case 37: + d = -d; + case 39: + t = max(x1, x2); + x1 = min(x1, x2); + x2 = max(t + d, x1); + if (aspectRatio) aspectRatioYX(); + break; + case 38: + d = -d; + case 40: + t = max(y1, y2); + y1 = min(y1, y2); + y2 = max(t + d, y1); + if (aspectRatio) aspectRatioXY(); + break; + default: + return; + } + + doResize(); + } + else { + x1 = min(x1, x2); + y1 = min(y1, y2); + + switch (key) { + case 37: + doMove(max(x1 - d, left), y1); + break; + case 38: + doMove(x1, max(y1 - d, top)); + break; + case 39: + doMove(x1 + min(d, imgWidth - selX(x2)), y1); + break; + case 40: + doMove(x1, y1 + min(d, imgHeight - selY(y2))); + break; + default: + return; + } + } + + return false; + }; + + function styleOptions($elem, props) { + for (option in props) + if (options[option] !== undefined) + $elem.css(props[option], options[option]); + } + + function setOptions(newOptions) { + if (newOptions.parent) + ($parent = $(newOptions.parent)).append($box.add($outer)); + + options = $.extend(options, newOptions); + + adjust(); + + if (newOptions.handles != null) { + $handles.remove(); + $handles = $([]); + + i = newOptions.handles ? newOptions.handles == 'corners' ? 4 : 8 : 0; + + while (i--) + $handles = $handles.add(div()); + + $handles.addClass(options.classPrefix + '-handle').css({ + position: 'absolute', + fontSize: 0, + zIndex: zIndex + 1 || 1 + }); + + if (!parseInt($handles.css('width'))) + $handles.width(5).height(5); + + if (o = options.borderWidth) + $handles.css({ borderWidth: o, borderStyle: 'solid' }); + + styleOptions($handles, { borderColor1: 'border-color', + borderColor2: 'background-color', + borderOpacity: 'opacity' }); + } + + scaleX = options.imageWidth / imgWidth || 1; + scaleY = options.imageHeight / imgHeight || 1; + + if (newOptions.x1 != null) { + setSelection(newOptions.x1, newOptions.y1, newOptions.x2, + newOptions.y2); + newOptions.show = !newOptions.hide; + } + + if (newOptions.keys) + options.keys = $.extend({ shift: 1, ctrl: 'resize' }, + newOptions.keys); + + $outer.addClass(options.classPrefix + '-outer'); + $area.addClass(options.classPrefix + '-selection'); + for (i = 0; i++ < 4;) + $($border[i-1]).addClass(options.classPrefix + '-border' + i); + + styleOptions($area, { selectionColor: 'background-color', + selectionOpacity: 'opacity' }); + styleOptions($border, { borderOpacity: 'opacity', + borderWidth: 'border-width' }); + styleOptions($outer, { outerColor: 'background-color', + outerOpacity: 'opacity' }); + if (o = options.borderColor1) + $($border[0]).css({ borderStyle: 'solid', borderColor: o }); + if (o = options.borderColor2) + $($border[1]).css({ borderStyle: 'dashed', borderColor: o }); + + $box.append($area.add($border).add($handles).add($areaOpera)); + + if ($.browser.msie) { + if (o = $outer.css('filter').match(/opacity=([0-9]+)/)) + $outer.css('opacity', o[1]/100); + if (o = $border.css('filter').match(/opacity=([0-9]+)/)) + $border.css('opacity', o[1]/100); + } + + if (newOptions.hide) + hide($box.add($outer)); + else if (newOptions.show && imgLoaded) { + shown = true; + $box.add($outer).fadeIn(options.fadeSpeed||0); + doUpdate(); + } + + aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; + + if (options.disable || options.enable === false) { + $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown); + $img.add($outer).unbind('mousedown', imgMouseDown); + $(window).unbind('resize', parentScroll); + $img.add($img.parents()).unbind('scroll', parentScroll); + } + else if (options.enable || options.disable === false) { + if (options.resizable || options.movable) + $box.mousemove(areaMouseMove).mousedown(areaMouseDown); + + if (!options.persistent) + $img.add($outer).mousedown(imgMouseDown); + $(window).resize(parentScroll); + $img.add($img.parents()).scroll(parentScroll); + } + + options.enable = options.disable = undefined; + } + + this.getOptions = function () { return options; }; + + this.setOptions = setOptions; + + this.getSelection = getSelection; + + this.setSelection = setSelection; + + this.update = doUpdate; + + $p = $img; + + while ($p.length && !$p.is('body')) { + if (!isNaN($p.css('z-index')) && $p.css('z-index') > zIndex) + zIndex = $p.css('z-index'); + if ($p.css('position') == 'fixed') + position = 'fixed'; + + $p = $p.parent(); + } + + if (!isNaN(options.zIndex)) + zIndex = options.zIndex; + + if ($.browser.msie) + $img.attr('unselectable', 'on'); + + $.imgAreaSelect.keyPress = $.browser.msie || + $.browser.safari ? 'keydown' : 'keypress'; + + if ($.browser.opera) + $areaOpera = div().css({ width: '100%', height: '100%', + position: 'absolute', zIndex: zIndex + 2 || 2 }); + + $box.add($outer).css({ visibility: 'hidden', position: position, + overflow: 'hidden', zIndex: zIndex || '0' }); + $box.css({ zIndex: zIndex + 2 || 2 }); + $area.add($border).css({ position: 'absolute' }); + + img.complete || img.readyState == 'complete' || !$img.is('img') ? + imgLoad() : $img.one('load', imgLoad); + +}; + +$.fn.imgAreaSelect = function (options) { + options = options || {}; + + this.each(function () { + if ($(this).data('imgAreaSelect')) + $(this).data('imgAreaSelect').setOptions(options); + else { + if (options.enable === undefined && options.disable === undefined) + options.enable = true; + + $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options)); + } + }); + + if (options.instance) + return $(this).data('imgAreaSelect'); + + return this; +}; + +})(jQuery); diff --git a/src/wp-includes/js/imgareaselect/jquery.imgareaselect.js b/src/wp-includes/js/imgareaselect/jquery.imgareaselect.js new file mode 100644 index 00000000..9f2aee24 --- /dev/null +++ b/src/wp-includes/js/imgareaselect/jquery.imgareaselect.js @@ -0,0 +1 @@ +(function(e){var b=Math.abs,a=Math.max,d=Math.min,c=Math.round;function f(){return e("
    ")}e.imgAreaSelect=function(q,S){var aw=e(q),U,ar=f(),af=f(),H=f().add(f()).add(f()).add(f()),Y=f().add(f()).add(f()).add(f()),L=e([]),R,n,p,az,N,j,A,M,B=0,ad="absolute",Q,P,aa,Z,V=10,I,T,K,y,aA,x,ay,v={x1:0,y1:0,x2:0,y2:0,width:0,height:0},l,aq,am,ag,ac,an,u;function G(h){return h+az.left-M.left}function F(h){return h+az.top-M.top}function E(h){return h-az.left+M.left}function z(h){return h-az.top+M.top}function ak(h){return h.pageX-M.left}function ai(h){return h.pageY-M.top}function D(h){var o=h||aa,i=h||Z;return{x1:c(v.x1*o),y1:c(v.y1*i),x2:c(v.x2*o),y2:c(v.y2*i),width:c(v.x2*o)-c(v.x1*o),height:c(v.y2*i)-c(v.y1*i)}}function ae(i,w,h,o,aB){var aD=aB||aa,aC=aB||Z;v={x1:c(i/aD),y1:c(w/aC),x2:c(h/aD),y2:c(o/aC)};v.width=(h=G(v.x2))-(i=G(v.x1));v.height=(o=G(v.y2))-(w=G(v.y1))}function ao(){if(!aw.width()){return}az={left:c(aw.offset().left),top:c(aw.offset().top)};N=aw.width();j=aw.height();if(e().jquery=="1.3.2"&&e.browser.safari&&ad=="fixed"){az.top+=a(document.documentElement.scrollTop,e("body").scrollTop());az.left+=a(document.documentElement.scrollLeft,e("body").scrollLeft())}M=e.inArray(A.css("position"),["absolute","relative"])+1?{left:c(A.offset().left)-A.scrollLeft(),top:c(A.offset().top)-A.scrollTop()}:ad=="fixed"?{left:e(document).scrollLeft(),top:e(document).scrollTop()}:{left:0,top:0};n=G(0);p=F(0)}function X(h){if(!K){return}ar.css({left:G(v.x1),top:F(v.y1)}).add(af).width(ac=v.width).height(an=v.height);af.add(H).add(L).css({left:0,top:0});H.width(a(ac-H.outerWidth()+H.innerWidth(),0)).height(a(an-H.outerHeight()+H.innerHeight(),0));e(Y[0]).css({left:n,top:p,width:v.x1,height:j});e(Y[1]).css({left:n+v.x1,top:p,width:ac,height:v.y1});e(Y[2]).css({left:n+v.x2,top:p,width:N-v.x2,height:j});e(Y[3]).css({left:n+v.x1,top:p+v.y2,width:ac,height:j-v.y2});ac-=L.outerWidth();an-=L.outerHeight();switch(L.length){case 8:e(L[4]).css({left:ac/2});e(L[5]).css({left:ac,top:an/2});e(L[6]).css({left:ac/2,top:an});e(L[7]).css({top:an/2});case 4:L.slice(1,3).css({left:ac});L.slice(2,4).css({top:an})}if(h!==false){if(e.imgAreaSelect.keyPress!=at){e(document).unbind(e.imgAreaSelect.keyPress,e.imgAreaSelect.onKeyPress)}if(S.keys){e(document)[e.imgAreaSelect.keyPress](e.imgAreaSelect.onKeyPress=at)}}if(e.browser.msie&&H.outerWidth()-H.innerWidth()==2){H.css("margin",0);setTimeout(function(){H.css("margin","auto")},0)}}function t(h){ao();X(h);y=G(v.x1);aA=F(v.y1);x=G(v.x2);ay=F(v.y2)}function ah(h,i){S.fadeSpeed?h.fadeOut(S.fadeSpeed,i):h.hide()}function C(i){var h=E(ak(i))-v.x1,o=z(ai(i))-v.y1;if(!u){ao();u=true;ar.one("mouseout",function(){u=false})}I="";if(S.resizable){if(o<=V){I="n"}else{if(o>=v.height-V){I="s"}}if(h<=V){I+="w"}else{if(h>=v.width-V){I+="e"}}}ar.css("cursor",I?I+"-resize":S.movable?"move":"");if(R){R.toggle()}}function aj(h){e("body").css("cursor","");if(S.autoHide||v.width*v.height==0){ah(ar.add(Y),function(){e(this).hide()})}S.onSelectEnd(q,D());e(document).unbind("mousemove",ab);ar.mousemove(C)}function s(h){if(h.which!=1){return false}ao();if(I){e("body").css("cursor",I+"-resize");y=G(v[/w/.test(I)?"x2":"x1"]);aA=F(v[/n/.test(I)?"y2":"y1"]);e(document).mousemove(ab).one("mouseup",aj);ar.unbind("mousemove",C)}else{if(S.movable){Q=n+v.x1-ak(h);P=p+v.y1-ai(h);ar.unbind("mousemove",C);e(document).mousemove(g).one("mouseup",function(){S.onSelectEnd(q,D());e(document).unbind("mousemove",g);ar.mousemove(C)})}else{aw.mousedown(h)}}return false}function r(){x=a(n,d(n+N,y+b(ay-aA)*T*(x>y||-1)));ay=c(a(p,d(p+j,aA+b(x-y)/T*(ay>aA||-1))));x=c(x)}function al(){ay=a(p,d(p+j,aA+b(x-y)/T*(ay>aA||-1)));x=c(a(n,d(n+N,y+b(ay-aA)*T*(x>y||-1))));ay=c(ay)}function av(){if(b(x-y)n+N){y=n+N-S.minWidth}}}if(b(ay-aA)p+j){aA=p+j-S.minHeight}}}x=a(n,d(x,n+N));ay=a(p,d(ay,p+j));if(T){if(b(x-y)/T>b(ay-aA)){al()}else{r()}}if(b(x-y)>S.maxWidth){x=y-S.maxWidth*(xS.maxHeight){ay=aA-S.maxHeight*(ayB){B=l.css("z-index")}if(l.css("position")=="fixed"){ad="fixed"}l=l.parent()}if(!isNaN(S.zIndex)){B=S.zIndex}if(e.browser.msie){aw.attr("unselectable","on")}e.imgAreaSelect.keyPress=e.browser.msie||e.browser.safari?"keydown":"keypress";if(e.browser.opera){R=f().css({width:"100%",height:"100%",position:"absolute",zIndex:B+2||2})}ar.add(Y).css({visibility:"hidden",position:ad,overflow:"hidden",zIndex:B||"0"});ar.css({zIndex:B+2||2});af.add(H).css({position:"absolute"});q.complete||q.readyState=="complete"||!aw.is("img")?au():aw.one("load",au)};e.fn.imgAreaSelect=function(g){g=g||{};this.each(function(){if(e(this).data("imgAreaSelect")){e(this).data("imgAreaSelect").setOptions(g)}else{if(g.enable===undefined&&g.disable===undefined){g.enable=true}e(this).data("imgAreaSelect",new e.imgAreaSelect(this,g))}});if(g.instance){return e(this).data("imgAreaSelect")}return this}})(jQuery); \ No newline at end of file diff --git a/src/wp-includes/js/jcrop/Jcrop.gif b/src/wp-includes/js/jcrop/Jcrop.gif new file mode 100644 index 00000000..72ea7ccb Binary files /dev/null and b/src/wp-includes/js/jcrop/Jcrop.gif differ diff --git a/src/wp-includes/js/jcrop/jquery.Jcrop.css b/src/wp-includes/js/jcrop/jquery.Jcrop.css new file mode 100644 index 00000000..24925dc9 --- /dev/null +++ b/src/wp-includes/js/jcrop/jquery.Jcrop.css @@ -0,0 +1,35 @@ +/* Fixes issue here http://code.google.com/p/jcrop/issues/detail?id=1 */ +.jcrop-holder { text-align: left; } + +.jcrop-vline, .jcrop-hline +{ + font-size: 0; + position: absolute; + background: white url('Jcrop.gif') top left repeat; +} +.jcrop-vline { height: 100%; width: 1px !important; } +.jcrop-hline { width: 100%; height: 1px !important; } +.jcrop-handle { + font-size: 1px; + width: 7px !important; + height: 7px !important; + border: 1px #eee solid; + background-color: #333; + *width: 9px; + *height: 9px; +} + +.jcrop-tracker { width: 100%; height: 100%; } + +.custom .jcrop-vline, +.custom .jcrop-hline +{ + background: yellow; +} +.custom .jcrop-handle +{ + border-color: black; + background-color: #C7BB00; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} diff --git a/src/wp-includes/js/jcrop/jquery.Jcrop.dev.js b/src/wp-includes/js/jcrop/jquery.Jcrop.dev.js new file mode 100644 index 00000000..ad261f97 --- /dev/null +++ b/src/wp-includes/js/jcrop/jquery.Jcrop.dev.js @@ -0,0 +1,1197 @@ +/** + * jquery.Jcrop.js v0.9.8 + * jQuery Image Cropping Plugin + * @author Kelly Hallman + * Copyright (c) 2008-2009 Kelly Hallman - released under MIT License {{{ + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + + * }}} + */ + +(function($) { + +$.Jcrop = function(obj,opt) +{ + // Initialization {{{ + + // Sanitize some options {{{ + var obj = obj, opt = opt; + + if (typeof(obj) !== 'object') obj = $(obj)[0]; + if (typeof(opt) !== 'object') opt = { }; + + // Some on-the-fly fixes for MSIE...sigh + if (!('trackDocument' in opt)) + { + opt.trackDocument = $.browser.msie ? false : true; + if ($.browser.msie && $.browser.version.split('.')[0] == '8') + opt.trackDocument = true; + } + + if (!('keySupport' in opt)) + opt.keySupport = $.browser.msie ? false : true; + + // }}} + // Extend the default options {{{ + var defaults = { + + // Basic Settings + trackDocument: false, + baseClass: 'jcrop', + addClass: null, + + // Styling Options + bgColor: 'black', + bgOpacity: .6, + borderOpacity: .4, + handleOpacity: .5, + + handlePad: 5, + handleSize: 9, + handleOffset: 5, + edgeMargin: 14, + + aspectRatio: 0, + keySupport: true, + cornerHandles: true, + sideHandles: true, + drawBorders: true, + dragEdges: true, + + boxWidth: 0, + boxHeight: 0, + + boundary: 8, + animationDelay: 20, + swingSpeed: 3, + + allowSelect: true, + allowMove: true, + allowResize: true, + + minSelect: [ 0, 0 ], + maxSize: [ 0, 0 ], + minSize: [ 0, 0 ], + + // Callbacks / Event Handlers + onChange: function() { }, + onSelect: function() { } + + }; + var options = defaults; + setOptions(opt); + + // }}} + // Initialize some jQuery objects {{{ + + var $origimg = $(obj); + var $img = $origimg.clone().removeAttr('id').css({ position: 'absolute' }); + + $img.width($origimg.width()); + $img.height($origimg.height()); + $origimg.after($img).hide(); + + presize($img,options.boxWidth,options.boxHeight); + + var boundx = $img.width(), + boundy = $img.height(), + + $div = $('
    ') + .width(boundx).height(boundy) + .addClass(cssClass('holder')) + .css({ + position: 'relative', + backgroundColor: options.bgColor + }).insertAfter($origimg).append($img); + ; + + if (options.addClass) $div.addClass(options.addClass); + //$img.wrap($div); + + var $img2 = $('')/*{{{*/ + .attr('src',$img.attr('src')) + .css('position','absolute') + .width(boundx).height(boundy) + ;/*}}}*/ + var $img_holder = $('
    ')/*{{{*/ + .width(pct(100)).height(pct(100)) + .css({ + zIndex: 310, + position: 'absolute', + overflow: 'hidden' + }) + .append($img2) + ;/*}}}*/ + var $hdl_holder = $('
    ')/*{{{*/ + .width(pct(100)).height(pct(100)) + .css('zIndex',320); + /*}}}*/ + var $sel = $('
    ')/*{{{*/ + .css({ + position: 'absolute', + zIndex: 300 + }) + .insertBefore($img) + .append($img_holder,$hdl_holder) + ;/*}}}*/ + + var bound = options.boundary; + var $trk = newTracker().width(boundx+(bound*2)).height(boundy+(bound*2)) + .css({ position: 'absolute', top: px(-bound), left: px(-bound), zIndex: 290 }) + .mousedown(newSelection); + + /* }}} */ + // Set more variables {{{ + + var xlimit, ylimit, xmin, ymin; + var xscale, yscale, enabled = true; + var docOffset = getPos($img), + // Internal states + btndown, lastcurs, dimmed, animating, + shift_down; + + // }}} + + + // }}} + // Internal Modules {{{ + + var Coords = function()/*{{{*/ + { + var x1 = 0, y1 = 0, x2 = 0, y2 = 0, ox, oy; + + function setPressed(pos)/*{{{*/ + { + var pos = rebound(pos); + x2 = x1 = pos[0]; + y2 = y1 = pos[1]; + }; + /*}}}*/ + function setCurrent(pos)/*{{{*/ + { + var pos = rebound(pos); + ox = pos[0] - x2; + oy = pos[1] - y2; + x2 = pos[0]; + y2 = pos[1]; + }; + /*}}}*/ + function getOffset()/*{{{*/ + { + return [ ox, oy ]; + }; + /*}}}*/ + function moveOffset(offset)/*{{{*/ + { + var ox = offset[0], oy = offset[1]; + + if (0 > x1 + ox) ox -= ox + x1; + if (0 > y1 + oy) oy -= oy + y1; + + if (boundy < y2 + oy) oy += boundy - (y2 + oy); + if (boundx < x2 + ox) ox += boundx - (x2 + ox); + + x1 += ox; + x2 += ox; + y1 += oy; + y2 += oy; + }; + /*}}}*/ + function getCorner(ord)/*{{{*/ + { + var c = getFixed(); + switch(ord) + { + case 'ne': return [ c.x2, c.y ]; + case 'nw': return [ c.x, c.y ]; + case 'se': return [ c.x2, c.y2 ]; + case 'sw': return [ c.x, c.y2 ]; + } + }; + /*}}}*/ + function getFixed()/*{{{*/ + { + if (!options.aspectRatio) return getRect(); + // This function could use some optimization I think... + var aspect = options.aspectRatio, + min_x = options.minSize[0]/xscale, + min_y = options.minSize[1]/yscale, + max_x = options.maxSize[0]/xscale, + max_y = options.maxSize[1]/yscale, + rw = x2 - x1, + rh = y2 - y1, + rwa = Math.abs(rw), + rha = Math.abs(rh), + real_ratio = rwa / rha, + xx, yy + ; + if (max_x == 0) { max_x = boundx * 10 } + if (max_y == 0) { max_y = boundy * 10 } + if (real_ratio < aspect) + { + yy = y2; + w = rha * aspect; + xx = rw < 0 ? x1 - w : w + x1; + + if (xx < 0) + { + xx = 0; + h = Math.abs((xx - x1) / aspect); + yy = rh < 0 ? y1 - h: h + y1; + } + else if (xx > boundx) + { + xx = boundx; + h = Math.abs((xx - x1) / aspect); + yy = rh < 0 ? y1 - h : h + y1; + } + } + else + { + xx = x2; + h = rwa / aspect; + yy = rh < 0 ? y1 - h : y1 + h; + if (yy < 0) + { + yy = 0; + w = Math.abs((yy - y1) * aspect); + xx = rw < 0 ? x1 - w : w + x1; + } + else if (yy > boundy) + { + yy = boundy; + w = Math.abs(yy - y1) * aspect; + xx = rw < 0 ? x1 - w : w + x1; + } + } + + // Magic %-) + if(xx > x1) { // right side + if(xx - x1 < min_x) { + xx = x1 + min_x; + } else if (xx - x1 > max_x) { + xx = x1 + max_x; + } + if(yy > y1) { + yy = y1 + (xx - x1)/aspect; + } else { + yy = y1 - (xx - x1)/aspect; + } + } else if (xx < x1) { // left side + if(x1 - xx < min_x) { + xx = x1 - min_x + } else if (x1 - xx > max_x) { + xx = x1 - max_x; + } + if(yy > y1) { + yy = y1 + (x1 - xx)/aspect; + } else { + yy = y1 - (x1 - xx)/aspect; + } + } + + if(xx < 0) { + x1 -= xx; + xx = 0; + } else if (xx > boundx) { + x1 -= xx - boundx; + xx = boundx; + } + + if(yy < 0) { + y1 -= yy; + yy = 0; + } else if (yy > boundy) { + y1 -= yy - boundy; + yy = boundy; + } + + return last = makeObj(flipCoords(x1,y1,xx,yy)); + }; + /*}}}*/ + function rebound(p)/*{{{*/ + { + if (p[0] < 0) p[0] = 0; + if (p[1] < 0) p[1] = 0; + + if (p[0] > boundx) p[0] = boundx; + if (p[1] > boundy) p[1] = boundy; + + return [ p[0], p[1] ]; + }; + /*}}}*/ + function flipCoords(x1,y1,x2,y2)/*{{{*/ + { + var xa = x1, xb = x2, ya = y1, yb = y2; + if (x2 < x1) + { + xa = x2; + xb = x1; + } + if (y2 < y1) + { + ya = y2; + yb = y1; + } + return [ Math.round(xa), Math.round(ya), Math.round(xb), Math.round(yb) ]; + }; + /*}}}*/ + function getRect()/*{{{*/ + { + var xsize = x2 - x1; + var ysize = y2 - y1; + + if (xlimit && (Math.abs(xsize) > xlimit)) + x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit); + if (ylimit && (Math.abs(ysize) > ylimit)) + y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit); + + if (ymin && (Math.abs(ysize) < ymin)) + y2 = (ysize > 0) ? (y1 + ymin) : (y1 - ymin); + if (xmin && (Math.abs(xsize) < xmin)) + x2 = (xsize > 0) ? (x1 + xmin) : (x1 - xmin); + + if (x1 < 0) { x2 -= x1; x1 -= x1; } + if (y1 < 0) { y2 -= y1; y1 -= y1; } + if (x2 < 0) { x1 -= x2; x2 -= x2; } + if (y2 < 0) { y1 -= y2; y2 -= y2; } + if (x2 > boundx) { var delta = x2 - boundx; x1 -= delta; x2 -= delta; } + if (y2 > boundy) { var delta = y2 - boundy; y1 -= delta; y2 -= delta; } + if (x1 > boundx) { var delta = x1 - boundy; y2 -= delta; y1 -= delta; } + if (y1 > boundy) { var delta = y1 - boundy; y2 -= delta; y1 -= delta; } + + return makeObj(flipCoords(x1,y1,x2,y2)); + }; + /*}}}*/ + function makeObj(a)/*{{{*/ + { + return { x: a[0], y: a[1], x2: a[2], y2: a[3], + w: a[2] - a[0], h: a[3] - a[1] }; + }; + /*}}}*/ + + return { + flipCoords: flipCoords, + setPressed: setPressed, + setCurrent: setCurrent, + getOffset: getOffset, + moveOffset: moveOffset, + getCorner: getCorner, + getFixed: getFixed + }; + }(); + + /*}}}*/ + var Selection = function()/*{{{*/ + { + var start, end, dragmode, awake, hdep = 370; + var borders = { }; + var handle = { }; + var seehandles = false; + var hhs = options.handleOffset; + + /* Insert draggable elements {{{*/ + + // Insert border divs for outline + if (options.drawBorders) { + borders = { + top: insertBorder('hline') + .css('top',$.browser.msie?px(-1):px(0)), + bottom: insertBorder('hline'), + left: insertBorder('vline'), + right: insertBorder('vline') + }; + } + + // Insert handles on edges + if (options.dragEdges) { + handle.t = insertDragbar('n'); + handle.b = insertDragbar('s'); + handle.r = insertDragbar('e'); + handle.l = insertDragbar('w'); + } + + // Insert side handles + options.sideHandles && + createHandles(['n','s','e','w']); + + // Insert corner handles + options.cornerHandles && + createHandles(['sw','nw','ne','se']); + + /*}}}*/ + // Private Methods + function insertBorder(type)/*{{{*/ + { + var jq = $('
    ') + .css({position: 'absolute', opacity: options.borderOpacity }) + .addClass(cssClass(type)); + $img_holder.append(jq); + return jq; + }; + /*}}}*/ + function dragDiv(ord,zi)/*{{{*/ + { + var jq = $('
    ') + .mousedown(createDragger(ord)) + .css({ + cursor: ord+'-resize', + position: 'absolute', + zIndex: zi + }) + ; + $hdl_holder.append(jq); + return jq; + }; + /*}}}*/ + function insertHandle(ord)/*{{{*/ + { + return dragDiv(ord,hdep++) + .css({ top: px(-hhs+1), left: px(-hhs+1), opacity: options.handleOpacity }) + .addClass(cssClass('handle')); + }; + /*}}}*/ + function insertDragbar(ord)/*{{{*/ + { + var s = options.handleSize, + o = hhs, + h = s, w = s, + t = o, l = o; + + switch(ord) + { + case 'n': case 's': w = pct(100); break; + case 'e': case 'w': h = pct(100); break; + } + + return dragDiv(ord,hdep++).width(w).height(h) + .css({ top: px(-t+1), left: px(-l+1)}); + }; + /*}}}*/ + function createHandles(li)/*{{{*/ + { + for(i in li) handle[li[i]] = insertHandle(li[i]); + }; + /*}}}*/ + function moveHandles(c)/*{{{*/ + { + var midvert = Math.round((c.h / 2) - hhs), + midhoriz = Math.round((c.w / 2) - hhs), + north = west = -hhs+1, + east = c.w - hhs, + south = c.h - hhs, + x, y; + + 'e' in handle && + handle.e.css({ top: px(midvert), left: px(east) }) && + handle.w.css({ top: px(midvert) }) && + handle.s.css({ top: px(south), left: px(midhoriz) }) && + handle.n.css({ left: px(midhoriz) }); + + 'ne' in handle && + handle.ne.css({ left: px(east) }) && + handle.se.css({ top: px(south), left: px(east) }) && + handle.sw.css({ top: px(south) }); + + 'b' in handle && + handle.b.css({ top: px(south) }) && + handle.r.css({ left: px(east) }); + }; + /*}}}*/ + function moveto(x,y)/*{{{*/ + { + $img2.css({ top: px(-y), left: px(-x) }); + $sel.css({ top: px(y), left: px(x) }); + }; + /*}}}*/ + function resize(w,h)/*{{{*/ + { + $sel.width(w).height(h); + }; + /*}}}*/ + function refresh()/*{{{*/ + { + var c = Coords.getFixed(); + + Coords.setPressed([c.x,c.y]); + Coords.setCurrent([c.x2,c.y2]); + + updateVisible(); + }; + /*}}}*/ + + // Internal Methods + function updateVisible()/*{{{*/ + { if (awake) return update(); }; + /*}}}*/ + function update()/*{{{*/ + { + var c = Coords.getFixed(); + + resize(c.w,c.h); + moveto(c.x,c.y); + + options.drawBorders && + borders['right'].css({ left: px(c.w-1) }) && + borders['bottom'].css({ top: px(c.h-1) }); + + seehandles && moveHandles(c); + awake || show(); + + options.onChange(unscale(c)); + }; + /*}}}*/ + function show()/*{{{*/ + { + $sel.show(); + $img.css('opacity',options.bgOpacity); + awake = true; + }; + /*}}}*/ + function release()/*{{{*/ + { + disableHandles(); + $sel.hide(); + $img.css('opacity',1); + awake = false; + }; + /*}}}*/ + function showHandles()//{{{ + { + if (seehandles) + { + moveHandles(Coords.getFixed()); + $hdl_holder.show(); + } + }; + //}}} + function enableHandles()/*{{{*/ + { + seehandles = true; + if (options.allowResize) + { + moveHandles(Coords.getFixed()); + $hdl_holder.show(); + return true; + } + }; + /*}}}*/ + function disableHandles()/*{{{*/ + { + seehandles = false; + $hdl_holder.hide(); + }; + /*}}}*/ + function animMode(v)/*{{{*/ + { + (animating = v) ? disableHandles(): enableHandles(); + }; + /*}}}*/ + function done()/*{{{*/ + { + animMode(false); + refresh(); + }; + /*}}}*/ + + var $track = newTracker().mousedown(createDragger('move')) + .css({ cursor: 'move', position: 'absolute', zIndex: 360 }) + + $img_holder.append($track); + disableHandles(); + + return { + updateVisible: updateVisible, + update: update, + release: release, + refresh: refresh, + setCursor: function (cursor) { $track.css('cursor',cursor); }, + enableHandles: enableHandles, + enableOnly: function() { seehandles = true; }, + showHandles: showHandles, + disableHandles: disableHandles, + animMode: animMode, + done: done + }; + }(); + /*}}}*/ + var Tracker = function()/*{{{*/ + { + var onMove = function() { }, + onDone = function() { }, + trackDoc = options.trackDocument; + + if (!trackDoc) + { + $trk + .mousemove(trackMove) + .mouseup(trackUp) + .mouseout(trackUp) + ; + } + + function toFront()/*{{{*/ + { + $trk.css({zIndex:450}); + if (trackDoc) + { + $(document) + .mousemove(trackMove) + .mouseup(trackUp) + ; + } + } + /*}}}*/ + function toBack()/*{{{*/ + { + $trk.css({zIndex:290}); + if (trackDoc) + { + $(document) + .unbind('mousemove',trackMove) + .unbind('mouseup',trackUp) + ; + } + } + /*}}}*/ + function trackMove(e)/*{{{*/ + { + onMove(mouseAbs(e)); + }; + /*}}}*/ + function trackUp(e)/*{{{*/ + { + e.preventDefault(); + e.stopPropagation(); + + if (btndown) + { + btndown = false; + + onDone(mouseAbs(e)); + options.onSelect(unscale(Coords.getFixed())); + toBack(); + onMove = function() { }; + onDone = function() { }; + } + + return false; + }; + /*}}}*/ + + function activateHandlers(move,done)/* {{{ */ + { + btndown = true; + onMove = move; + onDone = done; + toFront(); + return false; + }; + /* }}} */ + + function setCursor(t) { $trk.css('cursor',t); }; + + $img.before($trk); + return { + activateHandlers: activateHandlers, + setCursor: setCursor + }; + }(); + /*}}}*/ + var KeyManager = function()/*{{{*/ + { + var $keymgr = $('') + .css({ position: 'absolute', left: '-30px' }) + .keypress(parseKey) + .blur(onBlur), + + $keywrap = $('
    ') + .css({ + position: 'absolute', + overflow: 'hidden' + }) + .append($keymgr) + ; + + function watchKeys()/*{{{*/ + { + if (options.keySupport) + { + $keymgr.show(); + $keymgr.focus(); + } + }; + /*}}}*/ + function onBlur(e)/*{{{*/ + { + $keymgr.hide(); + }; + /*}}}*/ + function doNudge(e,x,y)/*{{{*/ + { + if (options.allowMove) { + Coords.moveOffset([x,y]); + Selection.updateVisible(); + }; + e.preventDefault(); + e.stopPropagation(); + }; + /*}}}*/ + function parseKey(e)/*{{{*/ + { + if (e.ctrlKey) return true; + shift_down = e.shiftKey ? true : false; + var nudge = shift_down ? 10 : 1; + switch(e.keyCode) + { + case 37: doNudge(e,-nudge,0); break; + case 39: doNudge(e,nudge,0); break; + case 38: doNudge(e,0,-nudge); break; + case 40: doNudge(e,0,nudge); break; + + case 27: Selection.release(); break; + + case 9: return true; + } + + return nothing(e); + }; + /*}}}*/ + + if (options.keySupport) $keywrap.insertBefore($img); + return { + watchKeys: watchKeys + }; + }(); + /*}}}*/ + + // }}} + // Internal Methods {{{ + + function px(n) { return '' + parseInt(n) + 'px'; }; + function pct(n) { return '' + parseInt(n) + '%'; }; + function cssClass(cl) { return options.baseClass + '-' + cl; }; + function getPos(obj)/*{{{*/ + { + // Updated in v0.9.4 to use built-in dimensions plugin + var pos = $(obj).offset(); + return [ pos.left, pos.top ]; + }; + /*}}}*/ + function mouseAbs(e)/*{{{*/ + { + return [ (e.pageX - docOffset[0]), (e.pageY - docOffset[1]) ]; + }; + /*}}}*/ + function myCursor(type)/*{{{*/ + { + if (type != lastcurs) + { + Tracker.setCursor(type); + //Handles.xsetCursor(type); + lastcurs = type; + } + }; + /*}}}*/ + function startDragMode(mode,pos)/*{{{*/ + { + docOffset = getPos($img); + Tracker.setCursor(mode=='move'?mode:mode+'-resize'); + + if (mode == 'move') + return Tracker.activateHandlers(createMover(pos), doneSelect); + + var fc = Coords.getFixed(); + var opp = oppLockCorner(mode); + var opc = Coords.getCorner(oppLockCorner(opp)); + + Coords.setPressed(Coords.getCorner(opp)); + Coords.setCurrent(opc); + + Tracker.activateHandlers(dragmodeHandler(mode,fc),doneSelect); + }; + /*}}}*/ + function dragmodeHandler(mode,f)/*{{{*/ + { + return function(pos) { + if (!options.aspectRatio) switch(mode) + { + case 'e': pos[1] = f.y2; break; + case 'w': pos[1] = f.y2; break; + case 'n': pos[0] = f.x2; break; + case 's': pos[0] = f.x2; break; + } + else switch(mode) + { + case 'e': pos[1] = f.y+1; break; + case 'w': pos[1] = f.y+1; break; + case 'n': pos[0] = f.x+1; break; + case 's': pos[0] = f.x+1; break; + } + Coords.setCurrent(pos); + Selection.update(); + }; + }; + /*}}}*/ + function createMover(pos)/*{{{*/ + { + var lloc = pos; + KeyManager.watchKeys(); + + return function(pos) + { + Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]); + lloc = pos; + + Selection.update(); + }; + }; + /*}}}*/ + function oppLockCorner(ord)/*{{{*/ + { + switch(ord) + { + case 'n': return 'sw'; + case 's': return 'nw'; + case 'e': return 'nw'; + case 'w': return 'ne'; + case 'ne': return 'sw'; + case 'nw': return 'se'; + case 'se': return 'nw'; + case 'sw': return 'ne'; + }; + }; + /*}}}*/ + function createDragger(ord)/*{{{*/ + { + return function(e) { + if (options.disabled) return false; + if ((ord == 'move') && !options.allowMove) return false; + btndown = true; + startDragMode(ord,mouseAbs(e)); + e.stopPropagation(); + e.preventDefault(); + return false; + }; + }; + /*}}}*/ + function presize($obj,w,h)/*{{{*/ + { + var nw = $obj.width(), nh = $obj.height(); + if ((nw > w) && w > 0) + { + nw = w; + nh = (w/$obj.width()) * $obj.height(); + } + if ((nh > h) && h > 0) + { + nh = h; + nw = (h/$obj.height()) * $obj.width(); + } + xscale = $obj.width() / nw; + yscale = $obj.height() / nh; + $obj.width(nw).height(nh); + }; + /*}}}*/ + function unscale(c)/*{{{*/ + { + return { + x: parseInt(c.x * xscale), y: parseInt(c.y * yscale), + x2: parseInt(c.x2 * xscale), y2: parseInt(c.y2 * yscale), + w: parseInt(c.w * xscale), h: parseInt(c.h * yscale) + }; + }; + /*}}}*/ + function doneSelect(pos)/*{{{*/ + { + var c = Coords.getFixed(); + if (c.w > options.minSelect[0] && c.h > options.minSelect[1]) + { + Selection.enableHandles(); + Selection.done(); + } + else + { + Selection.release(); + } + Tracker.setCursor( options.allowSelect?'crosshair':'default' ); + }; + /*}}}*/ + function newSelection(e)/*{{{*/ + { + if (options.disabled) return false; + if (!options.allowSelect) return false; + btndown = true; + docOffset = getPos($img); + Selection.disableHandles(); + myCursor('crosshair'); + var pos = mouseAbs(e); + Coords.setPressed(pos); + Tracker.activateHandlers(selectDrag,doneSelect); + KeyManager.watchKeys(); + Selection.update(); + + e.stopPropagation(); + e.preventDefault(); + return false; + }; + /*}}}*/ + function selectDrag(pos)/*{{{*/ + { + Coords.setCurrent(pos); + Selection.update(); + }; + /*}}}*/ + function newTracker() + { + var trk = $('
    ').addClass(cssClass('tracker')); + $.browser.msie && trk.css({ opacity: 0, backgroundColor: 'white' }); + return trk; + }; + + // }}} + // API methods {{{ + + function animateTo(a)/*{{{*/ + { + var x1 = a[0] / xscale, + y1 = a[1] / yscale, + x2 = a[2] / xscale, + y2 = a[3] / yscale; + + if (animating) return; + + var animto = Coords.flipCoords(x1,y1,x2,y2); + var c = Coords.getFixed(); + var animat = initcr = [ c.x, c.y, c.x2, c.y2 ]; + var interv = options.animationDelay; + + var x = animat[0]; + var y = animat[1]; + var x2 = animat[2]; + var y2 = animat[3]; + var ix1 = animto[0] - initcr[0]; + var iy1 = animto[1] - initcr[1]; + var ix2 = animto[2] - initcr[2]; + var iy2 = animto[3] - initcr[3]; + var pcent = 0; + var velocity = options.swingSpeed; + + Selection.animMode(true); + + var animator = function() + { + return function() + { + pcent += (100 - pcent) / velocity; + + animat[0] = x + ((pcent / 100) * ix1); + animat[1] = y + ((pcent / 100) * iy1); + animat[2] = x2 + ((pcent / 100) * ix2); + animat[3] = y2 + ((pcent / 100) * iy2); + + if (pcent < 100) animateStart(); + else Selection.done(); + + if (pcent >= 99.8) pcent = 100; + + setSelectRaw(animat); + }; + }(); + + function animateStart() + { window.setTimeout(animator,interv); }; + + animateStart(); + }; + /*}}}*/ + function setSelect(rect)//{{{ + { + setSelectRaw([rect[0]/xscale,rect[1]/yscale,rect[2]/xscale,rect[3]/yscale]); + }; + //}}} + function setSelectRaw(l) /*{{{*/ + { + Coords.setPressed([l[0],l[1]]); + Coords.setCurrent([l[2],l[3]]); + Selection.update(); + }; + /*}}}*/ + function setOptions(opt)/*{{{*/ + { + if (typeof(opt) != 'object') opt = { }; + options = $.extend(options,opt); + + if (typeof(options.onChange)!=='function') + options.onChange = function() { }; + + if (typeof(options.onSelect)!=='function') + options.onSelect = function() { }; + + }; + /*}}}*/ + function tellSelect()/*{{{*/ + { + return unscale(Coords.getFixed()); + }; + /*}}}*/ + function tellScaled()/*{{{*/ + { + return Coords.getFixed(); + }; + /*}}}*/ + function setOptionsNew(opt)/*{{{*/ + { + setOptions(opt); + interfaceUpdate(); + }; + /*}}}*/ + function disableCrop()//{{{ + { + options.disabled = true; + Selection.disableHandles(); + Selection.setCursor('default'); + Tracker.setCursor('default'); + }; + //}}} + function enableCrop()//{{{ + { + options.disabled = false; + interfaceUpdate(); + }; + //}}} + function cancelCrop()//{{{ + { + Selection.done(); + Tracker.activateHandlers(null,null); + }; + //}}} + function destroy()//{{{ + { + $div.remove(); + $origimg.show(); + }; + //}}} + + function interfaceUpdate(alt)//{{{ + // This method tweaks the interface based on options object. + // Called when options are changed and at end of initialization. + { + options.allowResize ? + alt?Selection.enableOnly():Selection.enableHandles(): + Selection.disableHandles(); + + Tracker.setCursor( options.allowSelect? 'crosshair': 'default' ); + Selection.setCursor( options.allowMove? 'move': 'default' ); + + $div.css('backgroundColor',options.bgColor); + + if ('setSelect' in options) { + setSelect(opt.setSelect); + Selection.done(); + delete(options.setSelect); + } + + if ('trueSize' in options) { + xscale = options.trueSize[0] / boundx; + yscale = options.trueSize[1] / boundy; + } + + xlimit = options.maxSize[0] || 0; + ylimit = options.maxSize[1] || 0; + xmin = options.minSize[0] || 0; + ymin = options.minSize[1] || 0; + + if ('outerImage' in options) + { + $img.attr('src',options.outerImage); + delete(options.outerImage); + } + + Selection.refresh(); + }; + //}}} + + // }}} + + $hdl_holder.hide(); + interfaceUpdate(true); + + var api = { + animateTo: animateTo, + setSelect: setSelect, + setOptions: setOptionsNew, + tellSelect: tellSelect, + tellScaled: tellScaled, + + disable: disableCrop, + enable: enableCrop, + cancel: cancelCrop, + + focus: KeyManager.watchKeys, + + getBounds: function() { return [ boundx * xscale, boundy * yscale ]; }, + getWidgetSize: function() { return [ boundx, boundy ]; }, + + release: Selection.release, + destroy: destroy + + }; + + $origimg.data('Jcrop',api); + return api; +}; + +$.fn.Jcrop = function(options)/*{{{*/ +{ + function attachWhenDone(from)/*{{{*/ + { + var loadsrc = options.useImg || from.src; + var img = new Image(); + img.onload = function() { $.Jcrop(from,options); }; + img.src = loadsrc; + }; + /*}}}*/ + if (typeof(options) !== 'object') options = { }; + + // Iterate over each object, attach Jcrop + this.each(function() + { + // If we've already attached to this object + if ($(this).data('Jcrop')) + { + // The API can be requested this way (undocumented) + if (options == 'api') return $(this).data('Jcrop'); + // Otherwise, we just reset the options... + else $(this).data('Jcrop').setOptions(options); + } + // If we haven't been attached, preload and attach + else attachWhenDone(this); + }); + + // Return "this" so we're chainable a la jQuery plugin-style! + return this; +}; +/*}}}*/ + +})(jQuery); diff --git a/src/wp-includes/js/jcrop/jquery.Jcrop.js b/src/wp-includes/js/jcrop/jquery.Jcrop.js new file mode 100644 index 00000000..70b55053 --- /dev/null +++ b/src/wp-includes/js/jcrop/jquery.Jcrop.js @@ -0,0 +1 @@ +(function(a){a.Jcrop=function(d,A){var d=d,A=A;if(typeof(d)!=="object"){d=a(d)[0]}if(typeof(A)!=="object"){A={}}if(!("trackDocument" in A)){A.trackDocument=a.browser.msie?false:true;if(a.browser.msie&&a.browser.version.split(".")[0]=="8"){A.trackDocument=true}}if(!("keySupport" in A)){A.keySupport=a.browser.msie?false:true}var U={trackDocument:false,baseClass:"jcrop",addClass:null,bgColor:"black",bgOpacity:0.6,borderOpacity:0.4,handleOpacity:0.5,handlePad:5,handleSize:9,handleOffset:5,edgeMargin:14,aspectRatio:0,keySupport:true,cornerHandles:true,sideHandles:true,drawBorders:true,dragEdges:true,boxWidth:0,boxHeight:0,boundary:8,animationDelay:20,swingSpeed:3,allowSelect:true,allowMove:true,allowResize:true,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){}};var H=U;z(A);var W=a(d);var al=W.clone().removeAttr("id").css({position:"absolute"});al.width(W.width());al.height(W.height());W.after(al).hide();T(al,H.boxWidth,H.boxHeight);var Q=al.width(),O=al.height(),Z=a("
    ").width(Q).height(O).addClass(C("holder")).css({position:"relative",backgroundColor:H.bgColor}).insertAfter(W).append(al);if(H.addClass){Z.addClass(H.addClass)}var I=a("").attr("src",al.attr("src")).css("position","absolute").width(Q).height(O);var k=a("
    ").width(K(100)).height(K(100)).css({zIndex:310,position:"absolute",overflow:"hidden"}).append(I);var L=a("
    ").width(K(100)).height(K(100)).css("zIndex",320);var y=a("
    ").css({position:"absolute",zIndex:300}).insertBefore(al).append(k,L);var t=H.boundary;var b=ae().width(Q+(t*2)).height(O+(t*2)).css({position:"absolute",top:l(-t),left:l(-t),zIndex:290}).mousedown(ac);var x,ah,p,S;var M,e,n=true;var ad=D(al),r,an,am,B,ab;var aa=function(){var aq=0,aC=0,ap=0,aB=0,au,ar;function aw(aF){var aF=at(aF);ap=aq=aF[0];aB=aC=aF[1]}function av(aF){var aF=at(aF);au=aF[0]-ap;ar=aF[1]-aB;ap=aF[0];aB=aF[1]}function aE(){return[au,ar]}function ao(aH){var aG=aH[0],aF=aH[1];if(0>aq+aG){aG-=aG+aq}if(0>aC+aF){aF-=aF+aC}if(OQ){aF=Q;h=Math.abs((aF-aq)/aH);aM=aP<0?aC-h:h+aC}}}else{aF=ap;h=aJ/aH;aM=aP<0?aC-h:aC+h;if(aM<0){aM=0;w=Math.abs((aM-aC)*aH);aF=aI<0?aq-w:w+aq}else{if(aM>O){aM=O;w=Math.abs(aM-aC)*aH;aF=aI<0?aq-w:w+aq}}}if(aF>aq){if(aF-aqaG){aF=aq+aG}}if(aM>aC){aM=aC+(aF-aq)/aH}else{aM=aC-(aF-aq)/aH}}else{if(aFaG){aF=aq-aG}}if(aM>aC){aM=aC+(aq-aF)/aH}else{aM=aC-(aq-aF)/aH}}}if(aF<0){aq-=aF;aF=0}else{if(aF>Q){aq-=aF-Q;aF=Q}}if(aM<0){aC-=aM;aM=0}else{if(aM>O){aC-=aM-O;aM=O}}return last=az(ay(aq,aC,aF,aM))}function at(aF){if(aF[0]<0){aF[0]=0}if(aF[1]<0){aF[1]=0}if(aF[0]>Q){aF[0]=Q}if(aF[1]>O){aF[1]=O}return[aF[0],aF[1]]}function ay(aI,aK,aH,aJ){var aM=aI,aL=aH,aG=aK,aF=aJ;if(aHx)){ap=(aG>0)?(aq+x):(aq-x)}if(ah&&(Math.abs(aF)>ah)){aB=(aF>0)?(aC+ah):(aC-ah)}if(S&&(Math.abs(aF)0)?(aC+S):(aC-S)}if(p&&(Math.abs(aG)0)?(aq+p):(aq-p)}if(aq<0){ap-=aq;aq-=aq}if(aC<0){aB-=aC;aC-=aC}if(ap<0){aq-=ap;ap-=ap}if(aB<0){aC-=aB;aB-=aB}if(ap>Q){var aH=ap-Q;aq-=aH;ap-=aH}if(aB>O){var aH=aB-O;aC-=aH;aB-=aH}if(aq>Q){var aH=aq-O;aB-=aH;aC-=aH}if(aC>O){var aH=aC-O;aB-=aH;aC-=aH}return az(ay(aq,aC,ap,aB))}function az(aF){return{x:aF[0],y:aF[1],x2:aF[2],y2:aF[3],w:aF[2]-aF[0],h:aF[3]-aF[1]}}return{flipCoords:ay,setPressed:aw,setCurrent:av,getOffset:aE,moveOffset:ao,getCorner:ax,getFixed:aD}}();var X=function(){var aw,ar,aC,aB,aK=370;var av={};var aO={};var aq=false;var aA=H.handleOffset;if(H.drawBorders){av={top:ax("hline").css("top",a.browser.msie?l(-1):l(0)),bottom:ax("hline"),left:ax("vline"),right:ax("vline")}}if(H.dragEdges){aO.t=aJ("n");aO.b=aJ("s");aO.r=aJ("e");aO.l=aJ("w")}H.sideHandles&&aF(["n","s","e","w"]);H.cornerHandles&&aF(["sw","nw","ne","se"]);function ax(aR){var aS=a("
    ").css({position:"absolute",opacity:H.borderOpacity}).addClass(C(aR));k.append(aS);return aS}function ap(aR,aS){var aT=a("
    ").mousedown(c(aR)).css({cursor:aR+"-resize",position:"absolute",zIndex:aS});L.append(aT);return aT}function aD(aR){return ap(aR,aK++).css({top:l(-aA+1),left:l(-aA+1),opacity:H.handleOpacity}).addClass(C("handle"))}function aJ(aT){var aW=H.handleSize,aX=aA,aV=aW,aS=aW,aU=aX,aR=aX;switch(aT){case"n":case"s":aS=K(100);break;case"e":case"w":aV=K(100);break}return ap(aT,aK++).width(aS).height(aV).css({top:l(-aU+1),left:l(-aR+1)})}function aF(aR){for(i in aR){aO[aR[i]]=aD(aR[i])}}function aH(aY){var aT=Math.round((aY.h/2)-aA),aS=Math.round((aY.w/2)-aA),aW=west=-aA+1,aV=aY.w-aA,aU=aY.h-aA,aR,aX;"e" in aO&&aO.e.css({top:l(aT),left:l(aV)})&&aO.w.css({top:l(aT)})&&aO.s.css({top:l(aU),left:l(aS)})&&aO.n.css({left:l(aS)});"ne" in aO&&aO.ne.css({left:l(aV)})&&aO.se.css({top:l(aU),left:l(aV)})&&aO.sw.css({top:l(aU)});"b" in aO&&aO.b.css({top:l(aU)})&&aO.r.css({left:l(aV)})}function az(aR,aS){I.css({top:l(-aS),left:l(-aR)});y.css({top:l(aS),left:l(aR)})}function aQ(aR,aS){y.width(aR).height(aS)}function at(){var aR=aa.getFixed();aa.setPressed([aR.x,aR.y]);aa.setCurrent([aR.x2,aR.y2]);aN()}function aN(){if(aB){return ay()}}function ay(){var aR=aa.getFixed();aQ(aR.w,aR.h);az(aR.x,aR.y);H.drawBorders&&av.right.css({left:l(aR.w-1)})&&av.bottom.css({top:l(aR.h-1)});aq&&aH(aR);aB||aP();H.onChange(Y(aR))}function aP(){y.show();al.css("opacity",H.bgOpacity);aB=true}function aL(){aM();y.hide();al.css("opacity",1);aB=false}function ao(){if(aq){aH(aa.getFixed());L.show()}}function aG(){aq=true;if(H.allowResize){aH(aa.getFixed());L.show();return true}}function aM(){aq=false;L.hide()}function aI(aR){(B=aR)?aM():aG()}function aE(){aI(false);at()}var au=ae().mousedown(c("move")).css({cursor:"move",position:"absolute",zIndex:360});k.append(au);aM();return{updateVisible:aN,update:ay,release:aL,refresh:at,setCursor:function(aR){au.css("cursor",aR)},enableHandles:aG,enableOnly:function(){aq=true},showHandles:ao,disableHandles:aM,animMode:aI,done:aE}}();var P=function(){var ap=function(){},ar=function(){},aq=H.trackDocument;if(!aq){b.mousemove(ao).mouseup(at).mouseout(at)}function ax(){b.css({zIndex:450});if(aq){a(document).mousemove(ao).mouseup(at)}}function aw(){b.css({zIndex:290});if(aq){a(document).unbind("mousemove",ao).unbind("mouseup",at)}}function ao(ay){ap(F(ay))}function at(ay){ay.preventDefault();ay.stopPropagation();if(r){r=false;ar(F(ay));H.onSelect(Y(aa.getFixed()));aw();ap=function(){};ar=function(){}}return false}function au(az,ay){r=true;ap=az;ar=ay;ax();return false}function av(ay){b.css("cursor",ay)}al.before(b);return{activateHandlers:au,setCursor:av}}();var ak=function(){var ar=a('').css({position:"absolute",left:"-30px"}).keypress(ao).blur(at),au=a("
    ").css({position:"absolute",overflow:"hidden"}).append(ar);function ap(){if(H.keySupport){ar.show();ar.focus()}}function at(av){ar.hide()}function aq(aw,av,ax){if(H.allowMove){aa.moveOffset([av,ax]);X.updateVisible()}aw.preventDefault();aw.stopPropagation()}function ao(aw){if(aw.ctrlKey){return true}ab=aw.shiftKey?true:false;var av=ab?10:1;switch(aw.keyCode){case 37:aq(aw,-av,0);break;case 39:aq(aw,av,0);break;case 38:aq(aw,0,-av);break;case 40:aq(aw,0,av);break;case 27:X.release();break;case 9:return true}return nothing(aw)}if(H.keySupport){au.insertBefore(al)}return{watchKeys:ap}}();function l(ao){return""+parseInt(ao)+"px"}function K(ao){return""+parseInt(ao)+"%"}function C(ao){return H.baseClass+"-"+ao}function D(ao){var ap=a(ao).offset();return[ap.left,ap.top]}function F(ao){return[(ao.pageX-ad[0]),(ao.pageY-ad[1])]}function E(ao){if(ao!=an){P.setCursor(ao);an=ao}}function f(aq,at){ad=D(al);P.setCursor(aq=="move"?aq:aq+"-resize");if(aq=="move"){return P.activateHandlers(R(at),o)}var ao=aa.getFixed();var ap=q(aq);var ar=aa.getCorner(q(ap));aa.setPressed(aa.getCorner(ap));aa.setCurrent(ar);P.activateHandlers(G(aq,ao),o)}function G(ap,ao){return function(aq){if(!H.aspectRatio){switch(ap){case"e":aq[1]=ao.y2;break;case"w":aq[1]=ao.y2;break;case"n":aq[0]=ao.x2;break;case"s":aq[0]=ao.x2;break}}else{switch(ap){case"e":aq[1]=ao.y+1;break;case"w":aq[1]=ao.y+1;break;case"n":aq[0]=ao.x+1;break;case"s":aq[0]=ao.x+1;break}}aa.setCurrent(aq);X.update()}}function R(ap){var ao=ap;ak.watchKeys();return function(aq){aa.moveOffset([aq[0]-ao[0],aq[1]-ao[1]]);ao=aq;X.update()}}function q(ao){switch(ao){case"n":return"sw";case"s":return"nw";case"e":return"nw";case"w":return"ne";case"ne":return"sw";case"nw":return"se";case"se":return"nw";case"sw":return"ne"}}function c(ao){return function(ap){if(H.disabled){return false}if((ao=="move")&&!H.allowMove){return false}r=true;f(ao,F(ap));ap.stopPropagation();ap.preventDefault();return false}}function T(at,ap,ar){var ao=at.width(),aq=at.height();if((ao>ap)&&ap>0){ao=ap;aq=(ap/at.width())*at.height()}if((aq>ar)&&ar>0){aq=ar;ao=(ar/at.height())*at.width()}M=at.width()/ao;e=at.height()/aq;at.width(ao).height(aq)}function Y(ao){return{x:parseInt(ao.x*M),y:parseInt(ao.y*e),x2:parseInt(ao.x2*M),y2:parseInt(ao.y2*e),w:parseInt(ao.w*M),h:parseInt(ao.h*e)}}function o(ap){var ao=aa.getFixed();if(ao.w>H.minSelect[0]&&ao.h>H.minSelect[1]){X.enableHandles();X.done()}else{X.release()}P.setCursor(H.allowSelect?"crosshair":"default")}function ac(ao){if(H.disabled){return false}if(!H.allowSelect){return false}r=true;ad=D(al);X.disableHandles();E("crosshair");var ap=F(ao);aa.setPressed(ap);P.activateHandlers(aj,o);ak.watchKeys();X.update();ao.stopPropagation();ao.preventDefault();return false}function aj(ao){aa.setCurrent(ao);X.update()}function ae(){var ao=a("
    ").addClass(C("tracker"));a.browser.msie&&ao.css({opacity:0,backgroundColor:"white"});return ao}function s(aG){var aB=aG[0]/M,ap=aG[1]/e,aA=aG[2]/M,ao=aG[3]/e;if(B){return}var az=aa.flipCoords(aB,ap,aA,ao);var aE=aa.getFixed();var ar=initcr=[aE.x,aE.y,aE.x2,aE.y2];var aq=H.animationDelay;var ax=ar[0];var aw=ar[1];var aA=ar[2];var ao=ar[3];var aD=az[0]-initcr[0];var au=az[1]-initcr[1];var aC=az[2]-initcr[2];var at=az[3]-initcr[3];var ay=0;var av=H.swingSpeed;X.animMode(true);var aF=function(){return function(){ay+=(100-ay)/av;ar[0]=ax+((ay/100)*aD);ar[1]=aw+((ay/100)*au);ar[2]=aA+((ay/100)*aC);ar[3]=ao+((ay/100)*at);if(ay<100){aH()}else{X.done()}if(ay>=99.8){ay=100}ai(ar)}}();function aH(){window.setTimeout(aF,aq)}aH()}function J(ao){ai([ao[0]/M,ao[1]/e,ao[2]/M,ao[3]/e])}function ai(ao){aa.setPressed([ao[0],ao[1]]);aa.setCurrent([ao[2],ao[3]]);X.update()}function z(ao){if(typeof(ao)!="object"){ao={}}H=a.extend(H,ao);if(typeof(H.onChange)!=="function"){H.onChange=function(){}}if(typeof(H.onSelect)!=="function"){H.onSelect=function(){}}}function j(){return Y(aa.getFixed())}function ag(){return aa.getFixed()}function u(ao){z(ao);N()}function v(){H.disabled=true;X.disableHandles();X.setCursor("default");P.setCursor("default")}function V(){H.disabled=false;N()}function m(){X.done();P.activateHandlers(null,null)}function af(){Z.remove();W.show()}function N(ao){H.allowResize?ao?X.enableOnly():X.enableHandles():X.disableHandles();P.setCursor(H.allowSelect?"crosshair":"default");X.setCursor(H.allowMove?"move":"default");Z.css("backgroundColor",H.bgColor);if("setSelect" in H){J(A.setSelect);X.done();delete (H.setSelect)}if("trueSize" in H){M=H.trueSize[0]/Q;e=H.trueSize[1]/O}x=H.maxSize[0]||0;ah=H.maxSize[1]||0;p=H.minSize[0]||0;S=H.minSize[1]||0;if("outerImage" in H){al.attr("src",H.outerImage);delete (H.outerImage)}X.refresh()}L.hide();N(true);var g={animateTo:s,setSelect:J,setOptions:u,tellSelect:j,tellScaled:ag,disable:v,enable:V,cancel:m,focus:ak.watchKeys,getBounds:function(){return[Q*M,O*e]},getWidgetSize:function(){return[Q,O]},release:X.release,destroy:af};W.data("Jcrop",g);return g};a.fn.Jcrop=function(c){function b(f){var e=c.useImg||f.src;var d=new Image();d.onload=function(){a.Jcrop(f,c)};d.src=e}if(typeof(c)!=="object"){c={}}this.each(function(){if(a(this).data("Jcrop")){if(c=="api"){return a(this).data("Jcrop")}else{a(this).data("Jcrop").setOptions(c)}}else{b(this)}});return this}})(jQuery); \ No newline at end of file diff --git a/src/wp-includes/js/jquery/jquery.color.dev.js b/src/wp-includes/js/jquery/jquery.color.dev.js new file mode 100644 index 00000000..1dffbd5c --- /dev/null +++ b/src/wp-includes/js/jquery/jquery.color.dev.js @@ -0,0 +1,128 @@ +/* + * jQuery Color Animations + * Copyright 2007 John Resig + * Released under the MIT and GPL licenses. + */ + +(function(jQuery){ + + // We override the animation for all of these color styles + jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){ + jQuery.fx.step[attr] = function(fx){ + if ( fx.state == 0 ) { + fx.start = getColor( fx.elem, attr ); + fx.end = getRGB( fx.end ); + } + + fx.elem.style[attr] = "rgb(" + [ + Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0), + Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0), + Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0) + ].join(",") + ")"; + } + }); + + // Color Conversion functions from highlightFade + // By Blair Mitchelmore + // http://jquery.offput.ca/highlightFade/ + + // Parse strings looking for color tuples [255,255,255] + function getRGB(color) { + var result; + + // Check if we're already dealing with an array of colors + if ( color && color.constructor == Array && color.length == 3 ) + return color; + + // Look for rgb(num,num,num) + if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) + return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])]; + + // Look for rgb(num%,num%,num%) + if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) + return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; + + // Look for #a0b1c2 + if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) + return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; + + // Look for #fff + if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) + return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; + + // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 + if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) + return colors['transparent'] + + // Otherwise, we're most likely dealing with a named color + return colors[jQuery.trim(color).toLowerCase()]; + } + + function getColor(elem, attr) { + var color; + + do { + color = jQuery.curCSS(elem, attr); + + // Keep going until we find an element that has color, or we hit the body + if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") ) + break; + + attr = "backgroundColor"; + } while ( elem = elem.parentNode ); + + return getRGB(color); + }; + + // Some named colors to work with + // From Interface by Stefan Petre + // http://interface.eyecon.ro/ + + var colors = { + aqua:[0,255,255], + azure:[240,255,255], + beige:[245,245,220], + black:[0,0,0], + blue:[0,0,255], + brown:[165,42,42], + cyan:[0,255,255], + darkblue:[0,0,139], + darkcyan:[0,139,139], + darkgrey:[169,169,169], + darkgreen:[0,100,0], + darkkhaki:[189,183,107], + darkmagenta:[139,0,139], + darkolivegreen:[85,107,47], + darkorange:[255,140,0], + darkorchid:[153,50,204], + darkred:[139,0,0], + darksalmon:[233,150,122], + darkviolet:[148,0,211], + fuchsia:[255,0,255], + gold:[255,215,0], + green:[0,128,0], + indigo:[75,0,130], + khaki:[240,230,140], + lightblue:[173,216,230], + lightcyan:[224,255,255], + lightgreen:[144,238,144], + lightgrey:[211,211,211], + lightpink:[255,182,193], + lightyellow:[255,255,224], + lime:[0,255,0], + magenta:[255,0,255], + maroon:[128,0,0], + navy:[0,0,128], + olive:[128,128,0], + orange:[255,165,0], + pink:[255,192,203], + purple:[128,0,128], + violet:[128,0,128], + red:[255,0,0], + silver:[192,192,192], + white:[255,255,255], + yellow:[255,255,0], + transparent: [255,255,255] + }; + +})(jQuery); diff --git a/src/wp-includes/js/jquery/jquery.color.js b/src/wp-includes/js/jquery/jquery.color.js new file mode 100644 index 00000000..03c13f64 --- /dev/null +++ b/src/wp-includes/js/jquery/jquery.color.js @@ -0,0 +1 @@ +(function(d){d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(f,e){d.fx.step[e]=function(g){if(g.state==0){g.start=c(g.elem,e);g.end=b(g.end)}g.elem.style[e]="rgb("+[Math.max(Math.min(parseInt((g.pos*(g.end[0]-g.start[0]))+g.start[0]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[1]-g.start[1]))+g.start[1]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[2]-g.start[2]))+g.start[2]),255),0)].join(",")+")"}});function b(f){var e;if(f&&f.constructor==Array&&f.length==3){return f}if(e=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(f)){return[parseInt(e[1]),parseInt(e[2]),parseInt(e[3])]}if(e=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(f)){return[parseFloat(e[1])*2.55,parseFloat(e[2])*2.55,parseFloat(e[3])*2.55]}if(e=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(f)){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}if(e=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(f)){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}if(e=/rgba\(0, 0, 0, 0\)/.exec(f)){return a.transparent}return a[d.trim(f).toLowerCase()]}function c(g,e){var f;do{f=d.curCSS(g,e);if(f!=""&&f!="transparent"||d.nodeName(g,"body")){break}e="backgroundColor"}while(g=g.parentNode);return b(f)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]}})(jQuery); \ No newline at end of file diff --git a/src/wp-includes/js/jquery/jquery.form.dev.js b/src/wp-includes/js/jquery/jquery.form.dev.js new file mode 100644 index 00000000..2ee5c962 --- /dev/null +++ b/src/wp-includes/js/jquery/jquery.form.dev.js @@ -0,0 +1,872 @@ +/* + * jQuery Form Plugin + * version: 2.02 (12/16/2007) + * @requires jQuery v1.1 or later + * + * Examples at: http://malsup.com/jquery/form/ + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Revision: $Id$ + */ + (function($) { +/** + * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX. + * + * ajaxSubmit accepts a single argument which can be either a success callback function + * or an options Object. If a function is provided it will be invoked upon successful + * completion of the submit and will be passed the response from the server. + * If an options Object is provided, the following attributes are supported: + * + * target: Identifies the element(s) in the page to be updated with the server response. + * This value may be specified as a jQuery selection string, a jQuery object, + * or a DOM element. + * default value: null + * + * url: URL to which the form data will be submitted. + * default value: value of form's 'action' attribute + * + * type: The method in which the form data should be submitted, 'GET' or 'POST'. + * default value: value of form's 'method' attribute (or 'GET' if none found) + * + * data: Additional data to add to the request, specified as key/value pairs (see $.ajax). + * + * beforeSubmit: Callback method to be invoked before the form is submitted. + * default value: null + * + * success: Callback method to be invoked after the form has been successfully submitted + * and the response has been returned from the server + * default value: null + * + * dataType: Expected dataType of the response. One of: null, 'xml', 'script', or 'json' + * default value: null + * + * semantic: Boolean flag indicating whether data must be submitted in semantic order (slower). + * default value: false + * + * resetForm: Boolean flag indicating whether the form should be reset if the submit is successful + * + * clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful + * + * + * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for + * validating the form data. If the 'beforeSubmit' callback returns false then the form will + * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data + * in array format, the jQuery object, and the options object passed into ajaxSubmit. + * The form data array takes the following form: + * + * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] + * + * If a 'success' callback method is provided it is invoked after the response has been returned + * from the server. It is passed the responseText or responseXML value (depending on dataType). + * See jQuery.ajax for further details. + * + * + * The dataType option provides a means for specifying how the server response should be handled. + * This maps directly to the jQuery.httpData method. The following values are supported: + * + * 'xml': if dataType == 'xml' the server response is treated as XML and the 'success' + * callback method, if specified, will be passed the responseXML value + * 'json': if dataType == 'json' the server response will be evaluted and passed to + * the 'success' callback, if specified + * 'script': if dataType == 'script' the server response is evaluated in the global context + * + * + * Note that it does not make sense to use both the 'target' and 'dataType' options. If both + * are provided the target will be ignored. + * + * The semantic argument can be used to force form serialization in semantic order. + * This is normally true anyway, unless the form contains input elements of type='image'. + * If your form must be submitted with name/value pairs in semantic order and your form + * contains an input of type='image" then pass true for this arg, otherwise pass false + * (or nothing) to avoid the overhead for this logic. + * + * + * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this: + * + * $("#form-id").submit(function() { + * $(this).ajaxSubmit(options); + * return false; // cancel conventional submit + * }); + * + * When using ajaxForm(), however, this is done for you. + * + * @example + * $('#myForm').ajaxSubmit(function(data) { + * alert('Form submit succeeded! Server returned: ' + data); + * }); + * @desc Submit form and alert server response + * + * + * @example + * var options = { + * target: '#myTargetDiv' + * }; + * $('#myForm').ajaxSubmit(options); + * @desc Submit form and update page element with server response + * + * + * @example + * var options = { + * success: function(responseText) { + * alert(responseText); + * } + * }; + * $('#myForm').ajaxSubmit(options); + * @desc Submit form and alert the server response + * + * + * @example + * var options = { + * beforeSubmit: function(formArray, jqForm) { + * if (formArray.length == 0) { + * alert('Please enter data.'); + * return false; + * } + * } + * }; + * $('#myForm').ajaxSubmit(options); + * @desc Pre-submit validation which aborts the submit operation if form data is empty + * + * + * @example + * var options = { + * url: myJsonUrl.php, + * dataType: 'json', + * success: function(data) { + * // 'data' is an object representing the the evaluated json data + * } + * }; + * $('#myForm').ajaxSubmit(options); + * @desc json data returned and evaluated + * + * + * @example + * var options = { + * url: myXmlUrl.php, + * dataType: 'xml', + * success: function(responseXML) { + * // responseXML is XML document object + * var data = $('myElement', responseXML).text(); + * } + * }; + * $('#myForm').ajaxSubmit(options); + * @desc XML data returned from server + * + * + * @example + * var options = { + * resetForm: true + * }; + * $('#myForm').ajaxSubmit(options); + * @desc submit form and reset it if successful + * + * @example + * $('#myForm).submit(function() { + * $(this).ajaxSubmit(); + * return false; + * }); + * @desc Bind form's submit event to use ajaxSubmit + * + * + * @name ajaxSubmit + * @type jQuery + * @param options object literal containing options which control the form submission process + * @cat Plugins/Form + * @return jQuery + */ +$.fn.ajaxSubmit = function(options) { + if (typeof options == 'function') + options = { success: options }; + + options = $.extend({ + url: this.attr('action') || window.location.toString(), + type: this.attr('method') || 'GET' + }, options || {}); + + // hook for manipulating the form data before it is extracted; + // convenient for use with rich editors like tinyMCE or FCKEditor + var veto = {}; + $.event.trigger('form.pre.serialize', [this, options, veto]); + if (veto.veto) return this; + + var a = this.formToArray(options.semantic); + if (options.data) { + for (var n in options.data) + a.push( { name: n, value: options.data[n] } ); + } + + // give pre-submit callback an opportunity to abort the submit + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this; + + // fire vetoable 'validate' event + $.event.trigger('form.submit.validate', [a, this, options, veto]); + if (veto.veto) return this; + + var q = $.param(a);//.replace(/%20/g,'+'); + + if (options.type.toUpperCase() == 'GET') { + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; + options.data = null; // data is null for 'get' + } + else + options.data = q; // data is the query string for 'post' + + var $form = this, callbacks = []; + if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); + if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); + + // perform a load on the target only if dataType is not provided + if (!options.dataType && options.target) { + var oldSuccess = options.success || function(){}; + callbacks.push(function(data) { + if (this.evalScripts) + $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments); + else // jQuery v1.1.4 + $(options.target).html(data).each(oldSuccess, arguments); + }); + } + else if (options.success) + callbacks.push(options.success); + + options.success = function(data, status) { + for (var i=0, max=callbacks.length; i < max; i++) + callbacks[i](data, status, $form); + }; + + // are there files to upload? + var files = $('input:file', this).fieldValue(); + var found = false; + for (var j=0; j < files.length; j++) + if (files[j]) + found = true; + + // options.iframe allows user to force iframe mode + if (options.iframe || found) { + // hack to fix Safari hang (thanks to Tim Molendijk for this) + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d + if ($.browser.safari && options.closeKeepAlive) + $.get(options.closeKeepAlive, fileUpload); + else + fileUpload(); + } + else + $.ajax(options); + + // fire 'notify' event + $.event.trigger('form.submit.notify', [this, options]); + return this; + + + // private function for handling file uploads (hat tip to YAHOO!) + function fileUpload() { + var form = $form[0]; + var opts = $.extend({}, $.ajaxSettings, options); + + var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++; + var $io = $(''); + this.iefix = $(this.update.id+'_iefix'); + } + if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); + }, + + fixIEOverlapping: function() { + Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); + this.iefix.style.zIndex = 1; + this.update.style.zIndex = 2; + Element.show(this.iefix); + }, + + hide: function() { + this.stopIndicator(); + if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); + if(this.iefix) Element.hide(this.iefix); + }, + + startIndicator: function() { + if(this.options.indicator) Element.show(this.options.indicator); + }, + + stopIndicator: function() { + if(this.options.indicator) Element.hide(this.options.indicator); + }, + + onKeyPress: function(event) { + if(this.active) + switch(event.keyCode) { + case Event.KEY_TAB: + case Event.KEY_RETURN: + this.selectEntry(); + Event.stop(event); + case Event.KEY_ESC: + this.hide(); + this.active = false; + Event.stop(event); + return; + case Event.KEY_LEFT: + case Event.KEY_RIGHT: + return; + case Event.KEY_UP: + this.markPrevious(); + this.render(); + Event.stop(event); + return; + case Event.KEY_DOWN: + this.markNext(); + this.render(); + Event.stop(event); + return; + } + else + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || + (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; + + this.changed = true; + this.hasFocus = true; + + if(this.observer) clearTimeout(this.observer); + this.observer = + setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); + }, + + activate: function() { + this.changed = false; + this.hasFocus = true; + this.getUpdatedChoices(); + }, + + onHover: function(event) { + var element = Event.findElement(event, 'LI'); + if(this.index != element.autocompleteIndex) + { + this.index = element.autocompleteIndex; + this.render(); + } + Event.stop(event); + }, + + onClick: function(event) { + var element = Event.findElement(event, 'LI'); + this.index = element.autocompleteIndex; + this.selectEntry(); + this.hide(); + }, + + onBlur: function(event) { + // needed to make click events working + setTimeout(this.hide.bind(this), 250); + this.hasFocus = false; + this.active = false; + }, + + render: function() { + if(this.entryCount > 0) { + for (var i = 0; i < this.entryCount; i++) + this.index==i ? + Element.addClassName(this.getEntry(i),"selected") : + Element.removeClassName(this.getEntry(i),"selected"); + if(this.hasFocus) { + this.show(); + this.active = true; + } + } else { + this.active = false; + this.hide(); + } + }, + + markPrevious: function() { + if(this.index > 0) this.index--; + else this.index = this.entryCount-1; + this.getEntry(this.index).scrollIntoView(true); + }, + + markNext: function() { + if(this.index < this.entryCount-1) this.index++; + else this.index = 0; + this.getEntry(this.index).scrollIntoView(false); + }, + + getEntry: function(index) { + return this.update.firstChild.childNodes[index]; + }, + + getCurrentEntry: function() { + return this.getEntry(this.index); + }, + + selectEntry: function() { + this.active = false; + this.updateElement(this.getCurrentEntry()); + }, + + updateElement: function(selectedElement) { + if (this.options.updateElement) { + this.options.updateElement(selectedElement); + return; + } + var value = ''; + if (this.options.select) { + var nodes = $(selectedElement).select('.' + this.options.select) || []; + if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); + } else + value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); + + var bounds = this.getTokenBounds(); + if (bounds[0] != -1) { + var newValue = this.element.value.substr(0, bounds[0]); + var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); + if (whitespace) + newValue += whitespace[0]; + this.element.value = newValue + value + this.element.value.substr(bounds[1]); + } else { + this.element.value = value; + } + this.oldElementValue = this.element.value; + this.element.focus(); + + if (this.options.afterUpdateElement) + this.options.afterUpdateElement(this.element, selectedElement); + }, + + updateChoices: function(choices) { + if(!this.changed && this.hasFocus) { + this.update.innerHTML = choices; + Element.cleanWhitespace(this.update); + Element.cleanWhitespace(this.update.down()); + + if(this.update.firstChild && this.update.down().childNodes) { + this.entryCount = + this.update.down().childNodes.length; + for (var i = 0; i < this.entryCount; i++) { + var entry = this.getEntry(i); + entry.autocompleteIndex = i; + this.addObservers(entry); + } + } else { + this.entryCount = 0; + } + + this.stopIndicator(); + this.index = 0; + + if(this.entryCount==1 && this.options.autoSelect) { + this.selectEntry(); + this.hide(); + } else { + this.render(); + } + } + }, + + addObservers: function(element) { + Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); + Event.observe(element, "click", this.onClick.bindAsEventListener(this)); + }, + + onObserverEvent: function() { + this.changed = false; + this.tokenBounds = null; + if(this.getToken().length>=this.options.minChars) { + this.getUpdatedChoices(); + } else { + this.active = false; + this.hide(); + } + this.oldElementValue = this.element.value; + }, + + getToken: function() { + var bounds = this.getTokenBounds(); + return this.element.value.substring(bounds[0], bounds[1]).strip(); + }, + + getTokenBounds: function() { + if (null != this.tokenBounds) return this.tokenBounds; + var value = this.element.value; + if (value.strip().empty()) return [-1, 0]; + var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue); + var offset = (diff == this.oldElementValue.length ? 1 : 0); + var prevTokenPos = -1, nextTokenPos = value.length; + var tp; + for (var index = 0, l = this.options.tokens.length; index < l; ++index) { + tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); + if (tp > prevTokenPos) prevTokenPos = tp; + tp = value.indexOf(this.options.tokens[index], diff + offset); + if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; + } + return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); + } +}); + +Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) { + var boundary = Math.min(newS.length, oldS.length); + for (var index = 0; index < boundary; ++index) + if (newS[index] != oldS[index]) + return index; + return boundary; +}; + +Ajax.Autocompleter = Class.create(Autocompleter.Base, { + initialize: function(element, update, url, options) { + this.baseInitialize(element, update, options); + this.options.asynchronous = true; + this.options.onComplete = this.onComplete.bind(this); + this.options.defaultParams = this.options.parameters || null; + this.url = url; + }, + + getUpdatedChoices: function() { + this.startIndicator(); + + var entry = encodeURIComponent(this.options.paramName) + '=' + + encodeURIComponent(this.getToken()); + + this.options.parameters = this.options.callback ? + this.options.callback(this.element, entry) : entry; + + if(this.options.defaultParams) + this.options.parameters += '&' + this.options.defaultParams; + + new Ajax.Request(this.url, this.options); + }, + + onComplete: function(request) { + this.updateChoices(request.responseText); + } +}); + +// The local array autocompleter. Used when you'd prefer to +// inject an array of autocompletion options into the page, rather +// than sending out Ajax queries, which can be quite slow sometimes. +// +// The constructor takes four parameters. The first two are, as usual, +// the id of the monitored textbox, and id of the autocompletion menu. +// The third is the array you want to autocomplete from, and the fourth +// is the options block. +// +// Extra local autocompletion options: +// - choices - How many autocompletion choices to offer +// +// - partialSearch - If false, the autocompleter will match entered +// text only at the beginning of strings in the +// autocomplete array. Defaults to true, which will +// match text at the beginning of any *word* in the +// strings in the autocomplete array. If you want to +// search anywhere in the string, additionally set +// the option fullSearch to true (default: off). +// +// - fullSsearch - Search anywhere in autocomplete array strings. +// +// - partialChars - How many characters to enter before triggering +// a partial match (unlike minChars, which defines +// how many characters are required to do any match +// at all). Defaults to 2. +// +// - ignoreCase - Whether to ignore case when autocompleting. +// Defaults to true. +// +// It's possible to pass in a custom function as the 'selector' +// option, if you prefer to write your own autocompletion logic. +// In that case, the other options above will not apply unless +// you support them. + +Autocompleter.Local = Class.create(Autocompleter.Base, { + initialize: function(element, update, array, options) { + this.baseInitialize(element, update, options); + this.options.array = array; + }, + + getUpdatedChoices: function() { + this.updateChoices(this.options.selector(this)); + }, + + setOptions: function(options) { + this.options = Object.extend({ + choices: 10, + partialSearch: true, + partialChars: 2, + ignoreCase: true, + fullSearch: false, + selector: function(instance) { + var ret = []; // Beginning matches + var partial = []; // Inside matches + var entry = instance.getToken(); + var count = 0; + + for (var i = 0; i < instance.options.array.length && + ret.length < instance.options.choices ; i++) { + + var elem = instance.options.array[i]; + var foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase()) : + elem.indexOf(entry); + + while (foundPos != -1) { + if (foundPos == 0 && elem.length != entry.length) { + ret.push("
  • " + elem.substr(0, entry.length) + "" + + elem.substr(entry.length) + "
  • "); + break; + } else if (entry.length >= instance.options.partialChars && + instance.options.partialSearch && foundPos != -1) { + if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { + partial.push("
  • " + elem.substr(0, foundPos) + "" + + elem.substr(foundPos, entry.length) + "" + elem.substr( + foundPos + entry.length) + "
  • "); + break; + } + } + + foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : + elem.indexOf(entry, foundPos + 1); + + } + } + if (partial.length) + ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)); + return "
      " + ret.join('') + "
    "; + } + }, options || { }); + } +}); + +// AJAX in-place editor and collection editor +// Full rewrite by Christophe Porteneuve (April 2007). + +// Use this if you notice weird scrolling problems on some browsers, +// the DOM might be a bit confused when this gets called so do this +// waits 1 ms (with setTimeout) until it does the activation +Field.scrollFreeActivate = function(field) { + setTimeout(function() { + Field.activate(field); + }, 1); +}; + +Ajax.InPlaceEditor = Class.create({ + initialize: function(element, url, options) { + this.url = url; + this.element = element = $(element); + this.prepareOptions(); + this._controls = { }; + arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! + Object.extend(this.options, options || { }); + if (!this.options.formId && this.element.id) { + this.options.formId = this.element.id + '-inplaceeditor'; + if ($(this.options.formId)) + this.options.formId = ''; + } + if (this.options.externalControl) + this.options.externalControl = $(this.options.externalControl); + if (!this.options.externalControl) + this.options.externalControlOnly = false; + this._originalBackground = this.element.getStyle('background-color') || 'transparent'; + this.element.title = this.options.clickToEditText; + this._boundCancelHandler = this.handleFormCancellation.bind(this); + this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); + this._boundFailureHandler = this.handleAJAXFailure.bind(this); + this._boundSubmitHandler = this.handleFormSubmission.bind(this); + this._boundWrapperHandler = this.wrapUp.bind(this); + this.registerListeners(); + }, + checkForEscapeOrReturn: function(e) { + if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; + if (Event.KEY_ESC == e.keyCode) + this.handleFormCancellation(e); + else if (Event.KEY_RETURN == e.keyCode) + this.handleFormSubmission(e); + }, + createControl: function(mode, handler, extraClasses) { + var control = this.options[mode + 'Control']; + var text = this.options[mode + 'Text']; + if ('button' == control) { + var btn = document.createElement('input'); + btn.type = 'submit'; + btn.value = text; + btn.className = 'editor_' + mode + '_button'; + if ('cancel' == mode) + btn.onclick = this._boundCancelHandler; + this._form.appendChild(btn); + this._controls[mode] = btn; + } else if ('link' == control) { + var link = document.createElement('a'); + link.href = '#'; + link.appendChild(document.createTextNode(text)); + link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; + link.className = 'editor_' + mode + '_link'; + if (extraClasses) + link.className += ' ' + extraClasses; + this._form.appendChild(link); + this._controls[mode] = link; + } + }, + createEditField: function() { + var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); + var fld; + if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { + fld = document.createElement('input'); + fld.type = 'text'; + var size = this.options.size || this.options.cols || 0; + if (0 < size) fld.size = size; + } else { + fld = document.createElement('textarea'); + fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); + fld.cols = this.options.cols || 40; + } + fld.name = this.options.paramName; + fld.value = text; // No HTML breaks conversion anymore + fld.className = 'editor_field'; + if (this.options.submitOnBlur) + fld.onblur = this._boundSubmitHandler; + this._controls.editor = fld; + if (this.options.loadTextURL) + this.loadExternalText(); + this._form.appendChild(this._controls.editor); + }, + createForm: function() { + var ipe = this; + function addText(mode, condition) { + var text = ipe.options['text' + mode + 'Controls']; + if (!text || condition === false) return; + ipe._form.appendChild(document.createTextNode(text)); + }; + this._form = $(document.createElement('form')); + this._form.id = this.options.formId; + this._form.addClassName(this.options.formClassName); + this._form.onsubmit = this._boundSubmitHandler; + this.createEditField(); + if ('textarea' == this._controls.editor.tagName.toLowerCase()) + this._form.appendChild(document.createElement('br')); + if (this.options.onFormCustomization) + this.options.onFormCustomization(this, this._form); + addText('Before', this.options.okControl || this.options.cancelControl); + this.createControl('ok', this._boundSubmitHandler); + addText('Between', this.options.okControl && this.options.cancelControl); + this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); + addText('After', this.options.okControl || this.options.cancelControl); + }, + destroy: function() { + if (this._oldInnerHTML) + this.element.innerHTML = this._oldInnerHTML; + this.leaveEditMode(); + this.unregisterListeners(); + }, + enterEditMode: function(e) { + if (this._saving || this._editing) return; + this._editing = true; + this.triggerCallback('onEnterEditMode'); + if (this.options.externalControl) + this.options.externalControl.hide(); + this.element.hide(); + this.createForm(); + this.element.parentNode.insertBefore(this._form, this.element); + if (!this.options.loadTextURL) + this.postProcessEditField(); + if (e) Event.stop(e); + }, + enterHover: function(e) { + if (this.options.hoverClassName) + this.element.addClassName(this.options.hoverClassName); + if (this._saving) return; + this.triggerCallback('onEnterHover'); + }, + getText: function() { + return this.element.innerHTML.unescapeHTML(); + }, + handleAJAXFailure: function(transport) { + this.triggerCallback('onFailure', transport); + if (this._oldInnerHTML) { + this.element.innerHTML = this._oldInnerHTML; + this._oldInnerHTML = null; + } + }, + handleFormCancellation: function(e) { + this.wrapUp(); + if (e) Event.stop(e); + }, + handleFormSubmission: function(e) { + var form = this._form; + var value = $F(this._controls.editor); + this.prepareSubmission(); + var params = this.options.callback(form, value) || ''; + if (Object.isString(params)) + params = params.toQueryParams(); + params.editorId = this.element.id; + if (this.options.htmlResponse) { + var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); + Object.extend(options, { + parameters: params, + onComplete: this._boundWrapperHandler, + onFailure: this._boundFailureHandler + }); + new Ajax.Updater({ success: this.element }, this.url, options); + } else { + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: params, + onComplete: this._boundWrapperHandler, + onFailure: this._boundFailureHandler + }); + new Ajax.Request(this.url, options); + } + if (e) Event.stop(e); + }, + leaveEditMode: function() { + this.element.removeClassName(this.options.savingClassName); + this.removeForm(); + this.leaveHover(); + this.element.style.backgroundColor = this._originalBackground; + this.element.show(); + if (this.options.externalControl) + this.options.externalControl.show(); + this._saving = false; + this._editing = false; + this._oldInnerHTML = null; + this.triggerCallback('onLeaveEditMode'); + }, + leaveHover: function(e) { + if (this.options.hoverClassName) + this.element.removeClassName(this.options.hoverClassName); + if (this._saving) return; + this.triggerCallback('onLeaveHover'); + }, + loadExternalText: function() { + this._form.addClassName(this.options.loadingClassName); + this._controls.editor.disabled = true; + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: 'editorId=' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + this._form.removeClassName(this.options.loadingClassName); + var text = transport.responseText; + if (this.options.stripLoadedTextTags) + text = text.stripTags(); + this._controls.editor.value = text; + this._controls.editor.disabled = false; + this.postProcessEditField(); + }.bind(this), + onFailure: this._boundFailureHandler + }); + new Ajax.Request(this.options.loadTextURL, options); + }, + postProcessEditField: function() { + var fpc = this.options.fieldPostCreation; + if (fpc) + $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); + }, + prepareOptions: function() { + this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); + Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); + [this._extraDefaultOptions].flatten().compact().each(function(defs) { + Object.extend(this.options, defs); + }.bind(this)); + }, + prepareSubmission: function() { + this._saving = true; + this.removeForm(); + this.leaveHover(); + this.showSaving(); + }, + registerListeners: function() { + this._listeners = { }; + var listener; + $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { + listener = this[pair.value].bind(this); + this._listeners[pair.key] = listener; + if (!this.options.externalControlOnly) + this.element.observe(pair.key, listener); + if (this.options.externalControl) + this.options.externalControl.observe(pair.key, listener); + }.bind(this)); + }, + removeForm: function() { + if (!this._form) return; + this._form.remove(); + this._form = null; + this._controls = { }; + }, + showSaving: function() { + this._oldInnerHTML = this.element.innerHTML; + this.element.innerHTML = this.options.savingText; + this.element.addClassName(this.options.savingClassName); + this.element.style.backgroundColor = this._originalBackground; + this.element.show(); + }, + triggerCallback: function(cbName, arg) { + if ('function' == typeof this.options[cbName]) { + this.options[cbName](this, arg); + } + }, + unregisterListeners: function() { + $H(this._listeners).each(function(pair) { + if (!this.options.externalControlOnly) + this.element.stopObserving(pair.key, pair.value); + if (this.options.externalControl) + this.options.externalControl.stopObserving(pair.key, pair.value); + }.bind(this)); + }, + wrapUp: function(transport) { + this.leaveEditMode(); + // Can't use triggerCallback due to backward compatibility: requires + // binding + direct element + this._boundComplete(transport, this.element); + } +}); + +Object.extend(Ajax.InPlaceEditor.prototype, { + dispose: Ajax.InPlaceEditor.prototype.destroy +}); + +Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, { + initialize: function($super, element, url, options) { + this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; + $super(element, url, options); + }, + + createEditField: function() { + var list = document.createElement('select'); + list.name = this.options.paramName; + list.size = 1; + this._controls.editor = list; + this._collection = this.options.collection || []; + if (this.options.loadCollectionURL) + this.loadCollection(); + else + this.checkForExternalText(); + this._form.appendChild(this._controls.editor); + }, + + loadCollection: function() { + this._form.addClassName(this.options.loadingClassName); + this.showLoadingText(this.options.loadingCollectionText); + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: 'editorId=' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + var js = transport.responseText.strip(); + if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check + throw('Server returned an invalid collection representation.'); + this._collection = eval(js); + this.checkForExternalText(); + }.bind(this), + onFailure: this.onFailure + }); + new Ajax.Request(this.options.loadCollectionURL, options); + }, + + showLoadingText: function(text) { + this._controls.editor.disabled = true; + var tempOption = this._controls.editor.firstChild; + if (!tempOption) { + tempOption = document.createElement('option'); + tempOption.value = ''; + this._controls.editor.appendChild(tempOption); + tempOption.selected = true; + } + tempOption.update((text || '').stripScripts().stripTags()); + }, + + checkForExternalText: function() { + this._text = this.getText(); + if (this.options.loadTextURL) + this.loadExternalText(); + else + this.buildOptionList(); + }, + + loadExternalText: function() { + this.showLoadingText(this.options.loadingText); + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: 'editorId=' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + this._text = transport.responseText.strip(); + this.buildOptionList(); + }.bind(this), + onFailure: this.onFailure + }); + new Ajax.Request(this.options.loadTextURL, options); + }, + + buildOptionList: function() { + this._form.removeClassName(this.options.loadingClassName); + this._collection = this._collection.map(function(entry) { + return 2 === entry.length ? entry : [entry, entry].flatten(); + }); + var marker = ('value' in this.options) ? this.options.value : this._text; + var textFound = this._collection.any(function(entry) { + return entry[0] == marker; + }.bind(this)); + this._controls.editor.update(''); + var option; + this._collection.each(function(entry, index) { + option = document.createElement('option'); + option.value = entry[0]; + option.selected = textFound ? entry[0] == marker : 0 == index; + option.appendChild(document.createTextNode(entry[1])); + this._controls.editor.appendChild(option); + }.bind(this)); + this._controls.editor.disabled = false; + Field.scrollFreeActivate(this._controls.editor); + } +}); + +//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** +//**** This only exists for a while, in order to let **** +//**** users adapt to the new API. Read up on the new **** +//**** API and convert your code to it ASAP! **** + +Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { + if (!options) return; + function fallback(name, expr) { + if (name in options || expr === undefined) return; + options[name] = expr; + }; + fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : + options.cancelLink == options.cancelButton == false ? false : undefined))); + fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : + options.okLink == options.okButton == false ? false : undefined))); + fallback('highlightColor', options.highlightcolor); + fallback('highlightEndColor', options.highlightendcolor); +}; + +Object.extend(Ajax.InPlaceEditor, { + DefaultOptions: { + ajaxOptions: { }, + autoRows: 3, // Use when multi-line w/ rows == 1 + cancelControl: 'link', // 'link'|'button'|false + cancelText: 'cancel', + clickToEditText: 'Click to edit', + externalControl: null, // id|elt + externalControlOnly: false, + fieldPostCreation: 'activate', // 'activate'|'focus'|false + formClassName: 'inplaceeditor-form', + formId: null, // id|elt + highlightColor: '#ffff99', + highlightEndColor: '#ffffff', + hoverClassName: '', + htmlResponse: true, + loadingClassName: 'inplaceeditor-loading', + loadingText: 'Loading...', + okControl: 'button', // 'link'|'button'|false + okText: 'ok', + paramName: 'value', + rows: 1, // If 1 and multi-line, uses autoRows + savingClassName: 'inplaceeditor-saving', + savingText: 'Saving...', + size: 0, + stripLoadedTextTags: false, + submitOnBlur: false, + textAfterControls: '', + textBeforeControls: '', + textBetweenControls: '' + }, + DefaultCallbacks: { + callback: function(form) { + return Form.serialize(form); + }, + onComplete: function(transport, element) { + // For backward compatibility, this one is bound to the IPE, and passes + // the element directly. It was too often customized, so we don't break it. + new Effect.Highlight(element, { + startcolor: this.options.highlightColor, keepBackgroundImage: true }); + }, + onEnterEditMode: null, + onEnterHover: function(ipe) { + ipe.element.style.backgroundColor = ipe.options.highlightColor; + if (ipe._effect) + ipe._effect.cancel(); + }, + onFailure: function(transport, ipe) { + alert('Error communication with the server: ' + transport.responseText.stripTags()); + }, + onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. + onLeaveEditMode: null, + onLeaveHover: function(ipe) { + ipe._effect = new Effect.Highlight(ipe.element, { + startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, + restorecolor: ipe._originalBackground, keepBackgroundImage: true + }); + } + }, + Listeners: { + click: 'enterEditMode', + keydown: 'checkForEscapeOrReturn', + mouseover: 'enterHover', + mouseout: 'leaveHover' + } +}); + +Ajax.InPlaceCollectionEditor.DefaultOptions = { + loadingCollectionText: 'Loading options...' +}; + +// Delayed observer, like Form.Element.Observer, +// but waits for delay after last key input +// Ideal for live-search fields + +Form.Element.DelayedObserver = Class.create({ + initialize: function(element, delay, callback) { + this.delay = delay || 0.5; + this.element = $(element); + this.callback = callback; + this.timer = null; + this.lastValue = $F(this.element); + Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); + }, + delayedListener: function(event) { + if(this.lastValue == $F(this.element)) return; + if(this.timer) clearTimeout(this.timer); + this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); + this.lastValue = $F(this.element); + }, + onTimerEvent: function() { + this.timer = null; + this.callback(this.element, $F(this.element)); + } +}); \ No newline at end of file diff --git a/src/wp-includes/js/scriptaculous/dragdrop.js b/src/wp-includes/js/scriptaculous/dragdrop.js new file mode 100644 index 00000000..15c6dbca --- /dev/null +++ b/src/wp-includes/js/scriptaculous/dragdrop.js @@ -0,0 +1,974 @@ +// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +if(Object.isUndefined(Effect)) + throw("dragdrop.js requires including script.aculo.us' effects.js library"); + +var Droppables = { + drops: [], + + remove: function(element) { + this.drops = this.drops.reject(function(d) { return d.element==$(element) }); + }, + + add: function(element) { + element = $(element); + var options = Object.extend({ + greedy: true, + hoverclass: null, + tree: false + }, arguments[1] || { }); + + // cache containers + if(options.containment) { + options._containers = []; + var containment = options.containment; + if(Object.isArray(containment)) { + containment.each( function(c) { options._containers.push($(c)) }); + } else { + options._containers.push($(containment)); + } + } + + if(options.accept) options.accept = [options.accept].flatten(); + + Element.makePositioned(element); // fix IE + options.element = element; + + this.drops.push(options); + }, + + findDeepestChild: function(drops) { + deepest = drops[0]; + + for (i = 1; i < drops.length; ++i) + if (Element.isParent(drops[i].element, deepest.element)) + deepest = drops[i]; + + return deepest; + }, + + isContained: function(element, drop) { + var containmentNode; + if(drop.tree) { + containmentNode = element.treeNode; + } else { + containmentNode = element.parentNode; + } + return drop._containers.detect(function(c) { return containmentNode == c }); + }, + + isAffected: function(point, element, drop) { + return ( + (drop.element!=element) && + ((!drop._containers) || + this.isContained(element, drop)) && + ((!drop.accept) || + (Element.classNames(element).detect( + function(v) { return drop.accept.include(v) } ) )) && + Position.within(drop.element, point[0], point[1]) ); + }, + + deactivate: function(drop) { + if(drop.hoverclass) + Element.removeClassName(drop.element, drop.hoverclass); + this.last_active = null; + }, + + activate: function(drop) { + if(drop.hoverclass) + Element.addClassName(drop.element, drop.hoverclass); + this.last_active = drop; + }, + + show: function(point, element) { + if(!this.drops.length) return; + var drop, affected = []; + + this.drops.each( function(drop) { + if(Droppables.isAffected(point, element, drop)) + affected.push(drop); + }); + + if(affected.length>0) + drop = Droppables.findDeepestChild(affected); + + if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); + if (drop) { + Position.within(drop.element, point[0], point[1]); + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); + + if (drop != this.last_active) Droppables.activate(drop); + } + }, + + fire: function(event, element) { + if(!this.last_active) return; + Position.prepare(); + + if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) + if (this.last_active.onDrop) { + this.last_active.onDrop(element, this.last_active.element, event); + return true; + } + }, + + reset: function() { + if(this.last_active) + this.deactivate(this.last_active); + } +}; + +var Draggables = { + drags: [], + observers: [], + + register: function(draggable) { + if(this.drags.length == 0) { + this.eventMouseUp = this.endDrag.bindAsEventListener(this); + this.eventMouseMove = this.updateDrag.bindAsEventListener(this); + this.eventKeypress = this.keyPress.bindAsEventListener(this); + + Event.observe(document, "mouseup", this.eventMouseUp); + Event.observe(document, "mousemove", this.eventMouseMove); + Event.observe(document, "keypress", this.eventKeypress); + } + this.drags.push(draggable); + }, + + unregister: function(draggable) { + this.drags = this.drags.reject(function(d) { return d==draggable }); + if(this.drags.length == 0) { + Event.stopObserving(document, "mouseup", this.eventMouseUp); + Event.stopObserving(document, "mousemove", this.eventMouseMove); + Event.stopObserving(document, "keypress", this.eventKeypress); + } + }, + + activate: function(draggable) { + if(draggable.options.delay) { + this._timeout = setTimeout(function() { + Draggables._timeout = null; + window.focus(); + Draggables.activeDraggable = draggable; + }.bind(this), draggable.options.delay); + } else { + window.focus(); // allows keypress events if window isn't currently focused, fails for Safari + this.activeDraggable = draggable; + } + }, + + deactivate: function() { + this.activeDraggable = null; + }, + + updateDrag: function(event) { + if(!this.activeDraggable) return; + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + // Mozilla-based browsers fire successive mousemove events with + // the same coordinates, prevent needless redrawing (moz bug?) + if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; + this._lastPointer = pointer; + + this.activeDraggable.updateDrag(event, pointer); + }, + + endDrag: function(event) { + if(this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + } + if(!this.activeDraggable) return; + this._lastPointer = null; + this.activeDraggable.endDrag(event); + this.activeDraggable = null; + }, + + keyPress: function(event) { + if(this.activeDraggable) + this.activeDraggable.keyPress(event); + }, + + addObserver: function(observer) { + this.observers.push(observer); + this._cacheObserverCallbacks(); + }, + + removeObserver: function(element) { // element instead of observer fixes mem leaks + this.observers = this.observers.reject( function(o) { return o.element==element }); + this._cacheObserverCallbacks(); + }, + + notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' + if(this[eventName+'Count'] > 0) + this.observers.each( function(o) { + if(o[eventName]) o[eventName](eventName, draggable, event); + }); + if(draggable.options[eventName]) draggable.options[eventName](draggable, event); + }, + + _cacheObserverCallbacks: function() { + ['onStart','onEnd','onDrag'].each( function(eventName) { + Draggables[eventName+'Count'] = Draggables.observers.select( + function(o) { return o[eventName]; } + ).length; + }); + } +}; + +/*--------------------------------------------------------------------------*/ + +var Draggable = Class.create({ + initialize: function(element) { + var defaults = { + handle: false, + reverteffect: function(element, top_offset, left_offset) { + var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; + new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, + queue: {scope:'_draggable', position:'end'} + }); + }, + endeffect: function(element) { + var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; + new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, + queue: {scope:'_draggable', position:'end'}, + afterFinish: function(){ + Draggable._dragging[element] = false + } + }); + }, + zindex: 1000, + revert: false, + quiet: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } + delay: 0 + }; + + if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) + Object.extend(defaults, { + starteffect: function(element) { + element._opacity = Element.getOpacity(element); + Draggable._dragging[element] = true; + new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); + } + }); + + var options = Object.extend(defaults, arguments[1] || { }); + + this.element = $(element); + + if(options.handle && Object.isString(options.handle)) + this.handle = this.element.down('.'+options.handle, 0); + + if(!this.handle) this.handle = $(options.handle); + if(!this.handle) this.handle = this.element; + + if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { + options.scroll = $(options.scroll); + this._isScrollChild = Element.childOf(this.element, options.scroll); + } + + Element.makePositioned(this.element); // fix IE + + this.options = options; + this.dragging = false; + + this.eventMouseDown = this.initDrag.bindAsEventListener(this); + Event.observe(this.handle, "mousedown", this.eventMouseDown); + + Draggables.register(this); + }, + + destroy: function() { + Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); + Draggables.unregister(this); + }, + + currentDelta: function() { + return([ + parseInt(Element.getStyle(this.element,'left') || '0'), + parseInt(Element.getStyle(this.element,'top') || '0')]); + }, + + initDrag: function(event) { + if(!Object.isUndefined(Draggable._dragging[this.element]) && + Draggable._dragging[this.element]) return; + if(Event.isLeftClick(event)) { + // abort on form elements, fixes a Firefox issue + var src = Event.element(event); + if((tag_name = src.tagName.toUpperCase()) && ( + tag_name=='INPUT' || + tag_name=='SELECT' || + tag_name=='OPTION' || + tag_name=='BUTTON' || + tag_name=='TEXTAREA')) return; + + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var pos = this.element.cumulativeOffset(); + this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); + + Draggables.activate(this); + Event.stop(event); + } + }, + + startDrag: function(event) { + this.dragging = true; + if(!this.delta) + this.delta = this.currentDelta(); + + if(this.options.zindex) { + this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); + this.element.style.zIndex = this.options.zindex; + } + + if(this.options.ghosting) { + this._clone = this.element.cloneNode(true); + this._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); + if (!this._originallyAbsolute) + Position.absolutize(this.element); + this.element.parentNode.insertBefore(this._clone, this.element); + } + + if(this.options.scroll) { + if (this.options.scroll == window) { + var where = this._getWindowScroll(this.options.scroll); + this.originalScrollLeft = where.left; + this.originalScrollTop = where.top; + } else { + this.originalScrollLeft = this.options.scroll.scrollLeft; + this.originalScrollTop = this.options.scroll.scrollTop; + } + } + + Draggables.notify('onStart', this, event); + + if(this.options.starteffect) this.options.starteffect(this.element); + }, + + updateDrag: function(event, pointer) { + if(!this.dragging) this.startDrag(event); + + if(!this.options.quiet){ + Position.prepare(); + Droppables.show(pointer, this.element); + } + + Draggables.notify('onDrag', this, event); + + this.draw(pointer); + if(this.options.change) this.options.change(this); + + if(this.options.scroll) { + this.stopScrolling(); + + var p; + if (this.options.scroll == window) { + with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } + } else { + p = Position.page(this.options.scroll); + p[0] += this.options.scroll.scrollLeft + Position.deltaX; + p[1] += this.options.scroll.scrollTop + Position.deltaY; + p.push(p[0]+this.options.scroll.offsetWidth); + p.push(p[1]+this.options.scroll.offsetHeight); + } + var speed = [0,0]; + if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); + if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); + if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); + if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); + this.startScrolling(speed); + } + + // fix AppleWebKit rendering + if(Prototype.Browser.WebKit) window.scrollBy(0,0); + + Event.stop(event); + }, + + finishDrag: function(event, success) { + this.dragging = false; + + if(this.options.quiet){ + Position.prepare(); + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + Droppables.show(pointer, this.element); + } + + if(this.options.ghosting) { + if (!this._originallyAbsolute) + Position.relativize(this.element); + delete this._originallyAbsolute; + Element.remove(this._clone); + this._clone = null; + } + + var dropped = false; + if(success) { + dropped = Droppables.fire(event, this.element); + if (!dropped) dropped = false; + } + if(dropped && this.options.onDropped) this.options.onDropped(this.element); + Draggables.notify('onEnd', this, event); + + var revert = this.options.revert; + if(revert && Object.isFunction(revert)) revert = revert(this.element); + + var d = this.currentDelta(); + if(revert && this.options.reverteffect) { + if (dropped == 0 || revert != 'failure') + this.options.reverteffect(this.element, + d[1]-this.delta[1], d[0]-this.delta[0]); + } else { + this.delta = d; + } + + if(this.options.zindex) + this.element.style.zIndex = this.originalZ; + + if(this.options.endeffect) + this.options.endeffect(this.element); + + Draggables.deactivate(this); + Droppables.reset(); + }, + + keyPress: function(event) { + if(event.keyCode!=Event.KEY_ESC) return; + this.finishDrag(event, false); + Event.stop(event); + }, + + endDrag: function(event) { + if(!this.dragging) return; + this.stopScrolling(); + this.finishDrag(event, true); + Event.stop(event); + }, + + draw: function(point) { + var pos = this.element.cumulativeOffset(); + if(this.options.ghosting) { + var r = Position.realOffset(this.element); + pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; + } + + var d = this.currentDelta(); + pos[0] -= d[0]; pos[1] -= d[1]; + + if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { + pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; + pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; + } + + var p = [0,1].map(function(i){ + return (point[i]-pos[i]-this.offset[i]) + }.bind(this)); + + if(this.options.snap) { + if(Object.isFunction(this.options.snap)) { + p = this.options.snap(p[0],p[1],this); + } else { + if(Object.isArray(this.options.snap)) { + p = p.map( function(v, i) { + return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)); + } else { + p = p.map( function(v) { + return (v/this.options.snap).round()*this.options.snap }.bind(this)); + } + }} + + var style = this.element.style; + if((!this.options.constraint) || (this.options.constraint=='horizontal')) + style.left = p[0] + "px"; + if((!this.options.constraint) || (this.options.constraint=='vertical')) + style.top = p[1] + "px"; + + if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering + }, + + stopScrolling: function() { + if(this.scrollInterval) { + clearInterval(this.scrollInterval); + this.scrollInterval = null; + Draggables._lastScrollPointer = null; + } + }, + + startScrolling: function(speed) { + if(!(speed[0] || speed[1])) return; + this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; + this.lastScrolled = new Date(); + this.scrollInterval = setInterval(this.scroll.bind(this), 10); + }, + + scroll: function() { + var current = new Date(); + var delta = current - this.lastScrolled; + this.lastScrolled = current; + if(this.options.scroll == window) { + with (this._getWindowScroll(this.options.scroll)) { + if (this.scrollSpeed[0] || this.scrollSpeed[1]) { + var d = delta / 1000; + this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); + } + } + } else { + this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; + this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; + } + + Position.prepare(); + Droppables.show(Draggables._lastPointer, this.element); + Draggables.notify('onDrag', this); + if (this._isScrollChild) { + Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); + Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; + Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; + if (Draggables._lastScrollPointer[0] < 0) + Draggables._lastScrollPointer[0] = 0; + if (Draggables._lastScrollPointer[1] < 0) + Draggables._lastScrollPointer[1] = 0; + this.draw(Draggables._lastScrollPointer); + } + + if(this.options.change) this.options.change(this); + }, + + _getWindowScroll: function(w) { + var T, L, W, H; + with (w.document) { + if (w.document.documentElement && documentElement.scrollTop) { + T = documentElement.scrollTop; + L = documentElement.scrollLeft; + } else if (w.document.body) { + T = body.scrollTop; + L = body.scrollLeft; + } + if (w.innerWidth) { + W = w.innerWidth; + H = w.innerHeight; + } else if (w.document.documentElement && documentElement.clientWidth) { + W = documentElement.clientWidth; + H = documentElement.clientHeight; + } else { + W = body.offsetWidth; + H = body.offsetHeight; + } + } + return { top: T, left: L, width: W, height: H }; + } +}); + +Draggable._dragging = { }; + +/*--------------------------------------------------------------------------*/ + +var SortableObserver = Class.create({ + initialize: function(element, observer) { + this.element = $(element); + this.observer = observer; + this.lastValue = Sortable.serialize(this.element); + }, + + onStart: function() { + this.lastValue = Sortable.serialize(this.element); + }, + + onEnd: function() { + Sortable.unmark(); + if(this.lastValue != Sortable.serialize(this.element)) + this.observer(this.element) + } +}); + +var Sortable = { + SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, + + sortables: { }, + + _findRootElement: function(element) { + while (element.tagName.toUpperCase() != "BODY") { + if(element.id && Sortable.sortables[element.id]) return element; + element = element.parentNode; + } + }, + + options: function(element) { + element = Sortable._findRootElement($(element)); + if(!element) return; + return Sortable.sortables[element.id]; + }, + + destroy: function(element){ + element = $(element); + var s = Sortable.sortables[element.id]; + + if(s) { + Draggables.removeObserver(s.element); + s.droppables.each(function(d){ Droppables.remove(d) }); + s.draggables.invoke('destroy'); + + delete Sortable.sortables[s.element.id]; + } + }, + + create: function(element) { + element = $(element); + var options = Object.extend({ + element: element, + tag: 'li', // assumes li children, override with tag: 'tagname' + dropOnEmpty: false, + tree: false, + treeTag: 'ul', + overlap: 'vertical', // one of 'vertical', 'horizontal' + constraint: 'vertical', // one of 'vertical', 'horizontal', false + containment: element, // also takes array of elements (or id's); or false + handle: false, // or a CSS class + only: false, + delay: 0, + hoverclass: null, + ghosting: false, + quiet: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + format: this.SERIALIZE_RULE, + + // these take arrays of elements or ids and can be + // used for better initialization performance + elements: false, + handles: false, + + onChange: Prototype.emptyFunction, + onUpdate: Prototype.emptyFunction + }, arguments[1] || { }); + + // clear any old sortable with same element + this.destroy(element); + + // build options for the draggables + var options_for_draggable = { + revert: true, + quiet: options.quiet, + scroll: options.scroll, + scrollSpeed: options.scrollSpeed, + scrollSensitivity: options.scrollSensitivity, + delay: options.delay, + ghosting: options.ghosting, + constraint: options.constraint, + handle: options.handle }; + + if(options.starteffect) + options_for_draggable.starteffect = options.starteffect; + + if(options.reverteffect) + options_for_draggable.reverteffect = options.reverteffect; + else + if(options.ghosting) options_for_draggable.reverteffect = function(element) { + element.style.top = 0; + element.style.left = 0; + }; + + if(options.endeffect) + options_for_draggable.endeffect = options.endeffect; + + if(options.zindex) + options_for_draggable.zindex = options.zindex; + + // build options for the droppables + var options_for_droppable = { + overlap: options.overlap, + containment: options.containment, + tree: options.tree, + hoverclass: options.hoverclass, + onHover: Sortable.onHover + }; + + var options_for_tree = { + onHover: Sortable.onEmptyHover, + overlap: options.overlap, + containment: options.containment, + hoverclass: options.hoverclass + }; + + // fix for gecko engine + Element.cleanWhitespace(element); + + options.draggables = []; + options.droppables = []; + + // drop on empty handling + if(options.dropOnEmpty || options.tree) { + Droppables.add(element, options_for_tree); + options.droppables.push(element); + } + + (options.elements || this.findElements(element, options) || []).each( function(e,i) { + var handle = options.handles ? $(options.handles[i]) : + (options.handle ? $(e).select('.' + options.handle)[0] : e); + options.draggables.push( + new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); + Droppables.add(e, options_for_droppable); + if(options.tree) e.treeNode = element; + options.droppables.push(e); + }); + + if(options.tree) { + (Sortable.findTreeElements(element, options) || []).each( function(e) { + Droppables.add(e, options_for_tree); + e.treeNode = element; + options.droppables.push(e); + }); + } + + // keep reference + this.sortables[element.identify()] = options; + + // for onupdate + Draggables.addObserver(new SortableObserver(element, options.onUpdate)); + + }, + + // return all suitable-for-sortable elements in a guaranteed order + findElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.tag); + }, + + findTreeElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.treeTag); + }, + + onHover: function(element, dropon, overlap) { + if(Element.isParent(dropon, element)) return; + + if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { + return; + } else if(overlap>0.5) { + Sortable.mark(dropon, 'before'); + if(dropon.previousSibling != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, dropon); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } else { + Sortable.mark(dropon, 'after'); + var nextElement = dropon.nextSibling || null; + if(nextElement != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, nextElement); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } + }, + + onEmptyHover: function(element, dropon, overlap) { + var oldParentNode = element.parentNode; + var droponOptions = Sortable.options(dropon); + + if(!Element.isParent(dropon, element)) { + var index; + + var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); + var child = null; + + if(children) { + var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); + + for (index = 0; index < children.length; index += 1) { + if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { + offset -= Element.offsetSize (children[index], droponOptions.overlap); + } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { + child = index + 1 < children.length ? children[index + 1] : null; + break; + } else { + child = children[index]; + break; + } + } + } + + dropon.insertBefore(element, child); + + Sortable.options(oldParentNode).onChange(element); + droponOptions.onChange(element); + } + }, + + unmark: function() { + if(Sortable._marker) Sortable._marker.hide(); + }, + + mark: function(dropon, position) { + // mark on ghosting only + var sortable = Sortable.options(dropon.parentNode); + if(sortable && !sortable.ghosting) return; + + if(!Sortable._marker) { + Sortable._marker = + ($('dropmarker') || Element.extend(document.createElement('DIV'))). + hide().addClassName('dropmarker').setStyle({position:'absolute'}); + document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); + } + var offsets = dropon.cumulativeOffset(); + Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); + + if(position=='after') + if(sortable.overlap == 'horizontal') + Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); + else + Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); + + Sortable._marker.show(); + }, + + _tree: function(element, options, parent) { + var children = Sortable.findElements(element, options) || []; + + for (var i = 0; i < children.length; ++i) { + var match = children[i].id.match(options.format); + + if (!match) continue; + + var child = { + id: encodeURIComponent(match ? match[1] : null), + element: element, + parent: parent, + children: [], + position: parent.children.length, + container: $(children[i]).down(options.treeTag) + }; + + /* Get the element containing the children and recurse over it */ + if (child.container) + this._tree(child.container, options, child); + + parent.children.push (child); + } + + return parent; + }, + + tree: function(element) { + element = $(element); + var sortableOptions = this.options(element); + var options = Object.extend({ + tag: sortableOptions.tag, + treeTag: sortableOptions.treeTag, + only: sortableOptions.only, + name: element.id, + format: sortableOptions.format + }, arguments[1] || { }); + + var root = { + id: null, + parent: null, + children: [], + container: element, + position: 0 + }; + + return Sortable._tree(element, options, root); + }, + + /* Construct a [i] index for a particular node */ + _constructIndex: function(node) { + var index = ''; + do { + if (node.id) index = '[' + node.position + ']' + index; + } while ((node = node.parent) != null); + return index; + }, + + sequence: function(element) { + element = $(element); + var options = Object.extend(this.options(element), arguments[1] || { }); + + return $(this.findElements(element, options) || []).map( function(item) { + return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; + }); + }, + + setSequence: function(element, new_sequence) { + element = $(element); + var options = Object.extend(this.options(element), arguments[2] || { }); + + var nodeMap = { }; + this.findElements(element, options).each( function(n) { + if (n.id.match(options.format)) + nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; + n.parentNode.removeChild(n); + }); + + new_sequence.each(function(ident) { + var n = nodeMap[ident]; + if (n) { + n[1].appendChild(n[0]); + delete nodeMap[ident]; + } + }); + }, + + serialize: function(element) { + element = $(element); + var options = Object.extend(Sortable.options(element), arguments[1] || { }); + var name = encodeURIComponent( + (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); + + if (options.tree) { + return Sortable.tree(element, arguments[1]).children.map( function (item) { + return [name + Sortable._constructIndex(item) + "[id]=" + + encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); + }).flatten().join('&'); + } else { + return Sortable.sequence(element, arguments[1]).map( function(item) { + return name + "[]=" + encodeURIComponent(item); + }).join('&'); + } + } +}; + +// Returns true if child is contained within element +Element.isParent = function(child, element) { + if (!child.parentNode || child == element) return false; + if (child.parentNode == element) return true; + return Element.isParent(child.parentNode, element); +}; + +Element.findChildren = function(element, only, recursive, tagName) { + if(!element.hasChildNodes()) return null; + tagName = tagName.toUpperCase(); + if(only) only = [only].flatten(); + var elements = []; + $A(element.childNodes).each( function(e) { + if(e.tagName && e.tagName.toUpperCase()==tagName && + (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) + elements.push(e); + if(recursive) { + var grandchildren = Element.findChildren(e, only, recursive, tagName); + if(grandchildren) elements.push(grandchildren); + } + }); + + return (elements.length>0 ? elements.flatten() : []); +}; + +Element.offsetSize = function (element, type) { + return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; +}; \ No newline at end of file diff --git a/src/wp-includes/js/scriptaculous/effects.js b/src/wp-includes/js/scriptaculous/effects.js new file mode 100644 index 00000000..066ee590 --- /dev/null +++ b/src/wp-includes/js/scriptaculous/effects.js @@ -0,0 +1,1123 @@ +// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +// converts rgb() and #xxx to #xxxxxx format, +// returns self (or first argument) if not convertable +String.prototype.parseColor = function() { + var color = '#'; + if (this.slice(0,4) == 'rgb(') { + var cols = this.slice(4,this.length-1).split(','); + var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); + } else { + if (this.slice(0,1) == '#') { + if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); + if (this.length==7) color = this.toLowerCase(); + } + } + return (color.length==7 ? color : (arguments[0] || this)); +}; + +/*--------------------------------------------------------------------------*/ + +Element.collectTextNodes = function(element) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); + }).flatten().join(''); +}; + +Element.collectTextNodesIgnoreClass = function(element, className) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? + Element.collectTextNodesIgnoreClass(node, className) : '')); + }).flatten().join(''); +}; + +Element.setContentZoom = function(element, percent) { + element = $(element); + element.setStyle({fontSize: (percent/100) + 'em'}); + if (Prototype.Browser.WebKit) window.scrollBy(0,0); + return element; +}; + +Element.getInlineOpacity = function(element){ + return $(element).style.opacity || ''; +}; + +Element.forceRerendering = function(element) { + try { + element = $(element); + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch(e) { } +}; + +/*--------------------------------------------------------------------------*/ + +var Effect = { + _elementDoesNotExistError: { + name: 'ElementDoesNotExistError', + message: 'The specified DOM element does not exist, but is required for this effect to operate' + }, + Transitions: { + linear: Prototype.K, + sinoidal: function(pos) { + return (-Math.cos(pos*Math.PI)/2) + .5; + }, + reverse: function(pos) { + return 1-pos; + }, + flicker: function(pos) { + var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4; + return pos > 1 ? 1 : pos; + }, + wobble: function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5; + }, + pulse: function(pos, pulses) { + return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5; + }, + spring: function(pos) { + return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); + }, + none: function(pos) { + return 0; + }, + full: function(pos) { + return 1; + } + }, + DefaultOptions: { + duration: 1.0, // seconds + fps: 100, // 100= assume 66fps max. + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' + }, + tagifyText: function(element) { + var tagifyStyle = 'position:relative'; + if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; + + element = $(element); + $A(element.childNodes).each( function(child) { + if (child.nodeType==3) { + child.nodeValue.toArray().each( function(character) { + element.insertBefore( + new Element('span', {style: tagifyStyle}).update( + character == ' ' ? String.fromCharCode(160) : character), + child); + }); + Element.remove(child); + } + }); + }, + multiple: function(element, effect) { + var elements; + if (((typeof element == 'object') || + Object.isFunction(element)) && + (element.length)) + elements = element; + else + elements = $(element).childNodes; + + var options = Object.extend({ + speed: 0.1, + delay: 0.0 + }, arguments[2] || { }); + var masterDelay = options.delay; + + $A(elements).each( function(element, index) { + new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); + }); + }, + PAIRS: { + 'slide': ['SlideDown','SlideUp'], + 'blind': ['BlindDown','BlindUp'], + 'appear': ['Appear','Fade'] + }, + toggle: function(element, effect, options) { + element = $(element); + effect = (effect || 'appear').toLowerCase(); + + return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({ + queue: { position:'end', scope:(element.id || 'global'), limit: 1 } + }, options || {})); + } +}; + +Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; + +/* ------------- core effects ------------- */ + +Effect.ScopedQueue = Class.create(Enumerable, { + initialize: function() { + this.effects = []; + this.interval = null; + }, + _each: function(iterator) { + this.effects._each(iterator); + }, + add: function(effect) { + var timestamp = new Date().getTime(); + + var position = Object.isString(effect.options.queue) ? + effect.options.queue : effect.options.queue.position; + + switch(position) { + case 'front': + // move unstarted effects after this effect + this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { + e.startOn += effect.finishOn; + e.finishOn += effect.finishOn; + }); + break; + case 'with-last': + timestamp = this.effects.pluck('startOn').max() || timestamp; + break; + case 'end': + // start effect after last queued effect has finished + timestamp = this.effects.pluck('finishOn').max() || timestamp; + break; + } + + effect.startOn += timestamp; + effect.finishOn += timestamp; + + if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) + this.effects.push(effect); + + if (!this.interval) + this.interval = setInterval(this.loop.bind(this), 15); + }, + remove: function(effect) { + this.effects = this.effects.reject(function(e) { return e==effect }); + if (this.effects.length == 0) { + clearInterval(this.interval); + this.interval = null; + } + }, + loop: function() { + var timePos = new Date().getTime(); + for(var i=0, len=this.effects.length;i= this.startOn) { + if (timePos >= this.finishOn) { + this.render(1.0); + this.cancel(); + this.event('beforeFinish'); + if (this.finish) this.finish(); + this.event('afterFinish'); + return; + } + var pos = (timePos - this.startOn) / this.totalTime, + frame = (pos * this.totalFrames).round(); + if (frame > this.currentFrame) { + this.render(pos); + this.currentFrame = frame; + } + } + }, + cancel: function() { + if (!this.options.sync) + Effect.Queues.get(Object.isString(this.options.queue) ? + 'global' : this.options.queue.scope).remove(this); + this.state = 'finished'; + }, + event: function(eventName) { + if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); + if (this.options[eventName]) this.options[eventName](this); + }, + inspect: function() { + var data = $H(); + for(property in this) + if (!Object.isFunction(this[property])) data.set(property, this[property]); + return '#'; + } +}); + +Effect.Parallel = Class.create(Effect.Base, { + initialize: function(effects) { + this.effects = effects || []; + this.start(arguments[1]); + }, + update: function(position) { + this.effects.invoke('render', position); + }, + finish: function(position) { + this.effects.each( function(effect) { + effect.render(1.0); + effect.cancel(); + effect.event('beforeFinish'); + if (effect.finish) effect.finish(position); + effect.event('afterFinish'); + }); + } +}); + +Effect.Tween = Class.create(Effect.Base, { + initialize: function(object, from, to) { + object = Object.isString(object) ? $(object) : object; + var args = $A(arguments), method = args.last(), + options = args.length == 5 ? args[3] : null; + this.method = Object.isFunction(method) ? method.bind(object) : + Object.isFunction(object[method]) ? object[method].bind(object) : + function(value) { object[method] = value }; + this.start(Object.extend({ from: from, to: to }, options || { })); + }, + update: function(position) { + this.method(position); + } +}); + +Effect.Event = Class.create(Effect.Base, { + initialize: function() { + this.start(Object.extend({ duration: 0 }, arguments[0] || { })); + }, + update: Prototype.emptyFunction +}); + +Effect.Opacity = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + // make this work on IE on elements without 'layout' + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) + this.element.setStyle({zoom: 1}); + var options = Object.extend({ + from: this.element.getOpacity() || 0.0, + to: 1.0 + }, arguments[1] || { }); + this.start(options); + }, + update: function(position) { + this.element.setOpacity(position); + } +}); + +Effect.Move = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ + x: 0, + y: 0, + mode: 'relative' + }, arguments[1] || { }); + this.start(options); + }, + setup: function() { + this.element.makePositioned(); + this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); + this.originalTop = parseFloat(this.element.getStyle('top') || '0'); + if (this.options.mode == 'absolute') { + this.options.x = this.options.x - this.originalLeft; + this.options.y = this.options.y - this.originalTop; + } + }, + update: function(position) { + this.element.setStyle({ + left: (this.options.x * position + this.originalLeft).round() + 'px', + top: (this.options.y * position + this.originalTop).round() + 'px' + }); + } +}); + +// for backwards compatibility +Effect.MoveBy = function(element, toTop, toLeft) { + return new Effect.Move(element, + Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); +}; + +Effect.Scale = Class.create(Effect.Base, { + initialize: function(element, percent) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ + scaleX: true, + scaleY: true, + scaleContent: true, + scaleFromCenter: false, + scaleMode: 'box', // 'box' or 'contents' or { } with provided values + scaleFrom: 100.0, + scaleTo: percent + }, arguments[2] || { }); + this.start(options); + }, + setup: function() { + this.restoreAfterFinish = this.options.restoreAfterFinish || false; + this.elementPositioning = this.element.getStyle('position'); + + this.originalStyle = { }; + ['top','left','width','height','fontSize'].each( function(k) { + this.originalStyle[k] = this.element.style[k]; + }.bind(this)); + + this.originalTop = this.element.offsetTop; + this.originalLeft = this.element.offsetLeft; + + var fontSize = this.element.getStyle('font-size') || '100%'; + ['em','px','%','pt'].each( function(fontSizeType) { + if (fontSize.indexOf(fontSizeType)>0) { + this.fontSize = parseFloat(fontSize); + this.fontSizeType = fontSizeType; + } + }.bind(this)); + + this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; + + this.dims = null; + if (this.options.scaleMode=='box') + this.dims = [this.element.offsetHeight, this.element.offsetWidth]; + if (/^content/.test(this.options.scaleMode)) + this.dims = [this.element.scrollHeight, this.element.scrollWidth]; + if (!this.dims) + this.dims = [this.options.scaleMode.originalHeight, + this.options.scaleMode.originalWidth]; + }, + update: function(position) { + var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); + if (this.options.scaleContent && this.fontSize) + this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); + this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); + }, + finish: function(position) { + if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); + }, + setDimensions: function(height, width) { + var d = { }; + if (this.options.scaleX) d.width = width.round() + 'px'; + if (this.options.scaleY) d.height = height.round() + 'px'; + if (this.options.scaleFromCenter) { + var topd = (height - this.dims[0])/2; + var leftd = (width - this.dims[1])/2; + if (this.elementPositioning == 'absolute') { + if (this.options.scaleY) d.top = this.originalTop-topd + 'px'; + if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; + } else { + if (this.options.scaleY) d.top = -topd + 'px'; + if (this.options.scaleX) d.left = -leftd + 'px'; + } + } + this.element.setStyle(d); + } +}); + +Effect.Highlight = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { }); + this.start(options); + }, + setup: function() { + // Prevent executing on elements not in the layout flow + if (this.element.getStyle('display')=='none') { this.cancel(); return; } + // Disable background image during the effect + this.oldStyle = { }; + if (!this.options.keepBackgroundImage) { + this.oldStyle.backgroundImage = this.element.getStyle('background-image'); + this.element.setStyle({backgroundImage: 'none'}); + } + if (!this.options.endcolor) + this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); + if (!this.options.restorecolor) + this.options.restorecolor = this.element.getStyle('background-color'); + // init color calculations + this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); + this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); + }, + update: function(position) { + this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ + return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); + }, + finish: function() { + this.element.setStyle(Object.extend(this.oldStyle, { + backgroundColor: this.options.restorecolor + })); + } +}); + +Effect.ScrollTo = function(element) { + var options = arguments[1] || { }, + scrollOffsets = document.viewport.getScrollOffsets(), + elementOffsets = $(element).cumulativeOffset(); + + if (options.offset) elementOffsets[1] += options.offset; + + return new Effect.Tween(null, + scrollOffsets.top, + elementOffsets[1], + options, + function(p){ scrollTo(scrollOffsets.left, p.round()); } + ); +}; + +/* ------------- combination effects ------------- */ + +Effect.Fade = function(element) { + element = $(element); + var oldOpacity = element.getInlineOpacity(); + var options = Object.extend({ + from: element.getOpacity() || 1.0, + to: 0.0, + afterFinishInternal: function(effect) { + if (effect.options.to!=0) return; + effect.element.hide().setStyle({opacity: oldOpacity}); + } + }, arguments[1] || { }); + return new Effect.Opacity(element,options); +}; + +Effect.Appear = function(element) { + element = $(element); + var options = Object.extend({ + from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), + to: 1.0, + // force Safari to render floated elements properly + afterFinishInternal: function(effect) { + effect.element.forceRerendering(); + }, + beforeSetup: function(effect) { + effect.element.setOpacity(effect.options.from).show(); + }}, arguments[1] || { }); + return new Effect.Opacity(element,options); +}; + +Effect.Puff = function(element) { + element = $(element); + var oldStyle = { + opacity: element.getInlineOpacity(), + position: element.getStyle('position'), + top: element.style.top, + left: element.style.left, + width: element.style.width, + height: element.style.height + }; + return new Effect.Parallel( + [ new Effect.Scale(element, 200, + { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], + Object.extend({ duration: 1.0, + beforeSetupInternal: function(effect) { + Position.absolutize(effect.effects[0].element); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().setStyle(oldStyle); } + }, arguments[1] || { }) + ); +}; + +Effect.BlindUp = function(element) { + element = $(element); + element.makeClipping(); + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + restoreAfterFinish: true, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping(); + } + }, arguments[1] || { }) + ); +}; + +Effect.BlindDown = function(element) { + element = $(element); + var elementDimensions = element.getDimensions(); + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, + scaleX: false, + scaleFrom: 0, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makeClipping().setStyle({height: '0px'}).show(); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping(); + } + }, arguments[1] || { })); +}; + +Effect.SwitchOff = function(element) { + element = $(element); + var oldOpacity = element.getInlineOpacity(); + return new Effect.Appear(element, Object.extend({ + duration: 0.4, + from: 0, + transition: Effect.Transitions.flicker, + afterFinishInternal: function(effect) { + new Effect.Scale(effect.element, 1, { + duration: 0.3, scaleFromCenter: true, + scaleX: false, scaleContent: false, restoreAfterFinish: true, + beforeSetup: function(effect) { + effect.element.makePositioned().makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); + } + }); + } + }, arguments[1] || { })); +}; + +Effect.DropOut = function(element) { + element = $(element); + var oldStyle = { + top: element.getStyle('top'), + left: element.getStyle('left'), + opacity: element.getInlineOpacity() }; + return new Effect.Parallel( + [ new Effect.Move(element, {x: 0, y: 100, sync: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 }) ], + Object.extend( + { duration: 0.5, + beforeSetup: function(effect) { + effect.effects[0].element.makePositioned(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); + } + }, arguments[1] || { })); +}; + +Effect.Shake = function(element) { + element = $(element); + var options = Object.extend({ + distance: 20, + duration: 0.5 + }, arguments[1] || {}); + var distance = parseFloat(options.distance); + var split = parseFloat(options.duration) / 10.0; + var oldStyle = { + top: element.getStyle('top'), + left: element.getStyle('left') }; + return new Effect.Move(element, + { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { + effect.element.undoPositioned().setStyle(oldStyle); + }}); }}); }}); }}); }}); }}); +}; + +Effect.SlideDown = function(element) { + element = $(element).cleanWhitespace(); + // SlideDown need to have the content of the element wrapped in a container element with fixed height! + var oldInnerBottom = element.down().getStyle('bottom'); + var elementDimensions = element.getDimensions(); + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, + scaleX: false, + scaleFrom: window.opera ? 0 : 1, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makePositioned(); + effect.element.down().makePositioned(); + if (window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping().setStyle({height: '0px'}).show(); + }, + afterUpdateInternal: function(effect) { + effect.element.down().setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping().undoPositioned(); + effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } + }, arguments[1] || { }) + ); +}; + +Effect.SlideUp = function(element) { + element = $(element).cleanWhitespace(); + var oldInnerBottom = element.down().getStyle('bottom'); + var elementDimensions = element.getDimensions(); + return new Effect.Scale(element, window.opera ? 0 : 1, + Object.extend({ scaleContent: false, + scaleX: false, + scaleMode: 'box', + scaleFrom: 100, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makePositioned(); + effect.element.down().makePositioned(); + if (window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping().show(); + }, + afterUpdateInternal: function(effect) { + effect.element.down().setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().undoPositioned(); + effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); + } + }, arguments[1] || { }) + ); +}; + +// Bug in opera makes the TD containing this element expand for a instance after finish +Effect.Squish = function(element) { + return new Effect.Scale(element, window.opera ? 1 : 0, { + restoreAfterFinish: true, + beforeSetup: function(effect) { + effect.element.makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping(); + } + }); +}; + +Effect.Grow = function(element) { + element = $(element); + var options = Object.extend({ + direction: 'center', + moveTransition: Effect.Transitions.sinoidal, + scaleTransition: Effect.Transitions.sinoidal, + opacityTransition: Effect.Transitions.full + }, arguments[1] || { }); + var oldStyle = { + top: element.style.top, + left: element.style.left, + height: element.style.height, + width: element.style.width, + opacity: element.getInlineOpacity() }; + + var dims = element.getDimensions(); + var initialMoveX, initialMoveY; + var moveX, moveY; + + switch (options.direction) { + case 'top-left': + initialMoveX = initialMoveY = moveX = moveY = 0; + break; + case 'top-right': + initialMoveX = dims.width; + initialMoveY = moveY = 0; + moveX = -dims.width; + break; + case 'bottom-left': + initialMoveX = moveX = 0; + initialMoveY = dims.height; + moveY = -dims.height; + break; + case 'bottom-right': + initialMoveX = dims.width; + initialMoveY = dims.height; + moveX = -dims.width; + moveY = -dims.height; + break; + case 'center': + initialMoveX = dims.width / 2; + initialMoveY = dims.height / 2; + moveX = -dims.width / 2; + moveY = -dims.height / 2; + break; + } + + return new Effect.Move(element, { + x: initialMoveX, + y: initialMoveY, + duration: 0.01, + beforeSetup: function(effect) { + effect.element.hide().makeClipping().makePositioned(); + }, + afterFinishInternal: function(effect) { + new Effect.Parallel( + [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), + new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), + new Effect.Scale(effect.element, 100, { + scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, + sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) + ], Object.extend({ + beforeSetup: function(effect) { + effect.effects[0].element.setStyle({height: '0px'}).show(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); + } + }, options) + ); + } + }); +}; + +Effect.Shrink = function(element) { + element = $(element); + var options = Object.extend({ + direction: 'center', + moveTransition: Effect.Transitions.sinoidal, + scaleTransition: Effect.Transitions.sinoidal, + opacityTransition: Effect.Transitions.none + }, arguments[1] || { }); + var oldStyle = { + top: element.style.top, + left: element.style.left, + height: element.style.height, + width: element.style.width, + opacity: element.getInlineOpacity() }; + + var dims = element.getDimensions(); + var moveX, moveY; + + switch (options.direction) { + case 'top-left': + moveX = moveY = 0; + break; + case 'top-right': + moveX = dims.width; + moveY = 0; + break; + case 'bottom-left': + moveX = 0; + moveY = dims.height; + break; + case 'bottom-right': + moveX = dims.width; + moveY = dims.height; + break; + case 'center': + moveX = dims.width / 2; + moveY = dims.height / 2; + break; + } + + return new Effect.Parallel( + [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), + new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), + new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) + ], Object.extend({ + beforeStartInternal: function(effect) { + effect.effects[0].element.makePositioned().makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } + }, options) + ); +}; + +Effect.Pulsate = function(element) { + element = $(element); + var options = arguments[1] || { }, + oldOpacity = element.getInlineOpacity(), + transition = options.transition || Effect.Transitions.linear, + reverser = function(pos){ + return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5); + }; + + return new Effect.Opacity(element, + Object.extend(Object.extend({ duration: 2.0, from: 0, + afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } + }, options), {transition: reverser})); +}; + +Effect.Fold = function(element) { + element = $(element); + var oldStyle = { + top: element.style.top, + left: element.style.left, + width: element.style.width, + height: element.style.height }; + element.makeClipping(); + return new Effect.Scale(element, 5, Object.extend({ + scaleContent: false, + scaleX: false, + afterFinishInternal: function(effect) { + new Effect.Scale(element, 1, { + scaleContent: false, + scaleY: false, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().setStyle(oldStyle); + } }); + }}, arguments[1] || { })); +}; + +Effect.Morph = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ + style: { } + }, arguments[1] || { }); + + if (!Object.isString(options.style)) this.style = $H(options.style); + else { + if (options.style.include(':')) + this.style = options.style.parseStyle(); + else { + this.element.addClassName(options.style); + this.style = $H(this.element.getStyles()); + this.element.removeClassName(options.style); + var css = this.element.getStyles(); + this.style = this.style.reject(function(style) { + return style.value == css[style.key]; + }); + options.afterFinishInternal = function(effect) { + effect.element.addClassName(effect.options.style); + effect.transforms.each(function(transform) { + effect.element.style[transform.style] = ''; + }); + }; + } + } + this.start(options); + }, + + setup: function(){ + function parseColor(color){ + if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; + color = color.parseColor(); + return $R(0,2).map(function(i){ + return parseInt( color.slice(i*2+1,i*2+3), 16 ); + }); + } + this.transforms = this.style.map(function(pair){ + var property = pair[0], value = pair[1], unit = null; + + if (value.parseColor('#zzzzzz') != '#zzzzzz') { + value = value.parseColor(); + unit = 'color'; + } else if (property == 'opacity') { + value = parseFloat(value); + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) + this.element.setStyle({zoom: 1}); + } else if (Element.CSS_LENGTH.test(value)) { + var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); + value = parseFloat(components[1]); + unit = (components.length == 3) ? components[2] : null; + } + + var originalValue = this.element.getStyle(property); + return { + style: property.camelize(), + originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), + targetValue: unit=='color' ? parseColor(value) : value, + unit: unit + }; + }.bind(this)).reject(function(transform){ + return ( + (transform.originalValue == transform.targetValue) || + ( + transform.unit != 'color' && + (isNaN(transform.originalValue) || isNaN(transform.targetValue)) + ) + ); + }); + }, + update: function(position) { + var style = { }, transform, i = this.transforms.length; + while(i--) + style[(transform = this.transforms[i]).style] = + transform.unit=='color' ? '#'+ + (Math.round(transform.originalValue[0]+ + (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + + (Math.round(transform.originalValue[1]+ + (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + + (Math.round(transform.originalValue[2]+ + (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : + (transform.originalValue + + (transform.targetValue - transform.originalValue) * position).toFixed(3) + + (transform.unit === null ? '' : transform.unit); + this.element.setStyle(style, true); + } +}); + +Effect.Transform = Class.create({ + initialize: function(tracks){ + this.tracks = []; + this.options = arguments[1] || { }; + this.addTracks(tracks); + }, + addTracks: function(tracks){ + tracks.each(function(track){ + track = $H(track); + var data = track.values().first(); + this.tracks.push($H({ + ids: track.keys().first(), + effect: Effect.Morph, + options: { style: data } + })); + }.bind(this)); + return this; + }, + play: function(){ + return new Effect.Parallel( + this.tracks.map(function(track){ + var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options'); + var elements = [$(ids) || $$(ids)].flatten(); + return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) }); + }).flatten(), + this.options + ); + } +}); + +Element.CSS_PROPERTIES = $w( + 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + + 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + + 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + + 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + + 'fontSize fontWeight height left letterSpacing lineHeight ' + + 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+ + 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + + 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + + 'right textIndent top width wordSpacing zIndex'); + +Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; + +String.__parseStyleElement = document.createElement('div'); +String.prototype.parseStyle = function(){ + var style, styleRules = $H(); + if (Prototype.Browser.WebKit) + style = new Element('div',{style:this}).style; + else { + String.__parseStyleElement.innerHTML = '
    '; + style = String.__parseStyleElement.childNodes[0].style; + } + + Element.CSS_PROPERTIES.each(function(property){ + if (style[property]) styleRules.set(property, style[property]); + }); + + if (Prototype.Browser.IE && this.include('opacity')) + styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); + + return styleRules; +}; + +if (document.defaultView && document.defaultView.getComputedStyle) { + Element.getStyles = function(element) { + var css = document.defaultView.getComputedStyle($(element), null); + return Element.CSS_PROPERTIES.inject({ }, function(styles, property) { + styles[property] = css[property]; + return styles; + }); + }; +} else { + Element.getStyles = function(element) { + element = $(element); + var css = element.currentStyle, styles; + styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) { + results[property] = css[property]; + return results; + }); + if (!styles.opacity) styles.opacity = element.getOpacity(); + return styles; + }; +} + +Effect.Methods = { + morph: function(element, style) { + element = $(element); + new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { })); + return element; + }, + visualEffect: function(element, effect, options) { + element = $(element); + var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); + new Effect[klass](element, options); + return element; + }, + highlight: function(element, options) { + element = $(element); + new Effect.Highlight(element, options); + return element; + } +}; + +$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ + 'pulsate shake puff squish switchOff dropOut').each( + function(effect) { + Effect.Methods[effect] = function(element, options){ + element = $(element); + Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); + return element; + }; + } +); + +$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( + function(f) { Effect.Methods[f] = Element[f]; } +); + +Element.addMethods(Effect.Methods); \ No newline at end of file diff --git a/src/wp-includes/js/scriptaculous/scriptaculous.js b/src/wp-includes/js/scriptaculous/scriptaculous.js new file mode 100644 index 00000000..6bf437ac --- /dev/null +++ b/src/wp-includes/js/scriptaculous/scriptaculous.js @@ -0,0 +1,68 @@ +// script.aculo.us scriptaculous.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +var Scriptaculous = { + Version: '1.8.3', + require: function(libraryName) { + try{ + // inserting via DOM fails in Safari 2.0, so brute force approach + document.write(' + + Notes: + You must provide set minimum_flash_version setting to "8" if you are using SWFUpload for Flash Player 8. + The swfuploadLoadFailed event is only fired if the minimum version of Flash Player is not met. Other issues such as missing SWF files, browser bugs + or corrupt Flash Player installations will not trigger this event. + The swfuploadPreLoad event is fired as soon as the minimum version of Flash Player is found. It does not wait for SWFUpload to load and can + be used to prepare the SWFUploadUI and hide alternate content. + swfobject's onDomReady event is cross-browser safe but will default to the window.onload event when DOMReady is not supported by the browser. + Early DOM Loading is supported in major modern browsers but cannot be guaranteed for every browser ever made. +*/ + + +// SWFObject v2.1 must be loaded + +var SWFUpload; +if (typeof(SWFUpload) === "function") { + SWFUpload.onload = function () {}; + + swfobject.addDomLoadEvent(function () { + if (typeof(SWFUpload.onload) === "function") { + SWFUpload.onload.call(window); + } + }); + + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + + this.ensureDefault("minimum_flash_version", "9.0.28"); + this.ensureDefault("swfupload_pre_load_handler", null); + this.ensureDefault("swfupload_load_failed_handler", null); + + delete this.ensureDefault; + + }; + })(SWFUpload.prototype.initSettings); + + + SWFUpload.prototype.loadFlash = function (oldLoadFlash) { + return function () { + var hasFlash = swfobject.hasFlashPlayerVersion(this.settings.minimum_flash_version); + + if (hasFlash) { + this.queueEvent("swfupload_pre_load_handler"); + if (typeof(oldLoadFlash) === "function") { + oldLoadFlash.call(this); + } + } else { + this.queueEvent("swfupload_load_failed_handler"); + } + }; + + }(SWFUpload.prototype.loadFlash); + + SWFUpload.prototype.displayDebugInfo = function (oldDisplayDebugInfo) { + return function () { + if (typeof(oldDisplayDebugInfo) === "function") { + oldDisplayDebugInfo.call(this); + } + + this.debug( + [ + "SWFUpload.SWFObject Plugin settings:", "\n", + "\t", "minimum_flash_version: ", this.settings.minimum_flash_version, "\n", + "\t", "swfupload_pre_load_handler assigned: ", (typeof(this.settings.swfupload_pre_load_handler) === "function").toString(), "\n", + "\t", "swfupload_load_failed_handler assigned: ", (typeof(this.settings.swfupload_load_failed_handler) === "function").toString(), "\n", + ].join("") + ); + }; + }(SWFUpload.prototype.displayDebugInfo); +} diff --git a/src/wp-includes/js/swfupload/swfupload-all.js b/src/wp-includes/js/swfupload/swfupload-all.js new file mode 100644 index 00000000..afb79213 --- /dev/null +++ b/src/wp-includes/js/swfupload/swfupload-all.js @@ -0,0 +1,8 @@ +// swfupload +var SWFUpload;if(SWFUpload==undefined){SWFUpload=function(a){this.initSWFUpload(a)}}SWFUpload.prototype.initSWFUpload=function(b){try{this.customSettings={};this.settings=b;this.eventQueue=[];this.movieName="SWFUpload_"+SWFUpload.movieCount++;this.movieElement=null;SWFUpload.instances[this.movieName]=this;this.initSettings();this.loadFlash()}catch(a){delete SWFUpload.instances[this.movieName];throw a}};SWFUpload.instances={};SWFUpload.movieCount=0;SWFUpload.version="2.2.0 2009-03-25";SWFUpload.QUEUE_ERROR={QUEUE_LIMIT_EXCEEDED:-100,FILE_EXCEEDS_SIZE_LIMIT:-110,ZERO_BYTE_FILE:-120,INVALID_FILETYPE:-130};SWFUpload.UPLOAD_ERROR={HTTP_ERROR:-200,MISSING_UPLOAD_URL:-210,IO_ERROR:-220,SECURITY_ERROR:-230,UPLOAD_LIMIT_EXCEEDED:-240,UPLOAD_FAILED:-250,SPECIFIED_FILE_ID_NOT_FOUND:-260,FILE_VALIDATION_FAILED:-270,FILE_CANCELLED:-280,UPLOAD_STOPPED:-290};SWFUpload.FILE_STATUS={QUEUED:-1,IN_PROGRESS:-2,ERROR:-3,COMPLETE:-4,CANCELLED:-5};SWFUpload.BUTTON_ACTION={SELECT_FILE:-100,SELECT_FILES:-110,START_UPLOAD:-120};SWFUpload.CURSOR={ARROW:-1,HAND:-2};SWFUpload.WINDOW_MODE={WINDOW:"window",TRANSPARENT:"transparent",OPAQUE:"opaque"};SWFUpload.completeURL=function(a){if(typeof(a)!=="string"||a.match(/^https?:\/\//i)||a.match(/^\//)){return a}var c,b;c=window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:"");b=window.location.pathname.lastIndexOf("/");if(b<=0){path="/"}else{path=window.location.pathname.substr(0,b)+"/"}return path+a};SWFUpload.prototype.initSettings=function(){this.ensureDefault=function(b,a){this.settings[b]=(this.settings[b]==undefined)?a:this.settings[b]};this.ensureDefault("upload_url","");this.ensureDefault("preserve_relative_urls",false);this.ensureDefault("file_post_name","Filedata");this.ensureDefault("post_params",{});this.ensureDefault("use_query_string",false);this.ensureDefault("requeue_on_error",false);this.ensureDefault("http_success",[]);this.ensureDefault("assume_success_timeout",0);this.ensureDefault("file_types","*.*");this.ensureDefault("file_types_description","All Files");this.ensureDefault("file_size_limit",0);this.ensureDefault("file_upload_limit",0);this.ensureDefault("file_queue_limit",0);this.ensureDefault("flash_url","swfupload.swf");this.ensureDefault("prevent_swf_caching",true);this.ensureDefault("button_image_url","");this.ensureDefault("button_width",1);this.ensureDefault("button_height",1);this.ensureDefault("button_text","");this.ensureDefault("button_text_style","color: #000000; font-size: 16pt;");this.ensureDefault("button_text_top_padding",0);this.ensureDefault("button_text_left_padding",0);this.ensureDefault("button_action",SWFUpload.BUTTON_ACTION.SELECT_FILES);this.ensureDefault("button_disabled",false);this.ensureDefault("button_placeholder_id","");this.ensureDefault("button_placeholder",null);this.ensureDefault("button_cursor",SWFUpload.CURSOR.ARROW);this.ensureDefault("button_window_mode",SWFUpload.WINDOW_MODE.WINDOW);this.ensureDefault("debug",false);this.settings.debug_enabled=this.settings.debug;this.settings.return_upload_start_handler=this.returnUploadStart;this.ensureDefault("swfupload_loaded_handler",null);this.ensureDefault("file_dialog_start_handler",null);this.ensureDefault("file_queued_handler",null);this.ensureDefault("file_queue_error_handler",null);this.ensureDefault("file_dialog_complete_handler",null);this.ensureDefault("upload_start_handler",null);this.ensureDefault("upload_progress_handler",null);this.ensureDefault("upload_error_handler",null);this.ensureDefault("upload_success_handler",null);this.ensureDefault("upload_complete_handler",null);this.ensureDefault("debug_handler",this.debugMessage);this.ensureDefault("custom_settings",{});this.customSettings=this.settings.custom_settings;if(!!this.settings.prevent_swf_caching){this.settings.flash_url=this.settings.flash_url+(this.settings.flash_url.indexOf("?")<0?"?":"&")+"preventswfcaching="+new Date().getTime()}if(!this.settings.preserve_relative_urls){this.settings.upload_url=SWFUpload.completeURL(this.settings.upload_url);this.settings.button_image_url=SWFUpload.completeURL(this.settings.button_image_url)}delete this.ensureDefault};SWFUpload.prototype.loadFlash=function(){var a,b;if(document.getElementById(this.movieName)!==null){throw"ID "+this.movieName+" is already in use. The Flash Object could not be added"}a=document.getElementById(this.settings.button_placeholder_id)||this.settings.button_placeholder;if(a==undefined){throw"Could not find the placeholder element: "+this.settings.button_placeholder_id}b=document.createElement("div");b.innerHTML=this.getFlashHTML();a.parentNode.replaceChild(b.firstChild,a);if(window[this.movieName]==undefined){window[this.movieName]=this.getMovieElement()}};SWFUpload.prototype.getFlashHTML=function(){return['','','','','','','',""].join("")};SWFUpload.prototype.getFlashVars=function(){var b=this.buildParamString(),a=this.settings.http_success.join(",");return["movieName=",encodeURIComponent(this.movieName),"&uploadURL=",encodeURIComponent(this.settings.upload_url),"&useQueryString=",encodeURIComponent(this.settings.use_query_string),"&requeueOnError=",encodeURIComponent(this.settings.requeue_on_error),"&httpSuccess=",encodeURIComponent(a),"&assumeSuccessTimeout=",encodeURIComponent(this.settings.assume_success_timeout),"&params=",encodeURIComponent(b),"&filePostName=",encodeURIComponent(this.settings.file_post_name),"&fileTypes=",encodeURIComponent(this.settings.file_types),"&fileTypesDescription=",encodeURIComponent(this.settings.file_types_description),"&fileSizeLimit=",encodeURIComponent(this.settings.file_size_limit),"&fileUploadLimit=",encodeURIComponent(this.settings.file_upload_limit),"&fileQueueLimit=",encodeURIComponent(this.settings.file_queue_limit),"&debugEnabled=",encodeURIComponent(this.settings.debug_enabled),"&buttonImageURL=",encodeURIComponent(this.settings.button_image_url),"&buttonWidth=",encodeURIComponent(this.settings.button_width),"&buttonHeight=",encodeURIComponent(this.settings.button_height),"&buttonText=",encodeURIComponent(this.settings.button_text),"&buttonTextTopPadding=",encodeURIComponent(this.settings.button_text_top_padding),"&buttonTextLeftPadding=",encodeURIComponent(this.settings.button_text_left_padding),"&buttonTextStyle=",encodeURIComponent(this.settings.button_text_style),"&buttonAction=",encodeURIComponent(this.settings.button_action),"&buttonDisabled=",encodeURIComponent(this.settings.button_disabled),"&buttonCursor=",encodeURIComponent(this.settings.button_cursor)].join("")};SWFUpload.prototype.getMovieElement=function(){if(this.movieElement==undefined){this.movieElement=document.getElementById(this.movieName)}if(this.movieElement===null){throw"Could not find Flash element"}return this.movieElement};SWFUpload.prototype.buildParamString=function(){var c=this.settings.post_params,b=[],a;if(typeof(c)==="object"){for(a in c){if(c.hasOwnProperty(a)){b.push(encodeURIComponent(a.toString())+"="+encodeURIComponent(c[a].toString()))}}}return b.join("&")};SWFUpload.prototype.destroy=function(){try{this.cancelUpload(null,false);var a=null,c;a=this.getMovieElement();if(a&&typeof(a.CallFunction)==="unknown"){for(c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(e){}}try{a.parentNode.removeChild(a)}catch(b){}}window[this.movieName]=null;SWFUpload.instances[this.movieName]=null;delete SWFUpload.instances[this.movieName];this.movieElement=null;this.settings=null;this.customSettings=null;this.eventQueue=null;this.movieName=null;return true}catch(d){return false}};SWFUpload.prototype.addSetting=function(b,c,a){if(c==undefined){return(this.settings[b]=a)}else{return(this.settings[b]=c)}};SWFUpload.prototype.getSetting=function(a){if(this.settings[a]!=undefined){return this.settings[a]}return""};SWFUpload.prototype.callFlash=function(functionName,argumentArray){argumentArray=argumentArray||[];var movieElement=this.getMovieElement(),returnValue,returnString;try{returnString=movieElement.CallFunction(''+__flash__argumentsToXML(argumentArray,0)+"");returnValue=eval(returnString)}catch(ex){throw"Call to "+functionName+" failed"}if(returnValue!=undefined&&typeof returnValue.post==="object"){returnValue=this.unescapeFilePostParams(returnValue)}return returnValue};SWFUpload.prototype.selectFile=function(){this.callFlash("SelectFile")};SWFUpload.prototype.selectFiles=function(){this.callFlash("SelectFiles")};SWFUpload.prototype.startUpload=function(a){this.callFlash("StartUpload",[a])};SWFUpload.prototype.cancelUpload=function(a,b){if(b!==false){b=true}this.callFlash("CancelUpload",[a,b])};SWFUpload.prototype.stopUpload=function(){this.callFlash("StopUpload")};SWFUpload.prototype.getStats=function(){return this.callFlash("GetStats")};SWFUpload.prototype.setStats=function(a){this.callFlash("SetStats",[a])};SWFUpload.prototype.getFile=function(a){if(typeof(a)==="number"){return this.callFlash("GetFileByIndex",[a])}else{return this.callFlash("GetFile",[a])}};SWFUpload.prototype.addFileParam=function(a,b,c){return this.callFlash("AddFileParam",[a,b,c])};SWFUpload.prototype.removeFileParam=function(a,b){this.callFlash("RemoveFileParam",[a,b])};SWFUpload.prototype.setUploadURL=function(a){this.settings.upload_url=a.toString();this.callFlash("SetUploadURL",[a])};SWFUpload.prototype.setPostParams=function(a){this.settings.post_params=a;this.callFlash("SetPostParams",[a])};SWFUpload.prototype.addPostParam=function(a,b){this.settings.post_params[a]=b;this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.removePostParam=function(a){delete this.settings.post_params[a];this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.setFileTypes=function(a,b){this.settings.file_types=a;this.settings.file_types_description=b;this.callFlash("SetFileTypes",[a,b])};SWFUpload.prototype.setFileSizeLimit=function(a){this.settings.file_size_limit=a;this.callFlash("SetFileSizeLimit",[a])};SWFUpload.prototype.setFileUploadLimit=function(a){this.settings.file_upload_limit=a;this.callFlash("SetFileUploadLimit",[a])};SWFUpload.prototype.setFileQueueLimit=function(a){this.settings.file_queue_limit=a;this.callFlash("SetFileQueueLimit",[a])};SWFUpload.prototype.setFilePostName=function(a){this.settings.file_post_name=a;this.callFlash("SetFilePostName",[a])};SWFUpload.prototype.setUseQueryString=function(a){this.settings.use_query_string=a;this.callFlash("SetUseQueryString",[a])};SWFUpload.prototype.setRequeueOnError=function(a){this.settings.requeue_on_error=a;this.callFlash("SetRequeueOnError",[a])};SWFUpload.prototype.setHTTPSuccess=function(a){if(typeof a==="string"){a=a.replace(" ","").split(",")}this.settings.http_success=a;this.callFlash("SetHTTPSuccess",[a])};SWFUpload.prototype.setAssumeSuccessTimeout=function(a){this.settings.assume_success_timeout=a;this.callFlash("SetAssumeSuccessTimeout",[a])};SWFUpload.prototype.setDebugEnabled=function(a){this.settings.debug_enabled=a;this.callFlash("SetDebugEnabled",[a])};SWFUpload.prototype.setButtonImageURL=function(a){if(a==undefined){a=""}this.settings.button_image_url=a;this.callFlash("SetButtonImageURL",[a])};SWFUpload.prototype.setButtonDimensions=function(c,a){this.settings.button_width=c;this.settings.button_height=a;var b=this.getMovieElement();if(b!=undefined){b.style.width=c+"px";b.style.height=a+"px"}this.callFlash("SetButtonDimensions",[c,a])};SWFUpload.prototype.setButtonText=function(a){this.settings.button_text=a;this.callFlash("SetButtonText",[a])};SWFUpload.prototype.setButtonTextPadding=function(b,a){this.settings.button_text_top_padding=a;this.settings.button_text_left_padding=b;this.callFlash("SetButtonTextPadding",[b,a])};SWFUpload.prototype.setButtonTextStyle=function(a){this.settings.button_text_style=a;this.callFlash("SetButtonTextStyle",[a])};SWFUpload.prototype.setButtonDisabled=function(a){this.settings.button_disabled=a;this.callFlash("SetButtonDisabled",[a])};SWFUpload.prototype.setButtonAction=function(a){this.settings.button_action=a;this.callFlash("SetButtonAction",[a])};SWFUpload.prototype.setButtonCursor=function(a){this.settings.button_cursor=a;this.callFlash("SetButtonCursor",[a])};SWFUpload.prototype.queueEvent=function(b,c){if(c==undefined){c=[]}else{if(!(c instanceof Array)){c=[c]}}var a=this;if(typeof this.settings[b]==="function"){this.eventQueue.push(function(){this.settings[b].apply(this,c)});setTimeout(function(){a.executeNextEvent()},0)}else{if(this.settings[b]!==null){throw"Event handler "+b+" is unknown or is not a function"}}};SWFUpload.prototype.executeNextEvent=function(){var a=this.eventQueue?this.eventQueue.shift():null;if(typeof(a)==="function"){a.apply(this)}};SWFUpload.prototype.unescapeFilePostParams=function(c){var e=/[$]([0-9a-f]{4})/i,f={},d,a,b;if(c!=undefined){for(a in c.post){if(c.post.hasOwnProperty(a)){d=a;while((b=e.exec(d))!==null){d=d.replace(b[0],String.fromCharCode(parseInt("0x"+b[1],16)))}f[d]=c.post[a]}}c.post=f}return c};SWFUpload.prototype.testExternalInterface=function(){try{return this.callFlash("TestExternalInterface")}catch(a){return false}};SWFUpload.prototype.flashReady=function(){var a=this.getMovieElement();if(!a){this.debug("Flash called back ready but the flash movie can't be found.");return}this.cleanUp(a);this.queueEvent("swfupload_loaded_handler")};SWFUpload.prototype.cleanUp=function(a){var c;try{if(this.movieElement&&typeof(a.CallFunction)==="unknown"){this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");for(c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(b){}}}}catch(d){}window.__flash__removeCallback=function(e,f){try{if(e){e[f]=null}}catch(g){}}};SWFUpload.prototype.fileDialogStart=function(){this.queueEvent("file_dialog_start_handler")};SWFUpload.prototype.fileQueued=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("file_queued_handler",a)};SWFUpload.prototype.fileQueueError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("file_queue_error_handler",[a,c,b])};SWFUpload.prototype.fileDialogComplete=function(b,c,a){this.queueEvent("file_dialog_complete_handler",[b,c,a])};SWFUpload.prototype.uploadStart=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("return_upload_start_handler",a)};SWFUpload.prototype.returnUploadStart=function(a){var b;if(typeof this.settings.upload_start_handler==="function"){a=this.unescapeFilePostParams(a);b=this.settings.upload_start_handler.call(this,a)}else{if(this.settings.upload_start_handler!=undefined){throw"upload_start_handler must be a function"}}if(b===undefined){b=true}b=!!b;this.callFlash("ReturnUploadStart",[b])};SWFUpload.prototype.uploadProgress=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_progress_handler",[a,c,b])};SWFUpload.prototype.uploadError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_error_handler",[a,c,b])};SWFUpload.prototype.uploadSuccess=function(b,a,c){b=this.unescapeFilePostParams(b);this.queueEvent("upload_success_handler",[b,a,c])};SWFUpload.prototype.uploadComplete=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("upload_complete_handler",a)};SWFUpload.prototype.debug=function(a){this.queueEvent("debug_handler",a)}; +// swfupload.queue +var SWFUpload;if(typeof(SWFUpload)==="function"){SWFUpload.queue={};SWFUpload.prototype.initSettings=(function(a){return function(){if(typeof(a)==="function"){a.call(this)}this.queueSettings={};this.queueSettings.queue_cancelled_flag=false;this.queueSettings.queue_upload_count=0;this.queueSettings.user_upload_complete_handler=this.settings.upload_complete_handler;this.queueSettings.user_upload_start_handler=this.settings.upload_start_handler;this.settings.upload_complete_handler=SWFUpload.queue.uploadCompleteHandler;this.settings.upload_start_handler=SWFUpload.queue.uploadStartHandler;this.settings.queue_complete_handler=this.settings.queue_complete_handler||null}})(SWFUpload.prototype.initSettings);SWFUpload.prototype.startUpload=function(a){this.queueSettings.queue_cancelled_flag=false;this.callFlash("StartUpload",[a])};SWFUpload.prototype.cancelQueue=function(){this.queueSettings.queue_cancelled_flag=true;this.stopUpload();var a=this.getStats();while(a.files_queued>0){this.cancelUpload();a=this.getStats()}};SWFUpload.queue.uploadStartHandler=function(a){var b;if(typeof(this.queueSettings.user_upload_start_handler)==="function"){b=this.queueSettings.user_upload_start_handler.call(this,a)}b=(b===false)?false:true;this.queueSettings.queue_cancelled_flag=!b;return b};SWFUpload.queue.uploadCompleteHandler=function(b){var c=this.queueSettings.user_upload_complete_handler,d,a;if(b.filestatus===SWFUpload.FILE_STATUS.COMPLETE){this.queueSettings.queue_upload_count++}if(typeof(c)==="function"){d=(c.call(this,b)===false)?false:true}else{if(b.filestatus===SWFUpload.FILE_STATUS.QUEUED){d=false}else{d=true}}if(d){a=this.getStats();if(a.files_queued>0&&this.queueSettings.queue_cancelled_flag===false){this.startUpload()}else{if(this.queueSettings.queue_cancelled_flag===false){this.queueEvent("queue_complete_handler",[this.queueSettings.queue_upload_count]);this.queueSettings.queue_upload_count=0}else{this.queueSettings.queue_cancelled_flag=false;this.queueSettings.queue_upload_count=0}}}}}; +// swfobject +var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write(" + + + +
    + +
    + + + + + diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js new file mode 100644 index 00000000..e57c9438 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js @@ -0,0 +1 @@ +(function(){var d=tinymce.DOM,b=tinymce.dom.Element,a=tinymce.dom.Event,e=tinymce.each,c=tinymce.is;tinymce.create("tinymce.plugins.InlinePopups",{init:function(f,g){f.onBeforeRenderUI.add(function(){f.windowManager=new tinymce.InlineWindowManager(f);d.loadCSS(g+"/skins/"+(f.settings.inlinepopups_skin||"clearlooks2")+"/window.css")})},getInfo:function(){return{longname:"InlinePopups",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.create("tinymce.InlineWindowManager:tinymce.WindowManager",{InlineWindowManager:function(f){var g=this;g.parent(f);g.zIndex=300000;g.count=0;g.windows={}},open:function(r,j){var y=this,i,k="",q=y.editor,g=0,s=0,h,m,n,o,l,v,x;r=r||{};j=j||{};if(!r.inline){return y.parent(r,j)}if(!r.type){y.bookmark=q.selection.getBookmark(1)}i=d.uniqueId();h=d.getViewPort();r.width=parseInt(r.width||320);r.height=parseInt(r.height||240)+(tinymce.isIE?8:0);r.min_width=parseInt(r.min_width||150);r.min_height=parseInt(r.min_height||100);r.max_width=parseInt(r.max_width||2000);r.max_height=parseInt(r.max_height||2000);r.left=r.left||Math.round(Math.max(h.x,h.x+(h.w/2)-(r.width/2)));r.top=r.top||Math.round(Math.max(h.y,h.y+(h.h/2)-(r.height/2)));r.movable=r.resizable=true;j.mce_width=r.width;j.mce_height=r.height;j.mce_inline=true;j.mce_window_id=i;j.mce_auto_focus=r.auto_focus;y.features=r;y.params=j;y.onOpen.dispatch(y,r,j);if(r.type){k+=" mceModal";if(r.type){k+=" mce"+r.type.substring(0,1).toUpperCase()+r.type.substring(1)}r.resizable=false}if(r.statusbar){k+=" mceStatusbar"}if(r.resizable){k+=" mceResizable"}if(r.minimizable){k+=" mceMinimizable"}if(r.maximizable){k+=" mceMaximizable"}if(r.movable){k+=" mceMovable"}y._addAll(d.doc.body,["div",{id:i,"class":(q.settings.inlinepopups_skin||"clearlooks2")+(tinymce.isIE&&window.getSelection?" ie9":""),style:"width:100px;height:100px"},["div",{id:i+"_wrapper","class":"mceWrapper"+k},["div",{id:i+"_top","class":"mceTop"},["div",{"class":"mceLeft"}],["div",{"class":"mceCenter"}],["div",{"class":"mceRight"}],["span",{id:i+"_title"},r.title||""]],["div",{id:i+"_middle","class":"mceMiddle"},["div",{id:i+"_left","class":"mceLeft"}],["span",{id:i+"_content"}],["div",{id:i+"_right","class":"mceRight"}]],["div",{id:i+"_bottom","class":"mceBottom"},["div",{"class":"mceLeft"}],["div",{"class":"mceCenter"}],["div",{"class":"mceRight"}],["span",{id:i+"_status"},"Content"]],["a",{"class":"mceMove",tabindex:"-1",href:"javascript:;"}],["a",{"class":"mceMin",tabindex:"-1",href:"javascript:;",onmousedown:"return false;"}],["a",{"class":"mceMax",tabindex:"-1",href:"javascript:;",onmousedown:"return false;"}],["a",{"class":"mceMed",tabindex:"-1",href:"javascript:;",onmousedown:"return false;"}],["a",{"class":"mceClose",tabindex:"-1",href:"javascript:;",onmousedown:"return false;"}],["a",{id:i+"_resize_n","class":"mceResize mceResizeN",tabindex:"-1",href:"javascript:;"}],["a",{id:i+"_resize_s","class":"mceResize mceResizeS",tabindex:"-1",href:"javascript:;"}],["a",{id:i+"_resize_w","class":"mceResize mceResizeW",tabindex:"-1",href:"javascript:;"}],["a",{id:i+"_resize_e","class":"mceResize mceResizeE",tabindex:"-1",href:"javascript:;"}],["a",{id:i+"_resize_nw","class":"mceResize mceResizeNW",tabindex:"-1",href:"javascript:;"}],["a",{id:i+"_resize_ne","class":"mceResize mceResizeNE",tabindex:"-1",href:"javascript:;"}],["a",{id:i+"_resize_sw","class":"mceResize mceResizeSW",tabindex:"-1",href:"javascript:;"}],["a",{id:i+"_resize_se","class":"mceResize mceResizeSE",tabindex:"-1",href:"javascript:;"}]]]);d.setStyles(i,{top:-10000,left:-10000});if(tinymce.isGecko){d.setStyle(i,"overflow","auto")}if(!r.type){g+=d.get(i+"_left").clientWidth;g+=d.get(i+"_right").clientWidth;s+=d.get(i+"_top").clientHeight;s+=d.get(i+"_bottom").clientHeight}d.setStyles(i,{top:r.top,left:r.left,width:r.width+g,height:r.height+s});x=r.url||r.file;if(x){if(tinymce.relaxedDomain){x+=(x.indexOf("?")==-1?"?":"&")+"mce_rdomain="+tinymce.relaxedDomain}x=tinymce._addVer(x)}if(!r.type){d.add(i+"_content","iframe",{id:i+"_ifr",src:'javascript:""',frameBorder:0,style:"border:0;width:10px;height:10px"});d.setStyles(i+"_ifr",{width:r.width,height:r.height});d.setAttrib(i+"_ifr","src",x)}else{d.add(i+"_wrapper","a",{id:i+"_ok","class":"mceButton mceOk",href:"javascript:;",onmousedown:"return false;"},"Ok");if(r.type=="confirm"){d.add(i+"_wrapper","a",{"class":"mceButton mceCancel",href:"javascript:;",onmousedown:"return false;"},"Cancel")}d.add(i+"_middle","div",{"class":"mceIcon"});d.setHTML(i+"_content",r.content.replace("\n","
    "))}n=a.add(i,"mousedown",function(t){var u=t.target,f,p;f=y.windows[i];y.focus(i);if(u.nodeName=="A"||u.nodeName=="a"){if(u.className=="mceMax"){f.oldPos=f.element.getXY();f.oldSize=f.element.getSize();p=d.getViewPort();p.w-=2;p.h-=2;f.element.moveTo(p.x,p.y);f.element.resizeTo(p.w,p.h);d.setStyles(i+"_ifr",{width:p.w-f.deltaWidth,height:p.h-f.deltaHeight});d.addClass(i+"_wrapper","mceMaximized")}else{if(u.className=="mceMed"){f.element.moveTo(f.oldPos.x,f.oldPos.y);f.element.resizeTo(f.oldSize.w,f.oldSize.h);f.iframeElement.resizeTo(f.oldSize.w-f.deltaWidth,f.oldSize.h-f.deltaHeight);d.removeClass(i+"_wrapper","mceMaximized")}else{if(u.className=="mceMove"){return y._startDrag(i,t,u.className)}else{if(d.hasClass(u,"mceResize")){return y._startDrag(i,t,u.className.substring(13))}}}}}});o=a.add(i,"click",function(f){var p=f.target;y.focus(i);if(p.nodeName=="A"||p.nodeName=="a"){switch(p.className){case"mceClose":y.close(null,i);return a.cancel(f);case"mceButton mceOk":case"mceButton mceCancel":r.button_func(p.className=="mceButton mceOk");return a.cancel(f)}}});v=y.windows[i]={id:i,mousedown_func:n,click_func:o,element:new b(i,{blocker:1,container:q.getContainer()}),iframeElement:new b(i+"_ifr"),features:r,deltaWidth:g,deltaHeight:s};v.iframeElement.on("focus",function(){y.focus(i)});if(y.count==0&&y.editor.getParam("dialog_type","modal")=="modal"){d.add(d.doc.body,"div",{id:"mceModalBlocker","class":(y.editor.settings.inlinepopups_skin||"clearlooks2")+"_modalBlocker",style:{zIndex:y.zIndex-1}});d.show("mceModalBlocker")}else{d.setStyle("mceModalBlocker","z-index",y.zIndex-1)}if(tinymce.isIE6||/Firefox\/2\./.test(navigator.userAgent)||(tinymce.isIE&&!d.boxModel)){d.setStyles("mceModalBlocker",{position:"absolute",left:h.x,top:h.y,width:h.w-2,height:h.h-2})}y.focus(i);y._fixIELayout(i,1);if(d.get(i+"_ok")){d.get(i+"_ok").focus()}y.count++;return v},focus:function(h){var g=this,f;if(f=g.windows[h]){f.zIndex=this.zIndex++;f.element.setStyle("zIndex",f.zIndex);f.element.update();h=h+"_wrapper";d.removeClass(g.lastId,"mceFocus");d.addClass(h,"mceFocus");g.lastId=h}},_addAll:function(k,h){var g,l,f=this,j=tinymce.DOM;if(c(h,"string")){k.appendChild(j.doc.createTextNode(h))}else{if(h.length){k=k.appendChild(j.create(h[0],h[1]));for(g=2;gf){i=m;f=m.zIndex}});if(i){h.focus(i.id)}}},setTitle:function(f,g){var h;f=this._findId(f);if(h=d.get(f+"_title")){h.innerHTML=d.encode(g)}},alert:function(g,f,j){var i=this,h;h=i.open({title:i,type:"alert",button_func:function(k){if(f){f.call(k||i,k)}i.close(null,h.id)},content:d.encode(i.editor.getLang(g,g)),inline:1,width:400,height:130})},confirm:function(g,f,j){var i=this,h;h=i.open({title:i,type:"confirm",button_func:function(k){if(f){f.call(k||i,k)}i.close(null,h.id)},content:d.encode(i.editor.getLang(g,g)),inline:1,width:400,height:130})},_findId:function(f){var g=this;if(typeof(f)=="string"){return f}e(g.windows,function(h){var i=d.get(h.id+"_ifr");if(i&&f==i.contentWindow){f=h.id;return false}});return f},_fixIELayout:function(i,h){var f,g;if(!tinymce.isIE6){return}e(["n","s","w","e","nw","ne","sw","se"],function(j){var k=d.get(i+"_resize_"+j);d.setStyles(k,{width:h?k.clientWidth:"",height:h?k.clientHeight:"",cursor:d.getStyle(k,"cursor",1)});d.setStyle(i+"_bottom","bottom","-1px");k=0});if(f=this.windows[i]){f.element.hide();f.element.show();e(d.select("div,a",i),function(k,j){if(k.currentStyle.backgroundImage!="none"){g=new Image();g.src=k.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/,"$1")}});d.get(i).style.filter=""}}});tinymce.PluginManager.add("inlinepopups",tinymce.plugins.InlinePopups)})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif new file mode 100644 index 00000000..94abd087 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/button.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/button.gif new file mode 100644 index 00000000..e671094c Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/button.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif new file mode 100644 index 00000000..b408ae1f Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif new file mode 100644 index 00000000..497307a8 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif new file mode 100644 index 00000000..c894b2e8 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/drag.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/drag.gif new file mode 100644 index 00000000..bf0a03ee Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/drag.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif new file mode 100644 index 00000000..c2a2ad45 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif new file mode 100644 index 00000000..43a735f2 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/window.css b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/window.css new file mode 100644 index 00000000..9b9fddae --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/inlinepopups/skins/clearlooks2/window.css @@ -0,0 +1,136 @@ +/* Clearlooks 2 */ + +/* Reset */ +.clearlooks2, .clearlooks2 div, .clearlooks2 span, .clearlooks2 a {vertical-align:baseline; text-align:left; position:absolute; border:0; padding:0; margin:0; background:transparent; font-family:Arial,Verdana; font-size:11px; color:#000; text-decoration:none; font-weight:normal; width:auto; height:auto; overflow:hidden; display:block} + +/* General */ +.clearlooks2 {position:absolute; direction:ltr} +.clearlooks2 .mceWrapper {position:static} +.mceEventBlocker {position:fixed; left:0; top:0; background:url(img/horizontal.gif) no-repeat 0 -75px; width:100%; height:100%} +.clearlooks2 .mcePlaceHolder {border:1px solid #000; background:#888; top:0; left:0; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50)} +.clearlooks2_modalBlocker {position:fixed; left:0; top:0; width:100%; height:100%; background:#FFF; opacity:0.6; -ms-filter:'alpha(opacity=60)'; filter:alpha(opacity=60); display:none} + +/* Top */ +.clearlooks2 .mceTop, +.clearlooks2 .mceTop div { + top:0; + width:100%; + height:23px +} +.clearlooks2 .mceTop .mceLeft { + width:55%; + background-image: none; + border-style: solid none none solid; + border-width: 1px; +} +.clearlooks2 .mceTop .mceCenter { +} +.clearlooks2 .mceTop .mceRight { + right:0; + width:55%; + height:23px; + background-image: none; + border-style: solid solid none none; + border-width: 1px; +} +.clearlooks2 .mceTop span { + width:100%; + font: 12px/20px bold "Lucida Grande","Lucida Sans Unicode",Tahoma,Verdana,sans-serif; + text-align:center; + vertical-align:middle; + line-height:23px; + font-weight:bold; +} +.clearlooks2 .mceFocus .mceTop .mceLeft { + background-image: none; + border-style: solid none none solid; + border-width: 1px; +} +.clearlooks2 .mceFocus .mceTop .mceCenter { +} +.clearlooks2 .mceFocus .mceTop .mceRight { + background-image: none; + border-style: solid solid none none; + border-width: 1px; +} +.clearlooks2 .mceFocus .mceTop span { +color:#FFF +} + +/* Middle */ +.clearlooks2 .mceMiddle, .clearlooks2 .mceMiddle div {top:0} +.clearlooks2 .mceMiddle {width:100%; height:100%; clip:rect(23px auto auto auto)} +.clearlooks2 .mceMiddle .mceLeft {left:0; width:5px; height:100%; background:#E4F2FD;border-left:1px solid #c6d9e9} +.clearlooks2 .mceMiddle span {top:23px; left:5px; width:100%; height:100%; background:#FFF} +.clearlooks2 .mceMiddle .mceRight {right:0; width:5px; height:100%; background:#E4F2FD;border-right:1px solid #c6d9e9} + +/* Bottom */ +.clearlooks2 .mceBottom, .clearlooks2 .mceBottom div {height:6px} +.clearlooks2 .mceBottom {left:0; bottom:0; width:100%;background:#E4F2FD;border-bottom:1px solid #c6d9e9} +.clearlooks2 .mceBottom div {top:0} +.clearlooks2 .mceBottom .mceLeft {left:0; width:5px; background:#E4F2FD ;border-left:1px solid #c6d9e9} +.clearlooks2 .mceBottom .mceCenter {left:5px; width:100%} +.clearlooks2 .mceBottom .mceRight {right:0; width:6px; background:#E4F2FD url(img/drag.gif) no-repeat;border-right:1px solid #c6d9e9} +.clearlooks2 .mceBottom span {display:none} +.clearlooks2 .mceStatusbar .mceBottom, .clearlooks2 .mceStatusbar .mceBottom div {height:23px} +.clearlooks2 .mceStatusbar .mceBottom .mceLeft {background:url(img/corners.gif) -29px 0} +.clearlooks2 .mceStatusbar .mceBottom .mceCenter {background:url(img/horizontal.gif) 0 -52px} +.clearlooks2 .mceStatusbar .mceBottom .mceRight {background:url(img/corners.gif) -24px 0} +.clearlooks2 .mceStatusbar .mceBottom span {display:block; left:7px; font-family:Arial, Verdana; font-size:11px; line-height:23px} + +/* Actions */ +.clearlooks2 a {width:29px; height:16px; top:3px} +.clearlooks2 .mceClose {right:6px; background:url(img/buttons.gif) -87px 0} +.clearlooks2 .mceMin {display:none; right:68px; background:url(img/buttons.gif) 0 0} +.clearlooks2 .mceMed {display:none; right:37px; background:url(img/buttons.gif) -29px 0} +.clearlooks2 .mceMax {display:none; right:37px; background:url(img/buttons.gif) -58px 0} +.clearlooks2 .mceMove {display:none;width:100%;cursor:move;background:url(img/corners.gif) no-repeat -100px -100px} +.clearlooks2 .mceMovable .mceMove {display:block} +.clearlooks2 .mceFocus .mceClose {right:6px; background:url(img/buttons.gif) -87px -16px} +.clearlooks2 .mceFocus .mceMin {right:68px; background:url(img/buttons.gif) 0 -16px} +.clearlooks2 .mceFocus .mceMed {right:37px; background:url(img/buttons.gif) -29px -16px} +.clearlooks2 .mceFocus .mceMax {right:37px; background:url(img/buttons.gif) -58px -16px} +.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px} +.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px} +.clearlooks2 .mceFocus .mceMin:hover {right:68px; background:url(img/buttons.gif) 0 -32px} +.clearlooks2 .mceFocus .mceMed:hover {right:37px; background:url(img/buttons.gif) -29px -32px} +.clearlooks2 .mceFocus .mceMax:hover {right:37px; background:url(img/buttons.gif) -58px -32px} + +/* Resize */ +.clearlooks2 .mceResize {top:auto; left:auto; display:none; width:5px; height:5px; background:url(img/horizontal.gif) no-repeat 0 -75px} +.clearlooks2 .mceResizable .mceResize {display:block} +.clearlooks2 .mceResizable .mceMin, .clearlooks2 .mceMax {display:none} +.clearlooks2 .mceMinimizable .mceMin {display:block} +.clearlooks2 .mceMaximizable .mceMax {display:block} +.clearlooks2 .mceMaximized .mceMed {display:block} +.clearlooks2 .mceMaximized .mceMax {display:none} +.clearlooks2 a.mceResizeN {top:0; left:0; width:100%; cursor:n-resize} +.clearlooks2 a.mceResizeNW {top:0; left:0; cursor:nw-resize} +.clearlooks2 a.mceResizeNE {top:0; right:0; cursor:ne-resize} +.clearlooks2 a.mceResizeW {top:0; left:0; height:100%; cursor:w-resize} +.clearlooks2 a.mceResizeE {top:0; right:0; height:100%; cursor:e-resize} +.clearlooks2 a.mceResizeS {bottom:0; left:0; width:100%; cursor:s-resize} +.clearlooks2 a.mceResizeSW {bottom:0; left:0; cursor:sw-resize} +.clearlooks2 a.mceResizeSE {bottom:0; right:0; cursor:se-resize} + +/* Alert/Confirm */ +.clearlooks2 .mceButton {font-weight:bold; bottom:10px; width:80px; height:30px; background:url(img/button.gif); line-height:30px; vertical-align:middle; text-align:center; outline:0} +.clearlooks2 .mceMiddle .mceIcon {left:15px; top:35px; width:32px; height:32px} +.clearlooks2 .mceAlert .mceMiddle span, .clearlooks2 .mceConfirm .mceMiddle span {background:transparent;left:60px; top:35px; width:320px; height:50px; font-weight:bold; overflow:auto; white-space:normal} +.clearlooks2 a:hover {font-weight:bold;} +.clearlooks2 .mceAlert .mceMiddle, .clearlooks2 .mceConfirm .mceMiddle {background:#E4F2FD} +.clearlooks2 .mceAlert .mceOk {left:50%; top:auto; margin-left: -40px} +.clearlooks2 .mceAlert .mceIcon {background:url(img/alert.gif)} +.clearlooks2 .mceConfirm .mceOk {left:50%; top:auto; margin-left: -90px} +.clearlooks2 .mceConfirm .mceCancel {left:50%; top:auto} +.clearlooks2 .mceConfirm .mceIcon {background:url(img/confirm.gif)} + +/* IE9 fixes */ +.clearlooks2.ie9 .mceTop .mceCenter {clip:auto;} +.clearlooks2.ie9 .mceMiddle {clip:auto;} +.clearlooks2.ie9 .mceMiddle .mceLeft, .clearlooks2.ie9 .mceMiddle .mceRight {top: 23px;} +.clearlooks2.ie9 .mceAlert .mceMiddle span, .clearlooks2.ie9 .mceConfirm .mceMiddle span {top:13px;} +.clearlooks2.ie9 .mceModal .mceMiddle {top:23px} +.clearlooks2.ie9 .mceModal .mceMiddle .mceLeft, .clearlooks2.ie9 .mceModal .mceMiddle .mceRight {top: 0} +.clearlooks2.ie9 .mceMiddle .mceIcon {top:13px} +.clearlooks2.ie9 .mceTop .mceCenter {top:0; right:auto; left:6px; width:calc(100%-12px)} diff --git a/src/wp-includes/js/tinymce/plugins/inlinepopups/template.htm b/src/wp-includes/js/tinymce/plugins/inlinepopups/template.htm new file mode 100644 index 00000000..bcad9df6 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/inlinepopups/template.htm @@ -0,0 +1,387 @@ + + + +Template for dialogs + + + + +
    +
    +
    +
    +
    +
    +
    + Blured +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Focused +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Statusbar +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Statusbar, Resizable +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Resizable, Maximizable +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Blurred, Maximizable, Statusbar, Resizable +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Maximized, Maximizable, Minimizable +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Blured +
    + +
    +
    + Content +
    +
    + +
    +
    +
    +
    + Statusbar text. +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    + Alert +
    + +
    +
    + + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + +
    +
    +
    + +
    +
    +
    +
    +
    + + + Ok + +
    +
    + +
    +
    +
    +
    +
    +
    + Confirm +
    + +
    +
    + + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + +
    +
    +
    + +
    +
    +
    +
    +
    + + + Ok + Cancel + +
    +
    +
    + + + diff --git a/src/wp-includes/js/tinymce/plugins/paste/blank.htm b/src/wp-includes/js/tinymce/plugins/paste/blank.htm new file mode 100644 index 00000000..4382a11c --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/paste/blank.htm @@ -0,0 +1,21 @@ + + +blank_page + + + + + + + + diff --git a/src/wp-includes/js/tinymce/plugins/paste/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/paste/editor_plugin.js new file mode 100644 index 00000000..55205957 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/paste/editor_plugin.js @@ -0,0 +1 @@ +(function(){var c=tinymce.each,d=null,a={paste_auto_cleanup_on_paste:true,paste_block_drop:false,paste_retain_style_properties:"none",paste_strip_class_attributes:"mso",paste_remove_spans:false,paste_remove_styles:false,paste_remove_styles_if_webkit:true,paste_convert_middot_lists:true,paste_convert_headers_to_strong:false,paste_dialog_width:"450",paste_dialog_height:"400",paste_text_use_dialog:false,paste_text_sticky:false,paste_text_notifyalways:false,paste_text_linebreaktype:"p",paste_text_replacements:[[/\u2026/g,"..."],[/[\x93\x94\u201c\u201d]/g,'"'],[/[\x60\x91\x92\u2018\u2019]/g,"'"]]};function b(e,f){return e.getParam(f,a[f])}tinymce.create("tinymce.plugins.PastePlugin",{init:function(e,f){var g=this;g.editor=e;g.url=f;g.onPreProcess=new tinymce.util.Dispatcher(g);g.onPostProcess=new tinymce.util.Dispatcher(g);g.onPreProcess.add(g._preProcess);g.onPostProcess.add(g._postProcess);g.onPreProcess.add(function(j,k){e.execCallback("paste_preprocess",j,k)});g.onPostProcess.add(function(j,k){e.execCallback("paste_postprocess",j,k)});e.pasteAsPlainText=false;function i(l,j){var k=e.dom;g.onPreProcess.dispatch(g,l);l.node=k.create("div",0,l.content);g.onPostProcess.dispatch(g,l);l.content=e.serializer.serialize(l.node,{getInner:1});if((!j)&&(e.pasteAsPlainText)){g._insertPlainText(e,k,l.content);if(!b(e,"paste_text_sticky")){e.pasteAsPlainText=false;e.controlManager.setActive("pastetext",false)}}else{if(/<(p|h[1-6]|ul|ol)/.test(l.content)){g._insertBlockContent(e,k,l.content)}else{g._insert(l.content)}}}e.addCommand("mceInsertClipboardContent",function(j,k){i(k,true)});if(!b(e,"paste_text_use_dialog")){e.addCommand("mcePasteText",function(k,j){var l=tinymce.util.Cookie;e.pasteAsPlainText=!e.pasteAsPlainText;e.controlManager.setActive("pastetext",e.pasteAsPlainText);if((e.pasteAsPlainText)&&(!l.get("tinymcePasteText"))){if(b(e,"paste_text_sticky")){e.windowManager.alert(e.translate("paste.plaintext_mode_sticky"))}else{e.windowManager.alert(e.translate("paste.plaintext_mode_sticky"))}if(!b(e,"paste_text_notifyalways")){l.set("tinymcePasteText","1",new Date(new Date().getFullYear()+1,12,31))}}})}e.addButton("pastetext",{title:"paste.paste_text_desc",cmd:"mcePasteText"});e.addButton("selectall",{title:"paste.selectall_desc",cmd:"selectall"});function h(s){var m,q,k,l=e.selection,p=e.dom,r=e.getBody(),j;if(e.pasteAsPlainText&&(s.clipboardData||p.doc.dataTransfer)){s.preventDefault();i({content:(s.clipboardData||p.doc.dataTransfer).getData("Text").replace(/\r?\n/g,'
    ')});return}if(p.get("_mcePaste")){return}m=p.add(r,"div",{id:"_mcePaste","class":"mcePaste"},'\uFEFF
    ');if(r!=e.getDoc().body){j=p.getPos(e.selection.getStart(),r).y}else{j=r.scrollTop}p.setStyles(m,{position:"absolute",left:-10000,top:j,width:1,height:1,overflow:"hidden"});if(tinymce.isIE){k=p.doc.body.createTextRange();k.moveToElementText(m);k.execCommand("Paste");p.remove(m);if(m.innerHTML==="\uFEFF"){e.execCommand("mcePasteWord");s.preventDefault();return}i({content:m.innerHTML});return tinymce.dom.Event.cancel(s)}else{function o(n){n.preventDefault()}p.bind(e.getDoc(),"mousedown",o);p.bind(e.getDoc(),"keydown",o);q=e.selection.getRng();m=m.firstChild;k=e.getDoc().createRange();k.setStart(m,0);k.setEnd(m,1);l.setRng(k);window.setTimeout(function(){var t="",n=p.select("div.mcePaste");c(n,function(v){var u=v.firstChild;if(u&&u.nodeName=="DIV"&&u.style.marginTop&&u.style.backgroundColor){p.remove(u,1)}c(p.select("div.mcePaste",v),function(w){p.remove(w,1)});c(p.select("span.Apple-style-span",v),function(w){p.remove(w,1)});c(p.select("br[_mce_bogus]",v),function(w){p.remove(w)});t+=v.innerHTML});c(n,function(u){p.remove(u)});if(q){l.setRng(q)}i({content:t});p.unbind(e.getDoc(),"mousedown",o);p.unbind(e.getDoc(),"keydown",o)},0)}}if(b(e,"paste_auto_cleanup_on_paste")){if(tinymce.isOpera||/Firefox\/2/.test(navigator.userAgent)){e.onKeyDown.add(function(j,k){if(((tinymce.isMac?k.metaKey:k.ctrlKey)&&k.keyCode==86)||(k.shiftKey&&k.keyCode==45)){h(k)}})}else{e.onPaste.addToTop(function(j,k){return h(k)})}}if(b(e,"paste_block_drop")){e.onInit.add(function(){e.dom.bind(e.getBody(),["dragend","dragover","draggesture","dragdrop","drop","drag"],function(j){j.preventDefault();j.stopPropagation();return false})})}g._legacySupport()},getInfo:function(){return{longname:"Paste text/word",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_preProcess:function(i,f){var l=this.editor,k=f.content,q=tinymce.grep,p=tinymce.explode,g=tinymce.trim,m,j;function e(h){c(h,function(o){if(o.constructor==RegExp){k=k.replace(o,"")}else{k=k.replace(o[0],o[1])}})}if(/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(k)||f.wordContent){f.wordContent=true;e([/^\s*( )+/gi,/( |]*>)+\s*$/gi]);if(b(l,"paste_convert_headers_to_strong")){k=k.replace(/

    ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"

    $1

    ")}if(b(l,"paste_convert_middot_lists")){e([[//gi,"$&__MCE_ITEM__"],[/(]+(?:mso-list:|:\s*symbol)[^>]+>)/gi,"$1__MCE_ITEM__"]])}e([//gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\u00a0"]]);do{m=k.length;k=k.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi,"$1")}while(m!=k.length);if(b(l,"paste_retain_style_properties").replace(/^none$/i,"").length==0){k=k.replace(/<\/?span[^>]*>/gi,"")}else{e([[/([\s\u00a0]*)<\/span>/gi,function(o,h){return(h.length>0)?h.replace(/./," ").slice(Math.floor(h.length/2)).split("").join("\u00a0"):""}],[/(<[a-z][^>]*)\sstyle="([^"]*)"/gi,function(u,h,t){var v=[],o=0,r=p(g(t).replace(/"/gi,"'"),";");c(r,function(s){var w,y,z=p(s,":");function x(A){return A+((A!=="0")&&(/\d$/.test(A)))?"px":""}if(z.length==2){w=z[0].toLowerCase();y=z[1].toLowerCase();switch(w){case"mso-padding-alt":case"mso-padding-top-alt":case"mso-padding-right-alt":case"mso-padding-bottom-alt":case"mso-padding-left-alt":case"mso-margin-alt":case"mso-margin-top-alt":case"mso-margin-right-alt":case"mso-margin-bottom-alt":case"mso-margin-left-alt":case"mso-table-layout-alt":case"mso-height":case"mso-width":case"mso-vertical-align-alt":v[o++]=w.replace(/^mso-|-alt$/g,"")+":"+x(y);return;case"horiz-align":v[o++]="text-align:"+y;return;case"vert-align":v[o++]="vertical-align:"+y;return;case"font-color":case"mso-foreground":v[o++]="color:"+y;return;case"mso-background":case"mso-highlight":v[o++]="background:"+y;return;case"mso-default-height":v[o++]="min-height:"+x(y);return;case"mso-default-width":v[o++]="min-width:"+x(y);return;case"mso-padding-between-alt":v[o++]="border-collapse:separate;border-spacing:"+x(y);return;case"text-line-through":if((y=="single")||(y=="double")){v[o++]="text-decoration:line-through"}return;case"mso-zero-height":if(y=="yes"){v[o++]="display:none"}return}if(/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(w)){return}v[o++]=w+":"+z[1]}});if(o>0){return h+' style="'+v.join(";")+'"'}else{return h}}]])}}if(b(l,"paste_convert_headers_to_strong")){e([[/]*>/gi,"

    "],[/<\/h[1-6][^>]*>/gi,"

    "]])}j=b(l,"paste_strip_class_attributes");if(j!=="none"){function n(r,o){if(j==="all"){return""}var h=q(p(o.replace(/^(["'])(.*)\1$/,"$2")," "),function(s){return(/^(?!mso)/i.test(s))});return h.length?' class="'+h.join(" ")+'"':""}k=k.replace(/ class="([^"]+)"/gi,n);k=k.replace(/ class=(\w+)/gi,n)}if(b(l,"paste_remove_spans")){k=k.replace(/<\/?span[^>]*>/gi,"")}f.content=k},_postProcess:function(h,j){var g=this,f=g.editor,i=f.dom,e;if(j.wordContent){c(i.select("a",j.node),function(k){if(!k.href||k.href.indexOf("#_Toc")!=-1){i.remove(k,1)}});if(b(f,"paste_convert_middot_lists")){g._convertLists(h,j)}e=b(f,"paste_retain_style_properties");if((tinymce.is(e,"string"))&&(e!=="all")&&(e!=="*")){e=tinymce.explode(e.replace(/^none$/i,""));c(i.select("*",j.node),function(n){var o={},l=0,m,p,k;if(e){for(m=0;m0){i.setStyles(n,o)}else{if(n.nodeName=="SPAN"&&!n.className){i.remove(n,true)}}})}}if(b(f,"paste_remove_styles")||(b(f,"paste_remove_styles_if_webkit")&&tinymce.isWebKit)){c(i.select("*[style]",j.node),function(k){k.removeAttribute("style");k.removeAttribute("_mce_style")})}else{if(tinymce.isWebKit){c(i.select("*",j.node),function(k){k.removeAttribute("_mce_style")})}}},_convertLists:function(h,f){var j=h.editor.dom,i,m,e=-1,g,n=[],l,k;c(j.select("p",f.node),function(u){var r,v="",t,s,o,q;for(r=u.firstChild;r&&r.nodeType==3;r=r.nextSibling){v+=r.nodeValue}v=u.innerHTML.replace(/<\/?\w+[^>]*>/gi,"").replace(/ /g,"\u00a0");if(/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(v)){t="ul"}if(/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(v)){t="ol"}if(t){g=parseFloat(u.style.marginLeft||0);if(g>e){n.push(g)}if(!i||t!=l){i=j.create(t);j.insertAfter(i,u)}else{if(g>e){i=m.appendChild(j.create(t))}else{if(g]*>/gi,"");if(t=="ul"&&/^[\u2022\u00b7\u00a7\u00d8o]/.test(p)){j.remove(w)}else{if(/^[\s\S]*\w+\.( |\u00a0)*\s*/.test(p)){j.remove(w)}}});s=u.innerHTML;if(t=="ul"){s=u.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*( |\u00a0)+\s*/,"")}else{s=u.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^\s*\w+\.( |\u00a0)+\s*/,"")}m=i.appendChild(j.create("li",0,s));j.remove(u);e=g;l=t}else{i=e=0}});k=f.node.innerHTML;if(k.indexOf("__MCE_ITEM__")!=-1){f.node.innerHTML=k.replace(/__MCE_ITEM__/g,"")}},_insertBlockContent:function(l,h,m){var f,j,g=l.selection,q,n,e,o,i,k="mce_marker";function p(t){var s;if(tinymce.isIE){s=l.getDoc().body.createTextRange();s.moveToElementText(t);s.collapse(false);s.select()}else{g.select(t,1);g.collapse(false)}}this._insert('',1);j=h.get(k);f=h.getParent(j,"p,h1,h2,h3,h4,h5,h6,ul,ol,th,td");if(f&&!/TD|TH/.test(f.nodeName)){j=h.split(f,j);c(h.create("div",0,m).childNodes,function(r){q=j.parentNode.insertBefore(r.cloneNode(true),j)});p(q)}else{h.setOuterHTML(j,m);g.select(l.getBody(),1);g.collapse(0)}while(n=h.get(k)){h.remove(n)}n=g.getStart();e=h.getViewPort(l.getWin());o=l.dom.getPos(n).y;i=n.clientHeight;if(oe.y+e.h){l.getDoc().body.scrollTop=o0)){if(!d){d=("34,quot,38,amp,39,apos,60,lt,62,gt,"+j.serializer.settings.entities).split(",")}if(/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(v)){q([/[\n\r]+/g])}else{q([/\r+/g])}q([[/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi,"\n\n"],[/]*>|<\/tr>/gi,"\n"],[/<\/t[dh]>\s*]*>/gi,"\t"],/<[a-z!\/?][^>]*>/gi,[/ /gi," "],[/&(#\d+|[a-z0-9]{1,10});/gi,function(i,h){if(h.charAt(0)==="#"){return String.fromCharCode(h.slice(1))}else{return((i=y(d,h))>0)?String.fromCharCode(d[i-1]):" "}}],[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi,"$1"],[/\n{3,}/g,"\n\n"],/^\s+|\s+$/g]);v=x.encode(v);if(!s.isCollapsed()){z.execCommand("Delete",false,null)}if(m(o,"array")||(m(o,"array"))){q(o)}else{if(m(o,"string")){q(new RegExp(o,"gi"))}}if(g=="none"){q([[/\n+/g," "]])}else{if(g=="br"){q([[/\n/g,"
    "]])}else{q([/^\s+|\s+$/g,[/\n\n/g,"

    "],[/\n/g,"
    "]])}}if((l=v.indexOf("

    "))!=-1){k=v.lastIndexOf("

    ");r=s.getNode();e=[];do{if(r.nodeType==1){if(r.nodeName=="TD"||r.nodeName=="BODY"){break}e[e.length]=r}}while(r=r.parentNode);if(e.length>0){p=v.substring(0,l);f="";for(t=0,u=e.length;t";f+="<"+e[e.length-t-1].nodeName.toLowerCase()+">"}if(l==k){v=p+f+v.substring(l+7)}else{v=p+v.substring(l+4,k+4)+f+v.substring(k+7)}}}j.execCommand("mceInsertRawHTML",false,v+' ');window.setTimeout(function(){var h=x.get("_plain_text_marker"),B,i,A,w;s.select(h,false);z.execCommand("Delete",false,null);h=null;B=s.getStart();i=x.getViewPort(n);A=x.getPos(B).y;w=B.clientHeight;if((Ai.y+i.h)){z.body.scrollTop=A 1) { + h = ''; + tinymce.each(lines, function(row) { + h += '

    ' + row + '

    '; + }); + } + } + + tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h}); + tinyMCEPopup.close(); + }, + + resize : function() { + var vp = tinyMCEPopup.dom.getViewPort(window), el; + + el = document.getElementById('content'); + + el.style.width = (vp.w - 20) + 'px'; + el.style.height = (vp.h - 90) + 'px'; + } +}; + +tinyMCEPopup.onInit.add(PasteTextDialog.init, PasteTextDialog); diff --git a/src/wp-includes/js/tinymce/plugins/paste/js/pasteword.js b/src/wp-includes/js/tinymce/plugins/paste/js/pasteword.js new file mode 100644 index 00000000..959bf399 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/paste/js/pasteword.js @@ -0,0 +1,51 @@ +tinyMCEPopup.requireLangPack(); + +var PasteWordDialog = { + init : function() { + var ed = tinyMCEPopup.editor, el = document.getElementById('iframecontainer'), ifr, doc, css, cssHTML = ''; + + // Create iframe + el.innerHTML = ''; + ifr = document.getElementById('iframe'); + doc = ifr.contentWindow.document; + + // Force absolute CSS urls + css = [ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css")]; + css = css.concat(tinymce.explode(ed.settings.content_css) || []); + tinymce.each(css, function(u) { + cssHTML += ''; + }); + + // Write content into iframe + doc.open(); + doc.write('' + cssHTML + ''); + doc.close(); + + doc.designMode = 'on'; + this.resize(); + + window.setTimeout(function() { + ifr.contentWindow.focus(); + }, 10); + }, + + insert : function() { + var h = document.getElementById('iframe').contentWindow.document.body.innerHTML; + + tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h, wordContent : true}); + tinyMCEPopup.close(); + }, + + resize : function() { + var vp = tinyMCEPopup.dom.getViewPort(window), el; + + el = document.getElementById('iframe'); + + if (el) { + el.style.width = (vp.w - 20) + 'px'; + el.style.height = (vp.h - 90) + 'px'; + } + } +}; + +tinyMCEPopup.onInit.add(PasteWordDialog.init, PasteWordDialog); diff --git a/src/wp-includes/js/tinymce/plugins/paste/pastetext.htm b/src/wp-includes/js/tinymce/plugins/paste/pastetext.htm new file mode 100644 index 00000000..462e6efc --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/paste/pastetext.htm @@ -0,0 +1,32 @@ + + + {#paste.paste_text_desc} + + + + +
    +
    {#paste.paste_text_desc}
    + +
    + +
    + +
    + +
    {#paste_dlg.text_title}
    + + + +
    +
    + +
    + +
    + +
    +
    +
    + + \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/paste/pasteword.htm b/src/wp-includes/js/tinymce/plugins/paste/pasteword.htm new file mode 100644 index 00000000..7b42d8ca --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/paste/pasteword.htm @@ -0,0 +1,26 @@ + + + {#paste.paste_word_desc} + + + + +
    +
    {#paste.paste_word_desc}
    + +
    {#paste_dlg.word_title}
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    + + diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/classes/EnchantSpell.php b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/EnchantSpell.php new file mode 100644 index 00000000..59133c6c --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/EnchantSpell.php @@ -0,0 +1,67 @@ += 1.4.1 + * @param Array $words Array of words to check. + * @return Array of misspelled words. + */ + function &checkWords($lang, $words) { + $r = enchant_broker_init(); + + if (enchant_broker_dict_exists($r,$lang)) { + $d = enchant_broker_request_dict($r, $lang); + + $returnData = array(); + foreach($words as $key => $value) { + $correct = enchant_dict_check($d, $value); + if(!$correct) { + $returnData[] = trim($value); + } + } + + return $returnData; + enchant_broker_free_dict($d); + } else { + + } + enchant_broker_free($r); + } + + /** + * Returns suggestions for a specific word. + * + * @param String $lang Selected language code (like en_US or de_DE). Shortcodes like "en" and "de" work with enchant >= 1.4.1 + * @param String $word Specific word to get suggestions for. + * @return Array of suggestions for the specified word. + */ + function &getSuggestions($lang, $word) { + $r = enchant_broker_init(); + $suggs = array(); + + if (enchant_broker_dict_exists($r,$lang)) { + $d = enchant_broker_request_dict($r, $lang); + $suggs = enchant_dict_suggest($d, $word); + + enchant_broker_free_dict($d); + } else { + + } + enchant_broker_free($r); + + return $suggs; + } +} + +?> \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/classes/GoogleSpell.php b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/GoogleSpell.php new file mode 100644 index 00000000..446b96ac --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/GoogleSpell.php @@ -0,0 +1,159 @@ +_getMatches($lang, $wordstr); + $words = array(); + + for ($i=0; $i_unhtmlentities(mb_substr($wordstr, $matches[$i][1], $matches[$i][2], "UTF-8")); + + return $words; + } + + /** + * Returns suggestions of for a specific word. + * + * @param {String} $lang Language code like sv or en. + * @param {String} $word Specific word to get suggestions for. + * @return {Array} Array of suggestions for the specified word. + */ + function &getSuggestions($lang, $word) { + $sug = array(); + $osug = array(); + $matches = $this->_getMatches($lang, $word); + + if (count($matches) > 0) + $sug = explode("\t", utf8_encode($this->_unhtmlentities($matches[0][4]))); + + // Remove empty + foreach ($sug as $item) { + if ($item) + $osug[] = $item; + } + + return $osug; + } + + function &_getMatches($lang, $str) { + $server = "www.google.com"; + $port = 443; + $path = "/tbproxy/spell?lang=" . $lang . "&hl=en"; + $host = "www.google.com"; + $url = "https://" . $server; + + // Setup XML request + $xml = '' . $str . ''; + + $header = "POST ".$path." HTTP/1.0 \r\n"; + $header .= "MIME-Version: 1.0 \r\n"; + $header .= "Content-type: application/PTI26 \r\n"; + $header .= "Content-length: ".strlen($xml)." \r\n"; + $header .= "Content-transfer-encoding: text \r\n"; + $header .= "Request-number: 1 \r\n"; + $header .= "Document-type: Request \r\n"; + $header .= "Interface-Version: Test 1.4 \r\n"; + $header .= "Connection: close \r\n\r\n"; + $header .= $xml; + + // Use curl if it exists + if (function_exists('curl_init')) { + // Use curl + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL,$url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + $xml = curl_exec($ch); + curl_close($ch); + } else { + // Use raw sockets + $fp = fsockopen("ssl://" . $server, $port, $errno, $errstr, 30); + if ($fp) { + // Send request + fwrite($fp, $header); + + // Read response + $xml = ""; + while (!feof($fp)) + $xml .= fgets($fp, 128); + + fclose($fp); + } else + echo "Could not open SSL connection to google."; + } + + // Grab and parse content + $matches = array(); + preg_match_all('/([^<]*)<\/c>/', $xml, $matches, PREG_SET_ORDER); + + return $matches; + } + + function _unhtmlentities($string) { + $string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string); + $string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string); + + $trans_tbl = get_html_translation_table(HTML_ENTITIES); + $trans_tbl = array_flip($trans_tbl); + + return strtr($string, $trans_tbl); + } +} + +// Patch in multibyte support +if (!function_exists('mb_substr')) { + function mb_substr($str, $start, $len = '', $encoding="UTF-8"){ + $limit = strlen($str); + + for ($s = 0; $start > 0;--$start) {// found the real start + if ($s >= $limit) + break; + + if ($str[$s] <= "\x7F") + ++$s; + else { + ++$s; // skip length + + while ($str[$s] >= "\x80" && $str[$s] <= "\xBF") + ++$s; + } + } + + if ($len == '') + return substr($str, $s); + else + for ($e = $s; $len > 0; --$len) {//found the real end + if ($e >= $limit) + break; + + if ($str[$e] <= "\x7F") + ++$e; + else { + ++$e;//skip length + + while ($str[$e] >= "\x80" && $str[$e] <= "\xBF" && $e < $limit) + ++$e; + } + } + + return substr($str, $s, $e - $s); + } +} + +?> \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/classes/PSpell.php b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/PSpell.php new file mode 100644 index 00000000..3c6424d8 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/PSpell.php @@ -0,0 +1,82 @@ +_getPLink($lang); + + $outWords = array(); + foreach ($words as $word) { + if (!pspell_check($plink, trim($word))) + $outWords[] = utf8_encode($word); + } + + return $outWords; + } + + /** + * Returns suggestions of for a specific word. + * + * @param {String} $lang Language code like sv or en. + * @param {String} $word Specific word to get suggestions for. + * @return {Array} Array of suggestions for the specified word. + */ + function &getSuggestions($lang, $word) { + $words = pspell_suggest($this->_getPLink($lang), $word); + + for ($i=0; $ithrowError("PSpell support not found in PHP installation."); + + // Setup PSpell link + $plink = pspell_new( + $lang, + $this->_config['PSpell.spelling'], + $this->_config['PSpell.jargon'], + $this->_config['PSpell.encoding'], + $this->_config['PSpell.mode'] + ); + + // Setup PSpell link +/* if (!$plink) { + $pspellConfig = pspell_config_create( + $lang, + $this->_config['PSpell.spelling'], + $this->_config['PSpell.jargon'], + $this->_config['PSpell.encoding'] + ); + + $plink = pspell_new_config($pspell_config); + }*/ + + if (!$plink) + $this->throwError("No PSpell link found opened."); + + return $plink; + } +} + +?> diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/classes/PSpellShell.php b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/PSpellShell.php new file mode 100644 index 00000000..7d3102c7 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/PSpellShell.php @@ -0,0 +1,113 @@ +_getCMD($lang); + + if ($fh = fopen($this->_tmpfile, "w")) { + fwrite($fh, "!\n"); + + foreach($words as $key => $value) + fwrite($fh, "^" . $value . "\n"); + + fclose($fh); + } else + $this->throwError("PSpell support was not found."); + + $data = shell_exec($cmd); + @unlink($this->_tmpfile); + + $returnData = array(); + $dataArr = preg_split("/[\r\n]/", $data, -1, PREG_SPLIT_NO_EMPTY); + + foreach ($dataArr as $dstr) { + $matches = array(); + + // Skip this line. + if (strpos($dstr, "@") === 0) + continue; + + preg_match("/\& ([^ ]+) .*/i", $dstr, $matches); + + if (!empty($matches[1])) + $returnData[] = utf8_encode(trim($matches[1])); + } + + return $returnData; + } + + /** + * Returns suggestions of for a specific word. + * + * @param {String} $lang Language code like sv or en. + * @param {String} $word Specific word to get suggestions for. + * @return {Array} Array of suggestions for the specified word. + */ + function &getSuggestions($lang, $word) { + $cmd = $this->_getCMD($lang); + + if (function_exists("mb_convert_encoding")) + $word = mb_convert_encoding($word, "ISO-8859-1", mb_detect_encoding($word, "UTF-8")); + else + $word = utf8_encode($word); + + if ($fh = fopen($this->_tmpfile, "w")) { + fwrite($fh, "!\n"); + fwrite($fh, "^$word\n"); + fclose($fh); + } else + $this->throwError("Error opening tmp file."); + + $data = shell_exec($cmd); + @unlink($this->_tmpfile); + + $returnData = array(); + $dataArr = preg_split("/\n/", $data, -1, PREG_SPLIT_NO_EMPTY); + + foreach($dataArr as $dstr) { + $matches = array(); + + // Skip this line. + if (strpos($dstr, "@") === 0) + continue; + + preg_match("/\&[^:]+:(.*)/i", $dstr, $matches); + + if (!empty($matches[1])) { + $words = array_slice(explode(',', $matches[1]), 0, 10); + + for ($i=0; $i_tmpfile = tempnam($this->_config['PSpellShell.tmp'], "tinyspell"); + + if(preg_match("#win#i", php_uname())) + return $this->_config['PSpellShell.aspell'] . " -a --lang=". escapeshellarg($lang) . " --encoding=utf-8 -H < " . $this->_tmpfile . " 2>&1"; + + return "cat ". $this->_tmpfile ." | " . $this->_config['PSpellShell.aspell'] . " -a --encoding=utf-8 -H --lang=". escapeshellarg($lang); + } +} + +?> \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/classes/SpellChecker.php b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/SpellChecker.php new file mode 100644 index 00000000..5d9205fe --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/SpellChecker.php @@ -0,0 +1,62 @@ +_config = $config; + } + + /** + * Simple loopback function everything that gets in will be send back. + * + * @param $args.. Arguments. + * @return {Array} Array of all input arguments. + */ + function &loopback(/* args.. */) { + return func_get_args(); + } + + /** + * Spellchecks an array of words. + * + * @param {String} $lang Language code like sv or en. + * @param {Array} $words Array of words to spellcheck. + * @return {Array} Array of misspelled words. + */ + function &checkWords($lang, $words) { + return $words; + } + + /** + * Returns suggestions of for a specific word. + * + * @param {String} $lang Language code like sv or en. + * @param {String} $word Specific word to get suggestions for. + * @return {Array} Array of suggestions for the specified word. + */ + function &getSuggestions($lang, $word) { + return array(); + } + + /** + * Throws an error message back to the user. This will stop all execution. + * + * @param {String} $str Message to send back to user. + */ + function throwError($str) { + die('{"result":null,"id":null,"error":{"errstr":"' . addslashes($str) . '","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}'); + } +} + +?> diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/classes/utils/JSON.php b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/utils/JSON.php new file mode 100644 index 00000000..1f2b92ca --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/utils/JSON.php @@ -0,0 +1,595 @@ +_data = $data; + $this->_len = strlen($data); + $this->_pos = -1; + $this->_location = JSON_IN_BETWEEN; + $this->_lastLocations = array(); + $this->_needProp = false; + } + + function getToken() { + return $this->_token; + } + + function getLocation() { + return $this->_location; + } + + function getTokenName() { + switch ($this->_token) { + case JSON_BOOL: + return 'JSON_BOOL'; + + case JSON_INT: + return 'JSON_INT'; + + case JSON_STR: + return 'JSON_STR'; + + case JSON_FLOAT: + return 'JSON_FLOAT'; + + case JSON_NULL: + return 'JSON_NULL'; + + case JSON_START_OBJ: + return 'JSON_START_OBJ'; + + case JSON_END_OBJ: + return 'JSON_END_OBJ'; + + case JSON_START_ARRAY: + return 'JSON_START_ARRAY'; + + case JSON_END_ARRAY: + return 'JSON_END_ARRAY'; + + case JSON_KEY: + return 'JSON_KEY'; + } + + return 'UNKNOWN'; + } + + function getValue() { + return $this->_value; + } + + function readToken() { + $chr = $this->read(); + + if ($chr != null) { + switch ($chr) { + case '[': + $this->_lastLocation[] = $this->_location; + $this->_location = JSON_IN_ARRAY; + $this->_token = JSON_START_ARRAY; + $this->_value = null; + $this->readAway(); + return true; + + case ']': + $this->_location = array_pop($this->_lastLocation); + $this->_token = JSON_END_ARRAY; + $this->_value = null; + $this->readAway(); + + if ($this->_location == JSON_IN_OBJECT) + $this->_needProp = true; + + return true; + + case '{': + $this->_lastLocation[] = $this->_location; + $this->_location = JSON_IN_OBJECT; + $this->_needProp = true; + $this->_token = JSON_START_OBJ; + $this->_value = null; + $this->readAway(); + return true; + + case '}': + $this->_location = array_pop($this->_lastLocation); + $this->_token = JSON_END_OBJ; + $this->_value = null; + $this->readAway(); + + if ($this->_location == JSON_IN_OBJECT) + $this->_needProp = true; + + return true; + + // String + case '"': + case '\'': + return $this->_readString($chr); + + // Null + case 'n': + return $this->_readNull(); + + // Bool + case 't': + case 'f': + return $this->_readBool($chr); + + default: + // Is number + if (is_numeric($chr) || $chr == '-' || $chr == '.') + return $this->_readNumber($chr); + + return true; + } + } + + return false; + } + + function _readBool($chr) { + $this->_token = JSON_BOOL; + $this->_value = $chr == 't'; + + if ($chr == 't') + $this->skip(3); // rue + else + $this->skip(4); // alse + + $this->readAway(); + + if ($this->_location == JSON_IN_OBJECT && !$this->_needProp) + $this->_needProp = true; + + return true; + } + + function _readNull() { + $this->_token = JSON_NULL; + $this->_value = null; + + $this->skip(3); // ull + $this->readAway(); + + if ($this->_location == JSON_IN_OBJECT && !$this->_needProp) + $this->_needProp = true; + + return true; + } + + function _readString($quote) { + $output = ""; + $this->_token = JSON_STR; + $endString = false; + + while (($chr = $this->peek()) != -1) { + switch ($chr) { + case '\\': + // Read away slash + $this->read(); + + // Read escape code + $chr = $this->read(); + switch ($chr) { + case 't': + $output .= "\t"; + break; + + case 'b': + $output .= "\b"; + break; + + case 'f': + $output .= "\f"; + break; + + case 'r': + $output .= "\r"; + break; + + case 'n': + $output .= "\n"; + break; + + case 'u': + $output .= $this->_int2utf8(hexdec($this->read(4))); + break; + + default: + $output .= $chr; + break; + } + + break; + + case '\'': + case '"': + if ($chr == $quote) + $endString = true; + + $chr = $this->read(); + if ($chr != -1 && $chr != $quote) + $output .= $chr; + + break; + + default: + $output .= $this->read(); + } + + // String terminated + if ($endString) + break; + } + + $this->readAway(); + $this->_value = $output; + + // Needed a property + if ($this->_needProp) { + $this->_token = JSON_KEY; + $this->_needProp = false; + return true; + } + + if ($this->_location == JSON_IN_OBJECT && !$this->_needProp) + $this->_needProp = true; + + return true; + } + + function _int2utf8($int) { + $int = intval($int); + + switch ($int) { + case 0: + return chr(0); + + case ($int & 0x7F): + return chr($int); + + case ($int & 0x7FF): + return chr(0xC0 | (($int >> 6) & 0x1F)) . chr(0x80 | ($int & 0x3F)); + + case ($int & 0xFFFF): + return chr(0xE0 | (($int >> 12) & 0x0F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr (0x80 | ($int & 0x3F)); + + case ($int & 0x1FFFFF): + return chr(0xF0 | ($int >> 18)) . chr(0x80 | (($int >> 12) & 0x3F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr(0x80 | ($int & 0x3F)); + } + } + + function _readNumber($start) { + $value = ""; + $isFloat = false; + + $this->_token = JSON_INT; + $value .= $start; + + while (($chr = $this->peek()) != -1) { + if (is_numeric($chr) || $chr == '-' || $chr == '.') { + if ($chr == '.') + $isFloat = true; + + $value .= $this->read(); + } else + break; + } + + $this->readAway(); + + if ($isFloat) { + $this->_token = JSON_FLOAT; + $this->_value = floatval($value); + } else + $this->_value = intval($value); + + if ($this->_location == JSON_IN_OBJECT && !$this->_needProp) + $this->_needProp = true; + + return true; + } + + function readAway() { + while (($chr = $this->peek()) != null) { + if ($chr != ':' && $chr != ',' && $chr != ' ') + return; + + $this->read(); + } + } + + function read($len = 1) { + if ($this->_pos < $this->_len) { + if ($len > 1) { + $str = substr($this->_data, $this->_pos + 1, $len); + $this->_pos += $len; + + return $str; + } else + return $this->_data[++$this->_pos]; + } + + return null; + } + + function skip($len) { + $this->_pos += $len; + } + + function peek() { + if ($this->_pos < $this->_len) + return $this->_data[$this->_pos + 1]; + + return null; + } +} + +/** + * This class handles JSON stuff. + * + * @package MCManager.utils + */ +class Moxiecode_JSON { + function Moxiecode_JSON() { + } + + function decode($input) { + $reader = new Moxiecode_JSONReader($input); + + return $this->readValue($reader); + } + + function readValue(&$reader) { + $this->data = array(); + $this->parents = array(); + $this->cur =& $this->data; + $key = null; + $loc = JSON_IN_ARRAY; + + while ($reader->readToken()) { + switch ($reader->getToken()) { + case JSON_STR: + case JSON_INT: + case JSON_BOOL: + case JSON_FLOAT: + case JSON_NULL: + switch ($reader->getLocation()) { + case JSON_IN_OBJECT: + $this->cur[$key] = $reader->getValue(); + break; + + case JSON_IN_ARRAY: + $this->cur[] = $reader->getValue(); + break; + + default: + return $reader->getValue(); + } + break; + + case JSON_KEY: + $key = $reader->getValue(); + break; + + case JSON_START_OBJ: + case JSON_START_ARRAY: + if ($loc == JSON_IN_OBJECT) + $this->addArray($key); + else + $this->addArray(null); + + $cur =& $obj; + + $loc = $reader->getLocation(); + break; + + case JSON_END_OBJ: + case JSON_END_ARRAY: + $loc = $reader->getLocation(); + + if (count($this->parents) > 0) { + $this->cur =& $this->parents[count($this->parents) - 1]; + array_pop($this->parents); + } + break; + } + } + + return $this->data[0]; + } + + // This method was needed since PHP is crapy and doesn't have pointers/references + function addArray($key) { + $this->parents[] =& $this->cur; + $ar = array(); + + if ($key) + $this->cur[$key] =& $ar; + else + $this->cur[] =& $ar; + + $this->cur =& $ar; + } + + function getDelim($index, &$reader) { + switch ($reader->getLocation()) { + case JSON_IN_ARRAY: + case JSON_IN_OBJECT: + if ($index > 0) + return ","; + break; + } + + return ""; + } + + function encode($input) { + switch (gettype($input)) { + case 'boolean': + return $input ? 'true' : 'false'; + + case 'integer': + return (int) $input; + + case 'float': + case 'double': + return (float) $input; + + case 'NULL': + return 'null'; + + case 'string': + return $this->encodeString($input); + + case 'array': + return $this->_encodeArray($input); + + case 'object': + return $this->_encodeArray(get_object_vars($input)); + } + + return ''; + } + + function encodeString($input) { + // Needs to be escaped + if (preg_match('/[^a-zA-Z0-9]/', $input)) { + $output = ''; + + for ($i=0; $i_utf82utf16($char))); + } if (($byte & 0xF0) == 0xE0) { + $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2])); + $i += 2; + $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char))); + } if (($byte & 0xF8) == 0xF0) { + $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3])); + $i += 3; + $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char))); + } if (($byte & 0xFC) == 0xF8) { + $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4])); + $i += 4; + $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char))); + } if (($byte & 0xFE) == 0xFC) { + $char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4]), ord($input[$i + 5])); + $i += 5; + $output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char))); + } else if ($byte < 128) + $output .= $input[$i]; + } + } + + return '"' . $output . '"'; + } + + return '"' . $input . '"'; + } + + function _utf82utf16($utf8) { + if (function_exists('mb_convert_encoding')) + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + + switch (strlen($utf8)) { + case 1: + return $utf8; + + case 2: + return chr(0x07 & (ord($utf8[0]) >> 2)) . chr((0xC0 & (ord($utf8[0]) << 6)) | (0x3F & ord($utf8[1]))); + + case 3: + return chr((0xF0 & (ord($utf8[0]) << 4)) | (0x0F & (ord($utf8[1]) >> 2))) . chr((0xC0 & (ord($utf8[1]) << 6)) | (0x7F & ord($utf8[2]))); + } + + return ''; + } + + function _encodeArray($input) { + $output = ''; + $isIndexed = true; + + $keys = array_keys($input); + for ($i=0; $iencodeString($keys[$i]) . ':' . $this->encode($input[$keys[$i]]); + $isIndexed = false; + } else + $output .= $this->encode($input[$keys[$i]]); + + if ($i != count($keys) - 1) + $output .= ','; + } + + return $isIndexed ? '[' . $output . ']' : '{' . $output . '}'; + } +} + +?> diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/classes/utils/Logger.php b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/utils/Logger.php new file mode 100644 index 00000000..a1fb4cd0 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/classes/utils/Logger.php @@ -0,0 +1,268 @@ +_path = ""; + $this->_filename = "{level}.log"; + $this->setMaxSize("100k"); + $this->_maxFiles = 10; + $this->_level = MC_LOGGER_DEBUG; + $this->_format = "[{time}] [{level}] {message}"; + } + + /** + * Sets the current log level, use the MC_LOGGER constants. + * + * @param int $level Log level instance for example MC_LOGGER_DEBUG. + */ + function setLevel($level) { + if (is_string($level)) { + switch (strtolower($level)) { + case "debug": + $level = MC_LOGGER_DEBUG; + break; + + case "info": + $level = MC_LOGGER_INFO; + break; + + case "warn": + case "warning": + $level = MC_LOGGER_WARN; + break; + + case "error": + $level = MC_LOGGER_ERROR; + break; + + case "fatal": + $level = MC_LOGGER_FATAL; + break; + + default: + $level = MC_LOGGER_FATAL; + } + } + + $this->_level = $level; + } + + /** + * Returns the current log level for example MC_LOGGER_DEBUG. + * + * @return int Current log level for example MC_LOGGER_DEBUG. + */ + function getLevel() { + return $this->_level; + } + + function setPath($path) { + $this->_path = $path; + } + + function getPath() { + return $this->_path; + } + + function setFileName($file_name) { + $this->_filename = $file_name; + } + + function getFileName() { + return $this->_filename; + } + + function setFormat($format) { + $this->_format = $format; + } + + function getFormat() { + return $this->_format; + } + + function setMaxSize($size) { + // Fix log max size + $logMaxSizeBytes = intval(preg_replace("/[^0-9]/", "", $size)); + + // Is KB + if (strpos((strtolower($size)), "k") > 0) + $logMaxSizeBytes *= 1024; + + // Is MB + if (strpos((strtolower($size)), "m") > 0) + $logMaxSizeBytes *= (1024 * 1024); + + $this->_maxSizeBytes = $logMaxSizeBytes; + $this->_maxSize = $size; + } + + function getMaxSize() { + return $this->_maxSize; + } + + function setMaxFiles($max_files) { + $this->_maxFiles = $max_files; + } + + function getMaxFiles() { + return $this->_maxFiles; + } + + function debug($msg) { + $args = func_get_args(); + $this->_logMsg(MC_LOGGER_DEBUG, implode(', ', $args)); + } + + function info($msg) { + $args = func_get_args(); + $this->_logMsg(MC_LOGGER_INFO, implode(', ', $args)); + } + + function warn($msg) { + $args = func_get_args(); + $this->_logMsg(MC_LOGGER_WARN, implode(', ', $args)); + } + + function error($msg) { + $args = func_get_args(); + $this->_logMsg(MC_LOGGER_ERROR, implode(', ', $args)); + } + + function fatal($msg) { + $args = func_get_args(); + $this->_logMsg(MC_LOGGER_FATAL, implode(', ', $args)); + } + + function isDebugEnabled() { + return $this->_level >= MC_LOGGER_DEBUG; + } + + function isInfoEnabled() { + return $this->_level >= MC_LOGGER_INFO; + } + + function isWarnEnabled() { + return $this->_level >= MC_LOGGER_WARN; + } + + function isErrorEnabled() { + return $this->_level >= MC_LOGGER_ERROR; + } + + function isFatalEnabled() { + return $this->_level >= MC_LOGGER_FATAL; + } + + function _logMsg($level, $message) { + $roll = false; + + if ($level < $this->_level) + return; + + $logFile = $this->toOSPath($this->_path . "/" . $this->_filename); + + switch ($level) { + case MC_LOGGER_DEBUG: + $levelName = "DEBUG"; + break; + + case MC_LOGGER_INFO: + $levelName = "INFO"; + break; + + case MC_LOGGER_WARN: + $levelName = "WARN"; + break; + + case MC_LOGGER_ERROR: + $levelName = "ERROR"; + break; + + case MC_LOGGER_FATAL: + $levelName = "FATAL"; + break; + } + + $logFile = str_replace('{level}', strtolower($levelName), $logFile); + + $text = $this->_format; + $text = str_replace('{time}', date("Y-m-d H:i:s"), $text); + $text = str_replace('{level}', strtolower($levelName), $text); + $text = str_replace('{message}', $message, $text); + $message = $text . "\r\n"; + + // Check filesize + if (file_exists($logFile)) { + $size = @filesize($logFile); + + if ($size + strlen($message) > $this->_maxSizeBytes) + $roll = true; + } + + // Roll if the size is right + if ($roll) { + for ($i=$this->_maxFiles-1; $i>=1; $i--) { + $rfile = $this->toOSPath($logFile . "." . $i); + $nfile = $this->toOSPath($logFile . "." . ($i+1)); + + if (@file_exists($rfile)) + @rename($rfile, $nfile); + } + + @rename($logFile, $this->toOSPath($logFile . ".1")); + + // Delete last logfile + $delfile = $this->toOSPath($logFile . "." . ($this->_maxFiles + 1)); + if (@file_exists($delfile)) + @unlink($delfile); + } + + // Append log line + if (($fp = @fopen($logFile, "a")) != null) { + @fputs($fp, $message); + @fflush($fp); + @fclose($fp); + } + } + + /** + * Converts a Unix path to OS specific path. + * + * @param String $path Unix path to convert. + */ + function toOSPath($path) { + return str_replace("/", DIRECTORY_SEPARATOR, $path); + } +} + +?> \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/config.php b/src/wp-includes/js/tinymce/plugins/spellchecker/config.php new file mode 100644 index 00000000..795495a6 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/config.php @@ -0,0 +1,27 @@ + diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/css/content.css b/src/wp-includes/js/tinymce/plugins/spellchecker/css/content.css new file mode 100644 index 00000000..656ce1ee --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/css/content.css @@ -0,0 +1 @@ +.mceItemHiddenSpellWord {background:url(../img/wline.gif) repeat-x bottom left; cursor:default;} diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js new file mode 100644 index 00000000..3d1bf018 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js @@ -0,0 +1 @@ +(function(){var a=tinymce.util.JSONRequest,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.SpellcheckerPlugin",{getInfo:function(){return{longname:"Spellchecker",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker",version:tinymce.majorVersion+"."+tinymce.minorVersion}},init:function(e,f){var g=this,d;g.url=f;g.editor=e;g.rpcUrl=e.getParam("spellchecker_rpc_url",this.url+'/rpc.php');if(g.rpcUrl=="{backend}"){if(tinymce.isIE){return}g.hasSupport=true;e.onContextMenu.addToTop(function(h,i){if(g.active){return false}})}e.addCommand("mceSpellCheck",function(){if(g.rpcUrl=="{backend}"){g.editor.getBody().spellcheck=g.active=!g.active;return}if(!g.active){e.setProgressState(1);g._sendRPC("checkWords",[g.selectedLang,g._getWords()],function(h){if(h.length>0){g.active=1;g._markWords(h);e.setProgressState(0);e.nodeChanged()}else{e.setProgressState(0);if(e.getParam("spellchecker_report_no_misspellings",true)){e.windowManager.alert("spellchecker.no_mpell")}}})}else{g._done()}});e.onInit.add(function(){if(e.settings.content_css!==false){e.dom.loadCSS(f+"/css/content.css")}});e.onClick.add(g._showMenu,g);e.onContextMenu.add(g._showMenu,g);e.onBeforeGetContent.add(function(){if(g.active){g._removeWords()}});e.onNodeChange.add(function(i,h){h.setActive("spellchecker",g.active)});e.onSetContent.add(function(){g._done()});e.onBeforeGetContent.add(function(){g._done()});e.onBeforeExecCommand.add(function(h,i){if(i=="mceFullScreen"){g._done()}});g.languages={};c(e.getParam("spellchecker_languages","+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv","hash"),function(i,h){if(h.indexOf("+")===0){h=h.substring(1);g.selectedLang=i}g.languages[h]=i})},createControl:function(h,d){var f=this,g,e=f.editor;if(h=="spellchecker"){if(f.rpcUrl=="{backend}"){if(f.hasSupport){g=d.createButton(h,{title:"spellchecker.desc",cmd:"mceSpellCheck",scope:f})}return g}g=d.createSplitButton(h,{title:"spellchecker.desc",cmd:"mceSpellCheck",scope:f});g.onRenderMenu.add(function(j,i){i.add({title:"spellchecker.langs","class":"mceMenuItemTitle"}).setDisabled(1);c(f.languages,function(n,m){var p={icon:1},l;p.onclick=function(){l.setSelected(1);f.selectedItem.setSelected(0);f.selectedItem=l;f.selectedLang=n};p.title=m;l=i.add(p);l.setSelected(n==f.selectedLang);if(n==f.selectedLang){f.selectedItem=l}})});return g}},_walk:function(i,g){var h=this.editor.getDoc(),e;if(h.createTreeWalker){e=h.createTreeWalker(i,NodeFilter.SHOW_TEXT,null,false);while((i=e.nextNode())!=null){g.call(this,i)}}else{tinymce.walk(i,g,"childNodes")}},_getSeparators:function(){var e="",d,f=this.editor.getParam("spellchecker_word_separator_chars",'\\s!"#$%&()*+,-./:;<=>?@[]^_{|}\u201d\u201c');for(d=0;d$1$2');q=q.replace(g,'$1$2');j.replace(j.create("span",{"class":"mceItemHidden"},q),r)}}});l.moveToBookmark(m)},_showMenu:function(g,i){var h=this,g=h.editor,d=h._menu,k,j=g.dom,f=j.getViewPort(g.getWin());if(!d){k=b.getPos(g.getContentAreaContainer());d=g.controlManager.createDropMenu("spellcheckermenu",{offset_x:k.x,offset_y:k.y,"class":"mceNoIcons"});h._menu=d}if(j.hasClass(i.target,"mceItemHiddenSpellWord")){d.removeAll();d.add({title:"spellchecker.wait","class":"mceMenuItemTitle"}).setDisabled(1);h._sendRPC("getSuggestions",[h.selectedLang,j.decode(i.target.innerHTML)],function(l){var e;d.removeAll();if(l.length>0){d.add({title:"spellchecker.sug","class":"mceMenuItemTitle"}).setDisabled(1);c(l,function(m){d.add({title:m,onclick:function(){j.replace(g.getDoc().createTextNode(m),i.target);h._checkDone()}})});d.addSeparator()}else{d.add({title:"spellchecker.no_sug","class":"mceMenuItemTitle"}).setDisabled(1)}e=h.editor.getParam("spellchecker_enable_ignore_rpc","");d.add({title:"spellchecker.ignore_word",onclick:function(){var m=i.target.innerHTML;j.remove(i.target,1);h._checkDone();if(ignore_rpc){g.setProgressState(1);h._sendRPC("ignoreWord",[h.selectedLang,m],function(n){g.setProgressState(0)})}}});d.add({title:"spellchecker.ignore_words",onclick:function(){var m=i.target.innerHTML;h._removeWords(j.decode(m));h._checkDone();if(ignore_rpc){g.setProgressState(1);h._sendRPC("ignoreWords",[h.selectedLang,m],function(n){g.setProgressState(0)})}}});if(h.editor.getParam("spellchecker_enable_learn_rpc")){d.add({title:"spellchecker.learn_word",onclick:function(){var m=i.target.innerHTML;j.remove(i.target,1);h._checkDone();g.setProgressState(1);h._sendRPC("learnWord",[h.selectedLang,m],function(n){g.setProgressState(0)})}})}d.update()});g.selection.select(i.target);k=j.getPos(i.target);d.showMenu(k.x,k.y+i.target.offsetHeight-f.y);return tinymce.dom.Event.cancel(i)}else{d.hideMenu()}},_checkDone:function(){var e=this,d=e.editor,g=d.dom,f;c(g.select("span"),function(h){if(h&&g.hasClass(h,"mceItemHiddenSpellWord")){f=true;return false}});if(!f){e._done()}},_done:function(){var d=this,e=d.active;if(d.active){d.active=0;d._removeWords();if(d._menu){d._menu.hideMenu()}if(e){d.editor.nodeChanged()}}},_sendRPC:function(e,g,d){var f=this;a.sendRPC({url:f.rpcUrl,method:e,params:g,success:d,error:function(i,h){f.editor.setProgressState(0);f.editor.windowManager.alert(i.errstr||("Error response: "+h.responseText))}})}});tinymce.PluginManager.add("spellchecker",tinymce.plugins.SpellcheckerPlugin)})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/img/wline.gif b/src/wp-includes/js/tinymce/plugins/spellchecker/img/wline.gif new file mode 100644 index 00000000..7d0a4dbc Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/spellchecker/img/wline.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/includes/general.php b/src/wp-includes/js/tinymce/plugins/spellchecker/includes/general.php new file mode 100644 index 00000000..ffea3a0c --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/includes/general.php @@ -0,0 +1,98 @@ + $value) + $newarray[$name] = $value; + + return $newarray; + } + + return $_REQUEST[$name]; +} + +function &getLogger() { + global $mcLogger, $man; + + if (isset($man)) + $mcLogger = $man->getLogger(); + + if (!$mcLogger) { + $mcLogger = new Moxiecode_Logger(); + + // Set logger options + $mcLogger->setPath(dirname(__FILE__) . "/../logs"); + $mcLogger->setMaxSize("100kb"); + $mcLogger->setMaxFiles("10"); + $mcLogger->setFormat("{time} - {message}"); + } + + return $mcLogger; +} + +function debug($msg) { + $args = func_get_args(); + + $log = getLogger(); + $log->debug(implode(', ', $args)); +} + +function info($msg) { + $args = func_get_args(); + + $log = getLogger(); + $log->info(implode(', ', $args)); +} + +function error($msg) { + $args = func_get_args(); + + $log = getLogger(); + $log->error(implode(', ', $args)); +} + +function warn($msg) { + $args = func_get_args(); + + $log = getLogger(); + $log->warn(implode(', ', $args)); +} + +function fatal($msg) { + $args = func_get_args(); + + $log = getLogger(); + $log->fatal(implode(', ', $args)); +} + +?> \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/spellchecker/rpc.php b/src/wp-includes/js/tinymce/plugins/spellchecker/rpc.php new file mode 100644 index 00000000..6a567348 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/spellchecker/rpc.php @@ -0,0 +1,112 @@ +decode($raw); + +// Execute RPC +if (isset($config['general.engine'])) { + $spellchecker = new $config['general.engine']($config); + $result = call_user_func_array(array($spellchecker, $input['method']), $input['params']); +} else + die('{"result":null,"id":null,"error":{"errstr":"You must choose an spellchecker engine in the config.php file.","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}'); + +// Request and response id should always be the same +$output = array( + "id" => $input->id, + "result" => $result, + "error" => null +); + +// Return JSON encoded string +echo $json->encode($output); + +?> diff --git a/src/wp-includes/js/tinymce/plugins/tabfocus/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/tabfocus/editor_plugin.js new file mode 100644 index 00000000..27d24402 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/tabfocus/editor_plugin.js @@ -0,0 +1 @@ +(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(i){o=c.getParent(l.id,"form");n=o.elements;if(o){d(n,function(s,r){if(s.id==l.id){j=r;return false}});if(i>0){for(m=j+1;m=0;m--){if(n[m].type!="hidden"){return n[m]}}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(l=tinymce.get(n.id||n.name)){l.focus()}else{window.setTimeout(function(){window.focus();n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}f.onInit.add(function(){d(c.select("a:first,a:last",f.getContainer()),function(i){a.add(i,"focus",function(){f.focus()})})})},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/css/content.css b/src/wp-includes/js/tinymce/plugins/wordpress/css/content.css new file mode 100644 index 00000000..f8384955 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wordpress/css/content.css @@ -0,0 +1,29 @@ + +.mceWPnextpage, .mceWPmore { + border: 0px; + border-top: 1px dotted #cccccc; + display: block; + width: 100%; + height: 12px; + margin-top: 15px; +} +.mceWPmore { + background: #ffffff url(../img/more_bug.gif) no-repeat right top; +} +.mceWPnextpage { + background: #ffffff url(../img/page_bug.gif) no-repeat right top; +} + +img.wpGallery { + border: 1px dashed #888; + background: #f2f8ff url("../../wpgallery/img/gallery.png") no-repeat scroll center center; + width: 99%; + height: 250px; +} + +img.wp-oembed { + border: 1px dashed #888; + background: #f7f5f2 url("../img/embedded.png") no-repeat scroll center center; + width: 300px; + height: 250px; +} diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.dev.js b/src/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.dev.js new file mode 100644 index 00000000..f8998688 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.dev.js @@ -0,0 +1,412 @@ +/** + * WordPress plugin. + */ + +(function() { + var DOM = tinymce.DOM; + + tinymce.create('tinymce.plugins.WordPress', { + mceTout : 0, + + init : function(ed, url) { + var t = this, tbId = ed.getParam('wordpress_adv_toolbar', 'toolbar2'), last = 0, moreHTML, nextpageHTML; + moreHTML = ''; + nextpageHTML = ''; + + if ( getUserSetting('hidetb', '0') == '1' ) + ed.settings.wordpress_adv_hidden = 0; + + // Hides the specified toolbar and resizes the iframe + ed.onPostRender.add(function() { + var adv_toolbar = ed.controlManager.get(tbId); + if ( ed.getParam('wordpress_adv_hidden', 1) && adv_toolbar ) { + DOM.hide(adv_toolbar.id); + t._resizeIframe(ed, tbId, 28); + } + }); + + // Register commands + ed.addCommand('WP_More', function() { + ed.execCommand('mceInsertContent', 0, moreHTML); + }); + + ed.addCommand('WP_Page', function() { + ed.execCommand('mceInsertContent', 0, nextpageHTML); + }); + + ed.addCommand('WP_Help', function() { + ed.windowManager.open({ + url : tinymce.baseURL + '/wp-mce-help.php', + width : 450, + height : 420, + inline : 1 + }); + }); + + ed.addCommand('WP_Adv', function() { + var cm = ed.controlManager, id = cm.get(tbId).id; + + if ( 'undefined' == id ) + return; + + if ( DOM.isHidden(id) ) { + cm.setActive('wp_adv', 1); + DOM.show(id); + t._resizeIframe(ed, tbId, -28); + ed.settings.wordpress_adv_hidden = 0; + setUserSetting('hidetb', '1'); + } else { + cm.setActive('wp_adv', 0); + DOM.hide(id); + t._resizeIframe(ed, tbId, 28); + ed.settings.wordpress_adv_hidden = 1; + setUserSetting('hidetb', '0'); + } + }); + + // Register buttons + ed.addButton('wp_more', { + title : 'wordpress.wp_more_desc', + image : url + '/img/more.gif', + cmd : 'WP_More' + }); + + ed.addButton('wp_page', { + title : 'wordpress.wp_page_desc', + image : url + '/img/page.gif', + cmd : 'WP_Page' + }); + + ed.addButton('wp_help', { + title : 'wordpress.wp_help_desc', + image : url + '/img/help.gif', + cmd : 'WP_Help' + }); + + ed.addButton('wp_adv', { + title : 'wordpress.wp_adv_desc', + image : url + '/img/toolbars.gif', + cmd : 'WP_Adv' + }); + + // Add Media buttons + ed.addButton('add_media', { + title : 'wordpress.add_media', + image : url + '/img/media.gif', + onclick : function() { + tb_show('', tinymce.DOM.get('add_media').href); + tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' ); + } + }); + + ed.addButton('add_image', { + title : 'wordpress.add_image', + image : url + '/img/image.gif', + onclick : function() { + tb_show('', tinymce.DOM.get('add_image').href); + tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' ); + } + }); + + ed.addButton('add_video', { + title : 'wordpress.add_video', + image : url + '/img/video.gif', + onclick : function() { + tb_show('', tinymce.DOM.get('add_video').href); + tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' ); + } + }); + + ed.addButton('add_audio', { + title : 'wordpress.add_audio', + image : url + '/img/audio.gif', + onclick : function() { + tb_show('', tinymce.DOM.get('add_audio').href); + tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' ); + } + }); + + // Add Media buttons to fullscreen and handle align buttons for image captions + ed.onBeforeExecCommand.add(function(ed, cmd, ui, val, o) { + var DOM = tinymce.DOM, n, DL, DIV, cls, a, align; + if ( 'mceFullScreen' == cmd ) { + if ( 'mce_fullscreen' != ed.id && DOM.get('add_audio') && DOM.get('add_video') && DOM.get('add_image') && DOM.get('add_media') ) + ed.settings.theme_advanced_buttons1 += ',|,add_image,add_video,add_audio,add_media'; + } + + if ( 'JustifyLeft' == cmd || 'JustifyRight' == cmd || 'JustifyCenter' == cmd ) { + n = ed.selection.getNode(); + + if ( n.nodeName == 'IMG' ) { + align = cmd.substr(7).toLowerCase(); + a = 'align' + align; + DL = ed.dom.getParent(n, 'dl.wp-caption'); + DIV = ed.dom.getParent(n, 'div.mceTemp'); + + if ( DL && DIV ) { + cls = ed.dom.hasClass(DL, a) ? 'alignnone' : a; + DL.className = DL.className.replace(/align[^ '"]+\s?/g, ''); + ed.dom.addClass(DL, cls); + + if (cls == 'aligncenter') + ed.dom.addClass(DIV, 'mceIEcenter'); + else + ed.dom.removeClass(DIV, 'mceIEcenter'); + + o.terminate = true; + ed.execCommand('mceRepaint'); + } else { + if ( ed.dom.hasClass(n, a) ) + ed.dom.addClass(n, 'alignnone'); + else + ed.dom.removeClass(n, 'alignnone'); + } + } + } + }); + + ed.onInit.add(function(ed) { + // make sure these run last + ed.onNodeChange.add( function(ed, cm, e) { + var DL; + + if ( e.nodeName == 'IMG' ) { + DL = ed.dom.getParent(e, 'dl.wp-caption'); + } else if ( e.nodeName == 'DIV' && ed.dom.hasClass(e, 'mceTemp') ) { + DL = e.firstChild; + + if ( ! ed.dom.hasClass(DL, 'wp-caption') ) + DL = false; + } + + if ( DL ) { + if ( ed.dom.hasClass(DL, 'alignleft') ) + cm.setActive('justifyleft', 1); + else if ( ed.dom.hasClass(DL, 'alignright') ) + cm.setActive('justifyright', 1); + else if ( ed.dom.hasClass(DL, 'aligncenter') ) + cm.setActive('justifycenter', 1); + } + }); + + // remove invalid parent paragraphs when pasting HTML and/or switching to the HTML editor and back + ed.onBeforeSetContent.add(function(ed, o) { + if ( o.content ) { + o.content = o.content.replace(/

    \s*<(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)( [^>]*)?>/gi, '<$1$2>'); + o.content = o.content.replace(/<\/(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)>\s*<\/p>/gi, ''); + } + }); + }); + + // Word count if script is loaded + if ( 'undefined' != typeof wpWordCount ) { + ed.onKeyUp.add(function(ed, e) { + if ( e.keyCode == last ) return; + if ( 13 == e.keyCode || 8 == last || 46 == last ) wpWordCount.wc( ed.getContent({format : 'raw'}) ); + last = e.keyCode; + }); + }; + + ed.onSaveContent.add(function(ed, o) { + if ( typeof(switchEditors) == 'object' ) { + if ( ed.isHidden() ) + o.content = o.element.value; + else + o.content = switchEditors.pre_wpautop(o.content); + } + }); + + /* disable for now + ed.onBeforeSetContent.add(function(ed, o) { + o.content = t._setEmbed(o.content); + }); + + ed.onPostProcess.add(function(ed, o) { + if ( o.get ) + o.content = t._getEmbed(o.content); + }); + */ + + // Add listeners to handle more break + t._handleMoreBreak(ed, url); + + // Add custom shortcuts + ed.addShortcut('alt+shift+c', ed.getLang('justifycenter_desc'), 'JustifyCenter'); + ed.addShortcut('alt+shift+r', ed.getLang('justifyright_desc'), 'JustifyRight'); + ed.addShortcut('alt+shift+l', ed.getLang('justifyleft_desc'), 'JustifyLeft'); + ed.addShortcut('alt+shift+j', ed.getLang('justifyfull_desc'), 'JustifyFull'); + ed.addShortcut('alt+shift+q', ed.getLang('blockquote_desc'), 'mceBlockQuote'); + ed.addShortcut('alt+shift+u', ed.getLang('bullist_desc'), 'InsertUnorderedList'); + ed.addShortcut('alt+shift+o', ed.getLang('numlist_desc'), 'InsertOrderedList'); + ed.addShortcut('alt+shift+d', ed.getLang('striketrough_desc'), 'Strikethrough'); + ed.addShortcut('alt+shift+n', ed.getLang('spellchecker.desc'), 'mceSpellCheck'); + ed.addShortcut('alt+shift+a', ed.getLang('link_desc'), 'mceLink'); + ed.addShortcut('alt+shift+s', ed.getLang('unlink_desc'), 'unlink'); + ed.addShortcut('alt+shift+m', ed.getLang('image_desc'), 'mceImage'); + ed.addShortcut('alt+shift+g', ed.getLang('fullscreen.desc'), 'mceFullScreen'); + ed.addShortcut('alt+shift+z', ed.getLang('wp_adv_desc'), 'WP_Adv'); + ed.addShortcut('alt+shift+h', ed.getLang('help_desc'), 'WP_Help'); + ed.addShortcut('alt+shift+t', ed.getLang('wp_more_desc'), 'WP_More'); + ed.addShortcut('alt+shift+p', ed.getLang('wp_page_desc'), 'WP_Page'); + ed.addShortcut('ctrl+s', ed.getLang('save_desc'), function(){if('function'==typeof autosave)autosave();}); + + if ( tinymce.isWebKit ) { + ed.addShortcut('alt+shift+b', ed.getLang('bold_desc'), 'Bold'); + ed.addShortcut('alt+shift+i', ed.getLang('italic_desc'), 'Italic'); + } + + ed.onInit.add(function(ed) { + tinymce.dom.Event.add(ed.getWin(), 'scroll', function(e) { + ed.plugins.wordpress._hideButtons(); + }); + tinymce.dom.Event.add(ed.getBody(), 'dragstart', function(e) { + ed.plugins.wordpress._hideButtons(); + }); + }); + + ed.onBeforeExecCommand.add(function(ed, cmd, ui, val) { + ed.plugins.wordpress._hideButtons(); + }); + + ed.onSaveContent.add(function(ed, o) { + ed.plugins.wordpress._hideButtons(); + }); + + ed.onMouseDown.add(function(ed, e) { + if ( e.target.nodeName != 'IMG' ) + ed.plugins.wordpress._hideButtons(); + }); + }, + + getInfo : function() { + return { + longname : 'WordPress Plugin', + author : 'WordPress', // add Moxiecode? + authorurl : 'http://wordpress.org', + infourl : 'http://wordpress.org', + version : '3.0' + }; + }, + + // Internal functions + _setEmbed : function(c) { + return c.replace(/\[embed\]([\s\S]+?)\[\/embed\][\s\u00a0]*/g, function(a,b){ + return ''+b+''; + }); + }, + + _getEmbed : function(c) { + return c.replace(/]+>/g, function(a) { + if ( a.indexOf('class="wp-oembed') != -1 ) { + var u = a.match(/alt="([^\"]+)"/); + if ( u[1] ) + a = '[embed]' + u[1] + '[/embed]'; + } + return a; + }); + }, + + _showButtons : function(n, id) { + var ed = tinyMCE.activeEditor, p1, p2, vp, DOM = tinymce.DOM, X, Y; + + vp = ed.dom.getViewPort(ed.getWin()); + p1 = DOM.getPos(ed.getContentAreaContainer()); + p2 = ed.dom.getPos(n); + + X = Math.max(p2.x - vp.x, 0) + p1.x; + Y = Math.max(p2.y - vp.y, 0) + p1.y; + + DOM.setStyles(id, { + 'top' : Y+5+'px', + 'left' : X+5+'px', + 'display' : 'block' + }); + + if ( this.mceTout ) + clearTimeout(this.mceTout); + + this.mceTout = setTimeout( function(){ed.plugins.wordpress._hideButtons();}, 5000 ); + }, + + _hideButtons : function() { + if ( !this.mceTout ) + return; + + if ( document.getElementById('wp_editbtns') ) + tinymce.DOM.hide('wp_editbtns'); + + if ( document.getElementById('wp_gallerybtns') ) + tinymce.DOM.hide('wp_gallerybtns'); + + clearTimeout(this.mceTout); + this.mceTout = 0; + }, + + // Resizes the iframe by a relative height value + _resizeIframe : function(ed, tb_id, dy) { + var ifr = ed.getContentAreaContainer().firstChild; + + DOM.setStyle(ifr, 'height', ifr.clientHeight + dy); // Resize iframe + ed.theme.deltaHeight += dy; // For resize cookie + }, + + _handleMoreBreak : function(ed, url) { + var moreHTML, nextpageHTML; + + moreHTML = '$1'; + nextpageHTML = ''; + + // Load plugin specific CSS into editor + ed.onInit.add(function() { + ed.dom.loadCSS(url + '/css/content.css'); + }); + + // Display morebreak instead if img in element path + ed.onPostRender.add(function() { + if (ed.theme.onResolveName) { + ed.theme.onResolveName.add(function(th, o) { + if (o.node.nodeName == 'IMG') { + if ( ed.dom.hasClass(o.node, 'mceWPmore') ) + o.name = 'wpmore'; + if ( ed.dom.hasClass(o.node, 'mceWPnextpage') ) + o.name = 'wppage'; + } + + }); + } + }); + + // Replace morebreak with images + ed.onBeforeSetContent.add(function(ed, o) { + if ( o.content ) { + o.content = o.content.replace(//g, moreHTML); + o.content = o.content.replace(//g, nextpageHTML); + } + }); + + // Replace images with morebreak + ed.onPostProcess.add(function(ed, o) { + if (o.get) + o.content = o.content.replace(/]+>/g, function(im) { + if (im.indexOf('class="mceWPmore') !== -1) { + var m, moretext = (m = im.match(/alt="(.*?)"/)) ? m[1] : ''; + im = ''; + } + if (im.indexOf('class="mceWPnextpage') !== -1) + im = ''; + + return im; + }); + }); + + // Set active buttons if user selected pagebreak or more break + ed.onNodeChange.add(function(ed, cm, n) { + cm.setActive('wp_page', n.nodeName === 'IMG' && ed.dom.hasClass(n, 'mceWPnextpage')); + cm.setActive('wp_more', n.nodeName === 'IMG' && ed.dom.hasClass(n, 'mceWPmore')); + }); + } + }); + + // Register plugin + tinymce.PluginManager.add('wordpress', tinymce.plugins.WordPress); +})(); diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js new file mode 100644 index 00000000..3d215bd8 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js @@ -0,0 +1 @@ +(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.WordPress",{mceTout:0,init:function(c,d){var e=this,h=c.getParam("wordpress_adv_toolbar","toolbar2"),g=0,f,b;f='';b='';if(getUserSetting("hidetb","0")=="1"){c.settings.wordpress_adv_hidden=0}c.onPostRender.add(function(){var i=c.controlManager.get(h);if(c.getParam("wordpress_adv_hidden",1)&&i){a.hide(i.id);e._resizeIframe(c,h,28)}});c.addCommand("WP_More",function(){c.execCommand("mceInsertContent",0,f)});c.addCommand("WP_Page",function(){c.execCommand("mceInsertContent",0,b)});c.addCommand("WP_Help",function(){c.windowManager.open({url:tinymce.baseURL+"/wp-mce-help.php",width:450,height:420,inline:1})});c.addCommand("WP_Adv",function(){var i=c.controlManager,j=i.get(h).id;if("undefined"==j){return}if(a.isHidden(j)){i.setActive("wp_adv",1);a.show(j);e._resizeIframe(c,h,-28);c.settings.wordpress_adv_hidden=0;setUserSetting("hidetb","1")}else{i.setActive("wp_adv",0);a.hide(j);e._resizeIframe(c,h,28);c.settings.wordpress_adv_hidden=1;setUserSetting("hidetb","0")}});c.addButton("wp_more",{title:"wordpress.wp_more_desc",image:d+"/img/more.gif",cmd:"WP_More"});c.addButton("wp_page",{title:"wordpress.wp_page_desc",image:d+"/img/page.gif",cmd:"WP_Page"});c.addButton("wp_help",{title:"wordpress.wp_help_desc",image:d+"/img/help.gif",cmd:"WP_Help"});c.addButton("wp_adv",{title:"wordpress.wp_adv_desc",image:d+"/img/toolbars.gif",cmd:"WP_Adv"});c.addButton("add_media",{title:"wordpress.add_media",image:d+"/img/media.gif",onclick:function(){tb_show("",tinymce.DOM.get("add_media").href);tinymce.DOM.setStyle(["TB_overlay","TB_window","TB_load"],"z-index","999999")}});c.addButton("add_image",{title:"wordpress.add_image",image:d+"/img/image.gif",onclick:function(){tb_show("",tinymce.DOM.get("add_image").href);tinymce.DOM.setStyle(["TB_overlay","TB_window","TB_load"],"z-index","999999")}});c.addButton("add_video",{title:"wordpress.add_video",image:d+"/img/video.gif",onclick:function(){tb_show("",tinymce.DOM.get("add_video").href);tinymce.DOM.setStyle(["TB_overlay","TB_window","TB_load"],"z-index","999999")}});c.addButton("add_audio",{title:"wordpress.add_audio",image:d+"/img/audio.gif",onclick:function(){tb_show("",tinymce.DOM.get("add_audio").href);tinymce.DOM.setStyle(["TB_overlay","TB_window","TB_load"],"z-index","999999")}});c.onBeforeExecCommand.add(function(p,m,s,l,j){var v=tinymce.DOM,k,i,r,u,t,q;if("mceFullScreen"==m){if("mce_fullscreen"!=p.id&&v.get("add_audio")&&v.get("add_video")&&v.get("add_image")&&v.get("add_media")){p.settings.theme_advanced_buttons1+=",|,add_image,add_video,add_audio,add_media"}}if("JustifyLeft"==m||"JustifyRight"==m||"JustifyCenter"==m){k=p.selection.getNode();if(k.nodeName=="IMG"){q=m.substr(7).toLowerCase();t="align"+q;i=p.dom.getParent(k,"dl.wp-caption");r=p.dom.getParent(k,"div.mceTemp");if(i&&r){u=p.dom.hasClass(i,t)?"alignnone":t;i.className=i.className.replace(/align[^ '"]+\s?/g,"");p.dom.addClass(i,u);if(u=="aligncenter"){p.dom.addClass(r,"mceIEcenter")}else{p.dom.removeClass(r,"mceIEcenter")}j.terminate=true;p.execCommand("mceRepaint")}else{if(p.dom.hasClass(k,t)){p.dom.addClass(k,"alignnone")}else{p.dom.removeClass(k,"alignnone")}}}}});c.onInit.add(function(i){i.onNodeChange.add(function(k,j,m){var l;if(m.nodeName=="IMG"){l=k.dom.getParent(m,"dl.wp-caption")}else{if(m.nodeName=="DIV"&&k.dom.hasClass(m,"mceTemp")){l=m.firstChild;if(!k.dom.hasClass(l,"wp-caption")){l=false}}}if(l){if(k.dom.hasClass(l,"alignleft")){j.setActive("justifyleft",1)}else{if(k.dom.hasClass(l,"alignright")){j.setActive("justifyright",1)}else{if(k.dom.hasClass(l,"aligncenter")){j.setActive("justifycenter",1)}}}}});i.onBeforeSetContent.add(function(j,k){if(k.content){k.content=k.content.replace(/

    \s*<(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)( [^>]*)?>/gi,"<$1$2>");k.content=k.content.replace(/<\/(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)>\s*<\/p>/gi,"")}})});if("undefined"!=typeof wpWordCount){c.onKeyUp.add(function(i,j){if(j.keyCode==g){return}if(13==j.keyCode||8==g||46==g){wpWordCount.wc(i.getContent({format:"raw"}))}g=j.keyCode})}c.onSaveContent.add(function(i,j){if(typeof(switchEditors)=="object"){if(i.isHidden()){j.content=j.element.value}else{j.content=switchEditors.pre_wpautop(j.content)}}});e._handleMoreBreak(c,d);c.addShortcut("alt+shift+c",c.getLang("justifycenter_desc"),"JustifyCenter");c.addShortcut("alt+shift+r",c.getLang("justifyright_desc"),"JustifyRight");c.addShortcut("alt+shift+l",c.getLang("justifyleft_desc"),"JustifyLeft");c.addShortcut("alt+shift+j",c.getLang("justifyfull_desc"),"JustifyFull");c.addShortcut("alt+shift+q",c.getLang("blockquote_desc"),"mceBlockQuote");c.addShortcut("alt+shift+u",c.getLang("bullist_desc"),"InsertUnorderedList");c.addShortcut("alt+shift+o",c.getLang("numlist_desc"),"InsertOrderedList");c.addShortcut("alt+shift+d",c.getLang("striketrough_desc"),"Strikethrough");c.addShortcut("alt+shift+n",c.getLang("spellchecker.desc"),"mceSpellCheck");c.addShortcut("alt+shift+a",c.getLang("link_desc"),"mceLink");c.addShortcut("alt+shift+s",c.getLang("unlink_desc"),"unlink");c.addShortcut("alt+shift+m",c.getLang("image_desc"),"mceImage");c.addShortcut("alt+shift+g",c.getLang("fullscreen.desc"),"mceFullScreen");c.addShortcut("alt+shift+z",c.getLang("wp_adv_desc"),"WP_Adv");c.addShortcut("alt+shift+h",c.getLang("help_desc"),"WP_Help");c.addShortcut("alt+shift+t",c.getLang("wp_more_desc"),"WP_More");c.addShortcut("alt+shift+p",c.getLang("wp_page_desc"),"WP_Page");c.addShortcut("ctrl+s",c.getLang("save_desc"),function(){if("function"==typeof autosave){autosave()}});if(tinymce.isWebKit){c.addShortcut("alt+shift+b",c.getLang("bold_desc"),"Bold");c.addShortcut("alt+shift+i",c.getLang("italic_desc"),"Italic")}c.onInit.add(function(i){tinymce.dom.Event.add(i.getWin(),"scroll",function(j){i.plugins.wordpress._hideButtons()});tinymce.dom.Event.add(i.getBody(),"dragstart",function(j){i.plugins.wordpress._hideButtons()})});c.onBeforeExecCommand.add(function(i,k,j,l){i.plugins.wordpress._hideButtons()});c.onSaveContent.add(function(i,j){i.plugins.wordpress._hideButtons()});c.onMouseDown.add(function(i,j){if(j.target.nodeName!="IMG"){i.plugins.wordpress._hideButtons()}})},getInfo:function(){return{longname:"WordPress Plugin",author:"WordPress",authorurl:"http://wordpress.org",infourl:"http://wordpress.org",version:"3.0"}},_setEmbed:function(b){return b.replace(/\[embed\]([\s\S]+?)\[\/embed\][\s\u00a0]*/g,function(d,c){return''+c+''})},_getEmbed:function(b){return b.replace(/]+>/g,function(c){if(c.indexOf('class="wp-oembed')!=-1){var d=c.match(/alt="([^\"]+)"/);if(d[1]){c="[embed]"+d[1]+"[/embed]"}}return c})},_showButtons:function(f,d){var g=tinyMCE.activeEditor,i,h,b,j=tinymce.DOM,e,c;b=g.dom.getViewPort(g.getWin());i=j.getPos(g.getContentAreaContainer());h=g.dom.getPos(f);e=Math.max(h.x-b.x,0)+i.x;c=Math.max(h.y-b.y,0)+i.y;j.setStyles(d,{top:c+5+"px",left:e+5+"px",display:"block"});if(this.mceTout){clearTimeout(this.mceTout)}this.mceTout=setTimeout(function(){g.plugins.wordpress._hideButtons()},5000)},_hideButtons:function(){if(!this.mceTout){return}if(document.getElementById("wp_editbtns")){tinymce.DOM.hide("wp_editbtns")}if(document.getElementById("wp_gallerybtns")){tinymce.DOM.hide("wp_gallerybtns")}clearTimeout(this.mceTout);this.mceTout=0},_resizeIframe:function(c,e,b){var d=c.getContentAreaContainer().firstChild;a.setStyle(d,"height",d.clientHeight+b);c.theme.deltaHeight+=b},_handleMoreBreak:function(c,d){var e,b;e='$1';b='';c.onInit.add(function(){c.dom.loadCSS(d+"/css/content.css")});c.onPostRender.add(function(){if(c.theme.onResolveName){c.theme.onResolveName.add(function(f,g){if(g.node.nodeName=="IMG"){if(c.dom.hasClass(g.node,"mceWPmore")){g.name="wpmore"}if(c.dom.hasClass(g.node,"mceWPnextpage")){g.name="wppage"}}})}});c.onBeforeSetContent.add(function(f,g){if(g.content){g.content=g.content.replace(//g,e);g.content=g.content.replace(//g,b)}});c.onPostProcess.add(function(f,g){if(g.get){g.content=g.content.replace(/]+>/g,function(i){if(i.indexOf('class="mceWPmore')!==-1){var h,j=(h=i.match(/alt="(.*?)"/))?h[1]:"";i=""}if(i.indexOf('class="mceWPnextpage')!==-1){i=""}return i})}});c.onNodeChange.add(function(g,f,h){f.setActive("wp_page",h.nodeName==="IMG"&&g.dom.hasClass(h,"mceWPnextpage"));f.setActive("wp_more",h.nodeName==="IMG"&&g.dom.hasClass(h,"mceWPmore"))})}});tinymce.PluginManager.add("wordpress",tinymce.plugins.WordPress)})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/audio.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/audio.gif new file mode 100644 index 00000000..f8ad2238 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/audio.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/embedded.png b/src/wp-includes/js/tinymce/plugins/wordpress/img/embedded.png new file mode 100644 index 00000000..173401ba Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/embedded.png differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/help.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/help.gif new file mode 100644 index 00000000..51a1ee42 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/help.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/image.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/image.gif new file mode 100644 index 00000000..6736e6b0 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/image.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/media.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/media.gif new file mode 100644 index 00000000..786e4f55 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/media.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/more.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/more.gif new file mode 100644 index 00000000..4ff564d5 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/more.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/more_bug.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/more_bug.gif new file mode 100644 index 00000000..4589cb4d Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/more_bug.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/page.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/page.gif new file mode 100644 index 00000000..1cea78ac Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/page.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/page_bug.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/page_bug.gif new file mode 100644 index 00000000..9ea35656 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/page_bug.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/toolbars.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/toolbars.gif new file mode 100644 index 00000000..dcb70665 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/toolbars.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif new file mode 100644 index 00000000..38848651 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/img/video.gif b/src/wp-includes/js/tinymce/plugins/wordpress/img/video.gif new file mode 100644 index 00000000..b8e0975b Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wordpress/img/video.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js b/src/wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js new file mode 100644 index 00000000..bdc63ddc --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js @@ -0,0 +1,97 @@ +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function($) { + var wpDialogFn = function( fn ) { + return function() { + if ( this.features.wpDialog ) + return fn.apply( this, arguments ); + else + return this.parent.apply( this, arguments ); + }; + }; + + tinymce.create('tinymce.plugins.WPDialogs', { + init : function(ed, url) { + // Replace window manager + ed.onBeforeRenderUI.add(function() { + ed.windowManager = new tinymce.WPWindowManager(ed); + }); + }, + + getInfo : function() { + return { + longname : 'WPDialogs', + author : 'WordPress', + authorurl : 'http://wordpress.org', + infourl : 'http://wordpress.org', + version : '0.1' + }; + } + }); + + $(document).ready(function() { + $.widget("wp.wpdialog", $.ui.dialog, { + open: function() { + // Initialize tinyMCEPopup if it exists. + if ( tinyMCEPopup ) + tinyMCEPopup.init(); + // Open the dialog. + $.ui.dialog.prototype.open.apply( this, arguments ); + // WebKit leaves focus in the TinyMCE editor unless we shift focus. + this.element.focus(); + this._trigger('refresh'); + } + }); + }); + + tinymce.create('tinymce.WPWindowManager:tinymce.InlineWindowManager', { + WPWindowManager : function(ed) { + this.parent(ed); + }, + + open : function(f, p) { + var t = this, element; + // Can't use wpDialogFn here; this.features isn't set yet. + if ( ! f.wpDialog ) + return this.parent( f, p ); + else if ( ! f.id ) + return; + + element = $('#' + f.id); + if ( ! element.length ) + return; + + t.features = f; + t.params = p; + t.onOpen.dispatch(t, f, p); + t.element = t.windows[ f.id ] = element; + + // Store selection + t.bookmark = t.editor.selection.getBookmark(1); + + element.wpdialog({ + title: f.title, + width: f.width, + height: f.height, + modal: true, + dialogClass: 'wp-dialog', + zIndex: 300000 + }); + }, + close : wpDialogFn(function() { + this.element.wpdialog('close'); + }) + }); + + // Register plugin + tinymce.PluginManager.add('wpdialogs', tinymce.plugins.WPDialogs); +})(jQuery); + diff --git a/src/wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js new file mode 100644 index 00000000..fc621f13 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js @@ -0,0 +1 @@ +(function(b){var a=function(c){return function(){if(this.features.wpDialog){return c.apply(this,arguments)}else{return this.parent.apply(this,arguments)}}};tinymce.create("tinymce.plugins.WPDialogs",{init:function(c,d){c.onBeforeRenderUI.add(function(){c.windowManager=new tinymce.WPWindowManager(c)})},getInfo:function(){return{longname:"WPDialogs",author:"WordPress",authorurl:"http://wordpress.org",infourl:"http://wordpress.org",version:"0.1"}}});b(document).ready(function(){b.widget("wp.wpdialog",b.ui.dialog,{open:function(){if(tinyMCEPopup){tinyMCEPopup.init()}b.ui.dialog.prototype.open.apply(this,arguments);this.element.focus();this._trigger("refresh")}})});tinymce.create("tinymce.WPWindowManager:tinymce.InlineWindowManager",{WPWindowManager:function(c){this.parent(c)},open:function(e,g){var d=this,c;if(!e.wpDialog){return this.parent(e,g)}else{if(!e.id){return}}c=b("#"+e.id);if(!c.length){return}d.features=e;d.params=g;d.onOpen.dispatch(d,e,g);d.element=d.windows[e.id]=c;d.bookmark=d.editor.selection.getBookmark(1);c.wpdialog({title:e.title,width:e.width,height:e.height,modal:true,dialogClass:"wp-dialog",zIndex:300000})},close:a(function(){this.element.wpdialog("close")})});tinymce.PluginManager.add("wpdialogs",tinymce.plugins.WPDialogs)})(jQuery); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wpdialogs/js/popup.dev.js b/src/wp-includes/js/tinymce/plugins/wpdialogs/js/popup.dev.js new file mode 100644 index 00000000..3f79a257 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpdialogs/js/popup.dev.js @@ -0,0 +1,432 @@ +/** + * popup.js + * + * An altered version of tinyMCEPopup to work in the same window as tinymce. + * + * ------------------------------------------------------------------ + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +// Some global instances + +/** + * TinyMCE popup/dialog helper class. This gives you easy access to the + * parent editor instance and a bunch of other things. It's higly recommended + * that you load this script into your dialogs. + * + * @static + * @class tinyMCEPopup + */ +var tinyMCEPopup = { + /** + * Initializes the popup this will be called automatically. + * + * @method init + */ + init : function() { + var t = this, w, ti; + + // Find window & API + w = t.getWin(); + tinymce = w.tinymce; + tinyMCE = w.tinyMCE; + t.editor = tinymce.EditorManager.activeEditor; + t.params = t.editor.windowManager.params; + t.features = t.editor.windowManager.features; + t.dom = tinymce.dom; + + // Setup on init listeners + t.listeners = []; + t.onInit = { + add : function(f, s) { + t.listeners.push({func : f, scope : s}); + } + }; + + t.isWindow = false; + t.id = t.features.id; + t.editor.windowManager.onOpen.dispatch(t.editor.windowManager, window); + }, + + /** + * Returns the reference to the parent window that opened the dialog. + * + * @method getWin + * @return {Window} Reference to the parent window that opened the dialog. + */ + getWin : function() { + return window; + }, + + /** + * Returns a window argument/parameter by name. + * + * @method getWindowArg + * @param {String} n Name of the window argument to retrive. + * @param {String} dv Optional default value to return. + * @return {String} Argument value or default value if it wasn't found. + */ + getWindowArg : function(n, dv) { + var v = this.params[n]; + + return tinymce.is(v) ? v : dv; + }, + + /** + * Returns a editor parameter/config option value. + * + * @method getParam + * @param {String} n Name of the editor config option to retrive. + * @param {String} dv Optional default value to return. + * @return {String} Parameter value or default value if it wasn't found. + */ + getParam : function(n, dv) { + return this.editor.getParam(n, dv); + }, + + /** + * Returns a language item by key. + * + * @method getLang + * @param {String} n Language item like mydialog.something. + * @param {String} dv Optional default value to return. + * @return {String} Language value for the item like "my string" or the default value if it wasn't found. + */ + getLang : function(n, dv) { + return this.editor.getLang(n, dv); + }, + + /** + * Executed a command on editor that opened the dialog/popup. + * + * @method execCommand + * @param {String} cmd Command to execute. + * @param {Boolean} ui Optional boolean value if the UI for the command should be presented or not. + * @param {Object} val Optional value to pass with the comman like an URL. + * @param {Object} a Optional arguments object. + */ + execCommand : function(cmd, ui, val, a) { + a = a || {}; + a.skip_focus = 1; + + this.restoreSelection(); + return this.editor.execCommand(cmd, ui, val, a); + }, + + /** + * Resizes the dialog to the inner size of the window. This is needed since various browsers + * have different border sizes on windows. + * + * @method resizeToInnerSize + */ + resizeToInnerSize : function() { + var t = this; + + // Detach it to workaround a Chrome specific bug + // https://sourceforge.net/tracker/?func=detail&atid=635682&aid=2926339&group_id=103281 + setTimeout(function() { + var vp = t.dom.getViewPort(window); + + t.editor.windowManager.resizeBy( + t.getWindowArg('mce_width') - vp.w, + t.getWindowArg('mce_height') - vp.h, + t.id || window + ); + }, 0); + }, + + /** + * Will executed the specified string when the page has been loaded. This function + * was added for compatibility with the 2.x branch. + * + * @method executeOnLoad + * @param {String} s String to evalutate on init. + */ + executeOnLoad : function(s) { + this.onInit.add(function() { + eval(s); + }); + }, + + /** + * Stores the current editor selection for later restoration. This can be useful since some browsers + * looses it's selection if a control element is selected/focused inside the dialogs. + * + * @method storeSelection + */ + storeSelection : function() { + this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark(1); + }, + + /** + * Restores any stored selection. This can be useful since some browsers + * looses it's selection if a control element is selected/focused inside the dialogs. + * + * @method restoreSelection + */ + restoreSelection : function() { + var t = tinyMCEPopup; + + if (!t.isWindow && tinymce.isIE) + t.editor.selection.moveToBookmark(t.editor.windowManager.bookmark); + }, + + /** + * Loads a specific dialog language pack. If you pass in plugin_url as a arugment + * when you open the window it will load the /langs/_dlg.js lang pack file. + * + * @method requireLangPack + */ + requireLangPack : function() { + var t = this, u = t.getWindowArg('plugin_url') || t.getWindowArg('theme_url'); + + if (u && t.editor.settings.language && t.features.translate_i18n !== false) { + u += '/langs/' + t.editor.settings.language + '_dlg.js'; + + if (!tinymce.ScriptLoader.isDone(u)) { + document.write(''); + tinymce.ScriptLoader.markDone(u); + } + } + }, + + /** + * Executes a color picker on the specified element id. When the user + * then selects a color it will be set as the value of the specified element. + * + * @method pickColor + * @param {DOMEvent} e DOM event object. + * @param {string} element_id Element id to be filled with the color value from the picker. + */ + pickColor : function(e, element_id) { + this.execCommand('mceColorPicker', true, { + color : document.getElementById(element_id).value, + func : function(c) { + document.getElementById(element_id).value = c; + + try { + document.getElementById(element_id).onchange(); + } catch (ex) { + // Try fire event, ignore errors + } + } + }); + }, + + /** + * Opens a filebrowser/imagebrowser this will set the output value from + * the browser as a value on the specified element. + * + * @method openBrowser + * @param {string} element_id Id of the element to set value in. + * @param {string} type Type of browser to open image/file/flash. + * @param {string} option Option name to get the file_broswer_callback function name from. + */ + openBrowser : function(element_id, type, option) { + tinyMCEPopup.restoreSelection(); + this.editor.execCallback('file_browser_callback', element_id, document.getElementById(element_id).value, type, window); + }, + + /** + * Creates a confirm dialog. Please don't use the blocking behavior of this + * native version use the callback method instead then it can be extended. + * + * @method confirm + * @param {String} t Title for the new confirm dialog. + * @param {function} cb Callback function to be executed after the user has selected ok or cancel. + * @param {Object} s Optional scope to execute the callback in. + */ + confirm : function(t, cb, s) { + this.editor.windowManager.confirm(t, cb, s, window); + }, + + /** + * Creates a alert dialog. Please don't use the blocking behavior of this + * native version use the callback method instead then it can be extended. + * + * @method alert + * @param {String} t Title for the new alert dialog. + * @param {function} cb Callback function to be executed after the user has selected ok. + * @param {Object} s Optional scope to execute the callback in. + */ + alert : function(tx, cb, s) { + this.editor.windowManager.alert(tx, cb, s, window); + }, + + /** + * Closes the current window. + * + * @method close + */ + close : function() { + var t = this; + + // To avoid domain relaxing issue in Opera + function close() { + t.editor.windowManager.close(window); + t.editor = null; + }; + + if (tinymce.isOpera) + t.getWin().setTimeout(close, 0); + else + close(); + }, + + // Internal functions + + _restoreSelection : function() { + var e = window.event.srcElement; + + if (e.nodeName == 'INPUT' && (e.type == 'submit' || e.type == 'button')) + tinyMCEPopup.restoreSelection(); + }, + +/* _restoreSelection : function() { + var e = window.event.srcElement; + + // If user focus a non text input or textarea + if ((e.nodeName != 'INPUT' && e.nodeName != 'TEXTAREA') || e.type != 'text') + tinyMCEPopup.restoreSelection(); + },*/ + + _onDOMLoaded : function() { + var t = tinyMCEPopup, ti = document.title, bm, h, nv; + + if (t.domLoaded) + return; + + t.domLoaded = 1; + + tinyMCEPopup.init(); + + // Translate page + if (t.features.translate_i18n !== false) { + h = document.body.innerHTML; + + // Replace a=x with a="x" in IE + if (tinymce.isIE) + h = h.replace(/ (value|title|alt)=([^"][^\s>]+)/gi, ' $1="$2"') + + document.dir = t.editor.getParam('directionality',''); + + if ((nv = t.editor.translate(h)) && nv != h) + document.body.innerHTML = nv; + + if ((nv = t.editor.translate(ti)) && nv != ti) + document.title = ti = nv; + } + + document.body.style.display = ''; + + // Restore selection in IE when focus is placed on a non textarea or input element of the type text + if (tinymce.isIE) { + document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection); + + // Add base target element for it since it would fail with modal dialogs + t.dom.add(t.dom.select('head')[0], 'base', {target : '_self'}); + } + + t.restoreSelection(); + + // Set inline title + if (!t.isWindow) + t.editor.windowManager.setTitle(window, ti); + else + window.focus(); + + if (!tinymce.isIE && !t.isWindow) { + tinymce.dom.Event._add(document, 'focus', function() { + t.editor.windowManager.focus(t.id); + }); + } + + // Patch for accessibility + tinymce.each(t.dom.select('select'), function(e) { + e.onkeydown = tinyMCEPopup._accessHandler; + }); + + // Call onInit + // Init must be called before focus so the selection won't get lost by the focus call + tinymce.each(t.listeners, function(o) { + o.func.call(o.scope, t.editor); + }); + + // Move focus to window + if (t.getWindowArg('mce_auto_focus', true)) { + window.focus(); + + // Focus element with mceFocus class + tinymce.each(document.forms, function(f) { + tinymce.each(f.elements, function(e) { + if (t.dom.hasClass(e, 'mceFocus') && !e.disabled) { + e.focus(); + return false; // Break loop + } + }); + }); + } + + document.onkeyup = tinyMCEPopup._closeWinKeyHandler; + }, + + _accessHandler : function(e) { + e = e || window.event; + + if (e.keyCode == 13 || e.keyCode == 32) { + e = e.target || e.srcElement; + + if (e.onchange) + e.onchange(); + + return tinymce.dom.Event.cancel(e); + } + }, + + _closeWinKeyHandler : function(e) { + e = e || window.event; + + if (e.keyCode == 27) + tinyMCEPopup.close(); + }, + + _wait : function() { + // Use IE method + if (document.attachEvent) { + document.attachEvent("onreadystatechange", function() { + if (document.readyState === "complete") { + document.detachEvent("onreadystatechange", arguments.callee); + tinyMCEPopup._onDOMLoaded(); + } + }); + + if (document.documentElement.doScroll && window == window.top) { + (function() { + if (tinyMCEPopup.domLoaded) + return; + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch (ex) { + setTimeout(arguments.callee, 0); + return; + } + + tinyMCEPopup._onDOMLoaded(); + })(); + } + + document.attachEvent('onload', tinyMCEPopup._onDOMLoaded); + } else if (document.addEventListener) { + window.addEventListener('DOMContentLoaded', tinyMCEPopup._onDOMLoaded, false); + window.addEventListener('load', tinyMCEPopup._onDOMLoaded, false); + } + } +}; diff --git a/src/wp-includes/js/tinymce/plugins/wpdialogs/js/popup.js b/src/wp-includes/js/tinymce/plugins/wpdialogs/js/popup.js new file mode 100644 index 00000000..abacbd3a --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpdialogs/js/popup.js @@ -0,0 +1 @@ +var tinyMCEPopup={init:function(){var b=this,a,c;a=b.getWin();tinymce=a.tinymce;tinyMCE=a.tinyMCE;b.editor=tinymce.EditorManager.activeEditor;b.params=b.editor.windowManager.params;b.features=b.editor.windowManager.features;b.dom=tinymce.dom;b.listeners=[];b.onInit={add:function(e,d){b.listeners.push({func:e,scope:d})}};b.isWindow=false;b.id=b.features.id;b.editor.windowManager.onOpen.dispatch(b.editor.windowManager,window)},getWin:function(){return window},getWindowArg:function(c,b){var a=this.params[c];return tinymce.is(a)?a:b},getParam:function(b,a){return this.editor.getParam(b,a)},getLang:function(b,a){return this.editor.getLang(b,a)},execCommand:function(d,c,e,b){b=b||{};b.skip_focus=1;this.restoreSelection();return this.editor.execCommand(d,c,e,b)},resizeToInnerSize:function(){var a=this;setTimeout(function(){var b=a.dom.getViewPort(window);a.editor.windowManager.resizeBy(a.getWindowArg("mce_width")-b.w,a.getWindowArg("mce_height")-b.h,a.id||window)},0)},executeOnLoad:function(s){this.onInit.add(function(){eval(s)})},storeSelection:function(){this.editor.windowManager.bookmark=tinyMCEPopup.editor.selection.getBookmark(1)},restoreSelection:function(){var a=tinyMCEPopup;if(!a.isWindow&&tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},requireLangPack:function(){var b=this,a=b.getWindowArg("plugin_url")||b.getWindowArg("theme_url");if(a&&b.editor.settings.language&&b.features.translate_i18n!==false){a+="/langs/"+b.editor.settings.language+"_dlg.js";if(!tinymce.ScriptLoader.isDone(a)){document.write(' + + + + + + + + + +

    + +
    +
    +
    +
    {#wpeditimage.size}
    +
    +
    {#wpeditimage.s130}
    +
    {#wpeditimage.s120}
    +
    {#wpeditimage.s110}
    +
    {#wpeditimage.s100}
    +
    {#wpeditimage.s90}
    +
    {#wpeditimage.s80}
    +
    {#wpeditimage.s70}
    +
    {#wpeditimage.s60}
    +
    +
    +
    + + + Lorem ipsum dolor sit amet consectetuer velit pretium euismod ipsum enim. Mi cursus at a mollis senectus id arcu gravida quis urna. Sed et felis id tempus Morbi mauris tincidunt enim In mauris. Pede eu risus velit libero natoque enim lorem adipiscing ipsum consequat. In malesuada et sociis tincidunt tempus pellentesque cursus convallis ipsum Suspendisse. Risus In ac quis ut Nunc convallis laoreet ante Suspendisse Nam. Amet amet urna condimentum Vestibulum sem at Curabitur lorem et cursus. Sodales tortor fermentum leo dui habitant Nunc Sed Vestibulum. + Ut lorem In penatibus libero id ipsum sagittis nec elit Sed. Condimentum eget Vivamus vel consectetuer lorem molestie turpis amet tellus id. Condimentum vel ridiculus Fusce sed pede Nam nunc sodales eros tempor. Sit lacus magna dictumst Curabitur fringilla auctor id vitae wisi facilisi. Fermentum eget turpis felis velit leo Nunc Proin orci molestie Praesent. Curabitur tellus scelerisque suscipit ut sem amet cursus mi Morbi eu. Donec libero Vestibulum augue et mollis accumsan ornare condimentum In enim. Leo eget ac consectetuer quis condimentum malesuada. + Condimentum commodo et Lorem fringilla malesuada libero volutpat sem tellus enim. Tincidunt sed at Aenean nec nonummy porttitor Nam Sed Nulla ut. Auctor leo In aliquet Curabitur eros et velit Quisque justo morbi. Et vel mauris sit nulla semper vitae et quis at dui. Id at elit laoreet justo eu mauris Quisque et interdum pharetra. Nullam accumsan interdum Maecenas condimentum quis quis Fusce a sollicitudin Sed. Non Quisque Vivamus congue porttitor non semper ipsum porttitor quis vel. Donec eros lacus volutpat et tincidunt sem convallis id venenatis sit. Consectetuer odio. + Semper faucibus Morbi nulla convallis orci Aliquam Sed porttitor et Pellentesque. Venenatis laoreet lorem id a a Morbi augue turpis id semper. Arcu volutpat ac mauris Vestibulum fringilla Aenean condimentum nibh sed id. Sagittis eu lacus orci urna tellus tellus pretium Curabitur dui nunc. Et nibh eu eu nibh adipiscing at lorem Vestibulum adipiscing augue. Magna convallis Phasellus dolor malesuada Curabitur ornare adipiscing tellus Aliquam tempus. Id Aliquam Integer augue Nulla consectetuer ac Donec Curabitur tincidunt et. Id vel Nunc amet lacus dui magna ridiculus penatibus laoreet Duis. Enim sagittis nibh quis Nulla nec laoreet vel Maecenas mattis vel. + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    + + +
    + + + +

    {#wpeditimage.link_help}

    +
    + + + +
    + + + + +
    +
    +
    + + + diff --git a/src/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.dev.js b/src/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.dev.js new file mode 100644 index 00000000..ff3cb479 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.dev.js @@ -0,0 +1,219 @@ + +(function() { + tinymce.create('tinymce.plugins.wpEditImage', { + + init : function(ed, url) { + var t = this; + + t.url = url; + t._createButtons(); + + // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('...'); + ed.addCommand('WP_EditImage', function() { + var el = ed.selection.getNode(), vp = tinymce.DOM.getViewPort(), H = vp.h, W = ( 720 < vp.w ) ? 720 : vp.w, cls = ed.dom.getAttrib(el, 'class'); + + if ( cls.indexOf('mceItem') != -1 || cls.indexOf('wpGallery') != -1 || el.nodeName != 'IMG' ) + return; + + tb_show('', url + '/editimage.html?ver=321&TB_iframe=true'); + tinymce.DOM.setStyles('TB_window', { + 'width':( W - 50 )+'px', + 'height':( H - 45 )+'px', + 'margin-left':'-'+parseInt((( W - 50 ) / 2),10) + 'px' + }); + + if ( ! tinymce.isIE6 ) { + tinymce.DOM.setStyles('TB_window', { + 'top':'20px', + 'marginTop':'0' + }); + } + + tinymce.DOM.setStyles('TB_iframeContent', { + 'width':( W - 50 )+'px', + 'height':( H - 75 )+'px' + }); + tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' ); + }); + + ed.onInit.add(function(ed) { + tinymce.dom.Event.add(ed.getBody(), 'dragstart', function(e) { + if ( !tinymce.isGecko && e.target.nodeName == 'IMG' && ed.dom.getParent(e.target, 'dl.wp-caption') ) + return tinymce.dom.Event.cancel(e); + }); + }); + + // resize the caption
    when the image is soft-resized by the user (only possible in Firefox and IE) + ed.onMouseUp.add(function(ed, e) { + if ( tinymce.isWebKit || tinymce.isOpera ) + return; + + if ( ed.dom.getParent(e.target, 'div.mceTemp') || ed.dom.is(e.target, 'div.mceTemp') ) { + window.setTimeout(function(){ + var ed = tinyMCE.activeEditor, n = ed.selection.getNode(), DL, width; + + if ( 'IMG' == n.nodeName ) { + DL = ed.dom.getParent(n, 'dl.wp-caption'); + width = ed.dom.getAttrib(n, 'width') || n.width; + width = parseInt(width, 10); + + if ( DL && width != ( parseInt(ed.dom.getStyle(DL, 'width'), 10) - 10 ) ) { + ed.dom.setStyle(DL, 'width', 10 + width); + ed.execCommand('mceRepaint'); + } + } + }, 100); + } + }); + + // show editimage buttons + ed.onMouseDown.add(function(ed, e) { + var p; + + if ( e.target.nodeName == 'IMG' && ed.dom.getAttrib(e.target, 'class').indexOf('mceItem') == -1 ) { + ed.plugins.wordpress._showButtons(e.target, 'wp_editbtns'); + if ( tinymce.isGecko && (p = ed.dom.getParent(e.target, 'dl.wp-caption')) && ed.dom.hasClass(p.parentNode, 'mceTemp') ) + ed.selection.select(p.parentNode); + } + }); + + // when pressing Return inside a caption move the cursor to a new parapraph under it + ed.onKeyPress.add(function(ed, e) { + var n, DL, DIV, P; + + if ( e.keyCode == 13 ) { + n = ed.selection.getNode(); + DL = ed.dom.getParent(n, 'dl.wp-caption'); + DIV = ed.dom.getParent(DL, 'div.mceTemp'); + + if ( DL && DIV ) { + P = ed.dom.create('p', {}, ' '); + ed.dom.insertAfter( P, DIV ); + + if ( P.firstChild ) + ed.selection.select(P.firstChild); + else + ed.selection.select(P); + + tinymce.dom.Event.cancel(e); + return false; + } + } + }); + + ed.onBeforeSetContent.add(function(ed, o) { + o.content = t._do_shcode(o.content); + }); + + ed.onPostProcess.add(function(ed, o) { + if (o.get) + o.content = t._get_shcode(o.content); + }); + }, + + _do_shcode : function(co) { + return co.replace(/(?:

    )?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?[\s\u00a0]*/g, function(a,b,c){ + var id, cls, w, cap, div_cls; + + b = b.replace(/\\'|\\'|\\'/g, ''').replace(/\\"|\\"/g, '"'); + c = c.replace(/\\'|\\'/g, ''').replace(/\\"/g, '"'); + id = b.match(/id=['"]([^'"]+)/i); + cls = b.match(/align=['"]([^'"]+)/i); + w = b.match(/width=['"]([0-9]+)/); + cap = b.match(/caption=['"]([^'"]+)/i); + + id = ( id && id[1] ) ? id[1] : ''; + cls = ( cls && cls[1] ) ? cls[1] : 'alignnone'; + w = ( w && w[1] ) ? w[1] : ''; + cap = ( cap && cap[1] ) ? cap[1] : ''; + if ( ! w || ! cap ) return c; + + div_cls = (cls == 'aligncenter') ? 'mceTemp mceIEcenter' : 'mceTemp'; + + return '

    '+c+'
    '+cap+'
    '; + }); + }, + + _get_shcode : function(co) { + return co.replace(/
    \s*]+)>\s*]+>([\s\S]+?)<\/dt>\s*]+>(.+?)<\/dd>\s*<\/dl>\s*<\/div>\s*/gi, function(a,b,c,cap){ + var id, cls, w; + + id = b.match(/id=['"]([^'"]+)/i); + cls = b.match(/class=['"]([^'"]+)/i); + w = c.match(/width=['"]([0-9]+)/); + + id = ( id && id[1] ) ? id[1] : ''; + cls = ( cls && cls[1] ) ? cls[1] : 'alignnone'; + w = ( w && w[1] ) ? w[1] : ''; + + if ( ! w || ! cap ) return c; + cls = cls.match(/align[^ '"]+/) || 'alignnone'; + cap = cap.replace(/<\S[^<>]*>/gi, '').replace(/'/g, ''').replace(/"/g, '"'); + + return '[caption id="'+id+'" align="'+cls+'" width="'+w+'" caption="'+cap+'"]'+c+'[/caption]'; + }); + }, + + _createButtons : function() { + var t = this, ed = tinyMCE.activeEditor, DOM = tinymce.DOM, editButton, dellButton; + + DOM.remove('wp_editbtns'); + + DOM.add(document.body, 'div', { + id : 'wp_editbtns', + style : 'display:none;' + }); + + editButton = DOM.add('wp_editbtns', 'img', { + src : t.url+'/img/image.png', + id : 'wp_editimgbtn', + width : '24', + height : '24', + title : ed.getLang('wpeditimage.edit_img') + }); + + tinymce.dom.Event.add(editButton, 'mousedown', function(e) { + var ed = tinyMCE.activeEditor; + ed.windowManager.bookmark = ed.selection.getBookmark('simple'); + ed.execCommand("WP_EditImage"); + }); + + dellButton = DOM.add('wp_editbtns', 'img', { + src : t.url+'/img/delete.png', + id : 'wp_delimgbtn', + width : '24', + height : '24', + title : ed.getLang('wpeditimage.del_img') + }); + + tinymce.dom.Event.add(dellButton, 'mousedown', function(e) { + var ed = tinyMCE.activeEditor, el = ed.selection.getNode(), p; + + if ( el.nodeName == 'IMG' && ed.dom.getAttrib(el, 'class').indexOf('mceItem') == -1 ) { + if ( (p = ed.dom.getParent(el, 'div')) && ed.dom.hasClass(p, 'mceTemp') ) + ed.dom.remove(p); + else if ( (p = ed.dom.getParent(el, 'A')) && p.childNodes.length == 1 ) + ed.dom.remove(p); + else + ed.dom.remove(el); + + ed.execCommand('mceRepaint'); + return false; + } + }); + }, + + getInfo : function() { + return { + longname : 'Edit Image', + author : 'WordPress', + authorurl : 'http://wordpress.org', + infourl : '', + version : "1.0" + }; + } + }); + + tinymce.PluginManager.add('wpeditimage', tinymce.plugins.wpEditImage); +})(); diff --git a/src/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.js new file mode 100644 index 00000000..ece134b1 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.js @@ -0,0 +1 @@ +(function(){tinymce.create("tinymce.plugins.wpEditImage",{init:function(a,b){var c=this;c.url=b;c._createButtons();a.addCommand("WP_EditImage",function(){var h=a.selection.getNode(),f=tinymce.DOM.getViewPort(),g=f.h,d=(720)?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?[\s\u00a0]*/g,function(g,d,k){var j,f,e,h,i;d=d.replace(/\\'|\\'|\\'/g,"'").replace(/\\"|\\"/g,""");k=k.replace(/\\'|\\'/g,"'").replace(/\\"/g,""");j=d.match(/id=['"]([^'"]+)/i);f=d.match(/align=['"]([^'"]+)/i);e=d.match(/width=['"]([0-9]+)/);h=d.match(/caption=['"]([^'"]+)/i);j=(j&&j[1])?j[1]:"";f=(f&&f[1])?f[1]:"alignnone";e=(e&&e[1])?e[1]:"";h=(h&&h[1])?h[1]:"";if(!e||!h){return k}i=(f=="aligncenter")?"mceTemp mceIEcenter":"mceTemp";return'
    '+k+'
    '+h+"
    "})},_get_shcode:function(a){return a.replace(/
    \s*]+)>\s*]+>([\s\S]+?)<\/dt>\s*]+>(.+?)<\/dd>\s*<\/dl>\s*<\/div>\s*/gi,function(g,d,j,h){var i,f,e;i=d.match(/id=['"]([^'"]+)/i);f=d.match(/class=['"]([^'"]+)/i);e=j.match(/width=['"]([0-9]+)/);i=(i&&i[1])?i[1]:"";f=(f&&f[1])?f[1]:"alignnone";e=(e&&e[1])?e[1]:"";if(!e||!h){return j}f=f.match(/align[^ '"]+/)||"alignnone";h=h.replace(/<\S[^<>]*>/gi,"").replace(/'/g,"'").replace(/"/g,""");return'[caption id="'+i+'" align="'+f+'" width="'+e+'" caption="'+h+'"]'+j+"[/caption]"})},_createButtons:function(){var b=this,a=tinyMCE.activeEditor,d=tinymce.DOM,e,c;d.remove("wp_editbtns");d.add(document.body,"div",{id:"wp_editbtns",style:"display:none;"});e=d.add("wp_editbtns","img",{src:b.url+"/img/image.png",id:"wp_editimgbtn",width:"24",height:"24",title:a.getLang("wpeditimage.edit_img")});tinymce.dom.Event.add(e,"mousedown",function(g){var f=tinyMCE.activeEditor;f.windowManager.bookmark=f.selection.getBookmark("simple");f.execCommand("WP_EditImage")});c=d.add("wp_editbtns","img",{src:b.url+"/img/delete.png",id:"wp_delimgbtn",width:"24",height:"24",title:a.getLang("wpeditimage.del_img")});tinymce.dom.Event.add(c,"mousedown",function(i){var f=tinyMCE.activeEditor,g=f.selection.getNode(),h;if(g.nodeName=="IMG"&&f.dom.getAttrib(g,"class").indexOf("mceItem")==-1){if((h=f.dom.getParent(g,"div"))&&f.dom.hasClass(h,"mceTemp")){f.dom.remove(h)}else{if((h=f.dom.getParent(g,"A"))&&h.childNodes.length==1){f.dom.remove(h)}else{f.dom.remove(g)}}f.execCommand("mceRepaint");return false}})},getInfo:function(){return{longname:"Edit Image",author:"WordPress",authorurl:"http://wordpress.org",infourl:"",version:"1.0"}}});tinymce.PluginManager.add("wpeditimage",tinymce.plugins.wpEditImage)})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wpeditimage/img/delete.png b/src/wp-includes/js/tinymce/plugins/wpeditimage/img/delete.png new file mode 100644 index 00000000..d64d8a66 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wpeditimage/img/delete.png differ diff --git a/src/wp-includes/js/tinymce/plugins/wpeditimage/img/image.png b/src/wp-includes/js/tinymce/plugins/wpeditimage/img/image.png new file mode 100644 index 00000000..f3d4b449 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wpeditimage/img/image.png differ diff --git a/src/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js b/src/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js new file mode 100644 index 00000000..1acf9f04 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js @@ -0,0 +1,613 @@ + +var tinymce = null, tinyMCEPopup, tinyMCE, wpImage; + +tinyMCEPopup = { + init: function() { + var t = this, w, li, q, i, it; + + li = ('' + document.location.search).replace(/^\?/, '').split('&'); + q = {}; + for ( i = 0; i < li.length; i++ ) { + it = li[i].split('='); + q[unescape(it[0])] = unescape(it[1]); + } + + if (q.mce_rdomain) + document.domain = q.mce_rdomain; + + // Find window & API + w = t.getWin(); + tinymce = w.tinymce; + tinyMCE = w.tinyMCE; + t.editor = tinymce.EditorManager.activeEditor; + t.params = t.editor.windowManager.params; + + // Setup local DOM + t.dom = t.editor.windowManager.createInstance('tinymce.dom.DOMUtils', document); + t.editor.windowManager.onOpen.dispatch(t.editor.windowManager, window); + }, + + getWin : function() { + return window.dialogArguments || opener || parent || top; + }, + + getParam : function(n, dv) { + return this.editor.getParam(n, dv); + }, + + close : function() { + var t = this, win = t.getWin(); + + // To avoid domain relaxing issue in Opera + function close() { + win.tb_remove(); + tinymce = tinyMCE = t.editor = t.dom = t.dom.doc = null; // Cleanup + }; + + if (tinymce.isOpera) + win.setTimeout(close, 0); + else + close(); + }, + + execCommand : function(cmd, ui, val, a) { + a = a || {}; + a.skip_focus = 1; + + this.restoreSelection(); + return this.editor.execCommand(cmd, ui, val, a); + }, + + storeSelection : function() { + this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark('simple'); + }, + + restoreSelection : function() { + var t = tinyMCEPopup; + + if (tinymce.isIE) + t.editor.selection.moveToBookmark(t.editor.windowManager.bookmark); + } +} +tinyMCEPopup.init(); + +wpImage = { + preInit : function() { + // import colors stylesheet from parent + var win = tinyMCEPopup.getWin(), styles = win.document.styleSheets, url, i; + + for ( i = 0; i < styles.length; i++ ) { + url = styles.item(i).href; + if ( url && url.indexOf('colors') != -1 ) + document.write( '' ); + } + }, + + I : function(e) { + return document.getElementById(e); + }, + + current : '', + link : '', + link_rel : '', + target_value : '', + current_size_sel : 's100', + width : '', + height : '', + align : '', + img_alt : '', + + setTabs : function(tab) { + var t = this; + + if ( 'current' == tab.className ) return false; + t.I('div_advanced').style.display = ( 'tab_advanced' == tab.id ) ? 'block' : 'none'; + t.I('div_basic').style.display = ( 'tab_basic' == tab.id ) ? 'block' : 'none'; + t.I('tab_basic').className = t.I('tab_advanced').className = ''; + tab.className = 'current'; + return false; + }, + + img_seturl : function(u) { + var t = this, rel = t.I('link_rel').value; + + if ( 'current' == u ) { + t.I('link_href').value = t.current; + t.I('link_rel').value = t.link_rel; + } else { + t.I('link_href').value = t.link; + if ( rel ) { + rel = rel.replace( /attachment|wp-att-[0-9]+/gi, '' ); + t.I('link_rel').value = tinymce.trim(rel); + } + } + }, + + imgAlignCls : function(v) { + var t = this, cls = t.I('img_classes').value; + + t.I('img_demo').className = t.align = v; + + cls = cls.replace( /align[^ "']+/gi, '' ); + cls += (' ' + v); + cls = cls.replace( /\s+/g, ' ' ).replace( /^\s/, '' ); + + if ( 'aligncenter' == v ) { + t.I('hspace').value = ''; + t.updateStyle('hspace'); + } + + t.I('img_classes').value = cls; + }, + + showSize : function(el) { + var t = this, demo = t.I('img_demo'), w = t.width, h = t.height, id = el.id || 's100', size; + + size = parseInt(id.substring(1)) / 200; + demo.width = Math.round(w * size); + demo.height = Math.round(h * size); + + t.showSizeClear(); + el.style.borderColor = '#A3A3A3'; + el.style.backgroundColor = '#E5E5E5'; + }, + + showSizeSet : function() { + var t = this, s130, s120, s110; + + if ( (t.width * 1.3) > parseInt(t.preloadImg.width) ) { + s130 = t.I('s130'), s120 = t.I('s120'), s110 = t.I('s110'); + + s130.onclick = s120.onclick = s110.onclick = null; + s130.onmouseover = s120.onmouseover = s110.onmouseover = null; + s130.style.color = s120.style.color = s110.style.color = '#aaa'; + } + }, + + showSizeRem : function() { + var t = this, demo = t.I('img_demo'), f = document.forms[0]; + + demo.width = Math.round(f.width.value * 0.5); + demo.height = Math.round(f.height.value * 0.5); + t.showSizeClear(); + t.I(t.current_size_sel).style.borderColor = '#A3A3A3'; + t.I(t.current_size_sel).style.backgroundColor = '#E5E5E5'; + + return false; + }, + + showSizeClear : function() { + var divs = this.I('img_size').getElementsByTagName('div'), i; + + for ( i = 0; i < divs.length; i++ ) { + divs[i].style.borderColor = '#f1f1f1'; + divs[i].style.backgroundColor = '#f1f1f1'; + } + }, + + imgEditSize : function(el) { + var t = this, f = document.forms[0], W, H, w, h, id; + + if ( ! t.preloadImg || ! t.preloadImg.width || ! t.preloadImg.height ) + return; + + W = parseInt(t.preloadImg.width), H = parseInt(t.preloadImg.height), w = t.width || W, h = t.height || H, id = el.id || 's100'; + + size = parseInt(id.substring(1)) / 100; + + w = Math.round(w * size); + h = Math.round(h * size); + + f.width.value = Math.min(W, w); + f.height.value = Math.min(H, h); + + t.current_size_sel = id; + t.demoSetSize(); + }, + + demoSetSize : function(img) { + var demo = this.I('img_demo'), f = document.forms[0]; + + demo.width = f.width.value ? Math.round(f.width.value * 0.5) : ''; + demo.height = f.height.value ? Math.round(f.height.value * 0.5) : ''; + }, + + demoSetStyle : function() { + var f = document.forms[0], demo = this.I('img_demo'), dom = tinyMCEPopup.editor.dom; + + if (demo) { + dom.setAttrib(demo, 'style', f.img_style.value); + dom.setStyle(demo, 'width', ''); + dom.setStyle(demo, 'height', ''); + } + }, + + origSize : function() { + var t = this, f = document.forms[0], el = t.I('s100'); + + f.width.value = t.width = t.preloadImg.width; + f.height.value = t.height = t.preloadImg.height; + t.showSizeSet(); + t.demoSetSize(); + t.showSize(el); + }, + + init : function() { + var ed = tinyMCEPopup.editor, h; + + h = document.body.innerHTML; + document.body.innerHTML = ed.translate(h); + window.setTimeout( function(){wpImage.setup();}, 500 ); + }, + + setup : function() { + var t = this, c, el, link, fname, f = document.forms[0], ed = tinyMCEPopup.editor, + d = t.I('img_demo'), dom = tinyMCEPopup.dom, DL, caption = '', dlc, pa; + + document.dir = tinyMCEPopup.editor.getParam('directionality',''); + + if ( tinyMCEPopup.editor.getParam('wpeditimage_disable_captions', false) ) + t.I('cap_field').style.display = 'none'; + + tinyMCEPopup.restoreSelection(); + el = ed.selection.getNode(); + if (el.nodeName != 'IMG') + return; + + f.img_src.value = d.src = link = ed.dom.getAttrib(el, 'src'); + ed.dom.setStyle(el, 'float', ''); + t.getImageData(); + c = ed.dom.getAttrib(el, 'class'); + + if ( DL = dom.getParent(el, 'dl') ) { + dlc = ed.dom.getAttrib(DL, 'class'); + dlc = dlc.match(/align[^ "']+/i); + if ( dlc && ! dom.hasClass(el, dlc) ) { + c += ' '+dlc; + tinymce.trim(c); + } + + tinymce.each(DL.childNodes, function(e) { + if ( e.nodeName == 'DD' && dom.hasClass(e, 'wp-caption-dd') ) { + caption = e.innerHTML; + return; + } + }); + } + + f.img_cap.value = caption; + f.img_title.value = ed.dom.getAttrib(el, 'title'); + f.img_alt.value = ed.dom.getAttrib(el, 'alt'); + f.border.value = ed.dom.getAttrib(el, 'border'); + f.vspace.value = ed.dom.getAttrib(el, 'vspace'); + f.hspace.value = ed.dom.getAttrib(el, 'hspace'); + f.align.value = ed.dom.getAttrib(el, 'align'); + f.width.value = t.width = ed.dom.getAttrib(el, 'width'); + f.height.value = t.height = ed.dom.getAttrib(el, 'height'); + f.img_classes.value = c; + f.img_style.value = ed.dom.getAttrib(el, 'style'); + + // Move attribs to styles + if ( dom.getAttrib(el, 'hspace') ) + t.updateStyle('hspace'); + + if ( dom.getAttrib(el, 'border') ) + t.updateStyle('border'); + + if ( dom.getAttrib(el, 'vspace') ) + t.updateStyle('vspace'); + + if ( pa = ed.dom.getParent(el, 'A') ) { + f.link_href.value = t.current = ed.dom.getAttrib(pa, 'href'); + f.link_title.value = ed.dom.getAttrib(pa, 'title'); + f.link_rel.value = t.link_rel = ed.dom.getAttrib(pa, 'rel'); + f.link_style.value = ed.dom.getAttrib(pa, 'style'); + t.target_value = ed.dom.getAttrib(pa, 'target'); + f.link_classes.value = ed.dom.getAttrib(pa, 'class'); + } + + f.link_target.checked = ( t.target_value && t.target_value == '_blank' ) ? 'checked' : ''; + + fname = link.substring( link.lastIndexOf('/') ); + fname = fname.replace(/-[0-9]{2,4}x[0-9]{2,4}/, '' ); + t.link = link.substring( 0, link.lastIndexOf('/') ) + fname; + + if ( c.indexOf('alignleft') != -1 ) { + t.I('alignleft').checked = "checked"; + d.className = t.align = "alignleft"; + } else if ( c.indexOf('aligncenter') != -1 ) { + t.I('aligncenter').checked = "checked"; + d.className = t.align = "aligncenter"; + } else if ( c.indexOf('alignright') != -1 ) { + t.I('alignright').checked = "checked"; + d.className = t.align = "alignright"; + } else if ( c.indexOf('alignnone') != -1 ) { + t.I('alignnone').checked = "checked"; + d.className = t.align = "alignnone"; + } + + if ( t.width && t.preloadImg.width ) t.showSizeSet(); + document.body.style.display = ''; + }, + + remove : function() { + var ed = tinyMCEPopup.editor, p, el; + + tinyMCEPopup.restoreSelection(); + el = ed.selection.getNode(); + if (el.nodeName != 'IMG') return; + + if ( (p = ed.dom.getParent(el, 'div')) && ed.dom.hasClass(p, 'mceTemp') ) + ed.dom.remove(p); + else if ( (p = ed.dom.getParent(el, 'A')) && p.childNodes.length == 1 ) + ed.dom.remove(p); + else ed.dom.remove(el); + + ed.execCommand('mceRepaint'); + tinyMCEPopup.close(); + return; + }, + + update : function() { + var t = this, f = document.forms[0], ed = tinyMCEPopup.editor, el, b, fixSafari = null, + DL, P, A, DIV, do_caption = null, img_class = f.img_classes.value, html, + id, cap_id = '', cap, DT, DD, cap_width, div_cls, lnk = '', pa, aa; + + tinyMCEPopup.restoreSelection(); + el = ed.selection.getNode(); + + if (el.nodeName != 'IMG') return; + if (f.img_src.value === '') { + t.remove(); + return; + } + + if ( f.img_cap.value != '' && f.width.value != '' ) { + do_caption = 1; + img_class = img_class.replace( /align[^ "']+\s?/gi, '' ); + } + + A = ed.dom.getParent(el, 'a'); + P = ed.dom.getParent(el, 'p'); + DL = ed.dom.getParent(el, 'dl'); + DIV = ed.dom.getParent(el, 'div'); + + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + + ed.dom.setAttribs(el, { + src : f.img_src.value, + title : f.img_title.value, + alt : f.img_alt.value, + width : f.width.value, + height : f.height.value, + style : f.img_style.value, + 'class' : img_class + }); + + if ( f.link_href.value ) { + // Create new anchor elements + if ( A == null ) { + if ( ! f.link_href.value.match(/https?:\/\//i) ) + f.link_href.value = tinyMCEPopup.editor.documentBaseURI.toAbsolute(f.link_href.value); + + if ( tinymce.isWebKit && ed.dom.hasClass(el, 'aligncenter') ) { + ed.dom.removeClass(el, 'aligncenter'); + fixSafari = 1; + } + + tinyMCEPopup.execCommand("CreateLink", false, "#mce_temp_url#", {skip_undo : 1}); + if ( fixSafari ) ed.dom.addClass(el, 'aligncenter'); + + tinymce.each(ed.dom.select("a"), function(n) { + if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') { + + ed.dom.setAttribs(n, { + href : f.link_href.value, + title : f.link_title.value, + rel : f.link_rel.value, + target : (f.link_target.checked == true) ? '_blank' : '', + 'class' : f.link_classes.value, + style : f.link_style.value + }); + } + }); + } else { + ed.dom.setAttribs(A, { + href : f.link_href.value, + title : f.link_title.value, + rel : f.link_rel.value, + target : (f.link_target.checked == true) ? '_blank' : '', + 'class' : f.link_classes.value, + style : f.link_style.value + }); + } + } + + if ( do_caption ) { + cap_width = 10 + parseInt(f.width.value); + div_cls = (t.align == 'aligncenter') ? 'mceTemp mceIEcenter' : 'mceTemp'; + + if ( DL ) { + ed.dom.setAttribs(DL, { + 'class' : 'wp-caption '+t.align, + style : 'width: '+cap_width+'px;' + }); + + if ( DIV ) + ed.dom.setAttrib(DIV, 'class', div_cls); + + if ( (DT = ed.dom.getParent(el, 'dt')) && (DD = DT.nextSibling) && ed.dom.hasClass(DD, 'wp-caption-dd') ) + ed.dom.setHTML(DD, f.img_cap.value); + + } else { + if ( (id = f.img_classes.value.match( /wp-image-([0-9]{1,6})/ )) && id[1] ) + cap_id = 'attachment_'+id[1]; + + if ( f.link_href.value && (lnk = ed.dom.getParent(el, 'a')) ) { + if ( lnk.childNodes.length == 1 ) + html = ed.dom.getOuterHTML(lnk); + else { + html = ed.dom.getOuterHTML(lnk); + html = html.match(/]+>/i); + html = html+ed.dom.getOuterHTML(el)+''; + } + } else html = ed.dom.getOuterHTML(el); + + html = '
    '+html+'
    '+f.img_cap.value+'
    '; + + cap = ed.dom.create('div', {'class': div_cls}, html); + + if ( P ) { + P.parentNode.insertBefore(cap, P); + if ( P.childNodes.length == 1 ) + ed.dom.remove(P); + else if ( lnk && lnk.childNodes.length == 1 ) + ed.dom.remove(lnk); + else ed.dom.remove(el); + } else if ( pa = ed.dom.getParent(el, 'TD,TH,LI') ) { + pa.appendChild(cap); + if ( lnk && lnk.childNodes.length == 1 ) + ed.dom.remove(lnk); + else ed.dom.remove(el); + } + } + + } else { + if ( DL && DIV ) { + if ( f.link_href.value && (aa = ed.dom.getParent(el, 'a')) ) html = ed.dom.getOuterHTML(aa); + else html = ed.dom.getOuterHTML(el); + + P = ed.dom.create('p', {}, html); + DIV.parentNode.insertBefore(P, DIV); + ed.dom.remove(DIV); + } + } + + if ( f.img_classes.value.indexOf('aligncenter') != -1 ) { + if ( P && ( ! P.style || P.style.textAlign != 'center' ) ) + ed.dom.setStyle(P, 'textAlign', 'center'); + } else { + if ( P && P.style && P.style.textAlign == 'center' ) + ed.dom.setStyle(P, 'textAlign', ''); + } + + if ( ! f.link_href.value && A ) { + b = ed.selection.getBookmark(); + ed.dom.remove(A, 1); + ed.selection.moveToBookmark(b); + } + + tinyMCEPopup.execCommand("mceEndUndoLevel"); + ed.execCommand('mceRepaint'); + tinyMCEPopup.close(); + }, + + updateStyle : function(ty) { + var dom = tinyMCEPopup.dom, v, f = document.forms[0], img = dom.create('img', {style : f.img_style.value}); + + if (tinyMCEPopup.editor.settings.inline_styles) { + // Handle align + if (ty == 'align') { + dom.setStyle(img, 'float', ''); + dom.setStyle(img, 'vertical-align', ''); + + v = f.align.value; + if (v) { + if (v == 'left' || v == 'right') + dom.setStyle(img, 'float', v); + else + img.style.verticalAlign = v; + } + } + + // Handle border + if (ty == 'border') { + dom.setStyle(img, 'border', ''); + + v = f.border.value; + if (v || v == '0') { + if (v == '0') + img.style.border = '0'; + else + img.style.border = v + 'px solid black'; + } + } + + // Handle hspace + if (ty == 'hspace') { + dom.setStyle(img, 'marginLeft', ''); + dom.setStyle(img, 'marginRight', ''); + + v = f.hspace.value; + if (v) { + img.style.marginLeft = v + 'px'; + img.style.marginRight = v + 'px'; + } + } + + // Handle vspace + if (ty == 'vspace') { + dom.setStyle(img, 'marginTop', ''); + dom.setStyle(img, 'marginBottom', ''); + + v = f.vspace.value; + if (v) { + img.style.marginTop = v + 'px'; + img.style.marginBottom = v + 'px'; + } + } + + // Merge + f.img_style.value = dom.serializeStyle(dom.parseStyle(img.style.cssText)); + this.demoSetStyle(); + } + }, + + checkVal : function(f) { + + if ( f.value == '' ) { + // if ( f.id == 'width' ) f.value = this.width || this.preloadImg.width; + // if ( f.id == 'height' ) f.value = this.height || this.preloadImg.height; + if ( f.id == 'img_src' ) f.value = this.I('img_demo').src || this.preloadImg.src; + } + }, + + resetImageData : function() { + var f = document.forms[0]; + + f.width.value = f.height.value = ''; + }, + + updateImageData : function() { + var f = document.forms[0], t = wpImage, w = f.width.value, h = f.height.value; + + if ( !w && h ) + w = f.width.value = t.width = Math.round( t.preloadImg.width / (t.preloadImg.height / h) ); + else if ( w && !h ) + h = f.height.value = t.height = Math.round( t.preloadImg.height / (t.preloadImg.width / w) ); + + if ( !w ) + f.width.value = t.width = t.preloadImg.width; + + if ( !h ) + f.height.value = t.height = t.preloadImg.height; + + t.showSizeSet(); + t.demoSetSize(); + if ( f.img_style.value ) + t.demoSetStyle(); + }, + + getImageData : function() { + var t = wpImage, f = document.forms[0]; + + t.preloadImg = new Image(); + t.preloadImg.onload = t.updateImageData; + t.preloadImg.onerror = t.resetImageData; + t.preloadImg.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(f.img_src.value); + } +}; + +window.onload = function(){wpImage.init();} +wpImage.preInit(); diff --git a/src/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.js b/src/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.js new file mode 100644 index 00000000..0a801bd5 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.js @@ -0,0 +1 @@ +var tinymce=null,tinyMCEPopup,tinyMCE,wpImage;tinyMCEPopup={init:function(){var d=this,b,a,f,c,e;a=(""+document.location.search).replace(/^\?/,"").split("&");f={};for(c=0;c')}}},I:function(a){return document.getElementById(a)},current:"",link:"",link_rel:"",target_value:"",current_size_sel:"s100",width:"",height:"",align:"",img_alt:"",setTabs:function(b){var a=this;if("current"==b.className){return false}a.I("div_advanced").style.display=("tab_advanced"==b.id)?"block":"none";a.I("div_basic").style.display=("tab_basic"==b.id)?"block":"none";a.I("tab_basic").className=a.I("tab_advanced").className="";b.className="current";return false},img_seturl:function(b){var c=this,a=c.I("link_rel").value;if("current"==b){c.I("link_href").value=c.current;c.I("link_rel").value=c.link_rel}else{c.I("link_href").value=c.link;if(a){a=a.replace(/attachment|wp-att-[0-9]+/gi,"");c.I("link_rel").value=tinymce.trim(a)}}},imgAlignCls:function(b){var c=this,a=c.I("img_classes").value;c.I("img_demo").className=c.align=b;a=a.replace(/align[^ "']+/gi,"");a+=(" "+b);a=a.replace(/\s+/g," ").replace(/^\s/,"");if("aligncenter"==b){c.I("hspace").value="";c.updateStyle("hspace")}c.I("img_classes").value=a},showSize:function(e){var c=this,f=c.I("img_demo"),a=c.width,d=c.height,g=e.id||"s100",b;b=parseInt(g.substring(1))/200;f.width=Math.round(a*b);f.height=Math.round(d*b);c.showSizeClear();e.style.borderColor="#A3A3A3";e.style.backgroundColor="#E5E5E5"},showSizeSet:function(){var b=this,d,c,a;if((b.width*1.3)>parseInt(b.preloadImg.width)){d=b.I("s130"),c=b.I("s120"),a=b.I("s110");d.onclick=c.onclick=a.onclick=null;d.onmouseover=c.onmouseover=a.onmouseover=null;d.style.color=c.style.color=a.style.color="#aaa"}},showSizeRem:function(){var a=this,c=a.I("img_demo"),b=document.forms[0];c.width=Math.round(b.width.value*0.5);c.height=Math.round(b.height.value*0.5);a.showSizeClear();a.I(a.current_size_sel).style.borderColor="#A3A3A3";a.I(a.current_size_sel).style.backgroundColor="#E5E5E5";return false},showSizeClear:function(){var b=this.I("img_size").getElementsByTagName("div"),a;for(a=0;a]+>/i);l=l+g.dom.getOuterHTML(e)+""}}else{l=g.dom.getOuterHTML(e)}l='
    '+l+'
    '+v.img_cap.value+"
    ";j=g.dom.create("div",{"class":z},l);if(h){h.parentNode.insertBefore(j,h);if(h.childNodes.length==1){g.dom.remove(h)}else{if(w&&w.childNodes.length==1){g.dom.remove(w)}else{g.dom.remove(e)}}}else{if(c=g.dom.getParent(e,"TD,TH,LI")){c.appendChild(j);if(w&&w.childNodes.length==1){g.dom.remove(w)}else{g.dom.remove(e)}}}}}else{if(n&&r){if(v.link_href.value&&(y=g.dom.getParent(e,"a"))){l=g.dom.getOuterHTML(y)}else{l=g.dom.getOuterHTML(e)}h=g.dom.create("p",{},l);r.parentNode.insertBefore(h,r);g.dom.remove(r)}}if(v.img_classes.value.indexOf("aligncenter")!=-1){if(h&&(!h.style||h.style.textAlign!="center")){g.dom.setStyle(h,"textAlign","center")}}else{if(h&&h.style&&h.style.textAlign=="center"){g.dom.setStyle(h,"textAlign","")}}if(!v.link_href.value&&p){x=g.selection.getBookmark();g.dom.remove(p,1);g.selection.moveToBookmark(x)}tinyMCEPopup.execCommand("mceEndUndoLevel");g.execCommand("mceRepaint");tinyMCEPopup.close()},updateStyle:function(a){var e=tinyMCEPopup.dom,c,d=document.forms[0],b=e.create("img",{style:d.img_style.value});if(tinyMCEPopup.editor.settings.inline_styles){if(a=="align"){e.setStyle(b,"float","");e.setStyle(b,"vertical-align","");c=d.align.value;if(c){if(c=="left"||c=="right"){e.setStyle(b,"float",c)}else{b.style.verticalAlign=c}}}if(a=="border"){e.setStyle(b,"border","");c=d.border.value;if(c||c=="0"){if(c=="0"){b.style.border="0"}else{b.style.border=c+"px solid black"}}}if(a=="hspace"){e.setStyle(b,"marginLeft","");e.setStyle(b,"marginRight","");c=d.hspace.value;if(c){b.style.marginLeft=c+"px";b.style.marginRight=c+"px"}}if(a=="vspace"){e.setStyle(b,"marginTop","");e.setStyle(b,"marginBottom","");c=d.vspace.value;if(c){b.style.marginTop=c+"px";b.style.marginBottom=c+"px"}}d.img_style.value=e.serializeStyle(e.parseStyle(b.style.cssText));this.demoSetStyle()}},checkVal:function(a){if(a.value==""){if(a.id=="img_src"){a.value=this.I("img_demo").src||this.preloadImg.src}}},resetImageData:function(){var a=document.forms[0];a.width.value=a.height.value=""},updateImageData:function(){var d=document.forms[0],b=wpImage,a=d.width.value,c=d.height.value;if(!a&&c){a=d.width.value=b.width=Math.round(b.preloadImg.width/(b.preloadImg.height/c))}else{if(a&&!c){c=d.height.value=b.height=Math.round(b.preloadImg.height/(b.preloadImg.width/a))}}if(!a){d.width.value=b.width=b.preloadImg.width}if(!c){d.height.value=b.height=b.preloadImg.height}b.showSizeSet();b.demoSetSize();if(d.img_style.value){b.demoSetStyle()}},getImageData:function(){var a=wpImage,b=document.forms[0];a.preloadImg=new Image();a.preloadImg.onload=a.updateImageData;a.preloadImg.onerror=a.resetImageData;a.preloadImg.src=tinyMCEPopup.editor.documentBaseURI.toAbsolute(b.img_src.value)}};window.onload=function(){wpImage.init()};wpImage.preInit(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.dev.js b/src/wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.dev.js new file mode 100644 index 00000000..6f571848 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.dev.js @@ -0,0 +1,119 @@ + +(function() { + tinymce.create('tinymce.plugins.wpGallery', { + + init : function(ed, url) { + var t = this; + + t.url = url; + t._createButtons(); + + // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('...'); + ed.addCommand('WP_Gallery', function() { + var el = ed.selection.getNode(), post_id, vp = tinymce.DOM.getViewPort(), + H = vp.h - 80, W = ( 640 < vp.w ) ? 640 : vp.w; + + if ( el.nodeName != 'IMG' ) return; + if ( ed.dom.getAttrib(el, 'class').indexOf('wpGallery') == -1 ) return; + + post_id = tinymce.DOM.get('post_ID').value; + tb_show('', tinymce.documentBaseURL + '/media-upload.php?post_id='+post_id+'&tab=gallery&TB_iframe=true&width='+W+'&height='+H); + + tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' ); + }); + + ed.onMouseDown.add(function(ed, e) { + if ( e.target.nodeName == 'IMG' && ed.dom.hasClass(e.target, 'wpGallery') ) + ed.plugins.wordpress._showButtons(e.target, 'wp_gallerybtns'); + }); + + ed.onBeforeSetContent.add(function(ed, o) { + o.content = t._do_gallery(o.content); + }); + + ed.onPostProcess.add(function(ed, o) { + if (o.get) + o.content = t._get_gallery(o.content); + }); + }, + + _do_gallery : function(co) { + return co.replace(/\[gallery([^\]]*)\]/g, function(a,b){ + return ''; + }); + }, + + _get_gallery : function(co) { + + function getAttr(s, n) { + n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s); + return n ? tinymce.DOM.decode(n[1]) : ''; + }; + + return co.replace(/(?:]*>)*(]+>)(?:<\/p>)*/g, function(a,im) { + var cls = getAttr(im, 'class'); + + if ( cls.indexOf('wpGallery') != -1 ) + return '

    ['+tinymce.trim(getAttr(im, 'title'))+']

    '; + + return a; + }); + }, + + _createButtons : function() { + var t = this, ed = tinyMCE.activeEditor, DOM = tinymce.DOM, editButton, dellButton; + + DOM.remove('wp_gallerybtns'); + + DOM.add(document.body, 'div', { + id : 'wp_gallerybtns', + style : 'display:none;' + }); + + editButton = DOM.add('wp_gallerybtns', 'img', { + src : t.url+'/img/edit.png', + id : 'wp_editgallery', + width : '24', + height : '24', + title : ed.getLang('wordpress.editgallery') + }); + + tinymce.dom.Event.add(editButton, 'mousedown', function(e) { + var ed = tinyMCE.activeEditor; + ed.windowManager.bookmark = ed.selection.getBookmark('simple'); + ed.execCommand("WP_Gallery"); + }); + + dellButton = DOM.add('wp_gallerybtns', 'img', { + src : t.url+'/img/delete.png', + id : 'wp_delgallery', + width : '24', + height : '24', + title : ed.getLang('wordpress.delgallery') + }); + + tinymce.dom.Event.add(dellButton, 'mousedown', function(e) { + var ed = tinyMCE.activeEditor, el = ed.selection.getNode(); + + if ( el.nodeName == 'IMG' && ed.dom.hasClass(el, 'wpGallery') ) { + ed.dom.remove(el); + + ed.execCommand('mceRepaint'); + return false; + } + }); + }, + + getInfo : function() { + return { + longname : 'Gallery Settings', + author : 'WordPress', + authorurl : 'http://wordpress.org', + infourl : '', + version : "1.0" + }; + } + }); + + tinymce.PluginManager.add('wpgallery', tinymce.plugins.wpGallery); +})(); diff --git a/src/wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.js new file mode 100644 index 00000000..0c2824ac --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.js @@ -0,0 +1 @@ +(function(){tinymce.create("tinymce.plugins.wpGallery",{init:function(a,b){var c=this;c.url=b;c._createButtons();a.addCommand("WP_Gallery",function(){var h=a.selection.getNode(),f,e=tinymce.DOM.getViewPort(),g=e.h-80,d=(640'})},_get_gallery:function(b){function a(c,d){d=new RegExp(d+'="([^"]+)"',"g").exec(c);return d?tinymce.DOM.decode(d[1]):""}return b.replace(/(?:]*>)*(]+>)(?:<\/p>)*/g,function(e,d){var c=a(d,"class");if(c.indexOf("wpGallery")!=-1){return"

    ["+tinymce.trim(a(d,"title"))+"]

    "}return e})},_createButtons:function(){var b=this,a=tinyMCE.activeEditor,d=tinymce.DOM,e,c;d.remove("wp_gallerybtns");d.add(document.body,"div",{id:"wp_gallerybtns",style:"display:none;"});e=d.add("wp_gallerybtns","img",{src:b.url+"/img/edit.png",id:"wp_editgallery",width:"24",height:"24",title:a.getLang("wordpress.editgallery")});tinymce.dom.Event.add(e,"mousedown",function(g){var f=tinyMCE.activeEditor;f.windowManager.bookmark=f.selection.getBookmark("simple");f.execCommand("WP_Gallery")});c=d.add("wp_gallerybtns","img",{src:b.url+"/img/delete.png",id:"wp_delgallery",width:"24",height:"24",title:a.getLang("wordpress.delgallery")});tinymce.dom.Event.add(c,"mousedown",function(h){var f=tinyMCE.activeEditor,g=f.selection.getNode();if(g.nodeName=="IMG"&&f.dom.hasClass(g,"wpGallery")){f.dom.remove(g);f.execCommand("mceRepaint");return false}})},getInfo:function(){return{longname:"Gallery Settings",author:"WordPress",authorurl:"http://wordpress.org",infourl:"",version:"1.0"}}});tinymce.PluginManager.add("wpgallery",tinymce.plugins.wpGallery)})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wpgallery/img/delete.png b/src/wp-includes/js/tinymce/plugins/wpgallery/img/delete.png new file mode 100644 index 00000000..d64d8a66 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wpgallery/img/delete.png differ diff --git a/src/wp-includes/js/tinymce/plugins/wpgallery/img/edit.png b/src/wp-includes/js/tinymce/plugins/wpgallery/img/edit.png new file mode 100644 index 00000000..41def511 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wpgallery/img/edit.png differ diff --git a/src/wp-includes/js/tinymce/plugins/wpgallery/img/gallery.png b/src/wp-includes/js/tinymce/plugins/wpgallery/img/gallery.png new file mode 100644 index 00000000..803ad630 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wpgallery/img/gallery.png differ diff --git a/src/wp-includes/js/tinymce/plugins/wpgallery/img/t.gif b/src/wp-includes/js/tinymce/plugins/wpgallery/img/t.gif new file mode 100644 index 00000000..38848651 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wpgallery/img/t.gif differ diff --git a/src/wp-includes/js/tinymce/plugins/wplink/css/wplink-rtl.css b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink-rtl.css new file mode 100644 index 00000000..6d0d4c32 --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink-rtl.css @@ -0,0 +1 @@ +#wp-link #internal-toggle{padding-right:18px;padding-left:0;}#wp-link label span{text-align:left;padding-left:5px;padding-right:0;}#wp-link .link-search-wrapper span{float:right;}#wp-link .link-search-wrapper input[type="text"]{float:right;}#wp-link .link-search-wrapper img.waiting{margin:8px 4px 0 1px;float:right;}#wp-link .link-target{margin:0 87px 0 0;}#wp-link .item-info{left:5px;right:auto;top:4px;bottom:0;}#wp-link #search-panel{float:right;}#wp-link-cancel{float:right;}#wp-link-update{float:left;}#wp-link .toggle-arrow{background-position:bottom right;}#wp-link .toggle-arrow-active{background-position:center right;} \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wplink/css/wplink-rtl.dev.css b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink-rtl.dev.css new file mode 100644 index 00000000..d64f198b --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink-rtl.dev.css @@ -0,0 +1,54 @@ +#wp-link #internal-toggle { + padding-right: 18px; + padding-left: 0; +} + +#wp-link label span { + text-align: left; + padding-left: 5px; + padding-right: 0; +} + +#wp-link .link-search-wrapper span { + float: right; +} + +#wp-link .link-search-wrapper input[type="text"] { + float: right; +} + +#wp-link .link-search-wrapper img.waiting { + margin: 8px 4px 0 1px; + float: right; +} + +#wp-link .link-target { + margin: 0 87px 0 0; +} + +#wp-link .item-info { + left: 5px; + right: auto; + top: 4px; + bottom: 0; +} + +#wp-link #search-panel { + float: right; +} + +#wp-link-cancel { + float: right; +} + +#wp-link-update { + float: left; +} + +#wp-link .toggle-arrow { + background-position: bottom right; +} + +#wp-link .toggle-arrow-active { + background-position: center right; +} \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wplink/css/wplink.css b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink.css new file mode 100644 index 00000000..a1560b3f --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink.css @@ -0,0 +1 @@ +#wp-link{line-height:1.4em;font-size:12px;}#wp-link ol,#wp-link ul{list-style:none;margin:0;padding:0;}#wp-link input[type="text"]{-webkit-box-sizing:border-box;}#wp-link input[type="text"],#wp-link textarea{border-width:1px;border-style:solid;-moz-border-radius:4px;-khtml-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;font-size:12px;margin:1px;padding:3px;}#wp-link #link-options{padding:10px 0 14px;border-bottom:1px solid #dfdfdf;margin:0 6px 14px;}#wp-link p.howto{margin:3px;}#wp-link #internal-toggle{display:inline-block;cursor:pointer;padding-left:18px;}#wp-link .toggle-arrow{background:transparent url('../img/toggle-arrow.png') top left no-repeat;height:23px;line-height:23px;}#wp-link .toggle-arrow-active{background-position:center left;}#wp-link label input[type="text"]{width:360px;margin-top:5px;}#wp-link label span{display:inline-block;width:80px;text-align:right;padding-right:5px;}#wp-link .link-search-wrapper{margin:5px 6px 9px;display:block;overflow:hidden;}#wp-link .link-search-wrapper span{float:left;margin-top:6px;}#wp-link .link-search-wrapper input[type="text"]{float:left;width:220px;}#wp-link .link-search-wrapper img.waiting{margin:8px 1px 0 4px;float:left;display:none;}#wp-link .link-target{width:auto;padding:3px 0 0;margin:0 0 0 87px;font-size:11px;}#wp-link .query-results{border:1px #dfdfdf solid;margin:0 5px 5px;background:#fff;height:185px;overflow:auto;position:relative;}#wp-link li,#wp-link .query-notice{clear:both;margin-bottom:0;border-bottom:1px solid #f1f1f1;color:#333;padding:4px 6px;cursor:pointer;position:relative;}#wp-link li:hover{background:#eaf2fa;color:#151515;}#wp-link li.unselectable{border-bottom:1px solid #dfdfdf;}#wp-link li.unselectable:hover{background:#fff;cursor:auto;color:#333;}#wp-link li.selected{background:#ddd;color:#333;}#wp-link li.selected .item-title{font-weight:bold;}#wp-link .item-title{display:inline-block;width:80%;}#wp-link .item-info{text-transform:uppercase;color:#666;font-size:11px;position:absolute;right:5px;top:4px;bottom:0;}#wp-link #search-results{display:none;}#wp-link #search-panel{float:left;width:100%;}#wp-link .river-waiting{display:none;padding:10px 0;}#wp-link .river-waiting img.waiting{margin:0 auto;display:block;}#wp-link .submitbox{padding:5px 10px;font-size:11px;overflow:auto;height:29px;}#wp-link-cancel{line-height:25px;float:left;}#wp-link-update{line-height:23px;float:right;} \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wplink/css/wplink.dev.css b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink.dev.css new file mode 100644 index 00000000..16db9e5c --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/css/wplink.dev.css @@ -0,0 +1,163 @@ +#wp-link { + line-height: 1.4em; + font-size: 12px; +} + +#wp-link ol, +#wp-link ul { + list-style: none; + margin: 0; + padding: 0; +} + +#wp-link input[type="text"] { + -webkit-box-sizing: border-box; +} + +#wp-link input[type="text"], +#wp-link textarea { + border-width: 1px; + border-style: solid; + -moz-border-radius: 4px; + -khtml-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + font-size: 12px; + margin: 1px; + padding: 3px; +} + +#wp-link #link-options { + padding: 10px 0 14px; + border-bottom: 1px solid #dfdfdf; + margin: 0 6px 14px; +} +#wp-link p.howto { + margin: 3px; +} +#wp-link #internal-toggle { + display: inline-block; + cursor: pointer; + padding-left: 18px; +} +#wp-link .toggle-arrow { + background: transparent url( '../img/toggle-arrow.png' ) top left no-repeat; + height: 23px; + line-height: 23px; +} +#wp-link .toggle-arrow-active { + background-position: center left; +} +#wp-link label input[type="text"] { + width: 360px; + margin-top: 5px; +} +#wp-link label span { + display: inline-block; + width: 80px; + text-align: right; + padding-right: 5px; +} +#wp-link .link-search-wrapper { + margin: 5px 6px 9px; + display: block; + overflow: hidden; +} +#wp-link .link-search-wrapper span { + float: left; + margin-top: 6px; +} +#wp-link .link-search-wrapper input[type="text"] { + float: left; + width: 220px; +} +#wp-link .link-search-wrapper img.waiting { + margin: 8px 1px 0 4px; + float: left; + display: none; +} +#wp-link .link-target { + width: auto; + padding: 3px 0 0; + margin: 0 0 0 87px; + font-size: 11px; +} +#wp-link .query-results { + border: 1px #dfdfdf solid; + margin: 0 5px 5px; + background: #fff; + height: 185px; + overflow: auto; + position: relative; +} +#wp-link li, +#wp-link .query-notice { + clear: both; + margin-bottom: 0; + border-bottom: 1px solid #f1f1f1; + color: #333; + padding: 4px 6px; + cursor: pointer; + position: relative; +} +#wp-link li:hover { + background: #eaf2fa; + color: #151515; +} +#wp-link li.unselectable { + border-bottom: 1px solid #dfdfdf; +} +#wp-link li.unselectable:hover { + background: #fff; + cursor: auto; + color: #333; +} +#wp-link li.selected { + background: #ddd; + color: #333; +} +#wp-link li.selected .item-title { + font-weight: bold; +} +#wp-link .item-title { + display: inline-block; + width: 80%; +} +#wp-link .item-info { + text-transform: uppercase; + color: #666; + font-size: 11px; + position: absolute; + right: 5px; + top: 4px; + bottom: 0; +} +#wp-link #search-results { + display: none; +} +#wp-link #search-panel { + float: left; + width: 100%; +} +#wp-link .river-waiting { + display: none; + padding: 10px 0; +} +#wp-link .river-waiting img.waiting { + margin: 0 auto; + display: block; +} +#wp-link .submitbox { + padding: 5px 10px; + font-size: 11px; + overflow: auto; + height: 29px; +} +#wp-link-cancel { + line-height: 25px; + float: left; +} +#wp-link-update { + line-height: 23px; + float: right; +} \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wplink/editor_plugin.dev.js b/src/wp-includes/js/tinymce/plugins/wplink/editor_plugin.dev.js new file mode 100644 index 00000000..ff1c4ebc --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/editor_plugin.dev.js @@ -0,0 +1,60 @@ +(function() { + tinymce.create('tinymce.plugins.wpLink', { + /** + * Initializes the plugin, this will be executed after the plugin has been created. + * This call is done before the editor instance has finished it's initialization so use the onInit event + * of the editor instance to intercept that event. + * + * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in. + * @param {string} url Absolute URL to where the plugin is located. + */ + init : function(ed, url) { + var disabled = true; + + // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample'); + ed.addCommand('WP_Link', function() { + if ( disabled ) + return; + ed.windowManager.open({ + id : 'wp-link', + width : 480, + height : "auto", + wpDialog : true, + title : ed.getLang('advlink.link_desc') + }, { + plugin_url : url // Plugin absolute URL + }); + }); + + // Register example button + ed.addButton('link', { + title : ed.getLang('advanced.link_desc'), + cmd : 'WP_Link' + }); + + ed.addShortcut('alt+shift+a', ed.getLang('advanced.link_desc'), 'WP_Link'); + + ed.onNodeChange.add(function(ed, cm, n, co) { + disabled = co && n.nodeName != 'A'; + }); + }, + /** + * Returns information about the plugin as a name/value array. + * The current keys are longname, author, authorurl, infourl and version. + * + * @return {Object} Name/value array containing information about the plugin. + */ + getInfo : function() { + return { + longname : 'WordPress Link Dialog', + author : 'WordPress', + authorurl : 'http://wordpress.org', + infourl : '', + version : "1.0" + }; + } + }); + + // Register plugin + tinymce.PluginManager.add('wplink', tinymce.plugins.wpLink); +})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wplink/editor_plugin.js b/src/wp-includes/js/tinymce/plugins/wplink/editor_plugin.js new file mode 100644 index 00000000..49b94aed --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/editor_plugin.js @@ -0,0 +1 @@ +(function(){tinymce.create("tinymce.plugins.wpLink",{init:function(a,b){var c=true;a.addCommand("WP_Link",function(){if(c){return}a.windowManager.open({id:"wp-link",width:480,height:"auto",wpDialog:true,title:a.getLang("advlink.link_desc")},{plugin_url:b})});a.addButton("link",{title:a.getLang("advanced.link_desc"),cmd:"WP_Link"});a.addShortcut("alt+shift+a",a.getLang("advanced.link_desc"),"WP_Link");a.onNodeChange.add(function(e,d,g,f){c=f&&g.nodeName!="A"})},getInfo:function(){return{longname:"WordPress Link Dialog",author:"WordPress",authorurl:"http://wordpress.org",infourl:"",version:"1.0"}}});tinymce.PluginManager.add("wplink",tinymce.plugins.wpLink)})(); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wplink/img/toggle-arrow.png b/src/wp-includes/js/tinymce/plugins/wplink/img/toggle-arrow.png new file mode 100644 index 00000000..5d4a6d34 Binary files /dev/null and b/src/wp-includes/js/tinymce/plugins/wplink/img/toggle-arrow.png differ diff --git a/src/wp-includes/js/tinymce/plugins/wplink/js/wplink.dev.js b/src/wp-includes/js/tinymce/plugins/wplink/js/wplink.dev.js new file mode 100644 index 00000000..8f12ebec --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/js/wplink.dev.js @@ -0,0 +1,455 @@ +var wpLink; + +(function($){ + var inputs = {}, rivers = {}, ed, River, Query; + + wpLink = { + timeToTriggerRiver: 150, + minRiverAJAXDuration: 200, + riverBottomThreshold: 5, + keySensitivity: 100, + lastSearch: '', + init : function() { + inputs.dialog = $('#wp-link'); + inputs.submit = $('#wp-link-submit'); + // URL + inputs.url = $('#url-field'); + // Secondary options + inputs.title = $('#link-title-field'); + // Advanced Options + inputs.openInNewTab = $('#link-target-checkbox'); + inputs.search = $('#search-field'); + // Build Rivers + rivers.search = new River( $('#search-results') ); + rivers.recent = new River( $('#most-recent-results') ); + rivers.elements = $('.query-results', inputs.dialog); + + // Bind event handlers + inputs.dialog.keydown( wpLink.keydown ); + inputs.dialog.keyup( wpLink.keyup ); + inputs.submit.click( function(e){ + wpLink.update(); + e.preventDefault(); + }); + $('#wp-link-cancel').click( wpLink.cancel ); + $('#internal-toggle').click( wpLink.toggleInternalLinking ); + + rivers.elements.bind('river-select', wpLink.updateFields ); + + inputs.search.keyup( wpLink.searchInternalLinks ); + + inputs.dialog.bind('wpdialogrefresh', wpLink.refresh); + }, + + refresh : function() { + var e; + ed = tinyMCEPopup.editor; + + // Refresh rivers (clear links, check visibility) + rivers.search.refresh(); + rivers.recent.refresh(); + + tinyMCEPopup.restoreSelection(); + + // If link exists, select proper values. + if ( e = ed.dom.getParent(ed.selection.getNode(), 'A') ) { + // Set URL and description. + inputs.url.val( e.href ); + inputs.title.val( ed.dom.getAttrib(e, 'title') ); + // Set open in new tab. + if ( "_blank" == ed.dom.getAttrib(e, 'target') ) + inputs.openInNewTab.attr('checked','checked'); + // Update save prompt. + inputs.submit.val( wpLinkL10n.update ); + + // If there's no link, set the default values. + } else { + wpLink.setDefaultValues(); + // Update save prompt. + inputs.submit.val( wpLinkL10n.save ); + } + + tinyMCEPopup.storeSelection(); + // Focus the URL field and highlight its contents. + // If this is moved above the selection changes, + // IE will show a flashing cursor over the dialog. + inputs.url.focus()[0].select(); + // Load the most recent results if this is the first time opening the panel. + if ( ! rivers.recent.ul.children().length ) + rivers.recent.ajax(); + }, + + cancel : function() { + tinyMCEPopup.close(); + }, + + update : function() { + var ed = tinyMCEPopup.editor, + attrs = { + href : inputs.url.val(), + title : inputs.title.val(), + target : inputs.openInNewTab.attr('checked') ? '_blank' : '' + }, e, b; + + tinyMCEPopup.restoreSelection(); + e = ed.dom.getParent(ed.selection.getNode(), 'A'); + + // If the values are empty, unlink and return + if ( ! attrs.href || attrs.href == 'http://' ) { + if ( e ) { + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + b = ed.selection.getBookmark(); + ed.dom.remove(e, 1); + ed.selection.moveToBookmark(b); + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + } + return; + } + + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + + if (e == null) { + ed.getDoc().execCommand("unlink", false, null); + tinyMCEPopup.execCommand("CreateLink", false, "#mce_temp_url#", {skip_undo : 1}); + + tinymce.each(ed.dom.select("a"), function(n) { + if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') { + e = n; + ed.dom.setAttribs(e, attrs); + } + }); + + // Sometimes WebKit lets a user create a link where + // they shouldn't be able to. In this case, CreateLink + // injects "#mce_temp_url#" into their content. Fix it. + if ( $(e).text() == '#mce_temp_url#' ) { + ed.dom.remove(e); + e = null; + } + } else { + ed.dom.setAttribs(e, attrs); + } + + // Don't move caret if selection was image + if ( e && (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') ) { + ed.focus(); + ed.selection.select(e); + ed.selection.collapse(0); + tinyMCEPopup.storeSelection(); + } + + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + }, + + updateFields : function( e, li, originalEvent ) { + inputs.url.val( li.children('.item-permalink').val() ); + inputs.title.val( li.hasClass('no-title') ? '' : li.children('.item-title').text() ); + if ( originalEvent && originalEvent.type == "click" ) + inputs.url.focus(); + }, + setDefaultValues : function() { + // Set URL and description to defaults. + // Leave the new tab setting as-is. + inputs.url.val('http://'); + inputs.title.val(''); + }, + + searchInternalLinks : function() { + var t = $(this), waiting, + search = t.val(); + + if ( search.length > 2 ) { + rivers.recent.hide(); + rivers.search.show(); + + // Don't search if the keypress didn't change the title. + if ( wpLink.lastSearch == search ) + return; + + wpLink.lastSearch = search; + waiting = t.siblings('img.waiting').show(); + + rivers.search.change( search ); + rivers.search.ajax( function(){ waiting.hide(); }); + } else { + rivers.search.hide(); + rivers.recent.show(); + } + }, + + next : function() { + rivers.search.next(); + rivers.recent.next(); + }, + prev : function() { + rivers.search.prev(); + rivers.recent.prev(); + }, + + keydown : function( event ) { + var fn, key = $.ui.keyCode; + + switch( event.which ) { + case key.UP: + fn = 'prev'; + case key.DOWN: + fn = fn || 'next'; + clearInterval( wpLink.keyInterval ); + wpLink[ fn ](); + wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity ); + break; + default: + return; + } + event.preventDefault(); + }, + keyup: function( event ) { + var key = $.ui.keyCode; + + switch( event.which ) { + case key.ESCAPE: + wpLink.cancel(); + break; + case key.UP: + case key.DOWN: + clearInterval( wpLink.keyInterval ); + break; + default: + return; + } + event.preventDefault(); + }, + + delayedCallback : function( func, delay ) { + var timeoutTriggered, funcTriggered, funcArgs, funcContext; + + if ( ! delay ) + return func; + + setTimeout( function() { + if ( funcTriggered ) + return func.apply( funcContext, funcArgs ); + // Otherwise, wait. + timeoutTriggered = true; + }, delay); + + return function() { + if ( timeoutTriggered ) + return func.apply( this, arguments ); + // Otherwise, wait. + funcArgs = arguments; + funcContext = this; + funcTriggered = true; + }; + }, + + toggleInternalLinking : function( event ) { + var panel = $('#search-panel'), + widget = inputs.dialog.wpdialog('widget'), + // We're about to toggle visibility; it's currently the opposite + visible = !panel.is(':visible'), + win = $(window); + + $(this).toggleClass('toggle-arrow-active', visible); + + inputs.dialog.height('auto'); + panel.slideToggle( 300, function() { + setUserSetting('wplink', visible ? '1' : '0'); + inputs[ visible ? 'search' : 'url' ].focus(); + + // Move the box if the box is now expanded, was opened in a collapsed state, + // and if it needs to be moved. (Judged by bottom not being positive or + // bottom being smaller than top.) + var scroll = win.scrollTop(), + top = widget.offset().top, + bottom = top + widget.outerHeight(), + diff = bottom - win.height(); + + if ( diff > scroll ) { + widget.animate({'top': diff < top ? top - diff : scroll }, 200); + } + }); + event.preventDefault(); + } + } + + River = function( element, search ) { + var self = this; + this.element = element; + this.ul = element.children('ul'); + this.waiting = element.find('.river-waiting'); + + this.change( search ); + this.refresh(); + + element.scroll( function(){ self.maybeLoad(); }); + element.delegate('li', 'click', function(e){ self.select( $(this), e ); }); + }; + + $.extend( River.prototype, { + refresh: function() { + this.deselect(); + this.visible = this.element.is(':visible'); + }, + show: function() { + if ( ! this.visible ) { + this.deselect(); + this.element.show(); + this.visible = true; + } + }, + hide: function() { + this.element.hide(); + this.visible = false; + }, + // Selects a list item and triggers the river-select event. + select: function( li, event ) { + var liHeight, elHeight, liTop, elTop; + + if ( li.hasClass('unselectable') || li == this.selected ) + return; + + this.deselect(); + this.selected = li.addClass('selected'); + // Make sure the element is visible + liHeight = li.outerHeight(); + elHeight = this.element.height(); + liTop = li.position().top; + elTop = this.element.scrollTop(); + + if ( liTop < 0 ) // Make first visible element + this.element.scrollTop( elTop + liTop ); + else if ( liTop + liHeight > elHeight ) // Make last visible element + this.element.scrollTop( elTop + liTop - elHeight + liHeight ); + + // Trigger the river-select event + this.element.trigger('river-select', [ li, event, this ]); + }, + deselect: function() { + if ( this.selected ) + this.selected.removeClass('selected'); + this.selected = false; + }, + prev: function() { + if ( ! this.visible ) + return; + + var to; + if ( this.selected ) { + to = this.selected.prev('li'); + if ( to.length ) + this.select( to ); + } + }, + next: function() { + if ( ! this.visible ) + return; + + var to = this.selected ? this.selected.next('li') : $('li:not(.unselectable):first', this.element); + if ( to.length ) + this.select( to ); + }, + ajax: function( callback ) { + var self = this, + delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration, + response = wpLink.delayedCallback( function( results, params ) { + self.process( results, params ); + if ( callback ) + callback( results, params ); + }, delay ); + + this.query.ajax( response ); + }, + change: function( search ) { + if ( this.query && this._search == search ) + return; + + this._search = search; + this.query = new Query( search ); + this.element.scrollTop(0); + }, + process: function( results, params ) { + var list = '', alt = true, classes = '', + firstPage = params.page == 1; + + if ( !results ) { + if ( firstPage ) { + list += '
  • ' + + wpLinkL10n.noMatchesFound + + '
  • '; + } + } else { + $.each( results, function() { + classes = alt ? 'alternate' : ''; + classes += this['title'] ? '' : ' no-title'; + list += classes ? '
  • ' : '
  • '; + list += ''; + list += ''; + list += this['title'] ? this['title'] : wpLinkL10n.noTitle; + list += '' + this['info'] + '
  • '; + alt = ! alt; + }); + } + + this.ul[ firstPage ? 'html' : 'append' ]( list ); + }, + maybeLoad: function() { + var self = this, + el = this.element, + bottom = el.scrollTop() + el.height(); + + if ( ! this.query.ready() || bottom < this.ul.height() - wpLink.riverBottomThreshold ) + return; + + setTimeout(function() { + var newTop = el.scrollTop(), + newBottom = newTop + el.height(); + + if ( ! self.query.ready() || newBottom < self.ul.height() - wpLink.riverBottomThreshold ) + return; + + self.waiting.show(); + el.scrollTop( newTop + self.waiting.outerHeight() ); + + self.ajax( function() { self.waiting.hide(); }); + }, wpLink.timeToTriggerRiver ); + } + }); + + Query = function( search ) { + this.page = 1; + this.allLoaded = false; + this.querying = false; + this.search = search; + }; + + $.extend( Query.prototype, { + ready: function() { + return !( this.querying || this.allLoaded ); + }, + ajax: function( callback ) { + var self = this, + query = { + action : 'wp-link-ajax', + page : this.page, + '_ajax_linking_nonce' : $('#_ajax_linking_nonce').val() + }; + + if ( this.search ) + query.search = this.search; + + this.querying = true; + + $.post( ajaxurl, query, function(r) { + self.page++; + self.querying = false; + self.allLoaded = !r; + callback( r, query ); + }, "json" ); + } + }); + + $(document).ready( wpLink.init ); +})(jQuery); \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/plugins/wplink/js/wplink.js b/src/wp-includes/js/tinymce/plugins/wplink/js/wplink.js new file mode 100644 index 00000000..565c49bb --- /dev/null +++ b/src/wp-includes/js/tinymce/plugins/wplink/js/wplink.js @@ -0,0 +1 @@ +var wpLink;(function(f){var b={},e={},d,a,c;wpLink={timeToTriggerRiver:150,minRiverAJAXDuration:200,riverBottomThreshold:5,keySensitivity:100,lastSearch:"",init:function(){b.dialog=f("#wp-link");b.submit=f("#wp-link-submit");b.url=f("#url-field");b.title=f("#link-title-field");b.openInNewTab=f("#link-target-checkbox");b.search=f("#search-field");e.search=new a(f("#search-results"));e.recent=new a(f("#most-recent-results"));e.elements=f(".query-results",b.dialog);b.dialog.keydown(wpLink.keydown);b.dialog.keyup(wpLink.keyup);b.submit.click(function(g){wpLink.update();g.preventDefault()});f("#wp-link-cancel").click(wpLink.cancel);f("#internal-toggle").click(wpLink.toggleInternalLinking);e.elements.bind("river-select",wpLink.updateFields);b.search.keyup(wpLink.searchInternalLinks);b.dialog.bind("wpdialogrefresh",wpLink.refresh)},refresh:function(){var g;d=tinyMCEPopup.editor;e.search.refresh();e.recent.refresh();tinyMCEPopup.restoreSelection();if(g=d.dom.getParent(d.selection.getNode(),"A")){b.url.val(g.href);b.title.val(d.dom.getAttrib(g,"title"));if("_blank"==d.dom.getAttrib(g,"target")){b.openInNewTab.attr("checked","checked")}b.submit.val(wpLinkL10n.update)}else{wpLink.setDefaultValues();b.submit.val(wpLinkL10n.save)}tinyMCEPopup.storeSelection();b.url.focus()[0].select();if(!e.recent.ul.children().length){e.recent.ajax()}},cancel:function(){tinyMCEPopup.close()},update:function(){var h=tinyMCEPopup.editor,i={href:b.url.val(),title:b.title.val(),target:b.openInNewTab.attr("checked")?"_blank":""},j,g;tinyMCEPopup.restoreSelection();j=h.dom.getParent(h.selection.getNode(),"A");if(!i.href||i.href=="http://"){if(j){tinyMCEPopup.execCommand("mceBeginUndoLevel");g=h.selection.getBookmark();h.dom.remove(j,1);h.selection.moveToBookmark(g);tinyMCEPopup.execCommand("mceEndUndoLevel");tinyMCEPopup.close()}return}tinyMCEPopup.execCommand("mceBeginUndoLevel");if(j==null){h.getDoc().execCommand("unlink",false,null);tinyMCEPopup.execCommand("CreateLink",false,"#mce_temp_url#",{skip_undo:1});tinymce.each(h.dom.select("a"),function(k){if(h.dom.getAttrib(k,"href")=="#mce_temp_url#"){j=k;h.dom.setAttribs(j,i)}});if(f(j).text()=="#mce_temp_url#"){h.dom.remove(j);j=null}}else{h.dom.setAttribs(j,i)}if(j&&(j.childNodes.length!=1||j.firstChild.nodeName!="IMG")){h.focus();h.selection.select(j);h.selection.collapse(0);tinyMCEPopup.storeSelection()}tinyMCEPopup.execCommand("mceEndUndoLevel");tinyMCEPopup.close()},updateFields:function(i,h,g){b.url.val(h.children(".item-permalink").val());b.title.val(h.hasClass("no-title")?"":h.children(".item-title").text());if(g&&g.type=="click"){b.url.focus()}},setDefaultValues:function(){b.url.val("http://");b.title.val("")},searchInternalLinks:function(){var h=f(this),i,g=h.val();if(g.length>2){e.recent.hide();e.search.show();if(wpLink.lastSearch==g){return}wpLink.lastSearch=g;i=h.siblings("img.waiting").show();e.search.change(g);e.search.ajax(function(){i.hide()})}else{e.search.hide();e.recent.show()}},next:function(){e.search.next();e.recent.next()},prev:function(){e.search.prev();e.recent.prev()},keydown:function(i){var h,g=f.ui.keyCode;switch(i.which){case g.UP:h="prev";case g.DOWN:h=h||"next";clearInterval(wpLink.keyInterval);wpLink[h]();wpLink.keyInterval=setInterval(wpLink[h],wpLink.keySensitivity);break;default:return}i.preventDefault()},keyup:function(h){var g=f.ui.keyCode;switch(h.which){case g.ESCAPE:wpLink.cancel();break;case g.UP:case g.DOWN:clearInterval(wpLink.keyInterval);break;default:return}h.preventDefault()},delayedCallback:function(i,g){var l,k,j,h;if(!g){return i}setTimeout(function(){if(k){return i.apply(h,j)}l=true},g);return function(){if(l){return i.apply(this,arguments)}j=arguments;h=this;k=true}},toggleInternalLinking:function(h){var g=f("#search-panel"),i=b.dialog.wpdialog("widget"),k=!g.is(":visible"),j=f(window);f(this).toggleClass("toggle-arrow-active",k);b.dialog.height("auto");g.slideToggle(300,function(){setUserSetting("wplink",k?"1":"0");b[k?"search":"url"].focus();var l=j.scrollTop(),o=i.offset().top,m=o+i.outerHeight(),n=m-j.height();if(n>l){i.animate({top:ni){this.element.scrollTop(g+l-i+j)}}this.element.trigger("river-select",[h,k,this])},deselect:function(){if(this.selected){this.selected.removeClass("selected")}this.selected=false},prev:function(){if(!this.visible){return}var g;if(this.selected){g=this.selected.prev("li");if(g.length){this.select(g)}}},next:function(){if(!this.visible){return}var g=this.selected?this.selected.next("li"):f("li:not(.unselectable):first",this.element);if(g.length){this.select(g)}},ajax:function(j){var h=this,i=this.query.page==1?0:wpLink.minRiverAJAXDuration,g=wpLink.delayedCallback(function(k,l){h.process(k,l);if(j){j(k,l)}},i);this.query.ajax(g)},change:function(g){if(this.query&&this._search==g){return}this._search=g;this.query=new c(g);this.element.scrollTop(0)},process:function(h,l){var i="",j=true,g="",k=l.page==1;if(!h){if(k){i+='
  • '+wpLinkL10n.noMatchesFound+"
  • "}}else{f.each(h,function(){g=j?"alternate":"";g+=this["title"]?"":" no-title";i+=g?'
  • ':"
  • ";i+='';i+='';i+=this["title"]?this["title"]:wpLinkL10n.noTitle;i+=''+this["info"]+"
  • ";j=!j})}this.ul[k?"html":"append"](i)},maybeLoad:function(){var h=this,i=this.element,g=i.scrollTop()+i.height();if(!this.query.ready()||g + + + {#advanced_dlg.about_title} + + + + + + + +
    +
    +

    {#advanced_dlg.about_title}

    +

    Version: ()

    +

    TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under LGPL + by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.

    +

    Copyright © 2003-2008, Moxiecode Systems AB, All rights reserved.

    +

    For more information about this software visit the TinyMCE website.

    + +
    + Got Moxie? + Hosted By Sourceforge + Also on freshmeat +
    +
    + +
    +
    +

    {#advanced_dlg.about_loaded}

    + +
    +
    + +

     

    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + + diff --git a/src/wp-includes/js/tinymce/themes/advanced/anchor.htm b/src/wp-includes/js/tinymce/themes/advanced/anchor.htm new file mode 100644 index 00000000..b7bbe95c --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/anchor.htm @@ -0,0 +1,31 @@ + + + + {#advanced_dlg.anchor_title} + + + + +
    + + + + + + + + +
    {#advanced_dlg.anchor_title}
    {#advanced_dlg.anchor_name}:
    + +
    +
    + +
    + +
    + +
    +
    +
    + + diff --git a/src/wp-includes/js/tinymce/themes/advanced/charmap.htm b/src/wp-includes/js/tinymce/themes/advanced/charmap.htm new file mode 100644 index 00000000..7a5ac7e1 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/charmap.htm @@ -0,0 +1,52 @@ + + + + {#advanced_dlg.charmap_title} + + + + + + + + + + + + + + + +
    {#advanced_dlg.charmap_title}
    + + + + + + + + + +
     
     
    +
    + + + + + + + + + + + + + + + + +
    HTML-Code
     
     
    NUM-Code
     
    +
    + + + diff --git a/src/wp-includes/js/tinymce/themes/advanced/color_picker.htm b/src/wp-includes/js/tinymce/themes/advanced/color_picker.htm new file mode 100644 index 00000000..2d00cd5c --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/color_picker.htm @@ -0,0 +1,75 @@ + + + + {#advanced_dlg.colorpicker_title} + + + + + +
    + + +
    +
    +
    + {#advanced_dlg.colorpicker_picker_title} +
    + + +
    + +
    + +
    +
    +
    +
    + +
    +
    + {#advanced_dlg.colorpicker_palette_title} +
    + +
    + +
    +
    +
    + +
    +
    + {#advanced_dlg.colorpicker_named_title} +
    + +
    + +
    + +
    + {#advanced_dlg.colorpicker_name} +
    +
    +
    +
    + +
    +
    + +
    + +
    + +
    + +
    +
    +
    + + diff --git a/src/wp-includes/js/tinymce/themes/advanced/editor_template.js b/src/wp-includes/js/tinymce/themes/advanced/editor_template.js new file mode 100644 index 00000000..c5a1719a --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/editor_template.js @@ -0,0 +1 @@ +(function(e){var d=e.DOM,b=e.dom.Event,h=e.extend,f=e.each,a=e.util.Cookie,g,c=e.explode;e.ThemeManager.requireLangPack("advanced");e.create("tinymce.themes.AdvancedTheme",{sizes:[8,10,12,14,18,24,36],controls:{bold:["bold_desc","Bold"],italic:["italic_desc","Italic"],underline:["underline_desc","Underline"],strikethrough:["striketrough_desc","Strikethrough"],justifyleft:["justifyleft_desc","JustifyLeft"],justifycenter:["justifycenter_desc","JustifyCenter"],justifyright:["justifyright_desc","JustifyRight"],justifyfull:["justifyfull_desc","JustifyFull"],bullist:["bullist_desc","InsertUnorderedList"],numlist:["numlist_desc","InsertOrderedList"],outdent:["outdent_desc","Outdent"],indent:["indent_desc","Indent"],cut:["cut_desc","Cut"],copy:["copy_desc","Copy"],paste:["paste_desc","Paste"],undo:["undo_desc","Undo"],redo:["redo_desc","Redo"],link:["link_desc","mceLink"],unlink:["unlink_desc","unlink"],image:["image_desc","mceImage"],cleanup:["cleanup_desc","mceCleanup"],help:["help_desc","mceHelp"],code:["code_desc","mceCodeEditor"],hr:["hr_desc","InsertHorizontalRule"],removeformat:["removeformat_desc","RemoveFormat"],sub:["sub_desc","subscript"],sup:["sup_desc","superscript"],forecolor:["forecolor_desc","ForeColor"],forecolorpicker:["forecolor_desc","mceForeColor"],backcolor:["backcolor_desc","HiliteColor"],backcolorpicker:["backcolor_desc","mceBackColor"],charmap:["charmap_desc","mceCharMap"],visualaid:["visualaid_desc","mceToggleVisualAid"],anchor:["anchor_desc","mceInsertAnchor"],newdocument:["newdocument_desc","mceNewDocument"],blockquote:["blockquote_desc","mceBlockQuote"]},stateControls:["bold","italic","underline","strikethrough","bullist","numlist","justifyleft","justifycenter","justifyright","justifyfull","sub","sup","blockquote"],init:function(j,k){var l=this,m,i,n;l.editor=j;l.url=k;l.onResolveName=new e.util.Dispatcher(this);l.settings=m=h({theme_advanced_path:true,theme_advanced_toolbar_location:"bottom",theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,|,sub,sup,|,charmap",theme_advanced_blockformats:"p,address,pre,h1,h2,h3,h4,h5,h6",theme_advanced_toolbar_align:"center",theme_advanced_fonts:"Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",theme_advanced_more_colors:1,theme_advanced_row_height:23,theme_advanced_resize_horizontal:1,theme_advanced_resizing_use_cookie:1,theme_advanced_font_sizes:"1,2,3,4,5,6,7",readonly:j.settings.readonly},j.settings);if(!m.font_size_style_values){m.font_size_style_values="8pt,10pt,12pt,14pt,18pt,24pt,36pt"}if(e.is(m.theme_advanced_font_sizes,"string")){m.font_size_style_values=e.explode(m.font_size_style_values);m.font_size_classes=e.explode(m.font_size_classes||"");n={};j.settings.theme_advanced_font_sizes=m.theme_advanced_font_sizes;f(j.getParam("theme_advanced_font_sizes","","hash"),function(q,p){var o;if(p==q&&q>=1&&q<=7){p=q+" ("+l.sizes[q-1]+"pt)";o=m.font_size_classes[q-1];q=m.font_size_style_values[q-1]||(l.sizes[q-1]+"pt")}if(/^\s*\./.test(q)){o=q.replace(/\./g,"")}n[p]=o?{"class":o}:{fontSize:q}});m.theme_advanced_font_sizes=n}if((i=m.theme_advanced_path_location)&&i!="none"){m.theme_advanced_statusbar_location=m.theme_advanced_path_location}if(m.theme_advanced_statusbar_location=="none"){m.theme_advanced_statusbar_location=0}j.onInit.add(function(){if(!j.settings.readonly){j.onNodeChange.add(l._nodeChanged,l)}if(j.settings.content_css!==false){j.dom.loadCSS(j.baseURI.toAbsolute(k+"/skins/"+j.settings.skin+"/content.css"))}});j.onSetProgressState.add(function(q,o,r){var s,t=q.id,p;if(o){l.progressTimer=setTimeout(function(){s=q.getContainer();s=s.insertBefore(d.create("DIV",{style:"position:relative"}),s.firstChild);p=d.get(q.id+"_tbl");d.add(s,"div",{id:t+"_blocker","class":"mceBlocker",style:{width:p.clientWidth+2,height:p.clientHeight+2}});d.add(s,"div",{id:t+"_progress","class":"mceProgress",style:{left:p.clientWidth/2,top:p.clientHeight/2}})},r||0)}else{d.remove(t+"_blocker");d.remove(t+"_progress");clearTimeout(l.progressTimer)}});d.loadCSS(m.editor_css?j.documentBaseURI.toAbsolute(m.editor_css):k+"/skins/"+j.settings.skin+"/ui.css");if(m.skin_variant){d.loadCSS(k+"/skins/"+j.settings.skin+"/ui_"+m.skin_variant+".css")}},createControl:function(l,i){var j,k;if(k=i.createControl(l)){return k}switch(l){case"styleselect":return this._createStyleSelect();case"formatselect":return this._createBlockFormats();case"fontselect":return this._createFontSelect();case"fontsizeselect":return this._createFontSizeSelect();case"forecolor":return this._createForeColorMenu();case"backcolor":return this._createBackColorMenu()}if((j=this.controls[l])){return i.createButton(l,{title:"advanced."+j[0],cmd:j[1],ui:j[2],value:j[3]})}},execCommand:function(k,j,l){var i=this["_"+k];if(i){i.call(this,j,l);return true}return false},_importClasses:function(k){var i=this.editor,j=i.controlManager.get("styleselect");if(j.getLength()==0){f(i.dom.getClasses(),function(n,l){var m="style_"+l;i.formatter.register(m,{inline:"span",attributes:{"class":n["class"]},selector:"*"});j.add(n["class"],m)})}},_createStyleSelect:function(m){var k=this,i=k.editor,j=i.controlManager,l;l=j.createListBox("styleselect",{title:"advanced.style_select",onselect:function(o){var p,n=[];f(l.items,function(q){n.push(q.value)});i.focus();i.undoManager.add();p=i.formatter.matchAll(n);if(!o||p[0]==o){i.formatter.remove(p[0])}else{i.formatter.apply(o)}i.undoManager.add();i.nodeChanged();return false}});i.onInit.add(function(){var o=0,n=i.getParam("style_formats");if(n){f(n,function(p){var q,r=0;f(p,function(){r++});if(r>1){q=p.name=p.name||"style_"+(o++);i.formatter.register(q,p);l.add(p.title,q)}else{l.add(p.title)}})}else{f(i.getParam("theme_advanced_styles","","hash"),function(r,q){var p;if(r){p="style_"+(o++);i.formatter.register(p,{inline:"span",classes:r,selector:"*"});l.add(k.editor.translate(q),p)}})}});if(l.getLength()==0){l.onPostRender.add(function(o,p){if(!l.NativeListBox){b.add(p.id+"_text","focus",k._importClasses,k);b.add(p.id+"_text","mousedown",k._importClasses,k);b.add(p.id+"_open","focus",k._importClasses,k);b.add(p.id+"_open","mousedown",k._importClasses,k)}else{b.add(p.id,"focus",k._importClasses,k)}})}return l},_createFontSelect:function(){var k,j=this,i=j.editor;k=i.controlManager.createListBox("fontselect",{title:"advanced.fontdefault",onselect:function(l){var m=k.items[k.selectedIndex];if(!l&&m){i.execCommand("FontName",false,m.value);return}i.execCommand("FontName",false,l);k.select(function(n){return l==n});return false}});if(k){f(i.getParam("theme_advanced_fonts",j.settings.theme_advanced_fonts,"hash"),function(m,l){k.add(i.translate(l),m,{style:m.indexOf("dings")==-1?"font-family:"+m:""})})}return k},_createFontSizeSelect:function(){var m=this,k=m.editor,n,l=0,j=[];n=k.controlManager.createListBox("fontsizeselect",{title:"advanced.font_size",onselect:function(i){var o=n.items[n.selectedIndex];if(!i&&o){o=o.value;if(o["class"]){k.formatter.toggle("fontsize_class",{value:o["class"]});k.undoManager.add();k.nodeChanged()}else{k.execCommand("FontSize",false,o.fontSize)}return}if(i["class"]){k.focus();k.undoManager.add();k.formatter.toggle("fontsize_class",{value:i["class"]});k.undoManager.add();k.nodeChanged()}else{k.execCommand("FontSize",false,i.fontSize)}n.select(function(p){return i==p});return false}});if(n){f(m.settings.theme_advanced_font_sizes,function(o,i){var p=o.fontSize;if(p>=1&&p<=7){p=m.sizes[parseInt(p)-1]+"pt"}n.add(i,o,{style:"font-size:"+p,"class":"mceFontSize"+(l++)+(" "+(o["class"]||""))})})}return n},_createBlockFormats:function(){var k,i={p:"advanced.paragraph",address:"advanced.address",pre:"advanced.pre",h1:"advanced.h1",h2:"advanced.h2",h3:"advanced.h3",h4:"advanced.h4",h5:"advanced.h5",h6:"advanced.h6",div:"advanced.div",blockquote:"advanced.blockquote",code:"advanced.code",dt:"advanced.dt",dd:"advanced.dd",samp:"advanced.samp"},j=this;k=j.editor.controlManager.createListBox("formatselect",{title:"advanced.block",cmd:"FormatBlock"});if(k){f(j.editor.getParam("theme_advanced_blockformats",j.settings.theme_advanced_blockformats,"hash"),function(m,l){k.add(j.editor.translate(l!=m?l:i[m]),m,{"class":"mce_formatPreview mce_"+m})})}return k},_createForeColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_text_colors){l.colors=i}if(k.theme_advanced_default_foreground_color){l.default_color=k.theme_advanced_default_foreground_color}l.title="advanced.forecolor_desc";l.cmd="ForeColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("forecolor",l);return m},_createBackColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_background_colors){l.colors=i}if(k.theme_advanced_default_background_color){l.default_color=k.theme_advanced_default_background_color}l.title="advanced.backcolor_desc";l.cmd="HiliteColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("backcolor",l);return m},renderUI:function(k){var m,l,q,v=this,r=v.editor,w=v.settings,u,j,i;m=j=d.create("span",{id:r.id+"_parent","class":"mceEditor "+r.settings.skin+"Skin"+(w.skin_variant?" "+r.settings.skin+"Skin"+v._ufirst(w.skin_variant):"")});if(!d.boxModel){m=d.add(m,"div",{"class":"mceOldBoxModel"})}m=u=d.add(m,"table",{id:r.id+"_tbl","class":"mceLayout",cellSpacing:0,cellPadding:0});m=q=d.add(m,"tbody");switch((w.theme_advanced_layout_manager||"").toLowerCase()){case"rowlayout":l=v._rowLayout(w,q,k);break;case"customlayout":l=r.execCallback("theme_advanced_custom_layout",w,q,k,j);break;default:l=v._simpleLayout(w,q,k,j)}m=k.targetNode;i=d.stdMode?u.getElementsByTagName("tr"):u.rows;d.addClass(i[0],"mceFirst");d.addClass(i[i.length-1],"mceLast");f(d.select("tr",q),function(o){d.addClass(o.firstChild,"mceFirst");d.addClass(o.childNodes[o.childNodes.length-1],"mceLast")});if(d.get(w.theme_advanced_toolbar_container)){d.get(w.theme_advanced_toolbar_container).appendChild(j)}else{d.insertAfter(j,m)}b.add(r.id+"_path_row","click",function(n){n=n.target;if(n.nodeName=="A"){v._sel(n.className.replace(/^.*mcePath_([0-9]+).*$/,"$1"));return b.cancel(n)}});if(!r.getParam("accessibility_focus")){b.add(d.add(j,"a",{href:"#"},""),"focus",function(){tinyMCE.get(r.id).focus()})}if(w.theme_advanced_toolbar_location=="external"){k.deltaHeight=0}v.deltaHeight=k.deltaHeight;k.targetNode=null;return{iframeContainer:l,editorContainer:r.id+"_parent",sizeContainer:u,deltaHeight:k.deltaHeight}},getInfo:function(){return{longname:"Advanced theme",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",version:e.majorVersion+"."+e.minorVersion}},resizeBy:function(i,j){var k=d.get(this.editor.id+"_tbl");this.resizeTo(k.clientWidth+i,k.clientHeight+j)},resizeTo:function(i,m,k){var j=this.editor,l=this.settings,n=d.get(j.id+"_tbl"),o=d.get(j.id+"_ifr");i=Math.max(l.theme_advanced_resizing_min_width||100,i);m=Math.max(l.theme_advanced_resizing_min_height||100,m);i=Math.min(l.theme_advanced_resizing_max_width||65535,i);m=Math.min(l.theme_advanced_resizing_max_height||65535,m);d.setStyle(n,"height","");d.setStyle(o,"height",m);if(l.theme_advanced_resize_horizontal){d.setStyle(n,"width","");d.setStyle(o,"width",i);if(i"))}q.push(d.createHTML("a",{href:"#",accesskey:"q",title:r.getLang("advanced.toolbar_focus")},""));for(p=1;(y=A["theme_advanced_buttons"+p]);p++){m=j.createToolbar("toolbar"+p,{"class":"mceToolbarRow"+p});if(A["theme_advanced_buttons"+p+"_add"]){y+=","+A["theme_advanced_buttons"+p+"_add"]}if(A["theme_advanced_buttons"+p+"_add_before"]){y=A["theme_advanced_buttons"+p+"_add_before"]+","+y}z._addControls(y,m);q.push(m.renderHTML());k.deltaHeight-=A.theme_advanced_row_height}q.push(d.createHTML("a",{href:"#",accesskey:"z",title:r.getLang("advanced.toolbar_focus"),onfocus:"tinyMCE.getInstanceById('"+r.id+"').focus();"},""));d.setHTML(l,q.join(""))},_addStatusBar:function(m,j){var k,v=this,p=v.editor,w=v.settings,i,q,u,l;k=d.add(m,"tr");k=l=d.add(k,"td",{"class":"mceStatusbar"});k=d.add(k,"div",{id:p.id+"_path_row"},w.theme_advanced_path?p.translate("advanced.path")+": ":" ");d.add(k,"a",{href:"#",accesskey:"x"});if(w.theme_advanced_resizing){d.add(l,"a",{id:p.id+"_resize",href:"javascript:;",onclick:"return false;","class":"mceResize"});if(w.theme_advanced_resizing_use_cookie){p.onPostRender.add(function(){var n=a.getHash("TinyMCE_"+p.id+"_size"),r=d.get(p.id+"_tbl");if(!n){return}v.resizeTo(n.cw,n.ch)})}p.onPostRender.add(function(){b.add(p.id+"_resize","click",function(n){n.preventDefault()});b.add(p.id+"_resize","mousedown",function(D){var t,r,s,o,C,z,A,F,n,E,x;function y(G){G.preventDefault();n=A+(G.screenX-C);E=F+(G.screenY-z);v.resizeTo(n,E)}function B(G){b.remove(d.doc,"mousemove",t);b.remove(p.getDoc(),"mousemove",r);b.remove(d.doc,"mouseup",s);b.remove(p.getDoc(),"mouseup",o);n=A+(G.screenX-C);E=F+(G.screenY-z);v.resizeTo(n,E,true)}D.preventDefault();C=D.screenX;z=D.screenY;x=d.get(v.editor.id+"_ifr");A=n=x.clientWidth;F=E=x.clientHeight;t=b.add(d.doc,"mousemove",y);r=b.add(p.getDoc(),"mousemove",y);s=b.add(d.doc,"mouseup",B);o=b.add(p.getDoc(),"mouseup",B)})})}j.deltaHeight-=21;k=m=null},_nodeChanged:function(r,z,l,x,j){var C=this,i,y=0,B,u,D=C.settings,A,k,w,m,q;e.each(C.stateControls,function(n){z.setActive(n,r.queryCommandState(C.controls[n][1]))});function o(p){var s,n=j.parents,t=p;if(typeof(p)=="string"){t=function(v){return v.nodeName==p}}for(s=0;s + + + {#advanced_dlg.image_title} + + + + + + +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
     
    + x +
    +
    +
    + +
    +
    + +
    + +
    + +
    +
    +
    + + diff --git a/src/wp-includes/js/tinymce/themes/advanced/img/colorpicker.jpg b/src/wp-includes/js/tinymce/themes/advanced/img/colorpicker.jpg new file mode 100644 index 00000000..b4c542d1 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/img/colorpicker.jpg differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/img/fm.gif b/src/wp-includes/js/tinymce/themes/advanced/img/fm.gif new file mode 100644 index 00000000..b5f022b5 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/img/fm.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/img/gotmoxie.png b/src/wp-includes/js/tinymce/themes/advanced/img/gotmoxie.png new file mode 100644 index 00000000..8a396e03 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/img/gotmoxie.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/img/icons.gif b/src/wp-includes/js/tinymce/themes/advanced/img/icons.gif new file mode 100644 index 00000000..e46de533 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/img/icons.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/img/sflogo.png b/src/wp-includes/js/tinymce/themes/advanced/img/sflogo.png new file mode 100644 index 00000000..142a6f99 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/img/sflogo.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/js/about.js b/src/wp-includes/js/tinymce/themes/advanced/js/about.js new file mode 100644 index 00000000..7fc8ba2a --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/js/about.js @@ -0,0 +1,72 @@ +tinyMCEPopup.requireLangPack(); + +function init() { + var ed, tcont; + + tinyMCEPopup.resizeToInnerSize(); + ed = tinyMCEPopup.editor; + + // Give FF some time + window.setTimeout(insertHelpIFrame, 10); + + tcont = document.getElementById('plugintablecontainer'); + document.getElementById('plugins_tab').style.display = 'none'; + + var html = ""; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + + tinymce.each(ed.plugins, function(p, n) { + var info; + + if (!p.getInfo) + return; + + html += ''; + + info = p.getInfo(); + + if (info.infourl != null && info.infourl != '') + html += ''; + else + html += ''; + + if (info.authorurl != null && info.authorurl != '') + html += ''; + else + html += ''; + + html += ''; + html += ''; + + document.getElementById('plugins_tab').style.display = ''; + + }); + + html += ''; + html += '
    ' + ed.getLang('advanced_dlg.about_plugin') + '' + ed.getLang('advanced_dlg.about_author') + '' + ed.getLang('advanced_dlg.about_version') + '
    ' + info.longname + '' + info.longname + '' + info.author + '' + info.author + '' + info.version + '
    '; + + tcont.innerHTML = html; + + tinyMCEPopup.dom.get('version').innerHTML = tinymce.majorVersion + "." + tinymce.minorVersion; + tinyMCEPopup.dom.get('date').innerHTML = tinymce.releaseDate; +} + +function insertHelpIFrame() { + var html; + + if (tinyMCEPopup.getParam('docs_url')) { + html = ''; + document.getElementById('iframecontainer').innerHTML = html; + document.getElementById('help_tab').style.display = 'block'; + } +} + +tinyMCEPopup.onInit.add(init); diff --git a/src/wp-includes/js/tinymce/themes/advanced/js/anchor.js b/src/wp-includes/js/tinymce/themes/advanced/js/anchor.js new file mode 100644 index 00000000..d7a854e9 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/js/anchor.js @@ -0,0 +1,37 @@ +tinyMCEPopup.requireLangPack(); + +var AnchorDialog = { + init : function(ed) { + var action, elm, f = document.forms[0]; + + this.editor = ed; + elm = ed.dom.getParent(ed.selection.getNode(), 'A'); + v = ed.dom.getAttrib(elm, 'name'); + + if (v) { + this.action = 'update'; + f.anchorName.value = v; + } + + f.insert.value = ed.getLang(elm ? 'update' : 'insert'); + }, + + update : function() { + var ed = this.editor, elm, name = document.forms[0].anchorName.value; + + tinyMCEPopup.restoreSelection(); + + if (this.action != 'update') + ed.selection.collapse(1); + + elm = ed.dom.getParent(ed.selection.getNode(), 'A'); + if (elm) + elm.name = name; + else + ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', {name : name, 'class' : 'mceItemAnchor'}, '')); + + tinyMCEPopup.close(); + } +}; + +tinyMCEPopup.onInit.add(AnchorDialog.init, AnchorDialog); diff --git a/src/wp-includes/js/tinymce/themes/advanced/js/charmap.js b/src/wp-includes/js/tinymce/themes/advanced/js/charmap.js new file mode 100644 index 00000000..53a26836 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/js/charmap.js @@ -0,0 +1,335 @@ +/** + * charmap.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +tinyMCEPopup.requireLangPack(); + +var charmap = [ + [' ', ' ', true, 'no-break space'], + ['&', '&', true, 'ampersand'], + ['"', '"', true, 'quotation mark'], +// finance + ['¢', '¢', true, 'cent sign'], + ['€', '€', true, 'euro sign'], + ['£', '£', true, 'pound sign'], + ['¥', '¥', true, 'yen sign'], +// signs + ['©', '©', true, 'copyright sign'], + ['®', '®', true, 'registered sign'], + ['™', '™', true, 'trade mark sign'], + ['‰', '‰', true, 'per mille sign'], + ['µ', 'µ', true, 'micro sign'], + ['·', '·', true, 'middle dot'], + ['•', '•', true, 'bullet'], + ['…', '…', true, 'three dot leader'], + ['′', '′', true, 'minutes / feet'], + ['″', '″', true, 'seconds / inches'], + ['§', '§', true, 'section sign'], + ['¶', '¶', true, 'paragraph sign'], + ['ß', 'ß', true, 'sharp s / ess-zed'], +// quotations + ['‹', '‹', true, 'single left-pointing angle quotation mark'], + ['›', '›', true, 'single right-pointing angle quotation mark'], + ['«', '«', true, 'left pointing guillemet'], + ['»', '»', true, 'right pointing guillemet'], + ['‘', '‘', true, 'left single quotation mark'], + ['’', '’', true, 'right single quotation mark'], + ['“', '“', true, 'left double quotation mark'], + ['”', '”', true, 'right double quotation mark'], + ['‚', '‚', true, 'single low-9 quotation mark'], + ['„', '„', true, 'double low-9 quotation mark'], + ['<', '<', true, 'less-than sign'], + ['>', '>', true, 'greater-than sign'], + ['≤', '≤', true, 'less-than or equal to'], + ['≥', '≥', true, 'greater-than or equal to'], + ['–', '–', true, 'en dash'], + ['—', '—', true, 'em dash'], + ['¯', '¯', true, 'macron'], + ['‾', '‾', true, 'overline'], + ['¤', '¤', true, 'currency sign'], + ['¦', '¦', true, 'broken bar'], + ['¨', '¨', true, 'diaeresis'], + ['¡', '¡', true, 'inverted exclamation mark'], + ['¿', '¿', true, 'turned question mark'], + ['ˆ', 'ˆ', true, 'circumflex accent'], + ['˜', '˜', true, 'small tilde'], + ['°', '°', true, 'degree sign'], + ['−', '−', true, 'minus sign'], + ['±', '±', true, 'plus-minus sign'], + ['÷', '÷', true, 'division sign'], + ['⁄', '⁄', true, 'fraction slash'], + ['×', '×', true, 'multiplication sign'], + ['¹', '¹', true, 'superscript one'], + ['²', '²', true, 'superscript two'], + ['³', '³', true, 'superscript three'], + ['¼', '¼', true, 'fraction one quarter'], + ['½', '½', true, 'fraction one half'], + ['¾', '¾', true, 'fraction three quarters'], +// math / logical + ['ƒ', 'ƒ', true, 'function / florin'], + ['∫', '∫', true, 'integral'], + ['∑', '∑', true, 'n-ary sumation'], + ['∞', '∞', true, 'infinity'], + ['√', '√', true, 'square root'], + ['∼', '∼', false,'similar to'], + ['≅', '≅', false,'approximately equal to'], + ['≈', '≈', true, 'almost equal to'], + ['≠', '≠', true, 'not equal to'], + ['≡', '≡', true, 'identical to'], + ['∈', '∈', false,'element of'], + ['∉', '∉', false,'not an element of'], + ['∋', '∋', false,'contains as member'], + ['∏', '∏', true, 'n-ary product'], + ['∧', '∧', false,'logical and'], + ['∨', '∨', false,'logical or'], + ['¬', '¬', true, 'not sign'], + ['∩', '∩', true, 'intersection'], + ['∪', '∪', false,'union'], + ['∂', '∂', true, 'partial differential'], + ['∀', '∀', false,'for all'], + ['∃', '∃', false,'there exists'], + ['∅', '∅', false,'diameter'], + ['∇', '∇', false,'backward difference'], + ['∗', '∗', false,'asterisk operator'], + ['∝', '∝', false,'proportional to'], + ['∠', '∠', false,'angle'], +// undefined + ['´', '´', true, 'acute accent'], + ['¸', '¸', true, 'cedilla'], + ['ª', 'ª', true, 'feminine ordinal indicator'], + ['º', 'º', true, 'masculine ordinal indicator'], + ['†', '†', true, 'dagger'], + ['‡', '‡', true, 'double dagger'], +// alphabetical special chars + ['À', 'À', true, 'A - grave'], + ['Á', 'Á', true, 'A - acute'], + ['Â', 'Â', true, 'A - circumflex'], + ['Ã', 'Ã', true, 'A - tilde'], + ['Ä', 'Ä', true, 'A - diaeresis'], + ['Å', 'Å', true, 'A - ring above'], + ['Æ', 'Æ', true, 'ligature AE'], + ['Ç', 'Ç', true, 'C - cedilla'], + ['È', 'È', true, 'E - grave'], + ['É', 'É', true, 'E - acute'], + ['Ê', 'Ê', true, 'E - circumflex'], + ['Ë', 'Ë', true, 'E - diaeresis'], + ['Ì', 'Ì', true, 'I - grave'], + ['Í', 'Í', true, 'I - acute'], + ['Î', 'Î', true, 'I - circumflex'], + ['Ï', 'Ï', true, 'I - diaeresis'], + ['Ð', 'Ð', true, 'ETH'], + ['Ñ', 'Ñ', true, 'N - tilde'], + ['Ò', 'Ò', true, 'O - grave'], + ['Ó', 'Ó', true, 'O - acute'], + ['Ô', 'Ô', true, 'O - circumflex'], + ['Õ', 'Õ', true, 'O - tilde'], + ['Ö', 'Ö', true, 'O - diaeresis'], + ['Ø', 'Ø', true, 'O - slash'], + ['Œ', 'Œ', true, 'ligature OE'], + ['Š', 'Š', true, 'S - caron'], + ['Ù', 'Ù', true, 'U - grave'], + ['Ú', 'Ú', true, 'U - acute'], + ['Û', 'Û', true, 'U - circumflex'], + ['Ü', 'Ü', true, 'U - diaeresis'], + ['Ý', 'Ý', true, 'Y - acute'], + ['Ÿ', 'Ÿ', true, 'Y - diaeresis'], + ['Þ', 'Þ', true, 'THORN'], + ['à', 'à', true, 'a - grave'], + ['á', 'á', true, 'a - acute'], + ['â', 'â', true, 'a - circumflex'], + ['ã', 'ã', true, 'a - tilde'], + ['ä', 'ä', true, 'a - diaeresis'], + ['å', 'å', true, 'a - ring above'], + ['æ', 'æ', true, 'ligature ae'], + ['ç', 'ç', true, 'c - cedilla'], + ['è', 'è', true, 'e - grave'], + ['é', 'é', true, 'e - acute'], + ['ê', 'ê', true, 'e - circumflex'], + ['ë', 'ë', true, 'e - diaeresis'], + ['ì', 'ì', true, 'i - grave'], + ['í', 'í', true, 'i - acute'], + ['î', 'î', true, 'i - circumflex'], + ['ï', 'ï', true, 'i - diaeresis'], + ['ð', 'ð', true, 'eth'], + ['ñ', 'ñ', true, 'n - tilde'], + ['ò', 'ò', true, 'o - grave'], + ['ó', 'ó', true, 'o - acute'], + ['ô', 'ô', true, 'o - circumflex'], + ['õ', 'õ', true, 'o - tilde'], + ['ö', 'ö', true, 'o - diaeresis'], + ['ø', 'ø', true, 'o slash'], + ['œ', 'œ', true, 'ligature oe'], + ['š', 'š', true, 's - caron'], + ['ù', 'ù', true, 'u - grave'], + ['ú', 'ú', true, 'u - acute'], + ['û', 'û', true, 'u - circumflex'], + ['ü', 'ü', true, 'u - diaeresis'], + ['ý', 'ý', true, 'y - acute'], + ['þ', 'þ', true, 'thorn'], + ['ÿ', 'ÿ', true, 'y - diaeresis'], + ['Α', 'Α', true, 'Alpha'], + ['Β', 'Β', true, 'Beta'], + ['Γ', 'Γ', true, 'Gamma'], + ['Δ', 'Δ', true, 'Delta'], + ['Ε', 'Ε', true, 'Epsilon'], + ['Ζ', 'Ζ', true, 'Zeta'], + ['Η', 'Η', true, 'Eta'], + ['Θ', 'Θ', true, 'Theta'], + ['Ι', 'Ι', true, 'Iota'], + ['Κ', 'Κ', true, 'Kappa'], + ['Λ', 'Λ', true, 'Lambda'], + ['Μ', 'Μ', true, 'Mu'], + ['Ν', 'Ν', true, 'Nu'], + ['Ξ', 'Ξ', true, 'Xi'], + ['Ο', 'Ο', true, 'Omicron'], + ['Π', 'Π', true, 'Pi'], + ['Ρ', 'Ρ', true, 'Rho'], + ['Σ', 'Σ', true, 'Sigma'], + ['Τ', 'Τ', true, 'Tau'], + ['Υ', 'Υ', true, 'Upsilon'], + ['Φ', 'Φ', true, 'Phi'], + ['Χ', 'Χ', true, 'Chi'], + ['Ψ', 'Ψ', true, 'Psi'], + ['Ω', 'Ω', true, 'Omega'], + ['α', 'α', true, 'alpha'], + ['β', 'β', true, 'beta'], + ['γ', 'γ', true, 'gamma'], + ['δ', 'δ', true, 'delta'], + ['ε', 'ε', true, 'epsilon'], + ['ζ', 'ζ', true, 'zeta'], + ['η', 'η', true, 'eta'], + ['θ', 'θ', true, 'theta'], + ['ι', 'ι', true, 'iota'], + ['κ', 'κ', true, 'kappa'], + ['λ', 'λ', true, 'lambda'], + ['μ', 'μ', true, 'mu'], + ['ν', 'ν', true, 'nu'], + ['ξ', 'ξ', true, 'xi'], + ['ο', 'ο', true, 'omicron'], + ['π', 'π', true, 'pi'], + ['ρ', 'ρ', true, 'rho'], + ['ς', 'ς', true, 'final sigma'], + ['σ', 'σ', true, 'sigma'], + ['τ', 'τ', true, 'tau'], + ['υ', 'υ', true, 'upsilon'], + ['φ', 'φ', true, 'phi'], + ['χ', 'χ', true, 'chi'], + ['ψ', 'ψ', true, 'psi'], + ['ω', 'ω', true, 'omega'], +// symbols + ['ℵ', 'ℵ', false,'alef symbol'], + ['ϖ', 'ϖ', false,'pi symbol'], + ['ℜ', 'ℜ', false,'real part symbol'], + ['ϑ','ϑ', false,'theta symbol'], + ['ϒ', 'ϒ', false,'upsilon - hook symbol'], + ['℘', '℘', false,'Weierstrass p'], + ['ℑ', 'ℑ', false,'imaginary part'], +// arrows + ['←', '←', true, 'leftwards arrow'], + ['↑', '↑', true, 'upwards arrow'], + ['→', '→', true, 'rightwards arrow'], + ['↓', '↓', true, 'downwards arrow'], + ['↔', '↔', true, 'left right arrow'], + ['↵', '↵', false,'carriage return'], + ['⇐', '⇐', false,'leftwards double arrow'], + ['⇑', '⇑', false,'upwards double arrow'], + ['⇒', '⇒', false,'rightwards double arrow'], + ['⇓', '⇓', false,'downwards double arrow'], + ['⇔', '⇔', false,'left right double arrow'], + ['∴', '∴', false,'therefore'], + ['⊂', '⊂', false,'subset of'], + ['⊃', '⊃', false,'superset of'], + ['⊄', '⊄', false,'not a subset of'], + ['⊆', '⊆', false,'subset of or equal to'], + ['⊇', '⊇', false,'superset of or equal to'], + ['⊕', '⊕', false,'circled plus'], + ['⊗', '⊗', false,'circled times'], + ['⊥', '⊥', false,'perpendicular'], + ['⋅', '⋅', false,'dot operator'], + ['⌈', '⌈', false,'left ceiling'], + ['⌉', '⌉', false,'right ceiling'], + ['⌊', '⌊', false,'left floor'], + ['⌋', '⌋', false,'right floor'], + ['⟨', '〈', false,'left-pointing angle bracket'], + ['⟩', '〉', false,'right-pointing angle bracket'], + ['◊', '◊', true,'lozenge'], + ['♠', '♠', false,'black spade suit'], + ['♣', '♣', true, 'black club suit'], + ['♥', '♥', true, 'black heart suit'], + ['♦', '♦', true, 'black diamond suit'], + [' ', ' ', false,'en space'], + [' ', ' ', false,'em space'], + [' ', ' ', false,'thin space'], + ['‌', '‌', false,'zero width non-joiner'], + ['‍', '‍', false,'zero width joiner'], + ['‎', '‎', false,'left-to-right mark'], + ['‏', '‏', false,'right-to-left mark'], + ['­', '­', false,'soft hyphen'] +]; + +tinyMCEPopup.onInit.add(function() { + tinyMCEPopup.dom.setHTML('charmapView', renderCharMapHTML()); +}); + +function renderCharMapHTML() { + var charsPerRow = 20, tdWidth=20, tdHeight=20, i; + var html = ''; + var cols=-1; + + for (i=0; i' + + '' + + charmap[i][1] + + ''; + if ((cols+1) % charsPerRow == 0) + html += ''; + } + } + + if (cols % charsPerRow > 0) { + var padd = charsPerRow - (cols % charsPerRow); + for (var i=0; i '; + } + + html += '
    '; + + return html; +} + +function insertChar(chr) { + tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';'); + + // Refocus in window + if (tinyMCEPopup.isWindow) + window.focus(); + + tinyMCEPopup.editor.focus(); + tinyMCEPopup.close(); +} + +function previewChar(codeA, codeB, codeN) { + var elmA = document.getElementById('codeA'); + var elmB = document.getElementById('codeB'); + var elmV = document.getElementById('codeV'); + var elmN = document.getElementById('codeN'); + + if (codeA=='#160;') { + elmV.innerHTML = '__'; + } else { + elmV.innerHTML = '&' + codeA; + } + + elmB.innerHTML = '&' + codeA; + elmA.innerHTML = '&' + codeB; + elmN.innerHTML = codeN; +} diff --git a/src/wp-includes/js/tinymce/themes/advanced/js/color_picker.js b/src/wp-includes/js/tinymce/themes/advanced/js/color_picker.js new file mode 100644 index 00000000..c1a65db2 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/js/color_picker.js @@ -0,0 +1,253 @@ +tinyMCEPopup.requireLangPack(); + +var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false; + +var colors = [ + "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033", + "#330066","#330099","#3300cc","#3300ff","#660000","#660033","#660066","#660099", + "#6600cc","#6600ff","#990000","#990033","#990066","#990099","#9900cc","#9900ff", + "#cc0000","#cc0033","#cc0066","#cc0099","#cc00cc","#cc00ff","#ff0000","#ff0033", + "#ff0066","#ff0099","#ff00cc","#ff00ff","#003300","#003333","#003366","#003399", + "#0033cc","#0033ff","#333300","#333333","#333366","#333399","#3333cc","#3333ff", + "#663300","#663333","#663366","#663399","#6633cc","#6633ff","#993300","#993333", + "#993366","#993399","#9933cc","#9933ff","#cc3300","#cc3333","#cc3366","#cc3399", + "#cc33cc","#cc33ff","#ff3300","#ff3333","#ff3366","#ff3399","#ff33cc","#ff33ff", + "#006600","#006633","#006666","#006699","#0066cc","#0066ff","#336600","#336633", + "#336666","#336699","#3366cc","#3366ff","#666600","#666633","#666666","#666699", + "#6666cc","#6666ff","#996600","#996633","#996666","#996699","#9966cc","#9966ff", + "#cc6600","#cc6633","#cc6666","#cc6699","#cc66cc","#cc66ff","#ff6600","#ff6633", + "#ff6666","#ff6699","#ff66cc","#ff66ff","#009900","#009933","#009966","#009999", + "#0099cc","#0099ff","#339900","#339933","#339966","#339999","#3399cc","#3399ff", + "#669900","#669933","#669966","#669999","#6699cc","#6699ff","#999900","#999933", + "#999966","#999999","#9999cc","#9999ff","#cc9900","#cc9933","#cc9966","#cc9999", + "#cc99cc","#cc99ff","#ff9900","#ff9933","#ff9966","#ff9999","#ff99cc","#ff99ff", + "#00cc00","#00cc33","#00cc66","#00cc99","#00cccc","#00ccff","#33cc00","#33cc33", + "#33cc66","#33cc99","#33cccc","#33ccff","#66cc00","#66cc33","#66cc66","#66cc99", + "#66cccc","#66ccff","#99cc00","#99cc33","#99cc66","#99cc99","#99cccc","#99ccff", + "#cccc00","#cccc33","#cccc66","#cccc99","#cccccc","#ccccff","#ffcc00","#ffcc33", + "#ffcc66","#ffcc99","#ffcccc","#ffccff","#00ff00","#00ff33","#00ff66","#00ff99", + "#00ffcc","#00ffff","#33ff00","#33ff33","#33ff66","#33ff99","#33ffcc","#33ffff", + "#66ff00","#66ff33","#66ff66","#66ff99","#66ffcc","#66ffff","#99ff00","#99ff33", + "#99ff66","#99ff99","#99ffcc","#99ffff","#ccff00","#ccff33","#ccff66","#ccff99", + "#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff" +]; + +var named = { + '#F0F8FF':'AliceBlue','#FAEBD7':'AntiqueWhite','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige', + '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'BlanchedAlmond','#0000FF':'Blue','#8A2BE2':'BlueViolet','#A52A2A':'Brown', + '#DEB887':'BurlyWood','#5F9EA0':'CadetBlue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'CornflowerBlue', + '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'DarkBlue','#008B8B':'DarkCyan','#B8860B':'DarkGoldenRod', + '#A9A9A9':'DarkGray','#A9A9A9':'DarkGrey','#006400':'DarkGreen','#BDB76B':'DarkKhaki','#8B008B':'DarkMagenta','#556B2F':'DarkOliveGreen', + '#FF8C00':'Darkorange','#9932CC':'DarkOrchid','#8B0000':'DarkRed','#E9967A':'DarkSalmon','#8FBC8F':'DarkSeaGreen','#483D8B':'DarkSlateBlue', + '#2F4F4F':'DarkSlateGray','#2F4F4F':'DarkSlateGrey','#00CED1':'DarkTurquoise','#9400D3':'DarkViolet','#FF1493':'DeepPink','#00BFFF':'DeepSkyBlue', + '#696969':'DimGray','#696969':'DimGrey','#1E90FF':'DodgerBlue','#B22222':'FireBrick','#FFFAF0':'FloralWhite','#228B22':'ForestGreen', + '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'GhostWhite','#FFD700':'Gold','#DAA520':'GoldenRod','#808080':'Gray','#808080':'Grey', + '#008000':'Green','#ADFF2F':'GreenYellow','#F0FFF0':'HoneyDew','#FF69B4':'HotPink','#CD5C5C':'IndianRed','#4B0082':'Indigo','#FFFFF0':'Ivory', + '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'LavenderBlush','#7CFC00':'LawnGreen','#FFFACD':'LemonChiffon','#ADD8E6':'LightBlue', + '#F08080':'LightCoral','#E0FFFF':'LightCyan','#FAFAD2':'LightGoldenRodYellow','#D3D3D3':'LightGray','#D3D3D3':'LightGrey','#90EE90':'LightGreen', + '#FFB6C1':'LightPink','#FFA07A':'LightSalmon','#20B2AA':'LightSeaGreen','#87CEFA':'LightSkyBlue','#778899':'LightSlateGray','#778899':'LightSlateGrey', + '#B0C4DE':'LightSteelBlue','#FFFFE0':'LightYellow','#00FF00':'Lime','#32CD32':'LimeGreen','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon', + '#66CDAA':'MediumAquaMarine','#0000CD':'MediumBlue','#BA55D3':'MediumOrchid','#9370D8':'MediumPurple','#3CB371':'MediumSeaGreen','#7B68EE':'MediumSlateBlue', + '#00FA9A':'MediumSpringGreen','#48D1CC':'MediumTurquoise','#C71585':'MediumVioletRed','#191970':'MidnightBlue','#F5FFFA':'MintCream','#FFE4E1':'MistyRose','#FFE4B5':'Moccasin', + '#FFDEAD':'NavajoWhite','#000080':'Navy','#FDF5E6':'OldLace','#808000':'Olive','#6B8E23':'OliveDrab','#FFA500':'Orange','#FF4500':'OrangeRed','#DA70D6':'Orchid', + '#EEE8AA':'PaleGoldenRod','#98FB98':'PaleGreen','#AFEEEE':'PaleTurquoise','#D87093':'PaleVioletRed','#FFEFD5':'PapayaWhip','#FFDAB9':'PeachPuff', + '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'PowderBlue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'RosyBrown','#4169E1':'RoyalBlue', + '#8B4513':'SaddleBrown','#FA8072':'Salmon','#F4A460':'SandyBrown','#2E8B57':'SeaGreen','#FFF5EE':'SeaShell','#A0522D':'Sienna','#C0C0C0':'Silver', + '#87CEEB':'SkyBlue','#6A5ACD':'SlateBlue','#708090':'SlateGray','#708090':'SlateGrey','#FFFAFA':'Snow','#00FF7F':'SpringGreen', + '#4682B4':'SteelBlue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet', + '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'WhiteSmoke','#FFFF00':'Yellow','#9ACD32':'YellowGreen' +}; + +function init() { + var inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color')); + + tinyMCEPopup.resizeToInnerSize(); + + generatePicker(); + + if (inputColor) { + changeFinalColor(inputColor); + + col = convertHexToRGB(inputColor); + + if (col) + updateLight(col.r, col.g, col.b); + } +} + +function insertAction() { + var color = document.getElementById("color").value, f = tinyMCEPopup.getWindowArg('func'); + + tinyMCEPopup.restoreSelection(); + + if (f) + f(color); + + tinyMCEPopup.close(); +} + +function showColor(color, name) { + if (name) + document.getElementById("colorname").innerHTML = name; + + document.getElementById("preview").style.backgroundColor = color; + document.getElementById("color").value = color.toLowerCase(); +} + +function convertRGBToHex(col) { + var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi"); + + if (!col) + return col; + + var rgb = col.replace(re, "$1,$2,$3").split(','); + if (rgb.length == 3) { + r = parseInt(rgb[0]).toString(16); + g = parseInt(rgb[1]).toString(16); + b = parseInt(rgb[2]).toString(16); + + r = r.length == 1 ? '0' + r : r; + g = g.length == 1 ? '0' + g : g; + b = b.length == 1 ? '0' + b : b; + + return "#" + r + g + b; + } + + return col; +} + +function convertHexToRGB(col) { + if (col.indexOf('#') != -1) { + col = col.replace(new RegExp('[^0-9A-F]', 'gi'), ''); + + r = parseInt(col.substring(0, 2), 16); + g = parseInt(col.substring(2, 4), 16); + b = parseInt(col.substring(4, 6), 16); + + return {r : r, g : g, b : b}; + } + + return null; +} + +function generatePicker() { + var el = document.getElementById('light'), h = '', i; + + for (i = 0; i < detail; i++){ + h += '
    '; + } + + el.innerHTML = h; +} + +function generateWebColors() { + var el = document.getElementById('webcolors'), h = '', i; + + if (el.className == 'generated') + return; + + h += '' + + ''; + + for (i=0; i' + + '' + + ''; + if ((i+1) % 18 == 0) + h += ''; + } + + h += '
    '; + + el.innerHTML = h; + el.className = 'generated'; +} + +function generateNamedColors() { + var el = document.getElementById('namedcolors'), h = '', n, v, i = 0; + + if (el.className == 'generated') + return; + + for (n in named) { + v = named[n]; + h += '' + } + + el.innerHTML = h; + el.className = 'generated'; +} + +function dechex(n) { + return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16); +} + +function computeColor(e) { + var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB; + + x = e.offsetX ? e.offsetX : (e.target ? e.clientX - e.target.x : 0); + y = e.offsetY ? e.offsetY : (e.target ? e.clientY - e.target.y : 0); + + partWidth = document.getElementById('colors').width / 6; + partDetail = detail / 2; + imHeight = document.getElementById('colors').height; + + r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255; + g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255 + (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth); + b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth); + + coef = (imHeight - y) / imHeight; + r = 128 + (r - 128) * coef; + g = 128 + (g - 128) * coef; + b = 128 + (b - 128) * coef; + + changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b)); + updateLight(r, g, b); +} + +function updateLight(r, g, b) { + var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color; + + for (i=0; i=0) && (i'); + }, + + init : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor; + + // Setup browse button + document.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image'); + if (isVisible('srcbrowser')) + document.getElementById('src').style.width = '180px'; + + e = ed.selection.getNode(); + + this.fillFileList('image_list', 'tinyMCEImageList'); + + if (e.nodeName == 'IMG') { + f.src.value = ed.dom.getAttrib(e, 'src'); + f.alt.value = ed.dom.getAttrib(e, 'alt'); + f.border.value = this.getAttrib(e, 'border'); + f.vspace.value = this.getAttrib(e, 'vspace'); + f.hspace.value = this.getAttrib(e, 'hspace'); + f.width.value = ed.dom.getAttrib(e, 'width'); + f.height.value = ed.dom.getAttrib(e, 'height'); + f.insert.value = ed.getLang('update'); + f.class_name.value = ed.dom.getAttrib(e, 'class'); + this.styleVal = ed.dom.getAttrib(e, 'style'); + selectByValue(f, 'image_list', f.src.value); + selectByValue(f, 'align', this.getAttrib(e, 'align')); + this.updateStyle(); + } + }, + + fillFileList : function(id, l) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + l = window[l]; + + if (l && l.length > 0) { + lst.options[lst.options.length] = new Option('', ''); + + tinymce.each(l, function(o) { + lst.options[lst.options.length] = new Option(o[0], o[1]); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + update : function() { + var f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, args = {}, el; + + tinyMCEPopup.restoreSelection(); + + if (f.src.value === '') { + if (ed.selection.getNode().nodeName == 'IMG') { + ed.dom.remove(ed.selection.getNode()); + ed.execCommand('mceRepaint'); + } + + tinyMCEPopup.close(); + return; + } + + if (!ed.settings.inline_styles) { + args = tinymce.extend(args, { + vspace : nl.vspace.value, + hspace : nl.hspace.value, + border : nl.border.value, + align : getSelectValue(f, 'align') + }); + } else + args.style = this.styleVal; + + tinymce.extend(args, { + src : f.src.value, + alt : f.alt.value, + width : f.width.value, + height : f.height.value, + 'class' : f.class_name.value + }); + + el = ed.selection.getNode(); + + if (el && el.nodeName == 'IMG') { + ed.dom.setAttribs(el, args); + } else { + ed.execCommand('mceInsertContent', false, '', {skip_undo : 1}); + ed.dom.setAttribs('__mce_tmp', args); + ed.dom.setAttrib('__mce_tmp', 'id', ''); + ed.undoManager.add(); + } + + tinyMCEPopup.close(); + }, + + updateStyle : function() { + var dom = tinyMCEPopup.dom, st, v, cls, oldcls, rep, f = document.forms[0]; + + if (tinyMCEPopup.editor.settings.inline_styles) { + st = tinyMCEPopup.dom.parseStyle(this.styleVal); + + // Handle align + v = getSelectValue(f, 'align'); + cls = f.class_name.value || ''; + cls = cls ? cls.replace(/alignright\s*|alignleft\s*|aligncenter\s*/g, '') : ''; + cls = cls ? cls.replace(/^\s*(.+?)\s*$/, '$1') : ''; + if (v) { + if (v == 'left' || v == 'right') { + st['float'] = v; + delete st['vertical-align']; + oldcls = cls ? ' '+cls : ''; + f.class_name.value = 'align' + v + oldcls; + } else { + st['vertical-align'] = v; + delete st['float']; + f.class_name.value = cls; + } + } else { + delete st['float']; + delete st['vertical-align']; + f.class_name.value = cls; + } + + // Handle border + v = f.border.value; + if (v || v == '0') { + if (v == '0') + st['border'] = '0'; + else + st['border'] = v + 'px solid black'; + } else + delete st['border']; + + // Handle hspace + v = f.hspace.value; + if (v) { + delete st['margin']; + st['margin-left'] = v + 'px'; + st['margin-right'] = v + 'px'; + } else { + delete st['margin-left']; + delete st['margin-right']; + } + + // Handle vspace + v = f.vspace.value; + if (v) { + delete st['margin']; + st['margin-top'] = v + 'px'; + st['margin-bottom'] = v + 'px'; + } else { + delete st['margin-top']; + delete st['margin-bottom']; + } + + // Merge + st = tinyMCEPopup.dom.parseStyle(dom.serializeStyle(st), 'img'); + this.styleVal = dom.serializeStyle(st, 'img'); + } + }, + + getAttrib : function(e, at) { + var ed = tinyMCEPopup.editor, dom = ed.dom, v, v2; + + if (ed.settings.inline_styles) { + switch (at) { + case 'align': + if (v = dom.getStyle(e, 'float')) + return v; + + if (v = dom.getStyle(e, 'vertical-align')) + return v; + + break; + + case 'hspace': + v = dom.getStyle(e, 'margin-left') + v2 = dom.getStyle(e, 'margin-right'); + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'vspace': + v = dom.getStyle(e, 'margin-top') + v2 = dom.getStyle(e, 'margin-bottom'); + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'border': + v = 0; + + tinymce.each(['top', 'right', 'bottom', 'left'], function(sv) { + sv = dom.getStyle(e, 'border-' + sv + '-width'); + + // False or not the same as prev + if (!sv || (sv != v && v !== 0)) { + v = 0; + return false; + } + + if (sv) + v = sv; + }); + + if (v) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + } + } + + if (v = dom.getAttrib(e, at)) + return v; + + return ''; + }, + + resetImageData : function() { + var f = document.forms[0]; + + f.width.value = f.height.value = ""; + }, + + updateImageData : function() { + var f = document.forms[0], t = ImageDialog; + + if (f.width.value == "") + f.width.value = t.preloadImg.width; + + if (f.height.value == "") + f.height.value = t.preloadImg.height; + }, + + getImageData : function() { + var f = document.forms[0]; + + this.preloadImg = new Image(); + this.preloadImg.onload = this.updateImageData; + this.preloadImg.onerror = this.resetImageData; + this.preloadImg.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(f.src.value); + } +}; + +ImageDialog.preInit(); +tinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog); diff --git a/src/wp-includes/js/tinymce/themes/advanced/js/link.js b/src/wp-includes/js/tinymce/themes/advanced/js/link.js new file mode 100644 index 00000000..73b9f597 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/js/link.js @@ -0,0 +1,156 @@ +tinyMCEPopup.requireLangPack(); + +var LinkDialog = { + preInit : function() { + var url; + + if (url = tinyMCEPopup.getParam("external_link_list_url")) + document.write(''); + }, + + init : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor; + + // Setup browse button + document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser', 'href', 'file', 'theme_advanced_link'); + if (isVisible('hrefbrowser')) + document.getElementById('href').style.width = '180px'; + + this.fillClassList('class_list'); + this.fillFileList('link_list', 'tinyMCELinkList'); + this.fillTargetList('target_list'); + + if (e = ed.dom.getParent(ed.selection.getNode(), 'A')) { + f.href.value = ed.dom.getAttrib(e, 'href'); + f.linktitle.value = ed.dom.getAttrib(e, 'title'); + f.insert.value = ed.getLang('update'); + selectByValue(f, 'link_list', f.href.value); + selectByValue(f, 'target_list', ed.dom.getAttrib(e, 'target')); + selectByValue(f, 'class_list', ed.dom.getAttrib(e, 'class')); + } + }, + + update : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor, e, b; + + tinyMCEPopup.restoreSelection(); + e = ed.dom.getParent(ed.selection.getNode(), 'A'); + + // Remove element if there is no href + if (!f.href.value) { + if (e) { + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + b = ed.selection.getBookmark(); + ed.dom.remove(e, 1); + ed.selection.moveToBookmark(b); + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + return; + } + } + + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + + // Create new anchor elements + if (e == null) { + ed.getDoc().execCommand("unlink", false, null); + tinyMCEPopup.execCommand("CreateLink", false, "#mce_temp_url#", {skip_undo : 1}); + + tinymce.each(ed.dom.select("a"), function(n) { + if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') { + e = n; + + ed.dom.setAttribs(e, { + href : f.href.value, + title : f.linktitle.value, + target : f.target_list ? getSelectValue(f, "target_list") : null, + 'class' : f.class_list ? getSelectValue(f, "class_list") : null + }); + } + }); + } else { + ed.dom.setAttribs(e, { + href : f.href.value, + title : f.linktitle.value, + target : f.target_list ? getSelectValue(f, "target_list") : null, + 'class' : f.class_list ? getSelectValue(f, "class_list") : null + }); + } + + // Don't move caret if selection was image + if (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') { + ed.focus(); + ed.selection.select(e); + ed.selection.collapse(0); + tinyMCEPopup.storeSelection(); + } + + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + }, + + checkPrefix : function(n) { + if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_email'))) + n.value = 'mailto:' + n.value; + + if (/^\s*www\./i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_external'))) + n.value = 'http://' + n.value; + }, + + fillFileList : function(id, l) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + l = window[l]; + + if (l && l.length > 0) { + lst.options[lst.options.length] = new Option('', ''); + + tinymce.each(l, function(o) { + lst.options[lst.options.length] = new Option(o[0], o[1]); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + fillClassList : function(id) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + if (v = tinyMCEPopup.getParam('theme_advanced_styles')) { + cl = []; + + tinymce.each(v.split(';'), function(v) { + var p = v.split('='); + + cl.push({'title' : p[0], 'class' : p[1]}); + }); + } else + cl = tinyMCEPopup.editor.dom.getClasses(); + + if (cl.length > 0) { + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); + + tinymce.each(cl, function(o) { + lst.options[lst.options.length] = new Option(o.title || o['class'], o['class']); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + fillTargetList : function(id) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v; + + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_same'), '_self'); + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_blank'), '_blank'); + + if (v = tinyMCEPopup.getParam('theme_advanced_link_targets')) { + tinymce.each(v.split(','), function(v) { + v = v.split('='); + lst.options[lst.options.length] = new Option(v[0], v[1]); + }); + } + } +}; + +LinkDialog.preInit(); +tinyMCEPopup.onInit.add(LinkDialog.init, LinkDialog); diff --git a/src/wp-includes/js/tinymce/themes/advanced/js/source_editor.js b/src/wp-includes/js/tinymce/themes/advanced/js/source_editor.js new file mode 100644 index 00000000..4f61d1c7 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/js/source_editor.js @@ -0,0 +1,56 @@ +tinyMCEPopup.requireLangPack(); +tinyMCEPopup.onInit.add(onLoadInit); + +function saveContent() { + tinyMCEPopup.editor.setContent(document.getElementById('htmlSource').value, {source_view : true}); + tinyMCEPopup.close(); +} + +function onLoadInit() { + tinyMCEPopup.resizeToInnerSize(); + + // Remove Gecko spellchecking + if (tinymce.isGecko) + document.body.spellcheck = tinyMCEPopup.editor.getParam("gecko_spellcheck"); + + document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent({source_view : true}); + + if (tinyMCEPopup.editor.getParam("theme_advanced_source_editor_wrap", true)) { + setWrap('soft'); + document.getElementById('wraped').checked = true; + } + + resizeInputs(); +} + +function setWrap(val) { + var v, n, s = document.getElementById('htmlSource'); + + s.wrap = val; + + if (!tinymce.isIE) { + v = s.value; + n = s.cloneNode(false); + n.setAttribute("wrap", val); + s.parentNode.replaceChild(n, s); + n.value = v; + } +} + +function toggleWordWrap(elm) { + if (elm.checked) + setWrap('soft'); + else + setWrap('off'); +} + +function resizeInputs() { + var vp = tinyMCEPopup.dom.getViewPort(window), el; + + el = document.getElementById('htmlSource'); + + if (el) { + el.style.width = (vp.w - 20) + 'px'; + el.style.height = (vp.h - 65) + 'px'; + } +} diff --git a/src/wp-includes/js/tinymce/themes/advanced/link.htm b/src/wp-includes/js/tinymce/themes/advanced/link.htm new file mode 100644 index 00000000..e0eb4ba3 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/link.htm @@ -0,0 +1,63 @@ + + + + {#advanced_dlg.link_title} + + + + + + + +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
     
    +
    +
    + +
    +
    + +
    + +
    + +
    +
    +
    + + diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/content.css b/src/wp-includes/js/tinymce/themes/advanced/skins/default/content.css new file mode 100644 index 00000000..dd8fb95e --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/default/content.css @@ -0,0 +1,36 @@ +body, td, pre {color:#000; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;} +body {background:#FFF;} +body.mceForceColors {background:#FFF; color:#000;} +h1 {font-size: 2em} +h2 {font-size: 1.5em} +h3 {font-size: 1.17em} +h4 {font-size: 1em} +h5 {font-size: .83em} +h6 {font-size: .75em} +.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} +a.mceItemAnchor {display:inline-block; width:11px !important; height:11px !important; background:url(img/items.gif) no-repeat 0 0;} +span.mceItemNbsp {background: #DDD} +td.mceSelected, th.mceSelected {background-color:#3399ff !important} +img {border:0;} +table {cursor:default} +table td, table th {cursor:text} +ins {border-bottom:1px solid green; text-decoration: none; color:green} +del {color:red; text-decoration:line-through} +cite {border-bottom:1px dashed blue} +acronym {border-bottom:1px dotted #CCC; cursor:help} +abbr {border-bottom:1px dashed #CCC; cursor:help} + +/* IE */ +* html body { +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +} + +img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} +font[face=mceinline] {font-family:inherit !important} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/dialog.css b/src/wp-includes/js/tinymce/themes/advanced/skins/default/dialog.css new file mode 100644 index 00000000..1f5598c6 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/default/dialog.css @@ -0,0 +1,117 @@ +/* Generic */ +body { +font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDDDDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +background:#F0F0EE; +padding:0; +margin:8px 8px 0 8px; +} + +html {background:#F0F0EE;} +td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +textarea {resize:none;outline:none;} +a:link, a:visited {color:black;} +a:hover {color:#2B6FB6;} +.nowrap {white-space: nowrap} + +/* Forms */ +fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;} +legend {color:#2B6FB6; font-weight:bold;} +label.msg {display:none;} +label.invalid {color:#EE0000; display:inline;} +input.invalid {border:1px solid #EE0000;} +input {background:#FFF; border:1px solid #CCC;} +input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +input, select, textarea {border:1px solid #808080;} +input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} +input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} +.input_noborder {border:0;} + +/* Buttons */ +#insert, #cancel, input.button, .updateButton { +border:0; margin:0; padding:0; +font-weight:bold; +width:94px; height:26px; +background:url(img/buttons.png) 0 -26px; +cursor:pointer; +padding-bottom:2px; +float:left; +} + +#insert {background:url(img/buttons.png) 0 -52px} +#cancel {background:url(img/buttons.png) 0 0; float:right} + +/* Browse */ +a.pickcolor, a.browse {text-decoration:none} +a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} +.mceOldBoxModel a.browse span {width:22px; height:20px;} +a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} +a.browse span.disabled {border:1px solid white; opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} +a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} +.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} +a.pickcolor:hover span {background-color:#B2BBD0;} +a.pickcolor:hover span.disabled {} + +/* Charmap */ +table.charmap {border:1px solid #AAA; text-align:center} +td.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;} +#charmap a {display:block; color:#000; text-decoration:none; border:0} +#charmap a:hover {background:#CCC;color:#2B6FB6} +#charmap #codeN {font-size:10px; font-family:Arial,Helvetica,sans-serif; text-align:center} +#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center} + +/* Source */ +.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} +.mceActionPanel {margin-top:5px;} + +/* Tabs classes */ +.tabs {width:100%; height:18px; line-height:normal; background:url(img/tabs.gif) repeat-x 0 -72px;} +.tabs ul {margin:0; padding:0; list-style:none;} +.tabs li {float:left; background:url(img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:17px; height:18px; display:block;} +.tabs li.current {background:url(img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} +.tabs span {float:left; display:block; background:url(img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} +.tabs .current span {background:url(img/tabs.gif) no-repeat right -54px;} +.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} +.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} + +/* Panels */ +.panel_wrapper div.panel {display:none;} +.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} +.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} + +/* Columns */ +.column {float:left;} +.properties {width:100%;} +.properties .column1 {} +.properties .column2 {text-align:left;} + +/* Titles */ +h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} +h3 {font-size:14px;} +.title {font-size:12px; font-weight:bold; color:#2B6FB6;} + +/* Dialog specific */ +#link .panel_wrapper, #link div.current {height:125px;} +#image .panel_wrapper, #image div.current {height:200px;} +#plugintable thead {font-weight:bold; background:#DDD;} +#plugintable, #about #plugintable td {border:1px solid #919B9C;} +#plugintable {width:96%; margin-top:10px;} +#pluginscontainer {height:290px; overflow:auto;} +#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} +#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} +#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} +#colorpicker #light div {overflow:hidden;} +#colorpicker #previewblock {float:right; padding-left:10px; height:20px;} +#colorpicker .panel_wrapper div.current {height:175px;} +#colorpicker #namedcolors {width:150px;} +#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} +#colorpicker #colornamecontainer {margin-top:5px;} +#colorpicker #picker_panel fieldset {margin:auto;width:325px;} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/buttons.png b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/buttons.png new file mode 100644 index 00000000..7dd58418 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/buttons.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/items.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/items.gif new file mode 100644 index 00000000..2eafd795 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/items.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/menu_arrow.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/menu_arrow.gif new file mode 100644 index 00000000..85e31dfb Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/menu_arrow.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/menu_check.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/menu_check.gif new file mode 100644 index 00000000..adfdddcc Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/menu_check.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/progress.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/progress.gif new file mode 100644 index 00000000..5bb90fd6 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/progress.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/tabs.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/tabs.gif new file mode 100644 index 00000000..ce4be635 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/default/img/tabs.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/default/ui.css b/src/wp-includes/js/tinymce/themes/advanced/skins/default/ui.css new file mode 100644 index 00000000..7f6cf5fd --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/default/ui.css @@ -0,0 +1,213 @@ +/* Reset */ +.defaultSkin table, .defaultSkin tbody, .defaultSkin a, .defaultSkin img, .defaultSkin tr, .defaultSkin div, .defaultSkin td, .defaultSkin iframe, .defaultSkin span, .defaultSkin *, .defaultSkin .mceText {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate; text-align:left} +.defaultSkin a:hover, .defaultSkin a:link, .defaultSkin a:visited, .defaultSkin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000} +.defaultSkin table td {vertical-align:middle} + +/* Containers */ +.defaultSkin table {direction:ltr; background:#F0F0EE} +.defaultSkin iframe {display:block; background:#FFF} +.defaultSkin .mceToolbar {height:26px} +.defaultSkin .mceLeft {text-align:left} +.defaultSkin .mceRight {text-align:right} + +/* External */ +.defaultSkin .mceExternalToolbar {position:absolute; border:1px solid #CCC; border-bottom:0; display:none;} +.defaultSkin .mceExternalToolbar td.mceToolbar {padding-right:13px;} +.defaultSkin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0} + +/* Layout */ +.defaultSkin table.mceLayout {border:0; border-left:1px solid #CCC; border-right:1px solid #CCC} +.defaultSkin table.mceLayout tr.mceFirst td {border-top:1px solid #CCC} +.defaultSkin table.mceLayout tr.mceLast td {border-bottom:1px solid #CCC} +.defaultSkin table.mceToolbar, .defaultSkin tr.mceFirst .mceToolbar tr td, .defaultSkin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0;} +.defaultSkin td.mceToolbar {padding-top:1px; vertical-align:top} +.defaultSkin .mceIframeContainer {border-top:1px solid #CCC; border-bottom:1px solid #CCC} +.defaultSkin .mceStatusbar {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; display:block; height:20px} +.defaultSkin .mceStatusbar div {float:left; margin:2px} +.defaultSkin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0} +.defaultSkin .mceStatusbar a:hover {text-decoration:underline} +.defaultSkin table.mceToolbar {margin-left:3px} +.defaultSkin span.mceIcon, .defaultSkin img.mceIcon {display:block; width:20px; height:20px} +.defaultSkin .mceIcon {background:url(../../img/icons.gif) no-repeat 20px 20px} +.defaultSkin td.mceCenter {text-align:center;} +.defaultSkin td.mceCenter table {margin:0 auto; text-align:left;} +.defaultSkin td.mceRight table {margin:0 0 0 auto;} + +/* Button */ +.defaultSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px; margin-right:1px} +.defaultSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0} +.defaultSkin a.mceButtonActive, .defaultSkin a.mceButtonSelected {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceButtonDisabled .mceIcon {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +.defaultSkin .mceButtonLabeled {width:auto} +.defaultSkin .mceButtonLabeled span.mceIcon {float:left} +.defaultSkin span.mceButtonLabel {display:block; font-size:10px; padding:4px 6px 0 22px; font-family:Tahoma,Verdana,Arial,Helvetica} +.defaultSkin .mceButtonDisabled .mceButtonLabel {color:#888} + +/* Separator */ +.defaultSkin .mceSeparator {display:block; background:url(../../img/icons.gif) -180px 0; width:2px; height:20px; margin:2px 2px 0 4px} + +/* ListBox */ +.defaultSkin .mceListBox, .defaultSkin .mceListBox a {display:block} +.defaultSkin .mceListBox .mceText {padding-left:4px; width:70px; text-align:left; border:1px solid #CCC; border-right:0; background:#FFF; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} +.defaultSkin .mceListBox .mceOpen {width:9px; height:20px; background:url(../../img/icons.gif) -741px 0; margin-right:2px; border:1px solid #CCC;} +.defaultSkin table.mceListBoxEnabled:hover .mceText, .defaultSkin .mceListBoxHover .mceText, .defaultSkin .mceListBoxSelected .mceText {border:1px solid #A2ABC0; border-right:0; background:#FFF} +.defaultSkin table.mceListBoxEnabled:hover .mceOpen, .defaultSkin .mceListBoxHover .mceOpen, .defaultSkin .mceListBoxSelected .mceOpen {background-color:#FFF; border:1px solid #A2ABC0} +.defaultSkin .mceListBoxDisabled a.mceText {color:gray; background-color:transparent;} +.defaultSkin .mceListBoxMenu {overflow:auto; overflow-x:hidden} +.defaultSkin .mceOldBoxModel .mceListBox .mceText {height:22px} +.defaultSkin .mceOldBoxModel .mceListBox .mceOpen {width:11px; height:22px;} +.defaultSkin select.mceNativeListBox {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:7pt; background:#F0F0EE; border:1px solid gray; margin-right:2px;} + +/* SplitButton */ +.defaultSkin .mceSplitButton {width:32px; height:20px; direction:ltr} +.defaultSkin .mceSplitButton a, .defaultSkin .mceSplitButton span {height:20px; display:block} +.defaultSkin .mceSplitButton a.mceAction {width:20px; border:1px solid #F0F0EE; border-right:0;} +.defaultSkin .mceSplitButton span.mceAction {width:20px; background-image:url(../../img/icons.gif);} +.defaultSkin .mceSplitButton a.mceOpen {width:9px; background:url(../../img/icons.gif) -741px 0; border:1px solid #F0F0EE;} +.defaultSkin .mceSplitButton span.mceOpen {display:none} +.defaultSkin table.mceSplitButtonEnabled:hover a.mceAction, .defaultSkin .mceSplitButtonHover a.mceAction, .defaultSkin .mceSplitButtonSelected a.mceAction {border:1px solid #0A246A; border-right:0; background-color:#B2BBD0} +.defaultSkin table.mceSplitButtonEnabled:hover a.mceOpen, .defaultSkin .mceSplitButtonHover a.mceOpen, .defaultSkin .mceSplitButtonSelected a.mceOpen {background-color:#B2BBD0; border:1px solid #0A246A;} +.defaultSkin .mceSplitButtonDisabled .mceAction, .defaultSkin .mceSplitButtonDisabled a.mceOpen {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +.defaultSkin .mceSplitButtonActive a.mceAction {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceSplitButtonActive a.mceOpen {border-left:0;} + +/* ColorSplitButton */ +.defaultSkin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray} +.defaultSkin .mceColorSplitMenu td {padding:2px} +.defaultSkin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080} +.defaultSkin .mceColorSplitMenu td.mceMoreColors {padding:1px 3px 1px 1px} +.defaultSkin .mceColorSplitMenu a.mceMoreColors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF} +.defaultSkin .mceColorSplitMenu a.mceMoreColors:hover {border:1px solid #0A246A; background-color:#B6BDD2} +.defaultSkin a.mceMoreColors:hover {border:1px solid #0A246A} +.defaultSkin .mceColorPreview {margin-left:2px; width:16px; height:4px; overflow:hidden; background:#9a9b9a} +.defaultSkin .mce_forecolor span.mceAction, .defaultSkin .mce_backcolor span.mceAction {overflow:hidden; height:16px} + +/* Menu */ +.defaultSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8} +.defaultSkin .mceNoIcons span.mceIcon {width:0;} +.defaultSkin .mceNoIcons a .mceText {padding-left:10px} +.defaultSkin .mceMenu table {background:#FFF} +.defaultSkin .mceMenu a, .defaultSkin .mceMenu span, .defaultSkin .mceMenu {display:block} +.defaultSkin .mceMenu td {height:20px} +.defaultSkin .mceMenu a {position:relative;padding:3px 0 4px 0} +.defaultSkin .mceMenu .mceText {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block} +.defaultSkin .mceMenu span.mceText, .defaultSkin .mceMenu .mcePreview {font-size:11px} +.defaultSkin .mceMenu pre.mceText {font-family:Monospace} +.defaultSkin .mceMenu .mceIcon {position:absolute; top:0; left:0; width:22px;} +.defaultSkin .mceMenu .mceMenuItemEnabled a:hover, .defaultSkin .mceMenu .mceMenuItemActive {background-color:#dbecf3} +.defaultSkin td.mceMenuItemSeparator {background:#DDD; height:1px} +.defaultSkin .mceMenuItemTitle a {border:0; background:#EEE; border-bottom:1px solid #DDD} +.defaultSkin .mceMenuItemTitle span.mceText {color:#000; font-weight:bold; padding-left:4px} +.defaultSkin .mceMenuItemDisabled .mceText {color:#888} +.defaultSkin .mceMenuItemSelected .mceIcon {background:url(img/menu_check.gif)} +.defaultSkin .mceNoIcons .mceMenuItemSelected a {background:url(img/menu_arrow.gif) no-repeat -6px center} +.defaultSkin .mceMenu span.mceMenuLine {display:none} +.defaultSkin .mceMenuItemSub a {background:url(img/menu_arrow.gif) no-repeat top right;} + +/* Progress,Resize */ +.defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50); background:#FFF} +.defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} + +/* Formats */ +.defaultSkin .mce_formatPreview a {font-size:10px} +.defaultSkin .mce_p span.mceText {} +.defaultSkin .mce_address span.mceText {font-style:italic} +.defaultSkin .mce_pre span.mceText {font-family:monospace} +.defaultSkin .mce_h1 span.mceText {font-weight:bolder; font-size: 2em} +.defaultSkin .mce_h2 span.mceText {font-weight:bolder; font-size: 1.5em} +.defaultSkin .mce_h3 span.mceText {font-weight:bolder; font-size: 1.17em} +.defaultSkin .mce_h4 span.mceText {font-weight:bolder; font-size: 1em} +.defaultSkin .mce_h5 span.mceText {font-weight:bolder; font-size: .83em} +.defaultSkin .mce_h6 span.mceText {font-weight:bolder; font-size: .75em} + +/* Theme */ +.defaultSkin span.mce_bold {background-position:0 0} +.defaultSkin span.mce_italic {background-position:-60px 0} +.defaultSkin span.mce_underline {background-position:-140px 0} +.defaultSkin span.mce_strikethrough {background-position:-120px 0} +.defaultSkin span.mce_undo {background-position:-160px 0} +.defaultSkin span.mce_redo {background-position:-100px 0} +.defaultSkin span.mce_cleanup {background-position:-40px 0} +.defaultSkin span.mce_bullist {background-position:-20px 0} +.defaultSkin span.mce_numlist {background-position:-80px 0} +.defaultSkin span.mce_justifyleft {background-position:-460px 0} +.defaultSkin span.mce_justifyright {background-position:-480px 0} +.defaultSkin span.mce_justifycenter {background-position:-420px 0} +.defaultSkin span.mce_justifyfull {background-position:-440px 0} +.defaultSkin span.mce_anchor {background-position:-200px 0} +.defaultSkin span.mce_indent {background-position:-400px 0} +.defaultSkin span.mce_outdent {background-position:-540px 0} +.defaultSkin span.mce_link {background-position:-500px 0} +.defaultSkin span.mce_unlink {background-position:-640px 0} +.defaultSkin span.mce_sub {background-position:-600px 0} +.defaultSkin span.mce_sup {background-position:-620px 0} +.defaultSkin span.mce_removeformat {background-position:-580px 0} +.defaultSkin span.mce_newdocument {background-position:-520px 0} +.defaultSkin span.mce_image {background-position:-380px 0} +.defaultSkin span.mce_help {background-position:-340px 0} +.defaultSkin span.mce_code {background-position:-260px 0} +.defaultSkin span.mce_hr {background-position:-360px 0} +.defaultSkin span.mce_visualaid {background-position:-660px 0} +.defaultSkin span.mce_charmap {background-position:-240px 0} +.defaultSkin span.mce_paste {background-position:-560px 0} +.defaultSkin span.mce_copy {background-position:-700px 0} +.defaultSkin span.mce_cut {background-position:-680px 0} +.defaultSkin span.mce_blockquote {background-position:-220px 0} +.defaultSkin .mce_forecolor span.mceAction {background-position:-720px 0} +.defaultSkin .mce_backcolor span.mceAction {background-position:-760px 0} +.defaultSkin span.mce_forecolorpicker {background-position:-720px 0} +.defaultSkin span.mce_backcolorpicker {background-position:-760px 0} + +/* Plugins */ +.defaultSkin span.mce_advhr {background-position:-0px -20px} +.defaultSkin span.mce_ltr {background-position:-20px -20px} +.defaultSkin span.mce_rtl {background-position:-40px -20px} +.defaultSkin span.mce_emotions {background-position:-60px -20px} +.defaultSkin span.mce_fullpage {background-position:-80px -20px} +.defaultSkin span.mce_fullscreen {background-position:-100px -20px} +.defaultSkin span.mce_iespell {background-position:-120px -20px} +.defaultSkin span.mce_insertdate {background-position:-140px -20px} +.defaultSkin span.mce_inserttime {background-position:-160px -20px} +.defaultSkin span.mce_absolute {background-position:-180px -20px} +.defaultSkin span.mce_backward {background-position:-200px -20px} +.defaultSkin span.mce_forward {background-position:-220px -20px} +.defaultSkin span.mce_insert_layer {background-position:-240px -20px} +.defaultSkin span.mce_insertlayer {background-position:-260px -20px} +.defaultSkin span.mce_movebackward {background-position:-280px -20px} +.defaultSkin span.mce_moveforward {background-position:-300px -20px} +.defaultSkin span.mce_media {background-position:-320px -20px} +.defaultSkin span.mce_nonbreaking {background-position:-340px -20px} +.defaultSkin span.mce_pastetext {background-position:-360px -20px} +.defaultSkin span.mce_pasteword {background-position:-380px -20px} +.defaultSkin span.mce_selectall {background-position:-400px -20px} +.defaultSkin span.mce_preview {background-position:-420px -20px} +.defaultSkin span.mce_print {background-position:-440px -20px} +.defaultSkin span.mce_cancel {background-position:-460px -20px} +.defaultSkin span.mce_save {background-position:-480px -20px} +.defaultSkin span.mce_replace {background-position:-500px -20px} +.defaultSkin span.mce_search {background-position:-520px -20px} +.defaultSkin span.mce_styleprops {background-position:-560px -20px} +.defaultSkin span.mce_table {background-position:-580px -20px} +.defaultSkin span.mce_cell_props {background-position:-600px -20px} +.defaultSkin span.mce_delete_table {background-position:-620px -20px} +.defaultSkin span.mce_delete_col {background-position:-640px -20px} +.defaultSkin span.mce_delete_row {background-position:-660px -20px} +.defaultSkin span.mce_col_after {background-position:-680px -20px} +.defaultSkin span.mce_col_before {background-position:-700px -20px} +.defaultSkin span.mce_row_after {background-position:-720px -20px} +.defaultSkin span.mce_row_before {background-position:-740px -20px} +.defaultSkin span.mce_merge_cells {background-position:-760px -20px} +.defaultSkin span.mce_table_props {background-position:-980px -20px} +.defaultSkin span.mce_row_props {background-position:-780px -20px} +.defaultSkin span.mce_split_cells {background-position:-800px -20px} +.defaultSkin span.mce_template {background-position:-820px -20px} +.defaultSkin span.mce_visualchars {background-position:-840px -20px} +.defaultSkin span.mce_abbr {background-position:-860px -20px} +.defaultSkin span.mce_acronym {background-position:-880px -20px} +.defaultSkin span.mce_attribs {background-position:-900px -20px} +.defaultSkin span.mce_cite {background-position:-920px -20px} +.defaultSkin span.mce_del {background-position:-940px -20px} +.defaultSkin span.mce_ins {background-position:-960px -20px} +.defaultSkin span.mce_pagebreak {background-position:0 -40px} +.defaultSkin span.mce_restoredraft {background-position:-20px -40px} +.defaultSkin span.mce_spellchecker {background-position:-540px -20px} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/content.css b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/content.css new file mode 100644 index 00000000..500fa0de --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/content.css @@ -0,0 +1,36 @@ +body, td, pre {color:#000; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;} +body {background:#FFF;} +body.mceForceColors {background:#FFF; color:#000;} +h1 {font-size: 2em} +h2 {font-size: 1.5em} +h3 {font-size: 1.17em} +h4 {font-size: 1em} +h5 {font-size: .83em} +h6 {font-size: .75em} +.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} +a.mceItemAnchor {display:inline-block; width:11px !important; height:11px !important; background:url(../default/img/items.gif) no-repeat 0 0;} +span.mceItemNbsp {background: #DDD} +td.mceSelected, th.mceSelected {background-color:#3399ff !important} +img {border:0;} +table {cursor:default} +table td, table th {cursor:text} +ins {border-bottom:1px solid green; text-decoration: none; color:green} +del {color:red; text-decoration:line-through} +cite {border-bottom:1px dashed blue} +acronym {border-bottom:1px dotted #CCC; cursor:help} +abbr {border-bottom:1px dashed #CCC; cursor:help} + +/* IE */ +* html body { +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +} + +img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} +font[face=mceinline] {font-family:inherit !important} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/dialog.css b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/dialog.css new file mode 100644 index 00000000..3b0760a6 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/dialog.css @@ -0,0 +1,116 @@ +/* Generic */ +body { +font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDDDDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +background:#F0F0EE; +padding:0; +margin:8px 8px 0 8px; +} + +html {background:#F0F0EE;} +td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +textarea {resize:none;outline:none;} +a:link, a:visited {color:black;} +a:hover {color:#2B6FB6;} +.nowrap {white-space: nowrap} + +/* Forms */ +fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;} +legend {color:#2B6FB6; font-weight:bold;} +label.msg {display:none;} +label.invalid {color:#EE0000; display:inline;} +input.invalid {border:1px solid #EE0000;} +input {background:#FFF; border:1px solid #CCC;} +input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +input, select, textarea {border:1px solid #808080;} +input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} +input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} +.input_noborder {border:0;} + +/* Buttons */ +#insert, #cancel, input.button, .updateButton { +border:0; margin:0; padding:0; +font-weight:bold; +width:94px; height:26px; +background:url(../default/img/buttons.png) 0 -26px; +cursor:pointer; +padding-bottom:2px; +float:left; +} + +#insert {background:url(../default/img/buttons.png) 0 -52px} +#cancel {background:url(../default/img/buttons.png) 0 0; float:right} + +/* Browse */ +a.pickcolor, a.browse {text-decoration:none} +a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} +.mceOldBoxModel a.browse span {width:22px; height:20px;} +a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} +a.browse span.disabled {border:1px solid white; opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} +a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} +.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} +a.pickcolor:hover span {background-color:#B2BBD0;} +a.pickcolor:hover span.disabled {} + +/* Charmap */ +table.charmap {border:1px solid #AAA; text-align:center} +td.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;} +#charmap a {display:block; color:#000; text-decoration:none; border:0} +#charmap a:hover {background:#CCC;color:#2B6FB6} +#charmap #codeN {font-size:10px; font-family:Arial,Helvetica,sans-serif; text-align:center} +#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center} + +/* Source */ +.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} +.mceActionPanel {margin-top:5px;} + +/* Tabs classes */ +.tabs {width:100%; height:18px; line-height:normal; background:url(../default/img/tabs.gif) repeat-x 0 -72px;} +.tabs ul {margin:0; padding:0; list-style:none;} +.tabs li {float:left; background:url(../default/img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:17px; height:18px; display:block;} +.tabs li.current {background:url(../default/img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} +.tabs span {float:left; display:block; background:url(../default/img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} +.tabs .current span {background:url(../default/img/tabs.gif) no-repeat right -54px;} +.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} +.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} + +/* Panels */ +.panel_wrapper div.panel {display:none;} +.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} +.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} + +/* Columns */ +.column {float:left;} +.properties {width:100%;} +.properties .column1 {} +.properties .column2 {text-align:left;} + +/* Titles */ +h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} +h3 {font-size:14px;} +.title {font-size:12px; font-weight:bold; color:#2B6FB6;} + +/* Dialog specific */ +#link .panel_wrapper, #link div.current {height:125px;} +#image .panel_wrapper, #image div.current {height:200px;} +#plugintable thead {font-weight:bold; background:#DDD;} +#plugintable, #about #plugintable td {border:1px solid #919B9C;} +#plugintable {width:96%; margin-top:10px;} +#pluginscontainer {height:290px; overflow:auto;} +#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} +#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} +#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} +#colorpicker #light div {overflow:hidden;} +#colorpicker #previewblock {float:right; padding-left:10px; height:20px;} +#colorpicker .panel_wrapper div.current {height:175px;} +#colorpicker #namedcolors {width:150px;} +#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} +#colorpicker #colornamecontainer {margin-top:5px;} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg.png b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg.png new file mode 100644 index 00000000..12cfb419 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg_black.png b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg_black.png new file mode 100644 index 00000000..8996c749 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg_black.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg_silver.png b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg_silver.png new file mode 100644 index 00000000..bd5d2550 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/img/button_bg_silver.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui.css b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui.css new file mode 100644 index 00000000..52f5760f --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui.css @@ -0,0 +1,215 @@ +/* Reset */ +.o2k7Skin table, .o2k7Skin tbody, .o2k7Skin a, .o2k7Skin img, .o2k7Skin tr, .o2k7Skin div, .o2k7Skin td, .o2k7Skin iframe, .o2k7Skin span, .o2k7Skin *, .o2k7Skin .mceText {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate; text-align:left} +.o2k7Skin a:hover, .o2k7Skin a:link, .o2k7Skin a:visited, .o2k7Skin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000} +.o2k7Skin table td {vertical-align:middle} + +/* Containers */ +.o2k7Skin table {background:#E5EFFD} +.o2k7Skin iframe {display:block; background:#FFF} +.o2k7Skin .mceToolbar {height:26px} + +/* External */ +.o2k7Skin .mceExternalToolbar {position:absolute; border:1px solid #ABC6DD; border-bottom:0; display:none} +.o2k7Skin .mceExternalToolbar td.mceToolbar {padding-right:13px;} +.o2k7Skin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0} + +/* Layout */ +.o2k7Skin table.mceLayout {border:0; border-left:1px solid #ABC6DD; border-right:1px solid #ABC6DD} +.o2k7Skin table.mceLayout tr.mceFirst td {border-top:1px solid #ABC6DD} +.o2k7Skin table.mceLayout tr.mceLast td {border-bottom:1px solid #ABC6DD} +.o2k7Skin table.mceToolbar, .o2k7Skin tr.mceFirst .mceToolbar tr td, .o2k7Skin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0} +.o2k7Skin .mceIframeContainer {border-top:1px solid #ABC6DD; border-bottom:1px solid #ABC6DD} +.o2k7Skin .mceStatusbar {display:block; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; height:20px} +.o2k7Skin .mceStatusbar div {float:left; padding:2px} +.o2k7Skin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0} +.o2k7Skin .mceStatusbar a:hover {text-decoration:underline} +.o2k7Skin table.mceToolbar {margin-left:3px} +.o2k7Skin .mceToolbar .mceToolbarStart span {display:block; background:url(img/button_bg.png) -22px 0; width:1px; height:22px; margin-left:3px;} +.o2k7Skin .mceToolbar td.mceFirst span {margin:0} +.o2k7Skin .mceToolbar .mceToolbarEnd span {display:block; background:url(img/button_bg.png) -22px 0; width:1px; height:22px} +.o2k7Skin .mceToolbar .mceToolbarEndListBox span, .o2k7Skin .mceToolbar .mceToolbarStartListBox span {display:none} +.o2k7Skin span.mceIcon, .o2k7Skin img.mceIcon {display:block; width:20px; height:20px} +.o2k7Skin .mceIcon {background:url(../../img/icons.gif) no-repeat 20px 20px} +.o2k7Skin td.mceCenter {text-align:center;} +.o2k7Skin td.mceCenter table {margin:0 auto; text-align:left;} +.o2k7Skin td.mceRight table {margin:0 0 0 auto;} + +/* Button */ +.o2k7Skin .mceButton {display:block; background:url(img/button_bg.png); width:22px; height:22px} +.o2k7Skin a.mceButton span, .o2k7Skin a.mceButton img {margin-left:1px} +.o2k7Skin .mceOldBoxModel a.mceButton span, .o2k7Skin .mceOldBoxModel a.mceButton img {margin:0 0 0 1px} +.o2k7Skin a.mceButtonEnabled:hover {background-color:#B2BBD0; background-position:0 -22px} +.o2k7Skin a.mceButtonActive, .o2k7Skin a.mceButtonSelected {background-position:0 -44px} +.o2k7Skin .mceButtonDisabled .mceIcon {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +.o2k7Skin .mceButtonLabeled {width:auto} +.o2k7Skin .mceButtonLabeled span.mceIcon {float:left} +.o2k7Skin span.mceButtonLabel {display:block; font-size:10px; padding:4px 6px 0 22px; font-family:Tahoma,Verdana,Arial,Helvetica} +.o2k7Skin .mceButtonDisabled .mceButtonLabel {color:#888} + +/* Separator */ +.o2k7Skin .mceSeparator {display:block; background:url(img/button_bg.png) -22px 0; width:5px; height:22px} + +/* ListBox */ +.o2k7Skin .mceListBox {margin-left:3px} +.o2k7Skin .mceListBox, .o2k7Skin .mceListBox a {display:block} +.o2k7Skin .mceListBox .mceText {padding-left:4px; text-align:left; width:70px; border:1px solid #b3c7e1; border-right:0; background:#eaf2fb; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} +.o2k7Skin .mceListBox .mceOpen {width:14px; height:22px; background:url(img/button_bg.png) -66px 0} +.o2k7Skin table.mceListBoxEnabled:hover .mceText, .o2k7Skin .mceListBoxHover .mceText, .o2k7Skin .mceListBoxSelected .mceText {background:#FFF} +.o2k7Skin table.mceListBoxEnabled:hover .mceOpen, .o2k7Skin .mceListBoxHover .mceOpen, .o2k7Skin .mceListBoxSelected .mceOpen {background-position:-66px -22px} +.o2k7Skin .mceListBoxDisabled .mceText {color:gray} +.o2k7Skin .mceListBoxMenu {overflow:auto; overflow-x:hidden} +.o2k7Skin .mceOldBoxModel .mceListBox .mceText {height:22px} +.o2k7Skin select.mceListBox {font-family:Tahoma,Verdana,Arial,Helvetica; font-size:12px; border:1px solid #b3c7e1; background:#FFF;} + +/* SplitButton */ +.o2k7Skin .mceSplitButton, .o2k7Skin .mceSplitButton a, .o2k7Skin .mceSplitButton span {display:block; height:22px} +.o2k7Skin .mceSplitButton {background:url(img/button_bg.png)} +.o2k7Skin .mceSplitButton a.mceAction {width:22px} +.o2k7Skin .mceSplitButton span.mceAction {width:22px; background-image:url(../../img/icons.gif)} +.o2k7Skin .mceSplitButton a.mceOpen {width:10px; background:url(img/button_bg.png) -44px 0} +.o2k7Skin .mceSplitButton span.mceOpen {display:none} +.o2k7Skin table.mceSplitButtonEnabled:hover a.mceAction, .o2k7Skin .mceSplitButtonHover a.mceAction, .o2k7Skin .mceSplitButtonSelected {background:url(img/button_bg.png) 0 -22px} +.o2k7Skin table.mceSplitButtonEnabled:hover a.mceOpen, .o2k7Skin .mceSplitButtonHover a.mceOpen, .o2k7Skin .mceSplitButtonSelected a.mceOpen {background-position:-44px -44px} +.o2k7Skin .mceSplitButtonDisabled .mceAction {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +.o2k7Skin .mceSplitButtonActive {background-position:0 -44px} + +/* ColorSplitButton */ +.o2k7Skin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray} +.o2k7Skin .mceColorSplitMenu td {padding:2px} +.o2k7Skin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080} +.o2k7Skin .mceColorSplitMenu td.mceMoreColors {padding:1px 3px 1px 1px} +.o2k7Skin .mceColorSplitMenu a.mceMoreColors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF} +.o2k7Skin .mceColorSplitMenu a.mceMoreColors:hover {border:1px solid #0A246A; background-color:#B6BDD2} +.o2k7Skin a.mceMoreColors:hover {border:1px solid #0A246A} +.o2k7Skin .mceColorPreview {margin-left:2px; width:16px; height:4px; overflow:hidden; background:#9a9b9a;overflow:hidden} +.o2k7Skin .mce_forecolor span.mceAction, .o2k7Skin .mce_backcolor span.mceAction {height:15px;overflow:hidden} + +/* Menu */ +.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD} +.o2k7Skin .mceNoIcons span.mceIcon {width:0;} +.o2k7Skin .mceNoIcons a .mceText {padding-left:10px} +.o2k7Skin .mceMenu table {background:#FFF} +.o2k7Skin .mceMenu a, .o2k7Skin .mceMenu span, .o2k7Skin .mceMenu {display:block} +.o2k7Skin .mceMenu td {height:20px} +.o2k7Skin .mceMenu a {position:relative;padding:3px 0 4px 0} +.o2k7Skin .mceMenu .mceText {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block} +.o2k7Skin .mceMenu span.mceText, .o2k7Skin .mceMenu .mcePreview {font-size:11px} +.o2k7Skin .mceMenu pre.mceText {font-family:Monospace} +.o2k7Skin .mceMenu .mceIcon {position:absolute; top:0; left:0; width:22px;} +.o2k7Skin .mceMenu .mceMenuItemEnabled a:hover, .o2k7Skin .mceMenu .mceMenuItemActive {background-color:#dbecf3} +.o2k7Skin td.mceMenuItemSeparator {background:#DDD; height:1px} +.o2k7Skin .mceMenuItemTitle a {border:0; background:#E5EFFD; border-bottom:1px solid #ABC6DD} +.o2k7Skin .mceMenuItemTitle span.mceText {color:#000; font-weight:bold; padding-left:4px} +.o2k7Skin .mceMenuItemDisabled .mceText {color:#888} +.o2k7Skin .mceMenuItemSelected .mceIcon {background:url(../default/img/menu_check.gif)} +.o2k7Skin .mceNoIcons .mceMenuItemSelected a {background:url(../default/img/menu_arrow.gif) no-repeat -6px center} +.o2k7Skin .mceMenu span.mceMenuLine {display:none} +.o2k7Skin .mceMenuItemSub a {background:url(../default/img/menu_arrow.gif) no-repeat top right;} + +/* Progress,Resize */ +.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF} +.o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} + +/* Formats */ +.o2k7Skin .mce_formatPreview a {font-size:10px} +.o2k7Skin .mce_p span.mceText {} +.o2k7Skin .mce_address span.mceText {font-style:italic} +.o2k7Skin .mce_pre span.mceText {font-family:monospace} +.o2k7Skin .mce_h1 span.mceText {font-weight:bolder; font-size: 2em} +.o2k7Skin .mce_h2 span.mceText {font-weight:bolder; font-size: 1.5em} +.o2k7Skin .mce_h3 span.mceText {font-weight:bolder; font-size: 1.17em} +.o2k7Skin .mce_h4 span.mceText {font-weight:bolder; font-size: 1em} +.o2k7Skin .mce_h5 span.mceText {font-weight:bolder; font-size: .83em} +.o2k7Skin .mce_h6 span.mceText {font-weight:bolder; font-size: .75em} + +/* Theme */ +.o2k7Skin span.mce_bold {background-position:0 0} +.o2k7Skin span.mce_italic {background-position:-60px 0} +.o2k7Skin span.mce_underline {background-position:-140px 0} +.o2k7Skin span.mce_strikethrough {background-position:-120px 0} +.o2k7Skin span.mce_undo {background-position:-160px 0} +.o2k7Skin span.mce_redo {background-position:-100px 0} +.o2k7Skin span.mce_cleanup {background-position:-40px 0} +.o2k7Skin span.mce_bullist {background-position:-20px 0} +.o2k7Skin span.mce_numlist {background-position:-80px 0} +.o2k7Skin span.mce_justifyleft {background-position:-460px 0} +.o2k7Skin span.mce_justifyright {background-position:-480px 0} +.o2k7Skin span.mce_justifycenter {background-position:-420px 0} +.o2k7Skin span.mce_justifyfull {background-position:-440px 0} +.o2k7Skin span.mce_anchor {background-position:-200px 0} +.o2k7Skin span.mce_indent {background-position:-400px 0} +.o2k7Skin span.mce_outdent {background-position:-540px 0} +.o2k7Skin span.mce_link {background-position:-500px 0} +.o2k7Skin span.mce_unlink {background-position:-640px 0} +.o2k7Skin span.mce_sub {background-position:-600px 0} +.o2k7Skin span.mce_sup {background-position:-620px 0} +.o2k7Skin span.mce_removeformat {background-position:-580px 0} +.o2k7Skin span.mce_newdocument {background-position:-520px 0} +.o2k7Skin span.mce_image {background-position:-380px 0} +.o2k7Skin span.mce_help {background-position:-340px 0} +.o2k7Skin span.mce_code {background-position:-260px 0} +.o2k7Skin span.mce_hr {background-position:-360px 0} +.o2k7Skin span.mce_visualaid {background-position:-660px 0} +.o2k7Skin span.mce_charmap {background-position:-240px 0} +.o2k7Skin span.mce_paste {background-position:-560px 0} +.o2k7Skin span.mce_copy {background-position:-700px 0} +.o2k7Skin span.mce_cut {background-position:-680px 0} +.o2k7Skin span.mce_blockquote {background-position:-220px 0} +.o2k7Skin .mce_forecolor span.mceAction {background-position:-720px 0} +.o2k7Skin .mce_backcolor span.mceAction {background-position:-760px 0} +.o2k7Skin span.mce_forecolorpicker {background-position:-720px 0} +.o2k7Skin span.mce_backcolorpicker {background-position:-760px 0} + +/* Plugins */ +.o2k7Skin span.mce_advhr {background-position:-0px -20px} +.o2k7Skin span.mce_ltr {background-position:-20px -20px} +.o2k7Skin span.mce_rtl {background-position:-40px -20px} +.o2k7Skin span.mce_emotions {background-position:-60px -20px} +.o2k7Skin span.mce_fullpage {background-position:-80px -20px} +.o2k7Skin span.mce_fullscreen {background-position:-100px -20px} +.o2k7Skin span.mce_iespell {background-position:-120px -20px} +.o2k7Skin span.mce_insertdate {background-position:-140px -20px} +.o2k7Skin span.mce_inserttime {background-position:-160px -20px} +.o2k7Skin span.mce_absolute {background-position:-180px -20px} +.o2k7Skin span.mce_backward {background-position:-200px -20px} +.o2k7Skin span.mce_forward {background-position:-220px -20px} +.o2k7Skin span.mce_insert_layer {background-position:-240px -20px} +.o2k7Skin span.mce_insertlayer {background-position:-260px -20px} +.o2k7Skin span.mce_movebackward {background-position:-280px -20px} +.o2k7Skin span.mce_moveforward {background-position:-300px -20px} +.o2k7Skin span.mce_media {background-position:-320px -20px} +.o2k7Skin span.mce_nonbreaking {background-position:-340px -20px} +.o2k7Skin span.mce_pastetext {background-position:-360px -20px} +.o2k7Skin span.mce_pasteword {background-position:-380px -20px} +.o2k7Skin span.mce_selectall {background-position:-400px -20px} +.o2k7Skin span.mce_preview {background-position:-420px -20px} +.o2k7Skin span.mce_print {background-position:-440px -20px} +.o2k7Skin span.mce_cancel {background-position:-460px -20px} +.o2k7Skin span.mce_save {background-position:-480px -20px} +.o2k7Skin span.mce_replace {background-position:-500px -20px} +.o2k7Skin span.mce_search {background-position:-520px -20px} +.o2k7Skin span.mce_styleprops {background-position:-560px -20px} +.o2k7Skin span.mce_table {background-position:-580px -20px} +.o2k7Skin span.mce_cell_props {background-position:-600px -20px} +.o2k7Skin span.mce_delete_table {background-position:-620px -20px} +.o2k7Skin span.mce_delete_col {background-position:-640px -20px} +.o2k7Skin span.mce_delete_row {background-position:-660px -20px} +.o2k7Skin span.mce_col_after {background-position:-680px -20px} +.o2k7Skin span.mce_col_before {background-position:-700px -20px} +.o2k7Skin span.mce_row_after {background-position:-720px -20px} +.o2k7Skin span.mce_row_before {background-position:-740px -20px} +.o2k7Skin span.mce_merge_cells {background-position:-760px -20px} +.o2k7Skin span.mce_table_props {background-position:-980px -20px} +.o2k7Skin span.mce_row_props {background-position:-780px -20px} +.o2k7Skin span.mce_split_cells {background-position:-800px -20px} +.o2k7Skin span.mce_template {background-position:-820px -20px} +.o2k7Skin span.mce_visualchars {background-position:-840px -20px} +.o2k7Skin span.mce_abbr {background-position:-860px -20px} +.o2k7Skin span.mce_acronym {background-position:-880px -20px} +.o2k7Skin span.mce_attribs {background-position:-900px -20px} +.o2k7Skin span.mce_cite {background-position:-920px -20px} +.o2k7Skin span.mce_del {background-position:-940px -20px} +.o2k7Skin span.mce_ins {background-position:-960px -20px} +.o2k7Skin span.mce_pagebreak {background-position:0 -40px} +.o2k7Skin span.mce_restoredraft {background-position:-20px -40px} +.o2k7Skin span.mce_spellchecker {background-position:-540px -20px} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui_black.css b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui_black.css new file mode 100644 index 00000000..81dbfe41 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui_black.css @@ -0,0 +1,8 @@ +/* Black */ +.o2k7SkinBlack .mceToolbar .mceToolbarStart span, .o2k7SkinBlack .mceToolbar .mceToolbarEnd span, .o2k7SkinBlack .mceButton, .o2k7SkinBlack .mceSplitButton, .o2k7SkinBlack .mceSeparator, .o2k7SkinBlack .mceSplitButton a.mceOpen, .o2k7SkinBlack .mceListBox a.mceOpen {background-image:url(img/button_bg_black.png)} +.o2k7SkinBlack table, .o2k7SkinBlack .mceMenuItemTitle a, .o2k7SkinBlack .mceMenuItemTitle span.mceText, .o2k7SkinBlack .mceStatusbar div, .o2k7SkinBlack .mceStatusbar span, .o2k7SkinBlack .mceStatusbar a {background:#535353; color:#FFF} +.o2k7SkinBlack table.mceListBoxEnabled .mceText, o2k7SkinBlack .mceListBox .mceText {background:#FFF; border:1px solid #CBCFD4; border-bottom-color:#989FA9; border-right:0} +.o2k7SkinBlack table.mceListBoxEnabled:hover .mceText, .o2k7SkinBlack .mceListBoxHover .mceText, .o2k7SkinBlack .mceListBoxSelected .mceText {background:#FFF; border:1px solid #FFBD69; border-right:0} +.o2k7SkinBlack .mceExternalToolbar, .o2k7SkinBlack .mceListBox .mceText, .o2k7SkinBlack div.mceMenu, .o2k7SkinBlack table.mceLayout, .o2k7SkinBlack .mceMenuItemTitle a, .o2k7SkinBlack table.mceLayout tr.mceFirst td, .o2k7SkinBlack table.mceLayout, .o2k7SkinBlack .mceMenuItemTitle a, .o2k7SkinBlack table.mceLayout tr.mceLast td, .o2k7SkinBlack .mceIframeContainer {border-color: #535353;} +.o2k7SkinBlack table.mceSplitButtonEnabled:hover a.mceAction, .o2k7SkinBlack .mceSplitButtonHover a.mceAction, .o2k7SkinBlack .mceSplitButtonSelected {background-image:url(img/button_bg_black.png)} +.o2k7SkinBlack .mceMenu .mceMenuItemEnabled a:hover, .o2k7SkinBlack .mceMenu .mceMenuItemActive {background-color:#FFE7A1} \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui_silver.css b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui_silver.css new file mode 100644 index 00000000..e8ae844f --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/o2k7/ui_silver.css @@ -0,0 +1,5 @@ +/* Silver */ +.o2k7SkinSilver .mceToolbar .mceToolbarStart span, .o2k7SkinSilver .mceButton, .o2k7SkinSilver .mceSplitButton, .o2k7SkinSilver .mceSeparator, .o2k7SkinSilver .mceSplitButton a.mceOpen, .o2k7SkinSilver .mceListBox a.mceOpen {background-image:url(img/button_bg_silver.png)} +.o2k7SkinSilver table, .o2k7SkinSilver .mceMenuItemTitle a {background:#eee} +.o2k7SkinSilver .mceListBox .mceText {background:#FFF} +.o2k7SkinSilver .mceExternalToolbar, .o2k7SkinSilver .mceListBox .mceText, .o2k7SkinSilver div.mceMenu, .o2k7SkinSilver table.mceLayout, .o2k7SkinSilver .mceMenuItemTitle a, .o2k7SkinSilver table.mceLayout tr.mceFirst td, .o2k7SkinSilver table.mceLayout, .o2k7SkinSilver .mceMenuItemTitle a, .o2k7SkinSilver table.mceLayout tr.mceLast td, .o2k7SkinSilver .mceIframeContainer {border-color: #bbb} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css new file mode 100644 index 00000000..40dfd3e2 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css @@ -0,0 +1,85 @@ +/* default styles */ +body {background:#FFF;} +body.mceForceColors {background:#FFF; color:#000;} +h1 {font-size: 2em} +h2 {font-size: 1.5em} +h3 {font-size: 1.17em} +h4 {font-size: 1em} +h5 {font-size: .83em} +h6 {font-size: .75em} +.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} +a.mceItemAnchor {width:12px; line-height:6px; overflow:hidden; padding-left:12px; background:url(../default/img/items.gif) no-repeat bottom left;} +img.mceItemAnchor {width:12px; height:12px; background:url(../default/img/items.gif) no-repeat;} +img {border:0;} +table {cursor:default} +table td, table th {cursor:text} +ins {border-bottom:1px solid green; text-decoration: none; color:green} +del {color:red; text-decoration:line-through} +cite {border-bottom:1px dashed blue} +acronym {border-bottom:1px dotted #CCC; cursor:help} +abbr, html\:abbr {border-bottom:1px dashed #CCC; cursor:help} + +/* WordPress styles */ +html { + background-color: #fff; +} + +.aligncenter, +dl.aligncenter { + display: block; + margin-left: auto; + margin-right: auto; +} + +.alignleft { + float: left; +} + +.alignright { + float: right; +} + +.wp-caption { + border: 1px solid #ddd; + text-align: center; + background-color: #f3f3f3; + padding-top: 4px; + margin: 10px; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +.wp-caption img { + margin: 0; + padding: 0; + border: 0 none; +} + +.wp-caption-dd { + font-size: 11px; + line-height: 17px; + padding: 0 4px 5px; + margin: 0; +} + +body.mceContentBody { + font: 13px/19px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + padding: 0.6em; + margin: 0; +} + +pre { + font: 12px/18px Consolas, Monaco, "Courier New", Courier, monospace; +} + +td { + color: #000; + font-size: 11px; + margin: 8px; +} + +.mceIEcenter { + text-align: center; +} diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/dialog.css b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/dialog.css new file mode 100644 index 00000000..7fe6b8dc --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/dialog.css @@ -0,0 +1,117 @@ +/* Generic */ +body { +font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; +background:#f1f1f1; +padding:0; +margin:8px 8px 0 8px; +} + +html {background:#f1f1f1;} +td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +textarea {resize:none;outline:none;} +a:link, a:visited {color:black;} +a:hover {color:#2B6FB6;} +.nowrap {white-space: nowrap} + +/* Forms */ +fieldset {margin:0; padding:4px; border:1px solid #dfdfdf; font-family:Verdana, Arial; font-size:10px;} +legend {color:#2B6FB6; font-weight:bold;} +label.msg {display:none;} +label.invalid {color:#EE0000; display:inline;} +input.invalid {border:1px solid #EE0000;} +input {background:#FFF; border:1px solid #dfdfdf;} +input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +input, select, textarea {border:1px solid #dfdfdf;} +input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} +input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} +.input_noborder {border:0;} + +/* Buttons */ +#insert, #cancel, #apply, .mceActionPanel .button, input.mceButton, .updateButton { + border: 1px solid #bbb; + margin:0; + padding:0 0 1px; + font-weight:bold; + font-size: 11px; + width:94px; + height:24px; + background:url(img/fade-butt.png) 0 0; + color:#000; + cursor:pointer; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +#insert:hover, #cancel:hover, input.mceButton:hover, .updateButton:hover, +#insert:focus, #cancel:focus, input.mceButton:focus, .updateButton:focus { + border: 1px solid #555; +} + +/* Browse */ +a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} +.mceOldBoxModel a.browse span {width:22px; height:20px;} +a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} +a.browse span.disabled {border:1px solid white; -moz-opacity:0.3; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);} +a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} +a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} +.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} +a.pickcolor:hover span {background-color:#B2BBD0;} +a.pickcolor, a.browse {text-decoration:none} + +/* Charmap */ +table.charmap {border:1px solid #AAA; text-align:center} +td.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;} +#charmap a {display:block; color:#000; text-decoration:none; border:0} +#charmap a:hover {background:#CCC;color:#2B6FB6} +#charmap #codeN {font-size:10px; font-family:Arial,Helvetica,sans-serif; text-align:center} +#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center} +#charmap #charmapView {background-color:#fff;} + +/* Source */ +.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} +.mceActionPanel {margin-top:5px;} + +/* Tabs classes */ +.tabs {width:100%; height:18px; line-height:normal; background:url(img/tabs.gif) repeat-x 0 -72px;} +.tabs ul {margin:0; padding:0; list-style:none;} +.tabs li {float:left; background:url(img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:17px; height:18px; display:block;} +.tabs li.current {background:url(img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} +.tabs span {float:left; display:block; background:url(img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} +.tabs .current span {background:url(img/tabs.gif) no-repeat right -54px;} +.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} +.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} + +/* Panels */ +.panel_wrapper div.panel {display:none;} +.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} +.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} + +/* Columns */ +.column {float:left;} +.properties {width:100%;} +.properties .column1 {} +.properties .column2 {text-align:left;} + +/* Titles */ +h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} +h3 {font-size:14px;} +.title {font-size:12px; font-weight:bold; color:#2B6FB6;} + +/* Dialog specific */ +#link .panel_wrapper, #link div.current {height:125px;} +#image .panel_wrapper, #image div.current {height:200px;} +#plugintable thead {font-weight:bold; background:#DDD;} +#plugintable, #about #plugintable td {border:1px solid #919B9C;} +#plugintable {width:96%; margin-top:10px;} +#pluginscontainer {height:290px; overflow:auto;} +#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} +#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} +#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} +#colorpicker #light div {overflow:hidden;} +#colorpicker #previewblock {float:right; padding-left:10px; height:20px;} +#colorpicker .panel_wrapper div.current {height:175px;} +#colorpicker #namedcolors {width:150px;} +#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} +#colorpicker #colornamecontainer {margin-top:5px;} +#colorpicker #picker_panel fieldset {margin:auto;width:325px;} \ No newline at end of file diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/butt2.png b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/butt2.png new file mode 100644 index 00000000..adb83cdb Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/butt2.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/button_bg.png b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/button_bg.png new file mode 100644 index 00000000..12cfb419 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/button_bg.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/down_arrow.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/down_arrow.gif new file mode 100644 index 00000000..687b241e Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/down_arrow.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/fade-butt.png b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/fade-butt.png new file mode 100644 index 00000000..42f08b79 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/fade-butt.png differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/separator.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/separator.gif new file mode 100644 index 00000000..4f39b809 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/separator.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/tabs.gif b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/tabs.gif new file mode 100644 index 00000000..ce4be635 Binary files /dev/null and b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/tabs.gif differ diff --git a/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/ui.css b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/ui.css new file mode 100644 index 00000000..f4b1fe44 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/ui.css @@ -0,0 +1,382 @@ +/* Reset */ +.wp_themeSkin table, .wp_themeSkin tbody, .wp_themeSkin a, .wp_themeSkin img, .wp_themeSkin tr, .wp_themeSkin div, .wp_themeSkin td, .wp_themeSkin iframe, .wp_themeSkin span, .wp_themeSkin *, .wp_themeSkin .mceText { +border:0; margin:0; padding:0; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; vertical-align:baseline; width:auto; border-collapse:separate; +} +.wp_themeSkin a:hover, .wp_themeSkin a:link, .wp_themeSkin a:visited, .wp_themeSkin a:active {text-decoration:none; font-weight:normal; cursor:default;} +.wp_themeSkin table td {vertical-align:middle} + +/* Containers */ +.wp_themeSkin table {} +.wp_themeSkin iframe {display:block;} +.wp_themeSkin .mceToolbar {padding: 2px;} + +/* External */ +.wp_themeSkin .mceExternalToolbar {position:absolute; border-bottom:0; display:none} +.wp_themeSkin .mceExternalToolbar td.mceToolbar {padding-right:13px;} +.wp_themeSkin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0} + +/* Layout */ +.wp_themeSkin table.mceToolbar, .wp_themeSkin tr.mceFirst .mceToolbar tr td, .wp_themeSkin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0} +.wp_themeSkin table.mceLayout {border:0;} +.wp_themeSkin .mceIframeContainer {} +.wp_themeSkin .mceStatusbar { + display: block; + font-family: 'MS Sans Serif',sans-serif,Verdana,Arial; + font-size: 9pt; + line-height: 16px; + overflow: visible; + height: 20px; + border-top-width: 1px; + border-top-style: solid; +} +.wp_themeSkin .mceStatusbar div {float:left; padding:2px;} +.wp_themeSkin .mceStatusbar a.mceResize { + display: block; + float: right; + background: url(../../img/icons.gif) -800px 0; + width: 20px; + height: 20px; + cursor: se-resize +} +.wp_themeSkin .mceStatusbar a:hover {text-decoration:underline} +.wp_themeSkin table.mceToolbar {margin: 0 2px 2px;} +.wp_themeSkin #content_toolbar1 {margin-top: 2px;} +.wp_themeSkin .mceToolbar .mceToolbarEndListBox span {display:none} +.wp_themeSkin span.mceIcon, .wp_themeSkin img.mceIcon {display:block; width:20px; height:20px} +.wp_themeSkin .mceIcon {background:url(../../img/icons.gif) no-repeat 20px 20px} + +/* Button */ +.wp_themeSkin .mceButton { + display:block; + width: 20px; + height: 20px; + cursor: default; + padding: 1px 2px; + margin: 1px; + background-image: url(img/butt2.png); + background-position: left top; + background-repeat: repeat-x; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + -khtml-border-radius: 3px; + border-radius: 3px; +} +.wp_themeSkin a.mceButton span, .wp_themeSkin a.mceButton img {} +.wp_themeSkin .mceOldBoxModel a.mceButton span, .wp_themeSkin .mceOldBoxModel a.mceButton img {margin:0 0 0 1px} +.wp_themeSkin a.mceButtonEnabled:hover { + background-position:0 -10px; +} +.wp_themeSkin a.mceButtonActive, .wp_themeSkin a.mceButtonSelected { + background-image: inherit; +} +.wp_themeSkin .mceButtonDisabled .mceIcon {opacity:0.3; filter:alpha(opacity=30);} +.wp_themeSkin .mceButtonDisabled {} + +/* Separator */ +.wp_themeSkin .mceSeparator { + height: 24px; + width: 1px; + display: block; + background: transparent; + overflow: hidden; + margin: 0 2px; +} + +/* ListBox */ +.wp_themeSkin .mceListBox, .wp_themeSkin .mceListBox a {display:block} +.wp_themeSkin .mceListBox .mceText { + padding: 1px 2px 1px 5px; + text-align:left; + text-decoration: none !important; + width:70px; + background-image: url(img/butt2.png); + background-position: left top; + background-repeat: repeat-x; + font-family: Tahoma,Verdana,Arial,Helvetica; + font-size: 11px; + height: 20px; + line-height: 20px; + overflow: hidden; +} +.wp_themeSkin .mceListBox { + margin: 1px; + direction: ltr; +} +.wp_themeSkin .mceListBox .mceOpen { + width: 14px; + height: 20px; + border-collapse: separate; + background-image: url(img/butt2.png); + background-position: left top; + background-repeat: repeat-x; + padding: 1px; + border-left: 0 none !important; +} +.wp_themeSkin .mceListBox .mceOpen span { + display: block; + width:14px; + height:20px; + background-image: url(img/down_arrow.gif); + background-position: 2px 1px; + background-repeat: no-repeat; +} +.wp_themeSkin table.mceListBoxEnabled:hover .mceText, +.wp_themeSkin .mceListBoxHover .mceText, +.wp_themeSkin .mceListBoxSelected .mceText, +.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen, +.wp_themeSkin .mceListBoxHover .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceOpen { + background-image: none; +} +.wp_themeSkin .mceListBoxDisabled .mceText {color:gray} +.wp_themeSkin .mceListBoxMenu {overflow:auto; overflow-x:hidden} +.wp_themeSkin .mceOldBoxModel .mceListBox .mceText {height:22px} +.wp_themeSkin select.mceListBox {font-family:Tahoma,Verdana,Arial,Helvetica; font-size:12px;} + +/* SplitButton */ +.wp_themeSkin .mceSplitButton a, .wp_themeSkin .mceSplitButton span {display:block; height:20px} +.wp_themeSkin .mceSplitButton { + display:block; + margin: 1px; + direction: ltr; +} +.wp_themeSkin table.mceSplitButton td { + padding: 2px; + background-image: url(img/butt2.png); + background-position: left top; + background-repeat: repeat-x; +} +.wp_themeSkin .mceSplitButton a.mceAction { + height:20px; + width:20px; + padding: 1px 2px; +} +.wp_themeSkin .mceSplitButton span.mceAction { + background-image: url(../../img/icons.gif); + background-repeat: no-repeat; + background-color: transparent; + width:20px; +} +.wp_themeSkin .mceSplitButton a.mceOpen { + width:10px; + height:20px; + background-image: url(img/down_arrow.gif); + background-position: 1px 2px; + background-repeat: no-repeat; + padding: 1px; + border-left: 0 none !important; +} +.wp_themeSkin .mceSplitButton span.mceOpen {display:none} +.wp_themeSkin .mceSplitButtonDisabled .mceAction { + opacity:0.3; filter:alpha(opacity=30); +} +.wp_themeSkin .mceListBox a.mceText, .wp_themeSkin .mceSplitButton a.mceAction { + -moz-border-radius-bottomleft: 3px; + -webkit-border-bottom-left-radius: 3px; + -khtml-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -moz-border-radius-topleft: 3px; + -webkit-border-top-left-radius: 3px; + -khtml-border-top-left-radius: 3px; + border-top-left-radius: 3px; +} +.wp_themeSkin .mceSplitButton a.mceOpen, .wp_themeSkin .mceListBox a.mceOpen { + -moz-border-radius-bottomright: 3px; + -webkit-border-bottom-right-radius: 3px; + -khtml-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -webkit-border-top-right-radius: 3px; + -khtml-border-top-right-radius: 3px; + border-top-right-radius: 3px; +} + +/* ColorSplitButton */ +.wp_themeSkin div.mceColorSplitMenu table {} +.wp_themeSkin .mceColorSplitMenu td {padding:2px} +.wp_themeSkin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden;} +.wp_themeSkin .mceColorSplitMenu td.mceMoreColors {padding:1px 3px 1px 1px} +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px;} +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover {} +.wp_themeSkin a.mceMoreColors:hover {} +.wp_themeSkin .mceColorPreview {margin: -4px 0 0 2px; width:16px; height:4px; overflow:hidden} + +/* Menu */ +.wp_themeSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000;} +.wp_themeSkin .mceNoIcons span.mceIcon {width:0;} +.wp_themeSkin .mceNoIcons a .mceText {padding-left:10px} +.wp_themeSkin .mceMenu table {} +.wp_themeSkin .mceMenu a, .wp_themeSkin .mceMenu span, .wp_themeSkin .mceMenu {display:block} +.wp_themeSkin .mceMenu td {height:20px;overflow:hidden;} +.wp_themeSkin .mceMenu a { + position:relative; + padding:3px 0 4px 0; + text-decoration: none !important; +} +.wp_themeSkin .mceMenu .mceText { + position:relative; + display:block; + font-family:Tahoma,Verdana,Arial,Helvetica; + cursor:default; + margin:0; + padding:0 25px; +} +.wp_themeSkin .mceMenu span.mceText, .wp_themeSkin .mceMenu .mcePreview {font-size:11px} +.wp_themeSkin .mceMenu pre.mceText {font-family:Monospace} +.wp_themeSkin .mceMenu .mceIcon {position:absolute; top:0; left:0; width:22px;} +.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover, +.wp_themeSkin .mceMenu .mceMenuItemActive {} +.wp_themeSkin td.mceMenuItemSeparator {height:1px} +.wp_themeSkin .mceMenuItemTitle a { + border-top: 0; + border-right: 0; + border-left: 0; + border-bottom-style: solid; + border-bottom-width: 1px; + text-decoration: none !important; +} +.wp_themeSkin .mceMenuItemTitle span.mceText {font-weight:bold; padding-left:4px} +.wp_themeSkin .mceMenuItemDisabled .mceText {} +.wp_themeSkin .mceMenuItemSelected .mceIcon {background:url(../default/img/menu_check.gif)} +.wp_themeSkin .mceNoIcons .mceMenuItemSelected a {background:url(../default/img/menu_arrow.gif) no-repeat -6px center} +.wp_themeSkin .mceMenu span.mceMenuLine {display:none} +.wp_themeSkin .mceMenuItemSub a {background:url(../default/img/menu_arrow.gif) no-repeat top right;} + +/* Progress,Resize */ +.wp_themeSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; filter:alpha(opacity=50); background:#FFF} +.wp_themeSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} +.wp_themeSkin .mcePlaceHolder {border:1px dotted gray} + +/* Formats */ +.wp_themeSkin .mce_formatPreview a {font-size:10px} +.wp_themeSkin .mce_p span.mceText {} +.wp_themeSkin .mce_address span.mceText {font-style:italic} +.wp_themeSkin .mce_pre span.mceText {font-family:monospace} +.wp_themeSkin .mce_h1 span.mceText {font-weight:bolder; font-size: 2em} +.wp_themeSkin .mce_h2 span.mceText {font-weight:bolder; font-size: 1.5em} +.wp_themeSkin .mce_h3 span.mceText {font-weight:bolder; font-size: 1.17em} +.wp_themeSkin .mce_h4 span.mceText {font-weight:bolder; font-size: 1em} +.wp_themeSkin .mce_h5 span.mceText {font-weight:bolder; font-size: .83em} +.wp_themeSkin .mce_h6 span.mceText {font-weight:bolder; font-size: .75em} + +/* Theme */ +.wp_themeSkin span.mce_bold {background-position:0 0} +.wp_themeSkin span.mce_italic {background-position:-60px 0} +.wp_themeSkin span.mce_underline {background-position:-140px 0} +.wp_themeSkin span.mce_strikethrough {background-position:-120px 0} +.wp_themeSkin span.mce_undo {background-position:-160px 0} +.wp_themeSkin span.mce_redo {background-position:-100px 0} +.wp_themeSkin span.mce_cleanup {background-position:-40px 0} +.wp_themeSkin span.mce_bullist {background-position:-20px 0} +.wp_themeSkin span.mce_numlist {background-position:-80px 0} +.wp_themeSkin span.mce_justifyleft {background-position:-460px 0} +.wp_themeSkin span.mce_justifyright {background-position:-480px 0} +.wp_themeSkin span.mce_justifycenter {background-position:-420px 0} +.wp_themeSkin span.mce_justifyfull {background-position:-440px 0} +.wp_themeSkin span.mce_anchor {background-position:-200px 0} +.wp_themeSkin span.mce_indent {background-position:-400px 0} +.wp_themeSkin span.mce_outdent {background-position:-540px 0} +.wp_themeSkin span.mce_link {background-position:-500px 0} +.wp_themeSkin span.mce_unlink {background-position:-640px 0} +.wp_themeSkin span.mce_sub {background-position:-600px 0} +.wp_themeSkin span.mce_sup {background-position:-620px 0} +.wp_themeSkin span.mce_removeformat {background-position:-580px 0} +.wp_themeSkin span.mce_newdocument {background-position:-520px 0} +.wp_themeSkin span.mce_image {background-position:-380px 0} +.wp_themeSkin span.mce_help {background-position:-340px 0} +.wp_themeSkin span.mce_code {background-position:-260px 0} +.wp_themeSkin span.mce_hr {background-position:-360px 0} +.wp_themeSkin span.mce_visualaid {background-position:-660px 0} +.wp_themeSkin span.mce_charmap {background-position:-240px 0} +.wp_themeSkin span.mce_paste {background-position:-560px 0} +.wp_themeSkin span.mce_copy {background-position:-700px 0} +.wp_themeSkin span.mce_cut {background-position:-680px 0} +.wp_themeSkin span.mce_blockquote {background-position:-220px 0} +.wp_themeSkin .mce_forecolor span.mceAction {background-position:-720px 0} +.wp_themeSkin .mce_backcolor span.mceAction {background-position:-760px 0} +.wp_themeSkin .mce_forecolorpicker {background-position:-720px 0} +.wp_themeSkin .mce_backcolorpicker {background-position:-760px 0} + +/* Plugins */ +.wp_themeSkin span.mce_advhr {background-position:-0px -20px} +.wp_themeSkin span.mce_ltr {background-position:-20px -20px} +.wp_themeSkin span.mce_rtl {background-position:-40px -20px} +.wp_themeSkin span.mce_emotions {background-position:-60px -20px} +.wp_themeSkin span.mce_fullpage {background-position:-80px -20px} +.wp_themeSkin span.mce_fullscreen {background-position:-100px -20px} +.wp_themeSkin span.mce_iespell {background-position:-120px -20px} +.wp_themeSkin span.mce_insertdate {background-position:-140px -20px} +.wp_themeSkin span.mce_inserttime {background-position:-160px -20px} +.wp_themeSkin span.mce_absolute {background-position:-180px -20px} +.wp_themeSkin span.mce_backward {background-position:-200px -20px} +.wp_themeSkin span.mce_forward {background-position:-220px -20px} +.wp_themeSkin span.mce_insert_layer {background-position:-240px -20px} +.wp_themeSkin span.mce_insertlayer {background-position:-260px -20px} +.wp_themeSkin span.mce_movebackward {background-position:-280px -20px} +.wp_themeSkin span.mce_moveforward {background-position:-300px -20px} +.wp_themeSkin span.mce_media {background-position:-320px -20px} +.wp_themeSkin span.mce_nonbreaking {background-position:-340px -20px} +.wp_themeSkin span.mce_pastetext {background-position:-360px -20px} +.wp_themeSkin span.mce_pasteword {background-position:-380px -20px} +.wp_themeSkin span.mce_selectall {background-position:-400px -20px} +.wp_themeSkin span.mce_preview {background-position:-420px -20px} +.wp_themeSkin span.mce_print {background-position:-440px -20px} +.wp_themeSkin span.mce_cancel {background-position:-460px -20px} +.wp_themeSkin span.mce_save {background-position:-480px -20px} +.wp_themeSkin span.mce_replace {background-position:-500px -20px} +.wp_themeSkin span.mce_search {background-position:-520px -20px} +.wp_themeSkin span.mce_styleprops {background-position:-560px -20px} +.wp_themeSkin span.mce_table {background-position:-580px -20px} +.wp_themeSkin span.mce_cell_props {background-position:-600px -20px} +.wp_themeSkin span.mce_delete_table {background-position:-620px -20px} +.wp_themeSkin span.mce_delete_col {background-position:-640px -20px} +.wp_themeSkin span.mce_delete_row {background-position:-660px -20px} +.wp_themeSkin span.mce_col_after {background-position:-680px -20px} +.wp_themeSkin span.mce_col_before {background-position:-700px -20px} +.wp_themeSkin span.mce_row_after {background-position:-720px -20px} +.wp_themeSkin span.mce_row_before {background-position:-740px -20px} +.wp_themeSkin span.mce_merge_cells {background-position:-760px -20px} +.wp_themeSkin span.mce_table_props {background-position:-980px -20px} +.wp_themeSkin span.mce_row_props {background-position:-780px -20px} +.wp_themeSkin span.mce_split_cells {background-position:-800px -20px} +.wp_themeSkin span.mce_template {background-position:-820px -20px} +.wp_themeSkin span.mce_visualchars {background-position:-840px -20px} +.wp_themeSkin span.mce_abbr {background-position:-860px -20px} +.wp_themeSkin span.mce_acronym {background-position:-880px -20px} +.wp_themeSkin span.mce_attribs {background-position:-900px -20px} +.wp_themeSkin span.mce_cite {background-position:-920px -20px} +.wp_themeSkin span.mce_del {background-position:-940px -20px} +.wp_themeSkin span.mce_ins {background-position:-960px -20px} +.wp_themeSkin span.mce_pagebreak {background-position:0 -40px} +.wp_themeSkin span.mce_spellchecker {background-position:-540px -20px} + +/* border */ +.wp_themeSkin .mceExternalToolbar, +.wp_themeSkin .mceButton, +.wp_themeSkin a.mceButtonEnabled:hover, +.wp_themeSkin a.mceButtonActive, +.wp_themeSkin a.mceButtonSelected, +.wp_themeSkin .mceListBox .mceText, +.wp_themeSkin .mceListBox .mceOpen, +.wp_themeSkin table.mceListBoxEnabled:hover .mceText, +.wp_themeSkin .mceListBoxHover .mceText, +.wp_themeSkin .mceListBoxSelected .mceText, +.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen, +.wp_themeSkin .mceListBoxHover .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceOpen, +.wp_themeSkin select.mceListBox, +.wp_themeSkin .mceSplitButton a.mceAction, +.wp_themeSkin .mceSplitButton a.mceOpen, +.wp_themeSkin .mceSplitButton a.mceOpen:hover, +.wp_themeSkin .mceSplitButtonSelected a.mceOpen, +.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction, +.wp_themeSkin .mceSplitButton a.mceAction:hover, +.wp_themeSkin div.mceColorSplitMenu table, +.wp_themeSkin .mceColorSplitMenu a, +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors, +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover, +.wp_themeSkin a.mceMoreColors:hover, +.wp_themeSkin .mceMenu { + border-style: solid; + border-width: 1px; +} diff --git a/src/wp-includes/js/tinymce/themes/advanced/source_editor.htm b/src/wp-includes/js/tinymce/themes/advanced/source_editor.htm new file mode 100644 index 00000000..b0db4ba6 --- /dev/null +++ b/src/wp-includes/js/tinymce/themes/advanced/source_editor.htm @@ -0,0 +1,30 @@ + + + {#advanced_dlg.code_title} + + + + +
    +
    {#advanced_dlg.code_title}
    + +
    + +
    + +
    + + + +
    +
    + +
    + +
    + +
    +
    +
    + + diff --git a/src/wp-includes/js/tinymce/tiny_mce.js b/src/wp-includes/js/tinymce/tiny_mce.js new file mode 100644 index 00000000..22c4401f --- /dev/null +++ b/src/wp-includes/js/tinymce/tiny_mce.js @@ -0,0 +1 @@ +(function(d){var a=/^\s*|\s*$/g,e,c="B".replace(/A(.)|B/,"$1")==="$1";var b={majorVersion:"3",minorVersion:"3.9.3",releaseDate:"2010-12-20",_init:function(){var s=this,q=document,o=navigator,g=o.userAgent,m,f,l,k,j,r;s.isOpera=d.opera&&opera.buildNumber;s.isWebKit=/WebKit/.test(g);s.isIE=!s.isWebKit&&!s.isOpera&&(/MSIE/gi).test(g)&&(/Explorer/gi).test(o.appName);s.isIE6=s.isIE&&/MSIE [56]/.test(g);s.isGecko=!s.isWebKit&&/Gecko/.test(g);s.isMac=g.indexOf("Mac")!=-1;s.isAir=/adobeair/i.test(g);s.isIDevice=/(iPad|iPhone)/.test(g);if(d.tinyMCEPreInit){s.suffix=tinyMCEPreInit.suffix;s.baseURL=tinyMCEPreInit.base;s.query=tinyMCEPreInit.query;return}s.suffix="";f=q.getElementsByTagName("base");for(m=0;m=c.length){for(e=0,b=g.length;e=c.length||g[e]!=c[e]){f=e+1;break}}}if(g.length=g.length||g[e]!=c[e]){f=e+1;break}}}if(f==1){return h}for(e=0,b=g.length-(f-1);e=0;c--){if(f[c].length==0||f[c]=="."){continue}if(f[c]==".."){b++;continue}if(b>0){b--;continue}h.push(f[c])}c=e.length-b;if(c<=0){g=h.reverse().join("/")}else{g=e.slice(0,c).join("/")+"/"+h.reverse().join("/")}if(g.indexOf("/")!==0){g="/"+g}if(d&&g.lastIndexOf("/")!==g.length-1){g+=d}return g},getURI:function(d){var c,b=this;if(!b.source||d){c="";if(!d){if(b.protocol){c+=b.protocol+"://"}if(b.userInfo){c+=b.userInfo+"@"}if(b.host){c+=b.host}if(b.port){c+=":"+b.port}}if(b.path){c+=b.path}if(b.query){c+="?"+b.query}if(b.anchor){c+="#"+b.anchor}b.source=c}return b.source}})})();(function(){var a=tinymce.each;tinymce.create("static tinymce.util.Cookie",{getHash:function(d){var b=this.get(d),c;if(b){a(b.split("&"),function(e){e=e.split("=");c=c||{};c[unescape(e[0])]=unescape(e[1])})}return c},setHash:function(j,b,g,f,i,c){var h="";a(b,function(e,d){h+=(!h?"":"&")+escape(d)+"="+escape(e)});this.set(j,h,g,f,i,c)},get:function(i){var h=document.cookie,g,f=i+"=",d;if(!h){return}d=h.indexOf("; "+f);if(d==-1){d=h.indexOf(f);if(d!=0){return null}}else{d+=2}g=h.indexOf(";",d);if(g==-1){g=h.length}return unescape(h.substring(d+f.length,g))},set:function(i,b,g,f,h,c){document.cookie=i+"="+escape(b)+((g)?"; expires="+g.toGMTString():"")+((f)?"; path="+escape(f):"")+((h)?"; domain="+h:"")+((c)?"; secure":"")},remove:function(e,b){var c=new Date();c.setTime(c.getTime()-1000);this.set(e,"",c,b,c)}})})();tinymce.create("static tinymce.util.JSON",{serialize:function(e){var c,a,d=tinymce.util.JSON.serialize,b;if(e==null){return"null"}b=typeof e;if(b=="string"){a="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+e.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(g,f){c=a.indexOf(f);if(c+1){return"\\"+a.charAt(c+1)}g=f.charCodeAt().toString(16);return"\\u"+"0000".substring(g.length)+g})+'"'}if(b=="object"){if(e.hasOwnProperty&&e instanceof Array){for(c=0,a="[";c0?",":"")+d(e[c])}return a+"]"}a="{";for(c in e){a+=typeof e[c]!="function"?(a.length>1?',"':'"')+c+'":'+d(e[c]):""}return a+"}"}return""+e},parse:function(s){try{return eval("("+s+")")}catch(ex){}}});tinymce.create("static tinymce.util.XHR",{send:function(g){var a,e,b=window,h=0;g.scope=g.scope||this;g.success_scope=g.success_scope||g.scope;g.error_scope=g.error_scope||g.scope;g.async=g.async===false?false:true;g.data=g.data||"";function d(i){a=0;try{a=new ActiveXObject(i)}catch(c){}return a}a=b.XMLHttpRequest?new XMLHttpRequest():d("Microsoft.XMLHTTP")||d("Msxml2.XMLHTTP");if(a){if(a.overrideMimeType){a.overrideMimeType(g.content_type)}a.open(g.type||(g.data?"POST":"GET"),g.url,g.async);if(g.content_type){a.setRequestHeader("Content-Type",g.content_type)}a.setRequestHeader("X-Requested-With","XMLHttpRequest");a.send(g.data);function f(){if(!g.async||a.readyState==4||h++>10000){if(g.success&&h<10000&&a.status==200){g.success.call(g.success_scope,""+a.responseText,a,g)}else{if(g.error){g.error.call(g.error_scope,h>10000?"TIMED_OUT":"GENERAL",a,g)}}a=null}else{b.setTimeout(f,10)}}if(!g.async){return f()}e=b.setTimeout(f,10)}}});(function(){var c=tinymce.extend,b=tinymce.util.JSON,a=tinymce.util.XHR;tinymce.create("tinymce.util.JSONRequest",{JSONRequest:function(d){this.settings=c({},d);this.count=0},send:function(f){var e=f.error,d=f.success;f=c(this.settings,f);f.success=function(h,g){h=b.parse(h);if(typeof(h)=="undefined"){h={error:"JSON Parse error."}}if(h.error){e.call(f.error_scope||f.scope,h.error,g)}else{d.call(f.success_scope||f.scope,h.result)}};f.error=function(h,g){e.call(f.error_scope||f.scope,h,g)};f.data=b.serialize({id:f.id||"c"+(this.count++),method:f.method,params:f.params});f.content_type="application/json";a.send(f)},"static":{sendRPC:function(d){return new tinymce.util.JSONRequest().send(d)}}})}());(function(m){var k=m.each,j=m.is,i=m.isWebKit,d=m.isIE,a=/^(H[1-6R]|P|DIV|ADDRESS|PRE|FORM|T(ABLE|BODY|HEAD|FOOT|H|R|D)|LI|OL|UL|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|MENU|ISINDEX|SAMP)$/,e=g("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),f=g("src,href,style,coords,shape"),c={"&":"&",'"':""","<":"<",">":">"},n=/[<>&\"]/g,b=/^([a-z0-9],?)+$/i,h=/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)(\s*\/?)>/g,l=/(\w+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;function g(q){var p={},o;q=q.split(",");for(o=q.length;o>=0;o--){p[q[o]]=1}return p}m.create("tinymce.dom.DOMUtils",{doc:null,root:null,files:null,pixelStyles:/^(top|left|bottom|right|width|height|borderWidth)$/,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},DOMUtils:function(u,q){var p=this,o;p.doc=u;p.win=window;p.files={};p.cssFlicker=false;p.counter=0;p.stdMode=u.documentMode>=8;p.boxModel=!m.isIE||u.compatMode=="CSS1Compat"||p.stdMode;p.settings=q=m.extend({keep_values:false,hex_colors:1,process_html:1},q);if(m.isIE6){try{u.execCommand("BackgroundImageCache",false,true)}catch(r){p.cssFlicker=true}}if(q.valid_styles){p._styles={};k(q.valid_styles,function(t,s){p._styles[s]=m.explode(t)})}m.addUnload(p.destroy,p)},getRoot:function(){var o=this,p=o.settings;return(p&&o.get(p.root_element))||o.doc.body},getViewPort:function(p){var q,o;p=!p?this.win:p;q=p.document;o=this.boxModel?q.documentElement:q.body;return{x:p.pageXOffset||o.scrollLeft,y:p.pageYOffset||o.scrollTop,w:p.innerWidth||o.clientWidth,h:p.innerHeight||o.clientHeight}},getRect:function(s){var r,o=this,q;s=o.get(s);r=o.getPos(s);q=o.getSize(s);return{x:r.x,y:r.y,w:q.w,h:q.h}},getSize:function(r){var p=this,o,q;r=p.get(r);o=p.getStyle(r,"width");q=p.getStyle(r,"height");if(o.indexOf("px")===-1){o=0}if(q.indexOf("px")===-1){q=0}return{w:parseInt(o)||r.offsetWidth||r.clientWidth,h:parseInt(q)||r.offsetHeight||r.clientHeight}},getParent:function(q,p,o){return this.getParents(q,p,o,false)},getParents:function(z,v,s,y){var q=this,p,u=q.settings,x=[];z=q.get(z);y=y===undefined;if(u.strict_root){s=s||q.getRoot()}if(j(v,"string")){p=v;if(v==="*"){v=function(o){return o.nodeType==1}}else{v=function(o){return q.is(o,p)}}}while(z){if(z==s||!z.nodeType||z.nodeType===9){break}if(!v||v(z)){if(y){x.push(z)}else{return z}}z=z.parentNode}return y?x:null},get:function(o){var p;if(o&&this.doc&&typeof(o)=="string"){p=o;o=this.doc.getElementById(o);if(o&&o.id!==p){return this.doc.getElementsByName(p)[1]}}return o},getNext:function(p,o){return this._findSib(p,o,"nextSibling")},getPrev:function(p,o){return this._findSib(p,o,"previousSibling")},select:function(q,p){var o=this;return m.dom.Sizzle(q,o.get(p)||o.get(o.settings.root_element)||o.doc,[])},is:function(q,o){var p;if(q.length===undefined){if(o==="*"){return q.nodeType==1}if(b.test(o)){o=o.toLowerCase().split(/,/);q=q.nodeName.toLowerCase();for(p=o.length-1;p>=0;p--){if(o[p]==q){return true}}return false}}return m.dom.Sizzle.matches(o,q.nodeType?[q]:q).length>0},add:function(s,v,o,r,u){var q=this;return this.run(s,function(y){var x,t;x=j(v,"string")?q.doc.createElement(v):v;q.setAttribs(x,o);if(r){if(r.nodeType){x.appendChild(r)}else{q.setHTML(x,r)}}return !u?y.appendChild(x):x})},create:function(q,o,p){return this.add(this.doc.createElement(q),q,o,p,1)},createHTML:function(v,p,s){var u="",r=this,q;u+="<"+v;for(q in p){if(p.hasOwnProperty(q)){u+=" "+q+'="'+r.encode(p[q])+'"'}}if(typeof(s)!="undefined"){return u+">"+s+""}return u+" />"},remove:function(o,p){return this.run(o,function(r){var q,s;q=r.parentNode;if(!q){return null}if(p){while(s=r.firstChild){if(!m.isIE||s.nodeType!==3||s.nodeValue){q.insertBefore(s,r)}else{r.removeChild(s)}}}return q.removeChild(r)})},setStyle:function(r,o,p){var q=this;return q.run(r,function(v){var u,t;u=v.style;o=o.replace(/-(\D)/g,function(x,s){return s.toUpperCase()});if(q.pixelStyles.test(o)&&(m.is(p,"number")||/^[\-0-9\.]+$/.test(p))){p+="px"}switch(o){case"opacity":if(d){u.filter=p===""?"":"alpha(opacity="+(p*100)+")";if(!r.currentStyle||!r.currentStyle.hasLayout){u.display="inline-block"}}u[o]=u["-moz-opacity"]=u["-khtml-opacity"]=p||"";break;case"float":d?u.styleFloat=p:u.cssFloat=p;break;default:u[o]=p||""}if(q.settings.update_styles){q.setAttrib(v,"_mce_style")}})},getStyle:function(r,o,q){r=this.get(r);if(!r){return false}if(this.doc.defaultView&&q){o=o.replace(/[A-Z]/g,function(s){return"-"+s});try{return this.doc.defaultView.getComputedStyle(r,null).getPropertyValue(o)}catch(p){return null}}o=o.replace(/-(\D)/g,function(t,s){return s.toUpperCase()});if(o=="float"){o=d?"styleFloat":"cssFloat"}if(r.currentStyle&&q){return r.currentStyle[o]}return r.style[o]},setStyles:function(u,v){var q=this,r=q.settings,p;p=r.update_styles;r.update_styles=0;k(v,function(o,s){q.setStyle(u,s,o)});r.update_styles=p;if(r.update_styles){q.setAttrib(u,r.cssText)}},setAttrib:function(q,r,o){var p=this;if(!q||!r){return}if(p.settings.strict){r=r.toLowerCase()}return this.run(q,function(u){var t=p.settings;switch(r){case"style":if(!j(o,"string")){k(o,function(s,x){p.setStyle(u,x,s)});return}if(t.keep_values){if(o&&!p._isRes(o)){u.setAttribute("_mce_style",o,2)}else{u.removeAttribute("_mce_style",2)}}u.style.cssText=o;break;case"class":u.className=o||"";break;case"src":case"href":if(t.keep_values){if(t.url_converter){o=t.url_converter.call(t.url_converter_scope||p,o,r,u)}p.setAttrib(u,"_mce_"+r,o,2)}break;case"shape":u.setAttribute("_mce_style",o);break}if(j(o)&&o!==null&&o.length!==0){u.setAttribute(r,""+o,2)}else{u.removeAttribute(r,2)}})},setAttribs:function(q,r){var p=this;return this.run(q,function(o){k(r,function(s,t){p.setAttrib(o,t,s)})})},getAttrib:function(r,s,q){var o,p=this;r=p.get(r);if(!r||r.nodeType!==1){return false}if(!j(q)){q=""}if(/^(src|href|style|coords|shape)$/.test(s)){o=r.getAttribute("_mce_"+s);if(o){return o}}if(d&&p.props[s]){o=r[p.props[s]];o=o&&o.nodeValue?o.nodeValue:o}if(!o){o=r.getAttribute(s,2)}if(/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(s)){if(r[p.props[s]]===true&&o===""){return s}return o?s:""}if(r.nodeName==="FORM"&&r.getAttributeNode(s)){return r.getAttributeNode(s).nodeValue}if(s==="style"){o=o||r.style.cssText;if(o){o=p.serializeStyle(p.parseStyle(o),r.nodeName);if(p.settings.keep_values&&!p._isRes(o)){r.setAttribute("_mce_style",o)}}}if(i&&s==="class"&&o){o=o.replace(/(apple|webkit)\-[a-z\-]+/gi,"")}if(d){switch(s){case"rowspan":case"colspan":if(o===1){o=""}break;case"size":if(o==="+0"||o===20||o===0){o=""}break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":if(o===0){o=""}break;case"hspace":if(o===-1){o=""}break;case"maxlength":case"tabindex":if(o===32768||o===2147483647||o==="32768"){o=""}break;case"multiple":case"compact":case"noshade":case"nowrap":if(o===65535){return s}return q;case"shape":o=o.toLowerCase();break;default:if(s.indexOf("on")===0&&o){o=m._replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1",""+o)}}}return(o!==undefined&&o!==null&&o!=="")?""+o:q},getPos:function(A,s){var p=this,o=0,z=0,u,v=p.doc,q;A=p.get(A);s=s||v.body;if(A){if(d&&!p.stdMode){A=A.getBoundingClientRect();u=p.boxModel?v.documentElement:v.body;o=p.getStyle(p.select("html")[0],"borderWidth");o=(o=="medium"||p.boxModel&&!p.isIE6)&&2||o;return{x:A.left+u.scrollLeft-o,y:A.top+u.scrollTop-o}}q=A;while(q&&q!=s&&q.nodeType){o+=q.offsetLeft||0;z+=q.offsetTop||0;q=q.offsetParent}q=A.parentNode;while(q&&q!=s&&q.nodeType){o-=q.scrollLeft||0;z-=q.scrollTop||0;q=q.parentNode}}return{x:o,y:z}},parseStyle:function(r){var u=this,v=u.settings,x={};if(!r){return x}function p(D,A,C){var z,B,o,y;z=x[D+"-top"+A];if(!z){return}B=x[D+"-right"+A];if(z!=B){return}o=x[D+"-bottom"+A];if(B!=o){return}y=x[D+"-left"+A];if(o!=y){return}x[C]=y;delete x[D+"-top"+A];delete x[D+"-right"+A];delete x[D+"-bottom"+A];delete x[D+"-left"+A]}function q(y,s,o,A){var z;z=x[s];if(!z){return}z=x[o];if(!z){return}z=x[A];if(!z){return}x[y]=x[s]+" "+x[o]+" "+x[A];delete x[s];delete x[o];delete x[A]}r=r.replace(/&(#?[a-z0-9]+);/g,"&$1_MCE_SEMI_");k(r.split(";"),function(s){var o,t=[];if(s){s=s.replace(/_MCE_SEMI_/g,";");s=s.replace(/url\([^\)]+\)/g,function(y){t.push(y);return"url("+t.length+")"});s=s.split(":");o=m.trim(s[1]);o=o.replace(/url\(([^\)]+)\)/g,function(z,y){return t[parseInt(y)-1]});o=o.replace(/rgb\([^\)]+\)/g,function(y){return u.toHex(y)});if(v.url_converter){o=o.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g,function(y,z){return"url("+v.url_converter.call(v.url_converter_scope||u,u.decode(z),"style",null)+")"})}x[m.trim(s[0]).toLowerCase()]=o}});p("border","","border");p("border","-width","border-width");p("border","-color","border-color");p("border","-style","border-style");p("padding","","padding");p("margin","","margin");q("border","border-width","border-style","border-color");if(d){if(x.border=="medium none"){x.border=""}}return x},serializeStyle:function(v,p){var q=this,r="";function u(s,o){if(o&&s){if(o.indexOf("-")===0){return}switch(o){case"font-weight":if(s==700){s="bold"}break;case"color":case"background-color":s=s.toLowerCase();break}r+=(r?" ":"")+o+": "+s+";"}}if(p&&q._styles){k(q._styles["*"],function(o){u(v[o],o)});k(q._styles[p.toLowerCase()],function(o){u(v[o],o)})}else{k(v,u)}return r},loadCSS:function(o){var q=this,r=q.doc,p;if(!o){o=""}p=q.select("head")[0];k(o.split(","),function(s){var t;if(q.files[s]){return}q.files[s]=true;t=q.create("link",{rel:"stylesheet",href:m._addVer(s)});if(d&&r.documentMode&&r.recalc){t.onload=function(){r.recalc();t.onload=null}}p.appendChild(t)})},addClass:function(o,p){return this.run(o,function(q){var r;if(!p){return 0}if(this.hasClass(q,p)){return q.className}r=this.removeClass(q,p);return q.className=(r!=""?(r+" "):"")+p})},removeClass:function(q,r){var o=this,p;return o.run(q,function(t){var s;if(o.hasClass(t,r)){if(!p){p=new RegExp("(^|\\s+)"+r+"(\\s+|$)","g")}s=t.className.replace(p," ");s=m.trim(s!=" "?s:"");t.className=s;if(!s){t.removeAttribute("class");t.removeAttribute("className")}return s}return t.className})},hasClass:function(p,o){p=this.get(p);if(!p||!o){return false}return(" "+p.className+" ").indexOf(" "+o+" ")!==-1},show:function(o){return this.setStyle(o,"display","block")},hide:function(o){return this.setStyle(o,"display","none")},isHidden:function(o){o=this.get(o);return !o||o.style.display=="none"||this.getStyle(o,"display")=="none"},uniqueId:function(o){return(!o?"mce_":o)+(this.counter++)},setHTML:function(q,p){var o=this;return this.run(q,function(v){var r,t,s,z,u,r;p=o.processHTML(p);if(d){function y(){while(v.firstChild){v.firstChild.removeNode()}try{v.innerHTML="
    "+p;v.removeChild(v.firstChild)}catch(x){r=o.create("div");r.innerHTML="
    "+p;k(r.childNodes,function(B,A){if(A){v.appendChild(B)}})}}if(o.settings.fix_ie_paragraphs){p=p.replace(/

    <\/p>|]+)><\/p>|/gi,' 

    ')}y();if(o.settings.fix_ie_paragraphs){s=v.getElementsByTagName("p");for(t=s.length-1,r=0;t>=0;t--){z=s[t];if(!z.hasChildNodes()){if(!z._mce_keep){r=1;break}z.removeAttribute("_mce_keep")}}}if(r){p=p.replace(/

    ]+)>|

    /ig,'

    ');p=p.replace(/<\/p>/gi,"
    ");y();if(o.settings.fix_ie_paragraphs){s=v.getElementsByTagName("DIV");for(t=s.length-1;t>=0;t--){z=s[t];if(z._mce_tmp){u=o.doc.createElement("p");z.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi,function(A,x){var B;if(x!=="_mce_tmp"){B=z.getAttribute(x);if(!B&&x==="class"){B=z.className}u.setAttribute(x,B)}});for(r=0;r]+)\/>|/gi,"",r);if(q.keep_values){if(/)/g,"\n");t=t.replace(/^[\r\n]*|[\r\n]*$/g,"");t=t.replace(/^\s*(\/\/\s*|\]\]>|-->|\]\]-->)\s*$/g,"");return t}r=r.replace(/]+|)>([\s\S]*?)<\/script>/gi,function(s,x,t){if(!x){x=' type="text/javascript"'}x=x.replace(/src=\"([^\"]+)\"?/i,function(y,z){if(q.url_converter){z=p.encode(q.url_converter.call(q.url_converter_scope||p,p.decode(z),"src","script"))}return'_mce_src="'+z+'"'});if(m.trim(t)){v.push(o(t));t=""}return""+t+""});r=r.replace(/]+|)>([\s\S]*?)<\/style>/gi,function(s,x,t){if(t){v.push(o(t));t=""}return""+t+""});r=r.replace(/]+|)>([\s\S]*?)<\/noscript>/g,function(s,x,t){return""})}r=m._replace(//g,"",r);function u(s){return s.replace(h,function(y,z,x,t){return"<"+z+x.replace(l,function(B,A,E,D,C){var F;A=A.toLowerCase();E=E||D||C||"";if(e[A]){if(E==="false"||E==="0"){return}return A+'="'+A+'"'}if(f[A]&&x.indexOf("_mce_"+A)==-1){F=p.decode(E);if(q.url_converter&&(A=="src"||A=="href")){F=q.url_converter.call(q.url_converter_scope||p,F,A,z)}if(A=="style"){F=p.serializeStyle(p.parseStyle(F),A)}return A+'="'+E+'" _mce_'+A+'="'+p.encode(F)+'"'}return B})+t+">"})}r=u(r);r=r.replace(/MCE_SCRIPT:([0-9]+)/g,function(t,s){return v[s]})}return r},getOuterHTML:function(o){var p;o=this.get(o);if(!o){return null}if(o.outerHTML!==undefined){return o.outerHTML}p=(o.ownerDocument||this.doc).createElement("body");p.appendChild(o.cloneNode(true));return p.innerHTML},setOuterHTML:function(r,p,s){var o=this;function q(u,t,x){var y,v;v=x.createElement("body");v.innerHTML=t;y=v.lastChild;while(y){o.insertAfter(y.cloneNode(true),u);y=y.previousSibling}o.remove(u)}return this.run(r,function(u){u=o.get(u);if(u.nodeType==1){s=s||u.ownerDocument||o.doc;if(d){try{if(d&&u.nodeType==1){u.outerHTML=p}else{q(u,p,s)}}catch(t){q(u,p,s)}}else{q(u,p,s)}}})},decode:function(p){var q,r,o;if(/&[\w#]+;/.test(p)){q=this.doc.createElement("div");q.innerHTML=p;r=q.firstChild;o="";if(r){do{o+=r.nodeValue}while(r=r.nextSibling)}return o||p}return p},encode:function(o){return(""+o).replace(n,function(p){return c[p]})},insertAfter:function(o,p){p=this.get(p);return this.run(o,function(r){var q,s;q=p.parentNode;s=p.nextSibling;if(s){q.insertBefore(r,s)}else{q.appendChild(r)}return r})},isBlock:function(o){if(o.nodeType&&o.nodeType!==1){return false}o=o.nodeName||o;return a.test(o)},replace:function(s,r,p){var q=this;if(j(r,"array")){s=s.cloneNode(true)}return q.run(r,function(t){if(p){k(m.grep(t.childNodes),function(o){s.appendChild(o)})}return t.parentNode.replaceChild(s,t)})},rename:function(r,o){var q=this,p;if(r.nodeName!=o.toUpperCase()){p=q.create(o);k(q.getAttribs(r),function(s){q.setAttrib(p,s.nodeName,q.getAttrib(r,s.nodeName))});q.replace(p,r,1)}return p||r},findCommonAncestor:function(q,o){var r=q,p;while(r){p=o;while(p&&r!=p){p=p.parentNode}if(r==p){break}r=r.parentNode}if(!r&&q.ownerDocument){return q.ownerDocument.documentElement}return r},toHex:function(o){var q=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(o);function p(r){r=parseInt(r).toString(16);return r.length>1?r:"0"+r}if(q){o="#"+p(q[1])+p(q[2])+p(q[3]);return o}return o},getClasses:function(){var s=this,o=[],r,u={},v=s.settings.class_filter,q;if(s.classes){return s.classes}function x(t){k(t.imports,function(y){x(y)});k(t.cssRules||t.rules,function(y){switch(y.type||1){case 1:if(y.selectorText){k(y.selectorText.split(","),function(z){z=z.replace(/^\s*|\s*$|^\s\./g,"");if(/\.mce/.test(z)||!/\.[\w\-]+$/.test(z)){return}q=z;z=m._replace(/.*\.([a-z0-9_\-]+).*/i,"$1",z);if(v&&!(z=v(z,q))){return}if(!u[z]){o.push({"class":z});u[z]=1}})}break;case 3:x(y.styleSheet);break}})}try{k(s.doc.styleSheets,x)}catch(p){}if(o.length>0){s.classes=o}return o},run:function(u,r,q){var p=this,v;if(p.doc&&typeof(u)==="string"){u=p.get(u)}if(!u){return false}q=q||this;if(!u.nodeType&&(u.length||u.length===0)){v=[];k(u,function(s,o){if(s){if(typeof(s)=="string"){s=p.doc.getElementById(s)}v.push(r.call(q,s,o))}});return v}return r.call(q,u)},getAttribs:function(q){var p;q=this.get(q);if(!q){return[]}if(d){p=[];if(q.nodeName=="OBJECT"){return q.attributes}if(q.nodeName==="OPTION"&&this.getAttrib(q,"selected")){p.push({specified:1,nodeName:"selected"})}q.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi,"").replace(/[\w:\-]+/gi,function(o){p.push({specified:1,nodeName:o})});return p}return q.attributes},destroy:function(p){var o=this;if(o.events){o.events.destroy()}o.win=o.doc=o.root=o.events=null;if(!p){m.removeUnload(o.destroy)}},createRng:function(){var o=this.doc;return o.createRange?o.createRange():new m.dom.Range(this)},nodeIndex:function(s,t){var o=0,q,r,p;if(s){for(q=s.nodeType,s=s.previousSibling,r=s;s;s=s.previousSibling){p=s.nodeType;if(t&&p==3){if(p==q||!s.nodeValue.length){continue}}o++;q=p}}return o},split:function(u,s,y){var z=this,o=z.createRng(),v,q,x;function p(A){var t,r=A.childNodes;if(A.nodeType==1&&A.getAttribute("_mce_type")=="bookmark"){return}for(t=r.length-1;t>=0;t--){p(r[t])}if(A.nodeType!=9){if(A.nodeType==3&&A.nodeValue.length>0){if(!z.isBlock(A.parentNode)||m.trim(A.nodeValue).length>0){return}}if(A.nodeType==1){r=A.childNodes;if(r.length==1&&r[0]&&r[0].nodeType==1&&r[0].getAttribute("_mce_type")=="bookmark"){A.parentNode.insertBefore(r[0],A)}if(r.length||/^(br|hr|input|img)$/i.test(A.nodeName)){return}}z.remove(A)}return A}if(u&&s){o.setStart(u.parentNode,z.nodeIndex(u));o.setEnd(s.parentNode,z.nodeIndex(s));v=o.extractContents();o=z.createRng();o.setStart(s.parentNode,z.nodeIndex(s)+1);o.setEnd(u.parentNode,z.nodeIndex(u)+1);q=o.extractContents();x=u.parentNode;x.insertBefore(p(v),u);if(y){x.replaceChild(y,s)}else{x.insertBefore(s,u)}x.insertBefore(p(q),u);z.remove(u);return y||s}},bind:function(s,o,r,q){var p=this;if(!p.events){p.events=new m.dom.EventUtils()}return p.events.add(s,o,r,q||this)},unbind:function(r,o,q){var p=this;if(!p.events){p.events=new m.dom.EventUtils()}return p.events.remove(r,o,q)},_findSib:function(r,o,p){var q=this,s=o;if(r){if(j(s,"string")){s=function(t){return q.is(t,o)}}for(r=r[p];r;r=r[p]){if(s(r)){return r}}}return null},_isRes:function(o){return/^(top|left|bottom|right|width|height)/i.test(o)||/;\s*(top|left|bottom|right|width|height)/i.test(o)}});m.DOM=new m.dom.DOMUtils(document,{process_html:0})})(tinymce);(function(a){function b(c){var N=this,e=c.doc,S=0,E=1,j=2,D=true,R=false,U="startOffset",h="startContainer",P="endContainer",z="endOffset",k=tinymce.extend,n=c.nodeIndex;k(N,{startContainer:e,startOffset:0,endContainer:e,endOffset:0,collapsed:D,commonAncestorContainer:e,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:q,setEnd:s,setStartBefore:g,setStartAfter:I,setEndBefore:J,setEndAfter:u,collapse:A,selectNode:x,selectNodeContents:F,compareBoundaryPoints:v,deleteContents:p,extractContents:H,cloneContents:d,insertNode:C,surroundContents:M,cloneRange:K});function q(V,t){B(D,V,t)}function s(V,t){B(R,V,t)}function g(t){q(t.parentNode,n(t))}function I(t){q(t.parentNode,n(t)+1)}function J(t){s(t.parentNode,n(t))}function u(t){s(t.parentNode,n(t)+1)}function A(t){if(t){N[P]=N[h];N[z]=N[U]}else{N[h]=N[P];N[U]=N[z]}N.collapsed=D}function x(t){g(t);u(t)}function F(t){q(t,0);s(t,t.nodeType===1?t.childNodes.length:t.nodeValue.length)}function v(W,X){var Z=N[h],Y=N[U],V=N[P],t=N[z];if(W===0){return G(Z,Y,Z,Y)}if(W===1){return G(Z,Y,V,t)}if(W===2){return G(V,t,V,t)}if(W===3){return G(V,t,Z,Y)}}function p(){m(j)}function H(){return m(S)}function d(){return m(E)}function C(Y){var V=this[h],t=this[U],X,W;if((V.nodeType===3||V.nodeType===4)&&V.nodeValue){if(!t){V.parentNode.insertBefore(Y,V)}else{if(t>=V.nodeValue.length){c.insertAfter(Y,V)}else{X=V.splitText(t);V.parentNode.insertBefore(Y,X)}}}else{if(V.childNodes.length>0){W=V.childNodes[t]}if(W){V.insertBefore(Y,W)}else{V.appendChild(Y)}}}function M(V){var t=N.extractContents();N.insertNode(V);V.appendChild(t);N.selectNode(V)}function K(){return k(new b(c),{startContainer:N[h],startOffset:N[U],endContainer:N[P],endOffset:N[z],collapsed:N.collapsed,commonAncestorContainer:N.commonAncestorContainer})}function O(t,V){var W;if(t.nodeType==3){return t}if(V<0){return t}W=t.firstChild;while(W&&V>0){--V;W=W.nextSibling}if(W){return W}return t}function l(){return(N[h]==N[P]&&N[U]==N[z])}function G(X,Z,V,Y){var aa,W,t,ab,ad,ac;if(X==V){if(Z==Y){return 0}if(Z0){N.collapse(V)}}else{N.collapse(V)}N.collapsed=l();N.commonAncestorContainer=c.findCommonAncestor(N[h],N[P])}function m(ab){var aa,X=0,ad=0,V,Z,W,Y,t,ac;if(N[h]==N[P]){return f(ab)}for(aa=N[P],V=aa.parentNode;V;aa=V,V=V.parentNode){if(V==N[h]){return r(aa,ab)}++X}for(aa=N[h],V=aa.parentNode;V;aa=V,V=V.parentNode){if(V==N[P]){return T(aa,ab)}++ad}Z=ad-X;W=N[h];while(Z>0){W=W.parentNode;Z--}Y=N[P];while(Z<0){Y=Y.parentNode;Z++}for(t=W.parentNode,ac=Y.parentNode;t!=ac;t=t.parentNode,ac=ac.parentNode){W=t;Y=ac}return o(W,Y,ab)}function f(Z){var ab,Y,X,aa,t,W,V;if(Z!=j){ab=e.createDocumentFragment()}if(N[U]==N[z]){return ab}if(N[h].nodeType==3){Y=N[h].nodeValue;X=Y.substring(N[U],N[z]);if(Z!=E){N[h].deleteData(N[U],N[z]-N[U]);N.collapse(D)}if(Z==j){return}ab.appendChild(e.createTextNode(X));return ab}aa=O(N[h],N[U]);t=N[z]-N[U];while(t>0){W=aa.nextSibling;V=y(aa,Z);if(ab){ab.appendChild(V)}--t;aa=W}if(Z!=E){N.collapse(D)}return ab}function r(ab,Y){var aa,Z,V,t,X,W;if(Y!=j){aa=e.createDocumentFragment()}Z=i(ab,Y);if(aa){aa.appendChild(Z)}V=n(ab);t=V-N[U];if(t<=0){if(Y!=E){N.setEndBefore(ab);N.collapse(R)}return aa}Z=ab.previousSibling;while(t>0){X=Z.previousSibling;W=y(Z,Y);if(aa){aa.insertBefore(W,aa.firstChild)}--t;Z=X}if(Y!=E){N.setEndBefore(ab);N.collapse(R)}return aa}function T(Z,Y){var ab,V,aa,t,X,W;if(Y!=j){ab=e.createDocumentFragment()}aa=Q(Z,Y);if(ab){ab.appendChild(aa)}V=n(Z);++V;t=N[z]-V;aa=Z.nextSibling;while(t>0){X=aa.nextSibling;W=y(aa,Y);if(ab){ab.appendChild(W)}--t;aa=X}if(Y!=E){N.setStartAfter(Z);N.collapse(D)}return ab}function o(Z,t,ac){var W,ae,Y,aa,ab,V,ad,X;if(ac!=j){ae=e.createDocumentFragment()}W=Q(Z,ac);if(ae){ae.appendChild(W)}Y=Z.parentNode;aa=n(Z);ab=n(t);++aa;V=ab-aa;ad=Z.nextSibling;while(V>0){X=ad.nextSibling;W=y(ad,ac);if(ae){ae.appendChild(W)}ad=X;--V}W=i(t,ac);if(ae){ae.appendChild(W)}if(ac!=E){N.setStartAfter(Z);N.collapse(D)}return ae}function i(aa,ab){var W=O(N[P],N[z]-1),ac,Z,Y,t,V,X=W!=N[P];if(W==aa){return L(W,X,R,ab)}ac=W.parentNode;Z=L(ac,R,R,ab);while(ac){while(W){Y=W.previousSibling;t=L(W,X,R,ab);if(ab!=j){Z.insertBefore(t,Z.firstChild)}X=D;W=Y}if(ac==aa){return Z}W=ac.previousSibling;ac=ac.parentNode;V=L(ac,R,R,ab);if(ab!=j){V.appendChild(Z)}Z=V}}function Q(aa,ab){var X=O(N[h],N[U]),Y=X!=N[h],ac,Z,W,t,V;if(X==aa){return L(X,Y,D,ab)}ac=X.parentNode;Z=L(ac,R,D,ab);while(ac){while(X){W=X.nextSibling;t=L(X,Y,D,ab);if(ab!=j){Z.appendChild(t)}Y=D;X=W}if(ac==aa){return Z}X=ac.nextSibling;ac=ac.parentNode;V=L(ac,R,D,ab);if(ab!=j){V.appendChild(Z)}Z=V}}function L(t,Y,ab,ac){var X,W,Z,V,aa;if(Y){return y(t,ac)}if(t.nodeType==3){X=t.nodeValue;if(ab){V=N[U];W=X.substring(V);Z=X.substring(0,V)}else{V=N[z];W=X.substring(0,V);Z=X.substring(V)}if(ac!=E){t.nodeValue=Z}if(ac==j){return}aa=t.cloneNode(R);aa.nodeValue=W;return aa}if(ac==j){return}return t.cloneNode(R)}function y(V,t){if(t!=j){return t==E?V.cloneNode(D):V}V.parentNode.removeChild(V)}}a.Range=b})(tinymce.dom);(function(){function a(g){var i=this,j="\uFEFF",e,h,d=g.dom,c=true,f=false;function b(){var n=g.getRng(),k=d.createRng(),m,o;m=n.item?n.item(0):n.parentElement();if(m.ownerDocument!=d.doc){return k}if(n.item||!m.hasChildNodes()){k.setStart(m.parentNode,d.nodeIndex(m));k.setEnd(k.startContainer,k.startOffset+1);return k}o=g.isCollapsed();function l(s){var u,q,t,p,A=0,x,y,z,r,v;r=n.duplicate();r.collapse(s);u=d.create("a");z=r.parentElement();if(!z.hasChildNodes()){k[s?"setStart":"setEnd"](z,0);return}z.appendChild(u);r.moveToElementText(u);v=n.compareEndPoints(s?"StartToStart":"EndToEnd",r);if(v>0){k[s?"setStartAfter":"setEndAfter"](z);d.remove(u);return}p=tinymce.grep(z.childNodes);x=p.length-1;while(A<=x){y=Math.floor((A+x)/2);z.insertBefore(u,p[y]);r.moveToElementText(u);v=n.compareEndPoints(s?"StartToStart":"EndToEnd",r);if(v>0){A=y+1}else{if(v<0){x=y-1}else{found=true;break}}}q=v>0||y==0?u.nextSibling:u.previousSibling;if(q.nodeType==1){d.remove(u);t=d.nodeIndex(q);q=q.parentNode;if(!s||y>0){t++}}else{if(v>0||y==0){r.setEndPoint(s?"StartToStart":"EndToEnd",n);t=r.text.length}else{r.setEndPoint(s?"StartToStart":"EndToEnd",n);t=q.nodeValue.length-r.text.length}d.remove(u)}k[s?"setStart":"setEnd"](q,t)}l(true);if(!o){l()}return k}this.addRange=function(k){var p,n,m,r,u,s,t=g.dom.doc,o=t.body;function l(B){var x,A,v,z,y;v=d.create("a");x=B?m:u;A=B?r:s;z=p.duplicate();if(x==t){x=o;A=0}if(x.nodeType==3){x.parentNode.insertBefore(v,x);z.moveToElementText(v);z.moveStart("character",A);d.remove(v);p.setEndPoint(B?"StartToStart":"EndToEnd",z)}else{y=x.childNodes;if(y.length){if(A>=y.length){d.insertAfter(v,y[y.length-1])}else{x.insertBefore(v,y[A])}z.moveToElementText(v)}else{v=t.createTextNode(j);x.appendChild(v);z.moveToElementText(v.parentNode);z.collapse(c)}p.setEndPoint(B?"StartToStart":"EndToEnd",z);d.remove(v)}}this.destroy();m=k.startContainer;r=k.startOffset;u=k.endContainer;s=k.endOffset;p=o.createTextRange();if(m==u&&m.nodeType==1&&r==s-1){if(r==s-1){try{n=o.createControlRange();n.addElement(m.childNodes[r]);n.select();n.scrollIntoView();return}catch(q){}}}l(true);l();p.select();p.scrollIntoView()};this.getRangeAt=function(){if(!e||!tinymce.dom.RangeUtils.compareRanges(h,g.getRng())){e=b();h=g.getRng()}try{e.startContainer.nextSibling}catch(k){e=b();h=null}return e};this.destroy=function(){h=e=null}}tinymce.dom.TridentSelection=a})();(function(){var p=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,j=0,d=Object.prototype.toString,o=false,i=true;[0,0].sort(function(){i=false;return 0});var b=function(v,e,z,A){z=z||[];e=e||document;var C=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!v||typeof v!=="string"){return z}var x=[],s,E,H,r,u=true,t=b.isXML(e),B=v,D,G,F,y;do{p.exec("");s=p.exec(B);if(s){B=s[3];x.push(s[1]);if(s[2]){r=s[3];break}}}while(s);if(x.length>1&&k.exec(v)){if(x.length===2&&f.relative[x[0]]){E=h(x[0]+x[1],e)}else{E=f.relative[x[0]]?[e]:b(x.shift(),e);while(x.length){v=x.shift();if(f.relative[v]){v+=x.shift()}E=h(v,E)}}}else{if(!A&&x.length>1&&e.nodeType===9&&!t&&f.match.ID.test(x[0])&&!f.match.ID.test(x[x.length-1])){D=b.find(x.shift(),e,t);e=D.expr?b.filter(D.expr,D.set)[0]:D.set[0]}if(e){D=A?{expr:x.pop(),set:a(A)}:b.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&e.parentNode?e.parentNode:e,t);E=D.expr?b.filter(D.expr,D.set):D.set;if(x.length>0){H=a(E)}else{u=false}while(x.length){G=x.pop();F=G;if(!f.relative[G]){G=""}else{F=x.pop()}if(F==null){F=e}f.relative[G](H,F,t)}}else{H=x=[]}}if(!H){H=E}if(!H){b.error(G||v)}if(d.call(H)==="[object Array]"){if(!u){z.push.apply(z,H)}else{if(e&&e.nodeType===1){for(y=0;H[y]!=null;y++){if(H[y]&&(H[y]===true||H[y].nodeType===1&&b.contains(e,H[y]))){z.push(E[y])}}}else{for(y=0;H[y]!=null;y++){if(H[y]&&H[y].nodeType===1){z.push(E[y])}}}}}else{a(H,z)}if(r){b(r,C,z,A);b.uniqueSort(z)}return z};b.uniqueSort=function(r){if(c){o=i;r.sort(c);if(o){for(var e=1;e":function(x,r){var u=typeof r==="string",v,s=0,e=x.length;if(u&&!/\W/.test(r)){r=r.toLowerCase();for(;s=0)){if(!s){e.push(v)}}else{if(s){r[u]=false}}}}return false},ID:function(e){return e[1].replace(/\\/g,"")},TAG:function(r,e){return r[1].toLowerCase()},CHILD:function(e){if(e[1]==="nth"){var r=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(r[1]+(r[2]||1))-0;e[3]=r[3]-0}e[0]=j++;return e},ATTR:function(u,r,s,e,v,x){var t=u[1].replace(/\\/g,"");if(!x&&f.attrMap[t]){u[1]=f.attrMap[t]}if(u[2]==="~="){u[4]=" "+u[4]+" "}return u},PSEUDO:function(u,r,s,e,v){if(u[1]==="not"){if((p.exec(u[3])||"").length>1||/^\w/.test(u[3])){u[3]=b(u[3],null,null,r)}else{var t=b.filter(u[3],r,s,true^v);if(!s){e.push.apply(e,t)}return false}}else{if(f.match.POS.test(u[0])||f.match.CHILD.test(u[0])){return true}}return u},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(s,r,e){return !!b(e[3],s).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(e){return"text"===e.type},radio:function(e){return"radio"===e.type},checkbox:function(e){return"checkbox"===e.type},file:function(e){return"file"===e.type},password:function(e){return"password"===e.type},submit:function(e){return"submit"===e.type},image:function(e){return"image"===e.type},reset:function(e){return"reset"===e.type},button:function(e){return"button"===e.type||e.nodeName.toLowerCase()==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)}},setFilters:{first:function(r,e){return e===0},last:function(s,r,e,t){return r===t.length-1},even:function(r,e){return e%2===0},odd:function(r,e){return e%2===1},lt:function(s,r,e){return re[3]-0},nth:function(s,r,e){return e[3]-0===r},eq:function(s,r,e){return e[3]-0===r}},filter:{PSEUDO:function(s,y,x,z){var e=y[1],r=f.filters[e];if(r){return r(s,x,y,z)}else{if(e==="contains"){return(s.textContent||s.innerText||b.getText([s])||"").indexOf(y[3])>=0}else{if(e==="not"){var t=y[3];for(var v=0,u=t.length;v=0)}}},ID:function(r,e){return r.nodeType===1&&r.getAttribute("id")===e},TAG:function(r,e){return(e==="*"&&r.nodeType===1)||r.nodeName.toLowerCase()===e},CLASS:function(r,e){return(" "+(r.className||r.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(v,t){var s=t[1],e=f.attrHandle[s]?f.attrHandle[s](v):v[s]!=null?v[s]:v.getAttribute(s),x=e+"",u=t[2],r=t[4];return e==null?u==="!=":u==="="?x===r:u==="*="?x.indexOf(r)>=0:u==="~="?(" "+x+" ").indexOf(r)>=0:!r?x&&e!==false:u==="!="?x!==r:u==="^="?x.indexOf(r)===0:u==="$="?x.substr(x.length-r.length)===r:u==="|="?x===r||x.substr(0,r.length+1)===r+"-":false},POS:function(u,r,s,v){var e=r[2],t=f.setFilters[e];if(t){return t(u,s,r,v)}}}};var k=f.match.POS,g=function(r,e){return"\\"+(e-0+1)};for(var m in f.match){f.match[m]=new RegExp(f.match[m].source+(/(?![^\[]*\])(?![^\(]*\))/.source));f.leftMatch[m]=new RegExp(/(^(?:.|\r|\n)*?)/.source+f.match[m].source.replace(/\\(\d+)/g,g))}var a=function(r,e){r=Array.prototype.slice.call(r,0);if(e){e.push.apply(e,r);return e}return r};try{Array.prototype.slice.call(document.documentElement.childNodes,0)[0].nodeType}catch(l){a=function(u,t){var r=t||[],s=0;if(d.call(u)==="[object Array]"){Array.prototype.push.apply(r,u)}else{if(typeof u.length==="number"){for(var e=u.length;s";var e=document.documentElement;e.insertBefore(r,e.firstChild);if(document.getElementById(s)){f.find.ID=function(u,v,x){if(typeof v.getElementById!=="undefined"&&!x){var t=v.getElementById(u[1]);return t?t.id===u[1]||typeof t.getAttributeNode!=="undefined"&&t.getAttributeNode("id").nodeValue===u[1]?[t]:undefined:[]}};f.filter.ID=function(v,t){var u=typeof v.getAttributeNode!=="undefined"&&v.getAttributeNode("id");return v.nodeType===1&&u&&u.nodeValue===t}}e.removeChild(r);e=r=null})();(function(){var e=document.createElement("div");e.appendChild(document.createComment(""));if(e.getElementsByTagName("*").length>0){f.find.TAG=function(r,v){var u=v.getElementsByTagName(r[1]);if(r[1]==="*"){var t=[];for(var s=0;u[s];s++){if(u[s].nodeType===1){t.push(u[s])}}u=t}return u}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){f.attrHandle.href=function(r){return r.getAttribute("href",2)}}e=null})();if(document.querySelectorAll){(function(){var e=b,s=document.createElement("div");s.innerHTML="

    ";if(s.querySelectorAll&&s.querySelectorAll(".TEST").length===0){return}b=function(x,v,t,u){v=v||document;if(!u&&v.nodeType===9&&!b.isXML(v)){try{return a(v.querySelectorAll(x),t)}catch(y){}}return e(x,v,t,u)};for(var r in e){b[r]=e[r]}s=null})()}(function(){var e=document.createElement("div");e.innerHTML="
    ";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}f.order.splice(1,0,"CLASS");f.find.CLASS=function(r,s,t){if(typeof s.getElementsByClassName!=="undefined"&&!t){return s.getElementsByClassName(r[1])}};e=null})();function n(r,x,v,A,y,z){for(var t=0,s=A.length;t0){u=e;break}}}e=e[r]}A[t]=u}}}b.contains=document.compareDocumentPosition?function(r,e){return !!(r.compareDocumentPosition(e)&16)}:function(r,e){return r!==e&&(r.contains?r.contains(e):true)};b.isXML=function(e){var r=(e?e.ownerDocument||e:0).documentElement;return r?r.nodeName!=="HTML":false};var h=function(e,y){var t=[],u="",v,s=y.nodeType?[y]:y;while((v=f.match.PSEUDO.exec(e))){u+=v[0];e=e.replace(f.match.PSEUDO,"")}e=f.relative[e]?e+"*":e;for(var x=0,r=s.length;x=0;h--){k=g[h];if(k.obj===l){j._remove(k.obj,k.name,k.cfunc);k.obj=k.cfunc=null;g.splice(h,1)}}}},cancel:function(g){if(!g){return false}this.stop(g);return this.prevent(g)},stop:function(g){if(g.stopPropagation){g.stopPropagation()}else{g.cancelBubble=true}return false},prevent:function(g){if(g.preventDefault){g.preventDefault()}else{g.returnValue=false}return false},destroy:function(){var g=this;f(g.events,function(j,h){g._remove(j.obj,j.name,j.cfunc);j.obj=j.cfunc=null});g.events=[];g=null},_add:function(h,i,g){if(h.attachEvent){h.attachEvent("on"+i,g)}else{if(h.addEventListener){h.addEventListener(i,g,false)}else{h["on"+i]=g}}},_remove:function(i,j,h){if(i){try{if(i.detachEvent){i.detachEvent("on"+j,h)}else{if(i.removeEventListener){i.removeEventListener(j,h,false)}else{i["on"+j]=null}}}catch(g){}}},_pageInit:function(h){var g=this;if(g.domLoaded){return}g.domLoaded=true;f(g.inits,function(i){i()});g.inits=[]},_wait:function(i){var g=this,h=i.document;if(i.tinyMCE_GZ&&tinyMCE_GZ.loaded){g.domLoaded=1;return}if(h.attachEvent){h.attachEvent("onreadystatechange",function(){if(h.readyState==="complete"){h.detachEvent("onreadystatechange",arguments.callee);g._pageInit(i)}});if(h.documentElement.doScroll&&i==i.top){(function(){if(g.domLoaded){return}try{h.documentElement.doScroll("left")}catch(j){setTimeout(arguments.callee,0);return}g._pageInit(i)})()}}else{if(h.addEventListener){g._add(i,"DOMContentLoaded",function(){g._pageInit(i)})}}g._add(i,"load",function(){g._pageInit(i)})},_stoppers:{preventDefault:function(){this.returnValue=false},stopPropagation:function(){this.cancelBubble=true}}});a=d.dom.Event=new d.dom.EventUtils();a._wait(window);d.addUnload(function(){a.destroy()})})(tinymce);(function(a){a.dom.Element=function(f,d){var b=this,e,c;b.settings=d=d||{};b.id=f;b.dom=e=d.dom||a.DOM;if(!a.isIE){c=e.get(b.id)}a.each(("getPos,getRect,getParent,add,setStyle,getStyle,setStyles,setAttrib,setAttribs,getAttrib,addClass,removeClass,hasClass,getOuterHTML,setOuterHTML,remove,show,hide,isHidden,setHTML,get").split(/,/),function(g){b[g]=function(){var h=[f],j;for(j=0;j_';if(k.startContainer==l&&k.endContainer==l){l.body.innerHTML=j}else{k.deleteContents();if(l.body.childNodes.length==0){l.body.innerHTML=j}else{if(k.createContextualFragment){k.insertNode(k.createContextualFragment(j))}else{var m=l.createDocumentFragment(),f=l.createElement("div");m.appendChild(f);f.outerHTML=j;k.insertNode(m)}}}n=g.dom.get("__caret");k=l.createRange();k.setStartBefore(n);k.setEndBefore(n);g.setRng(k);g.dom.remove("__caret")}else{if(k.item){l.execCommand("Delete",false,null);k=g.getRng()}k.pasteHTML(j)}g.onSetContent.dispatch(g,i)},getStart:function(){var g=this.getRng(),h,f,j,i;if(g.duplicate||g.item){if(g.item){return g.item(0)}j=g.duplicate();j.collapse(1);h=j.parentElement();f=i=g.parentElement();while(i=i.parentNode){if(i==h){h=f;break}}if(h&&h.nodeName=="BODY"){return h.firstChild||h}return h}else{h=g.startContainer;if(h.nodeType==1&&h.hasChildNodes()){h=h.childNodes[Math.min(h.childNodes.length-1,g.startOffset)]}if(h&&h.nodeType==3){return h.parentNode}return h}},getEnd:function(){var g=this,h=g.getRng(),i,f;if(h.duplicate||h.item){if(h.item){return h.item(0)}h=h.duplicate();h.collapse(0);i=h.parentElement();if(i&&i.nodeName=="BODY"){return i.lastChild||i}return i}else{i=h.endContainer;f=h.endOffset;if(i.nodeType==1&&i.hasChildNodes()){i=i.childNodes[f>0?f-1:f]}if(i&&i.nodeType==3){return i.parentNode}return i}},getBookmark:function(q,r){var u=this,m=u.dom,g,j,i,n,h,o,p,l="\uFEFF",s;function f(v,x){var t=0;d(m.select(v),function(z,y){if(z==x){t=y}});return t}if(q==2){function k(){var v=u.getRng(true),t=m.getRoot(),x={};function y(B,G){var A=B[G?"startContainer":"endContainer"],F=B[G?"startOffset":"endOffset"],z=[],C,E,D=0;if(A.nodeType==3){if(r){for(C=A.previousSibling;C&&C.nodeType==3;C=C.previousSibling){F+=C.nodeValue.length}}z.push(F)}else{E=A.childNodes;if(F>=E.length&&E.length){D=1;F=Math.max(0,E.length-1)}z.push(u.dom.nodeIndex(E[F],r)+D)}for(;A&&A!=t;A=A.parentNode){z.push(u.dom.nodeIndex(A,r))}return z}x.start=y(v,true);if(!u.isCollapsed()){x.end=y(v)}return x}return k()}if(q){return{rng:u.getRng()}}g=u.getRng();i=m.uniqueId();n=tinyMCE.activeEditor.selection.isCollapsed();s="overflow:hidden;line-height:0px";if(g.duplicate||g.item){if(!g.item){j=g.duplicate();g.collapse();g.pasteHTML(''+l+"");if(!n){j.collapse(false);j.pasteHTML(''+l+"")}}else{o=g.item(0);h=o.nodeName;return{name:h,index:f(h,o)}}}else{o=u.getNode();h=o.nodeName;if(h=="IMG"){return{name:h,index:f(h,o)}}j=g.cloneRange();if(!n){j.collapse(false);j.insertNode(m.create("span",{_mce_type:"bookmark",id:i+"_end",style:s},l))}g.collapse(true);g.insertNode(m.create("span",{_mce_type:"bookmark",id:i+"_start",style:s},l))}u.moveToBookmark({id:i,keep:1});return{id:i}},moveToBookmark:function(n){var r=this,l=r.dom,i,h,f,q,j,s,o,p;if(r.tridentSel){r.tridentSel.destroy()}if(n){if(n.start){f=l.createRng();q=l.getRoot();function g(z){var t=n[z?"start":"end"],v,x,y,u;if(t){for(x=q,v=t.length-1;v>=1;v--){u=x.childNodes;if(u.length){x=u[t[v]]}}if(z){f.setStart(x,t[0])}else{f.setEnd(x,t[0])}}}g(true);g();r.setRng(f)}else{if(n.id){function k(A){var u=l.get(n.id+"_"+A),z,t,x,y,v=n.keep;if(u){z=u.parentNode;if(A=="start"){if(!v){t=l.nodeIndex(u)}else{z=u.firstChild;t=1}j=s=z;o=p=t}else{if(!v){t=l.nodeIndex(u)}else{z=u.firstChild;t=1}s=z;p=t}if(!v){y=u.previousSibling;x=u.nextSibling;d(c.grep(u.childNodes),function(B){if(B.nodeType==3){B.nodeValue=B.nodeValue.replace(/\uFEFF/g,"")}});while(u=l.get(n.id+"_"+A)){l.remove(u,1)}if(y&&x&&y.nodeType==x.nodeType&&y.nodeType==3&&!c.isOpera){t=y.nodeValue.length;y.appendData(x.nodeValue);l.remove(x);if(A=="start"){j=s=y;o=p=t}else{s=y;p=t}}}}}function m(t){if(!a&&l.isBlock(t)&&!t.innerHTML){t.innerHTML='
    '}return t}k("start");k("end");if(j){f=l.createRng();f.setStart(m(j),o);f.setEnd(m(s),p);r.setRng(f)}}else{if(n.name){r.select(l.select(n.name)[n.index])}else{if(n.rng){r.setRng(n.rng)}}}}}},select:function(k,j){var i=this,l=i.dom,g=l.createRng(),f;f=l.nodeIndex(k);g.setStart(k.parentNode,f);g.setEnd(k.parentNode,f+1);if(j){function h(m,o){var n=new c.dom.TreeWalker(m,m);do{if(m.nodeType==3&&c.trim(m.nodeValue).length!=0){if(o){g.setStart(m,0)}else{g.setEnd(m,m.nodeValue.length)}return}if(m.nodeName=="BR"){if(o){g.setStartBefore(m)}else{g.setEndBefore(m)}return}}while(m=(o?n.next():n.prev()))}h(k,1);h(k)}i.setRng(g);return k},isCollapsed:function(){var f=this,h=f.getRng(),g=f.getSel();if(!h||h.item){return false}if(h.compareEndPoints){return h.compareEndPoints("StartToEnd",h)===0}return !g||h.collapsed},collapse:function(f){var g=this,h=g.getRng(),i;if(h.item){i=h.item(0);h=this.win.document.body.createTextRange();h.moveToElementText(i)}h.collapse(!!f);g.setRng(h)},getSel:function(){var g=this,f=this.win;return f.getSelection?f.getSelection():f.document.selection},getRng:function(l){var g=this,h,i,k,j=g.win.document;if(l&&g.tridentSel){return g.tridentSel.getRangeAt(0)}try{if(h=g.getSel()){i=h.rangeCount>0?h.getRangeAt(0):(h.createRange?h.createRange():j.createRange())}}catch(f){}if(c.isIE&&i.setStart&&j.selection.createRange().item){k=j.selection.createRange().item(0);i=j.createRange();i.setStartBefore(k);i.setEndAfter(k)}if(!i){i=j.createRange?j.createRange():j.body.createTextRange()}if(g.selectedRange&&g.explicitRange){if(i.compareBoundaryPoints(i.START_TO_START,g.selectedRange)===0&&i.compareBoundaryPoints(i.END_TO_END,g.selectedRange)===0){i=g.explicitRange}else{g.selectedRange=null;g.explicitRange=null}}return i},setRng:function(i){var h,g=this;if(!g.tridentSel){h=g.getSel();if(h){g.explicitRange=i;h.removeAllRanges();h.addRange(i);g.selectedRange=h.getRangeAt(0)}}else{if(i.cloneRange){g.tridentSel.addRange(i);return}try{i.select()}catch(f){}}},setNode:function(g){var f=this;f.setContent(f.dom.getOuterHTML(g));return g},getNode:function(){var g=this,f=g.getRng(),h=g.getSel(),i;if(f.setStart){if(!f){return g.dom.getRoot()}i=f.commonAncestorContainer;if(!f.collapsed){if(f.startContainer==f.endContainer){if(f.startOffset-f.endOffset<2){if(f.startContainer.hasChildNodes()){i=f.startContainer.childNodes[f.startOffset]}}}if(c.isWebKit&&h.anchorNode&&h.anchorNode.nodeType==1){return h.anchorNode.childNodes[h.anchorOffset]}}if(i&&i.nodeType==3){return i.parentNode}return i}return f.item?f.item(0):f.parentElement()},getSelectedBlocks:function(g,f){var i=this,j=i.dom,m,h,l,k=[];m=j.getParent(g||i.getStart(),j.isBlock);h=j.getParent(f||i.getEnd(),j.isBlock);if(m){k.push(m)}if(m&&h&&m!=h){l=m;while((l=l.nextSibling)&&l!=h){if(j.isBlock(l)){k.push(l)}}}if(h&&m!=h){k.push(h)}return k},destroy:function(g){var f=this;f.win=null;if(f.tridentSel){f.tridentSel.destroy()}if(!g){c.removeUnload(f.destroy)}},_fixIESelection:function(){var m=this.dom,l=m.doc,g=l.body,i,j;l.documentElement.unselectable=true;function k(n,q){var o=g.createTextRange();try{o.moveToPoint(n,q)}catch(p){o=null}return o}function h(o){var n;if(o.button){n=k(o.x,o.y);if(n){if(n.compareEndPoints("StartToStart",j)>0){n.setEndPoint("StartToStart",j)}else{n.setEndPoint("EndToEnd",j)}n.select()}}else{f()}}function f(){m.unbind(l,"mouseup",f);m.unbind(l,"mousemove",h);i=0}m.bind(l,"mousedown",function(n){if(n.target.nodeName==="HTML"){if(i){f()}i=1;j=k(n.x,n.y);if(j){m.bind(l,"mouseup",f);m.bind(l,"mousemove",h);m.win.focus();j.select()}}})}})})(tinymce);(function(a){a.create("tinymce.dom.XMLWriter",{node:null,XMLWriter:function(c){function b(){var e=document.implementation;if(!e||!e.createDocument){try{return new ActiveXObject("MSXML2.DOMDocument")}catch(d){}try{return new ActiveXObject("Microsoft.XmlDom")}catch(d){}}else{return e.createDocument("","",null)}}this.doc=b();this.valid=a.isOpera||a.isWebKit;this.reset()},reset:function(){var b=this,c=b.doc;if(c.firstChild){c.removeChild(c.firstChild)}b.node=c.appendChild(c.createElement("html"))},writeStartElement:function(c){var b=this;b.node=b.node.appendChild(b.doc.createElement(c))},writeAttribute:function(c,b){if(this.valid){b=b.replace(/>/g,"%MCGT%")}this.node.setAttribute(c,b)},writeEndElement:function(){this.node=this.node.parentNode},writeFullEndElement:function(){var b=this,c=b.node;c.appendChild(b.doc.createTextNode(""));b.node=c.parentNode},writeText:function(b){if(this.valid){b=b.replace(/>/g,"%MCGT%")}this.node.appendChild(this.doc.createTextNode(b))},writeCDATA:function(b){this.node.appendChild(this.doc.createCDATASection(b))},writeComment:function(b){if(a.isIE){b=b.replace(/^\-|\-$/g," ")}this.node.appendChild(this.doc.createComment(b.replace(/\-\-/g," ")))},getContent:function(){var b;b=this.doc.xml||new XMLSerializer().serializeToString(this.doc);b=b.replace(/<\?[^?]+\?>|]*>|<\/html>||]+>/g,"");b=b.replace(/ ?\/>/g," />");if(this.valid){b=b.replace(/\%MCGT%/g,">")}return b}})})(tinymce);(function(c){var d=/[&\"<>]/g,b=/[<>&]/g,a={"&":"&",'"':""","<":"<",">":">"};c.create("tinymce.dom.StringWriter",{str:null,tags:null,count:0,settings:null,indent:null,StringWriter:function(e){this.settings=c.extend({indent_char:" ",indentation:0},e);this.reset()},reset:function(){this.indent="";this.str="";this.tags=[];this.count=0},writeStartElement:function(e){this._writeAttributesEnd();this.writeRaw("<"+e);this.tags.push(e);this.inAttr=true;this.count++;this.elementCount=this.count;this.attrs={}},writeAttribute:function(g,e){var f=this;if(!f.attrs[g]){f.writeRaw(" "+f.encode(g,true)+'="'+f.encode(e,true)+'"');f.attrs[g]=e}},writeEndElement:function(){var e;if(this.tags.length>0){e=this.tags.pop();if(this._writeAttributesEnd(1)){this.writeRaw("")}if(this.settings.indentation>0){this.writeRaw("\n")}}},writeFullEndElement:function(){if(this.tags.length>0){this._writeAttributesEnd();this.writeRaw("");if(this.settings.indentation>0){this.writeRaw("\n")}}},writeText:function(e){this._writeAttributesEnd();this.writeRaw(this.encode(e));this.count++},writeCDATA:function(e){this._writeAttributesEnd();this.writeRaw("");this.count++},writeComment:function(e){this._writeAttributesEnd();this.writeRaw("");this.count++},writeRaw:function(e){this.str+=e},encode:function(f,e){return f.replace(e?d:b,function(g){return a[g]})},getContent:function(){return this.str},_writeAttributesEnd:function(e){if(!this.inAttr){return}this.inAttr=false;if(e&&this.elementCount==this.count){this.writeRaw(" />");return false}this.writeRaw(">");return true}})})(tinymce);(function(e){var g=e.extend,f=e.each,b=e.util.Dispatcher,d=e.isIE,a=e.isGecko;function c(h){return h.replace(/([?+*])/g,".$1")}e.create("tinymce.dom.Serializer",{Serializer:function(j){var i=this;i.key=0;i.onPreProcess=new b(i);i.onPostProcess=new b(i);try{i.writer=new e.dom.XMLWriter()}catch(h){i.writer=new e.dom.StringWriter()}if(e.isIE&&document.documentMode>8){i.writer=new e.dom.StringWriter()}i.settings=j=g({dom:e.DOM,valid_nodes:0,node_filter:0,attr_filter:0,invalid_attrs:/^(_mce_|_moz_|sizset|sizcache)/,closed:/^(br|hr|input|meta|img|link|param|area)$/,entity_encoding:"named",entities:"160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro",valid_elements:"*[*]",extended_valid_elements:0,invalid_elements:0,fix_table_elements:1,fix_list_elements:true,fix_content_duplication:true,convert_fonts_to_spans:false,font_size_classes:0,apply_source_formatting:0,indent_mode:"simple",indent_char:"\t",indent_levels:1,remove_linebreaks:1,remove_redundant_brs:1,element_format:"xhtml"},j);i.dom=j.dom;i.schema=j.schema;if(j.entity_encoding=="named"&&!j.entities){j.entity_encoding="raw"}if(j.remove_redundant_brs){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/(
    \s*)+<\/(p|h[1-6]|div|li)>/gi,function(n,m,o){if(/^
    \s*<\//.test(n)){return""}return n})})}if(j.element_format=="html"){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/<([^>]+) \/>/g,"<$1>")})}if(j.fix_list_elements){i.onPreProcess.add(function(v,s){var l,z,y=["ol","ul"],u,t,q,k=/^(OL|UL)$/,A;function m(r,x){var o=x.split(","),p;while((r=r.previousSibling)!=null){for(p=0;p1){f(q[1].split("|"),function(u){var p={},t;k=k||[];u=u.replace(/::/g,"~");u=/^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(u);u[2]=u[2].replace(/~/g,":");if(u[1]=="!"){r=r||[];r.push(u[2])}if(u[1]=="-"){for(t=0;t]*>)(.*?)(<\/script>)/g},{pattern:/(]*>)(.*?)(<\/noscript>)/g},{pattern:/(]*>)(.*?)(<\/style>)/g},{pattern:/(]*>)(.*?)(<\/pre>)/g,encode:1},{pattern:/()/g}]});j=l.content;if(k.entity_encoding!=="raw"){j=i._encode(j)}if(!n.set){j=e._replace(/

    \s+<\/p>|]+)>\s+<\/p>/g,k.entity_encoding=="numeric"?" 

    ":" 

    ",j);if(k.remove_linebreaks){j=j.replace(/\r?\n|\r/g," ");j=e._replace(/(<[^>]+>)\s+/g,"$1 ",j);j=e._replace(/\s+(<\/[^>]+>)/g," $1",j);j=e._replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g,"<$1 $2>",j);j=e._replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g,"<$1>",j);j=e._replace(/\s+<\/(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g,"",j)}if(k.apply_source_formatting&&k.indent_mode=="simple"){j=e._replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g,"\n<$1$2$3>\n",j);j=e._replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g,"\n<$1$2>",j);j=e._replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g,"\n",j);j=j.replace(/\n\n/g,"\n")}}j=i._unprotect(j,l);j=e._replace(//g,"",j);if(k.entity_encoding=="raw"){j=e._replace(/

     <\/p>|]+)> <\/p>/g,"\u00a0

    ",j)}j=j.replace(/]+|)>([\s\S]*?)<\/noscript>/g,function(h,p,o){return""+i.dom.decode(o.replace(//g,""))+""})}n.content=j},_serializeNode:function(E,J){var A=this,B=A.settings,y=A.writer,q,j,u,G,F,I,C,h,z,k,r,D,p,m,H,o,x;if(!B.node_filter||B.node_filter(E)){switch(E.nodeType){case 1:if(E.hasAttribute?E.hasAttribute("_mce_bogus"):E.getAttribute("_mce_bogus")){return}p=H=false;q=E.hasChildNodes();k=E.getAttribute("_mce_name")||E.nodeName.toLowerCase();o=E.getAttribute("_mce_type");if(o){if(!A._info.cleanup){p=true;return}else{H=1}}if(d){x=E.scopeName;if(x&&x!=="HTML"&&x!=="html"){k=x+":"+k}}if(k.indexOf("mce:")===0){k=k.substring(4)}if(!H){if(!A.validElementsRE||!A.validElementsRE.test(k)||(A.invalidElementsRE&&A.invalidElementsRE.test(k))||J){p=true;break}}if(d){if(B.fix_content_duplication){if(E._mce_serialized==A.key){return}E._mce_serialized=A.key}if(k.charAt(0)=="/"){k=k.substring(1)}}else{if(a){if(E.nodeName==="BR"&&E.getAttribute("type")=="_moz"){return}}}if(B.validate_children){if(A.elementName&&!A.schema.isValid(A.elementName,k)){p=true;break}A.elementName=k}r=A.findRule(k);if(!r){p=true;break}k=r.name||k;m=B.closed.test(k);if((!q&&r.noEmpty)||(d&&!k)){p=true;break}if(r.requiredAttribs){I=r.requiredAttribs;for(G=I.length-1;G>=0;G--){if(this.dom.getAttrib(E,I[G])!==""){break}}if(G==-1){p=true;break}}y.writeStartElement(k);if(r.attribs){for(G=0,C=r.attribs,F=C.length;G-1;G--){h=C[G];if(h.specified){I=h.nodeName.toLowerCase();if(B.invalid_attrs.test(I)||!r.validAttribsRE.test(I)){continue}D=A.findAttribRule(r,I);z=A._getAttrib(E,D,I);if(z!==null){y.writeAttribute(I,z)}}}}if(o&&H){y.writeAttribute("_mce_type",o)}if(k==="script"&&e.trim(E.innerHTML)){y.writeText("// ");y.writeCDATA(E.innerHTML.replace(/|<\[CDATA\[|\]\]>/g,""));q=false;break}if(r.padd){if(q&&(u=E.firstChild)&&u.nodeType===1&&E.childNodes.length===1){if(u.hasAttribute?u.hasAttribute("_mce_bogus"):u.getAttribute("_mce_bogus")){y.writeText("\u00a0")}}else{if(!q){y.writeText("\u00a0")}}}break;case 3:if(B.validate_children&&A.elementName&&!A.schema.isValid(A.elementName,"#text")){return}return y.writeText(E.nodeValue);case 4:return y.writeCDATA(E.nodeValue);case 8:return y.writeComment(E.nodeValue)}}else{if(E.nodeType==1){q=E.hasChildNodes()}}if(q&&!m){u=E.firstChild;while(u){A._serializeNode(u);A.elementName=k;u=u.nextSibling}}if(!p){if(!m){y.writeFullEndElement()}else{y.writeEndElement()}}},_protect:function(j){var i=this;j.items=j.items||[];function h(l){return l.replace(/[\r\n\\]/g,function(m){if(m==="\n"){return"\\n"}else{if(m==="\\"){return"\\\\"}}return"\\r"})}function k(l){return l.replace(/\\[\\rn]/g,function(m){if(m==="\\n"){return"\n"}else{if(m==="\\\\"){return"\\"}}return"\r"})}f(j.patterns,function(l){j.content=k(h(j.content).replace(l.pattern,function(n,o,m,p){m=k(m);if(l.encode){m=i._encode(m)}j.items.push(m);return o+""+p}))});return j},_unprotect:function(i,j){i=i.replace(/\"))}if(a&&j.ListBox){if(a.Button||a.SplitButton){e+=b.createHTML("td",{"class":"mceToolbarEnd"},b.createHTML("span",null,""))}}if(b.stdMode){e+=''+j.renderHTML()+""}else{e+=""+j.renderHTML()+""}if(f&&j.ListBox){if(f.Button||f.SplitButton){e+=b.createHTML("td",{"class":"mceToolbarStart"},b.createHTML("span",null,""))}}}g="mceToolbarEnd";if(j.Button){g+=" mceToolbarEndButton"}else{if(j.SplitButton){g+=" mceToolbarEndSplitButton"}else{if(j.ListBox){g+=" mceToolbarEndListBox"}}}e+=b.createHTML("td",{"class":g},b.createHTML("span",null,""));return b.createHTML("table",{id:l.id,"class":"mceToolbar"+(m["class"]?" "+m["class"]:""),cellpadding:"0",cellspacing:"0",align:l.settings.align||""},""+e+"")}});(function(b){var a=b.util.Dispatcher,c=b.each;b.create("tinymce.AddOnManager",{AddOnManager:function(){var d=this;d.items=[];d.urls={};d.lookup={};d.onAdd=new a(d)},get:function(d){return this.lookup[d]},requireLangPack:function(e){var d=b.settings;if(d&&d.language){b.ScriptLoader.add(this.urls[e]+"/langs/"+d.language+".js")}},add:function(e,d){this.items.push(d);this.lookup[e]=d;this.onAdd.dispatch(this,e,d);return d},load:function(h,e,d,g){var f=this;if(f.urls[h]){return}if(e.indexOf("/")!=0&&e.indexOf("://")==-1){e=b.baseURL+"/"+e}f.urls[h]=e.substring(0,e.lastIndexOf("/"));if(!f.lookup[h]){b.ScriptLoader.add(e,d,g)}}});b.PluginManager=new b.AddOnManager();b.ThemeManager=new b.AddOnManager()}(tinymce));(function(j){var g=j.each,d=j.extend,k=j.DOM,i=j.dom.Event,f=j.ThemeManager,b=j.PluginManager,e=j.explode,h=j.util.Dispatcher,a,c=0;j.documentBaseURL=window.location.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,"");if(!/[\/\\]$/.test(j.documentBaseURL)){j.documentBaseURL+="/"}j.baseURL=new j.util.URI(j.documentBaseURL).toAbsolute(j.baseURL);j.baseURI=new j.util.URI(j.baseURL);j.onBeforeUnload=new h(j);i.add(window,"beforeunload",function(l){j.onBeforeUnload.dispatch(j,l)});j.onAddEditor=new h(j);j.onRemoveEditor=new h(j);j.EditorManager=d(j,{editors:[],i18n:{},activeEditor:null,init:function(q){var n=this,p,l=j.ScriptLoader,u,o=[],m;function r(x,y,t){var v=x[y];if(!v){return}if(j.is(v,"string")){t=v.replace(/\.\w+$/,"");t=t?j.resolve(t):0;v=j.resolve(v)}return v.apply(t||this,Array.prototype.slice.call(arguments,2))}q=d({theme:"simple",language:"en"},q);n.settings=q;i.add(document,"init",function(){var s,v;r(q,"onpageload");switch(q.mode){case"exact":s=q.elements||"";if(s.length>0){g(e(s),function(x){if(k.get(x)){m=new j.Editor(x,q);o.push(m);m.render(1)}else{g(document.forms,function(y){g(y.elements,function(z){if(z.name===x){x="mce_editor_"+c++;k.setAttrib(z,"id",x);m=new j.Editor(x,q);o.push(m);m.render(1)}})})}})}break;case"textareas":case"specific_textareas":function t(y,x){return x.constructor===RegExp?x.test(y.className):k.hasClass(y,x)}g(k.select("textarea"),function(x){if(q.editor_deselector&&t(x,q.editor_deselector)){return}if(!q.editor_selector||t(x,q.editor_selector)){u=k.get(x.name);if(!x.id&&!u){x.id=x.name}if(!x.id||n.get(x.id)){x.id=k.uniqueId()}m=new j.Editor(x.id,q);o.push(m);m.render(1)}});break}if(q.oninit){s=v=0;g(o,function(x){v++;if(!x.initialized){x.onInit.add(function(){s++;if(s==v){r(q,"oninit")}})}else{s++}if(s==v){r(q,"oninit")}})}})},get:function(l){if(l===a){return this.editors}return this.editors[l]},getInstanceById:function(l){return this.get(l)},add:function(m){var l=this,n=l.editors;n[m.id]=m;n.push(m);l._setActive(m);l.onAddEditor.dispatch(l,m);return m},remove:function(n){var m=this,l,o=m.editors;if(!o[n.id]){return null}delete o[n.id];for(l=0;l':"",visual_table_class:"mceItemTable",visual:1,font_size_style_values:"xx-small,x-small,small,medium,large,x-large,xx-large",apply_source_formatting:1,directionality:"ltr",forced_root_block:"p",valid_elements:"@[id|class|style|title|dir';if(F.document_base_url!=m.documentBaseURL){E.iframeHTML+=''}E.iframeHTML+='';if(m.relaxedDomain){E.iframeHTML+=' + + + + + + + + + + + +
      +
    • +
    • +
    • +
    • +
    + +
    + +
    +

    +

    Rich editing, also called WYSIWYG for What You See Is What You Get, means your text is formatted as you type. The rich editor creates HTML code behind the scenes while you concentrate on writing. Font styles, links and images all appear approximately as they will on the internet.') ?>

    +

    +

    +

    +
    + + + + + + +
    + +
    +
    + +
    +
    + + + diff --git a/src/wp-includes/js/tinymce/wp-tinymce.js.gz b/src/wp-includes/js/tinymce/wp-tinymce.js.gz new file mode 100644 index 00000000..b818471d Binary files /dev/null and b/src/wp-includes/js/tinymce/wp-tinymce.js.gz differ diff --git a/src/wp-includes/js/tinymce/wp-tinymce.php b/src/wp-includes/js/tinymce/wp-tinymce.php new file mode 100644 index 00000000..02be3f20 --- /dev/null +++ b/src/wp-includes/js/tinymce/wp-tinymce.php @@ -0,0 +1,37 @@ +' + anError.message + '

    '; + response.errors.push( anError ); + parsed.errors = true; + } ).size() ) { response.errors = false; } + parsed.responses.push( response ); + } ); + if ( err.length ) { re.html( '
    ' + err + '
    ' ); } + return parsed; + } + if ( isNaN(x) ) { return !re.html('

    ' + x + '

    '); } + x = parseInt(x,10); + if ( -1 == x ) { return !re.html('

    ' + wpAjax.noPerm + '

    '); } + else if ( 0 === x ) { return !re.html('

    ' + wpAjax.broken + '

    '); } + return true; + }, + invalidateForm: function ( selector ) { + return jQuery( selector ).addClass( 'form-invalid' ).find('input:visible').change( function() { jQuery(this).closest('.form-invalid').removeClass( 'form-invalid' ); } ); + }, + validateForm: function( selector ) { + selector = jQuery( selector ); + return !wpAjax.invalidateForm( selector.find('.form-required').filter( function() { return jQuery('input:visible', this).val() == ''; } ) ).size(); + } +}, wpAjax || { noPerm: 'You do not have permission to do that.', broken: 'An unidentified error has occurred.' } ); + +// Basic form validation +jQuery(document).ready( function($){ + $('form.validate').submit( function() { return wpAjax.validateForm( $(this) ); } ); +}); diff --git a/src/wp-includes/js/wp-ajax-response.js b/src/wp-includes/js/wp-ajax-response.js new file mode 100644 index 00000000..bdfa53ab --- /dev/null +++ b/src/wp-includes/js/wp-ajax-response.js @@ -0,0 +1 @@ +var wpAjax=jQuery.extend({unserialize:function(c){var d={},e,a,b,f;if(!c){return d}e=c.split("?");if(e[1]){c=e[1]}a=c.split("&");for(b in a){if(jQuery.isFunction(a.hasOwnProperty)&&!a.hasOwnProperty(b)){continue}f=a[b].split("=");d[f[0]]=f[1]}return d},parseAjaxResponse:function(a,f,g){var b={},c=jQuery("#"+f).html(""),d="";if(a&&typeof a=="object"&&a.getElementsByTagName("wp_ajax")){b.responses=[];b.errors=false;jQuery("response",a).each(function(){var h=jQuery(this),i=jQuery(this.firstChild),e;e={action:h.attr("action"),what:i.get(0).nodeName,id:i.attr("id"),oldId:i.attr("old_id"),position:i.attr("position")};e.data=jQuery("response_data",i).text();e.supplemental={};if(!jQuery("supplemental",i).children().each(function(){e.supplemental[this.nodeName]=jQuery(this).text()}).size()){e.supplemental=false}e.errors=[];if(!jQuery("wp_error",i).each(function(){var j=jQuery(this).attr("code"),m,l,k;m={code:j,message:this.firstChild.nodeValue,data:false};l=jQuery('wp_error_data[code="'+j+'"]',a);if(l){m.data=l.get()}k=jQuery("form-field",l).text();if(k){j=k}if(g){wpAjax.invalidateForm(jQuery("#"+g+' :input[name="'+j+'"]').parents(".form-field:first"))}d+="

    "+m.message+"

    ";e.errors.push(m);b.errors=true}).size()){e.errors=false}b.responses.push(e)});if(d.length){c.html('
    '+d+"
    ")}return b}if(isNaN(a)){return !c.html('

    '+a+"

    ")}a=parseInt(a,10);if(-1==a){return !c.html('

    '+wpAjax.noPerm+"

    ")}else{if(0===a){return !c.html('

    '+wpAjax.broken+"

    ")}}return true},invalidateForm:function(a){return jQuery(a).addClass("form-invalid").find("input:visible").change(function(){jQuery(this).closest(".form-invalid").removeClass("form-invalid")})},validateForm:function(a){a=jQuery(a);return !wpAjax.invalidateForm(a.find(".form-required").filter(function(){return jQuery("input:visible",this).val()==""})).size()}},wpAjax||{noPerm:"You do not have permission to do that.",broken:"An unidentified error has occurred."});jQuery(document).ready(function(a){a("form.validate").submit(function(){return wpAjax.validateForm(a(this))})}); \ No newline at end of file diff --git a/src/wp-includes/js/wp-list-revisions.dev.js b/src/wp-includes/js/wp-list-revisions.dev.js new file mode 100644 index 00000000..9c702c65 --- /dev/null +++ b/src/wp-includes/js/wp-list-revisions.dev.js @@ -0,0 +1,24 @@ +(function(w) { + var init = function() { + var pr = document.getElementById('post-revisions'), + inputs = pr ? pr.getElementsByTagName('input') : []; + pr.onclick = function() { + var i, checkCount = 0, side; + for ( i = 0; i < inputs.length; i++ ) { + checkCount += inputs[i].checked ? 1 : 0; + side = inputs[i].getAttribute('name'); + if ( ! inputs[i].checked && + ( 'left' == side && 1 > checkCount || 'right' == side && 1 < checkCount && ( ! inputs[i-1] || ! inputs[i-1].checked ) ) && + ! ( inputs[i+1] && inputs[i+1].checked && 'right' == inputs[i+1].getAttribute('name') ) ) + inputs[i].style.visibility = 'hidden'; + else if ( 'left' == side || 'right' == side ) + inputs[i].style.visibility = 'visible'; + } + } + pr.onclick(); + } + if ( w && w.addEventListener ) + w.addEventListener('load', init, false); + else if ( w && w.attachEvent ) + w.attachEvent('onload', init); +})(window); diff --git a/src/wp-includes/js/wp-list-revisions.js b/src/wp-includes/js/wp-list-revisions.js new file mode 100644 index 00000000..417572db --- /dev/null +++ b/src/wp-includes/js/wp-list-revisions.js @@ -0,0 +1 @@ +(function(a){var b=function(){var d=document.getElementById("post-revisions"),c=d?d.getElementsByTagName("input"):[];d.onclick=function(){var g,f=0,e;for(g=0;gf||"right"==e&&1
    + * + * Or instead, you can do: + * + * timer_stop(1); + * + * which will do what the above does. If you need the result, you can assign it to a variable, but + * most cases, you only need to echo it. + * + * @since 0.71 + * @global int $timestart Seconds and Microseconds added together from when timer_start() is called + * @global int $timeend Seconds and Microseconds added together from when function is called + * + * @param int $display Use '0' or null to not echo anything and 1 to echo the total time + * @param int $precision The amount of digits from the right of the decimal to display. Default is 3. + * @return float The "second.microsecond" finished time calculation + */ +function timer_stop( $display = 0, $precision = 3 ) { // if called like timer_stop(1), will echo $timetotal + global $timestart, $timeend; + $mtime = microtime(); + $mtime = explode( ' ', $mtime ); + $timeend = $mtime[1] + $mtime[0]; + $timetotal = $timeend - $timestart; + $r = ( function_exists( 'number_format_i18n' ) ) ? number_format_i18n( $timetotal, $precision ) : number_format( $timetotal, $precision ); + if ( $display ) + echo $r; + return $r; +} + +/** + * Sets PHP error handling and handles WordPress debug mode. + * + * Uses three constants: WP_DEBUG, WP_DEBUG_DISPLAY, and WP_DEBUG_LOG. All three can be + * defined in wp-config.php. Example: define( 'WP_DEBUG', true ); + * + * WP_DEBUG_DISPLAY and WP_DEBUG_LOG perform no function unless WP_DEBUG is true. + * WP_DEBUG defaults to false. + * + * When WP_DEBUG is true, all PHP notices are reported. WordPress will also display + * notices, including one when a deprecated WordPress function, function argument, + * or file is used. Deprecated code may be removed from a later version. + * + * It is strongly recommended that plugin and theme developers use WP_DEBUG in their + * development environments. + * + * When WP_DEBUG_DISPLAY is true, WordPress will force errors to be displayed. + * WP_DEBUG_DISPLAY defaults to true. Defining it as false prevents WordPress from + * changing the global configuration setting. (Defining WP_DEBUG_DISPLAY as false + * will never force errors to be hidden.) + * + * When WP_DEBUG_LOG is true, errors will be logged to wp-content/debug.log. + * WP_DEBUG_LOG defaults to false. + * + * @access private + * @since 3.0.0 + */ +function wp_debug_mode() { + if ( WP_DEBUG ) { + // E_DEPRECATED is a core PHP constant in PHP 5.3. Don't define this yourself. + // The two statements are equivalent, just one is for 5.3+ and for less than 5.3. + if ( defined( 'E_DEPRECATED' ) ) + error_reporting( E_ALL & ~E_DEPRECATED & ~E_STRICT ); + else + error_reporting( E_ALL ); + + if ( WP_DEBUG_DISPLAY ) + ini_set( 'display_errors', 1 ); + + if ( WP_DEBUG_LOG ) { + ini_set( 'log_errors', 1 ); + ini_set( 'error_log', WP_CONTENT_DIR . '/debug.log' ); + } + } else { + if ( defined( 'E_RECOVERABLE_ERROR' ) ) + error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR ); + else + error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING ); + } +} + +/** + * Sets the location of the language directory. + * + * To set directory manually, define WP_LANG_DIR in wp-config.php. + * + * First looks for language folder in WP_CONTENT_DIR and uses that folder if it + * exists. Or it uses the "languages" folder in WPINC. + * + * The WP_LANG_DIR constant was introduced in 2.1.0. + * + * @access private + * @since 3.0.0 + */ +function wp_set_lang_dir() { + if ( !defined( 'WP_LANG_DIR' ) ) { + if ( file_exists( WP_CONTENT_DIR . '/languages' ) && @is_dir( WP_CONTENT_DIR . '/languages' ) ) { + define( 'WP_LANG_DIR', WP_CONTENT_DIR . '/languages' ); // no leading slash, no trailing slash, full path, not relative to ABSPATH + if ( !defined( 'LANGDIR' ) ) { + // Old static relative path maintained for limited backwards compatibility - won't work in some cases + define( 'LANGDIR', 'wp-content/languages' ); + } + } else { + define( 'WP_LANG_DIR', ABSPATH . WPINC . '/languages' ); // no leading slash, no trailing slash, full path, not relative to ABSPATH + if ( !defined( 'LANGDIR' ) ) { + // Old relative path maintained for backwards compatibility + define( 'LANGDIR', WPINC . '/languages' ); + } + } + } +} + +/** + * Load the correct database class file. + * + * This function is used to load the database class file either at runtime or by + * wp-admin/setup-config.php. We must globalize $wpdb to ensure that it is + * defined globally by the inline code in wp-db.php. + * + * @since 2.5.0 + * @global $wpdb WordPress Database Object + */ +function require_wp_db() { + global $wpdb; + + require_once( ABSPATH . WPINC . '/wp-db.php' ); + if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) + require_once( WP_CONTENT_DIR . '/db.php' ); + + if ( isset( $wpdb ) ) + return; + + $wpdb = new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST ); +} + +/** + * Sets the database table prefix and the format specifiers for database table columns. + * + * Columns not listed here default to %s. + * + * @see wpdb::$field_types Since 2.8.0 + * @see wpdb::prepare() + * @see wpdb::insert() + * @see wpdb::update() + * @see wpdb::set_prefix() + * + * @access private + * @since 3.0.0 + */ +function wp_set_wpdb_vars() { + global $wpdb, $table_prefix; + if ( !empty( $wpdb->error ) ) + dead_db(); + + $wpdb->field_types = array( 'post_author' => '%d', 'post_parent' => '%d', 'menu_order' => '%d', 'term_id' => '%d', 'term_group' => '%d', 'term_taxonomy_id' => '%d', + 'parent' => '%d', 'count' => '%d','object_id' => '%d', 'term_order' => '%d', 'ID' => '%d', 'commment_ID' => '%d', 'comment_post_ID' => '%d', 'comment_parent' => '%d', + 'user_id' => '%d', 'link_id' => '%d', 'link_owner' => '%d', 'link_rating' => '%d', 'option_id' => '%d', 'blog_id' => '%d', 'meta_id' => '%d', 'post_id' => '%d', + 'user_status' => '%d', 'umeta_id' => '%d', 'comment_karma' => '%d', 'comment_count' => '%d', + // multisite: + 'active' => '%d', 'cat_id' => '%d', 'deleted' => '%d', 'lang_id' => '%d', 'mature' => '%d', 'public' => '%d', 'site_id' => '%d', 'spam' => '%d', + ); + + $prefix = $wpdb->set_prefix( $table_prefix ); + + if ( is_wp_error( $prefix ) ) + wp_die( /*WP_I18N_BAD_PREFIX*/'ERROR: $table_prefix en wp-config.php sólo puede contener números, letras y guiones bajos.'/*/WP_I18N_BAD_PREFIX*/ ); +} + +/** + * Starts the WordPress object cache. + * + * If an object-cache.php file exists in the wp-content directory, + * it uses that drop-in as an external object cache. + * + * @access private + * @since 3.0.0 + */ +function wp_start_object_cache() { + global $_wp_using_ext_object_cache; + + $first_init = false; + if ( ! function_exists( 'wp_cache_init' ) ) { + if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) { + require_once ( WP_CONTENT_DIR . '/object-cache.php' ); + $_wp_using_ext_object_cache = true; + } else { + require_once ( ABSPATH . WPINC . '/cache.php' ); + $_wp_using_ext_object_cache = false; + } + $first_init = true; + } else if ( !$_wp_using_ext_object_cache && file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) { + // Sometimes advanced-cache.php can load object-cache.php before it is loaded here. + // This breaks the function_exists check above and can result in $_wp_using_ext_object_cache + // being set incorrectly. Double check if an external cache exists. + $_wp_using_ext_object_cache = true; + } + + // If cache supports reset, reset instead of init if already initialized. + // Reset signals to the cache that global IDs have changed and it may need to update keys + // and cleanup caches. + if ( !$first_init && function_exists('wp_cache_reset') ) + wp_cache_reset(); + else + wp_cache_init(); + + if ( function_exists( 'wp_cache_add_global_groups' ) ) { + wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) ); + wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) ); + } +} + +/** + * Redirects to the installer if WordPress is not installed. + * + * Dies with an error message when multisite is enabled. + * + * @access private + * @since 3.0.0 + */ +function wp_not_installed() { + if ( is_multisite() ) { + if ( ! is_blog_installed() && ! defined( 'WP_INSTALLING' ) ) + wp_die( __( 'The site you have requested is not installed properly. Please contact the system administrator.' ) ); + } elseif ( ! is_blog_installed() && false === strpos( $_SERVER['PHP_SELF'], 'install.php' ) && !defined( 'WP_INSTALLING' ) ) { + + $link = wp_guess_url() . '/wp-admin/install.php'; + + require( ABSPATH . WPINC . '/kses.php' ); + require( ABSPATH . WPINC . '/pluggable.php' ); + require( ABSPATH . WPINC . '/formatting.php' ); + wp_redirect( $link ); + die(); + } +} + +/** + * Returns array of must-use plugin files to be included in global scope. + * + * The default directory is wp-content/mu-plugins. To change the default directory + * manually, define WPMU_PLUGIN_DIR and WPMU_PLUGIN_URL + * in wp-config.php. + * + * @access private + * @since 3.0.0 + * @return array Files to include + */ +function wp_get_mu_plugins() { + $mu_plugins = array(); + if ( !is_dir( WPMU_PLUGIN_DIR ) ) + return $mu_plugins; + if ( ! $dh = opendir( WPMU_PLUGIN_DIR ) ) + return $mu_plugins; + while ( ( $plugin = readdir( $dh ) ) !== false ) { + if ( substr( $plugin, -4 ) == '.php' ) + $mu_plugins[] = WPMU_PLUGIN_DIR . '/' . $plugin; + } + closedir( $dh ); + sort( $mu_plugins ); + + return $mu_plugins; +} + +/** + * Returns array of plugin files to be included in global scope. + * + * The default directory is wp-content/plugins. To change the default directory + * manually, define WP_PLUGIN_DIR and WP_PLUGIN_URL + * in wp-config.php. + * + * @access private + * @since 3.0.0 + * @return array Files to include + */ +function wp_get_active_and_valid_plugins() { + $plugins = array(); + $active_plugins = (array) get_option( 'active_plugins', array() ); + + // Check for hacks file if the option is enabled + if ( get_option( 'hack_file' ) && file_exists( ABSPATH . 'my-hacks.php' ) ) { + _deprecated_file( 'my-hacks.php', '1.5' ); + array_unshift( $plugins, ABSPATH . 'my-hacks.php' ); + } + + if ( empty( $active_plugins ) || defined( 'WP_INSTALLING' ) ) + return $plugins; + + $network_plugins = is_multisite() ? wp_get_active_network_plugins() : false; + + foreach ( $active_plugins as $plugin ) { + if ( ! validate_file( $plugin ) // $plugin must validate as file + && '.php' == substr( $plugin, -4 ) // $plugin must end with '.php' + && file_exists( WP_PLUGIN_DIR . '/' . $plugin ) // $plugin must exist + // not already included as a network plugin + && ( ! $network_plugins || ! in_array( WP_PLUGIN_DIR . '/' . $plugin, $network_plugins ) ) + ) + $plugins[] = WP_PLUGIN_DIR . '/' . $plugin; + } + return $plugins; +} + +/** + * Sets internal encoding using mb_internal_encoding(). + * + * In most cases the default internal encoding is latin1, which is of no use, + * since we want to use the mb_ functions for utf-8 strings. + * + * @access private + * @since 3.0.0 + */ +function wp_set_internal_encoding() { + if ( function_exists( 'mb_internal_encoding' ) ) { + if ( !@mb_internal_encoding( get_option( 'blog_charset' ) ) ) + mb_internal_encoding( 'UTF-8' ); + } +} + +/** + * Add magic quotes to $_GET, $_POST, $_COOKIE, and $_SERVER. + * + * Also forces $_REQUEST to be $_GET + $_POST. If $_SERVER, $_COOKIE, + * or $_ENV are needed, use those superglobals directly. + * + * @access private + * @since 3.0.0 + */ +function wp_magic_quotes() { + // If already slashed, strip. + if ( get_magic_quotes_gpc() ) { + $_GET = stripslashes_deep( $_GET ); + $_POST = stripslashes_deep( $_POST ); + $_COOKIE = stripslashes_deep( $_COOKIE ); + } + + // Escape with wpdb. + $_GET = add_magic_quotes( $_GET ); + $_POST = add_magic_quotes( $_POST ); + $_COOKIE = add_magic_quotes( $_COOKIE ); + $_SERVER = add_magic_quotes( $_SERVER ); + + // Force REQUEST to be GET + POST. + $_REQUEST = array_merge( $_GET, $_POST ); +} + +/** + * Runs just before PHP shuts down execution. + * + * @access private + * @since 1.2.0 + */ +function shutdown_action_hook() { + do_action( 'shutdown' ); + wp_cache_close(); +} + +/** + * Copy an object. + * + * Returns a cloned copy of an object. + * + * @since 2.7.0 + * + * @param object $object The object to clone + * @return object The cloned object + */ +function wp_clone( $object ) { + static $can_clone; + if ( !isset( $can_clone ) ) + $can_clone = version_compare( phpversion(), '5.0', '>=' ); + + return $can_clone ? clone( $object ) : $object; +} + +/** + * Whether the current request is for a network or blog admin page + * + * Does not inform on whether the user is an admin! Use capability checks to + * tell if the user should be accessing a section or not. + * + * @since 1.5.1 + * + * @return bool True if inside WordPress administration pages. + */ +function is_admin() { + if ( defined( 'WP_ADMIN' ) ) + return WP_ADMIN; + return false; +} + +/** + * Whether the current request is for a blog admin screen /wp-admin/ + * + * Does not inform on whether the user is a blog admin! Use capability checks to + * tell if the user should be accessing a section or not. + * + * @since 3.1.0 + * + * @return bool True if inside WordPress network administration pages. + */ +function is_blog_admin() { + if ( defined( 'WP_BLOG_ADMIN' ) ) + return WP_BLOG_ADMIN; + return false; +} + +/** + * Whether the current request is for a network admin screen /wp-admin/network/ + * + * Does not inform on whether the user is a network admin! Use capability checks to + * tell if the user should be accessing a section or not. + * + * @since 3.1.0 + * + * @return bool True if inside WordPress network administration pages. + */ +function is_network_admin() { + if ( defined( 'WP_NETWORK_ADMIN' ) ) + return WP_NETWORK_ADMIN; + return false; +} + +/** + * Whether the current request is for a user admin screen /wp-admin/user/ + * + * Does not inform on whether the user is an admin! Use capability checks to + * tell if the user should be accessing a section or not. + * + * @since 3.1.0 + * + * @return bool True if inside WordPress user administration pages. + */ +function is_user_admin() { + if ( defined( 'WP_USER_ADMIN' ) ) + return WP_USER_ADMIN; + return false; +} + +/** + * Whether Multisite support is enabled + * + * @since 3.0.0 + * + * @return bool True if multisite is enabled, false otherwise. + */ +function is_multisite() { + if ( defined( 'MULTISITE' ) ) + return MULTISITE; + + if ( defined( 'SUBDOMAIN_INSTALL' ) || defined( 'VHOST' ) || defined( 'SUNRISE' ) ) + return true; + + return false; +} + +?> diff --git a/src/wp-includes/locale.php b/src/wp-includes/locale.php new file mode 100644 index 00000000..e69cbf5d --- /dev/null +++ b/src/wp-includes/locale.php @@ -0,0 +1,351 @@ +weekday[0] = /* translators: weekday */ __('Sunday'); + $this->weekday[1] = /* translators: weekday */ __('Monday'); + $this->weekday[2] = /* translators: weekday */ __('Tuesday'); + $this->weekday[3] = /* translators: weekday */ __('Wednesday'); + $this->weekday[4] = /* translators: weekday */ __('Thursday'); + $this->weekday[5] = /* translators: weekday */ __('Friday'); + $this->weekday[6] = /* translators: weekday */ __('Saturday'); + + // The first letter of each day. The _%day%_initial suffix is a hack to make + // sure the day initials are unique. + $this->weekday_initial[__('Sunday')] = /* translators: one-letter abbreviation of the weekday */ __('S_Sunday_initial'); + $this->weekday_initial[__('Monday')] = /* translators: one-letter abbreviation of the weekday */ __('M_Monday_initial'); + $this->weekday_initial[__('Tuesday')] = /* translators: one-letter abbreviation of the weekday */ __('T_Tuesday_initial'); + $this->weekday_initial[__('Wednesday')] = /* translators: one-letter abbreviation of the weekday */ __('W_Wednesday_initial'); + $this->weekday_initial[__('Thursday')] = /* translators: one-letter abbreviation of the weekday */ __('T_Thursday_initial'); + $this->weekday_initial[__('Friday')] = /* translators: one-letter abbreviation of the weekday */ __('F_Friday_initial'); + $this->weekday_initial[__('Saturday')] = /* translators: one-letter abbreviation of the weekday */ __('S_Saturday_initial'); + + foreach ($this->weekday_initial as $weekday_ => $weekday_initial_) { + $this->weekday_initial[$weekday_] = preg_replace('/_.+_initial$/', '', $weekday_initial_); + } + + // Abbreviations for each day. + $this->weekday_abbrev[__('Sunday')] = /* translators: three-letter abbreviation of the weekday */ __('Sun'); + $this->weekday_abbrev[__('Monday')] = /* translators: three-letter abbreviation of the weekday */ __('Mon'); + $this->weekday_abbrev[__('Tuesday')] = /* translators: three-letter abbreviation of the weekday */ __('Tue'); + $this->weekday_abbrev[__('Wednesday')] = /* translators: three-letter abbreviation of the weekday */ __('Wed'); + $this->weekday_abbrev[__('Thursday')] = /* translators: three-letter abbreviation of the weekday */ __('Thu'); + $this->weekday_abbrev[__('Friday')] = /* translators: three-letter abbreviation of the weekday */ __('Fri'); + $this->weekday_abbrev[__('Saturday')] = /* translators: three-letter abbreviation of the weekday */ __('Sat'); + + // The Months + $this->month['01'] = /* translators: month name */ __('January'); + $this->month['02'] = /* translators: month name */ __('February'); + $this->month['03'] = /* translators: month name */ __('March'); + $this->month['04'] = /* translators: month name */ __('April'); + $this->month['05'] = /* translators: month name */ __('May'); + $this->month['06'] = /* translators: month name */ __('June'); + $this->month['07'] = /* translators: month name */ __('July'); + $this->month['08'] = /* translators: month name */ __('August'); + $this->month['09'] = /* translators: month name */ __('September'); + $this->month['10'] = /* translators: month name */ __('October'); + $this->month['11'] = /* translators: month name */ __('November'); + $this->month['12'] = /* translators: month name */ __('December'); + + // Abbreviations for each month. Uses the same hack as above to get around the + // 'May' duplication. + $this->month_abbrev[__('January')] = /* translators: three-letter abbreviation of the month */ __('Jan_January_abbreviation'); + $this->month_abbrev[__('February')] = /* translators: three-letter abbreviation of the month */ __('Feb_February_abbreviation'); + $this->month_abbrev[__('March')] = /* translators: three-letter abbreviation of the month */ __('Mar_March_abbreviation'); + $this->month_abbrev[__('April')] = /* translators: three-letter abbreviation of the month */ __('Apr_April_abbreviation'); + $this->month_abbrev[__('May')] = /* translators: three-letter abbreviation of the month */ __('May_May_abbreviation'); + $this->month_abbrev[__('June')] = /* translators: three-letter abbreviation of the month */ __('Jun_June_abbreviation'); + $this->month_abbrev[__('July')] = /* translators: three-letter abbreviation of the month */ __('Jul_July_abbreviation'); + $this->month_abbrev[__('August')] = /* translators: three-letter abbreviation of the month */ __('Aug_August_abbreviation'); + $this->month_abbrev[__('September')] = /* translators: three-letter abbreviation of the month */ __('Sep_September_abbreviation'); + $this->month_abbrev[__('October')] = /* translators: three-letter abbreviation of the month */ __('Oct_October_abbreviation'); + $this->month_abbrev[__('November')] = /* translators: three-letter abbreviation of the month */ __('Nov_November_abbreviation'); + $this->month_abbrev[__('December')] = /* translators: three-letter abbreviation of the month */ __('Dec_December_abbreviation'); + + foreach ($this->month_abbrev as $month_ => $month_abbrev_) { + $this->month_abbrev[$month_] = preg_replace('/_.+_abbreviation$/', '', $month_abbrev_); + } + + // The Meridiems + $this->meridiem['am'] = __('am'); + $this->meridiem['pm'] = __('pm'); + $this->meridiem['AM'] = __('AM'); + $this->meridiem['PM'] = __('PM'); + + // Numbers formatting + // See http://php.net/number_format + + /* translators: $thousands_sep argument for http://php.net/number_format, default is , */ + $trans = __('number_format_thousands_sep'); + $this->number_format['thousands_sep'] = ('number_format_thousands_sep' == $trans) ? ',' : $trans; + + /* translators: $dec_point argument for http://php.net/number_format, default is . */ + $trans = __('number_format_decimal_point'); + $this->number_format['decimal_point'] = ('number_format_decimal_point' == $trans) ? '.' : $trans; + + // Import global locale vars set during inclusion of $locale.php. + foreach ( (array) $this->locale_vars as $var ) { + if ( isset($GLOBALS[$var]) ) + $this->$var = $GLOBALS[$var]; + } + + } + + /** + * Retrieve the full translated weekday word. + * + * Week starts on translated Sunday and can be fetched + * by using 0 (zero). So the week starts with 0 (zero) + * and ends on Saturday with is fetched by using 6 (six). + * + * @since 2.1.0 + * @access public + * + * @param int $weekday_number 0 for Sunday through 6 Saturday + * @return string Full translated weekday + */ + function get_weekday($weekday_number) { + return $this->weekday[$weekday_number]; + } + + /** + * Retrieve the translated weekday initial. + * + * The weekday initial is retrieved by the translated + * full weekday word. When translating the weekday initial + * pay attention to make sure that the starting letter does + * not conflict. + * + * @since 2.1.0 + * @access public + * + * @param string $weekday_name + * @return string + */ + function get_weekday_initial($weekday_name) { + return $this->weekday_initial[$weekday_name]; + } + + /** + * Retrieve the translated weekday abbreviation. + * + * The weekday abbreviation is retrieved by the translated + * full weekday word. + * + * @since 2.1.0 + * @access public + * + * @param string $weekday_name Full translated weekday word + * @return string Translated weekday abbreviation + */ + function get_weekday_abbrev($weekday_name) { + return $this->weekday_abbrev[$weekday_name]; + } + + /** + * Retrieve the full translated month by month number. + * + * The $month_number parameter has to be a string + * because it must have the '0' in front of any number + * that is less than 10. Starts from '01' and ends at + * '12'. + * + * You can use an integer instead and it will add the + * '0' before the numbers less than 10 for you. + * + * @since 2.1.0 + * @access public + * + * @param string|int $month_number '01' through '12' + * @return string Translated full month name + */ + function get_month($month_number) { + return $this->month[zeroise($month_number, 2)]; + } + + /** + * Retrieve translated version of month abbreviation string. + * + * The $month_name parameter is expected to be the translated or + * translatable version of the month. + * + * @since 2.1.0 + * @access public + * + * @param string $month_name Translated month to get abbreviated version + * @return string Translated abbreviated month + */ + function get_month_abbrev($month_name) { + return $this->month_abbrev[$month_name]; + } + + /** + * Retrieve translated version of meridiem string. + * + * The $meridiem parameter is expected to not be translated. + * + * @since 2.1.0 + * @access public + * + * @param string $meridiem Either 'am', 'pm', 'AM', or 'PM'. Not translated version. + * @return string Translated version + */ + function get_meridiem($meridiem) { + return $this->meridiem[$meridiem]; + } + + /** + * Global variables are deprecated. For backwards compatibility only. + * + * @deprecated For backwards compatibility only. + * @access private + * + * @since 2.1.0 + */ + function register_globals() { + $GLOBALS['weekday'] = $this->weekday; + $GLOBALS['weekday_initial'] = $this->weekday_initial; + $GLOBALS['weekday_abbrev'] = $this->weekday_abbrev; + $GLOBALS['month'] = $this->month; + $GLOBALS['month_abbrev'] = $this->month_abbrev; + } + + /** + * PHP4 style constructor which calls helper methods to set up object variables + * + * @uses WP_Locale::init() + * @uses WP_Locale::register_globals() + * @since 2.1.0 + * + * @return WP_Locale + */ + function WP_Locale() { + $this->init(); + $this->register_globals(); + } + /** + * Checks if current locale is RTL. + * + * @since 3.0.0 + * @return bool Whether locale is RTL. + */ + function is_rtl() { + return 'rtl' == $this->text_direction; + } +} + +/** + * Checks if current locale is RTL. + * + * @since 3.0.0 + * @return bool Whether locale is RTL. + */ +function is_rtl() { + global $wp_locale; + return $wp_locale->is_rtl(); +} + +?> diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php new file mode 100644 index 00000000..041c4e56 --- /dev/null +++ b/src/wp-includes/media.php @@ -0,0 +1,1408 @@ + 0 ) + $max_width = min( intval($content_width), $max_width ); + } elseif ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) { + $max_width = intval( $_wp_additional_image_sizes[$size]['width'] ); + $max_height = intval( $_wp_additional_image_sizes[$size]['height'] ); + if ( intval($content_width) > 0 && is_admin() ) // Only in admin. Assume that theme authors know what they're doing. + $max_width = min( intval($content_width), $max_width ); + } + // $size == 'full' has no constraint + else { + $max_width = $width; + $max_height = $height; + } + + list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size ); + + return wp_constrain_dimensions( $width, $height, $max_width, $max_height ); +} + +/** + * Retrieve width and height attributes using given width and height values. + * + * Both attributes are required in the sense that both parameters must have a + * value, but are optional in that if you set them to false or null, then they + * will not be added to the returned string. + * + * You can set the value using a string, but it will only take numeric values. + * If you wish to put 'px' after the numbers, then it will be stripped out of + * the return. + * + * @since 2.5.0 + * + * @param int|string $width Optional. Width attribute value. + * @param int|string $height Optional. Height attribute value. + * @return string HTML attributes for width and, or height. + */ +function image_hwstring($width, $height) { + $out = ''; + if ($width) + $out .= 'width="'.intval($width).'" '; + if ($height) + $out .= 'height="'.intval($height).'" '; + return $out; +} + +/** + * Scale an image to fit a particular size (such as 'thumb' or 'medium'). + * + * Array with image url, width, height, and whether is intermediate size, in + * that order is returned on success is returned. $is_intermediate is true if + * $url is a resized image, false if it is the original. + * + * The URL might be the original image, or it might be a resized version. This + * function won't create a new resized copy, it will just return an already + * resized one if it exists. + * + * A plugin may use the 'image_downsize' filter to hook into and offer image + * resizing services for images. The hook must return an array with the same + * elements that are returned in the function. The first element being the URL + * to the new image that was resized. + * + * @since 2.5.0 + * @uses apply_filters() Calls 'image_downsize' on $id and $size to provide + * resize services. + * + * @param int $id Attachment ID for image. + * @param string $size Optional, default is 'medium'. Size of image, can be 'thumbnail'. + * @return bool|array False on failure, array on success. + */ +function image_downsize($id, $size = 'medium') { + + if ( !wp_attachment_is_image($id) ) + return false; + + $img_url = wp_get_attachment_url($id); + $meta = wp_get_attachment_metadata($id); + $width = $height = 0; + $is_intermediate = false; + $img_url_basename = wp_basename($img_url); + + // plugins can use this to provide resize services + if ( $out = apply_filters('image_downsize', false, $id, $size) ) + return $out; + + // try for a new style intermediate size + if ( $intermediate = image_get_intermediate_size($id, $size) ) { + $img_url = str_replace($img_url_basename, $intermediate['file'], $img_url); + $width = $intermediate['width']; + $height = $intermediate['height']; + $is_intermediate = true; + } + elseif ( $size == 'thumbnail' ) { + // fall back to the old thumbnail + if ( ($thumb_file = wp_get_attachment_thumb_file($id)) && $info = getimagesize($thumb_file) ) { + $img_url = str_replace($img_url_basename, wp_basename($thumb_file), $img_url); + $width = $info[0]; + $height = $info[1]; + $is_intermediate = true; + } + } + if ( !$width && !$height && isset($meta['width'], $meta['height']) ) { + // any other type: use the real image + $width = $meta['width']; + $height = $meta['height']; + } + + if ( $img_url) { + // we have the actual image size, but might need to further constrain it if content_width is narrower + list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size ); + + return array( $img_url, $width, $height, $is_intermediate ); + } + return false; + +} + +/** + * Registers a new image size + */ +function add_image_size( $name, $width = 0, $height = 0, $crop = false ) { + global $_wp_additional_image_sizes; + $_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop ); +} + +/** + * Registers an image size for the post thumbnail + */ +function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) { + add_image_size( 'post-thumbnail', $width, $height, $crop ); +} + +/** + * An tag for an image attachment, scaling it down if requested. + * + * The filter 'get_image_tag_class' allows for changing the class name for the + * image without having to use regular expressions on the HTML content. The + * parameters are: what WordPress will use for the class, the Attachment ID, + * image align value, and the size the image should be. + * + * The second filter 'get_image_tag' has the HTML content, which can then be + * further manipulated by a plugin to change all attribute values and even HTML + * content. + * + * @since 2.5.0 + * + * @uses apply_filters() The 'get_image_tag_class' filter is the IMG element + * class attribute. + * @uses apply_filters() The 'get_image_tag' filter is the full IMG element with + * all attributes. + * + * @param int $id Attachment ID. + * @param string $alt Image Description for the alt attribute. + * @param string $title Image Description for the title attribute. + * @param string $align Part of the class name for aligning the image. + * @param string $size Optional. Default is 'medium'. + * @return string HTML IMG element for given image attachment + */ +function get_image_tag($id, $alt, $title, $align, $size='medium') { + + list( $img_src, $width, $height ) = image_downsize($id, $size); + $hwstring = image_hwstring($width, $height); + + $class = 'align' . esc_attr($align) .' size-' . esc_attr($size) . ' wp-image-' . $id; + $class = apply_filters('get_image_tag_class', $class, $id, $align, $size); + + $html = '' . esc_attr($alt) . ''; + + $html = apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size ); + + return $html; +} + +/** + * Load an image from a string, if PHP supports it. + * + * @since 2.1.0 + * + * @param string $file Filename of the image to load. + * @return resource The resulting image resource on success, Error string on failure. + */ +function wp_load_image( $file ) { + if ( is_numeric( $file ) ) + $file = get_attached_file( $file ); + + if ( ! file_exists( $file ) ) + return sprintf(__('File “%s” doesn’t exist?'), $file); + + if ( ! function_exists('imagecreatefromstring') ) + return __('The GD image library is not installed.'); + + // Set artificially high because GD uses uncompressed images in memory + @ini_set('memory_limit', '256M'); + $image = imagecreatefromstring( file_get_contents( $file ) ); + + if ( !is_resource( $image ) ) + return sprintf(__('File “%s” is not an image.'), $file); + + return $image; +} + +/** + * Calculates the new dimentions for a downsampled image. + * + * If either width or height are empty, no constraint is applied on + * that dimension. + * + * @since 2.5.0 + * + * @param int $current_width Current width of the image. + * @param int $current_height Current height of the image. + * @param int $max_width Optional. Maximum wanted width. + * @param int $max_height Optional. Maximum wanted height. + * @return array First item is the width, the second item is the height. + */ +function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) { + if ( !$max_width and !$max_height ) + return array( $current_width, $current_height ); + + $width_ratio = $height_ratio = 1.0; + $did_width = $did_height = false; + + if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) { + $width_ratio = $max_width / $current_width; + $did_width = true; + } + + if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) { + $height_ratio = $max_height / $current_height; + $did_height = true; + } + + // Calculate the larger/smaller ratios + $smaller_ratio = min( $width_ratio, $height_ratio ); + $larger_ratio = max( $width_ratio, $height_ratio ); + + if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height ) + // The larger ratio is too big. It would result in an overflow. + $ratio = $smaller_ratio; + else + // The larger ratio fits, and is likely to be a more "snug" fit. + $ratio = $larger_ratio; + + $w = intval( $current_width * $ratio ); + $h = intval( $current_height * $ratio ); + + // Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short + // We also have issues with recursive calls resulting in an ever-changing result. Contraining to the result of a constraint should yield the original result. + // Thus we look for dimensions that are one pixel shy of the max value and bump them up + if ( $did_width && $w == $max_width - 1 ) + $w = $max_width; // Round it up + if ( $did_height && $h == $max_height - 1 ) + $h = $max_height; // Round it up + + return array( $w, $h ); +} + +/** + * Retrieve calculated resized dimensions for use in imagecopyresampled(). + * + * Calculate dimensions and coordinates for a resized image that fits within a + * specified width and height. If $crop is true, the largest matching central + * portion of the image will be cropped out and resized to the required size. + * + * @since 2.5.0 + * + * @param int $orig_w Original width. + * @param int $orig_h Original height. + * @param int $dest_w New width. + * @param int $dest_h New height. + * @param bool $crop Optional, default is false. Whether to crop image or resize. + * @return bool|array False, on failure. Returned array matches parameters for imagecopyresampled() PHP function. + */ +function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) { + + if ($orig_w <= 0 || $orig_h <= 0) + return false; + // at least one of dest_w or dest_h must be specific + if ($dest_w <= 0 && $dest_h <= 0) + return false; + + if ( $crop ) { + // crop the largest possible portion of the original image that we can size to $dest_w x $dest_h + $aspect_ratio = $orig_w / $orig_h; + $new_w = min($dest_w, $orig_w); + $new_h = min($dest_h, $orig_h); + + if ( !$new_w ) { + $new_w = intval($new_h * $aspect_ratio); + } + + if ( !$new_h ) { + $new_h = intval($new_w / $aspect_ratio); + } + + $size_ratio = max($new_w / $orig_w, $new_h / $orig_h); + + $crop_w = round($new_w / $size_ratio); + $crop_h = round($new_h / $size_ratio); + + $s_x = floor( ($orig_w - $crop_w) / 2 ); + $s_y = floor( ($orig_h - $crop_h) / 2 ); + } else { + // don't crop, just resize using $dest_w x $dest_h as a maximum bounding box + $crop_w = $orig_w; + $crop_h = $orig_h; + + $s_x = 0; + $s_y = 0; + + list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h ); + } + + // if the resulting image would be the same size or larger we don't want to resize it + if ( $new_w >= $orig_w && $new_h >= $orig_h ) + return false; + + // the return array matches the parameters to imagecopyresampled() + // int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h + return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); + +} + +/** + * Scale down an image to fit a particular size and save a new copy of the image. + * + * The PNG transparency will be preserved using the function, as well as the + * image type. If the file going in is PNG, then the resized image is going to + * be PNG. The only supported image types are PNG, GIF, and JPEG. + * + * Some functionality requires API to exist, so some PHP version may lose out + * support. This is not the fault of WordPress (where functionality is + * downgraded, not actual defects), but of your PHP version. + * + * @since 2.5.0 + * + * @param string $file Image file path. + * @param int $max_w Maximum width to resize to. + * @param int $max_h Maximum height to resize to. + * @param bool $crop Optional. Whether to crop image or resize. + * @param string $suffix Optional. File Suffix. + * @param string $dest_path Optional. New image file path. + * @param int $jpeg_quality Optional, default is 90. Image quality percentage. + * @return mixed WP_Error on failure. String with new destination path. + */ +function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) { + + $image = wp_load_image( $file ); + if ( !is_resource( $image ) ) + return new WP_Error( 'error_loading_image', $image, $file ); + + $size = @getimagesize( $file ); + if ( !$size ) + return new WP_Error('invalid_image', __('Could not read image size'), $file); + list($orig_w, $orig_h, $orig_type) = $size; + + $dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop); + if ( !$dims ) + return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') ); + list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims; + + $newimage = wp_imagecreatetruecolor( $dst_w, $dst_h ); + + imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); + + // convert from full colors to index colors, like original PNG. + if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) ) + imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) ); + + // we don't need the original in memory anymore + imagedestroy( $image ); + + // $suffix will be appended to the destination filename, just before the extension + if ( !$suffix ) + $suffix = "{$dst_w}x{$dst_h}"; + + $info = pathinfo($file); + $dir = $info['dirname']; + $ext = $info['extension']; + $name = wp_basename($file, ".$ext"); + + if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) ) + $dir = $_dest_path; + $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}"; + + if ( IMAGETYPE_GIF == $orig_type ) { + if ( !imagegif( $newimage, $destfilename ) ) + return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); + } elseif ( IMAGETYPE_PNG == $orig_type ) { + if ( !imagepng( $newimage, $destfilename ) ) + return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); + } else { + // all other formats are converted to jpg + $destfilename = "{$dir}/{$name}-{$suffix}.jpg"; + if ( !imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) ) + return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); + } + + imagedestroy( $newimage ); + + // Set correct file permissions + $stat = stat( dirname( $destfilename )); + $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits + @ chmod( $destfilename, $perms ); + + return $destfilename; +} + +/** + * Resize an image to make a thumbnail or intermediate size. + * + * The returned array has the file size, the image width, and image height. The + * filter 'image_make_intermediate_size' can be used to hook in and change the + * values of the returned array. The only parameter is the resized file path. + * + * @since 2.5.0 + * + * @param string $file File path. + * @param int $width Image width. + * @param int $height Image height. + * @param bool $crop Optional, default is false. Whether to crop image to specified height and width or resize. + * @return bool|array False, if no image was created. Metadata array on success. + */ +function image_make_intermediate_size($file, $width, $height, $crop=false) { + if ( $width || $height ) { + $resized_file = image_resize($file, $width, $height, $crop); + if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) { + $resized_file = apply_filters('image_make_intermediate_size', $resized_file); + return array( + 'file' => wp_basename( $resized_file ), + 'width' => $info[0], + 'height' => $info[1], + ); + } + } + return false; +} + +/** + * Retrieve the image's intermediate size (resized) path, width, and height. + * + * The $size parameter can be an array with the width and height respectively. + * If the size matches the 'sizes' metadata array for width and height, then it + * will be used. If there is no direct match, then the nearest image size larger + * than the specified size will be used. If nothing is found, then the function + * will break out and return false. + * + * The metadata 'sizes' is used for compatible sizes that can be used for the + * parameter $size value. + * + * The url path will be given, when the $size parameter is a string. + * + * If you are passing an array for the $size, you should consider using + * add_image_size() so that a cropped version is generated. It's much more + * efficient than having to find the closest-sized image and then having the + * browser scale down the image. + * + * @since 2.5.0 + * @see add_image_size() + * + * @param int $post_id Attachment ID for image. + * @param array|string $size Optional, default is 'thumbnail'. Size of image, either array or string. + * @return bool|array False on failure or array of file path, width, and height on success. + */ +function image_get_intermediate_size($post_id, $size='thumbnail') { + if ( !is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) ) + return false; + + // get the best one for a specified set of dimensions + if ( is_array($size) && !empty($imagedata['sizes']) ) { + foreach ( $imagedata['sizes'] as $_size => $data ) { + // already cropped to width or height; so use this size + if ( ( $data['width'] == $size[0] && $data['height'] <= $size[1] ) || ( $data['height'] == $size[1] && $data['width'] <= $size[0] ) ) { + $file = $data['file']; + list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); + return compact( 'file', 'width', 'height' ); + } + // add to lookup table: area => size + $areas[$data['width'] * $data['height']] = $_size; + } + if ( !$size || !empty($areas) ) { + // find for the smallest image not smaller than the desired size + ksort($areas); + foreach ( $areas as $_size ) { + $data = $imagedata['sizes'][$_size]; + if ( $data['width'] >= $size[0] || $data['height'] >= $size[1] ) { + // Skip images with unexpectedly divergent aspect ratios (crops) + // First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop + $maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false ); + // If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size + if ( 'thumbnail' != $_size && ( !$maybe_cropped || ( $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] ) || ( $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'] ) ) ) + continue; + // If we're still here, then we're going to use this size + $file = $data['file']; + list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); + return compact( 'file', 'width', 'height' ); + } + } + } + } + + if ( is_array($size) || empty($size) || empty($imagedata['sizes'][$size]) ) + return false; + + $data = $imagedata['sizes'][$size]; + // include the full filesystem path of the intermediate file + if ( empty($data['path']) && !empty($data['file']) ) { + $file_url = wp_get_attachment_url($post_id); + $data['path'] = path_join( dirname($imagedata['file']), $data['file'] ); + $data['url'] = path_join( dirname($file_url), $data['file'] ); + } + return $data; +} + +/** + * Get the available image sizes + * @since 3.0.0 + * @return array Returns a filtered array of image size strings + */ +function get_intermediate_image_sizes() { + global $_wp_additional_image_sizes; + $image_sizes = array('thumbnail', 'medium', 'large'); // Standard sizes + if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) + $image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) ); + + return apply_filters( 'intermediate_image_sizes', $image_sizes ); +} + +/** + * Retrieve an image to represent an attachment. + * + * A mime icon for files, thumbnail or intermediate size for images. + * + * @since 2.5.0 + * + * @param int $attachment_id Image attachment ID. + * @param string $size Optional, default is 'thumbnail'. + * @param bool $icon Optional, default is false. Whether it is an icon. + * @return bool|array Returns an array (url, width, height), or false, if no image is available. + */ +function wp_get_attachment_image_src($attachment_id, $size='thumbnail', $icon = false) { + + // get a thumbnail or intermediate image if there is one + if ( $image = image_downsize($attachment_id, $size) ) + return $image; + + $src = false; + + if ( $icon && $src = wp_mime_type_icon($attachment_id) ) { + $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/crystal' ); + $src_file = $icon_dir . '/' . wp_basename($src); + @list($width, $height) = getimagesize($src_file); + } + if ( $src && $width && $height ) + return array( $src, $width, $height ); + return false; +} + +/** + * Get an HTML img element representing an image attachment + * + * While $size will accept an array, it is better to register a size with + * add_image_size() so that a cropped version is generated. It's much more + * efficient than having to find the closest-sized image and then having the + * browser scale down the image. + * + * @see add_image_size() + * @uses apply_filters() Calls 'wp_get_attachment_image_attributes' hook on attributes array + * @uses wp_get_attachment_image_src() Gets attachment file URL and dimensions + * @since 2.5.0 + * + * @param int $attachment_id Image attachment ID. + * @param string $size Optional, default is 'thumbnail'. + * @param bool $icon Optional, default is false. Whether it is an icon. + * @return string HTML img element or empty string on failure. + */ +function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = '') { + + $html = ''; + $image = wp_get_attachment_image_src($attachment_id, $size, $icon); + if ( $image ) { + list($src, $width, $height) = $image; + $hwstring = image_hwstring($width, $height); + if ( is_array($size) ) + $size = join('x', $size); + $attachment =& get_post($attachment_id); + $default_attr = array( + 'src' => $src, + 'class' => "attachment-$size", + 'alt' => trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )), // Use Alt field first + 'title' => trim(strip_tags( $attachment->post_title )), + ); + if ( empty($default_attr['alt']) ) + $default_attr['alt'] = trim(strip_tags( $attachment->post_excerpt )); // If not, Use the Caption + if ( empty($default_attr['alt']) ) + $default_attr['alt'] = trim(strip_tags( $attachment->post_title )); // Finally, use the title + + $attr = wp_parse_args($attr, $default_attr); + $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment ); + $attr = array_map( 'esc_attr', $attr ); + $html = rtrim(" $value ) { + $html .= " $name=" . '"' . $value . '"'; + } + $html .= ' />'; + } + + return $html; +} + +/** + * Adds a 'wp-post-image' class to post thumbnail thumbnails + * Uses the begin_fetch_post_thumbnail_html and end_fetch_post_thumbnail_html action hooks to + * dynamically add/remove itself so as to only filter post thumbnail thumbnails + * + * @since 2.9.0 + * @param array $attr Attributes including src, class, alt, title + * @return array + */ +function _wp_post_thumbnail_class_filter( $attr ) { + $attr['class'] .= ' wp-post-image'; + return $attr; +} + +/** + * Adds _wp_post_thumbnail_class_filter to the wp_get_attachment_image_attributes filter + * + * @since 2.9.0 + */ +function _wp_post_thumbnail_class_filter_add( $attr ) { + add_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); +} + +/** + * Removes _wp_post_thumbnail_class_filter from the wp_get_attachment_image_attributes filter + * + * @since 2.9.0 + */ +function _wp_post_thumbnail_class_filter_remove( $attr ) { + remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); +} + +add_shortcode('wp_caption', 'img_caption_shortcode'); +add_shortcode('caption', 'img_caption_shortcode'); + +/** + * The Caption shortcode. + * + * Allows a plugin to replace the content that would otherwise be returned. The + * filter is 'img_caption_shortcode' and passes an empty string, the attr + * parameter and the content parameter values. + * + * The supported attributes for the shortcode are 'id', 'align', 'width', and + * 'caption'. + * + * @since 2.6.0 + * + * @param array $attr Attributes attributed to the shortcode. + * @param string $content Optional. Shortcode content. + * @return string + */ +function img_caption_shortcode($attr, $content = null) { + + // Allow plugins/themes to override the default caption template. + $output = apply_filters('img_caption_shortcode', '', $attr, $content); + if ( $output != '' ) + return $output; + + extract(shortcode_atts(array( + 'id' => '', + 'align' => 'alignnone', + 'width' => '', + 'caption' => '' + ), $attr)); + + if ( 1 > (int) $width || empty($caption) ) + return $content; + + if ( $id ) $id = 'id="' . esc_attr($id) . '" '; + + return '
    ' + . do_shortcode( $content ) . '

    ' . $caption . '

    '; +} + +add_shortcode('gallery', 'gallery_shortcode'); + +/** + * The Gallery shortcode. + * + * This implements the functionality of the Gallery Shortcode for displaying + * WordPress images on a post. + * + * @since 2.5.0 + * + * @param array $attr Attributes attributed to the shortcode. + * @return string HTML content to display gallery. + */ +function gallery_shortcode($attr) { + global $post, $wp_locale; + + static $instance = 0; + $instance++; + + // Allow plugins/themes to override the default gallery template. + $output = apply_filters('post_gallery', '', $attr); + if ( $output != '' ) + return $output; + + // We're trusting author input, so let's at least make sure it looks like a valid orderby statement + if ( isset( $attr['orderby'] ) ) { + $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] ); + if ( !$attr['orderby'] ) + unset( $attr['orderby'] ); + } + + extract(shortcode_atts(array( + 'order' => 'ASC', + 'orderby' => 'menu_order ID', + 'id' => $post->ID, + 'itemtag' => 'dl', + 'icontag' => 'dt', + 'captiontag' => 'dd', + 'columns' => 3, + 'size' => 'thumbnail', + 'include' => '', + 'exclude' => '' + ), $attr)); + + $id = intval($id); + if ( 'RAND' == $order ) + $orderby = 'none'; + + if ( !empty($include) ) { + $include = preg_replace( '/[^0-9,]+/', '', $include ); + $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); + + $attachments = array(); + foreach ( $_attachments as $key => $val ) { + $attachments[$val->ID] = $_attachments[$key]; + } + } elseif ( !empty($exclude) ) { + $exclude = preg_replace( '/[^0-9,]+/', '', $exclude ); + $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); + } else { + $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); + } + + if ( empty($attachments) ) + return ''; + + if ( is_feed() ) { + $output = "\n"; + foreach ( $attachments as $att_id => $attachment ) + $output .= wp_get_attachment_link($att_id, $size, true) . "\n"; + return $output; + } + + $itemtag = tag_escape($itemtag); + $captiontag = tag_escape($captiontag); + $columns = intval($columns); + $itemwidth = $columns > 0 ? floor(100/$columns) : 100; + $float = is_rtl() ? 'right' : 'left'; + + $selector = "gallery-{$instance}"; + + $gallery_style = $gallery_div = ''; + if ( apply_filters( 'use_default_gallery_style', true ) ) + $gallery_style = " + + "; + $size_class = sanitize_html_class( $size ); + $gallery_div = "\n"; + + return $output; +} + +/** + * Display previous image link that has the same post parent. + * + * @since 2.5.0 + * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string. 0 or 'none' will default to post_title or $text; + * @param string $text Optional, default is false. If included, link will reflect $text variable. + * @return string HTML content. + */ +function previous_image_link($size = 'thumbnail', $text = false) { + adjacent_image_link(true, $size, $text); +} + +/** + * Display next image link that has the same post parent. + * + * @since 2.5.0 + * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string. 0 or 'none' will default to post_title or $text; + * @param string $text Optional, default is false. If included, link will reflect $text variable. + * @return string HTML content. + */ +function next_image_link($size = 'thumbnail', $text = false) { + adjacent_image_link(false, $size, $text); +} + +/** + * Display next or previous image link that has the same post parent. + * + * Retrieves the current attachment object from the $post global. + * + * @since 2.5.0 + * + * @param bool $prev Optional. Default is true to display previous link, true for next. + */ +function adjacent_image_link($prev = true, $size = 'thumbnail', $text = false) { + global $post; + $post = get_post($post); + $attachments = array_values(get_children( array('post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID') )); + + foreach ( $attachments as $k => $attachment ) + if ( $attachment->ID == $post->ID ) + break; + + $k = $prev ? $k - 1 : $k + 1; + + if ( isset($attachments[$k]) ) + echo wp_get_attachment_link($attachments[$k]->ID, $size, true, false, $text); +} + +/** + * Retrieve taxonomies attached to the attachment. + * + * @since 2.5.0 + * + * @param int|array|object $attachment Attachment ID, Attachment data array, or Attachment data object. + * @return array Empty array on failure. List of taxonomies on success. + */ +function get_attachment_taxonomies($attachment) { + if ( is_int( $attachment ) ) + $attachment = get_post($attachment); + else if ( is_array($attachment) ) + $attachment = (object) $attachment; + + if ( ! is_object($attachment) ) + return array(); + + $filename = basename($attachment->guid); + + $objects = array('attachment'); + + if ( false !== strpos($filename, '.') ) + $objects[] = 'attachment:' . substr($filename, strrpos($filename, '.') + 1); + if ( !empty($attachment->post_mime_type) ) { + $objects[] = 'attachment:' . $attachment->post_mime_type; + if ( false !== strpos($attachment->post_mime_type, '/') ) + foreach ( explode('/', $attachment->post_mime_type) as $token ) + if ( !empty($token) ) + $objects[] = "attachment:$token"; + } + + $taxonomies = array(); + foreach ( $objects as $object ) + if ( $taxes = get_object_taxonomies($object) ) + $taxonomies = array_merge($taxonomies, $taxes); + + return array_unique($taxonomies); +} + +/** + * Check if the installed version of GD supports particular image type + * + * @since 2.9.0 + * + * @param string $mime_type + * @return bool + */ +function gd_edit_image_support($mime_type) { + if ( function_exists('imagetypes') ) { + switch( $mime_type ) { + case 'image/jpeg': + return (imagetypes() & IMG_JPG) != 0; + case 'image/png': + return (imagetypes() & IMG_PNG) != 0; + case 'image/gif': + return (imagetypes() & IMG_GIF) != 0; + } + } else { + switch( $mime_type ) { + case 'image/jpeg': + return function_exists('imagecreatefromjpeg'); + case 'image/png': + return function_exists('imagecreatefrompng'); + case 'image/gif': + return function_exists('imagecreatefromgif'); + } + } + return false; +} + +/** + * Create new GD image resource with transparency support + * + * @since 2.9.0 + * + * @param int $width Image width + * @param int $height Image height + * @return image resource + */ +function wp_imagecreatetruecolor($width, $height) { + $img = imagecreatetruecolor($width, $height); + if ( is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha') ) { + imagealphablending($img, false); + imagesavealpha($img, true); + } + return $img; +} + +/** + * API for easily embedding rich media such as videos and images into content. + * + * @package WordPress + * @subpackage Embed + * @since 2.9.0 + */ +class WP_Embed { + var $handlers = array(); + var $post_ID; + var $usecache = true; + var $linkifunknown = true; + + /** + * PHP4 constructor + */ + function WP_Embed() { + return $this->__construct(); + } + + /** + * PHP5 constructor + */ + function __construct() { + // Hack to get the [embed] shortcode to run before wpautop() + add_filter( 'the_content', array(&$this, 'run_shortcode'), 8 ); + + // Shortcode placeholder for strip_shortcodes() + add_shortcode( 'embed', '__return_false' ); + + // Attempts to embed all URLs in a post + if ( get_option('embed_autourls') ) + add_filter( 'the_content', array(&$this, 'autoembed'), 8 ); + + // After a post is saved, invalidate the oEmbed cache + add_action( 'save_post', array(&$this, 'delete_oembed_caches') ); + + // After a post is saved, cache oEmbed items via AJAX + add_action( 'edit_form_advanced', array(&$this, 'maybe_run_ajax_cache') ); + } + + /** + * Process the [embed] shortcode. + * + * Since the [embed] shortcode needs to be run earlier than other shortcodes, + * this function removes all existing shortcodes, registers the [embed] shortcode, + * calls {@link do_shortcode()}, and then re-registers the old shortcodes. + * + * @uses $shortcode_tags + * @uses remove_all_shortcodes() + * @uses add_shortcode() + * @uses do_shortcode() + * + * @param string $content Content to parse + * @return string Content with shortcode parsed + */ + function run_shortcode( $content ) { + global $shortcode_tags; + + // Back up current registered shortcodes and clear them all out + $orig_shortcode_tags = $shortcode_tags; + remove_all_shortcodes(); + + add_shortcode( 'embed', array(&$this, 'shortcode') ); + + // Do the shortcode (only the [embed] one is registered) + $content = do_shortcode( $content ); + + // Put the original shortcodes back + $shortcode_tags = $orig_shortcode_tags; + + return $content; + } + + /** + * If a post/page was saved, then output Javascript to make + * an AJAX request that will call WP_Embed::cache_oembed(). + */ + function maybe_run_ajax_cache() { + global $post_ID; + + if ( empty($post_ID) || empty($_GET['message']) || 1 != $_GET['message'] ) + return; + +?> + +handlers[$priority][$id] = array( + 'regex' => $regex, + 'callback' => $callback, + ); + } + + /** + * Unregister a previously registered embed handler. Do not use this function directly, use {@link wp_embed_unregister_handler()} instead. + * + * @param string $id The handler ID that should be removed. + * @param int $priority Optional. The priority of the handler to be removed (default: 10). + */ + function unregister_handler( $id, $priority = 10 ) { + if ( isset($this->handlers[$priority][$id]) ) + unset($this->handlers[$priority][$id]); + } + + /** + * The {@link do_shortcode()} callback function. + * + * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of the registered embed handlers. + * If none of the regex matches and it's enabled, then the URL will be given to the {@link WP_oEmbed} class. + * + * @uses wp_oembed_get() + * @uses wp_parse_args() + * @uses wp_embed_defaults() + * @uses WP_Embed::maybe_make_link() + * @uses get_option() + * @uses current_user_can() + * @uses wp_cache_get() + * @uses wp_cache_set() + * @uses get_post_meta() + * @uses update_post_meta() + * + * @param array $attr Shortcode attributes. + * @param string $url The URL attempting to be embeded. + * @return string The embed HTML on success, otherwise the original URL. + */ + function shortcode( $attr, $url = '' ) { + global $post; + + if ( empty($url) ) + return ''; + + $rawattr = $attr; + $attr = wp_parse_args( $attr, wp_embed_defaults() ); + + // kses converts & into & and we need to undo this + // See http://core.trac.wordpress.org/ticket/11311 + $url = str_replace( '&', '&', $url ); + + // Look for known internal handlers + ksort( $this->handlers ); + foreach ( $this->handlers as $priority => $handlers ) { + foreach ( $handlers as $id => $handler ) { + if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) { + if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) ) + return apply_filters( 'embed_handler_html', $return, $url, $attr ); + } + } + } + + $post_ID = ( !empty($post->ID) ) ? $post->ID : null; + if ( !empty($this->post_ID) ) // Potentially set by WP_Embed::cache_oembed() + $post_ID = $this->post_ID; + + // Unknown URL format. Let oEmbed have a go. + if ( $post_ID ) { + + // Check for a cached result (stored in the post meta) + $cachekey = '_oembed_' . md5( $url . serialize( $attr ) ); + if ( $this->usecache ) { + $cache = get_post_meta( $post_ID, $cachekey, true ); + + // Failures are cached + if ( '{{unknown}}' === $cache ) + return $this->maybe_make_link( $url ); + + if ( !empty($cache) ) + return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID ); + } + + // Use oEmbed to get the HTML + $attr['discover'] = ( apply_filters('embed_oembed_discover', false) && author_can( $post_ID, 'unfiltered_html' ) ); + $html = wp_oembed_get( $url, $attr ); + + // Cache the result + $cache = ( $html ) ? $html : '{{unknown}}'; + update_post_meta( $post_ID, $cachekey, $cache ); + + // If there was a result, return it + if ( $html ) + return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_ID ); + } + + // Still unknown + return $this->maybe_make_link( $url ); + } + + /** + * Delete all oEmbed caches. + * + * @param int $post_ID Post ID to delete the caches for. + */ + function delete_oembed_caches( $post_ID ) { + $post_metas = get_post_custom_keys( $post_ID ); + if ( empty($post_metas) ) + return; + + foreach( $post_metas as $post_meta_key ) { + if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) ) + delete_post_meta( $post_ID, $post_meta_key ); + } + } + + /** + * Triggers a caching of all oEmbed results. + * + * @param int $post_ID Post ID to do the caching for. + */ + function cache_oembed( $post_ID ) { + $post = get_post( $post_ID ); + + if ( empty($post->ID) || !in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', array( 'post', 'page' ) ) ) ) + return; + + // Trigger a caching + if ( !empty($post->post_content) ) { + $this->post_ID = $post->ID; + $this->usecache = false; + + $content = $this->run_shortcode( $post->post_content ); + if ( get_option('embed_autourls') ) + $this->autoembed( $content ); + + $this->usecache = true; + } + } + + /** + * Passes any unlinked URLs that are on their own line to {@link WP_Embed::shortcode()} for potential embedding. + * + * @uses WP_Embed::autoembed_callback() + * + * @param string $content The content to be searched. + * @return string Potentially modified $content. + */ + function autoembed( $content ) { + return preg_replace_callback( '|^\s*(https?://[^\s"]+)\s*$|im', array(&$this, 'autoembed_callback'), $content ); + } + + /** + * Callback function for {@link WP_Embed::autoembed()}. + * + * @uses WP_Embed::shortcode() + * + * @param array $match A regex match array. + * @return string The embed HTML on success, otherwise the original URL. + */ + function autoembed_callback( $match ) { + $oldval = $this->linkifunknown; + $this->linkifunknown = false; + $return = $this->shortcode( array(), $match[1] ); + $this->linkifunknown = $oldval; + + return "\n$return\n"; + } + + /** + * Conditionally makes a hyperlink based on an internal class variable. + * + * @param string $url URL to potentially be linked. + * @return string Linked URL or the original URL. + */ + function maybe_make_link( $url ) { + $output = ( $this->linkifunknown ) ? '' . esc_html($url) . '' : $url; + return apply_filters( 'embed_maybe_make_link', $output, $url ); + } +} +$wp_embed = new WP_Embed(); + +/** + * Register an embed handler. This function should probably only be used for sites that do not support oEmbed. + * + * @since 2.9.0 + * @see WP_Embed::register_handler() + */ +function wp_embed_register_handler( $id, $regex, $callback, $priority = 10 ) { + global $wp_embed; + $wp_embed->register_handler( $id, $regex, $callback, $priority ); +} + +/** + * Unregister a previously registered embed handler. + * + * @since 2.9.0 + * @see WP_Embed::unregister_handler() + */ +function wp_embed_unregister_handler( $id, $priority = 10 ) { + global $wp_embed; + $wp_embed->unregister_handler( $id, $priority ); +} + +/** + * Create default array of embed parameters. + * + * @since 2.9.0 + * + * @return array Default embed parameters. + */ +function wp_embed_defaults() { + if ( !empty($GLOBALS['content_width']) ) + $theme_width = (int) $GLOBALS['content_width']; + + $width = get_option('embed_size_w'); + + if ( empty($width) && !empty($theme_width) ) + $width = $theme_width; + + if ( empty($width) ) + $width = 500; + + $height = get_option('embed_size_h'); + + if ( empty($height) ) + $height = 700; + + return apply_filters( 'embed_defaults', array( + 'width' => $width, + 'height' => $height, + ) ); +} + +/** + * Based on a supplied width/height example, return the biggest possible dimensions based on the max width/height. + * + * @since 2.9.0 + * @uses wp_constrain_dimensions() This function passes the widths and the heights. + * + * @param int $example_width The width of an example embed. + * @param int $example_height The height of an example embed. + * @param int $max_width The maximum allowed width. + * @param int $max_height The maximum allowed height. + * @return array The maximum possible width and height based on the example ratio. + */ +function wp_expand_dimensions( $example_width, $example_height, $max_width, $max_height ) { + $example_width = (int) $example_width; + $example_height = (int) $example_height; + $max_width = (int) $max_width; + $max_height = (int) $max_height; + + return wp_constrain_dimensions( $example_width * 1000000, $example_height * 1000000, $max_width, $max_height ); +} + +/** + * Attempts to fetch the embed HTML for a provided URL using oEmbed. + * + * @since 2.9.0 + * @see WP_oEmbed + * + * @uses _wp_oembed_get_object() + * @uses WP_oEmbed::get_html() + * + * @param string $url The URL that should be embeded. + * @param array $args Addtional arguments and parameters. + * @return string The original URL on failure or the embed HTML on success. + */ +function wp_oembed_get( $url, $args = '' ) { + require_once( ABSPATH . WPINC . '/class-oembed.php' ); + $oembed = _wp_oembed_get_object(); + return $oembed->get_html( $url, $args ); +} + +/** + * Adds a URL format and oEmbed provider URL pair. + * + * @since 2.9.0 + * @see WP_oEmbed + * + * @uses _wp_oembed_get_object() + * + * @param string $format The format of URL that this provider can handle. You can use asterisks as wildcards. + * @param string $provider The URL to the oEmbed provider. + * @param boolean $regex Whether the $format parameter is in a regex format. + */ +function wp_oembed_add_provider( $format, $provider, $regex = false ) { + require_once( ABSPATH . WPINC . '/class-oembed.php' ); + $oembed = _wp_oembed_get_object(); + $oembed->providers[$format] = array( $provider, $regex ); +} \ No newline at end of file diff --git a/src/wp-includes/meta.php b/src/wp-includes/meta.php new file mode 100644 index 00000000..08d51a26 --- /dev/null +++ b/src/wp-includes/meta.php @@ -0,0 +1,522 @@ +get_var( $wpdb->prepare( + "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d", + $meta_key, $object_id ) ) ) + return false; + + $_meta_value = $meta_value; + $meta_value = maybe_serialize( $meta_value ); + + do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value ); + + $wpdb->insert( $table, array( + $column => $object_id, + 'meta_key' => $meta_key, + 'meta_value' => $meta_value + ) ); + + wp_cache_delete($object_id, $meta_type . '_meta'); + // users cache stores usermeta that must be cleared. + if ( 'user' == $meta_type ) + clean_user_cache($object_id); + + do_action( "added_{$meta_type}_meta", $wpdb->insert_id, $object_id, $meta_key, $_meta_value ); + + return true; +} + +/** + * Update metadata for the specified object. If no value already exists for the specified object + * ID and metadata key, the metadata will be added. + * + * @since 2.9.0 + * @uses $wpdb WordPress database object for queries. + * @uses do_action() Calls 'update_{$meta_type}_meta' before updating metadata with meta_id of + * metadata entry to update, object ID, meta key, and meta value + * @uses do_action() Calls 'updated_{$meta_type}_meta' after updating metadata with meta_id of + * updated metadata entry, object ID, meta key, and meta value + * + * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) + * @param int $object_id ID of the object metadata is for + * @param string $meta_key Metadata key + * @param string $meta_value Metadata value + * @param string $prev_value Optional. If specified, only update existing metadata entries with + * the specified value. Otherwise, update all entries. + * @return bool True on successful update, false on failure. + */ +function update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_value = '') { + if ( !$meta_type || !$meta_key ) + return false; + + if ( !$object_id = absint($object_id) ) + return false; + + if ( ! $table = _get_meta_table($meta_type) ) + return false; + + global $wpdb; + + $column = esc_sql($meta_type . '_id'); + $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; + + // expected_slashed ($meta_key) + $meta_key = stripslashes($meta_key); + $meta_value = stripslashes_deep($meta_value); + $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type ); + + $check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value ); + if ( null !== $check ) + return (bool) $check; + + if ( ! $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ) ) + return add_metadata($meta_type, $object_id, $meta_key, $meta_value); + + // Compare existing value to new value if no prev value given and the key exists only once. + if ( empty($prev_value) ) { + $old_value = get_metadata($meta_type, $object_id, $meta_key); + if ( count($old_value) == 1 ) { + if ( $old_value[0] === $meta_value ) + return false; + } + } + + $_meta_value = $meta_value; + $meta_value = maybe_serialize( $meta_value ); + + $data = compact( 'meta_value' ); + $where = array( $column => $object_id, 'meta_key' => $meta_key ); + + if ( !empty( $prev_value ) ) { + $prev_value = maybe_serialize($prev_value); + $where['meta_value'] = $prev_value; + } + + do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); + + $wpdb->update( $table, $data, $where ); + wp_cache_delete($object_id, $meta_type . '_meta'); + // users cache stores usermeta that must be cleared. + if ( 'user' == $meta_type ) + clean_user_cache($object_id); + + do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value ); + + return true; +} + +/** + * Delete metadata for the specified object. + * + * @since 2.9.0 + * @uses $wpdb WordPress database object for queries. + * @uses do_action() Calls 'deleted_{$meta_type}_meta' after deleting with meta_id of + * deleted metadata entries, object ID, meta key, and meta value + * + * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) + * @param int $object_id ID of the object metadata is for + * @param string $meta_key Metadata key + * @param string $meta_value Optional. Metadata value. If specified, only delete metadata entries + * with this value. Otherwise, delete all entries with the specified meta_key. + * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries + * for all objects, ignoring the specified object_id. Otherwise, only delete matching + * metadata entries for the specified object_id. + * @return bool True on successful delete, false on failure. + */ +function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false) { + if ( !$meta_type || !$meta_key ) + return false; + + if ( (!$object_id = absint($object_id)) && !$delete_all ) + return false; + + if ( ! $table = _get_meta_table($meta_type) ) + return false; + + global $wpdb; + + $type_column = esc_sql($meta_type . '_id'); + $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; + // expected_slashed ($meta_key) + $meta_key = stripslashes($meta_key); + $meta_value = stripslashes_deep($meta_value); + + $check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all ); + if ( null !== $check ) + return (bool) $check; + + $_meta_value = $meta_value; + $meta_value = maybe_serialize( $meta_value ); + + $query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key ); + + if ( !$delete_all ) + $query .= $wpdb->prepare(" AND $type_column = %d", $object_id ); + + if ( $meta_value ) + $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value ); + + $meta_ids = $wpdb->get_col( $query ); + if ( !count( $meta_ids ) ) + return false; + + do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value ); + + $query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . " )"; + + $count = $wpdb->query($query); + + if ( !$count ) + return false; + + wp_cache_delete($object_id, $meta_type . '_meta'); + // users cache stores usermeta that must be cleared. + if ( 'user' == $meta_type ) + clean_user_cache($object_id); + + do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value ); + + return true; +} + +/** + * Retrieve metadata for the specified object. + * + * @since 2.9.0 + * + * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) + * @param int $object_id ID of the object metadata is for + * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for + * the specified object. + * @param bool $single Optional, default is false. If true, return only the first value of the + * specified meta_key. This parameter has no effect if meta_key is not specified. + * @return string|array Single metadata value, or array of values + */ +function get_metadata($meta_type, $object_id, $meta_key = '', $single = false) { + if ( !$meta_type ) + return false; + + if ( !$object_id = absint($object_id) ) + return false; + + $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single ); + if ( null !== $check ) { + if ( $single && is_array( $check ) ) + return $check[0]; + else + return $check; + } + + $meta_cache = wp_cache_get($object_id, $meta_type . '_meta'); + + if ( !$meta_cache ) { + $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); + $meta_cache = $meta_cache[$object_id]; + } + + if ( !$meta_key ) + return $meta_cache; + + if ( isset($meta_cache[$meta_key]) ) { + if ( $single ) + return maybe_unserialize( $meta_cache[$meta_key][0] ); + else + return array_map('maybe_unserialize', $meta_cache[$meta_key]); + } + + if ($single) + return ''; + else + return array(); +} + +/** + * Update the metadata cache for the specified objects. + * + * @since 2.9.0 + * @uses $wpdb WordPress database object for queries. + * + * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) + * @param int|array $object_ids array or comma delimited list of object IDs to update cache for + * @return mixed Metadata cache for the specified objects, or false on failure. + */ +function update_meta_cache($meta_type, $object_ids) { + if ( empty( $meta_type ) || empty( $object_ids ) ) + return false; + + if ( ! $table = _get_meta_table($meta_type) ) + return false; + + $column = esc_sql($meta_type . '_id'); + + global $wpdb; + + if ( !is_array($object_ids) ) { + $object_ids = preg_replace('|[^0-9,]|', '', $object_ids); + $object_ids = explode(',', $object_ids); + } + + $object_ids = array_map('intval', $object_ids); + + $cache_key = $meta_type . '_meta'; + $ids = array(); + $cache = array(); + foreach ( $object_ids as $id ) { + $cached_object = wp_cache_get( $id, $cache_key ); + if ( false === $cached_object ) + $ids[] = $id; + else + $cache[$id] = $cached_object; + } + + if ( empty( $ids ) ) + return $cache; + + // Get meta info + $id_list = join(',', $ids); + $meta_list = $wpdb->get_results( $wpdb->prepare("SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list)", + $meta_type), ARRAY_A ); + + if ( !empty($meta_list) ) { + foreach ( $meta_list as $metarow) { + $mpid = intval($metarow[$column]); + $mkey = $metarow['meta_key']; + $mval = $metarow['meta_value']; + + // Force subkeys to be array type: + if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) ) + $cache[$mpid] = array(); + if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) ) + $cache[$mpid][$mkey] = array(); + + // Add a value to the current pid/key: + $cache[$mpid][$mkey][] = $mval; + } + } + + foreach ( $ids as $id ) { + if ( ! isset($cache[$id]) ) + $cache[$id] = array(); + wp_cache_add( $id, $cache[$id], $cache_key ); + } + + return $cache; +} + +/** + * Given a meta query, generates SQL clauses to be appended to a main query + * + * @since 3.1.0 + * @access private + * + * @param array $meta_query List of metadata queries. A single query is an associative array: + * - 'key' string The meta key + * - 'value' string|array The meta value + * - 'compare' (optional) string How to compare the key to the value. + * Possible values: '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN'. + * Default: '=' + * - 'type' string (optional) The type of the value. + * Possible values: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. + * Default: 'CHAR' + * + * @param string $type Type of meta + * @param string $primary_table + * @param string $primary_id_column + * @param object $context (optional) The main query object + * @return array( 'join' => $join_sql, 'where' => $where_sql ) + */ +function _get_meta_sql( $meta_query, $type, $primary_table, $primary_id_column, $context = null ) { + global $wpdb; + + if ( ! $meta_table = _get_meta_table( $type ) ) + return false; + + $meta_id_column = esc_sql( $type . '_id' ); + + $join = ''; + $where = ''; + $i = 0; + foreach ( $meta_query as $q ) { + $meta_key = isset( $q['key'] ) ? trim( $q['key'] ) : ''; + $meta_value = isset( $q['value'] ) ? $q['value'] : ''; + $meta_compare = isset( $q['compare'] ) ? strtoupper( $q['compare'] ) : '='; + $meta_type = isset( $q['type'] ) ? strtoupper( $q['type'] ) : 'CHAR'; + + if ( ! in_array( $meta_compare, array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) + $meta_compare = '='; + + if ( 'NUMERIC' == $meta_type ) + $meta_type = 'SIGNED'; + elseif ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED' ) ) ) + $meta_type = 'CHAR'; + + if ( empty( $meta_key ) && empty( $meta_value ) ) + continue; + + $alias = $i ? 'mt' . $i : $meta_table; + + $join .= "\nINNER JOIN $meta_table"; + $join .= $i ? " AS $alias" : ''; + $join .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)"; + + $i++; + + if ( !empty( $meta_key ) ) + $where .= $wpdb->prepare( " AND $alias.meta_key = %s", $meta_key ); + + if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) { + if ( ! is_array( $meta_value ) ) + $meta_value = preg_split( '/[,\s]+/', $meta_value ); + } else { + $meta_value = trim( $meta_value ); + } + + if ( empty( $meta_value ) ) + continue; + + if ( 'IN' == substr( $meta_compare, -2) ) { + $meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')'; + } elseif ( 'BETWEEN' == substr( $meta_compare, -7) ) { + $meta_value = array_slice( $meta_value, 0, 2 ); + $meta_compare_string = '%s AND %s'; + } elseif ( 'LIKE' == substr( $meta_compare, -4 ) ) { + $meta_value = '%' . like_escape( $meta_value ) . '%'; + $meta_compare_string = '%s'; + } else { + $meta_compare_string = '%s'; + } + + // @todo Temporary hack to support empty values. Do not use outside of core. + if ( '_wp_zero_value' == $meta_value ) + $meta_value = 0; + + $where .= $wpdb->prepare( " AND CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$meta_compare_string}", $meta_value ); + } + + return apply_filters_ref_array( 'get_meta_sql', array( compact( 'join', 'where' ), $meta_query, $type, $primary_table, $primary_id_column, &$context ) ); +} + +/** + * Populates the $meta_query property + * + * @access private + * @since 3.1.0 + * + * @param array $qv The query variables + */ +function _parse_meta_query( &$qv ) { + $meta_query = array(); + + // Simple query needs to be first for orderby=meta_value to work correctly + foreach ( array( 'key', 'value', 'compare', 'type' ) as $key ) { + if ( !empty( $qv[ "meta_$key" ] ) ) + $meta_query[0][ $key ] = $qv[ "meta_$key" ]; + } + + if ( !empty( $qv['meta_query'] ) && is_array( $qv['meta_query'] ) ) { + $meta_query = array_merge( $meta_query, $qv['meta_query'] ); + } + + $qv['meta_query'] = $meta_query; +} + +/** + * Retrieve the name of the metadata table for the specified object type. + * + * @since 2.9.0 + * @uses $wpdb WordPress database object for queries. + * + * @param string $type Type of object to get metadata table for (e.g., comment, post, or user) + * @return mixed Metadata table name, or false if no metadata table exists + */ +function _get_meta_table($type) { + global $wpdb; + + $table_name = $type . 'meta'; + + if ( empty($wpdb->$table_name) ) + return false; + + return $wpdb->$table_name; +} + +/** + * Determine whether a meta key is protected + * + * @since 3.1.3 + * + * @param string $meta_key Meta key + * @return bool True if the key is protected, false otherwise. + */ +function is_protected_meta( $meta_key, $meta_type = null ) { + $protected = ( '_' == $meta_key[0] ); + + return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type ); +} + +/** + * Sanitize meta value + * + * @since 3.1.3 + * + * @param string $meta_key Meta key + * @param mixed $meta_value Meta value to sanitize + * @param string $meta_type Type of meta + * @return mixed Sanitized $meta_value + */ +function sanitize_meta( $meta_key, $meta_value, $meta_type = null ) { + return apply_filters( 'sanitize_meta', $meta_value, $meta_key, $meta_type ); +} + +?> diff --git a/src/wp-includes/ms-blogs.php b/src/wp-includes/ms-blogs.php new file mode 100644 index 00000000..0deca99a --- /dev/null +++ b/src/wp-includes/ms-blogs.php @@ -0,0 +1,681 @@ +update( $wpdb->blogs, array('last_updated' => current_time('mysql', true)), array('blog_id' => $wpdb->blogid) ); + refresh_blog_details( $wpdb->blogid ); + + do_action( 'wpmu_blog_updated', $wpdb->blogid ); +} + +/** + * Get a full blog URL, given a blog id. + * + * @since MU + * + * @param int $blog_id Blog ID + * @return string + */ +function get_blogaddress_by_id( $blog_id ) { + $bloginfo = get_blog_details( (int) $blog_id, false ); // only get bare details! + return esc_url( 'http://' . $bloginfo->domain . $bloginfo->path ); +} + +/** + * Get a full blog URL, given a blog name. + * + * @since MU + * + * @param string $blogname The (subdomain or directory) name + * @return string + */ +function get_blogaddress_by_name( $blogname ) { + global $current_site; + + if ( is_subdomain_install() ) { + if ( $blogname == 'main' ) + $blogname = 'www'; + $url = rtrim( network_home_url(), '/' ); + if ( !empty( $blogname ) ) + $url = preg_replace( '|^([^\.]+://)|', '$1' . $blogname . '.', $url ); + } else { + $url = network_home_url( $blogname ); + } + return esc_url( $url . '/' ); +} + +/** + * Get a full blog URL, given a domain and a path. + * + * @since MU + * + * @param string $domain + * @param string $path + * @return string + */ +function get_blogaddress_by_domain( $domain, $path ) { + if ( is_subdomain_install() ) { + $url = "http://".$domain.$path; + } else { + if ( $domain != $_SERVER['HTTP_HOST'] ) { + $blogname = substr( $domain, 0, strpos( $domain, '.' ) ); + $url = 'http://' . substr( $domain, strpos( $domain, '.' ) + 1 ) . $path; + // we're not installing the main blog + if ( $blogname != 'www.' ) + $url .= $blogname . '/'; + } else { // main blog + $url = 'http://' . $domain . $path; + } + } + return esc_url( $url ); +} + +/** + * Given a blog's (subdomain or directory) name, retrieve it's id. + * + * @since MU + * + * @param string $name + * @return int A blog id + */ +function get_id_from_blogname( $name ) { + global $wpdb, $current_site; + $blog_id = wp_cache_get( "get_id_from_blogname_" . $name, 'blog-details' ); + if ( $blog_id ) + return $blog_id; + + if ( is_subdomain_install() ) { + $domain = $name . '.' . $current_site->domain; + $path = $current_site->path; + } else { + $domain = $current_site->domain; + $path = $current_site->path . $name . '/'; + } + $blog_id = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domain, $path) ); + wp_cache_set( 'get_id_from_blogname_' . $name, $blog_id, 'blog-details' ); + return $blog_id; +} + +/** + * Retrieve the details for a blog from the blogs table and blog options. + * + * @since MU + * + * @param int|string|array $fields A blog ID, a blog name, or an array of fields to query against. + * @param bool $get_all Whether to retrieve all details or only the details in the blogs table. Default is true. + * @return object Blog details. + */ +function get_blog_details( $fields, $get_all = true ) { + global $wpdb; + + if ( is_array($fields ) ) { + if ( isset($fields['blog_id']) ) { + $blog_id = $fields['blog_id']; + } elseif ( isset($fields['domain']) && isset($fields['path']) ) { + $key = md5( $fields['domain'] . $fields['path'] ); + $blog = wp_cache_get($key, 'blog-lookup'); + if ( false !== $blog ) + return $blog; + if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) { + $nowww = substr( $fields['domain'], 4 ); + $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) AND path = %s ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'], $fields['path'] ) ); + } else { + $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $fields['domain'], $fields['path'] ) ); + } + if ( $blog ) { + wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details'); + $blog_id = $blog->blog_id; + } else { + return false; + } + } elseif ( isset($fields['domain']) && is_subdomain_install() ) { + $key = md5( $fields['domain'] ); + $blog = wp_cache_get($key, 'blog-lookup'); + if ( false !== $blog ) + return $blog; + if ( substr( $fields['domain'], 0, 4 ) == 'www.' ) { + $nowww = substr( $fields['domain'], 4 ); + $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain IN (%s,%s) ORDER BY CHAR_LENGTH(domain) DESC", $nowww, $fields['domain'] ) ); + } else { + $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $fields['domain'] ) ); + } + if ( $blog ) { + wp_cache_set($blog->blog_id . 'short', $blog, 'blog-details'); + $blog_id = $blog->blog_id; + } else { + return false; + } + } else { + return false; + } + } else { + if ( !is_numeric( $fields ) ) + $blog_id = get_id_from_blogname( $fields ); + else + $blog_id = $fields; + } + + $blog_id = (int) $blog_id; + + $all = $get_all == true ? '' : 'short'; + $details = wp_cache_get( $blog_id . $all, 'blog-details' ); + + if ( $details ) { + if ( ! is_object( $details ) ) { + if ( $details == -1 ) { + return false; + } else { + // Clear old pre-serialized objects. Cache clients do better with that. + wp_cache_delete( $blog_id . $all, 'blog-details' ); + unset($details); + } + } else { + return $details; + } + } + + // Try the other cache. + if ( $get_all ) { + $details = wp_cache_get( $blog_id . 'short', 'blog-details' ); + } else { + $details = wp_cache_get( $blog_id, 'blog-details' ); + // If short was requested and full cache is set, we can return. + if ( $details ) { + if ( ! is_object( $details ) ) { + if ( $details == -1 ) { + return false; + } else { + // Clear old pre-serialized objects. Cache clients do better with that. + wp_cache_delete( $blog_id, 'blog-details' ); + unset($details); + } + } else { + return $details; + } + } + } + + if ( empty($details) ) { + $details = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE blog_id = %d /* get_blog_details */", $blog_id ) ); + if ( ! $details ) { + // Set the full cache. + wp_cache_set( $blog_id, -1, 'blog-details' ); + return false; + } + } + + if ( ! $get_all ) { + wp_cache_set( $blog_id . $all, $details, 'blog-details' ); + return $details; + } + + $details->blogname = get_blog_option( $blog_id, 'blogname' ); + $details->siteurl = get_blog_option( $blog_id, 'siteurl' ); + $details->post_count = get_blog_option( $blog_id, 'post_count' ); + + $details = apply_filters( 'blog_details', $details ); + + wp_cache_set( $blog_id . $all, $details, 'blog-details' ); + + $key = md5( $details->domain . $details->path ); + wp_cache_set( $key, $details, 'blog-lookup' ); + + return $details; +} + +/** + * Clear the blog details cache. + * + * @since MU + * + * @param int $blog_id Blog ID + */ +function refresh_blog_details( $blog_id ) { + $blog_id = (int) $blog_id; + $details = get_blog_details( $blog_id, false ); + + wp_cache_delete( $blog_id , 'blog-details' ); + wp_cache_delete( $blog_id . 'short' , 'blog-details' ); + wp_cache_delete( md5( $details->domain . $details->path ) , 'blog-lookup' ); + wp_cache_delete( 'current_blog_' . $details->domain, 'site-options' ); + wp_cache_delete( 'current_blog_' . $details->domain . $details->path, 'site-options' ); +} + +/** + * Update the details for a blog. Updates the blogs table for a given blog id. + * + * @since MU + * + * @param int $blog_id Blog ID + * @param array $details Array of details keyed by blogs table field names. + * @return bool True if update succeeds, false otherwise. + */ +function update_blog_details( $blog_id, $details = array() ) { + global $wpdb; + + if ( empty($details) ) + return false; + + if ( is_object($details) ) + $details = get_object_vars($details); + + $current_details = get_blog_details($blog_id, false); + if ( empty($current_details) ) + return false; + + $current_details = get_object_vars($current_details); + + $details = array_merge($current_details, $details); + $details['last_updated'] = current_time('mysql', true); + + $update_details = array(); + $fields = array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id'); + foreach ( array_intersect( array_keys( $details ), $fields ) as $field ) + $update_details[$field] = $details[$field]; + + $wpdb->update( $wpdb->blogs, $update_details, array('blog_id' => $blog_id) ); + + // If spam status changed, issue actions. + if ( $details[ 'spam' ] != $current_details[ 'spam' ] ) { + if ( $details[ 'spam' ] == 1 ) + do_action( "make_spam_blog", $blog_id ); + else + do_action( "make_ham_blog", $blog_id ); + } + + if ( isset($details[ 'public' ]) ) + update_blog_option( $blog_id, 'blog_public', $details[ 'public' ] ); + + refresh_blog_details($blog_id); + + return true; +} + +/** + * Retrieve option value based on setting name and blog_id. + * + * If the option does not exist or does not have a value, then the return value + * will be false. This is useful to check whether you need to install an option + * and is commonly used during installation of plugin options and to test + * whether upgrading is required. + * + * There is a filter called 'blog_option_$option' with the $option being + * replaced with the option name. The filter takes two parameters. $value and + * $blog_id. It returns $value. + * The 'option_$option' filter in get_option() is not called. + * + * @since MU + * @uses apply_filters() Calls 'blog_option_$optionname' with the option name value. + * + * @param int $blog_id is the id of the blog. + * @param string $setting Name of option to retrieve. Should already be SQL-escaped. + * @param string $default (optional) Default value returned if option not found. + * @return mixed Value set for the option. + */ +function get_blog_option( $blog_id, $setting, $default = false ) { + global $wpdb; + + $key = $blog_id."-".$setting."-blog_option"; + $value = wp_cache_get( $key, "site-options" ); + if ( $value == null ) { + if ( $blog_id == $wpdb->blogid ) { + $value = get_option( $setting, $default ); + $notoptions = wp_cache_get( 'notoptions', 'options' ); + if ( isset( $notoptions[$setting] ) ) { + wp_cache_set( $key, 'noop', 'site-options' ); + $value = $default; + } elseif ( $value == false ) { + wp_cache_set( $key, 'falsevalue', 'site-options' ); + } else { + wp_cache_set( $key, $value, 'site-options' ); + } + return apply_filters( 'blog_option_' . $setting, $value, $blog_id ); + } else { + $blog_prefix = $wpdb->get_blog_prefix( $blog_id ); + $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$blog_prefix}options WHERE option_name = %s", $setting ) ); + if ( is_object( $row ) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values + $value = $row->option_value; + if ( $value == false ) + wp_cache_set( $key, 'falsevalue', 'site-options' ); + else + wp_cache_set( $key, $value, 'site-options' ); + } else { // option does not exist, so we must cache its non-existence + wp_cache_set( $key, 'noop', 'site-options' ); + $value = $default; + } + } + } elseif ( $value == 'noop' ) { + $value = $default; + } elseif ( $value == 'falsevalue' ) { + $value = false; + } + // If home is not set use siteurl. + if ( 'home' == $setting && '' == $value ) + return get_blog_option( $blog_id, 'siteurl' ); + + if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting ) + $value = untrailingslashit( $value ); + + return apply_filters( 'blog_option_' . $setting, maybe_unserialize( $value ), $blog_id ); +} + +/** + * Add an option for a particular blog. + * + * @since MU + * + * @param int $id The blog id + * @param string $key The option key + * @param mixed $value The option value + */ +function add_blog_option( $id, $key, $value ) { + $id = (int) $id; + + switch_to_blog($id); + add_option( $key, $value ); + restore_current_blog(); + wp_cache_set( $id."-".$key."-blog_option", $value, 'site-options' ); +} + +/** + * Delete an option for a particular blog. + * + * @since MU + * + * @param int $id The blog id + * @param string $key The option key + */ +function delete_blog_option( $id, $key ) { + $id = (int) $id; + + switch_to_blog($id); + delete_option( $key ); + restore_current_blog(); + wp_cache_set( $id."-".$key."-blog_option", '', 'site-options' ); +} + +/** + * Update an option for a particular blog. + * + * @since MU + * + * @param int $id The blog id + * @param string $key The option key + * @param mixed $value The option value + */ +function update_blog_option( $id, $key, $value, $deprecated = null ) { + $id = (int) $id; + + if ( null !== $deprecated ) + _deprecated_argument( __FUNCTION__, '3.1' ); + + switch_to_blog($id); + update_option( $key, $value ); + restore_current_blog(); + + refresh_blog_details( $id ); + + wp_cache_set( $id."-".$key."-blog_option", $value, 'site-options'); +} + +/** + * Switch the current blog. + * + * This function is useful if you need to pull posts, or other information, + * from other blogs. You can switch back afterwards using restore_current_blog(). + * + * Things that aren't switched: + * - autoloaded options. See #14992 + * - plugins. See #14941 + * + * @see restore_current_blog() + * @since MU + * + * @param int $new_blog The id of the blog you want to switch to. Default: current blog + * @param bool $validate Whether to check if $new_blog exists before proceeding + * @return bool True on success, False if the validation failed + */ +function switch_to_blog( $new_blog, $validate = false ) { + global $wpdb, $table_prefix, $blog_id, $switched, $switched_stack, $wp_roles, $wp_object_cache; + + if ( empty($new_blog) ) + $new_blog = $blog_id; + + if ( $validate && ! get_blog_details( $new_blog ) ) + return false; + + if ( empty($switched_stack) ) + $switched_stack = array(); + + $switched_stack[] = $blog_id; + + /* If we're switching to the same blog id that we're on, + * set the right vars, do the associated actions, but skip + * the extra unnecessary work */ + if ( $blog_id == $new_blog ) { + do_action( 'switch_blog', $blog_id, $blog_id ); + $switched = true; + return true; + } + + $wpdb->set_blog_id($new_blog); + $table_prefix = $wpdb->prefix; + $prev_blog_id = $blog_id; + $blog_id = $new_blog; + + if ( is_object( $wp_roles ) ) { + $wpdb->suppress_errors(); + if ( method_exists( $wp_roles ,'_init' ) ) + $wp_roles->_init(); + elseif ( method_exists( $wp_roles, '__construct' ) ) + $wp_roles->__construct(); + $wpdb->suppress_errors( false ); + } + + if ( did_action('init') ) { + $current_user = wp_get_current_user(); + if ( is_object( $current_user ) ) + $current_user->for_blog( $blog_id ); + } + + if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) + $global_groups = $wp_object_cache->global_groups; + else + $global_groups = false; + + wp_cache_init(); + if ( function_exists('wp_cache_add_global_groups') ) { + if ( is_array( $global_groups ) ) + wp_cache_add_global_groups( $global_groups ); + else + wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) ); + wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' )); + } + + do_action('switch_blog', $blog_id, $prev_blog_id); + $switched = true; + return true; +} + +/** + * Restore the current blog, after calling switch_to_blog() + * + * @see switch_to_blog() + * @since MU + * + * @return bool True on success, False if we're already on the current blog + */ +function restore_current_blog() { + global $table_prefix, $wpdb, $blog_id, $switched, $switched_stack, $wp_roles, $wp_object_cache; + + if ( !$switched ) + return false; + + if ( !is_array( $switched_stack ) ) + return false; + + $blog = array_pop( $switched_stack ); + if ( $blog_id == $blog ) { + do_action( 'switch_blog', $blog, $blog ); + /* If we still have items in the switched stack, consider ourselves still 'switched' */ + $switched = ( is_array( $switched_stack ) && count( $switched_stack ) > 0 ); + return true; + } + + $wpdb->set_blog_id($blog); + $prev_blog_id = $blog_id; + $blog_id = $blog; + $table_prefix = $wpdb->prefix; + + if ( is_object( $wp_roles ) ) { + $wpdb->suppress_errors(); + if ( method_exists( $wp_roles ,'_init' ) ) + $wp_roles->_init(); + elseif ( method_exists( $wp_roles, '__construct' ) ) + $wp_roles->__construct(); + $wpdb->suppress_errors( false ); + } + + if ( did_action('init') ) { + $current_user = wp_get_current_user(); + if ( is_object( $current_user ) ) + $current_user->for_blog( $blog_id ); + } + + if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) + $global_groups = $wp_object_cache->global_groups; + else + $global_groups = false; + + wp_cache_init(); + if ( function_exists('wp_cache_add_global_groups') ) { + if ( is_array( $global_groups ) ) + wp_cache_add_global_groups( $global_groups ); + else + wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) ); + wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' )); + } + + do_action('switch_blog', $blog_id, $prev_blog_id); + + /* If we still have items in the switched stack, consider ourselves still 'switched' */ + $switched = ( is_array( $switched_stack ) && count( $switched_stack ) > 0 ); + return true; +} + +/** + * Check if a particular blog is archived. + * + * @since MU + * + * @param int $id The blog id + * @return string Whether the blog is archived or not + */ +function is_archived( $id ) { + return get_blog_status($id, 'archived'); +} + +/** + * Update the 'archived' status of a particular blog. + * + * @since MU + * + * @param int $id The blog id + * @param string $archived The new status + * @return string $archived + */ +function update_archived( $id, $archived ) { + update_blog_status($id, 'archived', $archived); + return $archived; +} + +/** + * Update a blog details field. + * + * @since MU + * + * @param int $blog_id BLog ID + * @param string $pref A field name + * @param string $value Value for $pref + * @return string $value + */ +function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) { + global $wpdb; + + if ( null !== $deprecated ) + _deprecated_argument( __FUNCTION__, '3.1' ); + + if ( !in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) ) + return $value; + + $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) ); + + refresh_blog_details($blog_id); + + if ( 'spam' == $pref ) + ( $value == 1 ) ? do_action( 'make_spam_blog', $blog_id ) : do_action( 'make_ham_blog', $blog_id ); + elseif ( 'mature' == $pref ) + ( $value == 1 ) ? do_action( 'mature_blog', $blog_id ) : do_action( 'unmature_blog', $blog_id ); + elseif ( 'archived' == $pref ) + ( $value == 1 ) ? do_action( 'archive_blog', $blog_id ) : do_action( 'unarchive_blog', $blog_id ); + elseif ( 'archived' == $pref ) + ( $value == 1 ) ? do_action( 'archive_blog', $blog_id ) : do_action( 'unarchive_blog', $blog_id ); + + return $value; +} + +/** + * Get a blog details field. + * + * @since MU + * + * @param int $id The blog id + * @param string $pref A field name + * @return bool $value + */ +function get_blog_status( $id, $pref ) { + global $wpdb; + + $details = get_blog_details( $id, false ); + if ( $details ) + return $details->$pref; + + return $wpdb->get_var( $wpdb->prepare("SELECT %s FROM {$wpdb->blogs} WHERE blog_id = %d", $pref, $id) ); +} + +/** + * Get a list of most recently updated blogs. + * + * @since MU + * + * @param mixed $deprecated Not used + * @param int $start The offset + * @param int $quantity The maximum number of blogs to retrieve. Default is 40. + * @return array The list of blogs + */ +function get_last_updated( $deprecated = '', $start = 0, $quantity = 40 ) { + global $wpdb; + + if ( ! empty( $deprecated ) ) + _deprecated_argument( __FUNCTION__, 'MU' ); // never used + + return $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' AND last_updated != '0000-00-00 00:00:00' ORDER BY last_updated DESC limit %d, %d", $wpdb->siteid, $start, $quantity ) , ARRAY_A ); +} + +?> diff --git a/src/wp-includes/ms-default-constants.php b/src/wp-includes/ms-default-constants.php new file mode 100644 index 00000000..12dc661a --- /dev/null +++ b/src/wp-includes/ms-default-constants.php @@ -0,0 +1,140 @@ +blogid}/files/" ); + if ( 'wp-content/blogs.dir' == UPLOADBLOGSDIR ) + define( 'BLOGUPLOADDIR', WP_CONTENT_DIR . "/blogs.dir/{$wpdb->blogid}/files/" ); + } +} + +/** + * Defines Multisite cookie constants. + * + * @since 3.0.0 + */ +function ms_cookie_constants( ) { + global $current_site; + + /** + * @since 1.2.0 + */ + if ( !defined( 'COOKIEPATH' ) ) + define( 'COOKIEPATH', $current_site->path ); + + /** + * @since 1.5.0 + */ + if ( !defined( 'SITECOOKIEPATH' ) ) + define( 'SITECOOKIEPATH', $current_site->path ); + + /** + * @since 2.6.0 + */ + if ( !defined( 'ADMIN_COOKIE_PATH' ) ) { + if( !is_subdomain_install() ) { + define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH ); + } else { + define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH . 'wp-admin' ); + } + } + + /** + * @since 2.0.0 + */ + if ( !defined('COOKIE_DOMAIN') && is_subdomain_install() ) { + if ( !empty( $current_site->cookie_domain ) ) + define('COOKIE_DOMAIN', '.' . $current_site->cookie_domain); + else + define('COOKIE_DOMAIN', '.' . $current_site->domain); + } +} + +/** + * Defines Multisite file constants. + * + * @since 3.0.0 + */ +function ms_file_constants( ) { + /** + * Optional support for X-Sendfile header + * @since 3.0.0 + */ + if ( !defined( 'WPMU_SENDFILE' ) ) + define( 'WPMU_SENDFILE', false ); + + /** + * Optional support for X-Accel-Redirect header + * @since 3.0.0 + */ + if ( !defined( 'WPMU_ACCEL_REDIRECT' ) ) + define( 'WPMU_ACCEL_REDIRECT', false ); +} + +/** + * Defines Multisite subdomain constants and handles warnings and notices. + * + * VHOST is deprecated in favor of SUBDOMAIN_INSTALL, which is a bool. + * + * On first call, the constants are checked and defined. On second call, + * we will have translations loaded and can trigger warnings easily. + * + * @since 3.0.0 + */ +function ms_subdomain_constants() { + static $error = null; + static $error_warn = false; + + if ( false === $error ) + return; + + if ( $error ) { + $vhost_deprecated = __( 'The constant VHOST is deprecated. Use the boolean constant SUBDOMAIN_INSTALL in wp-config.php to enable a subdomain configuration. Use is_subdomain_install() to check whether a subdomain configuration is enabled.' ); + if ( $error_warn ) { + trigger_error( __( 'Conflicting values for the constants VHOST and SUBDOMAIN_INSTALL. The value of SUBDOMAIN_INSTALL will be assumed to be your subdomain configuration setting.' ) . ' ' . $vhost_deprecated, E_USER_WARNING ); + } else { + _deprecated_argument( 'define()', '3.0', $vhost_deprecated ); + } + return; + } + + if ( defined( 'SUBDOMAIN_INSTALL' ) && defined( 'VHOST' ) ) { + if ( SUBDOMAIN_INSTALL == ( 'yes' == VHOST ) ) { + $error = true; + } else { + $error = $error_warn = true; + } + } elseif ( defined( 'SUBDOMAIN_INSTALL' ) ) { + define( 'VHOST', SUBDOMAIN_INSTALL ? 'yes' : 'no' ); + } elseif ( defined( 'VHOST' ) ) { + $error = true; + define( 'SUBDOMAIN_INSTALL', 'yes' == VHOST ); + } else { + define( 'SUBDOMAIN_INSTALL', false ); + define( 'VHOST', 'no' ); + } +} +add_action( 'init', 'ms_subdomain_constants' ); + +?> diff --git a/src/wp-includes/ms-default-filters.php b/src/wp-includes/ms-default-filters.php new file mode 100644 index 00000000..e533252f --- /dev/null +++ b/src/wp-includes/ms-default-filters.php @@ -0,0 +1,66 @@ + diff --git a/src/wp-includes/ms-deprecated.php b/src/wp-includes/ms-deprecated.php new file mode 100644 index 00000000..a7f7eb23 --- /dev/null +++ b/src/wp-includes/ms-deprecated.php @@ -0,0 +1,203 @@ +ID ) ) + return false; + $user_id = $user->ID; + } + + return is_super_admin( $user_id ); +} + +if ( !function_exists( 'graceful_fail' ) ) : +/** + * @since MU + * @deprecated 3.0.0 + * @deprecated Use wp_die() + * @see wp_die() + */ +function graceful_fail( $message ) { + _deprecated_function( __FUNCTION__, '3.0', 'wp_die()' ); + $message = apply_filters( 'graceful_fail', $message ); + $message_template = apply_filters( 'graceful_fail_template', +' + + +Error! + + + +

    %s

    + +' ); + die( sprintf( $message_template, $message ) ); +} +endif; + +/** + * @since MU + * @deprecated 3.0.0 + * @deprecated Use get_user_by() + * @see get_user_by() + */ +function get_user_details( $username ) { + _deprecated_function( __FUNCTION__, '3.0', 'get_user_by()' ); + return get_user_by('login', $username); +} + +/** + * @since MU + * @deprecated 3.0.0 + * @deprecated Use clean_post_cache() + * @see clean_post_cache() + */ +function clear_global_post_cache( $post_id ) { + _deprecated_function( __FUNCTION__, '3.0', 'clean_post_cache()' ); +} + +/** + * @since MU + * @deprecated 3.0.0 + * @deprecated Use is_main_site() + * @see is_main_site() + */ +function is_main_blog() { + _deprecated_function( __FUNCTION__, '3.0', 'is_main_site()' ); + return is_main_site(); +} + +/** + * @since MU + * @deprecated 3.0.0 + * @deprecated Use is_email() + * @see is_email() + */ +function validate_email( $email, $check_domain = true) { + _deprecated_function( __FUNCTION__, '3.0', 'is_email()' ); + return is_email( $email, $check_domain ); +} + +/** + * @since MU + * @deprecated 3.0.0 + * @deprecated No alternative available. For performance reasons this function is not recommended. + */ +function get_blog_list( $start = 0, $num = 10, $deprecated = '' ) { + _deprecated_function( __FUNCTION__, '3.0' ); + + global $wpdb; + $blogs = $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", $wpdb->siteid), ARRAY_A ); + + foreach ( (array) $blogs as $details ) { + $blog_list[ $details['blog_id'] ] = $details; + $blog_list[ $details['blog_id'] ]['postcount'] = $wpdb->get_var( "SELECT COUNT(ID) FROM " . $wpdb->get_blog_prefix( $details['blog_id'] ). "posts WHERE post_status='publish' AND post_type='post'" ); + } + unset( $blogs ); + $blogs = $blog_list; + + if ( false == is_array( $blogs ) ) + return array(); + + if ( $num == 'all' ) + return array_slice( $blogs, $start, count( $blogs ) ); + else + return array_slice( $blogs, $start, $num ); +} + +/** + * @since MU + * @deprecated 3.0.0 + * @deprecated No alternative available. For performance reasons this function is not recommended. + */ +function get_most_active_blogs( $num = 10, $display = true ) { + _deprecated_function( __FUNCTION__, '3.0' ); + + $blogs = get_blog_list( 0, 'all', false ); // $blog_id -> $details + if ( is_array( $blogs ) ) { + reset( $blogs ); + foreach ( (array) $blogs as $key => $details ) { + $most_active[ $details['blog_id'] ] = $details['postcount']; + $blog_list[ $details['blog_id'] ] = $details; // array_slice() removes keys!! + } + arsort( $most_active ); + reset( $most_active ); + foreach ( (array) $most_active as $key => $details ) + $t[ $key ] = $blog_list[ $key ]; + + unset( $most_active ); + $most_active = $t; + } + + if ( $display == true ) { + if ( is_array( $most_active ) ) { + reset( $most_active ); + foreach ( (array) $most_active as $key => $details ) { + $url = esc_url('http://' . $details['domain'] . $details['path']); + echo '
  • ' . $details['postcount'] . " $url
  • "; + } + } + } + return array_slice( $most_active, 0, $num ); +} +?> diff --git a/src/wp-includes/ms-files.php b/src/wp-includes/ms-files.php new file mode 100644 index 00000000..5ec6d1dd --- /dev/null +++ b/src/wp-includes/ms-files.php @@ -0,0 +1,83 @@ +archived == '1' || $current_blog->spam == '1' || $current_blog->deleted == '1' ) { + status_header( 404 ); + die( '404 — File not found.' ); +} + +$file = BLOGUPLOADDIR . str_replace( '..', '', $_GET[ 'file' ] ); +if ( !is_file( $file ) ) { + status_header( 404 ); + die( '404 — File not found.' ); +} + +$mime = wp_check_filetype( $file ); +if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) ) + $mime[ 'type' ] = mime_content_type( $file ); + +if( $mime[ 'type' ] ) + $mimetype = $mime[ 'type' ]; +else + $mimetype = 'image/' . substr( $file, strrpos( $file, '.' ) + 1 ); + +header( 'Content-type: ' . $mimetype ); // always send this +if ( false === strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) ) + header( 'Content-Length: ' . filesize( $file ) ); + +// Optional support for X-Sendfile and X-Accel-Redirect +if ( WPMU_ACCEL_REDIRECT ) { + header( 'X-Accel-Redirect: ' . str_replace( WP_CONTENT_DIR, '', $file ) ); + exit; +} elseif ( WPMU_SENDFILE ) { + header( 'X-Sendfile: ' . $file ); + exit; +} + +$last_modified = gmdate( 'D, d M Y H:i:s', filemtime( $file ) ); +$etag = '"' . md5( $last_modified ) . '"'; +header( "Last-Modified: $last_modified GMT" ); +header( 'ETag: ' . $etag ); +header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 100000000 ) . ' GMT' ); + +// Support for Conditional GET +$client_etag = isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ? stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) : false; + +if( ! isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) + $_SERVER['HTTP_IF_MODIFIED_SINCE'] = false; + +$client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ); +// If string is empty, return 0. If not, attempt to parse into a timestamp +$client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0; + +// Make a timestamp for our most recent modification... +$modified_timestamp = strtotime($last_modified); + +if ( ( $client_last_modified && $client_etag ) + ? ( ( $client_modified_timestamp >= $modified_timestamp) && ( $client_etag == $etag ) ) + : ( ( $client_modified_timestamp >= $modified_timestamp) || ( $client_etag == $etag ) ) + ) { + status_header( 304 ); + exit; +} + +// If we made it this far, just serve the file +readfile( $file ); +?> diff --git a/src/wp-includes/ms-functions.php b/src/wp-includes/ms-functions.php new file mode 100644 index 00000000..16f5a05a --- /dev/null +++ b/src/wp-includes/ms-functions.php @@ -0,0 +1,2076 @@ +siteid; + else + $site_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->site WHERE domain = %s AND path = %s", $sitedomain, $path ) ); + + if ( $site_id ) + return $wpdb->get_results( $wpdb->prepare( "SELECT u.ID, u.user_login, u.user_pass FROM $wpdb->users AS u, $wpdb->sitemeta AS sm WHERE sm.meta_key = 'admin_user_id' AND u.ID = sm.meta_value AND sm.site_id = %d", $site_id ), ARRAY_A ); + + return false; +} + +/** + * Get one of a user's active blogs + * + * Returns the user's primary blog, if she has one and + * it is active. If it's inactive, function returns another + * active blog of the user. If none are found, the user + * is added as a Subscriber to the Dashboard Blog and that blog + * is returned. + * + * @since MU 1.0 + * @uses get_blogs_of_user() + * @uses add_user_to_blog() + * @uses get_blog_details() + * + * @param int $user_id The unique ID of the user + * @return object The blog object + */ +function get_active_blog_for_user( $user_id ) { + global $wpdb; + $blogs = get_blogs_of_user( $user_id ); + if ( empty( $blogs ) ) + return null; + + if ( !is_multisite() ) + return $blogs[$wpdb->blogid]; + + $primary_blog = get_user_meta( $user_id, 'primary_blog', true ); + $first_blog = current($blogs); + if ( false !== $primary_blog ) { + if ( ! isset( $blogs[ $primary_blog ] ) ) { + update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id ); + $primary = $first_blog; + } else { + $primary = get_blog_details( $primary_blog ); + } + } else { + //TODO Review this call to add_user_to_blog too - to get here the user must have a role on this blog? + add_user_to_blog( $first_blog->userblog_id, $user_id, 'subscriber' ); + update_user_meta( $user_id, 'primary_blog', $first_blog->userblog_id ); + $primary = $first_blog; + } + + if ( ( ! is_object( $primary ) ) || ( is_object( $primary ) && $primary->archived == 1 || $primary->spam == 1 || $primary->deleted == 1 ) ) { + $blogs = get_blogs_of_user( $user_id, true ); // if a user's primary blog is shut down, check their other blogs. + $ret = false; + if ( is_array( $blogs ) && count( $blogs ) > 0 ) { + foreach ( (array) $blogs as $blog_id => $blog ) { + if ( $blog->site_id != $wpdb->siteid ) + continue; + $details = get_blog_details( $blog_id ); + if ( is_object( $details ) && $details->archived == 0 && $details->spam == 0 && $details->deleted == 0 ) { + $ret = $blog; + if ( get_user_meta( $user_id , 'primary_blog', true ) != $blog_id ) + update_user_meta( $user_id, 'primary_blog', $blog_id ); + if ( !get_user_meta($user_id , 'source_domain', true) ) + update_user_meta( $user_id, 'source_domain', $blog->domain ); + break; + } + } + } else { + return null; + } + return $ret; + } else { + return $primary; + } +} + +/** + * Find out whether a user is a member of a given blog. + * + * @since MU 1.1 + * @uses get_blogs_of_user() + * + * @param int $user_id The unique ID of the user + * @param int $blog Optional. If no blog_id is provided, current site is used + * @return bool + */ +function is_user_member_of_blog( $user_id, $blog_id = 0 ) { + $user_id = (int) $user_id; + $blog_id = (int) $blog_id; + + if ( $blog_id == 0 ) { + global $wpdb; + $blog_id = $wpdb->blogid; + } + + $blogs = get_blogs_of_user( $user_id ); + if ( is_array( $blogs ) ) + return array_key_exists( $blog_id, $blogs ); + else + return false; +} + +/** + * The number of active users in your installation. + * + * The count is cached and updated twice daily. This is not a live count. + * + * @since MU 2.7 + * + * @return int + */ +function get_user_count() { + return get_site_option( 'user_count' ); +} + +/** + * The number of active sites on your installation. + * + * The count is cached and updated twice daily. This is not a live count. + * + * @since MU 1.0 + * + * @param int $id Optional. A site_id. + * @return int + */ +function get_blog_count( $id = 0 ) { + return get_site_option( 'blog_count' ); +} + +/** + * Get a blog post from any site on the network. + * + * @since MU 1.0 + * + * @param int $blog_id ID of the blog. + * @param int $post_id ID of the post you're looking for. + * @return object The post. + */ +function get_blog_post( $blog_id, $post_id ) { + global $wpdb; + + $key = $blog_id . '-' . $post_id; + $post = wp_cache_get( $key, 'global-posts' ); + if ( $post == false ) { + $post = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->get_blog_prefix( $blog_id ) . 'posts WHERE ID = %d', $post_id ) ); + wp_cache_add( $key, $post, 'global-posts' ); + } + + return $post; +} + +/** + * Add a user to a blog. + * + * Use the 'add_user_to_blog' action to fire an event when + * users are added to a blog. + * + * @since MU 1.0 + * + * @param int $blog_id ID of the blog you're adding the user to. + * @param int $user_id ID of the user you're adding. + * @param string $role The role you want the user to have + * @return bool + */ +function add_user_to_blog( $blog_id, $user_id, $role ) { + switch_to_blog($blog_id); + + $user = new WP_User($user_id); + + if ( empty( $user->ID ) ) { + restore_current_blog(); + return new WP_Error('user_does_not_exist', __('That user does not exist.')); + } + + if ( !get_user_meta($user_id, 'primary_blog', true) ) { + update_user_meta($user_id, 'primary_blog', $blog_id); + $details = get_blog_details($blog_id); + update_user_meta($user_id, 'source_domain', $details->domain); + } + + $user->set_role($role); + + do_action('add_user_to_blog', $user_id, $role, $blog_id); + wp_cache_delete( $user_id, 'users' ); + restore_current_blog(); + return true; +} + +/** + * Remove a user from a blog. + * + * Use the 'remove_user_from_blog' action to fire an event when + * users are removed from a blog. + * + * Accepts an optional $reassign parameter, if you want to + * reassign the user's blog posts to another user upon removal. + * + * @since MU 1.0 + * + * @param int $user_id ID of the user you're removing. + * @param int $blog_id ID of the blog you're removing the user from. + * @param string $reassign Optional. A user to whom to reassign posts. + * @return bool + */ +function remove_user_from_blog($user_id, $blog_id = '', $reassign = '') { + global $wpdb; + switch_to_blog($blog_id); + $user_id = (int) $user_id; + do_action('remove_user_from_blog', $user_id, $blog_id); + + // If being removed from the primary blog, set a new primary if the user is assigned + // to multiple blogs. + $primary_blog = get_user_meta($user_id, 'primary_blog', true); + if ( $primary_blog == $blog_id ) { + $new_id = ''; + $new_domain = ''; + $blogs = get_blogs_of_user($user_id); + foreach ( (array) $blogs as $blog ) { + if ( $blog->userblog_id == $blog_id ) + continue; + $new_id = $blog->userblog_id; + $new_domain = $blog->domain; + break; + } + + update_user_meta($user_id, 'primary_blog', $new_id); + update_user_meta($user_id, 'source_domain', $new_domain); + } + + // wp_revoke_user($user_id); + $user = new WP_User($user_id); + if ( empty( $user->ID ) ) { + restore_current_blog(); + return new WP_Error('user_does_not_exist', __('That user does not exist.')); + } + + $user->remove_all_caps(); + + $blogs = get_blogs_of_user($user_id); + if ( count($blogs) == 0 ) { + update_user_meta($user_id, 'primary_blog', ''); + update_user_meta($user_id, 'source_domain', ''); + } + + if ( $reassign != '' ) { + $reassign = (int) $reassign; + $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_author = %d WHERE post_author = %d", $reassign, $user_id) ); + $wpdb->query( $wpdb->prepare("UPDATE $wpdb->links SET link_owner = %d WHERE link_owner = %d", $reassign, $user_id) ); + } + + restore_current_blog(); +} + +/** + * Create an empty blog. + * + * @since MU 1.0 + * @uses install_blog() + * + * @param string $domain The new blog's domain. + * @param string $path The new blog's path. + * @param string $string The new blog's title. + * @param int $site Optional. Defaults to 1. + * @return int The ID of the newly created blog + */ +function create_empty_blog( $domain, $path, $weblog_title, $site_id = 1 ) { + $domain = addslashes( $domain ); + $weblog_title = addslashes( $weblog_title ); + + if ( empty($path) ) + $path = '/'; + + // Check if the domain has been used already. We should return an error message. + if ( domain_exists($domain, $path, $site_id) ) + return __( 'Error: Site URL already taken.' ); + + // Need to back up wpdb table names, and create a new wp_blogs entry for new blog. + // Need to get blog_id from wp_blogs, and create new table names. + // Must restore table names at the end of function. + + if ( ! $blog_id = insert_blog($domain, $path, $site_id) ) + return __( 'Error: problem creating site entry.' ); + + switch_to_blog($blog_id); + install_blog($blog_id); + restore_current_blog(); + + return $blog_id; +} + +/** + * Get the permalink for a post on another blog. + * + * @since MU 1.0 + * + * @param int $_blog_id ID of the source blog. + * @param int $post_id ID of the desired post. + * @return string The post's permalink + */ +function get_blog_permalink( $_blog_id, $post_id ) { + $key = "{$_blog_id}-{$post_id}-blog_permalink"; + $link = wp_cache_get( $key, 'site-options' ); + if ( $link == false ) { + switch_to_blog( $_blog_id ); + $link = get_permalink( $post_id ); + restore_current_blog(); + wp_cache_add( $key, $link, 'site-options', 360 ); + } + return $link; +} + +/** + * Get a blog's numeric ID from its URL. + * + * On a subdirectory installation like example.com/blog1/, + * $domain will be the root 'example.com' and $path the + * subdirectory '/blog1/'. With subdomains like blog1.example.com, + * $domain is 'blog1.example.com' and $path is '/'. + * + * @since MU 2.6.5 + * + * @param string $domain + * @param string $path Optional. Not required for subdomain installations. + * @return int + */ +function get_blog_id_from_url( $domain, $path = '/' ) { + global $wpdb; + + $domain = strtolower( $wpdb->escape( $domain ) ); + $path = strtolower( $wpdb->escape( $path ) ); + $id = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' ); + + if ( $id == -1 ) { // blog does not exist + return 0; + } elseif ( $id ) { + return (int)$id; + } + + $id = $wpdb->get_var( "SELECT blog_id FROM $wpdb->blogs WHERE domain = '$domain' and path = '$path' /* get_blog_id_from_url */" ); + + if ( !$id ) { + wp_cache_set( md5( $domain . $path ), -1, 'blog-id-cache' ); + return false; + } + wp_cache_set( md5( $domain . $path ), $id, 'blog-id-cache' ); + + return $id; +} + +// Admin functions + +/** + * Redirect a user based on $_GET or $_POST arguments. + * + * The function looks for redirect arguments in the following order: + * 1) $_GET['ref'] + * 2) $_POST['ref'] + * 3) $_SERVER['HTTP_REFERER'] + * 4) $_GET['redirect'] + * 5) $_POST['redirect'] + * 6) $url + * + * @since MU + * @uses wpmu_admin_redirect_add_updated_param() + * + * @param string $url + */ +function wpmu_admin_do_redirect( $url = '' ) { + $ref = ''; + if ( isset( $_GET['ref'] ) ) + $ref = $_GET['ref']; + if ( isset( $_POST['ref'] ) ) + $ref = $_POST['ref']; + + if ( $ref ) { + $ref = wpmu_admin_redirect_add_updated_param( $ref ); + wp_redirect( $ref ); + exit(); + } + if ( empty( $_SERVER['HTTP_REFERER'] ) == false ) { + wp_redirect( $_SERVER['HTTP_REFERER'] ); + exit(); + } + + $url = wpmu_admin_redirect_add_updated_param( $url ); + if ( isset( $_GET['redirect'] ) ) { + if ( substr( $_GET['redirect'], 0, 2 ) == 's_' ) + $url .= '&action=blogs&s='. esc_html( substr( $_GET['redirect'], 2 ) ); + } elseif ( isset( $_POST['redirect'] ) ) { + $url = wpmu_admin_redirect_add_updated_param( $_POST['redirect'] ); + } + wp_redirect( $url ); + exit(); +} + +/** + * Adds an 'updated=true' argument to a URL. + * + * @since MU + * + * @param string $url + * @return string + */ +function wpmu_admin_redirect_add_updated_param( $url = '' ) { + if ( strpos( $url, 'updated=true' ) === false ) { + if ( strpos( $url, '?' ) === false ) + return $url . '?updated=true'; + else + return $url . '&updated=true'; + } + return $url; +} + +/** + * Checks an email address against a list of banned domains. + * + * This function checks against the Banned Email Domains list + * at wp-admin/network/settings.php. The check is only run on + * self-registrations; user creation at wp-admin/network/users.php + * bypasses this check. + * + * @since MU + * + * @param string $user_email The email provided by the user at registration. + * @return bool Returns true when the email address is banned. + */ +function is_email_address_unsafe( $user_email ) { + $banned_names = get_site_option( 'banned_email_domains' ); + if ($banned_names && !is_array( $banned_names )) + $banned_names = explode( "\n", $banned_names); + + if ( is_array( $banned_names ) && empty( $banned_names ) == false ) { + $email_domain = strtolower( substr( $user_email, 1 + strpos( $user_email, '@' ) ) ); + foreach ( (array) $banned_names as $banned_domain ) { + if ( $banned_domain == '' ) + continue; + if ( + strstr( $email_domain, $banned_domain ) || + ( + strstr( $banned_domain, '/' ) && + preg_match( $banned_domain, $email_domain ) + ) + ) + return true; + } + } + return false; +} + +/** + * Processes new user registrations. + * + * Checks the data provided by the user during signup. Verifies + * the validity and uniqueness of user names and user email addresses, + * and checks email addresses against admin-provided domain + * whitelists and blacklists. + * + * The hook 'wpmu_validate_user_signup' provides an easy way + * to modify the signup process. The value $result, which is passed + * to the hook, contains both the user-provided info and the error + * messages created by the function. 'wpmu_validate_user_signup' allows + * you to process the data in any way you'd like, and unset the + * relevant errors if necessary. + * + * @since MU + * @uses is_email_address_unsafe() + * @uses username_exists() + * @uses email_exists() + * + * @param string $user_name The login name provided by the user. + * @param string $user_email The email provided by the user. + * @return array Contains username, email, and error messages. + */ +function wpmu_validate_user_signup($user_name, $user_email) { + global $wpdb; + + $errors = new WP_Error(); + + $orig_username = $user_name; + $user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) ); + $maybe = array(); + preg_match( '/[a-z0-9]+/', $user_name, $maybe ); + + if ( $user_name != $orig_username || $user_name != $maybe[0] ) { + $errors->add( 'user_name', __( 'Only lowercase letters (a-z) and numbers are allowed.' ) ); + $user_name = $orig_username; + } + + $user_email = sanitize_email( $user_email ); + + if ( empty( $user_name ) ) + $errors->add('user_name', __('Please enter a username')); + + $illegal_names = get_site_option( 'illegal_names' ); + if ( is_array( $illegal_names ) == false ) { + $illegal_names = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' ); + add_site_option( 'illegal_names', $illegal_names ); + } + if ( in_array( $user_name, $illegal_names ) == true ) + $errors->add('user_name', __('That username is not allowed')); + + if ( is_email_address_unsafe( $user_email ) ) + $errors->add('user_email', __('You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider.')); + + if ( strlen( $user_name ) < 4 ) + $errors->add('user_name', __('Username must be at least 4 characters')); + + if ( strpos( ' ' . $user_name, '_' ) != false ) + $errors->add( 'user_name', __( 'Sorry, usernames may not contain the character “_”!' ) ); + + // all numeric? + $match = array(); + preg_match( '/[0-9]*/', $user_name, $match ); + if ( $match[0] == $user_name ) + $errors->add('user_name', __('Sorry, usernames must have letters too!')); + + if ( !is_email( $user_email ) ) + $errors->add('user_email', __('Please enter a correct email address')); + + $limited_email_domains = get_site_option( 'limited_email_domains' ); + if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) == false ) { + $emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) ); + if ( in_array( $emaildomain, $limited_email_domains ) == false ) + $errors->add('user_email', __('Sorry, that email address is not allowed!')); + } + + // Check if the username has been used already. + if ( username_exists($user_name) ) + $errors->add('user_name', __('Sorry, that username already exists!')); + + // Check if the email address has been used already. + if ( email_exists($user_email) ) + $errors->add('user_email', __('Sorry, that email address is already used!')); + + // Has someone already signed up for this username? + $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name) ); + if ( $signup != null ) { + $registered_at = mysql2date('U', $signup->registered); + $now = current_time( 'timestamp', true ); + $diff = $now - $registered_at; + // If registered more than two days ago, cancel registration and let this signup go through. + if ( $diff > 172800 ) + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE user_login = %s", $user_name) ); + else + $errors->add('user_name', __('That username is currently reserved but may be available in a couple of days.')); + + if ( $signup->active == 0 && $signup->user_email == $user_email ) + $errors->add('user_email_used', __('username and email used')); + } + + $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_email = %s", $user_email) ); + if ( $signup != null ) { + $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered); + // If registered more than two days ago, cancel registration and let this signup go through. + if ( $diff > 172800 ) + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE user_email = %s", $user_email) ); + else + $errors->add('user_email', __('That email address has already been used. Please check your inbox for an activation email. It will become available in a couple of days if you do nothing.')); + } + + $result = array('user_name' => $user_name, 'orig_username' => $orig_username, 'user_email' => $user_email, 'errors' => $errors); + + return apply_filters('wpmu_validate_user_signup', $result); +} + +/** + * Processes new site registrations. + * + * Checks the data provided by the user during blog signup. Verifies + * the validity and uniqueness of blog paths and domains. + * + * This function prevents the current user from registering a new site + * with a blogname equivalent to another user's login name. Passing the + * $user parameter to the function, where $user is the other user, is + * effectively an override of this limitation. + * + * Filter 'wpmu_validate_blog_signup' if you want to modify + * the way that WordPress validates new site signups. + * + * @since MU + * @uses domain_exists() + * @uses username_exists() + * + * @param string $blogname The blog name provided by the user. Must be unique. + * @param string $blog_title The blog title provided by the user. + * @return array Contains the new site data and error messages. + */ +function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') { + global $wpdb, $domain, $base, $current_site; + + $blog_title = strip_tags( $blog_title ); + $blog_title = substr( $blog_title, 0, 50 ); + + $errors = new WP_Error(); + $illegal_names = get_site_option( 'illegal_names' ); + if ( $illegal_names == false ) { + $illegal_names = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' ); + add_site_option( 'illegal_names', $illegal_names ); + } + + // On sub dir installs, Some names are so illegal, only a filter can spring them from jail + if (! is_subdomain_install() ) + $illegal_names = array_merge($illegal_names, apply_filters( 'subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' ) ) ); + + + if ( empty( $blogname ) ) + $errors->add('blogname', __('Please enter a site name')); + + $maybe = array(); + preg_match( '/[a-z0-9]+/', $blogname, $maybe ); + if ( $blogname != $maybe[0] ) + $errors->add('blogname', __('Only lowercase letters and numbers allowed')); + + if ( in_array( $blogname, $illegal_names ) == true ) + $errors->add('blogname', __('That name is not allowed')); + + if ( strlen( $blogname ) < 4 && !is_super_admin() ) + $errors->add('blogname', __('Site name must be at least 4 characters')); + + if ( strpos( ' ' . $blogname, '_' ) != false ) + $errors->add( 'blogname', __( 'Sorry, site names may not contain the character “_”!' ) ); + + // do not allow users to create a blog that conflicts with a page on the main blog. + if ( !is_subdomain_install() && $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM " . $wpdb->get_blog_prefix( $current_site->blog_id ) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname ) ) ) + $errors->add( 'blogname', __( 'Sorry, you may not use that site name.' ) ); + + // all numeric? + $match = array(); + preg_match( '/[0-9]*/', $blogname, $match ); + if ( $match[0] == $blogname ) + $errors->add('blogname', __('Sorry, site names must have letters too!')); + + $blogname = apply_filters( 'newblogname', $blogname ); + + $blog_title = stripslashes( $blog_title ); + + if ( empty( $blog_title ) ) + $errors->add('blog_title', __('Please enter a site title')); + + // Check if the domain/path has been used already. + if ( is_subdomain_install() ) { + $mydomain = $blogname . '.' . preg_replace( '|^www\.|', '', $domain ); + $path = $base; + } else { + $mydomain = "$domain"; + $path = $base.$blogname.'/'; + } + if ( domain_exists($mydomain, $path) ) + $errors->add('blogname', __('Sorry, that site already exists!')); + + if ( username_exists( $blogname ) ) { + if ( is_object( $user ) == false || ( is_object($user) && ( $user->user_login != $blogname ) ) ) + $errors->add( 'blogname', __( 'Sorry, that site is reserved!' ) ); + } + + // Has someone already signed up for this domain? + $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) ); // TODO: Check email too? + if ( ! empty($signup) ) { + $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered); + // If registered more than two days ago, cancel registration and let this signup go through. + if ( $diff > 172800 ) + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) ); + else + $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.')); + } + + $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors); + return apply_filters('wpmu_validate_blog_signup', $result); +} + +/** + * Record site signup information for future activation. + * + * @since MU + * @uses wpmu_signup_blog_notification() + * + * @param string $domain The requested domain. + * @param string $path The requested path. + * @param string $title The requested site title. + * @param string $user The user's requested login name. + * @param string $user_email The user's email address. + * @param array $meta By default, contains the requested privacy setting and lang_id. + */ +function wpmu_signup_blog($domain, $path, $title, $user, $user_email, $meta = '') { + global $wpdb; + + $key = substr( md5( time() . rand() . $domain ), 0, 16 ); + $meta = serialize($meta); + $domain = $wpdb->escape($domain); + $path = $wpdb->escape($path); + $title = $wpdb->escape($title); + + $wpdb->insert( $wpdb->signups, array( + 'domain' => $domain, + 'path' => $path, + 'title' => $title, + 'user_login' => $user, + 'user_email' => $user_email, + 'registered' => current_time('mysql', true), + 'activation_key' => $key, + 'meta' => $meta + ) ); + + wpmu_signup_blog_notification($domain, $path, $title, $user, $user_email, $key, $meta); +} + +/** + * Record user signup information for future activation. + * + * This function is used when user registration is open but + * new site registration is not. + * + * @since MU + * @uses wpmu_signup_user_notification() + * + * @param string $user The user's requested login name. + * @param string $user_email The user's email address. + * @param array $meta By default, this is an empty array. + */ +function wpmu_signup_user($user, $user_email, $meta = '') { + global $wpdb; + + // Format data + $user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) ); + $user_email = sanitize_email( $user_email ); + $key = substr( md5( time() . rand() . $user_email ), 0, 16 ); + $meta = serialize($meta); + + $wpdb->insert( $wpdb->signups, array( + 'domain' => '', + 'path' => '', + 'title' => '', + 'user_login' => $user, + 'user_email' => $user_email, + 'registered' => current_time('mysql', true), + 'activation_key' => $key, + 'meta' => $meta + ) ); + + wpmu_signup_user_notification($user, $user_email, $key, $meta); +} + +/** + * Notify user of signup success. + * + * This is the notification function used when site registration + * is enabled. + * + * Filter 'wpmu_signup_blog_notification' to bypass this function or + * replace it with your own notification behavior. + * + * Filter 'wpmu_signup_blog_notification_email' and + * 'wpmu_signup_blog_notification_email' to change the content + * and subject line of the email sent to newly registered users. + * + * @since MU + * + * @param string $domain The new blog domain. + * @param string $path The new blog path. + * @param string $title The site title. + * @param string $user The user's login name. + * @param string $user_email The user's email address. + * @param array $meta By default, contains the requested privacy setting and lang_id. + * @param string $key The activation key created in wpmu_signup_blog() + * @return bool + */ +function wpmu_signup_blog_notification($domain, $path, $title, $user, $user_email, $key, $meta = '') { + global $current_site; + + if ( !apply_filters('wpmu_signup_blog_notification', $domain, $path, $title, $user, $user_email, $key, $meta) ) + return false; + + // Send email with activation link. + if ( !is_subdomain_install() || $current_site->id != 1 ) + $activate_url = network_site_url("wp-activate.php?key=$key"); + else + $activate_url = "http://{$domain}{$path}wp-activate.php?key=$key"; // @todo use *_url() API + + $activate_url = esc_url($activate_url); + $admin_email = get_site_option( 'admin_email' ); + if ( $admin_email == '' ) + $admin_email = 'support@' . $_SERVER['SERVER_NAME']; + $from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) ); + $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; + $message = sprintf( + apply_filters( 'wpmu_signup_blog_notification_email', + __( "To activate your blog, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your site here:\n\n%s" ), + $domain, $path, $title, $user, $user_email, $key, $meta + ), + $activate_url, + esc_url( "http://{$domain}{$path}" ), + $key + ); + // TODO: Don't hard code activation link. + $subject = sprintf( + apply_filters( 'wpmu_signup_blog_notification_subject', + __( '[%1$s] Activate %2$s' ), + $domain, $path, $title, $user, $user_email, $key, $meta + ), + $from_name, + esc_url( 'http://' . $domain . $path ) + ); + wp_mail($user_email, $subject, $message, $message_headers); + return true; +} + +/** + * Notify user of signup success. + * + * This is the notification function used when no new site has + * been requested. + * + * Filter 'wpmu_signup_user_notification' to bypass this function or + * replace it with your own notification behavior. + * + * Filter 'wpmu_signup_user_notification_email' and + * 'wpmu_signup_user_notification_subject' to change the content + * and subject line of the email sent to newly registered users. + * + * @since MU + * + * @param string $user The user's login name. + * @param string $user_email The user's email address. + * @param array $meta By default, an empty array. + * @param string $key The activation key created in wpmu_signup_user() + * @return bool + */ +function wpmu_signup_user_notification($user, $user_email, $key, $meta = '') { + if ( !apply_filters('wpmu_signup_user_notification', $user, $user_email, $key, $meta) ) + return false; + + // Send email with activation link. + $admin_email = get_site_option( 'admin_email' ); + if ( $admin_email == '' ) + $admin_email = 'support@' . $_SERVER['SERVER_NAME']; + $from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) ); + $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; + $message = sprintf( + apply_filters( 'wpmu_signup_user_notification_email', + __( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\n" ), + $user, $user_email, $key, $meta + ), + site_url( "wp-activate.php?key=$key" ), + $key + ); + // TODO: Don't hard code activation link. + $subject = sprintf( + apply_filters( 'wpmu_signup_user_notification_subject', + __( '[%1$s] Activate %2$s' ), + $user, $user_email, $key, $meta + ), + $from_name, + $user + ); + wp_mail($user_email, $subject, $message, $message_headers); + return true; +} + +/** + * Activate a signup. + * + * Hook to 'wpmu_activate_user' or 'wpmu_activate_blog' for events + * that should happen only when users or sites are self-created (since + * those actions are not called when users and sites are created + * by a Super Admin). + * + * @since MU + * @uses wp_generate_password() + * @uses wpmu_welcome_user_notification() + * @uses add_user_to_blog() + * @uses add_new_user_to_blog() + * @uses wpmu_create_user() + * @uses wpmu_create_blog() + * @uses wpmu_welcome_notification() + * + * @param string $key The activation key provided to the user. + * @return array An array containing information about the activated user and/or blog + */ +function wpmu_activate_signup($key) { + global $wpdb, $current_site; + + $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key) ); + + if ( empty( $signup ) ) + return new WP_Error( 'invalid_key', __( 'Invalid activation key.' ) ); + + if ( $signup->active ) { + if ( empty( $signup->domain ) ) + return new WP_Error( 'already_active', __( 'The user is already active.' ), $signup ); + else + return new WP_Error( 'already_active', __( 'The site is already active.' ), $signup ); + } + + $meta = unserialize($signup->meta); + $user_login = $wpdb->escape($signup->user_login); + $user_email = $wpdb->escape($signup->user_email); + $password = wp_generate_password( 12, false ); + + $user_id = username_exists($user_login); + + if ( ! $user_id ) + $user_id = wpmu_create_user($user_login, $password, $user_email); + else + $user_already_exists = true; + + if ( ! $user_id ) + return new WP_Error('create_user', __('Could not create user'), $signup); + + $now = current_time('mysql', true); + + if ( empty($signup->domain) ) { + $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) ); + + if ( isset( $user_already_exists ) ) + return new WP_Error( 'user_already_exists', __( 'That username is already activated.' ), $signup); + + wpmu_welcome_user_notification($user_id, $password, $meta); + + add_new_user_to_blog( $user_id, $user_email, $meta ); + do_action('wpmu_activate_user', $user_id, $password, $meta); + return array('user_id' => $user_id, 'password' => $password, 'meta' => $meta); + } + + $blog_id = wpmu_create_blog( $signup->domain, $signup->path, $signup->title, $user_id, $meta, $wpdb->siteid ); + + // TODO: What to do if we create a user but cannot create a blog? + if ( is_wp_error($blog_id) ) { + // If blog is taken, that means a previous attempt to activate this blog failed in between creating the blog and + // setting the activation flag. Let's just set the active flag and instruct the user to reset their password. + if ( 'blog_taken' == $blog_id->get_error_code() ) { + $blog_id->add_data( $signup ); + $wpdb->update( $wpdb->signups, array( 'active' => 1, 'activated' => $now ), array( 'activation_key' => $key ) ); + } + return $blog_id; + } + + $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) ); + wpmu_welcome_notification($blog_id, $user_id, $password, $signup->title, $meta); + do_action('wpmu_activate_blog', $blog_id, $user_id, $password, $signup->title, $meta); + + return array('blog_id' => $blog_id, 'user_id' => $user_id, 'password' => $password, 'title' => $signup->title, 'meta' => $meta); +} + +/** + * Create a user. + * + * This function runs when a user self-registers as well as when + * a Super Admin creates a new user. Hook to 'wpmu_new_user' for events + * that should affect all new users, but only on Multisite (otherwise + * use 'user_register'). + * + * @since MU + * @uses wp_create_user() + * + * @param string $user_name The new user's login name. + * @param string $password The new user's password. + * @param string $email The new user's email address. + * @return mixed Returns false on failure, or int $user_id on success + */ +function wpmu_create_user( $user_name, $password, $email) { + $user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) ); + + $user_id = wp_create_user( $user_name, $password, $email ); + if ( is_wp_error($user_id) ) + return false; + + // Newly created users have no roles or caps until they are added to a blog. + delete_user_option( $user_id, 'capabilities' ); + delete_user_option( $user_id, 'user_level' ); + + do_action( 'wpmu_new_user', $user_id ); + + return $user_id; +} + +/** + * Create a site. + * + * This function runs when a user self-registers a new site as well + * as when a Super Admin creates a new site. Hook to 'wpmu_new_blog' + * for events that should affect all new sites. + * + * On subdirectory installs, $domain is the same as the main site's + * domain, and the path is the subdirectory name (eg 'example.com' + * and '/blog1/'). On subdomain installs, $domain is the new subdomain + + * root domain (eg 'blog1.example.com'), and $path is '/'. + * + * @since MU + * @uses domain_exists() + * @uses insert_blog() + * @uses wp_install_defaults() + * @uses add_user_to_blog() + * + * @param string $domain The new site's domain. + * @param string $path The new site's path. + * @param string $title The new site's title. + * @param int $user_id The user ID of the new site's admin. + * @param array $meta Optional. Used to set initial site options. + * @param int $site_id Optional. Only relevant on multi-network installs. + * @return mixed Returns WP_Error object on failure, int $blog_id on success + */ +function wpmu_create_blog($domain, $path, $title, $user_id, $meta = '', $site_id = 1) { + $domain = preg_replace( '/\s+/', '', sanitize_user( $domain, true ) ); + + if ( is_subdomain_install() ) + $domain = str_replace( '@', '', $domain ); + + $title = strip_tags( $title ); + $user_id = (int) $user_id; + + if ( empty($path) ) + $path = '/'; + + // Check if the domain has been used already. We should return an error message. + if ( domain_exists($domain, $path, $site_id) ) + return new WP_Error('blog_taken', __('Site already exists.')); + + if ( !defined('WP_INSTALLING') ) + define( 'WP_INSTALLING', true ); + + if ( ! $blog_id = insert_blog($domain, $path, $site_id) ) + return new WP_Error('insert_blog', __('Could not create site.')); + + switch_to_blog($blog_id); + install_blog($blog_id, $title); + wp_install_defaults($user_id); + + add_user_to_blog($blog_id, $user_id, 'administrator'); + + if ( is_array($meta) ) foreach ($meta as $key => $value) { + if ( $key == 'public' || $key == 'archived' || $key == 'mature' || $key == 'spam' || $key == 'deleted' || $key == 'lang_id' ) + update_blog_status( $blog_id, $key, $value ); + else + update_option( $key, $value ); + } + + add_option( 'WPLANG', get_site_option( 'WPLANG' ) ); + update_option( 'blog_public', (int)$meta['public'] ); + + if ( !is_super_admin() && ! get_user_meta( $user_id, 'primary_blog', true ) ) + update_user_meta( $user_id, 'primary_blog', $blog_id ); + + restore_current_blog(); + do_action( 'wpmu_new_blog', $blog_id, $user_id, $domain, $path, $site_id, $meta ); + + return $blog_id; +} + +/** + * Notifies the network admin that a new site has been activated. + * + * Filter 'newblog_notify_siteadmin' to change the content of + * the notification email. + * + * @since MU + * + * @param int $blog_id The new site's ID. + * @return bool + */ +function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) { + if ( get_site_option( 'registrationnotification' ) != 'yes' ) + return false; + + $email = get_site_option( 'admin_email' ); + if ( is_email($email) == false ) + return false; + + $options_site_url = esc_url(network_admin_url('settings.php')); + + switch_to_blog( $blog_id ); + $blogname = get_option( 'blogname' ); + $siteurl = site_url(); + restore_current_blog(); + + $msg = sprintf( __( 'New Site: %1s +URL: %2s +Remote IP: %3s + +Disable these notifications: %4s' ), $blogname, $siteurl, $_SERVER['REMOTE_ADDR'], $options_site_url); + $msg = apply_filters( 'newblog_notify_siteadmin', $msg ); + + wp_mail( $email, sprintf( __( 'New Site Registration: %s' ), $siteurl ), $msg ); + return true; +} + +/** + * Notifies the network admin that a new user has been activated. + * + * Filter 'newuser_notify_siteadmin' to change the content of + * the notification email. + * + * @since MU + * + * @param int $user_id The new user's ID. + * @return bool + */ +function newuser_notify_siteadmin( $user_id ) { + if ( get_site_option( 'registrationnotification' ) != 'yes' ) + return false; + + $email = get_site_option( 'admin_email' ); + + if ( is_email($email) == false ) + return false; + + $user = new WP_User($user_id); + + $options_site_url = esc_url(network_admin_url('settings.php')); + $msg = sprintf(__('New User: %1s +Remote IP: %2s + +Disable these notifications: %3s'), $user->user_login, $_SERVER['REMOTE_ADDR'], $options_site_url); + + $msg = apply_filters( 'newuser_notify_siteadmin', $msg ); + wp_mail( $email, sprintf(__('New User Registration: %s'), $user->user_login), $msg ); + return true; +} + +/** + * Check whether a blogname is already taken. + * + * Used during the new site registration process to ensure + * that each blogname is unique. + * + * @since MU + * + * @param string $domain The domain to be checked. + * @param string $path The path to be checked. + * @param int $site_id Optional. Relevant only on multi-network installs. + * @return int + */ +function domain_exists($domain, $path, $site_id = 1) { + global $wpdb; + return $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s AND site_id = %d", $domain, $path, $site_id) ); +} + +/** + * Store basic site info in the blogs table. + * + * This function creates a row in the wp_blogs table and returns + * the new blog's ID. It is the first step in creating a new blog. + * + * @since MU + * + * @param string $domain The domain of the new site. + * @param string $path The path of the new site. + * @param int $site_id Unless you're running a multi-network install, be sure to set this value to 1. + * @return int The ID of the new row + */ +function insert_blog($domain, $path, $site_id) { + global $wpdb; + + $path = trailingslashit($path); + $site_id = (int) $site_id; + + $result = $wpdb->insert( $wpdb->blogs, array('site_id' => $site_id, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql')) ); + if ( ! $result ) + return false; + + refresh_blog_details($wpdb->insert_id); + return $wpdb->insert_id; +} + +/** + * Install an empty blog. + * + * Creates the new blog tables and options. If calling this function + * directly, be sure to use switch_to_blog() first, so that $wpdb + * points to the new blog. + * + * @since MU + * @uses make_db_current_silent() + * @uses populate_roles() + * + * @param int $blog_id The value returned by insert_blog(). + * @param string $blog_title The title of the new site. + */ +function install_blog($blog_id, $blog_title = '') { + global $wpdb, $table_prefix, $wp_roles; + $wpdb->suppress_errors(); + + // Cast for security + $blog_id = (int) $blog_id; + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + if ( $wpdb->get_results("SELECT ID FROM $wpdb->posts") ) + die(__('

    Already Installed

    You appear to have already installed WordPress. To reinstall please clear your old database tables first.

    ') . ''); + + $wpdb->suppress_errors(false); + + $url = get_blogaddress_by_id($blog_id); + + // Set everything up + make_db_current_silent(); + populate_options(); + populate_roles(); + $wp_roles->_init(); + + // fix url. + update_option('siteurl', $url); + update_option('home', $url); + update_option('fileupload_url', $url . "files" ); + update_option('upload_path', UPLOADBLOGSDIR . "/$blog_id/files"); + update_option('blogname', stripslashes( $blog_title ) ); + update_option('admin_email', ''); + $wpdb->update( $wpdb->options, array('option_value' => ''), array('option_name' => 'admin_email') ); + + // remove all perms + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE meta_key = %s", $table_prefix.'user_level') ); + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE meta_key = %s", $table_prefix.'capabilities') ); + + $wpdb->suppress_errors( false ); +} + +/** + * Set blog defaults. + * + * This function creates a row in the wp_blogs table. + * + * @since MU + * @deprecated MU + * @deprecated Use wp_install_defaults() + * @uses wp_install_defaults() + * + * @param int $blog_id Ignored in this function. + * @param int $user_id + */ +function install_blog_defaults($blog_id, $user_id) { + global $wpdb; + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + $wpdb->suppress_errors(); + + wp_install_defaults($user_id); + + $wpdb->suppress_errors( false ); +} + +/** + * Notify a user that her blog activation has been successful. + * + * Filter 'wpmu_welcome_notification' to disable or bypass. + * + * Filter 'update_welcome_email' and 'update_welcome_subject' to + * modify the content and subject line of the notification email. + * + * @since MU + * + * @param int $blog_id + * @param int $user_id + * @param string $password + * @param string $title The new blog's title + * @param array $meta Optional. Not used in the default function, but is passed along to hooks for customization. + * @return bool + */ +function wpmu_welcome_notification($blog_id, $user_id, $password, $title, $meta = '') { + global $current_site; + + if ( !apply_filters('wpmu_welcome_notification', $blog_id, $user_id, $password, $title, $meta) ) + return false; + + $welcome_email = stripslashes( get_site_option( 'welcome_email' ) ); + if ( $welcome_email == false ) + $welcome_email = stripslashes( __( 'Dear User, + +Your new SITE_NAME site has been successfully set up at: +BLOG_URL + +You can log in to the administrator account with the following information: +Username: USERNAME +Password: PASSWORD +Login Here: BLOG_URLwp-login.php + +We hope you enjoy your new site. +Thanks! + +--The Team @ SITE_NAME' ) ); + + $url = get_blogaddress_by_id($blog_id); + $user = new WP_User($user_id); + + $welcome_email = str_replace( 'SITE_NAME', $current_site->site_name, $welcome_email ); + $welcome_email = str_replace( 'BLOG_TITLE', $title, $welcome_email ); + $welcome_email = str_replace( 'BLOG_URL', $url, $welcome_email ); + $welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email ); + $welcome_email = str_replace( 'PASSWORD', $password, $welcome_email ); + + $welcome_email = apply_filters( 'update_welcome_email', $welcome_email, $blog_id, $user_id, $password, $title, $meta); + $admin_email = get_site_option( 'admin_email' ); + + if ( $admin_email == '' ) + $admin_email = 'support@' . $_SERVER['SERVER_NAME']; + + $from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) ); + $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; + $message = $welcome_email; + + if ( empty( $current_site->site_name ) ) + $current_site->site_name = 'WordPress MU'; + + $subject = apply_filters( 'update_welcome_subject', sprintf(__('New %1$s Site: %2$s'), $current_site->site_name, stripslashes( $title ) ) ); + wp_mail($user->user_email, $subject, $message, $message_headers); + return true; +} + +/** + * Notify a user that her account activation has been successful. + * + * Filter 'wpmu_welcome_user_notification' to disable or bypass. + * + * Filter 'update_welcome_user_email' and 'update_welcome_user_subject' to + * modify the content and subject line of the notification email. + * + * @since MU + * + * @param int $user_id + * @param string $password + * @param array $meta Optional. Not used in the default function, but is passed along to hooks for customization. + * @return bool + */ +function wpmu_welcome_user_notification($user_id, $password, $meta = '') { + global $current_site; + + if ( !apply_filters('wpmu_welcome_user_notification', $user_id, $password, $meta) ) + return false; + + $welcome_email = get_site_option( 'welcome_user_email' ); + + $user = new WP_User($user_id); + + $welcome_email = apply_filters( 'update_welcome_user_email', $welcome_email, $user_id, $password, $meta); + $welcome_email = str_replace( 'SITE_NAME', $current_site->site_name, $welcome_email ); + $welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email ); + $welcome_email = str_replace( 'PASSWORD', $password, $welcome_email ); + $welcome_email = str_replace( 'LOGINLINK', wp_login_url(), $welcome_email ); + + $admin_email = get_site_option( 'admin_email' ); + + if ( $admin_email == '' ) + $admin_email = 'support@' . $_SERVER['SERVER_NAME']; + + $from_name = get_site_option( 'site_name' ) == '' ? 'WordPress' : esc_html( get_site_option( 'site_name' ) ); + $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; + $message = $welcome_email; + + if ( empty( $current_site->site_name ) ) + $current_site->site_name = 'WordPress MU'; + + $subject = apply_filters( 'update_welcome_user_subject', sprintf(__('New %1$s User: %2$s'), $current_site->site_name, $user->user_login) ); + wp_mail($user->user_email, $subject, $message, $message_headers); + return true; +} + +/** + * Get the current site info. + * + * Returns an object containing the ID, domain, path, and site_name + * of the site being viewed. + * + * @since MU + * + * @return object + */ +function get_current_site() { + global $current_site; + return $current_site; +} + +/** + * Get a numeric user ID from either an email address or a login. + * + * @since MU + * @uses is_email() + * + * @param string $string + * @return int + */ +function get_user_id_from_string( $string ) { + $user_id = 0; + if ( is_email( $string ) ) { + $user = get_user_by('email', $string); + if ( $user ) + $user_id = $user->ID; + } elseif ( is_numeric( $string ) ) { + $user_id = $string; + } else { + $user = get_user_by('login', $string); + if ( $user ) + $user_id = $user->ID; + } + + return $user_id; +} + +/** + * Get a user's most recent post. + * + * Walks through each of a user's blogs to find the post with + * the most recent post_date_gmt. + * + * @since MU + * @uses get_blogs_of_user() + * + * @param int $user_id + * @return array Contains the blog_id, post_id, post_date_gmt, and post_gmt_ts + */ +function get_most_recent_post_of_user( $user_id ) { + global $wpdb; + + $user_blogs = get_blogs_of_user( (int) $user_id ); + $most_recent_post = array(); + + // Walk through each blog and get the most recent post + // published by $user_id + foreach ( (array) $user_blogs as $blog ) { + $recent_post = $wpdb->get_row( $wpdb->prepare("SELECT ID, post_date_gmt FROM {$wpdb->base_prefix}{$blog->userblog_id}_posts WHERE post_author = %d AND post_type = 'post' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1", $user_id ), ARRAY_A); + + // Make sure we found a post + if ( isset($recent_post['ID']) ) { + $post_gmt_ts = strtotime($recent_post['post_date_gmt']); + + // If this is the first post checked or if this post is + // newer than the current recent post, make it the new + // most recent post. + if ( !isset($most_recent_post['post_gmt_ts']) || ( $post_gmt_ts > $most_recent_post['post_gmt_ts'] ) ) { + $most_recent_post = array( + 'blog_id' => $blog->userblog_id, + 'post_id' => $recent_post['ID'], + 'post_date_gmt' => $recent_post['post_date_gmt'], + 'post_gmt_ts' => $post_gmt_ts + ); + } + } + } + + return $most_recent_post; +} + +// Misc functions + +/** + * Get the size of a directory. + * + * A helper function that is used primarily to check whether + * a blog has exceeded its allowed upload space. + * + * @since MU + * @uses recurse_dirsize() + * + * @param string $directory + * @return int + */ +function get_dirsize( $directory ) { + $dirsize = get_transient( 'dirsize_cache' ); + if ( is_array( $dirsize ) && isset( $dirsize[ $directory ][ 'size' ] ) ) + return $dirsize[ $directory ][ 'size' ]; + + if ( false == is_array( $dirsize ) ) + $dirsize = array(); + + $dirsize[ $directory ][ 'size' ] = recurse_dirsize( $directory ); + + set_transient( 'dirsize_cache', $dirsize, 3600 ); + return $dirsize[ $directory ][ 'size' ]; +} + +/** + * Get the size of a directory recursively. + * + * Used by get_dirsize() to get a directory's size when it contains + * other directories. + * + * @since MU + * + * @param string $directory + * @return int + */ +function recurse_dirsize( $directory ) { + $size = 0; + + if ( substr( $directory, -1 ) == '/' ) + $directory = substr($directory,0,-1); + + if ( !file_exists($directory) || !is_dir( $directory ) || !is_readable( $directory ) ) + return false; + + if ($handle = opendir($directory)) { + while(($file = readdir($handle)) !== false) { + $path = $directory.'/'.$file; + if ($file != '.' && $file != '..') { + if (is_file($path)) { + $size += filesize($path); + } elseif (is_dir($path)) { + $handlesize = recurse_dirsize($path); + if ($handlesize > 0) + $size += $handlesize; + } + } + } + closedir($handle); + } + return $size; +} + +/** + * Check whether a blog has used its allotted upload space. + * + * Used by get_dirsize() to get a directory's size when it contains + * other directories. + * + * @since MU + * @uses get_dirsize() + * + * @param bool $echo Optional. If $echo is set and the quota is exceeded, a warning message is echoed. Default is true. + * @return int + */ +function upload_is_user_over_quota( $echo = true ) { + if ( get_site_option( 'upload_space_check_disabled' ) ) + return false; + + $spaceAllowed = get_space_allowed(); + if ( empty( $spaceAllowed ) || !is_numeric( $spaceAllowed ) ) + $spaceAllowed = 10; // Default space allowed is 10 MB + + $dirName = BLOGUPLOADDIR; + $size = get_dirsize($dirName) / 1024 / 1024; + + if ( ($spaceAllowed-$size) < 0 ) { + if ( $echo ) + _e( 'Sorry, you have used your space allocation. Please delete some files to upload more files.' ); // No space left + return true; + } else { + return false; + } +} + +/** + * Check an array of MIME types against a whitelist. + * + * WordPress ships with a set of allowed upload filetypes, + * which is defined in wp-includes/functions.php in + * get_allowed_mime_types(). This function is used to filter + * that list against the filetype whitelist provided by Multisite + * Super Admins at wp-admin/network/settings.php. + * + * @since MU + * + * @param array $mimes + * @return array + */ +function check_upload_mimes( $mimes ) { + $site_exts = explode( ' ', get_site_option( 'upload_filetypes' ) ); + foreach ( $site_exts as $ext ) { + foreach ( $mimes as $ext_pattern => $mime ) { + if ( $ext != '' && strpos( $ext_pattern, $ext ) !== false ) + $site_mimes[$ext_pattern] = $mime; + } + } + return $site_mimes; +} + +/** + * Update a blog's post count. + * + * WordPress MS stores a blog's post count as an option so as + * to avoid extraneous COUNTs when a blog's details are fetched + * with get_blog_details(). This function is called when posts + * are published to make sure the count stays current. + * + * @since MU + */ +function update_posts_count( $deprecated = '' ) { + global $wpdb; + update_option( 'post_count', (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_status = 'publish' and post_type = 'post'" ) ); +} + +/** + * Logs user registrations. + * + * @since MU + * + * @param int $blog_id + * @param int $user_id + */ +function wpmu_log_new_registrations( $blog_id, $user_id ) { + global $wpdb; + $user = new WP_User( (int) $user_id ); + $wpdb->insert( $wpdb->registration_log, array('email' => $user->user_email, 'IP' => preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] ), 'blog_id' => $blog_id, 'date_registered' => current_time('mysql')) ); +} + +/** + * Get the remaining upload space for this blog. + * + * @since MU + * @uses upload_is_user_over_quota() + * @uses get_space_allowed() + * @uses get_dirsize() + * + * @param int $size + * @return int + */ +function fix_import_form_size( $size ) { + if ( upload_is_user_over_quota( false ) == true ) + return 0; + + $spaceAllowed = 1024 * 1024 * get_space_allowed(); + $dirName = BLOGUPLOADDIR; + $dirsize = get_dirsize($dirName) ; + if ( $size > $spaceAllowed - $dirsize ) + return $spaceAllowed - $dirsize; // remaining space + else + return $size; // default +} + +/** + * Maintains a canonical list of terms by syncing terms created for each blog with the global terms table. + * + * @since 3.0.0 + * + * @see term_id_filter + * + * @param int $term_id An ID for a term on the current blog. + * @return int An ID from the global terms table mapped from $term_id. + */ +function global_terms( $term_id, $deprecated = '' ) { + global $wpdb; + static $global_terms_recurse = null; + + if ( !global_terms_enabled() ) + return $term_id; + + // prevent a race condition + $recurse_start = false; + if ( $global_terms_recurse === null ) { + $recurse_start = true; + $global_terms_recurse = 1; + } elseif ( 10 < $global_terms_recurse++ ) { + return $term_id; + } + + $term_id = intval( $term_id ); + $c = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->terms WHERE term_id = %d", $term_id ) ); + + $global_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM $wpdb->sitecategories WHERE category_nicename = %s", $c->slug ) ); + if ( $global_id == null ) { + $used_global_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM $wpdb->sitecategories WHERE cat_ID = %d", $c->term_id ) ); + if ( null == $used_global_id ) { + $wpdb->insert( $wpdb->sitecategories, array( 'cat_ID' => $term_id, 'cat_name' => $c->name, 'category_nicename' => $c->slug ) ); + $global_id = $wpdb->insert_id; + if ( empty( $global_id ) ) + return $term_id; + } else { + $max_global_id = $wpdb->get_var( "SELECT MAX(cat_ID) FROM $wpdb->sitecategories" ); + $max_local_id = $wpdb->get_var( "SELECT MAX(term_id) FROM $wpdb->terms" ); + $new_global_id = max( $max_global_id, $max_local_id ) + mt_rand( 100, 400 ); + $wpdb->insert( $wpdb->sitecategories, array( 'cat_ID' => $new_global_id, 'cat_name' => $c->name, 'category_nicename' => $c->slug ) ); + $global_id = $wpdb->insert_id; + } + } elseif ( $global_id != $term_id ) { + $local_id = $wpdb->get_row( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms WHERE term_id = %d", $global_id ) ); + if ( null != $local_id ) + $local_id = global_terms( $local_id ); + if ( 10 < $global_terms_recurse ) + $global_id = $term_id; + } + + if ( $global_id != $term_id ) { + if ( get_option( 'default_category' ) == $term_id ) + update_option( 'default_category', $global_id ); + + $wpdb->update( $wpdb->terms, array('term_id' => $global_id), array('term_id' => $term_id) ); + $wpdb->update( $wpdb->term_taxonomy, array('term_id' => $global_id), array('term_id' => $term_id) ); + $wpdb->update( $wpdb->term_taxonomy, array('parent' => $global_id), array('parent' => $term_id) ); + + clean_term_cache($term_id); + } + if( $recurse_start ) + $global_terms_recurse = null; + + return $global_id; +} + +/** + * Ensure that the current site's domain is listed in the allowed redirect host list. + * + * @see wp_validate_redirect() + * @since MU + * + * @return array The current site's domain + */ +function redirect_this_site( $deprecated = '' ) { + global $current_site; + return array( $current_site->domain ); +} + +/** + * Check whether an upload is too big. + * + * @since MU + * + * @param array $upload + * @return mixed If the upload is under the size limit, $upload is returned. Otherwise returns an error message. + */ +function upload_is_file_too_big( $upload ) { + if ( is_array( $upload ) == false || defined( 'WP_IMPORTING' ) ) + return $upload; + + if ( strlen( $upload['bits'] ) > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) ) + return sprintf( __( 'This file is too big. Files must be less than %d KB in size.' ) . '
    ', get_site_option( 'fileupload_maxk', 1500 )); + + return $upload; +} + +/** + * Add a nonce field to the signup page. + * + * @since MU + * @uses wp_nonce_field() + */ +function signup_nonce_fields() { + $id = mt_rand(); + echo ""; + wp_nonce_field('signup_form_' . $id, '_signup_form', false); +} + +/** + * Process the signup nonce created in signup_nonce_fields(). + * + * @since MU + * @uses wp_create_nonce() + * + * @param array $result + * @return array + */ +function signup_nonce_check( $result ) { + if ( !strpos( $_SERVER[ 'PHP_SELF' ], 'wp-signup.php' ) ) + return $result; + + if ( wp_create_nonce('signup_form_' . $_POST[ 'signup_form_id' ]) != $_POST['_signup_form'] ) + wp_die( __('Please try again!') ); + + return $result; +} + +/** + * Correct 404 redirects when NOBLOGREDIRECT is defined. + * + * @since MU + */ +function maybe_redirect_404() { + global $current_site; + if ( is_main_site() && is_404() && defined( 'NOBLOGREDIRECT' ) && ( $destination = apply_filters( 'blog_redirect_404', NOBLOGREDIRECT ) ) ) { + if ( $destination == '%siteurl%' ) + $destination = network_home_url(); + wp_redirect( $destination ); + exit(); + } +} + +/** + * Add a new user to a blog by visiting /newbloguser/username/. + * + * This will only work when the user's details are saved as an option + * keyed as 'new_user_x', where 'x' is the username of the user to be + * added, as when a user is invited through the regular WP Add User interface. + * + * @since MU + * @uses add_existing_user_to_blog() + */ +function maybe_add_existing_user_to_blog() { + if ( false === strpos( $_SERVER[ 'REQUEST_URI' ], '/newbloguser/' ) ) + return false; + + $parts = explode( '/', $_SERVER[ 'REQUEST_URI' ] ); + $key = array_pop( $parts ); + + if ( $key == '' ) + $key = array_pop( $parts ); + + $details = get_option( 'new_user_' . $key ); + if ( !empty( $details ) ) + delete_option( 'new_user_' . $key ); + + if ( empty( $details ) || is_wp_error( add_existing_user_to_blog( $details ) ) ) + wp_die( sprintf(__('An error occurred adding you to this site. Back to the homepage.'), site_url() ) ); + + wp_die( sprintf(__('You have been added to this site. Please visit the homepage or login using your username and password.'), site_url(), admin_url() ), __('Success') ); +} + +/** + * Add a user to a blog based on details from maybe_add_existing_user_to_blog(). + * + * @since MU + * @uses add_user_to_blog() + * + * @param array $details + */ +function add_existing_user_to_blog( $details = false ) { + global $blog_id; + + if ( is_array( $details ) ) { + $result = add_user_to_blog( $blog_id, $details[ 'user_id' ], $details[ 'role' ] ); + do_action( 'added_existing_user', $details[ 'user_id' ], $result ); + } + return $result; +} + +/** + * Add a newly created user to the appropriate blog + * + * @since MU + * + * @param int $user_id + * @param string $email + * @param array $meta + */ +function add_new_user_to_blog( $user_id, $email, $meta ) { + global $current_site; + if ( $meta[ 'add_to_blog' ] ) { + $blog_id = $meta[ 'add_to_blog' ]; + $role = $meta[ 'new_role' ]; + remove_user_from_blog($user_id, $current_site->blog_id); // remove user from main blog. + add_user_to_blog( $blog_id, $user_id, $role ); + update_user_meta( $user_id, 'primary_blog', $blog_id ); + } +} + +/** + * Correct From host on outgoing mail to match the site domain + * + * @since MU + */ +function fix_phpmailer_messageid( $phpmailer ) { + global $current_site; + $phpmailer->Hostname = $current_site->domain; +} + +/** + * Check to see whether a user is marked as a spammer, based on username + * + * @since MU + * @uses get_current_user_id() + * @uses get_user_id_from_string() + * + * @param string $username + * @return bool + */ +function is_user_spammy( $username = 0 ) { + if ( $username == 0 ) { + $user_id = get_current_user_id(); + } else { + $user_id = get_user_id_from_string( $username ); + } + $u = new WP_User( $user_id ); + + return ( isset( $u->spam ) && $u->spam == 1 ); +} + +/** + * Update this blog's 'public' setting in the global blogs table. + * + * Public blogs have a setting of 1, private blogs are 0. + * + * @since MU + * @uses update_blog_status() + * + * @param int $old_value + * @param int $value The new public value + * @return bool + */ +function update_blog_public( $old_value, $value ) { + global $wpdb; + do_action('update_blog_public'); + update_blog_status( $wpdb->blogid, 'public', (int) $value ); +} +add_action('update_option_blog_public', 'update_blog_public', 10, 2); + +/** + * Get the "dashboard blog", the blog where users without a blog edit their profile data. + * + * @since MU + * @uses get_blog_details() + * + * @return int + */ +function get_dashboard_blog() { + if ( $blog = get_site_option( 'dashboard_blog' ) ) + return get_blog_details( $blog ); + + return get_blog_details( $GLOBALS['current_site']->blog_id ); +} + +/** + * Check whether a usermeta key has to do with the current blog. + * + * @since MU + * @uses wp_get_current_user() + * + * @param string $key + * @param int $user_id Optional. Defaults to current user. + * @param int $blog_id Optional. Defaults to current blog. + * @return bool + */ +function is_user_option_local( $key, $user_id = 0, $blog_id = 0 ) { + global $wpdb; + + $current_user = wp_get_current_user(); + if ( $user_id == 0 ) + $user_id = $current_user->ID; + if ( $blog_id == 0 ) + $blog_id = $wpdb->blogid; + + $local_key = $wpdb->base_prefix . $blog_id . '_' . $key; + + if ( isset( $current_user->$local_key ) ) + return true; + + return false; +} + +/** + * Check whether users can self-register, based on Network settings. + * + * @since MU + * + * @return bool + */ +function users_can_register_signup_filter() { + $registration = get_site_option('registration'); + if ( $registration == 'all' || $registration == 'user' ) + return true; + + return false; +} +add_filter('option_users_can_register', 'users_can_register_signup_filter'); + +/** + * Ensure that the welcome message is not empty. Currently unused. + * + * @since MU + * + * @param string $text + * @return string + */ +function welcome_user_msg_filter( $text ) { + if ( !$text ) { + return __( 'Dear User, + +Your new account is set up. + +You can log in with the following information: +Username: USERNAME +Password: PASSWORD +LOGINLINK + +Thanks! + +--The Team @ SITE_NAME' ); + } + return $text; +} +add_filter( 'site_option_welcome_user_email', 'welcome_user_msg_filter' ); + +/** + * Whether to force SSL on content. + * + * @since 2.8.5 + * + * @param string|bool $force + * @return bool True if forced, false if not forced. + */ +function force_ssl_content( $force = '' ) { + static $forced_content; + + if ( '' != $force ) { + $old_forced = $forced_content; + $forced_content = $force; + return $old_forced; + } + + return $forced_content; +} + +/** + * Formats an String URL to use HTTPS if HTTP is found. + * Useful as a filter. + * + * @since 2.8.5 + **/ +function filter_SSL( $url ) { + if ( !is_string( $url ) ) + return get_bloginfo( 'url' ); //return home blog url with proper scheme + + $arrURL = parse_url( $url ); + + if ( force_ssl_content() && is_ssl() ) { + if ( 'http' === $arrURL['scheme'] && 'https' !== $arrURL['scheme'] ) + $url = str_replace( $arrURL['scheme'], 'https', $url ); + } + + return $url; +} + +/** + * Schedule update of the network-wide counts for the current network. + * + * @since 3.1.0 + */ +function wp_schedule_update_network_counts() { + if ( !is_main_site() ) + return; + + if ( !wp_next_scheduled('update_network_counts') && !defined('WP_INSTALLING') ) + wp_schedule_event(time(), 'twicedaily', 'update_network_counts'); +} + +/** + * Update the network-wide counts for the current network. + * + * @since 3.1.0 + */ +function wp_update_network_counts() { + global $wpdb; + + $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $wpdb->siteid) ); + update_site_option( 'blog_count', $count ); + + $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'") ); + update_site_option( 'user_count', $count ); +} + +?> \ No newline at end of file diff --git a/src/wp-includes/ms-load.php b/src/wp-includes/ms-load.php new file mode 100644 index 00000000..353cbe2f --- /dev/null +++ b/src/wp-includes/ms-load.php @@ -0,0 +1,250 @@ +WP_PLUGIN_DIR and WP_PLUGIN_URL + * in wp-config.php. + * + * @access private + * @since 3.1.0 + * @return array Files to include + */ +function wp_get_active_network_plugins() { + $active_plugins = (array) get_site_option( 'active_sitewide_plugins', array() ); + if ( empty( $active_plugins ) ) + return array(); + + $plugins = array(); + $active_plugins = array_keys( $active_plugins ); + sort( $active_plugins ); + + foreach ( $active_plugins as $plugin ) { + if ( ! validate_file( $plugin ) // $plugin must validate as file + && '.php' == substr( $plugin, -4 ) // $plugin must end with '.php' + && file_exists( WP_PLUGIN_DIR . '/' . $plugin ) // $plugin must exist + ) + $plugins[] = WP_PLUGIN_DIR . '/' . $plugin; + } + return $plugins; +} + +/** + * Checks status of current blog. + * + * Checks if the blog is deleted, inactive, archived, or spammed. + * + * Dies with a default message if the blog does not pass the check. + * + * To change the default message when a blog does not pass the check, + * use the wp-content/blog-deleted.php, blog-inactive.php and + * blog-suspended.php drop-ins. + * + * @return bool|string Returns true on success, or drop-in file to include. + */ +function ms_site_check() { + global $wpdb, $current_blog; + + // Allow short-circuiting + $check = apply_filters('ms_site_check', null); + if ( null !== $check ) + return true; + + // Allow super admins to see blocked sites + if ( is_super_admin() ) + return true; + + if ( '1' == $current_blog->deleted ) { + if ( file_exists( WP_CONTENT_DIR . '/blog-deleted.php' ) ) + return WP_CONTENT_DIR . '/blog-deleted.php'; + else + wp_die( __( 'This user has elected to delete their account and the content is no longer available.' ), '', array( 'response' => 410 ) ); + } + + if ( '2' == $current_blog->deleted ) { + if ( file_exists( WP_CONTENT_DIR . '/blog-inactive.php' ) ) + return WP_CONTENT_DIR . '/blog-inactive.php'; + else + wp_die( sprintf( __( 'This site has not been activated yet. If you are having problems activating your site, please contact %1$s.' ), str_replace( '@', ' AT ', get_site_option( 'admin_email', "support@{$current_site->domain}" ) ) ) ); + } + + if ( $current_blog->archived == '1' || $current_blog->spam == '1' ) { + if ( file_exists( WP_CONTENT_DIR . '/blog-suspended.php' ) ) + return WP_CONTENT_DIR . '/blog-suspended.php'; + else + wp_die( __( 'This site has been archived or suspended.' ), '', array( 'response' => 410 ) ); + } + + return true; +} + +/** + * Sets current site name. + * + * @access private + * @since 3.0.0 + * @return object $current_site object with site_name + */ +function get_current_site_name( $current_site ) { + global $wpdb; + + $current_site->site_name = wp_cache_get( $current_site->id . ':site_name', 'site-options' ); + if ( ! $current_site->site_name ) { + $current_site->site_name = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = %d AND meta_key = 'site_name'", $current_site->id ) ); + if ( ! $current_site->site_name ) + $current_site->site_name = ucfirst( $current_site->domain ); + } + wp_cache_set( $current_site->id . ':site_name', $current_site->site_name, 'site-options' ); + + return $current_site; +} + +/** + * Sets current_site object. + * + * @access private + * @since 3.0.0 + * @return object $current_site object + */ +function wpmu_current_site() { + global $wpdb, $current_site, $domain, $path, $sites, $cookie_domain; + if ( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) ) { + $current_site->id = defined( 'SITE_ID_CURRENT_SITE' ) ? SITE_ID_CURRENT_SITE : 1; + $current_site->domain = DOMAIN_CURRENT_SITE; + $current_site->path = $path = PATH_CURRENT_SITE; + if ( defined( 'BLOG_ID_CURRENT_SITE' ) ) + $current_site->blog_id = BLOG_ID_CURRENT_SITE; + elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) // deprecated. + $current_site->blog_id = BLOGID_CURRENT_SITE; + if ( DOMAIN_CURRENT_SITE == $domain ) + $current_site->cookie_domain = $cookie_domain; + elseif ( substr( $current_site->domain, 0, 4 ) == 'www.' ) + $current_site->cookie_domain = substr( $current_site->domain, 4 ); + else + $current_site->cookie_domain = $current_site->domain; + + wp_load_core_site_options( $current_site->id ); + + return $current_site; + } + + $current_site = wp_cache_get( 'current_site', 'site-options' ); + if ( $current_site ) + return $current_site; + + $sites = $wpdb->get_results( "SELECT * FROM $wpdb->site" ); // usually only one site + if ( 1 == count( $sites ) ) { + $current_site = $sites[0]; + wp_load_core_site_options( $current_site->id ); + $path = $current_site->path; + $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path ) ); + $current_site = get_current_site_name( $current_site ); + if ( substr( $current_site->domain, 0, 4 ) == 'www.' ) + $current_site->cookie_domain = substr( $current_site->domain, 4 ); + wp_cache_set( 'current_site', $current_site, 'site-options' ); + return $current_site; + } + $path = substr( $_SERVER[ 'REQUEST_URI' ], 0, 1 + strpos( $_SERVER[ 'REQUEST_URI' ], '/', 1 ) ); + + if ( $domain == $cookie_domain ) + $current_site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $domain, $path ) ); + else + $current_site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->site WHERE domain IN ( %s, %s ) AND path = %s ORDER BY CHAR_LENGTH( domain ) DESC LIMIT 1", $domain, $cookie_domain, $path ) ); + + if ( ! $current_site ) { + if ( $domain == $cookie_domain ) + $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $domain ) ); + else + $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain IN ( %s, %s ) AND path = '/' ORDER BY CHAR_LENGTH( domain ) DESC LIMIT 1", $domain, $cookie_domain, $path ) ); + } + + if ( $current_site ) { + $path = $current_site->path; + $current_site->cookie_domain = $cookie_domain; + return $current_site; + } + + if ( is_subdomain_install() ) { + $sitedomain = substr( $domain, 1 + strpos( $domain, '.' ) ); + $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $sitedomain, $path) ); + if ( $current_site ) { + $current_site->cookie_domain = $current_site->domain; + return $current_site; + } + + $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $sitedomain) ); + } + + if ( $current_site || defined( 'WP_INSTALLING' ) ) { + $path = '/'; + return $current_site; + } + + // Still no dice. + if ( 1 == count( $sites ) ) + wp_die( sprintf( /*WP_I18N_BLOG_DOESNT_EXIST*/'That site does not exist. Please try %s.'/*/WP_I18N_BLOG_DOESNT_EXIST*/, $sites[0]->domain . $sites[0]->path ) ); + else + wp_die( /*WP_I18N_NO_SITE_DEFINED*/'No site defined on this host. If you are the owner of this site, please check Debugging a WordPress Network for help.'/*/WP_I18N_NO_SITE_DEFINED*/ ); +} + +/** + * Displays a failure message. + * + * Used when a blog's tables do not exist. Checks for a missing $wpdb->site table as well. + * + * @access private + * @since 3.0.0 + */ +function ms_not_installed() { + global $wpdb, $domain, $path; + + $title = /*WP_I18N_FATAL_ERROR*/'Error establishing database connection'/*/WP_I18N_FATAL_ERROR*/; + $msg = '

    ' . $title . '

    '; + if ( ! is_admin() ) + die( $msg ); + $msg .= '

    ' . /*WP_I18N_CONTACT_OWNER*/'If your site does not display, please contact the owner of this network.'/*/WP_I18N_CONTACT_OWNER*/ . ''; + $msg .= ' ' . /*WP_I18N_CHECK_MYSQL*/'If you are the owner of this network please check that MySQL is running properly and all tables are error free.'/*/WP_I18N_CHECK_MYSQL*/ . '

    '; + if ( false && !$wpdb->get_var( "SHOW TABLES LIKE '$wpdb->site'" ) ) + $msg .= '

    ' . sprintf( /*WP_I18N_TABLES_MISSING_LONG*/'Database tables are missing. This means that MySQL is not running, WordPress was not installed properly, or someone deleted %s. You really should look at your database now.'/*/WP_I18N_TABLES_MISSING_LONG*/, $wpdb->site ) . '

    '; + else + $msg .= '

    ' . sprintf( /*WP_I18N_NO_SITE_FOUND*/'Could not find site %1$s. Searched for table %2$s in database %3$s. Is that right?'/*/WP_I18N_NO_SITE_FOUND*/, rtrim( $domain . $path, '/' ), $wpdb->blogs, DB_NAME ) . '

    '; + $msg .= '

    ' . /*WP_I18N_WHAT_DO_I_DO*/'What do I do now?'/*WP_I18N_WHAT_DO_I_DO*/ . ' '; + $msg .= /*WP_I18N_RTFM*/'Read the bug report page. Some of the guidelines there may help you figure out what went wrong.'/*/WP_I18N_RTFM*/; + $msg .= ' ' . /*WP_I18N_STUCK*/'If you’re still stuck with this message, then check that your database contains the following tables:'/*/WP_I18N_STUCK*/ . '

      '; + foreach ( $wpdb->tables('global') as $t => $table ) { + if ( 'sitecategories' == $t ) + continue; + $msg .= '
    • ' . $table . '
    • '; + } + $msg .= '
    '; + + wp_die( $msg, $title ); +} + +?> \ No newline at end of file diff --git a/src/wp-includes/ms-settings.php b/src/wp-includes/ms-settings.php new file mode 100644 index 00000000..9022313e --- /dev/null +++ b/src/wp-includes/ms-settings.php @@ -0,0 +1,136 @@ +wp-config.php. $base is set to BASE when it should be like / or /blogs/.'/*/WP_I18N_BASE_ERROR*/ ); + +/** Include Multisite initialization functions */ +require( ABSPATH . WPINC . '/ms-load.php' ); +require( ABSPATH . WPINC . '/ms-default-constants.php' ); + +if ( defined( 'SUNRISE' ) ) + include_once( WP_CONTENT_DIR . '/sunrise.php' ); + +/** Check for and define SUBDOMAIN_INSTALL and the deprecated VHOST constant. */ +ms_subdomain_constants(); + +if ( !isset( $current_site ) || !isset( $current_blog ) ) { + + $domain = addslashes( $_SERVER['HTTP_HOST'] ); + if ( false !== strpos( $domain, ':' ) ) { + if ( substr( $domain, -3 ) == ':80' ) { + $domain = substr( $domain, 0, -3 ); + $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -3 ); + } elseif ( substr( $domain, -4 ) == ':443' ) { + $domain = substr( $domain, 0, -4 ); + $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -4 ); + } else { + wp_die( /*WP_I18N_NO_PORT_NUMBER*/'Multisite only works without the port number in the URL.'/*/WP_I18N_NO_PORT_NUMBER*/ ); + } + } + + $domain = rtrim( $domain, '.' ); + $cookie_domain = $domain; + if ( substr( $cookie_domain, 0, 4 ) == 'www.' ) + $cookie_domain = substr( $cookie_domain, 4 ); + + $path = preg_replace( '|([a-z0-9-]+.php.*)|', '', $_SERVER['REQUEST_URI'] ); + $path = str_replace ( '/wp-admin/', '/', $path ); + $path = preg_replace( '|(/[a-z0-9-]+?/).*|', '$1', $path ); + + $current_site = wpmu_current_site(); + if ( ! isset( $current_site->blog_id ) ) + $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path ) ); + + if ( is_subdomain_install() ) { + $current_blog = wp_cache_get( 'current_blog_' . $domain, 'site-options' ); + if ( !$current_blog ) { + $current_blog = get_blog_details( array( 'domain' => $domain ), false ); + if ( $current_blog ) + wp_cache_set( 'current_blog_' . $domain, $current_blog, 'site-options' ); + } + if ( $current_blog && $current_blog->site_id != $current_site->id ) { + $current_site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->site WHERE id = %d", $current_blog->site_id ) ); + if ( ! isset( $current_site->blog_id ) ) + $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path ) ); + } else + $blogname = substr( $domain, 0, strpos( $domain, '.' ) ); + } else { + $blogname = htmlspecialchars( substr( $_SERVER[ 'REQUEST_URI' ], strlen( $path ) ) ); + if ( false !== strpos( $blogname, '/' ) ) + $blogname = substr( $blogname, 0, strpos( $blogname, '/' ) ); + if ( false !== strpos( $blogname, '?' ) ) + $blogname = substr( $blogname, 0, strpos( $blogname, '?' ) ); + $reserved_blognames = array( 'page', 'comments', 'blog', 'wp-admin', 'wp-includes', 'wp-content', 'files', 'feed' ); + if ( $blogname != '' && ! in_array( $blogname, $reserved_blognames ) && ! is_file( $blogname ) ) + $path .= $blogname . '/'; + $current_blog = wp_cache_get( 'current_blog_' . $domain . $path, 'site-options' ); + if ( ! $current_blog ) { + $current_blog = get_blog_details( array( 'domain' => $domain, 'path' => $path ), false ); + if ( $current_blog ) + wp_cache_set( 'current_blog_' . $domain . $path, $current_blog, 'site-options' ); + } + unset($reserved_blognames); + } + + if ( ! defined( 'WP_INSTALLING' ) && is_subdomain_install() && ! is_object( $current_blog ) ) { + if ( defined( 'NOBLOGREDIRECT' ) ) { + $destination = NOBLOGREDIRECT; + if ( '%siteurl%' == $destination ) + $destination = "http://" . $current_site->domain . $current_site->path; + } else { + $destination = 'http://' . $current_site->domain . $current_site->path . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain ); + } + header( 'Location: ' . $destination ); + die(); + } + + if ( ! defined( 'WP_INSTALLING' ) ) { + if ( $current_site && ! $current_blog ) { + if ( $current_site->domain != $_SERVER[ 'HTTP_HOST' ] ) { + header( 'Location: http://' . $current_site->domain . $current_site->path ); + exit; + } + $current_blog = get_blog_details( array( 'domain' => $current_site->domain, 'path' => $current_site->path ), false ); + } + if ( ! $current_blog || ! $current_site ) + ms_not_installed(); + } + + $blog_id = $current_blog->blog_id; + $public = $current_blog->public; + + if ( empty( $current_blog->site_id ) ) + $current_blog->site_id = 1; + $site_id = $current_blog->site_id; + + $current_site = get_current_site_name( $current_site ); + + if ( ! $blog_id ) { + if ( defined( 'WP_INSTALLING' ) ) { + $current_blog->blog_id = $blog_id = 1; + } else { + $msg = ! $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->site'" ) ? ' ' . /*WP_I18N_TABLES_MISSING*/'Database tables are missing.'/*/WP_I18N_TABLES_MISSING*/ : ''; + wp_die( /*WP_I18N_NO_BLOG*/'No site by that name on this system.'/*/WP_I18N_NO_BLOG*/ . $msg ); + } + } +} +$wpdb->set_prefix( $table_prefix, false ); // $table_prefix can be set in sunrise.php +$wpdb->set_blog_id( $current_blog->blog_id, $current_blog->site_id ); +$table_prefix = $wpdb->get_blog_prefix(); + +// need to init cache again after blog_id is set +wp_start_object_cache(); + +// Define upload directory constants +ms_upload_constants(); diff --git a/src/wp-includes/nav-menu-template.php b/src/wp-includes/nav-menu-template.php new file mode 100644 index 00000000..21898ab8 --- /dev/null +++ b/src/wp-includes/nav-menu-template.php @@ -0,0 +1,489 @@ + 'menu_item_parent', 'id' => 'db_id' ); + + /** + * @see Walker::start_lvl() + * @since 3.0.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param int $depth Depth of page. Used for padding. + */ + function start_lvl(&$output, $depth) { + $indent = str_repeat("\t", $depth); + $output .= "\n$indent
      \n"; + } + + /** + * @see Walker::end_lvl() + * @since 3.0.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param int $depth Depth of page. Used for padding. + */ + function end_lvl(&$output, $depth) { + $indent = str_repeat("\t", $depth); + $output .= "$indent
    \n"; + } + + /** + * @see Walker::start_el() + * @since 3.0.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $item Menu item data object. + * @param int $depth Depth of menu item. Used for padding. + * @param int $current_page Menu item ID. + * @param object $args + */ + function start_el(&$output, $item, $depth, $args) { + global $wp_query; + $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; + + $class_names = $value = ''; + + $classes = empty( $item->classes ) ? array() : (array) $item->classes; + $classes[] = 'menu-item-' . $item->ID; + + $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) ); + $class_names = ' class="' . esc_attr( $class_names ) . '"'; + + $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args ); + $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : ''; + + $output .= $indent . ''; + + $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : ''; + $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : ''; + $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : ''; + $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : ''; + + $item_output = $args->before; + $item_output .= ''; + $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after; + $item_output .= ''; + $item_output .= $args->after; + + $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); + } + + /** + * @see Walker::end_el() + * @since 3.0.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $item Page data object. Not used. + * @param int $depth Depth of page. Not Used. + */ + function end_el(&$output, $item, $depth) { + $output .= "\n"; + } +} + +/** + * Displays a navigation menu. + * + * Optional $args contents: + * + * menu - The menu that is desired. Accepts (matching in order) id, slug, name. Defaults to blank. + * menu_class - CSS class to use for the ul element which forms the menu. Defaults to 'menu'. + * menu_id - The ID that is applied to the ul element which forms the menu. Defaults to the menu slug, incremented. + * container - Whether to wrap the ul, and what to wrap it with. Defaults to 'div'. + * container_class - the class that is applied to the container. Defaults to 'menu-{menu slug}-container'. + * container_id - The ID that is applied to the container. Defaults to blank. + * fallback_cb - If the menu doesn't exists, a callback function will fire. Defaults to 'wp_page_menu'. Set to false for no fallback. + * before - Text before the link text. + * after - Text after the link text. + * link_before - Text before the link. + * link_after - Text after the link. + * echo - Whether to echo the menu or return it. Defaults to echo. + * depth - how many levels of the hierarchy are to be included. 0 means all. Defaults to 0. + * walker - allows a custom walker to be specified. + * theme_location - the location in the theme to be used. Must be registered with register_nav_menu() in order to be selectable by the user. + * items_wrap - How the list items should be wrapped. Defaults to a ul with an id and class. Uses printf() format with numbered placeholders. + * + * @since 3.0.0 + * + * @param array $args Arguments + */ +function wp_nav_menu( $args = array() ) { + static $menu_id_slugs = array(); + + $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '', + 'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '
      %3$s
    ', + 'depth' => 0, 'walker' => '', 'theme_location' => '' ); + + $args = wp_parse_args( $args, $defaults ); + $args = apply_filters( 'wp_nav_menu_args', $args ); + $args = (object) $args; + + // Get the nav menu based on the requested menu + $menu = wp_get_nav_menu_object( $args->menu ); + + // Get the nav menu based on the theme_location + if ( ! $menu && $args->theme_location && ( $locations = get_nav_menu_locations() ) && isset( $locations[ $args->theme_location ] ) ) + $menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] ); + + // get the first menu that has items if we still can't find a menu + if ( ! $menu && !$args->theme_location ) { + $menus = wp_get_nav_menus(); + foreach ( $menus as $menu_maybe ) { + if ( $menu_items = wp_get_nav_menu_items($menu_maybe->term_id) ) { + $menu = $menu_maybe; + break; + } + } + } + + // If the menu exists, get its items. + if ( $menu && ! is_wp_error($menu) && !isset($menu_items) ) + $menu_items = wp_get_nav_menu_items( $menu->term_id ); + + // If no menu was found or if the menu has no items and no location was requested, call the fallback_cb if it exists + if ( ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) && !$args->theme_location ) ) + && $args->fallback_cb && is_callable( $args->fallback_cb ) ) + return call_user_func( $args->fallback_cb, (array) $args ); + + // If no fallback function was specified and the menu doesn't exists, bail. + if ( !$menu || is_wp_error($menu) ) + return false; + + $nav_menu = $items = ''; + + $show_container = false; + if ( $args->container ) { + $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) ); + if ( in_array( $args->container, $allowed_tags ) ) { + $show_container = true; + $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-'. $menu->slug .'-container"'; + $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : ''; + $nav_menu .= '<'. $args->container . $id . $class . '>'; + } + } + + // Set up the $menu_item variables + _wp_menu_item_classes_by_context( $menu_items ); + + $sorted_menu_items = array(); + foreach ( (array) $menu_items as $key => $menu_item ) + $sorted_menu_items[$menu_item->menu_order] = $menu_item; + + unset($menu_items); + + $sorted_menu_items = apply_filters( 'wp_nav_menu_objects', $sorted_menu_items, $args ); + + $items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args ); + unset($sorted_menu_items); + + // Attributes + if ( ! empty( $args->menu_id ) ) { + $wrap_id = $args->menu_id; + } else { + $wrap_id = 'menu-' . $menu->slug; + while ( in_array( $wrap_id, $menu_id_slugs ) ) { + if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) ) + $wrap_id = preg_replace('#-(\d+)$#', '-' . ++$matches[1], $wrap_id ); + else + $wrap_id = $wrap_id . '-1'; + } + } + $menu_id_slugs[] = $wrap_id; + + $wrap_class = $args->menu_class ? $args->menu_class : ''; + + // Allow plugins to hook into the menu to add their own
  • 's + $items = apply_filters( 'wp_nav_menu_items', $items, $args ); + $items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args ); + + $nav_menu .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items ); + unset( $items ); + + if ( $show_container ) + $nav_menu .= 'container . '>'; + + $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args ); + + if ( $args->echo ) + echo $nav_menu; + else + return $nav_menu; +} + +/** + * Add the class property classes for the current context, if applicable. + * + * @access private + * @since 3.0 + * + * @param array $menu_items The current menu item objects to which to add the class property information. + */ +function _wp_menu_item_classes_by_context( &$menu_items ) { + global $wp_query; + + $queried_object = $wp_query->get_queried_object(); + $queried_object_id = (int) $wp_query->queried_object_id; + + $active_object = ''; + $active_ancestor_item_ids = array(); + $active_parent_item_ids = array(); + $active_parent_object_ids = array(); + $possible_taxonomy_ancestors = array(); + $possible_object_parents = array(); + $home_page_id = (int) get_option( 'page_for_posts' ); + + if ( $wp_query->is_singular && ! empty( $queried_object->post_type ) && ! is_post_type_hierarchical( $queried_object->post_type ) ) { + foreach ( (array) get_object_taxonomies( $queried_object->post_type ) as $taxonomy ) { + if ( is_taxonomy_hierarchical( $taxonomy ) ) { + $term_hierarchy = _get_term_hierarchy( $taxonomy ); + $terms = wp_get_object_terms( $queried_object_id, $taxonomy, array( 'fields' => 'ids' ) ); + if ( is_array( $terms ) ) { + $possible_object_parents = array_merge( $possible_object_parents, $terms ); + $term_to_ancestor = array(); + foreach ( (array) $term_hierarchy as $anc => $descs ) { + foreach ( (array) $descs as $desc ) + $term_to_ancestor[ $desc ] = $anc; + } + + foreach ( $terms as $desc ) { + do { + $possible_taxonomy_ancestors[ $taxonomy ][] = $desc; + if ( isset( $term_to_ancestor[ $desc ] ) ) { + $_desc = $term_to_ancestor[ $desc ]; + unset( $term_to_ancestor[ $desc ] ); + $desc = $_desc; + } else { + $desc = 0; + } + } while ( ! empty( $desc ) ); + } + } + } + } + } elseif ( ! empty( $queried_object->post_type ) && is_post_type_hierarchical( $queried_object->post_type ) ) { + _get_post_ancestors( $queried_object ); + } elseif ( ! empty( $queried_object->taxonomy ) && is_taxonomy_hierarchical( $queried_object->taxonomy ) ) { + $term_hierarchy = _get_term_hierarchy( $queried_object->taxonomy ); + $term_to_ancestor = array(); + foreach ( (array) $term_hierarchy as $anc => $descs ) { + foreach ( (array) $descs as $desc ) + $term_to_ancestor[ $desc ] = $anc; + } + $desc = $queried_object->term_id; + do { + $possible_taxonomy_ancestors[ $queried_object->taxonomy ][] = $desc; + if ( isset( $term_to_ancestor[ $desc ] ) ) { + $_desc = $term_to_ancestor[ $desc ]; + unset( $term_to_ancestor[ $desc ] ); + $desc = $_desc; + } else { + $desc = 0; + } + } while ( ! empty( $desc ) ); + } + + $possible_object_parents = array_filter( $possible_object_parents ); + + $front_page_url = home_url(); + + foreach ( (array) $menu_items as $key => $menu_item ) { + + $menu_items[$key]->current = false; + + $classes = (array) $menu_item->classes; + $classes[] = 'menu-item'; + $classes[] = 'menu-item-type-' . $menu_item->type; + $classes[] = 'menu-item-object-' . $menu_item->object; + + // if the menu item corresponds to a taxonomy term for the currently-queried non-hierarchical post object + if ( $wp_query->is_singular && 'taxonomy' == $menu_item->type && in_array( $menu_item->object_id, $possible_object_parents ) ) { + $active_parent_object_ids[] = (int) $menu_item->object_id; + $active_parent_item_ids[] = (int) $menu_item->db_id; + $active_object = $queried_object->post_type; + + // if the menu item corresponds to the currently-queried post or taxonomy object + } elseif ( + $menu_item->object_id == $queried_object_id && + ( + ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && $wp_query->is_home && $home_page_id == $menu_item->object_id ) || + ( 'post_type' == $menu_item->type && $wp_query->is_singular ) || + ( 'taxonomy' == $menu_item->type && ( $wp_query->is_category || $wp_query->is_tag || $wp_query->is_tax ) ) + ) + ) { + $classes[] = 'current-menu-item'; + $menu_items[$key]->current = true; + $_anc_id = (int) $menu_item->db_id; + + while( + ( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) && + ! in_array( $_anc_id, $active_ancestor_item_ids ) + ) { + $active_ancestor_item_ids[] = $_anc_id; + } + + if ( 'post_type' == $menu_item->type && 'page' == $menu_item->object ) { + // Back compat classes for pages to match wp_page_menu() + $classes[] = 'page_item'; + $classes[] = 'page-item-' . $menu_item->object_id; + $classes[] = 'current_page_item'; + } + $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; + $active_parent_object_ids[] = (int) $menu_item->post_parent; + $active_object = $menu_item->object; + + // if the menu item corresponds to the currently-requested URL + } elseif ( 'custom' == $menu_item->object ) { + $current_url = untrailingslashit( ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); + $item_url = untrailingslashit( strpos( $menu_item->url, '#' ) ? substr( $menu_item->url, 0, strpos( $menu_item->url, '#' ) ) : $menu_item->url ); + $_indexless_current = untrailingslashit( preg_replace( '/index.php$/', '', $current_url ) ); + + if ( in_array( $item_url, array( $current_url, $_indexless_current ) ) ) { + $classes[] = 'current-menu-item'; + $menu_items[$key]->current = true; + $_anc_id = (int) $menu_item->db_id; + + while( + ( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) && + ! in_array( $_anc_id, $active_ancestor_item_ids ) + ) { + $active_ancestor_item_ids[] = $_anc_id; + } + + if ( in_array( home_url(), array( untrailingslashit( $current_url ), untrailingslashit( $_indexless_current ) ) ) ) { + // Back compat for home link to match wp_page_menu() + $classes[] = 'current_page_item'; + } + $active_parent_item_ids[] = (int) $menu_item->menu_item_parent; + $active_parent_object_ids[] = (int) $menu_item->post_parent; + $active_object = $menu_item->object; + + // give front page item current-menu-item class when extra query arguments involved + } elseif ( $item_url == $front_page_url && is_front_page() ) { + $classes[] = 'current-menu-item'; + } + + if ( untrailingslashit($item_url) == home_url() ) + $classes[] = 'menu-item-home'; + } + + // back-compat with wp_page_menu: add "current_page_parent" to static home page link for any non-page query + if ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && empty( $wp_query->is_page ) && $home_page_id == $menu_item->object_id ) + $classes[] = 'current_page_parent'; + + $menu_items[$key]->classes = array_unique( $classes ); + } + $active_ancestor_item_ids = array_filter( array_unique( $active_ancestor_item_ids ) ); + $active_parent_item_ids = array_filter( array_unique( $active_parent_item_ids ) ); + $active_parent_object_ids = array_filter( array_unique( $active_parent_object_ids ) ); + + // set parent's class + foreach ( (array) $menu_items as $key => $parent_item ) { + $classes = (array) $parent_item->classes; + $menu_items[$key]->current_item_ancestor = false; + $menu_items[$key]->current_item_parent = false; + + if ( + isset( $parent_item->type ) && + ( + // ancestral post object + ( + 'post_type' == $parent_item->type && + ! empty( $queried_object->post_type ) && + is_post_type_hierarchical( $queried_object->post_type ) && + in_array( $parent_item->object_id, $queried_object->ancestors ) && + $parent_item->object != $queried_object->ID + ) || + + // ancestral term + ( + 'taxonomy' == $parent_item->type && + isset( $possible_taxonomy_ancestors[ $parent_item->object ] ) && + in_array( $parent_item->object_id, $possible_taxonomy_ancestors[ $parent_item->object ] ) && + ( + ! isset( $queried_object->term_id ) || + $parent_item->object_id != $queried_object->term_id + ) + ) + ) + ) { + $classes[] = empty( $queried_object->taxonomy ) ? 'current-' . $queried_object->post_type . '-ancestor' : 'current-' . $queried_object->taxonomy . '-ancestor'; + } + + if ( in_array( intval( $parent_item->db_id ), $active_ancestor_item_ids ) ) { + $classes[] = 'current-menu-ancestor'; + $menu_items[$key]->current_item_ancestor = true; + } + if ( in_array( $parent_item->db_id, $active_parent_item_ids ) ) { + $classes[] = 'current-menu-parent'; + $menu_items[$key]->current_item_parent = true; + } + if ( in_array( $parent_item->object_id, $active_parent_object_ids ) ) + $classes[] = 'current-' . $active_object . '-parent'; + + if ( 'post_type' == $parent_item->type && 'page' == $parent_item->object ) { + // Back compat classes for pages to match wp_page_menu() + if ( in_array('current-menu-parent', $classes) ) + $classes[] = 'current_page_parent'; + if ( in_array('current-menu-ancestor', $classes) ) + $classes[] = 'current_page_ancestor'; + } + + $menu_items[$key]->classes = array_unique( $classes ); + } +} + +/** + * Retrieve the HTML list content for nav menu items. + * + * @uses Walker_Nav_Menu to create HTML list content. + * @since 3.0.0 + * @see Walker::walk() for parameters and return description. + */ +function walk_nav_menu_tree( $items, $depth, $r ) { + $walker = ( empty($r->walker) ) ? new Walker_Nav_Menu : $r->walker; + $args = array( $items, $depth, $r ); + + return call_user_func_array( array(&$walker, 'walk'), $args ); +} + +/** + * Prevents a menu item ID from being used more than once. + * + * @since 3.0.1 + * @access private + */ +function _nav_menu_item_id_use_once( $id, $item ) { + static $_used_ids = array(); + if ( in_array( $item->ID, $_used_ids ) ) + return ''; + $_used_ids[] = $item->ID; + return $id; +} +add_filter( 'nav_menu_item_id', '_nav_menu_item_id_use_once', 10, 2 ); diff --git a/src/wp-includes/nav-menu.php b/src/wp-includes/nav-menu.php new file mode 100644 index 00000000..e1af8f7a --- /dev/null +++ b/src/wp-includes/nav-menu.php @@ -0,0 +1,751 @@ +taxonomy ) && + 'nav_menu' == $menu_obj->taxonomy + ) + return true; + + return false; +} + +/** + * Register navigation menus for a theme. + * + * @since 3.0.0 + * + * @param array $locations Associative array of menu location identifiers (like a slug) and descriptive text. + */ +function register_nav_menus( $locations = array() ) { + global $_wp_registered_nav_menus; + + add_theme_support( 'menus' ); + + $_wp_registered_nav_menus = array_merge( (array) $_wp_registered_nav_menus, $locations ); +} + +/** + * Unregisters a navigation menu for a theme. + * + * @param array $location the menu location identifier + * + * @return bool True on success, false on failure. + */ +function unregister_nav_menu( $location ) { + global $_wp_registered_nav_menus; + + if ( is_array( $_wp_registered_nav_menus ) && isset( $_wp_registered_nav_menus[$location] ) ) { + unset( $_wp_registered_nav_menus[$location] ); + return true; + } + return false; +} + +/** + * Register a navigation menu for a theme. + * + * @since 3.0.0 + * + * @param string $location Menu location identifier, like a slug. + * @param string $description Menu location descriptive text. + */ +function register_nav_menu( $location, $description ) { + register_nav_menus( array( $location => $description ) ); +} +/** + * Returns an array of all registered navigation menus in a theme + * + * @since 3.0.0 + * @return array + */ +function get_registered_nav_menus() { + global $_wp_registered_nav_menus; + if ( isset( $_wp_registered_nav_menus ) ) + return $_wp_registered_nav_menus; + return array(); +} + +/** + * Returns an array with the registered navigation menu locations and the menu assigned to it + * + * @since 3.0.0 + * @return array + */ + +function get_nav_menu_locations() { + return get_theme_mod( 'nav_menu_locations' ); +} + +/** + * Whether a registered nav menu location has a menu assigned to it. + * + * @since 3.0.0 + * @param string $location Menu location identifier. + * @return bool Whether location has a menu. + */ +function has_nav_menu( $location ) { + $locations = get_nav_menu_locations(); + return ( ! empty( $locations[ $location ] ) ); +} + +/** + * Determine whether the given ID is a nav menu item. + * + * @since 3.0.0 + * + * @param int $menu_item_id The ID of the potential nav menu item. + * @return bool Whether the given ID is that of a nav menu item. + */ +function is_nav_menu_item( $menu_item_id = 0 ) { + return ( ! is_wp_error( $menu_item_id ) && ( 'nav_menu_item' == get_post_type( $menu_item_id ) ) ); +} + +/** + * Create a Navigation Menu. + * + * @since 3.0.0 + * + * @param string $menu_name Menu Name + * @return mixed Menu object on success|WP_Error on failure + */ +function wp_create_nav_menu( $menu_name ) { + return wp_update_nav_menu_object( 0, array( 'menu-name' => $menu_name ) ); +} + +/** + * Delete a Navigation Menu. + * + * @since 3.0.0 + * + * @param string $menu name|id|slug + * @return mixed Menu object on success|WP_Error on failure + */ +function wp_delete_nav_menu( $menu ) { + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu ) + return false; + + $menu_objects = get_objects_in_term( $menu->term_id, 'nav_menu' ); + if ( ! empty( $menu_objects ) ) { + foreach ( $menu_objects as $item ) { + wp_delete_post( $item ); + } + } + + $result = wp_delete_term( $menu->term_id, 'nav_menu' ); + + if ( $result && !is_wp_error($result) ) + do_action( 'wp_delete_nav_menu', $menu->term_id ); + + return $result; +} + +/** + * Save the properties of a menu or create a new menu with those properties. + * + * @since 3.0.0 + * + * @param int $menu_id The ID of the menu or "0" to create a new menu. + * @param array $menu_data The array of menu data. + * @return int|error object The menu's ID or WP_Error object. + */ +function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) { + $menu_id = (int) $menu_id; + + $_menu = wp_get_nav_menu_object( $menu_id ); + + $args = array( + 'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ), + 'name' => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ), + 'parent' => ( isset( $menu_data['parent'] ) ? (int) $menu_data['parent'] : 0 ), + 'slug' => null, + ); + + // double-check that we're not going to have one menu take the name of another + $_possible_existing = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' ); + if ( + $_possible_existing && + ! is_wp_error( $_possible_existing ) && + isset( $_possible_existing->term_id ) && + $_possible_existing->term_id != $menu_id + ) + return new WP_Error( 'menu_exists', sprintf( __('The menu name %s conflicts with another menu name. Please try another.'), esc_html( $menu_data['menu-name'] ) ) ); + + // menu doesn't already exist, so create a new menu + if ( ! $_menu || is_wp_error( $_menu ) ) { + $menu_exists = get_term_by( 'name', $menu_data['menu-name'], 'nav_menu' ); + + if ( $menu_exists ) + return new WP_Error( 'menu_exists', sprintf( __('The menu name %s conflicts with another menu name. Please try another.'), esc_html( $menu_data['menu-name'] ) ) ); + + $_menu = wp_insert_term( $menu_data['menu-name'], 'nav_menu', $args ); + + if ( is_wp_error( $_menu ) ) + return $_menu; + + do_action( 'wp_create_nav_menu', $_menu['term_id'], $menu_data ); + + return (int) $_menu['term_id']; + } + + if ( ! $_menu || ! isset( $_menu->term_id ) ) + return 0; + + $menu_id = (int) $_menu->term_id; + + $update_response = wp_update_term( $menu_id, 'nav_menu', $args ); + + if ( is_wp_error( $update_response ) ) + return $update_response; + + do_action( 'wp_update_nav_menu', $menu_id, $menu_data ); + return $menu_id; +} + +/** + * Save the properties of a menu item or create a new one. + * + * @since 3.0.0 + * + * @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan. + * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item. + * @param array $menu_item_data The menu item's data. + * @return int The menu item's database ID or WP_Error object on failure. + */ +function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array() ) { + $menu_id = (int) $menu_id; + $menu_item_db_id = (int) $menu_item_db_id; + + // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects + if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) + return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.')); + + $menu = wp_get_nav_menu_object( $menu_id ); + + if ( ( ! $menu && 0 !== $menu_id ) || is_wp_error( $menu ) ) + return $menu; + + $menu_items = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); + + $count = count( $menu_items ); + + $defaults = array( + 'menu-item-db-id' => $menu_item_db_id, + 'menu-item-object-id' => 0, + 'menu-item-object' => '', + 'menu-item-parent-id' => 0, + 'menu-item-position' => 0, + 'menu-item-type' => 'custom', + 'menu-item-title' => '', + 'menu-item-url' => '', + 'menu-item-description' => '', + 'menu-item-attr-title' => '', + 'menu-item-target' => '', + 'menu-item-classes' => '', + 'menu-item-xfn' => '', + 'menu-item-status' => '', + ); + + $args = wp_parse_args( $menu_item_data, $defaults ); + + if ( 0 == $menu_id ) { + $args['menu-item-position'] = 1; + } elseif ( 0 == (int) $args['menu-item-position'] ) { + $last_item = array_pop( $menu_items ); + $args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : $count; + } + + $original_parent = 0 < $menu_item_db_id ? get_post_field( 'post_parent', $menu_item_db_id ) : 0; + + if ( 'custom' != $args['menu-item-type'] ) { + /* if non-custom menu item, then: + * use original object's URL + * blank default title to sync with original object's + */ + + $args['menu-item-url'] = ''; + + $original_title = ''; + if ( 'taxonomy' == $args['menu-item-type'] ) { + $original_parent = get_term_field( 'parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' ); + $original_title = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' ); + } elseif ( 'post_type' == $args['menu-item-type'] ) { + + $original_object = get_post( $args['menu-item-object-id'] ); + $original_parent = (int) $original_object->post_parent; + $original_title = $original_object->post_title; + } + + if ( empty( $args['menu-item-title'] ) || $args['menu-item-title'] == $original_title ) { + $args['menu-item-title'] = ''; + + // hack to get wp to create a post object when too many properties are empty + if ( empty( $args['menu-item-description'] ) ) + $args['menu-item-description'] = ' '; + } + } + + // Populate the menu item object + $post = array( + 'menu_order' => $args['menu-item-position'], + 'ping_status' => 0, + 'post_content' => $args['menu-item-description'], + 'post_excerpt' => $args['menu-item-attr-title'], + 'post_parent' => $original_parent, + 'post_title' => $args['menu-item-title'], + 'post_type' => 'nav_menu_item', + ); + + if ( 0 != $menu_id ) + $post['tax_input'] = array( 'nav_menu' => array( intval( $menu->term_id ) ) ); + + // New menu item. Default is draft status + if ( 0 == $menu_item_db_id ) { + $post['ID'] = 0; + $post['post_status'] = 'publish' == $args['menu-item-status'] ? 'publish' : 'draft'; + $menu_item_db_id = wp_insert_post( $post ); + + // Update existing menu item. Default is publish status + } else { + $post['ID'] = $menu_item_db_id; + $post['post_status'] = 'draft' == $args['menu-item-status'] ? 'draft' : 'publish'; + wp_update_post( $post ); + } + + if ( 'custom' == $args['menu-item-type'] ) { + $args['menu-item-object-id'] = $menu_item_db_id; + $args['menu-item-object'] = 'custom'; + } + + if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) + return $menu_item_db_id; + + $menu_item_db_id = (int) $menu_item_db_id; + + update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']) ); + update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', (int) $args['menu-item-parent-id'] ); + update_post_meta( $menu_item_db_id, '_menu_item_object_id', (int) $args['menu-item-object-id'] ); + update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']) ); + update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']) ); + + $args['menu-item-classes'] = array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-classes'] ) ); + $args['menu-item-xfn'] = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-xfn'] ) ) ); + update_post_meta( $menu_item_db_id, '_menu_item_classes', $args['menu-item-classes'] ); + update_post_meta( $menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn'] ); + update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) ); + + if ( 0 == $menu_id ) + update_post_meta( $menu_item_db_id, '_menu_item_orphaned', time() ); + else + delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' ); + + do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args ); + + return $menu_item_db_id; +} + +/** + * Returns all navigation menu objects. + * + * @since 3.0.0 + * + * @param array $args Array of arguments passed on to get_terms(). + * @return array menu objects + */ +function wp_get_nav_menus( $args = array() ) { + $defaults = array( 'hide_empty' => false, 'orderby' => 'none' ); + $args = wp_parse_args( $args, $defaults ); + return apply_filters( 'wp_get_nav_menus', get_terms( 'nav_menu', $args), $args ); +} + +/** + * Sort menu items by the desired key. + * + * @since 3.0.0 + * @access private + * + * @param object $a The first object to compare + * @param object $b The second object to compare + * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b. + */ +function _sort_nav_menu_items( $a, $b ) { + global $_menu_item_sort_prop; + + if ( empty( $_menu_item_sort_prop ) ) + return 0; + + if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) ) + return 0; + + $_a = (int) $a->$_menu_item_sort_prop; + $_b = (int) $b->$_menu_item_sort_prop; + + if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop ) + return 0; + elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop ) + return $_a < $_b ? -1 : 1; + else + return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop ); +} + +/** + * Returns all menu items of a navigation menu. + * + * @since 3.0.0 + * + * @param string $menu menu name, id, or slug + * @param string $args + * @return mixed $items array of menu items, else false. + */ +function wp_get_nav_menu_items( $menu, $args = array() ) { + global $_wp_using_ext_object_cache; + + $menu = wp_get_nav_menu_object( $menu ); + + if ( ! $menu ) + return false; + + static $fetched = array(); + + $items = get_objects_in_term( $menu->term_id, 'nav_menu' ); + + if ( empty( $items ) ) + return $items; + + $defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', + 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true, + 'update_post_term_cache' => false ); + $args = wp_parse_args( $args, $defaults ); + if ( count( $items ) > 1 ) + $args['include'] = implode( ',', $items ); + else + $args['include'] = $items[0]; + + $items = get_posts( $args ); + + if ( is_wp_error( $items ) || ! is_array( $items ) ) + return false; + + // Get all posts and terms at once to prime the caches + if ( empty( $fetched[$menu->term_id] ) || $_wp_using_ext_object_cache ) { + $fetched[$menu->term_id] = true; + $posts = array(); + $terms = array(); + foreach ( $items as $item ) { + $object_id = get_post_meta( $item->ID, '_menu_item_object_id', true ); + $object = get_post_meta( $item->ID, '_menu_item_object', true ); + $type = get_post_meta( $item->ID, '_menu_item_type', true ); + + if ( 'post_type' == $type ) + $posts[$object][] = $object_id; + elseif ( 'taxonomy' == $type) + $terms[$object][] = $object_id; + } + + if ( ! empty( $posts ) ) { + foreach ( array_keys($posts) as $post_type ) { + get_posts( array('post__in' => $posts[$post_type], 'post_type' => $post_type, 'nopaging' => true, 'update_post_term_cache' => false) ); + } + } + unset($posts); + + if ( ! empty( $terms ) ) { + foreach ( array_keys($terms) as $taxonomy ) { + get_terms($taxonomy, array('include' => $terms[$taxonomy]) ); + } + } + unset($terms); + } + + $items = array_map( 'wp_setup_nav_menu_item', $items ); + + if ( ARRAY_A == $args['output'] ) { + $GLOBALS['_menu_item_sort_prop'] = $args['output_key']; + usort($items, '_sort_nav_menu_items'); + $i = 1; + foreach( $items as $k => $item ) { + $items[$k]->$args['output_key'] = $i++; + } + } + + return apply_filters( 'wp_get_nav_menu_items', $items, $menu, $args ); +} + +/** + * Decorates a menu item object with the shared navigation menu item properties. + * + * Properties: + * - db_id: The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist). + * - object_id: The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories. + * - type: The family of objects originally represented, such as "post_type" or "taxonomy." + * - object: The type of object originally represented, such as "category," "post", or "attachment." + * - type_label: The singular label used to describe this type of menu item. + * - post_parent: The DB ID of the original object's parent object, if any (0 otherwise). + * - menu_item_parent: The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise. + * - url: The URL to which this menu item points. + * - title: The title of this menu item. + * - target: The target attribute of the link element for this menu item. + * - attr_title: The title attribute of the link element for this menu item. + * - classes: The array of class attribute values for the link element of this menu item. + * - xfn: The XFN relationship expressed in the link of this menu item. + * - description: The description of this menu item. + * + * @since 3.0.0 + * + * @param object $menu_item The menu item to modify. + * @return object $menu_item The menu item with standard menu item properties. + */ +function wp_setup_nav_menu_item( $menu_item ) { + if ( isset( $menu_item->post_type ) ) { + if ( 'nav_menu_item' == $menu_item->post_type ) { + $menu_item->db_id = (int) $menu_item->ID; + $menu_item->menu_item_parent = empty( $menu_item->menu_item_parent ) ? get_post_meta( $menu_item->ID, '_menu_item_menu_item_parent', true ) : $menu_item->menu_item_parent; + $menu_item->object_id = empty( $menu_item->object_id ) ? get_post_meta( $menu_item->ID, '_menu_item_object_id', true ) : $menu_item->object_id; + $menu_item->object = empty( $menu_item->object ) ? get_post_meta( $menu_item->ID, '_menu_item_object', true ) : $menu_item->object; + $menu_item->type = empty( $menu_item->type ) ? get_post_meta( $menu_item->ID, '_menu_item_type', true ) : $menu_item->type; + + if ( 'post_type' == $menu_item->type ) { + $object = get_post_type_object( $menu_item->object ); + $menu_item->type_label = $object->labels->singular_name; + $menu_item->url = get_permalink( $menu_item->object_id ); + + $original_object = get_post( $menu_item->object_id ); + $original_title = $original_object->post_title; + $menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title; + + } elseif ( 'taxonomy' == $menu_item->type ) { + $object = get_taxonomy( $menu_item->object ); + $menu_item->type_label = $object->labels->singular_name; + $term_url = get_term_link( (int) $menu_item->object_id, $menu_item->object ); + $menu_item->url = !is_wp_error( $term_url ) ? $term_url : ''; + + $original_title = get_term_field( 'name', $menu_item->object_id, $menu_item->object, 'raw' ); + $menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title; + + } else { + $menu_item->type_label = __('Custom'); + $menu_item->title = $menu_item->post_title; + $menu_item->url = empty( $menu_item->url ) ? get_post_meta( $menu_item->ID, '_menu_item_url', true ) : $menu_item->url; + } + + $menu_item->target = empty( $menu_item->target ) ? get_post_meta( $menu_item->ID, '_menu_item_target', true ) : $menu_item->target; + + $menu_item->attr_title = empty( $menu_item->attr_title ) ? apply_filters( 'nav_menu_attr_title', $menu_item->post_excerpt ) : $menu_item->attr_title; + $menu_item->description = empty( $menu_item->description ) ? apply_filters( 'nav_menu_description', $menu_item->post_content ) : $menu_item->description; + + $menu_item->classes = empty( $menu_item->classes ) ? (array) get_post_meta( $menu_item->ID, '_menu_item_classes', true ) : $menu_item->classes; + $menu_item->xfn = empty( $menu_item->xfn ) ? get_post_meta( $menu_item->ID, '_menu_item_xfn', true ) : $menu_item->xfn; + } else { + $menu_item->db_id = 0; + $menu_item->menu_item_parent = 0; + $menu_item->object_id = (int) $menu_item->ID; + $menu_item->type = 'post_type'; + + $object = get_post_type_object( $menu_item->post_type ); + $menu_item->object = $object->name; + $menu_item->type_label = $object->labels->singular_name; + + $menu_item->title = $menu_item->post_title; + $menu_item->url = get_permalink( $menu_item->ID ); + $menu_item->target = ''; + + $menu_item->attr_title = apply_filters( 'nav_menu_attr_title', $menu_item->post_excerpt ); + $menu_item->description = apply_filters( 'nav_menu_description', $menu_item->post_content ); + $menu_item->classes = array(); + $menu_item->xfn = ''; + } + } elseif ( isset( $menu_item->taxonomy ) ) { + $menu_item->ID = $menu_item->term_id; + $menu_item->db_id = 0; + $menu_item->menu_item_parent = 0; + $menu_item->object_id = (int) $menu_item->term_id; + $menu_item->post_parent = (int) $menu_item->parent; + $menu_item->type = 'taxonomy'; + + $object = get_taxonomy( $menu_item->taxonomy ); + $menu_item->object = $object->name; + $menu_item->type_label = $object->labels->singular_name; + + $menu_item->title = $menu_item->name; + $menu_item->url = get_term_link( $menu_item, $menu_item->taxonomy ); + $menu_item->target = ''; + $menu_item->attr_title = ''; + $menu_item->description = get_term_field( 'description', $menu_item->term_id, $menu_item->taxonomy ); + $menu_item->classes = array(); + $menu_item->xfn = ''; + + } + + return apply_filters( 'wp_setup_nav_menu_item', $menu_item ); +} + +/** + * Get the menu items associated with a particular object. + * + * @since 3.0.0 + * + * @param int $object_id The ID of the original object. + * @param string $object_type The type of object, such as "taxonomy" or "post_type." + * @return array The array of menu item IDs; empty array if none; + */ +function wp_get_associated_nav_menu_items( $object_id = 0, $object_type = 'post_type' ) { + $object_id = (int) $object_id; + $menu_item_ids = array(); + + $query = new WP_Query; + $menu_items = $query->query( + array( + 'meta_key' => '_menu_item_object_id', + 'meta_value' => $object_id, + 'post_status' => 'any', + 'post_type' => 'nav_menu_item', + 'posts_per_page' => -1, + ) + ); + foreach( (array) $menu_items as $menu_item ) { + if ( isset( $menu_item->ID ) && is_nav_menu_item( $menu_item->ID ) ) { + if ( get_post_meta( $menu_item->ID, '_menu_item_type', true ) != $object_type ) + continue; + + $menu_item_ids[] = (int) $menu_item->ID; + } + } + + return array_unique( $menu_item_ids ); +} + +/** + * Callback for handling a menu item when its original object is deleted. + * + * @since 3.0.0 + * @access private + * + * @param int $object_id The ID of the original object being trashed. + * + */ +function _wp_delete_post_menu_item( $object_id = 0 ) { + $object_id = (int) $object_id; + + $menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'post_type' ); + + foreach( (array) $menu_item_ids as $menu_item_id ) { + wp_delete_post( $menu_item_id, true ); + } +} + +/** + * Callback for handling a menu item when its original object is deleted. + * + * @since 3.0.0 + * @access private + * + * @param int $object_id The ID of the original object being trashed. + * + */ +function _wp_delete_tax_menu_item( $object_id = 0 ) { + $object_id = (int) $object_id; + + $menu_item_ids = wp_get_associated_nav_menu_items( $object_id, 'taxonomy' ); + + foreach( (array) $menu_item_ids as $menu_item_id ) { + wp_delete_post( $menu_item_id, true ); + } +} + +/** + * Automatically add newly published page objects to menus with that as an option. + * + * @since 3.0.0 + * @access private + * + * @param string $new_status The new status of the post object. + * @param string $old_status The old status of the post object. + * @param object $post The post object being transitioned from one status to another. + * @return void + */ +function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) { + if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type ) + return; + if ( ! empty( $post->post_parent ) ) + return; + $auto_add = get_option( 'nav_menu_options' ); + if ( empty( $auto_add ) || ! is_array( $auto_add ) || ! isset( $auto_add['auto_add'] ) ) + return; + $auto_add = $auto_add['auto_add']; + if ( empty( $auto_add ) || ! is_array( $auto_add ) ) + return; + + $args = array( + 'menu-item-object-id' => $post->ID, + 'menu-item-object' => $post->post_type, + 'menu-item-type' => 'post_type', + 'menu-item-status' => 'publish', + ); + + foreach ( $auto_add as $menu_id ) { + $items = wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); + if ( ! is_array( $items ) ) + continue; + foreach ( $items as $item ) { + if ( $post->ID == $item->object_id ) + continue 2; + } + wp_update_nav_menu_item( $menu_id, 0, $args ); + } +} + +?> diff --git a/src/wp-includes/pluggable-deprecated.php b/src/wp-includes/pluggable-deprecated.php new file mode 100644 index 00000000..bb0e4f0e --- /dev/null +++ b/src/wp-includes/pluggable-deprecated.php @@ -0,0 +1,136 @@ +ID, $remember); +} +else : + _deprecated_function( 'wp_setcookie', '2.5', 'wp_set_auth_cookie()' ); +endif; + +if ( !function_exists('wp_clearcookie') ) : +/** + * Clears the authentication cookie, logging the user out. This function is deprecated. + * + * @since 1.5 + * @deprecated 2.5 + * @deprecated Use wp_clear_auth_cookie() + * @see wp_clear_auth_cookie() + */ +function wp_clearcookie() { + _deprecated_function( __FUNCTION__, '2.5', 'wp_clear_auth_cookie()' ); + wp_clear_auth_cookie(); +} +else : + _deprecated_function( 'wp_clearcookie', '2.5', 'wp_clear_auth_cookie()' ); +endif; + +if ( !function_exists('wp_get_cookie_login') ): +/** + * Gets the user cookie login. This function is deprecated. + * + * This function is deprecated and should no longer be extended as it won't be + * used anywhere in WordPress. Also, plugins shouldn't use it either. + * + * @since 2.0.3 + * @deprecated 2.5 + * @deprecated No alternative + * + * @return bool Always returns false + */ +function wp_get_cookie_login() { + _deprecated_function( __FUNCTION__, '2.5' ); + return false; +} +else : + _deprecated_function( 'wp_get_cookie_login', '2.5' ); +endif; + +if ( !function_exists('wp_login') ) : +/** + * Checks a users login information and logs them in if it checks out. This function is deprecated. + * + * Use the global $error to get the reason why the login failed. If the username + * is blank, no error will be set, so assume blank username on that case. + * + * Plugins extending this function should also provide the global $error and set + * what the error is, so that those checking the global for why there was a + * failure can utilize it later. + * + * @since 1.2.2 + * @deprecated Use wp_signon() + * @global string $error Error when false is returned + * + * @param string $username User's username + * @param string $password User's password + * @param bool $deprecated Not used + * @return bool False on login failure, true on successful check + */ +function wp_login($username, $password, $deprecated = '') { + _deprecated_function( __FUNCTION__, '2.5', 'wp_signon()' ); + global $error; + + $user = wp_authenticate($username, $password); + + if ( ! is_wp_error($user) ) + return true; + + $error = $user->get_error_message(); + return false; +} +else : + _deprecated_function( 'wp_login', '2.5', 'wp_signon()' ); +endif; \ No newline at end of file diff --git a/src/wp-includes/pluggable.php b/src/wp-includes/pluggable.php new file mode 100644 index 00000000..9bf35d70 --- /dev/null +++ b/src/wp-includes/pluggable.php @@ -0,0 +1,1774 @@ +ID) ) + return $current_user; + + $current_user = new WP_User($id, $name); + + setup_userdata($current_user->ID); + + do_action('set_current_user'); + + return $current_user; +} +endif; + +if ( !function_exists('wp_get_current_user') ) : +/** + * Retrieve the current user object. + * + * @since 2.0.3 + * + * @return WP_User Current user WP_User object + */ +function wp_get_current_user() { + global $current_user; + + get_currentuserinfo(); + + return $current_user; +} +endif; + +if ( !function_exists('get_currentuserinfo') ) : +/** + * Populate global variables with information about the currently logged in user. + * + * Will set the current user, if the current user is not set. The current user + * will be set to the logged in person. If no user is logged in, then it will + * set the current user to 0, which is invalid and won't have any permissions. + * + * @since 0.71 + * @uses $current_user Checks if the current user is set + * @uses wp_validate_auth_cookie() Retrieves current logged in user. + * + * @return bool|null False on XMLRPC Request and invalid auth cookie. Null when current user set + */ +function get_currentuserinfo() { + global $current_user; + + if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) + return false; + + if ( ! empty($current_user) ) + return; + + if ( ! $user = wp_validate_auth_cookie() ) { + if ( is_blog_admin() || is_network_admin() || empty($_COOKIE[LOGGED_IN_COOKIE]) || !$user = wp_validate_auth_cookie($_COOKIE[LOGGED_IN_COOKIE], 'logged_in') ) { + wp_set_current_user(0); + return false; + } + } + + wp_set_current_user($user); +} +endif; + +if ( !function_exists('get_userdata') ) : +/** + * Retrieve user info by user ID. + * + * @since 0.71 + * + * @param int $user_id User ID + * @return bool|object False on failure, User DB row object + */ +function get_userdata( $user_id ) { + global $wpdb; + + if ( ! is_numeric( $user_id ) ) + return false; + + $user_id = absint( $user_id ); + if ( ! $user_id ) + return false; + + $user = wp_cache_get( $user_id, 'users' ); + + if ( $user ) + return $user; + + if ( ! $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE ID = %d LIMIT 1", $user_id ) ) ) + return false; + + _fill_user( $user ); + + return $user; +} +endif; + +if ( !function_exists('cache_users') ) : +/** + * Retrieve info for user lists to prevent multiple queries by get_userdata() + * + * @since 3.0.0 + * + * @param array $users User ID numbers list + */ +function cache_users( $users ) { + global $wpdb; + + $clean = array(); + foreach($users as $id) { + $id = (int) $id; + if (wp_cache_get($id, 'users')) { + // seems to be cached already + } else { + $clean[] = $id; + } + } + + if ( 0 == count($clean) ) + return; + + $list = implode(',', $clean); + + $results = $wpdb->get_results("SELECT * FROM $wpdb->users WHERE ID IN ($list)"); + + _fill_many_users($results); +} +endif; + +if ( !function_exists('get_user_by') ) : +/** + * Retrieve user info by a given field + * + * @since 2.8.0 + * + * @param string $field The field to retrieve the user with. id | slug | email | login + * @param int|string $value A value for $field. A user ID, slug, email address, or login name. + * @return bool|object False on failure, User DB row object + */ +function get_user_by($field, $value) { + global $wpdb; + + switch ($field) { + case 'id': + return get_userdata($value); + break; + case 'slug': + $user_id = wp_cache_get($value, 'userslugs'); + $field = 'user_nicename'; + break; + case 'email': + $user_id = wp_cache_get($value, 'useremail'); + $field = 'user_email'; + break; + case 'login': + $value = sanitize_user( $value ); + $user_id = wp_cache_get($value, 'userlogins'); + $field = 'user_login'; + break; + default: + return false; + } + + if ( false !== $user_id ) + return get_userdata($user_id); + + if ( !$user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE $field = %s", $value) ) ) + return false; + + _fill_user($user); + + return $user; +} +endif; + +if ( !function_exists('get_userdatabylogin') ) : +/** + * Retrieve user info by login name. + * + * @since 0.71 + * + * @param string $user_login User's username + * @return bool|object False on failure, User DB row object + */ +function get_userdatabylogin($user_login) { + return get_user_by('login', $user_login); +} +endif; + +if ( !function_exists('get_user_by_email') ) : +/** + * Retrieve user info by email. + * + * @since 2.5 + * + * @param string $email User's email address + * @return bool|object False on failure, User DB row object + */ +function get_user_by_email($email) { + return get_user_by('email', $email); +} +endif; + +if ( !function_exists( 'wp_mail' ) ) : +/** + * Send mail, similar to PHP's mail + * + * A true return value does not automatically mean that the user received the + * email successfully. It just only means that the method used was able to + * process the request without any errors. + * + * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from + * creating a from address like 'Name ' when both are set. If + * just 'wp_mail_from' is set, then just the email address will be used with no + * name. + * + * The default content type is 'text/plain' which does not allow using HTML. + * However, you can set the content type of the email by using the + * 'wp_mail_content_type' filter. + * + * The default charset is based on the charset used on the blog. The charset can + * be set using the 'wp_mail_charset' filter. + * + * @since 1.2.1 + * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters. + * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address. + * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name. + * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type. + * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset + * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to + * phpmailer object. + * @uses PHPMailer + * @ + * + * @param string|array $to Array or comma-separated list of email addresses to send message. + * @param string $subject Email subject + * @param string $message Message contents + * @param string|array $headers Optional. Additional headers. + * @param string|array $attachments Optional. Files to attach. + * @return bool Whether the email contents were sent successfully. + */ +function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) { + // Compact the input, apply the filters, and extract them back out + extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) ); + + if ( !is_array($attachments) ) + $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) ); + + global $phpmailer; + + // (Re)create it, if it's gone missing + if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) { + require_once ABSPATH . WPINC . '/class-phpmailer.php'; + require_once ABSPATH . WPINC . '/class-smtp.php'; + $phpmailer = new PHPMailer(); + } + + // Headers + if ( empty( $headers ) ) { + $headers = array(); + } else { + if ( !is_array( $headers ) ) { + // Explode the headers out, so this function can take both + // string headers and an array of headers. + $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) ); + } else { + $tempheaders = $headers; + } + $headers = array(); + + // If it's actually got contents + if ( !empty( $tempheaders ) ) { + // Iterate through the raw headers + foreach ( (array) $tempheaders as $header ) { + if ( strpos($header, ':') === false ) { + if ( false !== stripos( $header, 'boundary=' ) ) { + $parts = preg_split('/boundary=/i', trim( $header ) ); + $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) ); + } + continue; + } + // Explode them out + list( $name, $content ) = explode( ':', trim( $header ), 2 ); + + // Cleanup crew + $name = trim( $name ); + $content = trim( $content ); + + switch ( strtolower( $name ) ) { + // Mainly for legacy -- process a From: header if it's there + case 'from': + if ( strpos($content, '<' ) !== false ) { + // So... making my life hard again? + $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 ); + $from_name = str_replace( '"', '', $from_name ); + $from_name = trim( $from_name ); + + $from_email = substr( $content, strpos( $content, '<' ) + 1 ); + $from_email = str_replace( '>', '', $from_email ); + $from_email = trim( $from_email ); + } else { + $from_email = trim( $content ); + } + break; + case 'content-type': + if ( strpos( $content, ';' ) !== false ) { + list( $type, $charset ) = explode( ';', $content ); + $content_type = trim( $type ); + if ( false !== stripos( $charset, 'charset=' ) ) { + $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) ); + } elseif ( false !== stripos( $charset, 'boundary=' ) ) { + $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset ) ); + $charset = ''; + } + } else { + $content_type = trim( $content ); + } + break; + case 'cc': + $cc = array_merge( (array) $cc, explode( ',', $content ) ); + break; + case 'bcc': + $bcc = array_merge( (array) $bcc, explode( ',', $content ) ); + break; + default: + // Add it to our grand headers array + $headers[trim( $name )] = trim( $content ); + break; + } + } + } + } + + // Empty out the values that may be set + $phpmailer->ClearAddresses(); + $phpmailer->ClearAllRecipients(); + $phpmailer->ClearAttachments(); + $phpmailer->ClearBCCs(); + $phpmailer->ClearCCs(); + $phpmailer->ClearCustomHeaders(); + $phpmailer->ClearReplyTos(); + + // From email and name + // If we don't have a name from the input headers + if ( !isset( $from_name ) ) + $from_name = 'WordPress'; + + /* If we don't have an email from the input headers default to wordpress@$sitename + * Some hosts will block outgoing mail from this address if it doesn't exist but + * there's no easy alternative. Defaulting to admin_email might appear to be another + * option but some hosts may refuse to relay mail from an unknown domain. See + * http://trac.wordpress.org/ticket/5007. + */ + + if ( !isset( $from_email ) ) { + // Get the site domain and get rid of www. + $sitename = strtolower( $_SERVER['SERVER_NAME'] ); + if ( substr( $sitename, 0, 4 ) == 'www.' ) { + $sitename = substr( $sitename, 4 ); + } + + $from_email = 'wordpress@' . $sitename; + } + + // Plugin authors can override the potentially troublesome default + $phpmailer->From = apply_filters( 'wp_mail_from' , $from_email ); + $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name ); + + // Set destination addresses + if ( !is_array( $to ) ) + $to = explode( ',', $to ); + + foreach ( (array) $to as $recipient ) { + $phpmailer->AddAddress( trim( $recipient ) ); + } + + // Set mail's subject and body + $phpmailer->Subject = $subject; + $phpmailer->Body = $message; + + // Add any CC and BCC recipients + if ( !empty( $cc ) ) { + foreach ( (array) $cc as $recipient ) { + $phpmailer->AddCc( trim($recipient) ); + } + } + + if ( !empty( $bcc ) ) { + foreach ( (array) $bcc as $recipient) { + $phpmailer->AddBcc( trim($recipient) ); + } + } + + // Set to use PHP's mail() + $phpmailer->IsMail(); + + // Set Content-Type and charset + // If we don't have a content-type from the input headers + if ( !isset( $content_type ) ) + $content_type = 'text/plain'; + + $content_type = apply_filters( 'wp_mail_content_type', $content_type ); + + $phpmailer->ContentType = $content_type; + + // Set whether it's plaintext, depending on $content_type + if ( 'text/html' == $content_type ) + $phpmailer->IsHTML( true ); + + // If we don't have a charset from the input headers + if ( !isset( $charset ) ) + $charset = get_bloginfo( 'charset' ); + + // Set the content-type and charset + $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset ); + + // Set custom headers + if ( !empty( $headers ) ) { + foreach( (array) $headers as $name => $content ) { + $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) ); + } + + if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) ) + $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) ); + } + + if ( !empty( $attachments ) ) { + foreach ( $attachments as $attachment ) { + $phpmailer->AddAttachment($attachment); + } + } + + do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) ); + + // Send! + $result = @$phpmailer->Send(); + + return $result; +} +endif; + +if ( !function_exists('wp_authenticate') ) : +/** + * Checks a user's login information and logs them in if it checks out. + * + * @since 2.5.0 + * + * @param string $username User's username + * @param string $password User's password + * @return WP_Error|WP_User WP_User object if login successful, otherwise WP_Error object. + */ +function wp_authenticate($username, $password) { + $username = sanitize_user($username); + $password = trim($password); + + $user = apply_filters('authenticate', null, $username, $password); + + if ( $user == null ) { + // TODO what should the error message be? (Or would these even happen?) + // Only needed if all authentication handlers fail to return anything. + $user = new WP_Error('authentication_failed', __('ERROR: Invalid username or incorrect password.')); + } + + $ignore_codes = array('empty_username', 'empty_password'); + + if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) { + do_action('wp_login_failed', $username); + } + + return $user; +} +endif; + +if ( !function_exists('wp_logout') ) : +/** + * Log the current user out. + * + * @since 2.5.0 + */ +function wp_logout() { + wp_clear_auth_cookie(); + do_action('wp_logout'); +} +endif; + +if ( !function_exists('wp_validate_auth_cookie') ) : +/** + * Validates authentication cookie. + * + * The checks include making sure that the authentication cookie is set and + * pulling in the contents (if $cookie is not used). + * + * Makes sure the cookie is not expired. Verifies the hash in cookie is what is + * should be and compares the two. + * + * @since 2.5 + * + * @param string $cookie Optional. If used, will validate contents instead of cookie's + * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in + * @return bool|int False if invalid cookie, User ID if valid. + */ +function wp_validate_auth_cookie($cookie = '', $scheme = '') { + if ( ! $cookie_elements = wp_parse_auth_cookie($cookie, $scheme) ) { + do_action('auth_cookie_malformed', $cookie, $scheme); + return false; + } + + extract($cookie_elements, EXTR_OVERWRITE); + + $expired = $expiration; + + // Allow a grace period for POST and AJAX requests + if ( defined('DOING_AJAX') || 'POST' == $_SERVER['REQUEST_METHOD'] ) + $expired += 3600; + + // Quick check to see if an honest cookie has expired + if ( $expired < time() ) { + do_action('auth_cookie_expired', $cookie_elements); + return false; + } + + $user = get_userdatabylogin($username); + if ( ! $user ) { + do_action('auth_cookie_bad_username', $cookie_elements); + return false; + } + + $pass_frag = substr($user->user_pass, 8, 4); + + $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme); + $hash = hash_hmac('md5', $username . '|' . $expiration, $key); + + if ( $hmac != $hash ) { + do_action('auth_cookie_bad_hash', $cookie_elements); + return false; + } + + if ( $expiration < time() ) // AJAX/POST grace period set above + $GLOBALS['login_grace_period'] = 1; + + do_action('auth_cookie_valid', $cookie_elements, $user); + + return $user->ID; +} +endif; + +if ( !function_exists('wp_generate_auth_cookie') ) : +/** + * Generate authentication cookie contents. + * + * @since 2.5 + * @uses apply_filters() Calls 'auth_cookie' hook on $cookie contents, User ID + * and expiration of cookie. + * + * @param int $user_id User ID + * @param int $expiration Cookie expiration in seconds + * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in + * @return string Authentication cookie contents + */ +function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') { + $user = get_userdata($user_id); + + $pass_frag = substr($user->user_pass, 8, 4); + + $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme); + $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key); + + $cookie = $user->user_login . '|' . $expiration . '|' . $hash; + + return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme); +} +endif; + +if ( !function_exists('wp_parse_auth_cookie') ) : +/** + * Parse a cookie into its components + * + * @since 2.7 + * + * @param string $cookie + * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in + * @return array Authentication cookie components + */ +function wp_parse_auth_cookie($cookie = '', $scheme = '') { + if ( empty($cookie) ) { + switch ($scheme){ + case 'auth': + $cookie_name = AUTH_COOKIE; + break; + case 'secure_auth': + $cookie_name = SECURE_AUTH_COOKIE; + break; + case "logged_in": + $cookie_name = LOGGED_IN_COOKIE; + break; + default: + if ( is_ssl() ) { + $cookie_name = SECURE_AUTH_COOKIE; + $scheme = 'secure_auth'; + } else { + $cookie_name = AUTH_COOKIE; + $scheme = 'auth'; + } + } + + if ( empty($_COOKIE[$cookie_name]) ) + return false; + $cookie = $_COOKIE[$cookie_name]; + } + + $cookie_elements = explode('|', $cookie); + if ( count($cookie_elements) != 3 ) + return false; + + list($username, $expiration, $hmac) = $cookie_elements; + + return compact('username', 'expiration', 'hmac', 'scheme'); +} +endif; + +if ( !function_exists('wp_set_auth_cookie') ) : +/** + * Sets the authentication cookies based User ID. + * + * The $remember parameter increases the time that the cookie will be kept. The + * default the cookie is kept without remembering is two days. When $remember is + * set, the cookies will be kept for 14 days or two weeks. + * + * @since 2.5 + * + * @param int $user_id User ID + * @param bool $remember Whether to remember the user + */ +function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { + if ( $remember ) { + $expiration = $expire = time() + apply_filters('auth_cookie_expiration', 1209600, $user_id, $remember); + } else { + $expiration = time() + apply_filters('auth_cookie_expiration', 172800, $user_id, $remember); + $expire = 0; + } + + if ( '' === $secure ) + $secure = is_ssl(); + + $secure = apply_filters('secure_auth_cookie', $secure, $user_id); + $secure_logged_in_cookie = apply_filters('secure_logged_in_cookie', false, $user_id, $secure); + + if ( $secure ) { + $auth_cookie_name = SECURE_AUTH_COOKIE; + $scheme = 'secure_auth'; + } else { + $auth_cookie_name = AUTH_COOKIE; + $scheme = 'auth'; + } + + $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme); + $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in'); + + do_action('set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme); + do_action('set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in'); + + // Set httponly if the php version is >= 5.2.0 + if ( version_compare(phpversion(), '5.2.0', 'ge') ) { + setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); + setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); + setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); + if ( COOKIEPATH != SITECOOKIEPATH ) + setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); + } else { + $cookie_domain = COOKIE_DOMAIN; + if ( !empty($cookie_domain) ) + $cookie_domain .= '; HttpOnly'; + setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, $cookie_domain, $secure); + setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, $cookie_domain, $secure); + setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, $cookie_domain, $secure_logged_in_cookie); + if ( COOKIEPATH != SITECOOKIEPATH ) + setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, $cookie_domain, $secure_logged_in_cookie); + } +} +endif; + +if ( !function_exists('wp_clear_auth_cookie') ) : +/** + * Removes all of the cookies associated with authentication. + * + * @since 2.5 + */ +function wp_clear_auth_cookie() { + do_action('clear_auth_cookie'); + + setcookie(AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN); + setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN); + setcookie(AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN); + setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN); + setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + + // Old cookies + setcookie(AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + + // Even older cookies + setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); +} +endif; + +if ( !function_exists('is_user_logged_in') ) : +/** + * Checks if the current visitor is a logged in user. + * + * @since 2.0.0 + * + * @return bool True if user is logged in, false if not logged in. + */ +function is_user_logged_in() { + $user = wp_get_current_user(); + + if ( $user->id == 0 ) + return false; + + return true; +} +endif; + +if ( !function_exists('auth_redirect') ) : +/** + * Checks if a user is logged in, if not it redirects them to the login page. + * + * @since 1.5 + */ +function auth_redirect() { + // Checks if a user is logged in, if not redirects them to the login page + + $secure = ( is_ssl() || force_ssl_admin() ); + + $secure = apply_filters('secure_auth_redirect', $secure); + + // If https is required and request is http, redirect + if ( $secure && !is_ssl() && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { + if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { + wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); + exit(); + } else { + wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); + exit(); + } + } + + if ( is_user_admin() ) + $scheme = 'logged_in'; + else + $scheme = apply_filters( 'auth_redirect_scheme', '' ); + + if ( $user_id = wp_validate_auth_cookie( '', $scheme) ) { + do_action('auth_redirect', $user_id); + + // If the user wants ssl but the session is not ssl, redirect. + if ( !$secure && get_user_option('use_ssl', $user_id) && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { + if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { + wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); + exit(); + } else { + wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); + exit(); + } + } + + return; // The cookie is good so we're done + } + + // The cookie is no good so force login + nocache_headers(); + + if ( is_ssl() ) + $proto = 'https://'; + else + $proto = 'http://'; + + $redirect = ( strpos($_SERVER['REQUEST_URI'], '/options.php') && wp_get_referer() ) ? wp_get_referer() : $proto . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + + $login_url = wp_login_url($redirect, true); + + wp_redirect($login_url); + exit(); +} +endif; + +if ( !function_exists('check_admin_referer') ) : +/** + * Makes sure that a user was referred from another admin page. + * + * To avoid security exploits. + * + * @since 1.2.0 + * @uses do_action() Calls 'check_admin_referer' on $action. + * + * @param string $action Action nonce + * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) + */ +function check_admin_referer($action = -1, $query_arg = '_wpnonce') { + $adminurl = strtolower(admin_url()); + $referer = strtolower(wp_get_referer()); + $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false; + if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) { + wp_nonce_ays($action); + die(); + } + do_action('check_admin_referer', $action, $result); + return $result; +}endif; + +if ( !function_exists('check_ajax_referer') ) : +/** + * Verifies the AJAX request to prevent processing requests external of the blog. + * + * @since 2.0.3 + * + * @param string $action Action nonce + * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) + */ +function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) { + if ( $query_arg ) + $nonce = $_REQUEST[$query_arg]; + else + $nonce = isset($_REQUEST['_ajax_nonce']) ? $_REQUEST['_ajax_nonce'] : $_REQUEST['_wpnonce']; + + $result = wp_verify_nonce( $nonce, $action ); + + if ( $die && false == $result ) + die('-1'); + + do_action('check_ajax_referer', $action, $result); + + return $result; +} +endif; + +if ( !function_exists('wp_redirect') ) : +/** + * Redirects to another page. + * + * @since 1.5.1 + * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status. + * + * @param string $location The path to redirect to + * @param int $status Status code to use + * @return bool False if $location is not set + */ +function wp_redirect($location, $status = 302) { + global $is_IIS; + + $location = apply_filters('wp_redirect', $location, $status); + $status = apply_filters('wp_redirect_status', $status, $location); + + if ( !$location ) // allows the wp_redirect filter to cancel a redirect + return false; + + $location = wp_sanitize_redirect($location); + + if ( !$is_IIS && php_sapi_name() != 'cgi-fcgi' ) + status_header($status); // This causes problems on IIS and some FastCGI setups + + header("Location: $location", true, $status); +} +endif; + +if ( !function_exists('wp_sanitize_redirect') ) : +/** + * Sanitizes a URL for use in a redirect. + * + * @since 2.3 + * + * @return string redirect-sanitized URL + **/ +function wp_sanitize_redirect($location) { + $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location); + $location = wp_kses_no_null($location); + + // remove %0d and %0a from location + $strip = array('%0d', '%0a', '%0D', '%0A'); + $location = _deep_replace($strip, $location); + return $location; +} +endif; + +if ( !function_exists('wp_safe_redirect') ) : +/** + * Performs a safe (local) redirect, using wp_redirect(). + * + * Checks whether the $location is using an allowed host, if it has an absolute + * path. A plugin can therefore set or remove allowed host(s) to or from the + * list. + * + * If the host is not allowed, then the redirect is to wp-admin on the siteurl + * instead. This prevents malicious redirects which redirect to another host, + * but only used in a few places. + * + * @since 2.3 + * @uses wp_validate_redirect() To validate the redirect is to an allowed host. + * + * @return void Does not return anything + **/ +function wp_safe_redirect($location, $status = 302) { + + // Need to look at the URL the way it will end up in wp_redirect() + $location = wp_sanitize_redirect($location); + + $location = wp_validate_redirect($location, admin_url()); + + wp_redirect($location, $status); +} +endif; + +if ( !function_exists('wp_validate_redirect') ) : +/** + * Validates a URL for use in a redirect. + * + * Checks whether the $location is using an allowed host, if it has an absolute + * path. A plugin can therefore set or remove allowed host(s) to or from the + * list. + * + * If the host is not allowed, then the redirect is to $default supplied + * + * @since 2.8.1 + * @uses apply_filters() Calls 'allowed_redirect_hosts' on an array containing + * WordPress host string and $location host string. + * + * @param string $location The redirect to validate + * @param string $default The value to return is $location is not allowed + * @return string redirect-sanitized URL + **/ +function wp_validate_redirect($location, $default = '') { + // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//' + if ( substr($location, 0, 2) == '//' ) + $location = 'http:' . $location; + + // In php 5 parse_url may fail if the URL query part contains http://, bug #38143 + $test = ( $cut = strpos($location, '?') ) ? substr( $location, 0, $cut ) : $location; + + $lp = parse_url($test); + + // Give up if malformed URL + if ( false === $lp ) + return $default; + + // Allow only http and https schemes. No data:, etc. + if ( isset($lp['scheme']) && !('http' == $lp['scheme'] || 'https' == $lp['scheme']) ) + return $default; + + // Reject if scheme is set but host is not. This catches urls like https:host.com for which parse_url does not set the host field. + if ( isset($lp['scheme']) && !isset($lp['host']) ) + return $default; + + $wpp = parse_url(home_url()); + + $allowed_hosts = (array) apply_filters('allowed_redirect_hosts', array($wpp['host']), isset($lp['host']) ? $lp['host'] : ''); + + if ( isset($lp['host']) && ( !in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host'])) ) + $location = $default; + + return $location; +} +endif; + +if ( ! function_exists('wp_notify_postauthor') ) : +/** + * Notify an author of a comment/trackback/pingback to one of their posts. + * + * @since 1.0.0 + * + * @param int $comment_id Comment ID + * @param string $comment_type Optional. The comment type either 'comment' (default), 'trackback', or 'pingback' + * @return bool False if user email does not exist. True on completion. + */ +function wp_notify_postauthor( $comment_id, $comment_type = '' ) { + $comment = get_comment( $comment_id ); + $post = get_post( $comment->comment_post_ID ); + $author = get_userdata( $post->post_author ); + + // The comment was left by the author + if ( $comment->user_id == $post->post_author ) + return false; + + // The author moderated a comment on his own post + if ( $post->post_author == get_current_user_id() ) + return false; + + // If there's no email to send the comment to + if ( '' == $author->user_email ) + return false; + + $comment_author_domain = @gethostbyaddr($comment->comment_author_IP); + + // The blogname option is escaped with esc_html on the way into the database in sanitize_option + // we want to reverse this for the plain text arena of emails. + $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + + if ( empty( $comment_type ) ) $comment_type = 'comment'; + + if ('comment' == $comment_type) { + $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n"; + /* translators: 1: comment author, 2: author IP, 3: author domain */ + $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; + $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= sprintf( __('Whois : http://whois.arin.net/rest/ip/%s'), $comment->comment_author_IP ) . "\r\n"; + $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + $notify_message .= __('You can see all comments on this post here: ') . "\r\n"; + /* translators: 1: blog name, 2: post title */ + $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title ); + } elseif ('trackback' == $comment_type) { + $notify_message = sprintf( __( 'New trackback on your post "%s"' ), $post->post_title ) . "\r\n"; + /* translators: 1: website name, 2: author IP, 3: author domain */ + $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + $notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n"; + /* translators: 1: blog name, 2: post title */ + $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title ); + } elseif ('pingback' == $comment_type) { + $notify_message = sprintf( __( 'New pingback on your post "%s"' ), $post->post_title ) . "\r\n"; + /* translators: 1: comment author, 2: author IP, 3: author domain */ + $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n"; + $notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n"; + /* translators: 1: blog name, 2: post title */ + $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title ); + } + $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n"; + $notify_message .= sprintf( __('Permalink: %s'), get_permalink( $comment->comment_post_ID ) . '#comment-' . $comment_id ) . "\r\n"; + if ( EMPTY_TRASH_DAYS ) + $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; + else + $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; + $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; + + $wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); + + if ( '' == $comment->comment_author ) { + $from = "From: \"$blogname\" <$wp_email>"; + if ( '' != $comment->comment_author_email ) + $reply_to = "Reply-To: $comment->comment_author_email"; + } else { + $from = "From: \"$comment->comment_author\" <$wp_email>"; + if ( '' != $comment->comment_author_email ) + $reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>"; + } + + $message_headers = "$from\n" + . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; + + if ( isset($reply_to) ) + $message_headers .= $reply_to . "\n"; + + $notify_message = apply_filters('comment_notification_text', $notify_message, $comment_id); + $subject = apply_filters('comment_notification_subject', $subject, $comment_id); + $message_headers = apply_filters('comment_notification_headers', $message_headers, $comment_id); + + @wp_mail( $author->user_email, $subject, $notify_message, $message_headers ); + + return true; +} +endif; + +if ( !function_exists('wp_notify_moderator') ) : +/** + * Notifies the moderator of the blog about a new comment that is awaiting approval. + * + * @since 1.0 + * @uses $wpdb + * + * @param int $comment_id Comment ID + * @return bool Always returns true + */ +function wp_notify_moderator($comment_id) { + global $wpdb; + + if ( 0 == get_option( 'moderation_notify' ) ) + return true; + + $comment = get_comment($comment_id); + $post = get_post($comment->comment_post_ID); + $user = get_userdata( $post->post_author ); + // Send to the administation and to the post author if the author can modify the comment. + $email_to = array( get_option('admin_email') ); + if ( user_can($user->ID, 'edit_comment', $comment_id) && !empty($user->user_email) && ( get_option('admin_email') != $user->user_email) ) + $email_to[] = $user->user_email; + + $comment_author_domain = @gethostbyaddr($comment->comment_author_IP); + $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'"); + + // The blogname option is escaped with esc_html on the way into the database in sanitize_option + // we want to reverse this for the plain text arena of emails. + $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + + switch ($comment->comment_type) + { + case 'trackback': + $notify_message = sprintf( __('A new trackback on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; + $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; + $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + break; + case 'pingback': + $notify_message = sprintf( __('A new pingback on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; + $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; + $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + break; + default: //Comments + $notify_message = sprintf( __('A new comment on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; + $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; + $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; + $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= sprintf( __('Whois : http://whois.arin.net/rest/ip/%s'), $comment->comment_author_IP ) . "\r\n"; + $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + break; + } + + $notify_message .= sprintf( __('Approve it: %s'), admin_url("comment.php?action=approve&c=$comment_id") ) . "\r\n"; + if ( EMPTY_TRASH_DAYS ) + $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; + else + $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; + $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; + + $notify_message .= sprintf( _n('Currently %s comment is waiting for approval. Please visit the moderation panel:', + 'Currently %s comments are waiting for approval. Please visit the moderation panel:', $comments_waiting), number_format_i18n($comments_waiting) ) . "\r\n"; + $notify_message .= admin_url("edit-comments.php?comment_status=moderated") . "\r\n"; + + $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), $blogname, $post->post_title ); + $message_headers = ''; + + $notify_message = apply_filters('comment_moderation_text', $notify_message, $comment_id); + $subject = apply_filters('comment_moderation_subject', $subject, $comment_id); + $message_headers = apply_filters('comment_moderation_headers', $message_headers); + + foreach ( $email_to as $email ) + @wp_mail($email, $subject, $notify_message, $message_headers); + + return true; +} +endif; + +if ( !function_exists('wp_password_change_notification') ) : +/** + * Notify the blog admin of a user changing password, normally via email. + * + * @since 2.7 + * + * @param object $user User Object + */ +function wp_password_change_notification(&$user) { + // send a copy of password change notification to the admin + // but check to see if it's the admin whose password we're changing, and skip this + if ( $user->user_email != get_option('admin_email') ) { + $message = sprintf(__('Password Lost and Changed for user: %s'), $user->user_login) . "\r\n"; + // The blogname option is escaped with esc_html on the way into the database in sanitize_option + // we want to reverse this for the plain text arena of emails. + $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + wp_mail(get_option('admin_email'), sprintf(__('[%s] Password Lost/Changed'), $blogname), $message); + } +} +endif; + +if ( !function_exists('wp_new_user_notification') ) : +/** + * Notify the blog admin of a new user, normally via email. + * + * @since 2.0 + * + * @param int $user_id User ID + * @param string $plaintext_pass Optional. The user's plaintext password + */ +function wp_new_user_notification($user_id, $plaintext_pass = '') { + $user = new WP_User($user_id); + + $user_login = stripslashes($user->user_login); + $user_email = stripslashes($user->user_email); + + // The blogname option is escaped with esc_html on the way into the database in sanitize_option + // we want to reverse this for the plain text arena of emails. + $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + + $message = sprintf(__('New user registration on your site %s:'), $blogname) . "\r\n\r\n"; + $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; + $message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n"; + + @wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), $blogname), $message); + + if ( empty($plaintext_pass) ) + return; + + $message = sprintf(__('Username: %s'), $user_login) . "\r\n"; + $message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n"; + $message .= wp_login_url() . "\r\n"; + + wp_mail($user_email, sprintf(__('[%s] Your username and password'), $blogname), $message); + +} +endif; + +if ( !function_exists('wp_nonce_tick') ) : +/** + * Get the time-dependent variable for nonce creation. + * + * A nonce has a lifespan of two ticks. Nonces in their second tick may be + * updated, e.g. by autosave. + * + * @since 2.5 + * + * @return int + */ +function wp_nonce_tick() { + $nonce_life = apply_filters('nonce_life', 86400); + + return ceil(time() / ( $nonce_life / 2 )); +} +endif; + +if ( !function_exists('wp_verify_nonce') ) : +/** + * Verify that correct nonce was used with time limit. + * + * The user is given an amount of time to use the token, so therefore, since the + * UID and $action remain the same, the independent variable is the time. + * + * @since 2.0.3 + * + * @param string $nonce Nonce that was used in the form to verify + * @param string|int $action Should give context to what is taking place and be the same when nonce was created. + * @return bool Whether the nonce check passed or failed. + */ +function wp_verify_nonce($nonce, $action = -1) { + $user = wp_get_current_user(); + $uid = (int) $user->id; + + $i = wp_nonce_tick(); + + // Nonce generated 0-12 hours ago + if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) == $nonce ) + return 1; + // Nonce generated 12-24 hours ago + if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) == $nonce ) + return 2; + // Invalid nonce + return false; +} +endif; + +if ( !function_exists('wp_create_nonce') ) : +/** + * Creates a random, one time use token. + * + * @since 2.0.3 + * + * @param string|int $action Scalar value to add context to the nonce. + * @return string The one use form token + */ +function wp_create_nonce($action = -1) { + $user = wp_get_current_user(); + $uid = (int) $user->id; + + $i = wp_nonce_tick(); + + return substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10); +} +endif; + +if ( !function_exists('wp_salt') ) : +/** + * Get salt to add to hashes to help prevent attacks. + * + * The secret key is located in two places: the database in case the secret key + * isn't defined in the second place, which is in the wp-config.php file. If you + * are going to set the secret key, then you must do so in the wp-config.php + * file. + * + * The secret key in the database is randomly generated and will be appended to + * the secret key that is in wp-config.php file in some instances. It is + * important to have the secret key defined or changed in wp-config.php. + * + * If you have installed WordPress 2.5 or later, then you will have the + * SECRET_KEY defined in the wp-config.php already. You will want to change the + * value in it because hackers will know what it is. If you have upgraded to + * WordPress 2.5 or later version from a version before WordPress 2.5, then you + * should add the constant to your wp-config.php file. + * + * Below is an example of how the SECRET_KEY constant is defined with a value. + * You must not copy the below example and paste into your wp-config.php. If you + * need an example, then you can have a + * {@link https://api.wordpress.org/secret-key/1.1/ secret key created} for you. + * + * + * define('SECRET_KEY', 'mAry1HadA15|\/|b17w55w1t3asSn09w'); + * + * + * Salting passwords helps against tools which has stored hashed values of + * common dictionary strings. The added values makes it harder to crack if given + * salt string is not weak. + * + * @since 2.5 + * @link https://api.wordpress.org/secret-key/1.1/ Create a Secret Key for wp-config.php + * + * @param string $scheme Authentication scheme + * @return string Salt value + */ +function wp_salt($scheme = 'auth') { + global $wp_default_secret_key; + $secret_key = ''; + if ( defined('SECRET_KEY') && ('' != SECRET_KEY) && ( $wp_default_secret_key != SECRET_KEY) ) + $secret_key = SECRET_KEY; + + if ( 'auth' == $scheme ) { + if ( defined('AUTH_KEY') && ('' != AUTH_KEY) && ( $wp_default_secret_key != AUTH_KEY) ) + $secret_key = AUTH_KEY; + + if ( defined('AUTH_SALT') && ('' != AUTH_SALT) && ( $wp_default_secret_key != AUTH_SALT) ) { + $salt = AUTH_SALT; + } elseif ( defined('SECRET_SALT') && ('' != SECRET_SALT) && ( $wp_default_secret_key != SECRET_SALT) ) { + $salt = SECRET_SALT; + } else { + $salt = get_site_option('auth_salt'); + if ( empty($salt) ) { + $salt = wp_generate_password( 64, true, true ); + update_site_option('auth_salt', $salt); + } + } + } elseif ( 'secure_auth' == $scheme ) { + if ( defined('SECURE_AUTH_KEY') && ('' != SECURE_AUTH_KEY) && ( $wp_default_secret_key != SECURE_AUTH_KEY) ) + $secret_key = SECURE_AUTH_KEY; + + if ( defined('SECURE_AUTH_SALT') && ('' != SECURE_AUTH_SALT) && ( $wp_default_secret_key != SECURE_AUTH_SALT) ) { + $salt = SECURE_AUTH_SALT; + } else { + $salt = get_site_option('secure_auth_salt'); + if ( empty($salt) ) { + $salt = wp_generate_password( 64, true, true ); + update_site_option('secure_auth_salt', $salt); + } + } + } elseif ( 'logged_in' == $scheme ) { + if ( defined('LOGGED_IN_KEY') && ('' != LOGGED_IN_KEY) && ( $wp_default_secret_key != LOGGED_IN_KEY) ) + $secret_key = LOGGED_IN_KEY; + + if ( defined('LOGGED_IN_SALT') && ('' != LOGGED_IN_SALT) && ( $wp_default_secret_key != LOGGED_IN_SALT) ) { + $salt = LOGGED_IN_SALT; + } else { + $salt = get_site_option('logged_in_salt'); + if ( empty($salt) ) { + $salt = wp_generate_password( 64, true, true ); + update_site_option('logged_in_salt', $salt); + } + } + } elseif ( 'nonce' == $scheme ) { + if ( defined('NONCE_KEY') && ('' != NONCE_KEY) && ( $wp_default_secret_key != NONCE_KEY) ) + $secret_key = NONCE_KEY; + + if ( defined('NONCE_SALT') && ('' != NONCE_SALT) && ( $wp_default_secret_key != NONCE_SALT) ) { + $salt = NONCE_SALT; + } else { + $salt = get_site_option('nonce_salt'); + if ( empty($salt) ) { + $salt = wp_generate_password( 64, true, true ); + update_site_option('nonce_salt', $salt); + } + } + } else { + // ensure each auth scheme has its own unique salt + $salt = hash_hmac('md5', $scheme, $secret_key); + } + + return apply_filters('salt', $secret_key . $salt, $scheme); +} +endif; + +if ( !function_exists('wp_hash') ) : +/** + * Get hash of given string. + * + * @since 2.0.3 + * @uses wp_salt() Get WordPress salt + * + * @param string $data Plain text to hash + * @return string Hash of $data + */ +function wp_hash($data, $scheme = 'auth') { + $salt = wp_salt($scheme); + + return hash_hmac('md5', $data, $salt); +} +endif; + +if ( !function_exists('wp_hash_password') ) : +/** + * Create a hash (encrypt) of a plain text password. + * + * For integration with other applications, this function can be overwritten to + * instead use the other package password checking algorithm. + * + * @since 2.5 + * @global object $wp_hasher PHPass object + * @uses PasswordHash::HashPassword + * + * @param string $password Plain text user password to hash + * @return string The hash string of the password + */ +function wp_hash_password($password) { + global $wp_hasher; + + if ( empty($wp_hasher) ) { + require_once( ABSPATH . 'wp-includes/class-phpass.php'); + // By default, use the portable hash from phpass + $wp_hasher = new PasswordHash(8, TRUE); + } + + return $wp_hasher->HashPassword($password); +} +endif; + +if ( !function_exists('wp_check_password') ) : +/** + * Checks the plaintext password against the encrypted Password. + * + * Maintains compatibility between old version and the new cookie authentication + * protocol using PHPass library. The $hash parameter is the encrypted password + * and the function compares the plain text password when encypted similarly + * against the already encrypted password to see if they match. + * + * For integration with other applications, this function can be overwritten to + * instead use the other package password checking algorithm. + * + * @since 2.5 + * @global object $wp_hasher PHPass object used for checking the password + * against the $hash + $password + * @uses PasswordHash::CheckPassword + * + * @param string $password Plaintext user's password + * @param string $hash Hash of the user's password to check against. + * @return bool False, if the $password does not match the hashed password + */ +function wp_check_password($password, $hash, $user_id = '') { + global $wp_hasher; + + // If the hash is still md5... + if ( strlen($hash) <= 32 ) { + $check = ( $hash == md5($password) ); + if ( $check && $user_id ) { + // Rehash using new hash. + wp_set_password($password, $user_id); + $hash = wp_hash_password($password); + } + + return apply_filters('check_password', $check, $password, $hash, $user_id); + } + + // If the stored hash is longer than an MD5, presume the + // new style phpass portable hash. + if ( empty($wp_hasher) ) { + require_once( ABSPATH . 'wp-includes/class-phpass.php'); + // By default, use the portable hash from phpass + $wp_hasher = new PasswordHash(8, TRUE); + } + + $check = $wp_hasher->CheckPassword($password, $hash); + + return apply_filters('check_password', $check, $password, $hash, $user_id); +} +endif; + +if ( !function_exists('wp_generate_password') ) : +/** + * Generates a random password drawn from the defined set of characters. + * + * @since 2.5 + * + * @param int $length The length of password to generate + * @param bool $special_chars Whether to include standard special characters. Default true. + * @param bool $extra_special_chars Whether to include other special characters. Used when + * generating secret keys and salts. Default false. + * @return string The random password + **/ +function wp_generate_password( $length = 12, $special_chars = true, $extra_special_chars = false ) { + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + if ( $special_chars ) + $chars .= '!@#$%^&*()'; + if ( $extra_special_chars ) + $chars .= '-_ []{}<>~`+=,.;:/?|'; + + $password = ''; + for ( $i = 0; $i < $length; $i++ ) { + $password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1); + } + + // random_password filter was previously in random_password function which was deprecated + return apply_filters('random_password', $password); +} +endif; + +if ( !function_exists('wp_rand') ) : + /** + * Generates a random number + * + * @since 2.6.2 + * + * @param int $min Lower limit for the generated number (optional, default is 0) + * @param int $max Upper limit for the generated number (optional, default is 4294967295) + * @return int A random number between min and max + */ +function wp_rand( $min = 0, $max = 0 ) { + global $rnd_value; + + // Reset $rnd_value after 14 uses + // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value + if ( strlen($rnd_value) < 8 ) { + if ( defined( 'WP_SETUP_CONFIG' ) ) + static $seed = ''; + else + $seed = get_transient('random_seed'); + $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed ); + $rnd_value .= sha1($rnd_value); + $rnd_value .= sha1($rnd_value . $seed); + $seed = md5($seed . $rnd_value); + if ( ! defined( 'WP_SETUP_CONFIG' ) ) + set_transient('random_seed', $seed); + } + + // Take the first 8 digits for our value + $value = substr($rnd_value, 0, 8); + + // Strip the first eight, leaving the remainder for the next call to wp_rand(). + $rnd_value = substr($rnd_value, 8); + + $value = abs(hexdec($value)); + + // Reduce the value to be within the min - max range + // 4294967295 = 0xffffffff = max random number + if ( $max != 0 ) + $value = $min + (($max - $min + 1) * ($value / (4294967295 + 1))); + + return abs(intval($value)); +} +endif; + +if ( !function_exists('wp_set_password') ) : +/** + * Updates the user's password with a new encrypted one. + * + * For integration with other applications, this function can be overwritten to + * instead use the other package password checking algorithm. + * + * @since 2.5 + * @uses $wpdb WordPress database object for queries + * @uses wp_hash_password() Used to encrypt the user's password before passing to the database + * + * @param string $password The plaintext new user password + * @param int $user_id User ID + */ +function wp_set_password( $password, $user_id ) { + global $wpdb; + + $hash = wp_hash_password($password); + $wpdb->update($wpdb->users, array('user_pass' => $hash, 'user_activation_key' => ''), array('ID' => $user_id) ); + + wp_cache_delete($user_id, 'users'); +} +endif; + +if ( !function_exists( 'get_avatar' ) ) : +/** + * Retrieve the avatar for a user who provided a user ID or email address. + * + * @since 2.5 + * @param int|string|object $id_or_email A user ID, email address, or comment object + * @param int $size Size of the avatar image + * @param string $default URL to a default image to use if no avatar is available + * @param string $alt Alternate text to use in image tag. Defaults to blank + * @return string tag for the user's avatar +*/ +function get_avatar( $id_or_email, $size = '96', $default = '', $alt = false ) { + if ( ! get_option('show_avatars') ) + return false; + + if ( false === $alt) + $safe_alt = ''; + else + $safe_alt = esc_attr( $alt ); + + if ( !is_numeric($size) ) + $size = '96'; + + $email = ''; + if ( is_numeric($id_or_email) ) { + $id = (int) $id_or_email; + $user = get_userdata($id); + if ( $user ) + $email = $user->user_email; + } elseif ( is_object($id_or_email) ) { + // No avatar for pingbacks or trackbacks + $allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment' ) ); + if ( ! empty( $id_or_email->comment_type ) && ! in_array( $id_or_email->comment_type, (array) $allowed_comment_types ) ) + return false; + + if ( !empty($id_or_email->user_id) ) { + $id = (int) $id_or_email->user_id; + $user = get_userdata($id); + if ( $user) + $email = $user->user_email; + } elseif ( !empty($id_or_email->comment_author_email) ) { + $email = $id_or_email->comment_author_email; + } + } else { + $email = $id_or_email; + } + + if ( empty($default) ) { + $avatar_default = get_option('avatar_default'); + if ( empty($avatar_default) ) + $default = 'mystery'; + else + $default = $avatar_default; + } + + if ( !empty($email) ) + $email_hash = md5( strtolower( $email ) ); + + if ( is_ssl() ) { + $host = 'https://secure.gravatar.com'; + } else { + if ( !empty($email) ) + $host = sprintf( "http://%d.gravatar.com", ( hexdec( $email_hash[0] ) % 2 ) ); + else + $host = 'http://0.gravatar.com'; + } + + if ( 'mystery' == $default ) + $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com') + elseif ( 'blank' == $default ) + $default = includes_url('images/blank.gif'); + elseif ( !empty($email) && 'gravatar_default' == $default ) + $default = ''; + elseif ( 'gravatar_default' == $default ) + $default = "$host/avatar/s={$size}"; + elseif ( empty($email) ) + $default = "$host/avatar/?d=$default&s={$size}"; + elseif ( strpos($default, 'http://') === 0 ) + $default = add_query_arg( 's', $size, $default ); + + if ( !empty($email) ) { + $out = "$host/avatar/"; + $out .= $email_hash; + $out .= '?s='.$size; + $out .= '&d=' . urlencode( $default ); + + $rating = get_option('avatar_rating'); + if ( !empty( $rating ) ) + $out .= "&r={$rating}"; + + $avatar = "{$safe_alt}"; + } else { + $avatar = "{$safe_alt}"; + } + + return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default, $alt); +} +endif; + +if ( !function_exists( 'wp_text_diff' ) ) : +/** + * Displays a human readable HTML representation of the difference between two strings. + * + * The Diff is available for getting the changes between versions. The output is + * HTML, so the primary use is for displaying the changes. If the two strings + * are equivalent, then an empty string will be returned. + * + * The arguments supported and can be changed are listed below. + * + * 'title' : Default is an empty string. Titles the diff in a manner compatible + * with the output. + * 'title_left' : Default is an empty string. Change the HTML to the left of the + * title. + * 'title_right' : Default is an empty string. Change the HTML to the right of + * the title. + * + * @since 2.6 + * @see wp_parse_args() Used to change defaults to user defined settings. + * @uses Text_Diff + * @uses WP_Text_Diff_Renderer_Table + * + * @param string $left_string "old" (left) version of string + * @param string $right_string "new" (right) version of string + * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. + * @return string Empty string if strings are equivalent or HTML with differences. + */ +function wp_text_diff( $left_string, $right_string, $args = null ) { + $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' ); + $args = wp_parse_args( $args, $defaults ); + + if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) ) + require( ABSPATH . WPINC . '/wp-diff.php' ); + + $left_string = normalize_whitespace($left_string); + $right_string = normalize_whitespace($right_string); + + $left_lines = split("\n", $left_string); + $right_lines = split("\n", $right_string); + + $text_diff = new Text_Diff($left_lines, $right_lines); + $renderer = new WP_Text_Diff_Renderer_Table(); + $diff = $renderer->render($text_diff); + + if ( !$diff ) + return ''; + + $r = "\n"; + $r .= ""; + + if ( $args['title'] || $args['title_left'] || $args['title_right'] ) + $r .= ""; + if ( $args['title'] ) + $r .= "\n"; + if ( $args['title_left'] || $args['title_right'] ) { + $r .= "\n"; + $r .= "\t\n"; + $r .= "\t\n"; + $r .= "\n"; + } + if ( $args['title'] || $args['title_left'] || $args['title_right'] ) + $r .= "\n"; + + $r .= "\n$diff\n\n"; + $r .= "
    $args[title]
    $args[title_left]$args[title_right]
    "; + + return $r; +} +endif; diff --git a/src/wp-includes/plugin.php b/src/wp-includes/plugin.php new file mode 100644 index 00000000..0c10e242 --- /dev/null +++ b/src/wp-includes/plugin.php @@ -0,0 +1,775 @@ + + * function example_hook($example) { echo $example; } + * add_filter('example_filter', 'example_hook'); + * + * + * In WordPress 1.5.1+, hooked functions can take extra arguments that are set + * when the matching do_action() or apply_filters() call is run. The + * $accepted_args allow for calling functions only when the number of args + * match. Hooked functions can take extra arguments that are set when the + * matching do_action() or apply_filters() call is run. For example, the action + * comment_id_not_found will pass any functions that hook onto it the ID of the + * requested comment. + * + * Note: the function will return true no matter if the + * function was hooked fails or not. There are no checks for whether the + * function exists beforehand and no checks to whether the $function_to_add + * is even a string. It is up to you to take care and this is done for + * optimization purposes, so everything is as quick as possible. + * + * @package WordPress + * @subpackage Plugin + * @since 0.71 + * @global array $wp_filter Stores all of the filters added in the form of + * wp_filter['tag']['array of priorities']['array of functions serialized']['array of ['array (functions, accepted_args)']'] + * @global array $merged_filters Tracks the tags that need to be merged for later. If the hook is added, it doesn't need to run through that process. + * + * @param string $tag The name of the filter to hook the $function_to_add to. + * @param callback $function_to_add The name of the function to be called when the filter is applied. + * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action. + * @param int $accepted_args optional. The number of arguments the function accept (default 1). + * @return boolean true + */ +function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + global $wp_filter, $merged_filters; + + $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); + $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); + unset( $merged_filters[ $tag ] ); + return true; +} + +/** + * Check if any filter has been registered for a hook. + * + * @package WordPress + * @subpackage Plugin + * @since 2.5 + * @global array $wp_filter Stores all of the filters + * + * @param string $tag The name of the filter hook. + * @param callback $function_to_check optional. If specified, return the priority of that function on this hook or false if not attached. + * @return int|boolean Optionally returns the priority on that hook for the specified function. + */ +function has_filter($tag, $function_to_check = false) { + global $wp_filter; + + $has = !empty($wp_filter[$tag]); + if ( false === $function_to_check || false == $has ) + return $has; + + if ( !$idx = _wp_filter_build_unique_id($tag, $function_to_check, false) ) + return false; + + foreach ( (array) array_keys($wp_filter[$tag]) as $priority ) { + if ( isset($wp_filter[$tag][$priority][$idx]) ) + return $priority; + } + + return false; +} + +/** + * Call the functions added to a filter hook. + * + * The callback functions attached to filter hook $tag are invoked by calling + * this function. This function can be used to create a new filter hook by + * simply calling this function with the name of the new hook specified using + * the $tag parameter. + * + * The function allows for additional arguments to be added and passed to hooks. + * + * function example_hook($string, $arg1, $arg2) + * { + * //Do stuff + * return $string; + * } + * $value = apply_filters('example_filter', 'filter me', 'arg1', 'arg2'); + * + * + * @package WordPress + * @subpackage Plugin + * @since 0.71 + * @global array $wp_filter Stores all of the filters + * @global array $merged_filters Merges the filter hooks using this function. + * @global array $wp_current_filter stores the list of current filters with the current one last + * + * @param string $tag The name of the filter hook. + * @param mixed $value The value on which the filters hooked to $tag are applied on. + * @param mixed $var,... Additional variables passed to the functions hooked to $tag. + * @return mixed The filtered value after all hooked functions are applied to it. + */ +function apply_filters($tag, $value) { + global $wp_filter, $merged_filters, $wp_current_filter; + + $args = array(); + $wp_current_filter[] = $tag; + + // Do 'all' actions first + if ( isset($wp_filter['all']) ) { + $args = func_get_args(); + _wp_call_all_hook($args); + } + + if ( !isset($wp_filter[$tag]) ) { + array_pop($wp_current_filter); + return $value; + } + + // Sort + if ( !isset( $merged_filters[ $tag ] ) ) { + ksort($wp_filter[$tag]); + $merged_filters[ $tag ] = true; + } + + reset( $wp_filter[ $tag ] ); + + if ( empty($args) ) + $args = func_get_args(); + + do { + foreach( (array) current($wp_filter[$tag]) as $the_ ) + if ( !is_null($the_['function']) ){ + $args[1] = $value; + $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args'])); + } + + } while ( next($wp_filter[$tag]) !== false ); + + array_pop( $wp_current_filter ); + + return $value; +} + +/** + * Execute functions hooked on a specific filter hook, specifying arguments in an array. + * + * @see apply_filters() This function is identical, but the arguments passed to the + * functions hooked to $tag are supplied using an array. + * + * @package WordPress + * @subpackage Plugin + * @since 3.0.0 + * @global array $wp_filter Stores all of the filters + * @global array $merged_filters Merges the filter hooks using this function. + * @global array $wp_current_filter stores the list of current filters with the current one last + * + * @param string $tag The name of the filter hook. + * @param array $args The arguments supplied to the functions hooked to $tag + * @return mixed The filtered value after all hooked functions are applied to it. + */ +function apply_filters_ref_array($tag, $args) { + global $wp_filter, $merged_filters, $wp_current_filter; + + $wp_current_filter[] = $tag; + + // Do 'all' actions first + if ( isset($wp_filter['all']) ) { + $all_args = func_get_args(); + _wp_call_all_hook($all_args); + } + + if ( !isset($wp_filter[$tag]) ) { + array_pop($wp_current_filter); + return $args[0]; + } + + // Sort + if ( !isset( $merged_filters[ $tag ] ) ) { + ksort($wp_filter[$tag]); + $merged_filters[ $tag ] = true; + } + + reset( $wp_filter[ $tag ] ); + + do { + foreach( (array) current($wp_filter[$tag]) as $the_ ) + if ( !is_null($the_['function']) ) + $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); + + } while ( next($wp_filter[$tag]) !== false ); + + array_pop( $wp_current_filter ); + + return $args[0]; +} + +/** + * Removes a function from a specified filter hook. + * + * This function removes a function attached to a specified filter hook. This + * method can be used to remove default functions attached to a specific filter + * hook and possibly replace them with a substitute. + * + * To remove a hook, the $function_to_remove and $priority arguments must match + * when the hook was added. This goes for both filters and actions. No warning + * will be given on removal failure. + * + * @package WordPress + * @subpackage Plugin + * @since 1.2 + * + * @param string $tag The filter hook to which the function to be removed is hooked. + * @param callback $function_to_remove The name of the function which should be removed. + * @param int $priority optional. The priority of the function (default: 10). + * @param int $accepted_args optional. The number of arguments the function accpets (default: 1). + * @return boolean Whether the function existed before it was removed. + */ +function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { + $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority); + + $r = isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); + + if ( true === $r) { + unset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); + if ( empty($GLOBALS['wp_filter'][$tag][$priority]) ) + unset($GLOBALS['wp_filter'][$tag][$priority]); + unset($GLOBALS['merged_filters'][$tag]); + } + + return $r; +} + +/** + * Remove all of the hooks from a filter. + * + * @since 2.7 + * + * @param string $tag The filter to remove hooks from. + * @param int $priority The priority number to remove. + * @return bool True when finished. + */ +function remove_all_filters($tag, $priority = false) { + global $wp_filter, $merged_filters; + + if( isset($wp_filter[$tag]) ) { + if( false !== $priority && isset($wp_filter[$tag][$priority]) ) + unset($wp_filter[$tag][$priority]); + else + unset($wp_filter[$tag]); + } + + if( isset($merged_filters[$tag]) ) + unset($merged_filters[$tag]); + + return true; +} + +/** + * Retrieve the name of the current filter or action. + * + * @package WordPress + * @subpackage Plugin + * @since 2.5 + * + * @return string Hook name of the current filter or action. + */ +function current_filter() { + global $wp_current_filter; + return end( $wp_current_filter ); +} + + +/** + * Hooks a function on to a specific action. + * + * Actions are the hooks that the WordPress core launches at specific points + * during execution, or when specific events occur. Plugins can specify that + * one or more of its PHP functions are executed at these points, using the + * Action API. + * + * @uses add_filter() Adds an action. Parameter list and functionality are the same. + * + * @package WordPress + * @subpackage Plugin + * @since 1.2 + * + * @param string $tag The name of the action to which the $function_to_add is hooked. + * @param callback $function_to_add The name of the function you wish to be called. + * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action. + * @param int $accepted_args optional. The number of arguments the function accept (default 1). + */ +function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + return add_filter($tag, $function_to_add, $priority, $accepted_args); +} + + +/** + * Execute functions hooked on a specific action hook. + * + * This function invokes all functions attached to action hook $tag. It is + * possible to create new action hooks by simply calling this function, + * specifying the name of the new hook using the $tag parameter. + * + * You can pass extra arguments to the hooks, much like you can with + * apply_filters(). + * + * @see apply_filters() This function works similar with the exception that + * nothing is returned and only the functions or methods are called. + * + * @package WordPress + * @subpackage Plugin + * @since 1.2 + * @global array $wp_filter Stores all of the filters + * @global array $wp_actions Increments the amount of times action was triggered. + * + * @param string $tag The name of the action to be executed. + * @param mixed $arg,... Optional additional arguments which are passed on to the functions hooked to the action. + * @return null Will return null if $tag does not exist in $wp_filter array + */ +function do_action($tag, $arg = '') { + global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; + + if ( ! isset($wp_actions) ) + $wp_actions = array(); + + if ( ! isset($wp_actions[$tag]) ) + $wp_actions[$tag] = 1; + else + ++$wp_actions[$tag]; + + $wp_current_filter[] = $tag; + + // Do 'all' actions first + if ( isset($wp_filter['all']) ) { + $all_args = func_get_args(); + _wp_call_all_hook($all_args); + } + + if ( !isset($wp_filter[$tag]) ) { + array_pop($wp_current_filter); + return; + } + + $args = array(); + if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this) + $args[] =& $arg[0]; + else + $args[] = $arg; + for ( $a = 2; $a < func_num_args(); $a++ ) + $args[] = func_get_arg($a); + + // Sort + if ( !isset( $merged_filters[ $tag ] ) ) { + ksort($wp_filter[$tag]); + $merged_filters[ $tag ] = true; + } + + reset( $wp_filter[ $tag ] ); + + do { + foreach ( (array) current($wp_filter[$tag]) as $the_ ) + if ( !is_null($the_['function']) ) + call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); + + } while ( next($wp_filter[$tag]) !== false ); + + array_pop($wp_current_filter); +} + +/** + * Retrieve the number times an action is fired. + * + * @package WordPress + * @subpackage Plugin + * @since 2.1 + * @global array $wp_actions Increments the amount of times action was triggered. + * + * @param string $tag The name of the action hook. + * @return int The number of times action hook $tag is fired + */ +function did_action($tag) { + global $wp_actions; + + if ( ! isset( $wp_actions ) || ! isset( $wp_actions[$tag] ) ) + return 0; + + return $wp_actions[$tag]; +} + +/** + * Execute functions hooked on a specific action hook, specifying arguments in an array. + * + * @see do_action() This function is identical, but the arguments passed to the + * functions hooked to $tag are supplied using an array. + * + * @package WordPress + * @subpackage Plugin + * @since 2.1 + * @global array $wp_filter Stores all of the filters + * @global array $wp_actions Increments the amount of times action was triggered. + * + * @param string $tag The name of the action to be executed. + * @param array $args The arguments supplied to the functions hooked to $tag + * @return null Will return null if $tag does not exist in $wp_filter array + */ +function do_action_ref_array($tag, $args) { + global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter; + + if ( ! isset($wp_actions) ) + $wp_actions = array(); + + if ( ! isset($wp_actions[$tag]) ) + $wp_actions[$tag] = 1; + else + ++$wp_actions[$tag]; + + $wp_current_filter[] = $tag; + + // Do 'all' actions first + if ( isset($wp_filter['all']) ) { + $all_args = func_get_args(); + _wp_call_all_hook($all_args); + } + + if ( !isset($wp_filter[$tag]) ) { + array_pop($wp_current_filter); + return; + } + + // Sort + if ( !isset( $merged_filters[ $tag ] ) ) { + ksort($wp_filter[$tag]); + $merged_filters[ $tag ] = true; + } + + reset( $wp_filter[ $tag ] ); + + do { + foreach( (array) current($wp_filter[$tag]) as $the_ ) + if ( !is_null($the_['function']) ) + call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); + + } while ( next($wp_filter[$tag]) !== false ); + + array_pop($wp_current_filter); +} + +/** + * Check if any action has been registered for a hook. + * + * @package WordPress + * @subpackage Plugin + * @since 2.5 + * @see has_filter() has_action() is an alias of has_filter(). + * + * @param string $tag The name of the action hook. + * @param callback $function_to_check optional. If specified, return the priority of that function on this hook or false if not attached. + * @return int|boolean Optionally returns the priority on that hook for the specified function. + */ +function has_action($tag, $function_to_check = false) { + return has_filter($tag, $function_to_check); +} + +/** + * Removes a function from a specified action hook. + * + * This function removes a function attached to a specified action hook. This + * method can be used to remove default functions attached to a specific filter + * hook and possibly replace them with a substitute. + * + * @package WordPress + * @subpackage Plugin + * @since 1.2 + * + * @param string $tag The action hook to which the function to be removed is hooked. + * @param callback $function_to_remove The name of the function which should be removed. + * @param int $priority optional The priority of the function (default: 10). + * @param int $accepted_args optional. The number of arguments the function accpets (default: 1). + * @return boolean Whether the function is removed. + */ +function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { + return remove_filter($tag, $function_to_remove, $priority, $accepted_args); +} + +/** + * Remove all of the hooks from an action. + * + * @since 2.7 + * + * @param string $tag The action to remove hooks from. + * @param int $priority The priority number to remove them from. + * @return bool True when finished. + */ +function remove_all_actions($tag, $priority = false) { + return remove_all_filters($tag, $priority); +} + +// +// Functions for handling plugins. +// + +/** + * Gets the basename of a plugin. + * + * This method extracts the name of a plugin from its filename. + * + * @package WordPress + * @subpackage Plugin + * @since 1.5 + * + * @access private + * + * @param string $file The filename of plugin. + * @return string The name of a plugin. + * @uses WP_PLUGIN_DIR + */ +function plugin_basename($file) { + $file = str_replace('\\','/',$file); // sanitize for Win32 installs + $file = preg_replace('|/+|','/', $file); // remove any duplicate slash + $plugin_dir = str_replace('\\','/',WP_PLUGIN_DIR); // sanitize for Win32 installs + $plugin_dir = preg_replace('|/+|','/', $plugin_dir); // remove any duplicate slash + $mu_plugin_dir = str_replace('\\','/',WPMU_PLUGIN_DIR); // sanitize for Win32 installs + $mu_plugin_dir = preg_replace('|/+|','/', $mu_plugin_dir); // remove any duplicate slash + $file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . preg_quote($mu_plugin_dir, '#') . '/#','',$file); // get relative path from plugins dir + $file = trim($file, '/'); + return $file; +} + +/** + * Gets the filesystem directory path (with trailing slash) for the plugin __FILE__ passed in + * @package WordPress + * @subpackage Plugin + * @since 2.8 + * + * @param string $file The filename of the plugin (__FILE__) + * @return string the filesystem path of the directory that contains the plugin + */ +function plugin_dir_path( $file ) { + return trailingslashit( dirname( $file ) ); +} + +/** + * Gets the URL directory path (with trailing slash) for the plugin __FILE__ passed in + * @package WordPress + * @subpackage Plugin + * @since 2.8 + * + * @param string $file The filename of the plugin (__FILE__) + * @return string the URL path of the directory that contains the plugin + */ +function plugin_dir_url( $file ) { + return trailingslashit( plugins_url( '', $file ) ); +} + +/** + * Set the activation hook for a plugin. + * + * When a plugin is activated, the action 'activate_PLUGINNAME' hook is + * activated. In the name of this hook, PLUGINNAME is replaced with the name of + * the plugin, including the optional subdirectory. For example, when the plugin + * is located in wp-content/plugin/sampleplugin/sample.php, then the name of + * this hook will become 'activate_sampleplugin/sample.php'. When the plugin + * consists of only one file and is (as by default) located at + * wp-content/plugin/sample.php the name of this hook will be + * 'activate_sample.php'. + * + * @package WordPress + * @subpackage Plugin + * @since 2.0 + * + * @param string $file The filename of the plugin including the path. + * @param callback $function the function hooked to the 'activate_PLUGIN' action. + */ +function register_activation_hook($file, $function) { + $file = plugin_basename($file); + add_action('activate_' . $file, $function); +} + +/** + * Set the deactivation hook for a plugin. + * + * When a plugin is deactivated, the action 'deactivate_PLUGINNAME' hook is + * deactivated. In the name of this hook, PLUGINNAME is replaced with the name + * of the plugin, including the optional subdirectory. For example, when the + * plugin is located in wp-content/plugin/sampleplugin/sample.php, then + * the name of this hook will become 'activate_sampleplugin/sample.php'. + * + * When the plugin consists of only one file and is (as by default) located at + * wp-content/plugin/sample.php the name of this hook will be + * 'activate_sample.php'. + * + * @package WordPress + * @subpackage Plugin + * @since 2.0 + * + * @param string $file The filename of the plugin including the path. + * @param callback $function the function hooked to the 'activate_PLUGIN' action. + */ +function register_deactivation_hook($file, $function) { + $file = plugin_basename($file); + add_action('deactivate_' . $file, $function); +} + +/** + * Set the uninstallation hook for a plugin. + * + * Registers the uninstall hook that will be called when the user clicks on the + * uninstall link that calls for the plugin to uninstall itself. The link won't + * be active unless the plugin hooks into the action. + * + * The plugin should not run arbitrary code outside of functions, when + * registering the uninstall hook. In order to run using the hook, the plugin + * will have to be included, which means that any code laying outside of a + * function will be run during the uninstall process. The plugin should not + * hinder the uninstall process. + * + * If the plugin can not be written without running code within the plugin, then + * the plugin should create a file named 'uninstall.php' in the base plugin + * folder. This file will be called, if it exists, during the uninstall process + * bypassing the uninstall hook. The plugin, when using the 'uninstall.php' + * should always check for the 'WP_UNINSTALL_PLUGIN' constant, before + * executing. + * + * @since 2.7 + * + * @param string $file + * @param callback $callback The callback to run when the hook is called. Must be a static method or function. + */ +function register_uninstall_hook( $file, $callback ) { + if ( is_array( $callback ) && is_object( $callback[0] ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Only a static class method or function can be used in an uninstall hook.' ), '3.1' ); + return; + } + + // The option should not be autoloaded, because it is not needed in most + // cases. Emphasis should be put on using the 'uninstall.php' way of + // uninstalling the plugin. + $uninstallable_plugins = (array) get_option('uninstall_plugins'); + $uninstallable_plugins[plugin_basename($file)] = $callback; + update_option('uninstall_plugins', $uninstallable_plugins); +} + +/** + * Calls the 'all' hook, which will process the functions hooked into it. + * + * The 'all' hook passes all of the arguments or parameters that were used for + * the hook, which this function was called for. + * + * This function is used internally for apply_filters(), do_action(), and + * do_action_ref_array() and is not meant to be used from outside those + * functions. This function does not check for the existence of the all hook, so + * it will fail unless the all hook exists prior to this function call. + * + * @package WordPress + * @subpackage Plugin + * @since 2.5 + * @access private + * + * @uses $wp_filter Used to process all of the functions in the 'all' hook + * + * @param array $args The collected parameters from the hook that was called. + * @param string $hook Optional. The hook name that was used to call the 'all' hook. + */ +function _wp_call_all_hook($args) { + global $wp_filter; + + reset( $wp_filter['all'] ); + do { + foreach( (array) current($wp_filter['all']) as $the_ ) + if ( !is_null($the_['function']) ) + call_user_func_array($the_['function'], $args); + + } while ( next($wp_filter['all']) !== false ); +} + +/** + * Build Unique ID for storage and retrieval. + * + * The old way to serialize the callback caused issues and this function is the + * solution. It works by checking for objects and creating an a new property in + * the class to keep track of the object and new objects of the same class that + * need to be added. + * + * It also allows for the removal of actions and filters for objects after they + * change class properties. It is possible to include the property $wp_filter_id + * in your class and set it to "null" or a number to bypass the workaround. + * However this will prevent you from adding new classes and any new classes + * will overwrite the previous hook by the same class. + * + * Functions and static method callbacks are just returned as strings and + * shouldn't have any speed penalty. + * + * @package WordPress + * @subpackage Plugin + * @access private + * @since 2.2.3 + * @link http://trac.wordpress.org/ticket/3875 + * + * @global array $wp_filter Storage for all of the filters and actions + * @param string $tag Used in counting how many hooks were applied + * @param callback $function Used for creating unique id + * @param int|bool $priority Used in counting how many hooks were applied. If === false and $function is an object reference, we return the unique id only if it already has one, false otherwise. + * @return string|bool Unique ID for usage as array key or false if $priority === false and $function is an object reference, and it does not already have a uniqe id. + */ +function _wp_filter_build_unique_id($tag, $function, $priority) { + global $wp_filter; + static $filter_id_count = 0; + + if ( is_string($function) ) + return $function; + + if ( is_object($function) ) { + // Closures are currently implemented as objects + $function = array( $function, '' ); + } else { + $function = (array) $function; + } + + if (is_object($function[0]) ) { + // Object Class Calling + if ( function_exists('spl_object_hash') ) { + return spl_object_hash($function[0]) . $function[1]; + } else { + $obj_idx = get_class($function[0]).$function[1]; + if ( !isset($function[0]->wp_filter_id) ) { + if ( false === $priority ) + return false; + $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; + $function[0]->wp_filter_id = $filter_id_count; + ++$filter_id_count; + } else { + $obj_idx .= $function[0]->wp_filter_id; + } + + return $obj_idx; + } + } else if ( is_string($function[0]) ) { + // Static Calling + return $function[0].$function[1]; + } +} + +?> diff --git a/src/wp-includes/pomo/entry.php b/src/wp-includes/pomo/entry.php new file mode 100644 index 00000000..07ddfd4d --- /dev/null +++ b/src/wp-includes/pomo/entry.php @@ -0,0 +1,69 @@ + $value) { + $this->$varname = $value; + } + if (isset($args['plural'])) $this->is_plural = true; + if (!is_array($this->translations)) $this->translations = array(); + if (!is_array($this->references)) $this->references = array(); + if (!is_array($this->flags)) $this->flags = array(); + } + + /** + * Generates a unique key for this entry + * + * @return string|bool the key or false if the entry is empty + */ + function key() { + if (is_null($this->singular)) return false; + // prepend context and EOT, like in MO files + return is_null($this->context)? $this->singular : $this->context.chr(4).$this->singular; + } +} +endif; \ No newline at end of file diff --git a/src/wp-includes/pomo/mo.php b/src/wp-includes/pomo/mo.php new file mode 100644 index 00000000..72e0e7bf --- /dev/null +++ b/src/wp-includes/pomo/mo.php @@ -0,0 +1,231 @@ +is_resource()) + return false; + return $this->import_from_reader($reader); + } + + function export_to_file($filename) { + $fh = fopen($filename, 'wb'); + if ( !$fh ) return false; + $entries = array_filter($this->entries, create_function('$e', 'return !empty($e->translations);')); + ksort($entries); + $magic = 0x950412de; + $revision = 0; + $total = count($entries) + 1; // all the headers are one entry + $originals_lenghts_addr = 28; + $translations_lenghts_addr = $originals_lenghts_addr + 8 * $total; + $size_of_hash = 0; + $hash_addr = $translations_lenghts_addr + 8 * $total; + $current_addr = $hash_addr; + fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr, + $translations_lenghts_addr, $size_of_hash, $hash_addr)); + fseek($fh, $originals_lenghts_addr); + + // headers' msgid is an empty string + fwrite($fh, pack('VV', 0, $current_addr)); + $current_addr++; + $originals_table = chr(0); + + foreach($entries as $entry) { + $originals_table .= $this->export_original($entry) . chr(0); + $length = strlen($this->export_original($entry)); + fwrite($fh, pack('VV', $length, $current_addr)); + $current_addr += $length + 1; // account for the NULL byte after + } + + $exported_headers = $this->export_headers(); + fwrite($fh, pack('VV', strlen($exported_headers), $current_addr)); + $current_addr += strlen($exported_headers) + 1; + $translations_table = $exported_headers . chr(0); + + foreach($entries as $entry) { + $translations_table .= $this->export_translations($entry) . chr(0); + $length = strlen($this->export_translations($entry)); + fwrite($fh, pack('VV', $length, $current_addr)); + $current_addr += $length + 1; + } + + fwrite($fh, $originals_table); + fwrite($fh, $translations_table); + fclose($fh); + } + + function export_original($entry) { + //TODO: warnings for control characters + $exported = $entry->singular; + if ($entry->is_plural) $exported .= chr(0).$entry->plural; + if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported; + return $exported; + } + + function export_translations($entry) { + //TODO: warnings for control characters + return implode(chr(0), $entry->translations); + } + + function export_headers() { + $exported = ''; + foreach($this->headers as $header => $value) { + $exported.= "$header: $value\n"; + } + return $exported; + } + + function get_byteorder($magic) { + // The magic is 0x950412de + + // bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565 + $magic_little = (int) - 1794895138; + $magic_little_64 = (int) 2500072158; + // 0xde120495 + $magic_big = ((int) - 569244523) & 0xFFFFFFFF; + if ($magic_little == $magic || $magic_little_64 == $magic) { + return 'little'; + } else if ($magic_big == $magic) { + return 'big'; + } else { + return false; + } + } + + function import_from_reader($reader) { + $endian_string = MO::get_byteorder($reader->readint32()); + if (false === $endian_string) { + return false; + } + $reader->setEndian($endian_string); + + $endian = ('big' == $endian_string)? 'N' : 'V'; + + $header = $reader->read(24); + if ($reader->strlen($header) != 24) + return false; + + // parse header + $header = unpack("{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header); + if (!is_array($header)) + return false; + + extract( $header ); + + // support revision 0 of MO format specs, only + if ($revision != 0) + return false; + + // seek to data blocks + $reader->seekto($originals_lenghts_addr); + + // read originals' indices + $originals_lengths_length = $translations_lenghts_addr - $originals_lenghts_addr; + if ( $originals_lengths_length != $total * 8 ) + return false; + + $originals = $reader->read($originals_lengths_length); + if ( $reader->strlen( $originals ) != $originals_lengths_length ) + return false; + + // read translations' indices + $translations_lenghts_length = $hash_addr - $translations_lenghts_addr; + if ( $translations_lenghts_length != $total * 8 ) + return false; + + $translations = $reader->read($translations_lenghts_length); + if ( $reader->strlen( $translations ) != $translations_lenghts_length ) + return false; + + // transform raw data into set of indices + $originals = $reader->str_split( $originals, 8 ); + $translations = $reader->str_split( $translations, 8 ); + + // skip hash table + $strings_addr = $hash_addr + $hash_length * 4; + + $reader->seekto($strings_addr); + + $strings = $reader->read_all(); + $reader->close(); + + for ( $i = 0; $i < $total; $i++ ) { + $o = unpack( "{$endian}length/{$endian}pos", $originals[$i] ); + $t = unpack( "{$endian}length/{$endian}pos", $translations[$i] ); + if ( !$o || !$t ) return false; + + // adjust offset due to reading strings to separate space before + $o['pos'] -= $strings_addr; + $t['pos'] -= $strings_addr; + + $original = $reader->substr( $strings, $o['pos'], $o['length'] ); + $translation = $reader->substr( $strings, $t['pos'], $t['length'] ); + + if ('' === $original) { + $this->set_headers($this->make_headers($translation)); + } else { + $entry = &$this->make_entry($original, $translation); + $this->entries[$entry->key()] = &$entry; + } + } + return true; + } + + /** + * Build a Translation_Entry from original string and translation strings, + * found in a MO file + * + * @static + * @param string $original original string to translate from MO file. Might contain + * 0x04 as context separator or 0x00 as singular/plural separator + * @param string $translation translation string from MO file. Might contain + * 0x00 as a plural translations separator + */ + function &make_entry($original, $translation) { + $entry = new Translation_Entry(); + // look for context + $parts = explode(chr(4), $original); + if (isset($parts[1])) { + $original = $parts[1]; + $entry->context = $parts[0]; + } + // look for plural original + $parts = explode(chr(0), $original); + $entry->singular = $parts[0]; + if (isset($parts[1])) { + $entry->is_plural = true; + $entry->plural = $parts[1]; + } + // plural translations are also separated by \0 + $entry->translations = explode(chr(0), $translation); + return $entry; + } + + function select_plural_form($count) { + return $this->gettext_select_plural_form($count); + } + + function get_plural_forms_count() { + return $this->_nplurals; + } +} +endif; \ No newline at end of file diff --git a/src/wp-includes/pomo/po.php b/src/wp-includes/pomo/po.php new file mode 100644 index 00000000..8e3eb611 --- /dev/null +++ b/src/wp-includes/pomo/po.php @@ -0,0 +1,363 @@ +headers as $header => $value) { + $header_string.= "$header: $value\n"; + } + $poified = PO::poify($header_string); + return rtrim("msgid \"\"\nmsgstr $poified"); + } + + /** + * Exports all entries to PO format + * + * @return string sequence of mgsgid/msgstr PO strings, doesn't containt newline at the end + */ + function export_entries() { + //TODO sorting + return implode("\n\n", array_map(array('PO', 'export_entry'), $this->entries)); + } + + /** + * Exports the whole PO file as a string + * + * @param bool $include_headers whether to include the headers in the export + * @return string ready for inclusion in PO file string for headers and all the enrtries + */ + function export($include_headers = true) { + $res = ''; + if ($include_headers) { + $res .= $this->export_headers(); + $res .= "\n\n"; + } + $res .= $this->export_entries(); + return $res; + } + + /** + * Same as {@link export}, but writes the result to a file + * + * @param string $filename where to write the PO string + * @param bool $include_headers whether to include tje headers in the export + * @return bool true on success, false on error + */ + function export_to_file($filename, $include_headers = true) { + $fh = fopen($filename, 'w'); + if (false === $fh) return false; + $export = $this->export($include_headers); + $res = fwrite($fh, $export); + if (false === $res) return false; + return fclose($fh); + } + + /** + * Formats a string in PO-style + * + * @static + * @param string $string the string to format + * @return string the poified string + */ + function poify($string) { + $quote = '"'; + $slash = '\\'; + $newline = "\n"; + + $replaces = array( + "$slash" => "$slash$slash", + "$quote" => "$slash$quote", + "\t" => '\t', + ); + + $string = str_replace(array_keys($replaces), array_values($replaces), $string); + + $po = $quote.implode("${slash}n$quote$newline$quote", explode($newline, $string)).$quote; + // add empty string on first line for readbility + if (false !== strpos($string, $newline) && + (substr_count($string, $newline) > 1 || !($newline === substr($string, -strlen($newline))))) { + $po = "$quote$quote$newline$po"; + } + // remove empty strings + $po = str_replace("$newline$quote$quote", '', $po); + return $po; + } + + /** + * Gives back the original string from a PO-formatted string + * + * @static + * @param string $string PO-formatted string + * @return string enascaped string + */ + function unpoify($string) { + $escapes = array('t' => "\t", 'n' => "\n", '\\' => '\\'); + $lines = array_map('trim', explode("\n", $string)); + $lines = array_map(array('PO', 'trim_quotes'), $lines); + $unpoified = ''; + $previous_is_backslash = false; + foreach($lines as $line) { + preg_match_all('/./u', $line, $chars); + $chars = $chars[0]; + foreach($chars as $char) { + if (!$previous_is_backslash) { + if ('\\' == $char) + $previous_is_backslash = true; + else + $unpoified .= $char; + } else { + $previous_is_backslash = false; + $unpoified .= isset($escapes[$char])? $escapes[$char] : $char; + } + } + } + return $unpoified; + } + + /** + * Inserts $with in the beginning of every new line of $string and + * returns the modified string + * + * @static + * @param string $string prepend lines in this string + * @param string $with prepend lines with this string + */ + function prepend_each_line($string, $with) { + $php_with = var_export($with, true); + $lines = explode("\n", $string); + // do not prepend the string on the last empty line, artefact by explode + if ("\n" == substr($string, -1)) unset($lines[count($lines) - 1]); + $res = implode("\n", array_map(create_function('$x', "return $php_with.\$x;"), $lines)); + // give back the empty line, we ignored above + if ("\n" == substr($string, -1)) $res .= "\n"; + return $res; + } + + /** + * Prepare a text as a comment -- wraps the lines and prepends # + * and a special character to each line + * + * @access private + * @param string $text the comment text + * @param string $char character to denote a special PO comment, + * like :, default is a space + */ + function comment_block($text, $char=' ') { + $text = wordwrap($text, PO_MAX_LINE_LEN - 3); + return PO::prepend_each_line($text, "#$char "); + } + + /** + * Builds a string from the entry for inclusion in PO file + * + * @static + * @param object &$entry the entry to convert to po string + * @return string|bool PO-style formatted string for the entry or + * false if the entry is empty + */ + function export_entry(&$entry) { + if (is_null($entry->singular)) return false; + $po = array(); + if (!empty($entry->translator_comments)) $po[] = PO::comment_block($entry->translator_comments); + if (!empty($entry->extracted_comments)) $po[] = PO::comment_block($entry->extracted_comments, '.'); + if (!empty($entry->references)) $po[] = PO::comment_block(implode(' ', $entry->references), ':'); + if (!empty($entry->flags)) $po[] = PO::comment_block(implode(", ", $entry->flags), ','); + if (!is_null($entry->context)) $po[] = 'msgctxt '.PO::poify($entry->context); + $po[] = 'msgid '.PO::poify($entry->singular); + if (!$entry->is_plural) { + $translation = empty($entry->translations)? '' : $entry->translations[0]; + $po[] = 'msgstr '.PO::poify($translation); + } else { + $po[] = 'msgid_plural '.PO::poify($entry->plural); + $translations = empty($entry->translations)? array('', '') : $entry->translations; + foreach($translations as $i => $translation) { + $po[] = "msgstr[$i] ".PO::poify($translation); + } + } + return implode("\n", $po); + } + + function import_from_file($filename) { + $f = fopen($filename, 'r'); + if (!$f) return false; + $lineno = 0; + while (true) { + $res = $this->read_entry($f, $lineno); + if (!$res) break; + if ($res['entry']->singular == '') { + $this->set_headers($this->make_headers($res['entry']->translations[0])); + } else { + $this->add_entry($res['entry']); + } + } + PO::read_line($f, 'clear'); + return $res !== false; + } + + function read_entry($f, $lineno = 0) { + $entry = new Translation_Entry(); + // where were we in the last step + // can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural + $context = ''; + $msgstr_index = 0; + $is_final = create_function('$context', 'return $context == "msgstr" || $context == "msgstr_plural";'); + while (true) { + $lineno++; + $line = PO::read_line($f); + if (!$line) { + if (feof($f)) { + if ($is_final($context)) + break; + elseif (!$context) // we haven't read a line and eof came + return null; + else + return false; + } else { + return false; + } + } + if ($line == "\n") continue; + $line = trim($line); + if (preg_match('/^#/', $line, $m)) { + // the comment is the start of a new entry + if ($is_final($context)) { + PO::read_line($f, 'put-back'); + $lineno--; + break; + } + // comments have to be at the beginning + if ($context && $context != 'comment') { + return false; + } + // add comment + $this->add_comment_to_entry($entry, $line); + } elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) { + if ($is_final($context)) { + PO::read_line($f, 'put-back'); + $lineno--; + break; + } + if ($context && $context != 'comment') { + return false; + } + $context = 'msgctxt'; + $entry->context .= PO::unpoify($m[1]); + } elseif (preg_match('/^msgid\s+(".*")/', $line, $m)) { + if ($is_final($context)) { + PO::read_line($f, 'put-back'); + $lineno--; + break; + } + if ($context && $context != 'msgctxt' && $context != 'comment') { + return false; + } + $context = 'msgid'; + $entry->singular .= PO::unpoify($m[1]); + } elseif (preg_match('/^msgid_plural\s+(".*")/', $line, $m)) { + if ($context != 'msgid') { + return false; + } + $context = 'msgid_plural'; + $entry->is_plural = true; + $entry->plural .= PO::unpoify($m[1]); + } elseif (preg_match('/^msgstr\s+(".*")/', $line, $m)) { + if ($context != 'msgid') { + return false; + } + $context = 'msgstr'; + $entry->translations = array(PO::unpoify($m[1])); + } elseif (preg_match('/^msgstr\[(\d+)\]\s+(".*")/', $line, $m)) { + if ($context != 'msgid_plural' && $context != 'msgstr_plural') { + return false; + } + $context = 'msgstr_plural'; + $msgstr_index = $m[1]; + $entry->translations[$m[1]] = PO::unpoify($m[2]); + } elseif (preg_match('/^".*"$/', $line)) { + $unpoified = PO::unpoify($line); + switch ($context) { + case 'msgid': + $entry->singular .= $unpoified; break; + case 'msgctxt': + $entry->context .= $unpoified; break; + case 'msgid_plural': + $entry->plural .= $unpoified; break; + case 'msgstr': + $entry->translations[0] .= $unpoified; break; + case 'msgstr_plural': + $entry->translations[$msgstr_index] .= $unpoified; break; + default: + return false; + } + } else { + return false; + } + } + if (array() == array_filter($entry->translations, create_function('$t', 'return $t || "0" === $t;'))) { + $entry->translations = array(); + } + return array('entry' => $entry, 'lineno' => $lineno); + } + + function read_line($f, $action = 'read') { + static $last_line = ''; + static $use_last_line = false; + if ('clear' == $action) { + $last_line = ''; + return true; + } + if ('put-back' == $action) { + $use_last_line = true; + return true; + } + $line = $use_last_line? $last_line : fgets($f); + $last_line = $line; + $use_last_line = false; + return $line; + } + + function add_comment_to_entry(&$entry, $po_comment_line) { + $first_two = substr($po_comment_line, 0, 2); + $comment = trim(substr($po_comment_line, 2)); + if ('#:' == $first_two) { + $entry->references = array_merge($entry->references, preg_split('/\s+/', $comment)); + } elseif ('#.' == $first_two) { + $entry->extracted_comments = trim($entry->extracted_comments . "\n" . $comment); + } elseif ('#,' == $first_two) { + $entry->flags = array_merge($entry->flags, preg_split('/,\s*/', $comment)); + } else { + $entry->translator_comments = trim($entry->translator_comments . "\n" . $comment); + } + } + + function trim_quotes($s) { + if ( substr($s, 0, 1) == '"') $s = substr($s, 1); + if ( substr($s, -1, 1) == '"') $s = substr($s, 0, -1); + return $s; + } +} +endif; diff --git a/src/wp-includes/pomo/streams.php b/src/wp-includes/pomo/streams.php new file mode 100644 index 00000000..289cc785 --- /dev/null +++ b/src/wp-includes/pomo/streams.php @@ -0,0 +1,209 @@ + + * + * @version $Id: streams.php 406 2010-02-07 11:10:24Z nbachiyski $ + * @package pomo + * @subpackage streams + */ + +if ( !class_exists( 'POMO_Reader' ) ): +class POMO_Reader { + + var $endian = 'little'; + var $_post = ''; + + function POMO_Reader() { + $this->is_overloaded = ((ini_get("mbstring.func_overload") & 2) != 0) && function_exists('mb_substr'); + $this->_pos = 0; + } + + /** + * Sets the endianness of the file. + * + * @param string $endian 'big' or 'little' + */ + function setEndian($endian) { + $this->endian = $endian; + } + + /** + * Reads a 32bit Integer from the Stream + * + * @return mixed The integer, corresponding to the next 32 bits from + * the stream of false if there are not enough bytes or on error + */ + function readint32() { + $bytes = $this->read(4); + if (4 != $this->strlen($bytes)) + return false; + $endian_letter = ('big' == $this->endian)? 'N' : 'V'; + $int = unpack($endian_letter, $bytes); + return array_shift($int); + } + + /** + * Reads an array of 32-bit Integers from the Stream + * + * @param integer count How many elements should be read + * @return mixed Array of integers or false if there isn't + * enough data or on error + */ + function readint32array($count) { + $bytes = $this->read(4 * $count); + if (4*$count != $this->strlen($bytes)) + return false; + $endian_letter = ('big' == $this->endian)? 'N' : 'V'; + return unpack($endian_letter.$count, $bytes); + } + + + function substr($string, $start, $length) { + if ($this->is_overloaded) { + return mb_substr($string, $start, $length, 'ascii'); + } else { + return substr($string, $start, $length); + } + } + + function strlen($string) { + if ($this->is_overloaded) { + return mb_strlen($string, 'ascii'); + } else { + return strlen($string); + } + } + + function str_split($string, $chunk_size) { + if (!function_exists('str_split')) { + $length = $this->strlen($string); + $out = array(); + for ($i = 0; $i < $length; $i += $chunk_size) + $out[] = $this->substr($string, $i, $chunk_size); + return $out; + } else { + return str_split( $string, $chunk_size ); + } + } + + + function pos() { + return $this->_pos; + } + + function is_resource() { + return true; + } + + function close() { + return true; + } +} +endif; + +if ( !class_exists( 'POMO_FileReader' ) ): +class POMO_FileReader extends POMO_Reader { + function POMO_FileReader($filename) { + parent::POMO_Reader(); + $this->_f = fopen($filename, 'r'); + } + + function read($bytes) { + return fread($this->_f, $bytes); + } + + function seekto($pos) { + if ( -1 == fseek($this->_f, $pos, SEEK_SET)) { + return false; + } + $this->_pos = $pos; + return true; + } + + function is_resource() { + return is_resource($this->_f); + } + + function feof() { + return feof($this->_f); + } + + function close() { + return fclose($this->_f); + } + + function read_all() { + $all = ''; + while ( !$this->feof() ) + $all .= $this->read(4096); + return $all; + } +} +endif; + +if ( !class_exists( 'POMO_StringReader' ) ): +/** + * Provides file-like methods for manipulating a string instead + * of a physical file. + */ +class POMO_StringReader extends POMO_Reader { + + var $_str = ''; + + function POMO_StringReader($str = '') { + parent::POMO_Reader(); + $this->_str = $str; + $this->_pos = 0; + } + + + function read($bytes) { + $data = $this->substr($this->_str, $this->_pos, $bytes); + $this->_pos += $bytes; + if ($this->strlen($this->_str) < $this->_pos) $this->_pos = $this->strlen($this->_str); + return $data; + } + + function seekto($pos) { + $this->_pos = $pos; + if ($this->strlen($this->_str) < $this->_pos) $this->_pos = $this->strlen($this->_str); + return $this->_pos; + } + + function length() { + return $this->strlen($this->_str); + } + + function read_all() { + return $this->substr($this->_str, $this->_pos, $this->strlen($this->_str)); + } + +} +endif; + +if ( !class_exists( 'POMO_CachedFileReader' ) ): +/** + * Reads the contents of the file in the beginning. + */ +class POMO_CachedFileReader extends POMO_StringReader { + function POMO_CachedFileReader($filename) { + parent::POMO_StringReader(); + $this->_str = file_get_contents($filename); + if (false === $this->_str) + return false; + $this->_pos = 0; + } +} +endif; + +if ( !class_exists( 'POMO_CachedIntFileReader' ) ): +/** + * Reads the contents of the file in the beginning. + */ +class POMO_CachedIntFileReader extends POMO_CachedFileReader { + function POMO_CachedIntFileReader($filename) { + parent::POMO_CachedFileReader($filename); + } +} +endif; \ No newline at end of file diff --git a/src/wp-includes/pomo/translations.php b/src/wp-includes/pomo/translations.php new file mode 100644 index 00000000..01be8df4 --- /dev/null +++ b/src/wp-includes/pomo/translations.php @@ -0,0 +1,253 @@ +key(); + if (false === $key) return false; + $this->entries[$key] = &$entry; + return true; + } + + /** + * Sets $header PO header to $value + * + * If the header already exists, it will be overwritten + * + * TODO: this should be out of this class, it is gettext specific + * + * @param string $header header name, without trailing : + * @param string $value header value, without trailing \n + */ + function set_header($header, $value) { + $this->headers[$header] = $value; + } + + function set_headers(&$headers) { + foreach($headers as $header => $value) { + $this->set_header($header, $value); + } + } + + function get_header($header) { + return isset($this->headers[$header])? $this->headers[$header] : false; + } + + function translate_entry(&$entry) { + $key = $entry->key(); + return isset($this->entries[$key])? $this->entries[$key] : false; + } + + function translate($singular, $context=null) { + $entry = new Translation_Entry(array('singular' => $singular, 'context' => $context)); + $translated = $this->translate_entry($entry); + return ($translated && !empty($translated->translations))? $translated->translations[0] : $singular; + } + + /** + * Given the number of items, returns the 0-based index of the plural form to use + * + * Here, in the base Translations class, the commong logic for English is implmented: + * 0 if there is one element, 1 otherwise + * + * This function should be overrided by the sub-classes. For example MO/PO can derive the logic + * from their headers. + * + * @param integer $count number of items + */ + function select_plural_form($count) { + return 1 == $count? 0 : 1; + } + + function get_plural_forms_count() { + return 2; + } + + function translate_plural($singular, $plural, $count, $context = null) { + $entry = new Translation_Entry(array('singular' => $singular, 'plural' => $plural, 'context' => $context)); + $translated = $this->translate_entry($entry); + $index = $this->select_plural_form($count); + $total_plural_forms = $this->get_plural_forms_count(); + if ($translated && 0 <= $index && $index < $total_plural_forms && + is_array($translated->translations) && + isset($translated->translations[$index])) + return $translated->translations[$index]; + else + return 1 == $count? $singular : $plural; + } + + /** + * Merge $other in the current object. + * + * @param Object &$other Another Translation object, whose translations will be merged in this one + * @return void + **/ + function merge_with(&$other) { + foreach( $other->entries as $entry ) { + $this->entries[$entry->key()] = $entry; + } + } +} + +class Gettext_Translations extends Translations { + /** + * The gettext implmentation of select_plural_form. + * + * It lives in this class, because there are more than one descendand, which will use it and + * they can't share it effectively. + * + */ + function gettext_select_plural_form($count) { + if (!isset($this->_gettext_select_plural_form) || is_null($this->_gettext_select_plural_form)) { + list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms')); + $this->_nplurals = $nplurals; + $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression); + } + return call_user_func($this->_gettext_select_plural_form, $count); + } + + function nplurals_and_expression_from_header($header) { + if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) { + $nplurals = (int)$matches[1]; + $expression = trim($this->parenthesize_plural_exression($matches[2])); + return array($nplurals, $expression); + } else { + return array(2, 'n != 1'); + } + } + + /** + * Makes a function, which will return the right translation index, according to the + * plural forms header + */ + function make_plural_form_function($nplurals, $expression) { + $expression = str_replace('n', '$n', $expression); + $func_body = " + \$index = (int)($expression); + return (\$index < $nplurals)? \$index : $nplurals - 1;"; + return create_function('$n', $func_body); + } + + /** + * Adds parantheses to the inner parts of ternary operators in + * plural expressions, because PHP evaluates ternary oerators from left to right + * + * @param string $expression the expression without parentheses + * @return string the expression with parentheses added + */ + function parenthesize_plural_exression($expression) { + $expression .= ';'; + $res = ''; + $depth = 0; + for ($i = 0; $i < strlen($expression); ++$i) { + $char = $expression[$i]; + switch ($char) { + case '?': + $res .= ' ? ('; + $depth++; + break; + case ':': + $res .= ') : ('; + break; + case ';': + $res .= str_repeat(')', $depth) . ';'; + $depth= 0; + break; + default: + $res .= $char; + } + } + return rtrim($res, ';'); + } + + function make_headers($translation) { + $headers = array(); + // sometimes \ns are used instead of real new lines + $translation = str_replace('\n', "\n", $translation); + $lines = explode("\n", $translation); + foreach($lines as $line) { + $parts = explode(':', $line, 2); + if (!isset($parts[1])) continue; + $headers[trim($parts[0])] = trim($parts[1]); + } + return $headers; + } + + function set_header($header, $value) { + parent::set_header($header, $value); + if ('Plural-Forms' == $header) { + list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms')); + $this->_nplurals = $nplurals; + $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression); + } + } +} +endif; + +if ( !class_exists( 'NOOP_Translations' ) ): +/** + * Provides the same interface as Translations, but doesn't do anything + */ +class NOOP_Translations { + var $entries = array(); + var $headers = array(); + + function add_entry($entry) { + return true; + } + + function set_header($header, $value) { + } + + function set_headers(&$headers) { + } + + function get_header($header) { + return false; + } + + function translate_entry(&$entry) { + return false; + } + + function translate($singular, $context=null) { + return $singular; + } + + function select_plural_form($count) { + return 1 == $count? 0 : 1; + } + + function get_plural_forms_count() { + return 2; + } + + function translate_plural($singular, $plural, $count, $context = null) { + return 1 == $count? $singular : $plural; + } + + function merge_with(&$other) { + } +} +endif; diff --git a/src/wp-includes/post-template.php b/src/wp-includes/post-template.php new file mode 100644 index 00000000..98b6fede --- /dev/null +++ b/src/wp-includes/post-template.php @@ -0,0 +1,1435 @@ +ID; +} + +/** + * Display or retrieve the current post title with optional content. + * + * @since 0.71 + * + * @param string $before Optional. Content to prepend to the title. + * @param string $after Optional. Content to append to the title. + * @param bool $echo Optional, default to true.Whether to display or return. + * @return null|string Null on no title. String if $echo parameter is false. + */ +function the_title($before = '', $after = '', $echo = true) { + $title = get_the_title(); + + if ( strlen($title) == 0 ) + return; + + $title = $before . $title . $after; + + if ( $echo ) + echo $title; + else + return $title; +} + +/** + * Sanitize the current title when retrieving or displaying. + * + * Works like {@link the_title()}, except the parameters can be in a string or + * an array. See the function for what can be override in the $args parameter. + * + * The title before it is displayed will have the tags stripped and {@link + * esc_attr()} before it is passed to the user or displayed. The default + * as with {@link the_title()}, is to display the title. + * + * @since 2.3.0 + * + * @param string|array $args Optional. Override the defaults. + * @return string|null Null on failure or display. String when echo is false. + */ +function the_title_attribute( $args = '' ) { + $title = get_the_title(); + + if ( strlen($title) == 0 ) + return; + + $defaults = array('before' => '', 'after' => '', 'echo' => true); + $r = wp_parse_args($args, $defaults); + extract( $r, EXTR_SKIP ); + + + $title = $before . $title . $after; + $title = esc_attr(strip_tags($title)); + + if ( $echo ) + echo $title; + else + return $title; +} + +/** + * Retrieve post title. + * + * If the post is protected and the visitor is not an admin, then "Protected" + * will be displayed before the post title. If the post is private, then + * "Private" will be located before the post title. + * + * @since 0.71 + * + * @param int $id Optional. Post ID. + * @return string + */ +function get_the_title( $id = 0 ) { + $post = &get_post($id); + + $title = isset($post->post_title) ? $post->post_title : ''; + $id = isset($post->ID) ? $post->ID : (int) $id; + + if ( !is_admin() ) { + if ( !empty($post->post_password) ) { + $protected_title_format = apply_filters('protected_title_format', __('Protected: %s')); + $title = sprintf($protected_title_format, $title); + } else if ( isset($post->post_status) && 'private' == $post->post_status ) { + $private_title_format = apply_filters('private_title_format', __('Private: %s')); + $title = sprintf($private_title_format, $title); + } + } + return apply_filters( 'the_title', $title, $id ); +} + +/** + * Display the Post Global Unique Identifier (guid). + * + * The guid will appear to be a link, but should not be used as an link to the + * post. The reason you should not use it as a link, is because of moving the + * blog across domains. + * + * Url is escaped to make it xml safe + * + * @since 1.5.0 + * + * @param int $id Optional. Post ID. + */ +function the_guid( $id = 0 ) { + echo esc_url( get_the_guid( $id ) ); +} + +/** + * Retrieve the Post Global Unique Identifier (guid). + * + * The guid will appear to be a link, but should not be used as an link to the + * post. The reason you should not use it as a link, is because of moving the + * blog across domains. + * + * @since 1.5.0 + * + * @param int $id Optional. Post ID. + * @return string + */ +function get_the_guid( $id = 0 ) { + $post = &get_post($id); + + return apply_filters('get_the_guid', $post->guid); +} + +/** + * Display the post content. + * + * @since 0.71 + * + * @param string $more_link_text Optional. Content for when there is more text. + * @param string $stripteaser Optional. Teaser content before the more text. + */ +function the_content($more_link_text = null, $stripteaser = 0) { + $content = get_the_content($more_link_text, $stripteaser); + $content = apply_filters('the_content', $content); + $content = str_replace(']]>', ']]>', $content); + echo $content; +} + +/** + * Retrieve the post content. + * + * @since 0.71 + * + * @param string $more_link_text Optional. Content for when there is more text. + * @param string $stripteaser Optional. Teaser content before the more text. + * @return string + */ +function get_the_content($more_link_text = null, $stripteaser = 0) { + global $post, $more, $page, $pages, $multipage, $preview; + + if ( null === $more_link_text ) + $more_link_text = __( '(more...)' ); + + $output = ''; + $hasTeaser = false; + + // If post password required and it doesn't match the cookie. + if ( post_password_required($post) ) { + $output = get_the_password_form(); + return $output; + } + + if ( $page > count($pages) ) // if the requested page doesn't exist + $page = count($pages); // give them the highest numbered page that DOES exist + + $content = $pages[$page-1]; + if ( preg_match('//', $content, $matches) ) { + $content = explode($matches[0], $content, 2); + if ( !empty($matches[1]) && !empty($more_link_text) ) + $more_link_text = strip_tags(wp_kses_no_null(trim($matches[1]))); + + $hasTeaser = true; + } else { + $content = array($content); + } + if ( (false !== strpos($post->post_content, '') && ((!$multipage) || ($page==1))) ) + $stripteaser = 1; + $teaser = $content[0]; + if ( ($more) && ($stripteaser) && ($hasTeaser) ) + $teaser = ''; + $output .= $teaser; + if ( count($content) > 1 ) { + if ( $more ) { + $output .= '' . $content[1]; + } else { + if ( ! empty($more_link_text) ) + $output .= apply_filters( 'the_content_more_link', ' ID}\" class=\"more-link\">$more_link_text", $more_link_text ); + $output = force_balance_tags($output); + } + + } + if ( $preview ) // preview fix for javascript bug with foreign languages + $output = preg_replace_callback('/\%u([0-9A-F]{4})/', '_convert_urlencoded_to_entities', $output); + + return $output; +} + +/** + * Preview fix for javascript bug with foreign languages + * + * @since 3.1.0 + * @access private + * @param array $match Match array from preg_replace_callback + * @returns string + */ +function _convert_urlencoded_to_entities( $match ) { + return '&#' . base_convert( $match[1], 16, 10 ) . ';'; +} + +/** + * Display the post excerpt. + * + * @since 0.71 + * @uses apply_filters() Calls 'the_excerpt' hook on post excerpt. + */ +function the_excerpt() { + echo apply_filters('the_excerpt', get_the_excerpt()); +} + +/** + * Retrieve the post excerpt. + * + * @since 0.71 + * + * @param mixed $deprecated Not used. + * @return string + */ +function get_the_excerpt( $deprecated = '' ) { + if ( !empty( $deprecated ) ) + _deprecated_argument( __FUNCTION__, '2.3' ); + + global $post; + $output = $post->post_excerpt; + if ( post_password_required($post) ) { + $output = __('There is no excerpt because this is a protected post.'); + return $output; + } + + return apply_filters('get_the_excerpt', $output); +} + +/** + * Whether post has excerpt. + * + * @since 2.3.0 + * + * @param int $id Optional. Post ID. + * @return bool + */ +function has_excerpt( $id = 0 ) { + $post = &get_post( $id ); + return ( !empty( $post->post_excerpt ) ); +} + +/** + * Display the classes for the post div. + * + * @since 2.7.0 + * + * @param string|array $class One or more classes to add to the class list. + * @param int $post_id An optional post ID. + */ +function post_class( $class = '', $post_id = null ) { + // Separates classes with a single space, collates classes for post DIV + echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"'; +} + +/** + * Retrieve the classes for the post div as an array. + * + * The class names are add are many. If the post is a sticky, then the 'sticky' + * class name. The class 'hentry' is always added to each post. For each + * category, the class will be added with 'category-' with category slug is + * added. The tags are the same way as the categories with 'tag-' before the tag + * slug. All classes are passed through the filter, 'post_class' with the list + * of classes, followed by $class parameter value, with the post ID as the last + * parameter. + * + * @since 2.7.0 + * + * @param string|array $class One or more classes to add to the class list. + * @param int $post_id An optional post ID. + * @return array Array of classes. + */ +function get_post_class( $class = '', $post_id = null ) { + $post = get_post($post_id); + + $classes = array(); + + if ( empty($post) ) + return $classes; + + $classes[] = 'post-' . $post->ID; + $classes[] = $post->post_type; + $classes[] = 'type-' . $post->post_type; + $classes[] = 'status-' . $post->post_status; + + // Post Format + $post_format = get_post_format( $post->ID ); + + if ( post_type_supports( $post->post_type, 'post-formats' ) ) { + if ( $post_format && !is_wp_error($post_format) ) + $classes[] = 'format-' . sanitize_html_class( $post_format ); + else + $classes[] = 'format-standard'; + } + + // post requires password + if ( post_password_required($post->ID) ) + $classes[] = 'post-password-required'; + + // sticky for Sticky Posts + if ( is_sticky($post->ID) && is_home() && !is_paged() ) + $classes[] = 'sticky'; + + // hentry for hAtom compliance + $classes[] = 'hentry'; + + // Categories + if ( is_object_in_taxonomy( $post->post_type, 'category' ) ) { + foreach ( (array) get_the_category($post->ID) as $cat ) { + if ( empty($cat->slug ) ) + continue; + $classes[] = 'category-' . sanitize_html_class($cat->slug, $cat->term_id); + } + } + + // Tags + if ( is_object_in_taxonomy( $post->post_type, 'post_tag' ) ) { + foreach ( (array) get_the_tags($post->ID) as $tag ) { + if ( empty($tag->slug ) ) + continue; + $classes[] = 'tag-' . sanitize_html_class($tag->slug, $tag->term_id); + } + } + + if ( !empty($class) ) { + if ( !is_array( $class ) ) + $class = preg_split('#\s+#', $class); + $classes = array_merge($classes, $class); + } + + $classes = array_map('esc_attr', $classes); + + return apply_filters('post_class', $classes, $class, $post->ID); +} + +/** + * Display the classes for the body element. + * + * @since 2.8.0 + * + * @param string|array $class One or more classes to add to the class list. + */ +function body_class( $class = '' ) { + // Separates classes with a single space, collates classes for body element + echo 'class="' . join( ' ', get_body_class( $class ) ) . '"'; +} + +/** + * Retrieve the classes for the body element as an array. + * + * @since 2.8.0 + * + * @param string|array $class One or more classes to add to the class list. + * @return array Array of classes. + */ +function get_body_class( $class = '' ) { + global $wp_query, $wpdb; + + $classes = array(); + + if ( is_rtl() ) + $classes[] = 'rtl'; + + if ( is_front_page() ) + $classes[] = 'home'; + if ( is_home() ) + $classes[] = 'blog'; + if ( is_archive() ) + $classes[] = 'archive'; + if ( is_date() ) + $classes[] = 'date'; + if ( is_search() ) + $classes[] = 'search'; + if ( is_paged() ) + $classes[] = 'paged'; + if ( is_attachment() ) + $classes[] = 'attachment'; + if ( is_404() ) + $classes[] = 'error404'; + + if ( is_single() ) { + $post_id = $wp_query->get_queried_object_id(); + $post = $wp_query->get_queried_object(); + + $classes[] = 'single'; + $classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id); + $classes[] = 'postid-' . $post_id; + + // Post Format + $post_format = get_post_format( $post->ID ); + + if ( $post_format && !is_wp_error($post_format) ) + $classes[] = 'single-format-' . sanitize_html_class( $post_format ); + else + $classes[] = 'single-format-standard'; + + if ( is_attachment() ) { + $mime_type = get_post_mime_type($post_id); + $mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' ); + $classes[] = 'attachmentid-' . $post_id; + $classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type ); + } + } elseif ( is_archive() ) { + if ( is_post_type_archive() ) { + $classes[] = 'post-type-archive'; + $classes[] = 'post-type-archive-' . sanitize_html_class( get_query_var( 'post_type' ) ); + } else if ( is_author() ) { + $author = $wp_query->get_queried_object(); + $classes[] = 'author'; + $classes[] = 'author-' . sanitize_html_class( $author->user_nicename , $author->ID ); + $classes[] = 'author-' . $author->ID; + } elseif ( is_category() ) { + $cat = $wp_query->get_queried_object(); + $classes[] = 'category'; + $classes[] = 'category-' . sanitize_html_class( $cat->slug, $cat->term_id ); + $classes[] = 'category-' . $cat->term_id; + } elseif ( is_tag() ) { + $tags = $wp_query->get_queried_object(); + $classes[] = 'tag'; + $classes[] = 'tag-' . sanitize_html_class( $tags->slug, $tags->term_id ); + $classes[] = 'tag-' . $tags->term_id; + } elseif ( is_tax() ) { + $term = $wp_query->get_queried_object(); + $classes[] = 'tax-' . sanitize_html_class( $term->taxonomy ); + $classes[] = 'term-' . sanitize_html_class( $term->slug, $term->term_id ); + $classes[] = 'term-' . $term->term_id; + } + } elseif ( is_page() ) { + $classes[] = 'page'; + + $page_id = $wp_query->get_queried_object_id(); + + $post = get_page($page_id); + + $classes[] = 'page-id-' . $page_id; + + if ( $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' AND post_status = 'publish' LIMIT 1", $page_id) ) ) + $classes[] = 'page-parent'; + + if ( $post->post_parent ) { + $classes[] = 'page-child'; + $classes[] = 'parent-pageid-' . $post->post_parent; + } + if ( is_page_template() ) { + $classes[] = 'page-template'; + $classes[] = 'page-template-' . sanitize_html_class( str_replace( '.', '-', get_post_meta( $page_id, '_wp_page_template', true ) ), '' ); + } + } elseif ( is_search() ) { + if ( !empty( $wp_query->posts ) ) + $classes[] = 'search-results'; + else + $classes[] = 'search-no-results'; + } + + if ( is_user_logged_in() ) + $classes[] = 'logged-in'; + + if ( is_admin_bar_showing() ) + $classes[] = 'admin-bar'; + + $page = $wp_query->get( 'page' ); + + if ( !$page || $page < 2) + $page = $wp_query->get( 'paged' ); + + if ( $page && $page > 1 ) { + $classes[] = 'paged-' . $page; + + if ( is_single() ) + $classes[] = 'single-paged-' . $page; + elseif ( is_page() ) + $classes[] = 'page-paged-' . $page; + elseif ( is_category() ) + $classes[] = 'category-paged-' . $page; + elseif ( is_tag() ) + $classes[] = 'tag-paged-' . $page; + elseif ( is_date() ) + $classes[] = 'date-paged-' . $page; + elseif ( is_author() ) + $classes[] = 'author-paged-' . $page; + elseif ( is_search() ) + $classes[] = 'search-paged-' . $page; + elseif ( is_post_type_archive() ) + $classes[] = 'post-type-paged-' . $page; + } + + if ( !empty( $class ) ) { + if ( !is_array( $class ) ) + $class = preg_split( '#\s+#', $class ); + $classes = array_merge( $classes, $class ); + } + + $classes = array_map( 'esc_attr', $classes ); + + return apply_filters( 'body_class', $classes, $class ); +} + +/** + * Whether post requires password and correct password has been provided. + * + * @since 2.7.0 + * + * @param int|object $post An optional post. Global $post used if not provided. + * @return bool false if a password is not required or the correct password cookie is present, true otherwise. + */ +function post_password_required( $post = null ) { + $post = get_post($post); + + if ( empty($post->post_password) ) + return false; + + if ( !isset($_COOKIE['wp-postpass_' . COOKIEHASH]) ) + return true; + + if ( $_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password ) + return true; + + return false; +} + +/** + * Display "sticky" CSS class, if a post is sticky. + * + * @since 2.7.0 + * + * @param int $post_id An optional post ID. + */ +function sticky_class( $post_id = null ) { + if ( !is_sticky($post_id) ) + return; + + echo " sticky"; +} + +/** + * Page Template Functions for usage in Themes + * + * @package WordPress + * @subpackage Template + */ + +/** + * The formatted output of a list of pages. + * + * Displays page links for paginated posts (i.e. includes the . + * Quicktag one or more times). This tag must be within The Loop. + * + * The defaults for overwriting are: + * 'next_or_number' - Default is 'number' (string). Indicates whether page + * numbers should be used. Valid values are number and next. + * 'nextpagelink' - Default is 'Next Page' (string). Text for link to next page. + * of the bookmark. + * 'previouspagelink' - Default is 'Previous Page' (string). Text for link to + * previous page, if available. + * 'pagelink' - Default is '%' (String).Format string for page numbers. The % in + * the parameter string will be replaced with the page number, so Page % + * generates "Page 1", "Page 2", etc. Defaults to %, just the page number. + * 'before' - Default is '

    Pages:' (string). The html or text to prepend to + * each bookmarks. + * 'after' - Default is '

    ' (string). The html or text to append to each + * bookmarks. + * 'link_before' - Default is '' (string). The html or text to prepend to each + * Pages link inside the tag. Also prepended to the current item, which + * is not linked. + * 'link_after' - Default is '' (string). The html or text to append to each + * Pages link inside the tag. Also appended to the current item, which + * is not linked. + * + * @since 1.2.0 + * @access private + * + * @param string|array $args Optional. Overwrite the defaults. + * @return string Formatted output in HTML. + */ +function wp_link_pages($args = '') { + $defaults = array( + 'before' => '

    ' . __('Pages:'), 'after' => '

    ', + 'link_before' => '', 'link_after' => '', + 'next_or_number' => 'number', 'nextpagelink' => __('Next page'), + 'previouspagelink' => __('Previous page'), 'pagelink' => '%', + 'echo' => 1 + ); + + $r = wp_parse_args( $args, $defaults ); + $r = apply_filters( 'wp_link_pages_args', $r ); + extract( $r, EXTR_SKIP ); + + global $page, $numpages, $multipage, $more, $pagenow; + + $output = ''; + if ( $multipage ) { + if ( 'number' == $next_or_number ) { + $output .= $before; + for ( $i = 1; $i < ($numpages+1); $i = $i + 1 ) { + $j = str_replace('%',$i,$pagelink); + $output .= ' '; + if ( ($i != $page) || ((!$more) && ($page==1)) ) { + $output .= _wp_link_page($i); + } + $output .= $link_before . $j . $link_after; + if ( ($i != $page) || ((!$more) && ($page==1)) ) + $output .= '
    '; + } + $output .= $after; + } else { + if ( $more ) { + $output .= $before; + $i = $page - 1; + if ( $i && $more ) { + $output .= _wp_link_page($i); + $output .= $link_before. $previouspagelink . $link_after . ''; + } + $i = $page + 1; + if ( $i <= $numpages && $more ) { + $output .= _wp_link_page($i); + $output .= $link_before. $nextpagelink . $link_after . ''; + } + $output .= $after; + } + } + } + + if ( $echo ) + echo $output; + + return $output; +} + +/** + * Helper function for wp_link_pages(). + * + * @since 3.1.0 + * @access private + * + * @param int $i Page number. + * @return string Link. + */ +function _wp_link_page( $i ) { + global $post, $wp_rewrite; + + if ( 1 == $i ) { + $url = get_permalink(); + } else { + if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) ) + $url = add_query_arg( 'page', $i, get_permalink() ); + elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID ) + $url = trailingslashit(get_permalink()) . user_trailingslashit("$wp_rewrite->pagination_base/" . $i, 'single_paged'); + else + $url = trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged'); + } + + return ''; +} + +// +// Post-meta: Custom per-post fields. +// + +/** + * Retrieve post custom meta data field. + * + * @since 1.5.0 + * + * @param string $key Meta data key name. + * @return bool|string|array Array of values or single value, if only one element exists. False will be returned if key does not exist. + */ +function post_custom( $key = '' ) { + $custom = get_post_custom(); + + if ( !isset( $custom[$key] ) ) + return false; + elseif ( 1 == count($custom[$key]) ) + return $custom[$key][0]; + else + return $custom[$key]; +} + +/** + * Display list of post custom fields. + * + * @internal This will probably change at some point... + * @since 1.2.0 + * @uses apply_filters() Calls 'the_meta_key' on list item HTML content, with key and value as separate parameters. + */ +function the_meta() { + if ( $keys = get_post_custom_keys() ) { + echo "\n"; + } +} + +// +// Pages +// + +/** + * Retrieve or display list of pages as a dropdown (select list). + * + * @since 2.1.0 + * + * @param array|string $args Optional. Override default arguments. + * @return string HTML content, if not displaying. + */ +function wp_dropdown_pages($args = '') { + $defaults = array( + 'depth' => 0, 'child_of' => 0, + 'selected' => 0, 'echo' => 1, + 'name' => 'page_id', 'id' => '', + 'show_option_none' => '', 'show_option_no_change' => '', + 'option_none_value' => '' + ); + + $r = wp_parse_args( $args, $defaults ); + extract( $r, EXTR_SKIP ); + + $pages = get_pages($r); + $output = ''; + $name = esc_attr($name); + // Back-compat with old system where both id and name were based on $name argument + if ( empty($id) ) + $id = $name; + + if ( ! empty($pages) ) { + $output = "\n"; + } + + $output = apply_filters('wp_dropdown_pages', $output); + + if ( $echo ) + echo $output; + + return $output; +} + +/** + * Retrieve or display list of pages in list (li) format. + * + * @since 1.5.0 + * + * @param array|string $args Optional. Override default arguments. + * @return string HTML content, if not displaying. + */ +function wp_list_pages($args = '') { + $defaults = array( + 'depth' => 0, 'show_date' => '', + 'date_format' => get_option('date_format'), + 'child_of' => 0, 'exclude' => '', + 'title_li' => __('Pages'), 'echo' => 1, + 'authors' => '', 'sort_column' => 'menu_order, post_title', + 'link_before' => '', 'link_after' => '', 'walker' => '', + ); + + $r = wp_parse_args( $args, $defaults ); + extract( $r, EXTR_SKIP ); + + $output = ''; + $current_page = 0; + + // sanitize, mostly to keep spaces out + $r['exclude'] = preg_replace('/[^0-9,]/', '', $r['exclude']); + + // Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array) + $exclude_array = ( $r['exclude'] ) ? explode(',', $r['exclude']) : array(); + $r['exclude'] = implode( ',', apply_filters('wp_list_pages_excludes', $exclude_array) ); + + // Query pages. + $r['hierarchical'] = 0; + $pages = get_pages($r); + + if ( !empty($pages) ) { + if ( $r['title_li'] ) + $output .= '
  • '; + } + + $output = apply_filters('wp_list_pages', $output, $r); + + if ( $r['echo'] ) + echo $output; + else + return $output; +} + +/** + * Display or retrieve list of pages with optional home link. + * + * The arguments are listed below and part of the arguments are for {@link + * wp_list_pages()} function. Check that function for more info on those + * arguments. + * + *
      + *
    • sort_column - How to sort the list of pages. Defaults + * to page title. Use column for posts table.
    • + *
    • menu_class - Class to use for the div ID which contains + * the page list. Defaults to 'menu'.
    • + *
    • echo - Whether to echo list or return it. Defaults to + * echo.
    • + *
    • link_before - Text before show_home argument text.
    • + *
    • link_after - Text after show_home argument text.
    • + *
    • show_home - If you set this argument, then it will + * display the link to the home page. The show_home argument really just needs + * to be set to the value of the text of the link.
    • + *
    + * + * @since 2.7.0 + * + * @param array|string $args + */ +function wp_page_menu( $args = array() ) { + $defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => ''); + $args = wp_parse_args( $args, $defaults ); + $args = apply_filters( 'wp_page_menu_args', $args ); + + $menu = ''; + + $list_args = $args; + + // Show Home in the menu + if ( ! empty($args['show_home']) ) { + if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] ) + $text = __('Home'); + else + $text = $args['show_home']; + $class = ''; + if ( is_front_page() && !is_paged() ) + $class = 'class="current_page_item"'; + $menu .= '
  • ' . $args['link_before'] . $text . $args['link_after'] . '
  • '; + // If the front page is a page, add it to the exclude list + if (get_option('show_on_front') == 'page') { + if ( !empty( $list_args['exclude'] ) ) { + $list_args['exclude'] .= ','; + } else { + $list_args['exclude'] = ''; + } + $list_args['exclude'] .= get_option('page_on_front'); + } + } + + $list_args['echo'] = false; + $list_args['title_li'] = ''; + $menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) ); + + if ( $menu ) + $menu = '
      ' . $menu . '
    '; + + $menu = '
    ' . $menu . "
    \n"; + $menu = apply_filters( 'wp_page_menu', $menu, $args ); + if ( $args['echo'] ) + echo $menu; + else + return $menu; +} + +// +// Page helpers +// + +/** + * Retrieve HTML list content for page list. + * + * @uses Walker_Page to create HTML list content. + * @since 2.1.0 + * @see Walker_Page::walk() for parameters and return description. + */ +function walk_page_tree($pages, $depth, $current_page, $r) { + if ( empty($r['walker']) ) + $walker = new Walker_Page; + else + $walker = $r['walker']; + + $args = array($pages, $depth, $r, $current_page); + return call_user_func_array(array(&$walker, 'walk'), $args); +} + +/** + * Retrieve HTML dropdown (select) content for page list. + * + * @uses Walker_PageDropdown to create HTML dropdown content. + * @since 2.1.0 + * @see Walker_PageDropdown::walk() for parameters and return description. + */ +function walk_page_dropdown_tree() { + $args = func_get_args(); + if ( empty($args[2]['walker']) ) // the user's options are the third parameter + $walker = new Walker_PageDropdown; + else + $walker = $args[2]['walker']; + + return call_user_func_array(array(&$walker, 'walk'), $args); +} + +/** + * Create HTML list of pages. + * + * @package WordPress + * @since 2.1.0 + * @uses Walker + */ +class Walker_Page extends Walker { + /** + * @see Walker::$tree_type + * @since 2.1.0 + * @var string + */ + var $tree_type = 'page'; + + /** + * @see Walker::$db_fields + * @since 2.1.0 + * @todo Decouple this. + * @var array + */ + var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); + + /** + * @see Walker::start_lvl() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param int $depth Depth of page. Used for padding. + */ + function start_lvl(&$output, $depth) { + $indent = str_repeat("\t", $depth); + $output .= "\n$indent
      \n"; + } + + /** + * @see Walker::end_lvl() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param int $depth Depth of page. Used for padding. + */ + function end_lvl(&$output, $depth) { + $indent = str_repeat("\t", $depth); + $output .= "$indent
    \n"; + } + + /** + * @see Walker::start_el() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $page Page data object. + * @param int $depth Depth of page. Used for padding. + * @param int $current_page Page ID. + * @param array $args + */ + function start_el(&$output, $page, $depth, $args, $current_page) { + if ( $depth ) + $indent = str_repeat("\t", $depth); + else + $indent = ''; + + extract($args, EXTR_SKIP); + $css_class = array('page_item', 'page-item-'.$page->ID); + if ( !empty($current_page) ) { + $_current_page = get_page( $current_page ); + _get_post_ancestors($_current_page); + if ( isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors) ) + $css_class[] = 'current_page_ancestor'; + if ( $page->ID == $current_page ) + $css_class[] = 'current_page_item'; + elseif ( $_current_page && $page->ID == $_current_page->post_parent ) + $css_class[] = 'current_page_parent'; + } elseif ( $page->ID == get_option('page_for_posts') ) { + $css_class[] = 'current_page_parent'; + } + + $css_class = implode(' ', apply_filters('page_css_class', $css_class, $page)); + + $output .= $indent . '
  • ' . $link_before . apply_filters( 'the_title', $page->post_title, $page->ID ) . $link_after . ''; + + if ( !empty($show_date) ) { + if ( 'modified' == $show_date ) + $time = $page->post_modified; + else + $time = $page->post_date; + + $output .= " " . mysql2date($date_format, $time); + } + } + + /** + * @see Walker::end_el() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $page Page data object. Not used. + * @param int $depth Depth of page. Not Used. + */ + function end_el(&$output, $page, $depth) { + $output .= "
  • \n"; + } + +} + +/** + * Create HTML dropdown list of pages. + * + * @package WordPress + * @since 2.1.0 + * @uses Walker + */ +class Walker_PageDropdown extends Walker { + /** + * @see Walker::$tree_type + * @since 2.1.0 + * @var string + */ + var $tree_type = 'page'; + + /** + * @see Walker::$db_fields + * @since 2.1.0 + * @todo Decouple this + * @var array + */ + var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); + + /** + * @see Walker::start_el() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $page Page data object. + * @param int $depth Depth of page in reference to parent pages. Used for padding. + * @param array $args Uses 'selected' argument for selected page to set selected HTML attribute for option element. + */ + function start_el(&$output, $page, $depth, $args) { + $pad = str_repeat(' ', $depth * 3); + + $output .= "\t\n"; + } +} + +// +// Attachments +// + +/** + * Display an attachment page link using an image or icon. + * + * @since 2.0.0 + * + * @param int $id Optional. Post ID. + * @param bool $fullsize Optional, default is false. Whether to use full size. + * @param bool $deprecated Deprecated. Not used. + * @param bool $permalink Optional, default is false. Whether to include permalink. + */ +function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $permalink = false ) { + if ( !empty( $deprecated ) ) + _deprecated_argument( __FUNCTION__, '2.5' ); + + if ( $fullsize ) + echo wp_get_attachment_link($id, 'full', $permalink); + else + echo wp_get_attachment_link($id, 'thumbnail', $permalink); +} + +/** + * Retrieve an attachment page link using an image or icon, if possible. + * + * @since 2.5.0 + * @uses apply_filters() Calls 'wp_get_attachment_link' filter on HTML content with same parameters as function. + * + * @param int $id Optional. Post ID. + * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string. + * @param bool $permalink Optional, default is false. Whether to add permalink to image. + * @param bool $icon Optional, default is false. Whether to include icon. + * @param string $text Optional, default is false. If string, then will be link text. + * @return string HTML content. + */ +function wp_get_attachment_link($id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false) { + $id = intval($id); + $_post = & get_post( $id ); + + if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) ) + return __('Missing Attachment'); + + if ( $permalink ) + $url = get_attachment_link($_post->ID); + + $post_title = esc_attr($_post->post_title); + + if ( $text ) { + $link_text = esc_attr($text); + } elseif ( ( is_int($size) && $size != 0 ) or ( is_string($size) && $size != 'none' ) or $size != false ) { + $link_text = wp_get_attachment_image($id, $size, $icon); + } else { + $link_text = ''; + } + + if( trim($link_text) == '' ) + $link_text = $_post->post_title; + + return apply_filters( 'wp_get_attachment_link', "$link_text", $id, $size, $permalink, $icon, $text ); +} + +/** + * Wrap attachment in <

    > element before content. + * + * @since 2.0.0 + * @uses apply_filters() Calls 'prepend_attachment' hook on HTML content. + * + * @param string $content + * @return string + */ +function prepend_attachment($content) { + global $post; + + if ( empty($post->post_type) || $post->post_type != 'attachment' ) + return $content; + + $p = '

    '; + // show the medium sized image representation of the attachment if available, and link to the raw file + $p .= wp_get_attachment_link(0, 'medium', false); + $p .= '

    '; + $p = apply_filters('prepend_attachment', $p); + + return "$p\n$content"; +} + +// +// Misc +// + +/** + * Retrieve protected post password form content. + * + * @since 1.0.0 + * @uses apply_filters() Calls 'the_password_form' filter on output. + * + * @return string HTML content for password form for password protected post. + */ +function get_the_password_form() { + global $post; + $label = 'pwbox-'.(empty($post->ID) ? rand() : $post->ID); + $output = '
    +

    ' . __("This post is password protected. To view it please enter your password below:") . '

    +

    +
    + '; + return apply_filters('the_password_form', $output); +} + +/** + * Whether currently in a page template. + * + * This template tag allows you to determine if you are in a page template. + * You can optionally provide a template name and then the check will be + * specific to that template. + * + * @since 2.5.0 + * @uses $wp_query + * + * @param string $template The specific template name if specific matching is required. + * @return bool False on failure, true if success. + */ +function is_page_template($template = '') { + if (!is_page()) { + return false; + } + + global $wp_query; + + $page = $wp_query->get_queried_object(); + $custom_fields = get_post_custom_values('_wp_page_template',$page->ID); + $page_template = $custom_fields[0]; + + // We have no argument passed so just see if a page_template has been specified + if ( empty( $template ) ) { + if (!empty( $page_template ) ) { + return true; + } + } elseif ( $template == $page_template) { + return true; + } + + return false; +} + +/** + * Retrieve formatted date timestamp of a revision (linked to that revisions's page). + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses date_i18n() + * + * @param int|object $revision Revision ID or revision object. + * @param bool $link Optional, default is true. Link to revisions's page? + * @return string i18n formatted datetimestamp or localized 'Current Revision'. + */ +function wp_post_revision_title( $revision, $link = true ) { + if ( !$revision = get_post( $revision ) ) + return $revision; + + if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) ) + return false; + + /* translators: revision date format, see http://php.net/date */ + $datef = _x( 'j F, Y @ G:i', 'revision date format'); + /* translators: 1: date */ + $autosavef = __( '%1$s [Autosave]' ); + /* translators: 1: date */ + $currentf = __( '%1$s [Current Revision]' ); + + $date = date_i18n( $datef, strtotime( $revision->post_modified ) ); + if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) ) + $date = "$date"; + + if ( !wp_is_post_revision( $revision ) ) + $date = sprintf( $currentf, $date ); + elseif ( wp_is_post_autosave( $revision ) ) + $date = sprintf( $autosavef, $date ); + + return $date; +} + +/** + * Display list of a post's revisions. + * + * Can output either a UL with edit links or a TABLE with diff interface, and + * restore action links. + * + * Second argument controls parameters: + * (bool) parent : include the parent (the "Current Revision") in the list. + * (string) format : 'list' or 'form-table'. 'list' outputs UL, 'form-table' + * outputs TABLE with UI. + * (int) right : what revision is currently being viewed - used in + * form-table format. + * (int) left : what revision is currently being diffed against right - + * used in form-table format. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses wp_get_post_revisions() + * @uses wp_post_revision_title() + * @uses get_edit_post_link() + * @uses get_the_author_meta() + * + * @todo split into two functions (list, form-table) ? + * + * @param int|object $post_id Post ID or post object. + * @param string|array $args See description {@link wp_parse_args()}. + * @return null + */ +function wp_list_post_revisions( $post_id = 0, $args = null ) { + if ( !$post = get_post( $post_id ) ) + return; + + $defaults = array( 'parent' => false, 'right' => false, 'left' => false, 'format' => 'list', 'type' => 'all' ); + extract( wp_parse_args( $args, $defaults ), EXTR_SKIP ); + + switch ( $type ) { + case 'autosave' : + if ( !$autosave = wp_get_post_autosave( $post->ID ) ) + return; + $revisions = array( $autosave ); + break; + case 'revision' : // just revisions - remove autosave later + case 'all' : + default : + if ( !$revisions = wp_get_post_revisions( $post->ID ) ) + return; + break; + } + + /* translators: post revision: 1: when, 2: author name */ + $titlef = _x( '%1$s by %2$s', 'post revision' ); + + if ( $parent ) + array_unshift( $revisions, $post ); + + $rows = ''; + $class = false; + $can_edit_post = current_user_can( 'edit_post', $post->ID ); + foreach ( $revisions as $revision ) { + if ( !current_user_can( 'read_post', $revision->ID ) ) + continue; + if ( 'revision' === $type && wp_is_post_autosave( $revision ) ) + continue; + + $date = wp_post_revision_title( $revision ); + $name = get_the_author_meta( 'display_name', $revision->post_author ); + + if ( 'form-table' == $format ) { + if ( $left ) + $left_checked = $left == $revision->ID ? ' checked="checked"' : ''; + else + $left_checked = $right_checked ? ' checked="checked"' : ''; // [sic] (the next one) + $right_checked = $right == $revision->ID ? ' checked="checked"' : ''; + + $class = $class ? '' : " class='alternate'"; + + if ( $post->ID != $revision->ID && $can_edit_post ) + $actions = 'ID|$revision->ID" ) . '">' . __( 'Restore' ) . ''; + else + $actions = ''; + + $rows .= "\n"; + $rows .= "\t\n"; + $rows .= "\t\n"; + $rows .= "\t$date\n"; + $rows .= "\t$name\n"; + $rows .= "\t$actions\n"; + $rows .= "\n"; + } else { + $title = sprintf( $titlef, $date, $name ); + $rows .= "\t
  • $title
  • \n"; + } + } + + if ( 'form-table' == $format ) : ?> + +
    + +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +\n"; + echo $rows; + echo ""; + endif; + +} diff --git a/src/wp-includes/post-thumbnail-template.php b/src/wp-includes/post-thumbnail-template.php new file mode 100644 index 00000000..3758d1d4 --- /dev/null +++ b/src/wp-includes/post-thumbnail-template.php @@ -0,0 +1,73 @@ + diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php new file mode 100644 index 00000000..d859473b --- /dev/null +++ b/src/wp-includes/post.php @@ -0,0 +1,5255 @@ + true, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ + 'capability_type' => 'post', + 'map_meta_cap' => true, + 'hierarchical' => false, + 'rewrite' => false, + 'query_var' => false, + 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ), + ) ); + + register_post_type( 'page', array( + 'public' => true, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ + 'capability_type' => 'page', + 'map_meta_cap' => true, + 'hierarchical' => true, + 'rewrite' => false, + 'query_var' => false, + 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ), + ) ); + + register_post_type( 'attachment', array( + 'labels' => array( + 'name' => __( 'Media' ), + ), + 'public' => true, + 'show_ui' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => 'media.php?attachment_id=%d', /* internal use only. don't use this when registering your own post type. */ + 'capability_type' => 'post', + 'map_meta_cap' => true, + 'hierarchical' => false, + 'rewrite' => false, + 'query_var' => false, + 'show_in_nav_menus' => false, + ) ); + + register_post_type( 'revision', array( + 'labels' => array( + 'name' => __( 'Revisions' ), + 'singular_name' => __( 'Revision' ), + ), + 'public' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => 'revision.php?revision=%d', /* internal use only. don't use this when registering your own post type. */ + 'capability_type' => 'post', + 'map_meta_cap' => true, + 'hierarchical' => false, + 'rewrite' => false, + 'query_var' => false, + 'can_export' => false, + ) ); + + register_post_type( 'nav_menu_item', array( + 'labels' => array( + 'name' => __( 'Navigation Menu Items' ), + 'singular_name' => __( 'Navigation Menu Item' ), + ), + 'public' => false, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + 'hierarchical' => false, + 'rewrite' => false, + 'query_var' => false, + ) ); + + register_post_status( 'publish', array( + 'label' => _x( 'Published', 'post' ), + 'public' => true, + '_builtin' => true, /* internal use only. */ + 'label_count' => _n_noop( 'Published (%s)', 'Published (%s)' ), + ) ); + + register_post_status( 'future', array( + 'label' => _x( 'Scheduled', 'post' ), + 'protected' => true, + '_builtin' => true, /* internal use only. */ + 'label_count' => _n_noop('Scheduled (%s)', 'Scheduled (%s)' ), + ) ); + + register_post_status( 'draft', array( + 'label' => _x( 'Draft', 'post' ), + 'protected' => true, + '_builtin' => true, /* internal use only. */ + 'label_count' => _n_noop( 'Draft (%s)', 'Drafts (%s)' ), + ) ); + + register_post_status( 'pending', array( + 'label' => _x( 'Pending', 'post' ), + 'protected' => true, + '_builtin' => true, /* internal use only. */ + 'label_count' => _n_noop( 'Pending (%s)', 'Pending (%s)' ), + ) ); + + register_post_status( 'private', array( + 'label' => _x( 'Private', 'post' ), + 'private' => true, + '_builtin' => true, /* internal use only. */ + 'label_count' => _n_noop( 'Private (%s)', 'Private (%s)' ), + ) ); + + register_post_status( 'trash', array( + 'label' => _x( 'Trash', 'post' ), + 'internal' => true, + '_builtin' => true, /* internal use only. */ + 'label_count' => _n_noop( 'Trash (%s)', 'Trash (%s)' ), + 'show_in_admin_status_list' => true, + ) ); + + register_post_status( 'auto-draft', array( + 'label' => 'auto-draft', + 'internal' => true, + '_builtin' => true, /* internal use only. */ + ) ); + + register_post_status( 'inherit', array( + 'label' => 'inherit', + 'internal' => true, + '_builtin' => true, /* internal use only. */ + 'exclude_from_search' => false, + ) ); +} +add_action( 'init', 'create_initial_post_types', 0 ); // highest priority + +/** + * Retrieve attached file path based on attachment ID. + * + * You can optionally send it through the 'get_attached_file' filter, but by + * default it will just return the file path unfiltered. + * + * The function works by getting the single post meta name, named + * '_wp_attached_file' and returning it. This is a convenience function to + * prevent looking up the meta name and provide a mechanism for sending the + * attached filename through a filter. + * + * @since 2.0.0 + * @uses apply_filters() Calls 'get_attached_file' on file path and attachment ID. + * + * @param int $attachment_id Attachment ID. + * @param bool $unfiltered Whether to apply filters. + * @return string The file path to the attached file. + */ +function get_attached_file( $attachment_id, $unfiltered = false ) { + $file = get_post_meta( $attachment_id, '_wp_attached_file', true ); + // If the file is relative, prepend upload dir + if ( 0 !== strpos($file, '/') && !preg_match('|^.:\\\|', $file) && ( ($uploads = wp_upload_dir()) && false === $uploads['error'] ) ) + $file = $uploads['basedir'] . "/$file"; + if ( $unfiltered ) + return $file; + return apply_filters( 'get_attached_file', $file, $attachment_id ); +} + +/** + * Update attachment file path based on attachment ID. + * + * Used to update the file path of the attachment, which uses post meta name + * '_wp_attached_file' to store the path of the attachment. + * + * @since 2.1.0 + * @uses apply_filters() Calls 'update_attached_file' on file path and attachment ID. + * + * @param int $attachment_id Attachment ID + * @param string $file File path for the attachment + * @return bool False on failure, true on success. + */ +function update_attached_file( $attachment_id, $file ) { + if ( !get_post( $attachment_id ) ) + return false; + + $file = apply_filters( 'update_attached_file', $file, $attachment_id ); + $file = _wp_relative_upload_path($file); + + return update_post_meta( $attachment_id, '_wp_attached_file', $file ); +} + +/** + * Return relative path to an uploaded file. + * + * The path is relative to the current upload dir. + * + * @since 2.9.0 + * @uses apply_filters() Calls '_wp_relative_upload_path' on file path. + * + * @param string $path Full path to the file + * @return string relative path on success, unchanged path on failure. + */ +function _wp_relative_upload_path( $path ) { + $new_path = $path; + + if ( ($uploads = wp_upload_dir()) && false === $uploads['error'] ) { + if ( 0 === strpos($new_path, $uploads['basedir']) ) { + $new_path = str_replace($uploads['basedir'], '', $new_path); + $new_path = ltrim($new_path, '/'); + } + } + + return apply_filters( '_wp_relative_upload_path', $new_path, $path ); +} + +/** + * Retrieve all children of the post parent ID. + * + * Normally, without any enhancements, the children would apply to pages. In the + * context of the inner workings of WordPress, pages, posts, and attachments + * share the same table, so therefore the functionality could apply to any one + * of them. It is then noted that while this function does not work on posts, it + * does not mean that it won't work on posts. It is recommended that you know + * what context you wish to retrieve the children of. + * + * Attachments may also be made the child of a post, so if that is an accurate + * statement (which needs to be verified), it would then be possible to get + * all of the attachments for a post. Attachments have since changed since + * version 2.5, so this is most likely unaccurate, but serves generally as an + * example of what is possible. + * + * The arguments listed as defaults are for this function and also of the + * {@link get_posts()} function. The arguments are combined with the + * get_children defaults and are then passed to the {@link get_posts()} + * function, which accepts additional arguments. You can replace the defaults in + * this function, listed below and the additional arguments listed in the + * {@link get_posts()} function. + * + * The 'post_parent' is the most important argument and important attention + * needs to be paid to the $args parameter. If you pass either an object or an + * integer (number), then just the 'post_parent' is grabbed and everything else + * is lost. If you don't specify any arguments, then it is assumed that you are + * in The Loop and the post parent will be grabbed for from the current post. + * + * The 'post_parent' argument is the ID to get the children. The 'numberposts' + * is the amount of posts to retrieve that has a default of '-1', which is + * used to get all of the posts. Giving a number higher than 0 will only + * retrieve that amount of posts. + * + * The 'post_type' and 'post_status' arguments can be used to choose what + * criteria of posts to retrieve. The 'post_type' can be anything, but WordPress + * post types are 'post', 'pages', and 'attachments'. The 'post_status' + * argument will accept any post status within the write administration panels. + * + * @see get_posts() Has additional arguments that can be replaced. + * @internal Claims made in the long description might be inaccurate. + * + * @since 2.0.0 + * + * @param mixed $args Optional. User defined arguments for replacing the defaults. + * @param string $output Optional. Constant for return type, either OBJECT (default), ARRAY_A, ARRAY_N. + * @return array|bool False on failure and the type will be determined by $output parameter. + */ +function get_children($args = '', $output = OBJECT) { + $kids = array(); + if ( empty( $args ) ) { + if ( isset( $GLOBALS['post'] ) ) { + $args = array('post_parent' => (int) $GLOBALS['post']->post_parent ); + } else { + return $kids; + } + } elseif ( is_object( $args ) ) { + $args = array('post_parent' => (int) $args->post_parent ); + } elseif ( is_numeric( $args ) ) { + $args = array('post_parent' => (int) $args); + } + + $defaults = array( + 'numberposts' => -1, 'post_type' => 'any', + 'post_status' => 'any', 'post_parent' => 0, + ); + + $r = wp_parse_args( $args, $defaults ); + + $children = get_posts( $r ); + + if ( !$children ) + return $kids; + + update_post_cache($children); + + foreach ( $children as $key => $child ) + $kids[$child->ID] = $children[$key]; + + if ( $output == OBJECT ) { + return $kids; + } elseif ( $output == ARRAY_A ) { + foreach ( (array) $kids as $kid ) + $weeuns[$kid->ID] = get_object_vars($kids[$kid->ID]); + return $weeuns; + } elseif ( $output == ARRAY_N ) { + foreach ( (array) $kids as $kid ) + $babes[$kid->ID] = array_values(get_object_vars($kids[$kid->ID])); + return $babes; + } else { + return $kids; + } +} + +/** + * Get extended entry info (). + * + * There should not be any space after the second dash and before the word + * 'more'. There can be text or space(s) after the word 'more', but won't be + * referenced. + * + * The returned array has 'main' and 'extended' keys. Main has the text before + * the . The 'extended' key has the content after the + * comment. + * + * @since 1.0.0 + * + * @param string $post Post content. + * @return array Post before ('main') and after ('extended'). + */ +function get_extended($post) { + //Match the new style more links + if ( preg_match('//', $post, $matches) ) { + list($main, $extended) = explode($matches[0], $post, 2); + } else { + $main = $post; + $extended = ''; + } + + // Strip leading and trailing whitespace + $main = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $main); + $extended = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $extended); + + return array('main' => $main, 'extended' => $extended); +} + +/** + * Retrieves post data given a post ID or post object. + * + * See {@link sanitize_post()} for optional $filter values. Also, the parameter + * $post, must be given as a variable, since it is passed by reference. + * + * @since 1.5.1 + * @uses $wpdb + * @link http://codex.wordpress.org/Function_Reference/get_post + * + * @param int|object $post Post ID or post object. + * @param string $output Optional, default is Object. Either OBJECT, ARRAY_A, or ARRAY_N. + * @param string $filter Optional, default is raw. + * @return mixed Post data + */ +function &get_post(&$post, $output = OBJECT, $filter = 'raw') { + global $wpdb; + $null = null; + + if ( empty($post) ) { + if ( isset($GLOBALS['post']) ) + $_post = & $GLOBALS['post']; + else + return $null; + } elseif ( is_object($post) && empty($post->filter) ) { + _get_post_ancestors($post); + $_post = sanitize_post($post, 'raw'); + wp_cache_add($post->ID, $_post, 'posts'); + } else { + if ( is_object($post) ) + $post_id = $post->ID; + else + $post_id = $post; + + $post_id = (int) $post_id; + if ( ! $_post = wp_cache_get($post_id, 'posts') ) { + $_post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id)); + if ( ! $_post ) + return $null; + _get_post_ancestors($_post); + $_post = sanitize_post($_post, 'raw'); + wp_cache_add($_post->ID, $_post, 'posts'); + } + } + + if ($filter != 'raw') + $_post = sanitize_post($_post, $filter); + + if ( $output == OBJECT ) { + return $_post; + } elseif ( $output == ARRAY_A ) { + $__post = get_object_vars($_post); + return $__post; + } elseif ( $output == ARRAY_N ) { + $__post = array_values(get_object_vars($_post)); + return $__post; + } else { + return $_post; + } +} + +/** + * Retrieve ancestors of a post. + * + * @since 2.5.0 + * + * @param int|object $post Post ID or post object + * @return array Ancestor IDs or empty array if none are found. + */ +function get_post_ancestors($post) { + $post = get_post($post); + + if ( !empty($post->ancestors) ) + return $post->ancestors; + + return array(); +} + +/** + * Retrieve data from a post field based on Post ID. + * + * Examples of the post field will be, 'post_type', 'post_status', 'content', + * etc and based off of the post object property or key names. + * + * The context values are based off of the taxonomy filter functions and + * supported values are found within those functions. + * + * @since 2.3.0 + * @uses sanitize_post_field() See for possible $context values. + * + * @param string $field Post field name + * @param id $post Post ID + * @param string $context Optional. How to filter the field. Default is display. + * @return WP_Error|string Value in post field or WP_Error on failure + */ +function get_post_field( $field, $post, $context = 'display' ) { + $post = (int) $post; + $post = get_post( $post ); + + if ( is_wp_error($post) ) + return $post; + + if ( !is_object($post) ) + return ''; + + if ( !isset($post->$field) ) + return ''; + + return sanitize_post_field($field, $post->$field, $post->ID, $context); +} + +/** + * Retrieve the mime type of an attachment based on the ID. + * + * This function can be used with any post type, but it makes more sense with + * attachments. + * + * @since 2.0.0 + * + * @param int $ID Optional. Post ID. + * @return bool|string False on failure or returns the mime type + */ +function get_post_mime_type($ID = '') { + $post = & get_post($ID); + + if ( is_object($post) ) + return $post->post_mime_type; + + return false; +} + +/** + * Retrieve the format slug for a post + * + * @since 3.1.0 + * + * @param int|object $post A post + * + * @return mixed The format if successful. False if no format is set. WP_Error if errors. + */ +function get_post_format( $post = null ) { + $post = get_post($post); + + if ( ! post_type_supports( $post->post_type, 'post-formats' ) ) + return false; + + $_format = get_the_terms( $post->ID, 'post_format' ); + + if ( empty( $_format ) ) + return false; + + $format = array_shift( $_format ); + + return ( str_replace('post-format-', '', $format->slug ) ); +} + +/** + * Check if a post has a particular format + * + * @since 3.1.0 + * @uses has_term() + * + * @param string $format The format to check for + * @param object|id $post The post to check. If not supplied, defaults to the current post if used in the loop. + * @return bool True if the post has the format, false otherwise. + */ +function has_post_format( $format, $post = null ) { + return has_term('post-format-' . sanitize_key($format), 'post_format', $post); +} + +/** + * Assign a format to a post + * + * @since 3.1.0 + * + * @param int|object $post The post for which to assign a format + * @param string $format A format to assign. Use an empty string or array to remove all formats from the post. + * @return mixed WP_Error on error. Array of affected term IDs on success. + */ +function set_post_format( $post, $format ) { + $post = get_post($post); + + if ( empty($post) ) + return new WP_Error('invalid_post', __('Invalid post')); + + if ( !empty($format) ) { + $format = sanitize_key($format); + if ( 'standard' == $format || !in_array( $format, array_keys( get_post_format_slugs() ) ) ) + $format = ''; + else + $format = 'post-format-' . $format; + } + + return wp_set_post_terms($post->ID, $format, 'post_format'); +} + +/** + * Retrieve the post status based on the Post ID. + * + * If the post ID is of an attachment, then the parent post status will be given + * instead. + * + * @since 2.0.0 + * + * @param int $ID Post ID + * @return string|bool Post status or false on failure. + */ +function get_post_status($ID = '') { + $post = get_post($ID); + + if ( !is_object($post) ) + return false; + + if ( 'attachment' == $post->post_type ) { + if ( 'private' == $post->post_status ) + return 'private'; + + // Unattached attachments are assumed to be published + if ( ( 'inherit' == $post->post_status ) && ( 0 == $post->post_parent) ) + return 'publish'; + + // Inherit status from the parent + if ( $post->post_parent && ( $post->ID != $post->post_parent ) ) + return get_post_status($post->post_parent); + } + + return $post->post_status; +} + +/** + * Retrieve all of the WordPress supported post statuses. + * + * Posts have a limited set of valid status values, this provides the + * post_status values and descriptions. + * + * @since 2.5.0 + * + * @return array List of post statuses. + */ +function get_post_statuses( ) { + $status = array( + 'draft' => __('Draft'), + 'pending' => __('Pending Review'), + 'private' => __('Private'), + 'publish' => __('Published') + ); + + return $status; +} + +/** + * Retrieve all of the WordPress support page statuses. + * + * Pages have a limited set of valid status values, this provides the + * post_status values and descriptions. + * + * @since 2.5.0 + * + * @return array List of page statuses. + */ +function get_page_statuses( ) { + $status = array( + 'draft' => __('Draft'), + 'private' => __('Private'), + 'publish' => __('Published') + ); + + return $status; +} + +/** + * Register a post type. Do not use before init. + * + * A simple function for creating or modifying a post status based on the + * parameters given. The function will accept an array (second optional + * parameter), along with a string for the post status name. + * + * + * Optional $args contents: + * + * label - A descriptive name for the post status marked for translation. Defaults to $post_status. + * public - Whether posts of this status should be shown in the front end of the site. Defaults to true. + * exclude_from_search - Whether to exclude posts with this post status from search results. Defaults to true. + * show_in_admin_all_list - Whether to include posts in the edit listing for their post type + * show_in_admin_status_list - Show in the list of statuses with post counts at the top of the edit + * listings, e.g. All (12) | Published (9) | My Custom Status (2) ... + * + * Arguments prefixed with an _underscore shouldn't be used by plugins and themes. + * + * @package WordPress + * @subpackage Post + * @since 3.0.0 + * @uses $wp_post_statuses Inserts new post status object into the list + * + * @param string $post_status Name of the post status. + * @param array|string $args See above description. + */ +function register_post_status($post_status, $args = array()) { + global $wp_post_statuses; + + if (!is_array($wp_post_statuses)) + $wp_post_statuses = array(); + + // Args prefixed with an underscore are reserved for internal use. + $defaults = array('label' => false, 'label_count' => false, 'exclude_from_search' => null, '_builtin' => false, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'post', 'hierarchical' => false, 'public' => null, 'internal' => null, 'protected' => null, 'private' => null, 'show_in_admin_all' => null, 'publicly_queryable' => null, 'show_in_admin_status_list' => null, 'show_in_admin_all_list' => null, 'single_view_cap' => null); + $args = wp_parse_args($args, $defaults); + $args = (object) $args; + + $post_status = sanitize_key($post_status); + $args->name = $post_status; + + if ( null === $args->public && null === $args->internal && null === $args->protected && null === $args->private ) + $args->internal = true; + + if ( null === $args->public ) + $args->public = false; + + if ( null === $args->private ) + $args->private = false; + + if ( null === $args->protected ) + $args->protected = false; + + if ( null === $args->internal ) + $args->internal = false; + + if ( null === $args->publicly_queryable ) + $args->publicly_queryable = $args->public; + + if ( null === $args->exclude_from_search ) + $args->exclude_from_search = $args->internal; + + if ( null === $args->show_in_admin_all_list ) + $args->show_in_admin_all_list = !$args->internal; + + if ( null === $args->show_in_admin_status_list ) + $args->show_in_admin_status_list = !$args->internal; + + if ( null === $args->single_view_cap ) + $args->single_view_cap = $args->public ? '' : 'edit'; + + if ( false === $args->label ) + $args->label = $post_status; + + if ( false === $args->label_count ) + $args->label_count = array( $args->label, $args->label ); + + $wp_post_statuses[$post_status] = $args; + + return $args; +} + +/** + * Retrieve a post status object by name + * + * @package WordPress + * @subpackage Post + * @since 3.0.0 + * @uses $wp_post_statuses + * @see register_post_status + * @see get_post_statuses + * + * @param string $post_status The name of a registered post status + * @return object A post status object + */ +function get_post_status_object( $post_status ) { + global $wp_post_statuses; + + if ( empty($wp_post_statuses[$post_status]) ) + return null; + + return $wp_post_statuses[$post_status]; +} + +/** + * Get a list of all registered post status objects. + * + * @package WordPress + * @subpackage Post + * @since 3.0.0 + * @uses $wp_post_statuses + * @see register_post_status + * @see get_post_status_object + * + * @param array|string $args An array of key => value arguments to match against the post status objects. + * @param string $output The type of output to return, either post status 'names' or 'objects'. 'names' is the default. + * @param string $operator The logical operation to perform. 'or' means only one element + * from the array needs to match; 'and' means all elements must match. The default is 'and'. + * @return array A list of post type names or objects + */ +function get_post_stati( $args = array(), $output = 'names', $operator = 'and' ) { + global $wp_post_statuses; + + $field = ('names' == $output) ? 'name' : false; + + return wp_filter_object_list($wp_post_statuses, $args, $operator, $field); +} + +/** + * Whether the post type is hierarchical. + * + * A false return value might also mean that the post type does not exist. + * + * @since 3.0.0 + * @see get_post_type_object + * + * @param string $post_type Post type name + * @return bool Whether post type is hierarchical. + */ +function is_post_type_hierarchical( $post_type ) { + if ( ! post_type_exists( $post_type ) ) + return false; + + $post_type = get_post_type_object( $post_type ); + return $post_type->hierarchical; +} + +/** + * Checks if a post type is registered. + * + * @since 3.0.0 + * @uses get_post_type_object() + * + * @param string $post_type Post type name + * @return bool Whether post type is registered. + */ +function post_type_exists( $post_type ) { + return (bool) get_post_type_object( $post_type ); +} + +/** + * Retrieve the post type of the current post or of a given post. + * + * @since 2.1.0 + * + * @uses $post The Loop current post global + * + * @param mixed $the_post Optional. Post object or post ID. + * @return bool|string post type or false on failure. + */ +function get_post_type( $the_post = false ) { + global $post; + + if ( false === $the_post ) + $the_post = $post; + elseif ( is_numeric($the_post) ) + $the_post = get_post($the_post); + + if ( is_object($the_post) ) + return $the_post->post_type; + + return false; +} + +/** + * Retrieve a post type object by name + * + * @package WordPress + * @subpackage Post + * @since 3.0.0 + * @uses $wp_post_types + * @see register_post_type + * @see get_post_types + * + * @param string $post_type The name of a registered post type + * @return object A post type object + */ +function get_post_type_object( $post_type ) { + global $wp_post_types; + + if ( empty($wp_post_types[$post_type]) ) + return null; + + return $wp_post_types[$post_type]; +} + +/** + * Get a list of all registered post type objects. + * + * @package WordPress + * @subpackage Post + * @since 2.9.0 + * @uses $wp_post_types + * @see register_post_type + * + * @param array|string $args An array of key => value arguments to match against the post type objects. + * @param string $output The type of output to return, either post type 'names' or 'objects'. 'names' is the default. + * @param string $operator The logical operation to perform. 'or' means only one element + * from the array needs to match; 'and' means all elements must match. The default is 'and'. + * @return array A list of post type names or objects + */ +function get_post_types( $args = array(), $output = 'names', $operator = 'and' ) { + global $wp_post_types; + + $field = ('names' == $output) ? 'name' : false; + + return wp_filter_object_list($wp_post_types, $args, $operator, $field); +} + +/** + * Register a post type. Do not use before init. + * + * A function for creating or modifying a post type based on the + * parameters given. The function will accept an array (second optional + * parameter), along with a string for the post type name. + * + * Optional $args contents: + * + * - label - Name of the post type shown in the menu. Usually plural. If not set, labels['name'] will be used. + * - description - A short descriptive summary of what the post type is. Defaults to blank. + * - public - Whether posts of this type should be shown in the admin UI. Defaults to false. + * - exclude_from_search - Whether to exclude posts with this post type from search results. + * Defaults to true if the type is not public, false if the type is public. + * - publicly_queryable - Whether post_type queries can be performed from the front page. + * Defaults to whatever public is set as. + * - show_ui - Whether to generate a default UI for managing this post type. Defaults to true + * if the type is public, false if the type is not public. + * - show_in_menu - Where to show the post type in the admin menu. True for a top level menu, + * false for no menu, or can be a top level page like 'tools.php' or 'edit.php?post_type=page'. + * show_ui must be true. + * - menu_position - The position in the menu order the post type should appear. Defaults to the bottom. + * - menu_icon - The url to the icon to be used for this menu. Defaults to use the posts icon. + * - capability_type - The string to use to build the read, edit, and delete capabilities. Defaults to 'post'. + * May be passed as an array to allow for alternative plurals when using this argument as a base to construct the + * capabilities, e.g. array('story', 'stories'). + * - capabilities - Array of capabilities for this post type. By default the capability_type is used + * as a base to construct capabilities. You can see accepted values in {@link get_post_type_capabilities()}. + * - map_meta_cap - Whether to use the internal default meta capability handling. Defaults to false. + * - hierarchical - Whether the post type is hierarchical. Defaults to false. + * - supports - An alias for calling add_post_type_support() directly. See {@link add_post_type_support()} + * for documentation. Defaults to none. + * - register_meta_box_cb - Provide a callback function that will be called when setting up the + * meta boxes for the edit form. Do remove_meta_box() and add_meta_box() calls in the callback. + * - taxonomies - An array of taxonomy identifiers that will be registered for the post type. + * Default is no taxonomies. Taxonomies can be registered later with register_taxonomy() or + * register_taxonomy_for_object_type(). + * - labels - An array of labels for this post type. By default post labels are used for non-hierarchical + * types and page labels for hierarchical ones. You can see accepted values in {@link get_post_type_labels()}. + * - permalink_epmask - The default rewrite endpoint bitmasks. + * - has_archive - True to enable post type archives. Will generate the proper rewrite rules if rewrite is enabled. + * - rewrite - false to prevent rewrite. Defaults to true. Use array('slug'=>$slug) to customize permastruct; + * default will use $post_type as slug. Other options include 'with_front', 'feeds', and 'pages'. + * - query_var - false to prevent queries, or string to value of the query var to use for this post type + * - can_export - true allows this post type to be exported. + * - show_in_nav_menus - true makes this post type available for selection in navigation menus. + * - _builtin - true if this post type is a native or "built-in" post_type. THIS IS FOR INTERNAL USE ONLY! + * - _edit_link - URL segement to use for edit link of this post type. THIS IS FOR INTERNAL USE ONLY! + * + * @since 2.9.0 + * @uses $wp_post_types Inserts new post type object into the list + * + * @param string $post_type Name of the post type. + * @param array|string $args See above description. + * @return object|WP_Error the registered post type object, or an error object + */ +function register_post_type($post_type, $args = array()) { + global $wp_post_types, $wp_rewrite, $wp; + + if ( !is_array($wp_post_types) ) + $wp_post_types = array(); + + // Args prefixed with an underscore are reserved for internal use. + $defaults = array( + 'labels' => array(), 'description' => '', 'publicly_queryable' => null, 'exclude_from_search' => null, + 'capability_type' => 'post', 'capabilities' => array(), 'map_meta_cap' => null, + '_builtin' => false, '_edit_link' => 'post.php?post=%d', 'hierarchical' => false, + 'public' => false, 'rewrite' => true, 'has_archive' => false, 'query_var' => true, + 'supports' => array(), 'register_meta_box_cb' => null, + 'taxonomies' => array(), 'show_ui' => null, 'menu_position' => null, 'menu_icon' => null, + 'permalink_epmask' => EP_PERMALINK, 'can_export' => true, 'show_in_nav_menus' => null, 'show_in_menu' => null, + ); + $args = wp_parse_args($args, $defaults); + $args = (object) $args; + + $post_type = sanitize_key($post_type); + $args->name = $post_type; + + if ( strlen( $post_type ) > 20 ) + return new WP_Error( 'post_type_too_long', __( 'Post types cannot exceed 20 characters in length' ) ); + + // If not set, default to the setting for public. + if ( null === $args->publicly_queryable ) + $args->publicly_queryable = $args->public; + + // If not set, default to the setting for public. + if ( null === $args->show_ui ) + $args->show_ui = $args->public; + + // If not set, default to the setting for show_ui. + if ( null === $args->show_in_menu || ! $args->show_ui ) + $args->show_in_menu = $args->show_ui; + + // Whether to show this type in nav-menus.php. Defaults to the setting for public. + if ( null === $args->show_in_nav_menus ) + $args->show_in_nav_menus = $args->public; + + // If not set, default to true if not public, false if public. + if ( null === $args->exclude_from_search ) + $args->exclude_from_search = !$args->public; + + // Back compat with quirky handling in version 3.0. #14122 + if ( empty( $args->capabilities ) && null === $args->map_meta_cap && in_array( $args->capability_type, array( 'post', 'page' ) ) ) + $args->map_meta_cap = true; + + if ( null === $args->map_meta_cap ) + $args->map_meta_cap = false; + + $args->cap = get_post_type_capabilities( $args ); + unset($args->capabilities); + + if ( is_array( $args->capability_type ) ) + $args->capability_type = $args->capability_type[0]; + + if ( ! empty($args->supports) ) { + add_post_type_support($post_type, $args->supports); + unset($args->supports); + } else { + // Add default features + add_post_type_support($post_type, array('title', 'editor')); + } + + if ( false !== $args->query_var && !empty($wp) ) { + if ( true === $args->query_var ) + $args->query_var = $post_type; + $args->query_var = sanitize_title_with_dashes($args->query_var); + $wp->add_query_var($args->query_var); + } + + if ( false !== $args->rewrite && '' != get_option('permalink_structure') ) { + if ( ! is_array( $args->rewrite ) ) + $args->rewrite = array(); + if ( empty( $args->rewrite['slug'] ) ) + $args->rewrite['slug'] = $post_type; + if ( ! isset( $args->rewrite['with_front'] ) ) + $args->rewrite['with_front'] = true; + if ( ! isset( $args->rewrite['pages'] ) ) + $args->rewrite['pages'] = true; + if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive ) + $args->rewrite['feeds'] = (bool) $args->has_archive; + + if ( $args->hierarchical ) + $wp_rewrite->add_rewrite_tag("%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name="); + else + $wp_rewrite->add_rewrite_tag("%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name="); + + if ( $args->has_archive ) { + $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive; + if ( $args->rewrite['with_front'] ) + $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; + else + $archive_slug = $wp_rewrite->root . $archive_slug; + + $wp_rewrite->add_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' ); + if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) { + $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; + $wp_rewrite->add_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); + $wp_rewrite->add_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); + } + if ( $args->rewrite['pages'] ) + $wp_rewrite->add_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' ); + } + + $wp_rewrite->add_permastruct($post_type, "{$args->rewrite['slug']}/%$post_type%", $args->rewrite['with_front'], $args->permalink_epmask); + } + + if ( $args->register_meta_box_cb ) + add_action('add_meta_boxes_' . $post_type, $args->register_meta_box_cb, 10, 1); + + $args->labels = get_post_type_labels( $args ); + $args->label = $args->labels->name; + + $wp_post_types[$post_type] = $args; + + add_action( 'future_' . $post_type, '_future_post_hook', 5, 2 ); + + foreach ( $args->taxonomies as $taxonomy ) { + register_taxonomy_for_object_type( $taxonomy, $post_type ); + } + + return $args; +} + +/** + * Builds an object with all post type capabilities out of a post type object + * + * Post type capabilities use the 'capability_type' argument as a base, if the + * capability is not set in the 'capabilities' argument array or if the + * 'capabilities' argument is not supplied. + * + * The capability_type argument can optionally be registered as an array, with + * the first value being singular and the second plural, e.g. array('story, 'stories') + * Otherwise, an 's' will be added to the value for the plural form. After + * registration, capability_type will always be a string of the singular value. + * + * By default, seven keys are accepted as part of the capabilities array: + * + * - edit_post, read_post, and delete_post are meta capabilities, which are then + * generally mapped to corresponding primitive capabilities depending on the + * context, which would be the post being edited/read/deleted and the user or + * role being checked. Thus these capabilities would generally not be granted + * directly to users or roles. + * + * - edit_posts - Controls whether objects of this post type can be edited. + * - edit_others_posts - Controls whether objects of this type owned by other users + * can be edited. If the post type does not support an author, then this will + * behave like edit_posts. + * - publish_posts - Controls publishing objects of this post type. + * - read_private_posts - Controls whether private objects can be read. + + * These four primitive capabilities are checked in core in various locations. + * There are also seven other primitive capabilities which are not referenced + * directly in core, except in map_meta_cap(), which takes the three aforementioned + * meta capabilities and translates them into one or more primitive capabilities + * that must then be checked against the user or role, depending on the context. + * + * - read - Controls whether objects of this post type can be read. + * - delete_posts - Controls whether objects of this post type can be deleted. + * - delete_private_posts - Controls whether private objects can be deleted. + * - delete_published_posts - Controls whether published objects can be deleted. + * - delete_others_posts - Controls whether objects owned by other users can be + * can be deleted. If the post type does not support an author, then this will + * behave like delete_posts. + * - edit_private_posts - Controls whether private objects can be edited. + * - edit_published_posts - Controls whether published objects can be deleted. + * + * These additional capabilities are only used in map_meta_cap(). Thus, they are + * only assigned by default if the post type is registered with the 'map_meta_cap' + * argument set to true (default is false). + * + * @see map_meta_cap() + * @since 3.0.0 + * + * @param object $args Post type registration arguments + * @return object object with all the capabilities as member variables + */ +function get_post_type_capabilities( $args ) { + if ( ! is_array( $args->capability_type ) ) + $args->capability_type = array( $args->capability_type, $args->capability_type . 's' ); + + // Singular base for meta capabilities, plural base for primitive capabilities. + list( $singular_base, $plural_base ) = $args->capability_type; + + $default_capabilities = array( + // Meta capabilities + 'edit_post' => 'edit_' . $singular_base, + 'read_post' => 'read_' . $singular_base, + 'delete_post' => 'delete_' . $singular_base, + // Primitive capabilities used outside of map_meta_cap(): + 'edit_posts' => 'edit_' . $plural_base, + 'edit_others_posts' => 'edit_others_' . $plural_base, + 'publish_posts' => 'publish_' . $plural_base, + 'read_private_posts' => 'read_private_' . $plural_base, + ); + + // Primitive capabilities used within map_meta_cap(): + if ( $args->map_meta_cap ) { + $default_capabilities_for_mapping = array( + 'read' => 'read', + 'delete_posts' => 'delete_' . $plural_base, + 'delete_private_posts' => 'delete_private_' . $plural_base, + 'delete_published_posts' => 'delete_published_' . $plural_base, + 'delete_others_posts' => 'delete_others_' . $plural_base, + 'edit_private_posts' => 'edit_private_' . $plural_base, + 'edit_published_posts' => 'edit_published_' . $plural_base, + ); + $default_capabilities = array_merge( $default_capabilities, $default_capabilities_for_mapping ); + } + + $capabilities = array_merge( $default_capabilities, $args->capabilities ); + + // Remember meta capabilities for future reference. + if ( $args->map_meta_cap ) + _post_type_meta_capabilities( $capabilities ); + + return (object) $capabilities; +} + +/** + * Stores or returns a list of post type meta caps for map_meta_cap(). + * + * @since 3.1.0 + * @access private + */ +function _post_type_meta_capabilities( $capabilities = null ) { + static $meta_caps = array(); + if ( null === $capabilities ) + return $meta_caps; + foreach ( $capabilities as $core => $custom ) { + if ( in_array( $core, array( 'read_post', 'delete_post', 'edit_post' ) ) ) + $meta_caps[ $custom ] = $core; + } +} + +/** + * Builds an object with all post type labels out of a post type object + * + * Accepted keys of the label array in the post type object: + * - name - general name for the post type, usually plural. The same and overriden by $post_type_object->label. Default is Posts/Pages + * - singular_name - name for one object of this post type. Default is Post/Page + * - add_new - Default is Add New for both hierarchical and non-hierarchical types. When internationalizing this string, please use a {@link http://codex.wordpress.org/I18n_for_WordPress_Developers#Disambiguation_by_context gettext context} matching your post type. Example: _x('Add New', 'product'); + * - add_new_item - Default is Add New Post/Add New Page + * - edit_item - Default is Edit Post/Edit Page + * - new_item - Default is New Post/New Page + * - view_item - Default is View Post/View Page + * - search_items - Default is Search Posts/Search Pages + * - not_found - Default is No posts found/No pages found + * - not_found_in_trash - Default is No posts found in Trash/No pages found in Trash + * - parent_item_colon - This string isn't used on non-hierarchical types. In hierarchical ones the default is Parent Page: + * + * Above, the first default value is for non-hierarchical post types (like posts) and the second one is for hierarchical post types (like pages). + * + * @since 3.0.0 + * @param object $post_type_object + * @return object object with all the labels as member variables + */ +function get_post_type_labels( $post_type_object ) { + $nohier_vs_hier_defaults = array( + 'name' => array( _x('Posts', 'post type general name'), _x('Pages', 'post type general name') ), + 'singular_name' => array( _x('Post', 'post type singular name'), _x('Page', 'post type singular name') ), + 'add_new' => array( _x('Add New', 'post'), _x('Add New', 'page') ), + 'add_new_item' => array( __('Add New Post'), __('Add New Page') ), + 'edit_item' => array( __('Edit Post'), __('Edit Page') ), + 'new_item' => array( __('New Post'), __('New Page') ), + 'view_item' => array( __('View Post'), __('View Page') ), + 'search_items' => array( __('Search Posts'), __('Search Pages') ), + 'not_found' => array( __('No posts found.'), __('No pages found.') ), + 'not_found_in_trash' => array( __('No posts found in Trash.'), __('No pages found in Trash.') ), + 'parent_item_colon' => array( null, __('Parent Page:') ), + ); + $nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name']; + return _get_custom_object_labels( $post_type_object, $nohier_vs_hier_defaults ); +} + +/** + * Builds an object with custom-something object (post type, taxonomy) labels out of a custom-something object + * + * @access private + * @since 3.0.0 + */ +function _get_custom_object_labels( $object, $nohier_vs_hier_defaults ) { + + if ( isset( $object->label ) && empty( $object->labels['name'] ) ) + $object->labels['name'] = $object->label; + + if ( !isset( $object->labels['singular_name'] ) && isset( $object->labels['name'] ) ) + $object->labels['singular_name'] = $object->labels['name']; + + if ( !isset( $object->labels['menu_name'] ) && isset( $object->labels['name'] ) ) + $object->labels['menu_name'] = $object->labels['name']; + + foreach ( $nohier_vs_hier_defaults as $key => $value ) + $defaults[$key] = $object->hierarchical ? $value[1] : $value[0]; + + $labels = array_merge( $defaults, $object->labels ); + return (object)$labels; +} + +/** + * Adds submenus for post types. + * + * @access private + * @since 3.1.0 + */ +function _add_post_type_submenus() { + foreach ( get_post_types( array( 'show_ui' => true ) ) as $ptype ) { + $ptype_obj = get_post_type_object( $ptype ); + // Submenus only. + if ( ! $ptype_obj->show_in_menu || $ptype_obj->show_in_menu === true ) + continue; + add_submenu_page( $ptype_obj->show_in_menu, $ptype_obj->labels->name, $ptype_obj->labels->menu_name, $ptype_obj->cap->edit_posts, "edit.php?post_type=$ptype" ); + } +} +add_action( 'admin_menu', '_add_post_type_submenus' ); + +/** + * Register support of certain features for a post type. + * + * All features are directly associated with a functional area of the edit screen, such as the + * editor or a meta box: 'title', 'editor', 'comments', 'revisions', 'trackbacks', 'author', + * 'excerpt', 'page-attributes', 'thumbnail', and 'custom-fields'. + * + * Additionally, the 'revisions' feature dictates whether the post type will store revisions, + * and the 'comments' feature dicates whether the comments count will show on the edit screen. + * + * @since 3.0.0 + * @param string $post_type The post type for which to add the feature + * @param string|array $feature the feature being added, can be an array of feature strings or a single string + */ +function add_post_type_support( $post_type, $feature ) { + global $_wp_post_type_features; + + $features = (array) $feature; + foreach ($features as $feature) { + if ( func_num_args() == 2 ) + $_wp_post_type_features[$post_type][$feature] = true; + else + $_wp_post_type_features[$post_type][$feature] = array_slice( func_get_args(), 2 ); + } +} + +/** + * Remove support for a feature from a post type. + * + * @since 3.0.0 + * @param string $post_type The post type for which to remove the feature + * @param string $feature The feature being removed + */ +function remove_post_type_support( $post_type, $feature ) { + global $_wp_post_type_features; + + if ( !isset($_wp_post_type_features[$post_type]) ) + return; + + if ( isset($_wp_post_type_features[$post_type][$feature]) ) + unset($_wp_post_type_features[$post_type][$feature]); +} + +/** + * Checks a post type's support for a given feature + * + * @since 3.0.0 + * @param string $post_type The post type being checked + * @param string $feature the feature being checked + * @return boolean + */ + +function post_type_supports( $post_type, $feature ) { + global $_wp_post_type_features; + + if ( !isset( $_wp_post_type_features[$post_type][$feature] ) ) + return false; + + // If no args passed then no extra checks need be performed + if ( func_num_args() <= 2 ) + return true; + + // @todo Allow pluggable arg checking + //$args = array_slice( func_get_args(), 2 ); + + return true; +} + +/** + * Updates the post type for the post ID. + * + * The page or post cache will be cleaned for the post ID. + * + * @since 2.5.0 + * + * @uses $wpdb + * + * @param int $post_id Post ID to change post type. Not actually optional. + * @param string $post_type Optional, default is post. Supported values are 'post' or 'page' to + * name a few. + * @return int Amount of rows changed. Should be 1 for success and 0 for failure. + */ +function set_post_type( $post_id = 0, $post_type = 'post' ) { + global $wpdb; + + $post_type = sanitize_post_field('post_type', $post_type, $post_id, 'db'); + $return = $wpdb->update($wpdb->posts, array('post_type' => $post_type), array('ID' => $post_id) ); + + if ( 'page' == $post_type ) + clean_page_cache($post_id); + else + clean_post_cache($post_id); + + return $return; +} + +/** + * Retrieve list of latest posts or posts matching criteria. + * + * The defaults are as follows: + * 'numberposts' - Default is 5. Total number of posts to retrieve. + * 'offset' - Default is 0. See {@link WP_Query::query()} for more. + * 'category' - What category to pull the posts from. + * 'orderby' - Default is 'post_date'. How to order the posts. + * 'order' - Default is 'DESC'. The order to retrieve the posts. + * 'include' - See {@link WP_Query::query()} for more. + * 'exclude' - See {@link WP_Query::query()} for more. + * 'meta_key' - See {@link WP_Query::query()} for more. + * 'meta_value' - See {@link WP_Query::query()} for more. + * 'post_type' - Default is 'post'. Can be 'page', or 'attachment' to name a few. + * 'post_parent' - The parent of the post or post type. + * 'post_status' - Default is 'published'. Post status to retrieve. + * + * @since 1.2.0 + * @uses $wpdb + * @uses WP_Query::query() See for more default arguments and information. + * @link http://codex.wordpress.org/Template_Tags/get_posts + * + * @param array $args Optional. Overrides defaults. + * @return array List of posts. + */ +function get_posts($args = null) { + $defaults = array( + 'numberposts' => 5, 'offset' => 0, + 'category' => 0, 'orderby' => 'post_date', + 'order' => 'DESC', 'include' => array(), + 'exclude' => array(), 'meta_key' => '', + 'meta_value' =>'', 'post_type' => 'post', + 'suppress_filters' => true + ); + + $r = wp_parse_args( $args, $defaults ); + if ( empty( $r['post_status'] ) ) + $r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish'; + if ( ! empty($r['numberposts']) && empty($r['posts_per_page']) ) + $r['posts_per_page'] = $r['numberposts']; + if ( ! empty($r['category']) ) + $r['cat'] = $r['category']; + if ( ! empty($r['include']) ) { + $incposts = wp_parse_id_list( $r['include'] ); + $r['posts_per_page'] = count($incposts); // only the number of posts included + $r['post__in'] = $incposts; + } elseif ( ! empty($r['exclude']) ) + $r['post__not_in'] = wp_parse_id_list( $r['exclude'] ); + + $r['ignore_sticky_posts'] = true; + $r['no_found_rows'] = true; + + $get_posts = new WP_Query; + return $get_posts->query($r); + +} + +// +// Post meta functions +// + +/** + * Add meta data field to a post. + * + * Post meta data is called "Custom Fields" on the Administration Panels. + * + * @since 1.5.0 + * @uses $wpdb + * @link http://codex.wordpress.org/Function_Reference/add_post_meta + * + * @param int $post_id Post ID. + * @param string $meta_key Metadata name. + * @param mixed $meta_value Metadata value. + * @param bool $unique Optional, default is false. Whether the same key should not be added. + * @return bool False for failure. True for success. + */ +function add_post_meta($post_id, $meta_key, $meta_value, $unique = false) { + // make sure meta is added to the post, not a revision + if ( $the_post = wp_is_post_revision($post_id) ) + $post_id = $the_post; + + return add_metadata('post', $post_id, $meta_key, $meta_value, $unique); +} + +/** + * Remove metadata matching criteria from a post. + * + * You can match based on the key, or key and value. Removing based on key and + * value, will keep from removing duplicate metadata with the same key. It also + * allows removing all metadata matching key, if needed. + * + * @since 1.5.0 + * @uses $wpdb + * @link http://codex.wordpress.org/Function_Reference/delete_post_meta + * + * @param int $post_id post ID + * @param string $meta_key Metadata name. + * @param mixed $meta_value Optional. Metadata value. + * @return bool False for failure. True for success. + */ +function delete_post_meta($post_id, $meta_key, $meta_value = '') { + // make sure meta is added to the post, not a revision + if ( $the_post = wp_is_post_revision($post_id) ) + $post_id = $the_post; + + return delete_metadata('post', $post_id, $meta_key, $meta_value); +} + +/** + * Retrieve post meta field for a post. + * + * @since 1.5.0 + * @uses $wpdb + * @link http://codex.wordpress.org/Function_Reference/get_post_meta + * + * @param int $post_id Post ID. + * @param string $key The meta key to retrieve. + * @param bool $single Whether to return a single value. + * @return mixed Will be an array if $single is false. Will be value of meta data field if $single + * is true. + */ +function get_post_meta($post_id, $key, $single = false) { + return get_metadata('post', $post_id, $key, $single); +} + +/** + * Update post meta field based on post ID. + * + * Use the $prev_value parameter to differentiate between meta fields with the + * same key and post ID. + * + * If the meta field for the post does not exist, it will be added. + * + * @since 1.5.0 + * @uses $wpdb + * @link http://codex.wordpress.org/Function_Reference/update_post_meta + * + * @param int $post_id Post ID. + * @param string $meta_key Metadata key. + * @param mixed $meta_value Metadata value. + * @param mixed $prev_value Optional. Previous value to check before removing. + * @return bool False on failure, true if success. + */ +function update_post_meta($post_id, $meta_key, $meta_value, $prev_value = '') { + // make sure meta is added to the post, not a revision + if ( $the_post = wp_is_post_revision($post_id) ) + $post_id = $the_post; + + return update_metadata('post', $post_id, $meta_key, $meta_value, $prev_value); +} + +/** + * Delete everything from post meta matching meta key. + * + * @since 2.3.0 + * @uses $wpdb + * + * @param string $post_meta_key Key to search for when deleting. + * @return bool Whether the post meta key was deleted from the database + */ +function delete_post_meta_by_key($post_meta_key) { + if ( !$post_meta_key ) + return false; + + global $wpdb; + $post_ids = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = %s", $post_meta_key)); + if ( $post_ids ) { + $postmetaids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = %s", $post_meta_key ) ); + $in = implode( ',', array_fill(1, count($postmetaids), '%d')); + do_action( 'delete_postmeta', $postmetaids ); + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_id IN($in)", $postmetaids )); + do_action( 'deleted_postmeta', $postmetaids ); + foreach ( $post_ids as $post_id ) + wp_cache_delete($post_id, 'post_meta'); + return true; + } + return false; +} + +/** + * Retrieve post meta fields, based on post ID. + * + * The post meta fields are retrieved from the cache, so the function is + * optimized to be called more than once. It also applies to the functions, that + * use this function. + * + * @since 1.2.0 + * @link http://codex.wordpress.org/Function_Reference/get_post_custom + * + * @uses $id Current Loop Post ID + * + * @param int $post_id post ID + * @return array + */ +function get_post_custom( $post_id = 0 ) { + $post_id = absint( $post_id ); + + if ( ! $post_id ) + $post_id = get_the_ID(); + + if ( ! wp_cache_get( $post_id, 'post_meta' ) ) + update_postmeta_cache( $post_id ); + + return wp_cache_get( $post_id, 'post_meta' ); +} + +/** + * Retrieve meta field names for a post. + * + * If there are no meta fields, then nothing (null) will be returned. + * + * @since 1.2.0 + * @link http://codex.wordpress.org/Function_Reference/get_post_custom_keys + * + * @param int $post_id post ID + * @return array|null Either array of the keys, or null if keys could not be retrieved. + */ +function get_post_custom_keys( $post_id = 0 ) { + $custom = get_post_custom( $post_id ); + + if ( !is_array($custom) ) + return; + + if ( $keys = array_keys($custom) ) + return $keys; +} + +/** + * Retrieve values for a custom post field. + * + * The parameters must not be considered optional. All of the post meta fields + * will be retrieved and only the meta field key values returned. + * + * @since 1.2.0 + * @link http://codex.wordpress.org/Function_Reference/get_post_custom_values + * + * @param string $key Meta field key. + * @param int $post_id Post ID + * @return array Meta field values. + */ +function get_post_custom_values( $key = '', $post_id = 0 ) { + if ( !$key ) + return null; + + $custom = get_post_custom($post_id); + + return isset($custom[$key]) ? $custom[$key] : null; +} + +/** + * Check if post is sticky. + * + * Sticky posts should remain at the top of The Loop. If the post ID is not + * given, then The Loop ID for the current post will be used. + * + * @since 2.7.0 + * + * @param int $post_id Optional. Post ID. + * @return bool Whether post is sticky. + */ +function is_sticky( $post_id = 0 ) { + $post_id = absint( $post_id ); + + if ( ! $post_id ) + $post_id = get_the_ID(); + + $stickies = get_option( 'sticky_posts' ); + + if ( ! is_array( $stickies ) ) + return false; + + if ( in_array( $post_id, $stickies ) ) + return true; + + return false; +} + +/** + * Sanitize every post field. + * + * If the context is 'raw', then the post object or array will get minimal santization of the int fields. + * + * @since 2.3.0 + * @uses sanitize_post_field() Used to sanitize the fields. + * + * @param object|array $post The Post Object or Array + * @param string $context Optional, default is 'display'. How to sanitize post fields. + * @return object|array The now sanitized Post Object or Array (will be the same type as $post) + */ +function sanitize_post($post, $context = 'display') { + if ( is_object($post) ) { + // Check if post already filtered for this context + if ( isset($post->filter) && $context == $post->filter ) + return $post; + if ( !isset($post->ID) ) + $post->ID = 0; + foreach ( array_keys(get_object_vars($post)) as $field ) + $post->$field = sanitize_post_field($field, $post->$field, $post->ID, $context); + $post->filter = $context; + } else { + // Check if post already filtered for this context + if ( isset($post['filter']) && $context == $post['filter'] ) + return $post; + if ( !isset($post['ID']) ) + $post['ID'] = 0; + foreach ( array_keys($post) as $field ) + $post[$field] = sanitize_post_field($field, $post[$field], $post['ID'], $context); + $post['filter'] = $context; + } + return $post; +} + +/** + * Sanitize post field based on context. + * + * Possible context values are: 'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The + * 'display' context is used by default. 'attribute' and 'js' contexts are treated like 'display' + * when calling filters. + * + * @since 2.3.0 + * @uses apply_filters() Calls 'edit_$field' and '{$field_no_prefix}_edit_pre' passing $value and + * $post_id if $context == 'edit' and field name prefix == 'post_'. + * + * @uses apply_filters() Calls 'edit_post_$field' passing $value and $post_id if $context == 'db'. + * @uses apply_filters() Calls 'pre_$field' passing $value if $context == 'db' and field name prefix == 'post_'. + * @uses apply_filters() Calls '{$field}_pre' passing $value if $context == 'db' and field name prefix != 'post_'. + * + * @uses apply_filters() Calls '$field' passing $value, $post_id and $context if $context == anything + * other than 'raw', 'edit' and 'db' and field name prefix == 'post_'. + * @uses apply_filters() Calls 'post_$field' passing $value if $context == anything other than 'raw', + * 'edit' and 'db' and field name prefix != 'post_'. + * + * @param string $field The Post Object field name. + * @param mixed $value The Post Object value. + * @param int $post_id Post ID. + * @param string $context How to sanitize post fields. Looks for 'raw', 'edit', 'db', 'display', + * 'attribute' and 'js'. + * @return mixed Sanitized value. + */ +function sanitize_post_field($field, $value, $post_id, $context) { + $int_fields = array('ID', 'post_parent', 'menu_order'); + if ( in_array($field, $int_fields) ) + $value = (int) $value; + + // Fields which contain arrays of ints. + $array_int_fields = array( 'ancestors' ); + if ( in_array($field, $array_int_fields) ) { + $value = array_map( 'absint', $value); + return $value; + } + + if ( 'raw' == $context ) + return $value; + + $prefixed = false; + if ( false !== strpos($field, 'post_') ) { + $prefixed = true; + $field_no_prefix = str_replace('post_', '', $field); + } + + if ( 'edit' == $context ) { + $format_to_edit = array('post_content', 'post_excerpt', 'post_title', 'post_password'); + + if ( $prefixed ) { + $value = apply_filters("edit_{$field}", $value, $post_id); + // Old school + $value = apply_filters("{$field_no_prefix}_edit_pre", $value, $post_id); + } else { + $value = apply_filters("edit_post_{$field}", $value, $post_id); + } + + if ( in_array($field, $format_to_edit) ) { + if ( 'post_content' == $field ) + $value = format_to_edit($value, user_can_richedit()); + else + $value = format_to_edit($value); + } else { + $value = esc_attr($value); + } + } else if ( 'db' == $context ) { + if ( $prefixed ) { + $value = apply_filters("pre_{$field}", $value); + $value = apply_filters("{$field_no_prefix}_save_pre", $value); + } else { + $value = apply_filters("pre_post_{$field}", $value); + $value = apply_filters("{$field}_pre", $value); + } + } else { + // Use display filters by default. + if ( $prefixed ) + $value = apply_filters($field, $value, $post_id, $context); + else + $value = apply_filters("post_{$field}", $value, $post_id, $context); + } + + if ( 'attribute' == $context ) + $value = esc_attr($value); + else if ( 'js' == $context ) + $value = esc_js($value); + + return $value; +} + +/** + * Make a post sticky. + * + * Sticky posts should be displayed at the top of the front page. + * + * @since 2.7.0 + * + * @param int $post_id Post ID. + */ +function stick_post($post_id) { + $stickies = get_option('sticky_posts'); + + if ( !is_array($stickies) ) + $stickies = array($post_id); + + if ( ! in_array($post_id, $stickies) ) + $stickies[] = $post_id; + + update_option('sticky_posts', $stickies); +} + +/** + * Unstick a post. + * + * Sticky posts should be displayed at the top of the front page. + * + * @since 2.7.0 + * + * @param int $post_id Post ID. + */ +function unstick_post($post_id) { + $stickies = get_option('sticky_posts'); + + if ( !is_array($stickies) ) + return; + + if ( ! in_array($post_id, $stickies) ) + return; + + $offset = array_search($post_id, $stickies); + if ( false === $offset ) + return; + + array_splice($stickies, $offset, 1); + + update_option('sticky_posts', $stickies); +} + +/** + * Count number of posts of a post type and is user has permissions to view. + * + * This function provides an efficient method of finding the amount of post's + * type a blog has. Another method is to count the amount of items in + * get_posts(), but that method has a lot of overhead with doing so. Therefore, + * when developing for 2.5+, use this function instead. + * + * The $perm parameter checks for 'readable' value and if the user can read + * private posts, it will display that for the user that is signed in. + * + * @since 2.5.0 + * @link http://codex.wordpress.org/Template_Tags/wp_count_posts + * + * @param string $type Optional. Post type to retrieve count + * @param string $perm Optional. 'readable' or empty. + * @return object Number of posts for each status + */ +function wp_count_posts( $type = 'post', $perm = '' ) { + global $wpdb; + + $user = wp_get_current_user(); + + $cache_key = $type; + + $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s"; + if ( 'readable' == $perm && is_user_logged_in() ) { + $post_type_object = get_post_type_object($type); + if ( !current_user_can( $post_type_object->cap->read_private_posts ) ) { + $cache_key .= '_' . $perm . '_' . $user->ID; + $query .= " AND (post_status != 'private' OR ( post_author = '$user->ID' AND post_status = 'private' ))"; + } + } + $query .= ' GROUP BY post_status'; + + $count = wp_cache_get($cache_key, 'counts'); + if ( false !== $count ) + return $count; + + $count = $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A ); + + $stats = array(); + foreach ( get_post_stati() as $state ) + $stats[$state] = 0; + + foreach ( (array) $count as $row ) + $stats[$row['post_status']] = $row['num_posts']; + + $stats = (object) $stats; + wp_cache_set($cache_key, $stats, 'counts'); + + return $stats; +} + + +/** + * Count number of attachments for the mime type(s). + * + * If you set the optional mime_type parameter, then an array will still be + * returned, but will only have the item you are looking for. It does not give + * you the number of attachments that are children of a post. You can get that + * by counting the number of children that post has. + * + * @since 2.5.0 + * + * @param string|array $mime_type Optional. Array or comma-separated list of MIME patterns. + * @return array Number of posts for each mime type. + */ +function wp_count_attachments( $mime_type = '' ) { + global $wpdb; + + $and = wp_post_mime_type_where( $mime_type ); + $count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' $and GROUP BY post_mime_type", ARRAY_A ); + + $stats = array( ); + foreach( (array) $count as $row ) { + $stats[$row['post_mime_type']] = $row['num_posts']; + } + $stats['trash'] = $wpdb->get_var( "SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'trash' $and"); + + return (object) $stats; +} + +/** + * Check a MIME-Type against a list. + * + * If the wildcard_mime_types parameter is a string, it must be comma separated + * list. If the real_mime_types is a string, it is also comma separated to + * create the list. + * + * @since 2.5.0 + * + * @param string|array $wildcard_mime_types e.g. audio/mpeg or image (same as image/*) or + * flash (same as *flash*). + * @param string|array $real_mime_types post_mime_type values + * @return array array(wildcard=>array(real types)) + */ +function wp_match_mime_types($wildcard_mime_types, $real_mime_types) { + $matches = array(); + if ( is_string($wildcard_mime_types) ) + $wildcard_mime_types = array_map('trim', explode(',', $wildcard_mime_types)); + if ( is_string($real_mime_types) ) + $real_mime_types = array_map('trim', explode(',', $real_mime_types)); + $wild = '[-._a-z0-9]*'; + foreach ( (array) $wildcard_mime_types as $type ) { + $type = str_replace('*', $wild, $type); + $patternses[1][$type] = "^$type$"; + if ( false === strpos($type, '/') ) { + $patternses[2][$type] = "^$type/"; + $patternses[3][$type] = $type; + } + } + asort($patternses); + foreach ( $patternses as $patterns ) + foreach ( $patterns as $type => $pattern ) + foreach ( (array) $real_mime_types as $real ) + if ( preg_match("#$pattern#", $real) && ( empty($matches[$type]) || false === array_search($real, $matches[$type]) ) ) + $matches[$type][] = $real; + return $matches; +} + +/** + * Convert MIME types into SQL. + * + * @since 2.5.0 + * + * @param string|array $post_mime_types List of mime types or comma separated string of mime types. + * @param string $table_alias Optional. Specify a table alias, if needed. + * @return string The SQL AND clause for mime searching. + */ +function wp_post_mime_type_where($post_mime_types, $table_alias = '') { + $where = ''; + $wildcards = array('', '%', '%/%'); + if ( is_string($post_mime_types) ) + $post_mime_types = array_map('trim', explode(',', $post_mime_types)); + foreach ( (array) $post_mime_types as $mime_type ) { + $mime_type = preg_replace('/\s/', '', $mime_type); + $slashpos = strpos($mime_type, '/'); + if ( false !== $slashpos ) { + $mime_group = preg_replace('/[^-*.a-zA-Z0-9]/', '', substr($mime_type, 0, $slashpos)); + $mime_subgroup = preg_replace('/[^-*.+a-zA-Z0-9]/', '', substr($mime_type, $slashpos + 1)); + if ( empty($mime_subgroup) ) + $mime_subgroup = '*'; + else + $mime_subgroup = str_replace('/', '', $mime_subgroup); + $mime_pattern = "$mime_group/$mime_subgroup"; + } else { + $mime_pattern = preg_replace('/[^-*.a-zA-Z0-9]/', '', $mime_type); + if ( false === strpos($mime_pattern, '*') ) + $mime_pattern .= '/*'; + } + + $mime_pattern = preg_replace('/\*+/', '%', $mime_pattern); + + if ( in_array( $mime_type, $wildcards ) ) + return ''; + + if ( false !== strpos($mime_pattern, '%') ) + $wheres[] = empty($table_alias) ? "post_mime_type LIKE '$mime_pattern'" : "$table_alias.post_mime_type LIKE '$mime_pattern'"; + else + $wheres[] = empty($table_alias) ? "post_mime_type = '$mime_pattern'" : "$table_alias.post_mime_type = '$mime_pattern'"; + } + if ( !empty($wheres) ) + $where = ' AND (' . join(' OR ', $wheres) . ') '; + return $where; +} + +/** + * Trashes or deletes a post or page. + * + * When the post and page is permanently deleted, everything that is tied to it is deleted also. + * This includes comments, post meta fields, and terms associated with the post. + * + * The post or page is moved to trash instead of permanently deleted unless trash is + * disabled, item is already in the trash, or $force_delete is true. + * + * @since 1.0.0 + * @uses do_action() on 'delete_post' before deletion unless post type is 'attachment'. + * @uses do_action() on 'deleted_post' after deletion unless post type is 'attachment'. + * @uses wp_delete_attachment() if post type is 'attachment'. + * @uses wp_trash_post() if item should be trashed. + * + * @param int $postid Post ID. + * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false. + * @return mixed False on failure + */ +function wp_delete_post( $postid = 0, $force_delete = false ) { + global $wpdb, $wp_rewrite; + + if ( !$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d", $postid)) ) + return $post; + + if ( !$force_delete && ( $post->post_type == 'post' || $post->post_type == 'page') && get_post_status( $postid ) != 'trash' && EMPTY_TRASH_DAYS ) + return wp_trash_post($postid); + + if ( $post->post_type == 'attachment' ) + return wp_delete_attachment( $postid, $force_delete ); + + do_action('delete_post', $postid); + + delete_post_meta($postid,'_wp_trash_meta_status'); + delete_post_meta($postid,'_wp_trash_meta_time'); + + wp_delete_object_term_relationships($postid, get_object_taxonomies($post->post_type)); + + $parent_data = array( 'post_parent' => $post->post_parent ); + $parent_where = array( 'post_parent' => $postid ); + + if ( 'page' == $post->post_type) { + // if the page is defined in option page_on_front or post_for_posts, + // adjust the corresponding options + if ( get_option('page_on_front') == $postid ) { + update_option('show_on_front', 'posts'); + delete_option('page_on_front'); + } + if ( get_option('page_for_posts') == $postid ) { + delete_option('page_for_posts'); + } + + // Point children of this page to its parent, also clean the cache of affected children + $children_query = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type='page'", $postid); + $children = $wpdb->get_results($children_query); + + $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'page' ) ); + } else { + unstick_post($postid); + } + + // Do raw query. wp_get_post_revisions() is filtered + $revision_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'revision'", $postid ) ); + // Use wp_delete_post (via wp_delete_post_revision) again. Ensures any meta/misplaced data gets cleaned up. + foreach ( $revision_ids as $revision_id ) + wp_delete_post_revision( $revision_id ); + + // Point all attachments to this post up one level + $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'attachment' ) ); + + $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $postid )); + if ( ! empty($comment_ids) ) { + do_action( 'delete_comment', $comment_ids ); + foreach ( $comment_ids as $comment_id ) + wp_delete_comment( $comment_id, true ); + do_action( 'deleted_comment', $comment_ids ); + } + + $post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $postid )); + if ( !empty($post_meta_ids) ) { + do_action( 'delete_postmeta', $post_meta_ids ); + $in_post_meta_ids = "'" . implode("', '", $post_meta_ids) . "'"; + $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_id IN($in_post_meta_ids)" ); + do_action( 'deleted_postmeta', $post_meta_ids ); + } + + do_action( 'delete_post', $postid ); + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $postid )); + do_action( 'deleted_post', $postid ); + + if ( 'page' == $post->post_type ) { + clean_page_cache($postid); + + foreach ( (array) $children as $child ) + clean_page_cache($child->ID); + + $wp_rewrite->flush_rules(false); + } else { + clean_post_cache($postid); + } + + wp_clear_scheduled_hook('publish_future_post', array( $postid ) ); + + do_action('deleted_post', $postid); + + return $post; +} + +/** + * Moves a post or page to the Trash + * + * If trash is disabled, the post or page is permanently deleted. + * + * @since 2.9.0 + * @uses do_action() on 'trash_post' before trashing + * @uses do_action() on 'trashed_post' after trashing + * @uses wp_delete_post() if trash is disabled + * + * @param int $post_id Post ID. + * @return mixed False on failure + */ +function wp_trash_post($post_id = 0) { + if ( !EMPTY_TRASH_DAYS ) + return wp_delete_post($post_id, true); + + if ( !$post = wp_get_single_post($post_id, ARRAY_A) ) + return $post; + + if ( $post['post_status'] == 'trash' ) + return false; + + do_action('trash_post', $post_id); + + add_post_meta($post_id,'_wp_trash_meta_status', $post['post_status']); + add_post_meta($post_id,'_wp_trash_meta_time', time()); + + $post['post_status'] = 'trash'; + wp_insert_post($post); + + wp_trash_post_comments($post_id); + + do_action('trashed_post', $post_id); + + return $post; +} + +/** + * Restores a post or page from the Trash + * + * @since 2.9.0 + * @uses do_action() on 'untrash_post' before undeletion + * @uses do_action() on 'untrashed_post' after undeletion + * + * @param int $post_id Post ID. + * @return mixed False on failure + */ +function wp_untrash_post($post_id = 0) { + if ( !$post = wp_get_single_post($post_id, ARRAY_A) ) + return $post; + + if ( $post['post_status'] != 'trash' ) + return false; + + do_action('untrash_post', $post_id); + + $post_status = get_post_meta($post_id, '_wp_trash_meta_status', true); + + $post['post_status'] = $post_status; + + delete_post_meta($post_id, '_wp_trash_meta_status'); + delete_post_meta($post_id, '_wp_trash_meta_time'); + + wp_insert_post($post); + + wp_untrash_post_comments($post_id); + + do_action('untrashed_post', $post_id); + + return $post; +} + +/** + * Moves comments for a post to the trash + * + * @since 2.9.0 + * @uses do_action() on 'trash_post_comments' before trashing + * @uses do_action() on 'trashed_post_comments' after trashing + * + * @param int $post Post ID or object. + * @return mixed False on failure + */ +function wp_trash_post_comments($post = null) { + global $wpdb; + + $post = get_post($post); + if ( empty($post) ) + return; + + $post_id = $post->ID; + + do_action('trash_post_comments', $post_id); + + $comments = $wpdb->get_results( $wpdb->prepare("SELECT comment_ID, comment_approved FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id) ); + if ( empty($comments) ) + return; + + // Cache current status for each comment + $statuses = array(); + foreach ( $comments as $comment ) + $statuses[$comment->comment_ID] = $comment->comment_approved; + add_post_meta($post_id, '_wp_trash_meta_comments_status', $statuses); + + // Set status for all comments to post-trashed + $result = $wpdb->update($wpdb->comments, array('comment_approved' => 'post-trashed'), array('comment_post_ID' => $post_id)); + + clean_comment_cache( array_keys($statuses) ); + + do_action('trashed_post_comments', $post_id, $statuses); + + return $result; +} + +/** + * Restore comments for a post from the trash + * + * @since 2.9.0 + * @uses do_action() on 'untrash_post_comments' before trashing + * @uses do_action() on 'untrashed_post_comments' after trashing + * + * @param int $post Post ID or object. + * @return mixed False on failure + */ +function wp_untrash_post_comments($post = null) { + global $wpdb; + + $post = get_post($post); + if ( empty($post) ) + return; + + $post_id = $post->ID; + + $statuses = get_post_meta($post_id, '_wp_trash_meta_comments_status', true); + + if ( empty($statuses) ) + return true; + + do_action('untrash_post_comments', $post_id); + + // Restore each comment to its original status + $group_by_status = array(); + foreach ( $statuses as $comment_id => $comment_status ) + $group_by_status[$comment_status][] = $comment_id; + + foreach ( $group_by_status as $status => $comments ) { + // Sanity check. This shouldn't happen. + if ( 'post-trashed' == $status ) + $status = '0'; + $comments_in = implode( "', '", $comments ); + $wpdb->query( "UPDATE $wpdb->comments SET comment_approved = '$status' WHERE comment_ID IN ('" . $comments_in . "')" ); + } + + clean_comment_cache( array_keys($statuses) ); + + delete_post_meta($post_id, '_wp_trash_meta_comments_status'); + + do_action('untrashed_post_comments', $post_id); +} + +/** + * Retrieve the list of categories for a post. + * + * Compatibility layer for themes and plugins. Also an easy layer of abstraction + * away from the complexity of the taxonomy layer. + * + * @since 2.1.0 + * + * @uses wp_get_object_terms() Retrieves the categories. Args details can be found here. + * + * @param int $post_id Optional. The Post ID. + * @param array $args Optional. Overwrite the defaults. + * @return array + */ +function wp_get_post_categories( $post_id = 0, $args = array() ) { + $post_id = (int) $post_id; + + $defaults = array('fields' => 'ids'); + $args = wp_parse_args( $args, $defaults ); + + $cats = wp_get_object_terms($post_id, 'category', $args); + return $cats; +} + +/** + * Retrieve the tags for a post. + * + * There is only one default for this function, called 'fields' and by default + * is set to 'all'. There are other defaults that can be overridden in + * {@link wp_get_object_terms()}. + * + * @package WordPress + * @subpackage Post + * @since 2.3.0 + * + * @uses wp_get_object_terms() Gets the tags for returning. Args can be found here + * + * @param int $post_id Optional. The Post ID + * @param array $args Optional. Overwrite the defaults + * @return array List of post tags. + */ +function wp_get_post_tags( $post_id = 0, $args = array() ) { + return wp_get_post_terms( $post_id, 'post_tag', $args); +} + +/** + * Retrieve the terms for a post. + * + * There is only one default for this function, called 'fields' and by default + * is set to 'all'. There are other defaults that can be overridden in + * {@link wp_get_object_terms()}. + * + * @package WordPress + * @subpackage Post + * @since 2.8.0 + * + * @uses wp_get_object_terms() Gets the tags for returning. Args can be found here + * + * @param int $post_id Optional. The Post ID + * @param string $taxonomy The taxonomy for which to retrieve terms. Defaults to post_tag. + * @param array $args Optional. Overwrite the defaults + * @return array List of post tags. + */ +function wp_get_post_terms( $post_id = 0, $taxonomy = 'post_tag', $args = array() ) { + $post_id = (int) $post_id; + + $defaults = array('fields' => 'all'); + $args = wp_parse_args( $args, $defaults ); + + $tags = wp_get_object_terms($post_id, $taxonomy, $args); + + return $tags; +} + +/** + * Retrieve number of recent posts. + * + * @since 1.0.0 + * @uses wp_parse_args() + * @uses get_posts() + * + * @param string $deprecated Deprecated. + * @param array $args Optional. Overrides defaults. + * @param string $output Optional. + * @return unknown. + */ +function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) { + + if ( is_numeric( $args ) ) { + _deprecated_argument( __FUNCTION__, '3.1', __( 'Passing an integer number of posts is deprecated. Pass an array of arguments instead.' ) ); + $args = array( 'numberposts' => absint( $args ) ); + } + + // Set default arguments + $defaults = array( + 'numberposts' => 10, 'offset' => 0, + 'category' => 0, 'orderby' => 'post_date', + 'order' => 'DESC', 'include' => '', + 'exclude' => '', 'meta_key' => '', + 'meta_value' =>'', 'post_type' => 'post', 'post_status' => 'draft, publish, future, pending, private', + 'suppress_filters' => true + ); + + $r = wp_parse_args( $args, $defaults ); + + $results = get_posts( $r ); + + // Backward compatibility. Prior to 3.1 expected posts to be returned in array + if ( ARRAY_A == $output ){ + foreach( $results as $key => $result ) { + $results[$key] = get_object_vars( $result ); + } + return $results ? $results : array(); + } + + return $results ? $results : false; + +} + +/** + * Retrieve a single post, based on post ID. + * + * Has categories in 'post_category' property or key. Has tags in 'tags_input' + * property or key. + * + * @since 1.0.0 + * + * @param int $postid Post ID. + * @param string $mode How to return result, either OBJECT, ARRAY_N, or ARRAY_A. + * @return object|array Post object or array holding post contents and information + */ +function wp_get_single_post($postid = 0, $mode = OBJECT) { + $postid = (int) $postid; + + $post = get_post($postid, $mode); + + if ( + ( OBJECT == $mode && empty( $post->ID ) ) || + ( OBJECT != $mode && empty( $post['ID'] ) ) + ) + return ( OBJECT == $mode ? null : array() ); + + // Set categories and tags + if ( $mode == OBJECT ) { + $post->post_category = array(); + if ( is_object_in_taxonomy($post->post_type, 'category') ) + $post->post_category = wp_get_post_categories($postid); + $post->tags_input = array(); + if ( is_object_in_taxonomy($post->post_type, 'post_tag') ) + $post->tags_input = wp_get_post_tags($postid, array('fields' => 'names')); + } else { + $post['post_category'] = array(); + if ( is_object_in_taxonomy($post['post_type'], 'category') ) + $post['post_category'] = wp_get_post_categories($postid); + $post['tags_input'] = array(); + if ( is_object_in_taxonomy($post['post_type'], 'post_tag') ) + $post['tags_input'] = wp_get_post_tags($postid, array('fields' => 'names')); + } + + return $post; +} + +/** + * Insert a post. + * + * If the $postarr parameter has 'ID' set to a value, then post will be updated. + * + * You can set the post date manually, but setting the values for 'post_date' + * and 'post_date_gmt' keys. You can close the comments or open the comments by + * setting the value for 'comment_status' key. + * + * The defaults for the parameter $postarr are: + * 'post_status' - Default is 'draft'. + * 'post_type' - Default is 'post'. + * 'post_author' - Default is current user ID ($user_ID). The ID of the user who added the post. + * 'ping_status' - Default is the value in 'default_ping_status' option. + * Whether the attachment can accept pings. + * 'post_parent' - Default is 0. Set this for the post it belongs to, if any. + * 'menu_order' - Default is 0. The order it is displayed. + * 'to_ping' - Whether to ping. + * 'pinged' - Default is empty string. + * 'post_password' - Default is empty string. The password to access the attachment. + * 'guid' - Global Unique ID for referencing the attachment. + * 'post_content_filtered' - Post content filtered. + * 'post_excerpt' - Post excerpt. + * + * @since 1.0.0 + * @uses $wpdb + * @uses $wp_rewrite + * @uses $user_ID + * @uses do_action() Calls 'pre_post_update' on post ID if this is an update. + * @uses do_action() Calls 'edit_post' action on post ID and post data if this is an update. + * @uses do_action() Calls 'save_post' and 'wp_insert_post' on post id and post data just before returning. + * @uses apply_filters() Calls 'wp_insert_post_data' passing $data, $postarr prior to database update or insert. + * @uses wp_transition_post_status() + * + * @param array $postarr Elements that make up post to insert. + * @param bool $wp_error Optional. Allow return of WP_Error on failure. + * @return int|WP_Error The value 0 or WP_Error on failure. The post ID on success. + */ +function wp_insert_post($postarr, $wp_error = false) { + global $wpdb, $wp_rewrite, $user_ID; + + $defaults = array('post_status' => 'draft', 'post_type' => 'post', 'post_author' => $user_ID, + 'ping_status' => get_option('default_ping_status'), 'post_parent' => 0, + 'menu_order' => 0, 'to_ping' => '', 'pinged' => '', 'post_password' => '', + 'guid' => '', 'post_content_filtered' => '', 'post_excerpt' => '', 'import_id' => 0, + 'post_content' => '', 'post_title' => ''); + + $postarr = wp_parse_args($postarr, $defaults); + $postarr = sanitize_post($postarr, 'db'); + + // export array as variables + extract($postarr, EXTR_SKIP); + + // Are we updating or creating? + $update = false; + if ( !empty($ID) ) { + $update = true; + $previous_status = get_post_field('post_status', $ID); + } else { + $previous_status = 'new'; + } + + if ( ('' == $post_content) && ('' == $post_title) && ('' == $post_excerpt) && ('attachment' != $post_type) ) { + if ( $wp_error ) + return new WP_Error('empty_content', __('Content, title, and excerpt are empty.')); + else + return 0; + } + + if ( empty($post_type) ) + $post_type = 'post'; + + if ( empty($post_status) ) + $post_status = 'draft'; + + if ( !empty($post_category) ) + $post_category = array_filter($post_category); // Filter out empty terms + + // Make sure we set a valid category. + if ( empty($post_category) || 0 == count($post_category) || !is_array($post_category) ) { + // 'post' requires at least one category. + if ( 'post' == $post_type && 'auto-draft' != $post_status ) + $post_category = array( get_option('default_category') ); + else + $post_category = array(); + } + + if ( empty($post_author) ) + $post_author = $user_ID; + + $post_ID = 0; + + // Get the post ID and GUID + if ( $update ) { + $post_ID = (int) $ID; + $guid = get_post_field( 'guid', $post_ID ); + $post_before = get_post($post_ID); + } + + // Don't allow contributors to set to set the post slug for pending review posts + if ( 'pending' == $post_status && !current_user_can( 'publish_posts' ) ) + $post_name = ''; + + // Create a valid post name. Drafts and pending posts are allowed to have an empty + // post name. + if ( empty($post_name) ) { + if ( !in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) + $post_name = sanitize_title($post_title); + else + $post_name = ''; + } else { + $post_name = sanitize_title($post_name); + } + + // If the post date is empty (due to having been new or a draft) and status is not 'draft' or 'pending', set date to now + if ( empty($post_date) || '0000-00-00 00:00:00' == $post_date ) + $post_date = current_time('mysql'); + + if ( empty($post_date_gmt) || '0000-00-00 00:00:00' == $post_date_gmt ) { + if ( !in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) + $post_date_gmt = get_gmt_from_date($post_date); + else + $post_date_gmt = '0000-00-00 00:00:00'; + } + + if ( $update || '0000-00-00 00:00:00' == $post_date ) { + $post_modified = current_time( 'mysql' ); + $post_modified_gmt = current_time( 'mysql', 1 ); + } else { + $post_modified = $post_date; + $post_modified_gmt = $post_date_gmt; + } + + if ( 'publish' == $post_status ) { + $now = gmdate('Y-m-d H:i:59'); + if ( mysql2date('U', $post_date_gmt, false) > mysql2date('U', $now, false) ) + $post_status = 'future'; + } elseif( 'future' == $post_status ) { + $now = gmdate('Y-m-d H:i:59'); + if ( mysql2date('U', $post_date_gmt, false) <= mysql2date('U', $now, false) ) + $post_status = 'publish'; + } + + if ( empty($comment_status) ) { + if ( $update ) + $comment_status = 'closed'; + else + $comment_status = get_option('default_comment_status'); + } + if ( empty($ping_status) ) + $ping_status = get_option('default_ping_status'); + + if ( isset($to_ping) ) + $to_ping = preg_replace('|\s+|', "\n", $to_ping); + else + $to_ping = ''; + + if ( ! isset($pinged) ) + $pinged = ''; + + if ( isset($post_parent) ) + $post_parent = (int) $post_parent; + else + $post_parent = 0; + + // Check the post_parent to see if it will cause a hierarchy loop + $post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, compact( array_keys( $postarr ) ), $postarr ); + + if ( isset($menu_order) ) + $menu_order = (int) $menu_order; + else + $menu_order = 0; + + if ( !isset($post_password) || 'private' == $post_status ) + $post_password = ''; + + $post_name = wp_unique_post_slug($post_name, $post_ID, $post_status, $post_type, $post_parent); + + // expected_slashed (everything!) + $data = compact( array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'guid' ) ); + $data = apply_filters('wp_insert_post_data', $data, $postarr); + $data = stripslashes_deep( $data ); + $where = array( 'ID' => $post_ID ); + + if ( $update ) { + do_action( 'pre_post_update', $post_ID ); + if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) { + if ( $wp_error ) + return new WP_Error('db_update_error', __('Could not update post in the database'), $wpdb->last_error); + else + return 0; + } + } else { + if ( isset($post_mime_type) ) + $data['post_mime_type'] = stripslashes( $post_mime_type ); // This isn't in the update + // If there is a suggested ID, use it if not already present + if ( !empty($import_id) ) { + $import_id = (int) $import_id; + if ( ! $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id) ) ) { + $data['ID'] = $import_id; + } + } + if ( false === $wpdb->insert( $wpdb->posts, $data ) ) { + if ( $wp_error ) + return new WP_Error('db_insert_error', __('Could not insert post into the database'), $wpdb->last_error); + else + return 0; + } + $post_ID = (int) $wpdb->insert_id; + + // use the newly generated $post_ID + $where = array( 'ID' => $post_ID ); + } + + if ( empty($data['post_name']) && !in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) { + $data['post_name'] = sanitize_title($data['post_title'], $post_ID); + $wpdb->update( $wpdb->posts, array( 'post_name' => $data['post_name'] ), $where ); + } + + if ( is_object_in_taxonomy($post_type, 'category') ) + wp_set_post_categories( $post_ID, $post_category ); + + if ( isset( $tags_input ) && is_object_in_taxonomy($post_type, 'post_tag') ) + wp_set_post_tags( $post_ID, $tags_input ); + + // new-style support for all custom taxonomies + if ( !empty($tax_input) ) { + foreach ( $tax_input as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + wp_set_post_terms( $post_ID, $tags, $taxonomy ); + } + } + + $current_guid = get_post_field( 'guid', $post_ID ); + + if ( 'page' == $data['post_type'] ) + clean_page_cache($post_ID); + else + clean_post_cache($post_ID); + + // Set GUID + if ( !$update && '' == $current_guid ) + $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where ); + + $post = get_post($post_ID); + + if ( !empty($page_template) && 'page' == $data['post_type'] ) { + $post->page_template = $page_template; + $page_templates = get_page_templates(); + if ( 'default' != $page_template && !in_array($page_template, $page_templates) ) { + if ( $wp_error ) + return new WP_Error('invalid_page_template', __('The page template is invalid.')); + else + return 0; + } + update_post_meta($post_ID, '_wp_page_template', $page_template); + } + + wp_transition_post_status($data['post_status'], $previous_status, $post); + + if ( $update ) { + do_action('edit_post', $post_ID, $post); + $post_after = get_post($post_ID); + do_action( 'post_updated', $post_ID, $post_after, $post_before); + } + + do_action('save_post', $post_ID, $post); + do_action('wp_insert_post', $post_ID, $post); + + return $post_ID; +} + +/** + * Update a post with new post data. + * + * The date does not have to be set for drafts. You can set the date and it will + * not be overridden. + * + * @since 1.0.0 + * + * @param array|object $postarr Post data. Arrays are expected to be escaped, objects are not. + * @return int 0 on failure, Post ID on success. + */ +function wp_update_post($postarr = array()) { + if ( is_object($postarr) ) { + // non-escaped post was passed + $postarr = get_object_vars($postarr); + $postarr = add_magic_quotes($postarr); + } + + // First, get all of the original fields + $post = wp_get_single_post($postarr['ID'], ARRAY_A); + + // Escape data pulled from DB. + $post = add_magic_quotes($post); + + // Passed post category list overwrites existing category list if not empty. + if ( isset($postarr['post_category']) && is_array($postarr['post_category']) + && 0 != count($postarr['post_category']) ) + $post_cats = $postarr['post_category']; + else + $post_cats = $post['post_category']; + + // Drafts shouldn't be assigned a date unless explicitly done so by the user + if ( isset( $post['post_status'] ) && in_array($post['post_status'], array('draft', 'pending', 'auto-draft')) && empty($postarr['edit_date']) && + ('0000-00-00 00:00:00' == $post['post_date_gmt']) ) + $clear_date = true; + else + $clear_date = false; + + // Merge old and new fields with new fields overwriting old ones. + $postarr = array_merge($post, $postarr); + $postarr['post_category'] = $post_cats; + if ( $clear_date ) { + $postarr['post_date'] = current_time('mysql'); + $postarr['post_date_gmt'] = ''; + } + + if ($postarr['post_type'] == 'attachment') + return wp_insert_attachment($postarr); + + return wp_insert_post($postarr); +} + +/** + * Publish a post by transitioning the post status. + * + * @since 2.1.0 + * @uses $wpdb + * @uses do_action() Calls 'edit_post', 'save_post', and 'wp_insert_post' on post_id and post data. + * + * @param int $post_id Post ID. + * @return null + */ +function wp_publish_post($post_id) { + global $wpdb; + + $post = get_post($post_id); + + if ( empty($post) ) + return; + + if ( 'publish' == $post->post_status ) + return; + + $wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post_id ) ); + + $old_status = $post->post_status; + $post->post_status = 'publish'; + wp_transition_post_status('publish', $old_status, $post); + + // Update counts for the post's terms. + foreach ( (array) get_object_taxonomies('post') as $taxonomy ) { + $tt_ids = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'tt_ids')); + wp_update_term_count($tt_ids, $taxonomy); + } + + do_action('edit_post', $post_id, $post); + do_action('save_post', $post_id, $post); + do_action('wp_insert_post', $post_id, $post); +} + +/** + * Publish future post and make sure post ID has future post status. + * + * Invoked by cron 'publish_future_post' event. This safeguard prevents cron + * from publishing drafts, etc. + * + * @since 2.5.0 + * + * @param int $post_id Post ID. + * @return null Nothing is returned. Which can mean that no action is required or post was published. + */ +function check_and_publish_future_post($post_id) { + + $post = get_post($post_id); + + if ( empty($post) ) + return; + + if ( 'future' != $post->post_status ) + return; + + $time = strtotime( $post->post_date_gmt . ' GMT' ); + + if ( $time > time() ) { // Uh oh, someone jumped the gun! + wp_clear_scheduled_hook( 'publish_future_post', array( $post_id ) ); // clear anything else in the system + wp_schedule_single_event( $time, 'publish_future_post', array( $post_id ) ); + return; + } + + return wp_publish_post($post_id); +} + + +/** + * Computes a unique slug for the post, when given the desired slug and some post details. + * + * @since 2.8.0 + * + * @global wpdb $wpdb + * @global WP_Rewrite $wp_rewrite + * @param string $slug the desired slug (post_name) + * @param integer $post_ID + * @param string $post_status no uniqueness checks are made if the post is still draft or pending + * @param string $post_type + * @param integer $post_parent + * @return string unique slug for the post, based on $post_name (with a -1, -2, etc. suffix) + */ +function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent ) { + if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) + return $slug; + + global $wpdb, $wp_rewrite; + + $feeds = $wp_rewrite->feeds; + if ( ! is_array( $feeds ) ) + $feeds = array(); + + $hierarchical_post_types = get_post_types( array('hierarchical' => true) ); + if ( 'attachment' == $post_type ) { + // Attachment slugs must be unique across all types. + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1"; + $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) ); + + if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) { + $suffix = 2; + do { + $alt_post_name = substr ($slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"; + $post_name_check = $wpdb->get_var( $wpdb->prepare($check_sql, $alt_post_name, $post_ID ) ); + $suffix++; + } while ( $post_name_check ); + $slug = $alt_post_name; + } + } elseif ( in_array( $post_type, $hierarchical_post_types ) ) { + // Page slugs must be unique within their own trees. Pages are in a separate + // namespace than posts so page slugs are allowed to overlap post slugs. + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d LIMIT 1"; + $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID, $post_parent ) ); + + if ( $post_name_check || in_array( $slug, $feeds ) || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug ) || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) { + $suffix = 2; + do { + $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"; + $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_ID, $post_parent ) ); + $suffix++; + } while ( $post_name_check ); + $slug = $alt_post_name; + } + } else { + // Post slugs must be unique across all posts. + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1"; + $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) ); + + if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) { + $suffix = 2; + do { + $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"; + $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) ); + $suffix++; + } while ( $post_name_check ); + $slug = $alt_post_name; + } + } + + return $slug; +} + +/** + * Adds tags to a post. + * + * @uses wp_set_post_tags() Same first two parameters, but the last parameter is always set to true. + * + * @package WordPress + * @subpackage Post + * @since 2.3.0 + * + * @param int $post_id Post ID + * @param string $tags The tags to set for the post, separated by commas. + * @return bool|null Will return false if $post_id is not an integer or is 0. Will return null otherwise + */ +function wp_add_post_tags($post_id = 0, $tags = '') { + return wp_set_post_tags($post_id, $tags, true); +} + + +/** + * Set the tags for a post. + * + * @since 2.3.0 + * @uses wp_set_object_terms() Sets the tags for the post. + * + * @param int $post_id Post ID. + * @param string $tags The tags to set for the post, separated by commas. + * @param bool $append If true, don't delete existing tags, just add on. If false, replace the tags with the new tags. + * @return mixed Array of affected term IDs. WP_Error or false on failure. + */ +function wp_set_post_tags( $post_id = 0, $tags = '', $append = false ) { + return wp_set_post_terms( $post_id, $tags, 'post_tag', $append); +} + +/** + * Set the terms for a post. + * + * @since 2.8.0 + * @uses wp_set_object_terms() Sets the tags for the post. + * + * @param int $post_id Post ID. + * @param string $tags The tags to set for the post, separated by commas. + * @param bool $append If true, don't delete existing tags, just add on. If false, replace the tags with the new tags. + * @return mixed Array of affected term IDs. WP_Error or false on failure. + */ +function wp_set_post_terms( $post_id = 0, $tags = '', $taxonomy = 'post_tag', $append = false ) { + $post_id = (int) $post_id; + + if ( !$post_id ) + return false; + + if ( empty($tags) ) + $tags = array(); + + $tags = is_array($tags) ? $tags : explode( ',', trim($tags, " \n\t\r\0\x0B,") ); + + // Hierarchical taxonomies must always pass IDs rather than names so that children with the same + // names but different parents aren't confused. + if ( is_taxonomy_hierarchical( $taxonomy ) ) { + $tags = array_map( 'intval', $tags ); + $tags = array_unique( $tags ); + } + + return wp_set_object_terms($post_id, $tags, $taxonomy, $append); +} + +/** + * Set categories for a post. + * + * If the post categories parameter is not set, then the default category is + * going used. + * + * @since 2.1.0 + * + * @param int $post_ID Post ID. + * @param array $post_categories Optional. List of categories. + * @return bool|mixed + */ +function wp_set_post_categories($post_ID = 0, $post_categories = array()) { + $post_ID = (int) $post_ID; + $post_type = get_post_type( $post_ID ); + $post_status = get_post_status( $post_ID ); + // If $post_categories isn't already an array, make it one: + if ( !is_array($post_categories) || empty($post_categories) ) { + if ( 'post' == $post_type && 'auto-draft' != $post_status ) + $post_categories = array( get_option('default_category') ); + else + $post_categories = array(); + } else if ( 1 == count($post_categories) && '' == reset($post_categories) ) { + return true; + } + + if ( !empty($post_categories) ) { + $post_categories = array_map('intval', $post_categories); + $post_categories = array_unique($post_categories); + } + + return wp_set_object_terms($post_ID, $post_categories, 'category'); +} + +/** + * Transition the post status of a post. + * + * Calls hooks to transition post status. + * + * The first is 'transition_post_status' with new status, old status, and post data. + * + * The next action called is 'OLDSTATUS_to_NEWSTATUS' the 'NEWSTATUS' is the + * $new_status parameter and the 'OLDSTATUS' is $old_status parameter; it has the + * post data. + * + * The final action is named 'NEWSTATUS_POSTTYPE', 'NEWSTATUS' is from the $new_status + * parameter and POSTTYPE is post_type post data. + * + * @since 2.3.0 + * @link http://codex.wordpress.org/Post_Status_Transitions + * + * @uses do_action() Calls 'transition_post_status' on $new_status, $old_status and + * $post if there is a status change. + * @uses do_action() Calls '{$old_status}_to_{$new_status}' on $post if there is a status change. + * @uses do_action() Calls '{$new_status}_{$post->post_type}' on post ID and $post. + * + * @param string $new_status Transition to this post status. + * @param string $old_status Previous post status. + * @param object $post Post data. + */ +function wp_transition_post_status($new_status, $old_status, $post) { + do_action('transition_post_status', $new_status, $old_status, $post); + do_action("{$old_status}_to_{$new_status}", $post); + do_action("{$new_status}_{$post->post_type}", $post->ID, $post); +} + +// +// Trackback and ping functions +// + +/** + * Add a URL to those already pung. + * + * @since 1.5.0 + * @uses $wpdb + * + * @param int $post_id Post ID. + * @param string $uri Ping URI. + * @return int How many rows were updated. + */ +function add_ping($post_id, $uri) { + global $wpdb; + $pung = $wpdb->get_var( $wpdb->prepare( "SELECT pinged FROM $wpdb->posts WHERE ID = %d", $post_id )); + $pung = trim($pung); + $pung = preg_split('/\s/', $pung); + $pung[] = $uri; + $new = implode("\n", $pung); + $new = apply_filters('add_ping', $new); + // expected_slashed ($new) + $new = stripslashes($new); + return $wpdb->update( $wpdb->posts, array( 'pinged' => $new ), array( 'ID' => $post_id ) ); +} + +/** + * Retrieve enclosures already enclosed for a post. + * + * @since 1.5.0 + * @uses $wpdb + * + * @param int $post_id Post ID. + * @return array List of enclosures + */ +function get_enclosed($post_id) { + $custom_fields = get_post_custom( $post_id ); + $pung = array(); + if ( !is_array( $custom_fields ) ) + return $pung; + + foreach ( $custom_fields as $key => $val ) { + if ( 'enclosure' != $key || !is_array( $val ) ) + continue; + foreach( $val as $enc ) { + $enclosure = split( "\n", $enc ); + $pung[] = trim( $enclosure[ 0 ] ); + } + } + $pung = apply_filters('get_enclosed', $pung, $post_id); + return $pung; +} + +/** + * Retrieve URLs already pinged for a post. + * + * @since 1.5.0 + * @uses $wpdb + * + * @param int $post_id Post ID. + * @return array + */ +function get_pung($post_id) { + global $wpdb; + $pung = $wpdb->get_var( $wpdb->prepare( "SELECT pinged FROM $wpdb->posts WHERE ID = %d", $post_id )); + $pung = trim($pung); + $pung = preg_split('/\s/', $pung); + $pung = apply_filters('get_pung', $pung); + return $pung; +} + +/** + * Retrieve URLs that need to be pinged. + * + * @since 1.5.0 + * @uses $wpdb + * + * @param int $post_id Post ID + * @return array + */ +function get_to_ping($post_id) { + global $wpdb; + $to_ping = $wpdb->get_var( $wpdb->prepare( "SELECT to_ping FROM $wpdb->posts WHERE ID = %d", $post_id )); + $to_ping = trim($to_ping); + $to_ping = preg_split('/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY); + $to_ping = apply_filters('get_to_ping', $to_ping); + return $to_ping; +} + +/** + * Do trackbacks for a list of URLs. + * + * @since 1.0.0 + * + * @param string $tb_list Comma separated list of URLs + * @param int $post_id Post ID + */ +function trackback_url_list($tb_list, $post_id) { + if ( ! empty( $tb_list ) ) { + // get post data + $postdata = wp_get_single_post($post_id, ARRAY_A); + + // import postdata as variables + extract($postdata, EXTR_SKIP); + + // form an excerpt + $excerpt = strip_tags($post_excerpt ? $post_excerpt : $post_content); + + if (strlen($excerpt) > 255) { + $excerpt = substr($excerpt,0,252) . '...'; + } + + $trackback_urls = explode(',', $tb_list); + foreach( (array) $trackback_urls as $tb_url) { + $tb_url = trim($tb_url); + trackback($tb_url, stripslashes($post_title), $excerpt, $post_id); + } + } +} + +// +// Page functions +// + +/** + * Get a list of page IDs. + * + * @since 2.0.0 + * @uses $wpdb + * + * @return array List of page IDs. + */ +function get_all_page_ids() { + global $wpdb; + + if ( ! $page_ids = wp_cache_get('all_page_ids', 'posts') ) { + $page_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_type = 'page'"); + wp_cache_add('all_page_ids', $page_ids, 'posts'); + } + + return $page_ids; +} + +/** + * Retrieves page data given a page ID or page object. + * + * @since 1.5.1 + * + * @param mixed $page Page object or page ID. Passed by reference. + * @param string $output What to output. OBJECT, ARRAY_A, or ARRAY_N. + * @param string $filter How the return value should be filtered. + * @return mixed Page data. + */ +function &get_page(&$page, $output = OBJECT, $filter = 'raw') { + $p = get_post($page, $output, $filter); + return $p; +} + +/** + * Retrieves a page given its path. + * + * @since 2.1.0 + * @uses $wpdb + * + * @param string $page_path Page path + * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. + * @param string $post_type Optional. Post type. Default page. + * @return mixed Null when complete. + */ +function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { + global $wpdb; + $null = null; + $page_path = rawurlencode(urldecode($page_path)); + $page_path = str_replace('%2F', '/', $page_path); + $page_path = str_replace('%20', ' ', $page_path); + $page_paths = '/' . trim($page_path, '/'); + $leaf_path = sanitize_title(basename($page_paths)); + $page_paths = explode('/', $page_paths); + $full_path = ''; + foreach ( (array) $page_paths as $pathdir ) + $full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir); + + $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = %s AND (post_type = %s OR post_type = 'attachment')", $leaf_path, $post_type )); + + if ( empty($pages) ) + return $null; + + foreach ( $pages as $page ) { + $path = '/' . $leaf_path; + $curpage = $page; + while ( $curpage->post_parent != 0 ) { + $post_parent = $curpage->post_parent; + $curpage = wp_cache_get( $post_parent, 'posts' ); + if ( false === $curpage ) + $curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = %d and post_type = %s", $post_parent, $post_type ) ); + $path = '/' . $curpage->post_name . $path; + } + + if ( $path == $full_path ) + return get_page($page->ID, $output, $post_type); + } + + return $null; +} + +/** + * Retrieve a page given its title. + * + * @since 2.1.0 + * @uses $wpdb + * + * @param string $page_title Page title + * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. + * @param string $post_type Optional. Post type. Default page. + * @return mixed + */ +function get_page_by_title($page_title, $output = OBJECT, $post_type = 'page' ) { + global $wpdb; + $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type= %s", $page_title, $post_type ) ); + if ( $page ) + return get_page($page, $output); + + return null; +} + +/** + * Retrieve child pages from list of pages matching page ID. + * + * Matches against the pages parameter against the page ID. Also matches all + * children for the same to retrieve all children of a page. Does not make any + * SQL queries to get the children. + * + * @since 1.5.1 + * + * @param int $page_id Page ID. + * @param array $pages List of pages' objects. + * @return array + */ +function &get_page_children($page_id, $pages) { + $page_list = array(); + foreach ( (array) $pages as $page ) { + if ( $page->post_parent == $page_id ) { + $page_list[] = $page; + if ( $children = get_page_children($page->ID, $pages) ) + $page_list = array_merge($page_list, $children); + } + } + return $page_list; +} + +/** + * Order the pages with children under parents in a flat list. + * + * It uses auxiliary structure to hold parent-children relationships and + * runs in O(N) complexity + * + * @since 2.0.0 + * + * @param array $pages Posts array. + * @param int $page_id Parent page ID. + * @return array A list arranged by hierarchy. Children immediately follow their parents. + */ +function &get_page_hierarchy( &$pages, $page_id = 0 ) { + if ( empty( $pages ) ) { + $result = array(); + return $result; + } + + $children = array(); + foreach ( (array) $pages as $p ) { + $parent_id = intval( $p->post_parent ); + $children[ $parent_id ][] = $p; + } + + $result = array(); + _page_traverse_name( $page_id, $children, $result ); + + return $result; +} + +/** + * function to traverse and return all the nested children post names of a root page. + * $children contains parent-chilren relations + * + * @since 2.9.0 + */ +function _page_traverse_name( $page_id, &$children, &$result ){ + if ( isset( $children[ $page_id ] ) ){ + foreach( (array)$children[ $page_id ] as $child ) { + $result[ $child->ID ] = $child->post_name; + _page_traverse_name( $child->ID, $children, $result ); + } + } +} + +/** + * Builds URI for a page. + * + * Sub pages will be in the "directory" under the parent page post name. + * + * @since 1.5.0 + * + * @param mixed $page Page object or page ID. + * @return string Page URI. + */ +function get_page_uri($page) { + if ( ! is_object($page) ) + $page = get_page($page); + $uri = $page->post_name; + + // A page cannot be it's own parent. + if ( $page->post_parent == $page->ID ) + return $uri; + + while ($page->post_parent != 0) { + $page = get_page($page->post_parent); + $uri = $page->post_name . "/" . $uri; + } + + return $uri; +} + +/** + * Retrieve a list of pages. + * + * The defaults that can be overridden are the following: 'child_of', + * 'sort_order', 'sort_column', 'post_title', 'hierarchical', 'exclude', + * 'include', 'meta_key', 'meta_value','authors', 'number', and 'offset'. + * + * @since 1.5.0 + * @uses $wpdb + * + * @param mixed $args Optional. Array or string of options that overrides defaults. + * @return array List of pages matching defaults or $args + */ +function &get_pages($args = '') { + global $wpdb; + + $defaults = array( + 'child_of' => 0, 'sort_order' => 'ASC', + 'sort_column' => 'post_title', 'hierarchical' => 1, + 'exclude' => array(), 'include' => array(), + 'meta_key' => '', 'meta_value' => '', + 'authors' => '', 'parent' => -1, 'exclude_tree' => '', + 'number' => '', 'offset' => 0, + 'post_type' => 'page', 'post_status' => 'publish', + ); + + $r = wp_parse_args( $args, $defaults ); + extract( $r, EXTR_SKIP ); + $number = (int) $number; + $offset = (int) $offset; + + // Make sure the post type is hierarchical + $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) ); + if ( !in_array( $post_type, $hierarchical_post_types ) ) + return false; + + // Make sure we have a valid post status + if ( !in_array($post_status, get_post_stati()) ) + return false; + + $cache = array(); + $key = md5( serialize( compact(array_keys($defaults)) ) ); + if ( $cache = wp_cache_get( 'get_pages', 'posts' ) ) { + if ( is_array($cache) && isset( $cache[ $key ] ) ) { + $pages = apply_filters('get_pages', $cache[ $key ], $r ); + return $pages; + } + } + + if ( !is_array($cache) ) + $cache = array(); + + $inclusions = ''; + if ( !empty($include) ) { + $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include + $parent = -1; + $exclude = ''; + $meta_key = ''; + $meta_value = ''; + $hierarchical = false; + $incpages = wp_parse_id_list( $include ); + if ( ! empty( $incpages ) ) { + foreach ( $incpages as $incpage ) { + if (empty($inclusions)) + $inclusions = $wpdb->prepare(' AND ( ID = %d ', $incpage); + else + $inclusions .= $wpdb->prepare(' OR ID = %d ', $incpage); + } + } + } + if (!empty($inclusions)) + $inclusions .= ')'; + + $exclusions = ''; + if ( !empty($exclude) ) { + $expages = wp_parse_id_list( $exclude ); + if ( ! empty( $expages ) ) { + foreach ( $expages as $expage ) { + if (empty($exclusions)) + $exclusions = $wpdb->prepare(' AND ( ID <> %d ', $expage); + else + $exclusions .= $wpdb->prepare(' AND ID <> %d ', $expage); + } + } + } + if (!empty($exclusions)) + $exclusions .= ')'; + + $author_query = ''; + if (!empty($authors)) { + $post_authors = preg_split('/[\s,]+/',$authors); + + if ( ! empty( $post_authors ) ) { + foreach ( $post_authors as $post_author ) { + //Do we have an author id or an author login? + if ( 0 == intval($post_author) ) { + $post_author = get_userdatabylogin($post_author); + if ( empty($post_author) ) + continue; + if ( empty($post_author->ID) ) + continue; + $post_author = $post_author->ID; + } + + if ( '' == $author_query ) + $author_query = $wpdb->prepare(' post_author = %d ', $post_author); + else + $author_query .= $wpdb->prepare(' OR post_author = %d ', $post_author); + } + if ( '' != $author_query ) + $author_query = " AND ($author_query)"; + } + } + + $join = ''; + $where = "$exclusions $inclusions "; + if ( ! empty( $meta_key ) || ! empty( $meta_value ) ) { + $join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )"; + + // meta_key and meta_value might be slashed + $meta_key = stripslashes($meta_key); + $meta_value = stripslashes($meta_value); + if ( ! empty( $meta_key ) ) + $where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s", $meta_key); + if ( ! empty( $meta_value ) ) + $where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_value = %s", $meta_value); + + } + + if ( $parent >= 0 ) + $where .= $wpdb->prepare(' AND post_parent = %d ', $parent); + + $where_post_type = $wpdb->prepare( "post_type = '%s' AND post_status = '%s'", $post_type, $post_status ); + + $query = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where "; + $query .= $author_query; + $query .= " ORDER BY " . $sort_column . " " . $sort_order ; + + if ( !empty($number) ) + $query .= ' LIMIT ' . $offset . ',' . $number; + + $pages = $wpdb->get_results($query); + + if ( empty($pages) ) { + $pages = apply_filters('get_pages', array(), $r); + return $pages; + } + + // Sanitize before caching so it'll only get done once + $num_pages = count($pages); + for ($i = 0; $i < $num_pages; $i++) { + $pages[$i] = sanitize_post($pages[$i], 'raw'); + } + + // Update cache. + update_page_cache($pages); + + if ( $child_of || $hierarchical ) + $pages = & get_page_children($child_of, $pages); + + if ( !empty($exclude_tree) ) { + $exclude = (int) $exclude_tree; + $children = get_page_children($exclude, $pages); + $excludes = array(); + foreach ( $children as $child ) + $excludes[] = $child->ID; + $excludes[] = $exclude; + $num_pages = count($pages); + for ( $i = 0; $i < $num_pages; $i++ ) { + if ( in_array($pages[$i]->ID, $excludes) ) + unset($pages[$i]); + } + } + + $cache[ $key ] = $pages; + wp_cache_set( 'get_pages', $cache, 'posts' ); + + $pages = apply_filters('get_pages', $pages, $r); + + return $pages; +} + +// +// Attachment functions +// + +/** + * Check if the attachment URI is local one and is really an attachment. + * + * @since 2.0.0 + * + * @param string $url URL to check + * @return bool True on success, false on failure. + */ +function is_local_attachment($url) { + if (strpos($url, home_url()) === false) + return false; + if (strpos($url, home_url('/?attachment_id=')) !== false) + return true; + if ( $id = url_to_postid($url) ) { + $post = & get_post($id); + if ( 'attachment' == $post->post_type ) + return true; + } + return false; +} + +/** + * Insert an attachment. + * + * If you set the 'ID' in the $object parameter, it will mean that you are + * updating and attempt to update the attachment. You can also set the + * attachment name or title by setting the key 'post_name' or 'post_title'. + * + * You can set the dates for the attachment manually by setting the 'post_date' + * and 'post_date_gmt' keys' values. + * + * By default, the comments will use the default settings for whether the + * comments are allowed. You can close them manually or keep them open by + * setting the value for the 'comment_status' key. + * + * The $object parameter can have the following: + * 'post_status' - Default is 'draft'. Can not be overridden, set the same as parent post. + * 'post_type' - Default is 'post', will be set to attachment. Can not override. + * 'post_author' - Default is current user ID. The ID of the user, who added the attachment. + * 'ping_status' - Default is the value in default ping status option. Whether the attachment + * can accept pings. + * 'post_parent' - Default is 0. Can use $parent parameter or set this for the post it belongs + * to, if any. + * 'menu_order' - Default is 0. The order it is displayed. + * 'to_ping' - Whether to ping. + * 'pinged' - Default is empty string. + * 'post_password' - Default is empty string. The password to access the attachment. + * 'guid' - Global Unique ID for referencing the attachment. + * 'post_content_filtered' - Attachment post content filtered. + * 'post_excerpt' - Attachment excerpt. + * + * @since 2.0.0 + * @uses $wpdb + * @uses $user_ID + * @uses do_action() Calls 'edit_attachment' on $post_ID if this is an update. + * @uses do_action() Calls 'add_attachment' on $post_ID if this is not an update. + * + * @param string|array $object Arguments to override defaults. + * @param string $file Optional filename. + * @param int $parent Parent post ID. + * @return int Attachment ID. + */ +function wp_insert_attachment($object, $file = false, $parent = 0) { + global $wpdb, $user_ID; + + $defaults = array('post_status' => 'inherit', 'post_type' => 'post', 'post_author' => $user_ID, + 'ping_status' => get_option('default_ping_status'), 'post_parent' => 0, + 'menu_order' => 0, 'to_ping' => '', 'pinged' => '', 'post_password' => '', + 'guid' => '', 'post_content_filtered' => '', 'post_excerpt' => '', 'import_id' => 0, 'context' => ''); + + $object = wp_parse_args($object, $defaults); + if ( !empty($parent) ) + $object['post_parent'] = $parent; + + $object = sanitize_post($object, 'db'); + + // export array as variables + extract($object, EXTR_SKIP); + + if ( empty($post_author) ) + $post_author = $user_ID; + + $post_type = 'attachment'; + + if ( ! in_array( $post_status, array( 'inherit', 'private' ) ) ) + $post_status = 'inherit'; + + // Make sure we set a valid category. + if ( !isset($post_category) || 0 == count($post_category) || !is_array($post_category) ) { + // 'post' requires at least one category. + if ( 'post' == $post_type ) + $post_category = array( get_option('default_category') ); + else + $post_category = array(); + } + + // Are we updating or creating? + if ( !empty($ID) ) { + $update = true; + $post_ID = (int) $ID; + } else { + $update = false; + $post_ID = 0; + } + + // Create a valid post name. + if ( empty($post_name) ) + $post_name = sanitize_title($post_title); + else + $post_name = sanitize_title($post_name); + + // expected_slashed ($post_name) + $post_name = wp_unique_post_slug($post_name, $post_ID, $post_status, $post_type, $post_parent); + + if ( empty($post_date) ) + $post_date = current_time('mysql'); + if ( empty($post_date_gmt) ) + $post_date_gmt = current_time('mysql', 1); + + if ( empty($post_modified) ) + $post_modified = $post_date; + if ( empty($post_modified_gmt) ) + $post_modified_gmt = $post_date_gmt; + + if ( empty($comment_status) ) { + if ( $update ) + $comment_status = 'closed'; + else + $comment_status = get_option('default_comment_status'); + } + if ( empty($ping_status) ) + $ping_status = get_option('default_ping_status'); + + if ( isset($to_ping) ) + $to_ping = preg_replace('|\s+|', "\n", $to_ping); + else + $to_ping = ''; + + if ( isset($post_parent) ) + $post_parent = (int) $post_parent; + else + $post_parent = 0; + + if ( isset($menu_order) ) + $menu_order = (int) $menu_order; + else + $menu_order = 0; + + if ( !isset($post_password) ) + $post_password = ''; + + if ( ! isset($pinged) ) + $pinged = ''; + + // expected_slashed (everything!) + $data = compact( array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'post_mime_type', 'guid' ) ); + $data = stripslashes_deep( $data ); + + if ( $update ) { + $wpdb->update( $wpdb->posts, $data, array( 'ID' => $post_ID ) ); + } else { + // If there is a suggested ID, use it if not already present + if ( !empty($import_id) ) { + $import_id = (int) $import_id; + if ( ! $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id) ) ) { + $data['ID'] = $import_id; + } + } + + $wpdb->insert( $wpdb->posts, $data ); + $post_ID = (int) $wpdb->insert_id; + } + + if ( empty($post_name) ) { + $post_name = sanitize_title($post_title, $post_ID); + $wpdb->update( $wpdb->posts, compact("post_name"), array( 'ID' => $post_ID ) ); + } + + wp_set_post_categories($post_ID, $post_category); + + if ( $file ) + update_attached_file( $post_ID, $file ); + + clean_post_cache($post_ID); + + if ( isset($post_parent) && $post_parent < 0 ) + add_post_meta($post_ID, '_wp_attachment_temp_parent', $post_parent, true); + + if ( ! empty( $context ) ) + add_post_meta( $post_ID, '_wp_attachment_context', $context, true ); + + if ( $update) { + do_action('edit_attachment', $post_ID); + } else { + do_action('add_attachment', $post_ID); + } + + return $post_ID; +} + +/** + * Trashes or deletes an attachment. + * + * When an attachment is permanently deleted, the file will also be removed. + * Deletion removes all post meta fields, taxonomy, comments, etc. associated + * with the attachment (except the main post). + * + * The attachment is moved to the trash instead of permanently deleted unless trash + * for media is disabled, item is already in the trash, or $force_delete is true. + * + * @since 2.0.0 + * @uses $wpdb + * @uses do_action() Calls 'delete_attachment' hook on Attachment ID. + * + * @param int $post_id Attachment ID. + * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false. + * @return mixed False on failure. Post data on success. + */ +function wp_delete_attachment( $post_id, $force_delete = false ) { + global $wpdb; + + if ( !$post = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id) ) ) + return $post; + + if ( 'attachment' != $post->post_type ) + return false; + + if ( !$force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' != $post->post_status ) + return wp_trash_post( $post_id ); + + delete_post_meta($post_id, '_wp_trash_meta_status'); + delete_post_meta($post_id, '_wp_trash_meta_time'); + + $meta = wp_get_attachment_metadata( $post_id ); + $backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true ); + $file = get_attached_file( $post_id ); + + if ( is_multisite() ) + delete_transient( 'dirsize_cache' ); + + do_action('delete_attachment', $post_id); + + wp_delete_object_term_relationships($post_id, array('category', 'post_tag')); + wp_delete_object_term_relationships($post_id, get_object_taxonomies($post->post_type)); + + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_thumbnail_id' AND meta_value = %d", $post_id )); + + $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id )); + if ( ! empty( $comment_ids ) ) { + do_action( 'delete_comment', $comment_ids ); + foreach ( $comment_ids as $comment_id ) + wp_delete_comment( $comment_id, true ); + do_action( 'deleted_comment', $comment_ids ); + } + + $post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id )); + if ( !empty($post_meta_ids) ) { + do_action( 'delete_postmeta', $post_meta_ids ); + $in_post_meta_ids = "'" . implode("', '", $post_meta_ids) . "'"; + $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_id IN($in_post_meta_ids)" ); + do_action( 'deleted_postmeta', $post_meta_ids ); + } + + do_action( 'delete_post', $post_id ); + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $post_id )); + do_action( 'deleted_post', $post_id ); + + $uploadpath = wp_upload_dir(); + + if ( ! empty($meta['thumb']) ) { + // Don't delete the thumb if another attachment uses it + if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $meta['thumb'] . '%', $post_id)) ) { + $thumbfile = str_replace(basename($file), $meta['thumb'], $file); + $thumbfile = apply_filters('wp_delete_file', $thumbfile); + @ unlink( path_join($uploadpath['basedir'], $thumbfile) ); + } + } + + // remove intermediate and backup images if there are any + foreach ( get_intermediate_image_sizes() as $size ) { + if ( $intermediate = image_get_intermediate_size($post_id, $size) ) { + $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']); + @ unlink( path_join($uploadpath['basedir'], $intermediate_file) ); + } + } + + if ( is_array($backup_sizes) ) { + foreach ( $backup_sizes as $size ) { + $del_file = path_join( dirname($meta['file']), $size['file'] ); + $del_file = apply_filters('wp_delete_file', $del_file); + @ unlink( path_join($uploadpath['basedir'], $del_file) ); + } + } + + $file = apply_filters('wp_delete_file', $file); + + if ( ! empty($file) ) + @ unlink($file); + + clean_post_cache($post_id); + + return $post; +} + +/** + * Retrieve attachment meta field for attachment ID. + * + * @since 2.1.0 + * + * @param int $post_id Attachment ID + * @param bool $unfiltered Optional, default is false. If true, filters are not run. + * @return string|bool Attachment meta field. False on failure. + */ +function wp_get_attachment_metadata( $post_id = 0, $unfiltered = false ) { + $post_id = (int) $post_id; + if ( !$post =& get_post( $post_id ) ) + return false; + + $data = get_post_meta( $post->ID, '_wp_attachment_metadata', true ); + + if ( $unfiltered ) + return $data; + + return apply_filters( 'wp_get_attachment_metadata', $data, $post->ID ); +} + +/** + * Update metadata for an attachment. + * + * @since 2.1.0 + * + * @param int $post_id Attachment ID. + * @param array $data Attachment data. + * @return int + */ +function wp_update_attachment_metadata( $post_id, $data ) { + $post_id = (int) $post_id; + if ( !$post =& get_post( $post_id ) ) + return false; + + $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ); + + return update_post_meta( $post->ID, '_wp_attachment_metadata', $data); +} + +/** + * Retrieve the URL for an attachment. + * + * @since 2.1.0 + * + * @param int $post_id Attachment ID. + * @return string + */ +function wp_get_attachment_url( $post_id = 0 ) { + $post_id = (int) $post_id; + if ( !$post =& get_post( $post_id ) ) + return false; + + $url = ''; + if ( $file = get_post_meta( $post->ID, '_wp_attached_file', true) ) { //Get attached file + if ( ($uploads = wp_upload_dir()) && false === $uploads['error'] ) { //Get upload directory + if ( 0 === strpos($file, $uploads['basedir']) ) //Check that the upload base exists in the file location + $url = str_replace($uploads['basedir'], $uploads['baseurl'], $file); //replace file location with url location + elseif ( false !== strpos($file, 'wp-content/uploads') ) + $url = $uploads['baseurl'] . substr( $file, strpos($file, 'wp-content/uploads') + 18 ); + else + $url = $uploads['baseurl'] . "/$file"; //Its a newly uploaded file, therefor $file is relative to the basedir. + } + } + + if ( empty($url) ) //If any of the above options failed, Fallback on the GUID as used pre-2.7, not recomended to rely upon this. + $url = get_the_guid( $post->ID ); + + $url = apply_filters( 'wp_get_attachment_url', $url, $post->ID ); + + if ( 'attachment' != $post->post_type || empty( $url ) ) + return false; + + return $url; +} + +/** + * Retrieve thumbnail for an attachment. + * + * @since 2.1.0 + * + * @param int $post_id Attachment ID. + * @return mixed False on failure. Thumbnail file path on success. + */ +function wp_get_attachment_thumb_file( $post_id = 0 ) { + $post_id = (int) $post_id; + if ( !$post =& get_post( $post_id ) ) + return false; + if ( !is_array( $imagedata = wp_get_attachment_metadata( $post->ID ) ) ) + return false; + + $file = get_attached_file( $post->ID ); + + if ( !empty($imagedata['thumb']) && ($thumbfile = str_replace(basename($file), $imagedata['thumb'], $file)) && file_exists($thumbfile) ) + return apply_filters( 'wp_get_attachment_thumb_file', $thumbfile, $post->ID ); + return false; +} + +/** + * Retrieve URL for an attachment thumbnail. + * + * @since 2.1.0 + * + * @param int $post_id Attachment ID + * @return string|bool False on failure. Thumbnail URL on success. + */ +function wp_get_attachment_thumb_url( $post_id = 0 ) { + $post_id = (int) $post_id; + if ( !$post =& get_post( $post_id ) ) + return false; + if ( !$url = wp_get_attachment_url( $post->ID ) ) + return false; + + $sized = image_downsize( $post_id, 'thumbnail' ); + if ( $sized ) + return $sized[0]; + + if ( !$thumb = wp_get_attachment_thumb_file( $post->ID ) ) + return false; + + $url = str_replace(basename($url), basename($thumb), $url); + + return apply_filters( 'wp_get_attachment_thumb_url', $url, $post->ID ); +} + +/** + * Check if the attachment is an image. + * + * @since 2.1.0 + * + * @param int $post_id Attachment ID + * @return bool + */ +function wp_attachment_is_image( $post_id = 0 ) { + $post_id = (int) $post_id; + if ( !$post =& get_post( $post_id ) ) + return false; + + if ( !$file = get_attached_file( $post->ID ) ) + return false; + + $ext = preg_match('/\.([^.]+)$/', $file, $matches) ? strtolower($matches[1]) : false; + + $image_exts = array('jpg', 'jpeg', 'gif', 'png'); + + if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) ) + return true; + return false; +} + +/** + * Retrieve the icon for a MIME type. + * + * @since 2.1.0 + * + * @param string $mime MIME type + * @return string|bool + */ +function wp_mime_type_icon( $mime = 0 ) { + if ( !is_numeric($mime) ) + $icon = wp_cache_get("mime_type_icon_$mime"); + if ( empty($icon) ) { + $post_id = 0; + $post_mimes = array(); + if ( is_numeric($mime) ) { + $mime = (int) $mime; + if ( $post =& get_post( $mime ) ) { + $post_id = (int) $post->ID; + $ext = preg_replace('/^.+?\.([^.]+)$/', '$1', $post->guid); + if ( !empty($ext) ) { + $post_mimes[] = $ext; + if ( $ext_type = wp_ext2type( $ext ) ) + $post_mimes[] = $ext_type; + } + $mime = $post->post_mime_type; + } else { + $mime = 0; + } + } else { + $post_mimes[] = $mime; + } + + $icon_files = wp_cache_get('icon_files'); + + if ( !is_array($icon_files) ) { + $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/crystal' ); + $icon_dir_uri = apply_filters( 'icon_dir_uri', includes_url('images/crystal') ); + $dirs = apply_filters( 'icon_dirs', array($icon_dir => $icon_dir_uri) ); + $icon_files = array(); + while ( $dirs ) { + $dir = array_shift($keys = array_keys($dirs)); + $uri = array_shift($dirs); + if ( $dh = opendir($dir) ) { + while ( false !== $file = readdir($dh) ) { + $file = basename($file); + if ( substr($file, 0, 1) == '.' ) + continue; + if ( !in_array(strtolower(substr($file, -4)), array('.png', '.gif', '.jpg') ) ) { + if ( is_dir("$dir/$file") ) + $dirs["$dir/$file"] = "$uri/$file"; + continue; + } + $icon_files["$dir/$file"] = "$uri/$file"; + } + closedir($dh); + } + } + wp_cache_set('icon_files', $icon_files, 600); + } + + // Icon basename - extension = MIME wildcard + foreach ( $icon_files as $file => $uri ) + $types[ preg_replace('/^([^.]*).*$/', '$1', basename($file)) ] =& $icon_files[$file]; + + if ( ! empty($mime) ) { + $post_mimes[] = substr($mime, 0, strpos($mime, '/')); + $post_mimes[] = substr($mime, strpos($mime, '/') + 1); + $post_mimes[] = str_replace('/', '_', $mime); + } + + $matches = wp_match_mime_types(array_keys($types), $post_mimes); + $matches['default'] = array('default'); + + foreach ( $matches as $match => $wilds ) { + if ( isset($types[$wilds[0]])) { + $icon = $types[$wilds[0]]; + if ( !is_numeric($mime) ) + wp_cache_set("mime_type_icon_$mime", $icon); + break; + } + } + } + + return apply_filters( 'wp_mime_type_icon', $icon, $mime, $post_id ); // Last arg is 0 if function pass mime type. +} + +/** + * Checked for changed slugs for published post objects and save the old slug. + * + * The function is used when a post object of any type is updated, + * by comparing the current and previous post objects. + * + * If the slug was changed and not already part of the old slugs then it will be + * added to the post meta field ('_wp_old_slug') for storing old slugs for that + * post. + * + * The most logically usage of this function is redirecting changed post objects, so + * that those that linked to an changed post will be redirected to the new post. + * + * @since 2.1.0 + * + * @param int $post_id Post ID. + * @param object $post The Post Object + * @param object $post_before The Previous Post Object + * @return int Same as $post_id + */ +function wp_check_for_changed_slugs($post_id, $post, $post_before) { + // dont bother if it hasnt changed + if ( $post->post_name == $post_before->post_name ) + return; + + // we're only concerned with published, non-hierarchical objects + if ( $post->post_status != 'publish' || is_post_type_hierarchical( $post->post_type ) ) + return; + + $old_slugs = (array) get_post_meta($post_id, '_wp_old_slug'); + + // if we haven't added this old slug before, add it now + if ( !empty( $post_before->post_name ) && !in_array($post_before->post_name, $old_slugs) ) + add_post_meta($post_id, '_wp_old_slug', $post_before->post_name); + + // if the new slug was used previously, delete it from the list + if ( in_array($post->post_name, $old_slugs) ) + delete_post_meta($post_id, '_wp_old_slug', $post->post_name); +} + +/** + * Retrieve the private post SQL based on capability. + * + * This function provides a standardized way to appropriately select on the + * post_status of posts/pages. The function will return a piece of SQL code that + * can be added to a WHERE clause; this SQL is constructed to allow all + * published posts, and all private posts to which the user has access. + * + * It also allows plugins that define their own post type to control the cap by + * using the hook 'pub_priv_sql_capability'. The plugin is expected to return + * the capability the user must have to read the private post type. + * + * @since 2.2.0 + * + * @uses $user_ID + * @uses apply_filters() Call 'pub_priv_sql_capability' filter for plugins with different post types. + * + * @param string $post_type currently only supports 'post' or 'page'. + * @return string SQL code that can be added to a where clause. + */ +function get_private_posts_cap_sql($post_type) { + return get_posts_by_author_sql($post_type, FALSE); +} + +/** + * Retrieve the post SQL based on capability, author, and type. + * + * See above for full description. + * + * @since 3.0.0 + * @param string $post_type currently only supports 'post' or 'page'. + * @param bool $full Optional. Returns a full WHERE statement instead of just an 'andalso' term. + * @param int $post_author Optional. Query posts having a single author ID. + * @return string SQL WHERE code that can be added to a query. + */ +function get_posts_by_author_sql($post_type, $full = TRUE, $post_author = NULL) { + global $user_ID, $wpdb; + + // Private posts + if ($post_type == 'post') { + $cap = 'read_private_posts'; + // Private pages + } elseif ($post_type == 'page') { + $cap = 'read_private_pages'; + // Dunno what it is, maybe plugins have their own post type? + } else { + $cap = ''; + $cap = apply_filters('pub_priv_sql_capability', $cap); + + if (empty($cap)) { + // We don't know what it is, filters don't change anything, + // so set the SQL up to return nothing. + return ' 1 = 0 '; + } + } + + if ($full) { + if (is_null($post_author)) { + $sql = $wpdb->prepare('WHERE post_type = %s AND ', $post_type); + } else { + $sql = $wpdb->prepare('WHERE post_author = %d AND post_type = %s AND ', $post_author, $post_type); + } + } else { + $sql = ''; + } + + $sql .= "(post_status = 'publish'"; + + if (current_user_can($cap)) { + // Does the user have the capability to view private posts? Guess so. + $sql .= " OR post_status = 'private'"; + } elseif (is_user_logged_in()) { + // Users can view their own private posts. + $id = (int) $user_ID; + if (is_null($post_author) || !$full) { + $sql .= " OR post_status = 'private' AND post_author = $id"; + } elseif ($id == (int)$post_author) { + $sql .= " OR post_status = 'private'"; + } // else none + } // else none + + $sql .= ')'; + + return $sql; +} + +/** + * Retrieve the date that the last post was published. + * + * The server timezone is the default and is the difference between GMT and + * server time. The 'blog' value is the date when the last post was posted. The + * 'gmt' is when the last post was posted in GMT formatted date. + * + * @since 0.71 + * + * @uses apply_filters() Calls 'get_lastpostdate' filter + * + * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'. + * @return string The date of the last post. + */ +function get_lastpostdate($timezone = 'server') { + return apply_filters( 'get_lastpostdate', _get_last_post_time( $timezone, 'date' ), $timezone ); +} + +/** + * Retrieve last post modified date depending on timezone. + * + * The server timezone is the default and is the difference between GMT and + * server time. The 'blog' value is just when the last post was modified. The + * 'gmt' is when the last post was modified in GMT time. + * + * @since 1.2.0 + * @uses apply_filters() Calls 'get_lastpostmodified' filter + * + * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'. + * @return string The date the post was last modified. + */ +function get_lastpostmodified($timezone = 'server') { + $lastpostmodified = _get_last_post_time( $timezone, 'modified' ); + + $lastpostdate = get_lastpostdate($timezone); + if ( $lastpostdate > $lastpostmodified ) + $lastpostmodified = $lastpostdate; + + return apply_filters( 'get_lastpostmodified', $lastpostmodified, $timezone ); +} + +/** + * Retrieve latest post date data based on timezone. + * + * @access private + * @since 3.1.0 + * + * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'. + * @param string $field Field to check. Can be 'date' or 'modified'. + * @return string The date. + */ +function _get_last_post_time( $timezone, $field ) { + global $wpdb; + + if ( !in_array( $field, array( 'date', 'modified' ) ) ) + return false; + + $timezone = strtolower( $timezone ); + + $key = "lastpost{$field}:$timezone"; + + $date = wp_cache_get( $key, 'timeinfo' ); + + if ( !$date ) { + $add_seconds_server = date('Z'); + + $post_types = get_post_types( array( 'publicly_queryable' => true ) ); + array_walk( $post_types, array( &$wpdb, 'escape_by_ref' ) ); + $post_types = "'" . implode( "', '", $post_types ) . "'"; + + switch ( $timezone ) { + case 'gmt': + $date = $wpdb->get_var("SELECT post_{$field}_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1"); + break; + case 'blog': + $date = $wpdb->get_var("SELECT post_{$field} FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1"); + break; + case 'server': + $date = $wpdb->get_var("SELECT DATE_ADD(post_{$field}_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1"); + break; + } + + if ( $date ) + wp_cache_set( $key, $date, 'timeinfo' ); + } + + return $date; +} + +/** + * Updates posts in cache. + * + * @usedby update_page_cache() Aliased by this function. + * + * @package WordPress + * @subpackage Cache + * @since 1.5.1 + * + * @param array $posts Array of post objects + */ +function update_post_cache(&$posts) { + if ( !$posts ) + return; + + foreach ( $posts as $post ) + wp_cache_add($post->ID, $post, 'posts'); +} + +/** + * Will clean the post in the cache. + * + * Cleaning means delete from the cache of the post. Will call to clean the term + * object cache associated with the post ID. + * + * clean_post_cache() will call itself recursively for each child post. + * + * This function not run if $_wp_suspend_cache_invalidation is not empty. See + * wp_suspend_cache_invalidation(). + * + * @package WordPress + * @subpackage Cache + * @since 2.0.0 + * + * @uses do_action() Calls 'clean_post_cache' on $id before adding children (if any). + * + * @param int $id The Post ID in the cache to clean + */ +function clean_post_cache($id) { + global $_wp_suspend_cache_invalidation, $wpdb; + + if ( !empty($_wp_suspend_cache_invalidation) ) + return; + + $id = (int) $id; + + if ( 0 === $id ) + return; + + wp_cache_delete($id, 'posts'); + wp_cache_delete($id, 'post_meta'); + + clean_object_term_cache($id, 'post'); + + wp_cache_delete( 'wp_get_archives', 'general' ); + + do_action('clean_post_cache', $id); + + if ( $children = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d", $id) ) ) { + foreach ( $children as $cid ) { + // Loop detection + if ( $cid == $id ) + continue; + clean_post_cache( $cid ); + } + } + + if ( is_multisite() ) + wp_cache_delete( $wpdb->blogid . '-' . $id, 'global-posts' ); +} + +/** + * Alias of update_post_cache(). + * + * @see update_post_cache() Posts and pages are the same, alias is intentional + * + * @package WordPress + * @subpackage Cache + * @since 1.5.1 + * + * @param array $pages list of page objects + */ +function update_page_cache(&$pages) { + update_post_cache($pages); +} + +/** + * Will clean the page in the cache. + * + * Clean (read: delete) page from cache that matches $id. Will also clean cache + * associated with 'all_page_ids' and 'get_pages'. + * + * @package WordPress + * @subpackage Cache + * @since 2.0.0 + * + * @uses do_action() Will call the 'clean_page_cache' hook action. + * + * @param int $id Page ID to clean + */ +function clean_page_cache($id) { + clean_post_cache($id); + + wp_cache_delete( 'all_page_ids', 'posts' ); + wp_cache_delete( 'get_pages', 'posts' ); + + do_action('clean_page_cache', $id); +} + +/** + * Call major cache updating functions for list of Post objects. + * + * @package WordPress + * @subpackage Cache + * @since 1.5.0 + * + * @uses $wpdb + * @uses update_post_cache() + * @uses update_object_term_cache() + * @uses update_postmeta_cache() + * + * @param array $posts Array of Post objects + * @param string $post_type The post type of the posts in $posts. Default is 'post'. + * @param bool $update_term_cache Whether to update the term cache. Default is true. + * @param bool $update_meta_cache Whether to update the meta cache. Default is true. + */ +function update_post_caches(&$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true) { + // No point in doing all this work if we didn't match any posts. + if ( !$posts ) + return; + + update_post_cache($posts); + + $post_ids = array(); + foreach ( $posts as $post ) + $post_ids[] = $post->ID; + + if ( empty($post_type) ) + $post_type = 'post'; + + if ( $update_term_cache ) { + if ( is_array($post_type) ) { + $ptypes = $post_type; + } elseif ( 'any' == $post_type ) { + // Just use the post_types in the supplied posts. + foreach ( $posts as $post ) + $ptypes[] = $post->post_type; + $ptypes = array_unique($ptypes); + } else { + $ptypes = array($post_type); + } + + if ( ! empty($ptypes) ) + update_object_term_cache($post_ids, $ptypes); + } + + if ( $update_meta_cache ) + update_postmeta_cache($post_ids); +} + +/** + * Updates metadata cache for list of post IDs. + * + * Performs SQL query to retrieve the metadata for the post IDs and updates the + * metadata cache for the posts. Therefore, the functions, which call this + * function, do not need to perform SQL queries on their own. + * + * @package WordPress + * @subpackage Cache + * @since 2.1.0 + * + * @uses $wpdb + * + * @param array $post_ids List of post IDs. + * @return bool|array Returns false if there is nothing to update or an array of metadata. + */ +function update_postmeta_cache($post_ids) { + return update_meta_cache('post', $post_ids); +} + +/** + * Will clean the attachment in the cache. + * + * Cleaning means delete from the cache. Optionaly will clean the term + * object cache associated with the attachment ID. + * + * This function will not run if $_wp_suspend_cache_invalidation is not empty. See + * wp_suspend_cache_invalidation(). + * + * @package WordPress + * @subpackage Cache + * @since 3.0.0 + * + * @uses do_action() Calls 'clean_attachment_cache' on $id. + * + * @param int $id The attachment ID in the cache to clean + * @param bool $clean_terms optional. Whether to clean terms cache + */ +function clean_attachment_cache($id, $clean_terms = false) { + global $_wp_suspend_cache_invalidation; + + if ( !empty($_wp_suspend_cache_invalidation) ) + return; + + $id = (int) $id; + + wp_cache_delete($id, 'posts'); + wp_cache_delete($id, 'post_meta'); + + if ( $clean_terms ) + clean_object_term_cache($id, 'attachment'); + + do_action('clean_attachment_cache', $id); +} + +// +// Hooks +// + +/** + * Hook for managing future post transitions to published. + * + * @since 2.3.0 + * @access private + * @uses $wpdb + * @uses do_action() Calls 'private_to_published' on post ID if this is a 'private_to_published' call. + * @uses wp_clear_scheduled_hook() with 'publish_future_post' and post ID. + * + * @param string $new_status New post status + * @param string $old_status Previous post status + * @param object $post Object type containing the post information + */ +function _transition_post_status($new_status, $old_status, $post) { + global $wpdb; + + if ( $old_status != 'publish' && $new_status == 'publish' ) { + // Reset GUID if transitioning to publish and it is empty + if ( '' == get_the_guid($post->ID) ) + $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) ); + do_action('private_to_published', $post->ID); // Deprecated, use private_to_publish + } + + // If published posts changed clear the lastpostmodified cache + if ( 'publish' == $new_status || 'publish' == $old_status) { + foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) { + wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' ); + wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' ); + } + } + + // Always clears the hook in case the post status bounced from future to draft. + wp_clear_scheduled_hook('publish_future_post', array( $post->ID ) ); +} + +/** + * Hook used to schedule publication for a post marked for the future. + * + * The $post properties used and must exist are 'ID' and 'post_date_gmt'. + * + * @since 2.3.0 + * @access private + * + * @param int $deprecated Not used. Can be set to null. Never implemented. + * Not marked as deprecated with _deprecated_argument() as it conflicts with + * wp_transition_post_status() and the default filter for _future_post_hook(). + * @param object $post Object type containing the post information + */ +function _future_post_hook( $deprecated = '', $post ) { + wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) ); + wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date ) . ' GMT') , 'publish_future_post', array( $post->ID ) ); +} + +/** + * Hook to schedule pings and enclosures when a post is published. + * + * @since 2.3.0 + * @access private + * @uses $wpdb + * @uses XMLRPC_REQUEST and APP_REQUEST constants. + * @uses do_action() Calls 'xmlprc_publish_post' on post ID if XMLRPC_REQUEST is defined. + * @uses do_action() Calls 'app_publish_post' on post ID if APP_REQUEST is defined. + * + * @param int $post_id The ID in the database table of the post being published + */ +function _publish_post_hook($post_id) { + global $wpdb; + + if ( defined('XMLRPC_REQUEST') ) + do_action('xmlrpc_publish_post', $post_id); + if ( defined('APP_REQUEST') ) + do_action('app_publish_post', $post_id); + + if ( defined('WP_IMPORTING') ) + return; + + $data = array( 'post_id' => $post_id, 'meta_value' => '1' ); + if ( get_option('default_pingback_flag') ) { + $wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_pingme' ) ); + do_action( 'added_postmeta', $wpdb->insert_id, $post_id, '_pingme', 1 ); + } + $wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_encloseme' ) ); + do_action( 'added_postmeta', $wpdb->insert_id, $post_id, '_encloseme', 1 ); + + wp_schedule_single_event(time(), 'do_pings'); +} + +/** + * Hook used to prevent page/post cache and rewrite rules from staying dirty. + * + * Does two things. If the post is a page and has a template then it will + * update/add that template to the meta. For both pages and posts, it will clean + * the post cache to make sure that the cache updates to the changes done + * recently. For pages, the rewrite rules of WordPress are flushed to allow for + * any changes. + * + * The $post parameter, only uses 'post_type' property and 'page_template' + * property. + * + * @since 2.3.0 + * @access private + * @uses $wp_rewrite Flushes Rewrite Rules. + * + * @param int $post_id The ID in the database table for the $post + * @param object $post Object type containing the post information + */ +function _save_post_hook($post_id, $post) { + if ( $post->post_type == 'page' ) { + clean_page_cache($post_id); + // Avoid flushing rules for every post during import. + if ( !defined('WP_IMPORTING') ) { + global $wp_rewrite; + $wp_rewrite->flush_rules(false); + } + } else { + clean_post_cache($post_id); + } +} + +/** + * Retrieve post ancestors and append to post ancestors property. + * + * Will only retrieve ancestors once, if property is already set, then nothing + * will be done. If there is not a parent post, or post ID and post parent ID + * are the same then nothing will be done. + * + * The parameter is passed by reference, so nothing needs to be returned. The + * property will be updated and can be referenced after the function is + * complete. The post parent will be an ancestor and the parent of the post + * parent will be an ancestor. There will only be two ancestors at the most. + * + * @since 2.5.0 + * @access private + * @uses $wpdb + * + * @param object $_post Post data. + * @return null When nothing needs to be done. + */ +function _get_post_ancestors(&$_post) { + global $wpdb; + + if ( isset($_post->ancestors) ) + return; + + $_post->ancestors = array(); + + if ( empty($_post->post_parent) || $_post->ID == $_post->post_parent ) + return; + + $id = $_post->ancestors[] = $_post->post_parent; + while ( $ancestor = $wpdb->get_var( $wpdb->prepare("SELECT `post_parent` FROM $wpdb->posts WHERE ID = %d LIMIT 1", $id) ) ) { + // Loop detection: If the ancestor has been seen before, break. + if ( ( $ancestor == $_post->ID ) || in_array($ancestor, $_post->ancestors) ) + break; + $id = $_post->ancestors[] = $ancestor; + } +} + +/** + * Determines which fields of posts are to be saved in revisions. + * + * Does two things. If passed a post *array*, it will return a post array ready + * to be insterted into the posts table as a post revision. Otherwise, returns + * an array whose keys are the post fields to be saved for post revisions. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * @access private + * @uses apply_filters() Calls '_wp_post_revision_fields' on 'title', 'content' and 'excerpt' fields. + * + * @param array $post Optional a post array to be processed for insertion as a post revision. + * @param bool $autosave optional Is the revision an autosave? + * @return array Post array ready to be inserted as a post revision or array of fields that can be versioned. + */ +function _wp_post_revision_fields( $post = null, $autosave = false ) { + static $fields = false; + + if ( !$fields ) { + // Allow these to be versioned + $fields = array( + 'post_title' => __( 'Title' ), + 'post_content' => __( 'Content' ), + 'post_excerpt' => __( 'Excerpt' ), + ); + + // Runs only once + $fields = apply_filters( '_wp_post_revision_fields', $fields ); + + // WP uses these internally either in versioning or elsewhere - they cannot be versioned + foreach ( array( 'ID', 'post_name', 'post_parent', 'post_date', 'post_date_gmt', 'post_status', 'post_type', 'comment_count', 'post_author' ) as $protect ) + unset( $fields[$protect] ); + } + + if ( !is_array($post) ) + return $fields; + + $return = array(); + foreach ( array_intersect( array_keys( $post ), array_keys( $fields ) ) as $field ) + $return[$field] = $post[$field]; + + $return['post_parent'] = $post['ID']; + $return['post_status'] = 'inherit'; + $return['post_type'] = 'revision'; + $return['post_name'] = $autosave ? "$post[ID]-autosave" : "$post[ID]-revision"; + $return['post_date'] = isset($post['post_modified']) ? $post['post_modified'] : ''; + $return['post_date_gmt'] = isset($post['post_modified_gmt']) ? $post['post_modified_gmt'] : ''; + + return $return; +} + +/** + * Saves an already existing post as a post revision. + * + * Typically used immediately prior to post updates. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses _wp_put_post_revision() + * + * @param int $post_id The ID of the post to save as a revision. + * @return mixed Null or 0 if error, new revision ID, if success. + */ +function wp_save_post_revision( $post_id ) { + // We do autosaves manually with wp_create_post_autosave() + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) + return; + + // WP_POST_REVISIONS = 0, false + if ( ! WP_POST_REVISIONS ) + return; + + if ( !$post = get_post( $post_id, ARRAY_A ) ) + return; + + if ( !post_type_supports($post['post_type'], 'revisions') ) + return; + + $return = _wp_put_post_revision( $post ); + + // WP_POST_REVISIONS = true (default), -1 + if ( !is_numeric( WP_POST_REVISIONS ) || WP_POST_REVISIONS < 0 ) + return $return; + + // all revisions and (possibly) one autosave + $revisions = wp_get_post_revisions( $post_id, array( 'order' => 'ASC' ) ); + + // WP_POST_REVISIONS = (int) (# of autosaves to save) + $delete = count($revisions) - WP_POST_REVISIONS; + + if ( $delete < 1 ) + return $return; + + $revisions = array_slice( $revisions, 0, $delete ); + + for ( $i = 0; isset($revisions[$i]); $i++ ) { + if ( false !== strpos( $revisions[$i]->post_name, 'autosave' ) ) + continue; + wp_delete_post_revision( $revisions[$i]->ID ); + } + + return $return; +} + +/** + * Retrieve the autosaved data of the specified post. + * + * Returns a post object containing the information that was autosaved for the + * specified post. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @param int $post_id The post ID. + * @return object|bool The autosaved data or false on failure or when no autosave exists. + */ +function wp_get_post_autosave( $post_id ) { + + if ( !$post = get_post( $post_id ) ) + return false; + + $q = array( + 'name' => "{$post->ID}-autosave", + 'post_parent' => $post->ID, + 'post_type' => 'revision', + 'post_status' => 'inherit' + ); + + // Use WP_Query so that the result gets cached + $autosave_query = new WP_Query; + + add_action( 'parse_query', '_wp_get_post_autosave_hack' ); + $autosave = $autosave_query->query( $q ); + remove_action( 'parse_query', '_wp_get_post_autosave_hack' ); + + if ( $autosave && is_array($autosave) && is_object($autosave[0]) ) + return $autosave[0]; + + return false; +} + +/** + * Internally used to hack WP_Query into submission. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @param object $query WP_Query object + */ +function _wp_get_post_autosave_hack( $query ) { + $query->is_single = false; +} + +/** + * Determines if the specified post is a revision. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @param int|object $post Post ID or post object. + * @return bool|int False if not a revision, ID of revision's parent otherwise. + */ +function wp_is_post_revision( $post ) { + if ( !$post = wp_get_post_revision( $post ) ) + return false; + return (int) $post->post_parent; +} + +/** + * Determines if the specified post is an autosave. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @param int|object $post Post ID or post object. + * @return bool|int False if not a revision, ID of autosave's parent otherwise + */ +function wp_is_post_autosave( $post ) { + if ( !$post = wp_get_post_revision( $post ) ) + return false; + if ( "{$post->post_parent}-autosave" !== $post->post_name ) + return false; + return (int) $post->post_parent; +} + +/** + * Inserts post data into the posts table as a post revision. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses wp_insert_post() + * + * @param int|object|array $post Post ID, post object OR post array. + * @param bool $autosave Optional. Is the revision an autosave? + * @return mixed Null or 0 if error, new revision ID if success. + */ +function _wp_put_post_revision( $post = null, $autosave = false ) { + if ( is_object($post) ) + $post = get_object_vars( $post ); + elseif ( !is_array($post) ) + $post = get_post($post, ARRAY_A); + if ( !$post || empty($post['ID']) ) + return; + + if ( isset($post['post_type']) && 'revision' == $post['post_type'] ) + return new WP_Error( 'post_type', __( 'Cannot create a revision of a revision' ) ); + + $post = _wp_post_revision_fields( $post, $autosave ); + $post = add_magic_quotes($post); //since data is from db + + $revision_id = wp_insert_post( $post ); + if ( is_wp_error($revision_id) ) + return $revision_id; + + if ( $revision_id ) + do_action( '_wp_put_post_revision', $revision_id ); + return $revision_id; +} + +/** + * Gets a post revision. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses get_post() + * + * @param int|object $post Post ID or post object + * @param string $output Optional. OBJECT, ARRAY_A, or ARRAY_N. + * @param string $filter Optional sanitation filter. @see sanitize_post() + * @return mixed Null if error or post object if success + */ +function &wp_get_post_revision(&$post, $output = OBJECT, $filter = 'raw') { + $null = null; + if ( !$revision = get_post( $post, OBJECT, $filter ) ) + return $revision; + if ( 'revision' !== $revision->post_type ) + return $null; + + if ( $output == OBJECT ) { + return $revision; + } elseif ( $output == ARRAY_A ) { + $_revision = get_object_vars($revision); + return $_revision; + } elseif ( $output == ARRAY_N ) { + $_revision = array_values(get_object_vars($revision)); + return $_revision; + } + + return $revision; +} + +/** + * Restores a post to the specified revision. + * + * Can restore a past revision using all fields of the post revision, or only selected fields. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses wp_get_post_revision() + * @uses wp_update_post() + * @uses do_action() Calls 'wp_restore_post_revision' on post ID and revision ID if wp_update_post() + * is successful. + * + * @param int|object $revision_id Revision ID or revision object. + * @param array $fields Optional. What fields to restore from. Defaults to all. + * @return mixed Null if error, false if no fields to restore, (int) post ID if success. + */ +function wp_restore_post_revision( $revision_id, $fields = null ) { + if ( !$revision = wp_get_post_revision( $revision_id, ARRAY_A ) ) + return $revision; + + if ( !is_array( $fields ) ) + $fields = array_keys( _wp_post_revision_fields() ); + + $update = array(); + foreach( array_intersect( array_keys( $revision ), $fields ) as $field ) + $update[$field] = $revision[$field]; + + if ( !$update ) + return false; + + $update['ID'] = $revision['post_parent']; + + $update = add_magic_quotes( $update ); //since data is from db + + $post_id = wp_update_post( $update ); + if ( is_wp_error( $post_id ) ) + return $post_id; + + if ( $post_id ) + do_action( 'wp_restore_post_revision', $post_id, $revision['ID'] ); + + return $post_id; +} + +/** + * Deletes a revision. + * + * Deletes the row from the posts table corresponding to the specified revision. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses wp_get_post_revision() + * @uses wp_delete_post() + * + * @param int|object $revision_id Revision ID or revision object. + * @return mixed Null or WP_Error if error, deleted post if success. + */ +function wp_delete_post_revision( $revision_id ) { + if ( !$revision = wp_get_post_revision( $revision_id ) ) + return $revision; + + $delete = wp_delete_post( $revision->ID ); + if ( is_wp_error( $delete ) ) + return $delete; + + if ( $delete ) + do_action( 'wp_delete_post_revision', $revision->ID, $revision ); + + return $delete; +} + +/** + * Returns all revisions of specified post. + * + * @package WordPress + * @subpackage Post_Revisions + * @since 2.6.0 + * + * @uses get_children() + * + * @param int|object $post_id Post ID or post object + * @return array empty if no revisions + */ +function wp_get_post_revisions( $post_id = 0, $args = null ) { + if ( ! WP_POST_REVISIONS ) + return array(); + if ( ( !$post = get_post( $post_id ) ) || empty( $post->ID ) ) + return array(); + + $defaults = array( 'order' => 'DESC', 'orderby' => 'date' ); + $args = wp_parse_args( $args, $defaults ); + $args = array_merge( $args, array( 'post_parent' => $post->ID, 'post_type' => 'revision', 'post_status' => 'inherit' ) ); + + if ( !$revisions = get_children( $args ) ) + return array(); + return $revisions; +} + +function _set_preview($post) { + + if ( ! is_object($post) ) + return $post; + + $preview = wp_get_post_autosave($post->ID); + + if ( ! is_object($preview) ) + return $post; + + $preview = sanitize_post($preview); + + $post->post_content = $preview->post_content; + $post->post_title = $preview->post_title; + $post->post_excerpt = $preview->post_excerpt; + + return $post; +} + +function _show_post_preview() { + + if ( isset($_GET['preview_id']) && isset($_GET['preview_nonce']) ) { + $id = (int) $_GET['preview_id']; + + if ( false == wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . $id ) ) + wp_die( __('You do not have permission to preview drafts.') ); + + add_filter('the_preview', '_set_preview'); + } +} + +/** + * Returns the post's parent's post_ID + * + * @since 3.1.0 + * + * @param int $post_id + * + * @return int|bool false on error + */ +function wp_get_post_parent_id( $post_ID ) { + $post = get_post( $post_ID ); + if ( !$post || is_wp_error( $post ) ) + return false; + return (int) $post->post_parent; +} + +/** + * Checks the given subset of the post hierarchy for hierarchy loops. + * Prevents loops from forming and breaks those that it finds. + * + * Attached to the wp_insert_post_parent filter. + * + * @since 3.1.0 + * @uses wp_find_hierarchy_loop() + * + * @param int $post_parent ID of the parent for the post we're checking. + * @parem int $post_ID ID of the post we're checking. + * + * @return int The new post_parent for the post. + */ +function wp_check_post_hierarchy_for_loops( $post_parent, $post_ID ) { + // Nothing fancy here - bail + if ( !$post_parent ) + return 0; + + // New post can't cause a loop + if ( empty( $post_ID ) ) + return $post_parent; + + // Can't be its own parent + if ( $post_parent == $post_ID ) + return 0; + + // Now look for larger loops + + if ( !$loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_ID, $post_parent ) ) + return $post_parent; // No loop + + // Setting $post_parent to the given value causes a loop + if ( isset( $loop[$post_ID] ) ) + return 0; + + // There's a loop, but it doesn't contain $post_ID. Break the loop. + foreach ( array_keys( $loop ) as $loop_member ) + wp_update_post( array( 'ID' => $loop_member, 'post_parent' => 0 ) ); + + return $post_parent; +} + +/** + * Returns an array of post format slugs to their translated and pretty display versions + * + * @since 3.1.0 + * + * @return array The array of translations + */ +function get_post_format_strings() { + $strings = array( + 'standard' => _x( 'Standard', 'Post format' ), // Special case. any value that evals to false will be considered standard + 'aside' => _x( 'Aside', 'Post format' ), + 'chat' => _x( 'Chat', 'Post format' ), + 'gallery' => _x( 'Gallery', 'Post format' ), + 'link' => _x( 'Link', 'Post format' ), + 'image' => _x( 'Image', 'Post format' ), + 'quote' => _x( 'Quote', 'Post format' ), + 'status' => _x( 'Status', 'Post format' ), + 'video' => _x( 'Video', 'Post format' ), + 'audio' => _x( 'Audio', 'Post format' ), + ); + return $strings; +} + +/** + * Retrieves an array of post format slugs. + * + * @since 3.1.0 + * + * @return array The array of post format slugs. + */ +function get_post_format_slugs() { + // 3.2-early: use array_combine() and array_keys( get_post_format_strings() ) + $slugs = array( + 'standard' => 'standard', // Special case. any value that evals to false will be considered standard + 'aside' => 'aside', + 'chat' => 'chat', + 'gallery' => 'gallery', + 'link' => 'link', + 'image' => 'image', + 'quote' => 'quote', + 'status' => 'status', + 'video' => 'video', + 'audio' => 'audio', + ); + return $slugs; +} + +/** + * Returns a pretty, translated version of a post format slug + * + * @since 3.1.0 + * + * @param string $slug A post format slug + * @return string The translated post format name + */ +function get_post_format_string( $slug ) { + $strings = get_post_format_strings(); + if ( !$slug ) + return $strings['standard']; + else + return ( isset( $strings[$slug] ) ) ? $strings[$slug] : ''; +} + +/** + * Sets a post thumbnail. + * + * @since 3.1.0 + * + * @param int|object $post Post ID or object where thumbnail should be attached. + * @param int $thumbnail_id Thumbnail to attach. + * @return bool True on success, false on failure. + */ +function set_post_thumbnail( $post, $thumbnail_id ) { + $post = get_post( $post ); + $thumbnail_id = absint( $thumbnail_id ); + if ( $post && $thumbnail_id && get_post( $thumbnail_id ) ) { + $thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'thumbnail' ); + if ( ! empty( $thumbnail_html ) ) { + update_post_meta( $post->ID, '_thumbnail_id', $thumbnail_id ); + return true; + } + } + return false; +} + +/** + * Returns a link to a post format index. + * + * @since 3.1.0 + * + * @param $format string Post format + * @return string Link + */ +function get_post_format_link( $format ) { + $term = get_term_by('slug', 'post-format-' . $format, 'post_format' ); + if ( ! $term || is_wp_error( $term ) ) + return false; + return get_term_link( $term ); +} + +/** + * Filters the request to allow for the format prefix. + * + * @access private + * @since 3.1.0 + */ +function _post_format_request( $qvs ) { + if ( ! isset( $qvs['post_format'] ) ) + return $qvs; + $slugs = get_post_format_slugs(); + if ( isset( $slugs[ $qvs['post_format'] ] ) ) + $qvs['post_format'] = 'post-format-' . $slugs[ $qvs['post_format'] ]; + $tax = get_taxonomy( 'post_format' ); + $qvs['post_type'] = $tax->object_type; + return $qvs; +} +add_filter( 'request', '_post_format_request' ); + +/** + * Filters the post format term link to remove the format prefix. + * + * @access private + * @since 3.1.0 + */ +function _post_format_link( $link, $term, $taxonomy ) { + global $wp_rewrite; + if ( 'post_format' != $taxonomy ) + return $link; + if ( $wp_rewrite->get_extra_permastruct( $taxonomy ) ) { + return str_replace( "/{$term->slug}", '/' . str_replace( 'post-format-', '', $term->slug ), $link ); + } else { + $link = remove_query_arg( 'post_format', $link ); + return add_query_arg( 'post_format', str_replace( 'post-format-', '', $term->slug ), $link ); + } +} +add_filter( 'term_link', '_post_format_link', 10, 3 ); + +/** + * Remove the post format prefix from the name property of the term object created by get_term(). + * + * @access private + * @since 3.1.0 + */ +function _post_format_get_term( $term ) { + if ( isset( $term->slug ) ) { + $term->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) ); + } + return $term; +} +add_filter( 'get_post_format', '_post_format_get_term' ); + +/** + * Remove the post format prefix from the name property of the term objects created by get_terms(). + * + * @access private + * @since 3.1.0 + */ +function _post_format_get_terms( $terms, $taxonomies, $args ) { + if ( in_array( 'post_format', (array) $taxonomies ) ) { + if ( isset( $args['fields'] ) && 'names' == $args['fields'] ) { + foreach( $terms as $order => $name ) { + $terms[$order] = get_post_format_string( str_replace( 'post-format-', '', $name ) ); + } + } else { + foreach ( (array) $terms as $order => $term ) { + if ( isset( $term->taxonomy ) && 'post_format' == $term->taxonomy ) { + $terms[$order]->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) ); + } + } + } + } + return $terms; +} +add_filter( 'get_terms', '_post_format_get_terms', 10, 3 ); + +/** + * Remove the post format prefix from the name property of the term objects created by wp_get_object_terms(). + * + * @access private + * @since 3.1.0 + */ +function _post_format_wp_get_object_terms( $terms ) { + foreach ( (array) $terms as $order => $term ) { + if ( isset( $term->taxonomy ) && 'post_format' == $term->taxonomy ) { + $terms[$order]->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) ); + } + } + return $terms; +} +add_filter( 'wp_get_object_terms', '_post_format_wp_get_object_terms' ); + +?> diff --git a/src/wp-includes/query.php b/src/wp-includes/query.php new file mode 100644 index 00000000..14942d94 --- /dev/null +++ b/src/wp-includes/query.php @@ -0,0 +1,3560 @@ +get($var); +} + + +/** + * Retrieve the currently-queried object. Wrapper for $wp_query->get_queried_object() + * + * @uses WP_Query::get_queried_object + * + * @since 3.1.0 + * @access public + * + * @return object + */ +function get_queried_object() { + global $wp_query; + return $wp_query->get_queried_object(); +} + +/** + * Retrieve ID of the current queried object. Wrapper for $wp_query->get_queried_object_id() + * + * @uses WP_Query::get_queried_object_id() + * + * @since 3.1.0 + * @access public + * + * @return int + */ +function get_queried_object_id() { + global $wp_query; + return $wp_query->get_queried_object_id(); +} + +/** + * Set query variable. + * + * @see WP_Query::set() + * @since 2.2.0 + * @uses $wp_query + * + * @param string $var Query variable key. + * @param mixed $value + * @return null + */ +function set_query_var($var, $value) { + global $wp_query; + + return $wp_query->set($var, $value); +} + +/** + * Set up The Loop with query parameters. + * + * This will override the current WordPress Loop and shouldn't be used more than + * once. This must not be used within the WordPress Loop. + * + * @since 1.5.0 + * @uses $wp_query + * + * @param string $query + * @return array List of posts + */ +function &query_posts($query) { + unset($GLOBALS['wp_query']); + $GLOBALS['wp_query'] =& new WP_Query(); + return $GLOBALS['wp_query']->query($query); +} + +/** + * Destroy the previous query and set up a new query. + * + * This should be used after {@link query_posts()} and before another {@link + * query_posts()}. This will remove obscure bugs that occur when the previous + * wp_query object is not destroyed properly before another is set up. + * + * @since 2.3.0 + * @uses $wp_query + */ +function wp_reset_query() { + unset($GLOBALS['wp_query']); + $GLOBALS['wp_query'] =& $GLOBALS['wp_the_query']; + wp_reset_postdata(); +} + +/** + * After looping through a separate query, this function restores + * the $post global to the current post in the main query + * + * @since 3.0.0 + * @uses $wp_query + */ +function wp_reset_postdata() { + global $wp_query; + if ( !empty($wp_query->post) ) { + $GLOBALS['post'] = $wp_query->post; + setup_postdata($wp_query->post); + } +} + +/* + * Query type checks. + */ + +/** + * Is the query for an archive page? + * + * Month, Year, Category, Author, Post Type archive... + * + * @see WP_Query::is_archive() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_archive() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_archive(); +} + +/** + * Is the query for a post type archive page? + * + * @see WP_Query::is_post_type_archive() + * @since 3.1.0 + * @uses $wp_query + * + * @param mixed $post_types Optional. Post type or array of posts types to check against. + * @return bool + */ +function is_post_type_archive( $post_types = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_post_type_archive( $post_types ); +} + +/** + * Is the query for an attachment page? + * + * @see WP_Query::is_attachment() + * @since 2.0.0 + * @uses $wp_query + * + * @return bool + */ +function is_attachment() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_attachment(); +} + +/** + * Is the query for an author archive page? + * + * If the $author parameter is specified, this function will additionally + * check if the query is for one of the authors specified. + * + * @see WP_Query::is_author() + * @since 1.5.0 + * @uses $wp_query + * + * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames + * @return bool + */ +function is_author( $author = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_author( $author ); +} + +/** + * Is the query for a category archive page? + * + * If the $category parameter is specified, this function will additionally + * check if the query is for one of the categories specified. + * + * @see WP_Query::is_category() + * @since 1.5.0 + * @uses $wp_query + * + * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs. + * @return bool + */ +function is_category( $category = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_category( $category ); +} + +/** + * Is the query for a tag archive page? + * + * If the $tag parameter is specified, this function will additionally + * check if the query is for one of the tags specified. + * + * @see WP_Query::is_tag() + * @since 2.3.0 + * @uses $wp_query + * + * @param mixed $slug Optional. Tag slug or array of slugs. + * @return bool + */ +function is_tag( $slug = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_tag( $slug ); +} + +/** + * Is the query for a taxonomy archive page? + * + * If the $taxonomy parameter is specified, this function will additionally + * check if the query is for that specific $taxonomy. + * + * If the $term parameter is specified in addition to the $taxonomy parameter, + * this function will additionally check if the query is for one of the terms + * specified. + * + * @see WP_Query::is_tax() + * @since 2.5.0 + * @uses $wp_query + * + * @param mixed $taxonomy Optional. Taxonomy slug or slugs. + * @param mixed $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs. + * @return bool + */ +function is_tax( $taxonomy = '', $term = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_tax( $taxonomy, $term ); +} + +/** + * Whether the current URL is within the comments popup window. + * + * @see WP_Query::is_comments_popup() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_comments_popup() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_comments_popup(); +} + +/** + * Is the query for a date archive? + * + * @see WP_Query::is_date() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_date() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_date(); +} + +/** + * Is the query for a day archive? + * + * @see WP_Query::is_day() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_day() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_day(); +} + +/** + * Is the query for a feed? + * + * @see WP_Query::is_feed() + * @since 1.5.0 + * @uses $wp_query + * + * @param string|array $feeds Optional feed types to check. + * @return bool + */ +function is_feed( $feeds = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_feed( $feeds ); +} + +/** + * Is the query for a comments feed? + * + * @see WP_Query::is_comments_feed() + * @since 3.0.0 + * @uses $wp_query + * + * @return bool + */ +function is_comment_feed() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_comment_feed(); +} + +/** + * Is the query for the front page of the site? + * + * This is for what is displayed at your site's main URL. + * + * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'. + * + * If you set a static page for the front page of your site, this function will return + * true when viewing that page. + * + * Otherwise the same as @see is_home() + * + * @see WP_Query::is_front_page() + * @since 2.5.0 + * @uses is_home() + * @uses get_option() + * + * @return bool True, if front of site. + */ +function is_front_page() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_front_page(); +} + +/** + * Is the query for the blog homepage? + * + * This is the page which shows the time based blog content of your site. + * + * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'. + * + * If you set a static page for the front page of your site, this function will return + * true only on the page you set as the "Posts page". + * + * @see is_front_page() + * + * @see WP_Query::is_home() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool True if blog view homepage. + */ +function is_home() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_home(); +} + +/** + * Is the query for a month archive? + * + * @see WP_Query::is_month() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_month() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_month(); +} + +/** + * Is the query for a single page? + * + * If the $page parameter is specified, this function will additionally + * check if the query is for one of the pages specified. + * + * @see is_single() + * @see is_singular() + * + * @see WP_Query::is_page() + * @since 1.5.0 + * @uses $wp_query + * + * @param mixed $page Page ID, title, slug, or array of such. + * @return bool + */ +function is_page( $page = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_page( $page ); +} + +/** + * Is the query for paged result and not for the first page? + * + * @see WP_Query::is_paged() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_paged() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_paged(); +} + +/** + * Is the query for a post or page preview? + * + * @see WP_Query::is_preview() + * @since 2.0.0 + * @uses $wp_query + * + * @return bool + */ +function is_preview() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_preview(); +} + +/** + * Is the query for the robots file? + * + * @see WP_Query::is_robots() + * @since 2.1.0 + * @uses $wp_query + * + * @return bool + */ +function is_robots() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_robots(); +} + +/** + * Is the query for a search? + * + * @see WP_Query::is_search() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_search() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_search(); +} + +/** + * Is the query for a single post? + * + * Works for any post type, except attachments and pages + * + * If the $post parameter is specified, this function will additionally + * check if the query is for one of the Posts specified. + * + * @see is_page() + * @see is_singular() + * + * @see WP_Query::is_single() + * @since 1.5.0 + * @uses $wp_query + * + * @param mixed $post Post ID, title, slug, or array of such. + * @return bool + */ +function is_single( $post = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_single( $post ); +} + +/** + * Is the query for a single post of any post type (post, attachment, page, ... )? + * + * If the $post_types parameter is specified, this function will additionally + * check if the query is for one of the Posts Types specified. + * + * @see is_page() + * @see is_single() + * + * @see WP_Query::is_singular() + * @since 1.5.0 + * @uses $wp_query + * + * @param mixed $post_types Optional. Post Type or array of Post Types + * @return bool + */ +function is_singular( $post_types = '' ) { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_singular( $post_types ); +} + +/** + * Is the query for a specific time? + * + * @see WP_Query::is_time() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_time() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_time(); +} + +/** + * Is the query for a trackback endpoint call? + * + * @see WP_Query::is_trackback() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_trackback() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_trackback(); +} + +/** + * Is the query for a specific year? + * + * @see WP_Query::is_year() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_year() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_year(); +} + +/** + * Is the query a 404 (returns no results)? + * + * @see WP_Query::is_404() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function is_404() { + global $wp_query; + + if ( ! isset( $wp_query ) ) { + _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' ); + return false; + } + + return $wp_query->is_404(); +} + +/* + * The Loop. Post loop control. + */ + +/** + * Whether current WordPress query has results to loop over. + * + * @see WP_Query::have_posts() + * @since 1.5.0 + * @uses $wp_query + * + * @return bool + */ +function have_posts() { + global $wp_query; + + return $wp_query->have_posts(); +} + +/** + * Whether the caller is in the Loop. + * + * @since 2.0.0 + * @uses $wp_query + * + * @return bool True if caller is within loop, false if loop hasn't started or ended. + */ +function in_the_loop() { + global $wp_query; + + return $wp_query->in_the_loop; +} + +/** + * Rewind the loop posts. + * + * @see WP_Query::rewind_posts() + * @since 1.5.0 + * @uses $wp_query + * + * @return null + */ +function rewind_posts() { + global $wp_query; + + return $wp_query->rewind_posts(); +} + +/** + * Iterate the post index in the loop. + * + * @see WP_Query::the_post() + * @since 1.5.0 + * @uses $wp_query + */ +function the_post() { + global $wp_query; + + $wp_query->the_post(); +} + +/* + * Comments loop. + */ + +/** + * Whether there are comments to loop over. + * + * @see WP_Query::have_comments() + * @since 2.2.0 + * @uses $wp_query + * + * @return bool + */ +function have_comments() { + global $wp_query; + return $wp_query->have_comments(); +} + +/** + * Iterate comment index in the comment loop. + * + * @see WP_Query::the_comment() + * @since 2.2.0 + * @uses $wp_query + * + * @return object + */ +function the_comment() { + global $wp_query; + return $wp_query->the_comment(); +} + +/* + * WP_Query + */ + +/** + * The WordPress Query class. + * + * @link http://codex.wordpress.org/Function_Reference/WP_Query Codex page. + * + * @since 1.5.0 + */ +class WP_Query { + + /** + * Query vars set by the user + * + * @since 1.5.0 + * @access public + * @var array + */ + var $query; + + /** + * Query vars, after parsing + * + * @since 1.5.0 + * @access public + * @var array + */ + var $query_vars = array(); + + /** + * Taxonomy query, as passed to get_tax_sql() + * + * @since 3.1.0 + * @access public + * @var object WP_Tax_Query + */ + var $tax_query; + + /** + * Holds the data for a single object that is queried. + * + * Holds the contents of a post, page, category, attachment. + * + * @since 1.5.0 + * @access public + * @var object|array + */ + var $queried_object; + + /** + * The ID of the queried object. + * + * @since 1.5.0 + * @access public + * @var int + */ + var $queried_object_id; + + /** + * Get post database query. + * + * @since 2.0.1 + * @access public + * @var string + */ + var $request; + + /** + * List of posts. + * + * @since 1.5.0 + * @access public + * @var array + */ + var $posts; + + /** + * The amount of posts for the current query. + * + * @since 1.5.0 + * @access public + * @var int + */ + var $post_count = 0; + + /** + * Index of the current item in the loop. + * + * @since 1.5.0 + * @access public + * @var int + */ + var $current_post = -1; + + /** + * Whether the loop has started and the caller is in the loop. + * + * @since 2.0.0 + * @access public + * @var bool + */ + var $in_the_loop = false; + + /** + * The current post ID. + * + * @since 1.5.0 + * @access public + * @var object + */ + var $post; + + /** + * The list of comments for current post. + * + * @since 2.2.0 + * @access public + * @var array + */ + var $comments; + + /** + * The amount of comments for the posts. + * + * @since 2.2.0 + * @access public + * @var int + */ + var $comment_count = 0; + + /** + * The index of the comment in the comment loop. + * + * @since 2.2.0 + * @access public + * @var int + */ + var $current_comment = -1; + + /** + * Current comment ID. + * + * @since 2.2.0 + * @access public + * @var int + */ + var $comment; + + /** + * Amount of posts if limit clause was not used. + * + * @since 2.1.0 + * @access public + * @var int + */ + var $found_posts = 0; + + /** + * The amount of pages. + * + * @since 2.1.0 + * @access public + * @var int + */ + var $max_num_pages = 0; + + /** + * The amount of comment pages. + * + * @since 2.7.0 + * @access public + * @var int + */ + var $max_num_comment_pages = 0; + + /** + * Set if query is single post. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_single = false; + + /** + * Set if query is preview of blog. + * + * @since 2.0.0 + * @access public + * @var bool + */ + var $is_preview = false; + + /** + * Set if query returns a page. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_page = false; + + /** + * Set if query is an archive list. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_archive = false; + + /** + * Set if query is part of a date. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_date = false; + + /** + * Set if query contains a year. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_year = false; + + /** + * Set if query contains a month. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_month = false; + + /** + * Set if query contains a day. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_day = false; + + /** + * Set if query contains time. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_time = false; + + /** + * Set if query contains an author. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_author = false; + + /** + * Set if query contains category. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_category = false; + + /** + * Set if query contains tag. + * + * @since 2.3.0 + * @access public + * @var bool + */ + var $is_tag = false; + + /** + * Set if query contains taxonomy. + * + * @since 2.5.0 + * @access public + * @var bool + */ + var $is_tax = false; + + /** + * Set if query was part of a search result. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_search = false; + + /** + * Set if query is feed display. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_feed = false; + + /** + * Set if query is comment feed display. + * + * @since 2.2.0 + * @access public + * @var bool + */ + var $is_comment_feed = false; + + /** + * Set if query is trackback. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_trackback = false; + + /** + * Set if query is blog homepage. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_home = false; + + /** + * Set if query couldn't found anything. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_404 = false; + + /** + * Set if query is within comments popup window. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_comments_popup = false; + + /** + * Set if query is paged + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_paged = false; + + /** + * Set if query is part of administration page. + * + * @since 1.5.0 + * @access public + * @var bool + */ + var $is_admin = false; + + /** + * Set if query is an attachment. + * + * @since 2.0.0 + * @access public + * @var bool + */ + var $is_attachment = false; + + /** + * Set if is single, is a page, or is an attachment. + * + * @since 2.1.0 + * @access public + * @var bool + */ + var $is_singular = false; + + /** + * Set if query is for robots. + * + * @since 2.1.0 + * @access public + * @var bool + */ + var $is_robots = false; + + /** + * Set if query contains posts. + * + * Basically, the homepage if the option isn't set for the static homepage. + * + * @since 2.1.0 + * @access public + * @var bool + */ + var $is_posts_page = false; + + /** + * Set if query is for a post type archive. + * + * @since 3.1.0 + * @access public + * @var bool + */ + var $is_post_type_archive = false; + + /** + * Stores the ->query_vars state like md5(serialize( $this->query_vars ) ) so we know + * whether we have to re-parse because something has changed + * + * @since 3.1.0 + * @access private + */ + var $query_vars_hash = false; + + /** + * Whether query vars have changed since the initial parse_query() call. Used to catch modifications to query vars made + * via pre_get_posts hooks. + * + * @since 3.1.1 + * @access private + */ + var $query_vars_changed = true; + + /** + * Resets query flags to false. + * + * The query flags are what page info WordPress was able to figure out. + * + * @since 2.0.0 + * @access private + */ + function init_query_flags() { + $this->is_single = false; + $this->is_preview = false; + $this->is_page = false; + $this->is_archive = false; + $this->is_date = false; + $this->is_year = false; + $this->is_month = false; + $this->is_day = false; + $this->is_time = false; + $this->is_author = false; + $this->is_category = false; + $this->is_tag = false; + $this->is_tax = false; + $this->is_search = false; + $this->is_feed = false; + $this->is_comment_feed = false; + $this->is_trackback = false; + $this->is_home = false; + $this->is_404 = false; + $this->is_comments_popup = false; + $this->is_paged = false; + $this->is_admin = false; + $this->is_attachment = false; + $this->is_singular = false; + $this->is_robots = false; + $this->is_posts_page = false; + $this->is_post_type_archive = false; + } + + /** + * Initiates object properties and sets default values. + * + * @since 1.5.0 + * @access public + */ + function init() { + unset($this->posts); + unset($this->query); + $this->query_vars = array(); + unset($this->queried_object); + unset($this->queried_object_id); + $this->post_count = 0; + $this->current_post = -1; + $this->in_the_loop = false; + unset( $this->request ); + unset( $this->post ); + unset( $this->comments ); + unset( $this->comment ); + $this->comment_count = 0; + $this->current_comment = -1; + $this->found_posts = 0; + $this->max_num_pages = 0; + $this->max_num_comment_pages = 0; + + $this->init_query_flags(); + } + + /** + * Reparse the query vars. + * + * @since 1.5.0 + * @access public + */ + function parse_query_vars() { + $this->parse_query(); + } + + /** + * Fills in the query variables, which do not exist within the parameter. + * + * @since 2.1.0 + * @access public + * + * @param array $array Defined query variables. + * @return array Complete query variables with undefined ones filled in empty. + */ + function fill_query_vars($array) { + $keys = array( + 'error' + , 'm' + , 'p' + , 'post_parent' + , 'subpost' + , 'subpost_id' + , 'attachment' + , 'attachment_id' + , 'name' + , 'static' + , 'pagename' + , 'page_id' + , 'second' + , 'minute' + , 'hour' + , 'day' + , 'monthnum' + , 'year' + , 'w' + , 'category_name' + , 'tag' + , 'cat' + , 'tag_id' + , 'author_name' + , 'feed' + , 'tb' + , 'paged' + , 'comments_popup' + , 'meta_key' + , 'meta_value' + , 'preview' + , 's' + , 'sentence' + , 'fields' + ); + + foreach ( $keys as $key ) { + if ( !isset($array[$key]) ) + $array[$key] = ''; + } + + $array_keys = array('category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in', + 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and'); + + foreach ( $array_keys as $key ) { + if ( !isset($array[$key]) ) + $array[$key] = array(); + } + return $array; + } + + /** + * Parse a query string and set query type booleans. + * + * @since 1.5.0 + * @access public + * + * @param string|array $query Optional query. + */ + function parse_query( $query = '' ) { + if ( ! empty( $query ) ) { + $this->init(); + $this->query = $this->query_vars = wp_parse_args( $query ); + } elseif ( ! isset( $this->query ) ) { + $this->query = $this->query_vars; + } + + $this->query_vars = $this->fill_query_vars($this->query_vars); + $qv = &$this->query_vars; + $this->query_vars_changed = true; + + if ( ! empty($qv['robots']) ) + $this->is_robots = true; + + $qv['p'] = absint($qv['p']); + $qv['page_id'] = absint($qv['page_id']); + $qv['year'] = absint($qv['year']); + $qv['monthnum'] = absint($qv['monthnum']); + $qv['day'] = absint($qv['day']); + $qv['w'] = absint($qv['w']); + $qv['m'] = absint($qv['m']); + $qv['paged'] = absint($qv['paged']); + $qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers + $qv['pagename'] = trim( $qv['pagename'] ); + $qv['name'] = trim( $qv['name'] ); + if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']); + if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']); + if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']); + + // Compat. Map subpost to attachment. + if ( '' != $qv['subpost'] ) + $qv['attachment'] = $qv['subpost']; + if ( '' != $qv['subpost_id'] ) + $qv['attachment_id'] = $qv['subpost_id']; + + $qv['attachment_id'] = absint($qv['attachment_id']); + + if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) { + $this->is_single = true; + $this->is_attachment = true; + } elseif ( '' != $qv['name'] ) { + $this->is_single = true; + } elseif ( $qv['p'] ) { + $this->is_single = true; + } elseif ( ('' !== $qv['hour']) && ('' !== $qv['minute']) &&('' !== $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day']) ) { + // If year, month, day, hour, minute, and second are set, a single + // post is being queried. + $this->is_single = true; + } elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) { + $this->is_page = true; + $this->is_single = false; + } else { + // Look for archive queries. Dates, categories, authors, search, post type archives. + + if ( !empty($qv['s']) ) { + $this->is_search = true; + } + + if ( '' !== $qv['second'] ) { + $this->is_time = true; + $this->is_date = true; + } + + if ( '' !== $qv['minute'] ) { + $this->is_time = true; + $this->is_date = true; + } + + if ( '' !== $qv['hour'] ) { + $this->is_time = true; + $this->is_date = true; + } + + if ( $qv['day'] ) { + if ( ! $this->is_date ) { + $this->is_day = true; + $this->is_date = true; + } + } + + if ( $qv['monthnum'] ) { + if ( ! $this->is_date ) { + $this->is_month = true; + $this->is_date = true; + } + } + + if ( $qv['year'] ) { + if ( ! $this->is_date ) { + $this->is_year = true; + $this->is_date = true; + } + } + + if ( $qv['m'] ) { + $this->is_date = true; + if ( strlen($qv['m']) > 9 ) { + $this->is_time = true; + } else if ( strlen($qv['m']) > 7 ) { + $this->is_day = true; + } else if ( strlen($qv['m']) > 5 ) { + $this->is_month = true; + } else { + $this->is_year = true; + } + } + + if ( '' != $qv['w'] ) { + $this->is_date = true; + } + + $this->query_vars_hash = false; + $this->parse_tax_query( $qv ); + + foreach ( $this->tax_query->queries as $tax_query ) { + if ( 'NOT IN' != $tax_query['operator'] ) { + switch ( $tax_query['taxonomy'] ) { + case 'category': + $this->is_category = true; + break; + case 'post_tag': + $this->is_tag = true; + break; + default: + $this->is_tax = true; + } + } + } + unset( $tax_query ); + + _parse_meta_query( $qv ); + + if ( empty($qv['author']) || ($qv['author'] == '0') ) { + $this->is_author = false; + } else { + $this->is_author = true; + } + + if ( '' != $qv['author_name'] ) + $this->is_author = true; + + if ( !empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) { + $post_type_obj = get_post_type_object( $qv['post_type'] ); + if ( ! empty( $post_type_obj->has_archive ) ) + $this->is_post_type_archive = true; + } + + if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax ) + $this->is_archive = true; + } + + if ( '' != $qv['feed'] ) + $this->is_feed = true; + + if ( '' != $qv['tb'] ) + $this->is_trackback = true; + + if ( '' != $qv['paged'] && ( intval($qv['paged']) > 1 ) ) + $this->is_paged = true; + + if ( '' != $qv['comments_popup'] ) + $this->is_comments_popup = true; + + // if we're previewing inside the write screen + if ( '' != $qv['preview'] ) + $this->is_preview = true; + + if ( is_admin() ) + $this->is_admin = true; + + if ( false !== strpos($qv['feed'], 'comments-') ) { + $qv['feed'] = str_replace('comments-', '', $qv['feed']); + $qv['withcomments'] = 1; + } + + $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; + + if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) ) + $this->is_comment_feed = true; + + if ( !( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_comments_popup || $this->is_robots ) ) + $this->is_home = true; + + // Correct is_* for page_on_front and page_for_posts + if ( $this->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front') ) { + $_query = wp_parse_args($this->query); + // pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename. + if ( isset($_query['pagename']) && '' == $_query['pagename'] ) + unset($_query['pagename']); + if ( empty($_query) || !array_diff( array_keys($_query), array('preview', 'page', 'paged', 'cpage') ) ) { + $this->is_page = true; + $this->is_home = false; + $qv['page_id'] = get_option('page_on_front'); + // Correct for page_on_front + if ( !empty($qv['paged']) ) { + $qv['page'] = $qv['paged']; + unset($qv['paged']); + } + } + } + + if ( '' != $qv['pagename'] ) { + $this->queried_object =& get_page_by_path($qv['pagename']); + if ( !empty($this->queried_object) ) + $this->queried_object_id = (int) $this->queried_object->ID; + else + unset($this->queried_object); + + if ( 'page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts') ) { + $this->is_page = false; + $this->is_home = true; + $this->is_posts_page = true; + } + } + + if ( $qv['page_id'] ) { + if ( 'page' == get_option('show_on_front') && $qv['page_id'] == get_option('page_for_posts') ) { + $this->is_page = false; + $this->is_home = true; + $this->is_posts_page = true; + } + } + + if ( !empty($qv['post_type']) ) { + if ( is_array($qv['post_type']) ) + $qv['post_type'] = array_map('sanitize_key', $qv['post_type']); + else + $qv['post_type'] = sanitize_key($qv['post_type']); + } + + if ( !empty($qv['post_status']) ) + $qv['post_status'] = preg_replace('|[^a-z0-9_,-]|', '', $qv['post_status']); + + if ( $this->is_posts_page && ( ! isset($qv['withcomments']) || ! $qv['withcomments'] ) ) + $this->is_comment_feed = false; + + $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; + // Done correcting is_* for page_on_front and page_for_posts + + if ( '404' == $qv['error'] ) + $this->set_404(); + + $this->query_vars_hash = md5( serialize( $this->query_vars ) ); + $this->query_vars_changed = false; + + do_action_ref_array('parse_query', array(&$this)); + } + + /* + * Parses various taxonomy related query vars. + * + * @access protected + * @since 3.1.0 + * + * @param array &$q The query variables + */ + function parse_tax_query( &$q ) { + if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) { + $tax_query = $q['tax_query']; + } else { + $tax_query = array(); + } + + if ( !empty($q['taxonomy']) && !empty($q['term']) ) { + $tax_query[] = array( + 'taxonomy' => $q['taxonomy'], + 'terms' => array( $q['term'] ), + 'field' => 'slug', + ); + } + + foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) { + if ( 'post_tag' == $taxonomy ) + continue; // Handled further down in the $q['tag'] block + + if ( $t->query_var && !empty( $q[$t->query_var] ) ) { + $tax_query_defaults = array( + 'taxonomy' => $taxonomy, + 'field' => 'slug', + ); + + if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) { + $q[$t->query_var] = wp_basename( $q[$t->query_var] ); + } + + $term = $q[$t->query_var]; + + if ( strpos($term, '+') !== false ) { + $terms = preg_split( '/[+]+/', $term ); + foreach ( $terms as $term ) { + $tax_query[] = array_merge( $tax_query_defaults, array( + 'terms' => array( $term ) + ) ); + } + } else { + $tax_query[] = array_merge( $tax_query_defaults, array( + 'terms' => preg_split( '/[,]+/', $term ) + ) ); + } + } + } + + // Category stuff + if ( !empty($q['cat']) && '0' != $q['cat'] && !$this->is_singular && $this->query_vars_changed ) { + $q['cat'] = ''.urldecode($q['cat']).''; + $q['cat'] = addslashes_gpc($q['cat']); + $cat_array = preg_split('/[,\s]+/', $q['cat']); + $q['cat'] = ''; + $req_cats = array(); + foreach ( (array) $cat_array as $cat ) { + $cat = intval($cat); + $req_cats[] = $cat; + $in = ($cat > 0); + $cat = abs($cat); + if ( $in ) { + $q['category__in'][] = $cat; + $q['category__in'] = array_merge( $q['category__in'], get_term_children($cat, 'category') ); + } else { + $q['category__not_in'][] = $cat; + $q['category__not_in'] = array_merge( $q['category__not_in'], get_term_children($cat, 'category') ); + } + } + $q['cat'] = implode(',', $req_cats); + } + + if ( !empty($q['category__in']) ) { + $q['category__in'] = array_map('absint', array_unique( (array) $q['category__in'] ) ); + $tax_query[] = array( + 'taxonomy' => 'category', + 'terms' => $q['category__in'], + 'field' => 'term_id', + 'include_children' => false + ); + } + + if ( !empty($q['category__not_in']) ) { + $q['category__not_in'] = array_map('absint', array_unique( (array) $q['category__not_in'] ) ); + $tax_query[] = array( + 'taxonomy' => 'category', + 'terms' => $q['category__not_in'], + 'operator' => 'NOT IN', + 'include_children' => false + ); + } + + if ( !empty($q['category__and']) ) { + $q['category__and'] = array_map('absint', array_unique( (array) $q['category__and'] ) ); + $tax_query[] = array( + 'taxonomy' => 'category', + 'terms' => $q['category__and'], + 'field' => 'term_id', + 'operator' => 'AND', + 'include_children' => false + ); + } + + // Tag stuff + if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) { + if ( strpos($q['tag'], ',') !== false ) { + $tags = preg_split('/[,\s]+/', $q['tag']); + foreach ( (array) $tags as $tag ) { + $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); + $q['tag_slug__in'][] = $tag; + } + } else if ( preg_match('/[+\s]+/', $q['tag']) || !empty($q['cat']) ) { + $tags = preg_split('/[+\s]+/', $q['tag']); + foreach ( (array) $tags as $tag ) { + $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); + $q['tag_slug__and'][] = $tag; + } + } else { + $q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db'); + $q['tag_slug__in'][] = $q['tag']; + } + } + + if ( !empty($q['tag_id']) ) { + $q['tag_id'] = absint( $q['tag_id'] ); + $tax_query[] = array( + 'taxonomy' => 'post_tag', + 'terms' => $q['tag_id'] + ); + } + + if ( !empty($q['tag__in']) ) { + $q['tag__in'] = array_map('absint', array_unique( (array) $q['tag__in'] ) ); + $tax_query[] = array( + 'taxonomy' => 'post_tag', + 'terms' => $q['tag__in'] + ); + } + + if ( !empty($q['tag__not_in']) ) { + $q['tag__not_in'] = array_map('absint', array_unique( (array) $q['tag__not_in'] ) ); + $tax_query[] = array( + 'taxonomy' => 'post_tag', + 'terms' => $q['tag__not_in'], + 'operator' => 'NOT IN' + ); + } + + if ( !empty($q['tag__and']) ) { + $q['tag__and'] = array_map('absint', array_unique( (array) $q['tag__and'] ) ); + $tax_query[] = array( + 'taxonomy' => 'post_tag', + 'terms' => $q['tag__and'], + 'operator' => 'AND' + ); + } + + if ( !empty($q['tag_slug__in']) ) { + $q['tag_slug__in'] = array_map('sanitize_title', array_unique( (array) $q['tag_slug__in'] ) ); + $tax_query[] = array( + 'taxonomy' => 'post_tag', + 'terms' => $q['tag_slug__in'], + 'field' => 'slug' + ); + } + + if ( !empty($q['tag_slug__and']) ) { + $q['tag_slug__and'] = array_map('sanitize_title', array_unique( (array) $q['tag_slug__and'] ) ); + $tax_query[] = array( + 'taxonomy' => 'post_tag', + 'terms' => $q['tag_slug__and'], + 'field' => 'slug', + 'operator' => 'AND' + ); + } + + $this->tax_query = new WP_Tax_Query( $tax_query ); + } + + /** + * Sets the 404 property and saves whether query is feed. + * + * @since 2.0.0 + * @access public + */ + function set_404() { + $is_feed = $this->is_feed; + + $this->init_query_flags(); + $this->is_404 = true; + + $this->is_feed = $is_feed; + } + + /** + * Retrieve query variable. + * + * @since 1.5.0 + * @access public + * + * @param string $query_var Query variable key. + * @return mixed + */ + function get($query_var) { + if ( isset($this->query_vars[$query_var]) ) + return $this->query_vars[$query_var]; + + return ''; + } + + /** + * Set query variable. + * + * @since 1.5.0 + * @access public + * + * @param string $query_var Query variable key. + * @param mixed $value Query variable value. + */ + function set($query_var, $value) { + $this->query_vars[$query_var] = $value; + } + + /** + * Retrieve the posts based on query variables. + * + * There are a few filters and actions that can be used to modify the post + * database query. + * + * @since 1.5.0 + * @access public + * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts. + * + * @return array List of posts. + */ + function &get_posts() { + global $wpdb, $user_ID, $_wp_using_ext_object_cache; + + $this->parse_query(); + + do_action_ref_array('pre_get_posts', array(&$this)); + + // Shorthand. + $q = &$this->query_vars; + + // Fill again in case pre_get_posts unset some vars. + $q = $this->fill_query_vars($q); + + // Set a flag if a pre_get_posts hook changed the query vars. + $hash = md5( serialize( $this->query_vars ) ); + if ( $hash != $this->query_vars_hash ) { + $this->query_vars_changed = true; + $this->query_vars_hash = $hash; + } + unset($hash); + + // First let's clear some variables + $distinct = ''; + $whichauthor = ''; + $whichmimetype = ''; + $where = ''; + $limits = ''; + $join = ''; + $search = ''; + $groupby = ''; + $fields = ''; + $post_status_join = false; + $page = 1; + + if ( isset( $q['caller_get_posts'] ) ) { + _deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) ); + if ( !isset( $q['ignore_sticky_posts'] ) ) + $q['ignore_sticky_posts'] = $q['caller_get_posts']; + } + + if ( !isset( $q['ignore_sticky_posts'] ) ) + $q['ignore_sticky_posts'] = false; + + if ( !isset($q['suppress_filters']) ) + $q['suppress_filters'] = false; + + if ( !isset($q['cache_results']) ) { + if ( $_wp_using_ext_object_cache ) + $q['cache_results'] = false; + else + $q['cache_results'] = true; + } + + if ( !isset($q['update_post_term_cache']) ) + $q['update_post_term_cache'] = true; + + if ( !isset($q['update_post_meta_cache']) ) + $q['update_post_meta_cache'] = true; + + if ( !isset($q['post_type']) ) { + if ( $this->is_search ) + $q['post_type'] = 'any'; + else + $q['post_type'] = ''; + } + $post_type = $q['post_type']; + if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 ) + $q['posts_per_page'] = get_option('posts_per_page'); + if ( isset($q['showposts']) && $q['showposts'] ) { + $q['showposts'] = (int) $q['showposts']; + $q['posts_per_page'] = $q['showposts']; + } + if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) ) + $q['posts_per_page'] = $q['posts_per_archive_page']; + if ( !isset($q['nopaging']) ) { + if ( $q['posts_per_page'] == -1 ) { + $q['nopaging'] = true; + } else { + $q['nopaging'] = false; + } + } + if ( $this->is_feed ) { + $q['posts_per_page'] = get_option('posts_per_rss'); + $q['nopaging'] = false; + } + $q['posts_per_page'] = (int) $q['posts_per_page']; + if ( $q['posts_per_page'] < -1 ) + $q['posts_per_page'] = abs($q['posts_per_page']); + else if ( $q['posts_per_page'] == 0 ) + $q['posts_per_page'] = 1; + + if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 ) + $q['comments_per_page'] = get_option('comments_per_page'); + + if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) { + $this->is_page = true; + $this->is_home = false; + $q['page_id'] = get_option('page_on_front'); + } + + if ( isset($q['page']) ) { + $q['page'] = trim($q['page'], '/'); + $q['page'] = absint($q['page']); + } + + // If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present. + if ( isset($q['no_found_rows']) ) + $q['no_found_rows'] = (bool) $q['no_found_rows']; + else + $q['no_found_rows'] = false; + + switch ( $q['fields'] ) { + case 'ids': + $fields = "$wpdb->posts.ID"; + break; + case 'id=>parent': + $fields = "$wpdb->posts.ID, $wpdb->posts.post_parent"; + break; + default: + $fields = "$wpdb->posts.*"; + } + + // If a month is specified in the querystring, load that month + if ( $q['m'] ) { + $q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']); + $where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4); + if ( strlen($q['m']) > 5 ) + $where .= " AND MONTH($wpdb->posts.post_date)=" . substr($q['m'], 4, 2); + if ( strlen($q['m']) > 7 ) + $where .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($q['m'], 6, 2); + if ( strlen($q['m']) > 9 ) + $where .= " AND HOUR($wpdb->posts.post_date)=" . substr($q['m'], 8, 2); + if ( strlen($q['m']) > 11 ) + $where .= " AND MINUTE($wpdb->posts.post_date)=" . substr($q['m'], 10, 2); + if ( strlen($q['m']) > 13 ) + $where .= " AND SECOND($wpdb->posts.post_date)=" . substr($q['m'], 12, 2); + } + + if ( '' !== $q['hour'] ) + $where .= " AND HOUR($wpdb->posts.post_date)='" . $q['hour'] . "'"; + + if ( '' !== $q['minute'] ) + $where .= " AND MINUTE($wpdb->posts.post_date)='" . $q['minute'] . "'"; + + if ( '' !== $q['second'] ) + $where .= " AND SECOND($wpdb->posts.post_date)='" . $q['second'] . "'"; + + if ( $q['year'] ) + $where .= " AND YEAR($wpdb->posts.post_date)='" . $q['year'] . "'"; + + if ( $q['monthnum'] ) + $where .= " AND MONTH($wpdb->posts.post_date)='" . $q['monthnum'] . "'"; + + if ( $q['day'] ) + $where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'"; + + // If we've got a post_type AND its not "any" post_type. + if ( !empty($q['post_type']) && 'any' != $q['post_type'] ) { + foreach ( (array)$q['post_type'] as $_post_type ) { + $ptype_obj = get_post_type_object($_post_type); + if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) ) + continue; + + if ( ! $ptype_obj->hierarchical || strpos($q[ $ptype_obj->query_var ], '/') === false ) { + // Non-hierarchical post_types & parent-level-hierarchical post_types can directly use 'name' + $q['name'] = $q[ $ptype_obj->query_var ]; + } else { + // Hierarchical post_types will operate through the + $q['pagename'] = $q[ $ptype_obj->query_var ]; + $q['name'] = ''; + } + + // Only one request for a slug is possible, this is why name & pagename are overwritten above. + break; + } //end foreach + unset($ptype_obj); + } + + if ( '' != $q['name'] ) { + $q['name'] = sanitize_title_for_query( $q['name'] ); + $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'"; + } elseif ( '' != $q['pagename'] ) { + if ( isset($this->queried_object_id) ) { + $reqpage = $this->queried_object_id; + } else { + if ( 'page' != $q['post_type'] ) { + foreach ( (array)$q['post_type'] as $_post_type ) { + $ptype_obj = get_post_type_object($_post_type); + if ( !$ptype_obj || !$ptype_obj->hierarchical ) + continue; + + $reqpage = get_page_by_path($q['pagename'], OBJECT, $_post_type); + if ( $reqpage ) + break; + } + unset($ptype_obj); + } else { + $reqpage = get_page_by_path($q['pagename']); + } + if ( !empty($reqpage) ) + $reqpage = $reqpage->ID; + else + $reqpage = 0; + } + + $page_for_posts = get_option('page_for_posts'); + if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) { + $q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) ); + $q['name'] = $q['pagename']; + $where .= " AND ($wpdb->posts.ID = '$reqpage')"; + $reqpage_obj = get_page($reqpage); + if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) { + $this->is_attachment = true; + $post_type = $q['post_type'] = 'attachment'; + $this->is_page = true; + $q['attachment_id'] = $reqpage; + } + } + } elseif ( '' != $q['attachment'] ) { + $q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) ); + $q['name'] = $q['attachment']; + $where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'"; + } + + if ( $q['w'] ) + $where .= ' AND ' . _wp_mysql_week( "`$wpdb->posts`.`post_date`" ) . " = '" . $q['w'] . "'"; + + if ( intval($q['comments_popup']) ) + $q['p'] = absint($q['comments_popup']); + + // If an attachment is requested by number, let it supercede any post number. + if ( $q['attachment_id'] ) + $q['p'] = absint($q['attachment_id']); + + // If a post number is specified, load that post + if ( $q['p'] ) { + $where .= " AND {$wpdb->posts}.ID = " . $q['p']; + } elseif ( $q['post__in'] ) { + $post__in = implode(',', array_map( 'absint', $q['post__in'] )); + $where .= " AND {$wpdb->posts}.ID IN ($post__in)"; + } elseif ( $q['post__not_in'] ) { + $post__not_in = implode(',', array_map( 'absint', $q['post__not_in'] )); + $where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)"; + } + + if ( is_numeric($q['post_parent']) ) + $where .= $wpdb->prepare( " AND $wpdb->posts.post_parent = %d ", $q['post_parent'] ); + + if ( $q['page_id'] ) { + if ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) { + $q['p'] = $q['page_id']; + $where = " AND {$wpdb->posts}.ID = " . $q['page_id']; + } + } + + // If a search pattern is specified, load the posts that match + if ( !empty($q['s']) ) { + // added slashes screw with quote grouping when done early, so done later + $q['s'] = stripslashes($q['s']); + if ( !empty($q['sentence']) ) { + $q['search_terms'] = array($q['s']); + } else { + preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q['s'], $matches); + $q['search_terms'] = array_map('_search_terms_tidy', $matches[0]); + } + $n = !empty($q['exact']) ? '' : '%'; + $searchand = ''; + foreach( (array) $q['search_terms'] as $term ) { + $term = esc_sql( like_escape( $term ) ); + $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))"; + $searchand = ' AND '; + } + $term = esc_sql( like_escape( $q['s'] ) ); + if ( empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] ) + $search .= " OR ($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')"; + + if ( !empty($search) ) { + $search = " AND ({$search}) "; + if ( !is_user_logged_in() ) + $search .= " AND ($wpdb->posts.post_password = '') "; + } + } + + // Allow plugins to contextually add/remove/modify the search section of the database query + $search = apply_filters_ref_array('posts_search', array( $search, &$this ) ); + + // Taxonomies + if ( !$this->is_singular ) { + $this->parse_tax_query( $q ); + + $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' ); + + $join .= $clauses['join']; + $where .= $clauses['where']; + } + + if ( $this->is_tax ) { + if ( empty($post_type) ) { + $post_type = 'any'; + $post_status_join = true; + } elseif ( in_array('attachment', (array) $post_type) ) { + $post_status_join = true; + } + } + + // Back-compat + if ( !empty($this->tax_query->queries) ) { + $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' ); + if ( !empty( $tax_query_in_and ) ) { + if ( !isset( $q['taxonomy'] ) ) { + foreach ( $tax_query_in_and as $a_tax_query ) { + if ( !in_array( $a_tax_query['taxonomy'], array( 'category', 'post_tag' ) ) ) { + $q['taxonomy'] = $a_tax_query['taxonomy']; + if ( 'slug' == $a_tax_query['field'] ) + $q['term'] = $a_tax_query['terms'][0]; + else + $q['term_id'] = $a_tax_query['terms'][0]; + + break; + } + } + } + + $cat_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'category' ) ); + if ( !empty( $cat_query ) ) { + $cat_query = reset( $cat_query ); + $the_cat = get_term_by( $cat_query['field'], $cat_query['terms'][0], 'category' ); + if ( $the_cat ) { + $this->set( 'cat', $the_cat->term_id ); + $this->set( 'category_name', $the_cat->slug ); + } + unset( $the_cat ); + } + unset( $cat_query ); + + $tag_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'post_tag' ) ); + if ( !empty( $tag_query ) ) { + $tag_query = reset( $tag_query ); + $the_tag = get_term_by( $tag_query['field'], $tag_query['terms'][0], 'post_tag' ); + if ( $the_tag ) { + $this->set( 'tag_id', $the_tag->term_id ); + } + unset( $the_tag ); + } + unset( $tag_query ); + } + } + + // Author/user stuff + + if ( empty($q['author']) || ($q['author'] == '0') ) { + $whichauthor = ''; + } else { + $q['author'] = (string)urldecode($q['author']); + $q['author'] = addslashes_gpc($q['author']); + if ( strpos($q['author'], '-') !== false ) { + $eq = '!='; + $andor = 'AND'; + $q['author'] = explode('-', $q['author']); + $q['author'] = (string)absint($q['author'][1]); + } else { + $eq = '='; + $andor = 'OR'; + } + $author_array = preg_split('/[,\s]+/', $q['author']); + $_author_array = array(); + foreach ( $author_array as $key => $_author ) + $_author_array[] = "$wpdb->posts.post_author " . $eq . ' ' . absint($_author); + $whichauthor .= ' AND (' . implode(" $andor ", $_author_array) . ')'; + unset($author_array, $_author_array); + } + + // Author stuff for nice URLs + + if ( '' != $q['author_name'] ) { + if ( strpos($q['author_name'], '/') !== false ) { + $q['author_name'] = explode('/', $q['author_name']); + if ( $q['author_name'][ count($q['author_name'])-1 ] ) { + $q['author_name'] = $q['author_name'][count($q['author_name'])-1]; // no trailing slash + } else { + $q['author_name'] = $q['author_name'][count($q['author_name'])-2]; // there was a trailling slash + } + } + $q['author_name'] = sanitize_title_for_query( $q['author_name'] ); + $q['author'] = get_user_by('slug', $q['author_name']); + if ( $q['author'] ) + $q['author'] = $q['author']->ID; + $whichauthor .= " AND ($wpdb->posts.post_author = " . absint($q['author']) . ')'; + } + + // MIME-Type stuff for attachment browsing + + if ( isset($q['post_mime_type']) && '' != $q['post_mime_type'] ) { + $table_alias = $post_status_join ? $wpdb->posts : ''; + $whichmimetype = wp_post_mime_type_where($q['post_mime_type'], $table_alias); + } + + $where .= $search . $whichauthor . $whichmimetype; + + if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) ) + $q['order'] = 'DESC'; + + // Order by + if ( empty($q['orderby']) ) { + $q['orderby'] = "$wpdb->posts.post_date " . $q['order']; + } elseif ( 'none' == $q['orderby'] ) { + $q['orderby'] = ''; + } else { + // Used to filter values + $allowed_keys = array('author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count'); + if ( !empty($q['meta_key']) ) { + $allowed_keys[] = $q['meta_key']; + $allowed_keys[] = 'meta_value'; + $allowed_keys[] = 'meta_value_num'; + } + $q['orderby'] = urldecode($q['orderby']); + $q['orderby'] = addslashes_gpc($q['orderby']); + $orderby_array = explode(' ', $q['orderby']); + $q['orderby'] = ''; + + foreach ( $orderby_array as $i => $orderby ) { + // Only allow certain values for safety + if ( ! in_array($orderby, $allowed_keys) ) + continue; + + switch ( $orderby ) { + case 'menu_order': + break; + case 'ID': + $orderby = "$wpdb->posts.ID"; + break; + case 'rand': + $orderby = 'RAND()'; + break; + case $q['meta_key']: + case 'meta_value': + $orderby = "$wpdb->postmeta.meta_value"; + break; + case 'meta_value_num': + $orderby = "$wpdb->postmeta.meta_value+0"; + break; + case 'comment_count': + $orderby = "$wpdb->posts.comment_count"; + break; + default: + $orderby = "$wpdb->posts.post_" . $orderby; + } + + $q['orderby'] .= (($i == 0) ? '' : ',') . $orderby; + } + + // append ASC or DESC at the end + if ( !empty($q['orderby'])) + $q['orderby'] .= " {$q['order']}"; + + if ( empty($q['orderby']) ) + $q['orderby'] = "$wpdb->posts.post_date ".$q['order']; + } + + if ( is_array( $post_type ) ) { + $post_type_cap = 'multiple_post_type'; + } else { + $post_type_object = get_post_type_object( $post_type ); + if ( empty( $post_type_object ) ) + $post_type_cap = $post_type; + } + + $exclude_post_types = ''; + $in_search_post_types = get_post_types( array('exclude_from_search' => false) ); + if ( ! empty( $in_search_post_types ) ) + $exclude_post_types .= $wpdb->prepare(" AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')"); + + if ( 'any' == $post_type ) { + $where .= $exclude_post_types; + } elseif ( !empty( $post_type ) && is_array( $post_type ) ) { + $where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')"; + } elseif ( ! empty( $post_type ) ) { + $where .= " AND $wpdb->posts.post_type = '$post_type'"; + $post_type_object = get_post_type_object ( $post_type ); + } elseif ( $this->is_attachment ) { + $where .= " AND $wpdb->posts.post_type = 'attachment'"; + $post_type_object = get_post_type_object ( 'attachment' ); + } elseif ( $this->is_page ) { + $where .= " AND $wpdb->posts.post_type = 'page'"; + $post_type_object = get_post_type_object ( 'page' ); + } else { + $where .= " AND $wpdb->posts.post_type = 'post'"; + $post_type_object = get_post_type_object ( 'post' ); + } + + if ( ! empty( $post_type_object ) ) { + $edit_cap = $post_type_object->cap->edit_post; + $read_cap = $post_type_object->cap->read_post; + $edit_others_cap = $post_type_object->cap->edit_others_posts; + $read_private_cap = $post_type_object->cap->read_private_posts; + } else { + $edit_cap = 'edit_' . $post_type_cap; + $read_cap = 'read_' . $post_type_cap; + $edit_others_cap = 'edit_others_' . $post_type_cap . 's'; + $read_private_cap = 'read_private_' . $post_type_cap . 's'; + } + + if ( isset($q['post_status']) && '' != $q['post_status'] ) { + $statuswheres = array(); + $q_status = explode(',', $q['post_status']); + $r_status = array(); + $p_status = array(); + $e_status = array(); + if ( $q['post_status'] == 'any' ) { + foreach ( get_post_stati( array('exclude_from_search' => true) ) as $status ) + $e_status[] = "$wpdb->posts.post_status <> '$status'"; + } else { + foreach ( get_post_stati() as $status ) { + if ( in_array( $status, $q_status ) ) { + if ( 'private' == $status ) + $p_status[] = "$wpdb->posts.post_status = '$status'"; + else + $r_status[] = "$wpdb->posts.post_status = '$status'"; + } + } + } + + if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) { + $r_status = array_merge($r_status, $p_status); + unset($p_status); + } + + if ( !empty($e_status) ) { + $statuswheres[] = "(" . join( ' AND ', $e_status ) . ")"; + } + if ( !empty($r_status) ) { + if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can($edit_others_cap) ) + $statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $r_status ) . "))"; + else + $statuswheres[] = "(" . join( ' OR ', $r_status ) . ")"; + } + if ( !empty($p_status) ) { + if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can($read_private_cap) ) + $statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $p_status ) . "))"; + else + $statuswheres[] = "(" . join( ' OR ', $p_status ) . ")"; + } + if ( $post_status_join ) { + $join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) "; + foreach ( $statuswheres as $index => $statuswhere ) + $statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))"; + } + foreach ( $statuswheres as $statuswhere ) + $where .= " AND $statuswhere"; + } elseif ( !$this->is_singular ) { + $where .= " AND ($wpdb->posts.post_status = 'publish'"; + + // Add public states. + $public_states = get_post_stati( array('public' => true) ); + foreach ( (array) $public_states as $state ) { + if ( 'publish' == $state ) // Publish is hard-coded above. + continue; + $where .= " OR $wpdb->posts.post_status = '$state'"; + } + + if ( is_admin() ) { + // Add protected states that should show in the admin all list. + $admin_all_states = get_post_stati( array('protected' => true, 'show_in_admin_all_list' => true) ); + foreach ( (array) $admin_all_states as $state ) + $where .= " OR $wpdb->posts.post_status = '$state'"; + } + + if ( is_user_logged_in() ) { + // Add private states that are limited to viewing by the author of a post or someone who has caps to read private states. + $private_states = get_post_stati( array('private' => true) ); + foreach ( (array) $private_states as $state ) + $where .= current_user_can( $read_private_cap ) ? " OR $wpdb->posts.post_status = '$state'" : " OR $wpdb->posts.post_author = $user_ID AND $wpdb->posts.post_status = '$state'"; + } + + $where .= ')'; + } + + // Parse the meta query again if query vars have changed. + if ( $this->query_vars_changed ) { + $meta_query_hash = md5( serialize( $q['meta_query'] ) ); + $_meta_query = $q['meta_query']; + unset( $q['meta_query'] ); + _parse_meta_query( $q ); + if ( md5( serialize( $q['meta_query'] ) ) != $meta_query_hash && is_array( $_meta_query ) ) + $q['meta_query'] = array_merge( $_meta_query, $q['meta_query'] ); + } + + if ( !empty( $q['meta_query'] ) ) { + $clauses = call_user_func_array( '_get_meta_sql', array( $q['meta_query'], 'post', $wpdb->posts, 'ID', &$this) ); + $join .= $clauses['join']; + $where .= $clauses['where']; + } + + if ( ! empty( $this->tax_query->queries ) || ! empty( $q['meta_query'] ) ) { + $groupby = "{$wpdb->posts}.ID"; + } + + // Apply filters on where and join prior to paging so that any + // manipulations to them are reflected in the paging by day queries. + if ( !$q['suppress_filters'] ) { + $where = apply_filters_ref_array('posts_where', array( $where, &$this ) ); + $join = apply_filters_ref_array('posts_join', array( $join, &$this ) ); + } + + // Paging + if ( empty($q['nopaging']) && !$this->is_singular ) { + $page = absint($q['paged']); + if ( empty($page) ) + $page = 1; + + if ( empty($q['offset']) ) { + $pgstrt = ''; + $pgstrt = ($page - 1) * $q['posts_per_page'] . ', '; + $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page']; + } else { // we're ignoring $page and using 'offset' + $q['offset'] = absint($q['offset']); + $pgstrt = $q['offset'] . ', '; + $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page']; + } + } + + // Comments feeds + if ( $this->is_comment_feed && ( $this->is_archive || $this->is_search || !$this->is_singular ) ) { + if ( $this->is_archive || $this->is_search ) { + $cjoin = "JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) $join "; + $cwhere = "WHERE comment_approved = '1' $where"; + $cgroupby = "$wpdb->comments.comment_id"; + } else { // Other non singular e.g. front + $cjoin = "JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID )"; + $cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'"; + $cgroupby = ''; + } + + if ( !$q['suppress_filters'] ) { + $cjoin = apply_filters_ref_array('comment_feed_join', array( $cjoin, &$this ) ); + $cwhere = apply_filters_ref_array('comment_feed_where', array( $cwhere, &$this ) ); + $cgroupby = apply_filters_ref_array('comment_feed_groupby', array( $cgroupby, &$this ) ); + $corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); + $climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) ); + } + $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; + $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; + + $this->comments = (array) $wpdb->get_results("SELECT $distinct $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits"); + $this->comment_count = count($this->comments); + + $post_ids = array(); + + foreach ( $this->comments as $comment ) + $post_ids[] = (int) $comment->comment_post_ID; + + $post_ids = join(',', $post_ids); + $join = ''; + if ( $post_ids ) + $where = "AND $wpdb->posts.ID IN ($post_ids) "; + else + $where = "AND 0"; + } + + $orderby = $q['orderby']; + + $pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' ); + + // Apply post-paging filters on where and join. Only plugins that + // manipulate paging queries should use these hooks. + if ( !$q['suppress_filters'] ) { + $where = apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) ); + $groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) ); + $join = apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) ); + $orderby = apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) ); + $distinct = apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) ); + $limits = apply_filters_ref_array( 'post_limits', array( $limits, &$this ) ); + $fields = apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) ); + + // Filter all clauses at once, for convenience + $clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) ); + foreach ( $pieces as $piece ) + $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; + } + + // Announce current selection parameters. For use by caching plugins. + do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join ); + + // Filter again for the benefit of caching plugins. Regular plugins should use the hooks above. + if ( !$q['suppress_filters'] ) { + $where = apply_filters_ref_array( 'posts_where_request', array( $where, &$this ) ); + $groupby = apply_filters_ref_array( 'posts_groupby_request', array( $groupby, &$this ) ); + $join = apply_filters_ref_array( 'posts_join_request', array( $join, &$this ) ); + $orderby = apply_filters_ref_array( 'posts_orderby_request', array( $orderby, &$this ) ); + $distinct = apply_filters_ref_array( 'posts_distinct_request', array( $distinct, &$this ) ); + $fields = apply_filters_ref_array( 'posts_fields_request', array( $fields, &$this ) ); + $limits = apply_filters_ref_array( 'post_limits_request', array( $limits, &$this ) ); + + // Filter all clauses at once, for convenience + $clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) ); + foreach ( $pieces as $piece ) + $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; + } + + if ( ! empty($groupby) ) + $groupby = 'GROUP BY ' . $groupby; + if ( !empty( $orderby ) ) + $orderby = 'ORDER BY ' . $orderby; + + $found_rows = ''; + if ( !$q['no_found_rows'] && !empty($limits) ) + $found_rows = 'SQL_CALC_FOUND_ROWS'; + + $this->request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; + if ( !$q['suppress_filters'] ) + $this->request = apply_filters_ref_array('posts_request', array( $this->request, &$this ) ); + + if ( 'ids' == $q['fields'] ) { + $this->posts = $wpdb->get_col($this->request); + + return $this->posts; + } + + if ( 'id=>parent' == $q['fields'] ) { + $this->posts = $wpdb->get_results($this->request); + + $r = array(); + foreach ( $this->posts as $post ) + $r[ $post->ID ] = $post->post_parent; + + return $r; + } + + $this->posts = $wpdb->get_results($this->request); + + // Raw results filter. Prior to status checks. + if ( !$q['suppress_filters'] ) + $this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) ); + + if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) { + $cjoin = apply_filters_ref_array('comment_feed_join', array( '', &$this ) ); + $cwhere = apply_filters_ref_array('comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) ); + $cgroupby = apply_filters_ref_array('comment_feed_groupby', array( '', &$this ) ); + $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; + $corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); + $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; + $climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) ); + $comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits"; + $this->comments = $wpdb->get_results($comments_request); + $this->comment_count = count($this->comments); + } + + if ( !$q['no_found_rows'] && !empty($limits) ) { + $found_posts_query = apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ); + $this->found_posts = $wpdb->get_var( $found_posts_query ); + $this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) ); + $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); + } + + // Check post status to determine if post should be displayed. + if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) { + $status = get_post_status($this->posts[0]); + $post_status_obj = get_post_status_object($status); + //$type = get_post_type($this->posts[0]); + if ( !$post_status_obj->public ) { + if ( ! is_user_logged_in() ) { + // User must be logged in to view unpublished posts. + $this->posts = array(); + } else { + if ( $post_status_obj->protected ) { + // User must have edit permissions on the draft to preview. + if ( ! current_user_can($edit_cap, $this->posts[0]->ID) ) { + $this->posts = array(); + } else { + $this->is_preview = true; + if ( 'future' != $status ) + $this->posts[0]->post_date = current_time('mysql'); + } + } elseif ( $post_status_obj->private ) { + if ( ! current_user_can($read_cap, $this->posts[0]->ID) ) + $this->posts = array(); + } else { + $this->posts = array(); + } + } + } + + if ( $this->is_preview && current_user_can( $edit_cap, $this->posts[0]->ID ) ) + $this->posts[0] = apply_filters_ref_array('the_preview', array( $this->posts[0], &$this )); + } + + // Put sticky posts at the top of the posts array + $sticky_posts = get_option('sticky_posts'); + if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) { + $num_posts = count($this->posts); + $sticky_offset = 0; + // Loop over posts and relocate stickies to the front. + for ( $i = 0; $i < $num_posts; $i++ ) { + if ( in_array($this->posts[$i]->ID, $sticky_posts) ) { + $sticky_post = $this->posts[$i]; + // Remove sticky from current position + array_splice($this->posts, $i, 1); + // Move to front, after other stickies + array_splice($this->posts, $sticky_offset, 0, array($sticky_post)); + // Increment the sticky offset. The next sticky will be placed at this offset. + $sticky_offset++; + // Remove post from sticky posts array + $offset = array_search($sticky_post->ID, $sticky_posts); + unset( $sticky_posts[$offset] ); + } + } + + // If any posts have been excluded specifically, Ignore those that are sticky. + if ( !empty($sticky_posts) && !empty($q['post__not_in']) ) + $sticky_posts = array_diff($sticky_posts, $q['post__not_in']); + + // Fetch sticky posts that weren't in the query results + if ( !empty($sticky_posts) ) { + $stickies__in = implode(',', array_map( 'absint', $sticky_posts )); + // honor post type(s) if not set to any + $stickies_where = ''; + if ( 'any' != $post_type && '' != $post_type ) { + if ( is_array( $post_type ) ) { + $post_types = join( "', '", $post_type ); + } else { + $post_types = $post_type; + } + $stickies_where = "AND $wpdb->posts.post_type IN ('" . $post_types . "')"; + } + + $stickies = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE $wpdb->posts.ID IN ($stickies__in) $stickies_where" ); + foreach ( $stickies as $sticky_post ) { + // Ignore sticky posts the current user cannot read or are not published. + if ( 'publish' != $sticky_post->post_status ) + continue; + array_splice($this->posts, $sticky_offset, 0, array($sticky_post)); + $sticky_offset++; + } + } + } + + if ( !$q['suppress_filters'] ) + $this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) ); + + $this->post_count = count($this->posts); + + // Sanitize before caching so it'll only get done once + for ( $i = 0; $i < $this->post_count; $i++ ) { + $this->posts[$i] = sanitize_post($this->posts[$i], 'raw'); + } + + if ( $q['cache_results'] ) + update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']); + + if ( $this->post_count > 0 ) { + $this->post = $this->posts[0]; + } + + return $this->posts; + } + + /** + * Set up the next post and iterate current post index. + * + * @since 1.5.0 + * @access public + * + * @return object Next post. + */ + function next_post() { + + $this->current_post++; + + $this->post = $this->posts[$this->current_post]; + return $this->post; + } + + /** + * Sets up the current post. + * + * Retrieves the next post, sets up the post, sets the 'in the loop' + * property to true. + * + * @since 1.5.0 + * @access public + * @uses $post + * @uses do_action_ref_array() Calls 'loop_start' if loop has just started + */ + function the_post() { + global $post; + $this->in_the_loop = true; + + if ( $this->current_post == -1 ) // loop has just started + do_action_ref_array('loop_start', array(&$this)); + + $post = $this->next_post(); + setup_postdata($post); + } + + /** + * Whether there are more posts available in the loop. + * + * Calls action 'loop_end', when the loop is complete. + * + * @since 1.5.0 + * @access public + * @uses do_action_ref_array() Calls 'loop_end' if loop is ended + * + * @return bool True if posts are available, false if end of loop. + */ + function have_posts() { + if ( $this->current_post + 1 < $this->post_count ) { + return true; + } elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) { + do_action_ref_array('loop_end', array(&$this)); + // Do some cleaning up after the loop + $this->rewind_posts(); + } + + $this->in_the_loop = false; + return false; + } + + /** + * Rewind the posts and reset post index. + * + * @since 1.5.0 + * @access public + */ + function rewind_posts() { + $this->current_post = -1; + if ( $this->post_count > 0 ) { + $this->post = $this->posts[0]; + } + } + + /** + * Iterate current comment index and return comment object. + * + * @since 2.2.0 + * @access public + * + * @return object Comment object. + */ + function next_comment() { + $this->current_comment++; + + $this->comment = $this->comments[$this->current_comment]; + return $this->comment; + } + + /** + * Sets up the current comment. + * + * @since 2.2.0 + * @access public + * @global object $comment Current comment. + * @uses do_action() Calls 'comment_loop_start' hook when first comment is processed. + */ + function the_comment() { + global $comment; + + $comment = $this->next_comment(); + + if ( $this->current_comment == 0 ) { + do_action('comment_loop_start'); + } + } + + /** + * Whether there are more comments available. + * + * Automatically rewinds comments when finished. + * + * @since 2.2.0 + * @access public + * + * @return bool True, if more comments. False, if no more posts. + */ + function have_comments() { + if ( $this->current_comment + 1 < $this->comment_count ) { + return true; + } elseif ( $this->current_comment + 1 == $this->comment_count ) { + $this->rewind_comments(); + } + + return false; + } + + /** + * Rewind the comments, resets the comment index and comment to first. + * + * @since 2.2.0 + * @access public + */ + function rewind_comments() { + $this->current_comment = -1; + if ( $this->comment_count > 0 ) { + $this->comment = $this->comments[0]; + } + } + + /** + * Sets up the WordPress query by parsing query string. + * + * @since 1.5.0 + * @access public + * + * @param string $query URL query string. + * @return array List of posts. + */ + function &query( $query ) { + $this->init(); + $this->query = $this->query_vars = wp_parse_args( $query ); + return $this->get_posts(); + } + + /** + * Retrieve queried object. + * + * If queried object is not set, then the queried object will be set from + * the category, tag, taxonomy, posts page, single post, page, or author + * query variable. After it is set up, it will be returned. + * + * @since 1.5.0 + * @access public + * + * @return object + */ + function get_queried_object() { + if ( isset($this->queried_object) ) + return $this->queried_object; + + $this->queried_object = NULL; + $this->queried_object_id = 0; + + if ( $this->is_category || $this->is_tag || $this->is_tax ) { + $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' ); + + $query = reset( $tax_query_in_and ); + + if ( 'term_id' == $query['field'] ) + $term = get_term( reset( $query['terms'] ), $query['taxonomy'] ); + else + $term = get_term_by( $query['field'], reset( $query['terms'] ), $query['taxonomy'] ); + + if ( $term && ! is_wp_error($term) ) { + $this->queried_object = $term; + $this->queried_object_id = (int) $term->term_id; + + if ( $this->is_category ) + _make_cat_compat( $this->queried_object ); + } + } elseif ( $this->is_post_type_archive ) { + $this->queried_object = get_post_type_object( $this->get('post_type') ); + } elseif ( $this->is_posts_page ) { + $page_for_posts = get_option('page_for_posts'); + $this->queried_object = & get_page( $page_for_posts ); + $this->queried_object_id = (int) $this->queried_object->ID; + } elseif ( $this->is_singular && !is_null($this->post) ) { + $this->queried_object = $this->post; + $this->queried_object_id = (int) $this->post->ID; + } elseif ( $this->is_author ) { + $this->queried_object_id = (int) $this->get('author'); + $this->queried_object = get_userdata( $this->queried_object_id ); + } + + return $this->queried_object; + } + + /** + * Retrieve ID of the current queried object. + * + * @since 1.5.0 + * @access public + * + * @return int + */ + function get_queried_object_id() { + $this->get_queried_object(); + + if ( isset($this->queried_object_id) ) { + return $this->queried_object_id; + } + + return 0; + } + + /** + * PHP4 type constructor. + * + * Sets up the WordPress query, if parameter is not empty. + * + * @since 1.5.0 + * @access public + * + * @param string $query URL query string. + * @return WP_Query + */ + function WP_Query($query = '') { + if ( ! empty($query) ) { + $this->query($query); + } + } + + /** + * Is the query for an archive page? + * + * Month, Year, Category, Author, Post Type archive... + * + * @since 3.1.0 + * + * @return bool + */ + function is_archive() { + return (bool) $this->is_archive; + } + + /** + * Is the query for a post type archive page? + * + * @since 3.1.0 + * + * @param mixed $post_types Optional. Post type or array of posts types to check against. + * @return bool + */ + function is_post_type_archive( $post_types = '' ) { + if ( empty( $post_types ) || !$this->is_post_type_archive ) + return (bool) $this->is_post_type_archive; + + $post_type_object = $this->get_queried_object(); + + return in_array( $post_type_object->name, (array) $post_types ); + } + + /** + * Is the query for an attachment page? + * + * @since 3.1.0 + * + * @return bool + */ + function is_attachment() { + return (bool) $this->is_attachment; + } + + /** + * Is the query for an author archive page? + * + * If the $author parameter is specified, this function will additionally + * check if the query is for one of the authors specified. + * + * @since 3.1.0 + * + * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames + * @return bool + */ + function is_author( $author = '' ) { + if ( !$this->is_author ) + return false; + + if ( empty($author) ) + return true; + + $author_obj = $this->get_queried_object(); + + $author = (array) $author; + + if ( in_array( $author_obj->ID, $author ) ) + return true; + elseif ( in_array( $author_obj->nickname, $author ) ) + return true; + elseif ( in_array( $author_obj->user_nicename, $author ) ) + return true; + + return false; + } + + /** + * Is the query for a category archive page? + * + * If the $category parameter is specified, this function will additionally + * check if the query is for one of the categories specified. + * + * @since 3.1.0 + * + * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs. + * @return bool + */ + function is_category( $category = '' ) { + if ( !$this->is_category ) + return false; + + if ( empty($category) ) + return true; + + $cat_obj = $this->get_queried_object(); + + $category = (array) $category; + + if ( in_array( $cat_obj->term_id, $category ) ) + return true; + elseif ( in_array( $cat_obj->name, $category ) ) + return true; + elseif ( in_array( $cat_obj->slug, $category ) ) + return true; + + return false; + } + + /** + * Is the query for a tag archive page? + * + * If the $tag parameter is specified, this function will additionally + * check if the query is for one of the tags specified. + * + * @since 3.1.0 + * + * @param mixed $slug Optional. Tag slug or array of slugs. + * @return bool + */ + function is_tag( $slug = '' ) { + if ( !$this->is_tag ) + return false; + + if ( empty( $slug ) ) + return true; + + $tag_obj = $this->get_queried_object(); + + $slug = (array) $slug; + + if ( in_array( $tag_obj->slug, $slug ) ) + return true; + + return false; + } + + /** + * Is the query for a taxonomy archive page? + * + * If the $taxonomy parameter is specified, this function will additionally + * check if the query is for that specific $taxonomy. + * + * If the $term parameter is specified in addition to the $taxonomy parameter, + * this function will additionally check if the query is for one of the terms + * specified. + * + * @since 3.1.0 + * + * @param mixed $taxonomy Optional. Taxonomy slug or slugs. + * @param mixed $term. Optional. Term ID, name, slug or array of Term IDs, names, and slugs. + * @return bool + */ + function is_tax( $taxonomy = '', $term = '' ) { + global $wp_taxonomies; + + if ( !$this->is_tax ) + return false; + + if ( empty( $taxonomy ) ) + return true; + + $queried_object = $this->get_queried_object(); + $tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy ); + $term_array = (array) $term; + + if ( empty( $term ) ) // Only a Taxonomy provided + return isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ); + + return isset( $queried_object->term_id ) && + count( array_intersect( + array( $queried_object->term_id, $queried_object->name, $queried_object->slug ), + $term_array + ) ); + } + + /** + * Whether the current URL is within the comments popup window. + * + * @since 3.1.0 + * + * @return bool + */ + function is_comments_popup() { + return (bool) $this->is_comments_popup; + } + + /** + * Is the query for a date archive? + * + * @since 3.1.0 + * + * @return bool + */ + function is_date() { + return (bool) $this->is_date; + } + + + /** + * Is the query for a day archive? + * + * @since 3.1.0 + * + * @return bool + */ + function is_day() { + return (bool) $this->is_day; + } + + /** + * Is the query for a feed? + * + * @since 3.1.0 + * + * @param string|array $feeds Optional feed types to check. + * @return bool + */ + function is_feed( $feeds = '' ) { + if ( empty( $feeds ) || ! $this->is_feed ) + return (bool) $this->is_feed; + $qv = $this->get( 'feed' ); + if ( 'feed' == $qv ) + $qv = get_default_feed(); + return in_array( $qv, (array) $feeds ); + } + + /** + * Is the query for a comments feed? + * + * @since 3.1.0 + * + * @return bool + */ + function is_comment_feed() { + return (bool) $this->is_comment_feed; + } + + /** + * Is the query for the front page of the site? + * + * This is for what is displayed at your site's main URL. + * + * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'. + * + * If you set a static page for the front page of your site, this function will return + * true when viewing that page. + * + * Otherwise the same as @see WP_Query::is_home() + * + * @since 3.1.0 + * @uses is_home() + * @uses get_option() + * + * @return bool True, if front of site. + */ + function is_front_page() { + // most likely case + if ( 'posts' == get_option( 'show_on_front') && $this->is_home() ) + return true; + elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) ) + return true; + else + return false; + } + + /** + * Is the query for the blog homepage? + * + * This is the page which shows the time based blog content of your site. + * + * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'. + * + * If you set a static page for the front page of your site, this function will return + * true only on the page you set as the "Posts page". + * + * @see WP_Query::is_front_page() + * + * @since 3.1.0 + * + * @return bool True if blog view homepage. + */ + function is_home() { + return (bool) $this->is_home; + } + + /** + * Is the query for a month archive? + * + * @since 3.1.0 + * + * @return bool + */ + function is_month() { + return (bool) $this->is_month; + } + + /** + * Is the query for a single page? + * + * If the $page parameter is specified, this function will additionally + * check if the query is for one of the pages specified. + * + * @see WP_Query::is_single() + * @see WP_Query::is_singular() + * + * @since 3.1.0 + * + * @param mixed $page Page ID, title, slug, or array of such. + * @return bool + */ + function is_page( $page = '' ) { + if ( !$this->is_page ) + return false; + + if ( empty( $page ) ) + return true; + + $page_obj = $this->get_queried_object(); + + $page = (array) $page; + + if ( in_array( $page_obj->ID, $page ) ) + return true; + elseif ( in_array( $page_obj->post_title, $page ) ) + return true; + else if ( in_array( $page_obj->post_name, $page ) ) + return true; + + return false; + } + + /** + * Is the query for paged result and not for the first page? + * + * @since 3.1.0 + * + * @return bool + */ + function is_paged() { + return (bool) $this->is_paged; + } + + /** + * Is the query for a post or page preview? + * + * @since 3.1.0 + * + * @return bool + */ + function is_preview() { + return (bool) $this->is_preview; + } + + /** + * Is the query for the robots file? + * + * @since 3.1.0 + * + * @return bool + */ + function is_robots() { + return (bool) $this->is_robots; + } + + /** + * Is the query for a search? + * + * @since 3.1.0 + * + * @return bool + */ + function is_search() { + return (bool) $this->is_search; + } + + /** + * Is the query for a single post? + * + * Works for any post type, except attachments and pages + * + * If the $post parameter is specified, this function will additionally + * check if the query is for one of the Posts specified. + * + * @see WP_Query::is_page() + * @see WP_Query::is_singular() + * + * @since 3.1.0 + * + * @param mixed $post Post ID, title, slug, or array of such. + * @return bool + */ + function is_single( $post = '' ) { + if ( !$this->is_single ) + return false; + + if ( empty($post) ) + return true; + + $post_obj = $this->get_queried_object(); + + $post = (array) $post; + + if ( in_array( $post_obj->ID, $post ) ) + return true; + elseif ( in_array( $post_obj->post_title, $post ) ) + return true; + elseif ( in_array( $post_obj->post_name, $post ) ) + return true; + + return false; + } + + /** + * Is the query for a single post of any post type (post, attachment, page, ... )? + * + * If the $post_types parameter is specified, this function will additionally + * check if the query is for one of the Posts Types specified. + * + * @see WP_Query::is_page() + * @see WP_Query::is_single() + * + * @since 3.1.0 + * + * @param mixed $post_types Optional. Post Type or array of Post Types + * @return bool + */ + function is_singular( $post_types = '' ) { + if ( empty( $post_types ) || !$this->is_singular ) + return (bool) $this->is_singular; + + $post_obj = $this->get_queried_object(); + + return in_array( $post_obj->post_type, (array) $post_types ); + } + + /** + * Is the query for a specific time? + * + * @since 3.1.0 + * + * @return bool + */ + function is_time() { + return (bool) $this->is_time; + } + + /** + * Is the query for a trackback endpoint call? + * + * @since 3.1.0 + * + * @return bool + */ + function is_trackback() { + return (bool) $this->is_trackback; + } + + /** + * Is the query for a specific year? + * + * @since 3.1.0 + * + * @return bool + */ + function is_year() { + return (bool) $this->is_year; + } + + /** + * Is the query a 404 (returns no results)? + * + * @since 3.1.0 + * + * @return bool + */ + function is_404() { + return (bool) $this->is_404; + } +} + +/** + * Redirect old slugs to the correct permalink. + * + * Attempts to find the current slug from the past slugs. + * + * @since 2.1.0 + * @uses $wp_query + * @uses $wpdb + * + * @return null If no link is found, null is returned. + */ +function wp_old_slug_redirect() { + global $wp_query; + if ( is_404() && '' != $wp_query->query_vars['name'] ) : + global $wpdb; + + // Guess the current post_type based on the query vars. + if ( get_query_var('post_type') ) + $post_type = get_query_var('post_type'); + elseif ( !empty($wp_query->query_vars['pagename']) ) + $post_type = 'page'; + else + $post_type = 'post'; + + // Do not attempt redirect for hierarchical post types + if ( is_post_type_hierarchical( $post_type ) ) + return; + + $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_slug' AND meta_value = %s", $post_type, $wp_query->query_vars['name']); + + // if year, monthnum, or day have been specified, make our query more precise + // just in case there are multiple identical _wp_old_slug values + if ( '' != $wp_query->query_vars['year'] ) + $query .= $wpdb->prepare(" AND YEAR(post_date) = %d", $wp_query->query_vars['year']); + if ( '' != $wp_query->query_vars['monthnum'] ) + $query .= $wpdb->prepare(" AND MONTH(post_date) = %d", $wp_query->query_vars['monthnum']); + if ( '' != $wp_query->query_vars['day'] ) + $query .= $wpdb->prepare(" AND DAYOFMONTH(post_date) = %d", $wp_query->query_vars['day']); + + $id = (int) $wpdb->get_var($query); + + if ( ! $id ) + return; + + $link = get_permalink($id); + + if ( !$link ) + return; + + wp_redirect($link, '301'); // Permanent redirect + exit; + endif; +} + +/** + * Set up global post data. + * + * @since 1.5.0 + * + * @param object $post Post data. + * @uses do_action_ref_array() Calls 'the_post' + * @return bool True when finished. + */ +function setup_postdata($post) { + global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages; + + $id = (int) $post->ID; + + $authordata = get_userdata($post->post_author); + + $currentday = mysql2date('d.m.y', $post->post_date, false); + $currentmonth = mysql2date('m', $post->post_date, false); + $numpages = 1; + $page = get_query_var('page'); + if ( !$page ) + $page = 1; + if ( is_single() || is_page() || is_feed() ) + $more = 1; + $content = $post->post_content; + if ( strpos( $content, '' ) ) { + if ( $page > 1 ) + $more = 1; + $multipage = 1; + $content = str_replace("\n\n", '', $content); + $content = str_replace("\n", '', $content); + $content = str_replace("\n", '', $content); + $pages = explode('', $content); + $numpages = count($pages); + } else { + $pages = array( $post->post_content ); + $multipage = 0; + } + + do_action_ref_array('the_post', array(&$post)); + + return true; +} +?> diff --git a/src/wp-includes/registration-functions.php b/src/wp-includes/registration-functions.php new file mode 100644 index 00000000..889919de --- /dev/null +++ b/src/wp-includes/registration-functions.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/src/wp-includes/registration.php b/src/wp-includes/registration.php new file mode 100644 index 00000000..07d919c6 --- /dev/null +++ b/src/wp-includes/registration.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/src/wp-includes/rewrite.php b/src/wp-includes/rewrite.php new file mode 100644 index 00000000..92d372e3 --- /dev/null +++ b/src/wp-includes/rewrite.php @@ -0,0 +1,1991 @@ +add_rule($regex, $redirect, $after); +} + +/** + * Add a new tag (like %postname%). + * + * Warning: you must call this on init or earlier, otherwise the query var + * addition stuff won't work. + * + * @since 2.1.0 + * + * @param string $tagname + * @param string $regex + */ +function add_rewrite_tag($tagname, $regex) { + //validation + if ( strlen($tagname) < 3 || $tagname[0] != '%' || $tagname[strlen($tagname)-1] != '%' ) + return; + + $qv = trim($tagname, '%'); + + global $wp_rewrite, $wp; + $wp->add_query_var($qv); + $wp_rewrite->add_rewrite_tag($tagname, $regex, $qv . '='); +} + +/** + * Add permalink structure. + * + * @see WP_Rewrite::add_permastruct() + * @since 3.0.0 + * + * @param string $name Name for permalink structure. + * @param string $struct Permalink structure. + * @param bool $with_front Prepend front base to permalink structure. + */ +function add_permastruct( $name, $struct, $with_front = true, $ep_mask = EP_NONE ) { + global $wp_rewrite; + return $wp_rewrite->add_permastruct( $name, $struct, $with_front, $ep_mask ); +} + +/** + * Add a new feed type like /atom1/. + * + * @since 2.1.0 + * + * @param string $feedname + * @param callback $function Callback to run on feed display. + * @return string Feed action name. + */ +function add_feed($feedname, $function) { + global $wp_rewrite; + if ( ! in_array($feedname, $wp_rewrite->feeds) ) //override the file if it is + $wp_rewrite->feeds[] = $feedname; + $hook = 'do_feed_' . $feedname; + // Remove default function hook + remove_action($hook, $hook, 10, 1); + add_action($hook, $function, 10, 1); + return $hook; +} + +/** + * Remove rewrite rules and then recreate rewrite rules. + * + * @see WP_Rewrite::flush_rules() + * @since 3.0.0 + * + * @param bool $hard Whether to update .htaccess (hard flush) or just update + * rewrite_rules transient (soft flush). Default is true (hard). + */ +function flush_rewrite_rules( $hard = true ) { + global $wp_rewrite; + $wp_rewrite->flush_rules( $hard ); +} + +//pseudo-places +/** + * Endpoint Mask for default, which is nothing. + * + * @since 2.1.0 + */ +define('EP_NONE', 0); + +/** + * Endpoint Mask for Permalink. + * + * @since 2.1.0 + */ +define('EP_PERMALINK', 1); + +/** + * Endpoint Mask for Attachment. + * + * @since 2.1.0 + */ +define('EP_ATTACHMENT', 2); + +/** + * Endpoint Mask for date. + * + * @since 2.1.0 + */ +define('EP_DATE', 4); + +/** + * Endpoint Mask for year + * + * @since 2.1.0 + */ +define('EP_YEAR', 8); + +/** + * Endpoint Mask for month. + * + * @since 2.1.0 + */ +define('EP_MONTH', 16); + +/** + * Endpoint Mask for day. + * + * @since 2.1.0 + */ +define('EP_DAY', 32); + +/** + * Endpoint Mask for root. + * + * @since 2.1.0 + */ +define('EP_ROOT', 64); + +/** + * Endpoint Mask for comments. + * + * @since 2.1.0 + */ +define('EP_COMMENTS', 128); + +/** + * Endpoint Mask for searches. + * + * @since 2.1.0 + */ +define('EP_SEARCH', 256); + +/** + * Endpoint Mask for categories. + * + * @since 2.1.0 + */ +define('EP_CATEGORIES', 512); + +/** + * Endpoint Mask for tags. + * + * @since 2.3.0 + */ +define('EP_TAGS', 1024); + +/** + * Endpoint Mask for authors. + * + * @since 2.1.0 + */ +define('EP_AUTHORS', 2048); + +/** + * Endpoint Mask for pages. + * + * @since 2.1.0 + */ +define('EP_PAGES', 4096); + +/** + * Endpoint Mask for everything. + * + * @since 2.1.0 + */ +define('EP_ALL', 8191); + +/** + * Add an endpoint, like /trackback/. + * + * The endpoints are added to the end of the request. So a request matching + * "/2008/10/14/my_post/myep/", the endpoint will be "/myep/". + * + * Be sure to flush the rewrite rules (wp_rewrite->flush_rules()) when your plugin gets + * activated (register_activation_hook()) and deactivated (register_deactivation_hook()) + * + * @since 2.1.0 + * @see WP_Rewrite::add_endpoint() Parameters and more description. + * @uses $wp_rewrite + * + * @param unknown_type $name + * @param unknown_type $places + */ +function add_rewrite_endpoint($name, $places) { + global $wp_rewrite; + $wp_rewrite->add_endpoint($name, $places); +} + +/** + * Filter the URL base for taxonomies. + * + * To remove any manually prepended /index.php/. + * + * @access private + * @since 2.6.0 + * + * @param string $base The taxonomy base that we're going to filter + * @return string + */ +function _wp_filter_taxonomy_base( $base ) { + if ( !empty( $base ) ) { + $base = preg_replace( '|^/index\.php/|', '', $base ); + $base = trim( $base, '/' ); + } + return $base; +} + +/** + * Examine a url and try to determine the post ID it represents. + * + * Checks are supposedly from the hosted site blog. + * + * @since 1.0.0 + * + * @param string $url Permalink to check. + * @return int Post ID, or 0 on failure. + */ +function url_to_postid($url) { + global $wp_rewrite; + + $url = apply_filters('url_to_postid', $url); + + // First, check to see if there is a 'p=N' or 'page_id=N' to match against + if ( preg_match('#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values) ) { + $id = absint($values[2]); + if ( $id ) + return $id; + } + + // Check to see if we are using rewrite rules + $rewrite = $wp_rewrite->wp_rewrite_rules(); + + // Not using rewrite rules, and 'p=N' and 'page_id=N' methods failed, so we're out of options + if ( empty($rewrite) ) + return 0; + + // Get rid of the #anchor + $url_split = explode('#', $url); + $url = $url_split[0]; + + // Get rid of URL ?query=string + $url_split = explode('?', $url); + $url = $url_split[0]; + + // Add 'www.' if it is absent and should be there + if ( false !== strpos(home_url(), '://www.') && false === strpos($url, '://www.') ) + $url = str_replace('://', '://www.', $url); + + // Strip 'www.' if it is present and shouldn't be + if ( false === strpos(home_url(), '://www.') ) + $url = str_replace('://www.', '://', $url); + + // Strip 'index.php/' if we're not using path info permalinks + if ( !$wp_rewrite->using_index_permalinks() ) + $url = str_replace('index.php/', '', $url); + + if ( false !== strpos($url, home_url()) ) { + // Chop off http://domain.com + $url = str_replace(home_url(), '', $url); + } else { + // Chop off /path/to/blog + $home_path = parse_url(home_url()); + $home_path = isset( $home_path['path'] ) ? $home_path['path'] : '' ; + $url = str_replace($home_path, '', $url); + } + + // Trim leading and lagging slashes + $url = trim($url, '/'); + + $request = $url; + + // Look for matches. + $request_match = $request; + foreach ( (array)$rewrite as $match => $query) { + // If the requesting file is the anchor of the match, prepend it + // to the path info. + if ( !empty($url) && ($url != $request) && (strpos($match, $url) === 0) ) + $request_match = $url . '/' . $request; + + if ( preg_match("!^$match!", $request_match, $matches) ) { + // Got a match. + // Trim the query of everything up to the '?'. + $query = preg_replace("!^.+\?!", '', $query); + + // Substitute the substring matches into the query. + $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); + + // Filter out non-public query vars + global $wp; + parse_str($query, $query_vars); + $query = array(); + foreach ( (array) $query_vars as $key => $value ) { + if ( in_array($key, $wp->public_query_vars) ) + $query[$key] = $value; + } + + // Do the query + $query = new WP_Query($query); + if ( !empty($query->posts) && $query->is_singular ) + return $query->post->ID; + else + return 0; + } + } + return 0; +} + +/** + * WordPress Rewrite Component. + * + * The WordPress Rewrite class writes the rewrite module rules to the .htaccess + * file. It also handles parsing the request to get the correct setup for the + * WordPress Query class. + * + * The Rewrite along with WP class function as a front controller for WordPress. + * You can add rules to trigger your page view and processing using this + * component. The full functionality of a front controller does not exist, + * meaning you can't define how the template files load based on the rewrite + * rules. + * + * @since 1.5.0 + */ +class WP_Rewrite { + /** + * Default permalink structure for WordPress. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $permalink_structure; + + /** + * Whether to add trailing slashes. + * + * @since 2.2.0 + * @access private + * @var bool + */ + var $use_trailing_slashes; + + /** + * Permalink author request base ( example.com/author/authorname ). + * + * @since 1.5.0 + * @access private + * @var string + */ + var $author_base = 'author'; + + /** + * Permalink request structure for author pages. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $author_structure; + + /** + * Permalink request structure for dates. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $date_structure; + + /** + * Permalink request structure for pages. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $page_structure; + + /** + * Search permalink base ( example.com/search/query ). + * + * @since 1.5.0 + * @access private + * @var string + */ + var $search_base = 'search'; + + /** + * Permalink request structure for searches. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $search_structure; + + /** + * Comments permalink base. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $comments_base = 'comments'; + + /** + * Pagination permalink base. + * + * @since 3.1.0 + * @access private + * @var string + */ + var $pagination_base = 'page'; + + /** + * Feed permalink base. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $feed_base = 'feed'; + + /** + * Comments feed request structure permalink. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $comments_feed_structure; + + /** + * Feed request structure permalink. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $feed_structure; + + /** + * Front URL path. + * + * The difference between the root property is that WordPress might be + * located at example/WordPress/index.php, if permalinks are turned off. The + * WordPress/index.php will be the front portion. If permalinks are turned + * on, this will most likely be empty or not set. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $front; + + /** + * Root URL path to WordPress (without domain). + * + * The difference between front property is that WordPress might be located + * at example.com/WordPress/. The root is the 'WordPress/' portion. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $root = ''; + + /** + * Permalink to the home page. + * + * @since 1.5.0 + * @access public + * @var string + */ + var $index = 'index.php'; + + /** + * Request match string. + * + * @since 1.5.0 + * @access private + * @var string + */ + var $matches = ''; + + /** + * Rewrite rules to match against the request to find the redirect or query. + * + * @since 1.5.0 + * @access private + * @var array + */ + var $rules; + + /** + * Additional rules added external to the rewrite class. + * + * Those not generated by the class, see add_rewrite_rule(). + * + * @since 2.1.0 + * @access private + * @var array + */ + var $extra_rules = array(); // + + /** + * Additional rules that belong at the beginning to match first. + * + * Those not generated by the class, see add_rewrite_rule(). + * + * @since 2.3.0 + * @access private + * @var array + */ + var $extra_rules_top = array(); // + + /** + * Rules that don't redirect to WP's index.php. + * + * These rules are written to the mod_rewrite portion of the .htaccess. + * + * @since 2.1.0 + * @access private + * @var array + */ + var $non_wp_rules = array(); // + + /** + * Extra permalink structures. + * + * @since 2.1.0 + * @access private + * @var array + */ + var $extra_permastructs = array(); + + /** + * Endpoints permalinks + * + * @since 2.1.0 + * @access private + * @var array + */ + var $endpoints; + + /** + * Whether to write every mod_rewrite rule for WordPress. + * + * This is off by default, turning it on might print a lot of rewrite rules + * to the .htaccess file. + * + * @since 2.0.0 + * @access public + * @var bool + */ + var $use_verbose_rules = false; + + /** + * Whether to write every mod_rewrite rule for WordPress pages. + * + * @since 2.5.0 + * @access public + * @var bool + */ + var $use_verbose_page_rules = true; + + /** + * Permalink structure search for preg_replace. + * + * @since 1.5.0 + * @access private + * @var array + */ + var $rewritecode = + array( + '%year%', + '%monthnum%', + '%day%', + '%hour%', + '%minute%', + '%second%', + '%postname%', + '%post_id%', + '%author%', + '%pagename%', + '%search%' + ); + + /** + * Preg_replace values for the search, see {@link WP_Rewrite::$rewritecode}. + * + * @since 1.5.0 + * @access private + * @var array + */ + var $rewritereplace = + array( + '([0-9]{4})', + '([0-9]{1,2})', + '([0-9]{1,2})', + '([0-9]{1,2})', + '([0-9]{1,2})', + '([0-9]{1,2})', + '([^/]+)', + '([0-9]+)', + '([^/]+)', + '([^/]+?)', + '(.+)' + ); + + /** + * Search for the query to look for replacing. + * + * @since 1.5.0 + * @access private + * @var array + */ + var $queryreplace = + array ( + 'year=', + 'monthnum=', + 'day=', + 'hour=', + 'minute=', + 'second=', + 'name=', + 'p=', + 'author_name=', + 'pagename=', + 's=' + ); + + /** + * Supported default feeds. + * + * @since 1.5.0 + * @access private + * @var array + */ + var $feeds = array ( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); + + /** + * Whether permalinks are being used. + * + * This can be either rewrite module or permalink in the HTTP query string. + * + * @since 1.5.0 + * @access public + * + * @return bool True, if permalinks are enabled. + */ + function using_permalinks() { + return ! empty($this->permalink_structure); + } + + /** + * Whether permalinks are being used and rewrite module is not enabled. + * + * Means that permalink links are enabled and index.php is in the URL. + * + * @since 1.5.0 + * @access public + * + * @return bool + */ + function using_index_permalinks() { + if ( empty($this->permalink_structure) ) + return false; + + // If the index is not in the permalink, we're using mod_rewrite. + if ( preg_match('#^/*' . $this->index . '#', $this->permalink_structure) ) + return true; + + return false; + } + + /** + * Whether permalinks are being used and rewrite module is enabled. + * + * Using permalinks and index.php is not in the URL. + * + * @since 1.5.0 + * @access public + * + * @return bool + */ + function using_mod_rewrite_permalinks() { + if ( $this->using_permalinks() && ! $this->using_index_permalinks() ) + return true; + else + return false; + } + + /** + * Index for matches for usage in preg_*() functions. + * + * The format of the string is, with empty matches property value, '$NUM'. + * The 'NUM' will be replaced with the value in the $number parameter. With + * the matches property not empty, the value of the returned string will + * contain that value of the matches property. The format then will be + * '$MATCHES[NUM]', with MATCHES as the value in the property and NUM the + * value of the $number parameter. + * + * @since 1.5.0 + * @access public + * + * @param int $number Index number. + * @return string + */ + function preg_index($number) { + $match_prefix = '$'; + $match_suffix = ''; + + if ( ! empty($this->matches) ) { + $match_prefix = '$' . $this->matches . '['; + $match_suffix = ']'; + } + + return "$match_prefix$number$match_suffix"; + } + + /** + * Retrieve all page and attachments for pages URIs. + * + * The attachments are for those that have pages as parents and will be + * retrieved. + * + * @since 2.5.0 + * @access public + * + * @return array Array of page URIs as first element and attachment URIs as second element. + */ + function page_uri_index() { + global $wpdb; + + //get pages in order of hierarchy, i.e. children after parents + $posts = get_page_hierarchy($wpdb->get_results("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'page'")); + + // If we have no pages get out quick + if ( !$posts ) + return array( array(), array() ); + + //now reverse it, because we need parents after children for rewrite rules to work properly + $posts = array_reverse($posts, true); + + $page_uris = array(); + $page_attachment_uris = array(); + + foreach ( $posts as $id => $post ) { + // URL => page name + $uri = get_page_uri($id); + $attachments = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = %d", $id )); + if ( !empty($attachments) ) { + foreach ( $attachments as $attachment ) { + $attach_uri = get_page_uri($attachment->ID); + $page_attachment_uris[$attach_uri] = $attachment->ID; + } + } + + $page_uris[$uri] = $id; + } + + return array( $page_uris, $page_attachment_uris ); + } + + /** + * Retrieve all of the rewrite rules for pages. + * + * If the 'use_verbose_page_rules' property is false, then there will only + * be a single rewrite rule for pages for those matching '%pagename%'. With + * the property set to true, the attachments and the pages will be added for + * each individual attachment URI and page URI, respectively. + * + * @since 1.5.0 + * @access public + * + * @return array + */ + function page_rewrite_rules() { + $rewrite_rules = array(); + $page_structure = $this->get_page_permastruct(); + + if ( ! $this->use_verbose_page_rules ) { + $this->add_rewrite_tag('%pagename%', "(.+?)", 'pagename='); + $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); + return $rewrite_rules; + } + + $page_uris = $this->page_uri_index(); + $uris = $page_uris[0]; + $attachment_uris = $page_uris[1]; + + if ( is_array( $attachment_uris ) ) { + foreach ( $attachment_uris as $uri => $pagename ) { + $this->add_rewrite_tag('%pagename%', "($uri)", 'attachment='); + $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); + } + } + if ( is_array( $uris ) ) { + foreach ( $uris as $uri => $pagename ) { + $this->add_rewrite_tag('%pagename%', "($uri)", 'pagename='); + $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); + } + } + + return $rewrite_rules; + } + + /** + * Retrieve date permalink structure, with year, month, and day. + * + * The permalink structure for the date, if not set already depends on the + * permalink structure. It can be one of three formats. The first is year, + * month, day; the second is day, month, year; and the last format is month, + * day, year. These are matched against the permalink structure for which + * one is used. If none matches, then the default will be used, which is + * year, month, day. + * + * Prevents post ID and date permalinks from overlapping. In the case of + * post_id, the date permalink will be prepended with front permalink with + * 'date/' before the actual permalink to form the complete date permalink + * structure. + * + * @since 1.5.0 + * @access public + * + * @return bool|string False on no permalink structure. Date permalink structure. + */ + function get_date_permastruct() { + if ( isset($this->date_structure) ) + return $this->date_structure; + + if ( empty($this->permalink_structure) ) { + $this->date_structure = ''; + return false; + } + + // The date permalink must have year, month, and day separated by slashes. + $endians = array('%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%'); + + $this->date_structure = ''; + $date_endian = ''; + + foreach ( $endians as $endian ) { + if ( false !== strpos($this->permalink_structure, $endian) ) { + $date_endian= $endian; + break; + } + } + + if ( empty($date_endian) ) + $date_endian = '%year%/%monthnum%/%day%'; + + // Do not allow the date tags and %post_id% to overlap in the permalink + // structure. If they do, move the date tags to $front/date/. + $front = $this->front; + preg_match_all('/%.+?%/', $this->permalink_structure, $tokens); + $tok_index = 1; + foreach ( (array) $tokens[0] as $token) { + if ( '%post_id%' == $token && ($tok_index <= 3) ) { + $front = $front . 'date/'; + break; + } + $tok_index++; + } + + $this->date_structure = $front . $date_endian; + + return $this->date_structure; + } + + /** + * Retrieve the year permalink structure without month and day. + * + * Gets the date permalink structure and strips out the month and day + * permalink structures. + * + * @since 1.5.0 + * @access public + * + * @return bool|string False on failure. Year structure on success. + */ + function get_year_permastruct() { + $structure = $this->get_date_permastruct($this->permalink_structure); + + if ( empty($structure) ) + return false; + + $structure = str_replace('%monthnum%', '', $structure); + $structure = str_replace('%day%', '', $structure); + + $structure = preg_replace('#/+#', '/', $structure); + + return $structure; + } + + /** + * Retrieve the month permalink structure without day and with year. + * + * Gets the date permalink structure and strips out the day permalink + * structures. Keeps the year permalink structure. + * + * @since 1.5.0 + * @access public + * + * @return bool|string False on failure. Year/Month structure on success. + */ + function get_month_permastruct() { + $structure = $this->get_date_permastruct($this->permalink_structure); + + if ( empty($structure) ) + return false; + + $structure = str_replace('%day%', '', $structure); + + $structure = preg_replace('#/+#', '/', $structure); + + return $structure; + } + + /** + * Retrieve the day permalink structure with month and year. + * + * Keeps date permalink structure with all year, month, and day. + * + * @since 1.5.0 + * @access public + * + * @return bool|string False on failure. Year/Month/Day structure on success. + */ + function get_day_permastruct() { + return $this->get_date_permastruct($this->permalink_structure); + } + + /** + * Retrieve the permalink structure for categories. + * + * If the category_base property has no value, then the category structure + * will have the front property value, followed by 'category', and finally + * '%category%'. If it does, then the root property will be used, along with + * the category_base property value. + * + * @since 1.5.0 + * @access public + * + * @return bool|string False on failure. Category permalink structure. + */ + function get_category_permastruct() { + return $this->get_extra_permastruct('category'); + } + + /** + * Retrieve the permalink structure for tags. + * + * If the tag_base property has no value, then the tag structure will have + * the front property value, followed by 'tag', and finally '%tag%'. If it + * does, then the root property will be used, along with the tag_base + * property value. + * + * @since 2.3.0 + * @access public + * + * @return bool|string False on failure. Tag permalink structure. + */ + function get_tag_permastruct() { + return $this->get_extra_permastruct('post_tag'); + } + + /** + * Retrieve extra permalink structure by name. + * + * @since 2.5.0 + * @access public + * + * @param string $name Permalink structure name. + * @return string|bool False if not found. Permalink structure string. + */ + function get_extra_permastruct($name) { + if ( empty($this->permalink_structure) ) + return false; + + if ( isset($this->extra_permastructs[$name]) ) + return $this->extra_permastructs[$name][0]; + + return false; + } + + /** + * Retrieve the author permalink structure. + * + * The permalink structure is front property, author base, and finally + * '/%author%'. Will set the author_structure property and then return it + * without attempting to set the value again. + * + * @since 1.5.0 + * @access public + * + * @return string|bool False if not found. Permalink structure string. + */ + function get_author_permastruct() { + if ( isset($this->author_structure) ) + return $this->author_structure; + + if ( empty($this->permalink_structure) ) { + $this->author_structure = ''; + return false; + } + + $this->author_structure = $this->front . $this->author_base . '/%author%'; + + return $this->author_structure; + } + + /** + * Retrieve the search permalink structure. + * + * The permalink structure is root property, search base, and finally + * '/%search%'. Will set the search_structure property and then return it + * without attempting to set the value again. + * + * @since 1.5.0 + * @access public + * + * @return string|bool False if not found. Permalink structure string. + */ + function get_search_permastruct() { + if ( isset($this->search_structure) ) + return $this->search_structure; + + if ( empty($this->permalink_structure) ) { + $this->search_structure = ''; + return false; + } + + $this->search_structure = $this->root . $this->search_base . '/%search%'; + + return $this->search_structure; + } + + /** + * Retrieve the page permalink structure. + * + * The permalink structure is root property, and '%pagename%'. Will set the + * page_structure property and then return it without attempting to set the + * value again. + * + * @since 1.5.0 + * @access public + * + * @return string|bool False if not found. Permalink structure string. + */ + function get_page_permastruct() { + if ( isset($this->page_structure) ) + return $this->page_structure; + + if (empty($this->permalink_structure)) { + $this->page_structure = ''; + return false; + } + + $this->page_structure = $this->root . '%pagename%'; + + return $this->page_structure; + } + + /** + * Retrieve the feed permalink structure. + * + * The permalink structure is root property, feed base, and finally + * '/%feed%'. Will set the feed_structure property and then return it + * without attempting to set the value again. + * + * @since 1.5.0 + * @access public + * + * @return string|bool False if not found. Permalink structure string. + */ + function get_feed_permastruct() { + if ( isset($this->feed_structure) ) + return $this->feed_structure; + + if ( empty($this->permalink_structure) ) { + $this->feed_structure = ''; + return false; + } + + $this->feed_structure = $this->root . $this->feed_base . '/%feed%'; + + return $this->feed_structure; + } + + /** + * Retrieve the comment feed permalink structure. + * + * The permalink structure is root property, comment base property, feed + * base and finally '/%feed%'. Will set the comment_feed_structure property + * and then return it without attempting to set the value again. + * + * @since 1.5.0 + * @access public + * + * @return string|bool False if not found. Permalink structure string. + */ + function get_comment_feed_permastruct() { + if ( isset($this->comment_feed_structure) ) + return $this->comment_feed_structure; + + if (empty($this->permalink_structure)) { + $this->comment_feed_structure = ''; + return false; + } + + $this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%'; + + return $this->comment_feed_structure; + } + + /** + * Append or update tag, pattern, and query for replacement. + * + * If the tag already exists, replace the existing pattern and query for + * that tag, otherwise add the new tag, pattern, and query to the end of the + * arrays. + * + * @internal What is the purpose of this function again? Need to finish long + * description. + * + * @since 1.5.0 + * @access public + * + * @param string $tag Append tag to rewritecode property array. + * @param string $pattern Append pattern to rewritereplace property array. + * @param string $query Append query to queryreplace property array. + */ + function add_rewrite_tag($tag, $pattern, $query) { + $position = array_search($tag, $this->rewritecode); + if ( false !== $position && null !== $position ) { + $this->rewritereplace[$position] = $pattern; + $this->queryreplace[$position] = $query; + } else { + $this->rewritecode[] = $tag; + $this->rewritereplace[] = $pattern; + $this->queryreplace[] = $query; + } + } + + /** + * Generate the rules from permalink structure. + * + * The main WP_Rewrite function for building the rewrite rule list. The + * contents of the function is a mix of black magic and regular expressions, + * so best just ignore the contents and move to the parameters. + * + * @since 1.5.0 + * @access public + * + * @param string $permalink_structure The permalink structure. + * @param int $ep_mask Optional, default is EP_NONE. Endpoint constant, see EP_* constants. + * @param bool $paged Optional, default is true. Whether permalink request is paged. + * @param bool $feed Optional, default is true. Whether for feed. + * @param bool $forcomments Optional, default is false. Whether for comments. + * @param bool $walk_dirs Optional, default is true. Whether to create list of directories to walk over. + * @param bool $endpoints Optional, default is true. Whether endpoints are enabled. + * @return array Rewrite rule list. + */ + function generate_rewrite_rules($permalink_structure, $ep_mask = EP_NONE, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true) { + //build a regex to match the feed section of URLs, something like (feed|atom|rss|rss2)/? + $feedregex2 = ''; + foreach ( (array) $this->feeds as $feed_name) + $feedregex2 .= $feed_name . '|'; + $feedregex2 = '(' . trim($feedregex2, '|') . ')/?$'; + + //$feedregex is identical but with /feed/ added on as well, so URLs like /feed/atom + //and /atom are both possible + $feedregex = $this->feed_base . '/' . $feedregex2; + + //build a regex to match the trackback and page/xx parts of URLs + $trackbackregex = 'trackback/?$'; + $pageregex = $this->pagination_base . '/?([0-9]{1,})/?$'; + $commentregex = 'comment-page-([0-9]{1,})/?$'; + + //build up an array of endpoint regexes to append => queries to append + if ( $endpoints ) { + $ep_query_append = array (); + foreach ( (array) $this->endpoints as $endpoint) { + //match everything after the endpoint name, but allow for nothing to appear there + $epmatch = $endpoint[1] . '(/(.*))?/?$'; + //this will be appended on to the rest of the query for each dir + $epquery = '&' . $endpoint[1] . '='; + $ep_query_append[$epmatch] = array ( $endpoint[0], $epquery ); + } + } + + //get everything up to the first rewrite tag + $front = substr($permalink_structure, 0, strpos($permalink_structure, '%')); + //build an array of the tags (note that said array ends up being in $tokens[0]) + preg_match_all('/%.+?%/', $permalink_structure, $tokens); + + $num_tokens = count($tokens[0]); + + $index = $this->index; //probably 'index.php' + $feedindex = $index; + $trackbackindex = $index; + //build a list from the rewritecode and queryreplace arrays, that will look something like + //tagname=$matches[i] where i is the current $i + for ( $i = 0; $i < $num_tokens; ++$i ) { + if ( 0 < $i ) + $queries[$i] = $queries[$i - 1] . '&'; + else + $queries[$i] = ''; + + $query_token = str_replace($this->rewritecode, $this->queryreplace, $tokens[0][$i]) . $this->preg_index($i+1); + $queries[$i] .= $query_token; + } + + //get the structure, minus any cruft (stuff that isn't tags) at the front + $structure = $permalink_structure; + if ( $front != '/' ) + $structure = str_replace($front, '', $structure); + + //create a list of dirs to walk over, making rewrite rules for each level + //so for example, a $structure of /%year%/%month%/%postname% would create + //rewrite rules for /%year%/, /%year%/%month%/ and /%year%/%month%/%postname% + $structure = trim($structure, '/'); + $dirs = $walk_dirs ? explode('/', $structure) : array( $structure ); + $num_dirs = count($dirs); + + //strip slashes from the front of $front + $front = preg_replace('|^/+|', '', $front); + + //the main workhorse loop + $post_rewrite = array(); + $struct = $front; + for ( $j = 0; $j < $num_dirs; ++$j ) { + //get the struct for this dir, and trim slashes off the front + $struct .= $dirs[$j] . '/'; //accumulate. see comment near explode('/', $structure) above + $struct = ltrim($struct, '/'); + + //replace tags with regexes + $match = str_replace($this->rewritecode, $this->rewritereplace, $struct); + + //make a list of tags, and store how many there are in $num_toks + $num_toks = preg_match_all('/%.+?%/', $struct, $toks); + + //get the 'tagname=$matches[i]' + $query = ( isset($queries) && is_array($queries) ) ? $queries[$num_toks - 1] : ''; + + //set up $ep_mask_specific which is used to match more specific URL types + switch ( $dirs[$j] ) { + case '%year%': + $ep_mask_specific = EP_YEAR; + break; + case '%monthnum%': + $ep_mask_specific = EP_MONTH; + break; + case '%day%': + $ep_mask_specific = EP_DAY; + break; + default: + $ep_mask_specific = EP_NONE; + } + + //create query for /page/xx + $pagematch = $match . $pageregex; + $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1); + + //create query for /comment-page-xx + $commentmatch = $match . $commentregex; + $commentquery = $index . '?' . $query . '&cpage=' . $this->preg_index($num_toks + 1); + + if ( get_option('page_on_front') ) { + //create query for Root /comment-page-xx + $rootcommentmatch = $match . $commentregex; + $rootcommentquery = $index . '?' . $query . '&page_id=' . get_option('page_on_front') . '&cpage=' . $this->preg_index($num_toks + 1); + } + + //create query for /feed/(feed|atom|rss|rss2|rdf) + $feedmatch = $match . $feedregex; + $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); + + //create query for /(feed|atom|rss|rss2|rdf) (see comment near creation of $feedregex) + $feedmatch2 = $match . $feedregex2; + $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); + + //if asked to, turn the feed queries into comment feed ones + if ( $forcomments ) { + $feedquery .= '&withcomments=1'; + $feedquery2 .= '&withcomments=1'; + } + + //start creating the array of rewrites for this dir + $rewrite = array(); + if ( $feed ) //...adding on /feed/ regexes => queries + $rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2); + if ( $paged ) //...and /page/xx ones + $rewrite = array_merge($rewrite, array($pagematch => $pagequery)); + + //only on pages with comments add ../comment-page-xx/ + if ( EP_PAGES & $ep_mask || EP_PERMALINK & $ep_mask ) + $rewrite = array_merge($rewrite, array($commentmatch => $commentquery)); + else if ( EP_ROOT & $ep_mask && get_option('page_on_front') ) + $rewrite = array_merge($rewrite, array($rootcommentmatch => $rootcommentquery)); + + //do endpoints + if ( $endpoints ) { + foreach ( (array) $ep_query_append as $regex => $ep) { + //add the endpoints on if the mask fits + if ( $ep[0] & $ep_mask || $ep[0] & $ep_mask_specific ) + $rewrite[$match . $regex] = $index . '?' . $query . $ep[1] . $this->preg_index($num_toks + 2); + } + } + + //if we've got some tags in this dir + if ( $num_toks ) { + $post = false; + $page = false; + + //check to see if this dir is permalink-level: i.e. the structure specifies an + //individual post. Do this by checking it contains at least one of 1) post name, + //2) post ID, 3) page name, 4) timestamp (year, month, day, hour, second and + //minute all present). Set these flags now as we need them for the endpoints. + if ( strpos($struct, '%postname%') !== false + || strpos($struct, '%post_id%') !== false + || strpos($struct, '%pagename%') !== false + || (strpos($struct, '%year%') !== false && strpos($struct, '%monthnum%') !== false && strpos($struct, '%day%') !== false && strpos($struct, '%hour%') !== false && strpos($struct, '%minute%') !== false && strpos($struct, '%second%') !== false) + ) { + $post = true; + if ( strpos($struct, '%pagename%') !== false ) + $page = true; + } + + if ( ! $post ) { + // For custom post types, we need to add on endpoints as well. + foreach ( get_post_types( array('_builtin' => false ) ) as $ptype ) { + if ( strpos($struct, "%$ptype%") !== false ) { + $post = true; + $page = is_post_type_hierarchical( $ptype ); // This is for page style attachment url's + break; + } + } + } + + //if we're creating rules for a permalink, do all the endpoints like attachments etc + if ( $post ) { + //create query and regex for trackback + $trackbackmatch = $match . $trackbackregex; + $trackbackquery = $trackbackindex . '?' . $query . '&tb=1'; + //trim slashes from the end of the regex for this dir + $match = rtrim($match, '/'); + //get rid of brackets + $submatchbase = str_replace( array('(', ')'), '', $match); + + //add a rule for at attachments, which take the form of /some-text + $sub1 = $submatchbase . '/([^/]+)/'; + $sub1tb = $sub1 . $trackbackregex; //add trackback regex /trackback/... + $sub1feed = $sub1 . $feedregex; //and /feed/(atom|...) + $sub1feed2 = $sub1 . $feedregex2; //and /(feed|atom...) + $sub1comment = $sub1 . $commentregex; //and /comment-page-xx + //add an ? as we don't have to match that last slash, and finally a $ so we + //match to the end of the URL + + //add another rule to match attachments in the explicit form: + ///attachment/some-text + $sub2 = $submatchbase . '/attachment/([^/]+)/'; + $sub2tb = $sub2 . $trackbackregex; //and add trackbacks /attachment/trackback + $sub2feed = $sub2 . $feedregex; //feeds, /attachment/feed/(atom|...) + $sub2feed2 = $sub2 . $feedregex2; //and feeds again on to this /attachment/(feed|atom...) + $sub2comment = $sub2 . $commentregex; //and /comment-page-xx + + //create queries for these extra tag-ons we've just dealt with + $subquery = $index . '?attachment=' . $this->preg_index(1); + $subtbquery = $subquery . '&tb=1'; + $subfeedquery = $subquery . '&feed=' . $this->preg_index(2); + $subcommentquery = $subquery . '&cpage=' . $this->preg_index(2); + + //do endpoints for attachments + if ( !empty($endpoints) ) { + foreach ( (array) $ep_query_append as $regex => $ep ) { + if ( $ep[0] & EP_ATTACHMENT ) { + $rewrite[$sub1 . $regex] = $subquery . $ep[1] . $this->preg_index(2); + $rewrite[$sub2 . $regex] = $subquery . $ep[1] . $this->preg_index(2); + } + } + } + + //now we've finished with endpoints, finish off the $sub1 and $sub2 matches + $sub1 .= '?$'; + $sub2 .= '?$'; + + //allow URLs like /2 for /page/2 + $match = $match . '(/[0-9]+)?/?$'; + $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1); + } else { //not matching a permalink so this is a lot simpler + //close the match and finalise the query + $match .= '?$'; + $query = $index . '?' . $query; + } + + //create the final array for this dir by joining the $rewrite array (which currently + //only contains rules/queries for trackback, pages etc) to the main regex/query for + //this dir + $rewrite = array_merge($rewrite, array($match => $query)); + + //if we're matching a permalink, add those extras (attachments etc) on + if ( $post ) { + //add trackback + $rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite); + + //add regexes/queries for attachments, attachment trackbacks and so on + if ( ! $page ) //require /attachment/stuff form for pages because of confusion with subpages + $rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery, $sub1comment => $subcommentquery)); + $rewrite = array_merge(array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery, $sub2comment => $subcommentquery), $rewrite); + } + } //if($num_toks) + //add the rules for this dir to the accumulating $post_rewrite + $post_rewrite = array_merge($rewrite, $post_rewrite); + } //foreach ($dir) + return $post_rewrite; //the finished rules. phew! + } + + /** + * Generate Rewrite rules with permalink structure and walking directory only. + * + * Shorten version of {@link WP_Rewrite::generate_rewrite_rules()} that + * allows for shorter list of parameters. See the method for longer + * description of what generating rewrite rules does. + * + * @uses WP_Rewrite::generate_rewrite_rules() See for long description and rest of parameters. + * @since 1.5.0 + * @access public + * + * @param string $permalink_structure The permalink structure to generate rules. + * @param bool $walk_dirs Optional, default is false. Whether to create list of directories to walk over. + * @return array + */ + function generate_rewrite_rule($permalink_structure, $walk_dirs = false) { + return $this->generate_rewrite_rules($permalink_structure, EP_NONE, false, false, false, $walk_dirs); + } + + /** + * Construct rewrite matches and queries from permalink structure. + * + * Runs the action 'generate_rewrite_rules' with the parameter that is an + * reference to the current WP_Rewrite instance to further manipulate the + * permalink structures and rewrite rules. Runs the 'rewrite_rules_array' + * filter on the full rewrite rule array. + * + * There are two ways to manipulate the rewrite rules, one by hooking into + * the 'generate_rewrite_rules' action and gaining full control of the + * object or just manipulating the rewrite rule array before it is passed + * from the function. + * + * @since 1.5.0 + * @access public + * + * @return array An associate array of matches and queries. + */ + function rewrite_rules() { + $rewrite = array(); + + if ( empty($this->permalink_structure) ) + return $rewrite; + + // robots.txt -only if installed at the root + $home_path = parse_url( home_url() ); + $robots_rewrite = ( empty( $home_path['path'] ) || '/' == $home_path['path'] ) ? array( 'robots\.txt$' => $this->index . '?robots=1' ) : array(); + + // Default Feed rules - These are require to allow for the direct access files to work with permalink structure starting with %category% + $default_feeds = array( '.*wp-atom.php$' => $this->index . '?feed=atom', + '.*wp-rdf.php$' => $this->index . '?feed=rdf', + '.*wp-rss.php$' => $this->index . '?feed=rss', + '.*wp-rss2.php$' => $this->index . '?feed=rss2', + '.*wp-feed.php$' => $this->index . '?feed=feed', + '.*wp-commentsrss2.php$' => $this->index . '?feed=rss2&withcomments=1'); + + // Registration rules + $registration_pages = array(); + if ( is_multisite() && is_main_site() ) { + $registration_pages['.*wp-signup.php$'] = $this->index . '?signup=true'; + $registration_pages['.*wp-activate.php$'] = $this->index . '?activate=true'; + } + + // Post + $post_rewrite = $this->generate_rewrite_rules($this->permalink_structure, EP_PERMALINK); + $post_rewrite = apply_filters('post_rewrite_rules', $post_rewrite); + + // Date + $date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct(), EP_DATE); + $date_rewrite = apply_filters('date_rewrite_rules', $date_rewrite); + + // Root + $root_rewrite = $this->generate_rewrite_rules($this->root . '/', EP_ROOT); + $root_rewrite = apply_filters('root_rewrite_rules', $root_rewrite); + + // Comments + $comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, EP_COMMENTS, true, true, true, false); + $comments_rewrite = apply_filters('comments_rewrite_rules', $comments_rewrite); + + // Search + $search_structure = $this->get_search_permastruct(); + $search_rewrite = $this->generate_rewrite_rules($search_structure, EP_SEARCH); + $search_rewrite = apply_filters('search_rewrite_rules', $search_rewrite); + + // Authors + $author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct(), EP_AUTHORS); + $author_rewrite = apply_filters('author_rewrite_rules', $author_rewrite); + + // Pages + $page_rewrite = $this->page_rewrite_rules(); + $page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite); + + // Extra permastructs + foreach ( $this->extra_permastructs as $permastructname => $permastruct ) { + if ( is_array($permastruct) ) + $rules = $this->generate_rewrite_rules($permastruct[0], $permastruct[1]); + else + $rules = $this->generate_rewrite_rules($permastruct, EP_NONE); + + $rules = apply_filters($permastructname . '_rewrite_rules', $rules); + if ( 'post_tag' == $permastructname ) + $rules = apply_filters('tag_rewrite_rules', $rules); + + $this->extra_rules_top = array_merge($this->extra_rules_top, $rules); + } + + // Put them together. + if ( $this->use_verbose_page_rules ) + $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $registration_pages, $page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules); + else + $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules); + + do_action_ref_array('generate_rewrite_rules', array(&$this)); + $this->rules = apply_filters('rewrite_rules_array', $this->rules); + + return $this->rules; + } + + /** + * Retrieve the rewrite rules. + * + * The difference between this method and {@link + * WP_Rewrite::rewrite_rules()} is that this method stores the rewrite rules + * in the 'rewrite_rules' option and retrieves it. This prevents having to + * process all of the permalinks to get the rewrite rules in the form of + * caching. + * + * @since 1.5.0 + * @access public + * + * @return array Rewrite rules. + */ + function wp_rewrite_rules() { + $this->rules = get_option('rewrite_rules'); + if ( empty($this->rules) ) { + $this->matches = 'matches'; + $this->rewrite_rules(); + update_option('rewrite_rules', $this->rules); + } + + return $this->rules; + } + + /** + * Retrieve mod_rewrite formatted rewrite rules to write to .htaccess. + * + * Does not actually write to the .htaccess file, but creates the rules for + * the process that will. + * + * Will add the non_wp_rules property rules to the .htaccess file before + * the WordPress rewrite rules one. + * + * @since 1.5.0 + * @access public + * + * @return string + */ + function mod_rewrite_rules() { + if ( ! $this->using_permalinks() ) + return ''; + + $site_root = parse_url(get_option('siteurl')); + if ( isset( $site_root['path'] ) ) + $site_root = trailingslashit($site_root['path']); + + $home_root = parse_url(home_url()); + if ( isset( $home_root['path'] ) ) + $home_root = trailingslashit($home_root['path']); + else + $home_root = '/'; + + $rules = "\n"; + $rules .= "RewriteEngine On\n"; + $rules .= "RewriteBase $home_root\n"; + $rules .= "RewriteRule ^index\.php$ - [L]\n"; // Prevent -f checks on index.php. + + //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all) + foreach ( (array) $this->non_wp_rules as $match => $query) { + // Apache 1.3 does not support the reluctant (non-greedy) modifier. + $match = str_replace('.+?', '.+', $match); + + // If the match is unanchored and greedy, prepend rewrite conditions + // to avoid infinite redirects and eclipsing of real files. + //if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) { + //nada. + //} + + $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; + } + + if ( $this->use_verbose_rules ) { + $this->matches = ''; + $rewrite = $this->rewrite_rules(); + $num_rules = count($rewrite); + $rules .= "RewriteCond %{REQUEST_FILENAME} -f [OR]\n" . + "RewriteCond %{REQUEST_FILENAME} -d\n" . + "RewriteRule ^.*$ - [S=$num_rules]\n"; + + foreach ( (array) $rewrite as $match => $query) { + // Apache 1.3 does not support the reluctant (non-greedy) modifier. + $match = str_replace('.+?', '.+', $match); + + // If the match is unanchored and greedy, prepend rewrite conditions + // to avoid infinite redirects and eclipsing of real files. + //if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) { + //nada. + //} + + if ( strpos($query, $this->index) !== false ) + $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; + else + $rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n"; + } + } else { + $rules .= "RewriteCond %{REQUEST_FILENAME} !-f\n" . + "RewriteCond %{REQUEST_FILENAME} !-d\n" . + "RewriteRule . {$home_root}{$this->index} [L]\n"; + } + + $rules .= "\n"; + + $rules = apply_filters('mod_rewrite_rules', $rules); + $rules = apply_filters('rewrite_rules', $rules); // Deprecated + + return $rules; + } + + /** + * Retrieve IIS7 URL Rewrite formatted rewrite rules to write to web.config file. + * + * Does not actually write to the web.config file, but creates the rules for + * the process that will. + * + * @since 2.8.0 + * @access public + * + * @return string + */ + function iis7_url_rewrite_rules( $add_parent_tags = false ) { + + if ( ! $this->using_permalinks() ) + return ''; + $rules = ''; + if ( $add_parent_tags ) { + $rules .= ' + + + '; + } + if ( !is_multisite() ) { + $rules .= ' + + + + + + + + '; + } else { + if (is_subdomain_install()) { + $rules .= ' + + + + + + + + + + + + + + + + + + + + '; + } else { + $rules .= ' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + } + } + if ( $add_parent_tags ) { + $rules .= ' + + + +'; + } + + $rules = apply_filters('iis7_url_rewrite_rules', $rules); + + return $rules; + } + + /** + * Add a straight rewrite rule. + * + * Any value in the $after parameter that isn't 'bottom' will be placed at + * the top of the rules. + * + * @since 2.1.0 + * @access public + * + * @param string $regex Regular expression to match against request. + * @param string $redirect URL regex redirects to when regex matches request. + * @param string $after Optional, default is bottom. Location to place rule. + */ + function add_rule($regex, $redirect, $after = 'bottom') { + //get everything up to the first ? + $index = (strpos($redirect, '?') == false ? strlen($redirect) : strpos($redirect, '?')); + $front = substr($redirect, 0, $index); + if ( $front != $this->index ) { //it doesn't redirect to WP's index.php + $this->add_external_rule($regex, $redirect); + } else { + if ( 'bottom' == $after) + $this->extra_rules = array_merge($this->extra_rules, array($regex => $redirect)); + else + $this->extra_rules_top = array_merge($this->extra_rules_top, array($regex => $redirect)); + //$this->extra_rules[$regex] = $redirect; + } + } + + /** + * Add a rule that doesn't redirect to index.php. + * + * Can redirect to any place. + * + * @since 2.1.0 + * @access public + * + * @param string $regex Regular expression to match against request. + * @param string $redirect URL regex redirects to when regex matches request. + */ + function add_external_rule($regex, $redirect) { + $this->non_wp_rules[$regex] = $redirect; + } + + /** + * Add an endpoint, like /trackback/. + * + * To be inserted after certain URL types (specified in $places). + * + * @since 2.1.0 + * @access public + * + * @param string $name Name of endpoint. + * @param array $places URL types that endpoint can be used. + */ + function add_endpoint($name, $places) { + global $wp; + $this->endpoints[] = array ( $places, $name ); + $wp->add_query_var($name); + } + + /** + * Add permalink structure. + * + * These are added along with the extra rewrite rules that are merged to the + * top. + * + * @since 2.5.0 + * @access public + * + * @param string $name Name for permalink structure. + * @param string $struct Permalink structure. + * @param bool $with_front Prepend front base to permalink structure. + */ + function add_permastruct($name, $struct, $with_front = true, $ep_mask = EP_NONE) { + if ( $with_front ) + $struct = $this->front . $struct; + else + $struct = $this->root . $struct; + $this->extra_permastructs[$name] = array($struct, $ep_mask); + } + + /** + * Remove rewrite rules and then recreate rewrite rules. + * + * Calls {@link WP_Rewrite::wp_rewrite_rules()} after removing the + * 'rewrite_rules' option. If the function named 'save_mod_rewrite_rules' + * exists, it will be called. + * + * @since 2.0.1 + * @access public + * @param bool $hard Whether to update .htaccess (hard flush) or just update rewrite_rules option (soft flush). Default is true (hard). + */ + function flush_rules($hard = true) { + delete_option('rewrite_rules'); + $this->wp_rewrite_rules(); + if ( $hard && function_exists('save_mod_rewrite_rules') ) + save_mod_rewrite_rules(); + if ( $hard && function_exists('iis7_save_url_rewrite_rules') ) + iis7_save_url_rewrite_rules(); + } + + /** + * Sets up the object's properties. + * + * The 'use_verbose_page_rules' object property will be set to true if the + * permalink structure begins with one of the following: '%postname%', '%category%', + * '%tag%', or '%author%'. + * + * @since 1.5.0 + * @access public + */ + function init() { + $this->extra_rules = $this->non_wp_rules = $this->endpoints = array(); + $this->permalink_structure = get_option('permalink_structure'); + $this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%')); + $this->root = ''; + if ( $this->using_index_permalinks() ) + $this->root = $this->index . '/'; + unset($this->author_structure); + unset($this->date_structure); + unset($this->page_structure); + unset($this->search_structure); + unset($this->feed_structure); + unset($this->comment_feed_structure); + $this->use_trailing_slashes = ( '/' == substr($this->permalink_structure, -1, 1) ); + + // Enable generic rules for pages if permalink structure doesn't begin with a wildcard. + if ( preg_match("/^[^%]*%(?:postname|category|tag|author)%/", $this->permalink_structure) ) + $this->use_verbose_page_rules = true; + else + $this->use_verbose_page_rules = false; + } + + /** + * Set the main permalink structure for the blog. + * + * Will update the 'permalink_structure' option, if there is a difference + * between the current permalink structure and the parameter value. Calls + * {@link WP_Rewrite::init()} after the option is updated. + * + * Fires the 'permalink_structure_changed' action once the init call has + * processed passing the old and new values + * + * @since 1.5.0 + * @access public + * + * @param string $permalink_structure Permalink structure. + */ + function set_permalink_structure($permalink_structure) { + if ( $permalink_structure != $this->permalink_structure ) { + update_option('permalink_structure', $permalink_structure); + $this->init(); + do_action('permalink_structure_changed', $this->permalink_structure, $permalink_structure); + } + } + + /** + * Set the category base for the category permalink. + * + * Will update the 'category_base' option, if there is a difference between + * the current category base and the parameter value. Calls + * {@link WP_Rewrite::init()} after the option is updated. + * + * @since 1.5.0 + * @access public + * + * @param string $category_base Category permalink structure base. + */ + function set_category_base($category_base) { + if ( $category_base != get_option('category_base') ) { + update_option('category_base', $category_base); + $this->init(); + } + } + + /** + * Set the tag base for the tag permalink. + * + * Will update the 'tag_base' option, if there is a difference between the + * current tag base and the parameter value. Calls + * {@link WP_Rewrite::init()} after the option is updated. + * + * @since 2.3.0 + * @access public + * + * @param string $tag_base Tag permalink structure base. + */ + function set_tag_base( $tag_base ) { + if ( $tag_base != get_option( 'tag_base') ) { + update_option( 'tag_base', $tag_base ); + $this->init(); + } + } + + /** + * PHP4 Constructor - Calls init(), which runs setup. + * + * @since 1.5.0 + * @access public + * + * @return WP_Rewrite + */ + function WP_Rewrite() { + $this->init(); + } +} + +?> diff --git a/src/wp-includes/rss-functions.php b/src/wp-includes/rss-functions.php new file mode 100644 index 00000000..ea326928 --- /dev/null +++ b/src/wp-includes/rss-functions.php @@ -0,0 +1,10 @@ + diff --git a/src/wp-includes/rss.php b/src/wp-includes/rss.php new file mode 100644 index 00000000..f23730d0 --- /dev/null +++ b/src/wp-includes/rss.php @@ -0,0 +1,939 @@ + + * @version 0.51 + * @license GPL + * + * @package External + * @subpackage MagpieRSS + */ + +/** + * Deprecated. Use SimplePie (class-simplepie.php) instead. + */ +_deprecated_file( basename( __FILE__ ), '3.0', WPINC . '/class-simplepie.php' ); + +/* + * Hook to use another RSS object instead of MagpieRSS + */ +do_action('load_feed_engine'); + +/** RSS feed constant. */ +define('RSS', 'RSS'); +define('ATOM', 'Atom'); +define('MAGPIE_USER_AGENT', 'WordPress/' . $GLOBALS['wp_version']); + +class MagpieRSS { + var $parser; + var $current_item = array(); // item currently being parsed + var $items = array(); // collection of parsed items + var $channel = array(); // hash of channel fields + var $textinput = array(); + var $image = array(); + var $feed_type; + var $feed_version; + + // parser variables + var $stack = array(); // parser stack + var $inchannel = false; + var $initem = false; + var $incontent = false; // if in Atom field + var $intextinput = false; + var $inimage = false; + var $current_field = ''; + var $current_namespace = false; + + //var $ERROR = ""; + + var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright'); + + function MagpieRSS ($source) { + + # if PHP xml isn't compiled in, die + # + if ( !function_exists('xml_parser_create') ) + trigger_error( "Failed to load PHP's XML Extension. http://www.php.net/manual/en/ref.xml.php" ); + + $parser = @xml_parser_create(); + + if ( !is_resource($parser) ) + trigger_error( "Failed to create an instance of PHP's XML parser. http://www.php.net/manual/en/ref.xml.php"); + + + $this->parser = $parser; + + # pass in parser, and a reference to this object + # set up handlers + # + xml_set_object( $this->parser, $this ); + xml_set_element_handler($this->parser, + 'feed_start_element', 'feed_end_element' ); + + xml_set_character_data_handler( $this->parser, 'feed_cdata' ); + + $status = xml_parse( $this->parser, $source ); + + if (! $status ) { + $errorcode = xml_get_error_code( $this->parser ); + if ( $errorcode != XML_ERROR_NONE ) { + $xml_error = xml_error_string( $errorcode ); + $error_line = xml_get_current_line_number($this->parser); + $error_col = xml_get_current_column_number($this->parser); + $errormsg = "$xml_error at line $error_line, column $error_col"; + + $this->error( $errormsg ); + } + } + + xml_parser_free( $this->parser ); + + $this->normalize(); + } + + function feed_start_element($p, $element, &$attrs) { + $el = $element = strtolower($element); + $attrs = array_change_key_case($attrs, CASE_LOWER); + + // check for a namespace, and split if found + $ns = false; + if ( strpos( $element, ':' ) ) { + list($ns, $el) = split( ':', $element, 2); + } + if ( $ns and $ns != 'rdf' ) { + $this->current_namespace = $ns; + } + + # if feed type isn't set, then this is first element of feed + # identify feed from root element + # + if (!isset($this->feed_type) ) { + if ( $el == 'rdf' ) { + $this->feed_type = RSS; + $this->feed_version = '1.0'; + } + elseif ( $el == 'rss' ) { + $this->feed_type = RSS; + $this->feed_version = $attrs['version']; + } + elseif ( $el == 'feed' ) { + $this->feed_type = ATOM; + $this->feed_version = $attrs['version']; + $this->inchannel = true; + } + return; + } + + if ( $el == 'channel' ) + { + $this->inchannel = true; + } + elseif ($el == 'item' or $el == 'entry' ) + { + $this->initem = true; + if ( isset($attrs['rdf:about']) ) { + $this->current_item['about'] = $attrs['rdf:about']; + } + } + + // if we're in the default namespace of an RSS feed, + // record textinput or image fields + elseif ( + $this->feed_type == RSS and + $this->current_namespace == '' and + $el == 'textinput' ) + { + $this->intextinput = true; + } + + elseif ( + $this->feed_type == RSS and + $this->current_namespace == '' and + $el == 'image' ) + { + $this->inimage = true; + } + + # handle atom content constructs + elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) ) + { + // avoid clashing w/ RSS mod_content + if ($el == 'content' ) { + $el = 'atom_content'; + } + + $this->incontent = $el; + + + } + + // if inside an Atom content construct (e.g. content or summary) field treat tags as text + elseif ($this->feed_type == ATOM and $this->incontent ) + { + // if tags are inlined, then flatten + $attrs_str = join(' ', + array_map(array('MagpieRSS', 'map_attrs'), + array_keys($attrs), + array_values($attrs) ) ); + + $this->append_content( "<$element $attrs_str>" ); + + array_unshift( $this->stack, $el ); + } + + // Atom support many links per containging element. + // Magpie treats link elements of type rel='alternate' + // as being equivalent to RSS's simple link element. + // + elseif ($this->feed_type == ATOM and $el == 'link' ) + { + if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' ) + { + $link_el = 'link'; + } + else { + $link_el = 'link_' . $attrs['rel']; + } + + $this->append($link_el, $attrs['href']); + } + // set stack[0] to current element + else { + array_unshift($this->stack, $el); + } + } + + + + function feed_cdata ($p, $text) { + + if ($this->feed_type == ATOM and $this->incontent) + { + $this->append_content( $text ); + } + else { + $current_el = join('_', array_reverse($this->stack)); + $this->append($current_el, $text); + } + } + + function feed_end_element ($p, $el) { + $el = strtolower($el); + + if ( $el == 'item' or $el == 'entry' ) + { + $this->items[] = $this->current_item; + $this->current_item = array(); + $this->initem = false; + } + elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' ) + { + $this->intextinput = false; + } + elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' ) + { + $this->inimage = false; + } + elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) ) + { + $this->incontent = false; + } + elseif ($el == 'channel' or $el == 'feed' ) + { + $this->inchannel = false; + } + elseif ($this->feed_type == ATOM and $this->incontent ) { + // balance tags properly + // note: i don't think this is actually neccessary + if ( $this->stack[0] == $el ) + { + $this->append_content(""); + } + else { + $this->append_content("<$el />"); + } + + array_shift( $this->stack ); + } + else { + array_shift( $this->stack ); + } + + $this->current_namespace = false; + } + + function concat (&$str1, $str2="") { + if (!isset($str1) ) { + $str1=""; + } + $str1 .= $str2; + } + + function append_content($text) { + if ( $this->initem ) { + $this->concat( $this->current_item[ $this->incontent ], $text ); + } + elseif ( $this->inchannel ) { + $this->concat( $this->channel[ $this->incontent ], $text ); + } + } + + // smart append - field and namespace aware + function append($el, $text) { + if (!$el) { + return; + } + if ( $this->current_namespace ) + { + if ( $this->initem ) { + $this->concat( + $this->current_item[ $this->current_namespace ][ $el ], $text); + } + elseif ($this->inchannel) { + $this->concat( + $this->channel[ $this->current_namespace][ $el ], $text ); + } + elseif ($this->intextinput) { + $this->concat( + $this->textinput[ $this->current_namespace][ $el ], $text ); + } + elseif ($this->inimage) { + $this->concat( + $this->image[ $this->current_namespace ][ $el ], $text ); + } + } + else { + if ( $this->initem ) { + $this->concat( + $this->current_item[ $el ], $text); + } + elseif ($this->intextinput) { + $this->concat( + $this->textinput[ $el ], $text ); + } + elseif ($this->inimage) { + $this->concat( + $this->image[ $el ], $text ); + } + elseif ($this->inchannel) { + $this->concat( + $this->channel[ $el ], $text ); + } + + } + } + + function normalize () { + // if atom populate rss fields + if ( $this->is_atom() ) { + $this->channel['descripton'] = $this->channel['tagline']; + for ( $i = 0; $i < count($this->items); $i++) { + $item = $this->items[$i]; + if ( isset($item['summary']) ) + $item['description'] = $item['summary']; + if ( isset($item['atom_content'])) + $item['content']['encoded'] = $item['atom_content']; + + $this->items[$i] = $item; + } + } + elseif ( $this->is_rss() ) { + $this->channel['tagline'] = $this->channel['description']; + for ( $i = 0; $i < count($this->items); $i++) { + $item = $this->items[$i]; + if ( isset($item['description'])) + $item['summary'] = $item['description']; + if ( isset($item['content']['encoded'] ) ) + $item['atom_content'] = $item['content']['encoded']; + + $this->items[$i] = $item; + } + } + } + + function is_rss () { + if ( $this->feed_type == RSS ) { + return $this->feed_version; + } + else { + return false; + } + } + + function is_atom() { + if ( $this->feed_type == ATOM ) { + return $this->feed_version; + } + else { + return false; + } + } + + function map_attrs($k, $v) { + return "$k=\"$v\""; + } + + function error( $errormsg, $lvl = E_USER_WARNING ) { + // append PHP's error message if track_errors enabled + if ( isset($php_errormsg) ) { + $errormsg .= " ($php_errormsg)"; + } + if ( MAGPIE_DEBUG ) { + trigger_error( $errormsg, $lvl); + } else { + error_log( $errormsg, 0); + } + } + +} + +if ( !function_exists('fetch_rss') ) : +/** + * Build Magpie object based on RSS from URL. + * + * @since 1.5.0 + * @package External + * @subpackage MagpieRSS + * + * @param string $url URL to retrieve feed + * @return bool|MagpieRSS false on failure or MagpieRSS object on success. + */ +function fetch_rss ($url) { + // initialize constants + init(); + + if ( !isset($url) ) { + // error("fetch_rss called without a url"); + return false; + } + + // if cache is disabled + if ( !MAGPIE_CACHE_ON ) { + // fetch file, and parse it + $resp = _fetch_remote_file( $url ); + if ( is_success( $resp->status ) ) { + return _response_to_rss( $resp ); + } + else { + // error("Failed to fetch $url and cache is off"); + return false; + } + } + // else cache is ON + else { + // Flow + // 1. check cache + // 2. if there is a hit, make sure its fresh + // 3. if cached obj fails freshness check, fetch remote + // 4. if remote fails, return stale object, or error + + $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE ); + + if (MAGPIE_DEBUG and $cache->ERROR) { + debug($cache->ERROR, E_USER_WARNING); + } + + + $cache_status = 0; // response of check_cache + $request_headers = array(); // HTTP headers to send with fetch + $rss = 0; // parsed RSS object + $errormsg = 0; // errors, if any + + if (!$cache->ERROR) { + // return cache HIT, MISS, or STALE + $cache_status = $cache->check_cache( $url ); + } + + // if object cached, and cache is fresh, return cached obj + if ( $cache_status == 'HIT' ) { + $rss = $cache->get( $url ); + if ( isset($rss) and $rss ) { + $rss->from_cache = 1; + if ( MAGPIE_DEBUG > 1) { + debug("MagpieRSS: Cache HIT", E_USER_NOTICE); + } + return $rss; + } + } + + // else attempt a conditional get + + // set up headers + if ( $cache_status == 'STALE' ) { + $rss = $cache->get( $url ); + if ( isset($rss->etag) and $rss->last_modified ) { + $request_headers['If-None-Match'] = $rss->etag; + $request_headers['If-Last-Modified'] = $rss->last_modified; + } + } + + $resp = _fetch_remote_file( $url, $request_headers ); + + if (isset($resp) and $resp) { + if ($resp->status == '304' ) { + // we have the most current copy + if ( MAGPIE_DEBUG > 1) { + debug("Got 304 for $url"); + } + // reset cache on 304 (at minutillo insistent prodding) + $cache->set($url, $rss); + return $rss; + } + elseif ( is_success( $resp->status ) ) { + $rss = _response_to_rss( $resp ); + if ( $rss ) { + if (MAGPIE_DEBUG > 1) { + debug("Fetch successful"); + } + // add object to cache + $cache->set( $url, $rss ); + return $rss; + } + } + else { + $errormsg = "Failed to fetch $url. "; + if ( $resp->error ) { + # compensate for Snoopy's annoying habbit to tacking + # on '\n' + $http_error = substr($resp->error, 0, -2); + $errormsg .= "(HTTP Error: $http_error)"; + } + else { + $errormsg .= "(HTTP Response: " . $resp->response_code .')'; + } + } + } + else { + $errormsg = "Unable to retrieve RSS file for unknown reasons."; + } + + // else fetch failed + + // attempt to return cached object + if ($rss) { + if ( MAGPIE_DEBUG ) { + debug("Returning STALE object for $url"); + } + return $rss; + } + + // else we totally failed + // error( $errormsg ); + + return false; + + } // end if ( !MAGPIE_CACHE_ON ) { +} // end fetch_rss() +endif; + +/** + * Retrieve URL headers and content using WP HTTP Request API. + * + * @since 1.5.0 + * @package External + * @subpackage MagpieRSS + * + * @param string $url URL to retrieve + * @param array $headers Optional. Headers to send to the URL. + * @return Snoopy style response + */ +function _fetch_remote_file($url, $headers = "" ) { + $resp = wp_remote_request($url, array('headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT)); + if ( is_wp_error($resp) ) { + $error = array_shift($resp->errors); + + $resp = new stdClass; + $resp->status = 500; + $resp->response_code = 500; + $resp->error = $error[0] . "\n"; //\n = Snoopy compatibility + return $resp; + } + + // Snoopy returns headers unprocessed. + // Also note, WP_HTTP lowercases all keys, Snoopy did not. + $return_headers = array(); + foreach ( $resp['headers'] as $key => $value ) { + if ( !is_array($value) ) { + $return_headers[] = "$key: $value"; + } else { + foreach ( $value as $v ) + $return_headers[] = "$key: $v"; + } + } + + $response = new stdClass; + $response->status = $resp['response']['code']; + $response->response_code = $resp['response']['code']; + $response->headers = $return_headers; + $response->results = $resp['body']; + + return $response; +} + +/** + * Retrieve + * + * @since 1.5.0 + * @package External + * @subpackage MagpieRSS + * + * @param unknown_type $resp + * @return unknown + */ +function _response_to_rss ($resp) { + $rss = new MagpieRSS( $resp->results ); + + // if RSS parsed successfully + if ( $rss && (!isset($rss->ERROR) || !$rss->ERROR) ) { + + // find Etag, and Last-Modified + foreach( (array) $resp->headers as $h) { + // 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1" + if (strpos($h, ": ")) { + list($field, $val) = explode(": ", $h, 2); + } + else { + $field = $h; + $val = ""; + } + + if ( $field == 'etag' ) { + $rss->etag = $val; + } + + if ( $field == 'last-modified' ) { + $rss->last_modified = $val; + } + } + + return $rss; + } // else construct error message + else { + $errormsg = "Failed to parse RSS file."; + + if ($rss) { + $errormsg .= " (" . $rss->ERROR . ")"; + } + // error($errormsg); + + return false; + } // end if ($rss and !$rss->error) +} + +/** + * Set up constants with default values, unless user overrides. + * + * @since 1.5.0 + * @package External + * @subpackage MagpieRSS + */ +function init () { + if ( defined('MAGPIE_INITALIZED') ) { + return; + } + else { + define('MAGPIE_INITALIZED', 1); + } + + if ( !defined('MAGPIE_CACHE_ON') ) { + define('MAGPIE_CACHE_ON', 1); + } + + if ( !defined('MAGPIE_CACHE_DIR') ) { + define('MAGPIE_CACHE_DIR', './cache'); + } + + if ( !defined('MAGPIE_CACHE_AGE') ) { + define('MAGPIE_CACHE_AGE', 60*60); // one hour + } + + if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) { + define('MAGPIE_CACHE_FRESH_ONLY', 0); + } + + if ( !defined('MAGPIE_DEBUG') ) { + define('MAGPIE_DEBUG', 0); + } + + if ( !defined('MAGPIE_USER_AGENT') ) { + $ua = 'WordPress/' . $GLOBALS['wp_version']; + + if ( MAGPIE_CACHE_ON ) { + $ua = $ua . ')'; + } + else { + $ua = $ua . '; No cache)'; + } + + define('MAGPIE_USER_AGENT', $ua); + } + + if ( !defined('MAGPIE_FETCH_TIME_OUT') ) { + define('MAGPIE_FETCH_TIME_OUT', 2); // 2 second timeout + } + + // use gzip encoding to fetch rss files if supported? + if ( !defined('MAGPIE_USE_GZIP') ) { + define('MAGPIE_USE_GZIP', true); + } +} + +function is_info ($sc) { + return $sc >= 100 && $sc < 200; +} + +function is_success ($sc) { + return $sc >= 200 && $sc < 300; +} + +function is_redirect ($sc) { + return $sc >= 300 && $sc < 400; +} + +function is_error ($sc) { + return $sc >= 400 && $sc < 600; +} + +function is_client_error ($sc) { + return $sc >= 400 && $sc < 500; +} + +function is_server_error ($sc) { + return $sc >= 500 && $sc < 600; +} + +class RSSCache { + var $BASE_CACHE; // where the cache files are stored + var $MAX_AGE = 43200; // when are files stale, default twelve hours + var $ERROR = ''; // accumulate error messages + + function RSSCache ($base='', $age='') { + $this->BASE_CACHE = WP_CONTENT_DIR . '/cache'; + if ( $base ) { + $this->BASE_CACHE = $base; + } + if ( $age ) { + $this->MAX_AGE = $age; + } + + } + +/*=======================================================================*\ + Function: set + Purpose: add an item to the cache, keyed on url + Input: url from wich the rss file was fetched + Output: true on sucess +\*=======================================================================*/ + function set ($url, $rss) { + $cache_option = 'rss_' . $this->file_name( $url ); + + set_transient($cache_option, $rss, $this->MAX_AGE); + + return $cache_option; + } + +/*=======================================================================*\ + Function: get + Purpose: fetch an item from the cache + Input: url from wich the rss file was fetched + Output: cached object on HIT, false on MISS +\*=======================================================================*/ + function get ($url) { + $this->ERROR = ""; + $cache_option = 'rss_' . $this->file_name( $url ); + + if ( ! $rss = get_transient( $cache_option ) ) { + $this->debug( + "Cache doesn't contain: $url (cache option: $cache_option)" + ); + return 0; + } + + return $rss; + } + +/*=======================================================================*\ + Function: check_cache + Purpose: check a url for membership in the cache + and whether the object is older then MAX_AGE (ie. STALE) + Input: url from wich the rss file was fetched + Output: cached object on HIT, false on MISS +\*=======================================================================*/ + function check_cache ( $url ) { + $this->ERROR = ""; + $cache_option = 'rss_' . $this->file_name( $url ); + + if ( get_transient($cache_option) ) { + // object exists and is current + return 'HIT'; + } else { + // object does not exist + return 'MISS'; + } + } + +/*=======================================================================*\ + Function: serialize +\*=======================================================================*/ + function serialize ( $rss ) { + return serialize( $rss ); + } + +/*=======================================================================*\ + Function: unserialize +\*=======================================================================*/ + function unserialize ( $data ) { + return unserialize( $data ); + } + +/*=======================================================================*\ + Function: file_name + Purpose: map url to location in cache + Input: url from wich the rss file was fetched + Output: a file name +\*=======================================================================*/ + function file_name ($url) { + return md5( $url ); + } + +/*=======================================================================*\ + Function: error + Purpose: register error +\*=======================================================================*/ + function error ($errormsg, $lvl=E_USER_WARNING) { + // append PHP's error message if track_errors enabled + if ( isset($php_errormsg) ) { + $errormsg .= " ($php_errormsg)"; + } + $this->ERROR = $errormsg; + if ( MAGPIE_DEBUG ) { + trigger_error( $errormsg, $lvl); + } + else { + error_log( $errormsg, 0); + } + } + function debug ($debugmsg, $lvl=E_USER_NOTICE) { + if ( MAGPIE_DEBUG ) { + $this->error("MagpieRSS [debug] $debugmsg", $lvl); + } + } +} + +if ( !function_exists('parse_w3cdtf') ) : +function parse_w3cdtf ( $date_str ) { + + # regex to match wc3dtf + $pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/"; + + if ( preg_match( $pat, $date_str, $match ) ) { + list( $year, $month, $day, $hours, $minutes, $seconds) = + array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[7]); + + # calc epoch for current date assuming GMT + $epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year); + + $offset = 0; + if ( $match[11] == 'Z' ) { + # zulu time, aka GMT + } + else { + list( $tz_mod, $tz_hour, $tz_min ) = + array( $match[8], $match[9], $match[10]); + + # zero out the variables + if ( ! $tz_hour ) { $tz_hour = 0; } + if ( ! $tz_min ) { $tz_min = 0; } + + $offset_secs = (($tz_hour*60)+$tz_min)*60; + + # is timezone ahead of GMT? then subtract offset + # + if ( $tz_mod == '+' ) { + $offset_secs = $offset_secs * -1; + } + + $offset = $offset_secs; + } + $epoch = $epoch + $offset; + return $epoch; + } + else { + return -1; + } +} +endif; + +if ( !function_exists('wp_rss') ) : +/** + * Display all RSS items in a HTML ordered list. + * + * @since 1.5.0 + * @package External + * @subpackage MagpieRSS + * + * @param string $url URL of feed to display. Will not auto sense feed URL. + * @param int $num_items Optional. Number of items to display, default is all. + */ +function wp_rss( $url, $num_items = -1 ) { + if ( $rss = fetch_rss( $url ) ) { + echo '
      '; + + if ( $num_items !== -1 ) { + $rss->items = array_slice( $rss->items, 0, $num_items ); + } + + foreach ( (array) $rss->items as $item ) { + printf( + '
    • %3$s
    • ', + esc_url( $item['link'] ), + esc_attr( strip_tags( $item['description'] ) ), + esc_html( $item['title'] ) + ); + } + + echo '
    '; + } else { + _e( 'An error has occurred, which probably means the feed is down. Try again later.' ); + } +} +endif; + +if ( !function_exists('get_rss') ) : +/** + * Display RSS items in HTML list items. + * + * You have to specify which HTML list you want, either ordered or unordered + * before using the function. You also have to specify how many items you wish + * to display. You can't display all of them like you can with wp_rss() + * function. + * + * @since 1.5.0 + * @package External + * @subpackage MagpieRSS + * + * @param string $url URL of feed to display. Will not auto sense feed URL. + * @param int $num_items Optional. Number of items to display, default is all. + * @return bool False on failure. + */ +function get_rss ($url, $num_items = 5) { // Like get posts, but for RSS + $rss = fetch_rss($url); + if ( $rss ) { + $rss->items = array_slice($rss->items, 0, $num_items); + foreach ( (array) $rss->items as $item ) { + echo "
  • \n"; + echo ""; + echo esc_html($item['title']); + echo "
    \n"; + echo "
  • \n"; + } + } else { + return false; + } +} +endif; + +?> diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php new file mode 100644 index 00000000..87c4393c --- /dev/null +++ b/src/wp-includes/script-loader.php @@ -0,0 +1,793 @@ +add_data( 'script-handle', 'group', 1 ); queues the script for the footer + * + * @since 2.6.0 + * + * @param object $scripts WP_Scripts object. + */ +function wp_default_scripts( &$scripts ) { + + if ( !$guessurl = site_url() ) + $guessurl = wp_guess_url(); + + $scripts->base_url = $guessurl; + $scripts->content_url = defined('WP_CONTENT_URL')? WP_CONTENT_URL : ''; + $scripts->default_version = get_bloginfo( 'version' ); + $scripts->default_dirs = array('/wp-admin/js/', '/wp-includes/js/'); + + $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : ''; + + // Always ensure that we have the convertEntities function + $scripts->add( 'l10n', "/wp-includes/js/l10n$suffix.js", false, '20101110' ); + $scripts->enqueue( 'l10n' ); + + $scripts->add( 'utils', "/wp-admin/js/utils$suffix.js", false, '20101110' ); + + $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array('jquery', 'hoverIntent', 'utils'), '20101211' ); + $scripts->add_data( 'common', 'group', 1 ); + $scripts->localize( 'common', 'commonL10n', array( + 'warnDelete' => __("You are about to permanently delete the selected items.\n 'Cancel' to stop, 'OK' to delete."), + 'l10n_print_after' => 'try{convertEntities(commonL10n);}catch(e){};' + ) ); + + $scripts->add( 'sack', "/wp-includes/js/tw-sack$suffix.js", false, '1.6.1' ); + $scripts->add_data( 'sack', 'group', 1 ); + + $scripts->add( 'quicktags', "/wp-includes/js/quicktags$suffix.js", false, '20090307' ); + $scripts->add_data( 'quicktags', 'group', 1 ); + $scripts->localize( 'quicktags', 'quicktagsL10n', array( + 'quickLinks' => __('(Quick Links)'), + 'wordLookup' => __('Enter a word to look up:'), + 'dictionaryLookup' => esc_attr(__('Dictionary lookup')), + 'lookup' => esc_attr(__('lookup')), + 'closeAllOpenTags' => esc_attr(__('Close all open tags')), + 'closeTags' => esc_attr(__('close tags')), + 'enterURL' => __('Enter the URL'), + 'enterImageURL' => __('Enter the URL of the image'), + 'enterImageDescription' => __('Enter a description of the image'), + 'l10n_print_after' => 'try{convertEntities(quicktagsL10n);}catch(e){};' + ) ); + + $scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array('prototype'), '3517m' ); + + $scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array('utils','jquery'), '20091124' ); + + $scripts->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6.1'); + + $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array('jquery'), '20091119' ); + $scripts->add_data( 'wp-ajax-response', 'group', 1 ); + $scripts->localize( 'wp-ajax-response', 'wpAjax', array( + 'noPerm' => __('You do not have permission to do that.'), + 'broken' => __('An unidentified error has occurred.'), + 'l10n_print_after' => 'try{convertEntities(wpAjax);}catch(e){};' + ) ); + + $scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array('schedule', 'wp-ajax-response'), '20101004' ); + $scripts->add_data( 'autosave', 'group', 1 ); + + $scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array('wp-ajax-response'), '20101222' ); + $scripts->add_data( 'wp-lists', 'group', 1 ); + + $scripts->add( 'scriptaculous-root', '/wp-includes/js/scriptaculous/wp-scriptaculous.js', array('prototype'), '1.8.3'); + $scripts->add( 'scriptaculous-builder', '/wp-includes/js/scriptaculous/builder.js', array('scriptaculous-root'), '1.8.3'); + $scripts->add( 'scriptaculous-dragdrop', '/wp-includes/js/scriptaculous/dragdrop.js', array('scriptaculous-builder', 'scriptaculous-effects'), '1.8.3'); + $scripts->add( 'scriptaculous-effects', '/wp-includes/js/scriptaculous/effects.js', array('scriptaculous-root'), '1.8.3'); + $scripts->add( 'scriptaculous-slider', '/wp-includes/js/scriptaculous/slider.js', array('scriptaculous-effects'), '1.8.3'); + $scripts->add( 'scriptaculous-sound', '/wp-includes/js/scriptaculous/sound.js', array( 'scriptaculous-root' ), '1.8.3' ); + $scripts->add( 'scriptaculous-controls', '/wp-includes/js/scriptaculous/controls.js', array('scriptaculous-root'), '1.8.3'); + $scripts->add( 'scriptaculous', '', array('scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls'), '1.8.3'); + + // not used in core, replaced by Jcrop.js + $scripts->add( 'cropper', '/wp-includes/js/crop/cropper.js', array('scriptaculous-dragdrop'), '20070118'); + + $scripts->add( 'jquery', '/wp-includes/js/jquery/jquery.js', false, '1.4.4'); + + $scripts->add( 'jquery-ui-core', '/wp-includes/js/jquery/ui.core.js', array('jquery'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-core', 'group', 1 ); + + $scripts->add( 'jquery-ui-position', '/wp-includes/js/jquery/ui.position.js', array('jquery'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-position', 'group', 1 ); + + $scripts->add( 'jquery-ui-widget', '/wp-includes/js/jquery/ui.widget.js', array('jquery'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-widget', 'group', 1 ); + + $scripts->add( 'jquery-ui-mouse', '/wp-includes/js/jquery/ui.mouse.js', array('jquery', 'jquery-ui-widget'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-mouse', 'group', 1 ); + + $scripts->add( 'jquery-ui-button', '/wp-includes/js/jquery/ui.button.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-button', 'group', 1 ); + + $scripts->add( 'jquery-ui-tabs', '/wp-includes/js/jquery/ui.tabs.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-tabs', 'group', 1 ); + + $scripts->add( 'jquery-ui-sortable', '/wp-includes/js/jquery/ui.sortable.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-sortable', 'group', 1 ); + + $scripts->add( 'jquery-ui-draggable', '/wp-includes/js/jquery/ui.draggable.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-draggable', 'group', 1 ); + + $scripts->add( 'jquery-ui-droppable', '/wp-includes/js/jquery/ui.droppable.js', array('jquery-ui-core', 'jquery-ui-mouse', 'jquery-ui-draggable'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-droppable', 'group', 1 ); + + $scripts->add( 'jquery-ui-selectable', '/wp-includes/js/jquery/ui.selectable.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-selectable', 'group', 1 ); + + $scripts->add( 'jquery-ui-resizable', '/wp-includes/js/jquery/ui.resizable.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-resizable', 'group', 1 ); + + $scripts->add( 'jquery-ui-dialog', '/wp-includes/js/jquery/ui.dialog.js', array('jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button', 'jquery-ui-position'), '1.8.9' ); + $scripts->add_data( 'jquery-ui-dialog', 'group', 1 ); + + // deprecated, not used in core, most functionality is included in jQuery 1.3 + $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array('jquery'), '2.02m'); + $scripts->add_data( 'jquery-form', 'group', 1 ); + + $scripts->add( 'jquery-color', "/wp-includes/js/jquery/jquery.color$suffix.js", array('jquery'), '2.0-4561m'); + $scripts->add_data( 'jquery-color', 'group', 1 ); + + $scripts->add( 'suggest', "/wp-includes/js/jquery/suggest$suffix.js", array('jquery'), '1.1-20110113'); + $scripts->add_data( 'suggest', 'group', 1 ); + + $scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20m'); + $scripts->add_data( 'schedule', 'group', 1 ); + + $scripts->add( 'jquery-query', "/wp-includes/js/jquery/jquery.query.js", array('jquery'), '2.1.7' ); + $scripts->add_data( 'jquery-query', 'group', 1 ); + + $scripts->add( 'jquery-serialize-object', "/wp-includes/js/jquery/jquery.serialize-object.js", array('jquery'), '0.2' ); + $scripts->add_data( 'jquery-serialize-object', 'group', 1 ); + + $scripts->add( 'jquery-hotkeys', "/wp-includes/js/jquery/jquery.hotkeys$suffix.js", array('jquery'), '0.0.2m' ); + $scripts->add_data( 'jquery-hotkeys', 'group', 1 ); + + $scripts->add( 'jquery-table-hotkeys', "/wp-includes/js/jquery/jquery.table-hotkeys$suffix.js", array('jquery', 'jquery-hotkeys'), '20090102' ); + $scripts->add_data( 'jquery-table-hotkeys', 'group', 1 ); + + $scripts->add( 'thickbox', "/wp-includes/js/thickbox/thickbox.js", array('jquery'), '3.1-20100407'); + $scripts->add_data( 'thickbox', 'group', 1 ); + $scripts->localize( 'thickbox', 'thickboxL10n', array( + 'next' => __('Next >'), + 'prev' => __('< Prev'), + 'image' => __('Image'), + 'of' => __('of'), + 'close' => __('Close'), + 'noiframes' => __('This feature requires inline frames. You have iframes disabled or your browser does not support them.'), + 'l10n_print_after' => 'try{convertEntities(thickboxL10n);}catch(e){};' + ) ); + + + $scripts->add( 'jcrop', "/wp-includes/js/jcrop/jquery.Jcrop$suffix.js", array('jquery'), '0.9.8-20110113'); + + $scripts->add( 'swfobject', "/wp-includes/js/swfobject.js", false, '2.2'); + + $scripts->add( 'swfupload', '/wp-includes/js/swfupload/swfupload.js', false, '2201-20110113'); + $scripts->add( 'swfupload-swfobject', '/wp-includes/js/swfupload/plugins/swfupload.swfobject.js', array('swfupload', 'swfobject'), '2201'); + $scripts->add( 'swfupload-queue', '/wp-includes/js/swfupload/plugins/swfupload.queue.js', array('swfupload'), '2201'); + $scripts->add( 'swfupload-speed', '/wp-includes/js/swfupload/plugins/swfupload.speed.js', array('swfupload'), '2201'); + + if ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) { + // queue all SWFUpload scripts that are used by default + $scripts->add( 'swfupload-all', false, array('swfupload', 'swfupload-swfobject', 'swfupload-queue'), '2201'); + } else { + $scripts->add( 'swfupload-all', '/wp-includes/js/swfupload/swfupload-all.js', array(), '2201'); + } + + $scripts->add( 'swfupload-handlers', "/wp-includes/js/swfupload/handlers$suffix.js", array('swfupload-all', 'jquery'), '2201-20100523'); + $max_upload_size = ( (int) ( $max_up = @ini_get('upload_max_filesize') ) < (int) ( $max_post = @ini_get('post_max_size') ) ) ? $max_up : $max_post; + if ( empty($max_upload_size) ) + $max_upload_size = __('not configured'); + // these error messages came from the sample swfupload js, they might need changing. + $scripts->localize( 'swfupload-handlers', 'swfuploadL10n', array( + 'queue_limit_exceeded' => __('You have attempted to queue too many files.'), + 'file_exceeds_size_limit' => __('This file exceeds the maximum upload size for this site.'), + 'zero_byte_file' => __('This file is empty. Please try another.'), + 'invalid_filetype' => __('This file type is not allowed. Please try another.'), + 'default_error' => __('An error occurred in the upload. Please try again later.'), + 'missing_upload_url' => __('There was a configuration error. Please contact the server administrator.'), + 'upload_limit_exceeded' => __('You may only upload 1 file.'), + 'http_error' => __('HTTP error.'), + 'upload_failed' => __('Upload failed.'), + 'io_error' => __('IO error.'), + 'security_error' => __('Security error.'), + 'file_cancelled' => __('File canceled.'), + 'upload_stopped' => __('Upload stopped.'), + 'dismiss' => __('Dismiss'), + 'crunching' => __('Crunching…'), + 'deleted' => __('moved to the trash.'), + 'error_uploading' => __('“%s” has failed to upload due to an error'), + 'l10n_print_after' => 'try{convertEntities(swfuploadL10n);}catch(e){};', + ) ); + + $scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", false, '20090102'); + + $scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", false, '20110113'); + + $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.1-20110113' ); + $scripts->add_data( 'imgareaselect', 'group', 1 ); + + $scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array('jquery'), '20101027' ); + $scripts->add_data( 'password-strength-meter', 'group', 1 ); + $scripts->localize( 'password-strength-meter', 'pwsL10n', array( + 'empty' => __('Strength indicator'), + 'short' => __('Very weak'), + 'bad' => __('Weak'), + /* translators: password strength */ + 'good' => _x('Medium', 'password strength'), + 'strong' => __('Strong'), + 'mismatch' => __('Mismatch'), + 'l10n_print_after' => 'try{convertEntities(pwsL10n);}catch(e){};' + ) ); + + $scripts->add( 'user-profile', "/wp-admin/js/user-profile$suffix.js", array( 'jquery', 'password-strength-meter' ), '20110113' ); + $scripts->add_data( 'user-profile', 'group', 1 ); + + $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", false, '20110131' ); + $scripts->add_data( 'admin-bar', 'group', 1 ); + + $scripts->add( 'wplink', "/wp-includes/js/tinymce/plugins/wplink/js/wplink$suffix.js", array('jquery'), '20110111' ); + $scripts->localize( 'wplink', 'wpLinkL10n', array( + 'update' => __('Update'), + 'save' => __('Add Link'), + 'noTitle' => __('(no title)'), + 'noMatchesFound' => __('No matches found.'), + 'l10n_print_after' => 'try{convertEntities(wpLinkL10n);}catch(e){};', + ) ); + + $scripts->add( 'wpdialogs-popup', "/wp-includes/js/tinymce/plugins/wpdialogs/js/popup$suffix.js", array( 'jquery-ui-dialog' ), '20101119' ); + + if ( is_admin() ) { + $scripts->add( 'ajaxcat', "/wp-admin/js/cat$suffix.js", array( 'wp-lists' ), '20090102' ); + $scripts->add_data( 'ajaxcat', 'group', 1 ); + $scripts->localize( 'ajaxcat', 'catL10n', array( + 'add' => esc_attr(__('Add')), + 'how' => __('Separate multiple categories with commas.'), + 'l10n_print_after' => 'try{convertEntities(catL10n);}catch(e){};' + ) ); + + $scripts->add( 'admin-categories', "/wp-admin/js/categories$suffix.js", array('wp-lists'), '20091201' ); + $scripts->add_data( 'admin-categories', 'group', 1 ); + + $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array('jquery', 'wp-ajax-response'), '20101216' ); + $scripts->add_data( 'admin-tags', 'group', 1 ); + $scripts->localize( 'admin-tags', 'tagsl10n', array( + 'noPerm' => __('You do not have permission to do that.'), + 'broken' => __('An unidentified error has occurred.'), + 'l10n_print_after' => 'try{convertEntities(tagsl10n);}catch(e){};' + )); + + $scripts->add( 'admin-custom-fields', "/wp-admin/js/custom-fields$suffix.js", array('wp-lists'), '20090106' ); + $scripts->add_data( 'admin-custom-fields', 'group', 1 ); + + $scripts->add( 'admin-comments', "/wp-admin/js/edit-comments$suffix.js", array('wp-lists', 'jquery-ui-resizable', 'quicktags', 'jquery-query'), '20110122' ); + $scripts->add_data( 'admin-comments', 'group', 1 ); + $scripts->localize( 'admin-comments', 'adminCommentsL10n', array( + 'hotkeys_highlight_first' => isset($_GET['hotkeys_highlight_first']), + 'hotkeys_highlight_last' => isset($_GET['hotkeys_highlight_last']) + ) ); + + $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array('jquery'), '20100403' ); + $scripts->add_data( 'xfn', 'group', 1 ); + + $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array('jquery-ui-sortable'), '20091012' ); + $scripts->add_data( 'postbox', 'group', 1 ); + + $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array('suggest', 'wp-lists', 'postbox'), '20110203' ); + $scripts->add_data( 'post', 'group', 1 ); + $scripts->localize( 'post', 'postL10n', array( + 'tagsUsed' => __('Tags used on this post:'), + 'add' => esc_attr(__('Add')), + 'addTag' => esc_attr(__('Add new Tag')), + 'separate' => __('Separate tags with commas'), + 'ok' => __('OK'), + 'cancel' => __('Cancel'), + 'edit' => __('Edit'), + 'publishOn' => __('Publish on:'), + 'publishOnFuture' => __('Schedule for:'), + 'publishOnPast' => __('Published on:'), + 'showcomm' => __('Show more comments'), + 'endcomm' => __('No more comments found.'), + 'publish' => __('Publish'), + 'schedule' => __('Schedule'), + 'update' => __('Update'), + 'savePending' => __('Save as Pending'), + 'saveDraft' => __('Save Draft'), + 'private' => __('Private'), + 'public' => __('Public'), + 'publicSticky' => __('Public, Sticky'), + 'password' => __('Password Protected'), + 'privatelyPublished' => __('Privately Published'), + 'published' => __('Published'), + 'l10n_print_after' => 'try{convertEntities(postL10n);}catch(e){};' + ) ); + + $scripts->add( 'link', "/wp-admin/js/link$suffix.js", array('wp-lists', 'postbox'), '20090526' ); + $scripts->add_data( 'link', 'group', 1 ); + + $scripts->add( 'comment', "/wp-admin/js/comment$suffix.js", array('jquery'), '20091202' ); + $scripts->add_data( 'comment', 'group', 1 ); + $scripts->localize( 'comment', 'commentL10n', array( + 'cancel' => __('Cancel'), + 'edit' => __('Edit'), + 'submittedOn' => __('Submitted on:'), + 'l10n_print_after' => 'try{convertEntities(commentL10n);}catch(e){};' + ) ); + + $scripts->add( 'admin-gallery', "/wp-admin/js/gallery$suffix.js", array( 'jquery-ui-sortable' ), '20090516' ); + + $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox' ), '20110113' ); + $scripts->add_data( 'media-upload', 'group', 1 ); + + $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), '20101007' ); + $scripts->add_data( 'admin-widgets', 'group', 1 ); + + $scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array( 'jquery' ), '20090422' ); + $scripts->add_data( 'word-count', 'group', 1 ); + $scripts->localize( 'word-count', 'wordCountL10n', array( + 'count' => __('Word count: %d'), + 'l10n_print_after' => 'try{convertEntities(wordCountL10n);}catch(e){};' + )); + + $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'thickbox' ), '20110118' ); + $scripts->add_data( 'theme', 'group', 1 ); + + $scripts->add( 'theme-preview', "/wp-admin/js/theme-preview$suffix.js", array( 'thickbox', 'jquery' ), '20100407' ); + $scripts->add_data( 'theme-preview', 'group', 1 ); + + $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'suggest' ), '20110113' ); + $scripts->add_data( 'inline-edit-post', 'group', 1 ); + $scripts->localize( 'inline-edit-post', 'inlineEditL10n', array( + 'error' => __('Error while saving the changes.'), + 'ntdeltitle' => __('Remove From Bulk Edit'), + 'notitle' => __('(no title)'), + 'l10n_print_after' => 'try{convertEntities(inlineEditL10n);}catch(e){};' + ) ); + + $scripts->add( 'inline-edit-tax', "/wp-admin/js/inline-edit-tax$suffix.js", array( 'jquery' ), '20100615' ); + $scripts->add_data( 'inline-edit-tax', 'group', 1 ); + $scripts->localize( 'inline-edit-tax', 'inlineEditL10n', array( + 'error' => __('Error while saving the changes.'), + 'l10n_print_after' => 'try{convertEntities(inlineEditL10n);}catch(e){};' + ) ); + + $scripts->add( 'plugin-install', "/wp-admin/js/plugin-install$suffix.js", array( 'jquery', 'thickbox' ), '20110113' ); + $scripts->add_data( 'plugin-install', 'group', 1 ); + $scripts->localize( 'plugin-install', 'plugininstallL10n', array( + 'plugin_information' => __('Plugin Information:'), + 'ays' => __('Are you sure you want to install this plugin?'), + 'l10n_print_after' => 'try{convertEntities(plugininstallL10n);}catch(e){};' + ) ); + + $scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array('jquery'), '1.2' ); + + $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), '20110113' ); + $scripts->add_data( 'dashboard', 'group', 1 ); + + $scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array('jquery'), '20090102' ); + $scripts->add_data( 'hoverIntent', 'group', 1 ); + + $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js", null, '20091223' ); + + $scripts->add( 'media', "/wp-admin/js/media$suffix.js", array( 'jquery-ui-draggable' ), '20101022' ); + $scripts->add_data( 'media', 'group', 1 ); + + $scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array('jquery', 'json2', 'imgareaselect'), '20091111' ); + $scripts->add_data( 'image-edit', 'group', 1 ); + + $scripts->add( 'set-post-thumbnail', "/wp-admin/js/set-post-thumbnail$suffix.js", array( 'jquery' ), '20100518' ); + $scripts->add_data( 'set-post-thumbnail', 'group', 1 ); + $scripts->localize( 'set-post-thumbnail', 'setPostThumbnailL10n', array( + 'setThumbnail' => __( 'Use as featured image' ), + 'saving' => __( 'Saving...' ), + 'error' => __( 'Could not set that as the thumbnail image. Try a different attachment.' ), + 'done' => __( 'Done' ), + 'l10n_print_after' => 'try{convertEntities(setPostThumbnailL10n);}catch(e){};' + ) ); + + // Navigation Menus + $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", array('jquery-ui-sortable'), '20100814' ); + $scripts->localize( 'nav-menu', 'navMenuL10n', array( + 'noResultsFound' => _x('No results found.', 'search results'), + 'warnDeleteMenu' => __( "You are about to permanently delete this menu. \n 'Cancel' to stop, 'OK' to delete." ), + 'saveAlert' => __('The changes you made will be lost if you navigate away from this page.'), + 'l10n_print_after' => 'try{convertEntities(navMenuL10n);}catch(e){};' + ) ); + + $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array('farbtastic'), '20101025' ); + $scripts->add_data( 'custom-background', 'group', 1 ); + } +} + +/** + * Assign default styles to $styles object. + * + * Nothing is returned, because the $styles parameter is passed by reference. + * Meaning that whatever object is passed will be updated without having to + * reassign the variable that was passed back to the same value. This saves + * memory. + * + * Adding default styles is not the only task, it also assigns the base_url + * property, the default version, and text direction for the object. + * + * @since 2.6.0 + * + * @param object $styles + */ +function wp_default_styles( &$styles ) { + // This checks to see if site_url() returns something and if it does not + // then it assigns $guess_url to wp_guess_url(). Strange format, but it works. + if ( ! $guessurl = site_url() ) + $guessurl = wp_guess_url(); + + $styles->base_url = $guessurl; + $styles->content_url = defined('WP_CONTENT_URL')? WP_CONTENT_URL : ''; + $styles->default_version = get_bloginfo( 'version' ); + $styles->text_direction = function_exists( 'is_rtl' ) && is_rtl() ? 'rtl' : 'ltr'; + $styles->default_dirs = array('/wp-admin/'); + + $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : ''; + + $rtl_styles = array( 'wp-admin', 'global', 'colors', 'colors-fresh', 'colors-classic', 'dashboard', 'ie', 'install', 'login', 'media', 'theme-editor', 'upload', 'widgets', 'press-this', 'plugin-install', 'nav-menu', 'farbtastic', 'admin-bar', 'wplink', 'theme-install' ); + // Any rtl stylesheets that don't have a .dev version for ltr + $no_suffix = array( 'farbtastic' ); + + $styles->add( 'wp-admin', "/wp-admin/css/wp-admin$suffix.css", array(), '20110214' ); + + $styles->add( 'ie', "/wp-admin/css/ie$suffix.css", array(), '20101102' ); + $styles->add_data( 'ie', 'conditional', 'lte IE 7' ); + + // all colors stylesheets need to have the same query strings (cache manifest compat) + $colors_version = '20110121'; + + // Register "meta" stylesheet for admin colors. All colors-* style sheets should have the same version string. + $styles->add( 'colors', true, array(), $colors_version ); + + // do not refer to these directly, the right one is queued by the above "meta" colors handle + $styles->add( 'colors-fresh', "/wp-admin/css/colors-fresh$suffix.css", array(), $colors_version ); + $styles->add( 'colors-classic', "/wp-admin/css/colors-classic$suffix.css", array(), $colors_version ); + + $styles->add( 'ms', "/wp-admin/css/ms$suffix.css", array(), '20101213' ); + $styles->add( 'global', "/wp-admin/css/global$suffix.css", array(), '20110121' ); + $styles->add( 'media', "/wp-admin/css/media$suffix.css", array(), '20110121' ); + $styles->add( 'widgets', "/wp-admin/css/widgets$suffix.css", array(), '20110104' ); + $styles->add( 'dashboard', "/wp-admin/css/dashboard$suffix.css", array(), '20110121' ); + $styles->add( 'install', "/wp-admin/css/install$suffix.css", array(), '20110121' ); // Readme as well + $styles->add( 'theme-editor', "/wp-admin/css/theme-editor$suffix.css", array(), '20101203' ); + $styles->add( 'press-this', "/wp-admin/css/press-this$suffix.css", array(), '20110121' ); + $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css', array(), '20090514' ); + $styles->add( 'login', "/wp-admin/css/login$suffix.css", array(), '20110121' ); + $styles->add( 'plugin-install', "/wp-admin/css/plugin-install$suffix.css", array(), '20101230' ); + $styles->add( 'theme-install', "/wp-admin/css/theme-install$suffix.css", array(), '20101226' ); + $styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.3u' ); + $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' ); + $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' ); + $styles->add( 'nav-menu', "/wp-admin/css/nav-menu$suffix.css", array(), '20100907' ); + $styles->add( 'admin-bar', "/wp-includes/css/admin-bar$suffix.css", array(), '20110325' ); + $styles->add( 'wp-jquery-ui-dialog', "/wp-includes/css/jquery-ui-dialog$suffix.css", array(), '20101224' ); + $styles->add( 'wplink', "/wp-includes/js/tinymce/plugins/wplink/css/wplink$suffix.css", array(), '20101224' ); + + foreach ( $rtl_styles as $rtl_style ) { + $styles->add_data( $rtl_style, 'rtl', true ); + if ( $suffix && ! in_array( $rtl_style, $no_suffix ) ) + $styles->add_data( $rtl_style, 'suffix', $suffix ); + } +} + +/** + * Reorder JavaScript scripts array to place prototype before jQuery. + * + * @since 2.3.1 + * + * @param array $js_array JavaScript scripst array + * @return array Reordered array, if needed. + */ +function wp_prototype_before_jquery( $js_array ) { + if ( false === $jquery = array_search( 'jquery', $js_array, true ) ) + return $js_array; + + if ( false === $prototype = array_search( 'prototype', $js_array, true ) ) + return $js_array; + + if ( $prototype < $jquery ) + return $js_array; + + unset($js_array[$prototype]); + + array_splice( $js_array, $jquery, 0, 'prototype' ); + + return $js_array; +} + +/** + * Load localized data on print rather than initialization. + * + * These localizations require information that may not be loaded even by init. + * + * @since 2.5.0 + */ +function wp_just_in_time_script_localization() { + + wp_localize_script( 'autosave', 'autosaveL10n', array( + 'autosaveInterval' => AUTOSAVE_INTERVAL, + 'previewPageText' => __('Preview this Page'), + 'previewPostText' => __('Preview this Post'), + 'requestFile' => admin_url('admin-ajax.php'), + 'savingText' => __('Saving Draft…'), + 'saveAlert' => __('The changes you made will be lost if you navigate away from this page.'), + 'l10n_print_after' => 'try{convertEntities(autosaveL10n);}catch(e){};' + ) ); + +} + +/** + * Administration Panel CSS for changing the styles. + * + * If installing the 'wp-admin/' directory will be replaced with './'. + * + * The $_wp_admin_css_colors global manages the Administration Panels CSS + * stylesheet that is loaded. The option that is set is 'admin_color' and is the + * color and key for the array. The value for the color key is an object with + * a 'url' parameter that has the URL path to the CSS file. + * + * The query from $src parameter will be appended to the URL that is given from + * the $_wp_admin_css_colors array value URL. + * + * @since 2.6.0 + * @uses $_wp_admin_css_colors + * + * @param string $src Source URL. + * @param string $handle Either 'colors' or 'colors-rtl'. + * @return string URL path to CSS stylesheet for Administration Panels. + */ +function wp_style_loader_src( $src, $handle ) { + if ( defined('WP_INSTALLING') ) + return preg_replace( '#^wp-admin/#', './', $src ); + + if ( 'colors' == $handle || 'colors-rtl' == $handle ) { + global $_wp_admin_css_colors; + $color = get_user_option('admin_color'); + + if ( empty($color) || !isset($_wp_admin_css_colors[$color]) ) + $color = 'fresh'; + + $color = $_wp_admin_css_colors[$color]; + $parsed = parse_url( $src ); + $url = $color->url; + + if ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) + $url = preg_replace('/.css$|.css(?=\?)/', '.dev.css', $url); + + if ( isset($parsed['query']) && $parsed['query'] ) { + wp_parse_str( $parsed['query'], $qv ); + $url = add_query_arg( $qv, $url ); + } + + return $url; + } + + return $src; +} + +/** + * Prints the script queue in the HTML head on admin pages. + * + * Postpones the scripts that were queued for the footer. + * print_footer_scripts() is called in the footer to print these scripts. + * + * @since 2.8 + * @see wp_print_scripts() + */ +function print_head_scripts() { + global $wp_scripts, $concatenate_scripts; + + if ( ! did_action('wp_print_scripts') ) + do_action('wp_print_scripts'); + + if ( !is_a($wp_scripts, 'WP_Scripts') ) + $wp_scripts = new WP_Scripts(); + + script_concat_settings(); + $wp_scripts->do_items( 'l10n' ); + $wp_scripts->do_concat = $concatenate_scripts; + $wp_scripts->do_head_items(); + + if ( apply_filters('print_head_scripts', true) ) + _print_scripts(); + + $wp_scripts->reset(); + return $wp_scripts->done; +} + +/** + * Prints the scripts that were queued for the footer on admin pages. + * + * @since 2.8 + */ +function print_footer_scripts() { + global $wp_scripts, $concatenate_scripts; + + if ( ! did_action('wp_print_footer_scripts') ) + do_action('wp_print_footer_scripts'); + + if ( !is_a($wp_scripts, 'WP_Scripts') ) + return array(); // No need to run if not instantiated. + + script_concat_settings(); + $wp_scripts->do_concat = $concatenate_scripts; + $wp_scripts->do_footer_items(); + + if ( apply_filters('print_footer_scripts', true) ) + _print_scripts(); + + $wp_scripts->reset(); + return $wp_scripts->done; +} + +function _print_scripts() { + global $wp_scripts, $compress_scripts; + + $zip = $compress_scripts ? 1 : 0; + if ( $zip && defined('ENFORCE_GZIP') && ENFORCE_GZIP ) + $zip = 'gzip'; + + if ( !empty($wp_scripts->concat) ) { + + if ( !empty($wp_scripts->print_code) ) { + echo "\n"; + } + + $ver = md5("$wp_scripts->concat_version"); + $src = $wp_scripts->base_url . "/wp-admin/load-scripts.php?c={$zip}&load=" . trim($wp_scripts->concat, ', ') . "&ver=$ver"; + echo "\n"; + } + + if ( !empty($wp_scripts->print_html) ) + echo $wp_scripts->print_html; +} + +/** + * Prints the script queue in the HTML head on the front end. + * + * Postpones the scripts that were queued for the footer. + * wp_print_footer_scripts() is called in the footer to print these scripts. + * + * @since 2.8 + */ +function wp_print_head_scripts() { + if ( ! did_action('wp_print_scripts') ) + do_action('wp_print_scripts'); + + global $wp_scripts; + + if ( !is_a($wp_scripts, 'WP_Scripts') ) + return array(); // no need to run if nothing is queued + + return print_head_scripts(); +} + +/** + * Prints the scripts that were queued for the footer on the front end. + * + * @since 2.8 + */ +function wp_print_footer_scripts() { + return print_footer_scripts(); +} + +/** + * Wrapper for do_action('wp_enqueue_scripts') + * + * Allows plugins to queue scripts for the front end using wp_enqueue_script(). + * Runs first in wp_head() where all is_home(), is_page(), etc. functions are available. + * + * @since 2.8 + */ +function wp_enqueue_scripts() { + do_action('wp_enqueue_scripts'); +} + +function print_admin_styles() { + global $wp_styles, $concatenate_scripts, $compress_css; + + if ( !is_a($wp_styles, 'WP_Styles') ) + $wp_styles = new WP_Styles(); + + script_concat_settings(); + $wp_styles->do_concat = $concatenate_scripts; + $zip = $compress_css ? 1 : 0; + if ( $zip && defined('ENFORCE_GZIP') && ENFORCE_GZIP ) + $zip = 'gzip'; + + $wp_styles->do_items(false); + + if ( apply_filters('print_admin_styles', true) ) { + if ( !empty($wp_styles->concat) ) { + $dir = $wp_styles->text_direction; + $ver = md5("$wp_styles->concat_version{$dir}"); + $href = $wp_styles->base_url . "/wp-admin/load-styles.php?c={$zip}&dir={$dir}&load=" . trim($wp_styles->concat, ', ') . "&ver=$ver"; + echo "\n"; + } + + if ( !empty($wp_styles->print_html) ) + echo $wp_styles->print_html; + } + + $wp_styles->do_concat = false; + $wp_styles->concat = $wp_styles->concat_version = $wp_styles->print_html = ''; + return $wp_styles->done; +} + +function script_concat_settings() { + global $concatenate_scripts, $compress_scripts, $compress_css; + + $compressed_output = ( ini_get('zlib.output_compression') || 'ob_gzhandler' == ini_get('output_handler') ); + + if ( ! isset($concatenate_scripts) ) { + $concatenate_scripts = defined('CONCATENATE_SCRIPTS') ? CONCATENATE_SCRIPTS : true; + if ( ! is_admin() || ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) ) + $concatenate_scripts = false; + } + + if ( ! isset($compress_scripts) ) { + $compress_scripts = defined('COMPRESS_SCRIPTS') ? COMPRESS_SCRIPTS : true; + if ( $compress_scripts && ( ! get_site_option('can_compress_scripts') || $compressed_output ) ) + $compress_scripts = false; + } + + if ( ! isset($compress_css) ) { + $compress_css = defined('COMPRESS_CSS') ? COMPRESS_CSS : true; + if ( $compress_css && ( ! get_site_option('can_compress_scripts') || $compressed_output ) ) + $compress_css = false; + } +} + +add_action( 'wp_default_scripts', 'wp_default_scripts' ); +add_filter( 'wp_print_scripts', 'wp_just_in_time_script_localization' ); +add_filter( 'print_scripts_array', 'wp_prototype_before_jquery' ); + +add_action( 'wp_default_styles', 'wp_default_styles' ); +add_filter( 'style_loader_src', 'wp_style_loader_src', 10, 2 ); diff --git a/src/wp-includes/shortcodes.php b/src/wp-includes/shortcodes.php new file mode 100644 index 00000000..f2048bda --- /dev/null +++ b/src/wp-includes/shortcodes.php @@ -0,0 +1,298 @@ + + * $out = do_shortcode($content); + * + * + * @link http://codex.wordpress.org/Shortcode_API + * + * @package WordPress + * @subpackage Shortcodes + * @since 2.5 + */ + +/** + * Container for storing shortcode tags and their hook to call for the shortcode + * + * @since 2.5 + * @name $shortcode_tags + * @var array + * @global array $shortcode_tags + */ +$shortcode_tags = array(); + +/** + * Add hook for shortcode tag. + * + * There can only be one hook for each shortcode. Which means that if another + * plugin has a similar shortcode, it will override yours or yours will override + * theirs depending on which order the plugins are included and/or ran. + * + * Simplest example of a shortcode tag using the API: + * + * + * // [footag foo="bar"] + * function footag_func($atts) { + * return "foo = {$atts[foo]}"; + * } + * add_shortcode('footag', 'footag_func'); + * + * + * Example with nice attribute defaults: + * + * + * // [bartag foo="bar"] + * function bartag_func($atts) { + * extract(shortcode_atts(array( + * 'foo' => 'no foo', + * 'baz' => 'default baz', + * ), $atts)); + * + * return "foo = {$foo}"; + * } + * add_shortcode('bartag', 'bartag_func'); + * + * + * Example with enclosed content: + * + * + * // [baztag]content[/baztag] + * function baztag_func($atts, $content='') { + * return "content = $content"; + * } + * add_shortcode('baztag', 'baztag_func'); + * + * + * @since 2.5 + * @uses $shortcode_tags + * + * @param string $tag Shortcode tag to be searched in post content. + * @param callable $func Hook to run when shortcode is found. + */ +function add_shortcode($tag, $func) { + global $shortcode_tags; + + if ( is_callable($func) ) + $shortcode_tags[$tag] = $func; +} + +/** + * Removes hook for shortcode. + * + * @since 2.5 + * @uses $shortcode_tags + * + * @param string $tag shortcode tag to remove hook for. + */ +function remove_shortcode($tag) { + global $shortcode_tags; + + unset($shortcode_tags[$tag]); +} + +/** + * Clear all shortcodes. + * + * This function is simple, it clears all of the shortcode tags by replacing the + * shortcodes global by a empty array. This is actually a very efficient method + * for removing all shortcodes. + * + * @since 2.5 + * @uses $shortcode_tags + */ +function remove_all_shortcodes() { + global $shortcode_tags; + + $shortcode_tags = array(); +} + +/** + * Search content for shortcodes and filter shortcodes through their hooks. + * + * If there are no shortcode tags defined, then the content will be returned + * without any filtering. This might cause issues when plugins are disabled but + * the shortcode will still show up in the post or content. + * + * @since 2.5 + * @uses $shortcode_tags + * @uses get_shortcode_regex() Gets the search pattern for searching shortcodes. + * + * @param string $content Content to search for shortcodes + * @return string Content with shortcodes filtered out. + */ +function do_shortcode($content) { + global $shortcode_tags; + + if (empty($shortcode_tags) || !is_array($shortcode_tags)) + return $content; + + $pattern = get_shortcode_regex(); + return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content); +} + +/** + * Retrieve the shortcode regular expression for searching. + * + * The regular expression combines the shortcode tags in the regular expression + * in a regex class. + * + * The regular expresion contains 6 different sub matches to help with parsing. + * + * 1/6 - An extra [ or ] to allow for escaping shortcodes with double [[]] + * 2 - The shortcode name + * 3 - The shortcode argument list + * 4 - The self closing / + * 5 - The content of a shortcode when it wraps some content. + * + * @since 2.5 + * @uses $shortcode_tags + * + * @return string The shortcode search regular expression + */ +function get_shortcode_regex() { + global $shortcode_tags; + $tagnames = array_keys($shortcode_tags); + $tagregexp = join( '|', array_map('preg_quote', $tagnames) ); + + // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes() + return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)'; +} + +/** + * Regular Expression callable for do_shortcode() for calling shortcode hook. + * @see get_shortcode_regex for details of the match array contents. + * + * @since 2.5 + * @access private + * @uses $shortcode_tags + * + * @param array $m Regular expression match array + * @return mixed False on failure. + */ +function do_shortcode_tag( $m ) { + global $shortcode_tags; + + // allow [[foo]] syntax for escaping a tag + if ( $m[1] == '[' && $m[6] == ']' ) { + return substr($m[0], 1, -1); + } + + $tag = $m[2]; + $attr = shortcode_parse_atts( $m[3] ); + + if ( isset( $m[5] ) ) { + // enclosing tag - extra parameter + return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, $m[5], $tag ) . $m[6]; + } else { + // self-closing tag + return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, NULL, $tag ) . $m[6]; + } +} + +/** + * Retrieve all attributes from the shortcodes tag. + * + * The attributes list has the attribute name as the key and the value of the + * attribute as the value in the key/value pair. This allows for easier + * retrieval of the attributes, since all attributes have to be known. + * + * @since 2.5 + * + * @param string $text + * @return array List of attributes and their value. + */ +function shortcode_parse_atts($text) { + $atts = array(); + $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/'; + $text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text); + if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) ) { + foreach ($match as $m) { + if (!empty($m[1])) + $atts[strtolower($m[1])] = stripcslashes($m[2]); + elseif (!empty($m[3])) + $atts[strtolower($m[3])] = stripcslashes($m[4]); + elseif (!empty($m[5])) + $atts[strtolower($m[5])] = stripcslashes($m[6]); + elseif (isset($m[7]) and strlen($m[7])) + $atts[] = stripcslashes($m[7]); + elseif (isset($m[8])) + $atts[] = stripcslashes($m[8]); + } + } else { + $atts = ltrim($text); + } + return $atts; +} + +/** + * Combine user attributes with known attributes and fill in defaults when needed. + * + * The pairs should be considered to be all of the attributes which are + * supported by the caller and given as a list. The returned attributes will + * only contain the attributes in the $pairs list. + * + * If the $atts list has unsupported attributes, then they will be ignored and + * removed from the final returned list. + * + * @since 2.5 + * + * @param array $pairs Entire list of supported attributes and their defaults. + * @param array $atts User defined attributes in shortcode tag. + * @return array Combined and filtered attribute list. + */ +function shortcode_atts($pairs, $atts) { + $atts = (array)$atts; + $out = array(); + foreach($pairs as $name => $default) { + if ( array_key_exists($name, $atts) ) + $out[$name] = $atts[$name]; + else + $out[$name] = $default; + } + return $out; +} + +/** + * Remove all shortcode tags from the given content. + * + * @since 2.5 + * @uses $shortcode_tags + * + * @param string $content Content to remove shortcode tags. + * @return string Content without shortcode tags. + */ +function strip_shortcodes( $content ) { + global $shortcode_tags; + + if (empty($shortcode_tags) || !is_array($shortcode_tags)) + return $content; + + $pattern = get_shortcode_regex(); + + return preg_replace('/'.$pattern.'/s', '$1$6', $content); +} + +add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop() + +?> \ No newline at end of file diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php new file mode 100644 index 00000000..d9ae2d5a --- /dev/null +++ b/src/wp-includes/taxonomy.php @@ -0,0 +1,3149 @@ + true, + 'update_count_callback' => '_update_post_term_count', + 'query_var' => 'category_name', + 'rewrite' => did_action( 'init' ) ? array( + 'hierarchical' => true, + 'slug' => get_option('category_base') ? get_option('category_base') : 'category', + 'with_front' => ( get_option('category_base') && ! $wp_rewrite->using_index_permalinks() ) ? false : true ) : false, + 'public' => true, + 'show_ui' => true, + '_builtin' => true, + ) ); + + register_taxonomy( 'post_tag', 'post', array( + 'hierarchical' => false, + 'update_count_callback' => '_update_post_term_count', + 'query_var' => 'tag', + 'rewrite' => did_action( 'init' ) ? array( + 'slug' => get_option('tag_base') ? get_option('tag_base') : 'tag', + 'with_front' => ( get_option('category_base') && ! $wp_rewrite->using_index_permalinks() ) ? false : true ) : false, + 'public' => true, + 'show_ui' => true, + '_builtin' => true, + ) ); + + register_taxonomy( 'nav_menu', 'nav_menu_item', array( + 'public' => false, + 'hierarchical' => false, + 'labels' => array( + 'name' => __( 'Navigation Menus' ), + 'singular_name' => __( 'Navigation Menu' ), + ), + 'query_var' => false, + 'rewrite' => false, + 'show_ui' => false, + '_builtin' => true, + 'show_in_nav_menus' => false, + ) ); + + register_taxonomy( 'link_category', 'link', array( + 'hierarchical' => false, + 'labels' => array( + 'name' => __( 'Link Categories' ), + 'singular_name' => __( 'Link Category' ), + 'search_items' => __( 'Search Link Categories' ), + 'popular_items' => null, + 'all_items' => __( 'All Link Categories' ), + 'edit_item' => __( 'Edit Link Category' ), + 'update_item' => __( 'Update Link Category' ), + 'add_new_item' => __( 'Add New Link Category' ), + 'new_item_name' => __( 'New Link Category Name' ), + 'separate_items_with_commas' => null, + 'add_or_remove_items' => null, + 'choose_from_most_used' => null, + ), + 'query_var' => false, + 'rewrite' => false, + 'public' => false, + 'show_ui' => false, + '_builtin' => true, + ) ); + + $rewrite = false; + if ( did_action( 'init' ) ) { + $rewrite = apply_filters( 'post_format_rewrite_base', 'type' ); + $rewrite = $rewrite ? array( 'slug' => $rewrite ) : false; + } + + register_taxonomy( 'post_format', 'post', array( + 'public' => true, + 'hierarchical' => false, + 'labels' => array( + 'name' => _x( 'Format', 'post format' ), + 'singular_name' => _x( 'Format', 'post format' ), + ), + 'query_var' => true, + 'rewrite' => $rewrite, + 'show_ui' => false, + '_builtin' => true, + 'show_in_nav_menus' => false, + ) ); +} +add_action( 'init', 'create_initial_taxonomies', 0 ); // highest priority + +/** + * Get a list of registered taxonomy objects. + * + * @package WordPress + * @subpackage Taxonomy + * @since 3.0.0 + * @uses $wp_taxonomies + * @see register_taxonomy + * + * @param array $args An array of key => value arguments to match against the taxonomy objects. + * @param string $output The type of output to return, either taxonomy 'names' or 'objects'. 'names' is the default. + * @param string $operator The logical operation to perform. 'or' means only one element + * from the array needs to match; 'and' means all elements must match. The default is 'and'. + * @return array A list of taxonomy names or objects + */ +function get_taxonomies( $args = array(), $output = 'names', $operator = 'and' ) { + global $wp_taxonomies; + + $field = ('names' == $output) ? 'name' : false; + + return wp_filter_object_list($wp_taxonomies, $args, $operator, $field); +} + + +/** + * Return all of the taxonomy names that are of $object_type. + * + * It appears that this function can be used to find all of the names inside of + * $wp_taxonomies global variable. + * + * Should + * result in Array('category', 'post_tag') + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wp_taxonomies + * + * @param array|string|object $object Name of the type of taxonomy object, or an object (row from posts) + * @param string $output The type of output to return, either taxonomy 'names' or 'objects'. 'names' is the default. + * @return array The names of all taxonomy of $object_type. + */ +function get_object_taxonomies($object, $output = 'names') { + global $wp_taxonomies; + + if ( is_object($object) ) { + if ( $object->post_type == 'attachment' ) + return get_attachment_taxonomies($object); + $object = $object->post_type; + } + + $object = (array) $object; + + $taxonomies = array(); + foreach ( (array) $wp_taxonomies as $tax_name => $tax_obj ) { + if ( array_intersect($object, (array) $tax_obj->object_type) ) { + if ( 'names' == $output ) + $taxonomies[] = $tax_name; + else + $taxonomies[ $tax_name ] = $tax_obj; + } + } + + return $taxonomies; +} + +/** + * Retrieves the taxonomy object of $taxonomy. + * + * The get_taxonomy function will first check that the parameter string given + * is a taxonomy object and if it is, it will return it. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wp_taxonomies + * @uses taxonomy_exists() Checks whether taxonomy exists + * + * @param string $taxonomy Name of taxonomy object to return + * @return object|bool The Taxonomy Object or false if $taxonomy doesn't exist + */ +function get_taxonomy( $taxonomy ) { + global $wp_taxonomies; + + if ( ! taxonomy_exists( $taxonomy ) ) + return false; + + return $wp_taxonomies[$taxonomy]; +} + +/** + * Checks that the taxonomy name exists. + * + * Formerly is_taxonomy(), introduced in 2.3.0. + * + * @package WordPress + * @subpackage Taxonomy + * @since 3.0.0 + * + * @uses $wp_taxonomies + * + * @param string $taxonomy Name of taxonomy object + * @return bool Whether the taxonomy exists. + */ +function taxonomy_exists( $taxonomy ) { + global $wp_taxonomies; + + return isset( $wp_taxonomies[$taxonomy] ); +} + +/** + * Whether the taxonomy object is hierarchical. + * + * Checks to make sure that the taxonomy is an object first. Then Gets the + * object, and finally returns the hierarchical value in the object. + * + * A false return value might also mean that the taxonomy does not exist. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses taxonomy_exists() Checks whether taxonomy exists + * @uses get_taxonomy() Used to get the taxonomy object + * + * @param string $taxonomy Name of taxonomy object + * @return bool Whether the taxonomy is hierarchical + */ +function is_taxonomy_hierarchical($taxonomy) { + if ( ! taxonomy_exists($taxonomy) ) + return false; + + $taxonomy = get_taxonomy($taxonomy); + return $taxonomy->hierarchical; +} + +/** + * Create or modify a taxonomy object. Do not use before init. + * + * A simple function for creating or modifying a taxonomy object based on the + * parameters given. The function will accept an array (third optional + * parameter), along with strings for the taxonomy name and another string for + * the object type. + * + * Nothing is returned, so expect error maybe or use taxonomy_exists() to check + * whether taxonomy exists. + * + * Optional $args contents: + * + * label - Name of the taxonomy shown in the menu. Usually plural. If not set, labels['name'] will be used. + * + * hierarchical - has some defined purpose at other parts of the API and is a + * boolean value. + * + * update_count_callback - works much like a hook, in that it will be called + * when the count is updated. + * + * rewrite - false to prevent rewrite, or array('slug'=>$slug) to customize + * permastruct; default will use $taxonomy as slug. + * + * query_var - false to prevent queries, or string to customize query var + * (?$query_var=$term); default will use $taxonomy as query var. + * + * public - If the taxonomy should be publically queryable; //@TODO not implemented. + * defaults to true. + * + * show_ui - If the WordPress UI admin tags UI should apply to this taxonomy; + * defaults to public. + * + * show_in_nav_menus - true makes this taxonomy available for selection in navigation menus. + * Defaults to public. + * + * show_tagcloud - false to prevent the taxonomy being listed in the Tag Cloud Widget; + * defaults to show_ui which defalts to public. + * + * labels - An array of labels for this taxonomy. You can see accepted values in {@link get_taxonomy_labels()}. By default tag labels are used for non-hierarchical types and category labels for hierarchical ones. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wp_taxonomies Inserts new taxonomy object into the list + * @uses $wp_rewrite Adds rewrite tags and permastructs + * @uses $wp Adds query vars + * + * @param string $taxonomy Name of taxonomy object + * @param array|string $object_type Name of the object type for the taxonomy object. + * @param array|string $args See above description for the two keys values. + */ +function register_taxonomy( $taxonomy, $object_type, $args = array() ) { + global $wp_taxonomies, $wp_rewrite, $wp; + + if ( ! is_array($wp_taxonomies) ) + $wp_taxonomies = array(); + + $defaults = array( 'hierarchical' => false, + 'update_count_callback' => '', + 'rewrite' => true, + 'query_var' => $taxonomy, + 'public' => true, + 'show_ui' => null, + 'show_tagcloud' => null, + '_builtin' => false, + 'labels' => array(), + 'capabilities' => array(), + 'show_in_nav_menus' => null, + ); + $args = wp_parse_args($args, $defaults); + + if ( false !== $args['query_var'] && !empty($wp) ) { + if ( true === $args['query_var'] ) + $args['query_var'] = $taxonomy; + $args['query_var'] = sanitize_title_with_dashes($args['query_var']); + $wp->add_query_var($args['query_var']); + } + + if ( false !== $args['rewrite'] && '' != get_option('permalink_structure') ) { + $args['rewrite'] = wp_parse_args($args['rewrite'], array( + 'slug' => sanitize_title_with_dashes($taxonomy), + 'with_front' => true, + 'hierarchical' => false + )); + + if ( $args['hierarchical'] && $args['rewrite']['hierarchical'] ) + $tag = '(.+?)'; + else + $tag = '([^/]+)'; + + $wp_rewrite->add_rewrite_tag("%$taxonomy%", $tag, $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term="); + $wp_rewrite->add_permastruct($taxonomy, "{$args['rewrite']['slug']}/%$taxonomy%", $args['rewrite']['with_front']); + } + + if ( is_null($args['show_ui']) ) + $args['show_ui'] = $args['public']; + + // Whether to show this type in nav-menus.php. Defaults to the setting for public. + if ( null === $args['show_in_nav_menus'] ) + $args['show_in_nav_menus'] = $args['public']; + + if ( is_null($args['show_tagcloud']) ) + $args['show_tagcloud'] = $args['show_ui']; + + $default_caps = array( + 'manage_terms' => 'manage_categories', + 'edit_terms' => 'manage_categories', + 'delete_terms' => 'manage_categories', + 'assign_terms' => 'edit_posts', + ); + $args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] ); + unset( $args['capabilities'] ); + + $args['name'] = $taxonomy; + $args['object_type'] = (array) $object_type; + + $args['labels'] = get_taxonomy_labels( (object) $args ); + $args['label'] = $args['labels']->name; + + $wp_taxonomies[$taxonomy] = (object) $args; + + // register callback handling for metabox + add_filter('wp_ajax_add-' . $taxonomy, '_wp_ajax_add_hierarchical_term'); +} + +/** + * Builds an object with all taxonomy labels out of a taxonomy object + * + * Accepted keys of the label array in the taxonomy object: + * - name - general name for the taxonomy, usually plural. The same as and overriden by $tax->label. Default is Post Tags/Categories + * - singular_name - name for one object of this taxonomy. Default is Post Tag/Category + * - search_items - Default is Search Tags/Search Categories + * - popular_items - This string isn't used on hierarchical taxonomies. Default is Popular Tags + * - all_items - Default is All Tags/All Categories + * - parent_item - This string isn't used on non-hierarchical taxonomies. In hierarchical ones the default is Parent Category + * - parent_item_colon - The same as parent_item, but with colon : in the end + * - edit_item - Default is Edit Tag/Edit Category + * - update_item - Default is Update Tag/Update Category + * - add_new_item - Default is Add New Tag/Add New Category + * - new_item_name - Default is New Tag Name/New Category Name + * - separate_items_with_commas - This string isn't used on hierarchical taxonomies. Default is "Separate tags with commas," used in the meta box. + * - add_or_remove_items - This string isn't used on hierarchical taxonomies. Default is "Add or remove tags," used in the meta box when JavaScript is disabled. + * - choose_from_most_used - This string isn't used on hierarchical taxonomies. Default is "Choose from the most used tags," used in the meta box. + * + * Above, the first default value is for non-hierarchical taxonomies (like tags) and the second one is for hierarchical taxonomies (like categories.) + * + * @since 3.0.0 + * @param object $tax Taxonomy object + * @return object object with all the labels as member variables + */ + +function get_taxonomy_labels( $tax ) { + if ( isset( $tax->helps ) && empty( $tax->labels['separate_items_with_commas'] ) ) + $tax->labels['separate_items_with_commas'] = $tax->helps; + + $nohier_vs_hier_defaults = array( + 'name' => array( _x( 'Post Tags', 'taxonomy general name' ), _x( 'Categories', 'taxonomy general name' ) ), + 'singular_name' => array( _x( 'Post Tag', 'taxonomy singular name' ), _x( 'Category', 'taxonomy singular name' ) ), + 'search_items' => array( __( 'Search Tags' ), __( 'Search Categories' ) ), + 'popular_items' => array( __( 'Popular Tags' ), null ), + 'all_items' => array( __( 'All Tags' ), __( 'All Categories' ) ), + 'parent_item' => array( null, __( 'Parent Category' ) ), + 'parent_item_colon' => array( null, __( 'Parent Category:' ) ), + 'edit_item' => array( __( 'Edit Tag' ), __( 'Edit Category' ) ), + 'update_item' => array( __( 'Update Tag' ), __( 'Update Category' ) ), + 'add_new_item' => array( __( 'Add New Tag' ), __( 'Add New Category' ) ), + 'new_item_name' => array( __( 'New Tag Name' ), __( 'New Category Name' ) ), + 'separate_items_with_commas' => array( __( 'Separate tags with commas' ), null ), + 'add_or_remove_items' => array( __( 'Add or remove tags' ), null ), + 'choose_from_most_used' => array( __( 'Choose from the most used tags' ), null ), + ); + $nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name']; + + return _get_custom_object_labels( $tax, $nohier_vs_hier_defaults ); +} + +/** + * Add an already registered taxonomy to an object type. + * + * @package WordPress + * @subpackage Taxonomy + * @since 3.0.0 + * @uses $wp_taxonomies Modifies taxonomy object + * + * @param string $taxonomy Name of taxonomy object + * @param array|string $object_type Name of the object type + * @return bool True if successful, false if not + */ +function register_taxonomy_for_object_type( $taxonomy, $object_type) { + global $wp_taxonomies; + + if ( !isset($wp_taxonomies[$taxonomy]) ) + return false; + + if ( ! get_post_type_object($object_type) ) + return false; + + $wp_taxonomies[$taxonomy]->object_type[] = $object_type; + + return true; +} + +// +// Term API +// + +/** + * Retrieve object_ids of valid taxonomy and term. + * + * The strings of $taxonomies must exist before this function will continue. On + * failure of finding a valid taxonomy, it will return an WP_Error class, kind + * of like Exceptions in PHP 5, except you can't catch them. Even so, you can + * still test for the WP_Error class and get the error message. + * + * The $terms aren't checked the same as $taxonomies, but still need to exist + * for $object_ids to be returned. + * + * It is possible to change the order that object_ids is returned by either + * using PHP sort family functions or using the database by using $args with + * either ASC or DESC array. The value should be in the key named 'order'. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * @uses wp_parse_args() Creates an array from string $args. + * + * @param int|array $term_ids Term id or array of term ids of terms that will be used + * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names + * @param array|string $args Change the order of the object_ids, either ASC or DESC + * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success + * the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found. + */ +function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) { + global $wpdb; + + if ( ! is_array( $term_ids ) ) + $term_ids = array( $term_ids ); + + if ( ! is_array( $taxonomies ) ) + $taxonomies = array( $taxonomies ); + + foreach ( (array) $taxonomies as $taxonomy ) { + if ( ! taxonomy_exists( $taxonomy ) ) + return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy' ) ); + } + + $defaults = array( 'order' => 'ASC' ); + $args = wp_parse_args( $args, $defaults ); + extract( $args, EXTR_SKIP ); + + $order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC'; + + $term_ids = array_map('intval', $term_ids ); + + $taxonomies = "'" . implode( "', '", $taxonomies ) . "'"; + $term_ids = "'" . implode( "', '", $term_ids ) . "'"; + + $object_ids = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($term_ids) ORDER BY tr.object_id $order"); + + if ( ! $object_ids ) + return array(); + + return $object_ids; +} + +/** + * Given a taxonomy query, generates SQL to be appended to a main query. + * + * @since 3.1.0 + * + * @see WP_Tax_Query + * + * @param array $tax_query A compact tax query + * @param string $primary_table + * @param string $primary_id_column + * @return array + */ +function get_tax_sql( $tax_query, $primary_table, $primary_id_column ) { + $tax_query_obj = new WP_Tax_Query( $tax_query ); + return $tax_query_obj->get_sql( $primary_table, $primary_id_column ); +} + +/** + * Container class for a multiple taxonomy query. + * + * @since 3.1.0 + */ +class WP_Tax_Query { + + /** + * List of taxonomy queries. A single taxonomy query is an associative array: + * - 'taxonomy' string The taxonomy being queried + * - 'terms' string|array The list of terms + * - 'field' string (optional) Which term field is being used. + * Possible values: 'term_id', 'slug' or 'name' + * Default: 'term_id' + * - 'operator' string (optional) + * Possible values: 'IN' and 'NOT IN'. + * Default: 'IN' + * - 'include_children' bool (optional) Whether to include child terms. + * Default: true + * + * @since 3.1.0 + * @access public + * @var array + */ + var $queries = array(); + + /** + * The relation between the queries. Can be one of 'AND' or 'OR'. + * + * @since 3.1.0 + * @access public + * @var string + */ + var $relation; + + /** + * PHP4 type constructor. + * + * Parses a compact tax query and sets defaults. + * + * @since 3.1.0 + * @access public + * + * @param array $tax_query A compact tax query: + * array( + * 'relation' => 'OR', + * array( + * 'taxonomy' => 'tax1', + * 'terms' => array( 'term1', 'term2' ), + * 'field' => 'slug', + * ), + * array( + * 'taxonomy' => 'tax2', + * 'terms' => array( 'term-a', 'term-b' ), + * 'field' => 'slug', + * ), + * ) + * + * @return WP_Tax_Query + */ + function WP_Tax_Query( $tax_query ) { + if ( isset( $tax_query['relation'] ) && strtoupper( $tax_query['relation'] ) == 'OR' ) { + $this->relation = 'OR'; + } else { + $this->relation = 'AND'; + } + + $defaults = array( + 'taxonomy' => '', + 'terms' => array(), + 'include_children' => true, + 'field' => 'term_id', + 'operator' => 'IN', + ); + + foreach ( $tax_query as $query ) { + if ( ! is_array( $query ) ) + continue; + + $query = array_merge( $defaults, $query ); + + $query['terms'] = (array) $query['terms']; + + $this->queries[] = $query; + } + } + + /** + * Generates SQL clauses to be appended to a main query. + * + * @since 3.1.0 + * @access public + * + * @param string $primary_table + * @param string $primary_id_column + * @return array + */ + function get_sql( $primary_table, $primary_id_column ) { + global $wpdb; + + $join = ''; + $where = array(); + $i = 0; + + foreach ( $this->queries as $query ) { + extract( $query ); + + if ( ! taxonomy_exists( $taxonomy ) ) + return array( 'join' => '', 'where' => ' AND 0 = 1'); + + $terms = array_unique( (array) $terms ); + + if ( empty( $terms ) ) + continue; + + if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) { + $this->_transform_terms( $terms, $taxonomy, $field, 'term_id' ); + + $children = array(); + foreach ( $terms as $term ) { + $children = array_merge( $children, get_term_children( $term, $taxonomy ) ); + $children[] = $term; + } + $terms = $children; + + $this->_transform_terms( $terms, $taxonomy, 'term_id', 'term_taxonomy_id' ); + } + else { + $this->_transform_terms( $terms, $taxonomy, $field, 'term_taxonomy_id' ); + } + + if ( 'IN' == $operator ) { + + if ( empty( $terms ) ) { + if ( 'OR' == $this->relation ) + continue; + else + return array( 'join' => '', 'where' => ' AND 0 = 1' ); + } + + $terms = implode( ',', $terms ); + + $alias = $i ? 'tt' . $i : $wpdb->term_relationships; + + $join .= " INNER JOIN $wpdb->term_relationships"; + $join .= $i ? " AS $alias" : ''; + $join .= " ON ($primary_table.$primary_id_column = $alias.object_id)"; + + $where[] = "$alias.term_taxonomy_id $operator ($terms)"; + } elseif ( 'NOT IN' == $operator ) { + + if ( empty( $terms ) ) + continue; + + $terms = implode( ',', $terms ); + + $where[] = "$primary_table.$primary_id_column NOT IN ( + SELECT object_id + FROM $wpdb->term_relationships + WHERE term_taxonomy_id IN ($terms) + )"; + } elseif ( 'AND' == $operator ) { + + if ( empty( $terms ) ) + continue; + + $num_terms = count( $terms ); + + $terms = implode( ',', $terms ); + + $where[] = "$primary_table.$primary_id_column IN ( + SELECT object_id + FROM $wpdb->term_relationships + WHERE term_taxonomy_id IN ($terms) + GROUP BY object_id HAVING COUNT(object_id) = $num_terms + )"; + } + + $i++; + } + + if ( !empty( $where ) ) + $where = ' AND ( ' . implode( " $this->relation ", $where ) . ' )'; + else + $where = ''; + + return compact( 'join', 'where' ); + } + + /** + * Transforms a list of terms, from one field to another. + * + * @since 3.1.0 + * @access private + * + * @param array &$terms The list of terms + * @param string $taxonomy The taxonomy of the terms + * @param string $field The initial field + * @param string $resulting_field The resulting field + */ + function _transform_terms( &$terms, $taxonomy, $field, $resulting_field ) { + global $wpdb; + + if ( empty( $terms ) ) + return; + + if ( $field == $resulting_field ) + return; + + $resulting_field = esc_sql( $resulting_field ); + + switch ( $field ) { + case 'slug': + case 'name': + $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'"; + $terms = $wpdb->get_col( " + SELECT $wpdb->term_taxonomy.$resulting_field + FROM $wpdb->term_taxonomy + INNER JOIN $wpdb->terms USING (term_id) + WHERE taxonomy = '$taxonomy' + AND $wpdb->terms.$field IN ($terms) + " ); + break; + + default: + $terms = implode( ',', array_map( 'intval', $terms ) ); + $terms = $wpdb->get_col( " + SELECT $resulting_field + FROM $wpdb->term_taxonomy + WHERE taxonomy = '$taxonomy' + AND term_id IN ($terms) + " ); + } + } +} + +/** + * Get all Term data from database by Term ID. + * + * The usage of the get_term function is to apply filters to a term object. It + * is possible to get a term object from the database before applying the + * filters. + * + * $term ID must be part of $taxonomy, to get from the database. Failure, might + * be able to be captured by the hooks. Failure would be the same value as $wpdb + * returns for the get_row method. + * + * There are two hooks, one is specifically for each term, named 'get_term', and + * the second is for the taxonomy name, 'term_$taxonomy'. Both hooks gets the + * term object, and the taxonomy name as parameters. Both hooks are expected to + * return a Term object. + * + * 'get_term' hook - Takes two parameters the term Object and the taxonomy name. + * Must return term object. Used in get_term() as a catch-all filter for every + * $term. + * + * 'get_$taxonomy' hook - Takes two parameters the term Object and the taxonomy + * name. Must return term object. $taxonomy will be the taxonomy name, so for + * example, if 'category', it would be 'get_category' as the filter name. Useful + * for custom taxonomies or plugging into default taxonomies. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * @uses sanitize_term() Cleanses the term based on $filter context before returning. + * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. + * + * @param int|object $term If integer, will get from database. If object will apply filters and return $term. + * @param string $taxonomy Taxonomy name that $term is part of. + * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N + * @param string $filter Optional, default is raw or no WordPress defined filter will applied. + * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not + * exist then WP_Error will be returned. + */ +function &get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { + global $wpdb; + $null = null; + + if ( empty($term) ) { + $error = new WP_Error('invalid_term', __('Empty Term')); + return $error; + } + + if ( ! taxonomy_exists($taxonomy) ) { + $error = new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); + return $error; + } + + if ( is_object($term) && empty($term->filter) ) { + wp_cache_add($term->term_id, $term, $taxonomy); + $_term = $term; + } else { + if ( is_object($term) ) + $term = $term->term_id; + $term = (int) $term; + if ( ! $_term = wp_cache_get($term, $taxonomy) ) { + $_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND t.term_id = %s LIMIT 1", $taxonomy, $term) ); + if ( ! $_term ) + return $null; + wp_cache_add($term, $_term, $taxonomy); + } + } + + $_term = apply_filters('get_term', $_term, $taxonomy); + $_term = apply_filters("get_$taxonomy", $_term, $taxonomy); + $_term = sanitize_term($_term, $taxonomy, $filter); + + if ( $output == OBJECT ) { + return $_term; + } elseif ( $output == ARRAY_A ) { + $__term = get_object_vars($_term); + return $__term; + } elseif ( $output == ARRAY_N ) { + $__term = array_values(get_object_vars($_term)); + return $__term; + } else { + return $_term; + } +} + +/** + * Get all Term data from database by Term field and data. + * + * Warning: $value is not escaped for 'name' $field. You must do it yourself, if + * required. + * + * The default $field is 'id', therefore it is possible to also use null for + * field, but not recommended that you do so. + * + * If $value does not exist, the return value will be false. If $taxonomy exists + * and $field and $value combinations exist, the Term will be returned. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * @uses sanitize_term() Cleanses the term based on $filter context before returning. + * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. + * + * @param string $field Either 'slug', 'name', or 'id' + * @param string|int $value Search for this term value + * @param string $taxonomy Taxonomy Name + * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N + * @param string $filter Optional, default is raw or no WordPress defined filter will applied. + * @return mixed Term Row from database. Will return false if $taxonomy does not exist or $term was not found. + */ +function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw') { + global $wpdb; + + if ( ! taxonomy_exists($taxonomy) ) + return false; + + if ( 'slug' == $field ) { + $field = 't.slug'; + $value = sanitize_title($value); + if ( empty($value) ) + return false; + } else if ( 'name' == $field ) { + // Assume already escaped + $value = stripslashes($value); + $field = 't.name'; + } else { + $term = get_term( (int) $value, $taxonomy, $output, $filter); + if ( is_wp_error( $term ) ) + $term = false; + return $term; + } + + $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND $field = %s LIMIT 1", $taxonomy, $value) ); + if ( !$term ) + return false; + + wp_cache_add($term->term_id, $term, $taxonomy); + + $term = apply_filters('get_term', $term, $taxonomy); + $term = apply_filters("get_$taxonomy", $term, $taxonomy); + $term = sanitize_term($term, $taxonomy, $filter); + + if ( $output == OBJECT ) { + return $term; + } elseif ( $output == ARRAY_A ) { + return get_object_vars($term); + } elseif ( $output == ARRAY_N ) { + return array_values(get_object_vars($term)); + } else { + return $term; + } +} + +/** + * Merge all term children into a single array of their IDs. + * + * This recursive function will merge all of the children of $term into the same + * array of term IDs. Only useful for taxonomies which are hierarchical. + * + * Will return an empty array if $term does not exist in $taxonomy. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * @uses _get_term_hierarchy() + * @uses get_term_children() Used to get the children of both $taxonomy and the parent $term + * + * @param string $term_id ID of Term to get children + * @param string $taxonomy Taxonomy Name + * @return array|WP_Error List of Term Objects. WP_Error returned if $taxonomy does not exist + */ +function get_term_children( $term_id, $taxonomy ) { + if ( ! taxonomy_exists($taxonomy) ) + return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); + + $term_id = intval( $term_id ); + + $terms = _get_term_hierarchy($taxonomy); + + if ( ! isset($terms[$term_id]) ) + return array(); + + $children = $terms[$term_id]; + + foreach ( (array) $terms[$term_id] as $child ) { + if ( isset($terms[$child]) ) + $children = array_merge($children, get_term_children($child, $taxonomy)); + } + + return $children; +} + +/** + * Get sanitized Term field. + * + * Does checks for $term, based on the $taxonomy. The function is for contextual + * reasons and for simplicity of usage. See sanitize_term_field() for more + * information. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses sanitize_term_field() Passes the return value in sanitize_term_field on success. + * + * @param string $field Term field to fetch + * @param int $term Term ID + * @param string $taxonomy Taxonomy Name + * @param string $context Optional, default is display. Look at sanitize_term_field() for available options. + * @return mixed Will return an empty string if $term is not an object or if $field is not set in $term. + */ +function get_term_field( $field, $term, $taxonomy, $context = 'display' ) { + $term = (int) $term; + $term = get_term( $term, $taxonomy ); + if ( is_wp_error($term) ) + return $term; + + if ( !is_object($term) ) + return ''; + + if ( !isset($term->$field) ) + return ''; + + return sanitize_term_field($field, $term->$field, $term->term_id, $taxonomy, $context); +} + +/** + * Sanitizes Term for editing. + * + * Return value is sanitize_term() and usage is for sanitizing the term for + * editing. Function is for contextual and simplicity. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses sanitize_term() Passes the return value on success + * + * @param int|object $id Term ID or Object + * @param string $taxonomy Taxonomy Name + * @return mixed|null|WP_Error Will return empty string if $term is not an object. + */ +function get_term_to_edit( $id, $taxonomy ) { + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error($term) ) + return $term; + + if ( !is_object($term) ) + return ''; + + return sanitize_term($term, $taxonomy, 'edit'); +} + +/** + * Retrieve the terms in a given taxonomy or list of taxonomies. + * + * You can fully inject any customizations to the query before it is sent, as + * well as control the output with a filter. + * + * The 'get_terms' filter will be called when the cache has the term and will + * pass the found term along with the array of $taxonomies and array of $args. + * This filter is also called before the array of terms is passed and will pass + * the array of terms, along with the $taxonomies and $args. + * + * The 'list_terms_exclusions' filter passes the compiled exclusions along with + * the $args. + * + * The 'get_terms_orderby' filter passes the ORDER BY clause for the query + * along with the $args array. + * + * The 'get_terms_fields' filter passes the fields for the SELECT query + * along with the $args array. + * + * The list of arguments that $args can contain, which will overwrite the defaults: + * + * orderby - Default is 'name'. Can be name, count, term_group, slug or nothing + * (will use term_id), Passing a custom value other than these will cause it to + * order based on the custom value. + * + * order - Default is ASC. Can use DESC. + * + * hide_empty - Default is true. Will not return empty terms, which means + * terms whose count is 0 according to the given taxonomy. + * + * exclude - Default is an empty array. An array, comma- or space-delimited string + * of term ids to exclude from the return array. If 'include' is non-empty, + * 'exclude' is ignored. + * + * exclude_tree - Default is an empty array. An array, comma- or space-delimited + * string of term ids to exclude from the return array, along with all of their + * descendant terms according to the primary taxonomy. If 'include' is non-empty, + * 'exclude_tree' is ignored. + * + * include - Default is an empty array. An array, comma- or space-delimited string + * of term ids to include in the return array. + * + * number - The maximum number of terms to return. Default is to return them all. + * + * offset - The number by which to offset the terms query. + * + * fields - Default is 'all', which returns an array of term objects. + * If 'fields' is 'ids' or 'names', returns an array of + * integers or strings, respectively. + * + * slug - Returns terms whose "slug" matches this value. Default is empty string. + * + * hierarchical - Whether to include terms that have non-empty descendants + * (even if 'hide_empty' is set to true). + * + * search - Returned terms' names will contain the value of 'search', + * case-insensitive. Default is an empty string. + * + * name__like - Returned terms' names will begin with the value of 'name__like', + * case-insensitive. Default is empty string. + * + * The argument 'pad_counts', if set to true will include the quantity of a term's + * children in the quantity of each term's "count" object variable. + * + * The 'get' argument, if set to 'all' instead of its default empty string, + * returns terms regardless of ancestry or whether the terms are empty. + * + * The 'child_of' argument, when used, should be set to the integer of a term ID. Its default + * is 0. If set to a non-zero value, all returned terms will be descendants + * of that term according to the given taxonomy. Hence 'child_of' is set to 0 + * if more than one taxonomy is passed in $taxonomies, because multiple taxonomies + * make term ancestry ambiguous. + * + * The 'parent' argument, when used, should be set to the integer of a term ID. Its default is + * the empty string '', which has a different meaning from the integer 0. + * If set to an integer value, all returned terms will have as an immediate + * ancestor the term whose ID is specified by that integer according to the given taxonomy. + * The 'parent' argument is different from 'child_of' in that a term X is considered a 'parent' + * of term Y only if term X is the father of term Y, not its grandfather or great-grandfather, etc. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * @uses wp_parse_args() Merges the defaults with those defined by $args and allows for strings. + * + * @param string|array $taxonomies Taxonomy name or list of Taxonomy names + * @param string|array $args The values of what to search for when returning terms + * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist. + */ +function &get_terms($taxonomies, $args = '') { + global $wpdb; + $empty_array = array(); + + $single_taxonomy = false; + if ( !is_array($taxonomies) ) { + $single_taxonomy = true; + $taxonomies = array($taxonomies); + } + + foreach ( $taxonomies as $taxonomy ) { + if ( ! taxonomy_exists($taxonomy) ) { + $error = & new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); + return $error; + } + } + + $defaults = array('orderby' => 'name', 'order' => 'ASC', + 'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(), + 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', + 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', + 'pad_counts' => false, 'offset' => '', 'search' => ''); + $args = wp_parse_args( $args, $defaults ); + $args['number'] = absint( $args['number'] ); + $args['offset'] = absint( $args['offset'] ); + if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || + '' !== $args['parent'] ) { + $args['child_of'] = 0; + $args['hierarchical'] = false; + $args['pad_counts'] = false; + } + + if ( 'all' == $args['get'] ) { + $args['child_of'] = 0; + $args['hide_empty'] = 0; + $args['hierarchical'] = false; + $args['pad_counts'] = false; + } + + $args = apply_filters( 'get_terms_args', $args, $taxonomies ); + + extract($args, EXTR_SKIP); + + if ( $child_of ) { + $hierarchy = _get_term_hierarchy($taxonomies[0]); + if ( !isset($hierarchy[$child_of]) ) + return $empty_array; + } + + if ( $parent ) { + $hierarchy = _get_term_hierarchy($taxonomies[0]); + if ( !isset($hierarchy[$parent]) ) + return $empty_array; + } + + // $args can be whatever, only use the args defined in defaults to compute the key + $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : ''; + $key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key ); + $last_changed = wp_cache_get('last_changed', 'terms'); + if ( !$last_changed ) { + $last_changed = time(); + wp_cache_set('last_changed', $last_changed, 'terms'); + } + $cache_key = "get_terms:$key:$last_changed"; + $cache = wp_cache_get( $cache_key, 'terms' ); + if ( false !== $cache ) { + $cache = apply_filters('get_terms', $cache, $taxonomies, $args); + return $cache; + } + + $_orderby = strtolower($orderby); + if ( 'count' == $_orderby ) + $orderby = 'tt.count'; + else if ( 'name' == $_orderby ) + $orderby = 't.name'; + else if ( 'slug' == $_orderby ) + $orderby = 't.slug'; + else if ( 'term_group' == $_orderby ) + $orderby = 't.term_group'; + else if ( 'none' == $_orderby ) + $orderby = ''; + elseif ( empty($_orderby) || 'id' == $_orderby ) + $orderby = 't.term_id'; + + $orderby = apply_filters( 'get_terms_orderby', $orderby, $args ); + + if ( !empty($orderby) ) + $orderby = "ORDER BY $orderby"; + else + $order = ''; + + $where = "tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')"; + $inclusions = ''; + if ( !empty($include) ) { + $exclude = ''; + $exclude_tree = ''; + $interms = wp_parse_id_list($include); + foreach ( $interms as $interm ) { + if ( empty($inclusions) ) + $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' '; + else + $inclusions .= ' OR t.term_id = ' . intval($interm) . ' '; + } + } + + if ( !empty($inclusions) ) + $inclusions .= ')'; + $where .= $inclusions; + + $exclusions = ''; + if ( !empty( $exclude_tree ) ) { + $excluded_trunks = wp_parse_id_list($exclude_tree); + foreach ( $excluded_trunks as $extrunk ) { + $excluded_children = (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids', 'hide_empty' => 0)); + $excluded_children[] = $extrunk; + foreach( $excluded_children as $exterm ) { + if ( empty($exclusions) ) + $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; + else + $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' '; + } + } + } + + if ( !empty($exclude) ) { + $exterms = wp_parse_id_list($exclude); + foreach ( $exterms as $exterm ) { + if ( empty($exclusions) ) + $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; + else + $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' '; + } + } + + if ( !empty($exclusions) ) + $exclusions .= ')'; + $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args ); + $where .= $exclusions; + + if ( !empty($slug) ) { + $slug = sanitize_title($slug); + $where .= " AND t.slug = '$slug'"; + } + + if ( !empty($name__like) ) { + $name__like = like_escape( $name__like ); + $where .= $wpdb->prepare( " AND t.name LIKE %s", $name__like . '%' ); + } + + if ( '' !== $parent ) { + $parent = (int) $parent; + $where .= " AND tt.parent = '$parent'"; + } + + if ( $hide_empty && !$hierarchical ) + $where .= ' AND tt.count > 0'; + + // don't limit the query results when we have to descend the family tree + if ( ! empty($number) && ! $hierarchical && empty( $child_of ) && '' === $parent ) { + if ( $offset ) + $limits = 'LIMIT ' . $offset . ',' . $number; + else + $limits = 'LIMIT ' . $number; + } else { + $limits = ''; + } + + if ( !empty($search) ) { + $search = like_escape($search); + $where .= $wpdb->prepare( " AND (t.name LIKE %s)", '%' . $search . '%'); + } + + $selects = array(); + switch ( $fields ) { + case 'all': + $selects = array('t.*', 'tt.*'); + break; + case 'ids': + case 'id=>parent': + $selects = array('t.term_id', 'tt.parent', 'tt.count'); + break; + case 'names': + $selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name'); + break; + case 'count': + $orderby = ''; + $order = ''; + $selects = array('COUNT(*)'); + } + + $_fields = $fields; + + $fields = implode(', ', apply_filters( 'get_terms_fields', $selects, $args )); + + $join = "INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id"; + + $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits' ); + $clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args ); + foreach ( $pieces as $piece ) + $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; + + $query = "SELECT $fields FROM $wpdb->terms AS t $join WHERE $where $orderby $order $limits"; + + $fields = $_fields; + + if ( 'count' == $fields ) { + $term_count = $wpdb->get_var($query); + return $term_count; + } + + $terms = $wpdb->get_results($query); + if ( 'all' == $fields ) { + update_term_cache($terms); + } + + if ( empty($terms) ) { + wp_cache_add( $cache_key, array(), 'terms', 86400 ); // one day + $terms = apply_filters('get_terms', array(), $taxonomies, $args); + return $terms; + } + + if ( $child_of ) { + $children = _get_term_hierarchy($taxonomies[0]); + if ( ! empty($children) ) + $terms = & _get_term_children($child_of, $terms, $taxonomies[0]); + } + + // Update term counts to include children. + if ( $pad_counts && 'all' == $fields ) + _pad_term_counts($terms, $taxonomies[0]); + + // Make sure we show empty categories that have children. + if ( $hierarchical && $hide_empty && is_array($terms) ) { + foreach ( $terms as $k => $term ) { + if ( ! $term->count ) { + $children = _get_term_children($term->term_id, $terms, $taxonomies[0]); + if ( is_array($children) ) + foreach ( $children as $child ) + if ( $child->count ) + continue 2; + + // It really is empty + unset($terms[$k]); + } + } + } + reset ( $terms ); + + $_terms = array(); + if ( 'id=>parent' == $fields ) { + while ( $term = array_shift($terms) ) + $_terms[$term->term_id] = $term->parent; + $terms = $_terms; + } elseif ( 'ids' == $fields ) { + while ( $term = array_shift($terms) ) + $_terms[] = $term->term_id; + $terms = $_terms; + } elseif ( 'names' == $fields ) { + while ( $term = array_shift($terms) ) + $_terms[] = $term->name; + $terms = $_terms; + } + + if ( 0 < $number && intval(@count($terms)) > $number ) { + $terms = array_slice($terms, $offset, $number); + } + + wp_cache_add( $cache_key, $terms, 'terms', 86400 ); // one day + + $terms = apply_filters('get_terms', $terms, $taxonomies, $args); + return $terms; +} + +/** + * Check if Term exists. + * + * Returns the index of a defined term, or 0 (false) if the term doesn't exist. + * + * Formerly is_term(), introduced in 2.3.0. + * + * @package WordPress + * @subpackage Taxonomy + * @since 3.0.0 + * + * @uses $wpdb + * + * @param int|string $term The term to check + * @param string $taxonomy The taxonomy name to use + * @param int $parent ID of parent term under which to confine the exists search. + * @return mixed Get the term id or Term Object, if exists. + */ +function term_exists($term, $taxonomy = '', $parent = 0) { + global $wpdb; + + $select = "SELECT term_id FROM $wpdb->terms as t WHERE "; + $tax_select = "SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE "; + + if ( is_int($term) ) { + if ( 0 == $term ) + return 0; + $where = 't.term_id = %d'; + if ( !empty($taxonomy) ) + return $wpdb->get_row( $wpdb->prepare( $tax_select . $where . " AND tt.taxonomy = %s", $term, $taxonomy ), ARRAY_A ); + else + return $wpdb->get_var( $wpdb->prepare( $select . $where, $term ) ); + } + + $term = trim( stripslashes( $term ) ); + + if ( '' === $slug = sanitize_title($term) ) + return 0; + + $where = 't.slug = %s'; + $else_where = 't.name = %s'; + $where_fields = array($slug); + $else_where_fields = array($term); + if ( !empty($taxonomy) ) { + $parent = (int) $parent; + if ( $parent > 0 ) { + $where_fields[] = $parent; + $else_where_fields[] = $parent; + $where .= ' AND tt.parent = %d'; + $else_where .= ' AND tt.parent = %d'; + } + + $where_fields[] = $taxonomy; + $else_where_fields[] = $taxonomy; + + if ( $result = $wpdb->get_row( $wpdb->prepare("SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $where AND tt.taxonomy = %s", $where_fields), ARRAY_A) ) + return $result; + + return $wpdb->get_row( $wpdb->prepare("SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $else_where AND tt.taxonomy = %s", $else_where_fields), ARRAY_A); + } + + if ( $result = $wpdb->get_var( $wpdb->prepare("SELECT term_id FROM $wpdb->terms as t WHERE $where", $where_fields) ) ) + return $result; + + return $wpdb->get_var( $wpdb->prepare("SELECT term_id FROM $wpdb->terms as t WHERE $else_where", $else_where_fields) ); +} + +/** + * Sanitize Term all fields. + * + * Relys on sanitize_term_field() to sanitize the term. The difference is that + * this function will sanitize all fields. The context is based + * on sanitize_term_field(). + * + * The $term is expected to be either an array or an object. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses sanitize_term_field Used to sanitize all fields in a term + * + * @param array|object $term The term to check + * @param string $taxonomy The taxonomy name to use + * @param string $context Default is 'display'. + * @return array|object Term with all fields sanitized + */ +function sanitize_term($term, $taxonomy, $context = 'display') { + + if ( 'raw' == $context ) + return $term; + + $fields = array('term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group'); + + $do_object = false; + if ( is_object($term) ) + $do_object = true; + + $term_id = $do_object ? $term->term_id : (isset($term['term_id']) ? $term['term_id'] : 0); + + foreach ( (array) $fields as $field ) { + if ( $do_object ) { + if ( isset($term->$field) ) + $term->$field = sanitize_term_field($field, $term->$field, $term_id, $taxonomy, $context); + } else { + if ( isset($term[$field]) ) + $term[$field] = sanitize_term_field($field, $term[$field], $term_id, $taxonomy, $context); + } + } + + if ( $do_object ) + $term->filter = $context; + else + $term['filter'] = $context; + + return $term; +} + +/** + * Cleanse the field value in the term based on the context. + * + * Passing a term field value through the function should be assumed to have + * cleansed the value for whatever context the term field is going to be used. + * + * If no context or an unsupported context is given, then default filters will + * be applied. + * + * There are enough filters for each context to support a custom filtering + * without creating your own filter function. Simply create a function that + * hooks into the filter you need. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * + * @param string $field Term field to sanitize + * @param string $value Search for this term value + * @param int $term_id Term ID + * @param string $taxonomy Taxonomy Name + * @param string $context Either edit, db, display, attribute, or js. + * @return mixed sanitized field + */ +function sanitize_term_field($field, $value, $term_id, $taxonomy, $context) { + if ( 'parent' == $field || 'term_id' == $field || 'count' == $field || 'term_group' == $field ) { + $value = (int) $value; + if ( $value < 0 ) + $value = 0; + } + + if ( 'raw' == $context ) + return $value; + + if ( 'edit' == $context ) { + $value = apply_filters("edit_term_{$field}", $value, $term_id, $taxonomy); + $value = apply_filters("edit_{$taxonomy}_{$field}", $value, $term_id); + if ( 'description' == $field ) + $value = esc_html($value); // textarea_escaped + else + $value = esc_attr($value); + } else if ( 'db' == $context ) { + $value = apply_filters("pre_term_{$field}", $value, $taxonomy); + $value = apply_filters("pre_{$taxonomy}_{$field}", $value); + // Back compat filters + if ( 'slug' == $field ) + $value = apply_filters('pre_category_nicename', $value); + + } else if ( 'rss' == $context ) { + $value = apply_filters("term_{$field}_rss", $value, $taxonomy); + $value = apply_filters("{$taxonomy}_{$field}_rss", $value); + } else { + // Use display filters by default. + $value = apply_filters("term_{$field}", $value, $term_id, $taxonomy, $context); + $value = apply_filters("{$taxonomy}_{$field}", $value, $term_id, $context); + } + + if ( 'attribute' == $context ) + $value = esc_attr($value); + else if ( 'js' == $context ) + $value = esc_js($value); + + return $value; +} + +/** + * Count how many terms are in Taxonomy. + * + * Default $args is 'hide_empty' which can be 'hide_empty=true' or array('hide_empty' => true). + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses get_terms() + * @uses wp_parse_args() Turns strings into arrays and merges defaults into an array. + * + * @param string $taxonomy Taxonomy name + * @param array|string $args Overwrite defaults. See get_terms() + * @return int How many terms are in $taxonomy + */ +function wp_count_terms( $taxonomy, $args = array() ) { + $defaults = array('hide_empty' => false); + $args = wp_parse_args($args, $defaults); + + // backwards compatibility + if ( isset($args['ignore_empty']) ) { + $args['hide_empty'] = $args['ignore_empty']; + unset($args['ignore_empty']); + } + + $args['fields'] = 'count'; + + return get_terms($taxonomy, $args); +} + +/** + * Will unlink the object from the taxonomy or taxonomies. + * + * Will remove all relationships between the object and any terms in + * a particular taxonomy or taxonomies. Does not remove the term or + * taxonomy itself. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wpdb + * + * @param int $object_id The term Object Id that refers to the term + * @param string|array $taxonomies List of Taxonomy Names or single Taxonomy name. + */ +function wp_delete_object_term_relationships( $object_id, $taxonomies ) { + global $wpdb; + + $object_id = (int) $object_id; + + if ( !is_array($taxonomies) ) + $taxonomies = array($taxonomies); + + foreach ( (array) $taxonomies as $taxonomy ) { + $tt_ids = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'tt_ids')); + $in_tt_ids = "'" . implode("', '", $tt_ids) . "'"; + do_action( 'delete_term_relationships', $object_id, $tt_ids ); + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id) ); + do_action( 'deleted_term_relationships', $object_id, $tt_ids ); + wp_update_term_count($tt_ids, $taxonomy); + } +} + +/** + * Removes a term from the database. + * + * If the term is a parent of other terms, then the children will be updated to + * that term's parent. + * + * The $args 'default' will only override the terms found, if there is only one + * term found. Any other and the found terms are used. + * + * The $args 'force_default' will force the term supplied as default to be + * assigned even if the object was not going to be termless + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * @uses do_action() Calls both 'delete_term' and 'delete_$taxonomy' action + * hooks, passing term object, term id. 'delete_term' gets an additional + * parameter with the $taxonomy parameter. + * + * @param int $term Term ID + * @param string $taxonomy Taxonomy Name + * @param array|string $args Optional. Change 'default' term id and override found term ids. + * @return bool|WP_Error Returns false if not term; true if completes delete action. + */ +function wp_delete_term( $term, $taxonomy, $args = array() ) { + global $wpdb; + + $term = (int) $term; + + if ( ! $ids = term_exists($term, $taxonomy) ) + return false; + if ( is_wp_error( $ids ) ) + return $ids; + + $tt_id = $ids['term_taxonomy_id']; + + $defaults = array(); + + if ( 'category' == $taxonomy ) { + $defaults['default'] = get_option( 'default_category' ); + if ( $defaults['default'] == $term ) + return 0; // Don't delete the default category + } + + $args = wp_parse_args($args, $defaults); + extract($args, EXTR_SKIP); + + if ( isset( $default ) ) { + $default = (int) $default; + if ( ! term_exists($default, $taxonomy) ) + unset($default); + } + + // Update children to point to new parent + if ( is_taxonomy_hierarchical($taxonomy) ) { + $term_obj = get_term($term, $taxonomy); + if ( is_wp_error( $term_obj ) ) + return $term_obj; + $parent = $term_obj->parent; + + $edit_tt_ids = $wpdb->get_col( "SELECT `term_taxonomy_id` FROM $wpdb->term_taxonomy WHERE `parent` = " . (int)$term_obj->term_id ); + do_action( 'edit_term_taxonomies', $edit_tt_ids ); + $wpdb->update( $wpdb->term_taxonomy, compact( 'parent' ), array( 'parent' => $term_obj->term_id) + compact( 'taxonomy' ) ); + do_action( 'edited_term_taxonomies', $edit_tt_ids ); + } + + $objects = $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $tt_id ) ); + + foreach ( (array) $objects as $object ) { + $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none')); + if ( 1 == count($terms) && isset($default) ) { + $terms = array($default); + } else { + $terms = array_diff($terms, array($term)); + if (isset($default) && isset($force_default) && $force_default) + $terms = array_merge($terms, array($default)); + } + $terms = array_map('intval', $terms); + wp_set_object_terms($object, $terms, $taxonomy); + } + + // Clean the relationship caches for all object types using this term + $tax_object = get_taxonomy( $taxonomy ); + foreach ( $tax_object->object_type as $object_type ) + clean_object_term_cache( $objects, $object_type ); + + do_action( 'delete_term_taxonomy', $tt_id ); + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $tt_id ) ); + do_action( 'deleted_term_taxonomy', $tt_id ); + + // Delete the term if no taxonomies use it. + if ( !$wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE term_id = %d", $term) ) ) + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->terms WHERE term_id = %d", $term) ); + + clean_term_cache($term, $taxonomy); + + do_action('delete_term', $term, $tt_id, $taxonomy); + do_action("delete_$taxonomy", $term, $tt_id); + + return true; +} + +/** + * Deletes one existing category. + * + * @since 2.0.0 + * @uses wp_delete_term() + * + * @param int $cat_ID + * @return mixed Returns true if completes delete action; false if term doesnt exist; + * Zero on attempted deletion of default Category; WP_Error object is also a possibility. + */ +function wp_delete_category( $cat_ID ) { + return wp_delete_term( $cat_ID, 'category' ); +} + +/** + * Retrieves the terms associated with the given object(s), in the supplied taxonomies. + * + * The following information has to do the $args parameter and for what can be + * contained in the string or array of that parameter, if it exists. + * + * The first argument is called, 'orderby' and has the default value of 'name'. + * The other value that is supported is 'count'. + * + * The second argument is called, 'order' and has the default value of 'ASC'. + * The only other value that will be acceptable is 'DESC'. + * + * The final argument supported is called, 'fields' and has the default value of + * 'all'. There are multiple other options that can be used instead. Supported + * values are as follows: 'all', 'ids', 'names', and finally + * 'all_with_object_id'. + * + * The fields argument also decides what will be returned. If 'all' or + * 'all_with_object_id' is choosen or the default kept intact, then all matching + * terms objects will be returned. If either 'ids' or 'names' is used, then an + * array of all matching term ids or term names will be returned respectively. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wpdb + * + * @param int|array $object_ids The ID(s) of the object(s) to retrieve. + * @param string|array $taxonomies The taxonomies to retrieve terms from. + * @param array|string $args Change what is returned + * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if $taxonomy does not exist. + */ +function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { + global $wpdb; + + if ( !is_array($taxonomies) ) + $taxonomies = array($taxonomies); + + foreach ( (array) $taxonomies as $taxonomy ) { + if ( ! taxonomy_exists($taxonomy) ) + return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); + } + + if ( !is_array($object_ids) ) + $object_ids = array($object_ids); + $object_ids = array_map('intval', $object_ids); + + $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all'); + $args = wp_parse_args( $args, $defaults ); + + $terms = array(); + if ( count($taxonomies) > 1 ) { + foreach ( $taxonomies as $index => $taxonomy ) { + $t = get_taxonomy($taxonomy); + if ( isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args) ) { + unset($taxonomies[$index]); + $terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args))); + } + } + } else { + $t = get_taxonomy($taxonomies[0]); + if ( isset($t->args) && is_array($t->args) ) + $args = array_merge($args, $t->args); + } + + extract($args, EXTR_SKIP); + + if ( 'count' == $orderby ) + $orderby = 'tt.count'; + else if ( 'name' == $orderby ) + $orderby = 't.name'; + else if ( 'slug' == $orderby ) + $orderby = 't.slug'; + else if ( 'term_group' == $orderby ) + $orderby = 't.term_group'; + else if ( 'term_order' == $orderby ) + $orderby = 'tr.term_order'; + else if ( 'none' == $orderby ) { + $orderby = ''; + $order = ''; + } else { + $orderby = 't.term_id'; + } + + // tt_ids queries can only be none or tr.term_taxonomy_id + if ( ('tt_ids' == $fields) && !empty($orderby) ) + $orderby = 'tr.term_taxonomy_id'; + + if ( !empty($orderby) ) + $orderby = "ORDER BY $orderby"; + + $taxonomies = "'" . implode("', '", $taxonomies) . "'"; + $object_ids = implode(', ', $object_ids); + + $select_this = ''; + if ( 'all' == $fields ) + $select_this = 't.*, tt.*'; + else if ( 'ids' == $fields ) + $select_this = 't.term_id'; + else if ( 'names' == $fields ) + $select_this = 't.name'; + else if ( 'all_with_object_id' == $fields ) + $select_this = 't.*, tt.*, tr.object_id'; + + $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tr.object_id IN ($object_ids) $orderby $order"; + + if ( 'all' == $fields || 'all_with_object_id' == $fields ) { + $terms = array_merge($terms, $wpdb->get_results($query)); + update_term_cache($terms); + } else if ( 'ids' == $fields || 'names' == $fields ) { + $terms = array_merge($terms, $wpdb->get_col($query)); + } else if ( 'tt_ids' == $fields ) { + $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) $orderby $order"); + } + + if ( ! $terms ) + $terms = array(); + + return apply_filters('wp_get_object_terms', $terms, $object_ids, $taxonomies, $args); +} + +/** + * Adds a new term to the database. Optionally marks it as an alias of an existing term. + * + * Error handling is assigned for the nonexistance of the $taxonomy and $term + * parameters before inserting. If both the term id and taxonomy exist + * previously, then an array will be returned that contains the term id and the + * contents of what is returned. The keys of the array are 'term_id' and + * 'term_taxonomy_id' containing numeric values. + * + * It is assumed that the term does not yet exist or the above will apply. The + * term will be first added to the term table and then related to the taxonomy + * if everything is well. If everything is correct, then several actions will be + * run prior to a filter and then several actions will be run after the filter + * is run. + * + * The arguments decide how the term is handled based on the $args parameter. + * The following is a list of the available overrides and the defaults. + * + * 'alias_of'. There is no default, but if added, expected is the slug that the + * term will be an alias of. Expected to be a string. + * + * 'description'. There is no default. If exists, will be added to the database + * along with the term. Expected to be a string. + * + * 'parent'. Expected to be numeric and default is 0 (zero). Will assign value + * of 'parent' to the term. + * + * 'slug'. Expected to be a string. There is no default. + * + * If 'slug' argument exists then the slug will be checked to see if it is not + * a valid term. If that check succeeds (it is not a valid term), then it is + * added and the term id is given. If it fails, then a check is made to whether + * the taxonomy is hierarchical and the parent argument is not empty. If the + * second check succeeds, the term will be inserted and the term id will be + * given. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wpdb + * + * @uses apply_filters() Calls 'pre_insert_term' hook with term and taxonomy as parameters. + * @uses do_action() Calls 'create_term' hook with the term id and taxonomy id as parameters. + * @uses do_action() Calls 'create_$taxonomy' hook with term id and taxonomy id as parameters. + * @uses apply_filters() Calls 'term_id_filter' hook with term id and taxonomy id as parameters. + * @uses do_action() Calls 'created_term' hook with the term id and taxonomy id as parameters. + * @uses do_action() Calls 'created_$taxonomy' hook with term id and taxonomy id as parameters. + * + * @param string $term The term to add or update. + * @param string $taxonomy The taxonomy to which to add the term + * @param array|string $args Change the values of the inserted term + * @return array|WP_Error The Term ID and Term Taxonomy ID + */ +function wp_insert_term( $term, $taxonomy, $args = array() ) { + global $wpdb; + + if ( ! taxonomy_exists($taxonomy) ) + return new WP_Error('invalid_taxonomy', __('Invalid taxonomy')); + + $term = apply_filters( 'pre_insert_term', $term, $taxonomy ); + if ( is_wp_error( $term ) ) + return $term; + + if ( is_int($term) && 0 == $term ) + return new WP_Error('invalid_term_id', __('Invalid term ID')); + + if ( '' == trim($term) ) + return new WP_Error('empty_term_name', __('A name is required for this term')); + + $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); + $args = wp_parse_args($args, $defaults); + $args['name'] = $term; + $args['taxonomy'] = $taxonomy; + $args = sanitize_term($args, $taxonomy, 'db'); + extract($args, EXTR_SKIP); + + // expected_slashed ($name) + $name = stripslashes($name); + $description = stripslashes($description); + + if ( empty($slug) ) + $slug = sanitize_title($name); + + $term_group = 0; + if ( $alias_of ) { + $alias = $wpdb->get_row( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $alias_of) ); + if ( $alias->term_group ) { + // The alias we want is already in a group, so let's use that one. + $term_group = $alias->term_group; + } else { + // The alias isn't in a group, so let's create a new one and firstly add the alias term to it. + $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1; + do_action( 'edit_terms', $alias->term_id ); + $wpdb->update($wpdb->terms, compact('term_group'), array('term_id' => $alias->term_id) ); + do_action( 'edited_terms', $alias->term_id ); + } + } + + if ( $term_id = term_exists($slug) ) { + $existing_term = $wpdb->get_row( $wpdb->prepare( "SELECT name FROM $wpdb->terms WHERE term_id = %d", $term_id), ARRAY_A ); + // We've got an existing term in the same taxonomy, which matches the name of the new term: + if ( is_taxonomy_hierarchical($taxonomy) && $existing_term['name'] == $name && $exists = term_exists( (int) $term_id, $taxonomy ) ) { + // Hierarchical, and it matches an existing term, Do not allow same "name" in the same level. + $siblings = get_terms($taxonomy, array('fields' => 'names', 'get' => 'all', 'parent' => (int)$parent) ); + if ( in_array($name, $siblings) ) { + return new WP_Error('term_exists', __('A term with the name provided already exists with this parent.'), $exists['term_id']); + } else { + $slug = wp_unique_term_slug($slug, (object) $args); + if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) ) + return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error); + $term_id = (int) $wpdb->insert_id; + } + } elseif ( $existing_term['name'] != $name ) { + // We've got an existing term, with a different name, Create the new term. + $slug = wp_unique_term_slug($slug, (object) $args); + if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) ) + return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error); + $term_id = (int) $wpdb->insert_id; + } elseif ( $exists = term_exists( (int) $term_id, $taxonomy ) ) { + // Same name, same slug. + return new WP_Error('term_exists', __('A term with the name provided already exists.'), $exists['term_id']); + } + } else { + // This term does not exist at all in the database, Create it. + $slug = wp_unique_term_slug($slug, (object) $args); + if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) ) + return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error); + $term_id = (int) $wpdb->insert_id; + } + + // Seems unreachable, However, Is used in the case that a term name is provided, which sanitizes to an empty string. + if ( empty($slug) ) { + $slug = sanitize_title($slug, $term_id); + do_action( 'edit_terms', $term_id ); + $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); + do_action( 'edited_terms', $term_id ); + } + + $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id ) ); + + if ( !empty($tt_id) ) + return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); + + $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent') + array( 'count' => 0 ) ); + $tt_id = (int) $wpdb->insert_id; + + do_action("create_term", $term_id, $tt_id, $taxonomy); + do_action("create_$taxonomy", $term_id, $tt_id); + + $term_id = apply_filters('term_id_filter', $term_id, $tt_id); + + clean_term_cache($term_id, $taxonomy); + + do_action("created_term", $term_id, $tt_id, $taxonomy); + do_action("created_$taxonomy", $term_id, $tt_id); + + return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); +} + +/** + * Create Term and Taxonomy Relationships. + * + * Relates an object (post, link etc) to a term and taxonomy type. Creates the + * term and taxonomy relationship if it doesn't already exist. Creates a term if + * it doesn't exist (using the slug). + * + * A relationship means that the term is grouped in or belongs to the taxonomy. + * A term has no meaning until it is given context by defining which taxonomy it + * exists under. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wpdb + * + * @param int $object_id The object to relate to. + * @param array|int|string $terms The slug or id of the term, will replace all existing + * related terms in this taxonomy. + * @param array|string $taxonomy The context in which to relate the term to the object. + * @param bool $append If false will delete difference of terms. + * @return array|WP_Error Affected Term IDs + */ +function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false) { + global $wpdb; + + $object_id = (int) $object_id; + + if ( ! taxonomy_exists($taxonomy) ) + return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); + + if ( !is_array($terms) ) + $terms = array($terms); + + if ( ! $append ) + $old_tt_ids = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'tt_ids', 'orderby' => 'none')); + else + $old_tt_ids = array(); + + $tt_ids = array(); + $term_ids = array(); + + foreach ( (array) $terms as $term) { + if ( !strlen(trim($term)) ) + continue; + + if ( !$term_info = term_exists($term, $taxonomy) ) { + // Skip if a non-existent term ID is passed. + if ( is_int($term) ) + continue; + $term_info = wp_insert_term($term, $taxonomy); + } + if ( is_wp_error($term_info) ) + return $term_info; + $term_ids[] = $term_info['term_id']; + $tt_id = $term_info['term_taxonomy_id']; + $tt_ids[] = $tt_id; + + if ( $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", $object_id, $tt_id ) ) ) + continue; + do_action( 'add_term_relationship', $object_id, $tt_id ); + $wpdb->insert( $wpdb->term_relationships, array( 'object_id' => $object_id, 'term_taxonomy_id' => $tt_id ) ); + do_action( 'added_term_relationship', $object_id, $tt_id ); + } + + wp_update_term_count($tt_ids, $taxonomy); + + if ( ! $append ) { + $delete_terms = array_diff($old_tt_ids, $tt_ids); + if ( $delete_terms ) { + $in_delete_terms = "'" . implode("', '", $delete_terms) . "'"; + do_action( 'delete_term_relationships', $object_id, $delete_terms ); + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_delete_terms)", $object_id) ); + do_action( 'deleted_term_relationships', $object_id, $delete_terms ); + wp_update_term_count($delete_terms, $taxonomy); + } + } + + $t = get_taxonomy($taxonomy); + if ( ! $append && isset($t->sort) && $t->sort ) { + $values = array(); + $term_order = 0; + $final_tt_ids = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'tt_ids')); + foreach ( $tt_ids as $tt_id ) + if ( in_array($tt_id, $final_tt_ids) ) + $values[] = $wpdb->prepare( "(%d, %d, %d)", $object_id, $tt_id, ++$term_order); + if ( $values ) + $wpdb->query("INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . join(',', $values) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)"); + } + + do_action('set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids); + return $tt_ids; +} + +/** + * Will make slug unique, if it isn't already. + * + * The $slug has to be unique global to every taxonomy, meaning that one + * taxonomy term can't have a matching slug with another taxonomy term. Each + * slug has to be globally unique for every taxonomy. + * + * The way this works is that if the taxonomy that the term belongs to is + * hierarchical and has a parent, it will append that parent to the $slug. + * + * If that still doesn't return an unique slug, then it try to append a number + * until it finds a number that is truely unique. + * + * The only purpose for $term is for appending a parent, if one exists. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wpdb + * + * @param string $slug The string that will be tried for a unique slug + * @param object $term The term object that the $slug will belong too + * @return string Will return a true unique slug. + */ +function wp_unique_term_slug($slug, $term) { + global $wpdb; + + if ( ! term_exists( $slug ) ) + return $slug; + + // If the taxonomy supports hierarchy and the term has a parent, make the slug unique + // by incorporating parent slugs. + if ( is_taxonomy_hierarchical($term->taxonomy) && !empty($term->parent) ) { + $the_parent = $term->parent; + while ( ! empty($the_parent) ) { + $parent_term = get_term($the_parent, $term->taxonomy); + if ( is_wp_error($parent_term) || empty($parent_term) ) + break; + $slug .= '-' . $parent_term->slug; + if ( ! term_exists( $slug ) ) + return $slug; + + if ( empty($parent_term->parent) ) + break; + $the_parent = $parent_term->parent; + } + } + + // If we didn't get a unique slug, try appending a number to make it unique. + if ( !empty($args['term_id']) ) + $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $args['term_id'] ); + else + $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug ); + + if ( $wpdb->get_var( $query ) ) { + $num = 2; + do { + $alt_slug = $slug . "-$num"; + $num++; + $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); + } while ( $slug_check ); + $slug = $alt_slug; + } + + return $slug; +} + +/** + * Update term based on arguments provided. + * + * The $args will indiscriminately override all values with the same field name. + * Care must be taken to not override important information need to update or + * update will fail (or perhaps create a new term, neither would be acceptable). + * + * Defaults will set 'alias_of', 'description', 'parent', and 'slug' if not + * defined in $args already. + * + * 'alias_of' will create a term group, if it doesn't already exist, and update + * it for the $term. + * + * If the 'slug' argument in $args is missing, then the 'name' in $args will be + * used. It should also be noted that if you set 'slug' and it isn't unique then + * a WP_Error will be passed back. If you don't pass any slug, then a unique one + * will be created for you. + * + * For what can be overrode in $args, check the term scheme can contain and stay + * away from the term keys. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses $wpdb + * @uses do_action() Will call both 'edit_term' and 'edit_$taxonomy' twice. + * @uses apply_filters() Will call the 'term_id_filter' filter and pass the term + * id and taxonomy id. + * + * @param int $term_id The ID of the term + * @param string $taxonomy The context in which to relate the term to the object. + * @param array|string $args Overwrite term field values + * @return array|WP_Error Returns Term ID and Taxonomy Term ID + */ +function wp_update_term( $term_id, $taxonomy, $args = array() ) { + global $wpdb; + + if ( ! taxonomy_exists($taxonomy) ) + return new WP_Error('invalid_taxonomy', __('Invalid taxonomy')); + + $term_id = (int) $term_id; + + // First, get all of the original args + $term = get_term ($term_id, $taxonomy, ARRAY_A); + + if ( is_wp_error( $term ) ) + return $term; + + // Escape data pulled from DB. + $term = add_magic_quotes($term); + + // Merge old and new args with new args overwriting old ones. + $args = array_merge($term, $args); + + $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); + $args = wp_parse_args($args, $defaults); + $args = sanitize_term($args, $taxonomy, 'db'); + extract($args, EXTR_SKIP); + + // expected_slashed ($name) + $name = stripslashes($name); + $description = stripslashes($description); + + if ( '' == trim($name) ) + return new WP_Error('empty_term_name', __('A name is required for this term')); + + $empty_slug = false; + if ( empty($slug) ) { + $empty_slug = true; + $slug = sanitize_title($name); + } + + if ( $alias_of ) { + $alias = $wpdb->get_row( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $alias_of) ); + if ( $alias->term_group ) { + // The alias we want is already in a group, so let's use that one. + $term_group = $alias->term_group; + } else { + // The alias isn't in a group, so let's create a new one and firstly add the alias term to it. + $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1; + do_action( 'edit_terms', $alias->term_id ); + $wpdb->update( $wpdb->terms, compact('term_group'), array( 'term_id' => $alias->term_id ) ); + do_action( 'edited_terms', $alias->term_id ); + } + } + + // Check $parent to see if it will cause a hierarchy loop + $parent = apply_filters( 'wp_update_term_parent', $parent, $term_id, $taxonomy, compact( array_keys( $args ) ), $args ); + + // Check for duplicate slug + $id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms WHERE slug = %s", $slug ) ); + if ( $id && ($id != $term_id) ) { + // If an empty slug was passed or the parent changed, reset the slug to something unique. + // Otherwise, bail. + if ( $empty_slug || ( $parent != $term['parent']) ) + $slug = wp_unique_term_slug($slug, (object) $args); + else + return new WP_Error('duplicate_term_slug', sprintf(__('The slug “%s” is already in use by another term'), $slug)); + } + do_action( 'edit_terms', $term_id ); + $wpdb->update($wpdb->terms, compact( 'name', 'slug', 'term_group' ), compact( 'term_id' ) ); + if ( empty($slug) ) { + $slug = sanitize_title($name, $term_id); + $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); + } + do_action( 'edited_terms', $term_id ); + + $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id) ); + do_action( 'edit_term_taxonomy', $tt_id, $taxonomy ); + $wpdb->update( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ), array( 'term_taxonomy_id' => $tt_id ) ); + do_action( 'edited_term_taxonomy', $tt_id, $taxonomy ); + + do_action("edit_term", $term_id, $tt_id, $taxonomy); + do_action("edit_$taxonomy", $term_id, $tt_id); + + $term_id = apply_filters('term_id_filter', $term_id, $tt_id); + + clean_term_cache($term_id, $taxonomy); + + do_action("edited_term", $term_id, $tt_id, $taxonomy); + do_action("edited_$taxonomy", $term_id, $tt_id); + + return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); +} + +/** + * Enable or disable term counting. + * + * @since 2.5.0 + * + * @param bool $defer Optional. Enable if true, disable if false. + * @return bool Whether term counting is enabled or disabled. + */ +function wp_defer_term_counting($defer=null) { + static $_defer = false; + + if ( is_bool($defer) ) { + $_defer = $defer; + // flush any deferred counts + if ( !$defer ) + wp_update_term_count( null, null, true ); + } + + return $_defer; +} + +/** + * Updates the amount of terms in taxonomy. + * + * If there is a taxonomy callback applyed, then it will be called for updating + * the count. + * + * The default action is to count what the amount of terms have the relationship + * of term ID. Once that is done, then update the database. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wpdb + * + * @param int|array $terms The term_taxonomy_id of the terms + * @param string $taxonomy The context of the term. + * @return bool If no terms will return false, and if successful will return true. + */ +function wp_update_term_count( $terms, $taxonomy, $do_deferred=false ) { + static $_deferred = array(); + + if ( $do_deferred ) { + foreach ( (array) array_keys($_deferred) as $tax ) { + wp_update_term_count_now( $_deferred[$tax], $tax ); + unset( $_deferred[$tax] ); + } + } + + if ( empty($terms) ) + return false; + + if ( !is_array($terms) ) + $terms = array($terms); + + if ( wp_defer_term_counting() ) { + if ( !isset($_deferred[$taxonomy]) ) + $_deferred[$taxonomy] = array(); + $_deferred[$taxonomy] = array_unique( array_merge($_deferred[$taxonomy], $terms) ); + return true; + } + + return wp_update_term_count_now( $terms, $taxonomy ); +} + +/** + * Perform term count update immediately. + * + * @since 2.5.0 + * + * @param array $terms The term_taxonomy_id of terms to update. + * @param string $taxonomy The context of the term. + * @return bool Always true when complete. + */ +function wp_update_term_count_now( $terms, $taxonomy ) { + global $wpdb; + + $terms = array_map('intval', $terms); + + $taxonomy = get_taxonomy($taxonomy); + if ( !empty($taxonomy->update_count_callback) ) { + call_user_func($taxonomy->update_count_callback, $terms, $taxonomy); + } else { + // Default count updater + foreach ( (array) $terms as $term) { + $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term) ); + do_action( 'edit_term_taxonomy', $term, $taxonomy ); + $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) ); + do_action( 'edited_term_taxonomy', $term, $taxonomy ); + } + + } + + clean_term_cache($terms, '', false); + + return true; +} + +// +// Cache +// + + +/** + * Removes the taxonomy relationship to terms from the cache. + * + * Will remove the entire taxonomy relationship containing term $object_id. The + * term IDs have to exist within the taxonomy $object_type for the deletion to + * take place. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @see get_object_taxonomies() for more on $object_type + * @uses do_action() Will call action hook named, 'clean_object_term_cache' after completion. + * Passes, function params in same order. + * + * @param int|array $object_ids Single or list of term object ID(s) + * @param array|string $object_type The taxonomy object type + */ +function clean_object_term_cache($object_ids, $object_type) { + if ( !is_array($object_ids) ) + $object_ids = array($object_ids); + + foreach ( $object_ids as $id ) + foreach ( get_object_taxonomies($object_type) as $taxonomy ) + wp_cache_delete($id, "{$taxonomy}_relationships"); + + do_action('clean_object_term_cache', $object_ids, $object_type); +} + + +/** + * Will remove all of the term ids from the cache. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses $wpdb + * + * @param int|array $ids Single or list of Term IDs + * @param string $taxonomy Can be empty and will assume tt_ids, else will use for context. + * @param bool $clean_taxonomy Whether to clean taxonomy wide caches (true), or just individual term object caches (false). Default is true. + */ +function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) { + global $wpdb; + static $cleaned = array(); + + if ( !is_array($ids) ) + $ids = array($ids); + + $taxonomies = array(); + // If no taxonomy, assume tt_ids. + if ( empty($taxonomy) ) { + $tt_ids = array_map('intval', $ids); + $tt_ids = implode(', ', $tt_ids); + $terms = $wpdb->get_results("SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)"); + $ids = array(); + foreach ( (array) $terms as $term ) { + $taxonomies[] = $term->taxonomy; + $ids[] = $term->term_id; + wp_cache_delete($term->term_id, $term->taxonomy); + } + $taxonomies = array_unique($taxonomies); + } else { + $taxonomies = array($taxonomy); + foreach ( $taxonomies as $taxonomy ) { + foreach ( $ids as $id ) { + wp_cache_delete($id, $taxonomy); + } + } + } + + foreach ( $taxonomies as $taxonomy ) { + if ( isset($cleaned[$taxonomy]) ) + continue; + $cleaned[$taxonomy] = true; + + if ( $clean_taxonomy ) { + wp_cache_delete('all_ids', $taxonomy); + wp_cache_delete('get', $taxonomy); + delete_option("{$taxonomy}_children"); + // Regenerate {$taxonomy}_children + _get_term_hierarchy($taxonomy); + } + + do_action('clean_term_cache', $ids, $taxonomy); + } + + wp_cache_set('last_changed', time(), 'terms'); +} + + +/** + * Retrieves the taxonomy relationship to the term object id. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @uses wp_cache_get() Retrieves taxonomy relationship from cache + * + * @param int|array $id Term object ID + * @param string $taxonomy Taxonomy Name + * @return bool|array Empty array if $terms found, but not $taxonomy. False if nothing is in cache for $taxonomy and $id. + */ +function &get_object_term_cache($id, $taxonomy) { + $cache = wp_cache_get($id, "{$taxonomy}_relationships"); + return $cache; +} + + +/** + * Updates the cache for Term ID(s). + * + * Will only update the cache for terms not already cached. + * + * The $object_ids expects that the ids be separated by commas, if it is a + * string. + * + * It should be noted that update_object_term_cache() is very time extensive. It + * is advised that the function is not called very often or at least not for a + * lot of terms that exist in a lot of taxonomies. The amount of time increases + * for each term and it also increases for each taxonomy the term belongs to. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * @uses wp_get_object_terms() Used to get terms from the database to update + * + * @param string|array $object_ids Single or list of term object ID(s) + * @param array|string $object_type The taxonomy object type + * @return null|bool Null value is given with empty $object_ids. False if + */ +function update_object_term_cache($object_ids, $object_type) { + if ( empty($object_ids) ) + return; + + if ( !is_array($object_ids) ) + $object_ids = explode(',', $object_ids); + + $object_ids = array_map('intval', $object_ids); + + $taxonomies = get_object_taxonomies($object_type); + + $ids = array(); + foreach ( (array) $object_ids as $id ) { + foreach ( $taxonomies as $taxonomy ) { + if ( false === wp_cache_get($id, "{$taxonomy}_relationships") ) { + $ids[] = $id; + break; + } + } + } + + if ( empty( $ids ) ) + return false; + + $terms = wp_get_object_terms($ids, $taxonomies, array('fields' => 'all_with_object_id')); + + $object_terms = array(); + foreach ( (array) $terms as $term ) + $object_terms[$term->object_id][$term->taxonomy][$term->term_id] = $term; + + foreach ( $ids as $id ) { + foreach ( $taxonomies as $taxonomy ) { + if ( ! isset($object_terms[$id][$taxonomy]) ) { + if ( !isset($object_terms[$id]) ) + $object_terms[$id] = array(); + $object_terms[$id][$taxonomy] = array(); + } + } + } + + foreach ( $object_terms as $id => $value ) { + foreach ( $value as $taxonomy => $terms ) { + wp_cache_set($id, $terms, "{$taxonomy}_relationships"); + } + } +} + + +/** + * Updates Terms to Taxonomy in cache. + * + * @package WordPress + * @subpackage Taxonomy + * @since 2.3.0 + * + * @param array $terms List of Term objects to change + * @param string $taxonomy Optional. Update Term to this taxonomy in cache + */ +function update_term_cache($terms, $taxonomy = '') { + foreach ( (array) $terms as $term ) { + $term_taxonomy = $taxonomy; + if ( empty($term_taxonomy) ) + $term_taxonomy = $term->taxonomy; + + wp_cache_add($term->term_id, $term, $term_taxonomy); + } +} + +// +// Private +// + + +/** + * Retrieves children of taxonomy as Term IDs. + * + * @package WordPress + * @subpackage Taxonomy + * @access private + * @since 2.3.0 + * + * @uses update_option() Stores all of the children in "$taxonomy_children" + * option. That is the name of the taxonomy, immediately followed by '_children'. + * + * @param string $taxonomy Taxonomy Name + * @return array Empty if $taxonomy isn't hierarchical or returns children as Term IDs. + */ +function _get_term_hierarchy($taxonomy) { + if ( !is_taxonomy_hierarchical($taxonomy) ) + return array(); + $children = get_option("{$taxonomy}_children"); + + if ( is_array($children) ) + return $children; + $children = array(); + $terms = get_terms($taxonomy, array('get' => 'all', 'orderby' => 'id', 'fields' => 'id=>parent')); + foreach ( $terms as $term_id => $parent ) { + if ( $parent > 0 ) + $children[$parent][] = $term_id; + } + update_option("{$taxonomy}_children", $children); + + return $children; +} + + +/** + * Get the subset of $terms that are descendants of $term_id. + * + * If $terms is an array of objects, then _get_term_children returns an array of objects. + * If $terms is an array of IDs, then _get_term_children returns an array of IDs. + * + * @package WordPress + * @subpackage Taxonomy + * @access private + * @since 2.3.0 + * + * @param int $term_id The ancestor term: all returned terms should be descendants of $term_id. + * @param array $terms The set of terms---either an array of term objects or term IDs---from which those that are descendants of $term_id will be chosen. + * @param string $taxonomy The taxonomy which determines the hierarchy of the terms. + * @return array The subset of $terms that are descendants of $term_id. + */ +function &_get_term_children($term_id, $terms, $taxonomy) { + $empty_array = array(); + if ( empty($terms) ) + return $empty_array; + + $term_list = array(); + $has_children = _get_term_hierarchy($taxonomy); + + if ( ( 0 != $term_id ) && ! isset($has_children[$term_id]) ) + return $empty_array; + + foreach ( (array) $terms as $term ) { + $use_id = false; + if ( !is_object($term) ) { + $term = get_term($term, $taxonomy); + if ( is_wp_error( $term ) ) + return $term; + $use_id = true; + } + + if ( $term->term_id == $term_id ) + continue; + + if ( $term->parent == $term_id ) { + if ( $use_id ) + $term_list[] = $term->term_id; + else + $term_list[] = $term; + + if ( !isset($has_children[$term->term_id]) ) + continue; + + if ( $children = _get_term_children($term->term_id, $terms, $taxonomy) ) + $term_list = array_merge($term_list, $children); + } + } + + return $term_list; +} + + +/** + * Add count of children to parent count. + * + * Recalculates term counts by including items from child terms. Assumes all + * relevant children are already in the $terms argument. + * + * @package WordPress + * @subpackage Taxonomy + * @access private + * @since 2.3.0 + * @uses $wpdb + * + * @param array $terms List of Term IDs + * @param string $taxonomy Term Context + * @return null Will break from function if conditions are not met. + */ +function _pad_term_counts(&$terms, $taxonomy) { + global $wpdb; + + // This function only works for hierarchical taxonomies like post categories. + if ( !is_taxonomy_hierarchical( $taxonomy ) ) + return; + + $term_hier = _get_term_hierarchy($taxonomy); + + if ( empty($term_hier) ) + return; + + $term_items = array(); + + foreach ( (array) $terms as $key => $term ) { + $terms_by_id[$term->term_id] = & $terms[$key]; + $term_ids[$term->term_taxonomy_id] = $term->term_id; + } + + // Get the object and term ids and stick them in a lookup table + $tax_obj = get_taxonomy($taxonomy); + $object_types = esc_sql($tax_obj->object_type); + $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (" . implode(',', array_keys($term_ids)) . ") AND post_type IN ('" . implode("', '", $object_types) . "') AND post_status = 'publish'"); + foreach ( $results as $row ) { + $id = $term_ids[$row->term_taxonomy_id]; + $term_items[$id][$row->object_id] = isset($term_items[$id][$row->object_id]) ? ++$term_items[$id][$row->object_id] : 1; + } + + // Touch every ancestor's lookup row for each post in each term + foreach ( $term_ids as $term_id ) { + $child = $term_id; + while ( $parent = $terms_by_id[$child]->parent ) { + if ( !empty($term_items[$term_id]) ) + foreach ( $term_items[$term_id] as $item_id => $touches ) { + $term_items[$parent][$item_id] = isset($term_items[$parent][$item_id]) ? ++$term_items[$parent][$item_id]: 1; + } + $child = $parent; + } + } + + // Transfer the touched cells + foreach ( (array) $term_items as $id => $items ) + if ( isset($terms_by_id[$id]) ) + $terms_by_id[$id]->count = count($items); +} + +// +// Default callbacks +// + +/** + * Will update term count based on object types of the current taxonomy. + * + * Private function for the default callback for post_tag and category + * taxonomies. + * + * @package WordPress + * @subpackage Taxonomy + * @access private + * @since 2.3.0 + * @uses $wpdb + * + * @param array $terms List of Term taxonomy IDs + * @param object $taxonomy Current taxonomy object of terms + */ +function _update_post_term_count( $terms, $taxonomy ) { + global $wpdb; + + $object_types = is_array($taxonomy->object_type) ? $taxonomy->object_type : array($taxonomy->object_type); + $object_types = esc_sql($object_types); + + foreach ( (array) $terms as $term ) { + $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('" . implode("', '", $object_types) . "') AND term_taxonomy_id = %d", $term ) ); + do_action( 'edit_term_taxonomy', $term, $taxonomy ); + $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) ); + do_action( 'edited_term_taxonomy', $term, $taxonomy ); + } +} + + +/** + * Generates a permalink for a taxonomy term archive. + * + * @since 2.5.0 + * + * @uses apply_filters() Calls 'term_link' with term link and term object, and taxonomy parameters. + * @uses apply_filters() For the post_tag Taxonomy, Calls 'tag_link' with tag link and tag ID as parameters. + * @uses apply_filters() For the category Taxonomy, Calls 'category_link' filter on category link and category ID. + * + * @param object|int|string $term + * @param string $taxonomy (optional if $term is object) + * @return string|WP_Error HTML link to taxonomy term archive on success, WP_Error if term does not exist. + */ +function get_term_link( $term, $taxonomy = '') { + global $wp_rewrite; + + if ( !is_object($term) ) { + if ( is_int($term) ) { + $term = &get_term($term, $taxonomy); + } else { + $term = &get_term_by('slug', $term, $taxonomy); + } + } + + if ( !is_object($term) ) + $term = new WP_Error('invalid_term', __('Empty Term')); + + if ( is_wp_error( $term ) ) + return $term; + + $taxonomy = $term->taxonomy; + + $termlink = $wp_rewrite->get_extra_permastruct($taxonomy); + + $slug = $term->slug; + $t = get_taxonomy($taxonomy); + + if ( empty($termlink) ) { + if ( 'category' == $taxonomy ) + $termlink = '?cat=' . $term->term_id; + elseif ( $t->query_var ) + $termlink = "?$t->query_var=$slug"; + else + $termlink = "?taxonomy=$taxonomy&term=$slug"; + $termlink = home_url($termlink); + } else { + if ( $t->rewrite['hierarchical'] ) { + $hierarchical_slugs = array(); + $ancestors = get_ancestors($term->term_id, $taxonomy); + foreach ( (array)$ancestors as $ancestor ) { + $ancestor_term = get_term($ancestor, $taxonomy); + $hierarchical_slugs[] = $ancestor_term->slug; + } + $hierarchical_slugs = array_reverse($hierarchical_slugs); + $hierarchical_slugs[] = $slug; + $termlink = str_replace("%$taxonomy%", implode('/', $hierarchical_slugs), $termlink); + } else { + $termlink = str_replace("%$taxonomy%", $slug, $termlink); + } + $termlink = home_url( user_trailingslashit($termlink, 'category') ); + } + // Back Compat filters. + if ( 'post_tag' == $taxonomy ) + $termlink = apply_filters( 'tag_link', $termlink, $term->term_id ); + elseif ( 'category' == $taxonomy ) + $termlink = apply_filters( 'category_link', $termlink, $term->term_id ); + + return apply_filters('term_link', $termlink, $term, $taxonomy); +} + +/** + * Display the taxonomies of a post with available options. + * + * This function can be used within the loop to display the taxonomies for a + * post without specifying the Post ID. You can also use it outside the Loop to + * display the taxonomies for a specific post. + * + * The available defaults are: + * 'post' : default is 0. The post ID to get taxonomies of. + * 'before' : default is empty string. Display before taxonomies list. + * 'sep' : default is empty string. Separate every taxonomy with value in this. + * 'after' : default is empty string. Display this after the taxonomies list. + * 'template' : The template to use for displaying the taxonomy terms. + * + * @since 2.5.0 + * @uses get_the_taxonomies() + * + * @param array $args Override the defaults. + */ +function the_taxonomies($args = array()) { + $defaults = array( + 'post' => 0, + 'before' => '', + 'sep' => ' ', + 'after' => '', + 'template' => '%s: %l.' + ); + + $r = wp_parse_args( $args, $defaults ); + extract( $r, EXTR_SKIP ); + + echo $before . join($sep, get_the_taxonomies($post, $r)) . $after; +} + +/** + * Retrieve all taxonomies associated with a post. + * + * This function can be used within the loop. It will also return an array of + * the taxonomies with links to the taxonomy and name. + * + * @since 2.5.0 + * + * @param int $post Optional. Post ID or will use Global Post ID (in loop). + * @param array $args Override the defaults. + * @return array + */ +function get_the_taxonomies($post = 0, $args = array() ) { + if ( is_int($post) ) + $post =& get_post($post); + elseif ( !is_object($post) ) + $post =& $GLOBALS['post']; + + $args = wp_parse_args( $args, array( + 'template' => '%s: %l.', + ) ); + extract( $args, EXTR_SKIP ); + + $taxonomies = array(); + + if ( !$post ) + return $taxonomies; + + foreach ( get_object_taxonomies($post) as $taxonomy ) { + $t = (array) get_taxonomy($taxonomy); + if ( empty($t['label']) ) + $t['label'] = $taxonomy; + if ( empty($t['args']) ) + $t['args'] = array(); + if ( empty($t['template']) ) + $t['template'] = $template; + + $terms = get_object_term_cache($post->ID, $taxonomy); + if ( empty($terms) ) + $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']); + + $links = array(); + + foreach ( $terms as $term ) + $links[] = "$term->name"; + + if ( $links ) + $taxonomies[$taxonomy] = wp_sprintf($t['template'], $t['label'], $links, $terms); + } + return $taxonomies; +} + +/** + * Retrieve all taxonomies of a post with just the names. + * + * @since 2.5.0 + * @uses get_object_taxonomies() + * + * @param int $post Optional. Post ID + * @return array + */ +function get_post_taxonomies($post = 0) { + $post =& get_post($post); + + return get_object_taxonomies($post); +} + +/** + * Determine if the given object is associated with any of the given terms. + * + * The given terms are checked against the object's terms' term_ids, names and slugs. + * Terms given as integers will only be checked against the object's terms' term_ids. + * If no terms are given, determines if object is associated with any terms in the given taxonomy. + * + * @since 2.7.0 + * @uses get_object_term_cache() + * @uses wp_get_object_terms() + * + * @param int $object_id ID of the object (post ID, link ID, ...) + * @param string $taxonomy Single taxonomy name + * @param int|string|array $terms Optional. Term term_id, name, slug or array of said + * @return bool|WP_Error. WP_Error on input error. + */ +function is_object_in_term( $object_id, $taxonomy, $terms = null ) { + if ( !$object_id = (int) $object_id ) + return new WP_Error( 'invalid_object', __( 'Invalid object ID' ) ); + + $object_terms = get_object_term_cache( $object_id, $taxonomy ); + if ( empty( $object_terms ) ) + $object_terms = wp_get_object_terms( $object_id, $taxonomy ); + + if ( is_wp_error( $object_terms ) ) + return $object_terms; + if ( empty( $object_terms ) ) + return false; + if ( empty( $terms ) ) + return ( !empty( $object_terms ) ); + + $terms = (array) $terms; + + if ( $ints = array_filter( $terms, 'is_int' ) ) + $strs = array_diff( $terms, $ints ); + else + $strs =& $terms; + + foreach ( $object_terms as $object_term ) { + if ( $ints && in_array( $object_term->term_id, $ints ) ) return true; // If int, check against term_id + if ( $strs ) { + if ( in_array( $object_term->term_id, $strs ) ) return true; + if ( in_array( $object_term->name, $strs ) ) return true; + if ( in_array( $object_term->slug, $strs ) ) return true; + } + } + + return false; +} + +/** + * Determine if the given object type is associated with the given taxonomy. + * + * @since 3.0.0 + * @uses get_object_taxonomies() + * + * @param string $object_type Object type string + * @param string $taxonomy Single taxonomy name + * @return bool True if object is associated with the taxonomy, otherwise false. + */ +function is_object_in_taxonomy($object_type, $taxonomy) { + $taxonomies = get_object_taxonomies($object_type); + + if ( empty($taxonomies) ) + return false; + + if ( in_array($taxonomy, $taxonomies) ) + return true; + + return false; +} + +/** + * Get an array of ancestor IDs for a given object. + * + * @param int $object_id The ID of the object + * @param string $object_type The type of object for which we'll be retrieving ancestors. + * @return array of ancestors from lowest to highest in the hierarchy. + */ +function get_ancestors($object_id = 0, $object_type = '') { + $object_id = (int) $object_id; + + $ancestors = array(); + + if ( empty( $object_id ) ) { + return apply_filters('get_ancestors', $ancestors, $object_id, $object_type); + } + + if ( is_taxonomy_hierarchical( $object_type ) ) { + $term = get_term($object_id, $object_type); + while ( ! is_wp_error($term) && ! empty( $term->parent ) && ! in_array( $term->parent, $ancestors ) ) { + $ancestors[] = (int) $term->parent; + $term = get_term($term->parent, $object_type); + } + } elseif ( null !== get_post_type_object( $object_type ) ) { + $object = get_post($object_id); + if ( ! is_wp_error( $object ) && isset( $object->ancestors ) && is_array( $object->ancestors ) ) + $ancestors = $object->ancestors; + else { + while ( ! is_wp_error($object) && ! empty( $object->post_parent ) && ! in_array( $object->post_parent, $ancestors ) ) { + $ancestors[] = (int) $object->post_parent; + $object = get_post($object->post_parent); + } + } + } + + return apply_filters('get_ancestors', $ancestors, $object_id, $object_type); +} + +/** + * Returns the term's parent's term_ID + * + * @since 3.1.0 + * + * @param int $term_id + * @param string $taxonomy + * + * @return int|bool false on error + */ +function wp_get_term_taxonomy_parent_id( $term_id, $taxonomy ) { + $term = get_term( $term_id, $taxonomy ); + if ( !$term || is_wp_error( $term ) ) + return false; + return (int) $term->parent; +} + +/** + * Checks the given subset of the term hierarchy for hierarchy loops. + * Prevents loops from forming and breaks those that it finds. + * + * Attached to the wp_update_term_parent filter. + * + * @since 3.1.0 + * @uses wp_find_hierarchy_loop() + * + * @param int $parent term_id of the parent for the term we're checking. + * @param int $term_id The term we're checking. + * @param string $taxonomy The taxonomy of the term we're checking. + * + * @return int The new parent for the term. + */ +function wp_check_term_hierarchy_for_loops( $parent, $term_id, $taxonomy ) { + // Nothing fancy here - bail + if ( !$parent ) + return 0; + + // Can't be its own parent + if ( $parent == $term_id ) + return 0; + + // Now look for larger loops + + if ( !$loop = wp_find_hierarchy_loop( 'wp_get_term_taxonomy_parent_id', $term_id, $parent, array( $taxonomy ) ) ) + return $parent; // No loop + + // Setting $parent to the given value causes a loop + if ( isset( $loop[$term_id] ) ) + return 0; + + // There's a loop, but it doesn't contain $term_id. Break the loop. + foreach ( array_keys( $loop ) as $loop_member ) + wp_update_term( $loop_member, $taxonomy, array( 'parent' => 0 ) ); + + return $parent; +} diff --git a/src/wp-includes/template-loader.php b/src/wp-includes/template-loader.php new file mode 100644 index 00000000..7c72a05e --- /dev/null +++ b/src/wp-includes/template-loader.php @@ -0,0 +1,47 @@ + diff --git a/src/wp-includes/theme-compat/comments-popup.php b/src/wp-includes/theme-compat/comments-popup.php new file mode 100644 index 00000000..12ad736e --- /dev/null +++ b/src/wp-includes/theme-compat/comments-popup.php @@ -0,0 +1,129 @@ + + + + <?php printf(__('%1$s - Comments on %2$s'), get_option('blogname'), the_title('','',false)); ?> + + + + + + + +

    + + +

    + +

    RSS feed for comments on this post.'); ?>

    + + +

    URL to TrackBack this entry is: %s'), get_trackback_url()); ?>

    + + + + + +
      + +
    1. + +

      %4$s'), get_comment_author_link(), get_comment_date(), get_comment_ID(), get_comment_time()); ?>

      +
    2. + + +
    + +

    + + + +

    +

    HTML allowed: %s'), allowed_tags()); ?>

    + +
    + +

    %2$s. Log out »'), get_option('siteurl') . '/wp-admin/profile.php', $user_identity, wp_logout_url(get_permalink())); ?>

    + +

    + + +

    + +

    + + +

    + +

    + + +

    + + +

    + +
    + +

    + +

    + + " /> + +

    + ID); ?> +
    + +

    + + +
    + + +

    + + + +

    WordPress'), 'http://wordpress.org/'); ?>

    + + + + diff --git a/src/wp-includes/theme-compat/comments.php b/src/wp-includes/theme-compat/comments.php new file mode 100644 index 00000000..c6fbb7fc --- /dev/null +++ b/src/wp-includes/theme-compat/comments.php @@ -0,0 +1,102 @@ + +

    + + + + + +

    + + + +
      + +
    + + + + + + + + + +

    + + + + + + + +
    + +

    + +
    + +
    + + +

    logged in to post a comment.'), wp_login_url( get_permalink() )); ?>

    + + +
    + + + +

    %2$s.'), get_option('siteurl') . '/wp-admin/profile.php', $user_identity); ?>

    + + + +

    /> +

    + +

    /> +

    + +

    +

    + + + + + +

    + +

    + +

    +ID); ?> + +
    + + +
    + + diff --git a/src/wp-includes/theme-compat/footer.php b/src/wp-includes/theme-compat/footer.php new file mode 100644 index 00000000..0e987ede --- /dev/null +++ b/src/wp-includes/theme-compat/footer.php @@ -0,0 +1,30 @@ + + +
    + +
    + + + + + + + diff --git a/src/wp-includes/theme-compat/header.php b/src/wp-includes/theme-compat/header.php new file mode 100644 index 00000000..7abaa02f --- /dev/null +++ b/src/wp-includes/theme-compat/header.php @@ -0,0 +1,50 @@ + + +> + + + + +<?php wp_title('«', true, 'right'); ?> <?php bloginfo('name'); ?> + + + + + + + + + + +> +
    + + + +
    diff --git a/src/wp-includes/theme-compat/sidebar.php b/src/wp-includes/theme-compat/sidebar.php new file mode 100644 index 00000000..9c8cf5b2 --- /dev/null +++ b/src/wp-includes/theme-compat/sidebar.php @@ -0,0 +1,84 @@ + + + diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php new file mode 100644 index 00000000..14176ac7 --- /dev/null +++ b/src/wp-includes/theme.php @@ -0,0 +1,1882 @@ +text_direction) && file_exists("$dir/{$wp_locale->text_direction}.css") ) + $stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css"; + else + $stylesheet_uri = ''; + return apply_filters('locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri); +} + +/** + * Retrieve name of the current theme. + * + * @since 1.5.0 + * @uses apply_filters() Calls 'template' filter on template option. + * + * @return string Template name. + */ +function get_template() { + return apply_filters('template', get_option('template')); +} + +/** + * Retrieve current theme directory. + * + * @since 1.5.0 + * @uses apply_filters() Calls 'template_directory' filter on template directory path and template name. + * + * @return string Template directory path. + */ +function get_template_directory() { + $template = get_template(); + $theme_root = get_theme_root( $template ); + $template_dir = "$theme_root/$template"; + + return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); +} + +/** + * Retrieve theme directory URI. + * + * @since 1.5.0 + * @uses apply_filters() Calls 'template_directory_uri' filter on template directory URI path and template name. + * + * @return string Template directory URI. + */ +function get_template_directory_uri() { + $template = get_template(); + $theme_root_uri = get_theme_root_uri( $template ); + $template_dir_uri = "$theme_root_uri/$template"; + + return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); +} + +/** + * Retrieve theme data from parsed theme file. + * + * The description will have the tags filtered with the following HTML elements + * whitelisted. The 'a' element with the href and title + * attributes. The abbr element with the title attribute. The + * acronym element with the title attribute allowed. The + * code, em, and strong elements also allowed. + * + * The style.css file must contain theme name, theme URI, and description. The + * data can also contain author URI, author, template (parent template), + * version, status, and finally tags. Some of these are not used by WordPress + * administration panels, but are used by theme directory web sites which list + * the theme. + * + * @since 1.5.0 + * + * @param string $theme_file Theme file path. + * @return array Theme data. + */ +function get_theme_data( $theme_file ) { + $default_headers = array( + 'Name' => 'Theme Name', + 'URI' => 'Theme URI', + 'Description' => 'Description', + 'Author' => 'Author', + 'AuthorURI' => 'Author URI', + 'Version' => 'Version', + 'Template' => 'Template', + 'Status' => 'Status', + 'Tags' => 'Tags' + ); + + $themes_allowed_tags = array( + 'a' => array( + 'href' => array(),'title' => array() + ), + 'abbr' => array( + 'title' => array() + ), + 'acronym' => array( + 'title' => array() + ), + 'code' => array(), + 'em' => array(), + 'strong' => array() + ); + + $theme_data = get_file_data( $theme_file, $default_headers, 'theme' ); + + $theme_data['Name'] = $theme_data['Title'] = wp_kses( $theme_data['Name'], $themes_allowed_tags ); + + $theme_data['URI'] = esc_url( $theme_data['URI'] ); + + $theme_data['Description'] = wptexturize( wp_kses( $theme_data['Description'], $themes_allowed_tags ) ); + + $theme_data['AuthorURI'] = esc_url( $theme_data['AuthorURI'] ); + + $theme_data['Template'] = wp_kses( $theme_data['Template'], $themes_allowed_tags ); + + $theme_data['Version'] = wp_kses( $theme_data['Version'], $themes_allowed_tags ); + + if ( $theme_data['Status'] == '' ) + $theme_data['Status'] = 'publish'; + else + $theme_data['Status'] = wp_kses( $theme_data['Status'], $themes_allowed_tags ); + + if ( $theme_data['Tags'] == '' ) + $theme_data['Tags'] = array(); + else + $theme_data['Tags'] = array_map( 'trim', explode( ',', wp_kses( $theme_data['Tags'], array() ) ) ); + + if ( $theme_data['Author'] == '' ) { + $theme_data['Author'] = $theme_data['AuthorName'] = __('Anonymous'); + } else { + $theme_data['AuthorName'] = wp_kses( $theme_data['Author'], $themes_allowed_tags ); + if ( empty( $theme_data['AuthorURI'] ) ) { + $theme_data['Author'] = $theme_data['AuthorName']; + } else { + $theme_data['Author'] = sprintf( '%3$s', $theme_data['AuthorURI'], esc_attr__( 'Visit author homepage' ), $theme_data['AuthorName'] ); + } + } + + return $theme_data; +} + +/** + * Retrieve list of themes with theme data in theme directory. + * + * The theme is broken, if it doesn't have a parent theme and is missing either + * style.css and, or index.php. If the theme has a parent theme then it is + * broken, if it is missing style.css; index.php is optional. The broken theme + * list is saved in the {@link $wp_broken_themes} global, which is displayed on + * the theme list in the administration panels. + * + * @since 1.5.0 + * @global array $wp_broken_themes Stores the broken themes. + * @global array $wp_themes Stores the working themes. + * + * @return array Theme list with theme data. + */ +function get_themes() { + global $wp_themes, $wp_broken_themes; + + if ( isset($wp_themes) ) + return $wp_themes; + + if ( !$theme_files = search_theme_directories() ) + return false; + + asort( $theme_files ); + + $wp_themes = array(); + + foreach ( (array) $theme_files as $theme_file ) { + $theme_root = $theme_file['theme_root']; + $theme_file = $theme_file['theme_file']; + + if ( !is_readable("$theme_root/$theme_file") ) { + $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.')); + continue; + } + + $theme_data = get_theme_data("$theme_root/$theme_file"); + + $name = $theme_data['Name']; + $title = $theme_data['Title']; + $description = wptexturize($theme_data['Description']); + $version = $theme_data['Version']; + $author = $theme_data['Author']; + $template = $theme_data['Template']; + $stylesheet = dirname($theme_file); + + $screenshot = false; + foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) { + if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) { + $screenshot = "screenshot.$ext"; + break; + } + } + + if ( empty($name) ) { + $name = dirname($theme_file); + $title = $name; + } + + $parent_template = $template; + + if ( empty($template) ) { + if ( file_exists("$theme_root/$stylesheet/index.php") ) + $template = $stylesheet; + else + continue; + } + + $template = trim( $template ); + + if ( !file_exists("$theme_root/$template/index.php") ) { + $parent_dir = dirname(dirname($theme_file)); + if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) { + $template = "$parent_dir/$template"; + $template_directory = "$theme_root/$template"; + } else { + /** + * The parent theme doesn't exist in the current theme's folder or sub folder + * so lets use the theme root for the parent template. + */ + if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) { + $template_directory = $theme_files[$template]['theme_root'] . "/$template"; + } else { + if ( empty( $parent_template) ) + $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'), 'error' => 'no_template'); + else + $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => sprintf( __('The parent theme is missing. Please install the "%s" parent theme.'), $parent_template ), 'error' => 'no_parent', 'parent' => $parent_template ); + continue; + } + + } + } else { + $template_directory = trim( $theme_root . '/' . $template ); + } + + $stylesheet_files = array(); + $template_files = array(); + + $stylesheet_dir = @ dir("$theme_root/$stylesheet"); + if ( $stylesheet_dir ) { + while ( ($file = $stylesheet_dir->read()) !== false ) { + if ( !preg_match('|^\.+$|', $file) ) { + if ( preg_match('|\.css$|', $file) ) + $stylesheet_files[] = "$theme_root/$stylesheet/$file"; + elseif ( preg_match('|\.php$|', $file) ) + $template_files[] = "$theme_root/$stylesheet/$file"; + } + } + @ $stylesheet_dir->close(); + } + + $template_dir = @ dir("$template_directory"); + if ( $template_dir ) { + while ( ($file = $template_dir->read()) !== false ) { + if ( preg_match('|^\.+$|', $file) ) + continue; + if ( preg_match('|\.php$|', $file) ) { + $template_files[] = "$template_directory/$file"; + } elseif ( is_dir("$template_directory/$file") ) { + $template_subdir = @ dir("$template_directory/$file"); + if ( !$template_subdir ) + continue; + while ( ($subfile = $template_subdir->read()) !== false ) { + if ( preg_match('|^\.+$|', $subfile) ) + continue; + if ( preg_match('|\.php$|', $subfile) ) + $template_files[] = "$template_directory/$file/$subfile"; + } + @ $template_subdir->close(); + } + } + @ $template_dir->close(); + } + + //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes + $template_files = array_unique($template_files); + $stylesheet_files = array_unique($stylesheet_files); + + $template_dir = $template_directory; + $stylesheet_dir = $theme_root . '/' . $stylesheet; + + if ( empty($template_dir) ) + $template_dir = '/'; + if ( empty($stylesheet_dir) ) + $stylesheet_dir = '/'; + + // Check for theme name collision. This occurs if a theme is copied to + // a new theme directory and the theme header is not updated. Whichever + // theme is first keeps the name. Subsequent themes get a suffix applied. + // The Twenty Ten, Default and Classic themes always trump their pretenders. + if ( isset($wp_themes[$name]) ) { + $trump_cards = array( + 'classic' => 'WordPress Classic', + 'default' => 'WordPress Default', + 'twentyten' => 'Twenty Ten', + ); + if ( isset( $trump_cards[ $stylesheet ] ) && $name == $trump_cards[ $stylesheet ] ) { + // If another theme has claimed to be one of our default themes, move + // them aside. + $suffix = $wp_themes[$name]['Stylesheet']; + $new_name = "$name/$suffix"; + $wp_themes[$new_name] = $wp_themes[$name]; + $wp_themes[$new_name]['Name'] = $new_name; + } else { + $name = "$name/$stylesheet"; + } + } + + $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root ); + $wp_themes[$name] = array( + 'Name' => $name, + 'Title' => $title, + 'Description' => $description, + 'Author' => $author, + 'Author Name' => $theme_data['AuthorName'], + 'Author URI' => $theme_data['AuthorURI'], + 'Version' => $version, + 'Template' => $template, + 'Stylesheet' => $stylesheet, + 'Template Files' => $template_files, + 'Stylesheet Files' => $stylesheet_files, + 'Template Dir' => $template_dir, + 'Stylesheet Dir' => $stylesheet_dir, + 'Status' => $theme_data['Status'], + 'Screenshot' => $screenshot, + 'Tags' => $theme_data['Tags'], + 'Theme Root' => $theme_root, + 'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ), + ); + } + + unset($theme_files); + + /* Store theme roots in the DB */ + if ( get_site_transient( 'theme_roots' ) != $theme_roots ) + set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours + unset($theme_roots); + + /* Resolve theme dependencies. */ + $theme_names = array_keys( $wp_themes ); + foreach ( (array) $theme_names as $theme_name ) { + $wp_themes[$theme_name]['Parent Theme'] = ''; + if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) { + foreach ( (array) $theme_names as $parent_theme_name ) { + if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) { + $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name']; + break; + } + } + } + } + + return $wp_themes; +} + +/** + * Retrieve theme roots. + * + * @since 2.9.0 + * + * @return array|string An arry of theme roots keyed by template/stylesheet or a single theme root if all themes have the same root. + */ +function get_theme_roots() { + global $wp_theme_directories; + + if ( count($wp_theme_directories) <= 1 ) + return '/themes'; + + $theme_roots = get_site_transient( 'theme_roots' ); + if ( false === $theme_roots ) { + get_themes(); + $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme() + } + return $theme_roots; +} + +/** + * Retrieve theme data. + * + * @since 1.5.0 + * + * @param string $theme Theme name. + * @return array|null Null, if theme name does not exist. Theme data, if exists. + */ +function get_theme($theme) { + $themes = get_themes(); + + if ( array_key_exists($theme, $themes) ) + return $themes[$theme]; + + return null; +} + +/** + * Retrieve current theme display name. + * + * If the 'current_theme' option has already been set, then it will be returned + * instead. If it is not set, then each theme will be iterated over until both + * the current stylesheet and current template name. + * + * @since 1.5.0 + * + * @return string + */ +function get_current_theme() { + if ( $theme = get_option('current_theme') ) + return $theme; + + $themes = get_themes(); + $theme_names = array_keys($themes); + $current_template = get_option('template'); + $current_stylesheet = get_option('stylesheet'); + $current_theme = 'Twenty Ten'; + + if ( $themes ) { + foreach ( (array) $theme_names as $theme_name ) { + if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet && + $themes[$theme_name]['Template'] == $current_template ) { + $current_theme = $themes[$theme_name]['Name']; + break; + } + } + } + + update_option('current_theme', $current_theme); + + return $current_theme; +} + +/** + * Register a directory that contains themes. + * + * @since 2.9.0 + * + * @param string $directory Either the full filesystem path to a theme folder or a folder within WP_CONTENT_DIR + * @return bool + */ +function register_theme_directory( $directory) { + global $wp_theme_directories; + + /* If this folder does not exist, return and do not register */ + if ( !file_exists( $directory ) ) + /* Try prepending as the theme directory could be relative to the content directory */ + $registered_directory = WP_CONTENT_DIR . '/' . $directory; + else + $registered_directory = $directory; + + /* If this folder does not exist, return and do not register */ + if ( !file_exists( $registered_directory ) ) + return false; + + $wp_theme_directories[] = $registered_directory; + + return true; +} + +/** + * Search all registered theme directories for complete and valid themes. + * + * @since 2.9.0 + * + * @return array Valid themes found + */ +function search_theme_directories() { + global $wp_theme_directories, $wp_broken_themes; + if ( empty( $wp_theme_directories ) ) + return false; + + $theme_files = array(); + $wp_broken_themes = array(); + + /* Loop the registered theme directories and extract all themes */ + foreach ( (array) $wp_theme_directories as $theme_root ) { + $theme_loc = $theme_root; + + /* We don't want to replace all forward slashes, see Trac #4541 */ + if ( '/' != WP_CONTENT_DIR ) + $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); + + /* Files in the root of the current theme directory and one subdir down */ + $themes_dir = @ opendir($theme_root); + + if ( !$themes_dir ) + return false; + + while ( ($theme_dir = readdir($themes_dir)) !== false ) { + if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { + if ( $theme_dir[0] == '.' || $theme_dir == 'CVS' ) + continue; + + $stylish_dir = @opendir($theme_root . '/' . $theme_dir); + $found_stylesheet = false; + + while ( ($theme_file = readdir($stylish_dir)) !== false ) { + if ( $theme_file == 'style.css' ) { + $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); + $found_stylesheet = true; + break; + } + } + @closedir($stylish_dir); + + if ( !$found_stylesheet ) { // look for themes in that dir + $subdir = "$theme_root/$theme_dir"; + $subdir_name = $theme_dir; + $theme_subdirs = @opendir( $subdir ); + + $found_subdir_themes = false; + while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { + if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { + if ( $theme_subdir[0] == '.' || $theme_subdir == 'CVS' ) + continue; + + $stylish_dir = @opendir($subdir . '/' . $theme_subdir); + $found_stylesheet = false; + + while ( ($theme_file = readdir($stylish_dir)) !== false ) { + if ( $theme_file == 'style.css' ) { + $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); + $found_stylesheet = true; + $found_subdir_themes = true; + break; + } + } + @closedir($stylish_dir); + } + } + @closedir($theme_subdirs); + if ( !$found_subdir_themes ) + $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); + } + } + } + @closedir( $themes_dir ); + } + return $theme_files; +} + +/** + * Retrieve path to themes directory. + * + * Does not have trailing slash. + * + * @since 1.5.0 + * @uses apply_filters() Calls 'theme_root' filter on path. + * + * @param string $stylesheet_or_template The stylesheet or template name of the theme + * @return string Theme path. + */ +function get_theme_root( $stylesheet_or_template = false ) { + if ( $stylesheet_or_template ) { + if ( $theme_root = get_raw_theme_root($stylesheet_or_template) ) + $theme_root = WP_CONTENT_DIR . $theme_root; + else + $theme_root = WP_CONTENT_DIR . '/themes'; + } else { + $theme_root = WP_CONTENT_DIR . '/themes'; + } + + return apply_filters( 'theme_root', $theme_root ); +} + +/** + * Retrieve URI for themes directory. + * + * Does not have trailing slash. + * + * @since 1.5.0 + * + * @param string $stylesheet_or_template The stylesheet or template name of the theme + * @return string Themes URI. + */ +function get_theme_root_uri( $stylesheet_or_template = false ) { + if ( $stylesheet_or_template ) { + if ( $theme_root = get_raw_theme_root($stylesheet_or_template) ) + $theme_root_uri = content_url( $theme_root ); + else + $theme_root_uri = content_url( 'themes' ); + } else { + $theme_root_uri = content_url( 'themes' ); + } + + return apply_filters( 'theme_root_uri', $theme_root_uri, get_option('siteurl'), $stylesheet_or_template ); +} + +/** + * Get the raw theme root relative to the content directory with no filters applied. + * + * @since 3.1.0 + * + * @param string $stylesheet_or_template The stylesheet or template name of the theme + * @return string Theme root + */ +function get_raw_theme_root( $stylesheet_or_template, $no_cache = false ) { + global $wp_theme_directories; + + if ( count($wp_theme_directories) <= 1 ) + return '/themes'; + + $theme_root = false; + + // If requesting the root for the current theme, consult options to avoid calling get_theme_roots() + if ( !$no_cache ) { + if ( get_option('stylesheet') == $stylesheet_or_template ) + $theme_root = get_option('stylesheet_root'); + elseif ( get_option('template') == $stylesheet_or_template ) + $theme_root = get_option('template_root'); + } + + if ( empty($theme_root) ) { + $theme_roots = get_theme_roots(); + if ( !empty($theme_roots[$stylesheet_or_template]) ) + $theme_root = $theme_roots[$stylesheet_or_template]; + } + + return $theme_root; +} + +/** + * Retrieve path to a template + * + * Used to quickly retrieve the path of a template without including the file + * extension. It will also check the parent theme, if the file exists, with + * the use of {@link locate_template()}. Allows for more generic template location + * without the use of the other get_*_template() functions. + * + * @since 1.5.0 + * + * @param string $type Filename without extension. + * @param array $templates An optional list of template candidates + * @return string Full path to file. + */ +function get_query_template( $type, $templates = array() ) { + $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); + + if ( empty( $templates ) ) + $templates = array("{$type}.php"); + + return apply_filters( "{$type}_template", locate_template( $templates ) ); +} + +/** + * Retrieve path of index template in current or parent template. + * + * @since 3.0.0 + * + * @return string + */ +function get_index_template() { + return get_query_template('index'); +} + +/** + * Retrieve path of 404 template in current or parent template. + * + * @since 1.5.0 + * + * @return string + */ +function get_404_template() { + return get_query_template('404'); +} + +/** + * Retrieve path of archive template in current or parent template. + * + * @since 1.5.0 + * + * @return string + */ +function get_archive_template() { + $post_type = get_query_var( 'post_type' ); + + $templates = array(); + + if ( $post_type ) + $templates[] = "archive-{$post_type}.php"; + $templates[] = 'archive.php'; + + return get_query_template( 'archive', $templates ); +} + +/** + * Retrieve path of author template in current or parent template. + * + * @since 1.5.0 + * + * @return string + */ +function get_author_template() { + $author = get_queried_object(); + + $templates = array(); + + $templates[] = "author-{$author->user_nicename}.php"; + $templates[] = "author-{$author->ID}.php"; + $templates[] = 'author.php'; + + return get_query_template( 'author', $templates ); +} + +/** + * Retrieve path of category template in current or parent template. + * + * Works by first retrieving the current slug for example 'category-default.php' and then + * trying category ID, for example 'category-1.php' and will finally fallback to category.php + * template, if those files don't exist. + * + * @since 1.5.0 + * @uses apply_filters() Calls 'category_template' on file path of category template. + * + * @return string + */ +function get_category_template() { + $category = get_queried_object(); + + $templates = array(); + + $templates[] = "category-{$category->slug}.php"; + $templates[] = "category-{$category->term_id}.php"; + $templates[] = "category.php"; + + return get_query_template( 'category', $templates ); +} + +/** + * Retrieve path of tag template in current or parent template. + * + * Works by first retrieving the current tag name, for example 'tag-wordpress.php' and then + * trying tag ID, for example 'tag-1.php' and will finally fallback to tag.php + * template, if those files don't exist. + * + * @since 2.3.0 + * @uses apply_filters() Calls 'tag_template' on file path of tag template. + * + * @return string + */ +function get_tag_template() { + $tag = get_queried_object(); + + $templates = array(); + + $templates[] = "tag-{$tag->slug}.php"; + $templates[] = "tag-{$tag->term_id}.php"; + $templates[] = "tag.php"; + + return get_query_template( 'tag', $templates ); +} + +/** + * Retrieve path of taxonomy template in current or parent template. + * + * Retrieves the taxonomy and term, if term is available. The template is + * prepended with 'taxonomy-' and followed by both the taxonomy string and + * the taxonomy string followed by a dash and then followed by the term. + * + * The taxonomy and term template is checked and used first, if it exists. + * Second, just the taxonomy template is checked, and then finally, taxonomy.php + * template is used. If none of the files exist, then it will fall back on to + * index.php. + * + * @since 2.5.0 + * @uses apply_filters() Calls 'taxonomy_template' filter on found path. + * + * @return string + */ +function get_taxonomy_template() { + $term = get_queried_object(); + $taxonomy = $term->taxonomy; + + $templates = array(); + + $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; + $templates[] = "taxonomy-$taxonomy.php"; + $templates[] = "taxonomy.php"; + + return get_query_template( 'taxonomy', $templates ); +} + +/** + * Retrieve path of date template in current or parent template. + * + * @since 1.5.0 + * + * @return string + */ +function get_date_template() { + return get_query_template('date'); +} + +/** + * Retrieve path of home template in current or parent template. + * + * This is the template used for the page containing the blog posts + * + * Attempts to locate 'home.php' first before falling back to 'index.php'. + * + * @since 1.5.0 + * @uses apply_filters() Calls 'home_template' on file path of home template. + * + * @return string + */ +function get_home_template() { + $templates = array( 'home.php', 'index.php' ); + + return get_query_template( 'home', $templates ); +} + +/** + * Retrieve path of front-page template in current or parent template. + * + * Looks for 'front-page.php'. + * + * @since 3.0.0 + * @uses apply_filters() Calls 'front_page_template' on file path of template. + * + * @return string + */ +function get_front_page_template() { + $templates = array('front-page.php'); + + return get_query_template( 'front_page', $templates ); +} + +/** + * Retrieve path of page template in current or parent template. + * + * Will first look for the specifically assigned page template + * The will search for 'page-{slug}.php' followed by 'page-id.php' + * and finally 'page.php' + * + * @since 1.5.0 + * + * @return string + */ +function get_page_template() { + $id = get_queried_object_id(); + $template = get_post_meta($id, '_wp_page_template', true); + $pagename = get_query_var('pagename'); + + if ( !$pagename && $id > 0 ) { + // If a static page is set as the front page, $pagename will not be set. Retrieve it from the queried object + $post = get_queried_object(); + $pagename = $post->post_name; + } + + if ( 'default' == $template ) + $template = ''; + + $templates = array(); + if ( !empty($template) && !validate_file($template) ) + $templates[] = $template; + if ( $pagename ) + $templates[] = "page-$pagename.php"; + if ( $id ) + $templates[] = "page-$id.php"; + $templates[] = "page.php"; + + return get_query_template( 'page', $templates ); +} + +/** + * Retrieve path of paged template in current or parent template. + * + * @since 1.5.0 + * + * @return string + */ +function get_paged_template() { + return get_query_template('paged'); +} + +/** + * Retrieve path of search template in current or parent template. + * + * @since 1.5.0 + * + * @return string + */ +function get_search_template() { + return get_query_template('search'); +} + +/** + * Retrieve path of single template in current or parent template. + * + * @since 1.5.0 + * + * @return string + */ +function get_single_template() { + $object = get_queried_object(); + + $templates = array(); + + $templates[] = "single-{$object->post_type}.php"; + $templates[] = "single.php"; + + return get_query_template( 'single', $templates ); +} + +/** + * Retrieve path of attachment template in current or parent template. + * + * The attachment path first checks if the first part of the mime type exists. + * The second check is for the second part of the mime type. The last check is + * for both types separated by an underscore. If neither are found then the file + * 'attachment.php' is checked and returned. + * + * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and + * finally 'text_plain.php'. + * + * @since 2.0.0 + * + * @return string + */ +function get_attachment_template() { + global $posts; + $type = explode('/', $posts[0]->post_mime_type); + if ( $template = get_query_template($type[0]) ) + return $template; + elseif ( $template = get_query_template($type[1]) ) + return $template; + elseif ( $template = get_query_template("$type[0]_$type[1]") ) + return $template; + else + return get_query_template('attachment'); +} + +/** + * Retrieve path of comment popup template in current or parent template. + * + * Checks for comment popup template in current template, if it exists or in the + * parent template. + * + * @since 1.5.0 + * @uses apply_filters() Calls 'comments_popup_template' filter on path. + * + * @return string + */ +function get_comments_popup_template() { + $template = get_query_template( 'comments_popup', array( 'comments-popup.php' ) ); + + // Backward compat code will be removed in a future release + if ('' == $template) + $template = ABSPATH . WPINC . '/theme-compat/comments-popup.php'; + + return $template; +} + +/** + * Retrieve the name of the highest priority template file that exists. + * + * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which + * inherit from a parent theme can just overload one file. + * + * @since 2.7.0 + * + * @param string|array $template_names Template file(s) to search for, in order. + * @param bool $load If true the template file will be loaded if it is found. + * @param bool $require_once Whether to require_once or require. Default true. Has no effect if $load is false. + * @return string The template filename if one is located. + */ +function locate_template($template_names, $load = false, $require_once = true ) { + $located = ''; + foreach ( (array) $template_names as $template_name ) { + if ( !$template_name ) + continue; + if ( file_exists(STYLESHEETPATH . '/' . $template_name)) { + $located = STYLESHEETPATH . '/' . $template_name; + break; + } else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) { + $located = TEMPLATEPATH . '/' . $template_name; + break; + } + } + + if ( $load && '' != $located ) + load_template( $located, $require_once ); + + return $located; +} + +/** + * Require the template file with WordPress environment. + * + * The globals are set up for the template file to ensure that the WordPress + * environment is available from within the function. The query variables are + * also available. + * + * @since 1.5.0 + * + * @param string $_template_file Path to template file. + * @param bool $require_once Whether to require_once or require. Default true. + */ +function load_template( $_template_file, $require_once = true ) { + global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; + + if ( is_array( $wp_query->query_vars ) ) + extract( $wp_query->query_vars, EXTR_SKIP ); + + if ( $require_once ) + require_once( $_template_file ); + else + require( $_template_file ); +} + +/** + * Display localized stylesheet link element. + * + * @since 2.1.0 + */ +function locale_stylesheet() { + $stylesheet = get_locale_stylesheet_uri(); + if ( empty($stylesheet) ) + return; + echo ''; +} + +/** + * Start preview theme output buffer. + * + * Will only preform task if the user has permissions and template and preview + * query variables exist. + * + * @since 2.6.0 + */ +function preview_theme() { + if ( ! (isset($_GET['template']) && isset($_GET['preview'])) ) + return; + + if ( !current_user_can( 'switch_themes' ) ) + return; + + // Admin Thickbox requests + if ( isset( $_GET['preview_iframe'] ) ) + show_admin_bar( false ); + + $_GET['template'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['template']); + + if ( validate_file($_GET['template']) ) + return; + + add_filter( 'template', '_preview_theme_template_filter' ); + + if ( isset($_GET['stylesheet']) ) { + $_GET['stylesheet'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['stylesheet']); + if ( validate_file($_GET['stylesheet']) ) + return; + add_filter( 'stylesheet', '_preview_theme_stylesheet_filter' ); + } + + // Prevent theme mods to current theme being used on theme being previewed + add_filter( 'pre_option_mods_' . get_current_theme(), '__return_empty_array' ); + + ob_start( 'preview_theme_ob_filter' ); +} +add_action('setup_theme', 'preview_theme'); + +/** + * Private function to modify the current template when previewing a theme + * + * @since 2.9.0 + * @access private + * + * @return string + */ +function _preview_theme_template_filter() { + return isset($_GET['template']) ? $_GET['template'] : ''; +} + +/** + * Private function to modify the current stylesheet when previewing a theme + * + * @since 2.9.0 + * @access private + * + * @return string + */ +function _preview_theme_stylesheet_filter() { + return isset($_GET['stylesheet']) ? $_GET['stylesheet'] : ''; +} + +/** + * Callback function for ob_start() to capture all links in the theme. + * + * @since 2.6.0 + * @access private + * + * @param string $content + * @return string + */ +function preview_theme_ob_filter( $content ) { + return preg_replace_callback( "|()|", 'preview_theme_ob_filter_callback', $content ); +} + +/** + * Manipulates preview theme links in order to control and maintain location. + * + * Callback function for preg_replace_callback() to accept and filter matches. + * + * @since 2.6.0 + * @access private + * + * @param array $matches + * @return string + */ +function preview_theme_ob_filter_callback( $matches ) { + if ( strpos($matches[4], 'onclick') !== false ) + $matches[4] = preg_replace('#onclick=([\'"]).*?(?. (? 1, 'template' => $_GET['template'], 'stylesheet' => @$_GET['stylesheet'] ), $matches[3] ); + if ( 0 === strpos($link, 'preview=1') ) + $link = "?$link"; + return $matches[1] . esc_attr( $link ) . $matches[4]; +} + +/** + * Switches current theme to new template and stylesheet names. + * + * @since 2.5.0 + * @uses do_action() Calls 'switch_theme' action on updated theme display name. + * + * @param string $template Template name + * @param string $stylesheet Stylesheet name. + */ +function switch_theme($template, $stylesheet) { + global $wp_theme_directories; + + update_option('template', $template); + update_option('stylesheet', $stylesheet); + if ( count($wp_theme_directories) > 1 ) { + update_option('template_root', get_raw_theme_root($template, true)); + update_option('stylesheet_root', get_raw_theme_root($stylesheet, true)); + } + delete_option('current_theme'); + $theme = get_current_theme(); + if ( is_admin() && false === get_option( "theme_mods_$stylesheet" ) ) { + $default_theme_mods = (array) get_option( "mods_$theme" ); + add_option( "theme_mods_$stylesheet", $default_theme_mods ); + } + do_action('switch_theme', $theme); +} + +/** + * Checks that current theme files 'index.php' and 'style.css' exists. + * + * Does not check the default theme, which is the fallback and should always exist. + * Will switch theme to the fallback theme if current theme does not validate. + * You can use the 'validate_current_theme' filter to return FALSE to + * disable this functionality. + * + * @since 1.5.0 + * @see WP_DEFAULT_THEME + * + * @return bool + */ +function validate_current_theme() { + // Don't validate during an install/upgrade. + if ( defined('WP_INSTALLING') || !apply_filters( 'validate_current_theme', true ) ) + return true; + + if ( get_template() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/index.php') ) { + switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); + return false; + } + + if ( get_stylesheet() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/style.css') ) { + switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); + return false; + } + + if ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { + switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); + return false; + } + + return true; +} + +/** + * Retrieve all theme modifications. + * + * @since 3.1.0 + * + * @return array Theme modifications. + */ +function get_theme_mods() { + $theme_slug = get_option( 'stylesheet' ); + if ( false === ( $mods = get_option( "theme_mods_$theme_slug" ) ) ) { + $theme_name = get_current_theme(); + $mods = get_option( "mods_$theme_name" ); // Deprecated location. + if ( is_admin() && false !== $mods ) { + update_option( "theme_mods_$theme_slug", $mods ); + delete_option( "mods_$theme_name" ); + } + } + return $mods; +} + +/** + * Retrieve theme modification value for the current theme. + * + * If the modification name does not exist, then the $default will be passed + * through {@link http://php.net/sprintf sprintf()} PHP function with the first + * string the template directory URI and the second string the stylesheet + * directory URI. + * + * @since 2.1.0 + * @uses apply_filters() Calls 'theme_mod_$name' filter on the value. + * + * @param string $name Theme modification name. + * @param bool|string $default + * @return string + */ +function get_theme_mod( $name, $default = false ) { + $mods = get_theme_mods(); + + if ( isset( $mods[ $name ] ) ) + return apply_filters( "theme_mod_$name", $mods[ $name ] ); + + return apply_filters( "theme_mod_$name", sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ) ); +} + +/** + * Update theme modification value for the current theme. + * + * @since 2.1.0 + * + * @param string $name Theme modification name. + * @param string $value theme modification value. + */ +function set_theme_mod( $name, $value ) { + $mods = get_theme_mods(); + + $mods[ $name ] = $value; + + $theme = get_option( 'stylesheet' ); + update_option( "theme_mods_$theme", $mods ); +} + +/** + * Remove theme modification name from current theme list. + * + * If removing the name also removes all elements, then the entire option will + * be removed. + * + * @since 2.1.0 + * + * @param string $name Theme modification name. + * @return null + */ +function remove_theme_mod( $name ) { + $mods = get_theme_mods(); + + if ( ! isset( $mods[ $name ] ) ) + return; + + unset( $mods[ $name ] ); + + if ( empty( $mods ) ) + return remove_theme_mods(); + + $theme = get_option( 'stylesheet' ); + update_option( "theme_mods_$theme", $mods ); +} + +/** + * Remove theme modifications option for current theme. + * + * @since 2.1.0 + */ +function remove_theme_mods() { + delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); + delete_option( 'mods_' . get_current_theme() ); +} + +/** + * Retrieve text color for custom header. + * + * @since 2.1.0 + * @uses HEADER_TEXTCOLOR + * + * @return string + */ +function get_header_textcolor() { + $default = defined('HEADER_TEXTCOLOR') ? HEADER_TEXTCOLOR : ''; + + return get_theme_mod('header_textcolor', $default); +} + +/** + * Display text color for custom header. + * + * @since 2.1.0 + */ +function header_textcolor() { + echo get_header_textcolor(); +} + +/** + * Retrieve header image for custom header. + * + * @since 2.1.0 + * @uses HEADER_IMAGE + * + * @return string + */ +function get_header_image() { + $default = defined( 'HEADER_IMAGE' ) ? HEADER_IMAGE : ''; + + $url = get_theme_mod( 'header_image', $default ); + + if ( is_ssl() ) + $url = str_replace( 'http://', 'https://', $url ); + else + $url = str_replace( 'https://', 'http://', $url ); + + return esc_url_raw( $url ); +} + +/** + * Display header image path. + * + * @since 2.1.0 + */ +function header_image() { + echo get_header_image(); +} + +/** + * Add callbacks for image header display. + * + * The parameter $header_callback callback will be required to display the + * content for the 'wp_head' action. The parameter $admin_header_callback + * callback will be added to Custom_Image_Header class and that will be added + * to the 'admin_menu' action. + * + * @since 2.1.0 + * @uses Custom_Image_Header Sets up for $admin_header_callback for administration panel display. + * + * @param callback $header_callback Call on 'wp_head' action. + * @param callback $admin_header_callback Call on custom header administration screen. + * @param callback $admin_image_div_callback Output a custom header image div on the custom header administration screen. Optional. + */ +function add_custom_image_header( $header_callback, $admin_header_callback, $admin_image_div_callback = '' ) { + if ( ! empty( $header_callback ) ) + add_action('wp_head', $header_callback); + + add_theme_support( 'custom-header', array( 'callback' => $header_callback ) ); + add_theme_support( 'custom-header-uploads' ); + + if ( ! is_admin() ) + return; + + global $custom_image_header; + + require_once( ABSPATH . 'wp-admin/custom-header.php' ); + $custom_image_header = new Custom_Image_Header( $admin_header_callback, $admin_image_div_callback ); + add_action( 'admin_menu', array( &$custom_image_header, 'init' ) ); +} + +/** + * Remove image header support. + * + * @since 3.1.0 + * @see add_custom_image_header() + * + * @return bool Whether support was removed. + */ +function remove_custom_image_header() { + if ( ! current_theme_supports( 'custom-header' ) ) + return false; + + $callback = get_theme_support( 'custom-header' ); + remove_action( 'wp_head', $callback[0]['callback'] ); + _remove_theme_support( 'custom-header' ); + remove_theme_support( 'custom-header-uploads' ); + + if ( is_admin() ) { + remove_action( 'admin_menu', array( &$GLOBALS['custom_image_header'], 'init' ) ); + unset( $GLOBALS['custom_image_header'] ); + } + + return true; +} + +/** + * Register a selection of default headers to be displayed by the custom header admin UI. + * + * @since 3.0.0 + * + * @param array $headers Array of headers keyed by a string id. The ids point to arrays containing 'url', 'thumbnail_url', and 'description' keys. + */ +function register_default_headers( $headers ) { + global $_wp_default_headers; + + $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); +} + +/** + * Unregister default headers. + * + * This function must be called after register_default_headers() has already added the + * header you want to remove. + * + * @see register_default_headers() + * @since 3.0.0 + * + * @param string|array $header The header string id (key of array) to remove, or an array thereof. + * @return True on success, false on failure. + */ +function unregister_default_headers( $header ) { + global $_wp_default_headers; + if ( is_array( $header ) ) { + array_map( 'unregister_default_headers', $header ); + } elseif ( isset( $_wp_default_headers[ $header ] ) ) { + unset( $_wp_default_headers[ $header ] ); + return true; + } else { + return false; + } +} + +/** + * Retrieve background image for custom background. + * + * @since 3.0.0 + * + * @return string + */ +function get_background_image() { + $default = defined('BACKGROUND_IMAGE') ? BACKGROUND_IMAGE : ''; + + return get_theme_mod('background_image', $default); +} + +/** + * Display background image path. + * + * @since 3.0.0 + */ +function background_image() { + echo get_background_image(); +} + +/** + * Retrieve value for custom background color. + * + * @since 3.0.0 + * @uses BACKGROUND_COLOR + * + * @return string + */ +function get_background_color() { + $default = defined('BACKGROUND_COLOR') ? BACKGROUND_COLOR : ''; + + return get_theme_mod('background_color', $default); +} + +/** + * Display background color value. + * + * @since 3.0.0 + */ +function background_color() { + echo get_background_color(); +} + +/** + * Add callbacks for background image display. + * + * The parameter $header_callback callback will be required to display the + * content for the 'wp_head' action. The parameter $admin_header_callback + * callback will be added to Custom_Background class and that will be added + * to the 'admin_menu' action. + * + * @since 3.0.0 + * @uses Custom_Background Sets up for $admin_header_callback for administration panel display. + * + * @param callback $header_callback Call on 'wp_head' action. + * @param callback $admin_header_callback Call on custom background administration screen. + * @param callback $admin_image_div_callback Output a custom background image div on the custom background administration screen. Optional. + */ +function add_custom_background( $header_callback = '', $admin_header_callback = '', $admin_image_div_callback = '' ) { + if ( isset( $GLOBALS['custom_background'] ) ) + return; + + if ( empty( $header_callback ) ) + $header_callback = '_custom_background_cb'; + + add_action( 'wp_head', $header_callback ); + + add_theme_support( 'custom-background', array( 'callback' => $header_callback ) ); + + if ( ! is_admin() ) + return; + require_once( ABSPATH . 'wp-admin/custom-background.php' ); + $GLOBALS['custom_background'] =& new Custom_Background( $admin_header_callback, $admin_image_div_callback ); + add_action( 'admin_menu', array( &$GLOBALS['custom_background'], 'init' ) ); +} + +/** + * Remove custom background support. + * + * @since 3.1.0 + * @see add_custom_background() + * + * @return bool Whether support was removed. + */ +function remove_custom_background() { + if ( ! current_theme_supports( 'custom-background' ) ) + return false; + + $callback = get_theme_support( 'custom-background' ); + remove_action( 'wp_head', $callback[0]['callback'] ); + _remove_theme_support( 'custom-background' ); + + if ( is_admin() ) { + remove_action( 'admin_menu', array( &$GLOBALS['custom_background'], 'init' ) ); + unset( $GLOBALS['custom_background'] ); + } + + return true; +} + +/** + * Default custom background callback. + * + * @since 3.0.0 + * @see add_custom_background() + * @access protected + */ +function _custom_background_cb() { + $background = get_background_image(); + $color = get_background_color(); + if ( ! $background && ! $color ) + return; + + $style = $color ? "background-color: #$color;" : ''; + + if ( $background ) { + $image = " background-image: url('$background');"; + + $repeat = get_theme_mod( 'background_repeat', 'repeat' ); + if ( ! in_array( $repeat, array( 'no-repeat', 'repeat-x', 'repeat-y', 'repeat' ) ) ) + $repeat = 'repeat'; + $repeat = " background-repeat: $repeat;"; + + $position = get_theme_mod( 'background_position_x', 'left' ); + if ( ! in_array( $position, array( 'center', 'right', 'left' ) ) ) + $position = 'left'; + $position = " background-position: top $position;"; + + $attachment = get_theme_mod( 'background_attachment', 'scroll' ); + if ( ! in_array( $attachment, array( 'fixed', 'scroll' ) ) ) + $attachment = 'scroll'; + $attachment = " background-attachment: $attachment;"; + + $style .= $image . $repeat . $position . $attachment; + } +?> + + diff --git a/src/wp-includes/update.php b/src/wp-includes/update.php new file mode 100644 index 00000000..1f9f2a9a --- /dev/null +++ b/src/wp-includes/update.php @@ -0,0 +1,375 @@ +updates = array(); + $current->version_checked = $wp_version; + } + + $locale = apply_filters( 'core_version_check_locale', get_locale() ); + + // Update last_checked for current to prevent multiple blocking requests if request hangs + $current->last_checked = time(); + set_site_transient( 'update_core', $current ); + + if ( method_exists( $wpdb, 'db_version' ) ) + $mysql_version = preg_replace('/[^0-9.].*/', '', $wpdb->db_version()); + else + $mysql_version = 'N/A'; + + if ( is_multisite( ) ) { + $user_count = get_user_count( ); + $num_blogs = get_blog_count( ); + $wp_install = network_site_url( ); + $multisite_enabled = 1; + } else { + $user_count = count_users( ); + $multisite_enabled = 0; + $num_blogs = 1; + $wp_install = home_url( '/' ); + } + + $local_package = isset( $wp_local_package )? $wp_local_package : ''; + $url = "http://api.wordpress.org/core/version-check/1.5/?version=$wp_version&php=$php_version&locale=$locale&mysql=$mysql_version&local_package=$local_package&blogs=$num_blogs&users={$user_count['total_users']}&multisite_enabled=$multisite_enabled"; + + $options = array( + 'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3 ), + 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ), + 'headers' => array( + 'wp_install' => $wp_install, + 'wp_blog' => home_url( '/' ) + ) + ); + + $response = wp_remote_get($url, $options); + + if ( is_wp_error( $response ) ) + return false; + + if ( 200 != $response['response']['code'] ) + return false; + + $body = trim( $response['body'] ); + $body = str_replace(array("\r\n", "\r"), "\n", $body); + $new_options = array(); + foreach ( explode( "\n\n", $body ) as $entry ) { + $returns = explode("\n", $entry); + $new_option = new stdClass(); + $new_option->response = esc_attr( $returns[0] ); + if ( isset( $returns[1] ) ) + $new_option->url = esc_url( $returns[1] ); + if ( isset( $returns[2] ) ) + $new_option->package = esc_url( $returns[2] ); + if ( isset( $returns[3] ) ) + $new_option->current = esc_attr( $returns[3] ); + if ( isset( $returns[4] ) ) + $new_option->locale = esc_attr( $returns[4] ); + if ( isset( $returns[5] ) ) + $new_option->php_version = esc_attr( $returns[5] ); + if ( isset( $returns[6] ) ) + $new_option->mysql_version = esc_attr( $returns[6] ); + $new_options[] = $new_option; + } + + $updates = new stdClass(); + $updates->updates = $new_options; + $updates->last_checked = time(); + $updates->version_checked = $wp_version; + set_site_transient( 'update_core', $updates); +} + +/** + * Check plugin versions against the latest versions hosted on WordPress.org. + * + * The WordPress version, PHP version, and Locale is sent along with a list of + * all plugins installed. Checks against the WordPress server at + * api.wordpress.org. Will only check if WordPress isn't installing. + * + * @package WordPress + * @since 2.3.0 + * @uses $wp_version Used to notify the WordPress version. + * + * @return mixed Returns null if update is unsupported. Returns false if check is too soon. + */ +function wp_update_plugins() { + global $wp_version; + + if ( defined('WP_INSTALLING') ) + return false; + + // If running blog-side, bail unless we've not checked in the last 12 hours + if ( !function_exists( 'get_plugins' ) ) + require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); + + $plugins = get_plugins(); + $active = get_option( 'active_plugins', array() ); + $current = get_site_transient( 'update_plugins' ); + if ( ! is_object($current) ) + $current = new stdClass; + + $new_option = new stdClass; + $new_option->last_checked = time(); + $timeout = 'load-plugins.php' == current_filter() ? 3600 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours + $time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked ); + + $plugin_changed = false; + foreach ( $plugins as $file => $p ) { + $new_option->checked[ $file ] = $p['Version']; + + if ( !isset( $current->checked[ $file ] ) || strval($current->checked[ $file ]) !== strval($p['Version']) ) + $plugin_changed = true; + } + + if ( isset ( $current->response ) && is_array( $current->response ) ) { + foreach ( $current->response as $plugin_file => $update_details ) { + if ( ! isset($plugins[ $plugin_file ]) ) { + $plugin_changed = true; + break; + } + } + } + + // Bail if we've checked in the last 12 hours and if nothing has changed + if ( $time_not_changed && !$plugin_changed ) + return false; + + // Update last_checked for current to prevent multiple blocking requests if request hangs + $current->last_checked = time(); + set_site_transient( 'update_plugins', $current ); + + $to_send = (object) compact('plugins', 'active'); + + $options = array( + 'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3), + 'body' => array( 'plugins' => serialize( $to_send ) ), + 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) + ); + + $raw_response = wp_remote_post('http://api.wordpress.org/plugins/update-check/1.0/', $options); + + if ( is_wp_error( $raw_response ) ) + return false; + + if ( 200 != $raw_response['response']['code'] ) + return false; + + $response = unserialize( $raw_response['body'] ); + + if ( false !== $response ) + $new_option->response = $response; + else + $new_option->response = array(); + + set_site_transient( 'update_plugins', $new_option ); +} + +/** + * Check theme versions against the latest versions hosted on WordPress.org. + * + * A list of all themes installed in sent to WP. Checks against the + * WordPress server at api.wordpress.org. Will only check if WordPress isn't + * installing. + * + * @package WordPress + * @since 2.7.0 + * @uses $wp_version Used to notify the WordPress version. + * + * @return mixed Returns null if update is unsupported. Returns false if check is too soon. + */ +function wp_update_themes( ) { + global $wp_version; + + if ( defined( 'WP_INSTALLING' ) ) + return false; + + if ( !function_exists( 'get_themes' ) ) + require_once( ABSPATH . 'wp-includes/theme.php' ); + + $installed_themes = get_themes( ); + $last_update = get_site_transient( 'update_themes' ); + if ( ! is_object($last_update) ) + $last_update = new stdClass; + + $timeout = 'load-themes.php' == current_filter() ? 3600 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours + $time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time( ) - $last_update->last_checked ); + + $themes = array(); + $checked = array(); + $exclude_fields = array('Template Files', 'Stylesheet Files', 'Status', 'Theme Root', 'Theme Root URI', 'Template Dir', 'Stylesheet Dir', 'Description', 'Tags', 'Screenshot'); + + // Put slug of current theme into request. + $themes['current_theme'] = get_option( 'stylesheet' ); + + foreach ( (array) $installed_themes as $theme_title => $theme ) { + $themes[$theme['Stylesheet']] = array(); + $checked[$theme['Stylesheet']] = $theme['Version']; + + $themes[$theme['Stylesheet']]['Name'] = $theme['Name']; + $themes[$theme['Stylesheet']]['Version'] = $theme['Version']; + + foreach ( (array) $theme as $key => $value ) { + if ( !in_array($key, $exclude_fields) ) + $themes[$theme['Stylesheet']][$key] = $value; + } + } + + $theme_changed = false; + foreach ( $checked as $slug => $v ) { + $update_request->checked[ $slug ] = $v; + + if ( !isset( $last_update->checked[ $slug ] ) || strval($last_update->checked[ $slug ]) !== strval($v) ) + $theme_changed = true; + } + + if ( isset ( $last_update->response ) && is_array( $last_update->response ) ) { + foreach ( $last_update->response as $slug => $update_details ) { + if ( ! isset($checked[ $slug ]) ) { + $theme_changed = true; + break; + } + } + } + + if ( $time_not_changed && !$theme_changed ) + return false; + + // Update last_checked for current to prevent multiple blocking requests if request hangs + $last_update->last_checked = time(); + set_site_transient( 'update_themes', $last_update ); + + $options = array( + 'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3), + 'body' => array( 'themes' => serialize( $themes ) ), + 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) + ); + + $raw_response = wp_remote_post( 'http://api.wordpress.org/themes/update-check/1.0/', $options ); + + if ( is_wp_error( $raw_response ) ) + return false; + + if ( 200 != $raw_response['response']['code'] ) + return false; + + $new_update = new stdClass; + $new_update->last_checked = time( ); + $response = unserialize( $raw_response['body'] ); + if ( $response ) { + $new_update->checked = $checked; + $new_update->response = $response; + } + + set_site_transient( 'update_themes', $new_update ); +} + +function _maybe_update_core() { + global $wp_version; + + $current = get_site_transient( 'update_core' ); + + if ( isset( $current->last_checked ) && + 43200 > ( time() - $current->last_checked ) && + isset( $current->version_checked ) && + $current->version_checked == $wp_version ) + return; + + wp_version_check(); +} +/** + * Check the last time plugins were run before checking plugin versions. + * + * This might have been backported to WordPress 2.6.1 for performance reasons. + * This is used for the wp-admin to check only so often instead of every page + * load. + * + * @since 2.7.0 + * @access private + */ +function _maybe_update_plugins() { + $current = get_site_transient( 'update_plugins' ); + if ( isset( $current->last_checked ) && 43200 > ( time() - $current->last_checked ) ) + return; + wp_update_plugins(); +} + +/** + * Check themes versions only after a duration of time. + * + * This is for performance reasons to make sure that on the theme version + * checker is not run on every page load. + * + * @since 2.7.0 + * @access private + */ +function _maybe_update_themes( ) { + $current = get_site_transient( 'update_themes' ); + if ( isset( $current->last_checked ) && 43200 > ( time( ) - $current->last_checked ) ) + return; + + wp_update_themes(); +} + +/** + * Schedule core, theme, and plugin update checks. + * + * @since 3.1.0 + */ +function wp_schedule_update_checks() { + if ( !wp_next_scheduled('wp_version_check') && !defined('WP_INSTALLING') ) + wp_schedule_event(time(), 'twicedaily', 'wp_version_check'); + + if ( !wp_next_scheduled('wp_update_plugins') && !defined('WP_INSTALLING') ) + wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins'); + + if ( !wp_next_scheduled('wp_update_themes') && !defined('WP_INSTALLING') ) + wp_schedule_event(time(), 'twicedaily', 'wp_update_themes'); +} + +if ( ! is_main_site() ) + return; + +add_action( 'admin_init', '_maybe_update_core' ); +add_action( 'wp_version_check', 'wp_version_check' ); + +add_action( 'load-plugins.php', 'wp_update_plugins' ); +add_action( 'load-update.php', 'wp_update_plugins' ); +add_action( 'load-update-core.php', 'wp_update_plugins' ); +add_action( 'admin_init', '_maybe_update_plugins' ); +add_action( 'wp_update_plugins', 'wp_update_plugins' ); + +add_action( 'load-themes.php', 'wp_update_themes' ); +add_action( 'load-update.php', 'wp_update_themes' ); +add_action( 'load-update-core.php', 'wp_update_themes' ); +add_action( 'admin_init', '_maybe_update_themes' ); +add_action( 'wp_update_themes', 'wp_update_themes' ); + +add_action('init', 'wp_schedule_update_checks'); + +?> diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php new file mode 100644 index 00000000..0a1a4354 --- /dev/null +++ b/src/wp-includes/user.php @@ -0,0 +1,1620 @@ +get_error_codes() == array('empty_username', 'empty_password') ) { + $user = new WP_Error('', ''); + } + + return $user; + } + + wp_set_auth_cookie($user->ID, $credentials['remember'], $secure_cookie); + do_action('wp_login', $credentials['user_login']); + return $user; +} + + +/** + * Authenticate the user using the username and password. + */ +add_filter('authenticate', 'wp_authenticate_username_password', 20, 3); +function wp_authenticate_username_password($user, $username, $password) { + if ( is_a($user, 'WP_User') ) { return $user; } + + if ( empty($username) || empty($password) ) { + $error = new WP_Error(); + + if ( empty($username) ) + $error->add('empty_username', __('ERROR: The username field is empty.')); + + if ( empty($password) ) + $error->add('empty_password', __('ERROR: The password field is empty.')); + + return $error; + } + + $userdata = get_user_by('login', $username); + + if ( !$userdata ) + return new WP_Error('invalid_username', sprintf(__('ERROR: Invalid username. Lost your password?'), site_url('wp-login.php?action=lostpassword', 'login'))); + + if ( is_multisite() ) { + // Is user marked as spam? + if ( 1 == $userdata->spam) + return new WP_Error('invalid_username', __('ERROR: Your account has been marked as a spammer.')); + + // Is a user's blog marked as spam? + if ( !is_super_admin( $userdata->ID ) && isset($userdata->primary_blog) ) { + $details = get_blog_details( $userdata->primary_blog ); + if ( is_object( $details ) && $details->spam == 1 ) + return new WP_Error('blog_suspended', __('Site Suspended.')); + } + } + + $userdata = apply_filters('wp_authenticate_user', $userdata, $password); + if ( is_wp_error($userdata) ) + return $userdata; + + if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) ) + return new WP_Error( 'incorrect_password', sprintf( __( 'ERROR: The password you entered for the username %1$s is incorrect. Lost your password?' ), + $username, site_url( 'wp-login.php?action=lostpassword', 'login' ) ) ); + + $user = new WP_User($userdata->ID); + return $user; +} + +/** + * Authenticate the user using the WordPress auth cookie. + */ +function wp_authenticate_cookie($user, $username, $password) { + if ( is_a($user, 'WP_User') ) { return $user; } + + if ( empty($username) && empty($password) ) { + $user_id = wp_validate_auth_cookie(); + if ( $user_id ) + return new WP_User($user_id); + + global $auth_secure_cookie; + + if ( $auth_secure_cookie ) + $auth_cookie = SECURE_AUTH_COOKIE; + else + $auth_cookie = AUTH_COOKIE; + + if ( !empty($_COOKIE[$auth_cookie]) ) + return new WP_Error('expired_session', __('Please log in again.')); + + // If the cookie is not set, be silent. + } + + return $user; +} + +/** + * Number of posts user has written. + * + * @since 3.0.0 + * @uses $wpdb WordPress database object for queries. + * + * @param int $userid User ID. + * @return int Amount of posts user has written. + */ +function count_user_posts($userid) { + global $wpdb; + + $where = get_posts_by_author_sql('post', TRUE, $userid); + + $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts $where" ); + + return apply_filters('get_usernumposts', $count, $userid); +} + +/** + * Number of posts written by a list of users. + * + * @since 3.0.0 + * @param array $users User ID number list. + * @return array Amount of posts each user has written. + */ +function count_many_users_posts($users) { + global $wpdb; + + $count = array(); + if ( ! is_array($users) || empty( $users ) ) + return $count; + + $userlist = implode( ',', $users ); + $where = get_posts_by_author_sql( 'post' ); + + $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N ); + foreach ( $result as $row ) { + $count[ $row[0] ] = $row[1]; + } + + foreach ( $users as $id ) { + if ( ! isset( $count[ $id ] ) ) + $count[ $id ] = 0; + } + + return $count; +} + +/** + * Check that the user login name and password is correct. + * + * @since 0.71 + * @todo xmlrpc only. Maybe move to xmlrpc.php. + * + * @param string $user_login User name. + * @param string $user_pass User password. + * @return bool False if does not authenticate, true if username and password authenticates. + */ +function user_pass_ok($user_login, $user_pass) { + $user = wp_authenticate($user_login, $user_pass); + if ( is_wp_error($user) ) + return false; + + return true; +} + +// +// User option functions +// + +/** + * Get the current user's ID + * + * @since MU + * + * @uses wp_get_current_user + * + * @return int The current user's ID + */ +function get_current_user_id() { + $user = wp_get_current_user(); + return ( isset( $user->ID ) ? (int) $user->ID : 0 ); +} + +/** + * Retrieve user option that can be either per Site or per Network. + * + * If the user ID is not given, then the current user will be used instead. If + * the user ID is given, then the user data will be retrieved. The filter for + * the result, will also pass the original option name and finally the user data + * object as the third parameter. + * + * The option will first check for the per site name and then the per Network name. + * + * @since 2.0.0 + * @uses $wpdb WordPress database object for queries. + * @uses apply_filters() Calls 'get_user_option_$option' hook with result, + * option parameter, and user data object. + * + * @param string $option User option name. + * @param int $user Optional. User ID. + * @param bool $deprecated Use get_option() to check for an option in the options table. + * @return mixed + */ +function get_user_option( $option, $user = 0, $deprecated = '' ) { + global $wpdb; + + if ( !empty( $deprecated ) ) + _deprecated_argument( __FUNCTION__, '3.0' ); + + if ( empty($user) ) { + $user = wp_get_current_user(); + $user = $user->ID; + } + + $user = get_userdata($user); + + // Keys used as object vars cannot have dashes. + $key = str_replace('-', '', $option); + + if ( isset( $user->{$wpdb->prefix . $key} ) ) // Blog specific + $result = $user->{$wpdb->prefix . $key}; + elseif ( isset( $user->{$key} ) ) // User specific and cross-blog + $result = $user->{$key}; + else + $result = false; + + return apply_filters("get_user_option_{$option}", $result, $option, $user); +} + +/** + * Update user option with global blog capability. + * + * User options are just like user metadata except that they have support for + * global blog options. If the 'global' parameter is false, which it is by default + * it will prepend the WordPress table prefix to the option name. + * + * Deletes the user option if $newvalue is empty. + * + * @since 2.0.0 + * @uses $wpdb WordPress database object for queries + * + * @param int $user_id User ID + * @param string $option_name User option name. + * @param mixed $newvalue User option value. + * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific). + * @return unknown + */ +function update_user_option( $user_id, $option_name, $newvalue, $global = false ) { + global $wpdb; + + if ( !$global ) + $option_name = $wpdb->prefix . $option_name; + + // For backward compatibility. See differences between update_user_meta() and deprecated update_usermeta(). + // http://core.trac.wordpress.org/ticket/13088 + if ( is_null( $newvalue ) || is_scalar( $newvalue ) && empty( $newvalue ) ) + return delete_user_meta( $user_id, $option_name ); + + return update_user_meta( $user_id, $option_name, $newvalue ); +} + +/** + * Delete user option with global blog capability. + * + * User options are just like user metadata except that they have support for + * global blog options. If the 'global' parameter is false, which it is by default + * it will prepend the WordPress table prefix to the option name. + * + * @since 3.0.0 + * @uses $wpdb WordPress database object for queries + * + * @param int $user_id User ID + * @param string $option_name User option name. + * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific). + * @return unknown + */ +function delete_user_option( $user_id, $option_name, $global = false ) { + global $wpdb; + + if ( !$global ) + $option_name = $wpdb->prefix . $option_name; + return delete_user_meta( $user_id, $option_name ); +} + +/** + * WordPress User Query class. + * + * @since 3.1.0 + */ +class WP_User_Query { + + /** + * List of found user ids + * + * @since 3.1.0 + * @access private + * @var array + */ + var $results; + + /** + * Total number of found users for the current query + * + * @since 3.1.0 + * @access private + * @var int + */ + var $total_users = 0; + + // SQL clauses + var $query_fields; + var $query_from; + var $query_where; + var $query_orderby; + var $query_limit; + + /** + * PHP4 constructor + */ + function WP_User_Query( $query = null ) { + $this->__construct( $query ); + } + + /** + * PHP5 constructor + * + * @since 3.1.0 + * + * @param string|array $args The query variables + * @return WP_User_Query + */ + function __construct( $query = null ) { + if ( !empty( $query ) ) { + $this->query_vars = wp_parse_args( $query, array( + 'blog_id' => $GLOBALS['blog_id'], + 'role' => '', + 'meta_key' => '', + 'meta_value' => '', + 'meta_compare' => '', + 'include' => array(), + 'exclude' => array(), + 'search' => '', + 'orderby' => 'login', + 'order' => 'ASC', + 'offset' => '', 'number' => '', + 'count_total' => true, + 'fields' => 'all', + 'who' => '' + ) ); + + $this->prepare_query(); + $this->query(); + } + } + + /** + * Prepare the query variables + * + * @since 3.1.0 + * @access private + */ + function prepare_query() { + global $wpdb; + + $qv = &$this->query_vars; + + if ( is_array( $qv['fields'] ) ) { + $qv['fields'] = array_unique( $qv['fields'] ); + + $this->query_fields = array(); + foreach ( $qv['fields'] as $field ) + $this->query_fields[] = $wpdb->users . '.' . esc_sql( $field ); + $this->query_fields = implode( ',', $this->query_fields ); + } elseif ( 'all' == $qv['fields'] ) { + $this->query_fields = "$wpdb->users.*"; + } else { + $this->query_fields = "$wpdb->users.ID"; + } + + $this->query_from = "FROM $wpdb->users"; + $this->query_where = "WHERE 1=1"; + + // sorting + if ( in_array( $qv['orderby'], array('nicename', 'email', 'url', 'registered') ) ) { + $orderby = 'user_' . $qv['orderby']; + } elseif ( in_array( $qv['orderby'], array('user_nicename', 'user_email', 'user_url', 'user_registered') ) ) { + $orderby = $qv['orderby']; + } elseif ( 'name' == $qv['orderby'] || 'display_name' == $qv['orderby'] ) { + $orderby = 'display_name'; + } elseif ( 'post_count' == $qv['orderby'] ) { + // todo: avoid the JOIN + $where = get_posts_by_author_sql('post'); + $this->query_from .= " LEFT OUTER JOIN ( + SELECT post_author, COUNT(*) as post_count + FROM $wpdb->posts + $where + GROUP BY post_author + ) p ON ({$wpdb->users}.ID = p.post_author) + "; + $orderby = 'post_count'; + } elseif ( 'ID' == $qv['orderby'] || 'id' == $qv['orderby'] ) { + $orderby = 'ID'; + } else { + $orderby = 'user_login'; + } + + $qv['order'] = strtoupper( $qv['order'] ); + if ( 'ASC' == $qv['order'] ) + $order = 'ASC'; + else + $order = 'DESC'; + $this->query_orderby = "ORDER BY $orderby $order"; + + // limit + if ( $qv['number'] ) { + if ( $qv['offset'] ) + $this->query_limit = $wpdb->prepare("LIMIT %d, %d", $qv['offset'], $qv['number']); + else + $this->query_limit = $wpdb->prepare("LIMIT %d", $qv['number']); + } + + $search = trim( $qv['search'] ); + if ( $search ) { + $leading_wild = ( ltrim($search, '*') != $search ); + $trailing_wild = ( rtrim($search, '*') != $search ); + if ( $leading_wild && $trailing_wild ) + $wild = 'both'; + elseif ( $leading_wild ) + $wild = 'leading'; + elseif ( $trailing_wild ) + $wild = 'trailing'; + else + $wild = false; + if ( $wild ) + $search = trim($search, '*'); + + if ( false !== strpos( $search, '@') ) + $search_columns = array('user_email'); + elseif ( is_numeric($search) ) + $search_columns = array('user_login', 'ID'); + elseif ( preg_match('|^https?://|', $search) ) + $search_columns = array('user_url'); + else + $search_columns = array('user_login', 'user_nicename'); + + $this->query_where .= $this->get_search_sql( $search, $search_columns, $wild ); + } + + $blog_id = absint( $qv['blog_id'] ); + + if ( 'authors' == $qv['who'] && $blog_id ) { + $qv['meta_key'] = $wpdb->get_blog_prefix( $blog_id ) . 'user_level'; + $qv['meta_value'] = '_wp_zero_value'; // Hack to pass '0' + $qv['meta_compare'] = '!='; + $qv['blog_id'] = $blog_id = 0; // Prevent extra meta query + } + + _parse_meta_query( $qv ); + + $role = trim( $qv['role'] ); + + if ( $blog_id && ( $role || is_multisite() ) ) { + $cap_meta_query = array(); + $cap_meta_query['key'] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities'; + + if ( $role ) { + $cap_meta_query['value'] = '"' . $role . '"'; + $cap_meta_query['compare'] = 'like'; + } + + $qv['meta_query'][] = $cap_meta_query; + } + + if ( !empty( $qv['meta_query'] ) ) { + $clauses = call_user_func_array( '_get_meta_sql', array( $qv['meta_query'], 'user', $wpdb->users, 'ID', &$this ) ); + $this->query_from .= $clauses['join']; + $this->query_where .= $clauses['where']; + } + + if ( !empty( $qv['include'] ) ) { + $ids = implode( ',', wp_parse_id_list( $qv['include'] ) ); + $this->query_where .= " AND $wpdb->users.ID IN ($ids)"; + } elseif ( !empty($qv['exclude']) ) { + $ids = implode( ',', wp_parse_id_list( $qv['exclude'] ) ); + $this->query_where .= " AND $wpdb->users.ID NOT IN ($ids)"; + } + + do_action_ref_array( 'pre_user_query', array( &$this ) ); + } + + /** + * Execute the query, with the current variables + * + * @since 3.1.0 + * @access private + */ + function query() { + global $wpdb; + + if ( is_array( $this->query_vars['fields'] ) || 'all' == $this->query_vars['fields'] ) { + $this->results = $wpdb->get_results("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); + } else { + $this->results = $wpdb->get_col("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); + } + + if ( $this->query_vars['count_total'] ) + $this->total_users = $wpdb->get_var("SELECT COUNT(*) $this->query_from $this->query_where"); + + if ( !$this->results ) + return; + + if ( 'all_with_meta' == $this->query_vars['fields'] ) { + cache_users( $this->results ); + + $r = array(); + foreach ( $this->results as $userid ) + $r[ $userid ] = new WP_User( $userid, '', $this->query_vars['blog_id'] ); + + $this->results = $r; + } + } + + /* + * Used internally to generate an SQL string for searching across multiple columns + * + * @access protected + * @since 3.1.0 + * + * @param string $string + * @param array $cols + * @param bool $wild Whether to allow wildcard searches. Default is false for Network Admin, true for + * single site. Single site allows leading and trailing wildcards, Network Admin only trailing. + * @return string + */ + function get_search_sql( $string, $cols, $wild = false ) { + $string = esc_sql( $string ); + + $searches = array(); + $leading_wild = ( 'leading' == $wild || 'both' == $wild ) ? '%' : ''; + $trailing_wild = ( 'trailing' == $wild || 'both' == $wild ) ? '%' : ''; + foreach ( $cols as $col ) { + if ( 'ID' == $col ) + $searches[] = "$col = '$string'"; + else + $searches[] = "$col LIKE '$leading_wild" . like_escape($string) . "$trailing_wild'"; + } + + return ' AND (' . implode(' OR ', $searches) . ')'; + } + + /** + * Return the list of users + * + * @since 3.1.0 + * @access public + * + * @return array + */ + function get_results() { + return $this->results; + } + + /** + * Return the total number of users for the current query + * + * @since 3.1.0 + * @access public + * + * @return array + */ + function get_total() { + return $this->total_users; + } +} + +/** + * Retrieve list of users matching criteria. + * + * @since 3.1.0 + * @uses $wpdb + * @uses WP_User_Query See for default arguments and information. + * + * @param array $args Optional. + * @return array List of users. + */ +function get_users( $args = array() ) { + + $args = wp_parse_args( $args ); + $args['count_total'] = false; + + $user_search = new WP_User_Query($args); + + return (array) $user_search->get_results(); +} + +/** + * Get the blogs a user belongs to. + * + * @since 3.0.0 + * + * @param int $id User Id + * @param bool $all Whether to retrieve all blogs or only blogs that are not marked as deleted, archived, or spam. + * @return array A list of the user's blogs. False if the user was not found or an empty array if the user has no blogs. + */ +function get_blogs_of_user( $id, $all = false ) { + global $wpdb; + + if ( !is_multisite() ) { + $blog_id = get_current_blog_id(); + $blogs = array(); + $blogs[ $blog_id ]->userblog_id = $blog_id; + $blogs[ $blog_id ]->blogname = get_option('blogname'); + $blogs[ $blog_id ]->domain = ''; + $blogs[ $blog_id ]->path = ''; + $blogs[ $blog_id ]->site_id = 1; + $blogs[ $blog_id ]->siteurl = get_option('siteurl'); + return $blogs; + } + + $blogs = wp_cache_get( 'blogs_of_user-' . $id, 'users' ); + + // Try priming the new cache from the old cache + if ( false === $blogs ) { + $cache_suffix = $all ? '_all' : '_short'; + $blogs = wp_cache_get( 'blogs_of_user_' . $id . $cache_suffix, 'users' ); + if ( is_array( $blogs ) ) { + $blogs = array_keys( $blogs ); + if ( $all ) + wp_cache_set( 'blogs_of_user-' . $id, $blogs, 'users' ); + } + } + + if ( false === $blogs ) { + $user = get_userdata( (int) $id ); + if ( !$user ) + return false; + + $blogs = $match = array(); + $prefix_length = strlen($wpdb->base_prefix); + foreach ( (array) $user as $key => $value ) { + if ( $prefix_length && substr($key, 0, $prefix_length) != $wpdb->base_prefix ) + continue; + if ( substr($key, -12, 12) != 'capabilities' ) + continue; + if ( preg_match( '/^' . $wpdb->base_prefix . '((\d+)_)?capabilities$/', $key, $match ) ) { + if ( count( $match ) > 2 ) + $blogs[] = (int) $match[ 2 ]; + else + $blogs[] = 1; + } + } + wp_cache_set( 'blogs_of_user-' . $id, $blogs, 'users' ); + } + + $blog_deets = array(); + foreach ( (array) $blogs as $blog_id ) { + $blog = get_blog_details( $blog_id ); + if ( $blog && isset( $blog->domain ) && ( $all == true || $all == false && ( $blog->archived == 0 && $blog->spam == 0 && $blog->deleted == 0 ) ) ) { + $blog_deets[ $blog_id ]->userblog_id = $blog_id; + $blog_deets[ $blog_id ]->blogname = $blog->blogname; + $blog_deets[ $blog_id ]->domain = $blog->domain; + $blog_deets[ $blog_id ]->path = $blog->path; + $blog_deets[ $blog_id ]->site_id = $blog->site_id; + $blog_deets[ $blog_id ]->siteurl = $blog->siteurl; + } + } + + return apply_filters( 'get_blogs_of_user', $blog_deets, $id, $all ); +} + +/** + * Checks if the current user belong to a given blog. + * + * @since 3.0.0 + * + * @param int $blog_id Blog ID + * @return bool True if the current users belong to $blog_id, false if not. + */ +function is_blog_user( $blog_id = 0 ) { + global $wpdb; + + $current_user = wp_get_current_user(); + if ( !$blog_id ) + $blog_id = $wpdb->blogid; + + $cap_key = $wpdb->base_prefix . $blog_id . '_capabilities'; + + if ( is_array($current_user->$cap_key) && in_array(1, $current_user->$cap_key) ) + return true; + + return false; +} + +/** + * Add meta data field to a user. + * + * Post meta data is called "Custom Fields" on the Administration Panels. + * + * @since 3.0.0 + * @uses add_metadata() + * @link http://codex.wordpress.org/Function_Reference/add_user_meta + * + * @param int $user_id Post ID. + * @param string $meta_key Metadata name. + * @param mixed $meta_value Metadata value. + * @param bool $unique Optional, default is false. Whether the same key should not be added. + * @return bool False for failure. True for success. + */ +function add_user_meta($user_id, $meta_key, $meta_value, $unique = false) { + return add_metadata('user', $user_id, $meta_key, $meta_value, $unique); +} + +/** + * Remove metadata matching criteria from a user. + * + * You can match based on the key, or key and value. Removing based on key and + * value, will keep from removing duplicate metadata with the same key. It also + * allows removing all metadata matching key, if needed. + * + * @since 3.0.0 + * @uses delete_metadata() + * @link http://codex.wordpress.org/Function_Reference/delete_user_meta + * + * @param int $user_id user ID + * @param string $meta_key Metadata name. + * @param mixed $meta_value Optional. Metadata value. + * @return bool False for failure. True for success. + */ +function delete_user_meta($user_id, $meta_key, $meta_value = '') { + return delete_metadata('user', $user_id, $meta_key, $meta_value); +} + +/** + * Retrieve user meta field for a user. + * + * @since 3.0.0 + * @uses get_metadata() + * @link http://codex.wordpress.org/Function_Reference/get_user_meta + * + * @param int $user_id Post ID. + * @param string $key The meta key to retrieve. + * @param bool $single Whether to return a single value. + * @return mixed Will be an array if $single is false. Will be value of meta data field if $single + * is true. + */ +function get_user_meta($user_id, $key, $single = false) { + return get_metadata('user', $user_id, $key, $single); +} + +/** + * Update user meta field based on user ID. + * + * Use the $prev_value parameter to differentiate between meta fields with the + * same key and user ID. + * + * If the meta field for the user does not exist, it will be added. + * + * @since 3.0.0 + * @uses update_metadata + * @link http://codex.wordpress.org/Function_Reference/update_user_meta + * + * @param int $user_id Post ID. + * @param string $meta_key Metadata key. + * @param mixed $meta_value Metadata value. + * @param mixed $prev_value Optional. Previous value to check before removing. + * @return bool False on failure, true if success. + */ +function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') { + return update_metadata('user', $user_id, $meta_key, $meta_value, $prev_value); +} + +/** + * Count number of users who have each of the user roles. + * + * Assumes there are neither duplicated nor orphaned capabilities meta_values. + * Assumes role names are unique phrases. Same assumption made by WP_User_Query::prepare_query() + * Using $strategy = 'time' this is CPU-intensive and should handle around 10^7 users. + * Using $strategy = 'memory' this is memory-intensive and should handle around 10^5 users, but see WP Bug #12257. + * + * @since 3.0.0 + * @param string $strategy 'time' or 'memory' + * @return array Includes a grand total and an array of counts indexed by role strings. + */ +function count_users($strategy = 'time') { + global $wpdb, $wp_roles; + + // Initialize + $id = get_current_blog_id(); + $blog_prefix = $wpdb->get_blog_prefix($id); + $result = array(); + + if ( 'time' == $strategy ) { + global $wp_roles; + + if ( ! isset( $wp_roles ) ) + $wp_roles = new WP_Roles(); + + $avail_roles = $wp_roles->get_names(); + + // Build a CPU-intensive query that will return concise information. + $select_count = array(); + foreach ( $avail_roles as $this_role => $name ) { + $select_count[] = "COUNT(NULLIF(`meta_value` LIKE '%" . like_escape($this_role) . "%', FALSE))"; + } + $select_count = implode(', ', $select_count); + + // Add the meta_value index to the selection list, then run the query. + $row = $wpdb->get_row( "SELECT $select_count, COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'", ARRAY_N ); + + // Run the previous loop again to associate results with role names. + $col = 0; + $role_counts = array(); + foreach ( $avail_roles as $this_role => $name ) { + $count = (int) $row[$col++]; + if ($count > 0) { + $role_counts[$this_role] = $count; + } + } + + // Get the meta_value index from the end of the result set. + $total_users = (int) $row[$col]; + + $result['total_users'] = $total_users; + $result['avail_roles'] =& $role_counts; + } else { + $avail_roles = array(); + + $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" ); + + foreach ( $users_of_blog as $caps_meta ) { + $b_roles = unserialize($caps_meta); + if ( is_array($b_roles) ) { + foreach ( $b_roles as $b_role => $val ) { + if ( isset($avail_roles[$b_role]) ) { + $avail_roles[$b_role]++; + } else { + $avail_roles[$b_role] = 1; + } + } + } + } + + $result['total_users'] = count( $users_of_blog ); + $result['avail_roles'] =& $avail_roles; + } + + return $result; +} + +// +// Private helper functions +// + +/** + * Set up global user vars. + * + * Used by wp_set_current_user() for back compat. Might be deprecated in the future. + * + * @since 2.0.4 + * @global string $userdata User description. + * @global string $user_login The user username for logging in + * @global int $user_level The level of the user + * @global int $user_ID The ID of the user + * @global string $user_email The email address of the user + * @global string $user_url The url in the user's profile + * @global string $user_pass_md5 MD5 of the user's password + * @global string $user_identity The display name of the user + * + * @param int $for_user_id Optional. User ID to set up global data. + */ +function setup_userdata($for_user_id = '') { + global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_pass_md5, $user_identity; + + if ( '' == $for_user_id ) + $user = wp_get_current_user(); + else + $user = new WP_User($for_user_id); + + $userdata = $user->data; + $user_ID = (int) $user->ID; + $user_level = (int) isset($user->user_level) ? $user->user_level : 0; + + if ( 0 == $user->ID ) { + $user_login = $user_email = $user_url = $user_pass_md5 = $user_identity = ''; + return; + } + + $user_login = $user->user_login; + $user_email = $user->user_email; + $user_url = $user->user_url; + $user_pass_md5 = md5($user->user_pass); + $user_identity = $user->display_name; +} + +/** + * Create dropdown HTML content of users. + * + * The content can either be displayed, which it is by default or retrieved by + * setting the 'echo' argument. The 'include' and 'exclude' arguments do not + * need to be used; all users will be displayed in that case. Only one can be + * used, either 'include' or 'exclude', but not both. + * + * The available arguments are as follows: + *
      + *
    1. show_option_all - Text to show all and whether HTML option exists.
    2. + *
    3. show_option_none - Text for show none and whether HTML option exists.
    4. + *
    5. hide_if_only_one_author - Don't create the dropdown if there is only one user.
    6. + *
    7. orderby - SQL order by clause for what order the users appear. Default is 'display_name'.
    8. + *
    9. order - Default is 'ASC'. Can also be 'DESC'.
    10. + *
    11. include - User IDs to include.
    12. + *
    13. exclude - User IDs to exclude.
    14. + *
    15. multi - Default is 'false'. Whether to skip the ID attribute on the 'select' element. A 'true' value is overridden when id argument is set.
    16. + *
    17. show - Default is 'display_name'. User table column to display. If the selected item is empty then the user_login will be displayed in parentheses
    18. + *
    19. echo - Default is '1'. Whether to display or retrieve content.
    20. + *
    21. selected - Which User ID is selected.
    22. + *
    23. include_selected - Always include the selected user ID in the dropdown. Default is false.
    24. + *
    25. name - Default is 'user'. Name attribute of select element.
    26. + *
    27. id - Default is the value of the 'name' parameter. ID attribute of select element.
    28. + *
    29. class - Class attribute of select element.
    30. + *
    31. blog_id - ID of blog (Multisite only). Defaults to ID of current blog.
    32. + *
    33. who - Which users to query. Currently only 'authors' is supported. Default is all users.
    34. + *
    + * + * @since 2.3.0 + * @uses $wpdb WordPress database object for queries + * + * @param string|array $args Optional. Override defaults. + * @return string|null Null on display. String of HTML content on retrieve. + */ +function wp_dropdown_users( $args = '' ) { + $defaults = array( + 'show_option_all' => '', 'show_option_none' => '', 'hide_if_only_one_author' => '', + 'orderby' => 'display_name', 'order' => 'ASC', + 'include' => '', 'exclude' => '', 'multi' => 0, + 'show' => 'display_name', 'echo' => 1, + 'selected' => 0, 'name' => 'user', 'class' => '', 'id' => '', + 'blog_id' => $GLOBALS['blog_id'], 'who' => '', 'include_selected' => false + ); + + $defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0; + + $r = wp_parse_args( $args, $defaults ); + extract( $r, EXTR_SKIP ); + + $query_args = wp_array_slice_assoc( $r, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who' ) ); + $query_args['fields'] = array( 'ID', $show ); + $users = get_users( $query_args ); + + $output = ''; + if ( !empty($users) && ( empty($hide_if_only_one_author) || count($users) > 1 ) ) { + $name = esc_attr( $name ); + if ( $multi && ! $id ) + $id = ''; + else + $id = $id ? " id='" . esc_attr( $id ) . "'" : " id='$name'"; + + $output = ""; + } + + $output = apply_filters('wp_dropdown_users', $output); + + if ( $echo ) + echo $output; + + return $output; +} + +/** + * Add user meta data as properties to given user object. + * + * The finished user data is cached, but the cache is not used to fill in the + * user data for the given object. Once the function has been used, the cache + * should be used to retrieve user data. The intention is if the current data + * had been cached already, there would be no need to call this function. + * + * @access private + * @since 2.5.0 + * @uses $wpdb WordPress database object for queries + * + * @param object $user The user data object. + */ +function _fill_user( &$user ) { + $metavalues = get_user_metavalues(array($user->ID)); + _fill_single_user($user, $metavalues[$user->ID]); +} + +/** + * Perform the query to get the $metavalues array(s) needed by _fill_user and _fill_many_users + * + * @since 3.0.0 + * @param array $ids User ID numbers list. + * @return array of arrays. The array is indexed by user_id, containing $metavalues object arrays. + */ +function get_user_metavalues($ids) { + $objects = array(); + + $ids = array_map('intval', $ids); + foreach ( $ids as $id ) + $objects[$id] = array(); + + $metas = update_meta_cache('user', $ids); + + foreach ( $metas as $id => $meta ) { + foreach ( $meta as $key => $metavalues ) { + foreach ( $metavalues as $value ) { + $objects[$id][] = (object)array( 'user_id' => $id, 'meta_key' => $key, 'meta_value' => $value); + } + } + } + + return $objects; +} + +/** + * Unserialize user metadata, fill $user object, then cache everything. + * + * @since 3.0.0 + * @param object $user The User object. + * @param array $metavalues An array of objects provided by get_user_metavalues() + */ +function _fill_single_user( &$user, &$metavalues ) { + global $wpdb; + + foreach ( $metavalues as $meta ) { + $value = maybe_unserialize($meta->meta_value); + // Keys used as object vars cannot have dashes. + $key = str_replace('-', '', $meta->meta_key); + $user->{$key} = $value; + } + + $level = $wpdb->prefix . 'user_level'; + if ( isset( $user->{$level} ) ) + $user->user_level = $user->{$level}; + + // For backwards compat. + if ( isset($user->first_name) ) + $user->user_firstname = $user->first_name; + if ( isset($user->last_name) ) + $user->user_lastname = $user->last_name; + if ( isset($user->description) ) + $user->user_description = $user->description; + + update_user_caches($user); +} + +/** + * Take an array of user objects, fill them with metas, and cache them. + * + * @since 3.0.0 + * @param array $users User objects + */ +function _fill_many_users( &$users ) { + $ids = array(); + foreach( $users as $user_object ) { + $ids[] = $user_object->ID; + } + + $metas = get_user_metavalues($ids); + + foreach ( $users as $user_object ) { + if ( isset($metas[$user_object->ID]) ) { + _fill_single_user($user_object, $metas[$user_object->ID]); + } + } +} + +/** + * Sanitize every user field. + * + * If the context is 'raw', then the user object or array will get minimal santization of the int fields. + * + * @since 2.3.0 + * @uses sanitize_user_field() Used to sanitize the fields. + * + * @param object|array $user The User Object or Array + * @param string $context Optional, default is 'display'. How to sanitize user fields. + * @return object|array The now sanitized User Object or Array (will be the same type as $user) + */ +function sanitize_user_object($user, $context = 'display') { + if ( is_object($user) ) { + if ( !isset($user->ID) ) + $user->ID = 0; + if ( isset($user->data) ) + $vars = get_object_vars( $user->data ); + else + $vars = get_object_vars($user); + foreach ( array_keys($vars) as $field ) { + if ( is_string($user->$field) || is_numeric($user->$field) ) + $user->$field = sanitize_user_field($field, $user->$field, $user->ID, $context); + } + $user->filter = $context; + } else { + if ( !isset($user['ID']) ) + $user['ID'] = 0; + foreach ( array_keys($user) as $field ) + $user[$field] = sanitize_user_field($field, $user[$field], $user['ID'], $context); + $user['filter'] = $context; + } + + return $user; +} + +/** + * Sanitize user field based on context. + * + * Possible context values are: 'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The + * 'display' context is used by default. 'attribute' and 'js' contexts are treated like 'display' + * when calling filters. + * + * @since 2.3.0 + * @uses apply_filters() Calls 'edit_$field' and '{$field_no_prefix}_edit_pre' passing $value and + * $user_id if $context == 'edit' and field name prefix == 'user_'. + * + * @uses apply_filters() Calls 'edit_user_$field' passing $value and $user_id if $context == 'db'. + * @uses apply_filters() Calls 'pre_$field' passing $value if $context == 'db' and field name prefix == 'user_'. + * @uses apply_filters() Calls '{$field}_pre' passing $value if $context == 'db' and field name prefix != 'user_'. + * + * @uses apply_filters() Calls '$field' passing $value, $user_id and $context if $context == anything + * other than 'raw', 'edit' and 'db' and field name prefix == 'user_'. + * @uses apply_filters() Calls 'user_$field' passing $value if $context == anything other than 'raw', + * 'edit' and 'db' and field name prefix != 'user_'. + * + * @param string $field The user Object field name. + * @param mixed $value The user Object value. + * @param int $user_id user ID. + * @param string $context How to sanitize user fields. Looks for 'raw', 'edit', 'db', 'display', + * 'attribute' and 'js'. + * @return mixed Sanitized value. + */ +function sanitize_user_field($field, $value, $user_id, $context) { + $int_fields = array('ID'); + if ( in_array($field, $int_fields) ) + $value = (int) $value; + + if ( 'raw' == $context ) + return $value; + + if ( !is_string($value) && !is_numeric($value) ) + return $value; + + $prefixed = false; + if ( false !== strpos($field, 'user_') ) { + $prefixed = true; + $field_no_prefix = str_replace('user_', '', $field); + } + + if ( 'edit' == $context ) { + if ( $prefixed ) { + $value = apply_filters("edit_{$field}", $value, $user_id); + } else { + $value = apply_filters("edit_user_{$field}", $value, $user_id); + } + + if ( 'description' == $field ) + $value = esc_html( $value ); // textarea_escaped? + else + $value = esc_attr($value); + } else if ( 'db' == $context ) { + if ( $prefixed ) { + $value = apply_filters("pre_{$field}", $value); + } else { + $value = apply_filters("pre_user_{$field}", $value); + } + } else { + // Use display filters by default. + if ( $prefixed ) + $value = apply_filters($field, $value, $user_id, $context); + else + $value = apply_filters("user_{$field}", $value, $user_id, $context); + } + + if ( 'user_url' == $field ) + $value = esc_url($value); + + if ( 'attribute' == $context ) + $value = esc_attr($value); + else if ( 'js' == $context ) + $value = esc_js($value); + + return $value; +} + +/** + * Update all user caches + * + * @since 3.0.0 + * + * @param object $user User object to be cached + */ +function update_user_caches(&$user) { + wp_cache_add($user->ID, $user, 'users'); + wp_cache_add($user->user_login, $user->ID, 'userlogins'); + wp_cache_add($user->user_email, $user->ID, 'useremail'); + wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); +} + +/** + * Clean all user caches + * + * @since 3.0.0 + * + * @param int $id User ID + */ +function clean_user_cache($id) { + $user = new WP_User($id); + + wp_cache_delete($id, 'users'); + wp_cache_delete($user->user_login, 'userlogins'); + wp_cache_delete($user->user_email, 'useremail'); + wp_cache_delete($user->user_nicename, 'userslugs'); + wp_cache_delete('blogs_of_user-' . $id, 'users'); +} + +/** + * Checks whether the given username exists. + * + * @since 2.0.0 + * + * @param string $username Username. + * @return null|int The user's ID on success, and null on failure. + */ +function username_exists( $username ) { + if ( $user = get_userdatabylogin( $username ) ) { + return $user->ID; + } else { + return null; + } +} + +/** + * Checks whether the given email exists. + * + * @since 2.1.0 + * @uses $wpdb + * + * @param string $email Email. + * @return bool|int The user's ID on success, and false on failure. + */ +function email_exists( $email ) { + if ( $user = get_user_by_email($email) ) + return $user->ID; + + return false; +} + +/** + * Checks whether an username is valid. + * + * @since 2.0.1 + * @uses apply_filters() Calls 'validate_username' hook on $valid check and $username as parameters + * + * @param string $username Username. + * @return bool Whether username given is valid + */ +function validate_username( $username ) { + $sanitized = sanitize_user( $username, true ); + $valid = ( $sanitized == $username ); + return apply_filters( 'validate_username', $valid, $username ); +} + +/** + * Insert an user into the database. + * + * Can update a current user or insert a new user based on whether the user's ID + * is present. + * + * Can be used to update the user's info (see below), set the user's role, and + * set the user's preference on whether they want the rich editor on. + * + * Most of the $userdata array fields have filters associated with the values. + * The exceptions are 'rich_editing', 'role', 'jabber', 'aim', 'yim', + * 'user_registered', and 'ID'. The filters have the prefix 'pre_user_' followed + * by the field name. An example using 'description' would have the filter + * called, 'pre_user_description' that can be hooked into. + * + * The $userdata array can contain the following fields: + * 'ID' - An integer that will be used for updating an existing user. + * 'user_pass' - A string that contains the plain text password for the user. + * 'user_login' - A string that contains the user's username for logging in. + * 'user_nicename' - A string that contains a nicer looking name for the user. + * The default is the user's username. + * 'user_url' - A string containing the user's URL for the user's web site. + * 'user_email' - A string containing the user's email address. + * 'display_name' - A string that will be shown on the site. Defaults to user's + * username. It is likely that you will want to change this, for both + * appearance and security through obscurity (that is if you don't use and + * delete the default 'admin' user). + * 'nickname' - The user's nickname, defaults to the user's username. + * 'first_name' - The user's first name. + * 'last_name' - The user's last name. + * 'description' - A string containing content about the user. + * 'rich_editing' - A string for whether to enable the rich editor. False + * if not empty. + * 'user_registered' - The date the user registered. Format is 'Y-m-d H:i:s'. + * 'role' - A string used to set the user's role. + * 'jabber' - User's Jabber account. + * 'aim' - User's AOL IM account. + * 'yim' - User's Yahoo IM account. + * + * @since 2.0.0 + * @uses $wpdb WordPress database layer. + * @uses apply_filters() Calls filters for most of the $userdata fields with the prefix 'pre_user'. See note above. + * @uses do_action() Calls 'profile_update' hook when updating giving the user's ID + * @uses do_action() Calls 'user_register' hook when creating a new user giving the user's ID + * + * @param array $userdata An array of user data. + * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not be created. + */ +function wp_insert_user($userdata) { + global $wpdb; + + extract($userdata, EXTR_SKIP); + + // Are we updating or creating? + if ( !empty($ID) ) { + $ID = (int) $ID; + $update = true; + $old_user_data = get_userdata($ID); + } else { + $update = false; + // Hash the password + $user_pass = wp_hash_password($user_pass); + } + + $user_login = sanitize_user($user_login, true); + $user_login = apply_filters('pre_user_login', $user_login); + + //Remove any non-printable chars from the login string to see if we have ended up with an empty username + $user_login = trim($user_login); + + if ( empty($user_login) ) + return new WP_Error('empty_user_login', __('Cannot create a user with an empty login name.') ); + + if ( !$update && username_exists( $user_login ) ) + return new WP_Error('existing_user_login', __('This username is already registered.') ); + + if ( empty($user_nicename) ) + $user_nicename = sanitize_title( $user_login ); + $user_nicename = apply_filters('pre_user_nicename', $user_nicename); + + if ( empty($user_url) ) + $user_url = ''; + $user_url = apply_filters('pre_user_url', $user_url); + + if ( empty($user_email) ) + $user_email = ''; + $user_email = apply_filters('pre_user_email', $user_email); + + if ( !$update && ! defined( 'WP_IMPORTING' ) && email_exists($user_email) ) + return new WP_Error('existing_user_email', __('This email address is already registered.') ); + + if ( empty($display_name) ) + $display_name = $user_login; + $display_name = apply_filters('pre_user_display_name', $display_name); + + if ( empty($nickname) ) + $nickname = $user_login; + $nickname = apply_filters('pre_user_nickname', $nickname); + + if ( empty($first_name) ) + $first_name = ''; + $first_name = apply_filters('pre_user_first_name', $first_name); + + if ( empty($last_name) ) + $last_name = ''; + $last_name = apply_filters('pre_user_last_name', $last_name); + + if ( empty($description) ) + $description = ''; + $description = apply_filters('pre_user_description', $description); + + if ( empty($rich_editing) ) + $rich_editing = 'true'; + + if ( empty($comment_shortcuts) ) + $comment_shortcuts = 'false'; + + if ( empty($admin_color) ) + $admin_color = 'fresh'; + $admin_color = preg_replace('|[^a-z0-9 _.\-@]|i', '', $admin_color); + + if ( empty($use_ssl) ) + $use_ssl = 0; + + if ( empty($user_registered) ) + $user_registered = gmdate('Y-m-d H:i:s'); + + if ( empty($show_admin_bar_front) ) + $show_admin_bar_front = 'true'; + + if ( empty($show_admin_bar_admin) ) + $show_admin_bar_admin = is_multisite() ? 'true' : 'false'; + + $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $user_nicename, $user_login)); + + if ( $user_nicename_check ) { + $suffix = 2; + while ($user_nicename_check) { + $alt_user_nicename = $user_nicename . "-$suffix"; + $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $alt_user_nicename, $user_login)); + $suffix++; + } + $user_nicename = $alt_user_nicename; + } + + $data = compact( 'user_pass', 'user_email', 'user_url', 'user_nicename', 'display_name', 'user_registered' ); + $data = stripslashes_deep( $data ); + + if ( $update ) { + $wpdb->update( $wpdb->users, $data, compact( 'ID' ) ); + $user_id = (int) $ID; + } else { + $wpdb->insert( $wpdb->users, $data + compact( 'user_login' ) ); + $user_id = (int) $wpdb->insert_id; + } + + update_user_meta( $user_id, 'first_name', $first_name ); + update_user_meta( $user_id, 'last_name', $last_name ); + update_user_meta( $user_id, 'nickname', $nickname ); + update_user_meta( $user_id, 'description', $description ); + update_user_meta( $user_id, 'rich_editing', $rich_editing ); + update_user_meta( $user_id, 'comment_shortcuts', $comment_shortcuts ); + update_user_meta( $user_id, 'admin_color', $admin_color ); + update_user_meta( $user_id, 'use_ssl', $use_ssl ); + update_user_meta( $user_id, 'show_admin_bar_front', $show_admin_bar_front ); + update_user_meta( $user_id, 'show_admin_bar_admin', $show_admin_bar_admin ); + + $user = new WP_User($user_id); + + foreach ( _wp_get_user_contactmethods( $user ) as $method => $name ) { + if ( empty($$method) ) + $$method = ''; + + update_user_meta( $user_id, $method, $$method ); + } + + if ( isset($role) ) + $user->set_role($role); + elseif ( !$update ) + $user->set_role(get_option('default_role')); + + wp_cache_delete($user_id, 'users'); + wp_cache_delete($user_login, 'userlogins'); + + if ( $update ) + do_action('profile_update', $user_id, $old_user_data); + else + do_action('user_register', $user_id); + + return $user_id; +} + +/** + * Update an user in the database. + * + * It is possible to update a user's password by specifying the 'user_pass' + * value in the $userdata parameter array. + * + * If $userdata does not contain an 'ID' key, then a new user will be created + * and the new user's ID will be returned. + * + * If current user's password is being updated, then the cookies will be + * cleared. + * + * @since 2.0.0 + * @see wp_insert_user() For what fields can be set in $userdata + * @uses wp_insert_user() Used to update existing user or add new one if user doesn't exist already + * + * @param array $userdata An array of user data. + * @return int The updated user's ID. + */ +function wp_update_user($userdata) { + $ID = (int) $userdata['ID']; + + // First, get all of the original fields + $user = get_userdata($ID); + + // Escape data pulled from DB. + $user = add_magic_quotes(get_object_vars($user)); + + // If password is changing, hash it now. + if ( ! empty($userdata['user_pass']) ) { + $plaintext_pass = $userdata['user_pass']; + $userdata['user_pass'] = wp_hash_password($userdata['user_pass']); + } + + wp_cache_delete($user[ 'user_email' ], 'useremail'); + + // Merge old and new fields with new fields overwriting old ones. + $userdata = array_merge($user, $userdata); + $user_id = wp_insert_user($userdata); + + // Update the cookies if the password changed. + $current_user = wp_get_current_user(); + if ( $current_user->id == $ID ) { + if ( isset($plaintext_pass) ) { + wp_clear_auth_cookie(); + wp_set_auth_cookie($ID); + } + } + + return $user_id; +} + +/** + * A simpler way of inserting an user into the database. + * + * Creates a new user with just the username, password, and email. For a more + * detail creation of a user, use wp_insert_user() to specify more infomation. + * + * @since 2.0.0 + * @see wp_insert_user() More complete way to create a new user + * + * @param string $username The user's username. + * @param string $password The user's password. + * @param string $email The user's email (optional). + * @return int The new user's ID. + */ +function wp_create_user($username, $password, $email = '') { + $user_login = esc_sql( $username ); + $user_email = esc_sql( $email ); + $user_pass = $password; + + $userdata = compact('user_login', 'user_email', 'user_pass'); + return wp_insert_user($userdata); +} + + +/** + * Set up the default contact methods + * + * @access private + * @since + * + * @param object $user User data object (optional) + * @return array $user_contactmethods Array of contact methods and their labels. + */ +function _wp_get_user_contactmethods( $user = null ) { + $user_contactmethods = array( + 'aim' => __('AIM'), + 'yim' => __('Yahoo IM'), + 'jabber' => __('Jabber / Google Talk') + ); + return apply_filters( 'user_contactmethods', $user_contactmethods, $user ); +} + +?> diff --git a/src/wp-includes/vars.php b/src/wp-includes/vars.php new file mode 100644 index 00000000..bfd2a5d3 --- /dev/null +++ b/src/wp-includes/vars.php @@ -0,0 +1,91 @@ + \ No newline at end of file diff --git a/src/wp-includes/version.php b/src/wp-includes/version.php new file mode 100644 index 00000000..544b4e34 --- /dev/null +++ b/src/wp-includes/version.php @@ -0,0 +1,62 @@ +' . __('There are no options for this widget.') . '

    '; + return 'noform'; + } + + // Functions you'll need to call. + + /** + * PHP4 constructor + */ + function WP_Widget( $id_base = false, $name, $widget_options = array(), $control_options = array() ) { + $this->__construct( $id_base, $name, $widget_options, $control_options ); + } + + /** + * PHP5 constructor + * + * @param string $id_base Optional Base ID for the widget, lower case, + * if left empty a portion of the widget's class name will be used. Has to be unique. + * @param string $name Name for the widget displayed on the configuration page. + * @param array $widget_options Optional Passed to wp_register_sidebar_widget() + * - description: shown on the configuration page + * - classname + * @param array $control_options Optional Passed to wp_register_widget_control() + * - width: required if more than 250px + * - height: currently not used but may be needed in the future + */ + function __construct( $id_base = false, $name, $widget_options = array(), $control_options = array() ) { + $this->id_base = empty($id_base) ? preg_replace( '/(wp_)?widget_/', '', strtolower(get_class($this)) ) : strtolower($id_base); + $this->name = $name; + $this->option_name = 'widget_' . $this->id_base; + $this->widget_options = wp_parse_args( $widget_options, array('classname' => $this->option_name) ); + $this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) ); + } + + /** + * Constructs name attributes for use in form() fields + * + * This function should be used in form() methods to create name attributes for fields to be saved by update() + * + * @param string $field_name Field name + * @return string Name attribute for $field_name + */ + function get_field_name($field_name) { + return 'widget-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']'; + } + + /** + * Constructs id attributes for use in form() fields + * + * This function should be used in form() methods to create id attributes for fields to be saved by update() + * + * @param string $field_name Field name + * @return string ID attribute for $field_name + */ + function get_field_id($field_name) { + return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name; + } + + // Private Functions. Don't worry about these. + + function _register() { + $settings = $this->get_settings(); + $empty = true; + + if ( is_array($settings) ) { + foreach ( array_keys($settings) as $number ) { + if ( is_numeric($number) ) { + $this->_set($number); + $this->_register_one($number); + $empty = false; + } + } + } + + if ( $empty ) { + // If there are none, we register the widget's existance with a + // generic template + $this->_set(1); + $this->_register_one(); + } + } + + function _set($number) { + $this->number = $number; + $this->id = $this->id_base . '-' . $number; + } + + function _get_display_callback() { + return array(&$this, 'display_callback'); + } + + function _get_update_callback() { + return array(&$this, 'update_callback'); + } + + function _get_form_callback() { + return array(&$this, 'form_callback'); + } + + /** Generate the actual widget content. + * Just finds the instance and calls widget(). + * Do NOT over-ride this function. */ + function display_callback( $args, $widget_args = 1 ) { + if ( is_numeric($widget_args) ) + $widget_args = array( 'number' => $widget_args ); + + $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); + $this->_set( $widget_args['number'] ); + $instance = $this->get_settings(); + + if ( array_key_exists( $this->number, $instance ) ) { + $instance = $instance[$this->number]; + // filters the widget's settings, return false to stop displaying the widget + $instance = apply_filters('widget_display_callback', $instance, $this, $args); + if ( false !== $instance ) + $this->widget($args, $instance); + } + } + + /** Deal with changed settings. + * Do NOT over-ride this function. */ + function update_callback( $widget_args = 1 ) { + global $wp_registered_widgets; + + if ( is_numeric($widget_args) ) + $widget_args = array( 'number' => $widget_args ); + + $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); + $all_instances = $this->get_settings(); + + // We need to update the data + if ( $this->updated ) + return; + + $sidebars_widgets = wp_get_sidebars_widgets(); + + if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { + // Delete the settings for this instance of the widget + if ( isset($_POST['the-widget-id']) ) + $del_id = $_POST['the-widget-id']; + else + return; + + if ( isset($wp_registered_widgets[$del_id]['params'][0]['number']) ) { + $number = $wp_registered_widgets[$del_id]['params'][0]['number']; + + if ( $this->id_base . '-' . $number == $del_id ) + unset($all_instances[$number]); + } + } else { + if ( isset($_POST['widget-' . $this->id_base]) && is_array($_POST['widget-' . $this->id_base]) ) { + $settings = $_POST['widget-' . $this->id_base]; + } elseif ( isset($_POST['id_base']) && $_POST['id_base'] == $this->id_base ) { + $num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['widget_number']; + $settings = array( $num => array() ); + } else { + return; + } + + foreach ( $settings as $number => $new_instance ) { + $new_instance = stripslashes_deep($new_instance); + $this->_set($number); + + $old_instance = isset($all_instances[$number]) ? $all_instances[$number] : array(); + + $instance = $this->update($new_instance, $old_instance); + + // filters the widget's settings before saving, return false to cancel saving (keep the old settings if updating) + $instance = apply_filters('widget_update_callback', $instance, $new_instance, $old_instance, $this); + if ( false !== $instance ) + $all_instances[$number] = $instance; + + break; // run only once + } + } + + $this->save_settings($all_instances); + $this->updated = true; + } + + /** Generate the control form. + * Do NOT over-ride this function. */ + function form_callback( $widget_args = 1 ) { + if ( is_numeric($widget_args) ) + $widget_args = array( 'number' => $widget_args ); + + $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); + $all_instances = $this->get_settings(); + + if ( -1 == $widget_args['number'] ) { + // We echo out a form where 'number' can be set later + $this->_set('__i__'); + $instance = array(); + } else { + $this->_set($widget_args['number']); + $instance = $all_instances[ $widget_args['number'] ]; + } + + // filters the widget admin form before displaying, return false to stop displaying it + $instance = apply_filters('widget_form_callback', $instance, $this); + + $return = null; + if ( false !== $instance ) { + $return = $this->form($instance); + // add extra fields in the widget form - be sure to set $return to null if you add any + // if the widget has no form the text echoed from the default form method can be hidden using css + do_action_ref_array( 'in_widget_form', array(&$this, &$return, $instance) ); + } + return $return; + } + + /** Helper function: Registers a single instance. */ + function _register_one($number = -1) { + wp_register_sidebar_widget( $this->id, $this->name, $this->_get_display_callback(), $this->widget_options, array( 'number' => $number ) ); + _register_widget_update_callback( $this->id_base, $this->_get_update_callback(), $this->control_options, array( 'number' => -1 ) ); + _register_widget_form_callback( $this->id, $this->name, $this->_get_form_callback(), $this->control_options, array( 'number' => $number ) ); + } + + function save_settings($settings) { + $settings['_multiwidget'] = 1; + update_option( $this->option_name, $settings ); + } + + function get_settings() { + $settings = get_option($this->option_name); + + if ( false === $settings && isset($this->alt_option_name) ) + $settings = get_option($this->alt_option_name); + + if ( !is_array($settings) ) + $settings = array(); + + if ( !array_key_exists('_multiwidget', $settings) ) { + // old format, conver if single widget + $settings = wp_convert_widget_settings($this->id_base, $this->option_name, $settings); + } + + unset($settings['_multiwidget'], $settings['__i__']); + return $settings; + } +} + +/** + * Singleton that registers and instantiates WP_Widget classes. + * + * @package WordPress + * @subpackage Widgets + * @since 2.8 + */ +class WP_Widget_Factory { + var $widgets = array(); + + function WP_Widget_Factory() { + add_action( 'widgets_init', array( &$this, '_register_widgets' ), 100 ); + } + + function register($widget_class) { + $this->widgets[$widget_class] = & new $widget_class(); + } + + function unregister($widget_class) { + if ( isset($this->widgets[$widget_class]) ) + unset($this->widgets[$widget_class]); + } + + function _register_widgets() { + global $wp_registered_widgets; + $keys = array_keys($this->widgets); + $registered = array_keys($wp_registered_widgets); + $registered = array_map('_get_widget_id_base', $registered); + + foreach ( $keys as $key ) { + // don't register new widget if old widget with the same id is already registered + if ( in_array($this->widgets[$key]->id_base, $registered, true) ) { + unset($this->widgets[$key]); + continue; + } + + $this->widgets[$key]->_register(); + } + } +} + +/* Global Variables */ + +/** @ignore */ +global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates; + +/** + * Stores the sidebars, since many themes can have more than one. + * + * @global array $wp_registered_sidebars + * @since 2.2.0 + */ +$wp_registered_sidebars = array(); + +/** + * Stores the registered widgets. + * + * @global array $wp_registered_widgets + * @since 2.2.0 + */ +$wp_registered_widgets = array(); + +/** + * Stores the registered widget control (options). + * + * @global array $wp_registered_widget_controls + * @since 2.2.0 + */ +$wp_registered_widget_controls = array(); +$wp_registered_widget_updates = array(); + +/** + * Private + */ +$_wp_sidebars_widgets = array(); + +/** + * Private + */ + $_wp_deprecated_widgets_callbacks = array( + 'wp_widget_pages', + 'wp_widget_pages_control', + 'wp_widget_calendar', + 'wp_widget_calendar_control', + 'wp_widget_archives', + 'wp_widget_archives_control', + 'wp_widget_links', + 'wp_widget_meta', + 'wp_widget_meta_control', + 'wp_widget_search', + 'wp_widget_recent_entries', + 'wp_widget_recent_entries_control', + 'wp_widget_tag_cloud', + 'wp_widget_tag_cloud_control', + 'wp_widget_categories', + 'wp_widget_categories_control', + 'wp_widget_text', + 'wp_widget_text_control', + 'wp_widget_rss', + 'wp_widget_rss_control', + 'wp_widget_recent_comments', + 'wp_widget_recent_comments_control' + ); + +/* Template tags & API functions */ + +/** + * Register a widget + * + * Registers a WP_Widget widget + * + * @since 2.8.0 + * + * @see WP_Widget + * @see WP_Widget_Factory + * @uses WP_Widget_Factory + * + * @param string $widget_class The name of a class that extends WP_Widget + */ +function register_widget($widget_class) { + global $wp_widget_factory; + + $wp_widget_factory->register($widget_class); +} + +/** + * Unregister a widget + * + * Unregisters a WP_Widget widget. Useful for unregistering default widgets. + * Run within a function hooked to the widgets_init action. + * + * @since 2.8.0 + * + * @see WP_Widget + * @see WP_Widget_Factory + * @uses WP_Widget_Factory + * + * @param string $widget_class The name of a class that extends WP_Widget + */ +function unregister_widget($widget_class) { + global $wp_widget_factory; + + $wp_widget_factory->unregister($widget_class); +} + +/** + * Creates multiple sidebars. + * + * If you wanted to quickly create multiple sidebars for a theme or internally. + * This function will allow you to do so. If you don't pass the 'name' and/or + * 'id' in $args, then they will be built for you. + * + * The default for the name is "Sidebar #", with '#' being replaced with the + * number the sidebar is currently when greater than one. If first sidebar, the + * name will be just "Sidebar". The default for id is "sidebar-" followed by the + * number the sidebar creation is currently at. If the id is provided, and mutliple + * sidebars are being defined, the id will have "-2" appended, and so on. + * + * @since 2.2.0 + * + * @see register_sidebar() The second parameter is documented by register_sidebar() and is the same here. + * @uses parse_str() Converts a string to an array to be used in the rest of the function. + * @uses register_sidebar() Sends single sidebar information [name, id] to this + * function to handle building the sidebar. + * + * @param int $number Number of sidebars to create. + * @param string|array $args Builds Sidebar based off of 'name' and 'id' values. + */ +function register_sidebars($number = 1, $args = array()) { + global $wp_registered_sidebars; + $number = (int) $number; + + if ( is_string($args) ) + parse_str($args, $args); + + for ( $i = 1; $i <= $number; $i++ ) { + $_args = $args; + + if ( $number > 1 ) + $_args['name'] = isset($args['name']) ? sprintf($args['name'], $i) : sprintf(__('Sidebar %d'), $i); + else + $_args['name'] = isset($args['name']) ? $args['name'] : __('Sidebar'); + + // Custom specified ID's are suffixed if they exist already. + // Automatically generated sidebar names need to be suffixed regardless starting at -0 + if ( isset($args['id']) ) { + $_args['id'] = $args['id']; + $n = 2; // Start at -2 for conflicting custom ID's + while ( isset($wp_registered_sidebars[$_args['id']]) ) + $_args['id'] = $args['id'] . '-' . $n++; + } else { + $n = count($wp_registered_sidebars); + do { + $_args['id'] = 'sidebar-' . ++$n; + } while ( isset($wp_registered_sidebars[$_args['id']]) ); + } + register_sidebar($_args); + } +} + +/** + * Builds the definition for a single sidebar and returns the ID. + * + * The $args parameter takes either a string or an array with 'name' and 'id' + * contained in either usage. It will be noted that the values will be applied + * to all sidebars, so if creating more than one, it will be advised to allow + * for WordPress to create the defaults for you. + * + * Example for string would be 'name=whatever;id=whatever1' and for + * the array it would be array( + * 'name' => 'whatever', + * 'id' => 'whatever1'). + * + * name - The name of the sidebar, which presumably the title which will be + * displayed. + * id - The unique identifier by which the sidebar will be called by. + * before_widget - The content that will prepended to the widgets when they are + * displayed. + * after_widget - The content that will be appended to the widgets when they are + * displayed. + * before_title - The content that will be prepended to the title when displayed. + * after_title - the content that will be appended to the title when displayed. + * + * Content is assumed to be HTML and should be formatted as such, but + * doesn't have to be. + * + * @since 2.2.0 + * @uses $wp_registered_sidebars Stores the new sidebar in this array by sidebar ID. + * + * @param string|array $args Builds Sidebar based off of 'name' and 'id' values + * @return string The sidebar id that was added. + */ +function register_sidebar($args = array()) { + global $wp_registered_sidebars; + + $i = count($wp_registered_sidebars) + 1; + + $defaults = array( + 'name' => sprintf(__('Sidebar %d'), $i ), + 'id' => "sidebar-$i", + 'description' => '', + 'before_widget' => '
  • ', + 'after_widget' => "
  • \n", + 'before_title' => '

    ', + 'after_title' => "

    \n", + ); + + $sidebar = wp_parse_args( $args, $defaults ); + + $wp_registered_sidebars[$sidebar['id']] = $sidebar; + + add_theme_support('widgets'); + + do_action( 'register_sidebar', $sidebar ); + + return $sidebar['id']; +} + +/** + * Removes a sidebar from the list. + * + * @since 2.2.0 + * + * @uses $wp_registered_sidebars Stores the new sidebar in this array by sidebar ID. + * + * @param string $name The ID of the sidebar when it was added. + */ +function unregister_sidebar( $name ) { + global $wp_registered_sidebars; + + if ( isset( $wp_registered_sidebars[$name] ) ) + unset( $wp_registered_sidebars[$name] ); +} + +/** + * Register widget for use in sidebars. + * + * The default widget option is 'classname' that can be override. + * + * The function can also be used to unregister widgets when $output_callback + * parameter is an empty string. + * + * @since 2.2.0 + * + * @uses $wp_registered_widgets Uses stored registered widgets. + * @uses $wp_register_widget_defaults Retrieves widget defaults. + * + * @param int|string $id Widget ID. + * @param string $name Widget display title. + * @param callback $output_callback Run when widget is called. + * @param array|string $options Optional. Widget Options. + * @param mixed $params,... Widget parameters to add to widget. + * @return null Will return if $output_callback is empty after removing widget. + */ +function wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) { + global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks; + + $id = strtolower($id); + + if ( empty($output_callback) ) { + unset($wp_registered_widgets[$id]); + return; + } + + $id_base = _get_widget_id_base($id); + if ( in_array($output_callback, $_wp_deprecated_widgets_callbacks, true) && !is_callable($output_callback) ) { + if ( isset($wp_registered_widget_controls[$id]) ) + unset($wp_registered_widget_controls[$id]); + + if ( isset($wp_registered_widget_updates[$id_base]) ) + unset($wp_registered_widget_updates[$id_base]); + + return; + } + + $defaults = array('classname' => $output_callback); + $options = wp_parse_args($options, $defaults); + $widget = array( + 'name' => $name, + 'id' => $id, + 'callback' => $output_callback, + 'params' => array_slice(func_get_args(), 4) + ); + $widget = array_merge($widget, $options); + + if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || did_action( 'widgets_init' ) ) ) { + do_action( 'wp_register_sidebar_widget', $widget ); + $wp_registered_widgets[$id] = $widget; + } +} + +/** + * Retrieve description for widget. + * + * When registering widgets, the options can also include 'description' that + * describes the widget for display on the widget administration panel or + * in the theme. + * + * @since 2.5.0 + * + * @param int|string $id Widget ID. + * @return string Widget description, if available. Null on failure to retrieve description. + */ +function wp_widget_description( $id ) { + if ( !is_scalar($id) ) + return; + + global $wp_registered_widgets; + + if ( isset($wp_registered_widgets[$id]['description']) ) + return esc_html( $wp_registered_widgets[$id]['description'] ); +} + +/** + * Retrieve description for a sidebar. + * + * When registering sidebars a 'description' parameter can be included that + * describes the sidebar for display on the widget administration panel. + * + * @since 2.9.0 + * + * @param int|string $id sidebar ID. + * @return string Sidebar description, if available. Null on failure to retrieve description. + */ +function wp_sidebar_description( $id ) { + if ( !is_scalar($id) ) + return; + + global $wp_registered_sidebars; + + if ( isset($wp_registered_sidebars[$id]['description']) ) + return esc_html( $wp_registered_sidebars[$id]['description'] ); +} + + +/** + * Remove widget from sidebar. + * + * @since 2.2.0 + * + * @param int|string $id Widget ID. + */ +function wp_unregister_sidebar_widget($id) { + do_action( 'wp_unregister_sidebar_widget', $id ); + + wp_register_sidebar_widget($id, '', ''); + wp_unregister_widget_control($id); +} + +/** + * Registers widget control callback for customizing options. + * + * The options contains the 'height', 'width', and 'id_base' keys. The 'height' + * option is never used. The 'width' option is the width of the fully expanded + * control form, but try hard to use the default width. The 'id_base' is for + * multi-widgets (widgets which allow multiple instances such as the text + * widget), an id_base must be provided. The widget id will end up looking like + * {$id_base}-{$unique_number}. + * + * @since 2.2.0 + * + * @param int|string $id Sidebar ID. + * @param string $name Sidebar display name. + * @param callback $control_callback Run when sidebar is displayed. + * @param array|string $options Optional. Widget options. See above long description. + * @param mixed $params,... Optional. Additional parameters to add to widget. + */ +function wp_register_widget_control($id, $name, $control_callback, $options = array()) { + global $wp_registered_widget_controls, $wp_registered_widget_updates, $wp_registered_widgets, $_wp_deprecated_widgets_callbacks; + + $id = strtolower($id); + $id_base = _get_widget_id_base($id); + + if ( empty($control_callback) ) { + unset($wp_registered_widget_controls[$id]); + unset($wp_registered_widget_updates[$id_base]); + return; + } + + if ( in_array($control_callback, $_wp_deprecated_widgets_callbacks, true) && !is_callable($control_callback) ) { + if ( isset($wp_registered_widgets[$id]) ) + unset($wp_registered_widgets[$id]); + + return; + } + + if ( isset($wp_registered_widget_controls[$id]) && !did_action( 'widgets_init' ) ) + return; + + $defaults = array('width' => 250, 'height' => 200 ); // height is never used + $options = wp_parse_args($options, $defaults); + $options['width'] = (int) $options['width']; + $options['height'] = (int) $options['height']; + + $widget = array( + 'name' => $name, + 'id' => $id, + 'callback' => $control_callback, + 'params' => array_slice(func_get_args(), 4) + ); + $widget = array_merge($widget, $options); + + $wp_registered_widget_controls[$id] = $widget; + + if ( isset($wp_registered_widget_updates[$id_base]) ) + return; + + if ( isset($widget['params'][0]['number']) ) + $widget['params'][0]['number'] = -1; + + unset($widget['width'], $widget['height'], $widget['name'], $widget['id']); + $wp_registered_widget_updates[$id_base] = $widget; +} + +function _register_widget_update_callback($id_base, $update_callback, $options = array()) { + global $wp_registered_widget_updates; + + if ( isset($wp_registered_widget_updates[$id_base]) ) { + if ( empty($update_callback) ) + unset($wp_registered_widget_updates[$id_base]); + return; + } + + $widget = array( + 'callback' => $update_callback, + 'params' => array_slice(func_get_args(), 3) + ); + + $widget = array_merge($widget, $options); + $wp_registered_widget_updates[$id_base] = $widget; +} + +function _register_widget_form_callback($id, $name, $form_callback, $options = array()) { + global $wp_registered_widget_controls; + + $id = strtolower($id); + + if ( empty($form_callback) ) { + unset($wp_registered_widget_controls[$id]); + return; + } + + if ( isset($wp_registered_widget_controls[$id]) && !did_action( 'widgets_init' ) ) + return; + + $defaults = array('width' => 250, 'height' => 200 ); + $options = wp_parse_args($options, $defaults); + $options['width'] = (int) $options['width']; + $options['height'] = (int) $options['height']; + + $widget = array( + 'name' => $name, + 'id' => $id, + 'callback' => $form_callback, + 'params' => array_slice(func_get_args(), 4) + ); + $widget = array_merge($widget, $options); + + $wp_registered_widget_controls[$id] = $widget; +} + +/** + * Remove control callback for widget. + * + * @since 2.2.0 + * @uses wp_register_widget_control() Unregisters by using empty callback. + * + * @param int|string $id Widget ID. + */ +function wp_unregister_widget_control($id) { + return wp_register_widget_control($id, '', ''); +} + +/** + * Display dynamic sidebar. + * + * By default it displays the default sidebar or 'sidebar-1'. The 'sidebar-1' is + * not named by the theme, the actual name is '1', but 'sidebar-' is added to + * the registered sidebars for the name. If you named your sidebar 'after-post', + * then the parameter $index will still be 'after-post', but the lookup will be + * for 'sidebar-after-post'. + * + * It is confusing for the $index parameter, but just know that it should just + * work. When you register the sidebar in the theme, you will use the same name + * for this function or "Pay no heed to the man behind the curtain." Just accept + * it as an oddity of WordPress sidebar register and display. + * + * @since 2.2.0 + * + * @param int|string $index Optional, default is 1. Name or ID of dynamic sidebar. + * @return bool True, if widget sidebar was found and called. False if not found or not called. + */ +function dynamic_sidebar($index = 1) { + global $wp_registered_sidebars, $wp_registered_widgets; + + if ( is_int($index) ) { + $index = "sidebar-$index"; + } else { + $index = sanitize_title($index); + foreach ( (array) $wp_registered_sidebars as $key => $value ) { + if ( sanitize_title($value['name']) == $index ) { + $index = $key; + break; + } + } + } + + $sidebars_widgets = wp_get_sidebars_widgets(); + + if ( empty($wp_registered_sidebars[$index]) || !array_key_exists($index, $sidebars_widgets) || !is_array($sidebars_widgets[$index]) || empty($sidebars_widgets[$index]) ) + return false; + + $sidebar = $wp_registered_sidebars[$index]; + + $did_one = false; + foreach ( (array) $sidebars_widgets[$index] as $id ) { + + if ( !isset($wp_registered_widgets[$id]) ) continue; + + $params = array_merge( + array( array_merge( $sidebar, array('widget_id' => $id, 'widget_name' => $wp_registered_widgets[$id]['name']) ) ), + (array) $wp_registered_widgets[$id]['params'] + ); + + // Substitute HTML id and class attributes into before_widget + $classname_ = ''; + foreach ( (array) $wp_registered_widgets[$id]['classname'] as $cn ) { + if ( is_string($cn) ) + $classname_ .= '_' . $cn; + elseif ( is_object($cn) ) + $classname_ .= '_' . get_class($cn); + } + $classname_ = ltrim($classname_, '_'); + $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_); + + $params = apply_filters( 'dynamic_sidebar_params', $params ); + + $callback = $wp_registered_widgets[$id]['callback']; + + do_action( 'dynamic_sidebar', $wp_registered_widgets[$id] ); + + if ( is_callable($callback) ) { + call_user_func_array($callback, $params); + $did_one = true; + } + } + + return $did_one; +} + +/** + * Whether widget is displayied on the front-end. + * + * Either $callback or $id_base can be used + * $id_base is the first argument when extending WP_Widget class + * Without the optional $widget_id parameter, returns the ID of the first sidebar + * in which the first instance of the widget with the given callback or $id_base is found. + * With the $widget_id parameter, returns the ID of the sidebar where + * the widget with that callback/$id_base AND that ID is found. + * + * NOTE: $widget_id and $id_base are the same for single widgets. To be effective + * this function has to run after widgets have initialized, at action 'init' or later. + * + * @since 2.2.0 + * + * @param string $callback Optional, Widget callback to check. + * @param int $widget_id Optional, but needed for checking. Widget ID. + * @param string $id_base Optional, the base ID of a widget created by extending WP_Widget. + * @param bool $skip_inactive Optional, whether to check in 'wp_inactive_widgets'. + * @return mixed false if widget is not active or id of sidebar in which the widget is active. + */ +function is_active_widget($callback = false, $widget_id = false, $id_base = false, $skip_inactive = true) { + global $wp_registered_widgets; + + $sidebars_widgets = wp_get_sidebars_widgets(); + + if ( is_array($sidebars_widgets) ) { + foreach ( $sidebars_widgets as $sidebar => $widgets ) { + if ( $skip_inactive && 'wp_inactive_widgets' == $sidebar ) + continue; + + if ( is_array($widgets) ) { + foreach ( $widgets as $widget ) { + if ( ( $callback && isset($wp_registered_widgets[$widget]['callback']) && $wp_registered_widgets[$widget]['callback'] == $callback ) || ( $id_base && _get_widget_id_base($widget) == $id_base ) ) { + if ( !$widget_id || $widget_id == $wp_registered_widgets[$widget]['id'] ) + return $sidebar; + } + } + } + } + } + return false; +} + +/** + * Whether the dynamic sidebar is enabled and used by theme. + * + * @since 2.2.0 + * + * @return bool True, if using widgets. False, if not using widgets. + */ +function is_dynamic_sidebar() { + global $wp_registered_widgets, $wp_registered_sidebars; + $sidebars_widgets = get_option('sidebars_widgets'); + foreach ( (array) $wp_registered_sidebars as $index => $sidebar ) { + if ( count($sidebars_widgets[$index]) ) { + foreach ( (array) $sidebars_widgets[$index] as $widget ) + if ( array_key_exists($widget, $wp_registered_widgets) ) + return true; + } + } + return false; +} + +/** + * Whether a sidebar is in use. + * + * @since 2.8 + * + * @param mixed $index Sidebar name, id or number to check. + * @return bool true if the sidebar is in use, false otherwise. + */ +function is_active_sidebar( $index ) { + $index = ( is_int($index) ) ? "sidebar-$index" : sanitize_title($index); + $sidebars_widgets = wp_get_sidebars_widgets(); + if ( !empty($sidebars_widgets[$index]) ) + return true; + + return false; +} + +/* Internal Functions */ + +/** + * Retrieve full list of sidebars and their widgets. + * + * Will upgrade sidebar widget list, if needed. Will also save updated list, if + * needed. + * + * @since 2.2.0 + * @access private + * + * @param bool $deprecated Not used (deprecated). + * @return array Upgraded list of widgets to version 3 array format when called from the admin. + */ +function wp_get_sidebars_widgets($deprecated = true) { + if ( $deprecated !== true ) + _deprecated_argument( __FUNCTION__, '2.8.1' ); + + global $wp_registered_widgets, $wp_registered_sidebars, $_wp_sidebars_widgets; + + // If loading from front page, consult $_wp_sidebars_widgets rather than options + // to see if wp_convert_widget_settings() has made manipulations in memory. + if ( !is_admin() ) { + if ( empty($_wp_sidebars_widgets) ) + $_wp_sidebars_widgets = get_option('sidebars_widgets', array()); + + $sidebars_widgets = $_wp_sidebars_widgets; + } else { + $sidebars_widgets = get_option('sidebars_widgets', array()); + $_sidebars_widgets = array(); + + if ( isset($sidebars_widgets['wp_inactive_widgets']) || empty($sidebars_widgets) ) + $sidebars_widgets['array_version'] = 3; + elseif ( !isset($sidebars_widgets['array_version']) ) + $sidebars_widgets['array_version'] = 1; + + switch ( $sidebars_widgets['array_version'] ) { + case 1 : + foreach ( (array) $sidebars_widgets as $index => $sidebar ) + if ( is_array($sidebar) ) + foreach ( (array) $sidebar as $i => $name ) { + $id = strtolower($name); + if ( isset($wp_registered_widgets[$id]) ) { + $_sidebars_widgets[$index][$i] = $id; + continue; + } + $id = sanitize_title($name); + if ( isset($wp_registered_widgets[$id]) ) { + $_sidebars_widgets[$index][$i] = $id; + continue; + } + + $found = false; + + foreach ( $wp_registered_widgets as $widget_id => $widget ) { + if ( strtolower($widget['name']) == strtolower($name) ) { + $_sidebars_widgets[$index][$i] = $widget['id']; + $found = true; + break; + } elseif ( sanitize_title($widget['name']) == sanitize_title($name) ) { + $_sidebars_widgets[$index][$i] = $widget['id']; + $found = true; + break; + } + } + + if ( $found ) + continue; + + unset($_sidebars_widgets[$index][$i]); + } + $_sidebars_widgets['array_version'] = 2; + $sidebars_widgets = $_sidebars_widgets; + unset($_sidebars_widgets); + + case 2 : + $sidebars = array_keys( $wp_registered_sidebars ); + if ( !empty( $sidebars ) ) { + // Move the known-good ones first + foreach ( (array) $sidebars as $id ) { + if ( array_key_exists( $id, $sidebars_widgets ) ) { + $_sidebars_widgets[$id] = $sidebars_widgets[$id]; + unset($sidebars_widgets[$id], $sidebars[$id]); + } + } + + // move the rest to wp_inactive_widgets + if ( !isset($_sidebars_widgets['wp_inactive_widgets']) ) + $_sidebars_widgets['wp_inactive_widgets'] = array(); + + if ( !empty($sidebars_widgets) ) { + foreach ( $sidebars_widgets as $lost => $val ) { + if ( is_array($val) ) + $_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $val ); + } + } + + $sidebars_widgets = $_sidebars_widgets; + unset($_sidebars_widgets); + } + } + } + + if ( is_array( $sidebars_widgets ) && isset($sidebars_widgets['array_version']) ) + unset($sidebars_widgets['array_version']); + + $sidebars_widgets = apply_filters('sidebars_widgets', $sidebars_widgets); + return $sidebars_widgets; +} + +/** + * Set the sidebar widget option to update sidebars. + * + * @since 2.2.0 + * @access private + * + * @param array $sidebars_widgets Sidebar widgets and their settings. + */ +function wp_set_sidebars_widgets( $sidebars_widgets ) { + if ( !isset( $sidebars_widgets['array_version'] ) ) + $sidebars_widgets['array_version'] = 3; + update_option( 'sidebars_widgets', $sidebars_widgets ); +} + +/** + * Retrieve default registered sidebars list. + * + * @since 2.2.0 + * @access private + * + * @return array + */ +function wp_get_widget_defaults() { + global $wp_registered_sidebars; + + $defaults = array(); + + foreach ( (array) $wp_registered_sidebars as $index => $sidebar ) + $defaults[$index] = array(); + + return $defaults; +} + +/** + * Convert the widget settings from single to multi-widget format. + * + * @since 2.8.0 + * + * @return array + */ +function wp_convert_widget_settings($base_name, $option_name, $settings) { + // This test may need expanding. + $single = $changed = false; + if ( empty($settings) ) { + $single = true; + } else { + foreach ( array_keys($settings) as $number ) { + if ( 'number' == $number ) + continue; + if ( !is_numeric($number) ) { + $single = true; + break; + } + } + } + + if ( $single ) { + $settings = array( 2 => $settings ); + + // If loading from the front page, update sidebar in memory but don't save to options + if ( is_admin() ) { + $sidebars_widgets = get_option('sidebars_widgets'); + } else { + if ( empty($GLOBALS['_wp_sidebars_widgets']) ) + $GLOBALS['_wp_sidebars_widgets'] = get_option('sidebars_widgets', array()); + $sidebars_widgets = &$GLOBALS['_wp_sidebars_widgets']; + } + + foreach ( (array) $sidebars_widgets as $index => $sidebar ) { + if ( is_array($sidebar) ) { + foreach ( $sidebar as $i => $name ) { + if ( $base_name == $name ) { + $sidebars_widgets[$index][$i] = "$name-2"; + $changed = true; + break 2; + } + } + } + } + + if ( is_admin() && $changed ) + update_option('sidebars_widgets', $sidebars_widgets); + } + + $settings['_multiwidget'] = 1; + if ( is_admin() ) + update_option( $option_name, $settings ); + + return $settings; +} + +/** + * Output an arbitrary widget as a template tag + * + * @since 2.8 + * + * @param string $widget the widget's PHP class name (see default-widgets.php) + * @param array $instance the widget's instance settings + * @param array $args the widget's sidebar args + * @return void + **/ +function the_widget($widget, $instance = array(), $args = array()) { + global $wp_widget_factory; + + $widget_obj = $wp_widget_factory->widgets[$widget]; + if ( !is_a($widget_obj, 'WP_Widget') ) + return; + + $before_widget = sprintf('
    ', $widget_obj->widget_options['classname']); + $default_args = array('before_widget' => $before_widget, 'after_widget' => "
    ", 'before_title' => '

    ', 'after_title' => '

    '); + + $args = wp_parse_args($args, $default_args); + $instance = wp_parse_args($instance); + + do_action( 'the_widget', $widget, $instance, $args ); + + $widget_obj->_set(-1); + $widget_obj->widget($args, $instance); +} + +/** + * Private + */ +function _get_widget_id_base($id) { + return preg_replace( '/-[0-9]+$/', '', $id ); +} diff --git a/src/wp-includes/wlwmanifest.xml b/src/wp-includes/wlwmanifest.xml new file mode 100644 index 00000000..eb131473 --- /dev/null +++ b/src/wp-includes/wlwmanifest.xml @@ -0,0 +1,44 @@ + + + + + + WordPress + Yes + Yes + + + + WordPress + images/wlw/wp-icon.png + images/wlw/wp-watermark.png + View site + Dashboard + + + + + + + + + + + + + + + diff --git a/src/wp-includes/wp-db.php b/src/wp-includes/wp-db.php new file mode 100644 index 00000000..2b4ec28a --- /dev/null +++ b/src/wp-includes/wp-db.php @@ -0,0 +1,1571 @@ + '%d' + * + * @since 2.8.0 + * @see wpdb:prepare() + * @see wpdb:insert() + * @see wpdb:update() + * @see wp_set_wpdb_vars() + * @access public + * @var array + */ + var $field_types = array(); + + /** + * Database table columns charset + * + * @since 2.2.0 + * @access public + * @var string + */ + var $charset; + + /** + * Database table columns collate + * + * @since 2.2.0 + * @access public + * @var string + */ + var $collate; + + /** + * Whether to use mysql_real_escape_string + * + * @since 2.8.0 + * @access public + * @var bool + */ + var $real_escape = false; + + /** + * Database Username + * + * @since 2.9.0 + * @access private + * @var string + */ + var $dbuser; + + /** + * A textual description of the last query/get_row/get_var call + * + * @since 3.0.0 + * @access public + * @var string + */ + var $func_call; + + /** + * Connects to the database server and selects a database + * + * PHP4 compatibility layer for calling the PHP5 constructor. + * + * @uses wpdb::__construct() Passes parameters and returns result + * @since 0.71 + * + * @param string $dbuser MySQL database user + * @param string $dbpassword MySQL database password + * @param string $dbname MySQL database name + * @param string $dbhost MySQL database host + */ + function wpdb( $dbuser, $dbpassword, $dbname, $dbhost ) { + return $this->__construct( $dbuser, $dbpassword, $dbname, $dbhost ); + } + + /** + * Connects to the database server and selects a database + * + * PHP5 style constructor for compatibility with PHP5. Does + * the actual setting up of the class properties and connection + * to the database. + * + * @link http://core.trac.wordpress.org/ticket/3354 + * @since 2.0.8 + * + * @param string $dbuser MySQL database user + * @param string $dbpassword MySQL database password + * @param string $dbname MySQL database name + * @param string $dbhost MySQL database host + */ + function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) { + register_shutdown_function( array( &$this, '__destruct' ) ); + + if ( WP_DEBUG ) + $this->show_errors(); + + $this->init_charset(); + + $this->dbuser = $dbuser; + $this->dbpassword = $dbpassword; + $this->dbname = $dbname; + $this->dbhost = $dbhost; + + $this->db_connect(); + } + + /** + * PHP5 style destructor and will run when database object is destroyed. + * + * @see wpdb::__construct() + * @since 2.0.8 + * @return bool true + */ + function __destruct() { + return true; + } + + /** + * Set $this->charset and $this->collate + * + * @since 3.1.0 + */ + function init_charset() { + if ( function_exists('is_multisite') && is_multisite() ) { + $this->charset = 'utf8'; + if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) + $this->collate = DB_COLLATE; + else + $this->collate = 'utf8_general_ci'; + } elseif ( defined( 'DB_COLLATE' ) ) { + $this->collate = DB_COLLATE; + } + + if ( defined( 'DB_CHARSET' ) ) + $this->charset = DB_CHARSET; + } + + /** + * Sets the connection's character set. + * + * @since 3.1.0 + * + * @param resource $dbh The resource given by mysql_connect + * @param string $charset The character set (optional) + * @param string $collate The collation (optional) + */ + function set_charset($dbh, $charset = null, $collate = null) { + if ( !isset($charset) ) + $charset = $this->charset; + if ( !isset($collate) ) + $collate = $this->collate; + if ( $this->has_cap( 'collation', $dbh ) && !empty( $charset ) ) { + if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset', $dbh ) ) { + mysql_set_charset( $charset, $dbh ); + $this->real_escape = true; + } else { + $query = $this->prepare( 'SET NAMES %s', $charset ); + if ( ! empty( $collate ) ) + $query .= $this->prepare( ' COLLATE %s', $collate ); + mysql_query( $query, $dbh ); + } + } + } + + /** + * Sets the table prefix for the WordPress tables. + * + * @since 2.5.0 + * + * @param string $prefix Alphanumeric name for the new prefix. + * @return string|WP_Error Old prefix or WP_Error on error + */ + function set_prefix( $prefix, $set_table_names = true ) { + + if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) + return new WP_Error('invalid_db_prefix', /*WP_I18N_DB_BAD_PREFIX*/'Prefijo de la base de datos no válido'/*/WP_I18N_DB_BAD_PREFIX*/); + + $old_prefix = is_multisite() ? '' : $prefix; + + if ( isset( $this->base_prefix ) ) + $old_prefix = $this->base_prefix; + + $this->base_prefix = $prefix; + + if ( $set_table_names ) { + foreach ( $this->tables( 'global' ) as $table => $prefixed_table ) + $this->$table = $prefixed_table; + + if ( is_multisite() && empty( $this->blogid ) ) + return $old_prefix; + + $this->prefix = $this->get_blog_prefix(); + + foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) + $this->$table = $prefixed_table; + + foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) + $this->$table = $prefixed_table; + } + return $old_prefix; + } + + /** + * Sets blog id. + * + * @since 3.0.0 + * @access public + * @param int $blog_id + * @param int $site_id Optional. + * @return string previous blog id + */ + function set_blog_id( $blog_id, $site_id = 0 ) { + if ( ! empty( $site_id ) ) + $this->siteid = $site_id; + + $old_blog_id = $this->blogid; + $this->blogid = $blog_id; + + $this->prefix = $this->get_blog_prefix(); + + foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) + $this->$table = $prefixed_table; + + foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) + $this->$table = $prefixed_table; + + return $old_blog_id; + } + + /** + * Gets blog prefix. + * + * @uses is_multisite() + * @since 3.0.0 + * @param int $blog_id Optional. + * @return string Blog prefix. + */ + function get_blog_prefix( $blog_id = null ) { + if ( is_multisite() ) { + if ( null === $blog_id ) + $blog_id = $this->blogid; + if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) ) + return $this->base_prefix; + else + return $this->base_prefix . $blog_id . '_'; + } else { + return $this->base_prefix; + } + } + + /** + * Returns an array of WordPress tables. + * + * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to + * override the WordPress users and usersmeta tables that would otherwise + * be determined by the prefix. + * + * The scope argument can take one of the following: + * + * 'all' - returns 'all' and 'global' tables. No old tables are returned. + * 'blog' - returns the blog-level tables for the queried blog. + * 'global' - returns the global tables for the installation, returning multisite tables only if running multisite. + * 'ms_global' - returns the multisite global tables, regardless if current installation is multisite. + * 'old' - returns tables which are deprecated. + * + * @since 3.0.0 + * @uses wpdb::$tables + * @uses wpdb::$old_tables + * @uses wpdb::$global_tables + * @uses wpdb::$ms_global_tables + * @uses is_multisite() + * + * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all. + * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog + * prefix is requested, then the custom users and usermeta tables will be mapped. + * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested. + * @return array Table names. When a prefix is requested, the key is the unprefixed table name. + */ + function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) { + switch ( $scope ) { + case 'all' : + $tables = array_merge( $this->global_tables, $this->tables ); + if ( is_multisite() ) + $tables = array_merge( $tables, $this->ms_global_tables ); + break; + case 'blog' : + $tables = $this->tables; + break; + case 'global' : + $tables = $this->global_tables; + if ( is_multisite() ) + $tables = array_merge( $tables, $this->ms_global_tables ); + break; + case 'ms_global' : + $tables = $this->ms_global_tables; + break; + case 'old' : + $tables = $this->old_tables; + break; + default : + return array(); + break; + } + + if ( $prefix ) { + if ( ! $blog_id ) + $blog_id = $this->blogid; + $blog_prefix = $this->get_blog_prefix( $blog_id ); + $base_prefix = $this->base_prefix; + $global_tables = array_merge( $this->global_tables, $this->ms_global_tables ); + foreach ( $tables as $k => $table ) { + if ( in_array( $table, $global_tables ) ) + $tables[ $table ] = $base_prefix . $table; + else + $tables[ $table ] = $blog_prefix . $table; + unset( $tables[ $k ] ); + } + + if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) ) + $tables['users'] = CUSTOM_USER_TABLE; + + if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) ) + $tables['usermeta'] = CUSTOM_USER_META_TABLE; + } + + return $tables; + } + + /** + * Selects a database using the current database connection. + * + * The database name will be changed based on the current database + * connection. On failure, the execution will bail and display an DB error. + * + * @since 0.71 + * + * @param string $db MySQL database name + * @param resource $dbh Optional link identifier. + * @return null Always null. + */ + function select( $db, $dbh = null) { + if ( is_null($dbh) ) + $dbh = $this->dbh; + + if ( !@mysql_select_db( $db, $dbh ) ) { + $this->ready = false; + $this->bail( sprintf( /*WP_I18N_DB_SELECT_DB*/'

    No se pudo elegir base de datos

    +

    Hemos podido conectar con el servidor de la bases de datos (lo que significa que tu nombre de usuario y la contraseña están correctos) pero no se pudo elegir la base de datos %1$s.

    +
      +
    • ¿Estás seguro que existe?
    • +
    • ¿El usuario %2$s tiene permiso para utilizar la base de datos %1$?
    • +
    • En algunos sistemas el nombre de la base de datos es el prefijo con el nombre de usuario, que sería como username_%1$s. ¿Podría ser ésto el problema?
    • +
    +

    Si no sabes cómo configurar una base de datos debes ponerte en contacto con el administrador de su hosting. Si todo lo demás falla puedes encontrar ayuda en los Foros de Soporte de WordPress.

    '/*/WP_I18N_DB_SELECT_DB*/, $db, $this->dbuser ), 'db_select_fail' ); + return; + } + } + + /** + * Weak escape, using addslashes() + * + * @see addslashes() + * @since 2.8.0 + * @access private + * + * @param string $string + * @return string + */ + function _weak_escape( $string ) { + return addslashes( $string ); + } + + /** + * Real escape, using mysql_real_escape_string() or addslashes() + * + * @see mysql_real_escape_string() + * @see addslashes() + * @since 2.8.0 + * @access private + * + * @param string $string to escape + * @return string escaped + */ + function _real_escape( $string ) { + if ( $this->dbh && $this->real_escape ) + return mysql_real_escape_string( $string, $this->dbh ); + else + return addslashes( $string ); + } + + /** + * Escape data. Works on arrays. + * + * @uses wpdb::_escape() + * @uses wpdb::_real_escape() + * @since 2.8.0 + * @access private + * + * @param string|array $data + * @return string|array escaped + */ + function _escape( $data ) { + if ( is_array( $data ) ) { + foreach ( (array) $data as $k => $v ) { + if ( is_array($v) ) + $data[$k] = $this->_escape( $v ); + else + $data[$k] = $this->_real_escape( $v ); + } + } else { + $data = $this->_real_escape( $data ); + } + + return $data; + } + + /** + * Escapes content for insertion into the database using addslashes(), for security. + * + * Works on arrays. + * + * @since 0.71 + * @param string|array $data to escape + * @return string|array escaped as query safe string + */ + function escape( $data ) { + if ( is_array( $data ) ) { + foreach ( (array) $data as $k => $v ) { + if ( is_array( $v ) ) + $data[$k] = $this->escape( $v ); + else + $data[$k] = $this->_weak_escape( $v ); + } + } else { + $data = $this->_weak_escape( $data ); + } + + return $data; + } + + /** + * Escapes content by reference for insertion into the database, for security + * + * @uses wpdb::_real_escape() + * @since 2.3.0 + * @param string $string to escape + * @return void + */ + function escape_by_ref( &$string ) { + $string = $this->_real_escape( $string ); + } + + /** + * Prepares a SQL query for safe execution. Uses sprintf()-like syntax. + * + * The following directives can be used in the query format string: + * %d (decimal number) + * %s (string) + * %% (literal percentage sign - no argument needed) + * + * Both %d and %s are to be left unquoted in the query string and they need an argument passed for them. + * Literals (%) as parts of the query must be properly written as %%. + * + * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string). + * Does not support sign, padding, alignment, width or precision specifiers. + * Does not support argument numbering/swapping. + * + * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}. + * + * Both %d and %s should be left unquoted in the query string. + * + * + * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 ) + * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' ); + * + * + * @link http://php.net/sprintf Description of syntax. + * @since 2.3.0 + * + * @param string $query Query statement with sprintf()-like placeholders + * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like + * {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if + * being called like {@link http://php.net/sprintf sprintf()}. + * @param mixed $args,... further variables to substitute into the query's placeholders if being called like + * {@link http://php.net/sprintf sprintf()}. + * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string + * if there was something to prepare + */ + function prepare( $query = null ) { // ( $query, *$args ) + if ( is_null( $query ) ) + return; + + $args = func_get_args(); + array_shift( $args ); + // If args were passed as an array (as in vsprintf), move them up + if ( isset( $args[0] ) && is_array($args[0]) ) + $args = $args[0]; + $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it + $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting + $query = preg_replace( '|(?dbh ); + $EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str ); + + if ( $this->suppress_errors ) + return false; + + if ( $caller = $this->get_caller() ) + $error_str = sprintf( /*WP_I18N_DB_QUERY_ERROR_FULL*/'Error %1$s de la base de datos de WordPress para la consulta %2$s realizada por %3$s'/*/WP_I18N_DB_QUERY_ERROR_FULL*/, $str, $this->last_query, $caller ); + else + $error_str = sprintf( /*WP_I18N_DB_QUERY_ERROR*/'Error %1$s de la base de datos de WordPress para la consulta %2$s'/*/WP_I18N_DB_QUERY_ERROR*/, $str, $this->last_query ); + + if ( function_exists( 'error_log' ) + && ( $log_file = @ini_get( 'error_log' ) ) + && ( 'syslog' == $log_file || @is_writable( $log_file ) ) + ) + @error_log( $error_str ); + + // Are we showing errors? + if ( ! $this->show_errors ) + return false; + + // If there is an error then take note of it + if ( is_multisite() ) { + $msg = "WordPress database error: [$str]\n{$this->last_query}\n"; + if ( defined( 'ERRORLOGFILE' ) ) + error_log( $msg, 3, ERRORLOGFILE ); + if ( defined( 'DIEONDBERROR' ) ) + wp_die( $msg ); + } else { + $str = htmlspecialchars( $str, ENT_QUOTES ); + $query = htmlspecialchars( $this->last_query, ENT_QUOTES ); + + print "
    +

    WordPress database error: [$str]
    + $query

    +
    "; + } + } + + /** + * Enables showing of database errors. + * + * This function should be used only to enable showing of errors. + * wpdb::hide_errors() should be used instead for hiding of errors. However, + * this function can be used to enable and disable showing of database + * errors. + * + * @since 0.71 + * @see wpdb::hide_errors() + * + * @param bool $show Whether to show or hide errors + * @return bool Old value for showing errors. + */ + function show_errors( $show = true ) { + $errors = $this->show_errors; + $this->show_errors = $show; + return $errors; + } + + /** + * Disables showing of database errors. + * + * By default database errors are not shown. + * + * @since 0.71 + * @see wpdb::show_errors() + * + * @return bool Whether showing of errors was active + */ + function hide_errors() { + $show = $this->show_errors; + $this->show_errors = false; + return $show; + } + + /** + * Whether to suppress database errors. + * + * By default database errors are suppressed, with a simple + * call to this function they can be enabled. + * + * @since 2.5.0 + * @see wpdb::hide_errors() + * @param bool $suppress Optional. New value. Defaults to true. + * @return bool Old value + */ + function suppress_errors( $suppress = true ) { + $errors = $this->suppress_errors; + $this->suppress_errors = (bool) $suppress; + return $errors; + } + + /** + * Kill cached query results. + * + * @since 0.71 + * @return void + */ + function flush() { + $this->last_result = array(); + $this->col_info = null; + $this->last_query = null; + } + + /** + * Connect to and select database + * + * @since 3.0.0 + */ + function db_connect() { + global $db_list, $global_db_list; + + if ( WP_DEBUG ) { + $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true ); + } else { + $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true ); + } + + if ( !$this->dbh ) { + $this->bail( sprintf( /*WP_I18N_DB_CONN_ERROR*/' +

    Error de conexión con la base de datos

    +

    Esto puede deberse a que los datos de usuario y contraseña de tu wp-config.php son incorrectos o a que no es posible contactar con el servidor de base de datos en %s, lo que podría significar que el servidor de bases de datos de tu host está inactivo.

    +
      +
    • ¿Estás seguro de que el nombre de usuario y la contraseña son correctos?
    • +
    • ¿Estás seguro de que el nombre del host es correcto?
    • +
    • ¿Estás seguro de que el servidor de bases de datos está activo?
    • +
    +

    Si no tienes muy claro lo que significan los términos anteriores, ponte en contacto con tu proveedor de alojamiento. Si necesitas más ayuda, puedes visitar los Foros de ayuda de WordPress.

    +'/*/WP_I18N_DB_CONN_ERROR*/, $this->dbhost ), 'db_connect_fail' ); + + return; + } + + $this->set_charset( $this->dbh ); + + $this->ready = true; + + $this->select( $this->dbname, $this->dbh ); + } + + /** + * Perform a MySQL database query, using current database connection. + * + * More information can be found on the codex page. + * + * @since 0.71 + * + * @param string $query Database query + * @return int|false Number of rows affected/selected or false on error + */ + function query( $query ) { + if ( ! $this->ready ) + return false; + + // some queries are made before the plugins have been loaded, and thus cannot be filtered with this method + if ( function_exists( 'apply_filters' ) ) + $query = apply_filters( 'query', $query ); + + $return_val = 0; + $this->flush(); + + // Log how the function was called + $this->func_call = "\$db->query(\"$query\")"; + + // Keep track of the last query for debug.. + $this->last_query = $query; + + if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) + $this->timer_start(); + + $this->result = @mysql_query( $query, $this->dbh ); + $this->num_queries++; + + if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) + $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); + + // If there is an error then take note of it.. + if ( $this->last_error = mysql_error( $this->dbh ) ) { + $this->print_error(); + return false; + } + + if ( preg_match( "/^\\s*(insert|delete|update|replace|alter) /i", $query ) ) { + $this->rows_affected = mysql_affected_rows( $this->dbh ); + // Take note of the insert_id + if ( preg_match( "/^\\s*(insert|replace) /i", $query ) ) { + $this->insert_id = mysql_insert_id($this->dbh); + } + // Return number of rows affected + $return_val = $this->rows_affected; + } else { + $i = 0; + while ( $i < @mysql_num_fields( $this->result ) ) { + $this->col_info[$i] = @mysql_fetch_field( $this->result ); + $i++; + } + $num_rows = 0; + while ( $row = @mysql_fetch_object( $this->result ) ) { + $this->last_result[$num_rows] = $row; + $num_rows++; + } + + @mysql_free_result( $this->result ); + + // Log number of rows the query returned + // and return number of rows selected + $this->num_rows = $num_rows; + $return_val = $num_rows; + } + + return $return_val; + } + + /** + * Insert a row into a table. + * + * + * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) ) + * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) ) + * + * + * @since 2.5.0 + * @see wpdb::prepare() + * @see wpdb::$field_types + * @see wp_set_wpdb_vars() + * + * @param string $table table name + * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data. + * A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. + * @return int|false The number of rows inserted, or false on error. + */ + function insert( $table, $data, $format = null ) { + return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' ); + } + + /** + * Replace a row into a table. + * + * + * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) ) + * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) ) + * + * + * @since 3.0.0 + * @see wpdb::prepare() + * @see wpdb::$field_types + * @see wp_set_wpdb_vars() + * + * @param string $table table name + * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data. + * A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. + * @return int|false The number of rows affected, or false on error. + */ + function replace( $table, $data, $format = null ) { + return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' ); + } + + /** + * Helper function for insert and replace. + * + * Runs an insert or replace query based on $type argument. + * + * @access private + * @since 3.0.0 + * @see wpdb::prepare() + * @see wpdb::$field_types + * @see wp_set_wpdb_vars() + * + * @param string $table table name + * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data. + * A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. + * @return int|false The number of rows affected, or false on error. + */ + function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) { + if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) + return false; + $formats = $format = (array) $format; + $fields = array_keys( $data ); + $formatted_fields = array(); + foreach ( $fields as $field ) { + if ( !empty( $format ) ) + $form = ( $form = array_shift( $formats ) ) ? $form : $format[0]; + elseif ( isset( $this->field_types[$field] ) ) + $form = $this->field_types[$field]; + else + $form = '%s'; + $formatted_fields[] = $form; + } + $sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES ('" . implode( "','", $formatted_fields ) . "')"; + return $this->query( $this->prepare( $sql, $data ) ); + } + + /** + * Update a row in the table + * + * + * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) ) + * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) ) + * + * + * @since 2.5.0 + * @see wpdb::prepare() + * @see wpdb::$field_types + * @see wp_set_wpdb_vars() + * + * @param string $table table name + * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw". + * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data. + * A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. + * @param array|string $format_where Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $where will be treated as strings. + * @return int|false The number of rows updated, or false on error. + */ + function update( $table, $data, $where, $format = null, $where_format = null ) { + if ( ! is_array( $data ) || ! is_array( $where ) ) + return false; + + $formats = $format = (array) $format; + $bits = $wheres = array(); + foreach ( (array) array_keys( $data ) as $field ) { + if ( !empty( $format ) ) + $form = ( $form = array_shift( $formats ) ) ? $form : $format[0]; + elseif ( isset($this->field_types[$field]) ) + $form = $this->field_types[$field]; + else + $form = '%s'; + $bits[] = "`$field` = {$form}"; + } + + $where_formats = $where_format = (array) $where_format; + foreach ( (array) array_keys( $where ) as $field ) { + if ( !empty( $where_format ) ) + $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0]; + elseif ( isset( $this->field_types[$field] ) ) + $form = $this->field_types[$field]; + else + $form = '%s'; + $wheres[] = "`$field` = {$form}"; + } + + $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres ); + return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) ); + } + + /** + * Retrieve one variable from the database. + * + * Executes a SQL query and returns the value from the SQL result. + * If the SQL result contains more than one column and/or more than one row, this function returns the value in the column and row specified. + * If $query is null, this function returns the value in the specified column and row from the previous SQL result. + * + * @since 0.71 + * + * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query. + * @param int $x Optional. Column of value to return. Indexed from 0. + * @param int $y Optional. Row of value to return. Indexed from 0. + * @return string|null Database query result (as string), or null on failure + */ + function get_var( $query = null, $x = 0, $y = 0 ) { + $this->func_call = "\$db->get_var(\"$query\", $x, $y)"; + if ( $query ) + $this->query( $query ); + + // Extract var out of cached results based x,y vals + if ( !empty( $this->last_result[$y] ) ) { + $values = array_values( get_object_vars( $this->last_result[$y] ) ); + } + + // If there is a value return it else return null + return ( isset( $values[$x] ) && $values[$x] !== '' ) ? $values[$x] : null; + } + + /** + * Retrieve one row from the database. + * + * Executes a SQL query and returns the row from the SQL result. + * + * @since 0.71 + * + * @param string|null $query SQL query. + * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...), + * a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively. + * @param int $y Optional. Row to return. Indexed from 0. + * @return mixed Database query result in format specifed by $output or null on failure + */ + function get_row( $query = null, $output = OBJECT, $y = 0 ) { + $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; + if ( $query ) + $this->query( $query ); + else + return null; + + if ( !isset( $this->last_result[$y] ) ) + return null; + + if ( $output == OBJECT ) { + return $this->last_result[$y] ? $this->last_result[$y] : null; + } elseif ( $output == ARRAY_A ) { + return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null; + } elseif ( $output == ARRAY_N ) { + return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null; + } else { + $this->print_error(/*WP_I18N_DB_GETROW_ERROR*/' $db->get_row(string query, output type, int offset) -- El tipo de salida (output) debe ser uno de estos: OBJECT, ARRAY_A, ARRAY_N'/*/WP_I18N_DB_GETROW_ERROR*/); + } + } + + /** + * Retrieve one column from the database. + * + * Executes a SQL query and returns the column from the SQL result. + * If the SQL result contains more than one column, this function returns the column specified. + * If $query is null, this function returns the specified column from the previous SQL result. + * + * @since 0.71 + * + * @param string|null $query Optional. SQL query. Defaults to previous query. + * @param int $x Optional. Column to return. Indexed from 0. + * @return array Database query result. Array indexed from 0 by SQL result row number. + */ + function get_col( $query = null , $x = 0 ) { + if ( $query ) + $this->query( $query ); + + $new_array = array(); + // Extract the column values + for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) { + $new_array[$i] = $this->get_var( null, $x, $i ); + } + return $new_array; + } + + /** + * Retrieve an entire SQL result set from the database (i.e., many rows) + * + * Executes a SQL query and returns the entire SQL result. + * + * @since 0.71 + * + * @param string $query SQL query. + * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number. + * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. + * With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded. + * @return mixed Database query results + */ + function get_results( $query = null, $output = OBJECT ) { + $this->func_call = "\$db->get_results(\"$query\", $output)"; + + if ( $query ) + $this->query( $query ); + else + return null; + + $new_array = array(); + if ( $output == OBJECT ) { + // Return an integer-keyed array of row objects + return $this->last_result; + } elseif ( $output == OBJECT_K ) { + // Return an array of row objects with keys from column 1 + // (Duplicates are discarded) + foreach ( $this->last_result as $row ) { + $key = array_shift( $var_by_ref = get_object_vars( $row ) ); + if ( ! isset( $new_array[ $key ] ) ) + $new_array[ $key ] = $row; + } + return $new_array; + } elseif ( $output == ARRAY_A || $output == ARRAY_N ) { + // Return an integer-keyed array of... + if ( $this->last_result ) { + foreach( (array) $this->last_result as $row ) { + if ( $output == ARRAY_N ) { + // ...integer-keyed row arrays + $new_array[] = array_values( get_object_vars( $row ) ); + } else { + // ...column name-keyed row arrays + $new_array[] = get_object_vars( $row ); + } + } + } + return $new_array; + } + return null; + } + + /** + * Retrieve column metadata from the last query. + * + * @since 0.71 + * + * @param string $info_type Optional. Type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill + * @param int $col_offset Optional. 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type + * @return mixed Column Results + */ + function get_col_info( $info_type = 'name', $col_offset = -1 ) { + if ( $this->col_info ) { + if ( $col_offset == -1 ) { + $i = 0; + $new_array = array(); + foreach( (array) $this->col_info as $col ) { + $new_array[$i] = $col->{$info_type}; + $i++; + } + return $new_array; + } else { + return $this->col_info[$col_offset]->{$info_type}; + } + } + } + + /** + * Starts the timer, for debugging purposes. + * + * @since 1.5.0 + * + * @return true + */ + function timer_start() { + $mtime = explode( ' ', microtime() ); + $this->time_start = $mtime[1] + $mtime[0]; + return true; + } + + /** + * Stops the debugging timer. + * + * @since 1.5.0 + * + * @return int Total time spent on the query, in milliseconds + */ + function timer_stop() { + $mtime = explode( ' ', microtime() ); + $time_end = $mtime[1] + $mtime[0]; + $time_total = $time_end - $this->time_start; + return $time_total; + } + + /** + * Wraps errors in a nice header and footer and dies. + * + * Will not die if wpdb::$show_errors is true + * + * @since 1.5.0 + * + * @param string $message The Error message + * @param string $error_code Optional. A Computer readable string to identify the error. + * @return false|void + */ + function bail( $message, $error_code = '500' ) { + if ( !$this->show_errors ) { + if ( class_exists( 'WP_Error' ) ) + $this->error = new WP_Error($error_code, $message); + else + $this->error = $message; + return false; + } + wp_die($message); + } + + /** + * Whether MySQL database is at least the required minimum version. + * + * @since 2.5.0 + * @uses $wp_version + * @uses $required_mysql_version + * + * @return WP_Error + */ + function check_database_version() { + global $wp_version, $required_mysql_version; + // Make sure the server has the required MySQL version + if ( version_compare($this->db_version(), $required_mysql_version, '<') ) + return new WP_Error('database_version', sprintf( __( 'ERROR: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version )); + } + + /** + * Whether the database supports collation. + * + * Called when WordPress is generating the table scheme. + * + * @since 2.5.0 + * + * @return bool True if collation is supported, false if version does not + */ + function supports_collation() { + return $this->has_cap( 'collation' ); + } + + /** + * Determine if a database supports a particular feature + * + * @since 2.7.0 + * @see wpdb::db_version() + * + * @param string $db_cap the feature + * @return bool + */ + function has_cap( $db_cap ) { + $version = $this->db_version(); + + switch ( strtolower( $db_cap ) ) { + case 'collation' : // @since 2.5.0 + case 'group_concat' : // @since 2.7 + case 'subqueries' : // @since 2.7 + return version_compare( $version, '4.1', '>=' ); + case 'set_charset' : + return version_compare($version, '5.0.7', '>='); + }; + + return false; + } + + /** + * Retrieve the name of the function that called wpdb. + * + * Searches up the list of functions until it reaches + * the one that would most logically had called this method. + * + * @since 2.5.0 + * + * @return string The name of the calling function + */ + function get_caller() { + $trace = array_reverse( debug_backtrace() ); + $caller = array(); + + foreach ( $trace as $call ) { + if ( isset( $call['class'] ) && __CLASS__ == $call['class'] ) + continue; // Filter out wpdb calls. + $caller[] = isset( $call['class'] ) ? "{$call['class']}->{$call['function']}" : $call['function']; + } + + return join( ', ', $caller ); + } + + /** + * The database version number. + * + * @since 2.7.0 + * + * @return false|string false on failure, version number on success + */ + function db_version() { + return preg_replace( '/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ) ); + } +} + +?> diff --git a/src/wp-includes/wp-diff.php b/src/wp-includes/wp-diff.php new file mode 100644 index 00000000..e2ceb9f7 --- /dev/null +++ b/src/wp-includes/wp-diff.php @@ -0,0 +1,478 @@ +$parent( $params ); + } + + /** + * @ignore + * + * @param string $header + * @return string + */ + function _startBlock( $header ) { + return ''; + } + + /** + * @ignore + * + * @param array $lines + * @param string $prefix + */ + function _lines( $lines, $prefix=' ' ) { + } + + /** + * @ignore + * + * @param string $line HTML-escape the value. + * @return string + */ + function addedLine( $line ) { + return "+{$line}"; + } + + /** + * @ignore + * + * @param string $line HTML-escape the value. + * @return string + */ + function deletedLine( $line ) { + return "-{$line}"; + } + + /** + * @ignore + * + * @param string $line HTML-escape the value. + * @return string + */ + function contextLine( $line ) { + return " {$line}"; + } + + /** + * @ignore + * + * @return string + */ + function emptyLine() { + return ' '; + } + + /** + * @ignore + * @access private + * + * @param array $lines + * @param bool $encode + * @return string + */ + function _added( $lines, $encode = true ) { + $r = ''; + foreach ($lines as $line) { + if ( $encode ) + $line = htmlspecialchars( $line ); + $r .= '' . $this->emptyLine() . $this->addedLine( $line ) . "\n"; + } + return $r; + } + + /** + * @ignore + * @access private + * + * @param array $lines + * @param bool $encode + * @return string + */ + function _deleted( $lines, $encode = true ) { + $r = ''; + foreach ($lines as $line) { + if ( $encode ) + $line = htmlspecialchars( $line ); + $r .= '' . $this->deletedLine( $line ) . $this->emptyLine() . "\n"; + } + return $r; + } + + /** + * @ignore + * @access private + * + * @param array $lines + * @param bool $encode + * @return string + */ + function _context( $lines, $encode = true ) { + $r = ''; + foreach ($lines as $line) { + if ( $encode ) + $line = htmlspecialchars( $line ); + $r .= '' . + $this->contextLine( $line ) . $this->contextLine( $line ) . "\n"; + } + return $r; + } + + /** + * Process changed lines to do word-by-word diffs for extra highlighting. + * + * (TRAC style) sometimes these lines can actually be deleted or added rows. + * We do additional processing to figure that out + * + * @access private + * @since 2.6.0 + * + * @param array $orig + * @param array $final + * @return string + */ + function _changed( $orig, $final ) { + $r = ''; + + // Does the aforementioned additional processing + // *_matches tell what rows are "the same" in orig and final. Those pairs will be diffed to get word changes + // match is numeric: an index in other column + // match is 'X': no match. It is a new row + // *_rows are column vectors for the orig column and the final column. + // row >= 0: an indix of the $orig or $final array + // row < 0: a blank row for that column + list($orig_matches, $final_matches, $orig_rows, $final_rows) = $this->interleave_changed_lines( $orig, $final ); + + + // These will hold the word changes as determined by an inline diff + $orig_diffs = array(); + $final_diffs = array(); + + // Compute word diffs for each matched pair using the inline diff + foreach ( $orig_matches as $o => $f ) { + if ( is_numeric($o) && is_numeric($f) ) { + $text_diff = new Text_Diff( 'auto', array( array($orig[$o]), array($final[$f]) ) ); + $renderer = new $this->inline_diff_renderer; + $diff = $renderer->render( $text_diff ); + + // If they're too different, don't include any or + if ( $diff_count = preg_match_all( '!(.*?|.*?)!', $diff, $diff_matches ) ) { + // length of all text between or + $stripped_matches = strlen(strip_tags( join(' ', $diff_matches[0]) )); + // since we count lengith of text between or (instead of picking just one), + // we double the length of chars not in those tags. + $stripped_diff = strlen(strip_tags( $diff )) * 2 - $stripped_matches; + $diff_ratio = $stripped_matches / $stripped_diff; + if ( $diff_ratio > $this->_diff_threshold ) + continue; // Too different. Don't save diffs. + } + + // Un-inline the diffs by removing del or ins + $orig_diffs[$o] = preg_replace( '|.*?|', '', $diff ); + $final_diffs[$f] = preg_replace( '|.*?|', '', $diff ); + } + } + + foreach ( array_keys($orig_rows) as $row ) { + // Both columns have blanks. Ignore them. + if ( $orig_rows[$row] < 0 && $final_rows[$row] < 0 ) + continue; + + // If we have a word based diff, use it. Otherwise, use the normal line. + if ( isset( $orig_diffs[$orig_rows[$row]] ) ) + $orig_line = $orig_diffs[$orig_rows[$row]]; + elseif ( isset( $orig[$orig_rows[$row]] ) ) + $orig_line = htmlspecialchars($orig[$orig_rows[$row]]); + else + $orig_line = ''; + + if ( isset( $final_diffs[$final_rows[$row]] ) ) + $final_line = $final_diffs[$final_rows[$row]]; + elseif ( isset( $final[$final_rows[$row]] ) ) + $final_line = htmlspecialchars($final[$final_rows[$row]]); + else + $final_line = ''; + + if ( $orig_rows[$row] < 0 ) { // Orig is blank. This is really an added row. + $r .= $this->_added( array($final_line), false ); + } elseif ( $final_rows[$row] < 0 ) { // Final is blank. This is really a deleted row. + $r .= $this->_deleted( array($orig_line), false ); + } else { // A true changed row. + $r .= '' . $this->deletedLine( $orig_line ) . $this->addedLine( $final_line ) . "\n"; + } + } + + return $r; + } + + /** + * Takes changed blocks and matches which rows in orig turned into which rows in final. + * + * Returns + * *_matches ( which rows match with which ) + * *_rows ( order of rows in each column interleaved with blank rows as + * necessary ) + * + * @since 2.6.0 + * + * @param unknown_type $orig + * @param unknown_type $final + * @return unknown + */ + function interleave_changed_lines( $orig, $final ) { + + // Contains all pairwise string comparisons. Keys are such that this need only be a one dimensional array. + $matches = array(); + foreach ( array_keys($orig) as $o ) { + foreach ( array_keys($final) as $f ) { + $matches["$o,$f"] = $this->compute_string_distance( $orig[$o], $final[$f] ); + } + } + asort($matches); // Order by string distance. + + $orig_matches = array(); + $final_matches = array(); + + foreach ( $matches as $keys => $difference ) { + list($o, $f) = explode(',', $keys); + $o = (int) $o; + $f = (int) $f; + + // Already have better matches for these guys + if ( isset($orig_matches[$o]) && isset($final_matches[$f]) ) + continue; + + // First match for these guys. Must be best match + if ( !isset($orig_matches[$o]) && !isset($final_matches[$f]) ) { + $orig_matches[$o] = $f; + $final_matches[$f] = $o; + continue; + } + + // Best match of this final is already taken? Must mean this final is a new row. + if ( isset($orig_matches[$o]) ) + $final_matches[$f] = 'x'; + + // Best match of this orig is already taken? Must mean this orig is a deleted row. + elseif ( isset($final_matches[$f]) ) + $orig_matches[$o] = 'x'; + } + + // We read the text in this order + ksort($orig_matches); + ksort($final_matches); + + + // Stores rows and blanks for each column. + $orig_rows = $orig_rows_copy = array_keys($orig_matches); + $final_rows = array_keys($final_matches); + + // Interleaves rows with blanks to keep matches aligned. + // We may end up with some extraneous blank rows, but we'll just ignore them later. + foreach ( $orig_rows_copy as $orig_row ) { + $final_pos = array_search($orig_matches[$orig_row], $final_rows, true); + $orig_pos = (int) array_search($orig_row, $orig_rows, true); + + if ( false === $final_pos ) { // This orig is paired with a blank final. + array_splice( $final_rows, $orig_pos, 0, -1 ); + } elseif ( $final_pos < $orig_pos ) { // This orig's match is up a ways. Pad final with blank rows. + $diff_pos = $final_pos - $orig_pos; + while ( $diff_pos < 0 ) + array_splice( $final_rows, $orig_pos, 0, $diff_pos++ ); + } elseif ( $final_pos > $orig_pos ) { // This orig's match is down a ways. Pad orig with blank rows. + $diff_pos = $orig_pos - $final_pos; + while ( $diff_pos < 0 ) + array_splice( $orig_rows, $orig_pos, 0, $diff_pos++ ); + } + } + + + // Pad the ends with blank rows if the columns aren't the same length + $diff_count = count($orig_rows) - count($final_rows); + if ( $diff_count < 0 ) { + while ( $diff_count < 0 ) + array_push($orig_rows, $diff_count++); + } elseif ( $diff_count > 0 ) { + $diff_count = -1 * $diff_count; + while ( $diff_count < 0 ) + array_push($final_rows, $diff_count++); + } + + return array($orig_matches, $final_matches, $orig_rows, $final_rows); + +/* + // Debug + echo "\n\n\n\n\n"; + + echo "-- DEBUG Matches: Orig -> Final --"; + + foreach ( $orig_matches as $o => $f ) { + echo "\n\n\n\n\n"; + echo "ORIG: $o, FINAL: $f\n"; + var_dump($orig[$o],$final[$f]); + } + echo "\n\n\n\n\n"; + + echo "-- DEBUG Matches: Final -> Orig --"; + + foreach ( $final_matches as $f => $o ) { + echo "\n\n\n\n\n"; + echo "FINAL: $f, ORIG: $o\n"; + var_dump($final[$f],$orig[$o]); + } + echo "\n\n\n\n\n"; + + echo "-- DEBUG Rows: Orig -- Final --"; + + echo "\n\n\n\n\n"; + foreach ( $orig_rows as $row => $o ) { + if ( $o < 0 ) + $o = 'X'; + $f = $final_rows[$row]; + if ( $f < 0 ) + $f = 'X'; + echo "$o -- $f\n"; + } + echo "\n\n\n\n\n"; + + echo "-- END DEBUG --"; + + echo "\n\n\n\n\n"; + + return array($orig_matches, $final_matches, $orig_rows, $final_rows); +*/ + } + + /** + * Computes a number that is intended to reflect the "distance" between two strings. + * + * @since 2.6.0 + * + * @param string $string1 + * @param string $string2 + * @return int + */ + function compute_string_distance( $string1, $string2 ) { + // Vectors containing character frequency for all chars in each string + $chars1 = count_chars($string1); + $chars2 = count_chars($string2); + + // L1-norm of difference vector. + $difference = array_sum( array_map( array(&$this, 'difference'), $chars1, $chars2 ) ); + + // $string1 has zero length? Odd. Give huge penalty by not dividing. + if ( !$string1 ) + return $difference; + + // Return distance per charcter (of string1) + return $difference / strlen($string1); + } + + /** + * @ignore + * @since 2.6.0 + * + * @param int $a + * @param int $b + * @return int + */ + function difference( $a, $b ) { + return abs( $a - $b ); + } + +} + +/** + * Better word splitting than the PEAR package provides. + * + * @since 2.6.0 + * @uses Text_Diff_Renderer_inline Extends + */ +class WP_Text_Diff_Renderer_inline extends Text_Diff_Renderer_inline { + + /** + * @ignore + * @since 2.6.0 + * + * @param string $string + * @param string $newlineEscape + * @return string + */ + function _splitOnWords($string, $newlineEscape = "\n") { + $string = str_replace("\0", '', $string); + $words = preg_split( '/([^\w])/u', $string, -1, PREG_SPLIT_DELIM_CAPTURE ); + $words = str_replace( "\n", $newlineEscape, $words ); + return $words; + } + +} + +?> diff --git a/src/wp-links-opml.php b/src/wp-links-opml.php new file mode 100644 index 00000000..e30869bd --- /dev/null +++ b/src/wp-links-opml.php @@ -0,0 +1,59 @@ +\n"; +?> + + + <?php printf( __('Links for %s'), esc_attr(get_bloginfo('name', 'display')) ); ?> + GMT + + + + 'link_category', 'hierarchical' => 0)); +else + $cats = get_categories(array('taxonomy' => 'link_category', 'hierarchical' => 0, 'include' => $link_cat)); + +foreach ( (array)$cats as $cat ) : + $catname = apply_filters('link_category', $cat->name); + +?> + + $cat->term_id)); + foreach ( (array)$bookmarks as $bookmark ) : + $title = apply_filters('link_title', $bookmark->link_name); +?> + + + + + + \ No newline at end of file diff --git a/src/wp-load.php b/src/wp-load.php new file mode 100644 index 00000000..965c460d --- /dev/null +++ b/src/wp-load.php @@ -0,0 +1,56 @@ +wp-config.php. Este archivo es necesario para empezar. ¿Necesitas ayuda? La encontrarás aquí (en inglés). Puedes crear un archivo wp-config.php a través de la web, pero esto no funciona en algunos servidores. Lo más seguro es crear el archivo manualmente.

    Crear un archivo de configuración'/*/WP_I18N_NO_CONFIG*/, $path), /*WP_I18N_ERROR_TITLE*/'WordPress › Error'/*/WP_I18N_ERROR_TITLE*/, array('text_direction' => $text_direction)); + +} + +?> \ No newline at end of file diff --git a/src/wp-login.php b/src/wp-login.php new file mode 100644 index 00000000..0f471b0d --- /dev/null +++ b/src/wp-login.php @@ -0,0 +1,705 @@ + element. + * @param string $message Optional. Message to display in header. + * @param WP_Error $wp_error Optional. WordPress Error Object + */ +function login_header($title = 'Log In', $message = '', $wp_error = '') { + global $error, $is_iphone, $interim_login, $current_site; + + // Don't index any of these forms + add_filter( 'pre_option_blog_public', '__return_zero' ); + add_action( 'login_head', 'noindex' ); + + if ( empty($wp_error) ) + $wp_error = new WP_Error(); + + // Shake it! + $shake_error_codes = array( 'empty_password', 'empty_email', 'invalid_email', 'invalidcombo', 'empty_username', 'invalid_username', 'incorrect_password' ); + $shake_error_codes = apply_filters( 'shake_error_codes', $shake_error_codes ); + + if ( $shake_error_codes && $wp_error->get_error_code() && in_array( $wp_error->get_error_code(), $shake_error_codes ) ) + add_action( 'login_head', 'wp_shake_js', 12 ); + + ?> + +> + + <?php bloginfo('name'); ?> › <?php echo $title; ?> + + + + + + + + + + +

    + +

    +add('error', $error); + unset($error); + } + + if ( $wp_error->get_error_code() ) { + $errors = ''; + $messages = ''; + foreach ( $wp_error->get_error_codes() as $code ) { + $severity = $wp_error->get_error_data($code); + foreach ( $wp_error->get_error_messages($code) as $error ) { + if ( 'message' == $severity ) + $messages .= ' ' . $error . "
    \n"; + else + $errors .= ' ' . $error . "
    \n"; + } + } + if ( !empty($errors) ) + echo '
    ' . apply_filters('login_errors', $errors) . "
    \n"; + if ( !empty($messages) ) + echo '

    ' . apply_filters('login_messages', $messages) . "

    \n"; + } +} // End of login_header() + +/** + * Outputs the footer for the login page. + * + * @param string $input_id Which input to auto-focus + */ +function login_footer($input_id = '') { + echo "
    \n"; + + if ( !empty($input_id) ) { +?> + + +

    + + + + + +add('empty_username', __('ERROR: Enter a username or e-mail address.')); + + if ( strpos($_POST['user_login'], '@') ) { + $user_data = get_user_by_email(trim($_POST['user_login'])); + if ( empty($user_data) ) + $errors->add('invalid_email', __('ERROR: There is no user registered with that email address.')); + } else { + $login = trim($_POST['user_login']); + $user_data = get_userdatabylogin($login); + } + + do_action('lostpassword_post'); + + if ( $errors->get_error_code() ) + return $errors; + + if ( !$user_data ) { + $errors->add('invalidcombo', __('ERROR: Invalid username or e-mail.')); + return $errors; + } + + // redefining user_login ensures we return the right case in the email + $user_login = $user_data->user_login; + $user_email = $user_data->user_email; + + do_action('retreive_password', $user_login); // Misspelled and deprecated + do_action('retrieve_password', $user_login); + + $allow = apply_filters('allow_password_reset', true, $user_data->ID); + + if ( ! $allow ) + return new WP_Error('no_password_reset', __('Password reset is not allowed for this user')); + else if ( is_wp_error($allow) ) + return $allow; + + $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login)); + if ( empty($key) ) { + // Generate something random for a key... + $key = wp_generate_password(20, false); + do_action('retrieve_password_key', $user_login, $key); + // Now insert the new md5 key into the db + $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login)); + } + $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n"; + $message .= network_site_url() . "\r\n\r\n"; + $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; + $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n"; + $message .= __('To reset your password, visit the following address:') . "\r\n\r\n"; + $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n"; + + if ( is_multisite() ) + $blogname = $GLOBALS['current_site']->site_name; + else + // The blogname option is escaped with esc_html on the way into the database in sanitize_option + // we want to reverse this for the plain text arena of emails. + $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + + $title = sprintf( __('[%s] Password Reset'), $blogname ); + + $title = apply_filters('retrieve_password_title', $title); + $message = apply_filters('retrieve_password_message', $message, $key); + + if ( $message && !wp_mail($user_email, $title, $message) ) + wp_die( __('The e-mail could not be sent.') . "
    \n" . __('Possible reason: your host may have disabled the mail() function...') ); + + return true; +} + +/** + * Retrieves a user row based on password reset key and login + * + * @uses $wpdb WordPress Database object + * + * @param string $key Hash to validate sending user's password + * @param string $login The user login + * + * @return object|WP_Error + */ +function check_password_reset_key($key, $login) { + global $wpdb; + + $key = preg_replace('/[^a-z0-9]/i', '', $key); + + if ( empty( $key ) || !is_string( $key ) ) + return new WP_Error('invalid_key', __('Invalid key')); + + if ( empty($login) || !is_string($login) ) + return new WP_Error('invalid_key', __('Invalid key')); + + $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $key, $login)); + + if ( empty( $user ) ) + return new WP_Error('invalid_key', __('Invalid key')); + + return $user; +} + +/** + * Handles resetting the user's password. + * + * @uses $wpdb WordPress Database object + * + * @param string $key Hash to validate sending user's password + */ +function reset_password($user, $new_pass) { + do_action('password_reset', $user, $new_pass); + + wp_set_password($new_pass, $user->ID); + + wp_password_change_notification($user); +} + +/** + * Handles registering a new user. + * + * @param string $user_login User's username for logging in + * @param string $user_email User's email address to send password and add + * @return int|WP_Error Either user's ID or error on failure. + */ +function register_new_user( $user_login, $user_email ) { + $errors = new WP_Error(); + + $sanitized_user_login = sanitize_user( $user_login ); + $user_email = apply_filters( 'user_registration_email', $user_email ); + + // Check the username + if ( $sanitized_user_login == '' ) { + $errors->add( 'empty_username', __( 'ERROR: Please enter a username.' ) ); + } elseif ( ! validate_username( $user_login ) ) { + $errors->add( 'invalid_username', __( 'ERROR: This username is invalid because it uses illegal characters. Please enter a valid username.' ) ); + $sanitized_user_login = ''; + } elseif ( username_exists( $sanitized_user_login ) ) { + $errors->add( 'username_exists', __( 'ERROR: This username is already registered, please choose another one.' ) ); + } + + // Check the e-mail address + if ( $user_email == '' ) { + $errors->add( 'empty_email', __( 'ERROR: Please type your e-mail address.' ) ); + } elseif ( ! is_email( $user_email ) ) { + $errors->add( 'invalid_email', __( 'ERROR: The email address isn’t correct.' ) ); + $user_email = ''; + } elseif ( email_exists( $user_email ) ) { + $errors->add( 'email_exists', __( 'ERROR: This email is already registered, please choose another one.' ) ); + } + + do_action( 'register_post', $sanitized_user_login, $user_email, $errors ); + + $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email ); + + if ( $errors->get_error_code() ) + return $errors; + + $user_pass = wp_generate_password( 12, false); + $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email ); + if ( ! $user_id ) { + $errors->add( 'registerfail', sprintf( __( 'ERROR: Couldn’t register you... please contact the webmaster !' ), get_option( 'admin_email' ) ) ); + return $errors; + } + + update_user_option( $user_id, 'default_password_nag', true, true ); //Set up the Password change nag. + + wp_new_user_notification( $user_id, $user_pass ); + + return $user_id; +} + +// +// Main +// + +$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'login'; +$errors = new WP_Error(); + +if ( isset($_GET['key']) ) + $action = 'resetpass'; + +// validate action so as to default to the login screen +if ( !in_array($action, array('logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login'), true) && false === has_filter('login_form_' . $action) ) + $action = 'login'; + +nocache_headers(); + +header('Content-Type: '.get_bloginfo('html_type').'; charset='.get_bloginfo('charset')); + +if ( defined('RELOCATE') ) { // Move flag is set + if ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != $_SERVER['PHP_SELF']) ) + $_SERVER['PHP_SELF'] = str_replace( $_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF'] ); + + $schema = is_ssl() ? 'https://' : 'http://'; + if ( dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) != get_option('siteurl') ) + update_option('siteurl', dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) ); +} + +//Set a cookie now to see if they are supported by the browser. +setcookie(TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN); +if ( SITECOOKIEPATH != COOKIEPATH ) + setcookie(TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN); + +// allow plugins to override the default actions, and to add extra actions if they want +do_action( 'login_init' ); +do_action( 'login_form_' . $action ); + +$http_post = ('POST' == $_SERVER['REQUEST_METHOD']); +switch ($action) { + +case 'logout' : + check_admin_referer('log-out'); + wp_logout(); + + $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?loggedout=true'; + wp_safe_redirect( $redirect_to ); + exit(); + +break; + +case 'lostpassword' : +case 'retrievepassword' : + + if ( $http_post ) { + $errors = retrieve_password(); + if ( !is_wp_error($errors) ) { + $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm'; + wp_safe_redirect( $redirect_to ); + exit(); + } + } + + if ( isset($_GET['error']) && 'invalidkey' == $_GET['error'] ) $errors->add('invalidkey', __('Sorry, that key does not appear to be valid.')); + $redirect_to = apply_filters( 'lostpassword_redirect', !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '' ); + + do_action('lost_password'); + login_header(__('Lost Password'), '

    ' . __('Please enter your username or email address. You will receive a link to create a new password via email.') . '

    ', $errors); + + $user_login = isset($_POST['user_login']) ? stripslashes($_POST['user_login']) : ''; + +?> + +
    +

    + +

    + + +

    +
    + + + +' . __('Your password has been reset.') . ' ' . __('Log in') . '

    '); + login_footer(); + exit; + } + + wp_enqueue_script('utils'); + wp_enqueue_script('user-profile'); + + login_header(__('Reset Password'), '

    ' . __('Enter your new password below.') . '

    ', $errors ); + +?> +
    + + +

    + +

    +

    + +

    + +
    +

    + +
    +

    +
    + + + +' . __('Register For This Site') . '

    ', $errors); +?> + +
    +

    + +

    +

    + +

    + +

    +
    + +

    +
    + + + +ID) ) { + $secure_cookie = true; + force_ssl_admin(true); + } + } + } + + if ( isset( $_REQUEST['redirect_to'] ) ) { + $redirect_to = $_REQUEST['redirect_to']; + // Redirect to https if user wants ssl + if ( $secure_cookie && false !== strpos($redirect_to, 'wp-admin') ) + $redirect_to = preg_replace('|^http://|', 'https://', $redirect_to); + } else { + $redirect_to = admin_url(); + } + + $reauth = empty($_REQUEST['reauth']) ? false : true; + + // If the user was redirected to a secure login form from a non-secure admin page, and secure login is required but secure admin is not, then don't use a secure + // cookie and redirect back to the referring non-secure admin page. This allows logins to always be POSTed over SSL while allowing the user to choose visiting + // the admin via http or https. + if ( !$secure_cookie && is_ssl() && force_ssl_login() && !force_ssl_admin() && ( 0 !== strpos($redirect_to, 'https') ) && ( 0 === strpos($redirect_to, 'http') ) ) + $secure_cookie = false; + + $user = wp_signon('', $secure_cookie); + + $redirect_to = apply_filters('login_redirect', $redirect_to, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user); + + if ( !is_wp_error($user) && !$reauth ) { + if ( $interim_login ) { + $message = '

    ' . __('You have logged in successfully.') . '

    '; + login_header( '', $message ); ?> + +

    +

    +
    +id) ) + $redirect_to = user_admin_url(); + elseif ( is_multisite() && !$user->has_cap('read') ) + $redirect_to = get_dashboard_url( $user->id ); + elseif ( !$user->has_cap('edit_posts') ) + $redirect_to = admin_url('profile.php'); + } + wp_safe_redirect($redirect_to); + exit(); + } + + $errors = $user; + // Clear errors if loggedout is set. + if ( !empty($_GET['loggedout']) || $reauth ) + $errors = new WP_Error(); + + // If cookies are disabled we can't log in even with a valid user+pass + if ( isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE]) ) + $errors->add('test_cookie', __("ERROR: Cookies are blocked or not supported by your browser. You must enable cookies to use WordPress.")); + + // Some parts of this script use the main login form to display a message + if ( isset($_GET['loggedout']) && TRUE == $_GET['loggedout'] ) + $errors->add('loggedout', __('You are now logged out.'), 'message'); + elseif ( isset($_GET['registration']) && 'disabled' == $_GET['registration'] ) + $errors->add('registerdisabled', __('User registration is currently not allowed.')); + elseif ( isset($_GET['checkemail']) && 'confirm' == $_GET['checkemail'] ) + $errors->add('confirm', __('Check your e-mail for the confirmation link.'), 'message'); + elseif ( isset($_GET['checkemail']) && 'newpass' == $_GET['checkemail'] ) + $errors->add('newpass', __('Check your e-mail for your new password.'), 'message'); + elseif ( isset($_GET['checkemail']) && 'registered' == $_GET['checkemail'] ) + $errors->add('registered', __('Registration complete. Please check your e-mail.'), 'message'); + elseif ( $interim_login ) + $errors->add('expired', __('Your session has expired. Please log-in again.'), 'message'); + + // Clear any stale cookies. + if ( $reauth ) + wp_clear_auth_cookie(); + + login_header(__('Log In'), '', $errors); + + if ( isset($_POST['log']) ) + $user_login = ( 'incorrect_password' == $errors->get_error_code() || 'empty_password' == $errors->get_error_code() ) ? esc_attr(stripslashes($_POST['log'])) : ''; + $rememberme = ! empty( $_POST['rememberme'] ); +?> + +
    +

    + +

    +

    + +

    + +

    +

    + + + + + + + +

    +
    + + + +
    +

    + +
    + + + + + + + diff --git a/src/wp-mail.php b/src/wp-mail.php new file mode 100644 index 00000000..69b54156 --- /dev/null +++ b/src/wp-mail.php @@ -0,0 +1,236 @@ + Writing + * + * @package WordPress + */ + +/** Make sure that the WordPress bootstrap has run before continuing. */ +require(dirname(__FILE__) . '/wp-load.php'); + +if ( ! apply_filters( 'enable_post_by_email_configuration', true ) ) + wp_die( __( 'This action has been disabled by the administrator.' ) ); + +/** Allow a plugin to do a complete takeover of Post by Email **/ +do_action('wp-mail.php'); + +/** Get the POP3 class with which to access the mailbox. */ +require_once( ABSPATH . WPINC . '/class-pop3.php' ); + +/** Only check at this interval for new messages. */ +if ( !defined('WP_MAIL_INTERVAL') ) + define('WP_MAIL_INTERVAL', 300); // 5 minutes + +$last_checked = get_transient('mailserver_last_checked'); + +if ( $last_checked ) + wp_die(__('Slow down cowboy, no need to check for new mails so often!')); + +set_transient('mailserver_last_checked', true, WP_MAIL_INTERVAL); + +$time_difference = get_option('gmt_offset') * 3600; + +$phone_delim = '::'; + +$pop3 = new POP3(); + +if ( !$pop3->connect( get_option('mailserver_url'), get_option('mailserver_port') ) || !$pop3->user( get_option('mailserver_login') ) ) + wp_die( esc_html( $pop3->ERROR ) ); + +$count = $pop3->pass( get_option('mailserver_pass') ); + +if( false === $count ) + wp_die( esc_html( $pop3->ERROR ) ); + +if( 0 === $count ) { + $pop3->quit(); + wp_die( __('There doesn’t seem to be any new mail.') ); +} + +for ( $i = 1; $i <= $count; $i++ ) { + + $message = $pop3->get($i); + + $bodysignal = false; + $boundary = ''; + $charset = ''; + $content = ''; + $content_type = ''; + $content_transfer_encoding = ''; + $post_author = 1; + $author_found = false; + $dmonths = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); + foreach ($message as $line) { + // body signal + if ( strlen($line) < 3 ) + $bodysignal = true; + if ( $bodysignal ) { + $content .= $line; + } else { + if ( preg_match('/Content-Type: /i', $line) ) { + $content_type = trim($line); + $content_type = substr($content_type, 14, strlen($content_type) - 14); + $content_type = explode(';', $content_type); + if ( ! empty( $content_type[1] ) ) { + $charset = explode('=', $content_type[1]); + $charset = ( ! empty( $charset[1] ) ) ? trim($charset[1]) : ''; + } + $content_type = $content_type[0]; + } + if ( preg_match('/Content-Transfer-Encoding: /i', $line) ) { + $content_transfer_encoding = trim($line); + $content_transfer_encoding = substr($content_transfer_encoding, 27, strlen($content_transfer_encoding) - 27); + $content_transfer_encoding = explode(';', $content_transfer_encoding); + $content_transfer_encoding = $content_transfer_encoding[0]; + } + if ( ( $content_type == 'multipart/alternative' ) && ( false !== strpos($line, 'boundary="') ) && ( '' == $boundary ) ) { + $boundary = trim($line); + $boundary = explode('"', $boundary); + $boundary = $boundary[1]; + } + if (preg_match('/Subject: /i', $line)) { + $subject = trim($line); + $subject = substr($subject, 9, strlen($subject) - 9); + // Captures any text in the subject before $phone_delim as the subject + if ( function_exists('iconv_mime_decode') ) { + $subject = iconv_mime_decode($subject, 2, get_option('blog_charset')); + } else { + $subject = wp_iso_descrambler($subject); + } + $subject = explode($phone_delim, $subject); + $subject = $subject[0]; + } + + // Set the author using the email address (From or Reply-To, the last used) + // otherwise use the site admin + if ( preg_match('/(From|Reply-To): /', $line) ) { + if ( preg_match('|[a-z0-9_.-]+@[a-z0-9_.-]+(?!.*<)|i', $line, $matches) ) + $author = $matches[0]; + else + $author = trim($line); + $author = sanitize_email($author); + if ( is_email($author) ) { + echo '

    ' . sprintf(__('Author is %s'), $author) . '

    '; + $userdata = get_user_by_email($author); + if ( empty($userdata) ) { + $author_found = false; + } else { + $post_author = $userdata->ID; + $author_found = true; + } + } else { + $author_found = false; + } + } + + if (preg_match('/Date: /i', $line)) { // of the form '20 Mar 2002 20:32:37' + $ddate = trim($line); + $ddate = str_replace('Date: ', '', $ddate); + if (strpos($ddate, ',')) { + $ddate = trim(substr($ddate, strpos($ddate, ',') + 1, strlen($ddate))); + } + $date_arr = explode(' ', $ddate); + $date_time = explode(':', $date_arr[3]); + + $ddate_H = $date_time[0]; + $ddate_i = $date_time[1]; + $ddate_s = $date_time[2]; + + $ddate_m = $date_arr[1]; + $ddate_d = $date_arr[0]; + $ddate_Y = $date_arr[2]; + for ( $j = 0; $j < 12; $j++ ) { + if ( $ddate_m == $dmonths[$j] ) { + $ddate_m = $j+1; + } + } + + $time_zn = intval($date_arr[4]) * 36; + $ddate_U = gmmktime($ddate_H, $ddate_i, $ddate_s, $ddate_m, $ddate_d, $ddate_Y); + $ddate_U = $ddate_U - $time_zn; + $post_date = gmdate('Y-m-d H:i:s', $ddate_U + $time_difference); + $post_date_gmt = gmdate('Y-m-d H:i:s', $ddate_U); + } + } + } + + // Set $post_status based on $author_found and on author's publish_posts capability + if ( $author_found ) { + $user = new WP_User($post_author); + $post_status = ( $user->has_cap('publish_posts') ) ? 'publish' : 'pending'; + } else { + // Author not found in DB, set status to pending. Author already set to admin. + $post_status = 'pending'; + } + + $subject = trim($subject); + + if ( $content_type == 'multipart/alternative' ) { + $content = explode('--'.$boundary, $content); + $content = $content[2]; + // match case-insensitive content-transfer-encoding + if ( preg_match( '/Content-Transfer-Encoding: quoted-printable/i', $content, $delim) ) { + $content = explode($delim[0], $content); + $content = $content[1]; + } + $content = strip_tags($content, '


    '); + } + $content = trim($content); + + //Give Post-By-Email extending plugins full access to the content + //Either the raw content or the content of the last quoted-printable section + $content = apply_filters('wp_mail_original_content', $content); + + if ( false !== stripos($content_transfer_encoding, "quoted-printable") ) { + $content = quoted_printable_decode($content); + } + + if ( function_exists('iconv') && ! empty( $charset ) ) { + $content = iconv($charset, get_option('blog_charset'), $content); + } + + // Captures any text in the body after $phone_delim as the body + $content = explode($phone_delim, $content); + $content = empty( $content[1] ) ? $content[0] : $content[1]; + + $content = trim($content); + + $post_content = apply_filters('phone_content', $content); + + $post_title = xmlrpc_getposttitle($content); + + if ($post_title == '') $post_title = $subject; + + $post_category = array(get_option('default_email_category')); + + $post_data = compact('post_content','post_title','post_date','post_date_gmt','post_author','post_category', 'post_status'); + $post_data = add_magic_quotes($post_data); + + $post_ID = wp_insert_post($post_data); + if ( is_wp_error( $post_ID ) ) + echo "\n" . $post_ID->get_error_message(); + + // We couldn't post, for whatever reason. Better move forward to the next email. + if ( empty( $post_ID ) ) + continue; + + do_action('publish_phone', $post_ID); + + echo "\n

    " . sprintf(__('Author: %s'), esc_html($post_author)) . '

    '; + echo "\n

    " . sprintf(__('Posted title: %s'), esc_html($post_title)) . '

    '; + + if(!$pop3->delete($i)) { + echo '

    ' . sprintf(__('Oops: %s'), esc_html($pop3->ERROR)) . '

    '; + $pop3->reset(); + exit; + } else { + echo '

    ' . sprintf(__('Mission complete. Message %s deleted.'), $i) . '

    '; + } + +} + +$pop3->quit(); + +?> diff --git a/src/wp-pass.php b/src/wp-pass.php new file mode 100644 index 00000000..c0c0c42a --- /dev/null +++ b/src/wp-pass.php @@ -0,0 +1,20 @@ + diff --git a/src/wp-rdf.php b/src/wp-rdf.php new file mode 100644 index 00000000..cc94ad06 --- /dev/null +++ b/src/wp-rdf.php @@ -0,0 +1,12 @@ + diff --git a/src/wp-register.php b/src/wp-register.php new file mode 100644 index 00000000..0b1a7697 --- /dev/null +++ b/src/wp-register.php @@ -0,0 +1,15 @@ + diff --git a/src/wp-rss.php b/src/wp-rss.php new file mode 100644 index 00000000..af2427ad --- /dev/null +++ b/src/wp-rss.php @@ -0,0 +1,12 @@ + diff --git a/src/wp-rss2.php b/src/wp-rss2.php new file mode 100644 index 00000000..de75c239 --- /dev/null +++ b/src/wp-rss2.php @@ -0,0 +1,12 @@ + diff --git a/src/wp-settings.php b/src/wp-settings.php new file mode 100644 index 00000000..2cd12c1c --- /dev/null +++ b/src/wp-settings.php @@ -0,0 +1,320 @@ +init(); + +/** + * Most of WP is loaded at this stage, and the user is authenticated. WP continues + * to load on the init hook that follows (e.g. widgets), and many plugins instantiate + * themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.). + * + * If you wish to plug an action once WP is loaded, use the wp_loaded hook below. + */ +do_action( 'init' ); + +// Check site status +if ( is_multisite() ) { + if ( true !== ( $file = ms_site_check() ) ) { + require( $file ); + die(); + } + unset($file); +} + +/** + * This hook is fired once WP, all plugins, and the theme are fully loaded and instantiated. + * + * AJAX requests should use wp-admin/admin-ajax.php. admin-ajax.php can handle requests for + * users not logged in. + * + * @link http://codex.wordpress.org/AJAX_in_Plugins + * + * @since 3.0.0 + */ +do_action('wp_loaded'); +?> diff --git a/src/wp-signup.php b/src/wp-signup.php new file mode 100644 index 00000000..c2ab566b --- /dev/null +++ b/src/wp-signup.php @@ -0,0 +1,455 @@ +\n"; +} + +if ( !is_multisite() ) { + wp_redirect( site_url('wp-login.php?action=register') ); + die(); +} + +if ( !is_main_site() ) { + wp_redirect( network_home_url( 'wp-signup.php' ) ); + die(); +} + +// Fix for page title +$wp_query->is_404 = false; + +function wpmu_signup_stylesheet() { + ?> + + +
    +
    +' . __('Site Name:') . ''; + else + echo ''; + + if ( $errmsg = $errors->get_error_message('blogname') ) { ?> +

    + ' . $current_site->domain . $current_site->path . '
    '; + else + echo '.' . ( $site_domain = preg_replace( '|^www\.|', '', $current_site->domain ) ) . '
    '; + + if ( !is_user_logged_in() ) { + if ( !is_subdomain_install() ) + $site = $current_site->domain . $current_site->path . __( 'sitename' ); + else + $site = __( 'domain' ) . '.' . $site_domain . $current_site->path; + echo '

    (' . sprintf( __('Your address will be %s.'), $site ) . ') ' . __( 'Must be at least 4 characters, letters and numbers only. It cannot be changed, so choose carefully!' ) . '

    '; + } + + // Blog Title + ?> + + get_error_message('blog_title') ) { ?> +

    + '; + ?> + +
    +

    + + +
    + + +

    +
    + + ' . __('Username:') . ''; + if ( $errmsg = $errors->get_error_message('user_name') ) { + echo '

    '.$errmsg.'

    '; + } + echo '
    '; + _e( '(Must be at least 4 characters, letters and numbers only.)' ); + ?> + + + get_error_message('user_email') ) { ?> +

    + +
    + get_error_message('generic') ) { + echo '

    ' . $errmsg . '

    '; + } + do_action( 'signup_extra_fields', $errors ); +} + +function validate_user_form() { + return wpmu_validate_user_signup($_POST['user_name'], $_POST['user_email']); +} + +function signup_another_blog($blogname = '', $blog_title = '', $errors = '') { + global $current_site; + $current_user = wp_get_current_user(); + + if ( ! is_wp_error($errors) ) { + $errors = new WP_Error(); + } + + // allow definition of default variables + $filtered_results = apply_filters('signup_another_blog_init', array('blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors )); + $blogname = $filtered_results['blogname']; + $blog_title = $filtered_results['blog_title']; + $errors = $filtered_results['errors']; + + echo '

    ' . sprintf( __( 'Get another %s site in seconds' ), $current_site->site_name ) . '

    '; + + if ( $errors->get_error_code() ) { + echo '

    ' . __( 'There was a problem, please correct the form below and try again.' ) . '

    '; + } + ?> +

    add another site to your account. There is no limit to the number of sites you can have, so create to your heart’s content, but write responsibly!' ), $current_user->display_name ) ?>

    + + ID); + if ( !empty($blogs) ) { ?> + +

    + + + +

    +
    + + + +

    +
    + get_error_code() ) { + signup_another_blog($blogname, $blog_title, $errors); + return false; + } + + $public = (int) $_POST['blog_public']; + $meta = apply_filters( 'signup_create_blog_meta', array( 'lang_id' => 1, 'public' => $public ) ); // deprecated + $meta = apply_filters( 'add_signup_meta', $meta ); + + wpmu_create_blog( $domain, $path, $blog_title, $current_user->id, $meta, $wpdb->siteid ); + confirm_another_blog_signup($domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta); + return true; +} + +function confirm_another_blog_signup($domain, $path, $blog_title, $user_name, $user_email = '', $meta = '') { + ?> +

    {$blog_title}" ) ?>

    +

    + http://%2$s is your new site. Log in as “%4$s” using your existing password.' ), $domain.$path, $domain.$path, "http://" . $domain.$path . "wp-login.php", $user_name ) ?> +

    + $user_name, 'user_email' => $user_email, 'errors' => $errors )); + $user_name = $filtered_results['user_name']; + $user_email = $filtered_results['user_email']; + $errors = $filtered_results['errors']; + + ?> + +

    site_name ) ?>

    +
    + + + + +

    + + + + + + /> + +
    + /> + + +

    + +

    +
    + get_error_code() ) { + signup_user($user_name, $user_email, $errors); + return false; + } + + if ( 'blog' == $_POST['signup_for'] ) { + signup_blog($user_name, $user_email); + return false; + } + + wpmu_signup_user($user_name, $user_email, apply_filters( "add_signup_meta", array() ) ); + + confirm_user_signup($user_name, $user_email); + return true; +} + +function confirm_user_signup($user_name, $user_email) { + ?> +

    +

    you must activate it.' ) ?>

    +

    %1$s and click the link given.' ), $user_email) ?>

    +

    + $user_name, 'user_email' => $user_email, 'blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors )); + $user_name = $filtered_results['user_name']; + $user_email = $filtered_results['user_email']; + $blogname = $filtered_results['blogname']; + $blog_title = $filtered_results['blog_title']; + $errors = $filtered_results['errors']; + + if ( empty($blogname) ) + $blogname = $user_name; + ?> +
    + + + + + +

    +
    + get_error_code() ) { + signup_user($user_name, $user_email, $errors); + return false; + } + + $result = wpmu_validate_blog_signup($_POST['blogname'], $_POST['blog_title']); + extract($result); + + if ( $errors->get_error_code() ) { + signup_blog($user_name, $user_email, $blogname, $blog_title, $errors); + return false; + } + + $public = (int) $_POST['blog_public']; + $meta = array ('lang_id' => 1, 'public' => $public); + $meta = apply_filters( "add_signup_meta", $meta ); + + wpmu_signup_blog($domain, $path, $blog_title, $user_name, $user_email, $meta); + confirm_blog_signup($domain, $path, $blog_title, $user_name, $user_email, $meta); + return true; +} + +function confirm_blog_signup($domain, $path, $blog_title, $user_name = '', $user_email = '', $meta) { + ?> +

    {$blog_title}" ) ?>

    + +

    you must activate it.' ) ?>

    +

    %s and click the link given.' ), $user_email) ?>

    +

    +

    +

    + +

      +
    • +
    • +
    • +
    +

    + ' . sprintf( __( 'Greetings Site Administrator! You are currently allowing “%s” registrations. To change or disable registration go to your Options page.' ), $i18n_signup[$active_signup], esc_url( network_admin_url( 'settings.php' ) ) ) . '
    '; + +$newblogname = isset($_GET['new']) ? strtolower(preg_replace('/^-|-$|[^-a-zA-Z0-9]/', '', $_GET['new'])) : null; + +$current_user = wp_get_current_user(); +if ( $active_signup == "none" ) { + _e( 'Registration has been disabled.' ); +} elseif ( $active_signup == 'blog' && !is_user_logged_in() ) { + if ( is_ssl() ) + $proto = 'https://'; + else + $proto = 'http://'; + $login_url = site_url( 'wp-login.php?redirect_to=' . urlencode($proto . $_SERVER['HTTP_HOST'] . '/wp-signup.php' )); + echo sprintf( __( 'You must first log in, and then you can create a new site.' ), $login_url ); +} else { + $stage = isset( $_POST['stage'] ) ? $_POST['stage'] : 'default'; + switch ( $stage ) { + case 'validate-user-signup' : + if ( $active_signup == 'all' || $_POST[ 'signup_for' ] == 'blog' && $active_signup == 'blog' || $_POST[ 'signup_for' ] == 'user' && $active_signup == 'user' ) + validate_user_signup(); + else + _e( 'User registration has been disabled.' ); + break; + case 'validate-blog-signup': + if ( $active_signup == 'all' || $active_signup == 'blog' ) + validate_blog_signup(); + else + _e( 'Site registration has been disabled.' ); + break; + case 'gimmeanotherblog': + validate_another_blog_signup(); + break; + case 'default': + default : + $user_email = isset( $_POST[ 'user_email' ] ) ? $_POST[ 'user_email' ] : ''; + do_action( "preprocess_signup_form" ); // populate the form from invites, elsewhere? + if ( is_user_logged_in() && ( $active_signup == 'all' || $active_signup == 'blog' ) ) + signup_another_blog($newblogname); + elseif ( is_user_logged_in() == false && ( $active_signup == 'all' || $active_signup == 'user' ) ) + signup_user( $newblogname, $user_email ); + elseif ( is_user_logged_in() == false && ( $active_signup == 'blog' ) ) + _e( 'Sorry, new registrations are not allowed at this time.' ); + else + _e( 'You are logged in already. No need to register again!' ); + + if ( $newblogname ) { + $newblog = get_blogaddress_by_name( $newblogname ); + + if ( $active_signup == 'blog' || $active_signup == 'all' ) + printf( __( '

    The site you were looking for, %s does not exist, but you can create it now!

    ' ), $newblog ); + else + printf( __( '

    The site you were looking for, %s, does not exist.

    ' ), $newblog ); + } + break; + } +} +?> +
    +
    + + + diff --git a/src/wp-trackback.php b/src/wp-trackback.php new file mode 100644 index 00000000..737fbcec --- /dev/null +++ b/src/wp-trackback.php @@ -0,0 +1,111 @@ + '1' ) ); +} + +/** + * trackback_response() - Respond with error or success XML message + * + * @param int|bool $error Whether there was an error + * @param string $error_message Error message if an error occurred + */ +function trackback_response($error = 0, $error_message = '') { + header('Content-Type: text/xml; charset=' . get_option('blog_charset') ); + if ($error) { + echo '\n"; + echo "\n"; + echo "1\n"; + echo "$error_message\n"; + echo ""; + die(); + } else { + echo '\n"; + echo "\n"; + echo "0\n"; + echo ""; + } +} + +// trackback is done by a POST +$request_array = 'HTTP_POST_VARS'; + +if ( !isset($_GET['tb_id']) || !$_GET['tb_id'] ) { + $tb_id = explode('/', $_SERVER['REQUEST_URI']); + $tb_id = intval( $tb_id[ count($tb_id) - 1 ] ); +} + +$tb_url = isset($_POST['url']) ? $_POST['url'] : ''; +$charset = isset($_POST['charset']) ? $_POST['charset'] : ''; + +// These three are stripslashed here so that they can be properly escaped after mb_convert_encoding() +$title = isset($_POST['title']) ? stripslashes($_POST['title']) : ''; +$excerpt = isset($_POST['excerpt']) ? stripslashes($_POST['excerpt']) : ''; +$blog_name = isset($_POST['blog_name']) ? stripslashes($_POST['blog_name']) : ''; + +if ($charset) + $charset = str_replace( array(',', ' '), '', strtoupper( trim($charset) ) ); +else + $charset = 'ASCII, UTF-8, ISO-8859-1, JIS, EUC-JP, SJIS'; + +// No valid uses for UTF-7 +if ( false !== strpos($charset, 'UTF-7') ) + die; + +if ( function_exists('mb_convert_encoding') ) { // For international trackbacks + $title = mb_convert_encoding($title, get_option('blog_charset'), $charset); + $excerpt = mb_convert_encoding($excerpt, get_option('blog_charset'), $charset); + $blog_name = mb_convert_encoding($blog_name, get_option('blog_charset'), $charset); +} + +// Now that mb_convert_encoding() has been given a swing, we need to escape these three +$title = $wpdb->escape($title); +$excerpt = $wpdb->escape($excerpt); +$blog_name = $wpdb->escape($blog_name); + +if ( is_single() || is_page() ) + $tb_id = $posts[0]->ID; + +if ( !isset($tb_id) || !intval( $tb_id ) ) + trackback_response(1, 'I really need an ID for this to work.'); + +if (empty($title) && empty($tb_url) && empty($blog_name)) { + // If it doesn't look like a trackback at all... + wp_redirect(get_permalink($tb_id)); + exit; +} + +if ( !empty($tb_url) && !empty($title) ) { + header('Content-Type: text/xml; charset=' . get_option('blog_charset') ); + + if ( !pings_open($tb_id) ) + trackback_response(1, 'Sorry, trackbacks are closed for this item.'); + + $title = wp_html_excerpt( $title, 250 ).'...'; + $excerpt = wp_html_excerpt( $excerpt, 252 ).'...'; + + $comment_post_ID = (int) $tb_id; + $comment_author = $blog_name; + $comment_author_email = ''; + $comment_author_url = $tb_url; + $comment_content = "$title\n\n$excerpt"; + $comment_type = 'trackback'; + + $dupe = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_author_url = %s", $comment_post_ID, $comment_author_url) ); + if ( $dupe ) + trackback_response(1, 'We already have a ping from that URL for this post.'); + + $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type'); + + wp_new_comment($commentdata); + + do_action('trackback_post', $wpdb->insert_id); + trackback_response(0); +} +?> \ No newline at end of file diff --git a/src/xmlrpc.php b/src/xmlrpc.php new file mode 100644 index 00000000..85171776 --- /dev/null +++ b/src/xmlrpc.php @@ -0,0 +1,107 @@ + +'; ?> + + + WordPress + http://wordpress.org/ + + + + + + + + + + +serve_request(); +?> \ No newline at end of file