From 933a35652e47b8a08ba0b0b1f2ddae434f26703f Mon Sep 17 00:00:00 2001 From: Hagen Peukert <hagen.peukert@uni-hamburg.de> Date: Wed, 17 Oct 2018 16:59:15 +0200 Subject: [PATCH] experiment image files --- .../_build/doctrees/environment.pickle | Bin 5908 -> 10884 bytes Morphilo_doc/_build/doctrees/index.doctree | Bin 5471 -> 5552 bytes .../doctrees/source/architecture.doctree | Bin 0 -> 14558 bytes .../_build/doctrees/source/controller.doctree | Bin 2817 -> 265566 bytes .../_build/doctrees/source/datamodel.doctree | Bin 7593 -> 83270 bytes .../_build/doctrees/source/framework.doctree | Bin 0 -> 9257 bytes .../_build/doctrees/source/view.doctree | Bin 0 -> 85499 bytes .../_build/html/_sources/index.rst.txt | 7 +- .../html/_sources/source/architecture.rst.txt | 66 + .../html/_sources/source/controller.rst.txt | 846 ++++++- .../html/_sources/source/datamodel.rst.txt | 217 +- .../html/_sources/source/framework.rst.txt | 27 + .../_build/html/_sources/source/view.rst.txt | 247 ++ Morphilo_doc/_build/html/index.html | 28 +- Morphilo_doc/_build/html/objects.inv | Bin 302 -> 337 bytes Morphilo_doc/_build/html/searchindex.js | 2 +- .../_build/html/source/architecture.html | 147 ++ .../_build/html/source/controller.html | 974 +++++++- .../_build/html/source/datamodel.html | 295 ++- .../_build/html/source/framework.html | 114 + Morphilo_doc/_build/html/source/view.html | 438 ++++ Morphilo_doc/_build/latex/Morphilo.aux | 23 +- .../_build/latex/Morphilo.fdb_latexmk | 37 +- Morphilo_doc/_build/latex/Morphilo.fls | 29 +- Morphilo_doc/_build/latex/Morphilo.log | 88 +- Morphilo_doc/_build/latex/Morphilo.out | 7 +- Morphilo_doc/_build/latex/Morphilo.pdf | Bin 47006 -> 0 bytes Morphilo_doc/_build/latex/Morphilo.tex | 2055 ++++++++++++++++- Morphilo_doc/_build/latex/Morphilo.toc | 5 - .../{source => _static}/architecture.pdf | Bin Morphilo_doc/index.rst | 5 +- Morphilo_doc/source/architecture.rst | 6 +- 32 files changed, 5522 insertions(+), 141 deletions(-) create mode 100644 Morphilo_doc/_build/doctrees/source/architecture.doctree create mode 100644 Morphilo_doc/_build/doctrees/source/framework.doctree create mode 100644 Morphilo_doc/_build/doctrees/source/view.doctree create mode 100644 Morphilo_doc/_build/html/_sources/source/architecture.rst.txt create mode 100644 Morphilo_doc/_build/html/_sources/source/framework.rst.txt create mode 100644 Morphilo_doc/_build/html/_sources/source/view.rst.txt create mode 100644 Morphilo_doc/_build/html/source/architecture.html create mode 100644 Morphilo_doc/_build/html/source/framework.html create mode 100644 Morphilo_doc/_build/html/source/view.html delete mode 100644 Morphilo_doc/_build/latex/Morphilo.pdf rename Morphilo_doc/{source => _static}/architecture.pdf (100%) diff --git a/Morphilo_doc/_build/doctrees/environment.pickle b/Morphilo_doc/_build/doctrees/environment.pickle index f1fe7ff4f12bb06e800accb161c3a099e8c7447e..44cad1ab2dc882083c923484739e0b01d6305342 100644 GIT binary patch literal 10884 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 IztSW<0DOWhPyhe` literal 5908 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 diff --git a/Morphilo_doc/_build/doctrees/index.doctree b/Morphilo_doc/_build/doctrees/index.doctree index 78f4aa8256d372d508c143c8fe0ef0613d2fc1a1..b1ce5341c9ec85930100b86af5caa390ac58d26e 100644 GIT binary patch delta 2956 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 delta 2999 zcmdm>eP3%rpoR(q14DUgPI7*3szOP=LT-LhK}KdyzIw4jN`7)_ZfaghVo7Fxp5nyf zsVd4)g}NpAx-f;h#kwd8H>)#tGJ{PGN0{o1%hbu2Sgf_w7#J9^D1Ov16WtM;^;wTF z)~ANDWn`wLq~;aIb%yd}<|XHprlh82=A;%E#>W;WXk<iX#H5CD<R(_6q!yH96efBz zmu9GYb7ly~mL?^ZCZ(1pW$0-(7ADmeCTnC!gfe7EW-w()Wk_epWEf`1)fT2`WT?bu zsK#a}$7U$S7N%whCT6I`7N%veC6;EWi+T%ZXk;*D2*(ztYh;*dHWp^o7G_Sq!!9k9 zl_8mt1U1PDWK#CziJT%laP>JET9fayOGxLoHWud97UpYYNMvMXNcm-``+<#=%*dE5 z&mvl%RGO2MS`wd=SzN+ZSfJThSXf(F1am6Xf>3TGRfWYM+e$P-*&u?2r4ft_3=CQs zN?=bwe4`c%3I<WIO~SE-Wg5w#m@CQ5Db~x&Pf0E20@)XzS(56I%T-ve*;rUnTUe=) zArZmPz`$Ttl$vIhke-^CnU|7Ukx*EbA(>GK@oFe1Ok-|gHOL(`lP7WtPu|VS$yhtt zms47^PP4JFzP7Ld<Xw=y3Yflv#G=IXqQruX!bXt3CQxXxiGo75dGcyb`S2Fa#=_Rx z!Zw)3dZ<R8g4Dc}%)IpYilWrC!gi3}4vkRuqSUmK%7WAgW(Ed^qSQ37KzU+OUSVfP zC?`lVu_!&Yq_AtUB9|g#_v8Xz*~tl9ob^2!{*ZtXjxFp(50lKioXosbuEIXe#=`#E z!U+(k$ki53geH>0NgAOnV0TQ;=#F4#U|=XNNznzlYf3640cC&!UNWN<<gck2S`i!! z3=FV<ES%OF(^xpYwr~b4dizV05;J5%*&r4d&IBjfL@=2Fij-Nkg|ks3B{x3>8Yy!S zk&*$9iMg<tP?(niiiP>Lg$qDF04baW3Cs*|&@Y@kkyFxqQ3fc)7uOapfhn2~RRj*> zrI=xy(b<vFHTeR!BIB~j1-x>wuoMINb$JFT&{otIu7sE-S6jFW7HF$AGA3s%LkX@m zsKK=uWW-u%aKXG-xURLaaD8pz23TmV0EbovER;+^`5PQe8*2+Ufr5z_o_32<6N{2F z5(+n?2htXJAZ-N)(ze>d?I0I}6mEq29~?+KK<U#)9OST_;E>u?TeushavM}7IHdOA z3aJ2IdB(lSAq6&VA2_7;*A^atm?l?Scn}s+hd?2<7bT<)qlVNjkb{n7XhpDr5+B%? zg-2T(3y;+n9*2d~e$;SEN}SBgCtZKSFO)YeKffd|za%xjC^fCP@MLY_sZfrh)U>?B z+|=U2)3t?XLIsK|bCdFO;$bR_3(v+Do(mOBEG@~0i9vLqk1f0qDuSjQB6Tsg@KPve zaweoYDK5MmTX>}&R1}5sB$pNyrRIT(yS&uGtA3$EB}IvO#cBCPx$(KF#l?x~sl|oY zVhgW>+*OcYRFYa$c*8H0BQqtwxFoTtr0}LUV<<1OV~PuJ#TMQU<%QV>alxJ1!n>gY znRzLhMXAXp@g<2xqUot6#fA4`3-5<=6sMMyWagz87e1J5%`e0LFu(9oZQ<j|ar|QS zPrMmJg^N;?^NUjAQ&K@iPikIrW@>TaQ@>E&oW#8J(!})C_~iVQ)WT<>OsRQ=&qFy& ziV~AklM<7&3tx1E@)e{OfZUK;l$w{ET3q<jFO;viq$sl>J~=-ZRK*q-zVZv@Ey+)g z2WiR4%*!q=d>zV~npaX(Sy=xjl&2^SBvqUmUs{w?_%>7~qokyu*h*i&BtJi=ST8fR zBuy{BC|y6JBsWLD@LecpN@7WBaY<rsLE(G9P@bYxP_V`4q?V=T6n^k#3KcHS1qEDb zeo1O^d`^CHBB<{C7+d%$lqWtVwYVfR4_xUNe)bFH%8*OUDS_(!;>{Y$3w3!;VsUY5 zapBj=69kmyzJ&^aTwa`$Se#LmT9A{NoLcxjlr<$asWiRt$K;CwB8)#LKNC=hDEt-5 z1~MSIr0{nrZ*gjJNnUAgd<7`73;%dChVrMB<`%@m6F_m{U%yb^l>Fq(ytI6%vVY!; zp?siX9aI4nmlUNY<`({+Tp%cE&cMjP5Xw=ITA-_HV3JbA2;vH+R%Did5=u#FF~k=| zOpFW+-mIZ)$@zI{ndwE$lMe`r%CRsqF!+UvCg<cQX2+-ICT8ZuC#IwnrGh+J#5(!2 zph^ZCBLhQcD06CFSrI!}HN>$6#i^w!`SBIGIYk^`VS&_&g8bst_{_YL)S|q^oZ=!* zu(%M&yTzqRC7C5TsSwW;ae>X`F3vA4N=}Uj#e5O><a!~|XdbW@{`}ICg3^-s)VyR+ zA)j8v3-S|dX-S%{MG+r}%>~t3T9i}757xt%nTMi90Hll)tVOptGrdS~@_QjsAtA6@ z&dikff}+&4%!(r6$zsB)&LUv<aF!${#g}KMlw=f%f&z;plrOcYD8C5d4l$6Stf3)p zx)w#^AU1nE#34lzlk0@VZ6p~P7&<~Z(^K<OixNxni;ASc_VIzE7ZEVhU{M}$a*Qto zr^h0h$rpu%8D%Fw6;@N00~sw)T$xvrSP`F*nVyl8nVwNnBo7j1$;r=4FH)GSC!%Dg z$jHEu@jH|cR0_l+{G<d@$CQ~;qzq#4rQ|0ghrP<=P7x(BRj?Cy;~}Xb9^8&BQk#5G zL{>{3><R9o#Paymyu_rO)RZC(P;fAY@`C*VD>I5TCv%9(IcS087&4S<i?kUT7&I~j zGm<idGW1JBg^Ej)ic2y}N<l5@cyP&Dq{GO-P+O!6a<@!|MuuE%k>2DqQ7r|1Mh1r1 ZA_I_n*+3DKQe0#RR%*n^z)+f`2LQq`C364( diff --git a/Morphilo_doc/_build/doctrees/source/architecture.doctree b/Morphilo_doc/_build/doctrees/source/architecture.doctree new file mode 100644 index 0000000000000000000000000000000000000000..c7a37e241c3d401cf38326992cd31161cf5e8614 GIT binary patch literal 14558 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 E0DnWkQUCw| literal 0 HcmV?d00001 diff --git a/Morphilo_doc/_build/doctrees/source/controller.doctree b/Morphilo_doc/_build/doctrees/source/controller.doctree index a0523de44000e258728112ae85166c7ff87ddb8b..af065b89378efaf7a1237ecbada92a78dddf1af2 100644 GIT binary patch literal 265566 zcmZo*N>0g7E-lH-Db~x&Pf0E20&#Ow^Gdi188sUVnQ9A}H9|S_5_3~aDhpDJ3t4Il zSv4Z~7#J8ba|?1(K`IkVGV}8a+595p7#JARQ}a@b5_1#^iZb((GYfK374p**@(WUn zAgb8?A_N&27?Shzl2Z#xN)vN3s~{2_ei4ie3=Fk?5n>SelA`>aoYW$P#FVVk;u4TO z#f6-HrJ;hwrAfslnI)wlTjNtw(~1kZY74nT`3e$?ic{lrQ;Ule(^HEJd14EBHPAg* zTv=R_nhR6JRmi8=Sjb;nD4-F_S(I2_oL^d$oLVRt$`Hy{kXV$OS5hd1VM1y$$YQQS zVa>)uk=jC0jSRt1h76$$5MQjeP#nf*3T1<uClTSuz`&rNk)NBYpO~ANl3H4<pPpHw zpPOG)kdc{_AD@z+tnZ7=foRlE&d-B}f?iQ^NugvYdr4wCC@Ko2LfMNU4k?rl<w`6m zDauSLElDjdl&LM0)d=NCDJ=l0D=w6a4P{TxNh~f-EiROg4dqBmOwKL>g_%NZD05~? zaiL;tp;D+A!X{nh@K#O?Wrdid5?iR6!I@YZ%94|rms+Ui%@oQ3ODTow8BC!Z$r+hB zDMhJyg&MJiniv6Jl39|I%2lYP*;uGuTd1RvAqb9VXSfd)9FgK#H$x~xEJGqgGD9kq z6|A*TFGHrbP+ucME;d6xHbWscLoqf(CAKs}&6_DhJ%cGjBeu{0J+4AhD@wQu4e{Az z)Y@2RTw7?Oks+9&n<3$sq2>oRPAEgWG%2w(DMJJtv8J_!X0V8bIxIsP<RWtv7ZqBB z3SuU0%ft+o*g~rejzo}i&A{es#1>j>WPpOhrnb-)6da&z;f#?j>@tKhOd%nW0S*Ft z6bqq205{Vi!w{UmFb#5SZ7g)EEp!HX)DFd?HeipUhh0HpQDS;gVnGI1p^Ii?p=)iS z8_1PfObiSm8L0}01f!6gpIeZhmzr0ikXfvdlUS6Vnp4SDT#%ZanU<NFqL7%EqEM8Y zm{O@wlCMx&oT`wSr%;@qo2rmenwL_Pnxc?jq)?o%kd;`Lr~pl=3K@xcDLI*W=?Wzo zsa!ev>6yu(Qlum!RiQXFu_!r1p|~_TLm{zPAu}%}wIVYwT}L6Qv_v5>r#N3BB{dPO zwLG&VLm?%zC^fkxzbG@c7~~MHw9Fh3t5~5pu?(y&xhOTU1k6fF%}Ir@KrSvVNCAs0 zfOY6``Q{g;=9i@w=_n*B6qTlAg36=BqDqj5iWG7a^Agj+MIksaiZY8qZcoWfOG^b6 zA__(MU|aK2xQa5<GfIj<0hJGyOwm&Sg=SJ>ab~hYNosONUVct~dZj{AYDQ*W3ds9N zA+27l011oCVvr11acWUnPHKssf@3i>Kyq>v@>0tclJiqi6*3ZwK_Q-$s!)`go>^Ry z3JUAQVueHns6J3cfWo&tHAy$EC@~%6CB2H=90iSx)S^_74GNA0iOCtM3L*Kq$%!Rk zmn3H9r50&|f<7m+7!+IzF-56q)j7o_R^_QlFk@;JiZk-di}etRH<S~epbFhV8OH-# zI<|o24bKe22<_3NHegBZQNzqZnb`28wL-7f#zODfLZ8uMYP6Ulv6w=x_g%r&VFswu z^Q|rP1Er>31_p+hq}24xJWxRgE%<7qa}x8?OB2&mZ6kbrbdnPbK<z@?>R?EztPlh( zbwO1@W*(?G<-#m!Q!A2Fiwa6KYjtuGlTveR(aKSs)Z*mCg4E=U#3I|8SS}lA$&K77 z02ikI*a}leSYaBFVHnZFz`!t=d{7wJ+E^G=TNpez!xuS0_<|Dzdiy9TCqFqmzOXdE zB$cZ$M6<Clw6-t|)<lH1*h0CHR27DUs=Wv-F$HOHYQz>sf>T{oZDBMhRGJwW7+^83 z3u=Yi1r+5crxq7G=NA=}7DLmSjXpF{K$O7Kh%UG-WtUu9T#}!wms^>fUzDnsn39s8 zSF8u?c<A9b5Mn}MOomWKD6|O*PHnMR{NU{ZYJtaP7)A^hXUDfT7ADjdCW0EgATLCL zqY>1k2W9P~+QMW|Aj^OP85V?gh|tSTEGWp#OSdabL9}5qz`jq#=6g3-UQ5d`j38)c zdTV20Mr~mx$Z07kZSf?qBQrqhDXX?H8!bI$fRj)T76-tSP%bzL<<%DEgM3#B@*PV0 zz#rq_RK{gfT9l((kXTZZT9ju83!7s7{G_bZ<P!Y?NFub+M^;r611`U+bMma9^0hS? zLK#`e$)*5{yS+U?$)+&FFrtEPPQ`R-VNq*iVR3C?$zTYxJa7_#rPI>d!ZMJnP|}nx zEOo-ut6gC^dOEGZ7TjL2bXtj?PO+I;)!JBCU0YZKN~h&0>9iE=NN_r>tu3s>nojGn zH~^kb8^Gzbv9_=Y<hyE&$PY<Or(Q9K+c0Pm*PJ1gQHz{bTd=s@+Xs|ZTQdwJ2HLr8 zt&N54wS^s^cmX-R5gZ$^B-2@2*aZqylq7?#XzNB#GCkOQ4Ue*3^dy7L%)Zvf!v5OA z2_UC+qa>M5up_}qW@2sOB&<nhG8PBG?VkcpGE-{{r-6KzOL~$)F0e3)wUWeioJCqm zVmi1un~0o5rekrdcK|4f%*Zf|$f3FO;Kdl&b%irq8w+RE7S0~1u$c;uURWBOQ(HI} z<Pv32Fu=kZQN+Zg=A|GvrO^}OJZxbb1S`AdXBb8(VK*4f+`<K|jfD$q3m1{%7UZ_y z9I&sz32$+2;S!KBRZI*Fe);7(pcXxJJO(k;l3G!cnwOHAqL5SxmWK|5C4<MfK|@f9 zIh9qZDWIX3<c!3ElGGwD@c0RcV+9>KtX0U*1C6zy4v_09fQFzH;0EU8RO*1o(YU~6 zSZc9CMq*hibi^ky1>}a3jKmU!lEmy(h2+E{@Hl*89>{)BkEA@mD5aQ7BPKPsAfwtb zEiJPmxTGkvpdhtK4>S^|qu`mBmIE1KcFilzg$f3jf>a^|xB`k&(=sdI0=1et3aJ$( zMTyDap&`(KT~TUIYFT1li2~S0g|wplTyV&gq*j!GhU65IGg6bYK~4gVMV01d7M7;w zr4|>%2K>P4pzg%hcmcZ%WN$9WqeZES#rb)ONja%p#ii-#sl}i^SurR;L2gOR%gZkT zM}-2^MD&^gZdy`lW)5Wh4btr4%1={BO#}@(Ld-}_0ec8$j+cu+Yycl_1ZWr$>^YeA zg`nw<l1fn8NGvGGsm#nv=PCxdr?@0DIWb2eH$Npcrx<2rAVf8EgdA!r(uf+QHM$gA zP6>tOlw}!)5hYYkub?5Afl97JB(;K_NzKFxHjwhP3O0tSNfm4&_LN$<ytT1#MQ!2A z(L!^y&>Y}G6S+!X46f2sOOwD8d#h>-SHqg3C=+{YPzu(<wV`}y^WE#fvwG_@*ub-T z39uq}17ucjV{PFkP{IdIlzXC1lyA-u%2)+$NrI>JwxC!AozjCFxHZENJl&3F%C^?V z!tJ$%J3tNX%_t4+jbIOg+blb43wMEBVaCY7-~pcT0=Eb96cQDZGK*5wixpBUQxytQ zi$KkalFTyj<Q%A`EGSAX%giq=RsfasC7|)-Oz`wxUVgbkNoFp%odIrHBr4?O=VvQ` z8XBP4ImoPEvI1&Y!K8Ci%TjYdHEC{YNk)E3v7SP3Nn#PWsQ{j>1KFIL2$~;+jG^i% zK-wp`i&97{4BP@zNJ&l0%u6j+NXsuRQb<n)4PPigEV2SMvhq^Plk;<P6Z2B4A%hjE zd8N6TwbdFiB^jw;wq`9Cbd(pw1+7>}two9}@aWHOY;lzYi~Kzqh7rct!x}uJGRQ+4 zT$)oJ*hQ&GVVwgS*9L_rD5#M_8ZsCSl7Iws;ojE9!hN-c`$yAj3MJ_kxv1L-DG5NM zi3e&655mehSm6U6O+17pLBqS;hry-Dk=nwepjes8$iNVjS(2Iy$v@SZCAn7VsU@XF zIkgG}rAaxN$qJxOL|!^5_k{-e1SA%LmJOvAY4|z^L5Hio@{@F+sx-N<7?zx0RDi`a z$XJkXYDr>BVo4%N=H->Z&2ua&O04wBEH1HuxYG{gP*4LqHLt|2C_mRNGbfb<vr|%w zGRxqG2PBqcfXs6Ni6)k$f(!$R5o=&xemUH%%)AniQGTVlNvTEtY2l#G8mc)8Sx5ny zA(U|dTA_dosbg5;)H@9{G;ut`Fru50fdLeY;G9W$Bw`pvQ50e^jY<)SVKQaWhiV)J zkym)4wXyJIZQ-fWECvcw)Ut)LI6^O9D2SyDp^PKo(iAqrb-K3j3@FBqGcz!NhqDk> z8CP&-UUDjAxBxo&0vhn~t#r;0N(GINq~@i7SMWgAJ1HPaM;(RC67a&E#AMJ!A80fO zAqg%z!Q&_88JWo$;8B!}l9B?2qSV6D)Z!A*@DgaLRdGRnUU6zMS8`&WLQ*Pdg%Ws` zQ6_lV5vYlkmRVF>qL5gWUJ6?B19BQjG%+c^EEU>dDuygeDo#z#&r3n5%uj>LD`<d6 zt&l1JP1wj(D#T}?nIzB<PGX)yX;F>>Xz@>ODx@K)m#W7FvJf(`qL2w*0R|EPvC_ca z0!MpdNh-t{kVc$B5vZ!kgBV|ym{STK(E{m9&n!#LLs+4w5K>tH8c@lpRDgzgX))AU zAh(p{E2LH=XC&sOr-Ix8T9F27ih|Z*K|Kt$u%IZvEHfpwSfR970p31^+nlHXs)`iS zGE;NF<9Q&LfL2ezRz>P51m}Z2Q(RI68s366PeJOCLI=KfQ;!SM*iBC@A+AcQMF|ne z@EUl17ifV3WS}h(ynIceJR>zv0TN0e+d)g(z%Br*hB!};3*>)js~KbfWRMa$n!%9* z8fin02v7|Nu?u7}G`NdW3-XIIOY(~<Ay$K=z!v7GfkGVOsLWz`l1b51aLh|lNXyJi z1P^OM!yl2zKp9sP#k+ansu7gJARbSuR44{@Ix3;6Kx1n-!xLP0f<nPBF*j9HuQ;<R zRYS8DG`0q78iA|Pv)HQ9Y*<_WT!vx9L1qR9(2(=U%KM-Zz|pJ^%3D;+`rw||pvw73 zkxc)L53`)Se2*(Iab)|#^R11A7itSHj#lUJ{@iGF4yv<8t8;LRb*NV7$U`Bg!HswD zaK@$D!poqnzLpWZm7yqA0W>>WQl1ZO+=6x$D5RF97Qvd2y3nx;1@MF_(lje*LqK^^ zW=TnEo({D2R#22*lA2tSnxasap9yM>=cQndf4EkF=5{ml^E7L96d;ZHqEyIM1xWK2 z(V{Pg4T1Uxhtz_$N<bPl?ye!A<{zl3pHi#?nn%TMe@RAWUN-8;0m#nGJgBvxR1V)$ z0BS#hcQK@<=qW(@FkpG`N-)r#h0NT7{Gt-jWG-kc2gql|C7@YO(9A7peW5~TN@^mg zO$O2in-5h;%t_BL$}Gvq1@~?;ixpBbiwklRD<Lh+w9=d$g`Cv9^pXrvPXw~_39^F$ z-1samO11*~0<(Q~1zY>96xKewnqe5Rg1S)*u2`ra!(d|rU=a-FVToU`IGW|)fElXM z3##OiVz=;GYh&T{+QJ*7c@t73fHKk0$(zW9?IlEEd$YFi7AQg&5LiMFUUULqLl5eU zA{DL*;B*cxo?%Pn;YkN=kv!on0vbEjR4B<P$}cZgfS1Kw)#!6Qx3QHkRj~5qPKIH` zeEh5G2ZN^y@3uA;-m5LVKV)J7IVIhMq$JP`#)I0zhgfGY9$|?l_zcEl4RD?Rq_*%W zC;(nEFff#4WESgX<tHiFf)au?7i2B~G@6qNngjq%H7MAEhTlP~(qj0e1GxL3l#-gJ zmy%eL3L1!0(nQf6npcvU1JXo<_EL~qB>kX4b59qDMwF=&h^_faS)MLP%E4VSJnA!3 zlr*gipJfPTJV2fpc#b8gylX)d11~ZRBYsjEIFB0UAP3K*hPfmM5Rwt#AVM(%e;_?- zm;(+b6fFb->QTd-%oMPO!k4X$g|BK0UxOypK>_y!lJr2E1>V#az6GToQ6>fkef`Wd z1;6}oP<zNg2Q-wG0~s7l%&P*=({TAZ2l<1S$}41~<`noRWhvN#hInD=$QQg>v`DWg zwWKIBwJa5`98`}(G<v$|rKgs7=7CyQ$*CF;Z)<8=BdxMeDoszztSAOepV!uKx#TB9 z#&WY#@^fAClRZ*%3KVQ%_UnN+xu!<=`e<lcb47rL?A#JTyJ9O9DhkpPlS?WUY!#4& z^)g{r!_>Q06cnWv7iZ?@*|<VB{o5&26u4G^Y=N4g2igY=nm|+1*Z0d0SJF{%%giZB zEh^Sah3L@G)U@V;>Q(@WDcC~H&`Sjks)DD?ii%4#ko=%&&84rOmRSKBy)8=2D^5!- z0_|eWh3=IH<=I5Y=p%f=0w~N<6cTgt^HLQGit<5Q7PvsuX`nzXEiTTiN`+)H)VVcC zE(2w-%rpfJ&%Bb<^wc6f@QDJRc_kVk*Mg!1w4q!>Q&U0FRsmt2Cb;H6$!G7d<+El` zK6?*ZL_N^S2r~1RlV>%EQ_-V_IpB2ksA2BVOG%F!=70+oF0xWn;fL17!jH9upGM1^ z(K4q5Pnq)uQbmDUN1tm8zd%|?GPQ+YF^eBiLqH?8@Ef=_^u4z52PkcoGB7ZJi?-ra zh&8Z+uOuJRC<0eKkWv#=cq8gF&?y6miVL;G_H_<Iuj|04DWqyZ^=n!e{>%`{_>9~# z`Gx6ZHSb<fiTOLjFk;{w`lq$A@NaG5KTxXx<mm6<AWzJY$_Ot_0te>*+9C!<1_n@g zih~ZY!KkED^HRXON04iXB1W(l%)?A3WN5?|F)=bQWI&EBsjWdPtih%gF*7nSv^Ey8 zFfuUI7O{fO5{$ra{eQ5_K~64W18ZZ4YMaRjYSlP{mf<U8Lgrsf3v%)kL0bqQwVXnE zVlk*P1<gr=_BN!Z<rk%L1?T4!Ip<`84*n?4DS|X|5Mt042B_9V2x_3TVT$u}ieN1m zkea|!(3o3c5vVx=N?>p?P_w15s8X*uwZsiH-CC@nlnvek3z}3^(os-?H^`xEaMKYa z0cnURft$lzP$R(BXu$PYDJf`!8WM=czqW#sf}@`cSP*OyTnVCu4^!ip9}bp<1Qe)w z0c!H*=M=%3WT53n3Pr^^B?`6*#W_WKg&<FA6c$x#f`TR}wYW5=q!=??iog<>>4pOw zX_)C|5-8npLekB4`bH=`fl?5kj~eD6Via8EgE|7xZWb~h93L<Nzx;3*6WWSLjbkJ; ztR6MY#f)c=AZkp5L?FolIj%vXAa$VF2C=n~n}62eoIrAXqXZi)x{J6V8JioNLwUfF zEf_JHLm^QD@1DbQA1L30Qv^5<f_TWW2Fb;sI0I#I+U3wJP<e_dU3tNA#|MqO84L^z zPWkycsfl?CnR&@Y{>jM-whARhrKzC44XD6{#C>sU324(-Nn&OmXuncUr9ysQDtLKw z9%xZeZfS7|Xf+RLP%tmGJf~6t(y2><rbKW{6Hoa9Ds22pbKUYw^HMZ473>rYHMy#b z_(25*sA&K`Y74xhs7L_paLf{BCa8oF1Zgmg7}TB;f@C3Ka5RX3eIu9!@o5$)ZXhug zqS;s^3RWTpQ4-3KAyZo<4(6cy9u!0xu|*Of-@9lw7D<9NN`ci1MhJio!-Gd{T4GLd zs&$bxNUcy7$O@!(PLT{)54!nk-g7~rD+|(Nh}}Fnh_B?qHY<Ql5zK;G0&))6S4i!W zB1N!DC5XxhQM9HBsH_GzCD4Y5ij=_`FdaA#<UkdO14Y1wp%h?Xvx-z9j#L9%tqwLx z5TDgqAV-2-4sMrdfc0rY^}Plinx~(eSOVI0my-kDZwH>6gXCn$s0(~3Km(i~@{4Q} zQ*tx&GK))!5=-(yCspO8fDZdgRY-&z0iMPK&H3f!mw@J+;AXfufw(!TX(gb+=VC6* z^}=vD1zYe*TNo-pO%)75q_z`oZADt3zy+l=q|B%d4hziKSOAI*9gqgYh>;dfx{ySs z2Tm;d-~bZLf&^X`C<P(XlL1(XAw)?;Hv<C$a{Q&ImW1YI=jE5@fyeDMuq?lU4GZaj z+k&v_2f~BbG&%}ON;<Hz9f<)h2v8cl$%#2R*{PMF<!zWPJ0q|&F{643D5^o5N-_*1 zCXwj{=y(Lg;W)hkQHA6KXnm!l0P_kw%cJ<D$OIB2rr_WP?KJ{*h6Y`5XMvIfB5|05 zU26djb-@TwUeebuFUl-IE-CWU6ksU^R5E~;41$in0}m=Eg7-_6<SP`V!go)BN~YY@ z63Eif;?xq*STJa~RiP+9AJhTxbq)e?L6tFx)&Lvi>7t{cq_2dMQb0BpCzhqcx<??@ z3Tb(ep-YS%2C!rbG8eS%0JN+TR1kr6fre;7*6S6e7U$=brD`aZ=9MI-r>Caqf|^BX zd79Q-AWg-3VBc#L=)nD4jMYuxq8`24ump!AX6juAO1)N)f(n!}1~804BZ}ZrIYgJ5 zj9`Xj5^(1Y6l(Z``ccCicwj^N4TORlp2J{H1BZ5zH6(}GfYYokIIKt0Y)&evX*LU# z=@CVM9XL4cp~2Y%Zf}5_5vdBG)tx!13TgR8=naQ*(BYWSLyl5YxFC6~C_gzorC7lh zoY4_E4XzAFR)c8ML9`Dvt&1E$nFXyG;0SgiX6{-8%3V$%4TceIRCoTPhB*ii;7Y#O zyx<H;tuEl;bp^X!Fbm?ZEKrz(V*s=R7u1$^1FLd}sERnn!oX0=1>R7RQ(OXCh@P33 zUdt5<K2a6a`GIXy$OE11keZ?ZU9t|UQ}aPfp+IUNYox%725O<J1{4yDi!;;niWNXp zO`z!{$l8499t2PkoR^vk8u2R02N?-oxR1R2j|<#r1f6;d+Mf!t1XR|S7K4lj?@0r9 z)j-pMsR|&|pv$5Zz}p=2K<ocOBH-d2!~u0xiy<>tNM@DfgSvQ-LpnffuzbM#S;5Po z&?alRK&ux@(=(u_ufk?>K!pYP=v9Rb&_>;S1?WDKL<PtJa0*cWf)@VgDIog~bgnHp zvQtXIXTK(vD3oXB<bd2$S`1mKg*eZ)EU_pvF|VW;=8F8%5(Ut#I@-2hJuat8h1}Fc zP=^*Wt_Zar6hI{zspvIlDR_rUW=d*a3F7GBL<P`+1q!fT6`*O?<ovwilA==3Dm&Qn zInZ9063{M(q*SP%Q&YH-Dj~C)kX<C;2~GvjbSG$E0&Iq}7`*r|IX@={a@Yy{+!0XV zfDc61Q}6_z-lzbY0R;_qCMOoB!j`gu>S)j|oy6keQqZnw(1|Pgd63RKc#acvka~U^ zbP=Clet0d&1BqpcnK__CN)$ATQ&XWmcu*5F5qt!Q0yNn}Be%H33X;}9`%S<KY9W0e zmE6P%|K#M-qGDThLv<BR@Q#!6RE3m$1yIihwooxAKfgc$nqI)$FA%<k9GhHP3_0x= zvM&haX$8>0Y6_C8Awig#rdyI)Tmm_=r5H4J0g6TRtr+=`xQ34*gK9F6uR*H>ixYEG zK`kgGeV|rHNh)Y?1f1z$5v`{X4vJ5ZLYNT9kj%Wyl1$Jp5%~BA^rRi=))VN0sS@yz zb#i`QT4s7FXv!FpwW?B!^7Xhp(-cbcQbDJ&Kr$_C_5(8Kp$W>;8Tlz7+rUY`BwqpK zMo1Xp@GK;PKq&#)!RR|miafxj9A-Jb9=fQg$P-eQA7=rTf}oux<QIbA^@78t3<Rwe z#8m{M$c>hOgR}$$Cr45XKycI&Q~o__m|^&+VI~dAK)Aa{i@*|ciohZ-NMq0&+|2U< z7l4AJ&Ae2F(PrLgGY{<s1xPDmw3!DQ<sVYbJftPdS)l$bxPuFx((nZrdw$Sj&ytye z0ku;Hnuh`R3Tt(BVI4h?7`Po%lv<XWm;-JWLwBYlcHm^@rGxeirRJ6BC}irT>VYQ@ zL02Y$x|g6vDD<Y3)V%b}yi`2}H_)bkP%jT;I#)7e-3F*nny3I?k^t@pL0i|ERiNHy zNJeTNq=B4YT2fG20^8UFnXgm;O<009^MFrX0v~vpo(Z~B1?*h#u6S@?Dl-ps^GGpV zH>@$Q#|7<Hfx1(m1EN58zQDRwAopjcKr9D!MPOD#G6+;0bq6?j6BO8PXqP)3v@1#> zH7^AeAmIMCo<cb2P8i7OKyhjbcp*qF7vyBCg8bs*%%mLf$ySiD0;Hh=@O?GVp&&^2 zrZ^R{^S>Arve0eo5QEcGOW><IYC$J&f-j$ebdllr*MI^Z+^Hz$0?kWhWR`$0Ye|H5 zxj-vlkQWrxDrkVNU4nK9^Q=H|2#JPTO-Q>0+%E%<QKaSP<m8uwyV6Ce;GPn=Lt2s# zj<G}q=wvikYF=_aIBcM6eh@vId{CdVC^auR6&!<LQ$f4zK||o6n8{59-6jJXXDH1{ z0gn)XF3SNYnS6yr@V>X)(wq|T<zLD9rFkXAI$WTs1n}N6P;7t<0UMYG-sqN>TnXxI zft{HGTDO~-2AcBD1l?5wS_cG)b&SrGKR8oicBb~gI#U6V&Xfr}(}A0lkkEtVxkn9? zk;F#x9L@3^xD`!<EC)81vK$9C0#}AZN*yCEzZC^STJAyMDl8bB+XN#<t1$Rj<Y*N( zT7@Z)R)rxq6hTcxL_;wIoXbL?x$FQF1A}Lt0!pQiJm(H=C!jB3fUi7(ow0{WL#uxs zSUUjD&;$=ngDinu+Q(G{K5q%c0ae7HF=<dU3{-D}kB7<x&wW4#O0!cd!Obn$oIy%v zadK%fY~mobpd>>fDK#g*9I3Sg@>?<JV9qqqts$U6V$fhZq+Uj}g<<00x*2q-9BgI- z)LaBj&}D*d7zJ;)0`(f82R`X3ASR4JCV;18K&=kYM7Tl$=%hYS3k)OzYF>hlBn7b{ z1K?l{;2WC~OQ33tQbAkWq5V~GgDVf*l!ly-1=av|IH++0J}D|80XFZet`2J3KxP#o zmmz{0eBe-o9#xc@0-gv056#1ykjN`jz!3w=YM^2A641m|VhMPrNl(EEddxg%SiK}a zJ2g)sF;5{ix1gjFtN__+4X~F|6><`bOB6t-9e^VM6r~`qLo9|27wbYM(=<V?Ht0D4 z2seXUgP_GzxruqD;N~UtRCUma=+GG>P(-F+wAaGGX&bY>b_CX53kNGOjM&MDNc_+W z7?dnwD`!Cd%cvguNgwJpQ0f5%7&rmdB3h&{@gbJ-i$K@-wl)?;g3GfgaFhy0>_LiB zST`3XP9f=U=tnBdbFkQh#OjbQ&yWw8&H`0crAg=)q7@Y7C*`E(CYEF-a}`B1GB9X1 z7R7)QK`b;8FflMNBqV@V*~WoI6l06x85tNr_Yj*DB``8DB!cesg%l7fv7xM>yCqUU zvc^S;j0_B=8A4#IL2Dk8AYD6%iABkfhH47fwp6g$;5(VKK=zj=C1yy4aw9pfC=Fy< zQifp!X#WhXpnlXa^HIZ0<PsB9MIZ`3cy$Qc`3)|t!954GBukI78f-6Bi|V3uNC;+t zLogE(f)Su?NU+cu!POXYn+=lmVM|xCz`>Ob4X#dBaJ7}FP?QQ;WdLdo6l8!`3xKLv zNUchnmRoW@bSS2{G$|z$bZRB&Ov;jc&<c%I_^F;&;Pp)4YfPZcK*Xt;pzQ|Wr4Ass zgGSg8?K?<Qt5_j7AF?zg52RM1B(XRf)D(i8D+)TcJ*QG3r4&4XhBW+>k_s6TO3X`6 z)#FlyEE6eK0Nv@XP+pXum#&bMnw$t)f{+JZN(tHyl?q*a0>0@zF%LT7pOlK^0z(5` zBLgl~&pd_1l$1=+S|A;;=fL+*D}XPJ0T;oLbt%xGF9(NGQ7LG#K}o(sYFb)ma%L)M z_z7A%z}GZDhqypP@kxorpe3QjAlHFzLx!Bt1RB-^U-Sdo@&#%{B_`#UmT;-67#bMp z7#J9+D5U0r_V+^$Wlc)01RbOb^(koNGqt!FG{6QLwN%J2ElDi`ougl%P*e&&;It?o zw6+IP_CUrQVGBjT<r2sbc{sI!2Na<VKG0wxXsJzUP6=oTP*1@L8sMNr2^rPkf)3^u zmlhP{gIev7<r2lYi8(ns3W)^;Mfnw(xrrsIIiRblOUhGI^AuFTQJ|s#I<&V~2PrVQ z;DHHhCYI*qWM+f(mE<cx;yDqt+znJ!=qM!Slw^RtS^~au8l)aP)Cx{%pmi(7pb!Bs zpMox6Q9vwSfrmPH)EB(61QZ#?dR(fGkVpcDLSAA?X%V=gnqHJ&4!NMb2(o|%x+Nzy z5xlw#q#0x;C|E!duK<d9_}V;BW-bBUd;sp^6lE5JPV$A^dk$WYqKACyFQ|DBs!5R6 zGUY=S5rJ;{29K(OMtq^?6M$OI`9&!TC6xt`9Y5f$4xr?m3rZi5Yly&h7l96~1&xiS zCFbOS`a320NJHkusS4ngSxKPV#zF0LF4z*Fq*Tb79Z**zzepjq0(2iZ=!{}$5`hiM z7wai_rhyj^K_x(|px~0QGtTl#b8^7-9K1>drAW~FIq)Dh$g=z*(7o%RAz{$1RiNDz zI-rAyixd(|LCds2>$@O#Vky8jHh~s(Wu|~GDF+oQsjySoGKx}D6%Z@Wz>By*k(&rQ zz&KR_cDs}w?B)hgYRs&{xVNDw2V6))+7=428H%ycYc@{9Iv=@^7DXFzg*dnhMyvWY zDC~WYmf?A$Wq1an=m(cx(0n*rhL4uvR4T*4Mc1G#!od@_)vyx0C=b#n$p<&G3&7>K zV8m!6d$f@~+Q?3>9BpJn8p)vECt}0EXd}C{IF*i#Y~-O4&|nB;It#S5z7Sk$7ePwx zPzI!<H9@yd6%~UeFq-4AV;hS~K&^4m?x0ezIb~qwf)T$!r-*_oh-lqd=s=1-_;%sU z<Ww-7mXnxX3};0<fVxz+>d@Jjq)PSJTJRcu&?W}Z)-F(2FB#HT0e4RzH&P)R4%-_J zx{@O?GcUDBA0`4e31Tw11B#difpwTjF-^Z5Y#yi|j<Wow2sFN-kO-Oy%+3(X0tGAb zaRTMwfWZhy?;D^&(h5)@8b<s89Zyh_nhWw4xbi0=$R0J!gm^6_sq#_7OhUm1ixQ~u zuplBU(1<pRm>?^vgft?mz{#i@99pBvC<~OUz<CvVn^92>IDBfM;lm5cW}w|Cptu0_ zri<!8NeOXnCFpvTqI$4u%(QnK)}?L$X)=u90i80Imx5^6HA3Q~32bLG*c8DC3_DS# z96;^^I~csEvIVTO6{eGsfx!_p&Zdx=lT!*l_#rbt4>pnmK9@YLG%p!6MhF_j0gt7@ z2RC(4H(P-Y6^3`~!N&rC2Rgua=fKApkoM$6=OpH(mnNpC+M=HI>zkhfzMjax0Cc+{ z)H!g2AqNg9_=0c2tknVU`L)Hg8vS5n$Q66=Q3m8o?2xC6HINEha749%0}3;u?!qFf z9THKXLx-pkkf3=@OwS;PBc!1}*n_dC1CmZV!Ktka9EgGupc7=M5J=#8Lj0iwy^D0P z2NOy@1?5agJ_R)bKsOE67WF_v4zm%^3zoo0m+(eFA6OpL3g`z%!2~d0Fk%4%0|RC* zfUFYLfgR@z8ZQN%#avqKl$xHIheg~qF9j}Io>Eefs>21F6)8?F@lQ@h;YZ|T=4B&9 zK+7>w9dmMA5=#=Xoh4p05tOHdvOqzATwzZF`vJqx-VZ<(_GFMA!=d57DUi$ox)Zdv zXd2j8f>}^cgQ5$O3Z{c2Zw5pO<dh}Qfo7NoK0-rFBerN3STQK(XM;7*0rLeTDi|0T zAiFdbl1qz<Qu9heLG4}e`O3kNvqF8-i$KR<I76hNf*RoS8bE42^V0H*K$Fz@c}RjT zpwlwoNlGCnAN_bA4NdE!xuDn)$^v-@IY#G!-G&*XFF-LmAEd`{VBNg{5>pGoA-M?b zTEQ%+XF$OVi78NEF9s`F0#Op7$-uw>Y9wobj!({1uvIXyR>)MafzCofZ%wmS$kf&b z9VNCD<WtPhSq3%?Gjv{qLT5Qhk0FT`f$sEZZ7f;|cIzsz@q$@U+d&?Hcn4JctOhGt z15pA=c%VC9uq8Zjq-w+#tph6tg~fWX<_%!JU<4?*Kx>3y=UpO>zJ#PbI3L%sm*6u3 z!5a>s+btjmL4nK!i-Hm$cpnDxA(!P!I!cJ%fRc_9xZ+gOQA*8A0iAA{2_`|4O`v`b z==5s15fDQmWg;j)Xk>y8aD__;<(C(0m>OtWE9iqdG@y-riFpd929Vi2@LrJAijtz# zT+qxNYzhzT2jp!D&{;*$xfh@TYDnPdfi2Mhli+Lz-wk06FJBQG;B6si3t4l)QyOUA zw9>CM7n0!MJR6v0@Pr4Gf~3EVptK~E1&VXz+_?!Hftcy<EhznM2I(=3*viPj0E!5R z`xOvgA@)pDaKL~=ocPFn)G((Uba>^XhPj9+h6;eA8Ol!01D#K=qX0Xp9?XJ8Irumm zE^ttT(hb-N&@+2SM5J$l6m6ggtS#CGj%vXyXi5NOU_@B}Iuo_FXa__Iq$~g}GsIRF zfRm6$Y|$=I>Hrl5yTL^PXbBtWTq{uVsHdmLrLV703f}hu+7<&n^BB|`fS&IUYlq|} z7kRos>nvM%8ct6w(SW62a3%qtYa0f-)l>s~TCE=Z2xjmZ_|UVKvr7~bON(<-i&OIy zO7l{{M`P&1a->3PQB`VbdTO2(7gTw2i9&925fyGAK=K5r7=haeJ@{F{7HSXbO#_fn zN(LV+44NT^j<kS!L!jIaO2ptfZ!RQ-XzD<%I4cDZ=?odBK~@VofC4<;1vS`8A+y-A zv?L?H2(*E%XfG)Kgt9;}k6a?`1E&GZ65$)DMA#3~1GzWqQNuFY#W5^5YYvBahJ+Lm z@r<O9U_2wKB@oXCAcep|a4tOrj$OelXyk*kF1QdtJ{j{cSmhCj%7|MG3=E(I2wqy? zS^+xc1^u22@I@7AiOI-UT;Lw#(l5tx_l3T`X9;LHAhlSbTo-iidTJi@(&o&(WKdlT z;vy;o1^Cs#pa6h$NkEHAKxfB7s!RA~8VXhl6$S8XG+;MqXoA{hM?onXvtB#~_B}=} z@MU5IWrO1&O@<No7#J8p@jyz@fKFKhH7N=*GIR1V2LScKl^)isK?WpvPCydRNpO-l z1r8L!ENGa4(g`^6WPn<er@>0jK$Jjgkh5S8dLTjrTO+pU97rC0oh<ksXz+@)c+j2- zuA=jhwXzq$=3fM9$pEchm8mVd1m<9x4{{19nl3XkFc2_49yEl<RdfYn$5pT$*TBXK zMpUsfFzD--r{?7;1f?ctl%y)8Bq|hV=B0q^mhk+dl9I{-g}lt7bnu1c>8a_dNvU}X z`6;PI3h6nipgYJji%Yl^6hP@y1G(%~P*X!Gv=tN-KtdWCsi0<wV@XL-W>RTMDzv@> zRRoX*tb(nr0%&R)q!`>K*8?BZQ>>w+q^SwANTH@ifq)q>Eih9xH8mCV^%e3;ixjF# zixk3Ai&8W5GEy^3ax#-MO7qgWs=)>;fO<LkptG5E4Xq&}$gNaRrbE7e2QF7z!=+GC zR0+`mHA+EWKQRTo!VxJq!+Z@<2@Wzyo(6dgtPyNG><R|N-80yN3}LPks6qyXFBGSO z8iFvpQZ-Qe4+=2D;f;&@WCd*nLxd5vTwDqYurnHAMVv0|Rw7VK2ecwAKMmXo1f6t= z>KpJN3CKSn$AJ9=Vt_E{oW$aS#N<?k3eZ3bf@`Y)XM;Qn=V&N_6@t1spiAzp^!3Zj z%k|2Q_413-^$jg8E%hPtC`VL+HuHdO0mTZ)S_noohd>=7Dzt|{Be_970f|M4;7jc_ zAO~=QZ=X`qM1&^Tc6eh6WVZ`AjzKK{q%73d5?C>Wz*F8PmSnhAV5^TnW|kI%!WKvE z12Gy*!t0G3P%o<jv>(c~0$zQ9PYM9{B3$y5HKBO{tWO~|Cl@VwWfY~RDJkfH+JCTS zt`1rh!;PqgCKh;`6tuY;9yjn>3ptxXTG)_H6g5!o(6%;ci6*qItp`!20WlbEUtnos zPG(6Zs1hp5&rv7@Wp0p_sN!&4NEdfN%meMbfm#Z6dNSxRY7NNMQEuRIB>44#3aQ{r zU7?8|miG1a6*ANFK(}Rp0}x^in5@kZ$^sSnkfv#<2wJrOF1L%WgX&?K+M*la5*xiD zQ1jIU*VZ>dvgq|dNor9pSJ5p<xqlm6?%x5a%Mgrk0-qE~X}Mo?7vwmhEKr>S^#lvZ z(xQ7Hahckp`(W#EIr;%el_9m<@(@yuKLY#nG1y|kET{uPo(EUs=s|=Ca;~B$kbrs$ zHsBe=07xbO9Lz!Y2Grjgu|+Sy@}L&NOR(lwU_P`4e+}kfY6jT@s=?ndGB9L88vt*? z+TVe7K()UIb1=1oYyxTj0MZVv+dqP}e*)_ejMxI2^i5O1TPv%nDNtA=Q@=LO5Xu6D z10+FZ!P5U{u&>a=LCu#Foc_OnWV4`2{VO;azJY`?1S8}L2Sd?!P)Zca0)-#cT38DH z0X7AfwLd}n42iPh7bJQ92D|MK*i^wRsJ$QugOg_#G!6a*tNI5~1xbVd!5nmlK;5hn zTg1S`zyO{ZWn=<f2*kt$xsPZH0|UcgjN~F_kb8x)Kt6>8c?Ni*k_GH;bZ^3<nH8i7 zGCP9PQ=n0`{Gt?4YZ5dzhO<2hJ;hm*3r7k@Gl$eRWf2<__<kmKaCC5hy(O3h^))Dt zz!47Gm&S!Cgo-$s7#K>EQXw1G_z@D|enJr!SQgrkg_RlHU<-I47C_PpFPMWKh(cMg zB8QKOfguZ8X7Gcx3xIV9MntkOFhD9UjJ7bmxeL3y1gWxw%hlF!!CJx)V~A)6gD%K} zH-kaCzzrl=JC)2vFhy-(P!pK+7BJKw$PHkSZ@{&_f&!wAi`F($phNQ)-ogSm+UeW+ zCB5-W<F+rkO<#&yzTgI*0;r7)34Kr_6do(YwtI<f_M*0KDQWdWoK0+-7n<BrTfAT+ zKm@3{3o5K2#XY=Y7X%kQ=!F%mVJifZg;ngr;Ic{tB$Oct+GNg9ogtJ3D#4&;!fI{M zExnlI`Y<!aAhif10|P^KYh#f(*i;ELQ$coti)dJ#ED2U71yKemXQja$bf-gIq!C*r z1C|H13uVEY<-mMs!%iN|!PE@02h^}r0J#!0_n-*Ys{~dq7-0fx&g7LSfD1{`I0d}y z#a}LG2xWmB0SPEbU8@W>65R!AzC7S2l?upy!w6%-_JJ2Kflly%JEgX!NEK53sev7@ z4z`IR$Adxv93N=ap9a_hO^5}MXwd?5(ETNp1q)eir0P!xtX&tZLonh$GXn#({(_`s zf}=RlLf=0*Srash1dbKTsxC@uu39cGlIty~50I)Yh}XgO7JMv*{*@NIbfkZsMRJuz z+Zv0^3X78Z3RGTGSX&WUSy8R70y~+=nhKJ_QR*p>_F66lP$dN_QXu6dypqxb7ZB)0 z3amoW2g$-JDFbkcVh9q-5R71E0GB95MxfGEC<|2FK#hjgRmNbIxQsRd=`(~IV+tu% z&A@h;gLMjKLCpqP3@#yIHI@Zfl_f+Kq-eAPbI>h=x=SOr$QmpUs<CXqnr*>+XpLnD z=3r_D*#oMv>_O!!bR@$8tlbf;1FGE#%)!(SvI(T!8KfQBD{%p9cLnPZjL-tr)LeMW zVrVG_Du*+KvOu;&gBdn{;087e-F7u!0dQsK4w8k%pa<A;PmmB&GXvx#sF|>+^8zcu zWu`YI>R`<bAF!#uU@eHo3&<{%Nb>_L^M@#dL|OotgKmvb7T84^u|<I(i$E=fAh6zG zuyVl&4e%Hro>>T_Fe?fHnIV(~vK`_{NE0CxY!<rJuuuyFX)+|uqHstGjsQC~5^TI+ z7Swi-`@w;cm?4#g+!fBk+VhP9n-L8$0}@m*U=F%_g|c8tG!`Te>-xrl^~ZyRG6W+U z!HJCW3Y>!ayOt|MC=28(NEE<Jp9HWI(S4=nD+*4#i6B{6+D!ucDH$Y$ly*Trg_;RV zyD4BLxXet2#4IfBrh!dO2Wvs3U65Vi=z<kE8DM3Z5M_`E$pUlGtr5xsyGSFpC>xaN zp=Cx6SbHv52eiz{19LF7gKPqo8TlaX&@!U{ti2GdLolL}fq{X-$Rsx=!O;lv3^d4L zMNkpgY3QDTMPo5Y78Z>qV84`tgfavpEGh9zQ5h&Mg|a}w19cEA4U~h;$K{|3kUql* zTaqk))G!AzF$o%f)3h$Cgk<?Du%D{Ib_!-eT?O(eN*byGtEz>lf~283FbCb4P#<Z; z7S)60L6uemSaTzo4^2T$U=F5ckUgLj)C}?^sPJq7>um)q7mP3m?N~vZ=t6i*Ne9n7 zYEc`=NTDo{V;}(zDNEbIMx(n#%~u4Ri#tG?3?r;D?L`k#ymog&!nzCWnQpL+f>}@p zfqV!KYiJh=JY3uZR@n<t3GP#ann2*tLAr#r4=j)Ac1Q`-4{<xFw5V-uESdl|aw1p@ zq_hAT39<-mdn(St9Z}}Pis(sTqb5U*(q#s(Rsi47NbJlsw30(~Zy;?yQ152oIyVE? zw;{D_L(`rOc^w-H`Zb_NK1E}2#C2+@)u#bDm$)7cI8h__XFy#UE>O0^(wvwA&Q6$_ z88VeT6(kF*ho*t^-*k{rhG2vaxJ6k`bp9)v0V)`TvOu{QQW9pts-Br(BXPN57D%5V z>GsWrlzwx-uAU3FLNE*J2#{C6<qxd2G7qe3K13Cyrda^ypt}m{0gc$Ag<yG5O|uBB zc`=v|t!b8kIhdM3_JC@drC@oG=4D{b%fWo8<`rNLre=^mAk8bm@*vHtz?xTs`B2Sk zz#L4?AbUWX*Mj9imE1b8=JjB{U<5yCY%dLT16>KUe5@|o01A4cERZdbD1%g98^K!8 ztx)ro09Rg{K$;A(nztDeC0oE2Zv~qom<6>2<Qj04fLGUT11s4MQ38pN9bgW+tx(r# z#1`!Y*$eX5F0kI+VC8}lpp}jEFWl*0s1sY5)1(k5t?(wZ(9RIb0woLNl(+{R$>?c9 z%~uMX68C~-A&W{#PXdn`=75)!fi_-%wp$eKgQVX5;N%55ksGx9--dyKfpoKx7PARu zfzm7H`Kd*zX{q2#H@J!pGJ#J|Jp{J+FxXRq5i$%64ER>U6&(TP2btQUqaY2TY(=SQ zrA3)pU{S?b<daoF2dRSG04g1hfixKsHvBjwEKY!(bP{9(c#*157RZs18Ea0s4~kBK z=c+RdBS1UuK^*~W#GT8?YxL-oYd~%2q%2PtkV8O=^JtcHz-ylo3-Q1S$t^RdB(<nm z54zr41LOb-bI+rOIiO{Cpc{D!EW9f^4T-ih;AlGwiM9yP!Ahvtjnh9)l#mun(kwod z^z{+3fn!-Dg>j(-iV1=XATwZ@9<sP2BfK;T-2XZUj+gV$cv;K<y7d#Xh!MI06`nze zm?b8nc}kVGX$G_kM(QD60Q&&5SXKZR%NHSK%tGS42cJ-cEW(7X{iK2K&};%P_bj>u z$uXC~F>?j%FTseR6EmO`1#VTPW=O%4*;TM-u0cJc4vq(6x)#+%*FjMylm%`}BE|O& zuu+)ttpbkkn;=bw5v1623li$L!4ACxHeE0aYB|XDU@w6iig&?E?m?758jAP99CX(} zU9AyY^Z?`@P($${SnngSa={2raEAuEKDX#GNRdz$$av%i#}lw(bhFib)xkb}3eseV zX3{f=U!H?4djZxjm<2T+<N~l?kVj!&f>pkPsDzKgpojTuuso(qG{7!-191s#6y`11 z$ai2Zh*21jMPS>J6UTe7(hq1#!Ceoe82<>C$Fv>NZTy64`)9C`U%*-rwu3Cfu>C7o z={Gc`;9e7w?cc%jn6_(y{r&^h_Mc!Qe}T0iYzJ8cvmG(i1R9QlOfP^~SY{na69yOR zzrptZf!d!2?Pe*$*GGW2qhvyk*@X*&wpM^vv=^tA6oa<kq!xh>l>#3;1G?G|a>jMB z0@Av>y!;Zl_SzaQ&}ta)#vr6{`wMmiX1HmC!|fkf)-b}Gx=t+m56J)w%%HWXjLeX= zs8qHjLnsRr&ZS9N(U6tfOkmrXp|(jfFfiZ@sv;I<1_sbI1gv1yim^p(%nS^nESV{W z=0)txIPM_;Nt+dMFhedP09g)dKXZbNGK|1)9~U!tH7GaOi9BFSL7jJ@ERdtYjpr=* zl?0$G4Y;a{cp+N&z*_hrT0qlg4B&VM*$!SQ3N8`_z={MRiXcUz5SW7=@j_YP1fmgJ zBn)yks7Mq6>lFnn7mN^NU|`6}*Go)E0q_4PEe37L0UsSuBnHwUlm)U2xqK7{>qNIm z%~uzk!X!YN4DlH&3Gt^C*csAb!vwRSc7fam&a%jbr3_f5EJP)|umt-HDdEe3<uRS5 z2X>Y`#96SyQUPqFB3KKezyMhUwjH^!R01nihAIV}Y*h=rCrKeE-?~TzWH5C9AChZS z!Rj$xqYrkC8b}l5m@E{-)FDBm0k%>TY=mGI)CQ0{FdU}^R;dk92@e|Z(H2OK(E-b2 zI>r#}7|<wth9N|AYh#ff*hqb_7DUj1EJC&&b{~QPShXQkwFxT&Lk#E?F{BfWxEzZW zk`wblmqr$Y4v`1lr2#JJU?+5eckF=9?gH(N1Rd9f>!2hZh4j>t5|9eeA%3NK*?IZp zdEhf4!N;p7f)@^z7VCg^%oZhr&X-q6R4C3&Nd=u$pPF0(I$j-YGkAw#PNf2<50s(+ zxhX)83v_I`LP1e#a%ORAP9^BFC)n9Qs5fyUN?=WpO`!Ap$}>_SXT8JD0R&0pCgx=p zl;$Lsq^2n3gIrS%Izb+KApqz^_sn92<ebz*P_ds_0(KZ^10&>kbntoYAhA3>F3&U& z19p3tLQyK{=7nO&DH>?EgrZasnxH!!Qo#WPau4`ESBNt~Aq@&~kbTgj)sfDPM;vPi zyYNX*0d)RVPEl%NN~J<-ML`beT*MTG#H9Q($no`DkbAU1=l6q-?+2NQIMo_r3$%FA z1Ya5kia^M%rJ(49TuYS*K86E&UIOUa0+6GjM-qY#h|esB2`1(g=Yua#NKH|IT@nD= zT@Ja{6}&4wH3hWY5@ZeNBmo8RDf&9#D_lUX0iQttcL?}E0nkMRpp)t$CkcSB#Q^Ds z1a?Yl5hN@TQ-TVJt=iz@<-j*pfOkN{FAIbvd-zuG)D-a8tABDb$ZMeerJ4%)MfxD8 zgX{vkEVCGV@FU1)pliQUxggzHP%2GS05uoDMu3NJ;fClbglB**MFZU)kqkP94jQ0E zsS2rurI}@kIjMP|`!z~3xXLpUOBBizi;-e66Ljeu(zVpZMafo>t7gC#4HTDx?#xI9 zpYxxVpIln3kPo_Yj0<)NM`8{*A1Q!0VL~n@=1NEa538xGD`X^sH72DhfHyaQLIC7A z__em6EC|*Ky4BVnbUy(oBtUx_K?x&24V-$pKp_MT2S_S_#71gfNoG+h^a41AeDIZU zNH#)xlPS=&1G=~vbkl4S<o+~_(g$R38fbTCd45qgBwH23oe41t(lJHc>;w@7bs{zO zxEvu_I5jT?bc2IJW?pd#=mHc_HiO)Bh1wGbAC3o0-RQ^n8G*}F%mUkp5q5r`F<6Bm zcm*rP1ul-``v$nY1-U9G&uTChw@{~zmbS(4OGcnqN{^Pd#Fw_9R78cswg`0Fb!%gh zDYz+S1}+!`BUo5Qn_{K8pn4B<@at$(EJFd*Isi2>iWNqiVxTs;24oW=ycIP(n_?(u zwSszUi18D1aDia~Eigc%5Rj`HLHB)YWGKcKS%Jn#m@`w%imY)BkuYbbm=@VUM@T@% zgGNYfA>CVuiA8phPOUxIHV24ppp#*<K=z{zh3GRfFo2tm(5o47H6KAmXHK5gAa6ZF zT?uI>LK=^V%U&U(gd30G1J?1h9g7?x;p+qrUuQ`8M(Du;a<mPe3_g~da2p)?W&==4 zhK#m>M$BBmLF)<)TF~95s;Cjd6_SyvkeriPTnxRU096{?)`xTmN;1LY0pJ^>K?4?f z#U(|h$tC$kTq&sqnaQAX30r>*bX6KyVW4v@DTk6f=ff=kbwp5|r3X5|9QiDABwNrA zA}`7;ODsuMfKN^;<W_=?S%(}GWX+|orGRV|=$>ErUE$zc0E>z$L6;sX6haPY0gZ2$ z6y@hY`ir2hdSZz}PAcf0Y9j;m-jEwO;4ync_VC`2JEXt?T|JCDW^iRBav}zlvq4Qa zq!6ps;{qSzS&cOIh3l+%<gm(5Qy3c2Qse<CXgtBW!3!KIf)S&+0W`8m%iMrmE`drS z@GvZR7Qh=E6F!ib09C0OtDpn*;h?z=U$6v5zJVXM?gx@bKOrZnG$$vu1bqGkSCKz6 zcvVsW*q%U;a_ABukj)UQLb;K26a|4YqD*a3Fi34E8$_xogqeW>Jie?2x`k08HUr`& zmDth@HD6coAap1*=DBvDQA+TkNL)o>5Ql_=9Rk`N2U?fq#lXOTxF-@cidU?Vm=3x< z($K&_6*Np$l98%VoSF{m27rf%L3~gX7&_gSnOBxtT#}id2)ZbuC=%-SD3IHsPDI=r zDU<~Y1yJiI8l(<XEyRFb6AM-@m<84@lm&7kBxEwc2b{!#r6C?hm<IE9Jjg7=2rBy| z0g_P@!R|`}I{@xJkfXsV2y_$)Cp?IYl0j{_B-rI3DPXOs5Ut=zC@uXAp)5qSLp+xT zR)Fa_H*lP$gJfZobs1n2GeJVojY?XeG@1n#P>e0ghPE{=igNI@HO-51LGH{D$^y9% z6dQSv5Cl!^Xtg#L<%6v$0GkS#a06M4*2)Aa)^BYrDg-Mof+z+jP>?4<CWGsK*c?YO zSXl{FnF9j@LjmMo4%Bj61AFC&^{RkUkgL%yS1AKqfEk$X@M^9cq{}dZDlVviq>)On z->Se?3ub|xg<Rf%ybew+;PR##thffE7_+>o1xsLf0AAkIf#pFtryguj1DG!u;R4z- zn~_<phg^z+4j4vhVt_Vwq^Fj+f?5!eW(VX@HVsV$I|U;H(7~sTpzsmO0yz^o3pRo6 z!El$aCpeWhgESdZ&k-$<fNcePu?=jsU>4M6Ab%r*vmLCY1EK^niQ5V0pgR@nC5_mk zE|6nEA=nMp+XGfE7$L;Kz>t`d5|ZzmUj&|maB%`%U(gFuEtCba2RS_Yz`D>aQS<cy zhetn1lOZl6CqR5R5p4Y=ut9=ZP<udb0{aem@^&&<<rIiYa2^BgQb3QQsbG0bC;5V% zG!5b;P__l_H<}JMat2rnVuliA5!iNEww(!9HVdlkC5Xp`F*yltxFa=^OA@nF!50hp zRyyYgr9vkaK$C$5`6ZzFhQu83lmuvQCnYll)FuWUY+aI(%7t`+IP@Or@(jp<sS1h3 z#hK}OkU1UDUD%MuG^E1-yT2KJDLTk3=v+o-G3bsm&?Fc5%Iv)S5{2Xp(1p+`3Q3g; z;Cr*dGm8qKmON;RC?h|m7&?=gnOl%wRFari0-DPNO+TiB&-gDX&xhQp4w?2Wwu1Ip zU|9>6scJ#fV_cA46Gqaih0QpDDpb(z8mUDJnR%Ju&P}lb$cOpKsm0(bH#xsF4?Jg^ zn3uwpoS$2eSOlKg0Z-NxL*{XE5=%hWp=TC@x&_IpMWB!Z_mGkkbCN+bs3096tDvWT zE98~tCZ!f}<)<kiCgh40z%$G627!)3QfUeJVr!62@Ll1cJK~E$vok3Q>8W|3bD2Q~ zC!$Rtfo+ECNzTs$#XHzAh)j7t((TmX+vh+lc|aN<p@r|RwOZZ0{FGE^uLq(WItP?g zX{(-?lAD>A3BJxMzepV%1JKwhE=ep&wN(e#JH;8PDeAR)T#k7upgvu4erZuLWEK{x z7!fA5NVAlXi8JtBcp0e*d8y?&l?t%%O-)fK106&Unkq|G$jML7Oa@J+7o`>#<maUn zE2LH=CYR(?f;3~DK;#0oBS2vZpSp)kAcE460{HfHP|{5TUEW=g3hn@dE`NvEmY<hX z2@lX@Xd=x>RRA4P3Q7>U1(`Xi;Peg(V(``m*o_+sAsMNapj1uhD)8ChLIAUP@q<^b zb09^`3velcKA|>RNGO0i&)CZdu+(S~Q9@J^0S+vpO9-%PL;>-rVJ1ou@u*=Yq>uos zgOm}E8fL;v36MP2assS=0E-FO@Cltu3CQ>i=y-JS4Tp0fZJBwXJYO^)Tto;)jJ6Y? zMet}l0krC5w4E@l+X={hT~L1k+<^f1br*n3g@uq(0kf~W2rPloqJZ~x7lYapppM!S zusKV?$^|1@LD#H;3LwzUypZ-EzRCdWZN{L6bPPT-z!d@HN@OrI+5z0t$V{<S2lLfq zYxOdOvOqpW?iMZsyAi`nzER*l*m97E3?n*03&%?+y;&IK1(*-ObrEVHfL)2z1CJVJ zf+fKh6zdhOfRx}X!C|}#?Eb+O#-P{-rzzOL+G?;<*Fc>LN^;;XDJU>NbrP3n31~h# zH@_$qyn+lgH<VeH3Tk-6mzHMamxI@XLOMa9E&!q?F9zvGwCcev>>@;gUR;t|P^^%d zSC*esmYSlc06zC0)VT$<-xa{!8_+5N$T$qN?+aSXnOFjDWrNqvg4_aXi9@@nkUlO* z0G!A`_G3<{Xe1;+%!CZwsH=l|OdvZ^`V7dEDd45G(3TI#7vN=)#o)jJEiz3_0e3Ax zjzxH$3%(??801`q;?msQ)D(r%0zHM`)Z~2d!n~Xu%q}C;Td5VGt9go26^cufKz%UK zWSpJ?c)Upg+;apQnwbI`1xU*TE$W3VrcFvL&IEULGfTj8UWt%pnxNVPB$AQ}nLE=1 zO%g)m0@8C&D$C3-EmkPb$S*2M&d<%vO9vZMl95@gkXTSql%JTKp`!o^U~nf2w2Csb zIJvaA7__`K4>T4~0O~k{dtJ#Hi3L_gsl}x^CB?Nm3dO15>yIHT7>iSrtuk{9it@{9 z^%Oi(i&AwIpvyWz>yS(Gxk~d=Qj0(f7C~bTprx#kyNvT;cNyy`_++9j5e0{ue{ymy z$OGlzUVnaZab{9ZDrg;VDQHNYl$lEZWXScN$*Bsi6(vQ95Z8md^pGeB0mqMqp(gT- zCCm|M)0O&K3Pq_UrA2wg(4hiQE<xB(44QC+Bt=L{0UM*EP?cJgk65aWJ`K4RoM|!3 z#~64gavfNOVZ;;Ap*~30Uk}$@U9=uj{%!ylY8%167mRocs^dUi=;2<dp)9Qd73_$m zHJiX8vKbm8kcBXy>5eU65yjY|t)S@+(EcKWqHTEQJ1mQ~L+3j{=7Z)tc0lT3h>=A* zArY_(Y~60K;gDGmkOR<WJwQi#AeX|>B{oRQ4Pf1}(Sn%Ff*2HlILcv=6cvkMuyIAn zR^XD0P$>-Q_Y$!#0Z~K_mO{8_4<v=}1*h<RkQ5#PI)4T^DUUWN@^e9R6{8Ibo#ey< zP}9S<dhn%XEcFFwt_pO>(|&OBJ^)GHn7z$|U<r(-2fVj=2vjM6dYgyA<{SYl7evh4 zgN#S+>Kz3uz%b7@1>Ds;29kx%+aCv;cmgDZJa2yzET9-$bP86H85NzzRgr<}Im4ne z(3%Y7Mo>+57UXEizC+N={W-8j=fUPe>M)SiXmuE93J^4Ne*vucB1AEGRuMFF4>B1% za}VonT>>k+3{_SLnz@HG#=%$rrKgr45=pUJQGPDCr3r3mB2VTg7v(2q8R{S}egg{` z!Ke0v9V6hkg6SxD`olR~)kRl8-b9<~zY2B{X85PVo08W+x(p)*#>v+qW$q1d=-mXn zRWJ+e59IL@P~d|5w&3xSTVTbvA&N0m@Ex!OhL7PX_%2u;l!Whr4Z08J3r2vBc7t3^ z1M41ut{ykE=F-;(-BzBMTmqV?DgfO}r~qlvd%8ep0?|&4EQVdroLp4k>0+p03))TU zSb};lCEDpRkfUC}C+>iffTlHy8AfE7VFbS0IXxA;S*$o!0W=*8+S!KWfnub)oIz6g zAh%*U3#BNvq$o4BEET@&1d(PvT|m3IJ)v9BG$1|(9YX|H3l6n>kPj#~*$8B^zCLIN zC1@M~(pLsIOzc5ntN`lhgF0a91x4U#;nWme&?2m2bp=@87#^(oMFoZ~pboRA3$DP0 zESN1VO4UzE1!c_C<dR|p6MT6j=z>BWhz|{s;w-<Yz=*1b8);e>Jpg4?p)64HM=oI> zg3~WXdiPBSm#~jOnhYaA2aM4#abr8G3URI!X^EUTvqo}af7CDoExA8xm`Qqq2M09% zBo97w3^^hpg$4-;pKMD&8Q?LbvUmb6wx5ENy<iqJSAfcLNEHDp*`I-xJclTWc)-BG z;8;|YSP2?gg6;aY1uaZafD3D+r<Q>3@=VPu0aed#nK`N8y-Tn%LPr5~OEB{7q2-{% zN}*b6Yq%ieVR}WWx%p+OxJ-i;3Yexr^dXD`twDntS)5sws-X$GZO#CEx(lM@1C@i| z(hq!Y2YSH(T48|gs-hxr!2p_l%rK02MwPIE-FSy|5+7y3gT+8fL#XH#B>B7sr;Rrw zD{X)>1SETa`T%diLGTU|1d!!`@4+1OS_E3#Xv7wM0M#R)to0GB_Y+vTV8m3&F;}n# z5@LiLJgfoQ1P@BBkOBN+E@Ww2_&MkBd-&2*OE6nWu(lN_Yk<yzD1zVru3rwSf)Qpa zAu1M4>!Qyf2Mc9^yoy{~egQii-Jfc{W#CNl6{N{9VlHic1ug{f`3qLgBK!sx$p!ZX zKo@EkeS@Us@8HPz0rrz%7Szk27y`#N^5V#!V3ofhDkC_+r?jQ!6sK}k7ySl#8XD6` zN4fj~tHlhd3UEmM1!*!wHRvD2QJ|}?YKs_Hz(+G>K}`qQ4|Wu|3D3v^I=zVrq6Crv znZX=%>!8lkh%Ex`G6tW3#R}HT239T@5dywL0J+6(V6C99Ur>~v1>P-@T9ODp$|57N zpdb~r+OH%ZbUq9yRe~1kL6+`8+L55r6uzdfh@FLjAwwt&<Wl7H!vVGz-I;2>)!<O! z1Zgs)oujx|AZI;+gMbI@6u~U0OF`iR4q@bI=LM_egQ$!U1xGt%z5;o2%DRXj<Zx(U zBc%ZWutrSZ)_{F02-0MT$5bJRbA`c<5CNMdm<6>8<T9{xK?4(@f<+XpN(`bZq6);r zTtw>$nh47*R>;gP$Vmllwg7LafUNDzOo4XCK#>cX@dmX|K>eLs1#lwB%}+_q0ne=^ zCWBUuf)*oYCW5Cp!COI**D!)C0!>drRyo5@S}E28O|C%~z(Q9+VwPLMC7`9JItnlv z-Wk%YRY=KCMOx+v+BTAyo2rmltdNqL3tk=!UbUE-Sd^2QS_C?RB^9#V6vtsET={ue zr#L~k$b-)<3ePV}DF&T+0$N)Lo_))y1WkrQ)?Q{pCtX2dhR6osMg?f<3cef@=1#;^ zFt}r-P@Y<ps!&>xlb@K9nxe-QoR75m8$6{3ssqx%N5&MTDu5aVC7=V0@)Z&xoi)@0 zk3jONpprf{ucQ`oeh<VNuu&j4LKY#z4TLlbQXnA&TFzXST2!e3%GubAhp2{|ucrV$ z?+9taH#N7Qq!OH(Akh!@KEyb5kLQ*amneXbGD-rSHI<pCkd$ANp#X9jXjM04b`w#6 z7juD%7s!=Kpeg0#<ou$P%)IoRN<D?(Ovq_8pyLBlOEU6PKvUbGjg6^Lk0s_oyj=ht zQi3d~Rwx0TumfJy3R*gxn3)Hf8U@W+BaSM{$pM|qlb8dWVb@Ur#YcK-Niq0@A|&@g zf)FT*ekV$f4?%P&$WN=+=z&jZ)!$@zI{nMJvYNtrpB(2xQjj|56kP*;JbltHH^ zfln8-f~}XO;*@|9)_GYYw24_*Sb=)Ic!%HMLu*JwY3LKO;^0yVvmC60kD^IH%EBUW zu?3ovMDj2f(WMr6g$k_;EwCkYEVDopNGLn#(TXgPJZOjOkSei2j?T%mqEUebHGQ<a zqJMcs^%+b$6jw!(kcO5NsPrk41{YR>qfMyMCe&yXYP1QJ2Wi=XCma>PGmZ)xbSRTh zrl3K6J8)+Y-20aS7gMs3VhVEtPYx`B(b$4d;K_sKL0v`#utADozF-9C3IO<ct_{4) zWd~^iL#FINQ+j!+<%n@#By}2^)?DDWFG4A(m6VeM4m!Ab#UOQ{RwZ)d*;c{8nhUf& z6EQOeYH}-Bp;!*uIjjU~C<<kP!T@<(K^g1`3{U%ZfqU92AWeot#D}Vo%18|yIqG14 z31&gP4T>>DLeKy!(S#_03<GI_Iq2a44KIz@B5hDefZ|>UtXCJTTrk21V;BfIcC<m0 zgSaQ)k=OU=fTB&)x=0UXk5CrKg~-vQ54I28d1}7>;Ak=cX)>g~V+<i7Y6SMOG1v)$ zSx^^(!T}tj$iqG+V3np2m3Rhd%s>u?1}@UDk2zQ)rY|ReeQ5#Ggm2i#65?Ddup_L& zW(j6Ntpd3W>|EHej}2IrEkqS~FL*7+un&57%nqy?(|wcR-7$NJ8wJ4wUTEF1A_s{3 z9Kkj_fz5(!Y{z0V@-hUFQ^9Trk3%|xwYxyIOR_RB_~n;_#|}Vyiy;$f`Jm0p;E@PW z2N}G08r0K4UiGL@lv<XWm;)L!fOPVq-Dq&<z9>H@rx<*iQDPpXBmr%u%?AyBRe)?s zPAo~y0}p{I<fkcsX8}`6i&BgAKu2MN#>ha6$DwB@Lq^148!I7Y9AXPLWKa+^7?g^% zkQrPY=2R*m&S?e@$LJ||mO#d_z$?g;DnTbi=YYJJl$e|iTDA`zvEYJw20VNNSzZnr z!~xA{fgB8CLo7~B0f!QF-~+r98+3p#+|7<yN?|>aF&dhnp)HTpyyR3Jh4NI;3h~mM z6oq8)XiHLlX$f>=IgXON7P{ge>dvCn#GIT;$icp_5wDa~(2jc003F0NprRlDfI=<S z0XcA3`X?tF)k204VMEQysUTm2qZ=A(u+c>gh=s7T!694P5sNU25p@mHiXqsbqh>95 zV?!xu0Y7NFMJ8lK3p_jo+7tt^5Pf_IJU9wEzB@Co1biqoBwF&*P<O6_(g|dz26Xj1 zXp0BRU>eA=MVZB^#gHQaN-`4j6pReGQu9D7Ns4u1((?05^72bkt3yD05TJu=ppE1C zxvAid--$&@nI%PuMU~*h1{(6sD=x?^LhR2jP6TBG1yCYT01ttd=%#>nv}Y!jg3dMr z4fyKSg2#42o6A9a6v|TJ!?;|qT@IOfC8_B};2~FN2%#UY06PBwlu*IBs~9v)Tbx{! znFJcd106~ZiA<1p6N?f{@{6E*+Cg5)038~SwCEWr|AP)E0L3JUN34OgWfte>fie%u zu@S|{TNNOV0U3{DOpJ&W1-i==v=9j?WkH3EU@1(Y0<>`+K758}Wg2?<?Fue5G0X3% z@bcRYQhxIjQL2K*N(QV@g^i_wn}|cBOocg_f+7{45hRtUV1r03P+{>+MtKUhj)=sM zl;~lJeQ+12Be67vr2|B1N7}iFL$oX{a)-2DJ;2RRPjE>p7%|%X9BqE)fCqOpG)J4C zB?_QIVYK;K4sI8N7Da>lW+S)xiQI_?b=x7Gc+g5XFK{X94Jk!2ha!Ez5*Q6t_)w%T zSROPS<p(y%AIukwXk=hufVDF+i@}XU1zS)jxj5CD3nl@cX$r~AO~sT-%}c>9k)NFG zl9`r<sRJ}=Tw07GR}=thL<?ns{D?e;6$o}DhNpZNf=73PK$;8(i4TGybzKNJa6`fF z7R-Wr3l!pzhy;ay7+6U-L`g(40|NtO?TtclerZuMD2UTjOCo%IK#O}J?Q{+3aylJo zKL)<zq9m~hv}*#qYXh4OBe;&D2vA^QhHxa<8JHow92~+?AWepJb7M3l3}e6n6bp8l zU>4Njpio1EVH{XVJVZ&v0R{$!2w$Jjyv!24;?xq)^t}9{RQUQ#|Du%CA`S4xQr27; z%AE6aL5s7BaVh{MRHxLE^3>EkP_5;dm*VW=7~+UieRxJ@NosLHVsa`LC4TuuxrsTM zRjC-NiV{F!jTu3SU_W9;&?;~QC4n><4vzpxhQxjfIBHYD-WJS)h6*UY5wV{JR+0`; z0zUawUmr0>1v<+EdC8!T0{HqVa2W<0bW2Kw-gleARZ>*RRb7+;3P{Y*&jj0n8TuQ* zp`QiP1UY(^Vh3bHe4hjMS}xdH!7Qk&K>mgJ9#j$JftBP#lt88;3cwt6XF|QB5nEIU zmIoC+;8j0G#bCZ*gfb%o11NnfROIG>X~<Rs5K{wE8tEuN${0;+E|=7jM9`^&AX$Z! z6zI*|$f6ohW5C<Fz-L^h78Qdp7(|L4E>I^rQvo~;1!86)nAr$s4uq+%4;j^it{MZi z4M6L@kc|WHlt2<tuvJJ&0qyj1%mMo;wForg3YrQ-x(F4d9@N;Vt$|F1LCRUsgbHXW zt`*YJi^ZDY9Sfj9N3NMlz#)hp;%dH|!3m=jk}#A;R`9~_5hpEli^?ELzZ{&dE5HFe znlwv@PMV-BjVK)|!J!CRldJ(gmR_c|s2Uuk=xJ3b3!J7kVvB0P@}Sb87Oc4r%omI} z!2~HCAUOyrPbk<bXn;xqh=e9I+km#8I)F=A9S2Z}tEZ=@06N$eG-m)h=@dF>4N4pk zjgYJjy(0}=T!54saDg@yAyk2~GH4xaQGSkJeo88&ywT7E2}giNb$#-a!P80_ntG{u zDaGNLB^eq@5O*kPYAR%EYa?%k0+|bTV{Hvp>`Bc_0ojtJt!+&e^AK~vAY-$sWh|u4 z4KgwZGdw`o?bLAT>q7z!e1;S#0wGI=K>-Get`f*$xW!hWd5TKNeXL2TXgA$KX4e#o zGSf3kKr>6A$%w?9ocwaoDbJwp1Nh2Oa6lm?Cs0%p8^fT3&Wkl*j!I4i=?zIOE+LRK zG&6*<Ksf`s2(JexbM$PX=DQDEgg1a?4I^|JNX!I9jgaE337nUj!Nv%ZZcK(y7AQBC zCS@ID0^c{$0yeJ|Y944?3@pY#XXvzn#6#JNQqxL{G9&mI7#MOBGjmGvt>B6jV>3`L znShuNI&+{MQd=P#S=0gXL?_tNE|B5i(nKf=<P6C91E-i67)p~e3?mjYF)%=~{G*0t z1C`|;HOzse-$xB|Vc8y~LZV)-2U(SxmjbbfN;w~7CL-@cjHXiV2N?~?{}5xrB>+m$ zjD!N9s2h@^d%!8W7m}hQCc~5NXl(`FR7_eei%7Acs)b7FRmlO8T0usF(`w9!ORVt1 zAGGuc)aUC1r`mo<s)h9VCV)BU)fcpy(}*pa2rAV<jk-x-y_3Pp1tZQeFfgd8ky-m< zw6D0-)D$#4K?@U7i}c{TV^OPT994T5=xlurO-%(G%<Z+P24Jh-VY)RHG>fKyd@7U$ z3M1tDeJa?;=mDhWdkkE^PXlQ(jJQON-~g4d;OYfbzz&KanGPxJW`Lu9CO9Ajv!LMw zN)O=v0(2Q()_F#717j9g@ob1<NE(|1=AZ{5B8|;uVPMF*0?|GXtbIOMhhT&-0|P@f z<nA}<@Gxiq&N@RV3uFx>nzF7lGBAJ|FAKn$(5+GPJpqoXg&^6iTM%0ofo)j~5`vz* zRGlG|1+p7z<~^vHOTbESnYk1a`=FDPs#_b2mVr%O4%Py>JOyMb$S!a|Wj%pdz5=Xl zB}5q{gjRt$=+;18q!C-R8e|bD7p?*8T?<w&7y(-C2Tn1_fm5^&q*y2mWDUeOkPD^O zgEgVsq2_xM96TF9nhbH6xDk>LHi0eQ3^qqF3u+C>MPTnGW=Lgmf*W(Gkd_@6m;+uq zxCN|pD@12R33!nr`Ta9;Tkl2NK%RuAJEYa0+rjR_44G5lkl6v!WH@k+-U$i(UEm<x z4R)$v7St!8a0LfGc$xVgu#&wHC6I)*56nUL8Z-zrVvF{JJO@fx2f%s{f|UzKoS{Z} zrUdH#DQQxpB(tNma6bg{r%)Csgpl*ZVX%MEgGbHx3^?YGfHWCKT%bl^fC_hLYkyD# z$WchDItGsR<KSQr%z}mzC@p|f6<X1L0<8EXL@^|NodR>v0}zqEP9qiVXTaLef^|U3 zu4*pCydSJ!2U!A%B6z`m4y*;;5;fm*;8;2jl7$uQ7r=I01PLJ(>>!(=X2J^gOJF6q z%)AVVd04@I1#Ie7uogtY4zddzOt6Ce8d%wNh%!j{+yHaXtr5xsyGSFp=qAV_Q2x6G z)_WVQToByzMhlvvJ0PV(Ss+Uwet{J0cfnfFZBX+)4-TArAWeo?&ASgt0S~|yKLnd1 zm<6>2<QlNo@D=Khz&am8bVeKj7wY=@@PopkBR!y%n+}K;K4e@7(liIJz0Cwqv!#Ic z-j_hH9D+A1OTc41sLePW?Ldq{JhCf^C!ipMreLH>;wjjlnBjZ@9L~=`nhb|eAUua8 zju+r4ehK!vU=}oFK=BSv9N<dl6<En@h!RMme*@;A2Ng6(HDZh2f&vSa=-+|$z6UE8 zj0m7cIje+})|50gi#~wt63PO(5;@m=1lx)3L^a>b;Mn{G(gZoxgyK#PsNhE=e^Aq2 zv*<G<biaVT{}t>M!7QjtL16+8U9`gY8(8soh+;@M{{VB)J%I@4pGbx8FR=FCU>&f+ z7qPYiR``M}fdmu0@cjeUf^LbL?-g)J{RPRw3g3TVJN|=&kP2Ur%}_I8g)aju=%^fA zW-_ueFl0auF9o%#nOH$b=P-k{APQfQUEpAX6}~KBWvmcoknmvxbI`33$^yGcBesYg zWDzJGa)9-6f|WxGU$mep;sPlZ$^uye@e8Ez<pyg(w?WPKDmZX>K$;+hFS>cWtl)EP z_`nu}7JX}E2xdVo0l5b3HGGAy09dCW*nYu*Yn%#!ya-KkNQI>^*j<?6at$0VA|Ooz z*rFDN1ilzJ2*trp70iPA1Qf2|zy}v@5@02uwWjcCFe$Klbgw~!KqIzD8ss@pqLKmY zl?5w@?AN2XEI}I6Dv|@)Ba{VlA##e82iu44JT>1N;E-1UX)>fvNee32AoVz;P*a42 zsuI}S%3x;*W<gyE3JY+kq7`Z?V8yBs#gI&^2Iio901>|Gtcbw^4X}1iunxfp5%6FE z#7UreMFm?0Sh)tW2NFu~a!m`Y3*8<y-<#lo(gw-G$~7IZHM$@nq;d^pIn+#8xuyqJ zg3C;ONZ`X7l?Gr_4Z&Iv<r>H?a7e+*H6ySxV~8?H5Sf5E=++2jfnB5#TVx8d2$TfP zz<SNW${`#6Fhi%v0;F0f3uF((JCLHy608f|5;fmj;P9~mX@cBji^WK5NK&u?TW<?C zNH7a(56Dem58^A`?7%whAv(clP=ju^MW1?e0Lx=K@iy3rju0n;f*W+RtrOTtXRsDX zaD$8lSp;@XYKBxscxe)Nw890f)D^0fm5G6&mP=nhGfg2euM*sx1&_JtD1iF63ZM~x z&}J?0-8IRHISR$8B?_<=kDx7OMWw0WW^5+(KufS@<N+I`1tp+cQo!=idF3pq9<;sy z*t~4099q=^mdk<4Va5%bWw1FL==3>wZ&`jCyaAq^3cmFyy$E!(Xc6fACCH{a==Qbz zG|)XcdFh~QeN%EXOF-MuGV>H5GiXTR1G<w3bRS{50_X%j_^dCiVGn8MgZ&K-7d17| zS}Pb6=07zx@Ug?tHJ_jn<4gr@g)9Yag=__Fg&gpCq1cz~K=)08wg<virh*Fwq_6-v zrMNV=wuY;gD><<wIYU7Md3%>aD)#j|Zs0V6nF8;CQ=mH}1v24JK%m)93KI}~W`hpt z2gNShCm&Gg4A$fW4+>&ZPmu?tQ1k>BE?(e-BN#DSxG0PkF3`dSRPBK4B5>2w8=Ovj zAn62B@B4x|=%o!}1(qMEyaCnw{$RZUVC9f@QL0`+QD$CAa7kivc1RIuRk5aZQ6NaY zP!`B0<eEPStPkB9HQ(ppLM<4i$q?Mw!fI#;B$<bToe%~#N-zs*6Ubd)A3~df;Mz7E ztTF<kGC~qOj07!$k#2hcm%v4lAj_d1M(S=vfi+{g_yyR-(I8ER1Wb;BI6D^Xm^iR` zf>}`OKrRG38yqq5U?m9<C6I_o1ar{shq_ZEwkQeY0#L*xgY~9>mE(z+RFHb1ERape z5t9bihi;9U?`yC((?Oc>L`(+6hnZj}WPyzm%!1kkau?W#$PtqbR+$4)32%gfm-``w zeJ)rY(@}50j>>~L3f2hA2OC)c)`Dn+fh+>sj@$?<1S>6qDg`Y?f*hQn0Nq|<T~rJ* z8@f6f$w4JxEtn2^3wBT`NE4(_j&5EVB!J4n7FU2x5zK;G0&)$+iO@D;C0JDzL{)@1 zxQYi~H<?ph0$LKBnU`J*KL!zU*n*A%blU)EePTvxVp(QRr2_c4f|7iN+{Elu@JXV1 zsi1>e6N@S#OQ1mex)O^(Ti}a9CpV-j<R+GY?j=l0P0r7S9X0?`l#>ZM8zV(WAtS#$ zwJfzr2Q;DzsyPv7yh4uT1TCTjpP>mId4-$^oC><69(*c5BJ8A2@Ua#O;8QIXQc}}0 z^D;rV|A5Yg$OK;&30jtyoLHO+UYZT!l)%^KK@S>DRe&0sUj!caO)AaINl7hI0AFVb zYBUz5a)F!!IifhfEVT%9yddbjRM16`MX5QJ3Q4KSiKWG<3VEriDWIdR@{3?*f>v=u z4iEt?4+S6A2|5q8A~y$q=mF$#67X>#@QV{c*FUBv7J*I<P0B1$NG#7TPb^B&QwRp1 z{s6igv{<1azXarf#2m2KAh$b$58qWtN=*aZ9}4nqK~a86DdZ}}vecsDOwh5k#h@@t zN(CKEl3tVux*}5#{V0HHaFW4Hp6}pC0n|W}s2Dg+p&jKinxtUSKZ27~Q7xpTssoon z_22|0I9djQmJ}<DmO<FcAmsg^pqdL@m4RDd4d67?2u(wvX&+c61-jBUGbOcHp|lu! zeK8lPVgn6;fQmm*p9i#}8#F|ap9Ts0@_cyFTMRkK8|4gdkQR^;paYCTGE$)z_NL{R z7NHC{K$m)h3hzWvMFV1_BGqEhL&y=6Dz!S$Gmjv{9kn`872pwtS{-oJ136g;)L(@h z@tm5NoB{Ppu0kSwz@{v*C^Hds&o1aVo756L1t)0z10DJS`5ZpOS*(zp4?24(5p?=< zQYz%UDo_moQUy6xhYNnSH0aJ^kT@t1AmIktxB#w-p&OGxrwpYkBqo=XCgvaq3FJ`N zj6`tMre)@(C?qPBCsu;20$0qb;G?*8pbh}p1hb_?2V8}LEJiq6j|+ST5ybJJi;qD^ zWG7WZ_OgMh)sl=<P?ejXl3J{%5Sdy6ih;~xg>tZOK^1mpUUE)pN~%IhD&*#3=<pFZ z!1F*RfZULp2RiQ?bP#=NF=#7r4(Mh$a4o9<Uce6xeg(9U0ylGt5cMp=-Qf9R@D2~q zSwzJOpu|-SxrI3=&kE#aumeD6AQk18re~l?fubII^cc8x0*X-34PmedD&_(ikP1G( z4BTvjCTei<L~=tG=os|kg4E<p&_>kO3X<4mvxlG#BP0h#QNF6;Ka*2U!3bWYUD~ z9|Q$uQYvN-I5|HjClz!@HgY21N~(l4Ai+Tdy4R-!W@BcWE+{UF6%vcVhj*0}m6l|{ zX5c}ikQu2U^#zbqp<p|*i(yAi6%^$sB_`!mDwO9Jm1HP@wz6jCgCi1rYF1_%xM>Ra z7U--o&`=Y^f5lwjjrKWtRv<A*6zC!gfr1`%Y7$B&2Bi>Cn-kIuRDj(54H`cMNo0UF z+kwjz*hnfg@h7E%$5&G;3UV@&GfO~+$@`aNq!yKDf-Zc^fTT#!o)J*mK#6})z(Z4T zT4H7nM!T#DTm)ja%f7<fWzCRw*&P=6HepaZuZ%inB<OG#Xd<RY5eYu{2c?7ri@*y= zFb@({kn#~M0E(#5;&FHtk4Om%65sH<5|Cs-5kEkMBa$mXS#;QyjZps~6^%$Dpl~0M zk`d|#SdD~SFc!5ydKazWmSG#XSQLyHZ5fWX4D-@KRq|-daI|FzYT^&ymLYO)8Pq>U z^p@MfWnu@kOa$GLts0V;?wns#P+A<ET2z*kTEgWIy4wh}`ZTko5_Dv7Nl|`|f(EF? z3cAfN1=KiA0iS`PkXBj*YP%|=<d^4Zg3sUu->g)SSX`W%qN4yFWd+|_R9c)`q+YC0 zQd*P;>hpn)a4iB|&kQv{Pr<2DAvq^AIU5u&`H(64eDGcE(4MewVjieVS(2EZ4jPyS z_gbJ*=<csofSnWzx{xUcbj~ffw^$7Eo<b)0=Hrsg#FErvXtz56a`!MwFw}w^3OZE? za`7052kL}Ey5aDPZ}K2_b?L$e$RQ^tr=;d&f`(K<r46V@l2WWtT#}iS12QBjl?!?< zEvOHem!bgC0vkI{g><1o{pr*^c<%^wN0mZxNn%k6D1bnR14BJung<G!)RbCCs~6<L zywr*ku%)1gf;cxPHLV0>L2<1@BKQ(jl#^&dqxs3;1rjM-rNtl%K*o5v`1>k226%!8 z9}-hQW7p7b7}zo3rWm+`h2$Ez$7=NyJoCWaTX+|yBr!cVF|V{1)Zqhl5J2{T`&gip zU`rCyq0v(diQ0mq)UwR{(&C&-$jE(a3iu%6N>E=r8|>i3oE%UZ1KSP>LXfKqit-Ec z!3QYk7o{jbj`S`qN`;PdfHvwwuER=AQOGZXuKh^SQ}D<yhsPC?u1wI`!6m6hxtXAQ z2w};p7<@`_P9kU)BQp=2zCl-S>5*`87Bo4BK$5cpIQ@Z+0k72oPs!V&h6&o4z<PRm z;59Oe@MzV`EOrImgQlSgUgeRo3VG746P(#G`-Kcl8R{8KppEZckbdDwW(Eejl?IO* zW|CJPfctsS@B^iNL~#I?p{O(fn*ffC;$mV71F-r*P!@pQL8vGID}pB(nw11#Yp@jr z&=xzkasVWSn&gLaF#s+atC6NrqjM7T(n}N5Q*E;n%Mx{x6Tvl`Z8bC%lUE8nYFLJ^ z6e#M3bb@-o6@D+c3=oVMt?(fgA_;jMqG1qZa)?6+<#LEB+Glf!J=pR&xKhu_v%;3q z!E(bVr^nDIs}rj5k(>LV20o;@4?ZseocsGBxgYbe)Cph-jHUtnu+)iQdC<C_NnnE} zgZY9HKN%Sq5cf7gj_tGqjU|Itex$;V#KTYlx`qjS(KAGuUSdj$20W$erKgr?7-(u* zbAei(`Or&zvr=-Q2kaq<g3N(m?gTn@OTktlD<xMC(unni>V=$Tr;(MPq@#do3)0fr ztd#s*$bILvpyQuFD>zai4QR-+4#ZU|nRzfzLZ-ezBmKpRWvL38C0qfC(7R+o3{d%^ zV5?A&TnzG-ODg0RShviaRFEvhO-k_0qXa(13nc58n41dn9Y__}Dg|4GqWt_4y`t3O z{G75>4N%(~Bnh%W(;BHK0k;gay)ZSe1axXD$V5!LkaXdS0g%RGJ#av1fLy5qc1tR# zSEmU&yPyx$U_@H6GzFY4Fw&7P54d?b6{OlQf`Mu1CmL|;ygDb(YJk$rqlP)4_yETQ zXwwQPb%7#_R_O-aK1$P0(KJY_WIDJwnE_5Vqs2)vXePM01l-deiNy)1a)H!YpsHpj zIBm>=ri~^B1_ph7&`6E~=q4iQ008LTKKM8XS4m=eXc6e7R8a39lqH-Ji&H~`d^9u_ zv=x+~Ln-<NrAaxN#Toj!(E35IA~nT6GsRX(K^s(ufb@B$XlNpzk_c<U)MN-{p_h5H z!4AYM^Tfer-W*7o*Gj4DA2rM&<o-tubJ2YOFQ(ugD4Gk&c=N!4J0I+J!H7W<xS%)( zrvT7FPoPAw0PN0%P<Mik<g4WZZN1^DE?NW%S|QXij>TYwn2{j~ALCd8(q$NdV$xDb zm@EU^wH$1OU>4YT<Q5gkDPXsO7f-JMD_#jvjM<`E1(v{Y2)sqL8Y~a;;To_(Yr%ZM zh$Kc(G6%0vO)LQ~zXY|BK;wm=<*N#b;Oh}`QcF@5Kw}=Db)=a&si2`W(4bd-QD%B( zUSbY(dl6)-7p$Y83u-ceM$A${BSbo&<+q@PLoh91S@0klEMIWx>w_Co`9-#gDY=<> zpc}ft*JSwzDZnH^<GFc>xvAhH3*1hCm<!r%l?NST1ewf*(FR0#1aihQh5~T&2g`UY zs4-;(Z3}{0KdER#G$4K8WyGLB0=I^YKv_C8FFP;495PI+QM3+}3WTyik%&A*wjLY{ z7_sIn1J27EK$;9kqo~9N+R_IFHMS_AN)&B`WXet8?6DafF@jmpcmw4bL{{7aR<aeM z1hS7|8<>M0k<bX&h%MR<ib_!K+X2?Q6Rcb?Vlx8+LqT#eIKg0VKPzeKDCq0wCT8YA zGnoQ7c_TD|CQy7+OA<ks*g@OeDXD3CDTyVipsN&>G<CR$Qe2u>l9>Zit)v995p;QD zNo7GQS6X6DajFiC0`30Ov@Y5O@{UjzC?JrN^KP)W&_hAZR|%Y)_kc7RMjR&O=SK~5 zKut`LD@gM9qlP)iJ_nnD*Y8Lgz`lp*fLIT*9e)_?g`}5#;0WCh_PJmdG+;on3{Ee| zyFw0tRUU+>jM&e>zyNAN7we^@g34Eo0!?c!U*{muH4>$H;MMWP3c2uJD4Gl?CqOcV z0w|0?1}WHrl!J;M-^9#3m;7XK+dKu-1@v^$w1)H(^HR%$^7Bj3dv{8Z!d(~CB!QWy zY0U*P7S<hu>ePXkqng%5hd?n3P2@<uvcq66VkQGEa56Xo(gaBc5c3Ct{~tBXfrbF2 zQA0u)9EBu<W8la=4)(cV7BpZ$F%C`!;041cz)DU+ltj3LTWCe8u&GJk)VxxKg2ePx z0<FrT)a2C6vQ&LgRDl+ydAe8^odN|ZW;~n*TZI`92H<!&1JYy|;Z2@99yQE?xdakq zFt?nAgvU9sXU~IOAeaSpASeXD;Q?!HT>z`P2vHTG0p7QPu@}g(1UyAnkPo`8pd7sV zIWHe_S7>HQYHl%jacgECbYc=T;!+Hqa|E?fAmfENhEYMy6HpUB6*L=~T9gV}C!CS0 zkds(k0$<o%kXV$Mn_7}u#06Q|3_cnGw2l<C^*Apj6SR2<G<TW^ab{vsQDP-zlm^s* zPRs<)Re~-}NGwat%mFWv1`Xd7rRJoTCFYfYR{17^+FKyUB3(ZUYUzNS2T38IDcfR& z;?z{oHBI1|zvTRsRE6Ta%z}bc@KN6wQ=8z{kz-B{iT8#gnOc&s0G&_<FJcANFffOL zT!%bo2(t{!jG?|hLN{nBbP;H`J9sueCm%FZ9OCK;o=<=o;gVRAsGz2%kXh_lT9T1p zlv$OU0^)=ACphO96{RMZV3};Z1WrSkY266k5Wfsb@5<mrhQ2w7*fa*7WI|73V8M}- z!eEnTum~gVE=8)QFVI{RZPHiK6-YUD6<k7H1E(&*(Gm)2DLiNcX3=N~g}a18?#qKJ zI&jSg?#o{XC#oBeM1|RxzX_JWD9hk|`CDLlP;cTk*q}RLzF<Tj=o+qo#F7lxih`ol zV$jA)8`m80_Deg+&1DL<3Ka!uiOG7P4r^vks)mw2d{_$9{{XGCDuRnB=_t5m=9Hus z73-x!jL`s1lYqv+G@#}xq$*fJjMjs0SWVRc4N<$~Cxe!R6x{_Cx<XkX4<mOJ?txv5 z;X_{=aLeRANRwg2B+|X}s9_F14?Sv_OSzXGKnjM3;Glm5_K08>)SsaEKt%Inu#zVb zC6IpNQ!oeJ<In)oh%I^s@;WGHpM&+j04o=a=mrIauaAFeNkJ)i6LUVC1sTnVK#~OY z4dC*i``Fw-m!6eqKqycLA)qL=q@)tU2S;g6K6pk3p$o!-^e{BQmwbSdM`~V)hNh;b zb<s<ZGljB19z>4TS77I&`%cZ*9vrQ&L7EH)onPKS;`1#yz~6y=AeaU9ASf2V@rm4z zdk<Fm0iqJVyB|G?e+0{8hJ_P2EIvWP0=B#VGuX&4U@eH<{UD3Lwu73>!kUdmU%|@0 zL6o7C8`7X-yuX7bkgP2F!OFl8%95F4Xk7G@m4P8KLnXH87b^n;#MOzV8EU>R@CMRv zuy!rY#-cx9d;Ws?2<L!ohsL%Z$hv=Ec_iyHRANz0{EzBO1~$-ngp6#UBMf22A{UY% zYr*~ncbAyJs+pmxXEQJ`VDt<^GC&LLatlEHXGoJ<1Jc~j$*%>SS)>4JqJTEVm*gu{ zrj{rqDwJeo7NvlPP_V9QgmeOH!J~_5ppng-N(FcW9J&e-)Hei8OJ;#?Dl1P-0`=MS zGK8{_g2x>cJS<?BV+M~aJiuAmz{fStU|?WCZ;xW}8Mu{6y2rrU$o5we8yonzMRssx zaDcre7%|u*136KFk`W?Naf1E91@%V{69a=P()>ObDA>VkgrU1L3rj%^$oT|$`Q-|b z-e*cabg?XGfCy>TCg@xV1<;_I4s>m8W-%zK<)ng_E`$1aNHa-^;2nplMWB<vz~?OJ zflesE=*1x|P(@wV3aVwHiw7W^T$2;?KpjNTQDdN#4)PXgdI^+DGm9Yu=%8L?UJAH3 z4Ouq~U4{%ET~9?@zu@Z}1YMZz1zO1fsS7|iMi(nUy3C+Ha4N|ApcS?7UNWdf2=Xd8 zY``nsK?hKP_unRghV2t`Dyvdc^tgQUi{Yz`A&vp*OjO7P?`|#t?NS6^D+Zfu0Q(2D zEEqH|0a>UG?vUo@r=)`R$AZ?>7Jyd9f|vRvXCxL_CFkcQrxujdDinh@Z|3Jgc3T#g zCKab9TY)r#^+IwxO2Fq7mso+^k5B{hYhsB)Zfas)u>xoU0(`+}v5o??VN?t*GD<R1 zGmDV-TZ6WHLiQQMlRz@03(J)cx)l|yD<d<tD6uFxqY_&w!VONUn5BpZycFSqlp<|| zHZ8;Yix^26B!Rl5fr69_F6V|-LIwp7_H+!A!JmvlDh4VQ7x6;s3_fsK%MVV#f)S%- zEu?8Otdi(ZE^Cn+37}>HqLCl~PPl^5gv-dpzz~uTuE@bPCrXKrbi4t0E*rETLq{P~ zFI7*WpeQvhvm&)vN1?bh4aNeESL-OGmL%)xC?qO)Bo=4nCKf2@>VmgBLC1<gwI_H^ zJQXz0UCfo8S_!TvGD|?`D;2}fk^-Lr0MZMpWgy84RJSLVfCt3WGC})PAm@*OOe{(* zF3l+^2DeWX67v)sL2d$7>IDVhqZ^7#67xWNlQQ%3^b}lD3!rCE<mV}5<d-Ytf)0Iv z`G_mO2<|7O0im2qu*C(X;PGgXof#1S>43wn7&L8<IQ|rL+7u!vK|5t2JAw2R96={c zfm`1S#U-f)pnxh%%*jkqfNmbjOaZkN(o^$Ni@?WjfwvBU$HY@BG9jmGKvkweC(;sg zGD|8Uu7EU|KnB1<3^EuGnuY;gk_kCw1AQ}xUXc)}mc?x33xg90X7wBZubxFf8Vw_u zX`hN7HB2Ty8G$s9rlY)cTBjpXNZlv~E@H&NsYfsioVbw7BTxy1D32t-iX|b6Be+4k zrBHJ(c#C8nxVg;blUNKsbq3njE>4A=?*>^}jM$k5+f|mFpI4ljl3E1XujmOnHAo>7 z)T0KSWRjY~1-&#FQg@-)st4LrQVS{<Q}wtUb8-}NQY$jS$B=+Z7SQ}$K}IU*pgm9q zgSL!wa`M3?8>sK2P@bBT13D8AR8nN-rGd_E$;{6yRwxJc08%STKpQnd3yzBNb3p|N zm%pn^Oj>?^NnU<QYPEkw8fc@PYhF5NZJmNkCV0jibogIJNlAf~zJ7Umxn6#13TUKL zAJW7Jt#C{MS(utvnhPyEK+S&WflDA~q*f$?{0^Fy0?B|nHsC4_v~vKYE1)PftyU9s z%mw(!L5OEElNBKIkdWQY#i`(-2*|W#Zel?}YKlT}X)<V8Rc0CJU_R(L0(c2OcybUL z#^4hH^V8rJ2bV^1D#R=lcO>S4yHH@K=%DrqK?Sr=etto%CTNo()SlG56i^=u)SoE^ zc?{%Fm{qWv3BOgrr65l$1ZRTw=Yo!Z;sQrvYHnt-0{Gacyb^`n!~$?14^&A(WmBQ| z5GR%=R)Y8Bf=+4#O=9MOPMpaH%^!f`6`oSSm0WQ?7by8bj;K+{PE9QUt0_v&0Vi+J z{3FN;&`DQdYq0g1q`)}^vrrC&7s}FL6^0Q~j0_B_D5+Y3_IU~1Q$ewGAhHq>IjKkn zQdr4?%O5##m<dM63`Cd>rSb>4AO{uQh%2P!!2ziN4M@-xjaUk+B1KS(L8i7y38W5o zrF0fp6!Q*gkOiQvw8|h&hTv--v6-m?iAhzk1JpnUL$8wtISF#<ApAP%8;lGLl$4mD zzULq)Fk#NXQeJ|ja`LRGR9u2g1Nj$f(V#9Zi_{?rK?9r+G$9Eg;tqu|K3Yen4(eFX zz$}tLQ%azDMlEnc(1s?2IiOh<aKnU{ZN#q7b`<CUUsq_$2{btjYGHtyCz%xrN}!ck zO2{jPV9hABl|luH$=QkNsS3%Z#U=T<dbyR!`9-OqNy+@YVm)w8pP7>n+5(0?&7uQ# zI%Z{`0I%$IAw}bS1_lOddhJoe9FXT8HO!@&_loo&xl<n;DF$Gl2}TV1NI_0rp!9_3 zxfp^yVg&Vw3~1#qXfsT*0w@(IK+*^(6)9A6>FMbe8G~X9vy*KC){hy*$?zyP1!**l zz-z&yhGj)&knlAJJIexWtY8+{R%AbbTn+I9Xe+BFSg{pEF=)~id8RKMG}C7dmcwu# ze7%MZ$aSF1W(zjT4y;@-0(8k5C<SRiGKr>+LTOrR5i&0yg_l}{%q=TJR-2!ch{}cW zG(ii<^V5)Jx$@Iei&7Ex<fmmK8JwSnY%549lFCw;u}YdcASo1mX($fNPfJ6RO)N#S zk*horNh%fDPzA85$d1cLl}<-;fdWVlS#2qbM@lo1?aVJNMY1%%6gButE0HD3klhE0 zB4kU-kW9@lLou|x6g6PWkuBlM$VauMv=YfAh5RxU$Cn{HC<EjML^LF#IzAD_8ijn6 zl);sOraHeY5n)n(8M4okN;8n95>a?4a%uVH$l+Cr8b>H`oe%2HBN>aLu^c4?%25Lo zIRx@irBD(<1`>}eKOc#wkdKm<%ga&Z%8<QKjuQIF@t=rdHL?k%X^BOMz~lnuUIZ7M znUO*lB#We4p)@TYor|IxRT4RzO4BNfkYu?k(^8SR3Lq|$Ngyt=G$^i6U5SVsup5!| zg480(qNHxFGSpI}3?&VKct{4JBuRzRvNA-xfUW^6vImurLRp}q7P`U&yoAC5TvB2b ztiGw>H8hSOO@<L!Yzz$G{DG*DVMQsLNPdw9nh2=GLKOnL6h#P9w4w>6!i~}d?;25n z6tT#vpv5e*kOH`<MH4}H6{rM6btkBpLlFTffja<ZKe+fsGdm4U6}T8iRs$}Ikp&dM z#W9Kq*tS#@2PouYxJe-&R5YV%1Sc3Yp-eO<<%5f9WJO%yq8eF50a9F}300z-1S+;s z)s%tCV>F>6RIh-Ga8xCbVjN8jRFoqNL5p)_Aq7wYk7_!kSVvU^D%w#*AjLb15TwvX z6#^IYC_<2;9$5%h+#`!AfQo!H0d!Y_iheXDi5X~7URH`O0<H#7wSkKaG$FJQ=YmuT zsEW$bBNJ3LpeZTEP=k>KFqI&3Dm0^jstaU;Ayo#l2)Non6#!Qqs6u5JuE9v!iD*hd zRSBvg=&plQDadM|)e5o@v}(Z+DoR9+F-R4IrYs*VHWW(JF!f=o0arQ5MnS6`WFctP zgCT@rekrKJLQz(lhL$3sRS~KpP!)qAf~pZ(Eup9aRYs^G0}?^ir+``TL#inxlN3N* z2q#Dv!WrC@cL7&Wf?3e|3)H>`cN`K+ld{e;GB9X17P*2Ix<M48bsw_0m>3v9JqUNO zG)6@S??HI5A+B!q1RLlD)*%?NlYxOjPfriLP6Rr|%T)k5^+f?RyPKB|A78fyZLrSI zgUkTs7jYrFUm9pCHMy#}KuaZ|J#WxFv@Mb`pgTR&Q^D(yeN#&^@>96Dz-JsJ!)#1X zEdehkO9dS&12PM;h7#3CYc9|=qM+b`RQd4xWxc^(!w3xDYH+RZ1CoW^FY5~q3qO!h z2ITr_w6G}h2Q?CevOs|bwFY+OYyemnE^7io`XIMmJ!)8n9K1zAkQ5LMwmSrDieMJh z9*~2;DFAi}Z75h(7(^9h4R|=1gKja@jT*5<5ny>xe=!oQISR}djBo*UpQ#YFMbRL? z31xwt1_=|$y|po5d(hpb=3593_gIi7L+Uvq4ibv-U@s<strpCJx(wuRa43RzOC*Ao zBteuwf-o7(L3b+DOB%67DImv!LNFDqHw~;@5PXqcNk%62WL=aF(j=4xvJN>|GQgVA z?NakC1qVweNE76WJlrOOny9UfMcH7-<bcf+%z|16av|8S$V<#~!7B40DkB8JH~Z=9 zqvW}we2~phFC%TfEdXo6bZ!~gxrHE2hB!<tf<#F%*zyvvIf7YGYd|gnI}^M%yA-UX z45B1L7L+g{<2ulS1g!ulDhFAM>DCIc0hn&B1iQ5oq{)y7)2krvt_C}*25hEa7Su|R zOCjzCjpfvWmDE9$K$22Dn1k*Hs9QB+iyA<#041eHu-+!Ha={2u1_lPKrCL!lNP|!o z$SUMy)B@IsZjTzYRBHukGQ?wQ8^n+8U`KR-%@WLlS_N_$*pJ9bs1vNR3!)OT-aiBC zE2PxY4VK4rRSh@>dLXWX?NaCk8`%fe0$aZ?lm)T~Y<p^kR2C-_14C(2Dwq#WDg9tQ z6QFv$K@$yJ80+{QK}(AB6u?)MfOoiJPHP90LaLNn&=fYt+&pyZ1yrL!5AXyJ8G|Y= z(5BtQGRV@NM9@*u8KAjpg_8XARPYhf;ALB&DdmEE$kHn4@-5IHc5!AE?5q<m&^oPx zoYG<i(3L;Xy}qC=sR~J{nR)4$#}0!gmz+yW^3&2lx9X%qcPAq`G_#^s0kQD8C^fmX zs2H+90J6MV0emKb0&J^uF6eIMRCqw;CZ?ofoBN&!4r$B?t%Z-3PJ%?L8#pS^_Z{Gf z3D6W5bixd4M1bUxroaY6Jb;`8buw}^fG6Ln8w*8~A$fBOIH^wsM}T0&Xi`V4Q=vvu zM;@RD6)K1#W*Ru$r$fX26-iTAkoGHRRY_55a(;RqD8qwtE@<H<^0W?8ib0>ag0{$f z6APfn)aWR9=9Q$Trxt-urUb14g|&sDhX{dIeIlubDF$uZ10A>tYrU7{XQn71*_&Ab zYo-^a7MFmQ^MJR(BhN;F2hC=H0|K)IXo8mjGa)6wOHwAp23bIXHhz;7P(`yKnRGTd zvCIL7kzm9KODxEF2$X9ec?i@nnhOq=d5~a1>!oIZC%NW><uH;Jyo<U3EDvfZEd-mj z2+S9Zuwh_e$V^kvP=uvgq%-3c^z|K+l8Q=`Gm=t4H{O-zr7NVBrWPp#rDlU_!~8t1 z>Y~M<)GCw(av^eiY6;kU4EOl9gIg|3L7EIHw|p5S)hq{lX$9Cy!7QkYK>kF8;7YKP zRS+eRrsZld2i=KKuV};;tpUq}f^02V^ExnJFv5+2fdMp+t^uk?Gb_Loq@Y3x%&<b5 zHq`?!0Wa3j)I>T}7Nioq2(X5$IzuQ6<SyiJTMxDb-BD`3o#1fW00}o&GF$*Z`w!Ux zMH?XjxC!jR&0xE!>_Jf2A);Xm*rKfviy+ak4a`CJF*IaAXLEt&LD8@Sta&GxFBoCV zz`y|Q&lH2s)GbO)1I2(|Nj^jrRA7TrHaua2@5v|*&n(H%C<gC--vtUyp)8P_kfUHX z*aCD1srhz;qhJq6lOYvs-wO%)ePB=R2iqx_1$7e0r-(p109JAkq689Xhrk?kH$wfQ z5nFT^<VsMO9Rce-3RW%%KGg~o|CtrAN>8t#v_zvAbdWD{Rj3DQT7!?tG(<W05~LU2 z!UP?PoLmapB?!4C6(pHi0omY~S*(zVd^ZTFOTdL%TO#76G^x0xC^IizqgXE|H7~s+ z1H6kJEzdw(iJ&7lLE(WMVaLF}Lk|o!-#&1J9R~%4VZ>fgFBrV%gA}i$<Qls99K}|c z$BRxt63j_(jGhAfdAP(VD3yZKJ8~EKG}xnOpdLjzq4O*#PNAtCsk?j*tQIpNOav!{ z^B_%VM}1y^gy}`FRhPip1+$>0gX{-83Ovkp8LZ?AL<uAlUIlZ|t%EvCBev)o$U;yi zybjiT1FT#yLWqHZ0W~WqDQQ|4-2|x?$^zMgoVag+b)j3L<~s%Kr`sS+h7n>IMnaCs z)3h$S1M%TquoLcq4HL|Q+68hK*oVl$ejlvz0YoKyWCFdAd<d4ubk<a`vmQa51sj=o z3^wu!SPNog0%Q@`_S6iijPTN=3{X%#1uK1qrWC!Fd=8e!w0#=b_7|wOzXTik3akZT zJIEpo+h2o~zClxp-nMxQmdCVxI@tDisJ6cc8~FjO1z|hLB8cr!e}4ok`vg@6N+Puw z12I@mG58GDfa#PO@ZQ81h;tx=lxX7#MPDI_;~UuW?_jea=@X0P$gNY5Yr)P3$Jr0C z_McGgXBZe5KpXX;J+>0i^27Wz#Evx3)r_e{pn;m4O3-K#Xe1}Ov_v;QElnXM6LfwU zNJlYvHv?<~gaY`+R|V*}4s^>zB6!P;9+wB`PF*ZpEuaM_$PQ5TgL9XLLQ!gB3eLS3 z*hX=FfxU_u>a*dY{u>hNrv@@Cune(e=7BfAfPw-fi#{eqAS8<ZK$6Q}aD4v*2ZCV4 zu#0cxgbqsDh=l$h>~RKm$O$Q+lTwMl>BAYC#B)=VGZOPMi*v#Em%|b`mcfkR(loTO z3}~eh4BoG*fu;Rqpaa_P2_Afax1<zw6;PU0#FQ$GU>{<p?|Ja_&BP8q8|5G=V-$lX z1kg)CW_Iu)DlF`v^KV$eeisCvgF75z7dbV9(k~)4vw{7~4)t#jBLf3`e_?(RXuC0J z+zqsw589+h+5-sMiV91*3L4N2a*&fha={0Fz;>|tW~QX%q$<Gn0fLA9^K<gkD?yh7 zCzdFb7MCXG<W!=T?`5e)m0T!=Jao`MF%5Kr2<Wg**k(qUBS0rpfQ-pYP6c26o|d1J zlV1)!_Y-ONB3B0JS{BItEzk-Ibbe)Gi9%XtQE>@)KX!g8=*k7q$wCFGCE)GcdJ4gi zjmO|iHb58hfio|XxeB1;T|g5g;N5X)nW-sUCHV@83ZP>kKtY+An4^%AnqHKe3fkd_ zt2*+`OUtQMD9*?)FUD5waDbx<Gg~f#XG=~<w(K5_OS;D;T78Nfl|@{T0)`u$;dsEY zC>SxC;RacTLoO*nWh0`b<ON3@A2j0TQapu$RB&La_(4ert>%Y~r9(!xVABpDg^;6@ zU{ep}MJd>49r(d+$1FOQ!;209NYMe>%|i4x9Bi`=H1=DOAS5pdfulqi>@C5F!5<~a zi3^mRAc+e!wl4zqi73P;SjYCoz;YOo2OrxP2g`$c&k|s>B*A>a2+-N#&=doT6$M)b zB_(Sv@X$3P>43&e6+qHphLr-U3}OhItGY-ElthHGKn_M8p^ye!hv7WmRp9Qh3`mn< zgg;`m7G#-%tpa3(f)e-0LXv_U*wgZ0R|sZ79SI5vL>Mc8l_)}#Kn8D=z#Mc}Lw%<a zTciw@2L-AMShFgaFBqW#oiHgcO3_QrOM#3hgS-R^KcvBD@CdUS$n!#3AnTDsOdV_% zy4`BNYr!F=0n%hhnnjwBpwI$4RU2%)U>4MNkoyrqp#xT;3sC|I3Oz6f-8oQaYs41m zgB%132?MZRL$Gqe2x(AA<fVZwSi<6e>mnnNHlZw#g~*;a25U#RP0e>b*z+bJO@;)` zHih`t4D29tu!(|MPzyn>1p60xRLcUa(h{N)KB|QtF;-xCOt)<SyUiNnHrS|^4cJIq zuolF~4#*;~?Z~5Ac3`FUP^Em}1!K_VNuZ#!E^+`F4NZJV1DcLt9hmOf2zHMXNRwd% z7UP^D!Q%q9))j1sU>4L4kXs-QgbqEqfmOLfRDnk)v5fv;Zu|29Yru5dW_Xq232`6x zp(ihh6TQKf`+&_NYUl~%TCnrMLr=b7?S4@0ax4rCp?PWfMJ1(qi6!8}JTg)hQgf41 zL30s#sl~;hlR=YmQgcD4c$B5)m4MDN0(CbOia`zcRE5Nx^!%dCl8jtE1y^Kk;PIzo z&;gU6Ym8vM574<HT%f5ANIM@ihoO+4rjVGI4_>>3tV~ZKBwryjC#STy1avGC<g_D5 z?*+Q{C^J8=7Ig4YVoq^B?4TgT(Ud4k!DnsM>VUcunXtR+Q}ar|i?1L@F@TPT0V&8! zQ7Fz=0G$~H8j`~r63O6uEWxY0Kvzkoz;6%%_ou+edn6?mXM)eE$;r%1O)OFX_wjNv z^U`$`l1fX!HA<pFPGV7dszO0x5oksT9_X;MSMpN9U8M5-qHKl4qWsdl6opJs_YX7_ z1qyoTi6T*%1!?NV3OR}8&@LZ%bP#kVBlLigq|}mf&@~HbMX80Qsd>qjT%hx7Ak#*m zutyH_V$iXWsR}vydFiP|3XtJKg``x_IiSUm2*?2?38+yeAP0d@-2q27L@y*+6qhLE z<fmsQD}cI&`Dq}9nc(A85{rvVb5ps%=V(H$fkaelv4Tc!YGQF|5hMz8!0WM#H6cfE z6{Ui91A*?EFH0=~_4kTE{aU!rq}1fZ(qho<p`i4Tn_rZwkdv7WNzRGj2!YxK3LJ<o z*g2mt-+|9bLe`lHJ~{}rI8Gz6SRuclAio&0=&m@mEVU>xM-w_gt5BMkS)x&_3GzPZ z2908c6p$vQfkVV;0-y}y2s%xu7IdO2_<jzsy_tD=sYMFOIf=!^(6n8gUsRHs;#BDa zp5F6KEU1N^+Y8Enpx&?oM1?|9r2;fALD35GUrv600pwIPP~uYn+n$qW1-X?5V!J|q zUU_0sN-^j<jMS3UVz48S?&<({!a<o6Yp>cLTzFuXW82{6SOBCPlN_3*3wTK#QH2Xw zC2H9M7J?NmV9ro3Sspda94%W0bJ+qLL;+V+kj#y{XaOfjNV!3ck_BWp`2|Z+Af!DL z1a6Q7gUb}bh|vZK?B1uLTx^UsNJbkZ8Q|mZXwV=*9vA}kW)OXw5O7fv3N1=NI|+%O zk3x*hfm+<q1~<4=O-W4wb%c<|9l_$@(iX?CBhqqc#NugC$?IQQ0@jyWtbtWcBB*tU zeMB-0>@Un_*8zC5D;(17+Cj=3;~?{QQ3Rw`hy+Jv6xhp<O`$_KDv=W`D2YN6ENCP% z8tls$h%d2@WX6K!Fd`j3k{Jh*hi%P`2OF0F5(1xwCsSLL2<D*c7s>+J3_4~ni5;;K zHyNxw1*}6b;y(ie15y%&t?GyNJCNEB&|Lr_MX9Ms>fy;=BQLdF!8tz{bfH2?ei3v} zft?0;Pp*T1S!z*HW=blT0(8eM=uSk?Wlo7jsjxBnVnZDT=%{S5ktUZyHJ5?{SXpj? zf-TG*(7C7uAWg-F@R@uag<>N(N7I^10osRBNX{)#P_$JrP_PFxtrUt4VfsVzHHwWu zYHPvUc|k!68H<B&=S>9%5PFcR`JMs~F{OcIVcU7r!6BLf63P&ah^2Li7G;780HG{U zL_!@6+Z>z)b^|U)XM^+^(!qf_kldXM4wpQzn*_6<t_B4bIBUSR8s~#m6+l!$23`xn z9CU9$eXJ2%R0NWTWrt$0{t}Q7EIX8fIhguER)MlZ8B%sA2WzhY>ky2X$-ux+&4oy> zL?_p3E;17<bhwj<v<ljH4)QEC&aX2<HsM!-osRBVHQ$rqgjxlXg(cK#uwQFHLK%>e zS<q5@PzXTHgr%ceuo7Hm)<Mz{XuP+&wXvukY-$5o3&K>8T`2L~2v*hvQ3i?UW-tfc z8lfz(i!@@3TEOz45%yNF<~A^2Fv5g^fq|SjDryJ0Tqq0V6o`)@TgW@W=Ayep&G#rc z2s=TV49T~&3z8eU!CvSATP2tUbqUB{;7|gurR@bP>4PYN1W`YjgYGn_7c^pvCV(6V z3ZaQ$y_3Mo1ta3Xa}Xuqa*w3Klj!7FG#O;GP!`C|$YD7J>;iNLtNES)hvig|CPR8S zZyF@jr-OrK2G~)8Sx`5F!U`Pf$TJ}`!767#RKjOM(38q+uso*sAl1Sgi1$D_qqeoN zXfD{ud0;J&oB_(iAdA4ZqwYM;kOH5p0iAr957xQ>O)IznLz)L!2$sim&1rC8FG6+A zVz7}*z*-Ql0a--QHA}%-mqE2&Wnf^?wB`aebWsK`L3<_~b8<8wty^m@N6?+ZKAFWO zu-1S=VvZrS9f2XIfoWWJYGrUL=;}V~Mj0vCf(*3ga?a0zox-kH1RAz2PSr@v0afp5 z`9%uw_Jxsx6-YhurX%FhQpmm|aEl2kgqMT;j2Xgbz#+T>62e!8c!0q7RiK4O(Mm`r zS_O{&)!?8Ij2O<*4@&6Z+yE|**MR-K7UFM6dAttHK~E2emiBs(JgjN50jz%`NC?(6 z*#zcb>IYc`YMN|DYMN{TYu^giAsCSa+uR0gBpZU$vymqF8ftLUHm@WxGp`ubvIX5d zjnqU|utRAhgU+^5P*6|+XH>nS)LhVkis1GzsC)vs8d9Re8^hbcZa{ann(sAmF4zu| zg|#tufE~RPB$Octo`XfngoYVHSs;HwEr2yRc7fI7vS2qPn}H^DQ4K5F14*EJ!Itg= z8zKnqVS$_hj>zPc{N&P-%$#Dqy!@2ZVlMFXOJ-VTY7tk_es=I#M+d;V4?=WDuz>cA z<QQq9I5ZSVU(q3ub7X3Z4uf@II{GR&RE~gD8N!V#Itp>>F|cLF!CE0s1z8VvDy&6( z0<7dDT!~C=(J3$o-708MYQz?u2Frum0cXIP&w}}a5yqf)K$?OEiOHkr9LVuPSs<4{ zVhYkwIuAA$-5F}WSHM2L0McYgww)It0dxuMfy-c<1hb$H0r?6XM&NvT1+3&ML<uBc zUITN`T?X}mMr_e_klR4va|5jRCRn*3_(U0uTu^iiq*y2mWDT<KZ-X_V+X2f3cR-pT zXVhStco*Wgdtl4&gUu1lf?5M|5!i3Yt&s;{l@B2*;jIz$_;>`C$8^zkaC|(5xCqu7 zc>*@_DOd}l{s&nEwjEz<<QZ7&b2P2sG7G7$d;ylnbj=O0YhI$d<`vk;*I+FO*MKa7 zxdy)X=?z%vTc}cA#1S^&aJDXb2QnF21S2`;Jy-*#b8dp2^8uvEFap!GkC3SP1h(`u z*bKoes1+cWK%56{rhNgc`U+7+{2GyOU=5f~y9FQQ`wnp)_BA3uAWr-Vw)_{^ETYzk zfLsf9K6s7DZ?N`1Q0+-f3=D3NyJI110AL5pfL0HH#&^Mi4LXSiwER5@v}_?Kxilvc zbP*_QVjiRndU+OPcTrv{d}1233l_dnR3S5u3pBkATIB$qxyIOW1HP;@FTVtFmr8z7 zW;)1y3Xm%(K@|aL$4ENpQq#oj)I5cPoW$f*kiCg1Dd2m=^U}eK0w4|t59UG#dAT$& zEC)-2$82jg^%OvjR#dlv25bZJi)$59QVTMZOF%2=Q$dSmpbHj?^K(i;JGvlu?7&aO z0j*bo99#$5y9K#u2kG>j;>_I4oWvqffI^n1z}B<kJVZmYRsqxP(ETr<ZTGdBT={u9 zm5`kYpy((m&xcg=3MG{VsgT=!G7|Grptrk%)-XU$^U+gq%P#`!(*fPHmY9+PUgDpa z16sP0n41b(iBXc64GI;IxoP=DxeBS7;PpHZw?h_O)PinVg9w0PJhKA4b|*70Ij1xw zH3i%1{lDM@h?y7e!t=sENM4AdQ3{1laDtqRHGzWU2P%ES?8crvVY1*9PRrB@o>C?$ zal)O3I8J9k(k9sDNJ$gS2Sqh{$}IX1DO4FaK)an7IUsx4MoY!il+jWVw2qCYr6Tg& z5vW>5RMJe~<j4$7j(5r2VvzzWzH>A4QWdb)>d2Fxu(AZllqa}mN>7DMZw5fmp2IWA z37^w}ZOhaFkCPYV7sF-1HiBv=>=U9aV83J54^QCr11kr3)8!rVCPar!*c7pGfcImv zgOdaYI9LQDhJTVk&K#iZ0LdJniB(Q;NN_<y0^IFKx@HG_{1Z1=4kPivCsujD@}Pbp zFW4+TFrNy?Kk<Xoq)-;fg~(k<0kHWP?(uyN?vn_DG*RLBCm~2e5e9on1Z<^X7Su%` ze<DIq6s$xHq6E^D76)_Coe1@cMr@G;SRNE)l3>kJV7_34BKr6gXm|?LY}SL1<8oCO zNrSv7lm)UEIb3AGhM-%j=KB&HF0vp^hD6#R2l2c-*l`MAa|N@Y)`DD&@Vp{ei4sH! z#PiBv4!S#_?$wAbQUS|@Jg*AYtOn)_Mp#3~Szx7{9?GFgpwT#ZDW{iOSelqqtf2&H zg(!hH#HfROD3k?q5pu9-fQ?6Yj+*alaIk2CG#N(NlWzB;hB*-1L5It0a#a^;K>|%1 z>?s|vt%6xlM}d5b2sB-=5<Q3#NTBJ1Iq0s0`bHzR$N(%4%CLrD%|>88Xz)v>w#XRF z!PE@02Q(mR0`ep%z)it=&A`e9Ba}eL7UdUfYg=<ce1dU$QGT(eb&)wpw@?<yUgU7K z0GontshaOwaJX86G#L_Wg%u>|tijH+0UIos1+^FCW^m9!hjw5C!?s|>b`ZsoK(q&Q z(48cd1q%lU4#W};N3eD$unxh9HU<U;eSJtMIKr-~1>HfWQIKD(Ylw9A0erzX>WNZZ z81*?gu@cg#18Pj@Kzf(p>Kk;=8OUdlkcJN)JA>Vc?lU#t_u#;G0m;G!k6pnYa{~!w zKu$8F$YVwBpqLcO0)-dUQLq7L53n7$9OVhp2RY1)G6#4;5{Ea~Up`<v1+$>80(lmk zIAG(xzF<{;5LJ*=;Sc7ZI}_?7jo6|9kV8SaBM_`N2&`N%!h?Z<fm)GT6b!OMC=28| zNFYMSf<wS|p*u~@_X9XuLqVDhsq2t1NMMG8y&3_wUN8&lI*|XtftiSMoHKk<6?xZL zB-nr`hyf7};9X~_IiQUtX$pwrL*Sbji#4&A-;iD<r2LKsc^6vZAq_#sfbGBxqmSS) ziUnzcoK0WLMY;nXHOzrH0al2|LBb~<?7alA)q+`2mx25Y4j=FUdLmd!5=03kr6q$o z=uU-t33N6+$g!Z5mI~IJ239T@aR5;cLmY#(9Oly3hse^rd?I|*3uduZln(NnP!=du zkW+XD*pKKzqUQSr9DA7{O@_lG0J0z{CmS5KIbd%KW<f&*6yM;K1FgfrW5>B*m3a`A zpsdIMNx@vzMfsp`fu<XztWW?}iy4?dz=2r^(u8&fT@l1l#bB#Sz}f|~pr(WD2RjO! zoJ+w<${<Q0$+;ZNLAMU-EREQr3Xp}M<Xj2XTLo4w7@>ow;8aq=l60y;<_KkhT!5T( zYQW~9Td(H(8|>R!kS4<j13Z>Nc7bEDunrO`^<ZZ=fUObCg1Q3a7jUQ`M^z(OWfMdt zd?pFKrP&OY$8_)?u!CD54u;JnwStXo18YId-GD3t+m2k;wu6;+peaRf{&#}qF>U_~ zw!I70_HM9|Jzy;e+d&p#*xn0P+J~kTy;If?mdCXHAK3N@sJ2f88#xKA1z|hLB8ctK ziJ{40WmBNah(5P&Dp&)iQ~tvTJElRLgMDIXIwWz-09!s2Y!*=yLm=0Joe$33v%uPC zL$$AGWMBx%R{))21fEU-E!)jWElCBRG6&jUS(;o@T9gWzG%Cu^2XAwQZYnL#$S=)F zQ2=k<O#;oA<d<cFrU4W@5eKfp=YK$Y9U;TTwV)${K-*ta6<{+fpe>*IX`svdQgjqD z^2<T%d~~>y^Ye-`Q&K^j7{U8<K^tg`LHmC}2aOklr(ZIQOF)wr`Dvi5fKov-9C_f& z5J1-Hagnp$95G@9GNTxI^b8~b^#hIpG>nB$3ef4Bp#1z2>;q|_roD~=wpG`l&8d(9 zwc?W0T))!Xq|_qpqiA!$v5A?mn3yxvGr;M5E+k>CrEzq_CI*l~ihi+8#tANiKC+AE zK{EY(aIRedj%UG$(Oe6fj<u~uY<wB?5s7l$Ij9VVl*piQlZD{8T?C0+tOK2k!EzY+ z8$Qsv1S}6~@GJ$JwG7OM+|rF%B!My~&V`zq)?A={8CeRp3WnAS`ud<bWUz+BobtrV zVujR-%;J(_E`5E4%rr<P0X_->RBwQaX9eiadIgXksA{hAjLe)=1&u5P8(RgGqO52+ zs8|xp0)+r_18W7?{TTlBWoHHr8m$CrGK>Hn+BB#=w+fPVSA(Nu4cJS9Sx_H?;t7!g z)`FF+gD8PCao2-6=s^GtDvj8p4Pbdtly3xU-UQ|gMrboIFl2!S&Y%kkL1UH*whB3^ zxw(nfNT-W~1!_SDi-Rmj4*bnvlhAEe^W^~t{uW5!YvHv9zT^~YOVL(HP;3J`bvxJs za-0hCDkRiE9^U~rZ70+;_y{#9`DWT0SZCURs#fTs?$(*w+MuD(T_EQRWug0dH`owN zKl6kAya%KSX@nZD4SOM8-3NBuez3WMSx{?1E{3=tl<yCKl^ld9fyDYDFbCZoQ1^mP zxChIFJbwhN`6!q#7@>e=cpmI~<k9(KAa4j|fviQ2@8e)I(Ct+76$JbJ1W1!1aTc6} zc>NUEX{W))3T8oV1-TdD^)p~4XCX=;UOxxspgRNVT#eYG^B{TH5bFi7{)-@?4Cqkv zB`^n5KgcRjsc{);i1i9s`&F<G!H8+#Ay&|>37HDEw%~O?dg-a4^FSc0Z$ViIz6A}m z*cQQ2Q&T904f%tWAqHU$bWo0<)dVfe1u0Rm1s_+dhfs+)sa6N10B*V_Xvh`hQ%G#V zhg`3L-Hq;3HD6J1gk1;8!iHRLfIWH>B$Oc-A&%RlMYlllER+Qb8K`xz!PMJe-MFl~ z1JY-R*XX;DWN{Ddmiu7S1hb&_fgA`<7O-K`2VhkXA*vuL;}MvH?f|G;HDZe%gXKY) z;t5#uQ!rmJ!Ut*U1Rkgq#9z@fkY9zeKu&~&5oE0NIoLjQ_o?}cfaBu@NRuJ;9rF?r zs;|IaehqelU>4Mcpl|?(DtG|p4Oq!rh!RMUz5{d6oecGwMr_f0kfT8%`T?x>BUrg0 zcuWJ7L`g}*MV~-s31xv?fgEa|!Dga6LCseT9BN-cnjnKHBwP3u5;EVwPX7+JMlcKN z3Xp%mAp;#m!M85<2iSn05Ch<2E8y}3Y3S=0SRT_K;$VOLhWG<Ew(<vT<X^BB#P|Zp zBCw;7$5#G<mHtOlie7j#aDtXHVcISMww;j^ymkU+I};~p^%FB#3&M7gMHsfTfR(bM zDMha~*}(Fcwo8I-XGgW218gKGSPQ~-kVRnI!GjZAU^U!OHSk&uQQ;PsrlHm7JRn=3 zH6&8B@Pf_2bec5SX?!3}NVOV13-~#~3o``3P7?$hE0_hf735xs>p>N|5Lk&YL<uCL ziGVri&VV{sBeqBsEDy?QVqneUV7_34JeCR_<agxyTms|?p)8QC$Qer#Yy`TMYQC~y zpG$!>84_i_G{oaFV28<qO%=?7S_*P4!sBvaCGrp@5RWT>Iq0r{x>h5$ND(X#^0*RM zvoe@37}1DYM}ho|To)tiN(CE8JqkHFO9MQOqk*e329+U*DggO#c*r~`TuxIHJY%l{ z3MHW|kiU?FRu$|>bWf@I%7cSe4W!9%koZ6y5_uZnz|{o1TQCdiEl`LfB2NpfL>r<6 z5_vjc4!S>~;h_;*qzm#XDDL#YdiBA|1tUzsi}#C5FsldX#0@-{QP1bME;0ZaD3k?q z3UYWGf(=G@hnlYvIJ}KOnhYth)ff^+CSXsPg6$H_f;t7{GjJF|D++M&WCm7g4p9lO z5zteK1y~-_)yiO3TS8n7E0e9jMp}clAWB7$MPS>JYXlpxQd=~o=-J;6ERSis3fOjg zRNEcEMmmDEAZ!O&gkifASgA8qDP)8i)X4|0MF8b5P3s~Tkm=CE4XG@41#7}|k}B9q zZXivNtu?h==q9>DqR0bmxhL2h!7QjXAQxdc(+jN98=?}tL#>tzy6qWcwsnyY$U100 z8p(~mU>%rlR0q4!52Ok0&{2qS{tyQSfUOM#8zPtmwFBf9hy$VX20>s|!4Opu8q5p~ zn1_yXfzGUi9K4v6nvt280=}UhX<q?oy()OD9^?Sfz&U8eeo<;}VrE`SYLNoyC{D=0 zOnF9Xo&xCJ08md5ba^QFG#|)REp)R0q!W^uT#}li#|1s^A9VI$u|iR4o<d1RQGRK9 z2H3JZ@bELpbR4FYD5NGPXMk3XfVUPv?E+nLmY7@uHUhlvL{A|o6?FLlct)WpRUxyO zt2jS5RUtV)B~>9MA9Q1PUOM<j0<fNfqSUg?{L<o_N`;iv;^d;tq|_8>SQLW}Ny|*m zP)G((LnNgtq~>JiW`fQ@O#vOLm<!p@kXZtm8pzF0DFtoE$ON5bT998{oSBr9%2kw_ zmY7_U51wKu$Ve<s)l+axPt42%IS+CYBxsuoD1?*q^O94G@<1Vw2s%);Bp<Xa2DF<b z53vshGTxz(lA4y82im%l0ot;XSpvEUp|~Wm1blIGB6w^}2Q(^{oB@kJ@YNBZT`#%$ zdHLWABT{oSlfm%_J<t=f?E-2+Cg|8lkR2(Y=@5|fKvN<m`JkOLpv$8{M|OflLFep3 z4oe3eZCP3jy9kF1J}(0{5IU&=I-jyEH8H0cGz9|=e(-)ug|ft=%*3P|P-H12C&D%c zQ8>E-witPK1uOt{3EK3Ez802SphCde2s6iO!Y4gKA-Pr=oX^niKN-ztLol0xrk8T^ ztiUM+v{?(310b8VGV`dD%fLHGpypGY$w1Bp?JWYE2Tj=|<}r%qw7~WfoyCg6AXQm7 zxRQzh=Ptp~N-A}<k{Yd~5|dJMY|*naW+jEZnE}++12_J_V{nn+Oce#mR9NTuqQP<) z)fs$_F9sx^<<AU0)F2jYTpUOUJpL_|1+oCrb;=52hMXN050cIbVP;?ecU8196k{_K zVlyCCsKl0LsQDU$Tek_E3=COe5R((ZCMSWkW(Y>;fiAEBE!D_O%S;9zl57Q;N>Z=| zw@n}|4qfn78jyBIQ8K8~m8mUC0UH6aOd%FzH^@q%ERfSd<MF8=b)Y_E8ra5kuyVmH zuy&y=kTW3OfsC<cfTht*gLxnmWR@X0uFZm!dD&n$<bW-Ky8+}da14T0ohCCgFn~GW zj$kfWeI7)81QP=TgO+|#KFAfwF#&OU0az8L(@nr(UkH-Tie>~yYZ2JkVvrE@2rsP+ zncAWfuz+H0Q7I<_LnupTilJ#y87BinB64(wvV!jUO#w@r6qR!_FqCEpWq}+D3hfGz z+YBM;ptZ565^PZw*j&*3iBJ~E>e3{TPtzDdKFxqA)^BYrss<~rfhYzWp$|2=G$|E~ zz+qAgR#pd9W(Hb1T9jD^YV<;<BB4uRd_Yr?uycFLi&EfQ#XyZ!&>USo$gP-HFEoHn z#tcVOczdrAq|q>f0;`)K$)OqSl@_ptf>~hqAZKlmPa$amH0sw1R@??rj5TYwgXJ(> z4$s;hAa{eZLMPa$F0gVzus@((SJ1sHkiHt|#%Kc_1&{!I<O`Dj;Dalg)<xYQ6NR!s zPD9Q`Jz$eD9O7#ZPKv!CO_1Ot)7m~r@b!beF#&9uU>4LZAiseFEfLxoo(NVo38E@u z8Y9lmFlZTANl_`Nn+EEAK{`U<eXF2^RZx&xR14~s<Um@2kPYw9Blw|7E<C>|MMJZe zt2`sWI8_0>hdwJm30$q^gS0}9I)HRwAv^j@i$LAURL}v=phE{heW_&7g$&6hkP`~9 z95MiIZNXZ3ntBS3IXQ?0bPB0CV8bAL^ubH!3W^}><v@MabjVE!l&)9<b@o9WL4>_T zw*Ii~{)Pk^7w8Z{q>Xp(paN+!IMOiFkp(;}PJyJQiQrhp*7ZV*RB*eSP@IAl(IHB) zw%f^#QHomdG>OonsgP_s4V(d|gX2<gGy|5T78MW942WF!fJ#kpF$!*0&HzW@Oh^=B zt$SvH<uI};yzZF|%BY~aXAan?xnSjj5pNkm+s>eQ4XJqty)hJaCQN3D0(4y%`1+V) ztd~`Dfhu-L>kxFPA7l|Q;>I-%P>BU@NNQShfeTTDDo9%at^l+eHVt|jpr$n!)Onzz zQ8Ftuz*-Ta&<lfMq8J;dKqnF+o#YJ})r9SD(bR!7b9EF9bQIuwIju4G(xI6G8C=C~ z3Pesx(;B*`5wf6H0kYsEvjV0GHoeIOQ4d!I;bN!)g$;Nh*cN4}F{*cTKud|!5O(M& zq^Fhy!xt56Xlhy)%>yL_p)62}LT)n52PX)O^yBLQZZa$YX)=uXI+|KQjaqPOLD_vv zQHnv?0yaof%|b|3vItywEC#0)!7OM}0+lG>q6*gHTLM<K6rzgw^R$+MHDD$|FL-NX zIV2fECZ*6?8$~N1PFxALd==O%qP9(dTnlzSxOcM}tbGksdleIS+XQG%0Ce;bXtp3# z0h~88bMh5H9cFNA58Pu0jnEeqr52~=flkxPNCoYtNX*Oymz8OyIcb?Wpi9NT!|f%B z#o3@HE_j0l_%x=1qI}py1CD#DA@^`)mMG+<LJn+7&H<Yax$Zepp)9qiQXw@hEi*YY zHLpY=FCTO%SW#+XN~J<^ep*R6=vM23qWtut#9Yu(RY|D|rJzf)GV?%_94V#Apq18o z3Lels8K7IhaubWPL04EM7nLT1W;Sv&b5e^-^7B%;@<DS(sS4$Zl^~<Q(<D$66pAZB zD}VJA97`0y^F7crx{4Kw^Gl18Q^6OlW#)p~#Nd!qC<l$Z<tC=2Dx_8v<bW<pvj$Zz z;5+7u74q^Gic8beQ;R{aD@G{R1MNKlHP&+yOG;9UxWLmYB^jWR-27CKwi0mUAdb)i z5AK1CE66WN%>z%=fM#KkT%xDopO>7fkeHmDT2PXhl$n!RQmIgqS`4~HuLyKdT2WCZ z=u)%N5*<+BfbUXE0_{XeRX{{1<YsP#(gIMRW~C;VfG*0;Oaa-L269YlG3f9Xs0)h0 zb7$~G1WFmXAp7%+QZn<>b1L<U)`HSIW)FECICWxX6km8oSr5`^7%`fB6%rLjlkY$! z-wluwc_X+;-2_gwf?41+joi`&mAK&Y7c$0_TABoHmq>%Upqs(kkkWe57SQ0BTzYCA z=w?6Nf}+g4<jjJcRNeeE-TZ>oB5+w;v=uyTrV?AU4U`ku6H7DHyjfwJq_%_2)Y5D$ z+5vXjPB33ELXLrf!5w0*LIBKMP&w@nH+L7vIH3#?s1x--PTURFj^xA)&<H4!eS1Kf z42dy*FC@hFft|G<Y_4Dy*iPgS1GyR;V&EF<09f%sh~kJk7SIWh>7a29@Z4`&X1W!4 zcGo2{F})V)l1|7dN=j-$YF<ieUUDX+Xa<$3X_;lI3R#I|iI7_k!SmaRC6K~5Gp{5y z9dyTM3b^D?0j*j{1x>scWMt;#bETE$fh&?kaOnw|9!~+)F(7kOQqvMkb4nBn5|gtN z(^H{CH_4^NCHc8}xs}QJMX8`gCi!{Adf=Jy%$)pM&~$dH0yMG};E@fA6nJEFfv&5} zNL7FozL|OH5KZ6%5}}(0QxZ!O6^c_6i;^>R6iN$n@)J{Z6p9nez_)yYE@Lb$PA%d} zEG@|Z7uC=)aL~X}T4_!W=-S4#5|D>M-tet-&JRjeK=mqku|_6nuVQWiXkTScB^SJ4 zPfdY12pkPiUk4QBC#Mz{JLeY_loki47M10smgs@P95ip3oSIn%TDYMAz6P|o1ad<p z$nNsgBv1?#rGXB~EXfDeG9Y6>XFWoEm71cEmYI{P!<DI*s)yKrS&~{&qL2)>40Hq< z_<GXhjMU`pV$k-U#JoySfPyW^2VFG@YAYm`C1&P8Rs%q4``pB0(D9L=piF`+pvcJq zPY!@mQep}C^3S~d67Z3rkb6Nv2BPT#t12(bEGbFN0|jVeo<eFxNl_x$)!<+%P6ew0 z=>_$9poV88mZgH!C#5RnCgzobR+cD$uXY6;T?%e(fHb7$rGT4gT*Z(ORVW6X|Dccv zT0vNlpI4l!kd&C54KfF$8WiWCbIek~!3l0sfZGwEl{Ij$fr27AAABY^x~D)PsZf!d z19m$otw53~sP>l%ET#&$-aO4@oDGgEWi5i+13?fQBXXd{Ov8sgPLHQwS}F_!`{G z0k=LtD^{Q_5U{&J4I1!0wM7b`_y(neV(@C8%rr<_3=*CoAAz)HB1bDY*g!49A_cJ7 z>8X&lJfMq4!2ws2uK<~QFM+gqAh7_81JJ>!1&}1Imw_lA!Gnm0z$FuA@yHG<jt@hM z$7)2$1sa$e#03|4d~&3fTVPL*7F(mm)-Wx$ijF|qUPr;rsbk<mOK`L~HQJmSZBC6g zr&23Q2CO-S-17tV^$<P3<KUv|1hlBSz{<b?T2qd*Wd>@ZLK|tR;FZ&$MliTj!UdUY zuMSB}kI{wnNn&(Cy^<K+oYaySUA?Tt7~QhO+FICBY;YSfsWcOGER2Gei@&czeiCT7 zO99jd1sR)`SyWsCZqdSee@M-It`N{j9eA)VFBLQ`o?Mig2tMB>F%M=Cv>6O>7|4eF zB5)TI+DQUC8`NI_^|^8qi;F>1MhYdRMR_`q25f0Dw4It-l98VR8g_(w5@qrkY8tpz zo|~ARs!$B>wdp7%m6j+Jr6v~V=YhIFpm`O<C?st3GruSWF#!*C3&^D~FF?Abd0e1F zck)1^!+823dJ2$XU&H`%B53FpbU;7YXXP2774V>t1@~H#6Y~_n?uA~S0JS}{SRpSJ z)FDhPs^o&r-GMZLTK)*PDkSEl=NDy`WaNUneUKo=7A&bnMa7`#0}teax){aKK~j*B zV0R>@7o~y*4!~UrF65!w{33<?JOxlZ=NBntq!xjCpGA<#!D2{f11+eE6U$P;tK1Xw zz?~{^oMaY5R&hYO?vSV`%LFg!2lc*ExFG%qNr2K3$X$?5Jg5hsngZ$2Xn;ESV5yYc z%)HFvlA^?t{31<|0pMX~NdFCV%n<12CD4cgXgVH|Q$T@N49Yy<WC|JsF5)UJNCEXc z!5vGGugX$$D#63KAbTJo8j_d}$x5J%gy`PGx~AYP1lmuNSX81=npcvU1L`m;<RoIv zH=tp3&>jl7tDrHS3QnJ(PBM5rAAAc%aY=pw*eyk=#ihBa;Lry}0_XsbyuADp@CX?w zZ)Sr=+7lH(*MAf#6y$?9N9HM%Wag%VOizVo7<7NsLNZt~D3BnFaEc)V6cBIY=^}tS z-iaw$rNxlGC8%2snyP?ib#MW}1ukY4G7^iDAe%Kn;aQqjl9-;JngVijO0k}TXBuR$ z3`i{~UQ%-lN-9ConF2{Ipivy~Abn=BLQyLCMiF><2i5~R#iS^+7#7vw2<C$I*%jbj zZ%{89oH%q8lJZL+`(yG!`#s=F(YyDslm=D>PQjqwHlmB41fB!{CrceJ&<>S6SPwci z1)S=OQlTXPIFc~>(kH=XJ!W582-cTA1?fv4p`b1Rcl1D20kkFnR|KGX08|YOOf3L* z5~#eOyb=H#g{`my#}>Fu9f5TK&QKYx0*XPiq~H<)RMZe#1%Lw-z2t<pHil3QfYlo~ zD*&+S(egh7wDc4<YeHH1UvwHWC~*ed(mx9>{RJaNTl%9d{n3`b!e~o>w56Ysnm0^Z z`pCmPpn)C4FwZ$~;eQ@l_|ITwU~mQPzz6ly2+t;iHn-;$mn4GLJe8!TfCCG>Eg=&j zS`0NNuoOIR@0_1kQk0(qX{~^Ig0L|b1*9osuDsN8aDPkzG!_AxhAc|VD~4XASdtI! z%cAv;Kt`n^jXgj$rWK`vJI^Wk1)!<Zl6-}X%yiI*L4J`!PJVf6kpk$d70_xdkT+5i zi&Bd9xIFU|GE0g<XSjjZ+kyJ-X_@Jzki{Q53W?C817Pd7N)!?mKxYPkPc=3&P)NxH zpFx~g!c~--o(Y=PhK>~!D}YBdKpjKqC=ayn2Abf6_EU=!b0Nnj>w#7RrYaN{q$Y#6 z&E@1&>VU3sHZnjS5`*jnfvf>bPRvnAtpF`B0}ZQyy0(cWB}JJ@r6s8fX_=`xDbR=j zFS0I5%}Y)#u7#=0O)W_T&AlstZa~HyK}kwY&d*IP<|+UUCqP{a34chiLl(+`ny{&f z#hIXE7C<L{CRHkcM^Hc>Ms*IPGY@X=<`>mMI`|+J;9;M<#N1TS$~K6igoH%offaRi zxSK&O-OS`vu#-W~$SekrT0w>@K%Oa11uX|D0>=x;bcl-;KvIx32EO@4srhB8MGy}| z>_ZM6E<^xk7AwF;Ws)it5>r5n=s+v+K;slhT0lcyAge%4deAx2CE%k<!5-v-rwi}| zI%vqMAipRPrUM-D;9OUfn3tZ4*h7$*mr|UZSddzaKJ|S8oM$n+>x!`M`bDq;!-!5M z<V;Pd9Zg)G2AeXPr3XAqgW~}y0m5?!opUtU9RxBoSWVF-NT=g6xZb$}PNISleJDv3 zk`wXt^@vNO5MxFY>3}CvNJI>RR0?qjfn*9%l!4r20yUCKlVBUHuY!~AHE7ZW?b}XB z04>$L4i-_2ExG|(M9Q3*VpMb!yiyctzdUS%HFIW)VbLw<{%Vl%p#9aiA>*qM6N~OZ zGRj@BZTG-tLv~q%>_^*W&Be&TfKpFBYMA+`VFtW3pmtpe&dSIUI-pf0bay1YrYyP- z3AzX1pnC`jx(E*RFdE5i3Cz?DS{e=7iT(&2XpbR*2HFh>UymFPO5{(#5*V!x_*THD zAbHpc%g?}OJqHPaPneLYEqVdwpz9aP0$B^n11~|xNL+!OWbg{C{WVyJU_?FQW?OJ` zJhhf9CK<FJ26XNgR}Az5@${m^f{e`M;^^Y!#GF)H13gpI*lO5{-}utp9KC|Pbdb)( z0?@XPYG=^=t^#QNGHCA#Z1+tqR}AF%anyx^8A4egFG1F4!;eya19l*~m(;xVK>m3P zl7yY4{0{7)_aLDRLGZb9(91=j9?B5P0{IzgKJ4t|4`B5;%>M`}GkD=Q+d_>h`UJ@X zpTSms0ULqCN|39-9YWag$zQ>GzCrXr4s-kt=AgR)>RgT3q8}h<fOdfX1nd0;RxTJ( z0E#pEM-s>bkU-1;uM+(Yb`HAh)x32;G4u!Ibi;@o1_lO%OG!&j$pjJ;wzO3A7ZO4L zzybCj?7{&HFi@<4lK|-K4o)V}*&V5nDuxTp0q+H1-~yfe%g6;fELbpt2NboSZF0~A zmjTVgNXH>Eft6wgy8$TJnYqBn3Uf0sFd&&y#KHwWD3=v%7aQ0BtagDM19mZ}+yW&$ zcCZc(s1AOZ>v9ma0w>5uwDrSWVD*?zG=z1cxIvmAhc<$oiDVoP#HGAod-=fT2u5JB z7o{ZuawXi^;GhcSgY0UH&rK~ZPE1cN;s@C%Q(GheHc~D&lr<-{EH%fQ8Fc)OLTo4- zWV2g_WQKffhDvNGOHO89s<(D13+O1pP*&HVApf8uK`zkIEo$CcFn<VvOa+CLFxb5! zV8bD&xrgSZRurUyj&D=|o&J~ynZpO~J`n{gLk}LI41Q1yih+!ToZ61Vh$3-F7)gNb zlmr_FX~TeA0Zw2U?%?3a;L~g@k^(D}Mks?-Jz20Ykpasg!h|V9F}6sSi-92v)RqDr zWm6;v;(^;;I6_Jh8dB`xjzNB&e(pu`=wYP*@)#(r6u}Ns0$VB=q0hj;;F$*sZH1i7 z63_-A1@Ildy2T}+DhPbuB<Re<)Vvg^5I78#!P+sxFbm{cP%x^1Y%?Us^dePA@T!5G zsSdUW61*UXV+5}TSeYhVnM`ew7MOz?o*6jPm;of@vLFEl&F>nqMcN=AfWk`$Y=bV? zP(kpm!!DphEFoukf>)V<w@knemrPVh%1O-2RsaR5wL&Q(8J6Zj5+XSK^uWeph9Af~ zpzzZN*=|S;+lmYz;b{o=h7s6aNO*!gh6v9LDR6=;O#-J{W3XxyglddbYYLVlHk1uf zLRk&ovN8kt6BNqkU<)n4h6;l3m3GR>PtH~-EX^-TRUjjTEx|@%hA_xypb)kK*=$Iu zO-0s_(6s?O-xh2qBy>R@LWC|fSna^d>=DW`Od(Y|IP5`9Q3tRbB3SVkkS@?*g_VrX zu#(Xc<U3HfI)QC;2AfK-WOM;5!wfT!vq53z3NjUc;phel4|lM&9$@nz;Q?|8MtFFF zm3bkQVT6Y_SPl^$pu!P%W_E*y2P88il9><4;h^B~1zYF`Hk2yK%pYtNW{`n=1`4tO zkj<1Qvp`6&27#R)47L*ztRN3z1ZxObStvpoMzDr~<q*M&Kbd(zgB6y{++oQq9OOGt zxJH0&j0BrXFquVxm0^Y%$l0JUiw2pBKbgfq!Xp-JZ5-G<NO*u8f)O6^U}XsiWf<X+ z2$n;H2mWN{1q~1MWR?VSI4C%h!4{@~4W&vlO9dN+8Dt=zfr2azWHaT-EFBW88DQsU zg6)I^E676_!I}kDmW@z`5v)02IYhAHPi8*QV1*?!Z&)(R1^EsXu6bY^^TDPPOlAdO zWtd?GayBT;3PGmgPi94s@F)gbTLLx@5*{FjV1!30SXmiD8Af=NgXIw6fj^n~LBj(* znN@%s4hoJ+u!U7%L#dL?s=-EK1{ug_pdhOO*-UvdtAzw>9oYHxU^^kf3i1#}ur`2| zH6oN@1Zxvm4iT*QlUV>XSYgS`AC}CTLB0cpYYW)MR<NlAlUW;B8D^M)oDB-Ic95y~ zlUWBOJUYSFc7e@<ga^nW7~#<kR@Q@1h7lgUU^zs1;7?{j(C|P{W_=)sgMy<UY~cj3 zp;Sp`6TwDd1{ug_pdgzBvYGN^HW?DEQ^3xj3bqpxtRN3z1nV@gvgrtA8LQCRW;4KY zh+xH^%+jF23QK0Guw*t9<U3Hf&H~#w8*D1UWHtw^3^U9?&IX0qT#%{wli55-c+3Y| zy8vt+Bs@S4!3d9qU}cLC$}qxXF<1@}9{7`4HZ(lYli3oG!$HBZ6l~!#u%T2*X3N1w zVFnq<XP_Wk0kWC$WVR9#tgFDzUk$bs609H(VFc?Mu(GuXWf;M_4lIWVR{Y7V78<Ou zWL5)9X6r$|1BL4bu#FqRrV>nMo50F2!wlqXP?&87nTkJ|ZGnWxR<O0(z~({11LP2l z@YoJkwgawArnYD&m_uv;^r8fSP{sq0Gk1ZU3G)1Iu<?7qCKB}gUa&Gu&x70uGIbxw zRQ#Ub5Apl~u(b!l=0Q9UatOlnsJ-n&VAY4=s%2`6j(|CcFu<R;CP2dglDD8?a1`WP zP#7Eo8-E;ZB2_Zh39wO^;RNyrD4b4$Y^FS8oq~krX|VIpfbE2YCCEd#!tyLw^*Oj| zncAZBU=AWI@n@*H(6EGLC}>z-0Qm?MmKVXsUjmy*Fg;xcE5i&YkQ+habOmH8{`7Pe z5(d}6)?Npj2MGg^LvV$`4Y2B)aMd!kMYq5lL>S;tPxGK*fRdhWgIo&=gF9g3?}AOF zN_x5nHVQMGK>h%Q(|wT5l&7Z$kg$9RcK#!<osh5uc?efnJ_f6Pf>4c7UOxrP5gWAY zQGymRMDYydM^NZK2V3|8Y$#Pi_a)dU%+Lk-3>3PrKsHkzy00Oj`v&a%w_rOVp$qa5 zB6Oi6Vei1o-XoM@1nUQ|93og5@lF*$gEf@J)6dPn=p%IWdn2qe`~>nND0DxA?fn8a zTQDMlfq@|adgGBoW*%sl8|W+|g<{YSMbLW2%#xf`J+2VgZd=eYIMCuc(BLj;e=7Lk zxx^ySv3C_E3b6g7nI-C=)B6;PGxCc{z{9;?!S-QB0VoteQSc4qJi~}28ad}t!%QRx z6@7=q)DLh_`~*7<5>ueS!HB6}U}e7%$}nQ;4_FQnQ=qb?=r3r>A`!GaAwway=pTre z0OH}8z&L`MExb>{V(vdEXh1Q?zzv?M<A%)CkvVU{1lEoj5g<>3B7&J4Jb_1s=|wEu zkV!tUGugoQKtdJdaEwr82P@-1D8mR<POuyzRPonZH=yAMskPL+ufxKR3*;kE_;G`6 z<N=#Xu;$_gE5i&Ykh4MI#0N4Jf6c`Y2@e6VwSr*tAmIUW2u64aft3j(lwpL22v`mg z9-vf)dnEWaG&~?R7^0XJ1vwlP9AaP##lePBrI?if8-*EUAfJJPOcG=><;AQNBv_@v z&X)n(2?<t^hcJRw7OYGTp$sEf<-u}@V8x%z9zcT?mdx(Ml9>X?cc5@p1ly<tHkDv9 zQwA%;3^S0kL1Cr>G8KO^Q-y?w8rWKOuz8U1067FBJT$<{G~vo*YKyeM9AX3D1xf%2 zWpy($Fo0aD4RR^S|2kkBbisxa^uHch8K(b1&IFmN4>A?M{|zAiHw0U21U3)ie~?2E z{zvU_7=u-tz*WoC7MX%M#0JA#v|yMH4F)rigF(Sy4z|GpY$(BCummf^3<i)hLBU`J zG8KO?SVMxr25hY@*gQxufE<D=80^5R?cu6rYKt7e9Abmv8(J`|h6aNp$ibjsa01)l z3^tTtFt~t~VFm-pnV?{B1(}LJ7~CMi;10Id18g277(foe6%3wW)n0JbGPOnCU=AV} z@Hf6-!2oG?31w}E27?dC!JuI91>4{UHdHVom4Sf)X>kSY%1MP1P-{y8-oDB&QYZm! zkpa)NBQ?T6N9z}ZE*r_rBckc$54IFDP(hvs1!@4ujfN5Fv~&|%`zsI<NkQO12?o0l z5=o$7!WBs&VAY{;)iSk3VPFm-lJM4uzD$hJ#0serg|c9YH5?QIpje6kTM-F1Rglt| zanNLT6xb-tum|}C6!y^|n<=jnV<6!f3wC}S*iJ}zf;@yPJmbNt6X2?4YKs!V97K5H zP4tNHgr#~|cqV~-1q#n(uoWp_Q|X-QQ^A&EhCImEppZ`kxskr9J{=NE8Q?(41iKFs zOQ2xF6-!xQ)!A^>GPOlHU=AXd@HSX{*<q<3(qciR`dm;5fMO{RY(+lURDwlx0azJk zxPsgX3fDrAsrZZNB1kwCgRLzAn+FL8kV9~VLn&Bw8C<nYZBaRxg9r!wxt|*r4zS$+ z6k0}CfLsg;hf1&&RbW%8lKZQ{Mq!2($S<I<ssY(ddG4=;gl8St`SoBsA>j$~5U%iS z0IP0<tCp!PY65c*;fX)@!^0Dn`(feP4DuByJX^q4w1Q2gbM9{gTZ$R-AYX$*z8&O7 z`sV%)NGx@N1EmY>K1eKqf(chFb%Ry+z*WoC7WINTh*-j(>iN)9y(AN)x!wl~0Z=UU zgRPhVHkB%=ej?Z?%&-Uf1r+v^KsHmJ>L)|Oa|+n`Q^9sZ!V}~nT;Vwlta>_JwM=c% z3@`@~p7>KeKP)_9son+}o-;wd0)^)+uobhxrqVgp&jDMC8S)@sgF=2T$c^+(_46RH zG#?x&3&8G!#1bf&aK+L>u<Au{)iSk3i@_X3Ea6Y}La<nZmGu_TSXu%K0Z=S01zWKU zY${b!{c^BTm|+j{3n=VYfNZ8b)vttv=PI!CSA*?@geS;DxWaP{SoK=CYMI)ibzlx6 zJn^S`czD86JuE!egM0-F&kbNJHiAv1bE@A2wiGkuLB0ls{AQ3F>6_}eKw@btI8e5M z-3N&!P%z<&rR`wVJK(B8^T1#ZB9`!{dQtRLUjt3`yFeiTilyCPEB1g*rAn&b3pNTf z>_L73h5bH|&6KD5{gCiH0CxUCu$_?b1bGNocpd_)J`7h4no|aI5aEeG)x*ORmg-^Q zc@*R;P<S2#TX7t0DxFjP39zM@ArJC3DCAFq+(_S4e+m*yr@?`82JAjaEP;XvS1g?c zt3C%;4VtY6a}cqFzkeeIOZBk+%_?ZBzW@pWP%K>pTX6|&D#8BEWw0{La0R&&6s}i5 zrsD74T!n<gHL$hU!RA520pt)|;cx@2`X*d8XvP}ML4*VT+^+x&2Uwj43y0ev7lXp# z4%mvjU{k4*`|p8`!VD{rUqE4XA7nG-x&HwqJRgFc{|Ia+Bs@VL!WEv6!K$CYRm;>C zJq2?R;fX)@!^0Dn`(fev4CE_Ncs>VP@d9iropb+7u%(zG5AroA<X?f@NZ;K58WKxy zz=84>>^?{=fr1HFEWHD(eh*hIQ(N=_%t6Ew{#37mp6ZuDbN@$B2!LYg6WEH+U{k4* z>c4=E!VG(mUqE616=XBzss0-zJimjT{{w6%Bs@VL!WEuB!K#13Rm;>C{RVRo;fX)h z!^0Dn>S5ve2jnYIc>V=j@egb&om2gPu%(zG5AroA<QaItbJz47$!6pM&v`TPfTre| zdB9WipzZZppkTrkODtg3tZ>ybwMA@T4kDKD*Lmu&R1d53V6nsw3IR|oae%Gh1e;2* z&f@|r!wgrDJ3-;f4KfvfoyP+S2VStXd|>k+sTJf9T;aeERxJQmEmK=02<9Nd0e|k- zfQ19B&Vz-65Xi-#a1aJtAp$m)D!E@2Y!qf#f&2mrD>0DGl;?hNNO($soi7Qt6B3>v z58(<=DX?m3xN4c&A{j6T5uW&SKRi6qbH6OeSD^5e16v^vHkHn~Ujb|>X2^ql4GMWh zkQ?b+=P5yANf{g{Dq#0PVhI#XxME2atXd7OTBf#09n3+*68==LiJs~gLF+sXPzZox zNfT^^7T8p(q<U?zQJ7&5@(U>JbwD;#p6YcW;i(69zCPGaNO*!ggeyD^z^V=5s%2`6 zjKCa3c;Zj>@bHACdRTZGgM0-FPZO{ereIU)oa)WMmSToH$k(8dHwU?qzNy{<5=)lg zK(PY54-!kDV8Rtk)?n2(aMd!kMYdoLB9`!{dM)%+KM$Jf?LZ*_iY0rn6%Jrisgmj) z!A4<*J;*Phuy+F4OnItzhJ>dJ*!iwtJ0al-@(`}@bOWn)hpU#UE%E?!5aEeG)x*OR zmg-^Q=?U@`C_KHuR(OL=rE{wH0b7b0@*rP>Lf#kTM*60DKS(V3g99Z1>^?{=fr1HF zECqs92f<a#)D{JUIfz)opX#;IQ~hb^tYru&1VFJA3brB)Y%0}GX9x!yhZ+7L|A4|D zbWThLbxvo9goJAp*c;Jcdm-Tp@))jgjRC8Ug{zjSEs6tk5aEiy1+5DUS6B-g7OwHI za7_SPkq9=GU<*14tPC@}K<)&ES2D;{{4MAdNI0Z|txW@)2MGs|LvV#dI#_iET(wMX zQ6`v!2nYP>OAi(fuog5d9I`+z2BoiTuoXFAQ>jv_=7NpF3@eadKw*^!vYGNyH6Ie5 z1z_hFg6)KaC&)v%!m|jhx)`onrnaaA%t3@F{!$elp0H9C7M`UbUxC823~WU?*i<@~ zsuf^MF+(2YYf#8ng4{^oQnd;aOV!{&sR6qW5=)?9!WB!kVAXYS)iSk3^<WMnmhh)~ zee_fhTe;K#3IR|oHG-{Z0-H*eRNo9X3N!3MegTDj3&>{5Q++EWJlnv|ZwK262~UuR zaD`_FSal~{wM=bM7np+xPyDGK9-gpN4-3z3kgq`D*#ows7i=n>Q+*%UQp}JC`5F}R z{UA5eH`Pyo#L`4?piBb04-!kDV8RtklfkN|z*WoC7EJ|n5V3?m)f=Lxdf1xfX`m1Q z#nN=J6*Iu5QYF>T1RI4J_8`B2!hROWX3A6jY)E*{0Xu&#*iJ}zf;@yPJm-N`&xfm) zsV!On<{-iof2xOvCoI*&!gC?WSD^4*1h!%^*i<^F`XyjXF+(2YYf#891-X&FseTzG zmX?D9Wd+!MkXQl*6RucV30A!dp&DcV#%iz}BGT|@0wdH+fY=wa1{5HmNLvfGaUIxH zs$_!oV52aj0^~JNRBQm*OnD~Q2npUzVCQcJ+X)F?kcSY#3*COW1*~i<LK#N5ZUf7q zhHKGw9tMUi8)gOu@Tq(|Ks;*@5BsJzU-Z!SwPl3um)QyOH7LAyfnBm2Y#Z6f@$CU? z#|&eTH$h>%7i1fG$MNlhgzJ8=GY^36frKl_;TYk15UlJFLK#N59tO)H!WDl<#TAxb zAsrPpUl(`?9s&6Y6oN;=b{+$pOR%eQ9IOm8q(BY_h13a<srb7pCm|tn3T*9Zuz8RW z0XYOCM9zSforNotsVzDO<{*Lqf0lKF1p%y&;>`?M!+0L#R8Rn109$bpY$`O%mgeN7 zmMD;WI^iX-QJ8@Q@(U=CE`w}_W?AxWD!Kv*$g5!IUjy3-2}qEK5CMt0b?G`-^$oac zncAY8U=C_{7Tp46&RkID1nob)4dUg1csQ~u&QQJs@+&Bm?}9D92ewNv!T@n@Cg|Mo z#Ny0iq7Kfy57v(vv><PRg7yK(IzzIIFM0?G&qrW~J_cI^2~UvIafRm-u<EA>)fhSU z8CVWAcyVsL^mRu~u811uIml<AfP4YA@g>+)XmX|OsK-}eqcFo1<TX&3z6RM0O|InI zRP+WCyl=tIe+RY`61*S}A%YiL!@LJ8`+!h}5w0J>a)@xn-`w(mg)5}FrRM7aF9|<^ z{09oz&tN;hfXx+*NJHLD4%u5(nwOGV1lqi=qfnBc580p&zkwR8gzSA*U%|FwMgk}t zK#}kb<VeGa44OI$ZKKt9NR0ge2g^^e10gX63Mh;i`vq3^8=(v%#{Pii5HW_o?(&4i z7_9C>#Moa@V1Q!mAK1?SU~>u9T@1XS33kjN200uQ#EiV)1pwlxTiGC|&O&a-En?yY zPuMf_f+p-)z~(_h1mqBm5Mc!?V}mP`sV!m$bBGNBAJiZa%BqIeT^t~%f&zdOYy}tC zRDuD(4OWI303dgQ0)Pi(D*now7ZLz`U~Boo=0O4g<Pbyvpw>A8VAX<f)iSk3LSPOe z9ProSzOZnB)#0#k5C*vz6b>R_D@4JjQl(H70~>`IRv^EC!b%)uGv$S%1SC8q!OoWg z+X)FzkcV)Er!-i#3|zHLZILXPg9uOjg&{mVA%!6#UCDub1qx4juoVhmQ|a9IR0La! z8S)@sgF;>j<VO1TJ(VG`qyi2URj~UYu>=YxT(P7ER;`XujZq$IfaMU8hCdVdp=JU^ z%RmzpAfQOo0^6t!HkB%wKnH9TW>kQ@28s$@kj<250zF9Z>Vutc0JaknydV!Df*0B{ zFa#?zLMX!sS7WdoB3$uj26(taGJ~3L0K8>j0`eayWKF?#nt{!w-?2C5VEZtG9~1(h z;I{xdk8a1_SVCgS3LF&HV5dQ12^2UOv19{QW{XgU5lePpIYcbsZw*AjQa`LU5DAYZ zdr&ZdV#xt)rz6;0f|a2YSQ%#Ef*cMCTxXD}_$xyfNQk(Ct#t#N2MH07Loh<b9jwd) zp$sELJi&5^5W!y_#K1xXQYj+J122%vLE+&Iw$TS{Dpkq@U$9Y_VFvOVD9rpoHd9_6 z_(Q@q0POrgu$_=_1$hV~T!X;Mf)UCv!ZidehX_~vDJ=ySuCSDr3{PpHApe0vHVkZM zIM`f*DJ=r53^UX~4hMx=B*;|!DJ=>TBGF)LW5DJ?LImUxj1Y+hD~m%Y!w8XhupA;p zKq;*#ftP_HYdffu59;zKf_U3NJRDtq^z`S82&W{Fk3iv+40cHh*fz39=TgDiF~bk! zO;GryfovmhbS@ndt{GrwW`ga3ge%D57~z@)R+bG{2HH&z=AZ>+E-2{EfPxMbka-~9 zX%G)bK*AFoBqIxD?T5DV^Fba11!Do&;zF=p<d2;cf%RjCBgk8za4ZH{N9Nc`2_zs( z!4540TLcM6kkb(XiP|qH2dl0?sK!XAm0&s4;Ke<5k_yYYkbp##h*cn;fdaA`Y-0`B zRH~GSwP2$#!xZE-P?*+%Y^J<KtcL_|1K9bEU^^kf3-S;mc%dz%Ca|(*gffh9Z2`+6 z!WDlDDGe5`uohApyhLmT`41GbZD2dw!RFF??4$#1D`q5s!T}TsoghcjdF-SM5@X%q zVCexn5E5gcfWnBeUa+!0gffg6>j%prVhn#BmJW+CSRIClu?e8S0L9ouu$_~@<`S&K zCWDn>1~JItpdg+CG8KOvHWd;g)4<kF2b%{85s*VLLSzP5*-W@HncAXRU=FcCP=*== zLRq(<rRr>uQ$YbR2W-V$u&D$CU>;Z*W&nWP2?~JuAXD)Nzye4BECgG-2y7lC06-2w z1ORFoxfrZ^30$>IZP8LN2N4dS${Tl~SOE(MNTG-bhh-oagTi4s*oqZkQ>juYt^^x} z8CD>_fWm4O$Y#n5#nq7TTmyFgTCkmv@C11XS9q=it6mRREmK>x0n9;!C;q|^9-ffG z5D}gmLB0Zo=O(Zfo57~idF*5h*iy`p2l*Nl@>@Y}r0>|tHb^XO2M5Xyu=^mf1PUfx zv9uGcdKX-^Ol{F_Fb5G!_zS>lSgMB<fQVSy0}269EbRqbu@7u2!Q8(etPC?;LGA>F z>j99d_;de3NH`n<TYDI69wZz<4#5=;N5HC&!d1)E799g~5aED7_t(I}0X_F02e}v& z4ky4?oCKRnmE3;{Y!qf#f&2mrtJ5HxDbM|9AmMoy?EG_JJ0al-@(`}@JP%fV0j^r6 zw&)_5g9uOjxgQ>$=(+zA$XB57ybQMD3fNRS=l-i;OEE(p<ZDpKUjw<3zPbN8B$jS~ z1LY>zeUMlJ1rx4Vx&>B!8=)GbHFO6ohln)%nV=3e6CnBpcR>LHinM!R8}EZnrAj7v z05%FUDnMQXMa4sq&6H<?N08us40iq#u$_?L1$hV&ywHBZQ?RmU2xS=I`W!5W2v_`> z0UoZ9%%JAm0Ph#P0QnCTvM<4Qz5<&|zme0|VEZtG9~1(h;C};h9^FPx-$G*P9XKf7 zgPjJ6B~ajC#L@?_vX2O57_syTEQg3C{8eEWEcHXGLN(t`cr1Me1p_FSzJTrg3O1Ku zW%v!O3^Q;+4hIG9caW+0E5jd<5cvtV_7~VZNQi(Of)OIW!OH%?mC4i={RMM~4T65u zAP~xuVS%gx`Ui3<C;<M0tzh5-%@7j|07kGf%m4tn6BGbUd;}+wnfbsI$t--JiDXu= zd5{1AIRp^^sC@x8uxfU=YMI(14loB14)_bg39xX0wFY3}zzK3OC>*%JR&aw&rAk4_ z12zgXtU!JNg%vNzX37gfK1g`-gPkt`wi6PbAP?aRPeHJ1A-HOp+9F{v2N9n53qW{y zLJB}cx)K5T3KX8AU@OGHrqa1JAP%+^Gvq<O28Fx?$c^-E4M;*_NeUb&(qQ*NVhI#X zxME2LtXdYK8lyav1Ir;I4Syz>gqjHutpRyZfPf-R0c@ip*i@=y0wu6fm{9@p8Yn81 zK{ivK2~;4#s|t3$8rV)q@Pa&q2wrGwKpm`11ECBfTs6URh;YT98Q|dx$qZ_~Q{eTC z7RY~~kktm;sRK5beyssruzi@p4+;TL@aut`N4M61J|vb5z(HXMb{Zs>K!Jl1OGaR2 z#t3B?v19_4L&OsP*1$qo>W8%k7Qkc46ch}gSTY0KX%04*U}b0lR)!h4Acunj*AiqZ z{?>pMBt)#i*4lv0gM<jkAs8WI3sz<aS0+<iWDn*L8w8tCgFq<D3)&iR067&D0FGcQ zoWQ0M3;<`aGRyz~xf2usE+A9!2Y@Ri0NlXVx`WMw1OUh(hyXxs4S0Z6d%{)A)E0Sx zImCv;KJ;+NgNB1Q$i<*=@Bv%l3pSNtIQW5;VTJ?9ouF{=2bqdL90DNW5D2z52y7lC z96%1i6%N5*)gf@zGPOmaU=Fe2a11>hDxu*J268bd9Kyj?M1V~t7!HwOWtiarawjMp zqClqN4~J+-IK+UhjRl(r2?vlvaD_u0Sam#HwM=bM0+@pc2mBS|30OG5T8FT3NCdeU z6b?yXE0V#cQl(-{0UL!GRv^EC!YUPHGvyUy8YDc^!OqVB+X)FzkcV)EXC_#67F@MV zZBaIug9uOj6(T%5Ar+!f7A!n-K)wQnXD--^Jg}*BZXM=>EyWCZkgq`@UjT9=eOrfx zkXR}L2TC#6eUMlJ1rx4VDgmo5g{zjSEh+<Z5V3?m)t|zZ>dQeP0E(pwuoabHQ>k`F zLKWCJ%<u>K2NeF*Als>PMnVlFTx-GJr~}&z30IKEaD{6<SakzjwM=bMBbb8-SNy3T z9<J!AzX{|sP`EaOt!M$8O6Szy3bqt8^g+G`g?<~zjr2|Z?T}dN00&AZ*nN;#0tFMU zSn2|+?uM(DsV(XOa}cqFzd3jYmii&hK|~qV3km^HEcJn{=m(ohu<n}xR)!g_Aa{bo zbt1@A{B_?XNH|OeTRR189wZz<4#5=;Q^BgI!BxxD7EK3p5aEEo6gUS92lTpc2FS&r zaF_|UViwp`s?>e6!A4<*70553u$lw1new`CE+jnXft^1eY$qf<K_0>to(sUL7s6G` z)D|rQa}eQ)Klj7K6Fv7Y2KfpUo=d=1ECriN=iI*xY$;~QgM1AN`Q;!t(l__7fW*>D zaG<OLyAKjepkTrkORK@E*T7ZF)E2D;a}cqFKh<BrmFm}lLI4y?>%mrR0Gmp+x^E-c zILz<|`3DsKn?SZxr|#Pf3D+%PZ)^qI3kg?{$8d$~Hn8gLaMd!kMLWP8M7ZKl{qS%_ zPyIVVJ_Cj8F0d85!KTtV_3r^&iW&MKUxPw_FUXDbP5t{Iv9uo?C<nmqgTxXjm~h3? zL9psWaMd!kMTfy0L@eR2`!2&$KYHDF1QY_GSUL)};uzRef_2|<urkbW1-TOxt|vgI z;;;KoLc-w`*xJ)z^B~~>atN+)I0IIF7Oon!LmJFMgaiIk;0i1p(CfbQAQywe;R4u- zi(pf!Qukc~8-*EGAisdZ>N3b?%Im%>knp?;cK$W6osjSZc?ef{UI(kb0ap#$Ar0mr z!V`b)hleM6?!N`{6(~G!gRQs&HkHn~|1Q{4%#a898Wi&PKyIXO?!OO-r3c_Zc?fnN zB$hzIge#UFfmJ_-tCp!PdIIJkVhMk$zlJN-KLv#VD3+dqt#}SLm1=e03$SsR;Scf; zDEwc7Y^P4$_X-lOufg7U1GX0ut{{)$3fH$_)$ib{WonDwgE@$B#h?1&;fkL6KY)A& z3fGTdD?WiurE}{447L<A^g+G`h5i?i8|j<+zd~Z^8#qwDgWU&-B~UQoilrZ5)j#2? zWonClfjNj+!e95@fTe!)y6-nA1VFL$2W-V(u&D&=zJFk4nBfX?Cn#M1gG|L=_c8E; zXT%x#K{Mh^{NRar@LA{}hu{haX0U1&xN4c&B33X55f1oEft#>!K(G7Q_!$^7K;gg+ zwt@p}Dpl$}POwp!VFmIFD6F_ZHd9{raYMqB2kd-au$_=}1@aKC@Z<xl=7+16sVx!! za}eQ)Klj7K6Fv6}f_w!EPa&`s!eCSBocl$<mSToH$k(8d7X`VIzPVov5=-LXK#>5u z4-!kDV8Rtkl3>+RaMd!kMbcmnB9`!{`rEity$mP>K(QnXwn7eUD%I*fd9ZPq;Scf; zDEt*bwo|9>Q-p-864)EcV0$6q3i24Pa8&`TR)wpUsV!0ia}eQ*KlQ`I6+QK<gM0=G zR}HWgnqX7uocguEmSToJ$k(9I*9N(fzNuda5=*+^K+yxc4-!kDV8Rtk`e4-taMd!k zMTTGwB9`!{{yXTYA2#o41PTFAEE$8XFaeuNl``KHY!qhLgZu&tdoz&Dl$ZJDknpqs zJKqv)CnP*U9>Nu#R$$fEaMd!kMK)j#B0TY@dU$xkQavm@Z9%>Qg{K|Z3VX1rbWZgS zU`sJW9^`9K$UB1ENZ(ZN1c@bQaG<z=-3N&!P%z<&C0DR&H@Iq<+9G!_2N6s7TYS%9 zsUFtigT;~uC<H*U<O#OI3v4RE7N0j*8D_YG+zAR-ACRf|TYSEdaPR|L>kl>$5)L4T z;0lKTu<Ag#YMI)iATS3J4)}Bb3s^Y7T70l@2nM+r6b>O^D?-7hQYH6?fsMipE0AA6 zVHFOtneyBp0SV7Yu=At9c0$4v<RM()84Xq)16M6mTNDfCAi@)W?uUmbdhU+{`3e-C z@n9<wz^2kU_a}la#SD3nuR$T71ac#NbAK`<mQuihk_vVoB$hzIge#WPz^c>Xs%2`6 zGQb=}EaA`nuVJYkJ@;pVLI4y?Szs%&!KM<-{W)M|nBfX?Cn#KVL8ju*{dtgZ$Ol_n z05%U24j_l%3Wq|l>LR#mncAXaFb5G1_;ddoSU8~P{t}RjLE%sewxSGdDphiSIoK%7 zumbr76jl`=n<>xzm5}hP0z1DNY$qf<K_0>to;6_AwQ$ukwMBJc4kA49=YDv2qUZj4 zkgq`D*#Nep5o{`*bAJ=qQp}JC`5F}R%^)|@H}|(dVyP7zC~aW(L1GCMOt@mH9jv+o zu3DzHs1wXV#1j5g{}w&f!&W?YfkFTjOWj~AdcdYqCDr$Wjlv9jkY7My-v_dp@>Jgs z3C{^&=T8LN2?<Y-hj4}GB(Unq2-O&CYNvqZhz;I%sKJX^Q9c#qNl@@k1KT(qY${cP zcLvxf%-{ui4HUdHK{it!yt5#|I~(l$Ibb^>!3**bB6y)I%IAWW%|j@|2-o>wIYhYP zFI?c^3MpLFd_OS4&VOD2@*gN<7lQ3v1U8p`E6Nvx?ZXUyPzZp6e+kHWbX!rr6cS6z zz(KJb>@-L$fdU63mR5k3twboph^19vIYcbsZ(8s$g|d`X7NllDnigul+)S`oS`7*Y zP%Nzh+qo8OF2TmdI<PX#zy&!R6u9d_rs8j0Y=DHwMzFP;z~(_h1mqBm5ZMe?wgsUK zBSf}><q#o)zqplzg$SgPfhZ5Qfm{v>kL_R^cYsZ$N_nsoY!qggfxHF^vt1yYDK8Ip zL&9|r*!g?Gc0$4x<ROf3-3L~-AE68*Tn~Wd5aEiyJb;HQtUQp0r?i70|A9jG5ZKPc zU~}nL9vlJNhZ+2!5C8@LQIPZKRvsLK#L{taP@Die4H8SBz`=;6lVD}15XvxO=`>gl z5li^X0~uKAhm{A2SULj=22d=W1>1QJY%am_;5=9vX5fMx4hq~0AXD*|2NxkBatUnh zWw3dW5CJ&^BSfx%m0g7^lc_Db2IdeO1WKquAe6O&6|&#-I>@P@0Js6R;wIQsf&p*~ ztPC>%K<)$uz-^GJ_ygb$BmnM$t-S{}4-x<%hads~b%)7)u<8d0)fg$`Ay^I(EcnYs zBUrGYmy3@;9smW)W3Y`+z@}2ATzm>P3Nz?HUIPW)Gmy=cmy6FK!TSR2{Fh)mA;Ams z5F&V??W9*=Wv>y+Fv9f>SPl`c_{&9jxWdXs6L`7!7UVxr$i4&H`5tU8{mR7;VEZtG z9~1(h;Qt769^J~tPmoyp3=WDfV5dQ12^2UOvGf(J>>ENEMl5{?%OPS3f4OJ_OZ~8N z(Hb60KS03%ilv`mJAZ-AC0H!{1}no1T#&;-f%^w!D*j^OFC;|%fvx=yHV+aaActUt z2!jA<Zk|y9Ha9O*Tf_wB5E}&cs6il<bsbtRG7CUw+gZR?u!2n`7yxWwWtaf~awjMN z*g>Y^4*(7U@Tvn&u(e!Z^B@5LatI;-P|HPbuxcK-YMI(1UN8p{4)_Z~Cs;T@3PMCU z@PS+mN(lU5D+Iu%Ql%gi1RI4JRv^EC!b%8aGvx)LFeE%hz|I#1+X)FzkcV)Erx;kZ zI9#<%ZIJ|+g9uOj1t2^;Aq5~JJS9QC0)?j(*a~T|sdOHNk^x(a8S)@sgF;>w<VO0A zLdij5Ngf<13Sjp^VhI#XxME2WtXc`78lyZ^2FoEL4SyzZM$H6>UXltZKtPeE3bs)V zY${bUfjZbI%%}i)4HOj`Ae$-A1e%cG)dD+T8*C>ectIXQ1TVBTpaWK>i%^CUu6kfO zM7ZM54DfJ;WCk@~7kE9R5Aq)<WDUS}8iLKGUu(b!Y#(OugF*ll{Kg>X(XBOL0*NJ4 za8Q_mod$^|P~c$1k~vtJ1(LF_pt?&ULlRmyWXRMOS%RgBji?k@27pCW3Ou5$Kp_E& zC~L5_Hehq<eXOc2*jCKw0tE#qy6ixXr1P<=_K-+(00)aB*nyBp0|gXDq&b0=IU^~< z5@{}AX+)&qZ^fm;A`RAxLqwV@C_F%s<_5Ob9c(VaMvMno8D=Ph+ztw5Pmrnj8!=vx zK=B4!>jO3q5-1>tU<8UUSeYM^GAx1O50*v*3jU(J02U~a_6(vZ4*)qH6eNLQOM}3s zQl%&l1{;MLY#`r(f-MAOGv!5jC?sgZz|Ic`+X)F;kcTjWHUg|H60S_9wkQhBK?EfJ z)Kv-#NJ#1u$_izJ3>-v*yaNiz7_b$wU{eXEtvIkU%s>LU6BJ1CAXD+DtprE_B!aC? z0-Fa30FXlv0RSxop;cNkSak|qwM=bMDwu-^2mA@D3>FTM1ceBPG?0ry;gAltA_HtH zRT5Mt*eJ}f0{I0LR#_mMDNj(@knqd_J3kj}CnP*U9>Nu#d0^G~aMd!kMFn6EB0TZ8 z3E<%gscI16SqSnKC_Ib6RuqFxrE>$h1Z*j0$b)<h3i(oy8|m9XE`!8UIXF-%!0v;@ z5-6B(#Zo0$broE-Ol?s$n1hHV{JFmxmg>=Se+?)EK(SN{wxSMfD#6@e4_1a5t{``U z!nFZpD*oKx2nmNKu(i!#^B~~>atN+)XaTEkg{zjSEouXE5aED7_t(I}0X_G(gIo*> zhYqk6onTX`lKZ>BMq!2($S<I<>IT_NdG7Clgl8|<`F&tJA>j$~5U%j-2dka{S1nUp zG!e`}geU&o4-ZfD+&>BAD^Pe&23s)&Y$}~||5UK0m?01HH7Mk#f!s*n+&>)>OEbWM zG861RNGySZ30Ex50;`^lq#8@JY7ST$5pVeOK`m-NQ1h*UcM#@+LIo6a^T5{52b)W^ zh58G?#$m<@$d8~nSqQS7It%p|LBe`5*c(g0_CmrM<S|58LmL)L!OE5)DZ>)T%fZr! zK*par;DHRu9BRJx@IYPx@+K&dSAwlw1vZy{-R0F_`!Hhx6bPVLSOan%-MY(bArZ9> z92D!pPJ=`gC~z<$Y6Do=MkHleB5D&@8WB<WYsYq2Zh+K|YQAmoh}sMa2~b3B0b9Ej zY%an2aT{0}X83~K4hrAxAXD+zk2@fNvJ-6WF0gr!Kmj=fBT#mOmF<Bmlc_D*3+50T z1f8fsAe1#1+CA6@aw;eQ_JgfB05+9i02~A>!wdkBJ3#?(2xKb$05}W@fFodQkAlsE z1OUh(hyXzC9vlO!J`PtcQ(JTb%po=$y3xa7B{UpPf?Ny=hf`oHPJ>M)7!GH^$}qzL z<W5jHoCTSRKOD|M!r?sF+6!RwAmIRV2(ECr2v&Uwu3DzH=rWi?Y&i6xhr<?VI9vg_ z7!(dy!B$)Yn@TVou7j0fh6Bi*pm4YWG8KO~+=PU~EwHt>!RA520pt)|;cy46`Yv3x zOl{FUFb5G1_$$hZuyBAi7-8XXALL?CI6MGb@eph(RT_+sz(!$)70553uzC!#neqnX z6G(VI1v~#4*iJ}zf;@yPJfDMAzksWjsV#a5<{-iof1L;qPe`38lm!dVS0G=3!t*uQ ziZ@_W>D*v^3$_$9<Uzg$h5S2^8|m9%d=H7G58y!g2zDPNmO#OTE0#WiRey%7mZ>fJ z0_GrM34et+1(xa|6(S;*zJfvk6ieU0R(uDWN-+2T04u``SCBhF;rbI~D*oL63la{$ z!Pfo(n+FL8kV9~V!(XuKe{j_@wMGBI97H(a&;3(j;eej|83duT%8Y`biEAc7@Wge5 zH3I{K6Zsd}g9iGU!A4<*70553uwnt(OnL5S6$H;tvw@w@4z?2#o*)n53QrEOYEHOn znc5;QFb5Hy_;WuzJkfJMH^^6@bj1U<f){KmopV1Q*iy`p2l*Nl^86q-(l_@DKw?P{ z94JCy_d#L_6im2cNf@kJ1g=`9wn!ArLBtaNR6h+p)x+9AVxSNJ#gaJK3JI{ORH^eM z!A4<*J;*Phu$KbaOnIu8hJ>dK*!i+xJ0al-@(`}@lmn}lhpU#UEm8n;5aEeG)x*OR zmg-^QsR;5FC_I(GRw#o_rE{uR0b7b0@*rP>LS7Z*M#G471_p-Eywr+<)Z~)X6orEP z;^NGtoK%I9%#xf`h5WMAqMXdURE7K^g_5GgyyDD~%=|n(u8^YC#FEUsbcM_kg~Vco z{Gyc1yu_kPg_6{Y5{0DH<iyhARE5lvM-4NJ6^io}iZk+yO7x1<AhDzl4ipWr`yjCd z3MO2!qzP871y?OoTci!<AYuuBs-KRY>R~+~9Z(2>Vo4Wlg&x>cs-${-uu+&{5Aq8r z><vIRQ=aM#A>nBRcD^y#PDpryJcKJeO~9&6;i_e7i_E|rM0ny)_3-e7rFvL+nuB}= z3Qr5L6_#LA1tU^vnZneO(if<fwE|m;8S)@sgF@aK<VO0YdK*YA*@6Sb4(vWiEP;Xv zS1j3sRXZT5#xfY<2$n{~8~%JS12rEYW?Y>>VFHRbXRxI%U{k4*4_v`UVa5i?cc9pC z1KCV@K5&PGum{-ro?ts6Aq?^mB7~s>f?i-{-bl)@1g#HP8WFVkvjjY7Az4DrcNTn{ z$rt2BP~iH3t@Q_+OTPiZ0I+?SF#rk#Pz(fuoJY3-!5~OP1%rbk1ne|OM1cYaBcejV z%EFM8VTq`4urwl~@b`aK!SVp4|D)!+5*|?zppXDXR3zBiD6qK%dqB}(Wtia$ayuw| zV?d_j?*YX^0woS?Z9LdKNT7fmf)OYQU}cGLWiquzNnj4KL9iAz2!ygk*dgl$l0i-d z1wabeid3+v1Op%qtPC>%K<)$uKsv}&`~i>w34lznwOL^EAOQe!2qFMb2L!Xhs&n9~ zWonCZ!5m`4VLf^{C_uv@59DG{IOKz^C;*#EFdPcO$}qzL<W5jH6oE{|9}dNka3}#= zTM9N05)L4T;0lK_u<CNSYMI)i3NQx|4*08u4X|*4b%kN!PziD|C>*N5R#bycrAoC> z12zgXtU!JNg;g!cX3DFDI!JidgPq?1wi6PbAP?aR&qlE7Cb(*u+M;GK2N9n5>jHRq zLh1scELeE9fP4iC&sMM%ZD3RB+&pRrTZ$R-AYX$*z60b&`ZkX`A+gj24wP=N`yjCd z3MO2!)B{%C3s)^uThs^UAYuuBs^5s7>S3i|KPUu1u`~f}#YC{FR7v%dz(!$)J;*Ph zu%8UFnetRW1rnZ9!Oouswi6PbAP?aR&*@;*GvKOaYKvxqIf(GYpX%Y^2}|{`@SFwm z6(~GsgRPhYHkHn)elFNj%#a898Wi&LKyIXOs-F*ur3K(XSqOF?B$hzIge#U7fmJU? zQjMiSv;-`Th&TNCU^8kyKy(V0g2Dt8Z_B`zE(e=Rm3*)QY!qf}fP4pvjg=sqDbEM1 zAR)XO?EE!gJ0T$q@(?0~p`C)YU}fu&lwk?l^<Zg4(BjV$@Sufc2{qrX@V4d#kQYIL zyAf>dCa}5m>lADT+lLtgpg;h{z!s46=+-IN3W=y~;GozJb{Zt2K!Jl1Q9HoOb|NXm z5>dOr(ujz{-zhi@%LA}Z!6A4=?FNMeD5Ca&t=$VYmtb3PA6OY?_=4OH3g7)8Q}MS2 z4?qItAlTYNVDlh>0&)mOpd1D(I|5fGQ(JTt%s~VJ{<L}o76g#ADwLHEZ44g+ITaKD z$H7*d0GmqZ;`=1nQq154`5F|Qr$BC`Z}EK^5<O?YfpQk?K1lR{f(a2ls9lzGVAbd0 zs%2`6E`T|RSi+xBPrzacl2C=R8lkat5flQTSh@tZ;xgD&g30s>SQ%!xg4_uT*Q+2? z@h8)3kZ`yTw)O_tJV-cz9D*wxZh}?cf~%IPExHZnAi@EErF9Ax4zMl@EFA8DTnq|_ zyI?EsflZ}KrF9={6lPd~`~nKA2Oyg%ue2UQ!t)W>`H#VNLc$Z|Azb141g!cgT(wMX z(K9dy5uW&SKRi5PxgQpu&q2Ndh35;f6)(Z2(mD6P0$Yk1@*rP>LjE<#jr7g^Zy>Ss z791$=!0v;@5-6B(#nOAQ>JM<$GPOk?!5l;^;ZOCa(NjIFjQ#`)0Z=S`23zq3Y%0|j zc76pLhZ+7L|A4~(8_0IU2zv$w2A9;d%slW6kwQ*pafw1|UP`e-d1gsQerbt9qC!$m zVqUfaXgbMSp%gLYRGOEWmy()SqF3}C60SeM-uMZ&7ZR=@kKqc}Utrb0;i_e7i~fK) zh;YT9`r+XUOZ~8L{R{FLC|v)6t@sZ%mCmW3K?t+}0W<VLz6OOpqY(JsczVv_F$sZJ z7%&Tg7D%vw-3N&!P%z<&C04L%Hn?h;+9Gx^2N6s7Q~w$C)E^D4`#3-$0E#6}uoYZj zQ>m8vxxvO^hCj$Zpz!Ab*-o9*&kG4xKCn0V!S+JJ7348o;VJ-DEeKaFQ(Ghi<{-iq zf1BbmEL>r23Rt)bgM0=GR}rukqF_@AwkgEG$}qzV<W5j{iGxhV-=>g&go7m5S}Cx3 zkZ=Gw1XnmngH_AGRm;>C$$~k=hQl@Va5w=?UveN9gTg@`Y=r{YRD$842v&v}4j^}e z!a)gSD*kX#hJ=F(*jiPvd5~}bIRsZYsDV|h!&S@F7HNPvh;YE4&#uG50oJyHg@Y!@ z#h`G|0$ZUCHkB%ED;=;=m|+F-3n;8~K{iv~w$g)yr#{&E24FiO;R*5(uJAMjt2TnG zmZ>c=26GVMiNAJ%hbOFdfrY0D$XB57GzD8>1~!$>wTn5}Qp}JC`5F}R79cm$w{2w! zi6tv=pjd<52Z<$6FyV?N8?b6yxN4c&B0De#5li?}{SEX~zXqE7?Li>`iX{iI6^>w2 zsaCr<fsMlqe~^Db;qMHxojSFP3nW}!!QOBK+Y1R-kjHR^t2<b=2VAvGZILIKg9umr zsUIG$u+$F=S1*vyK;h~Qw!#N&DxFimFW6Gd&<FV%6#9N3H_|ut`$J+W030ZRVD~{{ z2^37YVkro$IvB26rnV>q%t6Ew{?vaHJ@v!d0HL4|0L4-m*ottlsZ=TRBfv&shCRqH zps<ew*-Uwv9|Z}|Xt48Rz;;5y6XYRW;Ta279fzbE%MfEcSen=nzJ(gXh+*~wkUv2o zoCvlw32Z7=LO2<06lMs6d<P2Q6p+o7hj1z+gww#zPY2rx31N_j5Frd5X3qdC%S2L! zC1|t2(uknNU&O$J7E;8h`QCw#-e!Zm2nyUBu(i2hbLltCo(HxMGX_9`0E&Tpkn`v^ z%w7PAs6ud16oH)vi6~IuU_?|gSXl{@GAt2Q3YJDh6#kyZb66gL^fc6bpTQ%l3=|Te zh$;tLTLCtgU>my<tPC@JL2d_yZxzT?{B7)NNTAe!t*r%{2MH9ALofoR4y>#mu1u!3 zr~%9&HV9s#27yo(CkJHhO(V#upa5tBThR<Qm0$q0fR$ke0LY!70B8l7ia!9_AOX-0 zwzdOo9wY!j4nYI}>OgiUSala%wM=bMH<&|gIJ`y=2T^D^^nhFp3Wr{>6@6e+35G*I zSQ%zGfZPcRhY284@rT1iNH|OaTRRzS9wZz<4#5=;Q^2aH!d1)E7EJ?lhz*Cg=;5FU z4TtF<7lXoK2H1+3U{eW(!z{2e%y0m?6BG`!L8jslhdGdNm<zUc9@socIDj02D;(y7 zRWE?6mZ>dT2<9Nd0e=JJJuDnxolae7I4lCW7!(eR!B#8*n@W}HaVgj+%&-Fa1r%1x zKsHleJuZiY=L)d%SAy+?geS;DxWaQ4SoLbSYMI)iHDC_0;rS6gJYnf-Ey!1(@LUJB zVm;VYs)XkTuu+)d3GxdlJU4=DraU}1LBex0*!f$)c0$4v<RM()xfQH>8(g(aZP9ix z2N9n5+ZgchgtRe)vS8u41LP}Ec<uySu?uV}ox3r+!Iol%JjmCeklzDxBYnFudm*v3 z4;(1_!R~{^5-6B(#nJ(=>Vt6AGPOmAz#K#@;csAkfu(v#0|OCDhe06#ilrl9D~^Iq zC0Lps11rM}SCBhF;d&foD*n>+1SA|zf~`FTHV+aGAcx=zhtpuyXW*)3YKzW-If!t; zUz+}ag#)ZKg{9VWAQywe;XK%i3t&^JlKU@$jlv8okY7MybqQoM<+=YdBs{NxoqrW< zCnP*U9>Nu#*TAZ;!&S@F7To}I5aEeG_rt>zJ@?-P`3e-Cx4>512AfLf+<ymbDQ3un zd<_cuyC65xH}~Iz#L|6mpgaJ(4-!kDV8Rtk55cM*!BxxD7Ci=Y5V3?m_y2~adi31? z1QY_GSb7S!;u+Xfg1P@WSQ%!xg4_uT*B2mD@#p@RkZ^bfw)QpHJV-cz9D*wx-hfrV zg{zjSEqVv$Ai@EE?*9V|2lU+k9^_(BID7zG@eyn)RdW9)uu+&{1@a3htUiNmrabq5 zfrRH*u=Brx?SzCU$V0fo^E+7e54dWX+M=Ie4kA49=YDv2qUZi!AYXyP^EcRvKVVbo zocsTREyWCZkgq`@{}1Fw`sV)skXT|622Bq$3WKJvA+ZDsCS0+^1Xj%qS1nUp!~*6Z zVhMk$|BIgLVLeJ#Vd#c_Hn0`!U{k4*>N&thVTL`(FQBmJ1lde^s^=00Pq%Y}ozDZd z6B3>v58(<=Ua)FDxN4c&B7QIj5uW%{Jv=;NsU8-d0w7<3QoSJ93L&tmbWZicU`sJW z9^`9K$cup7NZ(X13W+5#aG;2T-3N&!P%z<&B?+)<Nw{j6+9D}12N6s7Q~f{mR1X_Z zk_LqUD3)ZvR>*=)rAn%o0~>`I_8`B2!d@O^Gv%pX0TP~yVCO4=?SzCU$V0foQyHvU z1+H4Awn!DsL4+s%R1XhNSgMDGry9stpzu@&TcH6qmCmVN6KpAF$b)<h3VAJ%8|j<s zwIQ*j0}d2ju=^mf1PUfxv7`r9t&gM{%h0j`SQ-&;`18Sk)O>)LUNHoP2`Ju-z?K?= zO{GdcFaaBd85<zqfnviHWHaUYzzh<?=3wVrfbE2YFvvrQ5Qa{#Sb~*VAt}QWwANs0 zM9|{T67ZmfWC=B2MrPPmeKsI3f&$kTY^@#GT>4F~*n{oEi~&#}fMUP_<UG1fuQ);? z$_X44&S0lOA_^2Z7!l<HR_2PN3`<10fu#`<g}?v9&Wv`aA{#uS+(97$iYO1TwVq&e z3HE@zz{)Vg7vy$O_<Dm(#oq(+fdq;#*jhiZd5}N>IRqn6{K3is;L2obivqzMVuOGO zH3)>V7D9)SgFsFN1wb&^iV(1=1Op%xtPC>%K<)$uKp4nW`~eUS34jQ&wUJ=+AOQe! z2qFMbr&prDs-xkmWonCJz#L-3K@dG0)<VM}7UW`3IK+XihzFZWFdP!V$}qzL<W5jH zB!W!E9}Y>7a7YGQn*ufu5)L4T;0lLSu<A6pYMI)ibTEh5a1cfhhXc@X$N;$*6b_kS zE3&|*5)6lIurkbW0J#$s4mluG@rOe$BpmX<*5-rFgM<UfA-KY!0Ia$Yu3DzHs0hp< zHXOvz!{Grm9Ew3M28BZj*osoHsRYBJ46F<@96;^_g+n>WRQ%yk0SSjnu(efS^B~~> zatN+)s0OR9fvc9OEvf}`5aEEonIH}e2iVZa8E81vfm{p<hkCFT4PaBLw#us!Y#e5I zf&2psuO^V~)LG@#3<=j3us2%4_CmrH<S|^~+6GqL4p%KxThsyOAi@=Y8v!1!kT!x) z7A#ylK|TY8YZusxZm_9zZZ`LTEyWCdkgq|Z-wSdheVfgFkXY&m2g(Gn`yjCd3MO2! zG!d+N5?r-RZP8>f2N6s7Q@;dy>W7tvQ$QgAilwPwE2e=>rAi}tI@l=8um|}C6!tSf zHdEe6o(T!hSzzbS2HOb<PmqUjh36cw>bY>$GPOnXz#K$);!pMP@Pws$Sa{9{`3e-C z3&2(^1e;3dRKEypDQ3und<_cu#UMA*H`OnJ#L`l5pezHs4-!kDV8Rtk%fYHwz*WoC z7Oezx5V3?m)k~tMdRSX%6(|Hiv9ua&#Tu}wR7v$~!A4<*J;*PhuwMtVnetS>9ul4# zz|P+Ywi6PbAP?aR&rM*}o8hWuYKyjjIf(GYpX%Y^2}|{`@Z1XW6(~HnfvwmMHkHn) zeh1i6%#a898Wi$7L2jgPs^0~PrQP5_*#mYTB$hzIge#Wzf>rN>tCp!P+7IR+VhMj| zP!^WzVUuC7SULa-0Z=R*1Y2<kY%0MP-(j#a%y0#{6BMpTK&Ikv@g0SP!!fY6$HC@7 z!U5zET;Xs6tokHewM=c%DKLlFaF9n22O&<#g1gfo7lXp#4A_dZU{eW(!#S`r%y0m? z6BG{TL8jslhYOH!xCplP64*RQIDj02D;zF^RbPRtmZ>ee3g!?S4oc|ZAO{VHYakbc z!r?mDiW^{435LT>urkbW0J#$s4!1z2;tz-0kZ`yIw)QUAJV-cz9D*wx?txX`hpU#U zEqVavAi@EEZJ-Pb2UrgP77h<VE(V3eBd`^Z!KPBBHh2Oy3Nx%gegTEmQ;^M+*9OlZ z;rSfw{1;$5A>j$~5U%ii30D0Iu3DzH=rx#w2v7XA0X#fmwE-+V-++7t3eUG-E8c-k zrE_iY9&9OQ$b)<h3i%HpH`2E@_y~!mPvAiL40azRmO#OTE0(^1Rey!6mZ>fJ2Ie4Q z34f|rK~MFtQt&${1VFL$18l`lu&Go@^}oPIVTL`(FQBmh4YHZ?RR0GOo`1p4{|B}c z5}qIr;R?_HVATvFu&HU8+9F0U2N9n5Q$0L9VW}P#o=hUp$!2B|(Cjx0*i<^FdRDNd zm?01HH7MlSKyIXOs%IAgPhoR_1BDapK1eKqf(chFae-BH!&S@F7V&^Nh*-j(>Q&KG zJ**AH3km^Hs^<e+!4Ec-Dyd!oY!qhLgZu&tdqI%Rl&5+jNO%f^oi75m6B3>v58(<= zQLt(;xN4c&B5^PW5uW%{Jv=;NsU8-d5+GlJ!c!7#g%sFSI;VPRu%(zG5AroA<Yho^ zq;IO1g~XB^I8fxl?t{b<D41}?k^)$@B3!jhZIKd~gNP;ksa_pD)x+jMltCc?iX|1W z6{=uUsgml|z(!$)J;*PhuvZ7!OnIu;fP|+e*!fyuJ0al-@(`}@)CQ~8fvc9OEz$*Z z5aEeG)x*ORmg-^QsR!~EC_MGSRv3UyrE{t`1Y3$3@*rP>Lf#1EM*60DV@NESfCI%8 z>^?{=fr1HFESZ5-n<J^lG979GmPW)I{(PW`nhy|50xUsc0*W^)u%*^uQ>l^<Y`{ig z#s<iDpxCel*-Uvpu!DrKJ=pmUU^^ip4Dt{ngrQ3U9Kp(*kd$EwT4%5{B53hv33$*# zvV@wiHhiYp1>{9g;JSjXbpxAAza;_gVEZs*02BzI81Mi&k8Vo>JRuR~1r7>tu+tzB z1qvLDi1Gm|^F>mIC8GSm(ujz{KMG_F%L9;6AT?hjctrVwLIM;~0bpwb!R8X|_XmNM zVTLcr?V#`t2APV#-yZ@Alu)p>VPNwhfdX;}Mxca)l|{gn$<!7_f;osFz+ViQz=8nQ z;g5t4d_;kq3JQQ|uoW?2Q=!E`X--aR30X&2fv%v41sjDKNFcv}0x1q;Gqe~W-=?B? zNI)ilou3G{6B3Xh4<P~)b!kBoSamX7wM=bM3Ydc$o<*r53=CQ2oD2+!849sQX&_!1 zh!@IMoL^d$oSGq-As?He5*x|_I?l@%XDFwG{0a)?46wzSV7mk(3>X*~Jo7+W6;g8x zG7^h3ixrAX5{pW7i%W_?*UG>S4NJ{SfePt?f;J1RA2Vn{-U0<}Hpn_dvWzdvfrMu+ z*r9n~iy+|%ayqW?%m=G3KvIn*(-wlIQA0RGAr?ninxdvyM8#DE@*F5Ei@}zbfK7#_ zSjw&@D+L>c8LS}Rfr7ORWHU6yl5bN{IV6NDz|OA(+X)F_kcSW<46V4Tz{;wTlwk?l z8n84XXz^EEX0V`zRa|E9@~{@<MNr_@fvv3vn=2TR#=yW3fO;iTX<iECP9z<Ll6>gZ zMha=5`;juBw<ZyNJrermH4R`}G2;Og6rgx$1Ub?$B7>%mLc6o62@+||;9zM1I}j3S zpn$@Nv{taPHY8<OBCQ=Pjfgb-m6$m!(qNSsBGNiQ;Q@-YPO!CIU~>spV%=b6n4t`E zJ1CTUK&Ila#Cjot(g(J-A8Z~ZP(TjB2$Tt6WfPH<VF{E;U};34;IGy!V1WXu))0ln zWRT-QK{5qw=~S?(R4F8;fsMipHjwW?!8RRaGv$TE3`o$<1Ur8g*iJ~$f;@x~w6np= z<{&A<60~!{(uknNUr4}%7FI}D!3&9bATNRfcRtwK1z>aO*ScK@whuD~K!E^?fkhza z(XDm67!pxSz(KJT>@-M3fdU63qLzV`Ek{y@C8Ab<r4bQ@zhH2H<pEg1U=NR|m7tIS zMbs*=wX4DA5-b?jfR$l}FUakn@LdZs6@S674iYHq!Pag7n+FLLkV7y6Wg}SGCM0E8 z0%bE;8WAY?3kEM(pr98FTR@Hn1<6*hrQ5)!Ql((n4mJui*g(Dm1=|jg&6F1mJ0U^4 z3+(*eU^^i}3-S;~(Cz^%+l!<OOVI8EOCy37f589`T3Es015a=JL0$v}?g6m12f^mj zuV6R?whuD~K!E^?fx{r@(XC)O0*R=j;Gj4Lb{Zt2K!JlCQK_MP$)!a_sd**wkX}X6 zaS;Xvzfi7})a3l4M9@u>MJK=_LW!j%`Dyw2C3*QJsqx^RLeWVP1_p1&Q1-mU+|<mJ z;-XVv`%Z)HW6M~V!Jf4h)Yaq2u#8}2U|^`t`pL?`kinUuTnY-3GoT<5OUw`qWeDX4 z-)xzdUzD3#RCE?>AursrqSUnFqH|!g&x<fHgmM(6rh%+1F1i2~ya*B$D6Y&+%Fl_1 z=_)R|B*MTDTXY#DDTv~Duz6R&vR6T}B4}FU!3wT{6<h}?;7rae0f$9#(G9TZO_0;o zGnhhoV4(-<NEO`zJ6s6vm-yV&;^M^g)Z(JsU~P9m+W0gZi|&HmeGeQ^poo#FExHfp zATk1|;4OLp>h*CjL;HXaK|FR44@bX6n=zE7q_QA23sM|w#1=gQ*$B!NkHI!R0b2sK z@hO;tnPfqZ1I5oXkY2+G8}QwcDWG$uQ&SX*OOuLAGD}K9DMO(sH7&I$H7_|e#Y#ab zCow5Cr#dIkDlfkzu`Dq&Cow4}wN^>5=s6@Yz5u)6CD>As3xu*jZbBqRcrQ5-6u|}g zMJ1_4MX$gi%8{7@O>wV5DNZPq7dbwQi{5}k_bn)@cwtcmiNtqcOW%WJ1TyndGK*4^ zOX5osi_%j|ii<vgwS5FhaulbQfG$%lF8Ty=U~)=+a%o9sPO)BEQGQ-YYF-LgSYl3T zYB5*QXAuU5{Gu;lbH9Srh6=%wTzpbua&}H;UUqTOH;_9SLxqb#*(fDGCAA<Gbij6U zW@>TKcd(y$a}x8?OB2&m<CF7KQj30oT)~u@SM(Fa;4CRhOil$ESM*DSfuSRmuOPJm z<ReIM7Z?2oo52U_su#p3=jZ08=9Lr|{Q-;emgFZRIpr_NK-Sc}lA_9@e;_tbQ5s0T zI5obsD5vN@NJu85q@<wON?*SuKR>5fFEh0yO)tMFT|c8FH%GsSL6m_Zlrtr<B(=CC zF}I+IQ4~}}@D!zjA}Ky6wJbHKh)I-z!J8>mxHvblsHCtoza+IdJ|{mpF(<XSh*=br z5m`W{@WiL27MEn^fpb$4E7%~ejKrK0s4;9HV^~9Zp&rXgEG|whE@B6%%h2-+l}Rls z$}fsf%}dTt$;?ZShj23z^HOqBi;6fvHVA-1tvDyKIHM@FASW?7wTKfW%$ky#RGMDI z1u`jAAT>8B6_lhZb5e^lQd3KcxJ4NlIzwgiOG^q$OK_Rb12TvW<h10HB3=-Ow>UMq zB(F3#z5-Nq74d;w<*|Qkq*34=)9Zi}=B|@}}e`XXd5lLlp}^6!VoQ7UhBbQe0A$ znwVQ82v#c!itn_{9B>@Pm!#$v<Rq4)772kY<tRuk&{Z`sNhuNraRpN=GD|?&qolML z8j2zyqgg}QlJoP@GSiDh!A61;OL9qkS!Qu&Nq$k07+6#^IVV3cJ3cixF*7GVF(sua z6&&K?qM%eKTT+yn3olU-=`X&x02Hti;6P(e%_}RC1RDnNctLS$X-a;4MQ%=!6j)dw zwW1)uI5j>quOzi7FEOXMNE$3I1PZ<4(j@Rb$Iwub0h`GUsf^-5nW;z?te6j!YT*S= zagiKYlpig|isV5-!dhCArfX580Ah1NjRK{0MX(;e%sk{sE>Z$1;{<EbEzV3YQU>w) z<5Mz=K_yr`G!Rw5dO0&w;tPsW(=scHR6)uZLS>UP5{nX(OHzv<fghg<9#o6ZO)SbT zEhth0`-ih6F)6-0Go>V>NF5Y69HD%Wqzg;QMH(Q}SVKeHbS;WBL2Pzdg{&pYz>pys z%AcNE0=n86l-mmulS_)U!BNDSo|>0hln9DY9k2`ez=;nL)Vg3%9&o;lhh)qmJ+M|D zP#Q~0gq8#PAWIcs<v@9Pxn4nKNk)DixEx4HEz>VZEhyG6G5{$PD6Y&aNvw#^$V|`3 z$xP2EDKZ2Jv*hIGr5722m@=qgjFwT2MHv{fz!``SRFKCb0@VbhnJF`+$P~ojOUX}0 zP8??7z?25%z=HVHoK$eB7Y`b!j8BFZ73N^?@<L-R9+ZWOi!49|P^cJ)6Q7w^oLU5` zz2Z~zK=GSWWC;!p?xMtUxR4bnk{CmI!C?un8mvKPmnMaZqPG_ytsxtbCWZ{f+9F#~ z1_q5R8)gQEtSvkY43JikNLCI=AOl2f2NAKn3=A3TGFD|-gLvj3B7u>CAuEQFfg!^( z!!+wACj&#)RS=N~692`;z>swd#FYZEwt+NkVrF2-P|gs`It}6-2N9q)Ru-tG4IVts z0*%XNfd-DVia=UHjfpH!4WE?@QhXicyfYwH7B2%s7N~KN#l+0OP#P+PT+_!xnp<|F zpd~f-padzEp$-}ib^!S_LoPN$F&4{kYH27ZtZpnWas)*}krOCh*+4lcrMSo$Y@UlK J14C(&9sng!_*nn| literal 2817 zcmZo*N>0g7E-lH-Db~x&Pf0E20&#Ow^Gdi188sUVnQ9A}H9|S_5_3~aDhpDJ3t4Il zSv4Z$7#JARQ}a@b5_1#^iZb((GYfK374p**@(WUn5=%1k^9tGgBE%RN7?ShzN{aGx za#D*F5>v8Di%URe7Z<Yom4*rymnIdLWR{eI)W@f!rWF@*)E07v@)aZ&6{p7MrWO|` zrl%Gca>W*Mhw>$t78RxDmBbh4mlh?b7V`Loa;2mu=R<Ad^$QhBEG@}T%g-;#%P&cd zFD^+eDk<diW(;KqIX*L`xRAfLP(UMtEmRKba$UH~b@S775iS?ZU=I~TxLX(5-9n|I z9LX7(IVnY{d4<BUg(B#|SDcy*@(x#_sAglKSZ$%WMkr@dVmZ{+5}^#CYz2uRj}%H~ zFom)~#ib$~85kJ!GxBp&^%HXwQ&LNd_0uy;^mFrz3NkWt^5awTll6U(IS`Hd2xsaQ z6_*rBhq9L>rh`0OC=<#KbxWaaC|6=hNl|7}X-R5vp<HdDyhbQTN@)Q|U2&m8Y$$tj zPGWI!YH^`rY$!)kVsds7C^D2{LzzM0rW{+Sk|C5B$_i1h8e6EA!Jb$e%94|rms+Uq z%@oQ3OEiTV8B7_%v4xr%=;2b5S(1~=Rj8%eSg2iFsH2e~0Ztyyh~(jjlst4ZBs0V^ zq%x#4WI|cNS_}0u<Z27`H8K=pGZbSplwvcKV>47^OEc8HnKGcZ8lYPml3G#1RcMIM zCZpEILgU&(6O9as4BZSVzYKLhuyK+Z+NDW}rAZl}cr>joG}FkC2xUMxD?=9K9&;4; z6k22mCT6I{7FuSoC4yYW3N}hOw$LgA<Z<iTLK~3BLAl2rntK9}bB{kf_t<7gW|%?( zAOq}kI~1FsK8KrcpJ52jlLSn4Xl*QXtSxi`dDa%iv({kGCYC0pmL?^Fd>YDKQk0li zoR(jdn_5)p>=()l&syNb;Zj@Z8p=_Wng&S}ZncH(p#sH~xk>ps@i3Leg&whmo}q#$ z856AAE4I)(R0K_VJXp#nw$L|}GdZ&aT#OVK`o$LdgMu-X2UY@rlU;ycs1V$Rh_WIu zwlE0ftb+WalGLKYV82j~%oJ#05aP`k%8Trl;=<6_!mv<Ym}L+Lgx3~EgbHNlrDPVR zCYQvQBo?KomJ}C8#ui3}aulbQlw{_m7Z*k&rSP<({JfIXycDjm#GKO9Vy?oN{KDAU z!Z?jkAy`nvgK||)W?pu2VZ1kEsBjUe=t_xCNi9gtOG(X3&P**XOz;ck%}LBlFHKBO zjZe-`Ni9qaWlGH}ObX>JDN0OE1sPG8+!4xGkXit8YHCqxUUF)2VTxZUUvWuMW<h*% zelDbVP4x@qEy+(tvNbJ~H8roKsIo9Ul&2^SBvYIkUs{w?m=P+IQBqP+Y^ASXlAoVb zte2TulBSnml&+sqlAEJnm>J5Ml30>jT#}euP?+Tx%2SjI3f%ad)Uwo^!fbD*P~qZS zP+41=Uy@oJpOc@Qn3Gyum=jx=8_E-(l3HAnnFo%_!aToFu8hQ-5~$XEZ`M#=sJo%X zPk~>Co?oa;YEe;sQG9A%a(+r?UV1!)n~|88l9O6gSQsh*3W(yI#Nv#i)PkJE<kZ5V zP}Y>xq|)@lV!u#<)ZC<0P?T5Zq!wqSrj`_zbcV|2mzETimf$k8G?WeGkmQoWvQS=7 zshL-r8(#rR`-SD+jG_D~rMU(1@YGgZSm77So06ZLnU|IiRaWWE7|K_kSd<5HaB)dd zYGQ6-m0zeRD5}yjbHG6zUy_<zkds)FT38**QIJ}ot7>49Qdkozm|Brp0!pJLrNz*& zsr6<JWlPS_OUq0ztb;~xa!GtyW^raoeo<k)U#MtuPJUu`d}?lDW=?!!N=i{GxBzeH z2$d}<%FKo5K}14{FD?LuRbyu;b822$VUr)!Uj@afr78LG6}dTu&7k0`D9A5PjnB+0 zNiE7t%qcEx@e36Kg-LN~61XIW`na_-lp9hB#e>pyVVhqlA1GlJrKZ6WX1iY~KU%;S zc7(E)mZa%g6n2JkLA8TYVV7ShUuGV16cu)da)MRr7H6gx_Js1sr(_l<Cgp~^=L z{X#i2Q{oGXQqwXk3j0DCLS>UP5{nX(OHzv<!5E*J2P!M#a}$fQOA8A7J3~235|iS~ zGgC@33MY7Tgz`a>7A&O|P7GxY4RO=8D4Z0^4r^#k&X5k}Pfsl=Nv$XWWw3(8<dVWE z9ig0%Rs<+Iruv2Qfs+U#(5Cr?@_@5Nd?7er6i)95<pCvzq(o@Gn-Qu2%Xj7F<$48` zB^mj7;Cz>oTBcu+T2QQCI1^N)=9MH?#AjrtXXIq2XOtAq3T4U3&r2_y9V&wwU}*Vd zPDWWMAE>m8M+DN`P^Qe3!g-;5Df!9BaXG&;R2q~43gT09Qo$uie0gR`Mm(%pu)r^r zHy)B4<3XvpxNu=?s2GS9pP5&jS_EqG#HZ$gVkf0=QAa3uQDQlqzZg{Pf`bQMcrNiP zO$rr7Fa9A-wx!+-8OpVV%QP~CGQ=_jGfYcEg-{xbkP2scZQ+UxnG6k3ExZz3H!6c# o1+W%XhIED^xP1`H2`hq&3s=P!t`21brI(cA!Zo#pYfF>#005^CPyhe` diff --git a/Morphilo_doc/_build/doctrees/source/datamodel.doctree b/Morphilo_doc/_build/doctrees/source/datamodel.doctree index ff65d2a7cdf4e021a3501a55726cfac05164f696..d9306dc94fb646762de7f705c1140572b16d39c5 100644 GIT binary patch literal 83270 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 delta 2368 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 SY@i5BDK1=7Te!9~Ne=-1mR$J& diff --git a/Morphilo_doc/_build/doctrees/source/framework.doctree b/Morphilo_doc/_build/doctrees/source/framework.doctree new file mode 100644 index 0000000000000000000000000000000000000000..398e1c277effc4fa832fe35372ae81e56970296b GIT binary patch literal 9257 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 WfTxQxQ;Lh&!RB!=GBA`T=>Y)Y6FI~H literal 0 HcmV?d00001 diff --git a/Morphilo_doc/_build/doctrees/source/view.doctree b/Morphilo_doc/_build/doctrees/source/view.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a2fb1ec70077bbaf14a994eace6594fb7c7a11cc GIT binary patch literal 85499 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 literal 0 HcmV?d00001 diff --git a/Morphilo_doc/_build/html/_sources/index.rst.txt b/Morphilo_doc/_build/html/_sources/index.rst.txt index 3c70750..c704306 100644 --- a/Morphilo_doc/_build/html/_sources/index.rst.txt +++ b/Morphilo_doc/_build/html/_sources/index.rst.txt @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to Morphilo's documentation! +Documentation Morphilo Project ==================================== .. toctree:: @@ -12,8 +12,9 @@ Welcome to Morphilo's documentation! source/datamodel.rst source/controller.rst - - + source/view.rst + source/architecture.rst + source/framework.rst Indices and tables ================== diff --git a/Morphilo_doc/_build/html/_sources/source/architecture.rst.txt b/Morphilo_doc/_build/html/_sources/source/architecture.rst.txt new file mode 100644 index 0000000..5b114bd --- /dev/null +++ b/Morphilo_doc/_build/html/_sources/source/architecture.rst.txt @@ -0,0 +1,66 @@ +Software Design +=============== + + +.. image:: architecture.* + + +The architecture of a possible **take-and-share**-approach for language +resources is visualized in figure \ref{fig:architect}. Because the very gist +of the approach becomes clearer if describing a concrete example, the case of +annotating lexical derivatives of Middle English and a respective database is +given as an illustration. +However, any other tool that helps with manual annotations and manages metadata of a corpus could be +substituted here instead. + +After inputting an untagged corpus or plain text, it is determined whether the +input material was annotated previously by a different user. This information is +usually provided by the metadata administered by the annotation tool; in the case at +hand it is called \emph{Morphilizer} in figure \ref{fig:architect}. An +alternative is a simple table look-up for all occurring words in the datasets Corpus 1 through Corpus n. If contained +completely, the \emph{yes}-branch is followed up further -- otherwise \emph{no} +succeeds. The difference between the two branches is subtle, yet crucial. On +both branches, the annotation tool (here \emph{Morphilizer}) is called, which, first, +sorts out all words that are not contained in the master database (here \emph{Morphilo-DB}) +and, second, makes reasonable suggestions on an optimal annotation of +the items. In both cases the +annotations are linked to the respective items (e.g. words) in the +text, but they are also persistently saved in an extra dataset, i.e. Corpus 1 +through n, together with all available metadata. + +The difference between both information streams is that +in the \emph{yes}-branch a comparison between the newly created dataset and +all of the previous datasets of this text is carried out. Within this +unit, all deviations and congruencies are marked and counted. The underlying +assumption is that with a growing number of comparable texts the +correct annotations approach a theoretic true value of a correct annotation +while errors level out provided that the sample size is large enough. How the +distribution of errors and correct annotations exactly looks like and if a +normal distribution can be assumed is still object of the ongoing research, but +independent of the concrete results, the component (called \emph{compare +manual annotations} in figure \ref{fig:architect}) allows for specifying the +exact form of the sample population. +In fact, it is necessary at that point to define the form of the distribution, +sample size, and the rejection region. The standard setting are a normal +distribution, a rejection region of $\alpha = 0.05$ and sample size of $30$ so +that a simple Gau\ss-Test can be calculated. + +Continuing the information flow further, these statistical calculations are +delivered to the quality-control-component. Based on the statistics, the +respective items together with the metadata, frequencies, and, of course, +annotations are written to the master database. All information in the master +database is directly used for automated annotations. Thus it is directly matched +to the input texts or corpora respectively through the \emph{Morphilizer}-tool. +The annotation tool decides on the entries looked up in the master which items +are to be manually annotated. + +The processes just described are all hidden from the user who has no possibility +to impact the set quality standards but by errors in the annotation process. The +user will only see the number of items of the input text he or she will process manually. The +annotator will also see an estimation of the workload beforehand. On this +number, a decision can be made if to start the annotation at all. It will be +possible to interrupt the annotation work and save progress on the server. And +the user will have access to the annotations made in the respective dataset, +correct them or save them and resume later. It is important to note that the user will receive +the tagged document only after all items are fully annotated. No partially +tagged text can be output. \ No newline at end of file diff --git a/Morphilo_doc/_build/html/_sources/source/controller.rst.txt b/Morphilo_doc/_build/html/_sources/source/controller.rst.txt index 9d4b511..6f6b896 100644 --- a/Morphilo_doc/_build/html/_sources/source/controller.rst.txt +++ b/Morphilo_doc/_build/html/_sources/source/controller.rst.txt @@ -2,4 +2,848 @@ Controller Adjustments ====================== General Principle of Operation ------------------------------- \ No newline at end of file +------------------------------ + +Figure \ref{fig:classDiag} illustrates the dependencies of the five java classes that were integrated to add the morphilo +functionality defined in the default package \emph{custom.mycore.addons.morphilo}. The general principle of operation +is the following. The handling of data search, upload, saving, and user +authentification is fully left to the MyCoRe functionality that is completely +implemented. The class \emph{ProcessCorpusServlet.java} receives a request from the webinterface to process an uploaded file, +i.e. a simple text corpus, and it checks if any of the words are available in the master database. All words that are not +listed in the master database are written to an extra file. These are the words that have to be manually annotated. At the end, the +servlet sends a response back to the user interface. In case of all words are contained in the master, an xml file is generated from the +master database that includes all annotated words of the original corpus. Usually this will not be the case for larger textfiles. +So if some words are not in the master, the user will get the response to initiate the manual annotation process. + +The manual annotation process is processed by the class +\emph{{Tag\-Corpus\-Serv\-let\-.ja\-va}}, which will build a JDOM object for the first word in the extra file. +This is done by creating an object of the \emph{JDOMorphilo.java} class. This class, in turn, will use the methods of +\emph{AffixStripper.java} that make simple, but reasonable, suggestions on the word structure. This JDOM object is then +given as a response back to the user. It is presented as a form, in which the user can make changes. This is necessary +because the word structure algorithm of \emph{AffixStripper.java} errs in some cases. Once the user agrees on the +suggestions or on his or her corrections, the JDOM object is saved as an xml that is only searchable, visible, and +changeable by the authenicated user (and the administrator), another file containing all processed words is created or +updated respectively and the \emph{TagCorpusServlet.java} servlet will restart until the last word in the extra list is +processed. This enables the user to stop and resume her or his annotation work at a later point in time. The +\emph{TagCorpusServlet} will call methods from \emph{ProcessCorpusServlet.java} to adjust the content of the extra +files harboring the untagged words. If this file is empty, and only then, it is replaced by the file comprising all words +from the original text file, both the ones from the master database and the ones that are annotated by the user, +in an annotated xml representation. + +Each time \emph{ProcessCorpusServlet.java} is instantiated, it also instantiates \emph{QualityControl.java}. This class checks if a +new word can be transferred to the master database. The algorithm can be freely adopted to higher or lower quality standards. +In its present configuration, a method tests at a limit of 20 different +registered users agreeing on the annotation of the same word. More specifically, +if 20 JDOM objects are identical except in the attribute field \emph{occurrences} in the metadata node, the JDOM object becomes +part of the master. The latter is easily done by changing the attribute \emph{creator} from the user name +to \emph{``administrator''} in the service node. This makes the dataset part of the master database. Moreover, the \emph{occurrences} +attribute is updated by adding up all occurrences of the word that stem from +different text corpora of the same time range. +\begin{landscape} + \begin{figure} + \centering + \includegraphics[scale=0.55]{morphilo_uml.png} + \caption{Class Diagram Morphilo} + \label{fig:classDiag} + \end{figure} +\end{landscape} + + + +Conceptualization +----------------- + +The controller component is largely +specified and ready to use in some hundred or so java classes handling the +logic of the search such as indexing, but also dealing with directories and +files as saving, creating, deleting, and updating files. +Moreover, a rudimentary user management comprising different roles and +rights is offered. The basic technology behind the controller's logic is the +servlet. As such all new code has to be registered as a servlet in the +web-fragment.xml (here the Apache Tomcat container) as listing \ref{lst:webfragment} shows. + +\begin{lstlisting}[language=XML,caption={Servlet Registering in the +web-fragment.xml (excerpt)},label=lst:webfragment,escapechar=|] +<servlet> + <servlet-name>ProcessCorpusServlet</servlet-name> + <servlet-class>custom.mycore.addons.morphilo.ProcessCorpusServlet</servlet-class> +</servlet> +<servlet-mapping> + <servlet-name>ProcessCorpusServlet</servlet-name> + <url-pattern>/servlets/object/process</url-pattern>|\label{ln:process}| +</servlet-mapping> +<servlet> + <servlet-name>TagCorpusServlet</servlet-name> + <servlet-class>custom.mycore.addons.morphilo.TagCorpusServlet</servlet-class> +</servlet> +<servlet-mapping> + <servlet-name>TagCorpusServlet</servlet-name> + <url-pattern>/servlets/object/tag</url-pattern>|\label{ln:tag}| +</servlet-mapping> +\end{lstlisting} + +Now, the logic has to be extended by the specifications analyzed in chapter +\ref{chap:concept} on conceptualization. More specifically, some +classes have to be added that take care of analyzing words +(\emph{AffixStripper.java, InflectionEnum.java, SuffixEnum.java, +PrefixEnum.java}), extracting the relevant words from the text and checking the +uniqueness of the text (\emph{ProcessCorpusServlet.java}), make reasonable +suggestions on the annotation (\emph{TagCorpusServlet.java}), build the object +of each annotated word (\emph{JDOMorphilo.java}), and check on the quality by applying +statistical models (\emph{QualityControl.java}). + +Implementation +-------------- + +Having taken a bird's eye perspective in the previous chapter, it is now time to take a look at the specific implementation at the level +of methods. Starting with the main servlet, \emph{ProcessCorpusServlet.java}, the class defines four getter method: +\renewcommand{\labelenumi}{(\theenumi)} +\begin{enumerate} + \item\label{itm:geturl} public String getURLParameter(MCRServletJob, String) + \item\label{itm:getcorp} public String getCorpusMetadata(MCRServletJob, String) + \item\label{itm:getcont} public ArrayList<String> getContentFromFile(MCRServletJob, String) + \item\label{itm:getderiv} public Path getDerivateFilePath(MCRServletJob, String) + \item\label{itm:now} public int getNumberOfWords(MCRServletJob job, String) +\end{enumerate} +Since each servlet in MyCoRe extends the class MCRServlet, it has access to MCRServletJob, from which the http requests and responses +can be used. This is the first argument in the above methods. The second argument of method (\ref{itm:geturl}) specifies the name of an url parameter, i.e. +the object id or the id of the derivate. The method returns the value of the given parameter. Typically MyCoRe uses the url to exchange +these ids. The second method provides us with the value of a data field in the xml document. So the string defines the name of an attribute. +\emph{getContentFromFile(MCRServletJob, String)} returns the words as a list from a file when given the filename as a string. +The getter listed in \ref{itm:getderiv}), returns the Path from the MyCoRe repository when the name of +the file is specified. And finally, method (\ref{itm:now}) returns the number of words by simply returning +\emph{getContentFromFile(job, fileName).size()}. + +There are two methods in every MyCoRe-Servlet that have to be overwritten, +\emph{protected void render(MCRServletJob, Exception)}, which redirects the requests as \emph{POST} or \emph{GET} responds, and +\emph{protected void think(MCRServletJob)}, in which the logic is implemented. Since the latter is important to understand the +core idea of the Morphilo algorithm, it is displayed in full length in source code \ref{src:think}. + +\begin{lstlisting}[language=java,caption={The overwritten think method},label=src:think,escapechar=|] +protected void think(MCRServletJob job) throws Exception +{ + this.job = job; + String dateFromCorp = getCorpusMetadata(job, "def.datefrom"); + String dateUntilCorp = getCorpusMetadata(job, "def.dateuntil"); + String corpID = getURLParameter(job, "objID"); + String derivID = getURLParameter(job, "id"); + + //if NoW is 0, fill with anzWords + MCRObject helpObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(corpID));|\label{ln:bugfixstart}| + Document jdomDocHelp = helpObj.createXML(); + XPathFactory xpfacty = XPathFactory.instance(); + XPathExpression<Element> xpExp = xpfacty.compile("//NoW", Filters.element()); + Element elem = xpExp.evaluateFirst(jdomDocHelp); + //fixes transferred morphilo data from previous stand alone project + int corpussize = getNumberOfWords(job, ""); + if (Integer.parseInt(elem.getText()) != corpussize) + { + elem.setText(Integer.toString(corpussize)); + helpObj = new MCRObject(jdomDocHelp); + MCRMetadataManager.update(helpObj); + }|\label{ln:bugfixend}| + + //Check if the uploaded corpus was processed before + SolrClient slr = MCRSolrClientFactory.getSolrClient();|\label{ln:solrstart}| + SolrQuery qry = new SolrQuery(); + qry.setFields("korpusname", "datefrom", "dateuntil", "NoW", "id"); + qry.setQuery("datefrom:" + dateFromCorp + " AND dateuntil:" + dateUntilCorp + " AND NoW:" + corpussize); + SolrDocumentList rslt = slr.query(qry).getResults();|\label{ln:solrresult}| + + Boolean incrOcc = true; + // if resultset contains only one, then it must be the newly created corpus + if (slr.query(qry).getResults().getNumFound() > 1) + { + incrOcc = false; + }|\label{ln:solrend}| + + //match all words in corpus with morphilo (creator=administrator) and save all words that are not in morphilo DB in leftovers + ArrayList<String> leftovers = new ArrayList<String>(); + ArrayList<String> processed = new ArrayList<String>(); + + leftovers = getUnknownWords(getContentFromFile(job, ""), dateFromCorp, dateUntilCorp, "", incrOcc, incrOcc, false);|\label{ln:callkeymeth}| + + //write all words of leftover in file as derivative to respective corpmeta dataset + MCRPath root = MCRPath.getPath(derivID, "/");|\label{ln:filesavestart}| + Path fn = getDerivateFilePath(job, "").getFileName(); + Path p = root.resolve("untagged-" + fn); + Files.write(p, leftovers);|\label{ln:filesaveend}| + + //create a file for all words that were processed + Path procWds = root.resolve("processed-" + fn); + Files.write(procWds, processed); +} +\end{lstlisting} +Using the above mentioned getter methods, the \emph{think} method assigns values to the object ID, needed to get the xml document +that contain the corpus metadata, the file ID, and the beginning and starting dates from the corpus to be analyzed. Lines \ref{ln:bugfixstart} +through \ref{ln:bugfixend} show how to access a mycore object as an xml document, a procedure that will be used in different variants +throughout this implementation. +By means of the object ID, the respective corpus is identified and a JDOM document is constructed, which can then be accessed +by XPath. The XPath factory instances are collections of the xml nodes. In the present case, it is save to assume that only one element +of \emph{NoW} is available (see corpus datamodel listing \ref{lst:corpusdatamodel} with $maxOccurs='1'$). So we do not have to loop through +the collection, but use the first node named \emph{NoW}. The if-test checks if the number of words of the uploaded file is the +same as the number written in the document. When the document is initially created by the MyCoRe logic it was configured to be zero. +If unequal, the setText(String) method is used to write the number of words of the corpus to the document. + +Lines \ref{ln:solrstart}--\ref{ln:solrend} reveal the second important ingredient, i.e. controlling the search engine. First, a solr +client and a query are initialized. Then, the output of the result set is defined by giving the fields of interest of the document. +In the case at hand, it is the id, the name of the corpus, the number of words, and the beginnig and ending dates. With \emph{setQuery} +it is possible to assign values to some or all of these fields. Finally, \emph{getResults()} carries out the search and writes +all hits to a \emph{SolrDocumentList} (line \ref{ln:solrresult}). The test that follows is really only to set a Boolean +encoding if the number of occurrences of that word in the master should be updated. To avoid multiple counts, +incrementing the word frequency is only done if it is a new corpus. + +In line \ref{ln:callkeymeth} \emph{getUnknownWords(ArrayList, String, String, String, Boolean, Boolean, Boolean)} is called and +returned as a list of words. This method is key and will be discussed in depth below. Finally, lines +\ref{ln:filesavestart}--\ref{ln:filesaveend} show how to handle file objects in MyCoRe. Using the file ID, the root path and the name +of the first file in that path are identified. Then, a second file starting with ``untagged'' is created and all words returned from +the \emph{getUnknownWords} is written to that file. By the same token an empty file is created (in the last two lines of the \emph{think}-method), +in which all words that are manually annotated will be saved. + +In a refactoring phase, the method \emph{getUnknownWords(ArrayList, String, String, String, Boolean, Boolean, Boolean)} could be subdivided into +three methods: for each Boolean parameter one. In fact, this method handles more than one task. This is mainly due to multiple code avoidance. +%this is just wrong because no resultset will substantially be more than 10-20 +%In addition, for large text files this method would run into efficiency problems if the master database also reaches the intended size of about +%$100,000$ entries and beyond because +In essence, an outer loop runs through all words of the corpus and an inner loop runs through all hits in the solr result set. Because the result +set is supposed to be small, approximately between $10-20$ items, efficiency +problems are unlikely to cause a problem, although there are some more loops running through collection of about the same sizes. +%As the hits naturally grow larger with an increasing size of the data base, processing time will rise exponentially. +Since each word is identified on the basis of its projected word type, the word form, and the time range it falls into, it is these variables that +have to be checked for existence in the documents. If not in the xml documents, +\emph{null} is returned and needs to be corrected. Moreover, user authentification must be considered. There are three different XPaths that are relevant. +\begin{itemize} + \item[-] \emph{//service/servflags/servflag[@type='createdby']} to test for the correct user + \item[-] \emph{//morphiloContainer/morphilo} to create the annotated document + \item[-] \emph{//morphiloContainer/morphilo/w} to set occurrences or add a link +\end{itemize} + +As an illustration of the core functioning of this method, listing \ref{src:getUnknowWords} is given. +\begin{lstlisting}[language=java,caption={Mode of Operation of getUnknownWords Method},label=src:getUnknowWords,escapechar=|] +public ArrayList<String> getUnknownWords( + ArrayList<String> corpus, + String timeCorpusBegin, + String timeCorpusEnd, + String wdtpe, + Boolean setOcc, + Boolean setXlink, + Boolean writeAllData) throws Exception + { + String currentUser = MCRSessionMgr.getCurrentSession().getUserInformation().getUserID(); + ArrayList lo = new ArrayList(); + + for (int i = 0; i < corpus.size(); i++) + { + SolrClient solrClient = MCRSolrClientFactory.getSolrClient(); + SolrQuery query = new SolrQuery(); + query.setFields("w","occurrence","begin","end", "id", "wordtype"); + query.setQuery(corpus.get(i)); + query.setRows(50); //more than 50 items are extremely unlikely + SolrDocumentList results = solrClient.query(query).getResults(); + Boolean available = false; + for (int entryNum = 0; entryNum < results.size(); entryNum++) + { + ... + // update in MCRMetaDataManager + String mcrIDString = results.get(entryNum).getFieldValue("id").toString(); + //MCRObjekt auslesen und JDOM-Document erzeugen: + MCRObject mcrObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(mcrIDString)); + Document jdomDoc = mcrObj.createXML(); + ... + //check and correction for word type + ... + //checkand correction time: timeCorrect + ... + //check if user correct: isAuthorized + ... + XPathExpression<Element> xp = xpfac.compile("//morphiloContainer/morphilo/w", Filters.element()); + //Iterates w-elements and increments occurrence attribute if setOcc is true + for (Element e : xp.evaluate(jdomDoc)) + { + //wenn Rechte da sind und Worttyp nirgends gegeben oder gleich ist + if (isAuthorized && timeCorrect + && ((e.getAttributeValue("wordtype") == null && wdtpe.equals("")) + || e.getAttributeValue("wordtype").equals(wordtype))) // nur zur Vereinheitlichung + { + int oc = -1; + available = true;|\label{ln:available}| + try + { + //adjust occurrence Attribut + if (setOcc) + { + oc = Integer.parseInt(e.getAttributeValue("occurrence")); + e.setAttribute("occurrence", Integer.toString(oc + 1)); + } + + //write morphilo-ObjectID in xml of corpmeta + if (setXlink) + { + Namespace xlinkNamespace = Namespace.getNamespace("xlink", "http://www.w3.org/1999/xlink");|\label{ln:namespace}| + MCRObject corpObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(getURLParameter(job, "objID"))); + Document corpDoc = corpObj.createXML(); + XPathExpression<Element> xpathEx = xpfac.compile("//corpuslink", Filters.element()); + Element elm = xpathEx.evaluateFirst(corpDoc); + elm.setAttribute("href" , mcrIDString, xlinkNamespace); + } + mcrObj = new MCRObject(jdomDoc);|\label{ln:updatestart}| + MCRMetadataManager.update(mcrObj); + QualityControl qc = new QualityControl(mcrObj);|\label{ln:updateend}| + } + catch(NumberFormatException except) + { + // ignore + } + } + } + if (!available) // if not available in datasets under the given conditions |\label{ln:notavailable}| + { + lo.add(corpus.get(i)); + } + } + return lo; + } +\end{lstlisting} +As can be seen from the functionality of listing \ref{src:getUnknowWords}, getting the unknown words of a corpus, is rather a side effect for the equally named method. +More precisely, a Boolean (line \ref{ln:available}) is set when the document is manipulated otherwise because it is clear that the word must exist then. +If the Boolean remains false (line \ref{ln:notavailable}), the word is put on the list of words that have to be annotated manually. As already explained above, the +first loop runs through all words (corpus) and the following lines a solr result set is created. This set is also looped through and it is checked if the time range, +the word type and the user are authorized. In the remainder, the occurrence attribute of the morphilo document can be incremented (setOcc is true) or/and the word is linked to the +corpus meta data (setXlink is true). While all code lines are equivalent with +what was explained in listing \ref{src:think}, it suffices to focus on an +additional name space, i.e. +``xlink'' has to be defined (line \ref{ln:namespace}). Once the linking of word +and corpus is set, the entire MyCoRe object has to be updated. This is done by the functionality of the framework (lines \ref{ln:updatestart}--\ref{ln:updateend}). +At the end, an instance of \emph{QualityControl} is created. + +%QualityControl +The class \emph{QualityControl} is instantiated with a constructor +depicted in listing \ref{src:constructQC}. +\begin{lstlisting}[language=java,caption={Constructor of QualityControl.java},label=src:constructQC,escapechar=|] +private MCRObject mycoreObject; +/* Constructor calls method to carry out quality control, i.e. if at least 20 + * different users agree 100% on the segments of the word under investigation + */ +public QualityControl(MCRObject mycoreObject) throws Exception +{ + this.mycoreObject = mycoreObject; + if (getEqualObjectNumber() > 20) + { + addToMorphiloDB(); + } +} +\end{lstlisting} +The constructor takes an MyCoRe object, a potential word candidate for the +master data base, which is assigned to a private class variable because the +object is used though not changed by some other java methods. +More importantly, there are two more methods: \emph{getEqualNumber()} and +\emph{addToMorphiloDB()}. While the former initiates a process of counting and +comparing objects, the latter is concerned with calculating the correct number +of occurrences from different, but not the same texts, and generating a MyCoRe object with the same content but with two different flags in the \emph{//service/servflags/servflag}-node, i.e. \emph{createdby='administrator'} and \emph{state='published'}. +And of course, the \emph{occurrence} attribute is set to the newly calculated value. The logic corresponds exactly to what was explained in +listing \ref{src:think} and will not be repeated here. The only difference are the paths compiled by the XPathFactory. They are +\begin{itemize} + \item[-] \emph{//service/servflags/servflag[@type='createdby']} and + \item[-] \emph{//service/servstates/servstate[@classid='state']}. +\end{itemize} +It is more instructive to document how the number of occurrences is calculated. There are two steps involved. First, a list with all mycore objects that are +equal to the object which the class is instantiated with (``mycoreObject'' in listing \ref{src:constructQC}) is created. This list is looped and all occurrence +attributes are summed up. Second, all occurrences from equal texts are substracted. Equal texts are identified on the basis of its meta data and its derivate. +There are some obvious shortcomings of this approach, which will be discussed in chapter \ref{chap:results}, section \ref{sec:improv}. Here, suffice it to +understand the mode of operation. Listing \ref{src:equalOcc} shows a possible solution. +\begin{lstlisting}[language=java,caption={Occurrence Extraction from Equal Texts (1)},label=src:equalOcc,escapechar=|] +/* returns number of Occurrences if Objects are equal, zero otherwise + */ +private int getOccurrencesFromEqualTexts(MCRObject mcrobj1, MCRObject mcrobj2) throws SAXException, IOException +{ + int occurrences = 1; + //extract corpmeta ObjectIDs from morphilo-Objects + String crpID1 = getAttributeValue("//corpuslink", "href", mcrobj1); + String crpID2 = getAttributeValue("//corpuslink", "href", mcrobj2); + //get these two corpmeta Objects + MCRObject corpo1 = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(crpID1)); + MCRObject corpo2 = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(crpID2)); + //are the texts equal? get list of 'processed-words' derivate + String corp1DerivID = getAttributeValue("//structure/derobjects/derobject", "href", corpo1); + String corp2DerivID = getAttributeValue("//structure/derobjects/derobject", "href", corpo2); + + ArrayList result = new ArrayList(getContentFromFile(corp1DerivID, ""));|\label{ln:writeContent}| + result.remove(getContentFromFile(corp2DerivID, ""));|\label{ln:removeContent}| + if (result.size() == 0) // the texts are equal + { + // extract occurrences of one the objects + occurrences = Integer.parseInt(getAttributeValue("//morphiloContainer/morphilo/w", "occurrence", mcrobj1)); + } + else + { + occurrences = 0; //project metadata happened to be the same, but texts are different + } + return occurrences; +} +\end{lstlisting} +In this implementation, the ids from the \emph{corpmeta} data model are accessed via the xlink attribute in the morphilo documents. +The method \emph{getAttributeValue(String, String, MCRObject)} does exactly the same as demonstrated earlier (see from line \ref{ln:namespace} +on in listing \ref{src:getUnknowWords}). The underlying logic is that the texts are equal if exactly the same number of words were uploaded. +So all words from one file are written to a list (line \ref{ln:writeContent}) and words from the other file are removed from the +very same list (line \ref{ln:removeContent}). If this list is empty, then the exact same number of words must have been in both files and the occurrences +are adjusted accordingly. Since this method is called from another private method that only contains a loop through all equal objects, one gets +the occurrences from all equal texts. For reasons of confirmability, the looping method is also given: +\begin{lstlisting}[language=java,caption={Occurrence Extraction from Equal Texts (2)},label=src:equalOcc2,escapechar=|] +private int getOccurrencesFromEqualTexts() throws Exception +{ + ArrayList<MCRObject> equalObjects = new ArrayList<MCRObject>(); + equalObjects = getAllEqualMCRObjects(); + int occurrences = 0; + for (MCRObject obj : equalObjects) + { + occurrences = occurrences + getOccurrencesFromEqualTexts(mycoreObject, obj); + } + return occurrences; +} +\end{lstlisting} + +Now, the constructor in listing \ref{src:constructQC} reveals another method that rolls out an equally complex concatenation of procedures. +As implied above, \emph{getEqualObjectNumber()} returns the number of equally annotated words. It does this by falling back to another +method from which the size of the returned list is calculated (\emph{getAllEqualMCRObjects().size()}). Hence, we should care about +\emph{getAllEqualMCRObjects()}. This method really has the same design as \emph{int getOccurrencesFromEqualTexts()} in listing \ref{src:equalOcc2}. +The difference is that another method (\emph{Boolean compareMCRObjects(MCRObject, MCRObject, String)}) is used within the loop and +that all equal objects are put into the list of MyCoRe objects that are returned. If this list comprises more than 20 +entries,\footnote{This number is somewhat arbitrary. It is inspired by the sample size n in t-distributed data.} the respective document +will be integrated in the master data base by the process described above. +The comparator logic is shown in listing \ref{src:compareMCR}. +\begin{lstlisting}[language=java,caption={Comparison of MyCoRe objects},label=src:compareMCR,escapechar=|] +private Boolean compareMCRObjects(MCRObject mcrobj1, MCRObject mcrobj2, String xpath) throws SAXException, IOException +{ + Boolean isEqual = false; + Boolean beginTime = false; + Boolean endTime = false; + Boolean occDiff = false; + Boolean corpusDiff = false; + + String source = getXMLFromObject(mcrobj1, xpath); + String target = getXMLFromObject(mcrobj2, xpath); + + XMLUnit.setIgnoreAttributeOrder(true); + XMLUnit.setIgnoreComments(true); + XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true); + XMLUnit.setIgnoreWhitespace(true); + XMLUnit.setNormalizeWhitespace(true); + + //differences in occurrences, end, begin should be ignored + try + { + Diff xmlDiff = new Diff(source, target); + DetailedDiff dd = new DetailedDiff(xmlDiff); + //counters for differences + int i = 0; + int j = 0; + int k = 0; + int l = 0; + // list containing all differences + List differences = dd.getAllDifferences();|\label{ln:difflist}| + for (Object object : differences) + { + Difference difference = (Difference) object; + //@begin,@end,... node is not in the difference list if the count is 0 + if (difference.getControlNodeDetail().getXpathLocation().endsWith("@begin")) i++;|\label{ln:diffbegin}| + if (difference.getControlNodeDetail().getXpathLocation().endsWith("@end")) j++; + if (difference.getControlNodeDetail().getXpathLocation().endsWith("@occurrence")) k++; + if (difference.getControlNodeDetail().getXpathLocation().endsWith("@corpus")) l++;|\label{ln:diffend}| + //@begin and @end have different values: they must be checked if they fall right in the allowed time range + if ( difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) + && difference.getControlNodeDetail().getXpathLocation().endsWith("@begin") + && (Integer.parseInt(difference.getControlNodeDetail().getValue()) < Integer.parseInt(difference.getTestNodeDetail().getValue())) ) + { + beginTime = true; + } + if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) + && difference.getControlNodeDetail().getXpathLocation().endsWith("@end") + && (Integer.parseInt(difference.getControlNodeDetail().getValue()) > Integer.parseInt(difference.getTestNodeDetail().getValue())) ) + { + endTime = true; + } + //attribute values of @occurrence and @corpus are ignored if they are different + if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) + && difference.getControlNodeDetail().getXpathLocation().endsWith("@occurrence")) + { + occDiff = true; + } + if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) + && difference.getControlNodeDetail().getXpathLocation().endsWith("@corpus")) + { + corpusDiff = true; + } + } + //if any of @begin, @end ... is identical set Boolean to true + if (i == 0) beginTime = true;|\label{ln:zerobegin}| + if (j == 0) endTime = true; + if (k == 0) occDiff = true; + if (l == 0) corpusDiff = true;|\label{ln:zeroend}| + //if the size of differences is greater than the number of changes admitted in @begin, @end ... something else must be different + if (beginTime && endTime && occDiff && corpusDiff && (i + j + k + l) == dd.getAllDifferences().size()) isEqual = true;|\label{ln:diffsum}| + } + catch (SAXException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + return isEqual; +} +\end{lstlisting} +In this method, XMLUnit is heavily used to make all necessary node comparisons. The matter becomes more complicated, however, if some attributes +are not only ignored, but evaluated according to a given definition as it is the case for the time range. If the evaluator and builder classes are +not to be overwritten entirely because needed for evaluating other nodes of the +xml document, the above solution appears a bit awkward. So there is potential for improvement before the production version is to be programmed. + +XMLUnit provides us with a +list of the differences of the two documents (see line \ref{ln:difflist}). There are four differences allowed, that is, the attributes \emph{occurrence}, +\emph{corpus}, \emph{begin}, and \emph{end}. For each of them a Boolean variable is set. Because any of the attributes could also be equal to the master +document and the difference list only contains the actual differences, one has to find a way to define both, equal and different, for the attributes. +This could be done by ignoring these nodes. Yet, this would not include testing if the beginning and ending dates fall into the range of the master +document. Therefore the attributes are counted as lines \ref{ln:diffbegin} through \ref{ln:diffend} reveal. If any two documents +differ in some of the four attributes just specified, then the sum of the counters (line \ref{ln:diffsum}) should not be greater than the collected differences +by XMLUnit. The rest of the if-tests assign truth values to the respective +Booleans. It is probably worth mentioning that if all counters are zero (lines +\ref{ln:zerobegin}-\ref{ln:zeroend}) the attributes and values are identical and hence the Boolean has to be set explicitly. Otherwise the test in line \ref{ln:diffsum} would fail. + +%TagCorpusServlet +Once quality control (explained in detail further down) has been passed, it is +the user's turn to interact further. By clicking on the option \emph{Manual tagging}, the \emph{TagCorpusServlet} will be callled. This servlet instantiates +\emph{ProcessCorpusServlet} to get access to the \emph{getUnknownWords}-method, which delivers the words still to be +processed and which overwrites the content of the file starting with \emph{untagged}. For the next word in \emph{leftovers} a new MyCoRe object is created +using the JDOM API and added to the file beginning with \emph{processed}. In line \ref{ln:tagmanu} of listing \ref{src:tagservlet}, the previously defined +entry mask is called, with which the proposed word structure could be confirmed or changed. How the word structure is determined will be shown later in +the text. +\begin{lstlisting}[language=java,caption={Manual Tagging Procedure},label=src:tagservlet,escapechar=|] +... +if (!leftovers.isEmpty()) +{ + ArrayList<String> processed = new ArrayList<String>(); + //processed.add(leftovers.get(0)); + JDOMorphilo jdm = new JDOMorphilo(); + MCRObject obj = jdm.createMorphiloObject(job, leftovers.get(0));|\label{ln:jdomobject}| + //write word to be annotated in process list and save it + Path filePathProc = pcs.getDerivateFilePath(job, "processed").getFileName(); + Path proc = root.resolve(filePathProc); + processed = pcs.getContentFromFile(job, "processed"); + processed.add(leftovers.get(0)); + Files.write(proc, processed); + + //call entry mask for next word + tagUrl = prop.getBaseURL() + "content/publish/morphilo.xed?id=" + obj.getId();|\label{ln:tagmanu}| +} +else +{ + //initiate process to give a complete tagged file of the original corpus + //if untagged-file is empty, match original file with morphilo + //creator=administrator OR creator=username and write matches in a new file + ArrayList<String> complete = new ArrayList<String>(); + ProcessCorpusServlet pcs2 = new ProcessCorpusServlet(); + complete = pcs2.getUnknownWords( + pcs2.getContentFromFile(job, ""), //main corpus file + pcs2.getCorpusMetadata(job, "def.datefrom"), + pcs2.getCorpusMetadata(job, "def.dateuntil"), + "", //wordtype + false, + false, + true); + + Files.delete(p); + MCRXMLFunctions mdm = new MCRXMLFunctions(); + String mainFile = mdm.getMainDocName(derivID); + Path newRoot = root.resolve("tagged-" + mainFile); + Files.write(newRoot, complete); + + //return to Menu page + tagUrl = prop.getBaseURL() + "receive/" + corpID; +} +\end{lstlisting} +At the point where no more items are in \emph{leftsovers} the \emph{getUnknownWords}-method is called whereas the last Boolean parameter +is set true. This indicates that the array list containing all available and relevant data to the respective user is returned as seen in +the code snippet in listing \ref{src:writeAll}. +\begin{lstlisting}[language=java,caption={Code snippet to deliver all data to the user},label=src:writeAll,escapechar=|] +... +// all data is written to lo in TEI +if (writeAllData && isAuthorized && timeCorrect) +{ + XPathExpression<Element> xpath = xpfac.compile("//morphiloContainer/morphilo", Filters.element()); + for (Element e : xpath.evaluate(jdomDoc)) + { + XMLOutputter outputter = new XMLOutputter(); + outputter.setFormat(Format.getPrettyFormat()); + lo.add(outputter.outputString(e.getContent())); + } +} +... +\end{lstlisting} +The complete list (\emph{lo}) is written to yet a third file starting with \emph{tagged} and finally returned to the main project webpage. + +%JDOMorphilo +The interesting question is now where does the word structure come from, which is filled in the entry mask as asserted above. +In listing \ref{src:tagservlet} line \ref{ln:jdomobject}, one can see that a JDOM object is created and the method +\emph{createMorphiloObject(MCRServletJob, String)} is called. The string parameter is the word that needs to be analyzed. +Most of the method is a mere application of the JDOM API given the data model in chapter \ref{chap:concept} section +\ref{subsec:datamodel} and listing \ref{lst:worddatamodel}. That means namespaces, elements and their attributes are defined in the correct +order and hierarchy. + +To fill the elements and attributes with text, i.e. prefixes, suffixes, stems, etc., a Hashmap -- containing the morpheme as +key and its position as value -- are created that are filled with the results from an AffixStripper instantiation. Depending on how many prefixes +or suffixes respectively are put in the hashmap, the same number of xml elements are created. As a final step, a valid MyCoRe id is generated using +the existing MyCoRe functionality, the object is created and returned to the TagCorpusServlet. + +%AffixStripper explanation +Last, the analyses of the word structure will be considered. It is implemented +in the \emph{AffixStripper.java} file. +All lexical affix morphemes and their allomorphs as well as the inflections were extracted from the +OED\footnote{Oxford English Dictionary http://www.oed.com/} and saved as enumerated lists (see the example in listing \ref{src:enumPref}). +The allomorphic items of these lists are mapped successively to the beginning in the case of prefixes +(see listing \ref{src:analyzePref}, line \ref{ln:prefLoop}) or to the end of words in the case of suffixes +(see listing \ref{src:analyzeSuf}). Since each +morphemic variant maps to its morpheme right away, it makes sense to use the morpheme and so +implicitly keep the relation to its allomorph. + +\begin{lstlisting}[language=java,caption={Enumeration Example for the Prefix "over"},label=src:enumPref,escapechar=|] +package custom.mycore.addons.morphilo; + +public enum PrefixEnum { +... + over("over"), ufer("over"), ufor("over"), uferr("over"), uvver("over"), obaer("over"), ober("over)"), ofaer("over"), + ofere("over"), ofir("over"), ofor("over"), ofer("over"), ouer("over"),oferr("over"), offerr("over"), offr("over"), aure("over"), + war("over"), euer("over"), oferre("over"), oouer("over"), oger("over"), ouere("over"), ouir("over"), ouire("over"), + ouur("over"), ouver("over"), ouyr("over"), ovar("over"), overe("over"), ovre("over"),ovur("over"), owuere("over"), owver("over"), + houyr("over"), ouyre("over"), ovir("over"), ovyr("over"), hover("over"), auver("over"), awver("over"), ovver("over"), + hauver("over"), ova("over"), ove("over"), obuh("over"), ovah("over"), ovuh("over"), ofowr("over"), ouuer("over"), oure("over"), + owere("over"), owr("over"), owre("over"), owur("over"), owyr("over"), our("over"), ower("over"), oher("over"), + ooer("over"), oor("over"), owwer("over"), ovr("over"), owir("over"), oar("over"), aur("over"), oer("over"), ufara("over"), + ufera("over"), ufere("over"), uferra("over"), ufora("over"), ufore("over"), ufra("over"), ufre("over"), ufyrra("over"), + yfera("over"), yfere("over"), yferra("over"), uuera("over"), ufe("over"), uferre("over"), uuer("over"), uuere("over"), + vfere("over"), vuer("over"), vuere("over"), vver("over"), uvvor("over") ... +...chap:results + private String morpheme; + //constructor + PrefixEnum(String morpheme) + { + this.morpheme = morpheme; + } + //getter Method + + public String getMorpheme() + { + return this.morpheme; + } +} +\end{lstlisting} +As can be seen in line \ref{ln:prefPutMorph} in listing \ref{src:analyzePref}, the morpheme is saved to a hash map together with its position, i.e. the size of the +map plus one at the time being. In line \ref{ln:prefCutoff} the \emph{analyzePrefix} method is recursively called until no more matches can be made. + +\begin{lstlisting}[language=java,caption={Method to recognize prefixes},label=src:analyzePref,escapechar=|] +private Map<String, Integer> prefixMorpheme = new HashMap<String,Integer>(); +... +private void analyzePrefix(String restword) +{ + if (!restword.isEmpty()) //Abbruchbedingung fuer Rekursion + { + for (PrefixEnum prefEnum : PrefixEnum.values())|\label{ln:prefLoop}| + { + String s = prefEnum.toString(); + if (restword.startsWith(s)) + { + prefixMorpheme.put(s, prefixMorpheme.size() + 1);|\label{ln:prefPutMorph}| + //cut off the prefix that is added to the list + analyzePrefix(restword.substring(s.length()));|\label{ln:prefCutoff}| + } + else + { + analyzePrefix(""); + } + } + } +} +\end{lstlisting} + +The recognition of suffixes differs only in the cut-off direction since suffixes occur at the end of a word. +Hence, line \ref{ln:prefCutoff} in listing \ref{src:analyzePref} reads in the case of suffixes. + +\begin{lstlisting}[language=java,caption={Cut-off mechanism for suffixes},label=src:analyzeSuf,escapechar=|] +analyzeSuffix(restword.substring(0, restword.length() - s.length())); +\end{lstlisting} + +It is important to note that inflections are suffixes (in the given model case of Middle English morphology) that usually occur at the very +end of a word, i.e. after all lexical suffixes, only once. It follows that inflections +have to be recognized at first without any repetition. So the procedure for inflections can be simplified +to a substantial degree as listing \ref{src:analyzeInfl} shows. + +\begin{lstlisting}[language=java,caption={Method to recognize inflections},label=src:analyzeInfl,escapechar=|] +private String analyzeInflection(String wrd) +{ + String infl = ""; + for (InflectionEnum inflEnum : InflectionEnum.values()) + { + if (wrd.endsWith(inflEnum.toString())) + { + infl = inflEnum.toString(); + } + } + return infl; +} +\end{lstlisting} + +Unfortunately the embeddedness problem prevents a very simple algorithm. Embeddedness occurs when a lexical item +is a substring of another lexical item. To illustrate, the suffix \emph{ion} is also contained in the suffix \emph{ation}, as is +\emph{ent} in \emph{ment}, and so on. The embeddedness problem cannot be solved completely on the basis of linear modelling, but +for a large part of embedded items one can work around it using implicitly Zipf's law, i.e. the correlation between frequency +and length of lexical items. The longer a word becomes, the less frequent it will occur. The simplest logic out of it is to assume +that longer suffixes (measured in letters) are preferred over shorter suffixes because it is more likely tha the longer the suffix string becomes, +the more likely it is one (as opposed to several) suffix unit(s). This is done in listing \ref{src:embedAffix}, whereas +the inner class \emph{sortedByLengthMap} returns a list sorted by length and the loop from line \ref{ln:deleteAffix} onwards deletes +the respective substrings. + +\begin{lstlisting}[language=java,caption={Method to workaround embeddedness},label=src:embedAffix,escapechar=|] +private Map<String, Integer> sortOutAffixes(Map<String, Integer> affix) +{ + Map<String,Integer> sortedByLengthMap = new TreeMap<String, Integer>(new Comparator<String>() + { + @Override + public int compare(String s1, String s2) + { + int cmp = Integer.compare(s1.length(), s2.length()); + return cmp != 0 ? cmp : s1.compareTo(s2); + } + } + ); + sortedByLengthMap.putAll(affix); + ArrayList<String> al1 = new ArrayList<String>(sortedByLengthMap.keySet()); + ArrayList<String> al2 = al1; + Collections.reverse(al2); + for (String s2 : al1)|\label{ln:deleteAffix}| + { + for (String s1 : al2) + if (s1.contains(s2) && s1.length() > s2.length()) + { + affix.remove(s2); + } + } + return affix; +} +\end{lstlisting} + +Finally, the position of the affix has to be calculated because the hashmap in line \ref{ln:prefPutMorph} in +listing \ref{src:analyzePref} does not keep the original order for changes taken place in addressing the affix embeddedness +(listing \ref{src:embedAffix}). Listing \ref{src:affixPos} depicts the preferred solution. +The recursive construction of the method is similar to \emph{private void analyzePrefix(String)} (listing \ref{src:analyzePref}) +only that the two affix types are handled in one method. For that, an additional parameter taking the form either \emph{suffix} +or \emph{prefix} is included. + +\begin{lstlisting}[language=java,caption={Method to determine position of the affix},label=src:affixPos,escapechar=|] +private void getAffixPosition(Map<String, Integer> affix, String restword, int pos, String affixtype) +{ + if (!restword.isEmpty()) //Abbruchbedingung fuer Rekursion + { + for (String s : affix.keySet()) + { + if (restword.startsWith(s) && affixtype.equals("prefix")) + { + pos++; + prefixMorpheme.put(s, pos); + //prefixAllomorph.add(pos-1, restword.substring(s.length())); + getAffixPosition(affix, restword.substring(s.length()), pos, affixtype); + } + else if (restword.endsWith(s) && affixtype.equals("suffix")) + { + pos++; + suffixMorpheme.put(s, pos); + //suffixAllomorph.add(pos-1, restword.substring(s.length())); + getAffixPosition(affix, restword.substring(0, restword.length() - s.length()), pos, affixtype); + } + else + { + getAffixPosition(affix, "", pos, affixtype); + } + } + } +} +\end{lstlisting} + +To give the complete word structure, the root of a word should also be provided. In listing \ref{src:rootAnalyze} a simple solution is offered, however, +considering compounds as words consisting of more than one root. +\begin{lstlisting}[language=java,caption={Method to determine roots},label=src:rootAnalyze,escapechar=|] +private ArrayList<String> analyzeRoot(Map<String, Integer> pref, Map<String, Integer> suf, int stemNumber) +{ + ArrayList<String> root = new ArrayList<String>(); + int j = 1; //one root always exists + // if word is a compound several roots exist + while (j <= stemNumber) + { + j++; + String rest = lemma;|\label{ln:lemma}| + + for (int i=0;i<pref.size();i++) + { + for (String s : pref.keySet()) + { + //if (i == pref.get(s)) + if (rest.length() > s.length() && s.equals(rest.substring(0, s.length()))) + { + rest = rest.substring(s.length(),rest.length()); + } + } + } + + for (int i=0;i<suf.size();i++) + { + for (String s : suf.keySet()) + { + //if (i == suf.get(s)) + if (s.length() < rest.length() && (s.equals(rest.substring(rest.length() - s.length(), rest.length())))) + { + rest = rest.substring(0, rest.length() - s.length()); + } + } + } + root.add(rest); + } + return root; +} +\end{lstlisting} +The logic behind this method is that the root is the remainder of a word when all prefixes and suffixes are substracted. +So the loops run through the number of prefixes and suffixes at each position and substract the affix. Really, there is +some code doubling with the previously described methods, which could be eliminated by making it more modular in a possible +refactoring phase. Again, this is not the concern of a prototype. Line \ref{ln:lemma} defines the initial state of a root, +which is the case for monomorphemic words. The \emph{lemma} is defined as the wordtoken without the inflection. Thus listing +\ref{src:lemmaAnalyze} reveals how the class variable is calculated +\begin{lstlisting}[language=java,caption={Method to determine lemma},label=src:lemmaAnalyze,escapechar=|] +/* + * Simplification: lemma = wordtoken - inflection + */ +private String analyzeLemma(String wrd, String infl) +{ + return wrd.substring(0, wrd.length() - infl.length()); +} +\end{lstlisting} +The constructor of \emph{AffixStripper} calls the method \emph{analyzeWord()} +whose only job is to calculate each structure element in the correct order +(listing \ref{src:lemmaAnalyze}). All structure elements are also provided by getters. +\begin{lstlisting}[language=java,caption={Method to determine all word structure},label=src:lemmaAnalyze,escapechar=|] +private void analyzeWord() +{ + //analyze inflection first because it always occurs at the end of a word + inflection = analyzeInflection(wordtoken); + lemma = analyzeLemma(wordtoken, inflection); + analyzePrefix(lemma); + analyzeSuffix(lemma); + getAffixPosition(sortOutAffixes(prefixMorpheme), lemma, 0, "prefix"); + getAffixPosition(sortOutAffixes(suffixMorpheme), lemma, 0, "suffix"); + prefixNumber = prefixMorpheme.size(); + suffixNumber = suffixMorpheme.size(); + wordroot = analyzeRoot(prefixMorpheme, suffixMorpheme, getStemNumber()); +} +\end{lstlisting} + +To conclude, the Morphilo implementation as presented here, aims at fulfilling the task of a working prototype. It is important to note +that it neither claims to be a very efficient nor a ready software program to be used in production. However, it marks a crucial milestone +on the way to a production system. At some listings sources of improvement were made explicit; at others no suggestions were made. In the latter +case this does not imply that there is no potential for improvement. Once acceptability tests are carried out, it will be the task of a follow up project +to identify these potentials and implement them accordingly. \ No newline at end of file diff --git a/Morphilo_doc/_build/html/_sources/source/datamodel.rst.txt b/Morphilo_doc/_build/html/_sources/source/datamodel.rst.txt index 2d0aef4..f206ef3 100644 --- a/Morphilo_doc/_build/html/_sources/source/datamodel.rst.txt +++ b/Morphilo_doc/_build/html/_sources/source/datamodel.rst.txt @@ -1,5 +1,60 @@ -Data Model Implementation -========================= +Data Model +========== + +Conceptualization +----------------- + +From both the user and task requirements one can derive that four basic +functions of data processing need to be carried out. Data have to be read, persistently +saved, searched, and deleted. Furthermore, some kind of user management +and multi-user processing is necessary. In addition, the framework should +support web technologies, be well documented, and easy to extent. Ideally, the +MVC pattern is realized. + +\subsection{Data Model}\label{subsec:datamodel} +The guidelines of the +\emph{TEI}-standard\footnote{http://www.tei-c.org/release/doc/tei-p5-doc/en/Guidelines.pdf} on the +word level are defined in line with the structure defined above in section \ref{subsec:morphologicalSystems}. +In listing \ref{lst:teiExamp} an +example is given for a possible markup at the word level for +\emph{comfortable}.\footnote{http://www.tei-c.org/release/doc/tei-p5-doc/en/html/ref-m.html} + +\begin{lstlisting}[language=XML, +caption={TEI-example for 'comfortable'},label=lst:teiExamp] +<w type="adjective"> + <m type="base"> + <m type="prefix" baseForm="con">com</m> + <m type="root">fort</m> + </m> + <m type="suffix">able</m> +</w> +\end{lstlisting} + +This data model reflects just one theoretical conception of a word structure model. +Crucially, the model emanates from the assumption +that the suffix node is on par with the word base. On the one hand, this +implies that the word stem directly dominates the suffix, but not the prefix. The prefix, on the +other hand, is enclosed in the base, which basically means a stronger lexical, +and less abstract, attachment to the root of a word. Modeling prefixes and suffixes on different +hierarchical levels has important consequences for the branching direction at +subword level (here right-branching). Left the theoretical interest aside, the +choice of the TEI standard is reasonable with view to a sustainable architecture that allows for +exchanging data with little to no additional adjustments. + +The negative account is that the model is not eligible for all languages. +It reflects a theoretical construction based on Indo-European +languages. If attention is paid to which language this software is used, it will +not be problematic. This is the case for most languages of the Indo-European +stem and corresponds to the overwhelming majority of all research carried out +(unfortunately). + +Implementation +-------------- + +As laid out in the task analysis in section \ref{subsec:datamodel}, it is +advantageous to use established standards. It was also shown that it makes sense +to keep the meta data of each corpus separate from the data model used for the +words to be analyzed. For the present case, the TEI-standard was identified as an appropriate markup for words. In terms of the implementation this means that @@ -26,3 +81,161 @@ Whereas attributes of the objecttype are specific to the repository framework, t recognized in the hierarchy of the meta data element starting with the name \emph{w} (line \ref{src:wordbegin}). +\begin{lstlisting}[language=XML,caption={Word Data +model},label=lst:worddatamodel,escapechar=|] <?xml version="1.0" encoding="UTF-8"?> +<objecttype + name="morphilo" + isChild="true" + isParent="true" + hasDerivates="true" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="datamodel.xsd"> + <metadata> + <element name="morphiloContainer" type="xml" style="dontknow" + notinherit="true" heritable="false"> + <xs:sequence> + <xs:element name="morphilo"> + <xs:complexType> + <xs:sequence> + <xs:element name="w" minOccurs="0" maxOccurs="unbounded">|label{src:wordbegin}| + <xs:complexType mixed="true"> + <xs:sequence> + <!-- stem --> + <xs:element name="m1" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType mixed="true"> + <xs:sequence> + <!-- base --> + <xs:element name="m2" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType mixed="true"> + <xs:sequence> + <!-- root --> + <xs:element name="m3" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType mixed="true"> + <xs:attribute name="type" type="xs:string"/> + </xs:complexType> + </xs:element> + <!-- prefix --> + <xs:element name="m4" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType mixed="true"> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="PrefixbaseForm" type="xs:string"/> + <xs:attribute name="position" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="type" type="xs:string"/> + </xs:complexType> + </xs:element> + <!-- suffix --> + <xs:element name="m5" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType mixed="true"> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="SuffixbaseForm" type="xs:string"/> + <xs:attribute name="position" type="xs:string"/> + <xs:attribute name="inflection" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <!-- stem-Attribute --> + <xs:attribute name="type" type="xs:string"/> + <xs:attribute name="pos" type="xs:string"/> + <xs:attribute name="occurrence" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + <!-- w -Attribute auf Wortebene --> + <xs:attribute name="lemma" type="xs:string"/> + <xs:attribute name="complexType" type="xs:string"/> + <xs:attribute name="wordtype" type="xs:string"/> + <xs:attribute name="occurrence" type="xs:string"/> + <xs:attribute name="corpus" type="xs:string"/> + <xs:attribute name="begin" type="xs:string"/> + <xs:attribute name="end" type="xs:string"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </element> + <element name="wordtype" type="classification" minOccurs="0" maxOccurs="1"> + <classification id="wordtype"/> + </element> + <element name="complexType" type="classification" minOccurs="0" maxOccurs="1"> + <classification id="complexType"/> + </element> + <element name="corpus" type="classification" minOccurs="0" maxOccurs="1"> + <classification id="corpus"/> + </element> + <element name="pos" type="classification" minOccurs="0" maxOccurs="1"> + <classification id="pos"/> + </element> + <element name="PrefixbaseForm" type="classification" minOccurs="0" + maxOccurs="1"> + <classification id="PrefixbaseForm"/> + </element> + <element name="SuffixbaseForm" type="classification" minOccurs="0" + maxOccurs="1"> + <classification id="SuffixbaseForm"/> + </element> + <element name="inflection" type="classification" minOccurs="0" maxOccurs="1"> + <classification id="inflection"/> + </element> + <element name="corpuslink" type="link" minOccurs="0" maxOccurs="unbounded" > + <target type="corpmeta"/> + </element> + </metadata> +</objecttype> +\end{lstlisting} + +Additionally, it is worth mentioning that some attributes are modeled as a +\emph{classification}. All these have to be listed +as separate elements in the data model. This has been done for all attributes +that are more or less subject to little or no change. In fact, all known suffix +and prefix morphemes should be known for the language investigated and are +therefore defined as a classification. +The same is true for the parts of speech named \emph{pos} in the morphilo data +model above. +Here the PENN-Treebank tagset was used. Last, the different morphemic layers in +the standard model named \emph{m} are changed to $m1$ through $m5$. This is the +only change in the standard that could be problematic if the data is to be +processed elsewhere and the change is not documented more explicitly. Yet, this +change was necessary for the MyCoRe repository throws errors caused by ambiguity +issues on the different $m$-layers. + +The second data model describes only very few properties of the text corpora +from which the words are extracted. Listing \ref{lst:corpusdatamodel} depicts +only the meta data element. For the sake of simplicity of the prototype, this +data model is kept as simple as possible. The obligatory field is the name of +the corpus. Specific dates of the corpus are classified as optional because in +some cases a text cannot be dated reliably. + + +\begin{lstlisting}[language=XML,caption={Corpus Data +Model},label=lst:corpusdatamodel] +<metadata> + <!-- Pflichtfelder --> + <element name="korpusname" type="text" minOccurs="1" maxOccurs="1"/> + <!-- Optionale Felder --> + <element name="sprache" type="text" minOccurs="0" maxOccurs="1"/> + <element name="size" type="number" minOccurs="0" maxOccurs="1"/> + <element name="datefrom" type="text" minOccurs="0" maxOccurs="1"/> + <element name="dateuntil" type="text" minOccurs="0" maxOccurs="1"/> + <!-- number of words --> + <element name="NoW" type="text" minOccurs="0" maxOccurs="1"/> + <element name="corpuslink" type="link" minOccurs="0" maxOccurs="unbounded"> + <target type="morphilo"/> + </element> +</metadata> +\end{lstlisting} + +As a final remark, one might have noticed that all attributes are modelled as +strings although other data types are available and fields encoding the dates or +the number of words suggest otherwise. The MyCoRe framework even provides a +data type \emph{historydate}. There is not a very satisfying answer to its +disuse. +All that can be said is that the use of data types different than the string +leads later on to problems in the convergence between the search engine and the +repository framework. These issues seem to be well known and can be followed on +github. \ No newline at end of file diff --git a/Morphilo_doc/_build/html/_sources/source/framework.rst.txt b/Morphilo_doc/_build/html/_sources/source/framework.rst.txt new file mode 100644 index 0000000..1b9925d --- /dev/null +++ b/Morphilo_doc/_build/html/_sources/source/framework.rst.txt @@ -0,0 +1,27 @@ +Framework +========= + +\begin{figure} + \centering + \includegraphics[scale=0.33]{mycore_architecture-2.png} + \caption[MyCoRe-Architecture and Components]{MyCoRe-Architecture and Components\protect\footnotemark} + \label{fig:abbMyCoReStruktur} +\end{figure} +\footnotetext{source: https://www.mycore.de} +To specify the MyCoRe framework the morphilo application logic will have to be implemented, +the TEI data model specified, and the input, search and output mask programmed. + +There are three directories which are +important for adjusting the MyCoRe framework to the needs of one's own application. These three directories +correspond essentially to the three components in the MVC model as explicated in +section \ref{subsec:mvc}. Roughly, they are envisualized in figure \ref{fig:abbMyCoReStruktur} in the upper +right hand corner. More precisely, the view (\emph{Layout} in figure \ref{fig:abbMyCoReStruktur}) and the model layer +(\emph{Datenmodell} in figure \ref{fig:abbMyCoReStruktur}) can be done +completely via the ``interface'', which is a directory with a predefined +structure and some standard files. For the configuration of the logic an extra directory is offered (/src/main/java/custom/mycore/addons/). Here all, java classes +extending the controller layer should be added. +Practically, all three MVC layers are placed in the +\emph{src/main/}-directory of the application. In one of the subdirectories, +\emph{datamodel/def}, the datamodel specifications are defined as xml files. It parallels the model +layer in the MVC pattern. How the data model was defined will be explained in +section \ref{subsec:datamodelimpl}. \ No newline at end of file diff --git a/Morphilo_doc/_build/html/_sources/source/view.rst.txt b/Morphilo_doc/_build/html/_sources/source/view.rst.txt new file mode 100644 index 0000000..5f09e06 --- /dev/null +++ b/Morphilo_doc/_build/html/_sources/source/view.rst.txt @@ -0,0 +1,247 @@ +View +==== + +Conceptualization +----------------- + +Lastly, the third directory (\emph{src/main/resources}) contains all code needed +for rendering the data to be displayed on the screen. So this corresponds to +the view in an MVC approach. It is done by xsl-files that (unfortunately) +contain some logic that really belongs to the controller. Thus, the division is +not as clear as implied in theory. I will discuss this issue more specifically in the +relevant subsection below. Among the resources are also all images, styles, and +javascripts. + +Implementation +-------------- + +As explained in section \ref{subsec:mvc}, the view component handles the visual +representation in the form of an interface that allows interaction between +the user and the task to be carried out by the machine. As a +webservice in the present case, all interaction happens via a browser, i.e. webpages are +visualized and responses are recognized by registering mouse or keyboard +events. More specifically, a webpage is rendered by transforming xml documents +to html pages. The MyCoRe repository framework uses an open source XSLT +processor from Apache, Xalan.\footnote{http://xalan.apache.org} This engine +transforms document nodes described by the XPath syntax into hypertext making +use of a special form of template matching. All templates are collected in so +called xml-encoded stylesheets. Since there are two data models with two +different structures, it is good practice to define two stylesheet files one for +each data model. + +As a demonstration, in listing \ref{lst:morphilostylesheet} below a short +extract is given for rendering the word data. + +\begin{lstlisting}[language=XML,caption={stylesheet +morphilo.xsl},label=lst:morphilostylesheet] +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:xalan="http://xml.apache.org/xalan" + xmlns:i18n="xalan://org.mycore.services.i18n.MCRTranslation" + xmlns:acl="xalan://org.mycore.access.MCRAccessManager" + xmlns:mcr="http://www.mycore.org/" xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:mods="http://www.loc.gov/mods/v3" + xmlns:encoder="xalan://java.net.URLEncoder" + xmlns:mcrxsl="xalan://org.mycore.common.xml.MCRXMLFunctions" + xmlns:mcrurn="xalan://org.mycore.urn.MCRXMLFunctions" + exclude-result-prefixes="xalan xlink mcr i18n acl mods mcrxsl mcrurn encoder" + version="1.0"> + <xsl:param name="MCR.Users.Superuser.UserName"/> + + <xsl:template match="/mycoreobject[contains(@ID,'_morphilo_')]"> + <head> + <link href="{$WebApplicationBaseURL}css/file.css" rel="stylesheet"/> + </head> + <div class="row"> + <xsl:call-template name="objectAction"> + <xsl:with-param name="id" select="@ID"/> + <xsl:with-param name="deriv" select="structure/derobjects/derobject/@xlink:href"/> + </xsl:call-template> + <xsl:variable name="objID" select="@ID"/> + <!-- Hier Ueberschrift setzen --> + <h1 style="text-indent: 4em;"> + <xsl:if test="metadata/def.morphiloContainer/morphiloContainer/morphilo/w"> + <xsl:value-of select="metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text()[string-length(normalize-space(.))>0]"/> + </xsl:if> + </h1> + <dl class="dl-horizontal"> + <!-- (1) Display word --> + <xsl:if test="metadata/def.morphiloContainer/morphiloContainer/morphilo/w"> + <dt> + <xsl:value-of select="i18n:translate('response.page.label.word')"/> + </dt> + <dd> + <xsl:value-of select="metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text()[string-length(normalize-space(.))>0]"/> + </dd> + </xsl:if> + <!-- (2) Display lemma --> + ... + </xsl:template> + ... + <xsl:template name="objectAction"> + ... + </xsl:template> +... +</xsl:stylesheet> +\end{lstlisting} +This template matches with +the root node of each \emph{MyCoRe object} ensuring that a valid MyCoRe model is +used and checking that the document to be processed contains a unique +identifier, here a \emph{MyCoRe-ID}, and the name of the correct data model, +here \emph{morphilo}. +Then, another template, \emph{objectAction}, is called together with two parameters, the ids +of the document object and attached files. In the remainder all relevant +information from the document is accessed by XPath, such as the word and the lemma, +and enriched with hypertext annotations it is rendered as a hypertext document. +The template \emph{objectAction} is key to understand the coupling process in the software +framework. It is therefore separately listed in \ref{lst:objActionTempl}. + +\begin{lstlisting}[language=XML,caption={template +objectAction},label=lst:objActionTempl,escapechar=|] +<xsl:template name="objectAction"> + <xsl:param name="id" select="./@ID"/> + <xsl:param name="accessedit" select="acl:checkPermission($id,'writedb')"/> + <xsl:param name="accessdelete" select="acl:checkPermission($id,'deletedb')"/> + <xsl:variable name="derivCorp" select="./@label"/> + <xsl:variable name="corpID" select="metadata/def.corpuslink[@class='MCRMetaLinkID']/corpuslink/@xlink:href"/> + <xsl:if test="$accessedit or $accessdelete">|\label{ln:ng}| + <div class="dropdown pull-right"> + <xsl:if test="string-length($corpID) > 0 or $CurrentUser='administrator'"> + <button class="btn btn-default dropdown-toggle" style="margin:10px" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true"> + <span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Annotieren + <span class="caret"></span> + </button> + </xsl:if> + <xsl:if test="string-length($corpID) > 0">|\label{ln:ru}| + <xsl:variable name="ifsDirectory" select="document(concat('ifs:/',$derivCorp))"/> + <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> + <li role="presentation"> + |\label{ln:nw1}|<a href="{$ServletsBaseURL}object/tag{$HttpSession}?id={$derivCorp}&objID={$corpID}" role="menuitem" tabindex="-1">|\label{ln:nw2}| + <xsl:value-of select="i18n:translate('object.nextObject')"/> + </a> + </li> + <li role="presentation"> + <a href="{$WebApplicationBaseURL}receive/{$corpID}" role="menuitem" tabindex="-1"> + <xsl:value-of select="i18n:translate('object.backToProject')"/> + </a> + </li> + </ul> + </xsl:if> + <xsl:if test="$CurrentUser='administrator'"> + <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> + <li role="presentation"> + <a role="menuitem" tabindex="-1" href="{$WebApplicationBaseURL}content/publish/morphilo.xed?id={$id}"> + <xsl:value-of select="i18n:translate('object.editWord')"/> + </a> + </li> + <li role="presentation"> + <a href="{$ServletsBaseURL}object/delete{$HttpSession}?id={$id}" role="menuitem" tabindex="-1" class="confirm_deletion option" data-text="Wirklich loeschen"> + <xsl:value-of select="i18n:translate('object.delWord')"/> + </a> + </li> + </ul> + </xsl:if> + </div> + <div class="row" style="margin-left:0px; margin-right:10px"> + <xsl:apply-templates select="structure/derobjects/derobject[acl:checkPermission(@xlink:href,'read')]"> + <xsl:with-param name="objID" select="@ID"/> + </xsl:apply-templates> + </div> + </xsl:if> +</xsl:template> +\end{lstlisting} +The \emph{objectAction} template defines the selection menu appearing -- once manual tagging has +started -- on the upper right hand side of the webpage entitled +\emph{Annotieren} and displaying the two options \emph{next word} or \emph{back +to project}. +The first thing to note here is that in line \ref{ln:ng} a simple test +excludes all guest users from accessing the procedure. After ensuring that only +the user who owns the corpus project has access (line \ref{ln:ru}), s/he will be +able to access the drop down menu, which is really a url, e.g. line +\ref{ln:nw1}. The attentive reader might have noticed that +the url exactly matches the definition in the web-fragment.xml as shown in +listing \ref{lst:webfragment}, line \ref{ln:tag}, which resolves to the +respective java class there. Really, this mechanism is the data interface within the +MVC pattern. The url also contains two variables, named \emph{derivCorp} and +\emph{corpID}, that are needed to identify the corpus and file object by the +java classes (see section \ref{sec:javacode}). + +The morphilo.xsl stylesheet contains yet another modification that deserves mention. +In listing \ref{lst:derobjectTempl}, line \ref{ln:morphMenu}, two menu options -- +\emph{Tag automatically} and \emph{Tag manually} -- are defined. The former option +initiates ProcessCorpusServlet.java as can be seen again in listing \ref{lst:webfragment}, +line \ref{ln:process}, which determines words that are not in the master data base. +Still, it is important to note that the menu option is only displayed if two restrictions +are met. First, a file has to be uploaded (line \ref{ln:1test}) and, second, there must be +only one file. This is necessary because in the annotation process other files will be generated +that store the words that were not yet processed or a file that includes the final result. The +generated files follow a certain pattern. The file harboring the final, entire TEI-annotated +corpus is prefixed by \emph{tagged}, the other file is prefixed \emph{untagged}. This circumstance +is exploited for manipulating the second option (line \ref{ln:loop}). A loop runs through all +files in the respective directory and if a file name starts with \emph{untagged}, +the option to manually tag is displayed. + +\begin{lstlisting}[language=XML,caption={template +matching derobject},label=lst:derobjectTempl,escapechar=|] +<xsl:template match="derobject" mode="derivateActions"> + <xsl:param name="deriv" /> + <xsl:param name="parentObjID" /> + <xsl:param name="suffix" select="''" /> + <xsl:param name="id" select="../../../@ID" /> + <xsl:if test="acl:checkPermission($deriv,'writedb')"> + <xsl:variable name="ifsDirectory" select="document(concat('ifs:',$deriv,'/'))" /> + <xsl:variable name="path" select="$ifsDirectory/mcr_directory/path" /> + ... + <div class="options pull-right"> + <div class="btn-group" style="margin:10px"> + <a href="#" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> + <i class="fa fa-cog"></i> + <xsl:value-of select="' Korpus'"/> + <span class="caret"></span> + </a> + <ul class="dropdown-menu dropdown-menu-right"> + <!-- Anpasssungen Morphilo -->|\label{ln:morphMenu}| + <xsl:if test="string-length($deriv) > 0">|\label{ln:1test}| + <xsl:if test="count($ifsDirectory/mcr_directory/children/child) = 1">|\label{ln:2test}| + <li role="presentation"> + <a href="{$ServletsBaseURL}object/process{$HttpSession}?id={$deriv}&objID={$id}" role="menuitem" tabindex="-1"> + <xsl:value-of select="i18n:translate('derivate.process')"/> + </a> + </li> + </xsl:if> + <xsl:for-each select="$ifsDirectory/mcr_directory/children/child">|\label{ln:loop}| + <xsl:variable name="untagged" select="concat($path, 'untagged')"/> + <xsl:variable name="filename" select="concat($path,./name)"/> + <xsl:if test="starts-with($filename, $untagged)"> + <li role="presentation"> + <a href="{$ServletsBaseURL}object/tag{$HttpSession}?id={$deriv}&objID={$id}" role="menuitem" tabindex="-1"> + <xsl:value-of select="i18n:translate('derivate.taggen')"/> + </a> + </li> + </xsl:if> + </xsl:for-each> + </xsl:if> + ... + </ul> + </div> + </div> + </xsl:if> +</xsl:template> +\end{lstlisting} + +Besides the two stylesheets morphilo.xsl and corpmeta.xsl, other stylesheets have +to be adjusted. They will not be discussed in detail here for they are self-explanatory for the most part. +Essentially, they render the overall layout (\emph{common-layout.xsl}, \emph{skeleton\_layout\_template.xsl}) +or the presentation +of the search results (\emph{response-page.xsl}) and definitions of the solr search fields (\emph{searchfields-solr.xsl}). +The former and latter also inherit templates from \emph{response-general.xsl} and \emph{response-browse.xsl}, in which the +navigation bar of search results can be changed. For the use of multilinguality a separate configuration directory +has to be created containing as many \emph{.property}-files as different +languages want to be displayed. In the current case these are restricted to German and English (\emph{messages\_de.properties} and \emph{messages\_en.properties}). +The property files include all \emph{i18n} definitions. All these files are located in the \emph{resources} directory. + +Furthermore, a search mask and a page for manually entering the annotations had +to be designed. +For these files a specially designed xml standard (\emph{xed}) is recommended to be used within the +repository framework. \ No newline at end of file diff --git a/Morphilo_doc/_build/html/index.html b/Morphilo_doc/_build/html/index.html index 0310738..91c11e7 100644 --- a/Morphilo_doc/_build/html/index.html +++ b/Morphilo_doc/_build/html/index.html @@ -6,7 +6,7 @@ <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title>Morphilo documentation</title> + <title>Documentation Morphilo Project — Morphilo documentation</title> <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <script type="text/javascript" src="_static/documentation_options.js"></script> @@ -15,7 +15,7 @@ <script type="text/javascript" src="_static/doctools.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> - <link rel="next" title="Data Model Implementation" href="source/datamodel.html" /> + <link rel="next" title="Data Model" href="source/datamodel.html" /> <link rel="stylesheet" href="_static/custom.css" type="text/css" /> @@ -30,16 +30,32 @@ <div class="bodywrapper"> <div class="body" role="main"> - <div class="section" id="welcome-to-morphilo-s-documentation"> -<h1>Documentation Morphilo Project<a class="headerlink" href="#welcome-to-morphilo-s-documentation" title="Permalink to this headline">¶</a></h1> + <div class="section" id="documentation-morphilo-project"> +<h1>Documentation Morphilo Project<a class="headerlink" href="#documentation-morphilo-project" title="Permalink to this headline">¶</a></h1> <div class="toctree-wrapper compound"> <p class="caption"><span class="caption-text">Contents:</span></p> <ul> -<li class="toctree-l1"><a class="reference internal" href="source/datamodel.html">Data Model Implementation</a></li> +<li class="toctree-l1"><a class="reference internal" href="source/datamodel.html">Data Model</a><ul> +<li class="toctree-l2"><a class="reference internal" href="source/datamodel.html#conceptualization">Conceptualization</a></li> +<li class="toctree-l2"><a class="reference internal" href="source/datamodel.html#implementation">Implementation</a></li> +</ul> +</li> <li class="toctree-l1"><a class="reference internal" href="source/controller.html">Controller Adjustments</a><ul> <li class="toctree-l2"><a class="reference internal" href="source/controller.html#general-principle-of-operation">General Principle of Operation</a></li> +<li class="toctree-l2"><a class="reference internal" href="source/controller.html#conceptualization">Conceptualization</a></li> +<li class="toctree-l2"><a class="reference internal" href="source/controller.html#implementation">Implementation</a><ul> +<li class="toctree-l3"><a class="reference internal" href="source/controller.html#id13">}</a></li> +</ul> +</li> +</ul> +</li> +<li class="toctree-l1"><a class="reference internal" href="source/view.html">View</a><ul> +<li class="toctree-l2"><a class="reference internal" href="source/view.html#conceptualization">Conceptualization</a></li> +<li class="toctree-l2"><a class="reference internal" href="source/view.html#implementation">Implementation</a></li> </ul> </li> +<li class="toctree-l1"><a class="reference internal" href="source/architecture.html">Software Design</a></li> +<li class="toctree-l1"><a class="reference internal" href="source/framework.html">Framework</a></li> </ul> </div> </div> @@ -67,7 +83,7 @@ <h3>Related Topics</h3> <ul> <li><a href="#">Documentation overview</a><ul> - <li>Next: <a href="source/datamodel.html" title="next chapter">Data Model Implementation</a></li> + <li>Next: <a href="source/datamodel.html" title="next chapter">Data Model</a></li> </ul></li> </ul> </div> diff --git a/Morphilo_doc/_build/html/objects.inv b/Morphilo_doc/_build/html/objects.inv index a3bd984f43ed29ed035122249fe1f8fa8cc43c7d..ac6220ca7ddb74e3021a0040cda45c6da6630b09 100644 GIT binary patch delta 226 zcmZ3-bdhO7d40gyyu%7S`<`o7G;VuUx;-;=sjO1ytS#2e=8CF2jM5_S?^9TiX`1)# z`}6sXa|)&YwWR+|d&(cN@n-kJ1-B=rYug3iTx-;;)j3auJtUFs_#|Gdi^{R?$$@h? z)C2CET_NqfZo98)kypP}gvMhVkD$k^m6Id?O#L}oX2E9(kAr&AjBSq(IDFWX(X1y~ z@yyljBjX;)n6rT|W?YC`;C9OESx<lHpLNS0SpGeDT|+nWnDXOa|0m1E{7lTb%zYs2 l^UNna+?SRn))m~WS(E$qpHzg@HkS0`<!g3XA6&3=2>@vcZ+HLz delta 191 zcmcb}w2o;)d40bv-ys8@*6;I_WELodnXzy?tE#X)n-GyZQ8>I)`QS0r9dhc5fxp^M zP5V(>_kJha?I>RUhmr3C?lHLT6fL!nHO~o{b7}Jo179si<40U8PBbJ4iSAsNIni$Y zcJYZkY&za~C)aT~|MHLcuEValJ9G)Nll*H(tE+$Vo<z3kN7`GQmg4e1sCh$U(;E)K zJA2+ao%!9)dGB@ghdIA~9rW^^wlStB)~Ywk%<5SFD!H4JUkV)C-L0QIyYVLgb;nl8 diff --git a/Morphilo_doc/_build/html/searchindex.js b/Morphilo_doc/_build/html/searchindex.js index d50f9f3..c36d4c6 100644 --- a/Morphilo_doc/_build/html/searchindex.js +++ b/Morphilo_doc/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["index","source/controller","source/datamodel"],envversion:52,filenames:["index.rst","source/controller.rst","source/datamodel.rst"],objects:{},objnames:{},objtypes:{},terms:{"case":2,For:2,The:2,accord:2,added:2,addit:2,adjust:0,affix:2,allow:2,also:2,applic:2,appropri:2,attribut:2,begin:2,best:2,both:2,can:2,chosen:2,compat:2,complet:2,compris:2,content:0,control:0,corpu:2,data:0,date:2,deriv:2,develop:2,diachron:2,dimens:2,effici:2,element:2,emph:2,end:2,extract:2,file:2,framework:2,futur:2,gener:0,given:2,guidelin:2,hand:2,have:2,hierarchi:2,histor:2,howev:2,identifi:2,ignor:2,implement:0,includ:2,index:0,inform:2,interact:2,line:2,link:2,list:2,lst:2,markup:2,mean:2,meet:2,meta:2,model:0,modul:[0,2],name:2,need:2,object:2,objecttyp:2,occurr:2,one:2,oper:0,other:2,page:0,phonolog:2,posit:2,potenti:2,predict:2,present:2,principl:0,process:2,product:2,quantif:2,question:2,reason:2,recogn:2,ref:2,regard:2,relev:2,repositori:2,requir:2,research:2,respect:2,result:2,same:2,search:0,solut:2,some:2,specif:2,src:2,standard:2,start:2,structur:2,subsequ:2,syntact:2,tei:2,term:2,thei:2,thereof:2,thi:2,time:2,type:2,use:2,wealth:2,were:2,wherea:2,word:2,wordbegin:2,worddatamodel:2,xml:2},titles:["Welcome to Morphilo\u2019s documentation!","Controller Adjustments","Data Model Implementation"],titleterms:{adjust:1,control:1,data:2,document:0,gener:1,implement:2,indic:0,model:2,morphilo:0,oper:1,principl:1,tabl:0,welcom:0}}) \ No newline at end of file +Search.setIndex({docnames:["index","source/architecture","source/controller","source/datamodel","source/framework","source/view"],envversion:52,filenames:["index.rst","source/architecture.rst","source/controller.rst","source/datamodel.rst","source/framework.rst","source/view.rst"],objects:{},objnames:{},objtypes:{},terms:{"0px":5,"10px":5,"1test":5,"2test":5,"4em":5,"abstract":3,"boolean":2,"case":[1,2,3,5],"catch":2,"class":[2,4,5],"default":[2,5],"enum":2,"final":[2,3,5],"function":[2,3],"import":[1,2,3,4,5],"int":2,"new":2,"null":2,"public":2,"return":2,"short":5,"throw":[2,3],"true":[1,2,3,5],"try":2,"void":2,"while":[1,2],AND:2,And:[1,2],For:[2,3,4,5],That:2,The:[1,2,3,5],Then:[2,5],There:[2,3,4],These:[2,3,4],Using:2,With:2,_morphilo_:5,abbmycorestruktur:4,abbruchbedingung:2,abl:[3,5],about:2,abov:[2,3],accept:2,access:[1,2,5],accessdelet:5,accessedit:5,accord:[2,3],accordingli:2,account:3,acl:5,actual:2,add:2,added:[2,3,4],adding:2,addit:[2,3],addition:3,addon:[2,4],address:2,addtomorphilodb:2,adject:3,adjust:[0,3,4,5],administ:1,administr:[2,5],admit:2,adopt:2,advantag:3,affix:[2,3],affixpo:2,affixstripp:2,affixtyp:2,after:[1,2,5],again:[2,5],agre:2,aim:2,al1:2,al2:2,algorithm:2,all:[1,2,3,4,5],allomorph:2,allow:[1,2,3,5],alon:2,alpha:1,alreadi:2,also:[1,2,3,5],altern:1,although:[2,3],alwai:2,ambigu:3,among:5,amp:5,analys:2,analysi:3,analyz:[2,3],analyzeinfl:2,analyzeinflect:2,analyzelemma:2,analyzepref:2,analyzeprefix:2,analyzeroot:2,analyzesuf:2,analyzesuffix:2,analyzeword:2,ani:[1,2],annot:[1,2,5],annotieren:5,anoth:[2,5],anpasssungen:5,answer:3,anzword:2,apach:[2,5],api:2,appear:[2,5],appli:[2,5],applic:[2,3,4],approach:[1,2,5],appropri:3,approxim:2,arbitrari:2,architect:1,architectur:[1,3,4],argument:2,aria:5,around:2,arrai:2,arraylist:2,asid:3,assert:2,assign:2,assum:[1,2],assumpt:[1,3],ation:2,attach:[3,5],attent:[3,5],attribut:[2,3],auf:3,aur:2,auslesen:2,authen:2,authentif:2,author:2,autom:1,automat:5,auver:2,avail:[1,2,3],avoid:2,awai:2,awkward:2,awver:2,back:[2,5],backtoproject:5,bar:5,base:[1,2,3,5],baseform:3,basi:2,basic:[2,3],becaus:[1,2,3,5],becom:[1,2],been:[2,3],befor:2,beforehand:1,begin:[2,3,4,5],beginnig:2,begintim:2,behind:2,being:2,belong:5,below:[2,5],besid:5,best:3,between:[1,2,3,5],beyond:2,bird:2,bit:2,both:[1,2,3],branch:[1,3],brows:5,browser:5,btn:5,bugfixend:2,bugfixstart:2,build:2,builder:2,button:5,calcul:[1,2],call:[1,2,5],callkeymeth:2,calll:2,can:[1,2,3,4,5],candid:2,cannot:[2,3],caption:[2,3,4,5],care:2,caret:5,carri:[1,2,3,5],caus:[2,3],center:[2,4],certain:5,chang:[2,3,5],changeabl:2,chap:2,chapter:2,check:[2,5],checkand:2,checkpermiss:5,child:5,children:5,choic:3,chosen:3,circumst:5,claim:2,classdiag:2,classid:2,classif:3,classifi:3,clear:[2,5],clearer:1,click:2,client:2,cmp:2,code:[2,5],cog:5,collect:[2,5],com:[2,3],come:2,comfort:3,common:5,compar:[1,2],comparemcr:2,comparemcrobject:2,compareto:2,comparison:[1,2],compat:3,compil:2,complet:[1,2,3,4],complex:2,complextyp:3,complic:2,compon:[1,2,4,5],componentsprotectfootnotemark:4,compound:2,compris:[2,3],con:3,concat:5,concaten:2,concept:[2,3],conceptu:0,concern:2,conclud:2,concret:1,condit:2,configur:[2,4,5],confirm:2,confirm_delet:5,congruenc:1,consequ:3,consid:2,consist:2,construct:[2,3],constructor:2,constructqc:2,contain:[1,2,5],content:[0,2,5],continu:1,control:[0,1,4,5],converg:3,core:2,corner:4,corp1derivid:2,corp2derivid:2,corpdoc:2,corpid:[2,5],corpmeta:[2,3,5],corpo1:2,corpo2:2,corpobj:2,corpora:[1,2,3],corpu:[1,2,3,5],corpusdatamodel:[2,3],corpusdiff:2,corpuslink:[2,3,5],corpuss:2,correct:[1,2,5],correl:2,correspond:[2,3,4,5],could:[1,2,3],count:[1,2,5],counter:2,coupl:5,cours:[1,2],creat:[1,2,5],createdbi:2,createmorphiloobject:2,createxml:2,creator:2,crpid1:2,crpid2:2,crucial:[1,2,3],css:5,current:5,currentus:[2,5],custom:[2,4],cut:2,data:[0,2,4,5],databas:[1,2],datamodel:[2,3,4],datamodelimpl:4,dataset:[1,2],date:[2,3],datefrom:[2,3],datefromcorp:2,datenmodel:4,dateuntil:[2,3],dateuntilcorp:2,deal:2,decid:1,decis:1,def:[2,4,5],defin:[1,2,3,4,5],definit:[2,5],degre:2,delet:[2,3,5],deleteaffix:2,deletedb:5,deliv:[1,2],delword:5,demonstr:[2,5],depend:2,depict:[2,3],depth:2,deriv:[1,2,3,5],derivateact:5,derivcorp:5,derivid:2,derobject:[2,5],derobjecttempl:5,describ:[1,2,3,5],deserv:5,design:[0,2,5],detail:[2,5],detaileddiff:2,determin:[1,2,5],develop:3,deviat:1,diachron:3,diagram:2,dictionari:2,diff:2,diffbegin:2,diffend:2,differ:[1,2,3,5],difflist:2,diffsum:2,dimens:3,direct:[2,3],directli:[1,3],directori:[2,4,5],discuss:[2,5],displai:[2,5],distribut:[1,2],disus:3,div:5,divis:5,doc:3,document:[1,2,3,5],doe:2,domin:3,done:[2,3,4,5],dontknow:3,doubl:2,down:[2,5],drop:5,dropdown:5,dropdownmenu1:5,due:2,each:[2,3,5],earlier:2,easi:3,easili:2,editword:5,effect:2,effici:[2,3],either:2,elem:2,element:[2,3],elig:3,elimin:2,elm:2,els:2,elsewher:3,eman:3,embed:2,embedaffix:2,embedded:2,emph:[1,2,3,4,5],empti:2,enabl:2,enclos:3,encod:[2,3,5],end:[2,3,4,5],endswith:2,endtim:2,engin:[2,3,5],english:[1,2,5],enough:1,enrich:5,ensur:5,ent:2,enter:5,entir:[2,5],entitl:5,entri:[1,2],entrynum:2,enumer:2,enumpref:2,envisu:4,equal:2,equalobject:2,equalocc2:2,equalocc:2,equival:2,err:2,error:[1,3],erzeugen:2,escapechar:[2,3,5],essenc:2,essenti:[4,5],establish:3,estim:1,etc:2,euer:2,european:3,evalu:2,evaluatefirst:2,even:3,event:5,everi:2,exact:[1,2],exactli:[1,2,5],exampl:[1,2,3],except:2,excerpt:2,exchang:[2,3],exclud:5,exist:2,expand:5,explain:[2,4,5],explan:2,explanatori:5,explic:4,explicit:2,explicitli:[2,3],exploit:5,exponenti:2,extend:[2,4],extent:3,extra:[1,2,4],extract:[2,3,5],extrem:2,eye:2,fact:[1,2,3],factori:2,fail:2,fall:2,fals:[2,3],felder:3,few:3,field:[2,3,5],fig:[1,2,4],figur:[1,2,4],file:[2,3,4,5],filenam:[2,5],filepathproc:2,filesaveend:2,filesavestart:2,fill:2,filter:2,find:2,first:[1,2,5],five:2,fix:2,flag:2,flow:1,focu:2,follow:[1,2,3,5],footnot:[2,3,5],footnotetext:4,form:[1,2,5],format:2,former:[2,5],fort:3,four:[2,3],fragment:[2,5],framework:[0,2,3,5],freeli:2,frequenc:[1,2],frequent:2,from:[1,2,3,5],fuer:2,fulfil:2,full:2,fulli:[1,2],further:[1,2],furthermor:[3,5],futur:3,gauss:1,gegeben:2,gener:[0,5],german:5,get:2,getaffixposit:2,getalldiffer:2,getallequalmcrobject:2,getattributevalu:2,getbaseurl:2,getcont:2,getcontentfromfil:2,getcontrolnodedetail:2,getcorp:2,getcorpusmetadata:2,getcurrentsess:2,getderiv:2,getderivatefilepath:2,getequalnumb:2,getequalobjectnumb:2,getfieldvalu:2,getfilenam:2,getid:2,getinst:2,getmaindocnam:2,getmorphem:2,getnamespac:2,getnumberofword:2,getnumfound:2,getoccurrencesfromequaltext:2,getpath:2,getprettyformat:2,getresult:2,getsolrcli:2,getstemnumb:2,getter:2,gettestnodedetail:2,gettext:2,getunknownword:2,getunknowword:2,geturl:2,geturlparamet:2,getuserid:2,getuserinform:2,getvalu:2,getxmlfromobject:2,getxpathloc:2,gist:1,github:3,give:2,given:[1,2,3,5],gleich:2,glyphicon:5,good:5,gov:5,greater:2,group:5,grow:[1,2],guest:5,guidelin:3,had:5,hand:[1,2,3,4,5],handl:[2,5],happen:[2,5],harbor:[2,5],has:[1,2,3,5],hasderiv:3,hash:2,hashmap:2,hauver:2,have:[1,2,3,4,5],head:5,heavili:2,help:1,helpobj:2,henc:2,her:2,here:[1,2,3,4,5],herit:3,hidden:[1,5],hier:5,hierarch:3,hierarchi:[2,3],higher:2,his:2,histor:3,historyd:3,hit:2,horizont:5,houyr:2,hover:2,how:[1,2,4],howev:[1,2,3],href:[2,5],html:[3,5],http:[2,3,4,5],httpsession:5,hundr:2,hypertext:5,i18n:5,idea:2,ideal:3,ident:2,identifi:[2,3,5],ids:[2,5],ifs:5,ifsdirectori:5,ignor:[2,3],illustr:[1,2],imag:5,impact:1,implement:[0,4],impli:[2,3,5],implicitli:2,importantli:2,improv:2,includ:[2,3,5],includegraph:[2,4],increas:2,increment:2,incrocc:2,indent:5,independ:1,index:[0,2],indic:2,indo:3,infl:2,inflect:[2,3],inflectionenum:2,inflenum:2,inform:[1,3,5],ingredi:2,inherit:5,initi:[2,5],inner:2,input:[1,4],inspir:2,instanc:[2,3],instanti:2,instead:1,instruct:2,integ:2,integr:2,intend:2,interact:[2,3,5],interest:[2,3],interfac:[2,4,5],interrupt:1,investig:[2,3],involv:2,ioexcept:2,ion:2,isauthor:2,ischild:3,isempti:2,isequ:2,ispar:3,issu:[3,5],ist:2,item:[1,2],itemlabel:2,iter:2,itm:2,its:[2,3],java:[2,4,5],javacod:5,javascript:5,jdm:2,jdom:2,jdomdoc:2,jdomdochelp:2,jdomobject:2,jdomorphilo:2,job:2,just:[1,2,3],keep:[2,3],kei:[2,5],kept:3,keyboard:5,keyset:2,kind:3,known:3,korpu:5,korpusnam:[2,3],label:[2,3,4,5],labelenumi:2,labelledbi:5,laid:3,landscap:2,languag:[1,2,3,5],larg:[1,2],larger:2,last:[2,3],lastli:5,later:[1,2,3],latter:[2,5],law:2,layer:[3,4],layout:[4,5],lead:3,least:2,left:[2,3,5],leftov:2,leftsov:2,lemma:[2,3,5],lemmaanalyz:2,length:[2,5],less:[2,3],let:2,letter:2,level:[1,2,3],lexic:[1,2,3],like:[1,2],limit:2,line:[2,3,5],linear:2,link:[1,2,3,5],list:[2,3,5],littl:3,loc:5,locat:5,loeschen:5,logic:[2,4,5],longer:2,look:[1,2],loop:[2,5],lower:2,lst:[2,3,5],lstlist:[2,3,5],machin:5,made:[1,2],main:[2,4,5],mainfil:2,mainli:2,major:3,make:[1,2,3,5],manag:[1,2,3],mani:[2,5],manipul:[2,5],manual:[1,2,5],map:2,margin:5,mark:[1,2],markup:3,mask:[2,4,5],master:[1,2,5],match:[1,2,5],materi:1,matter:2,maxoccur:[2,3],mcr:5,mcr_directori:5,mcraccessmanag:5,mcridstr:2,mcrmetadatamanag:2,mcrmetalinkid:5,mcrobj1:2,mcrobj2:2,mcrobj:2,mcrobject:2,mcrobjectid:2,mcrobjekt:2,mcrpath:2,mcrservlet:2,mcrservletjob:2,mcrsessionmgr:2,mcrsolrclientfactori:2,mcrtranslat:5,mcrurn:5,mcrxmlfunction:[2,5],mcrxsl:5,mdm:2,mean:[2,3],measur:2,mechan:[2,5],meet:3,ment:2,mention:[2,3,5],menu:[2,5],menuitem:5,mere:2,messages_d:5,messages_en:5,met:5,meta:[2,3],metadata:[1,2,3,5],method:2,middl:[1,2],might:[3,5],mileston:2,minoccur:3,mix:3,mod:5,mode:[2,5],model:[0,2,4,5],modif:5,modul:[0,3],modular:2,monomorphem:2,more:[2,3,4,5],moreov:2,morphem:[2,3],morphil:1,morphilo:[1,2,3,4,5],morphilo_uml:2,morphilocontain:[2,3,5],morphilostylesheet:5,morphmenu:5,morpholog:2,morphologicalsystem:3,most:[2,3,5],mous:5,multi:3,multilingu:5,multipl:2,must:[2,5],mvc:[3,4,5],mycor:[2,3,4,5],mycore_architectur:4,mycoreobject:[2,5],name:[2,3,5],namespac:2,natur:2,navig:5,necessari:[1,2,3,5],need:[2,3,4,5],neg:3,neither:2,net:5,newli:[1,2],newroot:2,next:[2,5],nextobject:5,nirgend:2,node:[2,3,5],nonamespaceschemaloc:3,nor:2,normal:[1,5],notavail:2,note:[1,2,5],notic:[3,5],notinherit:3,now:[2,3],number:[1,2,3],numberformatexcept:2,nur:2,nw1:5,nw2:5,oar:2,obaer:2,ober:2,obj:2,objactiontempl:5,object:[1,2,3,5],objectact:5,objectid:2,objecttyp:3,objid:[2,5],obligatori:3,obuh:2,obviou:2,occdiff:2,occur:[1,2],occurr:[2,3],oder:2,oed:2,oedfootnot:2,oer:2,ofaer:2,ofer:2,oferr:2,off:2,offer:[2,4],offerr:2,offr:2,ofir:2,ofor:2,ofowr:2,oger:2,oher:2,onc:[2,5],one:[2,3,4,5],ones:2,ongo:1,onli:[1,2,3,5],onward:2,ooer:2,oor:2,oouer:2,open:5,oper:0,oppos:2,optim:1,option:[2,3,5],optional:3,order:2,org:[2,3,5],origin:2,other:[1,2,3,5],otherwis:[1,2,3],ouer:2,ouir:2,our:2,out:[1,2,3,5],outer:2,output:[1,2,4],outputstr:2,outputt:2,ouuer:2,ouur:2,ouver:2,ouyr:2,ova:2,ovah:2,ovar:2,ove:2,over:2,overal:5,overrid:2,overwhelm:3,overwrit:2,overwritten:2,ovir:2,ovr:2,ovuh:2,ovur:2,ovver:2,ovyr:2,ower:2,owir:2,own:[4,5],owr:2,owuer:2,owur:2,owver:2,owwer:2,owyr:2,oxford:2,packag:2,page:[0,2,5],paid:3,par:3,parallel:4,param:5,paramet:[2,5],parentobjid:5,parseint:2,part:[2,3,5],partial:1,pass:2,path:[2,5],pattern:[2,3,4,5],pcs2:2,pcs:2,pdf:3,penn:3,persist:[1,3],perspect:2,pflichtfeld:3,phase:2,phonolog:3,place:[2,4],plain:1,plu:2,png:[2,4],point:[1,2],popul:1,pos:[2,3],posit:[2,3],possibl:[1,2,3],post:2,potenti:[2,3],practic:[4,5],precis:[2,4],predefin:4,predict:3,pref:2,prefcutoff:2,prefenum:2,prefer:2,prefix:[2,3,5],prefixallomorph:2,prefixbaseform:3,prefixenum:2,prefixmorphem:2,prefixnumb:2,prefloop:2,prefputmorph:2,present:[2,3,5],prevent:2,previou:[1,2],previous:[1,2],principl:0,printstacktrac:2,privat:2,probabl:2,problem:[2,3],problemat:3,proc:2,procedur:[2,5],process:[1,2,3,5],processcorpusservlet:[2,5],processor:5,procwd:2,product:[2,3],program:[2,4],progress:1,project:[2,5],prop:2,properti:[3,5],propos:2,protect:2,prototyp:[2,3],provid:[1,2,3],publish:[2,5],pull:5,put:2,putal:2,qry:2,qualiti:[1,2],qualitycontrol:2,quantif:3,queri:2,question:[2,3],rang:2,rather:2,reach:2,read:[2,3,5],reader:5,readi:2,realiz:3,realli:[2,5],reason:[1,2,3],receiv:[1,2,5],recht:2,recogn:[2,3,5],recognit:2,recommend:5,recurs:2,redirect:2,ref:[1,2,3,4,5],refactor:2,reflect:3,regard:3,region:1,regist:[2,5],reject:1,rekurs:2,rel:5,relat:2,releas:3,relev:[2,3,5],reliabl:3,remain:2,remaind:[2,5],remark:3,remov:2,removecont:2,render:[2,5],renewcommand:2,repeat:2,repetit:2,replac:2,repositori:[2,3,5],represent:[2,5],request:2,requir:3,research:[1,3],resolv:[2,5],resourc:[1,5],respect:[1,2,3,5],respond:2,respons:[2,5],rest:2,restart:2,restrict:5,restword:2,result:[1,2,3,5],resultset:2,resum:[1,2],retrievemcrobject:2,reveal:2,revers:2,right:[2,3,4,5],rise:2,role:[2,5],roll:2,root:[2,3,5],rootanalyz:2,roughli:4,row:5,rslt:2,rudimentari:2,run:[2,5],said:3,sake:3,same:[2,3],sampl:[1,2],satisfi:3,save:[1,2,3],saxexcept:2,scale:[2,4],screen:5,search:[0,2,3,4,5],searchabl:2,searchfield:5,sec:[2,5],second:[1,2,3,5],section:[2,3,4,5],see:[1,2,5],seem:3,seen:[2,5],segment:2,select:5,self:5,send:2,sens:[2,3],separ:[3,5],sequenc:3,serv:2,server:1,servflag:2,servic:[2,5],servlet:2,servletsbaseurl:5,servstat:2,set:[1,2],setattribut:2,setfield:2,setformat:2,setignoreattributeord:2,setignorecom:2,setignorediffbetweentextandcdata:2,setignorewhitespac:2,setnormalizewhitespac:2,setocc:2,setqueri:2,setrow:2,settext:2,setxlink:2,setzen:5,sever:2,share:1,she:1,shortcom:2,shorter:2,should:[2,3,4],show:2,shown:[2,3,5],side:[2,5],similar:2,simpl:[1,2,3,5],simplest:2,simpli:2,simplic:3,simplif:2,simplifi:2,sinc:[2,5],sind:2,size:[1,2,3],skeleton_layout_templ:5,slr:2,small:2,snippet:2,softwar:[0,2,3,5],solr:[2,5],solrclient:2,solrdocumentlist:2,solrend:2,solrqueri:2,solrresult:2,solrstart:2,solut:[2,3],solv:2,some:[2,3,4,5],someth:2,somewhat:2,sort:[1,2],sortedbylengthmap:2,sortoutaffix:2,sourc:[2,4,5],space:[2,5],span:5,special:5,specif:[2,3,4,5],specifi:[1,2,4],speech:3,sprach:3,src:[2,3,4,5],stand:2,standard:[1,2,3,4,5],standardfootnot:3,start:[1,2,3,5],startswith:2,state:2,statist:[1,2],stem:[2,3],stemnumb:2,step:2,still:[1,2,5],stop:2,store:5,stream:1,string:[2,3,5],stronger:3,structur:[2,3,4,5],style:[3,5],stylesheet:5,subdirectori:4,subdivid:2,subject:3,subsec:[2,3,4,5],subsect:[3,5],subsequ:3,substanti:2,substitut:1,substr:2,substract:2,subtl:1,subword:3,succe:1,success:2,suf:2,suffic:2,suffix:[2,3,5],suffixallomorph:2,suffixbaseform:3,suffixenum:2,suffixmorphem:2,suffixnumb:2,suggest:[1,2,3],sum:2,superus:5,support:3,suppos:2,sustain:3,syntact:3,syntax:5,system:2,tabindex:5,tabl:1,tag:[1,2,5],tagcorpusservlet:2,taggen:5,tagmanu:2,tagservlet:2,tagset:3,tagurl:2,take:[1,2],taken:2,target:[2,3],task:[2,3,5],technolog:[2,3],tei:[2,3,4,5],teiexamp:3,templat:5,term:3,test:[1,2,5],text:[1,2,3,5],textfil:2,tha:2,than:[2,3],theenumi:2,thei:[1,2,3,4,5],them:[1,2],theoret:[1,3],theori:5,therefor:[2,3,5],thereof:3,thi:[1,2,3,5],thing:5,think:2,third:[2,5],though:2,three:[2,4],through:[1,2,3,5],throughout:2,thu:[1,2,5],time:[2,3],timecorpusbegin:2,timecorpusend:2,timecorrect:2,togeth:[1,2,5],toggl:5,token:2,tomcat:2,tool:1,tostr:2,transfer:2,transform:5,translat:5,treebank:3,treemap:2,truth:2,turn:2,two:[1,2,5],type:[2,3,5],typic:2,ueberschrift:5,ufara:2,ufe:2,ufer:2,ufera:2,uferr:2,uferra:2,ufor:2,ufora:2,ufr:2,ufra:2,ufyrra:2,unbound:3,und:2,under:2,underli:[1,2],understand:[2,5],unequ:2,unfortun:[2,3,5],uniqu:[2,5],unit:[1,2],unknown:2,unlik:2,untag:[1,2,5],until:2,updat:2,updateend:2,updatestart:2,upload:[2,5],upper:[4,5],url:[2,5],urlencod:5,urn:5,use:[2,3,5],used:[1,2,3,5],user:[1,2,3,5],usernam:[2,5],uses:[2,5],using:2,usual:[1,2],utf:[3,5],uuer:2,uuera:2,uvver:2,uvvor:2,valid:[2,5],valu:[1,2,5],variabl:[2,5],variant:2,vereinheitlichung:2,veri:[1,2,3],version:[2,3,5],vfere:2,via:[2,4,5],view:[0,3,4],visibl:2,visual:[1,5],vuer:2,vver:2,wai:2,want:5,war:2,wdtpe:2,wealth:3,web:[2,3,5],webapplicationbaseurl:5,webfrag:[2,5],webinterfac:2,webpag:[2,5],webservic:5,well:[2,3],wenn:2,were:[2,3,5],what:2,when:2,where:2,wherea:[2,3],whether:1,which:[1,2,3,4,5],who:[1,5],whose:2,wirklich:5,within:[1,2,5],without:2,word:[1,2,3,5],wordbegin:3,worddatamodel:[2,3],wordroot:2,wordtoken:2,wordtyp:[2,3],work:[1,2],workaround:2,workload:1,worteben:3,worth:[2,3],worttyp:2,would:2,wrd:2,write:2,writeal:2,writealldata:2,writecont:2,writedb:5,written:[1,2],wrong:2,www:[2,3,4,5],xalan:5,xed:[2,5],xlink:[2,5],xlinknamespac:2,xml:[2,3,4,5],xmldiff:2,xmln:[3,5],xmloutputt:2,xmlschema:3,xmlunit:2,xpath:[2,5],xpathex:2,xpathexpress:2,xpathfactori:2,xpexp:2,xpfac:2,xpfacti:2,xsd:3,xsi:3,xsl:5,xslt:5,yes:1,yet:[1,2,3,5],yfera:2,yfere:2,yferra:2,zero:2,zerobegin:2,zeroend:2,zipf:2,zur:2},titles:["Documentation Morphilo Project","Software Design","Controller Adjustments","Data Model","Framework","View"],titleterms:{adjust:2,conceptu:[2,3,5],control:2,data:3,design:1,document:0,framework:4,gener:2,implement:[2,3,5],indic:0,model:3,morphilo:0,oper:2,principl:2,project:0,softwar:1,tabl:0,view:5,welcom:[]}}) \ No newline at end of file diff --git a/Morphilo_doc/_build/html/source/architecture.html b/Morphilo_doc/_build/html/source/architecture.html new file mode 100644 index 0000000..bb49762 --- /dev/null +++ b/Morphilo_doc/_build/html/source/architecture.html @@ -0,0 +1,147 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Software Design — Morphilo documentation</title> + <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> + <script type="text/javascript" src="../_static/documentation_options.js"></script> + <script type="text/javascript" src="../_static/jquery.js"></script> + <script type="text/javascript" src="../_static/underscore.js"></script> + <script type="text/javascript" src="../_static/doctools.js"></script> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + <link rel="next" title="Framework" href="framework.html" /> + <link rel="prev" title="View" href="view.html" /> + + <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body" role="main"> + + <div class="section" id="software-design"> +<h1>Software Design<a class="headerlink" href="#software-design" title="Permalink to this headline">¶</a></h1> +<img alt="source/architecture.*" src="source/architecture.*" /> +<p>The architecture of a possible <strong>take-and-share</strong>-approach for language +resources is visualized in figure ref{fig:architect}. Because the very gist +of the approach becomes clearer if describing a concrete example, the case of +annotating lexical derivatives of Middle English and a respective database is +given as an illustration. +However, any other tool that helps with manual annotations and manages metadata of a corpus could be +substituted here instead.</p> +<p>After inputting an untagged corpus or plain text, it is determined whether the +input material was annotated previously by a different user. This information is +usually provided by the metadata administered by the annotation tool; in the case at +hand it is called emph{Morphilizer} in figure ref{fig:architect}. An +alternative is a simple table look-up for all occurring words in the datasets Corpus 1 through Corpus n. If contained +completely, the emph{yes}-branch is followed up further – otherwise emph{no} +succeeds. The difference between the two branches is subtle, yet crucial. On +both branches, the annotation tool (here emph{Morphilizer}) is called, which, first, +sorts out all words that are not contained in the master database (here emph{Morphilo-DB}) +and, second, makes reasonable suggestions on an optimal annotation of +the items. In both cases the +annotations are linked to the respective items (e.g. words) in the +text, but they are also persistently saved in an extra dataset, i.e. Corpus 1 +through n, together with all available metadata.</p> +<p>The difference between both information streams is that +in the emph{yes}-branch a comparison between the newly created dataset and +all of the previous datasets of this text is carried out. Within this +unit, all deviations and congruencies are marked and counted. The underlying +assumption is that with a growing number of comparable texts the +correct annotations approach a theoretic true value of a correct annotation +while errors level out provided that the sample size is large enough. How the +distribution of errors and correct annotations exactly looks like and if a +normal distribution can be assumed is still object of the ongoing research, but +independent of the concrete results, the component (called emph{compare +manual annotations} in figure ref{fig:architect}) allows for specifying the +exact form of the sample population. +In fact, it is necessary at that point to define the form of the distribution, +sample size, and the rejection region. The standard setting are a normal +distribution, a rejection region of $alpha = 0.05$ and sample size of $30$ so +that a simple Gauss-Test can be calculated.</p> +<p>Continuing the information flow further, these statistical calculations are +delivered to the quality-control-component. Based on the statistics, the +respective items together with the metadata, frequencies, and, of course, +annotations are written to the master database. All information in the master +database is directly used for automated annotations. Thus it is directly matched +to the input texts or corpora respectively through the emph{Morphilizer}-tool. +The annotation tool decides on the entries looked up in the master which items +are to be manually annotated.</p> +<p>The processes just described are all hidden from the user who has no possibility +to impact the set quality standards but by errors in the annotation process. The +user will only see the number of items of the input text he or she will process manually. The +annotator will also see an estimation of the workload beforehand. On this +number, a decision can be made if to start the annotation at all. It will be +possible to interrupt the annotation work and save progress on the server. And +the user will have access to the annotations made in the respective dataset, +correct them or save them and resume later. It is important to note that the user will receive +the tagged document only after all items are fully annotated. No partially +tagged text can be output.</p> +</div> + + + </div> + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"><div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../index.html">Documentation overview</a><ul> + <li>Previous: <a href="view.html" title="previous chapter">View</a></li> + <li>Next: <a href="framework.html" title="next chapter">Framework</a></li> + </ul></li> +</ul> +</div> + <div role="note" aria-label="source link"> + <h3>This Page</h3> + <ul class="this-page-menu"> + <li><a href="../_sources/source/architecture.rst.txt" + rel="nofollow">Show Source</a></li> + </ul> + </div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2018, Hagen Peukert. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.7.2</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.10</a> + + | + <a href="../_sources/source/architecture.rst.txt" + rel="nofollow">Page source</a> + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/Morphilo_doc/_build/html/source/controller.html b/Morphilo_doc/_build/html/source/controller.html index a1b0ca7..92abe3a 100644 --- a/Morphilo_doc/_build/html/source/controller.html +++ b/Morphilo_doc/_build/html/source/controller.html @@ -15,7 +15,8 @@ <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="index" title="Index" href="../genindex.html" /> <link rel="search" title="Search" href="../search.html" /> - <link rel="prev" title="Data Model Implementation" href="datamodel.html" /> + <link rel="next" title="View" href="view.html" /> + <link rel="prev" title="Data Model" href="datamodel.html" /> <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> @@ -34,6 +35,969 @@ <h1>Controller Adjustments<a class="headerlink" href="#controller-adjustments" title="Permalink to this headline">¶</a></h1> <div class="section" id="general-principle-of-operation"> <h2>General Principle of Operation<a class="headerlink" href="#general-principle-of-operation" title="Permalink to this headline">¶</a></h2> +<p>Figure ref{fig:classDiag} illustrates the dependencies of the five java classes that were integrated to add the morphilo +functionality defined in the default package emph{custom.mycore.addons.morphilo}. The general principle of operation +is the following. The handling of data search, upload, saving, and user +authentification is fully left to the MyCoRe functionality that is completely +implemented. The class emph{ProcessCorpusServlet.java} receives a request from the webinterface to process an uploaded file, +i.e. a simple text corpus, and it checks if any of the words are available in the master database. All words that are not +listed in the master database are written to an extra file. These are the words that have to be manually annotated. At the end, the +servlet sends a response back to the user interface. In case of all words are contained in the master, an xml file is generated from the +master database that includes all annotated words of the original corpus. Usually this will not be the case for larger textfiles. +So if some words are not in the master, the user will get the response to initiate the manual annotation process.</p> +<p>The manual annotation process is processed by the class +emph{{Tag-Corpus-Serv-let-.ja-va}}, which will build a JDOM object for the first word in the extra file. +This is done by creating an object of the emph{JDOMorphilo.java} class. This class, in turn, will use the methods of +emph{AffixStripper.java} that make simple, but reasonable, suggestions on the word structure. This JDOM object is then +given as a response back to the user. It is presented as a form, in which the user can make changes. This is necessary +because the word structure algorithm of emph{AffixStripper.java} errs in some cases. Once the user agrees on the +suggestions or on his or her corrections, the JDOM object is saved as an xml that is only searchable, visible, and +changeable by the authenicated user (and the administrator), another file containing all processed words is created or +updated respectively and the emph{TagCorpusServlet.java} servlet will restart until the last word in the extra list is +processed. This enables the user to stop and resume her or his annotation work at a later point in time. The +emph{TagCorpusServlet} will call methods from emph{ProcessCorpusServlet.java} to adjust the content of the extra +files harboring the untagged words. If this file is empty, and only then, it is replaced by the file comprising all words +from the original text file, both the ones from the master database and the ones that are annotated by the user, +in an annotated xml representation.</p> +<p>Each time emph{ProcessCorpusServlet.java} is instantiated, it also instantiates emph{QualityControl.java}. This class checks if a +new word can be transferred to the master database. The algorithm can be freely adopted to higher or lower quality standards. +In its present configuration, a method tests at a limit of 20 different +registered users agreeing on the annotation of the same word. More specifically, +if 20 JDOM objects are identical except in the attribute field emph{occurrences} in the metadata node, the JDOM object becomes +part of the master. The latter is easily done by changing the attribute emph{creator} from the user name +to emph{<a href="#id1"><span class="problematic" id="id2">``</span></a>administrator’‘} in the service node. This makes the dataset part of the master database. Moreover, the emph{occurrences} +attribute is updated by adding up all occurrences of the word that stem from +different text corpora of the same time range. +begin{landscape}</p> +<blockquote> +<div><dl class="docutils"> +<dt>begin{figure}</dt> +<dd>centering +includegraphics[scale=0.55]{morphilo_uml.png} +caption{Class Diagram Morphilo} +label{fig:classDiag}</dd> +</dl> +<p>end{figure}</p> +</div></blockquote> +<p>end{landscape}</p> +</div> +<div class="section" id="conceptualization"> +<h2>Conceptualization<a class="headerlink" href="#conceptualization" title="Permalink to this headline">¶</a></h2> +<p>The controller component is largely +specified and ready to use in some hundred or so java classes handling the +logic of the search such as indexing, but also dealing with directories and +files as saving, creating, deleting, and updating files. +Moreover, a rudimentary user management comprising different roles and +rights is offered. The basic technology behind the controller’s logic is the +servlet. As such all new code has to be registered as a servlet in the +web-fragment.xml (here the Apache Tomcat container) as listing ref{lst:webfragment} shows.</p> +<p>begin{lstlisting}[language=XML,caption={Servlet Registering in the +web-fragment.xml (excerpt)},label=lst:webfragment,escapechar=|] +<servlet></p> +<blockquote> +<div><servlet-name>ProcessCorpusServlet</servlet-name> +<servlet-class>custom.mycore.addons.morphilo.ProcessCorpusServlet</servlet-class></div></blockquote> +<p></servlet> +<servlet-mapping></p> +<blockquote> +<div><servlet-name>ProcessCorpusServlet</servlet-name> +<url-pattern>/servlets/object/process</url-pattern>|label{ln:process}|</div></blockquote> +<p></servlet-mapping> +<servlet></p> +<blockquote> +<div><servlet-name>TagCorpusServlet</servlet-name> +<servlet-class>custom.mycore.addons.morphilo.TagCorpusServlet</servlet-class></div></blockquote> +<p></servlet> +<servlet-mapping></p> +<blockquote> +<div><servlet-name>TagCorpusServlet</servlet-name> +<url-pattern>/servlets/object/tag</url-pattern>|label{ln:tag}|</div></blockquote> +<p></servlet-mapping> +end{lstlisting}</p> +<p>Now, the logic has to be extended by the specifications analyzed in chapter +ref{chap:concept} on conceptualization. More specifically, some +classes have to be added that take care of analyzing words +(emph{AffixStripper.java, InflectionEnum.java, SuffixEnum.java, +PrefixEnum.java}), extracting the relevant words from the text and checking the +uniqueness of the text (emph{ProcessCorpusServlet.java}), make reasonable +suggestions on the annotation (emph{TagCorpusServlet.java}), build the object +of each annotated word (emph{JDOMorphilo.java}), and check on the quality by applying +statistical models (emph{QualityControl.java}).</p> +</div> +<div class="section" id="implementation"> +<h2>Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline">¶</a></h2> +<p>Having taken a bird’s eye perspective in the previous chapter, it is now time to take a look at the specific implementation at the level +of methods. Starting with the main servlet, emph{ProcessCorpusServlet.java}, the class defines four getter method: +renewcommand{labelenumi}{(theenumi)} +begin{enumerate}</p> +<blockquote> +<div>itemlabel{itm:geturl} public String getURLParameter(MCRServletJob, String) +itemlabel{itm:getcorp} public String getCorpusMetadata(MCRServletJob, String) +itemlabel{itm:getcont} public ArrayList<String> getContentFromFile(MCRServletJob, String) +itemlabel{itm:getderiv} public Path getDerivateFilePath(MCRServletJob, String) +itemlabel{itm:now} public int getNumberOfWords(MCRServletJob job, String)</div></blockquote> +<p>end{enumerate} +Since each servlet in MyCoRe extends the class MCRServlet, it has access to MCRServletJob, from which the http requests and responses +can be used. This is the first argument in the above methods. The second argument of method (ref{itm:geturl}) specifies the name of an url parameter, i.e. +the object id or the id of the derivate. The method returns the value of the given parameter. Typically MyCoRe uses the url to exchange +these ids. The second method provides us with the value of a data field in the xml document. So the string defines the name of an attribute. +emph{getContentFromFile(MCRServletJob, String)} returns the words as a list from a file when given the filename as a string. +The getter listed in ref{itm:getderiv}), returns the Path from the MyCoRe repository when the name of +the file is specified. And finally, method (ref{itm:now}) returns the number of words by simply returning +emph{getContentFromFile(job, fileName).size()}.</p> +<p>There are two methods in every MyCoRe-Servlet that have to be overwritten, +emph{protected void render(MCRServletJob, Exception)}, which redirects the requests as emph{POST} or emph{GET} responds, and +emph{protected void think(MCRServletJob)}, in which the logic is implemented. Since the latter is important to understand the +core idea of the Morphilo algorithm, it is displayed in full length in source code ref{src:think}.</p> +<p>begin{lstlisting}[language=java,caption={The overwritten think method},label=src:think,escapechar=|] +protected void think(MCRServletJob job) throws Exception +{</p> +<blockquote> +<div><p>this.job = job; +String dateFromCorp = getCorpusMetadata(job, “def.datefrom”); +String dateUntilCorp = getCorpusMetadata(job, “def.dateuntil”); +String corpID = getURLParameter(job, “objID”); +String derivID = getURLParameter(job, “id”);</p> +<p>//if NoW is 0, fill with anzWords +MCRObject helpObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(corpID));|label{ln:bugfixstart}| +Document jdomDocHelp = helpObj.createXML(); +XPathFactory xpfacty = XPathFactory.instance(); +XPathExpression<Element> xpExp = xpfacty.compile(“//NoW”, Filters.element()); +Element elem = xpExp.evaluateFirst(jdomDocHelp); +//fixes transferred morphilo data from previous stand alone project +int corpussize = getNumberOfWords(job, “”); +if (Integer.parseInt(elem.getText()) != corpussize) +{</p> +<blockquote> +<div>elem.setText(Integer.toString(corpussize)); +helpObj = new MCRObject(jdomDocHelp); +MCRMetadataManager.update(helpObj);</div></blockquote> +<p>}|label{ln:bugfixend}|</p> +<p>//Check if the uploaded corpus was processed before +SolrClient slr = MCRSolrClientFactory.getSolrClient();|label{ln:solrstart}| +SolrQuery qry = new SolrQuery(); +qry.setFields(“korpusname”, “datefrom”, “dateuntil”, “NoW”, “id”); +qry.setQuery(“datefrom:” + dateFromCorp + ” AND dateuntil:” + dateUntilCorp + ” AND NoW:” + corpussize); +SolrDocumentList rslt = slr.query(qry).getResults();|label{ln:solrresult}|</p> +<p>Boolean incrOcc = true; +// if resultset contains only one, then it must be the newly created corpus +if (slr.query(qry).getResults().getNumFound() > 1) +{</p> +<blockquote> +<div>incrOcc = false;</div></blockquote> +<p>}|label{ln:solrend}|</p> +<p>//match all words in corpus with morphilo (creator=administrator) and save all words that are not in morphilo DB in leftovers +ArrayList<String> leftovers = new ArrayList<String>(); +ArrayList<String> processed = new ArrayList<String>();</p> +<p>leftovers = getUnknownWords(getContentFromFile(job, “”), dateFromCorp, dateUntilCorp, “”, incrOcc, incrOcc, false);|label{ln:callkeymeth}|</p> +<p>//write all words of leftover in file as derivative to respective corpmeta dataset +MCRPath root = MCRPath.getPath(derivID, “/”);|label{ln:filesavestart}| +Path fn = getDerivateFilePath(job, “”).getFileName(); +Path p = root.resolve(“untagged-” + fn); +Files.write(p, leftovers);|label{ln:filesaveend}|</p> +<p>//create a file for all words that were processed +Path procWds = root.resolve(“processed-” + fn); +Files.write(procWds, processed);</p> +</div></blockquote> +<p>} +end{lstlisting} +Using the above mentioned getter methods, the emph{think} method assigns values to the object ID, needed to get the xml document +that contain the corpus metadata, the file ID, and the beginning and starting dates from the corpus to be analyzed. Lines ref{ln:bugfixstart} +through ref{ln:bugfixend} show how to access a mycore object as an xml document, a procedure that will be used in different variants +throughout this implementation. +By means of the object ID, the respective corpus is identified and a JDOM document is constructed, which can then be accessed +by XPath. The XPath factory instances are collections of the xml nodes. In the present case, it is save to assume that only one element +of emph{NoW} is available (see corpus datamodel listing ref{lst:corpusdatamodel} with $maxOccurs=‘1’$). So we do not have to loop through +the collection, but use the first node named emph{NoW}. The if-test checks if the number of words of the uploaded file is the +same as the number written in the document. When the document is initially created by the MyCoRe logic it was configured to be zero. +If unequal, the setText(String) method is used to write the number of words of the corpus to the document.</p> +<p>Lines ref{ln:solrstart}–ref{ln:solrend} reveal the second important ingredient, i.e. controlling the search engine. First, a solr +client and a query are initialized. Then, the output of the result set is defined by giving the fields of interest of the document. +In the case at hand, it is the id, the name of the corpus, the number of words, and the beginnig and ending dates. With emph{setQuery} +it is possible to assign values to some or all of these fields. Finally, emph{getResults()} carries out the search and writes +all hits to a emph{SolrDocumentList} (line ref{ln:solrresult}). The test that follows is really only to set a Boolean +encoding if the number of occurrences of that word in the master should be updated. To avoid multiple counts, +incrementing the word frequency is only done if it is a new corpus.</p> +<p>In line ref{ln:callkeymeth} emph{getUnknownWords(ArrayList, String, String, String, Boolean, Boolean, Boolean)} is called and +returned as a list of words. This method is key and will be discussed in depth below. Finally, lines +ref{ln:filesavestart}–ref{ln:filesaveend} show how to handle file objects in MyCoRe. Using the file ID, the root path and the name +of the first file in that path are identified. Then, a second file starting with <a href="#id3"><span class="problematic" id="id4">``</span></a>untagged’’ is created and all words returned from +the emph{getUnknownWords} is written to that file. By the same token an empty file is created (in the last two lines of the emph{think}-method), +in which all words that are manually annotated will be saved.</p> +<p>In a refactoring phase, the method emph{getUnknownWords(ArrayList, String, String, String, Boolean, Boolean, Boolean)} could be subdivided into +three methods: for each Boolean parameter one. In fact, this method handles more than one task. This is mainly due to multiple code avoidance. +%this is just wrong because no resultset will substantially be more than 10-20 +%In addition, for large text files this method would run into efficiency problems if the master database also reaches the intended size of about +%$100,000$ entries and beyond because +In essence, an outer loop runs through all words of the corpus and an inner loop runs through all hits in the solr result set. Because the result +set is supposed to be small, approximately between $10-20$ items, efficiency +problems are unlikely to cause a problem, although there are some more loops running through collection of about the same sizes. +%As the hits naturally grow larger with an increasing size of the data base, processing time will rise exponentially. +Since each word is identified on the basis of its projected word type, the word form, and the time range it falls into, it is these variables that +have to be checked for existence in the documents. If not in the xml documents, +emph{null} is returned and needs to be corrected. Moreover, user authentification must be considered. There are three different XPaths that are relevant. +begin{itemize}</p> +<blockquote> +<div>item[-] emph{//service/servflags/servflag[@type=’createdby’]} to test for the correct user +item[-] emph{//morphiloContainer/morphilo} to create the annotated document +item[-] emph{//morphiloContainer/morphilo/w} to set occurrences or add a link</div></blockquote> +<p>end{itemize}</p> +<p>As an illustration of the core functioning of this method, listing ref{src:getUnknowWords} is given. +begin{lstlisting}[language=java,caption={Mode of Operation of getUnknownWords Method},label=src:getUnknowWords,escapechar=|] +public ArrayList<String> getUnknownWords(</p> +<blockquote> +<div><p>ArrayList<String> corpus, +String timeCorpusBegin, +String timeCorpusEnd, +String wdtpe, +Boolean setOcc, +Boolean setXlink, +Boolean writeAllData) throws Exception +{</p> +<blockquote> +<div><p>String currentUser = MCRSessionMgr.getCurrentSession().getUserInformation().getUserID(); +ArrayList lo = new ArrayList();</p> +<p>for (int i = 0; i < corpus.size(); i++) +{</p> +<blockquote> +<div><p>SolrClient solrClient = MCRSolrClientFactory.getSolrClient(); +SolrQuery query = new SolrQuery(); +query.setFields(“w”,”occurrence”,”begin”,”end”, “id”, “wordtype”); +query.setQuery(corpus.get(i)); +query.setRows(50); //more than 50 items are extremely unlikely +SolrDocumentList results = solrClient.query(query).getResults(); +Boolean available = false; +for (int entryNum = 0; entryNum < results.size(); entryNum++) +{</p> +<blockquote> +<div>… +// update in MCRMetaDataManager +String mcrIDString = results.get(entryNum).getFieldValue(“id”).toString(); +//MCRObjekt auslesen und JDOM-Document erzeugen: +MCRObject mcrObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(mcrIDString)); +Document jdomDoc = mcrObj.createXML(); +… +//check and correction for word type +… +//checkand correction time: timeCorrect +… +//check if user correct: isAuthorized</div></blockquote> +<p>… +XPathExpression<Element> xp = xpfac.compile(“//morphiloContainer/morphilo/w”, Filters.element()); +//Iterates w-elements and increments occurrence attribute if setOcc is true +for (Element e : xp.evaluate(jdomDoc)) +{</p> +<blockquote> +<div><dl class="docutils"> +<dt>//wenn Rechte da sind und Worttyp nirgends gegeben oder gleich ist</dt> +<dd><blockquote class="first"> +<div><dl class="docutils"> +<dt>if (isAuthorized && timeCorrect</dt> +<dd>&& ((e.getAttributeValue(“wordtype”) == null && wdtpe.equals(“”)) +|| e.getAttributeValue(“wordtype”).equals(wordtype))) // nur zur Vereinheitlichung</dd> +</dl> +</div></blockquote> +<dl class="last docutils"> +<dt>{</dt> +<dd><blockquote class="first"> +<div>int oc = -1; +available = true;|label{ln:available}|</div></blockquote> +<dl class="last docutils"> +<dt>try</dt> +<dd><blockquote class="first"> +<div><dl class="docutils"> +<dt>{</dt> +<dd>//adjust occurrence Attribut +if (setOcc)</dd> +</dl> +</div></blockquote> +<dl class="last docutils"> +<dt>{</dt> +<dd><dl class="first last docutils"> +<dt>oc = Integer.parseInt(e.getAttributeValue(“occurrence”));</dt> +<dd><blockquote class="first"> +<div>e.setAttribute(“occurrence”, Integer.toString(oc + 1));</div></blockquote> +<p class="last">}</p> +</dd> +</dl> +</dd> +<dt>//write morphilo-ObjectID in xml of corpmeta</dt> +<dd><blockquote class="first"> +<div><blockquote> +<div><blockquote> +<div><p>if (setXlink) +{</p> +<blockquote> +<div>Namespace xlinkNamespace = Namespace.getNamespace(“xlink”, “<a class="reference external" href="http://www.w3.org/1999/xlink">http://www.w3.org/1999/xlink</a>”);|label{ln:namespace}| +MCRObject corpObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(getURLParameter(job, “objID”))); +Document corpDoc = corpObj.createXML(); +XPathExpression<Element> xpathEx = xpfac.compile(“//corpuslink”, Filters.element()); +Element elm = xpathEx.evaluateFirst(corpDoc); +elm.setAttribute(“href” , mcrIDString, xlinkNamespace);</div></blockquote> +<p>} +mcrObj = new MCRObject(jdomDoc);|label{ln:updatestart}| +MCRMetadataManager.update(mcrObj); +QualityControl qc = new QualityControl(mcrObj);|label{ln:updateend}|</p> +</div></blockquote> +<p>} +catch(NumberFormatException except) +{</p> +<blockquote> +<div>// ignore</div></blockquote> +<p>}</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +<p class="last">}</p> +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +<p>if (!available) // if not available in datasets under the given conditions <a href="#id16"><span class="problematic" id="id17">|\label{ln:notavailable}|</span></a> +{</p> +<blockquote> +<div>lo.add(corpus.get(i));</div></blockquote> +<p>}</p> +</div></blockquote> +<p>} +return lo;</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +</div></blockquote> +<p>end{lstlisting} +As can be seen from the functionality of listing ref{src:getUnknowWords}, getting the unknown words of a corpus, is rather a side effect for the equally named method. +More precisely, a Boolean (line ref{ln:available}) is set when the document is manipulated otherwise because it is clear that the word must exist then. +If the Boolean remains false (line ref{ln:notavailable}), the word is put on the list of words that have to be annotated manually. As already explained above, the +first loop runs through all words (corpus) and the following lines a solr result set is created. This set is also looped through and it is checked if the time range, +the word type and the user are authorized. In the remainder, the occurrence attribute of the morphilo document can be incremented (setOcc is true) or/and the word is linked to the +corpus meta data (setXlink is true). While all code lines are equivalent with +what was explained in listing ref{src:think}, it suffices to focus on an +additional name space, i.e. +<a href="#id5"><span class="problematic" id="id6">``</span></a>xlink’’ has to be defined (line ref{ln:namespace}). Once the linking of word +and corpus is set, the entire MyCoRe object has to be updated. This is done by the functionality of the framework (lines ref{ln:updatestart}–ref{ln:updateend}). +At the end, an instance of emph{QualityControl} is created.</p> +<p>%QualityControl +The class emph{QualityControl} is instantiated with a constructor +depicted in listing ref{src:constructQC}. +begin{lstlisting}[language=java,caption={Constructor of QualityControl.java},label=src:constructQC,escapechar=|] +private MCRObject mycoreObject; +/* Constructor calls method to carry out quality control, i.e. if at least 20</p> +<blockquote> +<div><ul class="simple"> +<li>different users agree 100% on the segments of the word under investigation</li> +</ul> +<p><a href="#id7"><span class="problematic" id="id8">*</span></a>/</p> +</div></blockquote> +<p>public QualityControl(MCRObject mycoreObject) throws Exception +{</p> +<blockquote> +<div><p>this.mycoreObject = mycoreObject; +if (getEqualObjectNumber() > 20) +{</p> +<blockquote> +<div>addToMorphiloDB();</div></blockquote> +<p>}</p> +</div></blockquote> +<p>} +end{lstlisting} +The constructor takes an MyCoRe object, a potential word candidate for the +master data base, which is assigned to a private class variable because the +object is used though not changed by some other java methods. +More importantly, there are two more methods: emph{getEqualNumber()} and +emph{addToMorphiloDB()}. While the former initiates a process of counting and +comparing objects, the latter is concerned with calculating the correct number +of occurrences from different, but not the same texts, and generating a MyCoRe object with the same content but with two different flags in the emph{//service/servflags/servflag}-node, i.e. emph{createdby=’administrator’} and emph{state=’published’}. +And of course, the emph{occurrence} attribute is set to the newly calculated value. The logic corresponds exactly to what was explained in +listing ref{src:think} and will not be repeated here. The only difference are the paths compiled by the XPathFactory. They are +begin{itemize}</p> +<blockquote> +<div>item[-] emph{//service/servflags/servflag[@type=’createdby’]} and +item[-] emph{//service/servstates/servstate[@classid=’state’]}.</div></blockquote> +<p>end{itemize} +It is more instructive to document how the number of occurrences is calculated. There are two steps involved. First, a list with all mycore objects that are +equal to the object which the class is instantiated with (<a href="#id9"><span class="problematic" id="id10">``</span></a>mycoreObject’’ in listing ref{src:constructQC}) is created. This list is looped and all occurrence +attributes are summed up. Second, all occurrences from equal texts are substracted. Equal texts are identified on the basis of its meta data and its derivate. +There are some obvious shortcomings of this approach, which will be discussed in chapter ref{chap:results}, section ref{sec:improv}. Here, suffice it to +understand the mode of operation. Listing ref{src:equalOcc} shows a possible solution. +begin{lstlisting}[language=java,caption={Occurrence Extraction from Equal Texts (1)},label=src:equalOcc,escapechar=|] +/* returns number of Occurrences if Objects are equal, zero otherwise</p> +<blockquote> +<div><a href="#id11"><span class="problematic" id="id12">*</span></a>/</div></blockquote> +<p>private int getOccurrencesFromEqualTexts(MCRObject mcrobj1, MCRObject mcrobj2) throws SAXException, IOException +{</p> +<blockquote> +<div><p>int occurrences = 1; +//extract corpmeta ObjectIDs from morphilo-Objects +String crpID1 = getAttributeValue(“//corpuslink”, “href”, mcrobj1); +String crpID2 = getAttributeValue(“//corpuslink”, “href”, mcrobj2); +//get these two corpmeta Objects +MCRObject corpo1 = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(crpID1)); +MCRObject corpo2 = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(crpID2)); +//are the texts equal? get list of ‘processed-words’ derivate +String corp1DerivID = getAttributeValue(“//structure/derobjects/derobject”, “href”, corpo1); +String corp2DerivID = getAttributeValue(“//structure/derobjects/derobject”, “href”, corpo2);</p> +<p>ArrayList result = new ArrayList(getContentFromFile(corp1DerivID, “”));|label{ln:writeContent}| +result.remove(getContentFromFile(corp2DerivID, “”));|label{ln:removeContent}| +if (result.size() == 0) // the texts are equal +{</p> +<blockquote> +<div>// extract occurrences of one the objects +occurrences = Integer.parseInt(getAttributeValue(“//morphiloContainer/morphilo/w”, “occurrence”, mcrobj1));</div></blockquote> +<p>} +else +{</p> +<blockquote> +<div>occurrences = 0; //project metadata happened to be the same, but texts are different</div></blockquote> +<p>} +return occurrences;</p> +</div></blockquote> +<p>} +end{lstlisting} +In this implementation, the ids from the emph{corpmeta} data model are accessed via the xlink attribute in the morphilo documents. +The method emph{getAttributeValue(String, String, MCRObject)} does exactly the same as demonstrated earlier (see from line ref{ln:namespace} +on in listing ref{src:getUnknowWords}). The underlying logic is that the texts are equal if exactly the same number of words were uploaded. +So all words from one file are written to a list (line ref{ln:writeContent}) and words from the other file are removed from the +very same list (line ref{ln:removeContent}). If this list is empty, then the exact same number of words must have been in both files and the occurrences +are adjusted accordingly. Since this method is called from another private method that only contains a loop through all equal objects, one gets +the occurrences from all equal texts. For reasons of confirmability, the looping method is also given: +begin{lstlisting}[language=java,caption={Occurrence Extraction from Equal Texts (2)},label=src:equalOcc2,escapechar=|] +private int getOccurrencesFromEqualTexts() throws Exception +{</p> +<blockquote> +<div><p>ArrayList<MCRObject> equalObjects = new ArrayList<MCRObject>(); +equalObjects = getAllEqualMCRObjects(); +int occurrences = 0; +for (MCRObject obj : equalObjects) +{</p> +<blockquote> +<div>occurrences = occurrences + getOccurrencesFromEqualTexts(mycoreObject, obj);</div></blockquote> +<p>} +return occurrences;</p> +</div></blockquote> +<p>} +end{lstlisting}</p> +<p>Now, the constructor in listing ref{src:constructQC} reveals another method that rolls out an equally complex concatenation of procedures. +As implied above, emph{getEqualObjectNumber()} returns the number of equally annotated words. It does this by falling back to another +method from which the size of the returned list is calculated (emph{getAllEqualMCRObjects().size()}). Hence, we should care about +emph{getAllEqualMCRObjects()}. This method really has the same design as emph{int getOccurrencesFromEqualTexts()} in listing ref{src:equalOcc2}. +The difference is that another method (emph{Boolean compareMCRObjects(MCRObject, MCRObject, String)}) is used within the loop and +that all equal objects are put into the list of MyCoRe objects that are returned. If this list comprises more than 20 +entries,footnote{This number is somewhat arbitrary. It is inspired by the sample size n in t-distributed data.} the respective document +will be integrated in the master data base by the process described above. +The comparator logic is shown in listing ref{src:compareMCR}. +begin{lstlisting}[language=java,caption={Comparison of MyCoRe objects},label=src:compareMCR,escapechar=|] +private Boolean compareMCRObjects(MCRObject mcrobj1, MCRObject mcrobj2, String xpath) throws SAXException, IOException +{</p> +<blockquote> +<div><p>Boolean isEqual = false; +Boolean beginTime = false; +Boolean endTime = false; +Boolean occDiff = false; +Boolean corpusDiff = false;</p> +<p>String source = getXMLFromObject(mcrobj1, xpath); +String target = getXMLFromObject(mcrobj2, xpath);</p> +<p>XMLUnit.setIgnoreAttributeOrder(true); +XMLUnit.setIgnoreComments(true); +XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true); +XMLUnit.setIgnoreWhitespace(true); +XMLUnit.setNormalizeWhitespace(true);</p> +<p>//differences in occurrences, end, begin should be ignored +try +{</p> +<blockquote> +<div><p>Diff xmlDiff = new Diff(source, target); +DetailedDiff dd = new DetailedDiff(xmlDiff); +//counters for differences +int i = 0; +int j = 0; +int k = 0; +int l = 0; +// list containing all differences +List differences = dd.getAllDifferences();|label{ln:difflist}| +for (Object object : differences) +{</p> +<blockquote> +<div><p>Difference difference = (Difference) object; +<a class="reference external" href="mailto://%40begin">//<span>@</span>begin</a>,@end,… node is not in the difference list if the count is 0 +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@begin”)) i++;|label{ln:diffbegin}| +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@end”)) j++; +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@occurrence”)) k++; +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@corpus”)) l++;|label{ln:diffend}| +//@begin and @end have different values: they must be checked if they fall right in the allowed time range +if ( difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation())</p> +<blockquote> +<div>&& difference.getControlNodeDetail().getXpathLocation().endsWith(“@begin”) +&& (Integer.parseInt(difference.getControlNodeDetail().getValue()) < Integer.parseInt(difference.getTestNodeDetail().getValue())) )</div></blockquote> +<dl class="docutils"> +<dt>{</dt> +<dd>beginTime = true;</dd> +</dl> +<p>} +if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation())</p> +<blockquote> +<div>&& difference.getControlNodeDetail().getXpathLocation().endsWith(“@end”) +&& (Integer.parseInt(difference.getControlNodeDetail().getValue()) > Integer.parseInt(difference.getTestNodeDetail().getValue())) )</div></blockquote> +<dl class="docutils"> +<dt>{</dt> +<dd>endTime = true;</dd> +</dl> +<p>} +//attribute values of @occurrence and @corpus are ignored if they are different +if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation())</p> +<blockquote> +<div>&& difference.getControlNodeDetail().getXpathLocation().endsWith(“@occurrence”))</div></blockquote> +<dl class="docutils"> +<dt>{</dt> +<dd>occDiff = true;</dd> +</dl> +<p>} +if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation())</p> +<blockquote> +<div>&& difference.getControlNodeDetail().getXpathLocation().endsWith(“@corpus”))</div></blockquote> +<dl class="docutils"> +<dt>{</dt> +<dd>corpusDiff = true;</dd> +</dl> +<p>}</p> +</div></blockquote> +<p>} +//if any of @begin, @end … is identical set Boolean to true +if (i == 0) beginTime = true;|label{ln:zerobegin}| +if (j == 0) endTime = true; +if (k == 0) occDiff = true; +if (l == 0) corpusDiff = true;|label{ln:zeroend}| +//if the size of differences is greater than the number of changes admitted in @begin, @end … something else must be different +if (beginTime && endTime && occDiff && corpusDiff && (i + j + k + l) == dd.getAllDifferences().size()) isEqual = true;|label{ln:diffsum}| +} +catch (SAXException e) +{</p> +<blockquote> +<div>e.printStackTrace();</div></blockquote> +<p>} +catch (IOException e) +{</p> +<blockquote> +<div>e.printStackTrace();</div></blockquote> +<p>}</p> +</div></blockquote> +<p>return isEqual;</p> +</div></blockquote> +<p>} +end{lstlisting} +In this method, XMLUnit is heavily used to make all necessary node comparisons. The matter becomes more complicated, however, if some attributes +are not only ignored, but evaluated according to a given definition as it is the case for the time range. If the evaluator and builder classes are +not to be overwritten entirely because needed for evaluating other nodes of the +xml document, the above solution appears a bit awkward. So there is potential for improvement before the production version is to be programmed.</p> +<p>XMLUnit provides us with a +list of the differences of the two documents (see line ref{ln:difflist}). There are four differences allowed, that is, the attributes emph{occurrence}, +emph{corpus}, emph{begin}, and emph{end}. For each of them a Boolean variable is set. Because any of the attributes could also be equal to the master +document and the difference list only contains the actual differences, one has to find a way to define both, equal and different, for the attributes. +This could be done by ignoring these nodes. Yet, this would not include testing if the beginning and ending dates fall into the range of the master +document. Therefore the attributes are counted as lines ref{ln:diffbegin} through ref{ln:diffend} reveal. If any two documents +differ in some of the four attributes just specified, then the sum of the counters (line ref{ln:diffsum}) should not be greater than the collected differences +by XMLUnit. The rest of the if-tests assign truth values to the respective +Booleans. It is probably worth mentioning that if all counters are zero (lines +ref{ln:zerobegin}-ref{ln:zeroend}) the attributes and values are identical and hence the Boolean has to be set explicitly. Otherwise the test in line ref{ln:diffsum} would fail.</p> +<p>%TagCorpusServlet +Once quality control (explained in detail further down) has been passed, it is +the user’s turn to interact further. By clicking on the option emph{Manual tagging}, the emph{TagCorpusServlet} will be callled. This servlet instantiates +emph{ProcessCorpusServlet} to get access to the emph{getUnknownWords}-method, which delivers the words still to be +processed and which overwrites the content of the file starting with emph{untagged}. For the next word in emph{leftovers} a new MyCoRe object is created +using the JDOM API and added to the file beginning with emph{processed}. In line ref{ln:tagmanu} of listing ref{src:tagservlet}, the previously defined +entry mask is called, with which the proposed word structure could be confirmed or changed. How the word structure is determined will be shown later in +the text. +begin{lstlisting}[language=java,caption={Manual Tagging Procedure},label=src:tagservlet,escapechar=|] +… +if (!leftovers.isEmpty()) +{</p> +<blockquote> +<div><p>ArrayList<String> processed = new ArrayList<String>(); +//processed.add(leftovers.get(0)); +JDOMorphilo jdm = new JDOMorphilo(); +MCRObject obj = jdm.createMorphiloObject(job, leftovers.get(0));|label{ln:jdomobject}| +//write word to be annotated in process list and save it +Path filePathProc = pcs.getDerivateFilePath(job, “processed”).getFileName(); +Path proc = root.resolve(filePathProc); +processed = pcs.getContentFromFile(job, “processed”); +processed.add(leftovers.get(0)); +Files.write(proc, processed);</p> +<p>//call entry mask for next word +tagUrl = prop.getBaseURL() + “content/publish/morphilo.xed?id=” + obj.getId();|label{ln:tagmanu}|</p> +</div></blockquote> +<p>} +else +{</p> +<blockquote> +<div><p>//initiate process to give a complete tagged file of the original corpus +//if untagged-file is empty, match original file with morphilo +//creator=administrator OR creator=username and write matches in a new file +ArrayList<String> complete = new ArrayList<String>(); +ProcessCorpusServlet pcs2 = new ProcessCorpusServlet(); +complete = pcs2.getUnknownWords(</p> +<blockquote> +<div>pcs2.getContentFromFile(job, “”), //main corpus file +pcs2.getCorpusMetadata(job, “def.datefrom”), +pcs2.getCorpusMetadata(job, “def.dateuntil”), +“”, //wordtype +false, +false, +true);</div></blockquote> +<p>Files.delete(p); +MCRXMLFunctions mdm = new MCRXMLFunctions(); +String mainFile = mdm.getMainDocName(derivID); +Path newRoot = root.resolve(“tagged-” + mainFile); +Files.write(newRoot, complete);</p> +<p>//return to Menu page +tagUrl = prop.getBaseURL() + “receive/” + corpID;</p> +</div></blockquote> +<p>} +end{lstlisting} +At the point where no more items are in emph{leftsovers} the emph{getUnknownWords}-method is called whereas the last Boolean parameter +is set true. This indicates that the array list containing all available and relevant data to the respective user is returned as seen in +the code snippet in listing ref{src:writeAll}. +begin{lstlisting}[language=java,caption={Code snippet to deliver all data to the user},label=src:writeAll,escapechar=|] +… +// all data is written to lo in TEI +if (writeAllData && isAuthorized && timeCorrect) +{</p> +<blockquote> +<div><p>XPathExpression<Element> xpath = xpfac.compile(“//morphiloContainer/morphilo”, Filters.element()); +for (Element e : xpath.evaluate(jdomDoc)) +{</p> +<blockquote> +<div>XMLOutputter outputter = new XMLOutputter(); +outputter.setFormat(Format.getPrettyFormat()); +lo.add(outputter.outputString(e.getContent()));</div></blockquote> +<p>}</p> +</div></blockquote> +<div class="section" id="id13"> +<h3>}<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3> +<p>end{lstlisting} +The complete list (emph{lo}) is written to yet a third file starting with emph{tagged} and finally returned to the main project webpage.</p> +<p>%JDOMorphilo +The interesting question is now where does the word structure come from, which is filled in the entry mask as asserted above. +In listing ref{src:tagservlet} line ref{ln:jdomobject}, one can see that a JDOM object is created and the method +emph{createMorphiloObject(MCRServletJob, String)} is called. The string parameter is the word that needs to be analyzed. +Most of the method is a mere application of the JDOM API given the data model in chapter ref{chap:concept} section +ref{subsec:datamodel} and listing ref{lst:worddatamodel}. That means namespaces, elements and their attributes are defined in the correct +order and hierarchy.</p> +<p>To fill the elements and attributes with text, i.e. prefixes, suffixes, stems, etc., a Hashmap – containing the morpheme as +key and its position as value – are created that are filled with the results from an AffixStripper instantiation. Depending on how many prefixes +or suffixes respectively are put in the hashmap, the same number of xml elements are created. As a final step, a valid MyCoRe id is generated using +the existing MyCoRe functionality, the object is created and returned to the TagCorpusServlet.</p> +<p>%AffixStripper explanation +Last, the analyses of the word structure will be considered. It is implemented +in the emph{AffixStripper.java} file. +All lexical affix morphemes and their allomorphs as well as the inflections were extracted from the +OEDfootnote{Oxford English Dictionary <a class="reference external" href="http://www.oed.com/">http://www.oed.com/</a>} and saved as enumerated lists (see the example in listing ref{src:enumPref}). +The allomorphic items of these lists are mapped successively to the beginning in the case of prefixes +(see listing ref{src:analyzePref}, line ref{ln:prefLoop}) or to the end of words in the case of suffixes +(see listing ref{src:analyzeSuf}). Since each +morphemic variant maps to its morpheme right away, it makes sense to use the morpheme and so +implicitly keep the relation to its allomorph.</p> +<p>begin{lstlisting}[language=java,caption={Enumeration Example for the Prefix “over”},label=src:enumPref,escapechar=|] +package custom.mycore.addons.morphilo;</p> +<p>public enum PrefixEnum { +…</p> +<blockquote> +<div>over(“over”), ufer(“over”), ufor(“over”), uferr(“over”), uvver(“over”), obaer(“over”), ober(“over)”), ofaer(“over”), +ofere(“over”), ofir(“over”), ofor(“over”), ofer(“over”), ouer(“over”),oferr(“over”), offerr(“over”), offr(“over”), aure(“over”), +war(“over”), euer(“over”), oferre(“over”), oouer(“over”), oger(“over”), ouere(“over”), ouir(“over”), ouire(“over”), +ouur(“over”), ouver(“over”), ouyr(“over”), ovar(“over”), overe(“over”), ovre(“over”),ovur(“over”), owuere(“over”), owver(“over”), +houyr(“over”), ouyre(“over”), ovir(“over”), ovyr(“over”), hover(“over”), auver(“over”), awver(“over”), ovver(“over”), +hauver(“over”), ova(“over”), ove(“over”), obuh(“over”), ovah(“over”), ovuh(“over”), ofowr(“over”), ouuer(“over”), oure(“over”), +owere(“over”), owr(“over”), owre(“over”), owur(“over”), owyr(“over”), our(“over”), ower(“over”), oher(“over”), +ooer(“over”), oor(“over”), owwer(“over”), ovr(“over”), owir(“over”), oar(“over”), aur(“over”), oer(“over”), ufara(“over”), +ufera(“over”), ufere(“over”), uferra(“over”), ufora(“over”), ufore(“over”), ufra(“over”), ufre(“over”), ufyrra(“over”), +yfera(“over”), yfere(“over”), yferra(“over”), uuera(“over”), ufe(“over”), uferre(“over”), uuer(“over”), uuere(“over”), +vfere(“over”), vuer(“over”), vuere(“over”), vver(“over”), uvvor(“over”) …</div></blockquote> +<dl class="docutils"> +<dt>…chap:results</dt> +<dd><p class="first">private String morpheme; +//constructor +PrefixEnum(String morpheme) +{</p> +<blockquote> +<div>this.morpheme = morpheme;</div></blockquote> +<p>} +//getter Method</p> +<p>public String getMorpheme() +{</p> +<blockquote> +<div>return this.morpheme;</div></blockquote> +<p class="last">}</p> +</dd> +</dl> +<p>} +end{lstlisting} +As can be seen in line ref{ln:prefPutMorph} in listing ref{src:analyzePref}, the morpheme is saved to a hash map together with its position, i.e. the size of the +map plus one at the time being. In line ref{ln:prefCutoff} the emph{analyzePrefix} method is recursively called until no more matches can be made.</p> +<p>begin{lstlisting}[language=java,caption={Method to recognize prefixes},label=src:analyzePref,escapechar=|] +private Map<String, Integer> prefixMorpheme = new HashMap<String,Integer>(); +… +private void analyzePrefix(String restword) +{</p> +<blockquote> +<div><p>if (!restword.isEmpty()) //Abbruchbedingung fuer Rekursion +{</p> +<blockquote> +<div><p>for (PrefixEnum prefEnum : PrefixEnum.values())|label{ln:prefLoop}| +{</p> +<blockquote> +<div><p>String s = prefEnum.toString(); +if (restword.startsWith(s)) +{</p> +<blockquote> +<div>prefixMorpheme.put(s, prefixMorpheme.size() + 1);|label{ln:prefPutMorph}| +//cut off the prefix that is added to the list +analyzePrefix(restword.substring(s.length()));|label{ln:prefCutoff}|</div></blockquote> +<p>} +else +{</p> +<blockquote> +<div>analyzePrefix(“”);</div></blockquote> +<p>}</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +<p>} +end{lstlisting}</p> +<p>The recognition of suffixes differs only in the cut-off direction since suffixes occur at the end of a word. +Hence, line ref{ln:prefCutoff} in listing ref{src:analyzePref} reads in the case of suffixes.</p> +<p>begin{lstlisting}[language=java,caption={Cut-off mechanism for suffixes},label=src:analyzeSuf,escapechar=|] +analyzeSuffix(restword.substring(0, restword.length() - s.length())); +end{lstlisting}</p> +<p>It is important to note that inflections are suffixes (in the given model case of Middle English morphology) that usually occur at the very +end of a word, i.e. after all lexical suffixes, only once. It follows that inflections +have to be recognized at first without any repetition. So the procedure for inflections can be simplified +to a substantial degree as listing ref{src:analyzeInfl} shows.</p> +<p>begin{lstlisting}[language=java,caption={Method to recognize inflections},label=src:analyzeInfl,escapechar=|] +private String analyzeInflection(String wrd) +{</p> +<blockquote> +<div><p>String infl = “”; +for (InflectionEnum inflEnum : InflectionEnum.values()) +{</p> +<blockquote> +<div><p>if (wrd.endsWith(inflEnum.toString())) +{</p> +<blockquote> +<div>infl = inflEnum.toString();</div></blockquote> +<p>}</p> +</div></blockquote> +<p>} +return infl;</p> +</div></blockquote> +<p>} +end{lstlisting}</p> +<p>Unfortunately the embeddedness problem prevents a very simple algorithm. Embeddedness occurs when a lexical item +is a substring of another lexical item. To illustrate, the suffix emph{ion} is also contained in the suffix emph{ation}, as is +emph{ent} in emph{ment}, and so on. The embeddedness problem cannot be solved completely on the basis of linear modelling, but +for a large part of embedded items one can work around it using implicitly Zipf’s law, i.e. the correlation between frequency +and length of lexical items. The longer a word becomes, the less frequent it will occur. The simplest logic out of it is to assume +that longer suffixes (measured in letters) are preferred over shorter suffixes because it is more likely tha the longer the suffix string becomes, +the more likely it is one (as opposed to several) suffix unit(s). This is done in listing ref{src:embedAffix}, whereas +the inner class emph{sortedByLengthMap} returns a list sorted by length and the loop from line ref{ln:deleteAffix} onwards deletes +the respective substrings.</p> +<p>begin{lstlisting}[language=java,caption={Method to workaround embeddedness},label=src:embedAffix,escapechar=|] +private Map<String, Integer> sortOutAffixes(Map<String, Integer> affix) +{</p> +<blockquote> +<div><dl class="docutils"> +<dt>Map<String,Integer> sortedByLengthMap = new TreeMap<String, Integer>(new Comparator<String>()</dt> +<dd><dl class="first docutils"> +<dt>{</dt> +<dd><p class="first">@Override +public int compare(String s1, String s2) +{</p> +<blockquote> +<div>int cmp = Integer.compare(s1.length(), s2.length()); +return cmp != 0 ? cmp : s1.compareTo(s2);</div></blockquote> +<p class="last">}</p> +</dd> +</dl> +<p class="last">}</p> +</dd> +</dl> +<p>); +sortedByLengthMap.putAll(affix); +ArrayList<String> al1 = new ArrayList<String>(sortedByLengthMap.keySet()); +ArrayList<String> al2 = al1; +Collections.reverse(al2); +for (String s2 : al1)|label{ln:deleteAffix}| +{</p> +<blockquote> +<div><dl class="docutils"> +<dt>for (String s1 <span class="classifier-delimiter">:</span> <span class="classifier">al2)</span></dt> +<dd><p class="first">if (s1.contains(s2) && s1.length() > s2.length()) +{</p> +<blockquote> +<div>affix.remove(s2);</div></blockquote> +<p class="last">}</p> +</dd> +</dl> +<p>}</p> +</div></blockquote> +<p>return affix;</p> +</div></blockquote> +<p>} +end{lstlisting}</p> +<p>Finally, the position of the affix has to be calculated because the hashmap in line ref{ln:prefPutMorph} in +listing ref{src:analyzePref} does not keep the original order for changes taken place in addressing the affix embeddedness +(listing ref{src:embedAffix}). Listing ref{src:affixPos} depicts the preferred solution. +The recursive construction of the method is similar to emph{private void analyzePrefix(String)} (listing ref{src:analyzePref}) +only that the two affix types are handled in one method. For that, an additional parameter taking the form either emph{suffix} +or emph{prefix} is included.</p> +<p>begin{lstlisting}[language=java,caption={Method to determine position of the affix},label=src:affixPos,escapechar=|] +private void getAffixPosition(Map<String, Integer> affix, String restword, int pos, String affixtype) +{</p> +<blockquote> +<div><p>if (!restword.isEmpty()) //Abbruchbedingung fuer Rekursion +{</p> +<blockquote> +<div><p>for (String s : affix.keySet()) +{</p> +<blockquote> +<div><p>if (restword.startsWith(s) && affixtype.equals(“prefix”)) +{</p> +<blockquote> +<div><blockquote> +<div>pos++; +prefixMorpheme.put(s, pos);</div></blockquote> +<dl class="docutils"> +<dt>//prefixAllomorph.add(pos-1, restword.substring(s.length()));</dt> +<dd>getAffixPosition(affix, restword.substring(s.length()), pos, affixtype);</dd> +</dl> +</div></blockquote> +<p>} +else if (restword.endsWith(s) && affixtype.equals(“suffix”)) +{</p> +<blockquote> +<div>pos++; +suffixMorpheme.put(s, pos); +//suffixAllomorph.add(pos-1, restword.substring(s.length())); +getAffixPosition(affix, restword.substring(0, restword.length() - s.length()), pos, affixtype);</div></blockquote> +<p>} +else +{</p> +<blockquote> +<div>getAffixPosition(affix, “”, pos, affixtype);</div></blockquote> +<p>}</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +<p>} +end{lstlisting}</p> +<p>To give the complete word structure, the root of a word should also be provided. In listing ref{src:rootAnalyze} a simple solution is offered, however, +considering compounds as words consisting of more than one root. +begin{lstlisting}[language=java,caption={Method to determine roots},label=src:rootAnalyze,escapechar=|] +private ArrayList<String> analyzeRoot(Map<String, Integer> pref, Map<String, Integer> suf, int stemNumber) +{</p> +<blockquote> +<div><p>ArrayList<String> root = new ArrayList<String>(); +int j = 1; //one root always exists +// if word is a compound several roots exist +while (j <= stemNumber) +{</p> +<blockquote> +<div><p>j++; +String rest = lemma;|label{ln:lemma}|</p> +<p>for (int i=0;i<pref.size();i++) +{</p> +<blockquote> +<div><p>for (String s : pref.keySet()) +{</p> +<blockquote> +<div><dl class="docutils"> +<dt>//if (i == pref.get(s))</dt> +<dd><p class="first">if (rest.length() > s.length() && s.equals(rest.substring(0, s.length()))) +{</p> +<blockquote class="last"> +<div>rest = rest.substring(s.length(),rest.length());</div></blockquote> +</dd> +</dl> +<p>}</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +<p>}</p> +<p>for (int i=0;i<suf.size();i++) +{</p> +<blockquote> +<div><p>for (String s : suf.keySet()) +{</p> +<blockquote> +<div><p>//if (i == suf.get(s)) +if (s.length() < rest.length() && (s.equals(rest.substring(rest.length() - s.length(), rest.length())))) +{</p> +<blockquote> +<div>rest = rest.substring(0, rest.length() - s.length());</div></blockquote> +<p>}</p> +</div></blockquote> +<p>}</p> +</div></blockquote> +<p>} +root.add(rest);</p> +</div></blockquote> +<p>} +return root;</p> +</div></blockquote> +<p>} +end{lstlisting} +The logic behind this method is that the root is the remainder of a word when all prefixes and suffixes are substracted. +So the loops run through the number of prefixes and suffixes at each position and substract the affix. Really, there is +some code doubling with the previously described methods, which could be eliminated by making it more modular in a possible +refactoring phase. Again, this is not the concern of a prototype. Line ref{ln:lemma} defines the initial state of a root, +which is the case for monomorphemic words. The emph{lemma} is defined as the wordtoken without the inflection. Thus listing +ref{src:lemmaAnalyze} reveals how the class variable is calculated +begin{lstlisting}[language=java,caption={Method to determine lemma},label=src:lemmaAnalyze,escapechar=|] +/*</p> +<blockquote> +<div><ul class="simple"> +<li>Simplification: lemma = wordtoken - inflection</li> +</ul> +<p><a href="#id14"><span class="problematic" id="id15">*</span></a>/</p> +</div></blockquote> +<p>private String analyzeLemma(String wrd, String infl) +{</p> +<blockquote> +<div>return wrd.substring(0, wrd.length() - infl.length());</div></blockquote> +<p>} +end{lstlisting} +The constructor of emph{AffixStripper} calls the method emph{analyzeWord()} +whose only job is to calculate each structure element in the correct order +(listing ref{src:lemmaAnalyze}). All structure elements are also provided by getters. +begin{lstlisting}[language=java,caption={Method to determine all word structure},label=src:lemmaAnalyze,escapechar=|] +private void analyzeWord() +{</p> +<blockquote> +<div>//analyze inflection first because it always occurs at the end of a word +inflection = analyzeInflection(wordtoken); +lemma = analyzeLemma(wordtoken, inflection); +analyzePrefix(lemma); +analyzeSuffix(lemma); +getAffixPosition(sortOutAffixes(prefixMorpheme), lemma, 0, “prefix”); +getAffixPosition(sortOutAffixes(suffixMorpheme), lemma, 0, “suffix”); +prefixNumber = prefixMorpheme.size(); +suffixNumber = suffixMorpheme.size(); +wordroot = analyzeRoot(prefixMorpheme, suffixMorpheme, getStemNumber());</div></blockquote> +<p>} +end{lstlisting}</p> +<p>To conclude, the Morphilo implementation as presented here, aims at fulfilling the task of a working prototype. It is important to note +that it neither claims to be a very efficient nor a ready software program to be used in production. However, it marks a crucial milestone +on the way to a production system. At some listings sources of improvement were made explicit; at others no suggestions were made. In the latter +case this does not imply that there is no potential for improvement. Once acceptability tests are carried out, it will be the task of a follow up project +to identify these potentials and implement them accordingly.</p> +</div> </div> </div> @@ -47,6 +1011,11 @@ <ul> <li><a class="reference internal" href="#">Controller Adjustments</a><ul> <li><a class="reference internal" href="#general-principle-of-operation">General Principle of Operation</a></li> +<li><a class="reference internal" href="#conceptualization">Conceptualization</a></li> +<li><a class="reference internal" href="#implementation">Implementation</a><ul> +<li><a class="reference internal" href="#id13">}</a></li> +</ul> +</li> </ul> </li> </ul> @@ -54,7 +1023,8 @@ <h3>Related Topics</h3> <ul> <li><a href="../index.html">Documentation overview</a><ul> - <li>Previous: <a href="datamodel.html" title="previous chapter">Data Model Implementation</a></li> + <li>Previous: <a href="datamodel.html" title="previous chapter">Data Model</a></li> + <li>Next: <a href="view.html" title="next chapter">View</a></li> </ul></li> </ul> </div> diff --git a/Morphilo_doc/_build/html/source/datamodel.html b/Morphilo_doc/_build/html/source/datamodel.html index b46e97e..ed8ca88 100644 --- a/Morphilo_doc/_build/html/source/datamodel.html +++ b/Morphilo_doc/_build/html/source/datamodel.html @@ -6,7 +6,7 @@ <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title>Data Model Implementation — Morphilo documentation</title> + <title>Data Model — Morphilo documentation</title> <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript" src="../_static/documentation_options.js"></script> @@ -16,7 +16,7 @@ <link rel="index" title="Index" href="../genindex.html" /> <link rel="search" title="Search" href="../search.html" /> <link rel="next" title="Controller Adjustments" href="controller.html" /> - <link rel="prev" title="Welcome to Morphilo’s documentation!" href="../index.html" /> + <link rel="prev" title="Documentation Morphilo Project" href="../index.html" /> <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> @@ -31,8 +31,60 @@ <div class="bodywrapper"> <div class="body" role="main"> - <div class="section" id="data-model-implementation"> -<h1>Data Model Implementation<a class="headerlink" href="#data-model-implementation" title="Permalink to this headline">¶</a></h1> + <div class="section" id="data-model"> +<h1>Data Model<a class="headerlink" href="#data-model" title="Permalink to this headline">¶</a></h1> +<div class="section" id="conceptualization"> +<h2>Conceptualization<a class="headerlink" href="#conceptualization" title="Permalink to this headline">¶</a></h2> +<p>From both the user and task requirements one can derive that four basic +functions of data processing need to be carried out. Data have to be read, persistently +saved, searched, and deleted. Furthermore, some kind of user management +and multi-user processing is necessary. In addition, the framework should +support web technologies, be well documented, and easy to extent. Ideally, the +MVC pattern is realized.</p> +<p>subsection{Data Model}label{subsec:datamodel} +The guidelines of the +emph{TEI}-standardfootnote{http://www.tei-c.org/release/doc/tei-p5-doc/en/Guidelines.pdf} on the +word level are defined in line with the structure defined above in section ref{subsec:morphologicalSystems}. +In listing ref{lst:teiExamp} an +example is given for a possible markup at the word level for +emph{comfortable}.footnote{http://www.tei-c.org/release/doc/tei-p5-doc/en/html/ref-m.html}</p> +<p>begin{lstlisting}[language=XML, +caption={TEI-example for ‘comfortable’},label=lst:teiExamp] +<w type=”adjective”></p> +<blockquote> +<div><dl class="docutils"> +<dt><m type=”base”></dt> +<dd><m type=”prefix” baseForm=”con”>com</m> +<m type=”root”>fort</m></dd> +</dl> +<p></m> +<m type=”suffix”>able</m></p> +</div></blockquote> +<p></w> +end{lstlisting}</p> +<p>This data model reflects just one theoretical conception of a word structure model. +Crucially, the model emanates from the assumption +that the suffix node is on par with the word base. On the one hand, this +implies that the word stem directly dominates the suffix, but not the prefix. The prefix, on the +other hand, is enclosed in the base, which basically means a stronger lexical, +and less abstract, attachment to the root of a word. Modeling prefixes and suffixes on different +hierarchical levels has important consequences for the branching direction at +subword level (here right-branching). Left the theoretical interest aside, the +choice of the TEI standard is reasonable with view to a sustainable architecture that allows for +exchanging data with little to no additional adjustments.</p> +<p>The negative account is that the model is not eligible for all languages. +It reflects a theoretical construction based on Indo-European +languages. If attention is paid to which language this software is used, it will +not be problematic. This is the case for most languages of the Indo-European +stem and corresponds to the overwhelming majority of all research carried out +(unfortunately).</p> +</div> +<div class="section" id="implementation"> +<h2>Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline">¶</a></h2> +<p>As laid out in the task analysis in section ref{subsec:datamodel}, it is +advantageous to use established standards. It was also shown that it makes sense +to keep the meta data of each corpus separate from the data model used for the +words to be analyzed.</p> <p>For the present case, the TEI-standard was identified as an appropriate markup for words. In terms of the implementation this means that the TEI guidelines have to be implemented as an object type compatible with the chosen @@ -56,6 +108,228 @@ in listing ref{lst:worddatamodel}. Whereas attributes of the objecttype are specific to the repository framework, the TEI structure can be recognized in the hierarchy of the meta data element starting with the name emph{w} (line ref{src:wordbegin}).</p> +<p>begin{lstlisting}[language=XML,caption={Word Data +model},label=lst:worddatamodel,escapechar=|] <?xml version=”1.0” encoding=”UTF-8”?> +<objecttype</p> +<blockquote> +<div><p>name=”morphilo” +isChild=”true” +isParent=”true” +hasDerivates=”true” +xmlns:xs=”http://www.w3.org/2001/XMLSchema” +xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” +xsi:noNamespaceSchemaLocation=”datamodel.xsd”> +<metadata></p> +<blockquote> +<div><element name=”morphiloContainer” type=”xml” style=”dontknow”</div></blockquote> +<dl class="docutils"> +<dt>notinherit=”true” heritable=”false”></dt> +<dd><blockquote class="first"> +<div><dl class="docutils"> +<dt><xs:sequence></dt> +<dd><dl class="first docutils"> +<dt><xs:element name=”morphilo”></dt> +<dd><dl class="first docutils"> +<dt><xs:complexType></dt> +<dd><dl class="first docutils"> +<dt><xs:sequence></dt> +<dd><dl class="first docutils"> +<dt><xs:element name=”w” minOccurs=”0” maxOccurs=”unbounded”>|label{src:wordbegin}|</dt> +<dd><dl class="first docutils"> +<dt><xs:complexType mixed=”true”></dt> +<dd><dl class="first docutils"> +<dt><xs:sequence></dt> +<dd><p class="first"><!– stem –> +<xs:element name=”m1” minOccurs=”0” maxOccurs=”unbounded”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xs:complexType mixed=”true”></dt> +<dd><dl class="first docutils"> +<dt><xs:sequence></dt> +<dd><p class="first"><!– base –> +<xs:element name=”m2” minOccurs=”0” maxOccurs=”unbounded”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xs:complexType mixed=”true”></dt> +<dd><dl class="first docutils"> +<dt><xs:sequence></dt> +<dd><p class="first"><!– root –> +<xs:element name=”m3” minOccurs=”0” maxOccurs=”unbounded”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xs:complexType mixed=”true”></dt> +<dd><xs:attribute name=”type” type=”xs:string”/></dd> +</dl> +<p></xs:complexType></p> +</div></blockquote> +<p></xs:element> +<!– prefix –> +<xs:element name=”m4” minOccurs=”0” maxOccurs=”unbounded”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xs:complexType mixed=”true”></dt> +<dd><xs:attribute name=”type” type=”xs:string”/> +<xs:attribute name=”PrefixbaseForm” type=”xs:string”/> +<xs:attribute name=”position” type=”xs:string”/></dd> +</dl> +<p></xs:complexType></p> +</div></blockquote> +<p class="last"></xs:element></p> +</dd> +</dl> +<p class="last"></xs:sequence> +<xs:attribute name=”type” type=”xs:string”/></p> +</dd> +</dl> +<p></xs:complexType></p> +</div></blockquote> +<p></xs:element> +<!– suffix –> +<xs:element name=”m5” minOccurs=”0” maxOccurs=”unbounded”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xs:complexType mixed=”true”></dt> +<dd><xs:attribute name=”type” type=”xs:string”/> +<xs:attribute name=”SuffixbaseForm” type=”xs:string”/> +<xs:attribute name=”position” type=”xs:string”/> +<xs:attribute name=”inflection” type=”xs:string”/></dd> +</dl> +<p></xs:complexType></p> +</div></blockquote> +<p class="last"></xs:element></p> +</dd> +</dl> +<p class="last"></xs:sequence> +<!– stem-Attribute –> +<xs:attribute name=”type” type=”xs:string”/> +<xs:attribute name=”pos” type=”xs:string”/> +<xs:attribute name=”occurrence” type=”xs:string”/></p> +</dd> +</dl> +<p></xs:complexType></p> +</div></blockquote> +<p class="last"></xs:element></p> +</dd> +</dl> +<p class="last"></xs:sequence> +<!– w -Attribute auf Wortebene –> +<xs:attribute name=”lemma” type=”xs:string”/> +<xs:attribute name=”complexType” type=”xs:string”/> +<xs:attribute name=”wordtype” type=”xs:string”/> +<xs:attribute name=”occurrence” type=”xs:string”/> +<xs:attribute name=”corpus” type=”xs:string”/> +<xs:attribute name=”begin” type=”xs:string”/> +<xs:attribute name=”end” type=”xs:string”/></p> +</dd> +</dl> +<p class="last"></xs:complexType></p> +</dd> +</dl> +<p class="last"></xs:element></p> +</dd> +</dl> +<p class="last"></xs:sequence></p> +</dd> +</dl> +<p class="last"></xs:complexType></p> +</dd> +</dl> +<p class="last"></xs:element></p> +</dd> +</dl> +<p></xs:sequence></p> +</div></blockquote> +<p></element> +<element name=”wordtype” type=”classification” minOccurs=”0” maxOccurs=”1”></p> +<blockquote> +<div><classification id=”wordtype”/></div></blockquote> +<p></element> +<element name=”complexType” type=”classification” minOccurs=”0” maxOccurs=”1”></p> +<blockquote> +<div><classification id=”complexType”/></div></blockquote> +<p></element> +<element name=”corpus” type=”classification” minOccurs=”0” maxOccurs=”1”></p> +<blockquote> +<div><classification id=”corpus”/></div></blockquote> +<p></element> +<element name=”pos” type=”classification” minOccurs=”0” maxOccurs=”1”></p> +<blockquote> +<div><classification id=”pos”/></div></blockquote> +<p></element> +<element name=”PrefixbaseForm” type=”classification” minOccurs=”0” +maxOccurs=”1”></p> +<blockquote> +<div><classification id=”PrefixbaseForm”/></div></blockquote> +<p></element> +<element name=”SuffixbaseForm” type=”classification” minOccurs=”0” +maxOccurs=”1”></p> +<blockquote> +<div><classification id=”SuffixbaseForm”/></div></blockquote> +<p></element> +<element name=”inflection” type=”classification” minOccurs=”0” maxOccurs=”1”></p> +<blockquote> +<div><classification id=”inflection”/></div></blockquote> +<p></element> +<element name=”corpuslink” type=”link” minOccurs=”0” maxOccurs=”unbounded” ></p> +<blockquote> +<div><target type=”corpmeta”/></div></blockquote> +<p class="last"></element></p> +</dd> +</dl> +<p></metadata></p> +</div></blockquote> +<p></objecttype> +end{lstlisting}</p> +<p>Additionally, it is worth mentioning that some attributes are modeled as a +emph{classification}. All these have to be listed +as separate elements in the data model. This has been done for all attributes +that are more or less subject to little or no change. In fact, all known suffix +and prefix morphemes should be known for the language investigated and are +therefore defined as a classification. +The same is true for the parts of speech named emph{pos} in the morphilo data +model above. +Here the PENN-Treebank tagset was used. Last, the different morphemic layers in +the standard model named emph{m} are changed to $m1$ through $m5$. This is the +only change in the standard that could be problematic if the data is to be +processed elsewhere and the change is not documented more explicitly. Yet, this +change was necessary for the MyCoRe repository throws errors caused by ambiguity +issues on the different $m$-layers.</p> +<p>The second data model describes only very few properties of the text corpora +from which the words are extracted. Listing ref{lst:corpusdatamodel} depicts +only the meta data element. For the sake of simplicity of the prototype, this +data model is kept as simple as possible. The obligatory field is the name of +the corpus. Specific dates of the corpus are classified as optional because in +some cases a text cannot be dated reliably.</p> +<p>begin{lstlisting}[language=XML,caption={Corpus Data +Model},label=lst:corpusdatamodel] +<metadata></p> +<blockquote> +<div><p><!– Pflichtfelder –> +<element name=”korpusname” type=”text” minOccurs=”1” maxOccurs=”1”/> +<!– Optionale Felder –> +<element name=”sprache” type=”text” minOccurs=”0” maxOccurs=”1”/> +<element name=”size” type=”number” minOccurs=”0” maxOccurs=”1”/> +<element name=”datefrom” type=”text” minOccurs=”0” maxOccurs=”1”/> +<element name=”dateuntil” type=”text” minOccurs=”0” maxOccurs=”1”/> +<!– number of words –> +<element name=”NoW” type=”text” minOccurs=”0” maxOccurs=”1”/> +<element name=”corpuslink” type=”link” minOccurs=”0” maxOccurs=”unbounded”></p> +<blockquote> +<div><target type=”morphilo”/></div></blockquote> +<p></element></p> +</div></blockquote> +<p></metadata> +end{lstlisting}</p> +<p>As a final remark, one might have noticed that all attributes are modelled as +strings although other data types are available and fields encoding the dates or +the number of words suggest otherwise. The MyCoRe framework even provides a +data type emph{historydate}. There is not a very satisfying answer to its +disuse. +All that can be said is that the use of data types different than the string +leads later on to problems in the convergence between the search engine and the +repository framework. These issues seem to be well known and can be followed on +github.</p> +</div> </div> @@ -63,11 +337,20 @@ emph{w} (line ref{src:wordbegin}).</p> </div> </div> <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"><div class="relations"> + <div class="sphinxsidebarwrapper"> + <h3><a href="../index.html">Table Of Contents</a></h3> + <ul> +<li><a class="reference internal" href="#">Data Model</a><ul> +<li><a class="reference internal" href="#conceptualization">Conceptualization</a></li> +<li><a class="reference internal" href="#implementation">Implementation</a></li> +</ul> +</li> +</ul> +<div class="relations"> <h3>Related Topics</h3> <ul> <li><a href="../index.html">Documentation overview</a><ul> - <li>Previous: <a href="../index.html" title="previous chapter">Welcome to Morphilo’s documentation!</a></li> + <li>Previous: <a href="../index.html" title="previous chapter">Documentation Morphilo Project</a></li> <li>Next: <a href="controller.html" title="next chapter">Controller Adjustments</a></li> </ul></li> </ul> diff --git a/Morphilo_doc/_build/html/source/framework.html b/Morphilo_doc/_build/html/source/framework.html new file mode 100644 index 0000000..d10a219 --- /dev/null +++ b/Morphilo_doc/_build/html/source/framework.html @@ -0,0 +1,114 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Framework — Morphilo documentation</title> + <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> + <script type="text/javascript" src="../_static/documentation_options.js"></script> + <script type="text/javascript" src="../_static/jquery.js"></script> + <script type="text/javascript" src="../_static/underscore.js"></script> + <script type="text/javascript" src="../_static/doctools.js"></script> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + <link rel="prev" title="Software Design" href="architecture.html" /> + + <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body" role="main"> + + <div class="section" id="framework"> +<h1>Framework<a class="headerlink" href="#framework" title="Permalink to this headline">¶</a></h1> +<dl class="docutils"> +<dt>begin{figure}</dt> +<dd>centering +includegraphics[scale=0.33]{mycore_architecture-2.png} +caption[MyCoRe-Architecture and Components]{MyCoRe-Architecture and Componentsprotectfootnotemark} +label{fig:abbMyCoReStruktur}</dd> +</dl> +<p>end{figure} +footnotetext{source: <a class="reference external" href="https://www.mycore.de">https://www.mycore.de</a>} +To specify the MyCoRe framework the morphilo application logic will have to be implemented, +the TEI data model specified, and the input, search and output mask programmed.</p> +<p>There are three directories which are +important for adjusting the MyCoRe framework to the needs of one’s own application. These three directories +correspond essentially to the three components in the MVC model as explicated in +section ref{subsec:mvc}. Roughly, they are envisualized in figure ref{fig:abbMyCoReStruktur} in the upper +right hand corner. More precisely, the view (emph{Layout} in figure ref{fig:abbMyCoReStruktur}) and the model layer +(emph{Datenmodell} in figure ref{fig:abbMyCoReStruktur}) can be done +completely via the <a href="#id1"><span class="problematic" id="id2">``</span></a>interface’‘, which is a directory with a predefined +structure and some standard files. For the configuration of the logic an extra directory is offered (/src/main/java/custom/mycore/addons/). Here all, java classes +extending the controller layer should be added. +Practically, all three MVC layers are placed in the +emph{src/main/}-directory of the application. In one of the subdirectories, +emph{datamodel/def}, the datamodel specifications are defined as xml files. It parallels the model +layer in the MVC pattern. How the data model was defined will be explained in +section ref{subsec:datamodelimpl}.</p> +</div> + + + </div> + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"><div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../index.html">Documentation overview</a><ul> + <li>Previous: <a href="architecture.html" title="previous chapter">Software Design</a></li> + </ul></li> +</ul> +</div> + <div role="note" aria-label="source link"> + <h3>This Page</h3> + <ul class="this-page-menu"> + <li><a href="../_sources/source/framework.rst.txt" + rel="nofollow">Show Source</a></li> + </ul> + </div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2018, Hagen Peukert. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.7.2</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.10</a> + + | + <a href="../_sources/source/framework.rst.txt" + rel="nofollow">Page source</a> + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/Morphilo_doc/_build/html/source/view.html b/Morphilo_doc/_build/html/source/view.html new file mode 100644 index 0000000..d9765a2 --- /dev/null +++ b/Morphilo_doc/_build/html/source/view.html @@ -0,0 +1,438 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>View — Morphilo documentation</title> + <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> + <script type="text/javascript" src="../_static/documentation_options.js"></script> + <script type="text/javascript" src="../_static/jquery.js"></script> + <script type="text/javascript" src="../_static/underscore.js"></script> + <script type="text/javascript" src="../_static/doctools.js"></script> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + <link rel="next" title="Software Design" href="architecture.html" /> + <link rel="prev" title="Controller Adjustments" href="controller.html" /> + + <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body" role="main"> + + <div class="section" id="view"> +<h1>View<a class="headerlink" href="#view" title="Permalink to this headline">¶</a></h1> +<div class="section" id="conceptualization"> +<h2>Conceptualization<a class="headerlink" href="#conceptualization" title="Permalink to this headline">¶</a></h2> +<p>Lastly, the third directory (emph{src/main/resources}) contains all code needed +for rendering the data to be displayed on the screen. So this corresponds to +the view in an MVC approach. It is done by xsl-files that (unfortunately) +contain some logic that really belongs to the controller. Thus, the division is +not as clear as implied in theory. I will discuss this issue more specifically in the +relevant subsection below. Among the resources are also all images, styles, and +javascripts.</p> +</div> +<div class="section" id="implementation"> +<h2>Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline">¶</a></h2> +<p>As explained in section ref{subsec:mvc}, the view component handles the visual +representation in the form of an interface that allows interaction between +the user and the task to be carried out by the machine. As a +webservice in the present case, all interaction happens via a browser, i.e. webpages are +visualized and responses are recognized by registering mouse or keyboard +events. More specifically, a webpage is rendered by transforming xml documents +to html pages. The MyCoRe repository framework uses an open source XSLT +processor from Apache, Xalan.footnote{http://xalan.apache.org} This engine +transforms document nodes described by the XPath syntax into hypertext making +use of a special form of template matching. All templates are collected in so +called xml-encoded stylesheets. Since there are two data models with two +different structures, it is good practice to define two stylesheet files one for +each data model.</p> +<p>As a demonstration, in listing ref{lst:morphilostylesheet} below a short +extract is given for rendering the word data.</p> +<p>begin{lstlisting}[language=XML,caption={stylesheet +morphilo.xsl},label=lst:morphilostylesheet] +<?xml version=”1.0” encoding=”UTF-8”?> +<xsl:stylesheet</p> +<blockquote> +<div><p>xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” +xmlns:xalan=”http://xml.apache.org/xalan” +xmlns:i18n=”xalan://org.mycore.services.i18n.MCRTranslation” +xmlns:acl=”xalan://org.mycore.access.MCRAccessManager” +xmlns:mcr=”http://www.mycore.org/” xmlns:xlink=”http://www.w3.org/1999/xlink” +xmlns:mods=”http://www.loc.gov/mods/v3” +xmlns:encoder=”xalan://java.net.URLEncoder” +xmlns:mcrxsl=”xalan://org.mycore.common.xml.MCRXMLFunctions” +xmlns:mcrurn=”xalan://org.mycore.urn.MCRXMLFunctions” +exclude-result-prefixes=”xalan xlink mcr i18n acl mods mcrxsl mcrurn encoder” +version=”1.0”> +<xsl:param name=”MCR.Users.Superuser.UserName”/></p> +<dl class="docutils"> +<dt><xsl:template match=”/mycoreobject[contains(@ID,’_morphilo_’)]”></dt> +<dd><dl class="first docutils"> +<dt><head></dt> +<dd><link href=”{$WebApplicationBaseURL}css/file.css” rel=”stylesheet”/></dd> +</dl> +<p></head> +<div class=”row”></p> +<blockquote class="last"> +<div><dl class="docutils"> +<dt><xsl:call-template name=”objectAction”></dt> +<dd><xsl:with-param name=”id” select=”@ID”/> +<xsl:with-param name=”deriv” select=”structure/derobjects/derobject/@xlink:href”/></dd> +</dl> +<p></xsl:call-template> +<xsl:variable name=”objID” select=”@ID”/> +<!– Hier Ueberschrift setzen –> +<h1 style=”text-indent: 4em;”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xsl:if test=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w”></dt> +<dd><xsl:value-of select=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text()[string-length(normalize-space(.))>0]”/></dd> +</dl> +<p></xsl:if></p> +</div></blockquote> +<p></h1> +<dl class=”dl-horizontal”> +<!– (1) Display word –></p> +<blockquote> +<div><dl class="docutils"> +<dt><xsl:if test=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w”></dt> +<dd><dl class="first docutils"> +<dt><dt></dt> +<dd><xsl:value-of select=”i18n:translate(‘response.page.label.word’)”/></dd> +</dl> +<p></dt> +<dd></p> +<blockquote> +<div><xsl:value-of select=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text()[string-length(normalize-space(.))>0]”/></div></blockquote> +<p class="last"></dd></p> +</dd> +</dl> +<p></xsl:if></p> +</div></blockquote> +<dl class="docutils"> +<dt><!– (2) Display lemma –></dt> +<dd>…</dd> +</dl> +</div></blockquote> +</dd> +</dl> +<p></xsl:template> +… +<xsl:template name=”objectAction”> +… +</xsl:template></p> +</div></blockquote> +<p>… +</xsl:stylesheet> +end{lstlisting} +This template matches with +the root node of each emph{MyCoRe object} ensuring that a valid MyCoRe model is +used and checking that the document to be processed contains a unique +identifier, here a emph{MyCoRe-ID}, and the name of the correct data model, +here emph{morphilo}. +Then, another template, emph{objectAction}, is called together with two parameters, the ids +of the document object and attached files. In the remainder all relevant +information from the document is accessed by XPath, such as the word and the lemma, +and enriched with hypertext annotations it is rendered as a hypertext document. +The template emph{objectAction} is key to understand the coupling process in the software +framework. It is therefore separately listed in ref{lst:objActionTempl}.</p> +<p>begin{lstlisting}[language=XML,caption={template +objectAction},label=lst:objActionTempl,escapechar=|] +<xsl:template name=”objectAction”></p> +<blockquote> +<div><p><xsl:param name=”id” select=”./@ID”/> +<xsl:param name=”accessedit” select=”acl:checkPermission($id,’writedb’)”/> +<xsl:param name=”accessdelete” select=”acl:checkPermission($id,’deletedb’)”/> +<xsl:variable name=”derivCorp” select=”./@label”/> +<xsl:variable name=”corpID” select=”metadata/def.corpuslink[@class=’MCRMetaLinkID’]/corpuslink/@xlink:href”/> +<xsl:if test=”$accessedit or $accessdelete”>|label{ln:ng}| +<div class=”dropdown pull-right”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xsl:if test=”string-length($corpID) &gt; 0 or $CurrentUser=’administrator’”></dt> +<dd><dl class="first docutils"> +<dt><button class=”btn btn-default dropdown-toggle” style=”margin:10px” type=”button” id=”dropdownMenu1” data-toggle=”dropdown” aria-expanded=”true”></dt> +<dd><span class=”glyphicon glyphicon-cog” aria-hidden=”true”></span> Annotieren +<span class=”caret”></span></dd> +</dl> +<p class="last"></button></p> +</dd> +</dl> +<p></xsl:if> +<xsl:if test=”string-length($corpID) &gt; 0”>|label{ln:ru}|</p> +<blockquote> +<div><p><xsl:variable name=”ifsDirectory” select=”document(concat(‘ifs:/’,$derivCorp))”/> +<ul class=”dropdown-menu” role=”menu” aria-labelledby=”dropdownMenu1”></p> +<blockquote> +<div><dl class="docutils"> +<dt><li role=”presentation”></dt> +<dd><dl class="first docutils"> +<dt><a href="#id1"><span class="problematic" id="id2">|\label{ln:nw1}|<a href="{$ServletsBaseURL}object/tag{$HttpSession}?id={$derivCorp}&amp;objID={$corpID}" role="menuitem" tabindex="-1">|</span></a>label{ln:nw2}|</dt> +<dd><xsl:value-of select=”i18n:translate(‘object.nextObject’)”/></dd> +</dl> +<p class="last"></a></p> +</dd> +</dl> +<p></li> +<li role=”presentation”></p> +<blockquote> +<div><dl class="docutils"> +<dt><a href=”{$WebApplicationBaseURL}receive/{$corpID}” role=”menuitem” tabindex=”-1”></dt> +<dd><xsl:value-of select=”i18n:translate(‘object.backToProject’)”/></dd> +</dl> +<p></a></p> +</div></blockquote> +<p></li></p> +</div></blockquote> +<p></ul></p> +</div></blockquote> +<p></xsl:if> +<xsl:if test=”$CurrentUser=’administrator’”></p> +<blockquote> +<div><dl class="docutils"> +<dt><ul class=”dropdown-menu” role=”menu” aria-labelledby=”dropdownMenu1”></dt> +<dd><blockquote class="first"> +<div><dl class="docutils"> +<dt><li role=”presentation”></dt> +<dd><dl class="first docutils"> +<dt><a role=”menuitem” tabindex=”-1” href=”{$WebApplicationBaseURL}content/publish/morphilo.xed?id={$id}”></dt> +<dd><xsl:value-of select=”i18n:translate(‘object.editWord’)”/></dd> +</dl> +<p class="last"></a></p> +</dd> +</dl> +<p></li> +<li role=”presentation”></p> +<blockquote> +<div><dl class="docutils"> +<dt><a href=”{$ServletsBaseURL}object/delete{$HttpSession}?id={$id}” role=”menuitem” tabindex=”-1” class=”confirm_deletion option” data-text=”Wirklich loeschen”></dt> +<dd><xsl:value-of select=”i18n:translate(‘object.delWord’)”/></dd> +</dl> +<p></a></p> +</div></blockquote> +</div></blockquote> +<p class="last"></li></p> +</dd> +</dl> +<p></ul></p> +</div></blockquote> +<p></xsl:if> +</div> +<div class=”row” style=”margin-left:0px; margin-right:10px”></p> +<blockquote> +<div><dl class="docutils"> +<dt><xsl:apply-templates select=”structure/derobjects/derobject[acl:checkPermission(@xlink:href,’read’)]”></dt> +<dd><xsl:with-param name=”objID” select=”@ID”/></dd> +</dl> +<p></xsl:apply-templates></p> +</div></blockquote> +<p></div></p> +</div></blockquote> +<p></xsl:if></p> +</div></blockquote> +<p></xsl:template> +end{lstlisting} +The emph{objectAction} template defines the selection menu appearing – once manual tagging has +started – on the upper right hand side of the webpage entitled +emph{Annotieren} and displaying the two options emph{next word} or emph{back +to project}. +The first thing to note here is that in line ref{ln:ng} a simple test +excludes all guest users from accessing the procedure. After ensuring that only +the user who owns the corpus project has access (line ref{ln:ru}), s/he will be +able to access the drop down menu, which is really a url, e.g. line +ref{ln:nw1}. The attentive reader might have noticed that +the url exactly matches the definition in the web-fragment.xml as shown in +listing ref{lst:webfragment}, line ref{ln:tag}, which resolves to the +respective java class there. Really, this mechanism is the data interface within the +MVC pattern. The url also contains two variables, named emph{derivCorp} and +emph{corpID}, that are needed to identify the corpus and file object by the +java classes (see section ref{sec:javacode}).</p> +<p>The morphilo.xsl stylesheet contains yet another modification that deserves mention. +In listing ref{lst:derobjectTempl}, line ref{ln:morphMenu}, two menu options – +emph{Tag automatically} and emph{Tag manually} – are defined. The former option +initiates ProcessCorpusServlet.java as can be seen again in listing ref{lst:webfragment}, +line ref{ln:process}, which determines words that are not in the master data base. +Still, it is important to note that the menu option is only displayed if two restrictions +are met. First, a file has to be uploaded (line ref{ln:1test}) and, second, there must be +only one file. This is necessary because in the annotation process other files will be generated +that store the words that were not yet processed or a file that includes the final result. The +generated files follow a certain pattern. The file harboring the final, entire TEI-annotated +corpus is prefixed by emph{tagged}, the other file is prefixed emph{untagged}. This circumstance +is exploited for manipulating the second option (line ref{ln:loop}). A loop runs through all +files in the respective directory and if a file name starts with emph{untagged}, +the option to manually tag is displayed.</p> +<p>begin{lstlisting}[language=XML,caption={template +matching derobject},label=lst:derobjectTempl,escapechar=|] +<xsl:template match=”derobject” mode=”derivateActions”></p> +<blockquote> +<div><p><xsl:param name=”deriv” /> +<xsl:param name=”parentObjID” /> +<xsl:param name=”suffix” select=”’‘” /> +<xsl:param name=”id” select=”../../../@ID” /> +<xsl:if test=”acl:checkPermission($deriv,’writedb’)”></p> +<blockquote> +<div><xsl:variable name=”ifsDirectory” select=”document(concat(‘ifs:’,$deriv,’/’))” /> +<xsl:variable name=”path” select=”$ifsDirectory/mcr_directory/path” /></div></blockquote> +<dl class="docutils"> +<dt>…</dt> +<dd><blockquote class="first"> +<div><dl class="docutils"> +<dt><div class=”options pull-right”></dt> +<dd><dl class="first docutils"> +<dt><div class=”btn-group” style=”margin:10px”></dt> +<dd><dl class="first docutils"> +<dt><a href=”#” class=”btn btn-default dropdown-toggle” data-toggle=”dropdown”></dt> +<dd><i class=”fa fa-cog”></i> +<xsl:value-of select=”’ Korpus’”/> +<span class=”caret”></span></dd> +</dl> +<p class="last"></a></p> +</dd> +<dt><ul class=”dropdown-menu dropdown-menu-right”></dt> +<dd><p class="first"><!– Anpasssungen Morphilo –>|label{ln:morphMenu}| +<xsl:if test=”string-length($deriv) &gt; 0”>|label{ln:1test}|</p> +<blockquote> +<div><dl class="docutils"> +<dt><xsl:if test=”count($ifsDirectory/mcr_directory/children/child) = 1”>|label{ln:2test}|</dt> +<dd><dl class="first docutils"> +<dt><li role=”presentation”></dt> +<dd><dl class="first docutils"> +<dt><a href=”{$ServletsBaseURL}object/process{$HttpSession}?id={$deriv}&amp;objID={$id}” role=”menuitem” tabindex=”-1”></dt> +<dd><xsl:value-of select=”i18n:translate(‘derivate.process’)”/></dd> +</dl> +<p class="last"></a></p> +</dd> +</dl> +<p class="last"></li></p> +</dd> +</dl> +<p></xsl:if> +<xsl:for-each select=”$ifsDirectory/mcr_directory/children/child”>|label{ln:loop}|</p> +<blockquote> +<div><p><xsl:variable name=”untagged” select=”concat($path, ‘untagged’)”/> +<xsl:variable name=”filename” select=”concat($path,./name)”/> +<xsl:if test=”starts-with($filename, $untagged)”></p> +<blockquote> +<div><dl class="docutils"> +<dt><li role=”presentation”></dt> +<dd><dl class="first docutils"> +<dt><a href=”{$ServletsBaseURL}object/tag{$HttpSession}?id={$deriv}&amp;objID={$id}” role=”menuitem” tabindex=”-1”></dt> +<dd><xsl:value-of select=”i18n:translate(‘derivate.taggen’)”/></dd> +</dl> +<p class="last"></a></p> +</dd> +</dl> +<p></li></p> +</div></blockquote> +<p></xsl:if></p> +</div></blockquote> +<p></xsl:for-each></p> +</div></blockquote> +<p class="last"></xsl:if></p> +</dd> +</dl> +<p class="last">… +</ul></p> +</dd> +</dl> +<p></div></p> +</div></blockquote> +<p class="last"></div></p> +</dd> +</dl> +<p></xsl:if></p> +</div></blockquote> +<p></xsl:template> +end{lstlisting}</p> +<p>Besides the two stylesheets morphilo.xsl and corpmeta.xsl, other stylesheets have +to be adjusted. They will not be discussed in detail here for they are self-explanatory for the most part. +Essentially, they render the overall layout (emph{common-layout.xsl}, emph{skeleton_layout_template.xsl}) +or the presentation +of the search results (emph{response-page.xsl}) and definitions of the solr search fields (emph{searchfields-solr.xsl}). +The former and latter also inherit templates from emph{response-general.xsl} and emph{response-browse.xsl}, in which the +navigation bar of search results can be changed. For the use of multilinguality a separate configuration directory +has to be created containing as many emph{.property}-files as different +languages want to be displayed. In the current case these are restricted to German and English (emph{messages_de.properties} and emph{messages_en.properties}). +The property files include all emph{i18n} definitions. All these files are located in the emph{resources} directory.</p> +<p>Furthermore, a search mask and a page for manually entering the annotations had +to be designed. +For these files a specially designed xml standard (emph{xed}) is recommended to be used within the +repository framework.</p> +</div> +</div> + + + </div> + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> + <h3><a href="../index.html">Table Of Contents</a></h3> + <ul> +<li><a class="reference internal" href="#">View</a><ul> +<li><a class="reference internal" href="#conceptualization">Conceptualization</a></li> +<li><a class="reference internal" href="#implementation">Implementation</a></li> +</ul> +</li> +</ul> +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../index.html">Documentation overview</a><ul> + <li>Previous: <a href="controller.html" title="previous chapter">Controller Adjustments</a></li> + <li>Next: <a href="architecture.html" title="next chapter">Software Design</a></li> + </ul></li> +</ul> +</div> + <div role="note" aria-label="source link"> + <h3>This Page</h3> + <ul class="this-page-menu"> + <li><a href="../_sources/source/view.rst.txt" + rel="nofollow">Show Source</a></li> + </ul> + </div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2018, Hagen Peukert. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.7.2</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.10</a> + + | + <a href="../_sources/source/view.rst.txt" + rel="nofollow">Page source</a> + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/Morphilo_doc/_build/latex/Morphilo.aux b/Morphilo_doc/_build/latex/Morphilo.aux index d61af2f..e36a19b 100644 --- a/Morphilo_doc/_build/latex/Morphilo.aux +++ b/Morphilo_doc/_build/latex/Morphilo.aux @@ -18,20 +18,13 @@ \providecommand\HyField@AuxAddToCoFields[2]{} \babel@aux{english}{} \newlabel{index::doc}{{}{1}{}{section*.2}{}} -\@writefile{toc}{\contentsline {chapter}{\numberline {1}Data Model Implementation}{1}{chapter.1}} +\@writefile{toc}{\contentsline {chapter}{\numberline {1}Data Model}{1}{chapter.1}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\newlabel{source/datamodel:data-model-implementation}{{1}{1}{Data Model Implementation}{chapter.1}{}} -\newlabel{source/datamodel::doc}{{1}{1}{Data Model Implementation}{chapter.1}{}} -\newlabel{source/datamodel:welcome-to-morphilo-s-documentation}{{1}{1}{Data Model Implementation}{chapter.1}{}} -\@writefile{toc}{\contentsline {chapter}{\numberline {2}Controller Adjustments}{3}{chapter.2}} -\@writefile{lof}{\addvspace {10\p@ }} -\@writefile{lot}{\addvspace {10\p@ }} -\newlabel{source/controller:controller-adjustments}{{2}{3}{Controller Adjustments}{chapter.2}{}} -\newlabel{source/controller::doc}{{2}{3}{Controller Adjustments}{chapter.2}{}} -\@writefile{toc}{\contentsline {section}{\numberline {2.1}General Principle of Operation}{3}{section.2.1}} -\newlabel{source/controller:general-principle-of-operation}{{2.1}{3}{General Principle of Operation}{section.2.1}{}} -\@writefile{toc}{\contentsline {chapter}{\numberline {3}Indices and tables}{5}{chapter.3}} -\@writefile{lof}{\addvspace {10\p@ }} -\@writefile{lot}{\addvspace {10\p@ }} -\newlabel{index:indices-and-tables}{{3}{5}{Indices and tables}{chapter.3}{}} +\newlabel{source/datamodel:documentation-morphilo-project}{{1}{1}{Data Model}{chapter.1}{}} +\newlabel{source/datamodel::doc}{{1}{1}{Data Model}{chapter.1}{}} +\newlabel{source/datamodel:data-model}{{1}{1}{Data Model}{chapter.1}{}} +\@writefile{toc}{\contentsline {section}{\numberline {1.1}Conceptualization}{1}{section.1.1}} +\newlabel{source/datamodel:conceptualization}{{1.1}{1}{Conceptualization}{section.1.1}{}} +\@writefile{toc}{\contentsline {section}{\numberline {1.2}Implementation}{1}{section.1.2}} +\newlabel{source/datamodel:implementation}{{1.2}{1}{Implementation}{section.1.2}{}} diff --git a/Morphilo_doc/_build/latex/Morphilo.fdb_latexmk b/Morphilo_doc/_build/latex/Morphilo.fdb_latexmk index 2c47a32..0ef1109 100644 --- a/Morphilo_doc/_build/latex/Morphilo.fdb_latexmk +++ b/Morphilo_doc/_build/latex/Morphilo.fdb_latexmk @@ -1,11 +1,11 @@ # Fdb version 3 -["makeindex Morphilo.idx"] 1539349060 "Morphilo.idx" "Morphilo.ind" "Morphilo" 1539349061 - "Morphilo.idx" 1539349060 0 d41d8cd98f00b204e9800998ecf8427e "" +["makeindex Morphilo.idx"] 1539349060 "Morphilo.idx" "Morphilo.ind" "Morphilo" 1539787485 + "Morphilo.idx" 1539787352 0 d41d8cd98f00b204e9800998ecf8427e "" (generated) + "Morphilo.ilg" "Morphilo.ind" -["pdflatex"] 1539349060 "Morphilo.tex" "Morphilo.pdf" "Morphilo" 1539349061 +["pdflatex"] 1539787485 "Morphilo.tex" "Morphilo.pdf" "Morphilo" 1539787485 "/etc/texmf/web2c/texmf.cnf" 1534936626 1101 af7716885e081ab43982cab7b4672c1a "" - "/usr/share/texlive/texmf-dist/fonts/enc/dvips/base/8r.enc" 1480098666 4850 80dc9bab7f31fb78a000ccfed0e27cab "" "/usr/share/texlive/texmf-dist/fonts/map/fontname/texfonts.map" 1511824771 3332 103109f5612ad95229751940c61aada0 "" "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/helvetic/phvb8r.tfm" 1480098688 4484 b828043cbd581d289d955903c1339981 "" "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/helvetic/phvb8t.tfm" 1480098688 6628 34c39492c0adc454c1c199922bba8363 "" @@ -13,28 +13,18 @@ "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/helvetic/phvr8t.tfm" 1480098688 7040 b2bd27e2bfe6f6948cbc3239cae7444f "" "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmb8r.tfm" 1480098689 4524 6bce29db5bc272ba5f332261583fee9c "" "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmb8t.tfm" 1480098689 6880 f19b8995b61c334d78fc734065f6b4d4 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmr8c.tfm" 1480098689 1352 fa28a7e6d323c65ce7d13d5342ff6be2 "" "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmr8r.tfm" 1480098689 4408 25b74d011a4c66b7f212c0cc3c90061b "" "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmr8t.tfm" 1480098689 6672 e3ab9e37e925f3045c9005e6d1473d56 "" "/usr/share/texlive/texmf-dist/fonts/tfm/jknappen/ec/ecrm1000.tfm" 1480098696 3584 adb004a0c8e7c46ee66cad73671f37b4 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1480098698 1004 54797486969f23fa377b128694d548df "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm" 1480098698 916 f87d7c45f9c908e672703b83b72241a3 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam5.tfm" 1480098698 924 9904cf1d39e9767e7a3622f2a125a565 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam7.tfm" 1480098698 928 2dc8d444221b7a635bb58038579b861a "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm" 1480098698 908 2921f8a10601f252058503cc6570e581 "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm5.tfm" 1480098698 940 75ac932a52f80982a9f8ea75d03a34cf "" - "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm" 1480098698 940 228d6584342e91276bf566bcf9716b83 "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmex10.tfm" 1480098701 992 662f679a0b3d2d53c1b94050fdaa3f50 "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm" 1480098701 1524 4414a8315f39513458b80dfc63bff03a "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr12.tfm" 1480098701 1288 655e228510b4c2a1abe905c368440826 "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr17.tfm" 1480098701 1292 296a67155bdbfc32aa9c636f21e91433 "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy10.tfm" 1480098701 1124 6c73e740cf17375f03eec0ee63599741 "" - "/usr/share/texlive/texmf-dist/fonts/type1/urw/helvetic/uhvb8a.pfb" 1480098746 35941 f27169cc74234d5bd5e4cca5abafaabb "" - "/usr/share/texlive/texmf-dist/fonts/type1/urw/times/utmb8a.pfb" 1480098746 44729 811d6c62865936705a31c797a1d5dada "" - "/usr/share/texlive/texmf-dist/fonts/type1/urw/times/utmr8a.pfb" 1480098746 46026 6dab18b61c907687b520c72847215a68 "" "/usr/share/texlive/texmf-dist/fonts/vf/adobe/helvetic/phvb8t.vf" 1480098757 2340 0efed6a948c3c37d870e4e7ddb85c7c3 "" "/usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmb8t.vf" 1480098758 2340 df9c920cc5688ebbf16a93f45ce7bdd3 "" - "/usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmr8c.vf" 1480098758 3556 8a9a6dcbcd146ef985683f677f4758a6 "" "/usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmr8t.vf" 1480098758 2348 91706c542228501c410c266421fbe30c "" "/usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii" 1480098806 71627 94eb9990bed73c364d7f53f960cc8c5b "" "/usr/share/texlive/texmf-dist/tex/generic/babel-english/english.ldf" 1496785618 7008 9ff5fdcc865b01beca2b0fe4a46231d4 "" @@ -116,7 +106,6 @@ "/usr/share/texlive/texmf-dist/tex/latex/psnfss/t1phv.fd" 1480098837 1488 9a55ac1cde6b4798a7f56844bb75a553 "" "/usr/share/texlive/texmf-dist/tex/latex/psnfss/t1ptm.fd" 1480098837 774 61d7da1e9f9e74989b196d147e623736 "" "/usr/share/texlive/texmf-dist/tex/latex/psnfss/times.sty" 1480098837 857 6c716f26c5eadfb81029fcd6ce2d45e6 "" - "/usr/share/texlive/texmf-dist/tex/latex/psnfss/ts1ptm.fd" 1480098837 619 96f56dc5d1ef1fe1121f1cfeec70ee0c "" "/usr/share/texlive/texmf-dist/tex/latex/tabulary/tabulary.sty" 1480098840 13791 8c83287d79183c3bf58fd70871e8a70b "" "/usr/share/texlive/texmf-dist/tex/latex/titlesec/titlesec.sty" 1480098841 37387 afa86533e532701faf233f3f592c61e0 "" "/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty" 1485129666 12396 d41f82b039f900e95f351e54ae740f31 "" @@ -130,20 +119,20 @@ "/usr/share/texmf/web2c/texmf.cnf" 1520210507 32485 c64754543d8ac501bea6e75e209ea521 "" "/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1534936964 2700761 ac0584cc9514ab21918550a6948c4ee2 "" "/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1534936984 4127050 03a6fcb3ed24b2a3ea3480b0b9907a5c "" - "Morphilo.aux" 1539349061 2013 11aa85ec61008c3d3e26ffd886907985 "" + "Morphilo.aux" 1539787473 1477 793e7b87aef4b9bac134adf8f9125ab3 "" "Morphilo.ind" 1539349060 0 d41d8cd98f00b204e9800998ecf8427e "makeindex Morphilo.idx" - "Morphilo.out" 1539349061 682 6029c0089617742ffad26495c33fcf03 "" - "Morphilo.tex" 1539349059 4616 848d76cc8b069c19a8fb2a2ce4b09737 "" - "Morphilo.toc" 1539349061 342 ac6875778cea5ee102b9b5dfd776b04e "" + "Morphilo.out" 1539787473 359 8f0f08e0cc33542e46a154cf270f9233 "" + "Morphilo.tex" 1539787485 97592 966a4c392c3d9d75dc858d7c1efdd907 "" + "Morphilo.toc" 1539787352 0 d41d8cd98f00b204e9800998ecf8427e "" "footnotehyper-sphinx.sty" 1523881736 8886 0562fcad2b7e25f93331edc6fc422c87 "" "sphinx.sty" 1523881736 67712 9b578972569f0169bf44cfae88da82f2 "" - "sphinxhighlight.sty" 1539349059 8137 b8d4ef963833564f6e4eadc09cd757c4 "" + "sphinxhighlight.sty" 1539787485 8137 b8d4ef963833564f6e4eadc09cd757c4 "" "sphinxmanual.cls" 1523881736 3589 0b0aac49c6f36925cf5f9d524a75a978 "" "sphinxmulticell.sty" 1523881736 14618 0defbdc8536ad2e67f1eac6a1431bc55 "" (generated) - "Morphilo.log" - "Morphilo.aux" + "Morphilo.out" "Morphilo.idx" - "Morphilo.toc" + "Morphilo.aux" "Morphilo.pdf" - "Morphilo.out" + "Morphilo.log" + "Morphilo.toc" diff --git a/Morphilo_doc/_build/latex/Morphilo.fls b/Morphilo_doc/_build/latex/Morphilo.fls index 8656387..f9629b7 100644 --- a/Morphilo_doc/_build/latex/Morphilo.fls +++ b/Morphilo_doc/_build/latex/Morphilo.fls @@ -241,32 +241,13 @@ INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/helvetic/phvr8t.tfm INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/helvetic/phvb8t.tfm INPUT Morphilo.toc INPUT Morphilo.toc -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmb8t.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam5.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm5.tfm OUTPUT Morphilo.toc INPUT /usr/share/texlive/texmf-dist/fonts/vf/adobe/helvetic/phvb8t.vf INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/helvetic/phvb8r.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmb8t.vf -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmb8r.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmr8t.vf -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmr8r.tfm INPUT /usr/share/texlive/texmf-dist/fonts/vf/adobe/helvetic/phvb8t.vf INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/helvetic/phvb8r.tfm -INPUT /usr/share/texlive/texmf-dist/tex/latex/psnfss/ts1ptm.fd -INPUT /usr/share/texlive/texmf-dist/tex/latex/psnfss/ts1ptm.fd -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmr8c.tfm -INPUT Morphilo.ind -INPUT Morphilo.ind -INPUT /usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmr8c.vf -INPUT Morphilo.aux -INPUT ./Morphilo.out -INPUT ./Morphilo.out -INPUT /usr/share/texlive/texmf-dist/fonts/enc/dvips/base/8r.enc -INPUT /usr/share/texlive/texmf-dist/fonts/type1/urw/helvetic/uhvb8a.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/urw/times/utmb8a.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/urw/times/utmr8a.pfb +INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmb8t.tfm +INPUT /usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmr8t.vf +INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmr8r.tfm +INPUT /usr/share/texlive/texmf-dist/fonts/vf/adobe/times/ptmb8t.vf +INPUT /usr/share/texlive/texmf-dist/fonts/tfm/adobe/times/ptmb8r.tfm diff --git a/Morphilo_doc/_build/latex/Morphilo.log b/Morphilo_doc/_build/latex/Morphilo.log index 46c0b95..aaf690d 100644 --- a/Morphilo_doc/_build/latex/Morphilo.log +++ b/Morphilo_doc/_build/latex/Morphilo.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) (preloaded format=pdflatex 2018.8.22) 12 OCT 2018 14:57 +This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) (preloaded format=pdflatex 2018.8.22) 17 OCT 2018 16:44 entering extended mode restricted \write18 enabled. %&-line parsing enabled. @@ -1137,10 +1137,7 @@ LaTeX Font Info: Font shape `T1/phv/bx/n' in size <12> not available ] LaTeX Font Info: Font shape `T1/phv/bx/n' in size <14.4> not available (Font) Font shape `T1/phv/b/n' tried instead on input line 69. - (./Morphilo.toc -LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <10> not available -(Font) Font shape `T1/ptm/b/n' tried instead on input line 2. -) + (./Morphilo.toc) \tf@toc=\write6 \openout6 = `Morphilo.toc'. @@ -1150,48 +1147,57 @@ LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <10> not available ] Chapter 1. -[1 -] [2 +Underfull \hbox (badness 10000) in paragraph at lines 94--97 +[]\T1/ptm/m/n/10 begin{lstlisting}[language=XML, caption={TEI-example for `com- +fort-able'},label=lst:teiExamp] <w + [] -] -Chapter 2. -[3] [4 +LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <10> not available +(Font) Font shape `T1/ptm/b/n' tried instead on input line 99. +[1 ] -Chapter 3. -LaTeX Font Info: Try loading font information for TS1+ptm on input line 110. +Underfull \hbox (badness 10000) in paragraph at lines 168--176 +[]\T1/ptm/m/n/10 name=^^Qmorphilo^^Q is-Child=^^Qtrue^^Q is-Par-ent=^^Qtrue^^Q +has-Derivates=^^Qtrue^^Q + [] + -(/usr/share/texlive/texmf-dist/tex/latex/psnfss/ts1ptm.fd -File: ts1ptm.fd 2001/06/04 font definitions for TS1/ptm. -) (./Morphilo.ind) -Package atveryend Info: Empty hook `BeforeClearDocument' on input line 125. +! LaTeX Error: Too deeply nested. -[5] -Package atveryend Info: Empty hook `AfterLastShipout' on input line 125. - (./Morphilo.aux) -Package atveryend Info: Executing hook `AtVeryEndDocument' on input line 125. -Package atveryend Info: Executing hook `AtEndAfterFileList' on input line 125. -Package rerunfilecheck Info: File `Morphilo.out' has not changed. -(rerunfilecheck) Checksum: 6029C0089617742FFAD26495C33FCF03;682. -Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 125. - ) +See the LaTeX manual or LaTeX Companion for explanation. +Type H <return> for immediate help. + ... + +l.185 ...reater{}}] \leavevmode\begin{description} + +? +! Interruption. +\GenericError ... + \endgroup +l.185 ...reater{}}] \leavevmode\begin{description} + +? ^^[[A +Type <return> to proceed, S to scroll future error messages, +R to run without stopping, Q to run quietly, +I to insert something, E to edit your file, +H for help, X to quit. +? +! Emergency stop. +\GenericError ... + \endgroup +l.185 ...reater{}}] \leavevmode\begin{description} + +End of file on the terminal! + + Here is how much of TeX's memory you used: - 13509 strings out of 492982 - 186890 string characters out of 6134896 - 274532 words of memory out of 5000000 - 16777 multiletter control sequences out of 15000+600000 - 37190 words of font info for 55 fonts, out of 8000000 for 9000 + 13449 strings out of 492982 + 186097 string characters out of 6134896 + 277384 words of memory out of 5000000 + 16746 multiletter control sequences out of 15000+600000 + 35585 words of font info for 48 fonts, out of 8000000 for 9000 1142 hyphenation exceptions out of 8191 37i,11n,45p,280b,360s stack positions out of 5000i,500n,10000p,200000b,80000s -{/usr/share/texlive/texmf-dist/fonts/enc/dvips/base/8r.enc}</usr/share/texliv -e/texmf-dist/fonts/type1/urw/helvetic/uhvb8a.pfb></usr/share/texlive/texmf-dist -/fonts/type1/urw/times/utmb8a.pfb></usr/share/texlive/texmf-dist/fonts/type1/ur -w/times/utmr8a.pfb> -Output written on Morphilo.pdf (9 pages, 47006 bytes). -PDF statistics: - 89 PDF objects out of 1000 (max. 8388607) - 69 compressed objects within 1 object stream - 14 named destinations out of 1000 (max. 500000) - 53 words of extra memory for PDF output out of 10000 (max. 10000000) - +! ==> Fatal error occurred, no output PDF file produced! diff --git a/Morphilo_doc/_build/latex/Morphilo.out b/Morphilo_doc/_build/latex/Morphilo.out index 5525dfa..11fd692 100644 --- a/Morphilo_doc/_build/latex/Morphilo.out +++ b/Morphilo_doc/_build/latex/Morphilo.out @@ -1,4 +1,3 @@ -\BOOKMARK [0][-]{chapter.1}{\376\377\000D\000a\000t\000a\000\040\000M\000o\000d\000e\000l\000\040\000I\000m\000p\000l\000e\000m\000e\000n\000t\000a\000t\000i\000o\000n}{}% 1 -\BOOKMARK [0][-]{chapter.2}{\376\377\000C\000o\000n\000t\000r\000o\000l\000l\000e\000r\000\040\000A\000d\000j\000u\000s\000t\000m\000e\000n\000t\000s}{}% 2 -\BOOKMARK [1][-]{section.2.1}{\376\377\000G\000e\000n\000e\000r\000a\000l\000\040\000P\000r\000i\000n\000c\000i\000p\000l\000e\000\040\000o\000f\000\040\000O\000p\000e\000r\000a\000t\000i\000o\000n}{chapter.2}% 3 -\BOOKMARK [0][-]{chapter.3}{\376\377\000I\000n\000d\000i\000c\000e\000s\000\040\000a\000n\000d\000\040\000t\000a\000b\000l\000e\000s}{}% 4 +\BOOKMARK [0][-]{chapter.1}{\376\377\000D\000a\000t\000a\000\040\000M\000o\000d\000e\000l}{}% 1 +\BOOKMARK [1][-]{section.1.1}{\376\377\000C\000o\000n\000c\000e\000p\000t\000u\000a\000l\000i\000z\000a\000t\000i\000o\000n}{chapter.1}% 2 +\BOOKMARK [1][-]{section.1.2}{\376\377\000I\000m\000p\000l\000e\000m\000e\000n\000t\000a\000t\000i\000o\000n}{chapter.1}% 3 diff --git a/Morphilo_doc/_build/latex/Morphilo.pdf b/Morphilo_doc/_build/latex/Morphilo.pdf deleted file mode 100644 index 5aae41856019d74b9c736803c3a49a5f541e0dd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47006 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 OQxjt@RaIAiH!c9628dn& diff --git a/Morphilo_doc/_build/latex/Morphilo.tex b/Morphilo_doc/_build/latex/Morphilo.tex index 4512096..4e090d9 100644 --- a/Morphilo_doc/_build/latex/Morphilo.tex +++ b/Morphilo_doc/_build/latex/Morphilo.tex @@ -56,7 +56,7 @@ \title{Morphilo Documentation} -\date{Oct 12, 2018} +\date{Oct 17, 2018} \release{} \author{Hagen Peukert} \newcommand{\sphinxlogo}{\vbox{}} @@ -71,8 +71,70 @@ -\chapter{Data Model Implementation} -\label{\detokenize{source/datamodel:data-model-implementation}}\label{\detokenize{source/datamodel::doc}}\label{\detokenize{source/datamodel:welcome-to-morphilo-s-documentation}} +\chapter{Data Model} +\label{\detokenize{source/datamodel:documentation-morphilo-project}}\label{\detokenize{source/datamodel::doc}}\label{\detokenize{source/datamodel:data-model}} + +\section{Conceptualization} +\label{\detokenize{source/datamodel:conceptualization}} +From both the user and task requirements one can derive that four basic +functions of data processing need to be carried out. Data have to be read, persistently +saved, searched, and deleted. Furthermore, some kind of user management +and multi-user processing is necessary. In addition, the framework should +support web technologies, be well documented, and easy to extent. Ideally, the +MVC pattern is realized. + +subsection\{Data Model\}label\{subsec:datamodel\} +The guidelines of the +emph\{TEI\}-standardfootnote\{http://www.tei-c.org/release/doc/tei-p5-doc/en/Guidelines.pdf\} on the +word level are defined in line with the structure defined above in section ref\{subsec:morphologicalSystems\}. +In listing ref\{lst:teiExamp\} an +example is given for a possible markup at the word level for +emph\{comfortable\}.footnote\{http://www.tei-c.org/release/doc/tei-p5-doc/en/html/ref-m.html\} + +begin\{lstlisting\}{[}language=XML, +caption=\{TEI-example for ‘comfortable’\},label=lst:teiExamp{]} +\textless{}w type=”adjective”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}m type=”base”\textgreater{}}] \leavevmode +\textless{}m type=”prefix” baseForm=”con”\textgreater{}com\textless{}/m\textgreater{} +\textless{}m type=”root”\textgreater{}fort\textless{}/m\textgreater{} + +\end{description} + +\textless{}/m\textgreater{} +\textless{}m type=”suffix”\textgreater{}able\textless{}/m\textgreater{} +\end{quote} + +\textless{}/w\textgreater{} +end\{lstlisting\} + +This data model reflects just one theoretical conception of a word structure model. +Crucially, the model emanates from the assumption +that the suffix node is on par with the word base. On the one hand, this +implies that the word stem directly dominates the suffix, but not the prefix. The prefix, on the +other hand, is enclosed in the base, which basically means a stronger lexical, +and less abstract, attachment to the root of a word. Modeling prefixes and suffixes on different +hierarchical levels has important consequences for the branching direction at +subword level (here right-branching). Left the theoretical interest aside, the +choice of the TEI standard is reasonable with view to a sustainable architecture that allows for +exchanging data with little to no additional adjustments. + +The negative account is that the model is not eligible for all languages. +It reflects a theoretical construction based on Indo-European +languages. If attention is paid to which language this software is used, it will +not be problematic. This is the case for most languages of the Indo-European +stem and corresponds to the overwhelming majority of all research carried out +(unfortunately). + + +\section{Implementation} +\label{\detokenize{source/datamodel:implementation}} +As laid out in the task analysis in section ref\{subsec:datamodel\}, it is +advantageous to use established standards. It was also shown that it makes sense +to keep the meta data of each corpus separate from the data model used for the +words to be analyzed. + For the present case, the TEI-standard was identified as an appropriate markup for words. In terms of the implementation this means that the TEI guidelines have to be implemented as an object type compatible with the chosen @@ -98,12 +160,1999 @@ Whereas attributes of the objecttype are specific to the repository framework, t recognized in the hierarchy of the meta data element starting with the name emph\{w\} (line ref\{src:wordbegin\}). +begin\{lstlisting\}{[}language=XML,caption=\{Word Data +model\},label=lst:worddatamodel,escapechar=\textbar{}{]} \textless{}?xml version=”1.0” encoding=”UTF-8”?\textgreater{} +\textless{}objecttype +\begin{quote} + +name=”morphilo” +isChild=”true” +isParent=”true” +hasDerivates=”true” +xmlns:xs=”http://www.w3.org/2001/XMLSchema” +xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” +xsi:noNamespaceSchemaLocation=”datamodel.xsd”\textgreater{} +\textless{}metadata\textgreater{} +\begin{quote} + +\textless{}element name=”morphiloContainer” type=”xml” style=”dontknow” +\end{quote} +\begin{description} +\item[{notinherit=”true” heritable=”false”\textgreater{}}] \leavevmode\begin{quote} +\begin{description} +\item[{\textless{}xs:sequence\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}xs:element name=”morphilo”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}xs:complexType\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}xs:sequence\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}xs:element name=”w” minOccurs=”0” maxOccurs=”unbounded”\textgreater{}\textbar{}label\{src:wordbegin\}\textbar{}}] \leavevmode\begin{description} +\item[{\textless{}xs:complexType mixed=”true”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}xs:sequence\textgreater{}}] \leavevmode +\textless{}!\textendash{} stem \textendash{}\textgreater{} +\textless{}xs:element name=”m1” minOccurs=”0” maxOccurs=”unbounded”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xs:complexType mixed=”true”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}xs:sequence\textgreater{}}] \leavevmode +\textless{}!\textendash{} base \textendash{}\textgreater{} +\textless{}xs:element name=”m2” minOccurs=”0” maxOccurs=”unbounded”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xs:complexType mixed=”true”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}xs:sequence\textgreater{}}] \leavevmode +\textless{}!\textendash{} root \textendash{}\textgreater{} +\textless{}xs:element name=”m3” minOccurs=”0” maxOccurs=”unbounded”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xs:complexType mixed=”true”\textgreater{}}] \leavevmode +\textless{}xs:attribute name=”type” type=”xs:string”/\textgreater{} + +\end{description} + +\textless{}/xs:complexType\textgreater{} +\end{quote} + +\textless{}/xs:element\textgreater{} +\textless{}!\textendash{} prefix \textendash{}\textgreater{} +\textless{}xs:element name=”m4” minOccurs=”0” maxOccurs=”unbounded”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xs:complexType mixed=”true”\textgreater{}}] \leavevmode +\textless{}xs:attribute name=”type” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”PrefixbaseForm” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”position” type=”xs:string”/\textgreater{} + +\end{description} + +\textless{}/xs:complexType\textgreater{} +\end{quote} + +\textless{}/xs:element\textgreater{} + +\end{description} + +\textless{}/xs:sequence\textgreater{} +\textless{}xs:attribute name=”type” type=”xs:string”/\textgreater{} + +\end{description} + +\textless{}/xs:complexType\textgreater{} +\end{quote} + +\textless{}/xs:element\textgreater{} +\textless{}!\textendash{} suffix \textendash{}\textgreater{} +\textless{}xs:element name=”m5” minOccurs=”0” maxOccurs=”unbounded”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xs:complexType mixed=”true”\textgreater{}}] \leavevmode +\textless{}xs:attribute name=”type” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”SuffixbaseForm” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”position” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”inflection” type=”xs:string”/\textgreater{} + +\end{description} + +\textless{}/xs:complexType\textgreater{} +\end{quote} + +\textless{}/xs:element\textgreater{} + +\end{description} + +\textless{}/xs:sequence\textgreater{} +\textless{}!\textendash{} stem-Attribute \textendash{}\textgreater{} +\textless{}xs:attribute name=”type” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”pos” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”occurrence” type=”xs:string”/\textgreater{} + +\end{description} + +\textless{}/xs:complexType\textgreater{} +\end{quote} + +\textless{}/xs:element\textgreater{} + +\end{description} + +\textless{}/xs:sequence\textgreater{} +\textless{}!\textendash{} w -Attribute auf Wortebene \textendash{}\textgreater{} +\textless{}xs:attribute name=”lemma” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”complexType” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”wordtype” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”occurrence” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”corpus” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”begin” type=”xs:string”/\textgreater{} +\textless{}xs:attribute name=”end” type=”xs:string”/\textgreater{} + +\end{description} + +\textless{}/xs:complexType\textgreater{} + +\end{description} + +\textless{}/xs:element\textgreater{} + +\end{description} + +\textless{}/xs:sequence\textgreater{} + +\end{description} + +\textless{}/xs:complexType\textgreater{} + +\end{description} + +\textless{}/xs:element\textgreater{} + +\end{description} + +\textless{}/xs:sequence\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”wordtype” type=”classification” minOccurs=”0” maxOccurs=”1”\textgreater{} +\begin{quote} + +\textless{}classification id=”wordtype”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”complexType” type=”classification” minOccurs=”0” maxOccurs=”1”\textgreater{} +\begin{quote} + +\textless{}classification id=”complexType”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”corpus” type=”classification” minOccurs=”0” maxOccurs=”1”\textgreater{} +\begin{quote} + +\textless{}classification id=”corpus”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”pos” type=”classification” minOccurs=”0” maxOccurs=”1”\textgreater{} +\begin{quote} + +\textless{}classification id=”pos”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”PrefixbaseForm” type=”classification” minOccurs=”0” +maxOccurs=”1”\textgreater{} +\begin{quote} + +\textless{}classification id=”PrefixbaseForm”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”SuffixbaseForm” type=”classification” minOccurs=”0” +maxOccurs=”1”\textgreater{} +\begin{quote} + +\textless{}classification id=”SuffixbaseForm”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”inflection” type=”classification” minOccurs=”0” maxOccurs=”1”\textgreater{} +\begin{quote} + +\textless{}classification id=”inflection”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\textless{}element name=”corpuslink” type=”link” minOccurs=”0” maxOccurs=”unbounded” \textgreater{} +\begin{quote} + +\textless{}target type=”corpmeta”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} + +\end{description} + +\textless{}/metadata\textgreater{} +\end{quote} + +\textless{}/objecttype\textgreater{} +end\{lstlisting\} + +Additionally, it is worth mentioning that some attributes are modeled as a +emph\{classification\}. All these have to be listed +as separate elements in the data model. This has been done for all attributes +that are more or less subject to little or no change. In fact, all known suffix +and prefix morphemes should be known for the language investigated and are +therefore defined as a classification. +The same is true for the parts of speech named emph\{pos\} in the morphilo data +model above. +Here the PENN-Treebank tagset was used. Last, the different morphemic layers in +the standard model named emph\{m\} are changed to \$m1\$ through \$m5\$. This is the +only change in the standard that could be problematic if the data is to be +processed elsewhere and the change is not documented more explicitly. Yet, this +change was necessary for the MyCoRe repository throws errors caused by ambiguity +issues on the different \$m\$-layers. + +The second data model describes only very few properties of the text corpora +from which the words are extracted. Listing ref\{lst:corpusdatamodel\} depicts +only the meta data element. For the sake of simplicity of the prototype, this +data model is kept as simple as possible. The obligatory field is the name of +the corpus. Specific dates of the corpus are classified as optional because in +some cases a text cannot be dated reliably. + +begin\{lstlisting\}{[}language=XML,caption=\{Corpus Data +Model\},label=lst:corpusdatamodel{]} +\textless{}metadata\textgreater{} +\begin{quote} + +\textless{}!\textendash{} Pflichtfelder \textendash{}\textgreater{} +\textless{}element name=”korpusname” type=”text” minOccurs=”1” maxOccurs=”1”/\textgreater{} +\textless{}!\textendash{} Optionale Felder \textendash{}\textgreater{} +\textless{}element name=”sprache” type=”text” minOccurs=”0” maxOccurs=”1”/\textgreater{} +\textless{}element name=”size” type=”number” minOccurs=”0” maxOccurs=”1”/\textgreater{} +\textless{}element name=”datefrom” type=”text” minOccurs=”0” maxOccurs=”1”/\textgreater{} +\textless{}element name=”dateuntil” type=”text” minOccurs=”0” maxOccurs=”1”/\textgreater{} +\textless{}!\textendash{} number of words \textendash{}\textgreater{} +\textless{}element name=”NoW” type=”text” minOccurs=”0” maxOccurs=”1”/\textgreater{} +\textless{}element name=”corpuslink” type=”link” minOccurs=”0” maxOccurs=”unbounded”\textgreater{} +\begin{quote} + +\textless{}target type=”morphilo”/\textgreater{} +\end{quote} + +\textless{}/element\textgreater{} +\end{quote} + +\textless{}/metadata\textgreater{} +end\{lstlisting\} + +As a final remark, one might have noticed that all attributes are modelled as +strings although other data types are available and fields encoding the dates or +the number of words suggest otherwise. The MyCoRe framework even provides a +data type emph\{historydate\}. There is not a very satisfying answer to its +disuse. +All that can be said is that the use of data types different than the string +leads later on to problems in the convergence between the search engine and the +repository framework. These issues seem to be well known and can be followed on +github. + \chapter{Controller Adjustments} \label{\detokenize{source/controller:controller-adjustments}}\label{\detokenize{source/controller::doc}} \section{General Principle of Operation} \label{\detokenize{source/controller:general-principle-of-operation}} +Figure ref\{fig:classDiag\} illustrates the dependencies of the five java classes that were integrated to add the morphilo +functionality defined in the default package emph\{custom.mycore.addons.morphilo\}. The general principle of operation +is the following. The handling of data search, upload, saving, and user +authentification is fully left to the MyCoRe functionality that is completely +implemented. The class emph\{ProcessCorpusServlet.java\} receives a request from the webinterface to process an uploaded file, +i.e. a simple text corpus, and it checks if any of the words are available in the master database. All words that are not +listed in the master database are written to an extra file. These are the words that have to be manually annotated. At the end, the +servlet sends a response back to the user interface. In case of all words are contained in the master, an xml file is generated from the +master database that includes all annotated words of the original corpus. Usually this will not be the case for larger textfiles. +So if some words are not in the master, the user will get the response to initiate the manual annotation process. + +The manual annotation process is processed by the class +emph\{\{Tag-Corpus-Serv-let-.ja-va\}\}, which will build a JDOM object for the first word in the extra file. +This is done by creating an object of the emph\{JDOMorphilo.java\} class. This class, in turn, will use the methods of +emph\{AffixStripper.java\} that make simple, but reasonable, suggestions on the word structure. This JDOM object is then +given as a response back to the user. It is presented as a form, in which the user can make changes. This is necessary +because the word structure algorithm of emph\{AffixStripper.java\} errs in some cases. Once the user agrees on the +suggestions or on his or her corrections, the JDOM object is saved as an xml that is only searchable, visible, and +changeable by the authenicated user (and the administrator), another file containing all processed words is created or +updated respectively and the emph\{TagCorpusServlet.java\} servlet will restart until the last word in the extra list is +processed. This enables the user to stop and resume her or his annotation work at a later point in time. The +emph\{TagCorpusServlet\} will call methods from emph\{ProcessCorpusServlet.java\} to adjust the content of the extra +files harboring the untagged words. If this file is empty, and only then, it is replaced by the file comprising all words +from the original text file, both the ones from the master database and the ones that are annotated by the user, +in an annotated xml representation. + +Each time emph\{ProcessCorpusServlet.java\} is instantiated, it also instantiates emph\{QualityControl.java\}. This class checks if a +new word can be transferred to the master database. The algorithm can be freely adopted to higher or lower quality standards. +In its present configuration, a method tests at a limit of 20 different +registered users agreeing on the annotation of the same word. More specifically, +if 20 JDOM objects are identical except in the attribute field emph\{occurrences\} in the metadata node, the JDOM object becomes +part of the master. The latter is easily done by changing the attribute emph\{creator\} from the user name +to emph\{{\color{red}\bfseries{}{}`{}`}administrator’‘\} in the service node. This makes the dataset part of the master database. Moreover, the emph\{occurrences\} +attribute is updated by adding up all occurrences of the word that stem from +different text corpora of the same time range. +begin\{landscape\} +\begin{quote} +\begin{description} +\item[{begin\{figure\}}] \leavevmode +centering +includegraphics{[}scale=0.55{]}\{morphilo\_uml.png\} +caption\{Class Diagram Morphilo\} +label\{fig:classDiag\} + +\end{description} + +end\{figure\} +\end{quote} + +end\{landscape\} + + +\section{Conceptualization} +\label{\detokenize{source/controller:conceptualization}} +The controller component is largely +specified and ready to use in some hundred or so java classes handling the +logic of the search such as indexing, but also dealing with directories and +files as saving, creating, deleting, and updating files. +Moreover, a rudimentary user management comprising different roles and +rights is offered. The basic technology behind the controller’s logic is the +servlet. As such all new code has to be registered as a servlet in the +web-fragment.xml (here the Apache Tomcat container) as listing ref\{lst:webfragment\} shows. + +begin\{lstlisting\}{[}language=XML,caption=\{Servlet Registering in the +web-fragment.xml (excerpt)\},label=lst:webfragment,escapechar=\textbar{}{]} +\textless{}servlet\textgreater{} +\begin{quote} + +\textless{}servlet-name\textgreater{}ProcessCorpusServlet\textless{}/servlet-name\textgreater{} +\textless{}servlet-class\textgreater{}custom.mycore.addons.morphilo.ProcessCorpusServlet\textless{}/servlet-class\textgreater{} +\end{quote} + +\textless{}/servlet\textgreater{} +\textless{}servlet-mapping\textgreater{} +\begin{quote} + +\textless{}servlet-name\textgreater{}ProcessCorpusServlet\textless{}/servlet-name\textgreater{} +\textless{}url-pattern\textgreater{}/servlets/object/process\textless{}/url-pattern\textgreater{}\textbar{}label\{ln:process\}\textbar{} +\end{quote} + +\textless{}/servlet-mapping\textgreater{} +\textless{}servlet\textgreater{} +\begin{quote} + +\textless{}servlet-name\textgreater{}TagCorpusServlet\textless{}/servlet-name\textgreater{} +\textless{}servlet-class\textgreater{}custom.mycore.addons.morphilo.TagCorpusServlet\textless{}/servlet-class\textgreater{} +\end{quote} + +\textless{}/servlet\textgreater{} +\textless{}servlet-mapping\textgreater{} +\begin{quote} + +\textless{}servlet-name\textgreater{}TagCorpusServlet\textless{}/servlet-name\textgreater{} +\textless{}url-pattern\textgreater{}/servlets/object/tag\textless{}/url-pattern\textgreater{}\textbar{}label\{ln:tag\}\textbar{} +\end{quote} + +\textless{}/servlet-mapping\textgreater{} +end\{lstlisting\} + +Now, the logic has to be extended by the specifications analyzed in chapter +ref\{chap:concept\} on conceptualization. More specifically, some +classes have to be added that take care of analyzing words +(emph\{AffixStripper.java, InflectionEnum.java, SuffixEnum.java, +PrefixEnum.java\}), extracting the relevant words from the text and checking the +uniqueness of the text (emph\{ProcessCorpusServlet.java\}), make reasonable +suggestions on the annotation (emph\{TagCorpusServlet.java\}), build the object +of each annotated word (emph\{JDOMorphilo.java\}), and check on the quality by applying +statistical models (emph\{QualityControl.java\}). + + +\section{Implementation} +\label{\detokenize{source/controller:implementation}} +Having taken a bird’s eye perspective in the previous chapter, it is now time to take a look at the specific implementation at the level +of methods. Starting with the main servlet, emph\{ProcessCorpusServlet.java\}, the class defines four getter method: +renewcommand\{labelenumi\}\{(theenumi)\} +begin\{enumerate\} +\begin{quote} + +itemlabel\{itm:geturl\} public String getURLParameter(MCRServletJob, String) +itemlabel\{itm:getcorp\} public String getCorpusMetadata(MCRServletJob, String) +itemlabel\{itm:getcont\} public ArrayList\textless{}String\textgreater{} getContentFromFile(MCRServletJob, String) +itemlabel\{itm:getderiv\} public Path getDerivateFilePath(MCRServletJob, String) +itemlabel\{itm:now\} public int getNumberOfWords(MCRServletJob job, String) +\end{quote} + +end\{enumerate\} +Since each servlet in MyCoRe extends the class MCRServlet, it has access to MCRServletJob, from which the http requests and responses +can be used. This is the first argument in the above methods. The second argument of method (ref\{itm:geturl\}) specifies the name of an url parameter, i.e. +the object id or the id of the derivate. The method returns the value of the given parameter. Typically MyCoRe uses the url to exchange +these ids. The second method provides us with the value of a data field in the xml document. So the string defines the name of an attribute. +emph\{getContentFromFile(MCRServletJob, String)\} returns the words as a list from a file when given the filename as a string. +The getter listed in ref\{itm:getderiv\}), returns the Path from the MyCoRe repository when the name of +the file is specified. And finally, method (ref\{itm:now\}) returns the number of words by simply returning +emph\{getContentFromFile(job, fileName).size()\}. + +There are two methods in every MyCoRe-Servlet that have to be overwritten, +emph\{protected void render(MCRServletJob, Exception)\}, which redirects the requests as emph\{POST\} or emph\{GET\} responds, and +emph\{protected void think(MCRServletJob)\}, in which the logic is implemented. Since the latter is important to understand the +core idea of the Morphilo algorithm, it is displayed in full length in source code ref\{src:think\}. + +begin\{lstlisting\}{[}language=java,caption=\{The overwritten think method\},label=src:think,escapechar=\textbar{}{]} +protected void think(MCRServletJob job) throws Exception +\{ +\begin{quote} + +this.job = job; +String dateFromCorp = getCorpusMetadata(job, “def.datefrom”); +String dateUntilCorp = getCorpusMetadata(job, “def.dateuntil”); +String corpID = getURLParameter(job, “objID”); +String derivID = getURLParameter(job, “id”); + +//if NoW is 0, fill with anzWords +MCRObject helpObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(corpID));\textbar{}label\{ln:bugfixstart\}\textbar{} +Document jdomDocHelp = helpObj.createXML(); +XPathFactory xpfacty = XPathFactory.instance(); +XPathExpression\textless{}Element\textgreater{} xpExp = xpfacty.compile(“//NoW”, Filters.element()); +Element elem = xpExp.evaluateFirst(jdomDocHelp); +//fixes transferred morphilo data from previous stand alone project +int corpussize = getNumberOfWords(job, “”); +if (Integer.parseInt(elem.getText()) != corpussize) +\{ +\begin{quote} + +elem.setText(Integer.toString(corpussize)); +helpObj = new MCRObject(jdomDocHelp); +MCRMetadataManager.update(helpObj); +\end{quote} + +\}\textbar{}label\{ln:bugfixend\}\textbar{} + +//Check if the uploaded corpus was processed before +SolrClient slr = MCRSolrClientFactory.getSolrClient();\textbar{}label\{ln:solrstart\}\textbar{} +SolrQuery qry = new SolrQuery(); +qry.setFields(“korpusname”, “datefrom”, “dateuntil”, “NoW”, “id”); +qry.setQuery(“datefrom:” + dateFromCorp + ” AND dateuntil:” + dateUntilCorp + ” AND NoW:” + corpussize); +SolrDocumentList rslt = slr.query(qry).getResults();\textbar{}label\{ln:solrresult\}\textbar{} + +Boolean incrOcc = true; +// if resultset contains only one, then it must be the newly created corpus +if (slr.query(qry).getResults().getNumFound() \textgreater{} 1) +\{ +\begin{quote} + +incrOcc = false; +\end{quote} + +\}\textbar{}label\{ln:solrend\}\textbar{} + +//match all words in corpus with morphilo (creator=administrator) and save all words that are not in morphilo DB in leftovers +ArrayList\textless{}String\textgreater{} leftovers = new ArrayList\textless{}String\textgreater{}(); +ArrayList\textless{}String\textgreater{} processed = new ArrayList\textless{}String\textgreater{}(); + +leftovers = getUnknownWords(getContentFromFile(job, “”), dateFromCorp, dateUntilCorp, “”, incrOcc, incrOcc, false);\textbar{}label\{ln:callkeymeth\}\textbar{} + +//write all words of leftover in file as derivative to respective corpmeta dataset +MCRPath root = MCRPath.getPath(derivID, “/”);\textbar{}label\{ln:filesavestart\}\textbar{} +Path fn = getDerivateFilePath(job, “”).getFileName(); +Path p = root.resolve(“untagged-” + fn); +Files.write(p, leftovers);\textbar{}label\{ln:filesaveend\}\textbar{} + +//create a file for all words that were processed +Path procWds = root.resolve(“processed-” + fn); +Files.write(procWds, processed); +\end{quote} + +\} +end\{lstlisting\} +Using the above mentioned getter methods, the emph\{think\} method assigns values to the object ID, needed to get the xml document +that contain the corpus metadata, the file ID, and the beginning and starting dates from the corpus to be analyzed. Lines ref\{ln:bugfixstart\} +through ref\{ln:bugfixend\} show how to access a mycore object as an xml document, a procedure that will be used in different variants +throughout this implementation. +By means of the object ID, the respective corpus is identified and a JDOM document is constructed, which can then be accessed +by XPath. The XPath factory instances are collections of the xml nodes. In the present case, it is save to assume that only one element +of emph\{NoW\} is available (see corpus datamodel listing ref\{lst:corpusdatamodel\} with \$maxOccurs=‘1’\$). So we do not have to loop through +the collection, but use the first node named emph\{NoW\}. The if-test checks if the number of words of the uploaded file is the +same as the number written in the document. When the document is initially created by the MyCoRe logic it was configured to be zero. +If unequal, the setText(String) method is used to write the number of words of the corpus to the document. + +Lines ref\{ln:solrstart\}\textendash{}ref\{ln:solrend\} reveal the second important ingredient, i.e. controlling the search engine. First, a solr +client and a query are initialized. Then, the output of the result set is defined by giving the fields of interest of the document. +In the case at hand, it is the id, the name of the corpus, the number of words, and the beginnig and ending dates. With emph\{setQuery\} +it is possible to assign values to some or all of these fields. Finally, emph\{getResults()\} carries out the search and writes +all hits to a emph\{SolrDocumentList\} (line ref\{ln:solrresult\}). The test that follows is really only to set a Boolean +encoding if the number of occurrences of that word in the master should be updated. To avoid multiple counts, +incrementing the word frequency is only done if it is a new corpus. + +In line ref\{ln:callkeymeth\} emph\{getUnknownWords(ArrayList, String, String, String, Boolean, Boolean, Boolean)\} is called and +returned as a list of words. This method is key and will be discussed in depth below. Finally, lines +ref\{ln:filesavestart\}\textendash{}ref\{ln:filesaveend\} show how to handle file objects in MyCoRe. Using the file ID, the root path and the name +of the first file in that path are identified. Then, a second file starting with {\color{red}\bfseries{}{}`{}`}untagged’’ is created and all words returned from +the emph\{getUnknownWords\} is written to that file. By the same token an empty file is created (in the last two lines of the emph\{think\}-method), +in which all words that are manually annotated will be saved. + +In a refactoring phase, the method emph\{getUnknownWords(ArrayList, String, String, String, Boolean, Boolean, Boolean)\} could be subdivided into +three methods: for each Boolean parameter one. In fact, this method handles more than one task. This is mainly due to multiple code avoidance. +\%this is just wrong because no resultset will substantially be more than 10-20 +\%In addition, for large text files this method would run into efficiency problems if the master database also reaches the intended size of about +\%\$100,000\$ entries and beyond because +In essence, an outer loop runs through all words of the corpus and an inner loop runs through all hits in the solr result set. Because the result +set is supposed to be small, approximately between \$10-20\$ items, efficiency +problems are unlikely to cause a problem, although there are some more loops running through collection of about the same sizes. +\%As the hits naturally grow larger with an increasing size of the data base, processing time will rise exponentially. +Since each word is identified on the basis of its projected word type, the word form, and the time range it falls into, it is these variables that +have to be checked for existence in the documents. If not in the xml documents, +emph\{null\} is returned and needs to be corrected. Moreover, user authentification must be considered. There are three different XPaths that are relevant. +begin\{itemize\} +\begin{quote} + +item{[}-{]} emph\{//service/servflags/servflag{[}@type=’createdby’{]}\} to test for the correct user +item{[}-{]} emph\{//morphiloContainer/morphilo\} to create the annotated document +item{[}-{]} emph\{//morphiloContainer/morphilo/w\} to set occurrences or add a link +\end{quote} + +end\{itemize\} + +As an illustration of the core functioning of this method, listing ref\{src:getUnknowWords\} is given. +begin\{lstlisting\}{[}language=java,caption=\{Mode of Operation of getUnknownWords Method\},label=src:getUnknowWords,escapechar=\textbar{}{]} +public ArrayList\textless{}String\textgreater{} getUnknownWords( +\begin{quote} + +ArrayList\textless{}String\textgreater{} corpus, +String timeCorpusBegin, +String timeCorpusEnd, +String wdtpe, +Boolean setOcc, +Boolean setXlink, +Boolean writeAllData) throws Exception +\{ +\begin{quote} + +String currentUser = MCRSessionMgr.getCurrentSession().getUserInformation().getUserID(); +ArrayList lo = new ArrayList(); + +for (int i = 0; i \textless{} corpus.size(); i++) +\{ +\begin{quote} + +SolrClient solrClient = MCRSolrClientFactory.getSolrClient(); +SolrQuery query = new SolrQuery(); +query.setFields(“w”,”occurrence”,”begin”,”end”, “id”, “wordtype”); +query.setQuery(corpus.get(i)); +query.setRows(50); //more than 50 items are extremely unlikely +SolrDocumentList results = solrClient.query(query).getResults(); +Boolean available = false; +for (int entryNum = 0; entryNum \textless{} results.size(); entryNum++) +\{ +\begin{quote} + +… +// update in MCRMetaDataManager +String mcrIDString = results.get(entryNum).getFieldValue(“id”).toString(); +//MCRObjekt auslesen und JDOM-Document erzeugen: +MCRObject mcrObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(mcrIDString)); +Document jdomDoc = mcrObj.createXML(); +… +//check and correction for word type +… +//checkand correction time: timeCorrect +… +//check if user correct: isAuthorized +\end{quote} + +… +XPathExpression\textless{}Element\textgreater{} xp = xpfac.compile(“//morphiloContainer/morphilo/w”, Filters.element()); +//Iterates w-elements and increments occurrence attribute if setOcc is true +for (Element e : xp.evaluate(jdomDoc)) +\{ +\begin{quote} +\begin{description} +\item[{//wenn Rechte da sind und Worttyp nirgends gegeben oder gleich ist}] \leavevmode\begin{quote} +\begin{description} +\item[{if (isAuthorized \&\& timeCorrect}] \leavevmode +\&\& ((e.getAttributeValue(“wordtype”) == null \&\& wdtpe.equals(“”)) +\textbar{}\textbar{} e.getAttributeValue(“wordtype”).equals(wordtype))) // nur zur Vereinheitlichung + +\end{description} +\end{quote} +\begin{description} +\item[{\{}] \leavevmode\begin{quote} + +int oc = -1; +available = true;\textbar{}label\{ln:available\}\textbar{} +\end{quote} +\begin{description} +\item[{try}] \leavevmode\begin{quote} +\begin{description} +\item[{\{}] \leavevmode +//adjust occurrence Attribut +if (setOcc) + +\end{description} +\end{quote} +\begin{description} +\item[{\{}] \leavevmode\begin{description} +\item[{oc = Integer.parseInt(e.getAttributeValue(“occurrence”));}] \leavevmode\begin{quote} + +e.setAttribute(“occurrence”, Integer.toString(oc + 1)); +\end{quote} + +\} + +\end{description} + +\item[{//write morphilo-ObjectID in xml of corpmeta}] \leavevmode\begin{quote} +\begin{quote} +\begin{quote} + +if (setXlink) +\{ +\begin{quote} + +Namespace xlinkNamespace = Namespace.getNamespace(“xlink”, “\sphinxurl{http://www.w3.org/1999/xlink}”);\textbar{}label\{ln:namespace\}\textbar{} +MCRObject corpObj = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(getURLParameter(job, “objID”))); +Document corpDoc = corpObj.createXML(); +XPathExpression\textless{}Element\textgreater{} xpathEx = xpfac.compile(“//corpuslink”, Filters.element()); +Element elm = xpathEx.evaluateFirst(corpDoc); +elm.setAttribute(“href” , mcrIDString, xlinkNamespace); +\end{quote} + +\} +mcrObj = new MCRObject(jdomDoc);\textbar{}label\{ln:updatestart\}\textbar{} +MCRMetadataManager.update(mcrObj); +QualityControl qc = new QualityControl(mcrObj);\textbar{}label\{ln:updateend\}\textbar{} +\end{quote} + +\} +catch(NumberFormatException except) +\{ +\begin{quote} + +// ignore +\end{quote} + +\} +\end{quote} + +\} +\end{quote} + +\} + +\end{description} + +\end{description} + +\end{description} + +\end{description} + +if (!available) // if not available in datasets under the given conditions {\color{red}\bfseries{}\textbar{}\textbackslash{}label\{ln:notavailable\}\textbar{}} +\{ +\begin{quote} + +lo.add(corpus.get(i)); +\end{quote} + +\} +\end{quote} + +\} +return lo; +\end{quote} + +\} +\end{quote} +\end{quote} + +end\{lstlisting\} +As can be seen from the functionality of listing ref\{src:getUnknowWords\}, getting the unknown words of a corpus, is rather a side effect for the equally named method. +More precisely, a Boolean (line ref\{ln:available\}) is set when the document is manipulated otherwise because it is clear that the word must exist then. +If the Boolean remains false (line ref\{ln:notavailable\}), the word is put on the list of words that have to be annotated manually. As already explained above, the +first loop runs through all words (corpus) and the following lines a solr result set is created. This set is also looped through and it is checked if the time range, +the word type and the user are authorized. In the remainder, the occurrence attribute of the morphilo document can be incremented (setOcc is true) or/and the word is linked to the +corpus meta data (setXlink is true). While all code lines are equivalent with +what was explained in listing ref\{src:think\}, it suffices to focus on an +additional name space, i.e. +{\color{red}\bfseries{}{}`{}`}xlink’’ has to be defined (line ref\{ln:namespace\}). Once the linking of word +and corpus is set, the entire MyCoRe object has to be updated. This is done by the functionality of the framework (lines ref\{ln:updatestart\}\textendash{}ref\{ln:updateend\}). +At the end, an instance of emph\{QualityControl\} is created. + +\%QualityControl +The class emph\{QualityControl\} is instantiated with a constructor +depicted in listing ref\{src:constructQC\}. +begin\{lstlisting\}{[}language=java,caption=\{Constructor of QualityControl.java\},label=src:constructQC,escapechar=\textbar{}{]} +private MCRObject mycoreObject; +/* Constructor calls method to carry out quality control, i.e. if at least 20 +\begin{quote} +\begin{itemize} +\item {} +different users agree 100\% on the segments of the word under investigation + +\end{itemize} + +{\color{red}\bfseries{}*}/ +\end{quote} + +public QualityControl(MCRObject mycoreObject) throws Exception +\{ +\begin{quote} + +this.mycoreObject = mycoreObject; +if (getEqualObjectNumber() \textgreater{} 20) +\{ +\begin{quote} + +addToMorphiloDB(); +\end{quote} + +\} +\end{quote} + +\} +end\{lstlisting\} +The constructor takes an MyCoRe object, a potential word candidate for the +master data base, which is assigned to a private class variable because the +object is used though not changed by some other java methods. +More importantly, there are two more methods: emph\{getEqualNumber()\} and +emph\{addToMorphiloDB()\}. While the former initiates a process of counting and +comparing objects, the latter is concerned with calculating the correct number +of occurrences from different, but not the same texts, and generating a MyCoRe object with the same content but with two different flags in the emph\{//service/servflags/servflag\}-node, i.e. emph\{createdby=’administrator’\} and emph\{state=’published’\}. +And of course, the emph\{occurrence\} attribute is set to the newly calculated value. The logic corresponds exactly to what was explained in +listing ref\{src:think\} and will not be repeated here. The only difference are the paths compiled by the XPathFactory. They are +begin\{itemize\} +\begin{quote} + +item{[}-{]} emph\{//service/servflags/servflag{[}@type=’createdby’{]}\} and +item{[}-{]} emph\{//service/servstates/servstate{[}@classid=’state’{]}\}. +\end{quote} + +end\{itemize\} +It is more instructive to document how the number of occurrences is calculated. There are two steps involved. First, a list with all mycore objects that are +equal to the object which the class is instantiated with ({\color{red}\bfseries{}{}`{}`}mycoreObject’’ in listing ref\{src:constructQC\}) is created. This list is looped and all occurrence +attributes are summed up. Second, all occurrences from equal texts are substracted. Equal texts are identified on the basis of its meta data and its derivate. +There are some obvious shortcomings of this approach, which will be discussed in chapter ref\{chap:results\}, section ref\{sec:improv\}. Here, suffice it to +understand the mode of operation. Listing ref\{src:equalOcc\} shows a possible solution. +begin\{lstlisting\}{[}language=java,caption=\{Occurrence Extraction from Equal Texts (1)\},label=src:equalOcc,escapechar=\textbar{}{]} +/* returns number of Occurrences if Objects are equal, zero otherwise +\begin{quote} + +{\color{red}\bfseries{}*}/ +\end{quote} + +private int getOccurrencesFromEqualTexts(MCRObject mcrobj1, MCRObject mcrobj2) throws SAXException, IOException +\{ +\begin{quote} + +int occurrences = 1; +//extract corpmeta ObjectIDs from morphilo-Objects +String crpID1 = getAttributeValue(“//corpuslink”, “href”, mcrobj1); +String crpID2 = getAttributeValue(“//corpuslink”, “href”, mcrobj2); +//get these two corpmeta Objects +MCRObject corpo1 = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(crpID1)); +MCRObject corpo2 = MCRMetadataManager.retrieveMCRObject(MCRObjectID.getInstance(crpID2)); +//are the texts equal? get list of ‘processed-words’ derivate +String corp1DerivID = getAttributeValue(“//structure/derobjects/derobject”, “href”, corpo1); +String corp2DerivID = getAttributeValue(“//structure/derobjects/derobject”, “href”, corpo2); + +ArrayList result = new ArrayList(getContentFromFile(corp1DerivID, “”));\textbar{}label\{ln:writeContent\}\textbar{} +result.remove(getContentFromFile(corp2DerivID, “”));\textbar{}label\{ln:removeContent\}\textbar{} +if (result.size() == 0) // the texts are equal +\{ +\begin{quote} + +// extract occurrences of one the objects +occurrences = Integer.parseInt(getAttributeValue(“//morphiloContainer/morphilo/w”, “occurrence”, mcrobj1)); +\end{quote} + +\} +else +\{ +\begin{quote} + +occurrences = 0; //project metadata happened to be the same, but texts are different +\end{quote} + +\} +return occurrences; +\end{quote} + +\} +end\{lstlisting\} +In this implementation, the ids from the emph\{corpmeta\} data model are accessed via the xlink attribute in the morphilo documents. +The method emph\{getAttributeValue(String, String, MCRObject)\} does exactly the same as demonstrated earlier (see from line ref\{ln:namespace\} +on in listing ref\{src:getUnknowWords\}). The underlying logic is that the texts are equal if exactly the same number of words were uploaded. +So all words from one file are written to a list (line ref\{ln:writeContent\}) and words from the other file are removed from the +very same list (line ref\{ln:removeContent\}). If this list is empty, then the exact same number of words must have been in both files and the occurrences +are adjusted accordingly. Since this method is called from another private method that only contains a loop through all equal objects, one gets +the occurrences from all equal texts. For reasons of confirmability, the looping method is also given: +begin\{lstlisting\}{[}language=java,caption=\{Occurrence Extraction from Equal Texts (2)\},label=src:equalOcc2,escapechar=\textbar{}{]} +private int getOccurrencesFromEqualTexts() throws Exception +\{ +\begin{quote} + +ArrayList\textless{}MCRObject\textgreater{} equalObjects = new ArrayList\textless{}MCRObject\textgreater{}(); +equalObjects = getAllEqualMCRObjects(); +int occurrences = 0; +for (MCRObject obj : equalObjects) +\{ +\begin{quote} + +occurrences = occurrences + getOccurrencesFromEqualTexts(mycoreObject, obj); +\end{quote} + +\} +return occurrences; +\end{quote} + +\} +end\{lstlisting\} + +Now, the constructor in listing ref\{src:constructQC\} reveals another method that rolls out an equally complex concatenation of procedures. +As implied above, emph\{getEqualObjectNumber()\} returns the number of equally annotated words. It does this by falling back to another +method from which the size of the returned list is calculated (emph\{getAllEqualMCRObjects().size()\}). Hence, we should care about +emph\{getAllEqualMCRObjects()\}. This method really has the same design as emph\{int getOccurrencesFromEqualTexts()\} in listing ref\{src:equalOcc2\}. +The difference is that another method (emph\{Boolean compareMCRObjects(MCRObject, MCRObject, String)\}) is used within the loop and +that all equal objects are put into the list of MyCoRe objects that are returned. If this list comprises more than 20 +entries,footnote\{This number is somewhat arbitrary. It is inspired by the sample size n in t-distributed data.\} the respective document +will be integrated in the master data base by the process described above. +The comparator logic is shown in listing ref\{src:compareMCR\}. +begin\{lstlisting\}{[}language=java,caption=\{Comparison of MyCoRe objects\},label=src:compareMCR,escapechar=\textbar{}{]} +private Boolean compareMCRObjects(MCRObject mcrobj1, MCRObject mcrobj2, String xpath) throws SAXException, IOException +\{ +\begin{quote} + +Boolean isEqual = false; +Boolean beginTime = false; +Boolean endTime = false; +Boolean occDiff = false; +Boolean corpusDiff = false; + +String source = getXMLFromObject(mcrobj1, xpath); +String target = getXMLFromObject(mcrobj2, xpath); + +XMLUnit.setIgnoreAttributeOrder(true); +XMLUnit.setIgnoreComments(true); +XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true); +XMLUnit.setIgnoreWhitespace(true); +XMLUnit.setNormalizeWhitespace(true); + +//differences in occurrences, end, begin should be ignored +try +\{ +\begin{quote} + +Diff xmlDiff = new Diff(source, target); +DetailedDiff dd = new DetailedDiff(xmlDiff); +//counters for differences +int i = 0; +int j = 0; +int k = 0; +int l = 0; +// list containing all differences +List differences = dd.getAllDifferences();\textbar{}label\{ln:difflist\}\textbar{} +for (Object object : differences) +\{ +\begin{quote} + +Difference difference = (Difference) object; +\sphinxhref{mailto://@begin}{//@begin},@end,… node is not in the difference list if the count is 0 +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@begin”)) i++;\textbar{}label\{ln:diffbegin\}\textbar{} +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@end”)) j++; +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@occurrence”)) k++; +if (difference.getControlNodeDetail().getXpathLocation().endsWith(“@corpus”)) l++;\textbar{}label\{ln:diffend\}\textbar{} +//@begin and @end have different values: they must be checked if they fall right in the allowed time range +if ( difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) +\begin{quote} + +\&\& difference.getControlNodeDetail().getXpathLocation().endsWith(“@begin”) +\&\& (Integer.parseInt(difference.getControlNodeDetail().getValue()) \textless{} Integer.parseInt(difference.getTestNodeDetail().getValue())) ) +\end{quote} +\begin{description} +\item[{\{}] \leavevmode +beginTime = true; + +\end{description} + +\} +if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) +\begin{quote} + +\&\& difference.getControlNodeDetail().getXpathLocation().endsWith(“@end”) +\&\& (Integer.parseInt(difference.getControlNodeDetail().getValue()) \textgreater{} Integer.parseInt(difference.getTestNodeDetail().getValue())) ) +\end{quote} +\begin{description} +\item[{\{}] \leavevmode +endTime = true; + +\end{description} + +\} +//attribute values of @occurrence and @corpus are ignored if they are different +if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) +\begin{quote} + +\&\& difference.getControlNodeDetail().getXpathLocation().endsWith(“@occurrence”)) +\end{quote} +\begin{description} +\item[{\{}] \leavevmode +occDiff = true; + +\end{description} + +\} +if (difference.getControlNodeDetail().getXpathLocation().equals(difference.getTestNodeDetail().getXpathLocation()) +\begin{quote} + +\&\& difference.getControlNodeDetail().getXpathLocation().endsWith(“@corpus”)) +\end{quote} +\begin{description} +\item[{\{}] \leavevmode +corpusDiff = true; + +\end{description} + +\} +\end{quote} + +\} +//if any of @begin, @end … is identical set Boolean to true +if (i == 0) beginTime = true;\textbar{}label\{ln:zerobegin\}\textbar{} +if (j == 0) endTime = true; +if (k == 0) occDiff = true; +if (l == 0) corpusDiff = true;\textbar{}label\{ln:zeroend\}\textbar{} +//if the size of differences is greater than the number of changes admitted in @begin, @end … something else must be different +if (beginTime \&\& endTime \&\& occDiff \&\& corpusDiff \&\& (i + j + k + l) == dd.getAllDifferences().size()) isEqual = true;\textbar{}label\{ln:diffsum\}\textbar{} +\} +catch (SAXException e) +\{ +\begin{quote} + +e.printStackTrace(); +\end{quote} + +\} +catch (IOException e) +\{ +\begin{quote} + +e.printStackTrace(); +\end{quote} + +\} +\end{quote} + +return isEqual; +\end{quote} + +\} +end\{lstlisting\} +In this method, XMLUnit is heavily used to make all necessary node comparisons. The matter becomes more complicated, however, if some attributes +are not only ignored, but evaluated according to a given definition as it is the case for the time range. If the evaluator and builder classes are +not to be overwritten entirely because needed for evaluating other nodes of the +xml document, the above solution appears a bit awkward. So there is potential for improvement before the production version is to be programmed. + +XMLUnit provides us with a +list of the differences of the two documents (see line ref\{ln:difflist\}). There are four differences allowed, that is, the attributes emph\{occurrence\}, +emph\{corpus\}, emph\{begin\}, and emph\{end\}. For each of them a Boolean variable is set. Because any of the attributes could also be equal to the master +document and the difference list only contains the actual differences, one has to find a way to define both, equal and different, for the attributes. +This could be done by ignoring these nodes. Yet, this would not include testing if the beginning and ending dates fall into the range of the master +document. Therefore the attributes are counted as lines ref\{ln:diffbegin\} through ref\{ln:diffend\} reveal. If any two documents +differ in some of the four attributes just specified, then the sum of the counters (line ref\{ln:diffsum\}) should not be greater than the collected differences +by XMLUnit. The rest of the if-tests assign truth values to the respective +Booleans. It is probably worth mentioning that if all counters are zero (lines +ref\{ln:zerobegin\}-ref\{ln:zeroend\}) the attributes and values are identical and hence the Boolean has to be set explicitly. Otherwise the test in line ref\{ln:diffsum\} would fail. + +\%TagCorpusServlet +Once quality control (explained in detail further down) has been passed, it is +the user’s turn to interact further. By clicking on the option emph\{Manual tagging\}, the emph\{TagCorpusServlet\} will be callled. This servlet instantiates +emph\{ProcessCorpusServlet\} to get access to the emph\{getUnknownWords\}-method, which delivers the words still to be +processed and which overwrites the content of the file starting with emph\{untagged\}. For the next word in emph\{leftovers\} a new MyCoRe object is created +using the JDOM API and added to the file beginning with emph\{processed\}. In line ref\{ln:tagmanu\} of listing ref\{src:tagservlet\}, the previously defined +entry mask is called, with which the proposed word structure could be confirmed or changed. How the word structure is determined will be shown later in +the text. +begin\{lstlisting\}{[}language=java,caption=\{Manual Tagging Procedure\},label=src:tagservlet,escapechar=\textbar{}{]} +… +if (!leftovers.isEmpty()) +\{ +\begin{quote} + +ArrayList\textless{}String\textgreater{} processed = new ArrayList\textless{}String\textgreater{}(); +//processed.add(leftovers.get(0)); +JDOMorphilo jdm = new JDOMorphilo(); +MCRObject obj = jdm.createMorphiloObject(job, leftovers.get(0));\textbar{}label\{ln:jdomobject\}\textbar{} +//write word to be annotated in process list and save it +Path filePathProc = pcs.getDerivateFilePath(job, “processed”).getFileName(); +Path proc = root.resolve(filePathProc); +processed = pcs.getContentFromFile(job, “processed”); +processed.add(leftovers.get(0)); +Files.write(proc, processed); + +//call entry mask for next word +tagUrl = prop.getBaseURL() + “content/publish/morphilo.xed?id=” + obj.getId();\textbar{}label\{ln:tagmanu\}\textbar{} +\end{quote} + +\} +else +\{ +\begin{quote} + +//initiate process to give a complete tagged file of the original corpus +//if untagged-file is empty, match original file with morphilo +//creator=administrator OR creator=username and write matches in a new file +ArrayList\textless{}String\textgreater{} complete = new ArrayList\textless{}String\textgreater{}(); +ProcessCorpusServlet pcs2 = new ProcessCorpusServlet(); +complete = pcs2.getUnknownWords( +\begin{quote} + +pcs2.getContentFromFile(job, “”), //main corpus file +pcs2.getCorpusMetadata(job, “def.datefrom”), +pcs2.getCorpusMetadata(job, “def.dateuntil”), +“”, //wordtype +false, +false, +true); +\end{quote} + +Files.delete(p); +MCRXMLFunctions mdm = new MCRXMLFunctions(); +String mainFile = mdm.getMainDocName(derivID); +Path newRoot = root.resolve(“tagged-” + mainFile); +Files.write(newRoot, complete); + +//return to Menu page +tagUrl = prop.getBaseURL() + “receive/” + corpID; +\end{quote} + +\} +end\{lstlisting\} +At the point where no more items are in emph\{leftsovers\} the emph\{getUnknownWords\}-method is called whereas the last Boolean parameter +is set true. This indicates that the array list containing all available and relevant data to the respective user is returned as seen in +the code snippet in listing ref\{src:writeAll\}. +begin\{lstlisting\}{[}language=java,caption=\{Code snippet to deliver all data to the user\},label=src:writeAll,escapechar=\textbar{}{]} +… +// all data is written to lo in TEI +if (writeAllData \&\& isAuthorized \&\& timeCorrect) +\{ +\begin{quote} + +XPathExpression\textless{}Element\textgreater{} xpath = xpfac.compile(“//morphiloContainer/morphilo”, Filters.element()); +for (Element e : xpath.evaluate(jdomDoc)) +\{ +\begin{quote} + +XMLOutputter outputter = new XMLOutputter(); +outputter.setFormat(Format.getPrettyFormat()); +lo.add(outputter.outputString(e.getContent())); +\end{quote} + +\} +\end{quote} + + +\subsection{\}} +\label{\detokenize{source/controller:id13}} +end\{lstlisting\} +The complete list (emph\{lo\}) is written to yet a third file starting with emph\{tagged\} and finally returned to the main project webpage. + +\%JDOMorphilo +The interesting question is now where does the word structure come from, which is filled in the entry mask as asserted above. +In listing ref\{src:tagservlet\} line ref\{ln:jdomobject\}, one can see that a JDOM object is created and the method +emph\{createMorphiloObject(MCRServletJob, String)\} is called. The string parameter is the word that needs to be analyzed. +Most of the method is a mere application of the JDOM API given the data model in chapter ref\{chap:concept\} section +ref\{subsec:datamodel\} and listing ref\{lst:worddatamodel\}. That means namespaces, elements and their attributes are defined in the correct +order and hierarchy. + +To fill the elements and attributes with text, i.e. prefixes, suffixes, stems, etc., a Hashmap \textendash{} containing the morpheme as +key and its position as value \textendash{} are created that are filled with the results from an AffixStripper instantiation. Depending on how many prefixes +or suffixes respectively are put in the hashmap, the same number of xml elements are created. As a final step, a valid MyCoRe id is generated using +the existing MyCoRe functionality, the object is created and returned to the TagCorpusServlet. + +\%AffixStripper explanation +Last, the analyses of the word structure will be considered. It is implemented +in the emph\{AffixStripper.java\} file. +All lexical affix morphemes and their allomorphs as well as the inflections were extracted from the +OEDfootnote\{Oxford English Dictionary \sphinxurl{http://www.oed.com/}\} and saved as enumerated lists (see the example in listing ref\{src:enumPref\}). +The allomorphic items of these lists are mapped successively to the beginning in the case of prefixes +(see listing ref\{src:analyzePref\}, line ref\{ln:prefLoop\}) or to the end of words in the case of suffixes +(see listing ref\{src:analyzeSuf\}). Since each +morphemic variant maps to its morpheme right away, it makes sense to use the morpheme and so +implicitly keep the relation to its allomorph. + +begin\{lstlisting\}{[}language=java,caption=\{Enumeration Example for the Prefix “over”\},label=src:enumPref,escapechar=\textbar{}{]} +package custom.mycore.addons.morphilo; + +public enum PrefixEnum \{ +… +\begin{quote} + +over(“over”), ufer(“over”), ufor(“over”), uferr(“over”), uvver(“over”), obaer(“over”), ober(“over)”), ofaer(“over”), +ofere(“over”), ofir(“over”), ofor(“over”), ofer(“over”), ouer(“over”),oferr(“over”), offerr(“over”), offr(“over”), aure(“over”), +war(“over”), euer(“over”), oferre(“over”), oouer(“over”), oger(“over”), ouere(“over”), ouir(“over”), ouire(“over”), +ouur(“over”), ouver(“over”), ouyr(“over”), ovar(“over”), overe(“over”), ovre(“over”),ovur(“over”), owuere(“over”), owver(“over”), +houyr(“over”), ouyre(“over”), ovir(“over”), ovyr(“over”), hover(“over”), auver(“over”), awver(“over”), ovver(“over”), +hauver(“over”), ova(“over”), ove(“over”), obuh(“over”), ovah(“over”), ovuh(“over”), ofowr(“over”), ouuer(“over”), oure(“over”), +owere(“over”), owr(“over”), owre(“over”), owur(“over”), owyr(“over”), our(“over”), ower(“over”), oher(“over”), +ooer(“over”), oor(“over”), owwer(“over”), ovr(“over”), owir(“over”), oar(“over”), aur(“over”), oer(“over”), ufara(“over”), +ufera(“over”), ufere(“over”), uferra(“over”), ufora(“over”), ufore(“over”), ufra(“over”), ufre(“over”), ufyrra(“over”), +yfera(“over”), yfere(“over”), yferra(“over”), uuera(“over”), ufe(“over”), uferre(“over”), uuer(“over”), uuere(“over”), +vfere(“over”), vuer(“over”), vuere(“over”), vver(“over”), uvvor(“over”) … +\end{quote} +\begin{description} +\item[{…chap:results}] \leavevmode +private String morpheme; +//constructor +PrefixEnum(String morpheme) +\{ +\begin{quote} + +this.morpheme = morpheme; +\end{quote} + +\} +//getter Method + +public String getMorpheme() +\{ +\begin{quote} + +return this.morpheme; +\end{quote} + +\} + +\end{description} + +\} +end\{lstlisting\} +As can be seen in line ref\{ln:prefPutMorph\} in listing ref\{src:analyzePref\}, the morpheme is saved to a hash map together with its position, i.e. the size of the +map plus one at the time being. In line ref\{ln:prefCutoff\} the emph\{analyzePrefix\} method is recursively called until no more matches can be made. + +begin\{lstlisting\}{[}language=java,caption=\{Method to recognize prefixes\},label=src:analyzePref,escapechar=\textbar{}{]} +private Map\textless{}String, Integer\textgreater{} prefixMorpheme = new HashMap\textless{}String,Integer\textgreater{}(); +… +private void analyzePrefix(String restword) +\{ +\begin{quote} + +if (!restword.isEmpty()) //Abbruchbedingung fuer Rekursion +\{ +\begin{quote} + +for (PrefixEnum prefEnum : PrefixEnum.values())\textbar{}label\{ln:prefLoop\}\textbar{} +\{ +\begin{quote} + +String s = prefEnum.toString(); +if (restword.startsWith(s)) +\{ +\begin{quote} + +prefixMorpheme.put(s, prefixMorpheme.size() + 1);\textbar{}label\{ln:prefPutMorph\}\textbar{} +//cut off the prefix that is added to the list +analyzePrefix(restword.substring(s.length()));\textbar{}label\{ln:prefCutoff\}\textbar{} +\end{quote} + +\} +else +\{ +\begin{quote} + +analyzePrefix(“”); +\end{quote} + +\} +\end{quote} + +\} +\end{quote} + +\} +\end{quote} + +\} +end\{lstlisting\} + +The recognition of suffixes differs only in the cut-off direction since suffixes occur at the end of a word. +Hence, line ref\{ln:prefCutoff\} in listing ref\{src:analyzePref\} reads in the case of suffixes. + +begin\{lstlisting\}{[}language=java,caption=\{Cut-off mechanism for suffixes\},label=src:analyzeSuf,escapechar=\textbar{}{]} +analyzeSuffix(restword.substring(0, restword.length() - s.length())); +end\{lstlisting\} + +It is important to note that inflections are suffixes (in the given model case of Middle English morphology) that usually occur at the very +end of a word, i.e. after all lexical suffixes, only once. It follows that inflections +have to be recognized at first without any repetition. So the procedure for inflections can be simplified +to a substantial degree as listing ref\{src:analyzeInfl\} shows. + +begin\{lstlisting\}{[}language=java,caption=\{Method to recognize inflections\},label=src:analyzeInfl,escapechar=\textbar{}{]} +private String analyzeInflection(String wrd) +\{ +\begin{quote} + +String infl = “”; +for (InflectionEnum inflEnum : InflectionEnum.values()) +\{ +\begin{quote} + +if (wrd.endsWith(inflEnum.toString())) +\{ +\begin{quote} + +infl = inflEnum.toString(); +\end{quote} + +\} +\end{quote} + +\} +return infl; +\end{quote} + +\} +end\{lstlisting\} + +Unfortunately the embeddedness problem prevents a very simple algorithm. Embeddedness occurs when a lexical item +is a substring of another lexical item. To illustrate, the suffix emph\{ion\} is also contained in the suffix emph\{ation\}, as is +emph\{ent\} in emph\{ment\}, and so on. The embeddedness problem cannot be solved completely on the basis of linear modelling, but +for a large part of embedded items one can work around it using implicitly Zipf’s law, i.e. the correlation between frequency +and length of lexical items. The longer a word becomes, the less frequent it will occur. The simplest logic out of it is to assume +that longer suffixes (measured in letters) are preferred over shorter suffixes because it is more likely tha the longer the suffix string becomes, +the more likely it is one (as opposed to several) suffix unit(s). This is done in listing ref\{src:embedAffix\}, whereas +the inner class emph\{sortedByLengthMap\} returns a list sorted by length and the loop from line ref\{ln:deleteAffix\} onwards deletes +the respective substrings. + +begin\{lstlisting\}{[}language=java,caption=\{Method to workaround embeddedness\},label=src:embedAffix,escapechar=\textbar{}{]} +private Map\textless{}String, Integer\textgreater{} sortOutAffixes(Map\textless{}String, Integer\textgreater{} affix) +\{ +\begin{quote} +\begin{description} +\item[{Map\textless{}String,Integer\textgreater{} sortedByLengthMap = new TreeMap\textless{}String, Integer\textgreater{}(new Comparator\textless{}String\textgreater{}()}] \leavevmode\begin{description} +\item[{\{}] \leavevmode +@Override +public int compare(String s1, String s2) +\{ +\begin{quote} + +int cmp = Integer.compare(s1.length(), s2.length()); +return cmp != 0 ? cmp : s1.compareTo(s2); +\end{quote} + +\} + +\end{description} + +\} + +\end{description} + +); +sortedByLengthMap.putAll(affix); +ArrayList\textless{}String\textgreater{} al1 = new ArrayList\textless{}String\textgreater{}(sortedByLengthMap.keySet()); +ArrayList\textless{}String\textgreater{} al2 = al1; +Collections.reverse(al2); +for (String s2 : al1)\textbar{}label\{ln:deleteAffix\}\textbar{} +\{ +\begin{quote} +\begin{description} +\item[{for (String s1}] \leavevmode{[}al2){]} +if (s1.contains(s2) \&\& s1.length() \textgreater{} s2.length()) +\{ +\begin{quote} + +affix.remove(s2); +\end{quote} + +\} + +\end{description} + +\} +\end{quote} + +return affix; +\end{quote} + +\} +end\{lstlisting\} + +Finally, the position of the affix has to be calculated because the hashmap in line ref\{ln:prefPutMorph\} in +listing ref\{src:analyzePref\} does not keep the original order for changes taken place in addressing the affix embeddedness +(listing ref\{src:embedAffix\}). Listing ref\{src:affixPos\} depicts the preferred solution. +The recursive construction of the method is similar to emph\{private void analyzePrefix(String)\} (listing ref\{src:analyzePref\}) +only that the two affix types are handled in one method. For that, an additional parameter taking the form either emph\{suffix\} +or emph\{prefix\} is included. + +begin\{lstlisting\}{[}language=java,caption=\{Method to determine position of the affix\},label=src:affixPos,escapechar=\textbar{}{]} +private void getAffixPosition(Map\textless{}String, Integer\textgreater{} affix, String restword, int pos, String affixtype) +\{ +\begin{quote} + +if (!restword.isEmpty()) //Abbruchbedingung fuer Rekursion +\{ +\begin{quote} + +for (String s : affix.keySet()) +\{ +\begin{quote} + +if (restword.startsWith(s) \&\& affixtype.equals(“prefix”)) +\{ +\begin{quote} +\begin{quote} + +pos++; +prefixMorpheme.put(s, pos); +\end{quote} +\begin{description} +\item[{//prefixAllomorph.add(pos-1, restword.substring(s.length()));}] \leavevmode +getAffixPosition(affix, restword.substring(s.length()), pos, affixtype); + +\end{description} +\end{quote} + +\} +else if (restword.endsWith(s) \&\& affixtype.equals(“suffix”)) +\{ +\begin{quote} + +pos++; +suffixMorpheme.put(s, pos); +//suffixAllomorph.add(pos-1, restword.substring(s.length())); +getAffixPosition(affix, restword.substring(0, restword.length() - s.length()), pos, affixtype); +\end{quote} + +\} +else +\{ +\begin{quote} + +getAffixPosition(affix, “”, pos, affixtype); +\end{quote} + +\} +\end{quote} + +\} +\end{quote} + +\} +\end{quote} + +\} +end\{lstlisting\} + +To give the complete word structure, the root of a word should also be provided. In listing ref\{src:rootAnalyze\} a simple solution is offered, however, +considering compounds as words consisting of more than one root. +begin\{lstlisting\}{[}language=java,caption=\{Method to determine roots\},label=src:rootAnalyze,escapechar=\textbar{}{]} +private ArrayList\textless{}String\textgreater{} analyzeRoot(Map\textless{}String, Integer\textgreater{} pref, Map\textless{}String, Integer\textgreater{} suf, int stemNumber) +\{ +\begin{quote} + +ArrayList\textless{}String\textgreater{} root = new ArrayList\textless{}String\textgreater{}(); +int j = 1; //one root always exists +// if word is a compound several roots exist +while (j \textless{}= stemNumber) +\{ +\begin{quote} + +j++; +String rest = lemma;\textbar{}label\{ln:lemma\}\textbar{} + +for (int i=0;i\textless{}pref.size();i++) +\{ +\begin{quote} + +for (String s : pref.keySet()) +\{ +\begin{quote} +\begin{description} +\item[{//if (i == pref.get(s))}] \leavevmode +if (rest.length() \textgreater{} s.length() \&\& s.equals(rest.substring(0, s.length()))) +\{ +\begin{quote} + +rest = rest.substring(s.length(),rest.length()); +\end{quote} + +\end{description} + +\} +\end{quote} + +\} +\end{quote} + +\} + +for (int i=0;i\textless{}suf.size();i++) +\{ +\begin{quote} + +for (String s : suf.keySet()) +\{ +\begin{quote} + +//if (i == suf.get(s)) +if (s.length() \textless{} rest.length() \&\& (s.equals(rest.substring(rest.length() - s.length(), rest.length())))) +\{ +\begin{quote} + +rest = rest.substring(0, rest.length() - s.length()); +\end{quote} + +\} +\end{quote} + +\} +\end{quote} + +\} +root.add(rest); +\end{quote} + +\} +return root; +\end{quote} + +\} +end\{lstlisting\} +The logic behind this method is that the root is the remainder of a word when all prefixes and suffixes are substracted. +So the loops run through the number of prefixes and suffixes at each position and substract the affix. Really, there is +some code doubling with the previously described methods, which could be eliminated by making it more modular in a possible +refactoring phase. Again, this is not the concern of a prototype. Line ref\{ln:lemma\} defines the initial state of a root, +which is the case for monomorphemic words. The emph\{lemma\} is defined as the wordtoken without the inflection. Thus listing +ref\{src:lemmaAnalyze\} reveals how the class variable is calculated +begin\{lstlisting\}{[}language=java,caption=\{Method to determine lemma\},label=src:lemmaAnalyze,escapechar=\textbar{}{]} +/* +\begin{quote} +\begin{itemize} +\item {} +Simplification: lemma = wordtoken - inflection + +\end{itemize} + +{\color{red}\bfseries{}*}/ +\end{quote} + +private String analyzeLemma(String wrd, String infl) +\{ +\begin{quote} + +return wrd.substring(0, wrd.length() - infl.length()); +\end{quote} + +\} +end\{lstlisting\} +The constructor of emph\{AffixStripper\} calls the method emph\{analyzeWord()\} +whose only job is to calculate each structure element in the correct order +(listing ref\{src:lemmaAnalyze\}). All structure elements are also provided by getters. +begin\{lstlisting\}{[}language=java,caption=\{Method to determine all word structure\},label=src:lemmaAnalyze,escapechar=\textbar{}{]} +private void analyzeWord() +\{ +\begin{quote} + +//analyze inflection first because it always occurs at the end of a word +inflection = analyzeInflection(wordtoken); +lemma = analyzeLemma(wordtoken, inflection); +analyzePrefix(lemma); +analyzeSuffix(lemma); +getAffixPosition(sortOutAffixes(prefixMorpheme), lemma, 0, “prefix”); +getAffixPosition(sortOutAffixes(suffixMorpheme), lemma, 0, “suffix”); +prefixNumber = prefixMorpheme.size(); +suffixNumber = suffixMorpheme.size(); +wordroot = analyzeRoot(prefixMorpheme, suffixMorpheme, getStemNumber()); +\end{quote} + +\} +end\{lstlisting\} + +To conclude, the Morphilo implementation as presented here, aims at fulfilling the task of a working prototype. It is important to note +that it neither claims to be a very efficient nor a ready software program to be used in production. However, it marks a crucial milestone +on the way to a production system. At some listings sources of improvement were made explicit; at others no suggestions were made. In the latter +case this does not imply that there is no potential for improvement. Once acceptability tests are carried out, it will be the task of a follow up project +to identify these potentials and implement them accordingly. + + +\chapter{View} +\label{\detokenize{source/view::doc}}\label{\detokenize{source/view:view}} + +\section{Conceptualization} +\label{\detokenize{source/view:conceptualization}} +Lastly, the third directory (emph\{src/main/resources\}) contains all code needed +for rendering the data to be displayed on the screen. So this corresponds to +the view in an MVC approach. It is done by xsl-files that (unfortunately) +contain some logic that really belongs to the controller. Thus, the division is +not as clear as implied in theory. I will discuss this issue more specifically in the +relevant subsection below. Among the resources are also all images, styles, and +javascripts. + + +\section{Implementation} +\label{\detokenize{source/view:implementation}} +As explained in section ref\{subsec:mvc\}, the view component handles the visual +representation in the form of an interface that allows interaction between +the user and the task to be carried out by the machine. As a +webservice in the present case, all interaction happens via a browser, i.e. webpages are +visualized and responses are recognized by registering mouse or keyboard +events. More specifically, a webpage is rendered by transforming xml documents +to html pages. The MyCoRe repository framework uses an open source XSLT +processor from Apache, Xalan.footnote\{http://xalan.apache.org\} This engine +transforms document nodes described by the XPath syntax into hypertext making +use of a special form of template matching. All templates are collected in so +called xml-encoded stylesheets. Since there are two data models with two +different structures, it is good practice to define two stylesheet files one for +each data model. + +As a demonstration, in listing ref\{lst:morphilostylesheet\} below a short +extract is given for rendering the word data. + +begin\{lstlisting\}{[}language=XML,caption=\{stylesheet +morphilo.xsl\},label=lst:morphilostylesheet{]} +\textless{}?xml version=”1.0” encoding=”UTF-8”?\textgreater{} +\textless{}xsl:stylesheet +\begin{quote} + +xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” +xmlns:xalan=”http://xml.apache.org/xalan” +xmlns:i18n=”xalan://org.mycore.services.i18n.MCRTranslation” +xmlns:acl=”xalan://org.mycore.access.MCRAccessManager” +xmlns:mcr=”http://www.mycore.org/” xmlns:xlink=”http://www.w3.org/1999/xlink” +xmlns:mods=”http://www.loc.gov/mods/v3” +xmlns:encoder=”xalan://java.net.URLEncoder” +xmlns:mcrxsl=”xalan://org.mycore.common.xml.MCRXMLFunctions” +xmlns:mcrurn=”xalan://org.mycore.urn.MCRXMLFunctions” +exclude-result-prefixes=”xalan xlink mcr i18n acl mods mcrxsl mcrurn encoder” +version=”1.0”\textgreater{} +\textless{}xsl:param name=”MCR.Users.Superuser.UserName”/\textgreater{} +\begin{description} +\item[{\textless{}xsl:template match=”/mycoreobject{[}contains(@ID,’\_morphilo\_’){]}”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}head\textgreater{}}] \leavevmode +\textless{}link href=”\{\$WebApplicationBaseURL\}css/file.css” rel=”stylesheet”/\textgreater{} + +\end{description} + +\textless{}/head\textgreater{} +\textless{}div class=”row”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xsl:call-template name=”objectAction”\textgreater{}}] \leavevmode +\textless{}xsl:with-param name=”id” select=”@ID”/\textgreater{} +\textless{}xsl:with-param name=”deriv” select=”structure/derobjects/derobject/@xlink:href”/\textgreater{} + +\end{description} + +\textless{}/xsl:call-template\textgreater{} +\textless{}xsl:variable name=”objID” select=”@ID”/\textgreater{} +\textless{}!\textendash{} Hier Ueberschrift setzen \textendash{}\textgreater{} +\textless{}h1 style=”text-indent: 4em;”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xsl:if test=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w”\textgreater{}}] \leavevmode +\textless{}xsl:value-of select=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text(){[}string-length(normalize-space(.))\textgreater{}0{]}”/\textgreater{} + +\end{description} + +\textless{}/xsl:if\textgreater{} +\end{quote} + +\textless{}/h1\textgreater{} +\textless{}dl class=”dl-horizontal”\textgreater{} +\textless{}!\textendash{} (1) Display word \textendash{}\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xsl:if test=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}dt\textgreater{}}] \leavevmode +\textless{}xsl:value-of select=”i18n:translate(‘response.page.label.word’)”/\textgreater{} + +\end{description} + +\textless{}/dt\textgreater{} +\textless{}dd\textgreater{} +\begin{quote} + +\textless{}xsl:value-of select=”metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text(){[}string-length(normalize-space(.))\textgreater{}0{]}”/\textgreater{} +\end{quote} + +\textless{}/dd\textgreater{} + +\end{description} + +\textless{}/xsl:if\textgreater{} +\end{quote} +\begin{description} +\item[{\textless{}!\textendash{} (2) Display lemma \textendash{}\textgreater{}}] \leavevmode +… + +\end{description} +\end{quote} + +\end{description} + +\textless{}/xsl:template\textgreater{} +… +\textless{}xsl:template name=”objectAction”\textgreater{} +… +\textless{}/xsl:template\textgreater{} +\end{quote} + +… +\textless{}/xsl:stylesheet\textgreater{} +end\{lstlisting\} +This template matches with +the root node of each emph\{MyCoRe object\} ensuring that a valid MyCoRe model is +used and checking that the document to be processed contains a unique +identifier, here a emph\{MyCoRe-ID\}, and the name of the correct data model, +here emph\{morphilo\}. +Then, another template, emph\{objectAction\}, is called together with two parameters, the ids +of the document object and attached files. In the remainder all relevant +information from the document is accessed by XPath, such as the word and the lemma, +and enriched with hypertext annotations it is rendered as a hypertext document. +The template emph\{objectAction\} is key to understand the coupling process in the software +framework. It is therefore separately listed in ref\{lst:objActionTempl\}. + +begin\{lstlisting\}{[}language=XML,caption=\{template +objectAction\},label=lst:objActionTempl,escapechar=\textbar{}{]} +\textless{}xsl:template name=”objectAction”\textgreater{} +\begin{quote} + +\textless{}xsl:param name=”id” select=”./@ID”/\textgreater{} +\textless{}xsl:param name=”accessedit” select=”acl:checkPermission(\$id,’writedb’)”/\textgreater{} +\textless{}xsl:param name=”accessdelete” select=”acl:checkPermission(\$id,’deletedb’)”/\textgreater{} +\textless{}xsl:variable name=”derivCorp” select=”./@label”/\textgreater{} +\textless{}xsl:variable name=”corpID” select=”metadata/def.corpuslink{[}@class=’MCRMetaLinkID’{]}/corpuslink/@xlink:href”/\textgreater{} +\textless{}xsl:if test=”\$accessedit or \$accessdelete”\textgreater{}\textbar{}label\{ln:ng\}\textbar{} +\textless{}div class=”dropdown pull-right”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xsl:if test=”string-length(\$corpID) \> 0 or \$CurrentUser=’administrator’”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}button class=”btn btn-default dropdown-toggle” style=”margin:10px” type=”button” id=”dropdownMenu1” data-toggle=”dropdown” aria-expanded=”true”\textgreater{}}] \leavevmode +\textless{}span class=”glyphicon glyphicon-cog” aria-hidden=”true”\textgreater{}\textless{}/span\textgreater{} Annotieren +\textless{}span class=”caret”\textgreater{}\textless{}/span\textgreater{} + +\end{description} + +\textless{}/button\textgreater{} + +\end{description} + +\textless{}/xsl:if\textgreater{} +\textless{}xsl:if test=”string-length(\$corpID) \> 0”\textgreater{}\textbar{}label\{ln:ru\}\textbar{} +\begin{quote} + +\textless{}xsl:variable name=”ifsDirectory” select=”document(concat(‘ifs:/’,\$derivCorp))”/\textgreater{} +\textless{}ul class=”dropdown-menu” role=”menu” aria-labelledby=”dropdownMenu1”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}li role=”presentation”\textgreater{}}] \leavevmode\begin{description} +\item[{{\color{red}\bfseries{}\textbar{}\textbackslash{}label\{ln:nw1\}\textbar{}\textless{}a href="\{\$ServletsBaseURL\}object/tag\{\$HttpSession\}?id=\{\$derivCorp\}\&objID=\{\$corpID\}" role="menuitem" tabindex="-1"\textgreater{}\textbar{}}label\{ln:nw2\}\textbar{}}] \leavevmode +\textless{}xsl:value-of select=”i18n:translate(‘object.nextObject’)”/\textgreater{} + +\end{description} + +\textless{}/a\textgreater{} + +\end{description} + +\textless{}/li\textgreater{} +\textless{}li role=”presentation”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}a href=”\{\$WebApplicationBaseURL\}receive/\{\$corpID\}” role=”menuitem” tabindex=”-1”\textgreater{}}] \leavevmode +\textless{}xsl:value-of select=”i18n:translate(‘object.backToProject’)”/\textgreater{} + +\end{description} + +\textless{}/a\textgreater{} +\end{quote} + +\textless{}/li\textgreater{} +\end{quote} + +\textless{}/ul\textgreater{} +\end{quote} + +\textless{}/xsl:if\textgreater{} +\textless{}xsl:if test=”\$CurrentUser=’administrator’”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}ul class=”dropdown-menu” role=”menu” aria-labelledby=”dropdownMenu1”\textgreater{}}] \leavevmode\begin{quote} +\begin{description} +\item[{\textless{}li role=”presentation”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}a role=”menuitem” tabindex=”-1” href=”\{\$WebApplicationBaseURL\}content/publish/morphilo.xed?id=\{\$id\}”\textgreater{}}] \leavevmode +\textless{}xsl:value-of select=”i18n:translate(‘object.editWord’)”/\textgreater{} + +\end{description} + +\textless{}/a\textgreater{} + +\end{description} + +\textless{}/li\textgreater{} +\textless{}li role=”presentation”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}a href=”\{\$ServletsBaseURL\}object/delete\{\$HttpSession\}?id=\{\$id\}” role=”menuitem” tabindex=”-1” class=”confirm\_deletion option” data-text=”Wirklich loeschen”\textgreater{}}] \leavevmode +\textless{}xsl:value-of select=”i18n:translate(‘object.delWord’)”/\textgreater{} + +\end{description} + +\textless{}/a\textgreater{} +\end{quote} +\end{quote} + +\textless{}/li\textgreater{} + +\end{description} + +\textless{}/ul\textgreater{} +\end{quote} + +\textless{}/xsl:if\textgreater{} +\textless{}/div\textgreater{} +\textless{}div class=”row” style=”margin-left:0px; margin-right:10px”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}xsl:apply-templates select=”structure/derobjects/derobject{[}acl:checkPermission(@xlink:href,’read’){]}”\textgreater{}}] \leavevmode +\textless{}xsl:with-param name=”objID” select=”@ID”/\textgreater{} + +\end{description} + +\textless{}/xsl:apply-templates\textgreater{} +\end{quote} + +\textless{}/div\textgreater{} +\end{quote} + +\textless{}/xsl:if\textgreater{} +\end{quote} + +\textless{}/xsl:template\textgreater{} +end\{lstlisting\} +The emph\{objectAction\} template defines the selection menu appearing \textendash{} once manual tagging has +started \textendash{} on the upper right hand side of the webpage entitled +emph\{Annotieren\} and displaying the two options emph\{next word\} or emph\{back +to project\}. +The first thing to note here is that in line ref\{ln:ng\} a simple test +excludes all guest users from accessing the procedure. After ensuring that only +the user who owns the corpus project has access (line ref\{ln:ru\}), s/he will be +able to access the drop down menu, which is really a url, e.g. line +ref\{ln:nw1\}. The attentive reader might have noticed that +the url exactly matches the definition in the web-fragment.xml as shown in +listing ref\{lst:webfragment\}, line ref\{ln:tag\}, which resolves to the +respective java class there. Really, this mechanism is the data interface within the +MVC pattern. The url also contains two variables, named emph\{derivCorp\} and +emph\{corpID\}, that are needed to identify the corpus and file object by the +java classes (see section ref\{sec:javacode\}). + +The morphilo.xsl stylesheet contains yet another modification that deserves mention. +In listing ref\{lst:derobjectTempl\}, line ref\{ln:morphMenu\}, two menu options \textendash{} +emph\{Tag automatically\} and emph\{Tag manually\} \textendash{} are defined. The former option +initiates ProcessCorpusServlet.java as can be seen again in listing ref\{lst:webfragment\}, +line ref\{ln:process\}, which determines words that are not in the master data base. +Still, it is important to note that the menu option is only displayed if two restrictions +are met. First, a file has to be uploaded (line ref\{ln:1test\}) and, second, there must be +only one file. This is necessary because in the annotation process other files will be generated +that store the words that were not yet processed or a file that includes the final result. The +generated files follow a certain pattern. The file harboring the final, entire TEI-annotated +corpus is prefixed by emph\{tagged\}, the other file is prefixed emph\{untagged\}. This circumstance +is exploited for manipulating the second option (line ref\{ln:loop\}). A loop runs through all +files in the respective directory and if a file name starts with emph\{untagged\}, +the option to manually tag is displayed. + +begin\{lstlisting\}{[}language=XML,caption=\{template +matching derobject\},label=lst:derobjectTempl,escapechar=\textbar{}{]} +\textless{}xsl:template match=”derobject” mode=”derivateActions”\textgreater{} +\begin{quote} + +\textless{}xsl:param name=”deriv” /\textgreater{} +\textless{}xsl:param name=”parentObjID” /\textgreater{} +\textless{}xsl:param name=”suffix” select=”’‘” /\textgreater{} +\textless{}xsl:param name=”id” select=”../../../@ID” /\textgreater{} +\textless{}xsl:if test=”acl:checkPermission(\$deriv,’writedb’)”\textgreater{} +\begin{quote} + +\textless{}xsl:variable name=”ifsDirectory” select=”document(concat(‘ifs:’,\$deriv,’/’))” /\textgreater{} +\textless{}xsl:variable name=”path” select=”\$ifsDirectory/mcr\_directory/path” /\textgreater{} +\end{quote} +\begin{description} +\item[{…}] \leavevmode\begin{quote} +\begin{description} +\item[{\textless{}div class=”options pull-right”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}div class=”btn-group” style=”margin:10px”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}a href=”\#” class=”btn btn-default dropdown-toggle” data-toggle=”dropdown”\textgreater{}}] \leavevmode +\textless{}i class=”fa fa-cog”\textgreater{}\textless{}/i\textgreater{} +\textless{}xsl:value-of select=”’ Korpus’”/\textgreater{} +\textless{}span class=”caret”\textgreater{}\textless{}/span\textgreater{} + +\end{description} + +\textless{}/a\textgreater{} + +\item[{\textless{}ul class=”dropdown-menu dropdown-menu-right”\textgreater{}}] \leavevmode +\textless{}!\textendash{} Anpasssungen Morphilo \textendash{}\textgreater{}\textbar{}label\{ln:morphMenu\}\textbar{} +\textless{}xsl:if test=”string-length(\$deriv) \> 0”\textgreater{}\textbar{}label\{ln:1test\}\textbar{} +\begin{quote} +\begin{description} +\item[{\textless{}xsl:if test=”count(\$ifsDirectory/mcr\_directory/children/child) = 1”\textgreater{}\textbar{}label\{ln:2test\}\textbar{}}] \leavevmode\begin{description} +\item[{\textless{}li role=”presentation”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}a href=”\{\$ServletsBaseURL\}object/process\{\$HttpSession\}?id=\{\$deriv\}\&objID=\{\$id\}” role=”menuitem” tabindex=”-1”\textgreater{}}] \leavevmode +\textless{}xsl:value-of select=”i18n:translate(‘derivate.process’)”/\textgreater{} + +\end{description} + +\textless{}/a\textgreater{} + +\end{description} + +\textless{}/li\textgreater{} + +\end{description} + +\textless{}/xsl:if\textgreater{} +\textless{}xsl:for-each select=”\$ifsDirectory/mcr\_directory/children/child”\textgreater{}\textbar{}label\{ln:loop\}\textbar{} +\begin{quote} + +\textless{}xsl:variable name=”untagged” select=”concat(\$path, ‘untagged’)”/\textgreater{} +\textless{}xsl:variable name=”filename” select=”concat(\$path,./name)”/\textgreater{} +\textless{}xsl:if test=”starts-with(\$filename, \$untagged)”\textgreater{} +\begin{quote} +\begin{description} +\item[{\textless{}li role=”presentation”\textgreater{}}] \leavevmode\begin{description} +\item[{\textless{}a href=”\{\$ServletsBaseURL\}object/tag\{\$HttpSession\}?id=\{\$deriv\}\&objID=\{\$id\}” role=”menuitem” tabindex=”-1”\textgreater{}}] \leavevmode +\textless{}xsl:value-of select=”i18n:translate(‘derivate.taggen’)”/\textgreater{} + +\end{description} + +\textless{}/a\textgreater{} + +\end{description} + +\textless{}/li\textgreater{} +\end{quote} + +\textless{}/xsl:if\textgreater{} +\end{quote} + +\textless{}/xsl:for-each\textgreater{} +\end{quote} + +\textless{}/xsl:if\textgreater{} + +\end{description} + +… +\textless{}/ul\textgreater{} + +\end{description} + +\textless{}/div\textgreater{} +\end{quote} + +\textless{}/div\textgreater{} + +\end{description} + +\textless{}/xsl:if\textgreater{} +\end{quote} + +\textless{}/xsl:template\textgreater{} +end\{lstlisting\} + +Besides the two stylesheets morphilo.xsl and corpmeta.xsl, other stylesheets have +to be adjusted. They will not be discussed in detail here for they are self-explanatory for the most part. +Essentially, they render the overall layout (emph\{common-layout.xsl\}, emph\{skeleton\_layout\_template.xsl\}) +or the presentation +of the search results (emph\{response-page.xsl\}) and definitions of the solr search fields (emph\{searchfields-solr.xsl\}). +The former and latter also inherit templates from emph\{response-general.xsl\} and emph\{response-browse.xsl\}, in which the +navigation bar of search results can be changed. For the use of multilinguality a separate configuration directory +has to be created containing as many emph\{.property\}-files as different +languages want to be displayed. In the current case these are restricted to German and English (emph\{messages\_de.properties\} and emph\{messages\_en.properties\}). +The property files include all emph\{i18n\} definitions. All these files are located in the emph\{resources\} directory. + +Furthermore, a search mask and a page for manually entering the annotations had +to be designed. +For these files a specially designed xml standard (emph\{xed\}) is recommended to be used within the +repository framework. + + +\chapter{Software Design} +\label{\detokenize{source/architecture::doc}}\label{\detokenize{source/architecture:software-design}} +!{[}Morphilo Architecture{]}(architecture.pdf) + +The architecture of a possible \textless{}em\textgreater{}take-and-share\textless{}/em\textgreater{}-approach for language +resources is visualized in figure ref\{fig:architect\}. Because the very gist +of the approach becomes clearer if describing a concrete example, the case of +annotating lexical derivatives of Middle English and a respective database is +given as an illustration. +However, any other tool that helps with manual annotations and manages metadata of a corpus could be +substituted here instead. + +After inputting an untagged corpus or plain text, it is determined whether the +input material was annotated previously by a different user. This information is +usually provided by the metadata administered by the annotation tool; in the case at +hand it is called emph\{Morphilizer\} in figure ref\{fig:architect\}. An +alternative is a simple table look-up for all occurring words in the datasets Corpus 1 through Corpus n. If contained +completely, the emph\{yes\}-branch is followed up further \textendash{} otherwise emph\{no\} +succeeds. The difference between the two branches is subtle, yet crucial. On +both branches, the annotation tool (here emph\{Morphilizer\}) is called, which, first, +sorts out all words that are not contained in the master database (here emph\{Morphilo-DB\}) +and, second, makes reasonable suggestions on an optimal annotation of +the items. In both cases the +annotations are linked to the respective items (e.g. words) in the +text, but they are also persistently saved in an extra dataset, i.e. Corpus 1 +through n, together with all available metadata. + +The difference between both information streams is that +in the emph\{yes\}-branch a comparison between the newly created dataset and +all of the previous datasets of this text is carried out. Within this +unit, all deviations and congruencies are marked and counted. The underlying +assumption is that with a growing number of comparable texts the +correct annotations approach a theoretic true value of a correct annotation +while errors level out provided that the sample size is large enough. How the +distribution of errors and correct annotations exactly looks like and if a +normal distribution can be assumed is still object of the ongoing research, but +independent of the concrete results, the component (called emph\{compare +manual annotations\} in figure ref\{fig:architect\}) allows for specifying the +exact form of the sample population. +In fact, it is necessary at that point to define the form of the distribution, +sample size, and the rejection region. The standard setting are a normal +distribution, a rejection region of \$alpha = 0.05\$ and sample size of \$30\$ so +that a simple Gauss-Test can be calculated. + +Continuing the information flow further, these statistical calculations are +delivered to the quality-control-component. Based on the statistics, the +respective items together with the metadata, frequencies, and, of course, +annotations are written to the master database. All information in the master +database is directly used for automated annotations. Thus it is directly matched +to the input texts or corpora respectively through the emph\{Morphilizer\}-tool. +The annotation tool decides on the entries looked up in the master which items +are to be manually annotated. + +The processes just described are all hidden from the user who has no possibility +to impact the set quality standards but by errors in the annotation process. The +user will only see the number of items of the input text he or she will process manually. The +annotator will also see an estimation of the workload beforehand. On this +number, a decision can be made if to start the annotation at all. It will be +possible to interrupt the annotation work and save progress on the server. And +the user will have access to the annotations made in the respective dataset, +correct them or save them and resume later. It is important to note that the user will receive +the tagged document only after all items are fully annotated. No partially +tagged text can be output. + + +\chapter{Framework} +\label{\detokenize{source/framework:framework}}\label{\detokenize{source/framework::doc}}\begin{description} +\item[{begin\{figure\}}] \leavevmode +centering +includegraphics{[}scale=0.33{]}\{mycore\_architecture-2.png\} +caption{[}MyCoRe-Architecture and Components{]}\{MyCoRe-Architecture and Componentsprotectfootnotemark\} +label\{fig:abbMyCoReStruktur\} + +\end{description} + +end\{figure\} +footnotetext\{source: \sphinxurl{https://www.mycore.de}\} +To specify the MyCoRe framework the morphilo application logic will have to be implemented, +the TEI data model specified, and the input, search and output mask programmed. + +There are three directories which are +important for adjusting the MyCoRe framework to the needs of one’s own application. These three directories +correspond essentially to the three components in the MVC model as explicated in +section ref\{subsec:mvc\}. Roughly, they are envisualized in figure ref\{fig:abbMyCoReStruktur\} in the upper +right hand corner. More precisely, the view (emph\{Layout\} in figure ref\{fig:abbMyCoReStruktur\}) and the model layer +(emph\{Datenmodell\} in figure ref\{fig:abbMyCoReStruktur\}) can be done +completely via the {\color{red}\bfseries{}{}`{}`}interface’‘, which is a directory with a predefined +structure and some standard files. For the configuration of the logic an extra directory is offered (/src/main/java/custom/mycore/addons/). Here all, java classes +extending the controller layer should be added. +Practically, all three MVC layers are placed in the +emph\{src/main/\}-directory of the application. In one of the subdirectories, +emph\{datamodel/def\}, the datamodel specifications are defined as xml files. It parallels the model +layer in the MVC pattern. How the data model was defined will be explained in +section ref\{subsec:datamodelimpl\}. + \chapter{Indices and tables} \label{\detokenize{index:indices-and-tables}}\begin{itemize} diff --git a/Morphilo_doc/_build/latex/Morphilo.toc b/Morphilo_doc/_build/latex/Morphilo.toc index 7e4a884..e69de29 100644 --- a/Morphilo_doc/_build/latex/Morphilo.toc +++ b/Morphilo_doc/_build/latex/Morphilo.toc @@ -1,5 +0,0 @@ -\babel@toc {english}{} -\contentsline {chapter}{\numberline {1}Data Model Implementation}{1}{chapter.1} -\contentsline {chapter}{\numberline {2}Controller Adjustments}{3}{chapter.2} -\contentsline {section}{\numberline {2.1}General Principle of Operation}{3}{section.2.1} -\contentsline {chapter}{\numberline {3}Indices and tables}{5}{chapter.3} diff --git a/Morphilo_doc/source/architecture.pdf b/Morphilo_doc/_static/architecture.pdf similarity index 100% rename from Morphilo_doc/source/architecture.pdf rename to Morphilo_doc/_static/architecture.pdf diff --git a/Morphilo_doc/index.rst b/Morphilo_doc/index.rst index 7af0585..c704306 100644 --- a/Morphilo_doc/index.rst +++ b/Morphilo_doc/index.rst @@ -12,8 +12,9 @@ Documentation Morphilo Project source/datamodel.rst source/controller.rst - - + source/view.rst + source/architecture.rst + source/framework.rst Indices and tables ================== diff --git a/Morphilo_doc/source/architecture.rst b/Morphilo_doc/source/architecture.rst index 8bc6449..5b114bd 100644 --- a/Morphilo_doc/source/architecture.rst +++ b/Morphilo_doc/source/architecture.rst @@ -1,9 +1,11 @@ Software Design =============== - -The architecture of a possible <em>take-and-share</em>-approach for language +.. image:: architecture.* + + +The architecture of a possible **take-and-share**-approach for language resources is visualized in figure \ref{fig:architect}. Because the very gist of the approach becomes clearer if describing a concrete example, the case of annotating lexical derivatives of Middle English and a respective database is -- GitLab