pax_global_header00006660000000000000000000000064141240554000014505gustar00rootroot0000000000000052 comment=1268b17ef5c01751582b0fa9731a86ad7dee95ac okasha-0.3.0/000077500000000000000000000000001412405540000127535ustar00rootroot00000000000000okasha-0.3.0/README000066400000000000000000000066141412405540000136420ustar00rootroot00000000000000okasha WSGI web fromwork =========================== this is almost do-nothing web framewrok the only needed file is okasha and the rest is a sample project for demonstration see: * http://ojuba.org/ * https://github.com/ojuba-org/okasha The Name ========== Okasha (or Okkasha with double stressed) means something that interconnected, and it also means the spider or its web. We named our project after one of the companions of prophet Muhammad (peace be upon him). His full name was Okasha ibn Muhsun ‫عكاشة بن محصن Features ========= * WSGI-enabled ie. can be used with mod_wsgi, mod_python, fast cgi, cgi, with paste or even without even a server * light weight * can be tuned to be suitable for desktop apps or public web servers * no extra dependencies * very simple The Concept ============ subclass baseWebApp and each non-private method will serve a page with same name, methods receives Request object and the rest of Uri parts (for example if you web app is app, and if the method is view and someone visited http://localhost/app/view/book1/page2 it will receive 'book1','page2' after the request argument) you may set response code and content type using the response property of Request object you may use @expose decorator to pass the returned value to some template method, the two most common template methods are * jsonDumps which will format the returned python object as a JSON javascript string. * formatTemplate - the returned dictionary or array will be the arguments to format the template files using python str.format * percentTemplate - the returned dictionary will be the arguments to format the template files using python % operator (something like C printf) * okasha.kidTemplate - the returned dictionary will be the arguments to format the kid template files and it also allow you to serve static files directly or redirect it to where it can be server by other means using the above ways one can create very effective web applications, just serve a static main HTML page (or use templates) then do the rest with AJAX/JSON Note: formatTemplate is very useful for Html but not when it contains js function because you have to escape { } into {{ }} Note: percentTemplate is very useful when Html code contains js functions but it's annoying when you got styles with % as you have to escape it into %% Does it depends on jQuery ? ============================= no, I've used it in the sample test.py for convenience, you may use any javascript library or write your own for example you may send ajax requests as in this tutorial http://www.w3schools.com/Ajax/ajax_browsers.asp Testing ======== you can test it by using python-paste for example to test the demonstration sample just run test.py then open your browser on the reported site Apache Deploying ================= install mod_wsgi and the next line to your httpd configuration WSGIScriptAlias /myapp /path/to/myapp.wsgi where /myapp is how your application is accessed (http://localhost/myapp) and where myapp.wsgi is a python file that just defines "application" for example it could be something like this from mymodule import myWebApp application=myWebApp(args_goes_here) see test.wsgi for details Google App Engine Deploying ============================ Just use the function run_wsgi_app(application) for details visit http://code.google.com/appengine/docs/python/tools/webapp/utilmodule.html#run_wsgi_app okasha-0.3.0/README.ar.txt000066400000000000000000000146241412405540000150610ustar00rootroot00000000000000====== إطار الويب عكاشة ====== انظر http://ojuba.org ===== تمهيد ===== إن مواقع الإنترنت الناجحة ليست مجرد صفحات HTML ساكنة بل إن أغلبها تحتوي على محتويات تفاعلية (تستخدم حسابات أو قواعد بيانات وتتفاعل مع المستخدم وتسمح لهم بالتعليق والتواصل معا). يتم توليد المحتويات عبر لغات برمجة تنفذ على الخادم إن تطوير تطبيقات الويب يحتوي على الكثير من الأمور الرتيبة المملة ومن هنا ظهرت الحاجة لأطر الويب web frameworks تم تطوير إطار الويب عكاشة أساسا من أجل عمل تطبيق الويب في مشروع ثواب ثم رأيت فصله حتى يمكن الاستفادة منه في عمل تطبيقات أخرى حيث أنه كود عام يصلح لأي تطبيق ويب. ===== الأسئلة الشائعة ===== ==== ما هو عكاشة ؟ ==== هو إطار ويب لعمل تطبيقات ويب متطورة بلغة البرمجة بايثون متوافقة مع مبدأ ويز-جي WSGI بكل بساطة وسهولة. ==== من هو عكاشة ؟ ==== هو الصحابي الجليل عكاشة بن محصن((هو عكاشة بن محصن ابن حرثان بن قيس بن مرة بن كبير بن غنم بن دودان بن أسد بن خزيمة)) رضي الله عنه وهو ممن يدخلون الجنة بلا حساب ولا عذاب. قال عنه ابن حجر في الإصابة: من السابقين الأولين وشهد بدراً، وقع ذكره في الصحيحين في حديث ابن عباس في السبعين ألفاً الذين يدخلون الجنة بغير حساب، فقال عكاشة: ادع الله أن يجعلني مني. قال: "أنت منهم". فقام آخر فقال: "سبقك بها عكاشة". قيل: استشهد عكاشة في قتال أهل الردة. ==== ما معنى الكلمة ؟ ==== في القاموس المحيط نجد أنها العَنْكَبوتُ، أو ذُكُورها، أو بَيْتُها (...) عُكاشَةُ الغَنَوِيُّ، وابنُ ثَوْرٍ، وابنُ مِحْصَنٍ، الصحابِيُّونَ. ذكر ابن منظور في لسان العرب تحت جذر عكش: عكَشَ عليه: حَمَلَ. وعَكِش النباتُ والشعرُ وتعَكَّش: كَثُرَ والتفَّ. وكلُّ شيءٍ لزم بعضُه بعضاً فقد تَعَكَّشَ. وشعرٌ عَكِشٌ ومُتَعَكِّشُ إِذا تلبَّد. وشعر عَكِشُ الأَطراف إِذا كان جَعْداً (...) وشجرة عَكِشَةٌ: كثيرةُ الفروع مُتَشَجِّنةٌ. والعُكَاشة والعُكَّاشةُ: **العنكبوت**: وبها سمي الرجل. (...) وعُكَيْشٌ وعُكَّاشةُ وعَكَّاشٌ: أَسماء. (...) وعُكَّاشة بن مِحْصن الأَسدي: من الصحابة، وقد يخفف. الشكر لأخي طه الزروقي الذي اختار الاسم. ==== من أين أحصل عليه ؟ ==== كود عكاشة متوفر من خلال git علىhttps://github.com/ojuba-org/okasha/ ==== لماذا لم يكتب على php كبقية التطبيقات في العالم ؟ ==== لغة php ليست لغة نظيفة خصوصا في ما يتعلق بدعم utf-8 ==== هل هو وفق بنية MVC ؟ ==== نعم تستطيع أن تقول ذلك. إذ يشكل الصنف baseWebApp المتحكم Controller ويترك لك الإطار اختيار أي كائن بايثوني ليكون النموذج Model (الذي قد يكون مصدره من قاعدة بيانات عبر elixir) وتحدد أي نظام قوالب تريد ليكون عنصر العرض. ==== أين تضعه مقارنة بالأطر البايثونية الأخرى ؟ ==== يمتاز عكاشة عن كل أطر الويب التي اختبرتها بالبساطة لهذا أعرفه إطار الويب البدهي trivial web framework أو إطار الويب الذي لا يقوم بشيء do nothing web framework بمعنى أنه لا يقف في طريقك ولن يكون صعبا عليك أن تدرك كل ما يحيط به في ذاكرتك دون الرجوع للوثائق. عكاشة أقرب ما يكون إلى cherrypy وأبعد ما يكون عن django الكثير من أطر الويب تحدد لك نموذج البيانات ومحرك القوالب وغير ذلك من عوامل كذلك فإنها غالبا تتطلب عمل شجرة معقدة من الملفات والإعدادات بل إنها في الغالب تأتي مع برنامج يعمل تلك الشجرة لتشابكها فيقوم البرنامج بعمل الكثير من الملفات التي قد لا تتمكن من هضمها كلها. في Pylon يتم تعريف طريقة التعامل مع URL من خلال مكتبة http://routes.groovie.org الذي بدوره يحاكي RoR حيث تربط أنت نمط من العناوين مع دالة معينة. في حين أن طريقة الربط محدد مسبقا في عكاشة بحيث تمنعك من "إطلاق النار على نفسك!" باختصار إن إطار عكاشة هو تطبيق لمبدأ بايثوني معروف وهو أن الصريح أفضل من الضمني والبسيط أفضل من المعقد. ==== كيف يمكنني اختبار برنامجي ؟ ==== يمكنك إطلاق خادم ضمني صغير يقوم بتشغيل تطبيق الويب دون الحاجة لخادم apache. ==== أين أجد هكذا خادم ضمني ؟ ==== بما أنه مطابق لمعايير WSGI يمكنك استخدام أي خادم ضمني يدعمها. أفضل مثال على ذلك هو عبر مكتبة python-paste وهي مكتبة بايثونية صرفة لا يزيد حجمها عن واحد ونصف ميغابايت. وهي تعمل على كل الأنظمة بما فيها ويندوز. ==== كيف يمكنني نشر تطبيق الويب ؟ وأي الاستضافات تدعمه ؟ ==== إن هناك عشرات الطرق لإطلاق تطبيقات عكاشة شأنه في ذلك شان تطبيقات WSGI حيث أنها معايير كتابة تطبيقات الويب في بايثون. ومن هذه الطرق انظر http://okasha.ojuba.org/deployment okasha-0.3.0/TODO000066400000000000000000000005651412405540000134510ustar00rootroot00000000000000 * use ObjectsCache to cache static files * make some template functions into classes to make them cache the template file * document how okasha is compared to django, Pylons, Sponge, Tornado, Turbogears, Turbogears 2, web.py, Flask, Bottle * add a function argument ObjectsCache that skips adding to cache if True * implement fileSizeGreaterThan() and use it okasha-0.3.0/demo-themes/000077500000000000000000000000001412405540000151625ustar00rootroot00000000000000okasha-0.3.0/demo-themes/default/000077500000000000000000000000001412405540000166065ustar00rootroot00000000000000okasha-0.3.0/demo-themes/default/static/000077500000000000000000000000001412405540000200755ustar00rootroot00000000000000okasha-0.3.0/demo-themes/default/static/docbook-img/000077500000000000000000000000001412405540000222675ustar00rootroot00000000000000okasha-0.3.0/demo-themes/default/static/docbook-img/1.png000066400000000000000000000011761412405540000231420ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭ IDATHǽJ+A(N(Ia[iؘF $v+" ba4)l`B3Q9^+n=́93石,puǙcN}yuTggM&2憈lh4դ?19). lnm'#ƔB@jI(eDj>o8%%qqf*mӀNM.n߷IhM5P~Rp,/P*-,J@u@|xX.'`Y̶&aj!PV?ZI1\L-ɠhf۾x̌ @>@X$coB t:OOEQrL.}!~bJ5Jml8?W*Ujk+^oZRooJ{{@HKvv2Ef l$""դץ;Na#IENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/10.png000066400000000000000000000015611412405540000232200ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǵU=Hra~ޫ,,, J44Cn ^X AjRTR4D?T3D ״n~׳py< ~H%x:;լժg,c0˲ ˧P_PT$85jNL{(zs^\0; R 2/9ݕDB5 2_ "C噙+L%IQ8wԂ TU%IGlV\___C<1M%v:N`dcd0fmr-_PWWYYWͅssvV.FChGKKGp448@IIQQI 0>:>LLOL^ow'z`|wT]-I@4z{fU$XF hzbTw~WN':Nht9!bX 0 97  x|Ld9]yA55FcM cdwv݀XZj4''@}T_\.uw|@0xp WWDE܂La($77@mmEEm- 8~D"˜ _eef"o~PQԿ //wt@֎Zu$> j(+ӓ "ƈaclaAe?BD)BIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/11.png000066400000000000000000000013571412405540000232240ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭzIDATHǽU=O"Q=o (D,XƱ&&&F-$D 4RI$ -~t6Z#fO]%&y0&:6Fp&ȘcDj,elvuKQek VVDM{-.\1zx,]Mxn :;;?ҒbMd[-II b@y{}y<]9lII,i~GGq\^]-\. g2 PnlTaLOF7$2iJ5-//u *S-NtT*|gLDЕv|D]_w50HLM%rya |;_uFChDBH ]_̀)N'8g߯(~?pHӪv*h\]5yMs53y(|e}P(p^*qwsM|my3pom[9}|n h& IHtNxz[}sCQcU(Xy?T3hIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/12.png000066400000000000000000000015131412405540000232170ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǽS;H+A=&ӈ߂"C@5} PZ$Ogc"XV*"*`?WyE}43̽g>lUUDBjIxzckk,~TW~8@,$oSS[Ryy(r~mla8$/Yf31Gmii^%1I4PӀ6ZT_T\pyyssyz5&c550U IVVzB0D~4tSׁ`~o~hl,/ol<%IDL0U T@4-Z`yyxxyxFG=G @AYP##8_}\v˕uGG]]GL>>&@oۛ6+X]U XdbVj"Hp:UEƖ>;/"gf^~A*?@LOs>;yOϏys|` ypsoMS9Ο9oia>ա $D5s"ƈķ cz0vw hZRIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/13.png000066400000000000000000000015631412405540000232250ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǽS+ta~;w&BS30 QR٫HI,b +",W#Jch.{oqǘͩs>{2|I꒤Z"' Z[˥GH0FX4 L쬢LO+J<~,Q,*Qk&gB858| .,U=g` `l{[Q X^8."y~ nIx4Hӎߏ8= hNgI \%%.p~.@*u{Je1McM 'kj~`ii ꚜ&.-ZKKnjƊ]Gd2B>ommm>6<-@iYz{ @^ٜ:?=AX[ۋC7wUW|[Yvfz8|ZG:N|/@yyaay9P_tb)h7hh^WvdN[,@0@,vz`\U $77$^WllllZfNfd6`6 01ML6(lsS&KRq1vrp=0Q DHΪjO UZUu`ȼ79U}~VՖ >!"`~QwcD(c16=(n9:l',jIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/14.png000066400000000000000000000014651412405540000232270ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǽUKHjQ]ĐN ¡8tX ́j 8i3Eq!H-Aڏ{W]{oMY묽=ՆBZ,r9R(fĕq"RBE@&2K&9Z:| J%ˎ@).dA ϫ<OO  RN|>x~fz]((xD_´UJ CTj5VպonA dn*yOx@>D(H &vf (~(sb|_0dF"hGrpx0N74R4 j77t|o&'Xly9ٓlh;v[ˈө)??FFc4z],R,`LW>JPT@q{h 6dg4rQx=@Q*5 pTJ% ;;>v T2 (2B Z R< ,k0r9%5wwgNDXHx>opzz=on"o !Ͽ rђma$^5GqMJ X$BIK8\jO\UeIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/15.png000066400000000000000000000015461412405540000232300ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǽUK#q}M$kD$ QD "((!L#62 rhke%(DM`P,LD%(~5ٹb/;M;{y3 h2HzzjucDEr"mzQ,)Ź9j<ߡZ\^VAQ}2Ţ2~r*%N'#7AĘid*(0Z:M @@r`joj*CD"D$or NOc1 N$an** ok B``c`0M&9v݀QWp.WKxlm t<Ng0KKKK@i(q/kjjjzܜh4=0Q$Q$_QVWedncS"Ed~7EyyQn`~xxt%iE"ψ&b(e1|>Ye0-/6IENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/2.png000066400000000000000000000013171412405540000231400ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭZIDATHǽT=K#Q=7J&c"[Mci4Sb@ !L6b 4Vi`yjsxʲJ2̽s?j&s6̼*ᰴDҶDD:vai~tmn##2>(" lo˘=aY }R- *ٙٝ=K|~6͵5\W3,u[[Xe u0@4:5Nc9j,(s{׻/6j٬a~⢮B@j5,}RlVQd q:ZM4`}H&dr0Oމf%w39TF<>3F=غYؘSa]4]቉pONyY vpAg\ƭmIDATHǵT=H#A&?.*$6I,b M0 H:ۀ$A+c+R;XXXI H j,1JعbܓNw_fd9essMsΣQaMB8'\vX4O2$H9.bv{?CׅglpM`ox{xxXNO8A@9p| ی '88/a*>sZv˲ |cc>ju:P?>GC؝@~R: \rB2 (JYz-ORu"17Hx-؇qqI'z<Ӫ SS ɜd26A<4d6nR~yi/`HIVS ~?˭rno:jZ(i@Pl<Tժ:bgg-FgfQxzj4RTBup پ_ ..S66 χCq21d뫱!ZJ)kEF[}w9!˄BH>Oi@W?T:и?IENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/4.png000066400000000000000000000013341412405540000231410ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭgIDATHǵT=K+A=!&BcHMaB@baDHaR $`ib !Bu=;e̹30Cml򲌌0FX@yWg9E4E9:=Ys %ٙ> ``ry)sN __9O$ `4r >womDkk0UUՕ"YuMu`<^כeYYcżCYǝkhPf*`iVj9L&.i[[<#%HLoLT 9vݞ]~Hda!tZZ T5a?/py~h6M ŒI ]ZF `Pׁ0i#xzb( &Jr01Ut Cx9!r8P. Qqs㚥""3?B˒\DuP ^ᑖȗP/<.cD:c1V,r^*q~{U $ 1FIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/5.png000066400000000000000000000013361412405540000231440ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭiIDATHǽU=H#a}_6,,qA!X1`-E*IUc.E@Lm IiD$$$*!/?{{rIxwYadymMggn"M#""͊NO[161V(dNgU@%IQ$io 67 +LӲGGq tvf~]^Fe Nx%A-.Z<?,IdFOLH|^Fcj3MB!uT6F"H^`s R԰.. i'|2 ^;_;m//@,(8z+b($f j^H(T0]VKׁJRr\gfa+x|t;ss t:~D(P*5\\8)| =3I4ID@&y6Ɔ8x8ڲ=?BӴ''qݮF\VxzU?=1FT(0cad2Q|Vb$$XIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/6.png000066400000000000000000000014611412405540000231440ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǵTK#Q^kk6j!l,bDlA#)X VA-h!&m:mD))RD$1Yd?x'].vf73;M`--lN'ccMOh_p{Ocf3kё%'6Y]1`mfs{xH$Qoo`wtr,}KBB5R489MFNjccg0mefutR;4P*=<4o !NeEKy`tQwd涶E-xXhb2KӼV(Z@ 03{{j6 %;;|H,F^.X^_^! Ve XQ*ժ(@wtwE$T*V*@,]<rb.׼f)R)TZUU(B#n gk-dVd2c*~?P,j" I(I@"5{wzJdeZ((" ImmDWW(ϗ|k|0-R@P.B]Kzҩ) ^^ dso`#z}S2Fcgg|/iZ(i׍N='L3ASIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/7.png000066400000000000000000000013061412405540000231430ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭQIDATHǵ1K#A,dYEH A?@`-DLҤbpM 1#ZL*8&as{B*۞˭reeѨeE@prR(u>nE!RU"faۆq/ DF"8N4y>&y7HP|~m-*fR sdj*(8KPHC!t0m4U4 ]YfRT >9zz l ǓI`0v\\6oo ggbpժz|lëU!j5!nnO{"bk4'#!C!=_ɑ"D@8 !_uGQc9燇w::kZzIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/8.png000066400000000000000000000014371412405540000231510ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǵU;H#Q=ofL2cA*b`i,@ (XXXKajcBLN!M R`)?mV]Ɉi.߹ch;sGF0fgOHƄbbe 6d4//?V:ph׫i[[,lܪ?aYBs? hwvj5;:;=5z4axy/qD]۽vZe]\uOO?uu|@\?^ cؘ$0bP,$07˭rv!IDLd~?ɜe2:p(($)J<ⵄò)Ɔ8Uf4 CC ͖J,PVvioc7$ BR)x]H캺\mm.NME@<〮:j Bá\_ؖ@hi‚߿ww: jZ|NN-D&&"@UTyRT. R)iΗlT⼣󕕦Wв/pp336PHIF"sD"ƈEc,4T4? g=YIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/9.png000066400000000000000000000014231412405540000231450ustar00rootroot00000000000000PNG  IHDROc#"bKGD pHYsHHFk> vpAg\ƭIDATHǽU=K#Q=o&8*"*H>A¨Xhg"b'V#B Ơ5`!F"& 2/1-~H\_{0 M`OM탃D6h_ {{c @2iۆ֟:;UVյ51Yn&g[[wuqln`\zt$|KNN Z5p88 Jx%@gc0}zn2M"Ӽlu~D@>_(|_a&c##6qT*q<>18ۭn7psxs4"IDLi61#xN \] IbLlvy9NO%Y$YCQ>E=h55_kp4+(+b|^ׁ}ZժUr>lZRX g ^ZJ뇇Vk[@4::KD"ÑWW//r+8>n[tv*  B@.w{y*j"awvjZ" <|fFzvpvƹ.R7)q>6a#Y\$I=z]\u@Q&cmoF"aU~;,×IENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/caution.png000066400000000000000000000037371412405540000244510ustar00rootroot00000000000000PNG  IHDR"":G gAMAOX2bKGD pHYsHHFk>AIDATXYlTrΌ=ټaRBbД%/D1jbB"P6,!`JixSU 钗%@QS0ŀ2c{}Š!9ҧYtϹu|EC<Ƶ.&J  (?g@mUU0d c ec_5\?G:K<4wlkiÆڢǜrzk7eꭡCc`YHະ*cgH-{-=jclK< R'VrZ{?VEfu;-hyt˙4X3()q`W3|QPmAjL+4qu"TzP!$2+,:H*e,i Gl(= Zz6VgR\ɦ3`PrD-%!jMT)8`E=b j:=-7ΩJSe3eĦMxOf4&j'(B +tY؋/W!nR-1iD\MlT.`S Z.̦f02ұm;/e3I%.]$FD[;X5o'6r 5q8cV~V*_.%SM[ɦˤ16a ۷(;{=*!kdmA:7nyB4Rh%iFY0 Ų KHcO̩q2j2ȕ+rmyu)>O|$DR({cͬy @ Pws$?;CPWOҥnKo'4Ͻ }+N鮟O뢕©W) LsPi͈L {wXˊ-0oR<͛4\y\>y3{v O}4 -%Z[F+9=}X3 )8Yؿ!ڲV̢E<˧NrfnZR)PJ`|cc&f3|3:8c8}}ЕptY+535&%ek))0γ=H45Q<1ĪY㟠tr<1((6jՎTtl؈>ͅBl}\Z"JI"zj5iIt QVcz||{[;~1oikeh|TD*Րr҄ H{(#h {ﮫ)͒l' #`:;~kW>MPJ!D8Nbi,DHK^c| g4br] Gs1Q;yHG/ &.k7Uq!V-qJR _HopqnqhEMkq'!p! )Ek9>8TG2iMʐhbQwx4+)7ikGd,hFuHRa vC-VXK[G}y!I9} (ΤJ>8qfhϱuet6)8rlpnvEl>`UĿge+ZF#Q:N؎U5BpJo-98r)=Ϊ Oe#ZEU"1v!ÿAL]k*'qZUqu8]C Act<,ьOz2N5ʜ'.Eck\?/7*ț_9'z_c{"zTXtSoftwarexsLOJUMLO JML/Ԯ MIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/important.png000066400000000000000000000046001412405540000250120ustar00rootroot00000000000000PNG  IHDR""jׁgAMAOX2bKGD pHYsHHFk> vpAg""_IDATh[lgggwfwۥ;¶íR/ȳ/cb4Ę@Hb5(I ŶPڮͶmn;q 7|39s7g%-;"Q$g"Yd U ōkєLFŋ@Cs898EH|>}ɮ^HV޲e׮N( .$[Zzg::o4W޶-S׬ }0J%x?T*ukCC*._+Wn>M4E=/-/B?+65 <8 (DzCC?x<_'N ^Gx3!e)'x`px*Q](UhmmoO$:;mkoߴȚre#EGG_d2㺓:NMٶmW4voٽvzq$Y9z#AyYVGHe^WTUQ|>U8EXF֭XB[Z0(&cO!0M˲,l6鹹 ,U.T1j\5MfţG>wnjW3"9|zJc,]]~ ޮi]],,s(4|4(Os\$i,B#,Kh0)jP:mp-RqQqPmq=v֏΅9ØDH$Zb1b1 DaIDI ! ?UJ4)lda|Ɂg>wo:=2;.iPX cP>_LN:Noa# Ԋa(<0(2($gwRR\.;vPo͛}s{NLLO6EaP[p ,\NϟC!8I;:Q%Ex)'G>]u8r3gC{oK]qw]|A1[T*y뛘 y9]I8yeH-3*r0>S >ط={Ʈ^(G TJr`.cc\[[(JIRss2bEc#!T0ȝLIq{Fw#k_~Ru-~A/]+WLZ5M&o׽d<͑sP=X` (I4L:N ##0@b2vr+0SnP:AaYnn&<iYF(yuYuR`dk.4AП jue9iHEYfXVeEa!V\R|!P, 2H6KRH֬I$$I94m۲дi0-H^ellr2MEi;wrg麦q\(2aE]//_7'ٞ (έ[S;7oޱ# ֮4hu,u  ǽ^Qպ:IjidLJ!BErzww ˖QTs(jB488hw޼N9s@6mYٳ5FG3ΞrVܰ!{͛wlk UcEYhD[Z.$b%ժe9M H]lKZҒWvn1!"zTXtSoftwarexsLOJUMLO JML/Ԯ MIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/note.png000066400000000000000000000043071412405540000237460ustar00rootroot00000000000000PNG  IHDR"":G bKGD pHYsHHFk>gIDATXkl[gq|Kعsu]ҵ ڵ5&bOBB|B$$@ hRՂhQ.em)i:'nI^&qqm> mn)>H^>y >< Y hs$i>D~Db4~$5{cccѣGXuȑu_03Pp8|ejj=`@EeeejEUUV+VUl6yH$J8} \n,LNq@!r~,OKK P(H&ȲLQQ `4ikk83H-..f'&&~q~~~<] BגdX;ք_?~Z2 qՊbA#("LNN^}KKK#掲24MCQ[[KP ɐH$QWWh@Ӵ-P$Q__/466z'N/--=4(ڵ`0 XL&^d2a)//G4$i&;@ # $뽭NшJf$IVVV4 łnd2 L&&&gffvHPw\.(c6QUEQP|>۷fQ]]};Ř󋣣$rvGYY,ilΒ$DXZZno}C`2*].qY. ׳wq8z~lۇ(LOO@]ϗ۞R)^!IB*S![J[1szzzltL&܍h4F =Gd2TT8)5U=Tv|T 㣼x.Op8lXVdYFeDQ$355bl6nۍX,:zhCL%ZJسDVWWD"0luttgyfA9ȝ]QUYc8g~IEQYYIr@dAA,"UD)+QZZBQNڨ=z*o( M˔ͱ{aax;7[\.)ٻww_|Afz!ZReaMAEbWhJ x/`0›oj==7`DS͛7l++lrahз8PFYd0Dry[$ZªbLANvfo?{SS!Y{ɽEfK72[ܔ:tt:n,f3^U(W4YJ\ʡG+([[(stWo5}=/LL¶7n655}v\M>xd.L&z= x/*'O2hdگęMy>y6Қ=%%%OtvvV7448 555v6x<`+Wd.\p2x)Jm_஧Nxb6F- F_c۳a@3eYSSNSUH$+++WUU O'IDATX͗klkml8N(!)!@bLP PC)KUZ VVB%*PRT)R*Hu7{܅KlDA$Y 614Jj$adY㘳C\D%Y'&]oanRZC}I jD@A5 I@ .d);NQ֣@)#7*QSɀ"IIs⟢JV$WA$ %AAmME .rآւuZ) M2r&HYQi=mv>8/ Q&|MӛwbToё˨9*">,=9f-ܠ/ ^ ΡH\}wmQLGBTcDm QuUaKHeidѵM_|y[MR'ӼxɡOFg?+D9F 0ͥ8Pmؠ$ۡ&r{`5QB\iVP' x-ׯ+eIS)4 kW +m(*N"bPƤ T\bԅh6H$AMU[X5UBROkh|k L[:H#FPllUJ2~\WPf'ФDu'9LjhtyTX.A\;O6[&pa136A;T 'NV[d9EhFƓU ;&2orxzrDg +VgYbcպ<tv[ذ̻lPf[Xdh(RwDWwF:Znݛ^<<9(-ĕpl̿_s}V&ǁ>g!U*XX.޺E^}թ^ %*A<_Ɍ^G=>}ݗPB,? .nA7MXCYU3WK6lo*2l,Cv>3ޝci;X-I׎"HSxtfz488V(<89ztuZWѨiA*E+ /Ԯ\{k|hϞ3mׯ0 :Ç<`OXM_\rygSi;}ǩRY,??C 9#bCn&+˝;<=<&8+9A#)Yj2 sIC|I0Qf Qv#KtG(/)K@uzrߚ(%|>ǎ}ґw=6ad4ua'KP]b<eKtuӬ͹۽&c6:~((u]Y&%@}L&m{[)m5H_e,Yۋu'¿czh'.ɧԫhOYsg 6ȰXǞjCN\G5)b2,,jG~ʲ,K%= ) -E灈ު? _>awӃ=.idʞO`Y&,L{ѭ>G~`d=rYHnYFIÞ¾qNN@86?xZcrӵL,Ywh2Cơ|R|H6$K rmbKVSM4ek2,W~4SP{!K`e2 䚾jߓvbJ|bXSS^.,_z")\%iLUX7|fRa])SL;i%ptSEz36˪S.Y q2&=j}d1 84r7Ap1[d glH\nWn-YFl\d:UiY%iX iS}NUzEd dJ4[4F|LUVnQ'K`9_ܜ,2mid +W&ҰUUY%%ңr:0*Yқ,aWCn,ʍrCu]G*E=F\D+Fvwd+˴V,ȝ`Y J%d nʝyr H,wl=|TדJd `,w\z.۟,6u]G%\XILIs˝6,ev0^+d +K}`]a%YV%Y{;tn٣M8Gn6y9ӒӠ uz%܆e[%WK8)"zZ0Au>("αL]Xpjuh(ʲK3&= Yb F붮,J|_$K5 aFϬvebFYmae>l%YbWxt$Lxtz"o[.#ˬFLV%<Oe/}%=t:Kװ224Yb~-:1|.2}<-9ºu?TZV `O6%TUjRrIG2CS.%~{,U.~Idiƞ9KQ|>d-ʩ$`+#톕d $K8xi}dg|\%`>dP ˔s7,Y]Ӗ;e>َ`v%K–v"I.sɳ,Y];Lr7Sn%$KL/Er[ËԉO޼֊%ǀzWk5>+{iQ"d ,eF-UU)y#5r .mMzݘv9Q,Llמg:1%S%rʎx2 $^LIE6I"Ճˎo-]&d[G)^~%KdDk?/\P]w3}~lNr&v(ݖ ʣ5s$GRR,A .Sy1e X%S%v$7[ZÔd9D]ht*q>mKϧ w<%Y_]T.Ym9Œi.7m:/?\MQuGq>CǷRŻ/k!*<3eX]דyî' ]At+fGG"NhealTLYx+Yy^rZ_lPCEdLˣ rc|nhN[ziMSvlvr8K,KUU߬R>#D=nsXt'Ekn(g i,x>S/pEjRUUUU-UQ#,O>7On ӖS%ZB3(3SbV|2ۗ=B^#L >G(l.0嚃6M.ՔEQe٧S]jvqFݗ%ͭljϴvD/ĶNRl;@z]rV}u1_Fe>hyF鵽vk5M<'dqʚlC64 e3Xu>ᴘ0rݪz̐~>u!_{ZZboGGprd=Ybc4;ukzr0ːJ߯n9MzvyDYAG$i(\kez]kxGpѫ>,w2gu1S{+ >rQwf5q|YUU:Nez_ I,1߯en4\&_Te 2o{,iQTǎ(cFHe{$Z q^ ʗJ!O]5>\2dDbS3;a+az_O EuH伳r|Q#>>9`wrs!EQ:ٌt(4jt)RdG7,}R,{tt0-ҰKH(lf Z^EQ<tѿ?tx,7ҲpneEᴿ+>?et@d)[LÞ',=|>_WUrclXdyhBk^.r'\q.p,Ok, ]|,wf%˦5=QV42{λeUdy,64mYd+Ym]*"˜ Kܛ, R&r IY}7]u%rEY+T`Cg&. .7q9>w8=k]UT|^u]ugQR K\v٣RLG6Yk,7\nbK 2th(g@5AnEg0_Ok^.,Yd]py\C`%A|qgq>~>(K!2osݥ#ZÎ3Ok^ ,^(qVvşrPA.nv/Q YYe^,&H\ߛzBn,K ,^fdh% _pJx<^L!dbh]ưsWftO_~\.}$K@TCe:kDn[,ΐ6MEjB%H0`*Ҥ YbQd,7nnSf5ʬkdEIL^]lj21Sb%}!o[Ye443G -˲'%"qS}*wGzI[+fCvl% ee{r+a?CIVDC:yߋ^,1;5*[ؗc= %9EQ!f疒%K,ޔ֊.JD3JKMng7]d5hni̊G!Oy\z:1#`.{e3a=S&4r0|IX\.+ƗRy ˗d2Vش?Ԥ+ds_?4q`!Fe*,5)㊙^(×d5}6U[4e~4q܄~Z5OJYbQ_ G`5ajR(U|N2d%|DSMaGm%zMj]CXח=xYbv_؉KeFIݭlUUէ[/l4|<&/ q^SeG[Ә2l]ןM$rX]DfrnK ԰SeZM<|>#tDnlf>BiV0%6n22{nlS=t,@s4aYbїzEZ8>Z_W֟&;ҢIdS0RU+u]ZF"uCLMb+it JMi)`ްzՔW92j%VeYe3[q+&ಪ*hd̢(ދI:r<؍/C2V%|>w-OxQ3̪zR@ %33d ()\,h-ywŎeiXq%Y%ЋO%Jh,d | (?m#Y,<Jė_Y|Z"eVvy|m =Vط,}> y>=5&Κf6Y+%KNS@d >R@ aMѻtk Kr^1YAnk#+h-|5I ,zSiV%yh!^W[d'])Ր}Y∦T @d 0% YcML d dJ`:;d”#N",1>t%)վ K<z,1!a)}_S҈SdPUUtyJ`S%Yb'<|JW,[}ߛr>T<ϒ4dt:9KV,mײT LfJOLj`פYbuh "Kle~<)y^4l Yb(edI؉)4sdR׵@X DT`,[T%0kXmn$JܲldMQ)iQC<) gJQ&d.$`MY YbcHsGSYjCaz&dmL LVF<{5&˄dmSUտIι#KlҔv#V%Ga%SEQx +uԦ d텕Qсy`WL,ðR F˲%>rد,=BG4Uy%Kl4NS~Szl%0Q( ^fc^`T%Yb/J* FDvy{xToVz,UVEa,W)K+F_t\$K'#0v2dRX LkJ%6`VSNf J6yd#˦)!Kʔ'9X)AHQ0%"Kc׉:XF 7 {7`d Lhʟ*^ IDATrϲIϧ4jd)VʓIJ%Y%h>dɔ&, ^U,т/zYBd tjy@ KtRYݏ}k-)A[F8|^,!%Fd'< K,%tjy@1TR- KuSJ%>]m_%3c%PZC dJ^9',deJ+C@XlJ,1`̮ "KlO y Y@&l5 ([J%Nw),K%kF@B%2OI< K,d %P~*+"KǼy@ї`a:P*Y"wY&(-Yblvd y@ؒ,JyW%6)K\P,y 1vBRd tPd7_*B%6ryd9J< K!;cLPڑdDJ,1@"K YVd7` y<\pj,YF]Cʢ(ʲd[,'3 y'X45򠲌HDkU@ q9V[O@ ˣ-q\c %@0mMy~S(n7W{ED&P^6,!nkkv1% DqؽZz\n}ei+`U$|^|†)+Sdܫ)[y>~~`%,OS.؜)ӻcB K.nʰ_MbFis$%@LnԔ鍻n&)M{hvv9FP2A~ӿdTUU׵d+Y(uDUUݵ39;2z~Chk InцOMWol2|u F4Oikݠ#%ij`,شTsYP׆d< .% G.y<C[wd^.3K$`PŮd$d Tzpr :—5,ɗ9H":+Su]_hTE_zGf~dW+hOO5w,cpI <4ՔG (})$KdAYRXUUq,y_vhPr4CTULЍ/O=d|aZYjOT+YBpy\}M)ӹs>%2 .̏rɰPEZ)=%2 .L֕) .ɒ,C[1s!YBp^'LM C#%.U,q+A*Ѻx\ P8,g)b5Y"(]"d);hDDvXs)$K)%Xy4%Kl&h-Yj:DZTcb=#EdIȗ@Aؙb,D,`.#ѭ,@d @Y |M{FPF稐At75[I8ғgLs߷r򥰲',sʲ^{_2ʪ*c)drLH:~g{ͯ׋,J{euޗ|feA$r+,q=-1y9/COn{ZKdI*)SExsdtUUdߔѰ Kb~:êөJ2hf%B>|%JB!fZkEDwXġcms#QX|% QEk[Ub?atX V%].o,zZz<s+3X9.RC=%|m:IԚe>Vn,ڬy^u][jҺy}OPIM[iNTǔέ$KB7͗*|>2)x:wL{g z%0Ɨơ|9-9㈴4N.݌j8CIz )ߧRѷw(3G '>%0/C—3EA&$!K`/C2/fi^ ƩW(ٓ(z||}i~e94,|erqbBl[D5n;8I%d %є K`<3H+T%0%pԗņLi ey=_n |_ dXvCrE#[ݑ Һd ,DYi%!_"7S$K`eH> +j@Zx:/ԗ`"CSg$K`M_زY,er3eU:S%/[`%V7*ȋt - )mN@XHT,,(˲՗J~0)W$K w_eJ~)~~ Y,HO)1 1%hMR*|EC!vx!\.9ד_A@(xiPfQrt(Ӽr^n+z L;ֺrѷ#,JJ%0PQu t!M>B0*D K+BVZ#̜)OR K`,2<^P%|>4RQ. %pTSDfSY~oŀG@ %Ldv(3D2䧼kQeY K /e*D' ,M(t:ΜOӓ* V@yR& YVܚ,Ҡd l@ֲfnV ^WlayM,2eY@SxkjnMvN,[%ȝ:Ok_g?iӺɷ&U,]ZeYl(kʸV '=] K`W ?5 ֎k;7QFWӑ' KfX؝}7;h?+wYl5 6*W?&A%]I;,Bd U m矎I=> ɬ$Ɇَm %] K# 5o3=a:LYC0BѯCYE8l8?)p)H.,#Sc%Fe]!A,d濼y^n3Zgd `ȠQ=ϧ'`SRt7d `?(Ǡ, K, K%d Y@%d Y@, K, Kd Y@%d Y@%d , K, K@%d Y@lRz?u>?`s6o; %u>Ϻ߽ ^\ZRunqnw7b3[㌽roA>/߽wGX\.^_ߑ/RYBo7t͝~CUUVo#q>~~ԹQz%Kl) |>,ˢ(\v:O*re5|e{̍6Y"w7ܿ}^xeA8C~_.QT7,}:f}_G:{TX]!|F v=5>ߢ(ʲ\Xns'g&l%Qezu]_{CiR3t^_: SȎvp=[U~Bw4B5eW2GM%M~{aOԫ^}ڼn~ORCU-%}*.:(,M8$'/;}%9 YR!h)u3cKTQU~^rHw4g*KW05i~Ot}Y"SV /~uak+굟2.92mO~_ ||>WBd J?<N6eLZ{ɼܧGkgXyl^뉧Leuf sX )e&{7be!ѬX(gKud*ZJWLnGy,eg_`2'KĚg:_@ ܟ/%"\^ڲߡtW|Ɇ>><l&ޔa#Q|E-NxFy-h&L~^.hCtqFX1We|EηBHsi=',羌׉1gQ8#r NtE.yS'/Y1ϻMYUՠ$ RMhAuj|Q5ȔC d2[OJe"=TʾɞO~lGp&U4T1Ұy;5eߨoZlg7[|N-:0nP9܈O#-nƎT8 '?*;RhؽvJYbi X>I.,~O_eq[Ȧ٩2mM^\߷;Dw oz}'ӫt,W49YCӹ oPxeqƠʋV>7teY$gI#͏<{=:ۺhDDb(ҴOC/}9"]@XP}B-)&AEv4A&a帩ʐKGJ~N{& %mkt]Ј:v}{\.???zFWӖ ik|vPCJePG+(˟i7hP*ɟS[pʦdvɃALʲ9JF,b$ïi| ;ĔaeS|KB:Bu.h 2-hezNUdʷ#_\w46jP'n#o^Ǐ% +{;y^Ļ^ͩf[۬g>Owz8p(n<$JkoB2,ikS6C̵Z{ern\۝VQOvߌorո a馬K D򴩝 F%wJ~xM*&MӯY%r +ӽ+*>6-C×t-欓Cqe>l55QpIWez=>k^^d9NWDu$ ^k/$K{luzԼ$ꊶߺ,Y ; Ӗ=@ۧ|E1A=̋}&GHch"t|iIJӖd⌜{4ӳv(>"~fc*:ZyA0"od1]묏Lds_;QvK /s($K{3xPmeZw*؜," ~oJa崥=dI+8ZX9L|?-|ė*&tոLT`qDfdm\y"غYсaGLX.Ӯkh._J% .ӶTq|7YnU+Y&/aP.D"akWڼ>~2},U]/O[8 GM,s.̶zhfScO Q3Njgruh&vPE KL~mg<" }K{Je2A6$K],Sp6tPdB]ǹLxrHI/ˡrlML^bocs>f龒THq9߾3YbKLlcn!=>qvl~}X`buDd: .?}ڢd <\dV>.$rnguMx'C{tڲUцPS`SU72~dB>Si}Fsm:ciqaPUKi%&m\|.K嗺~ZsE#nL,YbSd(9v*:L%<|[:^>:"=areY擔d~qjResutuc~A O_h>ѿLhDsWQ73F\xW|U ں9mL[,q^oތJñ$M.=}X~d9_Aȕ,"|wLS i!)L:qwd2uHî܏\}|/g6>[JzS$m} .,1KKcĴƵhY3~ї'xiIO’% uNVWAg_Aw\iK,7Yzp~muqПҊVq[-rSv3ylܑSR3]kꞐ *>(ZP[u_}eQ׫LYABXϖ+RNBSAV"AA7=iڼ;nkx^O(,W^u Vw IDATxo2#Z~PX&d{%u|5m۷(zFlSE{e:a9T!KLu~9nh/+/iF#N_eeuOx>O;0(47EQ0g rT,Ag>o6=ψAI%]_nС/{6,.ma׶{3w%˲g9gI貊, ="k|~MYv [E /tdN[%ˡCr dSAgxfy9cӋyJYbiFLi+ݫ,ڻL0w#tOXvo\% 5N_F2xǙ]~o+YbsS2DQ9ezs LXcIUVާgdiB FO^N˗녖 fVY\j^}[ndgY|W*:-Zyr;>.>wt? &9j-vwqdo?.xWuM^wz{,+鸒/Qu_'5>dU ʖO6ݒ}mg4Gѷtd]Ń2_NX%Ybp'Jʊz=C:yp%D2_p=ꓺlm{?˭N[u_̠/)Yb2'N^e\QtVN^vdb;d0ǜ%Y=(N}:'/VH9+,^ψo>7X$K,m>x<,Q,2SܽgE'!eQiW׆,(|>7N_| h#yգ357n=z/ö;UUԼst4LA_¢)ˡ%]#K\0t;OS߼Nc-Έ6? .Q8S-fi>@Կש vckMߟzi6̍Y&MNTO Mѧ tSƅs bsݾC4eY,):z4&K÷;Di8YL/lݿ! cӬ: =Ԉ.L\].W>zCkM^>м}V ͸vq7Crݟ[u_*5>k{Q,1fG4Z>P-2iϸ㨍Ѧ<%}Ц͟/,3k<;4TUTwdT}U&/{;Hu'u-y{^;49i޶XeI_-U~קks 4Yb՗ KCԛ^km~2ez a'AwqP|iȒ,1/[we0%&?EQl:#՗k]F4Fwb[܍ aǙd1}wP8p.tanR,˖V^\Fw FluOkցݫN!K.  u]w[ lI(nB >OrVYwx痁/YnKGAׇ`6r\Y_`t { 0z丛{^Yҷpu{;ݟY";~R?Aa(VҦ ^;,ˢ(cO_0+O7(+"J?#lkyܤ2CG}kvIѲ_q{GS퇗غ2Iچwߩl*qۗ AL&4^ha'Ybv˄}^ͣN6gL{hl7m5D[ߵߕ,X!Y}ɡtra]d[|>dڸy393m}ߏfI,hfޫ'< ̊MއXܶJ G8;LN{ gJ4qa|Tcwv4 Sɪ:ᶢݽ̆v-H'/sA=o{jyܗ-.S{!Tr*%Fx_i#1@X-.FD@%d Y@%d Y, K, K%d Y@%d Y@, K, K,Y@%d Y@%d , K, K@%d Y@%d Y@, K, Kd Y@%d Y@% K, KNIENDB`okasha-0.3.0/demo-themes/default/static/docbook-img/warning.png000066400000000000000000000026701412405540000244470ustar00rootroot00000000000000PNG  IHDR"":G bKGD pHYsHHFk>XIDATX]pUvOLf& $!! !b"$ -R/ԗ}]_Z}Pyk_}X(,%L`BRB&3ׇ4j0!ȩ׭[=N7ܷvΌh&h9f|Xq-{L=N<_#qpvo2y>5kJt۽ʬF<ͷ]Jgv~2ueG۵0n=t8+xGR5Ol0; Hb4zo.{DjH!:oPL0u bsKx5wEdQdbFю^:6gkn| RTXJFǴy72s.ZvF5T:=6OON[|m|f+D"NW}]n+,t2s/Zg3_{vuwgXww1}mZ_ڮ}= 'Uuܦk˞84i[u|&/6>ϑ 2p`L&;;wup,su`,Y@tw5?4m2 Sb a`x ka`]*M$jL=P9@kSlJVۍt@::d8sef/GmHf>HEȲH4Q=ͶܿnkDwm;rpo}Ry!=hU"d)bQCPVE9E`8\1\TQ]G芈hrq߆z%²a Zidš5UC}2[Hdڹ#ކa19mR!XI(!܀ C @ >yQ!^=:[b.:YsyJwO#m[򦘽 ia)DEX oMR^ H a/tb14S_gT;ƸPf y^~]N4[k @@DHDy%s' \]FT[kɑթ3Dy'ܜ5I^AF* 4#, ؘj}~1# m?SG֗Ů<+SiJc:eTR *Qf%g ?ܜ| 3s|gsbQdpP뒾jm/>ؤD!C 3ZG0-v=7nz|ُ>vMkY(X +5 ;vڒIENDB`okasha-0.3.0/demo-themes/default/static/jquery.min.js000066400000000000000000001576461412405540000225570ustar00rootroot00000000000000/* * jQuery JavaScript Library v1.3.2 * http://jquery.com/ * * Copyright (c) 2009 John Resig * Dual licensed under the MIT and GPL licenses. * http://docs.jquery.com/License * * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) * Revision: 6246 */ (function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); /* * Sizzle CSS Selector Engine - v0.9.3 * Copyright 2009, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();okasha-0.3.0/demo-themes/default/static/logo.gif000066400000000000000000000170601412405540000215300ustar00rootroot00000000000000GIF89a000@@@```PPP ppp!, dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.znl|$ۇb~@{n< k8  0 e /~ g  + ub" %֧"b˷"" $ _#"ס# ppD?"2v<OXp6O48噀%qTf`^ `Bd @w"AL& j @M3QN> pt7 *rS5F@)D[LQ ;S)0I;8p $XkGeW$h @  l@W<3^ss&` ((к\!GB ` -^Ll)^FgC@& g=q{{I8;Idp5̾s G&0a 0` ٗAE~fנX !^ RB BtqVe#PiqԵG:00TL/0bZ1cC .d DFq1P/ڜF2r7>%3Ra)hPΊǀcfL5x@,S _gB:B tC? (e &ҚÞD^FQ0 ƲQ;TM[IZ`GBam iẍ́Z=\%  LH`@q aQWjۂ; Xy*LV}ɒ ث#/N T3$JW$P@lZ`6&؎PX* 2pRW0 4<2HqSWH2y&AA@ЧBWl1t _E !Xf8 ԉLp9B~]cb'@}q  - ) % #?,R;p;W(>Dn*m3.z B_"8 6/tjJIxfO}<$bj8|-.~ T PYw+8- ;Afi2 bD JPv) (<'d)~e!afWFlQ,m Te19)BMAAa{1Q30i2X ZH$@3gO7$;eEY !C"n6"u[t'n=)&a`F%.<N _}LT@M ^#;Zi1Pޒʅ9ȉ "Z5O\(j ΠFJS< ti^0Jv.xb f?0 )sZq(X.fjfC @#<2?2At'&*TsAB/pL'&hnDi rDM%pj\ /H\\ D @Z7$࠾Wb࣡G|0ۚ dIc_1(fNxUi#-.hJ̢ůil Jiט>D[O}wSI.`GmSm&ɰl|jJuXQђmBUzpG?95$IeRq2k@l\\o`ZhR n2 \ҕlV:g%:k9i2)Uxl-@1F[2Ki(( ܆?_zL\́DmlHMih6 7^"VF pX)g q7٫mu:u L qv=;p._MfQX Lm AIIgKJE+ֈRXvű{eczam̃%$/?BGGV6Y!EǂtTw얿;~\:7g_*ƨVqz`<AW ]s?$@踴!c`J2A#6nA\.t,Oua;~A7\_j? /o-a nנfȴ Nw5V0R+3< ?8\ŁZK7pMPxdufőhPӀ ȹ̆켣J:GH'6~.5>-x;= xۏ24Q qEqDH'ug1@yCHh@Pk1v+Ucpq4M`-H7> AqDm/HWn1pQx2uFgxeuz̄|Eʄ2wet#Ez, fB}r/:&li< $+@i;YRVX" &l":%e51rKrA uBJ&lV8l0]xD^A$|qNܲxu5M,* M1 qW},rl[evŃWnHp7EUЈ7+-:3=c  Gu3lyڂ|ȡ[wYu.#ČCyFӆj ,4Q+U>bex6:]^rRZtVIrWhcv~I !6ʘFm5u-5%y,h-zWYsShX4b!35GwY2BD)a e$i CuϘ (P5U:0VV,iw8J!.BCeKx,RM[Et3r83)"@;|q&95FS;c(劂:Q1s琯BSB# &i'2oA f)$B{R'2-X$(w,3[U@2tv0*}ЀPpܘ^h5,hETy INGygx7]ev[2O8&aN`iB@mdG:Չ!Vy3UC8M?p0 pw*/8M(;#B;Jw  8M\KJ Jș"rM Xx&jyhH$IAX8u]a"NuK4xâ1N d}x J)Oi쨕:*2t= ŨIwpTLCevs3uD]uTWP!rGZe3)+}L`Nz!}@A2A{ }cN0~)gBc06Vk;#e87Jcj hJv'I]xp4/7z55/K!TsQlj8_) %MXX#eǮ(sb;d{iefeőVua붕jit+xhn{e|P+p{n{ɒQUk-Dk Hk(J{eL'N;̊!/BDZfҹpDx(G[WƩֺ0"Qjyb.zy-kڳ;ف9 , (**3Pzρw Q"{/ҷ. &pEs ^{Ƿ/e6ej+%4薤 ߪ ,+r=PMv& [r^8`6/^SG$uJhh3⪄ȺL,AЛ^*w::qjzõЖ306ڦ p *~ q9j/KJ[GuTfg,]EH!ĪVs`> 6J/k"aҟ䭘 _ Fِ-pxS;)HYE 9sT4%^CĿp"¯䠭SE)椞ڰ9ĉfrɜL0,ZmIvJC(򝐓U+*Y^ɛ=)IN#˔KgcOְyI3ߴ 9ml[ 7~䋙kNA/O=(ZY9pǖgLrIQ"1x9tECДv4\9 tbh[c{q5Z Cq7Y29i l0=Yq@WYDYR#L`tvH7ϋLZ'\pIQŬ16 L٣>tM}Y;=](% @LX˪UYu0Ca 8<9#Ya ~M(isKZa˥H%tYAUPz5‹ 'dQ-cC12=贝hzGqwnQ?hL,b(̤ _xCq<]ge-,LtJ1x脳*܀WjYs nֈggurAR9@^aJRf/]>{T5hp6TμL$I\r}D <nZ'Z`=1~.X? ϗ O}}w&Ы5}~9jjpNzʗ{W#Gi2U||x3BVE#!4T`SQN5 ]yBvK 6%zW5f-y Z .UiG&T< 4xDZ+vʋI j2N_q^ZMEH'ͱNQBT77az+6}1;dL`B:XP}!֢n!a(w5g_q7S١pp;;QT9W)=`qUtP<16(;oi7+kg8o9aSOcrRA'.UPwlX-e/zԓmv*k=OZWqӔ&~Nk=pkn;OCv[ZUcBi?Frg&2S'N vUgL1BN#@]J[u\eY3d6hRk}bofZ0i 8BH0&*p i@h=c1Jn%ҜSݵDu+64N,+](Jh(!45Ť8 8})RVّU ZƬ^,840D%tխ z M`A ((  ^, 4,DC2vEEqZ. 0$V "aF^$86xvE#'rJd@ O05ƀ F'O8 U`ڱ8/K@ υa`-FIطp>S.X1\( s> @q`MX Sn: P##.K@- 0.r  N| W0@ή]@@,( 0B5׮v ^R bv0|m02+̺_qWigh pcpѹW !W8 ;ś c?Wh 0!. :|h N&w,) 3 yP@ ~m5P1e$w5d8_w d%pX hEa! -FRT}X&?TU e#t 5F ЂWN{%pr], hG0"LI3E1DQ,hZϒk8qhLxmƔРÂdTU5F vG+ŪOH&pQPƹ hB]ZcQ$lЮS ; ֌iHϑ(a, {pJ-}2lpD3ېHauLؒ t/y22 ?>o֒›fhLVPvA0M/wE1.Bŧ"AS35~GZ\c.f&8|\qU\b#``"|ˆQHDE(G"Dڭ|g$s$YSQ0FHE Nd,q5 媅#ònrKُ vD I]"J2!Ba%2E CIU& Nsg>`9H8 5l { (.\A> BI/h$)Eb'`CZST\D+GɅJBц3ەHxRwZQaF{㼗ә7HT;ئE4l Lr)"&өJ j}8fCn䰪J!FVC"@fhݧKHGnD<# @!ꨥmgxm"Z[f[*p!1=Z67K)l8( gv9>ђ+aq3YjB1کs KicJl9)Qrq$j 6bQ L>b=PS) 9 ug=cNReK8B2l##9J^2'C9 ;okasha-0.3.0/demo-themes/default/static/logo.png000066400000000000000000001355121412405540000215520ustar00rootroot00000000000000PNG  IHDR t%bKGDC pHYsHHFk> vpAgg܊IDATx]w`=3 !4Rч`}G> MBU> >AH "E遐;ev7w6,S=\6l8 0!и1;/`h=ZX p#hd/((`C@+iA`W 9Ihegh֭b`Æ?_6Lej2\ZZ{tk֔K {Uܦ]m}+LCl[ W F0g^W^6HLTeU-ρfjtw)9~pOWʡCךCB:ߣc)?oΗ~:|og$Vkzg*F(I~,(zŗ~m1t߮/`h9wfh]U߸(\r Gݽf+牄pyȁ(u矀Wȧ:BB Oʭwś$ ks% :.P>*ZEL'm(u@\/. kWj2^lH\Y >@<^aWG_ᗋ,[&JxN Ԩ8scؓ 86ϙܕ!4hh؊6lFќ v8 3Չ$i#/3Y= A?- ڻw AUpUx4EP tP'>9a~b: 'ڰ`asW{<Ø QDrP(~pΤ0WqMΦA/z:PĮ@HMx\P;AHzHM蝌ϟhOg萪yAnIS6[GgU+תUE6QI86NM \p,rA2XNp MN/=//WjkՈQV~pM@Kу)I-t:U <'snݻD [*md_6 F0~QwK$)J.|Pp`S@4֙=y+2t5Ϯ]N!ظ1tަM6hm0 Uߔn_k AJ&յkU7~Gƌt! IvhSRfZ'}[MeĢ"`TS2 ߟ&>BEx/֦Lz8c*:C!V^6l$`JGO) -*r.ݜCV.nb*z=sZ5;^L.cPuW^ LzF5TKF[@f& t{U3sPu\::E$ȦMf+t\JHjڷVe9bbT(%xEBR a8 4Y I0ۼ!Q8\~|90֖l|n͌2"SyN&tC\Xid (yg'KhP3"w3rQ4Znv.NZer,.SD.\:)/ߕOU uy txju_uI:=j>g\ ~,8/3&eckɾ8!z!Ve9cs \SR::J>O.l lf%p-umWl*Cro F)ݵ_Vur`C2 hH:L=\}9gl? ^/6h{n{fLOgFt4 >[~l!3#51ͨJe2|S f+τN PЁ׊_+ذz2͟Fg#CN0ܓ) %짡ٟ,h=pI /@W/^9 Z:Q;@r4\ȅUeBt$UӀ/PXM7Cɑ) 62l zq){ Mcw߅/GE-x('/7FǠFwP!IS_ɩor9X $EAiig+TX Z˲W!Uڰ`#JWIM8VL7'|jIꝙu0 >0xsfke= aXtiԶWo42|WR:uquʧC I[8s υgYz|μlŔ5#P֐ a;6"Ɗ1R_!]-Vp*K)OVZ&zAj*3eK'xyO[s^Knp"S2?/`j{VS( RWGc: F;Nܦ k47QӒ@$܄3``o*t(xyM0ۿV,Z<ݲlڅԅ4\ 4]Ѕ+C(kJ2O_F)p(0dekW<' 2-|{ [K&_/t*Mt=#Hi|)[9^Hs gD78:_2$qU@6 ukP#sNg6$t!}e 4)qw ;ʊ*#%0#s)\j n@[y,w?M 72č`%gGH+ 7@PqzҀ7Oo#Ez}`l}dɥ_đX q v \z'U۶x/K ω_oD wߕmx#T`q-?U"WzEJA&<~dpj|1+SnrDJ75bYPovؕ4B&QsבPaVΨVYڥ`?_]Qs~*@H4FR_M&r ƶm|Ql#@M2Z4ҞBR WH$d[[VZ1i{y^|ÿLALω1{ mg668^cH<~<[J~ ߃gL՛|ߓj yq_2L$ oWVhyk <ǸtĊ0U1RTB{h0Fӭ#'a#R҆ (y W{ѣU@T6/^PNd(}|t3 &=^gJZs^z"=zmU'{pNr1o805{2VU mS3Cnȷ1:r7~<{ ri}ɗj*V ,A:Hua, ~tե۹d-5K/=n^o0HptǦ4!/J@I]ʕ=?w iUTc!&v/jԻh"?<"P=JaQ-D$aH "E{MԊn#@:@K@ǎ> 8Eɏ\,[V e5)D\>f8/>郘O˖%~}CRs1/#ض'%/YädP?L̟$nh,V,sۀYx֑>dV>H^[JCI2?E{=Q_`IY,\{f 1@y˗Oz$ < fJcz: ޤҀ(Jovlp2Hy|Ov&9ys Yyd+$3ҔY>c:' ա%YNnm6H?dBrxHVy5hK1ǎ{M8s/FH"^r_4ԵU2r_G3 ]"!lLG TХoK" ϻf쒨 ]yHC)le@윷2 V{zuޡ̭4gaeo3WP& y77sJdȑjPǦ4 N$Q!jE,ATh̦>>:M]UJJ(x]^{Rڷ_2q>\D ٰP )mYm<*I(wEok P4M%$) v /LPcҥ׽GBH׹?0oT/6sд)m@J`P6l ;0x UPxWxƻG@},."%Ź^{'} WⰇjB$ﭼ^9>) rm)7 vh\?PcnB@$ܻ 33dtV`|=}1u0*HkHQvQ錝\d\oc |߇ZI*Pоo-&RV):`E!mcl3|V0$dc1u J3w{rVRDm媁в S`` H~z:ksjU镻c-kЀug&=m֌XSP>~y,J6hFxxų33:ϻ gb D{<~QF +̌{mrXdn>sXFX R83Ҭ{j2׌ k ߫[4E .5",Ҿ $Hr'HM2_E7jY^ C.@Aѓckȑz3UlӖEF &0^k|'CV^lD(f:n"qYvwv8ԁ\IûfMWʕ@J2hTUaw !Ne.WYaMtHf{Wo6A+h1r! AģG9o2\Z֝ 0CsI۝i:|ih5\[ZW+,y_2ICeeCN2rEFUdBhSxTs'KabtFl$P1QbjߴCkܟ28ONʹq#/ oGIz H3cZxJ$"N3ԉA7ʿV2t~aӹRZP>0"<9o/!]¡'LmK7}Ѹ12:vm⠣SeH ϤaP[+\ ,m}<}SF'51|29)΁&9=thGmdHBr|lS,訅k2& U:ݻ??q 2Qas=h<" yOKD||iNVj!'x R{2̥uf4r6ކ_"{ȻBW+\i}Wj)$lu!z[we"v۷Ǖʛa]zc.EZY-jt)x*{up]F"qԷxF^c(pbj Ml&MhHRZ|Pt oc 058.x(8o'nLl$ P}"f+nt\IjG K p | զ 7JrlC\`$HRcxCҥV ňGE\5g"rd45c\?fnZ)i~JWwގpp9@"^5[H_4\WUp+W FLI pyXer*/5+ɑc8HDOj'g _:ψĵ{$ñMs\[DVȴ/l@{leNҙC7~6wDLq(Њ\|1cq0DU$MXT_rQd(7Sy-[Hs#'֟["1aalGqI4>`Fl<_Ŋſ [f&avn3Y!vx+OEiyfh2_-3*VR~n 1bQ(;s>Ԉ +`{hsB9߻!-[qt{cLx'00jN9pP``O a]7FXa* ƭ=81+KR{w{s$%p;.P&e7#hx \4+}UOQ7 Թ|0s.Ͻ{ :{s*YĦDl$P :)ZQvmf.;/ YO]}O&Q-u#矬_xYHgdUB hXV%`ayD\1l* HDCzf|%W+ElI5\Fs"㹖<3̑f}:YruRPge,KfF;܁SR^4? ꃙз/0I0'Z~=̪v)p?tS(;6m|IV[Z5@NuDRML&7=W>?$Yڽ+{!e-Hu$=BK4S@ޛmJ8  8@[Hh\Y:X>4~*@NuJ4 ЊtnF:sJN.ұLATb 崞mh`9d8Wa3hz1($(߲ѐ蟘!cG`h= :"zJ3$ ܎?[ iySy:QAG*|iy佐$\,]`G5eߋ,۰Vn.WZŹd1`"9<,5%%SMJaC`tFd;v$NqpL#t[2 pMeb}@7m\*KO%t4k3g6F6>BBټseJ4J{k[-Lׅ7)Q%T>מ\ƍ}?\y=rAiD m$v"e`d<]v>хe“29N$\gбd5J.y:f_(!|R7th*)L>sܲ%^ lϿtU F|jy<ޏ?oJ벇s&F]4w׳k oF)P$@!8DX VF.&kMEyn9 ]9v}O>q8xyߏPD3b[O11x KKg"@ѭo="+.2`l˪`N5Z Y{zmxl F` \k aW/݀GuYڑ+r6mnvVe:*@aC&v;e3.%q\ο&V b S͂q8Zьԫ( xC|NFYDJU=}?WϥBQsqQ9gi)}ڰPnpTB͂ !T/"ESy_4 ۋTLI %v vN>_ ػJ۶@1|&Y-`7:P\Ժ4\FEoJc'vNdޡfi4H4gCw1۝qdwf7͡ZsѤ ft(=K+so\k}D9".dN;H@8zZP,p$Hv?|~韾~27mJе+ IFOЫ[t g 7/5sPsJ2!llƽ 2 t52ndp;[adDR[vydG8k'SY~֯7˴gG,G xAwfQr*#SZ9a+sP\bU;_îahUBb%9U4iBm;*Vkf*k*e+8r)Ib/$$r!`昡-!C5cv9X*UzstHE0s%ϙ÷Q`;=hv uCӀjly _}j&HOaٌl*'L% q JӘsjW:rWlߵkA84i•^Km$58{3 QO۶t*U}WMwSʕ"\sL`E 8-fs۷lk4`;2{EE@ѣDi xE19^-)B- sé7ߘ9Z8|uԫL+|ǁnr'?2厀#^,_[WL-e|"QKS~y]!8[ֳ+ qYUO@II|J:ޑ+yN乑Hpt/xz)H݅2\$ =leWo6iWS's>D ٥w_幈q<9M / R^2Xwg! DZ)H؈P1Qt#:~E$)aGb"ʼn!g%ɰ7so܆ $:~2}x@o ;i #xЁqΌQ_9N0yyG7%y݀;г'Px!@`J/GR 0{NIIxx*<-( OKg{zb؎"D6 (pLK=^d*BvP B12P_L^&K}7j( +\ijF"C0'.BV곌.*|ُ7z77 Tc%ڪpArV-kx|i WkzԨ[0(ٰAV M0Qu ={oO<ߔ 43ge^ki{\{9tq@_jx"Hκ+PAs~H#{:5ճhVr22.ي _}gCcV[0KsfYT>j.=-[ZD@ix56b$ zjr4GN(`z(U&2eo%$ÈDT_~!qḮc D)d6o,BsN1re?GbK@#܁Lx׫((0S;*]g᯿t&6q nݺ u9 -ͅB[a L'+R2QBI/YF)-ױ`u*J81:VǥNK\o%9%Ө8ԦXڋ7eWUiɳPλwBjWZۍ2iеؚE~a cxT6UO+)ԛ@%qꘐgr>o"E4,e UdpaD,k9Lk#Seoz9%)EEEqMy+_}Bl49^JU0&n}WBd~2s 嶳 ul:8ii FX N1 rgd!+*Ӎx?2Dccs(eL)(=f(=V`HO"M5&H1ub))qQyh`i?~D:$nLp]AEʊܩ ;b9t6dp_9ШVdN0~q< mnbGu33<{ )X u7-J_^֍' JdA'z4fHuJ'D o3-W4#A~>I :$o%đ i(3i򴰮a(5.{ X'_ԌmZݭ6xa /%,ǵ_'zJ+(ejó(f3Jɡqe'6]ܺV~4+p+5+0Sȧ@]Ax5D9f/z.6$3ưJjk/-~̡wpܵe) >a;֣[΋,gzVyj}r " FD Cj+Fb_=Psei<+]mQeW`  M[1 j-{f98R.70sH:1~ApZۃCK5P_z؆4a;s!/t]^TGQd#8" eOLֱLVal^~oչvLUlG-A6+\mNl%Ǘہ]jPI\K[%!%BQYj-2%%ѐrSSbUfC7}0))S{M Hc#Dr7hҿdC+n IP( +$4E*ɄXyb#\?W^ddAe)) 0|;CLg\\2Lcg䆅XXJ9q\b| Mqd6ϒ(&+-Uq#Jx;<ϛޓX{XbVmJA4f=?]kp /euMlDHN {@.VjmEcٴJmb{G"9!K Qqf~Wtʎpd;PSQ+y?W@ˢu3f҉ R?#3-:\K$n*l$ »ňewjKYUunDT GF3/cGy['/[ow`\\AQ`/\ھ;Ŕ91?hջt! i1R|kW-Nw-S]a#@CB~萮:-1yOK ˒x++3Wv[}Z oN(uƁPKnmȥWg+~d(t,,aAF1%`DE^׌XI:\dh*dXg &Yr.٩o=7OސxGˈO8%㨳"s/6ʂ ;O8yy\\w4܁4@/2k3z?xqڷ9߹e j=RK3yjD  E g~dM9ذPf!A,p^P zrL )JJȦ7,q_o/:TRe1bo.\-eké8(mj=ϚEڔz#6&ZWm]-=?<#?w@I" \v۶lr M<ljT(~Rf?{HbRꝡhD'Q6yK8X$@Xw[ۜFRrco cw`6G&s l}QNYdHgX!?R2{Vo8yyG Oa0elYܶ]~2hr>}u}F`epbHhO:8B7>)v<%|qMS`$VRT V0`eӒĦ-eR0g_(x}f;t0½TғqA[#WFvU8<@H_ 7}: =}TUl9JL @%??1ʆ9n7eI`qePn#KoN?N9Y)ؓi\`?_ E_}#ָl4FrܒkYx͞3.*)$:YƙHq"!U{+oFqDB$w9k]3dOBsV[/ x$'Q 6;xBSh-;v qM\ A&2uDL/@d:0V^{ ЦP1OY%6@Y םP"1҅/ِVfT4?D{W4ߘN[ U|9;P=kɆi>E ֡vH8߅@c惔[b7VL-P> MV@z)Y) h~[h ωʕvTa\$"+u5e[丯__HbN;t{;ЬMQ4=dڴ!fMJk!BYyGSkɆOƔb8¡o[fE+ K nPTl#hӠsg@8Eyх29t*ro7!$\};#y="&[cr,47B|d,v-"-v:~=bjwm6%8RLe`9jXU*59lh;wJN}DEˬeE%9(e %XV㸫`{2"K[#4h`HbUu+05!hҍfD2 ~Yt 2_=K&$6z;k%S~) `; cX6xsDaN'{-Z2X{XA6 ML֭vN8s2>;Qh='c̍rt`\if fX490Th8<_u85X|Hiڶ% _ 1`cȸVå?r5իQf-[$ʕF#yw`ހeH/oS),:hס,>+W^I5!aU])kJ(S kJ'o|$JrZ[ juC@f1,-my~p%mKF35"g3pT^'6vG^{&%mTlm P@yM<-`J@]jCvm@[ƜEʃEE34G4R{c]kvKO z +Q!Z994f4yUKvúEmA˥RʁR!2 iW/,mq G+lagq/QY:&\wfπZRnСLddΓBWP:$`pZ zpY _1VeMC̐`4idןs~ `%'DVKXUQqb'm^XS@pJD@ϠaTå(.q>z8!CKx;]LILƾpHMWLE鈦o6DkSJ'fJ@g=|.WǮa]>]Lz\ UxlO+LH+k9K@J(4-9/vav"kW.:H_H_u0Ȍ,!8֐6>)H<t}bz Pc[*dG;7skZr8ZiDG3}`rNj$:xf$FB| KCم2-T$Qh8"ޝv-$ОwqndZ'ɃNF #D9ON8CvD6H; r?1$!9ܔ>c8ʅ-(֩Ð5ut02`_~a 9ao+hygJjG=:@(HiLV[U|XI.ի>/rBtͨ.2Y18) ۍ.|M̺ yIH|\AC T':]D_L_h/eE^ ެ?pm|.* >ߨ}wLJpRNk8~;{?{'p\3P.0,w nڕ4#%2ޑF<5T1CgXV5h 0֯pa:l T_|1 VΝ9!%/zdI{Cf6 q 9 !C Wj%F'B;҂[0ȸ}3T+-/$[ :eAW|nׯ)i4"En7&$[&3tlK:J y. jm/ YH(͙P67\ ^Q )Ҟ eSq]霰/I'&M.{oz?Kl@QVtYF.(h ^~~ <ȨWG2<ÕN^KB7WdBY•WClS-%yr(d?Nއ`!~ PPmKD* ڕL@Oiw Ֆ".9e.,֍/P42'PTK}A ZԮmK ?r6nyr{l.L |[&YQ`:h.ݥwU@{SU@O`i޽ewxY!5ЗEϚo .%bCgҥ3 #EÇGcH8F2B ` EFi&k$ұ"]+/Ve(4hs?PF|7=|iZiíZoS/F6^'k *JV7#<@jdӦe7nTWz~='2AHM:mQl5ќ %+!)2"tHȝp8 i/t7#2n7-{^g()6c}'&RXktge{P/,$wc, Yw5 Pڑ f8\gEtf9{!4dNIooU(mh`;Iyj\cB݊YĐ \1P&H3 i:O>A1PMV2e;G3F$fm3.s0g_#vp \T)-R목QA!K R *'Y'ܦ=Õ`6eIiLQﲺ BG31cs Ambκ*C'FHΝzJ ")W Ub:n?Y9H&l eny (E\'kkQ$۹16riۙO?>#8*($Ir׿}.WwUg)i:mtG~;W8hf+ـAN0Ь hӦYc5-j@˖w@ڎUp@QjVY}/ۥ} ,Yd`R/Ҧ8WP]ȉ"۟rd -Y, qrk()T5x7\*GHQ)t2)E c_XH 4==ѠW@H '1 8_n (kM`شɺ^6M,3&)-u+m>(!S:\"4B]Ѹƚ54W4ȟ|2#-9^jyMå wnsr"=?#ܩr|rK(U_H&UX-[V6yf(؍R)]h`"ٟU$@Q'E=F9YB6yݗ4[ffQ{%x-~O1#U%jMb_F\P=1ABѣ썰|ybK7Fig/I"8L{3jl /ZtD7lLԠC6X(mp66RѣTp$MYW_Lx ܞi?e{7dtSP׀en8[V7(yoڵIn;Lr 0EA/e=mEf|eノHʷSOiш{ߏ.] r(~]0Kp”"nu M#ef<^\}4-b`ÆGwZttD /?Do+ SK<{ %K tOקS%5`e7;F:7cgYܥ 't8J^pwQTC$ր1ɬ:'wG)AݬW.:0r$pcZAVu7@d]&q͵A:j{nج{&l7+g ~蒣g==?t3_/UR<: ׌sl [޿a`xcx}=SBuuDWSKW/8ΈA@STĭH.Z[={LiܓG2͜j;'+6m}YKSP'ن_0UZn^`+!v6NZ-*"݊#=_WFbEt4rlo$lܗ\FZذࢋ4-`H~NB@]t=dx!dѽoayŀcQ 0lQ zh(uۡ& e˖W7j,Nò`Z)iffy^'& tm4$&eU>6Oe==݃<#9p%& 98< Rj?U40@*>4/e@(Eh!]:n)F`%^ AW2!N&[,Jp vp{`WmbD6wR]s׃ GRj_#KIHuk?H V&~ ꕸ(M! !EǓYMി濯r_*Pp4lk7w>W_}8c( ~. kr( Oy^<Aȣqțh#*H>b\}Aޠ[n.F'(t8bNb-УVY *vが H)fKP;|>7oS&0bD*]#)GwǏ;̜"W0}zvћvfz[^/ 0d4~o(FxF21N w\W>| FBWCZU(4\-[g{2"a 3u 6unva؈4͛ 𲽔I)5A)ALLuuWy|v1VQC;u~3x] yo&O>J}5g?бcY@fzTs==zx.lܸXfT<-Mgu#wS8u)ݡܾpIz,CphCo3#J; h[qR99_ Ui|ՆrMs:@g'D؏/#0e(clҤ䝿H`l *(}\w>ڵ:%h<'>$ĴG QCh w/6mB;`V`u 1`f% !=Dڍф)i;{&cJEnEi/Zd|~<_0]]~J~2r1>k_%(3MJ}tV+.54̻vE~]!axX8}Ӂ wD\-όFPC޽4=-'gװaїS^"0cF\#wZ)C ʑ3W8B\̚WO0e{hM\⁢YZYW65k@,bQhu\_({:2i/=f& QJa# mY\q|eM;aEk`Z㏜ܾ7Uwٻ7rJeĔeE7l~23d_!__q p ̜I?dH?V(~=~?qPf-2{Aʽ~y=n hѺL'G{9XJגQҽʲ3d/e۷0J׼WRU>Sg\zV 8B4yd S6掇5+\#>0%`]( quߏͳR~{ 'z+W6~E3TYFJOIIdAZ PPt "eQ`D?>'#|E\c܍޽1cs(S6B)cǘs/٧6mFUHAOVzzJ=}uuq?U*WVV)3(x 5GZϹ˖lt@s6qfr7rgrs%Gd?!ժ>ݼp\L.P 1 b𕶌HxZf#co7r 0c#0cF?hՊѣuZ`B<. ;\1u4֐QYMs/,w <8We`# W8㌢ Xg!ÑBM|eJvfCwe9p}?+<)s馂Z ʮƽ?)L~ >4/R胍͕p%ꪌ۰ `+`˖#?toii&W@X {JJ7#3=* /əlKyen܆K[־}j8Pʷ[( 50ux;S,%yX`+½{c׾ Bdws%:~pO1/x%s jjoDz2lDž@ӦZEe жjUwd?$<\BggϾWUx!w(qQ<D}C=2B1z q̼UrFMV}tl`͡C\,CcJzu)8lzfPrkS$_@nD=pc̕cYb6-B@jgxNUp[6[Ҩ^̒}96 bl)?p%$5ͤ#=CֺФz>)nM@7ȏFu#^b<'%5on< ,c/D'd#!ѧO>C޿2NZbPA\Q<!㎣/m6fkx@N˚ךqw8p W8,)_זO63"ջ3Ψ\Oo * ԵZ+_?Im _rWuk!n݀0gT\+W64?Ó)WuNPg+aVFY؈,[.BNk-c Wl`q]̛d_ s Z0[x9k-3c0O.yebr5H@4}N5Et8@n9\R'@Æp@7"jzPظqTQ/taR1Z@JJON{pIA3q5j*S9Nэj:Fs(Em$0z@Lw&\ bU݁'46dh0+=@/ZB߻N^DOAK{d:Yzvєmp-;}Xz}Eq GlEjd xF0i #*ri"B] 5xM6 a "7߬ j Ԫ__e~}|Fo wʕ{JR+  Ƅ}Ahj`uw2&'$9Qhޜѣ3$KFqr%*:ݺ)/*/Ӧߍ#@郁sׁBϬG$"7:zѝtQ:|p5 #f6>mSV6F7|^<7m-|sS9}ay@$d$wjPb+Pv@;`vPB]Wjnee齢R'椕djeֻ'T8тyWY]W`0 +wn7|h#V~9QJ3K.iW_z30mھ+7nHhp^_NSF!vg OnHQǢXVO0rY; tK g$?F2s`k};d,Y8| UUFp %nB$g>XXI x *͞+HcԆQkK򯳴tB!ۼ<]ͶB`BQb *%"QL :̞ fӝ`͐V~˖6ig@U6n$\}Ky7<9R~<{]l(COk}ѣw/BjGT`MJV J-UWiʹfԩ4t h ^u/0VC=>?H')nV%0(YN$" Myߺ{M6܆js|%sž9ϗ,J" tҫn=lয়,ժb90"z#_}TT쳏}To ! z,` @vva%"i2S4% aС=_b=Qf!LZwN,¢H8[))R !{!=f+_DXE"`TmjȚ% ǻtlu'{#\z"cEB` 73{Hs)ϩ@cy˫(m+ԑfd#l@$^E-Y':q1BR̙[HVҗaC,,bE܆ۀ]xo|Il6Μ:@Y/_)H !WUr0H p0hu{u)]ö is]R/?1R LҫLxl6Z:[@NHaWU+~&:Y(Oo7wL|od @zXMn)H K.cTয়xM(kȑ<)7Ao]a#Y u+Y-?eFFګ|2?ۺu\VA 'ewUrmЩ^C0=̀]zۀ3uɫp.o_f%^P:>sH D xSDkZw:Z8ZMVPP?oZTx!Q Zmx͜9{~|䧟?뮈 `;]7/k]:7̛dt.ěSHE\ #F@dyFd﹣#0Zǘknbc0H;XB@^.{&z@߀6e AzP0G陿ZPq>}ԩJR\z ؁@::|O=jO*FFܳˉق,h# +}G5_{ 0|FA8HF  (j ޘFc(# pRnljСqQ-{(P^W^ t4>*dU0Ž: g `6C?xn.\K+IN,w6,8!of@Nϧ_f+yF=py$n5{zˇc%O59.<ށm;eSp`s{Pp+r@VjvLYp.-Zf4'[7LL}{~?V0bIi6lUd+VRVd Cv*}ɒCJ]$mQ{8~\On-ܯ *H z6}6| 0{N* _]~+VD)ʔXRVr?om@.tUtl$:LTr{L'>u,ugWap@M27m. +}?O#]v64 TIm(9"di&K&Ĕ޳gQscHQصbZ,` rQȪ#780<"߃6$a s#㸸rL;!`K 0AQ#:H +?F ϼX&We#0A`̇:4jb6 e2 غ5^_wJ !S5q>`BYA4P<@߾q\&TW/ 曣݉sx ~qk c]c~lte쫲'5]MȠU#bZ*YCPR razd6p 0v++'TU"ЬВᠶPܛp//1ElD~? cN|qĆ_`蔯ѣM7cqhp FLh 55(CU/6t0p LgΨVZ?۰Q ?HԆ?WW7pR#n xd+*b\fϫWo, Dtm",YnsI}ea,#XN'qm)`47Xm?fc4P"(Glۆ8M;QBNx`ʢܢ\):uO1<{o+"po}~PU]mmFthaÆn\~ nqdFz(3QBltg:L]}{ѓx}=-L7n,kqQ3բڳL*F;Yg-$a* xsB|N'ik*ߵkiHWn$ݱ N6Jwf!pZeNV'ݺyxCƲTA`nk`/Ƭ,>.WHPKp "оmm$/,Q*:w~{QEJ3+Oc;/o}v|:_ț® Yʘz/~PGn*VO<@9=9}K9YnP8}uVVv*@a!ZD 'PPެ  }c Ǖӛov@Zm'Jᠿ}o9>W؆|N^o[3IF?gkcȐ/WWbj2 `p$_Qcj׀;fG!6C;Q O SOP)nl`F[Xuu? PՁ p(B\cc p督>I$9B ad*N} JΙ~33W_xH4(rL%'6AQX!eIrb6&M8X:EjWFԩ쪱)D&R WӠ*ryн;* v}O=wLڣVQeв*S4ѳ%s+mڌzuԫT VTW5+5fYbKynId1c2-ees·^G*#d NS7uC3> aio}zg/=93ڔ3;~ذ%O<>"qO~bOȕĉRfwZS 4n7Au:س'nj]`Ѣa#FfP\̮/̞M/TwS4"M}ʋʋA@I]Ϛ=Xݭ i,dOx6sUS+ݛa<;i_T(UHÁUCj 6ȞJK~ e'v1Z7?bDC_Tڌ͞#|1;0_7ܼ$E8!KnysbE^ 8{Ӆ+1)){.s!:t}W^c;G6(P!,(#ّE&nMt?|=P;˗gkԹ'37.Y?' tUWmtݺNLp/rA(Q..u>$(߲MYmOsа7jDCCG9r>ȉ#'oP3OϞ+O?eEHxGZ<8"eWJ`֬YCw-]1LH.߲% ~!V}e .LLyJ>L -p1(/O ? |5r5We=<$)2eq{U9tflz!C:#bx>pz Lh `iHᥱ,(_P[f͸ph҄i`SSS 饗}]縍pCv~wj@OC_o+sH8|@ɍm}ʕf͚8o,ldrd̚9%ޒ/}+2b3"; qM(^ /a5/cN;})1\)SXjMF)p0"B_oޯ0- ~4.L$)m'hD*l6 4K eGx啜_r~'||k|WV7 +6Φұc60a/T'k&Cbk)O-ZJ7:> 4h쫎CV>}=p뭀gAT,/o1D<Eڷ՟8*CH;ISSOF[>+&br /Zʾa\a9޿ F)?:{jsI4jx^8)TFq˅F6Wqc!P\n#G9tg L7Ssu9f@pNOMo̦8j&:UGu@Ӓ}=(O:"8qGLÿb#}ETH(ꅟ \~Ko~co+.U1SP~*tf6ƏiFơEڔhϰQހÑ5AU+@2Iy)0f 0{Nٮj77~UliVX{3p?\q~~ЩXo w,к5Y5jf?NQINǏS !_T{˗KH}wO 5W#MMJ\+tezG#舎Wy Ku_ РM.T~W$ԿÆM|oCw=׀%Ko8t0cFG}EmzN#|Bt8 $Ay@ȫm:5NGz/o=')p8#Ͼ6Z{d.,[سY.zeT .;7llmz3Mয়x~#Fm8a)u1Z8_r_n=tfM;Ë/rLnœU^W^ C=c /f\zo={~w?Y>Gm6b :u!9dwOkWxIo$awh۬@8Nur;nW.҅oC_ hۖ1z4%f-Z̘SSh4H(X DHc Fw*G-|x۴4hsRӡѻ1[)аKo _'(FqBd#^^ ּ=8xH@X}$m[ ;2$g}XHB\8ƎcG{c̝rĘʿx cÇ*4,pB~E"Oﳾ}Wo~'ccK37xc„ܬ\^=L4GݯojWB! !m77*{flz7b^6lг#@!`!G*.Ҿ5fy{'j"ߏ4qRC± G}6QneӞ!eqOw]?SV( /SwҡCj?V  #GbvqcY(J`v?}^%p.>LFmPK(^vY}y.,Tg޽}ۏۈPҿQї240q2ߌmpq!~W^a9[6ʍ lN՜!lK,ŧxt,BG`g@W'˖%N=C!<Z1(Z_Q'ҍ67&dH~GX6<@BkC??w~[ײesÊhj p d-+K٣n PtiK7CggcG'8D+>jTS. n-*ojxPf#_ UW%VoڤvR;C.Uhs@z77@.xuTvthp{Qv-+gu6ߦM>vl\++>Wϟl4.1s@ LxU[ VevJ=63&L(Wp`Bࢭ٬uHQM+,K ʜKX'\UUU`4M4ƍVg1 3dyء?? \~9$ŜL,Y 믧aKm6ڵ;ջF ޫLT&c"frh ^ߪ <8?qm>D{skίa?b9v 0i<2OJJo i7Fasf"62d}c.waَbOO`ͥO>j ѳԳ2Xᐐ+2GkGks=<W_bפq50}z%Y C !ևR&)A\n^|I@f pMz^ h\8A MRN(PMG飀/港Ys@ ,^oW^}<{0GޞH e ]PSJ+72R6}I&+ϙwe["Q\4h*?W_FHsR.ӧO6(۠#|eKwW'{gS))Ze-Ϟg=s6>Y{3g8ʕr7@v\Fق8-2 e(7aTgӱݜg,=˽KIsOƂʕq}r_/ӓu}Oˍ-^\BCu:=[Y,v&i[nJ؆fpޗq:e4U(S)/eG11ڻrrp;ӝ CbtQ_ r'hU~mP5а̝ApϤ:_} |07pSI27;Уer*JNNnx4E,7f+%X&0`cc.o_Dԉ者hV=}!eˀ7ވBR^+WQ7γ, YЖP>:hJqO3"Ljό @{!yͿ5!jbNoikş:8u0puCz*~uzb@Pf)BI cnaq\G7ݐm?Oodea1GI <JPתk!6zUQصjǪѣKu \u]u q .wooAK4ɪ!Y-Y81/L4S}OuBF{Qr:6*з^F͊h(5@/ yOQ~~0|ovzIA;EVt!p;;IUopә}qw[_ ЩUwMMsSKNeiS?Ucg*GcL!.O@yAe9S3::H9Woa*.8ޑxR=Cй2FSֆ ԩN#1:~Ʋtl-g [S"S_ _ΊJ{F3bh#^$aB FhlV63f+PCib=lmbio.Lfc6p}ſ+?';xmp;jƽ۶̚=sNNz@Kצ 4ƹ4hhCo/^-un9 \w0|8ذP^n9@S;K9)}AU*c6rE]UYSOӹ=hWm0Raj@V_1/147pq0rH9|2T [|| ܩ*$8/_аG4n^^㜝KtH־ѼrlW*/8vm[ ܑo5 [s{^W//N>{`4+Ѡ2_ Yfc6W\f ػWBԬ6[# t[o՟Z*?pfl" nH.ґ͵+B06[nWJXddnl!O܀ D7n t{齀O4W^\cJ6#D 0b{o 3jG [[K{lt oL,/U{@cHr W=Tx*"!)CR)ԛ՛2niHP ƌTRe];b#v2s* ݻNNc&ȅa;v֓> v[ ?\H=цT@ xE? m=;,9~CHS\ǀ޽c `N6?(IYIrr#W3fPofয়+WN9π=__)Sbօ8E= mX7j'wˉFx"PB W/fJDp݋:};/źT_͛et=0^f4|0ѣy!yԆ_~Dib mDؕԹ\\[\[s\sQ}XߔOСZ$UoOP!6#)0s&0o7F <$EZ^j9,fF|)0,F lD$~8cǸ1"ԗƍ% diѦ~4i߾~+oX}6P ɾ}#G }uų 0Ap+hKr-  P zz*ԘZb_bc퓔>Dy&W>fh\a:t7Ffݖuб+˕̞Mïi>1|#bQ9͓Q:ШQԇ(|0u*0{vbIVxxG/K@9F$"LYbx<`d_DkuAkUV(++//38 p-dIYÑ(P>:ӣӔWFS)X%9Е_ {/%ư+Eҳ ͗f4a$/YJl?%p˖QG`9@nn]O@ڨ #)F>+:v/Cr jpvZll:Km6ӶkMʕ<%u8|Gjsov#$BT~Sn3 ++WW!ҼZWॗ,qG'r_,]ǁ{:u8Y5*SP?@LLDR 4Vg{1?2#uGUrOh.Y"ZNz.pEdž ~={bk G%z sB$WSH{]5oIn{Ũlcl^x( dg瘑 (w(wkDC Y?l]S4B+ wɾe34"#٬ÎB'UW%nk ԫ8 1~1}% |&YCQ?UQ/7zw%2J/G wXGjUW~R~k#l5.X"a`UƩxq⻥Xg# 28(ZűzL|d_]IxxQ@pѽRY P#wV=llGV}I;qR݄65 %e^= tYgl>-5D[7W]W]`d_޽+!|9Yؠ0甁veXwՀr.0}: ͸z~TɘHIr'}\=zhm-CTu@{H3 $AioPSV .yOL0H `  mfݭGp@ɾġ"gO:O h<w>P99>,GPrv)/ 3tN1ސocv)eN$[i> ѓO20qb.]h-+aF${Ц "O.Ikyd)\Q?eѼƨWR [z;^XՀ1cԌ{V`p913.7/.$REy^yغp ];UEU`.11]cÆH eMEo(+)a5zI\Lކ ?$+/-(*P7#iKyFUC}<7Jňa*运= ~m2Ī~YВj+Jd_}9pzW)=g*]~CR҆ e'WhÆ1@WK FZ;v݄FuFak>. JЄ6nօlta4 L50AܨcamJAFT1nD,]MP+3^. 9ϡ> 6'XiFny׊^gގky͒1a4+k=)iKR5Gh?h/s&O/ [J;ỹ\.ꊺ`j;x8'"cV`! p4v}m|1&c` ]弳(ӟ|kŰ k :͈ulG>mBŞm!P[;,(};w\ w"Iϵ> ݮq;"_PO<[7ڿ-ë>g/N-۶Eu%X!_Z F2D;!05\^v;khrO~v"哘Nq ney~hkvsb qw|"X0 v-?Ըhvw[h;]^3g&sD?[ؕ@MMp)/#ENn޴#)ZY?O,C=HY;)hkc"=6]E)WΏN^Q&9W*QUGWAm04TŪbU6mt+p8?~MM0gCtygKt:/wuQZvw !\^fs*R]x hN2]>_T{ { 6IDD|=8`]o\Ԏ H>0 iiYX̆{^NEDD*/4d JLKŵ H?`yB:}%tEXtdate:create2010-07-11T16:07:36+03:009U6%tEXtdate:modify2010-02-13T15:53:09+02:00/VO3tEXtsvg:base-urifile:///opt/proj/okasha/files/logo.svgjIENDB`okasha-0.3.0/demo-themes/default/static/logo.svg000066400000000000000000000545131412405540000215660ustar00rootroot00000000000000 image/svg+xml okasha-0.3.0/demo-themes/default/static/okasha-docbook.css000066400000000000000000000057001412405540000234750ustar00rootroot00000000000000/* CSS for Red Hat Linux Project docs from the Documentation Project Written by Tammy Fox and Garrett LeSage Copyright 2003 Tammy Fox, Garrett LeSage, and Red Hat, Inc. Copywight 2005 Tommy Reynolds License: GPL */ body { background-attachment scroll; background-color: #FEFEFF; background-image: url('watermark.png'); background-position: top center; background-repeat: repeat; margin-left: 1.5em; margin-right: 1.5em; direction: rtl; } p { line-height: 140%; } li p { # display: inline; } li p.title { display: inline; } div.table table { width: 95%; background-color: #DCDCDC; color: #000000; border-spacing: 0; } div.table table th { border: 1px solid #A9A9A9; background-color: #A9A9A9; color: #000000; } div.table table td { border: 1px solid #A9A9A9; background-color: #DCDCDC; color: #000000; padding: 0.5em; margin-bottom: 0.5em; margin-top: 2px; } div.note table, div.tip table, div.important table, div.caution table, div.warning table { width: 95%; border: 2px solid #D0D0B0; background-color: #FAF9E0; color: #000000; /* padding inside table area */ padding: 0.5em; margin-bottom: 0.5em; margin-top: 0.5em; } .qandaset table { border-collapse: collapse; } .qandaset { } .qandaset tr.question { } .qandaset tr.question td { font-weight: bold; padding: 1em 1em 0; } .qandaset tr.answer td { padding: 0.25em 1em 1.5em; } .qandaset tr.question td, .qandaset tr.answer td { } .segmentedlist { } .segmentedlist .title { font-weight: bold; margin-bottom: 0.5em; margin-top: 1.5em; } .segmentedlist table { border-collapse: collapse; margin-bottom: 2em; } .segmentedlist tr { border: 1px solid #22437f; } .segmentedlist tr.segtitle { background: #33649f; color: #fefefe; font-weight: bold; } .segmentedlist th { text-align: left; padding: 0.5em 5em 0.5em 0.5em; } .segmentedlist td { padding: 0.5em 5em 0.5em 0.5em; } hr { border: 0; border-bottom: 1px solid #ccc; } h1, h2, h3, h4 { font-family: luxi sans,sans-serif; color: #22437f; font-weight: bold; } h1 { font-size: 1.75em; } h2 { font-size: 1.25em; } h3 { font-size: 1.1em; } a:link { color: #060; } a:visited { color: #240; } a:hover { color: #02f; } code.programlisting, pre.programlisting { direction: ltr; } code.screen, pre.screen { direction: ltr; font-family: monospace; font-size: 1em; display: block; padding: 10px; border: 1px solid #bbb; background-color: #eee; color: #000; overflow: auto; border-radius: 2.5px; -moz-border-radius: 2.5px; margin: 0.5em 2em; } div.example { direction: ltr; padding: 10px; border: 1px solid #bbb; margin: 0.5em 2em; } .procedure ol li { margin-bottom: 0.5em; } .procedure ol li li { /* prevent inheritance */ margin-bottom: 0em; } .procedure ol li pre { direction: ltr; margin-bottom: 1em; } .itemizedlist ul li { margin-bottom: 0.5em; } .itemizedlist ul li li { /* prevent inheritance */ margin-bottom: 0em; } p.title { text-align: center; } okasha-0.3.0/demo-themes/default/templates/000077500000000000000000000000001412405540000206045ustar00rootroot00000000000000okasha-0.3.0/demo-themes/default/templates/bottle-base.tpl000066400000000000000000000001551412405540000235270ustar00rootroot00000000000000 {{_r.title or "Fallback title"}} %include okasha-0.3.0/demo-themes/default/templates/bottle-header.tpl000066400000000000000000000000241412405540000240400ustar00rootroot00000000000000

