From e1689b866889baeb386e33cbebf9cd283942c1dc Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 17 Apr 2014 16:25:34 +0400 Subject: [PATCH] 0052388: TC7.4.0:Texture is not correct by default --- src/GEOMGUI/CMakeLists.txt | 29 +++++--- src/GEOMGUI/GEOMGUI.qrc | 5 ++ src/GEOMGUI/GEOM_Displayer.cxx | 94 ++++++++++++++++--------- src/GEOMGUI/GeometryGUI.cxx | 4 ++ src/GEOMGUI/images/default_texture.png | Bin 0 -> 15675 bytes 5 files changed, 89 insertions(+), 43 deletions(-) create mode 100644 src/GEOMGUI/GEOMGUI.qrc create mode 100755 src/GEOMGUI/images/default_texture.png diff --git a/src/GEOMGUI/CMakeLists.txt b/src/GEOMGUI/CMakeLists.txt index b4005537f..c5dc25f8a 100755 --- a/src/GEOMGUI/CMakeLists.txt +++ b/src/GEOMGUI/CMakeLists.txt @@ -87,11 +87,27 @@ SET(_moc_HEADERS GeometryGUI.h ) +# --- resources --- + +# resource files / to be processed by rcc +SET(_rcc_RESOURCES GEOMGUI.qrc) + +# resource files / to be processed by lrelease +SET(_ts_RESOURCES + GEOM_images.ts + GEOM_msg_en.ts + GEOM_msg_fr.ts + GEOM_msg_ja.ts +) + # --- sources --- # sources / moc wrappings QT4_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS}) +# sources / rcc wrappings +QT4_ADD_RESOURCES(_rcc_SOURCES ${_rcc_RESOURCES}) + SET(GEOMGUI_SOURCES GeometryGUI.cxx GEOMGUI.cxx @@ -103,18 +119,9 @@ SET(GEOMGUI_SOURCES GEOMGUI_CreationInfoWdg.cxx GEOMGUI_DimensionProperty.cxx ${_moc_SOURCES} + ${_rcc_SOURCES} ) -# --- resources --- - -# resource files / to be processed by lrelease -SET(GEOMGUI_RESOURCES - GEOM_images.ts - GEOM_msg_en.ts - GEOM_msg_fr.ts - GEOM_msg_ja.ts -) - # --- rules --- ADD_LIBRARY(GEOM ${GEOMGUI_SOURCES}) @@ -122,4 +129,4 @@ TARGET_LINK_LIBRARIES(GEOM ${_link_LIBRARIES}) INSTALL(TARGETS GEOM EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) INSTALL(FILES ${GEOMGUI_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) -QT4_INSTALL_TS_RESOURCES("${GEOMGUI_RESOURCES}" "${SALOME_GEOM_INSTALL_RES_DATA}") +QT4_INSTALL_TS_RESOURCES("${_ts_RESOURCES}" "${SALOME_GEOM_INSTALL_RES_DATA}") diff --git a/src/GEOMGUI/GEOMGUI.qrc b/src/GEOMGUI/GEOMGUI.qrc new file mode 100644 index 000000000..43311c3ae --- /dev/null +++ b/src/GEOMGUI/GEOMGUI.qrc @@ -0,0 +1,5 @@ + + + images/default_texture.png + + diff --git a/src/GEOMGUI/GEOM_Displayer.cxx b/src/GEOMGUI/GEOM_Displayer.cxx index 16131193c..098436963 100644 --- a/src/GEOMGUI/GEOM_Displayer.cxx +++ b/src/GEOMGUI/GEOM_Displayer.cxx @@ -158,6 +158,50 @@ namespace return aMap; } + //=========================================================================== + // Function : imageToPixmap + // Purpose : Concert QImage to OCCT pixmap + //=========================================================================== + static inline Handle(Image_PixMap) imageToPixmap( const QImage& anImage ) + { + Handle(Image_PixMap) aPixmap = new Image_PixMap(); + if ( !anImage.isNull() ) { + aPixmap->InitTrash( Image_PixMap::ImgBGRA, anImage.width(), anImage.height() ); + aPixmap->SetTopDown( Standard_True ); + + const uchar* aImageBytes = anImage.bits(); + + for ( int aLine = anImage.height() - 1; aLine >= 0; --aLine ) { + Image_ColorBGRA* aPixmapBytes = aPixmap->EditData().ChangeRow(aLine); + + // convert pixels from ARGB to renderer-compatible RGBA + for ( int aByte = 0; aByte < anImage.width(); ++aByte ) { + aPixmapBytes->b() = (Standard_Byte) *aImageBytes++; + aPixmapBytes->g() = (Standard_Byte) *aImageBytes++; + aPixmapBytes->r() = (Standard_Byte) *aImageBytes++; + aPixmapBytes->a() = (Standard_Byte) *aImageBytes++; + aPixmapBytes++; + } + } + } + return aPixmap; + } + + //=========================================================================== + // Function : getDefaultTexture + // Purpose : Get default texture + //=========================================================================== + static inline Handle(Image_PixMap) getDefaultTexture() + { + static Handle(Image_PixMap) aPixmap; + if ( aPixmap.IsNull() ) { + QPixmap px(":images/default_texture.png"); + if ( !px.isNull() ) + aPixmap = imageToPixmap( px.toImage() ); + } + return aPixmap; + } + //=========================================================================== // Function : cacheTextureFor // Purpose : Load and cache image for the specified presentation. @@ -187,24 +231,7 @@ namespace if ( anImage.isNull() ) return NULL; - aPixmap = new Image_PixMap(); - aPixmap->InitTrash( Image_PixMap::ImgBGRA, anImage.width(), anImage.height() ); - aPixmap->SetTopDown( Standard_True ); - - const uchar* aImageBytes = anImage.bits(); - - for ( int aLine = anImage.height() - 1; aLine >= 0; --aLine ) { - Image_ColorBGRA* aPixmapBytes = aPixmap->EditData().ChangeRow(aLine); - - // convert pixels from ARGB to renderer-compatible RGBA - for ( int aByte = 0; aByte < anImage.width(); ++aByte ) { - aPixmapBytes->b() = (Standard_Byte) *aImageBytes++; - aPixmapBytes->g() = (Standard_Byte) *aImageBytes++; - aPixmapBytes->r() = (Standard_Byte) *aImageBytes++; - aPixmapBytes->a() = (Standard_Byte) *aImageBytes++; - aPixmapBytes++; - } - } + aPixmap = imageToPixmap( anImage ); aPixmapCacheMap.insert( thePath, aPixmap ); @@ -866,7 +893,7 @@ void GEOM_Displayer::updateShapeProperties( const Handle(GEOM_AISShape)& AISShap study->setObjectProperty( aMgrId, entry, GEOM::propertyName( GEOM::Texture ), QString( GetTexture().c_str() ) ); study->setObjectProperty( aMgrId, entry, GEOM::propertyName( GEOM::DisplayMode ), 3 ); - // Update porpeties map + // Update propeties map propMap = getObjectProperties( study, entry, myViewFrame ); } } @@ -875,26 +902,29 @@ void GEOM_Displayer::updateShapeProperties( const Handle(GEOM_AISShape)& AISShap aImagePath = propMap.value( GEOM::propertyName( GEOM::Texture ) ).toString(); } - if ( !aImagePath.isEmpty() ) { #if OCC_VERSION_LARGE > 0x06070000 - Handle(Image_PixMap) aPixmap = cacheTextureFor( aImagePath, AISShape ); + Handle(Image_PixMap) aPixmap; + if ( !aImagePath.isEmpty() ) + aPixmap = cacheTextureFor( aImagePath, AISShape ); + else + aPixmap = getDefaultTexture(); - // apply image to shape - if ( !aPixmap.IsNull() ) { - AISShape->SetTexturePixMap( aPixmap ); - AISShape->SetTextureMapOn(); - AISShape->DisableTextureModulate(); - } - else - AISShape->SetTextureMapOff(); + // apply image to shape + if ( !aPixmap.IsNull() ) { + AISShape->SetTexturePixMap( aPixmap ); + AISShape->SetTextureMapOn(); + AISShape->DisableTextureModulate(); + } + else { + AISShape->SetTextureMapOff(); + } #else + if ( !aImagePath.isEmpty() ) { AISShape->SetTextureFileName( TCollection_AsciiString( aImagePath.toUtf8().constData() ) ); AISShape->SetTextureMapOn(); AISShape->DisableTextureModulate(); -#endif } - else - AISShape->SetTextureMapOff(); +#endif // set line width AISShape->SetWidth( HasWidth() ? diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 8327f4869..fab29f562 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -224,6 +224,8 @@ GeometryGUI::GeometryGUI() : myCreationInfoWdg = 0; connect( Material_ResourceMgr::resourceMgr(), SIGNAL( changed() ), this, SLOT( updateMaterials() ) ); + + Q_INIT_RESOURCE( GEOMGUI ); } //======================================================================= @@ -2488,11 +2490,13 @@ void GeometryGUI::createPreferences() aModesList.append( tr("MEN_WIREFRAME") ); aModesList.append( tr("MEN_SHADING") ); aModesList.append( tr("MEN_SHADING_WITH_EDGES") ); + aModesList.append( tr("MEN_TEXTURE") ); QList anIndexesList; anIndexesList.append(0); anIndexesList.append(1); anIndexesList.append(2); + anIndexesList.append(3); setPreferenceProperty( dispmode, "strings", aModesList ); setPreferenceProperty( dispmode, "indexes", anIndexesList ); diff --git a/src/GEOMGUI/images/default_texture.png b/src/GEOMGUI/images/default_texture.png new file mode 100755 index 0000000000000000000000000000000000000000..b1caf0466db195833a31db5296c31a13d4e8931f GIT binary patch literal 15675 zcmYM51yEc46Rv4XiToA_^ifFtxGX&&o;A@1(}kDhe<#o|G^!{y{J>kMGd?Aq)(V1qSBm7Yqz< zIt&bseWC$a5(b99Rz_R|;J*CZ$1+KG!Ev{uT0^b#JjTvn6Tj0QhQ^9Nbuf{^$lgCn zew>Dao?(!Im34j3{z1tdlMO79EU`3iG=x79{QU$sMk-a>XdRzaBH`fk0dgn6jq!Su zt4;}&)J)SZ$P#{3?s*RBklPzdqGtDdD)C#MoQ&u9QKL(dEmEmcPofwyVat#&&in5o zOBw=H%*j(F&32W~S?wMobtjIQ^@a5*ZRYeo?>e>WGKH;wX8NNA*}j1B-4VZ!~vr+aj1gEZc+6; zR57oD+VITge#qUH^Wf(O9q^LB8#+_iwwRK50X_ltv$~j=*n`6Z(;Fw}@m2?Xw{?<+ zAI|xAZ(<>vf?v(yR1NLTUcDX~K2LQM+cBH-f$R&7cDR$jJ`p&!(>)!+l*|H%K$q5QY8|HwD&5_v~0g-059=>Xjmx3 zgKqqVvo_sqO~$Hk;+r}yuzXo6see-z5c_ z5#Y$0%qMqdK4IF*5Uj0XE2zSh6ncqqML6WG(A7RqhDdxWO#55E+Qjyhs--dUITN-i zZDYtvC(6#p@XO-Rks<>dJCQrDY?CX{``=#ssMT5EC!~*av8c>`9$Z2N_ZeoG>nmZ|+M%2pvz!!_)BPm%vC~mv%iQR!bf64THWv>b zP&@UPucuWMBTbn2qoGC2=0l5b(U@pQ*zD&3$L`+E0#KN)x{J;P1wapuEbUg`E)o`v3%;?Bkao8V*gwUWS^w?Zp)so?gTQ_ zj*V2>YzhbxYyaH(Ig`YBW~ZTTRI@B=a?;P}UlatCmk6gasHitrwAUqvtm+J+IR7uErP*TK{_AE({`Nea`9`i_UFu_)6EstoAL18vZl|J zbjg0lCA+Y%r&Qja2{Cs)M}cn}iQ13YrL_I-?@@>am#suT79G*R_EvpSV&G;q?-Lnv>5hr>)OVfwb6p^DqMMtMkXaGB!bbcY{N2iF zXnt^h{w%J`?|nOt%YyxJtR|=9dLA_4^EQc-Erfsewb=#4)AX8B+vs_O8MN; zo$KMVJw#7?H5P;?^d1(+ot>=j3G5wn*?PoLjB#qUVMU)>vmjUPO(#yLN(wQoJqQ%m z6Zpf*#yT@F{S()@UGaz3La*oN@Ni(zA`G%3vMKc_v(p;g1^FjbBh;?0*4k@Dz2ne@ z6gM2GwGf=x^RqLRe#=!FdEA19$QKEx4bA}#=7CB3$P`YHVtew{@hYm~Vd0VuS3J;R zJCAktf+{*X28E~^_7N>h^RY5Ro{DlEpPSOLiji!&MGVww}Hw0F-eKD}A z_t(N74>~MZJv{MBQPL7?1RS*=^bxoFdmv17W!^|F+liq&}5&kvJ;?Qiabr zqK-3IJ=Kz9{WTj-&6l-fT;B9%+WcrVr=`{8pS5@J+r^tsPEHsSzM+Y63xBhGGfNzc z0fmGe$0#gq){fscf+RHivk2Nz_T~pl+Ojg8lV&>a&#P?gPL>VQu$vbaT*IXJ^ejSz z^Km;9zXV2$&mqW8P#pyb7LRQ^wRW`scM&MY{K0l^)y*v4!`{rc8R-Pjot~ZL1Lp=B z8p{hX#F|o?eWw^{HU$n;*YJ7 zp$X$ly>q`hI$IHI*3K3ADAI^o{iAo+Pnz`OLK=oz|0%461NuNU3Y{N<|`J%*}4$iPXz%fu_s z`hfVvxB9Wl3VLB4v%RZvXEe3$2ZR22Dw57*TPs z^+p&iatp}J>`j-;zZdiLpIlD}DPan8n@5CsK-0>1VL2)D&9f?eg7vOewjZlg%c&&9 z$FtWDZ=G`)s;@B$(78QpS3B$SYMsb?soGk zG9y~oB*s6qv8DeS2du81U3A|bI_u;c!BB-Pao~Xtyjhx?T9ri!sAcy4)pAAlhj&XO zh!aL}C|o~!3+7DhI$@Fzj?+2$T=M5@Q)!0}_o8%*Q3khN8#dPZ(5H!Bn%A$YhsoY|{f&I|GS)xyZ>=m`nas*zz(Tq6_hQ z+nc+4Lq$QohtuBQ;j26TMR(_do1WFDMSzB}F)t6~dE;$)Z@|vL?^>fvP}ySCj4gxu zxM**$qgZ*4Y+1}In@RVp@Kl@U$x^a}UwSzP=FGgBk(rouqPwW!&1Az~(n@o$eQ0>b zg)+G%Do@~*UUgQgfb(ATJboF{uZg%eq)i04Z%wYQoNKL*xVGNc%LUtgAjYcJ+KB9w z-O~_{KbK~QLC?qAs*o6k!+yZTKoVqx8D;k>;yBvX*4y6UHltiEdeXTXg1}ErP{Iaw4uH!SXz{Nj>SGBfud}h|~R%1xT z+2dB%i0m1FHA{$-1^#p~n-M6G3CAj|6mLe4$YtV}`e+dn&`31oS_Knki46M|H-auQ zDLF$N8Mz@;zdsIgu1AH19r%%a7m(dGkUH;jc1E|0qM9a)veBtArV@} z&pJWu?r3Ov9nW%$1PizrZEg+>J2|@K>olu36t(#>5lA{3b97@*3`UN+lq;tMl^dW6 z5HxGaGPM@s=z?ICl}Ar|e|z2boEeI7n_~gWgN<@>1edZXhTdPYQ0`T~fv<$#UZvh2 z?nw@rG-yox&acCIafaHIt`(7FR6stKnravfpCa#KFC}T?Dh`6jzkGyO^9y2o98Pr8 z61S3jC87J;hb5sbR=J!mTA3MKM9g#0rRvC+FL75eL+!<$F*@PgT_=XCeIK zWBY3LiYO$Vb+2tMtp%qjnM7Cu48tI&aKN%G6UW|9$X33lY5pm4!zx77#1pS7+DYMI z8!@z{q-!7;zpxS;OSYb5abz95c=%_47jphhfwy8beivlRf|-#bQh-^ z<+z}R()5YRNV4hd(Ee};rJ};DY8;!4oL-LIHZsti?sEz5MXEl=w_f(24eZ1nSJMxl znuVv-%Hk#4aAnc?eM(}nQ@{A5;G)8CjNujX+@5Imj8&-)VXD&hnCH~aV3dW|)`7N2Wn$9CN+^%cIW zBzDLIp(S$nNp^b@yMVcQ9Cp<1d8dcDjE(nZ$hKW3WQ#BmzSN1LQkp(YL@h9#n0Vfc8AGdZl;60^^tT(!Hh z{E&QolP6``fSLLJc9GF&MO~#>UVPT?!=lx#-j_XSFz*K#;KqVLMC>qIWw-;uATED( z%~R1GZpzyHSDGuTVVF71pI^GhA6m>ydcKD)pj*kAx|-O$IOOJVb`b&bNUp4$8+Y&jBa1cS^FgjpF* z;U0|NtIho}rrmgIO>so@Gp(L2hQ|H2>R?!SdHH952RL8jDDRTn``PdShUOp&_q6V` zTP`ZL1x$V|LwY&kNkBw}948#B@T|bTQHYCl#FR8Q)u5E%FL~@_nrCSqN^RVKgZiRy@nRWIm55c^I9U7$DR*n8Xy>QTl?0*~Ijz^lKj zAk&7+m%%Jm>Zj%9tY~5hOPJm`noHp>6CX3b=oT5N6e=vEK;+vBat_rpIzbN0n?I!@ zz0CR@rH?;Ap3=U~GK{>3y=3-Xrc61umScu*?nmMik0U{b9z_4k5hSW7pp$kqdn6ZYTFEZ3nPI5OeB+vi9a}#$iCK^~> zb2`ndueU@@d_1~a7xu0B^Dp`ib&aU*cW?p4g)kj7KLhI$43E(^PeZh6D^=tbIHy_8 zE4G8k@y_zJ!gQ+uvjSq>=;e;Rd!` zcD8aj#CA+VYXzPuaw!?AJ|Uv>jLjms%GSKA%gSSktrEsL+8)uRpFc3Wm~1?dYB5N% zIL&c#gh|%3&(TW8m)XH1E*+y~3;NJ*I2^SGs7~2wTOr4&h zE3OR2HSzKis0}1q#REKNZ^=_q#Sy0g5(egdE{&gMC?Eq;oRQ&?A&TFM2Rm#LUjK7kj2~Sp| z!^@uMXewziQe9xw_=HgLN3#hxpkmP!mMLu)eEa#!|CgYGwFRfml31OzVDew0F*tgZ zWW{5Du8p@)#oTro?ag?B3ouR?UCQt+eVmQIovu&x{1{FhW7X2Hjf*U$c{jfH%%98Q z6!HirU}Bujrdk&aB(>Eu7=T*tZgC{pcQyDV%7z&01T5@-r3`#2ZWyD#t@JA8R%XXU zt_SfyTkWaQH%My@#ztSK!Bx!d49rQ{wXpFo2NZO-{JFie=9Z-P)b}?1Dsv$|-*ZC! zQO(^;J?*5LqWQ}LCC{PfWKd8n&kAF2B9N0aDZHbbUvsT&n-LP?e2UjEAp4 zeY7pKM6c~(lI2-&PK%|INtw5Ee;q%+U73RxGwZ&mlC_#$Pivx7NxI&SG`K@WcANOf zpE8SSkC->>tuG5+I&}a}$mlC;q zt0X8z>tJH6k*C3)zs)*#T5T}%`;~Tnx4+=bH-;Yar2x8pCL-qr>;Qy=Rh37|VVDY( zB2-*oIWz=uJin|;qIrMw`xS zkQWE`e?j6c>yuY*@!%Kb6lDrp8Zd1!VU0qg(G0ke!;|dnp(TIQu7`t3RbyVDSV*~G zDna_04!}w-hz5zL_ZAs)`2AdXcrd+|3LS#S@lGPRWx}sHy1I*=`&I2X0T>f^2A&>2 z}vE55d{I{t=bQ{}!BYZo!&re^o`&)P{P>@wzL|IS- z2Be6Ww*PxvCoh`dq4s@${p)`p<>t{V2FB{ZlLQ)iBWegzzhNGgn0ms)IVix2L|7>! z(Oup z7EzLZeo3s1$~VA-Cwsxfz?ptw)#eue7$7W`JvCa^B~NudL$b!bJ=Vq1(b=g-mqP5@ zQ4M#!BmduFOU5KB4X^rJHm>(p1SyR}v{4ud)UP=PADMv85wj$7rCIwzECxH(w8vI_sH{&q3`u{L06Q@@_dG zfk3=<&1@;Gj02Bat~7X#>Zsr(O)-YmX8Bz)R!&9?$~$$H6~ejOPo?cT3h9NrA7!Ts zt|V5Y!Wja}>=9WnqpGhZh&P~KRG$?W1QB^LjD|4UpStF>x>H;}g%8~P*87|C@oOOt z9d6m3!{8w77|^@4`X{$Xm9yLJt)mwCmyjOmNT+H#6-7jD6TJ>Eel5q-=_&#+*1fR6 zMjwQPXm!S1OM7+R+0CgqtG`Kieb9Cj`xq#}hiaNYOIm!HCu4(U$t9Q?)N@CK8TDl(Yj?LSy}hEf;AZMkJ#S|~w#wpN$ap)TOlX}7l*-d4T70?L*xt*P&KqaEIG)WSc1~KI_mdCt#QKyAU@tv?o6crvy;_<6E=ZH6)nQ-kF<*uznuXsT z{`XWbIqNmXXzFV0x)5b;BrMO5C^#j2PLsx0Z~(VMuHU57Q7VGE@?%vBk*p2~ZA;tc zdMyrQR7Lxen7B5rj4jE+V&ft0-i?N|!v?|jx5O4IL;)+@sn9z23&DbN6tyk!}WP{kT z4m?rJ<*1Z#a4jh_k@P)n8`ZwtHQW2{#!)}RX&YTl&2oPGaQy`P-8NMERFK`l_AO)^qC-a_5p8AJuNA2#0k+)N28y}HQV2RS(|HM z9G*a0+Bi6tAZ z_nr;j|2Igw_lz&IQY6&|UVaFN-XQ}n-gWy?C2%p6q6kcCx|4~Iep3&>Qqr;JRWbq$ zagtRUs#Ax@RL|De5Y^#B4`8)1Hm-#KJyY5d$Vj0rMx4y1lXLjwmekaCekVDi$gbP0 zSg2t_j&W^_G$3Mn?e@FdTz}p9l)s)Tm+}}!@P6axt7;*SLS$Fq={v@;!F6UAS9__< zoTjZx80gV zlzLmJi2?4KTr0Da#tR2yV9^hb<;}fr$Gd{FoMkmQ5sBFbcT)8a5};SWgTj!&^UviB zc5~fu`Y%hrf+OWI)zBu#rhQ<+}4Jyw6@ddyg~v(Lqnk}xlOZq zGF|YV4=zWDThl_Ggwa+TVpOUK_2*lR3o4qnTJWJs~AQufXQRLR=Dh8P-gs zSkY;>_dVvNGo_N5p3-u^wN{0D%Bq+yWe)Lwos8g4kb9|cf>6XV3-m6XuuQ!W9i~x8sY1T0b=ZY}?W_M!ie{Q*fHSJd z3Ew2<__iq7bBa(lKg(pDDns|}{=$@#Od=G$JSM$+me4PjK4bZn$xpN7g+QD)}a_2Hzh6#>SDIVbI=jCRL3$a0k?U zW(2&7sfdG;ilQ{BUNZs{1)9#PZ47tm+RMDbylEeNWLx}d;zUILnYvN^HW!2`k2HVL zI1`27ME5wl;S~%2!gGpg56CK>7qxn(`HIBvoKb zC3ElkaL465Xt|388V{7_;$Hk4xdN-)ihpvLxoUw+` zZq+39(cC4zh!Wv<4jQX@Uv%i{7ZZEm)U=l(Y;2sYK;Ze5sVqqz&$qIC4du9*Rgn>} z^LQjyM+Ly$%+bjXW@Yc>;3NUJGhKP#7^?50WwrRy%Z$d2ECA_qbt61t%qwclxA~^`&h1aNSWlJ=d9(Gu&@PKGS0fp<2$x%EqH|3-QDiMzzyOzu*oR}5L|t&SQ|l^3 z$HIDI;U(1z>T!tt4r>?rhOhC@}H(DK2FRj(R>UE}z}tjq+B zV)POnH&4u=tL`LX_X!^En4&IfAT_I)3?heJdPT}hn}+p0n-!Z{iS5^>7IJQaLCQ+w zy31SosKMA~PA=22hF0CP%K{KLxJ{MXlc|FRw;Fi8d}ZKwe)hC{cHrLZgOow0UMi~h zBOX|^1fS+8&-{IJxw<+-p&U5!AAupX%QPDB7qG@SpDtarDE?*B*Jb+ny7!Rhp!k3#gG*Rr@H8v}Jkl9|7*k6DidPjTDX-8U! zSe1S-zgH!0rpi2_b}%*kt9^Ax-i<0LuZzX+xd4v4T2Ron%3eVKqNw%8|JRR&P>%9$|tGx1C^$p^k^)^a>yW0ZGb!&*kInDhn$y#-S5n#w6>-o?kaX zQ)U`_2a~j5rb=a2MW$%LQa6w6!>e{Q?(W@Hy<0Eu+w7Xqe-qZpPdFcA4JqN$mrgu_ zqCu)gy>O##RX9HK(m^$zX&&)*%*TCNa)e>QDTxi)T&s+lBd^k$SRHIKvRdKai{SF0 zqv=cF&tkx%q_$F~(z#jPJ(p1^rEfPdlaoz0 zpz;X2cYxx@QGsK`0uFKswf4UhD+Tex6jz(8s)isQi3@B%ZkJ)BHWY!dmpmy7a0_$T z@Uhhxcm#iazToxqaDc+H(V?#ME?=bQ-e92jB{=WNpVULiZY(E%722?>{&nLHKf5}Z zpYjk?#sQ{xu`erN7SASrRKTn^>Po#yEA_;^ok~f==f4)s^A|0U^$KUDghH3f{Tpam z2*vF6OVA*bCAh@xR>O79(cRjn^0o6w?@bltlRdom6HnxmskkzLxa>=L!&?u2qN)MX zvqa<|q+020Yaj`|`Fk)`_+HH<$~?KXzrnV!AQ+ZGRKj5vOYx7KLHE_cx$l*AT@SQ* zp7SE#ohJ$y}6(E%DY+%gd}!m8{KGfhBYKUM}O* z-iKj^B+qcUadkp9>oY(Zq}TMA8h6GaFBwUVyDUH9kU1o$)A6=e+wHDsGb!hg`ZrIG z{lhYM@!HEg=MIi;_f@G%SvE)@p9YR|Ix=Cw@@{4H``kCWW6@U?dSj(2#(a);a&uf+ z0$v4o?z?l=-ePJCQ!Wa(`oH}i%ZEPCd)(fDO5QwjJ;bI{r{SG)WW z^w)~v#|i`jSz1Dv=bT(2Wfbp4`_?ac2*ick8Ed@`h56k$2Xb3$E0`B}% z8Dq>xS_<+h2U@zhy3+83yVU?inwHAxQb*+GQa0<%N56!KraGZRtN0xEJO7cU$IW|t z10Va%@v1>R$XHlhL!1(D0-~3v?+s1#g2adv^_sW^DXL5>O`iGlTbWR@Ei%124tSsV z;m0iEY>*{oeq`;4&Ya0eCI`lyvm*j|YBB#vuS1|GU{qFSliGlw-oq4osW!}nsm zivFA_SO^-qOREHg97;{S>$2Q4a$fd^pjs3@UL;&v8n39QuwQW!BkGp({`?Hwr|O?v zTIecfi9`QTq`_&2^#)E@8h$m62ZZu{(VoifmrXY^l&S2V>k+dh0)j+G=tB=okl>sijR~|vN<3PX7XyXcd5bB-;#jBT>JgtmW7q^!SZzs!7%dxbAV?wJ3hm4aCxfmNwLk+Hktl(LSX#%uCmLi$F zB9ZbJv$_m%BsCVTPCpa7Tq#+|)2iIIt}+7ODXs*CmD*AG=2vZE+xwS#50f zTIL^2>=_YLA5RAd|8b`S=Md}DGcg2|kFJs+bU(SB&54CXLJjXW73kUN)yD#U;M|fG z$kVBfg!zQv8@I~V$W~Gd>&KOJKM&Q|>+2MQ9-*lvuS-jiG~Aq(+KRMh=4!T_)PMly zpMbP6KvDDbP)oN&MSc}|gXTZUU-4!(f6CIIr0mM0)NvdCO8$}Abw@TC5F>h~(0L}5 zKt^Dtl#u8cT7P+p(7r!@KitVHX%mExq-?ZZNrXygHTMQEQ>6=}H}y|FqN}j<^h|Uc z%2p!CsRBa7@Df^YF{2#|8Z?+LIpQ}Z=1QvZ>lr=e3AN&!kN8V%DWLwVeTG#s4dk^_O6YC3iAQHrMGPMZ@=U-sGM7A z>Z3&IO;mM%E&3_~Bl+#e-Oq`F>~`gL$GWCxbA}FW9%6`;dI!RMmnWyADBNogdnx$~ zj=2CjQ#QP`C)F$+`Efm7$?XEf+<&CGg+GRqx8q9Ee`}EGGX|44QQ`+pPa#U-;`M1h z!g41X#Sm5OS$hX5?d+H_TpX3v-otQy;(GPJ!Mg9SUX5@y10C|5)FTyt$u=1)L;{IW*StPHq( zN|9Q!xhvA3W;x!Uw?~%_6q8cQq>#DW0!J}jenpTKCl`^;q6|dkARR>Z>xRmyIsViV zAm}Sunckgt^w3$3zV!E}p(_E2B?b^k<;g)3%Gt=9H=Wqv3|VKn$Xi8d$Jnr5VWvTQ zsOz?h01&jimf-icT02neVpI1V)H;WMcG?%SJD3&JXG?=xK%A(PT{F$%^CfsY^~B3Z4N`=qt1 zZLmT_dU*fO62Z=i1l%pQ26KZ%P*-O(3Bs7lL{(0-L@7S8JG_|Ew`Tr^3 zYH9zce5(nqZ*KV0*wkj+CYb!FNWR?2A-IHu!!((PtGee%`$)%=d%JvgCOZ#qr|_k@ zMRSU?DxCQ;vgFe9I<)#rv=z(lJ1k?V_%At1O57<~O&vykFTeG_;M1$ovh2;NacCk{ zB++nr_Wu=cfC(SoIGm>W1=rZPhW7Xb*K;-HeLXQ-*bQPS&jg)7Zi} z`XK5n^GE$~?C>$C_+H_o2G1nVe|eLccQy{U!Y6xtyaex$@4iN?(|cyLGHg(J1&`o# zS65SgLyH1ecIKh2&9H*v{pb*{K6DcCPk-utQb;YGm%4l0&x!jSI7_V+@R_sqsWW-6 z;KLKZjJ_8LSW9##qO8@(-E>{lbY$@7N6>#C76t1oeHC1Wm2V7q&$3@R#{* zo=j;Zyi8;uIkYCKQ~$TVuwtL4yNz z<|S0mH}zg=>{^10cYI<--!+2cYrZZNq2W+SrK--G(9OSaSpw}tM9rC3vQ z&-!O^7e9MBMl6;I2Z-ltYATnyvd?A{XJ*Ng3v|ePB|bUK(WY@-Qbr#hH?-u(ATK#S z6)H7mBvqdcKrz3}!v2G_hPAb?cb%Ip5NGayJNslDqD7o>FuG4LK-DhT(G8W>W%5oD zSjB=+|9$V8DPOU#*hb{B_^z+vn>k7{9j^(rfW_xW;;<=-W!(ADVpQ4F%6U(naJOVP z=ou`CUV|YPZ7T8`dj)2+hALKB$$lh6i=xo1SvXIHc4K@c~+A8SN>~inwyc?cDgR3 zj?x*f)I++YQA04f+NdP${MHk$Swc~755a1bnf;r`H8;}XaXR(C28^9cz8BDRg${$- zyzL!=gL0~NzKj2j#C8TEm$U>7-nv8lt9Sm1h`kp`D`x%(f!Q`h^93bLGX^wSFW8qr zXhS^{iIelP8muDf4nGE9O0}B$YZgYnj5}1l1*Fb%on?7KrE$h$L}O!?e=fIP%;Mo3 zRexg+54bZ&dYevw_`-BNzQWJOORByWu9oZ#R&?3fk@-K~;32lDsZJmxZEro7*v6D(Nz|jPcpz(ES_r5fNMnlp)1POHXV-X(+l@3&L zcaApQ{a$`}a4@&l5uD^O4lIH%Zp$L4RX#(($N!;@y16%SEF7Brw_J?4;``5huwlQs zYrWWP&^YAm-?WTv6vkZnLI-@~mzcvqTFu##&WF2s$F$q6ih>Dr4ADMsXb;EL)s-u? zSUUGKh>cRWA+aqD9B5YLGIwZHE$(q78>7L^fWHnfPoHE(ybx9C2_yma*cs5`lYpao z-GU@}K!e=XOvvBdni_U=TQp*bRC)3zg|fzq54N^kB=bA>2*ULgd^vAnsrSLB>*7Lo zleJmY>L33cb5#Iq$KjTCb^w_#;j)fka+)e-(iB<#^qkj|9viNxBM-3A<54@3pTnJW zB|$0Q8=_+_N-cG-=D{`K%n&4uM$*eJFo14N`3Ucr=cC zJ=PEqu_O77N>t2F8{eL9mV^Mo7s?NC6otglKy*dmgU;Hd7L~HX)P7gFON5J=ABZF0 z{^24H&Rl=j3cTaiV39~dUFOQ>w~{@imO*#5XRs?qFu8M9joi%n=LR4d^Z(!jSHtO3 z*Q{OjHfFG%#XIHocEx%kWGEI1fgJpuj+DN75u43aVYb||ERR-@4^*Czn;Vo9CtXoM z8BC1se-n{ku}#gr@nlVBmKyoXhmI+J+N| zZt(lFg&kT}WXB7x;vfTCamIOe)Sf9<>)L6K)qYcTIR>0ZjiHxvS}+Wi*1D6A6+3%ZM6U!6Q^7!S|ORN zxmmZ;5Upvgc?WZfi&_va&mdLtqs7*sd_+P`lGV@}guDa$vjTNkGdEk|D@;C3Z00wb zUi=C@)sHc~pYTh-E+g@$)@y_*ih1mDdw-vszk7G5_7~YGZ_r2@BzKz zfU7dO9weqU5wNAVJ**uOXX^q+06^iltfJWdu<1t&?@6;l0i(GCAhz&F5P`#YnW>&A zV2z_&5bp~j&ZP(qnxh|gZD$sI~lJd(EG+h zN~*sq4j5AI5+tK{6ZTt^0Mvhcm|s66VGSX1)4IC7{h6qJtJ{neHY`4qF^&vOjV9I~{4)wvb#r8MroU-|@Wo-yugC&zxy^K3!Q0K*~0EHabY!yO! z+2%^aR6Z)OFhfP4nyRrYXn~;~w$ZHYmk%cT#uf6n0VbCJD|guGU4w%mYQFFkSG9Am zt!&{`2QQwNrjan>Ipi>x=y-x1*^7)Q#lKO*Xl-uNiL5)vhU1Y< zc&i!>y#kW8R2w1wH-$}(pWo`Th+Qdv{?tik0+qv6T*=eyZ4bQN&ZH)@IUjyp&lp16r_%BLoriVXh`N7B+n#dOSV2qee5d5)ikP-OMgg)iv*K)Ao{et9_tw zEySohiVaT`nEh3VM`*m==HEn+m>9rmEX|7I(ZK|h%a^S~jc&{|iQ0*VA)Y=mVeO0!g=9yj4dFyr~HbG8W@5fy{o$!9I3{&wr@d|}p5S$Lkm{YQ1J`8xT zV&k|;9%YxR-YnKh!b^`J)^M--6jU*rC|(#y`yLdVg3T~vMT#}nZ(X`qm#N2yegwj9 z(!EinMRjwO`ut>EH#du`7lg6eyn0#2-ilRSwv7%3*xyNL-pm6}t*EbfDa@S+|M*J@ zINx&8#7JW?QS6I#GGKPj9DuQwoRPL0DphE)0V!pxSog5X5=x!i0zt;|R4c@&sm&Tk zsRQ`}r7=bzb1FMbgz5gjo~AF8K&&rrb11ZY$DWc6S!g5LL)1)Y2^1l^^Rg%Dg^&B? z{cWt}6?!IUEMPrOl~B7+j5neRU3BV3vPlcK;}6-m2RL{yEo zq=!+`%n^@{Z5v1FQlF{x91>zB(iqDzG5bm(PaPLS90|pVm>caGR&=ZCB)BtCy!teL zXlz1}1np~_M))n{WuA*w!qlSLAbC1)L3kgjyXbhVj&Y6JIIra@dqQdq_OF3bWtX-R zrVI`