From 15c9969abedf51d091e1b8b6346db4027a2a1d8b Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Fri, 4 Dec 2015 12:52:45 -0600 Subject: [PATCH] Adds transfer function support for SMask. --- src/core/evaluator.js | 19 ++++++++++++++++++- src/display/canvas.js | 21 ++++++++++++--------- test/pdfs/.gitignore | 1 + test/pdfs/issue5044.pdf | Bin 0 -> 24214 bytes test/test_manifest.json | 7 +++++++ 5 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 test/pdfs/issue5044.pdf diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 6d61fea1d..05bf061df 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -20,7 +20,8 @@ stdFontMap, symbolsFonts, getTilingPatternIR, warn, Util, Promise, RefSetCache, isRef, TextRenderingMode, IdentityToUnicodeMap, OPS, UNSUPPORTED_FEATURES, NormalizedUnicodes, IDENTITY_MATRIX, - reverseIfRtl, createPromiseCapability, ToUnicodeMap, getFontType */ + reverseIfRtl, createPromiseCapability, ToUnicodeMap, getFontType, + isPDFFunction, PDFFunction */ 'use strict'; @@ -274,6 +275,22 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { subtype: smask.get('S').name, backdrop: smask.get('BC') }; + + // The SMask might have a alpha/luminosity value transfer function -- + // we will build a map of integer values in range 0..255 to be fast. + var transferObj = smask.get('TR'); + if (isPDFFunction(transferObj)) { + var transferFn = PDFFunction.parse(this.xref, transferObj); + var transferMap = new Uint8Array(256); + var tmp = new Float32Array(1); + for (var i = 0; i < 255; i++) { + tmp[0] = i / 255; + transferFn(tmp, 0, tmp, 0); + transferMap[i] = (tmp[0] * 255) | 0; + } + smaskOptions.transferMap = transferMap; + } + return this.buildFormXObject(resources, smaskContent, smaskOptions, operatorList, task, stateManager.state.clone()); }, diff --git a/src/display/canvas.js b/src/display/canvas.js index 0ffe01de2..b704f8f06 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -632,27 +632,29 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } } - function composeSMaskAlpha(maskData, layerData) { + function composeSMaskAlpha(maskData, layerData, transferMap) { var length = maskData.length; var scale = 1 / 255; for (var i = 3; i < length; i += 4) { - var alpha = maskData[i]; + var alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; layerData[i] = (layerData[i] * alpha * scale) | 0; } } - function composeSMaskLuminosity(maskData, layerData) { + function composeSMaskLuminosity(maskData, layerData, transferMap) { var length = maskData.length; for (var i = 3; i < length; i += 4) { var y = (maskData[i - 3] * 77) + // * 0.3 / 255 * 0x10000 (maskData[i - 2] * 152) + // * 0.59 .... (maskData[i - 1] * 28); // * 0.11 .... - layerData[i] = (layerData[i] * y) >> 16; + layerData[i] = transferMap ? + (layerData[i] * transferMap[y >> 8]) >> 8 : + (layerData[i] * y) >> 16; } } function genericComposeSMask(maskCtx, layerCtx, width, height, - subtype, backdrop) { + subtype, backdrop, transferMap) { var hasBackdrop = !!backdrop; var r0 = hasBackdrop ? backdrop[0] : 0; var g0 = hasBackdrop ? backdrop[1] : 0; @@ -676,7 +678,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { if (hasBackdrop) { composeSMaskBackdrop(maskData.data, r0, g0, b0); } - composeFn(maskData.data, layerData.data); + composeFn(maskData.data, layerData.data, transferMap); maskCtx.putImageData(layerData, 0, row); } @@ -690,7 +692,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { smask.offsetX, smask.offsetY); var backdrop = smask.backdrop || null; - if (WebGLUtils.isEnabled) { + if (!smask.transferMap && WebGLUtils.isEnabled) { var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, {subtype: smask.subtype, backdrop: backdrop}); ctx.setTransform(1, 0, 0, 1, 0, 0); @@ -698,7 +700,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { return; } genericComposeSMask(maskCtx, layerCtx, mask.width, mask.height, - smask.subtype, backdrop); + smask.subtype, backdrop, smask.transferMap); ctx.drawImage(mask, 0, 0); } @@ -1749,7 +1751,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { scaleX: scaleX, scaleY: scaleY, subtype: group.smask.subtype, - backdrop: group.smask.backdrop + backdrop: group.smask.backdrop, + transferMap: group.smask.transferMap || null }); } else { // Setup the current ctx so when the group is popped we draw it at the diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 38a33eb86..d6062dc85 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -172,6 +172,7 @@ !issue5334.pdf !bug1186827.pdf !issue215.pdf +!issue5044.pdf !issue1512r.pdf !issue2128r.pdf !issue5540.pdf diff --git a/test/pdfs/issue5044.pdf b/test/pdfs/issue5044.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ed45dbc9130645ad19d02906a511cb7cebeec159 GIT binary patch literal 24214 zcmc$_1yo$k)-8$?Bm{S9+}+*XU4lz+cXx;2?k)*Vg1ft02=1=IA-74sob#P~&j0`K z-FL@$gFWc(wQJX2wbravwdd?6RS*%QWu#+VufNEd?X)-uO4Ym56eLI*pIax&zxV(?7Uc&`zAePv>0 zd_DQ=?cd_6;%;XGpjR+3{q^6$#KsB0{5!@hI2>k!r0+ta#FZ3%g%xnO5W+nhDJMfj24LHbu29@*oZNwdHo$Y@4 zt_%!?gMp2sodGZlM()4}C<7ROqR5U)O*;2X_)ueZh}|Hz?j9dvo1I<7u@O-mtVWBQIBp?B zg&T80H^;1NpXMS3YleR3AswoEmbS`UjxoUDV+~ z2EMWz>QGt<&Uh!yIOf;;LQJI%vM;-iWpy06oBFU$6&Q7^`kQ=S%|RXH_*`MtE{ZaA z6+H!lWA{XJ=Zpxd1c6N8H$v51onGrpy(Ig3sdP-Hn0>CPr0mxtvK8nYNFkKuca#mon8GT1E;L&8K9ELL2kmbx5S1Y@7qLJfx8Isfy_m{73&Jz|bVpP}vF0R{W7sQG(^`dxnhSqkZuWeprHe^)*L z<6ngfSVsh{?92>+n1ooHikn?xo8kX~bZzyPMX zCD0%g!zKL`z(Rt^TtpznP?0Frj8!^8#Y2gVL{Z@a0}K~nE)f;_yA(x4cUGb-Va_U8 zuU6Ba2Q=4~_8JzJOwYU*nn4tv0wB7bG(i1W@-$FSkGiyxQAT=i!7vd)5i~$MH$HrT z5Wf=vn|*5IO-n14=&!purSmgxS*GbwAak7m=^IDHE=&Ri0xLSl#^XbVu>+QAGow7qm&6iex&-&Mn2v%w47o2m@-G-sm1#o>e%LC@R)z_$3&~o5WtuRtJR0drq@# z5VvB}?Ffi)NyB2Kg;evM{lO0p7j??_hK$sSJ+d2NZZZ?s_3$4VF#M`)lSM&EHLcUk z;!Y}XPfj%Fcg^lQme%lnl%IJAJswpr$c`tn1*5Vx*Q|~|)3>36+>mHx;MKJ!se;s7 zLka9`e3m~0fLua?)URe<;fGl1#`kW*lfy+GA6q$s=2+5E@3TMV1lSIDgmB)bjhsHJ zaTjCo`x8r|F`J0)6qgiBi;RxKBcx0iKi?w$-0I{s9~_D1NgH^B=WYqJn&S2QusLF$p0Tz-9-f4WZuo z)(#HdPh0>tq)VCsbk*PdO~5%KTE1X;EPCO)G@*G!9IZF*!h#AMsNj9V;jxJE0{4?- zrI=KK<$1yiyw}7|*v)Tr0v~drCjl%_&!FBxNU2~m25%QZzWOaybK|}d?;cqfaYM_5 z#^_w$kZMHdLuly6*uXglp$XROPIx0Q_y&AROydpCg@{nB1_>wf!y)P|v&!Mvdq!(6ISs+tVOF53r0X8-$uBEz|wVh!@o z{4OwTNEy+zy=wX~`tPe#YQPr_j=6CW20F1eaqWB>F}0a&SSukK-YrD6_#O4U-5|Sg zYo%I6Jqvi(<#=xBMc5AOi|dQO7DLeAK^_aE1z{QRjxZTOVnw2Yi2Y{o&2tb^H;bZw zsk{?W2%>whwjpKB$3?+bNnA3y1XRfo5)360%Cvfa6-f&s9Wq|BHo}AAOick@ z`AU);fF9|)cz%UM3NloADO^#ZB{@#1CINQ=ci|$Xx1~0-8s(|YSz7XKBHmKo^x_H3 zDOV|5Llp_1;w+PnQanlJ6BklkQ}pO^$n^+)rCy4k8o?C11iF;{3#!%f#5U@?d4nZI z)AN%I!wl06!wmyBS^E@8TjTxX8<6G81P-dFNs9=vg=UJ}ryJ{K>$$#}d}F{9XD@u5 zNjT`cCfIMghA|;EdA~!kgS&&hQ#Y&x)y<%P$E<`^6qOLw5*2gBvfDJVHL=WAWv=_P zl``p`%7)4-i74qq5@=FPxs0mq9O_(FxplexEQ1A^g@MJA#p4{^r|5~23D@k2EIpQ= z+fSi~)y?4^jSm(-dJcIH6R^{<+p)2*Rk2f8`dP8kZPJI*chdJ*2I|eU;J!d;?P%?N z(Pc4I|?6xKC451zH8%{TxPL z?ISMuw%(Ifhi6H~OGXdLDlg8is^~XQ)K9=$?wXOYd}3`G$glpcsrgxKK9{qHXV9y_ zJ>#AljyF;xG7EhLU61C3Mw#}AhCq{26H>#v{;>L?=UZ>OrH+yJK#0YbQQdg)%I=qn zGTJqljuUV0be-xI^cK06i5r9)qDQhvMrhtpx6n3(+eIfAik2YnIi#cgjmGhds4Zx6 zPx6`>$&$4!&2h@{x8ntH@EGS9v$U8FQ}!E;xDIi2#&l77ZgzRIs>?}RT1O9~vJ26B zF1^;hD~r5K&yA1N@1)~q;^I(tJG~+ux^=t>yLC#(tesqU z{LSIZPT9yrWvpJ8racut4gua8;?HoD?y?=3%4@wQ*Byw3gqG09_`QDWz32;_JCmn4 zh?Jn(ped1*UY&3w$x2By$t^H>!7uC1wR)HS+hvKdi3OC*Wm9Ei=0Wv$^)o`G1`*ZN zI?TM}ZS*}X1q{N?!{&3RswnvaQ*kmBj+!4@Qa`@P{E&zu$si5XgsZctT{RUq$r)B0 zMcTdIPT#f}!5g|7dh}ua!0PI3+V1ia^3=t8YKc%0JYT83+$86!)78B3qx~qx8elE4 zbUq?B5^aLBW)rbGtC*`;-L7v|cedLv)Fh<1(MCJ|9>J>53eDh~+7H$f+DMK?u{uInyuT)(dzG+$|?8EWb-O;)b!RP2mi=3h3n zs2{hh8N9dGe`g+J98=F!TH7X7Wg$LSa#(oij~$b~+ji*LaFX?HV0ocq&DwVcG#b1Q znhzfpx7By>R>87D(7Mmy`^M*pJQtExm5oRC*$A94#}0Gso5EQm8-pA~GB! zluO--uepAEI;*m}a&^Q%rAqgr$)Rky?eR%9<&$Y8rw+GwmUr7p$aC~OeoJ<;-m#DQ z!Iv}ZwgbDm=j5%5kL{4&dk;E~^s6_`-a8+EX5oNGLOq<)wR`^5{my&fz4|-_UG`3w zf7FBH+3eZqcq^YAR-P)moWJ6E?rz~jS=;q-?t=bAU6^T1NTV?Q&!qb*`5wrLvI%Oj zda*6yIm#?=;Q=f8tTp!y^4TpNqEvJss_@!1$+c_WR zZ>;x>_qS(U&CiNUB33`O^WXSC=RF!-55yfD%iqZ-8~x_bQg zefzI%=&yY{kfHd;#{HF8cr^k^2uWdKAp=JfW5BOXtP()yPa~#3kC%VrpP2r7Z2$kT zsSQ?rABLlf`I5jn1luw`^KFi{P`J&BvPJqU+DcJ<`ul`>OYGXEIds9ggaqT!W0G;1 zX*h4HfX&EH?UI76ZM1I!raijmp&ymX6x3Xgh$#5#-2^GFMH?=-6O73;Eiz0dysn|RK%t!RpX5x8%OpLqON@Ic+Vdz z&!A3zYIUY=+k`{oAWeF?0^P1wKTEofBH~|Xu~Hun71AY7&~OA6i5ntI^5!YObB8S? zIs{|+j#WHiqA!;dj^P*YDegNhq;! zX93$D_-T&7@H)gwiQ>zH#DI6`R^Xv?c9vYH&1Isr4w{~*kdj@ZKJBEyhSqi#bapuK zQeKCVKEH3M%fi(doMa}VGpylg$n@9<4L+9QgT%K_v&pz0*ZrzJjZn<}AW!u{>fG?` zOY`X{g#+B(n3&w`M-Bg>fHVoP9#gC!em>WJvAVy+NMzhR<7D66bKcQEAe-k5MyXh}MS9-9En8 zRr#2>InA*>wB1^rXWS>m?5CdFt@oMz0JaD<`qbbSK6{Ak4)_^zmZy+)>eyHQ%lmfX zS}D(4j@$M;id8-S1}*jrd>pq(v#T++qnz9K6=Uz#eFOIcUI=n?yj1@~UHijyF*2}o z{wZ0%7@U8rYrlzsf7G>KM8Tiu|35_3Uv=$25$pdih^T+kn@qo{+rN0wzZ1kj;@H5+ z!5l~%zj6}{09r=CD^2=~9{s~l!M;)s|Hg*?MIDGc7y#MP|A7)^9jHLik|3$3)Y4?XO`HOe| zzn6l)c>3Q|^uMOyPoM$+Q=tDx?wNMD>#ZNdo8XNW2;)|4v>H@H+(y;bLq$GO_9vd_)NP49f;=VR zeE9cJGrh*2D>)@sEU}X5!#zZfgUeXQX5Kd-nfmGJo4xF#jg% z=*66EjGTbi{OXnk$d=h!8<^Vw-CzK^^eP}2*Z`%Pe|-E8U;*-n{}jSLsWGTXR7i{~ zP|(RLl|q65wjnbAJ-oke{yHG0f9#Nc5r==q_!mNfO2%*X?f(}aUvK`eKK_z={`mMi z55MTtf9f)?Mh2jGWCK(P&250`ku(M>SmsXdv=XmGq@xj#n>Vm=dc6vmYUW=v5U60i z?gxMOBqJ=Lt{_P*=wNPOC948NkgckX`7gPV`47ea2avxEf4unAS&BHIKpac2Jktbb+?69>ybV*l^6{C`7&u%yVV`iM6E72isrDvyzFaIZ#q{2T%wC)l(Bn0KL3}v5CVgoGAXl320PywzIP`v3?a$ zUzJY)z5462_G`X~r~{Qu1_sz)>d`Ce9L(*UY#jj1e{`jP4C4=t{{HnG@L*$O2e2@{ z9&A9cvoOCN?7+o?jpOxTWd*LAKv@$gFaqCkFufkX-mwBWSOLsHICHSWadQ#UsTekp(n7~J2E0LvjTz0AKi zJpWWYei{CZ^v~4%Ysd5ZBXAGG_!_$ZDEt0>rk;4ixT%QVoRxXnx|$vp)`gOguv5nd zk&yVuB1%FdqZ4}y1VBuayoE6)h65cSg(t!k#6uIaGq4v{Fh@`G<65t5%>Bqw0LbkQ z+XC!UFk{C1bU50w!|Yp~wf($pJM%8&Y>-pUD(8BiRleL{BODOcS{7|AWouT??sYZV zO&>Ph9oE`>X!YeLrMHzQ|B@#Ejbnwiec+xa-z^f%Y=V}uoWaubqljRP>Kq$A zUt`ly#6#Yo?dS5^WiX59hJYJr0iN08dQF>z3#vwpI~;nNmLjJ$|CK>PAF#Jy!;MHcmmJioIg%sqwg?x@O!zscsS z-f9d!5$7yzp&yM1n(~v5aMj|**sHwRVp{tpCo5^m+UiYe zLm0xobd1*nq&ZZB0?3*a(PD^{e7ZW5NybjBaSojU2nYu;EYjxr`kfledKRoQ1qX(Z zW3gYSW#Jw4YN_OviT4|b^!%I%8X%ulI_(AU^|1lCohDl#Y@Mj%fiCn7q6BZh$0V~& z!N-`Dv&%TT7_@!~VK<{&M_SKFqBoCZ47G^!g+IBW7Fm)BY@f$&m&EvekHUKRt*UhgfjnxwK%e9SK7x}?#jo&g9Cr*vKfrrI9;D@!Kcb4z z17riA7LFW*Z`ey=d2GbWM<6sOp|7qTC*5hpR!BQj>A^M&arY<-vr8SX`k#J;m<-;A z)HslR$+H3lfH6pVq*x>!NeJj2!IwyU@H4H={s>yBNM+7*3C5LUxF~zX`3|#0FriM` zJ&bLbe^Oy~#Y`KHlPd2_(C;dd>^TVv8)aYZPMz>U57rIBJA3{qFJ6klhiacWNjd%9 z%Eu?FDChYK@~`Zd(gq7d)hnXwK{v`E1qLZ>0&l;?4BVN2cKq6sI-dppEg?5;$nR3& z?fTy2oUTpJ$&`A)$UFAi!g?&0Pk9R{5@-SpSL;w?6N_gcrJi`t*Pxi7-k@cE%6?;h zkbc^oXCTjn7zWx{PmKKc#~Bijb+(wReh6I|yLHX*F@TP4R#Ud7hfRCKDES#Mj9$B( z^-t&rZ_aCbR@mJ#BHPKEm1kp=(5u%X&otz=tJ)F`Pbt?X&2~Xg*b6Ebv%vJ=vfcSU zClyai6&`I2j7**hcd9ok&%eD49%QZ>(J{}?AQ((Xc-iDk3g2wRzXn34+1Z}5B7b1g zw846aIu(ah&Uq)OPF2ad69&(wrFekr5ImLFANhpa+3G{bvG>CY`WyXw#*5I?$ zYQwA=lk%jDMGVy!q_Yl5N1w_^=l<9k!Bc@uNi5L)?eb- zt}hElyv9$2)r)O>+n9psd3G<$%nHRuJ8re@kSTlIJ7dlZ#5WRn)Yt}0uRGB1q(BA` z?mk_SUl%>@y}#xdK6QF5;Wp{m;&cx7eQ12X$SL~vE#U5>3+|Rt=K!9~y#aU^BZ85P zKLI^tj_1m?dU4yg2I==31Gu4UMOc;Yc#(-4TIY9=S1BJv7+y#e>hyaR278Cl$&_l@gCwUwwF8#<{)J5 zT(Q`cynmZj&20!sx!{@I1zf{4VNmQ$-g{_4@?OWO>+|K~G9)^`)!SRz(s$ymQFg>YJghNmA@SC7njZO*-5 z&JsSY@y#2tOb(gA#1a7%8Qt9F(t}PZ`2e4ac^A+d(aGSl0Gacpi`!CS>gryIEaRYHpZiI2Kxwpf3lCia@_oHy7H3KfMCC5IPA# ztIwS@_F)8Jumi_anvP!trAhk%@gCYNBtGP^GDWADzNT<12fd!--LGrDkBrGO4&VwZl|`bszHX5!=PZ(5f6#)D`#FN&d$=soq4nRJV$0N~bYL5>|vTuG%V$Ny}Zk5Pa6nDv?Mf4TW$sG=1$}4C~nYC?I;Rp|H0~}bxjx0ZiUtX45IYbUfH2P!@8lkTZc9?mYO={#E58=pI~u+NH?F%!M+z}JUc2i`m31YWStf>w@F z%jd6j1YjkSR4sVLvE;N6*=G8&q5%4c+e0k9D};PM(e1o5paXBLm|vCogyzTQ%II6P zqB3Sz=EJbb-dSOr9r#)OJok(1@_;pl>tV6_2mQ4he0`|-h+7K01Jpvu)7cZ@Q@4$A z$Ki|oh8)Wph?*Uy^lZ*4W_AYk`kPA3*^HN;skzEO(i-Yqw7T-0`DQ_Ue+GcO0ppvU5C^`?nuR(+s9_L7WR#!h6xpcyo%R$hBS;t* zO|DGEL)b(5K?c2+#&g*IlGdT6Rce)_qvVbPB{6N-YKL#9VYp|wV3=;leFtU7vPZXv zI-~>Bhv5N}IBKe2d&_tW%&5XX?*e`6q#rse1}lfjhP~a0$Ep?a3(sM|VF}bHMT^hr zrN!k37RBkGcFTI^gudvusd~$JD|vJEBcfoUAfw-FC;N0-6owSsVDuOT+L*l z+U*UKft)S3m{v`{5geqBvMR@scrMwUgK~vj5l)OefIP+bsMyHk9Ctz1M zboYg1hIDKNYHWp+zx+*~dRpPA(y8J+)lt&eaGg}>CHYQ$mx0^rdHY7Dv?HU~r_xGx=E-$k~RAnl2Zm zWE~Irr@r?}r?-$B78%|K0V>fa@u!ZBjIY>KF|W%yi-1#yA$s}PVl#H z_qNk3%YAqD8oBr~Fpt0Nbu5=}q(L6`F% zf^c4BM-r+hfjjw)ocBI4+=pu!*$li^9)s7p=56L#2cR?Wi%n%RWN@l|ysdF^Le8n^N)tZC9nNdCmzeJoZEJUoq zN)8GkK^+!GZi3dxea3jFgy9TVzyR~kAtJQ5XA`ML&`JdN7FDDLJBP4kN=H+04kLYJ^CLyYG@gh&_rl118V6wlr>kx&LWy&Cmn6rXOQ zCsB~B+zHX#H^>u_7$VhgkUsTBZr&PpZ~%0X=_3`8#FmE$AHwV|BHUC(!X&2DMZy<) zkDUB{^6B@bk!V$rhzB@n|mW8L(;0DP#vhy(_qlk(RX z;3CLbh02=@-ZBFRC=ZDrCmA1zy~)NS95=Z?tFA?MgcJ0-U$|bpvlo0Ki5D$tq-Yjt zkm%wPi;pFdOhz37V38(l6S_<38s=`(-b;KKQol@~iSIxKKuQS`slp};iKI)U2o*7u z#h}uOO2jGYQA$N5tC%OD68A+25(!73q$#x~0!XEv3ty%|C?%zm)udc8X`p-$KDVmq zlF_HA54sM1+G*K&+-AMxx;OZo88ae3w7hM)eFBuMINhtB@}J_L(w~x_DxKtB1o&ut ziG0a?>2l&bk|zdDcg_lde?=XV{1W_9dqo}6KV#`6_$9NZMVF*+lD(^&-@N&edf9jx zbXiy{>MpfZZl#>9mfclet7A{WotUMO=1M(5>6y4@khS#bxQFXG0Qj{APm>M@0e4Av zO?OduRd-o;9d}`OWp`=L($U;`(DlfTSg}7>bYA<1`hbTMBJ7Eqg z_cENtxax8gIn;U-dQ{{|%ELKHRf#jh3&VPewuv27rir#mb;F!H+&i8-w!`m+V>YGj zl{l-ObnZhP1n(se3i0kfw&)m7Io5~jcCpj9n6bA>brh$ZKd-pC2k>ZSQ^?1c49{#I z?HpX9HU;^h>PbQ;zTbz`5;tXFCMfX~GGkf*O@8#mR8iFqKJ-Lr1MvlXMdf^`&h+>%HI( z;juY>*Z3}|NtQ!ht>99rRkzf0DUSv|(a*ONJ?EVW>k-sKVBM3C?~-Z_8Pa)p+FHFw z+kMb~`gP{6$4*xBZ6L*Y7v#^SE;il;_4+(RlaQ9c%g9O-B*vw&x=GwjW_~wtUx1%z zK##)I)L^l=POVu$*JHPN3JOmklc!AMI(axKVzx=uWV3W>ir!UG`L;LysXV(QxA<#i zyMcj`vg1hpe4n(<)0`~(nuF!?v>ttn_5BI8+Uk_gUiqBsiuZ)=Y1`QgtEKN_XY-GD zeAnm1IBYiGp7xDm_%F7TOTOA9HJUW ztp-h;!gbK5CLiFX{S-Hw>jYZsYswZRDb2~wNBXg>j29`%= zdW=~pYDp-HC~Q=k4kc(@DZ=fI`r)^|GT%ae)rH(aKoc#XE3q&AJ|0p&LQ#>M=?Ph+ zT2il@kBZJ3a|u;kDr#T8wbIS;MR+uo1@G>#yHRP*UaV)p{Eipf1_~b~5XwSPLpARZ zamOOgXg0t6CjYYApVBb2VPUW_&ZWwqvc6{or<9#R+)TR%0f|f7EDTjEu|=5Z9kYm2 z&;S}b=R-v{jlK(s??;pOc+~Fm=x<-6wOJBx z-{e%ZLiqsaGaIElx_KbaIZXxoR`C;}AxH8v-Gn`R#?c9fKl<`)XlC z+Nu)SC}2l?Q|cx`x^fqhjr~+Y&V_`uCNfp5yLjEcF`0me!9+0>6=OkPF;2jn1*!Q< z(r&TfGb5wbIyd)c7HBN-<-!9G-6BpT?xFN#?ZepNrd_`lGB>J)`X);{R{EGg^0WEV zhX6eM@RXN(O(C$zatA!3Z9SFc9}k<9_I(K-WYiHslXD9hhH1tdR|@O}i?yWkn8Cf1`U`U2M+c4Jf&B%gs#MH{%zM{p zuFSp0q~vQB$MB6oSr^9gx)V$n%@?K{uWvh>$U(SejmBc0Eej^jcC1+=HI)$f@}x6H zvvCON5ou|DzIfx{!dOzoxN4>FtfZ-;TK48a)Sg%dL7x;UUlzHci=%`_t!xR6C87hD)h9Kede40wjAveYX_O|$hYg`Q6}1!qX#8k zJa$QWxPe3CCa$Ginl=vSpzIszsTseZC^o0|k&#UMTmXdLWBa?in6TNYf?LCF9`J1TG); zjF0DHw^=Zdv(|-#h_xjIB!Hyb#yA{!K6fF#YuV5g4%~E6jNSJi#4pIu>Tm*(G7yR2 z*dSv19Puz_;NQU)-`Ihiiy~H{`%&RRw1VGZhC1+*QR@?R3VZmHhaAKroXFrJ=^zrd zk+%uvDIB&;XJ|cqylzfzr)?`PvL%cbdKNtRk)=4LvL5XrgafApH_bAOQ<&n?2Q9)4 z_f+((pu|#X?&sAB(P`DW0#Z<~7qOy=h36-iT@vWVhDUo+SoP%^=G(F0{QcB?Z`?U! z5`B2n0!WWZU^Ag&Em@^bD2*QSSu+Nv9Bpyag7 zH+2(WmO=B4Et0LptVOh*7R}l{-#Xb$8r?cBpH`|~Q*`;tZ9!z6CeiuUWC_8){>};`hLhVZ zk2mYH4r+*HHC*;N6mmwcq&r9Vv)`j00vM;M&F)}F&tdVPDHtZH?F!T4%~Z;Y_pL_`c;~BOPiGdKBtAEC(Ee#c?JiHS*lnFpbRurgRT00fWEeH1*xO zKV|!uk2N=6M6}{*jka5egY^I&q&ZJKjXy1J zXXxdvygtpsco1_9gLWa~BhW#l@sU=9ZI#e!?2GuifMpQ!{CQ;`@!-{3gM z{0iB9M|mfo?a%u>Sr!ZpODI_g=<&`hFrx@zvry5I(_ES9D}?2rDT}`p9~8qB6BffO zM^N^oS|3_QFhIIPxM}cs@p|#J^6>CP;YWmS3*rmnjibyP2Y?1faX1GM``MY{qR!aC z5k*b5Q|~sC@sKnp4k(q;i z=n&^pT$c7RgKVq80|MbGm1vo;))HYgrpp_04BD9WibGxGZr}UEH*$~kdOBKC285B9 zJ(u7ik9$#6Pr=enY8tw!->)#{1Ia>3Z=FBWW;3nSe6cMf4n#6tn>HNqZcSN~jR;l9!j7+(+i&W#tlOSov6dm*0(d(db8}QbZPAOsR4r>&O7g0s}M@Mk83TKns6M z?Pt_JB4a`(QEc=R2~sW;L#FIzMUKA0!Kqo#!|z)ZEJ8Z>>w({iD_|~@dsvRW8 zB4Qz$w>_+Tc<3lD(!G3E5?^E4Z}#{a3z)$dtDw>0Y1XMmDJw5`GI-Th7ioJ8iEhGa zE2-cjp0~sl92}*U;eydrF%EyGpNHn}qO%42$nMtaJ%LLioi4*>q=!e~Nh(L+-7mJE zF{CMI>1ssOYP+U2xFX$@coTHIFWgsb$a4ttAkxmSb8gz(SM50(_fc5qdSS|ME^KM$*^N8C zKp+^FqVZ6$d|X9?E;PQjDX9`kZIr|h*Tr|{%B%{YiXT3A^5xA|d52z5gxMpr$FbLf z8o-ENu;5&eBF}LvKu5 z?911^k;rx958v{Izz5FR6QXl?A?6;7fCW5 zc+JojwD)2lgeJSWuxWHr#G;f=%S+)+xE5nNN|0_9>wzxExK6@5jta5S6zs;c>+amB9W!s+(JG5f+dfc#nS4Y(Zr-DbgNZ>P!ywU-UjC;N2&3HsxHinB=i-USVR zAJi<%?d)=tYH9dR`K|?mh2=s%c10m5)gY7pUy-oCbx*~-nnftxZ-Qosj<$F8NY}jKy5>5;s(Z$VpHo9FUVOx)R>vkeWzf8P8hwn702b*FL3e66FgpeVKVh8;&TdG3T2AkoocKG@=p{?xo1MiCw&b|njSN3 zK(*Dd!XH7tE5IVUkMrF;-ZYbiXtObO;ap@*6- zg-!8ZAyKCO@wEmdKR*3A0%KAb{KdPaaGf(ZH^r|{q_jOay1w1!{%V;!_Z6ioyBn?Y z#f>l}PT8HGG4)HC$*=}_D-5qqp0X3WHPT3nZ}5zWVk+lAuXBjvG+__Lo_70#F@|tX^OMsprYm`$N_(zLm7wtuT-|%U{GIj> z|4)2&bI_F!o&SYVpP-Xa%V*uN(^AVgAE|}Ze%kCXc3u;FC^s{4XrwR`b#|b~jDvEB zem&Ako@ZX7sM>hszO}OTBAMW_-+4!o&u&Ci8>(pFZs3l5JwW`~Nipf2cKsz>dbxw2 zxJKmJOMAZ~lW%63M1IkHcmxxbjn?{LvWM?KJCae8EgxL-n9fhT_ z?b+G>po)@`;82LVm_2Y&Q;Lc&+epb~G?Eh6F!BdDMX+cwAS3aiW5!>HS=z^ePpUmw z(e%5t0CL)i>7x$NXirYLMyiPw$wq-!3lV7AiGE)f zSwbSdAkx!r+U%HfkRHiM5SV1dSj?_^LRxp__eD?NE}2N&-NX9YV@>*!Ng}=>G_*^Y zH7&}-`h!7o>yNw(h6QYREvhTUF(FoYmXr*f(c$Xp>h0R#nYCe=co>%Hzh2@mNN(`PGC|R*-3No(rMU(+JW_ zdWKS(hK3j%N>qR2VsDqGaEP&GPM790@|IzAu}@EtOd|urAT)GvP(SIgSV9#93p2Q} zTc>)H>&p#>7<)8U>-vm4QJvXNh4ceg_u*=X(awB0`o!cS29fYys}?_V!PjOBN5eG} zWpV5Gd_D(v06j-HuK@LxPD?3_5ZczdMT-_T=ZmKCodtNboF6gu*90kS#ZMtH3-#Rr z1(_u~Ta{SPHO?6+g{df`n!7@E26mI{gGWWkRYQWxM0=7+P%WmS3hvwf`!VpL;QU99 zROc#_OOv(_nTMW4->~qI@v?BUG2$_FaaR$&6g>R&O!TeLwj&`DS!%uHhnf ztT_!jecxuGoGSLp)Qy+*&aWjqoH5^MWY#f(yP`2&Z%9 z9VVD+Xm>$yv7QK&h5){W?~nN&+ADr7wRSdZ^^^yvk^F&%CyR^XWdhB)`+X?F26?Jj zuZ?riGhDBOAM$JNXk64G3*uczfk==sn$!i9Od9D_DOkfiB_7K=kRcxOEe)Z;G~Gl$ z;O=_Ql_&4*W^(<$^92&Yf%OMth{(aFE}1%z_=t0TM{ineDsFy~r!h6ZL zK-5X1m~_=RT7LMjsMboyWN52d?qdUuj2vGFgFCJe4G;TI_!b-8g>D`WYdJYT>gI^x zXrjdD$z<_q-5Z{o!D0sQZ7iEd~a(`;n1BQ+o@`HZ{k$t*A>ywgc6=}C7H8@I*e)I7~Fqc zU|HjCF^*{*GEQimY{Z!iy&Zgug{x*vi9mrs37cV_dce7)gsy}~1W zGI&e0u57Wud#I*fg-z!``DiQl#WoACRv}`v1mD62SB2K_ITXyC*d!ZdkNpW~BvW_cR^d>=rh+D^7el7Gm9TRd%9LOdhb>4P`hj@T6eVkuR_i< zs)=o3!z%3n0xCtRq8y|{LK-a~Do8ORHFQOglF%WDR1qmk6Qv2#n{)(1GXzBh5ds8A z=*ANeK z^}}6s2J`J>dV)zJ^_x@xR=rBy?%+7BN%MZ(!?;h`s9Jk^ci&bYI`?~Sh zLSRhTO1L47S_a2_x?uP{=1#un7*_x1TFaE{Y#co20Xv3>(vY?X79vvjRKS0k#s#*h zh%g+0*#z6oB>Y?g;`481zY|a4R-%0#lI-1-6#0I?9mZDH*=R*xIV}`QV0x-|1}4S# zV%MgTxIGnR;oU4EI=0;qXJZ`ZA>-uR#=Os+m^9Va!EwxCK6spK73jRJw^x zM9R*aPH~$iLFUE}=^Fvf;~h8J&2VZOH*fwC0tD>-pwQdx*j;@tcOd9>x9v=T#n`Ll zxMAnv^%0MtwjbG0r}C3EE(zjBjQWVpIYW!hDDC%bwTw?^)BX&MSiLfN_oKARE4f8i zfl6hrm%S?X$>Ux!gQ)5q%>dNFnk4h>8_H?NFHDy|3>f?2xAQV=>m-nE!(wK6R3#&D zBI#Mr!=86N6LSye-px%2x2R1E@5AUv&*4T!mKw$H7*6o3vUxjw4|x9Yn3$_o$2MDypKDkbsO072Z8@;c+}CJ^`l`gN)$E%c*jOvfFgMU}L@gKv5?m z^QyL$=W^{103 z8Tp^{Cy7lY0@g}YKj{6{@_0vt2lp0zdtXu>s<7QYItrotJ_|#%&!ug~Eu z9h73Ev|UX9l=|l9u^XCo*Xw$sVQ)jk$qU&5=+H$kjy5^o` z=~U*%W8!(+`p-=@A=V0kA47a^Wijf^VU^(pqmd1%p}t}=Xra~GF>ou4WVm$IgUY~7 z+ESb;@@JQ{LH=FASAQ%UHMU9fspQXYrZOjf;E$3m*E z#GbzEe?kFeXoeyxZlGz71k$pIPck+NH$SH?XALVIY6B|7b z?Qt7bS129UXvOf();bIE_y5Dea5tHRcHy#`OYQbicIlQ=_{cEJvUszHyP;qHWF4YE z!S;s}aV5iY&6_S%vQ&8+!hQe1pL(#g`9><{Pi z!)D@4vv29@1#cAC>%Wd4-e>dGqG4086Yu%qSb-uUo?Dnxw9-MLxVvR0pf-;O z(&12PberLZOREwItz?iLEw+VxWlXPV3P2);sQ>y#yF;P z8&}LC(30!3Yh<7Let9v)YwwW>^J{OfdHmu=pg^pD3M6y&6UV~+g+NSq-0+Oa!H(Zd zT{Fle9dUzzA7md~GffL#JqAPl_(pwCN2014o|YHW$>n$@MoHTkR?o5Y=0PbIwO;(d z0^M=E>w-l@htzfMRO|c89aeB~CvkwEK|hcy(?cdg^9AuhDYEMoSWg<^5j7J%#3vD^ zN3XsdlQz)meR5NYr@N@kZDn2{(3?w2>vB<-FZrerZWs>J2Fv_dMzV1>02(D5lp`?1 z^B@wxe%@X9Ew?l2PB~u|~gG*_PT1DS!Xf$up z#<}n6)>`JrpUt#k;=FMCa`u~0j!6(JKw!=GubzjweRd(fn1z@3m)zl|a|yjpgeqrv zRB$Qv3G_OoOhDnzDD)0(o>x01de1p9Ih!P{DkGKA)B4p=WAmcLeZFCN_4&#xGuQi_ zq&z9p*J9Wm12+Q6+%ccc2fn+tjv2%y)T>iOn<%bq9(Nf1NxiK$+I0}uZO7#i}W z4IW@3l0Wr&nxc7UQI-H~`eIkWf%g8_w8dhezdzA;)}(C&KLScqR$M=)!jNq3-u(FVOw1&%muTyw|ge6GGwNF&H#amZy z>9d0lx$QbKX-{N-<7*To z@Y$#Np@M7oF#%(WBcp&t;`N!Ln)@EtC@=H7Zdw-16OGdAB->=RpW*lCpm@D3frE3* zqi-=yMRmShZ$j$=Er$oPM-)h{WaN~3ckP3v*peE&uaE7voOGW(o&Z9f9&(pl7!=tP zA@{cug+RMFe1EN*Jw+!XJ= znK#u&1#j7%s3o1^iG0gJZ>h2ski#tyA5jDDxx>DngF^c*uL~OXsx5Y9ohtKQ^3A^D z`x7XKao$eI%zDLmNG7HtT1Ja!*eaO_8JvWjQg+ni4Fy{Ui{-CFQvFlMR>rvIyb2|#y%)E<+QdN-QeHLAw z`*}AD${Z$b5px3yRlIR8UMQbRj5NSz!FLx zW=VqyOyov|8i9-1*OO}M>gt^Zt{Ht-c}<2vVY%fmlQU!qgU?E^gvwE43x?B+1WvK~ zo^D)4eL-eR_2aM!GG>FEM{h=BOrt4m>{#mjC3>)fC2AeJp3Ih4&#!r~-ysU1}U zyw5ZA25pzaO1QNfQ&ehSY{$#e{kkRIzKsi;bGo_=3z5F_QEXj|q`QDYP&iP?Mn{7rUCw4^Avq7_cTD$ZwgAXbf%&rv{^ zEpnDKN`mM1-3?jac!T#G&WOtMZmp+S^a8ko(ei1nqPMO=aNJ+3A4GX2;Y#HVrPM0LdCl_!Sasl4j`&D!vXR8w z41RqExRDWTNFsTX*CTT`4bWs;mL9f!;*8UC3lxJ#6J@3foQ*Cwi81*@_$}RB|5sb4 z&OlAhM4rm9!U#u*RJHtymKi&)@cz6329-KJBZ<32XXDPzpx=}Sg$zg(&KMzU8D?Y6 zL%4t+CN)OLMkXeN09qaAz7t5MvoKWsl;%6}S%Luq;{;)TtO~9t@3hb%>aEfGmnDi_ z)HIx4>g$ghe5Aa)SznKy90|t*3~AOf<#F0q6WMZRtryIrR1tE~-ppnT)KoY7=Fd#N z)~VW$)X$Fdxak}EYa@jHFuK?V!`0k$Zp-Xo;l*&C(kC6t_chhabLl8gr?vBXXe;Y# zz0^9>x7ky=oy^D;NGFT0E*$AHnGHls+6aa7u_-L;O3dq#U!1DQX z6GRbY_VIhjtM~G@Wrfqzp(9mQWHPzWw7(+WRQI;8!#O92xMLNzLK;B#p2H{ET!jJT zsdU!{e!`DQr>AA^DJn(bV;&*uQnB$>(7xulgCPM6aljJx8sYgQD52V|D&_;0RW6k%m8 zsG~1vOod3Lfk0`Xpf1MB-P1>q8W{XDh1lCu>_3$b!TCeBQ}mjGEC2`r$^t;Lva<3Z zkSPElLjC;5`M2?qx~B#P*kG)w5z;^Vq=p$^r6xxoa`)E`Gb*XP?N4wQL4Bv~e}4ZL zDD`%~XUhZ-1j{l}(bInyK_~Al%3~;nxIr$@Xf$~S&1OLPMf?<#&?Lp)Zcg11(?|OmC9cE4Zs=)w9ebmc# z?Od9|HN*42*w$zebI~P_nTCLS;esWUZ`hW$((~ xy9)t