{{title}}

okasha-0.3.0/demo-themes/default/templates/bottle-test.tpl000066400000000000000000000005311412405540000235720ustar00rootroot00000000000000%_r.title="Fav Colors :: Bottle Test" %include bottle-header title="Fav Color" %if colors: %for c in colors:

I like {{c}} apple

%end %else:

no color is provided

%end

for more details on this template visit Bottle Docs

%rebase bottle-base okasha-0.3.0/demo-themes/default/templates/cookies.html000066400000000000000000000011311412405540000231220ustar00rootroot00000000000000 cookies with okasha

welcome to okasha sample web application

the previous value for color cookie was [%(color)s]

okasha-0.3.0/demo-themes/default/templates/docbook.xsl000066400000000000000000000013051412405540000227530ustar00rootroot00000000000000 1 /_files/okasha-docbook.css text/css 1 /_files/docbook-img/ /_files/docbook-img/ figure after example after equation afer table after procedure after okasha-0.3.0/demo-themes/default/templates/format.html000066400000000000000000000010171412405540000227610ustar00rootroot00000000000000 {title}

this is from tmp.html template

we get the following arguments: {args}
the value of key2 is {key2}
again the value of key2 is {key2}
I don't want to show you the value of key1
okasha-0.3.0/demo-themes/default/templates/kidtest.kid000066400000000000000000000007751412405540000227550ustar00rootroot00000000000000 This is replaced with the value of the title variable.

