From c41c808834ca3252686998ba209565f87a194108 Mon Sep 17 00:00:00 2001 From: taynpg Date: Fri, 8 Mar 2024 12:00:42 +0800 Subject: [PATCH] first commit --- .clang-format | 12 + .clangd | 7 + .gitignore | 5 + .vscode/settings.json | 34 + 3rd/.gitignore | 2 + 3rd/build_command.txt | 1 + 3rd/jsoncpp-1.9.5.zip | Bin 0 -> 274500 bytes CMakeLists.txt | 27 + README.md | 3 + main.cpp | 37 + tinyxml2.cpp | 2986 +++++++++++++++++++++++++++++++++++++++++ tinyxml2.h | 2380 ++++++++++++++++++++++++++++++++ vs_generate.cpp | 200 +++ vs_generate.h | 83 ++ vs_json.cpp | 167 +++ vs_json.h | 26 + 16 files changed, 5970 insertions(+) create mode 100644 .clang-format create mode 100644 .clangd create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 3rd/.gitignore create mode 100644 3rd/build_command.txt create mode 100644 3rd/jsoncpp-1.9.5.zip create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 main.cpp create mode 100644 tinyxml2.cpp create mode 100644 tinyxml2.h create mode 100644 vs_generate.cpp create mode 100644 vs_generate.h create mode 100644 vs_json.cpp create mode 100644 vs_json.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..0b04276 --- /dev/null +++ b/.clang-format @@ -0,0 +1,12 @@ +# .clang-format + +# 风格格式化 +BasedOnStyle: Google +# 4 空格缩进 +IndentWidth: 4 +# 连续对齐变量的声明 +AlignConsecutiveDeclarations: true +# 指针左侧对齐 +PointerAlignment: Left +# 访问说明符(public、private等)的偏移 +AccessModifierOffset: -4 \ No newline at end of file diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..a0851df --- /dev/null +++ b/.clangd @@ -0,0 +1,7 @@ +Hover: + ShowAKA: Yes +Diagnostics: + UnusedIncludes: None + Suppress: [anon_type_definition] + ClangTidy: + Remove: misc-unused-alias-decls diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d0a1edc --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build +cmake-build* +.idea +.vs +.cache \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a9847bc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,34 @@ +{ + "files.autoSave": "onFocusChange", + "editor.fontSize": 17, + "editor.fontFamily": "'Operator Mono Lig Light', 'Operator Mono Lig Light', 'Operator Mono Lig Light'", + "editor.fontLigatures": true, + "cmake.configureOnOpen": true, + "cmake.generator": "Ninja", + "cmake.debugConfig": { + "console": "integratedTerminal", + "args": [ + "G:\\ACode\\RTM_x64_vs2015\\RTM_x64_vs2015_Use.sln", + "Debug|x64", + "D:/he.json", + "expect:..\\include" + ], + }, + "cmake.options.statusBarVisibility": "visible", + "editor.inlayHints.enabled": "off", + "C_Cpp.intelliSenseEngine": "disabled", + "clangd.arguments": [ + "--header-insertion=never", + "--all-scopes-completion", + "--completion-style=detailed", + "-j=4", + "--pch-storage=memory", + "--compile-commands-dir=build", + "--background-index", + "--ranking-model=heuristics", + "--query-driver=/usr/bin/g++" + ], + "files.associations": { + "filesystem": "cpp" + } +} \ No newline at end of file diff --git a/3rd/.gitignore b/3rd/.gitignore new file mode 100644 index 0000000..3b7c814 --- /dev/null +++ b/3rd/.gitignore @@ -0,0 +1,2 @@ +jsoncpp-lib +jsoncpp-1.9.5 \ No newline at end of file diff --git a/3rd/build_command.txt b/3rd/build_command.txt new file mode 100644 index 0000000..5248d30 --- /dev/null +++ b/3rd/build_command.txt @@ -0,0 +1 @@ +cmake .. -A x64 -DCMAKE_INSTALL_PREFIX=G:\0516\vs_generate\3rd\jsoncpp-lib -DJSONCPP_WITH_CMAKE_PACKAGE=ON \ No newline at end of file diff --git a/3rd/jsoncpp-1.9.5.zip b/3rd/jsoncpp-1.9.5.zip new file mode 100644 index 0000000000000000000000000000000000000000..ae0728603e5851cfbaf147b39e4ae791a1688cac GIT binary patch literal 274500 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 z

