From 08ba30e8f933711e8f623ced502d4c3ad53f97f5 Mon Sep 17 00:00:00 2001 From: pgagarinov Date: Fri, 22 Jan 2016 14:27:33 +0300 Subject: [PATCH] Initial commit: Version 1.5.2a of libpqtypes which contains a few critical bug fixes on top of official version 1.5.1 --- bin/glnxa64/libpqtypes.so | Bin 0 -> 435888 bytes bin/glnxa64/libpqtypes.so.0 | Bin 0 -> 435888 bytes bin/win32/libpqtypes.dll | Bin 0 -> 118272 bytes bin/win32/libpqtypes.lib | Bin 0 -> 303594 bytes bin/win32/libpqtypesdll.lib | Bin 0 -> 7668 bytes bin/win64/libpqtypes.dll | Bin 0 -> 134144 bytes bin/win64/libpqtypes.lib | Bin 0 -> 397814 bytes bin/win64/libpqtypesdll.lib | Bin 0 -> 7516 bytes source/AUTHORS | 33 + source/ChangeLog | 364 ++++ source/INSTALL | 119 ++ source/LICENSE | 22 + source/Makefile.am | 68 + source/Makefile.win32 | 49 + source/README | 54 + source/acinclude.m4 | 139 ++ source/configure.ac | 157 ++ source/docs/man3/PQclearSpecs.3 | 1 + source/docs/man3/PQclearTypes.3 | 1 + source/docs/man3/PQexecf.3 | 104 + source/docs/man3/PQexecvf.3 | 1 + source/docs/man3/PQgetErrorField.3 | 1 + source/docs/man3/PQgeterror.3 | 56 + source/docs/man3/PQgetf.3 | 104 + source/docs/man3/PQgetvf.3 | 1 + source/docs/man3/PQinitTypes.3 | 56 + source/docs/man3/PQlocalTZInfo.3 | 66 + source/docs/man3/PQparamClear.3 | 1 + source/docs/man3/PQparamCount.3 | 1 + source/docs/man3/PQparamCreate.3 | 76 + source/docs/man3/PQparamDup.3 | 1 + source/docs/man3/PQparamExec.3 | 106 + source/docs/man3/PQparamExecPrepared.3 | 1 + source/docs/man3/PQparamReset.3 | 1 + source/docs/man3/PQparamSendQuery.3 | 89 + source/docs/man3/PQparamSendQueryPrepared.3 | 1 + source/docs/man3/PQputf.3 | 120 ++ source/docs/man3/PQputvf.3 | 1 + source/docs/man3/PQregisterComposites.3 | 80 + source/docs/man3/PQregisterResult.3 | 122 ++ source/docs/man3/PQregisterSubClasses.3 | 62 + source/docs/man3/PQregisterTypes.3 | 90 + source/docs/man3/PQregisterUserDefinedTypes.3 | 82 + source/docs/man3/PQsendf.3 | 1 + source/docs/man3/PQsendvf.3 | 1 + source/docs/man3/PQseterror.3 | 1 + source/docs/man3/PQspecPrepare.3 | 123 ++ source/docs/man3/PQtypesRegister.3 | 53 + source/docs/man3/pqt-composites.3 | 263 +++ source/docs/man3/pqt-handlers.3 | 598 ++++++ source/docs/man3/pqt-specs.3 | 1221 ++++++++++++ source/groff2html | 109 ++ source/latest.diff | 709 +++++++ source/latest.log | 1167 +++++++++++ source/reconf | 25 + source/src/array.c | 278 +++ source/src/datetime.c | 1707 +++++++++++++++++ source/src/error.c | 330 ++++ source/src/events.c | 173 ++ source/src/exec.c | 562 ++++++ source/src/geo.c | 391 ++++ source/src/getaddrinfo.h | 146 ++ source/src/handler.c | 1077 +++++++++++ source/src/libpqtypes-int.h | 533 +++++ source/src/libpqtypes.h | 468 +++++ source/src/misc.c | 199 ++ source/src/network.c | 257 +++ source/src/numerics.c | 838 ++++++++ source/src/param.c | 493 +++++ source/src/port.c | 587 ++++++ source/src/record.c | 164 ++ source/src/regression-test.c | 1373 +++++++++++++ source/src/spec.c | 660 +++++++ source/src/utils.c | 265 +++ source/src/varlena.c | 88 + source/win32.mak | 66 + source/win32_d.mak | 66 + 77 files changed, 17222 insertions(+) create mode 100644 bin/glnxa64/libpqtypes.so create mode 100644 bin/glnxa64/libpqtypes.so.0 create mode 100644 bin/win32/libpqtypes.dll create mode 100644 bin/win32/libpqtypes.lib create mode 100644 bin/win32/libpqtypesdll.lib create mode 100644 bin/win64/libpqtypes.dll create mode 100644 bin/win64/libpqtypes.lib create mode 100644 bin/win64/libpqtypesdll.lib create mode 100644 source/AUTHORS create mode 100644 source/ChangeLog create mode 100644 source/INSTALL create mode 100644 source/LICENSE create mode 100644 source/Makefile.am create mode 100644 source/Makefile.win32 create mode 100644 source/README create mode 100644 source/acinclude.m4 create mode 100644 source/configure.ac create mode 100644 source/docs/man3/PQclearSpecs.3 create mode 100644 source/docs/man3/PQclearTypes.3 create mode 100644 source/docs/man3/PQexecf.3 create mode 100644 source/docs/man3/PQexecvf.3 create mode 100644 source/docs/man3/PQgetErrorField.3 create mode 100644 source/docs/man3/PQgeterror.3 create mode 100644 source/docs/man3/PQgetf.3 create mode 100644 source/docs/man3/PQgetvf.3 create mode 100644 source/docs/man3/PQinitTypes.3 create mode 100644 source/docs/man3/PQlocalTZInfo.3 create mode 100644 source/docs/man3/PQparamClear.3 create mode 100644 source/docs/man3/PQparamCount.3 create mode 100644 source/docs/man3/PQparamCreate.3 create mode 100644 source/docs/man3/PQparamDup.3 create mode 100644 source/docs/man3/PQparamExec.3 create mode 100644 source/docs/man3/PQparamExecPrepared.3 create mode 100644 source/docs/man3/PQparamReset.3 create mode 100644 source/docs/man3/PQparamSendQuery.3 create mode 100644 source/docs/man3/PQparamSendQueryPrepared.3 create mode 100644 source/docs/man3/PQputf.3 create mode 100644 source/docs/man3/PQputvf.3 create mode 100644 source/docs/man3/PQregisterComposites.3 create mode 100644 source/docs/man3/PQregisterResult.3 create mode 100644 source/docs/man3/PQregisterSubClasses.3 create mode 100644 source/docs/man3/PQregisterTypes.3 create mode 100644 source/docs/man3/PQregisterUserDefinedTypes.3 create mode 100644 source/docs/man3/PQsendf.3 create mode 100644 source/docs/man3/PQsendvf.3 create mode 100644 source/docs/man3/PQseterror.3 create mode 100644 source/docs/man3/PQspecPrepare.3 create mode 100644 source/docs/man3/PQtypesRegister.3 create mode 100644 source/docs/man3/pqt-composites.3 create mode 100644 source/docs/man3/pqt-handlers.3 create mode 100644 source/docs/man3/pqt-specs.3 create mode 100644 source/groff2html create mode 100644 source/latest.diff create mode 100644 source/latest.log create mode 100644 source/reconf create mode 100644 source/src/array.c create mode 100644 source/src/datetime.c create mode 100644 source/src/error.c create mode 100644 source/src/events.c create mode 100644 source/src/exec.c create mode 100644 source/src/geo.c create mode 100644 source/src/getaddrinfo.h create mode 100644 source/src/handler.c create mode 100644 source/src/libpqtypes-int.h create mode 100644 source/src/libpqtypes.h create mode 100644 source/src/misc.c create mode 100644 source/src/network.c create mode 100644 source/src/numerics.c create mode 100644 source/src/param.c create mode 100644 source/src/port.c create mode 100644 source/src/record.c create mode 100644 source/src/regression-test.c create mode 100644 source/src/spec.c create mode 100644 source/src/utils.c create mode 100644 source/src/varlena.c create mode 100644 source/win32.mak create mode 100644 source/win32_d.mak diff --git a/bin/glnxa64/libpqtypes.so b/bin/glnxa64/libpqtypes.so new file mode 100644 index 0000000000000000000000000000000000000000..e32763c75af469511f0284d2eb2e18fb79bae633 GIT binary patch literal 435888 zcmd?S33yaR_BVVx3q*z~hE2ns5E4PQm~;z>XrL3} zdTl3eGwA3{Tt;yj#bpptvBMS+mxv0eqlQJjO;{o-JLLVHs_O2_mCXBm-}ir?=lhfBSOs!p9cwcN|SUjL0rHk%UrBrDe|L>1i35tm3<@l*$Kr6?{XSLukqPNfIq zO^v7g{vzdXTz2eNQ5=kkP?EU(X`a6P=^hM^{Vw~GkxJD?JUw<_lDKchzc{|)U;Mt< zZ;N1${ibm-N(z4IyGf*5f1QFa_Dj61MpiWuBYR72EMZdJxBb~PldRy#BTuKJMo>1?|gh? zpSy5zPmI9tB78&m*5JDY-=+B8kFSC6gZTa#-&%Yh!uMf(AHg^Fc?=hS!S}EDK927b z_&$m6Q~1)S4&P_-eGcCj@QrT#&;FItMPpo-}mud zgD-s|_zv^UJ{jq?vVVT-1s~irXhp%Dz5BUKcLz4@du`69rh|L#9~t@cpD%s*pFO7U zdZ%FfLt|flVD9DjPr5McvQt~u_r33%^?k?h>vwtR<-O0I|BAir&U??ff5FJk+f$#L zy>i@)?5gJFdD`Lg-znH~)$_v^UH(qN{spIxI^J~7o_N8y7n+{`_nHf9ha4K>{c_*p zF3kh~v~%UpXO}nhom(;GKF9o1`-We*pmzCBYx)-NxHa?QYcHRcoALB(AAD~cc5usr zt))BPxP0&D2hV*c{PVd_U;So5->2?2hwokg={a}4k@Vy*=I#UM)t2mft#sS?nagh5 zv*+sBJMJj#R@3#}z7J*|J1eiM=48JCyT91-kgNBat#uji?tb|0ORnmkx39e5rH`M# zDK8ZLyylAw-n!uKNv{=n-}&dP?nvA6msPj9ldih#-{$lq$F7-j+wFl%UmxLoVEc*5 zdD^X^cl+*Aj%}-X^4ri0YwF6*&HuwMozGo1>FUdm^z4FZvUyuDxlfiK*G>zlW{R*?Kmr0;lK59bRe(SIA_WkYl z_l_Q4@^0TbPi*MBzyEWGmc6|A>A9~Cs7e~N=at)@i~NJy{l9&Zm9vxrbaMFT z4nDD+@~-G`W;xWy&m@0BJ9^SEcqabK+Nrmf+Nqyz?X;uTPPw|aQ$GjV;jd^1AKOm8 z!`ms>;dbP_-HsfHQ5^VMKiTcb4}tMa_4#l+{43kxf4m)iE^nt@{@#u~l(fUYrJZ)n zY=^(P9eqA-r#}0%!~aP;`0efFyQdxbcef+w`gZKR81?MH*ZO(AoqT@+J$&sHVAyU;BWjF2i_NQb};`2`B!j&;w1W9CHTuJsKSThD*F72jLuUae;=n~ zay|x0c*{^OXA9)g$077_6>!`JJEo71)lVm7#m}7f@*ibAvvbH1qjWC6P1zC4cQgl{ z6L_`IGrJoH77IDYSUq=A?4vmTH-X;|lJsnv$AMVAC5ifX2s!5n{xL$I+AF!7YXyFl zXqSRU4qOX8=(8MOlJB^ckqRb?>~pu!v#tl1bA{j^AnKv^2D>F$r)qu|2|RP6#^f{*_CY~Uls@hdr8QjjbG9;VyTCzF+86${!z#&6Lu1*=fIOZ zS;-RmC_?`l!M|GY7d3F;dx8Hbv7|FB6>nry?e29j6VEx>d-D z2syF(S&jN;?VHX8KPl#m9|}3y!l3q{{pfRftlh~_@wrRrlNM|DhZ)S~C3K~V@-`jj zxM*Hwps4?*A2|L3?x)XFLQb}r#JnZ&mxMlcQ9nM;uACcdubmtiDDa1by_Hi(!{-A2 zqr4O=uUNx4EGnWa($7=UmFLEY0ttRQ!+#&&CW&&{MY%Qz{?CQ}ExR}%s#{qk^luUE z@|MWvKZ3t8%K2mStRqOLb}3rO@oZ6m1p;prb{K2N|A_M1U*P<=ivHph`DW834xgAl zPYHhI8m>qmQP1ZxyUO^TU7auLExVb^*~ovCH%0vyy~%;Uh;pTf_KkeO@j}7hEXrFe z@IC@}2>!;eInV<%eW-gEi3%;Ji%Edy@%y%yn2>+Qa^mLu(^yeb=YLRcb@DE^P zpJY)#E+M}};E#*;Z4v!?sK9CAg!FOkCtEHU)GMo0KvvS9}4~zV%+fxJWbf= zil;enT*xUA^-%Rk4ori7^!Y%P%XKryk8zl-rBJ>_6tLlgk(hmIh5k(@r*{ebZ$ckM z_=j%={*!;`IW2yaTEV|!1IKBtjXtU&|l!)V)Y=# zotXc>Mc@%(AYvI^xjrUe#ABkFmE%JHCgBG}_ft9x{T;$UXxydGaDmr~a;Y3v9uj)i zii*5W;L7C5x6PU}dvaxJ&izv|v$(Rdv{EU*BQUu<7?@mKQBgc! znN>Qgq z%q=d@Wmi=2!1P(AZHT~KjHD9A(_(~3qx+^72l#!I7AIm7QDq|kHi&dT^enAFy~Q(& z0|g_fLE`2+%K(?n4$hiVN_AaExzTUgoQhe+0ahrgyUJiW(y5AYk0|1l`O|qDlowZ2 ziZ&x@Ad6>t=P{*9@l!xFsl*aSmCl|zB3N26A3$a7x-Cl{YypOh8-iRvc4Hpvp(q1H zGOg)?@*^n>po=yN6jYSr*3zk9Vu~clwyH>c36)~ZROmqIJp7q68UCR-kPC6#$lT0w ziGg}l`5fvAqK+hr(q>kc-WE@a6O=M#&b)X+?3(bB=@sxv@g#|4c@+ny#nZ}T1WTDS zbN+2`PzgN}G)j&B!dn=;R97({?Iq(bAmgSR$?)TbTrh$;$2K-65+wm6V@`E;AXq*V z9Vj82-jxKKLP%AYr9R{5OD=>gFz$xqC!EQfy;CRGZr6}Nkc zxwEw57W6=J)8MF>6PQynXJ!nEwN}YA`1@ET#R;lGYV3GQoS>8`bKu)!_rwWGLCg1z zr^E@7(oas|gh=5oA6<$BB>X=!v&3BzN%sjOjOihfl!~rgS}~nBBMFviN}n=6P|BSZ zr6wp!!$@DsM_NitP?Uy-Nz_UkqGbA1UXx5jaY^x1K{Fu|P3gg)a2k{tCn%+&v}8^N zcPNx5k(5fqDI3c%V%{cfKh`T*-GPCP$hemjU@o1^I8IbnmK4us!*F0ukPXp+IaA}q zJVxy~b4x4OU@y!nZ%z>XSr9O9QGRH{yaxp)gb4;uupGkT!y1Jqtl3%L5iXitk75G~ zMKBc@9vF|v9HNL(cq5WOYtEg_8wXfWMedm{V9j8qNG9Itpa{Qq2M~IQFofGG@`*(! z1tWs9OHmEwr9+q%Kp<)e`6x4|Pnp%Ha!#LX=&Jkpvx~`t*xm=OixsiC8m9p-DyT8w)^*rb$8) zrtF-9r^wu?>@I%NgK)ZspELQrGz7Zw56L9SNo={YBfHOrnf(7B|KpWHB{wnGqxCWe zzQK#9gGy1Z784YklB%2%>2$~W)2E+9i@gKcIu6cDTtxgG6tAEkedsTkail6E1l@)4 zCo2;K&E+S><;TteVH(6f4ly5J@pKPH$MB|`d3wZxpH;{wSeq>PIRbCA;GG4&!-8KR z@Foj>k-$w0eyPA)EO-xrAGP3D2wZulZMm`po@T*&3*2tOa|E7Y!TSr`Wx)psyugCr zAn+m!?h$yo1z#)hDhsX&yw-x>B=9;5K1$##EcmSgk67?Oj_2*$Xu&54{w51PMc^$K z{5F9r&$g}q@ngAsy9J*q_#GC!Lg3jJ{A(e{Wx*Q+e}M&`EAS!mc#8#JE^y_!w)Ovt!0i@%g}@ya z{NDo4w&3pw+-1Sv7kGgMuNQcc1>Y#}atppi;8hm&!CeB+w%|(4{w;WlzzZz+SpqMz z;O7dw+=6!zc$EdeNZ_>={8E9}S@0eLUtz(o6nMmf_Y`=e1Ux6e5%0f zEci5mudv`V1s<{BcL==Ef(HfOWWnbPyv2gQCvfG3w)MYI;C2hXNZ<|&UL){q3vLM9 zWx;C&USPo=6?l;aUncN!3qDZbRTjKZ*j23se@gJzS@35BzQTe(FYt&3e_7y-7W{RA zH(BsZFCq(-xavsf=2}Iu;3d6o^8QD6u8TRenwOr zfv>RO`J#Rz7QBz(Z?xcj1>R)AuN8QU1s^1E<)yau?-ID(g5M}`hXo%l@N5fyv%p;z ze3ZZoEcjS~7g_L00x!4VQv_aR!EY0Itp%SU@Hz`VN8l?gctGG03qD`qjTZbKfj3$3 z#R6}!;P(k!dAV)<8v?gm@IMROVZk2}c(w&!CUBPpe@fs57W`>}7g_M<1zv8!UlMqg z1%FlGwHEvhf!A5^l>%R3!B-1BV!=NUc%ubhC-5c<-XQQ63;wadl~>x=yiv zTWx$jz=CfTac7eMr_%{MCu;5JsFS6i!1YT~zO@UWg@B;#`wcx)9yv~9j5%>xV zep28O3vP?ee=T?ifj3$3vt#401wU8dig=DHwytuX!0i_NB7r+B_@x5Rw&0fu+-1S9 z6nKFJ?P~FsrNiD z;YAYu7YWZ;o#3A&;X6J!GrnxYnemK@%h=tNuPnzQ$saArZ<6H8c%39)#vPJ;886(D z(B}b3evyP%NqEL*3I10l+#%u5NcfIz34U?(grydaNt9Q{ni(pM?BX z5`Ue9FPHGbT?zgr5?&>KrNurD3I9h7#P5#%3I0k6Z<6ro629!01png_ zUMJxrCA{!hf`6fe7fE>RY!4-8v?lo9lK34G{(^+>NJ+HIV-nsZ;Zr1h+1UyH+a$bB z!o?9imRe{}@W;;NP(qP}*D+51C!=eEzg)r{5^i@C-Kjc_=_a|cO^WdcS25yggYdByoB%Qo8T{!@Foc#BjL+(6Z{J#yiUR&lJLUo z6Z}32FOu+gBs{~D;1@?oS*keovfRQK}?7UBZ`2_!lzEr{; z5?(9eg%Z9@!Yd@aPQrOh^Tg#6&OI8(S4j9!NzN(>zg)s267H1nO%i^$gf~j~6%xKf z!mpI@CJDbu!c7T(TEbf-{ErfTRKhbQTzMm5|5*~ACgI~G+%DlgB|JmIuaa!+knm9w-X!5GCES$o0TSLK;WH)tsD$4k;fk2AQ|u6y@H7b@DB*Sq z|FeW=NcbQLcS!hP3D1;p@u&t%&6e=t5`V6QUoYV<376;ZnuNO~{sIYqNx};y+%4fn z5RYbt@vDVKhZXDM;jTvm}m+$qY*~mMRYRJD;QltG=-MYI!514bSlxc zjGjU?g_zMQMvo(!%p+RP=#fNIh!`zm^f00+G>jH7dI-^H6YXO3bwpDr7|mvMU!p10 zi#izHlV}RrqIO1KMl^+LQH9YL6Ri^6avH!D=MhaIShR`JXA?~!RtMqfuX4T;fgM)xI}hN`H8(LIT# zAu4KT^kqcT5ENAyeKFBAltf!jvi2vMhLC6zqt7Nfhv-H|ClO7qJ{n>4@lw#_;-f1V zeTZms?a?|$?)VCHgv| zU5s8$G`Y}dHlyDlnp|Ym!RVKWCf69XGx`~#$;Cw#Mn6F`xwdG_3D*8ZyNGUL^!-GW z%ZfHKdNI-Ds-h7_-$gXJsOSntR}f9EDO$(q+leNZ6s=|S6ryh=x{A@`h#pFGIip7s zO`$-vh|$A{_7Ppc=pjT8BihC2>xd>-9?fQSU!wg)I~d)Q=zOB>jJ}NMn}}8zeKFA# z0z_Mmv-T&tfaoShpH1`#q8k~VMD$3aBaA*i6*LX0(G`q7MD%E)>lnS4=rKgsGI|%$ zw-8;$=&y;smFRLtZzY;S?`RRDKO~x_B+&v!uO*s7#;A+YtBD>@bT*^kAbJAP4o1I3 z^hBcVjDCjbNkl7*euC)9M7JDc?N4+O(M^oLpXg$u8yUTr=qW@;7=0JfB}A`abOq5< ziLPVx?L?OnUCZbxM3)g=#prQF-$ryfqel`=15mVx(Zh(IPILjIhY)=`(Jn?`NAwJ$ zvl-o&XbMfD4$xY7a1={sS~!({#%NhbHT?%IboAUiFTk*PO%Wd!&zjiURHk-^)lOVj zMxQ=v_iBj1P#GTlBD=r;GyMM3bbtNnWKD0;>dhN8+eYoP(}4^K>nwz&b7A~`tGueg zVKMoiq-)0D#U(uy^JBPVQ$sUM+?bjTM%ypH*XN-TP&#yj66_S6 z1Wv9u^4B4b#`q|SY;By##z*(9?pxer+@r^g()3dZ2DGV~k#YsOS55agb8{lb(2UU0 zY&CQuNm2B*TJo)#p-7rOG{bN7%&*z6R*%9^?KMgjZ_OTc>A4`(n!*%C$u}nEHl#Rh z5afQ3{WUu2ey78&e=;Q8?+2>7n$6)!>FR@TLa@&mm1Yca)I`+k@gPG{n-(5o_vWB^ z(seED|In`KpK4hRTK&Ofe>nXEcW7rvwVEDj^%(Z>B)dCwyj87kLB1Z_=UOO|=`jlJ z-kNXJ>U5GGI%ZR=4;CPI(`GsjwU?&mudKDv=l3S5{A0?mQ_iMO+vs!&V z%Y*dfl@me;MwK&QlUkjJG%Z|!S{lb|=||Lq;mRa&ROs8lYg^|rhU79;Hc@H?OC?># zQtB_pT}4#fSCHm0h83`UsJz2jK3hD-!%LCGic1&BY98aE@?Oh$zA+ZBKng7Kc8{^R z4wsC96u5>ltTW!&K@5ijK4Ud0LHbc~>3-V@k8!_(f}pg4EM(Ub6F{cWp9%O}3op)~ ziehzEvmc#DGho$IwLftiS8G;-Q8V&g2zfP4KRAA(dxCqSdy;#y7VaNOvMD){)}0jh zYR0V&Ej%nu({FaLzyQXne}_9-$CR@=yPoRQ@D_UXoo@A0b+cRj#2q?m)6+cqycB=9 z5M6jyuE%))0jTNG%hNqZKPMQ$1_m&d+tuntlm-QzM!<X4?Vi(^ymedfovpZ8#A5gBPUbU z&FaUx)=Qt39mw!NR6h@L>JnF@AJoXrH}Z4cp?$XD;k$RId2{x7jf>Ee?wQQ}h|h4R z4G;HvP75`pX!SoNL)}bt&I8cYqYphvH~W(BNYhGgftlXZO*8JyFqa>0ZKVWFZ}1r- z()=Z(d)ocB?e4JOY4e5F+uQ@ry7vWrhX#eHX$CR(qtZ=CPcm2Z+OpWLS9&C zPQ=~X6dNzxAAnnl1`%4Z@kG$I7W(fN`d=2h-a@BAFInDNOZp&7dc=}G(2~B+l0Mjy zKEgszvCwzK=(d#=yvc7&WEJJnca2ByK`;CIw1O&%_d9p%ZrA@|a8v zY;N6)p}MC=Bim+j4dEc{Cz=z{8Yn~s(BO5k-_VaowXB~t{Ya=@tB)rCqP^@k9;2+> z#=ooZ1H+tWz6#5)iNGw=)tZMP&TDwPFqcZNQ}P&{&{sWrJ_gG%xyJA`xA8D}2X*s+ z57nB>!2#Fi50A$fNpD5+7z@z9kJ->$J^I3K#wfc7hMl2)sEMqU?nlkRmG zl^JgJwFWRJsh{Y%>2cebPq8GCVPxZcqX`= zAO?s9nO^m^7BIoDP`=1C0H*7VQN1YVUPfLv^4bQ5RLZ*xdRRuF8}jML^T{^G=OUZ6 z>K1)s2Ft*W(R~ed0>6In=J4HH(#SP0{DQWsiD-I?Q?0hK zN`QPCR31!*cW^T~@KKr$2j?TlWn67M#BOi)h3BNGTWGAzrI3Qgog=vLVhpdDjSF(L zX}<8iY3^`gYiPF(34u%9#?8=YA)Mf!SEW)@c#Y0(Y7Qq_&tpu6C%+f#C4-zfTRr-Z ze*KtR-Qv}Ec=T`0z6YtT)#|SyyJr7A9ki0)e6}MY_-otyR9y8zdeu+OH-QqC6ScY9 zP<_V3JR^@WvVi5Z8uz=A6XoIyHKZXE3OO)n{HShm>pRTN2Y5zzP)6TSMq7NgPqokn z+klzQH1)wxSw$Y!_Xe(j5$0-P&%Yp0)#{s4wB#kR-0Uo~e8}(`L*>knk4Im}vzjEb z>L9Z6mu$)BS)mM+0eM?391t1&nBq%*GnPSDmcc%#j!KPZ0O|S`6p70}y`LB5c~&#( zgV!Qn)k+Y-ZLs-l+gWk`oCD08bJ&f6!ZUCxEV<@%c(hmXmW1{>y2d0V5};RT?( z=@%ORihF9l@#zQE2d6+mR17JI$`Lxw!P-IeR-~xit4O{Zm8@fshmin3~bb_1C%d{__I}-?-2im zP?{oM2%X(; zC$ahuZEDSd13pd-TPe~nq4ZFL?RN|#1;cS2J#;$Bt$*eT-*}EE z{MQe#40%r{5H=7I5FWkpo$fWwBRu-HBhmWP-QD3K$?oYN&O-O|=-ca$r@Hme-C4ho zgVm0D!=sYxTa!Fl-@`3?Rqbo<^vDxf7 zKbq#XZORL$WUQlc+!OvsuZ6g0)%zW04DdlSeTVxp@s!R!;e1VLO=HCU8f(Jn5HQ82kf5d z-|@0Fr=h_5fbdOcfAI24FTJF1I`UKf-egZWWu&{l36)VFs<*lIvrxDy%6U;k4&<&b z{^g?Eke7b+$S!wQqx&<{V_S=Cr>~`|WtleX%%7C02U~fJf(QlEZlC_^s4_JZ?&Wh$ z|Cj=nGPTdqL#q9pttS=bklJ~IGYxQn900$I44dlBwObyLYU1HPam7}fihqw>giuR>0(R(a;%;G0p) zXjsi}62x^dKWEp;S%@CVUKa545q#=hrZc2QXC8Cy)I5NqnZ}f+U zB_nYJCEkZbn!!=xUCH_SC;srb6eL1yV3uD;n;^G}lzhy{!?&j%_S^v+t6Vb~J|xwr zAJD>gbznIK1~XkDXjliIe%c=%(h-7uxB+nlvd>r7*tO8ww0wOd&mD_z6x2q0QB~BM zSN(v24C-KTRM(uV=^OHmS&I9xC*OuK^B%x!9QfnckC^Ts+1M2rp@rw!Vwo1%@(z1S ziFYkJ7Zwrx;r`~}9!hhk*g735a=6j&G%ZXh<}5TJ1(iYcT?B)eF1Mx!u~2j-YpKEw zia(4(Blp#36QLh4FZl_M&KQHCd?Va?a6QekGt`x8DB8Q~Skm0LFp;;#nGZl^#@j%1 z7O+3Y*gfjX?(R@?Z+F#+q`8YBHGY%%9^Eku&AQR8Z@{dnhBoEgRfC-HKLseEN3TrL zE7K{w3Yj)N4~rM4x~ogB0~h8QpiXyEmr&KRj1W3ZJA`5%MzJyMyVb|md)1Zez14d> zI+pA1MVUm5a@B$qclb`5N8jtwTg?tw$@PRa$hSic_v%NSzK4Oc>48Vb%EV^(k-hcD zx_fLN)*nyG`p^^Z_9fMpJL_{6Ab7LBf?vom*BpiNSsQX99(_g^s%5D=^7g@uD5beZ ziihACGg$qZufsC*ymVusf`ze~Lh98hb_S*={&4SQl{bl z-8hH&TARc>C=uPy4vy1UErSd*9OJ+e3GahwuynXiul`$fC@TVN9}&J2leYzF=tU{4 zu)M#2u!oh{V@#x(n_4rK1-9VT!uN2CXPv>kb~jg&`j=XLJ-L>{LQI2s7ZZ}=G4df~ zGnRdj>@jAfN4Mgl)=yRF(MvE>o0r0JZGIV=a1~F{WHdec4=~2+v!>OjA9{zj`_!ei z_^TgXz2VJg9@0;v{SoiHt1n%;6odJ7h*LVbvs%2x53_H^8&2DYgm!O5IuI_a0MLNwgi1=3sBTt_KnT;@AFS?#OUMVLTq;c4)BB$d3QIkBm= zm9+%i1NUlv9Xl8Y%{|cCt*1D>#<{FjoVYi1^gTzr?s#f>JFN58firCRz6!`Roio2?HoLc=Y^m2!Xe!2XVT0Ni1f>nB}TLbr+ zU!$99Ms{-s?@yR&vZ`P=6URij{d;UFfghOdQeDhLCBYkE=^s+_!xJ!T$}+L$iB%*` zU+YIazY$gJ-stJp4cTK-H3Tc2!3*f}(mb`AUL_f~54QZ!0F4-WxjmGeZ~Sm^yP*W>@GPs1{vIR%ewWH^Hi)z(JS~@}y_sabDiUT>Lb&(U zNO&_@GlF!h`H)B)!R`v$J>g0laF70rd8bICb$GBl0EgDu%*g`o&f#pp?(n1}bEv>O za@@u7Wbpl-kD#M}6**3gj--p+84nOI!z#}=18x~bOuNZN+h=gL0577Knh_v-9y zg;oX}+4z)sF#J0=dYo7C;Kh6#o!)Oy#NoAJ;LpQgUcC*uY2h(REL2ce=G&HHuL~Rt zlfbcnINkz>KfEy6PhA=VYJQRjJUw7`-eiOXObTfZ1>on%->NIeBzu;Qc3ws~rSO~r z<;W#9mP-mGTu!;9@>~KVkwb@g4ylxblXB?5a|rZ>^p0`q9Z32WB)y}Mex5%(5erTe zC_dN25qo(HllDB)fT-T%NiHmngkXb^s7p9)!3*XND z8sgczY*8D;k}JyxlV&rc*AN}{vZfKuLd}ky92%lmVs1ligPLDDfwf1zjajSt@qeJ6 z(E(vEbIs?XnKjCjGPa|3E=GuWU0}Y?I2&GctSv2=IpfQM9!w4Hh1 z*YSGBcYF@4y_6gt=V$-Kk; zXJA(zEl%52x4QHV%`fwP7}`N&K47bP1J!!YR@8bx^VSQ0G7UL=8te=0L16P0BB-pL6vy%kLOc_zAk+!6z>Z2o9vch; zdC}f*@67H=U`sOuV)kBdu0gxfy!|^MG;e<%zv^O>XAdu7PW+Y_F!{z(#KEn&nO*f6 zO}b1<{WGyIc^vF!07b(bxEH4CnBu1)e~wcPRo9YsZP;i+^i#5>4ZYGHwO}Y(JZ$wL&bzr1m zb8fz>!`6M=YR?Vk7hf^`h!Ok~HbsAdwPXDn%58?qgTL5|I?>dg7B^e+B-S23Rh_O2OFFhj6PI5b~iJ$&WRT0{>=}U z)j}B_ArT4#bPaAuWuEMS6 zgl$kuKHpQ*8t9}ML(`0Txizi9Y^ra+zG=qcL98ZGGn;JNW^5Z|`wZ1tkE%as7(6mo ze(GtB2!|+;mR}O_hP$2Tp0RF_tsXaPC7ZSB$6Odj{k8_5J^)8};^&EC`KY+mvhKep}-hgR8 zRcr6DI1q{~P^A&FyM~`wm7?#05zQSqpPB)w!w13sQ0oM0#==52QDrlF^O5bXt*fxM zt2FoGeoQ*Q@j2@dRY)W|n2*yhP!uOU#<*%VxHWR5>EaN=bSP^H5}6+|77SX{K#{_t zRu&`NNB!{~0#^HbGk3a665G5yHa|svufxyA@@xLHmwYfM&n5|qPDtPb zWPVQqZ^KVZD^z||IIn6y1`&t(C6*ajEo-ZlqV1P}TU^TLDp z>Z3QfbL)dHYVhjEsVPfJ2KlD1kG$W~>a#U4rs$$J^(mJx`U*>8<@m5EQSRuYF&q|> z`voE!+GaAp+sb;M)E}r5;9%3fj5eJhEzt?qLG`wsfbZT{GP6Z!7&;E){uo@w7#!Jx zLDTxPk)Otl`zc&|3~zeexM|&mPI-MqObau@Z?iT&&EvpUfIfXEc28&%XD7u_#)3ku zeQ}d>d`T-8`3Q#c3Rk6r*L~zG?C^Va4O_-=#FAO0O-7v-`>s{#+T ze-8W<@`HVjay73^*h~Fx3IBTn|4hd36F78+=A?E{tJ>31{j8@%Z)uZnRFV@NDD0?> ziMPreY}l%$9HyZaqi5p=^W4v@?U{2pnuV5*&xhF(U6l3@cs(F}EDlXr(r@ID2W`Rv zu*!LIllzUc^XbT29qP+#j7_1nsHGtgZsU$LEHKU;=Qc*9d%{DoV|Mfpb0>^)8yAH( z+OQR$?iR~`Uwdi)<%9>?uf}?mW>glk?twE69ag14)c7;BQ}cag@E13`&_>_xq(dyN zJ3-${^eIm7!ul0U4>Q``x-&YQRY}6%i?f$x<7tNVtjeokHb!Om^!1_RID@$ais+wd z$-^_TK#jpoGqTu86~d(hD&+Nuw$pEem#r)qk5q#&-mJo380|dse6%`(%F8ht)Eo{@ z^BXe|vmQV^<_nKWGcUlpAPX;h*}xxKj}FJD$+3Me%^2>`!fxD?hd7d{Q8OP+4%?^l zcmIap#_U#1u;~yKnq-hu3+Ja}8jG+JQ{BY5nlq`be!8fE1_SdgOu9WrDV7Omr5SWo z1;fTqZ2gV3puP^I?zJ;>GLK*_$rB!K)4%6S!C4Jh1orA%^o3op4vhUvu@LOZ`Z}D> z7J{=rb7yUakHcx4jC(F|hxTJ-c@~!8q=Iw%WEoI8^hVWSd)cW@JJltotdyE@VF=Z5v z=Z1UTiz)4L+QO}Q4R>Os+(TZ9RTGO@u($a4CK^zCmLWo%bj9PGxG^0=Z9O<>OYs|| z-hv3X5D{X}NnJE-_^D&Dc~pq4y2Afp!0qNVa~i3+hZnllkJOJ>k+FI8VtBgoh58Jf zc0{}%UvE)s9zrsz(@wSk8-fi=<8jY~-|?4BN~gnvTFE_Kw30hBhJ{neM`ISfyMr%l zozKP>?1zQZB^c*lPEZ;1r>~=^%4chV!hWn?n&D63iuf@MvVZ7+9=_>gfaA$O&He~Y z)6V`DKR-6l+9%tz(zKk2dG;rm`RnWB=gA(19b3+m@u}fMNDz}9tszfXdmitkd3^cr z_b13^qLOJEh@~vt;WZ{=Du|VK+O;<8K4gK$;~3ClYqzo4R67~aK`Qfch(s4H!);jA zM32WdOM@9Av?hXeV4O!j4@u!^t-b;KXl*o84gCgNGwZ0q)iqcgFmRr7rdL zID&l$wq5D68OP$VZnF|PtmhEU3lmXv%-8Ad7Gp9x{OXAGr` zq?GgIduUM%*)U+oZwKPCm4!c^G>j$ z1p5L!9%HRM&WjQ32J~3G2sMMzF%t6;wmCp+G6&7i$lQ!BPCeN;n>K15hv_0>6o>Gt zTRp0$1$NbCJ58&8GW()mFoSBq{w-MB8q}|-ZS!Vgp$5frDy;-$9n_9&5B)@|k(JaW zpMnX;_#}g(lXM!LJIA~mM$w9M{cHFY4C)Dfl^nPWDJg+*_?sHI4u3lYE@tMzRzV?` zPVB}l3Mu&tQifBG6D=uYC}k9-uru?L6?$pYH;+=XL)> zItoZ`(9+V(I$V@8-jc$sgWcn{q%iAXTK-W^L2)LMbrh1cbL5nmQOu*1Un~vJEQ+PT z&s!{tMhn*O(0=7~^GX0%p@&6b_6wKO*{^?$ESZ|TS0&tUqG(mP%NL%`EecjL;xy#p zp5X03;}+#3i$bx2qk+a9)!37~NWtrY#w}_-Srn8GW&({{)O@liLeB$gv8ec-!a*}< zBiU05>Ef1TL|QnaP=BC1EfHkrY$Xp>g)otit!ohCd$7egh#sZD zD#c-XngS0;+)a-Q%)lbjaLk_R!1aRkV1Kr?iu-9_2+OhQPV?6F%rI$*I5RM-YTl{d z9wQwmtdSm^#N$Sf@h6DArvsL|v9M@VrhrI2@*Pe`7D7Ev|*X!=mEIA)4U#qzToab3FC&~ovN%O`AS_(PZ^ z)^fm(zo~xggdse{aRU5BTeP@W;}~5}EN8LE`(*caA`=`g!0kAk@Y!)s)-F%D*GT<* zcl{4IaCZQ8)a;I}pU_GlmfFS+a?;r{)J+%j9n?PJ*c2drQlCROuP)w}#B`!%*6|G# zeP^~%9E@MAV|GSl3jWlGz=~UbRF@n<5zGn{lcWiv_!r?NLk zV?FajevHej_SvKlPgj@FnLBAglVx!YvM?_af_Kmj`{~bCj<5CEtKL75 z$?lK8$gtOM#70Np`uwU_+SMgr3gPU)8tydLZ{XTSpe-!`qiIOdO>`fvtM>Wyt`2JT zCv0AwNh@UWktmI2wHpoYd|@T>onLT)v)+W}Wm21oU&_50;;!nS8P? z;^}yI;x5~~>U-)`YRwF2oaj>R_owJCEW0M+4YHx5pCfO!N-m#f+q#yOn2sod30(^; zSf{RFijxJVZW8xR1qZeVHjs>&sH~fauny=p(q*94IRCsA%^6#Ny$#xgE{^ zrF#D~j9hBX6#S)r$@{alrTxg;Jjg7u*HLN&*3jROFluO=SUgCr*{t3_l1ZaI7kz=f zmgK}6^)qi&8~$*UamMOqF$x|M!=MfALk=t->R@c!EWp9nt5tx8{kDS8BED?KOB`2^UpU1;$O=n9=BE&z!RFB*FR*ra=GrKgjmdln_RI_9^3dL<^p^9DORT7 zcz}F>1gl1oJmwHVFHk-}0xdWJ6w{U9)j;_G33MKX@+e2}BB0U$IfzWHdli&Wq&WVp z52*1G$K$LT3*;Ly`e7WHfg+Rr%tv>L*-w-u$uq$ds9p0fU=c?k=oUF}XCd)6FtrV{ z)>EVWKMvgQk(-uT1LB2BieRS7DX5Y}+&j#Yk_hRu;=I_t^L=#qag+#o~9nh~JlB*o7he z5i=Gtr0ht-kX~g;vLUf}Js&Ix)u9tPqC~uoW_3}s{?Eqi%qUod-6mc~?Ij}l|Ifth zvLRs^mJEp%txde%rf5~NA(3&!<8?GRHzYESc)SiY?v4uM@jB4BAp5Xi4Fo)zth>xS}pzMDBFT;YL5=@Ju&9>-Q)$rU1VB{NHH#cLAQ7Mig!! z8aHNSM3?`H;|S`?BN~osWr9Rs$6`*3t-jW{G$#14t!ywFsf*(pPphB9XGeZ?V0X-I3dAZh;vsVZG$Iwz1rW70KW09GToUnQY(JfE zrZ3vJ3AN0ZboGAD#8bhN*455c;K9Of4kTkaH1?eE6pRV949}huW{(N;WnIGk;n<0v z!vEcgp8|g3hp+VVvy9leo@a*86>#ERZ%}J?z*k~Zl07M0a|sPaMi8g+j?l?qnvl)I zvKiZ)q4Sm)$Z^&I&n_G>S9~t;p};Ae^%x~-o*8*gI;%h{`lGTD%U|#!>cEqnm+78i z4oaTUi|@04i*^045#V>jgSJPJKYL95D(Y}EXeNhn8#~BuoZvE_*i3y)Y|^7I_Cx4R zAvN~uF(0J(Gy@qxT#7Sr4jAzmOwUT%r^nQ5!UjC?fTYyHU@=|)M$_rZ(Pk7eHoj=PeP`gxIG?Jw@NbZ8)#_o^u7Y7pAI*&A-DU{n*>3jS#j2LhFUl z?>WYUav&DZ*LUOe5uPaZg?1nH<1H=R9Q|2e;UsVD2vVqCv{OS~E_#0}YPm)nA5yEA zL#P>gi&q0pk|I>3+p(%*&H{?q38hk(?gX1Zj5#PhlTl9QiF5Iza?x6Y$Y8PJ8D)DE zW66TiFAx(haIw?n=8tc3;hNFU*^o!?`amgq=AjnxL=pDQM&Zo{KV!~L*6~Lc{U1MZK`UU6M`H z5D4*xaq^EIp!gKe3%16dpTGl?M?B#!nA~DnC2K3&TJmP$*}mZpa{=btc!Yx1Q1lty z)CUdlgl5=n&1r0(8||+dZ?P^G-yQPkN7b6eD5SP%J@rp%scFcSOT3nOjpqxr9VUIfp>8X&p>+_n6O3btRUPH|GjqmNG)hbpRoC>Ud+ zY3z(pHIWp~oJQCt+Z{#K@%=nH=3>{vqv5OI;~cyJ@KleEQ$ko7ItOc<)Hq>?T6DM5 zxd8Jqrp-IJK*ZDHhh?E5>9AY1ld`-K-+MaK8!YffiUX+px13dg=xKG$V@z=3Ef)u2 zEG{s3{P2~ytrqEIq#l@9xd%H9cVirwhY=}Yo&$TNH8Ey=(S@vFB#z4Ul%-r#$)`_v z9fgz5Uts_89Sn`}@-kbAKF=ZeU-GX${Rn@4;WR%_DLGS&g*g#8`D!OMZ@B;a-{CPB zcryKGqq9HkOF=z_7q^~1efr4O9*tL2;iJ~jdN+3HwNQOZIKwUZ0|!qcOP3+>@GrsJrsubZ2z<394GC#F#K#b}aR zJRcDDCDre>zgSfTFXvh7SG}8+h%fY2vM=lBHHs54K?$BL_v7*NtOL!L;(bz&f7?UZ znEEjODl9!`KcW;mPJ;JDbj&wyMgPa?LmarYYc_ZQ90!HxA~%Cphf~3UU31%OWOnm< z(%6|9A3N0=sy>XL@{xDZe?Cw&c!+XKV%mHcXsdxP-= zCgL$apK*gnZ(=$O^cize_jmV3`&Op;jGJ+mc)0y4Xb%0fk`{9a*J&k6`1XJ3;f1}d zbms9_VWNly*ZvE;vcpkl%ul#CdXf3(=0`}C?GZ2Pnvc7&g-o3VrCGFZ2Y#v}bh0>; z4#sCwXq8Jf;-ckjEpV-x<#86MS$=1cngutjWW{ihEDUvCmuI|ua3Qgd^E;HV7m4+*{P)asKa1J_WD~mY_3>8r^9=uang2Z3@iIz#suTP9%Q@`lAN*%I|9ScX z20n2q`+4LK?B_}PiOxl>nu}4tWwoJ$d7;)m>JlvPp+Ba+AHh#amsOgrk&b7$2)hVb z#`Od3gJ7A?LVo{^j-GCNf3!ne{$t(R(wp&5G|2M4LJ4I0MT@-0)7z%MBlG7(*bC9( z=W9l-8O56AggJ5rvs<_MDxk;vtH^NSegZX3(}i&VUH4!J8S;5_m&IMLY{=Swlp z7dhukX9-SZVSY@U1%k6G#yN*`R>3;rC3==P%LV5xF-}@vM%l|`&iTZ7hv4iL<2*q? zc(7k^vJ%})oVN`SFll~L|+9P_g5QJpGE?XZ3+LjF?A8q&8y?| z9neB)u8z~i=Yft6We&)NzBU48sYK6-(>aXhM@K2WGo$H9B=wt(skSuYpB$%uPA2+_ zIKA^k575nQ2qyk|M!z1XpJw!2(6Yb7{0gUlN5Re2p|+|cn*OMh4jyUx19-6vg%H*3 z;Ws~MdevFLrDjz-9k^1n9&pkMmzwpc)5U(DbQZAR=bT0C_Z4S3`$dGoe&2J};#YEe z)lL(&N}g{&W_N+Ju}>OEt-4+bW@*L)EDfG5oz2S-!=fT;s;G$;t*?U|Hb=vGxG}l@ z@KmQ`%_bz#T48vY7tdFxn2XUpj4|10!e6nJj7Sz!u0HTlTKG|C3yFb~jX(~?RhZm; z4;Pze2Tp@wHl@>Ww;Bw%!susKU^go|6y8d|lwu zoX9&gszNl%hX4%cyxAMw%y}<>DYPD$?x6FT^ojcu8U!ws|9qoj1=O9wYSH;?zE#eFZ=*KhRx>>M}|11Cie zm=BU%noexMTVo(3r`5a)B?N>MM`|_e_jqnr({b#IUQ|_{hLhF^1YCB^f)ER6IEy;Q z;nxcsc<&Zo4pW$kxh4k4dD(_H*Ntk+HG+e%6L|?>&9uKLL?hG;;FR4UdQxeS5iAfK zg=U`wM zA)Pr)(+ht=RnG2hdmpi_0h_r9b&Cfp&G{t8!W)lIx!4DZznC>jgX#Nk{HX6@(t+1^ zpLl%-x&kuSpf`%juGtDPIPZy!rL&Lt$<#FiZ$>~gUxGF_&eOvEKJ;OQ z#9!i7ZVIR0m#?e-k}=B7;Vuv5>s@0{Wj{Eb3}A9khW8y8|cM=R5dUk`@(Pw4ctar(SSiIE=k-k3-^Eww! zg8DmxiNq#D-q{YHp+clBjYKXiXIfn!+KA_opFHnL$fxXZIuW`LLg63iTnp?bJ)NtI z=h%%$?Mnf9_0h?k?FJ9HmI2Zht*yfkWr$ZrMeGBE%0h(UU8Da*YsdUe%=mG#JN70? zbO0BEEZ8nqQOtp4#pu$Q!=(k#Ws{;k$v(q_lUHCg>N`hs?QuL1((-Eb4Oy zP4{#Bjw>}|UZGK5(EJvi%M1_hf%PwVLb&69P{w0suOM-2MT z3~;CxI>I~t0zI)H^^a$0K`LqP+2l!uA3!{iL1M#$v)Qd1k?9CjOj%;%rm`15?fQEi>T3IkRn7wuaHyKgg?Ev1eS!T8}oGb(01YY9BF zSB~W})XUg3s+aH0i=egW^wsaPq%oMY<0wde4bH)hc4~OdC*E-~)PeVg+VLD+rdoYZ z68yTl@|v9euBy{6{{B)|HP)?5kwA+*nY2#e^s~tWmUiJTv24I5Y*9P3N;rs6E6#bh z0&?po{K*rXg`tKt+@Sf4Kap;y&}RBtjQMY&1ejMZeFPccFf^qt;ufG*&jW@v7GfdX zhw>cuIGuPg6f-;M+XopKZ;KmW zT|1J?#N5(vTyQb2_0OPVkzb$c%&m_mdGuG9_KWWE-LdpJY}d> zpA8+%{ZES}%O)x^LJPH;Uf#q`wHMPx30iA_7w@Lv>!4#Y=m5$fA9T@-E{o0HWF<5} zLKnQ^7kBvS4z!HpMs;O3JXpLDC;c%sbkMp8UedMOPPeKx^!y2{>z7ePH=cG$_Q&hm zZFEMIMb#JO;T^^= z?<~j<<1MPF$b#qyin?fg<$lL_(n&^+sH~fKeu>%^0U7lL$s;A~jr@umt&1uRIJH(h zIgD?nHz#sCRKQ`d9IRsC%tTuagSxaR<%~YV6n7~GuQ=T5 zK$&krCBiz<#Ydw$@Eq{Cn7&9Hj13W_T*p&fECo9tH`=I)3#f?;{q%YT54@)L@1mVI z1iaMIqWlG^F06}9WjU>9!rX`zZKerrk=FsJREvBTu_StE_EVnlB@)>AbR?#8CH~D* z-bIQz7J0?}ue84KKeMWUw^=(Kl3T*^00L~px=m<*TDrix$xf^)WPn6h6srnU2Rr{k zY9r`H^LF8zA$Z*ZUrsQedx{LfrLebo>mRdinUkZ)75+xA7F)E>Ww&_4TmZCL0nx|` zC(~iMu?xzaA&%HZCS8~hqPynPlVBH-SUQ|JPV+!$yuK(V)_LJqk+MD}>7pVmw4 zw_>;<2bfLE;hE-9Jk3)R89NE*lOWWC*HN%Xr?-Qs8t6hpsnxVz>K+4A#QD2JWQf`H zA{a!lKhZvs!|Y#&x}eu@G?-_j@l&1Y z#9d!eU!Me1q7%CT4FYn$X@0Vn0$CGHAx5S#w34hPq}2R+8m+iL+Lh%3z09jn3AkC` z5d95FwNw|&0Yy7-J*fR(p|(PK>IkP%1YqfN0yGHx3ZR*Ta$r8V4=2HPwsGi~Aewtl zQAPTl^b8bVA<>K!XD}6`XvRA8@L$;w1AV0N<$rMLni}=L3^HhOP2Yt<2L8@6$b7^M z0FFDZH`WzmgUk)2cH8(nXLIz}NmiI@$ohX@dHzEk2kmgi^33_m@5;md@h4*0jmFPk zeEOIFQ{(4N%u>F@(~f8XrOnr15jrLFxtWv2Hk2 zx}Sz#dMTfN(0vPymATYyvZ>UW#`)&gkD>Ha|vkFiM8e&D<|iH#4t9tHJlqL!UH1#J!1l_5W=9yh_$jKADe~XrC|s zZ?sRw0oFc+?y&*ae{Y+c9%24$-K5EZo8lwlAZmwe%{LzAgQ2Av)SADuZuYxih4(*< zhad5FIcU0I-sI0-fQhhi?o;$%+7|b4n`ytjRwD13$hfh=Dr%>rWH#Z!!ML0ykb~wa zLh}F*14o-xaBw)aSyz;cj|0?^5YmrAJ;3K+Oscv*GjJY;!chEK&?=ON^#R!amrxW_ zc&sLxyI9=>zF;dQ^cGRt;Y+K!u2--g2PI(eyUY(b%j?Y1YT-Ks%Ydxl-zmtzdTx+U zjGAlN{HR%vufL&Fv!xZb44Z*}LgX6#5KZ3F>vyGu)~3=@jlPZl+a9#_o{lHZXaqF! z3vo!zkF3M88IT@G-!l zW*d%PrSXO9`rX(8KY*9LU5Z`gi5cd1u=RZXByPd3=>cEXKE{S;D!celf4=&CDelmo zWb{wv3n_eqtzu$4L1Lp?2c?lAjZnSnF3&-n_uwYl|z*(tm z^Eb2{UJDk_$lSvLxV=hVH|AE3@Fjj)TdwDT11uagU*iZb4LkqC0r<^I4nldCxs;>1 ztVra0LK|HFi?(-xkE%Eu|96uBQPC4CYE;x!qmqi0C|IIUbI2~)grtF2c1*7|BMZ)>ZdwF&_RvGsnio=6@D+?w3DC;%#CNTc`kYl$lJo@?xwmYuhM2di^5G`ggZVgam!XIaA;p@r0OdpL@bpNf>1Qe&XdrWQ07!Hz>}Hw zse81_Ky2Eww(|!jjIgs%jl#0F<$hn{d9A>$i&?!fSHf-{ifpR z>$%+{q<03{CKPt7?nX6L4RkGdw`$02%E)3od@A47U|vKj2pOqWpdbKM=9tr5=1wgv;EvO8xW+7Ha(8R= zD{W#GMfQL@NT&qIAT2#nzk;jIFxWj*rwk?osbEm!?i6Y}3x=soYJ9q+2tMg~($~sd zrkHMB)H=t)z}5@xz$0)RRPENlCIfCF(N9bTz*g#4qT4AU|Fu-{h&8W=B>v%(JrF$AqR` zPV@ez?u%r|MfO-QZU3kq@oD>p#@H`}M?J)4Jy)(nc*KODO0R0~QX_NvWOc2MXLsK( zUPt0if;ZGaKd3hEXL?yDl;gT9@YbN{(=iM)#mzzw-p}Jb2e^h=uGWJw@>kx{kgM|Y z^yoqV`3Io?oPFv48k7;f&eQ)%ox0qT=Lx%K|G*@HefwxXnI5=-Iz(*PwK@vmom3!A8ZTD|;TD~}IY`p??Y(R~7XB*h z+J3!x9fV~gFfC$Q^(g1xRRfT}d8vB-?Nw8>r_mjp355}?Mf+(wK6U?gt_KN z-&;n!7Jac%dYTrg*WQwck@Jg?wTNgAqF&W(SA4Wegg7!_o)+w8+pvK~dXa*$ls%01 z+;WxANXh2AtUt=kw(6-ydIGPjkl<7Jo3p1zvDYdGsZSwfU%1TON>>yz*lXUq>TVeB zDeql%Ht&DsT{N;x32@!tw*&nD6Te*vyq^5ls8b5~ZIn(a;I|=?@;~Rd36{riN*c&K z^xtyZpDEIV+cwj$2jVtK|G(z8e(nqkkw{70l`0^M&Hf zBb4q@FgOOrj|RX)?DJ*;sQ90%C`(z;}69 z@~E%yQU6p=dE{vx!+LU(1aOLTP2s4LuzgXfvXa^avy}@EIylkPk(of#)I3}`f9b$a zi6=9CXpl#bZ_+Q~WXbCniw~e*EZ$dU?AP<#Xqoi9sEMlQ8 zZVl0ctfj=Pep~ht{W9wqPi3ZmsmIg)al#Tm%Ih6n81|(=UhiP%QEC{Vw~{blzik>f zvtJr2k$join5`6DJQZY>N8bSlpf9TaMWv7xTkhse$+j#$`M6UaJzvSJN&dI=te{`> z^lUuSpp$xt4F-kky1Iiw{M)a#Lx0N*F)@+W$B0e zE_z#@Zi-$bvV4@I*TkCYiNlpOWXW)?oN>)Z^<%z4KHsCV5s0$N5-BVO!CH3?t(FC5 zgfMSmYi5n!WmYQg7h136UL@;@j*n0DKk@t?ZoCV(ZeQ06x5|fe7jFp9etpO!S~>;lI`nD6Q^xoUzDg!zE_eMuFO7p zJM|9`E^_Hq8?6v~qUX;%Vg<@AkhTDc)TeTI+^5t3s?-1MPHRIR6!??iruTOYzl&I~ zVR;&ehsgIo46rMb3&xtNn87z}S=yrmCCU957!XXPFgIODoP2TcD$V*-a9BfO2ZFNk zaHnpZT9j;#^X$tUWhNZoC2lKF@fHd!ItaJvLi=<-WDY zuvt4p$LQK)M(9gw{|CGxwToU-Q2S}Bc8m}1@4O7JONQhIRePFEd|yUv>Z^J*Pgk(@ zW^!6vy$WV}<(a4oD|muTa;L}V?r4=Ez6`HMjN?L2ccN_OFbu9d0Q4JrKtEI$HVaUn znS;FTI%ykj7Re2RAzHjioE3EqUtvs9^KbVer7?TSJ(E8IqY18&D_+};8VmrV&`?t3!y zJbraw;>B_^&kFB-119fLEzSFd0@3-1266}GGC!k~JAR3D1nn4Vz865O9(f;XDHF-> zu9XQsr@!fgPrE%yy4_fLkqpvL7^HXp30m64oH4p+VzUh%Pr$#BQV zy~8sP>?4TCe0bP?q*N+Gn)h-qy9R1#`1T=~ynB8fS@4x;T>E^j$bSvm zglAv3&-aqT@5d3NaG&q*FV58+w2zQz(LHN_yzu)W93_S3T; zALL`$xuXWR8)$o*Mxk{d8Fmg>cjOuAsBjpKXP;2afrUJ!ZFH+aayg*`toFsM)l*%XH@Y z!RQEL67LqYW&Vm;mLL>%Y+<@^lPS517+c@5FW8NZIK5YaQknQtOzpyg)GB`z?V>P- z5S=!rF6B9BPo}|aT#n%-iZ^+r<0EX{-R=h1lx_@LNvRT<0zo47kcy~9+=fkV37?hp z&8@Tg-4tOjj61C4l&PEAr}&F>l@!Mdlf$K(+{cC84yDdq`I5C!t8YaFdwJ9%PIwSQ z`}qKoh<}QmJUna#=z$8MliunB+SLN>1H|yEsMD`4tl)UKurcR;&F84ySHoGM+avKA zBlZIoijpXcY%Oha2MHW?L2Xta_2`qR^Li+A1w({>C$I!`gXBst(7l&wSKr#`1ip{q z`{u;BY&p4gM9p8|2c5#!Kf^+&Db!dNvKA|2T6Y&7B4tHqUvM4aHgdu>hHijYTvk&4~&@+UtN#hup648)#C%E z@yW_FH6fR)jTQ^es(QWcT%U3C1{I9<-V)T{YR15wJcv*C(`sXHhq3YpB1@RO@fps| z+y7Ow6AYb_??+^|M*SJ*%$kju`kMj}U6Y!V=nYiiG2|K;U+xM!}3J#)2txqgz*B?u*!XT*D0%Rf|U_Hb0y7kk;K zlRf=<%z0EQH&XaF79x1Im+J@FTrx2A{Wt~9IMmBkPA(vcSkttS$pqlm-UOEC<%p0E z-FFvAlO?RECc*RS-AKJbrwJZ^RCuH>L9E&es%lkM;_~ zW9&72;`Z@MUXd+X9CLmsyr8P>Mhm0OQCWGsd6f_+YU4_$ao*%UrINT0Fk6`Y*_EP> zslsc~(^O$7bC*{bg6YD~x{g=)V?|#Y+$%`h)_ufcNrW4%{c6n#al z-ZAHwqR*+q=kuTn6Ds{QuW_az;rpMK&CmZP_nfCJQ3;b3^ z4x^S7EbWkg$ehftc8Opb@rPFfQjyz%%~M1|ifJPAQ#C!+2=__H{ziXG|4tQ&1!u9PdaZAf6j*s2E-h%*w3jcvx1*h-e6>4x)*pKe=Q%c=SSv;g6~z{_xt4g zD)0Lv^pY==K%{E9l9kumAICZJ!ZdWijn+BTC58x=}R6Y&n%`SXvcos{o5a}V%U_2Uw$M}>3(+RAe!XVv=>m|=!oELr12_|Jg3%<3-_ zmq(l44OQ=!C`d;xOM&cWmdn;FTskk{em6^cE%B_Z>~B{`dJ9}Ob|R=**$V**x}QG3 z<;SYgdtoAGzbD2x{idUZU!Z}YkH9^N|8vtY`C*{~YP;hh0;$YgMac^1_e%=u5Y=kYI;=p+wGSIUNway1M@?UlEZ zfC(kWS!DHS|MD)$V!ajPERj6Q$vyXC_(HC)W5RsxF_TpHYiJ-TAqwl14@kjW(U&Ff z6sk#vhWokgp4)JrV3QRyhC74~Hmf%o&Ln0I$yt;*B$8ZO$`rF5p(hKM!#nkOkfSNl zrm4e4^)MgiBS%v9Mq1T6J6s$JN1b^niydL@KoZ{6CMy^D506DLY<$=ifk3NBh&ibW zS#3uv3BL37iVl&CI-C<5v79lwviL&54tvLuzqrolyWj6VeITnYy z;JpB0*1(VEWQDu<#u#g(6_=ZkPL@MPT7r|t@JnIROs)1J!fAE-!gMw3MWZXQD4QgXNDpwXg{_>80TTwPKXqOR?l0%Ms z&EQy}jIwaN8jVd2=gy<^@(M4cHVjd6)p6W-EC3w0nwn5k6YnQ?8ODv*(w#z2nc#&K zB0S|kag47KohhtTGly)_^cu|fL6|bEW;hNTi*sya2p6T~hQ7!_6_^ayudwx|I~b<1 zYQGd?)r@Squ$A9EN`2{)&7XoVi~a5%aIN}U^OQFE{h2n zO2VKSSJd!T;OZ`Fg~9#rbl$@Nz`&R8=1W9Q)u21G!Ga)oc{ZIbLVQ)YX;+vfL6}vc z`zPHo94!ZKwlAQ&>ff5oTsTmT@yz9vn#?!pr3&VCz+^Qrif<&g>%`eQu}UY7 zU#@aC>csv!QOy6KRI3yF20LCG#;eg!?S+V*B`;r?)H`lH7UHvZIq* zPp40$4mT>EO8HlLpeKyd(r#NT-(=7q!wa-+tf19iqlvkMapZMdf`1fTM zph6*d=SEp++u|~bWmS&(GjDCGEia{vniMyM)LF5p6~jO@fn$eag-g`wgM|`EOf5(V z&I9NeVnrPSn81|QG)#oLcnS{Dr^=QxDtHDKK*YQ{^eX8P}p*O=O;4L>k1$ZyM`3yfHaVvuk4?A4i?5<)|}(g|2}ZPOm7nh^gaw zB-%)+(Fi^pHG-RD|Ke@;;wwa=E$XEXCG)efScM7E^Bc42ZF-$c%Y|PG<6FHfE}*-y zrbN^MV~LX|Q~qUP0=)H9N?blkZE|SLE&sslU$NP?4I6=p)*10HW>wj6*y~m!W%TSX zr3z+$ITK4)NHqnszt)?=u!e}vsPi`+4+Md$OgYc!mFC^=>%JM4KQD{NqB5|!jasZ3 zsqaz2iic!I+YB2SsgDGprEZolb+`OW$fO)N69+NSC(}1At0Ek)9Ug7%lA%?#E>?_q ziZ~15xE+yAeJJjWZ2D1l{>)!=swVZq`BKzGj__9uHR zROB+U{RojLE z*h=)G+E|IekqeaL%gp3ne>}=>QT!ByDqt3D6Xv!LaZmS(3%{FU4rU*5pDZO_mdC$2 zi`@SwNc^fGi`ZmWy7cQl;2u9{N49Iw&`yJ?*sA-#t5 zVLCnR&erKwU|j;%mr>vHn==a)gSLT(%=xdT)dc%qvtr)K>KkJ7PvyGVVb>j1O-TL}>1NUExim zhNx$bsZ>5MHfCq&P2isF7_QeHvd(#x{y=?*qY$irY%tkj7WeK;rTd1?RSo^rebCD@ z#8^Gpe0VOI%*xLaa>sm)-+Xuu@1e?$L@Dp#BJLRp$tBO5@w{2j4I9Ixk|6@m`qV0R zuSceGWsg!0IKTW2{>@)rhM36ST(}@|0DqZ?sKERA94&z((6|pmn;ue8)1L6ry(4T_jK72krd2AufM0{^GhJiglRn$ZNbxHvskts_oPg{E_!Uzi`fHZdjC zf2$X1m?>fw{Z`lj5wLRoW1Ke7KdSjgaytyrlLVE@0wU?zQ!E+^_9*)=Z6qrw&%joQ z!1PZ^;KpGh7PGVUDlc^3z>1m_Gfx+9ZVR=ASykD@O?gMO*_zH1^?0ah+jD08#7OdS zf2{gBRcb+h%EgZ+a`~G&GRDIYe{Q55Tkh!iqBID-q=QOoHi21&|g$3H+n;{#8+1wK{z;QwSg@&*%YC!sFEV zWS{*wW9j`^I~w&UE85!;aL z@COgtRMUPg^9|3{PcFYdTFE(=m!z$tXpfr=sbs5~(9=f|oDsvf- zK(eFM8dn~(kBPB!KLwA?V%9~CYF-Go_Yu8Da-U*76)v9WWk$3TbE_be=6~(qIiDF| zVW9JM*7NqbfDZ36G0^$TmQ|VKXj8#_k;CU4so|;v;WMiTJ|V&h+#)FH@$l_<(B~wo^ovd$_l5hbj7gWRr`I$o$C=4tDka8 zoDygqA8jVP2zzuF&p`}v5ZL5EMbN54E30C?XQYISqIU0O7n&2c|8s?sbg(`RaxWx$ zNT&ME!K(z)f{`JsL%Jyog^p4s`&Yy_s(oWhb1`$!GSq3K{K~gRZ0*phhRO>1VQqfC z=DuI(asmA{F_1z2z%^~u>~j}fj7Iw>w|}FMBcK0U{8KCF^G0>1=$rh(UzYv{ZXR6j z{3_0g1a=YYxU77>RgTE22|02(fC$-}J-hM(sr$`khtulg^t3DDTJCRkGL^i zk49)3Yo23-Ua=%EWf11#)g_IfpN1<71!CMte=2L96^~2vvx^P(sP~s!M*2)G&+W^5 zK<&I&^)vRt8i_?*4;)z@2_Kf<`>lx*N)n+O!7{-gvieof zg;R?{MARyg+a`*+>Zx?W(Cr;1-UWsDNF71m*(KXMibCzPD*74efb_1Amn}8npv>v2 zA~9pLUl*+CA4$H`6=8+h536WZ*Jx`=byutszmZK*KL;)Ma>%myi|}tcAMwVUC}#mc zWqzpPm}iy4R|&WZS0Rny zdac?uYvT=kCn$W&HNIj*vx8OWB%4NC!DB#qL)8CjwDPSizH3Z-YKaM@`q{Ipc8|1X zRqxJ7Op=hjv?PQjk6>YvJmr|(oi`Y38mjiTjInSpl{2Q7CwCs4h;8%{D6uTq zUhfatjU^jvin(6!b>o&AqB7R^Bd{U2J=brG*x~+RE8G=6qpnfrGcEV7((}}R<4uP5V56hXpvdv2PaOA-jgtry|vBb}OKI{>z-#&}069+Q;l7 zB|Bd|rq+qQby5)NqVIpdOhgw`E646+l2GR4gUsMME6u6*7CKUVXel_h2dnx%}c|A0XCk>FQVXOEK+47vcK4* z%H0TLN_O=o`o#R8P0YR(ySr)8!e;JIC{a(7c`8*;7x2_qJ=O74rk+Od)K5K~9kiN# z*yT#9*3qg`o4gXs0p%oG(a)Mt0xhhi1P~2zv1hDb#xL>~bQZVd+mZP<?i0|?&Lyl^H#Z&tG2h87FXfyJ9mFUFEDrav#;%k)xFVJ z!<;Qml9>*MK%djIZmxZKzVOz$zftR4XXp`=J$gzpZ>pA4#%++v=e{081>e3&p7mxP z(ckf7bFN*B?qBKB-54*t$DpvNa9vFrhDqcTk|$ zzDYcM=zqq6=zm%W-)+&?3yQ=4J^JHC(SPCo0(tyR_J;S#mhXuR4$u=9e51W##)XO$ zWqK9I%;7Vh?O|#_F7{l#Z`S0e?Y|}$-KBzHNM_$d>Qf|GV*7%1ESV^KmrvpmHyR{>(fLxnXr+Ia^@Q9ni3^ zJvTQ#i^uFgK2_|EgD>$GuyO%QLEIXBrf67?&KrOxqZD8xIR?e7PzjFO-&H1CNtg8u zYuHX@fSrUo;(kE)$zeZxaOaU)Zs4e6tUg2KkaI^h#%gY%UFHuYK5%c9%xtz9k3CVF z9KK?Xk!n1M9Bq5fFj7&;i_O+Z_v48zC_jt3a$gPG$E(j^t;DxMMyiZ&?p1){l3~IL z0sINMTDVl-V!!}UVKAeZ%iTvtiSoFJ@Jk!~IH0-5L3HyWR56U69a=4r+u0Fl;{Jf* z*LjlgLGt6l7@LVKR?|MPD$$Ci$Im50;2>~l6?dd@pky_~(3RKuOA~(=cl<5c2{bVoY);d|>cVt{CBknp)+q|MTu8KB2ll@nh7u zUr+xYo5B~lgKyh|m(aCXL!Wgg1;rYQ$%857oS6`oJ=Jb3^0HdoLlx%3iuj;1ASc_o z0?tTZh-rk;UU+#F<8vkh4`wlw)$qw6%4%(|5Y1tCX5{!fC~ zUrJ49Y;QBUvDh>s&vfi43O8je&WZRr8T+Zb4ptNDvI+5onyG}|Wx>jIL0jEDYOFk# z3c|OBoO#`0|C4N$VYF@Zk8zeHij39uMQlCe-_>_@ozrhjtuy2%zSb9$FhA_nm()4^ zEfOc8ASW=OC5pn;dyUi|X_kapts(DO{2T2jp8&X+mq|dqu(%FLbxz*}BwC}KAr}Hn z77pi#83P#cxoW)9&#E{_6WI7&UmA4!w;8KP?({&7-X&m0IsNC6xSPaZ@O}X$F5Khg z+zZUB`O4l( z4e4KK4EKZc`ZuI+AU)_z=%!Mt=V(ySddW!r6;Tv*Mi+tX;=Mj2eTOtg;Z(#xdIr>q zaW@}3Sc(r|TH>QT?un*zC1*sg>7AHMVsA+dTYE{|6GfLvOd_#V=X{IA-E6!ZoCuM4 zu+I4miMyz_Z(=ZseRWPr+(~7JvHz7^U#9Ef^InF?l{<{o`3z&$J59p+41kv8l0kxT znie>9oEiHkN2@L}tqsJ)rvsk@U+hGqcSn+2i>xP{y1gyp%N2r}W^xy9xWdUi(Sc&b z<*7J6kKdB`cz%1uhw|GyE>^}oh&?T0`$_u+hOy?F-P{)k@TBW+;jmwND`3bzzaUvj zW??0=Us#YX=dvEr*(Vhwi`gpuYn^>`LAq2bR%wY8Y^3CpRJ!Y$-E?Od*1cwLVtz|< zIj`2!L1*6H#B}-E#p_p2{hq`{^0wV)y%cmBcPGN~_NB106W*0LSKdDNNxAUO#6Wr5 zCSaUJJ7UiK&lATc-BOxZ#)oCQeHIbc7Sjo8{F>DSQI_K$b z&SNDIwEJ=hXz5Pz`^EK>c*$!B_TJL*Y-vl!-}(0xi*H_-<&iPNEBKjG0V67_Cf1Wu zrky1fy^WL!1PNi6gzmV_Kx2aMDLa}nN+dt*gS!ml-EXYCj4ZOf@&MGrUB(-nc+6a# z+*=%sovXe+=-tK_N(r=;q@kt9=)8)fxVX=Ixs*}!?E z)jyj}l1xb(l}}ru(rDi(Yj`%_bd~lGNvp_$lYBykkzTf7^;gEqyTLi)T?aHEX;dJ?qEQjP$KU(&Bw`5%0InG1Bew?p#~UwcL}7WiG#yB5rxD zOu1#9M=;M5c+rnd`$YM89Ur;gc@i_dn>mI$!|KJc4s#rcZ0kmU$%+3tusv$)0#z|zI5q!-E!KbicdFI3e zfmlZ?UkAj&d}QyQE#J&s?77yS%tyO1u5ATce*KU=4}zDj+TD^6#QU1H3RL1$#Q-v} zyOsKZ>~3w!?ruHJWL3Dkm5t0M=~>(Ae(Q9fDf+(2&06WN$mf|;|I8yiaDL3WR5+v# zzIhf$nKl13*2vhJ%MgSE!hU&ql79NAXU8NoqRz7s;m+K+_~h>`eu{*OA;d&ZdXY_qM#T9y<#NvBZ0AD^~>hyS(jP;ly(K+HdJCGTu?-` z-eQFS!>#`~fjCj4;?+b22#RrXN37H&Sr<~>M9TJ38C5w!d?BEEYXrR#eQ2Ew+mea8 zm|!Y>q>BJVN?Wsh4dEINU^5pTSl%JKJiCK7%P7bjG*<*Xs2P~USn-h&{-y~{j5_) z7^ic^ZwoX3-j*}VPUpO7i&bPAYm1}SYq`&L@+r)8X*vt{BIJt!k^A^v`N)Sox?n8< zgU9dAel>0^1*7c#2|3buqoC4tEIz{I_W5w~Qxw?_IZnd{6!$c<+JcV|aAUiIxbyZk zS9I?%0B~amVAT3W$WkL(7$=~N)N4ox@hNS;fCh(%IiCCoU^{%q${BnK8f(9Awmx%2 zk}WQYsJsnY?=(6xWkLUEEgd@!3RXVf5^R07e0R|Qif9;Xar(KFF}E?;y5-t_%5J{b zFu5;R$`ywyKR0J?x!u3sSj)vZFSM?^qD5udWpub@EgfA&!OB;H&XBf{e|xa<^W^%$ z;=qu82rVAfV~cU)Su~-A&bd(>263|EgdN;>mB0OPQ=MEfZfHO|P_YNI9b0I}=hBXCEmXDkN!oz}*!o~=hu4msv;!>7 zjxO5qTxjOD+sP{#t@W*&y@n{#Ko=VFJPol_L$)Q?(GXOm?}3Rav7{A>>40t*&AAfN z3-xY1Nww?q2&*XZqiKgF-!vTAq|RJJgIZS6kRdc=qi)F8+@=CT-9kP=yrYYTbkUG? z(vbC#ivHU|OE#L;KSQ}5=`QS%ouQfQX~}wW?hLhVl7^63LCv1N9=)+zdKmD zQ*{e|VTOn+aPGrj-95j6VR)iJl1BgNc1Zt(s$UIRuNW(D=fg;2ZONq&ZJjj2w6^H3 zaLfG9=>|MU1G=OEJEgDJKIP#bY<=GAiJthIGoQNM|GcsGd4@&n7Ox{92|U-alaAOK zbcWxgP~Va4pdV(Oa`2i0a_h+RugvUN4DPnCC)Fnoy*IQDNG9n-EEqnNa&tm@)>3ow5F4dvCS-l(nPg{jsuf zJkQ?2{NW7!iz&3ry1qRw7p-IeW%ExC6w36-GQPj(H}Q^SfiMHdC>EFYqcR4Z{z(SHp{8=OX{c z-h+%aaVA4_kERYY`KdqZl+>9WpB9DvFOPB>s*xlg`O|pjAc&0iXBnJk^=4xwM>G&n zYX^r~-_nfym6j}fV9ZX|{$IcnyABFfcD96Cca`rp39uCOcfq0CIHnnD{iJ{oK9&)= zhY`6aH1n(5@uMc^Hga}_TEEu3yon6LF`r1zz3}qhkh5$stLD|Y(TV&FwjUd8zmh-K z6yckQSY2NdtbV?IBvz*<;aQnEV8+xs$OF?`GMQ)Q^W)Kn)(kLPpU|!OG-P$EO4YD* z^TTpmIbwYtI{QEKDQF{}$6}n?_gZ?+d8*GBadu=Z*VbRBZwgA4Y!jyh?W=J(8q2NqKh))3 z4xY44w{RDnD=)=?nWpcR=R1ECrNZw?oUA!?Z-ijikNI6Nt#e z;Vfdb+)+YQiPX&DI#J6nC8I7vMu`}WFeQfCi;&_XeA*AoyqGJm@Tl61ROa;Itt4mr zJ6I7oQ{sPQ%D)!-iOC`Es52rYdpEa6n_dpt{eLvp89otxt2)mFPb3h~S5T*s zg`Tn#Z0tQ))xM5JywF1&9KKTOn7S8H%*i1^8>5@F# z^LcL0=lPO6J0#C`$@67C&%Asdv=C0}X5RlY+n+3`AQcojIun&_S^bsyZR@!`=C{nL zOnbTS;x`gtr5YGJZ7h=>gESL`m2%(RnP;j=@@#fy3MR?SJ9N1_caS2N(CSMtiCEh+ zhXS10JhPO=s=POmFJgV3`2+9LAF{t6w6B=K!TzO{vP89)Uxp_pE)u7Po3^_nvg4p5 zJ|b+5xr~2}*322X9VCK0?RAF@R)Zye9G-fOktXhx*yN_ZN1D|kn-OhD1m>U$MV5i&`9`Z1QquOg14Lsm2E0+E<&0<@rc4Y!<_&kIcQxIJ!BC@;uhGd* zNr6jrfw~Lji^SxZsz3fA$B#Yj8xmqo0-t?|tiaDXVtu7XFSm?7ASq4XqsvU|#cIr$ z;+KmP9`i)}4=hx6gV?~&j8uet#HdJopJT7SJ5GW)p>o`w5JriB_D8p370F^cw8!lx zd3=%|VXco3qO^v$e9Q<+J%W-U{qJBDLLuMIK$UTKn%ApU24rN z2{)agXvQX6keQqr6)MUBVQV}Tg^=krXbM<{%7N|ENM;@&Nwwg2Jb2^M>04txE%9!j z*70u93b{?BIK$SGk`MOLbQ$75bp#3Frmci`91t#^S=#w)NFD@l`XTEr;04uclPYng zb^}n(YiCA^i@bsTwhmQ%_8rKNj(xVmg%0U)f~fEdQI!4Y0-08zC&-Ys%38=&_2AD5y20JO#h5qAu|2tro2fw=S! z8?*0tiIVera?%Uahp1k-L6z&=NQyO9kAI!=fQMJ%dGUXE{SYNa>56}M!QDMfmo5o% z>W__IX0RHmp1;H8uUjFtN+hY7EPa%aoX-GJ!MBan6+Ffm9=8N5&fuQYQRYLAVCTcsr04H$$`#=+4jPM4p`I$OlX9?B?eWpDg`UQ`&>usq25b#Rkt?iGs+jyl>Q33HylKj#$uf8#31`2|+(YN!c39+^-U9 zgy9raZ3KLX0^OM<>YJ9=aMk89iqCJNSeIV(Y{9W zLW#37Sk95dI=B(IADvE*B_9uHnG?TUe7uM-PTx$VD!D+KSoqL1^Lt+PIBHu`aR%Kp zr2?Okd!&_YiRtj;oc%k+mpQ@H$Fhu2zy*s>!4+s$#XwG+pOM+_tt-S9F`UNSjy8ot zPMAZt192dibCWS>ot^oIsEzplj+i}Kwf8^xOnVBc#c3E>L6BlQ-|pQyFDW zscfj2XH?!^(FUGI<=rY4lTrD5HFS*12b3f*D)n{j;$t58rba7Qk#D+R`&TD_OPhmy zRQkVn{x<7|^|z9qZdlokrtkF<>9TNGxM_mVUio_vXRqMK?c_!iHykl*RzA-WYwKxa z<&C@qS!Y(gF2N1-L>+ee-$bCWEqYwa7Cv_chKqkGu{F?o>_e3O+I3D6;j-5+x3{ah zh#Czv74@KsKtDI>@>u6K|D{NR{)CGk%Yq;h-KTC80D_|e5OqparF;-;ri5-S{-Mqu z!o^2%w|gula@A$-kS-BDrD-WJ8VJ6&nULcfN&vMMFdD{n3dWW^jF$saYseRq5*~^) zRyid{vFAs)pef4i$k&bt1*2-+N4ss)84?5%hq3W$hdI;Rg{D)z8H?go`Mxb*2m@^LCQG%+-<{a)Kj>Tnz|U zXI7A@OhJ~)bn-D8M(}uG&@i1_HSPiM_v$e1i>c16C&=+4(_V2GUuvC(Y_(ejMEZ4; z>n;iEa+@fM0Q%IlAKu2JLMFYgPLKy1oq2mmur}@c%i(HirUJ1pq-X(dS%?kC3n*Qt zTQx}+=MQ~OjJ$2j@@qH8T3w`;b9fQe&6^+K`2$y=AR(N-i zBynR|xfLA4cBr)Kb=(|-c4Hu7btn%M>A%by{Kz)%T|W zN>F?WX)=NJ(UfC3ck}m<)ySfYRg^QF1?oZ;gxljMhMOjqrME0Qnsa4t>xp85SSNX+ zO%3H`G5>RTxcP(C3E#3t-022HoxbHzJV3!l{F2I;e1;!qq_2XNBQyqGYL!N1$RyLc zszLy%OK;S;E%1BHoUd$jZ8Qay!_BIQ>O9nBX&9pUBMdV2L7&gNXMpqedObWj#$4@v zzpU`P+5Io6CkrfUUs?l*H*3{2-2E@}QADCIGmnWsngg#7%n-+FmpX8`wla^v|+ zd~y!K8A%&()^p+F+5yS+r50yj>;X#olk{)g`R|QPQ#=2Oh2E}zO0wJ64m0h;g7zOp zejA(3>ZgsAz){ZiEaZYXQ7RkFph{^@wgKj)rug!*0h67-VqR99F}_j@q07#_Yl9+0Ar;Hj7Di)PKX zOUxNnVyt`}mS@p54B;z**=2tvX8&CAgPedyR}Wg7P5X$TaOrh2ci8nMVViiZ$&D)B z=4b5gA#)9^id}B(SRoYggk(6TyO;HjG;NCbH_E=MsdNBi<&}JbS4tT(sY7|zR6IvQ zNpdbv1&6XegP3-Gy;Lc?f+2fZwo1;+My<~jD6h)bj?q<~tgDnzeWlBK$C{pv`Jag- z*CV!HGH$#ZQfEYp6oLv`%qT!pReR8GP|y?*BlWBl(5-kj;(sRQT*GNW>GN~OF@2#v zsTokAEC`oXKb2?-*<*X+8nm#NZVp*biYcPhJwsIxUl?sdcSSxdD~|c!ia8Sn&t(_T zox{d3%ZBU|oXlW?SUi{V8fo z2=@e`bd*92wR4%TlFa`}vd2UJaVj)gBZYIP7qM>_u2*$@Gp02B)8wGYCP)q*Iv&j? zxQbD*`oy+fCmX5vd3JAP=;4TjchUy@jz;=R62sbdT^c{zOvZf3vk`x+QKQ^=Y)Azv z^9A6;(puO!KT@*mZhV-yJW8%U^_$yEE@ZqsAIDQ2rr+SlBkGXa?IojGm~T#e(zfH$ zI47dtidKHerOGkubg7Ngra$1$fEwe**Fj9J0mYAyRomHS+urXQDPa(vCS%?+(u*N- z+qHh~D4fd^Cv<(=H(&+(H+hnOXBTN*k!el!WjJ<4Uo7Vq9Y%@!AD|yI9^*KrG#R;C zN_Y}!b3Z~?TpDL___*3q((9MUP6il;Fg8?k^DRPSk_z(M0)5qq_a*^x7^&Xzf9pvo4~hK>4H?4;3rsYo zl}EyZxX1`+4B)1t)x9v+J@E>ph&lr|xg(CI9uzN*-T%SIH7e?EkoSNp_kS(LyuRRhb;0v* zc?OO6r6QN_kPpta1KgYSL%nP3hehsn>fw>QK-RrlKZ{1>Ua6l&n7NneXHkCS?g#$3 zV@Lvg;#U&+M^4?x}O7#zG@U`n`-Ojk6Hk1s%0xBTfqi+XvYtPhurxHKB-mar-JpJGot!D z`L5!#kOd3+;|2X4ZrYfg;+es@D}G>`V!4hFh$^5jAUR0-Sde2RVSA!(Stl^_Zo=Wu zJp)b?zu}eZ6;fP-?9460l-Rk*Q1({)+AeA8VeWikNdXh;66t&jyLi8mhKMEgo^1O= zrSZwwG@z-v72^}ihz;Qv-LNZ3A~YvWm%RNU>}1v+N(eYtBW^|G*(=#FyH&_-UAjjM{Mq^5p0GsW^TOUrN*k^S$Ed^4vRqth&JJlL*&@27xVbRnR^miCk@^zI@mFB4#E< ztlXC}?~7RYdVbjsbp+br{l2{6eUTlDo@Lg1U&Ldf=a+lEFG?o02ffBGFEL;Os>C=nn?{Y9SKm-Lq-JgFePsDcNxG+`5No2Q*~ z-dP5h#FJEFl`HJS)(a8Bt0(^*o?aN9XBgX6m~+`D#{i5eXdsAy$$IvE^bGbQR!qgp zY(=#r*O{aljcIWpHzkl8LCZMzCA}YQ!uBS6|3v0|TTEs5fh$J4GgKM4)iqL;vFEdVeHQl}`zQ0N&i#+1wV!Qm~qf%SN`BoMNo}8f3__%{gQ`Dor_;*`Rp_8&` zU|ZZh`EZdxnEU`&Zf*=7sXLLe-bN>g1YM*$mnM=Bpbj2I56mOzB>fic1ym(j!tuuVQzsWS5-}JBk{LU z7?rpu79vyPA%l=CL?-EFKfaf{4MsfxGQ9;EN`cI>MukXk_X)|mKO%huk=_cCWoIfR z`nW$QtL$bdiu6%PBsY|1iE-mf)!B$5R6{N)CS1)nA}^`^)-SU|E`E$2ZmGMlAZPw9 zDtwkdQ03m>-M#xzPk&^*$Fk#H?LY0o#4Hmx3g!0-#(b*cUJ_+qj#IIHd&M?hqeQ3f zQh)ze;e*XgC-mmMd*Y)dN)9V&)U0}cl-DqYKT{Vnfo1YJYimt@FFY;7*~4J!(!Up z1z(AZwt!+-0QBCNeVDWbJ@&{hHgy$CVZ^Lj_n1rsV*D<5AL%PdofmC-CE}Ev7pdNO zbwkuoJbH;FEn{-9dof)tXt9qvooyEXDbyZN14wyXg>6IpLynN#~DjFAI+JHmZuf>R!MIo&oC_!LQ7HgzU6f?j0b{ z6i9wSwmQL~EIu+~_3r#p0r8x_RlEZfdys0Sd;MVma7N5LTL5ol4}YEeeT{;wP2JZI zmh(@8f@ld|L611FX~cDW$LqdWqK`4zoF3BbsfVjWf3}5S4xzv!0I0D(}e%zChM4 zm<&U5YD@fBvu)>;xXJJ7@iC|)vYu045+Bm|jb|y9`Fv2$hSyZeU_lkxxGKpFMVyQfiIVUG95>iocq3N%M#SkiJX*bT!P%mv`ti+p%RTiFgpj{k<_(tC zg)7ADdck@nbFF}KMw|~-q33_VW-vsH42^vK1@vPbvEtt|0{d)gH7L?TiHMr_p3fC zkC6(BlyXKKssPIR_;(uS(OJ4UBg`sAkDJtoFcMOlnA;aK(iijw#EQp-5_t~E+BJaf zmA_B}eoV_5dq#cwV;HO4SgBln?8ZjUk%B<-gJQXd1?rW8vQPU*AP_{!e!EokK@m1a z>PwU`?hYyU>jMI!tr{y^k#k~qlMqmxWr#O&;x_(W?gr*o5MYNZUlYL%m6&YYA1i1^ z>bF3mc)huX*eu)09HeK7U?vlTP^8t%cOCiEakJ#c0SY7&6(HFG-=lTJ8ZYC;1sO%P zqK(f{YgED;&l1OuuUT_Z*2H#M`L?pIMC|ijzgPSqipQL})WK~g%q`@MSs5jLaHNP- zaxh?HjIAF8YpMGWI#N~&FVc@7N1^jo{+)71N2KyK>X50W)cv)W@pojD>6qP{rS(+7 z80Q|I9pTDXBhE~vsFb=3RbGl3sU^Z6hzQBP2$;py(q}iG$Ec8*&6nv!#=w7(rm5_D zBpRx}Fm5QN0kYW>;IA|MYHL?V=ZXGZ&+m#hZ5YGmmiP-%aU)|y>(Xu?;aE&=5~=+T zX?;_y-n3q;+8(NWYK+s@@|>D*xOkd7WASP_r#I5vn%W?>My%P5%HVaCvhO}Y{^Ru3Xys;B`NVQ zy)?jV`vF6{KW=RjpI*L% zMWgsr#9l7eBd+WLWUT4ZGE*d)Ft2?$M>X$^G}VSwMblbN+`5w93Xk+6 z`aonhCt@MC9Cwk5Ygn(>ZY;rVdxg+Jyqq}Ryws!3>}*DkVE^71wc?=fO_N8}XgS22BOR9y)u+M#;l z6jXl_KU0{g(jDVWS=)=l)!|#i&XBjm9OXivRF_j0yW53d>uxsW{T@pY9l4 ztU`)0cy5QZ48_bmx*ZFTdxN}ZjZf*PC6(Cn0B44513Wa#?2uYMau25#kKfXd&|<0i zjv~7AY5G|t9wQ3-A1Q!1QiB*F7>ep2lg;N@kQ9Ko0?>T{yeMa0gl)&1fZK33(qP9& zz1;2Ds+i(dF~yno>J-F{*vl5V-&M?!dnc4yqfdH2m%;&8_cvex>#bZWB5FL_gky)9 z*6h-d)!f%49$wgKxT#mr{;}+PsoPDR`F{#`d{TmYf;yVIl44=|VcA6r+I>P+sGqmp z8L}_tRN++g;2+CJ_GkLWEZoVmdF!Ym)ZhH8m=j}8C=jXUpsTt^MaHl#(n0NxZV`{AYX)U51Ff1e`+h-4avoWdLtvEM_vnxn1_R{)P;1AJVB>Zk%BjLH>WrHbv)Fmc zePsuB9^ppU1;7q5n+G4XZxi^kshdiv7Tzz77-?w!S%*OI?vC4tR ze&2|N$Wt|rvZF_Xa`=FC*bl2FASYxx^{7^7_dh(w%?MT_@fW>1mmEba7L`Yf)iyGF z@DTCiSo&N#!@ggDuxZRi%0Ct;A?t$j$flYAkAN~2sEBh_z?#E0VoP6Z zR1Qe307*RoIvy|7+DneDx0XRe#TxS3U@fD8D>SF9qk(3i;A^9`tbfcg@%+qpk>-Gi zqpWMf2tx`hc;MK(1TSk|zLE!yRXabz55=l?!pTka)#935MGqV+@>h5w=KMs=Zq#`h z1dUHGthkUj?vgc9wx9l&ypdV1<(~}M$NEyM`(F26Ej~Q&Z%k(vO4ufM2a-T$nibMi z^xNBZ??txc?t?_r49YOHbbrU_s@rsjhX5fCx@Q;Vd$yjQHEVPc z%_NzvAgT4$puIv01g%lo0zvB{DG-nXn?|WBGO=8Kk3OU9hNJ3X8u(gKKW4o)(vF`9 zYhOjrD@M>VqMn{ti~wJhGeQ^l&)kg+C0^Wr&&Qdc>=s$sCYThq%Q^txGcLMT0Sb}K`(T$FWX0Oq;*UDo&5T^=Xn$lf3fUXU$D{X{#}u0 zOn12Y73!4QjM@%r#MtaErzIQlFhXf{RRda9O>pYgj(08%2%^J}xw=nHs@vMN=pd<1 zma!Y$L!>9{GGle;_TZI%fBXaYRT)TjDGs~$<+A15ulBo{QDvJ^?BT%e9GKU)k{bd} zVlCJA9kXy&&}j|?hyBY)ih;BcbK?q$GFJV&Ms5#Y17i2OHKYL?+yp*G;QkL^{R@w830b!IC+-hasbSlLb19H= z4PK)}<1|)R+$)Hr7K+ZL#;>%@SiONy|Ck)Ce9|-ct4q2SpUU?_Pm%0;RMzi!*d3(_ zutzR5`w|+IC*SkOM@zHhDh{A7sgSl!z(0U_%Fycvtle2h;RkOqwyE4nBEXY|3w9{ z7(iFfdekRWNWtBdt&x#ZPXE*xtKY0FG`EDf6UC~KvKOkdgW--j0uNhcw|jz08wR|A zf6VL!)GBGo`#iX(sOsg$o)3VVdp@;xwLAEif^k3z6pbGrs{ar!4{ez;+Ed%ctJ}_l14WyLnpieqLemuDu2EAbZ?DPle_d4TG_xG6NuCh&9f#5H58B^=NA)=on zgn@X?ZA`T4(8N~;Er~nX%#gx1gNdxK7j}T{@ArTJ=alK0gPV6eIkumFT;fOgKZ#^v z`!IW*Pv?K-#v`}w{7S8-xTf&KFwX0On){&er8?2Xxl6eX#vW4P)_kQB<%n9G-PPeZ zN`0upB5>daz3OmSPS$M~!z#+TMvYtIe-kvMpzh4~7@4{GLkbL_061RQ6UPjT)o!;x z!Tp7yWsqzj!?gMH2hEw@I(tE&mH+2lJ#AL&^uU>cQ>XjpCgSrF@xZ*ft#jhd^X2o{ z3DKx;9BFe~0<)WE&z-+G&^&+s-1*YNdDG@kn;mGL)jYd-PCU>wH^J|z)1}n()|Qs$ z`H~u+F>OwO3a2eTeSy><|J6>LGiNTf09Ad-f)Hc^@#aPGK+D|uv!}&XW`1<0>2sSG z1f<-8#JqWP=L1@D&Tn3jm=#~3vi1NLh%cVk95^*`0CX14mR- zu`e*P)>jv6IJN22!DmgEe?8w+%7lhmU$)=kt+Si6^pfWV@oBT?1?JMWmRWNb=CVzn zMoT=hPP<~RFR-|I+I(MN_S`wX!1QU0eSsNs6Y}25`-0}CTsg%Ea7ec7oaQU0#apj# z4qTa-)k@b=HZZ+8-rN*#p6#1*~;&GUS7 zo8rDXTmd(oO3d2v;~V5xe)tzsuOWFI#lJB@exfmXjmG#t-J^lwITIS;M9gy zmaxh*hWDr>M)?QK+QtT7(7cGB;DiQW$P~2rl^^~AEhNxFK;xf43)QKg2H&XBJd7I6 zzcKOv;8A1c0gUTRpx2qSyG}~iQMwMI)I}s&QZH`sg((mL;|NGZE))>_$`Ai|8Eukh zjMO!zj(+b<7LhYJ5T6^UVyj61mxV85HV;0R zyGnAOP3~+y5eWy%sKB0eb}k=6L*(QEK&qTWIo_uJ%fdyz%$+m+f1ZDKYt#I>|4pH4 z^48h{DjInZ58nH_U!C(0bJh9X-FNY?tfssBPu|~k-d{@7c$< z`hs-Hd)YqkSs4E>|IVY1HvXNuVDh}V3(h@t`cyOm+Vw`TyZiAF?nwNL^RI;We*CSk zqYvkt8#r|V15{7KJzfg9R;ds=|GueIz<=I1CgoG-1!hc>Sw7HwwP+8_TGM>Kv2&U8 zn`Q*&&2L8KXr3NeFt53(wWXC=dd{@j&F2PAKXn1V>Av~{e^;NgaG4(CN?%d+YQ&lA zzoBNq&gYvjXXc!_3sFr(qsZz9s7w@tR;}^YxpNdRMLbn1o|t#(oW$(O5OEM#&YGTm z3k)d8U+HU@zqobI6~c*EG^5UV`ieBBP*a%S98b)jL#t0s>{GsJ?(ErUD*~W-QFD{h zRdTXIQC;KTG<&*GY#-tW=Az`x2{g~17hfD$fU+~^3MTAXq9ah5QUSGk<{Pg*N;RSl zTmjkXdlZZX((smPt+SZ=y*@C&YU@OX6DSydFGiIT~|P-`UiO5_~n#zi-im7tCXgU-bUAY{%0(# zT~v+r#;OH%DqOgxp=yD_eqj`&si!oosi}gcQgYAdDo8DolwxEZx)LnyMe6Li;mVa% zMR-AcbJtZZSqdd#?XzNeZ>?5)9jo#y>K^}I<{4wAmWG$t*HXy(@bD=);qa7EWurz; z4fhC_OrAI%YSt??lr_J8QFYa_1-<7(T~(`V(cEg4o1;`Zdv5pcy`a?p4x>dY>uMKZ zBKd9tAvYKNB5!?8L*2@%?hp^1RCW4BHC^6&ISL9dtz6wJyu9~n!lIF0;RcOM#lm=$ zR-zhP9xfYIGBrGQ;+P3kyRLmhc;Wwgi+7eNOkkxFYaE%x##Cso(gI&I?Q;!%^sBW58d^fPAsn5p6X zaJc*bdBtLb=#-9)=TK^Q>Dj8G8&r+a)X)U#-YdMojzFhY5vpo6Rm*!RWn)P`DvU}` z2zOn$Vnt1ODnYh_FjYfge#46S+I%5FHBor@4>XZzGy{dRSsy` zF9r`*W~x^>ySi$1cK0Yp)z9s|v@jYSj&`cpu5xq7kPfhfb913c@B!_|;57932orgl> z3F$wWP-QSFL2MgoTh;%35u(R;cT9A#iTS_GI??q04HJBr(?+5xJ{)#T^3i!AZko4e z5nCUzN%+4p)r%?8DwFw2A^-6bF!72@7{ivHc^zSEC-F+cVZGwk65qa>`0w77hf-DKrCr(YL)o%)pv z7u77NuZKVV^nDID_>8Tpn~F6qwn#CLlj>1F{+v>a8_>uF0HCt0XML6y{j3t zX2pt&R@TZcaxi`EHI>TCzj!Hjwt8bfeq}v&+I1^dEv>{(O}{r-UfD+p&Yg1|URx|( z?(hSMLxL`_1iMjVyzEeyF0ZbtTiSs6s4BdowhEg&u*@EstsEK98wBKXLHiG)uOF&b zLls!DaGNewg!Xc^`j+ygh3GpLixr)0b$jd0udZ0v)q~^z*UN;czX5f^8J*3i#@+QL7;7c8t`!wPsuuy3!4`R$f2=c|?aHOm_otXA!-G>!EdYP%@vEs??` z;NSD&+ZnuPQcwA4{dOnTh%tu({4t6ny)*DUKphYds&o2r$i(IW$3f-F+M1=%0p6x8 zP%nSr&5SbCC1vY9Z&ay5k;qM}!Ej?NYZ$R|aT%85%h+kaW7yEJ z?Eux~Xg8&PTLt}fJ@ZQ)X-6tEy6TL*7driIm6QLszw|N05fYB}tTVmXvg^5cX&vfB zFUJDBZmCl`$B+6{z5xh1x4o%F2Z`RpEBnk>sZery+&F+yct~d%)vtWs%ap4rH3}3Po?gX_Wu7}l# zFO>2*+-lK8+nt6QOy!PRB~V4nv(cyJ)gPNgk65@!>KnPm47`Vo)tkO3yWa2|YCo6m zKxgt7#&^*(cfcu8H>B>m!rh?-7(Ilr^kbwq zGmH}mXCkcr>QrP8!W}q9bONEzfIl3s@-uLHxB}rZoD|-Q@C3p=2z@D$$bP0HJc2L> z;c=!TOoQY72;OklB0Pq0Gr|)HcOl%2&lip$+}9xz$$?Ru*%AB^?#O~q9^oE@2NCW= zcobnyb|jK#8OA__r3kBYB9Ur@GjZ@{J;ID$kcT*KEF5gtQ$ z6k$eR@Jls}g9xh;4lF>u5bhWdiJU-KIxrH+zrGV zzG0EbYJ>+7Zbi5mKKi`~bB3ebG?Y66^+i}c67@y6V-(_>qrB0`hj8W?@I`n8VYmfC z+}KfzaP>IU2Vv=W$cyk8!i<*SKN0mum{AV75FWvi`h5roPR2V6hEu=?2Xi(f9Eh+Q z-+FCEcmm-*#^Z?75rjKtL5^0CA7K%~)pH;}@e0%*;W306tx^60@IiQDG58?NS%&sS zSdGxv26C)GeuO&^RwMM)p&W$!8X^$`cXk{^n1K+7+ah@geJde9!V?H95bj%rauLqN zF|~sTbMS>m+PR=#1N|c0d>PUa?m)N)Va{6gH-rZf9zl5Ia>&d0b;#Ei_1^%#2z?u& zUxXP5w<63zxCh}rg!>Whxf=4d1N|n*$MAcQAK^iS>k;nT40#Z4z6R}su=-lap9y_j z2e}Z=+=6-{%()(NAoSe;ec}|N?*}Ls;huYuA7RcOl+ywE5N05pi7*f0F@zNi?}L0y zzaRBLc<=$}rz7<9F!~X~eUG4Bi6cCYaL=QtXBhQ*A`;nwaP?E*+X?#l1>{EP`z87t z!s`8?M|c8ZPG`vRYm|d<<}=`ju=F7MNf*$)fc}PX&x@c(m~j~O%Yt05fWiq^Li9yp$3NW82%OG zU+texMV=wBB@os zVXI+d6Uq&?B6o49!rjM{P`DDybyLEGVrwGeOHQlJSc*Ws^KWeWa7b_qVEbYGEr?%_ zc-{zUKa~LZjlk;vJr#M>1*9Zi&!eJxE~cI*K;8!vE3?G9ETLE>N;52netmV07i2}YwN_AP#+=lkGP<4z> z09zGc`(Zi!+f>I9??U)3`WqdpbzhZOOS(OJfyHj{*^6_3zh-|J9!lHf8Xn5n=pG%) zbG;G>WgupF$Va8(pB}R9Wzs4ld%TN!(99=?N}VzYr3ECCG0VZBju<8zs>29$acWwCvp^1 zjN8~KhSUm?PTa>VTG*wA{HdspItFoHFs{yqVpqvu9W(_aww`v~Hl z`lBAQ5Pt~ql^8#c^3O1C+;=7J&s;I;@*BYKcss0J7$Fb))fU7bLws+x)9BDq)3rAc z@{Nh+yC3N%G9!_<>`Vx=@b4MQ*FF+?jPjusH@e(!LI&RjRw;gUxzzs$psNmJEfwDn zl>SGD_Pbs8I~zc$OYzS_N2~3G`(D7qG5*Rz;pL%>Vm11dJu3s<4$$==9qjW)*Gzj@ z7&{SFgY-Q}|B~g8{u&t zYy*Z{Bhsm%yp1WFJX_q?yHvjjqCtFJA`x~o`%&%BhC+OHeETPw--|=#?$;Byzc!p~ zhX(LF$~^`PiP^KUq44UcIU8%O1UynHcQ|?g+xdRvo7puIS;&0Q`$pGvv~P)3iQi&t zma;&VNIDFbOxau%!DL03OWNSGzR#eX+Mbb!x+4H~vHt(PxZuFqZ%AHnETT8wE$_!$@LcY8+jr&-8kHNV2aan)*;$4pi z_MaN?t1gU0ZvXcFgLS3rsf6rw_c3a~?~o45?H!)~GHx=LWIVDYgI8)eP0 zmt-Vky(^J#FY`opzGn>nmJN~}fN`~en?y=F%1HSY9!J%fB(k&hR$G}bQ*JLs&J zUQVd_?j-VM42wi&u{?R$Ug_{1RUkgXxW?^ugO(hPF)psXFza$9uG$XEOUzuVz0$#= z68zH6$CW|kClAY6i}+H+|Aldl%YnrgeiP!#85fNoYdOlHzF!2tBjC4{{3b;A3D92y zcs-5oc>wzajC%Jb7wzOp&<`vUyFe|M!MsX)P`*s~%Jv{V^-S|FtsND5MLOV0sa(~YHj67}st`;(C{%;QZ17BfpmaNu$i=*p3 zrq4n8L8Q-QI@T-L;J`e2R?9d^X+f2Mr8*aJJGebvQu6d!O;BXAPrQ@y{$iQl_9Sh+L&6^&H zoW}@xIDX3zKNIoyCLD*yO?M|0$OhEoMD?^Rx@iKs2sQ?dmtQhYsE=a! zeD}`5_oIOAhw*a|zX$OsCi*bGLFgODZ$bP%(Elw;jX4MKZp3e$8;Sga@ybq=a{oGp z^SA3>Tb()++u<Is;}I>OCs9eqKi@Wc?$8H ztK-+dq(6-K^@ztZH~KLC1H`XJytDp85bwdegyV>RFM*ype_~4-8@0t2cCDqQq4Ent zrNcu-^2hBp(2Jp#S9*O*cd{_?Tg8$An3V{*^(R1)`C*=Vh z{~E&?^@sY!>2Cx_XPh5xtaWK48u*r2-;=Bl-Wf&fyC5b2+bd)1pll1ro_vMm_PR^@Z-Cwomj^u*uSo&z$~|B)|zZ6pG-8+{l*2k|+G$Fe*6 z^a9i%^cxsEI^GZHTKF`4N(Zodd{Ox`NWUBO>%r%9(#QH8dJgRW?GQ}&V`VTZL2?-M z<=0_d8$VCR);}@5jK<`4Q9`YZwcHI{ADq7aQ8ORga|qtymEzsorSbi9WOUsIf0ml_ zDXV*0e1uwDOg|5)P&f`M+I~Ruz zb{-o#)OjYz!4nVr{U<1==q9{7WQ6i7`~)3e+gqlm<6YxXqz_;^bi2{D4Cy1R60``@ z3z2TzoY?Pk6_TbReJj$dQ-GkoWL?o{{&T;L^<11sXOuM@G35>)&zLjBIQ>B7@HfP< zL7~`N;NKgNWA%*!sf(lq%rJ=r%Rw3jP3CZe$sA(e;TlEFV{jfc!08>zK!$>q)&eacEkGy)BP*94{S=KjftAdsQ*gv3;!q*Y5wozja`uHahmdkp-JAb;sk;kPG4c{rbZg7^x=k7it>`J^s7o#=ff z+b=7O{s8(#LVw!+d~7HWMj~#}F;c8j{O(-uXBxn77x)bme$Mw`_4aJWG(4P_cZZ>G zTV6HZiuL=?Fq)8yE;Za1+90#3_0t>3cM$o$U_`8)67^&B6W2a8dub>SqaGtNIw~+- zC7J};4~BHYe*1B_!{hB6-eJnQ2Q{AM+(Ws0D!Tzx)o7Ruw_FX0N}$lX9e1Ogw0-zP zYm8VPN*e>?#`b**@iP%Wh4D*tJoR-L@w*UzE8}DBtNo30waS#A%CY|=zaZvF-xKls znPSBAq(>3rcbl4DVtc}!!Xu~e=H$IJaweao29g>`Y9OhBqz3-4)j+shi*|Hkyommp zocs(URl?>HwvzB%3ENB9Ny4rYc9$?$!h8w)Nf=++>DVBl+jBE+Aw}}}g71G$zm6{! zd@tr{=Ki(dhyJM3OYQU@>iiP~-?c@THAV2!^EEz0@bx$9{Moa0{cEq({O3q|?Ly6O zq2Lu$b^axSmzU`D*|T*1qJcWSM$!*GuG8xT-@iwvzb5pQpE1wb>8LO9O9bD#PUpW| z@b$G!HH-~{6K2Vq1wZ~zo&S2lZTW5z+?H><;9=|?ng3S7?fTszxLw}ejqp8!vwbMT z{es)|*(>@A!PDT|V);K8+%ErDg4_M!fZ#i>W@(1;g5b7%zZ0DOgZ%y= zxLv;^g0nn6Z!}7OOYk|r((=3~c-fI<2qV;7+ z`?G)X@ifByg4_K!B)DC_bUR)6ohx`=56!Q=;P&|G~Q2K#d(eJnRfqzy<`1vlXQ+J;&%y7d%))&!S}*m^7)D2 zl!x>W3vSmZN9-fz=kvHDKk5HJ!8u;}>=)ebzt0MO^ckK0yx{hD|E=I`5Ar)KxGmqS zf>&Rv_5J5Y`D-s=F6;|29tgc9>Gt?PCb&KRKWLQxaijFl1-JXhSAtioO{!r;1h?zw zmh$cX*G%we|C9FF3O^m?v>f!r&k@{ipO%8#{iBWGN8Zr&YbW@@-)epx1-Iv`u7cb8 z?IHLZGXIYk`R)9@CB3{#^Xn_PJ%0@l+}6jCMtG6ncKIcO+vSfFob_k>OcdOIvIR|sy;M-6s0h`~N0K ze%9wY!EJkXqu};@d$Zv7e6~Yydp^6Z5&fNl+xF!i!R`9|xDozfBl<@gr9Un>^~>i; z!EJs1QgB<}PYbT8u|5&pwqGv^ZtL5U{$$f%JVTF18-H2oZTsX?ZuM*A-G+ij~(fh;d8-l`*u=ryS}Eq{*(FGE4Xbh0uKAf@H=h;` zdZwQ%xXr)4;CB5x3vSoHo8Xk6`Fja&_qTjUI?L-XxUH`tg4_D~v{8EumvrXk!!r0B z!`WIsHvX?h_}7BVvdQQuFWrMW8!qJ3fc*||_cYB3ujtgX=gv+l#H$+h;E11k@QO-3 zdnH|#A@~+lKe!@!1)<|27+u7Ca_~-+503!xIUx!5S%Ad?*k>bz+@Nb-J$to0Etm+*ju zuSocggr7<19Vg{W*iFLz5|&6fUBbl@u99$*gxe*&N5aP?JRspK622qhXA*kLq|wDkYpZ|sVae~hv?U~G+)Id@L zXO9K~sA`k#xBPkcrf7}lOLoH<|2rn!``tuMCbK6skkr80qJa=9+GP8^aK-AT z>MINevthqaChd1qRhi76)Id@LXNd;RK|PynzZWg7TU1lkB#rU@?cc(F{|^5WJ<0c% ziL{c8OKKpgfwNfy^gB1%e%CH&sBWSXX`e5E?fxpc{%)csli8CRNNV70(E!hUG~Ir$ zs9CdQ#qy@;jP`pD?6*64ey}NOOy*5$AgO_~NCW(vH%+$R%T_F}TGKS8@%x?DSbMig zuD_e6$Yk!M29g>$Yc$XjHEpu}Ub?)hiN^;GuD`2byPGH1-)BwVOI9?gfushSrUBj= z)nxm=Y< z@3iFl`)uiY$$BO=kkmjEHP9OQn{2-umM&}B=|RJw|NA`H?mLq9yNNBD%%0RhQUhm; z2KYA<{wwyo;nF6ljNkG93%2{Sr2TG^9+R1q8c1s3?9l+fn`yHBu3XU2)b%&b_F(+n zp0wX*Pv=Y4G^v542AZS+{>}F$+i&_$>Khg;tNrex(0_6PZ1?P>{r>JsOy*2#AgO_~ zN&{_C+y9>Z{_ai`+V5Sk-FGJK_gU5dl9f$rAgO`xu7P&Q+GP8U+heQhRxPOc?qV4H zj{h#$?z@xry9ruMW=(1!se!Xe1DU97lkNA4rIk(98O=8L0-mJ(ZmKGi`I8z*YTzu< zKzr1)$@Y8Y$|f6duD>_oj{$v;e-J3a!|yW_L?@$?8c1p&se!Xr107KFCfo12szod6 znzjU|ef|xd;AeP}_WKNqNk%6%kkr6gtAUQFdF{nbyuGBpp{bwGtMBK(sS%R)``sw*hPXz)A#?8O<#0S z6HVxxfEZDlKI4c@zx91hSJmvB=wCTz(;NTNbZfqm{+X|A`t@IE`jecj6Fgd;*V~%X zUhCVLipqC}cgdRmAAM~4t=%;J2MKsHO4I+d(57FXt?8fn#`Zlh(xxxZ)AYCTvWEnZ z=D)wnrawMf(@zQ{AV!p?zj>8SUp`sWPd&rh;YVn9eJsjn-jDod1oRux*%A!|m+9jf zDwnHS6)0SuW|ts`%h!w^MwjXJs9@z%MN!y`1oG6c<-`Y8VSF2heBGQAyu*S8t_?@7XG7H_ifeoZ*T`cn$vQ-s4-9vFBdgmZ!;A)D7QiR1+_ z9u2Rlkb%L?NC8&?4eh$jso&a-6w(mV{|3t7k_%s=GHTmh`)?g2c)7#ttWJfTcNFRml3JxTar;t6t^NHjuWN)y9NMCas z^6U$yunL7rw*A3*OzCg3xMvK{BqTMvpfor@ zDbNU3gGq3pLOj6*APWvMzl72A1${vvL(JbIE-m;OGY(Z`Wx<=6XP9{_E<`L3z5oG& zMJi=x@L@6-t_FRD;ps>Ldi@1i1HS^e*;=>)>DF*$w<=jXj0_ZFRc!?)pLID1t;I@p z)@J|8v&&A2a(iNt0C3^R^M8~ ziVPx&Vf~5`g9&@Aml%KE-GF`8ZR9wF@dFJ{H&PD$K1f@YTSYBMwhwx;M&yFZu&(0I zNX;XU`HBhqteLFdD3S+t*XRsTb&Vp!^AHJ3UIowAFXLx_iZy{YqXqhcRnGi|b%<4; z#QYxXV{Fx|$%IE)8ThrPkY=;>B=TBQDaRHolkhacTdi9t-*h(64(m3?&mg?ZdWG>b znRk!1oA7MH_gfalnL~K5^*-Ubl;*KEesVzRY5Bf|=$v7DH_c`!SQW?bW+nnMv%iS*jc57+wzEWu#3s=kY%(R%S>73Ah1RmJGU z#*NH6aw}8ZHbuE9ynQJ%lu@smTbbh4u>hRSa~N%}JD!G)`ItK=z{Z3Rf~9$mvJr^v zwA3)0lbTkz^YhHyg6P)}qBEP_RDEMEgzo$neoWOX_Yi%aXe$zPDbtBv-fVpp(DBei z7xogf4SSD!+xjcIu%DP28r^k8rv-I&hIuaK`5UU0MNQo~1zF`WC(iL3M%PkAuLfXr zBf)MVK(XpEr(BM-Y!Yb>_X$BBBFwqB+Z=8s2UWx`gy1*{X8h77NaqSr5&T97!j!h+ zs7+8ACD=L@q8Y z5yf7cqF0DL2G5tMb5V@S$Wa{)329hJbCjX$RO7`Y$ zs2zLrB_yoIrn3|Jqe6Cv&|B|k*Iv!EA+Q*oPm%E&qE~}WXHE;IGNrXBy>|{%FQXah zTt=;~Ww$QG)YOSq&AgmO?VWU_zQe(^j%;dRBXqaEg5CN!&~6;gE0~COnQ?t?n8lUknfwV%Zt|g&4tm7`G+O3724=BM6(NC zf~`g0{5d+8^hvC(!eG!24c%$AVJcnz1103o61r?Kcsa&^-Fq##O)~R(n3MT4lifXk z=v>W~(i)1%krSvC4g@Al0Qvr_Ps5U}N?6<|I~q%xZ?K>0p&&Y3fL98pJ!eTV;3T8fPEcEO;bq@N0r_(!0Uv`i#`exFr zWB^d=n@=az{a4v*-GQ%hsO|n3y;1P7Bv3z5g}c_Fj{V+(G4b!=R*cbj!C}^kTKw0G*j?>y>bFWy#X0G9$5yR!cXAOCIwDctJVP($QSrX5wqP? ztXfp)A6iJ4smkc6?tG*1jFzDZ<*f$CsiI?c4Er6{3ARKA-7B+i2g8FJOj%Xy1-6sGK(1x8qAw zi1zLHT9`GEK>K!lt<4cYv~S1PM)eQv+woENb)JHAXa3yAjZ__~^xAdmL#_u>fzIpW*#=dhpf{dBj!tMjuqwlw6siO;WQ7^_8Vz$W1OvDZ>EJ*=t_GY z$!1y^eqCvgVr+WSJ_hWAn^d`wn$vgGvLh9wd`H2}ub{vd+IRF<%JTw#S~e^*270ev z1sh;}0Vdw>QDDPbPIxn6kL5*y-fIZ^tcOs9_gcb1t3ToE2&Y+XA+mQ1;dJXHA6Kl5`MDEhKO z15}66zO2wdg=k+^XpmV23A8UOG{pR83WQR=tk6(JrhQqVVdgJTG40C=6{!^M%L)xQ zF9L%K?aNB-Jq}~t>DW_t!Agt zzO2-xjMl!a)C(zu_GP7B^eSNO%Sx^J2ykgD`m$12wgX(=ioUGWwd(J*K{BnMh1b5U)H=f2mz7%2BDF6owc%3GhryMDPBkGTR1>x# z8B!J_A|oyJk_QkfUsmcGg4&mrdMT;2FDvyj!t`ZvFnfJZfXdI-_xjQRD(>uHnmdPB zJ0v}0C$Yb&B*y*)h-VI}m%4}3W=3Y}XLB)BQrDAG+zP`ypjZN8RG59#iNIK zd;CpgBQ-@Ka6pmFtB_#uathH*A!)%hGW97WJs2UGUm+Prht6adFsl)n*()_@jst1X z&&(l3Vzghj6lI*F5KsI1szpYso;rQOE+lKNQi8!nL|P~$E%-AcEfta;yn>~tDW zKEY5Ilfw#S&?gwmGI#4TdYV(9KIIb(<*LluCm8Cj5bYBT^^r2@6Aa~qa-WN58Lg zzl8YkE*+sX*mW$`^c%O?1+IxOdnyptuhYVniwRSI;g?V(V2YQ0Axn6{O?#fr5pBMx z=(9PZ&6gBxLEUKIYD?D60D!JG~ox$laIO*u}(9Wu5n4U_Dxq@jHsw zo5VLzfOi${X$OWq7qPIf-Fsz2ZK0d-F?aS#1v4t}YehW-)V*jvfK!PpiOMG9-h&3hoUQn6?glr(AIQJj^V9-WsL}h^RNo5Ea}^rz!%k@0?PpW34oFB7k2adV?T@Rea!`_a20&!%iXq@zwM0t9|{SZ zf2ksw7TC6riJupKjtul6^))A97u{F60*w5hNsf9jy;?K%YNkfP1yY~QNGteM5E2&V zErdXLn4-i`0_c1lI4U@&_FgRtH2UreoD;^F}ZzkC0kom45gaJ62lh{url zC}{43ABE9BRM9_2bpFSSv`Dw3E;k?jvCR2zODaqDp%yH8ElR#TT5|pqQZm_x zH3=CPz7j8ynJ4n}D zaU?#_I5Ay>`3ge5EX>)@;2s-pyT|hL9YmkU6OFQo3a2=T`ohU3T*lZ0M!}uZky;Nx zpS)U>pA97ceG!pTOh&y``Qz=J`E5nnG{UP?@-+CuK;&9yLId#U8HEcSG%Q}FoB32w zKDL_Mp+ojCwUV$5Kf7=<_UD{(2?$4@o|cZL&_;*3vO+xJAs8!vQ*-~&>|4;a%=c0r1bO!B zB+)Pi`fFr#Pz|X=BFKdx=40;s6_!1{u43MUYNb$$3TlgdP%RI(6X(iKID85`x7IM9 zSJY4Sf&b_z49Q_(Tux3ex`wobn!Hd`ufbm-)yO-J-`qSveYiZhW+@BDPJ`6L-CIGO zHx=<)K#?~Fz#j<=17M+L3x6o&Q=nTY#Ov3qSc^3$I!TU!1Nha0TMey^zJ>pb_HdIO6*{;u{?C z6CLqe9Pt-A;&(gZuXMye<%s`*BmS@>{$WS_2afpPIO6F_)FaQx|EnWD(-HrLBfc;e zUzmPTtiHkn5k(aeU1aLySCEBMz+0-nb}2B7;c6ZBw(CW-nHzKI2==#1$p%5yW4`Bl z969sY=l+09dF*zd6JXEFECf;Eh8j()=ZR_L#ladi&ITy&XpK&xmYK~|r??0?bJbGQ zr|>6;tL3I&;XV7Y6LEM1)PnFC;96kI{e}pfZ!C)yJP8Hp>O0CV=phueoB11;$H>5Op$nHkZS~?Hr|y|IHaa3yQ=1#-3}5DDifFZ zrX#Uaqr`#|>GY~Ts|BGrWr}i|8oX)}F8H3bq#`{fdZ5X^SV-|sA-{vDjQRY}{pZEToO< zuhy^Thz!`@xgiyii_F?C>%_2H#`ags(y%g^I(|r971s6x)pB&?Q)E``F^YWz_On|S ziC|eCAb8B3yRqsXr4Cu_=T@yb)HX^nRP+x4Eh%$>@YmZxz6$jjjm_NCl;>$6C29-v z3|WWpo}!eCE%Vtw;g=o0L`ivoYv-GhI)-Cuw@3ivr5^L336G*0O1}Y(8cOa#GL+5( zV2t6e@S0jpj#*JX=HYJ4))`3`lV~ip__Pq^p&avXFJSkQ*9l7e0ok;wzd{8c;9|tyW5CApH*xZyAAMDw~@;KtB4gtUse**!Ic=9z0T3oC}<3c#U zKoBmGe~+A48GEx9aHM~iK{$it>H zCXnv84!WV5&a3H+f|HV_*6nlZViFc?av=FX6NKV!`G%tY?4aAzsHjgJX@vvpbx|B! z9Le?A%o#;#LefPi8vg)`(O8|nN@vRfsM9D|BmLty=v@UL3i2M1{GhZh*DJlzYhjB# zP#YHJJng~h8H2a1TBs&!3cYUgyPvlYbmU(t1pa|~OA0n(oP`@+OB!V}MgHyaY*yMs zzo1eG)DRy)S4pkJ$ifk0s~0Mr_cJ8@9aS6u5&(17_@@zgzvS;7{|-EC7bq2ztf4q@ z!F-K=^2m5B60!O!0%&$u4xpnVjtfgSKIYDr*f94}L%qAnvAzs>^lD4zIOlxqp415L zY5oa0s207=>ZLf&F5>hA7oe%}-N1YFpl!)D$@@d5!#ea<4xs+S(csTDfDfLQ=OmSKs7cK4zQ*ns zM*ia>Ee-1{l9yDosLpb>pQ}F0D4Q>0f9@c`Ch5>@Qx{$KxDaGx6YVHz>l{shI(nMF z_}W@*-ra%6UN*{pC-kN9^sA!`-xY$T@dSIK1Q8*)HlE-_l%S1N{3r1QrBQ-DLhxcd zL5|35lszN_AI1~Rvl@>2-xl~iR3g(vs{-Ly4fLQ{w|?nZ+%-)aX(oWk?54Lt}-*CH^daz zW;F|kdodhG5bG{|gkW?$LA3GmON4;(EprgX%Qr))DBo3zO38PLME}T<5%NXbt?UOv z@W*(9GxgT|JwnfR{xF)yD0oETRXb1Os}S>1Hqw5HM}&IJoh6;@7Jig1d<7ceyyt}K zT&;f|7K9#Q&y7hF&|^$4sEtEHgw_>S+oG(VAgg_3^;%+9`CxS$S-nSAM^BULjVP=4 z$m*YD^{!BHL5KeAlZNk#Q)JG)N=!!k7 z16ck{Ot^ZH_Ze9&0;`hUq*t$#rj!6x?zS)JZMy;J2(GzS2p^Zt$24z+OsdZ}AC1U@ z#X>YT4^kZ&uPuF|)z3 ztzTo^1WZp_0h7#M0R&^s8->i$Yj^5ppoC=GF>M&^=?HYE;%&`cXy=HWGiP~)LT~Y zFVVPK)Qy+Y)S~VpL7wG42dxmzEFPE3ea5t(3ypLLG-h88n|W&f-YX@?3`0eJ z33|zNKrNXte-+*+G_oeb3?xe;HLh=#RJU+2Uoz{#M2+i$GDIq>?LrkD{l7K852^{= zav4QOC3TAM_(N2RU#Mjir6{;uC!QuneyOBz5dR%H+3HxX7EG3SndSM~yW=!!bh7e) zn2WM8#Q6adBDRBh_yV0sT9jj^tI><=3mWEdV(SodfQ0SGypFG7{=7;Il$c8POO{WR{`s<7&HvPdF3KO zSU5!`nB{KX9ZYDhT1^6=OeO)Es|NrWMVq$i(oWz+HM7@H>&vMCn|ZrI;+vf(E-G)Q?y{ttwP?z*p> zH1r|n|7f!=gB&{cbg0F_A^X~xu*FUqzx$b}u%oxcgk3B|@v2)Q6s+@g@ob)tvbphw z7@G$Yve_#XWb<-7o8Q@N3SZtDW5e#CB;g>TQU)VUtqLyNq^a2N%y-S!z0gZ(e6Od? zRTS%m;y5XenFDQ#XB7pFG&e&DFB1Mr^QkRpLz~a3J%{*GXQY-{(=C<7fUq?+6V*X zC+jB&9Zz2%r}C2>U8nqH^CXRavQF?8DF4?HrrG{4?I-)0gKkVhI_)P5N^c^+Doy9z zruZ58qa}?(UD+t@lq2oFg!~~#2P1#rHCi*|@%w~ykfVc9Fiq%K=lnYzh!@RsdL@DJ5yaVGb)qJS?i!Qw%PA<@=$Uh}8%21>42Ys|DC6f^Y#=uwE<=J>mtwU$0px zq>ESqB4riQ(Dx`2`N@OYpvK&4mk0qT`{y;0xYhJI0}S?pu`*N@`)jv2%KF0%F{Esu zZM6I75ieyOw#QGwPlQ16*(%mptr=$huMeH@E7OkLuGwM>^dXpahjZ#HlTf>vm~oZw z`YUxn>QdtBU8lxhC9d9yer3K39^+=&uCa)DH*hx`kGVA~a1h9FeGGm-N4kC!W4hkK zy2=gzYyN(b>^!LCWmOk=r*`2yL93g!SQSVp=q8A)dC1-CBae>VnxQV6^s3}GtW-NS zV2QIyFG`f#ZIg#?H|_t|blK{7%4WR~QTv~3G^`dV*D82uwyM|j8BMfQu-sv}P-QkbHWp!1FW z>~+mWYF*R$0^sW9g3i%mw!O|-rq(&v0PlYvTX1=F-IB{nuTaaL6C_s^uT}oWk#l4b zv0X~;s|z;FI&*rySfMQ-Qda170<=Qeb3xXx92V{oWYFHoRjPnmr09*^B?^C%xH@OD zTGcQDyboQy-EYw)al>R@X$HV2kDk5G^S&9Nr*;l$=oH=wU>G?>u||$vg(~kZ^T1a4 zq}XRe&^*fI+@T$zSdHh0C6$xqgt*lDEKDq(OALNVv`MJAk6Wy$;6^o#fkP?`sx^sG{4=-xs2uozRI7v-+(7 zoFEVYFnm7rK(gt4XYby&b=~wq3OK%Q&?o?lk*+2insov^lG&N z0GpZojecpVIB8lj5Yu%s?02UyB(N?M6K2;9hijl*O zitPA0{c=bs%E8}!*z>F{$5kwzliqy@dG&78}kjR@Po1%P|o zegu=%mx6@_JCGUA4QLe-UJf|_dQmN#Di@N)co_wEJJRz1BnbBxRf-U=I(C3NUYHC) zQLg%d+}?v};rl|$cb+K7UB4dzUU;Io)?!2{`fkldn}2QC>CG-E5*mtB_#;8s#iF%~ zIs=TNO zCbDND4i@!#XT}ayvavFr$p>}^FQ^m(WtFGCL?ihlWdmv@0Ws<^cOC){{aWQm%F6Xb z1W}?k_7lZyy-=Z>2($M6ZDv1F%qq$3+QiIY;+kEIthvaeUMN3q z^zTFFT~kIP%I_|^tCM2uC)W$!!cN}W!w+jNxDL_QeFSIo==VAMauLDhNE-si>>#+F z^9W(CWpw163mDl(8OGaVvE7hAv`y89`;s;vB9s1kP_eoZ6NKkyRe-s~*D3Fk290hQ zb8klWfN>jsw*%#>S(B*LIipdVwCQSY;9MVLZp>Q&zRf3gLaf&}4i%X<9WBzLFApls zX`oDxE17tTrwv)Rp*V^`J7Yc%3Eu*o$6?wKXv0&%ZPdnSZYvZTFgoIwLU2Gh%AIpQ ziV1B|BJr(%Bi_cG7bxgy`@9hKFn;Kzk?_<>;X_bMxUavNSMq12#tF^3-r2LGVM zX5Vd`zF{ij(ni8XDMG1t#)+;)}?{ zug13S01=)YNaFJt=A|ZGB<0#jlde8YbbZ@JQtt0^k(4KPk(9@Ak(9@Ak(9@Ak(9@A zk(9@Ak(9@Ak(9?!AB5_U4L#0_q&&`xq&&`xq&&`xq&&`xq&&`xq&&`xq&&`xq&&`x zq&&`xq~u__{@BptyhzI9yhzI9yhzI9yhzI9yhzI9yhzI9yhzI9yhsY3WG>kC$A%u~ zMN*!)i=>??z<02^y>yHh+j*Fx;EFT+s>??T<02`K<02`~Ju@Kb zcfLrfnd2g<_#31`{0cA_yFtpgc?d@TIr=NW(E$DV`0;FjiSYNF0WeK{brP$e^Q$}m+UbawukQT0^$^GFTZ3P9 z@yliaE%}2;YASt*e*mkmzPj@d(h~m)5q`%FQhvt`Qhw(RQvRX*2s^#pU&K4y)K_=@ z5#7L6e|6^{Nq!!SU)}kO3G1)!{G&)NH%PSu=)6J7U&0UWTIsLu{1Xl#xjFiR-*JPK ze-iWSukQSl3G1)!{8Lzl{_4&@m2&8>?)=jT>#y$o)7e1!t2_S;!uqQ_zvBiezvBie zzvBie|6EG*SZjWD=bv{JFu%HE1qerPkYa@T>drsE8^H7&|MLE567|)czm}lUoL}Af z9XCk%9XCk%>sbx`)t$eAA3cQ8T4kt$YC=Y+CTvMEqzpksdYb=|jR@6Ocm6d5^;dU( z#|={c=nYaFJYFBy8h*AuHqa1Mac2k9+@A!CHc0v*VpJ0Qn@VErPk}VM79>2$D^<_P z31pfD7#Qlau7F(ibS^*Z3OKKN3OKKN3OKKN3dmJY=kl|zKo^tkmSwc%XI+6TlSQG7 zp60bIV-kJ>&a0jR&a0jR&a0jR&a0jR`6@qk$`xB%e%2M}YjUCD^-+4SZ!3P=?HXxj z@FhU=W%Wx8vmHUB^&U*tW``Fbh>_KrTUfIrk+iJVM~H+k0#!Jx^&EN_JFO+stMxIa zbiSTQUTc20Vs>GkaNpJsGbM{iUfy5fns6xOD^>>j+avke_POh{k_m;}Z=} zh$Z&e0|mAJHNh#$gT$W>RlN0S8bPR#c{<+CDuqmYWmAb}1uH?pb}T@C}CTfl(yUYR1mRP2#}{pz7LY@O+Tct*e_tk_7awjMY#!^uFuR8%S3U|x z&fqG;z5bHUsz5N{;XEPFUMSSdP{vqI4QWe_>{ldVBNA5W1b>tXgaB0*Sz*JP{b!-Q z8?-lQTE_SIMB;yncr;rDny6<7>UPytl;u_>5H~&QF?YU!yuD81$6U>eG)-ytHLBTj z-ORZzO>*^yo#bQgT#NYLs=e1eiHH}V-Zp*K3t65b!ihf+<*^goCat!v`(7dWI|P7| zxGhAz@O~E6f``=Tb4Uo53XkRBp*!M6B~g!IJ9UbxU(X*?zTK=@k;K0x8O@#hDC0$n zfPF5v%I0*Bu3JAQ{Uz@AyQEX(t>fjN;=t3?1?p=3B>j54f zBl{f(j~q>9>jJ&oeY>i)L0wFU^0?Q@!-Y4=LPdSn#PcXOvU43gwnll}7v({H4t8*O zFrGuLkv+q~fpGDu4x64-!>vKKF*%usw$Axxa)QK)Gnu* zx;;{yZjThF+aty4_DFHMJyM)*j}+(q*(px9M~c(!k>YfFq&VFkDNeUXiqq|p;&gkY zINcs8PPa#j)9sNG=l1Y^gWIE7%ie{< zez>SWydjp;8)7-VA=V)CX_zAI4Y7upe}-Yz-Vn>_4Y7uqKf$I$dqXUzH^drl@~;+G zXm3cM*GDK*dqV;XuK+XU4GB2BA%Uu0;H14F0f#pvpuHiyPdni7h6Ehmkidl$LVH63 z7aahsy&-{`HvsGVv;!-Bfc1Uafwjv3i#H^Ydo9Gl_71}V5^+K za=rvt-jF~oL4BWgz~K!EIJ_Z&dR9YwLjny;Kp#eHEkbLlCS-(aLVar>ZrVmftF*u+ zbXzEINMH>??F|Vyydi<8H-v-7>$?Y3ezv~X_ca7n+}Xi2cg|wGIs0M6s3i6`mBd(H zu6?d2n0XE+*0wicIc&7$^4)CvI(}VkPvY0zmWy>y+uvXirx>2|5d^#Z4f$I6f?auS zhqahd*#s%WKnUd-!>F9LhyqogX;G?tP36gAdfy_Zrv(eIjHdTj>8kp{0j$2y@H~g& zg99rx?O@*8)1tm^5pK|*iINO!HGYFbh4v!y9mXprP;L=l=V@LelqwC+znDI9AL2b> zvK{pnK(FsT{3_+RU=PyI0hZ1Mi~2FzyVzUrV0rgi1tP*844dp|&Ml0S!g1w*_t5hLH z>Q53_W0VOkRezGe8mCgqgR`JZt4twN)!!$u#w&X|(`f%aa+qNL4h43ogCH(-H@LeF z<#yE9{!qOgOY!4UcZGK>MgMi_yTUu@t9?k}=7mT)hq}AGqrTcF15K`T=)20pccMJ= zhA~+E*{iY<$j!&x$=FWpqUH_kTnCoGUvdrUw=$(gHGD9<`)Hgj=k}8FmexqhT8!w~ zNYCOyne_z90jTenyN(oct_FL9xEt2vz6xw|CI07#XWT0Ms!OV&f2uv_6Raf7JJt(X z4=p9cd>l+VDY@>TT(6?ROXlb0htMOd+O+^6EF!Kc!_LZSzQy!!@0rUA*mTaa3%A~NX)?-KSz zM&40K%KlFII~M@StAYHyw#)3Y0R&5dcHb}gSzz|-g50Q?;dHNv2}K>3G-OxLWx{#m zAaLFSR$U`P!8$END(d9m(7oB+IwN1p8o6P?Y4R+8Aj({B8NGY&2$RPsDfdmz`4^hs9+t_&SzRN(5?#|1$6+8v_@;(Ml%XKU3dB^zvmdd!{MSg;zVtvO6DMWH=@DpUuRs-UPGY%mW$WNnX~Xi(#a zU;nlE(U%B&J{1wbl9(VZ7I;Ct6=3{NH%5|1P-cON8-WpMSVXUn2Z} z_Psv;B8OZeoRTvgNVCQG;Xk#KM$@QEguTYyh*FmbH{rcLm8UKd_S{KOUn1A_cU{$eliEy)t>_A>0M_+>X`g&)3j>k7~Ei$GR z!k1*E-HbtFrgg=yEA3Uf>(Y2 zJ~!|stWDx`0~KIUVV@fqhBEDQ1HT2F;M~AR;B>}w11+&r_E%H;`nKNqa|0B@J~z+` z_D%1U{WU!Sm$uaB24+yumipYlQ-GuA2KZ;3aJMRcm8ty)fL8oLBsJ9<=LT5)?|N?F z6Y{{hfs4t5e|gG3q8F<1ZRZ9^E<5Eb0jfS%q<6~xl7Wb6W1kz~Yxb5{oW-9TV1E1D z0O3UE1}KMpZh)|TZh#GBpBo_jpPU<@G>>KIa|0!Sxl?8Z2&+o)wq8c4ow9%a7J#jB zZeSM;#?#doKjg7`JHWA1GZ~{Qr zEC8-;M%QDY^?u3UJDhO0JfvT^0{bL$x8{8ZD#7PjtekU5uYR(~XBX%c=cfsZ<4|4Cw*;96q!-`n{&kuN z1_!`=WH~Mbdxej=GX;Grs}@Py!7XbofDRV}*bHC>fNr+{$gcyi3&0Wr_XD^MKyDfu z;~s8JpFqqX5Yv0&J(_Pd%IA%*kO9sCqvtgeAC;?Uo|dZ@cDo=jdbbyf>yh&pDyO=j zu=mA|oNsB4e)ncaZnz41?sO2TYFES)-~b9F+$B^Cqjmp?b^kMx{NR%HK7fk=WFHg4 z3?aM@WPO;bi9HRF_d}t10P=D>f?}0ZqUWi`vV0#b0^M%%3+8p_hRf0 zMMe7V=8#kLuM<_rK&I>m`I?m==7EnX%=Q(q0-hiu=O3WS3ajxYI?b1R+mW^X)LY*f zTzl|EZa@B^O;dTP-P;bW?Z?02XU<|y_qM}p`|}SRnHSKK{0@xzs}1^W4)eB`09CeO z4lUkJpoI;~Ai`WPL~w6AetGt$`@jXyWE~jigI59VzqyYLFIWwAJ|Hw^TP!Y-&bC2b z_BFgm?)iI3j&{a@^JATH9jN&cNiY3psL-WFi=>{enZXa!dx=Ez2I}QHS~aD6j~49z zXYbA9qbjoY@q5#qrn_%|4ulYqC4qz_1VZS9H3Y&Q5RpX|71>k-MHUeh35$pd;sT1e zMMXtLWz-p5a3$^wF1R~7Dz1zxxbO0No>S*`R{$NInfLv@e|+!flg_C+r%s(ZwcNT@ zr%qKO{!A;rmBt@|_zj78iiE|U;;xEa2rT#YwKj`S*7$XZf60n}QRDxL_)j%{2?m44 zTC~RzUwrCKMwFchv}tIVO7Ywhl#V}#1=nn;4mrj5DJ9ETWhik0l%*BQ_=-hztWT7t z9nC5JNzv@UrwMw5axb{q$U*Mc`w4egJ+#_&iu+hZ+kB!e77_c&5f%}R2B4-$!0PKJ z!*<6iStoq@<+~ZEyJCNKR$R;^ksW%xZ(M_&Tbd!PXCKsShnQkKV z+ZdE?GO!j&f(tOAD#c5)ip(kyDr2V^%y~Z#K^5;&{v2#B0cW-^H0*ZGHA9iI+x@6T zH!3f-Y(?CnL$_P=w{)CTmSv-;yy@KW-Q{f`l{c$9rn|gbqb}ufM|ICYF0N;$21jP2 z)7BThJ!Do;UtZ`qIW@6dW(M_LzStq@#B!M()R$QU9EVLTml;BRm#=x8Iht55vjji9 zWnww)xWSv{b|;j7MUB>XDJxEWP3+0n%_~}zN|vsnTfnzU0pBqNeB)Fwx))zCz4&tJ z#TN@6sjG*_qmwIydQcvz)>dDH?`6c}l= z&|T2IKhk6z9Ws^OP{g}1EHdnz;!2I5g7{*MX9jSPjb9plVmQRzbX%8TC>*N9=YW{j zNo0bNwfHEFzY_5iG#*7OUa#>S+!mR5*wX3H=@h@KXv%bvCgWh5q9vkCPb9LTO!JW? zTovsrS(YZ@L~n;C!RxcQK;xOk_f{6;G@d1ip{o3n%+`2H+|k5G0=bEC{0s}tOX!iz znnt!eU(q_Yaw0DMbuLIve{JP-MW2NuFydA#c@I;8oP%d#_>=~^i=PO?mLe$ab5|{B z&O%To9lO{%YY{3FLaKKu)ep$nNcC>51MoDA@iMHx?+@#xBGw1wc091fNB<3Uc&LZPV8%-1 zD1Vy9i@pYIqGE!k>nZ}d$%Ed~)bF}M>AL5Euj#r$=`)WbEL}G!U6+*i^}PEPQt`HiiGL7W5|~C@(m%`nwq+(Zr9wCW^~8 zO933}Z~<8PMIWK@<^?yK+V3VWqDhKa=bD7@B9E!IdBJrvWB3^Jg6n3+@KN12nbefW zJ<`13x|?x(0$*_D)(ftDuMxa_uMxa_uMxa_uMyl2Z<*LyUU21-k9ob7C&q7FZAFcm zZ+qtsQ;?ey1u8`6G6fn`r$B@16ljptt6w0qG~h~shDfI7l{93p0u9-#KtuK_(2%_f z9<|k4U&dQvsUZkxRT7ChU*ulK?GW?dyxqlP(PN&MUe&lSu$#O(W zF(glu@eposd9uO9nY-|6BGOmYW9E-ZeQ@$_P_^LURBd2h=8{a#+zpC-%q-$nea56u zx%@EU3_gi>s?MPBPYPE~;%yY~U5?fYit~80uv?Ww%`KD#BTnd>@YBm^ju|>tbHOlr ztY{+-BfcqHk|1JJC zy4kF|?M@aFyM+kzd9OKM2W~hR#J`k!$DpC61nZp)1n%iPk^kIKNN}lz_~+js8cw|y zI7HwlX@?s8S9YkWf5;AXIk@h#SrYnXa6`5=YN(5AZPwNMoz1#%a;vo2(9)`hNT|KuUue`~WY^81^0^^=EiqbvHNKkFgf zg8@cl-;JATUeS>V$A+QhPfP3UzKDQqrlr|tr)jp?XbmeFjO*W?GtU zcAD19y$qe*Y^J5zW~XU=TwbX+$!w;1?cYM4W;4y3G84>XGtINiPQ7Dz;L&WRc~eDa zatPN;9>Vpk%{0$4JN1sE5N0#YJDz7B&1RZ6g9q`%il; zp)k!WPBFPmweWp?UWW~ZKIcIw$?r(Om8)Zh@VSDDU=;AWa< zZKipa*{Nrloq7XEuA6B&0PW2*Z{Ta-sfTdAVXpwqL%5!0cIu5_db644jU;R~(>z(} zGiImWp?oo!%`|T`VY8X$jbR0u%`|T;VY8X$S!So6Wp?UWW~bhfl*Syw^(OG#DmT+u z0K$pQG)Bl~nm4gMz>ETKW=~X!Y^Hg$37SK=o@I9GS!So+Ts9D6cIurp2K3pet&u2# zR3Rgz3LBFQn7)X}h^n`xe9cIqX}PT6@v;fp{OVeN;)pF&XK&IV?< z*MbF)+tOfKP;764V(h&LAk)8oj{oVWINs(wuyoQFINt4qVD!n8A>JL&lP=r4s{tlU z>9gS>%DbB&W?)R&5}@b}7st)T+t0h_2Sb0~5MaESjCz2CPWp^lCp+F&!Z9a!EP2-! zf+i!&duTpsuVmCCLhC(7_)*FM+Ib8-MjIx``@}7zjgaqCqCRgE;cbM2M!u&>5=Ifp zD>#(sXK4F`)X(imq<&sfn-njY6v4iveQ_&jvI^3gyZtak$o5~FeH=N>HaJbQ4NlW+ zgVQwoIC5GWnP%y6U5HX`LiJTUQ5^ zUydWE#oa@|GZd!usC@h$$V(hkI+TMX@Djq!TX04qVW-8t(5^d5rbliUOsiVTV)-bS zV@%5mCOf(2KOMm0pYyQb((g0OLTb1K;zK4G^0z!$2ks+8-v9B^t+e^&Uk@LNW#9U zVnG9z^+&3pQi)2SNrMX(6E{DruVXF5)MUaal@%HSvji>4io&&oXvZbq;JclKQ~@!ErM@fK9_Eq4Kn zCmWMuw~_l4^wseR#AmHQWXWvB?nHFLMm7}}?BRV-aB&H-IERwT*lIB8^r6f})i=?|xQkTm=ERyj) z2{b~pWR>M}i)4vU0*!#gSKS_qP))vV>eUbu_ zEcRvTW|4Sk)>7ya;WEu|$v@a4N$R9pIXJCr*_hi%=bf#jS0>gU&c%mTu5^_)GR}-Z zn?z^En9@eZl-m%_mA=zP#+8OEvF;}4qVuG8)5ll`P`8!POkg`4H4|MRU-Ao_jWEWa z0vQ=@K`6dSMR*hKGB2G20-j$GcuPu$owq_KZ<59zh|j!VO?-5&V-De$<-!zP@iKg& z1T6Lv78r`d&Zc7d5h)76FYJn+@)ui6K2m}SbqRJP2!i(-xt7!=NNkeF8z?~+2g$+KM?o@z`An*L@@3}&I3T#TYUhO+iWvXsu){Tt17v67516^?4Pn3};3Tk1T zicW3MKvEDy=Udv|pm+`?wA!Oi*+6-amTj=a$-B!U`I}E7y{cNe3`jn+NM80yq*qnr zSGYL$89|v5_YNc@=~dOzWx%C@MRFhpZIUcHg|e9L3zA%mq?b=JTS!1C8O1G<$v#P4 zE>#xEa-XCwm!m9_8+?+wT;^CLPx&OGIy00&+@%)DXFiFjZmzGF3oMctT9p(UNEA9t zOLVnGQtFcc36g9j*=&)F@kxLLNr93)W|1uLNu~)&i6O~<%_5;3Yy#kbVv8$>9+QyF zShbgEvs-8?74PL9Sg$efisP~KE!!3Gfl2{ZK1 zkT63Gv!_@j?R^rXKKzoT{AML7XJ<9HfcNM~F>}Wv;x@&8lMr)7V_(c%ia8gOw3i{T zEv5?2q%|sLKE-?&p`Ja_%RW&ys6lz$!bc!Y$0h4ZGeuqMv>Mmz>A9f+sI*-YFlCT=V zybmpTe(>cn4Gh0h-``s#&5=%2Q>VW3qFap!EO>99#B>+wQD`;IEs`ldiRmuVqtI#& zQW9-7{JiRMD#ablRx@0&k0jot!?3GiN;{aPeGKL4C9UQlwi?_FQ8XVHowDS4YyFZR z%#v3jC{5@_<(X~7cicnjVUtLj&|=U?6WT(6O=vd&T>p$wasi0YZ}1Wx#TME2BD?|{ z*BTy`z)?dow~ho76_+<#3E09WC=q*>90bb0#KMY#sW&+y6kn=BN~3*C18lSQw3 zb@NO%$XAqr_42Bfr}ZBB&?5QKC#lmQ^S-r6T0rN%eBdIriy<}ipd$}6s`N>ucK!EA zJVQz31>WOq^jdcs>or^BldZT*Q@>uPv0let86Wxv(W z9&%!sq=q?aO|wYe^-1cs;!`b>RIpB#)4UhJ%M*&lW;v}9SP#? z6)DYQwg%WdDmQ6>pNr2R5h{pNDyQNNMeIsOqS~zMTl)qcHv)2H%TMO?sG&mM7KJE& zupz_bYi2?rZ&M-fK(_Y%N&gNp{jP*OJv9+kKM9d-VMJBZmKL8*`C*Dv{d2Ll#}6D8 zb~3w3ihVng-5F?frlxl?y9MBH^#2j{zu+oA_m7!-Y`yCLa^;iI|EE6yExqpo(1`w@ zB0&A8Tn$d5|81IVH}(HjGh{9LpF@IpwIW6TwHgrpf20BG|6nBY6Rx)xg z{g*059sT#CAw)zBA^LH6jff#c|2I&Yw3V{{aW5D)mLFDg35LJ(_A2G%mscSeh?A}%HRjmeRx>hhm-ArXj_eI0ch%Hkbm@Zm;Bg68*>B0 zc#Imv9sB-tnw|Es$Vau9EvzcK;f}s2v3uv|ycNgly|W+_xf-uejWMF0js%semSL@t z8J?Z^{~ztP|M$Hd z?V;bHF#5+HDV8yX~QHF8XJKx+i2C9)gY5hPLmg z!61qyPP9f=9LBIY(Rwt%$T0k*2cvn*@xRee`1o}iU5Q_}(bE{UQye+$8ZDyDPvc=h z?9an3R4V?<{`~K{g?fjhg>i7w)9s28VE=BRg7y6U`Mupj?F55KzFVjm^7P$8tp~gx zw@}=7{7tt|8L%miTKn^L-9k|a-z`)tz-E6wI-@h-stg`>jn114_QNxH*fm;B&prva zP&Y#yxc0%X*gMq%$m9Q0KFlfkXDKju!V7WCPuWp*7?^@xzF7xx;# zY(hj+xRd${|7Bl4x`3eB*WbT8DfY)ucn_!|to=}!#sb2f4byP11&d}tMG+$?wo^ed zHV=W|K^aiQ8LaByx9G^xb;AK3SQRZ0=k;k*si$`G+I7-)^Br6yh+x{W#I%<{^E4XD z!%H?5)2%rzis2=j1*mlDamv8!tVFk|P7B_z0k_%Q$WDhZs}JzMk(|(NBqwwm$qC&? zazeL}oX~A#ozP8dLvK)_a4#@XpHMD(e<)lJzf!_%0GVW(xeOW0kMRk03K0J_pHOU! zxsLA>ig}7pD7sMklRlxi8E&@d;S-AKvr(E35Z(6)wH$GwFr^QLU&gQagc^zYrtcGq zwf_fvLUHK&13sZRm?nKfeTGoWEtpNYhX+`Z?(4|7)l|wRN_TYZatLBJAUpYH=h z*lG}J-#sF*gY;pvF@?GBf26R=Y0YuYJt4r(-+DXqm?>~JRtjfvPaIDu%n=d&16j4? zLMYxTY*%g>z6p#RsX>uLoB*W;C0_DN4NBf3N65fk$siPzNi3{vAX>{0`N`2hqTCe; zo((LX4J@7wES?Q5o(&DpHbE36MSNcc?g6u0@t!5&+&9s8Qc7B~-H7)r;|r^euM){w%$&m zQ10lWj%;x62)#R|Jq~Za3yWDq4acR;5NrDrChhs=A9%cg1jTe=f8W&rP6O}_0XhIK zz6PIW*8w;dKnbsyO<8kvr%UnQjeo6-s!DJG5-dv1*KnyhpiycLXq4jE&6=Z2@lD#v ziT8Ta{J*)a&;Hb?{T;tLVK8jO>`RfswBdc-7vvk+5#17a2e_?o~h0P8m5g2i;s*%UG<5LxTb_u-U z7;GevqjlpGon;ZN+8@zeaJtjV=f-{VdEa93?EY9#nAB}XR0{Le{)iTXXn;kOg|eeO z`$|03BC6OQ5jibTB5LLcLu6^@T8jmH{C@MPwTQ0U9})9;!^-F3z4IyiQnA;g&}Dn9 zfD?cINu!S~Kylk0Ju!&0+94;t)50{0S(vh;o-t|24ogF{;TrU`iCParw_T9S5XFHg zPGF;X6z2oDiok&Yo+i)`K>wQne226=SR9|P44wtg%aPibLsU}0`4AqA2skRf2txw< ziBqx7N>nF7$z(qPE*E41q(cIyM-OEDo~GJPS=$G>*Ihgo@$XQeg#e0g#@{ReJW5=A z6o3~A90cH?O^~&bmj7eOItZ!jWc^#RjQ*M*wU)GvLZWhf(B%S#LNKmfL`>I=3dB`$85zmF%n^z9EmZs zw+xdP^7S}-6W%aqC{;EDM#fyYm68n8uLy0nY&uaH>Vh`ZVflzyG%4# zzISc}*DgQcwGL{E(f=Ij1NYg1f7pSa?LeF7 zEY<_;z$81c&t^<_yKv(2ddDM$uLKTa4yzlF%xK@OHmhxV?-}f6mXADcc4{9>=}Q?S%0PZGm34pTOa5#IlCK+R@JY_MYx5j>_2l*cSf-*#dbYFAJ(29iTB5)9%JRd7O zXZ#i2YrK+^=St+ySHu#;*I4n_nE1fS4o0evEyR5WfkXZ{s2h*JXmTd2SL$FMu`s)A zW44)Epw6YP$3obY<=__h4k)u(jsd$!MH?%U)Z8$fH}|Q z2*WeQX6Ce77<_?n{AEqXA@U9*q3o)Zy{icJi}**#Y$dx1-ywY5nu*x5F`dp(YZaugg0?bRa6pn9Hsa8S*_chh}2%1jl z#P_@cdOXCwz7MwBt4Zt+1{+xNi03DsY@xFt19THultiCxp}YF%mW3Xv=tarYf3eVW_D%hwh31ZX-MlLr zT6!lcDYet{HYn!TX1-z?S&A`m{2nXumxgyFka~NL)RkZOwy!0tE*;#M3kF&rJ;g$I zG-!VafMTz*u){R*;#z4`^MU@mg`O&CqwvhXC-Xcbk*u|!=O_!k!ACDG_R*^?^us>7 zw!4ph#zMbm(80w^6BSZX{(3TV6gF8Jr+gB+ujzd0mNpF>|IpHACH9t)HWFBVcT$_x zC~-rp#5@lRq7bwh?$ey&kz$lZahjnBEZ(}rN1tP%*Zb%_Q6K%Jh2H9;w`Th2fK~Rl zeDt0iA6;pofAP^ixJ2r*Id%F4Pdn|NMgAOj<`UuFRWEHLIDmD^$WOE(m zV3Fu^j(Fdtj71H&cZ0=1`F8#;g)>mI0QOxP4M5eV_I@y3XnA=8@x8@qQn=6T( zUZv#p1x4Jh1w(u@| zKuCGNWO4g$!73t(_BC-IA~0B13clgu%#6EnbDX?8zU7)8Kg5T~!q9gnxO?&7*D2)> zEMNXT_|)OsX~7#55_=jfZ;rbd8_LBi5Wf-x#nk}X-3wqgfF}TyldR)fgu34c;7R}& z1L!#k(Swk*{vk3tiT7{GOeo(xJy#>|SZgej$huZrc{2vqtX*7`1ueMw?m!ebu;zlroX!@= zdpdMK3eOe7QEwU^yIJ_I?nf;A4#YnSg5s9}^m_mRPvkI()3c-rtbDSOm9&mAZn?0& zWN~+C7h@&syO6}Rjd3m;Ru4AWWp9~`mVyCX;B3Xldhtt$Z?cvA0h|M%oY;;#5NcEl z;9~$s5cn3r769?Pl*?OC&{D8q9|~tX@!>lhc{n?}M&d`O`R5@zx5SBvik(W4P@rYt z-*Y>%Ju@2<4Yc#4<)B8N2T{S?B5;q9@Yx7=n{f=*sHRF8X&4yKep@nienzg1k(|q@T*e)wjQHZ)tnn%!ypM(6?4uoD#(0|Qnq$o~25rWg_<2^rKJ^nO{L{s+wa^|0c9hNfQiyM{(CvJ5 zVs$0{jD;TTqj&g1mwlmVSz_tOm0GvCEU!E7IP#R6e|V|ffYj||A;eI)qs_;B^Ax@s z{`nx5nCZ>X1j`;m+(8#L0>AcxuT*|FsJh@AE*D=Oa?-1PN-Y)*jzf}W-EerZSQ0#m zV0-M%yB$-E!=BZPyKm>)q(tQV6zJ|z^6w;<&`mQNT z74qf#0llYewZ@G=<1E{(0ik|U1E(jb(VQZIv3}zj`lb?Ws7tWgukf;+N?=q=UoOaW zIb_(ah=oQTsCG&olqV-O4aJiXzRT8tq*y~mKH`70jZUdW_+p0T#cRUfB23MV70r!) z6skCxsv0NZRR~uMde7u`JW6UxkMiKV^ib&_Cnq|{VTc=v{fNIY{iTwAwkD;s5ZKU+_E!<-~J7Fa_e+dyvL2vBuu{pov>Fvki^^RhfLtOj08D z*~^s(TBQ8pCnzNgEVmHH=O`%)e2*cG1Y)za+s7}lIDPQ@obIql8=>ByUV1}KWLifB zPg>b_HN=s?YY9EeVUeknbC;A9oxAfJ?;jx0MB7qW2_ncH+^U zrUV@FUa;Z^Tk#)T@iVOW6sXgPve%tt328^)(v=(HluHu(xa zOVQG(d&yVTWqc#A*7$~|AQ)}eA+gyXxs0EMD^XA8JMc1o2R_80dx0hF%thqaJq^D_c~q1VCKDE(_zq-$E|79-p~7L=6yK0o4l`P-WM_` zd0)-sZ!_<|?LY50+WCI+F5>%PBNNx|llOUvyf-rMq8I$UH!|;|8I-&w`E3YRzOeti zJMA~`etVer9C=sn(1iMmhtjLD-rN-*f^+0u_A|Kmbedw#7c!YOoRee?XP7LY8aRsY zK9JPw;FHW3lI}uc;5jd%q=&TqNVMztRop$1;$$m@fiIF26`BGyCC~AR6sK4z41Bkw zICQT(u1KUAoOGuvecq7a2}}2Nz{Ed z8lt;2g-RWa$nM8QBs>;eW|EaN{3^{Ibt2Di@!SpaeTZ%TT!Odx_dpm=D7*}rM^GlG z5AUyXSEg*&EFTa8MAiJ<5fdKSC|H?7xE5)<$SrOwQ|h6saHY4q9L8LgQj1h4AS_dm z7nId%6xKaAC4jV@I0fn1iHief@*&H_hg5!Sa%*e;Imd$3l=VVOe+Ir5?1%52z?Ahu z(dFZmM|63iG~Ba6XAG!CE_IGCM7cOq%elQa*M@t zby-}KU{S3^cZ0>w1d&s5rp7;qc#}8vp8^F&Xb>0*(-f{A?I2qqPTu1=&XDnF+-{Tl zqzcsP+TI8rjR?!ph!Lw$w6GkF7}+1B-tn^Hz#%)c7O2eSi67eP8H>$P^cxxN=W>u0 zs%FliJiIXS^+t%lTGlAI^PNeHNF^9We-F_sU79gSyfcz+2%{H>*(8k$GTAnqk@W8x zy-n;VxqY9>K}vayr2Et8ox-25QX4mV7Mh>AO^mzS!YuP!q;*E02C34j*ekdPZ4wb9 zT#b$7C^|62U1{8gG%;gn&9)3_xT+&jnKWO^l<$<0)(vjlxyf7uLT4;}J=Akr;g^}+ zKtwG7`Ef?lS9#QI@A9)ZbAqo=zjQf}GxCs>j_WQ$;Ed&Q5?r~AUseTIdkj-%;f$uY zwfc8W0LaA{gTd0FR@BICkfnj~|Hu}plJrL5J##fVzx7NVuVJcM{5YeN*TnGy$p|W{ z9C;GN@Jt18ZnRg*X3i-3?TozTvX5kn>D26qJU^WX6& zSqpyFwQr&1z2^UCJxRU{&6;c9;7O8aHO#ed{|!%)JSk(YeS;^-FAy--zWvX7lH?g0 zz4oo%@7!ySGg~0^x}w7V15c7vo?QDDvhFnxS@)VJJxOi=X(;?C@{_MGszXL?#!?iC zt%p%UV)fd$$UgU)N6Nq<6fOi|gNDKS9nS<1t3XFxni89f{=YOB<88W2!?AP>a!X^e z<_u-Wg2dH2vG*~AEM4lx8p!{Y*i%5ev7z`)iET#53dX(y9Cqp+p-JZv8ofUKa(vH5 zSKNer8<`_BcL0oBg&#Q=;}ty$(432b-^y}yu7B;fvJ3MRBX9Vv?2J)m|9&e|AmIM} zR`vvgNxt98fymSMTlos${rIi?4#odXzm+@}<5}0G*Y#UTA$-4;Edcv|D@y^Jb1~k$ ziC}Ne#dy_^08aR=dBx2I-oQ%4==m0JST7WY=UeLftz>%NZzbXV`K_cJzTZm1 zzTZk#kngvW@SpKpNomaa7H`5Zz&zi=0uYu$@Deyi1P`VXCawk86n-l=0Iz;437YdQ zf6Q;?1E9|a*LzR|sX|6b75e8}ZbC#;_^tc`|J83L!Qb;+$0QJLM6fBr8#e=#(PkbJ ziJF$+NC!MS@><+Fo*m^X@jvO=QLYk)XGhkt9vgvYM`ndQiridu)IaIju@N{WJUcQy z_0NwGIW_{%j(-R9P}p4R+YWg9W^c}6{`Jk?+4Kb&FuovHGerxG$R_OAw|+mA;3g*> z^w#e-5YWE$JLffM-)%#c`*W7d0rPQdmSP}oZM?j(<1c&_PTu5mD328vfb~G`QPZ&Y z-NWwctZofRfa=YhC3;Q zI30FAHF+klp!wPJ%P^f~X!wR-hT~a=nGAlw%mv8V_w?b4MyP;pxK3V;@+r6ey}Z?m6?3zU^|L zW^#Kjzf6lFsvfF=uE;0<0u4~_`S)mGEHE8UR;JrTltk7E9~vDlP=aZo{#=O`iPY8j zrPG)E`;}xlNYM5UN4?45)F@2{r`}FZlx^_}Rz$5*a}vVGt$DD%UyoO?9zRB5Ok2E) z8XJu5)i%qi!1W}&4ne87CZ9`kOmxiSUUM<>leYKgi5n@y)4-XwbR&yUz5_CFkZHHeaKb0BJnr3{!Lse0 zK+V|!;AQ}839JWj7l2OPG{s8jidBCym55~t)XQH~I@VZ+9HqM+fy2R*w4f?JSmUi` zlC(|8|MoL5!XqspuKZZ(9am{!v+&xtp7W1T##)Kp+4**&irj}-;z^1{1CYn9`4)`g zG6+7zN`v)j&Zn%Th9sY@s>kHp-ty$gX(vUayEC6u`%=SnL+f#jVJApJ--_mnl0a>d?b6r~&W9$Ln2 z$gdEIOqs@V%=r@W`B!`)939D1`t@Lq!7E4}_o!h=C;htMeZ+LgQUZ2CuBas14UTc; zZ&0MvTMn(b-L(|rHjN)(n4$=eC5o_?MHmX+reCdNWuJjy**BU*;n6^SzP1w@SlEgAf*>xRI(H8{8!D;WL z-DY7ux3tZ*?q7b{0q2Qa|EDH6sTzh14erHyN z$IkF5w6ldRyF*u;f zG_a$S5>CC6gl{8FC}$197ELiAH!lMi`3|wM&_xc~b#x6WF5Zr4CprWqp-UK@V#e+m zK;c*)y2h*1iO?-sEd1FhCT)qN;aw)_3c|a0GikI5;V)hV9E`pIQNv%)gx=_~JQHz| zLa=Ba{`oqx=tt6D4U6kYx<^=eA2Hr>A0!WNA`*mMyb2H(eARg?RX9tMSDmf=zU8}xdg)Ac%+H; zlt7xdh=GcfN5L%SJ;Fe*6jo}MH?-2gbX}$u}YLBTDE5oF}ba&|Xw1v%-(D&BKUq8F=pXOov+tm1hL=*24D3*;7d+ahj~ z*N53hUEXsr&6`1Pda;W43%TjVD&AIN^kNn7W2VuIRlKPT=*22tbIO+G#=-4$kLy!j zbC+HtR(KDSfnKcQwL_Gr7pr)k7|@GVylxEW#VTHJ2J~VTZy*D4+!BkAUoVwK(2G^P z3B+`9tME^k!_o?_hE( z9V!rRC;(1k$N90k9M<3vHlR?LZ6_3-1#EiVb*e^Or)r$MU!~y+e)2aq>r__(Y$&S% z%K*iScrADX@!yi(+0DZc?(y!hbiH52n}$r%^?ns^GV)FDF30A>9}c&7$Ru`*IE;xdLLM=5ze<$1n8uDJO$OJgV$-OktSC>P$K+F|B>FP)iXBHGxUz(ivN~a^(}yPohsIWmtus%yyZgH8g>B4Q{5a$TpI3s4$NrCFzn4Qz)PU8jl-D?nkmP8Bovt3jA|bV-z!T(Pl)*GFGr zyt!W`N}J@ExnCvfQEqd;O7vsGM^YNIP8FNb4e%DMQ?USqr4U@FVuY+y#U?HW*t8%v z^E}|A%PHb)f@Ym6Hit?IN4Y~6JCSfKN`txBT&gN7+J>q+X(Q;f!Icv(sX|6b6`C1N zD7+RCO=Gc>-@yOq6_kGgK_|-FrDLZWy*DD9xL<{x2dkH$YRKA$ZxVpQoej)z$LmVg zslN14Y;S_%I#qoHnw}GTV?6#xpTUbD_9ipJEog+_A{>mqL0Ek0g`*8Hn#A5GxmNrP zfTFV{xW<=+AG9IQtk}-`@IPa+6Z=RwW=w&LC*hZIloR`eP&fk(;!{Ft8OJ!W&j`gb zraH0D31v9JBgt>q$>4KfL3(qy6*{Xo3F=JOn@(gsEM0Fp@p$`0y54l+(I-cGj=X=e zJGj|TYZog_W$nG*q74@-}`Mc^3@x}17SHz}6L|qXRey#68HM)mT&Hg+%1uct@TeAgUUv1=L@DL6$ z_r8xHn}ebMd4)_S))@vc}F*@7EC5QOB zyaPhE>lv| zGQn->i`z}cm;ZRqui*E8apC0@=t$0V;QfDb5tY2^E2PAOZwGnYqxx`#;Z>mKgJ1iL z75{EJKGJAd)Ip5-jri*oIf>$*a1s+z{7aEg#D9PQ#eWxoQ^Xo-^R>w*V*WYqDw+hh zjiTrWega?*Xa*Aa8o+S?+PBvfF2=?Vw59`n5tZj7609!Zkr|QT8giflA0t2sJ_g_v z&s2e1f>$#rlKhsiTq)tN8eA{&4i-VLqD;{O)-c2w~Im8&cp60upzluxatRvROxf zZ0hYINvB?4@*g~bK*Uae)xezybo@dCE0Kv2Ueqw$H#hA#NcD76U4q2oT&I+84ewXL z4kHBzR+)9tS%-|Uhrks+TYX#hh?r78Y7(K}^2T7(Z`-opo(qW!uxe7kA#E1|re7Aa zUk_q7mRQkst5p9iEGUq@@(pR+A5JeZImlB}1#)&dY z*DGzFvV6{G8D|At03u;|x002RWmjQ&m(TJIpQR(}EAv@?0aj2m%>e7_x%11)?Ttpr zH7QTwo+j|kVBW9O2u(B$sY@&PW+Hei1#R2?N%a`R9Rh= zVD%_j%_XZJ_s^;mSQV0$+y>@+XIPw(VD)Z-)i$!)1XcwnOvdusGsHANo9}#vCXynC z!hF$oy_JLR8BKiFsHLjygR!;yC47zBlOm%s;0cy6OiM1(v_<&;%9k-wvfvxT+lv zXed0i-7yJxc)O_y_|QVJh5V45;A6?@$u+D78~ORta~0wm+(@v3RyYB%!r{o7$yZ_~ zKW@y#s+YfN#G%lv8u4vtR*ibo7$@Br<8T->>sNe53LB^QJXBPpdNPgR@MV}&9;bH- zP|--lDMcb*BXn=ByEQZ} zXE_|~jqk(tu)bW;O*h_ZWkQE9t5%q=IoYi-V3^gezo6#0+O_lt@W%6Vj``oX^iQpJ zod7mL3?}#urcTEtMp&4-79q|)oZ#ux3GN62Tuu=8$MygwHH^Fe7<5DQ9~D3Y-D|ar zSXu2l6F_3MD-=E-L457tH$sxAtX71+8H0j&T&)OwOHr^qfS=G$r1r0YC5&%CWEc8{ zaF)l_iqNlwvpud>g!T|FNaJb+u7PEsB#o;TxCWMiZdlGlAVmU|X#)u966 z9zWnDmLFsi+t>+=0~|So4JZ^QlTf%LW6A_%V}DfHB^=7x}93 z&SMnoHv9y*DB=~p0x)5`GZf16jdxfICv6&kx=Diyrg2dOm(CuHZjmtFVHGEgcbH~q z+67G0%WaIIFJZhx%(yfzir~`OQD8913ACaB?YUOt8}HCgMvZqQds%t$j-d&JZ@k0! zm|i+dSQbURX{?JZkBcJSbViqWTomz+qY%FFPBCELc!xVlzVXg%jPJhj&dY#LaRSGK zo!8+@un2{}$8QtztOt2B`GZJmipD!Ez8de4#PPT&;`JaL^tdSEnMDzgiy~f6#&>f9 zZAn>CA7~oy$Qq?F-nkA`zVVLX!9@|TKjE;)MGcF83>X@QkafIBPRz!8W^ z81Ec{!WiQnrguCpig+WK-Z$PM>>KZp#=mrya`?tOgni>3R*-MJL)bUoVcLxz7e%}y z2ygQEj`GG6zRlyJh<7BV@r`$AFU3U>7J#r6f{P-I2po)5-o)zw(s+kgxvKFFLEm_X z<6_ujy?ZATj(J=Z@#Zp1|I*p#K%Wh++klZOWQ0^^z}x15ia|dSds%y8cZS}uPafEYosy$Oo3We5c5k=7HBv;i02 z7v9C>9~g`mp?3+#i9ndKmtINm^riqWV<`i?71`U!mztRHybo5s36B)XH{p@dFpWzV zxSW-kSQ?isa5*d4WTkOg5tp+PlkJ=Eu%?qHJm-M5nDCUNyZR3R8M`;s8ESh=RLin1ngeO8{oOUGGM; z_d27ylegowCahiSIH?e;zzpj!D* zO@W^g)-?@=)yk&~Ww6&YTK0pqDN|YK0GFUl3JIGO#v`FFz6j&d39_NWxC&`ghEi(7 zc&IFv*v3e6n8Gqf$~k}%Ka;{VZUB?v)^c|CnG}lAhAkdQa%nw(GS)JlNg+)e(TGWu zdlcs1+l4%@CBI{z7dRKo87~OeT+EYSRA~CKj{8!|VNgfz(VZOkWdYmf&8C7I2Ba2H zUt59CKbLV;jPj>`X8`8o)?5J@3gmO3io<1pd{Pv`y}^(nP~i0lw3~zvu^AvLx`x#_ zjP!3JzJ2PChQ*;R@V~=Gol}B^JcSb{;u^29e5W@41}rB|gu4+5c0rIWX*4n@{*)S% zkte3?^dBU97++mRvhkGcFr+JzPn8MO=hx&qJr0FUB;irtV$#T(9-$1tT^@Hb4?va- z25J*%N_qi!pFk;q=HG#)(GD|#)^r6*|McB(ZLW;Ntr#`>E_&at0N ze#!b9g4G|RrFqoSr4$x&oJ{rRevkU28=UqaGWEBR^|uW1?JrVRQh#08`nzh(4y16G zmmGsA^D&n{j@5KF1z4{%pBXt&O~=*u1vr}mWTGLMYC4D2^g4ot)5}mz=Q8KPD4kT( z8_LJmxqJR|kWs4XI?zZpy-9%8)P%$xDPrJflP@xo$GzffCZnhmNYpOY91Dq%h&s5C zI#`D2uKhGwD_~FoTqtn5jn&APpy@saQMYDFk5UR&qEmXGiY(Riy#}P3^5?UHuAzQb zYm%o$JjB*~pU}@W)X#ND7@yt^hrD^gH_S`g4R7u^&w$8O&_>eN1DDd#zZf1;LET z7S@>y`oigSf^s*7IUPZ%v&)rFqR#F;9ekwD-UdqQtm&^>XNLfAN~<-A=xmDysIzX* zY9Iq5-wQU0e!&ysT|K78v)y2%!pd4`BvnB2YEc3^liX02{}OBANtU=$DPI&OtcCdv z{SrUP5?=y>!ucrSwsS$!W)JEFOASv?k}5g6JDb`W%42nNr2jh|(n>R%0a~a1kBVg7 zls0A*9?^dO4V2<7N|CMc_3@tNhzDF6{-D$ zoO?VdHx)kajWY|+)K4~(Ox*^~?6;s(o>bn%E5cXuf z`1&bVR*AZ5=xzjFD(egoNhi6V04wVo08VLhO(S|6rvd7%+iVRChOR%5Lhaq^yWXrM z^&qiU7>aJ)iPi0XrJ!co8LGXyPVYCB#AcARQO!Aq!@pPvLqeN5lL%v&&*X(&+McE-k1IOEKdDPp>b&tZHc1K-I?YHVPc zC}kK}rk70&EYr?R13v>} zYRYt!E$=!sL3g1{$nd`CP0WX`dma+Cmg(GwGUdyYT>t4Z*F2HzBh$osM3^F10y|XQ z-{OtP$E~4;O?%6g_SP#E?Jbuhcw0%45<+{MIqw7qZoD|9>&~#uE(=_yU5_!QLTaMW zosZVtw1MmNWh2f*!{t+g%6B`sUuD9T7d_qgo64WV@zbBE0bHTnibMle0$2cZq5*W0 z^D}{~0F*QWa5I3b3ETx>W@7*k1Nf4_a{wwb0B{xh5dw6SGN=iFuK+wsU=M(vuoi2# z8W}#CflOmi-dTt#ou*RGLOU^Vn$JnfiQtqhP4fx>r_-%Uf3&269*|%_UkG{X0j@J}7y#ZM zUiOlb`O~?%9Bhcu30+_Ik(sC=J~5QSeJ~{ziZ9{S!JEOVKO+asL#RzNDCRT(4Gwgj zK|Jp@B+aCo#B_VylHG{=xjDq-4e5uq0Ps41Y5--Um2?$I`955P-w}x$$vfpT`%W)- zhM)fy$b}#SS|i7+z{2VD?p|mb?+qve`U|2Ap%*1+8ea21<*&IQp28vh*P zO9yK0eSkpK;TpJ6spX9w39Qh4Fo?@t!)}#m?R?1KK_#7!cwdL)^@fQLu2~Of#bqnB z=)^z_6N}+(HNrHCtdP%-9xmta{aT`L$oGc{Pem9nKTr-zQ1%qcl?h4{-bBhy-$aab zSXhu}K_XSTq^WH{7cQ+fvQ$*Y@Fy7rikn3;>?NDiIFjM4% z4K7S;%vd^H#?sAD40SnD=*x3BQexXn#?8&G5t4EBP#IUx&Gp~&qvbt+f4=JsmUW6T zF8QLDPplAo@UgN|ero}_@eMf6eG~W>5SDpBKb`cU2=cgxySHIDmm%xGLLGh<65u@G z4FG78t?<1BBGY(}k{a&X4jD+}GT}`Kqb-0k*vzM#DwNw3lqMW6B4tT7YB@o9v`~%# z#_%-Z^MrB|D90rzj}gkhB`8h!WuaUR%Eh2GE%5}QH2e(w1F8CQb>zr~fbcBMLB-5* zFFOz#I1llq?NRXS0bEYtG5{GJ04xKr96*245BM8G?-jewkoy4)coIKLN-$c!2;eCI zL*8WcNBG&@2`{_j(Lj#V>~=7_4^j?icFPfePaMp}YjP==6FXovqVGj$Kn;NQWdLpf zu&^_L%>a(>3c||PAgo1bTMtA(4d9q^m&Iwf6qpmheZV)!{&Geh#C54A7{vJiBM**j zmox=M2z`qYb*%nP=27LJ9 zT0b$QV<={k+TvsuIY|RDi`=dO4zGo1r0Ct=nvE0JrbPGbX@=KCRV%!(`3x~g4C-~K zkfo>Kg~^AbO1H~ZiaiL-k`!{zscH}2WqkO-!~sOPBo48Zc2@O}OI3djJW!WItt-*G2F++tA9t}UthfXBRXf|;?)f?@A9?y0ubu>EULSOts4?7^J?iK&7lG4nUcB09GA~}Gvk$XJUH9Tu3gKV8%Kb>Q zM;)C(Yy7H4=Hk^~porm(%*Cry5TCesbqT}?h0nlmV~&cLSvwj0K_oTR1Q)2X`2X$& zs+S>cli|_IrpR9}Q0)M=W{>)}FHj}9+HdCrv<>&81K$GA%op%en;ISV51<>taKG*a zs!Z=+ph|du7pPJW{{mIQ{spS6ApZhY!hhxhRZ4Sv)3@+Kj!yU#F!!ig0Ky5weMX4k zesm&__%y)6$(rhBAVa=RZau+0#$-$ zk9z+Xs8)elD114nBCP#T_)7>X+}Xek_j|yC8>4jNB`CHxK{5701P;I*ra^S1W^#vV zvr24>xXt7a(`IsqX|oB42{wBYojBDA_Qt=oHm@R`-d@@aNkidm{0e)X8_giQjAh7K zez3ocqfu)RCwthQZFcXe*}d#xdunzsd)S_u-OC=fXPe!7ZCtj5~N3C~*3U>9bLq4xsRFFTDbBp)jS#5hnb~ z?WMYOJ?$2`j9BR6@rszMRXO`f`?y#^6Z8;Y}3CqIiB zgU7Aejl{Y40QELLJ#rrdaBPL^81$a^!`6u5_m=lkfwClt#ozn&ND=p?q? zuZk@&J9|hP2_(KcoFZO2V_a}L&Cy!$fQvkC4bNe;UylCfZsb^iZNUzeB)=_NNzqS~ zbV!2qHlLJ^^xV5jl$1S%k6ZH$NQ;H*T_pV!W$%auh`ZTjC-lY_-9$~Y8j_SOu>Y=Mnn7`v zoiPL0;gwj2Wh>jId=e$k8;J>VZYtEi6*Rd&f~Eo9xw*Rl91g%K+^$LJ2Yot-As#k_ z3g6Rc)*7!nMRZDdnp5a;X%WwRi02)rjITy<^ELh##Fq@zKo%By3ny!!6ajiHHz`oj zDRW~^;T*-XhCWj4T%=l}@f3@_9I32^QMk@R=lke{d)vZmEUvu`nya1po2_KRakqYF zQXCWm1I)1?k93n^okL6+SAN`u(vfR5^ z7h&24DTmhm5at0Rw^}$ZW0)2~8osDM!aOdAFbCMm0j|>pD~5|*&a=KksOteOO$9(# z@)V=4yS+k|*W*T8$R5bPx3xiapN+1467XGQ_ieKbGE)X(qjHHdVUL{%0v3M>^b^ZA z%vtNKC&W2DI9Ob)2_ULG?pF6Pq>};T3~-bI<2C{uFn$J*f4wF#0|u8FFl-3N^4lO+ zPZ~M8E2Utq24UrH8W_80i(1AY+?MUR0TxgB#BzaK>&BsOY0T?EAdUHJ0&L7#RmieT z$%mtO05gQ3}hX@ zp7dj+Zz3q2ahxWEp5$?lecPA+sKF}#6$B{%%K)4Ts`?g9R>?B2Yy^#qmirF@C5Pq3 z1gPch0G#ftL3Rd+I7pqxL8{e3SjKFUW2Eh_dB>&ET|oR8;5*KrJOefsY*eQrSXim# zC!+Ds0yEYOEe%u!+eYV zhskUUmuoyTNX7a^-P*}tXQ2g^HCyY(DcZncT@D(oSE@X;Gd^z3>Da_FL;Hu)SyA%h z`&n-vE(d`{mQY( zz?u~kDz7A;Psk^*X7z;lS_b8SWbSYf(|p#IQ<8x-=S=7WPtKonZh|X^CREBiVHZCs zaHqh8O5U61?&iiGm#^bXp(XbV&QQ(-qry)uO|(rHMX@Fdurkhv`Ws-PBY{(VC6zp? z=o2_R*K1>FS@p*mS`L*ZIU2tjJW3{O;B=(u+Xd_Fd@fOHOgjn}YaDaD%g?dW&#~}s zMPG~bJ2hD~sufq$ymn-$z#SJ{vz`AB3$EF5WC(AQJd*`8FFZs8 z3HmKW9M&|8=(N{;jU8;el5YXb$E|4($xXw1jSVk8!f#ryv1uKTU{*(LL%hz^cOle= z4ebqn#`6BF!sFYTvU1#M305++VK8+|ph1||90~=(p2#U#p@br6e=dTCH*(pg|0*yJ zi=&tUK}?vIA;_WMd?4^emBC^-1E0iOrTz|=cn*;UzeZ4&uU^(lhQtn1hrgWhm=BFX zjRAUdT~2#4*r?6N)u7>MUfwY->o9}OSEJPhGG`MR<~yk>>4BI7Mh0g;84WQ|IRkGc zj}u*TbI#6wtfV z7{i8dKKBQ*7QBTb1)FnH3R9$kbJ0b;W941@4)H9OMZ}>-l$Rmcoh0EGko-U_mJS~~ zpc*)kIZcs5u||`H5}wXro*i=bK**r;mv*RNvn2X9Mhq^AuGYrzDTw&2?fw7PlBhbr zfkijOke(BM3AT79Zb4}xgFvb3wj@fs{8V*Y66HalRCQYt4AOfoahh#TdQMxTjRktP4=9Dc9 z2EwSQDAy#h1j?z~is-{+pl(Z|?I@1AEs63VP^!8uiSi&&s=6(S@*q&Ex-E&)P(C&8 zviWR@rm_g?wj|1fK&f5aoybSsmV^o_5%7lNhkt1@1i)z!2(#)r=OQZ76?}9FG{O@D z1`b9%AnVC65{~d7kb(6eQ0isjuThSy)b&(egl>1RuAC(}_m1tK5n_U&nCW_!*>iTaj<$ zkqFAHp%rbeO>fpD+aO1l`Do68#5pa^yNL~cc(Bg%dswECBK8r4#IJ8Kz#GyqlnI{e{5|cQzcqtf6@;#2fjXeEB zi?hH?HiSHDL&!U3H8}Z)7Rkszv`9FEgYR#99H$Wep~X7^`-c{v25dHjym{Z_wP!Yj zylQ-!_!~lAhf^UAHp}rVtM2Cm$lwnmsi`J7w8-NByB^0cLfR%cwAcvwtH<#UVCx@R zWa)yQIkZUFKeR}4-4JRG(B2U82L2s9bwkJ-#%UBcgz9=6XL|q8B4Pi~BJ=PMEm98u z&>~^~&>}0yKeR~LKeWiS{-H&}{-H&}{-H%mV>X1m2|EFELx=?+oY)Xzglq_T6FUHG zfMqBIWlF zEfVITMYD29FFz61eklAI1QqUVV1~Q-&X(5hB2|oFwV|{GW$4~pcmYV==eB97n0yUB|xK*$2~O9Cz_rhdP<3OJ_yTC zS=l6~>x78ybC(jKWf)Eq=v=Vi9iW~AQNb$!ek8CBKnplLZTFp~Xn={RQ$!O@J{ysW z<*H`o(wMjXg|L|9^OV8xWE4=iQ_^23Yk#{^@Nzt)O;CjAn3PWY?Ml%A;@K1%eI6bD zsT4(&rd2xT!mhYA+^zA4qDS$;DNVF0)A)~NA>X3UGFnFR#uNkx@^iYi@809U?DqtMF&%$L`}^3 z5Ctk|jBx8Cq1!NknFM|T@jU=cGnlQ(hO-%*%)3pc8Dw(BPTEO#7@hK2N`f;Be1c&K zf+n|Uz|6AT(In9D%Rva`18;c(#~{Q z25Q@yM3hVdtLQFCN>yZ#Cdpd9xFzVsf29y_xkBMM-{xSh;{-e6HEh=P%Jrjmxa#kU zrjQ2DH~s&^kJ|sfsU!6m3O|P5ItGsiL5t${=l`t1BNxk!+aIj?EzJFj>Ign!o9U^<`5LtZxc?)bwx2q()Kf6lG;oDUb_U$TJLB3rj;Xh+nNokDlpXh|c0P{1N1t2Vi;OPrS$Y*qP zB3*YkgS586j0@ zT;O3<9}!JqSNSvkt6e3*-?OXa)pzDft_W*C6sGec;m!tTxYvROz5LMil%Uw&1jShT z2*N#n&FA2MOzbLSVpkaxyULi@RmQ}wGG^IT)^F1v^r0|4^oVt3{Q>7n1ediWlT83J z$<(+YTm~VGb!8A8?!RVT$@Y-6u4JBKU3moa_;c2kockCLL9ni5de&732<=-}#t;_@ zQ~FSNGJeIn@+|ARS<~?;J4=F8Y&Pf}8FRv!PGonv`@4h6Av`Ny4>;~_#y zSGLu_VniDaOW1f+>YCJ7S6MU3FQCx%QaAwk6V6P$efhXGuk%yw|6}h<0IMpl{_njL zo|A+<>}~->P?8rCwve4ALN@j#FHmDhUKYt_-g|){B$@zfttA19w#9&3TQyL%etsHo z>0%9N?P@?%Ynx>=7k?#t2YNUrXE#3pxW zCD#=T+v`ak8Hq>&s>XG$k>V*btuzgGjd`%Pb=<+mZDlJL_%1th8-Vqu?%fWMv%RKUX#*p_{tOXV&ZN zWrQ~V%ssUA;WFOh<1>j*n#!=>^bG{=*I6g3oQ8S5nS#8DgF*b05@~y=bhJ0rI{BQ{XVW+c!C4fBxsE1d(Ye*9IT8b_1b&h>`j))S>QkJ;Y?V z&5O~4*Wd|`J&9Oc%v4pH=;Wt>i_W0!WN}wI(tl^CPcq`JcBBiaQIy|TXv8%-($9CK zw>r|NI?})BNY8Vmf5nkr>PY{ZBmG)O`nMeEJMDDff5?$;Ux4ic{!cs7zo+sG-;Yq> zdB+RdqJoAA-}`v+lH&z^vx{HsL)V>jycmR@=NCPA(dT$E$$s$`USNfvM~XT-OTD1Z zn>tpf)9?}$x;M#~Rzm~%I?1;z{eCN#Ci43;N>48bHsjSM%-7c(}{xPI(3A&>qV6*QndRtMY+H2cn!oNg}n)vxD&u2#Ay1NNgZZx zVVe7qE}}h=!1Z_78>6UF<#-9$DXQGUbhxlWQROy{eFd@PHfs6}4DSQPnX&re&@lZ0 z8vmJJFdxNCkwlDDU5S02#9OaZfY|HeDtNty>mn_&+^=ws0B`#)b!^Cd>Qck#1-#24 z>)W}u78DzQ2i4xe@hLRRm1;1kP1U^LoQP6MbMWqY6iAwhz$psEAu#-E)ZCzp?BSZ# zUfL9b)uvw_ zE=$*V0vKI4gs@^NjN9W#r>%~5`Xi3?2OQ}?a-{b-(%*2T|H_dbF;lga>V4mlevu=6 zFxqa{o9sxRGh8EyBz5^I?^9^r0;X2A9bWZ>PSE3NT-WX zHU4f`xELL12WYQO!_dzo)#qjQyiL&=-h|3PfB3u~c800>@MRv_pU_aVvZPAT7o;v@ zMM}l5qc|%XzhpJ+6^gT>@k=I#cQ{IU`?oMjmrUe&&q$G~NvQZfE4D z&WM%j#K0N3${D%Y8F|DJiTk6DP#3HN1+kdH{Yf9*0~e&JDo3LSj100UVs#3AXpR2N zJr|9_s1)PXS{jUX2$VM<5I{g;YD>Bvf%_J2+C1lxbcJJ`Ldc+Nd9p^K zi3d=S3G+Rj15M^XGuONxnV6J5Kqj6E64xU@gt;66_jwr#s3IkjdrTrvZ2~E|PiS}- zp;wfsraqKC$Py{OXHVzGta^~`csQf8E&(>%0XA-{2AheJF8~FUj_9}zK;xn^RfWZP zW13O`}#FC^LOfXSToOn_M!vYV9*&5h!n|=);5AOPv}fcq;sc`IcDmPZK#1F+a2c0V3w|CIpC>$81D^ zh&ldR1c;a;HX%U7{BsHrHOFj5fXF!yfq6vF^N5z`5gpGX8lFe=n?k&^P$RLAgj_#! zBw>(%biyE&60>F@)&@B4AD=n!?Yb*4=Cj^HRyt0RB|&YG&88Be@mY#Ard$T-Bg_p1 zoiwRJWMI1AMFFDwA0XgP)!8-OD+#%TY!rNPN52b_U2s^9?3*=aG%*=-Z=o?*$tJAX ziyFtWvb@qFZJEsWLVh)#Z6}XK2Awgji^@z~h2V9%o*L*S^k?pQ4CmRVO}SYj@Ke+YURf7mVOCKE@Okov^=xUz&*vo!=P zhcz<}#+h@}n3BRU8reulV1(ipInomy>FXWoIga#wj`R{o`YVp~CP(_PxuJSH9O>zf z^m{|;?kY#R#?irq{AZT_7m6h{;MLDQZyI?O2qdk+WAe>#d8Fvv_l`wo zcchMyRR?iE6Sa{~Yo5X?zW@dy55k+e z*mYE_%IctUWaLam1~ziaC_qNejR?4-<|)*bk;5nHCcmgbJO>0Pm(5ohNRJ0sJ^-*q z7h-_%VVHY}z#apX1@P&7jhs%Yx1fDr$W|q&c-#R;Sb5^;-fS*Q0xa zBA22H^hPLaT%yK6` zgx8(wHQ6k2c{-i!&__6(#Yddi0q*BExJnJqrr>5rra#%49<_yB+!K!1qc7qXM~e4@ zuP5rUc^w^@s9qC!#C=Prlm1c`Ovl{Uuj4mQkkVJ!uj4Hac=~m`kAM-Epga08v~H6w zLM%4dk-jSk%7`o1=?jqmn<`xaH{#alVWNI~UcGV{{c)!puTR^r&oKPs4993iLwFG3 zW5nVv(&<#~c%2S3C$Dg%$N6=H=p;{NQtdV3+Vv~K?P~SPK_qc|^=s;d))4r(Z|QU* zp0DWi7NGOABmE&q`cECz{8*(ss+s(I{hB9mcG1#Ra0S;IIK*?Yv5@vY$ZybU>B5_l zB=4o*qB>||{TB@ZW-fUVl+nfd#MI?T8SxbIjWL$&1lQuu8azn=Qz!8owfwS}j%W>h z%_IWmB@1II8Ri2P5o7u(ksqxz3%TS*Bt+8U$Fc@EqbbWC%0dAKr@pqdEJDAe9#b#L zfvjFG--uae(0@e`E;JU5i?N)}j}80@A1xz+uD(<#`6V*r}UHyg9mL4w8)JbgpioI#)+r ztKQRmXRLe{ZO46C6jAVu9}dQ}Y3!d08c;hwBF{^(NF2?`I6eu?s&q&&l-M?vsKy-w+) zc;|oAZzz0$Ay!l2-_kA<{jsU}s4DoesmBqq&uvhF;JFQo1kY{IjRL`Q8~=%#g6B3U zTkzb*7T_N|w?S`$=QeHufUE3}P4%Eo``kt$fJM(n*61>>UVm(=36Sh_8T??uw9jo&F8kaDh3VXe+Hlf>T#+>T_$D0?W#~j;3i`9i zOIu4mj}(4I^v16!^&Ujd{A$!i;0gN(2jljSd^L)OEcDf=@1r{YYE*#gAhFUvp06ei z9^oJ%6FkB}wFi%Ij0dFPSEHyrbtfrT_E)1WM;i1^eqM{`MUEpJ-$b0hoTQI%#F8>7 zrrd(!;@9*}9pRujZ!Qp1W}!OXj3K7%L8>v9w#%A>Xh>|8=2^g?KXcDIC^zHOfehlx zTVXn?ZRmq|sJ@7$G&m84P^6F|yw!Xt!PExqGKCR%wUb__D3?H6+55S9IkS7`lp>8@cF!AOBl^zM5 zaKe{$}j$(l8D1tGjN$IkuFl^>kPw9LUxff_G+)!ID zzmU4{DjH66#pJ45*z_D3-;RNq%kQYS*B}}PpVwNt8#Yq(Xp47z71F8*4&{&I(=%67 z6iX6hwj9%S>ftxc`u=$7z6-CufdWPXWqL(t0;>FHUc(ulqYP+5DxPEMZd|j4FnLSo zp3ixax~B^uC-aRrE!&Yessr8##-xQ>wI0#&!18)J`_YTY#Q)Y1-00^?BNwU>n1u+9 zN+XS&IRyh}rl4NBUe~;Z>dn#_OM~_Dmz&D*xu9Dp)PDy$tbowGg|N7uqWoQoTb@Sr zT}0zRj@$1-|CuEd3pF&xp;|`@oj9@kJ-QzY8RL-z& zC+htHM~N99Ms%{T0dAYGK8xt^UEq>&G^)4L+Y&^l5W_#G!5WkC>aJe`Wa0}*cGG3p zTad~9Bm$2kFzMGiXTuq|5~ce9a?;Z}!*-nkhP*MBEIspycm&_luS3JPb^wO26wXP0 ze;Sn}ja#G!1(ovOa%8!LKN0d>8j7`F!YEGEd8m(#iNkg5+Y}r7E2{2U9yOi*0mDJ+ zo*4sCoey7SdzL!nI{-D=m!xCSyK%SE6!gLP(n{p`AtAg8X^0}rk0|;(M5omw%Wr}> z9i@tDZUs(HIdMvQQ^)L9j6uz+6~CYow^E5y&Jq*5bc|Xt@l{6zZMqa-%s07Bi&gKK z7NFqI+>;5Bz-@Yy+VpJz<~DKc%G(eF{l7^Aemx>n_XQjH7PaUo(o_RaQFQ;8(ZIKm zr8kJ~`&4WFSAg!qC8}!b^oe7Zh9btatT+e;;GtUhS1PiHitKO}dDRgyCQj8cZf>(P z^1L(hS4RY1S9OSlZv38pGb&M+f6s8-Kuuy?T_`+z{_;V5fBCFb)G*-3PXHK6iqI|KsztM2 z8%dXhlfWS6481l|XbQgt#fT@>72h;xt1G@|kcVQRy3w14Ro&>FOgDxPUh)7ET=Efq z9>SAv3{NJf)!;?XaVj~6j29p|-qC)BTtm8X`aZhK4A|4GlP2LiY}Q{Lzvl5E#LuC3Hyr+(%17 zH#9_Nv7c30`naY)-mVOi;O640GKK#n= z&*xTzeY7NWLqn9~hK4BT4GmEre?vo5=!S-ToPI%ZyODJp~EujIjkCssQlN>Dx-Ov#AH{8$=rEh46 z3f<5URUf*c;cq)y^0(g55EZ(iA*zWESbo&el4SIUOYTOlf8>USh&*WWQCn%Kab@^T z{{?VEY0G=m%`^^1G+hE4^#yt@jfggy`EPj{c}CMc+$G?ju#+NuvBM|4hnp{U2;RfZ z7du2>VnzZq>X>XkN_CJ|;P1SLo65(cpGf25iyfkqOxme{Ga~$a0?!L*jmT10G0=H! zzKTJ``6>o=T{U0DV5zGZE+9q2QrA7C1WRz7uY0gU*F9MJx`&^k@65r}skW}L8e#e~ z_iO-&i`iE&csr>1Fx1J|Hmyf`drLl3k$m?iOY^9FS$@fd{*AeG=^dl=2qBK%; z%g06ECnR_e$OAfiwq5t0XM$~*Ol?R;ePg#${&;$G4WgI6qYF($g#bx(e$fHSGL5>$ zSgvZjTUToCIS4FOw@f3DUnh{pP$2ow zOeuke%)J!9SND>a0@O>lBVbIFy4|<7Xk-q_*(!#@8bo%UXKBqqTg=A+sUhR z@?kNOey&~@-5UI z+pZ%-HgTtQWPf<=LCT4}Th~HIHw?F0mnJRJeKX?f8qowY3i_*MOR7%YNSSaq*gI04 zqo=CQJSU$(=jbEVIeH?fv);dsp^R3i^Qq7E>3k9zt*DxM{LBOW37sIu$Um{X3($Lh zT!#>-^;-Nyk_1!7q7vw>aup49=`4iTBs3XqA zHHojDGl!TH2F65-f#(k#Vh%lT@JNu_B}Q~~29n?p)j`lx#0WzSOo>j7&cTv$zd^_X ztmud0=b2_sjER68YvjZbRYYEj049wXQw)rbrgHQ;dO#3JGBWko(SA8G6dhn!0b;up zjUI%!w5uE(gQ98J5i}$SvLAsQ3K%*Q!H5}dP8_Xp8P<Tk7_IX&^f4N`#_)WNA)=T)+-Bxz)hASCZ1l9zgwTckf^CGTaijfIo614&FAgt8 zy`DAd);U}@HdNNaNQ|8pY#T+#A*zRfqT?M=Ab!b(W+HA{TrsjR+QXeap`Vc$Lm4ln zH&l=PW+J_Tc)6+7G=|_EJg5kQ6uzX;xcu{YVU6mT1F)0T8^Sy;m?@D5JN{fPp^WYj zX7GSI@Zvt55)C9NTcU!efF%WiV^5d;0{ac4f!5ITDEssf)XdRD2{Tmv)V0%)KzU{c zQR+v@Dlyq@&_GQbO}Vhw%b7>zNO2}nG0?%MnlmCCG(C6{$l`(l;0!0f47K?s1|%;- z955`LeTIj#&xjEFj8yD1%E><94X|^NeTX|WK_-KJ&L{S{z{x%rhO^H_PWAyGaA6*( zSf*H;{F%MRf)|LfIWjIdK$?>juZ<7!3mD*RUYiiAL)CC;5RRkTiJGvurb(e9Im|Rc z=DaL~5OLMzp;8o`94Z&a(s3F^0H{D z3X)wLK>xJbQ%(oVgd7{jt~NsxM&3d0ay8tg6tw+u0i z3*;$v&hlV6rn<0lD}v>)mx>1gNUU6otA#3CGpJtc}gbAT2v<+MMOjMMu zruRt>p{11#;*84`pHL72)JZ2{xW=IZJ<(hMizQ6)2+QaW7aIv7sWe67NFoC$<2rI% zZKUQVg({$^RzNiSPIJ6O(GSx@Xs!yePnah1@p{N-LFsUE$G=V;cd9yLY*mL?fvgJV z8R$MXt&$0Fp_6BzfIF$mR?;sH(Fv?eCkKU*6ETHD<33XXKXY2S#GbDwI7$Cf2k8fS z0@`<|*04H>JM@%J+@ZAck7bZ>a*hwtJ?Y}wJ|fCy9fRt#ZGn(BuF8b*f|^RE2K&%K z-_x9lioT}@lN?iyR?{-6P6EHcN#M5l=b_Q!UsEmXvqb4ZH9A%k1HTzdTAWSNoHG6_ z{V+t)wtjS}ttd_m(by!VGhJp=kW;GLoB;FD!3Q8vWdpkH_oOu?5FFAyr-W0I;*Z_R zI6YHxhqLI^aB?TnZBu`^=%z`)R*$tB84}rNt9QvkjJTu2Fq#$WZ-SZ<>ST(hB1$rZ zrcOlD96|%LH&kiTqBE2hooP?%Sz0(aD$_24*^bIka877=iM{7KDnoRh0~JKG&(#PG z_lhuCLkhMQd`bo^2rsG_KF67;l5&Gd4jGUat|aCM^PqYE)(3SzlLh?=^})~#LhdKx zpbJ9W5Yi0)4$%-CAs$70)`S(VNSV}}ut|#yafiAHu@R(s(A_7T4$pv1cDG{^##d#6 zEDhL`HHm8;c4&&k4`-U&PUZ_r9LhLFkw2v+I(P^SOO7c$A7dgs!+wT*QD$?<hekV82^0dGAF+%TZ4zNl3K1rJ%V$dsJ(UwHQ+xH)NUZFL5-Zy>1w8?y z?+oUHv8R|X!RA63dCH3eB|&Kt+O4d(V5&m{A$OT(Yv`?^o(to~84d&?BxY*SL--;J z)(#?wC|qbk^bt*QupE;HmOyB#PqS4Y&C8_PXM}fb7!H{l2QA>7oQ*4>g9X8-Va1#b zPD3)+nez+@JC9J+Vun!-<8%d94;jACWw#k_I33ZbksHodw$RWV-5>gGt|N-!%sUr8 zx)P^fjz*MJ!iAyUrRbuNtXpiWol8PBC@HoyybdL@mN^qu((-U|wIZ0qp~I|HiA4AI zV#BIXKBwcXFqo`m=cirTIptc&(s3F?VT%c$7HM}bab-(97FS_*y^@GygJW~HijR-8 zF#l?LwOw91YP-C2bb^CrctX9@7Di;^Yr#SbY|4Iz6m-a*%WV%P8C*? zOPfhBkyI*iG%R;wO$r9r2cWJvS^s2&}Yt0oO zvXU0I)|PrU*Q5o9;9tNV!O5A&D9SOvLWbC@(Gcgn8a>i6GY<%5#cFgA3`@sBYHfS4 zHp2mF2x$#Nog9O&h^po4|5b(HZ($Lqo~M~alMt&7w$6Vxzc?1(Xf`AUaj5CcAkO9J z5QEs%Pg;UwzPQW*0F+DXYxY}2C!fi1dNrD+&v*xKg*y}++~SyyF=E6qnoE;{1bKEF z!9F&R>Gd_eL_S@W*92#Je zC%p}sDaBgsqTT2^wQ zxzrtS->Jzv+cs~o3a-qX`40TyHd>(SAlRgIYoeg39ZEL=%5!3c!|=A7u>iU4VMK0Q z$A&bbWwu43w@Usj4vwcot}IbP#HkmA^lm1wPpEf0CE3au*oTDm@G~p^w5!xkRp9^P zQkg>x*=uA|>UV9l{J$^tUe?YbMgV zKKTZ?M|THpKD7GT3yi6 zL&*p2HgGa<$U*238S|a&tfWK8Md%P2IpO+=0mT0qn^l$iE`v%vcS~eQ;U{CjHWfg~ z6op$$Z7S{0jYo=evudz8jJxeE9~A0e?7t6@BFu&G0%5ZaPQ*Az1$#>DKBmcM7`j}K z8MfCuhZg4=?KyO$J=I}viGzjIx?%_b!8_j(#h_ncm!xsNFhusWp(Jdi9h+F4t`F=f zAx&`X|IE1AWAOjkCS%p}#8gUKICF#XIgPxJpfG#mkCtv9v&lFlh%Rvw#{>sqU24C8 zYUw0NA|hTIW=--;;du5UG3D1*owl;b2NKdN!?zWmNs^&8V~3w1`?Hje^fNf`N*)X>-1%!!JvTGdktG%WOa73K8 zuR%v?&%2)RgI)$A&U5-1V9f-X4fTfAI>kZsJV%GtC2V1R##XZ+sIyHoTVv3C`=Of` z&ThO@g+Ob=RS2i@bq*B*vx3vaK@<*$GZtc?NhrGnI)qx0f%c$M=7i)2RvQUN? zVr&*bl5=t_Ytr^?C!Xj#1ISMNs|Q8H0UOAdyeLW~%iz;_)+A5Y9Eb ze!^7*hmuW_%Qm>di66N!LQ5dMh(L6VmDCVAVS>h9N!8l=p(36*s<-h}G9(vs?uvYLeYiW=_*_4GH@dwmJn z8~ome+LCHt0$|r)lQ7FY&7J5@3<5Js8X8KP+_+NG@QLlCE@eg3kNh6(aNyKhyqJD*XmyY&hlD zIYKOqFs&Jbya}r+)PJknLu8au8vc+6z>#AjY4^e93|Hy#d7uV^KBrqtQ{HRtvJ&fKMYOiYUx4z zm{GnIk$o+M`>%{N4*NOm{(SO6L~m=M4*rdi%VEm)24~yNMSgE|Qpc)HZy3}!yIZJp z-U8|yLS=q$xHIiI!F$7?kyJ3=GIH%#1pfC%T7lR=kZxB-QyHe*Z)>jo5cgH}T1n%><>_%$={mPzAlF`+XGcBz83e+%^++BO@g!C>&yZ zbQ-nS4B-`mNDb^Y3*XN}21}H60-ypGMCYtVg$k>dQ195Sa=+gO)WkRv0+!g@k|vHD zvb>G4c(b{ceox|?(k`*nY!!F6NWXkY_}!v^T7{@f6GL+GM7ir*B;oa-S-$U}xT8gO ziFUJByw%(*`sa!*W|vr$D-sLEqE1oWE8h}c2$~o0iHZ(UBgIVKFQ?vkIrXhC4R5J zs>Z9Pw6IC+%=xVh6ONj&>`4gI9+&0G4fB?o=rFq>C(mJ+^MVr{lFvQSsfn@vnol&* z)s*-vF^O0EfKhPvRoImhdMfB`XsD$L7dg&7Gsa%2XU5~_nIn=#bXuO+;GdGW>Fu0A z$_`oKJ0Z8O866NC%I9@>Gje1?y0@*(m!5tkE`x|5p6TIm#{Q1e2$^D|HHmr1x->@o zz~~%4Up`AYT-LauE-P->@3u8xZCyTGL|T`bC%kze%yQ4EokbAnh2rZitsZZ}-c_EX zIq7>ntMWLptECXX<WlA-E%{4n}mK#v1*TtLM3i0@r1(?I%((z8ki_+R=enZW-jaOj)! zGljcPj@v0NP;Ip27saG<@dW0j?*RSnEizW-<)j0q=_+)+BV$qn9L~i(w1`w}J&-R3 zrHStwop-z__ou3igl>duFFjAtBZnRp!N>I!l1J&eiXH?pf>&G>wX_MN*>A=nOz>SzHn*YDo@*ym*jeIc8M&<#IjU)y7I(Jmh_Jj z8{Kn6RM%0j%#&M0O`#Z(D=U8@0`j-q9xxQe9r)cF4YNqMx#wF#_6AH$pdgOQ!b6iBXuGskobfKX#eLKJI zbloUd15{sAD?okGMOF7Tk=Wes>Z(HI4^1TKcDQK97cRF;F5Dr$+^@SsyuPtr+}^LS zVT$}>kt~}cQ>Ms<{FDqy|MJ8BmF0h5{AMF$*$#YX?my~_(cMXNk1MV?g8Lb*-UL!=INixFKNt2(M0 zil{MSgmsB2?(7FO=e3P^-PtcKheorXcyVLj6SJx+#DBKPTZ)2BCKXv*}01W9lmiR&oO@MD3 zR+1?X?U2plBIXrw6?l-4Iw_)LpJ)I&gVLZ1{DPiO5tOKTMUyXDSfsC=k3X-LIED>X*!XtLHqUvXJeOl!&zxj!e*niXS>A1qgi0iB{& z`g8Ky#21?S#Ap!SPc1og*n9c20;@dndDrh08)HvQoq2n;_|4{Snf4C1!J(gLb_81$ z(d!}_a;WdD$V)lYwKIq2V6Y#a5w1h@JR(NQp{W(#ikFh}WM+b#A`>Z#Sk^^9vPoP< zj1nnUDW;BcNzx#N%Njofzx`a&&r!*|j88KmO$N|o{_UQuhcTWEsnRUn?Ps+Hw>D7&dhulY!)^fLk*zM7FJEd~g`wEOn&V%Lv_*JfVu)CZ zu_9|~#H8OP8(}68sPp7VJkbI|85v#^{d;6m%zH5+p%2gZN#EYT+&-oF8e#C=B7aaPDNdy!@s(>jPskERL_Hz+>CO=%KME}0S65NI) z%SD>H0xc`QB(HHEsf|#9tE%ptLrDlK#=nKToG9))|aCLI$3#q_dF6S-`voR zl-05qmA-qPdq3oKLTdWnoCI%zH(ee`$)6_PXlfNZUDCb!ia_RkalENrJa16T#dAhq z*V%*crTG>4^Vf_1?fG9g^!>v*9jj+uziTz>cy$vo|2|Q;GLLKqQyEk^70lXz+#zh zwp9c?0T2Gse`3!jNCm~yrF!~334Hs0i?)1^+j2;BI>NcPimfi$3Upp>l(E3_o=91q zUh2t75dCFZ(HHag9TUFe*20+lJsDPBOwpbU@w+B#9fYp{XUjt#591>KVoA4^Jlski zWVvJZS@UA@MSo-vf87L~bf2}A8*nE=w{YkI)hIbOCw-R~*azE8_T-DLn=#~D1-NBG z?=OETR`iNly}<0gCK`hmTr$>Ujf+_&J66%WO#gCJ02KL$jWp5x%9O2ZKf8&BtZBH~n^*K*X+OilWq4H`4%i zS|m14J}?=A!*s{&hR6;z8GniLaFNps0|7ba`BC<7UYH(hvEki@dYSDU2! z58?qA5wbOz1o`djTT$U_vWLUe*}s(K4<^XbE3TZGx8?p7p1g(P|u0bjI4$VENum4LNQ>aau4=@AHt%|qbrd9DTS|+$6 zy06W;-x?Fp<0i%WCGTI+IC43@{!MWb}5djqQu{svmGOov_^>mlks&@6|J zc-LAz^lfor;o(%79`7k433hA1@h2j?H;j_6i%b2Yppvy)TCLiEH}kS=k2{ z83ONsPbZ3|!ns7XFz%&NT4mw?SSVIQ#x@RAc`*?$sG5HQ^!y?{PJN;WP03cnP??mR zg>t6L?-Bzrzd-xRIh?agW}d!YLMQfktbQQtL?&_HXOYAky|sSdIgHrW*GNlvKyHXxRZ#R~#zo?Evy6?| zp5V)a(fC~hro;GInLN}mL0pjaRD7nDX*TYhwK`!NKevhj$31X+^|kE~C*b$U@rb5w zS%aUhmOfaVvK+yOTOgh_D7Q--HlSpG1?JvK!+pEwesN1nUknos_F+LT)_)d>W`no% ze_1SkG?gfK4Ez@#Dm0(EOH<4@g!u~?uvb1HCy0T^^G@u4P)<2``jLfs^0IxWPs_ZS zi~g*Czgtk7}5tuPMT-0s)yh9T%q<3Wic#%ipcPL_wNjBIj=SV+%126sc|TmMCsrwm+vO4id-t@p zt4-sN z$m6htidtoi8042z#IFp$c(b|JS~6n!yEN~t5r<6KcQn37CNLsa>QMX&66XD^jG->k zXXfq}9nIa=_~C7=7qQ(2o7>f9T{Z-YOkvy~k(rzY;%yVU_U$mHnmza2tY6U#8M&**+fEbXI$BMP~Aq4-I2d49^bsSxrJV^cuJsCC;lpgJQA5Tc@PrnGWDj?*iuok7zOY zwq>U0c=n2Dw^*-iaaaY)>EY@_z>_Eb45O!bp&Tv~^TmeV$6v&}dM7WZdPt%%L0(89=hKrMnI9D=Po{eRXBTXh zs9dq`xESr16{k*rZu6B}Xr9QJz3 zj(hj!%N6+ld_sv^6GBd2NQtCy>c*@%SA2i){f|XtyQgS!`V{zR3Nc5BhFl!*6b+r? z;mwkq?`V|M?^2X^T8=}i3GX5O$W0vC2%I}}(`6nzhbaslA*+hRl4FR_9s`uCo@>alXHuD($@UeHwxXG6K@-?{(P>3xWW zY+>;wVEBqW^njcyqRBI4ib@%(U4B4Gr}AIe_t=(IVttnw+~<)om~qoRa>U<*K*w1K zh?QiEUoMZ!L!y5dpr1IwD^aGn+8Rgmr+HGoPe00~{K9JKyS_puAL*MMK+&;j&9ljZnftxE<|_7if{Imi2k78>vmj6Qj2ifG zgES#rlY3{|?cg2JNEET{?D}QOM^*nD_5t5!g5XfyxAk&r?r#x!jO)hQDwT)M9I87? z*WH+V$33Dc_a5s!*i%z+JGf;6+Fx4wGH95w6u&=A|=z3SSSBEqUU-gW|_VE<|zH`*-ZTvKU_cuA7eDb#$Tl zwplI zCyP01@s;mT4M0bhe?js@=tiERXLeH~e6?DPTaBdwGwf-aG ze5g!&MJXnM7n-qDEuJ@zi&r+Z#)ua!dHgv!)=C~?&54m?AJhNRACvmuqvZdFhdnCk z-%UqEz%Rx^3A&os5wI7imtZfT$FU^`5M7YJQon2y48#J zHcY7Zv=kOxDMxMbK-wG?{oSIe^`Lmw=srg6V%l-JwjiwN$aL+pQioZW#XKWZiuhda!IR+9JwN?-oDVgkCA^6nC}wk3t+Ag(-Qo z>8N;9_{9{zIJyaT(+;>ZV+vNM7r@mhuMtu1tF7Xpa{A-~5!DKSCX){Fi23A~t}A#( z4omfUPEbusYf^a09W>zBtu;VYx4!c^el279=gAHzfN3znV_zm~MHzme$UEUczgAh$ zZr5rnZg@e~<*BnpP3Knel+mh8b*Pw~BG5?@nOOv5c8XgpgV?by8zHNp*L^^SDBJ;P z_RZJQ9;A07Xt&PI*U}7qT|aOhV%O< zVys{M?ApE;CwIS7w0rmGS0%y&fISvf`EWqyy(a?XwXcDW@k@Eff5?+Eaq|}azZ@nL z=gUm>FB^GUkBU*9Vs$GdF_avTonP#4>5X|mM!pdvdW1YaY(a+1fI{pR*A&Wx*S5&` z{MYiIp}zSxJ!nEjuP%3%c%Ygstq+&KJ8Hp(;31I$^SJC!rmD4q29FiH?)c{-aJb&J%Is@ zC#qkTE8BL^82*YL#Hgk+Fz1W&&t<<@VjvZ3Xq8*m(~Mz?^(04>&MK#KN>lC~4_v-b zTzLG%snedv(mPU>(@44gY30~UCcycvk}aO+vC8X`MP+izq4bARipcE5`61bfWD2^( z8d6`dwc!HUxB3VSsJ$(;Zv1N_H(9JJ7h}5M2ReF6CXoGVE9O+mL#%f{Zva!6r3511 zC5Zz7vV?6UY`trB-6RX-6h?&Cydx-Qgo}-jh*Sdk1rgbEFf|Vl|JqC}bA#F20yz>Z zVsh_{*&>cKw+_eZFXdEw6$sl1SGs3O{>lt8uXQqM*AXsqweVJ-2y)~^kR!*eqX(oZ z{hSt~`aTp~<;}?QQQ&BXHK|U3Q#%JviwpY}W{8csZy$-1;}Y>l!^hDEa>ej;5Z!U7YPz~hY@!4PVY%b_pp@z1C=_> zvfu<(=PcvUKPn6Uj-7?hJ@~cQBZ&Y1@$K^fvc9fi-8mL&f~zBF@VO)enATTUy3R}6 z+G)cd!X;&84JuYui(jlm0EpTO4{ptW+}N!GA}Lo(gP6gTYUt~>G;U7nZcS)QJr4*wloPBAi#89kSM1v~#y zMh9{JtG5@_25P(wRi)=zef^Y7{6X0QA>!B)?9c~-{QIH0!F3;K{_QbL%r{Fhsy6ky z3i4O7Mo_0EynbQNYshMr(c?7SVu#OiaDvu}V+Z)b_Wk|jj5XnC;Hms1Hap-rMCTq) ze8u%jm2Y=-U^S}n3=~i(!o^cizTUBRFL59xV`n?tH$>j%Of_qsf#6&ef)F4qkeM@z z0I$`Z7K8fEQiVuY$fnGx&=gRzvxRu|4@MzRUZPfU#hi~RbBciztk3T-^}?>Z+kUuM)_C&i_a{jth{W1f5udx>(l9fAJ_ z#-2a--D|mK5~+H^C7BUHyA5Az?nE2zGt;Ome%4I-(tW0z=6})*Vt>yCiIw$quLgr9 z2t4_$iNM`R+3y$8z4DTC4f82>EN(YduN~2jMZ4F?RRXC#7|W`;=(=(mbG=U*i+DS$ z(SNb%zg*pYsu8Z8cK7|*9$6=n+_SF|;L{)4c~3J|2MMc2IfnAWWyQE~xW9I6`pK7i zL^O514ELrOQZ9!=x`!q(@s8PUjUREvp@+p#>~D>fX*oCGV3bHryIbxOvt_HuOcPIH zKl`^0GU%`0L=zHBXgMc6HIT62D@Pu#yp`*Fe6y-tJYvb#E3(9}_Dtme1)EZLM5JZX z8LeOQM(n#I+NW6)V&r%JBqwfp9=&#;u}$ot9d%KyKv2ADl1X_ndM!IGQzW+@OBep* zIbxcm2~mN#gAKS>82C>k{2kBkm6Z}3!3*cCUXdw_tjxj3tQmv%S>D0L*jm(W#Sd%P zm24#qYizFEmwdqS?}3JttYoY|7u|O(qj{g>-;R_uSI99|T+AvfBWBf!?MJt(|M$ns zy}mZD{_pk^@if^Vz#)~-Z%&in^h{Za{fND@y-~w*qdnV0?V5;FfK(u){lNm1pJZvi#fgu{WF1 zla+7fr&v>lS(^vTe5-kI#vbuUt6Uu1+yj47?v3!y6wF%mr8Y4tP39jyFh6tF-o}=K z`4x@x3uYaZ(`Vm7TcdBa(vHXppR4;^HMU=&onyXqm#FT>CVX*q_etw!bBt`d>uqs$ z`PD{{196UR-Km@vRgh=?)7u-_?Wib$=Xy|X8$5hJwtD37o$?ZBp1DN}@~6ZXo|XjSG0rQb%ydaIt!b-=p8>h_5%YU?TC+%K>gL8PA$oHd{s^G-F*<^PpZ)2+3abwYLl!0g8 z^^hEPRQwTc?_Dj}r<|}VPi__EJvja37K4wA`W|s1wqoBVi|G&(wu|DaJtKEeu!SC( zdyC*?>D_{@N=eCUYGurJ9MQ_$5)h64h4~HS$@b;06oXsEHECPg4(|7~ZE0(3+rm4U zpcnk%C^Rh@dsIyC#8N)(N}3Au>U7acQQiyRcT8bkd;$(+waW@md^*~5RE+49v$0j_ z6&x78tECfT|1x$doovR2nvu)k@K1ZME#4E4y-L=F5E&PMWG&-)Q0>2Xe=`i`2EWbm zIQyQYZ2Er^!;|gZeyL{1i_KV&Lp-wz8OZTOQWZ*zW97{?hemIIsz(%cSxbhmc!&0K zt>*qoXOUX^85F4v-qN~;vd`L{p6e#+K^tUl!=N}$JVm%NcESc~txSj~^+V9or99=a z;)W#P|8y%pW_wOL4o+;xIn3>x!AcmaelHyY<>I&UV!8LnR>p{wt&gP?oJuKp&GG#G zE*wlr_|F1gAg7^#e&!e4i~pW3cm>NLAQ?Z@N0SbVSy)^^D8`*raKsun2JsRI9&FTb zXD>u#6?rW#Yh8$XVE_#UmSR;alHy2lheNk}-@6`lVngKM1lkX=y&_$d_QD4&O8w%( zcCjv23_mW``Ni;dY`Sa})4Rk~OsNPFP)L$i@e`v*jy&t6kr1Wi&AG5u9(WjaJe6LW-(cu=nAVGMRltILyt$1<@NXCgb&?<9_dUW}E+23JAu(

fT@JFG3{~E@Rk{Bp5)9@cN3irL9=k1?!XCa^i5@e6)6^(A5*l$NP8|PthXh29WyW6@khpaQsZ>!-y3g zwkGIAq>ObHbzpyQq%3?Hq++^yT>E~Mo+IY8@05SUMrHYM#)1kl`uM5`v31phH5k7r z&lO{Eu?hBW4HFamGEv-%V=A%fZABgQAIRv1%_K?=ShRy9wf9+h`oFED7;D84z!yZy z!YUfFns#Cw6n8aC|IRB9rlwCj*tUMJ-I(Ls&EqE*mGcC>h#X8 z#0BL?r(;)dtcWWVi;s(p?%|WS9<)-1z{Is4F^AB`5(`cr9M6RDG-Ovg?z({D_|>iQ zfp2=mU}D@ySOtDo^m*1KBez+>+bD#KT)dekX+`{wNx*5yO?N^jfk75uO!s8|BU669;o$rowG zSzP27f7#p)9j_gC(TIz1(r-)A>AZ#T^ybn=@ykprf4I!wak^*$yu0sjv9d?+uo7Zu z(eSsMX~MY8!qMif;-b#O*gw#X_4ZsbzFY1`phtKMv4uv&gH8%(y|aCRyulMM?r)Ku zI62uXZrGfL-{azoo835i0bTVA7PkCk-Bn5Z^#=BezijH=iftiou^TnOKP2AYlzZcj z)j1WYx|2QFukp1YxAPXdiyRnwqg z>-j_c+vVCVE03**ZBZk}w4c}kD$D6QD!yjA#VgI|3R2slns?HgaUoVomV(2QI*+cNwHodSlmS7*U_cJ2 z46ZvoVh(BjyiglagdOY)^0_ei`6FCyw_&eRE9E@_YXp0&w(if1_s~5jEBW9|eD~sI zVsZIF+(XliBQJ0$kwO9g6|IAaF3~4WU)zW7=rR0iHI?_0SgyTTKt0GQbWEO#wBekm zU)-~)uMNuOGe-F_Y`B3{SSkAVWUTZYJt`voybka~7`2ws{u!Jl0{$vo$MLDX8q2u| z;G7E1y&!PLBA&iT>#g}gowPS=M@mNZ>H8Br_oo+qD?2Z5C!8?7M^Bu9kERuS#`E&9 zzo+-a>7(%F`#I8gASKTc?Nw3o=tRoc{S|@hn6fr7HS*#ZKMLfyz5ClB+SBuJ-H?nu zff}$nzz`u)5@Z6^*i+=FLT-3*R%VS{(v~i+?A;$|yY2-*kdyc0G2wI|wc`YB>Y)lx z?G5OM7}J-LLYFDHVFi!t76Z&%)vSPHxun(rH50B|7}Fejk}PcweFws1P>(+=v_R46 zs>(}f{uB1vr^0_NhgasX7y4$(PTLyH_(ifQfRj6LwC~U>2Xx$Bg-;o+MPhX4*wk?; zdHL%p`z?4_d?M01BqyS;j%Rf&+$n0?^R|03iW(`4i)=T{IP8opqHqd5GU%~@9!0!7 zqqmgPmJRF3@8Fr(ht>tfPQj-M)h&MMtv^t9owt@|5b8MOw7Jv1|*b%*4Z~dDDPQC9kuS zVOvQv@tE#5;cu6}ZG)*@&Qnuyab0P$ci`Kg>7D96M*+$=f8mPQxv{th(w!I^U*iwd zdebYswX{x+Xh}n9WjgMajGr+rHohV@eo>P8A5hbA!{n@4vGL`q&iK;Gk_N=;YO4J4 zZ%eSu75;gpthl|x*93f@zr&8^*&BQ;S&6dr`xiS zusCNfo<4s`>ALv(hC08u)L+*?u+V0swydhgXB3xLp`CT1zV_CZ8C5t#?^FFxokdCL z0qWAl^Kt28pxSTLqJtWI26|_0wHF0SRiD*Wl^Ml#)n)cbpcol-^p?837_U)qp4V6E zGwQGL(=Zj+2CA#Me)QKmFGjkdG{L_9vaZqFP+ncPz8IHS;(u=m26e4(gW=s!j}e^{ zC@)6=qLcLvRemoM%Hkyz*hS=HsEg+}mQ)A4pcRa6!W+)UIHdj9iy0NaYJ1xGL?BT=)^l-CJBtEL>kv%xgUq(8P#~KmeU#07=HDk*Yu%QMpfJXVjytud1%r zs4P)*h^moCixA)iIW=P%Nwd;G1AtctYJjaR?N~O|cxy`Qn?kgsd5~&TV>Y`1w~iE} zX=RD(2P8wWsp@B%`k9U&=6`g_y5jPZD$sYJHsJG?QTDZTt!(ksBm=dP-1OOaFP^Wu zjBr{D>4C;FR^>qv%UtH9p=Ia*8c!NR)m$%l77_yF>hm{2NDwf^rV3V7gU?@#egq<# zGK>8s6~^KvrPU~E_-l$Q!AU5#tfHZ$z7m2L7x9r~D{e5*f>MKo2gQ?u!%s0Zx2E2x zsjDSk_ZdXF!Q>=#9>^uxSYPF@^lt>eR1lf4pQm^&5xjAA8Hl_Tw>$(InheY)#H$Vd zx@xqot_s{iyir_BEJ7?qVg&^-@-@X(zB2F+D)t#mv**svpIf{R}^0pC@HgJR0k0(&?NGysPTi; zl33~$7qbOIjV$pKaZ*J|pyZn38ZZk zS+=39s-jAD9GY2Mig~3JBTnr=tB@g3UyoUVNCX^`vkVjodGE(f#YsW5Z5+Z9e6>6z z<-mR|s7p^zj2U=^?oO_%<({oXzi{JuTA_-GXi!y2HJDrt05~g|lGaw2)ULA$V&3fK z*_gZh4J9CRrsw5Fth;bomTxu1>oqW6eF>%!KyTuNFbvS%VkT<{5&y=Tl6pnhYD`Mj zu5Iu(65SHD+U=lT1lgdE{FTPlNxE5Ds-b?&vgkEbr-;VzLk%hA@vqm^#YG65J)XhQ zQ`7>!Lk0egRKL*#9`+FqEFf!&H`djnF*FD~oCGWBYMmM50{xA+-Dd#xl67Tu>ub4r z;6xHxIm^_TQ)iHDSUg{$&rL5jK)>KXf~`>0a)HT><(wY7>M)KAjy*A@QNwd9Pq;kC z(e2#D*95$f0@UQjAaOK8Qu0klh7Y%{KcH0 z0WGDW3iDx8FkT5vj1mwnP1Rm>ViTw%SPNk!+^7Q(adMhA)L8FW3XVY~zthLazN^1P#B~{QV2m&b?*(;Y9&t0@|;nM77*~?Y+ zfUo9g^%iedL6oXY;swzjrYZ(hQ&*~sST$(*UXW8=Xr3SYu4BN7RJ-hqR zYM)(*&|Jz2^IY@=$RUKd-+pf^B8InEBTsc6|5=}g-8 zeMoku@RB?bsxi*?qPNsoKv6gw4ZA&ymy|;yuB8Fjbi52K6@b3%1-mbv54gq4S1iuQ z&!Rl!@#2~tn1xGNb(zaLgpMo&XDwk?ZeYb%7pBoK&RJ*|$wv9b4PF%YmKhXL)zLTy z3ltR0UN}!x2koO#@xwwgDoX2WYG9H$fg!EFi2yN&;0!irLF&=ND%$UAkzg#%s>(c_7YZix(|imW|R5rY}$;N9S9Xvv7WXw(2wk z+(i3SN9tDuXG)hDKh8ONCG5Hxn;A->R_e`mJeE=UfTpM zU3E=%!Q$nf;w3Axmnz0W4XQCrEDIMc4DY+Obr2l$+0e#sX;lLl(FR^jFG;A9mPuhU zjBpt=>xRG*-9}2FokJI9?T8F_U|dpG1!A>_V|Gvyl2|SF*TK+(iIlA7ErkOC1Im!E z)lC)9WuRulOb+<@tumPTHK9S=r*2RQm7;kBdI>25HVD$>k=sTyJVJ;Xl~pWGs(s#y zVB5nYcE2dqUiXL%zqGmz#zYW47vz~(fvSvAtSMx3W3lX$gtMPsLomw$4{t z>8&Aci)E~?X$d()>R@-R)OMP3CoE7-A}7?)L_@UdP{T|!%z7UYSSfr1Y8Iv`QujfS z7IfUv4{Ewm140aq%Dt*nc?O2W4Zyws6hTDoS1T~{&-0c;#VDg()HyV_ z7A#)0EC-WQiLa@)6e3N*Sr%A3m&c1HW9<)sN=F(xCs)D(FAWZ{u1j|j4;TSowqnlQ z{MpNv8S1@rIBfWg21p5l7Yc!%7S@;4Vu;u+MIgDkn8QhlAu&e=eQ3PBrD3!eBqQC% z`GJ5o{T2Je{$l|LiCy7fC(Z@21yT<34is!}ld-n04t&UAVn_C3*o?{%@M*wX9b}wf z23tCS8IprAxt_)I6=<86Rg5@8ABSB$pK1*j;z&uAawx%EsH&Y&8~`pgC8cztjRab0 z75&y0Qydy5u^`+4Hl7?QE)LA#_lYwALxyrp+RXhHB(L8LZF~wk*W@9L~ZwBc4voXuve1V z*+9LPWP_pKTB1N|=F}u$24e%Q1o$A9;B?hcq;m^VMpsu=@3i1}Jc77Td0m2r)*0d2 zk|{$88P+9)MQKSb6h6{a7<;a$%mPuTAdlq^21*lmKq}WGwZhF_)Ve?DO>Nwq~$jjsuN-J*dG8H z4$gzDM2@O@xRl6H(A5=_=P!sbV~<=(fX94ckBssI!P!HmFnfcbY}aD_f#N>9x|M(o ztrgCzS~w(_+CwMPScsO@8>R3>f=Jx|e$;08v9z z;WQilP`@BGnG}!GdIP8viPn18vn$xvdU>+Y5zGW&X39Z1Y3|B)ddK!IaCc(MEFaQMtwNS`%P?YmcIeXt3y4+hYRvo^3pn7gB*$TXEsh zCPxNTQ5y(N5bz~)rr>^3yOZ=grQg;oT>@r~Z(UXWk^q)B{vU5=0w+gR?f;s|5GEu* zAPWIP2uVN?keMVv0FgxyRFv-Ng$e1IVP6Fk)fP1=X-ATy)}uv=ljnGQonQR?02oI?&@rx;C6fxu~X8f%mpKN zI!}^^3W*c?fZUXpe49IiiqP(Usx*OIoivkkBB$z;hU~P=m@Ykc_EdT1kzIE>G2Njz zeKyTGrc~;1nI2^$-MrB(+YPrf(Pc&aaN}yO`ynk|ER&|F$hg|`K?ey@E+nKm-Gdit zre@1D8?||{mYom-+5HyDSsckwkUIv=JIi8?7^F+(d{Nfs66qZJ$FQ=L$ghrNSK@9` zXo|RhWHBqtLoONPbC2HFMBMb6DTpW8rbv~oL0b(;-py|;xPMMn)RxqM8_B0q++SN# z2TnCs4LD6%9m!wYYAMuiUJ!V)vFgAZ<>S@vFVltku5u+5V72*KjAkgnV~te<9;d9# z9MqiVm$93=z(HfxfS)v09k|R`HQ;5+$~-{b6l($-s?MYWkf#0bGcDxf5Uy$R0uQy(I3jVh7rl;U1jW;6&|J`^qQ}D*xUhT=w z>6VJ$ZoIA(yu{kI0sN$~dY)GJrfGJk;Ptd&+mq=jc%1QOq~OWMo0)>;$3L5YE;=om z9kx=mT92-B^x%9o>6vsXCr4kpOWV-#%&>x9J?2{wTXl`AEolIIE!0J!rG(C)FHDy~ z*%P+Au)-p?CH>TpK_XJ2@g>Swt;e>c@}R<>>v6bD5N9V-(y`gcERxOiI4n7}BZZiz zOwkAG=lSKusHZ0LMIU+>FACfvZxUiZF9&>&vYg3zViLOMMS*kjCLxaYa=_zqCeIR+ z&}Vs3;9%Y)#3#KR@WPzQ1!5BVvtAVVg}h0K|MGIcujEXgCMKcXi$dI=lpT0a-Xz42 zyd3cUoXOM0B=i$r6!^QmNr>mY9Pq`QN!MebN6QDIG)my+%92jBF#Wy~KlRKG`NBq~ z^ea6|iojnhi=GMnq8DX=Tw}9Lg%P~KMqdSZfwG#>{7Q*uz1%+(GVmpqEI9vfS!c&1 z^w^e^fX66nSTeUGg$eP|R zlM-tJ>$?~WqoS*9W+5~}kxMn;8?4lqUNZ>sUC&%O2=QCbykQXHbZUCj2<;(4Cv8v8Ou%%jOdTDDJ)n|ww-M5^os*|^PTnS3 z=n*|qRoau&CV)|IOR8)0AUobrgcY66*q$61c}Ir6J1ki=aY!KybtIRr7>uMC21pgT zLni00V@N{>+XQ+D5Ze;Lk~o3~b!fe0L#zfIFTc3y{$w}-H&<4+A&0ur3j*&lRte(5vwTLV7Tq6_ul`Upnj{hD>NQ}^o8Z5P2$8?QSBZzQhrTNxG+tK<{)O?n)5jIhTrach?1A?*UUv$< z+IU?l_*&z2r)Q1I?5xsb(Kh-f&F4PLt1AWHskUSrP3wQqnyUdUD{EM?a4?1VoR^~k ziAJn_PXqF88conoYCP*|O=L#^+(cPhCxgjl9S3%eYd>(@u!&oDzPZ`B_Gw#<-?(eL zZHFhbCXV0fzuz1)eoTt^EK@su{=cDy_Tl|_AW3Ngtur=<|xp1Exb zvA1XLkV2F^vnz!-+%spU5J!3DtQ6uTV=mYsg`hV|?pOY!KT^?7n;>ndGj~b=z{5>y0C=9U>dXzS z!_qNWY4201X2+mwZ(|cjJ?z+R$(*nci|VK}?6VSE*kiw}MQ7EJnFC0&Zc`eLf5#&* zqH(=qlFo^j_0jp=z8_%Z7oRdR~{3-=#Ble@|fC%H*t(wV-gqMv{}kyx)$CJ zb>%TJ3vXr^2mV=kL}oPpS!0AZ0spKf!kdhL)(zopi+@%K;dSAkwLo~Yz$a*oGC=}a z9omxxJA~n$tmEw*8+RojLsDk)P%F_1i&@t7;c(0q^=s@*QXm(qz=Mr-DDVPh$<3Wb z(S;$VbiB&NTorhvnc~Jd!gk!=M9RPmjWyfE6zs1@9&@deobuSYi=&VbV}maX4G`nQ zlC$Gfma6%C^e9yUUZrFi{^Ti2O1QGBSINM_W{ySFEk zCb|%&Pn$X{IzL4er%ZiX0>mE=Af)-J-5EY+;1xdR2NtDJG|~UBn6=7w_^P6Z^(a?H zz&|N#Vrx0)Cs|3dil#_Cr_!6YO6Q87BJ!H|1>C{vbtrI_vgQtHaK@znL^EmwpStR# z@h+uZw@&d)W6Gcd(p+uHp_+sps3iS-bh1G9*V>z0Pf9s+kLrv~PWKY@HyaQ%!#J0} z88R_WQ~!53G5OC4WGS^aRM4%h-N+!Y?_=tEgE4{Y*ksH z4K5u9NQaaT6Lzx|D*bEIIvn`4v5o?6sSg6>8e-)j#DF~=JmJF%&+;tb=kux%*O}bm zK%OJDB}V`k_@^x^2O++p%=MDb=`Jrx?o-}FdTdLM0*=(D2+hbLwo&HrjiWB$!MPig@G$ zCqN%sbcaSBbTt3oW~1!LofR@r+vGEJ%DUQGRPNeBFv{AJ!-2#iBk8um=TvD!8!<-$ zyYnOF03~Q`@e3q@roFJbAJyQfpHv7~TuP!8!O(%QhB8mjY2G%2z=6yTZRM$*)>^n| z3WrXb%zwj8M_TNrqsUE1THq#rK1i{!EWH&-F0Dg?OhhnrP|(wvq5p2(=?LH^*3&-( ze7mtu0y3X>Ca+A~@s%xij31~Trrm_kvdJ6=Tt{z=H@gYMB4xHGixTkZdQ+n*2(eh1 z@(?)zAFAs{QxIaVGMym!?|H$nZR3!ug#3a%r>y{AQ(p z>%?)CiQ@|vM+1oGtUo|~Udt)dGVoWqILav$H(*2%_ec+Lc&d>qloONbgz@^CaZAKhyEpnCRNvtzBoJSF2K=kC zWbRry2(j5lnFW_jExIFzwe|JZplrv0yV_&q2Jl_V$_fL8hk|i~d7hQY?g=>2?x$9O z7L3KWPTnZPHep{XV_EY*@A1ot_fP|@+$ruWu8UZ9>wCY}2(oOoHA zeCA|g3X??StMWy81UI#5a2g0))J7oTuNan?$(0-##*EYNL*6FD~sxS z%CH1Z8&+5r9T3*KjZ_n$E(R9c~?plWBB`yl+dK)p!S6hw;rhf7~Bre*a zlxGubwSqX0*HkFsa5v)(pQ=|WJ~o=rmw1TYN^?@}tg}N=@Pdy5;enQuV6o-3qSX*B zA6HR3`#ds)R!fJ(1OYUAHzANfVV6hqCF>$5ysmHq9m;YSa8rec>#=DH;!Kk}3V5-X zTQLan6_Yz2_|3c=#IH>51mM$oIS7)K`}L%{hs`s`0}oV|guG%9;sag|c$$}6J_vDz z$sGm!ikDk42yv&$9S?jUF9-2w&s;tT@i$XGe5l4I)#j)pS-Mu?P^6on>4sgXSTq!o zM^?(VDq7h}I`=eeI;sJ0RaUl)h4~z&XP3SuskS7#NM5Z5=8n%?$l3}Vy9um1aCc+X zfQK5Z4m?s>S?EwFnqUpM+*ozs^~S0JZ#GsP_-$j=fcG1#4*aFDYQWzcs}B5&v1-6K zj8zA&H-Tc*fM*%24m{sjHQ)`#ssq1ftQzp!#)_^1X`yYbg{r{Ujnx3sQrVOXwVfqY z1@2|629TD@bfIV&xoH8s&UC9lswq;y7rYekXiKvJq;#26C`u*ffZs6PD)3HYHGmW{ zGZzkN-vETY4;9^X}1;KhooR$=vI1dS>yfGhf{?g-6F+H<_C> zPlTSf(P|%HjX4mCbm^(RO{4_$&DKM;uQjQj(9nZ=>flYYGcwx&R~f4U{Hn5CU#g{0 zpV|!F%24KOW~&NBJL{KFzwm;IvNG3Dn|ndvJ}rV! z2YW%_;ub-uPk2EfwJIKsf6~^tQZs2!W?7XlQe%!6mbpXaZ?>Y;f2a_L1=q^wsR-WW zE2I-H>xl0stx(U`S~@l0b;`;*L>Sg8J$t)X1b%akimUbPy9TUuqEy zo8~=w_Fz2@&nBuAx@-nZq3Wwzs{Ku5_Q?uKTeekkuCvMNGOq|EJNL!xIH%cR2=7x1 zMEe$^U!|%)wjgT2ITLC73h;1cWep8=xfcXpZLAvbvn{$%ubE&4xNwWiZ{`GQsd5We zwnsJg*DQw;u;0u#h<2{AO2FmDY7p0xo)t&X2piz1D*X%7ssVqctl`P&Zt08Wsuwlr zhN;%iRCtAF5mwErP(M_mFHAiQiz<+MdvZ{UCDa^m?Rs4Wdhty?{N-}N-CGMBt=qH$ z?ee`pFtwJYIgFcA1uAJgwT$Z!FENm*GCP&;m!RZ#?i)0I^mZKs+!!#p%@S2)3JHNvJrYrbjKW38wI z|3MR*ZCX{d9`r2SzRlcML-(hubS~&nWN+0z+^p1qd%cYs^#R9io3XMQLH$U%@bcg&2y3ETLON{@@TB`V=aaw2!~jj zaz5P*ouqbuZuYC#^`@fUbD~N=YFf2eE1He2(87*1t;*XJ(lP~$S*ltuY8$xOXg^gu zQ5&>qhKlvN3iRSxE7X&aLU#pGKC4mw*?LNa`q2)eMN<&>8Vu#STx{q+*T0B+*5s@| zxEpie!6_Nfeal!LK&Q|@o|f_DD*vYnx3IMPw^Ha6=noTcUvvGLjtqu{7y~jw@XIiH zhmD;6-e~0XXEFJI{~5H1>mzX>2c=<~6!oRpR#$g}b>K+H&)yqA- z7=ofm7L?>MFZbx;7nOL$>>Ur>M0Z1N$w|QNl_jA(y%?g)%K>K^>sVmFSABFb#1fM` z9(Yq;4q~;*odo=4UJl}ElZ&1%9ioM$LFD84UsV>hZ%a;&%XT%Zw7A52T?KmaG>9Ko4+%Yf zUdF~M^|Ru$3Sagt;G4?IcG6I7J2TLtEgj~sFk4mNAB|N3;@O$6rclGpd?l!;ylgPz zU{gNh34F%PH-H#)=F4WD+(Z}XJw}&hvBw@fK5ZWBz`Vzv0*^hh$LNv{^H-^PS$^c5 zZcx76szC453DP*^l&Ob>9IZ9p)oNV>?z9W7TL<2ztgIVAtvAaAfmbOj6NLJr7X&`g zA_%qRZe|g9pt3THP?&b`fU;hGYj*p~=J;E!t#;DTe0UCO5R^ zc%d=JTbnJ3J~ZXh)^rK0Ajf^RGDln8j{;IZ*Jo%!da-;vGz{q&weVp*=AQ?`yGhRt z`8@DY6(EL!8-XKKgz%bAFvIu?A8Ur1!;`;szFX1=mEngOhWf5yLfxXq3OjPqyO@w+ zKuJ?EfN&u!2GANB6hkeeCd}jz9a6u~4=spSlqs80LSRZ079nh16ZJ@vUtrzxLeXZ##86e{wC%t|#V3)+i| zQz*Dw{;#l-O)+*UEI%wezoEh&sw7JYR|e};k};qkir)|>t6~t zvm8tEe%$8YexB8%@C47AukcdOqF%lXQBOHcEA*;Wss@~>H`nCZCU8q-WmSgaU2oEq zz~x>y>;QOt-aJ-;o10bzh!5wnnnHQ=(Zw$A)>9xs0rxRh9k{QuvV_p(xTyktTqsj* z3AneOlAZ;`mPqMIJLtpsL^s8WY&8yxHrAn#n>5UV0%Qmy7ZJ7#`a1D2yGTud+uutcv%ofzy$`wH~qF{+0@6@BLy1+#`J4*Dx zbCi{J7^qvlAn=YBL8zy^An=bZf>0Y-z!l&oxy-65)FECFNYYu1P{){H73ixH^>eE7 zMXO2~h(Tw*oI+t!_6tDFXM$?T4!=^gxs{{@oNTOUIb5Y$G*Pa#yjGOW4^-k(0U=WhPl9i7m3<&mTK?gtpL4N)Q)Ud&NZzX@MFqy zLC0T?C$xPONZ$s&tQE}qwo&Gx+@X-y?8rv(wrHamJLtgy`#E{!3N$YgY)@*G`RoaO z7JR}x_ShSHY!rFyE%4YIdyGbG>~VJNv9HME>;jLoV~?ygI7;-Pb%Gn2^y6Yh>j2V3 zQt(aZSS0cti$n#9MWQP~L=MuNq~lq33Qo}DB0Ux@=j&+Km||Td8gyNHYJU@{0nad2 z9eAd)vf%=CyB7q0vqcc7D1>l*rihi$orKti($Qq?qZ9s3jB*j*9RmXXRDe*5t7_91QJgs2t`OD z2+T(p7d?)yOmweWbp3H0{doMY6|NunxUot=f+<*Z;|O|)fS-JmZ6k1)mfxk_lR|A_ zjZz1GxJ3}^JTC~$*QY1i!H&@)OtfN@CTV(8eVSpL59(cvulu_hUsD6mc|$;|E4!f8 z3qw<1(Qfkt>pmqQT|xH8v<3wc7KNx;$_=V;ma$4e-$2ole7<^qMvrcggU4Hf^=&k< z#g<^5X!cQmP7{2Pj{!({(%e8A$!UVG@R~p$eYC%QM8n}tWHP@4b9KKhs{1PS@-DkC zQUf-WRXpBf#cGjaJQQQaa*<*=>Z5yUJaa76Xjyr1WY({C(N9{*+zR}mvHE~NQC5~9 z)Gti125i@NyvTF|9B!-{aGbIFfSVhu2IO5fVheb#mjd#38<7HD=cRxT7%SR?Qi1iDiONAFwzoz=Ms|4$S(+L(Jc|=o&x*cZKRn zp@?0cQveBEW=0@^ixiNkMG8pNA_XJ?kqV>#rw%kakej%`U$pS+1bV(!$BBV2v5J*| zw6+r)%Hv*Y-N}Ft@*aW5Da$=}nQR67ZBCi;9Gr^{e1^qVC$?L2V&K(YY^ZRF$At?% zQlnT$J_mO9Ue6zps035{H7 z!Gp?^OBA5*90O}gl4({hz=2G&va$imU!;KB=1KwH$0r1&p+ysTa!wQMD^>zBLrWMy zhL9KoQm~?)OarcGVfDwx%NRe;OND)mA6k0WL~6kG^yO4;zKE|RV#R8aV!U?8isd53 zcYhS!1ZNVzo#y4)q!}yV^X)y9GV6sIzfjf?^@|j%MT&7y4@QdR zBE`6VPpaan_8P_-@KR+JhZ-wZixlHfPgAo?&0|zQ`r~*7(x||#l$8YqwWk*ZUSh21 zMz5Ypuqh)Bh(Tw*nnKMmTlSd=+{lk34W9OiE@^JO53$;K8)Vp2b#|0qHq5Vu+Fp?na1mYf2Dpt`cL0pi)&>Pew+E`mVJ zXM$_@&>MP?Yu#@R#twRm9Q3B4gOS=6RXrB1CU>Y3o~4RF{5BsuJg0JamNgkjmW7We zma5*(dTdW-reGYn_h*9tm6KCwho32WOpj7&AnLNizyjF|3)pR)vj(I#!;-}vDa34* z6XvKC;zG~tNFhG&nWIvOuX<)j3UQxjj!GdO_sotI;uX&vl|s;un{ir26p%6_PA-vv z*Xtng5-cuL3`9=KFvc%tD3o=A$7> z^iP=iGVn?>-vDCJnJ*VaA6=xpU2W`QwyMAbja33xja3C6W~|cT3i;Ut89u<%O{)4X zE#>}J(&#Sx2$d!hH>Sb-7K1cD$#N4+SP!V?7&Bf0?w~AZ3`{Jd2_!5h2A=J$g{@Dh zgyqzT>kbXZ@xTNqwE+^KOf4%1A&9Uj+NR)|;w@XeC7@4XAWVVZKDgYpYQP7LRRNau zR%bRoppLQ|pcNn=gpwT(@T?Zyq2jo}oK}JUqhJl-x_UEDUhUkOLhR|8qf>~IXHG~V z`aN@W3UQiePDqz4@p;c2o!+AazjNSz-K08oLJIw$p3nHBQ|Ldm@F%3uFSYPTr_k$a zrLYe@zJ)(Jh32zq$U}Dr^0e2n%9q;~zL-iwsKfQ-+7d#Ena#BR0(Yruz;mCX-OuX{n@KUxIC zXs^|?KR3l_gZ^1P^)nNx{6XO>o(06Md+Ad2r#JXFvBwED;38vHfafSH%Mj|nyddza z#;O6o)}jmbhzVAJkGBXyz2F6bFB_`{e5FMQ%-NO`1z>gZML0U_VRRZ2Q^ef!LzXam}g=8Mb8RtlM3;-Cwr$@qArfNcD=3wy?8>v zUoIEiy|us-ePY8$cV#RB=eIm$g8Ga-;;8|zY7q=m+(yryX^PR1+CopAVIq}_6<+RH zK-?A$sTC@IhpE+o3rA#;$pi#kqO5F4K^>)^7#6`WmvMS(z(k^*?ThMpk-4j1qR<7s93b5gnBZehiV14NcPeAh%=}4rcXGGajur@ z^H#PR@M&dbO#ro?KEsgS2pp-bOfd9tg_`-Jd5B7Uk)Ha4iB$fja2<130phl(lZ{sK z?M$r(yv0}*;6{32A z`=}nV6?VN)({-~@v8d~XdJ z^zevU=9xx8oIh5Pv1YsS4uv~=77({Z{cLX)pJQq@;8?xsEZqkfZb(o5rX<9YlUyM}&{=--` z;2X-yqKBF~I&&mF2KaVk)qwnFOQs9;eiN(!dyG{BR+N?LLd`b83UHuBFwFm>8va$5 zSqbN)UC`+!#+foQBF)TT4VM+lyEszqBU;2{$BdLDSq#9(DT3~e` zG00`$hH7A%8LH#%AkP9)PPto51Pw10MnGxE(rq#^PMwQ3p0S?))gZ4Ik2Um2QwA0= zmoX8LlSl#IT6$qK%S)fyXysR}=w%=w$Pa-o3@de*7V!crW(|0uva+5FwbBa$zuY1i zdN@wzX$0v=X~0G%`Uem;&-AczN~-{En5R0wf-1tEV8kN>Ow@ zX&hapD7yIb-*I%kL`PcEs!v9(!voiQa*u=f(DXyOd(Gg#Sbgh20xY_SJ5ejc*BPZh z0;!OM_4GoBtIT`}m<#{uDExV9pYY`~ol6$kr@psUYZ(`6XYU5L?;}n?7 zS}c-D$#Sbu-wFnNCHA77H9YEjwZnV*Veb|mm*bK33WJ2Lu zj1J|ODe8YTTje7x7e-hvjIdlVCG-y!Ax@g}cUXlcGb}=r8P{MS^l+Pwv%l)GXsrKT z&uwWR1}ObY;chy+Na;e$>uN7LT93`?0D?X#eFR9OHsyvghS135(l-`f*3rG4d#UnJ z!psZ*SF^-Wei@nBuz+H4{_n@>P<|;+v+YA6ItY_{v&;}oSP~nMzEjv77(-}{&4Dn} zXVx50%q6m$1`U)2@aL<-T(3FEa$giIwN1C3Y()#mxldpiKqehSC*T{ z;!gja32?d%=vquezCQ?&`p)>Tca+QL^6Zbta`a-Bmr<2^fU1fvZvHTM$rQhH9nzg+1r2mB|LektIerjLQn(WAQ@zd`Xg^@z{Mm3}7RkJ7f>OpnM9l`gpy zT+1#|6PM{xMmvyaSy`JveZva^A5~Uy<6W+2KW~bq?%YF#13bj;bjzDcAik$JO0pE89<n?vBWmQn*qw$6Mxg(6|m z1>#v|2A~h3JX8x$w1j$qc$Rx!K-{_@dMt=dtzLB?CC>z*h{xSUQym{#PZ%0;9HgPS zh2co;7U$dD@IK%j%5pyy0w!+xkU!;l&Pv+{9Hy~2%`k{Jbp(9P)G8EVq@`Vn6O69D zma6nOO{)exVoc^$uGxU!RhFw?Eroi-3j+VzA_z5WtXTx|W1g8ssH-NJAn;~oWrATn zNMp67Q3ZZlLy@uctwj)o?yOZU5rS%pLJ(6X3Po5=QHXqu@s5HRudx`*K*Ev^0nA5O zjv^GnqWH>b7@r6hMHk-_CAu3ex*lMkwQmEMkFLj}qxEHs18I6!y`B_`*hLUX;F%y4 zv5O!uU*z~k9cesnY4ifAtTfr`!j8~ui4as%6oQysguPLro1#TA#$Q{(;MZ+94BVyg zhvVt^1HfB0$ynmx?~8t-#1nZY1OdwTED6N_j&Zb?*-Be=e{0I5CHr`k|10SAp$2cBoF5|9+cRyf*!uZ{Z$YvdA;(4|^WFQS(cR+CAUu-{~c z9(L2*==u$+bgieMbw z5R*w9olPeB=;FzQ@*SnMk{YjG1mQ#OkAv%vgR>vy_C<ere7Hp!?ETrS^lKHD za)&tB)=H0bt=-cr^&yE-Rb-d84MMDPE)Gm-p>K6&67#;TpEaG|lH=du{0bZ%D- z{+Ov%!XnD%H>_5{GYkw|q=q_@g}1b&P;?Ku8Uiv3q=GLl8m+_3kGxVrv%R>8K>V-V zM_G33Af|<6o}kzLLQe_nR|<)uU=G?tMXookdaP9m`%EYzKUXbxFeXL=X0>MglFc<$ z;48{<%U(5w`iB<`ePZi=6Db3|R&;@xY?|3wqDQ&40o-x3?3A=Kuv=L!s9FleZ^9RJ zh*#C@II|Ts)p8a2n?+E<@Sa}lRE6hxR#<@fYM{$R8W{2sMzb_p=c%@vv-VaCB|SPG z_!P5Vx4pvA~oQK`T}jK8gR6+O2AEwRRK;gRtdPhv7%cdL@?Y$sz9`} zE(YaoRfo#v70ad!e9c%rKnyzbe5s1F_9YZ)5dB5zpbonSV7I*B8x>99N^{3$^^qu zaeAtGr~=P4Rt<=AS$%LA2*8Qcj_kTIu?M`HPa+QF)Dod8uN6&hf5{KuR*xk~qRhp&n5YGx-hEZjk z(zQtyZ5R1f_*Let27K?N%%Jpr;5=nzeIM!zUJ&@$mYHrQ2=$6`#Uk*{7D1>TC!1^F z0m{lOW~cqXr17AoQ3VpabO|7VJ6qKh>Nl1~ACSN^K`3Gui$DU;1fllTm_-nnPa__+ zaT?_~jY?4(WlQ4`OQQnZREsR1wChbF$i{_SPN7IhRzx7#WP(s6B!a+vZspWBPKM&# zddTer3%L%YQJm8r%MA|&_hDl5y_lz7GT{O9=6lWj9TrDFkh-`ydJC%5UsR>uG_F#A zQI+ERaevVcOrR1ou@aK7fUVILhr$5Dzo>^z6FaTr6c1AI(7do>+x4~Eu3($)DP0J- z>Dqg07)I7D<4B?lf;h`QB4NDCKn0SxGcS98jf-~8xUti|wWr^}DRZUFhQPejTA|Zg z8aj2M#2*Toq+NLz>(ZsY74GL*Kzf_3Q{NiAK+j*~<-VuzM|yNC37CS(h1=is^a!n% z6Qf0U$noB(_~0B5JV$wA?l^@Da$=JdIKSVOSMl%15WM)P(V>J@* zYv)MjZIMiD2YoVZPi91RLYZO7ypAD--mgwaCY^KVbzIgapJtty!Yuof^X9FiCt)7q zPo6e!xSoVbd?S*1>o!kq8AZ^i`iK^#63R%6e=ix*($Q*hRML5>$Z1G$PxNO`n|Ci~ z;m-4CPnq|9&cY?e^^$o%$j-(2EL974>rtjn;QOaE`)eXQ7~lt$RXk3yb+6f~0^eu0 zD!>mYOTL0SKZVFUhzIX4)bO+Bp!5%gdzgb#7Ip4lJvCF0?aB10F_J*0V9^_)BBS&; zJUJ^lP41LJZ>oH`@dKQg6P+)j&{MrAa2pftJlTmt6SP>(Wz+)oey_As4S0kK$es~+ zoU*c}gIeYVfuAu}4R}?Ht`c_8$df%xu>?HUSPeYRH&zLFg|VVleHT4-w29OQ6<+39 zitK=Ud=`BkCzgqy5+RfGZax&O(Bn7sD2)KzxGm#JBLI25Y1Rl(@AiVg_Zh1Oe7~|X zT`0cOR_wUJ5? zq_9G*O*E(7ts;j2Pc>F=Z0L~C&}c2h=6c*(p4DB}abVZD_5;Tao4B=XgT}Q_+iLvA zUE9ek1!qkhztexeIcEHr6mdLEm4$1qN}=yA_4z?P%1j4*&{!4VL(0m!Hq?Fkm6C$4 zeY`4s$ZVB>Hyf*tp^urN`nMJG#h8NnFHr+OH$#m-D)bRWW8`Bhf_vBd{;9ls)oD?W zjP<$-^x_^F>d8fJ=&s%ct zqsA(S{=`<;p@@8`X_aEFXgBv6mA=WeqTv>cM7|N>Rg(q#y(iVdDEn4U4LD9&S?7l8 z_JY9OTLhtw@`AvlTLi;Ob?R9>$#=f^5->J}6>9MXFt0U-SEu5(EtwN)%~fCiH@IuS zl`TO+{ZP3w9{?Y25j1Le=1T-S6t1JktdL{?Y1nxIs@Bv z63kpvvG6#>%2fqYHd&2<)Xdqcrcht99cUf+6J^PFsXD;aF;j-3l;Q7QJA;ww0eL!~eP2Ui_`CXXp_8R!(@)jvI z-LB~df?75Mg7`~b9fB^}l+*&+;RlLd)T68uRE(5`MZ%A1X@o^?L@X@g{iIc(mn|VN zh?Kcjz;<#|Ycsp>rJoe+=8jfv-~62yrU$7ByvbW7FO05(LQVJlB~&bWCKKvOP@!5u zoDXP7k6L!67Zk2*#VmCy+}^XoGA&T8E4-n&$3>gK3nH!P(_|}Dgl3nb#XH_msHi~5 zFgwYY=2tCFp)g-?)iEi^UhXQ(>uKE=a-+uEOhu>au|46N7rtJ|_+r+81R=LlM@6=G zP@4!9-6V-+;#!3=h0bt78#aX)ElizFW<1~vVqdDUU#`cIG9$?i@>$b5XKj}1*-|tc`b{QNv!9a+ns0B7Xn#GnG#^Yq)Algaeo5t}VM6D^ z3SAd8ACA54Dz;ae?JCe`yQm|L9adw9QS-$P=inR1Qnt}4#1|}zIY1wU$i-32iKB=w zVsy8b>QQ#Iz!l1Jo0wV(#Y?P25cqJ5VAw%6(X;P14<#V?1>}dx+ER!QsGKm{Q;3FV z4oe}9^30ADVyQ-~ibQ)2v)LJC}Pt6_T;AsyLHd|X+iAuN)((`@&~wxfN>ZYq74X_aH! zWo%9APdgLjuw;I`*wC5?6}@ONlo3N?qg4wbdV;i=?-uj`Va|;-Nrf^M#z~8k zZ_%QNOwQ2g$QwfRhGv`)^a5cnj5MFr2Kj?EObz%)Wo3gkY={^2>}y^T`1%?Z6TJ=6 z(4&lcAUA|Ek5K1&LEy)fRUFzTdUn7Rt7j<0z#1;Zr)s7W7jU|=GIvntdO_gFS_GA_ z!DGYnRaT}8b-oEkPoZwpkbY{Rm4NG;R-GWY(3g1+xUZLr z-9@)^?^ib)npWd&3jMRlMr?>HFjY?yf+RBcL4Z)L=)(cAp1fdPBcM!0R}Sdq0uR*+ zF0B%^ypE+CUH<%?lvJcWIRlOzm+HB%nwc8#E@fp64)u~31pc!{5NfP#J!`;m%E~NS z3<_>kGv721y}&z_<=*4}yyDlq81M}fiwEg{>p8-c5xIeeLwE&)lv)soj6h&MCMrQ7 zA_iPjOp`T$U45y57a6MpT&Aq7dQkrHX$AOg)2#u&)1nLY7Za=i|JEW1wZ82`qfx%E zD$FrkB_LNva?wk)E4&o&8^)>=*W;cQc9OcD`jm+@u2aZkXc;UR@)vlGIF)GN6F0%S z)gDV!plAmW>va|A#h1$H<#NH@TMPUgt-ytPEE?$4^tV>HXujaF@%yZ`YruKR%K9D@ zk6GPyfeLW-S3JbIV*8qTm~*c}3=|B)CspKC)2achx|5Nm3wWrqvIwC3GtLU|eABG~ z`DwyT7wU5+SOH$s;sokeFBtY)Zsu)nA|>D<#;OzTamFeE*^SF!BCgMyR6UL$S|7)& z^lZ~=d|2Umo`r3$dSo!gwxf|lD#Y)ecVmg76g>lv^|}i5;*o=1E*IRrwZK*!fL$r{488&AT*)~C#TbSXyy6HTN9 zoTRMwWPa#A;Wd|cnpzFGsXfE10Jl_DRvoDKdO={xST!KOc9`ixU2cLE;8iV7puXY- z!z6y7u|H)wlz^L=R-I`1Jx$qi0^jGQi0cZ^iX(_d+2iVYqG>gDQh1POVSBk}#kQkS zMk>Vb)*>uXl%n-1*6S+Ji$@uHxmP2?qV;K&o_oPcQUi`}d8!L_nmxs> z0T;FihMnUeJ=fr7<{-vH#t3}xU0`RPGfe1QLGi2!P9XBLYH0^e?|8gP4M zWy1pMT_#uo?$;s+b%+-PHjGsR_OZH|a=1ah7#;TLRKAuIW zy`B|D@O5?by18p?sM7q@p)5(*ezzHFVEa(d3T=}L@w*iXOVp)km5TM`*L>8C*Nevw zdbwOsduxForp~@;xz&IVji75afPXbs4ahJ5N$G$a=-WlJ-UfBTXfp?V@5UJ`6ND;{ zF+pHmS(#vV+W-4rwS0(qm;=OS(T6=gqACAYU#L1>o>wmG$p61g9@s7GB!M4jT0_Zk z{>LgeRz6^|tfR85Lw=@vS;xS#j%A&tWu2V;)2J+g0;#@bot%AMrN$(^fhiH<M?b1yozEfhv*iV7Dx=j0A5 zg!8jw=ZNgOCVQORBd}MH3?loeD9MQH?ulVC2pzO0=bS99-8mxl*!lFxIYNi8$vG#F zUb}NdPK=$;h@2yI#+saS^6a%cM`TItd}ibvp$pdJoRgQV-8mwc$If?-oFkO3$vG!i zuH88zH^$C)iJT*J`B=swurCXXj`FmIB`n%td#$ao!t#7+ z=s5dqw^ae2t1Nj#$Y2U_smYarpEFkF28BMwa-ut)4fQA&55V1wRR$ictfo(hipkZ0 z^Ndvie#uy6;0?a__K~8wgwO?OIr0>waqeGb?{TwdQ94cljhY9&%8R@%)Ahc!DnsF^5JGGB}y zib3a=X$MG>@)C~agESJ!6nqqD19iBW9_1xa@`I32_!Mg^2l0BZ6<3&DS`zw3QxXFI z?&%+xWxOd!-)44dGASU{YBIy=y~zx#N2$J~$;f@fxGVLN2PG3J;JH4v6@w5=4kAYq zzM#=vNX8AlPKFdP*ETl{GH|@9XaL3O48-XSkPhL>%f*17&~%0;gYw?Wi7B+tXduog zno2I#Cf;5zzhpxGy6*YdxC!evow58hRS9=Nt{c#}>>@-nY+7N34SSP@;3v->AY;>A zM1vWW>k3bP%_|<0@}ZZ(G#r&C9eQ7`-noXBg%X(S&C3T#J=dF;50Y@MH!mLyQzplsi<=Q#>nCSFrXC+f6Xo6Gp*e>7QXL0J$ zc6Ge)kJ*Z8qInZm`y8``@Z3KBK_rjDp-}6!?r^3=;e7D)9M#lPA-rynO-4T(^O&o7tzi zrDqSH5-q}GScF@IwEwXPkCHFqX6H|lyDe~;F-MsTcQ))3Rc-$Z^(ZSTka@TxIb-?! zNb%1)wrH^7$zLvWA5jTMH~dcBgwa{xhaCof7%2X@6(++MI7w$*dD+Y26oMZHa{E9% z{|=j(tH47|^|baB;z%zCJkjLj!@Uq6Hs-wc6ykJaip4N#37UN0XPeUKa)ML|(#_f6 z@w%kQb6y~~-rABwf!t3JDd6L#SOfl1S@OZcwiMzS&m2r4w$vZ98J3(em_oc=nc@Vv zqsh%3Od)nPrYOHliT#Z!k`NzMrgXxZ!bV;W;utS?lETySauAEW+_?%b$jd=o?&Ypl z_{F>�_39Y+2VvanttF%3N;C^+z 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 DifE)p literal 0 HcmV?d00001 diff --git a/bin/glnxa64/libpqtypes.so.0 b/bin/glnxa64/libpqtypes.so.0 new file mode 100644 index 0000000000000000000000000000000000000000..e32763c75af469511f0284d2eb2e18fb79bae633 GIT binary patch literal 435888 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�_39Y+2VvanttF%3N;C^+z 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 DifE)p literal 0 HcmV?d00001 diff --git a/bin/win32/libpqtypes.dll b/bin/win32/libpqtypes.dll new file mode 100644 index 0000000000000000000000000000000000000000..9ac77ddeefd44f6b6e347e745b0a1c6c8e772a75 GIT binary patch literal 118272 zcmeFae_)f<**}~#X&WGr04YQbQZQ~X*SKJ!6ziY>twlsUwy<)=U9=3Rq|&Xs~l-p}XUchVMc^L_t# z-+x{-z3=uKeegfB*HLVZ5F+^QlR? z$H)C?)>i$JKh0VeT6IU^n%i&t+U+;qTKLr)SFgS;QurS?7v3ISUASs>Vf9jf;jOpb zbo0E46URHXs+ZsXZmVNz$K1>>f1`cw`FPIXc<$VD<@GZ8d}H`pd38+foEt`Z!PlqH zJx9KuH&-vOGw05b*K_2xe$`h)tn;%l@GjEnmgtSTx=&U%Wb(YB%b7JnKVGMM3@JD0 zW%6TB;$p?GM?PBReU46-t5e@+uDTK=l8E@1qjTdW3b9=Fsy-ea(&-97@ZzI7-A#P` zS^o-ibRqL+y&Oru;e*rqsz;|&RM18;jk=o`xp{2_&oBNCe+b`W_-SzCPW~$d_VaGP z>Bh*7!1GEZ_25^D-{bg=`sYT|^VDp*Wd&>$zdg7Bx6%LHsA1miH{WvGS9Q9UiFgCt zbdzxH84D=#Ekx@7|L^}r3dD}Me^&gW-degNUhS+51VxK;Nvy_d6g5_{=45}h(?nq6 z5vR3tD0*&CIRc)D?Jzbsi6zd;(%nklBYbuz8^pZM_wJr0Y8(xr8@B7L!StTk4s&BR z-{GID`Jy&aS0*Mu!=8^XbK2v#I7?C&gzX8B(VJM}EcYqDLry#g9QBE6XR%lLi7aU^ z?Rk=AI^Sy@Z~6U_4!hg+T+5K~lnJZr`N(Xv>#GkHXBxJSG<>txus`8=kMdMH6u;hS z>)hKqPqc|86qvJpLQ@$o>=m9nNMb}iS?OWpSJu>+~Ty0MP;Swc#G3o zQQrC$Ahby=%Qvx-JaJ8#Sb&<0v6g(34pl8HH;L+UbGKIjsw0 z{dV+-)it^0DRk}Ug`|v=l&;>0T?8FoU&tiO zq3g&Nvd*pSVK96les&;QRC)k3udugXo>=P;d8j6yFY1gwR5#u7d$MVb!faI_eXQR| z#&y|SUWKrf07Vmc#*PYsi(Rxoq*iU~>{-tjHZ}$N+UkSKZ4VGV6B@O4_C%+VG9PDH z)|7#*^Z+SWalO-S**FV@#Uz5U%vmCa#X>tfbSsP=_!JV@-{Evv7xdRF9V0~#;8l$axmpenevjo^ zoQ1l`WJwS)%omo#gG6F(d>rH^wp=O(@0t%9dpj~u7nk$=exQyd1ox9j3Bpiq= zaXQ($7!HD#0Y7-hFap3qE%;4o|z7K>Xkc@j*?}f7P9ydnhMs3 zwxV~u!tJ0kvt>F+#WRDWH(~s-p-0$y(VO+57PULkQlU?A%9dCz3xRCOd0VsY;Q2ECS zNlxH`+#(OsAp)j^(cO?JZWlGi*xGWb&m*nEV}8Idc8dL$M_w@YzGUfzb6hkFl!iaAZ>6Cm z5#Q~DZdxqd65q%|&>>(HJ0+G0V>c)wcKYR0Scm5aBo@$XLl3Grm?aKV_s5%!amxzP ze=RAwhg8@D@kkgq$r>`%#f{DbMyKcpPFa{|UYqSI*=7C)33UD(YS2B<{ubsQxLKsSW>-;RqR}~OCmpLn)8y(GC9^WzI5-CG)|6v2u3t5j9aq^#g3T$ z4Z*M@tP3c=`jOO7MTu5(qRA9YtTy@^a<2_tsDlg?!;mUcPEjQqghe#!eBuS=Haudm zDT;fni9e2Xzy~9QA4OsD!K(L&%&~zv&k05JXQ@3$4t)kCvH6k{_rm0l2W$^KnNMhs zVc+T9DrPg0Y7j?aZ}-HGR0hMv#OYNz zB${LEth#=WEscMX83~WW`z%FHB;!qX<(yB`X(;l3kF?7U~cI+ zcAb@dvNWCnh_VAVS+xYMXv~u;%8b|NWX5Z<&?K2dQZ>?J+uf(AurIi0_Mrh% zWRYqqko6BWn85X_s0_YxGMzp+kz=0nyB~mAJm%7#X7RU1sbf@m-1k1_fv5o0kR8Z% z1OJliZe~U33Q7^#Vqed`_xJT2dRG;S>U*6Mq=OT+T9gZq0ft*8Pz@&HuzhH|Z zl|~v{6sb1Cq3Qb+m5~Y)L8r_aj<*`)b(HHOQcr66eeY9q9zHI$#98(FAykeICp!qn}b&W>imRq|kCM zh;pPTQALq_k+L4zFH?ALl)d`Aayg)c9+O&_%$Q-rxW@)7=4>WMmJ`pa9R44S85{sc z#*A~$7&9{@G88iO#2a*$Ep6qv#~j|E zj!N0-#O^@pkTCvpH_Cd0O0&q;>1jXp1ORAxYpWOD%cdkU?L?+gGXb>@*v}*WO;fB2 zE~+YPLjbXDr>oKBVV_`Q53lnliB%8=BCpv`STy& ztJAe!BB~rA-i4SNdhj)!)lZj$H4D*CQJN41F{g#MPb8H)K7^^ixCoT~WtV)1x*fXa z$aE2~AKPD_E|8wa#YLFNKEtU+lXxzJUcFXXD1?SmRcyR6)1)ceWU-b@EOvyf@-;ng z+1C>@l_=mA;dl7cdqF*TCy)gsd_SQA?1%Hl6xJybj36NKsF|YLKk9qEvg|Y72Smha zih0m&9;6BYR&H!c`o(f%=YhK?3y&k@7|>Y*q?&0(Q!*&lnmW^KuZyK8 ztZxurbL@n^#T7d-bN!cM<+{i?=}MmSLMlhRP@kyLD;^LN70%^k%BzvCuBdrMT))*w z+9gE*t~wAQAU(j%Xn{@clqqbIDH0+0M=|dyjJW}EtyNroGLZO&6Yg_!=dS1^ukzck zsF2eK8WeY%JJWYhqf5mB|CWguU@$Y%;q*p>SY_>e&(if@IVkbz1j~I7;zsyv@I4Y6 z%Z4aloS133?-st8*16ZxwOA&BQx`HRU}PHCT4E=_sncbeiD~~NM>FjRIXYlw+Vi+= zKcTYfHok`=PZ#+jxT*bwP>?+=v*aQvAaz=e`MSrQHO5M>mc## z;8=%}d>{NOorA{MJ>@z}#|gaWtkIiTq{mz}`GM?$#Mb}*;r?{khWTemcf)Hlgi_xC zl*^SrK=#34h42zpI~|4r@zK-|#mjT{AZwq@d0wx#p3Wc;+o^QI1MGS(n&-kG9XS^z zN(gl=2rOZhzIg)MIkZ050v5W%ho0~O=Q14@6X*$omTY;XBtuNHIS|Hs$D6E@HZ&(TwYW4BhK-_?=j`ye{2a5iGR) zbi05@ZaAK&+=-b(JWnnjjJQg(_*k}K;zT!%m_LldzVvGV1_R$Y91qcZZlK_>Y{M#r z`Xc(SnDH?(re7BGkK)=-6l6}+lqqfLpc{q7#rz}46dtd3H|sE?LUa0Ms4`3EeH3f> zLA&*pb0g-;%Oa-Ad6v$*k*bwgAZs)WMJv#B)&jL^0jMr-rogaPU@i-Q*ljLdOLqA;;y6NMoNrGt)a!di3=J;w;y3Q1@GY>WpJt(tyK&GrV4_2uN zXYzQA@mBNTJSGCaaG@_<@OGwEOUDn9emY?zUt>-&SECn^!P*Jw<;jri1{6z!sHN$| zk0sUV-qX`p

)fOuvaqNd~y4npoQ0@_Nb;Z#Ci0(s3b*a#_NdT2-1(pqGKI6p5kURBpk#*{%c8AY8L z1$}O)<>GgtwudoBW?X)W1t-GL*YQ>>Jb%hWyapR^_GW8t)ZBc{jp}*_9e%MRg(LPC zhel^0Tr57s)DWmxmDiv+(P!3##}>ZQM?&-?3DHkm`V0@k6O-3zL*J zicqZQ6bhNsuVsmf6_%_#S?e|WxY|;u>$o$ewoR`UeA=3bSTlqY{r4vS+ zE}VzSN|8HULP|K4r=Zx$0DaZYFX=4Xa?o#77Z_^6o);#rhl-O6VBIEn*94N2I;JX< z2_hGL6Ucz3BYXl%NkV*&GEF|QbamlYGf~$u74=~B;Rt;#9yPCPx2f&;b3%orUHcnTj21#T(92F%3YK%v4&J%Stu)0Xym+0UUHC#IjN` zppmv*t&^*qj!{cP>LO8Fi}Sp>38TQwDw+$)!>X1x7qD#L3W%H!Snm56x3Xbf2XJfW z(|jGrytHN8p3E@94AF@yfsrrzc4`HtQISBn5E#4-M!`x9s7o!Kj!yO}=aHS5WW(@; z^^`x)+3E8pRy!IL*EjLz)j0q-bPM!DLtpik4xKVLMpZ}&G;}Qjw;(2iEAu67tqvV{ zAbNpMI_Z_W|0XTB6_o#soPGe9V>=3yC_F9J=V-f17n#H{q&}cLC2eifnCv}Tb|j7x z_FrkKkl3Q;Mg$_@o$`GxQI5XUFO?(ur5vkabEy^r;=}YSTr>%)xpocnEixJoc>6DEBL9 z7*a0Ob~c2nMj-^N>2o7w)({F}#u-|Bwwf1ZYA&R_{of&$Rjd0GELnxtjH#PS>W>iQ zOx;e^e)xC%1u9#8;J^%v)!4Kq?ne_KwYlxedC`>^II5i(H@wQXTBYW&i@DTc?!Ibg zoemskmrR8LjYG#piHNf@@rV=9$N>mCt!ol5uq=v>JNdWZ8dJYgmf_Ntad#OYNMC<-@oqN#je4`h)Gid+^| zJye#CCh(T(@^UzpA0AGpl>rn0(r!#Fs$ajw={}hIC^`%tLS-#pgF%%o%#nxKgY9w5 zrF&YYt~Yk>x_u%R0ZLG?Z15F8fhNN`Ojt0-twvc;b}a_x>y=0T&N@JeyY0|gm^p|I z5^5-fms>z~_|U`7M2C~>b({~qh(zRXZ*eYb$;YtU;rtEWc<^hP1PU#`I=;dAD4tRi z@QOG52N}BsJa9cStciCxA3{=mv-1(YS>}wOcC4Z4yeO%?VPh!%G%l)y@Di;Vd(cr83-psVg6S7Q(D zL+;votW1L(u|7tykSOScO63P~h>+&S`w%-gMQfGWz!=m!c$2dn%~y+I6jS>E@oe6B ztDRl(-a)l1<}h=$v;5#hIw#|K=n&;iEJnvYC8KOp(Q0n*e|8F1>ltVuUSD;93)=BO z;jyzXd1I+N34g+32JxcujgKWQ5x!{Y#JZIZ!EvEIV0ksF zaiopXOdC2V6>Ec6sg1}+5%A@}D1Hr zrZ=Q4FmAGtaeR--MpbWO1~CUX#zSye@rOGGNq2Y8&@usLk4h0eYQ;^eWS&#(@JPjb=fix3d&tMi~mJAsRbk z&8Wd@C-kd^hQERA^c>`Jgq>s*CWh>pV-bQJ#;LC#QRJ(c%#wvfYikD@@R=R!)y$y-QPUSV# zB+N31%9SGw!cza4DOKgnL`+o`F=EPJtXbKydrb_w;y?y3n)yIg$)Q{>dK^5y@A<>M zk@2boFE(R}yVxxJHY^0xyOqTUM!auUl;cY%-s0-TZ@JEN=92q6* z2PCS>CIH5Ti@4vYnl6O)gF8t)&^9AO#&1YUfwf|H!$dq&USNE4QAoT%wU?)^RD&Rv z&h_AA_Mj>?dnnGJFb7N}uC${N<|7 zx*-bGxQ?QLfLUoNpJqm5SYK)&--b;*|K4GMV~|6nTKk3#$^95GOxf&xi-kwinH`r^9e$Z>U$gZ$oaZ zKhLMAf&N}N3$8J9hHb;0e?))T)CF{@zifcs>O+69H;Ue5Pn*e}v#`<;vdebq%^lV5 zr&39RtIy%RfTS zts(h$t@`%_Q`Vl6e|0&y?~;G-SO1!ra=%snoy@Toq6XkP)=ZWFx}LKUZh7@i}}=KzaZ6 zOtu1VNN2))jzm#j7|F@!aCJc0F(#*xIYBt(XQOiBIb0i1el#X0+#MkjSGj9cPCSPZ zGQTF9Q{u7~6j!{Xvf(+rCZJqBHXFM~xnv|8pTpk>D6_NKGPtk{mGrGytoa-c29#mw z4V5_Aoakodl~FnI9QFj17sup;Vh)iNlwXg^iRbW=fbvK-r^MxcaEa0}DjS}|n5eJI zW}E5_dqZRL8+;022)O7(DRob2rx1{GC4#}SAHQo*C+;Lk0S-_L2s)$;C)hu z8OWR$e2MQdXT9>XYl*6rB7Przvkk##bhWso3#_y@hM|}d*WQ5%4h>&hz$^a5(zcoP z%F1lf^|gt}TwS0u9We*f1!gJorqnpK4%W~Uxd0+6XQ{q=@xB)?pdYIktu#{LY>@G7Fb{~^A%vk%U{m5?MpD_VCoICLp z5RW_mf-BZ9f}+DYz}ue45;}uw=(ed{w~F@L?%cP?n?v2n+Z-4|L0eWsLR zMu5T}<2_cEHakx;qgN@GFciVmWxJXWX7U=W74Bd{a`1)eI^BqR+Z_lm)B5WusXY{# z5njeP&-YciN56~@1ZDf+YSDMbdOb>fF`(pKNcd_+ofl*{z5*!rd%S24?nrP1FH3mI z_Q;4rr9Op?7aPvCe7goh0A*U@0rzmx?kc5;PK=%?R&p@ZB)uXpw5OW(*RNC&ZElhq zLtvW03Kf&(%X;P8@})@}Rhm(JBoDY;7_@d8H zml_O~j&lKOwktBClPeS96;ql4Zy4LX6t_gqKG=X)lqzA8P5G2g*%Yx}1zfT%z5{w) z41!Kuq_bX$-!}Zrc+Rju`;j70eS|-qv=BR-CA@5Ka<&K`-EW+3+(1)+ap^AgV=ykn zwAv=uSK-%I{!1#uoXINKyL!7g91enE7^=P$hG3U7D{sugx=0kR|9}X1qVcG(ta+%XvFM`!!_zt*l zYNccwCv6(mb06w~58nSDdhST*TyM&Jad~`;ZEYkgn}Q@d9WZdow3uc6}3}K9~$Vfxn1y!1D(A{NMNs zR6^bW-1{YX;5NdLQq4->(FG)xcT{1GKca-)vw z$Eq;*zr|VmC|U&xit3eHccs&*i6VYKYENJhL9Xs|9;K}a0N6qDFCexqtPc%9)1e|a zfl(HyzRS{{)YpfSIT4fiAL5b96aPc_0RkLviG_>2vF%2ZzD4RzpVBS+%<2twUvG zpWAd>XJf9&VNecX(aCb(n6h5hjq#^38Ha}+{{!f_UQEL+rbgHjHz{H4LLyw#Vj5HQ zr9BmSt=`gI+4W0oSy?vO#!V#RR_x&EL_7#n%t*10Nim5zBd@LEGCsIty>?e#%Tp3F z8M+0}JLb-IuX67yoz5GIP;dr@rTvW6fn-2wM7l&`ZEkEhr_~Wq7Rj79G3W1)GoTy^ zF^d(EUuTXFYW+~n%)VY$4E&ptZCAM?M&^g!oFr>!M9a+rF24@K_u%f6XnL-^| z#w2PZ2ttvjBkj0SUl!u$P@)nDqbmh{`7xooNlnP;OEv+0xg0cT-$4+PLDxSba{;9d zf>caHzyV3K`S4_~hu^LUUd&=;wVWk_7LnEBe4yqOed1GPEd&bWF=7?`3M3W*Ux$xx z>qqWdIrK(PApoxJ&`6o#+$j1%2O_UY z$P2Dx-9wJzyh<2HpkRclD z1<@{$t+QQ?XrL45RmAAX<@9A;$?4ZS5$cRRM2}XbZ$y(&@ILW)fTW~3)l~141Nw}NV*n{o$p0$D*OFSO~8oz zZD=uo`vnlonqf63Sgnw(<|L~*LA64~@QI39Pvm)V6$Tl`3KW4Z(o&}+Vdz8S_1>Tl z6uFrM3Mw0=@ZHSa~1l2|^>3mTO3YN_5~CPlsg^BmEMm>M|3dVd2*Gl}}EURe%x z9nVWm0$m+mr5k)j6@n3|LAj<%9lg@vFi5ZKcw~HbUT7qfrYs@z0qEbi)reATjo9EM zJv32#?LSCW(ombSkg2U`7F%hZUOw3BmHTP1Uo*0JEAR-{aI?BEHUo;}lFzK~4>L#AH-sr2W|`QqpIB=0DetI{0V{%WF&i6@kFh>G zTC)e0U3iS`C~4jbh;*k<7(cVUs?qIzYixUWX$@G>fHkOuWCPCTt@bk;z(NgowC)oh z$w*+ZOzzfPWD}|0zZne*4xngIgO2GP%ttRzz{FDAS%i!eR1^IByl`gt+wn`H6Dh0ld}(Jk!KImH1J&OsJZ@1}DFWp|E`x02 zY=|M_!weeFEQ3s8#5O(DYJbV~94l8o{LSdjIyYwH!XtgsYvpW;>p4{w9&_{p=y*iJ z&BjcM+N38sSJXK|<&g4#=6uG=5ROt%3gJQm`5+;&q{**LmL4Vh=+&FuyUzyiq|Xg+ zA>sWwvX6mxXQLEH%o#d44hSV;1=dcpQcN zY50;|EgHIzQbdD|Fs$6wFv76#Ifm`B|B-(Tt~;gvq6Z<{|2G3MvnpZcw&Ru2>Y!I+ zf)%PGr5V^?CNs%^IWxInCdLr6&l^ix{fbS3O<^4eX-AaFRghW;kV=j{P%3~&y83ki zzj6`gOkjsP?zS|c|K($>5BimLndFShDZ3w)8Dk3}n+vU?_9WZ|<6sLK2fu#~tc0G5 z1xCyFd%QTeMvU`HSyx)rNqTmSIqQCqAWB0txgW&dAW|5%uwA4K3Oe?jag2IyT!BM- zsGd*L$4;q+Z)gA(dX7j^6Z!CnQEo&HQwwJmkH*JXS?APwky~6-DH>G$a}`t=)MO!W zb>eiMiuje?*!hZnD2hynKq3%&5dv|cKN{qAmFC84ll}lK9MRWp>eyxJ_z(;$X1tB~ z9g(I6ofy6ZM*xB3?2Vf4TD`ktSM=}ng;Vv5Ys!1yF$R6g#Zq%-l)X(fsHe*`$So^P z2(7y|S$d%Sd`m|sOAV{>M{vp5yC)?)dU9VzUE5)0D^n!;8Fg(}nF(1`b&V_u2!L{A z8HvPPRM#W9E{Tp4M`ahLa!PxuFpwe31#MRqNAo<028@22k_RF&!WmKe@pAzn1``~J z0kFwrqro1fGftBqsqbH;exbe?p!lqn>-StpKU3eE>HGXD^zs<_>5}>h@)OYswYiEcn|rCz1M#IN6^m*+ap)-BTRzqD{q1}e51tfN`pjB>qAC}$77fy6U}nxy zz<-9moAkNiN903L`8l$Wfq$oz)lu*VaYm7f!^D7coz!O%6fr>y-S8%=jDYg@(n&A| zN^}cs%}@kApt-hRm9=NqEb-nX_iQ23k`pVqu8RY~#2@5wKf@v&+jbHXiv?~*R!4Y} z5(Klo?>DfSmPX%dZo=Fw&o2{Ii^fMjz$QOeAL52_giOR~l;ev2GFUEGv(QVmv`&>9aoN4%wm7)k7J?$xAn8QX)Z5dq1IZ z{iCHH8y9b$sAstINclRHFU{lz6R~_inUzV2T&yC44UO}$&eM`?#!_!j6ZjSfm$2Su z1GNO6ama~$Zd{RDh(?ek^NnSP-2j>k%j*qTri~5HUT0QI$s);^GTQ}uuluW-Xh7eb z#!mD%8O7v4X%BXj**o_}ap+gM)^SNGz@!36W99~^2hpwS1}L1Ff}&0=Vr%?%zMywAem5+pr0BYz?_N6FyD=0b zW?(b~(d#1lGQtD;W|tf#f|$`=14G*i+i?*pviIfbfZpY8SLz}qa1Q1_xdV`<@}K19 zAkkaz^M;;A0_^dc`BL+D_K3c_CpM#4Q?i-9MQnyWUH{AF?jVmd3n=43aI|L+9bq-f z@1<(wOw;1UREN=-=X<5L3=PN(8)XJ+^=YBMAjPXZrFI#&Ww_&>@}P1vvIMaKDX3;` z#=!$)AwUFBMNQ?pJgI7v0g?in>K~Z1T^xPsR4R9y31k#3p?RZUf{4TdsSjHQ_Kn5ox;4y7a9gFl%K!F#!WC9#>B9o zp99;d8zP0+0>Uwp;qKTIMKb2QJ$N5|uQ_(gx^7B;>=ESSzeMa&{B6R<<1KKgpUsng zxok~(lGS2tf|T~ryFwq0QO?x4Xfr5%0K}oB+w2_bHARbtdULSg9RiL@N(PIdrfZW! zy~cA< zp;PX9u68)Et5KIh6rtJ3)Qv8B)MV*oJ&)!@TOKt=*ITwlFpMuPLpLw;9y@&A5X##^ zj{s%g1s^HDuaNA{#f$`7@s|bUyL#pOnKzNUKwpzP_8eE+Os)w^p~rjrY!cds1SO)J0) zeHk^^z7ET>dR+@AHkh8!>xCX!ULPv@E96gk5yw)+^HVFJ4Y@)gJ=e={aOPu_PUSK6 z?fgt7)6P~&inIT-6#gCyV+2N->tj1?US)QPBq`zdDFt{S#_7oUF!S@9Vdjs*w0G$U zrW>4c^$om+{Up1UUyQtxeb9bnD=HkJ|KoV_iwB*1aHZVPkx0+~PFzE#cVWfsgf`(i zDIAdHaQ~MmaacWg#6qZY)nU@z2CtX4Y%*6S;3NQsqHS=pb^tL;0>Os4i$hzH&N*w= zp*o@>vw{-{jSdBNvy)#sBs=-Ex}O^h9tR!jahFAJ-I5Ad`B%0_wjo<^z~&WZ2Bum2Qvkz2wN z2$`G9T?ZhPErr9hwEd2lFQAKUK#nBOiCSW7PwJxMu8{te zoj}rFB)!X|cT0NSG>(71%ffQ8?Kw4=!CPH>Zr_mxU}y@!BNT*&Ey%1X|3O(nL~+RPrWD^ zlrPG*8H1m0{o0&=CY~XjfC^S(X1~n0hao;txvto=a;B5GPlpA9D9&?C6(!2rdjD?J zn&3c<%`%aTY3K-BMF9TTyo}T->s1D-D{Io{s!eI*k}RhktFBBz(88E zFk~-89FZDBbdQ>+-%|~WAQGxly|{U4O12+)6rwVsA0NRJHp=M1#bz)3#UFu@maD70 z0cEC(;LwusbYp)3O_}*LWiC=pnZkX9#)wg=2_3+ipbHCtLi-LjBJG=t)FJqv182$l z?$z0>ZRPVL7Y9OXppcbaGOuZDwcAGWCN@Y7=Ju&Bpu}cr3@NwE#aWtp4?q+6kxap5 z6ilMS`37$3OZzRBUBp0a2c3nt0_SBM1F@>T*~uUwE&6SzTnod&6YBOGFB*Is<(cc_ zkz5aJxkBXx+9rWE(@8Ok7^V@Z+y6-IwaWy3U;SAPFGZE!kd^iAc#QX9Xh8WXG9rv9)-xNzF1pZid?Wt~sY59)=%Dxy2$JAQJ~~(s zJDIeRS`ajG_~Jhx{o>z}Zw-k66kL7$TU4aVT`>HB!!6$Mf>_@ooVS8!NGYoQ3+jmN zaFRiHOUYDnM?j{)1-Kxp{QXsQ1H=a0<2n|dqOJ+QghY*0& zdVSqgb@X~reI@CXjE-B;tj$5_cC%ysFf8q?fbter`ye?StX%z>5wlq>+^Ci=eGl6Z zH^xW|NIMo{5bC4Gyx}a{X$S@loD@5iKf*t%#g9e$7UAe3SE^+{YQUTnT3v3K-$Nt! zg6&>^0|w|qWe{ufEP=yZB1P~eICTgU2ON-lhu04Uq}0IT5R6yCacC9^s2%a@{hUl9 zBbOAcDv5sgiX;(y0Re3iKc1_YM`=0@A?imOi}6e*fRs@RH>>+D`p>2m#?0E#9@i5Q z;-ju9VsErkE8SW)=~_7BeNMen^snCQ>lM?e_h<9Z&0B=N`CR@vJ^forWFO<-QlRM| zD5t#CEG@bSQ#ix&fLk>3h z6FX9yQN9RR!|EY;ZTZ;cshOx=U9I8*m78j7QwCxzD5?tpj8vf#n{~PuQ*Lyqh9ce| zp{z}Y;S}^M8)c=V7P0;SnUzGdbp94BPej&q&rICnv~?VaTnY`a%r$t&Y|FNnG4nqP zGY^sp0_V1UGB;}MYSb<2Zr0ay9EiROhJdEzM4}ILQhsw4tCbsku04HuBn#SyvhCVr z>{BClL*-{&qv{%{JmpK>=|MD})AFJx{K{eJcp-x>Q^$JD!XD8ws1!ci{0l^WTu!>i z()o#n8XHKWO1CiN6;c|#=nSGlwRM0>fah{Fr_H*;l0C|hFoqqkWxeVqyIz&Dmd-8I zDw#Dz9BS^BF)dHZoIK0Fr`4_6&)w$Bct*n9Gpwv-mwkqrHKD4e#x>m1ht*AVgH3!g z=Qy@xUWuwfCOdVW9#cTz#3QP(xT_seg@d}XINgZM8csphfw_IH3R)^Bei`y{3;@C9 ztha0=Ge}PT)bB3Bd#ukuL-3jL0{mi+lF#-_;rj39g?Z@uC(!Juvj-JTW zO_lSa`i0#K^b2rc#6Myu3=uTcwB1Czcz|^brz7u!uW)d+I&9$8NM*Q#H9em|gbM-A zYnhPu>0unUu6g02lTnuzb46=uyH&RmqmAv!9CXIYxQSf5GVaYmnmJx;#G@6*U^Mr8 zjLd-3fVjohW3}P|K39|;(>}7xI2+>S=+8qYov#npNx>dchLb4=T)V9+aSB-uPGpK! z<8Hh$Iv;1PaqD`dOoo=hcF5TCR`d`~(Sq?k3v-n?S1ro0e3Dq>VE*XqXs}3d4b&OZ zft`FIJ^n&xIwZxh7liKr?RFh*)U&^EpDy?d-sa|WpdL2dm5)sbT~X|{I({ikbiChs zB6IVJcC+agyvNoxYb$=d&mi4?#AX_8&s*_Ce}@BCsrSlpgRLq63KrW8gb8sHg$ZOK zNz(_DMW@^jovr5B;GBz$h#BweaF*c?k(8NtehdwW8&T0qJngK;YZXiAhwIS@EXd`! z#C8+~M88*{0z5&}`IQjHe;z<@>HHq5WQW4RAN`M@^2;wXKLZZx5P5Y-9Xjyj2F-0e zxWpD4wnn}P;#$#23F@myE4+&5yy624j~&iRJYk6RD>+&#k)NdIZYAAPMX-rxS6~YP zvP8~7gfC4uPPQh;7utlrVvP-McZ7KLq4GlHQHK=8k3j}8SV%xu$oL-24`I876E`_w zRNHZ;pt#K}8C;b&)%=PyN+y>{5PhJrP_lF!*3m!@`{ppFfM0;4DOr()T!p$B!|Ui z6*w0l3InK7a`B4T4hKXN{aEhWuC6Foc&(Ps7r_7(UVJ9xIeCM#d!Cjz4s}Diurtzr zD(aIpU39Tdm#L}Ni0}B=V#jkL^3|6|y;@^(eH1w#9+t>C@b4hgDTA7+a#W^TGi4tD zl@XvJv?_fhP8+-;B6=;mlq&Kw!z2n zM2yL8893+fL^1S6E?rIMf!)eN4`M=xL)Op_6D&`-IR{azV;+6<9I$s;=ziqE!9B<` zj(N}={4S8rmGI-8EBcNNG@sYgbYTZLxG|S%LTe7)SX8=eCEP}vdlTQ#<0fKVDdWl@ z;x|IV z-E`=gj9?i{$E~=>IJXF*Sf(bJV+@5zmM4Cb}{i0 z^aB7bS}6)1#Vv>1O3o$A=_M*A3nlOalIE3C4xmmLXiC2A@sE5uP1?1?G5k1Em4nV&}}8IcUiqIiEekYNQ}& z)jXc9CcwfE1058uM&Tdg*7C$%IYUWPcpgA{TTVr&U7Ikhr>-T1YSi&`F4;DcR~wm88@am)RFiU|QLXig z4DtDf<0~T-*)2C^-!K6N8+k|^4JZ>-)Z7xaJ1^!a6z~Cm&6Ywv>MVto%*ZLx= zs?W{7ISryCU&=s)oKD&ayJbP;a z*`>z87oK1VM5c!bI{LF#Rv!)Gb_s41fRMGJf?})}qz;GL(}=t1abHUm-qo$w{j(fbX7FpXA{9I?ir1w7iQhwP{T1j2Dn5KQ|(1 zBR$|4cU}hx&1XS6Kjqao)!Q*7MQD&_4Mw>GqS8|`kx8P8lIjDS3x^?kky`<%dS~JGM z=oh;tb(^~C^s%)@T^NCJ+q(ieu^wxm$6)lrdlgVR%D^l59vJNYzBx5TC>lFHJzCnA zXBa7G&6KmD98P{`xh1lkoG)nQV4wIxZ=)O3&-T$VrTvQ?S({1@OeC$QyVuMhqahw|b)IncSomqBieLF(8J z8_p4!+-1kgNcQBaycAA=EhN+(a;6(DL>+d&55W{l0PV^?1;89qX%ypX2UF-=$>;>X zavcUe+09^4gm_Yi_;KrI4-aEVl0Dq-`Xmx)Pg9RatnF!PrsyozGadDSnKc)RS`eT+ zl|NwI1gMfiYP{PXSe0Z-uoEeyuH>(!tJEqMV2)%GSKGZleEcV1dV_vjc>|BYNm}N^)AD?E~R+9s2S+*@T_&7NVSmA=mm4(chxtTaw8(rT~ET^+~ zG5d+uY$Xj=;s{pDmZkdmB+Is74vud^l?E^Cs@kv=g*2R^t(RDqd)#W8Gkw?Kx zkXO1a&}SqV5LmBelKu&vr&SH|%1J)7XBg)TmyLRkWe?|;@u$c!Sb&py;Aik#ww%*- zu4T)$Mm%&~r^g)}1h~t=omt))aA%cwIH$X)`)XTPZSK}Q0Ha3w#g5q2BZi!a%;Acq z`hCPXC4iRSM;vp+(AmC?Xp>RC0p%H#7;_%aTbB`GDG-Oz98MZiJ$nscNx7M-klGp% zaHAh9y&+?Yr=%2=Na-ky4d+E~!YN}#Y1DDob+CM_?Vrl~I>yzteBims$A41eXFcS`Y-6fp+^Vq8HBE9PJzD> z5eFE%sW34-Npl{4n3eEcP2EmKY-)Z`Uu7}E>+=h#OOKcS1Rn0sbWm9J!zI~Tp6FKI+`s{ zOofu8&9^e1pY=VTP9IPwGMVF3Kv{4^qmLkYvTiEvM0<@2XT^W+=fz(-NT&kbvG}vR z#J`64UlAVf1p{&tmcbXtY<~>&f%BBHI1}Xz!h-nn(4JA~s{TiuFSiz7ZM`ryT97At zm8B_(v6TDCahp?IZA@8_$wcp)Z&;?Bgw$d=6w4p-`+-&^44sW$kdtqg9K#-&`S+Op zB~8Vjmp*XK=KE4JCgmkN)emuzJqt#aHr!;dFe9SYG0LGx2R0 zk%tj!C__I3GRHp5DbNf1-rqmSuR>MdbFMt^@~pCfytc-Dns}U*TQq;Q#xFBZ=a-p- zS$;XBPmR|&<Ow&R05A5Fpt&N+h!l<0Vjv5~KXWDFHlGx(q+3jNJ>N3P()ke7mg_mo zM!9S}0bf^`Qrh!W*Hnz{6}CFdfA)ysRJCw)+A-c(o~^Dsb@cuh6&Qxw(=yxS_Wq+-fL|G} ztdm(&uk#i@1Poc7yY3zrtFoO+8`4!UpEDcfG%@yzW?O@}EFk^~7kJY3QS02;uJp61>FR-V3&8bZ*D<(%xb+JLF|HJhW7B+&Wc+lwjXT+K?f5``L z=Oo!X=J*w|DUSDYk*}!qJ?v`;BFc=>epdJ&(zv%p&a-UE6ElXP?c^Q~IzuPP9T4we z`B|o0woMZA%fbKZ(f_gG)t1ix1A17t1@!7!&#~bfEuBA+NgkX6P7j~VC6LtZF~s_? zV>WWG+)rrPwi9zQWI#KMyFGdj{QN15+9hJ56_XxOVB-YHBqrK<^%_NigEzHEDa1{4 z+-nvEPTV!cYpsoOFAla)hjaJ_NL-A`@Qct?HWi_xQ8Q=x>L*Jq+wx+{oCxB=5f(<{ zSLenQ-bj)F<9X3M`PFX^2!iqGC@3PqjPgSb*}Adxa7NwyL`6Wko^3_KHu$PASfXL^#jl9pW)yom zhgxp{1>jWE>s9{TvLL-u46HO9kpCxPaIZA~TDLNugTS*`ud#Dz z{ci~c92ulI08qwbz6N4ye48OM&g>mU-=Om1`upe{z(EPGA+0JP@ZRO2Kx^@8(> zZ*iL2*O_!Z+}=Elz39tOB&fV0M{5Q-HA)-Sj_>o5v+X1;yldE})~7ThluRtbXH7aa z>fx|i^^}-IbxB?Y*z>OZre>TU+?Zq&Zj}6UG_NmzZepn(<@^ZpH23LC5^MDf246zG zTxhm*_2bU9PPcBHXs}tHD7yz6B8Du_zPk10YyQJ}?A_iIdD`dqFwqlxR_(QeUWSiK z_tMGy)9nm>v-~tU;brk|B-dEdrC-3J^1Hn#n)zU`Ec*4m4~~?ZFgp9!R<2yhmU2e7 zbZo!;zVM#X1G1%LVp*VM!Xd2@P}|-$xn_Y-Tx*S%jq{;BxxfdP{Km(DPM?0>f`si0 zT#aDTe6E0a?ddAbY^_?92ZW+5N;~!B5qwgOMq42*1gK6f z7cll+#@XU3w}84&f>p>9@YY5r1(ZA02zM+w+mo2z;hP}=<(qJsbM^quPwL@1>Ie|< zjLa+oW#mwNEVyMZH?hHmEw=-5xB9qdY*truVMC;t!S#@a^vf${_^1t|6|wMP;+}(B ztPR!U7T+1cU+iKx!6)t1MdpF!-fLx`xYP24c`b$>6t9W(<+whT?l&h)c&Q4}FyxOx zPmQw4jQptQk$mfd(LPX~N5V<;)AIb5G4trZ7DCH#9(|NY^~$Z?7y>wjx(Gfj>1vWL zESg1d60jzC2X352A6_9Il8ou_D>oov%;dV0^-2>ppGWvQ;-%7-8mZ#^kt!@tOo9c= zi5NZ+VtFEvV|ikLU!Jn_sm^%6{CEfN_gJ3r}DHuIQ@T9 z3B0;9e-CWB!H3cFr3ZM9Vk?%CCZQd40H(Ia>#9gwq_=Q2OHTH2fS(SS!L%<|R`U!L zEH~AQqZx&0jh#wIao({bw491b?#oIo0uvSclyS2`hG02^3+feRCLW+l!BhBZ5<=2= zVzCMncR!~l^ThuWgpN#lFQ?c6EI-C3L;q9s}H@co1&D7XMYIijmTi$BM>lI_)iMm=5SOQyp zML$U3@rt@-*s8N_0+uV_q=?VMcZcGuYvZez#8-Rct8qr5I$Yq;*|8Hod44XIXt9B( z8QY051~!1Xa$|o=%Rv<@xyC?6e)JyTU>>v43WUIt2Ny1;As|_P=ziDeomNw^yNL?W zuoohsZM6~uh)C@CCQDl2!tF(ch93UsO_;Av*j`|8-v6GDponG@Ai;u+IewQ>y3R1Dem`}Ny^mMVZHFd1pi*DX$ah5jO50f%&Gc{dF$}WL1P19#^`O91LfF5 zF?nteVuzHuzg2w(jB033f@~fmz9ZM*$DVG$fl3I2hXGnV1P=ZmL~GzfK(=%~Y(r^Z zjoGcG&Ogl98G~(j;3XwKOFarWuNgS)11!MY(WFWkpbNlH4N=9lzr@(PZD7c&C+@Nv+9FG3b8pxb7 z@N225n`A+uo(Jg_o@%es^b+5g;x$XqH?t5F$m1S8wFnn06#=ieURj5}l^K?SRtRzU z69#J)n3$~8l&Q2fUW2`_W*j;mh5(>Q6I3l+lKw#H0lyMJW{f#jpaZY`l+gVIYk{o6 zNQd2ND7!w<&eTz6sCm?hWq3K<5El|n57q@;hqc{(xa`OTIum31JGCo zG`2tvRW#s<1{!%;G@kyIEUGpDxdj>x;mSmv*_Q~KaVG3}Xbq-48{?-0Y*Y+O>}CTt zU{}8uq>@1;22}}i zKzR}WEQ@RnL6DUpAemYA=y2YIB+=nq!^;L|1Q)pu(uNyG9g>AS8Q~5GGlom-$2}F1$4743j20xoG>%3c zABol>3lmVfl0d+!Lc@i?%09H6Cq~9MAr*oWBi-^ zi06cG!Ey3O3bww{iUmb}trtoa$8W7xL*Jzz0s)+h?4s=Ymo1GBh)I;) z&Rwk+K;yveAYRh;znO5h50Y~X`(i!zuS7p!HnFJ8udZ;?t{xBa;uI+KTvALD>x#4( z(Re;qyJA;ybrBTD6n^6$@fYD&{HnYoHD0S9_c(zw)-u(KBRr?7J8$9bPDd@G!7jcl zH%{3m!!bimh?HuBO-*$fC#zqPLs!t*k0U>+D-HZyhkV9odIB&UrsB+s*jh8bb4n+A zt3zyuLPek35#Ab9N~VFFz<7t*&|-iMhA{&i>eW=J)s<)2a4p3YSOZOwRM7<8Z_3bJ zu3<{#Q8){8!rW%qCCtw!Y;IH!#juA5l=wnrvKXXJn_Zvof5-Pzq=|@Wky{O#mkZ7Z z;OCGoRz%P=1Z`O)kBeGmTiB41pKv-pf zaN5{d?Myb;q1NSeSG2R{#IoN~4$ON1lrPkx zMv$Wj)ZDlp9u1APGEmRTkWaAV$4ah!l+M0b}V3PI_ zwowdwW&K#&mHT6G-pCAE>yY3^$qUvXw&e&#`jdp`<3#JnY6WzA3eWJUhrChu{8}TM zVJ)>85f|E^cP`n%hAEAZtGX4Lj8-V6m)H0o-K|=4T-xD zJBN8+flew_fF5$U3F>H=!s1*wq3O%TG!U9Z;aLo!=s3GBOJb9$VnJ_A5sCA zFvND|U}oElBa4X!Q6#1~mH;Da=m-Q+`L4`vRq@R7o2Xh+QC0hI&cCSg1_7H5J;Hg} z=vmq1gl)@db26OTo-z1m$|mIo$fQ_Yt4`6{vB{S)h6O2O<;4-Z7KQ&_Xa}kBho5R=bg~V>(^fU{C)vcr z0==v>Ge4aiQdnwTCIb%Kkn@nBGGKv@!#spL#-;|<8Aw28QxDU~o~!>eIjo!dJzg?i zzo%BcEa62xdjWH~%>LO#*|UZr!w`JkoV(I|Q0%9pDgq zVvT9ebBT3ybXiq-&Ex0d>W0DEwJKA^Yw%U~$a-|SRT!_tE%aXY9YgkS5_yv3*=ciJ zPP4DU;2JQ>4uv9LOROQe+SFQpbdcxVA&)$Qc{$!!0XzshWfd!pmJMst=`?g0j`dP^ z-)@pqg3-Hg886L2&_Olept-}7e{sqg__IDUkSj%!khGGa45GPmNE|ZYqzn%5YM6B) z_C@16uh9^+hm{pJ;DoImlO)CZjF;(#4Eo4~Qw-~ST zDt+U|wuTy^$|NFLNmFmykF0?uJTf=Bh4y=gb1g3$oGrX;cDCWdO$wWF<)I9laOF(t zep~@9kA-~*x12I{s7d(VduAe`>;gHNOVfzpfXiI{I7lBOAot1t86`0M<;{6LVY9n7 z%SLXug|2@e;;{NbO^616iClg|ZxC~AIrN(K=MR1dY2Eo)AwyHn*zpUoTl4q@kqgLq zI2ULt4okmQ?^2<@}_NTW+wK?M*-?+X5fMzslJAEqH_Y0n7`O{W7x1Mu-7w z2YF;jXNr_(;Jpo82CLJn*I>28yh!Pu-eohT^Wcqm>c?^xfVCsz;6Erf^cP~;MLi&) z5G_V%sl5C+QM2Nlcl7lYILQl8l#nIXa{qD<3To%mzq>_d#C~{EqeXQ^E`8}LT&fGKi-<*5yx#!+{?!B`YY|XXeMZy-w z+36dH2WI4VzejzbxV-7WjJXvx`k+p~*@) zIVxxDo9tb(%;5O{4<&i+E8sDozYa1mF0(wm@JcNll2URpuGm{(1OnS57Rb@qAtUsC z>p}p1< z=kyMtDK@or5Hz2#B3wScd@Y(gZH~ziUWs3ZbMiE6yYCxRq?{91Aes#WkN5_|JGM_( ze0B}-x4X{Wopm{^v0so(D`4_vY!ni$*zgMLgigFhGyetdt>Qydur@yB*+oN5@1TZD zE4I3kZx)@YK=6%EZmsWl4}IXXuuN_(nc;?Ju40-wcWgn0l+!mTrx;#}KCsS>P0~Yu zLQW7Xdh3$bKB|DXcSzK(LENDhY|y7o#q77{ODl+qtd6b5yKOjE1SUfQ(VS|Bx^$j6HPMmEn*9{Ny9JN)0&MR+AGCZxt`X-oWg~ z=r931F?9F^u#`_{Vd%j8#?85uX9r@DfpngRh8!PcZk^uQP4OUFRFp1EVK7z0kFJw( z;bUF+g^(ILig*u7LRw;8&WV{&894Qi77Aw3u>iJ-8-sLVXnN-e^1_yU8Y7=L0bDW= zuKYSB39uyi)X?-!S|J2qw8Dw$oxe;<@=zkl%`Ay+JPGYNAUz|zF}?FENl7*W$ESv= zYbLbc_x^pD^?neDFY`=IGa8Y56|VSQfMW3otArO5T#8rxQ^g zL==*DIxQm68Jj8>3x#HqIH|M(HjND=ZyQ-`$)-UqSXLfuVGg_d05y7P42J%jhDpJT!$YZ8cV!`r**_&|k3WvwKM~ zeg6`9ER$v1U`d8;J8Y&{%&5$)q?ATz20? zlU$lG&Y&v7!8m+1avpu2jm#CWs?}uC!q;-}ZVJLK?fy8Zq##svS7{ceSs3sACh<@P z!xfpPvbrwqE(UX?PbFgRNIMO2M)rl(Q>B>})duFwV>8{z3k!*V?|ufVY}&K&OE5R2 z&j_;VF0!XuYtL%x(qe|9%;F$VOS(;z<=BgO*^ES%*qS{ylXkJajO{V>6U0e-*k-&u zF!mzL8fQg`DKA6pi0v~P)P17GbH2tCdx8HW-<4Q%ya9gR;a$kLROECs_+!|Xgg zcBmdK#;^(ns2s)Na2%VOwrHr8)pS;|w025GPKuw1co8Zn>x787Y>8FojO3hcf8xF9 zD*v_piEKZofqMUBqgf-RXN%>NmA$%&cc#*p*kAvjk3s(|%Ib0#c1!bEC4r=5(f<`E zS@%d)OOLX$tsM#~G(+7=-}uFmT`U)-ed8C)h4ej)hM~_QehSgMkS8O0`le2xw5#$? z^fEIR(Sl9>ke=ex01PXFmreYz1ycr4p3wXKEF-MhQO9vb-OyWjPO;~)GYRYqH~0~p zuIWQBBSPKK(<~Y3E)wXjo4cB5%NJ8DW3!HsKAE+b-TT;mAG`On`vG=8#O{aL{V2OP zviov&U%~EPc5h|(0K13TJ;v_s?7o5BJJ`LG-8ZxQ7Ixpp?%UaY2fOcN_a1h?pWSz} z`yO`hmHeSCgo}%y+2fPn-hbjwbPb2cX7#`q@<1p4HPa5^o{Nt{L*CE)5l4sX&is)X zF>}s%3ua6qb7sz&KTdgJS=xdBjgG3BI13lMiGBzk`*@F!U}NrE(~GhSp4zX3UApm9 z*6+lE#+HqPceQLBxhwVpi_C94KK#4>-(jl$3IT*Tpyb?in?5cHj#DXp)32(9J%&T_kmg5 zFpeo5icIZ(eChUXt}Clx|4p>kwuw7=0_7E{hR5(jSm58-%tkydWvAXm|AVU`0Tab`>t@kUUP{*b)*;NSa54s&&<^{t7tx^qeDcDB<#gbYyH7;Et0&(MVYz7a z)k8O4fR#R5>nO_DI*i-FYzn7{LsJp7bSXyvY?#%0ilPkRHgu9o)n%fHhTkv65w>^^ zUNh5(7uv3J!#9@SO3u&)6cI1F7+ZCgjK#4(h`h&G(bVi$wh&r*Ku z`1+WMs-fFt#XHAd1OsT2Lc{kl6IBfcF$3M@xn1R&uG?}pp3D+%%Z=1*6u8*iV>6ed z2(~G)6JrKSI3js;O&P9EL-c(?cq;QY@^a&C6b}dY3m^`B19p5<&)PuS#+neHWr?b~fPBWV!IfS$ zC02AuQyCVztmMt^2%(=LLIahJa$sR>JYuPeuggG~zhO_fa z*@Xy$O=ed=`Un zw#IaA8bFf!v{aLujse97MZ$lz4zOL+e_&kHYJ@xV3yQvf^^DeG60I*yrgo6pK#tQA zZZ2zsooE0{PkLA94DFy~R6UC1LqwDY)KxyXwS3UMwfwl7D#Jv&Z|p_b9gzm3^se$_ zWAWo-FEWWAiw^>$hL>8;$A&6F3WhF2pJD{EDnxEWwcrW+=G?&23M`9^E$Qn6;g8Y{ zYe>SA(dq1~Hj}Zf?_ieje&kI|2PjrQ#iH8>#*(`!_NMOYoWAN?=^)3X7-rOXQHeO^ z@w=_=a?DcyYIy#UY0xk&wu-#z+n?xuB4x*%lpZa;LY#7F`okqS{W$&MJMg`shOK2e z*sL47vimdm^n9-HZselw#+)g?6W)tVox8EWPCVjelMIt z$nHuby#AQIySU)-p{vgv**G{!u8HpIVQ&}Ags5l`)%_M-PbN(&%pyr~;9J7zVI=u(y=5<0Ok=j8 z$M7PcA{~U`M7z!MWUA$?3?4mPAc2TQ6>07e3d<1Qd zLrJ>hqlP%Ti7YDBFm%4`<}w%5A)bcfm7g}04;zMIO}+5Zg~<7&X4BhooMFHC()sj@ zr2D%s3ij_jY#Q!0sLFz8QDontJ_DIPmB@_?SE3D}c`d zS^-r6Eg&E8{@*z6RlqZVp8>W5J_`r}ZU>^0G|Zh0GJDK16BY6fI9)30pA4l0*(Uy05}CW4R{}L1auq% zJPP;;;5&dFfG+~-@t#4rbcInq;-wW}0AQ@pVFAE=&|w4+U#9^s0l5zl(w7x1R z#`sxY-XGT%c0cj|poheQ5g48=jlHH)jN(Ajv_#ADGle3@r`z`v?B#@GAX&_)vebusYA6Y(nk4ZdiM zcYB)sE&gUcEwHq;uAX?q;*>=Fp0r%u3(~_=GiaE@m&YR^R7xr}IWgr#Q7EeUwM{2}?_fF#c8_gmPjs$}hGI<(i)R(~+PP?BHj3lwFi^abhs zOAk*?jrYidMTr>`+uwxnvG_njtitTrAH@_fJu9vxX=0Mj$mFo} zJa1iGwHV^V!P?6$EnmR;JGiU@mzJP&BL5QEzeMtHz}UNi3Wcj-9`N$|GJ1l`HK5CE zC?Sx;<+KeYQeV1caXq)B3K4L@Ws#O3-Qrsbq%@0{0$(cQ^`#t=aEs+Ma9P0OQp}Se zL-n;3ih0dK;MD+-T7L@wbk&zsu&_GBt&{1glj*3%JKcDXTYirlzo_X(&hCXZERDNb zdcV6`qT7vp-N?>effwO&g9q;NdI>MDXOZ#DxeW$!VO14U`laf`G}5whnrtn#nR13+2^Ai^OZ49 z2?BA=FOkCMf!uk-I9&6Pex8&qHxG3_j|jj;Ny|Z7xlCKR%pbU1xtwn~=q*RF%4NBL z%MzEBN%B-yBGpN0BlHwPNjvA zQd$1yLUiUL-?`w?TzM=xx3+|vi}%c3DAm_olyxrB&tyQ*UQ#2~9bCyD>@1Pxv!qJmEnF!~=4A<0Cax0HMTuMvxKbPhm7qKx8C zD*1bT&0H|FmJ2njjFVC`ksAgwgu8g@zU zAagr9=fFfvS4}ZwV^;Glt=_8ud{g{bJo(1&DF((j^-P|NB^s>myh8bO6z!cW<(K!j zVp>O~{1ww@i-lTR&Xzx{oFJQwsR_D6LCnWLh!mX;WGCW!VVOBg zOdaKEKujgi^*&5e$0IgNCgYVpKImKJiTT%(y)p)~B|56MFdu@swj~f+hl-h7%9T|w z<(5{LK|d_y@W{cQ+e|d@U@&v3Lg*R9Nd6(opI!oS>QLQB2n>F}#JL*Nb5=tkyx$7xjmNe2d2)V2PA+vIw%dTTa8QwJ7>O zO_zuyr=1mD77j)2v%I&#(hZs_WwUoI9&QT8+m<0#XEMAR(r^;8V5 zKC<2)Ttzjp$_G<2S;}X{`Ps9gvy<)G5nn7G3HrPgmYT=n;F@4)9ZdMiHg=faVZBaz z7g}5h_G-*H!x0!bBFHHk_K|TJHtL|K&1Yw?1U+s{Cdrab8O#d9YEQOq-nW)){@@#y zZIa@QO9(S^D{1Zgtf&+ZwGfn^+-HBUR8sjZkgFJ5lwj|mv>!}GbEpl5GS)17?Y?Ge z!)eqIoh*+D{>^P(Dt%f4K7_@IAn$7n$JX<(W}{j_M;$|`eyH|Wfn5_NtIZQ2i2zfX z*$CoxDJ_?6!X`DL0E&Qt)oN>dLFi zOY3>Rx4npu%?UxGOX`RYU`4z~@xY1<^N7tsP{0=~;tP46N1t5IH&m3@@UvEiLIJ*> zPzsPUW$QRiu~3s#%Lt%Ao-e7bEm_Ji={b>LJi{1!6XT|XpY5G3EMvOOE}Bh`2nNN3je8(|TgaQ_=LwftPnkgh~(NDV2mQ z$5@OKB^AiQqr_Av;}_UnTaJv$7r|+v;4OH-a)4swo#=*>FAA(#ST9BJN4;2^3ZpfR zUkhu?%4_+#OUJW7*!AE8Ph7a3XB;OTM7+M9LHO*L8(hX8)%9)xBA*VbDF?*UwfFX>S4*T zkO}v)+vG~So)7X><@4&L8e(tx@UmvrMP;Ol2uekeYJdt`S;u(IxFv^4l}9B{3tU`N ziJC6~UvZs_J>N{UG=l;3epwde*ODfIXpa-h*xIgyCPcFt ztgfo8uB_*E6vm|Re_g5y^#2-cs z_W^>Eh%E_^A}6Fe#%qi+O4Oc`5ql%kds4qatpa}1YCfN+KWGE=I}Mff6^b&5LNP$- zWYPZDg-vPd*B8l!$~+^;Z`eZ%aOXtO*`@#bA`GI~AQ8s4X9i&ndulTCaJYV z>CYxaQpHWsIK154CMcsMRWz<^NOLnSp03_ML?y(;Na6nn>xqA+B@!~0q9gu04e=o` zHqkcE+A^<~8L1Ak)IksK7>I(bXnbWeRw1I;mzFX; z<07zOMPNaZ^FX|tq=@4a%Q;dUX+kLLaA}^N*!qTr|7Z-7L1qfM7~?tlX%1H{&tv_; zR;;DQFpu%^*l~t=BIuj#n620dV$ESL?hSLa+s|w=8B9pKd|kBFA2yS#Z!+k)7OaC zME)RcT0> zu?wUi8(G$vb%oyTo-ggTgn_{u4+pU7JkgRN#h5KkF%k@yrQz&mi-ax86IlhCgE2cy z8f~$;@s=vgIon8}k>2Ux$xx`!FfNcx%;bHbl0ooa*{mtc6frKL322%tO+9H_XzET= zsa#V2|H_6=SuPV&c-9S=C{Lvq1(s}ER6W=NDw%(0d71GH20LiAghiN{LD@dl**DCV z&0?s{mVjrKBHLgU3?W{AogYImHg1ff6*K84YaC@rb-9?fe8S#|D)jQ+P<&;;$KMeT zp+ZxmDt5vae+2c=-0F#VVAjMdAsEJoGm%&sF zz37|6)g{cLQgf3zo5WCNAY|{P(@t~>iXJMM&$->`3`8%Ei%d#Njw3N=z39*w1ssuG z<@td}qVZo=n}CeJ=eX6q0eSx zQ+{(8D?u+12D>T8T{ERA5W<*-tk`BFPGC%FYFi^e+>zBJV@I=LAjQFwyRxzNg#G-1 z>}H=Id5>g61va;ZIqrv(nwnyF(g1Qz2YSHbygkoZrf(5emn>mJRI` zKq0sT*)#|M!oA1d8D8H6`~8}18nTgZHsuxs1K>Sfq5x~E!`aa=205`7_`bu^d0?^P zxEzWRX$Ik^v!hXHO^U!xlhR?}a^(dmKxmyW!u?%-8^`@;R@2&OFp(Yi9Y!^D9_Pp+ zyEg_K+;hbHHmu`u4a^UP0ps@|CQddWx9YkjrL{V(R;oQC>VuKr)EtR%SAa*%Hcg9L zsNCMkP5z)iMjaIQ;5gpo<9<1*$suLL zh4q!DR;*IM{*QRg0iP$xjM~V%CDg>Mgg}uh=s}Hb&1#AV!Ou0^GQ@_6p_b_-*D^_3 z!#y>nN%px0)V4SK!m%d#7>cop7Lc%jvU1Wq)LoT-WduuyT>0erzL+}_YA%sRj~pjX zsS0_#ayV9-LlmQKJqGh_Wqu4uFq~aq!o9(jGiJD@V;|hFxH62hy*}mn)Z|K{nrQWT z%iGcAV>z1pNmgCJhc)#R$)TmN$#^2ZL?o_1t6u5#i8737p;RYqC1ya%sr4*=Zk%C@RZ7EnaqClqfv}NxGea|Ifo+id>*Vn`joIgaAjx$7~Ryj zQg%$i;XWq>L&d%a14d z%I}Bw`f;w;qdAvEQ7|82+=BAjn(`_|!=!dKHSe{sJy10x_`)=Tu9hM149>R!H1O}; zg?$4!#MZwEE&+BbgaPgafO&|s9DUji@ZXLzUVvd7KpXrz;vjsu8ZP{Ls}OG?03XKF zd;@3dpe1@ymSN=UhMa2fJczt|0L7)icf&2i4{G53s{!i(cL6p7b^vw(egOCh;8DO~ z!0!OB15N|R0Mp(@c>qNK2Ve={Hh>RsC!ib91Ly@j4R`@?4De^b-vGps$=nn!i_7LN z;4b8HxQj6Vna1UE7ju_z(=kZ6l=~QW88?HQ$$gx=oXg{`;6A}!$>nobai8P@{+06L zCesb>MbuOyG48>fTV!`FA*+0`ayp7Nk5?e3#t_!(#p0>A7aF)7HXLd08LQ6KC&F}zQ}1-0G0z90rdbkpbAg{C<7D& zM1U2b1?>JeNpBVc@5ir=kPa;X-us9&XW)S!`HkeCNB-ZG;%k8SY>`-<3%mmQl&&n` z9bb~-kN$?!gzuK}IZZeY22=j0fUl@$(YfQmNe7evAn;!g!cpA_E{-@AMg&066xv%PA=uY8~E^>Qv4p^%6oSLSKhlFIG-=Y-v(Tv za|>`K&(0*g1GqxN2H*;9G2nx*Nqh(=`3Hb&E|KzY1+L`30=QBajlg$oBC4@>2)OcI zH*l&KDoX`$h0ZeIlqX$clD`o+KK#PUUIe`Ar&63k;0ix^;7a}GlfTT*Jm889%mChl zACIBb8sJoqbmb)B9L164VdUsIox{MDw5Nb;(a+K~1YD7~LD`?mbqqL_i>{+d{)d5+ zAH_KYT&c$cz!f_8QT$4YKYhT98zh>0fh%R)16(QN{lF<7%CiSJ)fc^E2XKYvZNL>7 z-VB`NgyMGsSIW`>T&eeV;0kYJz$rhv!sIXWHUM0y(^lXsqSAZ4z!l!EAb+`yGy+#- z+YMYvTLs*zlk%?suJEl`j!z+C5^e=fbwu=Qfm8m37XhcXKvw~9YU6a}1E+UUoEg9s z+BCq49=dYm_!Nf&PBKi_$P450FbsU~faHG)xKgg;z=>Cs_84&Gy+?t!;wzVw;&4*@ zL%^wCD1JY1MgI2zSLASL$Um@PT6zot?lBJtL*v09?_5G2jXx!oZKYDM#2_lH#`lcl)HY zD}XEduo1XYmii>T3b>Mg8E_^4V&FtS@l6D-v=<|ACC?(@N}h$l6`t^N9HK2BxKhSE z;7Zvwz!hDWL-A$(%mG*Gbo60H->ldT9r)&>RD<@F4(P>2tln71~zF{zOwFaHXBPfh#mu09V>< z8E~bI6a!c27lA9~GRkp?9xZSspF-dY{RO}k`tyMkJrsWiaHURjWq-;y3%F9o(dWj? zI0Br)=^9SL>G=Tk$Wi!_+Xt7%7dzpOqL1l>OJj@x+(US7gj){~<>vypG-k<_pHCl= zo{z!Zjra%P_QKr*m-@9Wa1TLF18`dbRe&-;A)piQ*T5ycKk}>;e?WHoWVZ({^~;;( z=T`Z-LVhlkpL5`DL%dVZAb+@r;a0%iBR_AEp964@fu1V3q#ujm5}kQ)={;F+M}Lhl zz$wsm7%uUtS9Z6HT-*&p*aO%N*bL|ZtN;uk zUYYC`!lio9$nMB5CB6>ACB7bl%j8aWcfb`9A73NabN~W?KIGR3*9{N>6rYDna+d{{ z_&jt#;`?E^Uc~Q(OFC~mT%xmGc9+8~gTF{F-d_Nh_>l`Y5BZ$lkM;mK3OEet1&~hK z0hjbt2VBxE<4fT5bPg9S<()&a2b@fM4BGodh98fuMHV#aNXU4jEWjIq+ zjZfN+jeQKd`W;nQpRJlyKa~S22R`B)fNIQKS0|m}K38^vjO%s8s1Rym+@;C$l11t`pip{tDO|Ei4<-mEwfeTTV4?|bW$BNFGGdV~(1297NYUpYH3#zU@XJ)DiRSu{eIPW+> zIx=HjjZc1f*w?Agojo+J-Uma-KWJPHJ+0ZS>gsdnrkYaafXadMjRW*sDj$xn&TM2& zea0`KtKWyN9)zAQ?oxI2`6g>>c~lOl95{Cl&^K!{*46T7ZO@$we3J^-{V<+Civf1{ z%Q#c{6;)Sf!cR4=$^n%F=NAX2p*R`qYW53Inel~m^`*$-1jg0wpFmdw$S<>8)zm5n zR1T;dI6pX$i(+J~tJ%*%X2uWNTipm7$h*+hTrKuj*Q>fZGmfgMRSu{eIG;FhF$$Bh zt`0Qw4xC>cpifa}tgBas+B4+}j|`SU zSC7iNx?_o|t25=PnqK9A%7OET1JhBIjCFOhKY|~J$%rX=Nc{|S^|OF}8do={x;i6< zs)phAdT+s~k`{a2|1hzL%7-u5R{wGyT0q($)9C2GR{6T|KDk>hnm-)S{>y zP&tq(2k4v88SCmcPqW9HnYyNLvpO)Y)?i#c3_b1MsE(^Mty?v{$^n%F=MM)yj-q6& zt7HDQ%y#T?9NDV{=;?n4thf&QK?b_fWGhlq3G(^of(lrXWid| zo_+_=0bPAW)zumCQ%$ULK;^*s#Q{2llCiG#dSaQ5tD&MfJ8t&^dZ4R^Rb73437T3O zl>;gVGU5RJc6i3RnrtA^n5Qj#?xc_nFOTn>H7d3(AC4Lu0G#HO)Zbg0hI$8aNtU$%~)6Ccg%f}wVpr*bkJG% z??6xQ0%$&t-|%v(h^>@rO<))fm z<$%h8^Nj;np+Fhy>Ucb3WliJi&*MjGz5rMe#h$&eI<7w7WKAuP$^n%F=gxsoB5B6D zI^t^%MKT*&)49c`$Y_mg+fGi?bFZqaC2pv9l>;gVR1R?5)nG#Sjtsx%5shVf#GL&$ zu2LTz4{|ijPVrO1R9EGI$^n%FA4LxED0IfUIv5XRvaU#cr*Sp8bn*Dk9=XYW^sHVg z2UHHI9Qdem;2IP>V;e}&lkpjI(#!PCzmxbTNH50Kg8)@me^jMXEw{=6l>_M<7_TV`YuRnn?WD@Q*uNVLP!7CmsOAaBuN>{Rz=#7(QuQXxeQ$U^;60v+0a!!2CD!#g^||uC$u0KehkX{)+uV z;S+*Us1!WHT49&)pzw(Bs_-{qx>z7O#9FaS{IYmZ{G<4eIL*O3oQ|cAxa0GVuRC@- z9&$YI_=Dqw;|k|&=grP0=QiiJoZoZ)+WDUI6Rz7_Vb>Pdw_X3?dd&4}*9q6(Tp*6; zxC3xzYQLfVvG!r@DeV;9RXV+Hq0Xy&K=)JK&vnDP3-#CN&H6fhtNua#Bl@@X(+s@9 zWVpo;GHf+`-|#cT(}rV)Hw+gTXBg)jR~t7NHygiee8Tv&@wjoj=_S)YOc$E3GtV{u z$~@C@qs3v_Vkxoym$k)qukDYv5!-b8b#{ln-hQwBA^V^0Z`&se9}^Y|?Lvp}fS?nt zVwt!=Y!Gi3|3mzZIK@$la_)8vJI*+~&Tlw>?);VW$F8F;PRnt9D8tR#UuZwB`+;si zr_mqKKd(OpT1WNShU*OFhM3{ghHn`93`Y&WH@s`eGe(UM821=|WjtXVGhSf2&Qxw% zW?E_bJnG~n)2GZoGUr;}w`{XMX!Y8@WgD|u>^1h7{c52NbbU?OD+~!u;#b92#48w>z?x*fWo=$_CW)1A^y(O;&&K`-i;>D%<1^bhF&pg*C%#&DCN%1~!$G~8xbX;@_l z8168vMaer1n+*3DzGQgVkY!wKe9ZWokuzOoDnV&~X&N+LX4aaGW~*5=7n{q>4dz|u zr_F=r>nz2VA6frm6>ZCHdu)BSCVQ8?&wku~27GV`pB7#az9{}&%t7gY?Rd{o>wL|5 zrE8VzHIgYe_AvOI(XxYh9aNXIzwdJMy2V zy-L8EUT$-$_(yi2eLAO|chrUn$nBHQz)o{0A2vT{IvDEmm@nz$y#;GQgsm1g~ z(|1jenqD@2()?Ak$8y~AwDoQ465DTWm)qysgZ68MsL&#Ih~E;Q5C_CA$2T4S;ke8B zS7*KJ0T&nMxZQYfwzgQiN*hFL`MdTR-CVgkHN=b`+N3%!Y_qENYg)r3&hJH?Q6wt;`hY2 z#mgLDaD2^iuj9LT`$LXL9Zx!b>zL%c%z2Yj?<{jJb*^x(adtYt>-?ef5$EHOyJ6=$ zPK_(irE?X#R=BthtWPrj6lj~ZPiv29vvsp|b9I|^uj<~?{aF7w!>fi9hT9%X=1=b)9vy^+(octRdUOwp#lt;Vxmba8h_v zcvqM#P7`N}g1BD%y0}+7CeCv-I{au0I~;#@n9wd?L!Djfy4qDs@&IB$5_d#5P2a5V z)<2`S8QKlqXo)8cSEC(1ZhY71F|9Q{Z+hGGzGyAoihjYN0?=raR zTz9&5(EEEhZaW-}_Ezopv^~0C=w1RJuG6nYt2v{eYREHmLO1-(aMQt-;n}TW7o5_BGo~dzt-f_WSL6p2^k(pK*TG*$a-0I?b*cwEw>oO}!k~ijF@|+o0{#UZ9(S zHeRlquHUb}0-E*nhAoD#7awn~ z2CY$RyY(*X7VEdIKeHaRz5>29*}i9c#r7xLN!y#YGq!)&vh36BAG2R!=k2rYbL?ij z(>~8$YhPwxVQ;aA?d$EG_HFjB+8?n0z}^duf7t$l{bl>B_BZS!_9?b?4~ zeuI9qe!IR0qlG^7WJmPJ^h5g7dd`pwSuHSV4WgmKP;XcP{oW4Q-DcQn*lpNr=!XOk z7>*l;4Wot}^v1lg$Y?c|8QqYDR%6WAVccTeVZ7hiYusl%WISpdG@de!7_&?oQ@*Lt zWHc3cbf2i0PPV$aLDonRCr~<^uEfwk68z;$E`!w zQ`TYYY3qn})XLeiY&o`Eo5nW7mS@Yi@wNh6p{>ZKwHa+zn`kSBzOArT+1$2zTO<0h z6*e#QZ@?C|#cb`i4Ym$jr){%si*1{2yKRSUr>)0!zil^qyI$K~^mzMh{k8+PL$<@V zBhWYlwqv$I+i}~F?UZfUb{b=sQ5!xBV$ZSX+BNnW_B?w&q`tsjXfLvB?MA!RF4~Ks zD=O?&b~i>ijrQee1zvlrJ%E-Fv$xwf*gMc3HruzLO>DRCu^a%G0yM;YM zFUB~1!akv2I3OGn4hu(wqrw2%;-GLGz11mUSU4?=2%`cgW{EjsuBZ`bhV70`=rv0iKxmy0Vzuh=RE#IP6>+rzj#1ABpw!zh)2;I9}@?~yatkuK8(#cUh?yzB~WecbM<4~IEl6UR#U)4{NswHIQ`lK z+JHH1rV?>($?pJKY#1_}kMTCQLh?JLKdg^IBl6AyCl{9d4jYabNU{oCh3JQ+{Ewim zQC)M}q&S7zBJEMrfQh)z^+DS_5URY{vX2NmAn7| literal 0 HcmV?d00001 diff --git a/bin/win32/libpqtypes.lib b/bin/win32/libpqtypes.lib new file mode 100644 index 0000000000000000000000000000000000000000..5b0f17ea9f5cc5413479014ef504edcf8923fb06 GIT binary patch literal 303594 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

=N-o-;LhlD*0ylRNmkzG|~ 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 UQti*8RZ0r^j51Tdzm)_35B$qFegFUf literal 0 HcmV?d00001 diff --git a/bin/win64/libpqtypes.lib b/bin/win64/libpqtypes.lib new file mode 100644 index 0000000000000000000000000000000000000000..987823fe8cc2af5710957ce8756e24bc68002f8b GIT binary patch literal 397814 zcmeEv3w#_`b@!|#JMsg|Aus1e)`>zK0*NhY9Xk%u%+Ad2%hEnQXsU@*Y7K|KwBudK-=Kpya|s$+b<*yO$w!PO=yxraDdj||J-}$ zxvQ0ve0=n4b@kiPojd28`#SgBb6@AKxUx_k*>TmP%i>|Ty1%b??dsmX%X`D&tHdk5 ztV%HdwndUOuPRBOo8@TLBJxl!tz`^}ZX z91qO#z#I?E@xcEj9+?09N2M8l0|Q%CdF!gAE@yM5rKc=M&ev-LiOSeOVxl-vsqPs_ z6sy%rb)ZL4WXT0LWIdToTehLfm3nQGFeWRda;;b$NR*}q61h#56~a(;Ib-Th%CZ%C zuvRUVw+|$06#xTgJ7JAf%DalysZympkQghJWNGr|+ScvG+ScJcwPL}0s}*_J$Hps#S~v)~5&@O*$}PpJTW)=J-mx`RRpp+69yK)@DxzdsHmszjtBN5z zX|+;DNsJWAO4th8dDDmCy(o_x1 zB+}#~r(`FmC-Ye=E9a0up7PN`t>EK~fnyU+8eD~}6?{}v)^e7e%;YS2Qz*TomHM!k zUN26!9D)Q=I%+YM%gKXCZfUGUWsT@23MhLp4r6Vv-aJGtCFhcvq@L7JYvo;q@e&GY ztW=!>*2s=RwJ^dO4@-AxwCER=2DV7&^GLNRoA^)@QKH@PW?C(jw^PkAhH`6dpwExl zkn?#nnbWn5JQS_u(MoZuJg}CMUZ0$-RN-N*xiabFXXUJBsCqW3M(RqWq+FOl{4KJa zlg*@+&!-GWW_6gQ;+$fo#tLn`04d<%fku6*IO@f#n{qC%={YB_w2OD5PDMCe+%8Mb zhLQ1Np-S~Kg%^rRFc)w0^pOJD+h~1~{8Q{@tXeGkZxA~k7+7KVoFWi`d7`$f}xA^4Y8^^Cq{WP#ztpn)G6eX23_bV^FsS<{B@JKoW-e8}kh!acUZk%1mXIEaU>o==#VGG`)~03^p&nIje@8 z%4YLPHA5mSB)q-)AlX9Vh;f4-XI4(;m6WAW$Ki^gLUntc^&5RiL~Wv$tdChm$V@aV z4^d0Xx@ubKypweKW?-!ld1%p1MU<$3S)C261XXHu-V3pr_X06rE4pu5ebV)AEKU^} zR2@|dGWFUnUd8Y+nr6%r97>b-KJ^y(26FPx}&@xff8f(?7qwxOs_DkXDy6IAm0QjQM!oi*gz$YiK= z`|_$~rL(#r*GI!&5>{GECv7J!uSq2O&>01k#>*|oak4gb2EDgT^=|F!4S&vOZ8hs4 zCHT6dG`S}96@8DIOsP35pJ7SeJHep?L7FG>C1>cG7f|43JSZgitDvRYEDW(PQW%xxb@DoCU~()4JO$C4h&~7u3U`6i#ab)a zU@!-*Zm*@sE5lHhTgEFAqK;R}MM=B_BXq+8gxw&kxVLeVrPO3zhlCsG4}IvhOx?=cxr~f)SCHZRvQ{3# zGoO`_`|y{1##S6XoxzwRJSyy0O*?Jdc3Nf{Pmo-{t=mc_4Gokji@{F`HIvqpX^0>; z(hJ3vFm*%8J2}?mn}{Z?d@7Z;G4!AYOM*0nye4VtNi&m|hbO5h!{0PB1L>CMl&1*a zeFP-dnrt?mHx12k)w^K2FV`|TRn;>pl@PQ-;0I7IN2*hrrI_+AT5yR(zs@l;ifR~H zSwj~%SlfeTExcxC%QKPj_5VqQ+BZAY<Kfk zg;7D)bTF5bLuG*lEl?XXUhJ=hKRvi(u2xzgjKq@oPOuBS^r= zIaVr}GCcw#G-Z--Hn_zBos=~bXuTd@3hHp)w)2{;Cgm;WkO6+4VkLlDRtC{tP2@E( zsAEoNh_zqjBDE2t3s-?n8)-Rdrff6qWMvnwG`gD#sW#BhT000)e#wu}0zy4>OU_zK zMo(oeIlxq`5s9Jj5D6ye&?TrAuHVg)>W&r(zzyX23M~J+m0PAJ#jG608B-V$V=j!ov2l8hC5~Rv{|dPvhT}Ka$_#D{>Q3kjn0{=c zMw%7-j#u$H@;bZ+-KswjOktu7^1zTW6-EOWnr&hemL7+Y?53nppFCXI?fFMaRV3DX z9iJ+0_g*FowH^Ko&3^{o#`kQm@JvuA?UE#afF!+oBTH$9kB+OQkUHXFGtjNkC)0W+V_EXZ#3)U)Gyz)>uq5QrfQu9UOcbU~Qb|Ken;3V8XAOfx<)HLI zDR>c+oP$u;l%(wse{1zg8fb9|!DeL9IrL*vZ+tWq?orVdSxf1uWFB)UL)AUrL^hMg z#L>J4Fm=PGy!ccqpG@&+SaMpoQ--N}H3y+AbdZ1!k&`i6N~4Ga6%+<^Hc)ZXAesJS zlPH=(9%L zmY0|FDJNs+bSR!&#Y$P2li*`F%zjfxJg|=PPT6LO*J-gKMdi=m+2R9>7F{?#v4}{R zus1$0fawCR#;|&ua${fZ5IyVKK{eUX!D_=AO6<&>IF%bSKmANrEX zl%l4gFxhtV7Zp?4x_nbTJjV{4oMKoYmTRJ>YUyk$DchT)#PnRo*0M>tFd5cY`;usF zijmUg++Y;PNLp4#$;mmV>5GP=rVQ14YswvFhQtZ8dDX2)~aM!#SV8I#D4 zY-`akj;$LYj@dk;==3 z`u0fLjC?+ArW|>T5~YR(AIzTX@=&z4A&K-{Qp1;M+B8K=r%cn7jc9&AOUb8mkloSR z21ZWDc*Blzn}#7?PJtGE6Xa=7!|uZuJL%|9UYepYZCh8?DYR@QT0N<}j^QulL^7Julw(?! z2_-if%?`RU)rP_$r>}`504*n_lb}vF;b4MS)2XO8D&ZnXXEn`00m-9KAVP&>U{x_= zpqEcarH%nDP=&&b$>B%}jJ%mO(MIfO0?@884$tbCJ&d53Nn1%}G1Y17;r^x1)KY0R zg)ftvOrleRM{v}}y?0@_nwRz;2+ zQWdvEY7T0kr5b42PBd*8f~vVRW_z2WF%=9^p@2F~Uogp|BHi*}v~aSvk~B3`!eCS& zW^?JJmcx3J6&0^mDsN)C1k)_hp4l?85R_12ohBUg*h*f@$(4~>xCqdbq7a}PIMK?s za+>0p8g%h!#aVd_S8Zq-PBhiFijk^1wB;HK1R>1V?z;q0i2ORvL9}4`#zffZEjX70U{Vh_=_4 z%cx1y%&GENaX5mMF*K8wD)nd?zn7iLbPO%4sgPG+$PU)UaA=;(8x3#-_GA*<2ab}S{087w&$6|at!Od2){RE;(g zC!flvvxY6J(ZX>sa!?c$jv6V@{$w(#XU!C5jg(0J^n*dthH7G<7*z%PlV&=N4ui3L zxD@)aEDDV)DQilkwEL3|3Wx-p9_^a?RV8hqKQp27MQQ?{FfPUt?=^a)g!(ZJpUtT@ zl$VW>9-tpX6%&%g2H!W)v#@of=OmA8W*%U zHIu>kb4yf#=-0BSTSwI}wG~ZF|#xS7Zncux{`&+&m!^7pA0M( zrm&8vTG6C(%Z; zO>vQWWP(GX?M0K3PN$)ag4Lh~M3Rv07?=Rhnfn?G!^vi76|4dVzb}OWKoLP@PW07$ck1!Bt2%xF`}S#i||MY z-_nMaHZADwO$o`RF}I9rxu&UsWmKr)q(=ZVQZ1QW63rYtm#$GFN_Bq*vOS09aP1~* zQ@Es{%P305G%$jSrXs5t>1-a0SxS>!!#aFkM{fl!Fv{83Cz4I3Fz84{wXpuIWkPRq zH0-g8%Dk+dRc>@28db|iH6kx^Mh$c!S29KP0iBAKuEQr|D~HsH>aUv!(Jj=iD<|D7>;IX zlNb^hO?wW!#0C$8O%<6l4U8QiU$YydRe}vQ=usdJohAX0gKh-I!Gv2=VdT@vBouh) z$YxaL(F$}ngMlQ5r;*ad>KW#UupqLzi8CB1_q1RP)jBGb9m`Tw9jXCVnIgl8ekTWw zPl1ebqAf3hjV>m(OecvABNdiN<}j$X(NfS?M!%`443uJw_%WFiDdL2R`3TIjVW6Q8 zHQ`}wkjkqVr7BSYkJGirb#n-X%anAqWKhrg>I%nbPsl-g#>N_qYMM108Gj#Q3WL7WF1{`AT7Yq zQKHbzjV!icQlHTL&2f|*R9$rAP2ci{lR`gFJy+8=$HbHlXhI-IzO7M{YRD%Z> zY{-J*4hBaTLJ=nhYghv+&>q+!Y&i&(Ghox16s9gQs7nte2NGIg&vs$*D;dVbAy?2UI8iS zKWb`KFV;80{{oW}Neq>tE`f2;ZDRv>`)q2mk+O4X2y;1Ax~bH@{4{L3#@5mtDx3qi z%P4>?HG}d_%50-ZtuTSL!wPmAV+-Rg;Y!5xZ7!A4vb2GnCAnRxXppi{G1E4*v}$3v zef}^m#e8B?hp->2?A(JrA??zv%UTA4KaUXmswmd=_IGbq9_~%mz)F~eI9-#3 z>{L+cA|sUm9Zs>1xrM*IIe=D712+pI?(I5+h4=nb&WzwEDhRc~ebV0Yg+m{LE zjndHbl5Snj0-e{f3Wqt$!NNpk))LGmP0Y_?hl=2;_UX>!sDYkAgUsPP3O0YVPYJq? zv_WHGZ>umhpw=abg+`1au+tX3<*i^@Y!7Ki95tTGW9Jj5J8kTl89{q!mvU4KrfSgT zU~qt@R>E?6d+LUbeJ2=|%R`0IWN{X8f}Kz%#w2N4ZxP__sYCb1G7O}lo0#@#M;+y$ zc;~#Vwx^D@CsV~KGOr-pQBTXNt*1>Ic{l|+s)M4L1s(@0GFX`8iJwg_r)9`lD5=my zH`cKe?gZfTBo%3uZcm|1Yf){h3bRg{qULo>!fmWziv?{wYgasg$1WFD#mtyqpe=9c zSK8+{ox(5)lkxI3g`M@<)Xv%H)5I(W8&E{B->*uoq&YnKV$zuJnv#IT2QnF@=Xk1to`gWTS9Pp)_kd#srOpZGY)B6f+N@eVQ;ekIf6% zAK(|$EC^VO%Q!&ra~;V>sFTJp*}>E@)^P*n+CB#CI!xJF#gR31{o~lXH(SkN?hIR> z&_VjV(LM$TQxlG3VTH7HHx{i3%%m8qk-|csjD4uZGWY|-iFR>dtpf|R*h;O)nPRm* zRTwYgEZr;^4koeb_+}MdpH(RDM5Atxp=B|6wy@-~1>5HndcBI>zwHYPx;G|s)I2t7 zY$;AbjpVYUeKfRkp2J91)+rig42OSakvBB+=wLGh`f`TjCarxubnG@q<8x1Sp$+3z zoIq@?zL+v*z_7{*6(AH#JAT9jw~5t$8=DJ*1<)SFPC-(k$XMmyQlb-a?Q>%1vowQ@ zC758vw8zP57%nSVJqR#N`()t|YQ{1$SOoByvOR`_;jV(2ju4N{f`WN`8+~gq^X)LO zjRVtaw2UkdDgy~BWY*u$f@5PwL&s=OEf5QDE>>xG`7Aj3G-ggQ6HoD+kRFAV6wR=4 z@E4oXaHJU3ID6NLwN^zpai#*tvj)+~PNX{oPKtJPqyzdLC9)j@WMl(tQ5dab!5*Mq zJneBz93{YFlo7^hUv5@XPo))Xk@3omBAf*Wo37CRs^KzdpEeBMvEqRZH=(j_kCQhu zDbiHJd@u`6R!L!egzXGLK4_O8oHx}K)yiU4nCjH;`es4GKnceS4SDl;VYIZXGF7WU zF>RMPtSr#(CKFp>loRHjtenB_eceI96>k|xTnk$fv-USIIFQ6CMVx4fMASZYc_nRQ zbr)M+Ld7r(5;iENa55@f4DE}~fpG$yYr=-DvF+Fxk8>}x>D*{K&=FOr#gSrY7ZKLv zZEUzigC(RfXnv!!mz^bRD%qT{(QH`$0 zqN|nlolr<|)@Qh0#nH0%>4U0|F&Y#`ZvZ%ZR|AQh%{f>$N3KFqwM$+OV|^2w3NhSdqA6{U zhpoCek&WKFsbt#W&~8 z5lazyNFfCiN^TB4ani05v7r^qYq=D1=;A5tP(Qe!eHO7F1&jI^hvPI#fMaGKM&zki zQ?fYX&=R$MtXTMmkVqrepxVX@wtYU)24M&Vvv}x4QLIj}Tq@(l+$^#ktDKmkwQ@KR z?-h_&u6(hq8cBpx|<+6Z!_x6|&B3c^z|65^3(jQ`Z ztV=mqt8i#bm&?16m}bc@PNE{!*e1xjj%a?{#EqqcBw{wQ*o4Zud@liRx7r>V11SSX zA;63?O-Z#&IbwIRSwqj$ffkRztH?Upw!$7dEO=_3nDGbLO`^s-6^2<-$IRlmdp@)* zgVrQ$13?ndUqTpsqNC8OeQfY0b}<-O4)w?NY#F@`x{r;X+O)C9Q1_9sfr?a_nIiXb zA>Gh*7-{Uf^kx*W3#>wuH#1;|kS%QRH?hOsL&o+jc7*T*ka4afXVCF051Fm(28K}BiRL3ult!wR88hx>8U2@SB@OI2n{mOI zpN1Q+;1u%Ewaf&Dur$**Rt#CQb1l&Hjg7So?_bp)LU7^xR~1Hj0~mhzSYq{B|AQC4 zy0^Ht-~TW}_&PtlzjwI5cf`f;!$(H?))ZEch$#H<(J}7$7cabbRc~QcV$4me8$KK@ z2lwbM_2=FpT({ME0klLHdYPgH@8*!&t)VdSN{4Vg`t%Z_PXQi%_r<3l3JDM-6ui2J zdTAu9dxc0MK3*g(Tiy$8?UHya~^`63Z1 zhAoiQI9F!V96L8Sh~&CQqZ36;s-g>ENx&iB;%*NU1N%H|+QAGYtY8$F9Ww#Uj0}`P zgEm1x4p0V0OJtbPM@AQn-Dw$2`nU=9kV6M)eOw&+cPpA@k-bsL^0!xS)x0;+yE;y8 z+oENXBvn5rNed23Qv7?8^xnRhBDRv4A?mlal5~crmqy^ zY*?J)i9xlC{ndSYHSq;uU4PdM`QqRG=OWZG!O~y2{9Q`z(j99m(V3tZOA7>Sb1igB zK{_s6loC(RiF1RGzwCrl*^V2+>E`W&w~!^FoKZTL;I9LJl(PlWGL&s6-WG^5pf8IM z+U=DIQ8)=wLh?~vZ$QQ?&R=Sk8$&}sd*2r*Im76FF-zkyNiKpqxKi%}8_L3J^3 zPr_dpds1yKhJPX67PG(3052?L_(X~Rd@3{12vhNSY9aEvRGN=e1^?!|9mlJ+HZ|jc z{5DqTUj1SHnQdClo#O9H&Yj}#n>)qdH+PDERUbB@%$?$&`4s<5wm;|2_s?v0cJAc= z)>VCTC;!_R&z!Rfu&VEuZWEy0Eew7C{R{@oWURTbjVXbdY`pf(85vmh-_^*#%+`C= zIr{^!Pba2J`}H~d1Abx5*&hh(_L#Fj5ZX7<`RniM@Z$G(kYh&zUB8 zRi+8r81aV%f&V&Y3))^N@Cz_%(B?vvS?(`L%-KVj$sR(xn;l-4t%MW17UH#ARA_gh z#F}>I7G}9^;`Lmu^UJuZ;&tBTGiQ5(-`aWNcYXkJ&Pqj-U6MH~6-`B=%l|X1RJ^L| zZpmukoKcI=*e*F|)M6$JMs(BboKcIJY(f3vjar=8WiRfI%U69%C=mXOS-FotWs$q^-d4Vs=Y0i`fH}euX;SxFwgp(=%gH3t7>e~|k z-&y~7wRapR=PZWISqz!87&2!uWX@v9YdvQLE75btMz*d(G0YhoamSFj&~eV#h`T=~ zX~}cOMgoQLnv9LS#_P7{tdz_&?L?QU&RHqJf!v{{DgR%Jl@eHOO_>=O^2HJ98arQ% zo8aqoK$ssEu2o?67$!(@4R>fLI%nUct-%jiRC#UoO@Nq#S+g|m$KZ#r#l6~ro1}*e zbSFFe8mbby;{xWY>AFF>Kb~KdPKUN9N-&CCh7G5g?x2QMlwYP*m9!1>LmDo=+*ICK zuG|7!DzJh|=iWz0kqu;EtT0g;hXD?Lh&__&*I|?8_1xQyGW-9~rVCPyYmZ?44Ojkd z5``@e`LCtYox*L|%qk16hc4AhxVyCUc(!qTQ zChk1J9X0YGB?mI7hW>;Mc5J5}CSrxhj}R-pI<7QH2YH#ELOV`vsB&z6L_^Ev-u8l!_`8qf^<^>X}N*5ezYms!WDJ6VNI2* zu(?C`uZ&jchJkVglC0V6M-UVD!oX%U#C8rjjmuDlXc_ z_31D>jHOQMrt4&?cQRDFu(nSHT`u5Kggze=wzjb;IEm}qe4)!@_WB#xT}@ zj72@k5k$llwkT*^zTui?nW_&DtQ&zneN^(~_N`#b!gyu-KtEN#kNBExy1*LD>oEm| zt29%V0y~pt8Ag;?T~@c($$rd0ALVqSmaLCiFff>ys89LH{r}X46f_>(D3HOOc=E`^ z=oFJ`UM)f+M!V-$e_*$3HB0h9Vmqlrewtwi5trYlO|msK zV{3P%IJJTug+LwWVKYm?C2=q{DslbgHoN@Zsqw-${RN@TbZTsBgvkB|DPc2G&sJ+fq=GHBjtq%y%|4CTFsCWvTB zaC(TiYZ*61;}V{v?Q?UjKDo7ApWxj+v%!>tiAD&!@zGFthzf4agh@JdfHSEKWM>ZP z7O5MCog*=|gf!qn6<8g`4Q=518^P`*j5Nz*-@7P&$3|*`)6QPDoGbjxk6;DR3&B|*#Rq4FtUouXMGbG*H<-g(GQGRnRy)- zL!wV%T~Cl11N|cF;09KC65G!;XryuFyM_A{O%SgMQ4O=cxEBkS;e_!$QRMh%f`=g^rvKn^;4nRYuca9$1Tn zc-=Z{uoYjb08LdhNPg}GAPv!{^F$57I#_peszW<*!X4Q3!n z0M`mwsU)tUatXkM9j+B{Hn_U-Mln7_^#$>=nxX31B(|x}ELS{s^${&OrriZF~JnfVTTb>Oe2pMrcHsX!jOFvoO#=Qi%^a>HpSWs1c@?83=O7B48p=LuIeVy0(MPpgn4;aB;oQX+&zG+;L{Fl z!3((3=x%CGwSoQ$_4yz~+)jRk77*&8W3F7s4Z|j`jue_@ABzUr3=WhmY|Kz_2MVt8 z3@AB42-ING#C^0FzoX=6%w8&wg|8}yY4;qIHYb}V5E2MYAh>zf$UBY=6SQNv-k~KK znmaUbSqf~odJ`Ni6McfF9R(ZZ^>^gE?q* zdo4X)87_uS+Iq3)9)a`ZAT`1Qvgx-q3r&uo7k<#V4&k>3Ve}Cg^utjvEHyRP?9}7R#d> z>c#3F_p28WM61^*$&kY=$*z=BUDbk$zzyW0FAy+TA67|^X9eX#xjA;$|DIa0;JuMX>A#dlgD+KN!~5o0ekFRi9ko#F_r9^$wcabuA_rb- zy}=hB3$sx{95i8!hdj{nsp59;Wuh=r0QdXvXu*5DH;hLxS;PyBQa4$s?eIRL6NY4T zOJ%Y$zGr)d7b$`AIV0~gjJx` zy?WKmUqm&F7hcWcC5RKKX8P(?Gra_>nZ0|}OmF4-IA;(3;@3I7dv(rUygKJ^ex1{M zpw8(Pvrk@edi75qy!v-v{Q3`tG+Q$!ZX*z{{_(=PX%-QBD=rM!sF}C=sq!S$H}s{1 ziWK3Zzv756%}lS8oZI0ohd$j>nB;{^Dc@SF@G1)jdF`xLfjATLYL^$|qRTF0CV;)i z>i)jowX1vkF7Ne%m}ixE?dx~Lw=J5gj$ALA-_)g*;hQ81AReN^^8$7is^i6Sf!;5h ziTdhQtJbVp6OZ@xuTF6K+ZK)f>N08QXJebjPm-i7VV{`XrRW4lYP*X3O_FYa=l!rd z9CEN`eCcR$xW2t-&<+0(JTFGzWNBIQQdZ|Klq6ja?{tSG9m0=X48Qm?XWONdG&jtG z*kcKvj{@fJ1swg8m#va7-5rMOLimpa3`2C`BJr+3_|E}%ZYPKG;*G%l8a`hHn9m6~ z`ZrVhp2o)`0&b@Ck=^H$=JPn+C(B1QoR2f`@r))oS&o+9n*nzz;D!Y3O!OR*iwhVAh)1h@5L|x~9P$y#Zx7&%7I5Ir%QQWuY_f)M zmF*ShQyaf@yfl3N2?g7Oo7Ig&5!k$?o#^&)-^{A?+9GX6>G71vL0pD6C; zPo`8{ukVH!Ef>b8u1Cxe8KmZ3zxvX|rM-pgrz-X8Nb!1Vh=Fz|T_Ih0vNSA7-+(<_ zNjm!@G4H?4?Dkj2YVnmDFOKIY(R53_1+Q8wXA!Qbyw|Mnhd?G_LQ#qt>$)If!pHjz81)O{4L3 z?Le}Nk%z0PGuLLsq6w7N67_?GmGNfbFA?kmF64$ z(mX!6>c}S$gIj*fW+=bz{rdp5PCd20+c+>ph5t30wo>|Rn(z+cZl@SL8HNd zMLihP=`Mmg1Lz#ft5ziB=!I4TB#p-38;ysx>5~Lq4taFJ^kv5MEnTQNRQ_6{G2SB+ z2N;Y44qt$D@QPdmA5~_jv;ogJ^WB6euhLuL<5l_*_|~znpTu)5^L-i51oM3h&wl26 z63;&7`!SxB;ZEs4@Z?|Nk>W9WaG*MqG1${m zaynu+;2CzoUUnWnb;PKj4ZC0uLDIV;Mv{Oi_B^#5E!fQ}ml70n9QL+@{Vjdzh*1wg z_@mc${dxzia&t%0j2wfJg1s+6bi}B%$UVO9fo>m*>XsaXk)T#VKj9%Ld&J&j<*3q_ zqc|5x!CX+6)e&2PC#C&oiFZ%A62}VY z8kBxN@6Ubk)2WlZyc0K)V=$q-FGOfZ%q^Rb{Yw6MAFIf4B-l;|4D%BQb4Pgx>(De% zASBo~E<$)mjI;rAk8C#|L*L9_q+b>P35JJ#UW9n1O3i~gDvfZdE=EX4jARp)>IZi} z@KwKj4kLuzVpcxndz>E3QJRCb!}uf?2NCiuE!=&+Pv<)VXGv2zv);$!v41MXwl49? z`3C}v_fSC|1N$P)tUrYB+izJv=wrnw8*mJUN|m&D;aHjj8VBnIJvv`q@%w0MZmFIj z=nxDKONkI(szlNWg#_!1c%UQJLqKr4+E3SJYVWGPd z9p^qz@T4fiW(%-h@`ppCWN)}h5%N!wq=~>t+IXm&AYDEoOAF2hn$H1`u<22nDN-=^ zG~%u~V8QuSZs>6~)XT-G5nOYeWVvG5g^=5hsS!46tJg~7Y{-Vu-)v*Dwf(Ebn2*L} z7qc;0<&Bc`TY?jUJp~0(KXDrg$)KBIO!n;v92=8`haOB`-W=7%rB#Q5t)8O#BzUn7 zxD_PY;HbsSG^Y4Vz#JBEBn4ZI-KbqZ3z#2A;R5m*AWY7j0-<*v2|l=X^xh7b4N9Dq3fF?(w*d2xQMd>_YSI58U??BtW*S2+Byk;Z^0MZ!APr;A z1>DC4EcLcC)yI>7`M!Xgsr*Pzby6Y&j-@Zq%hIRo@H-W76#+~1W{UR!VD1UPwc-Q% z{Fed-UglcGi;z#B=#gtxAJqTjT~z>>_LDSdB5xAi9Ky5QQS?@9r~Aw~LH)Q1DOPYBp{@qP&~UlDLK#Y=o}1Te2e z;ac$h84v;&kRX7Yi5``+0+>xvxEA!L0Q0UWT%;Wly^jFq(^0q<^u7+5r=oBXdQ`u! z2pD*oYsG&L;R`8!4^sibwd21R0P}MJH&eMR2aU5%W~97Ft9WT-(+jxy=o84bi}!7S zStsDy#k)noaEhF-{-4afOe4nZ>z{k^`q$St^TJhEd2llup3|Jh$fJ#yjQgIQfBZBm z8l!QHM!%;U2Uweaj>5!D#EsV-ZVc9F!h#0*vNb*0V_5Jx3`l%xJQsY^8qcs-z3+Lg z@x=a@yMOJEK~HZypf|p19N4nNYW#ioc^W22Z~D15eZDq*Z6~HqR%+`${z-tSk(%#x#q(YW*T=mwNVXV-L+!HJM$LyL7zCzlYa z2+ADL7A`TSlRpZC5g0I+nfvZ@%zcL(W8atK=J7|n_m>a@<@Jjsr&%Vf1~M!L^-oYC z^K+RUt#`W37d_lJz5OkXdGsf1}JlyV7U~(PU%8C z-^P4z!IOTSQXbEXnU9pDmCQGe=S9r78VU>zfI1}$KEm&m2I1pWu7;0OslnI7zV3zZ z0_J;<2X~hT_aXQ=m7VaBdgQvx;Ng=B+}DM7k_H`^@_=~$TdoBR2ypt!;iz=EkD$-T zuR}_MF41>gE80{luZ1?Hfatrf6>U<3K$~XCknTnIFO=qELWG=~eo8CHB+<-$B;0uV z;qf5J-zp9c8SCnlx_Ub&JGRYR)oP+8G84J??L;o7U>>XSq|tb#?ldx;`u;<;F3yHW z7x4enCp8xDf4O$1cuS*Ig(f2p&-kG+&j+23HIkjvN++MaBC$;>^L*(NJo)Su%{lS; zDa8xB)(eA&O+3?oa;@f_)*`$^icUzfYzqPPQ^+WuT$=y;3Ux`6gjv)@JkV&crnsEH zty^AOy6<7MTgom?yB;>C&tq@yY%28vDf~KF3(=X6W@dO8JWSc6|K!s6ajxb*;sS^( zO7bFHkcauxMZF6q!?m=k`(n&~nn+gzX@Aj8=C{zmdE$Afr5>jLy8Cef*;Kt(?q*vqbkYVvsfv;Md8xV;l3~5vqh? zyz@kJA0>J#3*+;Zn5!JZTqP=l<}2kvnzQdd`0WGgm##eXmW2mYDzo@?hwpf5Pr{hK zt!GvD!JoNu8%^hw#@CGoLK%>8oTQu7eGut)!w%CMqd;=@UHElMGM=|H-$p!14R+mL zcz9yDj}p6+g;7??oy-4$iX`pDk1tkmA4$V^vM}N@qV2l9@I>j}%)*#_tu0`HE^Uf+ zFZ)UqxsPNPr%g~q-*tQ8iPFA>g{_!BPn!R#XcJ9073ANGUz9daMQp)5X+iJ2Rm5GK zv8Z<9$`I9`)p!<+MS8|6>ym$BR~dJocLx!KVtw$O{_cZU8OI-#ulUE>b-bSE?>!tp zdM@ht%8F6lJP$e-4G@}X#RRECsIRA#&}T8$%E zsOi3AA81&Y{A>4lRAAR9z|$zPuZlw37AUkh3hf-N``~w##$#TwE%sg_<+g&#jlloK zgFwLrz*))l-0@UxzOn!L`aUW?Ccwr?cdGS3!MZ=L+@M^)HBfl}a03#{3+g8Lc;VgU zh27(Y!6VV&z;*A3hZi3AQQ`e23yUpZBrPAsZ)l;k9P(^=@2TH-;~|KLU)-`pV3LUj zA|0_#JjoTe|Fu7FExDl#CN$AZUpiu>RdvJniSK>}8OIBAXNmuvQXKkJa4~~=5r0De z(?5LbaHluXOcIM6g9%OOlf2*)&6JMvzy9Q2A4?$=I0h4n>m-EwaeaTyzCZP`u3c^ERz3;nzT+~3wF_=(Xq-S=-xCRH!YtM%RSijG3 z=t^n8gyN!kB0sLjmFKVb6hhPY{UU+Hz2OBInoa45HSi?<`~CHaywA_$g3eNjQW)fC;(fm^?z(5gQo1si zyIlf{!G!99dbjWbm5)Uu8FCDU`R)-R^uqJ?zd|9%*E$A>2jwE1FH(g&V$|zX+j-!_ zzYlrtqJLU=PL`tiBF)p!*WLeSb)D?x>&pU*!G!X4iiZV{bm3R8xzNXYQeZI{`Yips z2q8buR|o$`0ldE4>XIlI;e4Hnkd9atPpZoo?;LucpRZ+t&Z$lLqG07)&T%Z2aaeP~G*>KiTACyX?V;vJ%3?>v;JQUab__hHb>kX7>xHx{{9&H7MFzzLgXZIfZ zl#g}3z+y0=xXx!-ZoYonbML?SSeFYd1{2EH1q_S&M{vo5|nJj31QyoK}bi8)KiiG?@eDE^LgV|L8k}h5ti5&GAuV=m*z$$dpzEtt&ijw zOekM(MrcQj_>yWEwC62OS9XBPzo1FKgRcg zGCT1@>(f)T)s~+#qSq0BOTSnZPO$auU^w zGO$b?NF<%2sqvFJ3Jw8J;k-y`Vsb03Mw1qVT=I{28RI8s$;T9y5gagJ=zNpWt6cHs z@sNQdEOUDW99;cpB`);@(#=CSX1P|`F)mWOqgE;Nt>LurMBAX*p69@FeK{l&ON%JPr>*?JiF**o{VyV8aq~k1@Y0TvKqPKR zfVc>v0(7@`3k1$bULa@2NMMk&B9NS|yg&}Qit(Tq$Z19beeUz%0_k`$kBi9PU<0&qhEL<7K#lLEWs!^qy|`4CqHz-iYk9lT&$)v?^~f- zQ@j*q6)^9P!ZB{57`USj;P(LY$tYYTA4Km_z&sg+YeDZAU^+>Yhnp#V)a{)Qm@A@i zE$Cehn9(R)Bz>gzyc;kdh{Cm?_gTOkio!+cQN4Xfz`)B~t9q;B%l83y9gRWYh)rjz zw<2I}7I5v#<<|uaBZx<o#55rKO<;EtUD9H|%y8s`KY+xZfqm%#TMTES5d62N^J{`UdyS{enxwQIk3 z0p>#ju3fnt1kBf>a4q=i2Y@*ig^TbN@%`y|TuL4|FWwgPEWlhHg^SQ5KHVi?7(qN* z)f=^s+neA}Z;|q&)vNab?gs*vROp%bO2Rm936168ynM7s-&+I>hisibQu}+G;F{C- zPQVQT?r{No65eM@-x(M&UO=NpxS7&N<)Q#)QxvX6eM|x7T~WA5eu>^k0Q2c6Tnl<% z2h3AZxClL}-&X_-yv((#Um9M-Xgm{et=bVap*OdJi}1nQAz!Wp+#VX!!qG(IOy&G7 z!2F|to2i`X^MBxRCXIICJh&F+ayeksC|smmh+Y9O?~KB=p!eH=`B)S#LXY~l2LueI zk6bIc+kjDGJyEy_J>tK=1k6{W za4qN^0nCr1a4qPa5~m#au2s35j0|2B#~F=GJj!_8DKg#Q-6Tor|D zk&o*Evm*)@$p_W%uL9-+QMeZLJ`0#bQMd>_O5b+?^HLP91-)fxoaayjg_|kAaeTW1 zFxLt=(j!{6^UD!FDq!Gcu2nlH_WbP=fa?U@7nN3**5}W)@6I`==J{<)A0dOzT zEC3vBw3&$yK6?qu89#C}l?&C|cL4LlC|rwjUh-B+T8Uzdkp;7-vzLWMFV3)>i*oJiAn&rp_4rm6mfkTyn*Ttc?P?nLY1KH;&SI<#`jD3e!VoO5( zQ?#Q(X1la#tHoLaTh|ui^d;YnKm~B)VPZj^<+ppjtmnJd^OfM^ng4Y!jP_OBgP-eq z;o-%=eN+sjPSbWm?ntX4M@8tvaNiPyQL%SOd+{XNu4_e?`VCH(Xu1Q!ndp*`?_f}S z;d5Opy3`ecE^R`qbxHHF_bEu9(#Wx>qPdSG7pEVDM4}R9c*3 zI2K+eK}hnqN;`)XEVpf@-7I}C+l}XF8_>wVHogNk#Ae%9y3dobf2`YV{2gN;Y&^Nx zIDYu}gT}sxRvPP{zU{khcAFR@4;lxS>@^Q`K6dm;QX{U!k1~yo#_Y)-#9o{^xR0{C zo`ub{qa>1nz$T`?LuLcJv+->ze)+%>W8dl$QVZt5%c zuHRZaXJ2=hh9kyK_r0eCcL*Q(CnRF;Rp-}J*uwKg67zlw;aecjV`xA(4s1RiMD06t z+jmTU z*TCNOZ>cW;%)ai5TYKLTyP=+Hob>U|+H#f#5jhS?vueV2#!L1+JP*x%-t$6#sSGuyn$1Oe?C3~skd0&FvWo$N%|CgvN)b0hP;6VDCI_aQtT z=KBbq{Obeo*(~fdbg~xnoeLlTdKG*o3p2eiyoR#{}L4xOeb7zj66i0!!qN*se6t4{;7j={?Vn>E^z`uyfbqO zhw5(%vM}u&!xp^Tde)+a^XNvhPUE4zZ(edAu&0d=;rTV|K<8fbzGpf(CrwXX&CsUb zf#d=+kXGW7N&Gt5-qQ;6(R-QsNE~pk_&9vLH)+84Fn+GP1|H4}+(%j5%EDHVP^m#? zj&g}f8Xh^4mK>I3GWU^8-icoaJMT|%xULobB0jn@AE&Qh6@8-XriA>h=<}4gszA%_ z=rG%{cily`E~9ZDs$u0}9^9>iir&GeRV6Z^N%sqBhP;A0CN%cGpe8!^@oesLc1UFxSQhY!-Tk z^yA!)K4<>XIF@u^f<*Flv;B|MPi;yS@v$)XKs$w>qo~D+m~#ZM(fF1K27t?r4aYGW z#?|bD-uIL>z4dDR5C$0KfEwdGdorlqgI}ja(@;E<)RBLHgDcCTu zGx)@41C5usZLExQ8~RK>aXY8+LM?tFOi`xQO1T^mk=%9( zbk_JL?2Kg!tu^uzG>Pnia}FB!eYXRr2!v`$rbfsf2zs2Wsfv^vmFsU{l1#=HcGAHg zrtUm&%Bk;Vt?@&f4l;cVSuh&^VIF|381s^!H`K0a?L0J$>@h(cug5^X`;Lz?NTwH` z;(qHqkA2!lpGKf0-}mf1_mg(sGJLD;v_@2r8(fA&K&Z{*Ob1vW4&#SIHC4btF@KoB zn8zO=jp*=7d;Jf)?;2&tm>%H0DD|h}cu^?F2R6ry##b3OI_qz(K&rS<9D%*9RUAayO%3^5 z#lce(Te?76+P_#@+PmnPu0snP8e0kbID$K6t?}8Oy&z)Z=w0I_>wwm?joGiU8_#NF zNC!4-w&Am@AQ8`Y-*GHh~y!PBu$Ytz>`QVjrb<1pWclIC{qL6dYDR9 z#;=oU=A5rc9zM*%zKEyHe9z#?zrF$=|GEq{Pm|QHdjuZNVcge+_rGFcD+I_5;y;ZA zd>HN{8Tk-?9ZcaQ+OBIw_dW*6Bx65~tGVF<`cJX?6uFPMnA0W*Hx=Y>MVmv$PU(_P z8SR!%8CoixQtf``4Tl!vz{{pBbOb=ztZXrUU6CIfM}O+7{T1 z_DEWdPxcu2Z!~_V$6@b(-LsAUgV)wFo+ATC(?g_sAHgpE#w$nr1O5D2;ZFW-Gj;OE z&4+YKgv6{lVGM%f9^g@__HE<9?%2_1jp@(!JV9w){~xt=_WtkH-fA=!8;zeBm;Bf` z(7D=Je@BlDjP8Bc0m$rl%xXM{Geyraim^T%AUg6XeCWP+lhpX>zMo!LyKLW2FQ~nR z2%STOpqTh1mIE?*=cy}<;~mBUJ$7UY?@D8Vb>NPk-=h@5T9gAt1blBdzCNw>#91^J zGZ)o;$Hxi!<&(NtGQ01fy~9QWgR^8HhJzr}eb7cMOU_3ueUI>jQe+Dlyf6i|mRjX; z#C#WvnVK221TK0_47bp>>ubYb0r~={fAL{F7*(yYz|%#(!9q~FzlX1s`RlaCQtJS( z{w7Q+n2{Gyyi47(sX`fNtSaanz0NrBeik1uau#e*d4oAji~@~)pQq84RDZM9*!yvK zxR~KNp#DgAA!_R>L;H?jQ14XsbuTli{zR2G?qW=7^gYJu|H}QuwaQjBe>xd*!*z#k ziYl0X`+%Y2d~PR0Xf6Sl+0cF6L(0|5_;pGL@Z?(M`{3Ki!hVP+7aE%oCv{<+5?QI? zUmt+)$1Lo5_lJNb2`O@%ldN;zyV|x#LN7&bU z;iJy6Q~EdfcpR_5M_KEXVwlS2xPON*T32%2F?hHrsrx%f&#n4I9PE(9WKZJf5xvv8Y2CY zjiBi^i}FRaxVQ@v5v*#(PI z4+io4QZ}x?dLwk703E=m{$JVh`8(ro*M7+}VZl9#FMUtxjc4t~F$<^R8ZV-Mzn(gI zHf!cIeum+6Jv2=ONl*gIz=k69PI$Tx&btHJ!f(QhQ(?8`%G%{k2x|%M-iNtf3HfuT zviGX3wJ6y)5?R+2-q(!jPxd_FC7kQguFU{{-scFhn7#ja_x}AT?R8f>x9{pcZ!f$M zp!U@!or_<>H3OvWwBtBt`OwPsH#oOF%f{+QJ_u}M1S7I5_ZkiTY7Fs@iROQUgHhG- z^-t6;pby$5Pti9DqKSYFE8U3zo~7fq!|7486eBge@gO5b63b0D(!;_~hUZeuLM#Kq zGDdUs|!kt?V6;y6;#5IIW>yX*4z&2D*x?4RlU2`L4HcY!xqS>17*I zLNBZ61;!b)o|Qz>?Zx;ggnB5_{dd^=pRfI%(a2%+@JMa`x*M0(cWMWE&ffo2eSz}V z)TYgme{iR1K7v~;$El4p^=)AurKrwso4zU2$r!@Y7Y$rhXO~s9o z&C3)L?nuCN=Woy}5$QgN+}+u^=y+<`5ts`M&0o5P7?1Wrm7tXY)lXV#TnzZKRSs7fg60F~o9=f|U;3A4q~&yalXN1b;{XTit&usnSC z;Md8HdGnrOFW&nY9JMPR_FM4T_;pHugeM)`>Xbg=ef~8qp%ECT`C&&F5eAlqA55q@C2Rfzi;>m}S zFTuy>*Qh_`7-MK=k1>otg>RDisCVQT-}b`3=Y?GWDa5I)gpX5M1s_kT2_GMtUgL#r zgO6hr;o}(Z_TWe`a@-GlaCG>9!+i$6ZkDRQh3_ZKcgzc0h^}xY%jHt|IK~3_Xb*tv zXz0uPZ0@7>6=Pv51jr%rpOAbQ?xTK{4(@eGM-VH~c3msFCkeU$``cw;m$MoCA%Q}) zI2Lgk_nitKr~feMQyi{qMgI-2A>D^SlW4oH72Q)jx`zOE2I`vJOyzMNgC;1V?YdTU z=~$%DGf*Cf0P51FTHqMrQsK0NkN^~r;q-7wro%+ac_!MtoQd8cdI;Al-5m1Fi@T&V zVkdVldZFu?1*E~iLJ;wJEM6)N zvb79K8b9zMQV>WZOV|lnjJ=bJAmo}Y#*$16yWlQQVw#TF7Ch(U_r4=%K-hp$m}3nF zzS%6s{^L)-yVbY-`o;iu_?Q^Q;2&3{qgy`KMFNY#w6Kv%pWiNE=pQ?-c)1%uxdpkev=%73B^Uqh9B3TeR%9CAL|)H zfnzYCxRxT+KSEfmK6Q_eMLi8U1`~>ldLuus_bjYn;?GUtQc>LuCKMM*e4h`uyz-gf z^|3AxSPX_8TcaMH9Pv?@$4*8_N34z~Ar;ShGgJka$4FlwH`~GIAN}s1f6qU{tP3n^ zL*aU-3FGilJ0I(6fyH1j7^~9N7Q)ftL^_tvgeAf#&EZ^-^z4Yy2?FAP3qN^If#-tV zhGLE)j3jKF(i3PYrym(`>=G9T`(y+b!Eo=jAv%Py-3y6FQb<~DN6h7~uRn4hZBkz zzN09}nQ?^roH^Qa>LotbnF5Q!gyLGkut<`V3m+?ftH5F~As#y)u>L{yu(1ePU=a+@ zVnu{d3_RqvP)M*&FJP3f6_7uB>uQJuw@%+Hur6q-(;kN9*6GrJ`~LkGc=GVK1Qvq{ z<^4j2<>s9%x%*fj6Icu;l=n9?EXp0Zcf5J(>u#i-g)@hvxf@3ftUVRHf zef~Lk_B)>Ru`Ur<3?@{D5DJ15C^=(Kr$6aqDFTbZgyMQ@D6V(zS@(S(Ym2~QFrm2K z#<1M_B3|{eb_y&86RNLE85Y$exfM56P&u3nC26m~A{ZX_S0Y3LkMWR4Lm@%=d>ODh zVkEc8Eno6gB-y3>guo&g))Tp6oEe-8_e9i3L1Kf=N$=V52lt^va(R9si8i=ZEIq;Y zz8ax^eO>k8)pxG)c>Z*O#b82Z*vqiEe3PVmKe_W8KGs_W7J~`ZS6?WuP147&^Rbcw zi@}8A>JP>Bp@q*SeXOem7J~`JMg4-Guin(~H+`(Kz+y0=xTtu2!!KP=eEgV?^=^U1 zU|N{Y0IKvs0YiRPU%gZcFA-V~q$b1`{eVB^1}uGoCur$J!;Z7)&UxB*St!VPj&n=wnR_ zECv&bOAW>Kp~)*ce5~IQSPUi!|$ca_Cr3_w*(f0!B@<8h!D;RL1~=ESAGW!!M*1Q#pFt3y6KA?!SJv( z)D1HiM@W#4fzXZ^X=UVIHgf2+T{@<~A{ZXFZ$>&MV0`0m_q{QVs&nbwEwBhC9D9ag zk#|+fHECv(ex?Cu(A5{PIb{}h}z+y0=xR4Fx%hl(1KKaG_eXMs2ECv&b%L&D`_6Kht z_Ob2}SPUi<*M>Iv`g4KBU_xN%3?>xUU?{GCIs1)WKGt^x7J~`J zH57_#`7?j8)5rR;z+y0=xHd5?S4x~W^!N=v))G=>;22COuFVMb`}f5!>Yw(pE)ZA@ zCKT5ehULapzxcoheXJ`47J~`Jb#*AN%hP{!tB zfyH1#a)ZV!9Wm-v$-Vf$2S4n$+}i{e!OWwXipafCLHTnXU^-&w6A`#e{^E4BXjg80 zPS7D39`=$5A=t1axgH@MF@rw9*}uIIO0G+X**-)l!Gy7HKuAYyC7$Gd^YW*YKGwQL zJd|MO!LZE8j-6Arojfd#5J-}>Zof=&V}Vo!1~V8$mx|M7_Mq7r|8C=;*%UvN+j3zh zgNTNIGqEtf($B2M1cJHUn5JMhdn4>3H9>RBHGyCb&CS#Vf;sJ`U=Gbq)igmj1#{>~ zW&#FhdGN(sHtywDS3s;m8AP0hYxx;T}{NNYF`zfdoIQFpwB7 z4kYNXf-LM1m8J^gSRQbRsiv$UDalOEl7mMU1`_g4L}cBY_+;L{ZdfFzodhzv9h@ZXqXASW`PolN;)lTG7i-FhoQh z2of=?s%#{koR!Mv<>0n@)HwFhkE3>31%Xr8&UzVD!5VO=A6Whw>6x)e<%u z%3;I!A`hWJHy0_{$?3^_*2>Dc%0Pm)lY_;upL`&}HjjO;N?N+A7&7009_D=7gFeusC^AFG{p{3Cyb9og$`9qm5)I{9<$@;) z8x7^KlvE!wASt{+-yj)+Slaw6z=d#K&4gUZJ!Py2hpYyy+xdoX%JMY+^9xOBW;E!FnGykTW$sTc~O5_7{L$I(E(S7N}7T>^y=2oO~D+RBwP#HO~D*G0_%ys zAO%sKT2{_#hN@?is_ZW1gF#TvY%PBvK^p}EV$193!5vm6W2%aik03%mj-y{0-Q!D7 z!5VHiiW>(fD!YnqOVCX@m)G>1lUE|7LTR8K1*9@;_tRj?DILt3%H`xiKgoOpf#`FB z+J?+7ipNdvmFg(BwKtoky)~C#etDcZvb6UmW@(S^>l))~ZIh)v(tYn2bGrfrmc(1% z3%_E%2f;k8EbUzhmHZ2U`>`0elR7_>rI0*EV%Le$SO?&kWt4~|i5`US0nA6DaEx(S zGT4L0=6?kkcO==4-ai9wp%`a)a4qOv1em@kTqJ!o;--;TDGJwu-g^M^n^Cw3J<7+Y z1q{m=9<40KT!!$!X@ZmG;K+;cX(iwXCjhq!a5(N8a?BD(V9kd<9>EYY1Gqj)DBM!~ zW~$#W0p=?L&MW6gepdqj2w+Zr15v|R4L_FO7Ug#tVAed^#q%2nFy79SbY(6S7DWTKBPI_o7uYL(j{%=60 z+)x>ApP22n9(E|U7Mcw1m|3*zUhmJ_k3>w4$E8kl8Y0x~xU->+SUr({#|X95p;{ek z4XC5#=^%9Dthy1a2-FcmeT}E=-fedR2(<`UQTh1IRuYR-IUo0aS1j1Y?~Q1pX7t1g zaMioa(Clnj6(1)i6%_-e7J_^Riu!D)p0lhein{j41zml5Sbdkp{n_8aa&Yh#0v5f~ie`=Rp zh()SR^Ok`ra}51G=;{Vcgb2PS2fhaO1$a7IDw$1WveO#H22}Y%De$S5Qnpdk(MDmL zZ^<5R)0oT62M0Rk@)?{<$#y6;=Pa~Cvi%&!lJbQ;nJvv^r$b_e5{G>i-NpI1XAXquPt5s*ZvmCZ#qqPgOrDZF_iI5-qxkW5@I& zyXnFKgS+nTkJPKd6_F3o)k5);$6TRmai1g96}X=x)Q@rJ^nJv76nB0Qh*)po&W{%n zi_I}Veneygh{8=ny;juup!o47Vr>J(k3ZP70cxsH4}s!v({|LZ+8af&4HzYUgSdS4 zGqgAFIGfYX}chO;{`dWe=n;) z^!0(R9?;W;dZ?Rv;r316%Ro}6?Sk}`;2{_L<2=m(`D}L-7uy|0vE5PeVJN7>c0uw} zcnJBldf^K@Q&(|#wJ6z?X~&XukZgsNHtkBZX?VjBvln_A$h2kq&|U>uZOI{QUz#&D zP=g&Iw4-cf?ah(Wpf0IxYF?CSvhW3gngG8uP)9C7+vRXzHY7IVw*rG7>_QNMWbuOC9{);t4VmA zh54@6Bc`1BBp$jq`Jv&;YA(Teba9kobdCRJ(F=y_=bB3}o=>b8-)JsEb|3TRHpBIx z<`RtO6RV_N=tTYe*yqOXG9M?mYF}c!pETK~g+oL2^D~C7LS*b=S$Ex@5R;cQfIf_g7M@|AK@CzJFe}UUp(D#{YmQ*jHe{@ z_2~Mq=}#VIxIWZeg7N5*QK@`zrmh35@%I_7h|VU#cyzJVHu3uBwP%zVu0u4JU_81G z5H60Ssp~Ie4qs}xMrba{?&feNe+spjypwpmxq6>xrk9@jF}(_ePK53ljI z(i1foG0LyrkwYK%#NMGI=O`_w{wIenw0U5`LUR$LUSl%NXtY&f4A8;-*sh($t*6X+E69wm*W5QJ>>n{^~18 zXMd^ug`;xdJNqlV{xH@_erJD$_lMH`QOpR@pCC%B;#DR1q*PInjH}l){jtk=QNtGn z=S^+GNHhIEHJ(Z(CQg}LHYF}EY!gPx8{34Dcx6+cyZHU8nP0&8B~9Mk>~9d}^d<~T zgxmfckxazXlhT!CiHVbaVr4L71mm-|BUpWwgQz)+n-{55q415%mrcV|dbuB{dEy)Jii*;>`lhZ2 ztFHX?=M}%Kqe4kO+8I((7O$96o-Ui1#(^ZrA5(-z=+9gDt^<@{*iScwYnJk%7RT@`ykBd-h@kJFQUX(4IA=R)11P7g1 zB~#nPh#*Poo1{EwDJ7|RSxE^BSE@9w2E-`pYDBDxm01!X+$tG*@O&tW-`De@hK(3D z#(cHPm#zgo@EU9bRn3;1ev6TE-t!v%e{8Ub7x+O%b=U9-rN>#If! zFxP1u+rOZ%RvfU}hfabNCpgy-pPmzNJpfss?StNLf$5kSh}sGBMqa6+1J#}3+A9N&rel9l^XZVk}&2yFe6lS z)&>?fjz!h`6^n%JWUMOwiemQ4DBKd8j;H1or7`U_Ky*#VL|IWKl)*yAEGp)V7-q-! zs+wK7QO#0eJ2lK=>J$zz@wO5~gHOxTSFNqvF(+S2i)Fi^}>usst?-9dwjPTemr2KKR_TfLZ z`rGzkn7uC@>ZO(G%UJyElfDm_SX61Y@7hhyW3{W*A z0^zY=S}|}Mr9I@8xvO;*esV~1p|jG(bwHoX)76_9U%eX2@tD&jvVuezKbIuOQ(AG( zE9++5S$m+4@>2~q?)E8v!$uAtF-&~9_MqH46{q~2bA+-m!ua`H@%Q0(Dc_3SE}#{^ z1<&X5J=o=>6`$W^zx~S-=BeK;w+hmw7bZ|8a^hv<2=iCGwC#!OmtAo*;9;2Jo zT=8JPQD!&06bL7JeWwC3KhExi!&(7f{kRRd3xF%&d7dR$mu5{^v znU?;XZGp>`F3h(Pz@+`SfOwn>%!PiOFCLV46EO0%$E`O&-qXOnybtm|1E!arH*n$+ zAn!O}M)`5R@G*&J0JG4K3y^meFgN&dK6$Kf_h}4BaY5ytqp)?Ia47e_`oZLQGYIFa zA7`K(dP?9$*IO*CGcOkS?QuDe>b1B>1XI42%HdCa#$jS(PjLHSk)|KmI1I=5G}2w4T( zYR+K6u^!~gkEMs>)GS6uc3H^R)*j z0{1C!M_^1$7s8dR{2dR>7>&!7eykreHHPx&SU)fX|Ie+NGY6K*9Av4i9`SjeT8kMm z*U@GQ$vtzOJhAQ?>soyL$>v74S99jVI`8kg7{?kP<7&lK@xNcXCn4l(&i`uG0b!wu z(Qr1jp}2hm$*!B3$=0X*5nXv3NX`$yxacCBvhk5ReJuNG_M5Twk;`G79E(k||B&O0 zuv!JnYSKk81lXZ?V#4|^jV*7NdP&r9Q9RqJ^$yL#SSd;JW;gISQ+S)Xo*gOl&n5m^YLs7Cze(uauHogOFD zf8nm4-UW*9K(;#tgj%SfD3(+9nOJC`A^ODu^3)#fu$YopXpXW@67+oBDcg2Ia^;hX z$fZm@;L0g?1Te6Uj5}r9E=Vq`l?pFqvWKC|72ctE78Vp`+b&4%U_8_dE^4|-cx~BC zC6fY*VhgThyF)?wL9!K69bu9$^GSAk?rb6=XPb--H8)`qRWIknrtQ1BJj~?8iA|XLlgbGr@q0h9NtqbN=XI=~st6BW%&{Zhx@;V({997xVbT6&RX2BaPgUC%fw8X6Z`uBo))8+}99xUG z^3&Cu%Cj%-ppJBQHh#Cxero_N3%6$8DgY`5dLjN7c9dCSJ(}xJc#8g}n zIdx}>P`}5$QmD6a=ag4ORxl~tfoSR!j>h-W@|1>T%Y{mUN(qIV#aCO~Re?~=g`!xX zCW&8YVh?K~PB9rb0>ybo4;GKDIBjHZ&~hLafC6>SV>N7wzdG)MSy%LCVVMnU(kLwF zU@2TV7C>W>9Lv!uT#YQ%Lm9KqoPq;q&|FSW*$2*~S}y_o68r`WPTlg!(z&BeVdDr$ zEljO;B#%*zWsf5fA(c2xK$Q?ppj6Ub2}&i{Vo>ZRY&RW*N*qNoan2Aw_c2Hu(a`a! z!m$-q6bpSVuCOfarF`23$)1CUx_!#1dcJS6Dbq%h4w9`x5#l1+5#6jF!@JJa2XkgW zwojHo9SJzT>YNP^E`&^Gagm*A+quYepxe|m(_0^1b&fgZXbjex>ZPi77HM5 z)>2srd$do1;_WPbQdKJoU>i?HvI8g~K)FS{R1s#bs_Mix<@>lI)}fA{DPu|asq#d$ z;;09uDsLmGYjH)arMR~VwHkMpl!$d5?$-!)GwzD_K~SyYw;gw4BXa74;@FMfO4~m` zDGpjGzFKfxa?TkM+uZ;{m1srf<2Oqsdt3CcJY#NzDtSXS3uCRY)TgL^psvCdw(h~5 zI&2ptKZA$=uKY8>OC7cgl7BHCLOx6OzZ`zXk~(Y`B!4*`>RRbb8>XJ(@TQVV8_Kj( zk#vx3g|yEt-N(bpsv9~VPNu%Oq3Lxh^XmbX86VnoWxf=r)96N%H8C^AUK*~dD@L-a zy6Mqus&$gCZl&qgNofpj@p!Bm;I>YZ>NW_QRdz70-lhS{(16Q#zHI5N)=3!ra^WXf=hZ0w=Qvm#upJ@>#{7^WU`MkCJV5k-9o;nORBs=;tf)v27-s zJQn*&W*o~yLXRy-jh%69J~zwYN31MbhGpmG=p97z7#?Ewzq$E zW288kGm2t5sW^aeLP0u6wnEw;kEnG1ih5dp>_0@bOu2%a$a5$=3c6^$1v`VV& z?!w)F@90=p(8u13$U|h>;-9X5xtYlN}6Q3I}BP z&qS%nLpfUYestx%AQI6vkwPA}a)sY325y7L+2d#a6Zlorn1Oe`N?i0xby%Y(D0r>YU`aT5!o zE4heL-g2M9E-qBM$ZF?>H;p5M5xrSxO` z?5e@u6TB-=ui}^b8RSEAfCrUX90QX?-;Wv!aBF5__&@V{(p%iE!3YuWYb*0XPEEnBW%9X6HiCe!Wqn?ze02XVBP-Ie%! zeO{)Ur17q9iH;j@fskaj9ZMaeE7yWfXHQ#KxoTVUeh*T70&h*Nl`D6Jvz04VKoR6w zA|pS0{q;cX>YBa&8vMtJX@j|j0;8Dn>^7Z;mF*lnZOKF>D&wBA4}<5KIAgv=0<;b( zZs(yQEDot`n-oZMEEWr{bC$^28*tVZGNCt=SxA=E{NM3}ipd(BsMAhO_t={5)Ne&U z#&MOI9(d^~oSWDb*-yRA?8>@}6xz-fOqW}`a7C;mao;J_4BSP_6$)19C=-i=s;khXso>N-$FL@eyBu-*`=AE?)b8Vu?+ zp;m)R2*vuv(jT!lf%-tG_dvZW)F+^nwqBSHRJb9aUY4g^E2W-t^$+K{ZTBGv)lw@e zAHN?Gzd;&ur~Z$zmz?vZ=3*4O7yP#23R`bLzk6j-klc1b%6rL++(2kqwrpxO5*5W3 zQ^|f9Sjx9uknBx($Pt`!w%omknJCJ(U69;A;vwYn)UJOi%#>+|f^?8<6}y4Mx?8c( z5qUj#cYnKEdzZ$@+;CA|6?w2x0ExhU@K3nHdRN{t${NHmz8)axu#3|cpSQT-B5VZY zabNbnn)(`St--bxWz2*pZ(~f?)LgwV*0`h=9Su&}cC2N{$rmTdNnw_KboRU@3z~Tb z*hx6h;`~fWb6vW2aZDeM5j*AN*f5+;tNJTn7sbOB3(P_&%-%>FT9wW|jjhEP+@bAL zyW23t8MEPN#QA<)%tOmMQSR#YIsU0Kt0!2`ym=pYuj_oK1{+DQ8|qq9!fF%_QCerGLQT!0-8IwCC*crAK;oXfwdUt$ zjZsYdMl4w=<>KPBP&g!QAgHp&bM7!)CupuNow&LR7w2BdzwC+mXt?a~o}{_HYdzB) zV=pQ*E0Z|!LWj37rmE|U4RgVqj`8O`Z{BUV&L#_-U_2|py2ID30Q>EJ>mM~-O~Rwr zHF$M#EN65*+V$ib!_}&}1mn@gG&i~)*z|{c43|BpA{bA+dUkPu2pNjbs-UqM;Cf#m#%3ap8KZJ#c4e{!FbZJFMN%zwX27{Vz|a? zF2Q(o?Jr!C{-B2U{oVnFYpUiFj7OKGUWg@)?#QG&<*PN9ox+yIZSKmk#?f8X$>(Or zN3S3pHe9jj)p+i8FMMGQhd6!7lD%chxPwfMyF<%4z>?bS`YI}4Kb&na7hT;_hC>K$$APDA~KAu4^fleBpqPYa)NyCGM%PtRfx7|O?aPin+I>C5!$yX&u*Z2Q;{&2%(pXebNkFG-@ z%hZCWpI^{yxUSK<1mn?lm~h$gdf~i*6AafcHJ4yKx(;`^Kv?hZ_xn!`7tflb6O8B7 zh8TRqA88KPQPQ@LidWssMdx)?|XdQ z?avTA4TqSvblx*8aG01lVwB_)*-VJDb)DkzaZ5fPICF-@{9mtZ_8 z&#`Yf6yqJ&`XQmQhU>?gOE4Z?MZ`O8)Z)VqIM;C9r?~{<(KSrCV!Y#;&|~|fhRe1C zCm4?|_J>B-Tc6#v+Hlz?g9yf>i>Yhc!&A#Hy2fyQs6!|ikFF6OT`awZ%T7$ecyzJ1 zF{|ylXTWgv)m^P%JpCXF2e=Axr<-!g8Z=|7%)$JP<|0N)%W!I?W7+WbXrtj14)ML4 z?OoCDu3N84OVu=Nu)DAhemvR1Us}e%*QDyHw;uksIWuC8)-D)NOvehB8o624e}$`V zHe8LGOE8{PJ;|eM+Z{hU$Z)ODT!QiF8Yf(K`?L1`Lx&o!8#I?-Ji5kvbWIy|@{bJH z&o!4|Ji0iiVaEL4c-^nL1mn?libvPuGd^8lbUmrL1mn>)!4t2`M%_EZaJ{U#1mn>a z_vpHCXE#@B{7rKS#-l4CTru23xVnwL|3;(hbIm0fJVm+cD*tek(&AcqS^~dth;@_h ztM9+_cT-jm)Lg`PM|!3335VFT&?N`{{3ydUU2_qmN`0G0J2`&T$>+a2`K;^YW1o)E zITlIC42O=UXtLs%{k{_6LYlShjP?5}EREWB#`=8~mL_dGWBtAgOM|wZv3_5Lr8(QqSii5rdXaj+ zmB*7Q?KPRtUwU4z3B|4c{6+!To9aciozCujGS>2G#@gO4E*q6)`|-cJQCX=zUzuK4 zKWsznm@aH86YKJrDumT$J2=A&J3mobAN0gd&Rjf20n!vtXAYgTogUa}ElW=AV2*Zj zPJGOXOag2_;c+Zesym+;=iaBV3bAM^!@3V1z&6i}i%dw013{GylT-+)salgIu z5#MY+?u3iShw^+27jFzSY!G=|+=_SF?K>5SLBKU?EXQ`ac3rFl=6a3e`?2gca(x4# zGLET!t1SR@$h@Vy|1x*i|-y_B78lD%cYm$K0;#zh+9y6pM(E#!0pjk z4$^bQ_Y_R3Pv*orTrRzg??R0cAZ|f=Plx|f;GWmmy~X!EVE(Rgx%4u=z4Ly3CtZBuV>y_iF(MGRpmOju{AUAq^g#->w{pJ-n57z*OE1&qhZ>_K z2J1Zn{n;;pdy1cb;Ml$8Du3I6`Lo9DP4Cyh^g2Yu?X|od2h1ox&X<0S#|&U<{J4Pf zawRa=`f)yaECP1}v(b+WkoPVy|KrE`sUbY8EXpBMz>rFwxP~a{cq)===a+R0aM<6b^ z=yK_0eq5z70>mw-{_<YaUK+0B$;F_~@uNSNJXf<}w#f^!n0;K*^{Y-zt{y`!9ad7cBf$7X`{*(%xH*l>58iu~B3%y(+6YaOk2 zUAh9YA-Z-yC84gho7x)3K+5Kx*qjaQ$k`A?WDhyhGh)rdosD(Gx&U`}1rcjG?(DE4 zV#dBusGm80cY``o{NBSoCKPV+PS5{ztfnd-6vcc{D{ey3u2vMgyQA2v6&>EQaXJp| zSiFGSJ7`LN0gTCG0u*O*G}SjOj@8YpUsPL@)7rc;7r=vn+~w<_;PRF2js^Yh(uKms z0^~1Tqv1CSmnvLoP`2X}6)8nAQX|Fh-zr>7P`FSJKHs;(#qtu#Rk-G}a7|CP#e1-5 zJ+F#Dc8{w-jrr~Z)p| z3}$&Mh5a@~3EA>3*mYDT3^5R@&0#^P#HEVGnV@Vp1%wKxqR31%+MGzpiXiI$;Wj5< z0v*uil(JZ$d3eR%HOup*hJII5hV|&!=WFk=`}gyG71Cf9u88c#Rk^(mzfCG~R>yW{ zfKaKZD5m1+;^)up9NkKPyV@h;UERtj(KAsDuo0-}(`X-LeYU%*9oQF@%FzO_u$mTt zfv{Z-2o*?0F_81cFSrFL`uDq+xa@pHAuMutFF9L)2I*d+$7Tv+Dt^+(xce6*#O~-& zwpZ50CpMp;P%UGu%n_zQ;KZBgV2EI*y8^HQNr%p6*LzvryQt1ZA*6FD+V{?d#X>a# zKLpi+D`K&8xl*X#;I5vo1*HnjyP#AP@n=w9;r<@$dF{|!b_ zz2J8RuCQzrqHNo#=U$#BJme;uJiNW)g0p2)tC6TE4wRK_qF%;jyCB)i@DQ@G8>-8{ zB%3nrP>>FitwNzHQFnB^`815%NOY%WGcz!itwNi*&D~~x5-rHv)dhD{BX3*ziBzZ^ z6lGdWPCTdFf)w z(|Wa~uZ*nPvaA;ZT-lme)>@K()`qr3_|}$p!{H~^@5x*7PS~=Rr>nPL)~#bp%a*S@ z)+e%g$#L5+-7mW81t@@}rfaw0KRXF*5-%ugJ?PN_j2|(a-+$d|47Dq>&(xKSjhvN; z{-k}^>{Ru7jPlKi zRJ^cf+*6nKk3POByl31um*x-oM)l2jHok(*B3>gPp$t35hg=UK$%=2wJGMYYGTfdV z_vEF0>XJjAtee;xsZe~oUY8%-PhNoC>dShSx0DR{Hqnun=qQPtwc$EMryH(_)h~qE zE?l+4!h zvYLB$lt((y{Xdbn>h&u=f-NIhC%`#(>5^~pe5?f{Lmf}?`OZ8H4X^kR8@#)+Bu|PY z#%<3Oq^mcSXSY;_RmE>TTvcbj;%#8JvJn?!?`?D+#cx$g6vcRN5I<$jr7NwuU>h>t zJ7oi)Yy~`R=IONJl$e>27?l-wBwGI1QJLMH$abW%u+g&{;A=arCi@knY#_%xgXmKlALLi<@Uh*OZ2F-e!1Z zd*-mZ>!Xi7Ws8fhyb?Kw$03Ma+1~tqD%%C&x5_!{@51Pmw@%Cl$ua`603;_yKn^Hw z-+7uahsO`e>^J^|=Dyg`z0`_hV{sP=K141bH?%qb@enxh!xfF_${t`f7GP5ODnyCL zn8+N!JXMz6l+Nzifu9Ip&y`y;r|-ROYYt8<|Ef0A z75B2{G^Fw+VPRq&Cq58lr8|i|^)wol8n+?3as-5@vfC4FEu17dc`MqK=+%eAvn>1` z$GukBkX^}WY6k*~EI1^(#+3nkB!W%`B(S|cf&&wmbs-gE>)bXzZ+%Bz$MbE6u#{Pe zA#WfnOWKmf9ZuVws@{!(ek!aJhV319zoX^fjzBJLEz6e|-qvPo$cEO-BFWbCd%@2C zs?RT<-({8V&J$=7w^Eu_}2H-6s)_JqIL->&-nihIiKchOY#S;<5UB9C=E(@eTuyNWj2n>MD3I9@UUk# z=bW=QOhn{4oQlXXi7yFtF7ArrKuS?R0HtvEf?}>ktOp&6HCg#R?@-+L_oCnq1@$MP zjsdkzsFOjVpM#Xs9Ne!RzZXCi%G3TR(n{}QP>T0UQ0zP-Rvt%f<9oEA-Y(y{Xu;B;o9`JVmt^L~jHujlYP*uMe$BkgS zbNynhV2U*@Tb!AEZ-1cA3bfdEHuYftvvn(4m$328T`cZh()SM8cc?k+Cw z^V)xGxP#di!2Au_@;q#xd)N{^pKxni-d>dGSkEY~F705=OOBfwiC%jI%w(+kJbEqP zk2i&f;(5CI&*|{%mDMlMn_X_lbL;;nuVa%sq8g?vmKHe4F%ij8%>0jGvvyL%m68K^-sBh|Y8mwbPZIm6^wvwXNrQb%^JkkDkUf$NcZOP-FNFa8p zj^`M)=&CairSk0S$<;^F_614|EB6><;)m6I&V~~Zv%lktSi^B=mPh2|Qw|OyRtBYw zAM$MXDhO366vayMmiP_QkdyU)mOq106bB`{aD~NS1ZCSUNbX+*DZ`wNT?J^%rdA_S zQS2y{Y(i}$=^)t(8S0mB^@G8lelXb64<_LH4KHY%GH;3%XLXFr^cE*(z7R_RybYGA zEZ&fgoLbkfZb-`b9GOy2qw`Qk1u$m7yImScV+~cE?Gm4}fi)i{pE8AW(HF+r7L7t* z|9tkPj??8l^1jTZS?ng~%6a5qh^`fzCs*hr$oaDn6V9qn}&Oq24@!Mq2T7B3=!M>S3-b8ER-e*Q}#&}K1O=O zXrwS3sEEuLu&G3Ijk{`Se+sIf_}%SL4?EP;4)qU*>W}70@kT-MBdG2AfL3KsQ7i@Q z#MKae+!2J>>P!mQAfjqM}&#lx%k>C_hNH zLW*&@8ia~xk;BcGyE;U}NL3V5ut3626m{4xNPZ7Nit#td@A5Cnr(8QEq=V$EkjU)Y zlDtM7#hsY3t_n%8gA6IJ>8F*2aXfLRJJ(+<>X{I@Gh1x8ytPyzL{9U5QEN*6}gR_F=?s%tX3c6$<)WUwyx)z89b z2L^hm9{D^M`*^!T>{iVIs{1k=kbMyJ>nAOnbX|J3u5}{nk~9sR7LAu>pM8kyN>z%n zc4fCKrk1ZdnqkC<6$%4eCc~~WVbRd33sY@XA*7f5E^mz#a=P8ev46S^!&;1;ToJJpdYn)T zaaZHCrJ&UJtb0Jka7C=g9E#&U<;TjTsINe&5!(TfulzXfW1}6hCWBIq!Awv?aYd|! zxc^C>(w4#y@mr1iaYFqJ_l@$D_Pe;VJR+|j{3>s|;hH+FA#zxsovel+pphL6Q#A zp^yU$yI6fgJ@UG=tHZ5{X62)Nj;X^|keON>q8FPl8)bN+bfy8OdAO}+pDfy(O%)!u zPZn)l>j633R(mWdX873)J~ZN(_H=^5DsQvenoq)^818gcL(bVxQM~ujq+mR@2Kas* z4o$_K$$#*fk6^rmWD%#A(qSJP_tCj`P;=m6cDp6EKDxV$v)gU3<`#@+w_7*iV!5LG z`CYGmX1K;HPi@hLKc;CP{*$61YuJ@1!-E}hV{Hgy;oZeYE#c7DxOc}@nvNb~;&m>3 z=<++oi&zt{E}@NgElW65 zsGon(ziV$h=2#P`eTh-2!GWOdl+P#jPyAOt9ga^7K6^h@mNnSyy7V3@+fx?_Vw7aI zM#@n#@?zL9{hKN8%?m^WlGC`8_q?;ezro~1O3UfpDKA)jOW`{Y;nBl6|T!In)%e4=GcuN$+?2QFmjBw~9+!@2iZhRgU-DdxuCJHR3hP$S) z=9yUBSM<_=0w)$XYc9cfV$oN)sF98(%5eQga|uSCw`(8%P`UF*kB>WdDAOCS{oxZ1 zaR!vU={vu=&BW_9EoXnrA1}7bCSLpf{jVGMcjEOo%_SI5yx4=A+<9T_lTpL1dWI$27yS_8b-dOa9PdLQ)RJJm+UoS#up#@q8X*vBxjyrb_6fPP%s`{G2v3B+OmG}T>4(aWuFZz7>}+&9$gol(7m_eqLoNG z!FY5X0bgU4qx(;9+hw>4HJ4yKx{eesI}Pt>dF?^NHC}TG#-ocpjw#Q{gU?!FxK7nv zg7NfLM+sL1cjI(|TlS&o#3;XIS`M+Qzra9497~J0{BW!s4xNTOd0!kb0v&b;6rF8P z=jcx5hhuHiBHi)LrbCZ*%Fhq9cENb!K3KTeqSLWOGF-pWT!N84u1LXTH17@bv3L>= zJ&iltpQ_rczi-0)gqCw`r!XHUTy}nSoK?5$SSQRcXfDBc!aPK{+`WV0`kUqw3~*Sf zs(qYR)MK zxdh{h#Zck0Ywo*Ues`JS8mhSj<0;`MdUWmB*?WiKN@y;@cyuw}R0(HdJo)DLb{no4 znoBSqUBf)O&MJR=k>OgPxdh|U#d2*dPd$F!?^A~BV$CHOkFH{mu46~PS#G%6G?!pJ zx<&|>-6CE8<;RB`uG=-2U_81;dUUbxHe7$uT!QiF8YNtIP3ivko`)H(jhag^p7)E< z!gV?BEJtVl_r<7!c8PjfbB*p)qQ(f9T`$;<8EY(WYc9cfLde$vRSrQ|M?HJSQHJYd z%_W!sOMLEq8YhVye)VAAzx$)d^}9n;X321Tub^z_HvsRd!a zpuh>n6Xx;oRi%Z`&#Jon&xXskh$I+K+k3Kbv9{8kyK)|~%Wiv*(7K3GezUa?vC3zG z#|QCRRJ)i@>0%m_@nHDm%1%Dldwkq!cna|05GTo5;}%?YW24G?mWdw!=Gwhg7KtbT)6C(B!2g8zcO6+YA(TeYC*!I>%Siik2GBEnoBSq zT_wV0*SI(T@WYo4*9)3UFdki{9$j}&eCja6^{(a;j7L|}(FMYK^|*1<4cEt-OE4Bv zw7PK_QFP2f_j_d-{K6q!0jwK7ESznZ1LO%`)8U8#mut7pMEHb5oNDG<@j);2{gtV? z2Wzg0N|$So#3bReYwjWA?|*orlY>JvmtZ_GO$nEsgNNMmUbW#$YA(TeQnlQpt6}9A zuN$tjHJ4yKx+V*kor4dL-`HrlF4SCt@#w-3)>SfhFS-9U!*!kJ5{ySzTDa_Yflt4h zU1PZJ(p-Y^=&JPST9v4)HC*d8mtZ`)rg(Jq>p$U6!}Xfx5{yUJRFAGrzk2Ql!}Y1= z5{ySzm2la8!KXF1ePXzJbi+e9!N{nIEj8UlT;B1@fFaLpwcPnf3*mtDrbJ!94Y!&RZV1mj7c86I8JZ+rXqh6|eq z#0kcui(}Vt2;GLXerulic|XH-ndTCVN7qc@vg6hF57D0)t{-YH!FY7>ZBg|gNJi`C z(>^`QaNVQ11cRp-`)Hret;8%m&1G%&Wz9v5>Oo{R4h5>*am`|#0YB5Dy_1-PE?4nj z2aGN<#3;W>b|G?n&TxEUzywjH2r!3mc&a~c~i!iEhC8#kIVa~98A ztc;B`XXao_$8g)Ei#EZe{j@z5kEgPov@ioPj)cX{nExdTMn*b`Gkz{{j;9j0IMcAO z$uUh*7N1;RRy8qQnTSu9jVH<;jox|!11-+plL;fS`6RCGN}-|8G%V6T=D?!L;s%)W zf~NW=381!jQ<938m6S|MSEfqin9Ih(3tDQS@Ff#Q);D=A`G6ZMG@6w?7C;%h5dnz> zKUeG=ph+xG`gkPhr0_~`JWcx8F_UOED|uScn1B$$uXBjTNG>&9G_O%nT8)R____EU zPv$Z^!a11+riBv2VAL&YnAbUJY+sis7uYT`HcI-+!s0@|zp|Lr*&TG+pBGgy`JvdQU+k}2hr<9b;Zngg!Of-NLjn1#ls0Zjyts+cfx zakJg*(88V0ZI5}m`lg!t1@#&I2rU!aU;V4Tsi|>Zb*)`(hZWjGe{D$1<)H#!UCK;==u1EqRIE{=c) zibGZ90387j6vwb!IszUjj!w~Y)myh_yMFnS!L&Bc1AjB*JWvWvd*eJ%903nZ5LsIt zyeo)q|6GR5O3LCDQ_9n26Vp|3e5#!=vY`&fx@ymFSh8%wNHHm)`MVZ8+ zMGcMxu#)olq=~7?sj}o$_Jgo@CLeWGABfMoDE2JRO2WRI^6JsFqw2V*3~|gYhqbPOeGPqIS-f?KTh&oRLG5E*`EP(j~^GXTmBhf-t*%E z|}_&9_dqA|qL3C@=;e6uMA?n;g22s&4~Tm#H48n-vSYcz&B>4Nm$ z2LH!^JNp2ENIY`sy#$!6UAUn5GCzKyF-l^v-Y$sXqrg4UU!gcBkW23ezkKua?nC*UCfV|Iv$zwvo zIq~qxWB6jgjPTzByj*_|xMz=0Sav13;&IWDXvcBU<%$RE(a(VSogWua z?w<$dbwAEm?pcq%0H${#wYu~M$QuI8Xg|&;k6C*fFcadO7qsd}YE#mn&UZPGeBj6V4K~|5jS%maJ_*$XCH9AfIDv=aTf*QT<0l5l=MgZ?{>=zirW3}74-nLK;DO1W(2=; zmFIpZ;2ADDryTh5gXN{OHLRkz`@Bc;GyVK-IrGC;-?$QhRFOd>rT82+X}2 z=d@S8{N-@uL5%?^E~p*iYtfrQIA1y7=bz7j`^u$P%7G8p1Gp|DvE2k09m5xdtAqbQ zV6ONM+@%oE3QU*Ll&02J%KWzNa=5V5;JrP}#2$grNhrNW45-oee%>(qNsXZN; z-mPIVCZ@8?&N?>c7=$u$;M`FijNfVxkfNBB9M*QSS_lIsVorqxAeNXx1BTfT9^x=5 znSG~iGHhXdk%+E!O2T&R$I2Y?5L3Ht^2fS-V2c(FFREYIk3aZ9j*jbE8}nM1MpCV% zvAS05DXYeQxDBlpk=FBir8buqPz1MMqC_p?cGC>Eb6r}PVhj_rH!uXMyi9bc8K8#a zQqkqqo9)=jtLQ3<(PiQwx(D^J4$5@54ywtw4#JsJ2f;|-LBsniQ#0c=Yh)l#tAJ#}2zE6WJFN+HgS%Ca;i~DVPn*=dQa{+tR_Tm@lQXT@w#7lI7Xw z5^dA8{S6ivF`=~xX@uZaF`%;~wa!VvlEDTsn6&FPl?x|)fdPG{N5@l{ez>}KJhhG< zyVkG!ivJ#3_a*=R;Uom?bX*ZJ`NW}f#JUIfnL@pe`)NYGiaTcSn~CDj zi?=1#vGCQQL>I+Zqgw6|?zU?Rr@`BP9AABZVHJMMLseX5BPR=NC3aA^Ekb>6dqgn0 znP^)nzfcXHDa&q7WM3}NK1)*%vg4ZwoRfLM$xurLs>tvQyc=8}TrV>1fFO_pZ^ZA{4<|&v9daT=;fAYRe#7 zOL?|eVX8GTfd91_vSkCTXmUF{yK5u`UHeIy#4d9pXKgqT!LPxkHi~nE6p`;Xieltc z{dySGD0#}7rn<>ppsL01P}Dc|Gy#gOP{djUs#Yl6EY2m{ZUG2YBNc@(i5=FkHSp*j zuoM*y_1@j{?e1He8YXOzF%6x1iOlr6Wb0sDbMsmoVJzl6Uit3+ z0DT3dqCk}5nlm_+y#!5SNAnLlH-79TXukzHqB|bd{=I^L>5k(}hhj>bj$;#k+3o@m zD%}*tbZZp9(10G+0MxDls9gh4iw6wvx3zD3K_eUWN=Yg)Y62T3w4ji!7{CWz?G&hp zd48USsAwCisq9xNl)7hC--l?-`E)}J8ddmCbSSo`Cd{n$wz~v`3bUdZ=8MHI6onNS zZ3UM>EO0jlH2IMIq?TV$i^cmEYX%dd6^#TCeS-B-b?dWbz}y%bc8bfS~|ej z(h&w=JOMoX9DKcKcNO7^uIzvUZU`S^8&i5t{st<3?#e31QLdpM`LK2*YN}gmMIxn{=MbPaC3oUA1S+= z_FJbRXCj#%qI~DQkdj1l6(w5!numJ-Z1xqv(=Z7zI7w4JJMi36?et1eyXwF!FAP^i z%bwQBzB`LDm4rcRggdLuUzN9(SxB(vZV$7#?n*PDLt649QYend+DV#yO5~SkD^VEP z0)uPptO1!VFkO`yT%J7*Id)Cqa)@xkk?BLUV%uDXCkP%|g&!BL28Hoa+|@X5;EU{a z@Q+vnKwT>o_n@{3bq=WS33WB7R-vwU{05=eA!opQ2B@=yx(L)&LS;dz5!CNMtr9@XbC_$l8dSQy5*_B?7WMyR$O8 zC!Kw#P7J`ng3-#Ih;qx91<@L`@S`Qjbg4w8?pwL)qv*Fn-Z$C+no#mNClAp}14P*71Ez=}l#W;9}GZdTm@kG7eSWZT3%s?c^e z7!br3{lM#)LlEdt=EAm_L!Iu4k89(ri+0VGl&Dmi)HppKWAu@@YNdhY%Lkfj2y;p? zv==!;j+Tv8DAMfw&fcH~^3USA9SYiydq&4@$A$aL3;Ih=g~!|3?P}r5XSH$8b%h!Y&<4_!=t17Y^)GP9|7c%i>q4o#$l2FFD8BN!zAx#?8LGpA3D5h$} zx*gP3q1J#>FBvR#wc^*!sX%=}DJe&TQc}i);%8CYy$(WE8%5>g_pRbLNJAFs|19nX zqbRNY5NZBZ>??W2w zHd(0hbhZx4Q=I)AY5*vugO!zfY!{^CH+X1Xcx<_QPnYeGN!hjwlKVSHE@iSKqRS^bf-ry*(yEU$Xv1&a!`JrmG3JXxn!%dL3ws==aQ|E0}ttH^}eC|?rvMf&`K52 zMYve@=Hm)mM>SicMvg2ViPn8~;egXpD?VI~lI`wwRu*!zddtaxaVGGY4& zlo}gxOw~jDehW%9{11TYE`Cpf>MGP$P@I{HSnq>kiHKOAfC>vm35u77zVgIx5blci zcu85rd*WSe&U{Zlq-x<)E;dG=MYvMPq3 z(Sq$)yk!Rzp+%I(>FhJ3L33$edOoLL9M9gp5Dq zipcDg@|%L+tXC{imQ^ozbvp{as+22=c^4BuWtugi zrPK*XI^Y=HGDv6Pgrx2erVO|Z1f>EMbNoO^VELae$g~(uuK7NRs97Bz{h~}@o`F#~ z%wS@U2ZtC$O_J=SOuSr_^uo8AyyjDqtHaSXcps>UtS$|;z&=1iOe05sfX{4C6s#`I z+f*7>XKiq@f5;qs3^BqsK*oX1r)&ySMq(YyjFuAp0SzbjTU{ZdA)`R$V#|hpei_be z!z4_D+Bt`08VYG~$(?FY6NLJeLp=fN6!8NgLwo+GOGx4{PZhCc6cVZ0!5mRQYeBru6|qCC;V0d%o_QZN>rT&>@)TD$G)y182nGGI*{ zA_liM;6<>cNac!p*_Js{7%d;nw4*IWmScbY18K#I4yD1zL6$5t4-tb=*q=wsnJR<2Q!qN%p&5vYK)hF&x+-`XwuSZN;Yz^3s( zEMeF@DW7$RwlcvE-f;6MNi@yd4`yHY!h49~{q)<84xK`%;1~f(fqN6aeF3P!rK|}r zMv02xJUyHcBNQ9HbA?(4s$QsHgQ7{th#cIoK&U^$uTCg7B8r0vtr}By45}^b2TJ*| zl~WDu8IB+M6z&4Y?^*|UE2vsr5o;|eNRL>51*NM0KR_wHG^wT9P`+U+c_%o2=Ymok zzjUaFL8%7gWKdjKWVWVX`FJo{{03>rwfa9RhQTO`LmH0n!`5@SQ?~7bHq!#dBxkL-{a7TF+{0mT8ba%*p#1G zmR7yz3uzpghAG14E`s54KbW1iR)=tp;}Dt2snrRg(Ug$Rqd(dT(qYnQDM&|1_fvG2 zbyT&XKW?g9i%&=Yf|<{~+2KuP&qPOpm%G=S2RN;ku>+D-@+23%*HJ4yKy7;NW=(@h(qk)F&bj>9gk1pno(RKHj z7auZQi#3;EJi59I7yapIw9s(1C{Hn0!xUEYx!O~w^j-E({LiD=9G~GM7?~VxLny;* zuA~Qil(AeEy2c4dy>D`m(+qSyI^|$b_?no~SZ)s|2cHoh%My$yrtH_e<{1sw4$UPP zp*b~SJFj^?hS?hnPSJ!zxABha%l6A%vEW1mUGGk@*blxY7H9wR_Ro!B)nhf6U_7yi z3Kyr7=zenZ<6juAQq3h8dCm`Mwv$+lvVSqm-dM124u`scgQb7i?zbnHykOfwS77;T z6KBRvEbi%X<%!0yDyMGf1mlSX>zOehch5;5lpC%aG?!pJC47J3vhygp>81ZRTy~!? z7>_RYx5n^e&mN5(hHInNB^Zw`Hp(Vmmz?w3D8u!p<`RrY7yH6o@%mhI3C5#~Zxcq> zjemK6lF_A%cw_p67>_QN0TZuZo%!>J4cB1Z3<}1hi*M*g7weAUN@y;@cyw{{&X}Mn zD=C_7xMpcC!2qWwZ-l^2J+#fA(pUNXP;)6Cv=YOMNW!rkdQ0ZP@Ck?5Yq9RVc4l&+ zEd?7^wVZ=3f63%ago)`*%e!81u+vIBqPYa)i7Cgh;ZO{BX4e;Yo_>SjdP#E$22Zi9 z-H8RYqxGvkzfm6GMjvsi=@e4=^mTlQ>1;%r=7q;9URgrpO^w6wBplkrJFepf-;H@I zI~d1l$%l1Hjl+e@t~>Wl+49I?PHK$ST!QhWMohTu*5)@iA9lats?c155wlcwL(dR; z!#qgj%-|i@6Zaj7VYD6QxmwPkPGLSmxa=^G|7Ot(gPbs5thof^3G0GCm4^eq3|`jR{h|rk%nuO z<`RrY7pI4f!L%{f1K${~S(-~Q9$jpMjjqGq+MF<47i%uTcyzH2nO@JEhCkL^g7N4Y z?$Ool_qRS~bUmiI1mn@gw;Q8tP|dju4cFV6OE4Z?BRsm+pL67`hAWQ)a5%wubd7|s z(KUV3m=%VrP;&{!ql-fhQ4)@ z;o7aa1mn?##>Ew{&mKr#ZMgdK)dx;69$hEHSB+9apz6ntbLFya#!xV1x29`3q*bdm zx04UIy4cQZ0`wGkheNt)w$^ojZjmho@7J1(7$y03j~q(8+vDSIX))}EWSunDuS!g_J7xK z9izDfx^7>TJj-y^ zX)eKdbfrAHo=CnKGhCNwF2Q(om3wquxU<_(!*#vp5{yUJWZ@csdkEJL8cN#?*UvSV zU_1xnR0tQ_f4g*=617%y5#y~XY2nh3t?C{Z++?_3(cZ-5;j*lM*g(gpTX%UNH-$N* zlh27BA9ro41fO~9-+9duN7{nu{2T`w0C&&Y$$g zeI_1-Lnrc%>kmi$;YTL!ZCcLEPH{h7xR}f2`m%9mY^D?UpJ^_^c;Y@wxa{K2nK#4r zh~^TECznxxa>jJK<|4)$Q^w01(=$cRE4VY4fAQGB{;Dm&535U0-g$_3jOpyk<+I>x za=FVD+k2hq#I&#G5{xINvmGu z_8IFY$1;skZ{mEX<`|TYardUiIq<<@Hz+a(gIfE>^z|k+uF`VOL27tscjpL~o$uYA zKI6D^oYc5pa|y9$oW=i}i~o z^Zt=*-ZNZVG?!pJx~e_87JUDAA;a~C<`RrYSB-E5$LsH!OE4Z?wH{s9r+>NK=*rU# zr(is~>V(UV*X3&?w;HYkG?!pJx)ykJ?YQ}O6Ajm3%_SI*u7$#N2<{G?SmkqFC!e1cBBvYfOpUT%J@}rfDIaUD^DKtY&9z9l*gTQz&|jbT8^iUj=33N= z>wMv2K9Z{{-3zTTDY~AzD?Yyy*J3;khxiqXp{(lt8iH(d9jv()D=t^d)*xIA3Tw)F z*R4K#u~V0aXfDBc%0{EZ1;X0$myho?TqT-IFnnyCseMQzeOx9cE`U!s#2Ih8vv#d{ z(9Q|G$7n8Mq*Wirw_-ZRw5#=NJU_juv3_1-Jw7PcG&kBdS&IvO-nJ=HpSPq!;jmzI zCvS!JiO?oUy}rr{H77+Im(6L?Mr^BL9kij^4sg}HB~7(6MG!_xcJFdFs1e)3NPp4y+TjWJx{!%-H()9G1seuHLbaJ$+F~>>9#y4nau-VLYoIF z1jFs5HV_XUgEvtef0ZJqPftv$&7|iwWy+Q;X|PQc zBeNH~a~ta=7dA9y<}c%_Njp!{4GrftH%@7&aZDNOSi2v1mAjsFGHbilsk8mXDUS)fp2Z?qATonR_^5^O5M-%*u zY@7MT6RXO~OVSmoI5x1^CVT78Z=^;3rrISJ>TI)(K~F7BrzcgErQ+D?=0+>C{z@MT zK&An9=Kb-Sg8X+^!ZCL7RB3{M8-%J0dqb!KJNi3i>*{P<&4HYHV1N zv3WIR0S5un7}f@OXS|e5{=;qo-C>mR3|DMTe_}`R+tzYn-m1 zzhvH$Wx9PsLsGS*p_Ju^D-vqMyIQ)swyf|RicLr|J`~Zb^5ZV zOzru}`X#m18CXhB*x{QJFH23Ws;W$<;_jUSidz?p%J`Hilc%JsDkjB|_3R3{fxri; zEGe%_OrDw~gk{VHnP0xRK2tw$QT@fWHNlCcQxD!&q&Jazt*RK+J%mXuW` zk@|WWJx_6{g?W4C1PT(5jNwZ92_sptYgE?RqU4;I1#*Z@tvM8@xX|Tg*HV|4T}NGB z_8`#ZrBK5<%kp^Hb<@SDWEHs?70QLtNn(6-dX)Z~XX(t#G}N2=wS!U$^p2)$S$Rq9#P zy@jtCm=zkgxA5JjF_cdy;d3oIrQbBnC)`V%o^a(GdaiW25}0c>Zf|<;2F9NDb#PK; zsZlvjPrL@)U%x{hC&nU}avOk)Zg28N0aN0~`K)B}L(yDdmTDZQQ-bo1(_L3;3`lW7 zR#3SS8a;om}a+1Q;AtFV2aFFMKRlKL+M*KQ18so(AS+Kh7tQ>4#(Pt^ECb zdIRJg4a{&q&L@xIs{&@O9~U6+a$vsa$NA(je0Kr!h#waq?=@il>c{!yadI;fMIPXy z%ay;>dz{7y5VxTGWf3^Vhm-vE)gyi&FW(1T1#nmI1MUXkwgFee1c&2fX0CFz6quD7 zm#bW{zTKfQlt&lT9vlh(-}-RWi?;heZ{2h?lux!oeHggXlV&$AIKOtOy7SPfrrBjn zaY)_bd5fB6FRGu9u1`FN4IMdj_`KOo4b4lcYiINH9lKxpUzs-5`(QJL1+sn9*$4vL zT;*yjV5+5*I|`@k9fjBk0<%ia9*AdB+0r7lX%gGk#J=eqy&>dzYzPVMU?h{-(oA+b zb{AIIy9=AUV8g`fZiZ3zMPR$^VSw+CD}q?T*tk&haA#SHSe#L1&0x1-S=Y;5-B{4o zz6V9It!JBoJ*v^JRutz{+UC8~VSq7x7GSKtDK_P_bXvAs=F{xXe$;+IMvs(-qrZVct@i_e6sJJL$qs)^R1QdI=k3XEuUz%MYwPK=9j6uTd44v69q-ZhN$T=7Ok~js>NHi)>hkEYPHp1yg)@oYwPW6OIvM0v}#)w>m|SE zd1rR_?4C`;rr-bP_xp1upR;-Qo#%aL=AD^$W_M?2&F-hOHl2gLyPjJAddo|EQ#2G! zy!6ySL*g%OQ!O>NQqthu%ngM)vNZviB@DU)&~2P&Igm zXle3GpBtIe)+ZVxi}A`Q-3$F?hU{*o8a2=YTs0dV)H33V7KE=|iYP6ov#0@x`6)O4Xf!I3i`D}+I)#-ON7oR1RTNE{ii zSO1^|eiOf-ycDP?`qn(*5k=ir2!rtIJz02ahXa<~(aluD_yuJXVnxwbN;e2Q7o@}Z zd37tKY`8MvAY=a*2X%5!FQS*?M_m)}+q>8GxNYMI_WKauw0;0`$!&jq_C|2*=I{HS z^|^RGZV&dmN^0!#+Ur(G^2NAklNx*KTh=>(lDDjXD+$>E?iRKMEbe6zQtfSPtg5rE z^OAzBO&OD>o*d7eIw|YX&P)2Y?p&}t*t#<(Yty_*fpz}|^F=VWE}9SmXB8(4b>;-|K; zR()V4&Q%{+4NCQa?}Ji(g|E2qp<;${FeqL;VOwlas+DuUjb*}H3W_sTE35#a+K!?! zaUK=kNDZMAU|@T9Fp6S(uf#8C#GsS9t>CA(Opt1~-NOWE>1L{qMn$oWD&5@pi~6nL zr&|`w7$Y^r(%XBUiK1>R_~}&(Kh&m3UnS4fY2|{npYBTVv4?8*Kx26I5ytR&ha1BK zhZsW|i8qXm_;H|C{S+TH3^gndsZSb)?(mR zB?g-9XPAsmM9i#B!>=6n5R2QDwTYWfL`>`4C2b~N;8t@c`s-FIm_-HHReU{sd4Y*7 zBd*M}w1oGhFgZl3=>ZbJNcZY5S+|$v-!~~>JjUwCD*eO^l#FP-h2VWIJC`s?DH*gOI znt5A2l%jQ#BKGXpXxf@VFs{`SgTQs$$C0{IWU#RmF|Idrm_v7-dAlGO;8cWj z@^73m;pa}Ce+dr5m%TMwJNA#bi(=*ZX(iO-TcdQawB1b$9x8XF{-CAk+TAO|PYR!4uK#T*QzECbWUBI|Lga5Ia0@IDZ#kX zk`iHe0%f^-JFmOlk;>OnR;lp`Ce2YTiutHW;aKm8GFG+278^rO@_HBcpuVpW1B+^`i1?@AzPHYjd3Co3~=~o+zqD} z-|Mt7>z&Nu2K6NO3r<9wx@ZdC6&r51u_IO1WwPS-8yvcv747#F=N3CsxmrpvuCxwz zrS<657k%B4GPRUoT=jm4NGWX?H19b$(~&wyO9{r67CnzsuG_{hYjLFFT1qgkwAi|O zD%Ur(lwe$Gaq8ftb=Y->PIuDUsHFtsO6zb}x&CnC-A#_vCM_ixS6WB7(ki;Y<}*iX zo0bxcD=pqGQ}0%>L7n{d!yj{`c4#TV(5rh^rY83SxpL;$cO^VK@-_^2THN?h6T~Po zn+`~V)p~RFIoqnc^&SmQFu>bz41by0b)wUHbG07*j%d;?xnqD01~{!|SX}+bQI6Df zEp?1)^GQ-6V1ohPqGNb|)`dw@F)bBJks1kXFu;igOZRH|{$rf9&eBpNl~mGA&0|GM z`CG%d>SuSYa^CG+p``@ls;}d0DGMksjsEW zlQG3s4;NF|Qc>AC^3nAabP8LcJqdd9q_UB+!*!sRg-#L$AuR53a79B zB$KMyxGUlf6Hom5!3QO8*Yh0X_HC5+X ze5;TxEwxGOINV%iQ|ANn$yn!G@QSOjUam5zQ!B|>FV|aD$yleRlJnrst*4#@Xf@aW z==<_ikCu(E+Sk?D&vB(kSTT0{B+S)5Erez!<;{Uw7|AK`cdx9hug2H7Twj~-={fAA zoZRvGAqGB&y-S|M-WUoP^OR?HUAWL6aKo_w;TV-1e4fMJfcW=0DkTMZ4(s_^=DIHI zLx^!G^N$KxfPZ15Jmu?*9Js&xC&TzDehl_cL1M^ca&PU&NV0L(MKKi}@ zX7FEB8a?HYL-A-}rh0Kc`pyPsxfkcjAN8#V<_0g$N8cu39{1ur`dDu}G)9#~+c{}C zCVyN2-(>*qkhc_ymry;`+hSl=YFrSwp6cy#V6OM#e9G}4Fr8kUryQL0{Q;Pdyf`0y z2mKX!$B&`6{GATWY%k77UmY;3y*QuzT@TEUy*M9z+kkn+i}UDXJNQUrq#!u>Jx81Z z{@}miwF>+gP>rhIeCoFhn2UD`OfE5cs^9y8c|_xSv)`-0?DFD#$~$lu?ziH{(33uv zcRVn~UYw7B-Jl0P`)4>&Y%G$4@kd`WXDm!T$Qoy}-GXieV6YA zj`f>J!KJo8*6+7caQG^-r=9Ww?xqwR^m*Fp2H@@jZsNNj5C-GdQ@z~?%v~DSTfKE@ zj3~sxuihyC{9fRAf%;+!F4Zo~_nUq=PkFBg?(e{@|2qhT-umTzz&xaJJ(ZXK>i59B z?Zx@{tIYQ>zr&BAH+{Ll%<$rT^i>1X=*9W?zpFJyrR-lHEXVaJxYYJ?8*ujmSMt8n z#`fJ)d$|~xc8%+;ymxDi(&(SRQxN$`3NE!BuwTBNfSF4 zxK#U12JTHioTnVE7#NQJr(xXoFO_N*{`J%jPQ!icLVfSLr*g3URRYuE#rd@RZvpc? zFV55Mhe6-3fqB-8^U=2(n2)_Uk3Qz_;ExPr41NrDIehfZ1ZJ)m=h4TTd|v~mL*qEk z`uRz==kI6?NC|%Jst_@^0JlS9duz{`AHxsf$6%MklRvhrT#XSR4u1JN9~qpSf-6rM zk3K*{f8cXVllmVX2Aro|u^hJr1IC;9G4xiB{W9=H2K*R$E61rCBS0Md?6(1GP6zHe zKH^6>0KcBv^J?tyxnA$`*;BgNkiQ+6r!FW3bENqpuj4GrTyDz7TXY0P{_a>#07*0e7RufRrHh;hA5tyie~1E(f@m_W~CJ zZeW%wD@X}`>C!)s+6x@7lPmWEcL;E6_5#Ow=QmSuspIM%;I0Sm>S3xZy^U|3z--ev zyM8_O#&Wz3Og}C)L$Gl^?H~lqSTD{;-z;F3d2v4a)&X;s7w6H(c5tu8NCt86^DifX z|1fZGX)H_AQ~!Mrm`^p%F0UtD`sc%jd)rHDedIyGNZ{si!4d-fO;72bj~$1`+Ww?eusW}{hkQSsa~8%AM-a4n3Z0fPyQ|k=2|b# zqmSeC1Hf$4IOfvNkBEY_oKHE*fLY|l`PgL*Fdbf;kG>xQ z^9wJ|qmTaJcN!xZ#KF%lywCLpaGz={OVg8G`X3cA4#1DWF0W6zr)Z1-aqvr*L&s^r z%{W@=>+L?ny})eJxSrBweY~VGUzYAp;66U)%hO#H3K%Q!W9Tj2HjPP67Y}&;_ukhy zrFda^*_?Tk%g?CA>%8;$8b-+BHPx)B#T&*=b84Df>f$~TUV*B*n#v|G)6z1xWm#ce zWplG{67#XQLs89gyx>~hlYAkT<~20e#v#wSJ1>b7_?7nkHIt;rZhd;wM5?WEMFrmC zuB>ZVA*WycAP*S7x>&LVTiS5^-ezO-3HbgI7B{9t+5%|{q%DxPfMo&t%|83@^DD8- z0G3zvA<#b`h(Ye-wEymd71N?=3#2WuFIj+V5BluCmo@g)edE<3d=3=;+xkq3w+SI(iYeUEx`NoefHn- zPEFs8$NM;Z-ncXEzx!s$v~=16X$$N#7T}tyKKpOHp_{Pg@{ufqlgSTuc1l@Zb4;G#JyF-n@1wm{kf`?LkPw`8CF_p&wdn##VJk^Y(cbnQydzx!s$v~=16 zX$$N#7T{i`efHn-8Iiu3jBCFa;{M4eY5(0fL#CzE7D!uQpRvIHC~2SlcU^PMf4cRR zW#|xyv*5q~o%Y|BNz(t*7D!tlZGm1bFch(U_TS4IR`;67UPOj~Sp@(6S=xW^g|*U< zv<1=@NLxVdvE66?T~*tJeR%t1PVSBW9Q^n5`1ytO^GiRgq@ybNnvcHw?}oZHD;nziVl?{i#qi(3^!mZR zm@zGzwm{kf`;Z0r&6_^^?^O-;HEa52G`_!c2<^GEuOYO+5-EE1-NHapZ#}LZFQeMo`yWoe}4n_PZH_p zm-|Z7OP4ckfwTqsXaVlI-Dm&3s{@uqKO^c^3khZ|SVu3?Y z&_4U`cuV3#2X3M+@+q3I7%U9lx+oIpKT!|A6oQ zDDA)dWXH5{+5%|{>^m0Vdoz9Z-_@1zzRthtwkP9oYubPBJB=@0(zFHA7U+`&_|5k| z`)}SqX^vN}YW&Z$!uuy@!*?%A`|tnUh-t~R1=1GSrz~(dO8ejQ-~ahd6#DOt@ZGni z{r5iA{?dg_TOe(L|J(vcK(x>P8{eO=X*$2M?my3l!T0!Yhwr{4?Z5kA#k6SJ0%;5E zOBOg1h3&KdZm6y9tIg=Pc`cBU_TPOqWm-OMfwTqo5epoJa`xGOx3u)xfph+SIX(t- z1wRPn6Zn3Q4?E3DTOe(Lv<3EA3mlD-_t}3p)l@Y!^=%4H|Gbqq!Fvd4|J{RO((JSa z(iYffEpQA<-uSgX?q1Ry@9XRH^8S2pm5}z|y;&z6m$pFK0{fx`LMU{f{dav!U06>1?ilbRybQc#nH8i5zw6)yxz@m|5l9~5r~D8;)0FXT@WiH)H0 zl|DQqJx%EYb*j>LoMB89DghH-{5UZ{l~4j3U&T=f$$ zURh-rT)zo@pbi)6hGvVm5ftC9LjJI~I^UCpK2Y580QxS)e(6GmKyeo`=v!|X2MM(U z6i35=alMo_BW7T#?bgC%w;s6j%F_>tPv2IU1cP_^8!}mV#1k zDAvI^!|Y(OjN-hlyZE02yNO?hq=m`@#gY{Xg=@$)jWx|i_)N3)osikSHap);d|+1n zyY0nGCYbGuvvbUj8y|w+)<^dI8;`={L(Rkxvu$g9K)0k~Ue?u#ShM^2mN(1<;R&i} z`zSuhOgyJCtxtr`>0+7Bl{6RH)Lc-gYCD_0N?I=WGChb^>j*b?T_!B}EnMsCaXC*OWKbK4x|t#VRs8 zPG(D{y2H$>=SAICX^6pREM+PJ%5=oDma5abpKk3wcJ1SNooumTGr=4t>axq(b{Cpx zt&wvgOCpQAkWrnLXz+>MFPc?Pn;q=phUS{V&AWe<*SY)g2JkxY%P`<9G=;8jgoSsz zP5la#!u`&s4u|o=ILk0j1T~JP)ZuFUSG_?|nK+LNZ=^;P>Hjo|gHaTF!&UeNjsDO{ z-B$3^d!Zmlvi(;Nf`ejO%17`&btx&fS4GidD*f++Vj5QP)4vXpPA}fOd=o|8R`An% zIU=EVFuWV`-Ty1)n|iIBkoMEBN*FjO(>N$T#5ic)VB?_NVLOIy->);$x~KcnU|wez zh+{84I9k=2(l`*c^Vp&(k6-*MV^w=co9UuM2;-N5E)vVmG~4H84~w-IWsivAG_(Mo z7;bdU=vZQNVo=_TZChIkq6u@Q_UqD$&BS&S{bhuiC_)2P4&O{{=`PPf^UbN~ijf~l zWI}d8QNouQ>l#W{ot=;5UHMb)vk z?>-pCiA>piag|xM-L%**m~Ah{&xp2{k2VuA_V>lvpw1d$b`+sowMRy@PBP+|-Phg# z)w>6DU%L_iixRJ>oVPF3MLpuH-KDV{lcMQWTr{O~M*qnnKIfRE+R@PV7)imLMbEv){w5+nZ zCd3G%d}dQkb4y)3RNEX{RomQLTfZVybAC;IJcRu}Dvj`5wzty63ufX~I`#b{>++5G zz+bX-yZhyBHQQc~FJ&DsdMZdKADt8NUqan3&msT7=^xLaoFRGa#uO zPp4Yr;F*=GB0DS$L~#-fB=U32&XvW7mE` zc(>WS2S7b1yr0`V5RwM}GrWnPsx?Ki)}9ewfDRqgr@^@c8u^r&k2>UT*RnP7no1*H zvpQ~^U)fZ(va-oo)+qmy?xrQz@N0Q5nu$+}Itr#*)nS=B@w`|Sel&gnOr04^bUsWQ zDX!&H9nfL6;1+@8ZEfq!x^8oO31-Y1m3Y2AC~@tDaIKsTOT8Qpt)JqTA=B7@3pEDE zkA-4wd?eHi96uClHjXNmweb((EyGdOA148vX=NCf;P`i;a4_b|-W^n6TT8ekBEUH6BSwmYU^ zIpPf@i9)meA|wu8QpzO&9}4%BVQ{W}h)|rp9xPNnsNq840?)ujnH{=8DU&FQdF8x? z^OAm;S`82+uQ3@It8jGtiW&y$0FfZ-Qv9r-;yGw2iqb=rZe9s|CEe6%<$|=IZj}o? zThA$LiH91NhgQ|BYG_&$s%dI!Xi{#D)A(VWf~#3YgyZhpxWL;^Q`VRtXd zd%dmml4;AAFV8w=JtN`jin7bK6UVh=;v*R+w#vJ8nBr;km$^$iSbbe%esb!^I951%PVW^YN{uPsv27A zsxfNDL(6OHt3#uXZyseFkB%`RX|Px~84de!_>xDEf)THSp^6OS;Sf$Z^WvNi*CUoILS}wu-VdV&eG z-7s0Q676p>hOPez&Qxt? zwcQ2!o_<+v*YJNvR@*xKFUpT+hb3vV1C*mp8htdY=p)Gza(r$yQJSyE$ynkki#^xu z#zgPw5$2RPvaVWzM^1X?qVjGgt`gIjdD}$5yzB|uPF;jooP(i8d6nG*lbe}i3Z|)T zvipa;EUiKDGK>OH)k4j)sTH8Ag!f}ms{MTcYMJmjGFJ#S2uH=Eqg6bjmrLx~II7l3 zU8?P_1f|+(6DXC&MK-knR4aZ~C6Ac?4OLnUcpG8F$04e&rhaT_bSM-mjLa>@2wprp zbo{c0hPu!^l8n$w#Ya`d8!F($=-xsS845+_%!!co+>1Vv*!PNAd%O$(vKtP>}|+;fVdm|R4AVqsg@Ks401tO}hT%5fw?F>-d< zJO!w2u5M~*Y^+JvUN)zwcuuI`EJp>T#=s6CT478`EIxaFEJj<8VN*dJS2RLTb0{R% zQB|xPK>fISVx)1^k6TT;zPXVWW@D3c6rATOn@R&|wjv2y(}_xZZT<3wrd2W^Ry0?w ztXWk#t^#JSS>1@+4AR_2OP^b`L|59FP<<#?JY$}!A<_8XQ!UlSGO{A-b%w>rENpbH z*jlWm<5cCb+wbm*ZS(Y$v3 zE002R+cgh^R?#D=4%b6NvC*pWSnY(a!>KVUvTM&$Bq@sDQ{x7E1$fdeLm|8V;0=rg z(Rrrj3Yy^-(B%H(jy`6rE>hnWq4hRa##jD_8S-!YW5!lBtZHm%u8r5YGx*hOtF&u$^Rq%ehO|1{gmm~OP}OB(dvJFXZ;s}~I7+>3x1Wq8p4{Cp@g#4jhz+gVDT(i9=fjq` zt+E4RkqYa^%95_babANcb!A(OvkYSnjvd0Q1a*~A%R#A|8+-u4i}eh7yr!;{JHb;| z#jk==SIU32d4qsfIBHNWXEZ2<LG|z?l_zGezA%Q54%+ zyYLPhGsHM_!YDi;IMNvQ{?Hx!Z6Dm3**I|NfN~{E)9~)Px^YlGv#O!KzQ;$Sx~-y} ziUnPF^Fl~2mbf#U*@`4~@d5ryJp5dY+v|C+$J(p2m&Q6yW}30~UuEY2w85SI*_0wb5K3SaCowrrj_(v_rCf^9doxuBpNTur2Ql+&t z`1$S^OWWQ|=@C}~hG!{@+qzStRw2sDTjDuMD27Jo)2#}L#IvoH=rk#6PC#VayKB5% zF$?S>w#?r~6WgMRe~EtHc?{!TAXu^X2eVhhLbxevMP2<|KX%)yVXfW$S`Li1uFc+K zvHhh(ur?d$v(4KBe02lWKk#Qp1qv5uQJ zphCFng115QkuB8DVlHxPy^6G2@(_`S-w~`)N<0VHXlREFZkt+}TmN;iB8lRut)0iV z2eTe4%3k<%>pehmIemNUm7tjI;ZfXU+GDo2-T+24k&(Uo;Ar9sp4hxAHmWoJ;~mZS z=_wj{hgG_8$93835aYgOi)X|HFyi3|4w5TAEVjfPZfkcSt8FDLD^GKZI?94p5v6eM zLj8!i#5}Hp(l(P8khT6giHK#F=XHmSfW%xnZsDek^Oe}SDEFiEcJXP)=@NOzvz_THkYV} zGg+JZO`VkWXy+yUTX!zl9crFbdNXj zWG$LFXuD{}(z6G6!&15MLQrA+GK@2E{EJY$-%XdDVO)UY<4~MothIT($FJP_EubEg z*xPL$A20k$cw24WA3?EmWXQ97CHoKX)X>5E=W6Jn(^o^sP*4hY0;o+Q%Lh)1Hx1O! zgvYzH&!zj^3!A8eR*EnlkVV!+NUz zs7<{LYMI2+fhdX3KrufV#>wyo>;f6^8x~b#QYnpM$9z$^6e)h2!0SMGXUWk4P+rUh21k zpYHE!-3n8SGX@Gd={qSXy+l#B75wzxuJrQm|5wU0by~R~?WbGi;;^#8M%lkkFop$2 z8H2VD?Cjr|u{2n&o&d1djDWNn$V*$A<00H1J-@b^_kzZ2Pibhv$%>kIsHveP zURz%?SwGz6UESm5fXBSKvPO!J0Bf4&VaXJp_Th;zZt+!B$^*n@HKDqi=H^fwYpg;S z)-*Nv;B6#tLt2jzt19d2Lgi7t)m1{P`{AR#TFXgWH0p_p zhpTtc;k^q5}e9Jm;)$Hg>w z3s(z-xvs-h?xnl9?afOX&5m2?98x_5%|OjsUlr=RHt!KoiuXP!t{TZOcHy`OKP$W@O_=RmQS5Bn zgePlZ3r2X`( zoCJmrFosSTYz)mEygjpX0G9A=jc0SMUnp?~hNxG$N=FP?%-QN96Thi!6N~;S>r<7v zn8Zmu=w6jjbq4iCcHLh!j} z;x#<~F6D*IC;I9LOIFQ}`5Vw&-SZtZOf;Mt%%!;AV97oGT1xN9Xj!^$(zN&?*07lP zt&|0GVLq&-!U?gC;vLYJgBgfhACz(N!UX@t3%ibng4D$ey9R=tSOCkFnX!)29nhX* zV%pk>!b#Gmbgrzn&r!_0*Ub(-HN>=Q8viApx$>5E_@7_8A?w?l^RehWUeLCcQ_?VW zZQy)ow3&EX&&|xNVhr~k6o_RNJ^%0)5Xm#OH3PJ^B{@&El_Oh5*0;OXUA)7H7nsOd z+w0JYy!q)Q+F$2Dtt!^h#)Qp|Zxidj&M+}|VR_9&hg6|;fqB^ztYVq6ELzfa*+W-B z0XOApxis(fr$n8RzXT=kTDLYkY{bvdR*~|zy{>Yq>?PK4455rbd-RxTW|q0-|K!~6 zDwR2!TA0U6jcGius_7eK%v5pSZLqdJa=KaLxy#NY}*ns;zD3#iKpwxtC6k;}u>|{_X4HJ~oyd0F$ zd?~1Y_+=RDaa3Ba0i~vO4}ntCI$kTP<&ekP6y@@8W`(~Ybv1!f6xy2cuJB|6Rn0OR z#yfIU6DWnF?^YCjcehB;kx{=D{B-|Q>sA;`FGme0eJ2H_mniDCf}h?`lwMAtzEYm4 z)5-;DKiw)9hm9VHJ0Z&ry?7$0UpeuH5rQ?H-hM^kOwDAkM3YwK6mG~ww?eN|1Up|J+btuPT9HEq=7 z5Ef?36owO!5N;208iQ9LKFQk}t$Gz>MB;6IW5D#ebukD=ENy!?KF51IgMJ^~c6JMB#-EFU{_a&koOEQ;lh$Xm!IA|v3 z?!gTW(U5o_Bh5CG*Nt6R`tqcad@Rx|cf7pF zo&-S434Bw6Xa!BadnuQtiT71vPsN}b1zC)BFPJ{9#8{paSyFLM*Rja4>TcseJqBxK z$m^ntHv>F%RmKrt@wlv3U6n1fc~^o`S9!diR9AVNYN@Nd+icwPpx7KUWch2WP&qhm z5NaxpN29Z47&Aegjh_{c0atZtMP(x50O5_)5WK@Ff!)r*D2g5XC_xiN-B$3^d#KXO zg}F}*5ul};sX7`JMOUG86KWwz`{`E5!0=3C_`Lm%;S=^VhR?z4LXAU~qD_y+B+T1R zQBR}o<^Q}tF4bwuB1^pB<60YySXo^;x+_tRnTVM>fkX9&A{~VR(MqeR`aS@Zs@r2g zsd^j(O4VaNC{>S~tti}lP-+fX3W~##6(-s>r6}5Lw5}=qo1iWlkJE6*Djaj8C|Y!a zNDxK+R`An3PU&WCeI?!0Y2|{npKg^4S)x^devM}*#fdGk#N&A{a>__4RU2Fyb}-I{ zATO$XYK0yVhA~}oNWP+2=F^2|E&g)6n|`}%SKd}xjQww=AI|6KLnf^j3R&RQ)^ z&-Wz|IJ+-Fv>YscPhC_c>4rbT%VE#N5>G#jY{S1jt6tmWJx>#s2!p9CA%1C$yu9TV z09F+SH_O7>D>*6gqK@xb!YfsD9RYQ!nT-Oan&?=YHw%<I8K z=_&`qhd#=|fH1O>96{8sBt@~3I8O;0flZmlCcHhEHE)QKg)644IYS!%->EPb@herB zE%1MNh0V1qOi`?`IXzZbm=9~m)m9&I%e}Y@&uSf4jj2og{2GWEEORh$P*QUs7w-mE z*DPyUkuC3vLp3m*&Zh>|=gAKl#HlR-gs?eBsZ$&+44bqH7H5jZurX!|hn`mjOKQ2r zu%&o6R|N}`uoyPxdnufsq;R@YINMV=Z=`VEN#Stnu7Z`H%z&43a0=)66b>H;y7lmK z$jvEB;Ve$!oSVW~ox-^?g>yp+=dKjaPg6LXQ#jjGIRBHv*_p!mFook>mRMFDrWzj% zVsYr~-1Zrp!r_IP8#60~b9M@+Hife~g>yv;=lT@R9Vwg#QaHa(;ru3r!@KwHQoNbM z`5=Y!MG9v~(5q)e3g>tiXPmq!tE3na46N(Ig*vE%mpsBNULA6^lwgc;vL;gQTYFh+7(xbX@pE3Kk6Rp&cW&ub~cxYFXINGGkr#_`J>sa;x1 zFs`(C4dA48Vqxv=j#N;)e!;lXlDq|Y5lzKgi~q97k&;a+z*YHAF4z99wC=xY`Rk6< zX*w;zxY8ObQdU}T$BsV0kvc<53C2~fELU1r3~G4FkvdOH3C5L{)Rf(#7JTy4?>SPf zTFRQm%1YN-(apByVmEN2?jXxqK7*>^VxMytGh#M zK2o*1B#+J6oNB9t{Pmo%xDQKthD}=PsFb$Kt3s#j9k-ph>L|OdKB1)q<0?C^$(^>^ zadX4xj@0W~N-!=vhg@l8cO*V_r2e6$1mj9;q)1twmx5%($5*uO0*O)7}1i( z!Q(}WR$}<@v?qV>NL{X_h=DSM&6=Y|ShgR_Yq8$l?dJq=f`JYk*_FTbo5(e)C16j2 zisfI6*Mo`8&qB;k(pbq0TgPHUHk`iY1iK~tUZ*Y?m&Hbllx4Bjs-eGfr2eX<1j9s) zk6oomwg&I*1OxQ440S8_JKHKbN}<`rxNUeMIKhCj5H^DwG!TQHb#|hbBE~Isl1K$` zbb=*SsHKQ;j}Ek|+slk{Wb$ zMT;Z#BP~UYTWY*W>27Sie(O=6J5o<;DPr7GxgupXi$UgDD;%jmYbj#fQhBblvY$8t z1GQCyUuY>}+)@)n%4(~(9+8<;uER8&7`GJtw9_(=$v?EpN$WH%MT}eORFUEwjNzdn zUz_eo&DB!GNE<_~sK6HGZexrJ1~%ZxS>Wu=`;B(mSc}$kT1p$s7b&ZaeemGAQ%?@1BgTxY47*|?_B4stEJMMY)Uyjr(T1qg$VP6@| zQMHp?%SEDx_F;H-0|B1W~JF;;W1Ij6cf$ydk4zyt%g;YfdX=goh9#;N5Z zEmfRS%QHmEs^#H-``hwjyO!r`DZ#j`F;k?hQatwAA#XZTtF)A0T%O+)Df)JX&PSia z96*&5pO4g1#Pl=D&%kQ4PtmVf?7?#lNaJ)K$)F-rFzHAm}7nw`!P zJ-6e?ezE)6CEs=|wo6ORO0igpNLd#9V8_axvuulfq@@JovRKTP0wI3Pks3UNJUm3j zPx+%`G>2T2Jt@zn#01X5k+nQz(3l@Mc^<2!N>lPYTcoT!zq_+`R;iumQ?-;}TzM`N zDXYz2bN{)wI#M&Wlwe%7Q!Y~0@DaJ`Z`oE&7{*yziWqmDo*`27w+!PxfA4HZ>N{GB z7*(gQXijRK&H*ME-~){;Q1b_uV9JRT34hg6b5iUx7xB(K^SQTv{Es=deg37T1mm*L zJdv_|-L02=G|iD3LSrKc#^rzJgX^SK_UoZtj?}SQN-(ap&J?L(JmMEvd+Y*7YLb=` zj4Q1LuC$Jyedo!JRJoQCj4Q2$B4w3p-e*NK9jO&sN-(ap*e0EFy?cGj-yNw-w3J|6 zX`z}S#j8u!((Pq4f96PiOG^m`vDlALb5y;TpMeFcJ$i{nz&l>zw(<+%#w>61u+~G2 zZc#4HOzW)_&OdFACDng_A{jz#&q@7sF?hiMM+Ewos}KAhdV$prkJ3_$Q`#X0gCrXc zeRBBSi|uxJvX&Bz%ZBHOl+{niUwY+fj#QDB5{#>#R)`dC2uiqn@Ek2)p&sg_!alA=zNW{kBWWtDXG+vS5+ z+9mDMQi5@n^jwj$yiNCgKN#vry`iN9<4Ws1S6Wk_x&B^9>SHY>7*|?#B4v5eEoZOa z?noWL0RurWuC!Kx>v*=VlAnFukvd6B3C5LHy+~Q*nmF!=xFc1pr3B+jtHG64_5;7I zb)+h^lwe$GHHuUSM>J03s4e;TI8qmADZ#i}%hyC|9F7ddn)iSUUKuZzRk9P~P zDUHBzV7)Uut1+bAqj?iJ>RueI5He_*-&&Q zE3GHA6fth83&2s&ttfTi;_;_CQXgw6V%$=zMQR{L5FWkz^DU0lXgVMSV${|8L^(GM z_FVVX-x_d&fjv0VMSpzwTR(F8aDvFs`&NcBM6}f8(u=)J82O7*|@CxYGL9 zGYgM%q<*QT1mjBUQjyYCWgI!>+6|7>b}c0sUYl1n(&Q3Cs&-i65*XpGops;@11I6g zp4)ZJ1^;qtXQ$S@E~R!Z6Dg~9j7yHZbDdo~A8RSWxJvPLk+R0Y^B(Ft%8}ZCI3f`Q zqW}S^OD-nuWq&TJW)#t#+Bzb zk+Qt#*56DR=}47nDZ#jE`EplU!4K}PaHMLrlwe$GT_IAeWwzeOUmLy3k!saaf^nsF zr7Nu&^-b?MQnzR+!MM_D7b&Y;LG$uOj?^!-lwe$GeZ!U3xSUI0a-?3+Qi5@%l@KXw zj$QSWOD}Syc4;ZWxJHMoL~1mS44-b9bfe>c`W>ja#JIgy2ROli-QLfC@L@-4ik2eA zEp@d>9gic!kC#7)>8j;dFV#}SKq_fI_Dyht0j_`Lkn;X*L*8=Q;jgsRH_;9ul{8D) zAW~L4>|gWd-@a+L!);nhFfJQjBT`n|Sg_O_>`1+(r3B+j>snV@$6vH(M@tFDl@qyPi zY{6h|TvbFTV;VM^#Cv(3-DLsh#g2-YLaDL%$4P zZ`V$pmJ*Ds6gP+zquFy`9JhInBlUGHB^Z~*(4dpjn(&9y-f*OD&{BeNrFD}ltxGN$ zeuyLWV=W~ZS6Vl_()xMLCl@$UPiQH@xYGKrNLe2Hg-K6lIa04^DZ#KV>@@?lyt^)L z5j{ua$Qo$c|2RyIt-5$u>$xSRE^ZYmtEU`x-1ypC?7HZ8Fd`8IA=lKqBoIDq`zB|jw^UYe%9VvOfQ>2pf ze21Oq2eg!6TzS4rq>}UONNv+nf^p@UIUHc@LOh?m;{Hj6e81K@!9-soaQn4FzZPpn zC7m+1rKPso)?uG8hI^qmonKjJ$GR9q$PVf8%2kc=3vG~>=fb6;ghLFLNY&WU_K79! zNkE@kv9=r&w>7S+tg5W8R(7C)lFunwRjVU;g14dLwi^3{F{>KtYu4CN&Kctx8|v1q zz_#(0ZIjO>9^1M(k=6-gs%o3yhV8hdQ^qc9SZzmHH2HPSH7o20`$SS|K<(I3*hf{L zi8lF6fR#t}(Ey$?4*PZDHKZzAGWneG%j+5{d>|^v}q=YOfp{?CY7&}R;EnFr}7nE87mc^%2#-0s8oC^-!VlpI>``8Y#PitUA9Jh z+sdXD&CM-%@6WP^N+pS{jFG}tX{!oKL8q{toF-wDGU{-3^DZb0m(MPl8Jjs{W|+-; z`b1r8B$}sBtZ$e;kvkzzpD3}?_ASx!aB-xlXl8M&By4TmFnwYzg!G4YrcadKG<_nM z!>Vq>ZpY8@MC+U5m3S4hh#%q6?L(RxmlS0uWmwi2F{Zh`5xYC%v4Kwg)S~FD@?z{~ z8=jtBI0L=XIk10f)cDwp!h*8m!qV{c2`UFVBByY6`Rsy-SqO2fKV!d&h6|b-F_b3d zD2bVrEr+Z1<(17Ujg%M9oE64U>`E!GBvw{jR903(2jYsEP+D9XnKiR$R+w9*x}qi) z&YD?VFmuL?u()qm+=Rkt>CDp7QdAhe1mlW2t*m_ZjG|a18rI*3amAim5G^i<&MFJ5 zkH)y-V&RflWLEKvl33Vz{Z%1!i(bA8TZk-gNVW~yxy?;7P7)iBdYT&I4OIc9ySH=no!{tRKv67PF!Z7OJ{k0Y+gIpJh`!`6h zvI)k-OlEGpGTzc`HH1m!(OHo~(<}+2$*B*#C}Fj!v#Gux)ohh6H`~is-7}SM^-q6% zPKq9d_oB7+JZwJJKuP#P6K$q~;&93AD7Ko8m51@&lj##1mZQ7Lmru~!h*YIg&Uh7@ zX_cW)nrhS;_Oq@!kAq-LJ_BMGIhC(7l@g)zQdl02#>%2)CB-FS^?4EPBqpj4j7*=X zzA!R9Z~8>}#)#c3C&tQV%$QkPQYL+u^8uCX@-yn=E!g3d*Li64SuSrsf)!)2h=XhSgYYh%Qo*87?g;EGjX}%fsrm@aYrr0gdSsD=q(5 zSORw@pV6?HcCm^|!ZV9X%VtJOXM3dU0p^!9rf1KH;Wyi@L(L{6dvvk}`VaG6&X#PK zJ~!LLwi={|t=iXke{>4lYP}vMN_UP|i9&m@+Lmr^Ma9gyx=$6dy;<#dVzk(dz)4BP zJMK$&+d{cfVV$7C;u4{vqPYee_SVMNR8*nC*19>=ZSncAQ?+SY&o*2NTW8qI*G*ui zIWt@kolzQ{SzZ!Wd+K6Pt6n`l2Tfr51ninLePU#;GzZe)R)TA{ff?lm;j+@wvZB($ zf-v`=#t^FZFUGhCx$MH|^oi3aT8eRw2F1;R!v-H=`s6=_t@H2YV{XA+>*vVVTxy!m zXsKyhV>f-@II9=kHEDk{?}Je z9}n+LPlB#8ePUR{nCUiA+do7HF%VM*mk=dn1JxkkS(lT^XX@XUfTv!F0iYB$DS z1x_s~nOPP!i^{|5CWy*7=QGtUje4GI`w4Yf;fk;tWDgQ*uI?k@6QNpGiXy8Eda^{E z+_mL+VCT@wO%hH5TPrsi%{z4x&zvwmC+E~t zPeuI1+*8L3d+Ffn%T42qPnXYsHCui35_gVW+X3)=34Yk{!5szv5rX)IhLtZ(et<_lqaVlNxg=b8SWYhnuL2z=r zPo4AFhTk6GF5X}9`r}_u>D~{_BO1s2^_1?b8lyD!obFq|S&OrJOZU4&v85h<485iM zl*TBef4Y1u_abmbd~%AAfnQJMtpjGY#`Tu&^%^4zaqzSA^WfhO+}HRd6`{BK{U$Is zC*l0;JOVm?sWGAu2fuV52mb}&zNHsO^j6+SfO%TudMYoId<&Qly*P17R!&qqJ#aXd z3gO4lo4#qllzMSK`pyI90xvGKuYjySFa(a6u43Pfg2yy_LS}gz_e;yPwBE<-KH^;C=PyhflD@il7fR>JoY;j zxZnBVJpOM+0DIv9mrDTzy6T?Fu@RX2G_JRD{6=F$Ar5}_KKj~#xyFn0 z=wtuAADG9yI3Im)0JF=B^XQ|U2aYt1Bk*JBt-O)j zF#^QFubsXP{&~R7r(;FnlBJ%~y&0IhHLkaGpVSyphy&Bb)cTa7;u(?ov3ap*!Q^AP zaAI6t?XqL{id{PQ%)&YIJlL{W(dfDkD9Kb2iiNEia~@)=69w}5b51)m zjC>q9@y(D87Zrt5xuW2I2Fj`JF%?B`#7R1KuN#$NjG8dO7?9hq@xPtrjs?R|iebs6 z=vaU~DN9Bqv!q}lWM*#)b`Ef=h+nfQ5ONvA{|p@2RACjx!g6H%|7Bs>)l^{>#lo`N z|9@UssYZI)uU3r^aBUAdPV&wUttgh~WZ@;ZRPL{s$?blJai_@<{OCX^GEX{O;?<(W zpC6)vU-Fu=xNU3VA6dnlBb(pE2L+xf3huzimZFJ0k;F^gbC2Apw(z(0JOe`|n z-i;5%hl0wnA9^RgIDTbecj7ty0fN@9jP}CM+CIAEH1%m1tH3lFUZ*)YkU2Y>D&bw z`=IZMCH|6iOc)NNRc4j8HJ6Q&N2S*GO?cUb%J8nB{M%z~zd7Y8= zqiG&kh97M}{uZ(+@pEGpT?LR^f?tMl29Aq`x)4WYt8duUk3l_-pB1KnP_|MOZ50uo zH73*U3~VtDMp2yHo`qk~*oY%_TftB7Ohn>q<~UMkrH1yTcdnp`+NhEI=cl(6eCU<^ zh6lNHvoual6-5WHbSLKmOkdp!DZ2HCBrJRMq+8j8`YdEmx)m~TV5V_k^$_DgY>j$g zZq|Z9G?f zw?5tw(hFSh0iJp+k>ProkXl1w-~&E*ju?`Ko;6MUWS@K(hs{n6BGT-7ubw7U4`y*6 z`BhK8^6E*|^Bk&2?P;7^Jy~tPKuK6R@vKb)xyd_*u$-xjTJRM%e5eEyLF+>`XzAnG z((xe@yQSw$9ourG*)e;VfTaZhHkkV==d8e2-Q#& z#fH)bZ6Y_+E$$rn^@;?;_lNU-8Qv)WY1N84f5pl%Gs{U3nkYvsuwfo zGP?rMZx`-Gl}bZM>9-wcx^y8PQ}D9As?6!guZQXOlt15@uWmTU3=3a_B&1$BSNUkUjJ2_LQwiM`IYke=K$1Ypu-(^pa zm-Lh~asAR?pT`Fe7?V$&re;x95Z^l4a^Jmj9{-P^)h$mJRUh> z?(ju2=9C%l%7#L9ea;S(k6(to>Z1(y0L~rLy@4|;+zvvSPEj=7ZNdu_3^od$7-UR} zXBxQ}{7#-HSM51p&5Vg!nT$B5d?xY5=D%gMKAn+x**4pr-6b?z>gCUbtYd65;gfIH zwa@&NyA^Wn^Q5}=5#xwy5>G2@c`U?>dS#)DK`FazuqhDo4Iut!xDP*NAw|(bKNMbI zTBb1#);TrVI`gedp3(Rc42Snv;vX^r+r^6<=}&px(e~3L?HA*r;HJ#Tx=%*ON8-3B zeuUj8pEVQsUKc*KAy*?yF#pQhWCl2QfL~sSkIHqe-bN$wq*W0?Y*8f`|rMS#`nQb{_T9;Y+%Q3^9#JlI`?4tW&A6T0AQ8+&@ zYdv3)<)s$$P@c6ZXjXk;q8`nTxq)c#Gx`1~X3VAZOXb#u81jM7e&EZbNmGe(j5VXI zNprcF12FZ$)OC}_vGTPFOc(Y|DPQLS8q;$ZER?AI2(eKY^ET zEhsZ`$Zip$+v4?`wwV2i5`5Ede$MWfm5WLSgis*mr^29K#xKLT6vvl@`Z116g!(m( z>iRDe=2m{{6q`zbQXcC&pm-DB3ipFh%|=mdHa{1heDrAoAHXQh{Lfg0<29h7cxCll z{DQ`n&`bSR@YDT>AV=bzGvkR2!>EQHPa4#xBoDHw5uj8W&Ct(utl*c%W<;thPFiG} zh9Whs*IkNd1x*xnTftB7(}>hpoXB^wZns7y%W^2)$w=z=)2)yrOEZj8*rmV6CT?ph zd0I!=ggTjq75wxoWMD{tV@Sck9sRcl8~c?T1{QL2ZD&ojx&R2tVq$b2>kbm95jpnc z{}bCan5{E;ZHBv+2~Pg;N$cdvKSt!4m_^j_-Uq+G#IKX+Yco#%t!uNH@x+2geEHA1 zHj58u^LI(%>T}Y}gIY$fyVw}b8C)#!RMvF>J>Nb9gPRK~V`6@>^!zXeH6RkD0qtr! z=J$_v%tnr%FG_UMU#QtAdt=z6XRoi{Ho@GqbcWROpM-h~N8WE>TQiI=|$7#{}om`lu_C{<>+t&LA< z|Cg=Jp-fr(m!OojIS+HJ%||v?cn5^CwxVe5-NFm}BGdSV$J%@Il@oedcS!xp$#rf3 z&XSiU1aTe=RPc!3hj%Rb+<6yRwHL;CcPC(s^Zxs}e;ROA(0&(KuhEd!hP^eC9(C~+ zuaW{`JlF4rY)5JoSqOp=YMLB*VCoDr<;a76ub-1-3Cz3u9cOrQq}7HaHGX~fqn%E< z=7Ga7Af;Rb!F9^@XyWxFoc-`CMMgbzbC-+t=q{Hd#hE*UVEB%+ooD9Io##Q|^pt1b zHDwr-lIOwTy7P<=%?cI|-SvOLxaxuhN z+p#l8e}?^1^1MH|PM*07-+p$Uw~37P$Sb-1aI)#nvm-_S#UL10o|!{;p0mIS2A<~; zzbAj4c-+bJC*Uw-AePp)^WIKi=R--KM1k<4Wr=k+N*~#~sx}9jTvd zDZ#kXI^31kvsYwRI8s}+lwe$G9pOrAi#hsCN9qkNB^Xy)N7`wDFou11&-Wdv_q3E? zTs!9+<&tvm@oRmJh#2L2$E$xhm$4wJW%AB)FmSa-zCH4ubDfsSZ{#r?4JmhTItE;) zH|_k+Pi7o#*Sqz_BEh&y8nUH87;FD@>#dH|Vx5*?7;QB4nCFp*Rr}A=FE2agsB4@& ze_czBR3%MXa&oLlSuKJ4&yTe8yg^F|#+B#eM2g;n;qJ@I-gTtz(o%wP)ehV!a>ygY z+lLH*%hX`w5lt{wk^i!yB+sckZznIfJ04QO0DA|+))mohmKL1SAtDf?R9fFTvd7%< z;{~C<9O3q>Cm<#m;LTo+9KT<)DC$^sn$~CiEDOSn`^3C5M@lSC>x&yLi!T1qgkJTr&xJdYJU94k1k*M2_kMkmkT*LuF}>j^bW z>u+?vgJ6A|>11kl<$0W>#ga0tJG%eh9jRw@T7q%qnK^Xl`4n)1fj4l>z;D}&3+{39 z{AaD_loUJXh?HgLXRAisa*A!|_q3E?TzO^-Rp00VVN9zZ`?@1#ed9?ml4ol|#vHoy z%vKW&JcJ|j9KH5)Oc`Kw2_wit$W6&}9=J|>9{%is{d4U+kJeIxapie}NO4qUnD*Dd zKjKJD*HVIU<(WBj=XoMH!2s{2(6b#~dF)kAo)>666Om`PH$GLQEIWq_fAyP*cAl%W zlwe$WrsbURbi`rDf6b9vt)&Fx8sqX^X??x%f^0{sLrV$9mDVJYQll8|V5~BpccgCD zQi5@%HQANcF^B#0K}YHrT1qgkw0QOA%zqBM|CAp&QronYU|eZUb)|J?=71L*sXu8c z!MM_zCQ@oPh3~B0Id_XA^^ukmj4Q3vU1@z-y!s$V3O7?E2*#Dxbdgds99(&RyYxaw zDx{?Z<4P+mQdZk&|7&|cM{1&$5{xUYh)7w!?wLn_*6v7|T1qg$;XaY(kjA_>X<23g zIL@x5Tb}zo%Nm*B`Lq-(BF?UT~w9Dnu`URMPlfBvMvMR}c8p z+l6*7_`a4BjH{%@B4zd5@6_D7#*unhO9=)ztPRo}(y})l8?6N9+1;0CfD;V7jU!7j zW$kruIi;|^6*VKJ6f;H2D#Z^b4I4hgF2!!0x?o(TFh$BL#X+Oqy2+91Hvo|cf}#Jh z^UNG#)e_?QwkEfsQhPHc?I@DO)USZKp*(B8pt8}~OUbp>muv&&QKxtwZT5aqOpv=u zd4z=Jk+C+PqKMw3$|GfQJ%ZMTR#>LMy{PQBPNB$RSQ0izZP&0e-cVm>EUT^0wSdw9 zv0qX$PrVcA<|$mR56;a~xbZ$XH&5Ymd~j}_!X@WU7cGfpz0bXu`*rXQLGFtakqtX| zEupMo)mbt}Czixwi{WWSydil5FT7`-+WL~1R)s*?;aV@)7Kdj=i_2%k@OrjdpMot9 zuosYCp~4+KtR*V4&j;Ucg_7E4X{%Q0&2Vu+!A!iHUKmyjSny^pn@0^^gy%*<&fDZ7 zjm_s;)E;TfkGG*aJWs~$hE9a1q1!BvjMdN?Z#8LEuQX;d*CS{(bfBaobCWku7ikn; zlAH~6I=b3N&MT<5mrLFNNn|zOsdBr2oto`ps&3+8s&Y;ALwcABndgV}FcmV_59whl zGt=w>50JptfGIws~UZswz?mS{0sB zZ8lIPSs!m$sdl832&=9*)93G4q8N-XLOEm_hgz&I%%A0&)#N3~PD^J0V0uFZ-UBOS^2|ygeJCsSm z4>uC=Q}+VL$?p~C*!2CkvdTIxhPkjRuZ>lFv#hDIo+`pl9@tnc0K6o?b zZ9kl+94`R(A#hLe9xnoKX!KN$6LHV#RQwovDhK<~JdF_`4t{p#EsLcoxYYK{TaZ`p z1@2hje&mPql$SSDp9k(8jb(r9sk|Qn(~k`np{Mdny=#m@>hgNheFX`PCXV-<5r*Q| zQ@U3HbA!h9lx_&}n}GSf#<3iJc4oEi&=`;sq`i3Z_c|1O1l$XBxCpq)>oI>TV8mt` z5}~*JT?5QdG|tYSC*7YR;t^o#SuJvl&8L z#gDCjg@Wq zG4y1Ya}iMh%zeizTyO2P0E5?T4qymD{QSlR+NBPdwO*W0Ic@^x`(B)<9JI?5z`Wwc z`RMxyn0_3H5qipB2yr1`!Ww7W#WODOX7?FT?=LAc z5nclI=`H2({JCc?h|G(e8ChU<+?Sn$wVdW5^%XUmb%j(OPu zPtttcD=#AEPtDF+e;ReRbz_Zv6;{JenK>+LeKr**=3_bR7OdeLQIyEIGMXqgm14X# zun?-V)?X-wm>DvwVq9cKt))xYKgV|nurP&e7UK$^$N;RN+!$zcr zmvOV&W_{7!jkeRy)VWewH7Oczb@$@}&+FV>k0j!QB8i8X_uT_QFwdnOX0h2(y5r$3 zIEl7)>bF*vhN8qXu|y}clXw{!Q#Aoq$0dqiDngm8l#~&zg!;?M=U75DT{F=kJt1$K z#G98r!JZPSz@qTQ73VBk(#4q}pW)pd=&#QXol5g3u~PA(ibI#a5h)z+d_i_}ZFD4eL={T#fn}CLk?Dsh53wjA><;x4ovqknTAPzGj?S3HM?+t0M z191oqX$OFK$2X*%gI1p>CX;>aG-t_9+t5z_7f;;bd4Z3I%Wy#q8zWd98m z5%h)S+Yh4#b05+M0;v$Afp~W+qzwb&GKlFe22f8eDwK)eG#%<$X0jIX1V^Kp;wY2_ z*+3jYVNti~y!7(Q9C|Y|w9Hpn4=LS@HKkFZY{-;uJCoQ;w_*+)f*sfRqF&$5-W|Q# zdo+Y9g86*rm~JD=-n>Q%Y9)18pslTr;2q8Uj>PQ2)t3*OUt6=d+WZyCYp8FmZQ{1Y z!PRGKQ6YC?5%~cB{4d!Ur*ichdi-awW@b!)tN{pKMhI)n`+z`Rb z?IU&d5qUv<{`z^gxOJQ3*x?{V=w|(o{W<(rOE}Z0X3j zm`hwMa}!mm{S#?p%ROKxlD!gouTnhPT%Jhw1WZ)*<^B?E$r!M+B-uYv6-=~cU5Bk* z$*{uLCX!{^=>99Ko+0z5EXrgd!{r^mJ2l2uzmB{03QWW4u3vH2E$ z{l>#12PP%2BpL66=fDdxOZ2{E@3XPO6dV%4Mg6b(g|VARHtt%R{#S9QF+0V093i>= zRU)ViXVq;0Gb3qg5Z|m10g|%;2!^XdACvd*R>^ zq6Q}cIDH$3%8NqG%L9Eg>SLas1XXJ;a z`sX8e#gU9C6NG8%$NHCX{WF@pL|p$%T>nu2gM=@`K4SMQxe#3)yGp{Vw;%HN2strc8gWO#eed zf3Qrlm6-4TK!YyA^eS4WzYy2Ap^QfHeGCas z5c9e3EiWO}r|-5xa7MmY6}SF!O3JM_O*x##Bj0gMNH03n)EnD0jI9{le0ihPM~c=fE}y-PlYtv>sGg&yYBVCM&Cdnm#51H-Te2SkDO>#uAZ4o`uzXp075Ej> zt_1q7pzDBI1@W>NF1msiwURDAlyN{BF8i0aVjg zh)w$kBJ8AKhBsr11BX=Qmh)I43X*5i7 zIZg6<{Qj3r@{0&SlU%AFRMvQoSmW6xw8L+g!ba<_lzL+h%TAD>iexjW=VJwLJ+)S=$Lfs^M_z zr>rfTl#+eDwVi{dty!H1Lqn?bs2@h>IR~BR99!pk(ds-{ymWLPz04KgTZ z8)i>RaTH=t+A3_asM~bP-x=m{cp6JM)#*JcrBNZYZbLV9nyDc6(ydbA(UXk%m8Q9S zlI_BvJkniH%7+i$PEw|SREEjAez;WMAJadL>2H_e@-bMJ9K_e0WEmHE`~Ql>;Tki% z`gH)j`D``TLw*l9CdwB!s7vxhTSFjm?N=HUFFP3vy5_uBCQs%<`u;nq33IOeCrK>P zpHE=fJprgXyezvnO~R0a4d!^A43@uB>(ZF2pN-i_>@ijct`rjC!Y`nqRNqmCF`L#>L#n#$xm8$Dirc%Yw=R|&xD;u~{WMz+y|g_#;Xyjy=cQl`d? zW}prnA&s+THACmEYUv-;^ooRf_fl>HwnrH`h%c+pw)uL0KF|J2Bdn# z6d=_P1_AMot?70EsD7YOCVoFJvOxxAqwzn4|0#|_><4e)2x??ex9Pm}z6?*JA585{ zbrOpI8EZf^6#polJ>jM8+!o5cfXLs!SDP?)Hl;5DI7^T%Y4M z3k4EZ>EMl$Y{z=QD0%k@7X>2H=y?AD>jc|J$%_wCF%P98!yUwb6|+K&`5z(+^bctL z=b^!-#e;PROt_FD6$`U=5`v^67>r-03!sWs1PU<%O=J=QvKGa%N5in%>J#t0PwVO; zdssC-z|*v>#-QT)eLkY-bpPHSeXhwfts4&BiNsT>ai3L`A8C*NMfd#n7pdL$sv1?5 zIQM(?fVR}$m%#Mb&P|0nR$?;u=-YQr^psHSAV{Rvb@wZ)Q=z_Lgc6Qp&p|H<#ibvH zI{4{Nwx&W|V1yEmW0wYNA+^8i!^f{}ONB}pp@idztG9%T;LMV{>c&t0kP0;e5<1}s zS|DehA{zFH*dBIZM+gRtUZyR(>cb6qh{9kmH~y334AoacMGgP8*In>bD%6vPl$;Fp zrDc8=R$RoTM@l$wh7lq@@MmbQX6)u8vg9ZkjiYkZLpMH6GBZuGz#%EWbUtroC^ed? zhxf3QGbLB0NxqvVNln5T%3i8RL0K?hwv_$bS8dmC53Lavyn_7t9aZ9g;-lWgu+CP&G5D_l8K^BPNH za(-k<$ic3fbIn%8-r(E`lnqHRz#9$p`(1o%o@&R8;~_&&Hge(I)pxXnGJ9p4_x9ylshsxXA&2Bwwj36Q5s z^}1!heRiN#s{4#k!f}-9iB>489sK;P!KqM(jZngIv>%Ra!N4#Efy=+E^H*lBaJShQ zuE=qg{K=361E(?w+-Xy0qxl$(O`BkZB1g$|bJ$C(LEifc22P_AxYJ&ocEAjSkBk_h z$Z@t+#v2S!e*nkO+iK@3B;)dYh~Q3DaoHXpi$Izx)x)_@{`FL=R9`XT5{{!(2T3Ti zt$y*{%N;r--cD95v=a8YZ9+;2{6*WQ$#}OCpOe(Ise=+RM zRH)01P{MJErI@=h1f&nhsuvdN=`+Q=m zc7A5)$=BEm?6YpR*;Fnz%^tKk-|Cf*8=-{b$OYSovvyLU{%C{}jw3FblvG@UE`Dfs zDwN#0g}-ndah)rn%-T8sg$tfeg*vSlJmG}ni0eE^Q*p6&Qla8TDB(EbLWf7F2+r&~ z)Bn2du2d+zV^o}Q1hpEHRPC4+fOX-l9bStB16)X;1?W2F=hv$^=BlSlMc)Oe9p~%| zL#!Q zP#+kfgyWbMTq2=pVd$Qk`04v8tNu?T6gg_VxWF79Q5PAQvtcvoviTBH)iPn+!NID> z;+i^xBBAVa(XsGQbAG1zzE9UYrBYvhX{zGKs!+D^Ju0EhvGONpUGeL&R=rO)Vi%61 zd}0#HOx#POpAM%&%`?Qpag6Uwp|h=yv-B{{Ke+u>%w&klFI7)I18UjrZnyN+SH`e*VbbP)!9vfE{H6Cfi-gfm&qxxieK~Xip#IfgEPd8d} z>m$&Gv1q)guxQ+*qVZAnprhI#kF)|{fdJor#&_GBtmRY7rdLcF91-`OsTPQ>ni zK4*!f7!O+FxA~+cKADY2Eys?u5=b9Q%eZJF9-9~|DYk#=ota_@HHRVID}r(V!nfqv?eYGBrS(fO?`_0$ zSxal1R?MxcuU}MKllJJWr>077js$KLhD$W~Q- z!-_(fnL#h;(9fLRq4?sI1&p-Xm3MH;&EaK6tZiC5Ez^#>UD8HI{G+ z9&u}KG;6OkT3lFGlqe~f7*)^bjCHG$(lnKzapEg-eDclg<93OWYMaPNa>1l%(YQpc zxTK&kYCeXS-oDIFv9m9s(O4a6TzRylV8X;$tk_DVbegYeUuHSf+FO^In1X0g(Zo^| zV1nz}%#7;XwEcLH4{yJytdnoV&jZFwETU#!rKiD|*-a69qHN1ym8OU`k;P8QRC}1e zv_^GLv{}^|#3J!)=1fXCcMVw;HLf^XJZ@5ATtTeNtSNUoOU+zMMAqISSE6ikXUb9@ zYVeeeNk$@Uc{J!0e#8lQ{Tv*aTn+LA&<^0UTz>74c@|@io=DwRpLDgNnyeNIx;3$nM zUR3@6#hz060PN(N1+|Ts&_tO3k8s?8qx64agQnHq@eslP;6t)<>swkNYYBTstnCc= zG~Qzskl7yvX&S^&8STW^2P*c#ix1;AVOI>E^f0z5I5swL8HGnkwugKgVOwZ9Gv+n`m28j{s(?0qek_LSW9toc?Q*a@-j67GGoQ>U)v&)T?bMMI~ z+qg~@!4Z--N^qSSJI8S5D!FQ#Z1$#;J0v1kh>2ly#CM|lWN@TmKAMLdQ2xj%75GU_6YT;Ql1;T}8qA%FzBF zd+9kOdgj2(QEQzdE`-=wbFoca^00lTO`kEQbrOorN|B^!UZRCGFy5Ee7coiWpa zA|jiIvucvdfK-!g1yUhsGPuYW(pW~SNBs^+^{C$iaS=Bp&lRyrhcvc2E+U6Cenv}a zIT>iE$oMd&k_`vq!Zx;)0e|J_J&6^n;~W`i=wQa+&Ia905!>96;Fvg);G*3(@F;t`9W&d8mbBxYOB3Z$=vo zaQt>U`{G&myd;^ESd&wM8f#$1)HHQWc8+ytSDMRX`D(a0JbgGfzx&`b)X# zvydmlId3j`bde{ zZ*{Ppr}Fi3<*wiMvGVn<5lT3Yd}T=}&RgjC>h)Bpe<&e7P65q=vjT=lVkbT&O>%ac zggsq3Gw+if64ZND!wNTNo`b_%w&xlYmQPRFp;UgUW6FbzfZDp+rm0wLYt&@rgiw}= zjQPGxXk3dprN-<3<}Ycgt(#wuC7{|R4Rei!7+!z7bvk8+N{7&O?M^=~hc(LLl{_{f z*>J688A*07aG6&kPN}S6IhMs(61G(`b9rYJdh z#gl8Fd5w)`F#i9kX?ASF7OlM9-s9-SzI_c0+VzH!WApR6Mk4PPaLkt^cgOoXcs~R0 zd&ac|AI;0O^XuXyi<{5tS*(Rbt%P^Q&bJ zqu+QP!f1)$vt92pTrM83!T)UIf5iMhRLLXx#(ykwk(Y1$kDC8+VNQ8;obkUv{V(VL zk?q^?Y1V(s1+p@-f>~Kvp&nUTJ+pdc0`|t?>H74g)fDzVU|7UJAi@hUA;YoTvhh!Y>hyVgQC0;!AtwLmB02+9UiUhW1pUNxK` z=nkCOkAm8IoH@b-wR>JdWR7D+%I_ z0odmd**pb5@IsS)_=lyJ_9oewgNnwL=Vsar@i@@y8EFmLW>g*M#%FX5I@?DYokDGM znFpQCh;)v}mUarY&2cX}TAR>Ab~=RG=7bj=jZ)}n(JAc^YMaZw=xD2HX^%jtZEo_XO%*2^9(OKI!rnpLTz)A7ajdd=mA?++1a$srCxN@U0T|s ztkBJqU39)|guRq>DK)Nl?FUJFrU&KNBEy%jaA0CZgrothCZ31iLqx_hr>uu|3C@Z) z-jIdlJt~Sf*WxX)c&RS)UC0#gCX2^Tq4aGqWFh%7uHrpm@t(7IuUowLfE4coi+9-K z^+Zvsd|>yC!8_5A_0YK8TE%;w#T#ewxUWFvm-`76uiD~qw}6Uwg~hwx;(g!Zt+#j^ zEFPbUQ~I`AJT8VPeXm=*zgWDFEZ$cZuP1thO5Xq=r7vR0LfQx*rEiqQL$PR_yqfN8 z0JVIg5L&e?v|#xJ%K1i{=rnWFE{zMfwf_kl2}|3!RHYTdUL0k6KgNMx(KS@0l~#SW znS%{p^D&_<>ynZoc=N~8`{=_rtli8jYc7rArAbY>GoR!;h@86#)yJjv7Z4r+hdiIC zda0x>tEZ{qnrVE&NCn@V)HddP?)mG7Z&+LJEjZ9SQDwfA11XH?2Zwyg;7Xe?)!RLg zn3Yc+2tE@;KZicN6h~5>%8~IR1ips{tCvVCyNS6&@bYc6*{X4U1Biwf#cs(;f!Gg2 z@&+7^G9lUXr(_%Pn>{h4ag|Q_z5%3s4*{vl3!u6u2`>!9D*)56JF3c4h?RG~$Oajd zS;l`DTDe9E$`zAhXF)a*M^O6!XX-Ycm)#6k{(Wf)Bqv!5Wdj^_xX|B98(YX~ckGpMWk2;FVnkv@Ff1J@r)*Qu= zbMhx|KrBPH7JMsz8)xJ3vJ3G(zsT7UUt2i2YU6aiR=aI$H9-Uq2GUn+7FY6a=2B5E z96_x6^=Pz8VqeRlPcXooqByme%Lm33QWtU%!5ORFwiOXx7pea0BS9gBSn)QY6(@e_`l3R-+#KJ*eZrP1Wf! zw|}wqSnD3t!$v6KIP!kHgfjbJ=^0Irq(VJogc1(>m)J1`(3nDJ|H=_P9RFyowmkBB zTPn?O7FF4oUg%pV#e3h2ljOop1ylt11at zO3b#xDQi0c_71wH2~Rv{)+lVM5sDnIZSM>*+tO@?TVhEV7fMXV3vyXLJ+)T&kDV*8 zw1|!!K6b1;p(;z9(dg*tXx#NNmpm0rEp_5nSjiGR7d)=gct+g)5UTBtRhpM^UyL`L z+b8~GX^|YZwBAyTXn=`4pxv4*F!93sWC z#b;zTC9&NBR1l9T%9GuWyNfJ{WsP+Wc+W@^9};%w+%7Squ!$Jj_O!pPGVD@YJ=nzE zZH<@|om5mlzHDM)S(J}X<6-flQp^nT#5aDaJrU=P9nB}n`4GAP=jZ#JGu(N*@JM$N zaW`?)`4WV85s%H_UBnY##(b4s9nO6hu@SO4Q^YHE>gF!ui!PqrMYQ!%DxlR`Fg2x$ zh<73E8*C{f?`j`B_UZ5Y;Bj91KpHRot5fXTze(ezr;qxcOXGR#+nvTs*T;DG`Q&NS zK(;xr@{7Pf#|Mw)H_9h(iVq%bb)8S%8lSwoeexdn!Q%+@nor)}eeecAU*>e2Y|g7b z*j`RbKl~COK&gao#%tctGJRho_D-uX}t7!Ie)11$y@G&cP#YX?2~to4<7r` zV?KE=`QWjC?DxqF%>dcvyxPGj@ITcDkLLK|G+uhWQC~qCFTLK_4l2`l>H65NYSMV# z`c|az()Aq&eOIUP()F=le%~kWmp*vxZ%?Q3($mLypH1U=r|-``c#QX-X*}ReDIjxtXVkOoL9Y( zH`oV{_T>_vyjebY9Dkd9@^13MqdnN*gU51y+$Zl%A3U~$Lq2#B@cLbblg)Y6M+E-E zeDID3Z=z3LjSn8{_bQ*f+kEhtzK4ABcKP6O{O$0``^*QA?WNCboNUgkKFB-82QLS_ z5k7bv-^Qo$((NwwO-$pZ+x!0D&G*5hyzC7f@)r2yt?|e@Pu>eYcqc>Ohdz0I=7MZ*Mk?UV43Seo&dlORo>ci?;9rnSaK5ZUPDd#ocC9j7M9^>ufgU9xg z?Ssd72l(Jo-#{Ncj^`));89<$PhOr+-cTPr<~QFb?>wKp3w`jI-?2V;OkaTy9@{~} z2aoYi^vRp-gU9qu_rYVlvwiTWZ>|p>^;P@e@yV2hK6s3Gkq;irxxojI>09QL_iZ0M zrf;PW9^+l*lXtyOp6-)(vrpdleejsy+kEht-#dKpsBgVb-p_sT81H>Pc@OyDF?|pD z;4$9c`sDr22aoYS<&(GFCvTSz9`o^nPu?CMJm%vyA3VnUmJc5Fz2k#Nd+?qQ9^-xA zC+}}Qcue2NK6p&uK_5J(?@J#%#v7=@$>zG7zx4FMW4wKR^1?oO{eAG5kK=vtSbit@ z;4vSk`Q&}WC+{quykS0hBYg7C_sP4^C+`xUym3BxMLv1seex#y;Bg*1*$0p9V3rRa z+u!9rc+@w~2ao#Z`{XV1$!qYzWB+LO!DBwYt3!S8Lg0<`!DGA^ z_~23B7@xeT4<6%<`{2>Ol=$FL-z1;BsXlli=$qw}cezhqrB7as4<7T2*XTQ(SAPqE zfj6Z)oEMMfywoRexep%O=}I5G5O}RVc+79o2ao!0^2z(24<6&a)hF-AK6oMMTkn&1 zk5AqPA3Wycmp*tQ@E-KZd&CEi@jm8*$9SLg$=m9K$9SLd!DGD7`QTCCi#~a;_~5a> zz2Sq$c;E5CqrUfi@Iv6d@00g8A3Ub-V;?-G@1PG}2)r+S@EEUrvl9PJ=VjN(>sezm z)PFA?)7RGrkNS@G$ve&mkNG{(2aoZd>VwC8Ls!P1=G7 zjh2A-;R+?>ep-Bip?#R`4G#2yIL) z@RH!HJp%71(Dx&7MqzI-T@M`Hy~XgG;4CwELGYwpJl@*)1A{|-bYA7m-Ocx;@zS4D zAn%txc@KN>T;-RIf_)sk-`~WPsq*YDzsKB+XPa@*eO-RX7#zjyKEI`DJn#HY_2Rkm z!S}$-0q<#p+g*FP3%nP>sava3$M)S_es2ZmZiCldepw&w21jZ1&M%)U-I>Nq&o6g+ zzv;zu<#!c$`&>M){&6Y_V$m&T%GCev@_WPgFgM0Q*Ij%n2H#n(y z@tlk+-rb1zLGZ42T!4V=(-Pwbi(|GCS!gm1N2Hq35 zD{V*NUw7p)_D6VT6bD^*=^F#TT7x4*oVrWj&(nD6?V0uaE1$eaym+qq2qV8wfcN`5 zRO`uIq76)B-`8^kY>kW<&aq2F=ucYzP>x0eYZSavio@XxD0@*p2*a1@ig^!9faJYzn2i+u1#Lf;R4 z@P>f5(~IY-H_l%^0q?NEWqzgnTs*!TDD*Sz3By6x9d8T#a=>}R;BkK5U40yT5B6l^ zpbO&gYJXy%4UP~^p39D(33+iEFTFm_0I$IZkM(w&7td8L!;$bU;C*~A0>FiFbeG>X z8}K<-9CY2~m*d+*;B0mC^o;>0;pTbh zn-9*n-8>I{>%h6k&GXQ=6`a@HJP&=Jl5?MABb5&ieW!pk!p-y0R}Rh`H_t=gx52r| z&GXRrOK>*1c`kjlFRy{~v76_iFZ+Hx`+$Sasy7dP7lJe0&GXRL1Wt>a=hDaa@)K|# za`Qa&?FQ#}h|*ch`R}`W0*p4!Z8@gXLFaaD<4HSALo96=}TewE5p7i0Iqko%5j5b~^rb zm%g@#FsH;p*IoM9{(ft4gou+@`a+Pu?34GpPu^QTdGC1fTy}Q_68LBE=CA_cPQ%e% zxoq5oYfKz;-IWXL?M-n0=H_{{`>e+>#^IprP9Mwpd~hbac^>*2z`4rJbM+&R3qJzq zJ~z)p-%fB|aq~R%eGE>H`jtKB@8KGw(G;5_Q) zdFXouoDMh7L*G~69P>NLZmQlq^yPyy#?AB4cNsW!Zk~s}8^KxU=DGCcAX$%s^Mb*n zeemj+Y;SuFj>?I_bM=qY&_CV+@5`qY>n!~1u7CU#leS;spzE$ZGkwp2^Jjw>z;Cbg zao+!-!2uN49q(fwJkB2v`rt9%FMaYdwyJcQXRq`z-d;X#qFbJF!O(2VHmNNBdj{ z&J6~yyY!t5-VY28_0f4<=dt`A^uaqGyr;c*uJ*!t$lKuk+2AsLl3y2(^PCUCId}wK z7kGhPI6aF4t~ZYE%I`98<{P~3%8%`DwZWl2IRfJOa+sZk|WG|1&s$ck^8Bo_6x67x0c69CTK^9{LKv zndIiV^s$_mfOEB*=b`V%;N0uxdFXo@oLAjE4}G72)8*#5^s(Mfei2_Y#zFUW`JDvL zY&XwC-wJTr+&qu;-4D)h-8`2**2k;hd}#2je(r8p;2i|#D;ux7{+78L^9USt-Sx}S z@Hh#aX)h^WKm6;ioxTgshX&6oKUY534*KrFygKuhv7Da*=XHZ;m9uM|<}~o$H8_CcyzD9U1z$D@#y|2R|2JRNT3laMxp?Yj zCHTN%ghTvCIBvu-@qhlcEZn%PX{udP!_O0H|C29O&#GM1+|;-z60cmbxOTz9rpQ!i z)lBJ>rpmhN%B9sxI-{nsDN>CjPO;+DezU@(B)4XUG}DB8AOM z>l8QRo2$I(r))j3sWes`u7N8dN@N&t*=|)F3_oyP@u}gOx(o|FIX4f{<)VfqptrVe?Ib~^Wq_nbbkvq{Txr<-l+_ccFOJ_5j zV)t@}Dyv*vxgt_tQ-?2rHZOL^RTe8n3As5=4O5DzYEvqg)TcEdgq%_sk#_6~5sR>i z*DS4b73Gwe)h(PEC}2g|eAD!qb?yuno2-JFzRqBin;X%`+zrT-y14bI<0^OGnruj& zT&ritT-9vz@DAZjy+wBzkBRk5S(%Jez~Kv zd!>bnT!wd6dj_(6++iAEid?c`5z9uUo5P7NUuW2|6_s^MDwn!6dK;QZURllZ+N%09 zHOt?j%){SVe%`^fvfApiV@)WACK!5G2)mafGEJq$$;StI46%co61%iZc3gR%P>=VB zJJo7R=Fq8)uUXpMSh=`niHlnT1DNu2hACN^){#mkgD-Lym7TJrt~$+PDw&gpDtwW<_*2KZ)E7hI;*?Ewb0BeY zifX^<9t%X|VwD!UG!;SOzyD+5v0ti8Q2jh-P;jb^9)3(y}r|e*gYN5X$6(dRh5m+jqc(y#cnpH*wbs4R=Xzy z1=C?*3MwsMSFq{ytgEc9w1zZS5}lsT(6MjBcDoa32whC?;l>(;TI|lPMiGv}sd2(W92l);#CT9Z{)`wz)2HDmg&Ze% zOb2t?Wjyd>+AJOfQwwlt)5yb#k^)>TpvtFChJ5NI9A!A5bn18qIaHQYW%&#o{6A?TPGv-8;FLo}IYO2vptBrVDKDHVClVMQoJnNkg!4osbt02G z@iKT!L|P{D2TEk(B%}@}{zP&n!n+J{mqA(v8da1{nSdj%m4RM{cPK2D?PXJ>A15E&7JpPZ5 zAvq-gB~V&28LDvNPh`9VBM8~%`%Ad&)JDit7t zf&}R}BXoh%h<|{TQijwQ2!)JssK0UW8Ha3+$|-1Sua!7Mp1dwHae= z#x8?DPJ}bmiDw=N6Pt)6zY^RW>iszS+DON1e8$a)nmeuoVB7YV&L6Y2U1@!Ob_irVUWsNWtR+mAhc?)2tTYibiMp-1X<~ zPe$T5wikQ;8NdBE?Sb8GguS#o=FiS|=f@o%!`u1nuXg8dza7Sn zd6VNVAJ&ImpF4dEzwIn2uqUBgN+~Z}RQV zU0&|;JkogNZf~3)*!8>H|B>vOyMB)}p1JvM`{K@z`}dLf?(%Y%r@KDwc_(K6?e*s_ zZ#Uol`$*+~Bzxty$8P)M&QDr>y6l@fzixZywg>L~yYolBy?osIkCcC=-yYuG-rV^+ zQhB-4_n+VYDS`i#z<)~MKPB*=68KLE{HFx||5O6Gctk9qWg^Lg1Z4xAB8ZQ%ohT>* zlp`n)=vYDdK*tE;;#^oz6evqj0;snjUK;fjG!rN&r~*h6go&f}C7uTiXe~g81+4`- zC}=&5{104|50klt0C(vI6al-c}L3~ZaJAxuWZwtx?dP7hY=ruv* zKraib0NO360qA)_EkMr-S_`y8(0ZWlf;Iwe5!4R!q@dkEzZ28}v`J7W5Vu9)A07sN zNKiJ=uLVVbekmv)=of;bK>sDE9O!3)DuC7tY5=-ZPz%tH1g!*N zpqm8k2GRv}0Id!T%1VwPZN>Dz|D+EPxUM8p<=SD#lI5!C5d5NGF zoWCh(EzS!Bt;e}q&_RxMpbnrsL7hN@ z1#uVoX@atWP8AdZI!RDI&_F>^pyLFU1N9eF0hBGM0q7_}EkJz)tp(~OXgyF!&_TU=H_#V?I)Dxd>IC{skk%6$IR#|{{asK5=mSCdK>Gznf&N=iInbX4RRFQg z1hfXAKL~08dQ;F^pw|Vh2YN-&Mxd7jwFA8%XgAPvf;xb93hD%US`gn(vsF+w&{KjU zK#vQ`2YO6U6zEYwB^XeS+2k-79E4&^>}S0{v7_JJ3%A?FRa> zpbnsQf;xeID2OKWdxEloZWa^)x=~O*P*PA7=(~c-fmR8s0BRA`0CcsW7NBnnS_^cg zp!Gmaf;IwuOHeydouJ)7iv)E5EfmxVR3nJHB<2aq2AV4<0yIZZKF};dQK0F9%7LZ` zssJh%)Bsc_s0C=eptV57g4P4Y1#JY132FzrM9^-aiv)E5jS|!ebemdr$_6?| zPy}eGpnRY+1x11QqK<%84s^Pp3ZRIf2B4D#wE&$UXf4q3g4P2K5VR5KXhH2j{RHg> z>MN)NC{s`;P!B;`Uzlh?*+5)g3uqCbe+tS6`dm;H=pTa0fj$vb0YpoW_6PK#pcbI_ z1+4}8tDyBj?+Mxn^sbFXvV5Rjf<^&7BPeR|56t+7BCD`?3xS>x zS%bw}4zyWhEkJ7ITm$r5k*x(%dd zAZRzx&jsxTx?4~Okh0_ZfbJ4mCy=u8hk*D}4*VTu#+wOryU4OFSq{*xB8ynEJfQE3 zEFVaXx}$*BiY#jJ534g~eM4biK$LEZ%aU)go&FQZtG*K-Y?FEsz@7 z*8!~**?J%~?r#A4j>tAzyiGvMMb>Wdb^6h zy9uaJWbHsI-km_>M7A49_3phuV@1{hr276opfMur1XB7A0deyU{=%ldOrY~cmJOul zG&w*cMHT^4GoC!4e39h?soBUVptD651yXaz1khO`D+e;l59kb$RR9^~2b3$a1|VhE zmIDnESqqS|dTW4A5!qTGWhd7GohY*PKskao039o6BaoU8Z2~$*WbHs)wP|zVD79Rexaa|!lGJy^Y$_7&Ua)1tsECTeYpgbV%lnH40 zKx$?*3g~Ylivp>cRs!gN$jX6KyPpZPPh=H9s@*RH`isaKfYc0SInbX()&it#*czaB zM79=4%|+J%y)Cl!Kx(GC0q6~pZ3I&KHUYgRvUVV)ZzmA<9%24x@%94k7Fh?7;_U-^ zUSyp>YNmAv=vk3zN1OAZOrRYi%LY=jr5vE`B8vd2*-{?R7LnxxshQCzpeIEZ1yb{- z1Q7RtV>|~^^Q)Oan?zOtq-JRgfgTZA1CW}tE(dx@WGz5yM!N>+*CJaBq~_1-fPN{m z^+0NNy#eSKBHIY0=17}>{!3)-Kx&q@6X<6m+YO|ycJ>0T7g-08x)$08#CKW+v`!#p zcMk#a)-T%MF{a(k1iDRR*+6Q}ngjF$kwt*ij5ZJG7Lnxxsq4^DKsSjj3Zx540Id;J z4y3NZW&*W}tODpdK?{Md5!3*rW=6|_t`b=bkh&6C1GGY9Yk`&tS_jl9XgyGapbbDv z1Z@QRrl3tg3k0&Gq ziEKBJn#b-18X~d|AXP{EfbvAvX~_-&4HlU;z?{cs0-YwZY#`N6bAV12Sp-PU5AuNc z*b3|)kh<0w1vF4(QJ~`lC4dkOc;!Ga7(g?DF!Tde0IB)zLLf}0A!`6qv*G1HxPXEz z(ZzIXn0adXxMU951?Rd2qm*FP2Z`{RO}Y8uGq1{x%n#4#O0-SQEuSCG>-;!;^i{d# zUHqP^Ha~pMLCE$kI|HZ(B_D^g}?hZ3!On)@K9 zk=gr6)H4#vrrc5b(#*E3s6H-~NM4m2Z5y*Dp%-MvHlgQftCo+_n$AsBjmu6{jn7If z+BGH-+=-t9QZR=_pP#7R6&)AW=$kCf%|9?@ez*Me& zsh*F+SFoj^QfBTZX@F=VE5(?(8@?~0QW=LnA+e7E^cPh9CiE!@{l(TkC0TG1=^;MoV?I1r3IIAqh)zq$LC!tj&34(^Y)g^rGGIn+0%w{O{ZYCPBu zP}`o3spycMo04nRtU0(p_|lfcJ@l>c4(`^sBH|%CnCg~~B_mt?* zNnJ_5Vv{%$hl9sbDet8~^@2Fe)d{-Qk^yLU@npCfDQ}!Kg;)oRL>34Iq>tbk=fPEj z^G8&h2cLRQNwh+JZ(M&iuD`VEaK_54Sl5==wOcue9q1cdwdE-McnUu@o!WZf(!$zZ zKRN|n@!H<$gIl*8$`C*MuOU0f zwXGgF>$p6Iz~bcy~(>|jS+e^Y+N zwj2l->Ms}8?s@RS3@tX~*|w}Un$Uyq#@Z$f*wnaj$#I2kp~RN=!|~vjcyKF%iV!)C zZQ0)|rthlVHQ{hq7ktOHWwo*}5561M_r$im->a~7Pt)nKwl%|%hfS5A3|w&VU46@t ztuO6EKK2=T8?y7jKu|`IGNmf~n}hFec|WsuPaS?EEth_$pl$UH(GR=2l0DfQv-M|d zcU_LE*|I-d-?C~;pW1d7B(x3Lz3Kk@?z=D9KcS-ts3q7In!KeWW5~{~Ey*zZbIvxV z?o?`t&pbD&`;#)rE0STc~%X5BXB=3u8pY?>Hn{o|2)^f%&d<4#KGFYF_|O`o-JuvXeOF{`w#C^OMEJtSiN zip;n^KNQ!Cvh07-mEdtq=JsxJHRcd%$#G+@*Bb4$LbI(>%G z=@;$kHRRdk#GJy`_pUig28m?P*pThXqEJF#oSSGX=weMqlSn@*zI#Gd$qPVonSS+Sa{Y}iBJNC z=X6rbGx+fgHEi+JP#l7aC`v;=LFnY@xF|1{_fp)7!P{9jUyIpvw`e>k@T|EfGv|2T!=p)Z!UO@Os5 zfVG^WtR@}=dbQ4Sl7Dc4@;PjmibP=NqNw+~@6t47^MC*r5J&=;CwUO-y z?xD?jK-xMjtZL1?o>o19y-2ln_8rw@?g6@ALUaJ3L871VGC}pWkAYNg`vOR{^^?%f zl@)IVQu?@#u3`gC?$+=>-CfYAdV)gi2|pKEVCRY2&V3o$*1bXP@tq;<(M>(Hjnz3? zbVE<=qIJE{D>Bh5dZSnL(fUt40li`%dc|=@uV_bMz7vD8mZ1-i<9{qOeuk2Cj0Ni< zb@USb@W?$eO#CqVmgu`m^pDUe)5Za5u574z9n$c5rOD~aS;>`|Y@(K_w~W6u(SrwG zI&6%V$>T7av05|Rz^9zs>`h(~nlCPV>T0H#*Q#H!0kKhe8g--slaa#kf42h-+ksx$ zpX%D#CT-RoY9JZP)+f5QCX2E>yZG0rGnzLC3%fc@GyG}lCkeAmg`|hclo1583gu(= zo~M@%Ab-0xigfP(`&X$^gk51h3Wy^HXpNmXeW!!{+SL`3Md&JxIU^}Ih7zDfEz&tI zg$6a0%m-3Ux*kY1>E%GGNpsmvb%!lLsv++JQr+h7K&qK@>{q^A(pJ8g04ZPIlu*9& zEZ|B zXy>o%iSE)1-6a#?+as zB`+-1|CG=_D$)N~+IDtBUkv3tG;}#k^Dt*u^H$6mj!LZBmff|Z+oI zf|z;6U&xFlL%Ff=qwyEAl7%qzm>SAFQ6`6+-OrTy;T4=A%2j%vl)@;aQz2f!ZnsK? z*MX*c!YUbsSTfsG$()j6Mx4-*v-`MqSI%dssrW}Dv4nIo zH6+^3UXD!8H#?>?n*&rf6U=5pUF;q>I#IPF(I&Pa5o}NBp)JfNuI?A-j$$^W%;DT^ zTv0nyGQtHSg}5^Kg2>8%h62tBZ~hD*uFuHCg=2WlJNOY3@vA_k zRdcfnTi*(=;SyEs+Aqdpl_-4kL->K=>Kwf|=i<_{ySlFGb@9V{a1D1#qD@R`>@og~ zZK7X7f39mv{{DLrgbPzxg9<*2Q!Mzbtep%FMuNoEBrZ5b)Jm7+7fCu^pOka(4P}c+d6JiQ$ylcT%z->3aR&yPAln4J z44~4Q&`Wdk5+l`h8ruSvr55Lwvn{Z-=g-}CJe2N}+UAO#TA11d^jDD`jUra&=o}!m z97W@zmZPQty(hdYfZi3f0O*f`8i3vsM1!+m5ERS3Z2qTv2~sr@E5ugty2u8e&UVxn z?WhmhQEzR)060y&psMVcG3KhQ6~)4ajY4 z?!E2Ju2j=Z24M8jDH!24?^wL0xd^4&+z6lmOhQO&0#euEEkLTJtpoZBQG~PyfW8m} zAouq8pDqKTRa;VsZRrr0K`qcTL*vq?)e7qC@cOOpn#=IvRy|eYwQ3%;;jE*PDcXt} zyrU|`tE#N4t8a?TtBKUrEU0X%T~?z-r(>~2?7O)R9_LWja44aFo@o6CstZMjg^4Sq z()H3vQL*4oWp1%5ctWD;jYRERT zjwQ(9q=aoe*~H#(;FeU}UUl(*;G5n6tVkWL{469_83xY3lwtS;NDWKZq4lX@>0TgZ zEI3n*ivi&Sd`iX#0@bA_A7@mE20^`}D85-F4er0Vnpw0g#4I`M-SZL_?Oxwb(*Ol_R_6#8o+*y-XnUn2OBaf_>Nz^Vrof4 zq<&e=()o+)ue8sSsKY%=QnJ+LhdB!41{PM}u@=dxQnoRVX)A@*q-|Hf3rD^ePu6I9 z0`v3ERi6i%GY*6fzH#C%+zG-$d>`YIE0GMwN6(L}G?eI>*Y4*{$^*t~x}JIPjbxd| z5GO0OWXHmHZ6B{^btIB~#m+;CZEn6w%>=fchJqO-Gab&2)B_1Kf%v>YNS<(+Cg@7Y z6iNb371^CYyhfwh!9}{9)rkw@YL=uBjmH#`1&+zojzKjZgXVI~h<@!^4Sg#xvnb8Y zoHk_!uEzBbFoDSnKiONBaSyBP;Cefkt4FD8)WW<(S9>B^2&Pd8t?kYGc;Pp*G+CWn z!NERa7V$sgNeqEDZbC21!_;K;K(xHVwjvbsv^=BW^nGRt=7(FqMC+G;k7l-fes)v8 zme0>=>fQ4Buy89k10>oK0fvliqNOy$ci6%|(QWvjbrW9iv;|)YQhe0Nrg_%r^_=oe zAhTs&!clHv^2!j%P1*6}g3PW-nek+O*8XddYXJ3oLDqgg%9`>IC9lldKL?`C5i3_v z5nkO1S$d&2UB$w57X$8T*z)lxLxL64|A9pZXoa3FrEP;Nh>~S_Yq91K<0HLlZp1q> zSa!(ldZy%}x3BKakO%&dyfSmuS6SiJ-!yb3R&5C#_)bcrp$<(X&d9J-gZLaexniSq zUiHp_psA0>$C(3aW~x*MoH_Y`DQ14Vwn*`$cx;POOuIlCxhJ9T#8PV?Q%A^F8XG{+ zi?cX2W(UF*Q26E_h%A#bb}yN7w*aV=$r6FmfGA?&A3hULUQpQjkET9PBK6vkD?xtYK3)L3vgZf;^0yqQ`cj3+0l zdwoOpj%-iP9dICsMSD&gBc(d}lzBa$7rSEa?8{|+r&;Vk6u}kZT27P576Ua3`YzB? zK{s2z&see-Eg7F^RlI&cO3Ud$-;%IHf$9W}0$L&{X35HczA3WlmW)rcFA&)yKq@WI z1F1M(15$B(2y}*6v4a-sgPu2E!j1(}zC{+|b&m4A4M^!*52W;QzmAIcEz9>k%Qu2% zUL%^n0i<%oyRktg<-XkT*$-PMb2_G_qKvL3p$=E{+v;CiFLXhoBQpns*6s z$N0H@;;onM-OQ)_b`;3{VXGZBXQFlN=dQ-Ys`jsFaHG((SNRu?{4k!(L-XBR*j7mU zYRHp8vnS+*Te(M(l$OyKhFf374?V~p@Ep*pL%59G3Sb6Dk5eI&1y*N*io5J8zDE@W zA?mnZbl{qErMC`a(1?$Q4n7Eug*FB&H-i-eFlmY8ahJ;(=!13^-gW!h*F^!U7$uQDg*b#m- zCTV9vk>HM){@I$sccW{X|D>{_AF@?5AC|``y0>N2h0VRx2!c!-HGooIO*6>MjNGH* z5v?p-M_h~tkr;~2ae6d{=^uW51WnO@QMow?uNtL=TWM|SPiN@{Y91OH4w|wU$4XWFwm=ApHlqe1y&lu@R4Nbjq$64LR z8rfc|t5%iJRoCDE!4mGYR)FznY3zzCFhrn99@x#(Thipj$ex43PO>0dyB`wF}8+xJO_P zLs~U{E8b!t#k&be>EnW!^5sTO<@q-KO)>d#k0F zI{$VAy>|aotJh6v%)O9^OLKVUMjB;{uL5qWBpl;t_4#bP|oN3c% zsLRU+_sr)o?g%Qo%$fU(JE#K-v*S+MN8rAu8i}hInUcdQW0n-fd|U;_^k*YvO>+`m zcq|<|Ui+sk^OgA9}@Ws#n14 znZmyzLaxJXw3S#B=DnBibI*G>Cc3t%>D?MUGMg+z2;01us?9{?;L3Kgj;BIbhA_qI zrSs{|m7HxAhj6FH#F=spt>jsHF>Y5WoUIoRF!2D~Z#OX>lyOW_boH1GZizL_z2fq1 z#~^>|4)tIlHFS>#QWJ_O&?_*(A=x!mCulNcFA16lq-3o?>PmP6keUi?1XB850D3_} zybh#7dQjGbfXtq|4xx* z1F3k=15#RM0;zZ_fmFQQ1NF3o;CmTVh;=|J#P5Jq2riwg5Zu+ZRYGvzvj?%Wmd#Q%kW2Lzf(E@)NAozX+$lJ;eqIc$s*R@yQ ze^oDB3l{b*g5sG%6&iB{~ zAe#iP?L(nR<5gXKe5B5 z0q{I=_glPAg9x&!L$r^m4Y9)}g^C3ocNMm+-2K4qJbNwfi#;WaTQi zV2fYw`_#%$+jnvdNU*bv9u@H6fwc{2Ee;k~I2UTmO+rXXI~WWmR<4F>?D4y_55e|@ zcM|Pj`oEtyszp^+|=@lQJXz9z_zk}xwIVR<+l9tA?;%mo7Z-&?QgevsKjc& z#8Ca)FQ#%&Wf}=l?={?1x=yrFx27Z4Czx#1y-^E{#qhE#JCLGy&0e;8PIiiAWi=wqf zoZSaUx{E581rtKgcQ|hsWBZ5-)Mnwg`(U~e))zOz`gnGlC~t(}>@fV%Y}qajYHyDh zzokJxZbo~Bs%zS6s@iI*^BaihmZi70simQ^&4b@>Y;JG!HaFEZ;#a^I+wNfwy~jI+Q(QZBxY_S3R--{y59LxFl}qW=XQ{tRc>R>Uc92hv(;G9y-?IC z#1rL;V*2DhNOil+jKdM#HpglU4(u{R&8A&uXgQA-;d^>6#?fv<_aKh!lJXReP8H>Y z`lFr2SsZve=tH`J@U=^YeMF^Vfbc7#=lSpqZGUWP?O)cXc@BO@tOZ$)UmNpct03-3 zx7IZ^dTT4|>Kz3@oR$TEGSNF_nt0}}t2QItU8A8g^>fNpSCc`Ptg|YOE6C~0<&h%dNLO)p%FwWS`~p}(U!Jo6~~65#i1v7i(?0`II*{5%hQq1wrwwV zgdLRWi#utVzPV`wa3^gSc^^$|kXmt~p9uLt4c*nI!N!q~xAlW>hAiMY@0pL&mr}U_ z7aOQ%KF-E=YN&w~`;i!V>2~u?aluw@M(@Ci<1z0q)J}?I%D0mJSDwOWoM_-bgb(#n zc2hV4M|QDJP^3kHtipj^tXpwp7waogDO@@8{_^al2Qx zZMJ8E!$45(*Sei?iy`Bv4Gg^a|MNa$`tyDa5&q8i}D{lZz}E>GfW* zWGfAgg_z~m2|nOizaU;geq*ZszbDosC3$4 zlT<0`xT~;jVBPwdl7>S6fPC0!0C#K;gE$qNi9@)9|yFshmwnn%=C z?|J!+covEVFC(g3FbG{(Lssb0i;Jiy;ci5A&7AhRCGEUrwbfy?jN80Ya=6_@CueuJu^d$|ar~@x9+EblBqzFSC zMO8~*(r^ly2#Wm4ZP@(v1Wi$CB}W=gVIc<8AUX-R!=C5jQ`x#l_}T9U;uMt&Z7V(K zprf^@spnV4X3DQ)YR0~n`<>i z`?ScBhEr5;ii^DXB-iVeOa9Q*6_O$ir~1K1=hwtO114*V*1yP+hEv!i>7YLOV%Zu^ z?IbUdG@R-$s6FsWZvHR(#55I`6lpj`^{lu^QSa^Ae3zz9kQ8Y+wIid<-A}w-Q+G&; zG@ROrQNRAaV^~w0Bt;rd?JTI>@kwr{19!VxQ)**4X*flro8lrxUGwZ>EGkJ8;yqv# z7HK#|L+@fdglW4^s&8?m#tN#$aHQcB)nZ-d-x>bgquLhTJ|{;SP7Q>Qwl(pTCms2< zK~kjQ6xByfh0k3xSlgnvv6CYWrzjnYi>N&zx9c|F%+k~_=}j6=QK`_jHaEZYrlx|D zA`Pdgbt*2Rn3MCL^{}IUHA{*#oTBG0HMO$gHAh{(N>ZfZ)ZT)k93i*t=*ynaF?>x@ zq~R1znTv}Q_430%jM9{9CP~97TB+3SMvwQ`AFZiU*|?I1Q(i{hRdExhDXJXKkrZh- zg-nGl)y~)SeCAS3oi8cUaB2vn-q`f7CQZ@(7;>cH)KK^o7t!^SyYTznf7BF>e8`c8 zQzh^zR;N9SPJIxA9d%t}B}E!e?I$Q@YyX`Vp_5V66iJbWQ~L`_W~XQRH4nCEYPFI!VrRwrc*VZ4QDZH{kIMQ&6#vZz+TwU?YCQZF1DbjFixS*(xlY81X4#PZkUG#=@ za-`wZf$-67RO;+o(5NeFFj9sbX*hKdd^D9jY6iMfMNN?uX*hMTpkyKNB)Rk|GVKMhZ&h*V-fM92BJ|Inr>d3_g0yHt^ruI<6}xDbjGt$EZ!_ zgCCK?b`MF4G@SCoN86fq;~OZ*iuy`Yq~TP#pj5B7N9&%GG_@xUpx{WuDKvkMG`#7Y z_Ukp3krZh-HCj+A4Oc#S_VJopAt};uY7C?Nga0~9Q+G*4i!Dm6Zl z6lpj$j#1~Yy!}N@?M(wiIMQ%xJbZMCy6n#(k85h0q)5Z5!x(kQz7~>M#V{u+(s1f< zLG6i8ay{RF@HtIACMnWz3Jn=zsHl4?-hf2e`bkox;Z%j7sJ|vRa%IPKO%103FC1w& zWxz*|4^NtV&MlgnB`MNyDj+BnS>gUXWV566o+~NRa4HBN-4nH~nsUCjMQ_UT+zhEridsnR>}1U|(@UVM@}@Y9JHlBkrgl@w_> z6@`zcW-lw-sHy8EMH)`U1T_$!NZJq)5Xli%~Ca zXn#Ue^k#cWz>q#|8UghwUQzYrzQxB#`)xK8~w`hq_Eu^k|GVKCc;OLZGOM;NJK|b zz53fUX*h*01eCJ1&zp~)r75qZNW-bgg4!9MK&E=Xp zQBtJg)Koz!Tl;>yVX3ArkrZh-HI3Q2Ve|7RYw8(Ek%m)83QFbjfo)41t<8TVMH)__ zsl|0E>e34aI$E{?18@?KG@LpLKDsWy{mnW1>lhv(DbjFihM;=llU&);FMO@3CP|To zQ#0YCZPoSfcuiBQBt;rd%@UL<8$0Y%nbnloB!ly$;ndNBQX{>FyWY4!Q(sA2q~X+T zK`C30{n7tgP4(IlC*erLsbk=yOYdLD?2e{ImH9D}A`PdIsSYZ$e9>c?nlCBRaB7aA zcETsQ0|(ysKTTaGDbjGN3O>bnd!X$u-TV#`M#YfcZBLFgoI+FUpuV5AsZ3KpNs2U_ zs$o>%vD2Q`lvhT9G@Pmxl&W7#rjK*vvLz|faB422o_%PtBfpkNiZq;>Cn$N^GwZBb zI8>>zR(g|$Q|P=MsquA#ZMu!=hEogRqx;IcFFR^q zO_j++A`PeN1*KYmXCAm5RZv~mTuG6JQw@w-IOE6LGSalhhEr{VQe|W11xq(-s(4qNgd+{7+To+i zhQDp6p_&>eDbjFip`g@tz3>hF-k>TQ$4ZJcoLVHPf%qhM_m1Ntnz~L>q~X+J_!Jjy zO9Mco;hEq%6qx-Mx>sLXdV)(P9NW-b)7`5B#&(6?Pi7cL^;neYh+6SNH ztSk2YO;ZykMH)__%SQ|q_2<%KF$z*KJY7OyUFh~^`xXo!>MJAx^m2Z zC??9*pOPXCr%n{q-uNWU~L(hEppTHQ=yyziMi?K{yFV8cv-IAKd~hKWwkv zHI=2V?2A0ICOtay(B5paOzY>-Mk^-u=SUuNW&=% za~=6LdBsKNYg;35jpRtfsa5dNx%}VCpE0;l`88Kkq~X-*f|42InX|l&3wnpL*S2n(DC!PQsCfQ)j|QkLQm*Zcso|qa;NdPOTP{ zvQ<>`!uFb)ASu#t>MTL^#3#9b93HFC)JjQ_hEr$5N2h#`3wL=|Q&&ogG@LqzQFpZ; zcbKL&N{Td`I#*D#x%51{Z|h7=^_P{EG@Lq*QA_^Z`vy%NAt};u>YsvAW#g9iK$)f* zBt;rdp|Bz~6t&ldhdO%mDNs2U_ zx)eTo<#yFCKfkG|Yb8Y*PF=>RF}q$gSW|CEiZqUd4PAt};u>KZ}y!Y8>E({GGv>RU;XhEtf#IBfMO zSqBdl-|b`?rv4=< z(s1e~_~^QP%ttf-($v$EA`Pc7*m6+QPQRiHXoY6@4^ysH8~4soNR#@;M(01wP;sk|GVK?tqU@ z!}gM=kJ7ekBt;rdq1ZWM7{7X-=QMSqq)5Z5y9AXly>%1b(9|W8A`PcdF&r`6=G2d( znz~m~q~X*(j9RE2D!mPoA`Pb=7L>~6Z}wb2QB$W$iZq;hL{O@Ynm+mMtfsD& z6lpm1D5I{QxatQ@Jt`^EaOyEZsaiSw-O+M(GQZYR8`DGt#>PJbDhEtC- zYSccz{YO*%2IC|gX*l%+d~`0KJZI4+O&uU9(s1fYM%~r>p3gKDkQ8Y+^%SEv{_nPL zH8n$0q~X+hL8&x6ey5tWrrIS%8csdUY_05bmt*8`wxmeIsb`q2-%RoggXFa0*?%qqUj)!|*Mdx=2!_;nb^wQnm8+&AZlV>Mluh$EK1)6$MQl#P3>w;3LarZY@qcZh?AGyyYMH)__lXK+PeSP~Mqp2Q4aT1O+oO%;J zy6xSv$QCHtR`b$myC@Io#>H|Tk7;ZCT0jhH|rUhEwQ<9Wngsrw>pN6!nXwNW-bm88!X1 zNvIZz8n7Qu!jXnkU%*GF#xtjEw~MBRONum{LSc1Ky)QZEJWYipMH)_h#VF6HT~V1- z3};D-G@L@`?XWep*H?}*zfe-7;nX*bdiE)=qx7CFDbjEXLm7vyU5`87(SO}2DbjH2 zJ3(!WPjZhA{>RRwu-#LVA`Pd$hmTJAOQ&slTvH!QiZq=1pP;tEC%N=tCu3-=Z2c}N z(s1er_-I=L*5xc)X-cQwd3thEo`9 zIc(jt=DA^-s+JUKIE5(?s9yLax6t#@F`7D2Ql#P3FYwW+@zdV#wrc89Ns)$A7+yGH zSaZn+M_s;0Ql#P3uZ;Tgs=YBJQTg?Xq)5Z5-xxLY#np}&ekCc=aO!tPy|wtW`Px>m z18@?KG@SYaJ~}m4ZX5#-6~n=jA`Peh6qG6(Z@qd08g)gDmlSC@^_QS};gj5dCp>qz zrlv}YG@R;yk1mI&4_`7G5qNElf#<&x1>nJDSFwaj^T$tOgKYRKTC=KZxHaEjhhtYbK~{l{sVI!IEa;S{|nLdWo!Z96W|R76sw;S{|FM%U%j z2R!Vcj*%2;IJKRidfFG@*(1^~q-`yg6lpj`zeB69YuUpC6Pmg}Ql#M&J@crk1&hx_ zSD?!L?UEu5r}{GLn$z!h)UW3yMH)`gv*y~?SKlmoNZa~UQl#M&Jq4<%*rus#H1(IH zNW&?5ldI0JJx;vnCQS_*ZYM2iI7P4J(YDrZSA4Uke3Bv!r*>pi$9<7oHI;zkrZh-HHg`&KQ4EWwzchnb}o~K zQ@b-;*I#(u-kKUBDbjFi4`yq-y+@y?sly~i8cyxWY~8!&GsksJlN4zPRmrTVX)kNt^WRh6imq)5Xldhw0k1M?2vOroi^k|GVK=%>wf4BJkm zm!B$IPfCh3obn1v#qg{}KRMd@_a#LdP7P+ZLc6X;0Ls=DNs)$A^!^eZ!y7izD>xOk z6UqrW(r{|1pi~Us{^$Y+b+DvJ!>JNMsWHIo!Sg0*TQNzIhEw!ZyKVtKk6hPJQ&o~8 z4X5^J)QUcbkI~dJNs)$A2M9{l<=lXG$~AS7q)5Z5VT_vJamH9p-6<*3aB4WCmR)!I z!J672DbjH2Kt>&~=g%WFwMkN>;nYEbQu%e=iw`f;lm~Xnk%m(TGh0{pdjR39vazS6 zNW-Z^1f_EMrkT&TXsTRNq~X*EMjiddH48K~K~kjQ6uqxa*UC?hdekunXpj_XI8`br zmCHAH4;ZX%oh~WTaB8HWR2m+-{BB2?zgAMD;S~MOrmkOCCjRTywjPrdX*lI$)E+Zw z2C7p29Z8XfQ+`3I7%txRtur+Bqohc~sd7f0x#qF+HMPSbqG)(X!zp@JUSHSgt4};x zQ^O@i8cvO7RR4=g|Dmanq)5Z5F^n4X!w)BEYL=u(!>O@?QmOI4Q+xcVsYQ|^4X4I2 zTL;?{6FCoua8-(ejWZ4W|rdtFiCo%QRIgDbjE% zz-*mz!4Ai2Dj_M-a4N{Cb2pS#YpO<4q~TOZP^yhOHvQ*%O`Rku(r_xwY|Thluh7(G zk|GVKBFxrjbFRirP1WW5Bt;rdMFpkWsEPIY=>vza)YK7@A`PdKf>JSD z^Xs~YHFczSKF3o>NiP|hEo#-rBY*? zwaX9J)UKs=*&q$4CJ9Q#aF^v@pRTEqk|GVKCNt`se_nHzrjn8(4X36EN|lZCR_{Ag zQ#Fzz4X36GN?q4=lb*O!QzuD^G@P0yD0N-GPdLr7iglT!NW-Zk88z#*fgfvI_ezR1 zoSM$44@R6iM^mpziZq-$icy&p|20TcUrLHJoSMO?N1oXWi-oF<>N(QRWzukJCZiTz z{Kd5$r@sk%m*V85R6w&hy$7#r`%xP`KY2m6x$oS~O{ZEE0 zG@cP{HH+J%szy+_U=NXNON%biSFu}}EvhNVLD= zAfl=^&6gBuc&V#r)JYrOy;@VtB}E!eH8ASc4+ed%sY@h98r%Mz(ubnf!!x_KzOB6# zZ*rB6=X;|Fc>q4C3>`i!^_-o~Bz{DO(^%xC_&CzJNl+@CuN=4G-Nt-6za%N4Vd>m# z+oGW1X56^!WKC_7l+cLt9qcN|tB+5dz=w#B=;6g%g(`B!M_ zSV;*DEAxv4wG(1T?oaQpO)7Qp^D&Yljh$i-NuSR7wOE9+gB^@#_V1e!q{^>nB}E!u zR+k70Lx16V4=H}fP9N0dnzH$}?~)>Ssvak(eep?d<*JeQ*wp+o;%wjJirg*9@q$vR z>KpcT@p1W7{aMCPXjrN)6_jd8?us0Iyrz2kZCgUaO3Mj?LJ<*Z5IkYrB6(eHW%*|F z1UrU~GQUhvDhJR1X{e>saA#?YG&~JY6x83O!y|oR^DmUco1oyy2(* zioqkk2scB9v%JV1=M{odalYY%`D>Qv<6J8#p0FT_kMo=Z#4Cxq=bgG39AI9uIq=;e8&v&XGxKU zx4ow`YWj_jAEi@c2dw>)BMql=j9RmH2ogoL8~aO&G&~K@5ET7f(~b!Bg4a)!tufg+ zLQ-cGxzq4WL8&xcS^QY~jC>lVBqcN~4Oa_FUbg4?HC3B6RV68*VQF}lpi~;x*8aSY zzOLgWMH+rxXA26qY(-t}pM4e$54?msS5jvexv%RSL8raloG%dJT!v2!+&$+lzVT@t z=YFH?;4dh0r}Kq^Qt7c;_cgeIhBLVJ*@% zf*Ow4k$d&qzb;cLi1+79iZncTt`*b)Hsm?t(_2o}lz)uvO&U&JCn#0w&c5}K{WR4g zDbn=t(5PE_cqk3|sC%slXCwwT{b6d^z~>B|s<%mOZIQd4UN0z>s%O@IcG=o|sy-?y zp<$_dgP_phinjNZJ`>6{wNX++!{$x@Vzxe>@ZKs-eJ?4YVYY4*6t!bCW@~)#Qm>}A z8w)Qup<%XeVzv%C;=mU*HAGTE!))DLz}9$42@SJ#3$t};-Lkek?&)Ivd*S7AJl+Z9+cNVbqlB9%& z*}99_`r5i`owl_}QbNOQ-7P5UFQ{zn^7vg*P5mV)p<%Y}VYV*3X!@_3+HD+_C;ZA5 zX_&2hnXPNS|9HNpMo3C%n63Mmtph*#WE)LIB_%Y>*8PG~W&VjT&1y{@Eh(X4wrJj8 zT%_vq{EvH`p{a$E5*lXf!8}FRy--}~TJ-D+JUDbny> z=3zl~-OIczsfUZaF6t3Mb=}K+EU8C2QI87hKE#gf2VP?;V~H;n3T9h9acr{I$R9)Toi+JW=GOGVe%@Ck3Ta;y6uU4 zYBWhoXjp1IB`B(u920BKg+`T=NsF0Cb4Biae_l{3 z->;gx{*~wQ`CcO_p<(&{f}m8Zwbx1KKBK9{k`fwL#x^ip%f}~1X(}fvp<%XO6x3e0 z4r=*RyY1YhsVgKUG|bjZ%+{VO&-z+ZcSuTTn5~xurA9md+2)QDH1(9EgofFo6&u|e z_y1t|NKI{&l+Z9+uQFS2dHS5BsV^lZG|bj(%+|lN=dIDypOO+9X6tokYfbB7M}7^! zjES7kFk5dhTc`dp?MrQIsHB93*?Ln@s%-o+tSP6dQIZlGX6r3x%ewf`WtxghN@$p^ zjm*~NU-@3w)J#bU4YTz&vo-F^nPWB8Bq^a`w%%d3Zhs}PLQ{0lnw-!uTkkSkJAAk4 zDNUU(DWPGu-V@Xygop#r*i(Bysj0P+5*pU}{aa8}OUTWOByLbG3!dJW6lr?UI%HMz z5?g1tt60sbuW5Ap(DAF1qGP*_`Y`X~g^#oSd0$wk-xQ`9PWt?zr|I_ROG&+7wn$27So(Y@D3v}RX3tM+s^1Y5TaQO*#L-acLtl8y|B(m>H?)L% zXU9|TSJ&zBjF1#*IQ223X5PE`ZcQa5MH){1M^H2mCg*LsXt}0pB}E!eeZp*QIk@2o zO|6g=X*l&MqrQE9@$H(rQc|Sh)PDt~V)*X3(=o@la~&%*k|GVKHVI1g<~NO-d$6Y7 zmK13~IaVP)6BPYQEsZQc-QkJP?9zhYRVr(q+tx~H^jVR+w0tfoRa&n8_p-^KEc0UAtQ)^<9xWzrGig%CB3d9<|`Re14rEDWPH4^*=%FC9kVj z#b=8&wOUd_!>;QGLG2BS+{ODJyg`@4HIgEYU83KXKBVR4`9~2B{o_=m_+!3FBBt;rKoUHVb;W%o_W)Tj}Y;fROubUyM%|*hx zgZf!eUC*TEN$TfL)GvbS@Yug=^^abcp<0twa*GV{pXZk%VaqXh*di#E%bR*7_x~lI z%O^`pXjm@)Dk!Rz(6C(oO;G#Tr#)Bv@%Ftc1wEcyBt;sYr@sqI z<>~7WZm8DOCP|UTo?BsAS2#)yKDYWqghRikNv+oNeK%u)7GA>b60raOqsUzg{uER` zeKy`c<&S*&43(77u=M#$P^#6sAyO96)Obk=4Qoj{n61aFj_;$XNsd9=4oj&AWntDM}Lc?s~hXozi_1&Kz?5n9yBqcP=Rxd%RmjB%?=Q(WsE-9g5 zwx}%WG<@@}_5s?~&Oy6G2@SJ_pH~N^Y~6ZN-%Xl2NK!(>Y;DJEg>S3*LsKD12@SKg zy`a=s>wwz-EYs9-}?xv>sG5-Qhj=Osh&Dot-gZly46}PslJ`4eu5fXgx>>1 zf^EFJ5+eb85$*y>^|L8QtF?omRINOC%ok_$>!C)1*Go!hSZdJS)#4&mdfz;(&o!EQ zTv9^AQhorlRo7$cE}D8zQbNOQ?I~6SLa;vPfZ;lDWPGl@h*ZIBGYz)LtoQl#On@ved*Tf+TkI%P(U>6HuG+gcY?l!q&q)Yr|O*H%$J z8GDc_N&*4Hp^rra$#5nW(fUbkm5tSvE!AD=Eh83>N8*7<+?ZC=iXgLRTbq0 zD1R&-4rbG#j1ihQX)=#M+=!->naPz*`G~kW5GZ&Wn`0`Lrca}p;Rgs zV4)R=TQF{oP3B!tnVz{J`fFhNxZ8a@hF_bVODCXfrI?S0ub|OY395(}jM9`Sr z)Hru51vzd8BcWi}GA3u-1vz3^W+ssdq1ecP3Y$#_9+9D{nnlBR+w=!=J=u~0ON zrXuXBj1eOg%|wEcxT(S^WYsh>Rt8xf&l-~}TN^4Hw^kfYBbbdN6T%q>P{=~mFjFxz z76~K))HT=C6}+%u)QHCeiFnLHib{E*(BnoZYh~i;v@xj#AzPJ=3kqi#>U}nrKzkWW zF{F?Y%P=#MP%;rp7?YaX+ve%|UZ`2NjCeAXidc!bn<`{0gQhGL4&s7RmGzZN&^XsL z)-|@a*B8F5@@yh*rV}B{NChl+LChH0cs!L3P*F}D zm}mvI!enAr(n2jICg0r^$UT2FnvTSh$%GN=RId|8CK-rE5^Lr2J&LUv*XYHci@PB`oovJo@V@lZULMcvc!Dlq&)4M)?RjKwlWx~WC9CZg0+ znJ9cU86zBuU?`Bzc10Gtri76;gP{Pb8Yc@~7m9w^Ol30BG-nFgv5E|WEDH%3ML|Qs;ZPw@}p|dT5in{G89=A!r0mc6*3et zGDvXLb|iXDGY$3%sWS!|jSPky$XptU>Jj4BhQt^a;)(*vBpK=gEo2o{HDg-wAgXF= zNo8Y0WlOZx?*gg4F#l)W;un- zpwq@+E|m@j+?4C;m@U)Drm}%-)+h9?O8W>Kd(~%@{NXlIXm^@;H6IMKyi3E&fQ%g-{;Z%wksdPFPPi2EjT_|jf z(acOH5HbTsqNb(2wX(jZp7bcK;v*b)*B!y^J{k@NqPV)o z>a7j8BStJ5PG>_I^!T>AfLWBPq?N)PE*3V-%0-oRTkGR}VPr}shIzZ0bq(-LBbrSH z(vft?5mX`DXiB2!0})oNrKYBFQC$_r$pxyKKbZ|AF#X1~HsVerjM1^$kV;?)z!6ws z>p?Sw3Llc@x851VG1-kIEHfc(*hC>4Ap;W!q!XZZIDCw{lIbkg zrs6KBkf8`FiiKH+6*VGrmo#r>+!aAxNGHPC0G0-9b)m2^uC?NUP$-Hv{_m_�(@P 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 X<@{8XZA6jcV4yoea{m9=r}uvV#EP}R literal 0 HcmV?d00001 diff --git a/bin/win64/libpqtypesdll.lib b/bin/win64/libpqtypesdll.lib new file mode 100644 index 0000000000000000000000000000000000000000..f0ce13c21d7deded0aee767c7163826dc7436d0c GIT binary patch literal 7516 zcmcIp&2Ljj5FY}Rl91py-*G60BAWI9B(VcX2!$q8jR^4UIH=-cjQtFjOziq2Di?a= z#EAn3RPG%36LR3hfdlHXM}#U){0EhwGyC;+o?o8xFg$6p-kEvx+nt@AoqaiWq0lJa zz1V*`$)CB@!u+|p`GvFdoPS1j=N8T>$*q0>xCAh817PqGz|bpzk#~~f7XgTd-$Z=O}$4M()4RdQ+?P+8b$j=<8LL6I@m`Vn^p7#TcpXSic;7j#ZF3^d4ThIkk7AP zb*^V~`IXD-%h^>YcRic0R&LjSZ{4rEO~~i3ZLFcF3#l2pn4x^eAFe&tf`5;&P^ ztyrk$Zmw>YYiOc!ub$^TCv(Sbxs67xVZ??ZWS2?yOU130Yz2$!WSV{phT&wy;IrqhKkTpXq~E!8D|ZI&#)>PmfY!lX_!Cb7qrJttGyth90}FyyLw z94FII4$r#HcC}^v;A4Aw+>%z4Tqjekx`hT;u~?p!_4e)MYN6Q_(JBX}O<5vOf1~L( zR@`!B(=Bo9`mGKH@7?9vy?U)#X$4?eBDHqQwf3gx1+iX|rR3-)*C&@O{XRLscu~GD zSX$n23oX~DAbCn-rCsM@VxX)|k!}J>^aPhNDGG$c*XwSPGJ*81#lk2-kqSMdVDqA9 z=<_B+AIF?}V*udMAiyikx$i~*F2(`g3}c>~0r-G4guLg-qXfJ*0Z_$u8{0DKyhs3i zi~+1*yM=mNQvf%o0UjgoJ^p@;zx%M=#{B*k-*d2?9RqlR^mGy+g>({iA0Q4M6>tne zhT$-L1N)&L4#EiRgBh5HBk&yzz#t^x5DY;Qj=~g-!UT-LB*Y;G2jDn-3wxliM+@933ZXISU=0r?uNk_0Lfyk8BZ!0^AFlJ%CZW5<@ z!!YdE+AWcXRjlf*$~K*5s`TUS+Q2lR(~N#AVAt!cN3HObb;8(D-g(}9-kBP(#TbjH zE19Xaf=ctci-(zYSXx{e0~W*E^YQ@HA}=a5$Bqrnv$7Ir1?0Yfbk&idMC33_#4&-u zBmw!;gpSEZVt|I-X^7&=SY>%p2Zj}6T2YHsr1{xay!l0Z3ALS$*we4c2()`v;x^G} zQjJ%G7RKBr3V?e?7$ z>#7S_?!qJ8QSB1Mem+$x6|TO8}YOr@s}X^ z5=&#uy$7iaLwr&{z)0)>vdKI>bPGs4i(jo28?|Pw+)B=7e@w2eUb`ZszCVYsPh%kh z%>DF>#;{-f;y^f(B9;m`A-_;y3M~S6$Qlx_~fze5O z9O8dZf7CHGS|K{{0%YKA(5@sF_bMSW(j_qGnr+kj4oR6g4F&GJmb8SEDJJ@p}`z@_qMf+862+do9CB5HL znn!y7=#FYh?`wE?H{MO+7`|jaOPy1JiT(w#XG;$$r(yYr&puv#@x=q)?Y;}bu=aRZ z^0eT_qhsj}=bIOn$rw8{FIh?WU?Rt7Di!QMETb_~Y8*Vjd_cV0-FNA^V4S03l?aCy zKiobv*~M$mXd#)RU!YlKu@8)QcM%gISOXT8sJFRs z-$vU7R)`l5Sy-}=_kl%^kC1&e=%LXS!3V{=yO>uo~>mIzB1%IMc95ofgRQTZIoM@(jbO$b`Y^ x+!7pj7dvl Last updated 2015-02-27 + diff --git a/source/ChangeLog b/source/ChangeLog new file mode 100644 index 0000000..0465ef5 --- /dev/null +++ b/source/ChangeLog @@ -0,0 +1,364 @@ + +LIBPQTYPES CHANGE LOG +--------------------- + +Initially, libpqtypes was a libpq patch named (PQparam/PGparam) and can +be found on the -hackers and -patches mailing lists. This change log +begins at the point libpqtypes was put on pgfoundry as its own project. + +To gain access to the "(NOT RELEASED)" code, do a cvs checkout. + +(NOT RELEASED), v1.5.2 +- BUG: Fixed putting binary empty strings. Previously, the string was + incorrectly converted to SQL NULLs, but now are properly packed and + transmitted. + - Reported by: Dmitry Epstein +- FEATURE: Added ability to put SQL NULLs for int2, int4, int8, float4, float8, + numeric,"char", bool and money types. This is accomplished by using + the type-spec pointer flag "*" and allowing these types to be passed as + pointers: + >> + int *i = NULL; + if(something_is_true) + *i = 10; + PQputf(param, "%int4*", i); + >> + Before this change, the use of "*" flag for these types was ignored + and passing any of them as pointers was not allowed. + - Requested by: Dmitry Epstein and several on stackoverflow. + http://stackoverflow.com/questions/18684331/passing-sql-null-as-a-sql-statement-parameter-value-using-the-postgresql-libpqty +- Updated Copyright statement from 2011 to 2008 - 2015, affected all source + code and man page files. +- Update an example within docs/man3/PQputf.3 to include putting a NULL + using the pass-by-pointer type-specifier flag '*'. +- Updated docs/man3/pqt-specs.3 to include documentation in regard to putting + NULLs using the pass-by-pointer flag. +- Removed the use of pqt_allowsptr() in spec.c, All built-in types now support + the use of the pass-by-pointer '*' flag. This was only allowing + variable-length data types like text, pqt.str, bpchar, etc... + +Jun 27, 2013 v1.5.1 +- fixed issue in spec.c where the type name was not being lower cased + when it was required. +- Moved AUTHORS, ChangeLog, INSTALL, LICENSE and README to EXTRA_DIST + - Jozef Mlich +- Modified configure.ac and Makefile.am to properly do SO versioning. + - Jozef Mlich +- error.c uses the GCC contructor attribute so it can create the the + TLS key for each thread's error structure. For whatever reason, + calling the constructor function 'my_init' was causing it to never + get called?!? Renamed it and all is well. This becomes apparent + when libpqtypes is linked with apps using pthread_key_create. +- Removed -no-undefined from LDFLAGS in Makefile.am. This proved to be + annoying. +- Updated groff2html so it no longer includes an inline style for + pre tag width. +- Updated pqt-handlers.3, the PGtypeHandler structure was out of date. +- pqt-composites.3 man page had a bug when registering the simple and complex + composite. It was only indicating 1 type instead of 2. + +Apr 11, 2011 v1.5.0 +- Bumped version to 1.5.0 due to many API removals and additions. +- Added -avoid-version and -no-undefined to Makefile.am. +- Added PQinitTypes to replace PQtypesRegister. The new function + adds no new behavior, just a name change. +- Deprecated PQtypesRegister, use PQinitTypes in its place. +- PQclearTypes was added to allow one to clear all registered type handlers. +- Added an internal API pqt_cleartypes since clearing the type data + is now called from PQclearTypes and pqt_eventproc. +- Added a PQclearSpecs function that allows clearing all prepared specifiers + in a single call. Currently, specs can be cleared one at a time by + setting PQspecPrepare's 3rd 'format' argument to NULL. This is useful + but makes clearing all specs difficult because it is not always known + what specs have been prepared by all modules of an application. +- Removed "automatic" re-registering of types during PQresetXXX. This + fails miserably during asynchronous resets. Replaced with the + folowing call sequence: PQresetXXX, PQclearTypes, PQregisterTypes. + NOTE: It is not required to re-register type handlers after a PQresetXXX. + It is only useful if there is concern that registered types may have + gone stale. + WARNING: If an application is reliant upon automatic re-registration of + type handlers during a PQresetXXX, you will have to update your + code to manually do a PQclearTypes followed by PQregisterTypes just + after the reset call. +- Removed the orig_xxx members and regtype from PGtypeHandler structure. + These members were used by the reset event which was yanked. +- Finally 86'd PQregisterTypeHandler, which has been deprecated since + v1.4.0, around 18 months as of Apr 2011. +- Updated copyright date from 2009 to 2011, affected source code and + man pages. +- Updated AUTHORS file to include a list of maintainers and some verbage. +- Deprecated PQregisterSubClasses, PQregisterComposites and + PQregisterUserDefinedTypes in favor of PQregisterTypes. This new + function takes a 'which' argument that indicates if PQT_SUBCLASS, + PQT_COMPOSITE or PQT_USERDEFINED types are being registered. This + function provides full support for asynchronous type registration via + a simple 'async' boolean argument. The typical PQconsumeInput, PQisBusy + and PQgetResult should be used to obtain a result. After a result is + obtained, the new PQregisterResult function needs to be called + to complete the registration. +- Added PQregisterResult which registers the types found within + the result set. Added to support asynchronous type registration and + to avoid type lookups for every new connection by caching the PGresult + type data for use with this function. +- Add PQregisterTypes.3 man page and added it to the make system install. +- Add PQregisterResult.3 man page and added it to the make system install. +- Removed referneces in documentation and code examples to PQregisterSubClasses, + PQregisterComposites and PQregisterUserDefinedTypes. Replaced with + new PQregisterTypes call. +- Regression test now uses PQregisterTypes. NOTE: no regression test + for PQregisterResult or asynchronous type registration yet. +- Marked PQregisterSubClasses.3, PQregisterComposites.3 and + PQregisterUserDefinedTypes.3 man pages as deprecated. They are still + installed with a `make install` and will be until removed. +- Added PQparamDup, which given a PGparam will make an exact duplicate. + This is useful in cases where you want to queue qeuries to execute + at a later time, like a connection pooler. The problem is PGparamCreate + requires a connection object, which may not be available when attempting + to enqueue a query with its PGparam object. Instead, a PGparam object + can used for the sole purpose of creating duplicates while there are + no available PGconn objects. +- Updated PGparamCreate man page to include documentation about PGparamDup. + +Feb 26, 2010 v1.4.3 +- Fixed bug in handler.c. The type lookup query was matching typename + its array based on the array name being '_' plus the typename. This + was slower and unsafe. + +Oct 03, 2010 v1.4.2 +- Fixed bug in events.c. When clearing a type handler list the 'max' count + (amount allocated) was not set to zero. This caused a crash during + a PQreset call. +- Updated PQgetf documentation, clarified how to handle errors when + getting data types that require memory management: PGresult and PGarray. +- Moved libpq-events.h out of libpqtypes.h and into libpqtypes-int.h. + Added libpq-fe to libpqtypes.h. + +Apr 06, 2010 v1.4.1 +- Fix memory leak in events.c during PGEVT_CONNRESET. Not a big deal as the + leak occurs within an out-of-memory error case, so the process is most + likely toast. Either way, leak has been plugged. +- pqt_allowsptr was returning FALSE if the type's schema was not provided. + It now returns TRUE as it should. +- Fixed how missing types are handled during register functions. They were + not properly indicating errors in all cases. + +Nov 10, 2009 v1.4.0 +- Added PQgetvf to compliment PQgetf. PQgetf is now a light wrapper + PQgetvf. This did not change the behavior of PQgetf in any way. +- Fixed bug in IPv6 regression_test. When AF_INET6 is available, the + 'hints' parameter to getaddrinfo should be supplied with the ai_family + set to AF_INET6. +- 63% Performance improvement to the type handling duplication which occurs + whenever a result is copied or a PGparam is created. Previously, the + type handlers contained allocated strings for the identifier names: + like type and schema name. When duplicating the handlers, the strdup + cost added up to a noticeable amount of time (mostly seen during + PQgetf(a_composite_or_array) which duplicates the handlers when generating + a new PGresult). These strings were changed to fixed length buffers + 65 bytes wide; 64 max char identifier plus terminating NUL. The names + no longer need to be deep copied, they are instead copied as part of a + larger memcpy. Additionally, the attDescs array now uses a fixed length + buffer when the number of compsoite attrs is <= 16 (common case). When + larger, allocation is used. 'freeAttDescs' flag was added to the + PGtypeHandler structure to indicate if the attDescs requires freeing. + In total, these changes made type handling duplication 63% faster. + NOTE: + This increased the size of PGtypeHandler by around 434 bytes. The + size of PGrecordAttDesc increased by 65 bytes. This change modified + 2 public structures so please ensure your libpqtypes.h is current. +- Split PQregisterTypeHandler into three different functions: + PQregisterComposites, PQregisterUserDefinedTypes and PQregisterSubClasses. + This was done for two reasons: needed the ability to register multiple + types at the same time, avoid round trip issues, and simplify the interface. +- PQregisterTypeHandler is now deprecated and should no longer be used. It + exists only for compatibility reasons. It is a wrapper to + PQregisterComposites, PQregisterUserDefinedTypes and PQregisterSubClasses. +- The PGEVT_REGISTER event was not be handled properly by libpqtypes. It + neglected to initialize the internal type formatting information. +- Error case in pqt_parse() was accessing a NULL pointer. +- Bug in network.c when getting text inet/cidr types. Apparently, windows + requires a few hints about the address family when using getaddrinfo: + both IPv4 and IPv6. This must be a recent Microsoft winsock update as + this code used to work. + +Sep 15, 2009 v1.3.4 +- In v1.2b, a caching system for type spec format strings was introduced. + PQputf and PQgetf would cache the last spec format seen, like "%int4". + This avoided constant type handling lookups when using arrays, since + one must put/get every element. This version expands on this concept + by adding an additional API call: PQspecPrepare. The application can + now prepare an unlimited number of spec format strings. + NOTE: + This change does not effect the behavior of putf or getf in older versions. + Although, some libpqtypes code may run slower since type spec format + strings are no longer automatically cached. If you have loops calling + putf or getf with the same spec format string, typically arrays, you + would probably benefit from PQspecPrepare. +- Added a PQsendf() and PQsendvf(), same as PQexecf and PQexecvf except they + are asynchronous versions. Created manual pages for these functions as well. +- Fixed a bug in PQexecf and PQexevf documentation, the prototypes were + documented as returning an int rather than a PGresult*. +- Fixed spelling error in PQspecPrepare.3 man page and added PQsendf and + PQsendvf to the list of supported functions. +- Fixed memory leak in the error handling code. Multi-threaded windows + builds were not cleaning up the internal error structure in error.c. + This is because windows has no automatic cleanup for TLS storage. The + only solution was to use fixed length buffers and truncate unusually + long error messages; including error fields. + +May 29, 2009 v1.3.3 +- Added PQexecf and PQexecvf which allows one to pack parameters and + execute a command all in one statement. Example: + PQexecf(conn, "SELECT %int4 + %int4", 1, 1); +- Updated the PQputf.3 man page execf documentation which stated that + execf should be implemented by the application ... not libpqtypes. + Apparently, we no longer feel that way :) +- Fixed bug in datetime.c that accessed index 7 of a 7 byte array, ooppps. + Thanks to GCC version 4.3.2 for catching this one: + "src/datetime.c:930: warning: array subscript is above array bounds" + +Apr 27, 2009 v1.3.2 +- Slight change in the behavior of PQputf and PQputvf. These functions + will now silently auto-fill unset composite fields with NULLs. This only + pertains to the last N fields: if there are 10 fields in a compsoite + and only 7 are put, the last 3 fields will be auto-filled with SQL NULLs. + Previously, an error was raised indicating the client and server have + different ideas about the number of fields in the composite. That error + is still raised if the number of params exceeds the number of composite + fields. Auto-filling only occurs when the number of params falls short. +- User-defined CFLAGS were being lost due to a dumb assigment at the + top of the script. It now properly appends flags to the ones supplied + by the user. +- Updated PQgetf man page to include a warning about getting arrays and + composites. If getf fails after an array or composite was retrieved, + the PGresult representing the array/composite must still be cleared. + The solution is to get arrays/composites by themselves or to always + make them the last field in the getf call (the latter only works + if there is only one array or composite in the field list). +- Fixed SEGFAULT when getting a NULL compsoite array item. + +Feb 11, 2009 v1.3.1 +- PQgetf of an empty array was always returning a result with a single + tuple (array item), eventhough the PGarray members were correctly set + for an empty array. This has been fixed. +- Added empty array test to regression-test.c. +- getaddrinfo is missing on Windows 2000 and earlier versions. Wspiapi.h + and ws2tcpip.h must be included to provide a replacement. libpqtypes-int.h + neglected to include Wspiapi.h, which it now does. + Microsoft docs on issue: http://support.microsoft.com/kb/955045 + +Feb 03, 2009 v1.3.0 +- The internal put_int2 and put_int4 type handlers were passing a va_arg + call as an argument to the pqt_buf_putint2 and pqt_buf_putint4 macros. + This corrupted the value being put on UnixWare 7.1.4. The return + of va_arg is now stored in a local variable that is passed to + one of the putintX macros. +- Renamed PGinet sa_len member since it conflicts with some systems. + For instance: SCO UnixWare defines a sa_len macro in sys/socket.h + #define sa_len sa_un.sa_s.sa_saus_len + Renamed it to sa_buf_len and changed all references. +- network.c had an issue with struct sockaddr not being zero'd on AIX. + This caused all inet/cidr tests to fail. Update regresion-test.c + with similar fixes. +- AI_NUMERICHOST defined if not available in network.c. If getaddrinfo + fails with EAI_BADFLAGS, its tried again w/o numeric host. +- AIX defaults to an unsigned char, which broke "char" type handling. + Changed PGchar typedef to signed char and added the GCC option + -fsigned-char to configure.ac. +- Changed the return type of PQgeterror from a const char* to a char*. + Having it be const served no purpose. +- Added PQparamCount which returns the number of parameters in a PGparam. + Added PQparamCount.3 man page and updated Makefile. +- Made errFields implementation more memory efficient by allocating all + fields as a single reusable buffer. +- Reformatted code to match PostgreSQL Project. This changed every + source file so take note when looking at CVS diffs. +- Defined HAVE_VSNPRINTF in port.c when compiling for mingw or cygwin. +- Fixed man page errors in PQputf and pqt-handlers. +- Updated INSTALL file to include the 'install' and uninstall' targets. +- Makefile.am (unix make) now installs PQgetErrorField man page. +- Update copyright notices to reflect 2009: source files, LICENSE + and man pages. +- Removed typeargs state flag PUT_STATE_FREEOUT from param.c since it + is no longer used. + +Dec 03, 2008 v1.2e +- Added support for PQresultErrorField as PQgetErrorField. PQparamExec and + PQparamExecPrepared clear resutls in a failure status, thus removing + the abillity to get error fields. PQgetErrorField can now be used and + it doesn't require a result. + +Dec 02, 2008 v1.2d +- Fixed bug when putting a NULL array item; %null or %pqt.null. array.c + was not adding in the 4 byte length when the length's value was NULL_LEN. + This resulted in "ERROR: insufficient data left in message" errors from + the server during a PQparamExec() call. +- Added a %null test in regression-test.c for composites and arrays. + +Nov 18, 2008 v1.2c +- removed GCC __thread modifier from error.c. Only pthread TLS keys + are now used. The TLS key for the error system is now intialized + with the GCC function attribute "constructor"; which replaced _init(). + This GCC attribute has been around since GCC version 2.7.0, old enough. + The error system used to intialize the TLS key via pthread_once(), + but this function is broken on all version of Solaris prior to 10 + (its actually a stub function the returns 0). This means libpqtypes + versions prior to this one cannot use thread-safe mode on Solaris 9 or + below. Windows continues to use __declspec(thread). +- The PATH geo type was completely broken (SIGBUS) on many RISC processors, + we tested a couple of UltraSparcs, Itanium, PA-RISC and MIPS. This is + due to memory alignment issues (boy, spoiled by x86!). A configure + check was added to detect when strict memory alignment is required + (STRICT_MEMORY_ALIGNMENT) and the source is toggled appropriately. +- Add pqt_buf_xxx functions to abstract reading and writing data + to/from buffers. Another memory alignment change. +- fixed regression-test.c on hpux which was referencing unknown macros: + LLONG_MAX and LLONG_MIN. HPUX uses LONG_LONG_MAX. +- cleaned up a few things in Makefile.am (unix make file) +- win32.mak for MSVC had an issue with include variable. created INC2 + to solve this. + +Nov 11, 2008 v1.2b +- Added a type specifier caching system. Whenever putf or getf are + called, it compares the specifier string with the last one libpqtypes + saw. If it is a match, the parsing and type handler lookup + stage can be bipassed, giving a 25% performance increase for arrays + and large result sets. This also makes libpqtypes noticably faster + than using libpq in text mode ... PQexec. +- preprocessing bug in port.c, #elif HAVE_VSNPRINTF instead of + #elif defined(HAVE_VSNPRINTF). +- windows was completely broken from a change in v1.2a. Apparantley + windows has different memory addresses for DLL exported functions; + the address seen outside the DLL and the address seen from within the DLL. + This broke the PQtypesRegister macro that was referencing PQtypesEventProc, + since the external address was being used to register the event proc + but the internal address was being used by libpqtypes. This problem was + solved by converting PQtypesRegister to a function, which forces the + event proc to always be referenced from within libpqtypes. + PQtypesEventProc was completely removed form the public interface. +- Updated make system to be more configurable, allows setting things + like CC, CFLAGS, etc.. at the prompt (see INSTALL). + +Sept 26, 2008 v1.2a +- libpqtypes uses the libpq event system, an approaved patch for 8.4. + The object hooks patch was redesigned and than renamed to libpq events. +- bug fix in timestamp code +- memory leak fix in error system, didn't clean up thread memory. +- pqytpe's PGEventProc is now a public function named PQtypesEventProc + +May 19, 2008 v1.0c +- Bug fix in datetime.c. When performing a time value conversion, 1-based + and 0-based month values were being used/confused. +- libpqtypes using objecthooks, a proposed patch for libpq allowing + outside apps, like libpqtypes, to hook into libpq. + +May 09, 2008 v1.0b +- Added copyright notice to all source files. +- Updated several man pages. +- Added an include for stdarg.h to libpqtypes.h +- Updated makefile and groff2html + +April 28, 2008 v1.0 +- libpqtypes project was created on pgfoundry +- make system was put into place (mingw, cygwin and msvc support) diff --git a/source/INSTALL b/source/INSTALL new file mode 100644 index 0000000..5a80559 --- /dev/null +++ b/source/INSTALL @@ -0,0 +1,119 @@ + +LIBPQTYPES INSTALLTION GUIDE +---------------------------- + +*) UNIX BUILDS + +For quick builds, run the below: + + ]# ./configure + ]# make + ]# make install + + (Also `make uninstall', which removes all installed headers, + libs and mans pages) + +By default, only a shared library is built. To build a static +library, use the `--enable-static' option. + +To build a thread-safe version, use the `--enable-thread-safety' option. +To use libpqtypes in a thread-safe environment, the system must have +pthreads installed. Most systems will have /usr/include/pthread.h +and /usr/lib/libpthread.so or /usr/lib/libthread.so. + +The default prefix is `/usr/local', so if the `--prefix' option is +not specified the header file(s) will be installed at +/usr/local/include and the library file(s) will be installed at +/usr/local/lib. + +If your system doesn't include a `long long' data type, resulting in +a library compile error, you can specify an alternative by setting +PQT_LONG_LONG=data_type during configure. + + ]# CFLAGS="-DPQT_LONG_LONG=my_int8" ./configure + +Files installed: + + - $(prefix)/include/libpqtypes.h + - $(prefix)/lib/libpqtypes.so + +When `--enable-static' is specified: + + - $(prefix)/lib/libpqtypes.a + +To dynamically link with libpqtypes, pass -lpqtypes to the linker. + + + +*) MINGW AND CYGWIN BUILDS + +There is no configure for MinGW or Cygwin. Execute the below from +the root of the source tar ball within the cygwin shell or msys. + + ]# make -f Makefile.win32 [options] [targets] + + + +*) MSVC BUILDS + +MSVC versions 6, 7 and 8 have all been tested. Versions prior to 6 +may work but are not supported. + +The MSVC build uses `nmake' and can be executed from the root of the +source tar ball at a DOS prompt: + + > nmake -f win32.mak [options] [targets] + + + +*) MINGW, CYGWIN & MSVC BUILDS: + +For the below examples, MAKE is defined as: + + # MSVC + MAKE = nmake -f win32.mak + + # CYGWIN & MINGW + MAKE = make -f Makefile.win32 + +Targets: + + all - build the libpqtypes library + test - build the libpqtypes regression test + clean - delete all files generated by compiles + install - Install the binaries, headers and man3 pages + uninstall - Uninstalls libpqtypes, reverse of install target + +Thread-safe: + + $(MAKE) MT=1 + + NOTE: MinGW and/or Cygwin may require installing pthreads. + +Specify alternative 64-bit int data type: + + $(MAKE) PQT_LONG_LONG=my_int8 + +Global make & nmake compiler/linker variables: + + CC = C compiler + INC = includes + CFLAGS = compiler flags + LPATH = library path. MINGW and CYGWIN use -L while MSVC can supply a single path + + # If libpq is not installed and you use MSVC, try this (replace paths): + > $(MAKE) INC="-Ic:\pgsql\src\interfaces\libpq" LPATH="-Ic:\pgsql\src\interfaces\libpq\Release" + +Files generated: + + libpqtypes.dll - Windows DLL + libpqtypesdll.lib - Import lib for DLL + libpqtypes.lib - Static library + +Where to install files: + + - System Include Path: libpqtypes.h + - System Library Path: libpqtypes.dll + - System Library Path: libpqtypesdll.lib + - System Library Path: libpqtypes.lib (static lib) + diff --git a/source/LICENSE b/source/LICENSE new file mode 100644 index 0000000..9bd43f4 --- /dev/null +++ b/source/LICENSE @@ -0,0 +1,22 @@ + +LIBPQTYPES +Software extension to the PostgreSQL libpq interface. + +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this +paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL ESILO, LLC. BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, +ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +ESILO, LLC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +ESILO, LLC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, +AND ESILO, LLC. HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, +ENHANCEMENTS, OR MODIFICATIONS. + diff --git a/source/Makefile.am b/source/Makefile.am new file mode 100644 index 0000000..182e6e1 --- /dev/null +++ b/source/Makefile.am @@ -0,0 +1,68 @@ +AM_LDFLAGS = +AUTOMAKE_OPTIONS = foreign +@SET_MAKE@ + +srcfiles = src/array.c src/datetime.c src/error.c \ + src/events.c src/exec.c src/geo.c src/handler.c \ + src/misc.c src/network.c src/numerics.c src/param.c \ + src/port.c src/record.c src/spec.c src/utils.c src/varlena.c \ + src/libpqtypes.h src/libpqtypes-int.h + +manpages = docs/man3/PQgeterror.3 docs/man3/PQgetf.3 \ + docs/man3/PQlocalTZInfo.3 docs/man3/PQparamClear.3 \ + docs/man3/PQparamCreate.3 docs/man3/PQparamExec.3 \ + docs/man3/PQparamExecPrepared.3 docs/man3/PQparamReset.3 \ + docs/man3/PQparamSendQuery.3 docs/man3/PQparamSendQueryPrepared.3 \ + docs/man3/PQputf.3 docs/man3/PQputvf.3 \ + docs/man3/PQseterror.3 docs/man3/pqt-composites.3 docs/man3/pqt-handlers.3 \ + docs/man3/PQgetErrorField.3 docs/man3/pqt-specs.3 \ + docs/man3/PQtypesRegister.3 docs/man3/PQparamCount.3 \ + docs/man3/PQexecf.3 docs/man3/PQexecvf.3 docs/man3/PQspecPrepare.3 \ + docs/man3/PQsendf.3 docs/man3/PQsendvf.3 docs/man3/PQgetvf.3 \ + docs/man3/PQregisterComposites.3 docs/man3/PQregisterUserDefinedTypes.3 \ + docs/man3/PQregisterSubClasses.3 docs/man3/PQregisterTypes.3 \ + docs/man3/PQregisterResult.3 docs/man3/PQinitTypes.3 \ + docs/man3/PQclearTypes.3 docs/man3/PQclearSpecs.3 + +lib_LTLIBRARIES = libpqtypes.la +libpqtypes_la_SOURCES = $(srcfiles) +libpqtypes_la_LDFLAGS = -version-info $(LIBPQTYPES_SO_VERSION) +include_HEADERS = src/libpqtypes.h +dist_man_MANS = $(manpages) +noinst = src/libpqtypes-int.h src/getaddrinfo.h + +EXTRA_DIST = install-sh src/regression-test.c src/getaddrinfo.h \ + win32.mak groff2html Makefile.win32 \ + AUTHORS ChangeLog INSTALL LICENSE README + +.PHONY: test +test: + $(CC) $(CFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H \ + -o test src/regression-test.c $(LDFLAGS) $(LIBS) -lpq -lpqtypes + @rm -f regression-test.o + +.PHONY: docs +docs: + @find docs/man3 -name '*.3' -type f | xargs -i ./groff2html \{\} + +uninstall: + rm -f ${prefix}/include/libpqtypes.h + rm -f ${prefix}/lib/libpqtypes.* + @if [ 1 ] ; then \ + _manpath=`man -w PQgetf`; \ + if test ! -z $$_manpath ; then \ + manpath=`dirname $$_manpath`; \ + for man in $(manpages); do \ + man=`basename $$man`; \ + if test -f $${manpath}/$$man ; then \ + echo rm -f $${manpath}/$$man; \ + rm -f $${manpath}/$$man; \ + fi; \ + done \ + fi; \ + fi; + + + + + diff --git a/source/Makefile.win32 b/source/Makefile.win32 new file mode 100644 index 0000000..d9a2077 --- /dev/null +++ b/source/Makefile.win32 @@ -0,0 +1,49 @@ +############################################################## +# Project: libpqtypes +# Makefile for Cygwin or Mingw Environments (GCC) +# +# make -f Makefile.win32 [options] [targets] +# +# For further build instructions, see the package's INSTALL file. +# +# Authors: Andrew Chernow, Merlin Moncure +# Contact: libpqtypes@esilo.com +############################################################## + +PROJNAME = libpqtypes + +DEPS = src/libpqtypes-int.h src/libpqtypes.h +OBJECTS = src/array.o src/datetime.o src/error.o \ + src/events.o src/exec.o src/geo.o src/handler.o \ + src/misc.o src/network.o src/numerics.o \ + src/param.o src/port.o src/record.o src/spec.c \ + src/utils.o src/varlena.o + +INC += -Isrc +LIBS = -lpq -lws2_32 +CFLAGS += -s -Wall -Wpointer-arith -D_GNU_SOURCE -O3 \ + -std=gnu99 -Wlong-long -D_WIN32_WINNT=0x0501 -D_REENTRANT + +ifdef MT + CFLAGS += -DPQT_THREAD_SAFE -D_THREAD_SAFE + LIBS += -lpthread +endif + +ifdef PQT_LONG_LONG + CFLAGS += -DPQT_LONG_LONG=$(PQT_LONG_LONG) +endif + +all: $(OBJECTS) + dllwrap -o $(PROJNAME).dll -dllname $(PROJNAME).dll $(OBJECTS) $(LPATH) $(LIBS) + dlltool --dllname $(PROJNAME).dll --output-lib $(PROJNAME).a + +test: + gcc $(CFLAGS) $(INC) -o regtest src/regression-test.c $(PROJNAME).dll $(LPATH) $(LIBS) + -@rm -f regression-test.o + +%.o: %.c $(DEPS) + gcc $(CFLAGS) $(INC) -o $@ -c $< + +clean: + -@rm -f $(OBJECTS) $(PROJNAME).so $(PROJNAME).a regtest + diff --git a/source/README b/source/README new file mode 100644 index 0000000..bdd6b97 --- /dev/null +++ b/source/README @@ -0,0 +1,54 @@ + +LIBPQTYPES LIBRARY +------------------ + +This package contains the source code, documentation and management +files for the libpqtypes library, an extension to the PostgreSQL +libpq library. + +libpqtypes is a libpq extension that offers a new way of handling +parameterized queries and getting result field values. Both +putting parameters and getting values use a printf/scanf style +interface, with consistent specifiers for both. + + - Full support for binary and text format (parameter and result) + + - Full support for composites, arrays and composite arrays. + + - printf style interface to libpq's binary parameterized API. + + - scanf style interface for getting values: PQgetvalue extension. + + - Ability to register user-defined types, aliases and data type + sub-classes for use with printf style interfaces: ex. "%mytype". + + - Per-thread global error message: PQgeterror, PQseterror. + + - Online docs as well as man pages. + +INSTALL +libpqtypes cannot be used by itself, it can only be used with libpq. +To build and install libpqtypes, see the INSTALL file included with +this package. + +LICENSE +libpqtypes is released under the BSD license just like all software +components of the PostgreSQL Database Management System. See the +LICENSE file included with this package. + +AUTHORS +libpqtypes is a contribution of eSilo, LLC and was written by +Andrew Chernow and Merlin Moncure. See the AUTHORS file. + +To report bugs, feature requests or general questions goto the +libpqtypes forum at http://pgfoundry.org/forum/?group_id=1000370 +or send an email to . + +Online documentation: + + http://libpqtypes.esilo.com/ + +The latest version: + + http://pgfoundry.org/projects/libpqtypes/ + diff --git a/source/acinclude.m4 b/source/acinclude.m4 new file mode 100644 index 0000000..ad3001c --- /dev/null +++ b/source/acinclude.m4 @@ -0,0 +1,139 @@ +AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + + +dnl the only difference - the LANG selection... and the default FLAGS + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])]) + +AC_DEFUN([AC_C_LONG_LONG], +[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long, +[if test "$GCC" = yes; then + ac_cv_c_long_long=yes + else + AC_TRY_COMPILE(,[long long int i;], + ac_cv_c_long_long=yes, + ac_cv_c_long_long=no) + fi]) + if test $ac_cv_c_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, [compiler understands long long]) + fi +]) + +dnl AC_CHECK_FUNC_IN(HEADER, FUNCTION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +AC_DEFUN([AC_CHECK_FUNC_IN], +[AC_MSG_CHECKING([for $2 in $1]) +AC_CACHE_VAL(ac_cv_func_$2, +[AC_TRY_LINK( +dnl Don't include because on OSF/1 3.0 it includes +dnl which includes which contains a prototype for +dnl select. Similarly for bzero. +[/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2(); below. */ +#include +#include <$1> +/* Override any gcc2 internal prototype to avoid an error. */ +]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus +extern "C" +#endif +])dnl +[/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $2(); +], [ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$2) || defined (__stub___$2) +choke me +#else +$2(); +#endif +], eval "ac_cv_func_$2=yes", eval "ac_cv_func_$2=no")]) +if eval "test \"`echo '$ac_cv_func_'$2`\" = yes"; then + AC_MSG_RESULT(yes) + ifelse([$3], , :, [$3]) +else + AC_MSG_RESULT(no) +ifelse([$4], , , [$4 +])dnl +fi +]) + +dnl AC_CHECK_FUNCS_IN(HEADER, FUNCTION... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +AC_DEFUN([AC_CHECK_FUNCS_IN], +[for ac_func in $2 +do +AC_CHECK_FUNC_IN($1, $ac_func, + ac_tr_func=HAVE_`echo $ac_func | sed -e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' -e 's:[[^A-Z0-9]]:_:g'` + AC_DEFINE_UNQUOTED($ac_tr_func) $3], $4)dnl +done +]) + diff --git a/source/configure.ac b/source/configure.ac new file mode 100644 index 0000000..0d9a95c --- /dev/null +++ b/source/configure.ac @@ -0,0 +1,157 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.57) +AC_INIT(libpqtypes, 1.5.2a, libpqtypes@esilo.com) +AC_CANONICAL_TARGET +AC_PROG_MAKE_SET +SET_MAKE="MAKE=make --no-print-directory" +AC_CONFIG_AUX_DIR([.]) +AM_INIT_AUTOMAKE(libpqtypes,1.5.1) +AC_SUBST([LIBPQTYPES_SO_VERSION], [1:5:1]) +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +AC_PROG_INSTALL +AC_CONFIG_SRCDIR([src/param.c]) +AM_CONFIG_HEADER([src/pqt_config.h:src/pqt_config.h.in]) +AC_PROG_CXX +AC_PROG_CC + +CPPFLAGS="$CPPFLAGS -Isrc" +if test "$CC" = "gcc" ; then + # always want reentrant funcs, not just thread-safe mode. -s + CFLAGS="$CFLAGS -O2 -Wall -Wpointer-arith -D_GNU_SOURCE -D_REENTRANT -fsigned-char" + + # gcc doesn't indicate an error for unknown options when they are + # not warning/feature options, -Wxxx or -fxxx. We have to test manually. + cprog="int main(void){return 0;}" + gcctest="gcc -x c -c - -o /dev/null" + + AC_MSG_CHECKING(CFLAGS for gcc -std=gnu99...) + result=`echo "$cprog" | $gcctest -std=gnu99 2>&1` + if test -z "$result" ; then + CFLAGS="$CFLAGS -std=gnu99" + AC_MSG_RESULT(-std=gnu99) + else + AC_MSG_RESULT([no, unknown]) + fi + + # turn on as many warnings as possible + AX_CFLAGS_GCC_OPTION([-Wclobbered]) + AX_CFLAGS_GCC_OPTION([-Wempty-body]) + AX_CFLAGS_GCC_OPTION([-Wignored-qualifiers]) + #AX_CFLAGS_GCC_OPTION([-Wmissing-field-initializers]) # annoying + AX_CFLAGS_GCC_OPTION([-Wmissing-parameter-type]) + AX_CFLAGS_GCC_OPTION([-Wold-style-declaration]) + AX_CFLAGS_GCC_OPTION([-Woverride-init]) + AX_CFLAGS_GCC_OPTION([-Wsign-compare]) + AX_CFLAGS_GCC_OPTION([-Wtype-limits]) + AX_CFLAGS_GCC_OPTION([-Wuninitialized]) + AX_CFLAGS_GCC_OPTION([-fomit-frame-pointer]) + AX_CFLAGS_GCC_OPTION([-fno-strict-aliasing]) + AX_CFLAGS_GCC_OPTION([-funroll-all-loops]) + AX_CFLAGS_GCC_OPTION([-funit-at-a-time]) +else + AC_MSG_ERROR([Using $CC instead of gcc, currently not supported]) +fi + +# Each case has an example of what target_os contains +case ${target_os} in + # solaris + solaris*) + CFLAGS="$CFLAGS -D_STDC_C99" + ;; + + # SCO UnixWare + *UnixWare*|*unixware*) + CFLAGS="$CFLAGS -D__UnixWare__" + ;; + + # SCO OpenServer + sco*) + CFLAGS="$CFLAGS -D__OpenServer__" + ;; +esac + +AC_ARG_ENABLE(thread-safety, [ --enable-thread-safety Enable threads], + [have_threads=yes], [have_threads=no]) + +if test "$have_threads" = "yes" ; then + AC_SEARCH_LIBS(pthread_create, [pthread thread],, + [AC_MSG_ERROR([Missing libpthread.so or libthread.so, cannot use --enable-thread-safety])]) + CFLAGS="$CFLAGS -DPQT_THREAD_SAFE -D_THREAD_SAFE" + + # SCO OpenServer 5, possibly other platforms, requires using FSU pthreads. + # We detect this by looking at the prototype for pthread_getspecific. + # There are a few other prototypes that are different as well but detecting + # one is plenty. + AC_MSG_CHECKING(whether FSU pthreads is being used) + AC_TRY_COMPILE( + [#include ], + [pthread_getspecific((pthread_key_t)(0), (void *)(0))], + [AC_DEFINE(PTHREAD_FSU, 1, + [Define to 1 if using FSU pthreads]) AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no)] + ) +fi + +# If strict memory alignment is required, this test will produce a +# Bus error. Most riscs CPUs (old and modern) are strict. +save_CFLAGS=$CFLAGS +CFLAGS="" +AC_MSG_CHECKING(if strict memory alignment is required) +AC_RUN_IFELSE([int main(void){char b[[8]];int*i=(int*)(b+1);*i=0;return 0;}], +[AC_MSG_RESULT(no)], [AC_DEFINE(STRICT_MEMORY_ALIGNMENT, 1, + [Define to 1 if architecture requires strict memory alignment]) AC_MSG_RESULT(yes)] +) +CFLAGS=$save_CFLAGS + +AC_HEADER_STDC +AC_CHECK_HEADERS([ \ +arpa/inet.h limits.h linux/limits.h netdb.h netinet/in.h stddef.h \ +sys/socket.h time.h math.h sys/time.h strings.h]) + +AC_STRUCT_TIMEZONE +AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,, \ +[#ifdef HAVE_TIME_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif]) + +AC_CHECK_TYPES(socklen_t,,, +[#include +#ifdef HAVE_APRA_INET_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif]) + +AC_CHECK_MEMBERS([struct sockaddr_storage.ss_len],,, \ +[#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif]) + +AC_C_CONST +AC_FUNC_MEMCMP +AC_FUNC_STRTOD +AC_HEADER_TIME +AC_TYPE_SIZE_T + +AC_SEARCH_LIBS(pow, m) +AC_SEARCH_LIBS(getaddrinfo, [nsl socket], \ + [AC_DEFINE([HAVE_GETADDRINFO], [], \ + [Define if getaddrinfo exists])], [], []) + +AC_CHECK_FUNCS([vsnprintf floor ceil rint hstrerror \ +localtime_r strtol strtoll strtoul]) + +AC_OUTPUT(Makefile) + + + diff --git a/source/docs/man3/PQclearSpecs.3 b/source/docs/man3/PQclearSpecs.3 new file mode 100644 index 0000000..85fad56 --- /dev/null +++ b/source/docs/man3/PQclearSpecs.3 @@ -0,0 +1 @@ +.so man3/PQspecPrepare.3 \ No newline at end of file diff --git a/source/docs/man3/PQclearTypes.3 b/source/docs/man3/PQclearTypes.3 new file mode 100644 index 0000000..ef0a6e4 --- /dev/null +++ b/source/docs/man3/PQclearTypes.3 @@ -0,0 +1 @@ +.so man3/PQinitTypes.3 diff --git a/source/docs/man3/PQexecf.3 b/source/docs/man3/PQexecf.3 new file mode 100644 index 0000000..3b0e800 --- /dev/null +++ b/source/docs/man3/PQexecf.3 @@ -0,0 +1,104 @@ +.TH "PQexecf" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQexecf \- Prepares parameters and executes a command. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +PGresult *PQexecf(const PGconn *\fIconn\fP, const char *\fIcmd\fP, ...); +.br +PGresult *PQexecvf(const PGconn *\fIconn\fP, const char *\fIcmd\fP, va_list \fIap\fP); +.br +int PQsendf(const PGconn *\fIconn\fP, const char *\fIcmd\fP, ...); +.br +int PQsendvf(const PGconn *\fIconn\fP, const char *\fIcmd\fP, va_list \fIap\fP); +\fP +.SH DESCRIPTION +.LP +The \fIPQexecf\fP() function executes a command that uses libpqtypes +type specifiers instead of $1, $2, etc... syntax. The idea +is to combine \fIPQputvf\fP() and \fIPQparamExec\fP() into a single call. +The variable argument list must match the type specs listed within the +cmd. The type specifiers should be placed where one would normally place +$1, $2, etc... + +The \fIPQexecvf\fP() function is identical to \fIPQexecf\fP() except +it takes a va_list. + +The \fIPQsendf\fP() and \fIPQsendvf\fP() functions are identical to +\fIPQexecf\fP() and \fIPQexecvf\fP() except they are asynchronous versions, +meaning an additional call, PQgetResult, must be issued to get the PGresult +object. For more information, see the PostgreSQL Documentation: specifically +the "Asynchronous Command Processing" section under +"Client Interfaces | libpq - C library". + +A prepared type spec "@name" can be used with these functions, granted that +\fIPQspecPrepare\fP() was called with a non-zero value for the is_stmt +argument. These functions needs an actual SQL statement to execute. +.SH RETURN VALUE +.LP +PQexecf and PQexecvf return NULL on error and a valid PGresult on success. +PQsendf and PQsendvf return zero on error and a non-zero value on success. +On error, use \fIPQgeterror(3)\fP to obtain an error message. +.SH EXAMPLES +.LP +.SS Using PQexecf +The example uses PQexecf function to execute a query. +.RS +.nf +.LP +\fB +/* The PQexecf call is shorthand for: + * + * PGparam *param = PQparamCreate(conn); + * PQputf(param, "%int4 %int4", 1, 1); + * res = PQparamExec(conn, param, "SELECT $1 + $2", 1); + * PQparamClear(param); + * + * As you may notice, PQexecf makes life much simpler. + */ +PGresult *res = PQexecf(conn, "SELECT %int4 + %int4", 1, 1); + +if(!res) + fprintf(stderr, "PQexecf failed: %s", PQgeterror()); +else + PQclear(res); + +/* A bit more common, this puts an int4 and a text into a generated + * PGparam and then executes 'myfunc($1, $2)' + */ +res = PQexecf(conn, "SELECT * FROM myfunc(%int4, %text)", 2, "abc"); + +/* Prepared type spec example. To use with execf, the final "is_stmt" + * argument must be set to a non-zero value! + */ +PQspecPrepare(conn, "account_insert", "INSERT INTO account VALUES " + "(%int8, %text, %int4)", 1); + +PGint8 acc_id = 78236; +PGtext acc_name = "ABC Coders, LLC."; +PGint4 acc_biz = ACC_BIZ_TECHNOLOGY; + +PQexecf(conn, "@account_insert", acc_id, acc_name, acc_biz); +\fP +.fi +.RE +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQgeterror(3)\fP, \fIPQputvf(3)\fP, \fIPQparamExec(3)\fP + diff --git a/source/docs/man3/PQexecvf.3 b/source/docs/man3/PQexecvf.3 new file mode 100644 index 0000000..77c4e1e --- /dev/null +++ b/source/docs/man3/PQexecvf.3 @@ -0,0 +1 @@ +.so man3/PQexecf.3 \ No newline at end of file diff --git a/source/docs/man3/PQgetErrorField.3 b/source/docs/man3/PQgetErrorField.3 new file mode 100644 index 0000000..e1ca3a1 --- /dev/null +++ b/source/docs/man3/PQgetErrorField.3 @@ -0,0 +1 @@ +.so man3/PQgeterror.3 \ No newline at end of file diff --git a/source/docs/man3/PQgeterror.3 b/source/docs/man3/PQgeterror.3 new file mode 100644 index 0000000..4c9fead --- /dev/null +++ b/source/docs/man3/PQgeterror.3 @@ -0,0 +1,56 @@ +.TH "PQgeterror" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQgeterror, PQseterror, PQgetErrorField \- libpqtypes error system management functions +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +char *PQgeterror(void); +.br +void PQseterror(const char *\fIformat\fP, ...); +.br +char *PQgetErrorField(int \fIfieldcode\fP); +\fP +.SH DESCRIPTION +.LP +The libpqtypes library maintains a per-thread global error message. The error +message is managed by \fIPQgeterror\fP() and \fiPQseterror\fP(). + +\fiPQseterror\fP() takes a regular printf compatible \fIformat\fP string for +setting the libpqtypes error message. + +\fiPQgetErrorField\fP() gets an error field from the last executed query. +The error field is only set by PQparamExec and PQparamExecPrepared. When +using libpq functions that return results, like PQexec, continue to use +PQresultErrorField. + +To clear the libpqtypes error message, call \fiPQseterror\fP() with a NULL +\fIformat\fP string: PQseterror(NULL); This will also clear error fields. +.SH RETURN VALUE +.LP +\fIPQgeterror\fP() returns the last error message for the calling thread. It will +never return NULL. +.LP +\fIPQgetErrorField\fP() returns the error field, referenced by fieldcode, for +the last executed query. NULL is returned if no value exists. +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-specs(3)\fP diff --git a/source/docs/man3/PQgetf.3 b/source/docs/man3/PQgetf.3 new file mode 100644 index 0000000..d1d8a98 --- /dev/null +++ b/source/docs/man3/PQgetf.3 @@ -0,0 +1,104 @@ +.TH "PQgetf" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQgetf \- Gets one or more values from a PGresult in a scanf fashion. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQgetf(const PGresult *\fIres\fP, int \fItup_num\fP, +.br + const char *\fIformat\fP, ...); +.br +int PQgetvf(const PGresult *\fIres\fP, int \fItup_num\fP, +.br + const char *\fIformat\fP, va_list ap); +\fP +.SH DESCRIPTION +.LP +The \fIPQgetf\fP() and \fIPQgetvf\fP() functions get one or more field +values from a PGresult using a scanf style interface. The \fItup_num\fP +argument indicates which tuple to read values from; values can +only be read from one tuple at a time. + +The \fIformat\fP argument is a data type specifier string +indicating the values to retrieve, like %int4 or #timestamp. Any +number of fields, in any order, can be retrieved in a single call. +Each data type specifier has a cooresponding \fBfield_num, type-args, [...]\fP +contained within the function\'s variable argument list. The +\fBfield_num\fP either indicates tuple field number or tuple field +name, depending on whether the data type in \fIformat\fP used a \'%\' +or \'#\' specifer mark (\`man \fIpqt-specs(3)\fP\'). The \fBtype-args\fP can be one or more +arguments required by the specific data type: for example, "%int4" +would require a pointer to a PGint4. All built-in PostgreSQL data +types require a single pointer value. +.SH RETURN VALUE +.LP +On success, a non-zero value is returned. On error, zero is +returned and \fIPQgeterror(3)\fP will contain an error message. + +If the retrieval of any field fails, the get operation is aborted and +function will fail. Eventhough some fields may have succeeded prior to +the failure, their values should not be trusted. Instead, make +another \fIPQgetf\fP() call. Getting an array or a composite can lead +to memory leaks when getf fails. This is because these types allocate +a PGresult object that must be cleared. To avoid leaks, it is recommended +to perform cleanup even if getf fails, retrieve arrays and composites by +themselves or make them the last field in a getf call. +.SH EXAMPLES +.LP +.SS Using PQgetf on a PGresult +The example uses the libpq PQexec function to execute a query and then uses +\fIPQgetf\fP() to retrieve field values. It is important to note that +libpqtypes execution functions, like \fIPQparamExec(3)\fP, do not need to +generate the PGresult provided to \fIPQgetf\fP(). +.RS +.nf +.LP +\fBint success; +PGint4 i4; +PGtext text; +PGbytea bytea; +PGpoint pt; +PGresult *res = PQexec(conn, "SELECT i,t,b,p FROM tbl"); + +/* Get some field values from the result (order doesn\'t matter) */ +success = PQgetf(res, + 0, /* get field values from tuple 0 */ + "%int4 #text %bytea %point", + /* type format specifiers (get text by name \'#\') */ + 0, &i4, /* get an int4 from field num 0 */ + "t", &text, /* get a text from field name "t" */ + 2, &bytea, /* get a bytea from field num 2 */ + 3, &pt); /* get a point from field num 3 */ + +/* Output an error message using PQgeterror(3). */ +if(!success) + fprintf(stderr, "*ERROR: %s\\n", PQgeterror()); + +/* Output the values, do this before PQclear() */ +else + printf("int4=%d, text=%s, bytea=%d bytes, point=(%f,%f)\\n", + i4, text, bytea.len, pt.x, pt.y); + +PQclear(res); +\fP +.fi +.RE +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-specs(3)\fP, \fIPQgeterror(3)\fP diff --git a/source/docs/man3/PQgetvf.3 b/source/docs/man3/PQgetvf.3 new file mode 100644 index 0000000..4fd6848 --- /dev/null +++ b/source/docs/man3/PQgetvf.3 @@ -0,0 +1 @@ +.so man3/PQgetf.3 diff --git a/source/docs/man3/PQinitTypes.3 b/source/docs/man3/PQinitTypes.3 new file mode 100644 index 0000000..4d592ac --- /dev/null +++ b/source/docs/man3/PQinitTypes.3 @@ -0,0 +1,56 @@ +.TH PQinitTypes 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQinitTypes \- Initializes libpqtypes with the libpq event system. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQinitTypes(PGconn *conn); +.br +int PQclearTypes(PGconn *\fIconn\fP); +\fP +.SH DESCRIPTION +.LP +libpqtypes makes use of the libpq Event System. Before using +libpqtypes, you must initialize libpqtypes as a libpq EventProc. +The PQinitTypes function takes a PGconn that libpqtypes will be initialized +with; each PGconn requires its own initialization. + +PQclearTypes removes all registered types from the given PGconn. A good use +for this is after a PQresetXXX call when it might be desired to re-register +all types that may have gone stale. +.SH RETURN VALUE +.LP +PQinitTypes and PQclearTypes return zero if it fails and non-zero if it succeeds. +.SH EXAMPLES +.LP +.SS Initializing libpqtypes +The examples shows how to initialize libpqtypes with the libpq event system. +.RS +.nf +.LP +\fB/* call prior to any other libpqtypes functions that operate on conn. */ +PQinitTypes(conn); +\fP +.fi +.RE +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +None + + diff --git a/source/docs/man3/PQlocalTZInfo.3 b/source/docs/man3/PQlocalTZInfo.3 new file mode 100644 index 0000000..563a6ea --- /dev/null +++ b/source/docs/man3/PQlocalTZInfo.3 @@ -0,0 +1,66 @@ +.TH "PQlocalTZInfo" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQlocalTZInfo \- Gets the local machine\'s timezone information. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +void PQlocalTZInfo(time_t *\fIt\fP, int *\fIgmtoff\fP, int *\fIisdst\fP, char **\fItzabbrp\fP); +\fP +.SH DESCRIPTION +.LP +This function retrieves the local machine\'s timezone information. + +If the \fIt\fP argument is not NULL, it represents a time_t value to get timezone +information for. If it is NULL, the current time is used. + +The \fIgmtoff\fP argument will be pointed at the number of seconds from GMT, +same value as the GNU (struct tm).tm_gmtoff extension. + +The \fIisdst\fP argument will be pointed at zero if in standard time, one if in +daylight savings time and negative one if unknown. + +The \fItzabbrp\fP argument will be pointed at the timezone abbreviation, like +PST, ADT, EST, etc.. +.SH RETURN VALUE +.LP +None. +.SH EXAMPLES +.LP +This example gets the local timezone information for a file\'s modified time. +.LP +.RS +.nf +\fBint gmtoff; +int isdst; +char *tzabbr; +struct stat st; + +stat("report.xml", &st); +PQlocalTZInfo(&st.st_mtime, &gmtoff, &isdst, &tzabbr); +\fP +.fi +.RE +.SH RATIONALE +.LP +libpqtypes needs the ability to get the local machine\'s timezone information for the +datetime data types. It later became apparent that a portable way of getting timezone +information was very useful and in demand. Thus, this function was made public. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-specs(3)\fP diff --git a/source/docs/man3/PQparamClear.3 b/source/docs/man3/PQparamClear.3 new file mode 100644 index 0000000..b26b4b0 --- /dev/null +++ b/source/docs/man3/PQparamClear.3 @@ -0,0 +1 @@ +.so man3/PQparamCreate.3 \ No newline at end of file diff --git a/source/docs/man3/PQparamCount.3 b/source/docs/man3/PQparamCount.3 new file mode 100644 index 0000000..b26b4b0 --- /dev/null +++ b/source/docs/man3/PQparamCount.3 @@ -0,0 +1 @@ +.so man3/PQparamCreate.3 \ No newline at end of file diff --git a/source/docs/man3/PQparamCreate.3 b/source/docs/man3/PQparamCreate.3 new file mode 100644 index 0000000..ba0b6f7 --- /dev/null +++ b/source/docs/man3/PQparamCreate.3 @@ -0,0 +1,76 @@ +.TH "PQparamCreate" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQparamCreate, PQparamCount PQparamReset, PQparamClear \- PGparam management functions. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +PGparam *PQparamCreate(const PGconn *\fIconn\fP); +.br +PGparam *PQparamDup(PGparam *\fIparam\fP); +.br +int PQparamCount(PGparam *\fIparam\fP); +.br +void PQparamReset(PGparam *\fIparam\fP); +.br +void PQparamClear(PGparam *\fIparam\fP); +\fP +.SH DESCRIPTION +.LP +These functions manage the opaque PGparam object. + +\fIPQparamCreate\fP() will allocate and initialize a new PGparam object. +After the create call, the PGparam object is ready for use. WARNING: Only +types that have been registered via PQregisterXXX, will be available +to the param. Meaning, the param is not updated with types registered +after the param is created. + +\fIPQparamDup\fP() will duplicate a given PGparam, including any internal +values that have already been put. This is useful in cases where you want +to queue qeuries to execute at a later time, like a connection pooler. The +problem is PGparamCreate requires a connection object, which may not be +available when attempting to enqueue a query with its PGparam object. +Instead, a PGparam object can used for the sole purpose of creating +duplicates while there are no available PGconn objects. + +\fIPQparamCount\fP() gets the number of parameters in a PGparam object. + +\fIPQparamReset\fP() will clear out any previously put parameters, but will +not free any memory. This is useful for application looking to "reuse" a +PGparam object. + +\fIPQparamClear\fP() releases all resources being used by a PGparam object, +the object should not be used after a clear. + +It is very important to call \fIPQparamReset\fP() if you plan on reusing a +PGparam object. +.SH RETURN VALUE +.LP +\fIPQparamCreate\fP() returns a pointer to a PGparam object on success and NULL +if something failed (check \fIPQgeterror(3)\fP for more information). + +\fIPQparamCount\fP() returns the number of parameters in a PGparam object. + +\fIPQparamReset\fP() and \fIPQparamClear\fP() have no return values. If +either function is provided a NULL PGparam pointer, it will silently fail. +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-specs(3)\fP, \fIPQputf(3)\fP, \fIPQgeterror(3)\fP, \fIPQparamExec(3)\fP diff --git a/source/docs/man3/PQparamDup.3 b/source/docs/man3/PQparamDup.3 new file mode 100644 index 0000000..6839531 --- /dev/null +++ b/source/docs/man3/PQparamDup.3 @@ -0,0 +1 @@ +.so man3/PQparamCreate.3 diff --git a/source/docs/man3/PQparamExec.3 b/source/docs/man3/PQparamExec.3 new file mode 100644 index 0000000..861b3cc --- /dev/null +++ b/source/docs/man3/PQparamExec.3 @@ -0,0 +1,106 @@ +.TH "PQparamExec" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQparamExec, PQparamExecPrepared \- Executes a paramertized query using the parameters in a PGparam. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +PGresult *PQparamExec(PGconn *\fIconn\fP, PGparam *\fIparam\fP, +.br + const char *\fIcommand\fP, int \fIresultFormat\fP); +.br +PGresult *PQparamExecPrepared(PGconn *\fIconn\fP, PGparam *\fIparam\fP, +.br + const char *\fIstmtName\fP, int \fIresultFormat\fP); +\fP +.SH DESCRIPTION +.LP +The \fIPQparamExec\fP() and \fIPQparamExecPrepared\fP() functions execute +a parameterized query using the parameters in a PGparam. The only difference +between these functions is that \fIPQparamExec\fP() expects a parameterized +\fIcommand\fP string while \fIPQparamExecPrepared\fP() expects a \fIstmtName\fP +previously prepared via PQprepare(). + +Both functions take a \fIparam\fP argument, which must contain the same number +of parameters as either the \fIcommand\fP string or previously prepared \fIstmtName\fP. +Internally, the \fIparam\fP is transformed into parallel arrays that are +supplied to a PQexecParams() or PQexecPrepared() call. + +The \fIresultFormat\fP argument indicates if text or binary results are desired; +a value of zero or one respectively. \fIPQgetf\fP supports both text and binary +result formats, with the exclusion of arrays and composites which only support binary. +.SH RETURN VALUE +.LP +On success, a pointer to a PGresult is returned. On error, NULL is +returned and \fIPQgeterror(3)\fP will contain an error message. + +\fBIMPORTANT!\fP +.br +There is a difference in behavior between \fIPQparamExec\fP() and \fIPQparamExecPrepared\fP() +and the libpq functions they wrap, PQexecParams() and PQexecPrepared(). +\fIPQparamExec\fP() and \fIPQparamExecPrepared\fP() only return a non-NULL +PGresult when the result status is either PGRES_COMMAND_OK, PGRES_TUPLES_OK or +PGRES_EMPTY_QUERY. If these functions detect any other result status, the +PGresult is cleared and a NULL result is returned. Before clearing the PGresult +and returning NULL, these functions first copy the result error message into the +libpqtypes error system, accessible via \fIPQgeterror(3)\fP. This allows applications +to get a result\'s error message without needing the result object. \fIconn\fP error +messages are also copied to the libpqtypes error system. + +This behavior difference provides a single error indicator, a NULL return, and a +single function that can get the error message, \fIPQgeterror\fP(). +.SH EXAMPLES +.LP +.SS Using PQparamExec +The example uses \fIPQparamExec\fP() to execute a query using a PGparam. +The example also demonstrates how to detect a failed exec and output an error +message. +.RS +.nf +.LP +\fBPGparam *param = PQparamCreate(conn); + +if(!PQputf(param, "%text %int4", "ACTIVE", CAT_CAR)) +{ + fprintf(stderr, "PQputf: %s\\n", PQgeterror()); +} +else +{ + PGresult *res = PQparamExec(conn, param, + "SELECT * FROM t WHERE status=$1 AND category=$2", 1); + + if(!res) + fprintf(stderr, "PQparamExec: %s\\n", PQgeterror()); + else + print_results(res); + + PQclear(res); +} + +PQparamClear(param); +\fP +.fi +.RE +.SS Using PQparamExecPrepared +\fIPQparamExecPrepared\fP() is behaves identically to \fIPQparamExec\fP(), except +\fIPQparamExecPrepared\fP() requires that a statement has been previously prepared +via PQprepare(). Also, a \fIstmtName\fP is supplied rather than a parameterized +\fIcommand\fP string. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQparamCreate(3)\fP, \fIPQparamSendQuery(3)\fP, \fIPQparamSendQueryPrepared(3)\fP diff --git a/source/docs/man3/PQparamExecPrepared.3 b/source/docs/man3/PQparamExecPrepared.3 new file mode 100644 index 0000000..c5f975f --- /dev/null +++ b/source/docs/man3/PQparamExecPrepared.3 @@ -0,0 +1 @@ +.so man3/PQparamExec.3 \ No newline at end of file diff --git a/source/docs/man3/PQparamReset.3 b/source/docs/man3/PQparamReset.3 new file mode 100644 index 0000000..b26b4b0 --- /dev/null +++ b/source/docs/man3/PQparamReset.3 @@ -0,0 +1 @@ +.so man3/PQparamCreate.3 \ No newline at end of file diff --git a/source/docs/man3/PQparamSendQuery.3 b/source/docs/man3/PQparamSendQuery.3 new file mode 100644 index 0000000..23e3ab7 --- /dev/null +++ b/source/docs/man3/PQparamSendQuery.3 @@ -0,0 +1,89 @@ +.TH "PQparamSendQuery" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQparamSendQuery, PQparamSendQueryPrepared \- Executes an asynchronous paramertized query using the parameters in a PGparam. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQparamSendQuery(PGconn *\fIconn\fP, PGparam *\fIparam\fP, +.br + const char *\fIcommand\fP, int \fIresultFormat\fP); +.br +int PQparamSendQueryPrepared(PGconn *\fIconn\fP, PGparam *\fIparam\fP, +.br + const char *\fIstmtName\fP, int \fIresultFormat\fP); +\fP +.SH DESCRIPTION +.LP +The \fIPQparamSendQuery\fP() and \fIPQparamSendQueryPrepared\fP() functions execute +an asynchronous paramertized query using the parameters in a PGparam. The only difference +between these functions is that \fIPQparamSendQuery\fP() expects a parameterized +\fIcommand\fP string while \fIPQparamSendQueryPrepared\fP() expects a \fIstmtName\fP +previously prepared via PQprepare(). + +Both functions take a \fIparam\fP argument, which must contain the same number +of parameters as either the \fIcommand\fP string or previously prepared \fIstmtName\fP. +Internally, the \fIparam\fP is transformed into parallel arrays that are +supplied to a PQsendQueryParams() or PQsendQueryPrepared() call. + +The \fIresultFormat\fP argument indicates if text or binary results are desired; +a value of zero or one respectively. \fIPQgetf\fP supports both text and binary +result formats, with the exclusion of arrays and composites which only support binary. + +After successfully calling \fIPQparamSendQuery\fP() or \fIPQparamSendQueryPrepared\fP(), +call libpq\'s PQgetResult() one or more times to obtain the results. +.SH RETURN VALUE +.LP +On success, a non-zero value is returned. On error, zero is +returned and \fIPQgeterror(3)\fP will contain an error message. +.SH EXAMPLES +.LP +.SS Using PQparamSendQuery +The example uses \fIPQparamSendQuery\fP() to execute a query using a PGparam. +.RS +.nf +.LP +\fBPGparam *param = PQparamCreate(conn); + +if(!PQputf(param, "%text %int4", "ACTIVE", CAT_CAR)) +{ + fprintf(stderr, "PQputf: %s\\n", PQgeterror()); +} +else +{ + int success = PQparamSendQuery(conn, param, + "SELECT * FROM t WHERE status=$1 AND category=$2", 1); + + if(!success) + fprintf(stderr, "PQparamSendQuery: %s\\n", PQgeterror()); + else + get_and_print_results(conn); /* calls PQgetResult() */ +} + +PQparamClear(param); +\fP +.fi +.RE +.SS Using PQparamSendQueryPrepared +\fIPQparamSendQueryPrepared\fP() is behaves identically to \fIPQparamSendQuery\fP(), except +\fIPQparamSendQueryPrepared\fP() requires that a statement has been previously prepared +via PQprepare(). Also, a \fIstmtName\fP is supplied rather than a parameterized +\fIcommand\fP string. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQparamCreate(3)\fP, \fIPQgeterror(3)\fP, \fIPQparamExec(3)\fP, \fIPQparamExecPrepared(3)\fP diff --git a/source/docs/man3/PQparamSendQueryPrepared.3 b/source/docs/man3/PQparamSendQueryPrepared.3 new file mode 100644 index 0000000..53e207b --- /dev/null +++ b/source/docs/man3/PQparamSendQueryPrepared.3 @@ -0,0 +1 @@ +.so man3/PQparamSendQuery.3 \ No newline at end of file diff --git a/source/docs/man3/PQputf.3 b/source/docs/man3/PQputf.3 new file mode 100644 index 0000000..999c986 --- /dev/null +++ b/source/docs/man3/PQputf.3 @@ -0,0 +1,120 @@ +.TH "PQputf" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQputf, PQputvf \- Packs a set of parameters in a PGparam for use with a parameterized query. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQputf(PGparam *\fIparam\fP, const char *\fIformat\fP, ...); +.br +int PQputvf(PGparam *\fIparam\fP, char *\fIstmtBuf\fP, size_t \fIstmtBufLen\fP, +.br + const char *\fIformat\fP, va_list \fIap\fP); +\fP +.SH DESCRIPTION +.LP +The \fIPQputf\fP() and \fIPQputvf\fP() functions put one or more query +parameters into a PGparam using a printf style interface. Any number +of parameters can be put at the same time. + +The \fIformat\fP argument is a data type specifier string indicating the +parameters being put, such as "%int4 %polygon". \fIformat\fP cannot be +NULL or an empty string. The variable argument list must match the +\fIformat\fP, either "..." or \fIap\fP. The number of arguments required +for each data type is dependant on the data type itself; built-in +PostgreSQL types always require a single argument. + +The \fIPQputvf\fP() function can construct a parameterized command string +from \fIformat\fP, as long as \fIstmtBuf\fP and \fIstmtBufLen\fP have been +provided. If the construction of \fIstmtBuf\fP is not desired, set it +to NULL and set \fIstmtBufLen\fP to 0. When a constructed statement is desired, +the contents of \fIformat\fP will be copied to \fIstmtBuf\fP and +all data type specifiers, like "%int4", will be replaced with $1, $2, etc... +syntax. The result is a parameterized statement in synch with \fIparam\fP +and ready to be executed. For instance: if \fIspec\fP is "SELECT %int4 + %int4", +the resulting \fIstmtBuf\fP would be "SELECT $1 + $2". +.SH RETURN VALUE +.LP +On success, a non-zero value is returned. On error, zero is +returned and \fIPQgeterror(3)\fP will contain an error message. + +If any put operation fails, the \fIparam\fP is reverted back to the number +of parameters it had prior to the function call; partial puts are not allowed. +.SH EXAMPLES +.LP +.SS Using PQputf +The example uses \fIPQputf\fP() to put a few parameters into a PGparam. Note +that the last parameter puts an SQL NULL as an int4 using the pass-by-pointer +type-specifier pointer flag '*', rather than pass-by-value. +.RS +.nf +.LP +\fBPGtext text = "foobar"; +PGint8 i8 = PQT_INT64CONST(1099511627776); +PGint4 *i4ptr = NULL; +PGparam *param = PQparamCreate(conn); + +if(!PQputf(param, "%text %int8 %int4*", text, i8, i4ptr)) + fprintf(stderr, "*ERROR: %s\\n", PQgeterror()); + +PQparamClear(param); +\fP +.fi +.RE +.SS Using PQputvf +The example creates an application function named execf. execf is a +wrapper to \fIPQputvf\fP(), as well as \fIPQparamExec(3)\fP. It is +similar to \fIPQexecf\fP(). The only difference is that the PQexecf +implementation uses a smaller stack buffer and allocates heap memory +when needed. +.RS +.nf +.LP +\fBPGresult * +execf(PGconn *conn, const char *format, ...) +{ + va_list ap; + char stmt[32768]; + PGparam *param; + PGresult *res = NULL; + + /* create the temporary PGparam */ + if(!(param = PQparamCreate(conn))) + return NULL; /* PQseterror already called */ + + /* put the params, create the stmt and exec it */ + va_start(ap, format); + if(PQputvf(param, stmt, sizeof(stmt), format, ap)) + res = PQparamExec(conn, param, stmt, 1); // resfmt is binary + va_end(ap); + + /* param must be cleared */ + PQparamClear(param); + return res; +} + +/* Example: execf will put 2 ints and execute "SELECT $1 + $2" */ +PGresult *res = execf(conn, "SELECT %int4 + %int4", 100, 67); +if(!res) + fprintf(stderr, "*ERROR: %s\\n", PQgeterror()); +\fP +.fi +.RE +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-specs(3)\fP, \fIPQparamCreate(3)\fP, \fIPQgeterror(3)\fP, \fIPQseterror(3)\fP diff --git a/source/docs/man3/PQputvf.3 b/source/docs/man3/PQputvf.3 new file mode 100644 index 0000000..f8762aa --- /dev/null +++ b/source/docs/man3/PQputvf.3 @@ -0,0 +1 @@ +.so man3/PQputf.3 diff --git a/source/docs/man3/PQregisterComposites.3 b/source/docs/man3/PQregisterComposites.3 new file mode 100644 index 0000000..3967201 --- /dev/null +++ b/source/docs/man3/PQregisterComposites.3 @@ -0,0 +1,80 @@ +.TH "PQregisterComposites" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQregisterComposites \- Registers a composites. +.SH SYNOPSIS +.LP +\fB#include +.br +int PQregisterComposites(PGconn *\fIconn\fP, PGregisterType *\fItypes\fP, +.br + int \fIcount\fP); +\fP +.SH DEPRECATED +.LP +THIS FUNCTION IS DEPRECATED. New applications should use PQregisterTypes. +This function is now a wrapper to PQregisterTypes. +.SH DESCRIPTION +.LP +The \fIPQregisterComposites\fP() function allows an application +to register one or more composites. This function can be +called as many times as an application needs on a PGconn. + +This function must execute a query against the backend to retrieve type +information for each composite, thus this should not be called from within +a transaction. It is recommended to register multiple composites at +the same time to avoid round trip overhead. + +The \fItypes\fP argument is an array containing \fIcount\fP composite types +to register. Composites do not use the typput or typget members of the +PGregisterType structure, thus these memebrs are ignored. If any composite +does not exist, the register is aborted. + +NOTE: The typname member of the PGregisterType structure can optionally +contain the type's schema: schema.typname. + +WARNING: \fIPQparamCreate\fP is only aware of types that have already been +registered. If you need to put a composite into a param, make sure it is first +registered. + +.SH EXAMPLES +.LP +.SS Using PQregisterComposites +The example registers two composite types. +.RS +.nf +.LP +\fBPGregisterType comp_types[] = { + {"myschema.simple", NULL, NULL}, + {"complex", NULL, NULL} +}; + +if (!PQregisterComposites(conn, comp_types, 2)) + fprintf(stderr, "PQregisterComposites: %s\\n", PQgeterror()); +\fP +.fi +.RE +.SH RETURN VALUE +.LP +On success, a non-zero value is returned. On error, zero is +returned and \fIPQgeterror(3)\fP will contain an error message. +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-handlers(3)\fP, \fIPQputf(3)\fP, \fIPQgetf(3)\fP + diff --git a/source/docs/man3/PQregisterResult.3 b/source/docs/man3/PQregisterResult.3 new file mode 100644 index 0000000..2987e11 --- /dev/null +++ b/source/docs/man3/PQregisterResult.3 @@ -0,0 +1,122 @@ +.TH "PQregisterResult" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQregisterResult \- Registers sub-classes, composites and user-defined types found within a PGresult. +.SH SYNOPSIS +.LP +\fB#include +.br +int PQregisterResult(PGconn *\fIconn\fP, int \fIwhich\fP, PGregisterType *\fItypes\fP, +.br + int \fIcount\fP, PGresult *\fIres\fP); +\fP +.SH DESCRIPTION +.LP +The \fIPQregisterResult\fP() function registers the types found within +a given PGresult, thus this function makes no calls to a PostgreSQL server +since the result data is already available. + +The \fIwhich\fP argument can be PQT_COMPOSITE or PQT_USERDEFINED, +but not PQT_SUBCLASS. The only reason being sub-classes don't talk to +the server so they have no result set. + +The \fItypes\fP argument is an array containing \fIcount\fP types +to register. This array must be identical to what was provided to +the originating PQregisterTypes call. + +The \fIres\fP argument is a PGresult normally created by calling +PQregisterTypes followed by PQgetResult. However, it is possible to +create your own result via PQmakeEmptyPGresult, PQsetResultAttrs, +PQsetvalue and call this function. This approach is a bit risky being +how the result set generated by type lookup queries are internal and +subject to change. + +.SH EXAMPLES +.LP +.SS Using PQregisterResult +The example registers two composite types asynchronously. It is worth +noting that the PGresult obtained via PQgetResult can be cached by an +application and used when creating new connections, as a way to avoid +repeatedly performing type lookups with the server. +.RS +.nf +.LP +\fBPGregisterType comp_types[] = { + {"myschema.simple", NULL, NULL}, + {"complex", NULL, NULL} +}; + +/* asynchronous registration */ +if (PQregisterTypes(conn, PQT_COMPOSITE, comp_types, 2, 1)) +{ + /* example of a typical event loop */ + for(;;) + { + int n; + fd_set set; + int fd = PQsocket(conn); + struct timeval tv = {0, 500000}; + + FD_ZERO(&set); + FD_SET(fd, &set); + n = select(fd + 1, &set, NULL, NULL, &tv); //or kqueue,epoll,poll,etc.. + + if (n == -1) + { + //error + } + else if (n == 0) + { + //timeout, do other work .... + } + else + { + PGresult *res; + + PQconsumeInput(conn); + if(!PQisBusy(conn)) + { + /* done */ + if(!(res = PQgetResult(conn))) + break; + + n = PQregisterResult(conn, PQT_COMPOSITE, comp_types, 2, res); + + /* This could also be cached and reused with PQregisterResult */ + PQclear(res); + + if (!n) + //error, consult PQgeterror() + } + } + } +} +\fP +.fi +.RE +.SH RETURN VALUE +.LP +On success, a non-zero value is returned. On error, zero is +returned and \fIPQgeterror(3)\fP will contain an error message. +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQregisterTypes(3)\fP, \fIpqt-handlers(3)\fP, \fIPQputf(3)\fP, \fIPQgetf(3)\fP + + + diff --git a/source/docs/man3/PQregisterSubClasses.3 b/source/docs/man3/PQregisterSubClasses.3 new file mode 100644 index 0000000..8570c47 --- /dev/null +++ b/source/docs/man3/PQregisterSubClasses.3 @@ -0,0 +1,62 @@ +.TH "PQregisterSubClasses" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQregisterSubClasses \- Registers a type aliases or sub-classes. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQregisterSubClasses(PGconn *\fIconn\fP, PGregisterType *\fItypes\fP, +.br + int \fIcount\fP); +\fP +.SH DEPRECATED +.LP +THIS FUNCTION IS DEPRECATED. New applications should use PQregisterTypes. +This function is now a wrapper to PQregisterTypes. +.SH DESCRIPTION +.LP +The \fIPQregisterSubClasses\fP() function allows an application +to register an alias or sub-class of another type. + +The \fItypes\fP argument is an array containing \fIcount\fP sub class types +to register. The typname member of the PGregisterType structure must +specify an inheritence relationship: ex. "myint=int4" where myint inherits +from int4. The \'=\' is called the inheritence operator. If both typput +and typget members of the PGregisterType structure are NULL, the type at +that element will behave identically to the type it is inheriting +from; an alias. Otherwise, the base type's put and/or get routines will +be overridden. + +NOTE: The typname member of the PGregisterType structure can optionally +contain the type's schema: schema.typname. + +WARNING: \fIPQparamCreate\fP is only aware of types that have already been +registered. If you need to put a type into a param, make sure it is first +registered. + +.SH RETURN VALUE +.LP +On success, a non-zero value is returned. On error, zero is +returned and \fIPQgeterror(3)\fP will contain an error message. +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-handlers(3)\fP, \fIPQputf(3)\fP, \fIPQgetf(3)\fP + diff --git a/source/docs/man3/PQregisterTypes.3 b/source/docs/man3/PQregisterTypes.3 new file mode 100644 index 0000000..0c09931 --- /dev/null +++ b/source/docs/man3/PQregisterTypes.3 @@ -0,0 +1,90 @@ +.TH "PQregisterTypes" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQregisterTypes \- Registers sub-classes, composites and user-defined types. +.SH SYNOPSIS +.LP +\fB#include +.br +int PQregisterTypes(PGconn *\fIconn\fP, int \fIwhich\fP, PGregisterType *\fItypes\fP, +.br + int \fIcount\fP, int \fIasync\fP); +\fP +.SH DESCRIPTION +.LP +The \fIPQregisterTypes\fP() function allows an application +to register one or more PQT_SUBCLASS, PQT_COMPOSITE or PQT_USERDEFINED +types which is defined by the \fIwhich\fP argument. + +When \fIwhich\fP is PQT_COMPOSITE or PQT_USERDEFINED, this function must +execute a query against the backend to retrieve type information, thus +this should not be called from within a transaction. It is recommended to +register multiple composites at the same time to avoid round trip overhead. + +The \fItypes\fP argument is an array containing \fIcount\fP types +to register. Composites do not use the typput or typget members of the +PGregisterType structure, thus these memebrs are ignored. If any composite +does not exist, the register is aborted. User-defined types must set either +typput and/or typget for each type. Sub-classes typname member of the +PGregisterType structure must specify an inheritence relationship: +ex. "myint=int4" where myint inherits from int4. The \'=\' is called the +inheritence operator. If both typput and typget members of the PGregisterType +structure are NULL, the type at that element will behave identically to the +type it is inheriting from; an alias. Otherwise, the base type's put and/or +get routines will be overridden. + +The \fIasync\fP argument indicates if the asynchronous type registration +should be used. When non-zero, the caller must proceed in the normal +async libpq fashion (PQconsumeInput, PQisBusy, PQgetResult) and provide a +PGresult to PQregisterResult when obtained to complete the registration. + +NOTE: The typname member of the PGregisterType structure can optionally +contain the type's schema: schema.typname. + +WARNING: \fIPQparamCreate\fP is only aware of types that have already been +registered. If you need to put a type into a param, make sure it is first +registered. + +.SH EXAMPLES +.LP +.SS Using PQregisterTypes +The example registers two composite types. +.RS +.nf +.LP +\fBPGregisterType comp_types[] = { + {"myschema.simple", NULL, NULL}, + {"complex", NULL, NULL} +}; + +if (!PQregisterTypes(conn, PQT_COMPOSITE, comp_types, 2, 0)) + fprintf(stderr, "PQregisterTypes: %s\\n", PQgeterror()); +\fP +.fi +.RE +.SH RETURN VALUE +.LP +On success, both PQregisterTypes returns a non-zero value. +On error, zero is returned and \fIPQgeterror(3)\fP will contain an +error message. +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQregisterResult(3)\fP, \fIpqt-handlers(3)\fP, \fIPQputf(3)\fP, \fIPQgetf(3)\fP + + diff --git a/source/docs/man3/PQregisterUserDefinedTypes.3 b/source/docs/man3/PQregisterUserDefinedTypes.3 new file mode 100644 index 0000000..f728c79 --- /dev/null +++ b/source/docs/man3/PQregisterUserDefinedTypes.3 @@ -0,0 +1,82 @@ +.TH "PQregisterUserDefinedTypes" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQregisterUserDefinedTypes \- Registers a user-defined types. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQregisterUserDefinedTypes(PGconn *\fIconn\fP, PGregisterType *\fItypes\fP, +.br + int \fIcount\fP); +\fP +.SH DEPRECATED +.LP +THIS FUNCTION IS DEPRECATED. New applications should use PQregisterTypes. +This function is now a wrapper to PQregisterTypes. +.SH DESCRIPTION +.LP +The \fIPQregisterUserDefinedTypes\fP() function allows an application +to register one or more user-defined types at runtime. User-defined types +are custom types in a backend that implement their own C procedures for +in/out/send/recv. + +This function must execute a query against the backend to retrieve type +information for each user-defined type, thus this should not be called +from within a transaction. It is recommended to register multiple types at +the same time to avoid round trip overhead. + +The \fItypes\fP argument is an array containing \fIcount\fP user-defined +types to register. If any type does not exist, the register +is aborted. Either typput and/or typget must be specified for each type +in the \fItypes\fP array. + +NOTE: The typname member of the PGregisterType structure can optionally +contain the type's schema: schema.typname. + +WARNING: \fIPQparamCreate\fP is only aware of types that have already been +registered. If you need to put a type into a param, make sure it is first +registered. + +\fBUser-defined Types Registration\fP +.br +This example registers two user-defined types. +.nf +.RS +.LP +\fBPGregisterType types[] = { + {"graphics.rgb", rgb_put, rgb_get}, + {"graphics.digon", digon_put, digon_get} +}; + +if (!PQregisterUserDefinedTypes(conn, types, 2)) + fprintf(stderr, "PQregisterUserDefinedTypes: %s\\n", PQgeterror()); +\fP +.RE +.fi + +.SH RETURN VALUE +.LP +On success, a non-zero value is returned. On error, zero is +returned and \fIPQgeterror(3)\fP will contain an error message. +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-handlers(3)\fP, \fIPQputf(3)\fP, \fIPQgetf(3)\fP + diff --git a/source/docs/man3/PQsendf.3 b/source/docs/man3/PQsendf.3 new file mode 100644 index 0000000..77c4e1e --- /dev/null +++ b/source/docs/man3/PQsendf.3 @@ -0,0 +1 @@ +.so man3/PQexecf.3 \ No newline at end of file diff --git a/source/docs/man3/PQsendvf.3 b/source/docs/man3/PQsendvf.3 new file mode 100644 index 0000000..77c4e1e --- /dev/null +++ b/source/docs/man3/PQsendvf.3 @@ -0,0 +1 @@ +.so man3/PQexecf.3 \ No newline at end of file diff --git a/source/docs/man3/PQseterror.3 b/source/docs/man3/PQseterror.3 new file mode 100644 index 0000000..e1ca3a1 --- /dev/null +++ b/source/docs/man3/PQseterror.3 @@ -0,0 +1 @@ +.so man3/PQgeterror.3 \ No newline at end of file diff --git a/source/docs/man3/PQspecPrepare.3 b/source/docs/man3/PQspecPrepare.3 new file mode 100644 index 0000000..1fb4ac0 --- /dev/null +++ b/source/docs/man3/PQspecPrepare.3 @@ -0,0 +1,123 @@ +.TH "PQspecPrepare" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQspecPrepare \- Prepares a libpqtypes specifier format string. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQspecPrepare(PGconn *\fIconn\fP, const char *\fIname\fP, +.br + const char *\fIformat\fP, int \fIis_stmt\fP); +.br +void PQclearSpecs(PGconn *\fIconn\fP); +\fP +.SH DESCRIPTION +.LP +PQspecPrepare allows an application to prepare specifier format strings +that will be used frequently. By preparing a specifier format string, +one avoids the parsing and type handler lookup costs. This becomes a +significant win when managing large result sets or arrays, where the +specifier format, like "%int4 %text %bytea", must be prepared for each +tuple/element. + +As with PQregisterXXX, only specifier format strings prepared prior +to the creation of a PGresult or PGparam, will be available for use. This is +because the prepared type spec is cached within a PGconn object and copied +to all subsequent PGparam and PGresult objects. + +Every prepared type spec is given a \fIname\fP, which is used as its unique identifier. +To use a prepared type spec, the \fIname\fP is provided where ever a regular +specifier format string is allowed, like PQputf or PQgetf. The \fIname\fP must +be proceeded by a \'@\' AT sign. For more information about the syntax, +see the \fIpqt-specs(3)\fP man page. + +The \fIformat\fP argument is the specifier format string being prepared. When +this is NULL, the \fIname\fP prepared type spec is removed from the PGconn\'s +internal array. + +The \fIis_stmt\fP argument indicates if a parementerized statement version of +\fIformat\fP should be cached along with the prepared type spec. This means +all type specifiers in \fIformat\fP, like "%int4", will be converted to "$1" +syntax. When is_stmt is non-zero, a statement will created and cached. +For more information on specifer format string to paremterized statements, see +the \fIPQputf(3)\fP man page. NOTE: to use a prepared type spec with +execution functions like PQexecf, \fIis_stmt\fP must be set to non-zero. + +PQclearSpecs removes all prepared specifiers from the given PGconn, as +opposed to removing them one by one by setting PQspecPrepare's format +argument to NULL. A good use for this is after a PQresetXXX call when it +might be desired to re-prepare all type specifiers. + +Functions that support the use of a prepared type spec are: \fIPQputf\fP, +\fIPQputvf\fP, \fIPQgetf\fP, \fIPQgetvf\fP, \fIPQexecf\fP, \fIPQexecvf\fP, +\fIPQsendf\fP, \fIPQsendvf\fP, \fIPQparamExec\fP, \fIPQparamSendQuery\fP. + +\fBHINT:\fP A good rule of thumb for using prepared type specs, is when there +are a large number of PQputf/PQgetf calls per statement execution. This +commonly occurs when dealing with large result sets and arrays. +.SH RETURN VALUE +.LP +PQspecPrepare and PQclearSpecs return a nonzero value on success and +zero if it fails. Use PQgeterror() to get an error message. +.SH EXAMPLES +.LP +This example prepares a type spec and issues some PQputf calls. +.LP +.RS +.nf +\fBint i; +PQparam *param; + +if(!PQspecPrepare(conn, "prepared_spec", "%int4 %text", 0)) +{ + fprintf(stderr, "PQspecPrepare: %s\n", PQgeterror()); + exit(1); +} + +/* create after preparing spec */ +param = PQparamCreate(conn); + +for(i=0; i < 100000; i++) +{ + /* NOTE: nothing else can be in format string */ + PQputf(param, "@prepared_spec", 4, "text"); +} + +/* This elects to prepare a statement as well. After this returns, + * "SELECT myfunc($1, $2)" will be cached along with the prepared spec. + */ +PQspecPrepare(conn, "myfunc", "SELECT myfunc(%int4, %text)", 1); + +/* "myfunc" tells execf to execute "SELECT myfunc($1, $2)". If is_stmt + * was set to zero during the PQspecPrepare, the below would be invalid + * because execf doesn't know what to execute. + */ +PQexecf(conn, "@myfunc", 123, "text"); + +/* clear'm all */ +PQclearSpecs(conn); +\fP +.fi +.RE +.SH RATIONALE +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIpqt-specs(3)\fP, \fIPQgetf(3)\fP, \fIPQputf(3)\fP. + diff --git a/source/docs/man3/PQtypesRegister.3 b/source/docs/man3/PQtypesRegister.3 new file mode 100644 index 0000000..aea1b48 --- /dev/null +++ b/source/docs/man3/PQtypesRegister.3 @@ -0,0 +1,53 @@ +.TH PQtypesRegister 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +PQtypesRegister \- Registers libpqtypes with the libpq event system. +.SH SYNOPSIS +.LP +\fB#include +.br +.sp +int PQtypesRegister(PGconn *conn); +\fP +.SH DEPRECATED +.LP +THIS FUNCTION IS DEPRECATED. New applications should use PQinitTypes. +This function is now a wrapper to PQinitTypes. +.SH DESCRIPTION +.LP +libpqtypes makes use of the libpq Event System. Before using +libpqtypes, you must register libpqtypes as a libpq EventProc. +The function takes a PGconn that libpqtypes will be registered +with; each PGconn requires its own registration. +.SH RETURN VALUE +.LP +The function returns zero if it fails and non-zero if it succeeds. +.SH EXAMPLES +.LP +.SS Registering libpqtypes +The examples shows how to register libpqtypes with the libpq event system. +.RS +.nf +.LP +\fB/* call prior to any other libpqtypes functions that operate on conn. */ +PQtypesRegister(conn); +\fP +.fi +.RE +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +None + diff --git a/source/docs/man3/pqt-composites.3 b/source/docs/man3/pqt-composites.3 new file mode 100644 index 0000000..3d055b5 --- /dev/null +++ b/source/docs/man3/pqt-composites.3 @@ -0,0 +1,263 @@ +.TH "pqt-composites" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +pqt-composites \- A manual for libpqtypes composite handling. +.SH NOTE TO READER +.LP +Please read the \fIpqt-specs(3)\fP manual page prior to this document. +This document does not explain how to put or get data types. It +only describes how to put or get composites and composite arrays. +.SH DESCRIPTION +.LP +A composite is put using the PGparam structure. Each attribute of a +composite is put into a PGparam. When all attributes have been put, +the PGparam is put into another PGparam. Composites must be registered +on a per connection basis, \`man \fIpqt-handlers(3)\fP\'. + +To get a composite, a PGresult structure is used. Each composite +attribute is a field of the result. For non-array composites, there +is always only one tuple. + +Composites are only handled using binary format. This means that any type used +as a composite attribute must be put and gotten in binary format. If a +user-defined type does not implement a send and recv function in the backend, +it can not be used as a composite attribute. +.SS Simple Composite Example +.LP +This example demostrates the basics of putting and getting a composite type. +.nf +.RS +\fB +CREATE TYPE simple AS (a int4, t text); + +PGregisterType type = {"simple", NULL, NULL}; + +/* need to register the simple composite */ +PQregisterTypes(conn, PQT_COMPOSITE, &type, 1, 0); + +/* Composite attributes are put into PGparam structures */ +PGparam *simple = PQparamCreate(conn); + +/* put the simple composite attributes */ +PQputf(simple, "%int4 %text*", 45, "foobar"); + +/* Put an int4 and a simple composite */ +PGparam *param = PQparamCreate(conn); +PQputf(param, "%int4 %simple", 10, simple); +PQparamClear(simple); + +/* exec an insert */ +res = PQparamExec(conn, param, "INSERT INTO t VALUES($1,$2)", resfmt); +PQparamClear(param); + +/* ------------------------- + * Getting a composite + */ + +PGint4 i4; +PGtext textp; +char text[80]; +PGresult *simple; + +/* Get a simple composite, provide a ptr to a PGresult ptr. */ +PQgetf(result, 0, "%simple", 0, &simple); + +/* no longer needed */ +PQclear(result); + +/* Get the simple composite attributes from the simple result. + * Reference fields by name by using a '#' rather than a '%'. + * The field names are the composite attributes. + */ +PQgetf(simple, 0, "#int4 #text", "a", &i4, "t", &textp); +strcpy(text, textp); +PQclear(simple); +\fP +.RE +.nf + +In the above example, we used the \'#\' specifier mark to reference +fields by their name. The field names for a composite result object +are the composite attribute names. +.SS Nested Composite example: +.LP +The below example puts and gets a nested composite. The simple composite +is used as an attribute within the complex composite. +.nf +.RS +\fB +CREATE TYPE simple AS (a int4, t text) +CREATE TYPE complex AS (f8 float8, s simple); + +/* need to register simple and complex */ +PGregisterType types[] = { + {"simple", NULL, NULL}, + {"complex", NULL, NULL} +}; + +PQregisterTypes(conn, PQT_COMPOSITE, types, 2, 0); + +/* Composite attributes are put into PGparam structures */ +PGparam *simple = PQparamCreate(conn); +PGparam *complex = PQparamCreate(conn); + +/* put the simple composite attributes */ +PQputf(simple, "%int4 %text*", 45, "foobar"); + +/* put the complex composite attributes, which includes + * a nested composite. + */ +PQputf(complex, "%float8 %simple", 111.2223334, simple); + +/* no longer needed */ +PQparamClear(simple); + +/* Put an int4 and a complex composite */ +PGparam *param = PQparamCreate(conn); +PQputf(param, "%int4 %complex", 10, complex); +PQparamClear(complex); + +/* exec an insert */ +res = PQparamExec(conn, param, "INSERT INTO t VALUES($1,$2)", resfmt); +PQparamClear(param); + +/* ------------------------- + * Getting a nested composite + */ + +PGfloat8 f8; +PGint4 i4; +PGtext textp; +char text[80]; +PGresult *complex; +PGresult *simple; + +/* Get the complex composite, provide a ptr to a PGresult ptr. */ +PQgetf(result, 0, "%complex", 0, &complex); + +/* no longer needed */ +PQclear(result); + +/* Get the complex composite attributes from the complex result. + * Composite attributes are the result fields. When getting + * a single composite, non-array, only tuple 0 will exist. + * For the nested simple composite, we again provide a ptr to + * a PGresult ptr. + */ +PQgetf(complex, 0, "%float8 %simple", 0, &f8, 1, &simple); + +/* no longer needed */ +PQclear(complex); + +/* Get the simple composite attributes from the simple result. + * Reference fields by name by using a '#' rather than a '%'. + */ +PQgetf(simple, 0, "#int4 #text", "a", &i4, "t", &textp); +strcpy(text, textp); +PQclear(simple); +\fP +.RE +.nf +.SS An array of composites: +.LP +This example makes an array of complex composites. It builds +off the previous example. +.nf +.RS +\fB +int i; +PGarray complex_arr; +PGparam *simple = PQparamCreate(conn); +PGparam *complex = PQparamCreate(conn); + +complex_arr.ndims = 0; +complex_arr.param = PQparamCreate(conn); + +for(i=0; i < 100; i++) +{ + /* put the simple composite attributes */ + PQputf(simple, "%int4 %text*", 45, "foobar"); + + /* put the complex composite attributes, which includes + * a nested composite. + */ + PQputf(complex, "%float8 %simple", 111.2223334, simple); + + /* put the complex composite */ + PQputf(complex_arr.param, "%complex", complex); + + /* You must reset the simple and complex composites for + * the next loop iteration. + */ + PQparamReset(simple); + PQparamReset(complex); +} + +/* not needed anymore */ +PQparamClear(simple); +PQparamClear(complex); + +/* Put a complex composite array */ +PGparam *param = PQparamCreate(conn); +PQputf(param, "%complex[]", &complex_arr); +PQparamClear(complex_arr.param); + +/* exec an insert */ +res = PQparamExec(conn, param, "INSERT INTO t VALUES($1)", resfmt); +PQparamClear(param); + +/* ------------------------- + * Getting an array of composites + */ + +int i; +int ntups; +PGfloat8 f8; +PGint4 i4; +PGtext textp; +PGresult *simple; +PGarray complex_arr; + +/* Get the complex[], provide a ptr to a PGarray. */ +PQgetf(exec_result, 0, "%complex[]", 0, &complex_arr); + +/* no longer needed */ +PQclear(exec_result); + +ntups = PQntuples(complex_arr.res); +for(i=0; i < ntups; i++) +{ + PQgetf(complex_arr.res, i, "%float8 %simple", 0, &f8, 1, &simple); + + /* Nested composites are like any other composite, tuple 0! Unless, + * its a nested composite array. + */ + PQgetf(simple, 0, "#int4 #text", "a", &i4, "t", &textp); + + printf("(%f, (%d, %s))\\n", f8, i4, textp); + PQclear(simple); +} + +PQclear(complex_arr.res); +\fP +.RE +.nf +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQgetf(3)\fP, \fIPQputf(3)\fP, \fIPQputvf(3)\fP diff --git a/source/docs/man3/pqt-handlers.3 b/source/docs/man3/pqt-handlers.3 new file mode 100644 index 0000000..ba2d275 --- /dev/null +++ b/source/docs/man3/pqt-handlers.3 @@ -0,0 +1,598 @@ +.TH "pqt-handlers" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +pqt-handlers \- A manual for implementing libpqtypes type handlers. +.SH DESCRIPTION +.LP +Type handlers are I/O routines used by libpqtypes for sending and receiving +data for specific types. Internally, libpqtypes uses type handlers to support +PostgreSQL's builtin base types: such as point, int4, timestamp, etc... + +NOTE: Builtin types always serialize parameters being sent "put" to the backend +in binary format; user-defined types may choose to use text format. C data +types are translated into the backend's external binary format. Even if text +results are used, C data types are still exposed when getting result data. + +\fBType handlers have the below three properties:\fP +.LP +.RS +\fBType Specifier Name\fP +.br +A [schema].type name that will be used to reference your handler. +\`man \fIpqt-specs\fP\' for complete documentation on syntax. + +\fBPut Routine\fP +.br +A PGtypeProc put routine takes a C data type and converts it into a valid backend +external format. The converted format is used with libpq's parameterized +API. For instance: a C int data type is used to put a postgresql int4. +To convert this to a valid external format, libpqtypes swaps the bytes +(when needed) so they are in network order. A put routine returns the number +of bytes being put. On error, a put routine must return -1. + +\fBGet Routine\fP +.br +A PGtypeProc get routine does the opposite of a put routine. It converts a +type's text or binary external format to its native C type. For instance: +a postgresql int4 is converted to a C int. For binary results, the 4 bytes +are converted to host order and stored as a C int. A get routine returns zero +to indicate success. On error, a get routine must return -1. +.RE + +\fBPGregisterType\fP +.br +The \fIPGregisterType\fP structure is used by all PQregisterXXX functions. +It contains a typname, put and get routine. The typname can optionally +contain the type's schema, like pg_catalog.int4. When registering a +sub class via PQregisterTypes, an inheritence operator must be used +within typname to indicate what type is being extended: myint4=int4. If the +typput and typget routines are NULL during a sub class registration, the +result is a direct sub class or alias of the base type: like "s=text" +allowing one to use "%s" instead of "%text". When registering a composite, +typput and typget are ignored. +.nf +.RS +\fB +typedef struct +{ + const char *typname; + PGtypeProc typput; + PGtypeProc typget; +} PGregisterType;\fP +.RE +.fi + +To implement a type handler, you need to be aware of 4 structures: +PGtypeFormatInfo, PGrecordAttDesc, PGtypeHandler and PGtypeArgs. All exist +for use with type handlers. + +\fBPGtypeFormatInfo\fP +.br +The \fIPGtypeFormatInfo\fP structure provides useful connection-based information for +type handlers. For instance, your handler may have different implementations +depending on the server version .. \fIsversion\fP. +.nf +.RS +\fB +typedef struct +{ + int sversion; /* server version, e.g. 70401 for 7.4.1 */ + int pversion; /* FE/BE protocol version in use */ + char datestyle[32]; /* server\'s datestyle: like "SQL, MDY" */ + + /* When non-zero, server uses int64 timestamps */ + int integer_datetimes; +} PGtypeFormatInfo;\fP +.RE +.fi + +\fBPGrecordAttDesc\fP +.br +The \fIPGrecordAttDesc\fP structure defines the attributes of a composite. +Internally, libpqtypes keeps track of composite attributes using this structure. +.nf +.RS +\fB +typedef struct +{ + Oid attoid; /* Oid of the attribute */ + int attlen; /* storage size of attribute. -1 if not known */ + int atttypmod; /* The typmod of attribute. */ + char *attname; /* The name of the attribute. */ +} PGrecordAttDesc;\fP +.RE +.fi + +\fBPGtypeHandler\fP +.br +The \fIPGtypeHandler\fP structure represents all the properties of a +type handler. When a type is registered, this structure is used to catalog +the type\'s information. +.nf +.RS +\fB +typedef struct pg_typhandler +{ + /* An internal libpqtypes assigned id for this type handler. */ + int id; + + /* The schema name of this type, which may be empty if not + * provided during registration. + */ + char typschema[65]; + + /* The name of this type: like int2 or bytea, cannot be empty */ + char typname[65]; + + /* The storage size of this type. -1 if not known. */ + int typlen; + + /* The backend OID of the type. */ + Oid typoid; + + /* The backend array OID of the type. */ + Oid typoid_array; + + /* The put handler for this type. */ + PGtypeProc typput; + + /* The get handler for this type. */ + PGtypeProc typget; + + /* If this handler is a sub-class, this will be the \'id\' of + * the super class type handler. It is set to -1 if not + * a sub-class. + */ + int base_id; + + /* Indicates the number of composite attributes within the + * \'attDescs\' array. This is set to 0 for non-composites. + */ + int nattrs; + + /* If non-zero, the 'attDescs' pointer must be freed. */ + int freeAttDescs; + + /* The memory behind the 'attDescs' pointer when the number of + * attrs is less than 16. When greater than 16, heap memory + * is used and 'freeAttDescs' is set to a non-zero value. + */ + PGrecordAttDesc attDescsBuf[16]; + + /* An array of PGrecordAttDesc, one element per record + * attribute. Must be freed if 'freeAttDescs' is non-zero. + */ + PGrecordAttDesc *attDescs; +} PGtypeHandler; +\fP +.RE +.fi + +\fBPGtypeArgs\fP +.br +The \fIPGtypeArgs\fP structure is passed to all put and get handlers. It +contains all values needed by type handlers. +.nf +.RS +\fB +struct pg_typeargs +{ + /* Indicates if this is a put or get operation. */ + int is_put; + + /* Formatting information. */ + const PGtypeFormatInfo *fmtinfo; + + /* Indicates if a request for a direct pointer was + * made, %text*. + */ + int is_ptr; + + /* + * When \fIis_put\fP is non-zero, set this to 1 for binary and 0 for + * text format. It defaults to binary. When \fIis_put\fP is 0, this + * indicates the field type PQftype of \fIget.field_num\fP. + */ + int format; + + /* An argument list. Arguments should be retrieved with va_arg. */ + va_list ap; + + /* The position of this typname within a specifier + * string, 1-based. + */ + int typpos; + + /* Type handler for the specifier at typpos. */ + PGtypeHandler *typhandler; + + /* + * Report an error from within a handler. This error message + * will show up in PQgeterror. + * + * This always returns -1 so one can report an error and return + * -1 from a handler in a single statement: + * + * return args->errorf(args, "ERROR: %s", strerror(errno)); + * + * errorf always prepends a small header + * "schema.typname[pos:num] - msg". For example, if the above + * failed within the int4 handler and typpos was 5, the + * resulting error message would be: + * + * pg_catalog.int4[pos:5] - ERROR: Invalid argument + * + * errorf does not put any newlines in error message. + */ + int (*errorf)(PGtypeArgs *args, const char *format, ...); + + /* Used by type sub-class handlers. When \fIis_put\fP is + * non-zero, a sub-class prepares type data and then calls + * super. When \fIis_put\fP is zero, a sub-class first + * calls super to get the base class's deserialized value + * and can then convert it. + */ + int (*super)(PGtypeArgs *args, ...); + + /* This structure is used when \fIis_put\fP is non-zero. */ + struct + { + /* The PGparam structure passed to \fIPQputf\fP(). */ + PGparam *param; + + /* A buffer used to store the type's output format. If + * more than 'outl' bytes are needed, see 'expandBuffer'. + * Normally data is copied to the out buffer, but it can + * also be pointed elsewhere: like a const string or static + * memory. When repointing the out buffer, DO NOT use + * 'expandBuffer'. Never use realloc on this buffer. + */ + char *out; + + /* The size in bytes of the 'out' buffer. If expandBuffer + * is used, this will reflect the new buffer length. + */ + int outl; + + /* Expands the 'out' buffer to 'new_len'. If new_len is + * less than or equal to the current length 'outl', the + * expand request is ignored. This behaves just like a + * realloc, existing data is copied to the new memory. + * You should never use realloc on the out buffer. + * Returns -1 on error and 0 for success. + */ + int (*expandBuffer)(PGtypeArgs *args, int new_len); + + /* internal use only. */ + char *__allocated_out; + } put; + + /* This structure is used when \fIis_put\fP is zero. */ + struct + { + /* The PGresult passed to \fIPQgetf\fP(). + PGresult *result; + + /* The tuple number */ + int tup_num; + + /* the tuple field number. */ + int field_num; + } get; +};\fP +.RE +.fi + +.SH USER-DEFINED TYPES +.LP +User-defined types are extended base types in the backend. They are not domains +or composites. These types have their own input/output and send/recv functions +(normally written in C). They normally include their own operator functions and +have an array oid. For libpqtypes to make use of these types, especially for binary +puts and gets, a type handler must be registered. This provides libpqtypes with a type +specifer, put and get routines for handling this type. + +User-defined types are registered on a per connection basis and must exist on the +server. If the type does not exist, the registration fails. If no schema name is +provided during registration, the server's search path is used to resolve the +type's existence and fetch its oid. If a schema name is provided during +registration, the search path is not used. + +.SS User-defined type example +.LP +Assume there is a user-defined type named \'rgb\' in the \'graphics\' schema. The +text output format is always in hex: \'#ff0000\' with a leading pound sign and +lowercase hex digits. The external binary format is a sequence of three unsigned +bytes: r, g and b. To use this type with libpqtypes, it must be registered. +.nf +.RS +\fB +/* register the rgb type */ +PGregisterType type = {"graphics.rgb", rgb_put, rgb_get}; +PQregisterTypes(conn, PQT_USERDEFINED, &type, 1, 0); + +/* put an rgb */ +rgb_t rgb = {218, 218, 218}; +PGparam *param = PQparamCreate(conn); +PQputf(param, "%rgb", &rgb); + +/* get an rgb from tuple 0 field 4 */ +rgb_t rgb; +PQgetf(result, 0, "%graphics.rgb", 4, &rgb); + +/* ------------------------------- + * EXAMPLE RGB IMPLEMENTATION + */ + +#define hex2dec(v) (unsigned char)(((v) > '9') ? \ + ((v) - 'a') + 10 : (v) - '0') + +/* example rgb struct */ +typedef struct +{ + unsigned char r; + unsigned char b; + unsigned char g; +} rgb_t; + +/* RGB PGtypeProc handler - always puts in binary format */ +int rgb_put(PGtypeArgs *args) +{ + unsigned char *out; + rgb_t *rgb = va_arg(args->ap, rgb_t *); + + /* If rgb is NULL, put an SQL NULL value */ + if(!rgb) + { + args->put.out = NULL; + return 0; + } + + /* write the 3 bytes to the args out buffer */ + out = (unsigned char *)args->put.out; + *out++ = rgb->r; + *out++ = rgb->g; + *out = rgb->b; + return 3; /* number of bytes the server should expect */ +} + +/* RGB PGtypeProc handler */ +int rgb_get(PGtypeArgs *args) +{ + rgb_t *rgb = va_arg(args->ap, rgb_t *); + char *value = PQgetvalue(args->get.result, + args->get.tup_num, args->get.field_num); + + if(!rgb) + return args->errorf(args, "rgb* cannot be NULL"); + + /* text format: ex. \'#ff9966\' */ + if(PQfformat(args->format) == 0) + { + value++; /* skip the \'#\' sign */ + rgb->r = (hex2dec(value[0]) << 4) | hex2dec(value[1]); + rgb->g = (hex2dec(value[2]) << 4) | hex2dec(value[3]); + rgb->b = (hex2dec(value[4]) << 4) | hex2dec(value[5]); + return 0; + } + + /* binary format */ + rgb->r = (unsigned char)value[0]; + rgb->g = (unsigned char)value[1]; + rgb->b = (unsigned char)value[2]; + return 0; +}\fP +.RE +.fi + +.SH TYPE SUB-CLASSING +.LP +Sub-classing a type means extending the put or get routines of a registered +type handler. The idea came about from trying to provide a convention for +registering domains; which amounts to simple aliases to libpqtypes. +Domain/alias registration would look like this: +.nf +.RS +\fBPGregisterType type = {"myint4=pg_catalog.int4", NULL, NULL}; +PQregisterTypes(conn, PQT_SUBCLASS, &type, 1, 0);\fP +.RE +.fi + +The 'typname' member syntax is: [schema].type=[base_schema].base_type +(schema is optional). No spaces are allowed unless contained within the schema +or type name, which would require double quoting the identifer. By passing NULL +for both the put and get handlers, the base type's handlers are used. Thus, +the result of the above is that "%myint4" and "%int4" behave identically. But +what happens if a put or get handler is provided during an alias registration? +Is this useful functionality to applications? The answer is sub-classing and +yes its useful. + +By providing a put and get handler during alias registration, one has +effectively sub-classed the base type. This is called sub-class registration. + +By sub-classing a registered type, applications can now put and get data +using their own data structures. The sub-class put and get routines handle +the dirty work of converting application structures to the base type's +structure. When sub-classing, no oid lookup occurs with the server. The +sub-class type is assumed to be application specific. Sub-classes are +registered on a per connection basis, just like user-defined types. The +reason for this is because the base type can be server-specific. + +\fBBENEFITS\fP + +1. Centralizes conversions from application data types to libpq data types +.br +2. Provides an easy all-inclusive interface for putting and getting values +.br +3. Allows applications to piggy-back off libpqtypes internal binary and text convertors +.br +4. Adds enormous flexiblity: (a few interesting ideas) +.br + -- %socket: sub-class the inet get routine and return a connected sockfd. +.br + -- %file: sub-class the text get routine and return a FILE* (text being a pathname) +.br + -- %filemd5: sub-class the bytea put routine and supply a pathname that is used to + md5 a file's contents, utlimately putting a 16 byte bytea. + +It is impossible to consider all of the uses for type sub-classing. The above +ideas are probably more extreme than common cases, such as taking an application +struct and converting it to what the base type expects. But, the extreme cases +are possible when desired. + +.SS Sub-class example +.LP +Assume you have an application that works with time_t epoch values a lot. It +would be useful if you could define a %epoch type handler. This avoids having +to convert a time_t to either a string or to a PGtimestamp (used by the timestamp & +timestamptz type handlers). The problem is, to use the binary interface you would +have to know how to serialize a timestamp to send/recv it from the server. If you +sub-class timestamptz, you can use PGtypeArgs.super to handle the dirty work. + +\fB**NOTE:\fP %epoch is only an example, it is not part of libpqtypes nor being proposed. +The goal here is to demonstrate how to implement a type sub-class handler. It is important +to note that %epoch will announce itself as a timestamptz to the backend. So when using +%epoch, make sure the context allows a timestamptz. +.nf +.RS +\fB +/* we are going to register this under the \'pqt\' schema */ +PGregisterType type = {"pqt.epoch=pg_catalog.timestamptz", epoch_put, epoch_get}; +PQregisterTypes(conn, PQT_SUBCLASS, &type, 1, 0)) + +/* putting an epoch */ +struct stat st; +if(stat("/home/foobar/archive.tgz", &st) == 0) +{ + PGparam *param = PQparamCreate(conn); + PQputf(param, "%epoch", st.st_mtime); + //.... +} + +/* getting an epoch value, using fully qualified type name */ +struct utimbuf ut = {0, 0}; +PQgetf(result, tup_num, "%pqt.epoch", field_num, &ut.modtime); + +/* ------------------------------- + * EXAMPLE EPOCH SUB-CLASS IMPLEMENTATION + */ + +/* convert a time_t to a PGtimestamp and call args->super() */ +int epoch_put(PGtypeArgs *args) +{ + struct tm *tm; + PGtimestamp ts; + time_t t = va_arg(args->ap, time_t); + + tm = localtime(&t); + ts.date.isbc = 0; + ts.date.year = tm->tm_year + 1900; /* always 4-digit year */ + ts.date.mon = tm->tm_mon; + ts.date.mday = tm->tm_mday; + ts.time.hour = tm->tm_hour; + ts.time.min = tm->tm_min; + ts.time.sec = tm->tm_sec; + ts.time.usec = 0; + ts.time.gmtoff = tm->tm_gmtoff; + + /* Internally, this calls the base type\'s put routine + * (the super class). In this case, the super class + * expects a PGtimestamp as input. The super function + * returns whatever the base type\'s put routine returns + * (which for all puts is the byte count or -1 on error). + */ + return args->super(args, &ts); +} + +/* Calls args->super() to get a PGtimestamp and then converts + * it to a time_t value. + */ +int epoch_get(PGtypeArgs *args) +{ + PGtimestamp ts; + time_t *t = va_arg(args->ap, time_t *); + + if(!t) + return args->errorf(args, "time_t* cannot be NULL"); + + /* zero user bits */ + *t = 0; + + /* Internally, this calls the base type\'s get routine, + * which returns 0 or -1 on error. + */ + if(args->super(args, &ts) == -1) + return -1; /* args->errorf called by super already */ + + /* Since PGtimestamp contains an epoch member, we can + * just copy that value rather than calling mktime(). + */ + *t = (time_t)ts.epoch; + return 0; +} +\fP +.RE +.fi + +.SH COMPOSITES +.LP +To get and put composites, they must be registered. During registration, +information about the composite type, likes its OID and attributes, are looked +up in the backend. The composite must exist or the registration fails. +Do a \`man \fIpqt-composites(3)\fP\' for a more information about composites. + +Registering a composite type: +.nf +.RS +\fB +CREATE TYPE simple AS (a int4, t text); +PGregisterType type = {"simple", NULL, NULL}; +PQregisterTypes(conn, PQT_COMPOSITE, &type, 1, 0);\fP +.RE +.fi + +*) The put and get routines must be NULL, composites cannot be sub-classed +.br +*) The provided name cannot resolve to the backend\'s RECORDOID +.br +*) The composite must exist at "conn" +.br +*) If no schema name is provided, the composite must be within the backend\'s search path. + +During registration of a composite, the below information is retreived from the backend: + +*) Oid of the composite type +.br +*) Array Oid of the composite type +.br +*) Type len of the compsoite type, PQfsize + +For each composite attribute: + +*) Oid of the attribute +.br +*) Name of the attribute +.br +*) Type len of the attribute, PQfsize +.br +*) The typmod of the attribute, PQfmod + +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQregisterTypes\fP(), \fIPQregisterResult\fP() diff --git a/source/docs/man3/pqt-specs.3 b/source/docs/man3/pqt-specs.3 new file mode 100644 index 0000000..5303d40 --- /dev/null +++ b/source/docs/man3/pqt-specs.3 @@ -0,0 +1,1221 @@ +.TH "pqt-specs" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +.SH NAME +pqt-specs \- A manual for libpqtypes data type specifier strings. +.SH DESCRIPTION +.LP +The type system allows addressing backend data types by their fully +qualified schema name. Similar to the backend type system, libpqtypes has +an input and output function for each type: put and get respectively. +All builtin types are supported by libpqtypes. Additional types, such as +composites and user-defined types, can be registered by an API-user +on a per connection basis. + +Putting and getting types are addressed by their backend names as +printf-style format specifiers. For instance: %int4, %timestamptz or %text. +They can also be addressed using their fully qualified schema names: +%pg_catalog.int4, %pg_catalog.timestamptz, %pg_catalog.text or +%myschema.mytype to avoid ambiguity. + +.SS Specifier Strings +\fISpecifier Mark\fP +.br +A specifier mark indicates where a specifier begins. A mark is not part +of the type name. + + % Marks the beginning of a type name. When getting results, this + also indicates that a field will be referenced by number. + + # Marks the beginning of a type name. When getting results, this + also indicates that a field will be referenced by name. + + @ Marks the beginning of a prepared specifier name, see + PQspecPrepare(). When used, it must be the first and only + specifier in the format string: "@prepared_spec", "@myfunc", + etc... NOTE: the \'@\' must be the first character, no spaces. + +\fIType Specifier\fP +.br +Type specifiers are comprised of an optional schema name and type name. +Type specifiers have a set of rules: + + -) Format: [schema].type - optional schema name, a "." separator + between schema and type and the type name. + + -) First character must be a-z or an underscore + + -) Double quotes are required for characters not in [a-zA-Z0-9_] + NOTE: In libpqtypes, this includes "double precision" + + -) Schema "." separator, specifier marks or flags are not included + in double quotes + + -) Non-quoted type names are casefolded, quoted names are not. + + -) Examples: + "%int4" + "%pg_catalog.int4" + "%\\"my oDd~ !tYpe naMe#\\"" + "%myschema.\\"my oDd~ !tYpe naMe#\\"" + "%abc.int4 %pg_catalog.int4" <= fully qualified type names + + -) Last in First out: To find a type referenced in a specifier + string, the search begins with the last type registered. + User registered type handlers are searched first, followed + by builtin types. + + -) pqt schema: There is a builtin schema named pqt. By default, + it contains two types: \'str\' and \'null\'. Anything can be + put into this schema, which has nothing to do with the server. + This is good for aliases or type sub-classes that are + client-specific. + +\fISpecifier Flag\fP +.br +Flags are used to alter the behavior of a type specifier. They are always placed +at the end of the specifier name. If the name is double quoted, the flag is just +after the closing quote. + + * This is called the pass-by-pointer flag. It is supported by all + builtin types during a \fIPQputf(3)\fP. For integer, bool, money and + "char" types (scalars), one can omit this flag to pass-by-value. For + all other types, omitting this flag has no effect; they are always + passed by pointer and thus this flag is not needed for things like + text, timestamp, uuid, etc.. + + Putting data: this flag tells libpqtypes to store a direct + pointer to the data being put, rather than making a copy of + it. For scalars (ints, bool, etc..), this tell libpqtypes + to dereference the pointer to get the value. However, an upside + is that you can pass in a C NULL for the scalar pointer and it + will produce an SQL NULL when put. + + Getting data: no built-in types make use of the pointer flag. + User-defined type handlers can make the pointer flag behave + anyway they see fit. The \'get\' type handler is supplied a + PGtypeArgs which contains an \'is_ptr\' member. + + [] This is called the array flag. It indicates that an array is + being referenced rather than a simple type. This flag is always + used with a PGarray. +.SH NUMERICS +.LP +With the exception of the "numeric" type, all numeric types behave +identically: int2, int4, int8, float4 and float8. +.RS +.nf +.LP +PG type C type +PGint2 short +PGint4 int +PGint8 long long (platform dependent) +PGfloat4 float +PGfloat8 double +.fi +.RE + +Putting numeric values: If the value supplied is too large for the PG +type, it will be silently truncated. Note the use of the pass-by-pointer +flag being used for the last two arguments, allowing you to easily put +an SQL NULL for any numeric type. +.RS +.nf +\fB +PGint2 i2 = 10; +PQputf(param, "%int2 %int4 %int8 %float4 %float8 %int2* %int8*", + SHRT_MAX, INT_MAX, LLONG_MAX, 1234.56, 123456.789, &i2, NULL);\fP +.fi +.RE + +Getting numeric values: Like scanf, the correctly sized data type must be +used. For instance: you cannot use a 4-byte int for %int2 - you must use a short. +.RS +.nf +\fB +// Read an int2 from field 0, int4 from field 1, int8 from +// field 2, float4 from field 3 and a float8 from field 4 +PGint2 i2; +PGint4 i4; +PGint8 i8; +PGfloat4 f4; +PGfloat8 f8; +PQgetf(result, tup_num, "%int2 %int4 %int8 %float4 %float8", + 0, &i2, 1, &i4, 2, &i8, 3, &f4, 4, &f8);\fP +.fi +.RE + +The numeric data type is always exposed in text format. +There is no C data structure. It is always sent in binary format. +.RS +.nf +\fB +PQputf(param, "%numeric", "1728718718271827121233.121212121212");\fP +.fi +.RE + +Even if binary results are used when getting a numeric value, libpqtypes will +internally convert the numeric to text. This has the advantage of allowing +you to use binary results and still have access to numeric fields. If you +want to work with a numeric in binary form, use PQgetvalue() on a binary result set. +.RS +.nf +\fB +PGnumeric numstr; +PQgetf(result, tup_num, "%numeric", field_num, &numstr);\fP +.fi +.RE + +The first argument is the field number of the numeric. The second argument is a +pointer to a PGnumeric to receive the numeric string value (which will +always be NUL terminated). +.SH ARRAY +.LP +Arrays are put using the PGarray structure. Elements are put using \fIPQputf(3)\fP +into a PGparam structure contained withn a PGarray. The PGarray contains +array dimension members for specifing the number of dimension, the +dimensions of each dimension and the lower bounds of each dimension. + +Arrays are only handled using binary format. This means that any type used +as an array element must be put and gotten in binary format. If a +user-defined type does not implement a send and recv function in the backend, +it can not be used as an array element. + +For a discussion of composite arrays, \`man pqt-composites(3)\'. +.RS +.nf +\fB +typedef struct +{ + /* The number of array dimensions. Specifing zero for this + * value on puts has special meaning. When zero, this value + * is set to one, dims[0] is set to the number of items in + * the \'param\' member and lbound[0] is set to one. + */ + int ndims; + + /* An array of lower bounds for each dimension. */ + int lbound[MAXDIM]; + + /* An array of dimensions for each dimension. */ + int dims[MAXDIM]; + + /* When putting array elements, this PGparam is used. Each + * item put is one array element. Because the \fIPQputf(3)\fP + * interface allows putting more than one item at a time, you + * can put multiple array elements. + */ + PGparam *param; + + /* When getting an array, this is the PGresult object that + * contains the array elements. Each element is one tuple, + * regardless of the array dimensions. If the array has 100 + * elements across 3 dimensions, PQntuples(arr.res) will return + * 100. The only valid field, for non-composite arrays, is + * field zero. + */ + PGresult *res; +} PGarray; +\fP +.fi +.RE + +When all elements have been put, the PGarray structure must be put using the +"[]" array specifer flag into a PGparam structure. \fIPQputf(3)\fP is used to build the +array elements and to put the resulting PGarray. + +Putting an array value: +.RS +.nf +\fB +PGint4 i; +PGarray arr; +PGparam *param; + +/* One dimensional arrays do not require setting dimension info. For + * convience, you can zero the structure or set ndims to zero. + */ +arr.ndims = 0; + +/* create the param object that will contain the elements */ +arr.param = PQparamCreate(conn); + +/* Use \fIPQputf(3)\fP to put the array elements */ +for(i=0; i < 1000; i++) + PQputf(arr.param, "%int4", i); + +/* The PGarray must be put into a PGparam struture. So far, only + * the array elements have been put. \'param\' can continue to be + * used to pack more parameters. The array is now a single parameter + * within \'param\'. + */ +param = PQparamCreate(conn); +PQputf(param, "%int[]", &arr); + +/* no longer needed */ +PQparamClear(arr.param); +\fP +.fi +.RE + +To get an array, \fIPQgetf(3)\fP is used in conjunction with the PGarray +structure. The result object contained with the PGarray is populated +with the array elements. The dimension info is assigned as well. Each +array element is its own tuple that only contains a single field for non +composite arrays. + +Getting an array value: +.RS +.nf +\fB +int i; +PGint4 val; +int ntups; +PGarray arr; +PGresult *result = ...; + +PQgetf(result, 0, "%int[]", 0, &arr); + +/* not needed anymore*/ +PQclear(result); + +/* each tuple is an array element */ +ntups = PQntuples(arr.res); +for(i=0; i < ntups; i++) +{ + /* Always field 0 */ + PQgetf(arr.res, i, "%int4", 0, &val); + printf("[%03d] %d\\n", i, val); +} + +PQclear(arr.res); +\fP +.fi +.RE + +The result object is not organized based on the dimension info. Indexes are always +zero-based. If the dimension info is meaningful to your application, index +translation must be done using the ndims, dims and lbound members of the PGarray +structure. + +You cannot reference an array element by field name. The only logical name for an +array element would be the string version of its index ... "0", "1", etc.. The +index value of a non-composite array is its tuple number, the field number is always +zero. This means "#int" is not legal for non-composite arrays. You must use +"%int" and reference field 0. +.SH CHAR +.LP +The "char" data type uses the PGchar. The value is limited to 8-bits. + +Putting a "char" value: +.RS +.nf +\fB +PGchar c = \'a\'; +PQputf(param, "%char %char %char*", 213, c, NULL);\fP +.fi +.RE + +Getting a "char" value: +.RS +.nf +\fB +PGchar c; +PQgetf(result, tup_num, "%char", field_num, &c);\fP +.fi +.RE +.SH VARIABLE-LENGTH CHARACTER TYPES +.LP +BPCHAR, VARCHAR, NAME and TEXT are handled identically. libpqtypes does no range +checking on NAME, BPCHAR or VARCHAR, it lets the server perform these checks. +There are two ways to put strings: allow libpqtypes to make an internal copy of the +string (default behavior) or as a direct pointer: (both require that the C +string is NUL-terminated) +.RS +.nf +\fB +/* Put a string so libpqtypes makes a copy. In this case, + * 4 copies would be made of the same string. + */ +PGtext str = "foobar"; +PQputf(param, "%bpchar %varchar %name %text", str, str, str, str); + +/* Put a string so libpqtypes doesn\'t make a copy, + * keeps a direct pointer. More efficient than above, + * especially if these are large strings. + */ +PQputf(param, "%bpchar* %varchar* %name* %text*", str, str, str, str);\fP +.fi +.RE + +WARNING: Be careful about variable scope when using the "*" specifier flag: +.RS +.nf +\fB +/* when \'func\' returns, the str pointer becomes invalid! + * The below should be using "%text" ... w/o the * flag. + */ +int func(PGparam *param) +{ + PGchar str[16]; + strcpy(str, "foobar"); + return PQputf(param, "%text*", str); // BAD IDEA! +}\fP +.fi +.RE + +To \fIPQgetf(3)\fP a string, you supply a pointer to a PGtext. Unlike putting string +values, getting them doesn\'t make use of the "*" specifier flag (silently ignored). +.RS +.nf +\fB +/* Get a string value */ +PGvarchar str; +PQgetf(result, tup_num, "%varchar", field_num, &str); + +/* identical to */ +str = PQgetvalue(result, tup_num, field_num);\fP +.fi +.RE + +The reason the \'*\' specifier flag is silently ignored, rather than raising a syntax +error, is it is common to define macros for specifer strings; that can be used for +puts and gets: +.RS +.nf +\fB +/* user_id, username, password */ +#define TYPESPEC_USERINFO "%int4 %text* %text*" + +PGint4 uid = 0; +PGtext user = "foo", pass = "bar"; +PQputf(param, TYPESPEC_USERINFO, uid, user, pass); +PQgetf(param, tup_num, TYPESPEC_USERINFO, 0, &uid, 1, &user, 2, &pass);\fP +.fi +.RE + +The above allowance is more useful than a syntax error. +.SH BYTEA +.LP +There are two ways to put a bytea: copy or direct pointer (just like variable-length +character types). In either case, you supply a pointer to a PGbytea. +.RS +.nf +\fB +typedef struct +{ + int len; /* number of bytes */ + char *data; /* pointer to the bytea data */ +} PGbytea; + +/* Put a bytea letting libpqtypes make a copy; */ +PGbytea bytea = {4, {0, 1, 2, 3}}; +PQputf(param, "%bytea", &bytea); + +/* Put a bytea not letting libpqtypes make a copy, stores a + * direct pointer to PGbytea.data. + */ +PQputf(param, "%bytea*", &bytea);\fP +.fi +.RE + +To get a bytea, you provide a pointer to a PGbytea. Unlike putting bytea +values, there is only one way to get them. +.RS +.nf +\fB +/* Get a bytea value (exposed as binary, no + * escaping/unescaping needed) + */ +PGbytea bytea; +PQgetf(result, tup_num, "%bytea", field_num, &bytea);\fP +.fi +.RE + +NOTE: For text results, PQgetlength will not match the length returned by \fIPQgetf(3)\fP. +The values \fIPQgetf(3)\fP assigns to the user provided PGbytea* represent the unescaped bytea value. +.SH DATE +.LP +PGdate is used by DATE, TIMESTAMP and TIMESTAMPTZ data types. To put a date, +you must set the isbc, year, mon and mday members. All other members are ignored. + +.RS +.nf +\fBtypedef struct +{ + /* When non-zero, the date is in the BC ERA. */ + int isbc; + + /* + * The BC or AD year, which is NOT adjusted by 1900 like + * the POSIX struct tm. Years are always positive values, + * even BC years. To distinguish between BC and AD years, + * use the isbc flag: (year 0 not used) + * Ex. -1210 is represented as: isbc=1, year=1209 + */ + int year; + + /* The number of months since January, in the range 0 to 11. */ + int mon; + + /* The day of the month, in the range 1 to 31. */ + int mday; + + /* The Julian day in the Gregorian calendar. */ + int jday; + + /* The number of days since January 1, in the range 0 to 365. */ + int yday; + + /* The number of days since Sunday, in the range 0 to 6. */ + int wday; +} PGdate;\fP +.fi +.RE + +Putting a date value: +.RS +.nf +\fB +// \'1401-01-19 BC\' +PGdate date; +date.isbc = 1; +date.year = 1401; +date.mon = 0; +date.mday = 19; +PQputf(param, "%date", &date);\fP +.fi +.RE + +Getting a date value: +.RS +.nf +\fB +PQgetf(result, tup_num, "%date", field_num, &date);\fP +.fi +.RE +.SH TIME +.LP +PGtime is used by TIME, TIMETZ, TIMESTAMP and TIMESTAMPTZ data types. To put a time, you must set the hour, min, sec and usec members. All other members are ignored. +.RS +.nf +\fB +typedef struct +{ + /* The number of hours past midnight, in the range 0 to 23. */ + int hour; + + /* The number of minutes after the hour, in the + * range 0 to 59. + */ + int min; + + /* The number of seconds after the minute, in the + * range 0 to 59. + */ + int sec; + + /* The number of microseconds after the second, in the + * range of 0 to 999999. + */ + int usec; + + /* + * When non-zero, this is a TIME WITH TIME ZONE. Otherwise, + * it is a TIME WITHOUT TIME ZONE. + */ + int withtz; + + /* A value of 1 indicates daylight savings time. A value of 0 + * indicates standard time. A value of -1 means unknown or + * could not determine. + */ + int isdst; + + /* Offset from UTC in seconds. This value is not always + * available. It is set to 0 if it cannot be determined. + */ + int gmtoff; + + /* Timezone abbreviation: such as EST, GMT, PDT, etc. + * This value is not always available. It is set to an empty + * string if it cannot be determined. + */ + char tzabbr[16]; +} PGtime; +\fP +.fi +.RE + +Putting a time value: +.RS +.nf +\fB +// \'10:41:06.002897\' +PGdate time; +time.hour = 10; +time.min = 41; +time.sec = 6; +time.usec = 2897; +PQputf(param, "%time", &time);\fP +.fi +.RE + +Getting a time value: +.RS +.nf +\fB +PQgetf(result, tup_num, "%time", field_num, &time); +\fP +.fi +.RE +.SH TIMETZ +.LP +The TIMETZ data type uses the PGtime structure, for a description of this +structure see the TIME section. To put a timetz, you must set the hour, min, +sec, usec and gmtoff members. All other members are ignored. + +Putting a timetz value: +.RS +.nf +\fB +// \'10:41:06.002897-05\' +PGdate timetz; +timetz.hour = 10; +timetz.min = 41; +timetz.sec = 6; +timetz.usec = 2897; +timetz.gmtoff = -18000; +PQputf(param, "%timetz", &timetz); +\fP +.fi +.RE + +Getting a timetz value: +.RS +.nf +\fB +PQgetf(result, tup_num, "%timetz", field_num, &timetz); +\fP +.fi +.RE +.SH TIMESTAMP +.LP +To put a timestamp, the isbc, year, mon, mday, hour, min, sec and usec members must be set. No other members are used. +.RS +.nf +\fB +typedef struct +{ + /* The number seconds before or after midnight UTC of + * January 1, 1970, not counting leap seconds. + */ + PGint8 epoch; + + /* The date part of the timestamp. */ + PGdate date; + + /* The time part of the timestamp. */ + PGtime time; +} PGtimestamp; +\fP +.fi +.RE + +Putting a timestamp value: +.RS +.nf +\fB +// \'2000-01-19 10:41:06\' +PGtimestamp ts; +ts.date.isbc = 0; +ts.date.year = 2000; +ts.date.mon = 0; +ts.date.mday = 19; +ts.time.hour = 10; +ts.time.min = 41; +ts.time.sec = 6; +ts.time.usec = 0; +PQputf(param, "%timestamp", &ts); +\fP +.fi +.RE + +Getting a timestamp value: +.RS +.nf +\fB +PQgetf(result, tup_num, "%timestamp", field_num, &ts); +\fP +.fi +.RE + +The timestamp type has no concept of timezone, so the value returned by \fIPQgetf(3)\fP is +exactly what the server sent; no timezone adjustments are attempted. The gmtoff is always +set to zero, tzabbr will be an empty string and withtz will be zero. +.SH TIMESTAMPTZ +.LP +To put a timestamptz, the isbc, year, mon, mday, hour, min, sec, usec and gmtoff +members must be set. No other members are used. + +Putting a timestamptz value: +.RS +.nf +\fB +// \'2000-01-19 10:41:06-05\' +PGtimestamp ts; +ts.date.isbc = 0; +ts.date.year = 2000; +ts.date.mon = 0; +ts.date.mday = 19; +ts.time.hour = 10; +ts.time.min = 41; +ts.time.sec = 6; +ts.time.usec = 0; +ts.time.gmtoff = -18000; +PQputf(param, "%timestamptz", &ts); +\fP +.fi +.RE + +Getting a timestamptz value: +.RS +.nf +\fB +PQgetf(result, tup_num, "%timestamptz", field_num, &ts); +\fP +.fi +.RE + +When using \fIPQgetf(3)\fP in binary mode, the timestamptz value is converted into the local +machine\'s timezone. If the local machine's timezone can not be determined, the +value will be in GMT (gmtoff is set to zero and tzabbr is set to GMT). + +When using \fIPQgetf(3)\fP in text mode, the timestamptz value is returned as a datetime string +in the server\'s timezone. No adjustments are made to this value. If the server is +using a DateStyle that encodes the gmtoff "00:00:00-05", then gmtoff will be set to +this value and tzabbr will be "GMT+/-hhmmss" (00:00:00-05 => GMT-0500). In this case, +isdst is set to -1 ... meaning unknown. If the server\'s DateStyle encodes a timezone +abbreviation, like PST, then tzabbr is set to this value. The gmtoff and isdst members +are properly set: + +.nf + DateStyle includes a timezone abbrev - "SQL, MDY" + 01/25/2007 00:00:00 EST => tzabbr=EST, gmtoff=-18000, isdst=0 + 01/25/2007 01:00:00 EDT => tzabbr=EDT, gmtoff=-14400, isdst=1 +.fi +.SH INTERVAL +.LP +To put an interval, all relevant members of a PGinterval should be assigned and those +not used should be set to zero. +.RS +.nf +\fB +typedef struct +{ + /* the number of years */ + int years; + + /* the number of months */ + int mons; + + /* the number of days */ + int days; + + /* the number of hours */ + int hours; + + /* the number of mins */ + int mins; + + /* the number of seconds */ + int secs; + + /* the number of microseconds */ + int usecs; +} PGinterval; +\fP +.fi +.RE + +Putting an interval value: +.RS +.nf +\fB +// "20 years 8 months 9 hours 10 mins 15 secs 123456 usecs" +PGinterval interval; +interval.years = 20; +interval.mons = 8; +interval.days = 0; // not used, set to 0 +interval.hours = 9; +interval.mins = 10; +interval.secs = 15; +interval.usecs = 123456; +PQputf(param, "%interval", &interval); +\fP +.fi +.RE + +Getting an interval value: +.RS +.nf +\fB +PQgetf(result, tup_num, "%interval", field_num, &interval); +\fP +.fi +.RE + +NOTE: When using text results with a non-ISO DateStyle, microseconds are +truncated to a 2 digit value. For example: "4 mins 2.11 secs" but microseconds +is really 111456. +.SH POINT +.LP +The PGpoint structure is used to put and get a point. +.RS +.nf +\fB +typedef struct +{ + double x; // point x value + double y; // point y value +} PGpoint; +\fP +.fi +.RE + +Putting a point value: +.RS +.nf +\fB +PGpoint pt = {12.345, 6.789}; +PQputf(param, "%point", &pt); +\fP +.fi +.RE + +Getting a point value: +.RS +.nf +\fB +PGpoint pt; +PQgetf(result, tup_num, "%point", field_num, &pt); +\fP +.fi +.RE +.SH LSEG +.LP +The PGlseg structure is used to put and get a line segnment. +.RS +.nf +\fB +typedef struct +{ + PGpoint pts[2]; +} PGlseg; +\fP +.fi +.RE + +Putting a lseg value: +.RS +.nf +\fB +PGlseg lseg = {{{12.345, 6.789}, {99.8, 88.9}}}; +PQputf(param, "%lseg", &lseg); +\fP +.fi +.RE + +Getting a lseg value: +.RS +.nf +\fB +PGlseg lseg; +PQgetf(result, tup_num, "%lseg", field_num, &lseg); +\fP +.fi +.RE +.SH BOX +.LP +The PGbox structure is used to put and get a box. +.RS +.nf +\fB +typedef struct +{ + PGpoint high; + PGpoint low; +} PGbox; +\fP +.fi +.RE + +Putting a box value: +.RS +.nf +\fB +PGbox box = {{12.345, 6.789}, {22.234, 1.9998}}; +PQputf(param, "%box", &box); +\fP +.fi +.RE + +Getting a box value: +.RS +.nf +\fB +PGbox box; +PQgetf(result, tup_num, "%box", field_num, &box); +\fP +.fi +.RE +.SH CIRCLE +.LP +The PGcircle structure is used to put and get a circle. +.RS +.nf +\fB +typedef struct +{ + PGpoint center; + double radius; +} PGcircle; +\fP +.fi +.RE + +Putting a circle value: +.RS +.nf +\fB +PGcircle circle = {{12.345, 6.789}, 2.34567}; +PQputf(param, "%circle", &circle); +\fP +.fi +.RE + +Getting a circle value: +.RS +.nf +\fB +PGcircle circle; +PQgetf(result, tup_num, "%circle", field_num, &circle); +\fP +.fi +.RE +.SH PATH +.LP +The PGpath structure is used to put and get a path. If the closed member is +non-zero, the path is closed, otherwise it is open. +.RS +.nf +\fB +typedef struct +{ + int npts; + int closed; + PGpoint *pts; +} PGpath; +\fP +.fi +.RE + +Putting a path value: +.RS +.nf +\fB +// Put a closed path that contains 2 points +PGpoint pts[] = {{12.345, 6.789}, {19.773, 7.882}}; +PGpath path = {2, 1, pts}; +PQputf(param, "%path", &path); +\fP +.fi +.RE + +Getting a path value: +.RS +.nf +\fB +PGpath path; +if(PQgetf(result, tup_num, "%path", field_num, &path)) +{ + // path.pts must be copied out if needed after clearing results + copy_points(path.npts, path.pts, ...); + + PQclear(result); + // path.pts is now invalid! +} +\fP +.fi +.RE +.SH POLYGON +.LP +The PGpolygon structure is used to put and get a polygon. +.RS +.nf +\fB +typedef struct +{ + int npts; + PGpoint *pts; +} PGpolygon; +\fP +.fi +.RE + +Putting a polygon value: +.RS +.nf +\fB +// Put a polygon that contains 2 points +PGpoint pts[] = {{12.345, 6.789}, {19.773, 7.882}}; +PGpolygon polygon = {2, 1, pts}; +PQputf(param, "%polygon", &polygon); +\fP +.fi +.RE + +Getting a polygon value: +.RS +.nf +\fB +PGpolygon polygon; +if(PQgetf(result, tup_num, "%polygon", field_num, &polygon)) +{ + // polygon.pts must be copied out if needed after clearing results + copy_points(polygon.npts, polygon.pts, ...); + + PQclear(result); + // polygon.pts is now invalid +} +\fP +.fi +.RE +.SH INET & CIDR +.LP +When putting an inet or cidr, all members must be set excluding the sa_len. +.RS +.nf +\fB +typedef struct +{ + /* The address mask, 32 for a single IP. */ + int mask; + + /* When non-zero, the PGinet structure represents a cidr + * otherwise an inet. + */ + int is_cidr; + + /* the length in bytes of the sa_buf member. */ + int sa_len; + + /* the socket address buffer, contains the data. This can + * be casted to a sockaddr, sockaddr_in, sockaddr_in6 or a + * sockaddr_storage structure. This buffer is 128 bytes so + * that it is large enough for a sockaddr_storage structure. + */ + char sa_buf[128]; +} PGinet; +\fP +.fi +.RE + +Putting an inet or cidr: +.RS +.nf +\fB +socklen_t len; +PGinet inet; + +cli_fd = accept(srv_fd, (struct sockaddr *)inet.sa_buf, &len); +if(cli_fd != -1) +{ + inet.is_cidr = 0; + inet.mask = 32; + PQputf(param, "%inet", &inet); +} +\fP +.fi +.RE + +Getting an inet or cidr: +.RS +.nf +\fB +PGinet inet; +unsigned short port; + +/* gets an inet from field 2 and an int2 from field 6 */ +if(PQgetf(result, tup_num, "%inet %int2", 2, &inet, 6, &port)) +{ + char ip[80]; + struct sockaddr *sa = (struct sockaddr *)inet.sa_buf; + + // converting a PGinet to an IPv4 or IPv6 address string + getnameinfo(sa, inet.sa_len, ip, sizeof(ip), + NULL, 0, NI_NUMERICHOST); + + // The inet data type does not store a port. + if(sa->sa_family == AF_INET) + ((struct sockaddr_in *)sa)->sin_port = htons(port); + else + ((struct sockaddr_in6 *)sa)->sin6_port = htons(port); + + printf("Connecting to %s:%d\\n", ip, port); + connect(sock_fd, sa, inet.sa_len); +} +\fP +.fi +.RE +.SH MACADDR +.LP +The PGmacaddr structure is used to put and get a macaddr. +.RS +.nf +\fB +typedef struct +{ + int a; + int b; + int c; + int d; + int e; + int f; +} PGmacaddr; +\fP +.fi +.RE + +Putting a macaddr value: +.RS +.nf +\fB +PGmacaddr macaddr = {0, 1, 2, 3, 4, 5}; +PQputf(param, "%macaddr", &macaddr); +\fP +.fi +.RE + +Getting a macaddr value: +.RS +.nf +\fB +PGmacaddr macaddr; +PQgetf(result, tup_num, "%macaddr", field_num, &macaddr); +\fP +.fi +.RE +.SH MONEY +.LP +The money type is put/get as a PGmoney (64-bit integer). It can be +converted to dollar and cents format by dividing by 100: +double money = (double)money64 / 100.0;. Pre 8.3 servers are limited to +32-bit money values. + +Putting a money value (put two money values, one is an SQL NULL): +.RS +.nf +\fB +PGmoney money = 600000000054LL; // 6 billion dollars and 54 cents +PQputf(param, "%money %money*", money, NULL); +\fP +.fi +.RE + +Getting a money value: +.RS +.nf +\fB +PQgetf(result, tup_num, "%money", field_num, &money); +\fP +.fi +.RE +.SH BOOL +.LP +The bool type is put/get as a PGbool. To put true or false, use 1 or 0. + +Putting a bool value (this puts true and a bool SQL NULL): +.RS +.nf +\fB +PGbool b = 1; // put true +PQputf(param, "%bool %bool*", b, NULL); +\fP +.fi +.RE + +Getting a bool value: +.RS +.nf +\fB +PGbool b; +PQgetf(result, tup_num, "%bool", field_num, &b); +\fP +.fi +.RE +.SH UUID +.LP +The uuid type is put/get as a sequence of 16 bytes. To put a uuid as +text, use "%str". NOTE: this type is not available on pre 8.3 servers. + +Putting a uuid value: +.RS +.nf +\fB +PGuuid uuid = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; +PQputf(param, "%uuid", uuid); +\fP +.fi +.RE + +Getting a uuid value: +.RS +.nf +\fB +PGuuid uuid; +PQgetf(result, tup_num, "%uuid", field_num, &uuid); +\fP +.fi +.RE + +WARNING: The data provided on a put call is expected to be at least 16 bytes. +.SH OID +.LP +Putting an oid value: +.RS +.nf +\fB +Oid oid = 2318; +PQputf(param, "%oid", oid); +\fP +.fi +.RE + +Getting an oid value: +.RS +.nf +\fB +Oid oid; +PQgetf(result, tup_num, "%oid", field_num, &oid); +\fP +.fi +.RE +.SH EXAMPLES +.LP +None. +.SH AUTHOR +.LP +A contribution of eSilo, LLC. for the PostgreSQL Database Management System. +Written by Andrew Chernow and Merlin Moncure. +.SH REPORTING BUGS +.LP +Report bugs to . +.SH COPYRIGHT +.LP +Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.LP +\fIPQgetf(3)\fP, \fIPQputf(3)\fP. diff --git a/source/groff2html b/source/groff2html new file mode 100644 index 0000000..c8a0182 --- /dev/null +++ b/source/groff2html @@ -0,0 +1,109 @@ +#!/bin/bash + +######################################################################## +# Converts a man page to very simple html, basically a page with +# A and PRE tags. Takes 1 arguments: path to the non-compressed man +# page. This expects the man page to be named PAGE_NAME.SECTION_NUMBER; +# like `PQgetf.3' or `printf.1'. +# +# FEATURES +# 1. Any some_man(3), no spaces before '(', is substituted for an +# A tag linking to http://libpqtypes.esilo.com/man3/$man.html +# +# 2. All '<' and '>' are replaced with HTML codes +# +# 3. Mans referencing other mans, via .so macro, are converted +# to symlinks in the output directory. +# +# ISSUES +# Hyperlinks are not 100% substitued into resulting html page. +# The only time there are issues is when the link text in the +# man page was broken across lines. No work-around at this time +# for this issue other than manually ensuring line breaks don't +# occur on `some_man(3)'. +# +# Man pages that reference other man pages, using the .so macro, +# must have the .so command in the first 'head' lines. The +# .so 'path_to_man' cannot include spaces. +###################################################################### + +DOCTYPE="" + +# adjust these to your web server +BASEURL="http:\/\/libpqtypes.esilo.com" +INC_BASEURL="$BASEURL\/include" +MAN_BASEURL="$BASEURL\/man" +OUTDIR=/esilo/www/libpqtypes.esilo.com/man +HEAD_SECTION="" +HEADER="libpqtypes home page

" +FOOTER="

libpqtypes home page" + +if [ $# = 0 ] ; then + echo "Must supply man page to convert" + exit +fi + +# ignore non-existent files +if test ! -f $1 ; then + exit +fi + +manpage=`basename $1` +section=`echo "$manpage" | awk -F . '{print $NF}'` +manpage=${manpage%.[^.]*} + +OUTDIR="${OUTDIR}${section}" +mkdir -p $OUTDIR + +# If a .so reference, create a symlink +solink=`head $1 | grep '.so .*' | cut -d ' ' -f 2` +if test ! -z $solink ; then + target=`basename $solink` + target=${target%.[^.]*} + echo "$OUTDIR/$manpage.html => $OUTDIR/$target.html" + + # remove existing symlink + rm -f $OUTDIR/$manpage.html + ln -s $OUTDIR/$target.html $OUTDIR/$manpage.html + exit +fi + +echo $OUTDIR/$manpage.html + +>$OUTDIR/$manpage.html + +# doctype +if test ! -z "$DOCTYPE" ; then + echo $DOCTYPE >>$OUTDIR/$manpage.html +fi + +# add stadard html tags, include a title +echo -e "\n\n$HEAD_SECTION\nman $manpage\n\n" >>$OUTDIR/$manpage.html + +if test ! -z "$HEADER" ; then + echo $HEADER >>$OUTDIR/$manpage.html +fi + +echo "

" >>$OUTDIR/$manpage.html
+
+# 1. output man in ascii
+# 2. post-process with col removing backspaces and tabs
+# 3. do some html code replacement 
+# 4. replace some_man(3) with A tags
+groff -t -e -mandoc -Tascii $1 2>/dev/null | col -bx | \
+sed 's//\>/g' | \
+sed "s/\<\([a-ZA-Z0-9_\-]*\.h\)\>/\<\1<\/a>\>/g" | \
+sed "s/\b\([a-zA-Z0-9_\-]\+\)(\([0-9]\))/\1(\2)<\/a>/g" \
+>>$OUTDIR/$manpage.html
+
+echo -e "
\n" >>$OUTDIR/$manpage.html + +if test ! -z "$FOOTER" ; then + echo $FOOTER >>$OUTDIR/$manpage.html +fi + +# html closing tags +echo -e "\n" >>$OUTDIR/$manpage.html + +chown apache:apache $OUTDIR/$manpage.html + diff --git a/source/latest.diff b/source/latest.diff new file mode 100644 index 0000000..70597cd --- /dev/null +++ b/source/latest.diff @@ -0,0 +1,709 @@ +Index: ChangeLog +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/ChangeLog,v +retrieving revision 1.64 +retrieving revision 1.67 +diff -r1.64 -r1.67 +10a11,36 +> (NOT RELEASED), v1.5.2 +> - BUG: Fixed putting binary empty strings. Previously, the string was +> incorrectly converted to SQL NULLs, but now are properly packed and +> transmitted. +> - Reported by: Dmitry Epstein +> - FEATURE: Added ability to put SQL NULLs for int2, int4, int8, float4, float8, +> numeric,"char", bool and money types. This is accomplished by using +> the type-spec pointer flag "*" and allowing these types to be passed as +> pointers: +> >> +> int *i = NULL; +> if(something_is_true) +> *i = 10; +> PQputf(param, "%int4*", i); +> >> +> Before this change, the use of "*" flag for these types was ignored +> and passing any of them as pointers was not allowed. +> - Requested by: Dmitry Epstein and several on stackoverflow. +> http://stackoverflow.com/questions/18684331/passing-sql-null-as-a-sql-statement-parameter-value-using-the-postgresql-libpqty +> - Updated Copyright statement from 2011 to 2008 - 2015, affected all source +> code and man page files. +> - Update an example within docs/man3/PQputf.3 to include putting a NULL +> using the pass-by-pointer type-specifier flag '*'. +> - Updated docs/man3/pqt-specs.3 to include documentation in regard to putting +> NULLs using the pass-by-pointer flag. +> +19c45 +< TLS key for each thread's error structure. For whatever reason, +--- +> TLS key for each thread's error structure. For whatever reason, +Index: LICENSE +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/LICENSE,v +retrieving revision 1.3 +retrieving revision 1.4 +diff -r1.3 -r1.4 +5c5 +< Copyright (c) 2009 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +20c20 +< AND ESILO, LLC. HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, +--- +> AND ESILO, LLC. HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, +Index: docs/man3/PQexecf.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQexecf.3,v +retrieving revision 1.6 +retrieving revision 1.8 +diff -r1.6 -r1.8 +1c1 +< .TH "PQexecf" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQexecf" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +96c96 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQgeterror.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQgeterror.3,v +retrieving revision 1.8 +retrieving revision 1.10 +diff -r1.8 -r1.10 +1c1 +< .TH "PQgeterror" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQgeterror" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +49c49 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQgetf.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQgetf.3,v +retrieving revision 1.9 +retrieving revision 1.11 +diff -r1.9 -r1.11 +1c1 +< .TH "PQgetf" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQgetf" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +97c97 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQinitTypes.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQinitTypes.3,v +retrieving revision 1.1 +retrieving revision 1.3 +diff -r1.1 -r1.3 +1c1 +< .TH PQinitTypes 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH PQinitTypes 3 2008-2015 "libpqtypes" "libpqtypes Manual" +47c47 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQlocalTZInfo.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQlocalTZInfo.3,v +retrieving revision 1.5 +retrieving revision 1.7 +diff -r1.5 -r1.7 +1c1 +< .TH "PQlocalTZInfo" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQlocalTZInfo" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +59c59 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQparamCreate.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamCreate.3,v +retrieving revision 1.9 +retrieving revision 1.11 +diff -r1.9 -r1.11 +1c1 +< .TH "PQparamCreate" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQparamCreate" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +69c69 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQparamExec.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamExec.3,v +retrieving revision 1.6 +retrieving revision 1.8 +diff -r1.6 -r1.8 +1c1 +< .TH "PQparamExec" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQparamExec" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +99c99 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQparamSendQuery.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamSendQuery.3,v +retrieving revision 1.4 +retrieving revision 1.6 +diff -r1.4 -r1.6 +1c1 +< .TH "PQparamSendQuery" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQparamSendQuery" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +82c82 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQputf.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQputf.3,v +retrieving revision 1.9 +retrieving revision 1.11 +diff -r1.9 -r1.11 +1c1 +< .TH "PQputf" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQputf" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +47c47,49 +< The example uses \fIPQputf\fP() to put a couple parameters into a PGparam. +--- +> The example uses \fIPQputf\fP() to put a few parameters into a PGparam. Note +> that the last parameter puts an SQL NULL as an int4 using the pass-by-pointer +> type-specifier pointer flag '*', rather than pass-by-value. +52a55 +> PGint4 *i4ptr = NULL; +55c58 +< if(!PQputf(param, "%text %int8", text, i8)) +--- +> if(!PQputf(param, "%text %int8 %int4*", text, i8, i4ptr)) +110c113 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQregisterComposites.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterComposites.3,v +retrieving revision 1.3 +retrieving revision 1.5 +diff -r1.3 -r1.5 +1c1 +< .TH "PQregisterComposites" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQregisterComposites" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +72c72 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQregisterResult.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterResult.3,v +retrieving revision 1.1 +retrieving revision 1.3 +diff -r1.1 -r1.3 +1c1 +< .TH "PQregisterResult" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQregisterResult" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +112c112 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQregisterSubClasses.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterSubClasses.3,v +retrieving revision 1.2 +retrieving revision 1.4 +diff -r1.2 -r1.4 +1c1 +< .TH "PQregisterSubClasses" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQregisterSubClasses" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +54c54 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQregisterTypes.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterTypes.3,v +retrieving revision 1.2 +retrieving revision 1.4 +diff -r1.2 -r1.4 +1c1 +< .TH "PQregisterTypes" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQregisterTypes" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +81c81 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQregisterUserDefinedTypes.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterUserDefinedTypes.3,v +retrieving revision 1.3 +retrieving revision 1.5 +diff -r1.3 -r1.5 +1c1 +< .TH "PQregisterUserDefinedTypes" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQregisterUserDefinedTypes" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +74c74 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQspecPrepare.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQspecPrepare.3,v +retrieving revision 1.13 +retrieving revision 1.15 +diff -r1.13 -r1.15 +1c1 +< .TH "PQspecPrepare" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "PQspecPrepare" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +115c115 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/PQtypesRegister.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQtypesRegister.3,v +retrieving revision 1.5 +retrieving revision 1.7 +diff -r1.5 -r1.7 +1c1 +< .TH PQtypesRegister 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH PQtypesRegister 3 2008-2015 "libpqtypes" "libpqtypes Manual" +45c45 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/pqt-composites.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/pqt-composites.3,v +retrieving revision 1.8 +retrieving revision 1.10 +diff -r1.8 -r1.10 +1c1 +< .TH "pqt-composites" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "pqt-composites" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +256c256 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/pqt-handlers.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/pqt-handlers.3,v +retrieving revision 1.12 +retrieving revision 1.14 +diff -r1.12 -r1.14 +1c1 +< .TH "pqt-handlers" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "pqt-handlers" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +155c155 +< /* The memory behind the 'attDescs' pointer when the number of +--- +> /* The memory behind the 'attDescs' pointer when the number of +591c591 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: docs/man3/pqt-specs.3 +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/pqt-specs.3,v +retrieving revision 1.14 +retrieving revision 1.16 +diff -r1.14 -r1.16 +1c1 +< .TH "pqt-specs" 3 2011 "libpqtypes" "libpqtypes Manual" +--- +> .TH "pqt-specs" 3 2008-2015 "libpqtypes" "libpqtypes Manual" +78,81c78,83 +< * This is called the pointer flag. It is only supported on a +< handful of builtin types during a \fIPQputf(3)\fP, but user registered +< types can provide support for them. Supported types are: +< VARCHAR, BPCHAR, TEXT, BYTEA, NAME and the pqt.str. +--- +> * This is called the pass-by-pointer flag. It is supported by all +> builtin types during a \fIPQputf(3)\fP. For integer, bool, money and +> "char" types (scalars), one can omit this flag to pass-by-value. For +> all other types, omitting this flag has no effect; they are always +> passed by pointer and thus this flag is not needed for things like +> text, timestamp, uuid, etc.. +85c87,90 +< it. +--- +> it. For scalars (ints, bool, etc..), this tell libpqtypes +> to dereference the pointer to get the value. However, an upside +> is that you can pass in a C NULL for the scalar pointer and it +> will produce an SQL NULL when put. +112c117,119 +< type, it will be silently truncated. +--- +> type, it will be silently truncated. Note the use of the pass-by-pointer +> flag being used for the last two arguments, allowing you to easily put +> an SQL NULL for any numeric type. +116,117c123,125 +< PQputf(param, "%int2 %int4 %int8 %float4 %float8", +< SHRT_MAX, INT_MAX, LLONG_MAX, 1234.56, 123456.789);\fP +--- +> PGint2 i2 = 10; +> PQputf(param, "%int2 %int4 %int8 %float4 %float8 %int2* %int8*", +> SHRT_MAX, INT_MAX, LLONG_MAX, 1234.56, 123456.789, &i2, NULL);\fP +305c313 +< PQputf(param, "%char %char", 213, c);\fP +--- +> PQputf(param, "%char %char %char*", 213, c, NULL);\fP +1106c1114 +< Putting a money value: +--- +> Putting a money value (put two money values, one is an SQL NULL): +1111c1119 +< PQputf(param, "%money", money); +--- +> PQputf(param, "%money %money*", money, NULL); +1128c1136 +< Putting a bool value: +--- +> Putting a bool value (this puts true and a bool SQL NULL): +1133c1141 +< PQputf(param, "%bool", b); +--- +> PQputf(param, "%bool %bool*", b, NULL); +1206c1214 +< Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/array.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/array.c,v +retrieving revision 1.11 +retrieving revision 1.13 +diff -r1.11 -r1.13 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/datetime.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/datetime.c,v +retrieving revision 1.12 +retrieving revision 1.14 +diff -r1.12 -r1.14 +7c7 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/error.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/error.c,v +retrieving revision 1.24 +retrieving revision 1.26 +diff -r1.24 -r1.26 +10c10 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/events.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/events.c,v +retrieving revision 1.16 +retrieving revision 1.18 +diff -r1.16 -r1.18 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/exec.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/exec.c,v +retrieving revision 1.25 +retrieving revision 1.27 +diff -r1.25 -r1.27 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/geo.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/geo.c,v +retrieving revision 1.11 +retrieving revision 1.13 +diff -r1.11 -r1.13 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/handler.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/handler.c,v +retrieving revision 1.29 +retrieving revision 1.31 +diff -r1.29 -r1.31 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/libpqtypes-int.h +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/libpqtypes-int.h,v +retrieving revision 1.23 +retrieving revision 1.25 +diff -r1.23 -r1.25 +7c7 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/libpqtypes.h +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/libpqtypes.h,v +retrieving revision 1.35 +retrieving revision 1.37 +diff -r1.35 -r1.37 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/misc.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/misc.c,v +retrieving revision 1.10 +retrieving revision 1.13 +diff -r1.10 -r1.13 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +17c17,30 +< *args->put.out = (PGchar) va_arg(args->ap, int); +--- +> PGchar c; +> +> if (args->is_ptr) +> { +> PGchar *ptr = (PGchar *) va_arg(args->ap, PGchar *); +> PUTNULLCHK(args, ptr); +> c = *ptr; +> } +> else +> { +> c = (PGchar) va_arg(args->ap, int); +> } +> +> *args->put.out = c; +34c47,60 +< *args->put.out = ((char) va_arg(args->ap, PGbool)!=0) ? 1 : 0; +--- +> char b; +> +> if (args->is_ptr) +> { +> PGbool *ptr = (PGbool *) va_arg(args->ap, PGbool *); +> PUTNULLCHK(args, ptr); +> b = (char) *ptr; +> } +> else +> { +> b = (char) va_arg(args->ap, PGbool); +> } +> +> *args->put.out = b != 0 ? 1 : 0; +56c82 +< PGmoney money = va_arg(args->ap, PGmoney); +--- +> PGmoney money; +58a85,95 +> if (args->is_ptr) +> { +> PGmoney *ptr = va_arg(args->ap, PGmoney *); +> PUTNULLCHK(args, ptr); +> money = *ptr; +> } +> else +> { +> money = va_arg(args->ap, PGmoney); +> } +> +Index: src/network.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/network.c,v +retrieving revision 1.10 +retrieving revision 1.12 +diff -r1.10 -r1.12 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/numerics.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/numerics.c,v +retrieving revision 1.11 +retrieving revision 1.14 +diff -r1.11 -r1.14 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +70c70,82 +< PGint2 n = (PGint2) va_arg(args->ap, int); +--- +> PGint2 n; +> +> if (args->is_ptr) +> { +> PGint4 *nptr = va_arg(args->ap, PGint4 *); +> PUTNULLCHK(args, nptr); +> n = (PGint2) *nptr; +> } +> else +> { +> n = (PGint2) va_arg(args->ap, PGint4); +> } +> +103c115,127 +< PGint4 n = va_arg(args->ap, PGint4); +--- +> PGint4 n; +> +> if (args->is_ptr) +> { +> PGint4 *nptr = va_arg(args->ap, PGint4 *); +> PUTNULLCHK(args, nptr); +> n = *nptr; +> } +> else +> { +> n = (PGint4) va_arg(args->ap, PGint4); +> } +> +136c160,172 +< PGint8 i8 = va_arg(args->ap, PGint8); +--- +> PGint8 i8; +> +> if (args->is_ptr) +> { +> PGint8 *nptr = va_arg(args->ap, PGint8 *); +> PUTNULLCHK(args, nptr); +> i8 = *nptr; +> } +> else +> { +> i8 = va_arg(args->ap, PGint8); +> } +> +163,164c199,211 +< PGfloat4 f = (PGfloat4) va_arg(args->ap, double); +< void *vp = (void *)&f; +--- +> void *vp; +> +> if (args->is_ptr) +> { +> vp = (void *) va_arg(args->ap, double *); +> PUTNULLCHK(args, vp); +> } +> else +> { +> PGfloat4 f = (PGfloat4) va_arg(args->ap, double); +> vp = (void *)&f; +> } +> +196c243,255 +< PGfloat8 d = va_arg(args->ap, PGfloat8); +--- +> PGfloat8 d; +> +> if (args->is_ptr) +> { +> PGfloat8 *ptr = (PGfloat8 *) va_arg(args->ap, PGfloat8 *); +> PUTNULLCHK(args, ptr); +> d = *ptr; +> } +> else +> { +> d = va_arg(args->ap, PGfloat8); +> } +> +234a294,295 +> PUTNULLCHK(args, str); +> +Index: src/param.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/param.c,v +retrieving revision 1.23 +retrieving revision 1.27 +diff -r1.23 -r1.27 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +415a416,424 +> else if (datal == 0) +> { +> /* BUG FIX: allows putting empty strings in binary mode. Without this, +> * empty strings would be converted to an SQL NULL. +> * Reported by: Dmitry Epstein +> */ +> static char zero[1] = {0}; +> v->data = zero; +> } +Index: src/port.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/port.c,v +retrieving revision 1.8 +retrieving revision 1.10 +diff -r1.8 -r1.10 +7c7 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/record.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/record.c,v +retrieving revision 1.9 +retrieving revision 1.11 +diff -r1.9 -r1.11 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/spec.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/spec.c,v +retrieving revision 1.10 +retrieving revision 1.12 +diff -r1.10 -r1.12 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/utils.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/utils.c,v +retrieving revision 1.11 +retrieving revision 1.13 +diff -r1.11 -r1.13 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. +Index: src/varlena.c +=================================================================== +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/varlena.c,v +retrieving revision 1.6 +retrieving revision 1.8 +diff -r1.6 -r1.8 +6c6 +< * Copyright (c) 2011 eSilo, LLC. All rights reserved. +--- +> * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. diff --git a/source/latest.log b/source/latest.log new file mode 100644 index 0000000..3f51890 --- /dev/null +++ b/source/latest.log @@ -0,0 +1,1167 @@ +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/AUTHORS,v +Working file: AUTHORS +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/ChangeLog,v +Working file: ChangeLog +head: 1.67 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 67; selected revisions: 3 +description: +---------------------------- +revision 1.67 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +9 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +---------------------------- +revision 1.66 +date: 2015/01/27 12:25:53; author: achernow; state: Exp; lines: +7 -4 +updated changelog and bug fix comment to give credit to those that reported the issues +---------------------------- +revision 1.65 +date: 2015/01/26 17:23:04; author: achernow; state: Exp; lines: +17 -1 +fixed empty string bug and putting NULLs for numberics, bools, etc.. +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/INSTALL,v +Working file: INSTALL +head: 1.6 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 6; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/LICENSE,v +Working file: LICENSE +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 1 +description: +---------------------------- +revision 1.4 +date: 2015/01/27 16:34:49; author: achernow; state: Exp; lines: +2 -2 +updated copyright date within LICENSE file, which was missed by previous refactor since it had a different date. +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/Makefile.am,v +Working file: Makefile.am +head: 1.24 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 24; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/Makefile.win32,v +Working file: Makefile.win32 +head: 1.7 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 7; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/README,v +Working file: README +head: 1.6 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 6; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/acinclude.m4,v +Working file: acinclude.m4 +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/configure.ac,v +Working file: configure.ac +head: 1.29 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 29; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/groff2html,v +Working file: groff2html +head: 1.12 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 12; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/reconf,v +Working file: reconf +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/win32.mak,v +Working file: win32.mak +head: 1.5 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 5; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQclearSpecs.3,v +Working file: docs/man3/PQclearSpecs.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQclearTypes.3,v +Working file: docs/man3/PQclearTypes.3 +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQexecf.3,v +Working file: docs/man3/PQexecf.3 +head: 1.8 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 8; selected revisions: 2 +description: +---------------------------- +revision 1.8 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.7 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQexecvf.3,v +Working file: docs/man3/PQexecvf.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQgetErrorField.3,v +Working file: docs/man3/PQgetErrorField.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQgeterror.3,v +Working file: docs/man3/PQgeterror.3 +head: 1.10 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 10; selected revisions: 2 +description: +---------------------------- +revision 1.10 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.9 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQgetf.3,v +Working file: docs/man3/PQgetf.3 +head: 1.11 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 11; selected revisions: 2 +description: +---------------------------- +revision 1.11 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.10 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQgetvf.3,v +Working file: docs/man3/PQgetvf.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQinitTypes.3,v +Working file: docs/man3/PQinitTypes.3 +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 2 +description: +---------------------------- +revision 1.3 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.2 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQlocalTZInfo.3,v +Working file: docs/man3/PQlocalTZInfo.3 +head: 1.7 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 7; selected revisions: 2 +description: +---------------------------- +revision 1.7 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.6 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamClear.3,v +Working file: docs/man3/PQparamClear.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamCount.3,v +Working file: docs/man3/PQparamCount.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamCreate.3,v +Working file: docs/man3/PQparamCreate.3 +head: 1.11 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 11; selected revisions: 2 +description: +---------------------------- +revision 1.11 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.10 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamDup.3,v +Working file: docs/man3/PQparamDup.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamExec.3,v +Working file: docs/man3/PQparamExec.3 +head: 1.8 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 8; selected revisions: 2 +description: +---------------------------- +revision 1.8 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.7 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamExecPrepared.3,v +Working file: docs/man3/PQparamExecPrepared.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamReset.3,v +Working file: docs/man3/PQparamReset.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamSendQuery.3,v +Working file: docs/man3/PQparamSendQuery.3 +head: 1.6 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 6; selected revisions: 2 +description: +---------------------------- +revision 1.6 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.5 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQparamSendQueryPrepared.3,v +Working file: docs/man3/PQparamSendQueryPrepared.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQputf.3,v +Working file: docs/man3/PQputf.3 +head: 1.11 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 11; selected revisions: 2 +description: +---------------------------- +revision 1.11 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.10 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +7 -4 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQputvf.3,v +Working file: docs/man3/PQputvf.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterComposites.3,v +Working file: docs/man3/PQregisterComposites.3 +head: 1.5 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 5; selected revisions: 2 +description: +---------------------------- +revision 1.5 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.4 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterResult.3,v +Working file: docs/man3/PQregisterResult.3 +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 2 +description: +---------------------------- +revision 1.3 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.2 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/Attic/PQregisterSubClass.3,v +Working file: docs/man3/PQregisterSubClass.3 +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterSubClasses.3,v +Working file: docs/man3/PQregisterSubClasses.3 +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 2 +description: +---------------------------- +revision 1.4 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.3 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/Attic/PQregisterTypeHandler.3,v +Working file: docs/man3/PQregisterTypeHandler.3 +head: 1.9 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 9; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterTypes.3,v +Working file: docs/man3/PQregisterTypes.3 +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 2 +description: +---------------------------- +revision 1.4 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.3 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQregisterUserDefinedTypes.3,v +Working file: docs/man3/PQregisterUserDefinedTypes.3 +head: 1.5 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 5; selected revisions: 2 +description: +---------------------------- +revision 1.5 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.4 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQsendf.3,v +Working file: docs/man3/PQsendf.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQsendvf.3,v +Working file: docs/man3/PQsendvf.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQseterror.3,v +Working file: docs/man3/PQseterror.3 +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQspecPrepare.3,v +Working file: docs/man3/PQspecPrepare.3 +head: 1.15 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 15; selected revisions: 2 +description: +---------------------------- +revision 1.15 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.14 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/Attic/PQtypesObjectHooks.3,v +Working file: docs/man3/PQtypesObjectHooks.3 +head: 1.5 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 5; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/PQtypesRegister.3,v +Working file: docs/man3/PQtypesRegister.3 +head: 1.7 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 7; selected revisions: 2 +description: +---------------------------- +revision 1.7 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.6 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/pqt-composites.3,v +Working file: docs/man3/pqt-composites.3 +head: 1.10 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 10; selected revisions: 2 +description: +---------------------------- +revision 1.10 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.9 +date: 2015/01/27 16:27:36; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/pqt-handlers.3,v +Working file: docs/man3/pqt-handlers.3 +head: 1.14 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 14; selected revisions: 2 +description: +---------------------------- +revision 1.14 +date: 2015/01/27 16:32:21; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.13 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +3 -3 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/docs/man3/pqt-specs.3,v +Working file: docs/man3/pqt-specs.3 +head: 1.16 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 16; selected revisions: 2 +description: +---------------------------- +revision 1.16 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.15 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +23 -15 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/array.c,v +Working file: src/array.c +head: 1.13 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 13; selected revisions: 2 +description: +---------------------------- +revision 1.13 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.12 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/datetime.c,v +Working file: src/datetime.c +head: 1.14 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 14; selected revisions: 2 +description: +---------------------------- +revision 1.14 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.13 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/error.c,v +Working file: src/error.c +head: 1.26 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 26; selected revisions: 2 +description: +---------------------------- +revision 1.26 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.25 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/events.c,v +Working file: src/events.c +head: 1.18 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 18; selected revisions: 2 +description: +---------------------------- +revision 1.18 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.17 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/exec.c,v +Working file: src/exec.c +head: 1.27 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 27; selected revisions: 2 +description: +---------------------------- +revision 1.27 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.26 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/geo.c,v +Working file: src/geo.c +head: 1.13 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 13; selected revisions: 2 +description: +---------------------------- +revision 1.13 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.12 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/getaddrinfo.h,v +Working file: src/getaddrinfo.h +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/handler.c,v +Working file: src/handler.c +head: 1.31 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 31; selected revisions: 2 +description: +---------------------------- +revision 1.31 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.30 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/Attic/hooks.c,v +Working file: src/hooks.c +head: 1.5 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 5; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/libpqtypes-int.h,v +Working file: src/libpqtypes-int.h +head: 1.25 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 25; selected revisions: 2 +description: +---------------------------- +revision 1.25 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.24 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/libpqtypes.h,v +Working file: src/libpqtypes.h +head: 1.37 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 37; selected revisions: 2 +description: +---------------------------- +revision 1.37 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.36 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/misc.c,v +Working file: src/misc.c +head: 1.13 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 13; selected revisions: 3 +description: +---------------------------- +revision 1.13 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.12 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +---------------------------- +revision 1.11 +date: 2015/01/26 17:23:04; author: achernow; state: Exp; lines: +40 -3 +fixed empty string bug and putting NULLs for numberics, bools, etc.. +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/network.c,v +Working file: src/network.c +head: 1.12 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 12; selected revisions: 2 +description: +---------------------------- +revision 1.12 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.11 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/numerics.c,v +Working file: src/numerics.c +head: 1.14 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 14; selected revisions: 3 +description: +---------------------------- +revision 1.14 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.13 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +2 -2 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +---------------------------- +revision 1.12 +date: 2015/01/26 17:23:04; author: achernow; state: Exp; lines: +67 -6 +fixed empty string bug and putting NULLs for numberics, bools, etc.. +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/param.c,v +Working file: src/param.c +head: 1.27 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 27; selected revisions: 4 +description: +---------------------------- +revision 1.27 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.26 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +---------------------------- +revision 1.25 +date: 2015/01/27 12:25:53; author: achernow; state: Exp; lines: +1 -0 +updated changelog and bug fix comment to give credit to those that reported the issues +---------------------------- +revision 1.24 +date: 2015/01/26 17:23:04; author: achernow; state: Exp; lines: +8 -0 +fixed empty string bug and putting NULLs for numberics, bools, etc.. +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/port.c,v +Working file: src/port.c +head: 1.10 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 10; selected revisions: 2 +description: +---------------------------- +revision 1.10 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.9 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/record.c,v +Working file: src/record.c +head: 1.11 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 11; selected revisions: 2 +description: +---------------------------- +revision 1.11 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.10 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/regression-test.c,v +Working file: src/regression-test.c +head: 1.28 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 28; selected revisions: 0 +description: +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/spec.c,v +Working file: src/spec.c +head: 1.12 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 12; selected revisions: 2 +description: +---------------------------- +revision 1.12 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.11 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/utils.c,v +Working file: src/utils.c +head: 1.13 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 13; selected revisions: 2 +description: +---------------------------- +revision 1.13 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.12 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= + +RCS file: /var/lib/gforge/chroot/cvsroot/libpqtypes/libpqtypes/src/varlena.c,v +Working file: src/varlena.c +head: 1.8 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 8; selected revisions: 2 +description: +---------------------------- +revision 1.8 +date: 2015/01/27 16:32:22; author: achernow; state: Exp; lines: +1 -1 +mis-tyyped copyright date change (extra spaces), had to refactor affecting all source and man3 files +---------------------------- +revision 1.7 +date: 2015/01/27 16:27:37; author: achernow; state: Exp; lines: +1 -1 +update pqt-specs.3, PQputf.3 and copyright notices in all source and man3 files +============================================================================= diff --git a/source/reconf b/source/reconf new file mode 100644 index 0000000..7b76083 --- /dev/null +++ b/source/reconf @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# http://opendx.npaci.edu/mail/opendx-dev/2003.07/msg00081.html + +rm -f aclocal.m4 + +CAT=false + +#You should add the contents of `/usr/local/share/aclocal/libtool15.m4' to `aclocal.m4'. +OUT=$(libtoolize --force --copy | grep "You should add the contents of \`[^']*' to \`aclocal.m4'.") +if [ $? == 0 ] ; then + ACLOCAL=$(echo $OUT | sed "s/You should add the contents of \`//;s/' to \`aclocal.m4'.//") + if [ $? == 0 ] ; then + CAT=true + fi +fi + +aclocal +if [ "$CAT" == "true" ] ; then + cat $ACLOCAL >> aclocal.m4 +fi +autoheader +automake -a -i +autoconf + diff --git a/source/src/array.c b/source/src/array.c new file mode 100644 index 0000000..c3354c1 --- /dev/null +++ b/source/src/array.c @@ -0,0 +1,278 @@ + +/* + * array.c + * Type handler for the array data type. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +int +pqt_put_array(PGtypeArgs *args) +{ + int i; + int hasnull=0; + int ndims; + int nitems; + int arrsize; + char *out; + int lbound[MAXDIM]; + int dims[MAXDIM]; + PGarray *arr = va_arg(args->ap, PGarray *); + + PUTNULLCHK(args, arr); + + if (arr->ndims < 0) + return args->errorf(args, "arr.ndims is invalid - %d", arr->ndims); + + /* auto configure when ndims is 0 to 1d array */ + if (arr->ndims == 0) + { + ndims = 1; + dims[0] = arr->param->vcnt; + lbound[0] = 1; + } + else + { + ndims = arr->ndims; + memcpy(lbound, arr->lbound, sizeof(lbound)); + memcpy(dims, arr->dims, sizeof(dims)); + } + + nitems = 1; + for (i=0; i < ndims; i++) + nitems *= dims[i]; + + /* make sure array is on the same page as the param */ + if (nitems != arr->param->vcnt) + return args->errorf(args, + "param element count %d is different than array's %d", + arr->param->vcnt, nitems); + + /* header: ndims + hasnull + elemtype + ((dims + lbound) * ndims) */ + arrsize = 4 + 4 + 4 + (8 * ndims); + + /* compute data length, also get the hasnull flag */ + for (i=0; i < arr->param->vcnt; i++) + { + if (arr->param->vals[i].format == 0) + return args->errorf(args, "Cannot put array elements in text format"); + + arrsize += 4; + if (arr->param->vals[i].datal == NULL_LEN) + hasnull = 1; + else + arrsize += arr->param->vals[i].datal; + } + + /* make sure args->put.out is large enough */ + if (args->put.expandBuffer(args, arrsize) == -1) + return -1; + + out = args->put.out; + + /* number od dimensions */ + pqt_buf_putint4(out, ndims); + out += 4; + + /* array hasnull flag */ + pqt_buf_putint4(out, hasnull); + out += 4; + + /* array element oid */ + pqt_buf_putint4(out, args->typhandler->typoid); + out += 4; + + /* dims and lbound */ + for (i=0; i < ndims; i++) + { + pqt_buf_putint4(out, dims[i]); + out += 4; + + pqt_buf_putint4(out, lbound[i]); + out += 4; + } + + /* write the element lengths and data */ + for (i=0; i < arr->param->vcnt; i++) + { + pqt_buf_putint4(out, arr->param->vals[i].datal); + out += 4; + + if (arr->param->vals[i].datal > 0) + { + memcpy(out, arr->param->vals[i].data, arr->param->vals[i].datal); + out += arr->param->vals[i].datal; + } + } + + return arrsize; +} + +int +pqt_get_array(PGtypeArgs *args) +{ + int i,t; + int vlen; + int ntups; + int nattrs; + Oid elemoid; + DECLVALUE(args); + PGresult *res; + int first_tup; + PGarray *arr = va_arg(args->ap, PGarray *); + + CHKGETVALS(args, arr); + + if (args->format == TEXTFMT) + return args->errorf(args, "array does not support text results"); + + /* number of dims */ + arr->ndims = pqt_buf_getint4(value); + value += 4; + + /* skip NULL flag */ + value += 4; + + /* check the element oid */ + elemoid = (Oid)pqt_buf_getint4(value); + if (elemoid != args->typhandler->typoid) + return args->errorf(args, + "array element type %u is different than what server says %u", + args->typhandler->typoid, elemoid); + value += 4; + + /* arr dims and lbounds */ + first_tup = 1; + for (i=0, ntups=1; i < arr->ndims; i++) + { + arr->dims[i] = pqt_buf_getint4(value); + value += 4; + + arr->lbound[i] = pqt_buf_getint4(value); + value += 4; + + ntups *= arr->dims[i]; + } + + /* This means ndims is zero because the above loop never iterated. */ + if (i == 0) + ntups = 0; + + /* numTuples is the number of array items + * and numAttributes is 1 for non-composites. + */ + nattrs = (args->typhandler->nattrs > 0) ? args->typhandler->nattrs : 1; + + if (!(res = pqt_copyresult(args, nattrs))) + RERR_MEM(args); + + for (t=0; t < ntups; t++) + { + /* get the value len */ + vlen = pqt_buf_getint4(value); + value += 4; + + /* Regular Array with 1 attr per tuple */ + if (args->typhandler->nattrs == 0) + { + /* set the field value */ + if (!PQsetvalue(res, t, 0, value, vlen)) + { + PQclear(res); + return -1; + } + + if (vlen > 0) + value += vlen; + + continue; + } + + /* ------------------------ + * COMPOSITE/RECORD + */ + + /* NULL compsoite array item, fill in attrs with NULL */ + if (vlen == NULL_LEN) + { + int x; + + for (x=0; x < nattrs; x++) + { + if (!PQsetvalue(res, t, x, NULL, NULL_LEN)) + { + PQclear(res); + return -1; + } + } + + /* move on to next tuple, done here. */ + continue; + } + + /* verify that server's attr count matches ours */ + if (first_tup) + { + int attcnt = pqt_buf_getint4(value); + + /* watch for invalidation issues */ + if (attcnt != nattrs) + { + PQclear(res); + return args->errorf(args, + "type handler attribute count is %d but server says it's %d", + args->typhandler->nattrs, attcnt); + } + } + + /* skip attr count */ + value += 4; + + /* composite attributes (record columns) */ + for (i=0; i < nattrs; i++) + { + /* watch for invalidation issues */ + if (first_tup && + (Oid) pqt_buf_getint4(value) != args->typhandler->attDescs[i].attoid) + { + Oid server_oid = (Oid) pqt_buf_getint4(value); + + args->errorf(args, + "type handler attribute OID is %u but server says it's %u", + args->typhandler->attDescs[i].attoid, server_oid); + + PQclear(res); + return -1; + } + + /* skip oid */ + value += 4; + + /* get the value length */ + vlen = pqt_buf_getint4(value); + value += 4; + + /* set the field value */ + if (!PQsetvalue(res, t, i, value, vlen)) + { + PQclear(res); + return -1; + } + + if (vlen > 0) + value += vlen; + } + + first_tup = 0; + } + + arr->res = res; + return 0; +} + + diff --git a/source/src/datetime.c b/source/src/datetime.c new file mode 100644 index 0000000..54d8228 --- /dev/null +++ b/source/src/datetime.c @@ -0,0 +1,1707 @@ + +/* + * datetime.c + * Type handler for TIME, TIMETZ, DATE, TIMESTAMP and TIMESTAMPTZ + * data types. Also includes public function PQlocalTZInfo. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Microsoft went overboard with these warnings. This avoids + * warnings about _timezone and _tzname. The alternatives + * provided by microsoft are terrible. All other warnings, + * like strdup, snprintf, strcpy, etc.. have been avoided + * by using Microsoft alternate functions. This whole thing + * is completely moronic. + */ +#define _CRT_SECURE_NO_WARNINGS + +#include "libpqtypes-int.h" + +#if defined(PQT_WIN32) || defined(HAVE_TIME_H) +# include +#endif + +#if defined(HAVE_CONFIG_H) && defined(HAVE_SYS_TIME_H) +# include +#endif + +#define MINGMTOFF -53940 /* -1459 */ +#define MAXGMTOFF 53940 /* +1459 */ +#define ISVALIDGMTOFF(off) ((off) >= MINGMTOFF && (off) <= MAXGMTOFF) + +#define CHECKDATEVALS(_args, _d) do{ \ + if ((_d)->year < 0) \ + RERR(_args, "invalid year value ... cannot be negative"); \ + if ((_d)->mon < 0 || (_d)->mon > 11) \ + RERR(_args, "invalid month value ... range is 0 to 11"); \ + if ((_d)->mday < 1 || (_d)->mday > 31) \ + RERR(_args, "invalid day value ... range is 1 to 31"); \ +}while (0) + +#define CHECKTIMEVALS(_args, _t, _withtz) do{ \ + if ((_t)->hour < 0 || (_t)->hour > 23) \ + RERR(_args, "invalid hour value ... range is 0 to 23"); \ + if ((_t)->min < 0 || (_t)->min > 59) \ + RERR(_args, "invalid minute value ... range is 0 to 59"); \ + if ((_t)->sec < 0 || (_t)->sec > 59) \ + RERR(_args, "invalid second value ... range is 0 to 59"); \ + if ((_t)->usec < 0 || (_t)->usec > 999999) \ + RERR(_args, "invalid microsecond value ... range is 0 to 999999"); \ + if ((_withtz) && !ISVALIDGMTOFF((_t)->gmtoff)) \ + return (_args)->errorf(_args, \ + "invalid gmtoff value ... range is %d to %d", MINGMTOFF, MAXGMTOFF); \ +}while (0) + +#define MONTHS_PER_YEAR 12 +#define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */ +#define SECS_PER_DAY 86400 +#define SECS_PER_HOUR 3600 +#define SECS_PER_MINUTE 60 +#define MINS_PER_HOUR 60 +#define USECS_PER_DAY PQT_INT64CONST(86400000000) +#define USECS_PER_HOUR PQT_INT64CONST(3600000000) +#define USECS_PER_MINUTE PQT_INT64CONST(60000000) +#define USECS_PER_SEC PQT_INT64CONST(1000000) +#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */ +#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */ + +#define TS_PREC_INV 1000000.0 +#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV) + +/* round off to MAX_TIME_PRECISION decimal places */ +#define TIME_PREC_INV 10000000000.0 +#define TIMEROUND(j) (rint(((double) (j)) * TIME_PREC_INV) / TIME_PREC_INV) + +#define TMODULO(t,q,u) \ +do { \ + (q) = (int) (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \ + if ((q) != 0) (t) -= rint((q) * (u)); \ +} while (0) + +/* Converts "1209 BC" notation to "-1208" */ +#define BC2YEAR(_isbc, _yr) (_isbc) ? -((_yr) - 1) : (_yr) +/* Converts "-1208" to "1209 BC" notation */ +#define YEAR2BC(_yr) ((_yr) <= 0) ? -((_yr) - 1) : (_yr) + +/* date & time functions */ +static int date2j(int y, int m, int d); +static void gmtoff2name(int gmtoff, char *tzNameBuf, size_t size); +static void tzabbr2info(const char *tzabbr, int *gmtoff, int *isdst); +static int text2time(char *timestr, PGtime *time, int withtz); +static int text2interval(char *intvlstr, PGinterval *interval); +static int text2date(const char *datestr, PGdate *date, + const char *datestyle); +static int bin2pgdate(int d, PGdate *date); +static int bin2pgtime(double t, int gmtoff, PGtime *time, int withtz); +static int bin2pginterval(double tval, int days, int mons, + PGinterval *interval); +static int bin2pgts(double ts, PGtimestamp *pgts, int withtz); +static char *time2t(PGtypeArgs *args, PGtime *t, void *val); + +#ifdef PQT_WINAPI +static char *_win32_tzabbr(const char *fullname); +#endif + +#if defined(HAVE_CONFIG_H) && !defined(HAVE_FLOOR) +static double +floor(double x) +{ + /* also works if modf always returns a positive fractional part */ + double val; + return modf(x, &val) < 0 ? val - 1.0 : val ; +} +#endif + +#if defined(HAVE_CONFIG_H) && !defined(HAVE_CEIL) +static double +ceil(double x) +{ + /* also works if modf always returns a positive fractional part */ + double val; + return modf(x, &val) > 0 ? val + 1.0 : val ; +} +#endif + +/* MSVC and unixes w/o rint */ +#if defined(PQT_MSVC) || (defined(HAVE_CONFIG_H) && !defined(HAVE_RINT)) +static double +rint(double x) +{ + double f, n = 0.; + + f = modf(x, &n); + + if (x > 0.) + { + if (f > .5) + n += 1.; + } + else if (x < 0.) + { + if (f < -.5) + n -= 1.; + } + + return n; +} +#endif + +/* + * time: PGtime members must be set: hour, min, sec, usec. + * timetz: PGtime members must be set: hour, min, sec, usec, gmtoff. + */ +static int +put_time2(PGtypeArgs *args, int withtz) +{ + int r=8; + char tbuf[8]; + PGtime *time = va_arg(args->ap, PGtime *); + + PUTNULLCHK(args, time); + CHECKTIMEVALS(args, time, withtz); + + pqt_swap8(args->put.out, time2t(args, time, tbuf), 1); + + if (withtz) + { + pqt_buf_putint4(args->put.out + 8, -time->gmtoff); + r += 4; + } + + return r; +} + +int +pqt_put_time(PGtypeArgs *args) +{ + return put_time2(args, 0); +} + +int +pqt_put_timetz(PGtypeArgs *args) +{ + return put_time2(args, 1); +} + +/* Also handles timetz */ +static int +get_time2(PGtypeArgs *args, int withtz) +{ + DECLVALUE(args); + double t; + int gmtoff=0; + char tbuf[8]; + PGtime *time = va_arg(args->ap, PGtime *); + + CHKGETVALS(args, time); + + if (args->format == TEXTFMT) + { + if (text2time(value, time, withtz) == -1) + RERR(args, "invalid time format"); + return 0; + } + + /* read and convert binary data */ + pqt_swap8(tbuf, value, 0); + if (withtz) + gmtoff = -pqt_buf_getint4(value + 8); + + /* Convert 8 byte integer format to double precision. */ + if (args->fmtinfo->integer_datetimes) + { + PGint8 n = *(PGint8 *) tbuf; + t = (double) n / 1000000.0; + } + else + { + t = *(double *) tbuf; + } + + /* convert binary data to a PGtime */ + if (bin2pgtime(t, gmtoff, time, withtz) == -1) + RERR(args, "negative julian day detected"); + + return 0; +} + +int +pqt_get_time(PGtypeArgs *args) +{ + return get_time2(args, 0); +} + +int +pqt_get_timetz(PGtypeArgs *args) +{ + return get_time2(args, 1); +} + +/* PGdate members required isbc, year, mon, mday */ +int +pqt_put_date(PGtypeArgs *args) +{ + int dval; + PGdate *date = va_arg(args->ap, PGdate *); + + PUTNULLCHK(args, date); + CHECKDATEVALS(args, date); + + dval = date2j(BC2YEAR(date->isbc, date->year), date->mon+1, date->mday) + - POSTGRES_EPOCH_JDATE; + + pqt_buf_putint4(args->put.out, dval); + return 4; +} + +int +pqt_get_date(PGtypeArgs *args) +{ + DECLVALUE(args); + int d; + PGdate *date = va_arg(args->ap, PGdate *); + + CHKGETVALS(args, date); + + if (args->format == TEXTFMT) + { + if (text2date(value, date, args->fmtinfo->datestyle) == -1) + RERR(args, "invalid date format"); + return 0; + } + + d = pqt_buf_getint4(value); + if (bin2pgdate(d, date) == -1) + RERR(args, "binary date conversion failed"); + + return 0; +} + +/* + * timestamp: The timestamp is never converted from what is provided. The + * timezone info is dropped as pgtype 'time' has no concept of timezones. + * The following PGtimestamp members must be set: date.isbc, date.year, + * date.mon, date.mday, time.hour, time.min, time.sec, time.usec. + * + * timestamptz: The timestamptz is always converted to GMT. Its adjusted + * by PGtime.gmtoff, so set this value to zero if you already have GMT. + * The following PGtimestamp members must be set: date.isbc, date.year, + * date.mon, date.mday, time.hour, time.min, time.sec, time.usec, + * time.gmtoff. + */ +static int +put_timestamp2(PGtypeArgs *args, int withtz) +{ + char tbuf[8]; + int year, mon; + PGtimestamp *pgts = va_arg(args->ap, PGtimestamp *); + PGtime *t = &pgts->time; + + PUTNULLCHK(args, pgts); + CHECKDATEVALS(args, &pgts->date); + CHECKTIMEVALS(args, t, withtz); + + mon = pgts->date.mon + 1; + year = BC2YEAR(pgts->date.isbc, pgts->date.year); + + time2t(args, t, tbuf); + + if (args->fmtinfo->integer_datetimes) + { + PGint8 time = *(PGint8 *) tbuf; + int date = date2j(year, mon, pgts->date.mday) - POSTGRES_EPOCH_JDATE; + PGint8 val = (PGint8) (date * USECS_PER_DAY + time); + + /* check for major overflow */ + if ((val - time) / USECS_PER_DAY != date) + RERR(args, "timestamp overflow"); + + /* check for just-barely overflow (okay except time-of-day wraps) */ + if ((val < 0 && date >= 0) || (val >= 0 && date < 0)) + RERR(args, "timestamp overflow"); + + /* currently in localtime, convert to GMT */ + if (withtz) + val -= (t->gmtoff * USECS_PER_SEC); + + pqt_swap8(args->put.out, &val, 1); + } + else + { + double time = *(double *) tbuf; + double date = date2j(year, mon, pgts->date.mday) - POSTGRES_EPOCH_JDATE; + double val = (double) (date * SECS_PER_DAY + time); + + /* currently in localtime, convert to GMT */ + if (withtz) + val -= (t->gmtoff); + + pqt_swap8(args->put.out, &val, 1); + } + + return 8; +} + +int +pqt_put_timestamp(PGtypeArgs *args) +{ + return put_timestamp2(args, 0); +} + +int +pqt_put_timestamptz(PGtypeArgs *args) +{ + return put_timestamp2(args, 1); +} + +/* Also handles timestamptz */ +static int +get_timestamp2(PGtypeArgs *args, int withtz) +{ + DECLVALUE(args); + char tsbuf[8]; + double ts; + PGtimestamp *pgts = va_arg(args->ap, PGtimestamp *); + + CHKGETVALS(args, pgts); + + if (args->format == TEXTFMT) + { + double time; + double date; + int year; + + if (text2date(value, &pgts->date, args->fmtinfo->datestyle) == -1) + RERR(args, "invalid date format"); + + if (text2time(value, &pgts->time, withtz) == -1) + RERR(args, "invalid time format"); + + /* compute ts & epoch values. */ + time2t(NULL, &pgts->time, &time); + year = BC2YEAR(pgts->date.isbc, pgts->date.year); + date = date2j(year, pgts->date.mon+1, pgts->date.mday) - + POSTGRES_EPOCH_JDATE; + ts = (double) (date * SECS_PER_DAY + time); + + /* currently in localtime, convert to GMT */ + if (pgts->time.withtz) + ts -= (pgts->time.gmtoff); + + pgts->epoch = (PGint8) rint(ts - ((double) pgts->time.usec/1000000.0) + + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY); + + return 0; + } + + pqt_swap8(tsbuf, value, 0); + + /* Convert 8 byte integer format to double precision. */ + if (args->fmtinfo->integer_datetimes) + { + PGint8 n = *(PGint8 *) tsbuf; + ts = (double)n / 1000000.0; + } + else + { + ts = *(double *) tsbuf; + } + + if (bin2pgts(ts, pgts, withtz) == -1) + RERR(args, "negative julian day detected"); + + return 0; +} + +int +pqt_get_timestamp(PGtypeArgs *args) +{ + return get_timestamp2(args, 0); +} + +int +pqt_get_timestamptz(PGtypeArgs *args) +{ + return get_timestamp2(args, 1); +} + +int +pqt_put_interval(PGtypeArgs *args) +{ + int day; + int month; + PGinterval *intvl = va_arg(args->ap, PGinterval *); + + PUTNULLCHK(args, intvl); + + month = intvl->years * MONTHS_PER_YEAR + intvl->mons; + day = intvl->days; + + if (args->fmtinfo->integer_datetimes) + { + PGint8 val = (PGint8) ((((((intvl->hours * PQT_INT64CONST(60)) + + intvl->mins) * PQT_INT64CONST(60)) + intvl->secs) * USECS_PER_SEC) + + intvl->usecs); + + pqt_swap8(args->put.out, &val, 1); + } + else + { + double val = (double) ((((intvl->hours * (double) MINS_PER_HOUR) + + intvl->mins) * (double) SECS_PER_MINUTE) + (double) intvl->secs + + ((double) intvl->usecs/1000000.0)); + + pqt_swap8(args->put.out, &val, 1); + } + + pqt_buf_putint4(args->put.out + 8, day); + pqt_buf_putint4(args->put.out + 12, month); + return 16; /* val(8) + day(4) + mon(4) */ + +} + +int +pqt_get_interval(PGtypeArgs *args) +{ + DECLVALUE(args); + double tval; + int mons; + int days; + char tvalbuf[8]; + PGinterval *interval = va_arg(args->ap, PGinterval *); + + CHKGETVALS(args, interval); + + if (args->format == TEXTFMT) + { + if (text2interval(value, interval)== -1) + RERR(args, "invalid interval format"); + return 0; + } + + pqt_swap8(tvalbuf, value, 0); + days = pqt_buf_getint4(value + 8); + mons = pqt_buf_getint4(value + 12); + + /* Convert 8 byte integer format to double precision. */ + if (args->fmtinfo->integer_datetimes) + { + PGint8 n = *(PGint8 *) tvalbuf; + tval = (double) n / 1000000.0; + } + else + { + tval = *(double *) tvalbuf; + } + + if (bin2pginterval(tval, days, mons, interval) == -1) + RERR(args, "binary interval conversion failed"); + return 0; +} + +void +PQlocalTZInfo(time_t *t, int *gmtoff, int *isdst, char **tzabbr) +{ +#if defined(HAVE_STRUCT_TM_TM_ZONE) || defined(HAVE_TM_ZONE) || \ + defined(HAVE_TZNAME) + time_t tbuf; + struct tm *loc; + struct tm buf; + + if (!t) + { + tbuf = time(NULL); + t = &tbuf; + } + +# ifdef HAVE_LOCALTIME_R + /* return value inconsistent. for instance: HP-UX 10 returns an int */ + loc = &buf; + localtime_r(t, loc); +# else + buf.tm_hour = 0; /* avoid compiler warning about unreferenced variable */ + loc = localtime(t); +# endif + + *gmtoff = 0; + *isdst = loc->tm_isdst==1 ? 1 : loc->tm_isdst==0 ? 0 : -1; + if (tzabbr) + *tzabbr = ""; + +# ifdef HAVE_STRUCT_TM_TM_GMTOFF + *gmtoff = (int) loc->tm_gmtoff; +# endif + +# if defined(HAVE_STRUCT_TM_TM_ZONE) || defined(HAVE_TM_ZONE) + if (tzabbr) + *tzabbr = (char *) loc->tm_zone; + + /* Use global timezone and tzname variables */ +# elif defined(HAVE_TZNAME) + *gmtoff = -((loc->tm_isdst > 0) ? pqt_timezone - SECS_PER_HOUR : + pqt_timezone); + if (tzabbr) + *tzabbr = pqt_tzname[(loc->tm_isdst > 0)]; + + /* When winapi is defined, msvc/mingw, tzname contains the windows + * timezone names, like "Eastern Daylight Time" instead of EDT. This + * function will map these names to the standard abbrev. + */ +# ifdef PQT_WINAPI + if (tzabbr) + *tzabbr = _win32_tzabbr(*tzabbr); +# endif +# endif /* HAVE_TZNAME */ + +#else + *gmtoff = 0; + *isdst = -1; + if (tzabbr) + *tzabbr = ""; +#endif /* HAVE_STRUCT_TM_TM_ZONE || HAVE_TM_ZONE || HAVE_TZNAME */ +} + +static char * +time2t(PGtypeArgs *args, PGtime *t, void *val) +{ + if (args && args->fmtinfo->integer_datetimes) + *(PGint8 *) val = (PGint8) (((((t->hour * MINS_PER_HOUR + t->min) * + SECS_PER_MINUTE) + t->sec) * USECS_PER_SEC) + t->usec); + else + *(double *) val = (double) (((t->hour * MINS_PER_HOUR + t->min) * + SECS_PER_MINUTE) + t->sec + (t->usec/1000000.0)); + return val; +} + +static int +text2date(const char *datestr, PGdate *date, const char *datestyle) +{ + int year; + + while (isspace((int) *datestr)) + ++datestr; + + errno = 0; + + /* ISO, SQL or German ('1997-12-17', '12/17/1997', '17.12.1997') */ + if (isdigit((int) *datestr)) + { + int n[3]; + + n[0] = (int) strtol(datestr, (char **) &datestr, 10); + if (errno || (*datestr!='-' && *datestr!='/' && *datestr!='.')) + return -1; + + n[1] = (int) strtol(datestr+1, (char **) &datestr, 10); + if (errno || (*datestr!='-' && *datestr!='/' && *datestr!='.')) + return -1; + + n[2] = (int) strtol(datestr+1, (char **) &datestr, 10); + if (errno) + return -1; + + if (!*datestyle || strstr(datestyle, "ISO") || strstr(datestyle, "YMD")) + { + date->year = n[0]; + date->mon = n[1]; + date->mday = n[2]; + } + else if (strstr(datestyle, "DMY")) + { + date->mday = n[0]; + date->mon = n[1]; + date->year = n[2]; + } + else /* MDY */ + { + date->mon = n[0]; + date->mday = n[1]; + date->year = n[2]; + } + + date->mon--; + } + /* Postgres style: 'Thu Dec 13 19:42:52.442126 2007 EST' */ + else + { + static char *monnames[] = {"jan", "feb", "mar", "apr", "may", + "jun", "jul", "aug", "sep", "oct","nov", "dec"}; + + int i; + + /* skip day of week name */ + if (!(datestr = strchr(datestr, ' '))) + return -1; + datestr++; + + /* datestr is the day DMY */ + if (isdigit((int) *datestr)) + { + date->mday = (int) strtol(datestr, (char **) &datestr, 10); + if (errno) + return -1; + + datestr++; + for (i=0; i < 12; i++) + { + if (pqt_strncasecmp(datestr, monnames[i], 3)==0) + { + date->mon = i; + break; + } + } + + if (i == 12) + return -1; + + datestr += 4; /* skip space after monname */ + } + /* datestr is the monname MDY */ + else + { + int i; + + for (i=0; i < 12; i++) + { + if (pqt_strncasecmp(datestr, monnames[i], 3)==0) + { + date->mon = i; + break; + } + } + + if (i == 12) + return -1; + + datestr += 4; /* skip space after monname */ + date->mday = (int) strtol(datestr, (char **) &datestr, 10); + if (errno) + return -1; + datestr++; /* space after month day */ + } + + /* skip time */ + if (!(datestr = strchr(datestr, ' '))) + return -1; + + date->year = (int) strtol(datestr, NULL, 10); + if (errno) + return -1; + } + + if (date->mday < 0 || date->mday > 31) + return -1; + + if (date->mon < 0 || date->mon > 11) + return -1; + + date->isbc = strstr(datestr, " BC") ? 1 : 0; + year = BC2YEAR(date->isbc, date->year); + date->jday = date2j(year, date->mon+1, date->mday); + date->wday = (date->jday + 1) % 7; + date->yday = date->jday - date2j(year, 1, 1); + return 0; +} + +/* timestr can be a valid timestamp[tz] or time[tz]. */ +static int +text2time(char *timestr, PGtime *time, int withtz) +{ + char *p; + + memset(time, 0, sizeof(PGtime)); + time->isdst = -1; + + if (!(p = strchr(timestr, ':'))) + return -1; + + timestr = p - 2; + errno = 0; + + time->hour = (int) strtol(timestr, ×tr, 10); + if (errno || *timestr != ':' || time->hour < 0 || time->hour > 23) + return -1; + + time->min = (int) strtol(timestr+1, ×tr, 10); + if (errno || *timestr != ':' || time->min < 0 || time->min > 59) + return -1; + + time->sec = (int) strtol(timestr+1, ×tr, 10); + if (errno || time->sec < 0 || time->sec > 59) + return -1; + + if (*timestr == '.') + { + int i=0; + char buf[7]; + + timestr++; + + /* Need 6 digits for usecs to work with strtol, so pad with zeros. */ + memset(buf, '0', 6); + buf[6] = 0; + while (isdigit((int) *timestr)) + buf[i++] = *timestr++; + + time->usec = (int) strtol(buf, NULL, 10); + if (errno || time->usec < 0 || time->usec > 999999) + return -1; + } + + /* no timezone present */ + if (!withtz) + return 0; + + + /* --------------------------------- + * Following ISO 8601, also detecting timezone abbrev. + */ + + time->withtz = 1; + + /* UTC, using 'Z' encoding '00:00:00Z' */ + if (*timestr == 'Z') + { + pqt_strcpy(time->tzabbr, sizeof(time->tzabbr), "UTC"); + timestr++; + } + /* have gmtoff */ + else if (*timestr=='-' || *timestr=='+') + { + int hour = 0; + int min = 0; + int sec = 0; + char sign = *timestr++; + char buf[3]; + + buf[0] = *timestr++; + buf[1] = *timestr++; + buf[2] = 0; + hour = (int) strtol(buf, NULL, 10); + if (errno) + return -1; + + /* +/-hh:mm:ss case (support seconds) */ + if (*timestr == ':') + timestr++; + + /* have minute field */ + if (isdigit((int) *timestr)) + { + buf[0] = *timestr++; + buf[1] = *timestr++; + min = (int) strtol(buf, NULL, 10); + if (errno) + return -1; + + if (*timestr == ':') + timestr++; + + /* have second field */ + if (isdigit((int) *timestr)) + { + buf[0] = *timestr++; + buf[1] = *timestr++; + sec = (int) strtol(buf, NULL, 10); + if (errno) + return -1; + } + } + + time->gmtoff = (hour * 3600) + (min * 60) + sec; + if (sign == '-') + time->gmtoff = -time->gmtoff; + + if (!ISVALIDGMTOFF(time->gmtoff)) + return -1; + } + + /* find the beginning of tzname */ + while (*timestr && !isalpha((int) *timestr)) + timestr++; + + if (*timestr) + { + /* find timezone abbrev end */ + if (!(p = strchr(timestr, ' '))) + p = timestr + strlen(timestr); + + memcpy(time->tzabbr, timestr, p - timestr); + time->tzabbr[p - timestr] = 0; + + /* BC is not a timezone, false-positive */ + if (strcmp(time->tzabbr, "BC")==0) + *time->tzabbr = 0; + } + + if (time->gmtoff != 0 && !*time->tzabbr) + gmtoff2name(time->gmtoff, time->tzabbr, sizeof(time->tzabbr)); + else if (time->gmtoff==0 && *time->tzabbr) + tzabbr2info(time->tzabbr, &time->gmtoff, &time->isdst); + + return 0; +} + +static int +text2interval(char *istr, PGinterval *interval) +{ + char *s; + PGtime pgtime; + int is_before = 0; + + errno = 0; + memset(interval, 0, sizeof(PGinterval)); + + is_before = strstr(istr, "ago") ? 1 : 0; + + if ((s = strstr(istr, " year"))) + { + for (s=s-1; s > istr && !isspace((int) *s); --s) ; + interval->years = (int)strtol(s, NULL, 10); + if (errno) + return -1; + if (!is_before) + is_before = interval->years < 0; + } + + if ((s = strstr(istr, " mon"))) + { + for (s=s-1; s > istr && !isspace((int) *s); --s) ; + interval->mons = (int)strtol(s, NULL, 10); + if (errno) + return -1; + if (!is_before) + is_before = interval->mons < 0; + } + + if ((s = strstr(istr, " day"))) + { + for (s=s-1; s > istr && !isspace((int) *s); --s) ; + interval->days = (int) strtol(s, NULL, 10); + if (errno) + return -1; + if (!is_before) + is_before = interval->days < 0; + } + + /* Means ISO DateStyle is in use, uses the 00:00:00 time format */ + if (text2time(istr, &pgtime, 0) == 0) + { + interval->usecs = pgtime.usec; + interval->secs = pgtime.sec; + interval->mins = pgtime.min; + interval->hours = pgtime.hour; + + /* text2time doesn't support negative values, detect is_before here. + * Find first ':' and subtract two-digit year + possible minus sign. + */ + if (!is_before) + is_before = (s = strchr(istr, ':')) && (*(s - 3) == '-'); + } + /* Means POSTGRES, SQL or GERMAN DateStyle is in use. */ + else + { + if ((s = strstr(istr, " hour"))) + { + for (s=s-1; s > istr && !isspace((int) *s); --s) ; + interval->hours = (int) strtol(s, NULL, 10); + if (errno) + return -1; + } + + if ((s = strstr(istr, " min"))) + { + for (s=s-1; s > istr && !isspace((int) *s); --s) ; + interval->mins = (int) strtol(s, NULL, 10); + if (errno) + return -1; + } + + if ((s = strstr(istr, " sec"))) + { + for (s=s-1; s > istr && !isspace((int) *s); --s) ; + interval->secs = (int) strtol(s, &s, 10); + if (errno) + return -1; + + /* usecs */ + if (*s == '.') + { + int i=0; + char buf[7]; + memset(buf, '0', 6); + buf[6] = 0; + for (s=s+1; isdigit((int) *s); s++) + buf[i++] = *s; + interval->usecs = atoi(buf); + } + } + } + + /* flip unit signs where still needed */ + if (is_before) + { + if (interval->years > 0) + interval->years = -interval->years; + if (interval->mons > 0) + interval->mons = -interval->mons; + if (interval->days > 0) + interval->days = -interval->days; + if (interval->hours > 0) + interval->hours = -interval->hours; + if (interval->mins > 0) + interval->mins = -interval->mins; + if (interval->secs > 0) + interval->secs = -interval->secs; + if (interval->usecs > 0) + interval->usecs = -interval->usecs; + } + + return 0; +} + +/* Uses ISO 8601 GMT+/-hhmmss notation. See tzabbr2info as well. */ +static void +gmtoff2name(int gmtoff, char *buf, size_t size) +{ + char sign; + int mins; + int secs; + + if (gmtoff < 0) + { + sign = '-'; + gmtoff = -gmtoff; + } + else + { + sign = '+'; + } + + mins = gmtoff % 3600; + secs = mins % 60; + + if (secs == 0) + pqt_snprintf(buf, size, "GMT%c%02d%02d", sign, gmtoff/3600, mins/60); + else + pqt_snprintf(buf, size, "GMT%c%02d%02d%02d", + sign, gmtoff/3600, mins/60, secs); +} + +static int +date2j(int y, int m, int d) +{ + int julian; + int century; + + if (m > 2) + { + m += 1; + y += 4800; + } + else + { + m += 13; + y += 4799; + } + + century = y / 100; + julian = y * 365 - 32167; + julian += y / 4 - century + century / 4; + julian += 7834 * m / 256 + d; + + return julian; +} + +static void +j2date(int jd, int *year, int *month, int *day) +{ + unsigned int julian; + unsigned int quad; + unsigned int extra; + int y; + + julian = jd; + julian += 32044; + quad = julian / 146097; + extra = (julian - quad * 146097) * 4 + 3; + julian += 60 + quad * 3 + extra / 146097; + quad = julian / 1461; + julian -= quad * 1461; + y = julian * 4 / 1461; + julian = ((y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366)) + + 123; + y += quad * 4; + *year = y - 4800; + quad = julian * 2141 / 65536; + *day = julian - 7834 * quad / 256; + *month = (quad + 10) % 12 + 1; +} + +static void +dt2time(double jd, int *hour, int *min, int *sec, double *fsec) +{ + *hour = (int) (jd / SECS_PER_HOUR); + jd -= (*hour) * SECS_PER_HOUR; + *min = (int) (jd / SECS_PER_MINUTE); + jd -= (*min) * SECS_PER_MINUTE; + *sec = (int) jd; + *fsec = jd - *sec; +} + +static int +bin2pgdate(int dval, PGdate *date) +{ + memset(date, 0, sizeof(PGdate)); + + j2date(dval + POSTGRES_EPOCH_JDATE, &date->year, &date->mon, &date->mday); + date->jday = date2j(date->year, date->mon, date->mday); + date->yday = date->jday - date2j(date->year, 1, 1); + date->wday = (date->jday + 1) % 7; + + if (date->year <= 0) + { + date->isbc = 1; + date->year = -(date->year-1); + } + + date->mon--; + return 0; +} + +/* gmtoff is seconds east of GMT, adjusted prior to call. */ +static int +bin2pgtime(double tval, int gmtoff, PGtime *time, int withtz) +{ + double rem; + + memset(time, 0, sizeof(PGtime)); + time->isdst = -1; /* no way of knowing */ + + if (withtz) + { + time->gmtoff = gmtoff; + gmtoff2name(time->gmtoff, time->tzabbr, sizeof(time->tzabbr)); + time->withtz = 1; + } + + RECALC: + rem = tval; + TMODULO(rem, time->hour, (double) SECS_PER_HOUR); + TMODULO(rem, time->min, (double) SECS_PER_MINUTE); + TMODULO(rem, time->sec, 1.0); + rem = TIMEROUND(rem); + + /* roundoff may need to propagate to higher-order fields */ + if (rem >= 1.0) + { + tval = ceil(tval); + goto RECALC; + } + + time->usec = (int) (rem * 1000000.0); + + return 0; +} + +static int +breakdown_time(double time, double *datep, PGdate *pgdate, + PGtime *pgtime, double *fsec) +{ + double date; + + TMODULO(time, date, (double) SECS_PER_DAY); + + if (time < 0) + { + time += SECS_PER_DAY; + date -= 1; + } + + /* add offset to go from J2000 back to standard Julian date */ + date += POSTGRES_EPOCH_JDATE; + + RECALC_DATE: + /* Julian day routine does not work for negative Julian days */ + if (date < 0 || date > (PGint8) INT_MAX) + return -1; + + j2date((int)date, &pgdate->year, &pgdate->mon, &pgdate->mday); + + RECALC_TIME: + dt2time(time, &pgtime->hour, &pgtime->min, &pgtime->sec, fsec); + *fsec = TSROUND(*fsec); + + /* roundoff may need to propagate to higher-order fields */ + if (*fsec >= 1.0) + { + time = ceil(time); + if (time >= (double) SECS_PER_DAY) + { + time = 0; + date += 1; + goto RECALC_DATE; + } + goto RECALC_TIME; + } + + if (datep) + *datep = date; + return 0; +} + +static int +bin2pgts(double ts, PGtimestamp *pgts, int withtz) +{ + double fsec; + double date; + double time; + + memset(pgts, 0, sizeof(PGtimestamp)); + pgts->time.isdst = -1; + + time = ts; + + /* server sent UTC, convert to localtime. Need to determine the + * gmtoff for the timestamp epoch value (daylight or not). This + * can differ from what zone the machine is in. If its July in + * NY but the timestamp is Jan, we need to apply EST to timestamp + * rather than EDT. + */ + if (withtz) + { + char *tzabbr; + time_t tepoch; + PGtime pgtime; + PGdate pgdate; + PGint8 t64 = (PGint8) rint(ts); + + pgts->epoch = (PGint8) rint((double) t64 + + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY); + + /* Safe range for a time_t is 0 - INT_MAX. Some system don't support + * negative values at all. System with 64-bit time_t can support + * wider ranges, but there is no way of determining what that is. + * NOTE: 64-bit time_t systems aren't limited to 31-bit upper values. + */ + if (pgts->epoch < 0 || (sizeof(time_t)==4 && pgts->epoch > INT_MAX)) + { + struct tm tm; + + /* pull out the date and time parts so we can issue a mktime + * call, which gets us epoch. + */ + if (breakdown_time(ts, NULL, &pgdate, &pgtime, &fsec) < 0) + return -1; + + memset(&tm, 0, sizeof(struct tm)); + tm.tm_year = 70; /* out-of-safe-range values use 1970 */ + + /* Daylight time was first used by Germany April 30, 1916. So, + * we only recognize its existence after this date. + */ + if (pgdate.year >= 1916) + tm.tm_mon = pgdate.mon - 1; + else /* Ignore month before Apr 1916, use Jan for standard time */ + tm.tm_mon = 0; + + tm.tm_mday = pgdate.mday; + tm.tm_hour = pgtime.hour; + tm.tm_min = pgtime.min; + tm.tm_sec = pgtime.sec; + tm.tm_isdst = -1; + + tepoch = mktime(&tm); + } + else + { + tepoch = (time_t) pgts->epoch; + } + + /* Have an epoch value that can be used to get TZInfo */ + PQlocalTZInfo(&tepoch, &pgts->time.gmtoff, &pgts->time.isdst, &tzabbr); + pqt_strcpy(pgts->time.tzabbr, sizeof(pgts->time.tzabbr), tzabbr); + + /* adjust postgres timestamp by gmtoff. */ + time += pgts->time.gmtoff; + pgts->time.withtz = 1; + } + + /* breakdown the `localtime' adjusted timestamp */ + if (breakdown_time(time, &date, &pgts->date, &pgts->time, &fsec) < 0) + return -1; + + /* jullian day */ + pgts->date.jday = (int) date; + + /* get the epoch, more accurate than previous calculation */ + pgts->epoch = (PGint8) rint( + ts - fsec + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY); + + /* NOTE: dbl_epsilon is too small "2.2204460492503131e-16" */ + pgts->time.usec = (int) (fsec * (1000000.0 + 1E-9)); + + /* use julian day calculations for wday and yday */ + pgts->date.wday = ((int) date + 1) % 7; + pgts->date.yday = (int) date - date2j(pgts->date.year, 1, 1); + + /* Adjust year if this is BC */ + if (pgts->date.year <= 0) + { + pgts->date.year = -(pgts->date.year-1); + pgts->date.isbc = 1; + } + + pgts->date.mon--; + return 0; +} + +static int +bin2pginterval(double tval, int days, int mons, PGinterval *interval) +{ + double time; + double tfrac; + + memset(interval, 0, sizeof(PGinterval)); + + interval->years = mons / MONTHS_PER_YEAR; + interval->mons = mons % MONTHS_PER_YEAR; + interval->days = days; + time = tval; + + RECALC: + TMODULO(time, tfrac, (double) SECS_PER_HOUR); + interval->hours = (int)tfrac; /* could overflow ... */ + + TMODULO(time, tfrac, (double) SECS_PER_MINUTE); + interval->mins = (int)tfrac; + + TMODULO(time, tfrac, 1.0); + interval->secs = (int)tfrac; + + time = TSROUND(time); + /* roundoff may need to propagate to higher-order fields */ + if (time >= 1.0) + { + time = ceil(tval); + goto RECALC; + } + + /* NOTE: dbl_epsilon is too small "2.2204460492503131e-16" */ + interval->usecs = (int) (time * (1000000.0 + 1E-9)); + + return 0; +} + + +/* Generated by the below query: + * + * SELECT '{"' || abbrev || '", ' || + * ((EXTRACT(HOUR FROM utc_offset) * 3600) + + * (EXTRACT(MINUTE FROM utc_offset) * 60) + + * EXTRACT(SECOND FROM utc_offset)) || + * ', ' || (CASE WHEN is_dst THEN 1 ELSE 0 END) || '},' + * FROM pg_timezone_abbrevs; + */ +struct _tzmap_ +{ + const char *abbrev; + int gmtoff; + unsigned char isdst; +}; + +static struct _tzmap_ tzmap[] = { + {"ACSST", 37800, 1}, + {"ACST", -14400, 1}, + {"ACT", -18000, 0}, + {"ADT", -10800, 1}, + {"AESST", 39600, 1}, + {"AEST", 36000, 0}, + {"AFT", 16200, 0}, + {"AKDT", -28800, 1}, + {"AKST", -32400, 0}, + {"ALMST", 25200, 1}, + {"ALMT", 21600, 0}, + {"AMST", 18000, 1}, + {"AMT", 14400, 0}, + {"ANAST", 46800, 1}, + {"ANAT", 43200, 0}, + {"ART", -10800, 0}, + {"AST", -14400, 0}, + {"AWSST", 32400, 1}, + {"AWST", 28800, 0}, + {"AZOST", 0, 1}, + {"AZOT", -3600, 0}, + {"AZST", 18000, 1}, + {"AZT", 14400, 0}, + {"BDST", 7200, 1}, + {"BDT", 21600, 0}, + {"BNT", 28800, 0}, + {"BORT", 28800, 0}, + {"BOT", -14400, 0}, + {"BRA", -10800, 0}, + {"BRST", -7200, 1}, + {"BRT", -10800, 0}, + {"BST", 3600, 1}, + {"BTT", 21600, 0}, + {"CADT", 37800, 1}, + {"CAST", 34200, 0}, + {"CCT", 28800, 0}, + {"CDT", -18000, 1}, + {"CEST", 7200, 1}, + {"CET", 3600, 0}, + {"CETDST", 7200, 1}, + {"CHADT", 49500, 1}, + {"CHAST", 45900, 0}, + {"CKT", 43200, 0}, + {"CLST", -10800, 1}, + {"CLT", -14400, 0}, + {"COT", -18000, 0}, + {"CST", -21600, 0}, + {"CXT", 25200, 0}, + {"DAVT", 25200, 0}, + {"DDUT", 36000, 0}, + {"EASST", -18000, 1}, + {"EAST", -21600, 0}, + {"EAT", 10800, 0}, + {"EDT", -14400, 1}, + {"EEST", 10800, 1}, + {"EET", 7200, 0}, + {"EETDST", 10800, 1}, + {"EGST", 0, 1}, + {"EGT", -3600, 0}, + {"EST", -18000, 0}, + {"FJST", -46800, 1}, + {"FJT", -43200, 0}, + {"FKST", -10800, 1}, + {"FKT", -14400, 0}, + {"FNST", -3600, 1}, + {"FNT", -7200, 0}, + {"GALT", -21600, 0}, + {"GAMT", -32400, 0}, + {"GEST", 14400, 1}, + {"GET", 10800, 0}, + {"GFT", -10800, 0}, + {"GILT", 43200, 0}, + {"GMT", 0, 0}, + {"GYT", -14400, 0}, + {"HKT", 28800, 0}, + {"HST", -36000, 0}, + {"ICT", 25200, 0}, + {"IOT", 21600, 0}, + {"IRKST", 32400, 1}, + {"IRKT", 28800, 0}, + {"IRT", 12600, 0}, + {"IST", 7200, 0}, + {"JAYT", 32400, 0}, + {"JST", 32400, 0}, + {"KDT", 36000, 1}, + {"KGST", 21600, 1}, + {"KGT", 18000, 0}, + {"KOST", 39600, 0}, + {"KRAST", 28800, 1}, + {"KRAT", 25200, 0}, + {"KST", 32400, 0}, + {"LHDT", 39600, 1}, + {"LHST", 37800, 0}, + {"LIGT", 36000, 0}, + {"LINT", 50400, 0}, + {"LKT", 21600, 0}, + {"MAGST", 43200, 1}, + {"MAGT", 39600, 0}, + {"MART", -34200, 0}, + {"MAWT", 21600, 0}, + {"MDT", -21600, 1}, + {"MEST", 7200, 1}, + {"MET", 3600, 0}, + {"METDST", 7200, 1}, + {"MEZ", 3600, 0}, + {"MHT", 43200, 0}, + {"MMT", 23400, 0}, + {"MPT", 36000, 0}, + {"MSD", 14400, 1}, + {"MSK", 10800, 0}, + {"MST", -25200, 0}, + {"MUT", 14400, 0}, + {"MVT", 18000, 0}, + {"MYT", 28800, 0}, + {"NDT", -9000, 1}, + {"NFT", -12600, 0}, + {"NOVST", 25200, 1}, + {"NOVT", 21600, 0}, + {"NPT", 20700, 0}, + {"NST", -12600, 0}, + {"NUT", -39600, 0}, + {"NZDT", 46800, 1}, + {"NZST", 43200, 0}, + {"NZT", 43200, 0}, + {"OMSST", 25200, 1}, + {"OMST", 21600, 0}, + {"PDT", -25200, 1}, + {"PET", -18000, 0}, + {"PETST", 46800, 1}, + {"PETT", 43200, 0}, + {"PGT", 36000, 0}, + {"PHOT", 46800, 0}, + {"PHT", 28800, 0}, + {"PKT", 18000, 0}, + {"PMDT", -7200, 1}, + {"PMST", -10800, 0}, + {"PONT", 39600, 0}, + {"PST", -28800, 0}, + {"PWT", 32400, 0}, + {"PYST", -10800, 1}, + {"PYT", -14400, 0}, + {"RET", 14400, 0}, + {"SADT", 37800, 1}, + {"SAST", 34200, 0}, + {"SCT", 14400, 0}, + {"TAHT", -36000, 0}, + {"TFT", 18000, 0}, + {"TJT", 18000, 0}, + {"TKT", -36000, 0}, + {"TMT", 18000, 0}, + {"TOT", 46800, 0}, + {"TRUT", 36000, 0}, + {"TVT", 43200, 0}, + {"UCT", 0, 0}, + {"ULAST", 32400, 1}, + {"ULAT", 28800, 0}, + {"UT", 0, 0}, + {"UTC", 0, 0}, + {"UYST", -7200, 1}, + {"UYT", -10800, 0}, + {"UZST", 21600, 1}, + {"UZT", 18000, 0}, + {"VET", -14400, 0}, + {"VLAST", 39600, 1}, + {"VLAT", 36000, 0}, + {"VUT", 39600, 0}, + {"WADT", 28800, 1}, + {"WAKT", 43200, 0}, + {"WAST", 25200, 0}, + {"WAT", 3600, 0}, + {"WDT", 32400, 1}, + {"WET", 0, 0}, + {"WETDST", 3600, 1}, + {"WFT", 43200, 0}, + {"WGST", -7200, 1}, + {"WGT", -10800, 0}, + {"YAKST", 36000, 1}, + {"YAKT", 32400, 0}, + {"YAPT", 36000, 0}, + {"YEKST", 21600, 1}, + {"YEKT", 18000, 0}, + {"Z", 0, 0}, + {"ZULU", 0, 0} +}; + +static void +tzabbr2info(const char *tzabbr, int *gmtoff, int *isdst) +{ + int i=0; + + *gmtoff = 0; + *isdst = -1; + + for (i=0; i < countof(tzmap); i++) + { + if (strcmp(tzabbr, tzmap[i].abbrev)==0) + { + *gmtoff = tzmap[i].gmtoff; + *isdst = (int) tzmap[i].isdst; + break; + } + } +} + + +#ifdef PQT_WINAPI +/* ############################################################## + TIME ZONE MAPPING + + Windows doesn't use any abbreviated time zone names, like + EST for Eastern Standard Time. The below list was required + to offer these abbreviations. + + This list was compiled from: + + http://www.date-time-zone.com/ + + which is the same list used by Java. It is a mapping from the windows + registry: "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones" + to the Olson Timezone Database: + + http://www.twinsun.com/tz/tz-link.htm + + NOTE: The below two time zones had a different display name in the + windows registry. The list was adjusted. + + Signapore Standard Time - Malay Peninsula Standard Time + Israel Standard Time - Jerusalem Standard Time +*/ + +static struct { + const char *abbr; + const char *fullname; +} _tzmap[] = { + {"EST", "AUS Eastern Standard Time" }, + {"EST", "AUS Eastern Daylight Time" }, + {"AFT", "Afghanistan Standard Time" }, + {"AKST", "Alaskan Standard Time" }, + {"AKDT", "Alaskan Daylight Time" }, + {"AST", "Arab Standard Time" }, + {"GST", "Arabian Standard Time" }, + {"AST", "Arabic Standard Time" }, + {"ADT", "Arabic Daylight Time" }, + {"AST", "Atlantic Standard Time" }, + {"ADT", "Atlantic Daylight Time" }, + {"AZOT", "Azores Standard Time" }, + {"AZOST", "Azores Daylight Time" }, + {"CST", "Canada Central Standard Time" }, + {"MDT", "Canada Central Daylight Time" }, + {"CVT", "Cape Verde Standard Time" }, + {"CVST", "Cape Verde Daylight Time" }, + {"GET", "Caucasus Standard Time" }, + {"GEST", "Caucasus Daylight Time" }, + {"CST", "Cen. Australia Standard Time" }, + {"CST", "Cen. Australia Daylight Time" }, + {"CST", "Central Standard Time" }, + {"CDT", "Central Daylight Time" }, + {"CST", "Central Standard Time (Mexico)" }, + {"CDT", "Central Daylight Time (Mexico)" }, + {"CST", "Central America Standard Time" }, + {"CDT", "Central America Daylight Time" }, + {"BDT", "Central Asia Standard Time" }, + {"CET", "Central Europe Standard Time" }, + {"CEST", "Central Europe Daylight Time" }, + {"CET", "Central European Standard Time" }, + {"CEST", "Central European Daylight Time" }, + {"MAGT", "Central Pacific Standard Time" }, + {"MAGST", "Central Pacific Daylight Time" }, + {"CST", "China Standard Time" }, + {"CDT", "China Daylight Time" }, + {"GMT+12", "Dateline Standard Time" }, + {"EAT", "E. Africa Standard Time" }, + {"EST", "E. Australia Standard Time" }, + {"EST", "E. Australia Daylight Time" }, + {"EET", "E. Europe Standard Time" }, + {"EEST", "E. Europe Daylight Time" }, + {"BRT", "E. South America Standard Time" }, + {"BRST", "E. South America Daylight Time" }, + {"EST", "Eastern Standard Time" }, + {"EDT", "Eastern Daylight Time" }, + {"EET", "Egypt Standard Time" }, + {"EEST", "Egypt Daylight Time" }, + {"YEKT", "Ekaterinburg Standard Time" }, + {"YEKST", "Ekaterinburg Daylight Time" }, + {"EET", "FLE Standard Time" }, + {"EEST", "FLE Daylight Time" }, + {"FJT", "Fiji Standard Time" }, + {"FJST", "Fiji Daylight Time" }, + {"GMT", "GMT Standard Time" }, + {"BST", "GMT Daylight Time" }, + {"EET", "GTB Standard Time" }, + {"EEST", "GTB Daylight Time" }, + {"WGT", "Greenland Standard Time" }, + {"WGST", "Greenland Daylight Time" }, + {"WET", "Greenwich Standard Time" }, + {"WEST", "Greenwich Daylight Time" }, + {"HST", "Hawaiian Standard Time" }, + {"HPT", "Hawaiian Daylight Time" }, + {"IST", "India Standard Time" }, + {"IST", "India Daylight Time" }, + {"IRST", "Iran Standard Time" }, + {"IRDT", "Iran Daylight Time" }, + {"IST", "Jerusalem Standard Time" }, + {"IDT", "Jerusalem Daylight Time" }, + {"KST", "Korea Standard Time" }, + {"KDT", "Korea Daylight Time" }, + {"CST", "Mexico Standard Time" }, + {"CDT", "Mexico Daylight Time" }, + {"MST", "Mexico Standard Time 2", }, + {"MDT", "Mexico Daylight Time 2", }, + {"FNT", "Mid-Atlantic Standard Time" }, + {"FNST", "Mid-Atlantic Daylight Time" }, + {"MST", "Mountain Standard Time" }, + {"MDT", "Mountain Daylight Time" }, + {"MST", "Mountain Standard Time (Mexico)" }, + {"MDT", "Mountain Daylight Time (Mexico)" }, + {"MMT", "Myanmar Standard Time" }, + {"NOVT", "N. Central Asia Standard Time" }, + {"NOVST", "N. Central Asia Daylight Time" }, + {"NPT", "Nepal Standard Time" }, + {"NZST", "New Zealand Standard Time" }, + {"NZDT", "New Zealand Daylight Time" }, + {"NST", "Newfoundland Standard Time" }, + {"NDT", "Newfoundland Daylight Time" }, + {"KRAT", "North Asia Standard Time" }, + {"KRAST", "North Asia Daylight Time" }, + {"IRKT", "North Asia East Standard Time" }, + {"IRKST", "North Asia East Daylight Time" }, + {"PST", "Pacific Standard Time" }, + {"PDT", "Pacific Daylight Time" }, + {"CLT", "Pacific SA Standard Time" }, + {"CLST", "Pacific SA Daylight Time" }, + {"CET", "Romance Standard Time" }, + {"CEST", "Romance Daylight Time" }, + {"MSK", "Russian Standard Time" }, + {"MSD", "Russian Daylight Time" }, + {"ART", "SA Eastern Standard Time" }, + {"ARST", "SA Eastern Daylight Time" }, + {"COT", "SA Pacific Standard Time" }, + {"COST", "SA Pacific Daylight Time" }, + {"VET", "SA Western Standard Time" }, + {"ICT", "SE Asia Standard Time" }, + {"WST", "Samoa Standard Time" }, + {"SGT", "Malay Peninsula Standard Time" }, + {"MALST", "Malay Peninsula Daylight Time" }, + {"SAST", "South Africa Standard Time" }, + {"SAST", "South Africa Daylight Time" }, + {"IST", "Sri Lanka Standard Time" }, + {"IST", "Sri Lanka Daylight Time" }, + {"CST", "Taipei Standard Time" }, + {"CDT", "Taipei Daylight Time" }, + {"EST", "Tasmania Standard Time" }, + {"EST", "Tasmania Daylight Time" }, + {"JST", "Tokyo Standard Time" }, + {"JDT", "Tokyo Daylight Time" }, + {"TOT", "Tonga Standard Time" }, + {"TOST", "Tonga Daylight Time" }, + {"EST", "US Eastern Standard Time" }, + {"EDT", "US Eastern Daylight Time" }, + {"MST", "US Mountain Standard Time" }, + {"MDT", "US Mountain Daylight Time" }, + {"VLAT", "Vladivostok Standard Time" }, + {"VLAST", "Vladivostok Daylight Time" }, + {"WST", "W. Australia Standard Time" }, + {"WST", "W. Australia Daylight Time" }, + {"WAT", "W. Central Africa Standard Time" }, + {"CET", "W. Europe Standard Time" }, + {"CEST", "W. Europe Daylight Time" }, + {"PKT", "West Asia Standard Time" }, + {"PKST", "West Asia Daylight Time" }, + {"ChST", "West Pacific Standard Time" }, + {"YAKT", "Yakutsk Standard Time" }, + {"YAKST", "Yakutsk Daylight Time" } +}; + +static char * +_win32_tzabbr(const char *fullname) +{ + int i; + static char empty_string[1] = {0}; + + for (i=0; i < countof(tzmap); i++) + if (pqt_strcasecmp(fullname, _tzmap[i].fullname)==0) + return (char *) _tzmap[i].abbr; + + return empty_string; +} + +#endif + diff --git a/source/src/error.c b/source/src/error.c new file mode 100644 index 0000000..3e9d8a8 --- /dev/null +++ b/source/src/error.c @@ -0,0 +1,330 @@ + +/* + * error.c + * The functions in this file represent the libpqtypes error + * system. It offers the API user the ability to set/get errors. + * The error system uses a per-thread global error, implemented + * using TLS (via declspec(thread) or pthread TLS). For + * non-PQT_THREAD_SAFE builds, a static buffer is used. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +/* Cannot use allocated memory for the pqterr_t members. This is + * because windows has no way of freeing per thread allocated + * memory automatically, other than DllMain which won't work for + * a third-party library such as libpqtypes. All error messages + * and fields are truncated to fit their buffers via pqt_strcpy(). + */ +typedef struct +{ + /* Room for user message and a full libpq message */ + char msg[1024 + 8192]; + + /* Error Fields (a little less than 8K for all) */ + char severity[16]; + char sqlstate[16]; + char message_primary[2048]; + char message_detail[1024]; + char message_hint[512]; + char stmt_position[16]; + char internal_position[16]; + char internal_query[2048]; + char context[2048]; + char source_file[256]; + char source_line[16]; + char source_function[80]; +} pqterr_t; + +/* non thread-safe, use a static */ +#ifndef PQT_THREAD_SAFE +static pqterr_t lasterr = {{0}}; + +/* MSVC always uses __declspec(thread) */ +#elif defined(PQT_MSVC) +static __declspec(thread) pqterr_t lasterr = {0}; + +/* Unix-variant, MinGW or Cygwin. */ +#else +#include +static pthread_key_t tlskey_lasterr; + +/* When the thread dies, this will get called. */ +static void tls_free_lasterr(void *value) +{ + if (value) + { + free(value); + pthread_setspecific(tlskey_lasterr, NULL); + + } +} + +/* called before main. This attribute is available since gcc 2.7.0. + * It replaced the obsolete _init ... destructor replaced _fini. + * We used to use pthread_once, but solaris doesn't support this + * in older versions (its simply a stub returning 0, ouch!). + */ +void __attribute__((constructor)) __InItErRoRkEy__(void) +{ + pthread_key_create(&tlskey_lasterr, tls_free_lasterr); +} +#endif + +static void +vseterror(const char *format, va_list ap, int append); + +static pqterr_t * +geterr(void) +{ + pqterr_t *err = NULL; + + /* Non thread-safe mode or windows msvc. */ +#if !defined(PQT_THREAD_SAFE) || defined(PQT_MSVC) + err = &lasterr; + + /* systems requiring pthread TLS keys */ +#else + + /* System is using FSU Threads, like SCO OpenServer 5, which + * has minor prototype differences. + */ +# ifdef PTHREAD_FSU + pthread_getspecific(tlskey_lasterr, (void **) &err); +# else + err = (pqterr_t *) pthread_getspecific(tlskey_lasterr); +# endif + + if (!err) + { + err = (pqterr_t *) malloc(sizeof(pqterr_t)); + if (!err) + return NULL; + memset(err, 0, sizeof(pqterr_t)); + pthread_setspecific(tlskey_lasterr, err); + } + +#endif + + return err; +} + +char * +PQgeterror(void) +{ + static char _empty[1] = {0}; + pqterr_t *err = geterr(); + return err ? err->msg : _empty; +} + +void +PQseterror(const char *format, ...) +{ + /* clear error message by passing in NULL, PQseterror(NULL).*/ + if (!format) + { + pqterr_t *err = geterr(); + + if (err && *err->msg) + { + /* do not memset the entire pqterr_t structure, its around 20K and + * causes performance problems when putting lots of array elements, + * since PQputvf always clears the error PQseterror(NULL) before + * attempting to put data. + */ + *err->msg = 0; + *err->severity = 0; + *err->sqlstate = 0; + *err->message_primary = 0; + *err->message_detail = 0; + *err->message_hint = 0; + *err->stmt_position = 0; + *err->internal_position = 0; + *err->internal_query = 0; + *err->context = 0; + *err->source_file = 0; + *err->source_line = 0; + *err->source_function = 0; + } + } + else + { + va_list ap; + va_start(ap, format); + vseterror(format, ap, FALSE); + } +} + +char * +PQgetErrorField(int fieldcode) +{ + pqterr_t *err = geterr(); + + if (!err) + return NULL; + + switch (fieldcode) + { + case PG_DIAG_SEVERITY: + return err->severity; + + case PG_DIAG_SQLSTATE: + return err->sqlstate; + + case PG_DIAG_MESSAGE_PRIMARY: + return err->message_primary; + + case PG_DIAG_MESSAGE_DETAIL: + return err->message_detail; + + case PG_DIAG_MESSAGE_HINT: + return err->message_hint; + + case PG_DIAG_STATEMENT_POSITION: + return err->stmt_position; + + case PG_DIAG_INTERNAL_POSITION: + return err->internal_position; + + case PG_DIAG_INTERNAL_QUERY: + return err->internal_query; + + case PG_DIAG_CONTEXT: + return err->context; + + case PG_DIAG_SOURCE_FILE: + return err->source_file; + + case PG_DIAG_SOURCE_LINE: + return err->source_line; + + case PG_DIAG_SOURCE_FUNCTION: + return err->source_function; + + default: + return NULL; + } +} + +/* Used by pqt_setresultfields */ +#define geterrfield(buf, name) do{ \ + if ((value = PQresultErrorField(res, name))) \ + pqt_strcpy(buf, sizeof(buf), value); \ + else \ + *buf = 0; \ +}while (0) + +void +pqt_setresultfields(const PGresult *res) +{ + char *value; + pqterr_t *err = geterr(); + + if (!err) + return; + + geterrfield(err->severity, PG_DIAG_SEVERITY); + geterrfield(err->sqlstate, PG_DIAG_SQLSTATE); + geterrfield(err->message_primary, PG_DIAG_MESSAGE_PRIMARY); + geterrfield(err->message_detail, PG_DIAG_MESSAGE_DETAIL); + geterrfield(err->message_hint, PG_DIAG_MESSAGE_HINT); + geterrfield(err->stmt_position, PG_DIAG_STATEMENT_POSITION); + geterrfield(err->internal_position, PG_DIAG_INTERNAL_POSITION); + geterrfield(err->internal_query, PG_DIAG_INTERNAL_QUERY); + geterrfield(err->context, PG_DIAG_CONTEXT); + geterrfield(err->source_file, PG_DIAG_SOURCE_FILE); + geterrfield(err->source_line, PG_DIAG_SOURCE_LINE); + geterrfield(err->source_function, PG_DIAG_SOURCE_FUNCTION); +} + +/* errorf() callback for PGtypeArgs, see PQputf() and PQgetf(). + * Always returns -1. + */ +int +pqt_argserrorf(PGtypeArgs *args, const char *format, ...) +{ + va_list ap; + char fqtn[200]; + + if (!args || !format || !*format) + return -1; + + pqt_fqtn(fqtn, sizeof(fqtn), args->typhandler->typschema, + args->typhandler->typname); + + /* put the header */ + PQseterror("%s[pos:%d] - ", fqtn, args->typpos); + + /* append message from type handler */ + va_start(ap, format); + vseterror(format, ap, TRUE); + return -1; +} + +static void +vseterror(const char *format, va_list ap, int append) +{ + int n; + int curlen = 0; + int size; + va_list ap2; + char *msg = NULL; + pqterr_t *err = geterr(); + + if (!err) + return; + + if (append) + curlen = (int) strlen(err->msg); + else + *err->msg = 0; + + va_copy(ap2, ap); + n = pqt_vsnprintf(err->msg + curlen, sizeof(err->msg) - curlen, format, ap2); + va_end(ap2); + + if (n > -1) + return; + + /* pqterr_t msg buffer is too small for the complete message. We have + * use a temporary buffer to get a successful sprintf so we can + * pqt_strcpy() the result; which truncates to fit. + */ + size = (int) sizeof(err->msg) * 2; + if (!(msg = (char *) malloc(size))) + return; + + while (1) + { + char *p; + + va_copy(ap2, ap); + n = pqt_vsnprintf(msg + curlen, size - curlen, format, ap2); + va_end(ap2); + + /* success */ + if (n > -1) + break; + + /* need more space */ + n = size * 2; + if (!(p = pqt_realloc(msg, n))) + { + /* we're here because sprintf failed, don't trust buffer contents */ + *msg = 0; + break; + } + + msg = p; + size = n; + } + + pqt_strcpy(err->msg, sizeof(err->msg), msg); + free(msg); +} + diff --git a/source/src/events.c b/source/src/events.c new file mode 100644 index 0000000..ea30927 --- /dev/null +++ b/source/src/events.c @@ -0,0 +1,173 @@ + +/* + * events.c + * The libpq PGEventProc implementation. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +static PGtypeData * +allocTypeData(PGconn *conn); + +static void +freeTypeData(PGtypeData *typeData); + +/* Deprecated, use PQinitTypes instead */ +int +PQtypesRegister(PGconn *conn) +{ + return PQinitTypes(conn); +} + +int +pqt_eventproc(PGEventId id, void *info, void *passThrough) +{ + switch (id) + { + case PGEVT_REGISTER: + { + PGEventRegister *e = (PGEventRegister *) info; + void *data = allocTypeData(e->conn); + if (!data) + return FALSE; + PQsetInstanceData((PGconn *) e->conn, pqt_eventproc, data); + break; + } + + case PGEVT_CONNRESET: + { + /* No special handling for PGEVT_CONNRESET. Previously, types were + * automatically re-registered but this idea fails miserably during + * asynchronous resets. Yanked in favor of using the following + * call sequence: PQresetXXX, PQclearTypes, PQregisterTypes. + */ + break; + } + + case PGEVT_CONNDESTROY: + { + PGEventConnDestroy *e = (PGEventConnDestroy *) info; + freeTypeData((PGtypeData *) PQinstanceData(e->conn, pqt_eventproc)); + break; + } + + case PGEVT_RESULTCREATE: + { + PGtypeData *resData; + PGEventResultCreate *e = (PGEventResultCreate *) info; + PGtypeData *connData = (PGtypeData *) PQinstanceData( + e->conn, pqt_eventproc); + + if (!connData || !(resData = allocTypeData(e->conn))) + return FALSE; + + /* copy type handlers from PGconn's typeData */ + if (connData->typhcnt > 0) + { + resData->typhandlers = pqt_duphandlers( + connData->typhandlers, connData->typhcnt); + + if (resData->typhandlers) + resData->typhcnt = connData->typhcnt; + } + + /* copy type specs from PGconn's typeData */ + if (connData->typspeccnt > 0) + { + resData->typspecs = pqt_dupspecs( + connData->typspecs, connData->typspeccnt); + + if (resData->typspecs) + resData->typspeccnt = connData->typspeccnt; + } + + PQresultSetInstanceData((PGresult *) e->result, pqt_eventproc, resData); + break; + } + + case PGEVT_RESULTCOPY: + { + PGtypeData *destData; + PGEventResultCopy *e = (PGEventResultCopy *) info; + PGtypeData *srcData = (PGtypeData *) PQresultInstanceData( + e->src, pqt_eventproc); + + if (!srcData || !(destData = allocTypeData(NULL))) + return FALSE; + + memcpy(&destData->fmtinfo, &srcData->fmtinfo, sizeof(PGtypeFormatInfo)); + + /* copy type handlers from PGresult's typeData */ + if (srcData->typhcnt > 0) + { + destData->typhandlers = pqt_duphandlers( + srcData->typhandlers, srcData->typhcnt); + + if (destData->typhandlers) + destData->typhcnt = srcData->typhcnt; + } + + /* copy type specs from PGresult's typeData */ + if (srcData->typspeccnt > 0) + { + destData->typspecs = pqt_dupspecs( + srcData->typspecs, srcData->typspeccnt); + + if (destData->typspecs) + destData->typspeccnt = srcData->typspeccnt; + } + + PQresultSetInstanceData(e->dest, pqt_eventproc, destData); + break; + } + + case PGEVT_RESULTDESTROY: + { + PGEventResultDestroy *e = (PGEventResultDestroy *) info; + freeTypeData((PGtypeData *) PQresultInstanceData( + e->result, pqt_eventproc)); + break; + } + } + + return TRUE; +} + +static PGtypeData * +allocTypeData(PGconn *conn) +{ + PGtypeData *typeData = (PGtypeData *) malloc(sizeof(PGtypeData)); + + if (typeData) + { + memset(typeData, 0, sizeof(PGtypeData)); + + /* get type formatting info from conn */ + if (conn) + pqt_getfmtinfo(conn, &typeData->fmtinfo); + } + + return typeData; +} + +static void +freeTypeData(PGtypeData *typeData) +{ + if (typeData) + { + pqt_cleartypes(typeData); + + pqt_freespecs(typeData->typspecs, typeData->typspeccnt); + typeData->typspecs = NULL; + typeData->typspeccnt = 0; + typeData->typspecmax = 0; + + free(typeData); + } +} + diff --git a/source/src/exec.c b/source/src/exec.c new file mode 100644 index 0000000..834a382 --- /dev/null +++ b/source/src/exec.c @@ -0,0 +1,562 @@ + +/* + * exec.c + * Query execution and data retrieval functions. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +/* + * Each param value requires an oid, ptr and 2 ints (oid, value, length, + * format). This makes the maximum size of a param 20 bytes. A stack size + * of 4k would allow for 204 query params. If more params are needed, + * heap memory is used. Needing more than 204 param values in a query + * is very rare, although possible. + */ +#define PARAM_STACKSIZE 4096 + +#define BUILD_ARRAYS(rettype) \ + rettype r; \ + char *buf = NULL; \ + Oid *oids = NULL; \ + char **vals = NULL; \ + int *lens = NULL; \ + int *fmts = NULL; \ + int vcnt = 0; \ + char stackbuffer[PARAM_STACKSIZE]; \ +\ + PQseterror(NULL); \ + if (!conn) \ + { \ + PQseterror("PGconn cannot be NULL"); \ + return (rettype)(0); \ + } \ +\ + if (param) \ + { \ + buf = stackbuffer; \ + if (!buildArrays(param, &buf, &oids, &vals, &lens, &fmts)) \ + return (rettype) (0); \ + vcnt = param->vcnt; \ + } + +#define RETURN_RESULT \ + if (param) \ + { \ + if (buf && buf != stackbuffer) \ + free(buf); \ + } \ + return r + +static int +buildArrays(PGparam *param, char **buf, Oid **oids, + char ***vals, int **lens, int **fmts); + +static PGresult * +copyExecError(PGconn *conn, PGresult *r); + +static const char * +getCommand(PGconn *conn, PGparam *param, const char *command); + +static int +_execvf(PGconn *conn, const char *cmdspec, va_list ap, PGresult **resp); + +int +PQgetf(const PGresult *res, int tup_num, const char *format, ...) +{ + int n; + va_list ap; + + va_start(ap, format); + n = PQgetvf(res, tup_num, format, ap); + va_end(ap); + + return n; +} + +int +PQgetvf(const PGresult *res, int tup_num, const char *format, va_list ap) +{ + int r; + PGtypeHandler *h; + PGtypeArgs args; + int typpos = 0; + int flags; + Oid ftype; + PGtypeData *resData; + PGtypeSpec *spec = NULL; + char tmp[200]; + + PQseterror(NULL); + + if (!res) + { + PQseterror("PGresult cannot be NULL"); + return FALSE; + } + + if (!(resData = (PGtypeData *) PQresultInstanceData(res, pqt_eventproc))) + { + PQseterror("PGresult at %p has no event data", res); + return FALSE; + } + + va_copy(args.ap, ap); + + /* "@name" format, lookup typeSpec in cache */ + if(format && *format == '@') + { + spec = pqt_getspec(resData->typspecs, resData->typspeccnt, format + 1); + + /* If we didn't find a type spec, this is an error. A format string + * with a '@' as its first character is reserved. + */ + if (!spec) + { + PQseterror("No such prepared specifier name: '%s'", format + 1); + va_end(args.ap); + return FALSE; + } + } + + while (format && *format) + { + if (spec) + { + /* done, no more handlers in cached spec string. */ + if (typpos == spec->idcnt) + break; + + h = pqt_gethandlerbyid(resData->typhandlers, resData->typhcnt, + spec->idlist[typpos]); + + /* should be an unusual, or a "will never happen", situation */ + if (!h) + { + va_end(args.ap); + PQseterror("Unknown type handler id at position %d", typpos+1); + return FALSE; + } + + flags = (int) spec->flags[typpos]; + typpos++; + } + else + { + format = pqt_parse(format, resData->typhandlers, resData->typhcnt, + NULL, 0, &h, NULL, &typpos, &flags); + + if (!format) + { + va_end(args.ap); + return FALSE; + } + + if (!h) + continue; + } + + if (flags & TYPFLAG_BYNAME) + args.get.field_num = PQfnumber(res, va_arg(args.ap, const char *)); + else + args.get.field_num = va_arg(args.ap, int); + + /* simplify life for handlers by checking getvalue's return here. */ + if (args.get.field_num < 0 || + !PQgetvalue(res, tup_num, args.get.field_num)) + { + PQseterror( + "Invalid tup_num[%d].field_num[%d] (position %d)", + tup_num, args.get.field_num, typpos); + va_end(args.ap); + return FALSE; + } + + ftype = PQftype(res, args.get.field_num); + if (((flags & TYPFLAG_ARRAY) && ftype != h->typoid_array) || + (!(flags & TYPFLAG_ARRAY) && ftype != h->typoid)) + { + Oid oid = (flags & TYPFLAG_ARRAY) ? h->typoid_array : h->typoid; + PQseterror( + "Trying to get type %u '%s' but server returned %u (position %d)", + oid, pqt_fqtn(tmp, sizeof(tmp), h->typschema, h->typname), + ftype, typpos); + va_end(args.ap); + return FALSE; + } + + args.is_put = 0; + args.get.result = (PGresult *) res; + args.format = PQfformat(res, args.get.field_num); + args.fmtinfo = &resData->fmtinfo; + args.get.tup_num = tup_num; + args.is_ptr = (flags & TYPFLAG_POINTER) ? 1 : 0; + args.typpos = typpos; + args.typhandler = h; + args.errorf = pqt_argserrorf; + args.super = pqt_argssuper; + + if (flags & TYPFLAG_ARRAY) + r = pqt_get_array(&args); + else + r = h->typget(&args); + + if (r == -1) + { + va_end(args.ap); + return FALSE; + } + } + + va_end(args.ap); + + return TRUE; +} + +/* -------------------------------- + * Exec and Send functions + */ + +PGresult * +PQexecf(PGconn *conn, const char *cmdspec, ...) +{ + va_list ap; + PGresult *res; + + va_start(ap, cmdspec); + res = PQexecvf(conn, cmdspec, ap); + va_end(ap); + + return res; +} + +PGresult * +PQexecvf(PGconn *conn, const char *cmdspec, va_list ap) +{ + PGresult *res; + (void) _execvf(conn, cmdspec, ap, &res); + return res; +} + +int +PQsendf(PGconn *conn, const char *cmdspec, ...) +{ + int n; + va_list ap; + + va_start(ap, cmdspec); + n = PQsendvf(conn, cmdspec, ap); + va_end(ap); + + return n; +} + +int +PQsendvf(PGconn *conn, const char *cmdspec, va_list ap) +{ + return _execvf(conn, cmdspec, ap, NULL); +} + +PGresult * +PQparamExec(PGconn *conn, PGparam *param, const char *command, + int resultFormat) +{ + BUILD_ARRAYS(PGresult *); + + command = getCommand(conn, param, command); + if (!command) + { + r = NULL; + } + else + { + r = PQexecParams(conn, command, vcnt, oids, + (const char *const * ) vals, lens, fmts, resultFormat); + + pqt_setresultfields(r); + r = copyExecError(conn, r); + } + + RETURN_RESULT; +} + +int +PQparamSendQuery(PGconn *conn, PGparam *param, const char *command, + int resultFormat) +{ + BUILD_ARRAYS(int); + + command = getCommand(conn, param, command); + if (!command) + { + r = FALSE; + } + else + { + r = PQsendQueryParams(conn, command, vcnt, oids, + (const char *const * ) vals, lens, fmts, resultFormat); + + if (!r) + PQseterror("PGconn: %s", PQerrorMessage(conn)); + } + + RETURN_RESULT; +} + +PGresult * +PQparamExecPrepared(PGconn *conn, PGparam *param, const char *stmtName, + int resultFormat) +{ + BUILD_ARRAYS(PGresult *); + + r = PQexecPrepared(conn, stmtName, vcnt, (const char *const * ) vals, + lens, fmts, resultFormat); + + pqt_setresultfields(r); + r = copyExecError(conn, r); + + RETURN_RESULT; +} + +int +PQparamSendQueryPrepared(PGconn *conn, PGparam *param, const char *stmtName, + int resultFormat) +{ + BUILD_ARRAYS(int); + + r = PQsendQueryPrepared(conn, stmtName, vcnt, + (const char *const * ) vals, lens, fmts, resultFormat); + + if (!r) + PQseterror("PGconn: %s", PQerrorMessage(conn)); + + RETURN_RESULT; +} + +/* Called by PQexecvf and PQsendvf. When resp is NULL, PQparamSendQuery + * is used to execute the command. Otherwise, PQparamExec is used. The + * return value is always zero when resp is not NULL. When resp is NULL, + * the return value is zero for error and non-zero for success (identical + * to PQparamSendQuery). + */ +static int +_execvf(PGconn *conn, const char *cmdspec, va_list ap, PGresult **resp) +{ + int retval = 0; + size_t stmt_len=0; + char buffer[8192]; /* could be larger these days but be conservative */ + char *stmt = NULL; + PGparam *param = NULL; + + if (resp) + *resp = NULL; + + if(!conn) + { + PQseterror("PGconn cannot be NULL"); + return FALSE; + } + + if(!cmdspec || !*cmdspec) + { + PQseterror("cmdspec cannot be NULL or an empty string"); + return FALSE; + } + + /* No stmt buf required for preapred type specs */ + if (*cmdspec != '@') + { + /* The resulting parameterized command is guarenteed to be smaller + * than the cmdspec. When needed, enlarge stmt buf to cmdspec length. + */ + stmt_len = strlen(cmdspec) + 1; + + /* stack buffer is too small, use heap */ + if (stmt_len > sizeof(buffer)) + { + if (!(stmt = (char *) malloc(stmt_len))) + { + PQseterror(PQT_OUTOFMEMORY); + return FALSE; + } + } + else + { + stmt = buffer; + stmt_len = sizeof(buffer); + } + } + + if ((param = PQparamCreate(conn))) + { + if (PQputvf(param, stmt, stmt_len, cmdspec, ap)) + { + const char *s = stmt ? stmt : cmdspec; + + if (resp) + *resp = PQparamExec(conn, param, s, 1); + else + retval = PQparamSendQuery(conn, param, s, 1); + } + + PQparamClear(param); + } + + if (stmt && stmt != buffer) + free(stmt); + + return retval; +} + +/* + * Assigns param values to param arrays, for use with postgres + * parameter API. 'buf' is expected to be PARAM_STACKSIZE bytes. If more + * memory is required, memory is allocated and assigned to *buf, which + * must be freed by caller. To determine if *buf was allocated, compare + * its address to the initially provided stack address. + * Returns 1 on success and 0 on error. + */ +static int +buildArrays(PGparam *param, char **buf, Oid **oids, + char ***vals, int **lens, int **fmts) +{ + int n; + + /* no params to assign */ + if (param->vcnt == 0) + return 1; + + /* required memory size for the 4 param arrays */ + n = (int) ((sizeof(void *) * param->vcnt) + /* values */ + ((sizeof(int) * 2) * param->vcnt) + /* lengths and formats */ + (sizeof(Oid) * param->vcnt)); /* oids */ + + /* required memory is too large for stack buffer, get some heap */ + if (n > PARAM_STACKSIZE) + { + char *p; + + if (!(p = (char *) malloc(n))) + { + PQseterror(PQT_OUTOFMEMORY); + return 0; + } + + *buf = p; + } + + /* give arrays memory from buffer, which could be stack or heap. */ + *vals = (char **) *buf; + *lens = (int *) (*buf + (sizeof(void *) * param->vcnt)); + *fmts = (*lens) + param->vcnt; + *oids = (Oid *) ((*fmts) + param->vcnt); + + /* loop param values and assign value, length, format + * and oid to arrays. + */ + for (n=0; n < param->vcnt; n++) + { + (*oids)[n] = param->vals[n].oid; + (*vals)[n] = param->vals[n].data; + (*lens)[n] = param->vals[n].datal; + (*fmts)[n] = param->vals[n].format; + } + + return 1; +} + +static PGresult * +copyExecError(PGconn *conn, PGresult *r) +{ + if (!r) + { + PQseterror("PGconn: %s", PQerrorMessage(conn)); + return NULL; + } + + switch (PQresultStatus(r)) + { + case PGRES_COMMAND_OK: + case PGRES_TUPLES_OK: + case PGRES_EMPTY_QUERY: + break; + + default: + { + PQseterror("PGresult: %s", PQresultErrorMessage(r)); + PQclear(r); + r = NULL; + break; + } + } + + return r; +} + +/* Using the param is preferred when both conn and param are provided. + * The conn is there in case the exec has no parameters, NULL param. + */ +static const char * +getCommand(PGconn *conn, PGparam *param, const char *command) +{ + PGtypeSpec *spec; + int typspeccnt = 0; + PGtypeSpec *typspecs = NULL; + + if (!command) + { + PQseterror("command to execute cannot be NULL"); + return NULL; + } + + if (*command != '@') + return command; + + if (param) + { + typspecs = param->typspecs; + typspeccnt = param->typspeccnt; + } + + /* Try to get instance data from the conn */ + if (!typspecs || typspeccnt == 0) + { + PGtypeData *data = PQinstanceData(conn, pqt_eventproc); + + if (!data) + { + PQseterror("PGconn at %p has no event data", conn); + return NULL; + } + + typspecs = data->typspecs; + typspeccnt = data->typspeccnt; + } + + spec = pqt_getspec(typspecs, typspeccnt, command + 1); + + /* If we didn't find a type spec, this is an error. A format string + * with an '@' as its first character is reserved. + */ + if (!spec) + { + PQseterror("No such prepared specifier name: '%s'", command + 1); + return NULL; + } + + /* make sure type spec was prepared with a statement */ + if (!spec->stmt || !*spec->stmt) + { + PQseterror("Prepared specifier name '%s' has no statement", command + 1); + return NULL; + } + + return (const char *) spec->stmt; +} + + diff --git a/source/src/geo.c b/source/src/geo.c new file mode 100644 index 0000000..7beecf2 --- /dev/null +++ b/source/src/geo.c @@ -0,0 +1,391 @@ + +/* + * geo.c + * Type handler for the geometric data types. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +static int text2point(PGpoint *pt, char *text, char **endptr); +static int text2points(PGtypeArgs *args, PGpoint **pts, int *npts); +static int bin2points(PGtypeArgs *args, char *valp, int ptcnt, + PGpoint **pts, int *npts); +static int putpoints(PGtypeArgs *args, int npts, PGpoint *pts, + int is_path, int closed); + +int +pqt_put_point(PGtypeArgs *args) +{ + unsigned int *buf; + PGpoint *pt = va_arg(args->ap, PGpoint *); + + PUTNULLCHK(args, pt); + + buf = (unsigned int *) args->put.out; + pqt_swap8(buf, &pt->x, 1); + pqt_swap8(buf + 2, &pt->y, 1); + return 16; +} + +int +pqt_get_point(PGtypeArgs *args) +{ + DECLVALUE(args); + PGpoint *pt = va_arg(args->ap, PGpoint *); + + CHKGETVALS(args, pt); + + if (args->format == TEXTFMT) + { + if (!text2point(pt, value, NULL)) + RERR_STR2INT(args); + + return 0; + } + + pqt_swap8(&pt->x, (unsigned int *) value, 0); + pqt_swap8(&pt->y, ((unsigned int *) (value)) + 2, 0); + return 0; +} + +int +pqt_put_lseg(PGtypeArgs *args) +{ + unsigned int *buf; + PGlseg *lseg = va_arg(args->ap, PGlseg *); + + PUTNULLCHK(args, lseg); + + buf = (unsigned int *) args->put.out; + pqt_swap8(buf, &lseg->pts[0].x, 1); + pqt_swap8(buf + 2, &lseg->pts[0].y, 1); + pqt_swap8(buf + 4, &lseg->pts[1].x, 1); + pqt_swap8(buf + 6, &lseg->pts[1].y, 1); + return 32; +} + +int +pqt_get_lseg(PGtypeArgs *args) +{ + DECLVALUE(args); + unsigned int *v; + PGlseg *lseg = va_arg(args->ap, PGlseg *); + + CHKGETVALS(args, lseg); + + if (args->format == TEXTFMT) + { + PGpoint *pts = (PGpoint *)lseg; + + if (*value++ != '[' || + !text2point(pts, value, &value) || + *value++ != ',' || + !text2point(pts + 1, value, &value) || + *value != ']') + RERR_STR2INT(args); + + return 0; + } + + v = (unsigned int *) value; + pqt_swap8(&lseg->pts[0].x, v, 0); + pqt_swap8(&lseg->pts[0].y, v + 2, 0); + pqt_swap8(&lseg->pts[1].x, v + 4, 0); + pqt_swap8(&lseg->pts[1].y, v + 6, 0); + return 0; +} + +int +pqt_put_box(PGtypeArgs *args) +{ + unsigned int *buf; + PGbox *box = va_arg(args->ap, PGbox *); + + PUTNULLCHK(args, box); + + buf = (unsigned int *) args->put.out; + pqt_swap8(buf, &box->high.x, 1); + pqt_swap8(buf + 2, &box->high.y, 1); + pqt_swap8(buf + 4, &box->low.x, 1); + pqt_swap8(buf + 6, &box->low.y, 1); + return 32; +} + +int +pqt_get_box(PGtypeArgs *args) +{ + DECLVALUE(args); + unsigned int *v; + PGbox *box = va_arg(args->ap, PGbox *); + + CHKGETVALS(args, box); + + if (args->format == TEXTFMT) + { + PGpoint *pts = (PGpoint *)box; + + if (!text2point(pts, value, &value) || + *value++ != ',' || + !text2point(pts + 1, value, NULL)) + RERR_STR2INT(args); + + return 0; + } + + v = (unsigned int *) value; + pqt_swap8(&box->high.x, v, 0); + pqt_swap8(&box->high.y, v + 2, 0); + pqt_swap8(&box->low.x, v + 4, 0); + pqt_swap8(&box->low.y, v + 6, 0); + return 0; +} + +int +pqt_put_circle(PGtypeArgs *args) +{ + unsigned int *buf; + PGcircle *circle = va_arg(args->ap, PGcircle *); + + PUTNULLCHK(args, circle); + + buf = (unsigned int *) args->put.out; + pqt_swap8(buf, &circle->center.x, 1); + pqt_swap8(buf + 2, &circle->center.y, 1); + pqt_swap8(buf + 4, &circle->radius, 1); + return 24; +} + +int +pqt_get_circle(PGtypeArgs *args) +{ + DECLVALUE(args); + unsigned int *v; + PGcircle *circle = va_arg(args->ap, PGcircle *); + + CHKGETVALS(args, circle); + + if (args->format == TEXTFMT) + { + if (*value++ != '<' || + !text2point((PGpoint *)circle, value, &value) || + *value++ != ',' || + !pqt_text_to_float8(&circle->radius, value, &value) || + *value != '>') + RERR_STR2INT(args); + + return 0; + } + + v = (unsigned int *) value; + pqt_swap8(&circle->center.x, v, 0); + pqt_swap8(&circle->center.y, v + 2, 0); + pqt_swap8(&circle->radius, v + 4, 0); + return 0; +} + +int +pqt_put_path(PGtypeArgs *args) +{ + PGpath *path = va_arg(args->ap, PGpath *); + PUTNULLCHK(args, path); + return putpoints(args, path->npts, path->pts, 1, path->closed ? 1 : 0); +} + +int +pqt_get_path(PGtypeArgs *args) +{ + DECLVALUE(args); + PGpath *path = va_arg(args->ap, PGpath *); + + CHKGETVALS(args, path); + + if (args->format == TEXTFMT) + { + path->closed = *value == '(' ? 1 : 0; + return text2points(args, &path->pts, &path->npts); + } + + path->closed = *value ? 1 : 0; + value++; + + return bin2points(args, + value + sizeof(int), /* beginning of point array */ + pqt_buf_getint4(value), /* number of points */ + &path->pts, &path->npts); +} + +int +pqt_put_polygon(PGtypeArgs *args) +{ + PGpolygon *polygon = va_arg(args->ap, PGpolygon *); + PUTNULLCHK(args, polygon); + return putpoints(args, polygon->npts, polygon->pts, 0, 0); +} + +int +pqt_get_polygon(PGtypeArgs *args) +{ + DECLVALUE(args); + PGpolygon *polygon = va_arg(args->ap, PGpolygon *); + + CHKGETVALS(args, polygon); + + if (args->format == TEXTFMT) + return text2points(args, &polygon->pts, &polygon->npts); + + return bin2points(args, + value + sizeof(int), /* beginning of point array */ + pqt_buf_getint4(value), /* number of points */ + &polygon->pts, + &polygon->npts); +} + + +static int +putpoints(PGtypeArgs *args, int npts, PGpoint *pts, + int is_path, int closed) +{ + int i; + int datal; + int hdr = (int) sizeof(int); + char *out; + + /* pts is for a path, include 1 byte open/closed flag */ + if (is_path) + hdr++; + + /* length of binary formated path */ + datal = (npts * sizeof(PGpoint)) + hdr; + + /* make sure out is large enough */ + if (args->put.expandBuffer(args, datal) == -1) + return -1; + + out = args->put.out; + if (is_path) + *out++ = closed ? 1 : 0; /* path open/closed flag */ + + /* write the number of points as an int32 */ + pqt_buf_putint4(out, npts); + out += 4; + + /* assign points to the data 'out' buffer */ + for (i=0; i < npts; i++) + { + pqt_swap8(out, &pts[i].x, 1); + out += sizeof(double); + + pqt_swap8(out, &pts[i].y, 1); + out += sizeof(double); + } + + return datal; +} + +static int +text2points(PGtypeArgs *args, PGpoint **pts, int *npts) +{ + DECLVALUE(args); + char *s; + int cnt = 0; + PGpoint *p = NULL; + + *pts = NULL; + *npts = 0; + + if (*value != '(' && *value != '[') + RERR(args, "malformed point array"); + + /* get the number of points by counting the '(' */ + for (s=value+1; *s; s++) + { + if (*s == '(') + { + if (!(s = strchr(s, ')'))) /* skip point contents */ + break; + cnt++; + } + } + + if (cnt == 0) + return 0; /* empty point list */ + + p = (PGpoint *) PQresultAlloc((PGresult *) args->get.result, + cnt * sizeof(PGpoint)); + if (!p) + RERR_MEM(args); + + for (cnt=0; *++value; ) + { + if (!text2point(&p[cnt++], value, &value)) + RERR_STR2INT(args); + + /* done */ + if (*value != ',') + break; + } + + *pts = p; + *npts = cnt; + return 0; +} + +static int +bin2points(PGtypeArgs *args, char *valp, int ptcnt, + PGpoint **pts, int *npts) +{ + int i; + PGpoint *p; + + *pts = NULL; + *npts = 0; + + if (ptcnt == 0) + return 0; + + p = (PGpoint *) PQresultAlloc((PGresult *) args->get.result, + ptcnt * sizeof(PGpoint)); + + if (!p) + RERR_MEM(args); + + for (i=0; i < ptcnt; i++) + { + pqt_swap8(&p[i].x, valp, 0); + valp += sizeof(double); + + pqt_swap8(&p[i].y, valp, 0); + valp += sizeof(double); + } + + *pts = p; + *npts = ptcnt; + return 0; +} + +static int +text2point(PGpoint *pt, char *text, char **endptr) +{ + if (*text++ != '(') + return 0; + + if (!pqt_text_to_float8(&pt->x, text, &text) || *text++ != ',') + return 0; + + if (!pqt_text_to_float8(&pt->y, text, &text) || *text++ != ')') + return 0; + + if (endptr) + *endptr = text; + return 1; +} + + + + + diff --git a/source/src/getaddrinfo.h b/source/src/getaddrinfo.h new file mode 100644 index 0000000..6814db4 --- /dev/null +++ b/source/src/getaddrinfo.h @@ -0,0 +1,146 @@ + +/* + * Copyright (c) 2003-2008, PostgreSQL Global Development Group + * $PostgreSQL: pgsql/src/include/getaddrinfo.h + */ + +#if defined(__CYGWIN__) || (defined(HAVE_CONFIG_H) && \ + !defined(HAVE_GETADDRINFO)) + +#ifndef GETADDRINFO_H +#define GETADDRINFO_H + +#include +#define _XOPEN_SOURCE_EXTENDED 1 +#include + + +/* Various macros that ought to be in , but might not be */ + +#ifndef EAI_FAIL +#define EAI_BADFLAGS (-1) +#define EAI_NONAME (-2) +#define EAI_AGAIN (-3) +#define EAI_FAIL (-4) +#define EAI_FAMILY (-6) +#define EAI_SOCKTYPE (-7) +#define EAI_SERVICE (-8) +#define EAI_MEMORY (-10) +#define EAI_SYSTEM (-11) +#endif /* !EAI_FAIL */ + +#ifndef AI_PASSIVE +#define AI_PASSIVE 0x0001 +#endif + +#ifndef AI_NUMERICHOST +/* + * some platforms don't support AI_NUMERICHOST; define as zero if using + * the system version of getaddrinfo... + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_NUMERICHOST 0 +#else +#define AI_NUMERICHOST 0x0004 +#endif +#endif + +#ifndef NI_NUMERICHOST +#define NI_NUMERICHOST 1 +#endif +#ifndef NI_NUMERICSERV +#define NI_NUMERICSERV 2 +#endif + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY +#define ss_family __ss_family +#else +#error struct sockaddr_storage does not provide an ss_family member +#endif +#endif + +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN +#define ss_len __ss_len +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 +#endif +#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +/* Define a struct sockaddr_storage if we don't have one. */ + +#ifndef __CYGWIN__ +struct sockaddr_storage +{ + union + { + struct sockaddr sa; /* get the system-dependent fields */ + long long int ss_align; /* ensures struct is properly aligned */ + char ss_pad[128]; /* ensures struct has desired size */ + } ss_stuff; +}; +#endif + +#define ss_family ss_stuff.sa.sa_family +/* It should have an ss_len field if sockaddr has sa_len. */ +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN +#define ss_len ss_stuff.sa.sa_len +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 +#endif +#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef HAVE_STRUCT_ADDRINFO + +struct addrinfo +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; +}; + +#endif /* HAVE_STRUCT_ADDRINFO */ + + + +/* Rename private copies per comments above */ +#ifdef getaddrinfo +#undef getaddrinfo +#endif + +#ifdef freeaddrinfo +#undef freeaddrinfo +#endif + +#ifdef gai_strerror +#undef gai_strerror +#endif + +#ifdef getnameinfo +#undef getnameinfo +#endif + +extern int getaddrinfo(const char *node, const char *service, + const struct addrinfo * hints, struct addrinfo ** res); +extern void freeaddrinfo(struct addrinfo * res); +extern const char *gai_strerror(int errcode); +extern int getnameinfo(const struct sockaddr * sa, int salen, + char *node, int nodelen, + char *service, int servicelen, int flags); + +#endif /* GETADDRINFO_H */ + +#endif /* HAVE_GETADDRINFO */ + diff --git a/source/src/handler.c b/source/src/handler.c new file mode 100644 index 0000000..8d908ad --- /dev/null +++ b/source/src/handler.c @@ -0,0 +1,1077 @@ + +/* + * handler.c + * Type handler management functions, the core of the handler system. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +/* ------------------------- + * Built-in handler defaults: + * base_id, nattrs, freeAttDescs, attDescsBuf, attDescs + */ +#define __HANDLER_DEFAULTS__ -1, 0, 0, {{0}}, NULL + +/* id, schema, typname, typlen, oid, arroid, typput, typget, defaults */ +static PGtypeHandler pg_handlers[] = { + /* character types */ + {0, "pg_catalog", "char", 1, CHAROID, 1002, pqt_put_char, + pqt_get_char, __HANDLER_DEFAULTS__}, + {1, "pg_catalog", "varchar", -1, VARCHAROID, 1015, pqt_put_text, + pqt_get_text, __HANDLER_DEFAULTS__}, /* supports ptr */ + {2, "pg_catalog", "bpchar", -1, BPCHAROID, 1014, pqt_put_text, + pqt_get_text, __HANDLER_DEFAULTS__}, /* supports ptr */ + {3, "pg_catalog", "text", -1, TEXTOID, 1009, pqt_put_text, + pqt_get_text, __HANDLER_DEFAULTS__}, /* supports ptr */ + + /* boolean types */ + {4, "pg_catalog", "bool", 1, BOOLOID, 1000, pqt_put_bool, + pqt_get_bool, __HANDLER_DEFAULTS__}, + + /* numeric types */ + {5, "pg_catalog", "int2", 2, INT2OID, 1005, pqt_put_int2, + pqt_get_int2, __HANDLER_DEFAULTS__}, + {6, "pg_catalog", "int4", 4, INT4OID, 1007, pqt_put_int4, + pqt_get_int4, __HANDLER_DEFAULTS__}, + {7, "pg_catalog", "int8", 8, INT8OID, 1016, pqt_put_int8, + pqt_get_int8, __HANDLER_DEFAULTS__}, + {8, "pg_catalog", "float4", 4, FLOAT4OID, 1021, pqt_put_float4, + pqt_get_float4, __HANDLER_DEFAULTS__}, + {9, "pg_catalog", "float8", 8, FLOAT8OID, 1022, pqt_put_float8, + pqt_get_float8, __HANDLER_DEFAULTS__}, + {10, "pg_catalog", "numeric", -1, NUMERICOID, 1231, pqt_put_numeric, + pqt_get_numeric, __HANDLER_DEFAULTS__}, + + /* bytea types */ + {11, "pg_catalog", "bytea", -1, BYTEAOID, 1001, pqt_put_bytea, + pqt_get_bytea, __HANDLER_DEFAULTS__}, /* supports ptr */ + + /* geometric types */ + {12, "pg_catalog", "point", 16, POINTOID, 1017, pqt_put_point, + pqt_get_point, __HANDLER_DEFAULTS__}, + {13, "pg_catalog", "lseg", 32, LSEGOID, 1018, pqt_put_lseg, + pqt_get_lseg, __HANDLER_DEFAULTS__}, + {14, "pg_catalog", "box", 32, BOXOID, 1020, pqt_put_box, + pqt_get_box, __HANDLER_DEFAULTS__}, + {15, "pg_catalog", "circle", 24, CIRCLEOID, 719, pqt_put_circle, + pqt_get_circle, __HANDLER_DEFAULTS__}, + {16, "pg_catalog", "path", -1, PATHOID, 1019, pqt_put_path, + pqt_get_path, __HANDLER_DEFAULTS__}, + {17, "pg_catalog", "polygon", -1, POLYGONOID, 1027, pqt_put_polygon, + pqt_get_polygon, __HANDLER_DEFAULTS__}, + + /* monetary types */ + {18, "pg_catalog", "money", 8, CASHOID, 791, pqt_put_money, + pqt_get_money, __HANDLER_DEFAULTS__}, + + /* network address typess */ + {19, "pg_catalog", "inet", -1, INETOID, 1041, pqt_put_inet, + pqt_get_inet, __HANDLER_DEFAULTS__}, + {20, "pg_catalog", "cidr", -1, CIDROID, 651, pqt_put_inet, + pqt_get_cidr, __HANDLER_DEFAULTS__}, + {21, "pg_catalog", "macaddr", 6, MACADDROID, 1040, pqt_put_macaddr, + pqt_get_macaddr, __HANDLER_DEFAULTS__}, + + /* date & time types */ + {22, "pg_catalog", "time", 8, TIMEOID, 1183, pqt_put_time, + pqt_get_time, __HANDLER_DEFAULTS__}, + {23, "pg_catalog", "timetz", 12, TIMETZOID, 1270, pqt_put_timetz, + pqt_get_timetz, __HANDLER_DEFAULTS__}, + {24, "pg_catalog", "date", 4, DATEOID, 1182, pqt_put_date, + pqt_get_date, __HANDLER_DEFAULTS__}, + {25, "pg_catalog", "timestamp", 8, TIMESTAMPOID, 1115, pqt_put_timestamp, + pqt_get_timestamp, __HANDLER_DEFAULTS__}, + {26, "pg_catalog", "timestamptz", 8, TIMESTAMPTZOID, 1185, + pqt_put_timestamptz, pqt_get_timestamptz, __HANDLER_DEFAULTS__}, + {27, "pg_catalog", "interval", 16, INTERVALOID, 1187, pqt_put_interval, + pqt_get_interval, __HANDLER_DEFAULTS__}, + + /* object identifier types */ + {28, "pg_catalog", "oid", 4, OIDOID, 1028, pqt_put_int4, + pqt_get_int4, __HANDLER_DEFAULTS__}, + + /* UUID types */ + {29, "pg_catalog", "uuid", 16, UUIDOID, 2951, pqt_put_uuid, + pqt_get_uuid, __HANDLER_DEFAULTS__}, + + /* Record types (composites) */ + {30, "pg_catalog", "record", -1, RECORDOID, 0, pqt_put_record, + pqt_get_record, __HANDLER_DEFAULTS__}, + + /* pqt types */ + {31, "pqt", "str", -1, InvalidOid, 0, pqt_put_str, + NULL, __HANDLER_DEFAULTS__}, /* supports ptr */ + {32, "pqt", "null", -1, InvalidOid, 0, pqt_put_null, + NULL, __HANDLER_DEFAULTS__}, + + /* more character types */ + {33, "pg_catalog", "name", -1, NAMEOID, 1003, pqt_put_text, + pqt_get_text, __HANDLER_DEFAULTS__} /* supports ptr */ +}; + +static int +expandHandlers(PGtypeData *typeData); + +static PGrecordAttDesc * +initAttDescs(PGtypeHandler *h, char *attrs); + +static char * +parseType(const char *spec, char *schema, char *typname, int typpos); + +static int +getTypeParams(PGconn *conn, PGregisterType *types, int count, + PGarray *names, PGarray *schemas); + +static int +checkTypeLookups(PGresult *res, PGregisterType *types, int count); + +/* If res is NULL, non-blocking send is used, otherwise a blocking + * exec is issued and *res contains the result. Returns zero on + * error and non-zero on success. + */ +static int +performRegisterQuery(PGconn *conn, int which, PGregisterType *types, + int count, PGresult **res); + +/* Called by PQregisterTypes() for each type provided. */ +static int +registerSubClass(PGtypeData *connData, const char *type_name, + PGtypeProc typput, PGtypeProc typget); + +int +PQinitTypes(PGconn *conn) +{ + return PQregisterEventProc(conn, pqt_eventproc, "pqtypes", NULL); +} + +/* Deprecated */ +int +PQregisterSubClasses(PGconn *conn, PGregisterType *types, int count) +{ + return PQregisterTypes(conn, PQT_SUBCLASS, types, count, 0); +} + +/* Deprecated */ +int +PQregisterUserDefinedTypes(PGconn *conn, PGregisterType *types, int count) +{ + return PQregisterTypes(conn, PQT_USERDEFINED, types, count, 0); +} + +/* Deprecated */ +int +PQregisterComposites(PGconn *conn, PGregisterType *types, int count) +{ + return PQregisterTypes(conn, PQT_COMPOSITE, types, count, 0); +} + +int +PQregisterTypes(PGconn *conn, int which, PGregisterType *types, + int count, int async) +{ + int n = FALSE; + + PQseterror(NULL); + + if (!conn) + { + PQseterror("PGconn cannot be NULL"); + return FALSE; + } + + if (!types) + { + PQseterror("PGregisterType[] cannot be NULL"); + return FALSE; + } + + if (count < 0) + { + PQseterror("PGregisterType[] count cannot be less than zero"); + return FALSE; + } + + /* nothing to do, silently ignore it */ + if (count == 0) + return TRUE; + + if (which == PQT_SUBCLASS) + { + int i; + PGtypeData *connData; + + if (!(connData = (PGtypeData *) PQinstanceData(conn, pqt_eventproc))) + { + PQseterror("PGconn is missing event data"); + return FALSE; + } + + for (i=0; i < count; i++) + { + n = registerSubClass(connData, types[i].typname, + types[i].typput, types[i].typget); + + if (!n) + return FALSE; + } + } + else + { + PGresult *res = NULL; + + n = performRegisterQuery(conn, which, types, count, async ? NULL : &res); + + /* If not async, register the result and clear it. */ + if (n && !async) + { + n = PQregisterResult(conn, which, types, count, res); + PQclear(res); + } + } + + return n; +} + +int +PQregisterResult(PGconn *conn, int which, PGregisterType *types, + int count, PGresult *res) +{ + int i; + PGtypeData *connData; + char typname[PQT_MAXIDLEN + 1]; + char typschema[PQT_MAXIDLEN + 1]; + /* inherit typput and typget from record type */ + PGtypeHandler *h_rec = pqt_gethandler(NULL, 0, "pg_catalog", "record"); + + PQseterror(NULL); + + if (!conn) + { + PQseterror("PGconn cannot be NULL"); + return FALSE; + } + + if (!res) + { + PQseterror("PGresult cannot be NULL"); + return FALSE; + } + + if (which == PQT_SUBCLASS) + { + PQseterror("Cannot call PQregisterResult for a subclass registration."); + return FALSE; + } + + if (!(connData = (PGtypeData *) PQinstanceData(conn, pqt_eventproc))) + { + PQseterror("PGconn is missing event data"); + return FALSE; + } + + if (!types) + { + PQseterror("PGregisterType[] cannot be NULL"); + return FALSE; + } + + if (count < 0) + { + PQseterror("PGregisterType[] count cannot be less than zero"); + return FALSE; + } + + if(!checkTypeLookups(res, types, count)) + return FALSE; + + for (i=0; i < PQntuples(res); i++) + { + int flags; + PGint2 typlen; + PGtypeHandler *h; + + if (which == PQT_USERDEFINED && !types[i].typput && !types[i].typget) + { + PQseterror("Must provide a put and/or a get routine: '%s'", + types[i].typname); + return FALSE; + } + + /* make sure conn's type handlers array is large enough */ + if (!expandHandlers(connData)) + return FALSE; + + /* create the handler */ + h = &connData->typhandlers[connData->typhcnt]; + memset(h, 0, sizeof(PGtypeHandler)); + + if (!PQgetf(res, i, "%oid %oid %int2", 1, &h->typoid, + 2, &h->typoid_array, 3, &typlen)) + { + return FALSE; + } + + h->id = connData->typhcnt + countof(pg_handlers); + h->typlen = (int) typlen; + h->base_id = -1; + + if (which == PQT_USERDEFINED) + { + h->typput = types[i].typput; + h->typget = types[i].typget; + } + else + { + h->typput = h_rec->typput; + h->typget = h_rec->typget; + } + + /* parse out type and schema names again */ + (void ) pqt_parsetype(types[i].typname, typschema, typname, &flags, 1); + pqt_strcpy(h->typschema, sizeof(h->typschema), typschema); + pqt_strcpy(h->typname, sizeof(h->typname), typname); + + /* Process composite attributes */ + if(which == PQT_COMPOSITE) + { + PGtext attrs; + int nattrs; + PGrecordAttDesc *attDescs; + + if (!PQgetf(res, i, "%text", 4, &attrs)) + { + return FALSE; + } + + if (!(attDescs = initAttDescs(h, attrs))) + return FALSE; + + for (nattrs=0; *attrs; nattrs++) + { + char *p; + char *name; + int len; + + /* Attribute Text Encoding: + * "attoid,attlen,atttypmod,name_hex attoid,etc..." + */ + + attDescs[nattrs].attoid = (int) strtol(attrs, &attrs, 10); + attDescs[nattrs].attlen = (int) strtol(attrs + 1, &attrs, 10); + attDescs[nattrs].atttypmod = (int) strtol(attrs + 1, &attrs, 10); + + /* skip comma before name */ + attrs++; + + /* attribute name in hex */ + if (!(p = strchr(attrs, ' '))) + p = attrs + strlen(attrs); /* last attr, point at NUL */ + + /* truncate name if it exceeds buffer */ + len = (int) (p - attrs); + if (len >= (int) sizeof(attDescs[nattrs].attname)) + len = (int) (sizeof(attDescs[nattrs].attname) - 1); + + /* hex decode and copy */ + for (name = attDescs[nattrs].attname; attrs < p; attrs += 2) + *name++ = (char) (pqt_hex_to_dec(attrs[0]) << 4) + | pqt_hex_to_dec(attrs[1]); + *name = 0; + } + + h->nattrs = nattrs; + h->attDescs = attDescs; + } + + connData->typhcnt++; + } + + return TRUE; +} + +int +PQclearTypes(PGconn *conn) +{ + PGtypeData *connData; + + if (!conn) + { + PQseterror("PGconn cannot be NULL"); + return FALSE; + } + + if (!(connData = (PGtypeData *) PQinstanceData(conn, pqt_eventproc))) + { + PQseterror("PGconn is missing event data"); + return FALSE; + } + + pqt_cleartypes(connData); + + return TRUE; +} + +/* Do not call when hcnt is 0. This returns NULL when malloc fails. + * Passing in 0 could only do the same thing (ambiguos), so it is simply + * not handled and may dump core. + */ +PGtypeHandler * +pqt_duphandlers(PGtypeHandler *handlers, int hcnt) +{ + int i; + PGtypeHandler *h = (PGtypeHandler *) malloc(hcnt * sizeof(PGtypeHandler)); + + if (!h) + return NULL; + + /* In the most common cases, this is the total cost of the dup. + * Previously, the handler had 4 inner strings that required a deep + * copy. Surprisingly, this had a noticeable overhead. This was + * solved by using fixed length buffers in the type handler struct. + * Also, a fixed length attDescs buffer was added to avoid having + * to perform a deep copy for the common cases, 16 or less attrs. + */ + memcpy(h, handlers, hcnt * sizeof(PGtypeHandler)); + + /* Possibly deep copy PGrecordAttDesc array. Otherwise, assign it + * to the fixed length buffer. + */ + for (i=0; i < hcnt; i++) + { + if (h[i].nattrs == 0) + continue; + + /* There are attributes but the attDescs buffer can be used rather + * than allocating and copying. The data was copied during the + * handlers memcpy prior to this loop. + */ + if (!h[i].freeAttDescs) + { + h[i].attDescs = h[i].attDescsBuf; + continue; + } + + /* ------------------------------ + * Must allocate and copy. + */ + + h[i].attDescs = (PGrecordAttDesc *) malloc( + h[i].nattrs * sizeof(PGrecordAttDesc)); + + if (!h[i].attDescs) + { + pqt_freehandlers(h, i+1); + return NULL; + } + + memcpy(h[i].attDescs, handlers[i].attDescs, + h[i].nattrs * sizeof(PGrecordAttDesc)); + } + + return h; +} + +void +pqt_cleartypes(PGtypeData *typeData) +{ + if (typeData) + { + pqt_freehandlers(typeData->typhandlers, typeData->typhcnt); + + typeData->typhandlers = NULL; + typeData->typhcnt = 0; + typeData->typhmax = 0; + } +} + +void +pqt_freehandlers(PGtypeHandler *handlers, int hcnt) +{ + int i; + + /* Free attDescs */ + for (i=0; i < hcnt; i++) + if (handlers[i].freeAttDescs && handlers[i].attDescs) + free(handlers[i].attDescs); + + if (handlers) + free(handlers); +} + +PGtypeHandler * +pqt_gethandler(PGtypeHandler *handlers, int hcnt, + const char *schema, const char *typname) +{ + int i; + int noschema = !schema || !*schema; + + if (!typname || !*typname) + return NULL; + + /* user registered types are searched first */ + for (i=0; i < hcnt; i++) + { + if ((noschema || strcmp(handlers[i].typschema, schema)==0) && + strcmp(handlers[i].typname, typname)==0) + { + return &handlers[i]; + } + } + + /* builtin types searched last */ + for (i=0; i < countof(pg_handlers); i++) + { + if ((noschema || strcmp(pg_handlers[i].typschema, schema)==0) && + strcmp(pg_handlers[i].typname, typname)==0) + { + return &pg_handlers[i]; + } + } + + return NULL; +} + +PGtypeHandler * +pqt_gethandlerbyid(PGtypeHandler *handlers, int hcnt, int id) +{ + if (id <= -1) + return NULL; + + if (id < countof(pg_handlers)) + return &pg_handlers[id]; + + id -= countof(pg_handlers); + if (id >= hcnt) + return NULL; + + return &handlers[id]; +} + +int +pqt_argssuper(PGtypeArgs *args, ...) +{ + int r; + va_list ap; + PGtypeHandler *baseclass; + PGtypeHandler *subclass = args->typhandler; + PGtypeData *resData = NULL; + + if (!args->is_put) + { + resData = (PGtypeData *) PQresultInstanceData( + args->get.result, pqt_eventproc); + + if (!resData) + return args->errorf(args, "PGresult is missing event data"); + } + + /* should always work, but play it safe */ + baseclass = pqt_gethandlerbyid( + args->is_put ? args->put.param->typhandlers : resData->typhandlers, + args->is_put ? args->put.param->typhcnt : resData->typhcnt, + subclass->base_id); + + if (!baseclass) + return args->errorf(args, "type handler has no base type"); + + args->typhandler = baseclass; + + va_copy(ap, args->ap); + va_start(args->ap, args); + r = args->is_put ? baseclass->typput(args) : baseclass->typget(args); + va_copy(args->ap, ap); + + args->typhandler = subclass; + return r; +} + +/* FQTN standards for Fully Qualified Type Name. Returns a pointer to out. + * Only returns NULL if out is NULL or outl <= 0. + */ +char * +pqt_fqtn(char *out, size_t outl, const char *schema, const char *typname) +{ + int r; + int have_schema = schema && *schema; + + if (!out || outl<=0) + return NULL; + + *out = 0; + if (!typname || !*typname) + return out; + + r = pqt_snprintf(out, outl, "%s%s%s", have_schema ? schema : "", + have_schema ? "." : "", typname); + + if (r < 0) + { + *out = 0; + return out; + } + + return out; +} + +/* only checks builin types or pqt types. User registered types must + * be checked by the user's handler functions. + */ +int +pqt_allowsptr(PGtypeHandler *h) +{ + /* pg_catalog.[bpchar, varchar, name, text, bytea] */ + if (strcmp(h->typschema, "pg_catalog")==0) + { + if (strcmp(h->typname, "bpchar") && + strcmp(h->typname, "varchar") && + strcmp(h->typname, "text") && + strcmp(h->typname, "bytea") && + strcmp(h->typname, "name")) + { + return FALSE; + } + } + /* pqt.str */ + else if (strcmp(h->typschema, "pqt")==0 && strcmp(h->typname, "str")) + { + return FALSE; + } + + return TRUE; +} + +void +pqt_getfmtinfo(const PGconn *conn, PGtypeFormatInfo *info) +{ + const char *value; + + memset(info, 0, sizeof(PGtypeFormatInfo)); + + if ((value = PQparameterStatus(conn, "DateStyle"))) + pqt_strcpy(info->datestyle, sizeof(info->datestyle), value); + + if ((value = PQparameterStatus(conn, "integer_datetimes"))) + info->integer_datetimes = strcmp(value, "on")==0 ? TRUE : FALSE; + + info->sversion = PQserverVersion(conn); + info->pversion = PQprotocolVersion(conn); +} + +static int registerSubClass(PGtypeData *connData, const char *type_name, + PGtypeProc typput, PGtypeProc typget) +{ + char *s; + PGtypeHandler *h_sub; + PGtypeHandler *h_base; + char sub_typschema[PQT_MAXIDLEN + 1]; + char sub_typname[PQT_MAXIDLEN + 1]; + char base_typschema[PQT_MAXIDLEN + 1]; + char base_typname[PQT_MAXIDLEN + 1]; + char sub_fqtn[200]; + char base_fqtn[200]; + + if (!(s = parseType(type_name, sub_typschema, sub_typname, 1))) + return FALSE; + + if (*s != '=') + { + PQseterror("Missing inheritence operator '=': %s", type_name); + return FALSE; + } + + if (!parseType(s + 1, base_typschema, base_typname, 1)) + return FALSE; + + /* lookup the base handler */ + h_base = pqt_gethandler(connData->typhandlers, connData->typhcnt, + base_typschema, base_typname); + + if (!h_base) + { + PQseterror("typname '%s' does not exist, '%s' cannot sub-class it", + pqt_fqtn(base_fqtn, sizeof(base_fqtn), base_typschema, base_typname), + pqt_fqtn(sub_fqtn, sizeof(sub_fqtn), sub_typschema, sub_typname)); + return FALSE; + } + + /* cannot sub-class a record type */ + if (h_base->typoid == RECORDOID) + { + PQseterror("Cannot sub-class pg_catalog.record '%s'", + pqt_fqtn(sub_fqtn, sizeof(sub_fqtn), sub_typschema, sub_typname)); + return FALSE; + } + + if (!expandHandlers(connData)) + return FALSE; + + h_sub = &connData->typhandlers[connData->typhcnt]; + memset(h_sub, 0, sizeof(PGtypeHandler)); + + h_sub->id = connData->typhcnt + countof(pg_handlers); + h_sub->typlen = h_base->typlen; + h_sub->typoid = h_base->typoid; + h_sub->typoid_array = h_base->typoid_array; + h_sub->typput = typput; + h_sub->typget = typget; + h_sub->base_id = h_base->id; + + pqt_strcpy(h_sub->typschema, + sizeof(h_sub->typschema), sub_typschema); + + pqt_strcpy(h_sub->typname, + sizeof(h_sub->typname), sub_typname); + + connData->typhcnt++; + return TRUE; +} + +static int +expandHandlers(PGtypeData *typeData) +{ + int hmax; + PGtypeHandler *h; + + if (typeData->typhcnt < typeData->typhmax) + return TRUE; + + hmax = typeData->typhmax ? (typeData->typhmax * 3) / 2 : 8; + h = (PGtypeHandler *) pqt_realloc( + typeData->typhandlers, sizeof(PGtypeHandler) * hmax); + + if (!h) + { + PQseterror(PQT_OUTOFMEMORY); + return FALSE; + } + + typeData->typhandlers = h; + typeData->typhmax = hmax; + return TRUE; +} + +static int +checkTypeLookups(PGresult *res, PGregisterType *types, int count) +{ + int i; + int ntups = PQntuples(res); + + /* The tuple count must match the requested count. The server omits + * tuples for types it did not find. For those it did find, it returns + * a sequenctial index. The first gap found is our missing type. This + * only reports about the first missing type. + */ + if (ntups == count) + return TRUE; + + for (i=0; i < ntups; i++) + { + int idx; + + if (!PQgetf(res, i, "%int4", 0, &idx)) + return FALSE; + + /* 'i' should always match idx-1, postgresql arrays are 1-based. + * This is a missing type, first gap in the sequence. + */ + if (i != idx-1) + break; + } + + PQseterror("server type lookup failed: could not find '%s'", + types[i].typname); + + return FALSE; +} + +/* This is part of a performance enhancement for getting arrays + * and/or composites. They require generating PGresults which + * causes pqt_duphandlers() to run. Its amazing how much a simple + * malloc+memcpy costs after around 10000 or so. The common case + * avoids this by using a fixed length PGrecordAttDesc buffer. If + * there are a large number of attributes, the slower path is used. + * Again this is small, maybe 10% of the overall 63% win. + */ +static PGrecordAttDesc *initAttDescs(PGtypeHandler *h, char *attrs) +{ + char *p; + int nattrs = 1; + PGrecordAttDesc *attDescs; + + for(p = attrs; *p; nattrs++, ++p) + if(!(p = strchr(p, ' '))) + break; + + if (nattrs < (int) (sizeof(h->attDescsBuf) / sizeof(h->attDescsBuf[0]))) + { + h->freeAttDescs = 0; + attDescs = h->attDescsBuf; + } + else + { + attDescs = (PGrecordAttDesc *) malloc(nattrs * sizeof(PGrecordAttDesc)); + if (!attDescs) + { + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + h->freeAttDescs = 1; + } + + return attDescs; +} + +/* wraps pqt_parsetype to toggle out illegal flags during a register */ +static char *parseType(const char *spec, char *typschema, char *typname, + int typpos) +{ + char *s; + int flags; + + if (!(s = pqt_parsetype(spec, typschema, typname, &flags, typpos))) + return NULL; + + if (flags & TYPFLAG_INVALID) + return NULL; + + if (flags & TYPFLAG_ARRAY) + { + PQseterror("Cannot use an array[] during a type handler registration."); + return NULL; + } + + if (flags & TYPFLAG_POINTER) + { + PQseterror("Cannot use a type* during a type handler registration."); + return NULL; + } + + return s; +} + +static int getTypeParams(PGconn *conn, PGregisterType *types, int count, + PGarray *names, PGarray *schemas) +{ + int i; + + names->ndims = 0; + schemas->ndims = 0; + + if (!(names->param = PQparamCreate(conn))) + return FALSE; + + if (!(schemas->param = PQparamCreate(conn))) + { + PQparamClear(names->param); + return FALSE; + } + + for (i=0; i < count; i++) + { + char typname[PQT_MAXIDLEN + 1]; + char typschema[PQT_MAXIDLEN + 1]; + char *s = parseType(types[i].typname, typschema, typname, 1); + + if (!s) + { + PQparamClear(names->param); + PQparamClear(schemas->param); + return FALSE; + } + + s = *typschema ? typschema : NULL; + if (!PQputf(names->param, "%text", typname) || + !PQputf(schemas->param, "%text", s)) + { + PQparamClear(names->param); + PQparamClear(schemas->param); + return FALSE; + } + } + + return TRUE; +} + + + +/* Lookup types, including composites. Arguments are: + * schemas text[], type_names text[], want_attrs bool + */ +#define LOOKUP_TYPES \ +"WITH nspnames AS" \ +"(" \ +" SELECT * FROM information_schema._pg_expandarray(%text[])" \ +")," \ +"typnames AS" \ +"(" \ +" SELECT * FROM information_schema._pg_expandarray(%text[])" \ +")," \ +"curpath AS" \ +"(" \ +" SELECT * FROM information_schema._pg_expandarray(current_schemas(true))" \ +")," \ +"composites AS" \ +"(" \ +" SELECT n.n AS idx, n.x AS nspname, t.x AS typname" \ +" FROM nspnames n LEFT JOIN typnames t ON n.n = t.n" \ +" AND n.x IS NOT NULL" \ +" WHERE t.x IS NOT NULL" \ +" UNION ALL" \ +" SELECT n.n AS idx," \ +" (" \ +" SELECT n.nspname from pg_type nt JOIN pg_namespace n ON " \ + "nt.typnamespace = n.oid" \ +" JOIN curpath c ON c.x = n.nspname" \ +" WHERE nt.typname = t.x" \ +" ORDER BY c.n LIMIT 1" \ +" ) AS nspname, t.x AS typname" \ +" FROM nspnames n LEFT JOIN typnames t ON n.n = t.n" \ +" AND n.x IS NULL" \ +" WHERE t.x IS NOT NULL" \ +")" \ +"SELECT idx, t.oid AS typoid, a.oid AS arroid, t.typlen," \ +" (" \ +" CASE WHEN %bool THEN (" \ +" SELECT array_to_string" \ +" (" \ +" ARRAY" \ +" (" \ +" SELECT CASE WHEN tt.typtype = 'd' THEN tt.typbasetype " \ + "ELSE a.atttypid END ||" \ +" ',' || attlen || ',' || atttypmod || ',' || " \ + "encode(attname::bytea, 'hex')" \ +" FROM pg_type b" \ +" JOIN pg_attribute a ON b.typrelid = a.attrelid" \ +" JOIN pg_type tt ON a.atttypid = tt.oid" \ +" WHERE b.oid = t.oid" \ +" AND a.attnum > 0" \ +" AND NOT a.attisdropped" \ +" ORDER BY a.attnum" \ +" ), ' ')" \ +" ) ELSE NULL END) AS arr_props" \ +" FROM composites c" \ +" JOIN pg_type t ON t.typname = c.typname" \ +" JOIN pg_namespace n ON t.typnamespace = n.oid AND n.nspname = c.nspname" \ +" JOIN pg_type a ON a.oid = t.typarray" \ +" ORDER BY idx;" + +/* Lookup types for pre 8.4 servers, including composites. Arguments are: + * want_attrs bool, schemas text[], type_names text[] + */ +#define LOOKUP_TYPES_PRE_8_4 \ +"SELECT idx, t.oid AS typoid, a.oid AS arroid, t.typlen," \ +" (" \ +" CASE WHEN %bool THEN (" \ +" SELECT array_to_string" \ +" (" \ +" ARRAY" \ +" (" \ +" SELECT CASE WHEN tt.typtype = 'd' THEN tt.typbasetype " \ + "ELSE a.atttypid END ||" \ +" ',' || attlen || ',' || atttypmod || ',' || " \ + "encode(attname::bytea, 'hex')" \ +" FROM pg_type b" \ +" JOIN pg_attribute a ON b.typrelid = a.attrelid" \ +" JOIN pg_type tt ON a.atttypid = tt.oid" \ +" WHERE b.oid = t.oid" \ +" AND a.attnum > 0" \ +" AND NOT a.attisdropped" \ +" ORDER BY a.attnum" \ +" ), ' ')" \ +" ) ELSE NULL END) AS arr_props" \ +" FROM" \ +" (" \ +" SELECT n.n AS idx, n.x AS nspname, t.x AS typname" \ +" FROM" \ +" (" \ +" SELECT * FROM information_schema._pg_expandarray(%text[])" \ +" ) n LEFT JOIN" \ +" (" \ +" SELECT * FROM information_schema._pg_expandarray(%text[])" \ +" ) t ON n.n = t.n" \ +" AND n.x IS NOT NULL" \ +" WHERE t.x IS NOT NULL" \ +" UNION ALL" \ +" SELECT n.n AS idx," \ +" (" \ +" SELECT n.nspname from pg_type nt JOIN pg_namespace n ON " \ + "nt.typnamespace = n.oid" \ +" JOIN" \ +" (" \ +" SELECT * FROM information_schema._pg_expandarray(" \ + "current_schemas(true))" \ +" ) c ON c.x = n.nspname" \ +" WHERE nt.typname = t.x" \ +" ORDER BY c.n LIMIT 1" \ +" ) AS nspname, t.x AS typname" \ +" FROM" \ +" (" \ +" SELECT * FROM information_schema._pg_expandarray($2)" \ +" ) n LEFT JOIN" \ +" (" \ +" SELECT * FROM information_schema._pg_expandarray($3)" \ +" ) t ON n.n = t.n" \ +" AND n.x IS NULL" \ +" WHERE t.x IS NOT NULL" \ +" ) c" \ +" JOIN pg_type t ON t.typname = c.typname" \ +" JOIN pg_namespace n ON t.typnamespace = n.oid AND n.nspname = c.nspname" \ +" JOIN pg_type a ON a.oid = t.typarray" \ +" ORDER BY idx" + +static PGresult * +execLookupTypes(PGconn *conn, PGtypeData *data, PGarray *schemas, + PGarray *names, int want_attrs) +{ + if(data->fmtinfo.sversion >= 80400) + return PQexecf(conn, LOOKUP_TYPES, schemas, names, want_attrs); + return PQexecf(conn, LOOKUP_TYPES_PRE_8_4, want_attrs, schemas, names); +} + +static int +sendLookupTypes(PGconn *conn, PGtypeData *data, PGarray *schemas, + PGarray *names, int want_attrs) +{ + if(data->fmtinfo.sversion >= 80400) + return PQsendf(conn, LOOKUP_TYPES, schemas, names, want_attrs); + return PQsendf(conn, LOOKUP_TYPES_PRE_8_4, want_attrs, schemas, names); +} + +static int +performRegisterQuery(PGconn *conn, int which, PGregisterType *types, + int count, PGresult **res) +{ + int n = FALSE; + PGtypeData *connData; + PGarray names; + PGarray schemas; + int want_attrs = which == PQT_COMPOSITE; + + if (!(connData = (PGtypeData *) PQinstanceData(conn, pqt_eventproc))) + { + PQseterror("PGconn is missing event data"); + return FALSE; + } + + if (!getTypeParams(conn, types, count, &names, &schemas)) + return FALSE; + + if (res) + *res = execLookupTypes(conn, connData, &schemas, &names, want_attrs); + else + n = sendLookupTypes(conn, connData, &schemas, &names, want_attrs); + + PQparamClear(names.param); + PQparamClear(schemas.param); + + if (res) + return *res ? TRUE : FALSE; + + return n; +} diff --git a/source/src/libpqtypes-int.h b/source/src/libpqtypes-int.h new file mode 100644 index 0000000..00faf93 --- /dev/null +++ b/source/src/libpqtypes-int.h @@ -0,0 +1,533 @@ + +/* + * libpqtypes-int.h + * Private header file for libpqtypes. All source files include + * this header. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef LIBPQTYPES_INT_H +#define LIBPQTYPES_INT_H + +#define PLN do{ \ + printf("%s:%d\n", __FUNCTION__, __LINE__); \ + fflush(stdout); \ +}while(0) + +#ifdef HAVE_CONFIG_H +# include "pqt_config.h" +#endif + +/* Using the windows compiler */ +#ifdef _MSC_VER +# define PQT_MSVC _MSC_VER +#endif + +/* We can/should use the Windows API */ +#if defined(PQT_MSVC) || defined(__MINGW32__) +# define PQT_WINAPI +#endif + +/* Compiling on a windows platform */ +#if defined(PQT_WINAPI) || defined(__CYGWIN__) +# define PQT_WIN32 +#endif + +/* WINAPI is available, include needed winsock headers */ +#ifdef PQT_WINAPI +# ifdef PQT_MSVC +# pragma warning (disable : 4706 4100 4711 4127 4702) +# pragma warning (disable: 4706 4100 4514 4710 4201 4206) +# endif +# include +# include +# include /* need for getaddrinfo (2000 and below */ +# include +#else +# if defined(__CYGWIN__) || defined(HAVE_SYS_TYPES_H) +# include +# endif +# if defined(__CYGWIN__) || defined(HAVE_SYS_SOCKET_H) +# include +# endif +# if defined(__CYGWIN__) || defined(HAVE_NETDB_H) +# include +# endif +# if defined(__CYGWIN__) || defined(HAVE_NETINET_IN_H) +# include +# endif +# if defined(__CYGWIN__) || defined(HAVE_ARPA_INET_H) +# include +# endif +#endif + +#include +#include +#include +#include + +/* string*.h, windows platforms just include string.h */ +#ifdef PQT_WIN32 +# include +#else +# ifdef HAVE_STRING_H +# include +# endif +# ifdef HAVE_STRINGS_H +# include +# endif +#endif + +/* Include stddef.h if on windows or if we have it */ +#if defined(PQT_WIN32) || defined(HAVE_STDDEF_H) +# include +#endif + +/* Include limits.h if on windows or if we have it */ +#if defined(PQT_WIN32) || defined(HAVE_LIMITS_H) +# include +#endif + +/* Include linux/limits.h if available */ +#if defined(HAVE_CONFIG_H) && defined(HAVE_LINUX_LIMITS_H) +# include +#endif + +/* Include math.h if on windows or if we have it */ +#if defined(PQT_WIN32) || defined(HAVE_MATH_H) +# include +#endif + +/* Include the public API, pulls in libpq-fe.h for us. */ +#include "libpqtypes.h" +#include "libpq-events.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TRUE +# define TRUE 1 +#endif + +#ifndef FALSE +# define FALSE 0 +#endif + +#ifndef NULL_LEN +# define NULL_LEN (-1) +#endif + +/* Win32 builds use _timezone and _tzname: manually define HAVE_TZNAME. */ +#ifdef PQT_WIN32 +# define HAVE_TZNAME +# define pqt_timezone _timezone +# define pqt_tzname _tzname +#else +# define pqt_timezone timezone +# define pqt_tzname tzname +#endif + +#define PQT_OUTOFMEMORY "Out of memory error" +#define PQT_MAXIDLEN 64 + +#define TEXTFMT 0 +#define BINARYFMT 1 +#define TYPFLAG_CASEFOLD 0x01 +#define TYPFLAG_ARRAY 0x02 +#define TYPFLAG_POINTER 0x04 +#define TYPFLAG_INVALID 0x08 +#define TYPFLAG_BYNAME 0x10 + +/* Avoid passing NULL to realloc, some systems don't support it */ +#define pqt_realloc(ptr, size) (ptr) ? realloc(ptr, size) : malloc(size) + +#define countof(array) (int) (sizeof(array) / sizeof(array[0])) + +/* MSVC 8 deprecated quite a few POSIX names */ +#if defined(PQT_MSVC) && PQT_MSVC >= 1400 +# undef strdup +# undef sscanf +# define strdup _strdup +# define sscanf sscanf_s +#endif + +/* define va_copy */ +#ifndef va_copy +# ifdef __va_copy +# define va_copy(dest, src) __va_copy(dest, src) +# else +# define va_copy(dest, src) (dest) = (src) +# endif +#endif + +#define pqt_hex_to_dec(v) \ + (unsigned char) (((v) > '9') ? ((v) - 'a') + 10 : (v) - '0') + +/* -------------------------------- + * Macros used by built-in handlers + */ + +/* used by get handlers */ +#define DECLLENGTH(args) \ + int valuel = PQgetlength((args)->get.result, (args)->get.tup_num, \ + (args)->get.field_num) + +/* used by get handlers */ +#define DECLVALUE(getargs) \ + char *value = PQgetvalue((getargs)->get.result, (getargs)->get.tup_num, \ + (getargs)->get.field_num) + +/* used by put handlers */ +#define PUTNULLCHK(args, valp) do{ \ + if (!(valp)) \ + return pqt_put_null(args); \ +}while (0) + +/* used by get handlers, checks for NULL pointers and PQgetisnull */ +#define CHKGETVALS(args, outp) do{ \ + if (!(outp)) \ + RERR(args, "output pointer is NULL"); \ + memset(outp, 0, sizeof(*(outp))); \ + if (PQgetisnull((args)->get.result, (args)->get.tup_num, \ + (args)->get.field_num)) \ + return 0; \ +}while (0) + +/* RERR for return error: errorf always returns -1 */ +#define RERR(_args, msg) return (_args)->errorf(_args, msg) +#define RERR_STR2INT(args) RERR(args, "String to integer conversion failed") +#define RERR_MEM(args) RERR(args, PQT_OUTOFMEMORY) + +#ifdef STRICT_MEMORY_ALIGNMENT +# define pqt_buf_putint2(_buffer, _val) do{ \ + short _v = (short) htons((short) (_val)); \ + memcpy(_buffer, &_v, sizeof(short)); \ + } while (0) + +# define pqt_buf_putint4(_buffer, _val) do{ \ + int _v = (int) htonl((int) (_val)); \ + memcpy(_buffer, &_v, sizeof(int)); \ + } while (0) + + short pqt_buf_getint2(char *buffer); + int pqt_buf_getint4(char *buffer); +#else +# define pqt_buf_putint2(_out, _val) \ + *(short *) (_out) = (short) htons((short) (_val)) +# define pqt_buf_getint2(_buffer) (short) ntohs(*(short *) (_buffer)) +# define pqt_buf_putint4(_out, _val) \ + *(int *) (_out) = (int) htonl((int) (_val)) +# define pqt_buf_getint4(_buffer) (int) ntohl(*(int *) (_buffer)) +#endif + +/* ---------------------------------- + * See: src/include/catalog/pg_type.h + * Used by built-in type handlers + */ + +/* numerics types */ +#define INT2OID 21 +#define INT4OID 23 +#define INT8OID 20 +#define FLOAT4OID 700 +#define FLOAT8OID 701 +#define NUMERICOID 1700 +/* geo types */ +#define POINTOID 600 +#define LSEGOID 601 +#define PATHOID 602 +#define BOXOID 603 +#define POLYGONOID 604 +#define LINEOID 628 /* not supported yet */ +#define CIRCLEOID 718 +/* network types */ +#define INETOID 869 +#define CIDROID 650 +#define MACADDROID 829 +/* variable length types */ +#define BPCHAROID 1042 +#define VARCHAROID 1043 +#define NAMEOID 19 +#define TEXTOID 25 +#define ZPBITOID 1560 /* not supported yet */ +#define VARBITOID 1562 /* not supported yet */ +#define BYTEAOID 17 +/* date and time types */ +#define DATEOID 1082 +#define TIMEOID 1083 +#define TIMETZOID 1266 +#define TIMESTAMPOID 1114 +#define TIMESTAMPTZOID 1184 +#define INTERVALOID 1186 +/* misc types */ +#define CHAROID 18 +#define BOOLOID 16 +#define OIDOID 26 +#define CASHOID 790 +#define RECORDOID 2249 +#define UUIDOID 2950 + +/* -------------------------------- + * Private Structures + */ + +/* Represents a param value. An array of PGvalues was choosen over + * allocating 4 separate arrays: oids, values, lengths, formats. Instead + * of 4 allocations you only have one. The PGvalue array can easily be + * converted to 4 arrays for execution. + */ +typedef struct +{ + int ptrl; /* Length of value's pointer */ + void *ptr; /* value pointer, data member uses this for non-NULL values */ + int datal; /* Length of current value: always <= ptrl */ + char *data; /* current value data, can be NULL ... thus the ptr member. */ + int format; /* format: 0=text, 1=binary */ + Oid oid; /* Oid of the data */ +} PGvalue; + +/* performance driven structure. Instead of parsing and looking up + * type specs each put or get, PQspecPrepare can be used to compile + * a spec format string into a PGtypeSpec object. The biggest wins are + * large results sets and arrays. + */ +typedef struct +{ + char *name; /* name for the prepared spec, used for lookup. */ + char *stmt; /* parameterized version of stmt, if supplied */ + int idcnt; /* number of handler ids */ + int *idlist; /* handler ids */ + unsigned char *flags; /* handler flags */ +} PGtypeSpec; + +/* PGparam structure */ +struct pg_param +{ + int vcnt; /* current number of param values */ + int vmax; /* number of PGvalue structs in 'vals' array. */ + PGvalue *vals; /* array of param values, grown when needed */ + + /* assigned during PQparamCreate */ + PGtypeFormatInfo fmtinfo; + int typhcnt; + PGtypeHandler *typhandlers; + + int typspeccnt; + PGtypeSpec *typspecs; +}; + +typedef struct +{ + PGtypeFormatInfo fmtinfo; + int typhcnt; + int typhmax; + PGtypeHandler *typhandlers; + + int typspeccnt; + int typspecmax; + PGtypeSpec *typspecs; +} PGtypeData; + +/* -------------------------------- + * Internal API functions (not exported) + */ + +/* === in events.c === */ + +/* The libpq PGEventProc */ +int pqt_eventproc(PGEventId id, void *info, void *passThrough); + +void pqt_cleartypes(PGtypeData *typeData); + +/* === in param.c === */ + +int pqt_putparam(PGparam *param, const void *data, int datal, + int flags, int format, Oid typoid); + +/* === in spec.c === */ + +PGtypeSpec *pqt_getspec(PGtypeSpec *specs, int count, const char *name); +PGtypeSpec *pqt_dupspecs(PGtypeSpec *specs, int count); +void pqt_clearspec(PGtypeSpec *cache); +void pqt_freespecs(PGtypeSpec *specs, int count); + +char *pqt_parse(const char *format, PGtypeHandler *h, int hcnt, + char *stmtBuf, size_t stmtBufLen, PGtypeHandler **out, size_t *stmtPos, + int *typpos, int *flags); + +char *pqt_parsetype(const char *spec, char *schema, char *typname, + int *flags, int typpos); + +/* === in handler.c === */ + +int pqt_allowsptr(PGtypeHandler *h); +void pqt_getfmtinfo(const PGconn *conn, PGtypeFormatInfo *info); +PGtypeHandler *pqt_duphandlers(PGtypeHandler *handlers, int hcnt); +void pqt_freehandlers(PGtypeHandler *handlers, int hcnt); +int pqt_argssuper(PGtypeArgs *args, ...); +int pqt_argserrorf(PGtypeArgs *args, const char *format, ...); +void pqt_setresultfields(const PGresult *res); + +PGtypeHandler *pqt_gethandler(PGtypeHandler *handlers, int hcnt, + const char *schema, const char *typname); + +PGtypeHandler *pqt_gethandlerbyid(PGtypeHandler *handlers, + int hcnt, int id); + +/* FQTN standards for Fully Qualified Type Name. Returns a pointer to out. + * Only returns NULL if out is NULL or outl == 0. + */ +char *pqt_fqtn(char *out, size_t outl, + const char *schema, const char *typname); + +/* == in utils.c == */ + +PGresult *pqt_copyresult(PGtypeArgs *args, int nattrs); +void pqt_swap8(void *outp, void *inp, int tonet); +int pqt_text_to_int8(char *val, void *out); +int pqt_text_to_float8(double *f8, char *text, char **endptr); + +/* Checks buffer and truncates 'src' if 'dest' is too small. */ +char *pqt_strcpy(char *dest, size_t size, const char *src); + +/* Taken from postgres project (named pg_xxx) */ +unsigned char pqt_tolower(unsigned char ch); +int pqt_strcasecmp(const char *s1, const char *s2); +int pqt_strncasecmp(const char *s1, const char *s2, size_t n); + +/* == in port.c == */ + +/* Define a strtoll macro for windows, except for MinGW & Cygwin + * which always have it. MSVC has _strtoi64, but MSVC 6 and under + * require that we declare the prototype. + */ +#ifdef PQT_MSVC +# if PQT_MSVC <= 1200 + __int64 __cdecl _strtoi64(const char *, char **, int); +# endif +# define strtoll _strtoi64 +#endif + +/* In rare cases these could be absent (older platforms). We implement + * drop-in replacements in port.c for those cases. strtod handled by + * configure, which adds a replacement for us. + * + * NOTE: only unixes use configure so sections wrapped around + * HAVE_CONFIG_H exclude windows. + */ +#ifdef HAVE_CONFIG_H +# ifndef HAVE_STRTOL + long strtol(const char *nptr, char **endptr, int base); +# endif +# ifndef HAVE_STRTOUL + unsigned long strtoul(const char *nptr, char **endptr, int base); +# endif +# ifndef HAVE_STRTOLL + long long int strtoll(const char *nptr, char **endptr, int base); +# endif +#endif + +/* Handles platform differences and always returns -1 for failure. + * On windows: MSVC 8 uses _snprintf_s, otherwise _snprintf. + */ +int pqt_snprintf(char *buf, size_t size, const char *format, ...); +int pqt_vsnprintf(char *buf, size_t size, const char *format, va_list ap); + +/* -------------------------------- + * Built-in Type Handlers + */ + +/* === in array.c === */ + +int pqt_put_array(PGtypeArgs *args); +int pqt_get_array(PGtypeArgs *args); + +/* == in datetime.c == */ + +int pqt_put_date(PGtypeArgs *args); +int pqt_get_date(PGtypeArgs *args); +int pqt_put_time(PGtypeArgs *args); +int pqt_get_time(PGtypeArgs *args); +int pqt_put_timetz(PGtypeArgs *args); +int pqt_get_timetz(PGtypeArgs *args); +int pqt_put_timestamp(PGtypeArgs *args); +int pqt_get_timestamp(PGtypeArgs *args); +int pqt_put_timestamptz(PGtypeArgs *args); +int pqt_get_timestamptz(PGtypeArgs *args); +int pqt_put_interval(PGtypeArgs *args); +int pqt_get_interval(PGtypeArgs *args); + +/* == in geo.c == */ + +int pqt_put_point(PGtypeArgs *args); +int pqt_get_point(PGtypeArgs *args); +int pqt_put_lseg(PGtypeArgs *args); +int pqt_get_lseg(PGtypeArgs *args); +int pqt_put_box(PGtypeArgs *args); +int pqt_get_box(PGtypeArgs *args); +int pqt_put_circle(PGtypeArgs *args); +int pqt_get_circle(PGtypeArgs *args); +int pqt_put_path(PGtypeArgs *args); +int pqt_get_path(PGtypeArgs *args); +int pqt_put_polygon(PGtypeArgs *args); +int pqt_get_polygon(PGtypeArgs *args); + +/* == in misc.c == */ + +int pqt_put_char(PGtypeArgs *args); /* "char" type, not char(N) */ +int pqt_get_char(PGtypeArgs *args); +int pqt_put_bool(PGtypeArgs *args); +int pqt_get_bool(PGtypeArgs *args); +int pqt_put_money(PGtypeArgs *args); +int pqt_get_money(PGtypeArgs *args); +int pqt_put_uuid(PGtypeArgs *args); +int pqt_get_uuid(PGtypeArgs *args); +int pqt_put_null(PGtypeArgs *args); /* no get for null */ + +/* == in network.c == */ + +int pqt_put_inet(PGtypeArgs *args); /* handles cidr */ +int pqt_get_inet(PGtypeArgs *args); +int pqt_get_cidr(PGtypeArgs *args); +int pqt_put_macaddr(PGtypeArgs *args); +int pqt_get_macaddr(PGtypeArgs *args); + +/* == in numerics.c == */ + +int pqt_put_int2(PGtypeArgs *args); +int pqt_get_int2(PGtypeArgs *args); +int pqt_put_int4(PGtypeArgs *args); /* handles oid */ +int pqt_get_int4(PGtypeArgs *args); /* handles oid */ +int pqt_put_int8(PGtypeArgs *args); +int pqt_get_int8(PGtypeArgs *args); +int pqt_put_float4(PGtypeArgs *args); +int pqt_get_float4(PGtypeArgs *args); +int pqt_put_float8(PGtypeArgs *args); +int pqt_get_float8(PGtypeArgs *args); +int pqt_put_numeric(PGtypeArgs *args); +int pqt_get_numeric(PGtypeArgs *args); + +/* == record.c (composites) == */ + +int pqt_put_record(PGtypeArgs *args); +int pqt_get_record(PGtypeArgs *args); + +/* == in varlena.c == */ + +int pqt_put_str(PGtypeArgs *args); /* no get for str - use PQgetvalue */ +int pqt_put_text(PGtypeArgs *args); /* handles varchar, bpchar and name */ +int pqt_get_text(PGtypeArgs *args); /* handles varchar, bpchar and name */ +int pqt_put_bytea(PGtypeArgs *args); +int pqt_get_bytea(PGtypeArgs *args); + +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/source/src/libpqtypes.h b/source/src/libpqtypes.h new file mode 100644 index 0000000..6e25a7d --- /dev/null +++ b/source/src/libpqtypes.h @@ -0,0 +1,468 @@ + +/* + * libpqtypes.h + * Public header for libpqtypes. Contains the entire public API. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef LIBPQTYPES_H +#define LIBPQTYPES_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) +# define PQT_EXPORT __declspec(dllexport) +#else +# define PQT_EXPORT extern +#endif + +/* MSVC 6 must use `i64', everything else uses `LL'. */ +#if !defined(_MSC_VER) || _MSC_VER > 1200 +# define PQT_INT64CONST(x) ((PGint8) x##LL) +#else +# define PQT_INT64CONST(x) ((PGint8) x##i64) +#endif + +enum +{ + PQT_SUBCLASS, + PQT_COMPOSITE, + PQT_USERDEFINED +}; + +typedef struct pg_param PGparam; +typedef struct pg_typeargs PGtypeArgs; +typedef int (*PGtypeProc)(PGtypeArgs *args); + +/* For use with a PQregisterXXX function */ +typedef struct +{ + const char *typname; + PGtypeProc typput; + PGtypeProc typget; +} PGregisterType; + +typedef struct +{ + int sversion; + int pversion; + char datestyle[48]; + int integer_datetimes; +} PGtypeFormatInfo; + +/* Record Attribute Description, its columns */ +typedef struct +{ + Oid attoid; + int attlen; + int atttypmod; + char attname[65]; +} PGrecordAttDesc; + +/* Type handler for putf and getf functions. The char fixed length buffers + * used to be allocated pointers. This was a performance problem when + * many type handlers are registered and one uses getf on a composite or + * an array. These types require generating a PGresult and duplicating + * the type handlers. Saved 40% by not having to deep copy the strings. + */ +typedef struct pg_typhandler +{ + int id; + char typschema[65]; + char typname[65]; + int typlen; + Oid typoid; + Oid typoid_array; + PGtypeProc typput; + PGtypeProc typget; + int base_id; + + /* For composites, contains each attribute of a composite */ + int nattrs; + int freeAttDescs; + PGrecordAttDesc attDescsBuf[16]; + PGrecordAttDesc *attDescs; +} PGtypeHandler; + +/* Values required during a type handler put ot get operation. */ +struct pg_typeargs +{ + int is_put; + const PGtypeFormatInfo *fmtinfo; + int is_ptr; + int format; + va_list ap; + int typpos; + PGtypeHandler *typhandler; + int (*errorf)(PGtypeArgs *args, const char *format, ...); + int (*super)(PGtypeArgs *args, ...); + + struct + { + PGparam *param; + char *out; + char *__allocated_out; /* leave me alone! */ + int outl; + int (*expandBuffer)(PGtypeArgs *args, int new_len); + } put; + + struct + { + PGresult *result; + int tup_num; + int field_num; + } get; +}; + + +/* ---------------- + * Variable Length types + * ---------------- + */ + +typedef char *PGtext; +typedef char *PGvarchar; +typedef char *PGbpchar; +typedef char *PGuuid; +typedef struct +{ + int len; + char *data; +} PGbytea; + +/* ---------------- + * Numeric types + * ---------------- + */ + +typedef signed char PGchar; +typedef int PGbool; +typedef short PGint2; +typedef int PGint4; +typedef float PGfloat4; +typedef double PGfloat8; +typedef char *PGnumeric; + +/* Defined by an end-user if the system is missing long long. */ +#ifdef PQT_LONG_LONG + typedef PQT_LONG_LONG PGint8; + typedef PQT_LONG_LONG PGmoney; + +/* MinGW and MSVC can use __int64 */ +#elif defined(__MINGW32__) || defined(_MSC_VER) + typedef __int64 PGint8; + typedef __int64 PGmoney; + +/* Cygwin and Unixes. */ +#else + typedef long long PGint8; + typedef long long PGmoney; +#endif + +/* ---------------- + * Geometric type structures + * ---------------- + */ + +typedef struct +{ + double x; + double y; +} PGpoint; + +typedef struct +{ + PGpoint pts[2]; +} PGlseg; + +typedef struct +{ + PGpoint high; + PGpoint low; +} PGbox; + +typedef struct +{ + PGpoint center; + double radius; +} PGcircle; + +typedef struct +{ + int npts; + int closed; + PGpoint *pts; /* for getf, only valid while PGresult is. */ +} PGpath; + +typedef struct +{ + int npts; + PGpoint *pts; /* for getf, only valid while PGresult is. */ +} PGpolygon; + +/* ---------------- + * Network type structures + * ---------------- + */ + +/* This struct works with CIDR as well. */ +typedef struct +{ + int mask; + int is_cidr; + int sa_buf_len; + + /* sockaddr buffer, can be casted to sockaddr, sockaddr_in, + * sockaddr_in6 or sockaddr_stroage. + */ + char sa_buf[128]; +} PGinet; + +typedef struct +{ + int a; + int b; + int c; + int d; + int e; + int f; +} PGmacaddr; + +/* ---------------- + * Date & Time structures + * ---------------- + */ + +typedef struct +{ + int years; + int mons; + int days; + int hours; + int mins; + int secs; + int usecs; +} PGinterval; + +typedef struct +{ + int isbc; + int year; + int mon; + int mday; + int jday; + int yday; + int wday; +} PGdate; + +typedef struct +{ + int hour; + int min; + int sec; + int usec; + int withtz; + int isdst; + int gmtoff; + char tzabbr[16]; +} PGtime; + +typedef struct +{ + PGint8 epoch; + PGdate date; + PGtime time; +} PGtimestamp; + +/* ---------------- + * Array structures + * ---------------- + */ + +#ifndef MAXDIM +# define MAXDIM 6 +#endif + +typedef struct +{ + int ndims; + int lbound[MAXDIM]; + int dims[MAXDIM]; + PGparam *param; + PGresult *res; +} PGarray; + +/* ---------------- + * Public API funcs + * ---------------- + */ + +/* === in events.c === */ + +/* Deprecated, see PQinitTypes */ +PQT_EXPORT int +PQtypesRegister(PGconn *conn); + +/* === in error.c === */ + +PQT_EXPORT char * +PQgeterror(void); + +/* PQseterror(NULL) will clear the error message */ +PQT_EXPORT void +PQseterror(const char *format, ...); + +/* Gets the error field for the last executed query. This only + * pertains to PQparamExec and PQparamExecPrepared. When using a + * standard libpq function like PQexec, PQresultErrorField should be used. + */ +PQT_EXPORT char * +PQgetErrorField(int fieldcode); + +/* === in spec.c === */ + +/* Set 'format' argument to NULL to clear a single prepared specifier. */ +PQT_EXPORT int +PQspecPrepare(PGconn *conn, const char *name, const char *format, int is_stmt); + +PQT_EXPORT int +PQclearSpecs(PGconn *conn); + +/* === in handler.c === */ + +/* Initialize type support on the given connection */ +PQT_EXPORT int +PQinitTypes(PGconn *conn); + +/* Deprecated, see PQregisterTypes */ +PQT_EXPORT int +PQregisterSubClasses(PGconn *conn, PGregisterType *types, int count); + +/* Deprecated, see PQregisterTypes */ +PQT_EXPORT int +PQregisterComposites(PGconn *conn, PGregisterType *types, int count); + +/* Deprecated, see PQregisterTypes */ +PQT_EXPORT int +PQregisterUserDefinedTypes(PGconn *conn, PGregisterType *types, int count); + +/* Registers PQT_SUBCLASS, PQT_COMPOSITE or PQT_USERDEFINED + * (the 'which' argument) for use with libpqtypes. + * + * For asynchronous type registration, set the 'async' argument to a + * non-zero value. This value is ignored when 'which' is PQT_SUBCLASS, + * since subclass registration does not execute any commands against the + * server. Use the standard PQconsumeInput, PQisBusy and PQgetResult + * to properly obtain a PGresult, which must be passed to PQregisterResult + * to complete the registration. + */ +PQT_EXPORT int +PQregisterTypes(PGconn *conn, int which, PGregisterType *types, + int count, int async); + +/* Registers a set of 'which' types found in the given PGresult. Caller + * is responsible for clearing the result 'res'. Useful for performing + * asynchronous type registration or for caching type result data to + * avoid lookups on a new connection. If PQregisterTypes is ran in async + * mode, the PGresult obtained via PGgetResult can be cached by an + * application and provided to this function for new connections. + * + * Types and count should be identical to what was originally supplied + * to PQregisterTypes. + * + * NOTE: although a PGconn is a required argument, it is never used + * to perform any network operation (non-blocking safe). + * + * PQT_SUBCLASS is not supported and will result in an error if supplied. + */ +PQT_EXPORT int +PQregisterResult(PGconn *conn, int which, PGregisterType *types, + int count, PGresult *res); + +/* Clears all type handlers registered on 'conn'. This is useful after a + * PQreset or PQresetPoll to optionally allow one to re-register types via + * PQregisterTypes. + */ +PQT_EXPORT int +PQclearTypes(PGconn *conn); + +/* === in param.c === */ + +PQT_EXPORT PGparam * +PQparamCreate(const PGconn *conn); + +PQT_EXPORT PGparam * +PQparamDup(PGparam *param); + +PQT_EXPORT int +PQparamCount(PGparam *param); + +PQT_EXPORT void +PQparamReset(PGparam *param); + +PQT_EXPORT void +PQparamClear(PGparam *param); + +PQT_EXPORT int +PQputf(PGparam *param, const char *format, ...); + +PQT_EXPORT int +PQputvf(PGparam *param, char *stmtBuf, size_t stmtBufLen, + const char *format, va_list ap); + +/* === in exec.c === */ + +PQT_EXPORT int +PQgetf(const PGresult *res, int tup_num, const char *format, ...); + +PQT_EXPORT int +PQgetvf(const PGresult *res, int tup_num, const char *format, va_list ap); + +PQT_EXPORT PGresult * +PQexecf(PGconn *conn, const char *cmdspec, ...); + +PQT_EXPORT PGresult * +PQexecvf(PGconn *conn, const char *cmdspec, va_list ap); + +PQT_EXPORT int +PQsendf(PGconn *conn, const char *cmdspec, ...); + +PQT_EXPORT int +PQsendvf(PGconn *conn, const char *cmdspec, va_list ap); + +PQT_EXPORT PGresult * +PQparamExec(PGconn *conn, PGparam *param, + const char *command, int resultFormat); + +PQT_EXPORT int +PQparamSendQuery(PGconn *conn, PGparam *param, + const char *command, int resultFormat); + +PQT_EXPORT PGresult * +PQparamExecPrepared(PGconn *conn, PGparam *param, + const char *stmtName, int resultFormat); + +PQT_EXPORT int +PQparamSendQueryPrepared(PGconn *conn, PGparam *param, + const char *stmtName, int resultFormat); + +/* === in datetime.c === */ + +PQT_EXPORT void +PQlocalTZInfo(time_t *t, int *gmtoff, int *isdst, char **tzabbrp); + +#ifdef __cplusplus +} +#endif +#endif /* !LIBPQTYPES_H */ + diff --git a/source/src/misc.c b/source/src/misc.c new file mode 100644 index 0000000..d6d04fc --- /dev/null +++ b/source/src/misc.c @@ -0,0 +1,199 @@ + +/* + * misc.c + * Type handler for CHAR, BOOL, MONEY, UUID data types. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +int +pqt_put_char(PGtypeArgs *args) +{ + PGchar c; + + if (args->is_ptr) + { + PGchar *ptr = (PGchar *) va_arg(args->ap, PGchar *); + PUTNULLCHK(args, ptr); + c = *ptr; + } + else + { + c = (PGchar) va_arg(args->ap, int); + } + + *args->put.out = c; + return 1; +} + +int +pqt_get_char(PGtypeArgs *args) +{ + DECLVALUE(args); + PGchar *chp = va_arg(args->ap, PGchar *); + CHKGETVALS(args, chp); + *chp = *value; + return 0; +} + +int +pqt_put_bool(PGtypeArgs *args) +{ + char b; + + if (args->is_ptr) + { + PGbool *ptr = (PGbool *) va_arg(args->ap, PGbool *); + PUTNULLCHK(args, ptr); + b = (char) *ptr; + } + else + { + b = (char) va_arg(args->ap, PGbool); + } + + *args->put.out = b != 0 ? 1 : 0; + return 1; +} + +int +pqt_get_bool(PGtypeArgs *args) +{ + DECLVALUE(args); + PGbool *boolp = va_arg(args->ap, PGbool *); + + CHKGETVALS(args, boolp); + + if (args->format == TEXTFMT) + *boolp = (*value == 't') ? 1 : 0; + else + *boolp = (*value)!=0 ? 1 : 0; + return 0; +} + +int +pqt_put_money(PGtypeArgs *args) +{ + PGmoney money; + int len = args->fmtinfo->sversion >= 80300 ? 8 : 4; + + if (args->is_ptr) + { + PGmoney *ptr = va_arg(args->ap, PGmoney *); + PUTNULLCHK(args, ptr); + money = *ptr; + } + else + { + money = va_arg(args->ap, PGmoney); + } + + if (len == 8) + pqt_swap8(args->put.out, &money, 1); + else /* truncate: pre 8.3 server expecting a 4 byte money */ + pqt_buf_putint4(args->put.out, (int) money); + + return len; +} + +int +pqt_get_money(PGtypeArgs *args) +{ + DECLVALUE(args); + DECLLENGTH(args); + PGmoney *moneyp = va_arg(args->ap, PGmoney *); + + CHKGETVALS(args, moneyp); + + if (args->format == TEXTFMT) + { + char buf[64]; + char c, *p = buf; + char *bufend = buf + sizeof(buf); + + for (; (c = *value) != '\0' && pap, PGuuid); + PUTNULLCHK(args, uuid); + args->put.out = uuid; + return 16; +} + +int +pqt_get_uuid(PGtypeArgs *args) +{ + DECLVALUE(args); + PGuuid *uuid = va_arg(args->ap, PGuuid *); + + CHKGETVALS(args, uuid); + + if (args->format == TEXTFMT) + { + int i; + char buf[128]; + char *p = buf; + DECLLENGTH(args); + + /* format: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 */ + for (i=0; i < valuel; i++) + { + if (value[i] != '-') + { + *p++ = (pqt_hex_to_dec(value[i]) << 4) | pqt_hex_to_dec(value[i+1]); + i++; + } + } + + *uuid = (char *) PQresultAlloc(args->get.result, p - buf); + if (!*uuid) + RERR_MEM(args); + + memcpy(*uuid, buf, p - buf); + return 0; + } + + *uuid = value; + return 0; +} + +int +pqt_put_null(PGtypeArgs *args) +{ + args->put.out = NULL; + return 0; +} + diff --git a/source/src/network.c b/source/src/network.c new file mode 100644 index 0000000..1fec3f3 --- /dev/null +++ b/source/src/network.c @@ -0,0 +1,257 @@ + +/* + * network.c + * Type handler for the network data types. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +#if defined(__CYGWIN__) || (defined(HAVE_CONFIG_H) && \ + !defined(HAVE_GETADDRINFO)) +# include "getaddrinfo.h" +#endif + +#ifndef PGSQL_AF_INET +# define PGSQL_AF_INET (AF_INET + 0) +#endif + +#ifndef PGSQL_AF_INET6 +# define PGSQL_AF_INET6 (AF_INET + 1) +#endif + +#ifndef AF_INET6 +#warning NO AF_INET6 SUPPORT! +#endif + +/* Some platforms don't define this, like AIX 4.3 */ +#ifndef AI_NUMERICHOST +# define AI_NUMERICHOST 0x04 +#endif + +/* handles cidr as well */ +int +pqt_put_inet(PGtypeArgs *args) +{ + unsigned char *b = (unsigned char *)args->put.out; + PGinet *inet = va_arg(args->ap, PGinet *); + int family; + + PUTNULLCHK(args, inet); + + family = ((struct sockaddr *)inet->sa_buf)->sa_family; + + if (family == AF_INET) + { + struct sockaddr_in *sa = (struct sockaddr_in *) inet->sa_buf; + *b++ = (unsigned char) PGSQL_AF_INET; + *b++ = (unsigned char) inet->mask; + *b++ = (unsigned char) (inet->is_cidr ? 1 : 0); + *b++ = (unsigned char) 4; + memcpy(b, &sa->sin_addr, 4); + b += 4; + } +#ifdef AF_INET6 + else if (family == AF_INET6) + { + struct sockaddr_in6 *sa = (struct sockaddr_in6 *) inet->sa_buf; + *b++ = (unsigned char) PGSQL_AF_INET6; + *b++ = (unsigned char) inet->mask; + *b++ = (unsigned char) (inet->is_cidr ? 1 : 0); + *b++ = (unsigned char) 16; + memcpy(b, &sa->sin6_addr, 16); + b += 16; + } +#endif + else + { + return args->errorf(args, "Unknown inet address family %d", family); + } + + return (int) ((char *) b - args->put.out); +} + +static int +get_inet2(PGtypeArgs *args, int is_cidr) +{ + DECLVALUE(args); + unsigned short family; + PGinet *inet = va_arg(args->ap, PGinet *); + + CHKGETVALS(args, inet); + + if (args->format == TEXTFMT) + { + int r; + char *p; + char ipstr[80]; + struct addrinfo *ai = NULL; + struct addrinfo hints; + + pqt_strcpy(ipstr, sizeof(ipstr), value); + if ((p = strrchr(ipstr, '/'))) + { + *p = 0; + inet->mask = atoi(p+1); + } + else + { + inet->mask = 32; + } + + inet->is_cidr = is_cidr; + + /* suppress hostname lookups */ + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_NUMERICHOST; + + /* Without this, windows chokes with WSAHOST_NOT_FOUND */ +#ifdef PQT_WIN32 + hints.ai_family = AF_INET; +#endif + + if ((r = getaddrinfo(ipstr, NULL, &hints, &ai)) || !ai) + { + if(r == EAI_BADFLAGS) + { + hints.ai_flags = 0; + r = getaddrinfo(ipstr, NULL, &hints, &ai); + } + /* Another WSAHOST_NOT_FOUND work around, but for IPv6 */ +#if defined(PQT_WIN32) && defined(AF_INET6) + else if(r == WSAHOST_NOT_FOUND) + { + hints.ai_flags = 0; + hints.ai_family = AF_INET6; + r = getaddrinfo(ipstr, NULL, &hints, &ai); + } +#endif + + if(r) + RERR_STR2INT(args); + } + + inet->sa_buf_len = (int) ai->ai_addrlen; + memcpy(inet->sa_buf, ai->ai_addr, inet->sa_buf_len); + + /* Some platforms, lika AIX 4.3, do not zero this structure properly. + * The family and port are dirty, so set the first 4 bytes to 0 and + * then re-set the family. I saw "0x1002" as the first 2 bytes of + * this structure (dumb getaddrinfo), it should be "0x0002" for AF_INET. + */ + memset(inet->sa_buf, 0, 4); + ((struct sockaddr *)inet->sa_buf)->sa_family = ai->ai_addr->sa_family; + + /* Uninitialized memory, postgres inet/cidr types don't store this. + * Make sure its set to 0. Another AIX problem (maybe other platforms). + */ +#ifdef AF_INET6 + if (ai->ai_addr->sa_family == AF_INET6) + ((struct sockaddr_in6 *)inet->sa_buf)->sin6_flowinfo = 0; +#endif + + freeaddrinfo(ai); + return 0; + } + + family = (unsigned short) *value++; + if (family == PGSQL_AF_INET) + { + struct sockaddr_in *sa = (struct sockaddr_in *) inet->sa_buf; + sa->sin_family = AF_INET; + inet->mask = (unsigned char) *value++; + inet->is_cidr = *value++; + memcpy(&sa->sin_addr, value + 1, *value); + inet->sa_buf_len = (int) sizeof(struct sockaddr_in); + } +#ifdef AF_INET6 + else if (family == PGSQL_AF_INET6) + { + struct sockaddr_in6 *sa = (struct sockaddr_in6 *) inet->sa_buf; + sa->sin6_family = AF_INET6; + inet->mask = (unsigned char) *value++; + inet->is_cidr = *value++; + memcpy(&sa->sin6_addr, value + 1, *value); + inet->sa_buf_len = (int) sizeof(struct sockaddr_in6); + } +#endif + else + { + return args->errorf(args, "Unknown inet address family %d", family); + } + + return 0; +} + +int +pqt_get_inet(PGtypeArgs *args) +{ + return get_inet2(args, 0); +} + +int +pqt_get_cidr(PGtypeArgs *args) +{ + return get_inet2(args, 1); +} + +int +pqt_put_macaddr(PGtypeArgs *args) +{ + PGmacaddr *mac = va_arg(args->ap, PGmacaddr *); + + PUTNULLCHK(args, mac); + + args->put.out[0] = (unsigned char) mac->a; + args->put.out[1] = (unsigned char) mac->b; + args->put.out[2] = (unsigned char) mac->c; + args->put.out[3] = (unsigned char) mac->d; + args->put.out[4] = (unsigned char) mac->e; + args->put.out[5] = (unsigned char) mac->f; + return 6; +} + +int +pqt_get_macaddr(PGtypeArgs *args) +{ + DECLVALUE(args); + unsigned char *p; + PGmacaddr *mac = va_arg(args->ap, PGmacaddr *); + + CHKGETVALS(args, mac); + + if (args->format == TEXTFMT) + { + int a,b,c,d,e,f; + int count = sscanf(value, "%x:%x:%x:%x:%x:%x", &a,&b,&c,&d,&e,&f); + + if (count != 6 || (a < 0) || (a > 255) || (b < 0) || (b > 255) || + (c < 0) || (c > 255) || (d < 0) || (d > 255) || + (e < 0) || (e > 255) || (f < 0) || (f > 255)) + RERR_STR2INT(args); + + mac->a = a; + mac->b = b; + mac->c = c; + mac->d = d; + mac->e = e; + mac->f = f; + return 0; + } + + p = (unsigned char *) value; + mac->a = *p++; + mac->b = *p++; + mac->c = *p++; + mac->d = *p++; + mac->e = *p++; + mac->f = *p; + return 0; +} + + + diff --git a/source/src/numerics.c b/source/src/numerics.c new file mode 100644 index 0000000..66da3a0 --- /dev/null +++ b/source/src/numerics.c @@ -0,0 +1,838 @@ + +/* + * numeric.c + * Type handler for the numeric data types. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" +#include +#include + +/* Extremely annoying warning "conversion from 'int ' to 'short'" on + * Visual Studio 6. Normally this warning is useful but not in this + * case. Disable it. + */ +#if defined(PQT_MSVC) && PQT_MSVC <= 1200 +# pragma warning (disable : 4244) +#endif + +/* + * Macros and structures for receiving numeric field in binary + */ +#define NBASE 10000 +#define HALF_NBASE 5000 +#define DEC_DIGITS 4 /* decimal digits per NBASE digit */ +#define MUL_GUARD_DIGITS 2 /* these are measured in NBASE digits */ +#define DIV_GUARD_DIGITS 4 + +/* + * Hardcoded precision limit - arbitrary, but must be small enough that + * dscale values will fit in 14 bits. + */ +#define NUMERIC_MAX_PRECISION 1000 + +/* + * Sign values and macros to deal with packing/unpacking n_sign_dscale + */ +#define NUMERIC_SIGN_MASK 0xC000 +#define NUMERIC_POS 0x0000 +#define NUMERIC_NEG 0x4000 +#define NUMERIC_NAN 0xC000 +#define NUMERIC_DSCALE_MASK 0x3FFF +#define NUMERIC_SIGN(n) ((n)->n_sign_dscale & NUMERIC_SIGN_MASK) +#define NUMERIC_DSCALE(n) ((n)->n_sign_dscale & NUMERIC_DSCALE_MASK) +#define NUMERIC_IS_NAN(n) (NUMERIC_SIGN(n) != NUMERIC_POS && \ + NUMERIC_SIGN(n) != NUMERIC_NEG) + +typedef short NumericDigit; +static const int round_powers[4] = {0, 1000, 100, 10}; + +typedef struct NumericVar +{ + int ndigits; /* # of digits in digits[] - can be 0! */ + int weight; /* weight of first digit */ + int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */ + int dscale; /* display scale */ + NumericDigit *buf; /* start of palloc'd space for digits[] */ + NumericDigit *digits; /* base-NBASE digits */ +} NumericVar; + +static NumericVar const_nan = +{0, 0, NUMERIC_NAN, 0, NULL, NULL}; + +static int str2num(PGtypeArgs *args, const char *str, NumericVar *dest); +static int num2str(char *out, size_t outl, NumericVar *var, int dscale); + +int +pqt_put_int2(PGtypeArgs *args) +{ + PGint2 n; + + if (args->is_ptr) + { + PGint4 *nptr = va_arg(args->ap, PGint4 *); + PUTNULLCHK(args, nptr); + n = (PGint2) *nptr; + } + else + { + n = (PGint2) va_arg(args->ap, PGint4); + } + + pqt_buf_putint2(args->put.out, n); + return 2; +} + +int +pqt_get_int2(PGtypeArgs *args) +{ + DECLVALUE(args); + PGint2 *i2p = va_arg(args->ap, PGint2 *); + + CHKGETVALS(args, i2p); + + if (args->format == TEXTFMT) + { + int n; + + errno = 0; + if ((n = (int) strtol(value, NULL, 10)) == 0 && errno) + RERR_STR2INT(args); + + *i2p = (PGint2)n; + return 0; + } + + *i2p = pqt_buf_getint2(value); + return 0; +} + +/* handles oid as well */ +int +pqt_put_int4(PGtypeArgs *args) +{ + PGint4 n; + + if (args->is_ptr) + { + PGint4 *nptr = va_arg(args->ap, PGint4 *); + PUTNULLCHK(args, nptr); + n = *nptr; + } + else + { + n = (PGint4) va_arg(args->ap, PGint4); + } + + *(PGint4 *)args->put.out = (PGint4) htonl(n); + return 4; +} + +/* handles oid as well */ +int +pqt_get_int4(PGtypeArgs *args) +{ + DECLVALUE(args); + PGint4 *i4p = va_arg(args->ap, PGint4 *); + + CHKGETVALS(args, i4p); + + if (args->format == TEXTFMT) + { + PGint4 n; + + /* Use strtoul so this can support Oid */ + if ((n = (PGint4) strtoul(value, NULL, 10)) == 0 && errno) + RERR_STR2INT(args); + + *i4p = n; + return 0; + } + + *i4p = (PGint4) pqt_buf_getint4(value); + return 0; +} + +int +pqt_put_int8(PGtypeArgs *args) +{ + PGint8 i8; + + if (args->is_ptr) + { + PGint8 *nptr = va_arg(args->ap, PGint8 *); + PUTNULLCHK(args, nptr); + i8 = *nptr; + } + else + { + i8 = va_arg(args->ap, PGint8); + } + + pqt_swap8(args->put.out, &i8, 1); + return 8; +} + +int +pqt_get_int8(PGtypeArgs *args) +{ + DECLVALUE(args); + PGint8 *i8p = va_arg(args->ap, PGint8 *); + + CHKGETVALS(args, i8p); + + if (args->format == TEXTFMT) + { + if (pqt_text_to_int8(value, i8p) == -1) + RERR_STR2INT(args); + return 0; + } + + pqt_swap8(i8p, value, 0); + return 0; +} + +int +pqt_put_float4(PGtypeArgs *args) +{ + void *vp; + PGfloat4 f; + + if (args->is_ptr) + { + vp = (void *) va_arg(args->ap, double *); + PUTNULLCHK(args, vp); + } + else + { + f = (PGfloat4) va_arg(args->ap, double); + vp = (void *)&f; + } + + pqt_buf_putint4(args->put.out, *(int *) vp); + return 4; +} + +int +pqt_get_float4(PGtypeArgs *args) +{ + DECLVALUE(args); + int *f4p = (int *) va_arg(args->ap, PGfloat4 *); + + CHKGETVALS(args, f4p); + + if (args->format == TEXTFMT) + { + PGfloat4 f; + + errno = 0; + if ((f = (PGfloat4) strtod(value, NULL)) == 0 && errno) + RERR_STR2INT(args); + + *(PGfloat4 *) f4p = f; + return 0; + } + + *f4p = pqt_buf_getint4(value); + return 0; +} + +int +pqt_put_float8(PGtypeArgs *args) +{ + PGfloat8 d; + + if (args->is_ptr) + { + PGfloat8 *ptr = (PGfloat8 *) va_arg(args->ap, PGfloat8 *); + PUTNULLCHK(args, ptr); + d = *ptr; + } + else + { + d = va_arg(args->ap, PGfloat8); + } + + pqt_swap8(args->put.out, &d, 1); + return 8; +} + +int +pqt_get_float8(PGtypeArgs *args) +{ + DECLVALUE(args); + PGfloat8 *f8p = va_arg(args->ap, PGfloat8 *); + + CHKGETVALS(args, f8p); + + if (args->format == TEXTFMT) + { + if (!pqt_text_to_float8(f8p, value, NULL)) + RERR_STR2INT(args); + + return 0; + } + + pqt_swap8(f8p, value, 0); + return 0; +} + +/* exposing a NumericVar struct to a libpq user, or something similar, + * doesn't seem useful w/o a library to operate on it. Instead, we + * always expose a numeric in text format and let the API user decide + * how to use it .. like strod or a 3rd party big number library. We + * always send a numeric in binary though. + */ +int +pqt_put_numeric(PGtypeArgs *args) +{ + int numlen; + NumericVar num = {0}; + short *out; + PGnumeric str = va_arg(args->ap, PGnumeric); + + PUTNULLCHK(args, str); + + if (str2num(args, str, &num)) + { + if (num.digits) + free(num.digits); + return -1; + } + + /* variable length data type, grow args->put.out buffer if needed */ + numlen = (int) sizeof(short) * (4 + num.ndigits); + if (args->put.expandBuffer(args, numlen) == -1) + return -1; + + out = (short *) args->put.out; + *out++ = htons((short) num.ndigits); + *out++ = htons((short) num.weight); + *out++ = htons((short) num.sign); + *out++ = htons((short) num.dscale); + + if (num.digits) + { + int i; + for (i=0; i < num.ndigits; i++) + *out++ = htons(num.digits[i]); + free(num.digits); + } + + return numlen; +} + +/* exposing a NumericVar struct to a libpq user, or something similar, + * doesn't seem useful w/o a library to operate on it. Instead, we + * always expose a numeric in text format and let the API user decide + * how to use it .. like strod or a 3rd party big number library. + */ +int +pqt_get_numeric(PGtypeArgs *args) +{ + int i; + short *s; + NumericVar num; + DECLVALUE(args); + char buf[4096]; + size_t len; + PGnumeric *str = va_arg(args->ap, PGnumeric *); + + CHKGETVALS(args, str); + + if (args->format == TEXTFMT) + { + *str = value; + return 0; + } + + s = (short *) value; + num.ndigits = ntohs(*s); s++; + num.weight = (short) ntohs(*s); s++; + num.sign = ntohs(*s); s++; + num.dscale = ntohs(*s); s++; + num.digits = (short *) malloc(num.ndigits * sizeof(short)); + if (!num.digits) + RERR_MEM(args); + + for (i=0; i < num.ndigits; i++) + { + num.digits[i] = ntohs(*s); + s++; + } + + i = num2str(buf, sizeof(buf), &num, num.dscale); + free(num.digits); + + /* num2str failed, only fails when 'str' is too small */ + if (i == -1) + RERR(args, "out buffer is too small"); + + len = strlen(buf)+1; + *str = PQresultAlloc(args->get.result, len); + if (!*str) + RERR_MEM(args); + + memcpy(*str, buf, len); + return 0; + +} + + +/* + * round_var + * + * Round the value of a variable to no more than rscale decimal digits + * after the decimal point. NOTE: we allow rscale < 0 here, implying + * rounding before the decimal point. + */ +static void +round_var(NumericVar *var, int rscale) +{ + NumericDigit *digits = var->digits; + int di; + int ndigits; + int carry; + + var->dscale = rscale; + + /* decimal digits wanted */ + di = (var->weight + 1) * DEC_DIGITS + rscale; + + /* + * If di = 0, the value loses all digits, but could round up to 1 if its + * first extra digit is >= 5. If di < 0 the result must be 0. + */ + if (di < 0) + { + var->ndigits = 0; + var->weight = 0; + var->sign = NUMERIC_POS; + } + else + { + /* NBASE digits wanted */ + ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS; + + /* 0, or number of decimal digits to keep in last NBASE digit */ + di %= DEC_DIGITS; + + if (ndigits < var->ndigits || + (ndigits == var->ndigits && di > 0)) + { + var->ndigits = ndigits; + + if (di == 0) + carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0; + else + { + /* Must round within last NBASE digit */ + int extra, + pow10; + + pow10 = round_powers[di]; + extra = digits[--ndigits] % pow10; + digits[ndigits] = digits[ndigits] - (NumericDigit) extra; + carry = 0; + if (extra >= pow10 / 2) + { + pow10 += digits[ndigits]; + if (pow10 >= NBASE) + { + pow10 -= NBASE; + carry = 1; + } + digits[ndigits] = (NumericDigit) pow10; + } + } + + /* Propagate carry if needed */ + while (carry) + { + carry += digits[--ndigits]; + if (carry >= NBASE) + { + digits[ndigits] = (NumericDigit) (carry - NBASE); + carry = 1; + } + else + { + digits[ndigits] = (NumericDigit) carry; + carry = 0; + } + } + + if (ndigits < 0) + { + var->digits--; + var->ndigits++; + var->weight++; + } + } + } +} + +/* + * strip_var + * + * Strip any leading and trailing zeroes from a numeric variable + */ +static void +strip_var(NumericVar *var) +{ + NumericDigit *digits = var->digits; + int ndigits = var->ndigits; + + /* Strip leading zeroes */ + while (ndigits > 0 && *digits == 0) + { + digits++; + var->weight--; + ndigits--; + } + + /* Strip trailing zeroes */ + while (ndigits > 0 && digits[ndigits - 1] == 0) + ndigits--; + + /* If it's zero, normalize the sign and weight */ + if (ndigits == 0) + { + var->sign = NUMERIC_POS; + var->weight = 0; + } + + if (ndigits != var->ndigits) { + memcpy(var->digits, digits, (ndigits) * sizeof(NumericDigit)); + var->ndigits = ndigits; + } +} + +/* + * str2num() + * + * Parse a string and put the number into a variable + * returns -1 on error and 0 for success. + */ +static int +str2num(PGtypeArgs *args, const char *str, NumericVar *dest) +{ + const char *cp = str; + int have_dp = FALSE; + int i; + unsigned char *decdigits; + int sign = NUMERIC_POS; + int dweight = -1; + int ddigits; + int dscale = 0; + int weight; + int ndigits; + int offset; + NumericDigit *digits; + + /* + * We first parse the string to extract decimal digits and determine the + * correct decimal weight. Then convert to NBASE representation. + */ + + /* skip leading spaces */ + while (*cp) + { + if (!isspace((unsigned char) *cp)) + break; + cp++; + } + + /* + * Check for NaN + */ + if (tolower(*cp) == 'n' && tolower(*(cp+1)) == 'a' + && tolower(*(cp+2)) == 'n') + { + cp += 3; + /* Should be nothing left but spaces */ + while (*cp) + { + if (!isspace(*cp)) + { + return args->errorf(args, + "invalid input syntax for type numeric: '%s'", str); + } + cp++; + } + *dest = const_nan; + return 0; + } + + switch (*cp) + { + case '+': + sign = NUMERIC_POS; + cp++; + break; + + case '-': + sign = NUMERIC_NEG; + cp++; + break; + } + + if (*cp == '.') + { + have_dp = TRUE; + cp++; + } + + if (!isdigit((unsigned char) *cp)) + return args->errorf(args, + "invalid input syntax for type numeric: '%s'", str); + + decdigits = (unsigned char *) malloc(strlen(cp) + DEC_DIGITS * 2); + + /* leading padding for digit alignment later */ + memset(decdigits, 0, DEC_DIGITS); + i = DEC_DIGITS; + + while (*cp) + { + if (isdigit((unsigned char) *cp)) + { + decdigits[i++] = *cp++ - '0'; + if (!have_dp) + dweight++; + else + dscale++; + } + else if (*cp == '.') + { + if (have_dp) + { + free(decdigits); + return args->errorf(args, + "invalid input syntax for type numeric: '%s'", str); + } + + have_dp = TRUE; + cp++; + } + else + break; + } + + ddigits = i - DEC_DIGITS; + /* trailing padding for digit alignment later */ + memset(decdigits + i, 0, DEC_DIGITS - 1); + + /* Handle exponent, if any */ + if (*cp == 'e' || *cp == 'E') + { + long exponent; + char *endptr; + + cp++; + exponent = strtol(cp, &endptr, 10); + if (endptr == cp) + { + free(decdigits); + return args->errorf(args, + "invalid input syntax for type numeric: '%s'", str); + } + + cp = endptr; + if (exponent > NUMERIC_MAX_PRECISION || + exponent < -NUMERIC_MAX_PRECISION) + { + free(decdigits); + return args->errorf(args, + "invalid input syntax for type numeric: '%s'", str); + } + + dweight += (int) exponent; + dscale -= (int) exponent; + if (dscale < 0) + dscale = 0; + } + + /* Should be nothing left but spaces */ + while (*cp) + { + if (!isspace((unsigned char) *cp)) + { + free(decdigits); + return args->errorf(args, + "invalid input syntax for type numeric: '%s'", str); + } + cp++; + } + + /* + * Okay, convert pure-decimal representation to base NBASE. First we need + * to determine the converted weight and ndigits. offset is the number of + * decimal zeroes to insert before the first given digit to have a + * correctly aligned first NBASE digit. + */ + if (dweight >= 0) + weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1; + else + weight = -((-dweight - 1) / DEC_DIGITS + 1); + offset = (weight + 1) * DEC_DIGITS - (dweight + 1); + ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS; + + dest->digits = (NumericDigit *) malloc((ndigits) * sizeof(NumericDigit)); + dest->ndigits = ndigits; + dest->sign = sign; + dest->weight = weight; + dest->dscale = dscale; + + i = DEC_DIGITS - offset; + digits = dest->digits; + + while (ndigits-- > 0) + { + *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 + + decdigits[i + 2]) * 10 + decdigits[i + 3]; + i += DEC_DIGITS; + } + + free(decdigits); + + /* Strip any leading/trailing zeroes, and normalize weight if zero */ + strip_var(dest); + return 0; +} + +/* + * num2str() - + * + * Convert a var to text representation (guts of numeric_out). + * CAUTION: var's contents may be modified by rounding! + * returns -1 on error and 0 for success. + */ +static int +num2str(char *out, size_t outl, NumericVar *var, int dscale) +{ + //char *str; + char *cp; + char *endcp; + int i; + int d; + NumericDigit dig; + NumericDigit d1; + + /* + * Handle NaN + */ + if (var->sign == NUMERIC_NAN) { + strcpy(out, "NaN"); + return 0; + } + + if (dscale < 0) + dscale = 0; + + /* + * Check if we must round up before printing the value and do so. + */ + round_var(var, dscale); + + /* + * Allocate space for the result. + * + * i is set to to # of decimal digits before decimal point. dscale is the + * # of decimal digits we will print after decimal point. We may generate + * as many as DEC_DIGITS-1 excess digits at the end, and in addition we + * need room for sign, decimal point, null terminator. + */ + i = (var->weight + 1) * DEC_DIGITS; + if (i <= 0) + i = 1; + + if (outl <= (size_t) (i + dscale + DEC_DIGITS + 2)) + return -1; + + //str = palloc(i + dscale + DEC_DIGITS + 2); + //cp = str + cp = out; + + /* + * Output a dash for negative values + */ + if (var->sign == NUMERIC_NEG) + *cp++ = '-'; + + /* + * Output all digits before the decimal point + */ + if (var->weight < 0) + { + d = var->weight + 1; + *cp++ = '0'; + } + else + { + for (d = 0; d <= var->weight; d++) + { + dig = (d < var->ndigits) ? var->digits[d] : 0; + /* In the first digit, suppress extra leading decimal zeroes */ + { + int putit = (d > 0); + + d1 = dig / 1000; + dig -= d1 * 1000; + putit |= (d1 > 0); + if (putit) + *cp++ = (char) (d1 + '0'); + d1 = dig / 100; + dig -= d1 * 100; + putit |= (d1 > 0); + if (putit) + *cp++ = (char) (d1 + '0'); + d1 = dig / 10; + dig -= d1 * 10; + putit |= (d1 > 0); + if (putit) + *cp++ = (char) (d1 + '0'); + *cp++ = (char) (dig + '0'); + } + } + } + + /* + * If requested, output a decimal point and all the digits that follow it. + * We initially put out a multiple of DEC_DIGITS digits, then truncate if + * needed. + */ + if (dscale > 0) + { + *cp++ = '.'; + endcp = cp + dscale; + for (i = 0; i < dscale; d++, i += DEC_DIGITS) + { + dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0; + d1 = dig / 1000; + dig -= d1 * 1000; + *cp++ = (char) (d1 + '0'); + d1 = dig / 100; + dig -= d1 * 100; + *cp++ = (char) (d1 + '0'); + d1 = dig / 10; + dig -= d1 * 10; + *cp++ = (char) (d1 + '0'); + *cp++ = (char) (dig + '0'); + } + cp = endcp; + } + + /* + * terminate the string and return it + */ + *cp = '\0'; + return 0; +} + + diff --git a/source/src/param.c b/source/src/param.c new file mode 100644 index 0000000..78aa6af --- /dev/null +++ b/source/src/param.c @@ -0,0 +1,493 @@ + +/* + * param.c + * Management functions for the PGparam object. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +static int argsExpandBuffer(PGtypeArgs *args, int new_len); + +PGparam * +PQparamCreate(const PGconn *conn) +{ + PGparam *param; + PGtypeData *connData; + + PQseterror(NULL); + + if (!conn) + { + PQseterror("PGconn cannot be NULL"); + return NULL; + } + + param = (PGparam *) malloc(sizeof(PGparam)); + if (!param) + { + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + memset(param, 0, sizeof(PGparam)); + + connData = (PGtypeData *) PQinstanceData(conn, pqt_eventproc); + if (!connData) + { + PQparamClear(param); + PQseterror("No type data exists for PGconn at %p", conn); + return NULL; + } + + /* copy any handlers from conn object */ + if (connData->typhcnt > 0) + { + param->typhandlers = pqt_duphandlers( + connData->typhandlers, connData->typhcnt); + + if (!param->typhandlers) + { + PQparamClear(param); + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + param->typhcnt = connData->typhcnt; + } + + /* copy any typespecs from conn object */ + if (connData->typspeccnt > 0) + { + param->typspecs = pqt_dupspecs( + connData->typspecs, connData->typspeccnt); + + if (!param->typspecs) + { + PQparamClear(param); + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + param->typspeccnt = connData->typspeccnt; + } + + pqt_getfmtinfo(conn, ¶m->fmtinfo); + return param; +} + +PQT_EXPORT PGparam * +PQparamDup(PGparam *param) +{ + PGparam *new_param; + + PQseterror(NULL); + + if (!param) + { + PQseterror("PGparam to duplicate cannot be NULL"); + return NULL; + } + + new_param = (PGparam *) malloc(sizeof(PGparam)); + if (!new_param) + { + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + memset(new_param, 0, sizeof(PGparam)); + + /* copy any handlers from conn object */ + if (param->typhcnt > 0) + { + new_param->typhandlers = pqt_duphandlers( + param->typhandlers, param->typhcnt); + + if (!new_param->typhandlers) + { + PQparamClear(new_param); + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + new_param->typhcnt = param->typhcnt; + } + + /* copy any typespecs from conn object */ + if (param->typspeccnt > 0) + { + new_param->typspecs = pqt_dupspecs( + param->typspecs, param->typspeccnt); + + if (!new_param->typspecs) + { + PQparamClear(new_param); + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + new_param->typspeccnt = param->typspeccnt; + } + + memcpy(&new_param->fmtinfo, ¶m->fmtinfo, sizeof(PGtypeFormatInfo)); + + /* copy any values, don't bother if array is empty. */ + if (param->vcnt > 0) + { + int i; + + for (i=0; i < param->vcnt; i++) + { + int flags = 0; + PGvalue *val = ¶m->vals[i]; + + /* Is val->data is direct user pointer? If so, set pointer flag + * so pqt_putparam doesn't deep copy it. + */ + if (val->ptr != val->data) + flags |= TYPFLAG_POINTER; + + if (!pqt_putparam(new_param, val->data, val->datal, flags, + val->format, val->oid)) + { + PQparamClear(new_param); + return NULL; + } + } + } + + return new_param; +} + +int +PQparamCount(PGparam *param) +{ + if (param) + return param->vcnt; + return 0; +} + +void +PQparamReset(PGparam *param) +{ + if (param) + param->vcnt = 0; +} + +void +PQparamClear(PGparam *param) +{ + int i; + + if (!param) + return; + + /* vmax is the size of the vals array. We don't use vcnt because + * someone could of just called PQparamReset, leaving vcnt 0. If + * we find any value pointers that are not NULL, free'm. + */ + for (i=0; i < param->vmax; i++) + if (param->vals[i].ptr) + free(param->vals[i].ptr); + + if (param->vals) + free(param->vals); + + pqt_freehandlers(param->typhandlers, param->typhcnt); + pqt_freespecs(param->typspecs, param->typspeccnt); + + param->vmax = 0; + param->vcnt = 0; + param->vals = NULL; + param->typhcnt = 0; + param->typhandlers = NULL; + param->typspeccnt = 0; + param->typspecs = NULL; + + free(param); +} + +int +PQputf(PGparam *param, const char *format, ...) +{ + int r; + va_list ap; + + /* This function is just a wrapper to PQputvf */ + va_start(ap, format); + r = PQputvf(param, NULL, 0, format, ap); + va_end(ap); + + return r; +} + +int +PQputvf(PGparam *param, char *stmtBuf, size_t stmtBufLen, + const char *format, va_list ap) +{ + int n=0; + int flags; + size_t stmtPos = 0; + int save_vcnt; + int typpos = 0; + PGtypeHandler *h; + PGtypeArgs args; + char args_outbuf[4096]; + PGtypeSpec *spec = NULL; + + PQseterror(NULL); + + if (!param) + { + PQseterror("PGparam cannot be NULL"); + return FALSE; + } + + if (!format || !*format) + { + PQseterror("param 'format' cannot be NULL or an empty string"); + return FALSE; + } + + if (stmtBuf && stmtBufLen < 1) + { + PQseterror("Invalid argument: stmtBufLen must be >= 1"); + return FALSE; + } + + save_vcnt = param->vcnt; + va_copy(args.ap, ap); + + /* "@name" format, lookup typeSpec in cache */ + if(format && *format == '@') + { + + spec = pqt_getspec(param->typspecs, param->typspeccnt, format + 1); + + /* If we didn't find a type spec, this is an error. A format string + * with a '@' as its first character is reserved. + */ + if (!spec) + { + PQseterror("No such prepared specifier name: '%s'", format + 1); + return FALSE; + } + } + + while (format && *format) + { + if (spec) + { + /* done, no more handlers in cached spec string. */ + if (typpos == spec->idcnt) + break; + + h = pqt_gethandlerbyid(param->typhandlers, param->typhcnt, + spec->idlist[typpos]); + + /* should be an unusual, or a "will never happen", situation */ + if (!h) + { + va_end(args.ap); + PQseterror("Unknown type handler id at position %d", typpos+1); + param->vcnt = save_vcnt; + return FALSE; + } + + flags = (int) spec->flags[typpos]; + typpos++; + } + else + { + format = pqt_parse(format, param->typhandlers, param->typhcnt, + stmtBuf, stmtBufLen, &h, &stmtPos, &typpos, &flags); + + if (!format) + { + param->vcnt = save_vcnt; + return FALSE; + } + + if (!h) + continue; + } + + args.is_put = 1; + args.put.param = param; + args.fmtinfo = ¶m->fmtinfo; + args.put.out = args_outbuf; + args.put.__allocated_out = NULL; + args.put.outl = (int) sizeof(args_outbuf); + args.is_ptr = (flags & TYPFLAG_POINTER) ? 1 : 0; + args.format = BINARYFMT; + args.put.expandBuffer = argsExpandBuffer; + args.typpos = typpos; + args.typhandler = h; + args.errorf = pqt_argserrorf; + args.super = pqt_argssuper; + *args.put.out = 0; + + if (flags & TYPFLAG_ARRAY) + n = pqt_put_array(&args); + else + n = h->typput(&args); + + if (n == -1) + { + if (args.put.__allocated_out && args.put.__allocated_out != args_outbuf) + free(args.put.__allocated_out); + param->vcnt = save_vcnt; + return FALSE; + } + + if (args.put.out == NULL) + { + args.format = BINARYFMT; + n = -1; + } + + n = pqt_putparam(param, args.put.out, n, flags, args.format, + (flags & TYPFLAG_ARRAY) ? h->typoid_array : h->typoid); + + if (args.put.__allocated_out && args.put.__allocated_out != args_outbuf) + free(args.put.__allocated_out); + + if (!n) + { + param->vcnt = save_vcnt; + return FALSE; + } + } + + if (stmtBuf) + stmtBuf[stmtPos] = 0; + + return TRUE; +} + + +/* ---------------------------- + * Helper functions + */ + +int +pqt_putparam(PGparam *param, const void *data, int datal, + int flags, int format, Oid typoid) +{ + PGvalue *v; + + if (!param) + return FALSE; + + if (!data) + datal = -1; + + /* need to grow param vals array */ + if (param->vcnt == param->vmax) + { + PGvalue *vals; + int vmax = param->vmax ? (param->vmax * 3) / 2 : 16; + + vals = (PGvalue *) pqt_realloc(param->vals, sizeof(PGvalue) * vmax); + if (!vals) + { + PQseterror(PQT_OUTOFMEMORY); + return FALSE; + } + + /* zero out the new array elements */ + memset(vals + param->vcnt, 0, (vmax - param->vcnt) * sizeof(PGvalue)); + param->vmax = vmax; + param->vals = vals; + } + + /* grab next param value */ + v = ¶m->vals[param->vcnt]; + + if (datal == -1) + { + v->data = NULL; + } + else if (datal == 0) + { + /* BUG FIX: allows putting empty strings in binary mode. Without this, + * empty strings would be converted to an SQL NULL. + * Reported by: Dmitry Epstein + */ + static char zero[1] = {0}; + v->data = zero; + } + /* wants to put a direct pointer */ + else if (flags & TYPFLAG_POINTER) + { + v->data = (char *) data; + } + else + { + /* need more mem for param value ptr */ + if (v->ptrl < datal) + { + char *ptr = (char *) pqt_realloc(v->ptr, datal); + + if (!ptr) + { + PQseterror(PQT_OUTOFMEMORY); + return FALSE; + } + + v->ptrl = datal; + v->ptr = ptr; + } + + memcpy(v->ptr, data, datal); + v->data = v->ptr; + } + + v->datal = datal; + v->format = format; + v->oid = typoid; + param->vcnt++; + return TRUE; +} + +/* returns 0 on success and -1 on error */ +static int +argsExpandBuffer(PGtypeArgs *args, int new_len) +{ + char *new_out; + + if (new_len <= args->put.outl) + return 0; + + if (!args->put.__allocated_out) + { + new_out = (char *) malloc(new_len); + if (!new_out) + return args->errorf(args, PQT_OUTOFMEMORY); + + /* fully copy existing stack buffer, we don't know what data + * the user has already written and may want to keep. + */ + memcpy(new_out, args->put.out, args->put.outl); + } + else + { + new_out = (char *) realloc(args->put.__allocated_out, new_len); + if (!new_out) + return args->errorf(args, PQT_OUTOFMEMORY); + } + + args->put.out = args->put.__allocated_out = new_out; + args->put.outl = new_len; + return 0; +} + + + + + diff --git a/source/src/port.c b/source/src/port.c new file mode 100644 index 0000000..c11a80e --- /dev/null +++ b/source/src/port.c @@ -0,0 +1,587 @@ + +/* + * port.c + * Portability functions. Some of these functions are drop-ins for + * systems missing them and others just centralize differences. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +#if defined(__MINGW32__) || defined(__CYGWIN__) +# define HAVE_VSNPRINTF +#endif + +int +pqt_snprintf(char *buf, size_t size, const char *format, ...) +{ + int n; + va_list ap; + va_start(ap, format); + n = pqt_vsnprintf(buf, size, format, ap); + va_end(ap); + return n; +} + +int +pqt_vsnprintf(char *buf, size_t size, const char *format, va_list ap) +{ + int n; + +#ifdef PQT_MSVC +# if PQT_MSVC >= 1400 + /* MSVC 8 */ + n = _vsnprintf_s(buf, size, size-1, format, ap); +# else + /* MSVC 6 or 7 */ + n = _vsnprintf(buf, size, format, ap); +# endif + +#elif defined(HAVE_VSNPRINTF) + /* All other platforms, including MinGW and Cygwin. */ + n = vsnprintf(buf, size, format, ap); +#else + /* Some platforms don't have the buffer-safe version */ + n = vsprintf(buf, format, ap); +#endif + + if (n > -1 && (size_t) n < size) + return n; + + /* Although some implementations return "required" buf size, this + * always return -1 to keep things consistent for caller. + */ + return -1; +} + +#if defined(HAVE_CONFIG_H) && (!defined(HAVE_STRTOL) || \ + !defined(HAVE_STRTOUL)) + +static unsigned long string2long(const char *nptr, char **endptr, + int base, int is_signed); + +#ifndef HAVE_STRTOL +long +strtol(const char *nptr, char **endptr, int base) +{ + return (signed long) string2long(nptr, endptr, base, 1); +} +#endif + +#ifndef HAVE_STRTOUL +unsigned long +strtoul(const char *nptr, char **endptr, int base) +{ + return (unsigned long) string2long(nptr, endptr, base, 0); +} +#endif + +#define between(a, c, z) \ + ((unsigned) ((c) - (a)) <= (unsigned) ((z) - (a))) + +static unsigned long +string2long(const char *nptr, char ** const endptr, + int base, int is_signed) +{ + unsigned int v; + unsigned long val = 0; + int c; + int ovfl = 0, sign = 1; + const char *startnptr = nptr, *nrstart; + + if (endptr) + *endptr = (char *) nptr; + + while (isspace(*nptr)) + nptr++; + c = *nptr; + + if (c == '-' || c == '+') + { + if (c == '-') + sign = -1; + nptr++; + } + nrstart = nptr; /* start of the number */ + + /* When base is 0, the syntax determines the actual base */ + if (base == 0) + { + if (*nptr == '0') + { + if (*++nptr == 'x' || *nptr == 'X') + { + base = 16; + nptr++; + } + else + { + base = 8; + } + } + else + { + base = 10; + } + } + else if (base==16 && *nptr=='0' && (*++nptr =='x' || *nptr =='X')) + { + nptr++; + } + + for (;;) + { + c = *nptr; + if (between('0', c, '9')) + v = c - '0'; + else if (between('a', c, 'z')) + v = c - 'a' + 0xa; + else if (between('A', c, 'Z')) + v = c - 'A' + 0xA; + else + break; + + if (v >= base) + break; + if (val > (ULONG_MAX - v) / base) + ovfl++; + + val = (val * base) + v; + nptr++; + } + + if (endptr) + { + if (nrstart == nptr) + *endptr = (char *) startnptr; + else + *endptr = (char *) nptr; + } + + if (!ovfl) + { + /* Overflow is only possible when converting a signed long. */ + if (is_signed && ((sign < 0 && val > -(unsigned long) LONG_MIN) + || (sign > 0 && val > LONG_MAX))) + ovfl++; + } + + if (ovfl) + { + errno = ERANGE; + if (is_signed) + { + if (sign < 0) + return LONG_MIN; + else + return LONG_MAX; + } + else + { + return ULONG_MAX; + } + } + + return (long) sign * val; +} + +#endif /* !strtol || !strtoul */ + + +/* Non-windows platforms that don't have strtoll */ +#if defined(HAVE_CONFIG_H) && !defined(HAVE_STRTOLL) + +#define MIN_INT64 (-MAX_INT64 - PQT_INT64CONST(1)) +#define MAX_INT64 PQT_INT64CONST(9223372036854775807) + +/* no locale support */ +long long int +strtoll(const char *nptr, char **endptr, int base) +{ + const char *s; + /* LONGLONG */ + long long int acc, cutoff; + int c; + int neg, any, cutlim; + + /* endptr may be NULL */ + +#ifdef __GNUC__ + /* This outrageous construct just to shut up a GCC warning. */ + (void) &acc; (void) &cutoff; +#endif + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = (unsigned char) *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for long longs is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? MIN_INT64 : MAX_INT64; + cutlim = (int) (cutoff % base); + cutoff /= base; + if (neg) { + if (cutlim > 0) { + cutlim -= base; + cutoff += 1; + } + cutlim = -cutlim; + } + for (acc = 0, any = 0;; c = (unsigned char) *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0) + continue; + if (neg) { + if (acc < cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + acc = MIN_INT64; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc -= c; + } + } else { + if (acc > cutoff || (acc == cutoff && c > cutlim)) { + any = -1; + acc = MAX_INT64; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc += c; + } + } + } + if (endptr != 0) + /* LINTED interface specification */ + *endptr = (char *) (any ? s - 1 : nptr); + return (acc); +} + +#endif /* !HAVE_STRTOLL */ + + +/* Non-windows machines missing getaddrinfo (postgres's port) */ +#if defined(__CYGWIN__) || (defined(HAVE_CONFIG_H) && \ + !defined(HAVE_GETADDRINFO)) +#undef FRONTEND +#include +#include +#include +#include + +#include "getaddrinfo.h" + +extern int h_errno; + +/* + * get address info for ipv4 sockets. + * + * Bugs: - only one addrinfo is set even though hintp is NULL or + * ai_socktype is 0 + * - AI_CANONNAME is not supported. + * - servname can only be a number, not text. + */ +int +getaddrinfo(const char *node, const char *service, + const struct addrinfo * hintp, + struct addrinfo ** res) +{ + struct addrinfo *ai; + struct sockaddr_in sin, + *psin; + struct addrinfo hints; + + if (hintp == NULL) + { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + } + else + memcpy(&hints, hintp, sizeof(hints)); + + if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) + return EAI_FAMILY; + + if (hints.ai_socktype == 0) + hints.ai_socktype = SOCK_STREAM; + + if (!node && !service) + return EAI_NONAME; + + memset(&sin, 0, sizeof(sin)); + + sin.sin_family = AF_INET; + + if (node) + { + if (node[0] == '\0') + sin.sin_addr.s_addr = htonl(INADDR_ANY); + else if (hints.ai_flags & AI_NUMERICHOST) + { + if (!inet_aton(node, &sin.sin_addr)) + return EAI_FAIL; + } + else + { + struct hostent *hp; + +#ifdef FRONTEND + struct hostent hpstr; + char buf[BUFSIZ]; + int herrno = 0; + + pqGethostbyname(node, &hpstr, buf, sizeof(buf), + &hp, &herrno); +#else + hp = gethostbyname(node); +#endif + if (hp == NULL) + { + switch (h_errno) + { + case HOST_NOT_FOUND: + case NO_DATA: + return EAI_NONAME; + case TRY_AGAIN: + return EAI_AGAIN; + case NO_RECOVERY: + default: + return EAI_FAIL; + } + } + if (hp->h_addrtype != AF_INET) + return EAI_FAIL; + + memcpy(&(sin.sin_addr), hp->h_addr, hp->h_length); + } + } + else + { + if (hints.ai_flags & AI_PASSIVE) + sin.sin_addr.s_addr = htonl(INADDR_ANY); + else + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + } + + if (service) + sin.sin_port = htons((unsigned short) atoi(service)); + +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN + sin.sin_len = sizeof(sin); +#endif + + ai = malloc(sizeof(*ai)); + if (!ai) + return EAI_MEMORY; + + psin = malloc(sizeof(*psin)); + if (!psin) + { + free(ai); + return EAI_MEMORY; + } + + memcpy(psin, &sin, sizeof(*psin)); + + ai->ai_flags = 0; + ai->ai_family = AF_INET; + ai->ai_socktype = hints.ai_socktype; + ai->ai_protocol = hints.ai_protocol; + ai->ai_addrlen = sizeof(*psin); + ai->ai_addr = (struct sockaddr *) psin; + ai->ai_canonname = NULL; + ai->ai_next = NULL; + + *res = ai; + + return 0; +} + + +void +freeaddrinfo(struct addrinfo * res) +{ + if (res) + { + if (res->ai_addr) + free(res->ai_addr); + free(res); + } +} + + +const char * +gai_strerror(int errcode) +{ +#ifdef HAVE_HSTRERROR + int hcode; + + switch (errcode) + { + case EAI_NONAME: + hcode = HOST_NOT_FOUND; + break; + case EAI_AGAIN: + hcode = TRY_AGAIN; + break; + case EAI_FAIL: + default: + hcode = NO_RECOVERY; + break; + } + + return hstrerror(hcode); +#else /* !HAVE_HSTRERROR */ + + switch (errcode) + { + case EAI_NONAME: + return "Unknown host"; + case EAI_AGAIN: + return "Host name lookup failure"; + /* Errors below are probably WIN32 only */ +#ifdef EAI_BADFLAGS + case EAI_BADFLAGS: + return "Invalid argument"; +#endif +#ifdef EAI_FAMILY + case EAI_FAMILY: + return "Address family not supported"; +#endif +#ifdef EAI_MEMORY + case EAI_MEMORY: + return "Not enough memory"; +#endif +#ifdef EAI_NODATA +#ifndef WIN32_ONLY_COMPILER /* MSVC complains because another case has the + * same value */ + case EAI_NODATA: + return "No host data of that type was found"; +#endif +#endif +#ifdef EAI_SERVICE + case EAI_SERVICE: + return "Class type not found"; +#endif +#ifdef EAI_SOCKTYPE + case EAI_SOCKTYPE: + return "Socket type not supported"; +#endif + default: + return "Unknown server error"; + } +#endif /* HAVE_HSTRERROR */ +} + +/* + * Convert an ipv4 address to a hostname. + * + * Bugs: - Only supports NI_NUMERICHOST and NI_NUMERICSERV + * It will never resolv a hostname. + * - No IPv6 support. + */ +int +getnameinfo(const struct sockaddr * sa, int salen, + char *node, int nodelen, + char *service, int servicelen, int flags) +{ + /* Invalid arguments. */ + if (sa == NULL || (node == NULL && service == NULL)) + return EAI_FAIL; + + /* We don't support those. */ + if ((node && !(flags & NI_NUMERICHOST)) + || (service && !(flags & NI_NUMERICSERV))) + return EAI_FAIL; + +#if defined(HAVE_IPV6) || defined(AF_INET6) + if (sa->sa_family == AF_INET6) + return EAI_FAMILY; +#endif + + if (node) + { + int ret = -1; + + if (sa->sa_family == AF_INET) + { + char *p; + + p = inet_ntoa(((struct sockaddr_in *) sa)->sin_addr); + ret = pqt_snprintf(node, nodelen, "%s", p); + } + if (ret == -1) + return EAI_MEMORY; + } + + if (service) + { + int ret = -1; + + if (sa->sa_family == AF_INET) + { + ret = pqt_snprintf(service, servicelen, "%d", + ntohs(((struct sockaddr_in *) sa)->sin_port)); + } + if (ret == -1) + return EAI_MEMORY; + } + + return 0; +} + +#endif /* HAVE_GETADDRINFO */ + + diff --git a/source/src/record.c b/source/src/record.c new file mode 100644 index 0000000..4088962 --- /dev/null +++ b/source/src/record.c @@ -0,0 +1,164 @@ + +/* + * record.c + * Type handler for the record/composite data type. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +int +pqt_put_record(PGtypeArgs *args) +{ + int i; + int len; + char *out; + PGparam *param = va_arg(args->ap, PGparam *); + + PUTNULLCHK(args, param); + + /* watch for invalidation issues */ + if (param->vcnt > args->typhandler->nattrs) + return args->errorf(args, + "param value count is %d but server says it's %d", + param->vcnt, args->typhandler->nattrs); + + /* Auto-fill the remaining fields with SQL NULLs. This feature was + * added because it was needed (by eSilo). We had a few cases where + * we needed to append new fields to existing composites but wanted + * to maintain backwards compatibility ... so some_func(mycomposite) + * would continue to work even for older versions unaware of the + * new composite fields. I guess for some this is unwanted behavior, + * but I think the cases for it are much more common. + */ + if (param->vcnt < args->typhandler->nattrs) + { + int nattrs = args->typhandler->nattrs - param->vcnt; + for (i=0; i < nattrs; i++) + pqt_putparam(param, NULL, 0, 0, BINARYFMT, + args->typhandler->attDescs[param->vcnt].attoid); + } + + /* column count, 4-byte integer */ + len = 4; + + /* determine total byte count to ensure args->put.out is large enough */ + for (i=0; i < param->vcnt; i++) + { + len += (4 + 4); /* oid + len */ + + if (param->vals[i].datal > 0) + len += param->vals[i].datal; + } + + /* ensure out buffer is large enough */ + if (args->put.expandBuffer(args, len) == -1) + return -1; + + out = args->put.out; + + /* write column count */ + pqt_buf_putint4(out, param->vcnt); + out += 4; + + for (i=0; i < param->vcnt; i++) + { + if (param->vals[i].format == 0) + return args->errorf(args, + "Cannot put composite attributes in text format"); + + if (param->vals[i].datal == NULL_LEN) + param->vals[i].oid = args->typhandler->attDescs[i].attoid; + + /* watch for invalidation issues */ + if (param->vals[i].oid != args->typhandler->attDescs[i].attoid) + return args->errorf(args, + "param value OID is %u but server says it's %u", + param->vals[i].oid, args->typhandler->attDescs[i].attoid); + + /* write column oid */ + pqt_buf_putint4(out, param->vals[i].oid); + out += 4; + + /* write column data length */ + pqt_buf_putint4(out, param->vals[i].datal); + out += 4; + + /* write the column data */ + if (param->vals[i].data && param->vals[i].datal > 0) + { + memcpy(out, param->vals[i].data, param->vals[i].datal); + out += param->vals[i].datal; + } + } + + return len; +} + +int +pqt_get_record(PGtypeArgs *args) +{ + int i; + int nattrs; + int vlen; + Oid server_oid; + DECLVALUE(args); + PGresult *res; + PGresult **resultp = va_arg(args->ap, PGresult **); + + CHKGETVALS(args, resultp); + + if (args->format == TEXTFMT) + return args->errorf(args, "record does not support text results"); + + /* get record column count, numAttributes */ + nattrs = pqt_buf_getint4(value); + value += 4; + + /* watch for invalidation issues */ + if (args->typhandler->nattrs != nattrs) + return args->errorf(args, + "type handler attribute count is %d but server says it's %d", + args->typhandler->nattrs, nattrs); + + if (!(res = pqt_copyresult(args, nattrs))) + RERR_MEM(args); + + for (i=0; i < nattrs; i++) + { + /* watch for invalidation issues */ + server_oid = (Oid) pqt_buf_getint4(value); + if (server_oid != args->typhandler->attDescs[i].attoid) + { + args->errorf(args, + "type handler attribute OID is %u but server says it's %u", + args->typhandler->attDescs[i].attoid, server_oid); + PQclear(res); + return -1; + } + + /* move past Oid */ + value += 4; + + /* get value length */ + vlen = pqt_buf_getint4(value); + value += 4; + + if (!PQsetvalue(res, 0, i, value, vlen)) + { + PQclear(res); + return -1; + } + + if (vlen > 0) + value += vlen; + } + + *resultp = res; + return 0; +} + diff --git a/source/src/regression-test.c b/source/src/regression-test.c new file mode 100644 index 0000000..e8845bb --- /dev/null +++ b/source/src/regression-test.c @@ -0,0 +1,1373 @@ + +#ifdef HAVE_CONFIG_H +# include "pqt_config.h" +#endif + +#define PLN do{ \ + printf("%s:%d\n", __FUNCTION__, __LINE__); \ + fflush(stdout); \ +}while(0) + +#if defined(_WIN32) || defined(_WIN64) +# define _CRT_SECURE_NO_WARNINGS /* shut up msvc8! */ +# ifdef _MSC_VER +# pragma warning (disable : 4127 4706) +# endif +# include +# include /* getnameinfo */ +# ifdef _MSC_VER +# define I64FMT "%I64d" +# else +# define I64FMT "%lld" +# endif +#else +# define SIGNAL_SUPPORT +# include +# include +# include +# include +# define I64FMT "%lld" +#endif + +#ifdef SIGNAL_SUPPORT +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef LLONG_MAX +# ifdef LONG_LONG_MAX +# define LLONG_MAX LONG_LONG_MAX +# else +# define LLONG_MAX 9223372036854775807LL +# endif +#endif + +#ifndef LLONG_MIN +# ifdef LONG_LONG_MIN +# define LLONG_MIN LONG_LONG_MIN +# else +# define LLONG_MIN -9223372036854775808LL +# endif +#endif + +#define RESERR PQresultErrorMessage(result) +#define CLEAR_TABLE(tname) PQclear(PQexec(conn, "TRUNCATE " tname)) +#define DROP_TABLE(tname) \ + PQclear(PQexec(conn, "DROP TABLE IF EXISTS " tname)) + +#define EXECOKAY(msg, status) do{ \ + if (PQresultStatus(result) != (status)) \ + { \ + fprintf(stderr, " **ERROR: %s - %s\n", msg, RESERR); \ + PQclear(result); \ + failcnt++; \ + return; \ + } \ +}while (0) + +#define CMDOKAY(msg) EXECOKAY(msg, PGRES_COMMAND_OK) +#define TUPSOKAY(msg) EXECOKAY(msg, PGRES_TUPLES_OK) + +#define PUTOKAY(paramobj, retval, msg) do{ \ + if ((retval) == 0){ \ + failcnt++; \ + fprintf(stderr, " **ERROR: %s - %s\n", msg, PQgeterror()); \ + return; \ + } \ +}while (0) + +#define GETOKAY(retval, msg) GETOKAY2(result, retval, msg) +#define GETOKAY2(_res, retval, msg) do{ \ + if ((retval) == 0){ \ + failcnt++; \ + fprintf(stderr, " **ERROR: %s - %s\n", msg, PQgeterror()); \ + PQclear(result); \ + return; \ + } \ +}while (0) + +#define CHKNUM(typspec, getval, putval) do{ \ + if ((getval) != (putval)) { \ + failcnt++; \ + fprintf(stderr, " %s - FAILED\n", typspec); \ + } \ + else \ + printf(" %s - passed\n", typspec); \ + testcnt++; \ +} while (0) + +#define CHKGEO(type) do{ \ + const char *typspec = "%" # type; \ + if (memcmp(& type, & type ## val, sizeof(type))) { \ + failcnt++; \ + fprintf(stderr, " %s - FAILED\n", typspec); \ + } \ + else \ + printf(" %s - passed\n", typspec); \ + testcnt++; \ +} while (0) + +#define CHKVLEN(typ, resval, inval) do{ \ + testcnt++; \ + if (strcmp(resval, inval)) { \ + failcnt++; \ + fprintf(stderr, " %%" typ " - FAILED\n"); \ + } \ + else \ + printf(" %%" typ " - passed\n"); \ +}while (0) + +static void cleanup(void); +static void test_natives(int format); +static void test_composite(void); +static void test_geometrics(int format); +static void test_varlen(int format); +static void test_datetime(int format); +static void test_network(int format); +static int epoch_put(PGtypeArgs *args); +static int epoch_get(PGtypeArgs *args); +static void test_subclass(int format); +static PGresult *execf(const char *cmdSpec, ...); +static int bpcharcmp(const char *put, const char *get, int charlen); + +#ifdef SIGNAL_SUPPORT +static void sighandler(int s); +#endif + +static void _notice_processor(void *arg, const char *message) +{/* do nothing */ + arg = NULL; + message = NULL; +} + + +static int testcnt = 0; +static int failcnt = 0; +static const char *datestyle = ""; +static PGconn *conn = NULL; +static PGparam *param = NULL; +static PGresult *result = NULL; + +#define ALIGN_NUM(val, mult) (((val) + ((mult) - 1)) & ~(((mult) - 1))) + +int main(int argc, char **argv) +{ + PGint4 n; + PGregisterType regtype; + char *conninfo = argc > 1 ? argv[1] : "hostaddr=127.0.0.1 user=postgres"; + + conn = PQconnectdb(conninfo); + if (PQstatus(conn) != CONNECTION_OK) + { + fprintf(stderr, "connection failure: %s\n", PQerrorMessage(conn)); + return 1; + } + + PQsetNoticeProcessor(conn, _notice_processor, NULL); + + if (!PQinitTypes(conn)) + { + fprintf(stderr, "Failed to initialize libpqtypes as " + "a libpq event proc\n"); + PQfinish(conn); + return 1; + } + + testcnt++; + regtype.typname = "bad_type"; + if(PQregisterTypes(conn, PQT_COMPOSITE, ®type, 1, 0)) + { + failcnt++; + fprintf(stderr, "Test bad type register failure case (FAILED)\n"); + } + + regtype.typname = "mytype_t"; + if(!PQregisterTypes(conn, PQT_COMPOSITE, ®type, 1, 0)) + fprintf(stderr, "%s\n", PQgeterror()); + + test_composite(); + + PQclear(PQexec(conn, "SET DateStyle TO 'ISO'")); + param = PQparamCreate(conn); + + /* test PQputvf - result should be 10 */ + testcnt++; + printf("\nPQputvf\n"); + result = execf("SELECT %int4 + (%int4 % %int4) AS answer", 9, 67, 3); + if (PQresultStatus(result) != PGRES_TUPLES_OK) + { + fprintf(stderr, " **ERROR: PQputvf - %s\n", PQgeterror()); + PQclear(result); + failcnt++; + return 1; + } + + PQgetf(result, 0, "#int4", "answer", &n); + PQclear(result); + if (n != 10) + { + failcnt++; + fprintf(stderr, " PQputvf - FAILED\n"); + } + else + { + printf(" PQputvf - passed\n"); + } + + testcnt++; + printf("\nPQspecPrepare\n"); + if(!PQspecPrepare(conn, "test", "SELECT %int8 + %int4", 1)) + { + failcnt++; + fprintf(stderr, " PQspecPrepare - FAILED (%s)\n", PQgeterror()); + } + else + { + char data[4]; + PGbytea ba; + PGint8 i8 = 45; + ba.len = 4; + ba.data = data; + + result = PQexecf(conn, "@test", i8, 4); + if(!result) + { + failcnt++; + fprintf(stderr, " PQspecPrepare - FAILED (%s)\n", PQgeterror()); + } + else + { + PGint8 i8out=0; + + PQgetf(result, 0, "%int8", 0, &i8out); + + if(i8 + 4 != i8out) + { + failcnt++; + fprintf(stderr, " PQspecPrepare - FAILED (expected " + "%lld but got %lld)\n", i8+4, i8out); + } + else + { + printf(" PQspecPrepare - passed\n"); + } + + PQclear(result); + } + } + + datestyle = PQparameterStatus(conn, "DateStyle"); + if (!datestyle) + datestyle = ""; + +#ifdef SIGNAL_SUPPORT + signal(SIGINT, sighandler); + signal(SIGILL, sighandler); + signal(SIGSEGV, sighandler); +# ifdef SIGFPE + signal(SIGFPE, sighandler); +# endif +# ifdef SIGBUS + signal(SIGBUS, sighandler); +# endif +#endif + + + test_natives(0); + test_natives(1); + test_varlen(0); + test_varlen(1); + test_geometrics(0); + test_geometrics(1); + test_network(0); + test_network(1); + + regtype.typname = "libpq.epoch=pg_catalog.timestamptz"; + regtype.typput = epoch_put; + regtype.typget = epoch_get; + + /* Test type sub-classing, use the epoch example from docs */ + if (!PQregisterTypes(conn, PQT_SUBCLASS, ®type, 1, 0)) + { + fprintf(stderr, "PQregisterTypes(epoch, subclass): %s\n", + PQerrorMessage(conn)); + } + else + { + test_subclass(0); + test_subclass(1); + } + + test_datetime(0); + test_datetime(1); + + /* datestyle is cached in PGparam. Since we need to change the datestyle, + * we destroy the current param and recreate it later. + */ + PQparamClear(param); + + /* Just tested ISO, test a non-ISO */ + PQclear(PQexec(conn, "SET DateStyle TO 'POSTGRES'")); + datestyle = PQparameterStatus(conn, "DateStyle"); + if (!datestyle) + datestyle = ""; + + param = PQparamCreate(conn); + test_datetime(0); + test_datetime(1); + cleanup(); + + printf("\nRan %d tests - %d failed\n", testcnt, failcnt); + return 1; +} + +/* Calls putf and executes cmdSpec. Returns a result object */ +static PGresult *execf(const char *cmdSpec, ...) +{ + int n; + PGresult *res; + va_list ap; + char stmt[4096]; + PGparam *prm = PQparamCreate(conn); + + va_start(ap, cmdSpec); + n = PQputvf(prm, stmt, sizeof(stmt), cmdSpec, ap); + va_end(ap); + + /* error message in PQparamErrorMessage */ + if (!n) + { + PQparamClear(prm); + return NULL; + } + + printf(" %s\n", stmt); + res = PQparamExec(conn, prm, stmt, 1); + PQparamClear(prm); + return res; +} + +/* Handle BPCHAR (Blank-Padded) SQL-type "character(n)" */ +static int bpcharcmp(const char *put, const char *get, int charlen) +{ + int i; + int len = (int)strlen(put); + + for (i=len; i < charlen; i++) + if (!isspace(get[i])) + return 1; + + return memcmp(put, get, len); +} + +static void cleanup(void) +{ + DROP_TABLE("libpq_natives"); + DROP_TABLE("libpq_varlen"); + DROP_TABLE("libpq_geos"); + DROP_TABLE("libpq_network"); + DROP_TABLE("libpq_datetime"); + DROP_TABLE("libpq_subclass"); + DROP_TABLE("libpq_composite"); + PQclear(PQexec(conn, "DROP TYPE complex")); + PQclear(PQexec(conn, "DROP TYPE simple")); + PQparamClear(param); + PQfinish(conn); +} + +/* make an effort to clean up */ +#ifdef SIGNAL_SUPPORT +static void sighandler(int s) +{ + cleanup(); + fprintf(stderr, "\n**Caught signal: %d ... aborting\n", s); + exit(1); +} +#endif + +static void test_composite(void) +{ + int i,x,r; + int ntups; + int inttups; + PGtext text; + PGparam *simple; + PGparam *complex; + PGparam *prm; + PGresult *simple_res; + PGarray intarr; + PGarray comparr; + PGchar buf[64]; + PGint4 a; + PGint8 b; + PGregisterType types[] = { + {"public.simple", NULL, NULL}, + {"public.complex", NULL, NULL} + }; + + printf("\nComposites & Arrays: (always binary)\n"); + + printf(" Testing empty array handling "); + PQclear(PQexec(conn, "DROP TABLE libpq_array")); + result = PQexec(conn, "CREATE TABLE libpq_array (arr int[])"); + CMDOKAY("creating libpq_array table:"); + PQclear(result); + + result = PQexec(conn, "INSERT INTO libpq_array VALUES ('{}')"); + CMDOKAY("inserting into libpq_array:"); + PQclear(result); + + result = PQparamExec(conn, NULL, "SELECT * FROM libpq_array", 1); + TUPSOKAY("executing select on libpq_array:"); + + r = PQgetf(result, 0, "%int4[]", 0, &intarr); + + GETOKAY(r, "Failed to get an empty array"); + PQclear(result); + + /* both values should be 0 */ + testcnt++; + if(PQntuples(intarr.res) != 0 || intarr.ndims != 0) + { + fprintf(stderr, "- FAILED\n ***ERROR: tuple and dimension " + "count should both be zero - ntups=%d, ndims=%d\n", + PQntuples(intarr.res), intarr.ndims); + failcnt++; + } + else + { + printf("- passed\n"); + } + PQclear(intarr.res); + + DROP_TABLE("libpq_composite"); + PQclear(PQexec(conn, "DROP TYPE public.complex")); + + PQclear(PQexec(conn, "DROP TYPE public.simple")); + result = PQexec(conn, "CREATE TYPE simple AS (a int4, b int8)"); + CMDOKAY("creating simple type"); + PQclear(result); + + result = PQexec(conn, "CREATE TYPE complex AS (t text, s simple, " + "arr int4[][])"); + CMDOKAY("creating complex type"); + PQclear(result); + + if (!PQregisterTypes(conn, PQT_COMPOSITE, types, 2, 0)) + { + fprintf(stderr, " **ERROR: PQregisterTypes(%s %s): %s\n", + types[0].typname, types[1].typname, PQgeterror()); + failcnt++; + return; + } + + result = PQexec(conn, "CREATE TABLE libpq_composite (comparr complex[])"); + CMDOKAY("creating libpq_composite table:"); + PQclear(result); + + simple = PQparamCreate(conn); + complex = PQparamCreate(conn); + prm = PQparamCreate(conn); + + /* array[10][3] */ + intarr.ndims = 2; + intarr.dims[0] = 10; + intarr.dims[1] = 3; + intarr.lbound[0] = 1; + intarr.lbound[1] = 1; + intarr.param = PQparamCreate(conn); + + /* If a 1D array is being used, you can avoid setting the dimension + * members of the PGarray structure by zeroing it. + */ + memset(&comparr, 0, sizeof(PGarray)); + comparr.param = PQparamCreate(conn); + + /* generate a complex[] containing 100 elements */ + for (i=0; i < 100; i++) + { + PGint8 val = ((PGint8)1<<48) + (PGint8)i; + + /* pack the fields of the 'simple' composite */ + r = PQputf(simple, "%int4 %int8", i+1000000, val); + PUTOKAY(simple, r, "putting simple attributes"); + + /* populate the complex.arr[10][3] */ + PQputf(intarr.param, "%null"); + for (x=1; x < 30; x++) + { + r= PQputf(intarr.param, "%int4", x+1); + PUTOKAY(intarr.param, r, "putting complex.arr element"); + } + + /* pack the fields of the 'complex' composite */ + sprintf((char *) buf, "text_%03d", i+1); + r = PQputf(complex, "%text %simple %int4[]", buf, simple, &intarr); + PUTOKAY(complex, r, "putting complex attributes"); + + /* now put element 'i' into the composite array */ + r = PQputf(comparr.param, "%complex", complex); + PUTOKAY(comparr.param, r, "putting complex[] element"); + + /* make sure to reset the params, otherwise you will continue to + * append parameters to below params. DO NOT reset the comparr.param, + * as this is the array we want to insert. + */ + PQparamReset(simple); + PQparamReset(intarr.param); + PQparamReset(complex); + + /* sneak in a NULL element. NULL composite array items + * used to be a bug. + */ + if(i == 49) + { + PQputf(comparr.param, "%complex", NULL); + i++; + } + } + + /* insert the complex[] */ + PQputf(prm, "%complex[]", &comparr); + result = PQparamExec(conn, prm, + "INSERT INTO libpq_composite VALUES ($1)", 1); + CMDOKAY("inserting into libpq_composite"); + PQclear(result); + + /* clear all params (order doesn't matter, they are + * isolated structures) + */ + PQparamClear(simple); + PQparamClear(intarr.param); + PQparamClear(complex); + PQparamClear(comparr.param); + PQparamClear(prm); + + /* select complex[] back out */ + result = PQparamExec(conn, NULL, "SELECT * FROM libpq_composite", 1); + TUPSOKAY("PQparamExec(SELECT:composite[])"); + + /* getf it into a PGarray */ + r = PQgetf(result, 0, "%complex[]", 0, &comparr); + GETOKAY(r, "PQgetf(complex[])"); + PQclear(result); + + /* composite arrays come back 1 tuple per element and 1 + * field per attribute + */ + ntups = PQntuples(comparr.res); + if (ntups != 100) + { + failcnt++; + fprintf(stderr, "put 100 elements into complex[] but " + "got back %d\n", ntups); + PQclear(comparr.res); + return; + } + + testcnt++; + for (i=0; i < ntups; i++) + { + /* Verify element 50 is NULL */ + if(i==50) + { + /* All fields should be NULL */ + if(!PQgetisnull(comparr.res, i, 0) || + !PQgetisnull(comparr.res, i, 1) || + !PQgetisnull(comparr.res, i, 2)) + { + failcnt++; + fprintf(stderr, " Element 50 should of been NULL\n"); + PQclear(comparr.res); + return; + } + + continue; + } + + /* get the complex composite at tuple 'i' */ + r = PQgetf(comparr.res, i, "%text %simple #int4[]", + 0, &text, 1, &simple_res, "arr", &intarr); + GETOKAY2(comparr.res, r, "PQgetf(comparr.res element)"); + + /* check the text field */ + sprintf((char *) buf, "text_%03d", i+1); + if (strcmp(text, (char *) buf)) + { + failcnt++; + fprintf(stderr, "complex[%d].t failed: sent=%s, recv=%s\n", + i, buf, text); + PQclear(simple_res); + PQclear(intarr.res); + PQclear(comparr.res); + return; + } + + /* Check the simple field: reference by fname, use '#' + * rather than '%' + */ + r = PQgetf(simple_res, 0, "#int4 #int8", "a", &a, "b", &b); + GETOKAY2(simple_res, r, "PQgetf(complex[].simple.*)"); + PQclear(simple_res); + + /* verify simple.* values */ + if (a != (i+1000000) || b != ((PGint8) 1<<48)+i) + { + failcnt++; + fprintf(stderr, "complex[%d].simple.* failed: " + "sent(a=%d, b=%lld), recv(a=%d, b=%lld)\n", + i, i+1000000, ((PGint8) 1<<48)+i, a, b); + PQclear(intarr.res); + PQclear(comparr.res); + return; + } + + /* check the int[10][3] field */ + if (intarr.dims[0] != 10 || intarr.dims[1] != 3 || + intarr.lbound[0] != 1 || intarr.lbound[1] != 1 || intarr.ndims != 2) + { + failcnt++; + fprintf(stderr, "complex[%d].int[][] dimension info failed: " + "sent(ndims=2, arr[1:10][1:3]), recv(ndims=%d, arr[%d:%d][%d:%d])\n", + i, intarr.ndims, intarr.lbound[0], intarr.dims[0], + intarr.lbound[1], intarr.dims[1]); + PQclear(intarr.res); + PQclear(comparr.res); + return; + } + + inttups = PQntuples(intarr.res); + for (x=1; x < inttups; x++) + { + r = PQgetf(intarr.res, x, "%int4", 0, &a); + GETOKAY2(intarr.res, r, "PQgetf(complex.int[][] element"); + + if (a != x+1) + { + failcnt++; + fprintf(stderr, " **ERROR: complex[%d].int4[][] sent=%d, recv=%d\n", + i, x+1, a); + PQclear(intarr.res); + PQclear(comparr.res); + return; + } + } + + PQclear(intarr.res); + } + + PQclear(comparr.res); + printf(" composite[] with nested composite and arrays passed\n"); +} + +static void test_natives(int format) +{ + int r; + PGchar ca; + PGchar cb; + PGint2 i2a, i2b; + PGint4 i4a, i4b; + PGint8 i8a, i8b; + PGfloat4 f4a, f4b; + PGfloat8 f8a, f8b; + PGmoney mona, monb; + Oid oida, oidb; + PGbool boola, boolb; + + PQparamReset(param); + printf("\nNative C types: (%s)\n", format ? "binary" : "text"); + + r = PQputf(param, "%char %char %int2 %int2 %int4 %int4 %int8 %int8 " + "%float4 %float4 %float8 %float8 %money %money %oid %oid %bool %bool", + -117, 224, -32000, 32000, INT_MIN, INT_MAX, LLONG_MIN, LLONG_MAX, + -1.23456f, 1.23456f, -123456789.654321, 123456789.654321, + (PGmoney)INT_MIN, 600000000054LL, 91982, 3000000000U, 0, 1); + PUTOKAY(param, r, "PQputf(natives)"); + + DROP_TABLE("libpq_natives"); + + result = PQexec(conn, "CREATE TABLE libpq_natives (" + "char_a \"char\", char_b \"char\", " + "i2_a int2, i2_b int2, " + "i4_a int4, i4_b int4, " + "i8_a int8, i8_b int8, " + "f4_a float4, f4_b float4, " + "f8_a float8, f8_b float8, " + "mon_a money, mon_b money, " + "oid_a oid, oid_b oid, " + "bool_a bool, bool_b bool)"); + CMDOKAY("creating libpq_natives table"); + PQclear(result); + + result = PQparamExec(conn, param, "INSERT INTO libpq_natives VALUES" + "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18)", + format); + CMDOKAY("PQparamExec(INSERT:natives)"); + PQclear(result); + + result = PQparamExec(conn, NULL, "SELECT * FROM libpq_natives", format); + TUPSOKAY("PQparamExec(SELECT:natives)"); + + r = PQgetf(result, 0, "%char %char %int2 %int2 %int4 %int4 %int8 %int8 " + "%float4 %float4 %float8 %float8 %money, %money %oid %oid %bool %bool", + 0, &ca, 1, &cb, 2, &i2a, 3, &i2b, 4, &i4a, 5, &i4b, 6, &i8a, 7, &i8b, 8, + &f4a, 9, &f4b, 10, &f8a, 11, &f8b, 12, &mona, 13, &monb, 14, &oida, + 15, &oidb, 16, &boola, 17, &boolb); + GETOKAY(r, "PQgetf(natives)"); + PQclear(result); + + CHKNUM("%char", ca, -117); + CHKNUM("%char", (unsigned char) cb, 224); + CHKNUM("%int2", i2a, -32000); + CHKNUM("%int2", i2b, 32000); + CHKNUM("%int4", i4a, INT_MIN); + CHKNUM("%int4", i4b, INT_MAX); + CHKNUM("%int8", i8a, LLONG_MIN); + CHKNUM("%int8", i8b, LLONG_MAX); + CHKNUM("%float4", f4a, -1.23456f); + CHKNUM("%float4", f4b, 1.23456f); + CHKNUM("%float8", f8a, -123456789.654321); + CHKNUM("%float8", f8b, 123456789.654321); + CHKNUM("%money", mona, (PGmoney) INT_MIN); + CHKNUM("%money", monb, 600000000054LL); + CHKNUM("%oid", oida, 91982); + CHKNUM("%oid", oidb, 3000000000U); + CHKNUM("%bool", boola, 0); + CHKNUM("%bool", boolb, 1); +} + +static void test_geometrics(int format) +{ + int r; + static PGpoint ptarr[6] = {{565677.342, 999112.33344}, + {-565677.342, -999112.33344}, {-565677.342, 999112.33344}, + {565677.342, 999112.33344}, {-565677.342, -999112.33344}, + {-565677.342, 999112.33344}}; + PGpoint point = {0}; + PGpoint pointval = {565677.342, 999112.33344}; + PGlseg lseg = {{{0}}}; + PGlseg lsegval = {{{565677.342, -999112.33344}, {88876.2314, 77283.323}}}; + PGbox box = {{0}}; + PGbox boxval = {{565677.342, 88876.2314}, {77283.323, -999112.33344}}; + PGcircle circle = {{0,0},0}; + PGcircle circleval = {{7765.435, -7743.2993}, 23384.102}; + PGpath path = {0, 0, NULL}; + PGpath pathval = {6, 1, ptarr}; + PGpolygon polygon = {0, NULL}; + PGpolygon polygonval = {6, ptarr}; + + PQparamReset(param); + printf("\nGeometric types: (%s)\n", format ? "binary" : "text"); + + r = PQputf(param, "%point %lseg %box %circle %path %polygon", + &pointval, &lsegval, &boxval, &circleval, &pathval, &polygonval); + PUTOKAY(param, r, "PQputf(geos)"); + + DROP_TABLE("libpq_geos"); + + result = PQexec(conn, "CREATE TABLE libpq_geos (" + "p point, l lseg, b box, c circle, pa path, poly polygon)"); + CMDOKAY("creating libpq_geos table"); + PQclear(result); + + result = PQparamExec(conn, param, "INSERT INTO libpq_geos VALUES" + "($1,$2,$3,$4,$5,$6)", format); + CMDOKAY("PQparamExec(INSERT:geos)"); + PQclear(result); + + result = PQparamExec(conn, NULL, "SELECT * FROM libpq_geos", format); + TUPSOKAY("PQparamExec(SELECT:geos)"); + + r = PQgetf(result, 0, "%point %lseg %box %circle %path %polygon", + 0, &point, 1, &lseg, 2, &box, 3, &circle, 4, &path, 5, &polygon); + GETOKAY(r, "PQgetf(geos)"); + + CHKGEO(point); + CHKGEO(lseg); + CHKGEO(box); + CHKGEO(circle); + + testcnt++; + if (path.closed == pathval.closed && path.npts == pathval.npts && + memcmp(path.pts, pathval.pts, path.npts * sizeof(PGpoint))==0) + printf(" %%path - passed\n"); + else + { + failcnt++; + fprintf(stderr, " %%path - FAILED\n"); + } + + testcnt++; + if (polygon.npts == polygon.npts && + memcmp(polygon.pts, polygon.pts, polygon.npts * sizeof(PGpoint))==0) + printf(" %%polygon - passed\n"); + else + { + failcnt++; + fprintf(stderr, " %%polygon - FAILED\n"); + } + + /* NOTE: this will invalidate path.pts and polygon.pts */ + PQclear(result); +} + +/* + * numeric is tested here because it is always exposed as a string. + * uuid is not a varlen data type, but testing it here is ok + */ +static void test_varlen(int format) +{ + int r; + static char byteadata[] = {0, 1, 2, 3, 4, 5, 6, 7}; + PGbpchar bpcharp=NULL; + PGbpchar bpcharin = "character(n) blank-padded"; + PGvarchar varcharp=NULL; + PGvarchar varcharin = "character varying(n)"; + PGtext textp=NULL; + PGtext textin = "variable unlimited length"; + PGbytea byteap; + PGbytea byteain = {8, byteadata}; + PGuuid uuid; + char uuidin[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + PGnumeric num; + PGnumeric numin = + "-62731893541288039212143296120112.12431212671229121291821928918211"; + + PQparamReset(param); + printf("\nVariable-length types: (%s)\n", format ? "binary" : "text"); + + r = PQputf(param, "%bpchar %bpchar* %varchar %varchar* " + "%text %text* %bytea %bytea* %uuid %numeric", + bpcharin, bpcharin, varcharin, varcharin, textin, textin, + &byteain, &byteain, uuidin, numin); + PUTOKAY(param, r, "PQputf(varlen)"); + + DROP_TABLE("libpq_varlen"); + + result = PQexec(conn, "CREATE TABLE libpq_varlen (" + "bp_a bpchar(32), bp_b bpchar(32), vc_a varchar(32), vc_b varchar(32), " + "text_a text, text_b text, bytea_a bytea, bytea_b bytea, " + "uid uuid, n numeric)"); + CMDOKAY("creating libpq_varlen table"); + PQclear(result); + + result = PQparamExec(conn, param, "INSERT INTO libpq_varlen VALUES" + "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)", format); + CMDOKAY("PQparamExec(INSERT:varlen)"); + PQclear(result); + + result = PQparamExec(conn, NULL, + "SELECT bp_a,vc_a,text_a,bytea_a,uid,n FROM libpq_varlen", format); + TUPSOKAY("PQparamExec(SELECT:varlen)"); + + r = PQgetf(result, 0, + "%bpchar %varchar %text %bytea %uuid %numeric", + 0, &bpcharp, /* field_num, PGbpchar* */ + 1, &varcharp, /* field_num, PGvarchar* */ + 2, &textp, /* field_num, PGtext* */ + 3, &byteap, /* field_num, PGbytea* */ + 4, &uuid, /* field_num, PGuuid* */ + 5, &num); /* field_num, PGnumeric* */ + GETOKAY(r, "PQgetf(varlen)"); + + /* Because we are using the '*' specifier flag, we clear the results at + * the end. '*' flag is just a pointer to the result: like PQgetvalue(). + */ + + testcnt++; + if (bpcharcmp(bpcharin, bpcharp, 32)) + { + failcnt++; + fprintf(stderr, " %%bpchar - FAILED\n"); + } + else + printf(" %%bpchar - passed\n"); + + CHKVLEN("varchar", varcharp, varcharin); + CHKVLEN("text", textp, textin); + + testcnt++; + if (byteain.len != byteap.len || + memcmp(byteap.data, byteain.data, byteap.len)) + { + failcnt++; + fprintf(stderr, " %%bytea* - FAILED\n"); + } + else + printf(" %%bytea* - passed\n"); + + testcnt++; + if (memcmp(uuid, uuidin, 16)) + { + failcnt++; + fprintf(stderr, " %%uuid - FAILED\n"); + } + else + printf(" %%uuid - passed\n"); + + CHKVLEN("numeric", num, numin); + PQclear(result); +} + +static void test_datetime(int format) +{ + int r; + time_t t; + struct tm *tm; + char *tzn; + PGdate date[3] = {{0}}; + static PGdate dateval[] = { + {0, 1476, 9, 1, 2260432, 274, 0}, /* 1476-10-01 */ + {1, 1209, 7, 17, 1280076, 229, 1}, /* 1209-08-17 BC */ + {0, 2007, 11, 23, 2454458, 356, 0}}; /* 2007-12-23 */ + PGtime tim[3] = {{0}}; + static PGtime timeval[] = { + {23, 10, 31, 7214, 0, -1, 0, {0}}, /* 23:10:31.007214 */ + { 2, 19, 52, 0, 0, -1, 0, {0}}, /* 02:19:52 */ + {15, 57, 7, 881542, 0, -1, 0, {0}}}; /* 15:57:07.881542 */ + PGtime timetz[3] = {{0}}; + PGtime timetzval[] = { + {23, 10, 31, 9888, 1, -1, -28800, {0}}, /* 23:10:31.009888-08 */ + { 2, 19, 52, 0, 1, -1, 7200, {0}}, /* 02:19:52+02 */ + {15, 57, 7, 881542, 1, -1, -10800, {0}}}; /* 15:57:07.881542-03 */ + PGtimestamp timestamp[3] = {{0, {0}, {0}}}; + PGtimestamp timestampval[] = { + { -15565394969, {0, 1476, 9, 1, 2260432, 274, 0}, + {23, 10, 31, 7214, 0, -1, 0, {0}}}, /* 1476-10-01 23:10:31.007214 */ + {-100268228408, {1, 1209, 7, 17, 1280076, 229, 1}, + { 2, 19, 52, 0, 0, -1, 0, {0}}}, /* 1209-08-17 02:19:52 BC */ + { 1198425427, {0, 2007, 11, 23, 2454458, 356, 0}, + {15, 57, 7, 881542, 0, -1, 0, {0}}}}; /* 2007-12-23 15:57:07.881542 */ + PGinterval interval = {0}; + PGinterval intervalval = /* 2,354 years 8 mons 23 days 14:54:27.029333 */ + {2354, 8, 23, 14, 54, 27, 29333}; + PGtimestamp timestamptz; + PGtimestamp timestamptzval; + + PQparamReset(param); + memset(×tamptz, 0, sizeof(PGtimestamp)); + memset(×tamptzval, 0, sizeof(PGtimestamp)); + + /* Jan 1, 1980 (returned: text=server time zone, binary=localtime) */ + t = 315532800; + tm = localtime(&t); + timestamptzval.epoch = t; + timestamptzval.time.hour = tm->tm_hour; + timestamptzval.time.min = tm->tm_min; + timestamptzval.time.sec = tm->tm_sec; + timestamptzval.time.usec = 0; + timestamptzval.time.withtz = 1; + timestamptzval.date.isbc = 0; + timestamptzval.date.year = tm->tm_year + 1900; + timestamptzval.date.mon = tm->tm_mon; + timestamptzval.date.mday = tm->tm_mday; + PQlocalTZInfo(&t, ×tamptzval.time.gmtoff, + ×tamptzval.time.isdst, &tzn); + strcpy(timestamptzval.time.tzabbr, tzn); + + strcpy(timetzval[0].tzabbr, "GMT-0800"); + strcpy(timetzval[1].tzabbr, "GMT+0200"); + strcpy(timetzval[2].tzabbr, "GMT-0300"); + + printf("\nDate & Time types: (%s '%s')\n", + format ? "binary" : "text", datestyle); + + r = PQputf(param, "%date %date %date %time %time %time %timetz %timetz " + "%timetz %timestamp %timestamp %timestamp %interval %timestamptz", + &dateval[0], &dateval[1], &dateval[2], &timeval[0], &timeval[1], + &timeval[2], &timetzval[0], &timetzval[1], &timetzval[2], + ×tampval[0], ×tampval[1], ×tampval[2], &intervalval, + ×tamptzval); + PUTOKAY(param, r, "PQputf(datetime)"); + + DROP_TABLE("libpq_datetime"); + + result = PQexec(conn, "CREATE TABLE libpq_datetime (" + "date_a date, date_b date, date_c date, " + "time_a time, time_b time, time_c time, " + "timetz_a timetz, timetz_b timetz, timetz_c timetz, " + "timestamp_a timestamp, timestamp_b timestamp, timestamp_c timestamp, " + "intvl interval, tstz timestamptz)"); + CMDOKAY("creating libpq_datetime table"); + PQclear(result); + + result = PQparamExec(conn, param, "INSERT INTO libpq_datetime VALUES" + "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)", format); + CMDOKAY("PQparamExec(INSERT:datetime)"); + PQclear(result); + + result = PQparamExec(conn, NULL, "SELECT * FROM libpq_datetime", format); + TUPSOKAY("PQparamExec(SELECT:datetime)"); + + r = PQgetf(result, 0, "%date %date %date %time %time %time %timetz " + "%timetz %timetz %timestamp %timestamp %timestamp %interval " + "%timestamptz", + 0, &date[0], 1, &date[1], 2, &date[2], + 3, &tim[0], 4, &tim[1], 5, &tim[2], + 6, &timetz[0], 7, &timetz[1], 8, &timetz[2], + 9, ×tamp[0], 10, ×tamp[1], 11, ×tamp[2], + 12, &interval, 13, ×tamptz); + GETOKAY(r, "PQgetf(datetime)"); + PQclear(result); + + for (r=0; r < 3; r++) + { + testcnt++; + if (memcmp(&date[r], &dateval[r], sizeof(PGdate)) == 0) + printf(" %%date - #%d passed\n", r+1); + else + { + failcnt++; + fprintf(stderr, " %%date - #%d FAILED\n", r+1); + } + } + + for (r=0; r < 3; r++) + { + testcnt++; + if (memcmp(&tim[r], &timeval[r], sizeof(PGtime)) == 0) + printf(" %%time - #%d passed\n", r+1); + else + { + failcnt++; + fprintf(stderr, " %%time - #%d FAILED\n", r+1); + } + } + + for (r=0; r < 3; r++) + { + testcnt++; + if (memcmp(&timetz[r], &timetzval[r], sizeof(PGtime)) == 0) + printf(" %%timetz - #%d passed\n", r+1); + else + { + failcnt++; + fprintf(stderr, " %%timetz - #%d FAILED\n", r+1); + } + } + + for (r=0; r < 3; r++) + { + + testcnt++; + if (memcmp(×tamp[r], ×tampval[r], sizeof(PGtimestamp)) == 0) + { + printf(" %%timestamp - #%d passed\n", r+1); + } + /* Windows may hit rounding issues with usecs. In this test, usecs of + * 7214 were coming back as 7215. + */ +#if defined(_WIN32) || defined(_WIN64) + else if (timestamp[r].time.usec+1 == timestampval[r].time.usec || + timestamp[r].time.usec-1 == timestampval[r].time.usec) + { + printf(" %%timestamp - #%d passed (warning: known usec rounding " + "issue - sent=%d, recv=%d)\n", r+1, + timestampval[r].time.usec, timestamp[r].time.usec); + } +#endif + else + { + failcnt++; + fprintf(stderr, " %%timestamp - #%d FAILED\n", r+1); + } + } + + /* interval usecs won't match when using a non-ISO datastyle because only + * 2 fractional digits are provided: 23.291876 => 23.29 secs. + */ + if (format == 0 && !strstr(datestyle, "ISO")) + { + printf(" **NOTE: non-ISO DateStyle interval text has a 2 digit limit " + "on the microsecond value ... adjusting\n => sent=%d, " + "received=%d\n", intervalval.usecs, interval.usecs); + interval.usecs = intervalval.usecs; + } + + testcnt++; + if (memcmp(&interval, &intervalval, sizeof(PGinterval)) == 0) + printf(" %%interval - passed\n"); + else + { + failcnt++; + fprintf(stderr, " %%interval - FAILED\n"); + + printf(" SENT: yr=%d,mon=%d,days=%d,hr=%d,min=%d,sec=%d,usec=%d\n", + intervalval.years, intervalval.mons, intervalval.days, + intervalval.hours, intervalval.mins, intervalval.secs, + intervalval.usecs); + printf(" RECV: yr=%d,mon=%d,days=%d,hr=%d,min=%d,sec=%d,usec=%d\n", + interval.years, interval.mons, interval.days, + interval.hours, interval.mins, interval.secs, interval.usecs); + } + + testcnt++; + + if (timestamptz.epoch == timestamptzval.epoch) + printf(" %%timestamptz - passed\n"); + else + { + failcnt++; + fprintf(stderr, " %%timestamptz - FAILED\n"); + + printf("SENT: epoch=%lld,isbc=%d,yr=%d,mon=%d,mday=%d,jday=%d," + "yday=%d,wday=%d,hr=%d,min=%d,sec=%d,usec=%d,withtz=%d," + "isdst=%d,tzabbr=%s,gmtoff=%d\n", + timestamptzval.epoch, + timestamptzval.date.isbc,timestamptzval.date.year, + timestamptzval.date.mon, + timestamptzval.date.mday,timestamptzval.date.jday, + timestamptzval.date.yday, + timestamptzval.date.wday, + timestamptzval.time.hour, timestamptzval.time.min, + timestamptzval.time.sec, + timestamptzval.time.usec, timestamptzval.time.withtz, + timestamptzval.time.isdst, + timestamptzval.time.tzabbr, timestamptzval.time.gmtoff); + + printf("RECV: epoch=%lld,isbc=%d,yr=%d,mon=%d,mday=%d,jday=%d," + "yday=%d,wday=%d,hr=%d,min=%d,sec=%d,usec=%d,withtz=%d,isdst=%d," + "tzabbr=%s,gmtoff=%d\n", + timestamptz.epoch, + timestamptz.date.isbc,timestamptz.date.year,timestamptz.date.mon, + timestamptz.date.mday,timestamptz.date.jday,timestamptz.date.yday, + timestamptz.date.wday, + timestamptz.time.hour, timestamptz.time.min, timestamptz.time.sec, + timestamptz.time.usec, timestamptz.time.withtz, timestamptz.time.isdst, + timestamptz.time.tzabbr, timestamptz.time.gmtoff); + } +} + +static void test_network(int format) +{ + int r; + PGinet ipv4, ipv4out; + PGinet ipv6, ipv6out; + PGmacaddr mac = {1,2,3,225,226,227}; + PGmacaddr macout; + int have_ipv4=1; + int have_ipv6=1; + +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(HAVE_GETADDRINFO) + struct addrinfo *info = NULL; + struct addrinfo hints = {0}; + + memset(&ipv4, 0, sizeof(PGinet)); + memset(&ipv4out, 0, sizeof(PGinet)); + memset(&ipv6, 0, sizeof(PGinet)); + memset(&ipv6out, 0, sizeof(PGinet)); + + PQparamReset(param); + printf("\nNetwork types: (%s)\n", format ? "binary" : "text"); + + /* this should always work */ + if ((r = getaddrinfo("192.168.123.77", NULL, NULL, &info))) + { + have_ipv4 = 0; + //testcnt++; + //failcnt++; + fprintf(stderr, " IPv4: SKIPPING TEST (no support)\n"); + } + else + { + ipv4.mask = 32; + ipv4.sa_buf_len = (int)info->ai_addrlen; + ipv4.is_cidr = 0; + memcpy(ipv4.sa_buf, info->ai_addr, ipv4.sa_buf_len); + memset(ipv4.sa_buf, 0, 2); + ((struct sockaddr *) ipv4.sa_buf)->sa_family = AF_INET; + freeaddrinfo(info); + } + +#ifdef AF_INET6 + hints.ai_family = AF_INET6; +#endif + + /* windows may choke on an IPv6 address */ + if ((r = getaddrinfo("2001:4f8:3:ba:2e0:81ff:fe22:d1f1", + NULL, &hints, &info))) + { + have_ipv6 = 0; + //testcnt++; + //failcnt++; + fprintf(stderr, " IPv6: SKIPPING TEST (no support - [%d] %s)\n", + r, gai_strerror(r)); + } + else + { + ipv6.mask = 32; + ipv6.sa_buf_len = (int)info->ai_addrlen; + ipv6.is_cidr = 0; + memcpy(ipv6.sa_buf, info->ai_addr, ipv6.sa_buf_len); + +#ifdef AF_INET6 + memset(ipv6.sa_buf, 0, 2); + ((struct sockaddr *) ipv6.sa_buf)->sa_family = AF_INET6; +#endif + + freeaddrinfo(info); + } + + r = have_ipv4 ? PQputf(param, "%inet", &ipv4) : PQputf(param, "%null"); + PUTOKAY(param, r, "PQputf(network-ipv4)"); + + r = have_ipv6 ? PQputf(param, "%inet", &ipv6) : PQputf(param, "%null"); + PUTOKAY(param, r, "PQputf(network-ipv6)"); + + r = PQputf(param, "%macaddr", &mac); + PUTOKAY(param, r, "PQputf(network-macaddr)"); + + DROP_TABLE("libpq_network"); + + result = PQexec(conn, "CREATE TABLE libpq_network (" + "ipv4 inet, ipv6 inet, mac macaddr)"); + CMDOKAY("creating libpq_network table"); + PQclear(result); + + result = PQparamExec(conn, param, + "INSERT INTO libpq_network VALUES ($1,$2,$3)", format); + CMDOKAY("PQparamExec(INSERT:network)"); + PQclear(result); + + result = PQparamExec(conn, NULL, "SELECT * FROM libpq_network", format); + TUPSOKAY("PQparamExec(SELECT:network)"); + + r = PQgetf(result, 0, "%inet %inet %macaddr", + 0, &ipv4out, 1, &ipv6out, 2, &macout); + GETOKAY(r, "PQgetf(network)"); + + PQclear(result); + + if (have_ipv4) + { + if (memcmp(&ipv4out, &ipv4, sizeof(PGinet))) + { + failcnt++; + fprintf(stderr, " %%inet - IPv4 FAILED\n"); + } + else + printf(" %%inet - IPv4 passed\n"); + } + + if (have_ipv6) + { + if (memcmp(&ipv6out, &ipv6, sizeof(PGinet))) + { + failcnt++; + fprintf(stderr, " %%inet - IPv6 FAILED\n"); + } + else + printf(" %%inet - IPv6 passed\n"); + } + + testcnt++; + if (memcmp(&macout, &mac, sizeof(PGmacaddr))) + { + failcnt++; + fprintf(stderr, " %%macaddr - FAILED\n"); + } + else + printf(" %%macaddr - passed\n"); +#else + printf("\nNetwork types: (%s) - skipping, no getaddrinfo()\n", + format ? "binary" : "text"); +#endif +} + +/* PGtypeProc put for epoch sub-class */ +static int epoch_put(PGtypeArgs *args) +{ + PGtimestamp ts; + time_t t = va_arg(args->ap, time_t); + struct tm *tm = localtime(&t); + + printf(" epoch_put('%ld')\n", t); + + ts.date.isbc = 0; + ts.date.year = tm->tm_year + 1900; /* PGtimestamp requires 4-digit year */ + ts.date.mon = tm->tm_mon; + ts.date.mday = tm->tm_mday; + ts.time.hour = tm->tm_hour; + ts.time.min = tm->tm_min; + ts.time.sec = tm->tm_sec; + ts.time.usec = 0; + + PQlocalTZInfo(&t, &ts.time.gmtoff, &ts.time.isdst, NULL); + return args->super(args, &ts); +} + +/* PGtypeProc get for epoch sub-class */ +static int epoch_get(PGtypeArgs *args) +{ + PGtimestamp ts; + time_t *t = va_arg(args->ap, time_t *); + + printf(" epoch_get(%s)\n", args->format==0 ? "text" : "binary"); + + if (args->super(args, &ts) == -1) + return -1; /* args->errorf called by super class */ + + /* since PGtimestamp contains an epoch member as an int8, we can + * just copy that value, rather than doing a mktime(). If time_t + * is 32-bits, the below has a limited range compared to an int8. + * Although, this will work fine for timestamps in a 32-bit time_t range. + * 64-bit time_t should always work. + */ + *t = (time_t)ts.epoch; + return 0; +} + +static void test_subclass(int format) +{ + int r; + PGparam *prm; + time_t timeout[2] = {0}; + /* 1970-01-01 00:00:00, 2000-01-01 00:00:00 */ + time_t timevals[] = {0, 946702800}; + + printf("\nSub-class: (%s)\n", format ? "binary" : "text"); + + DROP_TABLE("libpq_subclass"); + result = PQexec(conn, + "CREATE TABLE libpq_subclass (n timestamptz, a timestamptz)"); + CMDOKAY("creating libpq_subclass table"); + PQclear(result); + + prm = PQparamCreate(conn); + if (!PQputf(prm, "%epoch %epoch", timevals[0], timevals[1])) + fprintf(stderr, "subclass_put failed: %s\n", PQgeterror()); + result = PQparamExec(conn, prm, "INSERT INTO libpq_subclass " + "VALUES ($1, $2)", format); + PQparamClear(prm); + CMDOKAY("PQparamExec(INSERT:subclass)"); + PQclear(result); + + result = PQparamExec(conn, NULL, "SELECT * FROM libpq_subclass", format); + TUPSOKAY("PQparamExec(SELECT:subclass)"); + + /* use schema-qualified name */ + r = PQgetf(result, 0, "%libpq.epoch %epoch", + 0, &timeout[0], 1, &timeout[1]); + GETOKAY(r, "PQgetf(subclass)"); + PQclear(result); + + testcnt++; + if (memcmp(timeout, timevals, sizeof(timeout))) + { + failcnt++; + fprintf(stderr, " %%epoch - FAILED (putval=%ld,%ld, getval=%ld,%ld)\n", + timevals[0], timevals[1], timeout[0], timeout[1]); + } + else + fprintf(stderr, " %%epoch - passed\n"); +} + + diff --git a/source/src/spec.c b/source/src/spec.c new file mode 100644 index 0000000..6c5a97e --- /dev/null +++ b/source/src/spec.c @@ -0,0 +1,660 @@ + +/* + * spec.c + * Type Specifier parser and compiler. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +/* For use with pqt_parse */ +#define CHKSTMTBUF(nbytes_add) do{ \ + if ((*stmtPos + (nbytes_add)) >= stmtBufLen) \ + { \ + PQseterror("statement buffer is too small"); \ + return FALSE; \ + } \ +}while (0) + +/* For use with PQspecPrepare */ +#define FREESTMTBUF do{ \ + if (stmtBuf && stmtBuf != buffer) \ + free(stmtBuf); \ +}while(0) + +static char * +skipQuotes(char *s); + +static char * +parseId(char *id, char **start, int *len, int *flags, int typpos); + +static int +expandSpecs(PGtypeData *typeData); + +int +PQspecPrepare(PGconn *conn, const char *name, + const char *format, int is_stmt) +{ + int flags; + int typpos = 0; + int idmax = 0; + size_t stmtPos = 0; + PGtypeHandler *h; + PGtypeData *typeData; + PGtypeSpec *spec; + size_t stmtBufLen = 0; + char *stmtBuf = NULL; + char buffer[8192]; + + if (!conn) + { + PQseterror("PGConn cannot be NULL"); + return FALSE; + } + + if (!name || !*name) + { + PQseterror("Prepared specifier name cannot be NULL or an empty string"); + return FALSE; + } + + if (format && !*format) + { + PQseterror("Specifier format string cannot be empty"); + return FALSE; + } + + if (!isalnum(*name) && *name != '_') + { + PQseterror("Prepared specifier name must begin with an alpha, " + "number or underscore."); + return FALSE; + } + + typeData = PQinstanceData(conn, pqt_eventproc); + if (!typeData) + { + PQseterror("No type data exists for PGconn at %p", conn); + return FALSE; + } + + /* This is a removal request */ + if (!format) + { + int i; + + for (i=0; i < typeData->typspeccnt; i++) + { + if (strcmp(typeData->typspecs[i].name, name) == 0) + { + /* clear it */ + pqt_clearspec(&typeData->typspecs[i]); + + /* remove from list, not needed if its the last element */ + if (i != typeData->typspeccnt - 1) + memmove(typeData->typspecs + i, typeData->typspecs + i + 1, + (typeData->typspeccnt - i - 1) * sizeof(PGtypeSpec)); + + typeData->typspeccnt--; + break; + } + } + + /* always return TRUE, an error is not useful here */ + return TRUE; + } + + /* Already exists case */ + spec = pqt_getspec(typeData->typspecs, typeData->typspeccnt, name); + if (spec) + { + PQseterror("Prepared spec already exists '%s'", name); + return FALSE; + } + + /* Make sure specs array is large enough */ + if (!expandSpecs(typeData)) + return FALSE; + + spec = &typeData->typspecs[typeData->typspeccnt]; + + /* cache statement along with prepared type spec */ + if (is_stmt) + { + stmtBufLen = strlen(format) + 1; + + /* no room in stack, use heap */ + if (stmtBufLen > sizeof(buffer)) + { + stmtBuf = (char *) malloc(stmtBufLen); + if (!stmtBuf) + { + PQseterror(PQT_OUTOFMEMORY); + return FALSE; + } + } + else + { + stmtBuf = buffer; + stmtBufLen = sizeof(buffer); + } + } + + while (format && *format) + { + format = pqt_parse(format, typeData->typhandlers, typeData->typhcnt, + stmtBuf, stmtBufLen, &h, &stmtPos, &typpos, &flags); + + if (!format) + { + pqt_clearspec(spec); + FREESTMTBUF; + return FALSE; + } + + /* skipped harmless chars in format, like quoted sections. */ + if(!h) + continue; + + if (!spec->idlist || spec->idcnt == idmax) + { + int c = idmax ? idmax * 2 : 8; + void *p = pqt_realloc(spec->idlist, c * sizeof(int)); + + if (!p) + { + PQseterror(PQT_OUTOFMEMORY); + pqt_clearspec(spec); + FREESTMTBUF; + return FALSE; + } + + spec->idlist = (int *) p; + + p = pqt_realloc(spec->flags, c * sizeof(char)); + if (!p) + { + PQseterror(PQT_OUTOFMEMORY); + pqt_clearspec(spec); + FREESTMTBUF; + return FALSE; + } + + spec->flags = (unsigned char *) p; + idmax = c; + } + + /* Parallel arrays, every handler needs type flags */ + spec->idlist[spec->idcnt] = h->id; + spec->flags[spec->idcnt++] = (unsigned char) flags; + } + + /* terminate stmtBuf, guarenteed to have room for NUL */ + if (stmtBuf) + stmtBuf[stmtPos] = 0; + + /* copy name string */ + spec->name = strdup(name); + if (!spec->name) + { + pqt_clearspec(spec); + PQseterror(PQT_OUTOFMEMORY); + FREESTMTBUF; + return FALSE; + } + + /* copy the parameterized stmt string */ + if (stmtBuf) + { + spec->stmt = strdup(stmtBuf); + if (!spec->stmt) + { + pqt_clearspec(spec); + PQseterror(PQT_OUTOFMEMORY); + FREESTMTBUF; + return FALSE; + } + } + + FREESTMTBUF; + + /* Success, increment type spec count */ + typeData->typspeccnt++; + return TRUE; +} + +int +PQclearSpecs(PGconn *conn) +{ + PGtypeData *typeData; + + if (!conn) + { + PQseterror("PGConn cannot be NULL"); + return FALSE; + } + + typeData = PQinstanceData(conn, pqt_eventproc); + if (!typeData) + { + PQseterror("No type data exists for PGconn at %p", conn); + return FALSE; + } + + pqt_freespecs(typeData->typspecs, typeData->typspeccnt); + typeData->typspecs = NULL; + typeData->typspeccnt = 0; + typeData->typspecmax = 0; + + return TRUE; +} + +char *pqt_parse(const char *format, PGtypeHandler *h, int hcnt, + char *stmtBuf, size_t stmtBufLen, PGtypeHandler **out, size_t *stmtPos, + int *typpos, int *flags) +{ + int specMark; + char *s = skipQuotes((char *) format); + char typname[PQT_MAXIDLEN + 1]; + char schema[PQT_MAXIDLEN + 1]; + char tmp[200]; + + *out = NULL; + + if (!s) + return NULL; + + /* found quotes to skip */ + if (s != format) + { + if (stmtBuf) + { + size_t n = s - format; + CHKSTMTBUF(n); + memcpy(stmtBuf + *stmtPos, format, n); + (*stmtPos) += n; + } + + return s; + } + + specMark = *format; + if (specMark != '%' && specMark != '#') + { + if (stmtBuf) + { + CHKSTMTBUF(1); + stmtBuf[*stmtPos] = *format; + (*stmtPos)++; + } + + format++; + return (char *) format; + } + + /* spec skips % or # */ + if (!(s = pqt_parsetype(format + 1, schema, typname, flags, *typpos + 1))) + return NULL; + + if (*flags & TYPFLAG_INVALID) + { + if (stmtBuf) + { + CHKSTMTBUF(1); + stmtBuf[*stmtPos] = *format++; + (*stmtPos)++; + PQseterror(NULL); /* set by pqt_parsetype */ + return (char *) format; + } + + return NULL; + } + + (*typpos)++; + + if (!(*out = pqt_gethandler(h, hcnt, schema, typname))) + { + PQseterror("Uknown type '%s' (position %d)", + pqt_fqtn(tmp, sizeof(tmp), schema, typname), *typpos); + return NULL; + } + + if (stmtBuf) + { + int n = pqt_snprintf(tmp, sizeof(tmp), "$%d", *typpos); + CHKSTMTBUF(n); + memcpy(stmtBuf + *stmtPos, tmp, n); + (*stmtPos) += n; + } + + if (!(*out)->typput) + { + PGtypeHandler *o = pqt_gethandlerbyid(h, hcnt, (*out)->base_id); + if (!o || !o->typput) + { + PQseterror( + "Type '%s' doesn't support put operations (position %d)", + pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, + (*out)->typname), *typpos); + + *out = NULL; + return NULL; + } + + *out = o; + } + +#if 0 + if ((*flags & TYPFLAG_POINTER) && !pqt_allowsptr(*out)) + { + PQseterror( + "Type '%s' doesn't support putting pointers (position %d)", + pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, + (*out)->typname), *typpos); + + *out = NULL; + return NULL; + } +#endif + + if (specMark == '#') + (*flags) |= TYPFLAG_BYNAME; + + return s; +} + +void +pqt_clearspec(PGtypeSpec *spec) +{ + if (spec->name) + free(spec->name); + + if (spec->stmt) + free(spec->stmt); + + if (spec->idlist) + free(spec->idlist); + + if (spec->flags) + free(spec->flags); + + memset(spec, 0, sizeof(PGtypeSpec)); +} + +PGtypeSpec *pqt_dupspecs(PGtypeSpec *specs, int count) +{ + int i; + PGtypeSpec *new_specs = (PGtypeSpec *) malloc(count * sizeof(PGtypeSpec)); + + if (!new_specs) + return NULL; + + memset(new_specs, 0, count * sizeof(PGtypeSpec)); + + for (i=0; i < count; i++) + { + PGtypeSpec *s = &specs[i]; + PGtypeSpec *news = &new_specs[i]; + + news->idcnt = s->idcnt; + + news->name = strdup(s->name); + if (!news->name) + { + pqt_freespecs(new_specs, i+1); + return NULL; + } + + if(s->stmt) + { + news->stmt = strdup(s->stmt); + if (!news->stmt) + { + pqt_freespecs(new_specs, i+1); + return NULL; + } + } + + news->idlist = (int *) malloc(s->idcnt * sizeof(int)); + if (!news->idlist) + { + pqt_freespecs(new_specs, i+1); + return NULL; + } + + memcpy(news->idlist, s->idlist, s->idcnt * sizeof(int)); + + news->flags = (unsigned char *) malloc(s->idcnt * sizeof(char)); + if (!news->flags) + { + pqt_freespecs(new_specs, i+1); + return NULL; + } + + memcpy(news->flags, s->flags, s->idcnt * sizeof(char)); + } + + return new_specs; +} + +void pqt_freespecs(PGtypeSpec *specs, int count) +{ + int i; + + for (i=0; i < count; i++) + pqt_clearspec(&specs[i]); + + if (specs) + free(specs); +} + +PGtypeSpec *pqt_getspec(PGtypeSpec *specs, int count, const char *name) +{ + int i; + + for (i=0; i < count; i++) + if (strcmp(specs[i].name, name) == 0) + return &specs[i]; + + return NULL; +} + +/* Parse a type identifer name (schema qualified or not) from spec. spec + * must point to the first char after the % sign, which maybe a + * double quote. + * + * spec - pointer to typname, just after the '%' or '#' + * schema - buffer to receive schema (PQT_MAXIDLEN bytes) + * typname - buffer to receive typname (PQT_MAXIDLEN bytes) + * flags - a pointer to an int that is set one or more TYPFLAG_xxx + * typpos - 1-based position of spec in specifier string (0 for unknown) + */ +char * +pqt_parsetype(const char *spec, char *schema, char *typname, + int *flags, int typpos) +{ + int i; + char *start; + int len=0; + char *s = (char *)spec; + + if (!(s = parseId(s, &start, &len, flags, typpos))) + return NULL; + + /* not a valid specifer, false positive like "(x % y) = 0" */ + if (*flags & TYPFLAG_INVALID) + return s; + + *schema = 0; + if (*s == '.') + { + memcpy(schema, start, len); + schema[len] = 0; + if (*flags & TYPFLAG_CASEFOLD) + for (i=0; i < len; i++) + schema[i] = pqt_tolower(schema[i]); + + /* now get typname */ + if (!(s = parseId(++s, &start, &len, flags, typpos))) + return NULL; + + if (*flags & TYPFLAG_INVALID) + return s; + } + + memcpy(typname, start, len); + typname[len] = 0; + if (*flags & TYPFLAG_CASEFOLD) + for (i=0; i < len; i++) + typname[i] = pqt_tolower(typname[i]); + + return s; +} + +static char * +parseId(char *id, char **start, int *len, int *flags, int typpos) +{ + char *p = id; + + *flags = 0; + *start = NULL; + *len = 0; + + if (*p == '"') + p++; + + /* check first character */ + if (!isalpha(*p) && *p != '_') + { + *flags |= TYPFLAG_INVALID; + PQseterror( + "Invalid first character for identifier '%c' (pos:%d)", *p, typpos); + return p; + } + + if (*id == '"') + { + id++; + if (!(p = strchr(id, '"'))) + { + *flags |= TYPFLAG_INVALID; + PQseterror("Unterminated double quote '%s' (pos:%d)", + id-1, typpos); + return p; + } + + *len = (int) (p - id); + *start = id; + p++; + } + else + { + for (p=id+1; isalnum(*p) || *p=='_'; p++) ; + + *len = (int) (p - id); + *start = id; + *flags |= TYPFLAG_CASEFOLD; + } + + /* range check */ + if (*len == 0 || *len > PQT_MAXIDLEN) + { + *flags |= TYPFLAG_INVALID; + PQseterror("Identifier out of range %d (pos:%d), range is 1 to %d", + *len, typpos, PQT_MAXIDLEN); + return p; + } + + /* direct pointer request */ + if (*p == '*') + { + p++; + *flags |= TYPFLAG_POINTER; + } + + /* Is this an array? Ex. %int4[] or %"a b"[] */ + if (p[0] == '[' && p[1] == ']') + { + if (*flags & TYPFLAG_POINTER) + { + PQseterror( + "'*' specifer flag cannot be used with arrays[] '%s' (pos:%d)", + id, typpos); + return NULL; + } + + *flags |= TYPFLAG_ARRAY; + p += 2; + } + + return p; +} + +static int +expandSpecs(PGtypeData *typeData) +{ + int n; + PGtypeSpec *specs; + + if (typeData->typspeccnt < typeData->typspecmax) + return TRUE; + + n = typeData->typspecmax ? (typeData->typspecmax * 3) / 2 : 8; + + specs = (PGtypeSpec *) pqt_realloc( + typeData->typspecs, sizeof(PGtypeSpec) * n); + + if (!specs) + { + PQseterror(PQT_OUTOFMEMORY); + return FALSE; + } + + memset(specs + typeData->typspeccnt, 0, + (n - typeData->typspeccnt) * sizeof(PGtypeSpec)); + + typeData->typspecs = specs; + typeData->typspecmax = n; + return TRUE; +} + +/* skip quoted strings. Doesn't need to account for E'' syntax. The + * E is copied over prior to the quoted string. + * + * Returns a pointer to the next character after the closing quote or + * NULL if there was an error. + */ +static char * +skipQuotes(char *s) +{ + char *end; + + if (*s != '\'') + return s; + + end = s; + while (*++end) + { + /* If we see a backslash, skip an extra char. No need to dig any + * further since this method works with \digits and \hex. + */ + if (*end == '\\') + end++; + else if (*end == '\'') + break; + } + + /* unterminated quote */ + if (!*end) + { + PQseterror("unterminated single quoted string"); + return NULL; + } + + return ++end; /* skip ending quote */ +} + diff --git a/source/src/utils.c b/source/src/utils.c new file mode 100644 index 0000000..2ff0e7b --- /dev/null +++ b/source/src/utils.c @@ -0,0 +1,265 @@ + +/* + * util.c + * Utility functions. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +PGresult * +pqt_copyresult(PGtypeArgs *args, int nattrs) +{ + int i; + PGresult *res; + int tableid, columnid, format; + PGresAttDesc *ad = (PGresAttDesc *) malloc(nattrs * sizeof(PGresAttDesc)); + + if (!ad) + { + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + tableid = PQftable(args->get.result, args->get.field_num); + columnid = PQftablecol(args->get.result, args->get.field_num); + format = PQfformat(args->get.result, args->get.field_num); + + for (i=0; i < nattrs; i++) + { + ad[i].tableid = tableid; + ad[i].columnid = columnid; + ad[i].format = format; + + /* simple array */ + if (args->typhandler->nattrs == 0) + { + ad[i].typid = args->typhandler->typoid; + ad[i].typlen = args->typhandler->typlen; + ad[i].name = NULL; + ad[i].atttypmod = -1; + } + /* composite/record */ + else + { + ad[i].typid = args->typhandler->attDescs[i].attoid; + ad[i].typlen = args->typhandler->attDescs[i].attlen; + ad[i].name = args->typhandler->attDescs[i].attname; + ad[i].atttypmod = args->typhandler->attDescs[i].atttypmod; + } + } + + res = PQcopyResult(args->get.result, + PG_COPYRES_EVENTS | PG_COPYRES_NOTICEHOOKS); + + if (!res) + { + free(ad); + PQseterror(PQT_OUTOFMEMORY); + return NULL; + } + + if (!PQsetResultAttrs(res, nattrs, ad)) + { + PQclear(res); + PQseterror(PQT_OUTOFMEMORY); + res = NULL; + } + + free(ad); + return res; +} + +#ifdef STRICT_MEMORY_ALIGNMENT +short +pqt_buf_getint2(char *buffer) +{ + short n; + memcpy(&n, buffer, 2); + return (short) ntohs(n); +} + +int +pqt_buf_getint4(char *buffer) +{ + int n; + memcpy(&n, buffer, 4); + return (int) ntohl(n); +} +#endif + +void +pqt_swap8(void *outp, void *inp, int tonet) +{ + static int n = 1; + +#ifdef STRICT_MEMORY_ALIGNMENT + unsigned int in[2]; + unsigned int out[2]; + memcpy(&in, inp, 8); +#else + unsigned int *in = (unsigned int *) inp; + unsigned int *out = (unsigned int *) outp; +#endif + + /* swap when needed */ + if (*(char *)&n == 1) + { + out[0] = (unsigned int) (tonet ? htonl(in[1]) : ntohl(in[1])); + out[1] = (unsigned int) (tonet ? htonl(in[0]) : ntohl(in[0])); + } + else + { + out[0] = in[0]; + out[1] = in[1]; + } + +#ifdef STRICT_MEMORY_ALIGNMENT + memcpy(outp, out, 8); +#endif +} + +int +pqt_text_to_int8(char *val, void *out) +{ + PGint8 n; + + /* NOTE: port version of strtoll in port.c. */ + errno = 0; + if ((n = (PGint8) strtoll(val, NULL, 10)) == 0 && errno) + return -1; + + *(PGint8 *) out = n; + return 0; +} + +int +pqt_text_to_float8(double *f8, char *text, char **endptr) +{ + double d; + + errno = 0; + if ((d = strtod(text, endptr)) == 0 && errno) + return 0; + + *f8 = d; + return 1; +} + +/* Checks buffer and truncates 'src' if 'dest' is too small. */ +char * +pqt_strcpy(char *dest, size_t size, const char *src) +{ + size_t src_len = strlen(src); + + /* truncate if needed */ + if (src_len >= size) + src_len = size - 1; + + memcpy(dest, src, src_len); + dest[src_len] = 0; + return dest; +} + + +/* --------------------------- + * Everything below was taken from postgresql project + * A couple of changes here and there. + */ + +#ifndef HIGHBIT +# define HIGHBIT (0x80) +#endif + +#ifndef IS_HIGHBIT_SET +# define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT) +#endif + +/* + * Fold a character to lower case. + * + * Unlike some versions of tolower(), this is safe to apply to characters + * that aren't upper case letters. Note however that the whole thing is + * a bit bogus for multibyte character sets. + */ +unsigned char +pqt_tolower(unsigned char ch) +{ + if (ch >= 'A' && ch <= 'Z') + ch += 'a' - 'A'; + else if (IS_HIGHBIT_SET(ch) && isupper(ch)) + ch = (unsigned char) tolower(ch); + return ch; +} + +/* + * Case-independent comparison of two null-terminated strings. + */ +int +pqt_strcasecmp(const char *s1, const char *s2) +{ + for (;;) + { + unsigned char ch1 = (unsigned char) *s1++; + unsigned char ch2 = (unsigned char) *s2++; + + if (ch1 != ch2) + { + if (ch1 >= 'A' && ch1 <= 'Z') + ch1 += 'a' - 'A'; + else if (IS_HIGHBIT_SET(ch1) && isupper(ch1)) + ch1 = (unsigned char)tolower(ch1); + + if (ch2 >= 'A' && ch2 <= 'Z') + ch2 += 'a' - 'A'; + else if (IS_HIGHBIT_SET(ch2) && isupper(ch2)) + ch2 = (unsigned char)tolower(ch2); + + if (ch1 != ch2) + return (int) ch1 - (int) ch2; + } + if (ch1 == 0) + break; + } + return 0; +} + +/* + * Case-independent comparison of two not-necessarily-null-terminated + * strings. At most n bytes will be examined from each string. + */ +int +pqt_strncasecmp(const char *s1, const char *s2, size_t n) +{ + while (n-- > 0) + { + unsigned char ch1 = (unsigned char) *s1++; + unsigned char ch2 = (unsigned char) *s2++; + + if (ch1 != ch2) + { + if (ch1 >= 'A' && ch1 <= 'Z') + ch1 += 'a' - 'A'; + else if (IS_HIGHBIT_SET(ch1) && isupper(ch1)) + ch1 = (unsigned char)tolower(ch1); + + if (ch2 >= 'A' && ch2 <= 'Z') + ch2 += 'a' - 'A'; + else if (IS_HIGHBIT_SET(ch2) && isupper(ch2)) + ch2 = (unsigned char)tolower(ch2); + + if (ch1 != ch2) + return (int) ch1 - (int) ch2; + } + if (ch1 == 0) + break; + } + return 0; +} + + + diff --git a/source/src/varlena.c b/source/src/varlena.c new file mode 100644 index 0000000..a20727c --- /dev/null +++ b/source/src/varlena.c @@ -0,0 +1,88 @@ + +/* + * varlena.c + * Type handler for the variable length data types. + * + * Copyright (c) 2008-2015 eSilo, LLC. All rights reserved. + * This is free software; see the source for copying conditions. There is + * NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "libpqtypes-int.h" + +/* put a type in its string representation, text format */ +int +pqt_put_str(PGtypeArgs *args) +{ + args->format = TEXTFMT; + args->put.out = va_arg(args->ap, char *); + return args->put.out ? (int)strlen(args->put.out)+1 : 0; +} + +/* varchar, bpchar and name use the text handlers */ +int +pqt_put_text(PGtypeArgs *args) +{ + args->put.out = va_arg(args->ap, PGtext); + return args->put.out ? (int)strlen(args->put.out) : 0; +} + +/* varchar, bpchar and name use the text handlers */ +int +pqt_get_text(PGtypeArgs *args) +{ + DECLVALUE(args); + PGtext *textp = va_arg(args->ap, PGtext *); + CHKGETVALS(args, textp); + *textp = value; + return 0; +} + +int +pqt_put_bytea(PGtypeArgs *args) +{ + PGbytea *bytea = va_arg(args->ap, PGbytea *); + PUTNULLCHK(args, bytea); + args->put.out = bytea->data; + return bytea->len; +} + +int +pqt_get_bytea(PGtypeArgs *args) +{ + DECLVALUE(args); + DECLLENGTH(args); + PGbytea *bytea = va_arg(args->ap, PGbytea *); + + CHKGETVALS(args, bytea); + + if (args->format == TEXTFMT) + { + size_t len = 0; + + value = (char *) PQunescapeBytea((const unsigned char *) value, &len); + if (!value) + RERR_STR2INT(args); + + bytea->data = (char *) PQresultAlloc(args->get.result, len); + if (!bytea->data) + { + PQfreemem(value); + RERR_MEM(args); + } + + bytea->len = (int) len; + memcpy(bytea->data, value, len); + PQfreemem(value); + return 0; + } + + /* binary format */ + bytea->len = valuel; + bytea->data = value; + return 0; +} + + + diff --git a/source/win32.mak b/source/win32.mak new file mode 100644 index 0000000..3a5dd1d --- /dev/null +++ b/source/win32.mak @@ -0,0 +1,66 @@ +############################################################## +# Project: libpqtypes +# Makefile for Microsoft Visual Studio 6, 7 or 8 +# +# nmake -f win32.mak [options] [targets] +# +# For further build instructions, see the package's INSTALL file. +# +# Authors: Andrew Chernow, Merlin Moncure +# Contact: libpqtypes@esilo.com +############################################################## + +PROJNAME = libpqtypes + +OBJECTS = src\array.obj src\datetime.obj src\error.obj \ + src\events.obj src\exec.obj src\geo.obj src\handler.obj \ + src\misc.obj src\network.obj src\numerics.obj \ + src\param.obj src\port.obj src\record.obj src\spec.obj \ + src\utils.obj src\varlena.obj + + +CFLAGS = $(CFLAGS) /nologo /W4 /MD /GF /Ob2 /O2 /Oi- /D_WIN32_WINNT=0x0501 + +!IFDEF MT +CFLAGS = $(CFLAGS) /DPQT_THREAD_SAFE +!ENDIF + +!IFDEF PQT_LONG_LONG +CFLAGS = $(CFLAGS) /DPQT_LONG_LONG=$(PQT_LONG_LONG) +!ENDIF + +# set the libpath for libpq.dll and libpqdll.lib (same thing as gcc -L) +!IFDEF LPATH +LIBPATH = /LIBPATH:$(LPATH) +!ENDIF + +INC2 = $(INC) /Isrc +LIBS = ws2_32.lib libpq.lib +LINKOPTS = /nologo /subsystem:windows /incremental:no +LINKIGNORE = /IGNORE:4089 /IGNORE:4006 /IGNORE:4068 +LIBOPTS = /nologo /subsystem:windows $(LINKIGNORE) + +all: $(OBJECTS) + lib $(LIBOPTS) /OUT:$(PROJNAME).lib $(OBJECTS) + link $(LINKOPTS) /dll $(OBJECTS) /out:$(PROJNAME).dll \ + /IMPLIB:$(PROJNAME)dll.lib $(LIBS) $(LIBPATH) + +test: + $(CC) $(CFLAGS) $(INC2) src\regression-test.c /Feregtest.exe \ + $(LIBS) $(PROJNAME)dll.lib /link $(LIBPATH) $(LINKIGNORE) + -@del regression-test.obj + +$(OBJECTS): + $(CC) $(CFLAGS) $(INC2) /c $** /Fo$*.obj + +clean: + -@del /Q /F \ + $(OBJECTS) \ + $(PROJNAME).dll \ + $(PROJNAME).dll.manifest \ + $(PROJNAME).lib \ + $(PROJNAME)dll.lib \ + $(PROJNAME)dll.exp \ + regtest.exe \ + regtest.exe.manifest 2>NUL 1>NUL + diff --git a/source/win32_d.mak b/source/win32_d.mak new file mode 100644 index 0000000..9e8fbfd --- /dev/null +++ b/source/win32_d.mak @@ -0,0 +1,66 @@ +############################################################## +# Project: libpqtypes +# Makefile for Microsoft Visual Studio 6, 7 or 8 +# +# nmake -f win32.mak [options] [targets] +# +# For further build instructions, see the package's INSTALL file. +# +# Authors: Andrew Chernow, Merlin Moncure +# Contact: libpqtypes@esilo.com +############################################################## + +PROJNAME = libpqtypes + +OBJECTS = src\array.obj src\datetime.obj src\error.obj \ + src\events.obj src\exec.obj src\geo.obj src\handler.obj \ + src\misc.obj src\network.obj src\numerics.obj \ + src\param.obj src\port.obj src\record.obj src\spec.obj \ + src\utils.obj src\varlena.obj + + +CFLAGS = $(CFLAGS) /nologo /W3 /Zi /WX- /Od /MD /GF /Ob2 /Oi- /D_WIN32_WINNT=0x0501 /D "_DEBUG" + +!IFDEF MT +CFLAGS = $(CFLAGS) /DPQT_THREAD_SAFE +!ENDIF + +!IFDEF PQT_LONG_LONG +CFLAGS = $(CFLAGS) /DPQT_LONG_LONG=$(PQT_LONG_LONG) +!ENDIF + +# set the libpath for libpq.dll and libpqdll.lib (same thing as gcc -L) +!IFDEF LPATH +LIBPATH = /LIBPATH:$(LPATH) +!ENDIF + +INC2 = $(INC) /Isrc +LIBS = ws2_32.lib libpq.lib +LINKOPTS = /nologo /subsystem:windows /incremental /DEBUG +LINKIGNORE = /IGNORE:4089 /IGNORE:4006 /IGNORE:4068 +LIBOPTS = /nologo /subsystem:windows $(LINKIGNORE) + +all: $(OBJECTS) + lib $(LIBOPTS) /OUT:$(PROJNAME).lib $(OBJECTS) + link $(LINKOPTS) /dll $(OBJECTS) /out:$(PROJNAME).dll \ + /IMPLIB:$(PROJNAME)dll.lib $(LIBS) $(LIBPATH) + +test: + $(CC) $(CFLAGS) $(INC2) src\regression-test.c /Feregtest.exe \ + $(LIBS) $(PROJNAME)dll.lib /link $(LIBPATH) $(LINKIGNORE) + -@del regression-test.obj + +$(OBJECTS): + $(CC) $(CFLAGS) $(INC2) /c $** /Fo$*.obj + +clean: + -@del /Q /F \ + $(OBJECTS) \ + $(PROJNAME).dll \ + $(PROJNAME).dll.manifest \ + $(PROJNAME).lib \ + $(PROJNAME)dll.lib \ + $(PROJNAME)dll.exp \ + regtest.exe \ + regtest.exe.manifest 2>NUL 1>NUL +