title goes here

  • I like ${fruit}s

The current time is ${time.strftime('%C %c')}.

okasha-0.3.0/demo-themes/default/templates/main.html000066400000000000000000000031221412405540000224140ustar00rootroot00000000000000 %(title)s

welcome to okasha sample web application

we are running %(version)s in %(mode)s

random:[] - time:[]
the uppser case version of your input is []
we can split your input by - to be
okasha-0.3.0/demo-themes/default/templates/test.xsl000066400000000000000000000003121412405540000223070ustar00rootroot00000000000000 okasha-0.3.0/demo-themes/default/templates/tmp.html000066400000000000000000000010271412405540000222720ustar00rootroot00000000000000 %(title)s

this is from tmp.html template

we get the following arguments: %(args)s
the value of key2 is %(key2)s
again the value of key2 is %(key2)s
I don't want to show you the value of key1
okasha-0.3.0/demo-themes/default/templates/upload.html000066400000000000000000000014311412405540000227550ustar00rootroot00000000000000 file uploads with okasha

welcome to okasha sample web application

Upload file to /tmp

the last submitted value for b was "%(b)s" and for color was "%(color)s" and the content of the submitted file is
%(f)s
okasha-0.3.0/demo-themes/fancy/000077500000000000000000000000001412405540000162625ustar00rootroot00000000000000okasha-0.3.0/demo-themes/fancy/static/000077500000000000000000000000001412405540000175515ustar00rootroot00000000000000okasha-0.3.0/demo-themes/fancy/static/logo.png000066400000000000000000001405751412405540000212330ustar00rootroot00000000000000PNG  IHDR\rfsRGBbKGD pHYs  tIME7҆I IDATxw\g}~Ӧn]U- W٘ !8.7p ߄@IٺHnvHH] 6 ٖeIVVSOqff9sfvV-^5L{>|#֠qI}{c?z S2Unsd}j}rmЁ`nG Āxvp;V+&6^#Q=1Nza]Xyyun:VPT+dsdu"zQPVUopSEa`)7 sU/|ߺ z>/uZˁ]aPEʀPoUm)Z;h@Q[a(_X7bpas\W*Pu#2B@*^^A]7R4KZ ݡ ª@ 9`] =uNPlC|b&\hxW}9kD<ayA̯`!Y`1YM:v_*fj.= /rS*4e VM~΅Ը^Ci`=8 Pv˽av~F2!0.k >D#o)U3h7xnZ~\8.Y&N 8 N!1aTU=#C sa>=`MX񀦏Vs_?V4By50Z<.N{gZ]1YhU, A>CES}Zz  FWlN@`x6)Nסu Y Ufd7f꿫>~4 @5g( * о_y=tM>_"H"ͪ9g1MV];[^jTd5) _X_QDBIeQVp.'f9<+h Qŗ!~jK* 5C5EEr84b`N9nG$uG4cadXYIsQēICȮ@/'*hoz7u"l2uaq7s5z lLsVVE7Ej D @cĺ(U7xz/CJ{hy=S>G ($^$.iE )Md" CpgM FzW}}Xz/ S_/oTE Q+bٸLb2("u KfgXs6@]z%Wҙr9Pk E@Yה@K?É"!6A5g_` p` C҆3du;Հ.7]>}Cg/C*ZLZA_^CPI~ynKT?Xէ+ ݋; /Z_z94#! M fKo0f>ł"tLe8y1nG^MHEI$mI‘jYE!Iƪ ]HfK^z.#HU@Sk\OȥNj A)l Dp,6i,sZ+Kó ]0<&w7D$0gƜ! H"J. ӶNԖ4H!=ܦ MeU#!}P }gCs/s /TwIsO1!n{5zd,WcNK|Q{='z˧q/) xR^JkXא紗GMx<#N\Ic鹪b@2`i맱 =vb$ie "Ĺ;BoG{,s%|áERO_5j-BIsNBs \IsS8@˛etˢ2$ @O*%IʫT?XdI/svr18{+Jj=dV_wT ua`+6 !hV7+p3W#>߻ k?,Se"< KUu'4MQp8ӟfpL.g)7Ɵt!UZlGEf6M0O1dIIj å44g8HA+ch˔̩F &I4La~s#[~ Fem__mQ*\/4/ l qVwǹTN|İ#G Ih Y>Jx gn~hQU_bkHznE:t 6ׁN8 dL"$8ImWD˛_I[!uq,5E2Voi#n%j89q?dj}8q Nt gJv:t!q"DWH,g^=/|RǃdA_;GDyY=k0+ ]֤u` L1{_{FQ a UGXxVwL:IVUR|fƯ ]+]Lyz]Lq я4oe!D;*%.M'P`gu?GvvEӎA$,nH4i>CJBc֠ii^{tT>vIq$MyK4lY/K `Cɱb;d}}9lb ypId:f|k5al6o SR"_4/H ['& EKa.5.pѤ\~n ho5r_{A_݊6i.b_ulԩ߯/F}/p^+Y_A^8C#z ,z!`FB;=V:^{ xfǛM,!ѱ6p#[Fv;t4_Oz j~.]Ǻsa?Es̱ 0K>sv*U)q YX8=Q3jc̳ᮞf.4ݵHX8(a]yQ#0!=ƣ=Xs.ܥ@(i6u]˭?Rq:H"@tNk6OH ~`4Z aaK=y|s#6FƴlX3aģytz2JK@4x>0 ] 'EEh-ki0 ng^ *w9qrgRl\DbAL6_A/9>z33 .J\Xf nAnX, 6LKYFmh+'|QNmƎ,ؽ h/>A &$#3ڋiy\ Z}v?>y-qG.45h>oڳlpErI^Cw$&~޲T_}0ͯ ٌLĉ.="<8DivuM46de =j:Pmz"MGvo1 DKYSE  l}uU?S?_@bNyc8 ̯?|X:.]{x 7d$YU  d/%S=˕HZCc+HjQnRg?/e^M+g\?B~fZF虳v='qN}m݇ڹv2꘎FhGl4W1kMKjײc,N``=սrBw/7NQ!Y4tB!vnĆ#еr~Q>c^@7:;X!JuWAǸ.véԟnx?ݧ*xOG#Av]EðAl ;/ar`.gr1p;3cN߾ǚYgK\Y,2fk2dJ2;f8kg)'D7xG ˆVϕ,xk.x~eH?=P բy"9JSNp}.2_Dɏ9m7|ɏrGH$.ٞ4򒘭t it9s!N%5oe3]Kw/<@5uF)BrjnKz=$LӦÙZAsqLUi&ycz8/3 4 Oz~yG蚱h4{MG7tݧ2 i1:.zF4Q{i,)2&:-"o8ט=;zxrUr_ka4ĔHOڀ}m0԰>r ty}5sߥ2j(G1K)&obn>lwchT1 #cAqV/82zR|u1G .UhْncBK M)fz=^2KxK݀j9pH >M #gwp3m Z:,s~p0,ѩ(햃;Ř0mR4_/cلغ)]  igiED`kZqЧn xZ<&/$ߞvJ~~cqIC}? ģyO]T^g7]ka(5*񀖴_CД}-Ug?0  cY%.fŏqë:}ոи/ e<_la3xyC^F ,+5lbzttN_-_Sli*װ!f8 XC떣 MkVCDn~pU9ˢvGf8 = bFl_HV IDAT\1 7 >/VɧS.G1\‘:Jw1 \a\FpI'۫ˁ_I~:ח=S_\֕(]o/G74"75nʑ Mr -{eEg쩍9I)dLT\"kf^yy a[Dm+~wڿ7N 98h 'VUpZ8lͭL^2GW͟jީVƛ (/tAo)bA8\ƒi\'>My0bKKw,\q\U#tS ggpqKjo社eK5wN_gBy3ʡ79%.'sv~I~Y5ק,ZT!ϳȗq Z0ֽ4yD3dUl bil%yՒ6Fn(Y\d6# ͛DBվ$d!%We,xQ܁C#V&S }Bz`D` EwU(ڳvY9ӊ*B"t@pH#+6s|w.''lCЈ$t `#;́|O j.s 4|joyv󼒠R-]2DhNK y."j21 Y̿hnWfarp $Lֳm$$n ^~LO+׋B lE8 hu28e FG>Ww. 16!i70a z^Ʊc ?%4_o{+ p+I+ȗ,iK,7;IirtmMqLzMdWaQuE_j,KsMrWQ ژ#8U6a ,Y,.hzkuM{|.վ^?7l͛L'/)__6R۲ˉ Q7~z.O+OـHb9QI _SY\ɛ]9#踧nctI}[T}(hHđC6˗uh-,Lb}Dlbe-Rq.qf*_BG"q.ڪYD4 figEiE9P ?5rhMu~6ESo-c·ѺsVw vSvb5\4好tM%E8]DA˫O,]fr-cN18 \Qb>\G/'N]?:`W(-wS1MZNxSWAw{ 4E7 vL*V#PI̩FhĦ1'Xr JbL0D\Dt@RZoEb_#=~U޺iٶpss`4gaZ ɐm \Mܗ @04> v(8?j@ne:\5ƅ~}kM\YHƕ%/\N<(oTg-iпzM 4~G1:=!]Öw=QJ)xCe6:*{OUګT,({ȇr!N_S[A_}O]Q sاCY?noo0:G>5/V &Xq]K^O`I9 +[|#lD-# G4bƦqGHi%"]Lv0s!Vp4G߲0$@/즣P?Tm݀D(aƒ:F2ճ CܖRWYW+UE۫=5NF*`O?OikEWa q ę9s pï\p`ɿ]yW*k^}}L-x3ݏuq"_u}łV= =!0N']̡'iʂb6ek6Ov{ch&*= lb\1?s cN?(f-l#]Ld!#f"(i X.\Ks5H5 L Y2V_ȗuz &#p5nzlܪ_ j@!MxGx^=x/avץ2qt-tGC:p< a1d<b6J_]MUoOzq_E@FݑeN{vݺq<ޒ&w-w%jQֽ-~4qrjn?2%70C6]LzmL[N{D!=b,t ,#K8о(a&`&H-kVsw_;n!c[C5.lS{aL׳_^(j*Ә(꩕ګ!砼 L~Ue<KiҗK9kXP6DzxY?Av^Gσ72f6OaV2%NoJdE W?kg:;}~ͅwC%m޽K"o^NE@9%Hrjp[288=%hCW}VL9U4 ィ@_y$5V?p>w"k BAX'b_桫Ns!njWE=1Ӱig˿rgvo$ih2<3\GD/s$I҈+hF>:T0uC}LG >Jb^8cXӑ ۽< r'S;`O[ C^H_m ;Z6_Z刌ɚFǍѭFf2,|IY6R)H! ]>u=|i+4X IFqئ0H fw;ɼFM]?q}"VNt'cO %_J= sE ږ 3՘xIhVAס};-C 6Es mJ;]cؗ0'+`AO5z.V `^ _Ou \M'x0~L-gI*bN[D6Z ՆZP꫿(zm,`OƉY6[`L;_&Ob&C qDF޵S@rD; 'UhǛa(%ξ4ݍd'|wEkSqJjS/Y'G2W^7Pϖ2]U z^cQ|t#Ȼt&rgQ@_%#P{juӞ*f }00}98";NJrס5Γeið-)(SWkz,̢]y^Nl9Ÿw& ~}N6?8^S[x-pѬ/e?헊s6L1cK2${~j/}j dA>;D߫V_iz[Mw^A  ^2v1`FWT5?x}Vanـν+ \ԉ>#9J{-Ow ig0tvN6]1vI]}$z^/l . ;*{FJ ; ᣽K &}b`?_2YYdZ;+yS&euz,Y5O&'6ű%G?ތsBR{s`/R>wW'q~Y/-l A5tjg#/*aC3 *z5< ġFځ"6["K-un1O4sDXcĥGcmGKi2+xi9}A&LĿ :8rY!q7MTNG* o9vKAqǫn2ؐmc2s&QʹKwi;Gi,5YFSjZ?Cyqer,_O\@)%گ(˝oqH N֨( ݿ>Y׏3]([CI:"6BJA7f #5SpLG@ A򩭛Mœ{G:݅'ŁYH!Z\dﴜ,{O)A>*}zjiΟ8~]볗Yl |MC]Uɛ^O#HH:as-hyچ IDATYt_7EI}*0=. >bdoȥ#}sVN*Fģd#r8hO!t} Pґ>IGQ'sxE khX6lţpߏ֎~_"./X+ >(=D,<8FS2oәl|V#mdsk/\AR/,# ^u:l4&54#٨yKA-B#Y#\c7"Me~@AOFq:Fg&nQ_%l%:0# Se~MxhDhG{-r8\DtNfNpw:F;lior7UW l}V?'r`cMRm'S黂=8(v&ESt 2H Qܿ_mY2VЯנ"+ _ zM_𫴦t֪6o^‹q|:W1[/n30:=Y6z4} Q>]7?\&bpI4f1Na_k,c.QA!hxb6"GDlX|x4>3]V\5قxNCvI׻6L-m-[2\Y ?bK#ڒdSؔОU_C`.ed3:=4$<x[]jwj Xۗ=ˎ`_G=Yf_Kb_!^{%9R&@ O 2f4s  x$<*!v(-i|(@b2J\z-WFxє(-}σg_#}~N*]qf tVN ނLw3б_OG[Pi }M%![؜m" . Uo3r s1S6Ƀ-Mo$C+sjD: ;.uck3pMY L'tk}ݘ|QFW畣LbU dYhg-Y3Ɍ7uWv%ʟ3\cd` ,E2@#|pg᝵kFWqK|5KREsgz_pc̽0uZ1tT+E>d׎3u9L_g^ZBuH@6jH#DV@Ġ#41Hmފm(E]tMl.Ѻ.$:#Z^3 G@T'EhO#z"ʩ=!ъ.b.O~ůb>:x>:AR~P b<6lV幤:W,SCi'2@HGu"<aX:QKS¥ NҰ[9fm{$׀*n}5[Z1f-qlӧS詠E.lc>о~P{@|+<68h _C8i阍1K^~9)j)o X(x8yZOIob'D .wN13D dƜ<dpbE"^>uΛ,WA* :_~=p;r[agRә~re4]hu,+/TJ0'I;XzbK,KyٴYOc5C2nK n$02F?^23ImŖ1 :Nj*-BD:Uߴ[(@Vfu}TuH/5 _FS1T||QʓVGd;mO#m.xvB{ؓUѐRE|K\feA ^ pXݰOCyk}]yIas;^JTkojE9+\'ox}~?n8 wwք*:pc3m֟)HkF,W{:3ϱm|"67L>nҠe.i;I*xj-EDT}(ǟ>xdcU:kM`گE5w`B=V2K@b9=ꨊ 㭩wiC+J:ۇ8WN@Oo5p4ܒ3ś'C|[u+]-u++0U9HY8`֠⟿ٶ<9sϵ2Tk?:a6i$66g6:rD4It4MjԀtH*3DB*RVZ_5Qixg^iy=^)B_Vw$mD=vjkJO9x'4ev7Z ݷ_]qMIܢA+Dsjy=΃ YڿzS ^C2c*O6b_a_l0s~`Nhy;ȭZghpߊ]0npCl4Mf"ѝC9 imZx6.&ŚkH= Q4z.jnU :umwTo,ݕS*0(W\F3w@]%8׮}Z=jlF.X;XIۃV`0LuF)_Gf>NSngWa|A159Uq|I(BC%¾ir440$x 0qKO,H3I!.ѣ^uRɏ{c]i(;  YqxG36.(}<0cvv7ikǕ9X[W 6Mxv_P{@2Db ;!mqBMR.Jpʄf/ꠥ`P(nfz~an гt{3DPg}d>V_f]Y -Z{}m^^OXl$q1a-jcDm"_v&}[JvM"ɨCrGTRHGqĀH)G4lbT=6}Bꅇ,9uuƟ7\[mF kz'ԮN6sM=6\TdGZroqQ8w7#E*)z"J+TD8|~E`b-k* .ڬ8εi鸖4YgY`ey.% J6}Xt[k VWJ:Z}Z40a>1~%&%f1\f.eXW{e^W׍#.eHi ~>׀6_5wUF!LQ˰"U#Ld qhVSzĠ/7@'G@I DXOKmYy۳zj(o8X7  LJGwmTh*+A 8nkw,6,aFh󻉞j| <*PPVWoY]es}U$l5*Ui}%FZ{WiҠ"@, 4&[=K׍3wM{ p>0$8~CM7aA0)4׳_o;N*ݑ>x_~}}Rs!~!xB 3;.V} HWyjAnɓJA ҷbv2YSfbuɒ5QYS}^?L+$KuGf[e̡ϒ[ :re5x:E`mV ?Ϋ ߿jOلM1kƺ~> R -== ʕ5f{Bµ ;ݮvO+ dG7.@Vqھa>с_č9w"3pf_ߕpY,ư=n,鸇Hngb:TK뭩$` H!D5guj!mf =RbyUK-կv{O 6z֣,}FDz{@|4E"ci2'q1KKQ |ʴFM苲 'M|~p-[..i%3 W{ZU0Ѥڅ.u_r6]JJ㝸Ot NV?z@v,ZηXY*sQ}g+mm"vyN$5~>ezb^;^;I{hȍSye/5~40N_Rp¿\~-fkHHo%1.eQθ[5бr! IDATs dbd#blٮD嵻~w.N}J;-6g߄?db/Ij F>8pys R1S֞x`6$`IJ!: 6B2u8S;ȼ8'^uR Q'YVXu!MԯγkjLeEfZƠJCn-TS4|E ͑l)4RKLDSh*G~WFTB)|K5jZ$}5B*kfTko"Ln mŕ.nRR`~&tc%_2{Ȳ<;لL/Vo~N>݋ʹ ;pw3"jX%yײu[ghqݧ1'8}p_kyYB7.}8Rv|̕x`?ԨJ9@ D NjA-3dO-LfPzsA_bD]lzVǺB3+5v6.<QÃwR1;1;|}{'5Q7xb8్$⌤!b#~~s!$!iwO2 ;}iԲ KS=N/8+D9Kzk\%]w(ڡJ{ak"PȠ֢K|LJwC%jע3@yi0Jz&S$t*wn`B@@g0V+נm.o-Clr uiԷ.7) hCk F3)(-B?#$,fxr:,v/7!fI8g,ý YaU8.dMNbB}IN];$UbOɀۏ [;G_AW7ugih u)Jpc;40ڎxY*y5I$5yX{G 9Pgy֟ %~}  9+YA[$ l (E {>ZZ~׾7)&Nj~ϫ@.I(og 8I蒘 [ð4O}/?TLHDTTEE[z?: sZGҟ6JdU;;ʨضYdW|3ȑfТʕhR G0D-!wNcoZNؕ޺㝈ht/b KiWf{Jw>с|v*CNy~`jlV'zLgbf66:H3޻r_WITv g#yF^ݨ?ŏϐfY{Jt:@*-^֜|w2r}L1R+= ʔVw*2S8\  l3CE-#sq]3{ l/Zt.K&tNɗtr':϶b9Kk6Ja4n2z#(~f\&3$ӎtx^OW5`x2^X]v`k32vSOQ42+EE~Jo$GxA${Q_[/u0lM.A=2,D֗p&Bm$Lܛȫ2`(P*TC٨蘏ߦ{+DؙZta8z?R$t7MH[54dq, 1ٷ>ijsq}P+oaX';\+#)DHM_!Vn&>%i-J_)0}Lf&`-N@MWG}@"! F-'uP 7TMVNU- i_lY؛UpsJTPgwά=#"ܤJªM;s.)|E7]2h {r]N7o`yx-CIouͿ[G]:*A0P͏k3x^*P DCyQcYRO!d욆M ГSciGUpC1oxi)ـ#JҿeId9p|{R1`9DFѿN >/}N?{|"7 xƯR̒f(DUQJyvT^: .w JFso#}8Qpa\C6\-+QZI+ȎM(z6Nd;-4"UŪ&_yny-~/&l9Ǒ?zMBB>\ ~v؄z=2EM>ס] k0>ʃUbx=POcZ?0dH{oW0G .*t$y;x}x~z*zۚj=<7_UEȫʣT4l/ ; F)V0߶]*y҉N8Nb4MS!U^i eE_Nh )nDww{#.Pvۅ{c{cy=twa20jW0z1乂NLm|+Ծ N'2_BjߠcpnRWWN9!!e!ͪK:td)IVe8_X;-X5W(XN`}vE#mBbkI.$/c^vlj %[q&6zÄux%t]l`O9?qjK nY:ODŽmBecwn:ɏG(%ˎ֤_,za-C#=H(*)~' 0zR_\S{':;irIiǮ)*ATW~xdRQ}61qlQG梸3 EL!g)g}Kkf(Ipjt4JolE;A):\O3` {/t?ԁI? =(y.Q|5?=h #0Tk< F7.REA"w(W$ܲ̔Kx!Z\ ;_wu䷷ԯrWM<)ٕ"U7cOU4W-7}hq׌p2rϩptcAFF[J?,&WgJ<$#|e"9A̾?+4Dk pC e$j =Zyݘͯ 8 u04BS/db #Cod z!JíܗtjFhxMwU>$mtX:at/r3s 6~9y?t|e72$i鸆iJgNHl%7P.D,(:s8dphH[f^, `<0XO@?WR/s¶ XW *"jofqg Mm90Fy;z,SԤ A$J 8s`34䋯Gc纐-H?LZ.kk0D~0EWER- Xj#އ :\tlGG*܁ɽGzfδ7P1fA%lmAh RޏqVnb =ȃiZ]ggp8Jяd@Iҋ=nP?k%BX 0~C6jΖ9/eꆞ8v&  ڼi^ l!eaOp{|[/XBG{#* |V-cqs,N"ӝd.l#v!FEu4L[9J፴.M{Bb87oT p?dӅvLr='Ub>aH1%R{;Vhgۘs.qC25'~֯~v'{\Q$z#ͿIK> k4>2ndaٹsEeE:DXHѩV҅=J'oϴ2F-% 7+Eb.)xw 2;NSqH:Jȳ4x k_śіCTYI Buh!>s+?y[&&ܑ 2Lk#ON2,dJ FI ,G]{B >DW{>qgy!7.VFBEW&xh<מѳ`^Gh؇u b#]G5/p2{K|A Pӗ6_#hoPX_qR9~R8OA, Hv+ n%"2SB~g.l2~?cDta|իu?Mb BҰMҰs ?}f8΍8Q l`KASq5K6D̫w4'-˾Jrw$v?~ڱUYX_M^)tμX Jx!S!~PCoPjT'!,UN왂{o^.Ƞ#TD~wh |g1;\oI /bޫg_εեo,$穥fBA:Kᖣ)\qMb[n R0{/;*nŷW>m:y~[ 73u@%EuG<ĞsmwC ZG]z3?e_X_p'()-Kpix@_ -( IDAT^#3W]Ae[H$E ^`_`&Vmd7 qAAaFϖkҜKN13 mShi"%ԑMtN'lE]IIR@{~'? eʸSM=ǠuA?҆?$UOf">=|SzoA^ 4;ZY >xw510ŝFg e¿d?_ٰMtO%*}rrH칗X7z9\7?oF4,_2P=>!F}/ ?m}~, 3*4U~eZ/`ۊq.Nġ_*d}'ۊTUřLqԪ_h,\f|G_#2oYgR;~苬gGDh.tQT-53(an(NwsJpD>ulM?3nyVQy] ~_o>#8J摚kd+:`K,\fJ:!Tڳ^Go5 yPX?]",?3/LиOa M96 J2$;.ՕzM%|qrZ ƨBAᰳu W)n 3HN/Xyrm{O0)Qq~+4 DNJ!rŐ7 NrTdi6 -;7W1u0cRHwC@IFtr q65!a25kl!>'SA۰+Hqz| Z}N\#k(q‡wXx? f* &ڕReϪZdb J&2'hb7ۜFI.qΜheJmze?NSY}(и/)5_?q,A9E3 >iLIIt9T{fa*vno\1ˇʌ㺃*HZ}e%q HH sL{o7Y)5T$LaHKDZ4/p&2ic9}Y+ | .w ! 5Zr)?H ' 8•j ^o?>L 4`Fh"j_ǭ,}=[GMG'Nq*~2Go8}TU|<]?o44:ً~nbg[Li)Ds=>|̡~ *2rQuC<#;#Vg'{V<󎓢>;{)" (*vDc"J#(*b!X ˁppnǖWr/6;O9`sbY{tl[ F.1BzX3m -d z\s5PCN0O uǏ\uDX MBÙ(QR"mv~VS|j~zh$ )BRʏdsWvoytbW{ljCO`C>_/VjK9Sn RT [`:^6w"5{_)?J=ꏪ?H'IV4Z&4u6pg$S" @s5wω Rj"@#o+ O^ڛm0ջQz={[#ꐇlQ.Rx|~ج/2`݂9.k:У,Ӑk9t?޾C6k2PzaK] .i&$i>kj355 >gC O&/ @t]A@R_|ݒ @C9+>@e.DtujdȾj$xfq@q97RER9{ t$#!X!V$b Q8禍 5yFjNF`';ʢWē*Wy鴨ID2}U39%É,6E'lbeG)}u R -jɲg3wh}5Kg< X F(>uyTmmk926 ~D Qzb`= e?LgAݬh)~=t yXEAx8_d2uDg_!Y1~R~ S /$sOI|'@M?c8Ydhi-%PH]&?l - h95T03l;qxJSJUjJ:Qpד&2{9Q*E,*k/ZƫåZ'p04X<.A#c݂K[[mQ~,^V!ٛ/NXн(tgyQ( j]Z֕/5^jԄ|/Y` 0t[3)m{n/cqR~2g@_wx^aTe~^}6zL4}e92RM?Q% c[h}clfC~J~:O&[Pp8?A%@v1gR=9ڑU᣺GMlpf#8N59Tы-ۂ|>%~fp2;^p Gud-m))kKs>-))Bo3߭HvU Q^Jj0z%$\uƛxeD85}/b—*m4S}gƴt:^]$s+Oo L=-1' @ :ΦêyJ:UcF}r!$v 3_Ux`X39JST(kQ0z,wD'ѝf^~1 `fAe4 [hJ/MrlsNʮQuwGoqUgPѮÖxqfhJILjT|*; cIL%@TGATrDE/t#[>xρG8GS0#S>:AX r **UBj a2љ `˵loD?WTdzkUN%; ER`183TRM{lNF!A6*4r6RM @U.7J̄jh_=ANe(#6^` ^EN O-!i(~,'uzO3@[A؛PԖvz| !oS.(5lo΢H<|Sқ }/L#%UC?u篔3uoH2FS |ut2Mh4,OB0t1 Z n.+ioPjƠ7@c_ zkTx$q_ sxؙKm)E+rhI߳!N]ҬoEGfG~a:;en= ss`XJ<*H0_#3O40V7~fВЇDo+m$¨]zr ~yPTEܷ=n~Y~}gߩ"y6u_/bU'W{ʯ*ha؍>h{Kחط)SŵG7+G]Fӳ4aV :@S5_Fv;+<,+$31+ ctU~t([!r#a3 `\?Qom @H SY! Q xl\A ~)hoxܙJ>rY#Xt+UdSTslXsT壝*R'TFj83oJJ^k딉d= +MeO4jq`0RK_vf@2 :6Na3z|Ǖ]=BOn'ЏJ@93؅92/&!=ǓQxGBg4RBQ܈ ! 40auhu Pm(6 Q` NFj f6?(?iwnk}î`84f8UjG5 V;  77RK/8x9z59=|=h _mWGT0) qilGٖel>$]`; jn +@r9}PXRSN+@ L0|Rff}ܸZ,- ;`Sp'+$I:CQ`}_ڋ+WḯL}F*U&`=+V~]gi(6?NPvzgsMmJB.eZ bQ@;$^RUnՓ'bf'*?Ԡ6<^rҧb lsކ×$,s.E=op#I_5a6U"]_mR叿k8pF<ֳ֧ )~b')0R yJY)?| H<_z9Yd;G<KRg3X>0Q\SM qJ~%(=[ɭLo9?(!h($n9&с1E6)f\"sd{ BFI8"5ʩW8G _s59</q4CA0V# 9LB#ѴA6`#iAkd@MN9vI^iܰ_z/⧮ζV5lSX5p?K o }ff(IƓ4&RKzmyH&$87]\|]?*PG .w(/ HǶ⎖|ɋIݶ%* >:o_a(|jݝ8dQ@:u:{sjÛ`J}E0FA2& Osζk%a \ \M{Fo D*bJS{`x/nh_ %\;~-s~/n׊^r勨m* \udlUz$5$xq_׍OzMs{3D^n&쌁§Y~Y(?"c$l/I?rEGy$mP)#xWjq !&@$, IDAT,J+wEv.rmxPA x=6iכRc+;u!~Iί/Vr z툮glخ3#;)ñZoVF~ixUO*{zy@U3f݆wG1+u-Q@>d4GIuTBZ0i`IG,W&5q1,G|7CVeh~X|q:*O$yN8}16H/gKAq)>"gOk~p'W{= 8?E==oi| HFldŌf!QXhxtEr(u{ܳ4JrhdLxp<(7_; zsZD 6P pws* zvǕXԏIމvnkVULBeTV:z sb4V[t3 DWQ,etD E p#HI.%0Bp2.81HB?CW"c:j(ˀ,8p5 \#5(޾/<3A_+f!~Cz$LWgީWS"b%.|vŌhor1vfi#"3_:fҙ7ҷ4"V600v ۲' s,ZXS4 PXLOCx4̩!c3Vm yG?o;z6ݰg[@Ȇ0&BL;vp4,ah,řm@#E /_W3+=Chߕ0G ܂=݌} @!_:ow΁?Gȋ%iF>DT9+B~4g cqrOe\Sfk&9UkϦ` [7+Mk^@.?G;|c l] ''FI^%=Y'LLF&^nEgsrj_pe}VE B=XBr+H1EDHn~9tgf>=p?[^c_ d?~߃YrZ L)B1e%اyɪ}p" 'Ur,^~ho aX‚{pmݠ|]̫@][:g0Fm K?o Kd@HEQ-B~I xcV\:Sy V{N:Wp-n(Hy"8\` `e@~ -DJ;ivu"黕 D/h@cj}t%N!]^1wB睎kV|{AgL(}Xϵ=B* 2g\Ɣ7"h_?#Q]M-xt 0jd0>> v&>B%%[ XZܘJQPnin/f)T#xZYS|#q/^W ϥ7<כ^ل>jgpO:%@O;sEh`x6몂K qޏOd ϙe 8u/' =jL=D9)X$؅8Ʀ4x>>L&%WVct\Eĉ,B|[U*R|#[ mRg RCY{3"!NM0oĀ@/s08rb sl6a0u#i <}(leW*_RʣG ocB{3EUnLD!iq7(BX ~Ry ~Ji3y/^qΌJ>tQX,,(H85E\QH*lNCPϥ? y>2<_j;e ;H*WcKۢ{6ˉ*wkB!GSRŨv0i"}A/ö: TYz~BJK A'Mmi@ qrHa@쬕 'TV8FY=*/QHN-as]\{:j")dMHLXnU<RCo?ӷu,’I^7{lkfIn ]oð'\E'B,B߶ 2$] H>l%P8NbP3y :~?bdC+̛T/nɗS.I:9c! #`*Bo!XHaRpe9[9̠/g#ulG@_[pئ h=FcP3 UǪGONP&=䗒%5{_y!oz|vwTփesweZA![m!4Zp ʮ~]PrO^L2PC3߹8i ʋK/,t Nٸ?+2PbDH?Lr:NW* MȃB3 KH*~zW z*ED̩fXSk{M{a}_cgB A8n X7_/ӦY\'N:i59i){1O:3M,R'߈Sp }"'8󀈰jξo[8Zh|9G  ~J. e2A!CQ<&$g W_+|@)Oͨk<X<#c1'V@36b\OA!cp.^^\NB2PuWO]a uݸU6.}yֲ͢sɏ}B+cx^<-@m Zzٕͣ6Wdh76ho?d=4#W]_K* ſЫr3{mSe⦳OPʵH{اH]=tӥt&vM#Sf؅{J[VdJI+GB ";Ò$]7xu }Yz2YvgD#p{575R:AH~k`e͊h+xF R)y3^um @O4iBk~9E`_sُcMI1LdNu.)ʫMn<{:32/jyFG? ~Qd7\3xM>Zi~?KV@:| ;pkXi{V5.%0I3'/ K>&:p(pC!h^]o$t9||cgg[|5T1*pk.E֓,,$ %= y@Jpp!pae%!/[!X&`g$xȓޚF_!8JJ a:CwiK%(}1!.&J>`7cʇP&9g}藦=eAeʮkP~>BX.6MJ: Vlt㍮G]c! F.ލhd 7fr~= 8a"^k_Rsޘ%0}-)]Ƥj)99`} >Hɒ&[jB0>ິ ^"f$9(s`[AQz2+!# @XN&m=Ҕn:ZXqx 0%7@lh׎aSMw*%g#D'X"!i#Ǐ9?.̵\ؑwJJ;@dC@ 5TdJiz}G:q r gӵg{AwJIO) ҁ7]oxNJpϜ@gל'ryf>:Μ4&88|Wj*;s'N;!Z`Ms`uOOsX_4^FF)?%ZdCbs<$@3 u96G:Rȋi3 ec8lhJj/{H6K+ LD0#;~u`3nSAGU}ZtcH!kؚ& G$|C>19)+Xҿ4EaD!Y0O©: QbikyaDng4 \nk|*,4HK>"  ךIO,Ž-YRNt22Hـ%LN \0 47(~8acy']F|۪)MmjzrT*nG#8҃.L>jΚKs2̭b\Y|mL.uǺfQ !UMs ٳ&O|рOH^vytOdǻ>sYcvG#oL|%~9gAXo Mad:Q x 8Qƛaˎ Fp3yv9LG|BΧ 7ࣜ'"ˁ6H4f%x+\;#SIyRzI@)Pp G?i5ehL~{e b]7mr;/$der,uqZrNa)pMC|^7ᳰ3]H\A{V۞6^ %}R|E+ۮE,pU%KÙ{3s.^~t?FS~9$R=-sJ&g7HV`Vy?9[W(;~?@Zܕ|"&13PD0SL|wD89 +SpE(hrl2t|?i>x^ba @jz s!ɇ(0=ig^ån"=f^9L:4iړGr +yiSvU\E'Ḇ϶2m$ ,d+E5H!J|zіn:CLd3{#S:i5\(t >0fm;Kx{ykԫ=jZv5zqx3sPXGRI8!c$17#Yۤdҁː\󮊝,^Fa6/9L!fpw_Rο1XP^p&Ӣ!y{bT^MWĬq#@OR.|wHd6k\*@N <C|# &'Z"~V;SIЈF,>6܀a4n m:0e"3xo%_HӪ-H#<d.7fY0 t.LGp(%:XJӖEErj=[:%g&k[O~ݼr+| :ӂjBbm}$ |]=f-Qdt{2nlz9yֵ Cr%} s4 #ٟ وثائق عكاشة

طرق النشر

إن هناك عشرات الطرق لإطلاق تطبيقات عكاشة شأنه في ذلك شان تطبيقات WSGI حيث أنها معايير كتابة تطبيقات الويب في بايثون. ومن هذه الطرق

الطريقة التي ننصح بها هي mod_wsgi بشكل رسمي وعبر python-paste للاختبار والتطوير

طريقة CGI البائدة وما يشبهها

استخدم دالة run_with_cgi الموجودة في برنامج الصغير المرفق مع PEP 0333 هذه الدالة تستلم كائن تطبيق الويب.

ضع ذاك الكود (كود الدالة وإنشاء الكائن ثم استدعاء الدالة مع تمرير التطبيق لها) في ملف ثم ضعه في cgi-bin ثم اسمح بتنفيذه.

عبر خادم python-paste المنضدد

انظر صفحة مثال أولي بسيط

عبر mod_proxy في apache

لنفرض أن التطبيق يعمل على خادم paste الضمني على المنفذ 8080 ويستمع فقط للطلبات المحلية على العنوان 127.0.0.1 أي localhost حتى نجعله متوفر عبر خادم apache العام على منفذ 80 يمكننا بكل بساطة أن نضيف ما يلي إلى إعدادات Apache

ProxyPass         /myapp  http://localhost:8080/
ProxyPassReverse  /myapp  http://localhost:8080/

وفي هذه الحالة ستحال الطلبات القدمة إلى المنفذ 80 إن كانت تبدأ ب /myapp إلى http://localhost:8080/

عبر google app engine

لنفرض أن لديك تطبيق ويب اسمه test.py يحتوي على فئة اسمها MyWebApp ونريد تشغيله على غوغل apps engine لذا نعمل ملف الذي يشغله وليكن اسمه apptest.py مثلا هكذا:

#! /usr/bin/python
# -*- coding: UTF-8 -*-
import sys, os, os.path
from test import webApp
 
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
 
d=os.path.dirname(__file__)
application=MyWebApp(
    os.path.join(d, 'templates'),
    staticBaseDir={'/_files/':os.path.join(d, 'files')}
);
run_wsgi_app(application)

ونعمل ملف app.yaml نخبره أن يحل كل شيء إلى apptest.py هكذا

application: okashaTest
version: 1
runtime: python
api_version: 1

handlers:
- url: .*
  script: apptest.py

بعدها قم بتجربته فإن كان كل شيء على خير ما يرام يمكنك نقل تخديم الملفات الساكنة إلى google apps عوضا عن عكاشة بتعديل الملف app.yaml إلى

application: okashaTest
version: 1
runtime: python
api_version: 1

handlers:
- url: /_files
  static_dir: files

- url: .*
  script: apptest.py

ملاحظة: لا تستطيع استخدام قوالب formatTemplate لأنها غير متوفرة في بايثون 2.5 بل 2.6.

ملاحظة: عليك تعديل سطرين من كود baseWebApp.py عكاشة من except webAppBaseException as e إلى صيغة بايثون القديمة except webAppBaseException, e

عبر mod_python في خادم apache

عبر mod_wsgi في خادم apache

طريقة توزيع الملفات

قم بتثبيت إضافة mod_wsgi في خادم أباتشي من مدير الجزم (في أعجوبة اسم الحزم هو mod_wsgi)

تأكد من تثبيت الحزم التي قد تلزمك مثل python-kid أو python-elixir (هي لا تلزم عكاشة لكن من المفيد استعمالها)

بعد ذلك قم بإعادة توزيع الملفات بحيث تناسب الخادم فإن كان حسابك على الخادم يعطيك وصول إلى مجلد البيت وكنت تضع ملفاتك هناك ضعها خارج مجلد public_html. كذلك خصص مجلد لتضع فيه ما قد يلزمك من مكتبات بايثون بما فيها وحدة تطبيق الويب الخاص بك مثلا /home/ahmad/pyapps/ ثم اعمل ملف بايثون مهمته الوحيدة تعريف كائن اسمه application من صنف تطبيق الويب الخاص بك. سم ذاك الملف myapp.wsgi

# -*- coding: UTF-8 -*-
import sys, os, os.path
prefix=os.path.expanduser('~/myapp-files/')
pyprefix=os.path.expanduser('~/pyapps/')
sys.path.insert(0, pyprefix)
from myapp import MyApp
application=MyApp(
  os.path.join(prefix,'templates'),
  staticBaseDir={'/media/':os.path.join(prefix,'static-files')}
  );

هذا الملف يحدد /home/ahmad/pyapps/ كمجلد للبحث عن مكتبات بايثون والتي من بينها myapp.py كذلك يحدد المجلد /home/ahmad/myapp-files/ كي يحتوي على القوالب والملفات الساكنة.

إعداد apache

لنفرض أن لديك خادم وتريد تشغيل التطبيق فيه على جذر نطاق فرعي sub-domain اسمه myapp.myhost.org عندها تكون الإعدادات كما يلي:

<VirtualHost *:80>
  ServerName myapp.myhost.org
 
    WSGIDaemonProcess myapp.myhost.org processes=1 threads=15 display-name=myapp user=ahmad group=ahmadgroup
    WSGIProcessGroup myapp.myhost.org
 
    WSGIScriptAlias / /home/ahmad/pyapps/myapp.wsgi
 
</VirtualHost>

يمكنك أيضا إلقاء عبئ تحميل الملفات الساكنة على خادم الويب وليس على عكاشة وذلك بإضافة المقطع التالي داخل السابق

    DocumentRoot /home/ahmad/myapp-files/static-files/
    Alias /favicon.ico /home/ahmad/myapp-files/static-files/favicon.ico
 
    Alias /media/ /home/ahmad/myapp-files/static-files/
 
    <Directory /home/ahmad/myapp-files/static-files>
    Order allow,deny
    Allow from all
    </Directory>

عبر Fast CGI

توفر flup دعم fast cgi تطليقات wsgi مثل عكاشة كل ما عليك هو عمل ملف يشبه الملف أدناه وتسميته myapp.fcgi وحفظه في مكان يراه خادم apache

#! /usr/bin/python
# -*- coding: UTF-8 -*-
 
sys.path.insert(0, os.path.expanduser('~/projects/'))
from flup.server.fcgi import WSGIServer
from myapp import MyApp
application=MyApp(
  os.path.join(prefix,'templates'),
  staticBaseDir={'/media/':os.path.join(prefix,'static-files')}
  );
 
if __name__ == '__main__':
  WSGIServer(application).run()

انظر

خوادم أخرى

من أفضل خوادم WSGI أداءً وتوفيرا في الذاكرة وسرعة الاستجابة

تقييم خوادم WSGI

بعكس ما تتوقع فإن أداء twisted و tornado كان سئيا جدا في اختبارات الأداء.

okasha-0.3.0/docs/elixir.html000066400000000000000000000600051412405540000160660ustar00rootroot00000000000000 وثائق عكاشة

قواعد البيانات عبر الإكسير

مقدمة

يمكن استعمال ربط تطبيقات عكاشة مع قواعد البيانات مثل sqlite (دعمها مدمج في بايثون) أو mysql عبر حزم بايثون لهذا الغرض (مثل pymysql)

لكن في هذه الحالة يكون عليك متابعة عدد من الأمور مثل:

  • تكون محصور في قاعدة بيانات بعينها (مثلا سيكون من الصعب نقل الكود من SQLite إلى MySQL أو PostgreSQL)
  • عليك القيام يدويا بتحسين تعابير SQL
  • في sqlite لا تستطيع التحدّث مع اتصال فتحته في thread آخر ممّا يعني أنك قد تحتاج لعمل اتصال لكل طلب.

لذا هناك بديل لهذه الطريقة اسمه SQLAlchemy وحوله بُني الإكسير لتسهيله.

الإكسير عبارة عن ORM أي Object-relational mapping حيث تتحوّل الجداول والصفوف وعلاقاتها إلى كائنات.

تدعم SQLAlchemy عددا كبيرا من قواعد البيانات من بينها:

  • Sqlite
  • MySQL
  • Oracle
  • Postgresql

إنّ الإكسير يقوم بالكثير من التحسينات فهو مثلا يعمل اتصال واحد مع قاعدة البيانات إلاّ في حالة Sqlite يقوم بعمل اتصال لكل thread

الإكسير من خارج عكاشة

عمل المخطط

لنفترض أن لدينا قاعدة بيانات للكتب تتكوّن من جدول للمؤلفين وجدول للكتب وجدول للناشرين وجدول للتصنيفات من خلال keywords.

جدول الكتب يتكوّن من الحقول التالية:

  • معرف رقمي فريد تلقائي
  • اسم الكتاب وهو نص قصير
  • وصف الكتاب وهو نص حر طويل
  • عام النشر
  • معرف ISBN فريد ومفهرس
  • المؤلّفون وهي علاقة كثير لكثير many to many مع جدول المؤلفين يعني ممكن أن يكون أكثر من مؤلف لنفس الكتاب أو للمؤلف الواحد أكثر من كتاب
  • الناشر وهي علاقة كثير لواحد أي قد يكون لأكثر من كتاب ناشر واحد
  • التصنيفات وهي علاقة كثير لكثير.

جدول المؤلفون حيث يتكوّن من الحقول التالية:

  • معرف رقمي فريد تلقائي
  • اسم المؤلف وهو نص
  • عام الميلاد
  • عام الوفاة أو صفر للأحياء
  • الكتب وهي علاقة كثير لكثير (عكس علاقة المؤلفون في جدول الكتب)

جدول الناشرون

  • معرف رقمي فريد تلقائي
  • اسم الناشر وهو نص
  • الكتب وهي علاقة واحد لكثير (عكس علاقة الناشر في جدول الكتب)

جدول التصنيفات بالكلمات المفتاحية

  • معرف رقمي
  • الكلمة
  • الكتب وهي علاقة كثير لكثير

تنفيذ المخطط

لنكتب وحدة module تُعرّف هذه القاعدة كما يلي ونحفظها في ملف باسم bookstoreModel.py

from elixir import *
 
class Book(Entity):
  using_options(tablename="book")
  n = Field(Integer, primary_key=True, autoincrement=True)
  title = Field(Unicode(30), index=True)
  description = Field(UnicodeText)
  year = Field(Integer)
  isbn = Field(String(16), index=True, unique=True)
  authors = ManyToMany('Author', lazy=False)
  publisher = ManyToOne('Publisher', lazy=False)
  keywords = ManyToMany('Keywords', lazy=False)
 
class Author(Entity):
  using_options(tablename="author")
  n = Field(Integer, primary_key=True, autoincrement=True)
  name = Field(Unicode(30), index=True)
  details = Field(UnicodeText)
  year_of_birth = Field(Integer, index=True)
  year_of_death = Field(Integer, index=True, default=0)
  books = ManyToMany('Book', lazy=True)
 
class Publisher(Entity):
  using_options(tablename="publisher")
  n = Field(Integer, primary_key=True, autoincrement=True)
  name = Field(Unicode(30), index=True)
  books = OneToMany('Book', lazy=True)
 
class Keywords(Entity):
  using_options(tablename="keywords")
  n = Field(Integer, primary_key=True, autoincrement=True)
  name = Field(Unicode(30), index=True)
  books = ManyToMany('Book', lazy=True)

في نفس المجلد افتح بايثون التفاعلي واكتب فيه

from bookstoreModel import Book, Author, Publisher, Keywords
import elixir
elixir.metadata.bind='sqlite:///db.sqlite'
elixir.setup_all()
elixir.create_all()

الأمر الأخير create_all يعمل على إنشاء قاعدة البيانات (نستدعيه مرة واحدة حيث لاحقا نكتفي ب setup_all) وهي في مثالنا نتحدث مع قاعدة بيانات من نوع sqlite وهي موجودة في الملف db.sqlite لاحظ سطر bind

يمكنك طبعا استعمال mysql وتقديم اسم مستخدم وكلمة سر واسم القاعدة …إلخ مثلا

elixir.metadata.bind='mysql://user:pass@localhost/mytestdb'

لكن دعونا نتابع مستخدمين ملف sqlite وليس mysql. الآن اخرج من مفسر بايثون التفاعلي وانظر محتويات ملف db.sqlite عبر الأمر التالي:

sqlite3 db.sqlite .dump | less

ستلاحظ مخطط قاعدة البيانات schema دون مدخلات لأنها لا تزال خالية.

لنعد إلى مفسر بايثون التفاعلي ونفتح قاعدة البيانات بالأوامر

from bookstoreModel import Book, Author, Publisher, Keywords
import elixir
elixir.metadata.bind='sqlite:///db.sqlite'
elixir.setup_all()

في مراحل الاختبار يمكنك إظهار عمليات SQL حتى تراها بعينك وذلك بكتابة السطر

elixir.metadata.bind.echo = True

إضافة المدخلات

لنقم الآن بإدخال بعض الحقول في قواعد البيانات. ولنبدأ بعمل حقل في جدول الكلمات المفتاحية وذلك عبر الأمر

kw_s=Keywords(name=u"science")
kw_a=Keywords(name=u"art")
p1=Publisher(name=u"My Press")
p2=Publisher(name=u"Nashir2")
elixir.session.commit()

السطر الأول يعمل كائن من نوع Keywords ويعين خصائصه والتي هي name ويعطيها قيمة science وهذا يعني عمل صف في جدول keywords قيمة العمود name فيه هي science. يتم حفظ هذا الكائن في المتغير kw_s وهذا غير إلزامي لكنني فعلته لأني قد استخدمه لاحقا.

السطر الثاني عمل كائنا آخر وبالتالي صف آخر بقيمة أخرى. ثم علمنا ناشرين بنفس الطريقة. ولو قمت الآن بفتح قاعدة البيانات لن تجد فيها شيء ذلك أن الإكسير يجمع العمليات إلى أن تطلب منه إرسالها محسنة عبر الدالة elixir.session.commit.

لنضف الآن عدد من المؤلفين

a1=Author(name=u"Oqlah ibn Khalaf", details=u"short story pioneer in Balama", year_of_birth=1975)
a2=Author(name=u"John Random Hacker", details=u"fictional author from cyberspace", year_of_birth=1980)
elixir.session.commit()

لنضف الآن أحد الكتب

b1=Book(title=u"The twilight of Balama", description=u"a short story.", year=2010, isbn="0-1234-5678-9", publisher=p1)
b1.authors.append(a1)
b1.keywords.append(kw_a)
 
b2=Book(title=u"Facts you don't know", description=u"true stories from a fake author", year=2010, isbn="1-1234-5678-9", publisher=p2)
b2.authors.append(a2)
b2.keywords.append(kw_s)
 
elixir.session.commit()

لاحظ استخدام append لإضافة العلاقات. طبعا يمكنك استخدام الاستعلامات لتوليد الكائنات التي تمررها إلى append عوضا عن حفظ الكائنات في متغيرات

الاستعلام والتعديل

أغلق جلسة بايثون التفاعلي السابقة ولنبدأ واحدة جديدة ونكتب بدايتنا التقليدية

from bookstoreModel import Book, Author, Publisher, Keywords
import elixir
elixir.metadata.bind='sqlite:///db.sqlite'
elixir.setup_all()

لنستعلم عن شيء له معرف فريد أو فهرس فريد مثلا

b=Book.get_by(isbn="1-1234-5678-9")
print b.title

لاحظ استخدام get_by على الفئة نفسها دون كائن منها (يعرف هذا class method أو static method) مع تمرير لها معرف isbn للحصول على كائن الكتاب. وباملناسبة يمكننا التعديل على الكائن مباشرة حيث تعكس تلك التعديلات على قاعدة البيانات فور عمل commit مثلا لنفرض أني أريد زيادة علامة تعجب في نهاية العنوان

b.title+=u"!"
elixir.session.commit()

إن العلاقات تعمل بشكل تلقائي يعني لو استعلمنا عن الكتب تحت تصنيف art يمكننا طباعة أسماءها وأسماء مؤلفيها

kw=Keywords.get_by(name="art")
for b in kw.books:
  print "book: ",b.title,", authors: "
  for a in b.authors:
    print b.name,
  print "."

الاستعلام والفلترة

بطريقة مشابهة لنفرض أننا نريد كل الكتب التي طبعت بعد 1960

books=Book.query.filter(Book.year>1960)
for b in books: print b.title, "@", b.year

يمكننا أيضا تركيب الفلاتر وراء بعضها كذلك يمكننا ترتيب النتائج وأخذ أول كذا نتيجة

books=Book.query.filter(Book.year>1960).order_by(elixir.sqlalchemy.desc(Book.year)).limit(10)
for b in books: print b.title, "@", b.year

مثال على ربطها مع عكاشة

okasha-0.3.0/docs/images/000077500000000000000000000000001412405540000151505ustar00rootroot00000000000000okasha-0.3.0/docs/images/important.png000066400000000000000000000043121412405540000176730ustar00rootroot00000000000000PNG  IHDR00WbKGDIDATx{W?. [X Ei*HK#&ElJFc#hLFG(j)j-+/AX](>fgv޿73;3+TIn~{{=;|(4ik=o |t֣H2pi1Vb'SNu,ߌi(8?//V0~N>..kK~dmd]HE )%"i,)n^?$TȾm[r8$P.B^Kc8np%ٞ@xf9aRGiN }#Ԩ0H[0}p9.j7n`CtLGTF!\AHLX5b I+qvNA|i!Of:" f%Xne"1M(\o;U*k)6ncaq9ԭ|݆b&Z_bUY_g_k]<:SQNGɲYQaFSS]# 6c֯Α3!BO )sP_W Dirh6@B Q95W/@kGm!UDR";g=cq=}AoΟLAN)E2LCcd/Vtr 4mM<dh{{7J"?V &:-Z}0عN~otz_ePsWVI|vy#įRNd&`u&|~JV)ow> 9tx,KGAZ,jQ-=ǥa꣗]5 Ze[A+>S]9_D?s9*t"MMۋhwk׵!R![15GjAV*|VX_@΀܉ UZ:ip/g8ޕUN ]ih=WO7d}Ϋ!OA:RzYL摮>Q%)@Pә/OlZk.{xhm-!ܿ($g0݋t8;W/kA&)g\_SY @ijN Q!WW*ĸVڥu5@Řι&X,t:Y|$S38ӓlƲ.ñ4%7.|9abnide. W{WN\ѧޢ7@8U6!!ʇװWњfbJcu Wz_;&H\ìk!"r,p͜VQE.%[+'-*F#1H:*s,η*sb7:X2zd6UG}tgqx\ZGJI*--KB \U0jRVmU&s X̞gJ]Eix%Ns .S㏝K*@L>ETq`3\'>O mAv8]Y胖; l@Z.EPVpQ!X[n0p8nf3d# HdªFfT`*gjn-&s*'QC6"1`HI[D:nO2۲W8Lx,L 2q>ycv2.m3u^5Tp)iPc6}XKWH83Q*3ŭ8W߰lcF2*W 6m2h)U8pN[Rc< ?-%5$o<;"VIENDB`okasha-0.3.0/docs/images/note.png000066400000000000000000000047301412405540000166270ustar00rootroot00000000000000PNG  IHDR00WbKGD pHYs  ~tIME :9@>tEXtCommentCreated with The GIMP (c) 2003 Jakub 'jimmac' Steiner'3X IDATxYWsU3,' fqv㐘(X@x@""@gx`y@B!   %$, Kl !=]uU=3 v!#u6r^hhhUF rU>Fj(NO297͗Fk-/| Ghgmn\6Wvċ @w-yW>~"`G_m/@IYšv,ĿMD03cz@NqAQp^ѵk1 ȟt"=I)ޗ&yNbzzZ@D8}1t{99qz_ ==5~r z{jdY"R#KYN3u:7t/>|=AG6P \W3Sg>~>C{k,T1WhhH(`iڡyѕ(ݫr\M1tp ;9X'O%Z.1+71`8LE$ t)P(@ġ>チw=zf?+Sٸ:p6Lє"*_Ʋ8M JZ4oⱩY߿z_^l̄=8Ϋ723Wly[(4 XP @@xOp޸|S<̾?ayu3[fxvMH-hRn*:JJ!рHH3^in_ޣ1S\P(`|E3l1cu shBBjGؽ2^y-yn\K׀3]@NHp΁8+)|Q(Nz-chpyQj8J N$ j@k5Ay Vv'$i(Rss$TI E'F%/S[Vi<0;;"8'$> (A4"O4j.& %MJQ1?C(RABHNRb 18uhZƍ:Sl߶ :0i^u KQ ?ꀪ"Zf xwܱy?uFh疡~^~| 7_Wu<Nhpα !/:  8PZ^Y؃y6@?1l#Dլ:27枟?>~X\~&F֬ G|ʾsD),aVfG6X72PNYU]Ȳ^PB=7_* ){ `]/Y3P_awClYYmIQŠ6ĢQ#9Rίmfff6 3B)Kr-Rt@NUfDU͐ /X?Rc("FbNU|߫F ;יaf$Iҝ,tml޵033GJ:ifK,bCFQiR[ F+SA\6#J `vv+4jZs'0=:AxbL8c1Ӡ k|ňڑ =!"vQ=jm̌gƏo~ MS ~{#:c'NEnYk97_^wúl3zV4X?2̦sŖKlq?2>щ<ã㌎$i~x1PyL4Ml6gggOEQ@R=]FZ5!939UeÆ.2;T׷*ggӍ%;lň]X/?̗Q*ݲ{y9/弜t0 ?IENDB`okasha-0.3.0/docs/images/tip.png000066400000000000000000000055351412405540000164620ustar00rootroot00000000000000PNG  IHDR00WbKGD IDATx͚yluμGR4)ы6,9*R-P*l,+i9AiQw Wiq Fn\^buE[ɒBUU17q7s9c#1e;lwhXaŠ ܆+\g-EX ( j:p5`fVX!Y mnݷ{w6omͺu;{mŤi >}C^W@@"'r`>~ "(*x8q_?s@qՒ2Сy__uNr/lWyUz"zy柿mRR*EJ(XkQD29``ͷnػNMMN w ؐ]ۻwߟ=~juQ[8΀fsUIhEv/j]~lo YJ*!sOlpSdž8QUS㜠\xQ+> ru߇ &! {ol۶ZxK~4rQ5(wr<Qjb^W=ΝQd(EU}edd]H=4jSBZ-Q[9^&50|^~."KI$E"f>go60f& I ϟ:y),)T{s-i;O/IB;uIf}o2c3;.ZRrQhx'UO*)w39~Ki\ {RiFhf ?^ eN@|駞{XeRMIq)mh;G4ɋlE,`EkG2F SXxӏ?4<2DI% #!E}T"Aw3f>0 C tN|hr!h#ǧ2QISng/`Ȫ`K7N ><4-GL/p_/g$S't{O ^p"Icyw3NUH6B*u6md]ЈwM ^-` hY"8w_|oZ&#gH}BwjD\2KJdR)”'#^s:"M`0XvE%^|޽ѯg7]`Q%(gM6ej<_k_3\@k_"q `HS%2-"ڈՍO9vy> _ ;r#uh\viō poB{&DYE}Xk R28CN%h"P kQ+bmȷSP~dL c $fvMl9&jtc_nyꗸ1f*$C\fc6h5W\m[zHq_*5Oyܰi ׾HC\B-?uxz_D+625z Q-|{V}VB$TkmZm*ӃLk j4fh* ı~ܹ]9z_jSu?VoE5Aõh FM'jKrʭL7mb'5  I;9O2:Qlʡ]/ PȵzWjҬѨMnHRG;qiAz$zM7_S`g] B2K8%*L a|L/i4?:rzSUQ٪#M*xTKP[W.~]~螮U+{pITk;VkmɊ<+@gM+`wq?l*^3::::ah-Q LB<7l_z8ccc9|8Yhf|<WadIit9\9䖿7Zyt9r7ˉ_mrYx/ڥ>1WIENDB`okasha-0.3.0/docs/images/warning.png000066400000000000000000000062611412405540000173300ustar00rootroot00000000000000PNG  IHDR00WbKGD fIDATx՚{pUU$ Q4t0m(Z!)-i3ִ `V%GA@`(MmHDBHBnrs9??Vdٲedeem~Wꍄ7xwΝ MMMލx5߉Xi"dgge˖ɋ/V ˀPXf&ػw;v|cc#~;6t wwIZˉScRPP09''YTTt.xGcǎQ]]EY>aU0 !=3ܹsٺuO.]_|QD4eݿ,..޶m۶`+WPy ڵ Up)3ӧ1dƬ\n:e…=F@9r/BYQQ!['?e|{JXsQ^AN9r@;f4MScϗo?EKlgm߼ysܴGanOE1љ's}ئ0Qr+[_-c|<ΰYb3ev5%: > R[[KաChaɋNw׽ :I\ZI?J77FY7-=i2l,^y)-rPx[l|ee%}d8[x",Pl !LlKG nUub-=y2:ƍ|vmZTM6qرnRT1cD7 ;|_~~ N$E }W1>H B* i}|S~=yWzi T|fML;tPRRRF^5:,ˢ{iOJ F )BHawKaH!@8=)ᄿf=?<2AoWN''|wؖmY Hm[ٹg~8qzO@ O0*~\.W<*Ѻ]!c*^Im l!m+/^(Eahۚi5$x'g%@2|8'vՉ-T,D5A&{OԞז a@X&O*#n!ԁp8U]6u\(((JCIE іՙ@tLY;%#4 iCF1b*t FiiBSs3D R {vIo`!oȵfʏtPZ;KÅPUÃoq!vO4=a`SsӉLf,ZBkvD'%JlFPܨ@\.z:-Q{=DZ jO*& !_ #|?T+7|M `EAA)QvHKTkVhl|f9u5! i(/H `zN:BH) Iz(Sד P%FFۇMi[ \ 9gf8[ov_3v?RJ2e0t ] {!vQU5DwnzNkl+б4JGW'ЙgȜ934` TA( *t==p8T&h1zO|F"1 =[ zVSL+( sƌGg1}X6:z);TGJl+DH4l3w1wvԸc]]k;yN3f ř˹2\ o ]}JZ nwEPm0е zOcc-Ql};a\qYF;IK0RbFsEA%K._VV… cփ%u4Zϟ:ba~84 0jHmrk &ښv}ޡjѝ~c1g߾૪7oNZ uIfggjnMM %>Kmqqܚz¾jТFx@ƌqFJdggSRR*pT+B*pO@\3gl4Dee媬, @ 1i)-7|Y /]3gάOt:AիN'--JJh,g?cAXי6 DLx'e(2]׻.ߥAY\\,'M$`BO[ʰ:?䓉RS\FtK8јg/R^^I.uu}mu]}ÇOiiiƙD*uEb].yɜ9sn xEQ(,,ߦ4iȿt~k4{2ǃ<}Z} $1 H< وثائق عكاشة

إطار الويب عكاشة

تمهيد

إطار الويب عكاشة إنّ مواقع الإنترنت الناجحة ليست مجرّد صفحات HTML ساكنة بل إنّ أغلبها تحتوي على محتويات تفاعلية (تستخدم حسابات أو قواعد بيانات وتتفاعل مع المستخدمين وتسمح لهم بالتعليق والتواصل معاً)، يتم توليد المحتويات عبر لغات برمجة تنفّذ على الخادم.

إنّ تطوير تطبيقات الويب يحتوي على الكثير من الأمور الرتيبة المملّة، ومن هنا ظهرت الحاجة لأطر الويب web frameworks

تمّ تطوير إطار الويب عكاشة أساساً من أجل عمل تطبيق الويب في مشروع ثواب ثم رأيت فصله حتى يمكن الاستفادة منه في عمل تطبيقات أخرى حيث أنه كود عام يصلح لأي تطبيق ويب.

الوثائق

إن أفضل وثيقة لفهم عكاشة هي بالنظر إلى الكود وإلى مثال test.py لكن هذا لا يعني أنه لا يوجد وثائق. يمكنك أن تبدأ بقراءة

الأسئلة الشائعة

ما هو عكاشة ؟

هو إطار ويب لعمل تطبيقات ويب متطوّرة بلغة البرمجة بايثون متوافقة مع مبدأ ويز-جي WSGI بكل بساطة وسهولة.

من هو عكاشة ؟

هو الصحابي الجليل عكاشة بن محصن1) رضي الله عنه وهو ممّن يدخلون الجنّة بلا حساب ولا عذاب. قال عنه ابن حجر في الإصابة: من السابقين الأوّلين وشهد بدراً، وقع ذكره في الصحيحين في حديث ابن عباس في السبعين ألفاً الذين يدخلون الجنة بغير حساب، فقال عكاشة: ادع الله أن يجعلني منهم. قال: “أنت منهم”. فقام آخر فقال: “سبقك بها عكاشة”. قيل: استشهد عكاشة في قتال أهل الرّدة.

ما معنى الكلمة ؟

في القاموس المحيط نجد أنها العَنْكَبوتُ، أو ذُكُورها، أو بَيْتُها (…) عُكاشَةُ الغَنَوِيُّ، وابنُ ثَوْرٍ، وابنُ مِحْصَنٍ، الصحابِيُّونَ.

ذكر ابن منظور في لسان العرب تحت جذر عكش: عكَشَ عليه: حَمَلَ. وعَكِش النباتُ والشعرُ وتعَكَّش: كَثُرَ والتفَّ. وكلُّ شيءٍ لزم بعضُه بعضاً فقد تَعَكَّشَ. وشعرٌ عَكِشٌ ومُتَعَكِّشُ إِذا تلبَّد. وشعر عَكِشُ الأَطراف إِذا كان جَعْداً (…) وشجرة عَكِشَةٌ: كثيرةُ الفروع مُتَشَجِّنةٌ. والعُكَاشة والعُكَّاشةُ: العنكبوت: وبها سمي الرجل. (…) وعُكَيْشٌ وعُكَّاشةُ وعَكَّاشٌ: أَسماء. (…) وعُكَّاشة بن مِحْصن الأَسدي: من الصحابة، وقد يخفّف.

الشكر لأخي طه الزروقي الذي اختار الاسم.

من أين أحصل عليه ؟

كود عكاشة متوفّر من خلال بوتقة أعجوبة

للحصول على آخر إصدار اتبع الرابط التالي

لماذا لم يكتب على php كبقية التطبيقات في العالم ؟

لغة php ليست لغة نظيفة خصوصا في ما يتعلق بدعم utf-8

هل هو وفق بُنية MVC ؟

نعم تستطيع أن تقول ذلك. إذ يشكّل الصنف baseWebApp المتحكّم Controller ويترك لك الإطار اختيار أي كائن بايثوني ليكون النموذج Model (الذي قد يكون مصدره من قاعدة بيانات عبر elixir) وتحدّد أي نظام قوالب تريد ليكون عنصر العرض.

هل يدفع أم يسحب ؟

أطر الويب نوعان push-based و pull-based. الأول تقوم بالمعالجة ثم يدفع بالنتائج والثاني يقوم بعرض صفحة من القالب ثم يسحب النتائج إليها عبر مصادر متعدّدة.

يمكن تطبيق النمطين في حالة عكاشة. يمكنك أن تدفع بالقيم إلى قالب ليتم عرضها، كما ويمكنك البدء بصفحة هيكلية ثم سحب عدة مكونات فيها عبر ajax مثلا باستخدام قالب jsonDumps.

أين تضعه مقارنة بالأطر البايثونية الأخرى ؟

يمتاز عكاشة عن كل أطر الويب التي اختبرتها بالبساطة لهذا أُعرّفه إطار الويب البدهي trivial web framework أو إطار الويب الذي لا يقوم بشيء do nothing web framework بمعنى أنه لا يقف في طريقك ولن يكون صعبا عليك أن تدرك كل ما يحيط به في ذاكرتك دون الرجوع للوثائق.

عكاشة أقرب ما يكون إلى cherrypy وأبعد ما يكون عن django

الكثير من أطر الويب تحدّد لك نموذج البيانات ومحرّك القوالب وغير ذلك من العوامل، كذلك فإنّها غالبا تتطلّب عمل شجرة معقّدة من الملفات والإعدادات، بل إنّها في الغالب تأتي مع برنامج يعمل تلك الشجرة لتشابكها فيقوم البرنامج بعمل الكثير من الملفات التي قد لا تتمكن من هضمها كلها.

في Pylon يتم تعريف طريقة التعامل مع URL من خلال مكتبة routes الذي بدوره يحاكي RoR حيث تربط أنت نمط من العناوين مع دالة معينة. في حين أن طريقة الربط محدّد مسبقا في عكاشة بحيث تمنعك من “إطلاق النار على نفسك!”

باختصار إن إطار عكاشة هو تطبيق لمبدأ بايثوني معروف وهو أن الصريح أفضل من الضمني والبسيط أفضل من المعقد.

كيف يمكنني اختبار برنامجي ؟

يمكنك إطلاق خادم ضمني صغير يقوم بتشغيل تطبيق الويب دون الحاجة لخادم apache.

أين أجد هكذا خادم ضمني ؟

بما أنه مطابق لمعايير WSGI يمكنك استخدام أي خادم ضمني يدعمها. أفضل مثال على ذلك هو عبر مكتبة python-paste وهي مكتبة بايثونية صرفة لا يزيد حجمها عن واحد ونصف ميغابايت. وهي تعمل على كل الأنظمة بما فيها ويندوز.

كيف يمكنني نشر تطبيق الويب ؟ وأي الاستضافات تدعمه ؟

إن هناك عشرات الطرق لإطلاق تطبيقات عكاشة شأنه في ذلك شأن تطبيقات WSGI حيث أنها معايير كتابة تطبيقات الويب في بايثون. ومن هذه الطرق

  • عبر برنامج wrapper صغير يجعلها تعمل كتطبيق CGI على أي خادم يدعم CGI أو FastCGI أو ما شابه
  • عبر mod_wsgi في خادم apache
  • عبر mod_python في خادم apache (لكنه يحتاج wrapper ولا ننصح بها)
  • عبر خوادم ضمنية منضددة مثل python-paste
  • عبر تشغيل الخادم الضمني ثم عمل وكيل له proxy من خلال mod_proxy من داخل apache

للمزيد انظر صفحة طرق النشر

1) هو عكاشة بن محصن بن حرثان بن قيس بن مرة بن كبير بن غنم بن دودان بن أسد بن خزيمة
okasha-0.3.0/docs/sample1.html000066400000000000000000000611031412405540000161340ustar00rootroot00000000000000 وثائق عكاشة

مثال أولي بسيط

إن غالبية دوال وصنوف عكاشة موثّقة جيّداً لذا يمكنك استعمال pydoc للوصول لها.

كذلك يمكنك استعمال المثال test.py الموجود في كود عكاشة فهو يوضّح أغلب استخدامات عكاشة.

بعكس ذاك المثال المسهب فإن هذه الوثيقة ستعلّمك كيف تعمل مشروع بدهي مثل “مرحبا، يا عالم!”

وقبل أن تبدأ تخلّص من الخوف فأغلب الكود هو تعليقات (مجرد شرح).

كيف نبدأ ؟

أنشء مجلّد للمشروع. وإن لم تكن الاعتماديات1) مثبّتة في النظام أو كنت تريد أن يكون التطبيق الخاص بك قابل للنقل portable إلى أجهزة لا تضمن أن يكون عكاشة وبقية الاعتماديات مثبّتا فيها كل ما عليك هو وضع نسخة من تلك الحزم داخل مجلد المشروع الحالي.