b2E|-VwzOf>eqUHOLxY^r86#A(fP$S=@4222)Cp4&?eq<=JTyR}msDkKvlG1rP zannQN%3y+_oMr%)Ioh*7*$0Y%fQB)cjE661^Or{1lwB*B6<|4p_bb2Rb|dck{aHgau^Xz^slEKyCyz@)Czj!nCAg(Z(M% zJ@u>U4TkR;IHMk@lVmIxg*oB3;3;QEu4;a$z&>Y^U8w{L5ixBCe-sP=RD`(@FS3YO z81#hE$Y*GzMH(xaflbfY$hII`_exH!7o#Rs*&hSP(S$=Gusr4=T(`Ml5QTR`)9-C! z!OLZn1?(NKtAGQd6AC(!yEO*BP=1^gO!VCuD2eBXC8fZ9_EL8M z$hk>zL@X<2*ZyIboZsY7{w`KF7!Wj^iq%j_MYdpMd(hEnI%4AEHi+wRm}STlX+>#J z_us~*CjY0<<3{voJ%edP&W`I9K22aW!H4~`3E!0X1GF7of_r1R4GoB?0ol4!3r;^~ zT#SFzS)N3yniQ@-)V{x7`}#p|((}73_Od%aUb!`PC>J;U$ntnJk?Dp1;^h}Y_OssC zW1HBbR!+YRGlvQ>Ay?|`(9yZoD~dWmKATLoyE{OQ8T*Z{iqtAb87!;Mj)c9Bsh~D$ zT@)f$6&Bm(Iq>Wtz6aSig!{Af==d;#PkTtiMtGz3Y^uORvC%yEX(aI z!lW1w!;p_>iX2H@(G9uDO5+>Qfb|(^?35vsx0erZ*IrJ z|HJtN>2-Y__KZ*=2<}-14{6tX)9Rkt9VqC4c9Wg%f&v%DNyklnExK_sn#hxyi``x|4aKICs>he?a#x zD>@Ecb99w<`f*U`-wUJ*eKsAK1u01WJTY7+a6_~Wi@*h~@pMq9Bu7n}`HD9D&=L`FtR+xH zMK$AZ8`qM>VwA*?TTi&}-4O(Z?nDXcN#p4XSEuw!pH(kZ~(DEj7f?u?p}XA*vm0JT{ONqz*KQvRUQcmK_k?qpK>V!n>V4;O>6c$z{s^) zrH8s6$f)0t2<0D@HiOSbIxKNt7tpGS&?=_g<45s-Q$3eB)1O3<&+)i;)&bdx&Pt|& zVJ($@y)Vn=KDuxLyr7Cl9ojM1CzuqHfdw4GE<1M%$JT^Ll3oxY=7w_o9Z5XL!z7!4 zBJtx%Ap7%I3mRP3QI(q~Caei?UyOE%aspJ7)~@6W^Y9I0Yb&cp0A#7(qutIC(?;IQ zJTK2XbhNur;KGX6o;t0x%l>Ea*e|Z5d1W5X%~^$*3d5Q65}YFh1v$mxMTd2$^yAf^ zRQ_krekJure>h85byD_8MVPB$IC^n7-kRe`d*HGcvkQW?!FJ+T>+br|2FNrL8r zVWZTwr~DYt^K(y9{80E6r)t;D?Z(N~?m``{$c=Sd&bCH~t+c^-M}L4d27YO>cOuJh zR`+4pBv2GXS!W@b_W9P{sl1n%EBIEx$X0zgyeNyDF&+#PDkx$GtMj~j{h_}PnQV)I&awubA>;-T$VHg*A6J_ zAS#R|nK5(L#}*#c$G8}>s&lh5`>kwE@H(P`R>8iFelwwLG;==B)V0PTc?=A(N_g#)?SYJGAJApRsk4QnNUGe>ZZae#2;-$+GFZ))91$ zB(`FEG>g0zE9JDlU*T{WU6U9}ziZ1yC29XWYQZ>}eoGYCvBI(OE2ssDViZ-URihl1 z>PRdP++jhIT8r_jE?sd6J5^K+{{oG>(spEzK+vlin8O~5XmvQSqxr1&Rrb*>;AO`1 zr)uazBLoe47d4tS&Nud4(j0Pd@~2m>u+Wz+6n9j6B5<1D)v~$tKPndeQSv(1;-M&) zyo#(TPpel!rjL=8@kEh5GMoXJ+WRiDK5dcw2%7;uw7fY+)t@SKo@oLP-^T{;cYsXl zB^z#Jo;y`b_kWwpq|6@9YrVYI@bEFLER(kXxMgDVVD@!P1-ZoyyuW50q}9<)K&y&feHgbRFKX&Q7JdYYE37HJuQ3qM%5n_E}k~HS*3HTKZ5}gDmgBk1KZvp935)ACj>CUL9<@*2WfL=AAr&V(hwQ#ez66D|Md@pd zvq=y152rBzoIV>*9K-+(>8D10igJ?oB!39Uu5{Oqb$=qQ!tk@9h*w|`B zNqEDO!%Mm>Ob~7aIe{ERGE2~hWO--72p2?-Z&8Jwk=IV{^rrJ)c)T$5!Z$)dD4M$> z!4~Y%nVznxzcrw3 zZp49Hc)idqQlUJWuB{IPa9ZA^u{#^lqi75+(K#emAW;(^XQ!fiAPeF96V~URjp6SHdw;PdI5WlE!DyaFaHUz{!?e(hxbJnAqZj%UoUfbbU-a!gQY9 zjCS#QQ(FW_SWoM94cBfC*2-HdX_ZBq{jDxLrZ~NpL^At+yo^J+F;*NZiB`H<0`yYV z%f&~VFbt^U@m&}7@A=*^m7@dxxDt|~`=iB!@m~Li^kxXTa#CylX)g=MzEhlMA!Xh? z+=DMCfIu(3Z?*T?eAP8`Dd%ITsRw#AD7lC+p`r2ux#b4Qr-e|2t2nM1Z0U#<9Ek>? zgsVnC|Kst%k7tS>QYGpirK*9TbaIM54h!Ir#mLF!$<~h#j zgiy?8HXnBmg8v8x<{=z&BsS)?;V&4Lc3zs1Dt=WOB*mN~U|sfvtV+^2`YYGWUM)}J z$sYfTldTkhmSF<)xdsSg+SqBf>j5cVpKtm}rkf@&eDS1o+~NRU|(o<513 z46|mdp4%|Ir~sJPCIG%yAiU8K^*-j*e&rmVFnCu)E3Vrcj&A<@g(q2rn)K*`f%x{1whoOhpVoSnHq8?zkNQXTgD&Zm5ki3Qu%9kdBWmd zKY#T7znqqD!=$$96th7eLhDO+r&ml#ZN_(jexfeP4UOYkyp!>RH}`OuDoe8-N47Qa zt+@}@$>e%RPy~lZSwvSCx`U}z%Eo2VDAul6@_mK0p;A|10x-6PDEW-t4h&3Swue>g6WlT~@CO@X zxhTZ4ml~et}HjUqR0hG@u;+7FBvzCGT3>-6u*0M?z zz^ZzjpQSGFjUcT}7oGsqjeUh8s1A0ijdBhBEShZj1GdHXqrp}#IY}<6?jahp*u~~f zAr9bM@_`%jAz4Ii`Gw+fh01urhq&L8H@7C1GFvFqySQdyu?e%DR_f-hl*Z-O!OEP+ zgeeRq4D(ScAEmc)8P~VB*n5)iBrh^!nakAhW!#NcL=Y2!%PcEPY!{Mz3jXu z&>8YJSUP(7LC}%dTL`U;!JzXu@sZi4Urn=Q51LEhWvi3{Rno;4?M((_y%B8>m^P+p z$#l&;x0~Xvl;ToyYf6W$J{{*c{P(Jve%0h;l4w2X@!So!H06GtB!L5-%Ds(jAAoC5 z58?bq_RM5iuzSatAsA$f+>CJ`3I0(HmM22$+!1Y!NXc%)s)sy#>D`kuUkdNEA zp+-SYdaYvV=I;iCzqGQF=8b&IM{ljh#Wwb}tftV-S4KB*vm6E-Hj-%LSl*@o_0R;q zIo)4Tr)gBT$tuI|v1n7-(=(f!I318cJY>+w8mrqlBo4dlI|X6wzn**Y8y4=J=}rFpq)ToP{>VH39h+aiOibNmQR zbi?ZEhOkm)OTEIO0Wo0)#LPP)-cJ7Is!N?Ug&c5)e19Ks$JiuSRu5OG^QP3n?JO;U zg7!bBYjKQ|2PQ7ox89Ne=ci%c=GYKn44_B!?bnP=YK*=~y18FHXU0^sO0%iBv$#q&*!^yZ z@~{%ZC7)YE4Y5Bk+BGrYu73mSH=d4bRh>&tJU|gvi-x?eK{kUOLV8K9>@rIxo=xi+6{5`M@Qb06cdFX# zxq5<+?7#jOeC)DCF)0|U98(DY_KGmVW1Q^3uZ!SjA;;&D+%tSQ zf5x5lApy;o#aBLWQupfmUqsIe>#~BBrJGX2wn(0{G9;+Z`feI;R6WNA%W9N3OJx+k z%VDrUrjCG#Jl@QD{7eups*Jlm^4sj8J4*TBuhBSFogor`qoj(NtV%|!&N>@)LKhfV z7xs`uR!OZ4)?@`PDPq}CmE>H~ov4v4DYeE?)xqY2Tn%`EbfZ>%K|^OAFJcTU0Lo%C z7u2C|hX#b2-&{31bppe&PzBURs)I}*JjWr+U-A1c`a03rM8d2iWGL*nZkzyv%l0}r z2=1JNmG55^Kix-nZyTnE{b6~i+Wh!DQ#R^kU}oX`My)(s273{qtA5LBLppHsR#I`3 zF_<>I_Pc?<7j=_GIJASiVz(Wi*4WPsO!&^?A~s8$fy#s{?~@p_LkHX9*WBQL@$eEg zWKLCO(l59lq7svZbJO*q2}^dhys{;gb&_wRs{gt6z4`Sk)>rMRRy87kk@p@8HqP+Z z%TVCWXB#3mp*O=DHz`Qr=Fi8K8nUr>Kgcg&aG7t2kHZFSV(sL3h}q-w7*~+l+oTno zz3aj1`~~`wky}FSXFf?X#A}q3H5TJ^&xFCvq7Etn0zf=y=Ps z%azO2tEdsNjhx8!Hl&#O;bM+WC3;jgcemBJ%aI=gzeJ`eMym5@x71fg5W&?fXaX1c zi^N13;_S!`mX7809UTAjS=Xt8py4r`_U^TZO~rZOj?a12 z8?9qDm1Ng7`H$&v(Nb%5AVEG!&Cziu+B*$5xR}{@^=!}x39_1$h+fs6Xc zN2ONn+Zxnc(;-`jr8bGS<&gFM*O%@ZOvT0anPr&P#^pWH%kZ8Ftc0A>{rS+05N-SQ)NxwvytRQy z-&PK<@2rI&E$yo-u#LqR%z%;1+cnuH+wg|gx{(47TB(U!a2`>brb3j83M!DKaV2MD zz+a~=0mbxlts_RcJwl9P(E-N63<60os&i+#&O_YBJJ=aS=owSYEP@&-iUN*9mAlk6 z(ix*Dao8l$kC3uAM%mTP)Gw}+t)yG*ktTJ3*ZeR&M!{vE9&9AJX#v1TFKAhe}3gNk+hY@5Q2|KXk%8Gs5;c?t@B6PMfyFH3< z9~*kzN^OC?C&o>@g2FyUnpnZ3{7+i7Z$8l)axKez4tU!j$Zgru5Y`H6C2Ix@(uBF# zmcN~t(MtF7cfE6Pc0hjP@Oj7qD;>KC|7C9T-L~pE|L*-(yg)Hw*R&W@w2b5mTJQt> ztbf8*Ml8L1Rrb7)P4krXYFF<>5n^X!-9YLgAX^~%{=u-M42z^JgXGP5(c;k^=JQt8 zzKkysR3})TegY+(cb2q&%e4WGaulnT_O5EOeXzWCD$&q9cgL%v zozp#H^|nb)=W+7zk#FyX=Hx_RnmH~^U|pp*Ym+DHY@WkHF*hE&OlJ__&PD}$Ok7}_ zFK$ATR+7v{A(A67-ct8#{&|_ckh!blzfG!JcYabkR(Zo1dV3-NBa27p<@WclI`W*+ zS+qBJfr{E%qbGw}pue>5<}g&5m_RIiJna6;@yQ4nn_Q9ybRYBDzj1yv4yLL}bKj)b zjLz9KWJ~=>j2m8foXa)k?oGG?5K*a&L$@9q?^y`8j|X;6Dng7 zf38ox&W244+iNV45r$N(VkgGDGB>^jt1XQKjFnXDRx?DmbzZiUwflW)s$aGHZBv{V zc?eC8BnZcVMhe|&^Md%L4X3<6m3{EmHNg1>L*~rU(OG2Y7O7Cv*dL4T|MnN$*Naa9J<;WK9=4?HBtxHY%H`CNmn(tYJB0I1hn2c$sF|A{M zYQ};kEdB9L1BSd64V8>~K(VU&Zmm<Xo=X|Hg%zo@c82~oUf3EpKEO3uUSoA9%>3OG)#&nshO9kDo<`&)E;*?0d z!T9)7wLXobZx-jmq?LK?U?%$s7$9Qe4elR+oD3kw@xEj()7}G%oiQ6=6fr`PkTD0U zr)X@kJAz|!Mm>UY?fNyyk}Z+S32q#&#Kow_ndpSdz*vQ^cj3IG=b6sfX%G~fA|vxj z9}~zKf%!;dyT$i6EivH)bSB~w^5_N8;TMKRK)3Br+FdZcRZl=WdP#-Cw@VT%(#F8V zHqU*g7iBm7I;qP4Fsu=4A8ximU*PZ#z;x3Z7Ld)~+7v0vx=iBgOr-`E#rHOSJq082N)qVfwC6;8VEyl20OZ{^F`t zSklt&vOA1d_%yPf)KZ+l8Um_4>$Cb_ICLRQ>u4RAw_KTmBd)$drLT`^FaF8jqB&)h zH*H8+N+dBvHhNG}4883%GM*;9Cs{wg)!Wl&f!T4Z3}=Zew=^@#mLQ*-CGz+hHUHa$ zTKMHT4!W^5h+W3>;2m`}tL(B__n!%$JS#F4t}C_Gxo!oonyGzRNL;lDh{Nj6HOD&vT~zKT~w-{0?xBSRTz z+&=_C0~$ut1^m^w-dK%#r{b;Mzk=@c5H6jxYmkM>=12WW#la(rXKLZU+s{m z9LbMs4v@IKueoQ8`hOg0YHfr>r&U~%ji_Za{b~OUDWd-o^!|KLAaKAA(BOKf`O{~c zpVwMd--{3!0C=vWhpSyi!~dM}%t4Y*ZV`w~8WfD$4E6}`0w0bA8nV>lg>s`Ki{k%T zuA`@91(oX&vS-(t-4ENn-#UN-EkC$<#HA`nYGLgONY98Kh+Pz(@7Ewh;m5<&>`8f} z&L)-IkH2jZJJHP(ZnpeccY%QTcD1j6+J9Pg?v3CojKZRNs?V|k(ha5;TrQYGRD=DA zkB_I1fexS-6mZq~x34mEYiYq`lb=`TJP_RqxmDL7#@=2~3M1SK1eMB8$;~qgu)~ib zMCj3U!(9~b<#XFr3f0@+_@)_)sIuMh5|tCZw#l@4eBp!8r0-W3XP-Bb?8|FW=nD7y zkI=YZ)8DilvJPIYu6ODhoj~yuI)TJFvaUf|e05-WCX8mtAf8pM?s1|#itH`(dnUd9`PX>;Z5rd-6A&CxPWI0S8Y7tWiyWH? zka0(*Y6w1UwrZ=mabBz1_DS4=SS6RMGA7qS#~?P+95lI1aboI8fdfL4av(PB--b-D zILT(JDVsT;QA}w_M*p-#OTJg214O>fnG=HaBN(SnQ+p!iFU2o6#P?`)O1SFv)l zKS`oBe0Ln(Z*}*3YbL#FA?(v_*HwdQ%(+?m0&;?#a6Q4a#YsJ1HD-L|mLOz#9Q7^d zTYT?A$fSG8U0+!SIYhIiuqA{p^PG-p6lfclYR?H{0fi*dG1@`~h*Tn{`v_xv>(*I{ zE|Feg3tqv9^%twrhHqrjfp`k9+cbZTA{_>1HCBW~Mft+uI`kIR0S-TAgXDh|i7Fy2 z&#i|1!Xq2LvHxL`XrK1dm9p5X)e(<0l`8|5uL^}?z!+tmboJYzDxb2DDd^u z@)8f~M#PwsqNhoHZ?Oy-`nYud#jM<%ErgPgsm`G3pkFmb9ju+#3T8BV{uIEk$>;#| zniKi)1UOpzF(%mM?mm%IJIdC&;WmTO=Ah-R6hPW`mtr31PAc%@Y#SKl;0I=G^RqbA zWy-J6d7gbAzDT({Y+oE%=R3p1X1x*=K*gIo3Yf85Y>5()n8X{c5Zhp9-`MWZoh=yN z4Aj6_=Q@x#+YT{?na~}ZqvL7ZK2_bu+CNnFZz<@>PC1^LmR_<`@A&GXNlx=PfhF6} z%66yhms3NCo!6PvaL)PrEea5wDy3br@l9Re&!r%j%A$?Qn@opG*TEq10}f4==XT3C zD20~AP0F>|Y-;V1;-iy(%=`i_JS$@G9Fn{7hB$72z4<&}zBiig{I_8v2&D3Lacy;S z=ip()Y{Jzn+%_~b=_X;KD4#%sE=in9uX3G`u;p``R1X{2^NeKzMc=Bzbnbvn+;*a_ z8bkN%1RDvat~)QJ`$t)kOH%IZ>bT~HhL<*s855TAd_i{U?gO{oMIS!v`Pe2F%s-Nd zE3L>P&mCUnF7tQ}mG`n>Cuo<8a8bUd6R9*S%+zoVod2|W3EZZ5{8^vL&E1}+G0mN& z`G+Mus>{b12QA2~BpW_fj_Zw;67%KLrBx+-8UIf5Ze;bN5*na5*k?nQj!)wzsq{D( z`32>tBb$8a%!E`*!Yqg+3l<^mQ*PIX2Nb7X5Yc1}+K=9F&%(hV;@;Mq;7i_43 z9`hf^r%FP4${bsi0-fJd7@%?>O;YM)QZlW)@Hxf>gP3uv#E0GY?ZH6KSYa|dMico> z#l%c*G~*LKrbm-u8#|Ptj-VnVuD~_7en6}L5cyvrbqND-P4s$bEEB4BY801-I*deI zx=w$?T<1l<-(6E1aU;fOF|(VJ>oUmu*NwaYN|!Z=CKwd?2DM^LgaP~EbvWp_LDBPY z!OqmOG|%GJ^{sm6-;2{aFCBiBdeRVG1DV({lP1+Mh5_zds%yn_5X-i?N!szvrd zrRYe(&usY9>qcTg(BF7k{Zg@rkw85$=UKV~zt&AEExu@_ng5KV!SV;Oo5Lbl#V@ zqc(wP7roUSg8xO?Jw@pfL2?jdUwjH*HQujtjXa*AyV_Fm0XS~5% zLA5n=-)h!Y2Ujt$0Wd=GzvkZ&{RkQ_(kW7}GDz$8o%Jo2DngsVC%h!m?QYEju~nhb zZSvu--5tZOH^N#QruqQR*m+j?G$k$TS?9wG@qjl-E$&sr8+y9@{5(Av=Px9FGeFs- zJSy`3W1G>bZVAy?f_yy3+Bv|-!nj8yWLT{$f!iaUuIitt9CK91%Es-s3rEr)>q^gY?ilgwpf+Feux)>JUWf=3TB3ke`p?8TLoF7M=AL+ zvaw6~SesSzMO?G8B)TWJFcG(pc-W(@^WbIkg}4y_q*UrI2-FbEHGr)MCeXEJW3-rD z<4dLxVOGl=5Mc~PdnjU%;V3260c7lC>ikH9%LYkE6Y0(aL z=O+!MBZ$ez_bHdh0FtfN?Rd-sIbZimWGc##OjM$}Y;lQ>T36C9JZMD66=_bR^=56I z0X4v!BZX-kn}!PinIgTZh{+9!b9j`i^0h2ow&+o7Eilk)&vlLgw^1l_M~ZD&MnD#5 zt9G*S!mr-uNo(fIAQV2U)IO}>?r*)Tez=>;{i;9rNjb8*fOZo+o_k?1D<^0R6YJ$% zXS2oT_gYCV67jUm9Z>;>qEyd(8GIvaeT82~kCDyQcN;o81L_KjJU{h9)~|j+n}LxX zGtmdJs|r1PR?1g!a*eVgDjf)}^GN?{s;n5xi(Ra>Hr;5+Xm$AcQ0Z2cGT`V5pyhqc zVi|Mp!i18v_8P@>8nK#W^}fddCV zCzhK?Zm?vH4#T7K3m!mva0yx#G}XvZ{gTHJ7_*~Km=FtCTQhCgV_2Y`m@yO_(VA#} zMWOJmTIVSIrh!>8XT7rYAc&e!a&BYmn$aU_FX~9v9h%;fHng^=)vOVA!0N2S*5~6o zftbr8-G==f^*rq`3gcJv*N%*EQn}hU_Wo^fN8(@23}V9<;=Zp z`@=CZE%)?OF{BJdjsirQr7Si5Ver|}yPRIQF$`a7eVrCCb@GBi;!+8$No^|`k4Dk0 zC=6=R#Q2|MV!Dz%#7Og~jybGpLt)#_+R`lztkjKL@msIM{)xqUI;yyH;^c}1A>~I- z$H*Yr4pnj4rW+~1V*cz$%a@^DdNA>GH1Zcw(6YN#-R`H>m>nHHET*=&c*xW|zLHR( z3vdGR^+u1l9d=oyVKdVul82<%#1FMmo!;)&2s~eoEK$wp^}XJYD{S8!e_SUnLGPi$ z$=%Ij9l$=uSm7uw>DZ8ZIWG44EOBGQb^a6^GrX)TdmAYh!~?SP zaofLen+x*_BVTFSsfw<8&H7GAFGh1}Qa#6SLo{6STmRMTiLao`%4I6zCUEK?adoy;lK!w?mn%Q zs%TY)qB?C~+PYP((1OSoHKuWrJ=tBPh*$;?DLEg_W(!L~GvOO*sViNsszj19tpZSr zu=vs4jlPmp=O_%2j*#wE%P{m2bIKF`=WlV5<$IlgyPSCU1w?daB5f4SM3*-scs zm)hn79PYhHcG3b$=Ssv1Al#Ffw2NUxlRLu|ffQV4@=+kHaIlh%Lr)lbfwUsjm}QIs z7%8fLO&r%^^)KlnQ0EqVPH8(LE9Bw)9TDD0Q+xZaHJJGk6ECPkV_AqaKkxb>*6htr zEgwU!TePt=e3_3$6nSabeBJbGcAQ*d>xzM{oqu~&m+i1Nppc${yB*GYi{VN$O!`Rc zccQc-CI3ig<$_}n#EygGEVh7SVSN;`xxs|x%A!SWMQl!cGo&@UMGG9ti`DEhy)(79 zg#s*Z6g*dy8GuZ{s-{Xp8eL1u?R)<~Jb&Q@fxE!Lck@G7i{imM2-g7P-Z`uhRXXhi zv<;trjdv*sB}xBu^KcbzfP=+7FqxmVOP&!O!Oa?1g>N z<3AhnUS9QCG49!&j4hlafk1$~8IX|`o3yyns@{|GF;Pf943?@^?5%zEPp zQ-T@!vI!*?P`M;pFMaG5Qf&cj0nR-ZW0W|~nm@wFa+}($4jm#MC%yD=VtJ)*aN;f| zs66714zd#2#q}Z-hGR95oaLY~R}$ZuX%xwrL<4P1p$)2OcsHqdOb&;ftA?up$3DFW z$oh3x0XxKb`AL^&-lCQ$pFP|cSEZSBVL@b;z$W{I2Y4CF^t4OuP%77RQ)qd-Yjf!1 zOirNT1nSeKOF&p+@k3u zxK6c0aB4(fOneIO@gDkgY|v!G$+ME24qgbPlR(qufQnD~e{0Yihra$wR)`uJZcr8X zpk)&dCG(5Eap;IVUSW(xXJYACQrdxYDkm?BBpn!FT-T^;nu(hZ_YdY#2^oh_07egj z{;*_>s*lY1yAeJ#p@0#E&0Ps%mBuaofMqbzva}e8%QbfD!LgEM7$6ancv~Ab zNEpO<&f}1SB|ATFbX&@d;oSUimba}0WWvRNH07GhBr>a5-QeyiVQZKuhcFg;axD5Y z%m`Xathz{}nw;C*&4>HOqIaZZv&uDRk~lyosPetxtRROLIt`tVfW*@qw;U3(cOXsP z9c^={WI4OL7W438_y>NU2o71_p}Tla!X!lvkIL?QiqHX*(^}^^l^7XvycrHsx<9k5 zAu{2r!)Q$?a*JTy-Vqm{428NF#>d+*A&8t7&lz#rX$4$*Ixc%W0N&D9HlQj>IsN@%sEvlRiVyrht+8qrFC z6^Sbgmr4?`pmI*z{Cs6+BqYT1fN0A!x;oqKn9;apFOH}vTZ6oW*itmrrEvy|DVht% z$V{r8`U5=iWT`L09f$Tyn2s3tV)S_!8Th|hCg28^$!jWzstRFH9C?pTcXq~ zC2AOgcTL0Ih98RG-@<@6prJ6YcDI-=R`XjZdBD1dCUu4Z=C6O8-%mUiEqH*; zR%T!3tgMFitN4GHk3haF&x@Lc$Q{yK1+A@9$|{m^&$4TE0=dbaK@|XxF z$4>zVmgOyd@KwUg#o64=WsmrSrMe~%iAf0aJ`*X@<*mNvM@vG&MjndUgK*-MxlZm& zM+;AmOa>edFrIj?RPD)<*&kD|>Z1SdCnXGtmCg$IMh0TdepQ4U_4gbo$Zh)na}axM z1y|-n>d}Oa9T%BjIIr0vEJJ1}{W;KG`IGN%dEy{3YIyV5?aQ$x!Dv&1(ddreuWBs^$`TbCo-xHLeA8f1HElbfM$px&*e?S@5`GIY; z7S^9vADgKi0-XY7i{2)o#+Z-rF0gZ~<`FlXAEaw8pBMHz=+ytK&4BMWN;0?JU4O56 z0pjy}hc!qqQIy-)3X1K~8}ys=pQ&%reb8aiN7`L~Yyacyi9UWhN?Znj#YeeUhgSgC z>OJNE+(!#h)@J~o|Ec+M``EaZ0S0{GGjyTxoW$Zb)z|D$2pQXJCP%y?6O+dtacZEQ zR@r8Agdii_(7&PfO1(*3Iv|oHebZO7$jquepW4?3$_cESQ)xX%1bxj?ra}dl*kmfz zI#?Fd#H5pL)5%)BKP2_%_DZ;cMk+`z2(Pf@m@3V>3wmz`_`61U8=%I#fhlei41WU! zls+MsG*Zn49qB4ughTpMQ`jTuHApeFt=c?+I0oc9m?e8eS2zvvh+GDc^g|X&QkGat z+clTeO&P!yFBEm-?zMFbLm$kK>d06uw%|XgG#(Kl`;F><`&|N#)e0nl<6&Y72 zQKvV&Vm>}&s6GNC=zC`zZ_1^K1?guUdR$c6w%lD!Ez$zNBpU7o$@(B__q(z!i^+ck z{%nkFcOVBz?ay1qoZRXWDtwPqOjS9E_{Gb&Rpv+A?%l&she<0+?YCwiqvIB^(&&pL zJyu{(l7XPoniWIN@^5=>rV)m5EVpT<&Um06c^lfOx4e5jcJT1=^4{XPvGYS*@~=B% zh-sw#255tlY9OHmDV7}qF|Ec?qQ-au`Kv5R zsJc~>^fG}@TFsc%T8wX`lP`D`!3o~DsYYp){cVzEFYgQvuG~mvzi zf-^A)&qRd&-FvtDx^HcuT;0*ws4bU9iAHh|#E#9Hox=ojoP+>EJ{+xu=)9v5l%~>l zU%%|YbA9mxHPg+jVNmP4>pLr*kx9d&m(#WTB%*GJ6-zJWME4j{y58=e(h)TPddaY+gh`= zO)b6yJSPi4-12 z-v(dAp&xj9 z<&G8&RIM9vE!iDnz0jahdBecUJf{=uuCq#9DjecD9t_QloA3(T>Wz8+Jhpxvs4Y~- zO{&!~1d^9j788x)q+n5)GN#8Rs;$=w5iJi1Oe12^qmem>Sm^2cMmX(V6-1n9(D5~P zQ2R;5bv(hsR;m?Tic7d$dE4V@nA)J)*Z@U=XOE>|wW4SVz?(olf=kksUp3W`qU&nc zl0FCmPM3zRpdH_1@02_Rf%!DG6d0yIh)ZIvQIAWYGkm?Qz>xEn;dXT?1J0nd;}(jK zUpw}k0U`5%v>{fg=3i_6o)~u#u)oR+r*V<5!!Vmp={+WTYtJMq&>uKvWG8DWnIIv{ zEAY!`#sT-`+6ny`*F%B?e(g#>|t9kfC^IsdGlv8ednHu4|{lBAO~;wP8tW z@A89nU;Tya*52h#htJm{1X|FoNNB^Q{(m`L*;4b>tYP^?E)s}yAau4m>C*#b@uLv#Eu9MnlDJO46Ky+2G#Yj zHdXg*@gXY~XVduG`MygqN8r*Qof}L(r=6Rgt2TN0&R{~e^)&}q@|4VpYun3VAY;RI z6Q;83jc85tk6cSMI>97*MD#ol+0}N^BmNVd{)?CYNAY-{TpKMkhtwD`3p>&zJBdk^ z%kK2hsknV>>1}5mRcN|>YuSD0AXVwn#*s+~h5kt5;gOAR0S)J>QH9+Kj^$y_Fwjc zU%8Aoo{7q%HRsE46sB1;?>Vkj9Nsey*NcOX!u;u_Rd`+V(;@3g^6s>!f6J0Gwh_7zhEm?udAl1doffns0T)V8Z1l_Z3+NKLiPwKsFq2=}iR zowJ(ZOeP=@Y&B~}Djr!~)(*NdT4&c9fS4TKlN~b%XXzDyrWD{y0upYtlsltuog3DS z(?QTTwC>qB!p-_ZwBahW{e;pf4q3o_P!Xp$Z95C>i4?vv-BK< zPMf*-Z$IKcenR8gaD(Nkt&&sBbwGxxHNPP!@rM~0q<#=a+*pqmXul;!gi)%q*YuO$|Lfd^@b^eoTK{ufNQ# z@)p`|#aDPU6g#{;ewH|IaAGSFx3ez7q>ENc0Zl4SG0tt&nB{^G2sfjWsvTdlJm(dlO`#sHfQGFjzmn4-wESQEmVIdtR_HubJ|fexIsks-8&R8XcdOaWq_c;-Zc z5}aeUI6FvH0&!{h?k6;#fELA z5Q5briRjv9kFHd%DgPTbhky#zaA$Rpu)N-?$|%|~kzqVajz=0fs3J0EbAsCQ9P_=* z#d!sZ$uP5Nb;8a)cqaj>%}=3z;5jJVH+YxFpGdi;D7;JTrJRTtSa~;P0C|LnT4IV1 zTSfzh{*}CyB52JKxk>Igh$(Xp#lUx$j4xAMl^EqbrNbM4a)gCtu$j1IOfa_)Kx!fw zP3maZ;3}}Ni?Zahf?btBn}u~9W(s?Hbf7c%I#!4rdf1-O+>=0cI9%3fI#|kYNSoTOZ&sGJw@xH)jC$&K5047nvVppB4v5F#(rOxO-nWP0Cm_Q zC8m=Qs4UlhVuQ_{@85~Sf1Ybs+#Oyp8NWeJuJu{P#uN=h)JO#7%hHV<3gVmq3mNkl zN=LN|Vh9K>oW;$5x`O8d?69xRLfz%T#X|Y-KifWc$6iPGzuAAxysi8Qq8+ZlvX{4f zH#64p)r64QoEpVE?@VPoy2qTAF-&IAeC-`Q!zW!z2+x3DEXV9FZJZNIZSy{!ICX*n zHuN;*pSv!+{xUPLhBhArxh^JL!3hLp3Tr$C9GrWO{XGZVc}=r~?|rl_J%ZM~)C?Xw;I|zQ_AK#fW2!La7$_qbT9B=Y+dOYwFRN+2pAIJl8z*krXeHIS4?s(oanW|6y#ei4r}Ugz|8_zJ*$rD z(qeHwVATlLC*!v38wv;|%oJ$0Yo=Z4t-28(+@J;M#XS0Jft1%*4uei~YLPyW#(s8O zlrtWyc7qf%H7rjn_9p<``O!#^xCxLhZYjRpQ0-`=M{6z^UEji-5@d1Alg}=L!G6M)1_Y?|ME(*cG85>u%(&l4k+MuE`imI zoPQVq5JZcs^D{P=fkZO4Bvgs4DwWBuwAsURT>$bR(t6>*?>0o}wWlR0B79Yq6kE;= z8a+njB0$W^Jk%6(7)dP|gzPfWipsI8Y8{57TgP$~4(x{|&m+D#K_+9=Qs>fXyhT+$ za2u_CRP6vns3{gIl&Ql%n<4(bmVS0#X5l6$!O&>0N%yyL#_J+<@yf*eAM3Cx@f?l& zrk;b??3@BBsyv)YAVsjV7j2MP*-vlWZ`~<(9TN;}uqE;V*&O54&|P85k%U>kk%JU_ z_@8{jWITac5X|v^7Gb6qVo5Gzy{4s&4bAH+k#Q#GH1?vnCovD}DwqTVdKnj9l4Af3 z(=xpa_Pq^+CMrXxP99q~&GBGj1*S=-X>e2(AO{)=!;_mn!OgrBJ9d|#SY~H8d6Kl= znlH*fDB^|BfykAsGU92@4LTgI8Zn3`cqJj8Qwp>=cyNTB+S3P)G5g6XhEWAUjmSog zD9OH6rp#1Vv*PL ztiv<>w9fUd=9P@ToNV*}5M)BmtWd91jO=4~_G?7lY?(zW#j-SGktnf7Rq@t?dMR6I zZ|ZfZ6r3i?Mk!8{R>izV;ZjYG@bJ$FqMSs;?PdOFJ> zEpop^C8$Cx6@vAw+|95bvmAVQaHz#n>fghy@DK6%>gvu%X}PatJg2r6AD?<)@t%ew zBZ?+sQrjF#?YDF^p2-Ic_&TXx7{zR?$;%L{D6XI7U1-pax(AkHD03m+x@{3A96Vt# zQg!`NIk7;x9}Zzh_oGN=x?`PDCn!!Ge9{^lAR>2wD*0xG(m(g32*uL+VYLUe*y#Qh zl4js_xk>>zcG9!%)Pht%)54$o=)TpvJ1zQc|4ZJx*X$RKs@nU~*|SQ<0iu?SOF2o8 zNmRb!s<)>a87yCynN{Xk@k2f=Dd}G`%(=%nX0?O)^A?m`0q8g*nIIe7w^OUL0QG6M zDb)mbX5{8r__6GEWoyp*t(%jllgC2>TUY|0z;t2-A{KkBcbKDcVR3Be54zVOL0t8@}isEM!%QjWnxR zn`V(tFrre_#VFx~Gkbq<&Tcmi1l#ZTO+iQm*ZECwd|+P7XAT~U$^#7PDY>kk*Q3y{ z#C|dY#A5J=O|UGHS{-vw^ypSh8O1sZFh7_~mMaH_`1C@|eZYYx%?4#DpZ9B8?&=?6 zhtH^55h4hlo7|jy#afVJjQV^FmS~?-gRUxnxe}JLdX0LIn6%Up)-Yn1X=WcwmMy7> z)w7oPH48@gnNiculN4`mRiT~T5l~ih>j@-knM|2>I4_HvS_BUc$qAz|YOQSeG7~qd z{^_bQ4IYF#Gn(h++5J;pKCG>Ek_U-Jw8)n}{03SK_3-%f#KdXji7{L>+h(u3pyYOC zo%uP$6r2S|s8)BVajLS-=aw=fy{(ksh}Y6q2&1-=-8;a{a=*iUP?UN?wvw;NB6|x1 zt-k}jRDSycUfcfgQle@$80KhF4E>$ja@J?6M6xqm@85k+u)9jRpNF}GD3{N4e$mUq zSIkokQ~x!|EM_g)_p=W=9v{!GtH;FV8VO~pe2Qzp;N*D~oS}WQ!*kvNXEWbLy|G22 zPU`wR=`0^dxj8J+qR#9r*=(C_@Phg%MAKMi7aEhLc}nq%FqLFKLxHeN2(0JREg5@Tx3T*;&B;P#Dyc`4#QD>=q*!@G)Ea(=k2BE&DrDMPL|EQI_7!BL1%1E z6MkvzTUt-VG~&u@d)N&+vE`Of>D+xCW&F#JQNhLJDZyE}Nc@%#;aAIu29|7uSw~ig z!S42;MeK}i@`2!8xqEf~aBgoQrN_;cg=0^L96TxnkvZ=6rtoQ^PTMfw4FUeOjO74b z;yXHZm7Q5W4eQg~ki4`Q>U84Ah}>X*{!{|Bmo}EAH}`O&1P`e!)&YnUg8ZG$45U83 z;jBl(B_Fu4%^0y^xiH*n9$|x7F=lzCp>gg8Y|&VO@?!Rpfm%t{0blB% z2)mK!8Lb=P?KBrI$PXW)^NC+dJp$-i%T|(+A~T$moTy76l8gP6szks+HSif-X8$rU zal`OmKdu-n-nt*>TsR|*H6QEwY+6aNX$%3y5 z4%Ahbr0F}p4;0^VdW4Jyi9{Xm$>%#*z#lOSW~`fQ0G!k)UqgN(Q;#^i70%1r)&uJXVwisI{DwRe+1lQV#H@3iUkb_;%gUIHuxH+JC zoattT?QZ~`(P~h&VvxGg(N1^NO;?{j4Fkv$9#p$2MT%wg9z-A&_#Z5u#^Z&?#5bs-KRyADWG(!HZ4_NZugDah(kx+r%2M znl_;CU29MW14Yb0m$#K2nRIF!P(UD5-0W)zsH2}ewN(<-zy23u7zB+#(T_Zy)7p$W@|{61_PcCOuLKM_dF zt->Qbk{*>z>UA$Cg#iWEN-%R}wuaNCu`LV;_GxaaBZrw%5Cs0#?u<=<4E?p?ou|lZ zy0n8f98)onpa)grO(Nb6$An6y4<=UXYTp5!f-g`iJP>UAqiL@s@R?P}C(U$CkuzOi z1Y_f7eFNn*IShQ5 zTPOeV&@f4-Y?<0a4(vp?X)d!Z2KAPk!Y7IHCQh0296G$TN9T@$M_aL7;p{0a68S_k zR~<%m0u5?2TZ#}K=qXZgOF`%XPDi|LBnA((NO1Q+)>#jlAhHP7S7+^MZQYyHA35RjUeDbkAif*iydrU*}-v@uU)0S2VO&|4b>Ylr6;i*HMqLAwECybbEPNN)psh{(sYN~ASK>u|j zqCmThHGYAzHt_#xA}mY|P5$4BXi=4R{?%rC|Ec#^cu_-E=eZq-{Ed-qh-9j|bUdr{ zt^_AqAyG*%0MLl{-vz~IvbH8WFYHE`^7ZNZFic-+A|S|L+)Xb5pzBW{w~d(p5Qam| z47nMc5Ji|4TWWff&H47sP8dv$+S<{lM`tVqH1^jSj+t5F^t33F8FWs<($hRIscko+ z(Nq+IKD~H}xpM1ra7VOCZhDNn^8FL(ejOKx?GZKz88r^O*Q=5mD;JWfqo>!p6HB`i zP=|y=zQYz!H|K=CprH;&g-wF5x~1W;;QOw98`r2Th!^xxO|W7* zldDs0m?Mg$+xx209TH*m)9+9|({H!)WX8URei}?GUO+5?OTO!d?l(BkF7|U{EEx4@ZBKp(zdN6G`zO9Fz@Uz#Z;$v2`%} zEuxK?$yHbu?C$+DHR*~;@OXCJoB`ba=;C@x3)v525QhpHlYF}`s@Ww>z|F9QOn{ITm}?#q1J+iyfm(rkTjKx1+Q@pHVe;^J#>da*q@fR(?>25&Zf-9i4h)@zKjX zo))RVSLl~gpOl*Woad<+UB-SjFT8&d|J8`sc}9oKmif9)HevY*+!-{2l)O8Esx+$NiilFlB^KQ8*g(<^^wc?!(b^W`1 zi5-DWmsaPg8DsohFE4MqVcwi)~1!vgiCiyZPr49Y;5B$8jAP>s({;pqK=XK@24`0dXXVV*xU2+0~ zZz!JrmzOzkKGSp?&%k8`S>+4~%WcPGRd4ZddDuVG(w;0(>XF}k*m*|j4g9~}n;A3v zzOs-20IO*K)4gfsY;R}m;6V3_i~Z*!nX9qsw8??wd#e6;VMx1)#F<=Kv(bopMH0vC zNR__Mv93ZTH-Z2u8ABNa9H7>$+_c+Uj$J?(=lm2biXc$@;qr10))X9kWK=lWsmPqG z!;$;3`1i5*PYuym{0iC z)~?j}a)z?wlA^6`$q{-bzGWc%d38_ADE?{2$5p&s91rdDdj~Ttsa(O7 zbL4qa*A4zl&ClkdOJaZ9-+!KOO;)w%^+7L9buF}>Yy2+JEB%+5|FD-1_@q_7+a-3~ z=`OOTLM$lGBP7V5-azKOIoOIk;EV#-uVh=#ZqI|D(P@#pZ`MNF-G;ly1WPQFo)? z8XJF5(fFfUD(XMPnGc}mTrB$K5TL=M$)AgBSAW2+Ny3nGxwY@|>v6b8qatWEembu4 z-gWVyJ2fnsmiwCJIK0tt6A3kH0%i2(=F(M09NC>HM`42#Rlf4%Az_2Is>jiqorGEz ze&q$NuoA_Uef5wXqFAh)iYr!n*4CWVma3J5B#_9`ZNvk@$#B)*HF!Z+#!zQP@TBCa z`N*fy%dnO)uwKF=Hmjf4PxK4fYH1H z838&DA1yU60lzq(xQb<^4wCF&(au=!^lS24@$?T#8Nk`x;^LnQD8HuB*Fywc@6T@W zsYat1D|opfOG8NADJxdc373NM$cK>y#W>SLM}!myuO3F)V*?yjPGlcgJElFF%LmgP zwMn3)2?Y^9sv}$YPm+seD?pEz&aEx%TQNAsYCsiP z@1zQEmC0*?sFpx1h-LyRs)O#~Wv-W-s85$NU;pH{V7fa?e${K8*2kAV?aeso=QwUw z)T?D%)vJ;1;}lXqHA9XG&y8m?X_My;>_nX=*^qmfYh?+f;X2fjobTdL&CV(6bh2qT zU$;z#aq;o@a}K_^PGBW7R1KN%a6>VR5YBkW+dtRt(7Th5U9>3_2ak)jFB48I_L(VkjeT}PP36sXS^)jd{+ew{jr={f&$fL;s#+f>yAklDW%-|uc zhkNplm$_DFDf@?9UKqzK)UYWJ+OHmBnjtNb9`(h~x!dJrLJ7%hTIw%YW*zIVwLV&b z|E1}23+y&J2QQej*9pcI3mKQbG!=8x4{k}(}PbYd0(#b)L_fZ;G8 zN_F?S4b%u#l!8|bb*mZyP>rI71cYFk%A#vCI!=1mU`@YNXJrXzF@?SjF!x-i`MgH1 zz@~0L0HvdkGSQt(CzZnZQv;I@m{m}AkWvZ3~{CU=1CBIyoYn z4K3%JpE;=5T&$rF>j*d(asyGibB6h@YT3jQQK6~%n zT$I;19QZ+@G`i?&o}8L0`sSu-;)fd6w$ih~xz|{3t5kCG*{?+n$}HcXXx-gfE%M9T zkhF=lLVXPG)09ZjtJ8Ch-Swd3QYTa|qu0N-_OJDlaP20T6@eh7&u2PC>>#N=T+!%4*sW^6WSGqBKLKs#BmO^s8@s8R%**TM3UMQ^cnJJ*>$AAg z5u>9#kIzDDhnJWJU9YhDLL-J|Gp)-_@vbj&s;h#+t!pDur>zuuN|%zJRn-bbyLG>% zXsalGW_rryMZS40`47>NDLw$e`w9r-Mk08n)0xKGgSldAnb3Z=FJXTK@6FBmi*2a4>>atUYrV7A{$yRRKFNMDbsq|~p@B$M)iuh`yr0zU zhU=SE5rvJg({*RQwzggmAE_|1H=Y93U(qoAHYw5+Q)i`fVE?04;_Z{zy`mAp4S!J} z$PM(~SoMr`^oMLqX?H~$zT~q>&_c6AUd~P|%gUz8p(o3_u+0O*zX;NCG_QmFp*fQ{ z{7wiQt<#|@Tk3Q|Fzplnzb0h*!BZ}R0002uzX#5L%fmYTJ}lXq(z$rJ{AWG}Jt3hg zF(FSkBRfMaNi#7$r#w!hCLuo~O)EtsDXU09J3B26PE}C>5=CiYl9Ga=asDqoJ^i2H z$m4zVBI{H8e-gD20JUny%BziNow~ojZ~J@T{`X_B{~d$je@zNmry1b{1Q0;ycPPcE z4ZUjQiWIF^vg$+L)-`qVgYH@5qjSL8H7TmH-N3D660seR7^)H3%Zfd0e zKXAC-n`&tUpT8WgvFeTlWmIEs3D|H0vI zq(E|IOk0(gfX>Mci&mcH#^Wl^OEEKEFJ}0coso$liM(nKHOS_)j}763CFf zZX2P+?LTk?4%juK^h(%UxDGvM6VRO{(gcYcAX}GB?^AOhpJ3h?dtmP&?2=LXY!Z!& zwl{f3B=_{g8=RyM=yLp;Z$Ab2GX=|5U-GXPtO5pTr=mL{EuzjD6f!{$X~;H1BScbU z497_7CB$EzGYWls`W|8o^fYY{#vH+*0L1Y3mYq4W4ibU06jay597(%rmVmoAef~(@ z{!a5j&ip>zKL)btKFxw?GlM`Up|0D*ZBsFfB)WU?pN{0Je`yD`*Zf%G?2QJtC@{-C zE@GNOydB&QEi*!mIbLxb!txG9k*m=$B4xB->&jJ9laGm#jJpD(J%613Gb*>Bj4#?xKv|jcg8i;ojT(m*giun=(nBI$PQLX-pyQlzlhsad^@nPMJz z_5bB?Z~lYBb?X1W94`C+FAi7x|8Th3XMF#g!vzD#uX~gOOyPZ9|Iq`J_nTch@@Vi- z3Vd9CtCq_*hz$`tXWxUnq;-mL1n8P8>f#u?BAa@nnDi)S*wcudKw+yldYm0ydW9>D z>2Lga8~}qKWf#l?D!Jb49S~>vtsy*@SqlxC-^Q(5zrL={2k(hKoSOQl&-EqP=6;8I zeNVNz{?w!XWp~PI%PLE>L3eotCx^X9S3;h%;NHZcNGFazMOxoa;38;+1C$B@-K%#F z1kVNqD16It&H`F$cgVeFgtJX7Vc5KzcJ~TQq=gYu>@opNlZL5NBe9p9LB42OEaw&f@uG1rP4gz`7^OZ4={&avP%Dy}dcF6;%oP;*$?2scUu=j^gV;H{} zlL$ko(E+SIp1gkVf_pBXFE#ylj97|hQi^}q5tGO- znmQ;1)F1aA01ptOTA73wcwVA-PV zq6}G~6W}KS!|^y0nV3g*YW+snCz3a>UTa+;_GemdZ}agVxzF{^yzO3~`Y0lX4-9wr@C^KZ3z$-#w~NH|=GWR&pQ9U60pSCDaT$!s%k zLk3-eK#5n0nmk|X9f-8m0BFNe!g>NoEc(ES_ThvVM*G@y{R%p6Nl! z>27eoIVBBz-gj@7JhotDf_2Vs9kf^T-4omMm+wGxJ0--% z*B)Ly7z~@f4*q_5Aq>_j6BC8V5T<`nAz(-yzd~HyKZ8US90z86j2JG4DBZ(%Q_$?_ zyNHRSK9M3{5CRECTmVk6FG}%yC0eby(NdDrF}>(tFr`W zdE(6t!=T?dyP@|tfm1FlP0@Kj(f81ZiiqCpz+o?e`jxh;13-J-1Qu^}21DIRDq-gV zO0im0z2XTDf`KM8wDSX*sU)Tx#p+ z5|(b^z(CqB@(?CFf+{G9IP=roB__87>h!0Jh_Y$|_Gt`+J?&WET?-x!j-X6{q>5uk zIXLnts5tv*hj{ovG6}L~4z!P2Qe6Wf7=;jdXd>j2_dpLRNktDvgDA4-0HUw=8q240 zZlju;3xaLnJ+T=Og_<(@Y>P1bg5Qy$wEy7D6(x9}#F7JOv2EM7lRBxjdUdbfz4tkLjPqgsg?GN=na_P+!9LF+ zq$(NHipHS0hfNL{n=8NKORctR#bb3Me1*z&f%U0cR83Q}B&~(FL<(!vaN7CTwg`?6 zSb<*whbo%nx4rzDu$$JDw28$ejK`3rS=PF&>G`_gr$K#|paWjI$9(M1RjXbyby|nQ zwcCM7a_ZB_x?e@BFMg8kCtkcTU+C}F0gS3(%RIg4H~q1R(_!N29Trg84s(A z>jlq63G>ySI{vB2aE~Hbv)RzK?IydICSRBS%$crA=h6M}?t5lK*b*E*>{}*Ij~4#7 ze0dtCa;U|~LneG)5okH9K@dx9AK@nNt3gdPP*dOI|Dn&Vs%ntBc8lpx!@j^_+#&Za>0n|{YVoU({ z$>)n7dFkx{%8A-o{@ZU+AIGT}`sRi<`#IDvmJrq<#9H8QBO%-CfczPZ3g~^$BQ>lE z)j!;A--gkJgJE<$~6C%(kOsg2R zzDDV-RY(wA%MqSLnk?uWPLjT7PM0)pwr(9A~ z+b(b#%mck|<=|C)>#0?W7aq7hcCCCta?z&X0lRpT8a-g`1Wl4kX1~5+BVOAXjrzaq zw~hsB#9%=0Wk!dqb4P`5ZK^?a8OK)CG;~_&fu#%RfR;{1fjoHQdBHAWw1@ajh|}zYJ-`gSK%&PF7~_-#60k;iP(AEzMWVsk)%Roa;^IsILC}0_i&Sh z_W5-1n=^1|9?-jch*$G|+-9ei1~LK9PE+G}gFo!5%=LIq=>WWc&O?LH9*&NNy7mFK zqA@LT-a@~V(_xf6`#H6CjSO4~PSyiWXcOQP(u zrUA6c!K8w96D03rI0d*T{dYqq#AoVY%R(KZ}?}o zc@P#q*dv0UFfKMm8((^#-GI(F;n>pqFWF<$wz`|RKadi%do}Hg5ApGH(__DRA#j^x z4(5B^Bp3Z0N9%U37OC_4^)tDK8!agq+ftt0140I3B({ZFC7bhRp$dM!-Jl`$t9R~NT*#ktGFF6 zZ$6?JvfP6p%6uQ>@|+yG_}cp65*Q0;yFw%IJ7$J-fJdGo19$s)Pk(}?wIZwZPHTrF zuPNxyFf)Hi_iPVK2kHUf{$n`;5q-8Xr7KXup7i+Z{8iki9yGi?q&eT{Z4;j@S~R-N zUMM`j-Toc3r=5PePPc0yn|rewZ}_3f$DHh4|MUt|PCM_^ax64v9`wWy&!v=J@-dm2 z*9Ks;8=eR&?{&*C?>$pH80drjXg!;i%XY8l1|;PG9R;=NMLv1@9^Su*+*o9^Pa?NF zT5MbP4^MuP!#$%2*Hk@K`7X=u?{Vq^!CBaeKq^CY1JMWeB z!dfsUtI1{hVFYZ@Gn2q3Lc7OXT)QfycXeGX+zWo977G?TzE!-s?P~Fap+0dnC1x44 zcaiF8Ue(pVkbMvfSOJg$VSnL0tfI96A+v@OgcSdvC&mL3h9fX6&~DnRbmWS9vvad+ zJWcwPdzRo}Z@X@Dl~=}(`dpcXRLE7jsGE!mAeKX8s|%&l@}mDAMDE4Eh+Kx!VE+Gs z$mKq>Iq6g0ji+yB}Byx8 zh+M=^B6r*{i|C(3F2dj+L@ox-=)V)Wc;{?CdT*IT>zxmcRX7L$JL+%!2q$ETu>+wO z3wk4jqMUF5`P$&>AX3BiF7sVb(T+|cZ#`Nlo>K46Mi7$j&YD~T+_D~2e6{`>>;t^?0P6kCR# z9nn-?1>FJt_TGIp)-1dnmV|~R=Qm`(u*Y{Xgx6;`1UUWjRl@m!msqT9_hSj}7!tAj z%N>U<7Q|TY4qB@R51oLmDCr*6>-ttbEc#69#p zzloGHr(q}B@#5=7yas@2+aXV|FJQkQh4egL8LPa|-l~4t<1YxYR_DURGlQ`zBPilG z5N3||$d5qvHS`xFPJ){6?$KthKL-oUi3p`EwM2%J;73@*vV7BaoD9-#mhEMFd^?5x z#f@uBK^o~(3KMa8^i+GY-gZU9tD1x9YDYd|7z*sZ)vq*~SZC|x zz#_!>5JTPL+N?SZqQIKAro=7_{IcJUIegHpwO`X4*gfP@uE&8Ps3#(R4)a_uKM*9e zxN|Jjx>&`6X`O@qZj1ohECE4_`zY^CY6s2E2s*bTl6?ihTg(cC+IP3CABZV*uo@5@ z61Si{J^=oUccvJ=layV$cTGsGzQ}(|(f&lrpu_fUljn>B=JP>1M3ipU_xN4#@wVdtOXqHIKjd>h>yAovkkCUx`@D^9;n ze|EwDrsRM_F>1xZ2uCD|@P?daG)qD2nzI;WEpe7Aj5jC)P%F;1hl@vXQ1ABuP3t7c zKvbt3U!!c{i5%{a@Yt@6!~`JJE~{XSjKbce*9fH&?a)%Ir$@AWv^@b~lk}h~cNxT> zfDaaByR^i(-KPx8FrZ7%4LYYsqmfqr<;jHPFCq8wQ^@tk|4Yd26ZHZLM9l8IDkejWzy<_sF9*IEsdrAzpO1Vyo zixG#=P5*+s*4VpHujcr1>7!que%Kv~F*F6N@D>JByB?er^;H0z=)fe-O}-2dYUXrB z69hV}f>kf!otI@d5n8wt`{fMB%OTGjid^pP3ntMM*p1XzVCy`0*@+Nw#>@I)ck|jn zR*58gJVC(1`oyfg!;$M%Y`XzP00havo9zH@LHYnbF#M8PIw1(R!@EfqXnHm%WvPPU zqj%Ix?HMN0i@S{><`7cxwGf1|FhN9|1=K7mNfqt^W3qNYvPy`e_+qD5UDu>?nC0Z zKF%HhttV9IvVPpn!i>S6tHl%Z9tpLU*cWT;*s?@yQ2`~F>Q#?yx-*04yR)zy_LfOZ z9b3Y#K4(&#Xwm6)^NLb{4lBfZJNuyJVZ+VF>NxTS34~K`j%X#%fq;&R!ZMuM<(jjR z6rus-s@!a$-p#!1Y*@b@2*OZ9_}a~85c7o8uZ2I21gex}%~-!2j>UQ|F>EXm1Bd55 z{BUt8fqkB-Ecs*Li2f;A?D$-5%&MGLNz*NS;j>7hW*`@CnFVIf`ZZYhv;A%Kant)1EkOnu(=w@_ zkP~>UR$C=NA?&73Q|Ewm*4-6~xei{`cjhqzn!`v1mQH|;)UAFt1%^EZ`5Th`RXw8p z)uO~uw_-C8ig<~~?cKDbbGybsj?P<6AQ#9u=Vj3Q!}V3Gr&A*h?#6UF1wrsw$XAku z;HNr0ROxv3*n&bZ1{ThCs9lVi6BV1`)<#U=$Xb4MpQ`HE&YhKvfp`d&i!Dy%PpwHc z`Tc?pUy^`Fy}AzIsKAQ@y)k&*Ae~@mfZrT9WB%)K!1vn^LN%|X7}<&^+_5# zRHT8?SP>*v;&#hNI)1-O5IyUHiHqF%(2c@6WpbrSwgPdoM%%gXp<4sXX(z}8YCqbo zwJT`zzweUMHG00Wk)^iOtGPe*D`hq)F%S^+gQ<=(W|pAbp+hB;Sbl33`H|)b1>{ao zYSAdK7hR*E-pd-meu~pHxj?1Aa5Ul^-M0yh(mLIeTpNHy_KovBivKb1fHp;8br%oO4LXI9J-tmY8!8^edxZNH#1n zgo2rhAfO_)aujU-HZ|rOIZB5x2Y(rfl~T4K_fG*$EX71H{xsDp)JmG&^AKz3`rC=C zdS^!Rb!adv68i*am^fzjafakZ%(U*$P&|6S{)I|MSCAZ`A7Z7KrBO5M<_BG0$*iY=YCgLZU^qm*ZTxevAgB`b{xa~Du!~$p0L^I)!ri;JQIp%+nruX?C zI+P2^Zc;t7do+6qHLPBI)B1Um`PNE0*XcAmTuNx6_#!v~`bDemh&;1gcm&@3CJl=c zn7lQGF$B>h*V;Ri>lk4kT-6z~-~Y@_9240870+ z;I9S4qhng`dV(nHp1p!0!oh?AHOn*J5!hi=7NY1JXK5RE$*wQIAoApjA#23IMCB;Q z7O+MR4e(e)jSP7SI=#LDAA&2AldN+!hEJEQD=7fYJ7?Z1a$q{Mvn>qMdSC&Yb}Y6U z9d4)itsBlG;TKyC^iE`Ps{;f-$I3Rzb3|&)`&@b1thIS`rN+|DDBG*;g)mJBB(Hfa zWhOcjb33MklVfnBpqP>^=hr5#z`)74TQh9lok1S!K9;Mr6I4 zdJH=pV40(DA!+ic&Cf5aw=Z^l*op~jySg=5P6siMJ5547%nG(CAT~M?*%zPd>SMedVZb{j%sI4@jEv5qUIb00)tB_hBp#*!iUX6PU7F+#^0c z+6lHJX&ibFH&7(3hN&cRpG(BjsyKi_SpXuW*QLtD_}+wQb$IMZz6!$Aj`5bgIh0m& zdhlS0#Xm4`iGN1<31D>HJ(X>q-(b4z(?>WmrXz!eK0xsZIN zJ;#7KlGHHm999@tlWRkk4fUFBIg&e@s&<~?I)xl9Q^F%dTj14)>(4D#G{+O=gx^po zh)pDmG|Z->!>p42Y1b9@t80tlg!} zWNX}izHHU@ro)YMqFt#fDBi4IZ9}(MIzl%fFPIv{w0GVpSR>q+cF*zW8$nxS(j}aFrn+nd+fFzi_r`W5IXp<1eG)2-89#$b>fpiFc$?>>i(h?jdcg)6s`5P!DodnIn^shu{jrF<*PB@u-$bDP?{*hwHfciliFO! z*`wd4bDhORh~g|7w}IUN5|*ATzW~P~urWd@@|B{mQE9_`G8F7zB+S_rc7T-F=OlMk zlH|a2#IobKQGZ>;P1^GrWHlI~)+%fj_yIj7&UiJN-e0q>x>xKYZWdzBSGvFB8+Ch4@0JS=$*Qi}cU^Jr7B;1=V!wp?2p=Y)8 z+H}=EaXRy+xxNQz$UC-(DXJvr2%`BA+@lhmpCKo%33Bm(_XD0T?<=+f0qNW6kurA= zH>{#Bz-NakX2#Gk1ui?vV!&L_;B=VysK>3;*pZW1Lq072keh zbOJm1NU&vS!ywV+v4LfcQ2OX8VT!^;S$5-$lL&P0(x=Q216Ic&21l42ukT|qhagxt zV89L=(Yu0uPD^h5p@|1Y>G7iH`2k|ISv*F?x40@KRRfCYCgy6H!Z&8P=QOPO02K6t z0C#lL3(*@(41J7V)xH3F@sL}0@Ybf8$c%qv z+E}f5_9VEY(|yym&*<}##_0^H@T1NdH~=#RFw!&ZdOpzdIBR`P%P+2+;6m%27`A%u zfTZ11ZnbESb*%9ODOCtjT^`oc=SX~hzDqQV-Pg?PIa{D|*ZAoOjdyzY+VOF*U%Uja)3bq5KC)tr&HY~an(*gK`GB4THhi(2y%Jt=bm_=7fl4U=9%RZlL~}nNbI1H21a^o~J z!EEEZ0sBb9k7FUNK$NF>MRsZ*rw!Z%i~->%X|~wr&=Oq&PbLPg07EQWsSws5hVnMW zd^K@*WXz^Dt+!++qyfX!j-DX(XxAhE)yLKRU;DTZf`9XIJAeDQpxx)7|Ha2GfBdYM z{Wl-i{eSjx6aV4k-v8y}qJ8?fXvwPo@^Oj&J0I8m^&dWN@85h}lT>4|Paij}O3Hr4 z_aJT+Gzpb#+jmFQ*`HcUPvGt~PybNeyS(-*H_APL8Ow-nDZ;S^jU`%5i9QW?pk_*c zzB#pQ+x4{e$n;EHgJHAfT?NM=?AyGNZt3vX*#1h8y$K60NeW$@uR^vs^VWbey!EZ5 zTW}_T6Gn!!Cv9s6^nU&;g_6yg-2-A?66rRas|wLqUFJv|G#pfrmpduKXkdWp-*N>9 zNsT{Y4wR+|LI7@EMo|u2W;yOc?xi1PS1{U0QK>IQEQMy2HbWsmBa_cZa2*fj-+nGZ zj$1Ta9*+eie8tm4Uw}$!2vxlOiO0w4igO2CCgU~x0ybaxR)nG`CigT9*Z(Fr2G>6v z;U#r67~oy-W+3tF>gU@9^2WaQ&FXH(Mvph@Y~b6IjF;CWUpU8P%#_68UGyBtUd_SX zM@A=L!H*`Dr^|7j>>0QhFv$VWS;_(CrF92FzN5+gr=Z{$njgVJPT2t9b`A1rz)tWG zjWx$3w=Gs4069(1fJ@PFcV352kZK=vSgx1v%#=lEghHY8I#F7m3v}0VsX#@3`mNOi zWAN@-<3^goB5jzLe48w9Q9Cwl70ygpj6HzMZN#`MPxMcvFIu7N_+3eNS)zKl`64l! z2l(hv3Ci=B>N%VK{ttD`B)PpWGLh@^F`>2Hb#qBnW2KRGP0ZVV+qERB*oIe$AMWZv zm-kzX_S98s)~N-Uord*t8yfm!1A9Fp&^rvuDShQjTa=-EZo?4zK3qA6_ZBfnN5}9I zmgARH=lrolP}8qcFXizbn4tqlfzg;#yitsC7Z_f(^YwFWZ3=M1u%l01@0+9oF5#ne z5%s-G`z&(#c_mtlatP?*0tNw5?lx>P{jL=bq+H;g96f{4oi$Umv9+8YZu4BL%TqKY zBH~X%#wC&V4v^p&_Zp{8FOO|*ZIR(3$U#>WSj4o+;>(Cj)2eoIHz7%i4;s$OWUo5L(Gkj~0H?ngd(!%wHY`jBog_JtA{_LC z#fQ+5_Sv3TNHYMyv2IAic3zv|T?uur$r+qeLqM=HI8=mmbrPCR;A6|n#^%|RQmlYH zTQ}V0(lFQyJ()#lj&-G4&%j+pdJOi*f!A`S9a)8n&SZmM(S2-~q#+QV(mx0p~-=Q$pPyzbI`tvAy_gG1u503RW;tpP}M~Eft1pc z)pE)RA~HBedNNWydcH#HF=nNmVIQkdFG!Wfu@oT|!CbbRU9~{hjlTe<&rUgtVweNd8LWw`u8$V;1o?g&qC5=6yI1@FqCu zX-Yq|4NZ4gX8t+K*u<&s?(;|DB53yFb&H!WkowXG;yGgE+St+#0ayY2qsFfWIbkUZ zIg*EJ&2Fm`>_^d0%5bxCaCfAZ!;>n*skR=6F&2m#=}iy`Po-TfO?J3odo7o}awu^|IAt(dj|0 zECiGOamoWy+qOs;d4+DrF!^6oHD0Xl;VYK)BY`7%=)7n$t!1Jx+qi>SK-y9L>_Y16zkUox2Ia1f$u#L-O4Kxq-3@9 z0w1>_tDxkOOVaCE7~7281z1oEH(l3{ooS=E$Wr{4FEbh#RE^fh=_vyi*9Qui2qzXm zqL=hLlzwd%<=I3%sjS+cLrNM6-Og<(vg#$REKynateL?o@@O2Kj1Mwmx8BOG#?~#A z63n@Vy&l8METZTZtUa;>RMZ@bDQpkTqI{8#t4Wrd&qB&kUEe|HSj6s&h>Iy81aHk( zP(9me_3aQ`vEEjtij20w^Og%)#++(yrUAfsa5MhQ=yyrOZ_u4hfk7uyjL1^|K;L4| zEtmjp6tNHtE2P;8T)HJCT^&a`V!0dH8z!7Da{yd4NrV$6uc_&Yn>uR>U=+z!USwYP zF2>~=rc+W*)yx~4k@FnAE5S_jLs%2794lYvFOJ;EyP8$7fc{hgmnqjQ;~HpA83t9H zm^o_KkE`E}EVqF?hJtoE5ra5{Zcw|AKbFOFjcLU$+hxEuC|M-nU= z!(>*%!ZVS)+^C)vCY5O(a3nT-=@O%Kdh>;n|k z7aXwD5vHc6F+i-n!VqlSY@{-4{qe|0$ypcjjR+LUS`oTJM#l6m+CHra^sBPm!q~?p8U~f$GYv zr@ng(_Zc|()9p9ZEB2W6vvh?H4U@F8t5ux6w5q3^$L(cIi1Nmc#(MR{tJmtQ!fNLu z@;w1>HhXOj`VHsHOB5gy+LYHK`@G!J=T3Qvjn+LllvIlrqqU`amrDuXdhLJsJSBJA z#~aRZVd)NwWA*`#1j#X^d-BQ{kGc|?ey|oaeDUylPwS_qHABqFR{lJyb=f~ReOc%D z3#9N)9;EqSv*1O|i8(t?$qBV(k(T6DLfS=?*a{a)*{%nR9^+uTv~AAaYOoblp>q)h zbIarmCe}Uer%#!(eI+4mgzQ{sX`syE-U;FU&S+SEmHnD>~T^X_Nt0F7%a(*-X zVAp+Q+g(1wyPdcc_Yt4dZ@eosi7GJ^u(v#Z(?t(&s$MrUoT7rwwg<|)qB3pmpk+;7 z*ZUN5_qhgyuQ>>sZg(Qol0Su99G{3sDNK)Shfg8*?N1@si=_9rkSkD!-pY}E?(>(B zi}a<_uJd{1Q^+Nh{w#(36mrKc)jG{{KZRT;WyI<$LVn*C3>*C4LM|5cUqbHAA42X| zy}Da8s-L)Kfxm^^cU^jj5x(C-E~L{A{DP#`0N$sN3j<`CwD#?{kP916T1RXnfB1Fy zcrgtnh4N1!mm~j6{xa^TkgJ#3TKcDuOY_ZO(mr^J@wbqhY;{OeEU9hhlOw~d*Yt!wX~KSr6WWChmcD{)Qpe8syV~D)p!Hs%06WNr;vM)6uwGbpZTYd z>z5WFPRYNep@ivPii|#pnur+}#r3@;5jluu9`fIX+(uE4KZIP=KZV@Ye+ap?U2MOF z+^?TP?rYemkn1M{@mt9C`z_@1K4Sh;$kqN7a_!cQ|1RWq!O3vltIwJL7a=!Zb@X3C zuHL7RJNhZ)F7^B&Lay&0 zLax^_JzRPJZy{F%rkU@zkP9AJKlpO^hmb4$Dde(!3b|>&gXJZ|t{JU9 zHpVX*CmI1LYLyAL`gEUG6lA=gc^%Sv!=HH68x>F?(Y}$%b;_N;z#-t@y|k9gDQIYM zTJJ_F^QZ&@4d}qM@kqVvwQ<5kkRPQ%yxcB3i+&A>MOVsdX;_o(oU;?y} zM$+xJS04lV9PGN85q*z~eRt?6xC8DdNr5Bu@V9ibw(@1*?~LPH%l0p~tl?8AS7%@^ z=IxN%(TAJUctq&M7#^>86faFl%lf3xx0^TosRu-7O5oS4mt`G7*?itF>`MwgU*dvw zuN={tOyJ7Ufw>~WQI^;39AxdVEJO$fA_ubE4PYc{2DXxZ))yqjKvxl%;8E#XF;RHJ zI9JygZ@PZGKPsezm0?c7-y(N>SNo!Pun93kuLL?XnZ?Un0Hy`BMFQIiJ7c|acz8}( zZY_k5kNIpK?nlKU;{9QVOBOKuy+Ssx;3_)r0pF{89cV|?XS=?f2ZRe1q2J5vWFaX& z)wk$dPF)(cv5nB>)45H6!0eUNGfaYF$Vw`2m*iOQ7U?m*$rcr2AZ`>?xz@;Q!gws+ z71*Ojo*nHZ{z|=<2`4b{M=RTs>y_&%hmLTDoCtJ+tC}<`KxKE*rP=Ui<0KuM>z2r>|M{X?9;ViqLLk28o4-U_JT{I2aTDwST<|yS zw#Y+5RovH$;#S%#3$Mi8-uXtW%-kXjr$(v9XE$8na#UUOjJ&(K;i}Kz(?yMrjw_4< z)fV+Vp3`B z-qZm+G;EZ9P+sFYn^-Z}>A06dK?TCv7GJ0DTfn zB}1Gl%q14#1>EPw&6DGKp$fJO1++Fj_JK?}nMfn?qF7Yn0^8Uig+TEr3I>e#Z&4<4 zNy}N!9&`x@+8@+Jvl#U#-1~2kERV(Q1|}q`5dsttfVlIP@Y14M*Q`IB&O>EJV~D*q zTsO4UE_Jql(ha(oft$NnFDnPG>vOVLdZc+-U~qyhej#>$)TDBe=mY`hw%jtCUUa>R z+7am_v3{ia$u5u~i6+i>lykX5ElplJPjx^L4ag?~i_zfIjw|mmHZ6vIdz53EH$}3A zA$kh4(Osmu3HE9%4>{*zw}mPWBN+hY)LHq4v9iseJ7gKtDC&Dkhg2yVc*8FuAtZ~{ z$SD=EJ=y#dewy*ouq4iu$d8411ZVFTA7{9jdP+r<46>k@KgHU}@N{S!*BexGl4arD zM9>Amg=}%VY4<}=xf<=#UJJ?-h=dvg9feqP8AM=2xchzDP%`m}VLPoY50g_#QHrLS z3V;U^L6vnfRE?fbx)R$#QV1YCjNF28uFKnUfG)Zx=%`%!^{D1G5PGUdW!=g2cJDD!D&<5Zxa!?R_?#M;^{TraZTfe;qqDnWy*1$Q8C|6TG$pHzT=`U7Nr|!85oL& z_{!Yx0{-q;UU=|43AX~&$33EuDQe7Nxtq$Emk_$MTcPtH<2PW+icCx(6{0b1# zYI3H08aRFrvtui7*E|+Y&jgnkOLP&PY%n)4_zPF|8?X1n*(x3^P@dQf;o`uG%Avgh z5W=e7e5y7pDoJ>)U(fKHOHQkcmZ{4RY~diqO=@Lli^v~K(pyXKrQ1nvT_M^{ORW|J zPp5F@1B`7}t%%jOQXmxjFQ-%!xAfNzjqKpWG-BC4Y)~Hfj~#ODyyei+cJ=C=#KEPQ zUkN!gJmWEcL^Y2z6$#uxHf#h5^V;J>E|{nDb-+8N`q)j_KNs2kxE zjbT8Wgfi%nm4ctWK7L+!03})F-LzUTi+LgH1oui|{H27ApKwHnHDnkZwl1IWWxB zppJJWDm1K%Aczmks>iP{u|bGcC}dDDD*5(qfE@@X^+=u-q0{~|!3=GV`p`2`xDzcU z#jM(>b9a_@ex$KcZ;U*+q%egn!}#n9rRqYs8ZO`Tk?8@>U9YAvjq;XWY!pI2Bu2p^ z;UPt}1J!0jWih~sFsshUno@>yI#a0;Q4XXMLm;u+H{=0u&VV2}!UarU;6|;O``U!9 zwq9Y9;jz?x`m;ow=L{z~N;!N;FG>xO@Fw~A{iP0uHQ((3jG#xzkUk29iA2c zCgj@whmbq{Ddh6}CFC9wKfNAfWs9`pn#;hxzFr@*A_&7f#KYgDGmq;(M}WYMR_?6P z*e@4@1nJ>!@9AM8UbI3Z*2Tv$>#an%G#^mSnqh9?4kK=ez!H$H0$mBjY$-rlv2Sck zSnTSf>h*ztSshA0=pb74tSFy&Q^7VHH;0A+i0Fy#G=B%+gIB+oOc;3>i(|WLnXEUR z6I}8C&Ql=C_7vY0SsDn{C=2#TXB)J!6691p$_ISp%)LPHTgZi(`gbAM)zgDzsz-d^ z=^sLF;@^c_S-`uRs5^~P1W(RSAvgF_$fce4Y5cp8%lawgCO!UB$i@6E(t%~Vz3vNfXX2j~ zG?nM2lol-D3+GLRN$HX6I}OyKzuyu&&>4-cqQl5is6)+V2mAKiMLJM_bX9zjZu~h; zh|-`F;06zudDk@OISK=x;li>e-1@EzEII{! zWTdZlW}rAt;<48nCz5yENxAtZsC9vKq-?GH)IzNR1S+oTyYQ!W4P2$VWVuAx9r0$8 z8pn(pRf#m@NoZDw*u8*Q2}ha224{?YAXApb*y)XfW^B|!SlXJFqRqE<%v~2V@opgvW3C%Jrqxq(r60~+CkR~W)=B0_5UTr~b82+-L zJgG6xuRqmDccdwzS^GsWZ*E`y~j3D@xvVT0`>Ql<;(48w!1z}6Ld(b(b?$pZ|M zJqntz)CeALqGE7#rLmVrQo1>=zQY^XJ^M0@mSECaVV=?!+XsSJ3ae(;a2tdYRJUi&5+i8t&307N8!xKs% zZ22Bxm_Z^S+b7 z{}gg#e+#*lpF%G6Zy{H-Gdj>|H+q_y%}Fay7MxBKFSts1;`%3-@7eOBY#G1%$NOP$ z(1};orju+2F94mb4W!Egx;4Iu(oRg+L3?1^l6%?OGF#Uxjwsqyx*{>O zA1JB@kfY+&VruEK?5bxYzP_y;DX?DWhPCr4#XP=Jp76eUjPxH9QC1K7rZrdi>~6w8l$h4`~d?*^7VeQL^|07wSWbMF3p*^H4ys=Baz|6%QpvmgSke!#LAtlb$-}M!=|E@v^h0vI9YG2pY{ns)P#y( zk5y_doN-ZSvwNe3KMA`i!OpF8?*P1MA7^}}^fYxpQru~6kkDnw0#U`o;RGJc)KFvK z#*xkZ2voFNo7g65WrThsLG=b`9gR8`C=n#n65V>`&eV3II2=7l_|&(0-Q7k05x+at zlnsg2;yB7ewLDbvz=)a6WeGdU<{=nhEq$%4h8~Gg-wZ(1{f@o?MsFXv16Rw`ot37GM%cl~Z7NF(aM<@E=?T-w%`1U(0I*165%-{!Vc15_ujBRT;O}?P*G4X)e z)Ruk&3%nSPN zAsqY^yJorilxQ{M(3V^}H6A4(6vTZ}O#_v=5J&0m3p6g$)7@Q{=@U%h1{J_A=iSf+Mw5^wo8BZPazjDIkE_u*O==ze+$FQP}!V=R3wWPsit z_0-SwvJCJ6+g{wb50hSIU-%j)gZOaXhuYuCI60wF`drL4w<_v6HTqmq_Z=o4!8tU- zFNWEL_IVDxTb8KPU}c#}_WP~{l8B*bGeJZrz0E+AzX!k8#LKz&^wcYf`qQuq29bG3 z+}JjU9IY~hp)oZy&nT>2*cOo%LXh-#({E^2)s97tg!l&XC}^o9fWu?-OO?V zI@@!?LK!OzCcUS>V&jKS(c<8yR{-w+Y63E8>@0sknef&^p8r-nFM2%1BvB(Ma?aZi zzSHKA8vDA5F-3yJ4x&SCHl7QJIb`sPcFwdOnX=a}Rj6cY8RTH&>PDeZE$7CCb|iz{7B7{$NG?{$~{LjAJnF(Ucb4 z)bu2;P{Vz7S(ux00%iU;4DR%18$Xt=IL#mV!0rw*bk{cJEWH4+;6&TnFo8lK_BXCu z>?|2Mx&2#`#`Fg^htpy2e+jvf{~_ewEB_k%yO7KJmyqlBTgc`86mmIj{wCx`{)do@ z^rTnr{HKunCY~KTM4rj5wDu+&+-0~|ex0ZqB}I%s%Rx*HXqiu^s92RbG=m~su+WXzRLcV0-?~W?=STUl~H@C9WkIgFB*8x zluMn!y5~USG&et7k=a$3JCnf34ch{~YS*U)HGNUIP9WB@qLKiu7Bv&gmn0EDC!e zwc*MOyRg>}lT5R;<55s6fDa>PoVN-+>~}4B;#R%DHZ{MFF%+Ow=BNP`8?IF|DnoP> z?Dk6gV#3b;=-+=kCnw?u+iF?nqc<-Ulo=czNX~(-*%5h0q z3k#aSrY50?jLkaN+hDL(!Qr3m0_l>O-4Othb*wXaU3Dl>b`PE+&veRHRs!MP_K{Ob zYJ4RtjaJCQ>DyLMqoJA4ERuP~zj?N{6!7^%Ji816cfKn$r}#w}b#mJb&RSa^yEqM2G(9Mh3Bd)L3I5MFd_qroud2D651gYSh zoE;5ZeI7tXciA1IY4^9Z~r0r`v{?TzZysH|EL5@hV#`3b6Or)YS^wy#uEC1wha{M zH{T<=%z1!>h*#{srm<=Jq+R{%ZFzRf;OaBMh&Xl#Hm*Csy77*uvDrH~nWc9&!#r}F zt{H>y1ciRJ?EHfAIP!rWnJmoq_^a?fW267Y?Pkc$CkPJmxeTlrm}c`9&&wIEr-UvA z@aWfqSDm}1OOdaSJ03lE61QPwM{QNP7DbPN&C2IT2PywYq<+g1s!^#`Iy*=_!g^qxKwL8UPk2aPFM>2&Vyr)vew(zb?bt`0v-P6N38d zG2~)jeaua)W3uQ+?3__7?fPo?@v2RbS|rI?fZhWreD;2RB@I2!Hy^#IBetf@naGa; zddtLRV!E0(>>u101g)Q|V>$7|<1_65NM@9$6Fc@vo)@3f2#piyKui~0^l zkCbi*fRS3U*NMy&&k+PcC4H|TXOpR#ih(AsAo2|1CDz8g%x_*5STXGoQz${7g0(wA z%X|41Hv}knJYMy%it`<8-`Xk;oANwO!r3YrRl1Pt@XmN;e`0v|^fKc-4@hCho>?UQlU?jFmVopYGhCvD7}A zu!VqElmT5KCx_dx?`dIv>3-uimt+~p99*0c87D-N%|7Wy0=Bd(&fX;H0BIJ#79v`< zJG1fO|KaQ%qib8XzTd3a&Wdf@wr#E0wzJ}7#kOtRwr$&XR&Ms$&pz+Ld(M6C9j%Sl z=KL^f)~w#^U%gk=s2@hmXt1}sNCM-oK|RKghw%2d$RssAtyv97)Xng2H1rC+6M@!d z)ro8#%4%J5C?{8Ia@_YuX!`LO(9Ig_$vl85MUOJTPOx^>i=CSjx2ya*6nC{_h%FD^ z-d13=aRIiG&}{es25Quh8E2^mQ>n$dusBfMT+^I`0(qPch+L|^MYIz%SJSyWwj*37 z3E$C4!opk*VkEVV%-&zbqJ>%x1IouYv!3eOWzhT5qIRp?Ip?*Pc11y()f=_@qRbIO zfk_gJln&kN->n8~ozK0@6naQc0f>Hz4m2AM9`->3{6$#z-by_CCOlEIU= zr9&bF&JZ)z?(|!GiqTBV<<1P8C~Z}$AwvMmzgb?Ps=$XIN~goq%fw2HmfQo(udfaK zV`mP3(Wj`-BFHL+!9m$2*#q63Rmi zStw*)i{&}w0|gHLeN1ROZeHXrim?tHZR*vGb+K=7OAga--XX_L+|J*5&_`?wmBtQj zRMhagybu8ZQ+r#&+iq!oY#&QM>4RwVRpRj!^2teml|Sp>PWa}C;pdTDiTV%-w^m?? z^sNbZ5JPpYtT067y&u(#nG8$_R%4>-3|g7ob?QM5R?`2n9t>m#mFH>tL_D14fN$~8 zp{2yfYoY`K?h2)li`^`u9B&0ezzN7RWf{>7EtE+Zs)+SAurX2pNh*#@-b#BmcQIff zN&o6&P3Dyk!Br=AWxky#=EJLSaweAMaBu4Qf%v^uHj%7xb+)^OB>e=f{({!+xL}V8 z_Z6L`*pY)Yb`Y1bfF!}^j1N{VySvBtd_sUBf5hrV<6|d++b+<77#tcYv?W?2`RK-q zAPIC#Bkn@1&DUbSPObQuo{4V4Akx!miKsy^(4#*EjuA8M0lXs+drz;R>B6Kb^oNU5 zqh}xl7rrz$3jJaBJU@9@i*tDWs51&8IWDMvCxP0WP$ zjiCK_g^j6L1K$457V!I`cBk{s7ESK)kh-ZY>)o?-_b-&ydis1UL0qzF zs>*V_GckUOeuxRW&(Gj*T?O;;;mG}B`T->5&N*z;?W6LJm=2oM6Pu-$A!Kp0%@1O$ zuaETGRz=R+8?TEkp3n0b2qBjW5#=EfBg9&M^ABj!{l71S%IX!5;C1M~&|fsrdvC?H zgmYGso8MeaCU-85EIB4RZkErb)|D;SUQ69#1lfty<0pI_926G@ovK8x3-;fN*0aOc zxz|AwEmFB-_iHbcJ#z+#g`&jmT=HM9(u3%t*u7wShDw}?pJl%D>5k^pR-3BO7{gGb z8^7Mj%o|A;TBDtRE11OGBsfC{_N-&{cQrA8{V0+Xc7ekAdNEo=%jAh?SE9cfi-pH| z<*MVPX=>^VYU^yWY`>2*dTh`{)_CnxQ@u%pzVmqDyQuzIoGO%f_>w~*ZHdGraLun9 z+M>zj(xKsfK&t@<`OwY4k0%5NNQD;`pQ8JaKA5SW{v~uRK#Sixf#pHDP-)%9Iok+F z*iNv!P9J_hipIcXSgX$3#YT#n77{ehM9Zbc2F`!6k8a&nN3+k06+mB%O-{2Z%N4*k zy`R~T0hLuR%IYHoq+G?}_*DW$(e)&!tK$U@pZ%j%6d_i}2)uyA?03o5f5IO&Rt0fC z@4e>NwMBftR#JfmYPBe&L!j>umZU<-sJ~59K|}%jk=4p9r7*m$!gA8`POldzsci2C z(-1BMW>FfH(f?3wzqf`nP{cQUQEesYR;wpHNZay)+r(<5t=M0* z2MDJuR6HJ|e%`izXyjFRzI3kxDD2id+V`DQrc;-MbM!>TDXn;C^PeI?$iOMF+ok|7 z1wR*9KsT{8X8%F8i^cYWt?~7u9wJ=ufI`fu!pR!8j8XYch@e z%qY>id~BoCXrihWG_{3VygxxB+b-n91$j|;lV2uV?T8_Fph^C6jL*3BPA(~^G<9mT z5wFAjaV)A}D9Ci(x)^3tZz}c5=?SEjW#1cLkM)}PDEdmABV>=gU4{}Ak5>qmqFI40 z25MVIJ*gC%idu{lj{mHe#nV zr^Zg9D&{OapdzVjY~pcM2%Bmz34)p<3VcJqovfRlljR;+AEs*Sa;1McEYHNhBtuoZ zbUE-BMC#>bb6~lE`eP&4fY+qCLfgIU3A*GE(D;d^I?Sf$Ws|YQVQ&AyM*< zo!`rqDdXYh8CK+}N-Gh3H64grqycFHpF-BzX?q~^-1pqhTX5wPXq(`PQ)LugXulNL zh33p0uJXY_s~7iMGe*d~?T-na4mO@P4s}$h!Y1OTg3y$V5sM|I4e1orqi%u-kq28@ z8x5+a8wd0SnKW9PvPgBeur2y%b>^AnMM_n$R#ADt38BPp_SoKID5l@5XeLzxV)(zL z65}t@3oKkTf&!W(rX&N1)6XtV&jerTw=xm*I zq6vmVd)FgnBkfwN?f)Cq7W3nrGt$WO@>+;cxn|M(?EBMCP8`W;m*kCD z6(bGY>kT+*B>Ef&jRkDi5h!v5-yfv!7X=Y8;Ezb_Dr|#TY{ayaORHK3BV(kF^t0@R zWq!l&`v-NTFr^?EhcB_q3(>iam$p_pJ_G2#=2PVR)#V_u$G>Lcc-@?QxW=fC&M^+_ zm5f4no_2{Bad!^23Vy&nrVR;v2Sf05xQ{!#>!D}a^L{xGE|SdxzQXKj{j7|lrG4wu zbJ=6GX+z!O*}4yS{N%}LtPAhmxErgRbUV@)!|rDhW7Lw#qkte2r5+kJPm7a&;lRnQ zAfF&NDbn*nv6OSMs3<;4thP)6Jb4r{^erHmOZPQ!3VLOi$HtQufJpSuS!k%ndTMUp zh@n6$&>H;Rbb0V_Ru*Q!wP?XHZWXhsbHt-Z|I0#4Ix7^~tQ$4PuH^Xmw#dU%+FGt{AHd;}A1tUocpDcn(WK4Z!1p+E2Ymt4(4kQMV=vl7uM9B&_ zD0L}G_p6Mrs%K^Oq=wy0Hf1SW=iozxD3*8GT0I94a36?69>0YObwy#kqK>5pw1Eo; zY5fZvM3si)y_k|uziT~A*(>st?GU|Z4nUZ6=38_>_rs;KVn>QlOj0{MaHYmsnCcpf z%0&5ci2@}?gHYG@v6n1<6aJ}4H7;yZEYN6b-i(>ZoE{hE0P%?vEOQ^UCotQ{R2q(y zHkt_WWSGlrcb^-V%GXJaP^wFk3Z4{lVR&Ev{%HwQJ$>?k-L^|n6t~L5#U)3M5^7L5 zjB3+ZOf^MWd`N+A#}6vQzLQ#Kb?)_gqOhLf(i(A#<43`3o|R!XlfN2*!w@nYN@h5D zZHUbyHlI`fVA?tr zD1mEVdi}w)g)=1-{bJf;42&TB3)A)$z6|z@o_%wp{trys$-gsgX-iVRn6?K;)PFK< zAs{8G1PFEH?X7dfbN^)8$`t$$(>Codrfr)x38&Sk-!~{h24B+-Jn6_H275~Dt-6Z%2rtPEJ-T% zsDChRB|$2`n6^vMPQ7SP)8WpS~w#3K6)$#;_fE7KM6x$ zf0(vGe==Q5*r=CSQeB`c=Mt`zdCK0O0JD9$=oKGUT33{P-X9qs_Z-*w*d&W{AAt=c?3rHmr zej{pOT8-# zYJMp)f?a%UWh$f{Is^ge0oJJ02hbrtJY@R~quIUyx|3w?@#}ysMqg0s!A^R)FZ%7| z_i2M|{*SR2hP@GZ)zOK!YOs|-#U}CV z1L_hb_JcK3RoB`S>ko{gVv_k?^KLjvZ8=S9Ol@JIu2|le=#*R?V{aT`x%|odmkZ1j zglFfp0t)0(ff#KHU-RS33jua}J8JZ~0SjBoZ(H6^W*>A-)+=WIBbtXQ$yF*WuJcHw z1fe91Dx19topug-D_Ow)FUO_pLufS>8Ob8Wxy@@XQ#D#4H=wGFg-po%ca1f8eFyZq zO3ok3`=;>MG_p--!IZH~cPx{3gn8+GH|nE ziMsA}i{#(>Pk5GG+rDSh)N|$EIUVe6uBg8$SIPQ~k$yuZFZFv;^evlE1}`UKS8!Kj z5RvJ)>h3H-hRQN#WS8Ahdy@{2iv=_Ywi~60UutHqK4g^11?^`h_1_40%gjS}}hxZS4%cn6{e#hiTjX#k4)MJ~{{f7pAS5 z${$SIDWm_xwB5|0W)J$4X&VOn#k8$8Nx~Cm%Z)OK-e*fccq`Irp@(7uczekU2w^*Z z^^XrTZh1||Mpn6oCfX-fzHoi)08DIsrum-z%^(4gA!5CG6o8f>m^C$5O%eJTi^*(u z#}JKOm9-Tr$e_m1!{s&g@IH%lW|dy`#)fH#1F0ibe9nL$8%s z`&2N~O3 zHwCa$^dYiNuUXzfO6xma@8tSd9kOggWN&>kv*|PLv!YurJ3D7{)uhzlF@maB$mJOF{p;ba!+IR^M? zK{Du)tof<;P(TdhLetf}N8i<6i1xqFXax-rT_uOyVelK5{t6+%9f4u|t*}kgR}*ev zo_dzqwB=Z-^YnUju|sl)g)-Y1Bl%d@zO%@NtA`%f3%V6@V9q72*u4I-LH$uusEUQf zor5)h9v>v`AGMr_`7O~HDObGmJN@%P1m8W)VI$_XZWGe`!&DDXR&_lEOT$w0C0cMW zBvH&APWi<~jhJ;>5AXNuDe6OH-KCzkHJAmCxG9!2H`1IUkiF4^VlMq5p9E%QfF`BI zd%Q;0V13(UiPwZavH+h|07lyaOAauV+&!XaZs{WpC4B@1^{mx=wYrc+&FYEEo1tdQwyC85=ELd~61}t_*)}*8Qb;Pgy+` zE8)Fh4+RuJMAB{LlNrk1ei~^?7T@m6GD8(y`{r(gOOMPbUZ<^VbE7R78#m^$AqOHB zC$CL!7q6MQ@@nRGu?vF5b0L<>AY?{*aXo#Zx<=YKLIw9Z1i*f}#3Zb*0}+owlk|z9 z;N^!>)no~av*;!xP&2_XA9Q*aFV!x?R$;c+=l78`E%onQmKKe)mJU$vTJU{}ZY*Pk zNr2fU=lq5o8wE3MpvSdZ-VopvK@QFPcU+`VoPnf_!DfAVW*Q(n=7k(GG|YM!2uI;K zX=`1n6aZz+lWb>Oure>rfy?Oqy*^hWI~d49x;;PV7kA63Tu`Aw5D*(aFrnr(>>$Qa zXX6T;Cz|Hz#8~)BAqmZcj3H?4fk801T+v3I@gY;{4g3(>Wkcth_?heoiB9+sc1R$L z(9we)n!nb4g({7##+-NvDmJVw;l4eOQQG+ApICd(lM)dfesTIF(0 zj+OIbW9rcXq@hOmC9VusfWyf~9qEMR2asjAOa|u9u+nSIk=ZY$Eb!BP@iph+{KR(` zq$Zlp2J~Q*gW2?nII1_;u0ws0N$a?~3a&(&Da<-Az+f6viPZeC|J>A{tp)Y?LneuR z6Yj=00G&cXBTY!>_2LG%a=Ftd>OX^lME{^)f5UG=kzYi0C< zDNd1Ix~_z*XrW`pFGD~*VYjIoFa@aHwNJWrDz_%X_sS7U5eAggbiSj{@8^>rYRbo` zFhnC%p@uQ-Pp(>wZ`z4I11zBzxm`!O+r(>j8z;fQ0SK}JLgM!7hFWF{^mWpZRwQ3@ zK8GSmKQ@1CFgRJIbXB3**E5*l6~beTXU0jGQ!j#$I)jRiCpLxoz?n}fwFWlC#}%+O z%dyuPx@jXjKLk~&`+>`eEgG@lDBumGMh`o*48t!nc^X{v7_J$oB#ty7-;*}iSX%~xgCU8opGVMV7U>tq8@}@k!gUplUG6-1AJIpRtOq+4?(m7 z|5_UFUZcr_&0nK&y{IPx%4@(3A)2^XX8eT4nxEW8QhoH{`XO=r+=?_4;(Kva5_5{9 zUM}E;AqgfTQyx>HeNFvaIF!LWh4lO6vky}ECLMSLU!Kb1vn}?!L)scOJ0xfi-=aKY z3ZJD#TnIyr06up&$!jb`ZqgFO>|zhy;|+S+Q1@|)OVREUg}BOP3o!0lkn-I8yDIizmYNyo_VWizB`}y zeL!NR{-(F{Z4H!i2gpP5)0}x`(EY|?t9USN0-LVs&nFS$f!-%G8k!_;3RX(?oJrzl z;*d5Y;eVMr6k118lPxR68n;I8*9{*bH-=VwCnLJ2J7?{C$MRTA@cP1-(GABn2v?Eg z3att1H*%4WjSGhtye9Sp7JcXXMUtPd(X;{hPM2H4ucx>`;%9sMh{acZ zl>?Bky%3`M9VG;yiUB<&D>&{-1&VVr0dk0zMm7nTmXnZ82`Sd+JP1_(XK)}Kq{X~E z2Q?tW(W4p;HB6VJn~`zw{oIlNf^Ipr6TLBxG2-^4#fz!^InvawWyvYSH?NM#WVP{k zu;Nj!5CRgWC$;QUgy$qic|Q58G}ZVPV66Lg8cBI;<9)RpNo-1qNP6@ZXumXOh_bb1 zRGwpO0_2@IN<;Z35W64q?q|%tXpVTnA}NkRuEX5v?EDp^&wkX>_)6RgS$TGPW781J zCorXLa*zb3T?5nHi$sxoQwJudR=SSf>CCrBx&;O>yr$4!u{^-ETVU=7v=UhO~Npxv^Vl z!&>AEvw;=qPn+8Jle2xlATukpMu;;Hu}C^C|Hlo1inmu0=G&=$YEX7U)U^JC#119a z?O2F-+TlG8JDz>t`w9#RyH(&=Kl|ZDj4XLNOheXV6n|!*2zu^`k%c_9D$cclm=!%| z_bLl{!)!MUaSL`^!de4XF8TItsk2|5s ztAkp*8dj9&NLJPA z>62gb{j{;$;kc|Lewg5FjB5l-kK57|aev<%xIKR`PXPYNU_Bwq=Fskxp-C#6b2(~U z$=lIly=-Dh_w;z#@dCW)J>4T#xNjngJPGg=zssyw&H6raG8<|igcfwx9QDf3V<6pJ z%e&^vvTd7kb&9(LR=q{DS%srs0`tDjk1h{+X1gI2)a%&H3qC7JRs;QEXXHjmO^6@GTf5 z{x~o&w=w;*_;w871?G^ZU42K1)ic@?%%5!u4^<6fqoa?;0NvxJU6fYc4XMEerE@Df z1Q##v75g}?q0WVvq1q7wl2bA=bOyZmJXGUgGG|UT)|7K3D}uA%?gCP}95#*TGmz=; zv>zh(`A<(G=I#c{=HS9ylV*DQ-(0FtO;E#ju2*)C!j{)lc3c%xJo1*no)@PJ?j?7Z zmIC->raa|MV@IZu<91eM%eTWMb-qw4m5OWhe3w97i7DWU3)%Mp!4={?9ejOt$v?elF6&b zKj4<5jnxT0^z=9e7yzX~AL-GTY=_N9H)jIqJfOIXFdPABeXM5`4$5iX5traZF;%X_8ZZ43CRW0(P&SW?CbF1 zoZ*ru&!WDpAo5pmFq9jJ?2ca4ykt>)mL9W%QyTy?uZ6}Fvev5_tGD~5_rg#!Fwbd(kMJ75(b{@TwZ?uWuAUQF3ji52x5?yv9=;BU;vFI3~-ukZgB9vZpo zS=m||(f&O&{OjRAfsaNqWTi>p005AI004;o>d&6<%Q7cuVoz7w>#A=_u#=i5QiEEm^czi_X`Jr;X&4k#0Imd9!_4KuJZppY zr_lqFukd1au!kXsf4bLM#Krh9qpnviwDDas9b8KRe|%JHN%BJN51lqXrH--t87)bu zqBbb(OF`LqVp=_73o|1{%ukm6Ikwd8gIJSrTazIJ9I4!#qmhItlODyZeYT8=ykt3? zzz}LOw@E)Vm_l(DK62r#13lu?2i@hRIb}H}WlEImLT;59sDf!LSk1D5X&|F*Uhk|L zoo9i2#4;D>u^W0U2N7El2w8MwS3P~2e>$6Dpm5M9ZcksD_a$G^HlT0erbM(|@TQ(p2lUG7`k-WZ&@#NyBO$J~L2 z=`u6(Cl}Q78yVfmnyj0_<-%RC6r>7%ek{Tzve2$qXKiY*tvCh)-UO(41%{N6a_h z^6ZLJklYu@&?qG;h4Jafq1*5Gv*+X^w?u4=&m1G2pCqIHd@JO z@n>K^N_TP%z#6P)vFJJT&|h@xu90PV;hx~Css^&QqCh?`od=%YfbNeI)_QB^_$eMH z8PtON_*lAyLqPO*_$%|hI?$(wez8(Sd27hgd6JAw`!O;*WQ~AbJnI0-!og|kO2+c( z#4DIqgvlYS$w#dAyOFV5p8!I)XBr__P}xxy-qtfEDo-IZPXOCTAj~$*p%Hzvsh_%S z*RH@5no{g=#WpJo`o?mIoGz_%ex9LG;mo=G{;bj1W>am~L`-BpB^5b1oNl0dpzQ!P zDb`*T-Nff)y2dWyFn#!39;fa&;JvK}AKwFS3}QR7wq6^M`6`hwT*WRCA8LXvA=YBF zZGK*EH2_UcEmH{X1v^F%Z8+BDP|ItXkR-g=SV)!vm3OLO4fCM)LBIHpH@!F=t|H9B zZWz10PXP8-2*VrTmj$f54^c`#t5I*C6kmQxI8br|(xJV1v`t{5o+plIPB}z(DuIdp zP_BFH0WF#1orcXhgdvIW11gpr0$Cm5G^lvJoo+rTN5a;>+otaGFW3Bca=MO40G_lhwZq*`H-4%AAcOe(B&JH}n6tEF*h+8+#EOdn-Lh8gmC5>%Tj{2PEFt zMbCjp;H+oqWJCbz^;gaRluhl&RxFml;Yw4Va$Pz@Dp6E6 z0sq}KdK{gkyXQgb;hwHKnM+0kOJ??{wS3ldH!3l%M`9Tmt*O{e!|5|m7Fa?^1vy^{ zn8PS0d}1Evvxotua71#Q4Hm~L9}lS~|BG2pgF(%~$LI5!@;}%V``t z88Km{WARt=fO%}#0PP}2W=uT~tS%nvHZ1@xMMe4hZc-oS!HAH&-??IqNC1$@MBq}t zTIY&`$1aE8VuuVliz=somlP2AEWoNS2g!PKCN*P+bp<%sHi~RIW~^@v)~!g|^JZ=S zJ|J%h7C2HJA^hDrA!EU|9SeG$Rz{*L?y{t~#&2#8wr6KBxEx)~$ZYO6QpN;*f%=?q?%dPbPzqpo*nWL$ojg^&= z^}o2*+>)x;!rkSX6+&>h}M$3z=D){CgMr)2a0(_7X|H99r#br1)Ps^&e&ZgHwNf z{U@ikQna%93J-o~>exvZQIO-;zoC&S1Ro12%L|RNn59LF!-^d&k2}xjhJNyN0YmD= zAZA@=dc3bo(m*E8P>5dZ5Sd`#{aWgDsd0INq)FgYc#QHSPSmn|`*CzS>QDLH0S`i> zClDZnhc`@lobFeVtsC0sB0ve;>DnX3PaL6BfdFbjP$*`PtW)N9+9zieFNXdN^}B$b za4j`keAoaevnSy}5WzT+x}H8)mTJX!)0CHvZ6kBqsJaQz)p;dD>XO^F@`ctGUzV@= zaKUwU7vuEr<7hgS4^4X~?%6~jPy((`e8DM7t&3dZr+!WsaIXT*fhD-@Z!VPgNEukZ zyd(uRUXmwQ0$m<>cnOyZ880E01&bUy6uF_6nFuBBudCj2K>Fqg{Af7f*H(nOJ?tPY zhbR*!h*_q;{Vka%VzC`mxfW?h)d1XcpZUF>V|CmT7vKH`jSa_(fQxllhwSTz0 zdEg7+Ze`g%cQtU@YU(>SQZ+FbJx` zooN-X%$0>*xy&*RuWP~4h8LN(u{>kc|E*(r$f4A<@X(&|{i&GJEH+Hd*l`PiO&@-fw+y!?J zXYZ40#Wakd2ztn@q_JAqj}(A!0T}sERM(@MT&Qhx^a1pr{h8oD3ai84h5}W4GspiJ z*xH(aNYH#KH0YN@)Bmpu`iDaQ$&HPovt4?>y!`ojMxU9~%4gdcv7H0aGl<`Tl*uqd_N!ikMlCQQ zdJ6*L&C7L+s1MFHQ3}5prWc8t*>AWpnNkjr%n|ULFAr6xsd5tdSWqQB!@l{&+YoFS z!oCws-z-{9mk3JT`qPjBTId)LCuYFU;V6hhc2)~VJiifBTM@YW+VL0ygRgBmTS3uu zmD#!BZJ7u@Z_X~rPA+2jN}k3iS1fL2>gw46-Z-Hl%?Oy01KNw;oV^sSi!M~16q9FmvMQzO4=X)?A{}*}sujc&Hj{j;-NO#jS&o6T#eB~+s)trAX=*ygcef}qNW+>EH zf0=XR4y9-sA6~2-Pw?nLV2KT=?GpTrPP>h?W&{AgQsXn zXfn;uuWL!6A1ycI>Vd;`G@m6j_H;1}49Im1Ighv;nGqSh9ez_TdL{D^G`v0pg|Q}r z3$1&XuQXLr&Ahe%f`E06j*DC?kgUoA&Cc@Fc@?>i3;N5FBa#_o5xbQ8P(a>1BQSBj z!N8si;6GhSAoW86+wR!=Vsc9uO6e@tcSP59L%2zxl>&ZcN10ula+8RA=nxmAXz49O z)M!Ck9p|V-i;wVM8TN%06w0=%#mFY}i#Hb*_fworzP1^qyBJn4w$=rYKZ{;j2dJ%0 z@0JH_mr7f-FuKat+X*UO?r%uwV!AP`^e0qpE6G<+N}CNd|=Q%Oy&BzvHq=#nix6iI2+kJnAup<*joNQQlgw1 z9v4@huCAF=Dn8sDmr|Ubrj?|om>i!{tX7a)nx0!!TABeHv-^&0beKR!R)R*M?qIiQ zzhM9EzqsbVr_E;829{2S|5069X(8wIzN+p1b^m+X{MW<(A#Ii%8y8=&eY$Z`xW0FI zgmAKpaJjp;gHe$irI?(WTbdn{o82EBr=$@dADICdvn2=cm0%7%)u_%6v#<>*$}$Kk z>cW-tt*gpwvS=^Tu?@+KlI2or2{Vza;2AcQrlI-!AN{kLt+v;LyT9s5{?&aL{;iq+ zs;iv6k@HuqB5p14$6AuOwS%LcrKJOnfz?;$|M$jsit2#`#Q#e8c?R&X7bW4QC#Zo& zoX5f;0ZSGo$Xw)~kUKmEMX)K7`{+KOrp9q|n=a!^6yhmKzCBs@k!R3Ngazgb9H$r> zbaooJIspgLf~g{9-1&`0;Mlzw-Vvh``km8D-kJ;vh_mP@+%P$fVSg*^KL+*){=g%jUD@OtSD%sEUGH z&CTfx90iRcBxR-mR+Mm z_PVNSHZPK|FYq#v^-X|*ITjlOl1nvR>UrFDwLAaLt}}BxyLk_k#Q6TZ-)g43kE<~ zybRh?DNk51CCrGStu=DWYsWb(I7jrGTn@cu#NN(vmPirgJA=e+E2tuwsxe+dAhIuI zN*HrYde4y0>=+98)=(2Ep6PJKtaQ_DguNWQ0Y4`M*RTk)n#XZbzc}lil3BNh$^tQt zlWJK+k!Kj823<#`$4oAjpqcXE`;^w7ipeW5^^KvDuPRyCNwiM(Ih0 zIjezRvRJ;iKic97^fOUOEe2VA6R0s0PvV)pp&WFxF%7+{0>1BHq*%dZQeL6sFUf}c z)~wn|o;sS}pSJClU;11Z?mynIM8@!pY9Ixa(>>Ac0HK8O1pG@t{{S>w!-9{lcJHaNSIT~9*@I-Q)n~_h3 z38;>BoWQ8osE-H6>z~DC?WN=hu(RLUgK`dgQ>aj6pmQuTSMlr0gLZQ;`R=Pd*|;Di zCw|pYhCrI53fI08VYHY66va@4IeaGXw)0wQRz6SNs7ItX$KX+!dh9q7+7EU;D~pFl>Exe~f}pcN z(NS<<_gy~;PNYxVzABFJmmvRpGJ*LYmEw;?`9Gx)$(EJIt6xKO)Yoz~$$u~5OI~aY z^c-#MX-xmFFBK~CHoI)_-cwb{7R1Q#AkI40!sLjOl-jBt&JEI8F?J-|8$^wkCgfr6 zT_1xo0)X`knT`s=W6x` zsG{&S2tDZ;vM537dMgW9dTha$fEV=D)xvXz4d$<(tbj|llQGZz=d(kJy#m#YrS|a< zLuSCGZS|d?Fz~z<-I67p=WaeC)vx31Q_K5jf$q zC43w2UDaU5f$dUE)hhADr-=mC-oX>)EKm2})*^~G2h_pAy+o~RYYTp%a(`}owy^Wy z?eb{tY=NCTQQLop^%Jwt{7&B+zzK1?P;WF!7w67N96xKBKra{m39hWS==D4g(2+19OJs31}*d#;kh8Dt8{Wi%-F&_2y3sW_5SVDG|Ta>53HXGdTUkX2>thhFqJ+_3u>wKg=X{S7oeM7 zVp&c(3kX5dL2gMzB%r-&1Q zEFH)A*lxSkYu&Kj_A&1v<$99?)mKQGMBL*&x2u*%uje4om4(<6PJw5~wS*O%q&VT| zdGpS*)!DTqb~}1;<=mtJdNp@nwNQ0he)*k;vb8vn`eI(BWNfiG?1Wc-8KW8BGtv6` z<2rihc$ReHi(Vgz$|Wt^T>vS%I5Jm%Mijm}3Xs)_|XGXo@VLK|K@dNb!?sRV< z_`6eee64z4Ss5#0cwq)ldy+?WmkGIY{`M#PBkrf*c|buS^zYqQ=jTLR-WP=#ho6z` z9s02EkG#mAfPV?ipCL(Uw=X%+mrQ(v0stWWe~}3X2P1pOuOQIjA9P|tMgD8N{X-|3 zQ6L(MiLhzo&;-vU2K^wVpu{|qm0E6y>FqCuofn;uKE00Wk)t^zR+5EqO9wmNE=o7A5CyA%A+M^z}Ux2udp4A{+Yd+$L`5;e}Ym?8Q8ybR^tOaEMB(*+RnWHOjyP4e#_6xf8nR@D4kn! zywK`*kx5W5kD$*=$(87%#B9uSL;)&ZXxT7n>u7)2x_K?M9V4@(pOOOC7y(E=?_|zY zulLi{F;xXE@AXIDH(xdFIBQ(%0xWD=Yd|)111z_gfef@ZNwR1_wFfDte05_%=lmFX zuK1XI8L1ii*wNR8F{ia95wv?$3;GfL>}Sng;B~!;8*NxTM)VkM+hjDWVwv|`BK0dW zWgY_26T5N@`J)~wGE%!_!7D=BsERDScZ^pEi&>n|)K_cJ`d#Q3VrW09?D=v{qG&7Oc?4I@b6Be zyQ|+q*QIrq`R(7Pu?qnYt2LA>`#k?};AKT17K)}X~SQyk7&r-z@*l9Q14`IRS5%=ySr zIvm!RY*{SpAWB@8a8HzE^SNfjiG91CVWA)l>2&in-sSsZ>nfX4(zvlpqgriD07n{l zlF!7UaZk3Z4DV&>TlV1r=(*0dw#1rorSoCCp@PpLUaXpw9Fr6^xGQNy#lqN1!efRI z{N@NqYqgMfl#M_SKGfD?XOHh>vp2XU7k|t;QYsFaw>WdCQ}_5Ju=6diPzehI(p@1= zqeA8D@D%2iV`|4N(Sd}5{+F=iybbGLEoiXLiKBZEOZ{b6Y~#XDBJF~8g>uNbCC2ne z-LoLT+VE47gOjm*@D_TVlT3#b8pVYxPI!*Ld{Y^b_0{5(E*ao|+riOXJ3^1Q2a$?J zlyFx+GuZGgtM^)FQpbSfZY-;k5Yj`;f)32F!qDAniOOe(*D|p$kVpV#CHfsz!m)`l z!AKe6q@~qwK{Y1lmK%-t*${eEU3x~x6yXnbBS;<)@@kQU# zl~{Ac54t?zw4U+k-M}W(>LdS#?ZIHw$@$uOBOCz*YunD%dvnVaImz3%6EAppezZP= zi#0|8k6+AK5|obSpK?`G`VnX;=x)Cr^R?Snu{&ZlLb7c|_?Q9lv zdAArGCgW+O=IL2@wHP@>>IBDzr=4Sc{GnAt%mzlQYr5jAn1%>1HPZ?&&ii~?0pQ#> zM+(L%!R{SRrpuW93=WMGPs|;H?f3X)qVbR(=cq&EZ%HqFS4WS^<#;BI5S5{VGbg!q zPxzqY*b17rO|_&j9dvEF&sc<%03>KRuBM_dw*fE&hD*o-mlN2ZlkypPyp7FAoBSfXGl~3ZBifAUT7_B5eCvYW@1oNz{ToM=a7X z*AElAlJ)3aj8%TpH>Affr%HWpI#0 zwMw|lyndZ(kyK|43a?YA3KZnIwXPYDc12khAdMz z4!Dx!pk7H^!gF)@T|}?2MF}sJD~jy(ld#r-iaheXLI&ODglSav(?BIjLX_!jN3LA^ zikv%#BPlhcX0Sl^EJB5Zd8%y1Gqm5&wsY&EP)rAxZiO6`r(&~syCUH6dUSt3VZ=f8 z9O-sSj3?e~S;ENe@MHDozl_bqFVbdxUvqB>UjgsGuX6u2&Gfgd+Stb4MbF;wA4Av+N|U#Y2@F( zE-vR-KI7Jmg4P>bZk#R;2X1f9pkK#a>`~R-k*nYRL2^(mF#<4692cFULATJ(a*2G& z6{$DCq9FZLOm|qe_#_b<`j&L59CtDW<%}uCfRwYRV~jY;9wEOMlrVqj2i$S?ec<>J z7m2wua9py35Gc*p7ICFfhoLJ`l}|&NzkQD#0@%s9>Ga4Vg0oa~);?F0Bv7;nXMWwU zVG9*es#$=v4qd2CuUd3Dao32?8uLt{?vyc^GwoNObxoO;><$Bx>{y?>&6Tp58zB8{ zdAo3nqF8U~FVGw-qN+4Bq0A&u(HtxK`qL|a;JY^I{?5*h%RKJ@oFtCbx==03B>xU| z=*0%kyDexMu=xT#Gtp$=-Dl#ZhSE{BUS8jB0Eb=eX0WWVI^p^ML)beuiyE{`n#&O0^4gl~wX@`tv+d z(|7^Er=8}&j`En2shq_0H&f`epAAJA2@Jm=sDKE2L|7u|2e8@5;f8z{@V_{|2~5M`>6I` zd*Z(hYButdvV-*SU8hv4*C+>b(1>i}lnE8VLX+)|*Dehy^)!6^$Cv8>;FQmX<4lcA zjZ`2_yxBxCN}(!?Te~%xonX1fW66vIsK6RgB!SMDFGvHV9;=}MaU^oQC6W+l>X_&1 zjF#lGM!{*maH+^0!EAd(!H!3C=D)P#fEaV>+h;T!)?75>oGp?(O6+ zH&ZiLo{Pz$BevPvssXupINj{tzE4--y3klfaMEPf#fsWoh#h$z!%s6br?HZQvC}eHB z=yy6xvLAvc0+`!T3{0k!#ey9nzC$0jr-k?A>x0$*O1S+Y1mHHx40|E7 zrci?x`^T}oPmqj*<5jtcOpZ5HFjAaFv=FSvpt;h;9_QJ=-iiC2P$yDteP!4XYPs+2vL>@PXcucla zo6v5gEm7>MM86m}kiU&S*PN+b3n@?c*@l91$o>nO4Nn&_%Rc=SqEvS%f&5;L2~XmO z4D^^c?X-xEPhO{5#(w&wZ{+uMM=RI} zpPn6X?)Y@Vt%#`o_Rr{y&}dR5{|annB4;(X+1lO|(`479=3Zjb4NzW1Pmpu(?v8cJ zECxqwCR6b9-speDsvAMb>yuq1vi%OR+br%rnud`e`b1Sez5sP~lEuVSKAO({I7aw^ z|L6Jgcfp90fd>E(V*4K-ng8VqG5PPx?lsoGKvLVgmoI1Ynk3g<<<8zvbR9z#Us!UA<-lNlX%xsv%lLrc82+Nx_U8Yc_XhvLwa%cu6CF$Y@@` z2ZyR3m5L;NelydCa4VuZ4#}B80wWV=Ej)5(PM&p#PKr_dlMre}bmUUMuNyhPGeAm< z;`GXQbriC@<(<9Z@tH9rpy^c)@CKz}>1)zk0A{y@dOrTpnK3E7km7jIA|EpCsgO|IYvMdR7Gs5`?Smc_b8px z*r?%xD9t%gku4qp&e*skNOWQ485K)`OMy^FG3;=^c)>ohuLoXLj(;@a$Jy&%YFRmcgkTx_`Xmr9Lez|HvX&8IJ zg@fQ4mekXn?mfUrK(3$V@*;q)X2;G@OEgV65yR3bP&8{ZYmUJxe*-w6H;scO3#){$ z@FqYX&votWX5f0sU}6KUhhylD%qyCe^JMBm5}M|YAKBne3IIOpZI%O!lJ5_lWUStdMzVL z5j3`zzi8AzQF_R-=;i*KZNmyj3}L!UiDuEEMZjhv!4_q2r&{V7_( zD1tj6IhBBkxfXB7d7#Ofg({0uD?tw9mWp(zX@ehD`FrnIOMb^h-qz2S&ZVXz7tF2( zy!1P(U&HD(;jW|eI){>_=A>4ZtoqxAip}PD9+QAqC(=!y_e`0z24G-flnHIgTz=Z1 zwOEv2$I)kgg30I!oi&Kv8oVw`MTPYTWVR3KFQH$#%ni;UMb(VraS`4)vQPmUJi3pC zL=^(N?wSwNS+YjmdWuo0_ynUr~XD}V26wwRGZ7XOlENyl11?& zfBxw(KN!_wu|9vGLzTmzLC+wXa`N7ZI@l--VD?@r%LuEjD&Gk5R9U-pb?ilCJ8A6! zh(FB|iEWCiq)~%-(!Clc&RJH_Udqo1U$xOD@{;?7q%bff3ozyk>BLseKitXEX*ia+ zfj{%dZUx4|IKDolFTe=JPsgVg;u)<(J&h)M7e(0I`>h zR#*}u9bwB+j}p@P>^3uKHaYke9_{#7^XoKRXE|{s%skGgj5vOx0y)9GpQj$vgiWBm zRM#&{cE+iO!KL6{*xFuI=NVY-B6Sq7*9^1|_=W#8Yf7qg~WLo-cb@V`mew7~bLk~v+*yW@8On;wBME92d9+)wbH;)+P(g~Ra z(y)B~NMI*4ZdU>BeFqt>1+*xbtX8|&h>uhvvV_HYEpotD-6Qvbsn&93(TTPb{6g^j zBbdFQdxC7kKj?48e23}|l=IRQ0I!?edhMX8B6;4+mqW;7Fll0oKBPFh)>F@D_$I^+ z?V`NS&V_e)x9MVmfF{U3Z)S5~4K)b0H~(J^YMoUHxA4`b^5I{lH#wfD5yRRtFT#W9N~OkVQP8#rN+n=WMx3#Ao;T4p z)_8h5waCT?1ZLUTK%1%ZXe1YXZ|4k%Oh`AIT|-PBvE`@B7HOaK6;&1UR|N8Ue-F!P@zC!fuS8sqqRkZ1 z`QVXErfLQTdC`fz;FaHkn;iHtvz0=^irhN-rZm5rykQ}Cpt)sJCaSL4*o6$`nBDE!*suvvTScR(hygm&~Q_#(|J_pvYq3)pbVZ`m3XR(yF&_+`R)z;M8WE@?{7%phM^DQT`mE%vUX&K^#d9iUt1>%0kFNcB z1l~CGu@Ui%lwN7%HyB-n(< zj*9{e_MWiZWZ)rpJ5QGalI~U?ze!sJqC_Dq%#qy21=sHM#jZroTs3uVYJtk%wVV4X zp?e1tXs;QyJshGtM!ar6PVcYs!-@QZg;5q+wD0)?wp{E2KImCc2Ss<%@ULZ3?jan2 zCuDm)Xf!p0LLfIK|KI>R5Gp+2rH+5HvLc9mj7KVNiFg*hA$r6W%iEF|enI@X6WR?C z)RL?)ep&que4_&E8z)r*w;F?MHo4DVlQNe$1NxH`luUK zSds%Q*Y-&Ln6&pDn0x)%Ruz!|gZ`ME&R@DR$TVePQg`s~gGdGQf4cie^I9M4VQ@i* za3mgN&lT%b-Y#erw%R5=)}p}cHg*QtfTNqEGjSFFu>66divbc%5rRsf48lO@SY&MtRpbjUFzX4hLHe~D*^o!D_BV}Gdz~h)V_j3l9pNXuWzuE+KS8qxWD6y|2 z3}Sq?PNsyDMbimY!AYi*GfC(W%y-RBc?Z^fX8$0z<%-0obqdE`)&QAb8+w)yhy-?Ac}}VO2HPr&=1Vgp$taEi9dhai zHh@18I|nFG|HGKY7s{EI=-ECwKnrIZa;Z80EDsP^?@k+~HShWUq0))u?xILOl(|}4 z^}|F(u~ISX7@Icq>f?>&Q#5%gN`mx<)E$LTUJioPmt^i%8C@uaFd<*WVdx{+mubG$ zJGY+uV6)x~*0NHEWV*SlZ&5hoTJod+`|sbCXy_|l6i(HckSxcM4d)4H9Uu92 zDmkdmYGD}xyLcn*I6fwE4lB`eGjs}6Oh2}~#q=h0pf|?);vtXS;?B<)B6Q4Plxluh za9%cB+~${%d}fr16tAr+#yAcsw^bdYIH!mqmR0YapBtgVQSg^m?h4LfU@J$1^!a;% zm+np9r=(;#1&>HF%Vk@Y6oY)h{_h*m6ra6az(0**1h7aj^8KzV8409b%V!=T5(;5} zQV2LCp4=(1aW^CXC2PSP!P8T4;Yb4l2ssse4)x|D-dW$|L{rODp$12gD;GeRsa=gELBx< zis!s?4(#@ON|WexTar9KYDS26Gh9Sm3)Q#I^0}>v<$dgxxsS}DpW5@FN{05AT_ z&XJ$s)>%*M%Gb3iV%>@N1wvgJ8#l-zpa9`WpH~ok!{a{9K)!)p==w01aqXV^D+ zE8n^uTn=K16cP%$9S+FQh7Bp#(rG)d_SNYvq$${SsReTvmmK271Y$W|-E(O4hda+S zB~*p&H89E#MrK23_${()>GJ!;&bFbe`!VWE9Rl#XYZpi*itP*eitj&ViQ4gxMq>g1 z05w+tfd9Y8{6F;d{}tx?Z;I+QkA)i+TjK6B75saQG$k_0dTdgHad(Odse)+gmoqWb zrMpEuj3N$OXU0uQ>>Ed~&t>2GRY}=eqaCmHPPE7YIWkm8hdclq+pqy^_vGQd3PrB9 zjZf#jv6YupSMnkwtt3h8GP5iq%VdZ&k%L3=keo;=u59UnzN)T?M}0#(g|5INH|~@q zN`wYxxpo(C2fPHgvPC{8;pDJ0tA8!w1SzAe2sdH^v(eUT&v8T$}?34t+1&4gn|WBWT+9!Iup zCukogr8%eSwsJ~V$K%9Ap*u)f?2z1PDcLvPrx;n-Xj-jjttzg7L3TyE;}w3-!9MmH4y?)MvCNgQ&4~| z)jOV9(gJc5$V!GO042!6Efj|8!@L-pDEIiS2zSQmMk{m}bOXd+0tfgv#_0#gR3Lg4 z=Ti#Dw-cFN{jCy9rA(SmlL@9`Djvst;aV|{PZ$K9#l354-!e13{ph%=)wtY%ZUj= zae-sTgA@UN6VXfhuaC=X8)6I0{=h}n2x$GY-6is*WSX3pmSvR^vRw} zUIFn7&HYT%#(R`N>Z!N3F-yfV5H;9Ptn~TNb&!_giL8~qg4d7f`+kwy-wL;_&NG$N z0=b~q&nDCwWkSR6ernl*AC|sQ3qh=l4S9+eT?qA_>S{B&lhne%K&|j1R1}^+emP^i z4cL9aUfd+U495Lm_^@=1# zhIrHvTbz=Ku^cojyotm5bTMqaNK8TNEn7EX)Q9Kxm*?O6Cynq2?-?M5qIT9_!NaU9e^dX zASM}Z?Sw?~>BwN!9qj-S`{j-%44@8DMQpIpOt?5Wkw}?~?Otfs`Y(`6-0kPtmi^pJ zlLg50#8@}=cZxLG*6>^I(0h>a zk6N$Y4jqg+zx9zUL=bW{aSm+7CYd#^nfWdkA?r?Rk70vGAVdD&1hkB@@7ih!d z6%p#$2*XHJw-@=zupm%$p7udB~CvL0!zx6w5Rz=hW20fNP|ZXJn=>!B1KPE5_L}Tk@M^T31tp&j3>+ z*;8!H1)Pr*G2paKJ)xWK{r$7fjRTo{l%>s-;t(4h^BFDfn=V62NwZ6ge|8V7;5!yV zH!m``7TIOxdXsLvfKFq2k$;Gm6)+q#QCK%(zksUXy+3y$CbXAhTg z4uGpZ&H&*)&<+36YwC^(mSo-Bc_C0K{fUlqfF)vkF9W+m=gc3Z7aQ|B^c}rr3`+u- zFgvG683u48uwZY(oE4~T zavP0o2xw#!5?Yi6$h)R-=$|!YxuV4(5C+0O1J!33)&$TI`W8UKC&$0=SJhwJs(H-c zOv**8rUeue*#M8UkJhLlN0u2U5b{93TII_vg}}bHRs8{0-S~5S(M_Q-A^Fl5SFZQ($X$LjVu7^WP;^ zlSkVRp`kqRfw2nt&B3aiM_?#JlJVq z2EK;__}6aj_5ro0_prtZs=S!X4itwrUo6Y3PW526=VKqS+UpJaQugOh`llu+$G2JP zntG?YPxy-69vAWz7rjI6qyc|v&1nKJ&DNlnoF2ZK58BNMB-jrCLPmLzp)U}Luhnu?i*}jABw^; zze&~%b-CapsDo*;b{bbx14Nbap|*S<(zDJLcO?`2PqHabw+1U>N^C$pkvj8|FMq%9 zIzeypNM@c35b_$5+|TJbDvdGpI7qaA4TEG9a!?SroGLeV@O8^@fV(q<t_>WDLv>HKt{(a|7wz_lU^QBMj1h@)m(R=9wbNeE%Oy~$@~Z{>%V zfpCD29@W#ko5K_VqA+Zy*uATIppD(;X+s#$4N!R<=#7$Z%T6Kc9J^>Bq|7?h5xSa* z+Wbh%s?y)XehyL1Ts|xCyIekKd|p4)z9&nU;;4%)@NaZCO6kGDDU@r~ES;4m=u&ro zuP^eLrD~hgNLRHnWU%LQH>%8rJhsTh6nJoNE+FH{HY(lR++4jUI?q!yRL<*PUJ0M> zvaWJhD!{^|$wMRgaqbPNxr%q3VQWC%$K1F0DZ;)U;AkmBAQ0I!Zkk!~0u^1NU3)iy z?F>wgzZs%Kiivq0nT8+;mc+>+3SokzB$)sVeSy;#FxMCje}1q}(#jAIg))7!4p_oZ zAk*JmXp0-sz#^*@co!3TbkuVw*UZ~zq4e3`qU#4-yQwU{*B?}So9nkxvkoM(fHZ^u zc74Adkl6u`JkwVWRz|9J)BUuE>x8E3fR$l*qf+mi8RoCXh#j+Nx;pd>jTviRB&3o4 zn88|;*GOE?yVvVi=ktxt0d}_P`C|e^s|6A>eJ@u6;@xP)(ZxbmM~6v(#*I9`JBDj( zN>?#DiBp$W!w;%$K>ZOSpnVh2YaX<@_8UK4mDwt!k*Z5a#G(^Od(|R^)+k#76~f1_ z>+gtUodXAJ1uEiza(w8Uj==x>klgN?0uSO0ewb*;lCK3C%pWu<{28hNi=M0>+zK1} z)9#UlU4Rt`4;yL7+D{~2)O#agTi7a0K5AK7p1;We7pbNlXx2NM%k%rP-dJt-*SGWe z)vjmVx93~N4H~%lAdUJL--!`kLSlAg$d+)i!9u|Hl!2uhgj_{_N(rzEG;=CfDnMO5$4j^ zhx14=JhHCWF(IEF~lSC@OeaNLDtQ=sO~;&XqoPOR_GMHSD*0Ub^*Vi*9`N%(ALH$AV{X}=E!zU8O%O!@KFrq zw6eQ-=&}`iy&b798>M{`!fZe!K<@}h9NSF9mvz}Yt6|I7z#A~J6KNFWbT^U)LWy5_3O92x=+lUN7u(C%j7S_nCe@@$_U`0w z3kXWc)&lq?`8;A=&fs)+#a`G&L#iV>`M^%Yp#hW}EZ}!jcj+fHQSEMn9%qpL73c>E zJ&A2`@_K7?h{N>q6k{N>f8y~&0I9`>GPd_4#EcJ(=L*7>a4t*I!yVoY?lud z#VT2!y*_Jd(BR3>juE0eeZGtlngpB!_F?;pt=sR4T3==B2kaKD0 z#pKX&7ac$=AK(2GHXkzZM{H$y{ZUnQV#619R&6M7!zBRCEy&~xp5!D}a7vDaL5r0!2zsz(#TI!C0(J z3MPbDAVfH2STI2lt6tx0HR5z)wbqgfiivs4S9TA)(c=!WS9@a-U7tXpWUDZka;L0; z8ipd2`>blmD31_|s%~T;Ylv8{I`oK!r1~}i);a&t#m&e0p6|EA)x~}JtoN$>H}~6W zm}zyiVkrnGYz7n*wU4Wd0^M~)4V*k-18Kd_naVKZm!1gA^SnQL(zDf)nyg?>U2)Y|E&ner3DB#Wos}I#iK6eTW_;HpDedl_tyd zKEU`9x3!Vui;GETI9%Zcm~A@R0iS{gcU5`$$5l%p_IjqHE7vJ8b7ttRNxfVBZ*KCyXFA_y zlBE;Uux`Ozg;7PQb9n7ExwH2)4fKTkXfm`zJsqvSgLR~|5YUgUkzLHkH^3G%oQpQ{ znMZ=h&usSD(D>gqY{qJedF+xQk+rESn`)4Jz@$ug{`zw+V#+>wQV9h1vHaIc8sowW z$mT5c$03OsbrLgG3F$w?r<_K_tyHn1xXt?Y47J7Z=no5h6I9YydH2lOu%pUn%vDPEJ5mIAFuZ)EcXq9&x41?K z&92tCnSflXLBkUQTgqV# zHgv{2;g~urkS>BB@3_F;>{LUTZ=-o=R;%}7pwFOokZ>kS=w85Ki@DTBSY$iD8%uhGH0KCQ-1rVVX7XMk~?-h zrdW>=!zU}YnA(|9oiQp@d9Pw>mu)o<7i$ue34^^l@tg?GbV z+LkR^_Jn6e?>}p9tiJ*A+<^Q%xW4gS-zN-h1LS4Yjo1!bf=SB3BHLo2adYcS7m%hs zZJL?%nokK>>wi~D1CRZ$NU4mlNA<_!UPzUc_(jNE=hl5ix_+m!dd0x1MG3bNO0327I0J4hIO`qfX>(eU44T~4<)J?!h|#Zl%3_U ztWCN6h)IMK@vqmOlvs-l_%oQ9FS3A~Q?13#gN8{eEw}j zm7BZ$yw|d3H#NDR)UE`aTAs~63wBG)+Uv##@haI!&O6qx(qnn`;`@oH)%uJ`25`lR zSLgP<|vVw}JPy=9Zi$)=Yqp zbq8IhOdU+zQ;=A~!CWM-qkX5=_Ff}+6C1OvQP?r!V4JUrtL_d7Wrc)gvE0oFj?JYi z3;M+cga3(Jt?SnFWLbTCl;#*Rz(Fi&xCtP^$}3(X^hGg2KM0Y7`#bu0o= zEsjz6we~tY$VEa`2@J4v@S|eH^q4#0Y0k6`*3PIE_&4oz!p-6Hxgaj*@pnG;1W%Tq zKbLi{i;bH<$LEsAx$E{;wKtdz;wn+c-&=UjhYrUJhB)o z&CD+G>1)o<%|%SKzFp8BQbCwEW|6inb8zvh!MZ(?Ma$bvSKn?2JFV+f+SZ5{E9ATd zDw~gu{$P43xqI#$IlEE)_VJA4Y)Dz>HwLM@M5e~Vv^DtB;+gjsB@ELV^;7b_?);uK z!?@qGTWNOQn*Ax4t&Y@o&bBoAgRl9L^*Z49mz+0YR+D&+o>*C6fuDa}l?%#Gn)E-$ zvGbtb=ZMW~hsDWe3fc;^@z|%4w;X_@afaRx0C;*#92G2Smrpla2)pZ(&}rEgw{qgM zE(sPIfH&98IQ7$wg*syoS#)#gGHTuYMwFV_%i{ZK+jXK&@jo4+^RuqSG1beln84TXUidpE)=o;9-eo*agZbz0 z`97llo_(gDIOq`RK5_WhM7yugB2Z#&gh9w1p3QiyGQOS_g7%};<&&#DuNfKd# zN!qY1RI17*e9Csr6~2wbB$Zc#V_(+DH5dZmnaEymE`GX@8NwvWgs%V*SOG)0@tox3 z>DZ)q)u;%Px|*$XRAnpC4>uf!y z{Kn%~hx;C_Fmf`<4vNLs4U9|WiBQN-u$-Wi6i<4!;2_J#XaQ_6I`wB;fze^-f|-CH z4X7KK9xP05rj!j~OdMQ|oQVg^lvs?_XDc!Hr3{gZm*-Trxet82*(WEz888T3r+(EU zuCEhoKroW#aY2D7&PopRyo~ru@363&ryt^$soo`^vvygQw5BSC5rJ<-W48QoAL$ zWdp@W=fwE;>^{=9keRpzCX40lRKx!KOgZ`>1OuaQrC@=6(zyO>C4PVBdgat;e6?X8 z8jVP>2?`nooR^LN|Vyym>uw|e-D>@^82VjS8~z-yB^|}QR&u&S$2Fpko^Ql z45_bhdirr{qT?!`6Zv}4sy~)h)GJ=uvRUN1=N0FxBq|H|upM7}5lsiUv_D~OeuV3l zs!0&(4G8};XC;+(nzs!*IRw?zu>R3(FTX7|nTz$V4YImrsLloU#37D_xnC3WIa{JIZpA9bFxt=?*)}!-!g4mmHwkyHHn-P+ygXpd0 z+C)k1`@*2$0?j>@0n)PIj62g8AT`;ef!pOE%NHj=r@6hCg8I0j!b+)PX;%sTn8a-^ zY}nbK&^k{{6K?!YuO$T7_ z^$h}D_wE!;iR<9_eEq(Eoa#}C`l}Fzb+ea9zl&-(uIUj>kx|Z2UECoN@(#rxtLCO^ z;Esj4v+PB3)w_EXQ07UU3B+PngL`Z98s2Mhx)a0{V$u2wn-DoD<CJKX)7pB+?; z_KFez`Gb4y_Nn_{ z@@?c_PV4^+PWxYB$p07q_W$95Qj!$xvi^(2_>R1KQkLyt(gtIf zgCIa_AJ3Hw9>MGm16RhJ2DFmHS|@nMio&E0h^CJj0+E%PQnqgv1VlML%tJ4~M!0w; zIB#!b#XxYh(h!qawBj%57P%lj_@|D=>h|2^4mmLWI}Z*CrAk4`Xr)EjjwpqIVZ*Rk z8A_^=FVo5h39U=_wuW;@mDO36fOev#a_&=hX!8N_m>CS9EjC=|VW$`Ww?)TT*2|!j>7w_~0Y-TrR9|6{b5B7fCYx0-YJ^hXwk3>6m zw8>icw%b}HDqFQ{YEVBRWRg94@v4&PVu+7~oKhE$`Ur)h>%3Y%DE{DzjnZQSEANd%N>Vjm>C`jAOkzwd-G>e}C|E(KC!wE+#!l zdHufLDz|6x{9e?#QzS}kN`^8dosrAAQ5a!|E87uwwUFWxh5tNS+bV8uY$A!l%RDpB zDw993E0?>wen<*)%Gay#7$_zjDQQQ}Q5VIAVyvoB!@{h)tV$%{&a1779GF?*Jr|^`|9uMlAwh(YaQLa zHTa%tf@Vm-Y558rA?IpNFo&k2``o|t@nVGs$(t%tFBw)W2x*&E3gbkom(N8`g|~O9 z5=Iy3;FwY7jPvi)mS<5WXjxA?FW801H^1vGTkbm^MisNBpUA z@5z0`Y&B|^XU%_Bw2#VCr3x=uPyWggK*gKuDLr*J~%iV@tVu zOtLBzs+V>t(amr`&E&p}_MqCG>vpDRPiV5B0!FyDaO7SL@O<@Mc~dYA{7Ftgr7l~-5$gVIGQH? zWR|jKG)P^$^r;8IzjrAkOes$tM8#ayCW%H{<(ziJh}gB|8z_P5d6^NN!vau_r&G>` zv>4A|^2sQLO|s_QJ|=l$NbPnsUW=60rC_CLcFKWZGOF|fvL}bQW)$Rx49+T79)^gc zFI_@u2uL$vqz6k9!SWgXF zEj!{F;g9ApqfWY$e`m*jV4j!*0vf?#?o(TZVS^Ql71S!P$wOU6O?Ch|6yS}*^xtAr zfey;A0>^nH={*YVl29M8Kn6MGYdr9%&Uboe=bz5QUM+#uZM(MviyET2*poo^1M=JA z$uZT4r)1k2w)IM+@{ zl`omeU?%sfoCMs~T-YNmG^cB^R?>h#pdT*B(YkaP#!vcl)Yv`7b>1wyBNO$Hc^wL} zUvm}xv9uS%-^T^^M|pWES%oJhsu=W#98gpIT?Ujv-)_40n_$^fdz^vu{3F&_48=O5 z$>~@Gt<}J|r8edLzV(cA6z`}tVXHI({mgpAK5^!SoU)1r`XnKCJos?6{dyVu$Zzxf!vqUdX+bQQ8$sM$$z|~=T=$)O|B(taLIs!#{#0&{>X)0`%iBjv( zBw8Qm1CW5mGC=2O3>1d1*#jg8d)2Q=%4iK6|HciPnGrRL)1NDgacUVHU?`I_(n&d~ zz}6w;uoj?LMA4xTjXK6oJ4uiz1qp#DvI`=rH3pYU%si5NA_$nXc`==gRFo{XvPL9laa?|k`JO>fUg^&A(GWL%^mkQDIc@g4-Lc_ z6kRa&PAkxaW3RqI2Jp!$=b1PoVq|PzcQ0b-y>>BbT6IC2D2tdfCwph0S3G5Zra~Yd z_6i8-EGWe%2v}USbJKzJS8lXfzlIywyBkqg>fSdh`OUj76RD;p26t72p4n1pY5l7O z%d3X=T2td?pQT8lfRutnxR8ppd0_d`6HkMI2h0@S*^{aG2fPv9D`6h&_C+4E!$YY33mo~ab+Jx=)w zcN8!v@=buAc(?|NB>g>TY*U$^ib4#Lr(O7pwCTm3_3tkq&PrP-Vorz>r4(=LeaIxY z(q5-l^)es{*h^U5JWq|T1zZWSnZjmU0v&zy-Fy>92XLtnQkk1sDJ^!fz8);w>L4MR zF5NC_pVV0cBc?)b{TwYpZy8oj^QuKRq7U%zA?45&bdAbGd zwr$(CZQI6a+jgI}ZJVcU+qT`OZDabKJKvqT_c!mv7qK&9|5FuvRqo1Fxiaf{P5{JT zn+KD%T%^gPAnwZ+2+G1blo!WC(NV7o)QX|*RqA$y!(tU!dtQT*PUEmzxP(0VP5Osx z@RKWk%hZY>y5qIdSyv?nn@R?CNyw8gD(!dA4<^U@#*t(K{h3wv>{TL#(_zoU+lBQ@ zb!dba+R3XL*e5yUKqL%h?q%Za>4k*-(=YSEs-x0UM$aXj8jhHK6tNC!#zt9tUHI6M z8FRKo*mbCUv{u2T*n(w-Spzr;w`KZHU?6lQ$7mJleKjYYGUDJsFyuxbE1%QoBW>5F z^ECG9lc?7WKh_z<>v5`x5`vyp1y+e$F@NtJ06N0}TX7fx=d?MoXG#{J;BmT=Vk2e> z$=86qAzp@j|2J}>s_bnM54Z=)gS=VuoegDPsPAhun|J;i3xIluH}eQF$SjA1>~}N= z=aKXFOc1APLn^)4AfA%c28YfWL*{~WJlID^5b{7FcmCVg>^s}H#TZLn>0`~7-(1l9 zaVCAopkJ&?MXj`yDs#WXua#nL_#$KrW!C5k-@~iyCT=i7r9}8plN2I}WIv=~A{@ z{A~%gt?fbTn*m0iBoT#wca1zgn2WuI^4JdMqMCPUl)fJohsQrI@sFU6!Ew|1l|fi- zcDs4BjXG0mr@HI$)!P!}fF0>#CVF*ku)y$ftm{ETha%+0s%p$)B3|A{z1qEYwIsW7 z=jr*y3D?m*l%Sw-8E2laqOw)Ov(3S){}#S&^SpHzVgVKAJ9_5(_6n>fZk14lB`A$+ z5D08&*?sYfnT0~iQdV-{AP4Yv`Wbb}svcHlcKOA_x^Rg01e0#$<&sEEEu%W!x$~CX z<#Ly{lpI zn>VLDNWeh(T-K&q$RavY7>_+9DeH&wW{0ZuZN&fpejmiO_1$u|?)VvjdNZ}M@P1~c z`-g{N$7+z^msj@ItQZN*Uhs zyOLuSEzpETPmNrWSC8FMMI`_xa?Rz@s+B~oSM33Rtwvd-+0)vX2(02 z`$_I*rBH1w9fG@VzI;vT1D|iAm3NQtK-?Zo-;mPGL7ff-Ri9hbV=1lcs*YCe?qJdL z+e+-+JFfDLqB$-En%zrEx7F<;ly%r;F;YqRpv`% z&&lQ~-HR`t@=CbAB$01KZi#6Vq%l=DSfcST(Jqr+!z@F4$M^T zJtXej_+zrF{i--$Z8=KhiF-Z@yv~JjT={&;MsxSG(CpmyHs4A0S46Kr`0n?ZbNl?p zP2t&l;oU!P5OoBFeq5<{AjNgDOJ3{bqJ0lx(Uw?U6ggaaZv|gQ8b1VUWA_8fGuy}c zm#`iFo|WZ&+%2DpH#0Z@xKDso{D<;kxh1l#ffyFOrWa?zCx;HP$84UiGZ*^uh!(fd z&^+j)3sk805pZx)rk#NC>ldr(VRV)Aog<|W-$C`^XVU%=UwR$5?gQqV@BcPa#NfQs zPWr)@oBvb|=>9=<`B$ajN2Eh*YiMKQWN&C}@{88l(D8>I|KAbaQ`1v${RA-JH}5%t z7c6>)>{&~@BVtr;fxxh)YY_Igm%q)8CiQyp*2%sbU)!)PNCtQ%?!qQ`JZp{S$D$jF z+8P-x9ar)O8aNL-@4IdIq4&B#HtXOZ_#**Ht#`!d$da8~Pxc1(Z6v0LAKQ8b0i@tk zugP8ZKN(wKnP>z*BP%RSO3k;hvg7^8ro;NPW#{Jqo95SmvA(YOC(w_d_RrGD{|Z$2 zKj@AB6U$C#@xO&d$+2B2wtf`-o814~om-olXHa-m@-G_qO6EqTE&nh3*vTu3yAzvU&W^Khx1bqMX)zP@i*f{IFqt>@o2=yLPhpZ&Hb4K>hL+sXQV$qx5!Yu`)?g<;!^4N_EQG>`vZZ+{71+BbmtHJ$mm}%`v1g3 zPpR$LZLlHuKI``tz$e6O)O1|sgYo3qJjD^pMv!etBSNrv)MHE(2`D+t_xQRcX=uiv z83=-345eJ5Uw6M>4X$T!Bk*N2q-=5)it3V=KFss&E?Bu*@X)OBYLrHqb_{zogDo#6 zc*V(B97{v@o<%_0Tk8j!&Qo+5W@(oBbC0gdmg_(aH?hSQRaFZ*jR7WHiMok5YH`}U^23^pOC!whl z8_Ky%7m8yp_T+J8x#efMrTg6odVjr6EUje1r?N})Y^K+ka%Jo4e?GpioZnYYsMpT2 z1UCE{Bl61ag2s@da94iaT*PyMOWsk4SPg0XFovy!%Qe^z%;Bb2-#`3S7uL_)f(1B1 z-5P4yBw;J5M;Xuyi2G8kd4SE$%w6Mb4>fcG&iUDFWLNKY-M~KP%#`lzGcCP~WV0H9 zS^<=*B;XwKsMP*%P zuHrIN2{z0c4@unKrP>Yc&ix6fW0oK-ddRE>7{Ea!Ys}KGYjJ`&3&9<|sYrh6y;8*p zz#5&@S8ISBMkAFtS|L?U+Y&pLRINtiK-xl(=&QwahiIy9Y-NKr?1A-5s-${idMh&6 zJc6?iI9gRt#XBgOq@jVork3u$Au{sgAom2_Y){YYLx;nJ@od=%U?od=OQvg-&^?QW4!;G4pOA$+%(xtQW!aJ7mhDR`+`K~4 zF?SeF_||NYDN|fLLA25^Xr(4a`HYef5pE zL2WR28ZJ0{I#{rOS?W7|A4qc|tcaS~ApX?;o@ct|7!t0s;739ESpx$UIe2Xk9O#2s zulq~j!MDpM88gP;SWr81k0yHm`95d=adG@msJaV|o)a_Hhm9q&vmPN;9X14Nx!|3wA1{? zsMzO9##nR|4;>tuB-eP?J!Hc21IUFD?4+B3ZoAr@33eqjs2zxlG>mrjM0xJpZAJAxLcjx~cKPKoY#wKSLc9j$q=p||CDAiT~nWU+pl~Ait78CF8os^L8dyP!O zIg1JU5(?&35co-(INB(XtFVg}S?L)m$yEuJ$MOFw70}rm|DPGaC$`V>hYlxl{T9J{h^Dgx3W&J^ zT3Um9!SX<6ZE|VtKtediLVCD!P8K{XEziwxAA)=Sr*uK8$ZpJv?7n`DOq7t_y2@ncG?^HC)Eo}7 zXo7Tds>Wr9!B~JR&q|emw-^04a8+i-FK*{As4!XG>IP?OH_fd>RmxQ_U3-pT1K!vJ zL$Z=9$#i3DnzPZ&G0G_G^N&r09Y2b)dz=CzhwkWh0haBqM*NMvl_~U-ks|2#|3+0z zhvi-1{JC2EKkc7a+tK6)rT8zapVR+dJ^0bCNGnp%NvX|FNl(hEDy+;)(@`j>&rZ<` zh5ag{UZhYVK`Tb5COIKFEB*W?HWTnPvq-5#F=qnaS$7CXA{^g1}9G6+RfqHs&f`bTye}=gYgLi<1 zgIqpT0tggw)+N9tEgvEkE%xvz7v(?+Kp7;Sl%J9Y)XE0kdj zXOkbNl8ddaiQ~TuvHo_hi~lF3V?Y1^(EndU{BP&^HxYNKYX2m9lpnr3hxB_MK+`52 zz3?2Z0u7tuxkLut`J2cr5^i0JXh6|Emhjg*9POB^Q=gVWnSlbE$Mndx_lZ%Rvnl(w zxX?F|B$fyvjGbpP0zEM#so(K7&h!?0PkZf*96&C5oGK1hcYwPU)mqkoR*LSFpt**d z=x=^ha8mSaHUp~V-Tr*l54lk}csW7iR!cW`>A9pvlc9($N3-B8QFaHE1P1ARc2%5} zc!6=)O-9nyf@7={r9Plfc9~=>s5aYlL}*3mhTqW)s3=y=`!}{>Mxps_4*N4}E+}Ax zA(#u#ig<4~cew!oyzNc=9sFLq5@S2RQp~oGvT$B;+2#UPGPuQkxv|e)edF?nx4l(( zMJ;=>c}vCQL8lRGDTj~%wzLL?i>yS9~8%3~fR909<(dAt=tjMrh%r}r91bQZT z(%xCRo{;tzJnYk-*dy@i0pB&C)T|Vpv>c0QqvE1ncZDOmzr5kPF5|%pH|kyo@h`#e z2}Rzw7+fY`t3@07P4XEIbodczR%xRauzZN$;DOD9ij{F7qb&-7r7C|-Bzu4n$`z!M zXbLEW-O)@lV|lWJ;Aua#x$Aft+mP!Tivke4)uvEREjbs0paE)7bk&wd6=6OGflSoS z?9#|1U0`O2c`y+_o%)`&KN;h~|4uv1SKWFmWqGQ%62a)ZDjjtxs@`&q42GZNn$(^F z5&^DWG_5}s(S;*}D@k!_!ql=QUb57jfK@3N6f?nY-hu^&28gh-qQr_yGTd7ESo%Yr zv4Mw+-ErvVl@_T__lDux6nY?96MD#D41{V%s@|pbkeA{kS0{FmIO{>cFTyiaroE^v`S2s)xM;~;DmYFxh+_e;ZRW6M5b~_uJpWG zTLVJ9VuMnS;%mvK@(DnKm##t}3b@2h{(c zo6^S6!uG!?(}uKu;C*8MT5zi~REVr6)sl?*zI47pfl3V)xqSUmkLl zL1$i;QKk7^-S{wGn4{gJJB)ms- z$&U$K%)k})a`AMAND#>`TB~&Ppz9o^$5|Ws_7%UAgf|XfAD9Q&HTD;Mdf>gYN2>fe z;L>+%IXOe`xurlyV69W(=H1lY5tlEVUVx}`d~k|}Z}pxghFHC)*fW2Jm&Bmfa1J67 zfA$uA;#Hc=y^Y#BNemyg)$eW<)+FN^VUi2T&S>>)n<4ol6EUKf%gOH!URxr!b3@$4 zTFOO={U?Z9!Ii^OO9_o+DtSQo7o%F44Mgb^VzV?n5etU6P6Z=_+hDrzJAu2d?EOV+ zABh}t`J>L1@9+^T4zjC^%F9f0OU4e~9-rw}7v1|)G;J52v)4uL1%Mn#d9zlCyG)`+ z9=v-AT@)WF^UI9C#<3D7GXe7G2VVaI?vu9r({d1jhuwfh8I5kVBDo=$S~POKwcF}e zf{!HVYF2(Bq?DhzCUq9j2_}=PSXX_pq{BV`F6&qVC-!^}|CAiGwnYn6 z>fCYoS1u$+Tb<2$mm~K)VRC-J!RMmy1%Vd`x8!auk)ZQrNyZNPmjA> zb7kca5gim8iygYUfRkDHa{`q8NMZQTAiWXR55)=+zX7L!zmhs8(J!FQx6bp*W zU1P!a(UA!{kLk(rZq6m=wa~IQy4qv7cf2_WGjoXk>qzAA)1MYhxx#7blh@~^?5n6@ zdhs1(WXM(`)9`mrIz_s6REu0_IsC)D*N+h#De(DsW}pC*Fg5YOj07-u9I-@7uYYvE z7?BVl7OTmCJK6~~U%*c(iR^X!mpGzx)IuQ{9*km{3wV6^?mzR}J3 zY+%7V@_N9{T!!ccx{AkpaPcJHsze_!jb}B*hM+u#$u`0U^dxUyI%pNfJ%M3#ss`a$ zZ2JQoFJ#F(;SpZsNZM|Qg|IcBY4+75^*wDNvwzf;`iC{zy)9Vs4Pper4A!( zmb98UJu@2jNxna&xBUWg_{`RheBYAu=sRbxanojKB=Sl%kt~3LZzYW-W<2^TID^Sy z)koWqCxrA4#*_SIcgN7LINbHcd3KsNE1!b`W#x~v!^IPk0Dd6<*8pCPVs9yBxKI`6 z55~(Gu|SPo?RM?9G|{%HWJbg;6jlg4;`0!VAQO=CdNrKoPzEX`I^ zTp#4`L}~H?=+^zTjtg=LxHrYr)NaT^T-tiGqyhjfB(oJ{g`Zts7pGyICpd3M{({8v z^XWl$w^6fHF597Rq?bXH7_>uNG?oyo^#y}zCGU9>77xHzRz1*cC(yGJRI~VJnKwNQ ztjIFpe9$KrBn&JTQbRia6h`R>K8ROg;c*V?sGUrB;A1>m45PYnn2Gd6R~|_`pw56z z#6>>p9L*5%+xqrt&s$&XqM?ss-~8;Dy9UKh7wE|l)3Xk#1X=QRX|_j#mB&2P$_4?O zI$6#!bhRySb(Wi1;76+=3=f%0&w`+&8ZEZ|HRX`MAZ9F-eUjDaFDL~Xv@)fXopc;# zSi-Oe0toeJ9F*3W@cgTM;ZiSlEWXy5P73d%$oxN#tm`)O%zWeiTB!01lm;#=`*n4D zgL~j`h2QW+2{rX@Cyv5U3Cr^96hc?=H_0&q95-qCcd-LkJL-$-@9R+e1f5!C4EoXo zc%_00Cw8tdvA`zIz9bnh0c951mOZ#IUQ6CU7;n}DL_cbLs$QUeDrwRynrro2*s6t; zfPDONGfF3zf0RuleDiN8ZNiP}TALIsd#c*{RdNF6?Bm?!TN>@yB2X^dY?VXMu()3? z!?Rn(bguE%RD_r9?%zGih3zOuxF*${;-7+JY=$9&cq!Ym$H-BKeNHq+(5^__QH8-f zomjh{L5En~EyvE~F}5(Ic3YNr7f4?T*W`U9N|aN9sS=ZD?2}Kew@8-CCcNU1Qu4Wk z8s(m*X%mgVIg(PG62tPIi>qzU4#*(gJZP9}L)vKL?w&E2Xn&Rg@&%}`$bYc#uH$F3 zpg&{|#x3svV9lqo%=fbQ{O5M*{dQ<+suEuj7B?MZ9V5Nz=m5AB(Q~HmWbKbdYiBs$ z5o?W8*#NmUtYwgOj%?5N_FscCXhJO~wlGWgQtYISJ^_97D`#nz-nJnCd8IB5cKCRQ zxe3J$QRG^>*_STh%(fRKk~g2`s7C#w0^O9Nah>T~_60}d_drfya)rN{1sb!Ypc`4s|zU)@INz%(`{bI|r-OGm@aP=Hl zms^^!rlLZQ)_z>73vFw+N6AK{${iVYed}a9BnG0fb!y`gysV0syw9aC(pfx%RoYHc z>iD+MYZ=>b;_t%-ekGtbr!U^`rar*MNqcr4SrK6+GgN9g)l?~q$VZI6X-<(dZzcG` zYLy|3f24Ur5LNe{P>kR69pn!#REjc9V zs6S)VPm~+L{^d<=SLCc=hb9#_m*jb9T*6InBC@%-NYYsz@Ed?W1!>X_-98mM1v;sl zz=>g^7{C+S+z%g7d9fG1WRqSpRh=?Op)(gdQhMi|Rr;Bd%7$&5vAaY^n_3J^uV90~ zQ?X^Q8^mQ;9@-4)yi2IY%G09uc|5>jN!2@XmTzv}F{-&alOl#abh+v*no>Joaz3+0kcv7n+ z8=sIXi?bQ3J+6_9e9Ge{WBDL%Y5GiH(~l=bMAs5Cfi_+iQ`0#cV$nYY)lwKyMcsGA zcRm}iDb?*ZvgAfM*L-|w_|-eE;3C+ogvCQNW`tDlB-@_%b{n50LQWZpv2HT&q}w zD^8PsQ&Eg(o2w0QOc#ijhMnxVD;cX2-;s7W3pX<0+0SoXeRF_;{GlWGl*W+nBW|bh zMHEq-(t(qufLvtIa%+t3m~hGdhvb6(pTD{wi6atW;S)J7T^*y68fH&MNT4LKh9{=y z0HcHK=Xkj|AdLCPf!1+r%D&f>=vM%M-tcVbJ!i1bLVD(~){bcIUuh+;Pd(){ZBPw1 zPab)~CrcTQD6LPSnU-bT2_GJFbJ~5AUPuZ~ms`P&qsfJht??{OHAc!s`c(RzQ5$jx z;mxHL#$d^xcrTKaYPx>;-r)diKiTtOr@vr%?;bn8;^D}JDs$+uC;Tx64Aed6C&R*i znwo57jBk`gyB?alRkA?qB%;)l9x&hZf7{CtaZmJ@Zb`;Z7e1fHIQTnQ-?d%?zDw)1 zpKrUw$JDvlCT#<~&ZaY_l_4Rzo>4-nIe#TSP)GX?<}xf*DvI__6hmP7!VIO1LXK0s zW}3(#7Zig8cQ3MvIIm$cpjpd*noSk&*$C#0IGi7`n!6RwnDzQpzDEJ1Yb_+~Tv4>e$yXQxsD5l>xLIFwP1xsK;nf8X76-#qi z8%SaymHvRw0If`pc~7ZVPqN|6yoR^r{kXc9nS} zr-%O_-`byFL86;$sCW zSv+wJME7BMVZ}9!*%=B;A_Gl0PAdC{kAhFIc)Py%xCMr`p)N=YiqjCka8X|du6x8k zeQOc8JDsjW%luqCsSxwNXpPPLLPrtgt*FjiiQXK7AJ*X^mQ6^3esV`WxY>z5V6cxH z5Lu)h$l>hH31+F#7&eyj=~EdATOS=gl>rjrLAZ5*5T&~wG8{qz!mPk=XW$aQ$1Cqr zIs3e%g;LnW5_CwQQk3gi8xdcYWUQ>NEj1`DlOh+azawlNSxd!eB#|7`8|cR<`{DKx zgjLGnq?ihF;sP_l$STvvjzgZpOYzJYI*pf-K}IX%VgxD*8xK9J76VAG**pp~?>Hc% zb_&5QyF*kJHEhkC+&&u&$|9+|NABf1q-Sac4)>@kx)x5~d`qHGE0=^8wap>D`3}v) z?ZV^!1PTSLIgnNowfSdS+P%3e_PK1c>OypIwV4^gi@#J76zdgj@Uk~po4tLc{mJuK zt?cW-CrAJ*MGy18x^d=Q{p+`9471A!k4}gxY5;{RK491sr8qW=235*Ems&79rU8GZ zX_#DFAJFK2X%xF{*co`XmV%~MSIq_ZGT^!DCz{2kT5d09XQF7gB#sI2_X@-Gd*_UyqCOF+X;!-6r0vjVC;8Rd3UmZN6}FfGU@>PPW6r} z5Hxd#C)O4k`RIdX^0hdW-;&kmFVC^dWEoSs{u+buPl2F|CISH;+;L}CZy8Ve@DI=aOwJP-w1pOy*T3riMl zAhbE_P4KK&j>^syl}c%m4fx`#VunEK2R(B=()MuGps%<1mg;OxP(gdENfdX*3Q8&U zbM?;RbqrK`LZQ;O^hJUKZa_BUhmt=&C$VDxcv*!(AFg^{e_0sQ@&tOdZ(d=WYQpA! z_|oeQ0^}{~z=&my%^c4TG&`7e`)3}D51C`=VHnPAvFl5PqZj355+{%Mip47HMWh3( z9RSkQ+#A^oFJMuaGqU2&ROk$nGuv?~dma@=8PT@bmv@(RqR?Cwjj7B^HUAxK;@Kma zz)Lq`F<8gLlM^EgWBsTaY$P2j3L>^C>?sa2xzTJ7DJltmr9K7p{!PG2epSlD74_HI zI%WHvts~Fd`alNu8qMVklhlah_Yfa>mt15et1F)Nt4L9I&;wCcGb576+VEKEwcu#k zON5Q0nh@%V*Zs4O$wbIa4_nA_tX+2*3Z?p?xxCDiZv_O^1p813^9UjwmUd0)aKNQ< z|EGorM`w%mz-vqYTxsILP;P~7ja+mRQqJCHS`G%48l3*;rGz3O&p;3eC3Ub&ci^f7 z-;$~JeJw)ZN8(KFBtLHXAt5BNhqi#dhm5+y69EhU0EYzL(#k6okeleBKfO+*VHboo z=S^Tl&|+z)Tt8mbAtJ4B2Ln?r?FNoT*B|bV?q$`bc44YKx zud1b9Tt`*F%d}>#)f|6RtDYJLR3^*!)D^S}{;s6PoI`k8(j{D9GfE4A&txe{kC$d8 zCJ*|SH9At#Iz_33S9*iBW+f%4E`rAo+Tvg8d8&%vI}<&osr*cUEv_#FneTCg7&0wp*~At%sl$Mylz`O zQgLY_3CoV=-A@l+a^ZA2+dNx*Xg$y8etq1kq;AY_i)0ytiHy%g!Kl2tllc4lWbqWk!Z zM@=P9rJ+&A41eAbotiI*&2(+3Q!3Ol2Yw;l^KoA%xfM)3db~virUfgh(>ma0$bQj4<|P(C%X(0 z0Ix(fA-XOc(4aO!N>_EM@%d(tKhH1dZ=*I)l^~QT{eo?d8obLUfeQ7o{mXQ?X3f@HkhJM{;xn6xAySY{PyS$LuwH$$>}sx4L*Jg>&pvj}NAO zDGj(JU*MHf;JzKGfhX@*b$RPv86^NS3vku<*+uKOKDph7FZSm_%gJX$;sO3n&O_`@ z=iiL`}FT zwJ}k~T7Q;?J?{!SB^j&|<=NUIA)C+Czcg)GBqi=vWtGp1Zho&5&o0=@h3L01Kdl4}o0BMa))MCsb4@ z1XYss1nV0Fj#FWFs*{+x*jU@n*BL-s#y&ki+l1!TLD48cvX#V!9hnS4bPhhfr=Hmh z_w5+PftQt#t`e%8e+$9dHnFqa{Ypq#_|+?>`q^G5P`~v3Rcpza?sb2B6j?eb-PBY( z$gcLfV)wLxeUGH+?wvfjoj~cKJhey|`NcEin_l{9!RmE!7Ymm+aloXj!kDfuT9sk) z89C;hB{z>_0me%uX2}4yQIJzA$qK#@Yl27jy0OYo?8SRuxdeui_dMpUgWC!;o-8wL zOz}XCfPv(n(gJ?QriF01p696wqf7(e*v zu!AQ0`*q1WXPJ-(m@>CyVByvM!xRRmhiX`$6U<-b=iZV8yz(nz_odtt486D%8fQ*b zD|`oyQf?Qj1y6t@{-u{wvO+I-szvr`!njLDH$OphU8cn)0gS9>Jf4ua^AM>hy%Io# z`?xSeJNq}i9l^RoAvDzTUAH@WzlPs*qj$Xd@5wE$SJQ``@qlx{H)!3d=G~KaKp0?s zOB0qgs>~Rz_D1NT5@N9Ug#{D!LJA|DaLW9LBQ#EKA5Po4;xE?bMVP@VVKnj=V)r1R ztR_K|!{k>3gNF`*_6sJv^kBNW!lkQKBHdk>2gIYOctN;JhDt?X+9E-G2J0m#As33_ zAve)mhYWo+bsfEij1C&mz;?BBAVxkR8lps3{$>@mHxw-axW>T(TmH&^kQzN$$KDQNeMttDmM5ms^fT)zWcSg6UU2>Ba>;IQ2as%sWBE0DmH zit`3JkYbM8T=h8*V07|Svg2h0)B}Qv%fKwWf{fq_$q;JW1D!EAM=XFgG0+TV?h5wL zfO|pm`t37)t4tw1I(0|q0Rm+4Sm}=o^9m(m;3RCa{S;cbWhz9VJfZIL9$B)d47!g=b@lfe%N_|r z=MWqPJ}R&k{LZ@MGSQUjth!H*RIQ*T;mWZyhL5}%BqkhL@PXO-hx$BEhTd7g!Qs9l zbC2GwE4bx2O(N^dC>)E$=RAMQ71FA=9D6vUQG zk!ETtd}mpWsh-HW3nfv?;3vY5yXi&(Cs(lNCa9vw!@rdT^_N5DV;(MQj&zaitH%MO zie*VQ7=g}s(qtaw4<ZHKJtpqBk0(NVvkdCxhYI4vC zDA!!;wc^At^oZ>y)gL*{ckRod0$zT*O>#nQWezFpGxKaRymSI979U#kJ6|786w9hX)4sO z*_NYE%+LFM;{ZSUxdQK3^6>T5z$L7vmHu>}Zaon}!FQ|G>WP+ybPx2mb)Dc@f2CdL zuiMT;rCi11y*NOmlQcZ*p+y%qN{M}C2MvBM?TA%AKTY18)tQhE(-_N6IrheiOP|v< za|vz4E6-LZGSa=q+TRQtTKRe`T^i9pR>)s}i-c6k8+8>;HDq>5@zqzZ7}L2#T?fS= zc!>NRq4X{lz6lC`cG_Sez>{=0|U6{(#fGalk(l2As~i%|9dN{A?&@Y(g$F zxi2&{1jQlE^mhmQT$W+rxmN9{#mZ7s)$v%IHTq*)7(!1r79W83Nq%u8a}pG5eQap<--V=v2UY@soYgut&_Rsy8q&IV__ z40GLy{UBkN0d?00Jv5d6?8sdQ96Wq#)g@dO4I$!n@fzgS}L_tG;qbG z2)>~CMZT(wDD}n1yDlle=^gQotrc`n$9Ygeb%6m%t+qu9q+SPiNmGY~QePIw^{#F1 ztGi_7fbH(w!Jo^mgSQv!)a=pp?ChyK^Z5rk2(ITquH73tePT;ovFxlIK$M$ ziqTyPjaDsP@H9~ZRc9HlA@z-uBe2U*%PDzU$>-m4bG&?)>+IjXHt-;;+H0)>}QzJdw_3E>6;e=Xg?rmj&6e#m7zbvCY*>| zBf&KLPR!}_^@z>phMf{3EbaAic_hq1yN-VD>r{*N2>O6XUU`}Aj90N5p0s~pDxQ^3 z95|k&1O2^h?Z(bxX3zu#=NYGf<7(Z|ZFqp2K=d6qZNF2bBEXbsQk|3D6jooG5I}KW z7DNV!&A|7^-e$lEm>2?2nRIO+UI0RRRBmke)HO`2N=rt74^m}ChRO5S$jrlX(dl^p z9murJnWh(kbAco!3@|I0QS*JTtwZBL`s{YR2BtH{l8Trkp$4{y*h>Olt__H(Qp|uY z!S?TT#whi5(aO#ivCf&ca%(;jqWlIWqy^uFbv+s(Nxt z54XA~Kz{9o90b5=sW&_<2TSLdW!gA2L z(js32IDx`kgIuTF%J9oY;z*e>iYV`O=4`@SfLp5rY;?d6=jH%0Ua~paoK-DpDVv3- z(5v6Lp)E+X^~!JRnE#PUZ;hYNqRJH`s&q9bdjDE0j2&t|m?u!J!`-rcJP2Yqxn{(^R z=A724D~FHJV6l7(j(z1~Eu)7clAT7o`C)n7Fz^M9Sf&guYOdJQp{Q1zA5du?dFyB zLCDzCC0n~!#z7vou{8=#{M1nunGRPZhujC23Fm7vG|it2)xkF~gecEtz|bm$0gEEg zP^V3!h(0GmQoHa3#bSpi6GB!ik|@|Y@54Mkp~&0R<{sbNJ@(BbO&iaf`(})42<@`B zN(H(yu}|m9=Slg*t7~W}xiQpH9~qI_ZWnulMx(mN{EUtcKN{d)Y`=lt2hwsg3k45T z`7vSUElift8*xX%+s7-M1F2#x@<0yV4BOGp*6^5ppOA>T^wep zE$bO|%+1x)&udghk}O7AAkj2Ply6%wir;aWTk#Dq0L_D1IT2rr`V$XT!@(8)W)YU- zy$8Q-CwE&dsnUxvF;im#LBMSfR@5M=ZAjiRW=@hDGJ zje^yu&)h=<`@l2Be?gFAL}{6MIm0YNmGNGp!4|T^#8OFjj+S}yq>tAyc|3sTA$D1E~Q4pgK(;w;umbsR(un{Y+#dee@)wdDV;NTs{d8{={+*YKOoe4w{Yx56<{ zykH(jUL;>A_NAAuj0}R5Xn>t{1eK$I_5&uv&n`p*=m87fO5e;J^ac;2MNeHaID598 z433sKZGGHDT~>lnZd9gajEE*P&70y1a}iqfT3$eAB!U|v5Hs|pM@;5*2lsH6uEipo zX@)DWFzkHW}jWU?)L-L%Om=8$#z zAB1`cYqy+2qhK=+rVXfS_piN3gnDCkBcHzqvA?w+@Q4KMy7%^+!kt2LAngqLNN`pj zOi;T)&RBtdU%G?vp^v9~ECo>0^8oxAY%^c=fN*0hI01%h%eTjI9PyDi&nKV-hn$3) zcu3{c>lg$~D;}o^=dCsjr4-UysWiTlOLRmG&Gy?>!n)J#@-mtil^-ZfHf#!wtOWGf ze`le&T+a(cDD+GKvsW zNhh-%o8<=c<5&~eOQF|(%V`WDV1qPDJp)Pt2Rrt-J$Svx*8&TBtoX2X2ger$mSfBz z8+b4K{j~id3lUzbZLQ%jmM6xtBZbw_Xj0zlObhbexxj)4-a-R>GZcgIEf+>(mO)j? zQ0JP4XmEza;kEYtauNFJkH=r)0ek3?XAM|tv;SfJAXP=9u)u2y z*tHHUOu0Se^K4r~j|`~(@(Jom2~Gj9*&}sBcOhZJ7WQR2-#ak;djNv_x}*k>n=gEN ze#dfT*V3;$M410gXyU;0VT8B48p4;B%~gy0Eyik|Id$IcFnS7_b^K|FKb=!@f~if0 zo2o|j0}4VKNOff7E$>LNuYi@RU1eZf_sgXw85TcpAKInYZG8qtFna%<>Pj|AAY zwuXYM)JDgfn(-ghqh>Sv_FH2;6YoILou>qPC&j{%7Ye9?0>)kJyH$p3eZr*CFP%TB zF~wD}CIWqpPyubG>nyNXrUWbv`E+1%yPb!m!dt1>8vsHsUSz(0_OeqmCzZrko>I=* zCV;lm7PxCFTB0c_>q|p44USg%9mydjpQ8Y9E~4~3Y11zYcFz@yF&SFc5m$R{gcNnw?&{!%fg=5Q+s$uq}+yCJ3R!x&ZIfW6LRbO76KH#yqQTZ1UC?>3UMR_sHEF7E<*7vlKie~1!m=zhg)U!V=fL2FSZ~hJ zIn`3J#@w8NCA?YiR>g=($X)B9YR%@}tsB2y77FnZHm)!IPV)kNX`1wpl?6Jm{tk`9 zVIK8+H*;GeZ>abI;b&_9&drPmn_{+Cnc{hUn&cHO-%fir9&9MiA5Ee3{6!CQ3x$gOqflWK>@0tg-kl61cApubF%npW>|(GpsKmIozp z%esv^yTni@daGxr-a>bb^-cZ+0vt3OY+Q0f2NFeljH?;nY zDja!epi&d~ZeF{y`B8XzOavF1%(w+BwrOF!3-D`~U@?5anC)70%T;ktMJzqVU(4MP zP*Hcl9n|pJ^{jKqR@ZcD4?Z$a=vBX3=q2iyjLQ6LSoY)S zT`~00Ac7K>o)(%P0+^5yElbYqsu=J-1j#kEOsXiObI5uU>+Hi8h~v{O${@_~IcHZl zJ4Fd57s3k>IbFgUxc}>rP8y9)WNB@mNB$TNo?`|g07xj>_9loz`ty^mThPw~^bF0R zKKl#dJ02|gLtf)#NvcU*&m#YK6Dt3!H&`J-8MrAqkus0bsk*sm)+jxx9pek9+3YIE z=ZuG9F_9IBMkhu#LZZz+&CtQX%<%$7ng!Qr!tK37{3zdE(Uk>bJ_v6tdhIIUgoP`u zL{lB%Uov0zE`ZPQ95Fo_L72Zacg90t*}|R{i0Jsc!V+;IG)E&{GttPXFDJcZ>ymx> zNOp7x4i+40`GtM9VGU{X9UNgN@z1>;>$Rxue$pqw3$e<*sNOIe0V#)A`DA#K&GR>Z zxBa5KJ}P2Am7TEei?7}VcfXc4yFt5&eZ>fLw^xgTktp8;Cd4c23>1QXd^qRib#64V{j^+X)n-eFb~@ z;$}imsBpW%4L?YSw_&o-x{fYT!?hb4-e<^<($Fh#|3Fs`%UROWEAa=REJfsyY3mwe zHoEQH_bry{d)M*D4w|ivXdmwdJl6OQfyF=QEzc9RU#v*OhRC-C)z`~fIaB0JBVMMX zWqdS+A5kvf)FNlkHIwP-#k~5&cGa9|TC4ednk-<`<3XbH07(`F=2isP0q!HyMONAbr68#L+MPHBJ@v zLImJ0%(yrMIQ(#tcPf@@&r#hAGBxYAmFnX{Qk2Et3H%T$@2F{t1uz7tCH4=8AQ*Iql4VfS75rLOxrI$?L>1Yt zIuZ^oyR22_N!Q6>9fewLt19KdQewE$JhFo=Z-_1X7ey;KTzMm0`NOH$GKb9UP;UZw zo>N%T9a;+f$DHvZ-P<&eR8^nyWlKMU>VxG|ZWp#G@wdsD8T3^(U3K`+&Q}*#S6rl% zI4mTxnvh_{%XEeZUX2#-g0r@;7{u6DbX-odbO909&Xob9pSJ;{9UD7#O`Y57Nahyl zjhYti&8MnuwGm-bV$Y-U@iuDYyR^y*z4G^1pCi(OAtrxPmwf6h7_xpnz5MJhkg

