From 8ceccabfd6cec98221490f6bffd4a458693231eb Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Tue, 31 Jan 2023 17:06:46 +0100 Subject: [PATCH 01/15] chore: update deps & gradle --- build.gradle | 14 +- gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 282 ++++++++++++++--------- gradlew.bat | 43 ++-- 5 files changed, 203 insertions(+), 138 deletions(-) diff --git a/build.gradle b/build.gradle index dd89e37..3e41d04 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,3 @@ -import org.gradle.api.tasks.wrapper.Wrapper.DistributionType - buildscript { repositories { maven { @@ -9,7 +7,7 @@ buildscript { } plugins { - id 'com.gradle.plugin-publish' version '1.0.0' + id 'com.gradle.plugin-publish' version '1.1.0' id 'maven-publish' id 'groovy' id 'idea' @@ -29,14 +27,14 @@ repositories { } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:3.4.6' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.4.0' implementation 'org.mongodb:mongo-java-driver:3.12.11' - testImplementation 'org.spockframework:spock-core:2.1-groovy-3.0', { + testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0', { exclude module: 'groovy-all' } testImplementation 'org.littleshoot:littleproxy:1.1.2' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' } task javadocJar(type: Jar, dependsOn: javadoc) { @@ -64,7 +62,7 @@ publishing { name = 'Gradle Mongo Plugin' description = 'Gradle plugin for managing a local instance of MongoDb' url = 'https://github.com/sourcemuse/GradleMongoPlugin' - + licenses { license { name = 'The Apache License, Version 2.0' @@ -89,7 +87,7 @@ publishing { } } } - } + } repositories { maven { name = 'ossSonatype' diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 26986 zcmY&O!TTh(EjcwabV>EWs*ftt9INv$vzxi+X&A!-s&6+hc zE3F=)b`he1{u^Q{Z^F$3+ng!Nm>_ z*0QiiNuLxEBan^V0M`#FjYJV9233#XKk}EPnG?9u2XOBg_*^87yAUrl!;R>0um`s{ps@06inrW?b*lrIb_q`^(K>ML zinn7U0YQsdb7r$L)RU;GnbKto0R>;jg73k%sjL%3R!uY*Lt`$E|5SD+IMn8;>7~gn zim`pJ;m3B>Z5KTj_$=D<-DyOqqVRZwYc>5zg(qZA=H+rLXDB90&ZG^jTF<=JZ)n(; zHI2`VXi{-_Yt%ob(O|n?|4>y)z}xFn9afk(0vG7X=02h;m9C)zfA3g^$?d~$8)+JZ zY|dDc&5{vP1O?UsrLw<`gr+dv;8*nAOv+!yj}A9tlsWzDI|`|Y^Jt6>UL#%hd!bx5 z0+=tlY|XsvD^HiF=gs8kw~-5tU|yZ;UG|99g9pI={Y&SuHxIGY>ZxQ)h-csz{&4!a z5%2CVWlCh{TrZw)b4>H9?B{CtaPzHAo1$jd^tSm{rz(<8iX>{jXIo;$zR!)Zsa3tecR8IXMN$lnbDnfCNgtu^obeKz3!68iXH4Jv*CNr9oW84f|gVT)&^uuz)e z-Avqyrm~QmXi6cZo9mDIu^s;eFvoggQLxPQ2Q*xIh{Y6@>%yH424T=t*~mIb%?P+D z{r^N6`csI0H&OXB5mQWp#AE^*4g5wDQ50qYZ85>onakSZnwgFpQtqzirO5t*HcpT5 z8LP32u%WSa*qpjR)_&3|8A@ZaJYhGAIlVIC7kBEF=Fya>&e)y7w5~eXwI17YjeaJ6O48&Wj=)__PVq7 zOcc1ZC!ZqmW1_A_GdXkAv^>4-Sjy)T4 zKpTpO-eCfDV7=pBGw4A95!#_a)9DC#UJFDC6kgoajt-@HJu=m6YD49q-Wb=^KEdMJ z4pTIDSFXma6Z&|^ObfX73O>0m9p%>OOrzsAd?TQU(xY}7awG>(gU;d=*+3H597IAYWhz8&g8?d%1I+}s6~ zU1CPs@BRoOz9k=;qo-qe6siYo?%T8xk1lO;rF1Fe(hL@?o0O>Xa+gQ%{+??(%^yc? zFH33F1P7ThPAMerNHn=vmyc#&@M$Eg=O?O%-=$3~@sk6phl-xHm$#}9zA_Yg)b4hI zKPN1vkEuqoYn+<8%1^ALc<}DI`t04}&^A-+{|qXB2reA16vN+IT$`^mG-~fdUGpJy zt+xF!?p|tJvnOluy_@YRNy$^Zm%L!E$o8t)=qY8i6}(Mqt4OS<@L^>}fYDpg|7Qtz zudz;G@th2J#uchDb2GFdg?fwW__t?GXX=6&1nzQW+b*RE3Xr|Q_Ge+J(ui{F7xl98 zV)KIc5F3onnh?d^p$$wi;P^0=z(5F#$tIA+6p|B{kQ8q)*9k&{ZENCR1zzaA`hRY| zAcAw8IR3#7Aj$xaWGUpT(lcHa@SV|$rZgJv4h4YU)EDeV@h6>c(dTVE-Jn^pHAzo$ z2|2Hkw^m#9mf3*yPaiDl(}3CKiZABJI`Q~7Ks-e>=&8Fv?X<*=S#&EB>9H_BkSCTr z9zn8R^_|-Vg);h=*!&JTBI;%dwg@AS3%`VChM(L43lv^IUHsg%blc24a*^4g0_6lg zk0Q{MeR!adQxNt`LoRiUAJoHIB++mM_eMFKw;vJqGwg?ir($OY?si$e#N$=v^1fBk z>#2`FdgG?E_YL$@CAr39tyvJ!$HgiB+VJNl^u7i`2JQ#GL2<%Ip9tPx!hqjIU8R^d zKTvU$d2-b&X_jq&ij>1Wv4Ycy#V2o)bh%JNThR)*oqvL!NfP8`+gXI}F z-|Xd4I)gCZzwuHF{{l<4gT6!bY0>NFfCK~k1M?rA{yzi-VBlaREG$ht?A?KV#T#0{qIjx~|52%(py z^xo6tMQkHJaxssxfW^#D@=xD++}wE=DZyv7KzDc^!sPKz?&nRn-ka`|%PndE_<-%F zfB7u|?!-}qIkXTflgv4u9^y^U-dGouP5S^Qm zCBWG*;b(9-kMv`R58u&Y?y1*$X!2XVzL)xbs7)uUZ@fWGMThzD*-EnC~6 zH0vh$WG!oaSHXK@^00i=DSg=0*pI2vx;&Y2nczIhYEa#f&P#0= z-pHZ-I9pe$l`^>Q>7d4U2Oj%ELPD(gg2h2v1hi^Vh#Tz;srf;;9H8a2(`UIqHry_Q zlZ9IFW})#~G<)xduE*&q`ywZIL;7%=8rclK_w3-m4#zzReePRQ@h3n%SK?+@fpHUq zk}vo3#M%j(k&=F?@n%sBdD+qfS8){|RH)+jDtYIk&_S7awQER#rBxHy>u@>|$2@=V;3w)7xG}psH&>#yW1HW-a&Lc3J3e z`1G^QTy2dHnTP#x&LIQrE<6Hjjn)05^>Wytt@GKJ6|5 zvGB1Uucf6e;uZpPS)mP)Z|#Qm35H`|diWNd^h4geAU|4~8HlgG;3{;^%mN*vOjmMW zc;}Og85x(9-(8pUq_2xt0d1b4x$`pi%I5&Z2v%H+NDPiYi;p+htNfSe4iC;2J4lg#wna__gSi#fDA zP2IASYQgI*-GhJ3=a0xibVZ#Zo-a->W#xS>iTEyLyR=w1zif%3V6c zxGDCL_=28)MG7En97D!VIy>Kbjr+faAhZO$*{@q zanY*C&3D+8LS4C0IF=i#RB&zOBzuLTI9&X%*oY)!AjKkDp5P)coB(>ph^H z^S?+&Bv==j#NH@P_-#M6S-xa-ZVlH{Hus}5+MkfQiksO$h~}r*gVFzHYk48H8-@Qd z^1%PFhU0&*h78cya#NGU__|U!RdD3y7?!Qnu0&%6ZBR(Q7f2SA6d1pm^cA##Z)E2_ z?*HBPb~8H@K4j<1Dw^UEIzvF7;tAptdeM5>MITz*Xh|-~#o#}?=I!otd&=42?S7tr z$Pa{e#-oIgX2mPrYY7(Wsa|4N>4|(!eGCppc3J7i83jCY*ikfsXoRA7d$O3_56Gz8 z^`i?=21?>5p?#f4M8JvZo$^mRst)kP)B7AXl6@kAi!M^#ER<60GdFG}O38k0mUQp^ zsiTQQzs)(){`83$P?t9MjUv@|mP;xux8`;2dOFH_#2U_0ppPoDgZBe@r!C;em|%im zP5WN|ng*h>`j`lJ*urmo5#Fl~Wa^D$Y&FoRcFs-@4Ph|60G+pH^WHt*(lWtG4;;m^ zg^})kyF|B={0(9WB2&yGFDpGt)IWa)X-|#=W?d&Bqfvf)DXd!lfPNXNDtR$`=w<24 zKuaajBFtygKbZT0ivjAhH=0h>0S>IOJxQ?wXH-0iLCtJ!wF5yyDr3ynaM z@w8K?8AmS&ZUhh7bB(_n!!Gz7of!_O#Etxp({0lXl8DCOHP0F@9nT5!>4)?P+Fc?^ zw;g{w^K6XL)8s=`4UjgJ6>;(^l8yiT06zMi-JiqS;)3Jl*}_z#-*`M0bKa|{s?A#( zbO4o-wzJCPGFx7XwUCm13M1$-XKPQ#<59Mu%Jjb*7?di%c(h7Nk1MRhm3wroPBpPD z+N1ouZfhL^dm!Z00h6pIU4{7LO3`MR9`ucCyIzZv)4&RBDN+Jg_M~;c$8Br8+VbnX zn`;h@nh{!!xFoXuEW(+Zt<YaHn|! z&D^cqTV@-REW1p;!JWN1?gp9jDsg7Z-pD7g#K<2^P6Ieq#ry*{735FkNOmt!f`Hmk zpQ$~ub`K_(;5~j9nsga4S)+h}>KMJ==`W>$USDAu87RN#UYhrJwQ<;D(aS+f>ykg-&~fNjPh<4_ZG!|GiLZKF5n?x~PgDr@h#C(udjz)hg7CWCY z6BXXRu>>@JLH+MiPH%hvnFYn)y#NMYaZ>i~l3VnAAW*os0Ad{!0bU6X@2Jy!n zL%szu+cBWr!eg` ziZV|Mk@D&rjP{_2bO*l+x_@K7pVI^U<1-8yvfMO~yiXB@l=dD*p26oCP^VSr86M`c zdp3ubd&D?6;a98lPYRdyZ^-WILkj+DZ@#AMK-9@m_?nc92XLcbXi>CtMr?7_t3}=dzL`qKMguB zZ<;~TRPL%C(2=6(6`JMM)11d<@x3MTM@oCeX0@}-&o}jJEuU&JYRv89y=otkqbspd zr0{wb@A8S&svfzc3-uL^ZANzjjP6JcE_EVRAMGR5RC2l-6`y)-91U;vJ)C5$*pXOs zJ$0qhSd7Kai#Sq2LeAB(=P{tjMX-k#msk<6Qr(Ke0?*j|KG=PCx2uKMba?7_f#aws z!_Ce1(pGb=-|EWKwsJ!`zJ0FWV}P%jdIBPM#FRM&*XES^3RXg?yr8AyaO&aU568PPZ zkQuV#iF+B2Wy#9B`-8yRWEs9EUnvyZX1b&)YIAsHt8YYcUR(>NUS^KNT?46l+;Hsm zp-r)S5s9=|dlGN}YD!%DNSR~IG`L^Kb2k3*wfCe$^EKr)(Nv^MJkm6Ci{{p znW;3vYG+20^+3RQPUZ)Qq3-uJZfvF$TbXntNiJK`MFb*00AAa@C@xM0mwIVEGTQiP zT~C_wnB}6D;EC60;zpsAggTStO)kcpJ-NPb(+E|B)fQy<@UVO>F%kdmmohva8<(Jy zD<1~&rd>urq6&E)m)k_>Y_JQ{gmZshOQuXVOHW~fX%|3&HVH*%8QS;`qAW$m{TM&R z_~%iyTZX}fsYu_WwD$o|{F_xe153$eD!Ou1xI74j4~P9P1QcI+cm|z!y@rw`bUB%c zq{^5QcT!N06$>}Cci3u3BPj;ILwg?EN{wRz;)HouO_xj^qb4_f1mdD@$|c)WB9DF# zNdmJCf+WzWSIh|$IQ?@<$8ZFX>U(ulZmO}RXmHsHq0{xCyl8XaTv0f2; zu8$A>p+S+FV!y@j->EVsp=TA2cptoSIYyg$;bUoOG2?VKR3z?zK-A(3{P4K5ah95a zdWiH~8(w2WM~QcBu)zd9b-62tmw*N4$AULqeh0wB%R}Y}9vTXpPD#()^Ru$h+IMof z?aZU<5KPlY?9SbF4&^Rh_veu#N)O(aq>=Iqbe!-gx9y{auS~Ju8Awk>PBk(QFPMY% zu4R<_ZW?~4=#I2k;~?R|0S^d4W}jwK&FA=}AYOSg0Mn1-mKHp;}t~7U+YFNsU=i~?f+`ngc`b_!x zMLEA&e)sVnB-N(`6wEW93ce`P=riAy-2tKR7W$-Ca|Q>IFZ6iA3|aN}s~n$vfcSy* zOE$c4)tyS9{K433TTQzJ+U0mSo@0X!Yw(9J9SZ6hZ>C~~REOy4Q`n%A?K@+j>_PeK zhP-zc;o=K!pxD6;>_+}SR5-jlK2A;D#l(u(!->lo66lDeyZNBeog*trH-ab{7NBIv zbgwMPW*p<({HODMsLlava5H)lFRkK7&S_lCu@8s#9k@NWIGdDb_EJ6e2%O)M!pt^_ z2W-Zjh?r7YY|x+NKq=udO67gI1MF9f#XW}$-|o;YEvPrOeHOxifNTi1Rv36UKazNU zYmtP38Co+G?%;m&H>_;)Nh`1za6k*>1vA(mz}Cdi=#2-ST?~!Zt(_L#A06!OIHU}* zuWyg7B<0vZAGM(>R_t{)hSxXDZ1*nsDHKbOv_%5mUZ}AG7YFp$gLx;f5ujHts{Wtejncj3&-53}q$Q*D=R42jW zhNyHWLmlJV1G9!nG={)$_Z+wuqUXTBoNKvP&>(ebHqeCZ-C1~XKs{|zD3s170ea@aOo=)CoibZruJ3+v7n+sOjEzezbjGf6(8@(nVUy zBd0fEKmDkSDl=_u6CG5KXve^jDXsiWs`Q!^d_^*wiJL?L+MyOFydT*;{HEXXQ%Ls; zs6|^u^b-FLANoxQ0$tn$AaFV+b|%)0gK;5RNTIU6-S^~{kjR*fY^aQp`++{==&6wB zB;=Db&N`)oH7kh6-NPF$p|^CVRBgw}W;>oBEy5IEnQ>np>3k?ZjNzRgfl!RzhG92w z({Etx|41M!LVxC_%t~whjn`zYp@G%m)rfebvCkvK-rp&T24G`KLXy+5!h9OjkrY+_ z@rz)pHl^}}y(KBO#))M86!M!eGd++Z-Dnk#>X16z=Mc4F|B4(%KtPEjmof;Q_m&l? z88JsFx|ltWvfRnbD!;{sE2@0wWH%#Cr!8%j-D{uQ{XuFQ7ZNBfV4?eKx&rW2!oJ4n zw3J&%(O8MO1|mv?1n71^QO$$f?y|Q)yS()k^ygn|TX@)}wlzmu`sBV_^WH{^#EcQ>0{uYUx{AIP{>1VoDfM{xI54UJdNu;mBAC6@Y74ZnB zUBLo}<$9+mZ|!I*Z~-}3a}JMDn=dS*`BV4+{DIO*oN(x!)%Q`MJ9Wt&YQyS#zwVEb zP_@82Pw20$q%Wd{xxVz?A5U@xmn7W0cZ~IwM_q5|>aHOKW{3V#Y&(%Fq0IA=95I@U zAE(ROz~v*DAkCMqI#avV8ajN+?>yy!;8yR-(2%%4!HwFTJ~{djW{1}`<3C-K)XVC+ zlGP_rdZ7uC7v&DG>S~2Scn5pB5i<;B?B1h#Cli>B^=rP}vqa+NSBkH2hQ5l`<-eV zs;Y5|qqEiz)OFN=9DmNh6PGN51201AI^1$zh*l3Xj%OZ?V23>C1aYD_e;G>KV7R&h zK(!0aQCHfn0+Yt3_^2h%w$cEvU}T;Aq^&DwH>Xc$ASNE)mF`GRR#JqtR#W~(&m`qCU z>jKG^#Hva)ItPc2LCrUnv$G^gL*+gNV9fsEZ?bqDL;d93K0GxB8% z?gt|;4@Srf?pr+K{>?(OwvWE!Xba4TyeIn@k+#ZvqXVXwTXOXiWNv!lL-yu@`#?Vr zBX0kw+?cga`%Z4*f1M&rx6duMYOeuPA$kWcoemeg*40Nc;{3`fbSJZLluFA2;1sOq zsx)=q!&5rbbvj#T>zk~%v_9(3T1bktIf2tnEsVJ?Z*tKU-0k*`UCF7spJ5cNssF2) zI_{*Su|}ZFuj@N2UScxg_L2u<9bAHIH@O>Dr8`&ELw%;o{iH?cCda6A zkVd2IGYkJkU=WJgE_)7E^Y27^3dpybtcMDMLGd2UrEEbw?ZVUFuwlKD5V;0Ft}E6k zAl9ef{38FE<-pj*&HNO(2N;xF$Ed`2EKhsr56NuLaK-E?@ZJ@vtNI+~k}zs?3Bb ziXeXIsSXaq-uJVAj}WdR08HCzS4W`8{W{~$TLU7w^>%|e}A8y z8DDeb%-Aj^)_Xdn;lfPagPm$47hiQ>e)Y6G)!ktl`|fTK@p#R*Q8!k@5 z#e0GKAQcgjr5{+n6Am)#SGmBSnS;fNFf97bTC+*7DfM0J4an7x?H;Gy;-q7vdetP+k7szZfG^SsoOd{?M?P#;=q; z%pK~*`4QLC$tacdwn5;jYy~JVt{g!n_Z2+bPpO-t1K*arORL6fs&ZX3=mdUb^8X+x zYZh0RX5CK5?>_Vf950^;E0igfS@ymo!hWt5e(PuC*nR32gNWWC#8b8thrqn%NQxaNL+46alID z>2rPKPdh5P!*MepV)W18Io=9??r-e;=ki6r1vh@<`Cc$)sp z?_nDuLFjJI0?clN3~E-r5o%VoaDUC!JDwn~de?_emZB39nALJl55a!96B9P1fMeFY zL+e>ea0~2_ADGlo2aVG8h%xo5j#N7v4peJQxs2DV-0AixM*q@7dj7rlm+pE5AEReJ zf&2B&5)<4>^k~Gk09MAD?I?O1QTy}7d)z)mc_^UpxHgm+*5A}%gUE@b^Cq%nE#PoQP9Cw`F_cN9t%&*A(EXb4?NL@eV))TD{01AV*vx)Q4MncQjz%+^JLQQd8MXCUoR9x(j4w3iPl!%^w5KQbkBE!-ka||0w|)^J1PQuB2WQ6&S1Y#t)g~4Gzj9Zp80VbZ<(=Xhj5k_n~u$#Rn%w> z!04_gJ1((xI|Iy*%&oRo;Y|~M6t0HWH}!ZUT?4y+SmKyxOtW$lrhb3-Ls}z zS=HStljDX6r@amM-r~LP7a|`;c#M2`Kng+6c4Jhv0ukB?S(7HgxWPzPT9B} zMM2-Rq;m+6;E3E#fhHBJV+QKo8Q*&bpA^h!Z?vYgSEMkM=UFWj-c114^(2}HD7{Y3 z$GfOUK0yQdobOP;@+~*+X5T?o1h7kYF?==k-7ZQ*XC@8UH*($S!xX676ZRGx066(5 zFj&RWB?rrYm@1?=M?JDaH`PN-Xbn|D^wK88_QJ_C1iU# z_ZK9yMzH*0p521IgGb8JWQhYnKcR$qtTP*ph5Z&;1x+B+nH3m}a+4zs#^Uim+Nd~K z)vD;VB*LlaBvZ-2vnrs~Dxcn9^wFE0HBg&5S*52eq@sPIE9Qs&LHZ;Qp=7poJ~X8> z;Wcr|d`$)OO~J`f9C(~c&!bAiJ~-V}cq2*5AMRahQJGj>^UaZl(h`7H*^%){5*d#6=jQ9}us(bBvG| z-*r!0-hAtZd<4r_aJB*LHheKP&X=K8jROrsYTuL-TSZn644Q}o^kAODREa#gP5A51 zV~rp}!5Be{r zrpuM10F~z0#0n-SWX+KGY_Y}Y*7T{P#SK|?I;u*=BM*b}MJ^zQt6DnyObFqeDprZ5 zL~~eZBV%?^K;?J+_}(CSKI=7O6mtQ1WpZ^2_l>SyO=t?nj6MVVs$zReWVV}}U&hfC zS1wxq7%g+*L({-HZrjx2J=R$P`OxZ?usu(^&w;sW0$Rb^+PkBdU7fHDG*(E)O#jw? z@F!`4pkZS6RU@FKyZ=-h3bJ8%MQbam*2Hwe};GHooKOZbc7uPoZSUfeZ4w|?T zgIZ4OX!x$+PN5V7H)hHFmXa#4*qo-2kbLtUFE234&tSvzP+(%P%!iD3a8mKq_#Vs3>(tZjSIpe$ID`xbLQE6nx1DTo3lPFe+TGkce^AlP3#Nl8$m42xCK9*K4#km%bVI!ecU7I?9j<6SFtD&WQ!=ejb?rEbfMW6j8E!Sp;73?GlKtw z;OyO(qq(AoPw{wu1=sb0XIG=ir_hpdEu|pFk;e3b&Wg5+KH5IVGZKey&XOHv=>}D* z$S~rL5dck73MPi|oSgcZJBKIHz%mZj@3XU+fj!SIRcNWL4$tBVEDL;Nka#uNTHaBB=gj5&ziO7T4UpCN{)wI(G-!QmJoF5#XO)R|$vfngg_tWUr=P|4m zO&$a@sH1}Q0@52w>njTV5cH()O6bF?jsUVYIDOdiX`CtjEoaol1$f`f0T<9G(2h2}N92cITBkDu`CGm{taC+rgM#I(Fz4J}h zhs*PL{jGej4sps4iAyL}A0Ql1442h-#ZutkJTZq*-aw&|Gx@ibaiq;a&98d;(~>`- zP;F2<1=Bs$7KSxnG%u`qWn4nb2KA*z2JZ;g!cz)fY-5ZolpQRHAt}wR{9l zU}&%F0Z4victNC4&eYTRFUcA4pOZ-T|6D|5CRD)3A47}qtM`(1(maSGWe#e+3~OUr z6wA7h0tFH+dLG3ZJgfv(-jg~TWNEdsrUU-BU|l!Cca{FHP-C=gqmJ18=syv=UrzIy zwbFtY#7}CHA0L*U$y?J&Xb-Q4zkF^!u6LfF{hVe$P6i^uY6gUl3vscKX^9Mfhfa%U z!AJvA-`UWRCSgs~2T^g^*m`&-jM~F*$?}Y*_?h?iN(BfG_B?SxJ@QiAhBHHi56;wv z14drs-js$T6!mF$c$W%i1Q|tjnjXYTOqQR1F1g+JZGw9`q9zh~TO6=&Os0-HzWGChF}2 zNDfZZI>)%mGUTVDuFtMX$|f@yEHguW$;_(dsg+l4)}pKjH4h@N2wRucWt)qCZEpga zGP3V`s+@x2=UJ^6zHFdiTcymxtSD<_)C@RNSUz!I-x0dtqoWr03>#@qgtCqQdPFm5 zcjmW!*oY`i`@}!ramDGDF30+yzUgSSC2Y_0vXxX2lJ%3LN6>@v*0{}D^*Ud@TXx`+ zs>m6O0-96BS&P(UwdI}ph^_0oQW8KTr;*sTa7foBy~0&8B1Pf9kSh4gEwSXt0y`;* zWerqT=6o2#t`8Z&n5Vkl=(drVkv4IptyuN+!_x2YK|vv=e4|!nv0;ga^$C4t;k;nQ zFq(6uQ8jnnWST@E=|LmUosYXHS3)ktE?V4+BNf@m0q$ya-`SpQ`&BR=4&q`xy-O-j z_dK!;$)^e=!M~ry@L+RQL4V7 zavSg-6gvSC`+^_hJ1Nrtd2 z*5PIiU4{uqcUTZpiY6R*p#|3OBEJ-eP~TER0i#AgIuKakR2(!%f2?Musb#Y|EvmJu zi?qf|CR?Mydf3^nv+2p48?Ej2?cKoV4VUyUoSk}D$xAEQs)_Mx9u6uZ-QTZ8r?#Y< zO6^YQh>|;hP^MW6odKOIk`CP+1QloUPVPK-oJ^B5(&McaB(ieMbt%gD&78|Fc3K6U z_T`KlQ)W5rm~vHLd2 zy0{d(f2AMYs!HuA!N*y00rVB+g8bM?xq8qGX^Ac^23715!GMYxE29GTGF?{{np3)jzi-S|g z_%C8jr^ifI3~6IUERvXNv=;Q9j|*>!a!9C)BTdSbg~gK6juzUEhM#?|-bHZfw!J>4_R zH+#puyyqKt<2U*fQxV|x$)Jwk_oL)iQ2n+f8?OGZJuu0bZY)Q-&s=(Rgvrqyg822! zzK$u0bVZ_L8v2I8n$W8#HR59=`G-Frz^iXyAN+6gDJ!ihjy@?*l~<$UPV<>g{1*ah-@Xut*X zLP@+UAE2SX6~GG}MqYUF$Fs9epeR5$2>LgYbt*cb1kOh;*c%GlkO%+DAQtc!xqvLj z$BOhhSE{sKwJF2sS5O24R$iGG^VM5Zhdsgtep3a}knK83&lw>@R{s${9(98^0%?}5 zV%{KHR{d`>`A0cF!NTQdv3ugkomE-8FUT|xMu2$ecMTOoK3m}k@zaS!6r6r0d2Mer ztfr+4C#r?Y1)<^4{?I48cN(%uANAGxcFzd9_WXXHkX`{L3R2F12e_H_QT+v!AhS5* z02(E#DjHH!b{;3McpIlZDs7KRGzr1)jlE)T4rQ@Fyxf#>26kuNmf+l~LMu;QG09eq zbqRfSJaO4nq{H75F=*ddZ@gGNuN8Q6+j;Nht$~7p}NCWwQq5~Td|BZYjzyJ+{7D-LSF`rFDa>V5Y zVnto@@|F|KWCY+0-qDBl!IPNEU`Uh8EGPoFNnaqBmx!vEgvT987;9mZO7!OC+MsZj zc`v1h%}$Hef>m6Qmse_s{p2^}J`Pinm7;8Wz+hx1d^oz2Ab4c-;phFVB5Ba*u7H{d z|8M^&!YJH@p&X_d&X?L~2rC0jzWPup>8yv3sYOFI^k_KX>Mv0| zCQ;OfbZUfk+I%q+NKOV)aPT7aeF=xI1;B>{3avILf#NRF9|%mfR79NpYa?Cr&^EzIoxf3hhx#Xt#N6eD8Crrn@x3w*`t zU955e%X~7D0#ZeM*;w@vd=c`dY*HDkjd9Ik88}45&XVEC@;(a}p76Hxw2`YUR9Iwp z^E?Td@$Uh*G-BxKD55Dc*4TK*5iKin1phWxCx{}?yQ{sSMst|61EF=Bp?^4BnvDwu`xO14agYhHDi4ETtH z^zf5QKGR6jtm$87G7g-b0S)8GLuCkceB)Et@CeOo!Fx%VuiB?zSQN$h_i2m znH>=qYyze@H{O0~YuKL2Ci`DFtso2e1^mS63Lm!W2f)VqD{Q z3IFV)KGCllb!^(vBf_?5IS%enjgA_e2>T{t(%CnZygV{UN3y1YpA8B+DWj}(!b$nO z5o!5?Qjc-~esUR_@x`1rD%=x6@nyJ}A~c))E_8t<+RTzX7k(kJ;A_JaU);SR-52J% z)9E_3^*nhO%GG_>{1GQ+h|{8Qgv>oIKJfry72a*lPi*py#^SuZ^ll#3%~S%kouMUM z*37d2UdOE=9Cg3;ycMd}!m7L_ls z|NU__r^2FoF~PvFnZdwF{)a!q{7(w6RtL^seR)~fs*T%6piKmpJf;}!HxU{ah=wbS zWB`Tc+d@!n4+Zo1DZ|+mKB%QuZba7(`#t+my! z)w=hq)5($z1ReY-1bE+M`^^eIGkm#ScXBKBefAGYs2^n2ED{MR0a;KB7@%h5EJ+{h z=u+Cm{8GMD=giR~$9-agRnQ51W_3!L?8%5eqe9$_oOh+7*8`hPnq7}rd8U8wT>VnV z%B%;U;BYlZV6vjsooz1B@ptpX>3a=kBRdYqIojVAeDz0Cxp>~W?>)*{e-}6uipsr1 z^O+YqbjrBT-38l!1G`khPHCTvd`^3s!cM7~4rCvmr1p!IKX=YgJkPwWd(_G?{ToM} z7HufohIThfJ0-FV2FFrL2?MWF5}D!{hu&kJ!r= zB{$0#p#vjFU2?hLo)L3yn;C_Z7C3DDI~6y)+ebh6kZ&;;0R2j}?AZTq$<;qT@dAB0 z+GM%+M%O<*aPk>V-i#kycqdf2|H|K?|3D<0`^V9%Qf}C2%iIT`vF}h!!*F~SD58G; zw0~nJ3X5ZpuKHyezuHyvEVAqhdD$HA^y@lu{gI{islZRmKc;}fm-3JtKM1Z`J2?L zP^;I@QM=aGYNIwunSIe-XEou}yVSE;1D`#gSEb2M6#cZss^ItouCLuDr!g1@Y<>^m*)D}Xf4iaP|c$kFybja#M&HV6Ua1J)>`SaRyy0_ zcR^}eLe7vgJKbvR#)XKLYw_1BA~|aAXr)W}Pu0z33tCj1<&t`n#?k(q_X3phi5_Nj z#O1QQ6LTQMuWjvQwHSk@-0?+}i>8b+uE-)yIkp9pk@l<%4CG03{BqNJTl(S$Ah zkdxzMU~}z`vt*V3Ak9Y4P8=@V#zGNsJ%O}CUZ>gK$Bu1~Ly)1WemZOEg$aQ> zf!I>lSC*bRqXC}ZuIXW2S%7@0VkTnUU%EmG2pmf5k6NalM8n%bY&ULV$Bpo5h7@Y| zW=K!cpC3X=&km}MH}`7qUubnhOzvJiAM=Loz0$<*B7;rxK?)69&Ww$`46ce3p)Tm; zS~8=wzjgKcjsVZr%_aFSiOaKT>W75h7+8~~9wUPwo18|n*xg10A0G&^iHruvMWl)Cs-)EiNw&haGcN3UoWzGzI zrL`(QC`OXpE;oisshu&Z+QPgF8|s5U{&%$A3JuUfNe!2yfyT2~5RPs8iOOW8s6jXc zvxw1MkTK2d2S^n)b&P3iM-+=;TbOd|xII<1t0ViUi*1;})Uk&!LIH#_hdQI106_vs z*Dx6&oKSIdjKhp9cuL!B&_s>O_JZwGi$1I94_n@4=zKGXieJR`ha{OL#+_9V4VIE* z?r44}NIa@d8Dk8`-2*%QGDx>kB8Ikq@}g-ltz^R+>0gkt9L4e-IPKl!&f0g6eXJls zGpjm*J?KqNUtA_dsd`w^gJ!o;K&K6+M{_A2**vEJA+}WGw`m+(v7)g#5_KuAvlNwq z%x1}}!vtPB1+Bg~c+((5Z`{23@PxTfd(s^FRO4>6`wBx2jSStdl|#$cs!Q`CIqyKj z17?zM6jP4$g4Y>=Ch>o!GW`WrB!$^i{$S<)E+fIlf3dZ-s&OKrZ)ekp2j0l|PmZ|? z(FvSe^ageavC1#Xz=uLcVzAl&9tz|vQonv#`Fi|iPAk*R%2J_Ci^k}b3v0pP^%__A zw2_(&o3CQGN-=mX^ZzOZ4Hc!f>oz?O#)FmY5ln9e++!<0`A4%8wSQ+ItCJM zMMH^?#(t8yVJqSR%e(b=2hhR;N_g)W!i>|ah@a3qR=3<|l4SY=1JUkU~5e{=_v?TmLQo35yI_&F&77Dic#Y z=y2YFF$4|7^f}ym0WaOqKtjH`?*=Gb<|?-ztI_xnNbcXgc|hj)EF2Ktx60tk(KU0) z#lSHw#5tz()Lp`&!yPF;>0aVhY!-P|L+1(Dte;9dJaSx#BCQ(Zz6p z>2O<+m>CKv4nR$Jz^2PAo&=wm_x?r^Zy zAw*AEN&I+GYGp)Q*f^0xp-U~lN1!S5Gp&S9cAJCdV#Qn3i6Fa{JS&d|uDuz+|NXf$ z7Zcb^Nk}cyX6dFtE-I=)#G;HYIt#-~@zpNN*^6c7S4(xMy@&q;d7U%y_o9L;MBr_>^ZjIDmpIwwe(^H{iR1xJc5?0`eOY~9BO2e zFj|lIZX{%K`=2^m=EaX$J3!9Frhn;Lh%uqlf%{lB>ChqITrzoaU&<&@sLQUORU*Xg zhmZ~!`3rjWP;|fII{GYZf}3^jh7kyLQ*J`%>QJwYh~n$Fh>zwOLu| zaT2xoe0BEke8=^1VM-TUl3_Jey@G~r(HM;#Rx6GO3rJ?;nzEBg#q?m7J)FX>Zr6q+ zjMAC+JKa>@EfX8J7VEo>9ASBZ-PG>_ia3@M=hSfE=C%tNVd83-9Zngjrt5OW@yJ%t z!hR$4X(CjX2r8;Nns~^qwoqpyeqUbw+X9t8OUQu_n|Q;9`Kozyp0*+T%b4{oZ(+4e zdd3hR?$hD&(qX9x>Y$XuI+YOc^MsD zOGlj%42Ii8@9G&1LET_9;*JUtw@xm+^^B5{|=>a{iRM!P@q$f;1c!Bn4w)6(iP?Hw7K_R!!oq5~|qq?7$>TJT$kpfpPA?YY5f z$)uOaG}4Dh0SyFkNwLCQ73(LwSM$q5R$WjjDrVmhMb}cVM)x{Tc~>jCDbW#W9Taw- zsXoDCuxj^!FR%AOVoo{Niaf+<+4<6R4ctaj1G$#CXzrU8Tbd0+oN)6Wq|Mbd`%Gmr z^@jLJz?z&?gL4#)Ek)8MQ%xI|qtam^1ENEg+BB?R!qPSF648G?}iJa>hAwir1S?6>fl_;>gn+Vs4Dv3zI zDnF7@d=hNPZO}S__;DKve&8;vMX&)JZKqs|=Zds8TfUs7a;cRiX#(weJ~wBK`dp8f zj^W?F+?*<7XyJ%S)Zsh9Trlr{fN@pP&3T5wkBvXTq?@`OTDj|~=(033XL95UXQm&h zUo0+PbSet~#kU5~2wA@mzrHz)F+3DJe<$t2v4dX2U~s@z7eWhFUaOjCjVNdD<+(@I za7?r&K`pso0@3x!k*f4=FD=Hg(9e6c*R#9Rw*1BNG4h8~!KXr2h*RT7ytPkz%ZuCF zVmsabV(afT)` zzOA(|bHTMW{po;W#Q^wrzDDwg!bh`T)avaEX`=_j$F$$MV_DGv zN}a2l!SYkA`vol+l5BF4;wW8%x(9~pHqBf$Cb)p;qdP59k&h!T#+M&)P(|wQ`JayVWD7&y2|l z^F^CuSvxl5IoYJq8U2Ny?f$`4;Ia_}^${_iH>lez;gFQ9Xo;2-a;xD=jQ`6LhhpC? zIe*#GiSZfZ1&ko-mRwBPylk(=w!zgIrJG|7&J65#!Ray^^70N zQoM&$`_>Dz&}@VOLkLLLe4oWHDXT3|RFd2a^1)_2`SYl_s57f>FwBLF71^6n?m7br z%b*X7iwltfLR}I1$NaWX?*)#1eiYrA4I!tuqeE;!wSq)5Itghe%ffD`J8*~L1CPl0 zku+|1o`h#?n?h1&)7Thm*RxzEjUN$^;_#r#o@`Xd0)&tu*&ToSk`u$=qI#Gpq0YR& z7mDOkkRyaN$dmTvWLP*Rk0Y^+i%0JgzXmPaxP5!&R~m7O3-$}fv0b=8P$JnImpPu* z%#RH$)7fVYd)LK`En|Z&QIPR4lp9fAykWHI6Dt2nb(Q>UG9~gxd`0x7##xc(cM4I> z8NblVT!`6S7fE(Cf7vmzZe3Y#Yp3u{(xBm1RkTz(srx0feM@2+TzQozaFHe z*0>~~$hZczNzVVevV-)4Na;LK(sLF>)jV@>>GnyyW; zWJ`^|cv_@&tlcbnLXExKACV?NuDjg@o=Uu^auGjQdK#rewU)7Ij>%4V@_qn$rJ)49 zqNhL5VfhDILNzU-*-;BYXN03Gf3h^xSDMGZ=Tc=UIiI~NfS{V7>mWa{6w!_b8sVq$ zQ>vIrVzE%(!KtUEqC}K&K0>~*DRP=@pH3+T-bXM*y}-SSNKEsyK|nnwAAj1ZZ~H*% zje@FS>Z|vX6;U2Q*@`ru>9GZpSeQARGC{06;^{wfe(qQz@0c0eJW1?I^v=AU?J!-N z5mv-)o;W`wU*nZzZXP|%`fxH?U*MFmIcIzV%0__Ff5D*@2fQqa**ZvQV_`Zu@QDJ6 zTh=e5u6N+N+!NL;K16uYMPiB*mga1GxxB2yem@0BxP`clk)84*IUs-%QXTUhDtllm z27-1_GQ)0Nbf4f?&gnBDn{Xkl6(Ab)MQxGE7GR5i2Gg>Hu+|1w+|B^EZ;DFVgNzj|24gN1%xtB*y+irWil)SV z*s@Ht!d5(eID}rp9&;kQzLtN|n@URl27B`of}o!En~P@Xp4SbOBB`xYN>Kr8G(CJZ zQZd-&W6U?z0hGr+8$Viv@RHb11Oi38H{R6&Ddz$puS(vHSft?A&&I5rp>iSU!h@O339 z@ss%oBt7NTK4pTZV*EHUFIHg!BZ8!SUPQ>V{>}0(S`Rk}T-8E$H0qKe^D0&AgAD)R z&LG~e8&vHA`K3H@qbb+FDdc%!lAkkEQtd|W=GlHGMKG*(x5AD2k#MFbuZ&*9334i? z96S6K_h%#EV5CQjxEacQA5@< zKUNsjR+Ki_Px<+?yEAbPRckNkK{SOwhvv%AbnDcH;awnr^Bn&ais8pAnIPZ zs1qCvqufZ1bwhaKu<{PKgw3uzoRmWoE?J%Pk(LM0a`~s=x!-o^z^5^~Nf4^=ZQ>!H zD9N2QQaOA2G}Jl_XGl!_lQ^#nI`i;KIo6_{`u(WUVE{+JI!U#L%&tRyP^iVM8{X2E zIxN$qgUMNYN@=oAdGN0eC`wlH`$NjvTT+r%Z~TY0q*5R@cb!;!b12TmTy5%45CJiod*7LneEKCsvPK(iQ`?M8)P16m1uNm1bBh;kUa!ck6b|tQSf>+H8kw` z76Ej1WeIsfq7~ugbI%}Ma{s|DBFZYGRf;zteC-uro7bT1cCdLEmqWMyk#gT2<&Yir zEvp~HoJ?>E-A5R=tcPqPj&Y2{(9bP}>!9aL(9N{!<}2jiA>oUj#@}+40EF)tAJXIB z7|_lE;Ce+7klMQZfGCp!+OaE0k}hHaavs! zn)Ek>h@N4#}zc0uerau0GNgZ#xw=a|%%u;If^?jSxsyxd_uxb6m zHjiL}OFgSZ!z%Ns+)%=1QlerD{vl$QQkV5ZY~N}es4AFTCn=HF-XtZA|KK2jJ%GOU z;v$x@!iDEMmHVn09(%Kpe%Z(NoKar03zS0H@{NR6{a}6Wx3B^X*HBdfoFldqcNjvv zxB6DWBQ~;zf=Kuba)1(*iN;~JpXtL>joyzUotem9xo_IovycJPNnDfH34PTO!fhmT z&PHF^K-I4%B=Bqu;v|c~MXnN>7_eXROBY;=oN6lbUPFPdSa{g@*=k)A(gT zq_>d*HmT_b2t_4pzZw77ouC5>Upjz#eQV6KhcSUUmOvm}(A&QKibJ;2W66aOB{Vd5a}mqOh3+ zeo5y*Ovw^VfMq$%QU|{)!`mS;KdH;#rJj{it4AaHoo_9?T^!~xALDinVs$$61#Sr) z<$4}XJ>8X&1|V(o3M1^{Y3rlQBt|U0*EB={yN5+!pjx04u$~BlDk8lEW4Ws@qWe+) zR~thvW{Jtw)Ji)Lpg6XaeppwITWJWZ{`Ke2jLV9sgRu6f)q}B&pMzK5e%o6owvWB-Owj^NI)n9nI{!yQ_+ z6q8Ch=<$AsOuAFQm*@bQ;Wh|#WXWJ93w_Ht2^fTvOo#B= z#-=mHeOyk^bv2@`RIlRC#&=KDSN7^yg$~Iy7QhsyxtZp8ZZVsV_O9ymQbWz*#X>WE zz@rhZ#@Kqet&xgFYd6iS=vl{5*t#nlvuHlionsV#L#hr#uCUmA5Lqan!j#F_ICdQ! zKXOU6i5ATglN1N>>T_mMs^||m{JEJbXq^E_R!k*OgF0ekh7r{VZ`@e*u1%gUdatl? z(Ln=1KNgQt#39jW?-_ur8(Sog%^`cTGKdS7&J6juAY&>jI32y4<>LMLr%zz?5)LFRNTea;V9rJyuWZ z1z`&)AjT7h==CaPnoT+CJ|}c*PY4~9kTBE)VdC*SG*U$V9`l81hxNWHw8zv)v~{3X zkxj#(L$V9Q_R<`AuVOQI(+tj&k?3Wk%+0$44a~r5r~qr<4nF?sDDEQaP^i17~)5YFw?! z@*1Pr8@qV^*TN0tLk>R2^!3!k&fVLgHb#_yzVkHk!Eg_p<6Po6*3$(;&uW{3bGO4} zderba1VDJtjMcdoE)Sc+*4KUK`OO~YnZhSzH9{bt4`$i`u@Wa9EuTV%;-I94u^J8t zNvk*La0@7bYIBmk`;r&1e;XZpt?(7I!2C;DkDUafi;lBzrU>_-5wo=p!e^-+Ktqg; zGQaM{OmIW&m(M(@Ha>!vmXlo#>^-)}%Wa7K`Yp56fup#|%^BDztDyo1TefTMliD4u zsW$Nwaa)Wq2QCII83McQ*n<3SrnuQ4DWXE(S+(*+_tDxuPYkAbAc=sf%V^9(Q`sh;c#6WS{ zg=gG?fgFM6Y_Z$ANDJZ~1m+}P%iz%7J5%PC_nSzN5vnYqWyhn^+M=mE@}TL1c6DmF zLV0FdG(#jCZyES0ayW19ZORL)!q=5yx&0~E{qF3q-K#&EYdAw~CSO}HFh<-$^MW>mNPsm zAb|i)7at1z2r~wLq07agnbe&J_3@(LZ1s0D+%7vmxl!V#z0@o8i18?@Y_kA_4rgM% znEtqdC1waVXH$EN4we%6F#n#ufa{cb@;Z_&KEm;7g!US7OPYD)p6S`ARexv8yW(CP zeeB}_1*MQU;HE7j>_S0WxPC<*y_|3kNiaQQBpk;g?;n_eiphQbC5s9UREWyKt8(u^ zHM`8F;EM_titwh*O5}e+XX5>dJBA`Y8WlR<4>JGs%VKSedO0WZo8Hju)6=FHSwrr{ zFD1 zWxCvBGQb-*ks#V-@bilTNDGN;=1y%mp9m^BPZHllO&NW>z(v2y9k$C0>l3;(gm1%7 zEU+XgF7T4iP@nuaE;@QzI*O5iApf)m9?qF2g?MO^6FJr^1oKJMsI&i}!I8%GI6b?# z#r}e(?KQCN1WX*tim^fo{X$1PYwq?Tji~?0Fq?lzV{{oclGm*XWBw^vBO9T6H<|Vs zmVR>2`kA!xMavBxe!(IJk@SuJlNju4B@J}|fJh)}F#DgnIL6+^`BqN2bEI^i_Ccr0RLgDG~s?;mQ{81(u;@st=W1Tndbtrnvb@m1<|DLn&{W(F;I7_ZqAU$dRM`2;w8172RPuzSh0sW>U;WF<7k5h*at@NUfD?s&ub&JZWd zq2t-&-x2L$bfzbh?U0X9#?!-odXQ&^E<^%t$Zd>DxrS#?GA1e-$5GwXFzZdwXesHX z#s!-Vj`V4qX(Dd)HIn1g6F-Hny7!pW}ASK zwSLBkx8_ecyS!z^<8f4~z1Q)alahtq>MW&~reMWIK+uchbw$$bFW~LUFrPrs(I5fA zOMq)@GC!M^wkT;W^I{;?+^%^@$%E^SZ)kY-mtCn??b=5xZOZjoj9I<|EsevKh<<#e zq-Ci^`qZ86xQbbkG@~xHYO}T3f)1IK_Vuu^)4?AhegrA&C<$h&VYph+r7J3$oF-f> zT$K3;uUN}}WR#AhQZ_H1JqyxBN4N>J6O0E=>Fbr@S7&riAIuszrx+=CQ!BQcg9VWl8NG_laC9D3WLUdI>V%H+V`jB_ro%u?pz1)@iB?QE+3OQAzXwHq{la;v)HnGU6ee7o7>68d;Y$=pC;x z{a7XHv?n2^Iw2!o-NUGbSc(QcqKx6yf_Vsk5qFV&<5Ynb>HP(Nc44*f=2Yd7yd-zkPFbIQ&a%cxy8BH2z z#0^QYYRCC;DaZ))UgG}mqS4(i z*<(!CPWu6qa;-P-8h`siLLtY-C}IA7n`iEb5D~sE^Ea`A;~z35ceBwwksHWvAm%qo@u@t@Tu1z89yD1edZ-(hu8}X z?^f2)Y*~5#ea_Bw`_I+Jr_(Z_s^{xGlK`mq5fSXl=9kdO3hd$aqlsX0Q$1;%w1KwZ zDk9S8NraI~RnQk2iDCD6Lh^6>ZPa_*!bxm_?(v1LsVh-H~-VHwx3T);=aIRXgPD zB%|4L+FERMm!(!wMIACL)i_qRkl!j5P;Ij#)%-wZHURaQuDF-2(D691)3qvTv@TcL zcGZH{3Ry?JbR@8BbOlsT#g(m?kf2ia+%(te1wD`^_U}VYXAFG1k7vjY48RXEKU!@| zD>G9RXB&_klTMNqA0*D}mGFWqjnEg|SBjjh+8-s8S}#zn4XoEKecU^pyz0X$#pg%V zR`RO21u?RI@LPl(YTSfaC%6i4wq zRzy6*&K`;kHqG8?8%YqxDcimBhsnB6-s6Cwwr3mseXn@|k;lRG;M3uBmcE49s9>2Z z^i#HvFBV?YgpCT-v))XHfNR68R%G$Uk|f(MGZw@Jq%xxJN>2-Hh`M|nqX~S+wkZhIwS|c+lFt$ly?hZej-`N z(*Pv(4lWfs_|h27-UTghhufp)WO$sAPN)Xvi;gm79c6*5a)q8oRB8zeFDcRFLcn*D zAFew0PXl>Pw>^QN_Sc?r1>z9~vjqWUwTU4LbhSZ2!)}#MfrA-7n&nREp-6TKswq;I^L+H#d$HTdpl??qSg!q z07L6lms(?srU$6Q7mps&)sn~A*vfM_CIs~)?j`Vwmr;@dtg;GlWOWKNzI3mWu5DklK$(rhMH-^|;TJw16@V zr;&&znb!$B3uEQ-t}t(E*PK3()%pcaJ?Y=Ha$wb2f=27m0sw;FPxYypw_BJr=wO#b zS}^h)5ol8PyCVTTrloww+XUlT-~3BMZ`40!lH5yX9Ok z;n|nSXjwI92^U;J_3CY(Z>X=~NB2Blyg#})z{L&#n}_|hyUlN&cfY7XzpsC_Lg-(H z#rk}sE`sz_Xp@nq=T63y+_Ru$buq^1JdW*<69=&eL&As0O06&z0SxYwqd(LGXqco4 zlGI{+ALdiH$IFMEp()wTRv63)&-SvOEWX9Q!@KN*BQYDjMfesR;q5KiU*z|UXCh)8 zL|bpv4_16k4lSb=q|Dcqs5Q;#s&z=0gP%tKcnS^Y?~z&R=vmA;GD{qk$}*wcLgm1m zI0rJ=r7tQOARt=!Dw$^bgU6<&Xg!8@&V(NAmKu(UAGtzBVg>t>s2(DUmVzxPL3W%- z2j~tzjoDl$&I$#c8FRu9nWsg(q;Avl`LkUkcXe~I5#{2X1ux4+${m5625_F6%~om^!0pZ4sXBD8`_>7E8WPd;b3ZvLk&Jdl@_rACe|Ed-? zsf0=v#@doc&h_nc2t3z!NUmDH2<8dc{A*~uU$1r%uxO~K$5K}vY3D;az9SeKFy`gR^ZpLTJtbqL>LfFb2*rg7czQiDbopsvY@BLu zG(N#@tnaNiHGxn&VB<^{ai?!1P;27k{GsaFIg^hV%P=aX^Cwn%R@Iru`cjKa)b*kQ z0?UvELZP+xOmGQ8YJpatt6|}`bTv9CGDkm05u1 zqb=cap}DF&dMyMZVaJy6b@VGCYA{B}n)SGLSe@})7@KHq#pSJEkVgs(udc&DiYWSh zox#pa-lQ(44O5b8Fi)4Ip{-b*ah_P6F&hXd+d?qsK&rKldHUsif{D)_3+Nk5Ws|?j zgjFxd4PMcObNAhQ46*$BQC_j~ zn&MQ}`)G6bz+uyctuI(BFtuyJn5vF?mi}Fl{&=iH`oIECsAbe9L$Lh|C~z-ky0X*M zzcNt{6@R4dlZ86nWAL4cmcPUcVm%FEl_D?$tuZoja_5KKV8%BZ*tx*N3*TVL%uNpu ze~AG7`gzQ#Z$)C{4OI?|LQPZKoLL-EzI9X3jWm#vgG=vfcI-=-`HWWBUw(wh_wW)N zk0|0-dJWE2M3-f^&gWlyfHK`Tm4RrQDsC)&*l_dmdtfph^pCX9_w+?w+zj!BR6a;0 z&ob!z!Jn;v!u8J%QzjHD$)H6|(SCR^{Uk$JgGdf(#yUPoq8Yu+rqUTi(13~?`K(K^ zIk*_w*nbpj=ghpFqpPu#qq~f8KDd_ZL%YNyc}LvFGIPe9)UPWv3t}7fZP>w z416E0H=?>RZ7h5=^ASXC+4!&v)Qpi(9m381Fl2=VXMDPYkP>*~24CDfHzk`Wx<>5h}N!f=AlV@zbzmC?YT<;{K#v`V+m3V~XMiqkyI?$6=x9jlx40Dr9FyOsu zDse1240B`^{JGv)b$IOL*pZ0#i`-8^enYwoA)H@>nZwSreIU^5)hZK7S@!r&PF7#l zsc9Ho^VxO}Xs$u{v=bWUmWC#%S7=uzHZreX;diXsC1O`nz<|r8KmZ14 zTgRpUS|{1>bIess)~;dn-hMmDxaQO}W)SLnJ(Qh`Mgj~XT71qv?eZk88p}>NjpPp^ zf7mTp=Lj0T;(c(C(TarL;k>0n+P|GVw3#~c#HlI5Dr{Ajst!eB>)&x{g3Gy59d$Ub;k$*%G7_%>-c1ECI)~O z)0;{Nz8Iq-`Y&k+1O&rht>d%4ftbLC;|u^KzCZ3ccFpzv2@@RA}P_;~`2=&v^le}T75{s9XCXs!N;tlGrjx~~iX9{WG) z#aBrHyVF17JFxmB3DN&VT;5uu{HwJ%FL0n0HMn7t=>5M!F#maqgHFBve*qbA=_D6` z+xsmsR{&t)4Mwr%04q%~04{vrM0{{jKh>Lx1|FUw02Bm*UA&3FFH>Rwo?x)pv=$&O zdYldQ&OEs57`ke?@fu)19}nIA}Eb4I~5x%`gD$zHfSu1^@A(m}41nO7H<1GT t?}0=EyDbp_O6S1|OO^niMX<@B0FJ5x%-eqajj#RfC;zrKDJ}m?`+vvL0v`YX delta 22520 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
IA&%cW_eA0aRkj43NJ!y{{iGp}3 zYgv8~@%tF0so9}97;ic=h}M@K(eDUHTI%8!2J!q|GQt)%eAdnEi_GSBEIGWJXMYsU3)--|dW z$Jm+o-3iV)RM$M$^sB^oiZv+)(|VIWP%YOY5IAm}HC5Z(9OFTDhEIYBto2l1fh!Dj z4GL4TE9;CD>YofWSSyoP*#?AmJ4_tXeaW)nDAvU<|5E;NGhM`o;RiSpQ!B?rJNcz) z?NN~>V;0@BXI!IUE!9NQ<=@Z54jP~tl*#<+t$>m%JD-;IrE=^0kiB26Hk*r&jSoRt zhy>AC@~e(*<9+QH2Tvzc?0Sg_-)IX{NTX^x^+hzO2iMQKAG2B2ys&Hk zR5&o5Yn)9IdFN(dZ*Df};=E$C7ryx1vX8yg%B9&G&sC&J={0{5^7526IrQQ$NG930 z6Hl>=5AjO-ektkDxkA?rj$DTKFU&#_Os)jIrZzoW)+L|5R+GPL=)}yMsLtlT%7Du; z#R&z%y@py|K-~^fEwe9*h3^Hl-Q(DaH06xHC!P8e}>W;i1J9 zTd0@y;k|48Ahw!dl8~%En|LqP_(t3{2*L6$Kh=I--3d+3Zib-!F5xoLFPQkG@_}C$>l3xS zP=WD0ePfUcr|A@J+wV|U*BITQSOOZtDPfj1vuCy6u#ZV!df0?WD|&xCLyGJU%SyeN zpHsD0rqGD23k>X_?Hb37dr`V!aC$*{x{nUEO#doe$6U=Y?1{M3m@_>^7>C%G_cl~p zWhS2`7s__;%5c-1-ohWkHH7$a@HMATJtcIC`tYV%0J$I%(#p4dIYa#Tkxatir^WaZ zyYM$Mmf&|odgUDf(7+}}%n^5h1Kxi?ja`8q^pZTU>v zHv|#MR@K?P0W`6KJ+!i-oDmUX9-X;wpZU_buj*VvuKdX=N=8~EsfgTP$fXBkUB@BI z;|*6zaG00Y!-flL6k+jBt}1qFc_rr1wafPS_nR3tqlLqa+0nV0zj4T+Ct$_?pbkCW z({l{Qb-Je45N}9a^X7GFxd{#Od1{h&LQEkk-Gcn`{M}2eAt8TR5~8~mrS#!C4G7RB z&8UzOIJg6&J|Q=a4BcEm^GiL)J2E2DthU)-o^HqPYrJD|RtVt>wpm2bUcK(eUwF*_ z+gA+#rso+d`xuP~b<&_tD;E=UdkYRTdmEs|lN!7UhmW!ij;J+apaDFyuzH&riaYoJ z+wv0)jRT0A6#^LNxIuQ9fHONO5XX2AaGis|{%CoJBL2^(C_o+SU!WKs1)z!~fc>|- z85$bhe~_r(qJTE+f5BWtn1Im&0Z@*Ff?6T}n5lttBpg&majPPjXaR$HIH;BurE&q! z771Ygts+N5ga5(&iU9?p1T?t_0lWn`=!E^2LSumj_TTy_RQ35EK1&?8pj;H_N$LOO zZT|rZ5cmg#1!ygDgT5)=jZwK_p_RAlBX{xutzjtFG0L~Ht?2onlKfp!m|A2`B zqa`@#TIcV3E-8TU3~t4%C0P)*(LW*<@M4)7_V3yTiizP5HghW=eOU_7^g_q|+fIPC zFV$lONUey1j;(+IFFs&ml>q2kfr9*OQ7Q#+x}px^dmuGD<>;!hbOWGpH+$sX$k$2*9xg2ic|H zf&#Y$K~`C};`){(=xOdP+ei%|iktwj*@lA3@^4MF_0)fvV1LCe87c{xJ!e{{!pa B4=Mlv diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 92f06b5..f42e62f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index af6708f..1b6c787 100755 --- a/gradlew +++ b/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m"' +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -89,84 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 0f8d593..ac1b06f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell From c19ecdec053a8d239a195b784acec5a99be70c24 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Tue, 31 Jan 2023 17:07:03 +0100 Subject: [PATCH 02/15] chore: adapt to flapdoodle.embed.mongo 4.x --- .../CustomFlapdoodleRuntimeConfig.groovy | 72 ------- .../adapters/ProcessOutputFactory.groovy | 100 +++++---- .../flapdoodle/adapters/StorageFactory.groovy | 14 -- .../gradle/GradleMongoPlugin.groovy | 192 +++++++++++------- .../gradle/plugin/MongoUtils.groovy | 6 +- 5 files changed, 179 insertions(+), 205 deletions(-) delete mode 100644 src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleRuntimeConfig.groovy delete mode 100644 src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/StorageFactory.groovy diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleRuntimeConfig.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleRuntimeConfig.groovy deleted file mode 100644 index 3bc2e7e..0000000 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleRuntimeConfig.groovy +++ /dev/null @@ -1,72 +0,0 @@ -package com.sourcemuse.gradle.plugin.flapdoodle.adapters -import de.flapdoodle.embed.mongo.config.Defaults.DownloadConfigDefaults -import de.flapdoodle.embed.mongo.config.Defaults.RuntimeConfigDefaults -import de.flapdoodle.embed.mongo.packageresolver.Command -import de.flapdoodle.embed.process.config.ImmutableRuntimeConfig -import de.flapdoodle.embed.process.config.store.HttpProxyFactory -import de.flapdoodle.embed.process.config.store.ImmutableDownloadConfig -import de.flapdoodle.embed.process.distribution.Distribution -import de.flapdoodle.embed.process.distribution.Version -import de.flapdoodle.embed.process.io.directories.FixedPath -import de.flapdoodle.embed.process.runtime.CommandLinePostProcessor -import de.flapdoodle.embed.process.store.ArtifactStore -import de.flapdoodle.embed.process.store.Downloader - -class CustomFlapdoodleRuntimeConfig extends RuntimeConfigDefaults { - private final Version version - private final String mongodVerbosity - private final String downloadUrl - private final String proxyHost - private final int proxyPort - private final String artifactStorePath - - CustomFlapdoodleRuntimeConfig(Version version, - String mongodVerbosity, - String downloadUrl, - String proxyHost, - int proxyPort, - String artifactStorePath) { - this.version = version - this.mongodVerbosity = mongodVerbosity - this.downloadUrl = downloadUrl - this.proxyHost = proxyHost - this.proxyPort = proxyPort - this.artifactStorePath = artifactStorePath - } - - ImmutableRuntimeConfig.Builder defaults(Command command) { - ImmutableRuntimeConfig.Builder runtimeConfigBuilder = super.defaults(command) - - ImmutableDownloadConfig.Builder downloadConfigBuilder = new DownloadConfigDefaults().defaultsForCommand(command) - downloadConfigBuilder.progressListener(new CustomFlapdoodleProcessLogger(version)) - - if (downloadUrl) { - downloadConfigBuilder.downloadPath(downloadUrl) - } - - if (proxyHost) { - downloadConfigBuilder.proxyFactory(new HttpProxyFactory(proxyHost, proxyPort)) - } - - if (artifactStorePath) { - downloadConfigBuilder.artifactStorePath(new FixedPath(artifactStorePath)) - } - - runtimeConfigBuilder.commandLinePostProcessor(new CommandLinePostProcessor() { - @Override - List process(Distribution distribution, List args) { - if (mongodVerbosity) args.add(mongodVerbosity) - return args - } - }) - - runtimeConfigBuilder.artifactStore(ArtifactStore.builder() - .downloadConfig(downloadConfigBuilder.build()) - .downloader(Downloader.platformDefault()) - .tempDirFactory(downloadConfigBuilder.artifactStorePath) - .executableNaming(downloadConfigBuilder.fileNaming) - .build()) - - runtimeConfigBuilder - } -} diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/ProcessOutputFactory.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/ProcessOutputFactory.groovy index 56f04f5..1854638 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/ProcessOutputFactory.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/ProcessOutputFactory.groovy @@ -1,64 +1,74 @@ package com.sourcemuse.gradle.plugin.flapdoodle.adapters -import static com.sourcemuse.gradle.plugin.LogDestination.CONSOLE -import static com.sourcemuse.gradle.plugin.LogDestination.FILE -import static com.sourcemuse.gradle.plugin.LogDestination.NONE - import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension import com.sourcemuse.gradle.plugin.LogDestination -import de.flapdoodle.embed.mongo.packageresolver.Command -import de.flapdoodle.embed.mongo.config.MongodProcessOutputConfig -import de.flapdoodle.embed.process.config.process.ProcessOutput import de.flapdoodle.embed.process.io.NamedOutputStreamProcessor -import de.flapdoodle.embed.process.io.NullProcessor -import de.flapdoodle.embed.process.io.Processors -import de.flapdoodle.embed.process.io.Slf4jLevel +import de.flapdoodle.embed.process.io.ProcessOutput +import de.flapdoodle.reverse.State +import de.flapdoodle.reverse.StateID +import de.flapdoodle.reverse.StateLookup +import de.flapdoodle.reverse.Transition import groovy.transform.TupleConstructor import org.gradle.api.GradleScriptException import org.gradle.api.Project -@TupleConstructor -class ProcessOutputFactory { - Project project - - ProcessOutput getProcessOutput(GradleMongoPluginExtension pluginExtension) { - def logDestination = pluginExtension.logging.toUpperCase() as LogDestination +import static com.sourcemuse.gradle.plugin.LogDestination.CONSOLE +import static com.sourcemuse.gradle.plugin.LogDestination.FILE +import static com.sourcemuse.gradle.plugin.LogDestination.NONE - if (logDestination == CONSOLE) { - return MongodProcessOutputConfig.getDefaultInstance(Command.MongoD) - } +@TupleConstructor +class ProcessOutputFactory implements Transition { + Project project + GradleMongoPluginExtension pluginExtension - if (logDestination == FILE) { - def logFile = new File(pluginExtension.logFilePath) - def logFilePath = logFile.isAbsolute() ? logFile.absolutePath : - createRelativeFilePathFromBuildDir(logFile) + ProcessOutput getProcessOutput() { + def logDestination = pluginExtension.logging.toUpperCase() as LogDestination - def fileOutputStreamProcessor = new FileOutputStreamProcessor(logFilePath) + if (logDestination == CONSOLE) { + return ProcessOutput.namedConsole("mongod") + } - return ProcessOutput.builder() - .output(new NamedOutputStreamProcessor('[mongod output]', fileOutputStreamProcessor)) - .error(new NamedOutputStreamProcessor('[mongod error]', fileOutputStreamProcessor)) - .commands(new NamedOutputStreamProcessor('[mongod commands]', fileOutputStreamProcessor)) - .build() - } + if (logDestination == FILE) { + def logFile = new File(pluginExtension.logFilePath) + def logFilePath = logFile.isAbsolute() ? logFile.absolutePath : + createRelativeFilePathFromBuildDir(logFile) - if (logDestination == NONE) { - def nullProcessor = new NullProcessor() - return ProcessOutput.builder() - .output(nullProcessor) - .error(nullProcessor) - .commands(nullProcessor) - .build() - } + def fileOutputStreamProcessor = new FileOutputStreamProcessor(logFilePath) - throw new GradleScriptException( - "Unrecognized 'logging' option: ${pluginExtension.logging}. " + - "Choose one of ${LogDestination.values().collect { it.toString().toLowerCase() }.join(', ')}.", - new IllegalArgumentException() - ) + return ProcessOutput.builder() + .output(new NamedOutputStreamProcessor('[mongod output]', fileOutputStreamProcessor)) + .error(new NamedOutputStreamProcessor('[mongod error]', fileOutputStreamProcessor)) + .commands(new NamedOutputStreamProcessor('[mongod commands]', fileOutputStreamProcessor)) + .build() } - private String createRelativeFilePathFromBuildDir(File logFile) { - project.buildDir.absolutePath + File.separatorChar + logFile.path + if (logDestination == NONE) { + return ProcessOutput.silent() } + + throw new GradleScriptException( + "Unrecognized 'logging' option: ${pluginExtension.logging}. " + + "Choose one of ${LogDestination.values().collect { it.toString().toLowerCase() }.join(', ')}.", + new IllegalArgumentException() + ) + } + + private String createRelativeFilePathFromBuildDir(File logFile) { + project.buildDir.absolutePath + File.separatorChar + logFile.path + } + + @Override + StateID destination() { + return StateID.of(ProcessOutput.class) + } + + @Override + Set> sources() { + return Set.of() + } + + @Override + State result(StateLookup lookup) { + return State.of(getProcessOutput()) + } } diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/StorageFactory.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/StorageFactory.groovy deleted file mode 100644 index 05f70e3..0000000 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/StorageFactory.groovy +++ /dev/null @@ -1,14 +0,0 @@ -package com.sourcemuse.gradle.plugin.flapdoodle.adapters - -import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension -import de.flapdoodle.embed.mongo.config.Storage - -class StorageFactory { - Storage getStorage(GradleMongoPluginExtension extension) { - if(extension.storageLocation){ - new Storage(extension.storageLocation, null, 0) - } else { - new Storage() - } - } -} diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy index f0d90aa..ed2c9f2 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy @@ -1,10 +1,27 @@ package com.sourcemuse.gradle.plugin.flapdoodle.gradle -import static com.sourcemuse.gradle.plugin.flapdoodle.gradle.ManageProcessInstruction.CONTINUE_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS -import static com.sourcemuse.gradle.plugin.flapdoodle.gradle.ManageProcessInstruction.STOP_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS - -import java.util.concurrent.atomic.AtomicInteger - +import com.mongodb.MongoClient +import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension +import com.sourcemuse.gradle.plugin.flapdoodle.adapters.CustomFlapdoodleProcessLogger +import com.sourcemuse.gradle.plugin.flapdoodle.adapters.ProcessOutputFactory +import com.sourcemuse.gradle.plugin.flapdoodle.adapters.VersionFactory +import de.flapdoodle.embed.mongo.commands.ImmutableMongodArguments +import de.flapdoodle.embed.mongo.commands.MongodArguments +import de.flapdoodle.embed.mongo.config.Net +import de.flapdoodle.embed.mongo.transitions.ImmutableMongod +import de.flapdoodle.embed.mongo.transitions.Mongod +import de.flapdoodle.embed.mongo.transitions.RunningMongodProcess +import de.flapdoodle.embed.mongo.types.DatabaseDir +import de.flapdoodle.embed.mongo.types.DistributionBaseUrl +import de.flapdoodle.embed.process.config.DownloadConfig +import de.flapdoodle.embed.process.io.directories.PersistentDir +import de.flapdoodle.embed.process.io.progress.ProgressListener +import de.flapdoodle.embed.process.net.HttpProxyFactory +import de.flapdoodle.embed.process.runtime.Network +import de.flapdoodle.embed.process.transitions.DownloadPackage +import de.flapdoodle.embed.process.types.ProcessConfig +import de.flapdoodle.reverse.Transition +import de.flapdoodle.reverse.transitions.Start import org.bson.Document import org.gradle.BuildListener import org.gradle.BuildResult @@ -15,21 +32,11 @@ import org.gradle.api.initialization.Settings import org.gradle.api.invocation.Gradle import org.gradle.api.tasks.TaskState -import com.mongodb.MongoClient -import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension -import com.sourcemuse.gradle.plugin.flapdoodle.adapters.CustomFlapdoodleRuntimeConfig -import com.sourcemuse.gradle.plugin.flapdoodle.adapters.ProcessOutputFactory -import com.sourcemuse.gradle.plugin.flapdoodle.adapters.StorageFactory -import com.sourcemuse.gradle.plugin.flapdoodle.adapters.VersionFactory +import java.nio.file.Path +import java.util.concurrent.atomic.AtomicInteger -import de.flapdoodle.embed.mongo.MongodProcess -import de.flapdoodle.embed.mongo.MongodStarter -import de.flapdoodle.embed.mongo.config.ImmutableMongoCmdOptions -import de.flapdoodle.embed.mongo.config.ImmutableMongodConfig -import de.flapdoodle.embed.mongo.config.Net -import de.flapdoodle.embed.mongo.packageresolver.Command -import de.flapdoodle.embed.mongo.runtime.Mongod -import de.flapdoodle.embed.process.runtime.Network +import static com.sourcemuse.gradle.plugin.flapdoodle.gradle.ManageProcessInstruction.CONTINUE_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS +import static com.sourcemuse.gradle.plugin.flapdoodle.gradle.ManageProcessInstruction.STOP_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS class GradleMongoPlugin implements Plugin { @@ -53,13 +60,13 @@ class GradleMongoPlugin implements Plugin { private static void configureTaskProperties(Project project) { project.extensions.create(PLUGIN_EXTENSION_NAME, GradleMongoPluginExtension) - project.getRootProject().extensions.extraProperties.set("mongoPortToProcessMap", new HashMap()) + project.getRootProject().extensions.extraProperties.set("mongoPortToProcessMap", new HashMap()) } private static void addStartManagedMongoDbTask(Project project) { project.task(group: TASK_GROUP_NAME, description: 'Starts a local MongoDb instance which will stop when the build process completes', 'startManagedMongoDb').doFirst { def mongoStartedByTask = startMongoDb(project, STOP_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS) - + if (mongoStartedByTask) { ensureMongoDbStopsEvenIfGradleDaemonIsRunning(project) } @@ -77,7 +84,7 @@ class GradleMongoPlugin implements Plugin { if (!stopMongoDbTaskPresent) { def lastTask = project.gradle.taskGraph.allTasks[-1] - + project.gradle.addBuildListener(new BuildListener() { @Override void buildFinished(BuildResult buildResult) { @@ -87,13 +94,13 @@ class GradleMongoPlugin implements Plugin { } } } - + @Override void projectsEvaluated(Gradle gradle) {} - + @Override void projectsLoaded(Gradle gradle) {} - + @Override void settingsEvaluated(Settings gradle) {} }) @@ -105,52 +112,68 @@ class GradleMongoPlugin implements Plugin { return startMongoDb(pluginExtension, project, manageProcessInstruction) } - private - static boolean startMongoDb(GradleMongoPluginExtension pluginExtension, Project project, ManageProcessInstruction manageProcessInstruction) { + private static boolean startMongoDb(GradleMongoPluginExtension pluginExtension, Project project, ManageProcessInstruction manageProcessInstruction) { if (mongoInstanceAlreadyRunning(pluginExtension.bindIp, pluginExtension.port)) { println "Mongo instance already running at ${pluginExtension.bindIp}:${pluginExtension.port}. Reusing." return false } - def processOutput = new ProcessOutputFactory(project).getProcessOutput(pluginExtension) def version = new VersionFactory().getVersion(pluginExtension) - def storage = new StorageFactory().getStorage(pluginExtension) - - def configBuilder = ImmutableMongodConfig.builder() - .cmdOptions(createMongoCommandOptions(pluginExtension)) - .version(version) - .replication(storage) - .net(new Net(pluginExtension.bindIp, pluginExtension.port, Network.localhostIsIPv6())) - - pluginExtension.args.each { k, v -> - if (!v) - configBuilder.putArgs("--${k}", null) - else - configBuilder.putArgs("--${k}", v) - } - pluginExtension.params.each { k, v -> configBuilder.putParams(k, v) } + ImmutableMongod.Builder builder = Mongod.builder() + builder.processOutput(new ProcessOutputFactory(project, pluginExtension)) + builder.net( + Start.to(Net.class) + .initializedWith(Net.of(pluginExtension.bindIp, pluginExtension.port, Network.localhostIsIPv6())) + ) + + builder.mongodArguments(createMongoCommandOptions(pluginExtension)) + + builder.processConfig( + Start.to(ProcessConfig.class) + .initializedWith(ProcessConfig.defaults().withDaemonProcess(manageProcessInstruction == STOP_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS)) + ) + + builder.progressListener( + Start.to(ProgressListener.class) + .initializedWith(new CustomFlapdoodleProcessLogger(version)) + ) + + if (pluginExtension.storageLocation) { + builder.databaseDir( + Start.to(DatabaseDir.class) + .initializedWith(DatabaseDir.of(Path.of(pluginExtension.storageLocation))) + ) + } - def mongodConfig = configBuilder.build() + if (pluginExtension.artifactStorePath) { + builder.persistentBaseDir( + Start.to(PersistentDir.class) + .initializedWith(PersistentDir.of(Path.of(pluginExtension.artifactStorePath))) + ) + } - def runtimeConfig = new CustomFlapdoodleRuntimeConfig(version, - pluginExtension.mongodVerbosity, - pluginExtension.downloadUrl, - pluginExtension.proxyHost, - pluginExtension.proxyPort, - pluginExtension.artifactStorePath) - .defaults(Command.MongoD) - .processOutput(processOutput) - .isDaemonProcess(manageProcessInstruction == STOP_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS) - .build() + if (pluginExtension.downloadUrl) { + builder.distributionBaseUrl( + Start.to(DistributionBaseUrl.class) + .initializedWith(DistributionBaseUrl.of(pluginExtension.downloadUrl)) + ) + } - def runtime = MongodStarter.getInstance(runtimeConfig) + if (pluginExtension.proxyHost) { + builder.downloadPackage( + DownloadPackage.withDefaults() + .withDownloadConfig( + DownloadConfig.defaults() + .withProxyFactory(new HttpProxyFactory(pluginExtension.proxyHost, pluginExtension.proxyPort)) + ) + ) + } - def mongodExecutable = runtime.prepare(mongodConfig) println "Starting Mongod ${version.asInDownloadPath()} on port ${pluginExtension.port}..." - def mongoProc = mongodExecutable.start() + RunningMongodProcess running = builder.build().start(version).current() println 'Mongod started.' - project.rootProject.mongoPortToProcessMap.put(pluginExtension.port, mongoProc) + project.rootProject.mongoPortToProcessMap.put(pluginExtension.port, running) return true } @@ -183,19 +206,42 @@ class GradleMongoPlugin implements Plugin { } } - private static ImmutableMongoCmdOptions createMongoCommandOptions(GradleMongoPluginExtension pluginExtension) { - def mongoCommandOptionsBuilder = ImmutableMongoCmdOptions.builder() - .useNoJournal(!pluginExtension.journalingEnabled) - .storageEngine(pluginExtension.storageEngine) - .auth(pluginExtension.auth) + private static Transition createMongoCommandOptions(GradleMongoPluginExtension pluginExtension) { + ImmutableMongodArguments.Builder builder = MongodArguments.builder() + + if (pluginExtension.mongodVerbosity) { + // is already sanitized by GradleMongoPluginExtension#parseMongodVerbosity + builder.putArgs(pluginExtension.mongodVerbosity, "") + } + + builder.useNoJournal(!pluginExtension.journalingEnabled) + builder.storageEngine(pluginExtension.storageEngine) + builder.auth(pluginExtension.auth) if (pluginExtension.syncDelay != null){ - mongoCommandOptionsBuilder.syncDelay(pluginExtension.syncDelay) + builder.syncDelay(pluginExtension.syncDelay) } else { - mongoCommandOptionsBuilder.useDefaultSyncDelay(true) + builder.useDefaultSyncDelay(true) } - mongoCommandOptionsBuilder.build() + if (pluginExtension.args != null && pluginExtension.args.size() > 0) { + pluginExtension.args.each {k, v -> + // automatically add - or -- to stay compatible with old plugin versions + if (!k.startsWith("-")) { + if (k.length() == 1) { + k = "-" + k + } else { + k = "--" + k + } + } + builder.putArgs(k, v) + } + } + if (pluginExtension.params != null && pluginExtension.params.size() > 0) { + builder.putAllParams(pluginExtension.params) + } + + return Start.to(MongodArguments.class).initializedWith(builder.build()) } private static void addStopMongoDbTask(Project project) { @@ -206,11 +252,11 @@ class GradleMongoPlugin implements Plugin { private static void stopMongoDb(Project project) { def port = project."$PLUGIN_EXTENSION_NAME".port as Integer - def proc = project.rootProject.mongoPortToProcessMap.remove(port) as MongodProcess + def proc = project.rootProject.mongoPortToProcessMap.remove(port) as RunningMongodProcess stopMongoDb(port, proc) } - private static void stopMongoDb(int port, MongodProcess proc) { + private static void stopMongoDb(int port, RunningMongodProcess proc) { println "Shutting-down Mongod on port ${port}." def force = (proc == null) @@ -220,7 +266,7 @@ class GradleMongoPlugin implements Plugin { force = true } - if (force && !Mongod.sendShutdown(InetAddress.getLoopbackAddress(), port)) { + if (force && !de.flapdoodle.embed.mongo.runtime.Mongod.sendShutdown(InetAddress.getLoopbackAddress(), port)) { println "Could not shut down mongo, is access control enabled?" } } @@ -260,7 +306,7 @@ class GradleMongoPlugin implements Plugin { } } } - + project.gradle.addBuildListener(new BuildListener() { @Override void buildFinished(BuildResult buildResult) { @@ -279,13 +325,13 @@ class GradleMongoPlugin implements Plugin { } } } - + @Override void projectsEvaluated(Gradle gradle) {} - + @Override void projectsLoaded(Gradle gradle) {} - + @Override void settingsEvaluated(Settings gradle) {} }) diff --git a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy index 6616a22..59eadd9 100644 --- a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy +++ b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy @@ -13,7 +13,11 @@ class MongoUtils { private static final String DATABASE_NAME = 'test' static void ensureMongoIsStopped(int port = DEFAULT_MONGOD_PORT) { - Mongod.sendShutdown(InetAddress.getLoopbackAddress(), port) + if (mongoInstanceRunning(port)) { + // try shutdown command for older versions first + Mongod.sendShutdownLegacy(InetAddress.getLoopbackAddress(), port) + || Mongod.sendShutdown(InetAddress.getLoopbackAddress(), port) + } } static MongoDatabase mongoDatabase(int port) { From 2a5edf3480e8c63f7bd20be7d8ca215562a6c7d8 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Wed, 1 Feb 2023 12:05:52 +0100 Subject: [PATCH 03/15] chore: remove custom progess logger It did not work anymore and the default flapdoodle one works fine too --- .../CustomFlapdoodleProcessLogger.groovy | 34 ------------------- .../gradle/GradleMongoPlugin.groovy | 7 ---- 2 files changed, 41 deletions(-) delete mode 100644 src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleProcessLogger.groovy diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleProcessLogger.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleProcessLogger.groovy deleted file mode 100644 index 71ffba2..0000000 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/CustomFlapdoodleProcessLogger.groovy +++ /dev/null @@ -1,34 +0,0 @@ -package com.sourcemuse.gradle.plugin.flapdoodle.adapters - -import de.flapdoodle.embed.process.distribution.Version -import de.flapdoodle.embed.process.io.progress.ProgressListener - - -class CustomFlapdoodleProcessLogger implements ProgressListener { - private final Version version - - CustomFlapdoodleProcessLogger(Version version) { - this.version = version - } - - @Override - void progress(String label, int percent) { - } - - @Override - void done(String label) { - } - - @Override - void start(String label) { - if (label.contains('Download')) { - println "Downloading Mongo ${version.asInDownloadPath()} distribution..." - } else if (label.contains('Extract')) { - println 'Extracting Mongo binaries...' - } - } - - @Override - void info(String label, String message) { - } -} diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy index ed2c9f2..0225d44 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy @@ -2,7 +2,6 @@ package com.sourcemuse.gradle.plugin.flapdoodle.gradle import com.mongodb.MongoClient import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension -import com.sourcemuse.gradle.plugin.flapdoodle.adapters.CustomFlapdoodleProcessLogger import com.sourcemuse.gradle.plugin.flapdoodle.adapters.ProcessOutputFactory import com.sourcemuse.gradle.plugin.flapdoodle.adapters.VersionFactory import de.flapdoodle.embed.mongo.commands.ImmutableMongodArguments @@ -15,7 +14,6 @@ import de.flapdoodle.embed.mongo.types.DatabaseDir import de.flapdoodle.embed.mongo.types.DistributionBaseUrl import de.flapdoodle.embed.process.config.DownloadConfig import de.flapdoodle.embed.process.io.directories.PersistentDir -import de.flapdoodle.embed.process.io.progress.ProgressListener import de.flapdoodle.embed.process.net.HttpProxyFactory import de.flapdoodle.embed.process.runtime.Network import de.flapdoodle.embed.process.transitions.DownloadPackage @@ -134,11 +132,6 @@ class GradleMongoPlugin implements Plugin { .initializedWith(ProcessConfig.defaults().withDaemonProcess(manageProcessInstruction == STOP_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS)) ) - builder.progressListener( - Start.to(ProgressListener.class) - .initializedWith(new CustomFlapdoodleProcessLogger(version)) - ) - if (pluginExtension.storageLocation) { builder.databaseDir( Start.to(DatabaseDir.class) From cf6ef5094ddfb206a88d97eee16b1a481116c0a6 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Wed, 1 Feb 2023 14:34:07 +0100 Subject: [PATCH 04/15] chore: lower jdk requirement --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3e41d04..8884d5d 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,8 @@ plugins { group = 'com.sourcemuse.gradle.plugin' version = '2.0.1-SNAPSHOT' -sourceCompatibility = 17 -targetCompatibility = 17 +sourceCompatibility = 11 +targetCompatibility = 11 repositories { mavenCentral() From d936dd62d90198f6781a03da566c0b41b154aa7d Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Mon, 6 Mar 2023 13:19:09 +0100 Subject: [PATCH 05/15] chore: update flapdoodle.embed.mongo --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8884d5d..2ba1fa6 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.4.0' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.6.1' implementation 'org.mongodb:mongo-java-driver:3.12.11' testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0', { From af44db35671032236e7085d076d55a120663fcf6 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Tue, 1 Aug 2023 13:48:13 +0200 Subject: [PATCH 06/15] chore: update deps --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 2ba1fa6..1876e3e 100644 --- a/build.gradle +++ b/build.gradle @@ -27,14 +27,14 @@ repositories { } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.6.1' - implementation 'org.mongodb:mongo-java-driver:3.12.11' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.7.2' + implementation 'org.mongodb:mongo-java-driver:3.12.14' testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0', { exclude module: 'groovy-all' } testImplementation 'org.littleshoot:littleproxy:1.1.2' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0' } task javadocJar(type: Jar, dependsOn: javadoc) { From e44707761dc3f7b9261761acb209ffaa2af503e8 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:21:28 +0200 Subject: [PATCH 07/15] chore: update deps --- build.gradle | 11 ++-- .../gradle/GradleMongoPlugin.groovy | 7 +-- .../plugin/MongoPluginConfigSpec.groovy | 2 +- .../gradle/plugin/MongoUtils.groovy | 51 ++++++++++--------- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/build.gradle b/build.gradle index 1876e3e..bbd63b1 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { } plugins { - id 'com.gradle.plugin-publish' version '1.1.0' + id 'com.gradle.plugin-publish' version '1.2.1' id 'maven-publish' id 'groovy' id 'idea' @@ -27,14 +27,17 @@ repositories { } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.7.2' - implementation 'org.mongodb:mongo-java-driver:3.12.14' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.12.6' + // Using 4.7 for maximal compatibility back to mongo 2.6 see https://www.mongodb.com/docs/drivers/java/sync/current/compatibility/ + // On Ubuntu 22.04 some tests with mongo versions before 3.6 require libssl1.0.0 + // you can get it from https://old-releases.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu13_amd64.deb + implementation 'org.mongodb:mongodb-driver-sync:4.7.2' testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0', { exclude module: 'groovy-all' } testImplementation 'org.littleshoot:littleproxy:1.1.2' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' } task javadocJar(type: Jar, dependsOn: javadoc) { diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy index 0225d44..4f589cb 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy @@ -1,6 +1,6 @@ package com.sourcemuse.gradle.plugin.flapdoodle.gradle -import com.mongodb.MongoClient +import com.mongodb.client.MongoClients import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension import com.sourcemuse.gradle.plugin.flapdoodle.adapters.ProcessOutputFactory import com.sourcemuse.gradle.plugin.flapdoodle.adapters.VersionFactory @@ -176,8 +176,9 @@ class GradleMongoPlugin implements Plugin { } try { - def mongoClient = new MongoClient(bindIp, port) - mongoClient.getDatabase('test').runCommand(new Document(buildinfo: 1)) + MongoClients.create("mongodb://${bindIp}:${port}").withCloseable { + it.getDatabase('test').runCommand(new Document(buildinfo: 1)) + } } catch (Throwable ignored) { return false } diff --git a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy index dbee4a3..7579089 100644 --- a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy +++ b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy @@ -17,7 +17,7 @@ import spock.lang.TempDir class MongoPluginConfigSpec extends Specification { - def static final VERBOSE_LOGGING_SAMPLE = 'ismaster' + def static final VERBOSE_LOGGING_SAMPLE = 'isMaster' @TempDir File tmp diff --git a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy index 59eadd9..0274edf 100644 --- a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy +++ b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy @@ -1,7 +1,12 @@ package com.sourcemuse.gradle.plugin -import com.mongodb.* -import com.mongodb.client.MongoDatabase +import com.mongodb.ConnectionString +import com.mongodb.MongoClientSettings +import com.mongodb.MongoCredential +import com.mongodb.MongoException +import com.mongodb.WriteConcern +import com.mongodb.client.MongoClient +import com.mongodb.client.MongoClients import de.flapdoodle.embed.mongo.runtime.Mongod import org.bson.Document @@ -20,13 +25,10 @@ class MongoUtils { } } - static MongoDatabase mongoDatabase(int port) { - def mongoClient = new MongoClient(LOOPBACK_ADDRESS, port) - mongoClient.getDatabase(DATABASE_NAME) - } - static Document mongoServerStatus(int port = DEFAULT_MONGOD_PORT) { - mongoDatabase(port).runCommand(new Document('serverStatus', 1)) + MongoClients.create("mongodb://${LOOPBACK_ADDRESS}:${port}").withCloseable { + return it.getDatabase(DATABASE_NAME).runCommand(new Document('serverStatus', 1)) + } } static boolean mongoInstanceRunning(int port = DEFAULT_MONGOD_PORT) { @@ -57,23 +59,19 @@ class MongoUtils { } static String getMongoVersionRunning(int port) { - try { - def mongoClient = new MongoClient(LOOPBACK_ADDRESS, port) - def result = mongoClient.getDatabase(DATABASE_NAME).runCommand(new Document('buildInfo', 1)) - return result.version - } catch (Exception e) { - return 'none' + MongoClients.create("mongodb://${LOOPBACK_ADDRESS}:${port}").withCloseable { + return it.getDatabase(DATABASE_NAME).runCommand(new Document('buildInfo', 1)).version } } static boolean makeJournaledWrite() { - try { - def options = MongoClientOptions.builder().writeConcern(WriteConcern.JOURNALED).build() - def mongoClient = new MongoClient("${LOOPBACK_ADDRESS}:${DEFAULT_MONGOD_PORT}", options) - writeSampleObjectToDb(mongoClient) + def settings = MongoClientSettings.builder() + .writeConcern(WriteConcern.JOURNALED) + .applyConnectionString(new ConnectionString("mongodb://${LOOPBACK_ADDRESS}:${DEFAULT_MONGOD_PORT}")) + .build() + MongoClients.create(settings).withCloseable { + writeSampleObjectToDb(it) return true - } catch (Exception e) { - return false } } @@ -85,16 +83,19 @@ class MongoUtils { } static boolean runMongoCommand(MongoCredential credential, Document cmd) { - ServerAddress addr = new ServerAddress("${LOOPBACK_ADDRESS}:${DEFAULT_MONGOD_PORT}") - def mongoClient = credential ? - new MongoClient(addr, credential, MongoClientOptions.builder().build()) : - new MongoClient(addr, MongoClientOptions.builder().build()) + def settings = MongoClientSettings.builder() + .applyConnectionString(new ConnectionString("mongodb://${LOOPBACK_ADDRESS}:${DEFAULT_MONGOD_PORT}")) + if (credential) { + settings.credential(credential) + } + + def mongoClient = MongoClients.create(settings.build()) try { mongoClient.getDatabase('admin').runCommand(cmd) } - catch (MongoException e) { + catch (MongoException ignored) { return false } finally { From 3e1e141f64f89804a9c4b55ed69fc531ca5912f1 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:56:45 +0200 Subject: [PATCH 08/15] feat: add support for replica set initialization --- README.md | 1 + build.gradle | 2 +- .../plugin/GradleMongoPluginExtension.groovy | 1 + .../gradle/GradleMongoPlugin.groovy | 43 +++++++++++++++++++ .../gradle/plugin/BuildScriptBuilder.groovy | 5 +++ .../plugin/MongoPluginConfigSpec.groovy | 32 +++++++++++--- .../gradle/plugin/MongoUtils.groovy | 16 +++++++ 7 files changed, 92 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b9fc282..093237d 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ The following properties are configurable: * ```storageEngine```: The name of the storage engine to use. Can be **'wiredTiger'** or **'mmapv1'** for MongoDB Community Edition (default is **'wiredTiger'** for Mongo 3.2 and later; otherwise it is **'mmapv1'**). Alternative distributions might support additional engines * ```storageLocation```: The directory location from where embedded Mongo will run, such as ```/tmp/storage``` (defaults to a java temp directory) * ```syncDelay```: The interval in seconds between fsync operations where mongod flushes its working memory to disk. See [syncdelay parameter](https://docs.mongodb.com/manual/reference/parameters/#param.syncdelay) for more information +* ```replicaSet```: Initializes a replica set with the specified name after mongod started (defaults to **null**) ### Tasks ### diff --git a/build.gradle b/build.gradle index bbd63b1..8d954ef 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ plugins { } group = 'com.sourcemuse.gradle.plugin' -version = '2.0.1-SNAPSHOT' +version = '2.1.0-SNAPSHOT' sourceCompatibility = 11 targetCompatibility = 11 diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/GradleMongoPluginExtension.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/GradleMongoPluginExtension.groovy index afe8f2d..904d0c6 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/GradleMongoPluginExtension.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/GradleMongoPluginExtension.groovy @@ -29,6 +29,7 @@ class GradleMongoPluginExtension { Map args = [:] Map params = [:] Integer syncDelay = null + String replicaSet = null void setDownloadUrl(String url) { try { diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy index 4f589cb..3f5f9f6 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy @@ -1,6 +1,8 @@ package com.sourcemuse.gradle.plugin.flapdoodle.gradle +import com.mongodb.MongoCommandException import com.mongodb.client.MongoClients +import com.mongodb.client.MongoDatabase import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension import com.sourcemuse.gradle.plugin.flapdoodle.adapters.ProcessOutputFactory import com.sourcemuse.gradle.plugin.flapdoodle.adapters.VersionFactory @@ -31,6 +33,7 @@ import org.gradle.api.invocation.Gradle import org.gradle.api.tasks.TaskState import java.nio.file.Path +import java.time.Instant import java.util.concurrent.atomic.AtomicInteger import static com.sourcemuse.gradle.plugin.flapdoodle.gradle.ManageProcessInstruction.CONTINUE_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS @@ -167,6 +170,13 @@ class GradleMongoPlugin implements Plugin { RunningMongodProcess running = builder.build().start(version).current() println 'Mongod started.' project.rootProject.mongoPortToProcessMap.put(pluginExtension.port, running) + + if (pluginExtension.replicaSet != null) { + println 'Initializing replica set...' + setupReplicaSet(pluginExtension.bindIp, pluginExtension.port) + println 'Mongod is writable' + } + return true } @@ -200,6 +210,35 @@ class GradleMongoPlugin implements Plugin { } } + private static void setupReplicaSet(String host, int port) { + MongoClients.create("mongodb://${host}:${port}").withCloseable { + MongoDatabase adminDB = it.getDatabase("admin") + + try { + adminDB.runCommand(new Document("replSetInitiate", new Document())) + } catch (MongoCommandException e) { + if (e.getErrorCode() != 23) { // ignore AlreadyInitialized errors + throw e + } + } + + // wait until replica set (this node) is writable + Instant stop = Instant.now().plusSeconds(10) + while (!adminDB.runCommand(new Document("isMaster", 1)).getBoolean("ismaster") && Instant.now().isBefore(stop)) { + try { + //noinspection BusyWait + Thread.sleep(100) + } catch (InterruptedException e) { + throw new RuntimeException(e) + } + } + + if (Instant.now().isAfter(stop)) { + throw new RuntimeException("Current node is not master/primary after 10s") + } + } + } + private static Transition createMongoCommandOptions(GradleMongoPluginExtension pluginExtension) { ImmutableMongodArguments.Builder builder = MongodArguments.builder() @@ -218,6 +257,10 @@ class GradleMongoPlugin implements Plugin { builder.useDefaultSyncDelay(true) } + if (pluginExtension.replicaSet != null) { + builder.putArgs("--replSet", pluginExtension.replicaSet) + } + if (pluginExtension.args != null && pluginExtension.args.size() > 0) { pluginExtension.args.each {k, v -> // automatically add - or -- to stay compatible with old plugin versions diff --git a/src/test/groovy/com/sourcemuse/gradle/plugin/BuildScriptBuilder.groovy b/src/test/groovy/com/sourcemuse/gradle/plugin/BuildScriptBuilder.groovy index 6526e07..c82840f 100644 --- a/src/test/groovy/com/sourcemuse/gradle/plugin/BuildScriptBuilder.groovy +++ b/src/test/groovy/com/sourcemuse/gradle/plugin/BuildScriptBuilder.groovy @@ -106,6 +106,11 @@ class BuildScriptBuilder { this } + BuildScriptBuilder withReplicaSet(String name) { + configProperties.replicaSet = asStringProperty(name) + this + } + BuildScriptBuilder withParams(Map params) { configProperties.params = params.inspect() this diff --git a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy index 7579089..12d8544 100644 --- a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy +++ b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoPluginConfigSpec.groovy @@ -1,20 +1,27 @@ package com.sourcemuse.gradle.plugin -import static com.sourcemuse.gradle.plugin.BuildScriptBuilder.* -import static com.sourcemuse.gradle.plugin.MongoUtils.* - +import com.mongodb.MongoCredential +import de.flapdoodle.embed.mongo.distribution.Version import org.bson.Document import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner import org.littleshoot.proxy.impl.DefaultHttpProxyServer - -import com.mongodb.MongoCredential - -import de.flapdoodle.embed.mongo.distribution.Version import spock.lang.Issue import spock.lang.Specification import spock.lang.TempDir +import static com.sourcemuse.gradle.plugin.BuildScriptBuilder.DEFAULT_MONGOD_PORT +import static com.sourcemuse.gradle.plugin.BuildScriptBuilder.MONGO_RUNNING_FLAG +import static com.sourcemuse.gradle.plugin.BuildScriptBuilder.START_MANAGED_MONGO_DB_FOR_TEST +import static com.sourcemuse.gradle.plugin.BuildScriptBuilder.START_MONGO_DB_FOR_TEST +import static com.sourcemuse.gradle.plugin.MongoUtils.ensureMongoIsStopped +import static com.sourcemuse.gradle.plugin.MongoUtils.getMongoVersionRunning +import static com.sourcemuse.gradle.plugin.MongoUtils.makeJournaledWrite +import static com.sourcemuse.gradle.plugin.MongoUtils.makeWriteWithTransaction +import static com.sourcemuse.gradle.plugin.MongoUtils.mongoInstanceRunning +import static com.sourcemuse.gradle.plugin.MongoUtils.mongoServerStatus +import static com.sourcemuse.gradle.plugin.MongoUtils.runMongoCommand + class MongoPluginConfigSpec extends Specification { def static final VERBOSE_LOGGING_SAMPLE = 'isMaster' @@ -356,6 +363,17 @@ class MongoPluginConfigSpec extends Specification { noExceptionThrown() } + def "transactions can be used"() { + setup: + // transactions require replica set & journaling + generate(buildScript.withReplicaSet("test").withJournalingEnabled().withMongoVersion("5.0.26")) + when: + runGradle(START_MONGO_DB_FOR_TEST) + makeWriteWithTransaction(DEFAULT_MONGOD_PORT) + then: + noExceptionThrown() + } + def cleanup() { ensureMongoIsStopped(buildScript.configuredPort ?: DEFAULT_MONGOD_PORT) } diff --git a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy index 0274edf..e55f804 100644 --- a/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy +++ b/src/test/groovy/com/sourcemuse/gradle/plugin/MongoUtils.groovy @@ -5,6 +5,7 @@ import com.mongodb.MongoClientSettings import com.mongodb.MongoCredential import com.mongodb.MongoException import com.mongodb.WriteConcern +import com.mongodb.client.ClientSession import com.mongodb.client.MongoClient import com.mongodb.client.MongoClients import de.flapdoodle.embed.mongo.runtime.Mongod @@ -103,4 +104,19 @@ class MongoUtils { } return true } + + static boolean makeWriteWithTransaction(int port) { + MongoClients.create("mongodb://${LOOPBACK_ADDRESS}:${port}").withCloseable { + try (ClientSession session = it.startSession()) { + session.startTransaction() + + it.getDatabase(DATABASE_NAME) + .getCollection("test") + .insertOne(session, new Document("foo", "bar")) + + session.commitTransaction() + } + } + return true + } } \ No newline at end of file From f96374d8f426ce8f715bf8cb27050e585996d885 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:15:19 +0200 Subject: [PATCH 09/15] chore: upgrade to gradle 8.8 --- gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 3 ++- gradlew | 18 ++++++++++++++---- gradlew.bat | 15 +++++++++------ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 GIT binary patch delta 36987 zcmaI7V{oQH*DaihZQHh;iEZ1qlL_wFwrx9iY}=lAVmp~6XP)<~uj)LfPMv>O^|iZy ztzLWgT6@0L%Mke=l%(I{A1%VOoaE&Om>6y_=vN2gUFd_< z`I49N?Bm%~A$xw!r1{R)ZEe!vOQUafT$v|Di? z@6~Mff!Wcm&giJ>4E38a-ShQMLFjksfkL-#Xul77x8}fyTFt*bZ&h9SH`}sN~U_x_}#Pldr> zv8PI_b7zggb-?EDtAWaYG&Te)NF^l1gw$7Xfa2Q-YdBa8OPHKtm_`rt1=~xTUSIjj z+go^${hAi!SRJv)2O8b=zR63PD~Tk*_Yvpua(%(S=~K{G?%DT~*d^Cr$1(C^Vm}Q~ zVLy^I#0UPTJ$oXhmg-9M7r#Aph|D-2@5k0J(p&-_!6)sMYQ$%^=aYgdxB?0>3_jC| zj2_tn`fWF<{xt_gWgU6)H1_9mv@wKgLm@)0lB7QcghC~{EFE*8e$P_$6b+0fIztRY zX@clnI-~S{Zp#fiojF&=p6!b96xJyKrUAo1@qMyVO1?#R+l;^G0&x(_^e1#~vIUzX z5t$4=rq03TE5&IOqI?!5vLi$C@RLRfot(xi zT;}ESD9NN7S~G}$ahl^rg7GMO!*7<4kBhQMUSS`ekSr#$rASIXZmOZ^c8<3KnC!<6 z7?zx@%cm}gQ?EGDTAE265Rqif)4jz>4)BxeDB;fdP2tPzlV5GSZ;`M}Cd5jF6o$i= z(ir7Yt+E1Z1c*{wzDQi@ak!pH0#gml1PC@))5D>OL4J3a&DwmI=`zji_dOfq#D!aerL|9DXaM+a9 z3J=wmi&H@KNW+@__HM|Cst)tVUv@%Yv*nIv!;L$H&t=xdv3V8r|M`st@ccn}rN@gP zD!i<6pLa@){asX!DBU zKSQ6TFzX<|F-UClir`U2H74RDBWDOHgOqA`=E{7#xe1C1pd_gSY=<>XrQ zo)%o|1RP5LU=XUb%9ri1?%a@R`&N#i4#_BwWR=i)73-j+730ZX;*dkNjs2-E7^xJJ z?^dLOQbk!6QWo)+Re{M7Rk0$L3r$^QfCe`#Lb(QiEY>bZC1uD9upUE|xK_G1EQuUZ zf!l?lt&gN2rEaL!SEQ8ZV>g>02S3EYO%dmo0fZ`KXi#4yBbUpahL}@|1mj1HJ*A-7 z=w;h%t0koLjMcM2+RM{pOqBqSqqGVmQx8DJL)aT(*P5@U^{%qC7$z|m3L-g77?xCP zRK-!J*rFA@<3}wvc|z_ z)}Ccor@8(juC*77A>*i+(@IWT?p)@iXS=H7R}BSuD$0}1q%cjJm>h`XSwEw?RWHO# ze%5l;23sUNkFQHDRt`QHNnlcsG4y4oX!Pviphr`2r4EuLbAu3c-vsk< z;C#bU$lgd8pOG-yfeZ*V%bPu8RhDIH#rjRP8vdP*7pnPjFOph2+3M;Z1kk+7SXe=GNJ6X$r^i{PG@!RjmyWWCh++^w!GUYDO-Tsk_}N z7#EvAR@ZKhSpYIJv1>%VZVkG^v{B8Cb|fy+aV#m7e|MEFS!EXoM{XK-Iu@;{PL^Y< z&{^c$(~NGga46)V4!Ots4s>8~34X}{74nmIlga_Srd*WeQrC6aT`*l>6ivlW{bK8C z_DeYI;u-e_-Q>I4pJZt~luT`Lo@TE_!DL|%2`mbwPuv78%tX7njeJ>kl%QM6B9?n? zK3?AuP_ddvn7`&_GPF1*zJpmD;U4Stu7ut785kOLi|nmnpSp`yg~@RS$}? zG?oU;l^b%ymH#O!A9Wj3V0x{2Am`#)n?XocB&5yzBn#1exuW%omymlf`<0?uce^4V z-T-^gBo%-pd@0EUj_AaNq`qyK+P((7nc7-&BAVG+8=P|#qyQ3v3TH00Uj4<+ z5z&n>JHUh=z=*ufAk%eNu=G9nw*3vO5&8AV>_)hDBQ6Ka*Xuz-{-~Zf&HS5Rh>Bya z3R*<_OV`)}`jO!U54MC90^^duSyBMXzsVt4#A>RY$S87**y9EUnI*7kz+i@*2+${E z?#p~)NP2Myd@(7;uP`SS2hB_Zr$-K`Uj6Otmg~yBMjUVjjFDalRrn=)-WF#JHdPxIifOd4 z(tMQ0raUN@I+cO1|ESG{CUX9J`gSGZ8pn&$^Qol!$6V3#PRltYB{&pT@`8XL;`iFX zTDj2&T7{aEX@z8=lDc4NGb9rC21tz^;=k1II07nZ+Hp3q2V40JUYDZiKtBcd4m~p3 zkm6gm)3G?AplO9OtP-`)CqQSRt0DJ9PI_b@s(iSviBG^5ukW6gYqT#_gY_3nNfr$J zUlj=r4FUop46-%K=*;x*i!HgtO8|d4kaa2=6%JM<+AW$5HCja#7$x%{!|JMP-vN?< z+YIGBhXQ{3YTcK-8KuOj%iX}BR7Lz7g-(PiB?wwe>Bq4SHFVNmU#b3u$OgrhxGzNh zpk}{Vu#Cyy^1I9!=UIoqRh4ApXf(i2qBL@LQVm7X`Vh)t^5KOOaiMExc&BZwED{*} zA$%lm339JHrJxW={CJ*GY?~QP8^QId`NZW|J9^vk%p6qNljZf0-c}0R%#tda=%z%? z7;x?QiYyyJvy5{W&hM>3RLiJK)SYVhJQ#suW_Fl?!P(VLlbZ1ho+R+3Upj!<+Q~55 zXNW?{d2=B5^P*ae^vZbl6yF7e6y$D98O^Ae!t4n~6Rz74Ha|@G!DCrGgCa2NUJ4u6 z&3+>VfvwfPs&kZOVBW6YUbBQ9=0aT4Mbw{R%%v$UmLWT=${g)D$-(lE`TFnx1D>|C zv$@yfvD;Lh6h>$o?YP3na~mKQI-$FS>*Uz}Le+`ic%46;-YJg5!940hz8?F)e z!!=G=XVo*Ng|#y3(VC(848`+U6a>rnwm9>!5-B<3AmiB>vKjtLL34=tQtGIqt@5mE z6XtDRL;83~T@P*e4^1Kg!L)jSV{J)RCs*VCZBL2G+!}xpx?rDv7FYSlL`}VDPzGFWR(r(k zl>QpK@(F>$o-mIA)0tjnmlo#gO1kF{{$wNYOij1jRsE^QX2G9(*HQW_4^q#{>HETj z)KXZS?{hx;bZzdh{{o=S>Nrf+jcHyn(POE_bLkQ;RA>+bR`Pk@U(p9k$I1?!mopld z6N*W;DAlaCgv>{85Tjp5d6xud$o<};xVIQ9B>d09JQPrH0PQUX7pu3>gXEnc5bU;< z+4@|>j_An;Dq$6IPajUw>LQwu7WbLHDM;dHK%+Q&Get{-B{ZN3BU)zM!$r&-y?tI7 zefXTSRuA0?TzH!#M|LARtH-EDEGkKVP9gYfhX-S@4G~{Ul(w@wh+k;N%C9MnVgtV*SUz%z`{Ak zM=zt8=PdCHL=`w#l*wQ}IX!_YZy63NM!msFk&a8q471j~*-VwRfxCV60q-gqBc6x5^BTZ1kHmcm zB@Pg6?8W}uuVy+y@39Jej%MiI!fz%m{w+&3t(c;IaECQLZc)^95pc|o-PFG3rz_}t z$d{*do`l?{=jL5(oNRLyiyw(YP7+@9L381o+h^FU>C5<8mRRW6@|e|koHivsqjOhE zX7gZL4G+U;OWV;V9!97rh791f!2Xr(!bZ#Rt~O)?^0YP+3J*-3P9j%e1+p}nB1>v&2#ANy$m^R`*%_4_i^#f-V$rbPn&lc{8@a}u4 zm}*>dCGpZ#FOowv6s{2aMTASa8UCH+psV-p>)raxb1J=idPm+TAFCh+R3P2@m*^Ra zl7P4h7W;~&*%`@|pf&CcPV&`HwrInIbxQRi6x?`XVZQw0=$?Q915(MhuQI-SZbXXOjwFPu%Xfp)hYS} zT>NO5ceDTDN}?ofDYYmi82v!w zTyjJ)bA+JbN&rVN)-1!uSp^$DPF@;|1>KAt|FT<*3nIf!k(WKT=g2+jkE-<3jpYIU z3efXbEz@>d)KcN{(HAtdVN zBJVQzEd-c!|9S{GbO$vA7* zsLOTYr3tz3oT)s4u3i7l=1rmRw=*mdS1b+HSW6T z8Q8HZr7jXtz$ow742XmCcA7I3(Ij?1q@;obb~e6uoDclx^O}SJ?+|lZwf3>vhKeWc zFPUoW%2u7$sw_U9q2-%O4gL0}k{+{+u%2lr+eO_^cLd4qrK0rQO_PLG8$RA49FlcA zHQ7#gLk4vz)Y%pG)}~UOuywA`q<|^rmMWnt?RWVhK-E^LM5T4IaEEDDXRC(tg?sMu zVjgj^K7w+I@Rd?498Yc|GyL*&P_2%~SET*2TwFX3(lTj=8XYxWKyyhh)B#3)b}y`v?0iwfZ~Ha-YX9v)^aG><)l3 z@OT31B?d&PH8xoW^^!|$k3hz!+q`l;Lxio0k_zmI!FkGpDvee9u;^Om9XW6Jc6GN1 zfRQpW_6@`UC)6E|o$1S#Lrr(!;*w5-&oTQWFDmUxN|t)6mG))O!~UHdLCSR@qi1NJ zP`9-0H=I}c$9Ht+uyhTnNY4^-s~$Z%>PWVR|Em}S)X-K-m%NYAj12u3nQx<)3DVb% z_013;dmg5x9igAy58<@YE^@pww#6}Oz(!bek&X;&7?M+?^%IlR<3i1~DD5bk9g<&m zBhj8u;McIM6Oq3tFY2h9=8o8p~)M$v_?1ltv|ko@arfhcLlUO_o4uKoGr# zYRf%|lu#u$s+lV~SHdtmM=1@J)b8%MixhrfGYN8F^Ni9%3Ejdp!SyG`w{%XGU6PxY9WYN zemCR-gryT!QU2^6*+lr9^_NHz!8gQzv&60aEvhUi2*?dM2#Cc0u*Byf1)x+_UlC0h zU7-0>t3tODqN)g*RHo0YkZH8VdYO_^{#;UJ@S}y`e6MM1+947!@;#4b$b2{Odg(}d zn!6*9fLR-fl*{LOvh8}qll$p^cT5+6YlD-qK5Hb*M8m&4MTW-5tIw{?sm!8mF2z+s z7fdNyq{V9{)z%$oq;)Q(3Fs!we+=Q>69{L0i(5OHCDByLKQv?YqVfxi#e5OpdJ4Um z`k5EyP*B2W=S@Xc=e0)zS$)+h(u#lm5d>@C#?R3b9)*N&{6b)j_8ig$w)4cG*{ihW zN__!uA;iCc%{Ma3B6Qp~v{Ohxa?zZrl5NwiOf2AOc#-)-uHLr94nQ0qhmE~r*7f72 z4=^Ixcq+T|`!P;jsAA4S#vUzR^j5F(!~LrJ&N$xq!*CuxTA#JfQ+$;F83wTELA&)RV zrWJ?Reb_P4irbwC1gsHu=Am{94V_~+O7ta+&}13A5(;z}FJeikKh97XTjigcEliY+ zQfSL zL3;$Ue+0$|+l8Str4>(RsNZNPL-QRwCwoB780}*^pv~#9n=J6qr}-#+-VA@{&+7-7 zwCTNtsipc`N-2JklH#>a1>$SPOXsPun?S9vAfl7@yRD*M8wX#bt;65FG-8ZG0a0ch z6Lu)ho5H$q^K@Tf{u^?-#XeX|$=(^}fQlCJT1+}d_=yC>5;k{>#h{N~rizGF1SN1~ zH6`5|U~VxX7ylPV-r?@ve#OhI+#*F_i|_rEkK=XM$9t0D_uD-l$jqyn1cO7mayTFP zHcc@$o-9n!T~lN_HxrD3o5T)1365|+xacUUU7~VWt*?yuydfkSCKvjZ`x3|>bknbn7p^#44*lj?_Smq-P zjG~N}%+E$hy&={v{VnEX)I5^$P8j5OJ1+Sh2U+X5Vm?rLg0x&anN1ziQmzqI3DxYC z-TKT(#G&Q-H9N_6EX9&OJ>pAQ0J4@FtV(`Z!_>iHKR~b&c z4m`3Iea!{9uZFvlZ0W}2eH_DP!D@;}teR^0KG02b)1F*@Mt*D9>n`OY^~+O+Em=Nr zhhf^G)EL(xy1#c5=T~h*IV_)r#pv1-bjW56xV9%`v0Lc}*V(iDW*NFLfR?ugn0CHk z7u*MCG=9Z4uAXWuZ#(|jnsxLk3rClbpTbY2Yf+sm_i|B2=j3i*=W}6!yBU#oteH5a zV1!9B+U{Wk7UZakizWB5q`T6=OcDaDM%-uxc*>wq0w?aTnoBon4lqG96R9 zGPEnUuR)X+!F%mb`~E2bC@QoB*CgELgq%=x6W>033!T84GCkZkS#7Bpq}?q}Pq`Rq zI1wlWgYk54$!s})>I8%7W(F^fpB3!6)Et?I_ix{wJG9!{^QChe_EhYd=oJx1NkGVJ zRT<%AVbG6>!`2Py1g=l4Opp&$**gnFoZs(tl8C=l?NY2{Q7FU$vKrhZIT$qETWdS3 zGHocm@hUlDsct&ubsxE{pHU4go;+y1AiBUc+On#C3+*|~B~^-M6(g>%79`H2om)(4 z98#g|Q17cl)EjFFLv3Po$F;)#?$?2Fgw<1<-^vX;RAPL46QP8vH8L>ZzW9sjeAT2N zsSM$0+8!bR`+PtEfVeS95AyR;9Pp15leOeM##J-bUX9}|*?MouBYm)x-&xh0Dho6O7C_jPEo}as6-G#3Wgh7?EdKJb&XaBe6q?!yFE~xG5&t>P7MbQR z&6aMTOI}eB0NhUn^y`qagz}PwSqMYKMy#q$;!Y~S;8rH>*BrbHnCrZGz}jVaXwZhb{^6jw3*O6?X_jjrgZ1!*r+Ll&6`H&q)jCMtDt*tYbJ44sqiu%6P#nZv?)W2 zsJy<_msgJgy&%<1jg#!@Ff7s78~AlOVmTA`Cd5zHh<#L2C1>`QtEnGqlN-XXIPR1pBXg55b@l+>bEHm z9=LA56`E(atPz9GBWJ~d@WwjUzNkmAL6-$YLKH0kP00~ubn*B?;0v_~8Fl2S1ajPJ z{Ld)P7-H01#r{Py!gx#_ED_LQU1}7^0=@27ZxgPnVZt1$XOl=TC{5H^*nGCS!Ic0{ z6Zue26aDCJG+W)vT&-Q?o%a2#pIrjvp^cqI#R-OEL8jCfwMrs}rW%gUkFFtIef^ik z+=p9$b?QmBHCLDVGd)y1QE`-2wBnBNNYh43aSU%T6CrZv0Cu4Wo4X%6!z3-y@%(VK zerMWnoei*SNenL`Pq;sQ^cmYxmITd~Xcg>2lV;Md`6c=W+mN z@-gzRN!=?V%bkGu6Vx`1|8T-94ByBcHfG;E-5HlJMcg6O9iKlc!0Rh2Nzp^)w}(nj z^c{wGT{LUz!-Ln}5GH@TJ5X>u2m*Rc;Wqgq42?R~>2SA#_s0ldjxHi?OLmZxJ!M&n zT|#l=d)QlHF|uSCxLtbr&*=D6c^(5CE+}!bVk&A}oQvS1MCWKtcHi@nTJmCOJpSJH z!U0!NY!>c{@(+v_L+pb-TKtwpPp)RBc%>vhso-w}=UX?aFQorYZPfxl4od!2Q;(4U z|C?(*p8%k*xMYMr_HBu`vxWCU+sgiZw#K1rI2;HncR-1lN zSFvH?z0@{2rBF;_R%;{8_J}70s(nE1$zc8V0`u@@020a}VzN=`EC@E~RJyUwyt8I9 z^e1^q-BNYkcCa;tkbv^9CuTX{%2g8T%Mjx8%Z0N+^U{X_n7ki z$_wBin0iZOb*j2|%0V{NT|^J)p1PZu9pW!Z__N0Ir(3}D>Sqj@CVmGIt*cQl65sJ} zf$0GdZOOJw{xps{0YfcWleF8m@<`8@OvE~G7cmT;}cN3=Tv4O2Tr&iLl?aKZaRRW!?2J8t$d?KEU5SlPdP;fc_l*ut$Q)>wc@ zM~1x77vU{?{MwNPCqgVxL`Ugi@7X&ZutzKaac^|*;t^xZO}JA&s2(G`-TpgSPLf-i z3BBQ{6?iWeMTUmaEQ>exdk4dq8(fydamLUJGzZZsN|dYbL!V!#OF5I&!WxKWNEitt zT;5+c((GAdFbS0BRv_v*ruABlkMmsivszb#GAP0#UKU-J-Uv?-^*#y`PR*y< zy7}OdsDkzf?vu?S%~vXwn_$k?tvKk)yhiB|?%~mMX&qBK8cMDJd>EOGqURHBmORgs zh*-Tk6NiK&PwrcsBR0WZb<)7le)^@J%v1ej`L8yUB#Lf7_@Q~RI}E^#D}uwCD}|z# zhoAL5k7!18ryP(@ioy93VN8%Xf=K$=pQ&>%CcbP#G5dVgwD(F=ijIdtnPZLKx};NK zPD-2rhTJ`8G$#(=pR?$UHbnc!eS0t{N}NDe%OV4A+Uz*gGKxbMXi%wsHv}Ktv#oN) zIrMnP{c<6Wu*@evA>7Ob7|dgp`;@g;-!{ia%6oXU^NA}?^O-+REEp)SyVJQEz*D?s zb!?gLlhf$Pu9D5govl`1a$j=w?i|T9-InEP)crpGB5Vh6Ug+CUo!}yj(vUrNET4(u z4i@A%5@)8MDdsVw;}-p3&LOFmieRplChLN;XsCzAQSE{T+|LEgs^pj#G_sJdbBB$m z7h&fXKJm~0mX1YsHt27d>y~O06OXyXq9#IoBSnXr^0*a4^d<#H$f8>UV^H!fq5SOC z23}*Bm7f3$lf5MOh?N2r*^5aill z5##=!ckX|J@c*DBe^fAoA^YJpGgb!uK;WULx~%+nZX3jZyq5onX8#F0slo(Yr5;+@ zq9BWl(=QS-NTL9OtZGX_o*%t&$piK8A5o z5FjAoBqi>4uHHuMKXtrc&(zaf7W-ym6wwdki(d14!+&<`v<@+A=H-_@%6tVaoo)hq z|J;D9f0UA?F>ePllc~V#iH!cl3>M+%Oppl6NSA@cY#3*D!F+j(J6yf&??GxH;nS{gpEzMkk-+N$(RK`A_NiAYU7!WoXTZ~M`SL2 zD9s!QuII@SBw5q;t5wj)38wvwvc{(T_M$@|1Hwwlrx>fCg`xu%t?{l{3tIxkAE1`) z{(?k0Vt+u`A0kT|KPTodID>rhNyIb0E9zgW_{+J-K+~7W5=y|e&m8jlaZo4UaJ-wE z9O$>eXt_o81HC~^Uw~bhD(~Pb-JvNcxw|%0^(y-6#Mw(DqSQW?izG`k8sm3A+2vZG ziuT*^Bj#N)#OS$_hY94|nTr+XSchmV&`@=R4JJV)j{VVfo&@v)75EAjDc}B&VkG2S z**P`2u~rpOI)zCqqTUjuRaiQ%@)MedB;lWkQhTH` zLo3$&rZn|!)>Wq0IV^nepXR#pySbS5e|!ES3lOh4l`@tHXT(B)KxpPwo1Qo>4D;@g zUtMk}DEwzcwCnS28!5q#5J0w`UunY+xo@@RwIKmK8NNH#-Kp7BUa|%^PA8=x_E_D1?P=t+89BQxM7@Cix1;$vj)#D9Ze|**g09KJ({eBh ze{NjyA)|aJHXD-$GaY9&^FNtsc+bZ=1*kM?(T6QmFPmhXe=E*YIMcUdTuaV{Ic%Es zv1t`}mIoUr7*xVChL&1IkS5cUWoHOL0VEN}{*iR%k+j)3mkCInaSDC%y&DoBOvKx$ z+6_|N4@}+p1Lir zn;9B6c&)JMvd`{Zb61CGj+a@=<`>K?+`xn7_E{yx(U_U>Z!k1TqxoS^_F~L)Vi zcbuZcBbQ2k_I>1;^PctI+6DN3fjR}G#j;m%vQ}8!4ND*>GF)m^ps_LuoQc;%SN=K- zG4cp1l-0WWwJ6Yy{i6RQ{OC6eNa-B-`AQ|?&6`I)b2<$N(_vaDqWMIM;>`MOAfxH- zixS4zXXg&a;UXae@3)5YnzsZqYDyB`DXOBGP3wpTYkF6D<5E&o9G{3KHK^0$!zc(d zhUIefNP0Y>+~q7Y{%fCtoMKt3I%fby1C(dPqEMKc@{41q+%;?3y2~pEfa9>50C!|e z%rw%Q$u+m=1AByiREw{(PI0-6^}z3VQOqeQM7I0|CEwsP5Q+=D;rBbgV9Q9$qeOz! z4pIjYa6aqG!_DwNE44HzuIpNG5?<|k#J!(f6O-c8_j!o8-#M*iQAiH3#fYw}4tq9Fl{ zrgp}zuDROYMrtb^-+mL*+Y>VoBE&xR@L=pt#^eqzXydX5-9g7L+2} z6+!NmBdfJR?liS!Z8i`b0m|pL7b>>ZZGyGE8irdhzOtIN_88jleE+mai=^ntPt$9j zmz*2l6J5XwpQnM~*P}5A+i@j+%OODV{Lb>}H9GE>Z^6DOfrD?sVg0Mr$?Y!tU;QB= zmpe+q)xtwG0v_(7eN}=XXLhVHCw{CCry!(2$|BQnGj9srF=}V)gH;v{euIVOE=>U! z^w7FuS(hG@ibUgc7QNV*TNy(0#6*LMHM5jB>(>CjDJywcH}nIr`WRz6(-nYej?TVn zyefLID#q^JIg9Xwb!~P=^bl(#68_q7eX)wdl37#S2CH~-WtQ9$i>AVwGQ|>xc_F1Z zFXkewN=>oOjG9a&WhrkOZJ6T(d40+PtxBB*Z8xjvl}nhWMb)#M{%n$Vm1gC{Mu!$n za}TRzGVMxkwMXtr>YL2tzqVuTir-k)Dz&Bz-cu&{mWpZfa5BxUtP07c2HIt6e3E14 zE_LVsf^p3Y9^5;Ard_Dexf^H;8=sq0NxdLXOO4JIKO@4>uZ|p8XjK?hSZ8e{{D6KV(E~ z4=2+ddOn)`$!;NWaTo}!oS@jg3re2mfR^Beug5@NhBReyu%FYA)UBmCSJ^@3Dt@+- zOLh-hSRLmXu%b8E-H__wgc_VNYgo676r1rs%&JkuDfneeY-4fRC7h7W;zYwG*Pdpy z9FuWV~HvLctO?RNyBpy;lT z=t~olEmqiq5tK|+BDIBq-OW;S=%w-S&G{oh4Ax?B26s%6Ev!bZS{3k^X|RU|VZiL9 zK@F8LTy8@g@vtJpinpyowr9@3xWc5EOKKnDd>u?zRMPSmtpc_djp*mGS*^w9x{bK8 z4T;AY=}p{#X<}LO6hfX=7u(xb5}Gt3!e94Ns>Ch4$Ou(0!v%D|G09IR@=5CK?O-pi zl>`PhLN6fCb(iylTWfe?k$8?cpL$dXpg2MOHrgoJaCq?`n&FlzY)+XdUgz7`=mXKx zFmgC5l2oCFc>o<=(@t!r*>RP|$YM!}W$@?3z2Go)oC`R5c+!`-1WNc4e3gULr>9Ka z!IC-X%eA4AHFQLJJ#r(XW{_f=0V4z27=^N3g@yY zB4VTgCM)~BA(=Yd0g0-w=a|J9(|u`$qYY@;iSnOpZ-C|{s>G|xih}+(Fs)(MALYMe zTn92U$sWQ$X>hL>$O}k=aYvZqAau?Y4Lc>P_;|7BJy1~?W27M6;^M@zXRKH)FO@0u zB$w?P^%C$WWYHYFnahr59Jsn7P}8AAa<`Z5!w!|7dZ!)WSV>%~IBGP+c@JqZ2`J14 z?*i8C_5p5`(XL5DB{+E`?4hpVR%mS-*W=J6} z{8j743h87@aG$j@se~U~^~|vgNmA5ioZ3J3(3cR2k15aT9LvepqekV;if(7KVoH4% z0Z8xU7G*LBil&yb(Jr&VA9xIH7Rw$C=K*v4fq)O}Svrk0?bDjXEc_yse7;iE%u1-N ztZ6N~^BNpB@FiF%$v{%V1??@1$J(4)jXa)|RIte?@@Sr@P*1}2jq(lyqO%yzMoyIo zehZLtmyxml+I90i%5A&7sj3(CZHbWct%L5LHL+V(Cb)~FwUF1NexTn*4SWGmOQQ*# zFaQ^*jS|AEph@9)ys>kIT14xnjf4g<__G9tFfnlw8Ndk+YPte$=fCciDf8+AyLo~o zIK@_!W2ozy%(&Z$YJiF&gf3L*fLRsb7KR_v%8N53c@*8{Cl;5n*eP|lykI|dT) zjwwYQG{Rn!?6{6F-)e;`r-h zaLB)_JB=bw74=?(uwLb!JExNvCU+&vP&Tk_J8)8g#%uG4{rO~K3A;=az^PJ`ECvKJ zhEBsrs`LdK9@vXsCuV~)A6>ZA7pzpxi?RT^XC5D*?<95p#R+R=mxG%L$WaXexVP9Wr3@WYro^6+<#g82O(GGcN|8-`*G=;DofCu34UQQT0 z^2y?_Lv@Tc+Ck>o40DVMIsEa90r}htE~HX{ef`MMrZ_x{9%_MNd&-7Wf$4jCxnW2y z*)Qx;Gbn~hukW_%i9k~$eEj9yz0zP~6k$X>jGshtu_9Q4A^Jl+7!~1{ay}b%bn?zd zc#`%k*RO%;IRFwa>~{WJVo5vcnqZNvWut4p*zqrzR+uZVUr6 zx8~p>x8%1PS4871mfLI#QXw(!Us&$f)@OLz_P>ED4F#}ec7l|mJtY99<&hc&{CNc z!$Y3k<+8sS#j`D9HJIqD+?Z2CYTV_O4XeVTfa9RcR|s=26E<_R3)#sSlI`^mznb}= zeGAv@&d#n1l~@(iPmwRGmp3m%2ukzumXbMl+3bxfWe(raic&a^QQ8s7c z{D%&+nHX)!+hRbtdo_K`Mq-MG(D>_PUQlg?yWh2GOGv3fk9s;+CJtv)`r2mnA6}s`+Iv8r(;g1=)E7dwU_S6gGVpJPfnj4MnM3GrZdwv0@R*2toBDus^@KG zGla!J=ms!ZV5n?N{}p%3*1K_69(Kf5P**%#RnG-k2dO*0Jj1I-e2N~@)UF5|Y-KCh zhx^<8S>NvF_{L#da$ubO!%~eU-A=D(-1;>1x6)toCPWfVCy>z}@YPo%w_yh=JOL=~ z6yXVDcp-qP6W)--pq=}u^JBQYp$b~h%( zKLKuYE(Ma(Ir#%sALic4!-q#BP?$Q>0kPx9` z#ls@k4y&ftQ}*c9V}*pI+PN#~1^LZ*8Xu*f=aqnx-@)4ka>aBC--7806_drw&)$f} zzc8-^B<}9XJz7eJ@L+zcXNgx*P}ehDh?C%89Amu{h@qrE7O1rzR(A_JB29Xb?ViY2 z$tpWF<1*H}YW_h#qE1%79I>+*;VMnMcElUo++ zpQ9wXuhVBECnCCyudI`DkiJy0xzxJ%TT#&ar|*$Rga$#?R;aGk>q2`xT} zqLsL{+DtDq(vMNMsDz}s5;&Kw1~$(mojiYpTlr%hn@==0QlKs ztX$>ej?^c`(|uz}XAa7K@dC$z-s606s0ci`9#-p~=*{dg_xT)tm&)i(p70#LHmAHY zk#R-?C=!QM+zc1c{Fi0s9SCY48-O7H#(gVHNpuyfk-G8({l8v9=$qpEj`E@;425A% z%l{f%jGXzjxA*%GbofIFvqOQEU88`;Cs;>BBMWl}Qk~X}_G(~bhw3-eb@cJXBdQe^lRax9 zkSo}p!q1b$)D*$5C#_fWK2Lmtid1NS2JVe7Aoxg_M^&pcFNm7{i4`qRf(gK(@IFuI z9Y$tzLgSQcME#4s#nww>$XGD+&nvcSeAR-VBy(PLuVN)bvYF7_74*=(2a^R?3VuKS zfdj^!mjl?o>+c`a^>ng7{%Iuz48Ix^+H}>9X`82&#cyS?k1$qbwT4ZbD>dvelVc$Y zL!v08DPS3- z|GFX_@L!9d*r0D=CD`8m24nd4MFjft2!0|nj%z%!`PTgn`g{CLS1g*#*(w8|sFV~B zqc{^=k(H{#0Ah@*tQgwCd0N@ON!I|)6^`Q?Xw~3P z0>F&P85;TXwk#VAWS+GnLle5wSz<>g3hqrf#qGfiyY=*_G1~|k*h-g(AA+NbC~N@A zVhf6A6qXmVY2Temx2|X$S0UFw%*D3^qpS5e`ZtH#e-p_hv3bYtz!vUA56&MBhN4*s znI=g8YNZ{TYX{~dPZ_gk$3 zZ?0ZR{D-aliB#|SEnR`T;N3$!}02ZQ(F`K#y94FLke@r z>i04JrfBacpWL!tC&p$j#%e~cG0Oa(wM#M(Mn!CQ&`w@usAmfZg29h)&o{r_NeX64w5N5WxG6 zq(-s6n3+LYQoRE}bt$YsBWg30rQ*(MSoLcIu2Zpl1bcHm-1-=no;nuG(Rr?&=9Dia z+wfu8KmGNY@a~FBD`eM%#b5ICn=aI`v<7i^08qgeb@EmZ1l73Fe^)VHH>vwnl#LfZ zYM}d!X*vZ=X-Kmm)|p~g8rR~7THpjqRDXxKte4N;M7#iYw%0~Ki2cgxoq;87kGDaW zGMa(5g9dgC3{EpOF1o}w3Ms0+270RrL{cUBU0=kwNClDNSwY!Lm!3n$dY&svjk#S0d>tPZn?&G%Bd ztl_HV)BD3T&C$JTZ)yChEr+){P!q~(%s;6J22$ep1;aq;vT%}A@4H_e%j*18G#k|8 zR4HfuOLp~*H8ydsM!zd^J6-{I0L19#cSH6ZtZzWy;Vf%NE{=DfqJAc(Hd_EwUk?-s zA$*+!uqnSkia#g=*o}g>+r%Me7rkks(=8I_1ku94GwiBA%18pKMzhP#Af0}S zeaw|!n{!*P9TQbotzCQLm5EQN>{zN@{lSM;n`U!Q*p-J1;p{Vto$r7*_uOOfBqxP8j9?Yom^}ld7Gy)Bh)og{sMVE=iz& zQ8tl{Xm~-Z3>H`75=x^d=n#jJ1K1%%tgPj|GD0Xzq9fV3Ma?HtM@!DivcDoBi|RXcCu&(8=pz_F%9yGJ4E2WNqNhi9LNi3%1JG?Rmen)( znidVu1H>g%W>~Nf(Wc-#-n>MaFPSE!=s9gJNWJ^lL>IYBfrCTlc~T6XDLkz-s$mN% zIcmW+gIppg>?!bII5df3{O}s)J@}LF^h1FuLYU-?Vze6uM;x907Tu2_LdU}6#WqSB zkug=xXpYs;RFi*m4cZ2p00*fzjt{@Wmy9zR#T`u%o(6TyxeX%8M$A)wCq!0MXnhE! zs@Iv}v%rr(7RGQM)UwkdzhO-}lT}7!tC()&KKc@Dj>7m_nc}0VC9Y|;4=Sm7dofgU z+K{Ti32BJ+5cs-Xy7B&*T#hw4cF}b803^9dTGqsxPPP=R8-^vbHS!I{bIm;SX<)F`Yyo-=KgvZ`cta>vzo9Our^+Bfz+X9 zV?O5|xpYjqy`sdQ#j!QoL4@>Z1VWi#YaYf}_?(VW)6Jb?I%0-9#+l|j!<_zMUmr28 zik23XZ+1$xq!fw=hEFm2nC5_iuZV4X9&o7i zLrgr7Ms~sCEB_sDy#`7cxztH9MxO%Vu$A2wR*M^gV1>YxG_=tHv&#iqu~^$wcGpy?v*h@t(H$ zH|bo)EDRwA1s%B4fQft7@6e$2;M@)U$T^O5!>z4AOYTn{6SGX8hvO!By2v73jw^`8 z=HZ`X|)E5WAI&98d=Qk&8#5X>qZ%dRAYO!+Y$z*tBa^ z&){4d!#2n2RL#)WWo)O2y|<3#!jz0SxnV@_sd+@2et6Qm__f*>Ztf*pa9^^XX$-2! z+e{3w^PgG{s$OocN`|_D^8+P}+Tw=R)lt|<;>l4~B4Y@ziF_jJ?^?260204x_$pCN2!RMELv&n7a0dHvv!~W*yB~qxQVSiJ7k{ROR50x*QuojGalJF_K$p&Ul?FMT z&DVHWb(8HD$KLuihvY@DN}=fG);!(efhBilm#&2~I0+NuobS=9Fxe zz#tO1zN?UV0{P6%Fu7I4?94bv_m+30R(ZD~*F9k2pnS9#`W3i=M@{Xe#Im1}$Au0o zHxX=o%Q~r(4Nt(_aGA;|qDjGcs5>nb5q?Z)GFD#iisNE^T(HXkzY7ftImPb!MlG_k zgpcSeWS082&ms4T`UWg^iI}i7!=&MC3K6rmfKU|M62D4GJSEtL%RFmFeIWo|379{H zrGTh}r&I^?;fwcO@-ljq7NFchF6Y2$%I$XOc`WQ3yUri>IJ3U+d$>nA2Omc?+Vu}4 zDKc`JU*$v+$ZnN{V*kM|~Oz5fC%_3L} zubS}2@T6qj53q?Hgk~U*`be^>m6Gl_bjnVurQfuZodxPFyx%$IQCF}2Rb&BGh<4$b z;mVdA990|@Ds|@~-FtqRNkQn%RcLefMO)&k1xdP=D(y+19}~feMzCYbVpfqMwXm62 zg6zvoLd2OSbfiVlxiN>(qh)DMBJ^VZT1Zz!;rFge+?LVH`D+>&L>W6%iqWX3VNaZ5 zAV`F`&Lhk(u}fBoxw052zhBEdZMq~|_C73Q#@UhFZP}lRlH%F$mMooQSxWbi&4ZT6 ziS$QR)Pm*Ni_YILnlA9wEob90F%A&GLv2 zkW^Uh(@WkC(rUJ%P`^p6zYt1}Z))akS+g6i<;^}f7 zZT8$~D`X0xfWFn8{ez$X^+zie9ca6ab&RE2gnC$Ypc)33`*xABXDL+g&R8F&9EJu} zfD_}@4m{4hk1EZGyRtP?hs3Yn;~Harq^tbP9EwBGjGu25XF>?agUOxds6U1fXSQj2 zYBT$(GTkJ*aG*6nOOUoDpL^h9<{5p!am_Tmfq;W(vEd1E!N0tz1_&qDO;F1@oZQ7moSvE9 z)H3IKYVyx6BCoY_T!k+>Qp!KU}%oSL4`(T-*zo_Q^-$zmMv~bCDPcyjQ z7n(KA8z`7cL&bS4h}T>ZUlF2&@<#;ku;y2=>Q^+6TP(THSlDlvq;aMG>eG=8Qw-8a zK#wRYS+-M&luF1FZe`io4|K~3liQ>1&o@|nFc-cx6O%L~$%v-8C7kVlzOQx^L4~$-2hOZGabOWL?#^*o(L*9ossJ(CfH`xxLNk&Aa z0#56|`2O#KcHfk<10^R34lz>%6RqqsG^rt|GAb&x>3|$4q*@O-=Xk#<<;bKmN-_Rjaaf!({{$@Y2@^TNyfN9*TQ=ZWtL z@5x4b^6S5we4oUKwENln$`JpP!uZn{AmP*~GgD+B#>_)PHUXh`R4&A&u?GnMcoeo; z=mVUTNql&a9(DREEY@zn8!UEGkSEPm{EPWj8~V|6!MUqaDm#9_WqJ>svqp^ z-5j65_>jw+DH6enmvIK;+@~?uh^U=!)nGYIPrqoiS7A8j9Vt@pQ1pm}kQPm@RlrS+AG}cf+sO%+n6s;atg|E7< z#$9)B@8lRi=!3C6R?-?aB+)`sGG;6hWA&|LA`~A!)tbn^rzCc>gB}YHl!(=;0bsKt z5VLrJ{Ofj*-^6DbG;dJkB>SasakjQL-&tz%aeQ1SWMcs}_s{*j`{`c-Az=+d#=N0t zLtbSA4QgDb_u6Jn_rY?4)TX!Ry*Qcw!y}hlq6*4RP zzy3aCM#r*nOGid!L1TF-u(Z?0r@+mIRmf~ut);TsMPJi}xS`jI|J4zij_)u-tFZv;xMU2?Xe^gx#=5eG6th8;&yqapc}8Xt@F?YZ8IZ%&@0 zi<2$U@z5Gb5f1vlTyq)wF%H!`Jdl2IuJI^@1%QMO7@0HWmxHE)U3VAzXirY89JQM19z?4 z`dFKpF{PMp`N(iqf$7J61XbZ^#J=DXY0l5F~vB6JR2) z654K)Kt>!3?}i^R4a8x7Qp!dlWD94pXL(O1-VRvGq^Fcm>>v)LhtUtHU(d8{FXReC zIWdIAXNky50&XLUy}RR-nlk7e z>rKDLIgd8sg6rRu6awe@u42O#-=JgTNgUK>9!|)b24u8Bd>P+wt)Q2*n_MnLN5U<0 zqyA@~A&QdWsQ_uPgbf|2Q`-vVJDu=XT5m*0qWOb}7brRn>TYh)q8%R=1ZrarsZkb2 zz8?iI*8WHzl-td++)1z;d4ES{fJ@8q z=TViP`Aj>fpwxWq>E$|t5!;^^5FO^NGDq!}*tK@0@>AIR!u>tAYV*j%Uo_9}ssul~ zwyCpPyJ{lZp<;`_@Cw2k@;P1?KNoZ^!Nrd+iG}ii2^gVGD>265s z2RM$uM9o?`pPyNo0L#kidYsnr8$04p#a;1dhQ!T+5AIi(Ku9da(DDK!`!_1l-0S2g zM(iKju(3Co*!;tCwr^Y_wO6ay{JnacPx_rKwoIw;+{yxzdy3G*9fb} zRp|3@bOlSkiEws-!CB_SK@(iTS;rWx5TN@BP^3!YP$4F3)RT$aq>Ee{N9ae0jpcIn zRa}5JEFC%Y8-#%8to|W;CHI@9@d4p*eow1&_bU6ZXeM*rU3c71r^W5#?qg#IrToi}LjJFB&;GTYOcO?#H?%!I6?zeUSN z%!E9T2g~$bAF+4z(pZVXq!UCX!<;pD5%~rN+ zEE;HumO;S2M5Hk>g`TvllDMpyN(&a~A4~Sdnt4jbcw&0Xd}(aO;Rw>AFWt$PtvUxT zB)|mfvML)?L7F$b#v)F$G}Gh-cyN*)zGHz+lIf?$1i>P3(asIYz~t9;RSz*$I|eOM zm@(804`s*#^g)L-b_-c`=hnd3`*`xbe z3}rP!Pim3Y?f7FYBM?*sWw@f65j`^UrELxV;QSoTyK}u3sP+Z^i7(8C0%WM+9&sO8 zs!Nh7QOSH`vMF%*i(D!-;Oj?juG1_}9sewcwSrlBy4gVzZ_Ab_{;9{ z$@BQ*F6Ve9;dxrP22LbhWnVo~Q-d%#mpPHt?>+g@92M@slJzAQniTT0whH(JKcIwx z9-+)%J2~V6Hrp*^PU%we|FZyY5~iTQ-^5)8ea%c1#@MNLYtRb9g|c6>9x+C_NK^ZV zvbEP((f&a*Nc11-h9aFe+REuyN8A%!*}FJHr!6FA))ywcpJ#Uk9DhVo$JY(Ldv}qv z_9Y(A$>Uron)tblzGL1;t9zJSMV)YS94Z>GMeC(i&J(M03i8+6hr+kVs*5|*^1W=4OKvz3%;-SS|rD#w+Kq) z<3_9DA}VY-4Oy5uqwFkC-Wn8TRZ8AE#gjm)p7ei?aWX0^Nj_RTpIp2l z5>RYCkYM1tjM@1mE@?p{k@yMvh_zLdfFyp`ftwOSjxljXS=%oJHWO7XWSp%`^R|yq zD693?BQyrDT*$u|)h)+*{7MBeG8n z>Q>!~-%tDBG2ML_AKpcEf7A2z;P%0q4UqIi@=*O0CNvMf+}WA-F{M>Ss+f}=CX+8!vANYVg zU31%sh@u&zY~^6KOg+sb)=X#Kg_MZ&*JUAxvB)XZ$ zTk}~!$;yUeq)V($K03#i$1C>g1!C~YJRl_t0yGj$_w=%4L1>E!$NR(^HqC#W&QiQw z;G{e+Dry%9owX<{W#(vLc-&+|mA0+UDw-Jtkm44i-&Rsi%ymDQ2pVf&@MHH5ACj#)PZ?FN^5PMC^v^Te%XllwQz?zCj5)idP zUv;;r*|XYb8knj(?n1=hLDtF1i+(fUfJ&Ftl=%niTv`p;bf0@o^uv1U$4+1CpqW$s zy!;npeaDP6iqk2d3dfkV7jMm&g^A))2-b&}3p!XCxTE%l|4M8wdk*mAtHfxs`Dez* zDlP&9+`PZ-a4g4&KxhZFD;8r3n!d3Cxt2Sgz# zN3x84z4x{J022`R2Y7T~`75}RJo=;f%0p=oO&5chCXrN$#A?d`c@tCJNxVgGUyRPf zO55h4uL`2~LX{0iEIBh>DMplSo(G#>NDvuIsm@qDFODAV-qBBQ%JU0YdgCV^+xy=k zXcwSd+5Mze1Cqb=gjbya`m>X#5(d(oceGuZvl3>ggsz-?;={|)5!etZ2d?Pc8W2Zt zXLu1AzK*D64#vko5W((K-2$y&bz!GwQ?Mjs9>{R@{bK?pI^Gy`;;-rpWX#R{sH~G@ z4;>(H2i=FikZkkaocR6X`;ZVY?o_;Uw*!DtOxy|(2gK?XN|7RVumqZ?@}b)*r*@&+ ziJ2}DYmrh!lGJjcBd8ZG3r5sgx;tU$d%27 zplmZ26=7b$yys_)pmK1#-gGt`!Mp$aflia-?$2g;`T?EMHOWKgFP0?h-QjlYx%{ zUz-b5;g?Nba7%6c!dR`EUQggxx6j-L1>fK}1nS#BkVZmRzMBgIT~Ju`k)5C`KV(8q)u9y%>mLdO*ZW`T-fcFOM9b%Q z43EKqrW~mKI|D(YbBz$)u*)YmXGBaFB1LZy=7W;<(r53Om70%xQlvjpKj4I+VRSSO z_=f}wu_!`+(3z15!(X^miGPu!OZtodY2$x`sR?1uHm!}B(1DR}nKYyCysY4ncu15~ zY~qJzukY+&5H@c;5{BAyxC^EsYRYO)Pppaq4&)mM%lM^=p-O)!sLJF~p6$SInmx`o zz2$_HKM7BGD7gt1K~`T39y=to)92GP`egBvS9d4Zw2dF-*$O|GfhSJ-jhp4F)-g)g z>O1>cSzkRHXw=9^4vfYK)%WM)oQ8Hocy9@47HHmeg7sRP6|}GEhYD9B;+IV#m1X?` z(q$QhyE+*9<3D?%DL-P$jBU7rpvrY=cMYxlWs~}5To`;v*!)qqF2RL3-6@gKSTuk4 zSf_6-#`r**((AC`{-QF!HctJH{@&oQ1@w`UmWo-0ZK8HC6;C_OJ5cQLy%TYNGt#1y zKydF3zJ|-n-a&T2G6*8=R0kFg*busbo&10_8<3B~CgXCS!vG*_4D|owVIdK}`4PInCK9TeUn)ND=X5X4`d&yE<59nsz+V%MQ zP#AkkQtW$DA(4@6PHw!6dtz+^it}rw_WAjGGzULKJb}HMeso8qlUcrOYw9YXO%1pWG$m_Ff;5}Lbk+2u$0ifZ6W&DA(Lgf*X8m^Eb)znCFq1j#A<=~*cq1ZMi;f>9a4 zGE;_qvHkgsc_1$-D+(r5;U?|P1qCnr*14Gv#HXD`PLV*pDrak*T+{DnkLs_S@GJ#| zNrUATuiTBt=5$b*aH}LwQTcLq9Rv1YD%tFDD?#ZZdUeUPR7%Zx{w81>2!MlpFS+ir zGB=tWz}TIT5;Cs9!X8QXJ7Va!>jHJojOte%A(kZ0c>CO@Qd zFx-*fkfwoTb5*LPichy(NiYvTNXGs9O1j*I?4NWCc}E+U>zK;h?Q;5@Jw4)>`F`!W z)6&`;BKuL3)N4wJDk_kW*oI18QI-qf=p~S0FX8cwWX-(7UoNSbQI*^%y_I$b4gsm; zHq6pio2k$e8}#>lVvX!Y3x~JNOL*d>EOH#0ZDT6Ks1!zqm(8L-O7^uS2#UGN5YJw% z0VNyV_IS^$LwEqwR(&qa9bzMqLOZkyJ;o@#e^4dDe)?2GuNjCDa}X00?wEG}&lG{? z6~4axpc$5MG$d&D?$&Gj1GKMVSN63jsD8H^wXbaVf~$NN@3kyM65SUrp7xc4lH6Bv zz~hcTP)Jp#l>lOA4C!wL-!CZ-e!9=X5F(maW|uE;!PHw;2*EK%^qet9j8E8jnpbxJ z;@$R|9}g*H^M62gQJ0L|TS=7mOB3=_r%!`HBJ@ubMe0|y@0wl4S2~n*5K5A&=?UyR z??vZx*5g|5syx_=?M6#fdC)?8d3jxPI_WPw-cOHD(ShU)j6ccfV z%R^$uyh<%;9~yJ;x*QZX&{cio$m8TZ8~vrW=*hsWnI)h^c(L+9)1_~UUNmfxnuk+q z$iIx*$~fI_P=Fb)-8vz6t>7E!CV4e#RGeJ@XfjG^~7lKxsv|S0aO4*gd z#>7AlwrJdu9gH3t&FZu4hev6i{Vdotd-}VElA@3M3>k0xV>y8Az_MG-A^@~_)L18r zp(@o?odRg?2Z7Pe96ghxx-n&~IaSh@k=#4}P-nb--$_5Kn>7h)`hqXZi>rSmFx>{n z7@>cdDf(??-PC`6q5V*%ZNm^Y{K>)tElp#96LJD^lpq3wINDjL#DbNoEa>)I+E??c z(XA_%Yy>I9tkj{nN4Gkkz2L}Y(~1I>K`XjHw;O0^4(jn*G)RpWmYTt0hmhUo^jzk4 z2-dVm>Ss@DSonH)vP^+O2Z=~UBG#(-)VEQTZYHgbDdKw7oUK2|_jQN7K!x|)uH=?) z2RTv#S7}lIpYpk#|6=YvWQ_?Ju7yee_x)A3p2y?6^qx<}t~4is!Nq!7Hp4)g$nbBO z$w?rcr4a<)_l-phT@?O5;ie^U46P%zt~$ccBwG5@iX;KY z)18@wV%KsGq#k7!iM)&5k^W@wr$F93#Z7|8Rw9f9%f2?FH)^q=C}lM^wz$DnhV~RUT&Dwk>bA^yQI$CZg7y?%u?OSTdsBxk_(i&fGHa0eKjfY>f+?c0 zBVLUdlL2TEw&gsY*ig3LiQ*Zj7vB7Z>@Ons`2joakt^R$^yfN!L4`Q-T6|U_)q=pw z*+|rb4i-rr7Yr0Ob0>BbGvylsf$)*=FN=oZ@P?gacX@~HeJ6T5H^qFqIb3L{nO&Vg z6x;p!3vhl$(b@r23KSJo#H8#zc5d;#U9PmJJWq2{D((bvQOrqgqOZlhs7>L}^0qs0 z#8yZdF-hqX3lg|`?K6O1rFN}LX;FH zmaTG7;!g(=vlF7z9W;OKtcegGqCQ`w@Es$3q=lgxxMAn30DLAJ11X>zW||7-$){rB zlN`wXyr7v-LO`7R0euj1t4AOw6MJ4L-2I56=0yAy~9I1jLlgt52Pv0>NM&0lrqo%Ie9hXTfZM-Q z>ka}%TUg-E34%@{j7CS#dV{sytQCi4Dq)>5({J`K4v(!Tej}oa7MdQn^pCzNxDbobluhE;bIXfb0$LVzx2%1)6GvT7hqtzBy;j@nmClpDd_5IJ z?(!G@V{J4>TGRR0jydOd|FexHY4QW4Ie^ zl~#^+B#t-bwUhyMs?Jj9%)*pEOnObEM3a6(;-DI1zu<{t87#GfRz@Ln1%$`#b*t(P z%H(icHO87l={E!oqfw3baqF@(hAGe}RVd-fciUoq+YgTJ*a8B}8? zd2KN@E$tzz9o3oP*AJ;h5@U(c6;MDqQPvHm){5w54$xEcsb}(q=+YFBzZQl}E5Nm2 zaCL=(0LDq$u$c&^8KVH9Y4V)POj`~SL2ux_Q6?7KgiqzZrsbbPoBRUt_%jjLejBrX z8(Q%Ha`^Cxhc0P({rpw9w>1e^WE+hKg?Y_jIoQ{-h>=8w$1xdG@PZBV`}pRP5ye<& zf|pmGzds2QABJft@-FP23o>%45TCj0jX|thKOVf!JI{!5cFF>>e}yy!Qw05WwzVv zGuY>bs)+luF5mrL%L=v>hicl>it?}+Mv7J0fals>*Y=Bo$zau!^@g(X^@ zn372Ze!FUSOeh|7&Wu%;3W^?h3jz+=aXDYDnAeOPYuPSJxK&SU(raS{wu#B`*tbjW z%!z=TWAZEwBZ`w=)ol5s{EUSko;uZBbTW5Xc=DLO$xtu zXxG3|-mfJRjjLTn#Nzfh)djtZyYesequJLt(rpSwi;44S_CB$L*>@TmJXGJx%Pu*# zzD>oO2u7X~ukiZ0SDDy)B$H&Yo4hzyK{DPN^4RH7Awk3P&#W(4TqW?$C)T# z*C@ipMViB=QhVE8j@vSx1~bM|zJ)C(Ety13Z_~U?h{=_@+>p(_2&1_j3n|Uwm?oi}D&K%Qm2ts-_UO0%=%;OQkBTI!QEDz9Jd9YLeirlncdc}s)6xVJ%vE3Sql zyI2f|WXL^@0^Z6|-9TBSxuz_6D!c=bQ!|Xr+)Xw*Q?8ELI4r4lAyVW@nKK~ALz)Y- zEsZ5t|C7YquY+<7v)dFcxtns^nkBXdX>2M?tz})#mWhdmFrpnhQC@RfU2bo666I->Fpc++oJ0r}&Sk^(e zXG_Di=-Gh=57Mu8X<1BwQY}Wvw6J>&eT11Y9R>FQKo&ztQ~;Vu5yg0bVzUk0V%0sl z0~@yQAPFC~Z_>q%D|6D#m0X*Fr#r3$w^8ESaN4VgbT)INqZa#*89Nu3KY@LGc9z*l46Ae z8>0nBXBVz86Zo#KDA_ilTF<5d(ev{D}F^?6PiT*X6NO}!A)^l));|A3%L<`f!&|&$o z?SDB=(n%uh^u$2Ce9?A}w5Y6g`WqG0u23!xy@c_sgK*d+g?g79X#fpx)+uV<@0C{` zp$a}OG(F4BF_KZSa%b}Kd7a#wMZX2*J8KXUF~`pqSo zfax56n&U|H87OxNSV@L;9y(FWK4cx|{SfDi2KZWtu`;0Blx=EZtCFR94s^r$4-+oE3Qa=9o(oYnIg9@yWO>9MSjudo59lbB+S5c?{kbcIe&wQ>Yv<_iMK8|Z z^$)9Wkg-6Al>e-IeVGpPZyJ3N?5E)cer?Fz@+TW_cuFLiqU4dI>dP3^Ij-N7K)6g& z4-TpbVUVtS!tb`3oxPj$PyX+y8IRkS#D<(n>{wvI1Jav9?#sPC&(8FVRI}mf!oo%fx}M&s@Ags zfl7Gpa-33{*2$Nz(1}l{;tA26zMKVtdIZ}Ixz=#-d^}~~ z%*)*uF458(h<}3BQzJX(Dh>=u)-wNT16&Gl3hB%hZ>#QM=o2j$X`p1YQF@}xF?wQu zz!R9gxMG+Ma?+NkhfWv84zd|%QzYThFtlb5nJv$X*%D(}j*c=wU{q~lt}N%LPhKQk zJ=8FlF@O`dgUA|`8_C6?vn6~w59qOt&?q6{VdX~(hAa(&4NF$yC0Plc)HRcxlM-ri zB?Rw6?|ytX)FmYh^{Wx1rO9iE?#wLGVgj}cAr|$)K}08sH_C}1$hgs}K0B_Y1I~C@ zOL{ z1Zfl%2LfHSj0bn{<4O;-p!s5H_boBjez{uo(eeQZ=DB1jR|nr7+`egy5!CYL-+&gM zH8X-({qZh!@R^{9;qCn84~(zrBBz=QpWXo~>l4Z+I}zfW#)^?mJLYK!HNV{a71HFt zZb_96PTal;{uDeIjprVOA7`|{$k^;xN>xYUr;JAo$mQZ+UNWWx+uey#Q@@>v#{%mg zh=!SU__$faqLdHPUBAix)ZFE}`U69MY94;S)@N)Rt)}z*nE)=nvHKHH)SBRwF6w@U z%{WAn?d<=tpyw-bUw9)*>i(&G`15L(`vbVn<6FbAfkF>Pb6#}1PI=uE+)rzF^G^S+ ze&GGoFSt7m|Fsx%P!q1?Z&5~3q3kfjeHZ^8bCWvRWMG!{NJ6yG={XLda{*G@ok|UR ztmP+?L29s9JcSRB{|Y}+YnL<0l~H-3AUX1J($9TVfOP577pB>?*8yuKQrBa7^)?$U z5a-6iG>Imtrw$rx;$7sXa?X8Byf%l0jI8aeZaRPZz4Y41;3MxcF3GS4sdLql>QYDE zEAcK{|L-naeh;*qzCQvl9h`lOiUr?id z+v?^Oxye_`ql+MG%>=)e@X#W*FCF8lyNI&Kz>sKDISoQVuaP%a?jMRWpQw|z8xr^3x5u04c%BP z3b>^9Z*$KFw0>B{858_?v1_O>nhWnrzn^oOhSO}%H z%Z5J+0G)Tn?&~;$zkv*YH2!Jo6oU+qScfFjv9L2-TD5>GmlJ+`qtHtTXW)`y#urM& zt}VpSxp#Of&nKYEMt5|^o&PagaK|=+dxAm)!^q~&^z~H;!u7=C9e7I;d5t~Gm)S`h zuTU&%GtiF&aFdWDb!sJ}cT&2*WvX`Xsi{U9dGer`Z9@^lJp(OMH~q|DDWBMV^a8Uw zo8a)Dx_piWgChXOgm3bd(WwGw%7UQGM)WeeeL?#DFJ)-dNnt@XjnH4JQH3EHL zR$B?5>3fOYqlw{+4~djG01ILH@I*_okPN96THH+(b#ip`0lox<0Sc^nZI3V@+(PA zyCHM18WF&4)O32~`xkjA&Wp!OXGK392=8J=J6)`5C7>VtAC;fdFR)LlBu|V|Ly=TH z&l|N<5Bm#MKN=;`T<}d=^iNAoxI~>WYgOSRA#Py!Jc&pDmM8>CysL?bK@1X-=ZB@O zs#QPUZ3-}5{ZYjTDb^=obcb7NMtshRnOakLg@P?op;*;2Gsz`&8bEiV^3I|U6>0jV zd0JhtAFlB`I8|>=SEl<6(vkzlds~XrXqkpB(|$BL-G0EH(|tRN|Fx|BX|J34cxcKE z0_|DVP@YKMmiD4l8lev2dcOEnvM-^0F4u!qz77cO>1}xr>QVSnM&^(T#aAan&22WD zm`>+yc}}<>YTyO!iIny-Cr#o(1d;81c9<~M+OKx$*$=9Dzw4r@t~0I=PL!-h=*Y)4 zJn2j2UEu2%3+LR~qo|To@P|rQ@^jF({u+=qzJ-kVV%f4>;()#DKl;B`v0sQoT_qj+ z`JJCo@m-yA!cOrS?sAXp5L8DKRzeHd5wxYZ*td%3+@g|GfH~7GQ(M8BA5kh>=LFu1 z>X|=nHyZ2FUrkPvD&yOfi(k`IWI}3lJ^8dm14Y`wnB&8jys7Z}(Pt^~&pM}HW|lx- z0tk>v6``i6KEzswg4Tfj&R=`%GQTN|R?O{S%WCov``f$ggsYHor2^He$(FebARqcZXjracd+=UxLrL{P1Ij`PnhTE4o^G(vL$nF;FvH>dV*r zPkW{z9@tAYv`v!nz~FGR`7mPT`>TKzIQNh9gJl8b>6iqY+2XmiXIBZQ*=+C?*l_W% zlx0KtF7u2<-B#RB)bi;;U!=rmW3+(?#i5VLdE{qHrmgjb;p)aIR4@yCPmgFAQy!H| z<3C^ndLBeYk_)(m!i!Ch*Xc&l zo0hGTbf^}v7Pk1y1YSLXwNfadAA<}W8u+-3Uz}56cUX(Ue_e?N&-Q9$Efy^y{1NC* z=8GS((F07i#WnvUbPOpt*&D2sKL7o~MhTt#>jqvaI~g)097{NcG$f`9v0Zlwjwx7} zbejC?7nRp$@(c2jcAjX^sL>Y4+4=H3|60}*6#u01glm6Vd?dg9QBgLo-T-RASP?qA z_nsQt>)Msut4ZQR_ONtSmg?8iRT)2Hne_5*ptC58Kw|pP+VI4)Hn$;a!4c{kZs{vT zr{y5|-+taT(b()njFDkH+~+yd>`O|%ecv@jqMJfWoHbHH*!_^XcS|}TwSUoW4Iz)N zVMJZ{%vqt!i%7OeNzJ5H@p--Yd4o|$=xCuI`iejNvk&OWQL@$@8}X|u>^y73>1@M) zp4v%9OS~`C@|*g`A13NA%(H85&m*P^{&=M?0+C0E-E;9@?=J!8vJ=I*0T0!6m?|)9v)j2cyL6 zel?wK52~P=ys3%>L)vAowVp;$jH0eob;4;SSFg%ZQ@{){U{%(ho3oxO{vu9RFQNsj z(RZ65xM`x=@R75@Cstzq0=kV;iLV!iszYeDO7+i#E9sTw>X<4>1L8IzC z{0gKt-CfGo^{Q}>B;OnM74e$;UfuCBjfM0#A?TY_m;ElVC)PND4pK}eKOW2<>s`NM z$=%Fl+4~T`=*Q^U?~pd9ObSyxM-pybd~!{`^|Da?vKVk#&aqNB?-*66Sa`FK(vmDW zU+%?rB?9DrukH}a^yYUo5Q}x3uxXeTNg=AQ=COu5|I4|Hi?B)RIJ<)}Q$K_IW&JMs zF4dj&UFrB=mT&*y_oG7xP4d%a?$3aNlRUc>GQnNx{Km~9X>3vd6AIHT0z_tu1)F!c z64_&q=-W>zpE|i|d_=6_3&R(upV(#ubD-6{C8tbh7|WWw^CIZWs+E{mDD5u8n#-YE zfD zg$*C2ZJxb@&~2ESsCzA!QajS%m@mmO7v}sKG@F>iXYHb4-N!eZy?=TeU&eyCzG^(j zV*>^_mc2Y;a{AoFkKqG?pPZdAhdE!GTH~#+lza+_Kb=_NJSggQwZOs2NaZ1q1ineUP6n)i2A@s0W z5vzZwryg(UDCqwR#DtYVqUSJcH5_&NaU3#IMp13iD5cFtcMd~m)|^J+fB}LNcebbn zTlN+`+!oCzJvRdDi;uHAzyE+3LOhEghf#s@A@nyB#|(!3$_800nml1MwOYg6g_!1L zyIe>>BW4r|4A5Gn-&m>w0(4njL5oXWj+#j?ssKc((b?dnxlj5dDlo&Fd0|DXN3bi8 zJR2_xjkD0?yzR6W6BGZuOP9%sedihUsJfheB=3f0hdx~^*wu^8(1^uBzX9^Am-K-H zuE!Yxj225u=nPg}T|3qq>JLhl9QecsYF7AkWfJ+l^7(#c+TbieilLfGH`PjZwYLQ| z1_m`%|C{5SLg3OlK(#R76>+c2`lP##ENP|z3$<;n%(AOHylE7N?!^yH(|yYWtKD;Y z+|_|`_Fu2i%Fq^pg*R^*ll>DQROxBYT7sndVW76-*kHsj!q_Z7lOztI9J|$3mKSLP4Mp1DkdeQ7lMvpqQ*Nie;g~@YedbCGHN6e0xc#kwQxN0 z^Vv#rKJAE9b#h*b;Bngxe;^6y|K&Ek{HxT%d2mvivAhS!cWgG?j}IwQ4|~8Spzf4! z*hlvTPC5d)v72oC%>g~bvs)9a;>x@bws#XZ35ZGF9n1Jdl!qen1I<(J=z;5J(Lmaj z=ZI&{j8>BOFq6!@_%GoRY}jEn%-_PLOq9+$n?Nh zu}?n{(tHF~oesPh27>LI2xE2-M<*NyzG@-Eu*>=hoz|QV;4nn=2hqC-lMDQJ*A$qy zB1sK`Y3~QcG!S3tC4BfMpkSJUv1j`UB@zAwV~`4f7p%to5krTG|HDC$<=R=uvZWNSAYY{6oc?3K+er?m_Z7MJyn4C5h<9k z=h$-P|NWZ(w|TZ*E5~aC=GU(pj91CI8+*1g2_w8KNIy{Kz+Dufr!B za*!iKcNwRcd5}aYBO@O{o3U#)!>}1Qpy-H&=LvO8d>XjX_45|w-p)jTfKyd0+nXsU&BOe65d-4RsUw6Mg zy}(p=um`g}eOYgMLMbL#o^_thr_j%s?e4m-uGxK`Q>@%MaiZm|K79NUk%Z)P#RZV*1GG2%eKhW{T;1i-e zBw=Tgl5H&Z=(#Kp#n6>jlqAXRynDu!frjKv(1l0rZuqJbTMlZhKHxetCCBsGf=%iH zmQAYDOZyWiTkd^DgHTKT$8)aUdHWiJ0;TCAJMcpjkk0$W$RK^6n!L>DY3eNppQoO5 z=1Phmn$E1}U(n8^->r08_Oma^Bih<-t_d=@(SQE%!KD$knimF+hmFigeq(BP|97K2 z&g%Ra|J)msl`W;4&wbHR;?qqbG*D>d<>r5O@@|!H(g|m0$ID|pGIx*FZqZfEr{9ET zm1M58Oz*WjdVG4=*|n<<(z;L^2{Q+@ymsigCqTm1ZuT?FGilmceIp-j?GtJB0cShR zqf1YC-8$($e|RRt>uUD352U(gdJV(J{)>Fbfyb@6yf=fZDcgJ1k=(u-#-`LpC!?cp zux5#jfhg^^I~SUI>eA>XcAKlm%x{gP62HpmI^J*LGFY^{l{WsO^5tl-)?z}%$?Ei) zI(;H(P-R3xufWBe5-~q|Z6LUc9k~*tml&Y4Pv9E#_gTMkB=u@(wm1o^)|KaG(ja}O zhcEfX@=EJhd3N~#;ffHfHRiIVwY2Jtm1{wH<3?X?KJPtK%kX`fwmM&aN2saV*d^t~-d8jcFKelOu1u#)L?b}9j@DrEk3zs zmLwva$*6SY?Bn{&qjA)!YTE~WAsuEI|FX?zvoA=Jza`T!;*!{3kLJGW4`?fVaF!sL zH0&`XOkP#DRH%LbZ0%Xsb<@WcUdHd6t?iYrmk?~54kM(+Aj`r-XH|n4_hZ~%2l==02UN39MR#|n1zvh%ZZ~lD`j?}|s}6D+ zc-6G$o4gs$l;^(RI;NNV4+?$SS)*_dGT@qwmk!E@E=k>eF15wTKiYQ%FJYnSn) zM*e7lbK2F^ro8Cew!02==YmDOWfDd-zS7xd?zriwCP9xr(*6`mErI`7X^LOh(~?aE zrYlBE^WqWex-pC1rusPD{C8~Dor91ceC@4%mw45*X9BflU6fP&d(7EQLVC3gFFi*+3$HoaE5`DIZNN+4f zrD=Nhe)?OUM5Uok40c=>yBu3y%9o)R=qaYvpPaa2KOb@ zT}!1cAs==0ivbCaURv3Z<^pHv_6^4afh{-NgJN8mGoA^ccHG+&_#osv=gx~7S4yy& z@m`^Ow_1^G)vlyrl|xp9cZXLx2i&Bd&8ME_3)`j<8=vz8Lz}}y-+V%EdQNXLTT(f_ zQa~H8^-A`bj=Nc7+~D3gleMeKeO2>lc0`Qt+N^k-S%*-vu zOh5O{bXGo1)vP@&qbMqjr?Y_qwkhquS(}u<9$PU+2i8^@_B+HQf1CZ z17Bj~{<)(?e#sQ>PFR$}%I@BfDKF)LePd1@n##t_d5eY(=@UfRmW0s)9g<7MRIak- zBoZLJZI85G$hm!YHdh2wwIHRB4Y*l?xbh+43zzu~LMe=@1V}uuE;jjwL{W^?Gyg*< z4>{)2s%ANV#@U99o%}oB4L+Q%RIDM3b#eOQEjL7zvo}<6INEHglA9E1xc|jzlHF5C z(2!89ClvM~Yd>*P)7u_tEKtg41~^4<)cfDub)?&(%vyqIVv5Sr=b~YH)LzRE-bHZ- zinz^>9k|yikaw$KyPu)cu%leq8O5Aggi3q7r>b0;pbt=nY#gFb2;mav>1M zL=XrZm^3605>!P%-cb}V(y={A6`BmS16t*vb$ux!CvbzA6Niv%+~C5*5u_mxs5hyD z4B-LEVLQOyDHPZ`DTe&U3x#NKW%3}hMgZ(f1weX~2*@>#0xwO8A&rFKqJZeF&<}9P z5@9%edY%U+7B8WAerH<(ph`I~cv@r=LLC1MrP?^pP z(k6IhzKitzSWt*%y%O(#Sxx;u(?Bw)q9-_*c=Db-*4eTRt~kb)bb%ZCH{asi=- z_*1{{XEx}}Z}s_4vfs_HsQG;#tf10{e_sN9{$P-@5Qw4+f}KMe$icv$;Q^%H8F)8I zo&yY~i?YG;V_-5}2q}N|S4A180=Pg&vB5$@;5VqUKKxfDo)-<84MU^vmoy0iA+z3X zXj?=sBmII^`8R{dMp0n-uo&{;-#?2b!Oz1uWIYInB#boZFoHwg&4NNz_)sKA#gI`s zaP6T{Dd5+49{dP|EK4G93Jm2!(4P}B*SR7xdnpXP8N~rC^W)YDxXVwM!bpQD7c(xNECxAehkA08+4t?U2wV$ep1F*Vf zutvHcEqjh?&ARxb?KtM!N7W{}(h%YICGL1boJPq_ON6wsZ3p7<}YII%U zEnH9v4LVpGJ3V4tTv-Zq@tQe`PJ}JS?v4%N?+C%ym5jc#lw~X^RfCZm^QzPPr#U*q-*SLQMUURq1W#wSCx-iHM>Yn$DXyeQ}`J}4> z`>s%vz~I3W=u@{()91P)5qk#I^TcoW6&SYBDR}d~POY6F87Syhnr@dxkyb4| za1__^WQtV$-X!i_6gnu9uD4D)Dm|yiCIlrKuwUEsipKN~6cyxm3a2U_x&bgQE@frY z2J;aXjxHv}e~z|nv3>2;_^P`0<1CXFYSwZeZC6G9hR;9S%+)q{k+|8O7927`?!zN6 zH(1<1e@&DZv5^0Z7-N3xc22!wd2biK#Ep-B;??c~5Q?4#a9dm3BJRL2Ru$S1csFio zo}t(erAF@1NIvDg3kzbTn1F2&OYZ_QQ6uBhiu;=i?$j^TO)utU z0fz&RGxOVBu~bYkhNK4L8JU;%sOh4DT%<+hVDmB>&2i(OpW%%Ej9@OgRA2Z=K7)UJ zM4Nn+{Vt1UD{^ST8ouc=#pTBGG>s#nzapcw zUa%SpgKYrFWKviqe=JDgo1i0fuyxAKa&cs*a7eMp9&k{r$>eT-Eqm)=P_{ELRfw~2 zq!hDLRR7pqpa9cEJ69^kE3UW8R-Zf*@2UN}d){|MvEYB1f`Gp%JdL$gmN;QQvt6-b zbzu$DQ@#+@8RJjDRL#X?AV~dF^wCIJ4h$R?1OyryWUI8RP+4TQ$R$1sB??Omjo(fB3tK_Aa`K)I|L%IbnVkzAv+-sZ&u|N# z!z0ab2k{ENYQ65G4R36uX=$QnV^f-(C&*-Y+7q?GRZF@?y3r3urJzRsh| z1!o=AN4R1c{f-(bJ`usimuYSmN~!i)TX*7Rq`ljv-3PzxspHY^a!<6sd?E(brObV! zN%WoNl8Y*=d0e}mPqLpdN3s>@qKoZd{ban;m+)duFhH+oeQ$baqk-&xMuI)o@LON_ zkLn}o2IE*;4OGg#^Rr_^D0DAC=e@y}ZFucOtauV#;Z%>9|DX~bFt1+4mKGe+a^QeeKn z{Cqg#SaZ2SW{qdMIe__8E&5S+dn>vc)_re;ah`-CBN>SVnwhiAlUH~*{73DDrirGo zOI}B3`Xfp)Bfmcxw&@1RgyXQ9=Z#m67x)Eq!+QAbE|Da=juXz@TVr(81z^>KB#q_8 z96XAolRrO!&jDxmm$0_@-~@TrFx8lMZja^Mk7~*q^VUWk6`-{3yy{Q6Ef4udNa-QD z5#+eDwWs5sG1lR#jK5px6e_*kTBT)wDy_qndvvVMG_fq&qy4<@>Kp=lz~s~clk8?) zg@iv1ju$(w#pyVkgM6*u{}H|!dg1$96{Pm6~G9=a)sw!0d zikmn~?Ah@%3rGvBde8xK*%3c*yP?7O$MD!6ggKo-ofh#m^LFm;m~2e4?Xq}>_6`=f z8l^9)#h5JnBA-E$BBL0c2C=J4_y%n%$)3p&?Oq`S)PUiBQ+p!q9t=)_2fQv+sd6IH zCVqa^aXP)TUZuf4UmVaGIL$voG{xYWpw%k!7?a_jc(0=1XC-pm}pYjo) zh7wG>lr_jjP6q_Z*c)+V63L{cYtkGF-%^DFkyRyD|6Yi^@kb7nLxW{lp=tV9#q^B- zJ#ux#TMKe)EHP_@LM%Zyi(t40TM#;l`XH&Cj7=z(IG-~S7Tvuw2Q+;{{NL?ObXJ<7 zK?MP+q)ZtEsDM!&7;nARG{JG*-Igc(E!jhH8EDXEZbKPpnBT@x1Wkdz0WbM}H=U>Xj|FZwzl^?T-I!1pX}?rxR)Iyp`%LJ(pa1N$-8!&p;oEyc zg2?;Kq;XaE$ebvOT%%fEKQDM}mpoV^ zeWtcoZr3Z5&vl14^*tK!q3jjiFWet?~V88;eduBWb47Kgsvc^OY4K)|s+{xV+dBGAKw z0}v_VR;gQ&Ti_a-KLoq)?{~HGn2yX$6grNH(BIzfuI#kb`K_-#?Mhj2Y}XfFN=wh!lYeUkB&7xSvQcRK4rV8C3@mEnYfWFC8NwGdy|Rs z zZ_Sdfsora*b1VWoWWGKpza6Tu`(EoW9@0X)?yl5>2p3WnwD1 z%*0fU2~`9k^J2681%u$N2+ySTZqQJYfUF=jkx&^|;z|w*vSQ|f^bT7OX(B=Ab7;?J zU8{9WM3^$~s_l}lXVB!Li$GY`O}%2BN#fS;Ax>nnftP5~E8&0&1ZIEE=opUTQo_|V z=cO52igb5SZPZhhpbTLF4KZMaR19i`rN!3I-wR28o5Ui=mq zpG)4f1s#k$+@y}6Kxim*1_d2c&(EqNYv1YBwsVi_V-QUr(R+8-1?2k#-Jd6p$UV3_ z5=P3eknuueT((aZzS1Rr=Q4UKa;lN}xWVi!_pM`G_p`8j#rGtA8b^tb4!A%F65A}J zY61HfInmmy+Ee~m0cP*~ofXGBet=;KnY(n!);Tim7Ce+L@PP6nS~*g%e1_PiR#I_h zV{9?Pj)nk}^xvd6%xJ%xqYp}|0-j*` zEb=K~?BxL~X|1KROv6%|EVm%|=ivjJ(^u-xZ;Hk3iu=!xAjy6upm34tOyE_KTA%5@ z{66%e5Jz`qR(!4SZDv@1;mb|UUOiDs_#_-<&VbS+G^XyQLiS$aUC0V zSb{%&X^~ORd9oBUB|AjUp2LQeY(E$RWsfS}w&cCD36@`R0!5E*p|=YDp}^qY^KxkF zE+mu(nW8nik5htkK^`_FxhAV6pOb0+4H}H=8U?@+fCEcKK~u2S6l}?*aZzW z*nZ&lBmVpQ;!xQye#G@U3)*+Jv>^ctrY5WmAhF|P$8%mKj0_=MdZ=-^m^rpMzMyKt zKr=I}>biiTa{bMFQ>HUrS2qSm@UsS;lGKSYxxlL2Nm0f*4?wJ;l8nLd+C2wv1nJoE zt`=G!6f{U&S`0M7`}USz9Z=4i71^&^Y9cHXuWXea5u~VSWcgQ(F=&u{A<%Qry6Q0s{3flpdXf>p*j;AY8ZPF}{9qTYgHzdIPq5-Q z9vNPrC-01_LTB5c`=}HD8xMW@czyvIFI?d=S908KyP=v}>@FT`6BSV;H}Md$(fQlz zn?&0_M#U7D$;7~DVRH~%=^s!v8A1*qnN3;ahu@m>p(bx}MOQpnxj(A?xB(9(RQOB6 zcG?tz0T<3dhwYysMTptHc0SZYUw@guPi4zA5+_dYLVo(um(^z4+9op{Zr6y%FOgg zl4R?bP;`gn@gcj24cm9*7(6_3Jej0H=%TkQf9A&jAt@^Fg*G$jzfi=rIMA1f2!O}m2mk1O=fkl));RbT>gF&7-3qPJg} z#|mcf0N5j?(|DoKdn>px!FzRyJu1VR2fyym(NML(dr!#ko#b!ArG@^CzNlxp!Yg7f zo_mIds*|pFGXC)_ zsFQXl!O+v@I%}i7e#_112zrb9?#oOwbH~F85?9yYl*D9j9;xf70lEGhfu}Cn21i~5 zRP{I&JYc^(%-CPJHG&=TofE|f-~FX2Y=dFy3st*N9d)Guw@M6Zo05~(eA_Am+``dK zveUM%+^q|8MOpLPDEFK*7${x~rNVKF*^-S9uR&_YfAo7p^J-76@swb8;PWxrR?z{E zO3D4;^);y_5U%doQ{y%V!U*|;v5E^kDNtDyTsMUhtx45YYP1dx9YdP$D(C0P5{AnC z3gh;Ve^bPOdisXxg+utf?m9_qT4oqyIcKD+R-8`;9&YrISDg0*gu~mV7HuDW$FWwZ zPkB$aaYAjCk0u8UFSnGMXYjm?qQ{)=Blp1pZU&rzF}ZPTo%X%FqW_#CTesgWuKJ)6 zLm_4lCW96Sw9eH>BI4rODReKZXpBi7YR;{~G-9vS*%Jr;8;3mhm;_iMZBCqkD&E}r9=aH@6PbZeKUQnL@4*v_kEP+zO zo?8*nBDG(C(`8$soNM1*PcV$&d`)BNx=>g1aUqF8K4cR53r{Z?yIcMetmfZ|`W#ST zHQfLa1cmH9lt#To#HlDLc4P zR%?c1F?F*gex>4omCT3^tRTm^Un|kSJ?UE@L&IY&2JtBD(E-3Zhg7=;0pBY5o>$_q^AwJ z`DM7MZxZVlQeO-1aU9<8<3A&gSPRn&QYg|>rpN+#p=UbS^apU~|DM2Hg`wKkyE^g# zLlN}OpU@e?hc&{b&~aW9e8IC*=+$bKVnyrdz6M2H=)P)2?dG7cXnZJ(XdvJ6`t+TQ zmDxcLvMPe9sW7=s#>rPSnrAVMqE1T0FdFD)jo-l#v*3ttCVs~fg|vZQHddKA##Tu+ z7voiCAQa>i)|`h{Xo2Di=R-;_*njbXOZ*B3u)f_*7TCPxA_8HYUHzX9j!-9vr3-vz zp%TwRL=}Nqf#h$O=P&!nbhjPR9uPHhBe(q5Gmq%G#H!|U2+wDi^+KV|=a&uPia49^ zAU3STZ6w4O{#sTgRv;{DYC@7*b-zV;GiQQgA&8Z+x2fj{ulB<=A3+j9guQrxi!<}T z4wDr1>H3GZMMB`hvW@Sk?_^nH;k(Rh4HIzlbCVlx9GSaiM0(H1)SMV;2hcNZWMb>? zt8bo`XS#cg<8bZ<5l=U~dyXuG?xy_vcj02hoIIB}kCG7)+4_MMd*L!>11gtza|_Ve z5r)MREVbKonv!r@?|J%h-IFxH4hJnO<%b68@?T8ueyk#2xW4pwTVoti>6*qb|I|E4 z^$@wF{PqFFUg#VY@HqzVi#qAeA;a|n(8t01@h7UE3qb?_)Shw+XQWVH-MpQ_Ioqt; zi+4XDJ}G>ArP+b-{DFz2+`2^R?!$;^xlN_BhN6;2XNEL+W538S7SJ=Gf)w&u9zAxAWROgL-@^A)wgMCw)=nT& z`U_v|XVgv6eynzvRZjx7)p@R&wER(7d{Ox2En@0YEV~(a-N)X5W~#lFMx zyG6@@a-fM|E2<$%+NW41d^@>={nqrT7)Zm*Sm>X8-c!jNiJy}pLi-9{;HmWI`tbmF z-;0B9$SaG~EeF8;f6|olaf#bM!azx-6f<@Jan%}mW&~&z@l=2 zRm@Fk1RYWI^1WR>?@c-6ezSUU?`kFvcoSrAfBZ8`_wDz%3!f->zhD7kH%baIuigYP zuUd4t;p&}$pI@`@Ln}+(2@cF_IcJ1mz21uo8Ir>=Y2KsutR%Vx_Q(%TYpBbN(e{Wk z_Nk86I2#VuXw0}wHmKa|_9({m>LI>N9Q>ud8O1~ISxn@5ySKyubyB(0#PIOWiP7yb z801r@PXoOf<-^!M9q(2TyK}_29sGQ_>~-}nz~8+chx+I!EJjC~cmtp`{GpMmUzt^D zC0WW3NeNY%>-WiMIS-O!_?$Nq>0F1UKE1UE$sQifT1aI4SV)7QP1KWi>AXpf+7*fi4- zR*>7R(gQtVlp3+$CXB|_XCP{lXWT>~BcTC}vB>t+3+tgE>q=vORmpI$0@#;++m4y~ z`U~@Rj~^5jE(Nj$#)KS4AiUvq%~RTwwNaJO$_ZbNa84=Dpzsa7`c%3hrf#Wbp!QlmeMWgYTz*%-%8|_Y|JS+ z4kLDccQ>Tig-|n0k$4uwZ@p*5nH|GeT5LPEa8y&FIsjw)o@_Wo*6s9AQCT}}yMSqi z;30W`NCR9gf&#%Vs9L+C-SS`4D$g95nmy-7f5kx&Jq8R`B7X7KtcoKQHKK(^q#fLR zP(3lw^oSB;N$?6@LfpP!C)DqcW5l#nNuze*5-LHf` zim>Pf@_;0~p7GAN%NM&pkYddgV}|t-C{5@>ZxUmN%BGAxzBibRH;7VToY=%{0FQeGiM6t;rk@ z$ozy5;{@JzG?Wqtw8~c$Mu*XH*3cN%lvyoDuB+syC(`2Gm|0U> zGjrwOZ1s!Snm@4k>U_F(y`Sf59TZ)RiwIe-t~^@)j7tFX430THk%^hkXRfnXz{PtTsGR zHICQeb&VqpLn`0YQ(HwA4|M8?BeY=d<23Pn+HKgI&OaJK1Ol-F2D4D5gJR}^%NNFi z5-0I>+0nY*X;b5^%(J=R>kNd7Twt7|mB}CjlxgaY>boPDq*|A337S zF~2fqPL{W1)oCfK6i+-1Dwa8cSk4-$oO40=3(7bp=2FcO!L7{sWqy^3hRK5=vI3SH zhG?cj(5jT0RIXcHyV}rH^f`Tcwspn!)W{q+Ils)48O}V^f^izAqQ~aJ3!Ju@&9ls3L?_NioMQe9^1Rup12y`vFM!JS+w7G~U%={+@# zf4L=HAu;6^4mUqA+RtFi^O%2XsN9E?XJ}gS%=j~K8~Uw)DhP=K+6)Wa(~T3%BG=1e zmSgV4e3p)TFNdQctY8o5X?MFKDNE`P=^sTX$-EC5UYc$iA%ScvDEY&>50XE#r}}h2 z+}WX%TcKi6D!>|1d>6y=>ghtgE0B=fr$VjJhie4;1;){LC`Wxw2b=2g@&>Bw1m=oti>8fkZ=;=zn zeP}-treWNp`qoPD>6o$TnxJbM32PREIl!MNO`8&K^AMPw+2)MVZp6`UhAeZf-!=MMv13&xhpiEW#^^u8zh( zQCK?Mpof(!YtpvhMXa5nxjw-QhT*s31jTki&Y#cFJK&Hf}YYHa+3r73A~6^4)%Ni<+{NVMZ z?n~*ys!ssYHW+>AidkDciGL7Mt`KV0WR9brr0cS+r4G~BqzlckgasgpsvKz6BuJ`J z(Jpij+k@t3#EwhPkP!_b|B|^!bvV58En{Hn?LK&?8^Yzez5Z5x)Py({gv2M7s1Fhh zDu&ByykRQvZJ(NhDQ_WD%bEP!$vn}fr{YsR`)SFWSfnWeY750uAd(-}vNkEM zWrOlst8ya7RcEQDtMJC{sp<=%5r5eBaVFj}l2$Pa!#{k`^_T+Wy}^(xXX$DD*8_-1 z3C`yPg4k0RAU4Y}w`N5!t&7N!!BJxtk*z_)N}=UFsd8j2t=2YlK>rqQ>L&WG)BP1} ziji&75nUYnCv4a2w5VApC2&dftS0gKY3Z4=Gn%EcM12Saz+q+W;hr*T55FVLH=5yNIyflf$3Hso z#F6Qdm*g^>8zy*krZOBf@|yIfFdQXsNWaJ3CK$5Idh#IY$+zeg8N<7$-1TvzxEa*T zysPW+*P}4?_M_HGD!3BUV77DOI`5_|m_N9msl zAPEjFCCI&2#(8uoQ6dRZ9vq=6O238)ubQlCn`pDFo~^5KT}Dtg7P@H*)Jl5LOBiXVP0{h5C}3)yPvRuiI=yTMua- zMPL&AT2+^ADe2wa)|8h0I8fyf5WC0*eqH*q$^_dgWff&dTO*-l!k9wyiuwAE(gvTL zw7O^7NO8cIZ~f;7Ei(Ia6ZT=FBGm0u|9mGEXIr}*8-n_0W7Jl#JTJ=E(qs^=pB+7d z9+h_{Z8mB)c^lkv0-sfd&zTiaohr{;C8ujF@6AVTT{o4IspT}1x|WVgOm+zvD**h1iO% zI+f+d6>gSiw6&#+!ZpJfj?pI7yiJo?V*cbujeK`ruHrm#xe&V;F)#KsBqIly>#;*; zd(z!EfdpK5B*o0xM>-6s#jG6~4XVn&K zO5p%Vb%OR-8^>~Vn+mdy0gm4>A)VPcJCpR=HaiPWuw@PoTkU^nGx86-jtfkI<{iiw zhW+p?EN8LCASGdb=qzlTaZLzkE8Xt|`bk>#vVC?>78`+Ac zL18T_Wd6>VPq1d6M4t8)AF1H9muWv1wl9o{?iIF=_P`FdFToA=ze7#-zw5sJE-J*y zOm)Z$-5+ZY4Vt}7eM{vo;3Ft*3M|Ndy?Ka8_BAPlh;3czP7Ov#?au8(bkOHRb+F;C zGGzSD4x-=WvtJ^FdAT0I$sWE66N>4uAfgaSJn}*fY}iM7EeWBzqk;g&jG{W=nPF5M zG{>UWv(wdbSe%yCeyI!pN{~pgMuqmUv)yFXlfE$8IOspPh0Px+9auU)^RSYaQnFPO z<=oJy98j>kEn5$rQ7it1|dcQLWVUW+r!!eb$+s-t^N?8D=ehH2Wo#6U5iM z7FceDV~sFA%#eJubLbfVMX2rcn9GhOX{wAv6jhDUf;{kX;VD%P33YL#PMxu^SW(*3 zLfzBwv(IxplD-Eks(*4w^|~Chg13Id_tK3HgIgnYK4kv> zBROO$J2?R`*jqvnzF*ijF(eSLiFIs4U~65wWM(;H{H46L6f-!d^eW4Yco~TQA=g$P zRv-&MmT$`=k$RPLCGjn{Oyr&Ki1(ueJoOXIQ`{iFUr0faXE)S1VMkUv;Y&$;PPx2Z z41c-2UJeJlfL{y`x`1CQiFFlF)7|mohK?XDz4`;VcGijHg=hvr|3ORr{d8t`dMUkeKF9QmM$D97AltnhQo)$Uu@p#NGAPM*PFXNqiEWThxvkfg%rq$ zxq}{{X4WSSmkVhn?*6ey~wh{-wm96S;S``{P8iQitVR6IW=0x%J36Ti+IS-g}F zstkPaBXvP3ic83sT7HIWH9VyEZM%9T4S@n}9QG(QJti^4_!CcjR z-th`YDIjl3+Pq*NTp0ongo|D%DCA{Ei81LijiO10Nlb z8If5gF%iRfF%ixcljn~UammkLO*E6{hcWm-8$JY0W-NyyNh!A=58xts1z%kutY#FN zbR=e|gHA5hTa;^qz+UCKk{U5PD^UwpaY0&Ls~ho?-;V!0PD4_Pw(S9dlAiKm?@9*a zmez+|^s|bjMy0*3jqv~Rk35XrT__%ac;rekNchR@{3DiPgnXnxa;q_{95DIrN1>p# z9{EEh5~`s`%?{IWh3qkntUjz$E2Puri;+ltI+%)$8>#P0Fnq%gIxHYJG=lhEUEXWy z4eYdTfxQ9$x3W~bzds%T3Ic)y`5#RBuY&00YQ<#bYGQ7m!dSryfUY@xh*m9OnomcP zgR6+G8mm5mE`#5ePb*`#F>E-j0>=ng+0yLU-sj;$Q{I-IHgZ)(3d?M6o~HqGex8;u z^Ls@7AoRu?!uUQomZ<2K7T(m$JOmItb9mCmBIBf?Dt})S=s0mX2AOp?Pj5R<*lRNq z=rqrV7`?XBsW`)d+eg|uX(&250DQ)Z*pPfD+y!~8}hbzLmO#gjfJ z|A=2#Iv({ach#E4L+|_d!(s`yF>ICpCoz6q!zR_^M0_3I!uW2Mn z_H3`2v;#+HK;tCRa5;QE@8k>?EPTsG@If-hoAwz9Cb_W%wD9dB_YVfyh0TS+Wh!c) zrSyxMJerg-&61N1(e!KlMjjXz7YHqdxWf<_G#WI>WJ<@w^aP5C^B)9R9TAtT{HEBq z-hOHuSe_|>$>BHlFBuE@CA_pkET)iFcj1=SRxz^>S63+BqErTv5**_XasQl?ev$85 zbu5~(6N0uFId-m4jgDIE2>WItlKFS!{CrYyN7ClOpN$GSsbeg(LdgX@5$Od2l23AY zDdnifmkZh`FwgiUSK*?HkgW3ikcF10b1U+kctu2jz+2-CZ~TKH?Kj4z)7d7K^&(jp z^7TX4;t2;vh|{uAg!BUr9?>8{HSS&QPb{*nrjq>pjBak0?KFJUz2OxcmaOvtUzkTCeP^4 zXYgcN>*Pjt?XdpCcWb&CvRJxpXC@eJ|ZpW8>LhB(mYtr1LVe^~PZ=S||taHUSz%9ka!E0!SxBgb6wIALB8 za_?Fggp!xoZTveGx4hfOK6#PuFqZVI)N%H)G$j+tW6-}Q2DPaz-OauzSZxN#I%%*K6ifhm$4fs z0%o4YU$2Oi=!KKDF6H0Vw^yyG(eaim>dhJ_hYQ|I5XPr^7%>r7tMX1vfndG6+9_(W z2F-bs%gC3_ndO|3#hP-gOD3c3*_r4_BfPVBo@|84dsQNdJ9r_dfBtN5+;fz!^Btwz z=-G+E068`miU^yzgoxLOf60%^31TEJW$`N_O*Kr>TqLZX`PC+ET0$fZehU&_NKf55 z+%qquM+U4k*R(mH0Qca`c?jf`r1I=tW5k4*8g6-b)8Oi#K!^jyqL3Ih{ zUhM-*zuXW~y4Nqpy`lTAHSxMgp_6?OL&H|H;v%nttK)^K3OhMh%qZ;dT)p7nVOhI5 zCH^IIdN$8QiR+Dn^f+x&suBL?LuH=LCtk&+i01BE<>X`9vVNw?wfVq_zg;|Q9D~ZV z1PmNU#dg3pFt<@-f9PPvFZ&iR@!Tg5orhd)gQLK<3^uOGx{rwkBqRzL6mhra{ka?W z@2KV}ohjt2T^}c9-mY!>!M2crn7!W-UNaWc+ogCkpHQ6zYebg%*%CEGcI{NK@Pvfo72pN>zcr_MiJdX+H*mjttOiF?hgpEIs5Yq)7+roB)SXo=o zkiKz3z8toLA-9RsQ(d<{dWf>zh7n8^cMK&MKp=grGq#PND5Gnb0v}GGxINBp29O5N zXqye0s8QNpvVLjNWf%Wu&A$p=Y>}bl6Sj?#Ahkrlw+f=hRFcRWD+rYli*8d!AIEn0 zz{B0P z04;LV;x?w!2Gygvl7M8MTL>Rl253x}##U(dSZ2)Ap_%TmGuPGB1|%4m3PsBK|=><47lPlNo4| z@Ovi9UqD4dh%NOuX5K_OF&5sdt*uq96ER&ot46{*Dc|WI<8?=T^PJJ%9kS;<6lc zIAk;yi|y|*f9^8X+qadk$6u!Oa^37~6`J%I^iH|3R&*Y(Np(*f$?34gYBsA>gSRpt z1|g0HwLjzR4H!c;hw|Rn*arT6^nueh^n%MRgRA}K?ip##ayvL=Bz!;QWt*xE{l_j$ zf9+P!m8yG6FKWPMiOeswKmwn6UnUF7PadIP(g5oj-;+V8pg0ld8Q7CZC}EKl!sawo z(>>1WM)O%L32#F-rA-gG3q;LMB7hsE1HM(FLSNNA)tvc@f5VXtl`0n013 z5C}#yhq$h-fss+L>g>KrAaW;-A17VZ;E%2cv5&^V@z;*Q#5<8tBH(2FC#f5jA}+AH z-*A5fDKw~r`++XRFuRWM1-WN+$8|1IZh%GW6S^^~;H;uzs?tbjNfEM`Ngy8YkW*y6 z5Qi8VW?qF%su_Z$e7ai!skU(s|!=2Y_ zHzbf)VD7sm6E1z72Mk~~86N{F1N*m+NbFxlgF=T^nVh-0W-fU+Smii7p*)(wk1Zc& zp@>UZ2wyPYEBmL$sy91~;kuP-d3b}`UiD>zj%ah&ycN{C=nhaFZcE}b!Nv_fofub* zwbl!qWC5ye;9ikeyHmxLUGpPkBHin)i`s({JWh16Ap!T;0Olr`$QcW<9}jY!v`8x} z2T~|xnI&8VsxlwrTIh7Qxy(YGSgSfAc-M+&)yd$EH$CXT-}mOC{0FItX~o*i-Q-Bc z#kB~S6fwo;VYsQj+U2bQ(J;Ma=nA7v%-)0^)04J+EN6;) zW<7bmN!T&$FEJL=@Lvq32>O9mceig4p+@Kf^HT<~tPrmFyK}jNz`hV{iIB|W5_TEu zuj)YnGuC?~AJqboNr|uHK?u~D_|xyQQFU*G@P+pc?Cb;5H}tugW~!9b4p9`t2DGlq znPia5X+Dikt?WpiD0uWQ?r(SFT0qQ#u_uPu0^79sJIv)0Yor4E#m9Z2H-yf?R&^8AkpBUOiNt@l^s= zR;P!+6%F@b8dO1td+28z6Omnqm6Z-Vew*)%b3hLihxy8!HikIuMwn_9CH1NyGApD; zJU+S`v5jlmK{h%4n`!P?8mp>Z2fQF+Pr*l~iLQG#239@#xs427Ws%+7M-gc}W0`Y$ zgxl`E3o%~OMz|ejMP2XxZ^u(xehd4Zuz%A)m^40EbZrd5sC#{})=t8)tm^g(c>rVR zi7$(2(~jAO*{=dkeb%o@>u2ubTB*#eQ69SQ{i>@u_sJ~&q)(+=g}0*-O|Q{7-;zWn z-ZNGurS;EwiUaMMyf)WPJB@;@uHLoNo=95#eS9cvm#SYixWu_Zb~6GqH1dV}@I{Kzp5pt{$&aZna3j9;)CoJ?=7#CkvZ>)9Fdio>?(~7E209Fs{6kb9+Z;ho zqMC{W8BhDqGdLX)7d1urH)prYCO?ce3#Fz!ezX}H$4u!0A9XsRx@nt;ZKv@iSL-5i zv(ovo_}%roIYJMqoB{h&akx`-AvZptGJR_>$2G>|ol8cE)E%PsGJ=XqoBrrj-=v=s zvjqjza!)eVzpf3ZeH2WstkIq`MJ1K!9)VKw&uL&2ZhUf_AV<~KCHKSf`lwYeSelaQ zHk|Ng`oqLg&o%c(RUa7&9F>FI;U{?_Br20;f6D#iv4~UNqdXS@a&Dm{brUCGATgY8 ziG}R3TeYX&G|CRWY%FP}qCRLMm8~<%Lztq@PCl|k>eyByX*AcmV>uxi9y%;MYN<)d zG$X5QW|V1l8VH&6X&I+jW(Z=j!lbfQoByVnhmuUik0~3oof)VzTaD;aT{XhYlNPnq zKTZfYXPwt`S|-QpVI){5tRMu4K`OozlP2;vRX&OH{PlFLh^m1pBG!Q81aZf3Yz*P5q@DK(ffJW- zf<`^}Jo@{kzpB^L)QsMdBZ7fuxN)_#a@DCKFrht=Qox!y;_>NEto|Q>{}xKph3x>P zj#lr4r6H6Gtg>FYz#2}*-rMVlyy*;oQ;b6VxD2E>(UH9T3d=zH+Xt^NGj*?d(zedT@%#7~$qMLGZ&O?v15|3wTC> zwg0b>vpF4Mtr+XqY4y(TyI^$5aM$5j(TVZnmU!0ShUU)S_W0x>Xx#vW;*Hwd^Ju!ndoVP_~+1s@&aZ53S*!>&C0AD^Y<0y^*?SytZHfGvAr-MahflC_-i@3djyv zJ0P6ZgGV`A5&lHcg*65fbV|Ytul9WKPjJDuH8g!OgN3esE5~Kl@EsOD9viIUpN;Zl zpa8-TR>vzp5&{S;Bu^s+qy^?zfhZ0+8N45Q1(JU3v@2&M@r0J~2`IgykLxz>+uytj z<4*A*{vnuv?aCdj0^!k=)Y+nXVO&s!)-h8!R4)UDlnshlQP$gNeq?3oj=`>Pm~5i* z2FXk+8NyCNRm{EGO^NzBsj&Kje^_-s$l{@kIIBv4^dxbgwzQA6Q^YP&@L0Ptayqrd z>zc_UoJpQS<2)nyf?!!gGP7BWBZQi!QQ}}5qw@wJVN}*IXo)rSkZ86hrewUUoSxQ6 z#X{AVBYT5}zH(O8qPPI6jTBo@-cWJ)WMfZ$V^is!dm%R+Sy{fOMiSg{sLd&Hb~rSk-Q7<#|sYkEn(bV z?20RZgzS~M1_JR_dV znYVWKif+r<@kN-Dx=k`QN!M&Ca8|ENG|n`C313oR91cZh@R4Zm_omDx-PO2=-YWc? zphmKmviTL8`}3dAn|B6c@Ha~48#Q`BkR=$J(xTgvILz4~?|LT>~_RbyZ6uk48O0Ma(N#Vn5<(WSYo8AI5*6V8DXr%yoV z3UTM$`1ZfVo<#4gr}<9fzjFd|m@Sjn$HafR#OPbbjO(jtq9xLi)x^uI@)s!x#G8O+(zB+LG`#N{53a<@S=)D6~Qgd-Su+*+JHE_1QB%$ zaT_PPT5wkR;t2NAbo_23)FVI@WC7JO_f7q~l4K|=f&BB^y;xZXd= zK+b$9=0?`UMxxg{l;^5wM)=%@VX_UP;@#*NYz2MXk?8(j=3RRxDPjMvfes!l28PE!&q{rR&@lPi77`9|Hiy%0y!G(Q^#)sbw32u=Z9|%JkWTc=j@~~zsUzy zxE61LS%aN;Q}G!{_Ig-0=IM+V2DO*wHLqIH?8}-4#LcWyf#?B#8QotfB}iLJgs8mm zeGyLhrs`Enjo~40NTr|bqRDL#7elcSjy|EkTRk!9ujhR$P->=5FmsAs^Jw@`g$z+A zwR$sH^Zh!$Tc3an9}FV@BOUb*14TbCQguTQ8b7SO(=B1UCm$pA*pOXH^Ln)Pb+!Cg z@WO{Jvg`Xe)imHon|?|><`yD&wt_2X$(RM*0A~w{sec#Yaz>^fSu00d)>e5L(?1Si z9Z(^tR+ZehuMY|}pLfGr*-?R@o3=N+>PRh3(JT*s>;xrcBz`$2oqr-EX!FK?ZBHt7 zMdzp!?q~_cxLK$!ETKBsBl&$2iBb-Qh5UM;hk+pNk3`!{*I@9GAezm7LHJnDJ_ z_nI^8suF3q1{Wgh^=7Q6*S8tr>f*u>@&!jJ$i?lRNx0&E&LSwpD5+kGH7IcJ6=0L! zpx}12eH@odwP8kjXoqmj0`U{dM=>Shn?d#wz%1({+KQtcC(!eAOJzUm>k4|9RoZUa z>wQ6jspPLftpAZF1R;~Jov@Q`Z~$@1_KK*&NTZeo4}TA2Wb?uNK+vrb_ljX)NT8+E z<fcjKXHhNXJx<`?LF+{3^V9ul`D#TA=P;t zBX2EgHPb0$swdWvK{H}~UM+X+XRYgIeGg*yJj}Dh_5BLMGoDV286B6KAH^6^VCtfR$Mb2#MY~0*5?_#NVNgh4)Um|y!ii^$<)?H5no=Gaj2F1nc&M)KJ9Q)i( zuO!tm`DDwOe?zTe#nKXl9aq2g`p3?m>@D~G)zPn0e{TJ^T+_3f?FguXFf+>N&k*U{ zdjocC!783%c}RVQFf(2Ym}o(w|~|;GE9?GiCQpJv3$af!55V5bAvAOGPNI8w%X) z9cf&AkN{^9!xSzk^c&!Wq!)pEiY?JLM1kQ`37;V-^z9))#{h=8ALM##kA=C9esNXg z;QEI40E@;yrSSV$fvW(^Jqj9azGrR(b2}wE<@c#%bH(sE2g#2O1N^H%gn&A!{IDI{p)t!^KN;#_~gCKTb#^A^(lPq zllT07al+qoca3QXQ4ju|bQ>8fDe5IBjJ{2CU=I__RVFmB@p|Zt4Y-Ed%VpUv*@fG# z`Hi7Sl@Z~}vR!0EJhO~);_K~2h8&@1_2b3G}_D&quQA-`5gcxWrg=m9o-aH~1q|DX#@p5y`Z85X0ZS8Qf zu+6b1VVx?v!NVcQLOtWHD%f0N)AMfUHPe&w_UaCND6nR?wN(2{O`^F$$C(4+zbEMv zgu0lR?Cc67I(uU?dpqrnrP*&tCW-c-q~V__#F9b2Lw3?21Nc*5xX3LtxwjhO`5BEX zihTMxST3XXxhwj954rytOZbAtQy8>6;dfptp1R0jW-u20WgXY{OIL@ds4c&-8E?y0 z@M0=AxXj49)!5=pWh=uvG3UT%V%t%REo&tuv}WGrW`o!xcSRMvQ^F`nfmJ?>{(`yD z$I#eCtqr0@8L+~>XPqHnUuY;Nv!X=UMnOnyk%&NZJz4!UPGNlGOCR&5Yj0X zlvPm0OF`wCNnvYJ*HJadPhPR#d7IF$SCNTh@V2xU7m{!^LP1Y|cX^D#I5x;cYTWQ{ zaCmk#EM2L=?Prtyt?SHuq9+Jf^TXXK7}0O^2K-KFiIeWpvO&?&&m|$h8N;GR)$Zfy z6G-B)&St-i49KdqBu$lvt^%a+rbb`y`_f(Fu;=qu6QI`({!_>MW2=rQ)&>*j&L3Pv zQ+x1EMs`WPj6h#k^#W|5oH#0tE@&ogjt4!Rr*unt{KAa-uV?5mRDw~tk*Q*z5@Ey| z9Uy4V@kmUXUQBfwADYkncw!C)`GP6;LXLXw*GcYOzes1cFd(~GNK)p9XOo#cP=LFx z+Na_iYyZg(`VG;ie#>j{Ng!FFTr!zu6^>3pm>=d(s=XO6U025G$>;w|{6lz{@RkxC za4d&4s*DX#zSaDYAK6j=0R2v>ubYjH1c?30VY!GJgZ7_@@)9U3i)9v7l#H#eqvmu8 zNiq)8EI3qKSyAx)P&rvlp7i75GR`c^d9E7TxE9t@)2>EYdFgdD-wO7za8DVH`t%KJ>*9&J-0?X7x+1*2q4m8^~YdSvTJp& z7AD)OZ??%$;vHc&0Q{1d|6RR#=X#xUv3Ih`FovnkRwtsvG$zxBYx-W=1JNg{>6b@t zc>($y6Qs2lg8E>C(<2>-D-^E7Az`|cz`HI^U4~W z$gIgLo=wD{%r5y9Zf!hyolx%ZM-?5N21Aj~n3fPL5@{?~*4%O8@_AMwTDJ76S<`jK0`TE^Ai;#Sz^)Bk2niWea7&kP;JYgONqJ zwAn&qh`5<`n3HPhoEoLXJP~itJWnR2XBNem}!h_>k79n<;;qqkZHctAjBxV zvxn#gorxx6(ibvcm?e@s{#=kan*)jM%G~$xw3f(sChjSsIoJkO=|+?b;;=vD)u@7; z2`0g?LuX$)($g;A)i5mDcc_zb;FGK~R799;+1Usak;a9TbTyY~B_LEbz3^NROhvvw zS($vXPa~_yZK94Z?x!YVs%LcBHaoC~$zVcWX>^v4pr>yj77JBw@)7 zZ72MIo|n5rjTaknd4$<#;0xqTGN_h^TBx#08^7Y5XAmkQ9rCX(9|zrsBLUmHDaE$y zMIgu6W{aVZIB|Ne2WUCu4!2HBos*-#DM`Ylu-LX#1!rr!6J){wPTN`XDM)l1T@W@R z#zCJSMszLfLjrgih0YE-KNO&^LFA=?nz=B8G{06A)#>e{2Dd<0M(1PM&Q zgFQP}+lY6c6O#vdll}Wg2V8q^G@=mT+)p*}4_jRz_O}odvHX}ZQVK!}3BOpi(Ctd#xfLv=@mu|rj=&6Ow_W%^SmR+wllV%TzFP2QTniJjot z;e*arY@u2e>iB;B)yhHf(V-!CW;G6CLX%VW^osOz4yWUaIr7R#IzuiLJiaxRRZdSU zWT3BQ=*}Vmdom^6ma_y-G=r%$6xSNbG@^ITrT1YK=Cht^%Mv5);ymSO+yh$uifc94 zOCRMYaG*I~I6NoWqYwVx`v&=MEwyAG155bhS;9{)g5`%hq@kIn9iNhKIRXJnz-hvO zn?(jAL$~lvKEqc6Q1jQ*D=8seN1_+dH-jVB2a2S|puq@B-|V#N{}Wj!-w^i$&mYkI zBNifK@=GdY#x*vrk!>KpL&b%*|kNP~=xbU{i~O$3$%#RTiY z1nQY9ocjuPx*RN?IUW-40Hr%4g=mj>lr)|i;@7JTJy;cF&cjs~GDh2uu}bT59R>r2 zGgk|PaCy9QGg3;1TDV`mIS%Wn6-jd{;_KEs+pWmJN$FF^h28f4F!7^s*(XWhGYuov za?U+b(Zm$t!r?;nCs@Vm{-a}5td&yv@hsWE&YA+vfW2VEfMyrITVseOJXe9K18ULq z#bu^gZWQlYdz-gf4Pru`stUjMXxrd567t5PkT9AX{AILHc8ZK#AvK*6U13{kIO^~{ zKxKoDNh80)9$MBcwnqnU8# z*_Q;M2+F|G{_W1Z*YvwECg7C*;h$wdpOt2FWr(aB$%yrQf z|E0cFS%dcJ8r}IiUbh_qKG{Da{PhErTA-C^z#GCiR&6pT?jwE=(I%TBnBbpB=&Kvc zrLG(JyppeLD_$T&#KcnKv8VZVPax}0pzTMcjMm;SQSrq*ag8}ER3kg&8awDqx-cN! zhH@}_N=Y>eC)h19;cAD)331>EX6sIB+|wUfLN~3SPe635W7%bwe1XG{V~rf8@FfWZ{m@52|3Pofc69r?F&*EVgkAC zjV4C8U5iF`zh#Lr{(Ct9GA-Tq0QuhwSb{B9lpIGa4`?nY63_$-qIC+4CK(aCAtpnY zPmu63Zfv&X?zzgmEOKzFF_?8(NCGv@x|o@o`LeL^ba=mCZ6gG- zaNY=vR|d6?bx&riEwUntk_J_+ca!^bi%OdJBUWLL}21mQ`D6cDUkjBN;Ro}aR1uPmoc06QDgnu9R9_?_TfVo2ApP?pW04Lmp7lP!sFtP;hPL&&W~uE zT!+0{@-^&72`-y`O&B$(+TY$5Cc5dFY6%SBkD6Kr3(R?xE(_^%`lZmrja0VL(>{qx zJ`M|I&!$u|#lSV%wC9O)!r^mb9h;un?zh}*M`+m}PLy z0M=Qj2>RGh@8bm3!{=LZ`7e55oCDwpdD!0oRvA`=U$&k0&S&>W%jY5ZhIcHUZI_}3 zfh;f&dZlOZC6YpqXwv#~YWayJ5zUgt)@+t?t&r1n0m3HfYVbX5Pb9*;`9(1`gGRVx ziT1zG;`tOnf{N>71Ip$IMNX_V40QHQ0Wqm0xN9*`qPEOzjX4NdAzYX&1d9mK@tdAx zt1-uxWNP91`3OL?!1Z%(_Q0;hO429N3sSv-vcx{j)$2-2`1{PkO)*tOy;axGlcaNwh*#k5!mEI7~}1|``ba-Ed9bRz>PK=AnGC>XLk;OGzUHvKae=2)8kcAn zqD5P zg+r#?z1fb7^``gBGXAR1`+UOyP^O3o76sE=FnC#(@cOaDWMX4&35@i?_TVZ!!suz3 z(MqK*3Q@p_dps`j=3zVe0f#^mbD(>CcPteL7Yv>!_FJxFtdC!~F`eUjs@$+fTa}MQ z6;395m4@o{Ww-IUr+QcI2KRyihumPtfRpQj;io&iX7^TMdiGzlgq3Rh+`SYeJ2o5h zt=_V+XVqM+jSIP4>o6^dxRJr*E z_@<ROYUn$j+Py7Vo7Z`2v)jQ8x}t9-Hu-MVU;3_qsr@tXHWxB zEv*1oN&kxgy?Bzr8QgK&ZzPMYO<2BMui0$E%DL)FxSrJpK!*e(qRk zHA7}HM9+E?O&sGRfooT1krdvZ4BI zRq^vj5AoW2;(pmF)+RhUhziagq|yd`%b05iW^pn_(^FR*5(m%8bVBN9L+>m2-y_Ey#Z zX*r|ud%ia)wW&--M3Y3STM1)$F_(sx%gbdg{VEQ9F2FzE^+=y`hyo0M|A}GDcro&O zBE-Hun7M)o5x3nJJ(=0$e%|y|uoMJ*-yr{?;DD`HrZ$?QuZFdZJD zA?_>jL$^m|nOxQvX+?G;H!dsz_`Ukg?Iin1UU=tFw*|-Fc!X&j=TJ1w)1spsk2Jbw1YCiQ@xb&JZw=;avUwkZ? zD_BZJPH_+3ic;hoS#bF$ga^Hf8ZaxL@VF<}GS1#_TnqvjJjDjd(RXYFG}ivzp+s6m z+ekd^4xm6#oj>X9S>sK}Ef>hC;IQBP)lXXDuoQQ{lI<>XWH=Xk+j{;=f`fId3&^rS zqMrRcT3e~#wJ)V<4hgy%E1QtY#^ppCOv?sdtZ|Q$^D*6j19AHuy9K=^)`P5%e?Gp8=J<@_J7J~ z%FL*+LwZ2><`EC-?Jpo?wxzF-)1G#~VRbHJslA)o$HvnebU)6tlc(T0+Fvle0+3#Q z2VS$_#k8a)hq#bt_5X+IdRw`{4nz~Hr>$6hF0tW zzFyQx+u9Y4XXdaxC}Z3w*nb(x??Po}?k9RdfeZx1|3AQ+IlxPvrNswSH;dO`&@#Y{ zCmi8^EQsZ{U!Y$AS#pS*B-ah><-riyZ zMSh=HhJpq`l=b=p$#QQgp=IQJq`$R9YmGB|YV9+mp=XiJF2SJuJ+ew2Jd4>z=kbHm z7$y~3$?WM97j*Zji%JG@@Rp{;(v8nKty_yWVkj33sga(@q38fS@D+-pYv{Ll^*~XS zB+NkxQWJQZuI|vYs4aCOjG$myG5>gg^VRWJRIFPY8*Q67s#}WnNtYMQxfr%mpK+vB zT^Bi+4fu|HO1^U!rp#oGJaLOpuv{SFT+|C9FvF3Z9C1V0EiD=2XiHsvcF~I}gzfbg> zFU$=L((LpnCRq%0ytQX0VQL4horofyb*y=74IQ0~s_vb#xbe~SqEfpr&@!^Ct~@qY zTAicrmt|oXhRtCLtu*F>OJLFp)calZ3U?){kt1_;a^+B}|KhBMlrtdKW~;c>z3Hpe z=YvMMZ++A?)i8N62=HmgUao6>J#s@i1xtJdi28@JRR`-weu z)8z2y@!ZE+!{b8plsL6paRkFoEuibD*Fu!R^-tC6F>TShp z!{iWj`n!XjR=f$FFB@jWl)>L`OGDexy5l_2x?=!aFbKQ+;McBXe>)ecSAXM7HhL@} zZ>^L~e-H^M-4N@3BMammy7%d!`3)d^qvcD#=n2tl@WCML)&D86TtfxdDbt=#jyy&S zWS=glhhm#4E(NzKTdgdIKdG!fSIaxIZ%&)0f_Rm2CP#fbULkR04#nR(W}V5`(G_?Q zGh5kh>|dEEjfg$k{>xm2>Mi)$P~Bhj3$`9WfmTfr4cP0@{^A028@<{+6!6WNUN^M$&ohl2(X zUr6QySMn)|%oE&bbpbUnKSG*NC@+Z=HA89iYWzzQw+5CN*o1Lnh(IlRm07Vn2&VxN zGxAf5WP4~iv}xcZ*4BxBH&;t_FIQ_7<$CCEnh)g)r`R)oJHy-+ebRsy|2*@UZ^JGY z&0AH<9B0O|AF1ZCIarnAK#5sxv&1ad6l(KTsY}drq&vpt4eVY~f9k z%=zTMl3kgiwMUhR=FG?~nqK!^)nY`IhB5PuhAq*c3@-OzQUf2{po?1o3o}xQ zLVqdO*Fv!sf?Z-sfJyri!SfBQ4mXhc73v)&l{tmgcM?x9+{j{J0Y};rDz=?|jo=S? zID_8X#-gV}Bj6{N!HxA!N+aX{P95+lyQDApc=V`l_%R-bvPPWd`vKo~>vRNVITL%i z+5J_Q#$iw`SG#?Hg$BNpC5=V^-aglHv?CJgj;b2q5C6VoY-E1D>_@EfEo@Ixz@YOj zZvYBlSJQdmUNgn7G3Kr{dtWd5;IM;WLTzRiH3)H|9@N%ZH31wJDL(g*a&?+gnPD%j zPuUeE+LNmfMa`-WV(+h*9Q8Vpq-mV|y{IHHf+F-9Z61idfCk5r*(QcAT3l@JZ!5EE z*l3B7ON05F3PR6>Sd{ALm+dHuS$N~2-QS58b0a|$~>Q@t!A(pN{tO#PaeD^pol7>>M!w{eaSi!UN5VMCY!K!Pc^o2^s8vJjI=S2-K50VfTY z`F(u>pc%tS@n9}INn@1KG*s?7k}#ah>#<4E&M5~O=5smpvo2zIZCK%kFL$yG`T*5h zpG{Wm*fNofMjO{vcKz^aGE;P@T$H0xE#4TwcOd81_ui&K3-V&+d3&%W3H3#^z%>&la0t4 zEpxmvwRvhXo#TQI8O73!?UKrkEdWoyY)pFwoMCmvqzx5^T;d6H(Id}8ioxHc2t+Gg zM4dwK{{kkEY2()rQ+b$nAh%qu@sEuHn@M@(2%>nF^QLQtnMZF*>!O~YsNZ#wUzJqS zSq2ZC^{^h)%g8yWN7Mc$&69GlR$@bhCupQ^K)B_wF#Tc%MW@4RkCcVDG6L|$i-*5{ zr9~RQk$swH@Oy(|Q~0!n7@uPeLgVDtZ+?O=d|ErMm%^w{Un(B9AuEgfoX_Znvz=N&OA0^*Vi~$8oU(mAfh0j*F~24<R%--nGX-W@_~_yu9Cizi-AT0v z;fC`m*O?_*LC`~1T;y2HkKnY%VCV1Z1LzBsXhgX$|EvF{1|};|`Ge@8A4LCu)!Pm` zIZ?6memhwThu#EvF}3`b>|Y`39w%yaar6QraB&((+|gt*4*DM#85hb}#T*lj=c<}d zY{i(VURXRdcrp!|94%FOq^X9ma=&|c=pI}4W^F3nhS^veo-*SScpdvx@O(XtVu#c8 z-*dt#6wxJL>yD00f>Q*&_umPp=98`6yl{y3{WnIhw=kk+%N5Fv(r0T{>{X>+BUSKs za4C2poHTk`3r~Pt?xzU^%wC=K1A^fe_YIC=n~<(r>GrTcbgn&_r~0b$ zU#&JtmpbF!h~A zBo{Br;u;<^9N*DZCKY6{j&)^aT7PJt?SN zkA_#*&bEN2?Gg`{T016&q=MNJ3Bm;=h$BDHij*9$yHMl;VjQ4B>_(YTsKu-WN{@cG zCv;+e7tB4yFYP()=q5Tfj$pD$<48a2=y`0NSz{rbxyGz;vPtIRUHmCcFT#{7^)?}yN94Lhu@wCXV z-}B7kkz6&bWG+SeF>C*;>6JmgJJt0A(#ju@a{edbZI6!p|GaZ|*ddb7xg^2AN6HQ3 znmD-QK;RE8L^H~Ofq;rYfq=OF=U@GQ55DmVgTnaZH3{$q1H%`NJd0QTe7hAK2#EDR z$Apd{l0W&807nzfDLP+f!us&;(~IyL(TDQ(IWIEOhpGcbns0) zY-nLru*~TL_Itc_d$r-daL@!RSdEh#AEa%3SF6=604}%BzaXNDbCFwr%BBndb={&2 zs`YNwZK-HkD$xor8)IpC_*-S8ZB zWH7qX0Ga{x$4?QO-Na{B?XwBdA;%5jkZ_E%YM!0}=Igjei`7Wx#K%}JmQkjs2d$T4 z%C&rgvU{l?++FhxPX6?3(Do-CwBbyf;Y_3=aC$-`LKq<;d~8gCaLkOUaCAnA#)p8- zGTvHEcM;HE^=7*~BUo76hW#1gqi`jzw-#d`fI-8pO^=J0l(RA0LSMwQ+7t2jN2+6E zydKvB`tSmTWcuzh+F4xq(K?hZ1qAz2jp?O@TL&>Fg;_>a6-MiHbox?uYWtAi zF*1K4tf6%vr$ou7&iuPhW!@2adz*Rkm#=lV<@PJdr7^)n1pl9dqz4YQ38 zTJ5)b>6P?BnBUb%5K>TFiN^$rS2@XLK{9##s%`*}8x*S|#&MVkkJLv<=9V&3X%DO5uuwa5kUS-|Kt<6JHkbgBIPyco zdBoQXR$whKq)AR2Vg11xRM@U9Y9WsJWf<7Cg>=?tON*==1aaM*c&h;r3uE z5y5~7@BIT?wW;x=#BlEp`IV*m-vvVndTsi=KmM1yFnx%Y{YzaqQTC0Nyw-TY6Ww>m znkyBn-aXF1I(jet0aryhq{p9xb#4Uv*_w#nOAgxY`Gyob{sbL+8E7sQgHc2gO0kW>^b-_ZC{8v#@S}5-mx(@Wg*h zCK>0SigV=7bZyuKVzc26f6eMxwSIe+g%}4KRKPHVl~^T^B-4>*XY>F8BoRiDYNRs{ zVHOT?@qrwSLg|w4h9U$-3;62Q`63E?gGzhDD($8|acaufRZok~u~E8n`IE1xQEc8p zmoP6tqDTso?P&_d;zrK^O~847h!jaC+2!s94m;ve2>+lciif80%A1NTbcJmokJE1w z|3d8`kKJQfo+63xJ*+qkQlN~Je?o`&SMB2yGlKnVRGYk8go9o81I#`?;N;ZyTRd4U zLPTdI**THDkq;w9pV6umwEZyukH6e}Z!jdXKtx1h?udM&Y09-EG4SA_yp&hxuTtvY zkqy`XMX8Z|fI3)mov0vS$8kXk?Ms0g4c0YqV~HCbnG*|lxd%Iz0!3bK%p!PwaGPPS zp5bU^(?jB$($H^y2=W`~o9dv0K6{HuIIH;4`y5VYCeOt~phl>XN! z$GMk@@u)~hg72O*qmT3$Th=I86K<^DfX!_3)!wVwZY840u4^e^0XBR<5MyHTmd#qC z%s`5&8QHd&`Ig*`=75%>7Z#J3=Wd zk`XkW6dm6`wp$2g1-FOwR+_6f!L*E!S}~q?8dYQ)mXQd%U_|E#F1{XR3@tm1q9Er* z(=C6>nx*V=-`N7tt}RNO5E0ak^zO6GCwonuKs|=b-B>TXW=(hOy)rLp?-w9b{*9Pr z^c>>K?zZFew!~?{WX~^;jBy86bxUJ+)uxM~BYsg}XPjT(Hf6{6x9<`UerD5Hj7uxv zGW75MUM-t!e6VFkq?K1?-}X5PMAJl{2EtpT(J6YMQwS*_g1%w;>MQUz4j+_5(3MA; z9Bqw}0;shra9llzJF8QD+%Mww5ocOQt|?InC2OrKj2#KJ_CP_-4>LQ5 zaYA%)_BdsA3aZ1Z4NrGTDG84I#OQd}OIUXtA2o)sAC;}|F!wfcPUA}z)W$X%NZMxBT zJ%m3Hp4bj(bTr^|J9~cW6g%oe$y3o&-Cf;%d39N_4&V0)DNq}5r$)eY+hFsh$=$^Rqp!63jbZUr}+8;FR)s00E_SaqB3ZVPkMXehu1&vcQMMmjJFz! zrWx}>E;))dzC2W9+U@nZuiD4H{DLl?7q4IVPHs4jRf%0-A@OF8=AH=B7rRodH0tIz zkZT@GVd|c;i`oZ3Ye;vl#IEC_D5v-hmQ#F~SDh6lqZo6Y;>X9BytezZ;LCkUs)3^H zJcCx1Ewgf*4gcP}GhT;VUU_D&SZvh9M_9&vsUj7Jda+n<)P?-UKJzdg#z&lHStix6 za+!fu-L;dU=@5=Rt7bgMuR0BUot zu8~X;q)Zr<(O|x3#OE*qexTt=E;28rN`evH%ouZZ3NsQMWhIyF9y~r7?A#=P!by6o zMB)~eDNhEVs_$5Qoxzmj5^Us0*}`tXTm>_AW?e~vqL7ncaUFG4tZx-&`fL6MBCIS* zMR2n6WTRibrBg`nZV%0BF+0L;jS<^oF#|KaA60r~zho=Pv>*d4JKbtEHI=n$W;y}v z&KttaYPusI{1F>9y~(tt8_Zm_T3uzh)!x!jYdrkphIRk9Qlqs&1yy|xXMj?Dr4Tx> z%-poKsoq18@mnMDHCS0$cfEvP8oOwr95-0Mc-$7IMKU<*3X5JZv7__P7dC>#-zt0H zdrfiE%jL@kBiprV2k3}O{0)sTlG2)s5AhUk9xMb&PmWNJ%$oQvu!%S36~7U0XY(mG zbbMyOztuY>zIJ-Mg{WTe0x7BnsRUh>3D*a@nAR*Az}3=Pk7+ixZW$DKSXCi?|IM2b zU2y{pNu)HbM@z=| z+&W2yZjyxh?7d1fq9gC1%GzzU(Nlti0xlZhBxRqKv?kV`K#o6zC@YrjND1?ioNUgn zaB&>h{b>fC2HJE>&KS+joc7veggNcBGJPVdX!73ci%3_HD2dTn#F>h8C4X2aBB}ia*;tjE&SX^5b18h%; zyf+YOA#}24RlOWb?mCjEKH)w*#qkd+i51*>q6TI-wYOtqnxJrqyx)nF^D!$?OzzXb z_*pzNfqObjLvQ{nG+JB}KGUh2$U_Ujl}o)}efYyC7F6;_-NtXB{#Wt44E;-Xf}Ij~ z&2%9OLL58OaGW2WM|rFdJ$nOXH%7f@2TvGMqy_#2+8+C^5+r!jjSv5OKDr24VA@l&_=XTRB7N?A$?q zX>-f%t^dLj?WKG+%TNJe#{6vEVPPesiH7eE0Wg`h=`jWp`yLvI_A)+Ox#S0N9zlk0 z<`3tA*oqP;?Hy+l=)YXkCvhEhXlSpEv=aA<^jwO%w3`fBqW~H%I!+yc2T|F!d z=cD;$eaD)Lpxj?-EJGJBF~C1eKQBds6|FR18*dbPJS0LtOpnjkfDx{hb6fG$*jd9` z*~?;dIk!-! z6peEi6hDZ$Ywd!m|E~Nu+9jCX(ddt5J~4;bR6v+rrrU*%uo7&pKy`HQjD1W#E5e`7 z6MQS-syXmh+wU`p+7J*+Pwh^t1M30i+gg$CM3?B7f}Yx*5`w$z`?Y^%#FZzWzz2=8 zgy=G7=+Fxo*=Q>f%{4XX_SM~tS}siTSw-;(g*jnE<><_~N$1nm@3W0{<4{#-?RA{O z8{y^ohZ_7tYFS-NA%8`a&zGH7y0S}kcTGzQj4C$f{kD4Ub2q30YJEK3f;GZXIQ7i) ze?t{v0Z6iZKGNDN1sb>H>hrLb4BKoA>MNWkFgbqI-Y5iGxwF6zt72vxX#%4l@k}<; zum#38ec?%KhlUf3wT|vgY`)6|E6>&Ngui7>{Qs8ILC`H(!xd~ONt%R6z5i+33OHzB zA^^Y}nfTps5`3(G%}5!(cZJ=py0C7ez>*6FxK~hq>0u^EoPq6lG>wWJCW6Mm3m?JN zMRNi=w;cWL>#aUE1A0E;2S$JPPCsde21U5OK_dc>of+a#bdp~Q(RptSY~98m4ksS* zZ3hm*$)BwAUE7{zVK>$8j-syAG%`6zs^~1|-3s%8>oWgS<|VSimhGV!D8sg9X7w{` z;#`xv*C*p7JBpJ@F8x{;9d3jpn~ zj(HF4cZd88vB&^LJlbbdAgud05qoo4? zAJ~yd2I5?f5Y+BWHbi_rzm9V9p%=|-sYxHoSqZpryWOZ-$Mk8CQ}!U2M%_f!hLL3Cu5 zkJL?|y#iBX1zjW5+5(o6vb^0#W3|h4GSda!m5qetXlgoID={wOdfPED%Zk;2N63$! z^3Aw`KtXE;^?rGq&dPb+WX+T^J&jMI;{}>86%X{)^Gp(V$>KZ|?PV|fybIp1eF3^s zhNRlsre4Iwhy_{Xvz5eYyG>6!3v)(=x;01f$mlXk<^Cr=IU^J~an$pA1X^c-jYlXG z(AEQxhu_$mCZvl-sHXO;1S1##zBt(1)wO8D1CnmpiRXIw{37ttc^Xoq39sgHYO8b; zHz{hKBRRWticoV@4=KvRg)oK=5X?#W$Z>naA6qCMf2{IKj>I&aZ)zuC%?-yhI~ej7 z$t}v1IY2C)&!%Ns=h1bC&r&T~llqL<#qady&3e6TZIYYt{80PiV63W#i!C;j5 z_`LnyGs@m&qr~g1H*C zuU0m+1w7VJ+FBB`gh*bheFaQpO=ga~2Jy)BR@YHOA3-%OF4T8$s!xgWXZt*z#vrY{ z0acLCJ<4PG{fcQb!@+j0Unku`C%uW5r4PCC)072s+|&0jtFmwpRQ#%1o!F4{bdRj4 zZ#Q)G3V8+mi?i77;i`MwGfEHEr%N|E;V0`bTesk)_{vT1h^8c&2z%fgKm&5mX+rPGa`!clEUXVjd-XoZfLPP8thI4+@e zopo7SAvvV;^lE%w`{()no_&A6_t`%0`~LB}JdfcqC7UmM@p^MCCdu|j*v03E9 zkB;Y$?<~6=b7W7p^O5qV4xbWoX3Kq-^464fI-#}IYrC>#tf_X7{m4|w6_ed(1YWNr zj&i$80eP=;TxVicvuRaRG?_7)rc_Vl%Vc@3_qVzx2~sl{L_bD0Qf?s`D7LP!D%KJE z(i0cZ2hP4qdZwV3n~K|4v-4RAg*ng77jRtrsI{@OmB$}Fw4ai&_NJhNlqT1=)3x2} zl*!3IeA@bNCt*_^s*W|OT;`L0bMx`j+>|3{wV&0J1gBLwLGmC@x2dm_=#4yjZWP4-dC8@Oxo;XHvvDhQZSDb6tEXv(= zt5D??N~nx{o1`62iVpnamG`F%Y2|QP%!JB|1}+VWp7M5nbWmf0maSB=a3tWaBq1e2 zS~)|0&2PZAWOT%Uzy1p4^U6o;oKUXt;Im~{bJG4yw!Xi~_x1;C`l%CdPrakp6mSK% z28SoJGPac@g}WjT_9FS$hWvV%E%u|nzqF)swmswoJ7w=?OOw3a)uvVL=5k9D z$(m7j_YYHd{~pkoMrJcD^m4|PL7!$?^4jaQ zrpn;5oCwk2LU!^_S?hJ14D+J!L;fDzG!f$t$G|(-(ZQn7Xn3H1SYH`_Ib5vgU*__m z@vrL@c_s9wx+rD+jxPb9Pfv^UAFBK(|D$wE!YQWee)T88zcV9KN|DLhbk5a$5--AJ zNm&4M7jt;-{w0Jsb%^ND%E22{8`%c4yw440AGHFf?Or)OfGOG_i`YyO#E>MJORowZ zdenPV+|F&cVM@V>&5-+?{PO%8X;PU)nm1yol6uvcH!*6y4j7saz03ycUOObz0<>j0fP_{e2vboIe=6Xq7|42SY+3#jVctq*f#MF>!g(Uw zj)NpnD<=ZeJ_@4aicPKUGeN(d;Q&KwW;nZ{uh19K6d>xGh5oqlvW6A%QkP-g#z4=) znLy_a5ykC-t0CbiqtDS#nVOL(_A;J~PianKCKS_+`I_-U}H z1qU%sVvxGsihz|DgSj1sNNEn7^a0!sB8n^h#94-)!7S@LtO;1n3>bx$Ck5D~Yo`^8 zD?7kho+tnnE(?ID(-QqL?W^I0yqxn8a>dqwOY>?7I0|{^i$EjY4M;nQ1T4u51PVi> z;3DRJEVrvr7!j~MS=MVqgnwy#-V(*K67WyE0iR`ioX7Ml*bjKQeEOJI6c?bzfo;VY zXt!bx2I2zLIMDbS1kFIK(hiBQ20bD3L7kF@9BzQ386bBpMlL)CfnDLqfhPcVSQ)MH VBfu2+*qg&~f-ihLS3eum{s(|${^$Sz diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f42e62f..8b580b9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..65dcd68 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -205,6 +209,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From 18e36dae7d4ad886d3e5c73a8214c89851d981bb Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:16:06 +0200 Subject: [PATCH 10/15] fix: stuff gradle 8.8 broke --- build.gradle | 30 ++++---- .../flapdoodle/adapters/VersionFactory.groovy | 68 ++++++------------- 2 files changed, 34 insertions(+), 64 deletions(-) diff --git a/build.gradle b/build.gradle index 8d954ef..7c45185 100644 --- a/build.gradle +++ b/build.gradle @@ -19,15 +19,17 @@ plugins { group = 'com.sourcemuse.gradle.plugin' version = '2.1.0-SNAPSHOT' -sourceCompatibility = 11 -targetCompatibility = 11 +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} repositories { mavenCentral() } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.12.6' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.13.1' // Using 4.7 for maximal compatibility back to mongo 2.6 see https://www.mongodb.com/docs/drivers/java/sync/current/compatibility/ // On Ubuntu 22.04 some tests with mongo versions before 3.6 require libssl1.0.0 // you can get it from https://old-releases.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu13_amd64.deb @@ -40,14 +42,15 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' } -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from 'build/docs/javadoc' +tasks.register("javadocJar", Jar) { + dependsOn javadoc + archiveClassifier = 'javadoc' + from 'build/docs/javadoc' } -task sourcesJar(type: Jar) { - classifier = 'sources' - from sourceSets.main.allSource +tasks.register("sourcesJar", Jar) { + archiveClassifier = 'sources' + from sourceSets.main.allSource } artifacts { @@ -107,18 +110,15 @@ signing { sign publishing.publications.mavenJava } -pluginBundle { - website = 'https://github.com/sourcemuse/GradleMongoPlugin' - vcsUrl = 'https://github.com/sourcemuse/GradleMongoPlugin' - tags = ['mongo', 'mongodb'] -} - gradlePlugin { + website = 'https://github.com/sourcemuse/GradleMongoPlugin' + vcsUrl = 'https://github.com/sourcemuse/GradleMongoPlugin' plugins { mongoPlugin { id = 'com.sourcemuse.mongo' displayName = 'Gradle Mongo plugin' description = 'Gradle plugin for running a managed instance of Mongo.' + tags = ['mongo', 'mongodb'] implementationClass = 'com.sourcemuse.gradle.plugin.flapdoodle.gradle.GradleMongoPlugin' } } diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/VersionFactory.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/VersionFactory.groovy index 27cae1f..9f11617 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/VersionFactory.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/adapters/VersionFactory.groovy @@ -1,69 +1,39 @@ package com.sourcemuse.gradle.plugin.flapdoodle.adapters -import static de.flapdoodle.embed.mongo.distribution.Version.Main.DEVELOPMENT -import static de.flapdoodle.embed.mongo.distribution.Version.Main.PRODUCTION - import com.sourcemuse.gradle.plugin.GradleMongoPluginExtension import de.flapdoodle.embed.mongo.distribution.IFeatureAwareVersion -import de.flapdoodle.embed.process.distribution.Version.GenericVersion -import de.flapdoodle.embed.mongo.packageresolver.Feature import de.flapdoodle.embed.mongo.distribution.Version import de.flapdoodle.embed.mongo.distribution.Versions -import de.flapdoodle.embed.mongo.distribution.Versions.GenericFeatureAwareVersion +import de.flapdoodle.embed.process.distribution.ImmutableGenericVersion +import static de.flapdoodle.embed.mongo.distribution.Version.Main.DEVELOPMENT +import static de.flapdoodle.embed.mongo.distribution.Version.Main.PRODUCTION class VersionFactory { - static final String LATEST_VERSION = '-LATEST' + static final String LATEST_VERSION = '-LATEST' - IFeatureAwareVersion getVersion(GradleMongoPluginExtension pluginExtension) { + static IFeatureAwareVersion getVersion(GradleMongoPluginExtension pluginExtension) { def suppliedVersion = pluginExtension.mongoVersion - if (versionIsDevOrProd(suppliedVersion)) { - return suppliedVersion as Version.Main + if (suppliedVersion == "DEVELOPMENT") { + return DEVELOPMENT + } else if (suppliedVersion == "PRODUCTION") { + return PRODUCTION + } else if (suppliedVersion == "latest") { + return Version.LATEST_NIGHTLY } - return parseVersionNumber(suppliedVersion) - } - - private static boolean versionIsDevOrProd(String suppliedVersion) { - try { - (suppliedVersion as Version.Main) in [DEVELOPMENT, PRODUCTION] - } catch (ignored) {} - } - - private static IFeatureAwareVersion parseVersionNumber(String suppliedVersion) { - String mongoVersion = convertToFlapdoodleVersion(suppliedVersion) - - if (mongoVersion.endsWith(LATEST_VERSION)) { - mongoVersion = mongoVersion.substring(0, mongoVersion.length() - LATEST_VERSION.length()) - - if (versionMatchesMainBranchVersion(mongoVersion)) { - return mongoVersion as Version.Main + if (suppliedVersion.endsWith(LATEST_VERSION)) { + def mainVersion = "V" + suppliedVersion.substring(0, suppliedVersion.length() - LATEST_VERSION.length()).replace(".", "_") + for (def v in Version.Main.values()) { + if (v.name() == mainVersion) { + return v } - } else if (versionMatchesSpecificVersion(mongoVersion)) { - return mongoVersion as Version - } else { - // we'll just assume that the version is newer and supports all features - return new GenericFeatureAwareVersion(GenericVersion.of(suppliedVersion)) + } } - } - - private static boolean versionMatchesMainBranchVersion(String mongoVersion) { - try { - mongoVersion in Version.Main.values().collect { it.toString() } - } catch (ignored) {} - } - - private static String convertToFlapdoodleVersion(String suppliedVersion) { - def mongoVersion = 'V' + suppliedVersion - mongoVersion = mongoVersion.replace('.', '_') - mongoVersion - } - private static Version versionMatchesSpecificVersion(String mongoVersion) { - try { - mongoVersion as Version - } catch (ignored) {} + // for some reason with gradle 8.8 and jdk 17 groovy is unable to use the static interface method Version.of + return new Versions.GenericFeatureAwareVersion(new ImmutableGenericVersion(suppliedVersion)) } } From 0b0a4d201c04c85fbec597ee9c12152df461db22 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:22:43 +0200 Subject: [PATCH 11/15] chore: update flapdoodle embed mongo --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7c45185..de1503b 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ repositories { } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.13.1' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.14.0' // Using 4.7 for maximal compatibility back to mongo 2.6 see https://www.mongodb.com/docs/drivers/java/sync/current/compatibility/ // On Ubuntu 22.04 some tests with mongo versions before 3.6 require libssl1.0.0 // you can get it from https://old-releases.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu13_amd64.deb From 09ceba26443852fec6d47906b7d94bf0cd52200f Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Fri, 30 Aug 2024 14:13:26 +0200 Subject: [PATCH 12/15] chore: update flapdoodle embed mongo --- build.gradle | 2 +- .../gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index de1503b..589eabf 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ repositories { } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.14.0' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.17.0' // Using 4.7 for maximal compatibility back to mongo 2.6 see https://www.mongodb.com/docs/drivers/java/sync/current/compatibility/ // On Ubuntu 22.04 some tests with mongo versions before 3.6 require libssl1.0.0 // you can get it from https://old-releases.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu13_amd64.deb diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy index 3f5f9f6..ee18c5f 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy @@ -16,10 +16,10 @@ import de.flapdoodle.embed.mongo.types.DatabaseDir import de.flapdoodle.embed.mongo.types.DistributionBaseUrl import de.flapdoodle.embed.process.config.DownloadConfig import de.flapdoodle.embed.process.io.directories.PersistentDir -import de.flapdoodle.embed.process.net.HttpProxyFactory import de.flapdoodle.embed.process.runtime.Network import de.flapdoodle.embed.process.transitions.DownloadPackage import de.flapdoodle.embed.process.types.ProcessConfig +import de.flapdoodle.net.ProxyFactory import de.flapdoodle.reverse.Transition import de.flapdoodle.reverse.transitions.Start import org.bson.Document @@ -161,7 +161,7 @@ class GradleMongoPlugin implements Plugin { DownloadPackage.withDefaults() .withDownloadConfig( DownloadConfig.defaults() - .withProxyFactory(new HttpProxyFactory(pluginExtension.proxyHost, pluginExtension.proxyPort)) + .withProxyFactory(ProxyFactory.of(pluginExtension.proxyHost, pluginExtension.proxyPort)) ) ) } From 104fca037503c5b5f1bc9ac949881e1ed65a1ed1 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Fri, 30 Aug 2024 15:07:11 +0200 Subject: [PATCH 13/15] fix: cleanup temp mongo dirs --- .../gradle/GradleMongoPlugin.groovy | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy index ee18c5f..a83f3b3 100644 --- a/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy +++ b/src/main/groovy/com/sourcemuse/gradle/plugin/flapdoodle/gradle/GradleMongoPlugin.groovy @@ -32,6 +32,7 @@ import org.gradle.api.initialization.Settings import org.gradle.api.invocation.Gradle import org.gradle.api.tasks.TaskState +import java.nio.file.Files import java.nio.file.Path import java.time.Instant import java.util.concurrent.atomic.AtomicInteger @@ -62,6 +63,7 @@ class GradleMongoPlugin implements Plugin { private static void configureTaskProperties(Project project) { project.extensions.create(PLUGIN_EXTENSION_NAME, GradleMongoPluginExtension) project.getRootProject().extensions.extraProperties.set("mongoPortToProcessMap", new HashMap()) + project.getRootProject().extensions.extraProperties.set("mongoPortToTempStorage", new HashMap()) } private static void addStartManagedMongoDbTask(Project project) { @@ -135,12 +137,18 @@ class GradleMongoPlugin implements Plugin { .initializedWith(ProcessConfig.defaults().withDaemonProcess(manageProcessInstruction == STOP_MONGO_PROCESS_WHEN_BUILD_PROCESS_STOPS)) ) - if (pluginExtension.storageLocation) { - builder.databaseDir( - Start.to(DatabaseDir.class) - .initializedWith(DatabaseDir.of(Path.of(pluginExtension.storageLocation))) - ) + Path storageLocation + if (pluginExtension.storageLocation == GradleMongoPluginExtension.EPHEMERAL_TEMPORARY_FOLDER) { + storageLocation = Files.createTempDirectory("$PLUGIN_EXTENSION_NAME-") + storageLocation.toFile().deleteOnExit() + project.rootProject.mongoPortToTempStorage.put(pluginExtension.port, storageLocation) + } else { + storageLocation = Path.of(pluginExtension.storageLocation) } + builder.databaseDir( + Start.to(DatabaseDir.class) + .initializedWith(DatabaseDir.of(storageLocation)) + ) if (pluginExtension.artifactStorePath) { builder.persistentBaseDir( @@ -290,10 +298,11 @@ class GradleMongoPlugin implements Plugin { private static void stopMongoDb(Project project) { def port = project."$PLUGIN_EXTENSION_NAME".port as Integer def proc = project.rootProject.mongoPortToProcessMap.remove(port) as RunningMongodProcess - stopMongoDb(port, proc) + def tempStorage = project.rootProject.mongoPortToTempStorage.remove(port) as Path + stopMongoDb(port, proc, tempStorage) } - private static void stopMongoDb(int port, RunningMongodProcess proc) { + private static void stopMongoDb(int port, RunningMongodProcess proc, Path tempStorage) { println "Shutting-down Mongod on port ${port}." def force = (proc == null) @@ -306,6 +315,10 @@ class GradleMongoPlugin implements Plugin { if (force && !de.flapdoodle.embed.mongo.runtime.Mongod.sendShutdown(InetAddress.getLoopbackAddress(), port)) { println "Could not shut down mongo, is access control enabled?" } + + if (tempStorage != null) { + tempStorage.deleteDir() + } } private static void extendAllTasksWithMongoOptions(Project project) { @@ -356,7 +369,7 @@ class GradleMongoPlugin implements Plugin { synchronized (rootProject) { def mongoDependencyCount = rootProject.mongoTaskDependenciesCountByPort.get(port).decrementAndGet() if (mongoDependencyCount == 0 && rootProject.mongoInstancesStartedDuringBuild.get(port)) { - stopMongoDb(port, rootProject.mongoPortToProcessMap.remove(port)) + stopMongoDb(port, rootProject.mongoPortToProcessMap.remove(port), rootProject.mongoPortToTempStorage.remove(port)) } } } From 0daaaa80b1b934caf75ab69e81382aafccb20776 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Fri, 30 Aug 2024 15:20:25 +0200 Subject: [PATCH 14/15] build: dummy to trigger jitpack --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 589eabf..eac6711 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ plugins { } group = 'com.sourcemuse.gradle.plugin' -version = '2.1.0-SNAPSHOT' +version = '2.1.1-SNAPSHOT' java { sourceCompatibility = JavaVersion.VERSION_11 From 2ab47272fd72a49033404bbdbe73343f4a225b12 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:50:40 +0200 Subject: [PATCH 15/15] chore: update flapdoodle embed mongo --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index eac6711..260e6bb 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ plugins { } group = 'com.sourcemuse.gradle.plugin' -version = '2.1.1-SNAPSHOT' +version = '2.1.2-SNAPSHOT' java { sourceCompatibility = JavaVersion.VERSION_11 @@ -29,7 +29,7 @@ repositories { } dependencies { - implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.17.0' + implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.21.0' // Using 4.7 for maximal compatibility back to mongo 2.6 see https://www.mongodb.com/docs/drivers/java/sync/current/compatibility/ // On Ubuntu 22.04 some tests with mongo versions before 3.6 require libssl1.0.0 // you can get it from https://old-releases.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu13_amd64.deb