بعكس أطر الويب الأخرى تطبيق الويب هو مجرّد ملف واحد به صنف واحد لذا اعمل ملف سمّه مثلا myapp.py ولتكن محتوياته كما يلي:

#! /usr/bin/python
# -*- coding: UTF-8 -*-
"""
this is my first okasha web app
"""
from okasha.baseWebApp import *
 
class MyApp(baseWebApp):
  def __init__(self, *args, **kw):
    baseWebApp.__init__(self,*args, **kw)

وبهذا نكون قد أنهينا أول تطبيق لنا

كيف نشغّل هذا التطبيق ؟

هناك عدّة طرق لإطلاق تطبيقات عكاشة. أسهلها وأفضلها خلال فترة التطوير هو استعمال حزمة python-paste

يمكنك عمل ملف منفصل اسمه serve.py مثلا يقوم على تشغيل التطبيق الخاص بك وذلك كما يلي

#! /usr/bin/python
# -*- coding: UTF-8 -*-
import sys, os, os.path
# this requires python-paste package
from paste import httpserver
from myapp import MyApp
 
d=os.path.dirname(sys.argv[0])
application=MyApp(
      os.path.join(d,'templates'),
      staticBaseDir={'/media/':os.path.join(d,'media')}
);
httpserver.serve(application, host='127.0.0.1', port='8080')

