From ea0703524f1a508b4c60c7a3ea5b5da3c40bca2f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 12 Mar 2012 18:20:16 +0000 Subject: [PATCH] image: Support SRC compositing with in the inline span-compositor Signed-off-by: Chris Wilson --- src/cairo-image-compositor.c | 106 ++++++++++++++++-- test/reference/operator-source.argb32.ref.png | Bin 5630 -> 5625 bytes test/reference/operator-source.rgb24.ref.png | Bin 4000 -> 3967 bytes 3 files changed, 96 insertions(+), 10 deletions(-) diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index 8db825028..990226a0f 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -2260,6 +2260,89 @@ _inplace_spans (void *abstract_renderer, return CAIRO_STATUS_SUCCESS; } +static cairo_status_t +_inplace_src_spans (void *abstract_renderer, + int y, int h, + const cairo_half_open_span_t *spans, + unsigned num_spans) +{ + cairo_image_span_renderer_t *r = abstract_renderer; + uint8_t *mask; + int x0, y0; + + if (num_spans == 0) + return CAIRO_STATUS_SUCCESS; + + x0 = r->composite->unbounded.x; + y0 = r->u.composite.mask_y; + r->u.composite.mask_y = y + h; + if (y != y0) { + pixman_image_composite32 (PIXMAN_OP_CLEAR, r->src, NULL, r->u.composite.dst, + 0, 0, + 0, 0, + x0, y0, + r->composite->unbounded.width, y - y0); + } + + mask = (uint8_t *)pixman_image_get_data (r->mask); + if (spans[0].x != x0) { + memset(mask, 0, spans[0].x - x0); + mask += spans[0].x - x0; + } + do { + int len = spans[1].x - spans[0].x; + *mask++ = spans[0].coverage; + if (len > 1) { + memset (mask, spans[0].coverage, --len); + mask += len; + } + spans++; + } while (--num_spans > 1); + if (spans[0].x-x0 != r->composite->unbounded.width) + memset(mask, 0, r->composite->unbounded.width+x0 - spans[0].x); + +#if PIXMAN_HAS_OP_LERP + pixman_image_composite32 (PIXMAN_OP_LERP_SRC, r->src, r->mask, r->u.composite.dst, + x0 + r->u.composite.src_x, + y + r->u.composite.src_y, + 0, 0, + x0, y, + r->composite->unbounded.width, h); +#else + pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, r->mask, NULL, r->u.composite.dst, + 0, 0, + 0, 0, + x0, y, + r->composite->unbounded.width, h); + pixman_image_composite32 (PIXMAN_OP_ADD, r->src, r->mask, r->u.composite.dst, + x0 + r->u.composite.src_x, + y + r->u.composite.src_y, + 0, 0, + x0, y, + r->composite->unbounded.width, h); +#endif + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_inplace_src_finish (void *abstract_renderer) +{ + cairo_image_span_renderer_t *r = abstract_renderer; + int y0 = r->u.composite.mask_y; + int y1 = r->composite->unbounded.y + r->composite->unbounded.height; + + if (y0 != y1) { + pixman_image_composite32 (PIXMAN_OP_CLEAR, r->src, NULL, r->u.composite.dst, + 0, 0, + 0, 0, + r->composite->unbounded.x, y0, + r->composite->unbounded.width, y1 - y0); + } + + return CAIRO_STATUS_SUCCESS; +} + static cairo_int_status_t inplace_renderer_init (cairo_image_span_renderer_t *r, const cairo_composite_rectangles_t *composite, @@ -2350,6 +2433,7 @@ inplace_renderer_init (cairo_image_span_renderer_t *r, } if (r->base.render_rows == NULL) { unsigned int width; + const cairo_pattern_t *src = &composite->source_pattern.base; if (r->op != 0xff) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -2357,25 +2441,29 @@ inplace_renderer_init (cairo_image_span_renderer_t *r, if (composite->is_bounded == 0) return CAIRO_INT_STATUS_UNSUPPORTED; + width = (composite->bounded.width + 3) & ~3; + r->base.render_rows = _inplace_spans; if (dst->base.is_clear && (composite->op == CAIRO_OPERATOR_SOURCE || composite->op == CAIRO_OPERATOR_OVER || composite->op == CAIRO_OPERATOR_ADD)) { r->op = PIXMAN_OP_SRC; + } else if (composite->op == CAIRO_OPERATOR_SOURCE) { + r->base.render_rows = _inplace_src_spans; + r->base.finish = _inplace_src_finish; + r->u.composite.mask_y = r->composite->unbounded.y; + width = (composite->unbounded.width + 3) & ~3; + } else if (composite->op == CAIRO_OPERATOR_CLEAR) { + r->op = PIXMAN_OP_OUT_REVERSE; + src = NULL; } else { - if (composite->op == CAIRO_OPERATOR_SOURCE || - composite->op == CAIRO_OPERATOR_CLEAR) - return CAIRO_INT_STATUS_UNSUPPORTED; - r->op = _pixman_operator (composite->op); } - width = (composite->bounded.width + 3) & ~3; if (width > sizeof (r->buf)) return CAIRO_INT_STATUS_UNSUPPORTED; - r->src = _pixman_image_for_pattern (dst, - &composite->source_pattern.base, FALSE, + r->src = _pixman_image_for_pattern (dst, src, FALSE, &composite->bounded, &composite->source_sample_area, &r->u.composite.src_x, &r->u.composite.src_y); @@ -2384,8 +2472,7 @@ inplace_renderer_init (cairo_image_span_renderer_t *r, /* Create an effectively unbounded mask by repeating the single line */ r->mask = pixman_image_create_bits (PIXMAN_a8, - composite->bounded.width, - composite->bounded.height, + width, composite->unbounded.height, (uint32_t *)r->buf, 0); if (unlikely (r->mask == NULL)) { pixman_image_unref (r->src); @@ -2393,7 +2480,6 @@ inplace_renderer_init (cairo_image_span_renderer_t *r, } r->u.composite.dst = dst->pixman_image; - r->base.render_rows = _inplace_spans; } r->bpp = PIXMAN_FORMAT_BPP(dst->pixman_format); diff --git a/test/reference/operator-source.argb32.ref.png b/test/reference/operator-source.argb32.ref.png index ca3d18c6d2a6a997c976760ffe92716055bbcca8..87e7374180836b8fda88ee97df3c236da84c04a1 100644 GIT binary patch delta 5621 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≫W!1EL4MP^3}gbk}gk$?2})?6z+ER_y-(s0TtVdmccvR)R$3JKGg~>8mAb==BkRWS;1XMs#C?bMw z)oQEOic2kS1zb>D!0S>8Xti2JN^5N`-d?W=Vzq$aRwST;VF@HG3Sr4MNoKOm`rbdz z%y8z+nI#dgPkr)xo_TU|=AF;{-tU}u`@O$&pxe6bbeeSPP=720G5|;TmC>KWIp?rH zCy3rwL6NzdzIMQp03{{jIB}VJaZ(DQvz?%zpqb2GUE%cSaLynqvwfJ%`xtCJK|w}W zIDi*u1Z=>$Kw&D5L2%_`C-=zL|@T+|4s*>|$8YbU45PU^Pfpu|>of zpcJ?;5kz@K-2yn4aNh;AyKSplmkN#JBo^T6LA#&Xo>{5 zEp#-mVb=O&9Ks?Aq@Zv*g(xi*;CzmX->U?euvu{~Xw&1yNp6(~r};w15*s z64p*(AAd5@KZy^5MB8@s7o7eDBhDR8xjh}uAGx{jEv)#d7ANe_*(4B2dHg(coOkft zty&ylJ4kgRCr7Y#D-0YM??_b@j2nmKYM2PDS979Q&Xv4wDd0p=JVDzg@R6|($6A37 z<@qsu>K{(IEnUt{{HZ#V<{C98>`#Bv5DDHt{0SX(53!a`WI z2;gJnzAT0l73zn);Uwk?OKuW^q3n({i70d$?~2ZFbcE>5@#AXF6}*`Rw2+2KfJaBL zIg6%)Y7S5zJ(@Kuxihn70g?cAsX5V6&xxxo-O4E{*-C6bM;>)u;j|GuI*~yry{OOr&aEy6B&Yx%{_cG)QK%}mgYywH_VpzSxVF1b*eylT`5IU;qiw0*G z&`kOwwKS1sQ*(e*gHBCNa%XC403iW+YED$Bxjc2ihv}1aD_G9(+G_f`6wU&$lG!Ic zIF6^wd5gDixbno^yc`-ZP$$hIS<44CLVMMzWV9H$hF2TCsb+$LB-cWY`mNK=Oew(9jT| zqy&~Og*|(~=ac^~T}r5Ad~m7jrZs?5i=#O@)scHq2JTW5zL;5aE%}v?^6={4b7w85 z)=l9xlyt3{Q^mjmy*N3w2Q4wZXnzGoZFlob>jtKn)8*t-dwvFPvr?qjxW@M@o<8#= zz51rZi8etbRjUy>!1=(yL>vPemPh?&5a<7%I|udW@VO1-*w!$s@eO|HRe(}jAqNhE z_|q?Vv0wlP3+l+TZD5MDgHfg~aH@aE8+rNEW*y}W^EQgDb>!tB|Jdr0E`NbZeh}uc zFlOXMaZdPUO~%m_Dh&1BiKqll61(#5q)FZv5hsAwugiG@QHQ+pcOZ8UY0uY`obaHm zL+%bKgNuw{=@rEop=^!Esk2ivRH(%?M{2mH_(Q<#bi3WYF&< zM=6y1S?((C!?C_TOeP;Dvwt6>xq>49GUhdc99p@G|FKQt1L43EJVHPH7S7`xE>*6A z-M6va)|YCZ7qi=k$?L=9siM&HHkb8@a7Odl(PFl_9C$)U=$Bp2@H6%@q)=%1(}6|T zj#X;MN;$**E4alI;hfLE>&Eb@%Z#_}00V718QJ$B1BNQ=1snvttADum5nqpNv;Wd7 z%oUcA{$+p7m+K|LRmRn}NxqF@4$of?oC%xY;i%X6E{640ZUHJJcZl@E& z`t=MSC=Iv2KJooFS~({y?tJ7JI`WSaH8J5BeSUY0J~hQ`TYrtJ!+VRFlSlJuK{4CP ztLbZroR<)ei+RtoktvbRbHYwWj;Ww1crB~i)to1}zx7hy>6pMrW1Gp$QE~=Rd3-;E z2Shm4^j&gS`=X4u9}(kfx}wD7S$?z>L>NY?y)^8jRC;r~g70Zx4r798r0Z*vKWy;%+nE zfQ>f4nq#MxyLh(cC;YvqBD50a?B|@`Dt|mi{OYg?4m{FqR&p(?Y-$cbJ-O~5r1F+2ZvWsWPkNxGWszZOSyNOgs>P0=*lRm zCUqFbW1%B3j;%e`GgaS##n^#Gzl8hRbc7@e9qeUDNbR&1$3Vb6h{}S`7(Jm4Td);- z;4vO*2w-S2;|-QG+?WmrS*Y5IU4ff?A%oHH$5>j*Hc7%_FrX_dBW1nfgbJc>c9U_q z9jmzmi+{Ndo2ws3%m5AKxFUt`;JJcQ?j0tOB!MI;wp=_`+5-U$-gcb&)l0cGjRYCoU2(s8Q&5?xZPPz6iM!KLk>g6BFSy z;tyD9kL;{O<34Y5*@0#<>t?gED004;%%(~P)w*!1E`7;sr!|m8QygbELtRHXBQTql zk^almfu*&c+zvMx0X4^j&ts?6t>)}waDUT22Dkix)yE>|gXlYam~`z}B}tAjL^+)5 zqhjmzHV2xUshd5UBE@+hU<$vY78Bvr6AamC)7+JPg&STO&nLyNb7gT)YB~Uqj*w>* zJM^f`h(F}SrOA1ehfiL|-;9s&8*dL<+!4-T_BEb zIi64YgNrQF{y&%wkREeJnAZ7fwu*qJMp`95NNK2;hA#)IY{UnH#wzPm42xFKXuU)V3RVl^lg&{ekJo3tg>I??d1zkir>v5s_q0oKO*~qOhiv zdn?01GRL*7>NAgJy+`v|Oaw5IP!ZeAMaDbw=6%~mz(tjkx zOG=K?(#zp=X$qAv`?nLO&Y3)&oKA@pK2GdUdO4h${+te>JZk7^;&eqMj|S(IrIo{} z?N5rCd0N)l?VxlyT@@*@Kk4Ui#`$wPt|+Yp)6>D}ib(FH{(q#E!>R4h>1ukXW8I|Y zbVVeO2IrKem&2*)PfDR`$=`K?g1t$KB){ClwvWN?a)!5df}<(GZid#BQPQYBuQ*QZ zk0OV&ww7HdPH?JTRaNTFJcg4{C=ZTJE4bx`p480g&GCEZv-H zp824NitQu#Vt>zNy#3|-T&UIACT)7h>Am+CytsK7yY`G@Yt8rgJoo~)3p&&E8XEAF zT(W7!)f;Z;*^@cFdvovnn;L#ywP0mAB_-fe?lC0D;Z)39*42?$non&78o{kQcy8n` z`NPa2Du&1au>wV|qhcOaS;e5OgV^uU;!I&f?tGSJPk&{-A%TsDTI9QC#W3nf?&br9YLQrmOf zvGY0ZICLLN#{7~$Oeg-=s|Gepa1bgJayBr94NURPWNr2Wp0H_fz5rHBupjm(tT1ar8h!OxEB$sZnlWqIgsif3_1JL71C39tCoQQ{5j)R*iB(D~D6dv__C* z`I4RCbj7qd>CMW&ra!5K()!Z8&VES(PG_wn0e?qphJM=p>B<$=75lmzWynQ~t-h)> zEfV3BT&#$DFFRYrMmS^bKS3y^NMEn%<>bKDtx%}JDJz3<gv$qXx&ZK6;7hi zN`GfLT9%a4m4y6sawgT*=QMG&MCuAh%aU@sB2=n!-z2AVq2JT!&;M7`J6)V_zv&62 zxL}%um`M5^e1x+=H>S?sEXo%;Olt5!#8flbsy5>>e zLeF38e5m>Fl`o8XL7Hno-W_66%}iP}A+W)gpZ({(PHFFBK>4rl%6= z8}TP9l=d1&LLCXz>fli%yh@r$8k(HA4jx5lMFNdbt|q5ggVTkC*Z3KHYEHLxTYp!r z`!4k~Im(@4k3gC$kZuu3*9fHPKj+Vp=askt&m5lj3nU`1Wp#hg1Eg316Gik#L1mSsceeAcmtS*jY~GZZ2hRfkz<4 zOdkRmT9R=D2;p>!Ip^)TSjm|;>C@{)cD6{Co*C2h)NdN`N0fIX3l*~-lz(FKxx3EM z5lY61MmTkZ5=}zgfG3DP(S%gCoE#`C!&p2j)}L`>Iw&gxr!!JgV+SZ|V!~6*ozRNi z){fQIfyFk1b))mC%@3m22hkgLF|2JZGg|@}Yyk|mHf+|-Tx3BNQJl@nKCReo9awB$ z%(j`VwVlaVh5!b=50jyc5`V`=F6k9QXA7dY`7k*u88k@Ed4by}yU8$maF|-?VVuZ^ zJ)OAp?O1*7SpAJ*7qh7qyZtN99HZtSH#O^HGs}M5F`~peX%a(oa>xw? zFa!b^_U)r%(K0J{$BN@*V9nlpLi{BT$V9dl_w}V>J6QTAIi*J)r;BKfyH!;KE^5vEfJ2J4EwuGJ4?-}qVUQFa(|?Ha`pA(8nS4zO9-in ztdN_G;C{}bf+DM%45@`4`bM&?C+Rg=%|X7A+ProC>vws+f2Gywq`$#Hme-5P@5fkM zi~qm@y#5cim>*ns-Ydw-W;2zXn1!%PLvmpaK2hLaKUxgajIU+nR4qzRac#gaEdJ8RV62BvTG*p z$TM?2fZL2WW?~ke9;A$0XVaLJ6P_Muabo64R@!6!_kUrEnJRq5#O4GX*}@Ud%=cEu z`m_06uPTQ#q~;`zM`h9!xiJR-EA258#jsE*gJ8MT$8c=4Wg%bQsW>t7B!_%!e^lfE zhM=;{Tg)&e;Do;?9O3-)4|)O7?E4#EoA%6&G+wVL8t0E%s6(epN|K${2IU6=7+fA4 zwE{^Bp>xwUlc`<`L@XM74xy7WaJyBU))N%?L+GR+dfjn)>k@DxkMC{?qHoQlxf#VX zRGP>Ntz(AwfBBLBWo|Se-#DG(hZ7R03vvsSv^d>4oN02pb2z)L+rAb1KbzY# UnlO%>XaE2J07*qoM6N<$f;VvZ!T}K>TG(3@CI3MJ7)@1=m9S* zz@Bm%e}wg4l{D?<{S{nG9d(kWJK0^&TB~m-NlmBeDc*lrpjue^F}qu`Qo7b+u7x2C zA!uOf>+JqAD}Mz|@IHbTEQQ@zQK{DZ5h#C0@GU-YGMsTx9M?Zm`wstL0)GU`B7&Rv zAkRb%;W|X^IU7pXN-&)Arf>A%+D~nR4Fy5?0FxHDpcWIAXZ#UbM(|B5Z-9&VTfDH8 zdeffJRD#u3-hh1Kn|NW06{TyLy@en`{0BCa?oDG@D}OE3cJJ028?}xOt+7$ty<008 zr}6?OD%E-$k8=8PI?T09#V4#@$H&H5u7ex@p3^h4QrB7iwuw5*>E(2oy`?rTviiSF z6r6?*&F`n7fwD45=Grw@tZ;NMK&FzdHUt%n}67D<*% zRI>HHB&Lm2$6*{_GQm&>=*WT6aCFGj6=HoOd4CJz7?3H5C4b+(ZLM_sHaL)}q`j}{ z58%pP(WA_7$7$37pr8JmBT+Y)KOj>b^dHBSy#d>ppO7i&N7p)Z$Xe;pA()R$r3MD| zCphBvwTzMfQ=Snjkfi>EW5}KwBL7cT)P5X2_TKu)Z?&S5UFfb|G&N-^UAq>m`BzL- z%6}f85qlnI!m5^W@_tD5=adT7NXGvX`v9lKs0Tyj9iqC;in>bd4V-<}-tvM}t5y`m zz?takV)=6R?BU`?VlggWWY3=X@`@jJS7M?vd%j9syI}?ChCGRXC#&iyGbVfbtnXQo znvUx!cvzrX@PEvzmXWAcFphZ2+gJEoS$`GHN+nNG#8b@=tFWS+GRbk`6?mrLFT(@g zCj4#qp-}!7GvgNVH}NR=OYwlW8-F-A>K2|t{DpXi@J8^*bD$s&9`J()yx_;4%CrZ7 z+6Hap!7xNe5=&EI2;Vt12!nS{0pvhg+SB=v&93aK_c-++?xV2I)=e8ZX3+N>m4BJ7 z+lQII52)PjS@QQfm9iIlmgaAxf*U;GX=eICz7IIis;GN{Mjw$@X4JFtBQ_W_>Cj^| zmk3l3)6W~!TdtZZRJs)o=E z>Mw9p=wsCr&CcS3N5X)^L6!5^6MylB7m2_OScyTUTkkn8J&fAGRB(a29}k2S1`o6S zQLZ0k)BjLDk|9FiK|yN* zYJjOxTv6QZcpy~B;6JgwnCmCmber;gLXWa@BDIa_*1H7i%yH%X>?cfoxPSjbm?Jk8 z#d-Mf!biQ{gKIw{QVt>53AH+t>RMJG;qqllUgUA{sy)Da>$p@wZ9CKT5(nefaiWeV zb!rQjJ1IFLQ&qe-n@ev}J0MWAI1x0c54e1el3&Qw-}2rxF6|R280X_euR+0OC?TVU z2cB5BZgNG%x%T#g6a^>XNq_0&gapLIv9gHRa|E{Wypab1Xi!IG7RpU*F@eK8KOj>< zff^*C%9MxLV+7unDWEs2R#B1bx#wnW+jhFWy&DwLQJHyiLSjAbZ&D8~aP4QAivl-^ zMjo=CAA}(>oAzph`iy1y6y%fmDk~Ksv55AcQXj=Ni0dPkLBRlt)_;+-p#9C-=g2Pr z*Z%#Vxm*QqcV1&-t31O_hh(ppye9I&1)c%a$*4dt!}{0xHw4~dA2`4)duydU@t;mko*`f70)1Q5o#C)4Qc{`N$lysIeXhB}nxr->@0?)ue z_vFbQptrZ%a1p@J%73sI0_}6$uQA>@gB^NDH-pv|e86GmJwk0I!GpXkQf;`8o2c=$ z_TdArFmFG#(+U2SKntiW3Xrj>yy?iKtBV zLL0@C3~HEI0(Ts@npLZ*sj0cSW6PF#MoA3Z2wGysFl@l-*vZ1*QGW~Nb=LHQ1MLy% z=Ds!cF$@2i`aYCXtcigG?OQSxVOTX$pR;fd^%GG#Su+fv4dbK4ugd$Q9E6Qi$Kg{~FKy2mhv1Tc8t;n5ahxt>?U- zz5$9n#C!1{=b5tx_0Mn<{@X;2CsfS&D1Cht#fXC+p247u$fO_y=b;aZkSWXCux4JF zg0lo?ClhWn85G!>3#H&J#2H~i|D8|{oElD;z@1Rw#D7FtXY1zPxecWaFAUpv+!jh$=+$y12qDbU28dkjqIIFeHeBKlo7LFBPI$0u-90fO;eIRlHb7W zU$glzYeA{v%uBpo!52bvXWG-Fh1tj1e1)~3lyjz%x2Fk|*`6N9nEh)u|BZHa`6_j)5^BCo~bnod*M+zOj9{}3)^XBTU*c6vYWMJ zuYc$$A}ns@;w>yw=@?;cU7|+OdZAG{Oj9{}3)yL9TU*c68r{h`ipgG@%F$a`rqYpZ zZ9P-V*4{Bnk1@ffqPDGfgVGx#QD!G!QhJpMHYcY^%UD}KcI^DIW0#VJ*RBa&OPaE{ z_CCb>E2cIu36vGYe$LgWxh3qkZn~>@1Ak0yWfCY46I;X8xi*w&;B&l3nfeuzK=Bcq z%2g+~EHJw0YE$=-+XDz1|h!H|AX14CApWCxg4WEf{EBqOnZKxKM zcUf1);zi!7XnN))eS|zO%M3kRcXUfTwUQDcTTh4GoO48#u~O0WK@v6c z$?5lV>QtuIsZ*4envYGdt&1b0#$NfLjO)0-041tMrfPDd0_>IhlAI__`+u!eL&v9< zl(>AECG48wE>NcCx|>=#KDLu(y?d;bsV}*kS~=RY+j|!%s~qpHY5o5=IW<)1z<6WE zk=fHob9M&-eWOOEYBGBoiK;QE0BV?yknx_)4w+ib4$-Y@P#9YJeNKmCja0*{F9`QJ z!JtMrtdHpnHZ_;+ux_2v>VHqdGfgU7zFf%G)70pO^)X%jR`-jfj}W|BXgPrHZtzKk zlD9N9I(uWf`m^^XvbV8n-HRuuYDJAsD{0R(Ta$9(jGiX7t0pT|V?&v4El8AVLzyBY zThEbt5cg4hBTvGA1My=GQa@Gv5(4lAG;d{3s=STK#%7YLfz(gAKz}V^PpW)}i4wK` zQlP5Y^9MKx2Vj?pk}I61V2@BPQFe3AL7_zM$)p%76@`RA#ZXh7YX9BPO24-*mq&!& zd(gh3W1{qoHX%@P22%ru$zGDuKr1b+nm;o|ZC$ZQD=D#DKTp}S{BCq!Tp!K&kkM1A zY&{`RaiS@{-%d-<)_=b}C9Sn^u8^%uR61KXEQg-2thtL&obu-m3p~~?^B)> zGw9g@HJ=-$2K6;_nha_P-%Xi%0yTkm2yX&!B{xb54Uj*GvxzwusnmDH@O8)(sNh{+ z{vD>3Z{ED5tZZVkhG!#3j`Y*gRd=NYd)s2(N;?Ws=$>U*4-O;B&iYgs8M25;S!Hm>w<-(In(b>wQ{kS`Fw9~lDSe55~=IW`~>nCwNlrfXKV63paLi? zV`w}M{k@q^#(&>rlD;c~?;WZ^f$!+l5`ijZsKB5ijPEt5IKFc-RgF7_Cr&|}!eWNN z5yhqA?qz%*lk{CGzJ8g~-&ESVY8?xfmX*yKKi-$DVQ2j2O_dAR4%D9k9|D!0MuG#vnQ2pb#4j(?3tl`!tYj-X-vUMKi4eNshQ>)dIUZ!@xWiL$ddC>$gX&|20!GFM8>XcGb@4(l-+tz@>| z-3ZC&bY~7U{P_T>Y+a(#_JYDE3@~07*qo IM6N<$g7+Sl0RR91 delta 3984 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