From 53b83cec1e9e3570a36e975bcb0c959a8b30abfd Mon Sep 17 00:00:00 2001 From: Emanuel Rabina Date: Tue, 9 Apr 2024 11:12:06 +1200 Subject: [PATCH] Test to capture adding a unit to a scene --- build.gradle | 2 + .../engine/graphics/ShaderConfig.groovy | 1 + .../redhorizon/explorer/UnitTests.groovy | 75 ++++++++++++++++++ .../net/ultraq/redhorizon/explorer/harv.shp | Bin 0 -> 40297 bytes .../redhorizon/explorer/ra-temperate.pal | Bin 0 -> 768 bytes 5 files changed, 78 insertions(+) create mode 100644 redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/UnitTests.groovy create mode 100644 redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/harv.shp create mode 100644 redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/ra-temperate.pal diff --git a/build.gradle b/build.gradle index 49940c55..0c44f2cf 100644 --- a/build.gradle +++ b/build.gradle @@ -59,6 +59,8 @@ subprojects { implementation "org.slf4j:slf4j-api:${slf4jVersion}" testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' + testImplementation 'net.bytebuddy:byte-buddy:1.14.13' + testImplementation 'org.objenesis:objenesis:3.3' } java { diff --git a/redhorizon-engine/source/nz/net/ultraq/redhorizon/engine/graphics/ShaderConfig.groovy b/redhorizon-engine/source/nz/net/ultraq/redhorizon/engine/graphics/ShaderConfig.groovy index f0839e3d..15fdabb1 100644 --- a/redhorizon-engine/source/nz/net/ultraq/redhorizon/engine/graphics/ShaderConfig.groovy +++ b/redhorizon-engine/source/nz/net/ultraq/redhorizon/engine/graphics/ShaderConfig.groovy @@ -36,6 +36,7 @@ class ShaderConfig { ShaderConfig(String name, String vertexShaderResourcePath, String fragmentShaderResourcePath, List attributes, Uniform... uniforms) { this.name = name + // TODO: I think these need to use closeable methods as getText() won't be doing that for us right? this.vertexShaderSource = getResourceAsStream(vertexShaderResourcePath).text this.fragmentShaderSource = getResourceAsStream(fragmentShaderResourcePath).text this.attributes = attributes diff --git a/redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/UnitTests.groovy b/redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/UnitTests.groovy new file mode 100644 index 00000000..cdeb44c0 --- /dev/null +++ b/redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/UnitTests.groovy @@ -0,0 +1,75 @@ +/* + * Copyright 2024, Emanuel Rabina (http://www.ultraq.net.nz/) + * + * 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 + * + * http://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. + */ + +package nz.net.ultraq.redhorizon.explorer + +import nz.net.ultraq.redhorizon.classic.filetypes.PalFile +import nz.net.ultraq.redhorizon.classic.filetypes.ShpFile +import nz.net.ultraq.redhorizon.classic.units.Unit +import nz.net.ultraq.redhorizon.classic.units.UnitData +import nz.net.ultraq.redhorizon.engine.graphics.GraphicsRequests +import nz.net.ultraq.redhorizon.engine.graphics.GraphicsRequests.SpriteSheetRequest +import nz.net.ultraq.redhorizon.engine.graphics.SpriteSheet +import nz.net.ultraq.redhorizon.engine.scenegraph.Scene + +import org.joml.primitives.Rectanglef +import spock.lang.Specification + +import groovy.json.JsonSlurper +import java.util.concurrent.Future + +/** + * Tests for the Unit class. + * + * @author Emanuel Rabina + */ +class UnitTests extends Specification { + + def "Can attach a unit to a scene"() { + given: + // Epic scene mocking 😅 + var scene = new Scene().tap { + it.graphicsRequestHandler = Mock(GraphicsRequests) { + requestCreateOrGet(_) >> { args -> + return args[0].class == SpriteSheetRequest ? + Mock(Future) { + get() >> Mock(SpriteSheet) { + getAt(0) >> new Rectanglef(0, 0, 1, 1) + } + } : + Mock(Future) { + get() >> null + } + } + } + } + // TODO: Definitely need a resource loader extension + var spriteFile = getResourceAsStream("nz/net/ultraq/redhorizon/explorer/harv.shp").withBufferedStream { stream -> + return new ShpFile(stream) + } + var palette = getResourceAsStream("nz/net/ultraq/redhorizon/explorer/ra-temperate.pal").withBufferedStream { stream -> + return new PalFile(stream) + } + var unitData = getResourceAsStream('nz/net/ultraq/redhorizon/classic/units/data/harv.json').withBufferedReader { reader -> + return new JsonSlurper().parseText(reader.text) as UnitData + } + when: + var unit = new Unit(spriteFile, palette, unitData) + scene << unit + then: + notThrown(Exception) + } +} diff --git a/redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/harv.shp b/redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/harv.shp new file mode 100644 index 0000000000000000000000000000000000000000..368a8a890b535e8369016013e96a2a2d06bbec05 GIT binary patch literal 40297 zcmdSB2bdgZnJ)TQ>XEGJR!QW;f?INu6=r%QIq_Sg>RdrRzk!5+kuq?te zJ)IU%<=vi!F9p+n9_-lC3;Z!9m7>1>0ckC5iLav~`wcFVA!L-gBOF zuVv})>R9#H`+wp6-tYeqSw)6P27hL0LT+NnHiG|t#`eZNiQf3-MZNLldA)HU*&DB4 z+8du*)*G*QWpBLb)xFVrZEyVLf9s9iH}u9e>E1ZKvNsAB^~U=y>5V%s?Tt^Z>5YYf z-q<(P8^5ukH*UVXH$Hb|Zxr6#8^yQu#?SuQ%dfw!H)h}28*lsb-gw~My>Z`P_D27& zdgGbDCd2XL=)EMpf{=G#{=VMv+4qt31voBbd*fHLz2`?pdgIJU@AH&EhU3TId3l@` zd&iGSB)um7zCv&OXrcG~t#WTHE4|OlB{Cd8en+`CRx7=+TP5iY`26h4i*OK&`aa??P+;wg5`HSA)8~^G9z0beqgJd{< zy#M9#!M`Wzx8rkrKGb{u{121#J8`_}!@c9bxvn>^80&rhP@N3NkAFEq(tm;XrJKFu z{VkGy501}o_r?#jd(R)}^u|a3q4)Wpe3T5wkN16yq(|`nZ*A)x|5zpIJdWR~^~UX5 z@A+Hw-uOYI_xYPFG8{k7+r3e7dgE0tNtf{Xe|&lTjoW*k>-NU`y1mce5s=~d@n44| zy$SFCYScUa(hic|jN`|5_TKlp8_96|_^O*o`Wig{$(wuQ@>_b(KlyQz{#!i%r=RGJ zyIvkMpX?nU{$%fcf4eJQb^rdKO3tpNiE3x5Gry(O)G(!*kFKG0-L$e9Bju!wQ#D%6 zk5XnXH!?DEVh3%B`Mg}N@RVDwl*?r~Cl%(uO}pY>E~!GilQ(K$$%Dy zd`4wYtz^i69<|#fp@qeh?_~^OL@1IBzk$D8FXg3~ZH!@$n+_S(!hU`Y*`Nj_qZOR# zOKICNwJ|rZWY+ONaH4YFbuH65c7`##-L4;GpG)6hm-AlW``zRJ$fzu#$absW_QX3`{Bk=C_zjwpoBI&EVx=YrL?5O|=Hzx-D@gmEXHOku)#CCiM=7=RyDIq| zt5$xOCsj_XRku=Ft^7#DX`Rm7x9Xiv_4GG6{Kz`Bf5qq3e)_d@pJOwW*598QBt!gp zr?QFRby@1{`!J%4dEuJNqr#7jvRDp6`TV&<^mcqB#33eM4bHugD{LjB|rBd?dL}djwppu(2m;a%k^5mFn>PdN{XBhqjnULL9)q;B*Av-vpL3) zg>wu#}s6JF5X_@3B}{$V(x49$*MUO4kHw`W}YQn4Tcz+tk+# zzuAz|)ZE7yix9W2GaqJ$cK}FhsC)EIyS?npspmP1ZFj<`waho! zPJe&@$(0F%kT4<_Z>3J<5?U)7u066Xan)a>w zrYUnw6!X%_^|bDE&GcGlY+RI!6(u*joxV}GJwF+^V`I3DrD~_s4gx7Z^G({6pWpTB`KNjvgnl2L2xmupdU^1GbDw%Q6&yr|t`7w#~7;sv0F4a;OuZ7!>+EPvU_ z3lkb?5s4H=sZ$l2d61XSd@M2a%$ctwMu*P+f_i!F!Y*pI{me_0VWmb%8M^6v`c}$Do`SX1+z=#UuC8 zAzKhe@(pLaq)31;8C4^GC;zv4&=L;)gx=1wF?ModA)hbEd9lK;CBGowHG)9N9eJFI z*n*S?A_cjk2tuWw1S@1y5v5Z3NR|oNx;`c-l3Z2_g3#hey`U+Ha2S;`d$_^wtXqv_ zsiFWM0-#e20-2Olc$1@_XC2aLunjkmfCYt;Go{%>Ecu1Ovc6A-ETvp3l&Zr6TBUl7 z16&B>d7%Q#iDIRe9n@;2W0!N8%glCEltk)+;dMq-i~47;iEn;?KfY4r2Q=7)r?vjp z+)bQLTK(iIRpv`}r`3-7qc+(+|3l7hMJ1_P>yS%_sri>UlV#ie71DkD{6u<4?Z@19 z&b%*?UOycCXchhAFD8Z_IQz46aDmM?Y%68+i&XKkwKN&PqOfdHRPv`}TDL8OABeFc zD4np3IX^K*ec+ix@V!8a#pR+p%pjT87VvLBuSFKXQw@8%8cXe2igLRf)Z&xaH zn6EO~?%>|bux_|s6|0+22k&6XdV9k1{Bq=z0T&Rf6bph_$_yMm&UOK>Cfn!&G%^{r z%H0Ijr=zrxgaqNP%V4yW4XledbM&Uo7j67cQ$>_@w|7z{-pafQ95%et-}V9^_GAI zDHI+n(+I%wN)(oHH^tcYenhk zeKbF)I_a7{CRAdBlpZ3K7FEbC4?hbuIlklhq3^)MRe3*6k*oAD>gTr{aAzZzird%a!CPYO(Eb(7AR?|WX-_hp%!QH%U)vUd3WRuI4vu%m;X z;keeAZyT0JC_||s0Xd_}IE&OIOXfy?- zy!X}YZNzo*IkDbohd!_!L#|M$lwz|}Xhi{*hY3(sN?SAA*@7qvFj=`g;u-iUY8Y@T zk@e&j)hB~m38BW`2CxGQTTqI`3i5dXSt=A21yD|J(S$NTs8ySjyV=ZouN75Gb-gZE zn&f%|FqVm=DRR21*TUBR88)-QYBem|uTmDNh6w4(rD9PoS1Z+8cqqZ~>)l2jIBW*3 z27HQ4zO4&D^B|ULn>}UC%GiP7Jl z{p)ie`-hi724LY*#77X4rhqgUE(zc&$|7d0Ft?pnEt1(Do3BocuBcY2$dY*Uep<7~ zc`iL@q;lmp{BT4zXz)>&X|hB>@dWg5`=x1GN$Q! z_V{q9i6LLp5e$(ve1=>JXCss*6=vtS=cdLy-*;`($W;*H_VX~>>6=UhRE5gqujw65 z*EZ_iHfF|eNFweU*`ChugEkD0B2?Owhv}PvWVh=Bj(*U@%>W!Exfrz5K_=8Ht-Vh( zVG@As)@=mi-L6um-ldlmnfgm|EkCKY`4Dg;4>c%m+`AjjFW;IOtom#bA zoG{H|E%5o8Cd)hnBv)(E)@biixU_bgt=o-dpEVmzKbcHlYZeN{T8q5lp%>}ljas8Y zSiRW{RxZkH)QasxTey91B~T7Go; z1#atQTB|j6JvU7y&UVg$N~4LB$C49)oikRP`Gp$(ZFx<7m-WUYPt`O?k(g)TBWl!6|#s7>!mi}Lqu&XPw(&r z7(CcUNgS&e$**<4)k@z&uGE!MYj1)x8lG3DA2g&wY$&^}=ERtbc&XWJQ|nexLJ?%}10vv;0@lZpr8A&piGGk-(tLM2XRkQrlwNuPx| zhO3*snRbu>$I)}dv&d4g_=BV0r`3gMeO$n=@axE6`Z6^<_H(3f=?q@UAU7Q42YH6y zq{@dcW>jbIn;AsH>(lFCieNk*Dl$f)&~!5y)dnIfnSd~dHO9>4CEpv(@ImIj;pcTl zV7IRIbzQ$sXf%8eX&lK|NWG#z8L6@-IQcHt@Z2#Er@IcPUZIZYrE+!ItX?kH z(#eM=SQF8U;~}zW^Q-vPnMCF-`@g`d9?7iuDEXP`gcaD9Rr_87v2pMVEOOI;0!|Ty z=ktP88QwLFrM@r0X|6*uW-}}+62B&tOHRtGwHqzOIZ?FyJ)}=<9e9$t(G>v}5y5z^ z)eJnR(Fyzjp)sG~ub8}sbG$Cn6>*|LawKaZoNF{2F#0Shno$QSS?1My?_>0a-$<{R zo8$KG4GqG6K&-X$b=EB@*=FxAOL4F{Q=s@!N8DA<}zePqk15Shki@DwgoaKWeQ?! zX7~YkBp4h(;A)zz!)GUQ;8*xTLJwc91?|JXpj9W6F`YbYO1h-BGe0ofuDB3r$#N=K_MpmceXeV{j$yMTgd?RM_Z-JBN_jyETj^C= z)TSGHf7HLXk2An(nPkWH$&}qq1|bsDyyTeOPO}v)|BTwn^zD5ui={-l*V&}mjiPda ztaFu0#kCuqR*P5kh-DG+xAtDaksUh1PqHIwBH2XN++mx|hKnc-R+C3|w)Yl}(z<#M zNrxySByW$d+)6#vWpuZjWIn1YC(dwtA7s)WJ-s}UrJnfH#M!ZP0K?7JB+D)=PMO}D+X4W&(FLcc89Dr3dKr<-wt725H448;`GfixT>8D zaxI?aH^E@!rZ&)K0c2Nucn$c)Ayt~%48l~%HGrH|{MBG+`6Jf@e=y7`OUSo|hxqkm z&}zlpiF{CDz%HaI-G#H?0Xk=`TH@DQF$q{^4;GnB#xNT>DZNQ8rq^QSBmL9LrHB8S z(VTmRH<^}{Qxvk+EnsoL^^_xm)&9_vj8V6{er5=M4GiP5S*=>(SI2gPum@hvI$|yk zu6zgSl4*AX@wxM>DSF zdd_uS(u$~GuFSZAaJiTlTg}Wmt=*?;-ujP6p2af`V!g54h^U-? zMIy74=JZCr@z`)8Go<3Qf5g&He=>2l{~Y8V21y`3{W;14TOs8NKe~f*#F!tFa?;~7 zlqVGz;MSINrw&qxmP7@B29XPv51|9+u~*B7 z3t&`YV483X2yDoDEhcBoGTc$+u*L8oG)!|s$d|}fR=XG{Hh2|wtXw(tPmJoO2Zx8q z851-R5L7ba;OFqyu^er4czt&Qh7hZ&R<4yZl->%IhhEE?qR{p4Ne{WWS0yRt^!O4y zdj-obVh_BVHFGKu#Shtr=^~+3$h!0ZSw|Js=)eSPi6eR4OY%dG-Hj31DWyFPr~@&N zceMBIW+PBkiWjtDt9(CBn?6RKjE(O_@I)OJaM*VT8`#$gEZaox;JQhF*-1o{_Zy0U z`oIA1@zmbM93n>Zx-Q#X_G?n22feQ2D>-QbCXKJ|+sLIecGq1%F1f?;Tb^fG$$+uU zO0w=Z4y@;fhm4e=*&v!)Bok@dEFWxZz6fq|qTwIhjxgI~ZNt#XRSw$4y^h(Ai_>*s6ULF~DAnPkx4SBvI)ou+)zqrTmz6 zi36#4$v?Uq*$FaEgfl_ABIJbAU!<&Z>~#D2Av0)~h1?vF{S9DofFI>I8_3?|nHy;S z8)|=gZI&~Gk|>wv-b#b1Vv)Kd6^V(UB71Bft>>lIa4D0qI|Y!Zweqox8P}Zv@?->V zAO{;46IE*}#ayRI9llr7PHk(ntdbaibwuY8CPf*oPpBT89vj zA+8=>uXQELQo(@0j~-AvhhGKQjd}OnWAp1A!}O!F5>-i=AE3UevIi$vKd&LqyZ7FE zEZAD=qiUJ&I+ZqZ`3~DU1jy#LZL=Jotk>^xeEMq4+WmS-Zc$I*QTgC;)*Zy36wsz2yt8?KKY5pvLQ25iq8%plR}` z88}W-p){k}@R~=SWGq9w&JP;=mzfoA*R#BEB3CFLp$Cij8#tQkM}=I0 zA2@aiV}ro3bkiW~Jyefe&5b}YPd^R3?qKZ{l3W<PrtjGuU@_ z{2V@Sp@@#`@#zmzmLSXE9-q98aur0*Ap8XB@gtO5S_u6RV?4Sa$(T?EPATMGK&pbU zcK(xbW?e-%nBHuGUIoVIK0=vNtv?DgGNybMy&DC-v)MniFK#L;;l%#3Md_cdyzy2J2iMrYu`2l=`duAfmDMu~)I? z2vBSeUuF6o7-hUUB$Z?1Y?RO1_uO-j15h(vDvQ8nZFQlVngMLpk;D2Ocwb}N>F$w@2xlT8c_6~0MfX{Xmc&JVkQJ-xb zUC&v$5qSTA-m*PFm>NdD-Ia4P5`)I^+gTHlL(sn9Viznx*GZzBOzxY?a9U0r%{ZOF zvHVJ2n0kPt&%42hYif;VT(%3_UdpM7z~qlPpO`xM6cCnvqfLL@3_SSJ+1DjJ(y*P_ znL94oU^QDE7FvqifK?4E3E_}6;o4*a=-O<4zL`KAw!s4-;lP~dMsla_fbB%cjFO!0 zNz)fG2Y!;^w`hLz(W%7N^-pc+8{TmC1Lv@MV{A(WvGCLfC|458Fk(oh&)iDc`6>Wg zR-V{P`S~7Pflkot8&6X74zYmb1)u{G5l|{ZasDz|F9--SHTZH0sk2Zzu^G6FE$|Sz z3Ot7-*ML}Dfq*~{&#kjzjEiC|n)@z|kd`0JZZg|g3Dvou(^?*pDdG6gRDdmZ=0Zlx zDg2Lg6!6jySc+JyR@$?92F4#;7>I9vvlF#Y&8fDdS)Bnd33f{tyo@8kqJ(1Dt80(hoGF>_>+5Y|cbJvH@Pa zB=g~{#_0L%*f2_%Iua&6R9Vz%t!xf6Z)G;y$p{NUDa>z0&T{X)aNVwB8aDM6yIK~; z4ab@O9IIbvCQ;4vLBHL*;;WW4;=!;TKg>G$EPf>Eb@`3%JpowZ;)vKF)baJ4k-aWu zG8cfENjk0{1$I{&QOHk^qrmh{M4XN|Qqu*tMc)Kgn{rW*bL~JH zDa_&RZ_H$v`z+7&Dmh{H9>x*J;F}t)HXLFI!aO&hOJ3jpmsv`}SVcclMfd;M++Nlutl=K6Nc+`e z33cw&Vai6z7MnisF-76@XDL)RKzG0{(0U-rr;nfn0B=7`f$%;}$1&z;nl|APh1#k0 zG(V7G!Nkdhli!NbmJayu+9)}qu)v!DCO`7s7XzGE56mX%g3U+bL6GCP%+a4#02BS1m~%Nw%Ok20ZW+hU<; zrA*6qT#vs3&iL8sWvuO9r)8xEBr9NCTBXX|X~qI+mMyv23~B~Zxl){%eUvfTv5~fo z9K%BxD+VE& z%#NqJ@ZD~(XV1O&hOSeeAKy0L;+zzU^CQ6pskvUvk!!YV&uo$)t)dec=HhFgTV+q~W?PVXalAb$JALrjR z|AvH48V-FPQtztkdfj9a_-dROVW|C918KGA@>l99y)pOR#OMZ8d#+TQkNj!h0lDw& zRp(&#VC;_taVwx9oW70HQJWj3G+BJ)AO#QrQbC)iby;8^AxKsLvKWM_^2h+KE653l zVjWQ8u?nsBXEOZI;}x1mt?vnsCaZ>bLJ@T4r!*=|?evyM-oU`RrK_M!pnf?0K3F2^ zFR5+daj$vgBhW2~(%vJ?=`S-{u{=q!YUz>Fj0S>^(kI;JsU+evR1#fa!ZKad{tDCY zWNl|m9T_RcX=cieN@89gufq#E^>I5l(uzC~rTtJ~xDyk{|BOW(Gm=FlZVywo)9r7M z4XlE(+U+-+hR34zb#=E>bmVXZ~u&igjgRh%>Nl{*_z`gyWnDRhi5i$ zD_?;#@kVO~On2i1-$%dmz^1;l;kmnd6O0E;gD5^SPVtu@2m-gJD7n)URFqp#AI0J$ z5Fz=(>4%^z0E0zY@y(WnQ@^E9g$+p&exlC^%Q^Ps0BywDB7O~+*jWB0#sUc~SA-gC z2;hb+>0}6ZmX~n3;N;t3C4aJlXiLgN+I2PL8>c=&X$6H^X~L=iKzsG5zj*QiS}PX# z9m_6EU#`|p{)9G)DCI%k1$~&&Dk{Q>H!?0NIyt4R$Wn%)Uv(0gQPP(HAeiP>t6V$< zQzMa8QM2pC1ixihi-?QrGp}SVF!|+TDofdB0PiyH%)Ao_LSoypM~5u8Ce;z6@T}{M zX--b51m5Tb>*s8D{=?Ki=~l{^`W!p_Z8tYIHdY5nlGF%TQ(L#^dA8fIH8-wxz(n$t z=DPFuBuv8Ey2-E7J+B#;ho%{%w`wE1>h#W7q3C<`KJfQ|4*KRIQ2NALDrSo88g;pA7QBl2jj_@-l>?Z8PHVD$_0-{XuzRtQKf9UARcV}gF2YNL+BTxP&{HTgB>MAy-+ zncG2>8ac%N^oKnY;XEQTS2ySE1ins0H7mVV^Bn5?TC+L-PYIOR0K=_od20Rv=qeh9 z{zR&8=$}>RM{nu-@H1yOpMx7hAOm@r^5oyfl&(|~gflk*YoO7fu?vL!BR`}f#6@yX zkktk&D4!gsjJ#B=^6Q{U1YaK&@`aOY!1QJZoPJoZu$Y&y?i?A}4-`1%+EYadolSfDqu-tOlpwUz5~7uVhH{!GcQ#t-tZuDsC&JsBCUhuh3U>XVHf3!l+~q2 zG+#nEb#oIT;)qvrX= zpdfbg{5{A)1G*C<5u(EYIxt1ZN-mTi$s|8u0g7QmnYxcg843JoK3jBCR?q@Vhcy!M zuQ=YN!Gq;SDqYiQ4#QuvEcN`%Pr*tQM)K9J;tsL3W)gHe8~d|jC2*DcyrE2%9sNeTel%lE>RV=L8eZWXmbRn(*@P( zI9_uZcWR8X3Jy|aJ6$^URAPmqgW`DnaS(E+zn*yLD0g=B99|JifqN6gCvT$cn0u>8 z`7_^Lpx!ERC{=_I?9p9RAeC{$V=+$$DvZ;grovKfp{xm82&*oi_)Z*)LF+X@st{K~ zPl(FH>{0L~;4j-zIxcJVA*ia&T}WGnQXwzKGMpi#gd23weN!^+6lzt7@T5w1l+PF; zkOY0NTR;&@ib1+8oo4M25)iqh93Np~JPXBAtRCan`k+*bSZeU8j(2n+U;LR-gf5Ia z#jo#z94;17Btj;0 zicd|D_IZO@DA$pe1Luq;f35A#!bug9#r|d}JhG!hBk%PZ=$M_UQT0xYeCT zQxQfal!Co(n^fG`mclC+#3SRZPDq3N(1}Y40SI2QlLrUN*1fuE9zn41BL7}zL_#L% zCc|`9tB;dUBDg>H2@b++aYXC{E~%k_H-WsE>{i+7Z_;G*jvQnzVFwl9@nq1oohCc8 z7KDZl*)YjFAmEVo+TMvG3I(B~w6_`@wo^hT))*;j*ThtoaH*+Bk!(Bp~07945NJBTMA=Fld{M7RlssmCn z;2#*KaDT5=D_H#&Px=S53}mE%--Uu`8frGk zT8c^uHBJ=SkeKfIdfSr^zKf;)0)n#*5#(Wz8kMR5D2%F2eOC_x?_rPDP@dVKM?sQo z;J=MZRFx8}z;*TnZECNcRKx>!uoght2|MH(%}G>&HR z1>_2p8d0W#8{h+@j?n1%es1))HexlU)9#QTW_g`NqXi%*y0$f;*&q2ynH!U zo5hmj$5zn60t}I%R4XM2uP7Mug+yim1_!tVm=uUxcR_11N<&6NsLW8N&p>5AH}y^0 z%$EUSvPunxH<3OQK29ng{|-$;RN^llUKdMHfD?s1c0En~g(fvK1B6TOa08*Z06Y8e zEId7oVa&M|`Rn;A0w7WD0(G%5JhYg$BOtCQBj<(Orr6;#dP9Ur$c+8AcW4g-nKPta z;Fz%_WPYR3XbL3)-W6_V4{#S2U}g)F5&=|YrNr;j1;r!xIe@L@hp4(ei*y`S;`OL1 z%d#SqYseK55}U4Tp^D;t9l8hUzyq||fKIH*`yiH}T1tNkm5lEjxT|}X-Jll9>|}?9 zLg3F0uxZV7tZFO7wZK(iF$4GoR8UxUV%*xRqsap)T!(Dbd_QxoCRfo%LQyw>|Dw8@ zWsX9tIj1{<|Q-R1TNP+=jWD)1wk z-36rp>Uz+Ob2@hNRcv}_J61!h;Q@6B#-M!=n>r6D8h)#t( z|9#EFYe>Uf;4^y}{6R$~H-UN`4pnR42V*T#(1Gw8DtOklA^dyzQ{2(M1PpgBKaQHy z{=eg9HzaWBjqZUDa3?n>K+ZLubQ8m$IQyz|W#7Mm(g30>N|OqYUr2Xj8C)zo#yuK- z(|n1(aiM1lHWGw3+&9#gKt_HhhvHbLO)iC23PoO6MUE`iD|uyVfp&xWU(a6(p*tvJ zg@s@o#9IVjVpV1%?l3fwG1AaZboe61fV~ZQIvv12W*}eb8Mi|MV~aw=Z?^l>4}zeJ zU^AKmq(TNz;vPJoK}*!KKer)Y0vAwRb_pMO5=>@{z@T~X>x^2W{=r0ST2!ca4-xLA$kolz$`L)p~GO_RVtX3>SNn5I=6AtQk;3g59 zzSspbx(8u4%jV5V4ZkmA%1TNa@|E=8;oE{>*)=e2u7mQ`Xa-VBvWZ-*0me@JxDSYq zTbJ5He`5nQ9`5#sFD0)>X%&kLqLOc8zA|Kxx*icc>(#qtaBF5+N9|w!ju?77`~dN@ zT=J2qA#V194j=8CXH~NN;}Ev2_}caT?M9=Xnuvq>A^;B#A>bow-Q*sIZ^umTmTuH+ z_)w0*L`dWs2O=cD3Cl{NeSZf!C$4t4TYR58fflJ|qg{q9f-Fbf&2y~%dzj&&VM=YJ z6A0KkU?)-M5_H`-u%Fw%I5ByGb0AeMfNyHd{)XGXEJ5v88;`C@?0@&~saYDpSV270 zqGv0#B_TnrRMHG|>MTj=Ww9_F(s36U0?8;$GlWIIPdh-84BZ_lmNgo}Cn!5f#;(Wc zu&m=R(D20Hygfn*+&(5H4F?Fy)MYU^Ml1|C}0hSFE22O*uSQ9noh8l_oi!s=aj-`z+{(|&q8 zxiXg9v~3q`s_S?Sq!-EkKtqe~kdF-0dND6h8?<_J#r3MsXZFvrMl6mar?8CrZh^?8 zWv4vA0Deam*L4VtCw^5g>HCwex`Z8M(g*wV`dq2o&q)i=L z$XwomK1t*`dc%Qmj(@cWmJ3F`0WeSQ;`j?so#1}_Fn9LoIU}RTa;BbKZVM9F%&M*= zLm*d$p004l{?jD?hG zA9(?n41Xu#{Hs_k=n+7LRRC15tPlSTdYuSNhUTWP5{l^6_Xx=idPO|r=9$>>Gzv0sOrYacW`cAyU?|g?mkEb zp_fUII#DN{hI87wO8Qzi2+@tQVEq4;(cwJ!i&SZu+yzHdsZ^n_L+y93(+*of9g)}M zkHHw{_$;{uUFe)qjv)U}0ZmoVnH|t>ImRY*UH3Z8AZm3rJQvtqRi&s`9ay1SEq!p0fK1X)Mon0Wr@+u*&XM=WYA$m5OWd8j|}6X=V?TD$O}XS3lYDL&me$@zz$k&veQEE2L#jme+{jj z2n}y(w1yD>yCA$#X7r`Qj0<#_xg7Wc z=*hqv!>z1EZwO$*54s3>K-|F|?|XpJMg;!5CW1w@h^!`SOf(u+D%2{h#n87PXy}e+ zY(xaP5mfC9=w(=QeFedN+@#xvYk+?WkPs3YKB_5`O=>>97FkW1)X+iKZMr7PtzL;L^#lZnIS}=q>XT$PKF?FADN!Su{aW54A4VbPn>};h> zzcCFW1VyrVZ5N^BHd~Pb8gvk{!EZ$nodhk#cG_*Isygf__2HEU3z!jutX=swv_UrP zCh!7c_}~>Bf;3i9GHcb4eznsNuDFS^17QzAwLPS@kn5We+V=NPZr~2x%)RYG`a}F` zdR%RvybqW{4^edLU%0)W<{;F|C{I-Ar{9)1d(AmCNj=ll2QTpG2BdFbajAp*GOPekdJQB|k_7lTl71fh`2TxFPD$2@v~ z#?oBNqYnzqOd%&a{C7b}y4Hbj)8ui)nq&=V;)D(@0@4yCC%TXof^6&_sM27SLA1cC zfm4P*><`H0m?{)CAgSQrZ+HkH_PLCS{z@dEL;U^e?>I9|Ao;+ zutNM3Xj$%`0dN;!1YX2{hyfK&uUSE(TLsFXt}r(Hi* z_<>z(Y|W^7;7dkLJVF@iSTXQw(7A_jZb+k>jliGq8|;VEK=_aYs;^k7#oD7CF=on* z#sa&7{wD>FBb!mt1P}+FB?ER2+Kw(%Gw6>(5?WN!>$cWR(k#k(2>iq}HiONG=P=+b25}Nv$9aOq?uhn`u!KH_&SJPL)f_hrDLv3?g zA&?VGbPsPt0UW)%?I!gu1Cp0o-1i^#Q?ES4a(n-tgGd?rfNE{oJbin1&#|2Vnch-5 z=)(i2b@E@hG`j83dN_b8M!S9b8N5seAA6F^LdW>Ts}ftk|I~Qm?D})~D#k6BDa(HB zas)YOv=rgBV3I8xg(vX85bU6-a@@u}+yK=CWa6<<7@-hI_&VfjNV&!#@4YeBxWy$) zSRLphW4q+|HqttfbfqZn(?I(h8hODMIX+Y>mV0C11Bp^%F~1MNcCVi8+FJTv(K+7OT>x2e~pH{6J_rd)yKqFjNjzfuIJ zB`fShuV)R2qg&(*84RJ-fy52+%W@egM3SZO18{lijGaeh3)TSL`K21)bt_1o3g9DJ z{JMP|7QkJHZa64flm=9(HFOA;(Sa$|p@2*eKIAd#1SF;cE~8LIQy7GR#5eEbhVRqk6s1+nT@9IPP2&>h5iVH@X<^KDolu`TWEk8Fyl^z_T2qkcD>$g zDGTzH(@&%0QU@VJx`%IPkF81|5~)7^n#AN$?ujO7u(PYr!Rb<%E8Bj8MiNs10%NM@ z@ihplQK77xSjfnL9ziWmlsd7*Oc;Z5&6&S}_5~<;AmTxvHKLa-y6O3|tLdAeTZ?N{ zaaLRb%PNd_qYzc$<3Fc$ODLrWGwT=dhPF(Ijyx-MWSGWOVCxI?9FRo;=%^xc35a5B zLq4*VHmj&h#6oi>3c)c{D=0Yo6EK+U!Owufs70{Go5=c50cI<$IDmq0U?2Vltds;C zG0_$K%yrx~_==&Xv!A8X5WQiIe+ZPVwO09#n% zw;PBu+Vl5wDjEKg(`=PWaBuAs_iQ7h6J4i8T8n@6WI;$bpOH~swJNJ zE%mQciL?995lt7zwg-9k)Bkf@h*h!XS`Zh+PT;OjZK7QPNueO*$Hw>}!}4u=9y>!U z@K4a>#0Ao^F(ve%9WkeW2=6Dwc!@KukiXW>w-6y2#>@|CpLW|q2{%7h)_BL?$1N$Bz42Q;FZBNl0)FU;1&_Rp@ zsahD#4WN@>DQ0UHNB~%h6KjEsg${_)Xa*C|nhRl0np7RVX%*=q~;&Mv#sS< z5*^)<@W$2Xgb(9FRu2s`qiXd;88#(Ltvqt-J&C>7B(!$tk-tbhbW>tsJC}3&y1>m4 z>ZxC2QxI4m^zJ;09&J%FG7!$I&goUOgS-n>9$_rrF9HmkZq8p%Uyo#~6DzVn0)ku{ zw{?dFKG7c-`=2!B;%tP5hg@Lp`?OXH(-feL)VnA&8{qY3eh$Js51M-reuqyWNc6Gs z0()FwtjWEIvT@guR&aJClml5TOzDjC!S`#~c)I|oFxFd;W>ut#se5q0NyE#N5cN-Z zsmp9xswu*RJ^eVNvm%TiTD-BrK*kNlQb!T63&peu{a~4QR;=ho?Mfb6Dik3bGZ!<| zpQC=0aIjT@jE-S8O-&UROb#SMiofh*286Gz6SuKu3F&=t`FYS}K{wKe?T$`-o3>%i(Nz{?(Yu~66y~3&U2K08C)b#> z0mv5=^r*3O-=o1h{rjdzkGvOqZ-4~Ajz?-~?xPF)9p(ODza#nFen;7V-|tAqen)le zcZ4DZr78L0g$<8#C1in(|9cxAp`#5I!NAXgf{3Mi{~LEa+BQnjx=EHeX#4&QtAP<9 zi+$SE@ECjOki`~lXtyy!&LhRQUuxm|QFtCK}tgYG@n zsHJ3ams+aPxqSRuL<=vEqO^BP1spp@2?zvRzIsEzA z3-$UgrjPnHVShsw|CaepqHh;N(Kz{Ek;N?aE0u0Ax6%}f#Y>Pck;GDJiAMFFA$|Sq z(xprLHHyMJs4wI1c8ZHn_T>TRzHo?P-=*Z#Yt4qSI ziiwmtrotMLI4J?|hNcaIPA?@Z@5h zV)Xcp6l2g!m)=VC8TclOaj4X-^aZRPKZ2jXu-~OkKXo!g)csX z>%ctY4fy{K`bE@Y8E)Yroxr;mzHc{6(=>zA+}%3~y#EV06&hC+fAemjHa;KvD+`ae zeQM#0&jAE>eu=}t*Wbo~jU*iQFbf!LkZ~&~^u7=gHE>0z~sU zjlu$0LIoO~2dr_-EyMMSx(y=!(zF~m;HU8KZNv39uxqozvq`Hus zAb)g=B$P5iEB%ozl90w0MC4!87p(uZMbcpix>y#)fGsXE&i}MW(#ZenJ(94c6@?1h z|L6Bef^)zs((md6T^e*X^9%jZhxlz2e@rlVpIwSu99O5&Syi8y7|Gw(4`nv0=;&KE z>kXaBkK}JX&x9Z{KAvb;%+CSTK6KB;M|ZOIoY=UVsgI0(nX6~VZ0C!deQf66esfm> z2$`LJ>8`#Q3v*K+xpQ%R+Z(HA+RW}n;IAcS)y&G>kP`RhM^>H3^-*7B$}=z=)Lj(& zHRfks>TX!RZOa!dLV}|0@w++OwA{w-#Slz^sr0+z=ljR8-wOf)6ir3xGfVM0`VR35 zwgN%acH0tE{qZu2M~$XI%OakDMk;>UUAoj@6j8o4S+L`GyGv8Hz4SSaDN==7lQKxx zr6~xi;*z{c$-5R8h38SD!QpOBI$>DdyEyyw%n@7&w!P>cP78`tVU6gInT(IPsDpXCJvvTWto>? z^EGN#rHVIm@iqO%VEQlR@J?9lUEIR8ncR|#UWmO97ke-~|8Z{NLJgK$%EorwqUc)| zuGi$)zNK9JlnMj-sYHC)(=TWo!zTN=&n@a*_rL`zlRPhFQuL>B@r&Y%=N7>~^~IOp zx0Jq<<9-qL;peD3;ViaYPcRR-_%FwE(fcQ!iu>qzDxQIBRq0c+(+lStdnB5E>GKP| z?B#QXL%Myzbtd3cW8Xy6y9qoXtHD3P1AcYkT$#IZ#@lXMz}$a>JH(8{E)QRJ2M`EX zc00b4VHdsv0Rz4?J~wE`<1fJzCdGUa5AVi17-riIe;m8s#P4IbF!6`jo%jRnPDr;c zK8IbzJt>1}NR8hIulYQ{J3-a|0K6KVf=h1v9)Mjcacd950oC`Z|79>v{T_^$ocCXW z@pc#|!-jE!O-ku@Y@A{~AF5Swai7JC1*HpHWR5v1^8!p!+>Q>_Aj-I7j)Pmo{Ni|i zSHG=+oVLft5CkD&d-2xAc1lZ)x%H*p-3-w8rPzw8fcqD@V^j0p1?x03{{ppOozgSM z+&dS=3pKxL&bf2JI4xZ>N4;#E*03Cvf^kar0gEU9qh*2*R*}#AAK4`3VFfk1|F}oW z5e+pN)U8KF8`4YQm}1~YbKKpI-&pQ4k_3J!_ZL|09E4u zu{~0}Kinf_@(ZkGCS7cvvf>Z7N!d5W#wFf(tCVF;r`?FfkLPwunM`o1l^#`_)Ccr< zCp?J2|MN~MlYQJRad#~t^>Hw)O6C7*vlQ&A_0O6s5Ji(af3RDM5$~2lUd6u}JN-1e z$yg9B^A}E^`D$8@GM8 z{zVSFc0A}#(y6PIbY~xSt90u5^quG!O8)#3>8`}{md34P?@C}RfYe#`F8Vx1W$54O zK-})6-u>Nkr=*MKPtDCAoBrJLc;e2Eo$Ykw(&4G;`MD+ZtqE*piODn<{o)rFu3fr> zqjn`w#Kkj4-_hy0+WY`}8@JGMtS$aubZa6;TbFg1myWUUMY|S`J?ws(p!<-yP`BU%@uhol-qc5b^5wa) z`(F6f{Gz3)rJwqPsY(BrrsnIvH#OeE)Z9#ACjs5Qn>96keBob9rMh>;ht}QP82$~u zK)6I=#q`wC*%_6Z+0Cw=Jw11KqOZSyF+<ny zIr@wA^daOmaT53?IM};s8V-xSJNDHy^CJFIyAea+lVCm{2g~A#K2b~oK0Wv=V zBxEw2F7MGKpvvahitv_-RjoMmM62YcGe4wW%jMAuCB+q=iGDdx#xU`G9DXB411*D z6%9H!77~zZpI(s@@r)iiF^5(MuBk{%MzR35zFN3x#RW4V(Z~bxqTOt zCFRk8=BN%vv}IrC*BsHHxPOCm@B)wyJYPmSC=T)Q?&ks>6y60?hX`H%w_n0JDCBvf z_w_Hp9Q5}B=AcNVc>kAB4hDiQ%0c0`khA+mkb|Sa0jza~3*Qk42>mX~LCi%tz_MiT zi03~Q^V~tQ3Bo{JoCAMfFkJjE()NG$!`DN=IeLO~FfmyDg*57kM$<85>Ulf>IY1;h zobbbyzbmH`m=Pl$D-=q4{$(5>2MDbxP5^KZFdQZLMN)BqNN^tNaxo696#a)-H%jAN z$I~^ua#hBn5@HyU*phNW!Qg){A#Wgocvpm1XDV3p_kgb4BOAh@)H`C4?hM&8r3}4}*quUp0s=$Ms8B#oX)SGL_@a;b&w7*b z!fm1$n&MzxL|U$xrgBd2-)B(G@cVrjV&k?_ESAYi>*;elLAa1|U-(n+``OlNWkqi5 zJbg|If^OW_sO0tO_vGbb$zn(PLs_|7kd8Y($5OU#$JU(QgCU#nvzQdSw8L*yLYTDP zz5D|k)3!&(|D79oL^NC?T`cz`Mhhx{3{|Ri8Tt0=j%$swvl|H%zA;FV%rN+Imx3et%&@`DxN|MnSW|nNy?KztmF)5jZ`!x#p z>;5y6+lApQHPS$O{T+zssFH9bHqr=gQ18$^>wf4yEy3m4nvn&lISxhM)+lkY@nNB_~t##%h0$EhhA5C z{}_NHI4c4F@r<`GW`mH?g^n3ta3~H+E>(2z8npN&BhWXR${nfeU>;2(7a5T4Eu&h_ zf9Cc1aqu%WvNd8y)YqEN(t>}2Gs#?!68?v*_w?vEV>%NAd5iYTNzpTs zu{$dES%0^gf-LdkO3P{YbVyAMg%-$GjJLEMek?B>&R>}F8?mQ_B~H-iO9w+!PlUuF z>kfm6Og$qWF(Di0pCcFVe0`Z{hrLAqjiBVhC0Z?xlFdtEXERN1%!nLb55)kz}ZjUhev0x zdx;k-m6yIClGEhN@;LoO5^b_!3t>D@yC2D+MfSk%Ci|zr2u&d*MrXFk37VR1aDh$M zqhJK(+%rsYj{PbeAV$D5%^~v<7r3M1UneI(w+!E)z1_l7(w89{7dZSO`=D0N%ZSGd z@4;#xCe})CcTc!?BRP(7l}^I78yZ}f^o+!6KA$qFI!-3}+jxQ}1 z62@mLPsm0^^+Jc}!Tog&hkSlbUEgq|l>sj_$hU|D|cnNtm$e!_#)_-ipRt?4Wgg^YgvhuR>;I)P|HOiT}$=;%CpPZrhKYfd_ zhYur&3&c_%KfnFgVU-Q%QP!V-jFPI6p7JkBN0k z9!D&R6cdN0#iAzsFcYo~bAfG76f1X4^RC}NhJ|gTx@b-F;o*GV!^IjjD>zsx4 z(Q{Ji4TPp=DH3Y=8%R3L()RKM@92Q}CF!?$4SKHJCf}Z<_wQM>O`DJ^?d;yeb9CQ< z33_lZhD0p*i-msoHToXC#^d+-^2Vb#e8KPh_v!XTsp`LT=ZP z{C7}hgw;yUv@#H0U4+NMg9TSKi}euJPkZ`cPDBY-GO#=yz}xf;;DE3=36%P=9;~zu zK)F*aQ9Jw?07kMnfRo|LkMrZr{R#ftVryrx{sr2v26340JN$(F%lpr>J$i%uEqle~ z+B$)}eZbwSOz>T8g8VWepP3WV9bJ~!&Om)KQ#U5q=LXOR&B#M{b?0lobzH;Wz2R~Zgo!s^AB36UuZTAmTl5vNu--pGkBhdq z(aIv&gP)UpYf>u|M$3Mzl&qbR?%gx@^9gBpD}BsgZQmUJ`ggQJt1B?~1#9qGN+IrW z6N$wxCJr|Ua|PrOCXujW@ExWHkz=k6^BUW>zujRV?wZ3KhaGNlF8pQWRHTsn&6m@! z8c)w7YUWLhsq9mUWCV>dVlsM<0Z-H2L5Ro}W=qm%p8;)K`RvZad-`5_Ug_Q+8C4Vo zF&p?)Mzsn8Yr6L*lN(!G7-qc@gbXE=@DoUkAX~Vy?2Q>kxT-8h{t|{WMYq{O8-D|flRu(2Oj~Mi176BaOn|_ zNmtZ zE`W*01GK@E9y3O&NZk$uf!Mn3XbQRgSiVGAlfuWW>pRh|poe>o#(@QaBp7tt)U)u}>ddMBIi}+z|6!W+PPHNC%EhOPnB% zAW8r}mLj?(x+M#z5SMidBO{5UOeg=rc6(|P0S6XSz3?k3DaPU^d~qA%t3clwa>zpT zqihl4P}4|BZWm5U2wvPIqv%8f*>a*2Tgv82qZ7I4LUt(U8(kQRDTb+DI`B?f0#y=Kww!Hbgiz^gbQkRvT9Rsyr|jtfjuz_8XRIeY==1*QRqo+)2v z+`w;57&(`j0@I$bIi?Uzw6aQ6Tw#o~Oi2dy5p$f@TM*f)ze$(-r(p8eV52PeXQht) z%LOvV?(goM;^6oExXa@VJU-swYcBXY_08hwT`)g3=gH)&7ZAMX^ zNEw5aU4n$M#}alClC}7hWL;#c_C%hdq-C0U6>n3F5~A~&sY%!$a~WV)-S>zAs(%9+ zAcV31^&4z3IDDPAoCpT9lo=Cpy(QceOq`>Ve?ndkhI@l2P^5z>H8L)(v;xI!GRM!ZQ!WMc@o{G!L#2cM` zeN#L84BX_$KugXFlc7nA^zL_b-6rg34yBW;Lr zzP~H@S2E7Se*0#DG34R`$N5<-hNyn3fAFXO{<%;LgC~Fu`@#SEN+^bSJof*CVn_q= z=a)b+2uvYSe&T~SehDB0(CfYukfG(Jo2MVcF(d)UfQ+IOE*!(3%hFR|4C9Z$7zFy% zkyj9g{a+Co^fVO151)c!0DM$W-wC?iPAAA{1B=1)y)R=iAQKmw6=FHxAoUo?mrmf zSr`I4{90$BR>-f`b9pm#4#|vM2Ti%$#-~5b!j7kFdjXcyuhW-B1uZ9#urOZ zbEdXzq@)0X^+wJ^?A76APc;M*V)Z_JnxhcU0Nb)IvuoKSOpqbl>U7CD#@5 z7Mv7L{5p>!v}jHq&4_m1-J2n!QL&M^iqKURKI2mEu#S+LS{;!?V&V=R#Wmf>W~qe) z2u;^0drvqupy}*&C{T+POS_TZ;P8BLX>pztgwBrBj=?F}(D09pNymk3o`X-10t;FQ z;yJcN=(s%UO59m4Gf5tkUE$(q5pM+l0d~>xLtJ=vB%&Y+C(~qwv)(O5GYxNrY$Th9 z&SA|*X$ia_2Kj{0(ab#lu9MLlBAmBk(F$T%q1f~AggpSi54%ip zT!gV+6KdU^BM^d!SsLkd6?+TCMVCqCNA9IyJm5OG>@z=axJ}?ex{MbWw8ei3Ld8{Z zNyKVK_PE#jOLOtO0Ki3;3%7-+y>mB}3* z?j0C>Hj^6|2F*-vB(jf7n zcUYh&9Q7gk1I0yfC>ldbVsFxma}e|rvy*c&HlxPKJWmCB`mbXpwij6%3B<=-T<2>_WBH4DR)|u=wyDyyQ@;&)g|B?X4H0{b~td1^I4`Z9f!a21}1@5 z$&y&~kF+&|`bFsPyxfPJn0R8&+Z&H&MiHKZ@b%uVo@fe4CUNY&YXX+>1hD4;aE6Kp z@x(>i-HVriNe;jY6!r^Gv%apus1HHbD6@-F;b|P{k^GJyPAvmL?g%YS_rK>sxGOc_ zTmUTc40a^8mg^q4Ci#_maB!X%>T8L4xpLqk0+MFEq`G9@7c4(R<%%ueb>H<0ZO_?q z$bHxMG}6963O(XwuXuTfR5=WOaf+%Kg=ND#a&rwTG4wMSH+cUKHsH3jcs!I!{H%2e>-XoQoqetWb z@*{8Sqe+SoCdLZF*G?^s$ko2ZRX>IQ0Cvs=SAQd-7qJ|MPq8^Fk|Zx+@(I@qYv1jc z9l7zIlR{rvn65g|4}MOf&38TvCw)TF^#WUWWLK7v%tvGXnnH(_=KH_vD{0C`sX>7& zs%mI12}Cjn-hP&DRU-e#gMNq00ntPa3Ow~0v0c0DXOveE$S_X}P@)Jw6*FRFg&?aF z^UkXTvrnNZkxPRqw0KsbknwQPHR99={2x%e_>BC-<*tu$oZdh{ta}Cbhh)Z0t`v$C zMh$k{q)NOE&csX{SHq*YHztj%HFGItw~KyVjEa=h_&1bSrwAL0CFT+Sl|^lMC_znriv5x~WaYF2>Hyr|KP0X>=v+{{_C~7BX$%Z9` zhtoa%bKq5r^>q)-Ntx7YW#F2;TCXgMfhJe39~SCm#+$1h>}-xR9rYF39A`Sc{^mGi zD9;^dpiTeU(o1d~74>$5&nB3BWHWfCQ5bdL*(8$>IvL79Azkn}Wq5D?9K{ITGP}?qg*cV3coVJAe5VAfR1ty{)lbc^Fc|n!y`a2{DpKY!9M!A zwERD%2S0J45h8Cf#EC8Jx+Xi^e30uvfVEHZ%LGcyV4urKtJFm!qk-EOOb2!Fd2@r_ zmGHghyDefVXC=qSwv5tP~E1 zUMDFYI{n6{7CkvWh2d_Thdy~2x`4S13!M(R>2{Gna)-JAB|*=QUeceX#OL8EF+8#t zACeb|f;$%T`NhTJ;vzotg?zqHD3J3A)!SINsqhuz-ZI(1kY${gHa6A?oO%RaNrdw; zX3AMf*}c24+rvx#rBVt1mv$ElhMe7@x3(5b#a4u6!e~WPEEX{iW_RlQ_95dQyM;m# zClv85rCF+PAoHG<5E7B|=1U8?J^4JNS<~;;e42)2OHI>sL-lZt`dN0Tr1~TcxtN;Q zZG701bR4euygr{#^@`JZS;aQ@XDL@aoOop}6GCJefd&Mw*Q~m*)QZQ=zX z_qJxGu9byc$s;dmc$=jn{&gMBG6^9HlH&16bnS4&@{rRNpOobPZ2NZubZk@^?FrPRS^$j5s-`2YMq_6YPDL!2e!*) zq@5_)opjIs{fmp`68b2=Si|4Kf+-H~-Jjc&!(nt@zPgy-m&>_l@87jlSZFUTg0{tu z{33`;fDQqsZ@6_YAN73 zfO_C6oiL~mYF@S0(b1`+sdm)b4`p|jS5{Y75hc}ZIxCe*bq@}=gER3MqQR9#Q`?<| z)wKC0T{p92{XY`vUC+HV+3_| z{W(fA1iH(p@*8l0`2xM$6lb7oaGP%RRF{C_GT=Fs3;?DTAV6I$dQAd|v!~4w#Shz} z1N~h`x9KPb*s>e=F~4PXdHxX!yZ$b4SQvAY8weT*W2JqsVX1@5Duw;-tYhPFIWQQ>fLhp0ndMKc@y|fpn!l2>s;80YWJD(ZGUhEH5uSTh+{y( z#3=z(yO^jdlDPFfp-tZuK%jOkx{Y}D;lZ)W+d{0NkAxByYSuXwkGC9p`K6c0E!4Az zN)@WsNscF9I%-9?Z3on-?V-1de0v1dPJr~g?SBJ%4(Q`n@-tkm743 zK0YpL+@oU6Df-Vvk^7t9l}5wqG}JKka8J;qq`JGifra+C%>9SICq*$C0U*yrL(!r# z8*n7jBm7%eMLC>5_||I{|L~0D`OeLfgj#^%TT9ZdKa)NvNZT%2BOm@#zPd-wZAcHU zG&C-XtnKJRd|TEG2=8bxAb_BQC`5vsC(@PGsVqS;5%3!tFuc1*rhvu*YhJQsu~bQY zmO{XoRDpyr9a=)dGK}9RNfr|P{2Z}fa4TsTsTC@FRaI52hTfE?=%HO6-fA9b-`%>q zwY9CK70uxTS+e5M>&j}qzPh@6JnJ!6WN7e}>Ohuk#t_eraWh8Nr|1R(jo{uv40#2v zz4a-+u>fVtR6oQPOQ3#^b!xJHk?CG!i{r7xIdID1=N2;*f0U^{dQoDZXqpYjpScEo zs2~I$hvdQhNq=`Yv!Fo0Za2dKlmNSvGJ7J+jXske%1UwQ5 z+THx*T|f=O+p{PWA$It{rV2p{HyXs_n=;nN#Zlat zAeRxJmW(xcyckwIS(YB?@bH6X+rf^Gg9i_`b&BTDK|w&i>M`0V$VWFeJlogl*6?MI zm%Phhn}9l^!T5*&FR}6}lo(N#>qT4@`xqXPT%gL5g$E+jBnX;&_`2|lf^h5W8|P&k zMA0yr+r-1co{?--Gp8hspAvT@jPV@2Le@BzJV7*{PHEafj1yL3@wPIMcy8w~ZcVy` zi%|0F4F=gaKFw@niNn!f6O=aE*JshS?X+-#^TK~Yw&iwr0l%E?KuYh(COWZ`h*eRX9leB0}CgWqdxI;sY#2Q%D72uyN# zc=+wVqXPYhL)ZjU_WXvP2^BJ{`tiGC7AohYVjQ!xqD1 zUL`-Uv5AA%P??&D&mWQDNYv$&7D`5LkXPqfI32ce9g=*Lh>f!(VUfg}jeEQem_L&E z8A;6IB2hAY4Qy)T4_A)5*RyFVHAev9l)Q#B@b=;c0rv*C2}$3;Lz9tNFl=fbY%K1D z>*IaL#l2pIT;MHmJ9veXWAsEgM#ASvVvHm&h*v-_T_wplX5r%YxOhWK+y+m81Gtif zC%{>tt&k&Z;lXA}2C3+vz#IdNK4{QJ>v{M`U0@DT2I$e+4?w_iToenZ4JOP?#cVsw5+X0yMlq&8IE7lagQ g?|I@m^*phh+WB00%r+&_{DLHApC^RbUm}734}X53K>z>% literal 0 HcmV?d00001 diff --git a/redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/ra-temperate.pal b/redhorizon-explorer/test/nz/net/ultraq/redhorizon/explorer/ra-temperate.pal new file mode 100644 index 0000000000000000000000000000000000000000..bb63fcdd50490a6ace83199cf15196a1e551c57e GIT binary patch literal 768 zcmWlX>5{7;5QV#v78wGj7yAT)^T#DeE+w)r215IPWK<`0|4kh^=V|qs}{yR z)(Lb-lJ&FKUJv_zUDw@qyWJUvvA0aqv~1gUJjZc7*Y*7nAt!YFz;OeFbVv?icwh&#yrBF(A>NpHXDaS@#I@Nd0Wgd^`;d&jf%X9gAl*_evOxb)+ z$By(3u4P>FKolrvh+r4Tb`)C3H+|P|tPP!Cw7b&dNO||^+K;aZ;Qrmtqq_9sd@8#- zS6`{jlPZngKhM`~zFp3juIXx_szMa3APJ3v6y7y}eu4 z)B1pQgjK@N@^`!cj?=5{uSa#M#E|ipWGciGMU@wD2j!NV?p?gK!j0jJZs6*~z9i0h zNKzEVw&xp`9oAJKIO4gPr+X5cL9q3Gu&nX9R@1*wEl&Bg@ogWD#^JQ{VI`+=<421MGttfJm#3KaJG+