فعند تنفيذ برنامج serve.py أعلاه سيعمل خادم paste الضمني المنضدد على المنفذ 8080 (يمكنك تحديد أي رقم) وسيقبل أي اتصالات من العنوان المحلي 127.0.0.1 . إن كنت تريده أن يستقبل من كل العناوين اجعله 0.0.0.0 للمزيد من الخيارات انظر وثائق paste

بل ويمكن وضع هذا الكود داخل الوحدة التي تحتوي تطبيق الويب نفسه يعني في مثالنا يمكن الاستغناء عن serve.py وذلك بأن نجعل ملف myapp.py كما يلي:

#! /usr/bin/python
# -*- coding: UTF-8 -*-
"""
this is my first okasha web app
"""
from okasha.baseWebApp import *
 
class MyApp(baseWebApp):
    def __init__(self, *args, **kw):
      baseWebApp.__init__(self,*args, **kw)
 
if __name__ == '__main__':
    # this requires python-paste package
    from paste import httpserver
    import sys, os, os.path
 
    d=os.path.dirname(sys.argv[0])
    application=MyApp(
      os.path.join(d,'templates'),
      staticBaseDir={'/media/':os.path.join(d,'media')}
    );
    httpserver.serve(application, host='127.0.0.1', port='8080')

وفي هذه الحالة لا نحتاج ملف serve.py حيث يمكننا إطلاق تطبيق الويب عبر تنفيذ myapp.py حيث أن الجزء في آخر الملف لن ينفّذ في حالة استخدام الملف كوحدة بايثونية (مكتبة) بل عند تنفيذه كبرنامج وليس مكتبة.

ما معنى الكود ؟

في أول البرنامج أول خطوة قمنا بها هي استيراد محتويات إطار الويب عكاشة

from okasha.baseWebApp import *

ثم قمنا بتعريف كائن مشتق من تطبيق الويب الأساسي في عكاشة baseWebApp

class MyApp(baseWebApp):

وفيه عرّفنا دالة الاستهلال التي كل مهمّتها هي استدعاء الدالة في الصنف الأساس وتمرير المعاملات له بشكل أعمى (سنشرح هذه المعاملات لاحقا)

  def __init__(self, *args, **kw):
    baseWebApp.__init__(self,*args, **kw)

يمكنك استقبال معاملات خاصة بك هكذا للاحتفاظ بها لاستخدامها لاحقا هكذا

  def __init__(self, name, *args, **kw):
    self.name=name
    baseWebApp.__init__(self,*args, **kw)

أما كود التشغيل فهو كما يلي:

from paste import httpserver

نستورد خادم http من داخل حزمة paste. يستقبل خادم paste تطبيق الويب المتوافق مع WSGI كمعامل أول هكذا

httpserver.serve(application, host='127.0.0.1', port='8080')

حيث application هو تطبيق الويب وهو في حالتنا كائن فرد من الصنف MyApp الذي اشتققناه من تطبيق الويب الأساسي في عكاشة baseWebApp

نقوم بعمل هذا الكائن كما نعمل أي متغير أو كائن في بايثون

    d=os.path.dirname(sys.argv[0])
    application=MyApp(
      os.path.join(d,'templates'),
      staticBaseDir={'/media/':os.path.join(d,'media')}
    );

المتغير d يمثّل المجلّد الذي يحتوي تطبيق الويب وقد قمنا بتحديد مجلد فرعي عنه اسمه templates كي يحتوي القوالب كذلك طلبنا أن تحال كل العناوين التي تبدأ ب /media/ إلى المجلد الفرعي media داخل مجلد التطبيق حيث يمكننا استخدامه لوضع ملفات الصور وملفات css وغيرها من الملفات الساكنة static files.

يوفّر عكاشة أكثر من طريقة لتخديم الملفات الساكنة منها أن تمرّر له قاموس staticBaseDir مفاتيحه هي الجزء في بداية العنوان ثم المجلد الذي سيتم البحث عن الملفات فيه (يمكن استخدام أكثر من مجلد)

كذلك هناك خاصية أخرى وهي عمل إعادة توجيه redirect لطلبات معيّنة إلى عنوان آخر أو خادم آخر يحتوي تلك الملفات الساكنة.

للمزيد انظر وثائق دالة الاستهلال لصنف baseWebApp في كود عكاشة.

ماذا يفعل هذا التطبيق الخالي ؟

سيبحث عكاشة عن الطريقة/الدالة في كائن التطبيق فإن لم يجد واحدة مناسبة فإنه يستدعي الدالة _root ويمرر لها كائن من الصنف Request يحتوي تفاصيل الطلب ويمرّر له بقية عناصر العنوان. وحيث أنّنا لم نعرّف تلك الدالة فإن دالة _root التلقائية الموجودة في عكاشة تعمل وتظهر لنا في شاشة المتصفح عند زيارة الموقع صفحة html تحتوي

You requested [/]

فإن زرنا العنوان http://localhost:8080/hello/omar سيظهر في المتصفح

You requested [/hello/omar]

كتابة دالة خاصة بنا

جرّب إضافة الكود التالي بعد دالة الاستهلال init في صنف MyApp

  @expose()
  def _root(self, rq, *args):
    return """<html><body>
<img src="/media/logo.gif"/>
<h1>welcome to my first okasha application</h1>
</body></html>"""

الكثير من النّاس لا يألَفون استخدام @ أو ما يُسمى decorator وشرحها في هذه المرحلة غير مناسب لكن اعلم أنها تستدعي دالة خاصة وهي expose موجودة داخل عكاشة تقوم هذه الدالة بتغيير الدالة التي بعدها وهي في مثالنا _root

يمكنك أن ترى وثائق دالة expose في كود عكاشة حتى تعرف ما هي المعاملات التي تستقبلها لكن إن استعملتها دون أي معاملات كما فعلنا فهي تعني أننا لن نستعمل أي قوالب بل سنعيد كود html

لاحظ أننا استعملنا ملف logo.gif الموجود في media لكن الرابط الذي استخدمناه قد لا يكون صحيحا دائما لأنه إن كان التطبيق يعمل من داخل سابقة ما حيث لا يكون التطبيق مربوط على جذر الخادم بل داخل سابقة هكذا http://myhost/myapp ويكون ذلك مفيدا عندما يكون هناك أكثر من تطبيق على نفس النطاق domain

وحتى لا تعيد كتابة الروابط يمكنك استخدام rq.script التي تعيد سابقة التطبيق الخاص بنا (طبعا ستكون نص خالي إن لم يكن هناك سابقة)

  @expose()
  def _root(self, rq, *args):
    return """<html><body>
<img src="%s/media/logo.gif"/>
<h1>welcome to my first okasha application</h1>
</body></html>""" % rq.script

التفاعل مع عناوين URL

  @expose()
  def hello(self, rq, *args):
    if not args: s="world"
    else: s=args[0]
    return """<html><body>
<h1>Hello, %s!</h1>
</body></html>""" % s
 
  @expose()
  def _root(self, rq, *args):
    if not args: raise redirectException(rq.script+'/hello/')
    elif args[0]=='favicon.ico': redirectException(rq.script+'/media/favicon.ico')
    else: raise forbiddenException()

في هذا المثال عملنا دالة اسمها hello سيتم تنفيذ هذه الدالة عند زيارة /hello/ أو /hello/Name/ أو ما شابه. هذه الدالة تستلم بقية العنوان على شكل معاملات حيث ستكون قيمة args منظومة خالية [] أو ['Name'] على الترتيب في المثالين.

كذلك جعلنا الوصول لجذر التطبيق يحيل إلى العنوان /hello/ الذي بدوره يطبع Hello, world! لأنه لا يوجد تتمة للعنوان (المنظومة خالية)

كذلك عملنا تحويلة أخرى داخل _root تحيل من favicon.ico إلى /media/favicon.ico

أمّا إن لم يجد دالة مناسبة ولم يحصل أي من الحالتين السابقتين (أي لم نطلب جذر التطبيق ولا favicon) عندها سينفذ ما بعد else وهو في حالتنا رفع الخطأ رقم 403 ممنوع الوصول لتلك الصفحة.

يمكنك مكان السطر الأخير كتابة ما يلي

  else: raise fileNotFoundException()

حتى تحصل على الخطأ 404 (صفحة غير موجودة)

كذلك يمكنك تخصيص الصفحة التي تظهر عند حدوث هذين الخطأين عبر تخصيص الدالة _403 و _404

التفاعل مع النماذج forms

غيّر الدالة hello لتصبح كما يلي :

  @expose()
  def hello(self, rq, *args):
    n=rq.q.getfirst('n','world').decode('utf-8')
    return """<html><body>
<h1>Hello, {0}!</h1>
<form name="MyForm">
Please enter name:
<input name="n" type="text" value="{0}"></input>
</form>
</body></html>""".format(n)

لاحظ استخدامنا ل rq.q.getfirst للحصول على قيمة عنصر من النموذج وهو في حالتنا n وهي ذاتها التي تأتي من مربع النص الذي اسمه n في كود html. إن لم تكن تلك القيمة التلقائية world مكانها

1) الاعتماديات التي نحتاجها في هذا المثال هي عكاشة و python-paste فقط
okasha-0.3.0/docs/templates.html000066400000000000000000000701671412405540000166020ustar00rootroot00000000000000 وثائق عكاشة

القوالب

تحتوي عكاشة على طريقة مرنة لعمل القوالب. حيث كل ما عليك هو تحديد الدالة التي ستسلم كائن بايثون (مصدره قد يكون قاعدة بيانات مثلا) مسؤولية تلك الدالة تحويل الكائن المستلم إلى صفحة ويب. يمكن استخدام كائن قابل للاستدعاء callable object أو نوع منه مكان الدالة حيث يتم إنشاء الكائن تلقائيا مرة واحدة عند تشغيل تطبيق الويب.

يتم تحديد الدالة عبر @expose

قوالب formatTemplate

هذه الدالة تحتاج تحديد ملف موجود في مجلد القوالب وتستلم قائمة من العناصر أو كائن من نوع قاموس dict. في الحالتين يوضع المعرف (الذي هو المفتاح في القاموس أو الإزاحة في القائمة) بين حاصرتين { }. إليك هذا المثال

  @expose(formatTemplate,["hello.html"])
  def hello(self, rq, *args):
    n=rq.q.getfirst('n','world').decode('utf-8')
    return {"name":n}

ويمكن أن تكون محتويات القالب كأي ملف HTML هكذا:

<html><body>
<h1>Hello, {name}!</h1>
<form name="MyForm">
Please enter name:
<input name="n" type="text" value="{name}"></input>
</form>
</body></html>

حيث سيتم تعويض قيم مفاتيح القاموس (وهي هنا name) مكان {name}

إن كنا أعدنا قائمة فإننا نستخدم الإزاحة هكذا {0} أي العنصر الأول و {1} أي العنصر الثاني.

توفر هذه الدالة الكثير من طرق التنسيق مثلا

<tt>{balance:.3f}</tt>

هذه الطريقة مفيدة جدا إلا أنه يعيبها

  • أنها لا تحتوي على حلقات تكرارية loops
  • مزعجة عندما يحتوي كود HTML على دوال جافاسكربت لأنه عليك تكرار الحاصرات

للمزيد انظر وثائق بايثون عن هذه الصيغة

قوالب percentTemplate

هذه الدالة تحتاج تحديد ملف موجود في مجلد القوالب وتستلم كائن من نوع قاموس dict مفاتيحه تستخدم كي يتم تعويض قيمها في القالب. إليك هذا المثال

  @expose(percentTemplate,["hello.html"])
  def hello(self, rq, *args):
    n=rq.q.getfirst('n','world').decode('utf-8')
    return {"n":n}

ويمكن أن تكون محتويات القالب كأي ملف HTML هكذا:

<html><body>
<h1>Hello, %(n)s!</h1>
<form name="MyForm">
Please enter name:
<input name="n" type="text" value="%(n)s"></input>
</form>
</body></html>

حيث سيتم تعويض قيم مفاتيح القاموس (وهي هنا n) مكان %(n)s والصيغة بكل بساطة تشبه printf وهي % ثم اسم المفتاح بين قوسين ثم رمز نوعه (غالبا s) ويجب الانتباه إلا أنه إن احتجت إلى % كما هي اكتب وهذه الطريقة كسابقتها يعيبها أنها لا تحتوي على حلقات تكرارية loops إلا أنها لا تكون مزعجة عندما يكون هناك داول javascript داخل كود html لكنها مزعجة عندما يكون هناك علامة % المستخدمة في سمات CSS حيث يجب أن تكتب

للمزيد انظر وثائق بايثون عن هذه الصيغة

قالب jsonDumps

في تطبيقات ويب 2.0 قد يلزمك إرسال بيانات عبر AJAX. إن أفضل طريقة للقيام بذلك هي عبر هيئة JSON وهي نص عبارة عن كود بلغة جافاسكربت يتم إرساله للطرف الآخر. يمنك تحويل أي كائن بايثوني إلى نص JSON عبر هذا القالب مهما كان معقدا يعني لو كان عندك منظومة array عناصرها قواميس dicts قيمها منظومة عناصرها منظومات …إلخ.

في هذا المثال فإن كود بايثون التالي يعيد منظومة بها 3 عناصر نصية

  @expose(jsonDumps)
  def array(self, rq, *args):
    return ["one","two","three"]

أما الكود التالي فيرسل قاموس (في جافاسكربت يصبح associated array) مفتاحاه الاسم name والوظيفة job

  @expose(jsonDumps)
  def array(self, rq, *args):
    return {"name":"Ahmad","job":"Manager"}

في جافاسكربت إن استلمت هذا الكائن تحت اسم d فإن القيم ستكون d.name و d.job

قوالب bottle المتقدمة

إن كنت بحاجة إلى جمل شرطية أو حلقات تكرارية أو تنفيذ أي كود بايثون أو حتى تسريع للقالب عبر عمل نسخة خبيئة مكونة من python byte code فإن هذا القالب هو ما تبحث عنه

لا يحتاج هذا القالب أي اعتماديات خارجية ويوفر العديد من المزايا المتقدمة على بساطته

في هذا القالب تستطيع وضع أي تعبير بايثوني (على أن يعيد نص أو عدة نصوص) بين حاصرتين مزدوجتين هكذا:

Hello, {{name}}!

هنا سيتم تعويض قيمة name بعد Hello. والتي قد تعطي شيء يشبه

Hello, Ali!

يمكن استخدام تعابير أعقد مثل

Hello, {{user.get_name() if user else "world"}}!