v{%&O%j_VacyXITq)bF`#P?+s+AFjdLi_@!d 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

NbvSq5DI7Q_xR|k#K$x<7R)R< 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 literal 0 HcmV?d00001 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8adb6c7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required (VERSION 3.8) +cmake_policy(SET CMP0074 NEW) + +project (vs_generate) +set(CMAKE_CXX_STANDARD 17) + +set(PROJECT_SOURCE + main.cpp vs_generate.cpp + vs_generate.h tinyxml2.h tinyxml2.cpp + vs_json.cpp vs_json.h +) + +set(JSONCPP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/jsoncpp-lib) +if (MSVC) + string(APPEND CMAKE_CXX_FLAGS " /source-charset:utf-8 /EHsc") + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories(${JSONCPP_DIR}/include) +link_directories(${JSONCPP_DIR}/lib) +add_executable(vs_generate ${PROJECT_SOURCE}) + +if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + target_link_libraries(vs_generate PRIVATE jsoncpp_staticD) +else() + target_link_libraries(vs_generate PRIVATE jsoncpp_static) +endif() diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae60be2 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# 说明 + +根据 vcxproj 或者 sln 工程文件导出 clangd 使用的 compile_commands.json 文件。 \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..051a1cf --- /dev/null +++ b/main.cpp @@ -0,0 +1,37 @@ +#include "vs_json.h" +#define VS_GENERATE_VERSION "v1.0" + +int main(int argc, char** argv) { + // + if (argc != 5) { + std::string help(VS_GENERATE_VERSION); + help.append("\n"); + help.append( + "vs_generate [xx.sln或xxx.vcxproj] [Debug|x64] [xxxx.json] " + "[expect:xxx;ccc;]"); + help.append("\n expect选项没有则:后空着即可。"); + std::cout << help << std::endl; + return 0; + } + + std::string sln_path(argv[1]); + VsParseSln sln; + if (!sln.parse(sln_path)) { + return -1; + } + + VsParsePro pro{}; + auto projs = sln.get_project(); + for (auto& item : projs) { + if (!pro.parse(&item, std::string(argv[2]))) { + continue; + } + } + + JsonCommand command{}; + command.set_expect(std::string(argv[4])); + command.set_out(std::string(argv[3])); + command.generate(projs); + + return 0; +} diff --git a/tinyxml2.cpp b/tinyxml2.cpp new file mode 100644 index 0000000..9173467 --- /dev/null +++ b/tinyxml2.cpp @@ -0,0 +1,2986 @@ +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml2.h" + +#include // yes, this one new style header, is in the Android SDK. +#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) +# include +# include +#else +# include +# include +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) + // Microsoft Visual Studio, version 2005 and higher. Not WinCE. + /*int _snprintf_s( + char *buffer, + size_t sizeOfBuffer, + size_t count, + const char *format [, + argument] ... + );*/ + static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) + { + va_list va; + va_start( va, format ); + const int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + va_end( va ); + return result; + } + + static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va ) + { + const int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + return result; + } + + #define TIXML_VSCPRINTF _vscprintf + #define TIXML_SSCANF sscanf_s +#elif defined _MSC_VER + // Microsoft Visual Studio 2003 and earlier or WinCE + #define TIXML_SNPRINTF _snprintf + #define TIXML_VSNPRINTF _vsnprintf + #define TIXML_SSCANF sscanf + #if (_MSC_VER < 1400 ) && (!defined WINCE) + // Microsoft Visual Studio 2003 and not WinCE. + #define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have. + #else + // Microsoft Visual Studio 2003 and earlier or WinCE. + static inline int TIXML_VSCPRINTF( const char* format, va_list va ) + { + int len = 512; + for (;;) { + len = len*2; + char* str = new char[len](); + const int required = _vsnprintf(str, len, format, va); + delete[] str; + if ( required != -1 ) { + TIXMLASSERT( required >= 0 ); + len = required; + break; + } + } + TIXMLASSERT( len >= 0 ); + return len; + } + #endif +#else + // GCC version 3 and higher + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_VSNPRINTF vsnprintf + static inline int TIXML_VSCPRINTF( const char* format, va_list va ) + { + int len = vsnprintf( 0, 0, format, va ); + TIXMLASSERT( len >= 0 ); + return len; + } + #define TIXML_SSCANF sscanf +#endif + +#if defined(_WIN64) + #define TIXML_FSEEK _fseeki64 + #define TIXML_FTELL _ftelli64 +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__ANDROID__) + #define TIXML_FSEEK fseeko + #define TIXML_FTELL ftello +#elif defined(__unix__) && defined(__x86_64__) + #define TIXML_FSEEK fseeko64 + #define TIXML_FTELL ftello64 +#else + #define TIXML_FSEEK fseek + #define TIXML_FTELL ftell +#endif + + +static const char LINE_FEED = static_cast(0x0a); // all line endings are normalized to LF +static const char LF = LINE_FEED; +static const char CARRIAGE_RETURN = static_cast(0x0d); // CR gets filtered out +static const char CR = CARRIAGE_RETURN; +static const char SINGLE_QUOTE = '\''; +static const char DOUBLE_QUOTE = '\"'; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// ef bb bf (Microsoft "lead bytes") - designates UTF-8 + +static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + +namespace tinyxml2 +{ + +struct Entity { + const char* pattern; + int length; + char value; +}; + +static const int NUM_ENTITIES = 5; +static const Entity entities[NUM_ENTITIES] = { + { "quot", 4, DOUBLE_QUOTE }, + { "amp", 3, '&' }, + { "apos", 4, SINGLE_QUOTE }, + { "lt", 2, '<' }, + { "gt", 2, '>' } +}; + + +StrPair::~StrPair() +{ + Reset(); +} + + +void StrPair::TransferTo( StrPair* other ) +{ + if ( this == other ) { + return; + } + // This in effect implements the assignment operator by "moving" + // ownership (as in auto_ptr). + + TIXMLASSERT( other != 0 ); + TIXMLASSERT( other->_flags == 0 ); + TIXMLASSERT( other->_start == 0 ); + TIXMLASSERT( other->_end == 0 ); + + other->Reset(); + + other->_flags = _flags; + other->_start = _start; + other->_end = _end; + + _flags = 0; + _start = 0; + _end = 0; +} + + +void StrPair::Reset() +{ + if ( _flags & NEEDS_DELETE ) { + delete [] _start; + } + _flags = 0; + _start = 0; + _end = 0; +} + + +void StrPair::SetStr( const char* str, int flags ) +{ + TIXMLASSERT( str ); + Reset(); + size_t len = strlen( str ); + TIXMLASSERT( _start == 0 ); + _start = new char[ len+1 ]; + memcpy( _start, str, len+1 ); + _end = _start + len; + _flags = flags | NEEDS_DELETE; +} + + +char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr ) +{ + TIXMLASSERT( p ); + TIXMLASSERT( endTag && *endTag ); + TIXMLASSERT(curLineNumPtr); + + char* start = p; + const char endChar = *endTag; + size_t length = strlen( endTag ); + + // Inner loop of text parsing. + while ( *p ) { + if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { + Set( start, p, strFlags ); + return p + length; + } else if (*p == '\n') { + ++(*curLineNumPtr); + } + ++p; + TIXMLASSERT( p ); + } + return 0; +} + + +char* StrPair::ParseName( char* p ) +{ + if ( !p || !(*p) ) { + return 0; + } + if ( !XMLUtil::IsNameStartChar( (unsigned char) *p ) ) { + return 0; + } + + char* const start = p; + ++p; + while ( *p && XMLUtil::IsNameChar( (unsigned char) *p ) ) { + ++p; + } + + Set( start, p, 0 ); + return p; +} + + +void StrPair::CollapseWhitespace() +{ + // Adjusting _start would cause undefined behavior on delete[] + TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 ); + // Trim leading space. + _start = XMLUtil::SkipWhiteSpace( _start, 0 ); + + if ( *_start ) { + const char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( *p ) { + if ( XMLUtil::IsWhiteSpace( *p )) { + p = XMLUtil::SkipWhiteSpace( p, 0 ); + if ( *p == 0 ) { + break; // don't write to q; this trims the trailing space. + } + *q = ' '; + ++q; + } + *q = *p; + ++q; + ++p; + } + *q = 0; + } +} + + +const char* StrPair::GetStr() +{ + TIXMLASSERT( _start ); + TIXMLASSERT( _end ); + if ( _flags & NEEDS_FLUSH ) { + *_end = 0; + _flags ^= NEEDS_FLUSH; + + if ( _flags ) { + const char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( p < _end ) { + if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { + // CR-LF pair becomes LF + // CR alone becomes LF + // LF-CR becomes LF + if ( *(p+1) == LF ) { + p += 2; + } + else { + ++p; + } + *q = LF; + ++q; + } + else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { + if ( *(p+1) == CR ) { + p += 2; + } + else { + ++p; + } + *q = LF; + ++q; + } + else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { + // Entities handled by tinyXML2: + // - special entities in the entity table [in/out] + // - numeric character reference [in] + // 中 or 中 + + if ( *(p+1) == '#' ) { + const int buflen = 10; + char buf[buflen] = { 0 }; + int len = 0; + const char* adjusted = const_cast( XMLUtil::GetCharacterRef( p, buf, &len ) ); + if ( adjusted == 0 ) { + *q = *p; + ++p; + ++q; + } + else { + TIXMLASSERT( 0 <= len && len <= buflen ); + TIXMLASSERT( q + len <= adjusted ); + p = adjusted; + memcpy( q, buf, len ); + q += len; + } + } + else { + bool entityFound = false; + for( int i = 0; i < NUM_ENTITIES; ++i ) { + const Entity& entity = entities[i]; + if ( strncmp( p + 1, entity.pattern, entity.length ) == 0 + && *( p + entity.length + 1 ) == ';' ) { + // Found an entity - convert. + *q = entity.value; + ++q; + p += entity.length + 2; + entityFound = true; + break; + } + } + if ( !entityFound ) { + // fixme: treat as error? + ++p; + ++q; + } + } + } + else { + *q = *p; + ++p; + ++q; + } + } + *q = 0; + } + // The loop below has plenty going on, and this + // is a less useful mode. Break it out. + if ( _flags & NEEDS_WHITESPACE_COLLAPSING ) { + CollapseWhitespace(); + } + _flags = (_flags & NEEDS_DELETE); + } + TIXMLASSERT( _start ); + return _start; +} + + + + +// --------- XMLUtil ----------- // + +const char* XMLUtil::writeBoolTrue = "true"; +const char* XMLUtil::writeBoolFalse = "false"; + +void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse) +{ + static const char* defTrue = "true"; + static const char* defFalse = "false"; + + writeBoolTrue = (writeTrue) ? writeTrue : defTrue; + writeBoolFalse = (writeFalse) ? writeFalse : defFalse; +} + + +const char* XMLUtil::ReadBOM( const char* p, bool* bom ) +{ + TIXMLASSERT( p ); + TIXMLASSERT( bom ); + *bom = false; + const unsigned char* pu = reinterpret_cast(p); + // Check for BOM: + if ( *(pu+0) == TIXML_UTF_LEAD_0 + && *(pu+1) == TIXML_UTF_LEAD_1 + && *(pu+2) == TIXML_UTF_LEAD_2 ) { + *bom = true; + p += 3; + } + TIXMLASSERT( p ); + return p; +} + + +void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) { + *length = 1; + } + else if ( input < 0x800 ) { + *length = 2; + } + else if ( input < 0x10000 ) { + *length = 3; + } + else if ( input < 0x200000 ) { + *length = 4; + } + else { + *length = 0; // This code won't convert this correctly anyway. + return; + } + + output += *length; + + // Scary scary fall throughs are annotated with carefully designed comments + // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc + switch (*length) { + case 4: + --output; + *output = static_cast((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 3: + --output; + *output = static_cast((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 2: + --output; + *output = static_cast((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 1: + --output; + *output = static_cast(input | FIRST_BYTE_MARK[*length]); + break; + default: + TIXMLASSERT( false ); + } +} + + +const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) +{ + // Presume an entity, and pull it out. + *length = 0; + + if ( *(p+1) == '#' && *(p+2) ) { + unsigned long ucs = 0; + TIXMLASSERT( sizeof( ucs ) >= 4 ); + ptrdiff_t delta = 0; + unsigned mult = 1; + static const char SEMICOLON = ';'; + + if ( *(p+2) == 'x' ) { + // Hexadecimal. + const char* q = p+3; + if ( !(*q) ) { + return 0; + } + + q = strchr( q, SEMICOLON ); + + if ( !q ) { + return 0; + } + TIXMLASSERT( *q == SEMICOLON ); + + delta = q-p; + --q; + + while ( *q != 'x' ) { + unsigned int digit = 0; + + if ( *q >= '0' && *q <= '9' ) { + digit = *q - '0'; + } + else if ( *q >= 'a' && *q <= 'f' ) { + digit = *q - 'a' + 10; + } + else if ( *q >= 'A' && *q <= 'F' ) { + digit = *q - 'A' + 10; + } + else { + return 0; + } + TIXMLASSERT( digit < 16 ); + TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); + const unsigned int digitScaled = mult * digit; + TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); + ucs += digitScaled; + TIXMLASSERT( mult <= UINT_MAX / 16 ); + mult *= 16; + --q; + } + } + else { + // Decimal. + const char* q = p+2; + if ( !(*q) ) { + return 0; + } + + q = strchr( q, SEMICOLON ); + + if ( !q ) { + return 0; + } + TIXMLASSERT( *q == SEMICOLON ); + + delta = q-p; + --q; + + while ( *q != '#' ) { + if ( *q >= '0' && *q <= '9' ) { + const unsigned int digit = *q - '0'; + TIXMLASSERT( digit < 10 ); + TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); + const unsigned int digitScaled = mult * digit; + TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); + ucs += digitScaled; + } + else { + return 0; + } + TIXMLASSERT( mult <= UINT_MAX / 10 ); + mult *= 10; + --q; + } + } + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + return p + delta + 1; + } + return p+1; +} + + +void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); +} + + +void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); +} + + +void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse); +} + +/* + ToStr() of a number is a very tricky topic. + https://github.com/leethomason/tinyxml2/issues/106 +*/ +void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v ); +} + + +void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v ); +} + + +void XMLUtil::ToStr( int64_t v, char* buffer, int bufferSize ) +{ + // horrible syntax trick to make the compiler happy about %lld + TIXML_SNPRINTF(buffer, bufferSize, "%lld", static_cast(v)); +} + +void XMLUtil::ToStr( uint64_t v, char* buffer, int bufferSize ) +{ + // horrible syntax trick to make the compiler happy about %llu + TIXML_SNPRINTF(buffer, bufferSize, "%llu", (long long)v); +} + +bool XMLUtil::ToInt(const char* str, int* value) +{ + if (IsPrefixHex(str)) { + unsigned v; + if (TIXML_SSCANF(str, "%x", &v) == 1) { + *value = static_cast(v); + return true; + } + } + else { + if (TIXML_SSCANF(str, "%d", value) == 1) { + return true; + } + } + return false; +} + +bool XMLUtil::ToUnsigned(const char* str, unsigned* value) +{ + if (TIXML_SSCANF(str, IsPrefixHex(str) ? "%x" : "%u", value) == 1) { + return true; + } + return false; +} + +bool XMLUtil::ToBool( const char* str, bool* value ) +{ + int ival = 0; + if ( ToInt( str, &ival )) { + *value = (ival==0) ? false : true; + return true; + } + static const char* TRUE_VALS[] = { "true", "True", "TRUE", 0 }; + static const char* FALSE_VALS[] = { "false", "False", "FALSE", 0 }; + + for (int i = 0; TRUE_VALS[i]; ++i) { + if (StringEqual(str, TRUE_VALS[i])) { + *value = true; + return true; + } + } + for (int i = 0; FALSE_VALS[i]; ++i) { + if (StringEqual(str, FALSE_VALS[i])) { + *value = false; + return true; + } + } + return false; +} + + +bool XMLUtil::ToFloat( const char* str, float* value ) +{ + if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { + return true; + } + return false; +} + + +bool XMLUtil::ToDouble( const char* str, double* value ) +{ + if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { + return true; + } + return false; +} + + +bool XMLUtil::ToInt64(const char* str, int64_t* value) +{ + if (IsPrefixHex(str)) { + unsigned long long v = 0; // horrible syntax trick to make the compiler happy about %llx + if (TIXML_SSCANF(str, "%llx", &v) == 1) { + *value = static_cast(v); + return true; + } + } + else { + long long v = 0; // horrible syntax trick to make the compiler happy about %lld + if (TIXML_SSCANF(str, "%lld", &v) == 1) { + *value = static_cast(v); + return true; + } + } + return false; +} + + +bool XMLUtil::ToUnsigned64(const char* str, uint64_t* value) { + unsigned long long v = 0; // horrible syntax trick to make the compiler happy about %llu + if(TIXML_SSCANF(str, IsPrefixHex(str) ? "%llx" : "%llu", &v) == 1) { + *value = (uint64_t)v; + return true; + } + return false; +} + + +char* XMLDocument::Identify( char* p, XMLNode** node ) +{ + TIXMLASSERT( node ); + TIXMLASSERT( p ); + char* const start = p; + int const startLine = _parseCurLineNum; + p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); + if( !*p ) { + *node = 0; + TIXMLASSERT( p ); + return p; + } + + // These strings define the matching patterns: + static const char* xmlHeader = { "( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += xmlHeaderLen; + } + else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { + returnNode = CreateUnlinkedNode( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += commentHeaderLen; + } + else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { + XMLText* text = CreateUnlinkedNode( _textPool ); + returnNode = text; + returnNode->_parseLineNum = _parseCurLineNum; + p += cdataHeaderLen; + text->SetCData( true ); + } + else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { + returnNode = CreateUnlinkedNode( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += dtdHeaderLen; + } + else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { + returnNode = CreateUnlinkedNode( _elementPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += elementHeaderLen; + } + else { + returnNode = CreateUnlinkedNode( _textPool ); + returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character + p = start; // Back it up, all the text counts. + _parseCurLineNum = startLine; + } + + TIXMLASSERT( returnNode ); + TIXMLASSERT( p ); + *node = returnNode; + return p; +} + + +bool XMLDocument::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + if ( visitor->VisitEnter( *this ) ) { + for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { + if ( !node->Accept( visitor ) ) { + break; + } + } + } + return visitor->VisitExit( *this ); +} + + +// --------- XMLNode ----------- // + +XMLNode::XMLNode( XMLDocument* doc ) : + _document( doc ), + _parent( 0 ), + _value(), + _parseLineNum( 0 ), + _firstChild( 0 ), _lastChild( 0 ), + _prev( 0 ), _next( 0 ), + _userData( 0 ), + _memPool( 0 ) +{ +} + + +XMLNode::~XMLNode() +{ + DeleteChildren(); + if ( _parent ) { + _parent->Unlink( this ); + } +} + +const char* XMLNode::Value() const +{ + // Edge case: XMLDocuments don't have a Value. Return null. + if ( this->ToDocument() ) + return 0; + return _value.GetStr(); +} + +void XMLNode::SetValue( const char* str, bool staticMem ) +{ + if ( staticMem ) { + _value.SetInternedStr( str ); + } + else { + _value.SetStr( str ); + } +} + +XMLNode* XMLNode::DeepClone(XMLDocument* target) const +{ + XMLNode* clone = this->ShallowClone(target); + if (!clone) return 0; + + for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) { + XMLNode* childClone = child->DeepClone(target); + TIXMLASSERT(childClone); + clone->InsertEndChild(childClone); + } + return clone; +} + +void XMLNode::DeleteChildren() +{ + while( _firstChild ) { + TIXMLASSERT( _lastChild ); + DeleteChild( _firstChild ); + } + _firstChild = _lastChild = 0; +} + + +void XMLNode::Unlink( XMLNode* child ) +{ + TIXMLASSERT( child ); + TIXMLASSERT( child->_document == _document ); + TIXMLASSERT( child->_parent == this ); + if ( child == _firstChild ) { + _firstChild = _firstChild->_next; + } + if ( child == _lastChild ) { + _lastChild = _lastChild->_prev; + } + + if ( child->_prev ) { + child->_prev->_next = child->_next; + } + if ( child->_next ) { + child->_next->_prev = child->_prev; + } + child->_next = 0; + child->_prev = 0; + child->_parent = 0; +} + + +void XMLNode::DeleteChild( XMLNode* node ) +{ + TIXMLASSERT( node ); + TIXMLASSERT( node->_document == _document ); + TIXMLASSERT( node->_parent == this ); + Unlink( node ); + TIXMLASSERT(node->_prev == 0); + TIXMLASSERT(node->_next == 0); + TIXMLASSERT(node->_parent == 0); + DeleteNode( node ); +} + + +XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) +{ + TIXMLASSERT( addThis ); + if ( addThis->_document != _document ) { + TIXMLASSERT( false ); + return 0; + } + InsertChildPreamble( addThis ); + + if ( _lastChild ) { + TIXMLASSERT( _firstChild ); + TIXMLASSERT( _lastChild->_next == 0 ); + _lastChild->_next = addThis; + addThis->_prev = _lastChild; + _lastChild = addThis; + + addThis->_next = 0; + } + else { + TIXMLASSERT( _firstChild == 0 ); + _firstChild = _lastChild = addThis; + + addThis->_prev = 0; + addThis->_next = 0; + } + addThis->_parent = this; + return addThis; +} + + +XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) +{ + TIXMLASSERT( addThis ); + if ( addThis->_document != _document ) { + TIXMLASSERT( false ); + return 0; + } + InsertChildPreamble( addThis ); + + if ( _firstChild ) { + TIXMLASSERT( _lastChild ); + TIXMLASSERT( _firstChild->_prev == 0 ); + + _firstChild->_prev = addThis; + addThis->_next = _firstChild; + _firstChild = addThis; + + addThis->_prev = 0; + } + else { + TIXMLASSERT( _lastChild == 0 ); + _firstChild = _lastChild = addThis; + + addThis->_prev = 0; + addThis->_next = 0; + } + addThis->_parent = this; + return addThis; +} + + +XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) +{ + TIXMLASSERT( addThis ); + if ( addThis->_document != _document ) { + TIXMLASSERT( false ); + return 0; + } + + TIXMLASSERT( afterThis ); + + if ( afterThis->_parent != this ) { + TIXMLASSERT( false ); + return 0; + } + if ( afterThis == addThis ) { + // Current state: BeforeThis -> AddThis -> OneAfterAddThis + // Now AddThis must disappear from it's location and then + // reappear between BeforeThis and OneAfterAddThis. + // So just leave it where it is. + return addThis; + } + + if ( afterThis->_next == 0 ) { + // The last node or the only node. + return InsertEndChild( addThis ); + } + InsertChildPreamble( addThis ); + addThis->_prev = afterThis; + addThis->_next = afterThis->_next; + afterThis->_next->_prev = addThis; + afterThis->_next = addThis; + addThis->_parent = this; + return addThis; +} + + + + +const XMLElement* XMLNode::FirstChildElement( const char* name ) const +{ + for( const XMLNode* node = _firstChild; node; node = node->_next ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +const XMLElement* XMLNode::LastChildElement( const char* name ) const +{ + for( const XMLNode* node = _lastChild; node; node = node->_prev ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +const XMLElement* XMLNode::NextSiblingElement( const char* name ) const +{ + for( const XMLNode* node = _next; node; node = node->_next ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const +{ + for( const XMLNode* node = _prev; node; node = node->_prev ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) +{ + // This is a recursive method, but thinking about it "at the current level" + // it is a pretty simple flat list: + // + // + // + // With a special case: + // + // + // + // + // Where the closing element (/foo) *must* be the next thing after the opening + // element, and the names must match. BUT the tricky bit is that the closing + // element will be read by the child. + // + // 'endTag' is the end tag for this node, it is returned by a call to a child. + // 'parentEnd' is the end tag for the parent, which is filled in and returned. + + XMLDocument::DepthTracker tracker(_document); + if (_document->Error()) + return 0; + + while( p && *p ) { + XMLNode* node = 0; + + p = _document->Identify( p, &node ); + TIXMLASSERT( p ); + if ( node == 0 ) { + break; + } + + const int initialLineNum = node->_parseLineNum; + + StrPair endTag; + p = node->ParseDeep( p, &endTag, curLineNumPtr ); + if ( !p ) { + DeleteNode( node ); + if ( !_document->Error() ) { + _document->SetError( XML_ERROR_PARSING, initialLineNum, 0); + } + break; + } + + const XMLDeclaration* const decl = node->ToDeclaration(); + if ( decl ) { + // Declarations are only allowed at document level + // + // Multiple declarations are allowed but all declarations + // must occur before anything else. + // + // Optimized due to a security test case. If the first node is + // a declaration, and the last node is a declaration, then only + // declarations have so far been added. + bool wellLocated = false; + + if (ToDocument()) { + if (FirstChild()) { + wellLocated = + FirstChild() && + FirstChild()->ToDeclaration() && + LastChild() && + LastChild()->ToDeclaration(); + } + else { + wellLocated = true; + } + } + if ( !wellLocated ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); + DeleteNode( node ); + break; + } + } + + XMLElement* ele = node->ToElement(); + if ( ele ) { + // We read the end tag. Return it to the parent. + if ( ele->ClosingType() == XMLElement::CLOSING ) { + if ( parentEndTag ) { + ele->_value.TransferTo( parentEndTag ); + } + node->_memPool->SetTracked(); // created and then immediately deleted. + DeleteNode( node ); + return p; + } + + // Handle an end tag returned to this level. + // And handle a bunch of annoying errors. + bool mismatch = false; + if ( endTag.Empty() ) { + if ( ele->ClosingType() == XMLElement::OPEN ) { + mismatch = true; + } + } + else { + if ( ele->ClosingType() != XMLElement::OPEN ) { + mismatch = true; + } + else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) { + mismatch = true; + } + } + if ( mismatch ) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); + DeleteNode( node ); + break; + } + } + InsertEndChild( node ); + } + return 0; +} + +/*static*/ void XMLNode::DeleteNode( XMLNode* node ) +{ + if ( node == 0 ) { + return; + } + TIXMLASSERT(node->_document); + if (!node->ToDocument()) { + node->_document->MarkInUse(node); + } + + MemPool* pool = node->_memPool; + node->~XMLNode(); + pool->Free( node ); +} + +void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const +{ + TIXMLASSERT( insertThis ); + TIXMLASSERT( insertThis->_document == _document ); + + if (insertThis->_parent) { + insertThis->_parent->Unlink( insertThis ); + } + else { + insertThis->_document->MarkInUse(insertThis); + insertThis->_memPool->SetTracked(); + } +} + +const XMLElement* XMLNode::ToElementWithName( const char* name ) const +{ + const XMLElement* element = this->ToElement(); + if ( element == 0 ) { + return 0; + } + if ( name == 0 ) { + return element; + } + if ( XMLUtil::StringEqual( element->Name(), name ) ) { + return element; + } + return 0; +} + +// --------- XMLText ---------- // +char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + if ( this->CData() ) { + p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_CDATA, _parseLineNum, 0 ); + } + return p; + } + else { + int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; + if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { + flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; + } + + p = _value.ParseText( p, "<", flags, curLineNumPtr ); + if ( p && *p ) { + return p-1; + } + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_TEXT, _parseLineNum, 0 ); + } + } + return 0; +} + + +XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? + text->SetCData( this->CData() ); + return text; +} + + +bool XMLText::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLText* text = compare->ToText(); + return ( text && XMLUtil::StringEqual( text->Value(), Value() ) ); +} + + +bool XMLText::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + + +// --------- XMLComment ---------- // + +XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLComment::~XMLComment() +{ +} + + +char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + // Comment parses as text. + p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_COMMENT, _parseLineNum, 0 ); + } + return p; +} + + +XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? + return comment; +} + + +bool XMLComment::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLComment* comment = compare->ToComment(); + return ( comment && XMLUtil::StringEqual( comment->Value(), Value() )); +} + + +bool XMLComment::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + + +// --------- XMLDeclaration ---------- // + +XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLDeclaration::~XMLDeclaration() +{ + //printf( "~XMLDeclaration\n" ); +} + + +char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + // Declaration parses as text. + p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0 ); + } + return p; +} + + +XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? + return dec; +} + + +bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLDeclaration* declaration = compare->ToDeclaration(); + return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() )); +} + + + +bool XMLDeclaration::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + +// --------- XMLUnknown ---------- // + +XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLUnknown::~XMLUnknown() +{ +} + + +char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + // Unknown parses as text. + p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0 ); + } + return p; +} + + +XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? + return text; +} + + +bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLUnknown* unknown = compare->ToUnknown(); + return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() )); +} + + +bool XMLUnknown::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + +// --------- XMLAttribute ---------- // + +const char* XMLAttribute::Name() const +{ + return _name.GetStr(); +} + +const char* XMLAttribute::Value() const +{ + return _value.GetStr(); +} + +char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr ) +{ + // Parse using the name rules: bug fix, was using ParseText before + p = _name.ParseName( p ); + if ( !p || !*p ) { + return 0; + } + + // Skip white space before = + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + if ( *p != '=' ) { + return 0; + } + + ++p; // move up to opening quote + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + if ( *p != '\"' && *p != '\'' ) { + return 0; + } + + const char endTag[2] = { *p, 0 }; + ++p; // move past opening quote + + p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr ); + return p; +} + + +void XMLAttribute::SetName( const char* n ) +{ + _name.SetStr( n ); +} + + +XMLError XMLAttribute::QueryIntValue( int* value ) const +{ + if ( XMLUtil::ToInt( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const +{ + if ( XMLUtil::ToUnsigned( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryInt64Value(int64_t* value) const +{ + if (XMLUtil::ToInt64(Value(), value)) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryUnsigned64Value(uint64_t* value) const +{ + if(XMLUtil::ToUnsigned64(Value(), value)) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryBoolValue( bool* value ) const +{ + if ( XMLUtil::ToBool( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryFloatValue( float* value ) const +{ + if ( XMLUtil::ToFloat( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryDoubleValue( double* value ) const +{ + if ( XMLUtil::ToDouble( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +void XMLAttribute::SetAttribute( const char* v ) +{ + _value.SetStr( v ); +} + + +void XMLAttribute::SetAttribute( int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute( unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute(int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); +} + +void XMLAttribute::SetAttribute(uint64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); +} + + +void XMLAttribute::SetAttribute( bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( float v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +// --------- XMLElement ---------- // +XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), + _closingType( OPEN ), + _rootAttribute( 0 ) +{ +} + + +XMLElement::~XMLElement() +{ + while( _rootAttribute ) { + XMLAttribute* next = _rootAttribute->_next; + DeleteAttribute( _rootAttribute ); + _rootAttribute = next; + } +} + + +const XMLAttribute* XMLElement::FindAttribute( const char* name ) const +{ + for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) { + if ( XMLUtil::StringEqual( a->Name(), name ) ) { + return a; + } + } + return 0; +} + + +const char* XMLElement::Attribute( const char* name, const char* value ) const +{ + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return 0; + } + if ( !value || XMLUtil::StringEqual( a->Value(), value )) { + return a->Value(); + } + return 0; +} + +int XMLElement::IntAttribute(const char* name, int defaultValue) const +{ + int i = defaultValue; + QueryIntAttribute(name, &i); + return i; +} + +unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const +{ + unsigned i = defaultValue; + QueryUnsignedAttribute(name, &i); + return i; +} + +int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const +{ + int64_t i = defaultValue; + QueryInt64Attribute(name, &i); + return i; +} + +uint64_t XMLElement::Unsigned64Attribute(const char* name, uint64_t defaultValue) const +{ + uint64_t i = defaultValue; + QueryUnsigned64Attribute(name, &i); + return i; +} + +bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const +{ + bool b = defaultValue; + QueryBoolAttribute(name, &b); + return b; +} + +double XMLElement::DoubleAttribute(const char* name, double defaultValue) const +{ + double d = defaultValue; + QueryDoubleAttribute(name, &d); + return d; +} + +float XMLElement::FloatAttribute(const char* name, float defaultValue) const +{ + float f = defaultValue; + QueryFloatAttribute(name, &f); + return f; +} + +const char* XMLElement::GetText() const +{ + /* skip comment node */ + const XMLNode* node = FirstChild(); + while (node) { + if (node->ToComment()) { + node = node->NextSibling(); + continue; + } + break; + } + + if ( node && node->ToText() ) { + return node->Value(); + } + return 0; +} + + +void XMLElement::SetText( const char* inText ) +{ + if ( FirstChild() && FirstChild()->ToText() ) + FirstChild()->SetValue( inText ); + else { + XMLText* theText = GetDocument()->NewText( inText ); + InsertFirstChild( theText ); + } +} + + +void XMLElement::SetText( int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + +void XMLElement::SetText( unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + +void XMLElement::SetText(int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); +} + +void XMLElement::SetText(uint64_t v) { + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); +} + + +void XMLElement::SetText( bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + +void XMLElement::SetText( float v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + +void XMLElement::SetText( double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + +XMLError XMLElement::QueryIntText( int* ival ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToInt( t, ival ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToUnsigned( t, uval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryInt64Text(int64_t* ival) const +{ + if (FirstChild() && FirstChild()->ToText()) { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToInt64(t, ival)) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryUnsigned64Text(uint64_t* ival) const +{ + if(FirstChild() && FirstChild()->ToText()) { + const char* t = FirstChild()->Value(); + if(XMLUtil::ToUnsigned64(t, ival)) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryBoolText( bool* bval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToBool( t, bval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryDoubleText( double* dval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToDouble( t, dval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryFloatText( float* fval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToFloat( t, fval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + +int XMLElement::IntText(int defaultValue) const +{ + int i = defaultValue; + QueryIntText(&i); + return i; +} + +unsigned XMLElement::UnsignedText(unsigned defaultValue) const +{ + unsigned i = defaultValue; + QueryUnsignedText(&i); + return i; +} + +int64_t XMLElement::Int64Text(int64_t defaultValue) const +{ + int64_t i = defaultValue; + QueryInt64Text(&i); + return i; +} + +uint64_t XMLElement::Unsigned64Text(uint64_t defaultValue) const +{ + uint64_t i = defaultValue; + QueryUnsigned64Text(&i); + return i; +} + +bool XMLElement::BoolText(bool defaultValue) const +{ + bool b = defaultValue; + QueryBoolText(&b); + return b; +} + +double XMLElement::DoubleText(double defaultValue) const +{ + double d = defaultValue; + QueryDoubleText(&d); + return d; +} + +float XMLElement::FloatText(float defaultValue) const +{ + float f = defaultValue; + QueryFloatText(&f); + return f; +} + + +XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) +{ + XMLAttribute* last = 0; + XMLAttribute* attrib = 0; + for( attrib = _rootAttribute; + attrib; + last = attrib, attrib = attrib->_next ) { + if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { + break; + } + } + if ( !attrib ) { + attrib = CreateAttribute(); + TIXMLASSERT( attrib ); + if ( last ) { + TIXMLASSERT( last->_next == 0 ); + last->_next = attrib; + } + else { + TIXMLASSERT( _rootAttribute == 0 ); + _rootAttribute = attrib; + } + attrib->SetName( name ); + } + return attrib; +} + + +void XMLElement::DeleteAttribute( const char* name ) +{ + XMLAttribute* prev = 0; + for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { + if ( XMLUtil::StringEqual( name, a->Name() ) ) { + if ( prev ) { + prev->_next = a->_next; + } + else { + _rootAttribute = a->_next; + } + DeleteAttribute( a ); + break; + } + prev = a; + } +} + + +char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr ) +{ + XMLAttribute* prevAttribute = 0; + + // Read the attributes. + while( p ) { + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + if ( !(*p) ) { + _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name() ); + return 0; + } + + // attribute. + if (XMLUtil::IsNameStartChar( (unsigned char) *p ) ) { + XMLAttribute* attrib = CreateAttribute(); + TIXMLASSERT( attrib ); + attrib->_parseLineNum = _document->_parseCurLineNum; + + const int attrLineNum = attrib->_parseLineNum; + + p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr ); + if ( !p || Attribute( attrib->Name() ) ) { + DeleteAttribute( attrib ); + _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name() ); + return 0; + } + // There is a minor bug here: if the attribute in the source xml + // document is duplicated, it will not be detected and the + // attribute will be doubly added. However, tracking the 'prevAttribute' + // avoids re-scanning the attribute list. Preferring performance for + // now, may reconsider in the future. + if ( prevAttribute ) { + TIXMLASSERT( prevAttribute->_next == 0 ); + prevAttribute->_next = attrib; + } + else { + TIXMLASSERT( _rootAttribute == 0 ); + _rootAttribute = attrib; + } + prevAttribute = attrib; + } + // end of the tag + else if ( *p == '>' ) { + ++p; + break; + } + // end of the tag + else if ( *p == '/' && *(p+1) == '>' ) { + _closingType = CLOSED; + return p+2; // done; sealed element. + } + else { + _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0 ); + return 0; + } + } + return p; +} + +void XMLElement::DeleteAttribute( XMLAttribute* attribute ) +{ + if ( attribute == 0 ) { + return; + } + MemPool* pool = attribute->_memPool; + attribute->~XMLAttribute(); + pool->Free( attribute ); +} + +XMLAttribute* XMLElement::CreateAttribute() +{ + TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); + XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); + TIXMLASSERT( attrib ); + attrib->_memPool = &_document->_attributePool; + attrib->_memPool->SetTracked(); + return attrib; +} + + +XMLElement* XMLElement::InsertNewChildElement(const char* name) +{ + XMLElement* node = _document->NewElement(name); + return InsertEndChild(node) ? node : 0; +} + +XMLComment* XMLElement::InsertNewComment(const char* comment) +{ + XMLComment* node = _document->NewComment(comment); + return InsertEndChild(node) ? node : 0; +} + +XMLText* XMLElement::InsertNewText(const char* text) +{ + XMLText* node = _document->NewText(text); + return InsertEndChild(node) ? node : 0; +} + +XMLDeclaration* XMLElement::InsertNewDeclaration(const char* text) +{ + XMLDeclaration* node = _document->NewDeclaration(text); + return InsertEndChild(node) ? node : 0; +} + +XMLUnknown* XMLElement::InsertNewUnknown(const char* text) +{ + XMLUnknown* node = _document->NewUnknown(text); + return InsertEndChild(node) ? node : 0; +} + + + +// +// +// foobar +// +char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) +{ + // Read the element name. + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + + // The closing element is the form. It is + // parsed just like a regular element then deleted from + // the DOM. + if ( *p == '/' ) { + _closingType = CLOSING; + ++p; + } + + p = _value.ParseName( p ); + if ( _value.Empty() ) { + return 0; + } + + p = ParseAttributes( p, curLineNumPtr ); + if ( !p || !*p || _closingType != OPEN ) { + return p; + } + + p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr ); + return p; +} + + + +XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? + for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { + element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? + } + return element; +} + + +bool XMLElement::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLElement* other = compare->ToElement(); + if ( other && XMLUtil::StringEqual( other->Name(), Name() )) { + + const XMLAttribute* a=FirstAttribute(); + const XMLAttribute* b=other->FirstAttribute(); + + while ( a && b ) { + if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { + return false; + } + a = a->Next(); + b = b->Next(); + } + if ( a || b ) { + // different count + return false; + } + return true; + } + return false; +} + + +bool XMLElement::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + if ( visitor->VisitEnter( *this, _rootAttribute ) ) { + for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { + if ( !node->Accept( visitor ) ) { + break; + } + } + } + return visitor->VisitExit( *this ); +} + + +// --------- XMLDocument ----------- // + +// Warning: List must match 'enum XMLError' +const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = { + "XML_SUCCESS", + "XML_NO_ATTRIBUTE", + "XML_WRONG_ATTRIBUTE_TYPE", + "XML_ERROR_FILE_NOT_FOUND", + "XML_ERROR_FILE_COULD_NOT_BE_OPENED", + "XML_ERROR_FILE_READ_ERROR", + "XML_ERROR_PARSING_ELEMENT", + "XML_ERROR_PARSING_ATTRIBUTE", + "XML_ERROR_PARSING_TEXT", + "XML_ERROR_PARSING_CDATA", + "XML_ERROR_PARSING_COMMENT", + "XML_ERROR_PARSING_DECLARATION", + "XML_ERROR_PARSING_UNKNOWN", + "XML_ERROR_EMPTY_DOCUMENT", + "XML_ERROR_MISMATCHED_ELEMENT", + "XML_ERROR_PARSING", + "XML_CAN_NOT_CONVERT_TEXT", + "XML_NO_TEXT_NODE", + "XML_ELEMENT_DEPTH_EXCEEDED" +}; + + +XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) : + XMLNode( 0 ), + _writeBOM( false ), + _processEntities( processEntities ), + _errorID(XML_SUCCESS), + _whitespaceMode( whitespaceMode ), + _errorStr(), + _errorLineNum( 0 ), + _charBuffer( 0 ), + _parseCurLineNum( 0 ), + _parsingDepth(0), + _unlinked(), + _elementPool(), + _attributePool(), + _textPool(), + _commentPool() +{ + // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) + _document = this; +} + + +XMLDocument::~XMLDocument() +{ + Clear(); +} + + +void XMLDocument::MarkInUse(const XMLNode* const node) +{ + TIXMLASSERT(node); + TIXMLASSERT(node->_parent == 0); + + for (int i = 0; i < _unlinked.Size(); ++i) { + if (node == _unlinked[i]) { + _unlinked.SwapRemove(i); + break; + } + } +} + +void XMLDocument::Clear() +{ + DeleteChildren(); + while( _unlinked.Size()) { + DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete. + } + +#ifdef TINYXML2_DEBUG + const bool hadError = Error(); +#endif + ClearError(); + + delete [] _charBuffer; + _charBuffer = 0; + _parsingDepth = 0; + +#if 0 + _textPool.Trace( "text" ); + _elementPool.Trace( "element" ); + _commentPool.Trace( "comment" ); + _attributePool.Trace( "attribute" ); +#endif + +#ifdef TINYXML2_DEBUG + if ( !hadError ) { + TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); + TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); + TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); + TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); + } +#endif +} + + +void XMLDocument::DeepCopy(XMLDocument* target) const +{ + TIXMLASSERT(target); + if (target == this) { + return; // technically success - a no-op. + } + + target->Clear(); + for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) { + target->InsertEndChild(node->DeepClone(target)); + } +} + +XMLElement* XMLDocument::NewElement( const char* name ) +{ + XMLElement* ele = CreateUnlinkedNode( _elementPool ); + ele->SetName( name ); + return ele; +} + + +XMLComment* XMLDocument::NewComment( const char* str ) +{ + XMLComment* comment = CreateUnlinkedNode( _commentPool ); + comment->SetValue( str ); + return comment; +} + + +XMLText* XMLDocument::NewText( const char* str ) +{ + XMLText* text = CreateUnlinkedNode( _textPool ); + text->SetValue( str ); + return text; +} + + +XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) +{ + XMLDeclaration* dec = CreateUnlinkedNode( _commentPool ); + dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); + return dec; +} + + +XMLUnknown* XMLDocument::NewUnknown( const char* str ) +{ + XMLUnknown* unk = CreateUnlinkedNode( _commentPool ); + unk->SetValue( str ); + return unk; +} + +static FILE* callfopen( const char* filepath, const char* mode ) +{ + TIXMLASSERT( filepath ); + TIXMLASSERT( mode ); +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) + FILE* fp = 0; + const errno_t err = fopen_s( &fp, filepath, mode ); + if ( err ) { + return 0; + } +#else + FILE* fp = fopen( filepath, mode ); +#endif + return fp; +} + +void XMLDocument::DeleteNode( XMLNode* node ) { + TIXMLASSERT( node ); + TIXMLASSERT(node->_document == this ); + if (node->_parent) { + node->_parent->DeleteChild( node ); + } + else { + // Isn't in the tree. + // Use the parent delete. + // Also, we need to mark it tracked: we 'know' + // it was never used. + node->_memPool->SetTracked(); + // Call the static XMLNode version: + XMLNode::DeleteNode(node); + } +} + + +XMLError XMLDocument::LoadFile( const char* filename ) +{ + if ( !filename ) { + TIXMLASSERT( false ); + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); + return _errorID; + } + + Clear(); + FILE* fp = callfopen( filename, "rb" ); + if ( !fp ) { + SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename ); + return _errorID; + } + LoadFile( fp ); + fclose( fp ); + return _errorID; +} + +XMLError XMLDocument::LoadFile( FILE* fp ) +{ + Clear(); + + TIXML_FSEEK( fp, 0, SEEK_SET ); + if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + TIXML_FSEEK( fp, 0, SEEK_END ); + + unsigned long long filelength; + { + const long long fileLengthSigned = TIXML_FTELL( fp ); + TIXML_FSEEK( fp, 0, SEEK_SET ); + if ( fileLengthSigned == -1L ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + TIXMLASSERT( fileLengthSigned >= 0 ); + filelength = static_cast(fileLengthSigned); + } + + const size_t maxSizeT = static_cast(-1); + // We'll do the comparison as an unsigned long long, because that's guaranteed to be at + // least 8 bytes, even on a 32-bit platform. + if ( filelength >= static_cast(maxSizeT) ) { + // Cannot handle files which won't fit in buffer together with null terminator + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + if ( filelength == 0 ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + + const size_t size = static_cast(filelength); + TIXMLASSERT( _charBuffer == 0 ); + _charBuffer = new char[size+1]; + const size_t read = fread( _charBuffer, 1, size, fp ); + if ( read != size ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + _charBuffer[size] = 0; + + Parse(); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( const char* filename, bool compact ) +{ + if ( !filename ) { + TIXMLASSERT( false ); + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); + return _errorID; + } + + FILE* fp = callfopen( filename, "w" ); + if ( !fp ) { + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename ); + return _errorID; + } + SaveFile(fp, compact); + fclose( fp ); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) +{ + // Clear any error from the last save, otherwise it will get reported + // for *this* call. + ClearError(); + XMLPrinter stream( fp, compact ); + Print( &stream ); + return _errorID; +} + + +XMLError XMLDocument::Parse( const char* p, size_t len ) +{ + Clear(); + + if ( len == 0 || !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + if ( len == static_cast(-1) ) { + len = strlen( p ); + } + TIXMLASSERT( _charBuffer == 0 ); + _charBuffer = new char[ len+1 ]; + memcpy( _charBuffer, p, len ); + _charBuffer[len] = 0; + + Parse(); + if ( Error() ) { + // clean up now essentially dangling memory. + // and the parse fail can put objects in the + // pools that are dead and inaccessible. + DeleteChildren(); + _elementPool.Clear(); + _attributePool.Clear(); + _textPool.Clear(); + _commentPool.Clear(); + } + return _errorID; +} + + +void XMLDocument::Print( XMLPrinter* streamer ) const +{ + if ( streamer ) { + Accept( streamer ); + } + else { + XMLPrinter stdoutStreamer( stdout ); + Accept( &stdoutStreamer ); + } +} + + +void XMLDocument::ClearError() { + _errorID = XML_SUCCESS; + _errorLineNum = 0; + _errorStr.Reset(); +} + + +void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... ) +{ + TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT ); + _errorID = error; + _errorLineNum = lineNum; + _errorStr.Reset(); + + const size_t BUFFER_SIZE = 1000; + char* buffer = new char[BUFFER_SIZE]; + + TIXMLASSERT(sizeof(error) <= sizeof(int)); + TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d", ErrorIDToName(error), int(error), int(error), lineNum); + + if (format) { + size_t len = strlen(buffer); + TIXML_SNPRINTF(buffer + len, BUFFER_SIZE - len, ": "); + len = strlen(buffer); + + va_list va; + va_start(va, format); + TIXML_VSNPRINTF(buffer + len, BUFFER_SIZE - len, format, va); + va_end(va); + } + _errorStr.SetStr(buffer); + delete[] buffer; +} + + +/*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID) +{ + TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT ); + const char* errorName = _errorNames[errorID]; + TIXMLASSERT( errorName && errorName[0] ); + return errorName; +} + +const char* XMLDocument::ErrorStr() const +{ + return _errorStr.Empty() ? "" : _errorStr.GetStr(); +} + + +void XMLDocument::PrintError() const +{ + printf("%s\n", ErrorStr()); +} + +const char* XMLDocument::ErrorName() const +{ + return ErrorIDToName(_errorID); +} + +void XMLDocument::Parse() +{ + TIXMLASSERT( NoChildren() ); // Clear() must have been called previously + TIXMLASSERT( _charBuffer ); + _parseCurLineNum = 1; + _parseLineNum = 1; + char* p = _charBuffer; + p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); + p = const_cast( XMLUtil::ReadBOM( p, &_writeBOM ) ); + if ( !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return; + } + ParseDeep(p, 0, &_parseCurLineNum ); +} + +void XMLDocument::PushDepth() +{ + _parsingDepth++; + if (_parsingDepth == TINYXML2_MAX_ELEMENT_DEPTH) { + SetError(XML_ELEMENT_DEPTH_EXCEEDED, _parseCurLineNum, "Element nesting is too deep." ); + } +} + +void XMLDocument::PopDepth() +{ + TIXMLASSERT(_parsingDepth > 0); + --_parsingDepth; +} + +XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : + _elementJustOpened( false ), + _stack(), + _firstElement( true ), + _fp( file ), + _depth( depth ), + _textDepth( -1 ), + _processEntities( true ), + _compactMode( compact ), + _buffer() +{ + for( int i=0; i(entityValue); + TIXMLASSERT( flagIndex < ENTITY_RANGE ); + _entityFlag[flagIndex] = true; + } + _restrictedEntityFlag[static_cast('&')] = true; + _restrictedEntityFlag[static_cast('<')] = true; + _restrictedEntityFlag[static_cast('>')] = true; // not required, but consistency is nice + _buffer.Push( 0 ); +} + + +void XMLPrinter::Print( const char* format, ... ) +{ + va_list va; + va_start( va, format ); + + if ( _fp ) { + vfprintf( _fp, format, va ); + } + else { + const int len = TIXML_VSCPRINTF( format, va ); + // Close out and re-start the va-args + va_end( va ); + TIXMLASSERT( len >= 0 ); + va_start( va, format ); + TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 ); + char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator. + TIXML_VSNPRINTF( p, len+1, format, va ); + } + va_end( va ); +} + + +void XMLPrinter::Write( const char* data, size_t size ) +{ + if ( _fp ) { + fwrite ( data , sizeof(char), size, _fp); + } + else { + char* p = _buffer.PushArr( static_cast(size) ) - 1; // back up over the null terminator. + memcpy( p, data, size ); + p[size] = 0; + } +} + + +void XMLPrinter::Putc( char ch ) +{ + if ( _fp ) { + fputc ( ch, _fp); + } + else { + char* p = _buffer.PushArr( sizeof(char) ) - 1; // back up over the null terminator. + p[0] = ch; + p[1] = 0; + } +} + + +void XMLPrinter::PrintSpace( int depth ) +{ + for( int i=0; i 0 && *q < ENTITY_RANGE ) { + // Check for entities. If one is found, flush + // the stream up until the entity, write the + // entity, and keep looking. + if ( flag[static_cast(*q)] ) { + while ( p < q ) { + const size_t delta = q - p; + const int toPrint = ( INT_MAX < delta ) ? INT_MAX : static_cast(delta); + Write( p, toPrint ); + p += toPrint; + } + bool entityPatternPrinted = false; + for( int i=0; i(delta); + Write( p, toPrint ); + } + } + else { + Write( p ); + } +} + + +void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) +{ + if ( writeBOM ) { + static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; + Write( reinterpret_cast< const char* >( bom ) ); + } + if ( writeDec ) { + PushDeclaration( "xml version=\"1.0\"" ); + } +} + +void XMLPrinter::PrepareForNewNode( bool compactMode ) +{ + SealElementIfJustOpened(); + + if ( compactMode ) { + return; + } + + if ( _firstElement ) { + PrintSpace (_depth); + } else if ( _textDepth < 0) { + Putc( '\n' ); + PrintSpace( _depth ); + } + + _firstElement = false; +} + +void XMLPrinter::OpenElement( const char* name, bool compactMode ) +{ + PrepareForNewNode( compactMode ); + _stack.Push( name ); + + Write ( "<" ); + Write ( name ); + + _elementJustOpened = true; + ++_depth; +} + + +void XMLPrinter::PushAttribute( const char* name, const char* value ) +{ + TIXMLASSERT( _elementJustOpened ); + Putc ( ' ' ); + Write( name ); + Write( "=\"" ); + PrintString( value, false ); + Putc ( '\"' ); +} + + +void XMLPrinter::PushAttribute( const char* name, int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute(const char* name, int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); +} + + +void XMLPrinter::PushAttribute(const char* name, uint64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); +} + + +void XMLPrinter::PushAttribute( const char* name, bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::CloseElement( bool compactMode ) +{ + --_depth; + const char* name = _stack.Pop(); + + if ( _elementJustOpened ) { + Write( "/>" ); + } + else { + if ( _textDepth < 0 && !compactMode) { + Putc( '\n' ); + PrintSpace( _depth ); + } + Write ( "" ); + } + + if ( _textDepth == _depth ) { + _textDepth = -1; + } + if ( _depth == 0 && !compactMode) { + Putc( '\n' ); + } + _elementJustOpened = false; +} + + +void XMLPrinter::SealElementIfJustOpened() +{ + if ( !_elementJustOpened ) { + return; + } + _elementJustOpened = false; + Putc( '>' ); +} + + +void XMLPrinter::PushText( const char* text, bool cdata ) +{ + _textDepth = _depth-1; + + SealElementIfJustOpened(); + if ( cdata ) { + Write( "" ); + } + else { + PrintString( text, true ); + } +} + + +void XMLPrinter::PushText( int64_t value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( uint64_t value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(value, buf, BUF_SIZE); + PushText(buf, false); +} + + +void XMLPrinter::PushText( int value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( unsigned value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( bool value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( float value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( double value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushComment( const char* comment ) +{ + PrepareForNewNode( _compactMode ); + + Write( "" ); +} + + +void XMLPrinter::PushDeclaration( const char* value ) +{ + PrepareForNewNode( _compactMode ); + + Write( "" ); +} + + +void XMLPrinter::PushUnknown( const char* value ) +{ + PrepareForNewNode( _compactMode ); + + Write( "' ); +} + + +bool XMLPrinter::VisitEnter( const XMLDocument& doc ) +{ + _processEntities = doc.ProcessEntities(); + if ( doc.HasBOM() ) { + PushHeader( true, false ); + } + return true; +} + + +bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) +{ + const XMLElement* parentElem = 0; + if ( element.Parent() ) { + parentElem = element.Parent()->ToElement(); + } + const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode; + OpenElement( element.Name(), compactMode ); + while ( attribute ) { + PushAttribute( attribute->Name(), attribute->Value() ); + attribute = attribute->Next(); + } + return true; +} + + +bool XMLPrinter::VisitExit( const XMLElement& element ) +{ + CloseElement( CompactMode(element) ); + return true; +} + + +bool XMLPrinter::Visit( const XMLText& text ) +{ + PushText( text.Value(), text.CData() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLComment& comment ) +{ + PushComment( comment.Value() ); + return true; +} + +bool XMLPrinter::Visit( const XMLDeclaration& declaration ) +{ + PushDeclaration( declaration.Value() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLUnknown& unknown ) +{ + PushUnknown( unknown.Value() ); + return true; +} + +} // namespace tinyxml2 diff --git a/tinyxml2.h b/tinyxml2.h new file mode 100644 index 0000000..36f8548 --- /dev/null +++ b/tinyxml2.h @@ -0,0 +1,2380 @@ +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef TINYXML2_INCLUDED +#define TINYXML2_INCLUDED + +#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) +# include +# include +# include +# include +# include +# if defined(__PS3__) +# include +# endif +#else +# include +# include +# include +# include +# include +#endif +#include + +/* + TODO: intern strings instead of allocation. +*/ +/* + gcc: + g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe + + Formatting, Artistic Style: + AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h +*/ + +#if defined( _DEBUG ) || defined (__DEBUG__) +# ifndef TINYXML2_DEBUG +# define TINYXML2_DEBUG +# endif +#endif + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4251) +#endif + +#ifdef _WIN32 +# ifdef TINYXML2_EXPORT +# define TINYXML2_LIB __declspec(dllexport) +# elif defined(TINYXML2_IMPORT) +# define TINYXML2_LIB __declspec(dllimport) +# else +# define TINYXML2_LIB +# endif +#elif __GNUC__ >= 4 +# define TINYXML2_LIB __attribute__((visibility("default"))) +#else +# define TINYXML2_LIB +#endif + + +#if !defined(TIXMLASSERT) +#if defined(TINYXML2_DEBUG) +# if defined(_MSC_VER) +# // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like +# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } +# elif defined (ANDROID_NDK) +# include +# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } +# else +# include +# define TIXMLASSERT assert +# endif +#else +# define TIXMLASSERT( x ) {} +#endif +#endif + +/* Versioning, past 1.0.14: + http://semver.org/ +*/ +static const int TIXML2_MAJOR_VERSION = 9; +static const int TIXML2_MINOR_VERSION = 0; +static const int TIXML2_PATCH_VERSION = 0; + +#define TINYXML2_MAJOR_VERSION 9 +#define TINYXML2_MINOR_VERSION 0 +#define TINYXML2_PATCH_VERSION 0 + +// A fixed element depth limit is problematic. There needs to be a +// limit to avoid a stack overflow. However, that limit varies per +// system, and the capacity of the stack. On the other hand, it's a trivial +// attack that can result from ill, malicious, or even correctly formed XML, +// so there needs to be a limit in place. +static const int TINYXML2_MAX_ELEMENT_DEPTH = 100; + +namespace tinyxml2 +{ +class XMLDocument; +class XMLElement; +class XMLAttribute; +class XMLComment; +class XMLText; +class XMLDeclaration; +class XMLUnknown; +class XMLPrinter; + +/* + A class that wraps strings. Normally stores the start and end + pointers into the XML file itself, and will apply normalization + and entity translation if actually read. Can also store (and memory + manage) a traditional char[] + + Isn't clear why TINYXML2_LIB is needed; but seems to fix #719 +*/ +class TINYXML2_LIB StrPair +{ +public: + enum Mode { + NEEDS_ENTITY_PROCESSING = 0x01, + NEEDS_NEWLINE_NORMALIZATION = 0x02, + NEEDS_WHITESPACE_COLLAPSING = 0x04, + + TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_NAME = 0, + ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + COMMENT = NEEDS_NEWLINE_NORMALIZATION + }; + + StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} + ~StrPair(); + + void Set( char* start, char* end, int flags ) { + TIXMLASSERT( start ); + TIXMLASSERT( end ); + Reset(); + _start = start; + _end = end; + _flags = flags | NEEDS_FLUSH; + } + + const char* GetStr(); + + bool Empty() const { + return _start == _end; + } + + void SetInternedStr( const char* str ) { + Reset(); + _start = const_cast(str); + } + + void SetStr( const char* str, int flags=0 ); + + char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr ); + char* ParseName( char* in ); + + void TransferTo( StrPair* other ); + void Reset(); + +private: + void CollapseWhitespace(); + + enum { + NEEDS_FLUSH = 0x100, + NEEDS_DELETE = 0x200 + }; + + int _flags; + char* _start; + char* _end; + + StrPair( const StrPair& other ); // not supported + void operator=( const StrPair& other ); // not supported, use TransferTo() +}; + + +/* + A dynamic array of Plain Old Data. Doesn't support constructors, etc. + Has a small initial memory pool, so that low or no usage will not + cause a call to new/delete +*/ +template +class DynArray +{ +public: + DynArray() : + _mem( _pool ), + _allocated( INITIAL_SIZE ), + _size( 0 ) + { + } + + ~DynArray() { + if ( _mem != _pool ) { + delete [] _mem; + } + } + + void Clear() { + _size = 0; + } + + void Push( T t ) { + TIXMLASSERT( _size < INT_MAX ); + EnsureCapacity( _size+1 ); + _mem[_size] = t; + ++_size; + } + + T* PushArr( int count ) { + TIXMLASSERT( count >= 0 ); + TIXMLASSERT( _size <= INT_MAX - count ); + EnsureCapacity( _size+count ); + T* ret = &_mem[_size]; + _size += count; + return ret; + } + + T Pop() { + TIXMLASSERT( _size > 0 ); + --_size; + return _mem[_size]; + } + + void PopArr( int count ) { + TIXMLASSERT( _size >= count ); + _size -= count; + } + + bool Empty() const { + return _size == 0; + } + + T& operator[](int i) { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + const T& operator[](int i) const { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + const T& PeekTop() const { + TIXMLASSERT( _size > 0 ); + return _mem[ _size - 1]; + } + + int Size() const { + TIXMLASSERT( _size >= 0 ); + return _size; + } + + int Capacity() const { + TIXMLASSERT( _allocated >= INITIAL_SIZE ); + return _allocated; + } + + void SwapRemove(int i) { + TIXMLASSERT(i >= 0 && i < _size); + TIXMLASSERT(_size > 0); + _mem[i] = _mem[_size - 1]; + --_size; + } + + const T* Mem() const { + TIXMLASSERT( _mem ); + return _mem; + } + + T* Mem() { + TIXMLASSERT( _mem ); + return _mem; + } + +private: + DynArray( const DynArray& ); // not supported + void operator=( const DynArray& ); // not supported + + void EnsureCapacity( int cap ) { + TIXMLASSERT( cap > 0 ); + if ( cap > _allocated ) { + TIXMLASSERT( cap <= INT_MAX / 2 ); + const int newAllocated = cap * 2; + T* newMem = new T[newAllocated]; + TIXMLASSERT( newAllocated >= _size ); + memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs + if ( _mem != _pool ) { + delete [] _mem; + } + _mem = newMem; + _allocated = newAllocated; + } + } + + T* _mem; + T _pool[INITIAL_SIZE]; + int _allocated; // objects allocated + int _size; // number objects in use +}; + + +/* + Parent virtual class of a pool for fast allocation + and deallocation of objects. +*/ +class MemPool +{ +public: + MemPool() {} + virtual ~MemPool() {} + + virtual int ItemSize() const = 0; + virtual void* Alloc() = 0; + virtual void Free( void* ) = 0; + virtual void SetTracked() = 0; +}; + + +/* + Template child class to create pools of the correct type. +*/ +template< int ITEM_SIZE > +class MemPoolT : public MemPool +{ +public: + MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} + ~MemPoolT() { + MemPoolT< ITEM_SIZE >::Clear(); + } + + void Clear() { + // Delete the blocks. + while( !_blockPtrs.Empty()) { + Block* lastBlock = _blockPtrs.Pop(); + delete lastBlock; + } + _root = 0; + _currentAllocs = 0; + _nAllocs = 0; + _maxAllocs = 0; + _nUntracked = 0; + } + + virtual int ItemSize() const { + return ITEM_SIZE; + } + int CurrentAllocs() const { + return _currentAllocs; + } + + virtual void* Alloc() { + if ( !_root ) { + // Need a new block. + Block* block = new Block(); + _blockPtrs.Push( block ); + + Item* blockItems = block->items; + for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) { + blockItems[i].next = &(blockItems[i + 1]); + } + blockItems[ITEMS_PER_BLOCK - 1].next = 0; + _root = blockItems; + } + Item* const result = _root; + TIXMLASSERT( result != 0 ); + _root = _root->next; + + ++_currentAllocs; + if ( _currentAllocs > _maxAllocs ) { + _maxAllocs = _currentAllocs; + } + ++_nAllocs; + ++_nUntracked; + return result; + } + + virtual void Free( void* mem ) { + if ( !mem ) { + return; + } + --_currentAllocs; + Item* item = static_cast( mem ); +#ifdef TINYXML2_DEBUG + memset( item, 0xfe, sizeof( *item ) ); +#endif + item->next = _root; + _root = item; + } + void Trace( const char* name ) { + printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", + name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, + ITEM_SIZE, _nAllocs, _blockPtrs.Size() ); + } + + void SetTracked() { + --_nUntracked; + } + + int Untracked() const { + return _nUntracked; + } + + // This number is perf sensitive. 4k seems like a good tradeoff on my machine. + // The test file is large, 170k. + // Release: VS2010 gcc(no opt) + // 1k: 4000 + // 2k: 4000 + // 4k: 3900 21000 + // 16k: 5200 + // 32k: 4300 + // 64k: 4000 21000 + // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK + // in private part if ITEMS_PER_BLOCK is private + enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE }; + +private: + MemPoolT( const MemPoolT& ); // not supported + void operator=( const MemPoolT& ); // not supported + + union Item { + Item* next; + char itemData[ITEM_SIZE]; + }; + struct Block { + Item items[ITEMS_PER_BLOCK]; + }; + DynArray< Block*, 10 > _blockPtrs; + Item* _root; + + int _currentAllocs; + int _nAllocs; + int _maxAllocs; + int _nUntracked; +}; + + + +/** + Implements the interface to the "Visitor pattern" (see the Accept() method.) + If you call the Accept() method, it requires being passed a XMLVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs + are simply called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its siblings will be visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the XMLDocument, although all nodes support visiting. + + You should never change the document from a callback. + + @sa XMLNode::Accept() +*/ +class TINYXML2_LIB XMLVisitor +{ +public: + virtual ~XMLVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { + return true; + } + /// Visit a document. + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + /// Visit an element. + virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { + return true; + } + /// Visit an element. + virtual bool VisitExit( const XMLElement& /*element*/ ) { + return true; + } + + /// Visit a declaration. + virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { + return true; + } + /// Visit a text node. + virtual bool Visit( const XMLText& /*text*/ ) { + return true; + } + /// Visit a comment node. + virtual bool Visit( const XMLComment& /*comment*/ ) { + return true; + } + /// Visit an unknown node. + virtual bool Visit( const XMLUnknown& /*unknown*/ ) { + return true; + } +}; + +// WARNING: must match XMLDocument::_errorNames[] +enum XMLError { + XML_SUCCESS = 0, + XML_NO_ATTRIBUTE, + XML_WRONG_ATTRIBUTE_TYPE, + XML_ERROR_FILE_NOT_FOUND, + XML_ERROR_FILE_COULD_NOT_BE_OPENED, + XML_ERROR_FILE_READ_ERROR, + XML_ERROR_PARSING_ELEMENT, + XML_ERROR_PARSING_ATTRIBUTE, + XML_ERROR_PARSING_TEXT, + XML_ERROR_PARSING_CDATA, + XML_ERROR_PARSING_COMMENT, + XML_ERROR_PARSING_DECLARATION, + XML_ERROR_PARSING_UNKNOWN, + XML_ERROR_EMPTY_DOCUMENT, + XML_ERROR_MISMATCHED_ELEMENT, + XML_ERROR_PARSING, + XML_CAN_NOT_CONVERT_TEXT, + XML_NO_TEXT_NODE, + XML_ELEMENT_DEPTH_EXCEEDED, + + XML_ERROR_COUNT +}; + + +/* + Utility functionality. +*/ +class TINYXML2_LIB XMLUtil +{ +public: + static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) { + TIXMLASSERT( p ); + + while( IsWhiteSpace(*p) ) { + if (curLineNumPtr && *p == '\n') { + ++(*curLineNumPtr); + } + ++p; + } + TIXMLASSERT( p ); + return p; + } + static char* SkipWhiteSpace( char* const p, int* curLineNumPtr ) { + return const_cast( SkipWhiteSpace( const_cast(p), curLineNumPtr ) ); + } + + // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't + // correct, but simple, and usually works. + static bool IsWhiteSpace( char p ) { + return !IsUTF8Continuation(p) && isspace( static_cast(p) ); + } + + inline static bool IsNameStartChar( unsigned char ch ) { + if ( ch >= 128 ) { + // This is a heuristic guess in attempt to not implement Unicode-aware isalpha() + return true; + } + if ( isalpha( ch ) ) { + return true; + } + return ch == ':' || ch == '_'; + } + + inline static bool IsNameChar( unsigned char ch ) { + return IsNameStartChar( ch ) + || isdigit( ch ) + || ch == '.' + || ch == '-'; + } + + inline static bool IsPrefixHex( const char* p) { + p = SkipWhiteSpace(p, 0); + return p && *p == '0' && ( *(p + 1) == 'x' || *(p + 1) == 'X'); + } + + inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { + if ( p == q ) { + return true; + } + TIXMLASSERT( p ); + TIXMLASSERT( q ); + TIXMLASSERT( nChar >= 0 ); + return strncmp( p, q, nChar ) == 0; + } + + inline static bool IsUTF8Continuation( const char p ) { + return ( p & 0x80 ) != 0; + } + + static const char* ReadBOM( const char* p, bool* hasBOM ); + // p is the starting location, + // the UTF-8 value of the entity will be placed in value, and length filled in. + static const char* GetCharacterRef( const char* p, char* value, int* length ); + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + + // converts primitive types to strings + static void ToStr( int v, char* buffer, int bufferSize ); + static void ToStr( unsigned v, char* buffer, int bufferSize ); + static void ToStr( bool v, char* buffer, int bufferSize ); + static void ToStr( float v, char* buffer, int bufferSize ); + static void ToStr( double v, char* buffer, int bufferSize ); + static void ToStr(int64_t v, char* buffer, int bufferSize); + static void ToStr(uint64_t v, char* buffer, int bufferSize); + + // converts strings to primitive types + static bool ToInt( const char* str, int* value ); + static bool ToUnsigned( const char* str, unsigned* value ); + static bool ToBool( const char* str, bool* value ); + static bool ToFloat( const char* str, float* value ); + static bool ToDouble( const char* str, double* value ); + static bool ToInt64(const char* str, int64_t* value); + static bool ToUnsigned64(const char* str, uint64_t* value); + // Changes what is serialized for a boolean value. + // Default to "true" and "false". Shouldn't be changed + // unless you have a special testing or compatibility need. + // Be careful: static, global, & not thread safe. + // Be sure to set static const memory as parameters. + static void SetBoolSerialization(const char* writeTrue, const char* writeFalse); + +private: + static const char* writeBoolTrue; + static const char* writeBoolFalse; +}; + + +/** XMLNode is a base class for every object that is in the + XML Document Object Model (DOM), except XMLAttributes. + Nodes have siblings, a parent, and children which can + be navigated. A node is always in a XMLDocument. + The type of a XMLNode can be queried, and it can + be cast to its more defined type. + + A XMLDocument allocates memory for all its Nodes. + When the XMLDocument gets deleted, all its Nodes + will also be deleted. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + @endverbatim +*/ +class TINYXML2_LIB XMLNode +{ + friend class XMLDocument; + friend class XMLElement; +public: + + /// Get the XMLDocument that owns this XMLNode. + const XMLDocument* GetDocument() const { + TIXMLASSERT( _document ); + return _document; + } + /// Get the XMLDocument that owns this XMLNode. + XMLDocument* GetDocument() { + TIXMLASSERT( _document ); + return _document; + } + + /// Safely cast to an Element, or null. + virtual XMLElement* ToElement() { + return 0; + } + /// Safely cast to Text, or null. + virtual XMLText* ToText() { + return 0; + } + /// Safely cast to a Comment, or null. + virtual XMLComment* ToComment() { + return 0; + } + /// Safely cast to a Document, or null. + virtual XMLDocument* ToDocument() { + return 0; + } + /// Safely cast to a Declaration, or null. + virtual XMLDeclaration* ToDeclaration() { + return 0; + } + /// Safely cast to an Unknown, or null. + virtual XMLUnknown* ToUnknown() { + return 0; + } + + virtual const XMLElement* ToElement() const { + return 0; + } + virtual const XMLText* ToText() const { + return 0; + } + virtual const XMLComment* ToComment() const { + return 0; + } + virtual const XMLDocument* ToDocument() const { + return 0; + } + virtual const XMLDeclaration* ToDeclaration() const { + return 0; + } + virtual const XMLUnknown* ToUnknown() const { + return 0; + } + + /** The meaning of 'value' changes for the specific type. + @verbatim + Document: empty (NULL is returned, not an empty string) + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + const char* Value() const; + + /** Set the Value of an XML node. + @sa Value() + */ + void SetValue( const char* val, bool staticMem=false ); + + /// Gets the line number the node is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } + + /// Get the parent of this node on the DOM. + const XMLNode* Parent() const { + return _parent; + } + + XMLNode* Parent() { + return _parent; + } + + /// Returns true if this node has no children. + bool NoChildren() const { + return !_firstChild; + } + + /// Get the first child node, or null if none exists. + const XMLNode* FirstChild() const { + return _firstChild; + } + + XMLNode* FirstChild() { + return _firstChild; + } + + /** Get the first child element, or optionally the first child + element with the specified name. + */ + const XMLElement* FirstChildElement( const char* name = 0 ) const; + + XMLElement* FirstChildElement( const char* name = 0 ) { + return const_cast(const_cast(this)->FirstChildElement( name )); + } + + /// Get the last child node, or null if none exists. + const XMLNode* LastChild() const { + return _lastChild; + } + + XMLNode* LastChild() { + return _lastChild; + } + + /** Get the last child element or optionally the last child + element with the specified name. + */ + const XMLElement* LastChildElement( const char* name = 0 ) const; + + XMLElement* LastChildElement( const char* name = 0 ) { + return const_cast(const_cast(this)->LastChildElement(name) ); + } + + /// Get the previous (left) sibling node of this node. + const XMLNode* PreviousSibling() const { + return _prev; + } + + XMLNode* PreviousSibling() { + return _prev; + } + + /// Get the previous (left) sibling element of this node, with an optionally supplied name. + const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ; + + XMLElement* PreviousSiblingElement( const char* name = 0 ) { + return const_cast(const_cast(this)->PreviousSiblingElement( name ) ); + } + + /// Get the next (right) sibling node of this node. + const XMLNode* NextSibling() const { + return _next; + } + + XMLNode* NextSibling() { + return _next; + } + + /// Get the next (right) sibling element of this node, with an optionally supplied name. + const XMLElement* NextSiblingElement( const char* name = 0 ) const; + + XMLElement* NextSiblingElement( const char* name = 0 ) { + return const_cast(const_cast(this)->NextSiblingElement( name ) ); + } + + /** + Add a child node as the last (right) child. + If the child node is already part of the document, + it is moved from its old location to the new location. + Returns the addThis argument or 0 if the node does not + belong to the same document. + */ + XMLNode* InsertEndChild( XMLNode* addThis ); + + XMLNode* LinkEndChild( XMLNode* addThis ) { + return InsertEndChild( addThis ); + } + /** + Add a child node as the first (left) child. + If the child node is already part of the document, + it is moved from its old location to the new location. + Returns the addThis argument or 0 if the node does not + belong to the same document. + */ + XMLNode* InsertFirstChild( XMLNode* addThis ); + /** + Add a node after the specified child node. + If the child node is already part of the document, + it is moved from its old location to the new location. + Returns the addThis argument or 0 if the afterThis node + is not a child of this node, or if the node does not + belong to the same document. + */ + XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); + + /** + Delete all the children of this node. + */ + void DeleteChildren(); + + /** + Delete a child of this node. + */ + void DeleteChild( XMLNode* node ); + + /** + Make a copy of this node, but not its children. + You may pass in a Document pointer that will be + the owner of the new Node. If the 'document' is + null, then the node returned will be allocated + from the current Document. (this->GetDocument()) + + Note: if called on a XMLDocument, this will return null. + */ + virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; + + /** + Make a copy of this node and all its children. + + If the 'target' is null, then the nodes will + be allocated in the current document. If 'target' + is specified, the memory will be allocated is the + specified XMLDocument. + + NOTE: This is probably not the correct tool to + copy a document, since XMLDocuments can have multiple + top level XMLNodes. You probably want to use + XMLDocument::DeepCopy() + */ + XMLNode* DeepClone( XMLDocument* target ) const; + + /** + Test if 2 nodes are the same, but don't test children. + The 2 nodes do not need to be in the same Document. + + Note: if called on a XMLDocument, this will return false. + */ + virtual bool ShallowEqual( const XMLNode* compare ) const = 0; + + /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the XMLVisitor interface. + + This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + XMLPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( XMLVisitor* visitor ) const = 0; + + /** + Set user data into the XMLNode. TinyXML-2 in + no way processes or interprets user data. + It is initially 0. + */ + void SetUserData(void* userData) { _userData = userData; } + + /** + Get user data set into the XMLNode. TinyXML-2 in + no way processes or interprets user data. + It is initially 0. + */ + void* GetUserData() const { return _userData; } + +protected: + explicit XMLNode( XMLDocument* ); + virtual ~XMLNode(); + + virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); + + XMLDocument* _document; + XMLNode* _parent; + mutable StrPair _value; + int _parseLineNum; + + XMLNode* _firstChild; + XMLNode* _lastChild; + + XMLNode* _prev; + XMLNode* _next; + + void* _userData; + +private: + MemPool* _memPool; + void Unlink( XMLNode* child ); + static void DeleteNode( XMLNode* node ); + void InsertChildPreamble( XMLNode* insertThis ) const; + const XMLElement* ToElementWithName( const char* name ) const; + + XMLNode( const XMLNode& ); // not supported + XMLNode& operator=( const XMLNode& ); // not supported +}; + + +/** XML text. + + Note that a text node can have child element nodes, for example: + @verbatim + This is bold + @endverbatim + + A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCData() and query it with CData(). +*/ +class TINYXML2_LIB XMLText : public XMLNode +{ + friend class XMLDocument; +public: + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLText* ToText() { + return this; + } + virtual const XMLText* ToText() const { + return this; + } + + /// Declare whether this should be CDATA or standard text. + void SetCData( bool isCData ) { + _isCData = isCData; + } + /// Returns true if this is a CDATA text element. + bool CData() const { + return _isCData; + } + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} + virtual ~XMLText() {} + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + bool _isCData; + + XMLText( const XMLText& ); // not supported + XMLText& operator=( const XMLText& ); // not supported +}; + + +/** An XML Comment. */ +class TINYXML2_LIB XMLComment : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLComment* ToComment() { + return this; + } + virtual const XMLComment* ToComment() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + explicit XMLComment( XMLDocument* doc ); + virtual ~XMLComment(); + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); + +private: + XMLComment( const XMLComment& ); // not supported + XMLComment& operator=( const XMLComment& ); // not supported +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXML-2 will happily read or write files without a declaration, + however. + + The text of the declaration isn't interpreted. It is parsed + and written as a string. +*/ +class TINYXML2_LIB XMLDeclaration : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLDeclaration* ToDeclaration() { + return this; + } + virtual const XMLDeclaration* ToDeclaration() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + explicit XMLDeclaration( XMLDocument* doc ); + virtual ~XMLDeclaration(); + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + XMLDeclaration( const XMLDeclaration& ); // not supported + XMLDeclaration& operator=( const XMLDeclaration& ); // not supported +}; + + +/** Any tag that TinyXML-2 doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into XMLUnknowns. +*/ +class TINYXML2_LIB XMLUnknown : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLUnknown* ToUnknown() { + return this; + } + virtual const XMLUnknown* ToUnknown() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + explicit XMLUnknown( XMLDocument* doc ); + virtual ~XMLUnknown(); + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + XMLUnknown( const XMLUnknown& ); // not supported + XMLUnknown& operator=( const XMLUnknown& ); // not supported +}; + + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not XMLNodes. You may only query the + Next() attribute in a list. +*/ +class TINYXML2_LIB XMLAttribute +{ + friend class XMLElement; +public: + /// The name of the attribute. + const char* Name() const; + + /// The value of the attribute. + const char* Value() const; + + /// Gets the line number the attribute is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } + + /// The next attribute in the list. + const XMLAttribute* Next() const { + return _next; + } + + /** IntValue interprets the attribute as an integer, and returns the value. + If the value isn't an integer, 0 will be returned. There is no error checking; + use QueryIntValue() if you need error checking. + */ + int IntValue() const { + int i = 0; + QueryIntValue(&i); + return i; + } + + int64_t Int64Value() const { + int64_t i = 0; + QueryInt64Value(&i); + return i; + } + + uint64_t Unsigned64Value() const { + uint64_t i = 0; + QueryUnsigned64Value(&i); + return i; + } + + /// Query as an unsigned integer. See IntValue() + unsigned UnsignedValue() const { + unsigned i=0; + QueryUnsignedValue( &i ); + return i; + } + /// Query as a boolean. See IntValue() + bool BoolValue() const { + bool b=false; + QueryBoolValue( &b ); + return b; + } + /// Query as a double. See IntValue() + double DoubleValue() const { + double d=0; + QueryDoubleValue( &d ); + return d; + } + /// Query as a float. See IntValue() + float FloatValue() const { + float f=0; + QueryFloatValue( &f ); + return f; + } + + /** QueryIntValue interprets the attribute as an integer, and returns the value + in the provided parameter. The function will return XML_SUCCESS on success, + and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. + */ + XMLError QueryIntValue( int* value ) const; + /// See QueryIntValue + XMLError QueryUnsignedValue( unsigned int* value ) const; + /// See QueryIntValue + XMLError QueryInt64Value(int64_t* value) const; + /// See QueryIntValue + XMLError QueryUnsigned64Value(uint64_t* value) const; + /// See QueryIntValue + XMLError QueryBoolValue( bool* value ) const; + /// See QueryIntValue + XMLError QueryDoubleValue( double* value ) const; + /// See QueryIntValue + XMLError QueryFloatValue( float* value ) const; + + /// Set the attribute to a string value. + void SetAttribute( const char* value ); + /// Set the attribute to value. + void SetAttribute( int value ); + /// Set the attribute to value. + void SetAttribute( unsigned value ); + /// Set the attribute to value. + void SetAttribute(int64_t value); + /// Set the attribute to value. + void SetAttribute(uint64_t value); + /// Set the attribute to value. + void SetAttribute( bool value ); + /// Set the attribute to value. + void SetAttribute( double value ); + /// Set the attribute to value. + void SetAttribute( float value ); + +private: + enum { BUF_SIZE = 200 }; + + XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {} + virtual ~XMLAttribute() {} + + XMLAttribute( const XMLAttribute& ); // not supported + void operator=( const XMLAttribute& ); // not supported + void SetName( const char* name ); + + char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr ); + + mutable StrPair _name; + mutable StrPair _value; + int _parseLineNum; + XMLAttribute* _next; + MemPool* _memPool; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TINYXML2_LIB XMLElement : public XMLNode +{ + friend class XMLDocument; +public: + /// Get the name of an element (which is the Value() of the node.) + const char* Name() const { + return Value(); + } + /// Set the name of the element. + void SetName( const char* str, bool staticMem=false ) { + SetValue( str, staticMem ); + } + + virtual XMLElement* ToElement() { + return this; + } + virtual const XMLElement* ToElement() const { + return this; + } + virtual bool Accept( XMLVisitor* visitor ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none + exists. For example: + + @verbatim + const char* value = ele->Attribute( "foo" ); + @endverbatim + + The 'value' parameter is normally null. However, if specified, + the attribute will only be returned if the 'name' and 'value' + match. This allow you to write code: + + @verbatim + if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); + @endverbatim + + rather than: + @verbatim + if ( ele->Attribute( "foo" ) ) { + if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); + } + @endverbatim + */ + const char* Attribute( const char* name, const char* value=0 ) const; + + /** Given an attribute name, IntAttribute() returns the value + of the attribute interpreted as an integer. The default + value will be returned if the attribute isn't present, + or if there is an error. (For a method with error + checking, see QueryIntAttribute()). + */ + int IntAttribute(const char* name, int defaultValue = 0) const; + /// See IntAttribute() + unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const; + /// See IntAttribute() + int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const; + /// See IntAttribute() + uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const; + /// See IntAttribute() + bool BoolAttribute(const char* name, bool defaultValue = false) const; + /// See IntAttribute() + double DoubleAttribute(const char* name, double defaultValue = 0) const; + /// See IntAttribute() + float FloatAttribute(const char* name, float defaultValue = 0) const; + + /** Given an attribute name, QueryIntAttribute() returns + XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion + can't be performed, or XML_NO_ATTRIBUTE if the attribute + doesn't exist. If successful, the result of the conversion + will be written to 'value'. If not successful, nothing will + be written to 'value'. This allows you to provide default + value: + + @verbatim + int value = 10; + QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 + @endverbatim + */ + XMLError QueryIntAttribute( const char* name, int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryIntValue( value ); + } + + /// See QueryIntAttribute() + XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryUnsignedValue( value ); + } + + /// See QueryIntAttribute() + XMLError QueryInt64Attribute(const char* name, int64_t* value) const { + const XMLAttribute* a = FindAttribute(name); + if (!a) { + return XML_NO_ATTRIBUTE; + } + return a->QueryInt64Value(value); + } + + /// See QueryIntAttribute() + XMLError QueryUnsigned64Attribute(const char* name, uint64_t* value) const { + const XMLAttribute* a = FindAttribute(name); + if(!a) { + return XML_NO_ATTRIBUTE; + } + return a->QueryUnsigned64Value(value); + } + + /// See QueryIntAttribute() + XMLError QueryBoolAttribute( const char* name, bool* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryBoolValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryDoubleAttribute( const char* name, double* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryDoubleValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryFloatAttribute( const char* name, float* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryFloatValue( value ); + } + + /// See QueryIntAttribute() + XMLError QueryStringAttribute(const char* name, const char** value) const { + const XMLAttribute* a = FindAttribute(name); + if (!a) { + return XML_NO_ATTRIBUTE; + } + *value = a->Value(); + return XML_SUCCESS; + } + + + + /** Given an attribute name, QueryAttribute() returns + XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion + can't be performed, or XML_NO_ATTRIBUTE if the attribute + doesn't exist. It is overloaded for the primitive types, + and is a generally more convenient replacement of + QueryIntAttribute() and related functions. + + If successful, the result of the conversion + will be written to 'value'. If not successful, nothing will + be written to 'value'. This allows you to provide default + value: + + @verbatim + int value = 10; + QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 + @endverbatim + */ + XMLError QueryAttribute( const char* name, int* value ) const { + return QueryIntAttribute( name, value ); + } + + XMLError QueryAttribute( const char* name, unsigned int* value ) const { + return QueryUnsignedAttribute( name, value ); + } + + XMLError QueryAttribute(const char* name, int64_t* value) const { + return QueryInt64Attribute(name, value); + } + + XMLError QueryAttribute(const char* name, uint64_t* value) const { + return QueryUnsigned64Attribute(name, value); + } + + XMLError QueryAttribute( const char* name, bool* value ) const { + return QueryBoolAttribute( name, value ); + } + + XMLError QueryAttribute( const char* name, double* value ) const { + return QueryDoubleAttribute( name, value ); + } + + XMLError QueryAttribute( const char* name, float* value ) const { + return QueryFloatAttribute( name, value ); + } + + XMLError QueryAttribute(const char* name, const char** value) const { + return QueryStringAttribute(name, value); + } + + /// Sets the named attribute to value. + void SetAttribute( const char* name, const char* value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, int value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, unsigned value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + + /// Sets the named attribute to value. + void SetAttribute(const char* name, int64_t value) { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + + /// Sets the named attribute to value. + void SetAttribute(const char* name, uint64_t value) { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + + /// Sets the named attribute to value. + void SetAttribute( const char* name, bool value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, double value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, float value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + + /** + Delete an attribute. + */ + void DeleteAttribute( const char* name ); + + /// Return the first attribute in the list. + const XMLAttribute* FirstAttribute() const { + return _rootAttribute; + } + /// Query a specific attribute in the list. + const XMLAttribute* FindAttribute( const char* name ) const; + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the XMLText child + and accessing it directly. + + If the first child of 'this' is a XMLText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + */ + const char* GetText() const; + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, SetText() is limited compared to creating an XMLText child + and mutating it directly. + + If the first child of 'this' is a XMLText, SetText() sets its value to + the given string, otherwise it will create a first child that is an XMLText. + + This is a convenient method for setting the text of simple contained text: + @verbatim + This is text + fooElement->SetText( "Hullaballoo!" ); + Hullaballoo! + @endverbatim + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then it will not change "This is text", but rather prefix it with a text element: + @verbatim + Hullaballoo!This is text + @endverbatim + + For this XML: + @verbatim + + @endverbatim + SetText() will generate + @verbatim + Hullaballoo! + @endverbatim + */ + void SetText( const char* inText ); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText( int value ); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText( unsigned value ); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(int64_t value); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(uint64_t value); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText( bool value ); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText( double value ); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText( float value ); + + /** + Convenience method to query the value of a child text node. This is probably best + shown by example. Given you have a document is this form: + @verbatim + + 1 + 1.4 + + @endverbatim + + The QueryIntText() and similar functions provide a safe and easier way to get to the + "value" of x and y. + + @verbatim + int x = 0; + float y = 0; // types of x and y are contrived for example + const XMLElement* xElement = pointElement->FirstChildElement( "x" ); + const XMLElement* yElement = pointElement->FirstChildElement( "y" ); + xElement->QueryIntText( &x ); + yElement->QueryFloatText( &y ); + @endverbatim + + @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted + to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. + + */ + XMLError QueryIntText( int* ival ) const; + /// See QueryIntText() + XMLError QueryUnsignedText( unsigned* uval ) const; + /// See QueryIntText() + XMLError QueryInt64Text(int64_t* uval) const; + /// See QueryIntText() + XMLError QueryUnsigned64Text(uint64_t* uval) const; + /// See QueryIntText() + XMLError QueryBoolText( bool* bval ) const; + /// See QueryIntText() + XMLError QueryDoubleText( double* dval ) const; + /// See QueryIntText() + XMLError QueryFloatText( float* fval ) const; + + int IntText(int defaultValue = 0) const; + + /// See QueryIntText() + unsigned UnsignedText(unsigned defaultValue = 0) const; + /// See QueryIntText() + int64_t Int64Text(int64_t defaultValue = 0) const; + /// See QueryIntText() + uint64_t Unsigned64Text(uint64_t defaultValue = 0) const; + /// See QueryIntText() + bool BoolText(bool defaultValue = false) const; + /// See QueryIntText() + double DoubleText(double defaultValue = 0) const; + /// See QueryIntText() + float FloatText(float defaultValue = 0) const; + + /** + Convenience method to create a new XMLElement and add it as last (right) + child of this node. Returns the created and inserted element. + */ + XMLElement* InsertNewChildElement(const char* name); + /// See InsertNewChildElement() + XMLComment* InsertNewComment(const char* comment); + /// See InsertNewChildElement() + XMLText* InsertNewText(const char* text); + /// See InsertNewChildElement() + XMLDeclaration* InsertNewDeclaration(const char* text); + /// See InsertNewChildElement() + XMLUnknown* InsertNewUnknown(const char* text); + + + // internal: + enum ElementClosingType { + OPEN, // + CLOSED, // + CLOSING // + }; + ElementClosingType ClosingType() const { + return _closingType; + } + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + XMLElement( XMLDocument* doc ); + virtual ~XMLElement(); + XMLElement( const XMLElement& ); // not supported + void operator=( const XMLElement& ); // not supported + + XMLAttribute* FindOrCreateAttribute( const char* name ); + char* ParseAttributes( char* p, int* curLineNumPtr ); + static void DeleteAttribute( XMLAttribute* attribute ); + XMLAttribute* CreateAttribute(); + + enum { BUF_SIZE = 200 }; + ElementClosingType _closingType; + // The attribute list is ordered; there is no 'lastAttribute' + // because the list needs to be scanned for dupes before adding + // a new attribute. + XMLAttribute* _rootAttribute; +}; + + +enum Whitespace { + PRESERVE_WHITESPACE, + COLLAPSE_WHITESPACE +}; + + +/** A Document binds together all the functionality. + It can be saved, loaded, and printed to the screen. + All Nodes are connected and allocated to a Document. + If the Document is deleted, all its Nodes are also deleted. +*/ +class TINYXML2_LIB XMLDocument : public XMLNode +{ + friend class XMLElement; + // Gives access to SetError and Push/PopDepth, but over-access for everything else. + // Wishing C++ had "internal" scope. + friend class XMLNode; + friend class XMLText; + friend class XMLComment; + friend class XMLDeclaration; + friend class XMLUnknown; +public: + /// constructor + XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE ); + ~XMLDocument(); + + virtual XMLDocument* ToDocument() { + TIXMLASSERT( this == _document ); + return this; + } + virtual const XMLDocument* ToDocument() const { + TIXMLASSERT( this == _document ); + return this; + } + + /** + Parse an XML file from a character string. + Returns XML_SUCCESS (0) on success, or + an errorID. + + You may optionally pass in the 'nBytes', which is + the number of bytes which will be parsed. If not + specified, TinyXML-2 will assume 'xml' points to a + null terminated string. + */ + XMLError Parse( const char* xml, size_t nBytes=static_cast(-1) ); + + /** + Load an XML file from disk. + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError LoadFile( const char* filename ); + + /** + Load an XML file from disk. You are responsible + for providing and closing the FILE*. + + NOTE: The file should be opened as binary ("rb") + not text in order for TinyXML-2 to correctly + do newline normalization. + + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError LoadFile( FILE* ); + + /** + Save the XML file to disk. + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError SaveFile( const char* filename, bool compact = false ); + + /** + Save the XML file to disk. You are responsible + for providing and closing the FILE*. + + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError SaveFile( FILE* fp, bool compact = false ); + + bool ProcessEntities() const { + return _processEntities; + } + Whitespace WhitespaceMode() const { + return _whitespaceMode; + } + + /** + Returns true if this document has a leading Byte Order Mark of UTF8. + */ + bool HasBOM() const { + return _writeBOM; + } + /** Sets whether to write the BOM when writing the file. + */ + void SetBOM( bool useBOM ) { + _writeBOM = useBOM; + } + + /** Return the root element of DOM. Equivalent to FirstChildElement(). + To get the first node, use FirstChild(). + */ + XMLElement* RootElement() { + return FirstChildElement(); + } + const XMLElement* RootElement() const { + return FirstChildElement(); + } + + /** Print the Document. If the Printer is not provided, it will + print to stdout. If you provide Printer, this can print to a file: + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Or you can use a printer to print to memory: + @verbatim + XMLPrinter printer; + doc.Print( &printer ); + // printer.CStr() has a const char* to the XML + @endverbatim + */ + void Print( XMLPrinter* streamer=0 ) const; + virtual bool Accept( XMLVisitor* visitor ) const; + + /** + Create a new Element associated with + this Document. The memory for the Element + is managed by the Document. + */ + XMLElement* NewElement( const char* name ); + /** + Create a new Comment associated with + this Document. The memory for the Comment + is managed by the Document. + */ + XMLComment* NewComment( const char* comment ); + /** + Create a new Text associated with + this Document. The memory for the Text + is managed by the Document. + */ + XMLText* NewText( const char* text ); + /** + Create a new Declaration associated with + this Document. The memory for the object + is managed by the Document. + + If the 'text' param is null, the standard + declaration is used.: + @verbatim + + @endverbatim + */ + XMLDeclaration* NewDeclaration( const char* text=0 ); + /** + Create a new Unknown associated with + this Document. The memory for the object + is managed by the Document. + */ + XMLUnknown* NewUnknown( const char* text ); + + /** + Delete a node associated with this document. + It will be unlinked from the DOM. + */ + void DeleteNode( XMLNode* node ); + + /// Clears the error flags. + void ClearError(); + + /// Return true if there was an error parsing the document. + bool Error() const { + return _errorID != XML_SUCCESS; + } + /// Return the errorID. + XMLError ErrorID() const { + return _errorID; + } + const char* ErrorName() const; + static const char* ErrorIDToName(XMLError errorID); + + /** Returns a "long form" error description. A hopefully helpful + diagnostic with location, line number, and/or additional info. + */ + const char* ErrorStr() const; + + /// A (trivial) utility function that prints the ErrorStr() to stdout. + void PrintError() const; + + /// Return the line where the error occurred, or zero if unknown. + int ErrorLineNum() const + { + return _errorLineNum; + } + + /// Clear the document, resetting it to the initial state. + void Clear(); + + /** + Copies this document to a target document. + The target will be completely cleared before the copy. + If you want to copy a sub-tree, see XMLNode::DeepClone(). + + NOTE: that the 'target' must be non-null. + */ + void DeepCopy(XMLDocument* target) const; + + // internal + char* Identify( char* p, XMLNode** node ); + + // internal + void MarkInUse(const XMLNode* const); + + virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { + return 0; + } + virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { + return false; + } + +private: + XMLDocument( const XMLDocument& ); // not supported + void operator=( const XMLDocument& ); // not supported + + bool _writeBOM; + bool _processEntities; + XMLError _errorID; + Whitespace _whitespaceMode; + mutable StrPair _errorStr; + int _errorLineNum; + char* _charBuffer; + int _parseCurLineNum; + int _parsingDepth; + // Memory tracking does add some overhead. + // However, the code assumes that you don't + // have a bunch of unlinked nodes around. + // Therefore it takes less memory to track + // in the document vs. a linked list in the XMLNode, + // and the performance is the same. + DynArray _unlinked; + + MemPoolT< sizeof(XMLElement) > _elementPool; + MemPoolT< sizeof(XMLAttribute) > _attributePool; + MemPoolT< sizeof(XMLText) > _textPool; + MemPoolT< sizeof(XMLComment) > _commentPool; + + static const char* _errorNames[XML_ERROR_COUNT]; + + void Parse(); + + void SetError( XMLError error, int lineNum, const char* format, ... ); + + // Something of an obvious security hole, once it was discovered. + // Either an ill-formed XML or an excessively deep one can overflow + // the stack. Track stack depth, and error out if needed. + class DepthTracker { + public: + explicit DepthTracker(XMLDocument * document) { + this->_document = document; + document->PushDepth(); + } + ~DepthTracker() { + _document->PopDepth(); + } + private: + XMLDocument * _document; + }; + void PushDepth(); + void PopDepth(); + + template + NodeType* CreateUnlinkedNode( MemPoolT& pool ); +}; + +template +inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT& pool ) +{ + TIXMLASSERT( sizeof( NodeType ) == PoolElementSize ); + TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() ); + NodeType* returnNode = new (pool.Alloc()) NodeType( this ); + TIXMLASSERT( returnNode ); + returnNode->_memPool = &pool; + + _unlinked.Push(returnNode); + return returnNode; +} + +/** + A XMLHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2 + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + XMLElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + XMLElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + XMLElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + XMLElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. XMLHandle addresses the verbosity + of such code. A XMLHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + XMLHandle docHandle( &document ); + XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + XMLHandle handleCopy = handle; + @endverbatim + + See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. +*/ +class TINYXML2_LIB XMLHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + explicit XMLHandle( XMLNode* node ) : _node( node ) { + } + /// Create a handle from a node. + explicit XMLHandle( XMLNode& node ) : _node( &node ) { + } + /// Copy constructor + XMLHandle( const XMLHandle& ref ) : _node( ref._node ) { + } + /// Assignment + XMLHandle& operator=( const XMLHandle& ref ) { + _node = ref._node; + return *this; + } + + /// Get the first child of this handle. + XMLHandle FirstChild() { + return XMLHandle( _node ? _node->FirstChild() : 0 ); + } + /// Get the first child element of this handle. + XMLHandle FirstChildElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 ); + } + /// Get the last child of this handle. + XMLHandle LastChild() { + return XMLHandle( _node ? _node->LastChild() : 0 ); + } + /// Get the last child element of this handle. + XMLHandle LastChildElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->LastChildElement( name ) : 0 ); + } + /// Get the previous sibling of this handle. + XMLHandle PreviousSibling() { + return XMLHandle( _node ? _node->PreviousSibling() : 0 ); + } + /// Get the previous sibling element of this handle. + XMLHandle PreviousSiblingElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); + } + /// Get the next sibling of this handle. + XMLHandle NextSibling() { + return XMLHandle( _node ? _node->NextSibling() : 0 ); + } + /// Get the next sibling element of this handle. + XMLHandle NextSiblingElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 ); + } + + /// Safe cast to XMLNode. This can return null. + XMLNode* ToNode() { + return _node; + } + /// Safe cast to XMLElement. This can return null. + XMLElement* ToElement() { + return ( _node ? _node->ToElement() : 0 ); + } + /// Safe cast to XMLText. This can return null. + XMLText* ToText() { + return ( _node ? _node->ToText() : 0 ); + } + /// Safe cast to XMLUnknown. This can return null. + XMLUnknown* ToUnknown() { + return ( _node ? _node->ToUnknown() : 0 ); + } + /// Safe cast to XMLDeclaration. This can return null. + XMLDeclaration* ToDeclaration() { + return ( _node ? _node->ToDeclaration() : 0 ); + } + +private: + XMLNode* _node; +}; + + +/** + A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the + same in all regards, except for the 'const' qualifiers. See XMLHandle for API. +*/ +class TINYXML2_LIB XMLConstHandle +{ +public: + explicit XMLConstHandle( const XMLNode* node ) : _node( node ) { + } + explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) { + } + XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) { + } + + XMLConstHandle& operator=( const XMLConstHandle& ref ) { + _node = ref._node; + return *this; + } + + const XMLConstHandle FirstChild() const { + return XMLConstHandle( _node ? _node->FirstChild() : 0 ); + } + const XMLConstHandle FirstChildElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 ); + } + const XMLConstHandle LastChild() const { + return XMLConstHandle( _node ? _node->LastChild() : 0 ); + } + const XMLConstHandle LastChildElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 ); + } + const XMLConstHandle PreviousSibling() const { + return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); + } + const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); + } + const XMLConstHandle NextSibling() const { + return XMLConstHandle( _node ? _node->NextSibling() : 0 ); + } + const XMLConstHandle NextSiblingElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 ); + } + + + const XMLNode* ToNode() const { + return _node; + } + const XMLElement* ToElement() const { + return ( _node ? _node->ToElement() : 0 ); + } + const XMLText* ToText() const { + return ( _node ? _node->ToText() : 0 ); + } + const XMLUnknown* ToUnknown() const { + return ( _node ? _node->ToUnknown() : 0 ); + } + const XMLDeclaration* ToDeclaration() const { + return ( _node ? _node->ToDeclaration() : 0 ); + } + +private: + const XMLNode* _node; +}; + + +/** + Printing functionality. The XMLPrinter gives you more + options than the XMLDocument::Print() method. + + It can: + -# Print to memory. + -# Print to a file you provide. + -# Print XML without a XMLDocument. + + Print to Memory + + @verbatim + XMLPrinter printer; + doc.Print( &printer ); + SomeFunction( printer.CStr() ); + @endverbatim + + Print to a File + + You provide the file pointer. + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Print without a XMLDocument + + When loading, an XML parser is very useful. However, sometimes + when saving, it just gets in the way. The code is often set up + for streaming, and constructing the DOM is just overhead. + + The Printer supports the streaming case. The following code + prints out a trivially simple XML file without ever creating + an XML document. + + @verbatim + XMLPrinter printer( fp ); + printer.OpenElement( "foo" ); + printer.PushAttribute( "foo", "bar" ); + printer.CloseElement(); + @endverbatim +*/ +class TINYXML2_LIB XMLPrinter : public XMLVisitor +{ +public: + /** Construct the printer. If the FILE* is specified, + this will print to the FILE. Else it will print + to memory, and the result is available in CStr(). + If 'compact' is set to true, then output is created + with only required whitespace and newlines. + */ + XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 ); + virtual ~XMLPrinter() {} + + /** If streaming, write the BOM and declaration. */ + void PushHeader( bool writeBOM, bool writeDeclaration ); + /** If streaming, start writing an element. + The element must be closed with CloseElement() + */ + void OpenElement( const char* name, bool compactMode=false ); + /// If streaming, add an attribute to an open element. + void PushAttribute( const char* name, const char* value ); + void PushAttribute( const char* name, int value ); + void PushAttribute( const char* name, unsigned value ); + void PushAttribute( const char* name, int64_t value ); + void PushAttribute( const char* name, uint64_t value ); + void PushAttribute( const char* name, bool value ); + void PushAttribute( const char* name, double value ); + /// If streaming, close the Element. + virtual void CloseElement( bool compactMode=false ); + + /// Add a text node. + void PushText( const char* text, bool cdata=false ); + /// Add a text node from an integer. + void PushText( int value ); + /// Add a text node from an unsigned. + void PushText( unsigned value ); + /// Add a text node from a signed 64bit integer. + void PushText( int64_t value ); + /// Add a text node from an unsigned 64bit integer. + void PushText( uint64_t value ); + /// Add a text node from a bool. + void PushText( bool value ); + /// Add a text node from a float. + void PushText( float value ); + /// Add a text node from a double. + void PushText( double value ); + + /// Add a comment + void PushComment( const char* comment ); + + void PushDeclaration( const char* value ); + void PushUnknown( const char* value ); + + virtual bool VisitEnter( const XMLDocument& /*doc*/ ); + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); + virtual bool VisitExit( const XMLElement& element ); + + virtual bool Visit( const XMLText& text ); + virtual bool Visit( const XMLComment& comment ); + virtual bool Visit( const XMLDeclaration& declaration ); + virtual bool Visit( const XMLUnknown& unknown ); + + /** + If in print to memory mode, return a pointer to + the XML file in memory. + */ + const char* CStr() const { + return _buffer.Mem(); + } + /** + If in print to memory mode, return the size + of the XML file in memory. (Note the size returned + includes the terminating null.) + */ + int CStrSize() const { + return _buffer.Size(); + } + /** + If in print to memory mode, reset the buffer to the + beginning. + */ + void ClearBuffer( bool resetToFirstElement = true ) { + _buffer.Clear(); + _buffer.Push(0); + _firstElement = resetToFirstElement; + } + +protected: + virtual bool CompactMode( const XMLElement& ) { return _compactMode; } + + /** Prints out the space before an element. You may override to change + the space and tabs used. A PrintSpace() override should call Print(). + */ + virtual void PrintSpace( int depth ); + virtual void Print( const char* format, ... ); + virtual void Write( const char* data, size_t size ); + virtual void Putc( char ch ); + + inline void Write(const char* data) { Write(data, strlen(data)); } + + void SealElementIfJustOpened(); + bool _elementJustOpened; + DynArray< const char*, 10 > _stack; + +private: + /** + Prepares to write a new node. This includes sealing an element that was + just opened, and writing any whitespace necessary if not in compact mode. + */ + void PrepareForNewNode( bool compactMode ); + void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. + + bool _firstElement; + FILE* _fp; + int _depth; + int _textDepth; + bool _processEntities; + bool _compactMode; + + enum { + ENTITY_RANGE = 64, + BUF_SIZE = 200 + }; + bool _entityFlag[ENTITY_RANGE]; + bool _restrictedEntityFlag[ENTITY_RANGE]; + + DynArray< char, 20 > _buffer; + + // Prohibit cloning, intentionally not implemented + XMLPrinter( const XMLPrinter& ); + XMLPrinter& operator=( const XMLPrinter& ); +}; + + +} // tinyxml2 + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // TINYXML2_INCLUDED diff --git a/vs_generate.cpp b/vs_generate.cpp new file mode 100644 index 0000000..88362ae --- /dev/null +++ b/vs_generate.cpp @@ -0,0 +1,200 @@ + +#include "vs_generate.h" + +#include +#include +#include +#include + +VsParseSln::VsParseSln() = default; + +// 解析关联 +void VsParseSln::parse_relate() { + for (auto& proj : projs_) { + for (auto& relate : proj.guid_relate_) { + std::string opth = hashmap_[relate]; + proj.relate_.push_back(opth); + } + } +} + +bool VsParseSln::parse(const std::string& path) { + std::ifstream sln_file(path, std::ios::in); + if (!sln_file.is_open()) { + std::cout << "没有找到 sln 文件或者打开文件失败,路径:" << path + << "\n"; + return false; + } + fs::path full_path(path); + fs::path parent_path = full_path.parent_path(); + + projs_.clear(); + std::string tmp{}; + std::regex re(R"(\"(.*?)\")"); + std::regex re2(R"((\{.*?\}))"); + std::smatch match{}; + ProjectInfo proj{}; + bool related = false; + bool add = false; + while (std::getline(sln_file, tmp)) { + if (tmp.find("Project") != std::string::npos && + tmp.find(".vcxproj") != std::string::npos) { + std::vector vec{}; + while (std::regex_search(tmp, match, re)) { + vec.push_back(match[1]); + tmp = match.suffix().str(); + } + // 这里应该有4个结果 + assert(vec.size() == 4); + proj.guid_ = vec[3]; + proj.path_ = parent_path.string() + "\\" + vec[2]; + add = true; + } + if (tmp.find("ProjectDependencies") != std::string::npos) { + related = true; + continue; + } + if (tmp.find("EndProjectSection") != std::string::npos) { + related = false; + continue; + } + if (related) { + // 这里要简单处理一下 + if (std::regex_search(tmp, match, re2)) { + std::string restr = match[1]; + proj.guid_relate_.push_back(restr); + } + } + if (tmp.find("EndProject") != std::string::npos && add) { + projs_.push_back(proj); + hashmap_[proj.guid_] = proj.path_; + proj.guid_relate_.clear(); + add = false; + } + } + + parse_relate(); + sln_file.close(); + return true; +} + +std::vector VsParseSln::get_project() const { return projs_; } + +void VsParsePro::handle_include(tinyxml2::XMLElement* node, + const std::string& key) const { + if (!node) { + return; + } + const char* data = node->Attribute("Condition"); + if (!data) { + return; + } + if (std::string(data).find(key) == std::string::npos) { + return; + } + tinyxml2::XMLElement* purpose = node->FirstChildElement(); + while (purpose) { + const char* name = purpose->Name(); + if (std::strcmp(name, "IncludePath") != 0) { + purpose = purpose->NextSiblingElement(); + continue; + } + const char* include_path = purpose->GetText(); + current_proj_->addtion_.append(";"); + current_proj_->addtion_.append(include_path); + break; + } +} +void VsParsePro::additon_include_and_predefine(tinyxml2::XMLElement* node, + const std::string& key) const { + if (!node) { + return; + } + const char* data = node->Attribute("Condition"); + if (!data) { + return; + } + if (std::string(data).find(key) == std::string::npos) { + return; + } + tinyxml2::XMLElement* cl = get_child_element(node, "ClCompile"); + const tinyxml2::XMLElement* purpose = + get_child_element(cl, "AdditionalIncludeDirectories"); + if (purpose) { + const char* addtion_dir = purpose->GetText(); + current_proj_->addtion_.append(";"); + current_proj_->addtion_.append(addtion_dir); + } + + purpose = get_child_element(cl, "PreprocessorDefinitions"); + if (purpose) { + const char* predefinition = purpose->GetText(); + current_proj_->predefinition_.append(";"); + current_proj_->predefinition_.append(predefinition); + } +} + +tinyxml2::XMLElement* VsParsePro::get_child_element(tinyxml2::XMLElement* node, + const std::string& key) { + tinyxml2::XMLElement* result{}; + if (!node) { + return result; + } + tinyxml2::XMLElement* n = node->FirstChildElement(); + while (n) { + if (std::strcmp(n->Name(), key.c_str()) == 0) { + result = n; + break; + } + n = n->NextSiblingElement(); + } + return result; +} + +bool VsParsePro::parse(ProjectInfo* proj, const std::string& key) { + current_proj_ = proj; + supplement(current_proj_); + + int ret = m_doc_.LoadFile(current_proj_->path_.c_str()); + if (ret != 0) { + std::cout << "解析失败:" << current_proj_->path_ << "\n"; + return false; + } + + tinyxml2::XMLElement* element = m_doc_.FirstChildElement(); + if (std::strcmp(element->Name(), "Project") != 0) { + std::cout << "不是合法的vcxproj文件。" << current_proj_->path_ << "\n"; + return false; + } + + addition_dir_.clear(); + tinyxml2::XMLElement* node = element->FirstChildElement(); + while (node) { + if (std::strcmp(node->Name(), "PropertyGroup") == 0) { + handle_include(node, key); + } + if (std::strcmp(node->Name(), "ItemDefinitionGroup") == 0) { + additon_include_and_predefine(node, key); + } + node = node->NextSiblingElement(); + } + tidy(current_proj_); + return true; +} + +// 对初步解析出的工程进行整理 +void VsParsePro::tidy(ProjectInfo* proj) {} + +// 补充其他信息 +void VsParsePro::supplement(ProjectInfo* proj) { + if (proj->path_.empty() || !fs::exists(proj->path_)) { + return; + } + fs::path path(proj->path_); + if (proj->proj_root_.empty()) { + proj->proj_root_ = path.parent_path().string(); + } + if (proj->name_.empty()) { + proj->name_ = path.filename().string(); + } +} diff --git a/vs_generate.h b/vs_generate.h new file mode 100644 index 0000000..8108d44 --- /dev/null +++ b/vs_generate.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include +#include + +#include "tinyxml2.h" + +#if defined(_MSC_VER) && !defined(__MINGW__) +#define CPP_STANDARD _MSVC_LANG +#else +#define CPP_STANDARD __cplusplus +#endif + +#if CPP_STANDARD >= 201703L // 检查C++17或更高版本支持 +#include +namespace fs = std::filesystem; +#elif CPP_STANDARD >= 201402L // 检查C++14或更高版本支持 +#include +namespace fs = std::experimental::filesystem; +#else +#error "不支持的C++标准版本" +#endif + +struct ProjectInfo { + std::string proj_root_{}; + std::string path_{}; + std::string name_{}; + std::string guid_{}; + // addtion_ ; 分隔 + std::string addtion_{}; + // predefinitaion ; 分隔 + std::string predefinition_{}; + // 关联的工程名称 + std::vector relate_{}; + // 关联的GUID + std::vector guid_relate_{}; +}; + +class VsParseSln { +public: + VsParseSln(); + ~VsParseSln() = default; + +public: + bool parse(const std::string& path); + std::vector get_project() const; + +private: + // 解析关联 + void parse_relate(); + +private: + std::vector projs_{}; + std::unordered_map hashmap_{}; +}; + +class VsParsePro { +private: + tinyxml2::XMLDocument m_doc_{}; + std::string addition_dir_{}; + ProjectInfo* current_proj_{}; + +public: + VsParsePro() = default; + ~VsParsePro() = default; + +private: + void handle_include(tinyxml2::XMLElement* node, const std::string& key) const; + void additon_include_and_predefine(tinyxml2::XMLElement* node, + const std::string& key) const; + static tinyxml2::XMLElement* get_child_element(tinyxml2::XMLElement* node, + const std::string& key); + // 对初步解析出的工程进行整理 + void tidy(ProjectInfo* proj); + // 补充其他信息 + static void supplement(ProjectInfo* proj); + +public: + // 对给定的工程初步解析 + bool parse(ProjectInfo* proj, const std::string& key); +}; diff --git a/vs_json.cpp b/vs_json.cpp new file mode 100644 index 0000000..46e7773 --- /dev/null +++ b/vs_json.cpp @@ -0,0 +1,167 @@ +#include "vs_json.h" + +#include +#include +#include + +JsonCommand::JsonCommand() = default; +JsonCommand::~JsonCommand() = default; + +void JsonCommand::set_expect(const std::string& exp) { expect_ = exp; } +void JsonCommand::set_out(const std::string& out) { out_ = out; } + +bool JsonCommand::generate(const std::vector& projs) { + Json::Value json_root{}; + for (const auto& item : projs) { + const auto& cpps = get_cpp_paths(item.proj_root_); + std::string command = get_command(&item, projs); + for (const auto& cpp : cpps) { + Json::Value jsn{}; + jsn["directory"] = item.proj_root_; + jsn["command"] = command + " -c " + cpp; // NOLINT + jsn["file"] = cpp; + json_root.append(jsn); + } + } + std::ofstream jsf(out_, std::ios::out); + if (!jsf.is_open()) { + std::cout << "不能打开文件:" << std::endl; + return false; + } + jsf << json_root.toStyledString(); + jsf.close(); + return true; +} + +std::string JsonCommand::get_command(const ProjectInfo* proj, + const std::vector& projs) { + std::string result{}; + result.append( + R"("C:\PROGRA~2\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe")"); + + std::string co_include = proj->addtion_; + std::string co_predefinitions = proj->predefinition_; + + std::string speciaA("$(IncludePath)"); + std::string speciaB("%(PreprocessorDefinitions)"); + std::string speciaC("%(AdditionalIncludeDirectories)"); + std::string speciaD("$(WindowsSDK_IncludePath)"); + std::string speciaE("$(VC_IncludePath)"); + + replaceAll(co_include, speciaA, ""); + replaceAll(co_include, speciaC, ""); + replaceAll(co_include, speciaD, ""); + replaceAll(co_include, speciaE, ""); + replaceAll(co_predefinitions, speciaB, ""); + + auto include_vec = split(co_include, ";"); + auto prede_vec = split(co_predefinitions, ";"); + + for (const auto& str : prede_vec) { + if (str.empty()) { + continue; + } + result.append(" -D" + str); + } + + for (const auto& str : include_vec) { + if (str.empty()) { + continue; + } + if (expect_.find(str) != std::string::npos) { + continue; + } + result.append(" -I" + fs::path(proj->proj_root_).append(str).string()); + } + + std::list proj_list{}; + std::vector re_relate{}; + auto handle = [&](const std::vector& lrelate) { + for (const auto& str : lrelate) { + proj_list.push_back(str); + } + }; + + for (const auto& str : proj->guid_relate_) { + // 这里的relate 子项目有别的依赖的话都需要加上 + // 这里假定不会出现循环引用的情况 (理论也不应该出现) + for (const auto& pj : projs) { + if (pj.guid_ == str) { + handle(pj.guid_relate_); + re_relate.push_back(pj.path_); + break; + } + } + + //std::string dir = fs::path(str).parent_path().string(); + //result.append(" -I" + dir); + } + + while (!proj_list.empty()) { + std::string& data = proj_list.front(); + for (const auto& pj : projs) { + if (data == pj.guid_) { + handle(pj.guid_relate_); + re_relate.push_back(pj.path_); + break; + } + } + proj_list.pop_front(); + } + + // 去重 + std::set no_reply{}; + for (const auto& str : re_relate) { + no_reply.insert(str); + } + for (const auto& str : no_reply) { + std::string dir = fs::path(str).parent_path().string(); + result.append(" -I" + dir); + } + + // std::cout << result << std::endl; + return result; +} + +std::vector JsonCommand::split(const std::string& source, + const std::string& sep) { + std::vector tokens; + std::size_t start = 0; + std::size_t end = 0; + + while ((end = source.find(sep, start)) != std::string::npos) { + tokens.push_back(source.substr(start, end - start)); + start = end + sep.length(); + } + + tokens.push_back(source.substr(start)); + return tokens; +} + +std::vector JsonCommand::get_cpp_paths( + const std::string& parent_path) { + std::vector vec{}; + try { + for (const auto& entry : fs::directory_iterator(parent_path)) { + if (!fs::is_regular_file(entry.path())) { + continue; + } + const fs::path& file_path(entry.path()); + if (file_path.extension().string() == ".cpp") { + vec.push_back(file_path.string()); + } + } + } catch (fs::filesystem_error& e) { + std::cout << "Error: " << e.what() << std::endl; + } + return vec; +} + +void JsonCommand::replaceAll(std::string& str, const std::string& from, + const std::string& to) { + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } +} diff --git a/vs_json.h b/vs_json.h new file mode 100644 index 0000000..726a211 --- /dev/null +++ b/vs_json.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "vs_generate.h" + +class JsonCommand { +public: + JsonCommand(); + ~JsonCommand(); + +public: + bool generate(const std::vector& projs); + void set_expect(const std::string& exp); + void set_out(const std::string& out); + +private: + std::string expect_{"expect"}; + std::string out_{"compile_commands.json" }; + std::string get_command(const ProjectInfo* proj, const std::vector& projs); + static std::vector get_cpp_paths(const std::string& parent_path); + static std::vector split(const std::string& source, + const std::string& sep); + static void replaceAll(std::string& str, const std::string& from, + const std::string& to); +};