From e1eccad87e274bc7869f849dcb5964866c01c5d1 Mon Sep 17 00:00:00 2001 From: Flaparoo <629229+flaparoo@users.noreply.github.com> Date: Tue, 28 Nov 2023 17:51:20 +0800 Subject: [PATCH] New app: coloursdemo --- apps/coloursdemo/ChangeLog | 1 + apps/coloursdemo/README.md | 22 +++++ apps/coloursdemo/coloursdemo-icon.js | 1 + apps/coloursdemo/coloursdemo.app.js | 128 +++++++++++++++++++++++++++ apps/coloursdemo/coloursdemo.png | Bin 0 -> 2234 bytes apps/coloursdemo/metadata.json | 17 ++++ apps/coloursdemo/screenshot.png | Bin 0 -> 5901 bytes 7 files changed, 169 insertions(+) create mode 100644 apps/coloursdemo/ChangeLog create mode 100644 apps/coloursdemo/README.md create mode 100644 apps/coloursdemo/coloursdemo-icon.js create mode 100644 apps/coloursdemo/coloursdemo.app.js create mode 100644 apps/coloursdemo/coloursdemo.png create mode 100644 apps/coloursdemo/metadata.json create mode 100644 apps/coloursdemo/screenshot.png diff --git a/apps/coloursdemo/ChangeLog b/apps/coloursdemo/ChangeLog new file mode 100644 index 000000000..d44ed23f0 --- /dev/null +++ b/apps/coloursdemo/ChangeLog @@ -0,0 +1 @@ +1.00: first release diff --git a/apps/coloursdemo/README.md b/apps/coloursdemo/README.md new file mode 100644 index 000000000..b0fdc6f6b --- /dev/null +++ b/apps/coloursdemo/README.md @@ -0,0 +1,22 @@ +# Colours Demo + +This is a simple app to demonstrate colours on a Bangle 2. + +The colours are "optimised" for the Bangle 2's 3-bit display. They only include values which use either the full, half or no primary RGB colour, which should reduce the artifacts due to dithering (the exception are light and dark grey). + +![](screenshot.png) + +Use this app for choosing colours for your own project, and copy the colour definitions from the source code. + + +## Use colours in other projects + +Copy-and-paste the colour constants to be used in your own app from `coloursdemo.app.js`. They are sandwiched between the "BEGIN" and "END" comments at the beginning of the file. + +With the constants available in your own code, you can for example set the foreground colour to yellow with: + + g.setColor(COLOUR_YELLOW); + +This works for any graphics call requiring a colour value (like `g.setBgColor()`). + + diff --git a/apps/coloursdemo/coloursdemo-icon.js b/apps/coloursdemo/coloursdemo-icon.js new file mode 100644 index 000000000..8c58b0b19 --- /dev/null +++ b/apps/coloursdemo/coloursdemo-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AC8sAAYqpmVdr2Irwvklkzq4qBx4ADxAvDM0EyxAABFwgABF4k5rsyGTksF5MzBwdjAAVdnIzCF69dF5FdEYUyF4YADGQSPVF5LwCRwIvHAAIvVllXF5DwCRwgAFNobwbxFeEISOIAAMzF6zwCsgqBDoMsmUzWQMzF5MyeC4lBEwM5nNAsgABGgMyX5JeWF4IsBFYYADnIvBHgJmBrouDBYIvZnIvHLwIABnBvCMwSOXeAQvImU4F4QADMwReXF5csFwwxDF7IlCYAqOEF44uYF5MzF5ReZR4LwBF4qOKnAvalgvBYAk6RxYvaeAs6EYK+lMAZOBlgtBAQS+jF4QoBSQQjBGRKOcF4YjCMgM4AAIyCBoaOcF4YwCAYIvCGQxeceAQvDGoIvFGQYveSAguJF8iOHAAYueF4iOqeAksRyz8CAAzwNR1RgDMQZeIADJ0JqwmCGQoFB0gAEq2A5wAG0ky54AFrowGFQVXAAIyGmVWF8VWF4QyGlmAF8QsDLYIyFFwovbGAIuDSoqOHF8CJCF4aOHF7q/CqyVEAoIuGF7hgEAAiOIF7xhDYgiOHF7oxDXwLyCRxAvfGAYAhF5QA/AH4AEA")) diff --git a/apps/coloursdemo/coloursdemo.app.js b/apps/coloursdemo/coloursdemo.app.js new file mode 100644 index 000000000..ffc86b97e --- /dev/null +++ b/apps/coloursdemo/coloursdemo.app.js @@ -0,0 +1,128 @@ +/* + * Demonstrate colours + */ + + +// BEGIN colour constants +const COLOUR_BLACK = 0x0000; // same as: g.setColor(0, 0, 0) +const COLOUR_DARK_GREY = 0x4208; // same as: g.setColor(0.25, 0.25, 0.25) +const COLOUR_GREY = 0x8410; // same as: g.setColor(0.5, 0.5, 0.5) +const COLOUR_LIGHT_GREY = 0xc618; // same as: g.setColor(0.75, 0.75, 0.75) +const COLOUR_WHITE = 0xffff; // same as: g.setColor(1, 1, 1) + +const COLOUR_RED = 0xf800; // same as: g.setColor(1, 0, 0) +const COLOUR_GREEN = 0x07e0; // same as: g.setColor(0, 1, 0) +const COLOUR_BLUE = 0x001f; // same as: g.setColor(0, 0, 1) +const COLOUR_YELLOW = 0xffe0; // same as: g.setColor(1, 1, 0) +const COLOUR_MAGENTA = 0xf81f; // same as: g.setColor(1, 0, 1) +const COLOUR_CYAN = 0x07ff; // same as: g.setColor(0, 1, 1) + +const COLOUR_LIGHT_RED = 0xfc10; // same as: g.setColor(1, 0.5, 0.5) +const COLOUR_LIGHT_GREEN = 0x87f0; // same as: g.setColor(0.5, 1, 0.5) +const COLOUR_LIGHT_BLUE = 0x841f; // same as: g.setColor(0.5, 0.5, 1) +const COLOUR_LIGHT_YELLOW = 0xfff0; // same as: g.setColor(1, 1, 0.5) +const COLOUR_LIGHT_MAGENTA = 0xfc1f; // same as: g.setColor(1, 0.5, 1) +const COLOUR_LIGHT_CYAN = 0x87ff; // same as: g.setColor(0.5, 1, 1) + +const COLOUR_DARK_RED = 0x8000; // same as: g.setColor(0.5, 0, 0) +const COLOUR_DARK_GREEN = 0x0400; // same as: g.setColor(0, 0.5, 0) +const COLOUR_DARK_BLUE = 0x0010; // same as: g.setColor(0, 0, 0.5) +const COLOUR_DARK_YELLOW = 0x8400; // same as: g.setColor(0.5, 0.5, 0) +const COLOUR_DARK_MAGENTA = 0x8010; // same as: g.setColor(0.5, 0, 0.5) +const COLOUR_DARK_CYAN = 0x0410; // same as: g.setColor(0, 0.5, 0.5) + +const COLOUR_PINK = 0xf810; // same as: g.setColor(1, 0, 0.5) +const COLOUR_LIMEGREEN = 0x87e0; // same as: g.setColor(0.5, 1, 0) +const COLOUR_ROYALBLUE = 0x041f; // same as: g.setColor(0, 0.5, 1) +const COLOUR_ORANGE = 0xfc00; // same as: g.setColor(1, 0.5, 0) +const COLOUR_INDIGO = 0x801f; // same as: g.setColor(0.5, 0, 1) +const COLOUR_TURQUOISE = 0x07f0; // same as: g.setColor(0, 1, 0.5) +// END colour constants + + +// array of colours to be demoed: +// [ colour value, label colour, label ] +const demo = [ + [ COLOUR_LIGHT_RED, COLOUR_BLACK, 'LIGHT RED' ], + [ COLOUR_RED, COLOUR_WHITE, 'RED' ], + [ COLOUR_DARK_RED, COLOUR_WHITE, 'DARK RED' ], + + [ COLOUR_LIGHT_YELLOW, COLOUR_BLACK, 'LIGHT YELLOW' ], + [ COLOUR_YELLOW, COLOUR_BLACK, 'YELLOW' ], + [ COLOUR_DARK_YELLOW, COLOUR_WHITE, 'DARK YELLOW' ], + + [ COLOUR_LIGHT_GREEN, COLOUR_BLACK, 'LIGHT GREEN' ], + [ COLOUR_GREEN, COLOUR_BLACK, 'GREEN' ], + [ COLOUR_DARK_GREEN, COLOUR_WHITE, 'DARK GREEN' ], + + [ COLOUR_LIGHT_CYAN, COLOUR_BLACK, 'LIGHT CYAN' ], + [ COLOUR_CYAN, COLOUR_BLACK, 'CYAN' ], + [ COLOUR_DARK_CYAN, COLOUR_WHITE, 'DARK CYAN' ], + + [ COLOUR_LIGHT_BLUE, COLOUR_BLACK, 'LIGHT BLUE' ], + [ COLOUR_BLUE, COLOUR_WHITE, 'BLUE' ], + [ COLOUR_DARK_BLUE, COLOUR_WHITE, 'DARK BLUE' ], + + [ COLOUR_LIGHT_MAGENTA, COLOUR_BLACK, 'LIGHT MAGENTA' ], + [ COLOUR_MAGENTA, COLOUR_WHITE, 'MAGENTA' ], + [ COLOUR_DARK_MAGENTA, COLOUR_WHITE, 'DARK MAGENTA' ], + + [ COLOUR_LIMEGREEN, COLOUR_BLACK, 'LIMEGREEN' ], + [ COLOUR_TURQUOISE, COLOUR_BLACK, 'TURQUOISE' ], + [ COLOUR_ROYALBLUE, COLOUR_WHITE, 'ROYALBLUE' ], + + [ COLOUR_ORANGE, COLOUR_BLACK, 'ORANGE' ], + [ COLOUR_PINK, COLOUR_WHITE, 'PINK' ], + [ COLOUR_INDIGO, COLOUR_WHITE, 'INDIGO' ], + + [ COLOUR_LIGHT_GREY, COLOUR_BLACK, 'LIGHT GREY' ], + [ COLOUR_GREY, COLOUR_BLACK, 'GREY' ], + [ COLOUR_DARK_GREY, COLOUR_WHITE, 'DARK GREY' ], + + [ COLOUR_WHITE, COLOUR_BLACK, 'WHITE' ], + [ COLOUR_BLACK, COLOUR_WHITE, 'BLACK' ], +]; + +const columns = 3; +const rows = 10; + + +// initialise +g.clear(reset); +g.setFont('6x8').setFontAlign(-1, -1); + +// calc some values required to draw the grid +const colWidth = Math.floor(g.getWidth() / columns); +const rowHeight = Math.floor(g.getHeight() / rows); +const xStart = Math.floor((g.getWidth() - (columns * colWidth)) / 2); +var x = xStart; +var y = Math.floor((g.getHeight() - (rows * rowHeight)) / 2); + +// loop through the colours to be demoed +for (var idx in demo) { + var colour = demo[idx][0]; + var labelColour = demo[idx][1]; + var label = demo[idx][2]; + + // draw coloured box + g.setColor(colour).fillRect(x, y, x + colWidth - 1, y + rowHeight - 1); + + // label it + g.setColor(labelColour).drawString(g.wrapString(label, colWidth).join("\n"), x, y); + + x += colWidth; + if ((x + colWidth) >= g.getWidth()) { + x = xStart; + y += rowHeight; + } +} + +// there's an "unused" box left - cross it out +g.setColor(COLOUR_RED); +g.drawLine(x, y, x + colWidth - 1, y + rowHeight - 1); +g.drawLine(x, y + rowHeight - 1, x + colWidth - 1, y); + + +// exit on button press +setWatch(e => { Bangle.showClock(); }, BTN1); + diff --git a/apps/coloursdemo/coloursdemo.png b/apps/coloursdemo/coloursdemo.png new file mode 100644 index 0000000000000000000000000000000000000000..305ccc9b8515ede1b583f61bc1bd7c5394649a1b GIT binary patch literal 2234 zcmV;r2u1gaP)8$dg(dPPu;&6cB zFNccA;?WoUfsJuukawcQZqx}%IM3N0E@|Ec z-V9c{{j>a?u5+R=77#72WSD`*IDr~ zniIs%f0t0R#MdP0{%J0q44U92cYW8A=PUy zAA%Kc?E$X0Cz7_Zea$e}$I&JugUh~lqP!=3aV6pLu1L&>FzU56jRe+w0@56z+|Ckn_@9L*O^EkM` z=K4Nat;&8g5Enr4p?;tR`L0Hz`Nk6mpv+jzTh|&MYvg^mZ%+z6c;}89oQ(dO7Y;_q zszaI4CPR^HIG*st*-afmokbeZ%!C%QDAj0psQ~Tg&O+z4j&)T=)P=Z+r%&H*cy=Z|)C~SxBy^4G257LfLO)myzS0y`=2?WYg2k zl$dn;-VUoS3_{B4da`${*UY4}X33Ydz9m8ch)ZrErRcXz-NZ)3zz>Kdjwi8Osg%PT*fQ2>fX7F}^&XbhnE>XoSBi$A^sG>5@{pgTIi z|Cp2+ZIy4#Xm}!uQ+`Zw7}(bjs{jQb{5~oGyYCnzt*VPFJaI~O-3Y}>ZJOB-ZFk+v zerZ4jSbF|kRDi{vt&q{UF|P3WM|#QbJ32FGpeWK6c|J^U=~Dr$r%z1@U-Id7U~DyD zd8H#R0Jg7{0Q_r4cHd~CINW2BJ5&Jv#IY#=!tr-OU+h*JH6DO8w=YEV(tgcsNz0-Y zhH~GdM!t3p3NL;H{OhM6>-kr~SiW&It;QFLxBhj7%7cVFR6J_{Os>3u;&H^}=>p?Q zUxc>GVT!{MLrMKeir5^acnroBZpdzK0_#9m%<#hAPM|nEYP3{-ch&$jZEa6cJRUWy zsDWgs2Qpf_KzQvS2#1FtuYV8F77QkYKwlz_P@ELe7bzp@b-oa{vmFYKOa{o@v#f{d1_;iH*=(iZe5&0L5wV-q=DjsdWH zUxCc_?Vw*ip?n@=V>t?FS*dqU02bI>-=;Vzyr{N81<2ji2PxG}km8J9K2zK!0%bt~ za#^OCD={|tZ^_R+Y~-w-E?}%Oq;H6C^wYc|&^-E*tY~uvKwI&zjceR0z+%q^V3x}2 z$i@SZTqTBS9vzPNv$STML7CAdiba>>a1H5EZJy+g`A;cMtT&XpA_Ty=$^}W4Qrz{= z*rf-QS!yA@6pytz*qp$k4GAo6e4Hs3E!Uc*BJ!6!JMCB01hd34RymX+)&gUb!BB)F zWMx^hId=GrCPeN|!C*oDXr@^d*7H&*$tw9{*&yIiatE7am;KXO$K%kn$8<(;{z$#B zFchxY2&si`KgFVmVJRL-sYVe}>ty|(w0t52wh9SO4=7Q+dL0h*ZLNoUS6gEG z!;_mJtxyRBzBmcfxw)e|q-D{T>HC01cT=n)WE6S8IAz>U$;u5zwrn=|_Jq0E+Y$9GVz1tn4>`k_|(D&wK)KIKIWO z_}?p^YaI{jaBc=2k0H^jK$YA+{(2>Dg(NG6Q+t*913*M`lFw+71Elt&HS(BqN@~N^ zV(j{#697$H+fxjOhscsySlI~92@S25PD3wP%6&kZ{m6^TJOuc!w0X#*{w6?fq-`?f zmDWLSX&o2@40`_I>yHaRrvOA$9?qv(bZZRckx`I}aeSC)Mmy)A95N%A#71^X8-^I07*qo IM6N<$f?{4Svj6}9 literal 0 HcmV?d00001 diff --git a/apps/coloursdemo/metadata.json b/apps/coloursdemo/metadata.json new file mode 100644 index 000000000..8c34d7ea8 --- /dev/null +++ b/apps/coloursdemo/metadata.json @@ -0,0 +1,17 @@ +{ + "id": "coloursdemo", + "name": "Colours Demo", + "shortName":"Colours Demo", + "version":"1.00", + "description": "Simple app to demonstrate colours", + "icon": "coloursdemo.png", + "screenshots": [{ "url": "screenshot.png" }], + "type": "app", + "tags": "tool", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + { "name":"coloursdemo.app.js", "url":"coloursdemo.app.js" }, + { "name":"coloursdemo.img", "url":"coloursdemo-icon.js", "evaluate":true } + ] +} diff --git a/apps/coloursdemo/screenshot.png b/apps/coloursdemo/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..350011b3f1826f3ea978b1f3d4cf678cbd3e2d5f GIT binary patch literal 5901 zcmV+o7xL(dP)&M7!fn3 z1QLlMwT4mVw=i(Y9u>rtRWSo`0FO&hIswdx8l17foLpb43~T_e#^kZf3yf~92Qhw> z5EmGj$_S0AB?hHTe20PEtc2x>YWh12{3I5}42%bDmI#5B6L_U5F?p>9HuSH? zxS|GjWp5YSC9JG^Q!N-CnI9PV6X2C(!m0?oVb>$U$S}Irj^KsZ415DEi{7dY{wuC; z23{0>H_dtlI1P-v8TckpR=)icAl?kTG6b*N_6hKU=PQI$ZZE`j#4LE{CqTRzctPYf zFzFNE-3;6SDGL|z2@r1vUKoKlO#1|QGX{Qr_%jzPcLODh-};3ujf+hajXK2`x(MFmMczsBJ%JcQ#|6}JbI1By5sA4zr<5|$XB|*&AhHgwbe%+k5=j{7vNBUfE>?bZ?Uf!(9;xHBg>^NBj@j38(gQWDdgJ_411#dcFCrr3# zOA1B|cnyHuLmb>h7y)1jglFAAF3<AsOn zYzYyr1*()^8{{@@%au}M&U9sr#DrHSSgBG%)7mro`fUc5p3bo{^7uy&Q|4_2)D-~? z3``mK?DJr;Uxj1_j%_>bJErt#opS@8`5}ALga60UQCNIdxdwnHsUwGB8Y3O$ zAZOAcJ{`(Q;?*-TE!5X>5;+sHw-u5!aIVn2LBKQlsY518!_;#%2*XGJvE}h-i zOxD5)182*S*SK`k!^#EN0Itr!Acr`qzyXhY5??yd!-KifCazWjGMoA0=6oWE0|TG3 z?)|Q`!BTW?b&D*AZ;17T|tQ>P;HKz6tfH!D&csnJHRe+r+?s0IPC9(o9$E76~ zElsn$5o6G^MlFdi82NQ2Zv(Zu919_PIeIXyv;ow;5R#^q{JDj6*Fln29=HOm0k6JR zNE8!@&+*RGAQe42qp&X$8E{L_^<<<03+o?qJg!g zKwFZm9i!#z&Bz@wvsBTPfouG|7=+RZ92ZM5BSs?eLa_ecf(B;&#`y6HpCRcyVAzQ< z5lbPhmoYvNhsuHyfn=LFKUPwD*yJ;t^HEH^{lL8dv_iQbaHVZO@CrcdVZ#T&oBM%J zFV`scpHfc`tSnpR2Oh~_{J=Sg-P3x(HFmnkT?&^Tw5=}(eoNYT!la>gyQaZlN749e z01A$%y*?S$G^~TZ6EzvbUpr~Q+_@nmW6k{L-nE*$-t=-fdjiG^^}74w6B)50%EVx( zR8g$~vzT54YArxvLgH6aa<6iq1Z3C00tk;jh+c$W&cbh;kB+efUZ@wBYpoAnKn#-r zKuqt)`I2vBh|)=7R?46n)6#NAGcW}z1{hs(DI4Q^rR8}NU}?1_LdjifIs;q4%P}?v zIajX)a*5#BmE;ZsXUnm1=~;$>Gau2pbS8g9DrJ&`vhe~S#tcjumXj9}LvnJU^on+g zDHFydlV7t3u486z&%kIII#1Y$29|!$X5cH*Va``us-^{I%#sYyq@q-g1mdewl1fyq zoFso>;A|c8nwTChBQVCj-3eMvD@%rsV&uS{(eRvYEt@wD_*HOgpE+SQ#CRp9y`o*Y zk7krMkX9|M<;xj(G!ss&uRUBAEb#*_w4k{U26p5*5mZANctN~%G3f&!MkjH8`A17D zYy_$_t<_sGak6v)%W8#w0K5qUmwbj6hjt>m4{-X8+-%L8ZBkYPT2FgE0Al+|9NKwH zKEZ^sC9lLp<_&iD1kEaCe*nBi1~$1@81F>FxX3>`O5fhD!X$;x>`WW;qQp=|pcmZbY4c@JRe?9Or zP`feRe&9tIv$Yv71FIPQb{-|4F)UyBw>3`IEbj})Qom4#1G6y}!Y5>4jsflG88v`C zPlxk7m<;Lp9vy0_zP^(QTY&?~aL^e#&yfP|GTd_a&jNQE&XI#T#2Wa=6L8eoVe{D* z6gQ0WoqHu-@L9`&`#C#GZv>+C=3WSqiJ>tOyeXKabnAV6L5pK=Fwp3#lT9(dDp5ek z2|5d+<$5uJP>{F}JA`(fV3dAq<&Xc*0@@BQE%z`%1(+Dagv1EyKE zz8}P!foEZ>d%f=mFT=q3iJ9cL)!Ztx{JUDc-Ep&21@8xO!oX?Y1DNAUTXg=P0X@8b zSkAA3Yt;3nFxJhO_k%ZKU~t5b0@18`y5VKXg5M9~?FU{GcrA>2KX@|+-mm6q0i1Qp z_`^cM2S%}$9zJPu=}x75`uoVAy{(Rq z#SV+HFBIE&yU_Z9Jz_HjGakb*rpP`wZe*;v-?JylVPXuYL1 zqZ|NY7~~R=Bw&@&@g$-7YRkJy=sp@v1f6@b<^-u56X`cfr(-`GyuofbN_KIgf^?FY zmFCx&mXssUAEbgq10bLyy(@?Hfms)r>M03`)yfq|CTuCYbs7q3TN(L-FG^xPVdk4I}Zi!*3B+?i-G#fKEF!$_#k4e~qfw9)bOm1cF zVN9$sCZ}CF09vJhCLy%zSAmT7DOeuVO28yPl^L_aOBtB<73e4W#vTA0m;P7=E&-{< zCXQohPExem%psd=wQj=5npU0-VqoB547h@O@+zx6=)NU3SOdTvybx||Rsa|Ox`EPj zgmrd52!wY{{RD_54Q$b_k{>veB52o(6N7A-AR`Cft@7tU_0emdT3GlZP^?^`3DF!t*n)I*?;^5@U^fJ`?&r8 zOCt8Iw%Q=I09fxb1SuwM z&?G-E>vFqr;8olh-q6Yk14|5B@-}FGV2(+lJdM$%$#6?X^ajo<<)f20>gO%`fvJor zFff%FMTQ5^GqU2AjL4mE@)MWnX^3{d`7|&O9Ar0s*!8u#P$RCq``S*-&&Sy zK{PS{_5;tuSofMg0pg&6kC3|0oMn8VrC&Id0xxfPGf#B;reH?FED&)Co`B$);)1z> zW1w8A9K=OQ`MH?RgUwHebvTWq_GFQY`7@{KDPP>>#B^+j+ogwS{dfh^L*!c6Mfreu zCrb1DZVjwRm+U9><2*d*&)w#2%R)PT>F|sq6jS>f-^bNU%hT#X&X7(g8jMVde`mqx%KfEs9Q7INmzbG`b_&8zV&D?9va6K<@)D!AX5hjnIns~3 zNQ~tg#xU?D=A<%0D%Z-`43h)MAI-q|qb}*|LzUAUD-&9n6))!iCW#@f^)AD}T0<-y zgij__21Pn9k=-PncF-*b=9m*REtVs#7}#1)fq^k|CGrk+T&>oX%CTr#QNuF!NDNP# zn`q!f^&iZ32xM5EsVpckXV-F=O$@8OB?gx?FvtefPPg2bv~t)7kbKfI-y)s+q72sV ze&&{lgJV>U5jjGj;~eH3-aH~=;qo8lN(?XM&o=Gn8`{sP21X~pD!p3^DPykClOGt+ z$iP3Cz8$=ojCga4KLFk!JvRftbhKaEEG!8&1HVcjp*8da;N1-TR`7;HkN0nCHUqyE z#G8TZ9`=382C$nKV#N*N2SB_Tcr);$=X8jL*nZ%rtRWS4ZU){m;;}vO0q|yCh_|k$ zNxN3ms+~Ii6Bs_ukljJX?~I*0s;5WqIIcwt6``9>a8BFdgw1i!0 zF^AO#^?{iy)eYA9=R!IP(VR)Q{PHGNG37|*7t;?r8hiE}#zH_l(?EK}Z~2WuNDZb0 zI6j2H2i|DmQxw#0_W8&Y{3*~Qcb!^dt@Q3$7Ed{*8nqzY0L?-At4(plOpC$ zWXg&RJn~Vo?nLIMEFhPmRf&Pc2zk6zX*50Vx|I=GNk>6g(9V(s)R?*z69)!%eqhg- zoQ8#lN}5(nhYcN-3#iJVROm*rEvShGrqR)XPKf5Enpu04VFgCUiw)Jhlxd}n8h{t| zO9IY{^j4rv$^i`=wy9leF|T^M=xJf!3gBuxE3*!6(M{vli|fOlFmUHSy>4a8(f9y( zp`%-N+p=KZ4E)YverKz44%`gH$=$=cR6+7fLBe&;a1 zvsIgcHv=!`(Y)>5*bMwmu6k#yHUn=4ek}vzkh2&6pMD2#|Ngy^$%TVI^Iv!1AKnjq z@RQJ(7{ib@mZnR;r8zOH^E5l9&*0K_(0sGn!+u248;idtRT?kcw(u=Kj|Z*4@V)L; zd!%lh=0N8IZ)iGPllqnI|M-S>5^9KYhwru_!%CIo2G9m^_l+X`r!q~g-L(I+FR%*Z zNXJ<#M=Q4$H(GwKzDo?OG4iTRWwpEXA@W)<&CJg+CuQp+Pl+M1{Tk7f`b}bZ%GTB~ z0=v;SGU^$ae(caXgS3w5b)6fGm6rWhV7IP-+IZ1%(CpL3t(M`n6~IZ3D;k)a+1PkZ z!^{Frt=$qEtgLH8iYXyfyi>xl-g@#|{4NljDD>cGvwFJ)k0 zTh2#V@-94SWAi2O&LW7>^=1rg_3LWh1nv6hhSC+`OJIJpTyxTw^8-_W)t*dkX6~zT zHBinXh|%>XUI@TVRJA-Z6EB57x!_hWY*O$G0@+^T3r{sbrTxP%IYMV7{zUoFaxIuCi zme^SXCg(qwJU0!RpccU$N}Z!k-UqreLmO>P0L*DCj!~}w814}}R~?r287vH315WKA zsC^6g63u-qu-Yg)vwAMrqXL+d7FPgl?$pk`SIfW_slZLnnR@$DUmF>(>F_kDQw-*@ zNQNiIMAQISk`9*iB_%`+`Yy1cT6_b*(mF&xum)gm6DKjV6xpUWxN`<9A+nA^E;h`t z+&z*MnFZoY3|#8#JHYEP5s<9`z@4$OMDa71^^qOW9KiYPPE)dP?4iq@H;Nm;BatOX0lG6_MF}yeZ>LtX8MsmRmn6jZyZVlWHE}MZX`mzV` z?o0&1^v%E(WBQb=ml(JMxYYh?Q0E4)+RM+&U