هذا التعبير البايثوني يعني إن كان الكائن user معرفا فإنه يستدعي الطريقة user.get_name وإلا فإنه يساوي الثابت “world”

كذلك يعمل على تخطي العلامة الخاصة ب html حتى تظهر بالشكل الصحيح. مثلا إن كانت القيمة مثلا <a> فإنه سيحوله إلى &lt;a&gt; حتى يظهر في HTML كما هو فإن كنت تريده أن يظهر دون تخطي ضع ! بعد فتح الحاصرتين.

Hello, {{!name}}!

يمكنك استخدام عبارات 'if' و 'elif' و 'else' و 'try' و 'except' و 'finally' و 'for' و 'while' و 'with' و 'def' و 'class' لكن على أن تبدأها ب % وأن لا يسبقها إلا مسافات وعلى أن تنهيها ب %end وذلك عوضا عن المسافات البادئة في بايثون مثلا يمكنك أن تعمل ما يشبه

<html>
 <head>
  <title>{{title}}</title>
 </head>
 <body>
  %if colors:
  %for c in colors:
    <p>I like <strong>{{c}}</strong> apple</p>
  %end
  %else:
    <p>no color is provided</p>
  %end
  <p>for more details on this template visit <a href="http://bottle.paws.de/docs/dev/stpl.html">Bottle Docs</a></p>
 </body>
</html>

كذلك يمكنك احتواء قالب آخر عبر %include ثم اسم الملف دون .tpl ثم إن شئت معاملات معرف = قيمة فاصلة معرف = قيمة وهكذا أو حتى ** ثم كائن dict

والأجمل من ذلك هو عمل قالب يحتوي عبارة %include دون أي معاملات في وسطه وفي ملف آخر يبدأ أو ينتهي بعملية %rebase متبوعة اسم ذاك القالب الأول (مع معاملات إن شئت) وعند استعمال الثاني سيتم معالجة القالب ثم حشره ناتجه في وسط الأول مكان كلمة %include

مثلا يكون عندك ملف layout.tpl يحتوي على كود html وكلمة %include في وسطه مثلا

<html>
<head>
  <title>{{title or 'No title'}}</title>
</head>
<body>
<div class="sidepane_block" style="width: 50%; float:right;">
{{sidepane()}}
</div>
<div class="content_block">
  %include
</div>
</body>
</html>

وفي ملف آخر نعمل

%def sidepane():
this will go on side box
%end
This is the page content: {{content}}
%rebase layout title='Content Title' sidepane=sidepane

علما أنه يمكن %rebase أكثر من مرة.

هذا القالب مستعار من إطار الويب bottle وهو وفق رخصة MIT الحرة المتساهلة للمزيد من المعلومات راجع وثائق قالب bottle

قوالب kid المتقدمة

إن كنت تريد قوالب تجمع بين بايثون و xml أو xhtml فعليك ب kid وهي حزمة متخصص في هذه الأشياء (اسمها في فيدورا هو python-kid).

إلى جانب حزمة python-okasha-kid التي هي جزء من عكاشة فإن هذا القالب بحاجة لحزمة خارجية وهي python-kid ولن يعمل إن لم تكن تلك الحزمة مثبتة.

وتستخدم كما في المثال المرفق مع عكاشة test.py هكذا:

from okasha.kidTemplate import kidTemplate
  @expose(kidTemplate,["kidtest.kid"])
  def kidtmp(self, rq, *args):
    return {
      'h1':'this is how kid templates works',
      'ls':['apple','banana','orange','tomato']
      }

حيث هنا كما في percentTemplate نعيد قاموس لكن ليس بالضرورة أن تكون قيمه نصوصا حيث يمكن أن تكون القيم منظومة array كما في ls

أما ملف القالب kidtest.kid فهو xml يحتوي على تعويض قيم وحلقات بل وأكود بلغة بايثون

لاحظ كيف استدعينا بايثون كما نفعل مع php هكذا

<?python
import time
title = "A Kid Template"
?>

كذلك لاحظ كيف قمنا بتعويض القيم في هذا السطر

<title py:content="title">

وفي هذا السطر

<h1 py:content="h1">title goes here</h1>

والأجمل هو الحلقات التكرارية كما في

<ul>
    <li py:for="fruit in ls">I like ${fruit}s</li>
</ul>

سيقوم kid بتحويل الملف kidtest.kid إلى وحدة بايثونية مصنفة kidtest.pyc وسيتم عمل خبيئة منها cache مما يعني أنه عليك إعادة تشغيل التطبيق عند تعديل القالب.

للمزيد انظر وثائق kid

قوالب xslt

قالب xsltTemplate لتحويل أي كود xml إلى أي كود xml آخر مثل xhtml بواسطة ملف xsl

إلى جانب حزمة python-okasha-xslt التي هي جزء من عكاشة فإن هذا القالب بحاجة لحزمة خارجية وهي python-lxml ولن يعمل إن لم تكن تلك الحزمة مثبتة.

سأكتب المزيد عنها

okasha-0.3.0/docs/update-from-site.sh000077500000000000000000000023231412405540000174270ustar00rootroot00000000000000#! /bin/bash exit 0 baseurl="http://www.ojuba.org/wiki/_export/xhtml/okasha/" for i in "" deployment sample1 templates elixir do fn="${i:-index}.html" i="${i:-الصفحة_الأولى}" echo "getting $fn from ${baseurl}${i}" rm "$fn" 2>/dev/null || : curl -L -o "$fn" "${baseurl}${i}" perl -i -lwne 'BEGIN{$echo=1;} s:okasha-logo:logo:g; s:href="/wiki/okasha/([^"]+)":href="${1}.html":g; s:src="/wiki/_media/okasha/([^?"]+)(\?[^"]*)?":src="../files/$1":g; s:href="/wiki/_detail/okasha/([^?"]+)(\?[^"]*)?":href="../files/$1":g; s!a href="http://!a target="_blank" href="http://!g; if(/\]*\>/){$echo=0;} if(/#discussion__section|\<(link|meta|script)[^>]*\>/){next;}if (/class="tags"/) {$echo=0;} if($echo){print $_;}if (/\<\/div\>/) {$echo=1;} if(/\<\/head\>/) { print ""; print ""; print "وثائق عكاشة"; print ""; print ""; print ""; print ""; $echo=1; } ' "$fn" done okasha-0.3.0/okasha/000077500000000000000000000000001412405540000142215ustar00rootroot00000000000000okasha-0.3.0/okasha/__init__.py000066400000000000000000000000001412405540000163200ustar00rootroot00000000000000okasha-0.3.0/okasha/baseWebApp.py000066400000000000000000000531411412405540000166100ustar00rootroot00000000000000# -*- coding: UTF-8 -*- """ Okasha - a very simple WSGI webframe work Copyright © 2009, Muayyad Alsadi Released under terms of Waqf Public License. This program is free software; you can redistribute it and/or modify it under the terms of the latest version Waqf Public License as published by Ojuba.org. 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. The Latest version of the license can be found on "http://waqf.ojuba.org/license" """ import sys, os, os.path, time, re # import json for templates try: import json except ImportError: import simplejson as json import urllib.parse # for parsing query string from cgi import FieldStorage # for html escaping from html import escape # for html escaping from operator import attrgetter # for OkashaFields from http.cookies import SimpleCookie # in python 3.0 it's from http.cookies import SimpleCookie from .utils import fromFs, toFs, safeHash try: from io import StringIO except ImportError: from io import StringIO #import urllib # to be used for quote and unquote # TODO: use c=Cookie.SimpleCookie(string) webAppResponses={ 200:'200 OK', 302:'302 Temporary Redirect', 304:'304 Not Modified', 403:'403 Forbidden', 404:'404 Not Found', 500:'500 Internal Server Error' } class webAppBaseException(Exception): """ exceptions like fileNotFoundException """ def __init__(self, code, *args,**kw): self.code=code self.args=args self.kw=kw notModifiedException=lambda *a,**kw: webAppBaseException(304,*a,**kw) forbiddenException=lambda *a,**kw: webAppBaseException(403,*a,**kw) fileNotFoundException=lambda *a,**kw: webAppBaseException(404,*a,**kw) def redirectException(location,*a,**kw): e=webAppBaseException(302,*a,**kw) if type(location)==str: l=location.encode('utf-8') else: l=location e.kw['location']=l return e class OkDict(dict): """ a dictionary that can be accessed through mydict.key constructor takes an extra argument that is the default value you can't set values for the following keys: 'iteritems', 'pop', 'has_key', 'viewkeys', 'viewitems', 'itervalues', 'get', 'keys', 'update', 'popitem', 'copy', 'iterkeys', 'fromkeys', 'setdefault', 'viewvalues', 'items', 'clear', 'values' example usage: mydict=OkDict(None, {"y":3}) print mydict.x print mydict.y mydict.y=2 mydict.x=7 print mydict.x print mydict.y """ def __init__(self, default=None, *a, **kw): self.__dict__["_default"]=default dict.__init__(self, *a, **kw) self.__dict__["_protect"] = set(dir(self)) self._protect.add("_protect") #print filter(lambda s: not s.startswith('_'), self._protect) def __getattr__(self, key): return self.get(key, self._default) def __setattr__(self, k, v): if k in self._protect: raise KeyError self[k]=v return v def __delattr__(self, key): if key in self: del self[key] return super(dict, self).__delattr__(key) class Response(OkDict): def __init__(self, rq=None, code=None,contentType=None,headers=None): OkDict.__init__(self) self.rq=rq self.code=code self.contentType=contentType self.headers=headers self.cookies=SimpleCookie('') self.title='' self.meta_description='' self.meta_keywords=[] self.js_links={} self.css_links={} def add_js_link(self, js, weight=50, pos='head', name=None): ''' js is relative to theme name is a way to avoid registering the same file twice pos can be head, begin, end ''' if not name: name=os.path.basename(js) if pos not in self.js_links: self.js_links[pos]={} if name in self.js_links[pos]: return False self.js_links[pos][name]=(weight, js) return True def add_css_link(self, css, weight=50, media='all', name=None): ''' css is relative to theme name is a way to avoid registering the same file twice ''' if not name: name=os.path.basename(css) if media not in self.css_links: self.css_links[media]={} if name in self.css_links[media]: return False self.css_links[media][name]=(weight, css) return True def render_css_links(self): r=[] for media, v in list(self.css_links.items()): l=list(v.values()) l.sort() for w,f in l: r.append('' % ( media, self.rq.script, self.rq.webapp._themePrefix, f, )) return '\n'.join(r) def render_js_links(self, pos='head'): if pos not in self.js_links: return '' r=[] l=list(self.js_links[pos].values()) l.sort() for w,f in l: r.append('' % ( self.rq.script, self.rq.webapp._themePrefix, f, )) return '\n'.join(r) def setCookie(self, key, value, t=None, path=None, domain=None, comment=None): """ sets or replace a cookies with key and value, and sets its expire time in seconds since now (if given) """ if isinstance(value,str): value=value.encode('utf8') self.cookies[key]=value if t!=None: # TODO: is this the right way of setting both expires and max-age self.cookies[key]['expires']=time.strftime("%a, %d %b %Y %H:%M:%S UTC", time.gmtime(time.time()+t)) if t>0: self.cookies[key]['max-age']=t if path==None: path=self.rq.script+'/' if isinstance(path,str): path=path.encode('utf8') self.cookies[key]['path']=path if domain!=None: self.cookies[key]['domain']=domain if comment!=None: self.cookies[key]['comment']=comment ok_tailing_digits=re.compile("^(.*?)(\d*)$",re.U) class OkashaFields(FieldStorage): def __init__(self, *args, **kw): self._ok_max_files_count=-1 FieldStorage.__init__(self, *args, **kw) # TODO: do we need to process tmp files by overriding make_file and delete ? def _suggest_fn(self, fn, suffix_len): if suffix_len==None: i=fn.rfind(".") if i<0: i=len(fn); b=fn[:i] e=fn[i:] l=ok_tailing_digits.findall(b) b=l[0][0] n=l[0][1] if not n: n=2 else: n=int(n)+1 fn=b+str(n) while(os.path.exists(fn)): n+=1; fn=b+str(n) return fn def save_as(self, key, fn, overwrite=False): if key not in self: return False l=self[key] if type(l) is type([]): if len(l)==1: i=l[0] else: return False else: i=l if os.path.exists(fn): if overwrite: os.unlink(fn) else: return False i.file.seek(0) try: open(fn,"wb").write(i.file.read()) finally: i.file.seek(0) return True def _save_in(self, i, d, overwrite, name_pattern, suffix_len, max_size): # FIXME: max_size is ignored r=0 if name_pattern==None: name_pattern=i.filename fn=os.path.join(d,name_pattern) if os.path.exists(fn): if overwrite==False: return 0 elif overwrite==None: fn=self._suggest_fn(name_pattern, suffix_len) else: os.unlink(fn) i.file.seek(0) # FIXME: done at once using memory, maybe we want to do it in chunks # FIXME: implement size-based limits try: open(fn,"wb").write(i.file.read()); r=1 # on success finally: i.file.seek(0) return r def save_in(self, key, d, overwrite=False, name_pattern=None,suffix_len=None, max_count=0, max_size=-1): """this method handles multiple files having same form name if overwrite==False then already existing files will be ignored if true they will be overwritten if None then number will be aded or incremented after name_pattern[:-suffix_len] if suffix_len==None then rfind('.') will be used return number of successfully saved files on success 0 key not found -1 max_count exceeded -2 max_size exceeded -3 dir does not exist -4 IOError """ if not os.path.isdir(d): return -3 r=0 if key not in self: return r l=self[key] if type(l) is type([]): c=len(l) if max_count<=0: max_count=self._ok_max_files_count if max_count>0 and len(l)>max_count: return -1 for i in l: try: r+=self._save_in(i, d. overwrite, name_pattern, suffix_len, max_size) except IOError: return -4 else: try: r=self._save_in(l, d, overwrite, name_pattern, suffix_len, max_size) except IOError: return -4 return r class Request: def __init__(self, webapp, environ, start_response): self.webapp=webapp self.environ=environ self.script=environ.get('SCRIPT_NAME','') # the uri of the webapp self.rhost=environ.get('REMOTE_ADDR','') self.start_response=start_response self.response=Response(self) # FIXME: find a way to simplify decoding query strings into unicode qs=environ.get('QUERY_STRING','') if 'wsgi.input' in environ: self.q=OkashaFields(fp=environ['wsgi.input'],environ=environ) else: self.q=OkashaFields(fp=StringIO(''),environ=environ) try: self.cookies=SimpleCookie(environ.get('HTTP_COOKIE','')) # cookies['key'].value except: self.cookies=SimpleCookie('') self.uri=environ['PATH_INFO'] # can be / or /view if type(self.uri)!=str: try: self.uri=self.uri.decode('utf8') except UnicodeDecodeError: webapp._logger.warning('unable to decode uri=[%s]' % self.uri.__repr__()) self.uri=None if not self.uri: self.uriList=[]; return if self.uri.endswith('/'): self.tailingSlash=True else: self.tailingSlash=False if self.uri.startswith('/'): self.uriList=self.uri[1:].split('/') else: self.uriList=self.uri.split('/') # NOTE: this should never happen if self.uriList and self.uriList[-1]=='': self.uriList.pop() class expose: def __init__(self, template=None, templateArgs=[],templateKw={}, responseCode=200, contentType='text/html; charset=utf-8', headers={}, requiresTailingSlash=False ): """ a decorator that applies the result of the function to the provided template """ if type(template) is type: self._template=template(*templateArgs,**templateKw) else: self._template=template self._templateArgs=templateArgs self._templateKw=templateKw self._response=responseCode self._contentType=contentType self._headers=headers self._requiresTailingSlash=requiresTailingSlash def __call__(self, func): def wrapper(*args): if not args: raise webAppBaseException(500) elif isinstance(args[0],baseWebApp) and len(args)>=2: rq=args[1] else: rq=args[0] if self._requiresTailingSlash and not rq.tailingSlash: raise redirectException(rq.script+rq.uri+'/') # FIXME: do we need here a try: except: if self._template: r=self._template(rq, func(*args), *self._templateArgs, **self._templateKw) else: r=func(*args) # fix response if rq.response.code==None: rq.response.code=self._response if rq.response.contentType==None: rq.response.contentType=self._contentType # FIXME: it should be merged not replaced if rq.response.headers==None: rq.response.headers=self._headers rs=webAppResponses.get(rq.response.code,"%d Unknown code" % rq.response.code) cookies=rq.response.cookies.output(header="") if cookies: h=[('Set-Cookie',c) for c in cookies.split('\n')] else: h=[] rq.start_response(rs, [('content-type', rq.response.contentType)]+h+[(k,rq.response.headers[k]) for k in rq.response.headers]) if type(r)==str: return (r.encode('utf8'),) elif isinstance(r, str): return (r,) return r return wrapper def formatTemplate(rq, v, bfn=None): """ see http://docs.python.org/library/string.html#format-string-syntax """ fn=rq.webapp._getTemplateFile(bfn) try: tmp=open(fn,'r').read().decode('utf-8') except IOError: raise fileNotFoundException() except: rq.webapp._logger.debug('template error fn=[%s]' % fn) raise # Note: try is used to check for valid template #try: s=[(tmp % v).encode('utf-8')] # NOTE: it expects a byte sequence not unicode object try: if isinstance(v,dict): s=tmp.format(**v) else: s=tmp.format(*v) except TypeError: raise KeyError except KeyError: raise TypeError # FIXME: use logger for above exceptions return s def percentTemplate(rq, v, bfn=None): """ see http://docs.python.org/library/stdtypes.html#string-formatting-operations """ fn=rq.webapp._getTemplateFile(bfn) try: tmp=open(fn,'r').read().decode('utf-8') except IOError: raise fileNotFoundException() except: rq.webapp._logger.debug('template error fn=[%s]' % fn) raise # Note: try is used to check for valid template #try: s=[(tmp % v).encode('utf-8')] # NOTE: it expects a byte sequence not unicode object try: s=tmp % v # NOTE: it expects a byte sequence not unicode object except TypeError: raise KeyError except KeyError: raise TypeError # FIXME: use logger for above exceptions return s def jsonDumps(rq, o): if not rq.response.contentType: rq.response.contentType='application/x-javascript; charset=utf-8' return json.dumps(o, ensure_ascii=False) class fakeLogger: def debug(self,msg): pass def info(self, msg): pass def warning(self, msg): pass def error(self, msg): pass def critical(self, msg): pass def parse_theme(theme_d): r={} fn=os.path.join(theme_d, "theme.txt") if not os.path.exists(fn): return {} try: f=open(fn) t=f.readlines() f.close() except: return {} for l in t: a=l.strip().split("=",1) if len(a)!=2: continue r[a[0].strip()]=a[1].strip() return r def get_theme_parent(theme_d): t=parse_theme(theme_d) return t.get('parent', None) def get_theme_dir(lookup, theme): for i in lookup: d=os.path.join(i, theme) if os.path.isdir(d): return d raise IOError def get_theme_dirs(lookup, theme): parents=[] while(theme): d=get_theme_dir(lookup, theme) parents.append(d) theme=get_theme_parent(d) return parents class baseWebApp: """ The base for our web Application, it's a mini web framework """ _mimeByExtension={ 'html': 'text/html', 'htm': 'text/html', 'txt': 'text/plain', 'css': 'text/css', 'js':'application/javascript', 'ico': 'image/x-icon', 'png': 'image/png', 'gif': 'image/gif', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg' } def __init__(self, theme_lookup, theme='default', themePrefix='/theme/', staticBaseDir={}, redirectBaseUrls={}, logger=fakeLogger(), max_files_count=-1, debug=False): """ staticBaseDirs: a dictionary of prefixes and corresponding directories for serving static content redirectBaseUrls: just like staticBaseDirs, but redirect to this BaseUrls instead of surving them if a prefix is specified in both, redirectBaseUrls will be used. logger is logging object from python logging module max_files_count is the max number of upload file fields with dupplicated names (-1 unlimited, 1 unique keys) """ self._logger=logger # TODO: add a self._templateFilesCache self._theme=theme self._theme_lookup=theme_lookup themesDir=get_theme_dirs(theme_lookup, theme) if not hasattr(themesDir, '__iter__'): themesDir=[themesDir] self._themesDir=list(map(os.path.abspath, themesDir)) self._templatesDir=[s+'/templates/' for s in themesDir] # TODO: add a self._staticFilesCache self._staticBaseDir={} self._themePrefix=themePrefix self._max_files_count=max_files_count self._debug=debug # FIXME: no longer needed for k in staticBaseDir: v=staticBaseDir[k] if not os.path.isdir(v): self._logger.warning("WARNING: directory [%s] not found, skipping" % v) continue self._staticBaseDir[self._tailingSlash(k)]=self._tailingOsSlash(fromFs(os.path.abspath(toFs(v)))) self._redirectBaseUrls={} for k in redirectBaseUrls: self._redirectBaseUrls[self._tailingSlash(k)]=self._tailingSlash(redirectBaseUrls[k]) self._staticBaseDirKeys=list(self._staticBaseDir.keys()) self._staticBaseDirKeys.sort() self._staticBaseDirKeys.reverse() # so it's from longer to shorter self._redirectBaseUrlsKeys=list(self._redirectBaseUrls.keys()) self._redirectBaseUrlsKeys.sort() self._redirectBaseUrlsKeys.reverse() def _getTemplateFile(self, fn, default="root.html"): if fn==None: fn=default if hasattr(self._templatesDir, '__iter__'): for i in self._templatesDir: tfn=os.path.join(i, fn) if os.path.isfile(tfn): return tfn else: return os.path.join(self._templatesDir, fn) raise fileNotFoundException() def _tailingOsSlash(self, s): if not s.endswith(os.sep): return s+os.sep return s def _tailingSlash(self, s): if not s.endswith('/'): return s+'/' return s def _handleException(self, rq, e): s='_'+str(e.code) if hasattr(self, s): return getattr(self, s)(rq, e) return self._genericException(rq, e) def _genericException(self, rq, e): rs=webAppResponses.get(e.code,"%d Unknown code" % e.code) if rq.uri: s="exception [%s] happened when visiting [%s]" % (rs,rq.uri) else: s="exception [%s] happened" % rs rq.start_response(rs, [('content-type', 'text/plain')]) return [s] def _302(self, rq, e): rs=webAppResponses[302] cookies=rq.response.cookies.output(header="") if cookies: h=[('Set-Cookie',c) for c in cookies.split('\n')] else: h=[] rq.start_response(rs, [ ('content-type', 'text/plain'), ('Location', e.kw['location'])]+h) return ("Redirect to "+ e.kw['location'],) # you may customize exceptions like this # @expose(response=404,contentType='text/plain; charset=utf-8') # def _404(self, rq, e): # if not rq.uri: return ('File was not found',) # return ('File [%s] was not found' % rq.uri,) def __serveTheme(self, rq): """ internal method to serve themed static files like png, css,js ...etc. """ fn=rq.uri[len(self._themePrefix):] if os.sep!='/': fn=fn.replace('/', os.sep) for i in self._themesDir: ffn=os.path.join(i, 'static', fn) if not os.path.abspath(ffn).startswith(i): return self._handleException(rq, forbiddenException()) if os.path.exists(ffn): return self.__serveStatic(rq, ffn) return self._handleException(rq, notModifiedException() ) def __serveStatic(self, rq, fn): """ internal method to serve static files like png, css,js ...etc. """ if not os.path.exists(fn): raise fileNotFoundException() try: t=os.stat(fn).st_mtime except IOError: raise fileNotFoundException() try: f=open(fn,'rb') except IOError: raise fileNotFoundException() ts=time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(t)) et='"'+safeHash("", ts)+'"' if rq.environ.get('If-None-Match','')==et or \ rq.environ.get('If-Modified-Since','')==ts: raise notModifiedException() ext=fn[fn.rfind('.'):][1:].lower() rq.start_response("200 OK", [('content-type', self._mimeByExtension.get(ext,"application/octet-stream")), ('Last-Modified', ts), ('ETag', et) ]) # NOTE: since the file object is iteratable then no need for returning [r.read()] return f def __call__(self, environ, start_response): rq=Request(self, environ, start_response) if rq.uri==None: # handle malformed uri return self._handleException(rq, webAppBaseException(500)) self._logger.info('got request for uri=[%s] from ip=[%s]' % (rq.uri,rq.environ.get('REMOTE_ADDR','unkown'))) self._logger.debug('got env=[%s]' % rq.environ) rq.q._ok_max_files_count=self._max_files_count if rq.uri.startswith(self._themePrefix): try: return self.__serveTheme(rq) except webAppBaseException as e: return self._handleException(rq, e) # check if we need to serve static content for k in self._staticBaseDirKeys: if rq.uri.startswith(k): # SECURITY CHECK: that filename is really in side base filename ie. no ".." trick # NOTE: no need for this check as it seems to be done by paste bfn=self._staticBaseDir[k] if os.sep!='/': fn=bfn+rq.uri[len(k):].replace('/',os.sep) else: fn=bfn+rq.uri[len(k):] if not os.path.abspath(fn).startswith(bfn): return self._handleException(rq, forbiddenException()) try: return self.__serveStatic(rq, fn) except webAppBaseException as e: return self._handleException(rq, e) # check if we need to serve redirect for k in self._redirectBaseUrlsKeys: if rq.uri.startswith(k): u=self._redirectBaseUrls[k]+rq.uri[len(k):] # FIXME: should we escape Location in start_response start_response("302 Temporary Redirect", [('Location',u),('content-type', 'text/html')]) return [('moved' % escape(u))] # pass control to the right method f=None if rq.uriList and not rq.uriList[0].startswith('_') and hasattr(self, rq.uriList[0]): f=getattr(self, rq.uriList[0]) # make sure "f" is callable not a property if not hasattr(f,"__call__"): f=None else: a=rq.uriList[1:] if not f: f=self._root a=rq.uriList try: r=f(rq, *a) except (KeyboardInterrupt, SystemExit, MemoryError): raise except webAppBaseException as e: return self._handleException(rq, e) #TODO: treat any other exception as 500 return r @expose() def _root(self, rq, *args): """ called when no suitable method is found and it will be called for / too """ return '''You requested [%s]'''% '/'.join(args) if __name__ == '__main__': # this requires python-paste package from paste import httpserver app=baseWebApp( '/path/to/templates/files/', staticBaseDir={'/_files/':'/path/to/static/files/'} ); # for options see http://pythonpaste.org/modules/httpserver.html httpserver.serve(app, host='127.0.0.1', port='8080') okasha-0.3.0/okasha/bottleTemplate.py000066400000000000000000000027551412405540000175710ustar00rootroot00000000000000# -*- coding: UTF-8 -*- """ Okasha - a very simple WSGI webframe work Copyright © 2009, Muayyad Alsadi Released under terms of Waqf Public License. This program is free software; you can redistribute it and/or modify it under the terms of the latest version Waqf Public License as published by Ojuba.org. 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. The Latest version of the license can be found on "http://waqf.ojuba.org/license" this is integrates bottle's SimpleTemplate into okasha for details and sytax visit http://bottle.paws.de/docs/dev/stpl.html """ import sys, os, os.path from .baseWebApp import fileNotFoundException from .bottleTemplateSegment import SimpleTemplate, TemplateError class bottleTemplate(object): def __init__(self, *a, **kw): self._tmp=None def _load(self, rq, bfn=None, **kw): if hasattr(rq.webapp._templatesDir, '__iter__'): d=rq.webapp._templatesDir else: d=[rq.webapp._templatesDir] if not bfn: bfn='root.tpl' try: self._tmp=SimpleTemplate(name=bfn, lookup=d) except: rq.webapp._logger.debug('template error fn=[%s]' % bfn) raise # FIXME: check for valid template def __call__(self, rq, o, *a, **kw): if not self._tmp: self._load(rq, *a, **kw) d=kw.copy() d.update(o) d['_r']=rq.response return self._tmp.render(**d) okasha-0.3.0/okasha/bottleTemplateSegment.py000066400000000000000000000300151412405540000211020ustar00rootroot00000000000000""" this is a segment from bottle Homepage and documentation: http://bottle.paws.de/ Licence (MIT) ------------- Copyright (c) 2009, Marcel Hellkamp. 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. """ import sys, os, os.path, tokenize, functools, re from html import escape from .baseWebApp import webAppBaseException ######################### class TemplateError(webAppBaseException): def __init__(self, message): webAppBaseException.__init__(self, 500, message) ######################### # taken from bottle at 5-Jul-2010 # http://github.com/defnull/bottle/tree/81bf74c36c4652958914d26ea91ec345e381572c ######################### if sys.version_info >= (3,0,0): # pragma: no cover # See Request.POST from io import BytesIO from io import TextIOWrapper class NCTextIOWrapper(TextIOWrapper): ''' Garbage collecting an io.TextIOWrapper(buffer) instance closes the wrapped buffer. This subclass keeps it open. ''' def close(self): pass StringType = bytes def touni(x, enc='utf8'): # Convert anything to unicode (py3) return str(x, encoding=enc) if isinstance(x, bytes) else str(x) else: from io import StringIO as BytesIO from types import StringType NCTextIOWrapper = None def touni(x, enc='utf8'): # Convert anything to unicode (py2) return x if isinstance(x, str) else str(str(x), encoding=enc) def tob(data, enc='utf8'): # Convert strings to bytes (py2 and py3) return data.encode(enc) if isinstance(data, str) else data class BaseTemplate(object): """ Base class and minimal API for template adapters """ extentions = ['tpl','html','thtml','stpl'] settings = {} #used in prepare() defaults = {} #used in render() def __init__(self, source=None, name=None, lookup=[], encoding='utf8', **settings): """ Create a new template. If the source parameter (str or buffer) is missing, the name argument is used to guess a template filename. Subclasses can assume that self.source and/or self.filename are set. Both are strings. The lookup, encoding and settings parameters are stored as instance variables. The lookup parameter stores a list containing directory paths. The encoding parameter should be used to decode byte strings or files. The settings parameter contains a dict for engine-specific settings. """ self.name = name self.source = source.read() if hasattr(source, 'read') else source self.filename = source.filename if hasattr(source, 'filename') else None self.lookup = list(map(os.path.abspath, lookup)) self.encoding = encoding self.settings = self.settings.copy() # Copy from class variable self.settings.update(settings) # Apply if not self.source and self.name: self.filename = self.search(self.name, self.lookup) if not self.filename: raise TemplateError('Template %s not found.' % repr(name)) if not self.source and not self.filename: raise TemplateError('No template specified.') self.prepare(**self.settings) @classmethod def search(cls, name, lookup=[]): """ Search name in all directiries specified in lookup. First without, then with common extentions. Return first hit. """ if os.path.isfile(name): return name for spath in lookup: fname = os.path.join(spath, name) if os.path.isfile(fname): return fname for ext in cls.extentions: if os.path.isfile('%s.%s' % (fname, ext)): return '%s.%s' % (fname, ext) @classmethod def global_config(cls, key, *args): ''' This reads or sets the global settings stored in class.settings. ''' if args: cls.settings[key] = args[0] else: return cls.settings[key] def prepare(self, **options): """ Run preparatios (parsing, caching, ...). It should be possible to call this again to refresh a template or to update settings. """ raise NotImplementedError def render(self, **args): """ Render the template with the specified local variables and return a single byte or unicode string. If it is a byte string, the encoding must match self.encoding. This method must be thread save! """ raise NotImplementedError class SimpleTemplate(BaseTemplate): blocks = ('if','elif','else','try','except','finally','for','while','with','def','class') dedent_blocks = ('elif', 'else', 'except', 'finally') def prepare(self, escape_func=escape, noescape=False): self.cache = {} if self.source: self.code = self.translate(self.source) self.co = compile(self.code, '', 'exec') else: self.code = self.translate(open(self.filename).read()) self.co = compile(self.code, self.filename, 'exec') enc = self.encoding self._str = lambda x: touni(x, enc) self._escape = lambda x: escape_func(touni(x, enc)) if noescape: self._str, self._escape = self._escape, self._str def translate(self, template): stack = [] # Current Code indentation lineno = 0 # Current line of code ptrbuffer = [] # Buffer for printable strings and token tuple instances codebuffer = [] # Buffer for generated python code touni = functools.partial(str, encoding=self.encoding) multiline = dedent = False def yield_tokens(line): for i, part in enumerate(re.split(r'\{\{(.*?)\}\}', line)): if i % 2: if part.startswith('!'): yield 'RAW', part[1:] else: yield 'CMD', part else: yield 'TXT', part def split_comment(codeline): """ Removes comments from a line of code. """ line = codeline.splitlines()[0] try: tokens = list(tokenize.generate_tokens(iter(line).__next__)) except tokenize.TokenError: return line.rsplit('#',1) if '#' in line else (line, '') for token in tokens: if token[0] == tokenize.COMMENT: start, end = token[2][1], token[3][1] return codeline[:start] + codeline[end:], codeline[start:end] return line, '' def flush(): # Flush the ptrbuffer if not ptrbuffer: return cline = '' for line in ptrbuffer: for token, value in line: if token == 'TXT': cline += repr(value) elif token == 'RAW': cline += '_str(%s)' % value elif token == 'CMD': cline += '_escape(%s)' % value cline += ', ' cline = cline[:-2] + '\\\n' cline = cline[:-2] if cline[:-1].endswith('\\\\\\\\\\n'): cline = cline[:-7] + cline[-1] # 'nobr\\\\\n' --> 'nobr' cline = '_printlist([' + cline + '])' del ptrbuffer[:] # Do this before calling code() again code(cline) def code(stmt): for line in stmt.splitlines(): codebuffer.append(' ' * len(stack) + line.strip()) for line in template.splitlines(True): lineno += 1 line = line if isinstance(line, str)\ else str(line, encoding=self.encoding) if lineno <= 2: m = re.search(r"%.*coding[:=]\s*([-\w\.]+)", line) if m: self.encoding = m.group(1) if m: line = line.replace('coding','coding (removed)') if line.strip()[:2].count('%') == 1: line = line.split('%',1)[1].lstrip() # Full line following the % cline = split_comment(line)[0].strip() cmd = re.split(r'[^a-zA-Z0-9_]', cline)[0] flush() ##encodig (TODO: why?) if cmd in self.blocks or multiline: cmd = multiline or cmd dedent = cmd in self.dedent_blocks # "else:" if dedent and not oneline and not multiline: cmd = stack.pop() code(line) oneline = not cline.endswith(':') # "if 1: pass" multiline = cmd if cline.endswith('\\') else False if not oneline and not multiline: stack.append(cmd) elif cmd == 'end' and stack: code('#end(%s) %s' % (stack.pop(), line.strip()[3:])) elif cmd == 'include': p = cline.split(None, 2)[1:] if len(p) == 2: code("_=_include(%s, _stdout, %s)" % (repr(p[0]), p[1])) elif p: code("_=_include(%s, _stdout)" % repr(p[0])) else: # Empty %include -> reverse of %rebase code("_printlist(_base)") elif cmd == 'rebase': p = cline.split(None, 2)[1:] if len(p) == 2: code("globals()['_rebase']=(%s, dict(%s))" % (repr(p[0]), p[1])) elif p: code("globals()['_rebase']=(%s, {})" % repr(p[0])) else: code(line) else: # Line starting with text (not '%') or '%%' (escaped) if line.strip().startswith('%%'): line = line.replace('%%', '%', 1) ptrbuffer.append(yield_tokens(line)) flush() return '\n'.join(codebuffer) + '\n' def subtemplate(self, _name, _stdout, **args): # NOTE: the following line added for okasha if '_r' not in args: args['_r']=None if _name not in self.cache: self.cache[_name] = self.__class__(name=_name, lookup=self.lookup) return self.cache[_name].execute(_stdout, **args) def execute(self, _stdout, **args): # NOTE: the following 4 lines added for okasha if '_r' not in args: args['_r']=None def _subtemplate(*a, **kw): if '_r' not in kw: kw['_r']=args['_r'] return self.subtemplate(*a, **kw) env = self.defaults.copy() env.update({'_stdout': _stdout, '_printlist': _stdout.extend, '_include': _subtemplate, '_str': self._str, # NOTE: _subtemplate added for okasha '_escape': self._escape}) env.update(args) eval(self.co, env) if '_rebase' in env: subtpl, rargs = env['_rebase'] rargs['_r']=args['_r'] # NOTE: added for okasha subtpl = self.__class__(name=subtpl, lookup=self.lookup) rargs['_base'] = _stdout[:] #copy stdout del _stdout[:] # clear stdout return subtpl.execute(_stdout, **rargs) return env def render(self, **args): """ Render the template using keyword arguments as local variables. """ stdout = [] self.execute(stdout, **args) return ''.join(stdout) okasha-0.3.0/okasha/utils.py000066400000000000000000000207241412405540000157400ustar00rootroot00000000000000# -*- coding: UTF-8 -*- """ Copyright © 2009, Muayyad Alsadi Released under terms of Waqf Public License. This program is free software; you can redistribute it and/or modify it under the terms of the latest version Waqf Public License as published by Ojuba.org. 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. The Latest version of the license can be found on "http://waqf.ojuba.org/license" """ import sys, time, hashlib, random import bisect from itertools import groupby import re fs_encoding=sys.getfilesystemencoding().startswith('ANSI') and 'UTF-8' or sys.getfilesystemencoding() dD_re=re.compile(r'(\d+|\D+)') def stringOrFloat(s): try: return float(s) except ValueError: return s def stringOrInt(s): try: return int(s) except ValueError: return s def strverscmp(a,b): "something like GNU strverscmp" return cmp([stringOrInt(i) for i in dD_re.findall(a)], [stringOrInt(i) for i in dD_re.findall(b)]) def strverscmp_old(a,b): "something like GNU strverscmp" return cmp([stringOrFloat(i) for i in dD_re.findall(a)], [stringOrFloat(i) for i in dD_re.findall(b)]) def fromFs(filenameblob): """ recives a blob encoded in filesystem encoding and convert it into a unicode object """ if type(filenameblob)!=str: return filenameblob.decode(fs_encoding) return filenameblob def toFs(filename): """ recives a unicode object and encode it into filesystem encoding """ if type(filename)==str: return filename.encode(fs_encoding) return filename def randomblob(m,M): return ''.join([chr(random.randrange(0,255)) for i in range(random.randrange(m,M))]) def safeHash(stringSeed, o): """ a URL safe hash, it results a 22 byte long string hash based on md5sum """ if isinstance(o,str): o=o.encode('utf8') return hashlib.md5(stringSeed+o).digest().encode('base64').replace('+','-').replace('/','_')[:22] # TODO: is this needed by anything ? def unixUniq(l): """ Unix-like uniq, the iteratable argument should be sorted first to get unique elements. """ return [j[0] for j in groupby(l,lambda i: i)] def unixUniqAndCount(l): """ Unix-like uniq -c, it returns an iteratable of tuples (count, uniq_entry) """ return [(len(list(j[1])),j[0]) for j in groupby(l,lambda i: i)] class ObjectsCacheObject: def __init__(self, objId, obj): self.objId=objId self.obj=obj self.atime=self.ctime=time.time() self.freq=1 # how many time it was accessed self.i=0 # shifted index def __cmp__(self, b): # passing cmp as an argument is twise as faster as overloading cmp if isinstance(b,ObjectsCacheObject): return cmp(self.atime,b.atime) if b<=0: return cmp(self.i,-b) return cmp(self.atime,b) def cmp_bisect_right(ccmp, a, x, lo=0, hi=None): """ same as bisect.bisect but uses custom cmp function """ if lo < 0: raise ValueError('lo must be non-negative') if hi is None: hi = len(a) while lo < hi: mid = (lo+hi)>>1 if ccmp(a[mid],x)>0: hi = mid # ie. if x < a[mid] else: lo = mid+1 return lo def cmp_bisect_left(ccmp, a, x, lo=0, hi=None): """ same as bisect.bisect_left but uses custom cmp function """ if lo < 0: raise ValueError('lo must be non-negative') if hi is None: hi = len(a) while lo < hi: mid = (lo+hi)>>1 if ccmp(x, a[mid])>0: lo = mid+1 # ie. if a[mid] < x else: hi = mid return lo class fakeLock: def acquire(self, blocking=True): pass def release(self): pass class ObjectsCache: _feasible_bisect_limit=4 def __init__(self, lock=None, minCount=10, maxCount=100, maxTime=3600): """ minCount is the minimum number of cached objects below which no cached object will be freed, use 0 to set no lower limit maxCount is the maximum number of cached objects above which no cached object will be kept, use 0 to set no upper limit maxTime is positive time to live in seconds, all objects older than this will be removed when free is called, use 0 to discard time checking example: setting minCount and maxTime to 0 will keep all cached objects no matter how many or for how long setting maxCount to 0 will disable caching (all objects will be freed when free is called) """ if not lock: self._lock=fakeLock() else: self._lock=lock self.maxTime=maxTime self.maxCount=maxCount self.minCount=minCount self._hash={} # a mapping between ids and shifted array index self._shift=0 # the current shift in array index self._shifts=0 # number of tailing shifts done self.objs=[] # objects list from older to most recent # when freeing old objects we don't need to update the mapping between ids and array index, we only adjust the shift def _get(self, objId): i=self._hash.get(objId,None) if i==None: return None si=min(i+self._shift,len(self.objs)-1) # NOTE: withou tailing shifts it would be o=self.objs[si] # because of Tailing Shifts we need to search between objs[si-shifts:si] # in case of shifts==0 then the object is at si # if shifts>0 then the worst case is that our very object was the target of all past tailing shifts, ie. it's on objs[si-shifts] # NOTE: worst case happens when one keep accessing the least expected object and this can only happen if the user access all objects in a uniform way cb=si-self._shifts # candidates lower bound if cb<0: cb=0 if si-cb=cb but it's guaranteed to work without it o=self.objs[sh] if o.i==i: break sh-=1 else: sh=cb+cmp_bisect_left(lambda a,b: cmp(a,b.i), self.objs[cb:si+1],i) o=self.objs[sh] o.atime=time.time() o.freq+=1 # Tailing shifts should be done if o is not the last one # change position from: oldest,older,*accessed*,old, recent # to be something like: oldest,older,old, recent, *accessed* # this will case the shifted index returned from hash of old and recent to be greater than its real value if shself._feasible_bisect_limit and (self._shifts>>1)>len(self.objs): self._reconstruct() # TODO: also if the oldest element is older than some limit an expensive reconstruction based on frequency maybe feasible l=len(self.objs) if self.minCount>0 and l<=self.minCount: return 0 k=l-self.minCount # max number of objs to remove j=max(l-self.maxCount,0) # number of objs to remove if self.maxTime>0: c=time.time()-self.maxTime # time older than which should be removed i=cmp_bisect_right(lambda a,b: cmp(a.atime,b),self.objs,c) # number of objs to remove by time i=max(i,j) else: i=j if self.minCount>0: i=min(j,k) # can be done by deleting hash elements which has values < -newshift for o in self.objs[:i]: del self._hash[o.objId] del self.objs[:i] self._shift-=i return i def _reconstruct(self): """ reconstruct objects so that no shifting is used, this expensive operation O(n) might speed things up for next retrievals """ for i,o in enumerate(self.objs): o.i=i; self._hash[o.objId]=i self._shift=0; self._shifts=0 okasha-0.3.0/okasha/xsltTemplate.py000066400000000000000000000027261412405540000172700ustar00rootroot00000000000000# -*- coding: UTF-8 -*- """ Okasha - a very simple WSGI webframe work Copyright © 2009, Muayyad Alsadi Released under terms of Waqf Public License. This program is free software; you can redistribute it and/or modify it under the terms of the latest version Waqf Public License as published by Ojuba.org. 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. The Latest version of the license can be found on "http://waqf.ojuba.org/license" """ import sys, os, os.path, threading from lxml import etree from .utils import ObjectsCache # kid has its own cache from .baseWebApp import fileNotFoundException xsltCache=ObjectsCache(lock=threading.Lock()) def xsltTemplate(rq, o, bfn=None, **kw): """ """ fn=rq.webapp._getTemplateFile(bfn, default="root.xsl") # prepare xsl trans trans=xsltCache.get(fn) if not trans: try: xslt_doc=etree.parse(fn) except IOError: raise fileNotFoundException() except: # FIXME: check for valid template # lxml.etree.XMLSyntaxError: rq.webapp._logger.debug('template error fn=[%s]' % fn) raise trans = etree.XSLT(xslt_doc) xsltCache.append(fn, trans) # prepare object if isinstance(o,str): doc=etree.fromstring(o) else: doc=o r = trans(doc, **kw) return etree.tostring(r, encoding='UTF-8' , pretty_print=True) okasha-0.3.0/python-okasha.spec000066400000000000000000000051721412405540000164210ustar00rootroot00000000000000%global owner ojuba-org %global commit #Write commit number here %global sname okasha Name: python-okasha Summary: WSGI web framework for python URL: http://ojuba.org Version: 0.3.0 Release: 1%{?dist} Source0: https://github.com/%{owner}/%{sname}/archive/%{commit}/%{sname}-%{commit}.tar.gz License: WAQFv2 Group: System Environment/Base BuildArch: noarch BuildRequires: python3-devel %description Almost do-nothing web framewrok that features: * WSGI-enabled ie. can be used with mod_wsgi, mod_python, fast cgi, cgi, with paste or even without even a server * light weight * can be tuned to be suitable for desktop apps or public web servers * no extra dependencies * very simple %package xslt Summary: xslt templates and support for okasha framework Group: System Environment/Base Requires: %{name} Requires: python-lxml %description xslt Adds support for xslt-based templates using python's lxml package %package docs Summary: documentation for okasha the trivial WSGI web framework for python Group: System Environment/Base Requires: python-okasha-xslt Requires: python-paste %description docs documentation for okasha and a sample web application that uses okasha %prep %setup -q -n %{sname}-%{commit} %build pushd docs bash ./update-from-site.sh popd %install %{__python3} setup.py install \ --root=$RPM_BUILD_ROOT \ --optimize=2 mkdir -p $RPM_BUILD_ROOT/%{_datadir}/doc/%{name}-docs/ cp -a test.py test.wsgi demo-themes $RPM_BUILD_ROOT/%{_datadir}/doc/%{name}-docs/ rm docs/update-from-site.sh cp -a docs/* $RPM_BUILD_ROOT/%{_datadir}/doc/%{name}-docs/ %files %defattr(-,root,root,-) %doc waqf2-ar.pdf README README.ar.txt TODO %{python3_sitelib}/%{sname}/__init__.py* %{python3_sitelib}/%{sname}/baseWebApp.py* %{python3_sitelib}/%{sname}/bottleTemplate.py* %{python3_sitelib}/%{sname}/bottleTemplateSegment.py* %{python3_sitelib}/%{sname}/utils.py* %{python3_sitelib}/*.egg-info %{python3_sitelib}/%{sname}/__pycache__/*.py* %files xslt %{python3_sitelib}/%{sname}/xsltTemplate.* %files docs %{_datadir}/doc/%{name}-docs/ %changelog * Sun Sep 26 2021 Ehab El-Gedawy - 0.3.0-1 - Port to python 3. * Sat Feb 15 2014 Mosaab Alzoubi - 0.2.4-3 - General Fixes. * Sat Feb 15 2014 Mosaab Alzoubi - 0.2.4-2 - Full Revision. * Sun Jul 11 2010 Muayyad Saleh AlSadi - 0.2.0-2 - add bottle tamplates support - add documentation * Sat Jun 12 2010 Muayyad Saleh AlSadi - 0.1.0-2 - let python-okasha-xslt and python-okasha-kid depend on python-okasha * Sat Jun 12 2010 Muayyad Saleh AlSadi - 0.1.0-1 - initial packing okasha-0.3.0/setup.py000066400000000000000000000007131412405540000144660ustar00rootroot00000000000000#! /usr/bin/python3 from distutils.core import setup from glob import * import os, sys # to install type: # python setup.py install --root=/ # do the install setup (name='okasha', version='0.1.0', description='trivial WSGI web framework for python', author='Muayyad Saleh Alsadi', author_email='alsadi@ojuba.org', url='http://git.ojuba.org/cgit/okasha/about/', license='Waqf', packages=['okasha'], data_files=[] ) okasha-0.3.0/test.py000077500000000000000000000234401412405540000143120ustar00rootroot00000000000000#! /usr/bin/python3 # -*- coding: UTF-8 -*- """ Okasha - a very simple WSGI webframe work Copyright © 2009, Muayyad Alsadi Released under terms of Waqf Public License. This program is free software; you can redistribute it and/or modify it under the terms of the latest version Waqf Public License as published by Ojuba.org. 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. The Latest version of the license can be found on "http://waqf.ojuba.org/license" """ from okasha.baseWebApp import * from okasha.xsltTemplate import xsltTemplate from okasha.bottleTemplate import bottleTemplate from glob import glob class webApp(baseWebApp): def __init__(self, mode,*args, **kw): """ mode is just an argument to show how to recive arguments """ self.mode=mode baseWebApp.__init__(self,*args, **kw) @expose() def verbatim(self, rq, *args): """ this is an example of sending a verbatim html code as-is to test it visit http://localhost:8080/verbatim/some/args/?id=5 """ return """

welcome to verbatim html from python

You requested [%s]
You query is [%s]
""" % (rq.script, escape('/'.join(args)), escape(rq.q.__repr__())) @expose(contentType="text/plain; charset=utf-8") def text(self, rq, *args): """ this is an example of sending a verbatim plain text as-is to test it visit http://localhost:8080/text/some/args/?id=5 """ return """welcome to verbatim plain text from python, this is not bold You requested [%s] You query is [%s] """ % ('/'.join(args), rq.q.__repr__()) @expose() def selective(self, rq, *args): """ this is an example of setting content type on the fly to test it visit http://localhost:8080/selective/?type=h http://localhost:8080/selective/?type=t """ if rq.q.getfirst('type','')=='t': rq.response.contentType="text/plain; charset=utf-8" return """welcome to selective plain or html text from python, is this bold You requested [%s] You query is [%s] """ % (escape('/'.join(args)), escape(rq.q.__repr__())) @expose() def _root(self, rq, *args): """ this is called when / or when no other suitable method is found you could just redirect to /index for example or raise fileNotFoundException() """ return """

welcome to Okasha

classic logo
logo from custom theme
file only found in base theme
You requested [%(u)s] which is not handled by any method
You query is [%(q)s]

try out the following

""" % {'script':rq.script,'u':escape('/'.join(args)), 'q':escape(rq.q.__repr__())} @expose(percentTemplate,["tmp.html"]) def tmp(self, rq, *args): """ this is how you can use simple % formatting templates, just return a dictionary, and it will be applied to the named template. to test it visit http://localhost:8080/tmp/some/args/?id=5 http://localhost:8080/tmp/err/raised/?id=5 """ if args and args[0]=='err': raise forbiddenException() return { 'title':'Okasha simple percent templates', 'key1':'val1','key2':'val2','args':'/'.join(args) } @expose(formatTemplate,["format.html"]) def format(self, rq, *args): """ this is how you can use simple formatting templates you may return a list and use {0}, {1} ...etc. you may return a dict and use {key1}, {key2} you may also use {key1[0]} if the value is a list or {key1.subkey} ... http://localhost:8080/format/some/args/?id=5 """ return { 'title':'Okasha simple format templates', 'key1':'val1','key2':'val2','args':'/'.join(args) } @expose(bottleTemplate,["bottle-test.tpl"]) def bottletmp(self, rq, *args): """ this is how you can use simple % formatting templates, just return a dictionary, and it will be applied to the named template. to test it visit http://localhost:8080/bottletmp/ http://localhost:8080/bottletmp/red/yellow/green/ """ return { 'title':'Okasha simple bottle templates', 'colors':args } @expose(xsltTemplate,["test.xsl"], contentType="text/xml; charset=utf-8") def xslt(self, rq, *args): """ http://localhost:8080/xslt/some/args/?id=5 """ return '''Text''' @expose(xsltTemplate,["docbook.xsl"]) def docbook(self, rq, *args): """ http://localhost:8080/docbook/some/args/?id=5 """ return '''\
عنوان الفصل الأول هذه هي الفقرة الأولى هذا عنوان مهم هذه فقرة من النص المهم هذه هي الفقرة الثانية
عنوان الفصل الثاني هذه هي الفقرة الأولى هذه هي الفقرة الثانية
عنوان فصل فرعي هذه الفقرة هي جزء من فصل فرعي داخل الفصل الثاني لمزيد من التفاصيل انظر
''' @expose(percentTemplate,["cookies.html"]) def cookies(self, rq, *args): """ http://localhost:8080/cookies/ """ if 'color' in rq.q: c=rq.q.getfirst('color','') rq.response.setCookie('color',c, 60*5) # expires in 5 minutes return {'color':c} if 'color' in rq.cookies: return {'color':rq.cookies['color'].value.decode('utf8')} return {'color':''} @expose(percentTemplate,["upload.html"]) def upload(self, rq, *args): """ http://localhost:8080/upload/ """ color=rq.q.getfirst('color','') b=rq.q.getfirst('b','') if 'file1' in rq.q: f=rq.q.getfirst('file1','') # get it as string rq.q.save_in('file1','/tmp/') else: f="" return {'color':color,'f':f,'b':b,'script':rq.script} def moved(self, rq, *args): """ this is an example of using redirects to test it visit http://localhost:8080/moved/ """ raise redirectException(rq.script+'/main/') @expose(percentTemplate,["main.html"]) def main(self, rq, *args): """ this is an example of using ajax/json also notice that we can access to class properties to test it visit http://localhost:8080/main/ """ return { 'title':'Okasha: sample web application', 'script':rq.script, 'mode':self.mode, 'version':'0.1.0' } @expose(jsonDumps) def ajaxGet(self, rq, *args): """ this is an example of using ajax/json to test it visit http://localhost:8080/ajaxGet" """ import time, random return {'time':time.time(),'rnd':random.randrange(1,7)} @expose(jsonDumps) def ajaxToUpper(self, rq, *args): """ this is an example of using ajax/json to test it visit http://localhost:8080/ajaxToUpper?text="LowerCaseMe" """ t=rq.q.getfirst('text','') return t.upper() @expose(jsonDumps) def ajaxSplit(self, rq, *args): """ this is an example of using ajax/json to test it visit http://localhost:8080/ajaxSplit?text=12-345-678&by=- """ t=rq.q.getfirst('text','') d=rq.q.getfirst('by','') return t.split(d) # you may customize exceptions like this # @expose(response=404,contentType='text/plain; charset=utf-8') # def _404(self, rq, e): # if rq.uri==None: return ('File is not found',) # return ('File [%s] is not found' % rq.uri,) if __name__ == '__main__': # this requires python-paste package import logging from paste import httpserver import sys, os, os.path myLogger=logging.getLogger('MyTestWebApp') h=logging.StreamHandler() # in production use WatchedFileHandler or RotatingFileHandler h.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")) myLogger.addHandler(h) myLogger.setLevel(logging.DEBUG) # in production use logging.INFO d=os.path.abspath(os.path.dirname(sys.argv[0])) lookup=[os.path.join(d,'demo-themes')] app=webApp( 'SafeMode', lookup, 'fancy', '/_theme/', staticBaseDir={'/_files/':os.path.join(d,'demo-themes/default/static/')}, logger=myLogger ); # for options see http://pythonpaste.org/modules/httpserver.html httpserver.serve(app, host='127.0.0.1', port='8080') okasha-0.3.0/test.wsgi000066400000000000000000000003351412405540000146260ustar00rootroot00000000000000# -*- coding: utf-8 -*- import sys, os, os.path from test import webApp d='/path/to/sample/prefix' application=webApp( 'SafeMode', os.path.join(d,'templates'), staticBaseDir={'/_files/':os.path.join(d,'files')} ); okasha-0.3.0/testsuit/000077500000000000000000000000001412405540000146375ustar00rootroot00000000000000okasha-0.3.0/testsuit/cachetest.py000066400000000000000000000000031412405540000171450ustar00rootroot00000000000000Nonokasha-0.3.0/waqf2-ar.pdf000066400000000000000000002072041412405540000150730ustar00rootroot00000000000000%PDF-1.4 %äüöß 2 0 obj <> stream x\K,rޟ_QkC-%$pw/5ww<$B1=C> 'i?~?=Ο1Go~hϟc~F81׬#>ͬ~UPFŧUMs?O_yԳVO5ݬ0eV;??Ͽ!>Wgc# 7[.("y rt i@--}znC''!YȾxQ%9n43dg9ܥ+?]7_O[e.[./$*3=mRY`D .7S8Rg 4/ l(̒"0Z!UO\m ʯ:X4`3$ͦ͡yU , .Ovnlx:p(HLpI6<@-Qc]q 3N4n{J>MQpg>6kws?Mj;Mq6aL&Q% ,3o6fqYpRXl9d?s?t'{s. n"r" -s'Ȕ)٭xr3i6(Gaǝiߤ a>dW=Gc&.V ٧s+^χ?ƒtk ^Z/f7,R'ĂY^y z7 e=Jw_eAj/4̋x ]9R-I_@tkS`rpy2 xR`9V2#d0Jdf5no PFpN٠{,퀬>UຑP@i:a p&D9?9SbQ|Kfnw[|FUyF$'*$jaW6v- HPY@P!*4 l* YXC ME'H=1\w FGdqH]($ASJt8U&t..q}ɱNdX|eఒ>>T;:2)%zz"_8i ,lz]p nv}%B"$[5A43M .ֺiF^|˒)WYR;4r p3b@Dq ~Jypr'? ͨBa -/($DA ag;,ÖE#yӖ_MB)^V`Seo'e^`9V*ArPB _poW_v* 5ԑf344 MEC,*#l_/rUOʵ'j09gA}!b^2@ B5J_;C[)6U)d9ǵo[4L:VAoxy3x'mBL+\pE`zOɔ }lQuqg|!ZsmphXLP^3omӓD 'vWmrlfSSyZ`:p}RK6Bb T"Hy@t%Kom6BdZV4o}] `tMęT 0C  KpK@v;vEfnv2;.s (qȢHmGDR tB.)6~V%q~irxa@ϴIX*tLx0%5=n3,i*0 {Wx=~3ϕ,3h<L4J@G$Kt(3$GgI~=B]i$1 w;0^%MtlL$C}Eǚ KeQ q(?&l̙e0}WLs]{RUu e!!5㧯 ߺp4 9КP614ԤH`foZG@4"aBNO7oq3lvpMź"^;P ɥW@/!^LF(r{t;6!,( ʼn?ѦO>}Ulhсgޏ.)l@QDՊuBwJ k}|Ց(<)>!lGą)gZsZA҈~|.77wx V&6|%eJ)\3./XP(EX12ɰvafp2}wĜ>|o)Z\ӼMS" VlO *U:H'ao (Slgڝ3LSl)FѮXW.ڹ68Yw|V @_d 'i,tI1m&,dpBYr%]ߛi@׍! ͇і@:b1+ ʬ-`]/v~F 1auR,WuIj-MNy>A_kA,(j2WWh3( ؞Wy2XQI "-IiC'tɚ6,EG{8TSҠt]Ik^fV m& #SM\{,X҃&9"\TTG>tvMr+ѶM!6I%﵄x8`x5#n%g)v) n.%4yɖY Z2ns2)ycp? |]o0.໎Yߥ("fP q&)j5gx1-&mZGv|%W\h׶7Aṋj$.1jVrlfb4hfyE>P ( <^4sC#;*:`*P@nmoۭJ^PA,xcea,?">Κ捆ؐN-\5h@ eV+TnOn$"c& caYiF5T>bD FnfM`KC\WÝ{J/^gY9۸LZ쥺XɻIE_cR3lTcOڑO(H=/gP;(kx=<&jd &Y_[9S;PiS;M`tfq].oH[C̙sB%:#@ukOI' s!*/cfW+md2ch.)֮2ӑwֹo+hkz#sK)qVu6ئbԺ\$9[~^iAay˗#sYff!-@b܎DI2$ە*GO~(03uT~H۱i-XYvpMJ>}jΕ&lAg6IR.-'F}aL䙓joo)k}O|jsԆxMM'\;ӉKw[1tdȃvoʓB&ߚR!;ReӨ] K3BMГzfXJ7" foN8|;|۵5! L edP1:Dn_z9w:itC* j-n2%xf:diOIM<mxgzR%Z]!b#kѶ~#[}]X^}= DxmA<.+5ĵkM٨Q$'{ISݿ*255{嵑Bly12À&{c1|EzΥwÜ ཅD`ogA}\OU[˺ |0(4|R|<G!r]ERRşI;\/D鿾,ԍb{s?`قkDҒE7r,޳3r߅ZM7>5=u\2i(%]xӂ\t!$nk\.T9]z60 +`RJr*~Ptv,:gnAPJZ}`s[ϵߨf%߶0h0W>4#۟>=2ˠv2#tbu3L fךN%{XWb8#0אDt MMyXLCfLOERWm22n6B-ot04X{ٸ&~sLv QK n6q҃)]Dג ]Ii8 -/Ϯ|`dL{ʂfs\CK 5h[^i8C|wD)]K]@m'Y@g!yNpWzw]a+쾕 6bMܻhP8{< ]`U4]B w]h"E7{o<(>ɸ2Si6߽4פǚMu=C+6c$?D mǥ˚XX}Бآ ڮJΣ2BV@״{^NvǷ דSԘ15݋xe"jW2di@Pw$Կ4XK+j,fD\yDHLen6γB7"&[& V7r7aheHJgnn`??~?~R endstream endobj 3 0 obj 5695 endobj 4 0 obj <> /Length 8 /Filter/FlateDecode >> stream x endstream endobj 5 0 obj <> endobj 7 0 obj <> stream x\I9rOgCUk_ Iu|(66>O,B?5=R(E(է>I|攜L?ǿo?Ӟb?vOڜ~Yhc|سI}6y1gmQ/ 9?/?4OΥ\L*Nq&.&6a s͝>?zS9ßy.0eÖe0^}Iņ0[Mڶ@ɇ(#]-Vçƣr>8 mY`AOu,' ,:./#7X~<⊎-:l6e[G+IQ f}qe^Y Ŏ6vmo㽌>}؜$/{K!=HJ>) :P hh 0*Jۡ@ɱh+OEiG ?Ѵw=>w5]PGtvC/t (4 Q=6O*a"WXj`y< <1Oku1W~ q C׾!ѹ]HJ5qqU2ݾ:o-0ƀ}i`%vs|o`yE >|1q*b0HTH`Fk~k@.݄Afۗ2wuWSq!5t4a9g[)3t|JZǰ,[VG1qMaJڐWrFGO,.n<(@ȶ^ơ3I簔9٣< ro5E( U7^au~Asq@‹:l/K>0?Bѷi};2@)rFιt#N59=Q [*)n ` fꔤ}Urn)k=XVNb0 bco|?VXCAM! Xk?;|;QpX6G䧽T >R4y+J?Ӧě8UȀn}dNUc3HLnlum 4n$*ir&NŚRtެ;rfN;HNGFtK.ocB!bҷnPVCe*|9h7X Ohx+(3*٤fsK\`sT@;6Xx,掉@o@20u"".2|d B b_'z7L\ç)(=!/-@+Ƀ_/>f<c*(]15<6:DtKU*stkXǟʍP,el&cE鹼!GZ(lHq*;)ԚnDrع ӽz㦢HFZVEح0y@af.-ؿN}G>-D4!lϾKb̡0RNo}ECxMt7UվVۛ=!mӠFDPm\A^U3˼QaYo'v%}MN(,C7eHgF3ETQ=4E?XK sAH{)ƥ#rsf: jG<@K}4}Ł1,(v$;WeSZ-]F ⡁j5{k|1j Zc,L" ohI4M;tld٧ Ћ3jJC;*3PEa{&+NG^sd>7[ $A_SN (lQhh/E5/npmlvD'qd6TpM*;Fzq~ā$?gXt۵1- 9V߰HL%J+CC0OKqQ9A={yEom$9YfjKT00, 1`6(aWr:f2E]F6TTb@DΌ6P>[f9}S[(i1Ľ֤v/ :ZFHoLW-((I)T &3Yml\رDaJP jI=5&fb9rck5e^ DۼR;h9'@&L~޹Z [,wBT7·T+ۆW^Ɇ@rJy0hkjPmrKiZcN70_1?vIZm T]+%AlRpXyWlXب˘9]; wغ&yc}S;1WYKrnB[C"z_i (N!pF.L(~老E\}X.a"!dgvxOV1mPJOwDI`fqt1a{G'&ǁK+XR3L1TAhD֌:>p vT#Y xzB(<^nN1e upNKJA9t:B3q;ά|MvnK-9P S5{v0 XCqb8:w8:Kafn~"8LJއAp=놞S'DBO7vzfJ[$T{!4b#I:ԶDߠG Gh|l+5ЁZ,Bz|? (=~9od*;̮/^WF @#w߱9^mX*𺊶k9i C\facUb4S"{?)a5?G ܕaBtNK+[a GEȄ̞QLhaldzy(=*@&$YCS[Rq'?q87(\S5ax_C|YPjie6Kxw#cRK`H0Ƅ\v_6 =4:^(}f̩L?QגV~'_<Z]p{}SGd 2vڤ=3΅!`}w0o6 !hmOg}E3LTFu F|fҨ/_/ao~􆧏*JYrK{˰O$Ks_K2(ސžg 1p+yB;a9ŗ:y 5s`1ct}wq5EukGvS$P>^4̸ ?2w9n_##eA,ac}GdDJ8)dwtȷ^vx7'8@O ^Jn6]^UviJ!V_80Og3:t]0|s HEw0{.{3{ICA1!i>u9`u 24†6u=4Fʯ}i.ō]D4DLM͎}&\*:~L6vsJ44A l]p10V{2ƷeyX ݪғ҃VPffy_@,e/uoj3ua_M.K+`1Hc$C6eE=O+͚}~_M?&Yע endstream endobj 8 0 obj 5294 endobj 9 0 obj <> /Length 8 /Filter/FlateDecode >> stream x endstream endobj 10 0 obj <> endobj 12 0 obj <> stream x[K$ϯaf|X|-#"53#v۝ųԛE]|ٿKr-]~_tw 3ň+/\ۢL=W _i߿hJ_\tm_^_3؀",GUWr@蛧E닄m,d/h?M 0PK'*#%' 'Zɚb?'AGUA w2be-HAz/]WSф/7|y?]z ,u:K۪G7gD i9,_6f|Y7.s^ܭ P2 ?b4C>D&&/zho!!pu)&2ȅ mK5 87.D8v[=07'$5}*J$pPYa2pn`״uY o.TTkSpA3Pi8_rS?gf:u%ti_,Z1d6 XY!8:HĄӼN oH@+@ۭngb< # [1Eri+B7ej U@B@UDIvI:Dvph:FNt ; -"r_ƜĆ$x} [&뇏N 5Kd|=%ơgPg vٞ7^c:= q2FS6 +}5YcA9rP%?@@^: ːVZQ2y Fc l' tͬQڨ'0q. MBhGV#GOZz~YJ{G;n3-+u9vFB^1$k "k | =oLĪE*Tb&#wG"Iz"CЀc!_ ;_i !ىX-|xaE؏څ7;gcE8j /q6=a^*h+x8OXp_&RO@"ހ*i rB1t U>4 x0iڮE LnBzGO0q|-:b\'Kz~`3D1N 8QiyS"tQ* HwZ >ՒREgW%Q4cTfGb^+3.c,/P9Xڱ]鎺hkb4J g]JS^2uB9>XkC Qu;D2,Cf xq#60P3ϑGTD)EkeZ:OJcTa0ĺ"E;guYHiVP{Yi:z:C|?ǛgľG%[8 4Tᆉ>A&5pߗ RA=LȚ4H[A}et+ք8e*0YBVE0>}O? j,c[+ wQaˆgή,KD'x{sp*Qi2D *,F)(/F OQ EVIϤVLFؐMа5N+.OQ*']IQI:8{"ѓ> dV]rol5CıVotNƪұ0ϩ6 vl.!lL% 3wF b͓6t:ewM)tL*d!ΏF1qe{wU;w$Rm@-P tU'Ii݇ ]s;G1G}A$ˇ6wG 7Fq 8Sd'q($(_GlQ}Rk< E|u@#7hAH'#/zeh8U\M)#$v|HTIr55=iת(gP3W'թh2u ýȍ5Ӧ1iʙeڳES`Oem+,%^V]65- r/Ն ژ>S6E}b׈Qu RBO4$iN&$"F:7-Hiwpk)[c,NǑO;*xTB eKPKOxJyU11ﴷ.M ^Ό3#p.L]ԌEG?$m9l;pqOGv#A8 \j##16Z_zl[;q E? Uixsz.q6!&B\9Df?S۹ +K׭h'CZӃ &'Z4(xlnykOur˥.fYâeLɧ8>[J4qm$7 Ղv5>1B_T}VsW#>oxN>r0f}[OЖ|7f#muҤzp]eaBJ,GH805 %Q&s<ůY'(28~r;uP|vu6)xvJ99UzHURtܺg{J@Uir>yQd!;k"׾jT섯+1z.cb(JCA$ D-F2Z\NK|ڤ)3N|Ek]^WƵ_#|~ a_.^> /Length 8 /Filter/FlateDecode >> stream x endstream endobj 15 0 obj <> endobj 17 0 obj <> stream xw|T?|fNݾ{vlnnMF $!BB ZE:HQPDDD 6rE\{\*9'{=#ϐ|Sޟ2gтS )s&ۻ '  S,*Dwj˦=rbG}S'uM1!>4p?!:7gѲ_}  92{I #sΤeS V'͙yrw.Kbļ M#6C˹ SmC=f_Մ4 } +!vI /#D)DAD"FD($JR D-QO4D1h&ZQDN&N!&)Tb:1E!Bb1XA$V#^#.'6M*jbq-I"v{>V6N. q8B<@%$"&AX` X. kzp96+Vp;Np=v6pCntU\KF$%7&A[Gz}p᜿>1B@{s $ qwtHdp' zYBOFO0m{L;z{r1={,OՋ?0iO3gr])g uzA ƉSe@=Wӝ=5zpzj5/ôsS%DOo4*Q  atvY@`O$?Hx{fY_.L-MČNd5j>gŪ] Bސq3SVH# xHlɦe(TVbЦ/Y]L,  ta/aN۪>A>B^Z;Ć>K)].}e@y8l" x鼢 Qh$^d$ VȰ͑ 1*3o ԑ^ƒ<>=Η$-B=0<G+KHdl0<<;>1pT/믴-=jSgoq)v l/+G$sD^ Iw..ZQc`f沾wCt~wtk7X)N>iɯr!fLr)Ӓ>cK*GVLLU4 8d3[\!?B%۱2ǰ\躬$KWoxHUþ[NH3ǾS9d{0=NL 9}/}gt XǺΟaBtVW o+bX0:+HS`( tf)8,'BlHb.ذ$6KZJV?0eq|h&b6^1qW,] =Hv`#ρ`Ț(,m&/r4E Qn2cJXƥ80n`wģѻ_@r'8I>Lމ*&6GqaiU(KN{̙IIe>Qejn%# |I˖t< $GY#1%5%x~XWy=)uuT} }=2}?r*7Cͨ!޸2n0twwFk=6gH>F˲9b!nT)o #^(- &βLew!9nǾ V  ȨZl ^񯁑v2 $, ,9kJu6ud-#n(Zar/- N\?8+zaFFPnl8غLioY<9:n*SޡojR`c452o<4+I]?#*N&Ӑ?:}s)ϓ}v>XZ=>  5_E:Ao/VLz8XCFVHI{cZ쭥̈́,k1$kňPh¥0@%,B U_EkX^"NĆ;8ʻ%FLol F-4{ef ϣ-AI& ;İh4-lХ9JASvMu}f~YތI2B@ᙑ$|;=ćϑB|H&F0+X&vq$;0|R5hei>i xiYT4Hy'׼RkPl>x*dăbOePHf)v $ȽKrqo˹=&nd-9z|jF[дf%94 ߢ9\~!^ӎ׊c4+ 7KP?e=!A+ ^ igL2 oXd6dp}IZ/TdetBmAxf0TkLvY\e 8ܦJL82&c`81nhWz \R*ת~ŋbB*BQ$p8◜dXXC-oPQA]?6fG|a،:Ղ$,D먑֡8'9MI3 ܦj:xko. _⧍г+8)80mKb-BY'}BcOJIC}Ŏ,Li "Vk* ]UM,e9UL%HN> U)6Q|FoߴkcԳ9vI Ml6љ\1B1Gf^6XQSO>#.kV.SG>So~Fts ZGmXll=!#ɣz |U$Yuk/~K/qfgFJ_t'g-JzDX'9Ҽ ~HnX" CmѻJk&P`!`q-j,ϙj\H(uYRdgl2%w^7߳|>^1N0/%8 ?6(RBVOZA&%㡤3\lA*gakz & >ȘH2tןĩ*Yȱp)dcC+'t甒_\q~Km B㓕JTC㐗&bHO`lS@5 SϾ:s쎒v82&B >oB۷ mX ׌cU3ֵV^\=ӫb&GhhQ@*ѹgFF S`׬ΒUiVUIu)SrP$.plP)Lc-Gg4J1 & aX5_Ub`zQ6."a}*mbЦϜKb+`5wdiߤܕ2?7f^18B rb;AZ"YHakm2"HF)UOo{FwQ3}U&Jq3 0H4|*|Gܱ=Zo]cK\5[FmdG{sp xwdWZBsoKֈCa~j<Pze*{ᦶ8L.[Z$trjWi̻Ux H^#yWOP `|]R!4dAV'iMgo6KiW (\BWo]8D:=\OzA6p'ae;2_#؎Pu,gCPrHȴ3FXS"PTna:W#%['e@Β$L0j9'zH6#˖І3e@(hD5$C"<kQ2f]SZ`1w,빣sy9n4 ~}]o0>]p%ȈFH>ړ}jѴ4NZǩN0hbWX~xi~OldEd&s]2<<5.i) Kr 8 ͳL)G܀Md$",c6Us wO:nBuG*k&go%дi!XjyZsR>Ic.Se'% JKQ;#`( %r T F3d gVL.а7otGf!'eat +aZ+ג4[R'?T}K,B))z2nn`3zE(>Ѥqd7Z=SCLH>NΰwsY z zIF,/4 ZխW ܋,-&#(\}0/N_pnO5Iy/ΡjFذBA5Ng789*-Ohgh,4I;63K-LZS\\Eq7g'{ͤFZ8)>@N~J\_6DIJ6-Ne9zTC޷IxtBn`sJ<(DPQk: RÑ4_jrX4eK&[<͈i{dJϗ2B"u/}?Xf|9۷d?}5j+hԞg˿SI8qM}ylƱRWٔ;m?Co-4GR+ZPTMl"^hW*]q!W׃|k"2dR0_(]PէWlRL\|qEU E p:e,?}-, |Iob},MTPkLolm/*unө/KuS!>!/7j\#Bo磔`sMf}Bt>7UIS3U˯i:2pBA`N5R>St@Ō'Jzq~}]}x/q\I r惢)RAJQ@pV<"KK-+LxŮ{ MYL~q^Y9#ʙ5)?M`--궧/~ǰnjzi'rr 6=Zu*e@/l3'AV;5:.C ٝ7J1\ u@Vk\w1}Ӟ+5U. T[͏̉sg^%^i)V B!@DxE0d1!K*m;?p Bf |*k<̴w,6L_Lfx!prUDX6:v |䆱jX3G8u'2μnD% ,W>\KNe Ns 9AKg s̽ٲ!nghnW|Y#$W١`y:iYVg_ :v3=#uZbDacD 6sL@4-SZ=ѐ e$ʰE*TW<-^7^+|䕺̠ig*oiha6+ ;j6i2F=`5#s"`J]vդٕt3?0>_Ho<0έR%Pm|H"n%bKrjǁo?woKgRo;FR7#Mjݕs6ż:A)t &`W1 :𥸪 3ŬB#ɹBc+/$`(3n_GECiGӣ1ǣ6S/ƃ&3teᄩ:MqZ},6bpj?[nKF 'xcmsznkwOcYg'm0RFħd>)40=ơ)G)mѩKylf{QJNԃsFF^(v1֠]grPh=TNH2>;b m"O@&Gk2.ĘA/2vOia߹TYpBlA Msg < Syx>E;|K;[hG$Ph_dihETSP5#:ÖF TԤxodZ\企 n(HfMFT 8pcİL9hM[y/NWoͳPVӆSM0!̗6?W (p9 -d&c)4BȖ m6!!(1+KْF{/{PLToCaVkAP2d4!@%Zg|{XS5?C6HY <`̊PY>g|'#{/ 62.OT_)}Ah;華'e^}p?u)' B…FqKjtFK|PhYNX8Y%O=3,SqKk&wbǴv'~g&Ҟkr>4߉w'&4ߋ %ZVCIaa=l0Qw|JV;,7Yke陳=,fOT8ϏO_RqAߔC G!9qJE|Hh੒CB Js_o!̃V@ uϊ^@ϵ\zygJ,IVJwچ##G6Y6iQ12P^ Nl~@Z;`ΞdJVKw>&4rNeĥ*-V]ܓ$x}Z8GfiO33ⶀB픒G+y^ XD1ϙ&_~%Ռ>C.El@N8(Y3/*2 bL0OuDeI]!.țNnp4}Zog.6<з2:ʡV}h-x-Z׮ poH&;8"!TK(9UmK醏Q+-Ykƭ'`:dSl ՞(7XF65>婫 ޵=(oE)}9&|e ;W Ǒjm]^z֓%ódJWS izn&*˫ƅ )3CfX2ngzK5Ƶ[}B1"L.ssB2֔M[y M7^-3Ȁ*iĜiI$h GE3NcI`7 LGVY=|D_ % |&Co]iO ,hdf2&LFgp) fxnQYd_֏FYkFu;@AҼ -ŏҍ02"H7Jk)@3l,pV١g.  i|4;,3z0y), 0P7#prVvs&d0NcRiϗ]E93T;%cQm1MF.yiZFWGAYADL>8 Es"Y; `u^R3>5[\={[3Wi$֦'օ$ôr, hXVv[tРQru2fb,V^)g%Fܳ@\(Dzfԃd.7&_p#1=H:`2L*Uzp-kHyV,> [&(qnk<ȥKjÿ$XB.|FQ<,EZ-ORRyI吋g+p !VS2Q>PjCr)Zߘs!#4ݟ4a䨈yBZS?,I2` 8J{_KXvXɫ|HsID<5f:3.K <٭ZGV1e=LF6g7ģu߂#L;%"ZfJLn b~JfLoW ߾*?3uM!GҢt) LcR $6Fw9PDCj8Y6AʷQ%Ì`"MvF!sA6X3ߖj f-眽nSSj8w7~1qELKR{n4[OiG?2-ݥ*1j(e'E``":SIѓ٢1UӋRAmϙ{="_/U*@߀tx$7n˨0>7~u+g{4t tq|4q*7AyV(+5MEק蝱7Rkpn2}zL? F{U|tfS( j -ufCݮ$ͬݿ+9{2y&% \4utРp^>Zُ|>q!"_cRB{&#DU2_-S/S; [EvQ]vh]^4O~"wAޔ+\;M:g/d |ɚEA -ZY!4q'ВslKHVgPa8qU:fZǙ`ja.]zԾzfUxVe:8qd_7W'RP΢Z/eo$%3>~tLM#OoOg P{4@P{) -ɪgF8-O3pVd2rZ23jN 'SwnSM%֓k#5mBΎ r#pEcWl+A-N O.tG(m&uu1>ur [bNW =[Òݐ(I/MhqX,+0.d¹h* NQ@U+ģ Up ZG #80."^7 # } Wk& ~YԵNYց}jcIWe{{'ݣ>&rd 4yx5Լ< t& %YvG:i du4d2IY&Fͱt41t1rURدx97 8²8!dgYF 0_L);83mvŅ8̤ W;U܎Mts -h?7,B}Z[Dq΁ۋ֞\4=ط'lAC,of\kb8GtNMӑ/J%q|+%\r-H$'0*ͽpGz3Z B#\meӇ.mŰo+ɽe \GV܍`u½gl$ n+)^ uC5²'bb@E>?,${Eu"$_lhBz'}/HdpITBZ~f/Ba~leqξg&CM{ZtiZ[G=0P$%hǽ7VnYsIIy|/딞Ե zJiP-@ xlZOoZ;וk;o .Gd"0|ɸgvQ|½ a(ֹ/蜚8315%D1Mq&(}r(I<94LgĆSHc&6zY}; صup7{-]s؃TaX0q]WyR5È}&nBcrPV8,2J ݺ$.PbO~Vğ^+ݑ9j5.Sh5rQ04V^S/KV=A+ %j%4n牰uYΌq(wf.}Qu3gq1޺y4ȤnWV:LJC#d̓_Bjy/ K|Qh)'{!'NW(=ɁKSZ?kTY4ХT@jۗ2zF386] Ϡ; NY< RiT~R_+,|K[$0TrBgVlc1}~ ;%hi ni3[S";P|H㳹VeA=aD:ed:Oa $$a {'x]Üw=&hzP:Ўo'ceց&_'z›O 4_RWO0ŕ&Ȱ 9OObSĿH~Wc]?̝Z#[Zues4`ǒ@U{ُ0hU dthNƷw"Hoϊ+x]Nj(%3\qZtX5 =rdVۓ i03fReA[92y\IV?(6FH5+4NB^%J'l%%jFGH±.ۮݕܳQlcz򖰹+\!yV81C͔{6$%Wh@?iE ,WԱN'9<{6]*.>if2guI9^nY ϒ^*Yz8yV;rމwCKsǐB#kW.nഒ@^?ufs-h7y`ζPh )/!{sIN{[:Sv{](8;`h:Yd^U%EvEm/(9$ZD]N,RUuwW m{z2뢛2$9_wrmFL3,I1N@}EI^ 4o9>,L{~:p){Iy~:oN'ssaԁ߂/I/ߍSą|KgXFVn6U\!6?pfl6?м&T9|1+^YU}$_Q="~ȒS]Y>iOW_t[*L-M5[^{5)Jdmz8W-V^ίsW4 hzE X֋Bvk m>{O +;WU =7|C~0uqJ']!EڟWZ7T}һտRWZĔFs[W:.&sVY4 {ےI|dqP{o{ bǢ7TG4е.j\iY-ӹOWW6ClȐ3bsW5/z̵_Y3[G;~rw=G¶fGf9w]RK/̷bYiٓYa.T ڭo wkMOS{F TW^9P~PHNJ]8lŷ+Ӥdː[v>eYw+R3O/dt< SmbNQ,oP'O3ij]kfVJ]_ 9u3xo'^W9(`l}z"Q'ѕx$~E,An(ޣu>]~K·7+.-j:&'͚WvۮXϵ0/7YxMrSQFVPC#_[E˺FS-3uˢumy⒭|Qgɖ6=~Dl\QN{xuĿ-b~kOk n}oM|Kf\qQhʵ~`e}G;krFeJ]d*^ I By!kyw8SzF p™_ӛ P}_J|v0][աOo]%7edD{KtfmwYU|wuZ^Bxpo틾~mx4'Up9 9Zkwz;CQh?yg%m@Ϻ&|~-Gߓ.Xmkˢ-I_:b;*JLվkyM΢4Yοa3f?];Qdf+:;InB`yzzfkxKnR>w^U?KWu7"څ1l`{Hv2 cooK+,^mjO/L)\Qr^OF:ʾB`2`z2WzV"KUUvYn;/}~3i!GJ*L 3t^_:a`갟铏?Ěć./5&"[0GI4O'ԗtW g S2J^ %Y؇ ] A׮n;}Tp- /tv~ Cpކ &l'8G _qVpp:m\ڣ> HOܿE~R`z/G.#}>C$8t) M ب!>N }vϳNao՟",FSgun]OX# E*..~⭻SxAH} xp-\t_GQ TwGwe~ CF?B0 tGBoRG)#~7GV^8zCZDЯS?E,87E['=aU{ "菪/ /nA#՗ G@;@`'܎@vEuC ]OPu?GQE^Us4coA2Fx dv vv HaSݎvkW8{C A@2[/~"ݴ&W \ @ܬsжD#  _mtv̨O}#a?ٸG xX=mנ_"+˿>ndQ: /,#O v#}F={_A,WoD@?nH P^s5E: >ôBnO^&X $C_}zXN}xh5l@=60>KuuAw ? a䱡W؏@|&Fn9 ;]zJsp^&o~ lP#.Jo ARz9Aw ^|nג>m\t>m߇ @Yr{YwQCrIKo]8 j m /^5s'/KuK.剔L)aZo5MGLo槖Lݕzoꃩ&GL,iciݚvWi%ln3G̟]2e dLdʘx,㉌32;3'3f'uYY˲z l}hko~2,YBb92krE˫9M9rr.ι*ٜs^5V6={sgs?='M=?}ߗ?]oWPZPUpnd[Ap_; -|𵢊"[(Ptq5E7U@#RqFq~X_(K%C%;K(yݒKJK/+=XzVW8+xe+N eue}e]Uvɕ=++}呕W}%_PrQ<||WT+2*+V\qJR<#+߭2\Uު:Zj۫WZuWyUzs%߬~DMDͮ{jV5/fڗj_eueuuM.{źKr7߭.^]ioVk dXwYX?a]C m8zû lmClڎl,lTmn 6^xƣ'MMUM@M5~ӉfԜ|-Be-7rVcu_u/kh+nsmo~מ^~Y5϶ZM::u|㾎:eC*uO 7TPB<!'EW""e,A4Ay(弜*E/biBsx9=;C rPs5/;avQ /geIe0w/SlQ(-/ :^^N x,7r?y9Gx-,2/K 2{V6Tk,K-eg{gf6N)-MM ժluz.e-(,^ltx#36pfM/L-Ǫ'SCSʺVuEB^sƑYOHʸ:t+PL}!"sJx֭>pݴ*4ۚmsg=:[Hxʄ )-&[ӅNo`٬t)6ih'BZ5!ºNe ևm r<3>6M=IĊI3LGab3]QgT8\P&"e4Q[7W{}3hvFpo: qi> 6ksb7BMOPsf*W{ e|pt }qPd 2ZI4{ds:'A{=S߽UqdNjh* CNj6ɲ'v?P{q{"Jҡ'gePw ف-netkڶJ-X ~ohVz]{=.rs|8ʔ a<ע@п=%!"l\Ǧn'z==M 8.J S0\ {!&5F<@RAke?R140BʜLĭfhB$9S L@6,` (Mi##PaVE\,]iIg2^0/آI.}{]hP9r{!H4, 1SI/"➛t\XZ .cJ4^:t ;7b"݈bLi!v~* [!dMgd~ j:cF}QtI OO$ؿXd@ C[b*BB!r1n1 KIm̍ӸF=qaԬyoЃR`?bJ  !(JŨ;8 Q0q@ /"q۪!ͧO OIsS|t Vj MnxX M`wKJBiA#0i cd@\JdNq=̃-4\o + ZitX`ZP!r{A(-usYjiEQ@,rB0NXO;bz#n2ͱO>aꦄZv9\Y(ML  #S`s0Sx^W~8 1 Ly><ƽhk _"Sѝ$?-f‹pVМÐ  [ɔ?< V؋-@50eȉv58G A1D`KpH4F̶:|mN2\IvX0( aiMs744ay1ۡSs I3n%]%[L23abqoo;ɺ\sq"dA$ R'¤8KKT|rK^FG7Uݤ<&e@u4؀c*78;=8l'l=6>?{̮ +c#}JE8\WX#&h18Jeˠ*wJk|\SG}Ve;oбI~\ N#ԕ5h~2;=CX v+cۆǔmc#pvAGb;&dwdMV4Veb>=Ŋc 50bnG t )pW A;` +I`O*}ݛq@s;l;cCVe|;`wxC)[A ;M8w Q q*;V{lpPF]!@o_ -UheF`{G4z@gzfY!,(B0%IhhV [S nW?$`EX'I7g6mP$ t2cL>89 sz#f8B\BKZl$\Gpt xz~(L3]X K-w }4"ePHvqvz"5۩WA*m!/ƈ|C<~?^mML3ˮ5 I[,ƭ~l$ay*MIIB'Q EA.7nK1rP=$iRr;L,c#,\r/Hڇbm 羋E]%Q2ԡVLEir8݄"MաD;ө0;"(8!’ wP~C'iJ{tG$9;Fb;ȵdC 5zc8sDl< v ~ltͦ,u{\g{D̒հa1AfXF{M{һIn{驓pR9 I8*@Vf#16@L? -?rG; iNAv~ A}1Zqrm!?H!1bLdڂҜJ<$#`i0isg۹Hd=u1@p8ȴO1$L8)3kQv9?6EX;cL{:!.3L94! #{M5!}4䎵7LXH}_r%\ a]Aꋶ,'x k M %H`oLęa-\"Pj栥'&d>h60N5V!^t!rC[0N Y9g(b$XtMҬϒ'yb7d\OX#ϲ%zz_hIK_熓 -ȵK ei$dt{I"^ 0aTݤKFcbeHD/"$iOxk8X>k~.27~I%!5C Rxv`ޢQ?DYZYa76l}qrFRY&ZL~)S4B3滦S|N-ӟxB߭i'wI>WSV<܂DHr<1T 0fSAӥD+EL-ԉ'>BGq>[{\%m-`1m_P}OYF4:ľ3ӣs4ܜIV.nI*JYJsgBa6f}(ON,4a|Z" -tbZ`Q8E%Xk-\?M34˄^A!cMķYL\hqczs0,l I٢Gş 5&2:l]操U}!lddX[)F 9ʌOKxYL[[oxFp'"4N'SQ<3]:{j3Eb|-]y e ^r6@y/q²Vp\Żw; KW2k4~@1re"}il#1;Uf'yCGgl.5Q?'i 1P/f)g <+w%-N 5͌ 9p8&)1Xn9.)<.M6Fb'KOs&ϓegrﲹUvZ🁥3vk}NO˱|:qu" /0qEԩ#`r[̓)[bŲ+6e p:L4D㱶2@l?!NUX5fqU#-vl,O^*I:j{r,'=Bw 稍;hcwq]0GgOVs 4$ _KO`R4I{8Zӛ$mivİZ.svO :GZ׉SEYfDZ .Eb&)Q Ov=>ة%Ⱦ,g{-]E}24W[|ڳ:815#3hRO Z!/uھ ڮz!zG*z >6Nh7FBϛF ^v߯ Ahbco=AP&NLkFB3;;SR(r|s@/00X Ҍ 3h`waA1&qqzjQhǞ8v [-vg9z)9b5AXV8ep)c9>|<2x($!u`$x?į_v⫍(yYfDT؉C<?HC1žcT?WLx&V5t'SSƼ caoL#KK,NI 2iflҷq-a_Zvg!Xr)p<ƍӏ<0GFh3:}1c8 Wpe8 56V3R*hDcB} @@=lR\>B`~k#sԸ jOpF6^Z뤺f=p^x"ai6Pj洟 T6n̬@Ef&&~N wY2̼A3µP'ߥk=RR%`zn&H^ Ԫʉ-};Pk75pZ7u}ԧ~ہNjHRԺ~ok F Qkg1j(I@MmlJ®[@~^^Zɓ+0В$\5P_ORe8j\>PtD>GJTF_f~i*kjހ}}KT> endobj 20 0 obj <> stream xeWn#7+t& `M,# Y>\&sHU^-lnc|<o?|[O~z*oj>}y]m\~{]?<~=u𴬟>.t[wa~Y{7Eax@˼eWW~:]ަOw]y~.})>,X,DXw!XU,2یMel *cW}/vƪ3Xx"T혶3 3d,N52V1 :)3vͿMOq5)>*/1̟hy P37B'P[}G*b5+B$`AOLJԊpT4ȩXrN''[ E u SgCZz78r C"_cEFAb,8i$]j;!WC!ǯzȨ{2fˉjy(:)R)jDU_*TK^K͖ћZ'-[]j?M9ք <זN{ڧNHx" o:e(CFU#kiiZv6 6LX*̴0Te&mI̴aÖJ[R[vkȎ}ImiZʃ bYvbst]ItSDN;GSY9n@lhYu <PO1x9|ˁ1yS=y<<@ECy 9W?͑nhԴo{%Ggy#?R/lR/ T} 1rPd+*P?v{ lJ8؂0tM9ɉ I ;$ RGJqё>K)X?}JLk$5Q}VL=89&j5xsR(I6d>5DOM> endobj 22 0 obj <> stream xݼ xչ7>gf4FcY.'xx8+Id[ؖdgc%@@ -e)RH)[)V (B{RJ^r½=̙3}LEfbt(B٘`R%z ~['v5UƃюoUST'p?SQT]㓱p(NGEMvNE50 dp U5=ƨ_PԞt$8}!n J ~-t9|rjh2s.waqIiYEeUM˚Z;VtuXf݆6m>>;ٱsמs; /CG~}w{C?>?gUah F*VTKUV8~]ڍnx2*)E=qQ05VڕzqJk~qrJ{Am4b e ͢;`q) {mjDrטcjN޼k:(Hv݀87lЮjTs\^*6kA֣c1o9JAa)'\ͰcN Aɱ\kc22䧟)xesh-{]#3g5[d(3xEn] bo#%4UTV pc<HK7O*)m7o&BQm1= PpJtQp,Yc =K7 u 1}q-}VOG%ܖ^mTmY*jvQ/~= (fTkk};vW[tj mW_rÆ\o;F}o19&\- yκ8mUVqu;}|ŏU-Xng~İ>Po"̀SKd-_Kfvqc@;3CW5?|DCٻ3vY:gRXZyv~NF#}ٴ6o8΍: ^|3 ]my뉼 ,Ȉ3֌$CEfM6*K[ oKֆ }N0d7T +I1* beȇ8G?Ə7Mu U<ün^14fgT*F#kE~|1 e wrkdJ.iVeWXW.uv2*:{JAc]&a%¼Kq:x; ^KNW=nh-48V^O?S+3萉6׋_NXMkF]ZMiwU()2DF6-3VB| l Pd3}СLEJk]n6쒪:CCVWeov-28tbkm%O^ /kïtER  @qݻWVUih XCI^qzЗL?J XRI+S}lciHiX]DMFK!%}bO|=AR Q0v[BCuV.׎5J]ކ]<-PVYscm[Fތ- ]P1vlR>?ۉh _LpJt!`,*0џ~1[x|ݑCs,C`usz5]uVś~,gT(ĊgUY]OPQg<6дOe{p yЃZ(ϻ3;,'ѿWѷ 6`c8/`ӳK٦%m^ؐ_wWf Tݠqהּh_{-gɑmaW)v>V[aA;Jsg5q|CAztfrMC '9r|qvl]$CTpfRiՉc \~7Ñ :o>2|&Kut4Oo,QlŞÒ弍?&*Y߱t2]]բ;lpl^bx]+2nv&Win=qjjՇV݉ASpƧlM^9:8i9x=1΢v+at)"p1^@KKSwo[ZȌsY>8a}GH=0!~[b~^62U-1m ;W.-j5v8=[-aozjzѐN&z _H<:>k**(3 rJ$>Dʱ{ݠ ѲKohm,YmKoTe݈J2#fFY监2L[?`ؕ|ֶ]CN8'ҭnG,#,S0-p h9mګ[W\LX&~2Ѵ}XsLziUO{zJpUhUjwV06+kۻLBM7[13羾}}~Xstx1TzV+֎TG_yA}Uߝvȴu%=r1}ɜ;'rxD1'O\ ?Rxzc/;Z,Q>] d6 42@߃A,z~QrnP Jf֥5]ݵ7-JyJ{p΢,֎<@ۧp&Ԓ2\vJXDµjǥl<8M9Jd=:kSsFNף0 OH c <$?_a P}E6,^ ?=nSd6nk$1"(=Aǩ I " b.@6`Ui;b&z7 vztM͉T-820Rg0-%wbEOv = `Gt?Vt hsgݳM]Y RG*#$ǒm >YaH!Z(c%.&!@w]+fV kfyj1P{5lu84Hx0[m.=sᄋcbP*iڍ.Wsnؑ[ijhK}H)\Ռ7m^X_2/Sρkat#I"_LNkA^܊P-5e( ?2.GO#'2zS).j@׸nr(\v;m,z1 1"~zi!CS-
Z`dN2N'G\R]Gۊ +.RȅHZa6mͲFlnؿ_޿3٘ t2IŠ^J&-+jGgz1g4)}w4`ǒN{Q+w[HӦ4p}iRqmEuoW(A8d~]zW|ֈRRU&s@%WuwiyW[⭶lsMyeYhdѫv/~.P|_qk/|䱙Î5vUKCE4-_qfsǿRH 4 ɵ_xǿsq -k'x7k=DJ"?sM!rg=ZҪ&|" ]Ҹ\K0|{ɹE9c_^~SWU^soW(@ەI&g)UDIX bdwUS:4tEK4:K,/7WDͣ>eUٵc Me̝Ρ-bx-2&y_WSx3q!eU͵ҩ q2v UmԹBNg6m4eU0\&cT!6:qp1Kqi5sHȜɼ2(k#ԅh>ӄ\U>9!څ]{[+.U)e 7dᙟl%<|Jd1s۶ 9r7de@~C6}b,* 59"JO3* >ʨƨ;X-,omwg쎕,堂\5Tu{8#7Päq?WLۺKϪBnHcsЧ1,ՋOAhKJ֥kx[Э;WExpFt (hx.`&2h/d8%qtu.ߵkuǪzt39t6*=z:*kW|C˦F{k5gmls5h◘Z)*|L٢VGбCTJlss=/ײ7JM5t#*|zU =<`I"ޠ~ŕ352eVy }h樊N;K7 {t_?͢-W;?Q53M }D7F,ğd R9IpN!Kn+ Z7=J %"P yVO~9;~yy([}+sOȰƜq]~}y/c Yb+WPv{=-a?v;+YMhB7Ztm,O2Ze>qZ(TNpK'uY2CJCZ+m73&K 7%VO۫ʳ#ױ,h6YdKˎ=۲ܶIWZt~Lw2R<JعkY_l}<4~@˕x*ARBH.D2?Eru\U?hU 57/)͌f6K'K4rowoB3\XT1]TrWO=9r---[_~~?5K|㯕LFHļKEWJϸѦ3ՋؠՕ|qVOOf4ZM✋ddu'9mLGMGH[w62rJB4a% sɠ6ף+6;cbNCe}*˕l(G{J'OtH #(gX)YӔrq>*] EA yu\ϝcvgH,9CJZNԃRޠ(. kF"v" N鮩97r|k֞U A" qKVֻ|2!q 5"q"6GǙ1I}̑E 2H,W='ʊ{l~憟>dnmTYkQ<>&~+DqH5>.{H:wY HѻFްt%97> #z%uu܃.;R^,M|kѠ NoG^9KG8wKy7 #~;KrHO.ʾկ JEx@B,4K[Uh3 YVѫ MsH5dՄS>:qqc s2ΔD r5`g7ć}Ŋ]Ey=Mdm-;sK?軯{ifwGlmHwm=ͭh fpy%%_0ŠOsO+~et.2N8b&.ɐp6yU' q*.3KLnKU|Kܰ-q,~΋.CF=RkP?hl݆Uh6N^ѳWki҆W8vڳ~1}3o*{.ƱRi03Jw|Jxyb.?\z{jnI"RX`\P f- 3,G(aߏdm0~1)]س|Mު%fz5(-f(uEZՏޫͪn59ҙ%} ,[[gBY貹oFUxW?qxFY+ξ{( 8$8k|vp MMQ٬ ]UX%t2a1/Av;XX9k)+>Tăэ1tF{"v} Rk'Tme#Wҩ)@^8r=/魨c[.0شe*luwg H{KP*Fd~ƌ\)ܪ/2\^4+0g{zp^#۝d΋=p"}A^ Tas3\iV1Ԭ>wk֖>ٻ6hMjmwv2oXP1yeB5PL;xȌ..(/{IcTP^}0_+- o!LU!l^!-,#KSM)꽡հ!*qOAxp>}KӕJ!RJ+v(7c,NTY39ݖAE)/6fmL/Bs;zޖA3whW!5'ߣ}{JX=ؾ=B3Yp1ڇ5rC& 5V s%q+EC&6*qE822k"{=B]?Rr,0kVx9. ;l*ƊQjwusSթP_Hlwal@Ż`+u0~\*S?c#NW/.b(hFyE2nhe{~E}tlj-I_ %*1Z-}KwSJ"o=Gggz@%);W.Z,vRFIʷWe3t=]p+V:ʷvͭ~}v`u}vޜcELVTVVo^BST㯫?E۱H62_̕wSH3N$yUځ\+ k4*2.-ڂf^լ̈́,ϭ^faɾT k=&zDc)F<Ӎ kd枛{6ɼKM&ݲIP. DO9׽+.'_Vl>jLk=T >o@c#w|N |. /C~n(窬l}Vf7kNJevaԉ7}^BQ轛؍|ɱLI#K;6"H ^<#=(&y&'}lR1Uinft0tפ겯d-7Cq=4ǜ j,ڹI! 3}YH0仨rɅğn(/3 [sj˺.ΔeOY\{88cSB6w,2Xg:Wz*WO/R8S!+TAHkH%^ÛdOZWoKņRۈ5M\Ԉ.jtd~ӼŒޛMoBg}ƴB{唏i*1_~J޹E5#Nʉy5J= 7y{X[Qe5/_d5\ A4*F'1O0Bzuٝ`xMbMn@W"thou-G~LhuW *j=$ dx{̐.-,*x9} *^ymQ J}J欆G{T Ζߩ[YR /_sh|DF.{v'\I݊J>uzZ2'mrNUxb޷\o+m6\\3wE$g+r9}F֓}Y"u% ߅\0|Pd:a-H_ϟ4gSzͧlZ9(8‘z%,?pvYZc =V\7ѝᛕTS7T-ۿ0d$7QB|KP]ӟ)_/w:~O(|ؓ_=ҡq.ӘM_Ȃ~+S^ aII^߈Ǚ'LFbWZDr&w~=yomirZ7gG-'+i_\zj6SРR3]`xkQg_?0Xyi2.R0^ rx2W`'-Og,F~L~r \UPdA˕vqC<^uV6"hslzU,&|ۍ0ǘAvkrRB[f :ܲUTabewٱŦsQcY$3rU3rp++EUZɤ_6A`}ҿtg7?/S?ߟg4skN|"R%m <)Q je!+ (üA A2vƟ ܌ߌˣ?ON 7tQ hiJ3u7jz6{<Z/K׸Lv+?>c@?qqc 5*7 ѕщgN5nj?nu n[ܨckHP Иwqc/3wsqc^Í6ŏ6Ƈ>;.Dڶ=a~iT-KղP7Q(JleP夎Qn0ڸ,gGRa^ao\ṵOpG}a]. 7)gځ@ / "_ "'J8xn?K]2\w@Ut _č:q_č:qC7F[B041̣p@Qڟz͉Mw 1h#bsԇ(9E5X} }%2gsCKg,͖N{}D*i9{)R|85s=yskJJUV+*oQ>LE*Ym]TWwתR߯~WV^71vmCMf1o5hW;ݢޮ]]XB7];{MC}~~HLi6 y 6|hH}z6c&cw.Z֘:뷭Y߲zf]`;h{kzNE+ٟr~ǝ{xYO[61ҞLgӍu}ү$^T~h4wМH~Q 4^ UA)YJr_AIs}5ExDur_CMA:}=a+-rXHAM>x[ܧ)W3԰,œ}%؞a{O4;#yZoϔזHhxL()*+KWWX9 .~;3[}Bᩨ0r:^a 8B)ae8:2.GљD00FPThOńXlG ``"4`D4K(`*|P$:3 ቨP+oLL*:̅+@br_E_U*/q@F&hh$0!4Eá!k:8"@t c bp8@\DLMXpg't`4uJ& &1Š``&n] ظDv ûfl/F@( hX>1%i!!w s=Ŧv ],ԔwA2U #-&?E"/ =fO`6 wi2ёHh:ECiYo{?<# ]-m=mR/#3uyֆ|_[SwsW%(l  m;B!X$` ߡIЬ0' Y$(^e$< GЬEӑH /13= &;c#`{>86Fl F`bX2`+3!z B$5XV H0G0b, 0c&`"A!:&Dd?i:MC<bQO5( h`fFC3 x(gb) 8 "̞ DŽhxb3 NFO< `G&` XX tL4 pR&0pptNe$ -pǾ!pOFB@ܞ?/#A&w&vX;dK̈Ϟ EDMJ τH0ƛ'v000<2CV! '&&I%Ԣsgw.WN0e `c ?I$`!/C0R-:v O"۱`T#!ݼax&lEe%IB&%+o* KȣY9B&Z0&] M ]?X4D=CQ>U{O某޳;a}$W A!} ͐^ZpX/ C̀ac2AI2 xÑV(d@4n2 SBpj1&i&6J"N.6A qc);"!,E^2iX%LHRŵl90 ޞV(P3OX7S1싈q֠7Z:<#.|&8`o xdAd7˻I1\/ v$B4u[~~[  ȀE +`H`r*IhL(sxАyA ÍNVj0DPCT'Oj߉ޓF0 *”"'z1x8);I,F In|f20U |$sKm"$4d1L8X` z1)B(!?7%I|AGg ^>z61@[# *P)B9L1rg江;{9-/d$x>d/*җ]NY rb58I4R&G"LɰejO+H~-e;ęX=,DJ 'ăS ( Sw9Fp5(sIv0o)·$^:"=,~^<7';杓t!OD 'RMIԔBr! 9X] gʽ{ gȽ(3LO- xL (&i6~,5 'N;ܕhq*9vI@o6s@lmkMp k:;zW 0gpBS:aegOo[ /tvuuzΞխ=˅fxW|ݝ`/yT^ kKK\65wvu 흃=xvXIklY/±i]ںzy@۷syǠA0Կҋ6Ԇ9%]> }T@OZ ̯I,oio }m-ok$v]!mV-@md `=@!^g0 eM@Wh|{/"'W zdX,xTYi^" 0N;0GPajEEb@R#T]ISJ^ѕ0+@MPAj:(5+T==xN#\o=#W1; 3Q ðW<12Iܞ:A? w92.KjtO&Ƨi27FbW_iF<YbJqBMod#E"cR*珓qJ58IGiK8EjTN |ɵJxn6%5X)Ib_?%AYrS2./i' );JSRUcr$tϿ$>YgLN3:?iM) fûE)KCu:s.-ŻSΟ(Z=&OK#2&0@%+tkTS:/$"l#5j5{ 6rهx-H;|[X-2$\XVcT{~} =Ubo|OVwV 9F8-Es3G1dHtJrхd )˴LG49)qHdytƬ&\ML텲z*WX~3ę=̟N9d7Jy]FSOŸaUu{Cm.S?i㫵+T>3# IWYZfHBu)q UD uLQV|ƱzNZx/%o9^VQ܋?W2Z47QwuR@>#{fnǨ3U':'ΉsW>)'NpBuN;[cZ=@7_${0khRud-i~^GIorV.hȪ>ήՄj9ߣKSw|tw](!e &X{ p']FDxW$oWNw̓86%=v/FyW--:2c9$(I3BLO+yﺒJze)*>aww=ҳipD]d~"6M;TH?l"tobTՁ m]Hԕ!d?L+I%wE>hVm47 㟧Bs%52lIJҩ\YC,j"MꕹBi7l!֒u9V~rV!WBVLFV@f.;iy?Y ϭs>n9yN#00VK*`_ X.E)_pZBSR@έ'_@U/5u E2 W }:. JnN*#̫4(\ #e»5nک|@\ApuyYyO~9_Զqwavn0> endobj 25 0 obj <> stream x]UɎ0+r9]B"a 34(l7UгS{UvyU8,;% c?}\~voØICUﮧ)[y㾸aܶl/#Ͻ-]>MՍK..zn^<,WBUXH>:77m۶en?}BDsªf籊E =b0&lE\8k7^#qq_\u_#nb6e_#ő٘[|r IP,}EeMdgn]:TXR,t K%AE ujb@!ް\Q%jj% )(@q@S|0R?0f;GPy_CCÒjE4D-ik#@zOuIékƺE9 FW4KwTw&Nf)."=:o)J:OV%~gĦs\fnPeI *MMBvI-6 DQCc6* H!Ȼy@xrǙ?*M ҴK endstream endobj 26 0 obj <> endobj 27 0 obj <> endobj 28 0 obj <> /ExtGState<> /ProcSet[/PDF/Text/ImageC/ImageI/ImageB] >> endobj 1 0 obj <>/Contents 2 0 R>> endobj 6 0 obj <>/Contents 7 0 R>> endobj 11 0 obj <>/Contents 12 0 R>> endobj 16 0 obj <> endobj 29 0 obj <> endobj 30 0 obj < /Producer /CreationDate(D:20131107230107+02'00')>> endobj xref 0 31 0000000000 65535 f 0000067608 00000 n 0000000019 00000 n 0000005785 00000 n 0000005806 00000 n 0000005983 00000 n 0000067752 00000 n 0000006023 00000 n 0000011388 00000 n 0000011409 00000 n 0000011586 00000 n 0000067896 00000 n 0000011627 00000 n 0000016121 00000 n 0000016143 00000 n 0000016321 00000 n 0000068042 00000 n 0000016362 00000 n 0000045740 00000 n 0000045763 00000 n 0000045962 00000 n 0000047141 00000 n 0000048305 00000 n 0000065858 00000 n 0000065881 00000 n 0000066080 00000 n 0000066790 00000 n 0000067392 00000 n 0000067435 00000 n 0000068155 00000 n 0000068253 00000 n trailer < <0EC24F05E6BD3F2819DE2C22DF5EDDC1> ] /DocChecksum /20C17C7440DED784BA5D3387BCBA4933 >> startxref 68428 %%EOF