From 0692ae20aa7e5cdcaa7bce263af247659d3eccd8 Mon Sep 17 00:00:00 2001 From: adrian w kirk Date: Sat, 22 May 2021 00:38:30 +0100 Subject: [PATCH] Intial version of font clock --- apps.json | 26 ++ apps/fontclock/ChangeLog | 1 + apps/fontclock/README.md | 43 ++ apps/fontclock/app.png | Bin 0 -> 33522 bytes apps/fontclock/custom.html | 200 +++++++++ apps/fontclock/display-01.png | Bin 0 -> 6287 bytes apps/fontclock/display-02.png | Bin 0 -> 8956 bytes apps/fontclock/display-03.png | Bin 0 -> 6665 bytes apps/fontclock/display-04.png | Bin 0 -> 7018 bytes apps/fontclock/display-05.png | Bin 0 -> 6261 bytes apps/fontclock/fontclock-icon.js | 1 + apps/fontclock/fontclock.font.abril_ff50.js | 87 ++++ apps/fontclock/fontclock.font.cpstc58.js | 59 +++ apps/fontclock/fontclock.font.js | 26 ++ apps/fontclock/fontclock.font.json | 23 ++ apps/fontclock/fontclock.font.mntn25.js | 76 ++++ apps/fontclock/fontclock.font.mntn50.js | 56 +++ apps/fontclock/fontclock.font.vector25.js | 55 +++ apps/fontclock/fontclock.font.vector50.js | 42 ++ apps/fontclock/fontclock.hand.js | 10 + apps/fontclock/fontclock.hourscriber.js | 137 +++++++ apps/fontclock/fontclock.js | 432 ++++++++++++++++++++ apps/fontclock/fontclock.png | Bin 0 -> 2669 bytes apps/fontclock/fontclock.thickhand.js | 103 +++++ apps/fontclock/fontclock.thinhand.js | 67 +++ 25 files changed, 1444 insertions(+) create mode 100644 apps/fontclock/ChangeLog create mode 100644 apps/fontclock/README.md create mode 100644 apps/fontclock/app.png create mode 100644 apps/fontclock/custom.html create mode 100644 apps/fontclock/display-01.png create mode 100644 apps/fontclock/display-02.png create mode 100644 apps/fontclock/display-03.png create mode 100644 apps/fontclock/display-04.png create mode 100644 apps/fontclock/display-05.png create mode 100644 apps/fontclock/fontclock-icon.js create mode 100644 apps/fontclock/fontclock.font.abril_ff50.js create mode 100644 apps/fontclock/fontclock.font.cpstc58.js create mode 100644 apps/fontclock/fontclock.font.js create mode 100644 apps/fontclock/fontclock.font.json create mode 100644 apps/fontclock/fontclock.font.mntn25.js create mode 100644 apps/fontclock/fontclock.font.mntn50.js create mode 100644 apps/fontclock/fontclock.font.vector25.js create mode 100644 apps/fontclock/fontclock.font.vector50.js create mode 100644 apps/fontclock/fontclock.hand.js create mode 100644 apps/fontclock/fontclock.hourscriber.js create mode 100644 apps/fontclock/fontclock.js create mode 100644 apps/fontclock/fontclock.png create mode 100644 apps/fontclock/fontclock.thickhand.js create mode 100644 apps/fontclock/fontclock.thinhand.js diff --git a/apps.json b/apps.json index bb37a489a..8ab683361 100644 --- a/apps.json +++ b/apps.json @@ -216,6 +216,32 @@ {"name":"wclock.img","url":"clock-word-icon.js","evaluate":true} ] }, + { "id": "fontclock", + "name": "Font Clock", + "icon": "fontclock.png", + "version":"0.01", + "description": "Choose the font and design of clock face from a library of available designs", + "tags": "clock", + "type":"clock", + "allow_emulator":true, + "readme": "README.md", + "custom":"custom.html", + "storage": [ + {"name":"fontclock.app.js","url":"fonclock.js"}, + {"name":"fontclock.img","url":"fontclock-icon.js","evaluate":true}, + {"name":"fontclock.hand.js","url":"fontclock.hand.js"}, + {"name":"fontclock.thinhand.js","url":"fontclock.thinhand.js"}, + {"name":"fontclock.thickhand.js","url":"fontclock.thickhand.js"}, + {"name":"fontclock.hourscriber.js","url":"fontclock.hourscriber.js"}, + {"name":"fontclock.font.js","url":"fontclock.font.js"}, + {"name":"fontclock.font.abril_ff50.js","url":"fontclock.font.abril_ff50.js"}, + {"name":"fontclock.font.cpstc58.js","url":"fontclock.font.cpstc58.js"}, + {"name":"fontclock.font.mntn25.js","url":"fontclock.font.mntn25.js"}, + {"name":"fontclock.font.mntn50.js","url":"fontclock.font.mntn50.js"}, + {"name":"fontclock.font.vector25.js","url":"fontclock.font.vector25.js"}, + {"name":"fontclock.font.vector50.js","url":"fontclock.font.vector50.js"} + ] + }, { "id": "slidingtext", "name": "Sliding Clock", "icon": "slidingtext.png", diff --git a/apps/fontclock/ChangeLog b/apps/fontclock/ChangeLog new file mode 100644 index 000000000..d53df991b --- /dev/null +++ b/apps/fontclock/ChangeLog @@ -0,0 +1 @@ +0.01: Initial Release diff --git a/apps/fontclock/README.md b/apps/fontclock/README.md new file mode 100644 index 000000000..cbdb2a3f8 --- /dev/null +++ b/apps/fontclock/README.md @@ -0,0 +1,43 @@ +# Sweep Clock + +The Sweep Clock provides a clock with a perfectly smooth sweep second hand with a single Numeral Display. + +![](app.png) + +## Usage + +### Button 1 + +Use Button 1 (the top right button) to change the numeral type + +| Default clock face | Roman Numeral Font | No Digits | +| ---- | ---- | ---- | +| ![](./numeral-01.jpg) | ![](numeral-02.jpg) | ![](numeral-03.jpg) | + + + +### Button 3 +Button 3 (bottom right button) is used to change the colour + +| Red | Grey | Purple | +| ---- | ---- | ---- | +| ![](./color-01.jpg) | ![](color-02.jpg) | ![](color-03.jpg) | + +### Button 4 +Button 4 (bottom left of screen) is used to change the date positioning (or to remove from the screen) + +| Top Right | Bottom Right | Bottom Left | Top Left | +| ---- | ---- | ---- | ---- | +| ![](./date-01.jpg) | ![](date-02.jpg) | ![](date-03.jpg) | ![](date-04.jpg) | + +## Further Details + +For further details of design and working please visit [The Project Page](https://www.notion.so/adrianwkirk/Sweep-hand-clock-6aa5b6b3d1074d4e87fc947975b1e4b7) + +## Requests + +Reach out to adrian@adriankirk.com if you have feature requests or notice bugs. + +## Creator + +Made by [Adrian Kirk](mailto:adrian@adriankirk.com) \ No newline at end of file diff --git a/apps/fontclock/app.png b/apps/fontclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..763c00b1de9f5c73ca4af264c6d65cc5eb08c090 GIT binary patch literal 33522 zcmY(q1AJUjw+A}0t;V({wr$&u?Z$4@rj2dewj0~F)3CALySmW-CCZt)NUI=ICNh z!pQ_=0+I>BlaP?`yO>$4=-Vnz~p!xmi0pkbKfL`ReHICO}5^$>_h=|FqN1 z+T#B>Ik^6>SRetJKi@F3FaeqWOB+;`|1+0Y$;H|n#QBrHAPfJ0O8)=y{+ACw^C$EF zPh(^A0@DPc_lO?ur$Hv8j{v>FdIHa_Hjik6PtV=TbJ#ZRLrE-bL=v6 zE{f?77wr%0u9JKZZ<7z1j&1Yv3C$6-#ct5Ly1E0Q1Kj;R8=uOy88ZEDJr6}c5ra;sB)CD&=tzG=m9)p@-qf6EleOm zE@`Bl+7`Cf8b)vM^B3mk%GlW0CZe~uwaFM82YUMW$k^LwZWpMYr~%F94gi^85ZnIV zKuE@qVf1#04tI?M)r@3H+?Q`MtGy6$sah1RSV%6wa$&(IV<<_DLh|;9&33cZhSIvn z^}$`}QF$A?I#aBeq}(@$s@IEaYPZ1bYC|TqVx{D^Flc9vm)$Nut74Ti=pMhv z8fiv2T@(}#T1LirznA;5wnkgC%jZONG;Few5DW_R9HgsTYbY)WO&u>O^QRzm9af*< z7ER3IY$Hzt{dD~O!KKZFz-d@(8#{LO7L@F@llcadT%R3lTHEn&fnA4(oV0b-)zz5T z*rT&3f(b_-cfkdIH>Km$HwhvR zlrAUk&BOKGt#TGhMD!@HJ31p1W69IQU#uaqIPKh+`CHg>;KYJ_o>5zi2RrFlH1AOG zZP1jI^|8V2`u|M0>@_>a&)cV)U5`7ndi8M^HW}s&Lo(`^ES8s+C-?2DdYxpNyWGV+ zxoqmpId7;Tn-RoTZ@fiB5woc_U9QqIcU@)Z2lTtEs;QY4%<_&M4k~XGy+TVn(~?5p z7l5Jf75#yB_VDP>4nLO_AQ{v0g?>}Yx6`@qTIcp?@tjbIjWzufk)2(=DK?!4SDu5^ zbhLLsnFYAZg246e>dG|?)gkT9N+UuWY}cD~l7Q}jzQDK`?%amAQ#mDJ>3|37|yDMwpnmmy6U88P5XqKAF@0?hZMM+ z6f!n|<{KmfeC4UEzJ%_=`R_R3$1SXmJDcq z9x290I}>0K()J1}lZO@$S2p_@ot{nzwzNlI$X8hc)-#Lcu2f+VPA+!@^eBbg)A95w z)?(@Kn=cb@kCc*UXd~O0DlNzl338q|=9& z8&jbcZ>rEEKQhY7F=b^oy1)ej1SfBc14oe5>nOP7ZiKyrwi2m6{2W7HAMv$hSZU1c z4MKvWX02c*314d)TMKm~kGwKpOoChL$|Prd>6i^#4Fw7xs+d!3@e9l-5k!N71Awt$fnO`6 zEj;>g#6dcB%cxfIzSwdE%DD66aZba5p#+&oC?2+n# zS4KEE_?VkAn?`G@P%2S4K~EM-BJNePYHWKkL*RQb-j@=CKEd7VV4Y#XEEy zLZ+_GP3}1|%7etZ%V`sygjD*Uhw@3N+$`(eM0PkPyAmCmPilZCPp(yf<4w#2bQL9mdIakWrL+8KdE$HOc+OjL-G$H7bkNgd*VIyliOG+w0ue9j6Mb4+j_I>+(u@Q%^T;71izN9tQ z!r(LoRxwRK3>qeo_2sOq9lUA5D;!0}X*_4~eY`i>5gHLn@DE#YBL-MTY!;QwNIxY! z35DFc1{`z?_GB7l?!2+gcLP@n0&HKuVY2?O2y`?_(OQmi8tLC;zc5r-hygi}(T{`! zgi6CXv`onf9!B8f@u9ypa&wyor}b4dj1#OxN%UF0u#G=v5ZNvX+H_L%dSJ1{aZZynxmG6Wm=) zK>)0nK~X%Da*xrMV~s-s|K^s;+PI}ipa*g~xNE;|1As!eHE`-rndaq#5I$QhGAu4T zT3wX6*CRHQ)_`%HXBVt~QQ|W%2;up&IB!Mi$atJAUvVZKm*3;rf-~TRm+s1PUw^5` z1y+XGfYxT@gRKZuaGH9WFu9ej4Q^z=DvM6y?>E_`)wMCP&ZMSuh4@`#M_Li(K-BXP zB+qC856jbqrfoUPQ!f70O9?kLcV#Ffd_Enf_8n}UdgpXqMHNp{HePzd;*$eRI7SqN=aYuuv$mffrWlb~q6T=H!t@OOwrrZRoT}pwn&rQ*3Z=e`ziA zo40N;Lw+a^cIiB2G}%D(jKb%jcdQD+TK|{pLTKFj8l`gj^cdj9OWna7ri#Zf82@ zZ<#$gggk#z>Oi85gHbax0xOZOrp}ajaG)G>U`YjZ zkynw%e7XHVK)nTK>IX?_b#?M_iF9h`BiTx`N4Dg}BRKxwC`uS@pJ{{Q<{F-|_%EgT zPz1%Wt3>jG|H`WiQ6 z3}y0-QsXYJ)ioqx-_jOyg4qc|;5F;8DM$b``~tp$kia+BRFsp~ThO^+-_8zCxu<#$ z8zn#h(|TYGiB3aPnqZ@CmWV?*D7ehOn5B4h@-5qImil_&OHL=Yf2*lvG-mdrN?iEA z>;!3BhVtKkGrrT47M$G;mxg1lQG^fL6 z1@DgH!RX}nU+^g2gx^c&Q<>|Iu3+!O-oq70Za3kA2;wVUCluWot$saIfnZlMf@FGR z0$#h2rT39Z=#NKjY*J2IO)~>YY+s@m0=S%pp$2e#wk1mvM(MYwd;Hs-w`$usmK3u; zm&=Hy1c0j#oDQ}&Yf8r@=zO_xY{z0*q94*xD$xDaZp)h?XOC!ATn&Aqqpw$bL^Vpe zo>AI;Rm1gL{o&hqDrkZkdM80%kK@kG*W`ztsGJ*roBZn$%3ztpOT6|#v?qAswXuVS zg^Nc46}k-5k5?{t>ey_#Ih6upei14qqk)XXmuI}p;@9g{=NLdY8|+=0E75+)2VvO` zPkq%plT;Sh10@~`C8tP4@PfAeo7Q9)H^t=;B(@W?ps9n<(L_2q-#wwahY-^2Cf40~ zq5p_v{m+OR66rjI!lE*8gm5hJuH-i01mgB5$HH(^wVi8s!O}9)CQ0&gaR2T7<&YBZX@UJopb8Sh zFEpG2InKAHUOw0&blura6m>OV7cI6_Fu{5VD7r%2lY|KK-wa+hoaNT=nYR56 ziMYN-sB3AII@V-Cc*#9tU(9MZ<)>RgR@S)YF-iRSrKj=X-QL0p(4lFHdjUy- z(aDBp0kwsHXuA0*JD_V|XsEO|63i()l5au?5AbjUp@@_e%%=SBH@ z*59%W66H0pHD~5XE?VG+8S;PVLMU^CQ#Wq3#(|D-X+;-w2PqWuGdIFURrqHB`z{@w7uH z-$O$~jdP{sBqTyr&FWDODY9?}0WHi~Fj8i`nRkwuVcdl3;4F*Es6G7b(^lvo}P{RG*IpFIx~9c{;M z%I@R&G(6sVYaReHSTJw&n%f>sBA-K_KP>XXQUtoP?^Fa)v~?B1C#<7?g#r>HG7Nm- z7~p zSPVcuuf!-%HuD5!oIStWq3GRzjeK8D|8xFwTAoH3b0lYU%LTqUw! zy|KVs;Bp;WjjhNUu7L9nv2}H!=x}0vt zz~Q%$8&hoe}M{i~q-brIOv6zk?5bOaiGpEU#Is#OX5JlyIwzotIy$X~xy0D4~E z`K)_N8C^ZS$3fjK#7`ZZ;@@XVtq@06AZ%?@*AdK%KBpM&!jQpZTK?O+J1k~i8CTD9*rY^1tBn4B0&KPPWQF(YxCVUcZixX-%?Nye2@94%5Z*R zUJI(78)46BQJmGG{a3&<-Lh=CN5XC8;bX%mD)slZOR`i>d6f7g2Zip^Tpv-_JM8h& zvXMI{bHw7otxzVLZtD@)NZ{Xd7bEGKYg}O^Tl}OIsckTif)9VrA6tA>3+h|}uEHKb zELR2+dN_H!iNADs z6Xv`>r|{Et>?x9zZ`m&VcYn%N?F{DuwaEb8-2R_?O~{swgz&ZO2Q@UtrR3AtRT%3$?I3lGQhMhuzJIoY6+D@Njk2fu{gPv4Mz$UE>k+;R=Cd2&Ms4(9wTAD@EL8SjlV%U4^0sco%n9R zExQp{RF)?XJX*=f5-{-atPE>Qm)5Hl{-)rNk>7{J=&K+5&Z0fS4bJSR8o`u5;T_;sGpSd z)LNM+c0vClk&D&%=_B;av{k|D#OxAf%^27Z#{V;k{Hq{=52ZmOy)Fj}TBC{YD#Iv z$`fIb8Zpk9?a;P_@Q|afBOXxqyN4fbo#*1fFkQ6X47QGyjja&(x>h}ALCx?Db3Fd! z<`Hx{`M&a;-r+%_zqtzR;Ie<5L)DosDI)pZO6+F|FL4e({TAw)dFNrGQvFRrW+70p zW%J<+u8>v+5%3AsXV~iQ`zBbw{kkw3(t^1J;{_?!xAVq+ z(cpp_5)}WQg+Fd}KTr5GmGA-CdBw$mFd0)%vxKM&ezjRNn;{IvcVVX^au>mkh1$8y z0oI4!_bV`mvg#yOvoNQSwoy(h=Q0~)rM*v)Ls66rUSkxTP8&|@{9ZW2V@9a*GZDve zTQc<>JY-kg+ECl%q;tCWagu4E1Y@aI8!ZJ9LFfupF?z5lj$HCr!uTtCX<&AhWW~9i ze1#p(%d&s-l!xb$x#}|@AYi5a5+K-%-6lqOd;RZIu~K__1yn)T%&0^pa=4uGk9@C* z#H^=hdKM42QCY)|jEG7I37=(OD1j?<&8z3GIRgpUca%SCb!^$`=WD)rzEWp?rkRM@ zj9g0Iy@vaAex8vJ#>>S{KA>o2RT5TT8A`GG2xy+X_&n>H?v z_e{aOqrnsjzexq&7TgMO7a6eY95;l(C;<5~8`#bULCz5&B~_EUnd@O9Znx*bnqQN1 zuQDVVe}BHEUf$QTX|F9UDs_w>6TJKT$94K(sB0wV^bEC@#(x_x4dMgM_TtAC)ShwU zV`5Yq1Z<{+%C#mw-|s=H_$36UQtLbc->QyY{ieUUs{I7HSL8^(cCc0cEWbwhmX$mA zz6|gb<`*SFHBRR@udDF2Or0kSh9-A!kh)@lK1Do4UZ|iU$zpXIb()YL_Lt{z1wlto z0KZ)NFGWSgxGU@WSdkiliHQmR29~+NW=bY-6v&6EPdPATO);Lu<=vq;ai_-e*}|`j zeE+O#XMUj*5HK7u>5%bx{9Rn0gv`dku59me$`doq^c#@v0rEjXNhQvDXbxuZ34qjc z&p>{zJ0j7q7r1l9BgL0p<-v>>T6~m!)R14LbQ1$fp0?I5<@^o1pgp*#5+U|`v-g3Z zS?vPubNekUfDnXwe!P7xge{7`fbE>a7tS9kiZ%+g({B{r^nb}Tv~A|16E;|QWJuY+xru^9qfie{`gVEU7XDM8cn-y6yQ7V3Q_7Be#DbPy) zQFc8?pAVtIQ_xM7xVgqN1rQ_&&lZ0CP@&R$I#zr-*^3HqHbvp5qg0`<(rHI-jip;F zcIQ#VIK1ikL*c}hu196@J;87~+O)h?YYryn0d2y)+nlSY&Y>B7rRj z7u<=TZk73C?tKt6W&)xb)FLqlC~F5gu16ziDH`9bJxw6~X_H)BZRiqcYD-8Aj#kB+ zH-C)#xAdE3QV}Bs!Yqf7#n2ezL2>dH*C0j?rv;keR|?=WWKtd%eIZ7xK*Gd{2lqJ< z-8nm>?uuCL6@;?@!Rt25&eZm2SLpSZdbYWxYs)}mbKYqYCx;R{r&!s6I`}Iw?To6v zzHb9fs%BllNL;uU`V0G{oIpV9^{m9rO4~$S^!h+Lr=xI#>?1KbvX-Z3NfZH(XmD^a zX3ydmUG{j=-toM?hQ-hVvEtX|)oM*H<~MeTFz|;tagS#F;9}$x%`ilnq|5hh#eL4v z+J8+}Iar+cL2nLR4m+A6W22CMVq%O0PqwHyZJNQa6?fj37nOD1E4HdmX7%%$IAiIK zUF0|!0k!Zg$VB`Ud>$8l*G#QvRX(*wOi-c7;zy6AG=V0>i|Zu;6P}I^Wm3bdyvl!} zeK5m%O9K>gJi>UBR7VLx_-PBPj3r7IZo65EWtq4yS7c^ur z0?$t27jZG0z$Ve8ZpI2#DuxWgL8y@_3uWy%KTb=Vnx%H;@n@{_9@PlPl0GF-*5=J= zxudLsedu_WfLeU*FX>1rQ5PoY#^VYZS`H`^CML#Hg@a(ztsc+oD`d?}YFpB>GrRdi zedfte4P4Q}kztw5Xq;bh#qN??k;b{z`TLm2P7R6d5+hLeOMau{VeyhaixNX%2s@X9x+-|u> zr8Odzt(czUqSA}yudg%cRO;rYE`CJ>8}BSedG&k~BQIzx(*_soBbgTc1_cw0HI(CB zFnIw``x8rGM)6%8_u*nClL;moQ`$;CLq1JV%b~?S_6(tXxwc%nL#h~cH+lsImuwY_v9ykk`6kWF4DaOPBa;< z8_FLaVWc(ulfHkKkS3R51jsW}f_IeW;^kZ?=iTT&J$FXS=-U?GFb$+F2{r8L+ z`RjL#@b`p5%;%{9FOeZP8giHu&9D1GM(;90TkcDlz%Qlo_G=y@HH{jZ-nSErwR4ru z51V4BE}_F08>MmHKn(q$W<)|(=_LP#vc^ph$B)qU=fCu3BN9u&&w4_o_>QmeG)-9H ztAG~wGVeE#_P_aPJV2tVxM!X` z9v0~V<&$x>t@-J`N}cZk^gfOt;1uLqyL!Vn_k@2<>=)gi@DPlpsM%GC-MJyb4*r$i zH1g|lt>c>EY3uBABwk67RIE0DYlY-r?Z1$G&1qJeFHJMT4c3zLM-J@k7-y*e# zpI%k_v*^>B(0jfDvo27sNP&>KF~+l*?!ZnI6w|LrH=K0cQbBUiwg zp$?E(2eUWtQb_?v$cXsqajuco&ML3tp%?zCKVPUf%c~@ckWF;aew{Hpw>ny|MM^_C z>?UjZ_EN?kVmoVGmwC$+Ol$rn0vhLTSYO&9)dr7CI*vR(Od7bn9G%1z@6LxJN^(G- zY|tR=kisM5@3sVSvwQ3Aq+AkjB=n3K3=T=>GeL?j?3L4_JH72l9H8reKaKJ1eEH6v z%5NP7U%$Ry!uD;U^Iyz5X#G*T-9sQ`Bt}{FHlf&iTyBbasJ_;9L&jR(t&H0N;!3VZEQ@;y^05zEgy&$ zPAz)MzJwi7t(QtL%or<>I#$@$Btqo*=%76R>*lrFFnKo4<;iS87v#~PknrAnrg**X2Q06HL7`#tZXdi<}bwFZtv8tW!S5Ggm zuhD1Zt~J2#VbCL+Z{cp;XTSLS8|HU+MN9AFT&Lm!x~|&lc7DYq#nXEpYekQYeY~N( zriROCV6n-+q!ppfo==CJe#9cr#mZxki?arDtmY@)L%(I+i#4ygI-A0UzMu zQRH1qRLaDd&Tn9AKJ{DSCVh*aD&KhYaV^{d>Hr~0z{g{BtlJ+^Q&EA{V%#dws$@Kc zQ>2tZg!8L*T>+7_7WTr>klv>6i)ktN7_a4_*}~YxdZ!U`k-4mu6KWmC^YQSOUqI*p znU)i3!7Kwl*X8Wnjjf|U%@Jc7bv*TN&H4$(wfo_Zpt!l1eJ6|G@KwX`@e^BJuGy;l zNa^2(m%3b9UEsoNr``|pr$)kwyP~Th8?j5;Ofubnyc~e+Z$?F}l^EbbK5EH_@Lq4f zwDwE8g_u!Z|49L+X=K6;@5=BU;?2jFMo=8vbsRo=mtq~vo9$M*V0hQa5=n}yS0m1B z4=$&=;5oS!Mq{-ei>md@FcWjtoo}7uf#;bz$OOEI2=pj5!(GbE60*qZ z;)Ui|=)teOFwXYR4c7p-)(V4W4Wj22dmCvN3VN+cA&)HZx`qY<^)6vDa#3?9(F_V| z>YkW<75|R`q5Vke_Xq)J25n1vW#P4E4k^D+=YpR=zg0G`UgB`@DJPevtbs<>>p}Gt z9N5kIRsf6`oRGp5ArUqMmtjEZc$%OJ8CjqD-5yF(V@ZiPy6WMXbb$Ai$HC~>q#8UP zE^e52?#+Gsm>KH4R6|7@Mox4jJPuCH06XOMeckewUiS-D%}`g(qD{<7J=I8gHFM(E zWgaOpEOj`|GzNAg4(*n$!d^)e6F7AV6YpQ9<`t*pI$kb3-?baiU$*dxM`O_H_s{E( zM9l~Ms?#?e4WB_i=D-(|s#M&dqF6=+Bvpefa-ol>Y6@0fL!$R5l*Bf)_4R6p^$ra0 zwS1Qq%AX5g%kZ9;@9>+)PN$k_G&&yhLRo19CC?NIgwXp6yl&2Kt4E?Q9>byr-XFEP z{bcVNei?V3IWcEG?(OB>;n$%sQLIm?LJjl@xPH;TUtiC+k;?=_4h(f4iwz4cRg}r4 zMdVA!q9srg7l-9f4hxo;N?O`7pjP_WV;*ff126PQPk#SY#RaqMFJK-nx0qvNRd&zz z=!C*nE&B$pZ!-0&R0tUe;RTJl6^H`8kJ630b-SP&5g!^6MWr(Tnj9MuKaMRA{#vcIQF??YesVmQ1rpMFGWt zadq0ai|DCQ|MPMkt1W#*j8Q9P7hRXcpoK~BgM$}yoJhsf?>hNR-a$~y+lwy-IiGmk$+^XRs0PW;WB~lHSIqmd zQbh4*)!k^plmV?Dy<1~K?@vEuR8XUYG#Ia6LA8njSu}3 z%5e2~#Ej!On7DPL#zVT=k~d*8?ZE+(qcUY%`^L#rVOUsl9N_!c{&j;-P!ctxZNi6> zsd;V2r~dKryXxqEiyftHALg08+7vCQDtMiyNB%rV=c#nZ-e)0G2SxbR{hjWMn}$9> z=HjoQu!)O)oulaN=VghX*rR?AZ}NtIPq=UhE+GZnBBHg;9go3K%1DV~De6U>gvj{jw>7} zWiaMxW1LOH_@X$)tHO0Ck$@!+zka~SldrV0GEk~KEMvvksh#q}o%8(7YyP{8a9L>5 zA}IcTeLi-xap?~;!xy|msX$2rm3ZPk; z!Qs)i?$&Saa;cQ9Y&;zkJfDW?vYAnO)4sJ%E)?)Mbv0LL>fd=#q9n~b%zVblNg9oQ z-x(flHnw`FXU_ev&n(x^uXEu`2&Qf+5Rm52EjN_y%q`U!XXVG?agVty60H`m03H)Y zU^WnLHf*qiI$j}fLXIx%%!*Q3Pyo7nSaJfoZatpu*B^?I(!y(O)z* z5s=N`vR?sdm?8@FCzax(1QFjJii?5@AL4qqVFe$Zkea}jj{O!}{!Mpe^nIf2y^-di zgczW-p#F0c|J6?^<34T5&-kD*G_#9ZA^v>MKNV6n7++8}J<9n%X4Bz$FPukC;~>es zf9XoA2#Av=+dG~^`B?BC7Y7E%DNx-N#0#yQxTAh`CVm%$R4T(06KC++r_aJda>}T_4N1>SbJ4@@T<_8ve6RArSVVds#H-GKH)|0| zDrNacg5EPc^=1_3N%{HxjZB3TQn{+5qa!di7!5?U{EzN7aRdad2!R*K8mPgGxylLy zZ`=r>W)1VBLBF{vhL!G#hIZx;9Z0W@G&TfJ0B3`=`WSR5>&+tr;}LzRN%&AUa@Dcw?E{lT3?u! z_M00O?Aw9NZb|Gz^H(+ek-YbM^6K9+{F1P`ZK%l{YdT&}Uv8M4z}yZ$_T!_?PotiI zyRce-dOtPjKc6PtIoEBa&A~x~!qH~(HmH?F%j}Qri-60HzqYa*#7`SriM+GAKjMtN z!3Exy!uQL!TJ&hi705>vZ3kq}wPYAA`@){yq6O7P6(ZSs2ZeY~QNm-PDcAVE>Ew)0 zPHGur1S|^T-qn;SlL+59^X`TdcZhX)jV)MtG`{{j3P9z$q*<0#QcFw%a};_r zZd>^U3W%XT-7nL@oSEYj)?fECA=RMv05rJe6+@{DjMF%Nbf=R*DJJ;%Kd0b%PeZp= zbch!9((Z_8f8B5!+jvghE<*hQP95w>Bm6v4hZKWqSynH~7Ti}KGeH?qEVlakNd9o# zD!cDy3j$_)S)1Xv^W~72<11qq_%m_j92}6F z#qW#qWeX{_idEbrG*aAZn1xQARnof4t;P+I04<5}Lm!(Nq!>dCzD-sNi48A`$s$?T zj|-goc?3vxd8~zu@~U0(*=eH(E?1Nl6V`0+8m=0MNYdH0GP06UK5R0?Q~d^8khIc; zNmoF%6ip@wJI0T48=2DJ_*K(HC+R)smKrVialMW|&GS+&0$-iZTJ!10-pURi-1UCx zRUu)3q8bCkv)(&;c+2+fGQoef%~rdA9JC~kA99v|W5_pE=2h^qhAtwfESdusa;@eE zyEKWw9+~FJf}NOK-$!H@e-FgL9P7X(kFkVH#UnWaeyklCP2V|733f6z8 zX!NT=kD*-pi)-)(c)$AVGj`=huPd zJK%7NQeOOGLr?ePi)}fWwWdq`?7`7P4|02;IIygBmB1ol z8w?K=qtbGw1Srd?;GbJ0UhrsKMS%yMZ!cUULLYZ&z$gWaQx^`Og4^DHp>8oEuk*{( zEg#q&R|_)Op0Vn#@bM6dD>!8EHT`_`dJ-WeLJI$z{Oa7Q=6SMzilzoU_j{Va_H;+> zJoGE9^5*h%69@m&j+=Qs)F?(!1mH`(e7YdSi_xLZ>Dd$T?}HiixarAA#oehu0&EB# z1ZfwTQ`f_f#P0(;H}yUrN>dvjw_D{43;Eq`a!CBJ-jdTPyk1eVb!sRUJsB?b(8cL& zw(#pPT%@~0DzwbwG0#5;APu&DaLm|v4NDPBlxG~ z*Coel%xCb+@5+72kUsy9V(&7|RUJdG_nmF}A8&IIi1snZQ)-IkY+6MqqeAKCrl3X$ za=ZYC3vul|!uJ5zUitl2tdY#XERdA-^5U2y$_wt8$6wfIZH=p{pHkdcLA9@{+iFwJ zpbLb`b?0}FmK%a1W~R86)SZ5V`8_Q3(W#!~-=^}~v3{_7TQqVI0gaB1PD1S0q=b%v z5nD5k?wxtg#s2Uxf%pZx&GE1?yi#}mi@4@%$Q}isX|ivV&94p!(xajk4aeU~_J^ET;&gry<|9euGj?1oLRdmPgFa;TJS6&%4*DBTIIl_-`y%G-h& z>scK3gH?Gj$|kKnlB*hV=%xp2u)ShxGSD@0Q`~v9YFPo-3WcMty}W9UFFg7P)i0+g z2c6N2{np*${3kzs@6BW)e#ZFaG*x%BiW+*m<7Rx(-9ME(967)lms~5j&qYULQy1;e zQ@=`N=Qa%Y-_vpobg|<#rd@Dx245rE;%_oJf6sR=_URrIw}Z9Q@? zELb5cH@Nx`TRg_?0YmAM1a>;dJ2=xFgQ4#@n}CQYN(9EZw4@{lR z3J|K^umF8GWLZ{J)%gwX=4CQrhkU39-L^Q2SO|F%5$#Xv&OVV%^_D$g{Y-6@4~dhD zYdC>6{@{KsfMl)NF}ZomUkcywcBPKlZ5mSM`Y8QgcslWCM3SJ>*NEi7TWaz$Ga5ub ztM_BNUlUn3y*HUIiyb_>#DLQuB}DN0=Y`e-y`liNBu!XIOAZZlSY0lSMX@r!F-D^$ z0C?1)2_jELD;`ZX$VG7=!~H9SjxuacMxKCSESVXk>I){iPNt&3{v?f-=ehanBQoDtFm2J1ku8H{N_VVB-t1kI_>F(Havf|dAwa$=&z zI9&q0GvRxVAPO!+5Ao#d1kxbz999_dcxQN~L6fQL@hit+jz9w~#Ag^J%w)Y47rH91 zY6lv5SpSa6cRan8R^`?;fA@DI(EZDNNbdLS|Isaxi)Db3+?Sj} zmBLTOosNepT@B~(Lo5zeky9>=VsP}n5)4+cjjld{s@PTo(hQyL;50?0{P7LihSSv3L`vQ8Dz&?kHtzB zjxTz=OhSS5TO66{PbXQR)KaaWyQYjmI^FMjETB%+?wtN{0ll#ge`kGQgpcu~u zKnA(adc=+|P+M$xEA6jivG-X?Di_8eq@^&R~W( zWV3K-0&#KS(MSUQhY(qnXd7`#yv#fS_Y;(9>=R4%XhDxZ=3!Fzfab=aP@tiTl@?}1o)QR$gB(I_@<5rywHXUQiVF9aEKA56 z1Y+)p9#5jIHWJ{0tesoRp}|-EO0yJai=+MEJ5F!o%qy^)uK<2wqJc=ny`CTlT>-G( zCHoxob)w}x)$TKS;=iU;wE0e>MZ@-QCQ67sZ2VJ`0;MFI!18%nM)Z&ZOU#7pTaXnx zF4e2xFQ+Rz$!AXs^M_p^^`Y}~42vjlC+ur4Q-y2$=mMgy^ZLR z7?S1YSZCL12Fpddexx`+wJzWqL@7V5H#f!1;Nak>1qu-+b2tjICKlEu%YS=fh%of_ zJ(_HZJsfLqxkL%nx3vu!9#|hw$?%2GT=1QdgI`S=lr)F!IX!m9xc!L zE7Cg4OE9EPv0NN-_xS~N>xQu}WXeGtOcFwo-E8p+|#Csxlx0E1MopqJ!CMc3j^cI565rgf^A8}TF`!Lyd)4X5` zl*m3tz{9`vloxN;PuSwh`BKA}o@YTgGHZxlYf1SGD;ymEM<02xmW*6@Zb0`?bcUlWnIO0+cO9^EKbrCrS2QI8=FDXgz;XjBP7@0-AFSjm(u zU-R5fKmG%stu{r?{`m<@KF!C&HON=Ot1=+0tuW=UyN}@Sy^lk zK*-;v!4je5N+ndI;;3f2PRDxDO&Mef+lbArLH0RmS%zIeI_lp_nc>N?ic|ewQwj64 z({505WRUxdeqd{yJWu0i(2vbgw_fMkJPXHN&ic)rBcS9Rp6F{dB1@>2*Hh?j==R@& zv~SM9G2Jmj{~kJlLuwc+y|W!i%8B&{7nK|)ul=ju2&>ep9At?ckEVdd^-`D1Xvf&@ zw>KUN4SJ1{1_91?#@o&APgK)=>(|$bMq*eaVX<8n6(#@0X5tDo28mip1P2U`>*{tRGX}P6OKw?J)DEZ<0@fveuBB1mne(yN7L1;tL~m5r zR-K;G0P-QkYqb9`QXr`!wC1;a-@$KtcwIFQA>%?}vMA!X^IZb9r(3 zkRyk0-&urs5pVY>C)C1aVNiL0-0$9BiWV%qpNFiItqAgguFIFS*=;eoX%6Uuv36r5 zb0sN6P}i8Fik|Pe2J@G03WEwPBll)Ul9P$6r-B~QbL=h_0U!phDfo2zfp|BU3SR$~ zCIopEqAOr=Mk`X)c1os~TQ3?R!r&aT>b~p1Mnl}8YlwmTfC8ypmT3t+s38O`28P3kl9^8yECr_hNklR{6=AkFQ@wHfX@gVDM z*~|VtIbdAC8f10X?+_1fk#^oBHS?l@#Bxvv{yzboKw`f$%4Jw+5GeIvdFI9U5k$TY z902UEL2*f`aaeu4egFVK07*naR45^VUI?pGpsJ&~x;mLKZj_ugd$c_J&wp8ZX(vD9 zKAINOY=;>z0PZj$1K}gtQA&cj|E2wNbWF4gk!TTRL9{)|B{gN?S?h|^bsQ3ij9yt$ znkVHYN2R8^5*Zk3rMB{@RF-B*T{T(bMyR2@qBk@cJRDix+j62tUxpBxK! z!i>XN05oGqw`l#lfBXY^?4e)C#*LdSH5N=UP3gZGFaYkqx$bsP1PFu6ZQHgTMiySW z7Y+(QusTpfQsy=~i~TErq*T@>z1j;tw1V1_G*i&T{i`c1vbg_cDiv2(cWJ7xRRE() z6E^OfyjWz!Am%kzN!cfh)Kp_&@*^Y(#TT2JrMs=OBY#m##1Uso| zRdtLH9js}g;xYJ<7X**ue<9Gj;Mf z2@7(Ux88bF7Z_`iX&X<+F`Li5Hvno)5-1IcgUM>zAbTau>dI8RisR5 z0>!hyVRc0_$_*QLSn;62a`RsPBiQU>!-y$Yn0mzx0w~%%|N8g;QL3s2A;dTSNM++< zBIIyZK7>_OO8ISZH$(L>_#LgY_UzsR%d8s2poUZ&66xW?k|beJqU2@nL_Xp5V5OO# z$?n-6iFxmf8886ui&;I1Hc3sn?|tvR_vMZ|ZUuf^BnW1WI1ON04O@F;>WC}k{L8+D z>g*qhcHFCD$DeGfW1rV_}_yxCmvx^#oqXC=w^<&9J<(W($^&~=ZH$aIZjjhb_NW9`*wa$ zsCDj9y#c-*J9erNYwFagQVVHsSXeN?Rj(jogBF0@CH-)=w(pOC?gStAxpXVsv-hCZ zA#g1SxhVTvQR%SaLQAy9Qh>1%3*NW@c)_tDX;6$D$vF!35q=)68*EE2O{0*B<5F~g zezdRzoPif4*0qpcCy6`yPlhV$f3Lg%Q_C7OYTvItn3q170R!MZnADy$NiZ?>CvyO= zUHiFAn>JO2Ry2bQ3iLzN$yx}YEGK%h(X791hm|qVn|fZAT35=gKYU2$ExbXF78YA+ zQUFR~ltv+ya7G{?xeumfTCv&5V22_naQfjq?W5ym3ew2VpEY}ueDKjK6=ty=_CI#? zFtqIs*w)L6W$%lZ2c*?p863+<$F|Jplb-a@x%%?+9O@g`I{)c8S#s_?x$NSFV8iQL_saxWXh;xP zXDk5tKo*)=9JpV0E?gKWS&j#LotsyL#iU;Aw$&r}(Ki-?anJ#CEObF6%gym5#K$NL z9s^tH4I9==X4-afb3xiu1+jBa=D4?JzyP?nX7VK4;og@Z{qVz&L49d0RScHY3)I&e zP6p)wBXa`d9{~tz$_xrC)@+s0h~*rFV0N3g?uN-_lbp9`E@C^UDX8g%WJ`ppI-*n= zrxcWAeU*|sK+Nbn7J!>zu;H()bYT&425Yi3emRTPw%UWh3yaHz=go&sxkisUCN3Jx z06~|0&X^}Z~$rlMOQ928aZO!X6i zMsn=#;nTXew!a9+GbAxa_rc9j2U%3N4aCY)V-;ZlJeqr2*DVT8RZ|Q?(K2qeudg3s zN^g|%GHXAsiPP*(%zLlQfB|r?OykKlLiV|?u2vQ=UMLF|%$Fmez6@&<9qtXseQO5_ zOlcwb$f{D8OZ({X@KDw7PM$Pc)^FUd*#wgk<3VBR;@1|PgZEj~)LINEFtY*W;T;5U z+W^Hr7*w38MT<)-;KUE%8OCS#Z;gVls1Fb;ciHnIFF}@@nVB3#_LQ&4Yp{;91`r8>&Hty-^>A9twEN zpd%2HZ+apfEn?DdOZrX3vPqg?@~;((+(0`O4w=HR$rDFQVq%iK{nqPpBy9)!Buj5V z>@-y;eP{rD(o@(w4OncnMWxcx(&WGYeMNTfIe;I1+at2;lp_W-_n?sxVQNg#&|v9+ zBS4KyV5b}v6@mK*d_sVW`VnCk~iOYP3kHS!=Jel?QlV85Bk*hK2PVZ%nSn;T`_`Ym$HS1*=JFFZ%;;pS%{#~LNgBpFTGY-wq8kzx#tZJ4+rSz1MF~$0QLyK#yXfyf(l#I5pOt2s+|M? zuUxZ3nr7HuP}a2;xFE8023@_tYgiySMt=ypesJqeGH&X{GJDn(88V~+;Eob+U*Ko76QhFi>v2^$zW0$A-6+4Q_;xh*X#$B>P+s3n~JY(K3<~ z6M${NhiOWJ)HLI8k)t|i*+3Z_tCY`1v+A~);5*rq7aD$ z;N1Sm?SSe`=}(~N6#NWL7)X7>Myr09yhqo}q(1 zt*dB1O#~Cbq?%=LZ16#1ZVS|UtK(ib?3dw^*z5|*j_^1NK(?fq1<2WsW%y{Ln0?Z$ zl8Mgjy|lF;G)W_M(;Od)V+qkC9gLoBdm%_^FMZzPx#~TYn}1Zd3{|B^q_(OEW|$uO zne7=Mx6NC3jtqdiGfRC~hd)@FP-bLgAau^va`wFGupvg`?p6e%a|dxFTu9BxzS0zu zP7DMval}7T%}|8Jp_h;a1YY3aE!LNUtLoYY@$lk(ZO##_VfW#epZ&X$LN^H+7IaKrw+wlZ4^3$kSAu08r) ze0`y>CRc$!Q;t6a2EfOkqdu#_A1PT(`qV!4)ZewA3FAkC8rcA}y5>)r^%?99b@g7yHg08ENafO>cZV82W8hprMLj*Hipu!Zq~fH^x<)u!Ay~=cTm83zkk((M!Xrlvl@ZVpKl#*)_)czEC|abZ z{IINBvr=As@jvS2M1N>*7YsFSeKcJj7yx%UHGO-5KXCrgNqs;1_!IffZywVQlapYC zK}Q2zv#6T|0s^=W0xfz25eN|xp_Ze8QYtJ2Kn{glVetE9t|PYX3@kQI0G7cx!^6`D zf5>F0_u_&BXBHTFmvtvEv)@7Sk&=y=&~8*7v!E}kpU6hrb@^_!=b{S>zXQi_pJN{c zcO&k*;?l)1@TitgK3${t`}_IGbyuA$*IsjlhP-|KwKqVa>(CB^#v4gBr@X6T0NmBg z^x=8_ut{M^X%D5P%b)-Fm@Iw!8M*%I3xrlw1dT-rISBmffh2km(c_2Iueyo=wggx@ zOdJ&he0KF!>oxA8Cc<R8^ zv@6jD0cHV}E{bH+4%OL7YdHO0qIMruReFt9OV{PuidPB;Ifh&X{tL4 zYqZ5OY4Rj_{q;8xh`vbo#sFbXKFD1@}g+==Q%ZDG8dw%>KNNLCG z9(FLC6LeqeG!POD1PLQ{vuD<)dnn3nM#pc z$AdQc{e~kjJjY5(z4Ej5$gUWKu(t(LRB%X=lau9=OD>iVKKM|wvvUlHt%um@s{wGQ z)6zF5`NQ=>d}fAVUA}xdG7c`2p@TzY){M!rW9L4lkWrwl+!IqL+pge;Uyh*a1Q2bN z16l=GgrCK3lS0!?kkp!>=N}6f4YJfh0Rd75+hi6Bi)aJgie9_2UbSCf@&Oi>Q92^R zgC!RUzwLc6(QUKQyp=#)58q&_wicf=TPDIIX+8vU1#rsPxobbR3dmgyYEABd&KRL# zA@F$)fI~)ze%H0@w%|JjK(&-7rNub_bf8>u#bvT`e>6$k{IRjhYHls{hDJd=9T%+V5b zIjASvW?>(;{WCxFKE9BW@)`w6HhaxQ!p$>4JiPs;sE~=k+GsDe>1CZ23S0grj^ zKfuF>Gv(D+UXfS-_qKfH+Kb>a=%zV`-u+;OjK>dJ*=PRpoeIqoDWKvX$*M1Ye1S2|)mKQ>1^lX4TdEDRQ43A8-KHz-zo0%Ks>7$RPN zVd576wpJU!-Wvy`dSuNR`J3X1F?1y!7%r&_&bY%PIsO zJ(K91!MwxNCv*IirVmXXtUBiW{6hK0*RGO(|MzY9IwK;cpv{Ur-S0<4M972*6J*)4 z<+=zua{zW9U)Fa6;C_1YHU-W_w!w)L$IIdcGo+@X2yAh^+T?C`g3~q;`d*7lrIIsWl6t(K-OG9~Ff35vE%q+1PNnB2rbwLVc{4Z!oBFwEh*9 zBMJx>5`vfGw!s`16Ao8LBt~=eVXYllR1or~zP4N{%8KNMYcD_~k9>LIKX0i)35UV9 zxL_nF4U%18leu5!qM!>Bz&(A+IQ3;_og1&eRGxnBe*iU9X7wf5UX-csd)TlPjSseE z%U0dL^E;S=XJ;m%?`MD@AP5;Q=Wl<1R<1%Ix+eTMX^FIX>nt$#w(o1D&bVTqV^m8Tg3ykd6wp>xv5yu4Lf;$Z z-UpwQ_dedBdrsNOQ?Nx4b6gZ?1w+a`cu*|NEO#Q7)*!jyym=d{^zSQ3YJOS z3)07zpk$OsN|H%J`I%TQDlP--?5}%DzEe7E74Cp7v@^s_Yq1Eiek27YSV{4ygC$_S zVHZs>*^36LDQhthz|=`2Wa-NNQe25~1Awg0Ju3|^D3LCKF$mdlt6TQXn_*+^<{@=8 zEt_wJo9F=%ebv19^TonRpY%iM=(AK}4F9yJU{M-p%vWENi?bRq7^JkBPnj{~F z6n;>z?34E(^!d}{_iG?Hf`qK$Qp8)PUoWXP!AG{asv0hR05&Djl+?CaYAMXEZ-Kf5 zDU0=LomQX$XQaBMq)NrHSGEj89QDx=*>w-F*$k97VN9~@Kaj1uVvd3AImZ(n87g^4 zOSB(SP;2SnE0zeY1N&wGxS_sI^ATrd=gGfcdAD`XO$##GacAd1poMofz;?)%PaHo= zwr<~}-*LfNGjy?df9WdmbgM_3g~~ZZMn=G=cnD%=uY+pIM;8{yxBODR836a;W9JW( zKYFr{|9$0kx%!Glx~F3}8iMEf7vE5dm^3&Z>~%e;YKuJj`={l)o9@Ifn)^@d{z^pP zpz4Kf5hQ8@&5JC$*;O1UKvlTK)3~fsYF2YXa|o=l6legm?qwa#uny0&3`&T_D=e)V zTZF^y|XJ%s)74smZOhrq8I^Muf~lP0KvM^;wW zm)^+302n{LzA9w%Xt?qI2Or6#aY+&r?g!vjt3-D<(x1HY+ETgY<}1L?dTadU&sJ}c zC;sw+{Nu@oVAC87i8MTi;A%%F{Q$(Lve-`OfxqCaV0{C3>Up`h1#k#X?yHrA15~7< zEL1-+FAZk`*7ByEi>6@haAkR zgIB91u-x@kDs|_WAH4rop=5g3?gQFCzZ(}Lx)rKG3*+Uuxi=^4OjAszZDIT0zU3Nu z`PC0#(Ul=CjWp-9{E!zcn6IofxfXlTY8}Lv=)eHDj~+HzXXQ0$GV>EvB zrTD=jmk_AP$II5p%;^)=@PT{F5+oCQ<+Tswj@xdQabt(KQYQkDI#fC-&_Kc;K(;Bd z4jqbKhtfy^&VIRnrlACLB=IvrWCM$?hEyL>PfGz338xZXR8U)GoMR%i;GiI7gP}lz zS)>)%&X$N%C){e4)e*t$iGnSdSyH!52{h;7;Ro*kckv8#-lf`i%Fsk?E7BZe<2@F~ zz{O!2q|)owZ_|4jlIIQx#eV;%7o_NDj%d)k`5j^Y)O0pG}dKeZ-PprRN}oYX}Hw{fj}xf zcg_@0%>CF8N6OyR!>aq`GC(#uhHNzS!Q8Ja8{XQxb-)FM;3dn;#fIC3__%2K{&#MG z6#n1ZKVwHzr+xHjG5nwDeT9Vwz~_EH68mJ8N^jbs4f5WbZn#AL_~eW5AI_8dsvK-f z5dV7COxd$%FWMj_rS`_4kkqmiQr{4;odjoiXxJA{es;U0VqxH7K%ntD_s?{SP{#(a=={-Jthv>!T3&$)la*b)Zkq%Lcp^S@ zr8+Y39*%+PES7S%14_?O$z)Peg1rCXN)^N(!moC+X0_)wE zt{4FK@*^h&qaQ21Xm)Q~C39y@ZI$+t`tIF-NPnquF;U7U5-3!yY}~R_sT4CUD9a0A z(PWXT9-0(-xi?CFUKZG12D!7q*xAr6%HIIt&q1*06O^J+_pAF=jE!R;1t*Z%52IeT zYY*p0p`)Y1VO15S{<%Yw6J+0kOazO!0tK+Ga76wf6}Hq}7>NVKtr$W(>aB$FlBH%J z6y{wC9XJEf?}reJY&28EF!(#wR~Cfv#&Ka0I{U2Yn)4|Sg0ynf;ljkl=ac0d#LKN( z3iA(1O3E;mGcc`&QQ?9bNme}_;B#nTW`p@=S)}XVnuMYgg|T8ZIy9j zhACTo6s++DOXlMTxmHrsawP_!CaY}iP2n>PYD5bx_ZEbatv)K%}tqy5dJ} z7ame-%isWHB?*-6py~`eOF$l3b?fWnf*)Bbl2t4jn zYmm&_-_K9o4oeZ}j?|pv^F;gfXi_SSx*VSsPS&|WfDOQ$0Abqan`rvzCXsL_JeZyX z0D9`)J~+r<+3!m9qYD662fN^qpZM1RD=n*_PxMP?h?Jp&HJ30Ku5sW%_NQh5=(Y{G zqc*5EIRSpBtFAatHX)iN7n5@6$A9qso8;l&KBXy8>#H#)_Xe3WXAW5D4>8vE;fNfa zpRsQSz`gWn2_S-p0+p>Bm&@GQ(-a&8ic$oCZ0+Y;WZdZCYNWxRH+^QA&^rhA#lb02R<{_5 z&?sSMdltLQ+AeBbLH3$sY}Y3GXFIVNPe^#2QK)k zX8^MTnj{4!8{HnnbYiFj=W(_yU%6iAC@LyU7c|vxW8tt17Y3@*==;0~KE^kH<#HHt z48|VZUmp6|ZSvqR|AYkrY&AmEjvbY#I_rZ6Qq@-a%fd<<0NcNolYCcjz$xIP58s#B z)5ieJUMf5yASwAhd^lSvqdz=}NLd(-f(fyUp*~u*W)qAX2En;K6hb145>e>HdO0~c zNHN+7!w66^P*4wdE5~muXcg?%B0+FcXH2Js2&j7M(N<`15KJE}qY7PQaE-tsJ4#@v z->&`L9qWPu4?yC$XH6d`d(%o}$gt6{9`ly;j2t!fMCMS5jt<4*P!379rK)mX1gtfN zFicXQqrw6%8T9T@=k!ZRhyOI_!-ZQH~{Nk-}BL0;{H~Tw(@6P=hQ6 z+}}dOs@I)|O~CO!0?gBsiO0yU;(qi+cD)q)Xq7|*A;c)_v(PP(l3ok9Jm)|#j!2Yw z&v-=1+`4Ti79STl=g*M!n|CVmG$hvVx8SJV#LPJm&@##Qykttpg#EF5_DvPx!0r-1^1=Y zi_(0Oz|P4n(2kShL)9^!;8Fks7&PGU_wxkMf{=)Wg%LMw7PAd()+OkkDeXm@q`aKy-Apz1AfI4BTL zj1ONAI^i$?uT&QeYhkd*WxrbsMoWtoFu-0s_+7Y{KX>6=S%Yvo6lU#DO;;h5^FqQg zTgCc*77e#za8WhI@I8|!j*`cpcn(exHL~dJsj~FF*RVfk7@jjfs-*$2I}iHnO;t0#ILaUrP&g(77pYu<$MQP)ZU zQ(Z%$mo6Oa0b{lcISU`$KYrXuI9_mX86dM}PLt2!_Q$qJp~FH0HQi|~^xHhArL74I zew+(XZ0BqctXl&YL7Hun%`b&;io!MusYqcl5PKMS=NEMPsE45BXqR!YFS&4`j2xaU zzxwUpuwePf6&KBuXP>^dN}>3B#r=%#7#;@a1A^B9Qf(VQ z%2vX}@#8Xo-vk>e6j{&&P_)9LVr6YfiK-wiW+V)@MK+bcX|3St;;Vx7h@YH_dW2qj2$~lyj@FlQKfF!0Jz;u znh%@-rFfvObWT{e=2O@@Pg3=YO@%1DB2cLQ7zK%NHds*l{N{pXrm+UWMx%tS+xEhc zBSnE?%`B~{5IPo=F*mP30o;UO=s=iKI7(`@C_wmPBL$QOpGcKhV$cUwQ2b2RozW=O z8VlC~5uLID1{@q87X-4}?33Tgy4z}%psphujm3a~%0*18z@QMQY-WM&-41pap=Fz0 z)U=YJcC3-$)ow&bVvmn{V6f|2%c{WkDX0sFk1{zEvij5sQ%c>=-do$@6!5;b_N>!b zvTΝ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 literal 0 HcmV?d00001 diff --git a/apps/fontclock/custom.html b/apps/fontclock/custom.html new file mode 100644 index 000000000..92fe4b619 --- /dev/null +++ b/apps/fontclock/custom.html @@ -0,0 +1,200 @@ + + + + + + +

Please select watch display

+ + + + + + +
+ + + +
+ +

Click

+ + + + + + diff --git a/apps/fontclock/display-01.png b/apps/fontclock/display-01.png new file mode 100644 index 0000000000000000000000000000000000000000..e7100a25fa02c69c807f941b6e97e65b37223500 GIT binary patch literal 6287 zcmeHK2U}BHmkyyf=@5zAg$n0wN+kl!V?C0tD$b^xgtelwK|(AV^P;UImoi zJ4*A4fK0si&i(E)-^@Jo115P+_B#7r?|%1QYoEPxqV;tjP*bo`0001LsD`QmzQy6M zAu`Yq=6jz7IS0>nFR#r7887>vUZem|@YCCx;YBJhfTCstM5fxWt}NA}2U6StK`XSnOPZ1hvc_AmR4#f4K#+9I z%&D<$6!+P+E>Va9xJxA^S9HjdTgp0SjKWZU`6Y&ImoVsV-KUk?0FCshJWL-{c_mSq z_AR3)v2xfn*Ixf}eKQ#sva|Kgn-k~_r5Vs63xVRRTZ0TZ zPHg@VO+xmvw$fS`YkF}Q@!${N{yiH+X=Na0bQ&gJli<9MNN%ru+>tyqv=n*XH#Ll@ z%D-znj7wD=a9llVZFN9#+Wsu0qIn|t&@pN-KVyflUQ49g*6V&^x0H;8>f6XZ=c`0k zlHd-OQ6-|nZY3V85S|X8MTbmiqX^6sg4r(QuLDQtD>-mV#6NH#mtsENno6HC252uV zZgU-qd+%5%-*d2c+5Y(9VPL{sR>+g5%5;FCW{sW5dhtsXK;IJpcihy#W=)8ntkICr z5)h9Dv5hLXUBh*7m=O9eQOyNQd?oGFcn`7ST>{8!5ZcrND@oWD1wW9=bO`EGd<(s& zPZ=KsD`3q9Zg$*pr=BD7Q4-oB3|+bdBL31TNu(qhMfLEOm+|;ilA9}K_ARW zfmJ-zr@tLmJn9H%NTp#?F3~48BE2Na3maB?T;RGzFiAtL;#M#sOu^kLYQi8Mw%JXU zNlx0a{FPpk+~S%;x71hhCZg&vnr@x1Qs3DESPnuhyI?#)$tq<9-ufFnB>fCb=oqy- zg*~MWrLsnla{7-!j%v>eT#J6_bCv4B`LknQ6%CCI!xg-VvO_K6En*j91l6Vsb4FQ4 z8^_Q=2+IA)?S;sdnR0!gi|!^p*pzg zE?4XUR@`Q`c7BFn4|FZkusdtn%)L`mT#zs$b~aQ7Efd=k&fbIS8CY&OobtUHz;6+? z7$tgn6 z)=WG}knGLz0ho)hi-(wdZns8~H~VW+gi_p++wWY(C>MbAGgC`aoi!orlItXPs=)rok_hUOi2c!*@<8LF3S>n|DO0Ifg`Dw&ikxyG z1Iw3fdY6SiKA3$r+icElMtUU-p-KsyG9AMlE5}R6wLk~&1NC|J z`CdO&xd@9wizJJdh0?aSfr&pIFa0hfNr(s|2o|jxl_EPyRk*r&x`!f$B2?7N)%lB@ zi~Ncn;A~+MtLwNloR4-bH&qH_%6o1J9cx1w!!|_LHue3P!3Axrx6_sWH|#O1vdgXg zNV$#MUayd^knfT0;W26jSoK)@*vH4Go4vzAnTwFCoRU1da=Qk*nzZD!_K)fn#uXA% zuckP5MRsMxZP{<;JQEiXuW=c2M!r3F{xbV;KV(mQwqX|4;8V*oD=|YOvnA6blPYr} z3`f)AjB$1k&_$7}(!GZ9`MG;}BDwKWm&?uvxhnx5knrF!;6lg_F`?i)LFWvL4Ee|J zoLYAis!^`euFj2`jjs><4$OWJJs8R29<<%C-r%FrqN(d8PoTl*Vw_}WTlFp4ERYuF z3z`db3ndGB0p6(OfE|=NYCqud+1oSg3*ZICg`Y__|Fw#Ev7IkV?YJvt056!oKy(RF zfGCix6(hTLMDv;T1pcy9dAV!Digu7nFH>7Dc&E;QR) z{yqJfbN7U=`^)d?aCGBQ-!wFB&1}urB6(^`yGq-(&c>VyYp|ugWHzQY9(74|q_AFQ zf1!m2U*TavL5YI}`l3608D>w)+eDvjZ`-BX?b-FNLJl7uMy|BihJH%ht0OX2Mt1S^ zrqt&gC+`jmtXw-b^9^s^j24Uzk5+*SLS<4S&Rj2Senxc|>fiIt+skNGI8)Jd*VO4( zbu@B>vB?X_?-%PsGdWumtJB&<-aobF?q@m`@G)(3IxCe_4A2Kc(=|**;2K4fykhBr zclSrUhxi9Bnm9eNhiNf<;e0an+VyX3N#gaC;^DT{M}2vw~f+`nD5w?jBG>c*ZsPD`3r#& zzTBIGJ)idKVJ?Mllf0mtB%d=He#a!pzu4?5q%>zC6trkt^V$v|tzX@<%NTfFEom-= zO!H_s%f4)QrQ0&hFuh-$zxCS}$9K!_MeDCtho%mQ=N(*|=cRpScfXa$RLV>r2)53m zgjN866 zYwjc#Ke^BL2dswgAJwmHejeG4sEpL5KBrm?sQZpx(i$5$OqyF{dLi_}?qX+CVeV>+ zBksoa0D(ZcL;KyQ4UJ-7oEIAs!qIZb{BMC5Dhm%95*qSB`O@+aP=WGoE0hOXeUDRW zsuqE5a@iU=nY4A-y)t7!IF%%XE=WR5;{^vH;FKHCgPpiMO;wz53*iM`MZfm{%3DWT zP)-{3^$~!`g49ZncYK`lkoQ9iI4oo)kH8tm#ePK(EsQ($=1*oH&z8kx`Z`eossTYY z#0(6pj~Ey%D-vz|3E%_S2fKIGD3LJRZ@`OSAM-rbuXWS z@_MG6#NZ(QU$2dw3DjOk2XGH>lL3GP^Z-Ju(B4};v zW@9Jl>*D^40+98U#+xp7-qv7W7iU*5XkKJQ42R2sc;ouW_wy+@5*MadQ3=`up?eJneiD z|59@G`fFME1q%H_gdl>#LjN7j8)5%H(0(C*(*9W2pK`Ll29wrD_}V!?QAN1mql%xJ zyol(1**|3d4f)qZ|71S$vh!4NbHNk6<^PqIzsUat|10qiNt1s{iu_aZAILwLzm_1a z=ZV0pS^tWmJVaLL-}?UYmlgUI;C}@C&usqDi%+LKg{;uuTSJ~A-v4YL|CUw@RaG+b zCD_j!^IYShQj>X#-0Ho!db|Olc`C;4n0_O|1YFzEm0OkV*hoFTuF+UGk@cyuclB`h zoaRai03;87kqoyzmIQYY#MRX7d8}9X z`tmu4f=@jpOb0pxahBALrEfb;4_xOkoJk{q&D6Du(!Z+3CP18#*J8OZ8SjA#?I{ok z!gUg4Xb3Y;;pB{%N>~ZD`S4lr`n$v^h*_!Qz2Ku}TS=VGZbMx?ZM z5<}gK1jt@iwrZ;O82uclx>lP^92Rt~0x>qq4B;ru;*J*j{_5q_opI4O_Gm%&qT9ed z5PcTq@WfXZMHT}aDuThi2{yyjw$tkE_2BpFTVHlTt8O7B=&jlBVnOUI`6UBH z!V!ZJeC!Mzf8Bofs2bepO{*UPo(0^9dI5g!6>_~>hu8KNNW=dA4#m}K=0jW3p7s0< z4!|R_zW7@~%O?x?JS?0#oB|2Zw}K9zXU~>4Gj)QzkSQ*7KoBfR`IeU;0UDAa@rn6X z5QLeRQDl?8wkv#gC-0J@b zFSlw0?4opng>hnYeLJ}ToVx{h&0GZlGwYt0b!u9tc=3HC0)VSs-r}YpspBQaTfPX! z=M?@Ipl;0eI$i#kkpZzvK>&>3Lg{%dgt!L;YqDTYo9`l#`{fE{d>-pD1Htdt*Ibb} zw@(D7I1IDTF#xo>L2Qpi5eci`Y#ea#U>AE!1cLD|BF38Iep8FX?-ku>oGawUeH>`S z*O%lurGL*axzVUSW|hOX5Ez;zMvP`g05?euLoaJiV)0MwYhu|So(Z$1NUUFeMvV3p z(ew9lKQ4YatDhZSz_Tap(5zkA#&w-b^FFZ{jMgmY@HE@nzW-5;sN%LHiBMdb`2$<<)Fhy~+%wBWE{cLsHN zX;@IUq|~nb<9OGiZ%!ObF@knNq%+08NlKN)Xr$jS)Lhs#4lW3$9Ef3u&o1(u~b+m&k`Xoh% zPgJo_Cl$x5G`q~k?_6F9Q602(MT447#e@P~Q%zd~0$pUMzo;l46U^DfC~k~`Zbfl_ z(s)x9w_sB|HN!Q{i?vWHDn^~0r7t*(sZIvM(Y_uf)9LDtkcU>I^!|73W#BqGlQzlL zI1OSXpQ2MyBdAR5t%Nw=7W4~z+`i`2tQ9kyH1+i290W-emBJ`!7Uw;Up{uDn`D{~I zTRo>?9T@0Za%x%iXx8U}T#n<--(YZTiSmKx+~>)%B-71>@T_%d?;*_)HfNuQ5yZQZH}Px5CYxdyV;N><##<&eV6bagjY_SItwf@sAV zf^miMCf|j^tH}|NhredZjl9?u-|&tnz`FJ$$-{upv1g$DbJ|@V-H)J$s@kb-3KXE; zhE`K7qOZ?{ER~GWt;B#KHN>47I7KA-{x$1Fg_dXpcbUC*jqrxjk|wYaVjsOC?#PTd z;-E|X;g$)R(TVTxXnsUSbw7e6Xw7)Y45z5Lb2FA^T`NuracfjdQAACv)d1}Z3o9_N zii4Fj3sA!LP~_-?1k->qP(!qXrijQlR`bDAwSw1rmGY^2m-Nd?U$bkAq}uv}+1!X6 z&Bed5#sqvor1>5`=B9&BO?p_k z2lL8!0EY@bJg%@oMyMd!AUF7@k>gw1Bc%=o0`zhj8{7kbR5bAtE6dV#fH393%o6z1 zGsghj^Z)Sw9+su~xMZF1fIyUZ)y3-Bm?)+bMYPcN`f?|yzw$njDRt6j7g&mJ_IFTs z`s;h9LyX7?t<__X@--?0e4y`Xi-#7IB#ddr2@VMiMSCD!?sjzh$kbP}8o+#rwYcMA za*Ah;Xkn7P{@W?}8~K*E(U9P?ES&s(pRRG&93YHJa377sB*BEaeU>2+p~H{TRjbscGi z4fmVhXSB~W6h=cLy~MPJXd#LmkxHCNkeZ9?Nl>Oo2%40aRA+8(b(rOlu30?%gIuz>tkEX7;w) zGr<5{6Ev+k?>B+lxY~8-n;d+xli`d#`nGImzU!Q&X{1bbm}-ry1=~Ka;A+o z0R#uCt|`sNeLSG5Dd3>G8w82q3X~Py_+SSg9A}Ui={|=6FFsDe1XYF|v&~aLDsY}W z_E5<1;chkx2hJ>{L>}KpkD&*jD-YcUb*49pv*AXQZRU)Le7`T0&+!{;0bp<_#FY zyIyFdIRJpa;Q$8fsDi=FI-YK}4$e>jKqWRK3)cWK_#kBGZW^o*f{pzqVi|i6JB8ez zE6kfTBL$mWE#|)bryAax)ks9wrHxCb@mo!41l@{9Ne z-)Z+sGQVI`i=+amP}s(R;nKU4LbcvY%v}Je9HxKB(6$O> zBqc>IWFXz1B6J%&7VKB ziQ%{;{wyM-$NU+L$Q2ni=Kxy9P2%gztQ8{h4zNNvYZunp04kX=dB{Okh4mB#(nd

YDLbVV~OS>(5jf<>zURsWIeAAC0K|Rv&rO*{hw>YgdP`0kzj~e+szI zR%GBad)F*__hL$~X zSYJA1*m2{et<4V3Vsl$WNMg*d>libVpSAzEPF=X$#_LH+H&99((ilDHe3wFt6WT>R zA&*_uEze~U#?^&s)+H6*By8;|gxo9Qt!0kQm$zdPPg1tK4}5UCJDWNC44|>Rvd4NX z=DlyGz+-3YviD^`Hz;{2JIwfn0vTYmS!F-EP7DPH=y(F`9d}fEv!}(*Hc4|B3rarCrE^dlev~f@Sp{vl@p^j(-4Gs*7I-|00}6haf4$ zx_~wpbEk{looET$S6*NjD}0rm=H8D_64>$*F@(C0L{;d7Lq?dLVlbK&mUWmZ@q6Wt zb;#Kw-b^^!Q>2qnDU|5kGr&b*=S7Uk8y2|kV$6^bf!zwm1@SpPi5O9cMeKAFzPgXw zwf2)-;=UQNT{rNj*hlP|2$F8ipTOS_1F4U~%|Bang`|Ni3cPi;xp0Oks1o87*^7G0 z8_GcjLY3rSLL3!e7PuB)>9Ce-+w};O!AE1#P&ScQrk=#GR-{5x`ybnWT$~tJ=nM%=qjRSl>FuV)j1GEgGZZ2 zo;WbN=A=O6O~j2ZlE>}Qc-qd;JA?qjEv=LNE>59BpzXDeF|dkJxk53e%d%4Y`#o)b`q@091-!iv9I~ zGnzAw`-=O_MCwn9YV8N>1HY0zr*<(gR$X`o)Pt3HW}i50$xx-o72>P2KZUjq31tNE zF{YQW^H$xd@_Gt4V_6kd+u^vW^9v3ja}YIlZadS>eE3#G%+B8|DT3KTsYf@b!j+DMBee3s! zNJp6!nWdVwE|+&S2Bq9OqWn?OIM`TG7%LV{^3k7g!K~d}-J?;XQDCJ?CEjA^V*g_0 zJ{xQCjjg_nK3|RZ9E1o;L_3GLrlr1=euqQ$9?_Hek!1~w#<}VMMqA_tXsvAsCcVw( zRSGMGwZl3i;}i>emEvvV4NuQ^`o{!btq9${F3E#dLK~p(GSV_SzbI8bs}i3rouxkz zK9CZ#p<{aeQjAaRoy({*tnu3U$D;0G*mtqThDCUT?|bS+@p%%dU8x?abg45z`vlUy zXMIrRgyQH8$$tH${M_$(!nsL6)SB~A?t0(=%szAyb2)7P9u|KKzjGFTmW*MGQ`*voHLlu=aV|f^-Cbnf6Aahsy>wAQ1mPUg1FopZ^0#susz5)`W+Ryx(=^ zuicY>9xVLYGKX(;R9~^QrPO3}2)Dnm;TWPi=ktBu;dEIpAs48FshX+sT-aWvc!pavGl=tW z+R{dAb8|Y%_^u$b7?3-)dH(E7yUqAN}@tWNs4BWXkh1UeuNHp2ioo=I6iaV(T zR~mY4hmm|MCm&&kr+laJr=8AQ&h1y>Ur5+xHJsI#W*fc*U3W0dGkj+Fg};RFNI*qU zM}X^tbLh-dM7>4TzS!VAmtnQIj%tlS=`!<# zB%nFK?a*sw?!CEJ@a^rmEPha%`Pz#~0|z5xlgPJ2)&9>IjK6t=coZBJTz$F;H+PB< zg*Oy7Q18?4?-M)Fe>EeSQ$L6%>1XJG^&F_Ehr_^%#cI~Ky6y)4XT93Tvfrd0xL2bj zHvGEBab&ad3y=d&VL2ailwMzs!uf>wzHy?o8=EAXkiUD^vvTw$%Z9Wb=Pw6E`El%w z^elX@vvw(JO!ZRT!TFli@C%tN6TI`eh`^K@i{Gqc(`zpfw{GJ*G;6r5M#2;b%kXHp z%t1AjYPF70%pKO`?|%5<*s|tcyj8j}I(u~Qo1JU(H%Z^cgNqWWYN@#+{tyG(PL^0dUfgE=8Iw-DQ@e>Pma&G2UXmB*_`W>x$c-onW6HuyO9^f?l@+* z9G8c~7GqCN>ehF@jvqu-M{5yX6Rrf-{_b5>pBz3;U0R_E76^vk?C;1f-R;sRGBO16 z1xX*<9=vF168+)4(vTdPAPvjE2)Y3;D>o!J4P(p|-L|jxQm>vso&H?D@okpFf%T2q5abw=amIeIeuEi~=#0~lR z6o74pYoX0OHN|qwJ>m0}fuVLzO6bik=d0JFBaz`P0dHO+(k)XqM-y!+4>>?mj)%J;kMmcm+s;gz)b z$Ot;?wSpR{+G=V7c+fN+026~8fQ6 zxZ?#_|EB*4%IkwwRne`!wI>wn>Sgcdtqk(WcG7$cJ-3Ms<_TpM;}_%? zWRbyVW@ZL?+Sp3!L6rW1qo1T%?7h9+B?Sb0eSP_TpYXeR+6f2&fj|L4VF6)bKC}d% z7tGb$(vQ#8i}i0M|4$DD>SgWe;O_0<=F0p>ucejSOK)iwmOqC6b^Pro)X(AHmR!C5 z2@4&dz#oo)5Wk?n{{-`Pu>D_Pe>i``{)+2wbD%%UBy}A8pw7k+2N(3HqFs{_77+&h zW#+$e{_W`B$fsUVPq3Q{8t5(a?`io5{GZJKANZF^qyN?9e{lW-`6mQPZBGZZHOoI^ zC?fDC5v#PGY5QzC9go;bVq|}tTX_|*iYS`g+Codaw2OSNWsRz z($dl>)hq;=AZ7;MO_|>Ex>6TjAdAJxJXJ!M0`{$$#8~%HMAzx*>GWxGvXkRbQ}9ZZ z>!zC<(-t@ER|D%$L%lUSqz`?o1Hjnq4t7}dV{0cqcIMt-8##hASzY(wAlN**T!#(B zdWKs3CBKgPb)8@X7cZI|ewTF>$|w{Yk`LopYYygYGS7v%-%!fS@k7!c5l8!a?{+nF^f!Cnn+JNU9*|^&YsnIWlw^MpEHBJl3gF<+P@Q-O9$Fw{T4H?wO zct&X&4_YE7PGx0~${OkB!lGlDK5o}N4aa0yMMnXZGX3c0-=%$vA25@ zrlp+!+~(buCOQ|XbYv$hG_dsEd~o7E_R%!{T!OP7C;;wK{sNVd)^MCRgEKzuUXTZv zI4fr#PO3m?&z?LYx1^^S_)$-fp^V&`Ct7*ED;87f>9QNY$T7s4tQ#^eZQbI{J3NuB z-sChYh&&CkrLC036DPQTGch=C|0EYno))qlc>*R@M`64;TN zaeszDH?U%+I{%k z`NY}R#g-QE-^cn{~d?`nt5v{vi zb8h+&Q6_+_a;Sohg_5bU&9s|h;lmMw)70Zn>%YkC__a0;2`_Pp!d#gbo^>yIX@Pvu zo`P^;t&L+jIiQ2pubNddO(A$K48vrKTb2>Q`t^%?OI*T#!>$p!WXjb($&gF6SOnWk+MkAa-Z2^EKQo2cCBHo`jm8>jg?(r@N+v7rlDGaEGR z1WYVk4~K_uSG+Q<#U<0md5$s6?{;!bn5aBK2Tq$ojE>4*78`vC->$vE^IL5E6zOX) zzglFYAq*2P0JS(Ay3jQy+}@VKGumC8`rUmWmJ(C=_&y;Kncsvl|F+g=6|T;9Pd}VV z3TbjVq^T*gbisUUbvBru1EMqe+0gWK;s-ePBJx+`TZV2`B7HKON;katLTt$pIf*s9JRjU z7>6Hs95^q3cuUYUSjXStJAG8{C0;H-kqx5eN_y%(gWhn_8iXzgaTU8ZfnA^dhc8|! zioh7duPf{PhZ}j?sJA%A@5R9%(7$ACa^)D`cyA81RnB{AG0Gzf`|$qbB;E*m0gqVM z8{c2EhmtJp`q$y!)*L}q{HfyR9*nhqiH(IE3S%2jjm3hH%KMi+ zBY&D|hnI2JX8QvpiqJ5QB?YWtpg>1nJe*EE0KdCn$et#|wBt;^qAM&~sZGia5_hC09-cK`??o_N)jpMs)k|QTJy4HX(y~_EKIrz>pW7Pr{2RZelipSRSP;%7R^ zhJkq;DJ*BYNj>rhv;&A!a1l5dY&z^k#$a`LTSMMkNu2q07aI< z67n5oEEe|I1DJoc|Jl3Wp^5$uXO{@VmgXtOQ*D;-^hw48=VJbZIf6r7&hzAk zIws&b5~#g-Sv01=2PLJnBz6tF8nvaM@Jx{*! z+$bLDAu_@6GXSy^4J)_LRa}ReZw?gPW;|974oldd6uv5TwpiJ1X=V^o&j?k3z-hPKN9~iumw{pPzw+_I83QaT{VzE z&$LZ>^6AEbsr}8RXN=9siz1`Rft~ulq7LT_f@`$lYE5p>qY`G-1DhA$v9T4$rv(XH zgdiOWC)pv@EG3*2lGFEJn0)0sl!+TCCeELSy_7YCbJKI+keHk462q*HCuGjxQCd8O z^anZG=M_uYLv|cmu6bXYR?VB$`#pxE8dZ9#I>Jbfi|iQl*pBF4Dm;vBG?BV4^ZbU; z8qBL0kJxMax}T-bG`4?gT}Q2mlu%6&(@BcHPQwN=m<#s_D_IbRJ}{q}d%2pWR$Y5p z4^IcF;V97&LrkwHwPa z`grJv?DD(qiQ6h-!vr~8>{WApnFrT$MN7CJ8|6#c5|tPUZR_P|l^`X~`oICn2G$S( zMOcGV9S)0J8pPaI_N2K>eqnL|D|D^th%L=xePGF+5RYnMECoNWmc+$Qow?U!3XD16 z1b6+OeHHyqGHB}u&GF&5cv>&YLh>cE9vYZ}A2Z=2}1hgQMJhSgZA z!IaJ#vRwQoh2< z7q56F8X7^9wMZ$!Y)^^A$Lz1iR`mEUXUwLLUpW7ohhfhgKh5dDyVF+?#B`vunKVPh z4T4Jo<c?=^dlU50g)IB=mcu=kKQ@F>WSHoVBM;ankU!SQ8h37Zt{Cs*T&p1iDp|GL zJlIK_>~y2n5Qh&NW>iEOKOAr0#9oIo-?stDbZEhNK$SS5tJZ93SIetzUvU?H{yq-9 zog24339PtszmRxT)H|LpD`17*Y{V5pjqC#09xUeN6JSUNp4HLgr+g}LYd1+PJE7$q zn~Ve#ceNRiAC3D?}SlwrL5dmU_on+jz$MW>D2@S-+w_YI6 z{fR~+MwBdJ(W((cK6W$RLj>9Y@nUvA-SpujXs#?#G>6^Sj=juIA5`&pZ_AZQY$upGEoa3e@f$i!bY+Kri3;W=a@mr(!EZ5YRmM}xx|HFVx8$g>+rHf2Jsvc4aG_bC z56`>hMs{#oN3u$-O{*ATCR4L^#QZaI1;s7yc!?O`)de3Ap4E_eOO-*~T5K**ds%9x zh_nYK$URqJi83R~o1k*5K2s9B7}+D-{DkX!mX#wKEwC1M`w(8U-QB{q$$Hj15%n{g z0KUf&6_oB#tL?QcUC0#3ZsN}UZf-*rU;xjEes&i&4oli zh-i8vXr8{>n6^5iz;f0W_bRE{rdV}cjeV?~C^t#6K|VbtgrzG>?+lB|7^0*} z6c`h_sk)hn-h3KaKn`2-hQ#)KN(6pkb)WeWyd9`|-H;1*9|?Af!D_Ed#Z|DbE+Z54 z8MD}(gm`Y^#dM^(r990aHpinEy;>z+i&wuPvR-@FO?_+`9p1q%V+dj7QjVKkD?Z=g zjD?i-YdTI{&|7l77!FGE3QFvn#G`}@T+#gq8u>9*H?oU+qnBUBLPC@v{`n#^@c!wG zZK>{gRx*2{d~3Gn`vmdJf&hIF%ad8`DZ&=pWeb zoU9|o7Yj9BEuiGC)S~2NJ`|CQ*Z3lv*<)kxp!C*MP97h)6drwsT(XkiWaHtaQa}*v z`+Mj_j<5Rjkl4@G{ERYSo<{R4&e&)P z51Srdit5_T?%O$Q=a~3N@Cvjs|8a)`gM#Y^K8H3Vb<@L8W3(pY7+wHc)DzCs>Fb0)i}jGQm)p5MdZTL!XrrGdf}j#6&=$ zYjS6AaFg4UieQUWLMl`PnQQp*ElubXih)gTAH+4@x;An{Kz7{pSi5wkUvj(%@3&hT z&qETPU%#L1{jOSfBe{uRx4UUAO9GLw5VGJFtCLWe-Cd$fpg0w~r4Hc9+0P|4hWVUC z)TLJ2F>F_I?hp3tFA^I24t}bHv79Q|9GM%mpQa!oI z62O6(4dO%U0maC1lkQFqpz|G1D_h7oQ(0mq`bR^k=*AQZIt_a!D({7=&^uT8ec-S% zR3r~eT-q11lk%)zQ>fR)l#ia4#FIFw4nN44Rmt65rQ|SH!ESWYqHW~Xoi7y*RI*xW zKY0RSLfApwK7%_Y{gNaSh?`@C?HK#E8-tQ11Y;T*^W-?RO^(N2CQ1U=H@{}S0!Xtl z4b*3Ndt;(h<*uJ&gj2q}WjiscIZN>3E|$K~e{g6*kq&d9gNoYSWu8Eg!|l$4HCm0Y zB=SPqJjh>uS4mf48%Sf5bgitG)HOShd4A5AAt&Raj;xKWx4Dk8<4y>eDU{=O4ZH?i zrlt+nO*xjTxKAcTUsZs^h1Pc~Xw#3gqkvxpvJ0BL|AlC7|Ewq_|s2 zw+v_Aqprw`lLx(UJ6k1CJ0@xmAk=Rkdyux*lRyVpiFEfu-E@PO)t>r@U|yEDI9?7% zPKVzr(nL(OklQ*B`_P)`gmmyRXlrK&zA1J>*g2NaU8VD?F|rfSIGJ~QcTcpZ>~dkB z{5Y-mckVxS57LZLV>UdB`#=-z!k|(WO;zdk80xyxXf>`UrGYFNcq>8-c_ienfGfPo zFLM`SA>?7=yrPG~>!0Nq&jj%-2t$%6<<-dXdRTwb#}*7bNMi?nZDefxCh~+__mK(( zg$e|C*#A!Y`}c289^h5$TNL&l6$MG`%ASX+g$ezGE0l{g%d#EH~bi)fw@<# zs{`n=mLt*K|K&}taK@ulPquX<(gkdmhbT|k)3ffAM>%qAq{{iQiPH0E8lNy#O=Kd! zFbh6jS3DWcxd~+~wnE+usU;R9Jok!a)#Zgb=ygLVy?fxdoC>}AC%Tz055aT;-Hne{ z)}%bzn)tSpKy)vtNXtZe?Xkk_>$$&JH$%~jdD#60l(HB*BOGt3(XuMalTDevxPPiP z*+1_W*rKj8^p&eeQ{$dn+`7zE?A+Fr%neTYMWLDJilox8zE{R>gGTc>@Py6HSgO}| zRK&l><$3jvbNrR3uZ#9AtvKA?Mm2Tlty&p>C z;dT zClvPHykBykD-1Qnp)Jd+EV{P9t`sJOsmRWZ#h(@mO9x9U(~or9l`PRT@u5GR87G;3 z8K4hc{qC2?p;XG#oBtUotanEaXMBba+ literal 0 HcmV?d00001 diff --git a/apps/fontclock/display-03.png b/apps/fontclock/display-03.png new file mode 100644 index 0000000000000000000000000000000000000000..9cbe805447be14a132521192ef890baa4812f32d GIT binary patch literal 6665 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 literal 0 HcmV?d00001 diff --git a/apps/fontclock/fontclock-icon.js b/apps/fontclock/fontclock-icon.js new file mode 100644 index 000000000..d9bdd8c65 --- /dev/null +++ b/apps/fontclock/fontclock-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("lEowkA/4AGmYIHABHzmVCCaE0kUin4TPmUimQTQ+UzmcvJ6EjCaP/kYABCaEymYTl+Q7SMgITTmQTQPAK0RMgITm+QTS+ciPCcikQpPY4MjmYTO+czmcyHh4TCmcvJ54nCPCBjBJx4oECc8zJ6ATTn48RE4YTTHh4SDH4ImRFBwTGFBgTGFBgSGFBYmHUgITRmcyFBASFAoUjE5PzkQLBHJxiDAQP/GxAA==")) diff --git a/apps/fontclock/fontclock.font.abril_ff50.js b/apps/fontclock/fontclock.font.abril_ff50.js new file mode 100644 index 000000000..d61a2ca49 --- /dev/null +++ b/apps/fontclock/fontclock.font.abril_ff50.js @@ -0,0 +1,87 @@ +var NumeralFont = require("fontclock.font.js"); + +const DIM_30x38 = [30,38]; +const DIM_49x38 = [49,38]; + +class DigitNumeralFont extends NumeralFont{ + constructor(){ + super(); + // dimension map provides the dimensions of the character for + // each number for plotting and collision detection + + /*this.dimension_map = { + 3 : [30,38], + 6 : [30,38], + 9 : [30,38], + 12: [49,38] + };*/ + this.widths = atob("DRIhFRwdHhsfGh8fDQ=="); + this.font = atob("AAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAD/AAAAAAB/4AAAAAAf+AAAAAAH/gAAAAAB/4AAAAAAf+AAAAAAD/AAAAAAA/gAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAPwAAAAAAf8AAAAAA/+AAAAAB/8AAAAAD/wAAAAAH/gAAAAAP/AAAAAAf+AAAAAA/8AAAAAB/4AAAAAD/wAAAAAH/gAAAAAP/AAAAAAH+AAAAAAB8AAAAAAAIAAAAAAAAAAAAAAAAAAH/8AAAAAP//8AAAAP///wAAAH///+AAAD////4AAB/////AAA/////wAAf////+AAH/////wAD/////8AA//////AAP/gAA/wADwAAAAeAA4AAAADgAMAAAAA4ADAAAAAOAAwAAAADgAMAAAAA4ADgAAAAeAA/gAAA/AAP/////wAD/////8AAf/////AAH/////gAA/////4AAH////8AAB////+AAAP////AAAA////gAAAD///gAAAAH//AAAAAAAAAAAAGAAAAAwABgAAAAMAAYAAAADAAGAAAAAwADgAAAAMAA//////AAP/////wAD/////8AA//////AAP/////wAD/////8AA//////AAP/////wAD/////8AA//////AAP/////wAAAAAAAMAAAAAAADAAAAAAAAwAAAAAAAMAAAAAAAAAAAAAAAAAAAHwAAD8AAH/AAB/AAD/wAA/wAA/+AAf8AAf/gAP/AAH/4AH/wAD/+AD/8AA//gB//AAOPwA//wADD4Aff8AAwAAPn/AAMAAPx/wADAAH8f8AA4AH+H/AAPgP/B/wAD///gf8AA///4H/AAP//8B/wAD//+Af8AAf//AH/AAH//wB/wAA//4A/8AAH/4Af/AAA/8A//wAAD8Af/8AAAAAD+AAAAAAAAAAAAAAAAAAAAAAAAPwAAA/gAP+AAAf8AD/wAAP/gB/+AAH/4Af/wAB/+AH/8AAf/gB//AAP/4wP/wAD/8OD+OAAw/DgPDgAMDAwAA4ADAAcAAOAAwAHAADgAOAH4AA4AD///AAeAA///+A/AAP/////wAD/////8AA//9///AAP//f//gAB//n//4AAf/w//+AAD/8P//AAAf+B//gAAB+AP/wAAAAAB/4AAAAAADwAAAAAAAAAAAAAAAeAAAAAAAfgAAAAAAf4AAAAAAPmAAAAAAPhgAAAAAPwYAAAAAPwGAAAAAHwBgAAAAHwAYDAAAH4AGAwAAH4ABgMAAH4AAYDAAD4AAGAwAD/////8AA//////AAP/////wAD/////8AA//////AAP/////wAD/////8AA//////AAP/////wAD/////8AAAAAAYDAAAAAAGAwAAAAABgMAAAAAAYBAAAAAB/4AAAAAAf+AAAAAAAAAAAAAAAD4AAAAAAB/gAAAAAA/8AAP//wf/gAD//8H/4AA//3B//AAP8Bgf/wAD/A4D/8AAfwOA/jgAH8DAH44AB/gwAAOAAf4MAADgAH+DAAA4AB/g4AAeAAf8PwA/AAH/D///wAB/w///8AAf8P///AAD/j///wAA/4f//4AAP+H//+AAH/A///AAD/wP//gAA/gB//wAAAAAH/4AAAAAAfwAAAAAAAAAAAAAAAAAAAAAD//wAAAAH///AAAAH///8AAAD////gAAD////8AAB/////gAAf////4AAP/////AAH/////wAB/////8AA//////gAP8B4AD4AD4A4AAOAA4AMAADgAOAHAAA4ADABwAAOAAwAcAAHgAMAH4AP4ADD5///8AA5/f///AAP/////wAD/////8AAf/v//+AAH/7///AAA/+f//wAAH/H//4AAA/gf/4AAABgD/8AAAAAAH4AAAAAAAAAAAAAAAAAAAAf/wAAAAAP/8AAAAAD/8AAAAAA/8AAAAAAP+AAA/AAD/gAA/4AA/4AA//AAP+AAf/wAD/gAf/+AA/4AP//gAP+AH//4AD/gD//+AA/4B///gAP+B/+BwAD/g/8AAAA/4f8AAAAP+P8AAAAD/n8AAAAA/78AAAAAP/+AAAAAD/+AAAAAA/+AAAAAAP+AAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAAB/gH/4AAA/8D//AAAf/h//wAAP/8f/+AAH//v//gAB//7//8AAf/////AAP/////wAD/////+AA//////gAP//+AB4ADgAeAAOAAwADgADgAMAA4AA4ADAAOAAOAA4AHwADgAP//+AD4AD/////+AA//////AAP/////wAD//7//8AAf/+///AAH//P//gAA//x//4AAH/4f/8AAA/8D/+AAAD8Af/AAAAAAB/AAAAAAAAAAAAA/gAAAAAA//APwAAA//8H+AAAf//j/wAAP//4/+AAD///f/gAB/////8AAf//+//AAP///v/wAD///7+eAA////PjgAPgAPwA4ADgAA4AOAAwAAOADgAMAADgA4ADAAA4AeAAwAAcAfgAPAAeA/wAD/////8AA//////AAP/////gAB/////wAAf////8AAD////+AAAf////AAAH////gAAAf///gAAAD///gAAAAH//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AH4AAAB/gD/AAAAf8B/4AAAP/Af+AAAD/wH/gAAA/8B/4AAAH/Af+AAAB/wD/AAAAP4A/gAAAAwABgAAAAAAAA=="); + var scale = 1; // size multiplier for this font + this.size = 50+(scale<<8)+(1<<16); + this.y_offset = -12; + /* scale + this.widths = atob("ExkuHicoKiYrJCsrEw=="); + this.font = atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAf+AAAAAAAAAB/8AAAAAAAAAP/4AAAAAAAAA//gAAAAAAAAD/+AAAAAAAAAP/4AAAAAAAAA//gAAAAAAAAD/+AAAAAAAAAP/wAAAAAAAAAf/AAAAAAAAAA/4AAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAA8AAAAAAAAAAfwAAAAAAAAAP/AAAAAAAAAH/8AAAAAAAAD/+AAAAAAAAB//AAAAAAAAA//gAAAAAAAAf/wAAAAAAAAP/4AAAAAAAAH/8AAAAAAAAD/+AAAAAAAAB//AAAAAAAAA//gAAAAAAAAf/wAAAAAAAAP/4AAAAAAAAH/8AAAAAAAAD/+AAAAAAAAB//AAAAAAAAA//gAAAAAAAAH/wAAAAAAAAAf4AAAAAAAAAB8AAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAB//wAAAAAAAB///8AAAAAAAf///+AAAAAAH////+AAAAAB/////+AAAAAP/////8AAAAB//////4AAAAP//////wAAAB///////gAAAP///////AAAA///////8AAAH///////4AAAf///////gAAB////////AAAP///////8AAA////////wAAD+AAAAAA/gAAPAAAAAAAeAAA4AAAAAAA4AAHgAAAAAADgAAcAAAAAAAOAABwAAAAAAA4AAHAAAAAAADgAAcAAAAAAAOAAB4AAAAAAA4AADgAAAAAAHgAAPgAAAAAB+AAA/8AAAAA/wAAD////////AAAP///////8AAAf///////wAAB///////+AAAD///////4AAAP///////AAAAf//////8AAAB///////gAAAD//////8AAAAH//////gAAAAP/////8AAAAAP/////AAAAAAf////4AAAAAAP///8AAAAAAAH//+AAAAAAAAADAAAAAAAAAAAAAAAAAAAIAAAAAAAAAABwAAAAAADAAAHAAAAAAAMAAAcAAAAAAAwAABwAAAAAADAAAHAAAAAAAMAAAcAAAAAAAwAABgAAAAAADAAAP///////8AAA////////wAAD////////AAAP///////8AAA////////wAAD////////AAAP///////8AAB////////wAAH////////AAAf///////8AAB////////wAAH////////AAAf///////8AAB////////wAAH////////AAAAAAAAAAAMAAAAAAAAAAAwAAAAAAAAAADAAAAAAAAAAAMAAAAAAAAAAAwAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAP+AAAAf8AAAD/8AAAD/wAAAf/4AAAf/AAAD//gAAD/8AAAP//AAAf/wAAB//8AAD//AAAH//wAAf/8AAA///AAD//wAAD//4AAf//AAAP//gAD//8AAA8P+AAfv/wAADg/wAD8//AAAcB8AAfj/8AABwAAAD+P/wAAHAAAAfw//AAAcAAAH+D/8AABwAAA/4P/wAAHgAAP/A//AAAfAAD/4D/8AAB/AD//AP/wAAD////8A//AAAP////gD/8AAA////8AP/wAAD////gA//AAAP///8AD/8AAAf///wAP/wAAB///+AA//AAAD///wAH/8AAAP//+AAf/wAAAf//wAD//AAAA//+AAf/8AAAB//wAP//wAAAD/8AD///AAAAA8AAP//8AAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAABwAAAP8AAAAA/4AAD/8AAAAH/wAAP/4AAAA//gAB//wAAAH/+AAH//gAAA//8AAf/+AAAH//wAD//8AAAf//AAH//wAAB//8AAf//AAAP//gAB//8AAA//+BwD/D4AADw/4GAP8HgAAOD/A4APwOAABwHwDgAAA4AAHAAAOAAADgAAcAAA4AAAOAABwAAHgAAA4AAHgAA+AAADgAAfAAH8AAAeAAB/wD/4AAD4AAH////4AAfgAAf////+B/+AAA////////wAAD///3////AAAP///f///8AAA///9////wAAD///j///+AAAH//+P///4AAAf//w////gAAA///B///8AAAB//4H///gAAAD//AP//+AAAAH/4Af//wAAAAH+AA//+AAAAAAAAB//gAAAAAAAAD/4AAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAfAAAAAAAAAAH8AAAAAAAAAA/wAAAAAAAAAP3AAAAAAAAAD+cAAAAAAAAA/hwAAAAAAAAH4HAAAAAAAAB+AcAAAAAAAAfwBwAAAAAAAH8AHAAAAAAAB/AAcAAAAAAAPwABwAAAAAAD+AAHADAAAAA/gAAcAMAAAAP4AABwAwAAAD+AAAHADAAAAfwAAAcAMAAAH8AAABwAwAAB////////AAAP///////8AAA////////wAAD////////AAAP///////8AAA////////wAAD////////AAAP///////8AAA////////wAAD////////AAAP///////8AAA////////wAAD////////AAAP///////8AAAAAAAABwAwAAAAAAAAHADAAAAAAAAAcAMAAAAAAAABwAwAAAAAAAAHADAAAAAAAAAcAAAAAAAAAB//gAAAAAAAAH/+AAAAAAAAAf/4AAAAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAf+AAAAAAAAAD/+AAAAAAAAAf/8AAAH///4B//wAAA////gH//gAAD///+A//+AAAP/ABwB//8AAA/8AHAH//wAAD/wA4Af//AAAH/gDgB/9+AAAf+AOAD/h4AAB/4AwAH+DgAAH/gHAAHAOAAAf/AcAAAA4AAB/8BwAAADgAAH/wHAAAAOAAAf/AeAAAA4AAB/+B8AAAHgAAD/4H4AAB+AAAP/gf////4AAA/+B/////AAAD/8H////8AAAP/wP////wAAA//A/////AAAD/8D////4AAAP/4P////gAAA//gf///8AAAD/+B////wAAAP/wD///+AAAB/+AH///wAAAP/wAf///AAAB/gAA///wAAAAAAAA//+AAAAAAAAA//gAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAH///4AAAAAAB////8AAAAAA/////4AAAAAH/////4AAAAB//////wAAAAP//////gAAAB///////AAAAP//////8AAAB///////4AAAH///////gAAA////////AAAD///////8AAAf///////wAAB////////AAAP/4B+AAD+AAA/4AHgAAD4AAD8AA4AAAHgAAPgAHgAAAOAAA8AAcAAAA4AAHgABwAAADgAAcAAPAAAAOAABwAA8AAAA4AAHAADwAAAHgAAcAAPwAAD+AABwPw/////4AADg/z/////AAAPD/P////8AAA//+/////wAAD//7////+AAAP//n////4AAAf//f////gAAB//5////8AAAD//j////gAAAP/+H///+AAAAf/wf///wAAAA//A///+AAAAA/wB///gAAAAAYAB//8AAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/gAAAAAAAD//+AAAAAAAAP//4AAAAAAAA//8AAAAAAAAD//AAAAAAAAAP/4AAAAAAAAA//gAAAH+AAAD/8AAAB/8AAAP/wAAAf/4AAA//AAAH//wAAD/8AAA///AAAP/wAAH//+AAA//AAA///4AAD/8AAP///gAAP/wAB///+AAA//AAP///4AAD/8AB////gAAP/wAP///+AAA//AD//wD4AAD/8Af/4ADAAAP/wD/8AAAAAA//Af/AAAAAAD/8D/wAAAAAAP/wf8AAAAAAA//H/gAAAAAAD/8/4AAAAAAAP/3+AAAAAAAA///gAAAAAAAD//8AAAAAAAAP//AAAAAAAAA//wAAAAAAAAD/8AAAAAAAAAP/gAAAAAAAAA/4AAAAAAAAAAAAAAAAAAAAAAAAAAD/wAAAAAH8AA//wAAAAB/8AH//wAAAAf/8A///AAAAD//4H//+AAAAf//g///8AAAD///D///wAAAP//8f///gAAB///5///+AAAH///n///8AAAf///////wAAD////////AAAP///////8AAA////////4AAD////////gAAP////gAB+AAB+AAP4AAB4AAHgAAfAAADgAAeAAA8AAAOAABwAADwAAA4AAHAAAPAAADgAAcAAA8AAAOAAB4AADwAAA4AAH4AAfgAAHgAAP////gAB+AAA////////4AAD////////gAAP///////8AAA////////wAAD////////AAAH///n///8AAAf//+f///gAAA///5///+AAAD///D///4AAAH//4P///AAAAP//gf//4AAAAf/4A///AAAAA//AB//4AAAAAfgAD//AAAAAAAAAD/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAAAAAAAf/8AA+AAAAAH//8AP+AAAAA///4B/8AAAAH///4P/4AAAA////h//wAAAH////H//gAAA////+f/+AAAD////5//4AAAf////3//wAAB/////f//AAAH////9//8AAA/////z/j4AAD/////H+HgAAP////8PgOAAA/gAAfwAA4AADwAAAPAADgAAeAAAA8AAOAAB4AAABwAA4AAHAAAAHAADgAAcAAAA4AAeAABwAAADgAD4AAHgAAAeAAfgAAeAAADwAH8AAA+AAA+AH/wAAD////////AAAP///////4AAA////////gAAD///////8AAAH///////wAAAf//////+AAAA///////4AAAD///////AAAAH//////4AAAAP//////AAAAAf/////wAAAAA/////8AAAAAA/////gAAAAAA////wAAAAAAAf//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPwAAfgAAAAAB/wAD/gAAAAAP/gAf/AAAAAB/+AD/8AAAAAH/8AP/4AAAAAf/wA//gAAAAD//AD/+AAAAAP/8AP/4AAAAAf/wA//gAAAAB/+AD/+AAAAAH/4AP/wAAAAAP/AAf+AAAAAAf4AA/wAAAAAAIAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); + var scale = 1; // size multiplier for this font + this.size = 70+(scale<<8)+(1<<16); + this.y_offset = -15 + */ + + // font size 90 + /*this.dimension_map = { + 1 : [50,70], + 2 : [50,70], + 3 : [50,70], + 4 : [50,70], + 5 : [50,70], + 6 : [54,70], + 7 : [54,70], + 8 : [54,70], + 9 : [54,70], + 10: [87,70], + 11: [87,70], + 12: [87,70] + }; + + this.widths = atob("GCA8JjI0NjE3Ljc3GA=="); + this.font = atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAD/gAAAAAAAAAAAAH/4AAAAAAAAAAAAP/8AAAAAAAAAAAAf/8AAAAAAAAAAAAf/+AAAAAAAAAAAAf/+AAAAAAAAAAAA//+AAAAAAAAAAAA//+AAAAAAAAAAAA//+AAAAAAAAAAAA//+AAAAAAAAAAAAf/+AAAAAAAAAAAAf/+AAAAAAAAAAAAf/8AAAAAAAAAAAAP/4AAAAAAAAAAAAH/4AAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAA/AAAAAAAAAAAAAH/AAAAAAAAAAAAA//AAAAAAAAAAAAH//AAAAAAAAAAAA//8AAAAAAAAAAAH//gAAAAAAAAAAA//8AAAAAAAAAAAH//gAAAAAAAAAAA//8AAAAAAAAAAAH//gAAAAAAAAAAA//8AAAAAAAAAAAH//gAAAAAAAAAAA//8AAAAAAAAAAAH//AAAAAAAAAAAA//4AAAAAAAAAAAH//AAAAAAAAAAAA//4AAAAAAAAAAAH//AAAAAAAAAAAA//4AAAAAAAAAAAH//AAAAAAAAAAAA//4AAAAAAAAAAAH//AAAAAAAAAAAA//4AAAAAAAAAAAD//AAAAAAAAAAAAD/4AAAAAAAAAAAAD/AAAAAAAAAAAAAD4AAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH///AAAAAAAAAAB////8AAAAAAAAAP/////gAAAAAAAA//////4AAAAAAAD//////+AAAAAAAH///////gAAAAAAP///////wAAAAAAf///////4AAAAAA////////8AAAAAB////////+AAAAAD/////////AAAAAH/////////gAAAAH/////////wAAAAP/////////wAAAAP/////////4AAAAf/////////4AAAAf/////////4AAAAf/////////8AAAA//////////8AAAA///gAAAAf/8AAAA/wAAAAAAAH+AAAA+AAAAAAAAB+AAAB8AAAAAAAAAeAAAB4AAAAAAAAAeAAAB4AAAAAAAAAOAAAB4AAAAAAAAAOAAABwAAAAAAAAAOAAABwAAAAAAAAAOAAABwAAAAAAAAAOAAAB4AAAAAAAAAOAAAB4AAAAAAAAAeAAAB4AAAAAAAAAeAAAB8AAAAAAAAA+AAAA+AAAAAAAAB+AAAA/4AAAAAAAP8AAAA////AAB///8AAAA//////////8AAAAf/////////8AAAAf/////////4AAAAf/////////4AAAAP/////////wAAAAP/////////wAAAAH/////////gAAAAH/////////gAAAAD/////////AAAAAB////////+AAAAAA////////8AAAAAAf///////8AAAAAAP///////wAAAAAAH///////gAAAAAAB///////AAAAAAAAf/////8AAAAAAAAH/////gAAAAAAAAA////8AAAAAAAAAAB///AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAOAAAAAAAAAcAAAAOAAAAAAAAAcAAAAeAAAAAAAAAcAAAAeAAAAAAAAAcAAAAcAAAAAAAAAcAAAAcAAAAAAAAAcAAAAcAAAAAAAAAcAAAAcAAAAAAAAAcAAAAcAAAAAAAAAcAAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAB//////////8AAAAAAAAAAAAAAcAAAAAAAAAAAAAAcAAAAAAAAAAAAAAcAAAAAAAAAAAAAAcAAAAAAAAAAAAAAcAAAAAAAAAAAAAAcAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAB/8AAAAAf/wAAAAD/8AAAAB//4AAAAH/8AAAAD//4AAAAP/8AAAAH//8AAAAf/8AAAAH//8AAAA//8AAAAP//8AAAB//8AAAAP//8AAAD//8AAAAf//8AAAH//8AAAAf//8AAAP//8AAAA///8AAAf//8AAAA///8AAA///8AAAA///4AAB/f/8AAAA+D/4AAD+f/8AAAA8D/wAAH8f/8AAAB4D/gAAP8f/8AAAB4AOAAAf4f/8AAABwAAAAA/wf/8AAABwAAAAB/wf/8AAABwAAAAD/gf/8AAABwAAAAP/Af/8AAAB4AAAAf+Af/8AAAB4AAAB/+Af/8AAAB8AAAH/8Af/8AAAB+AAAf/4Af/8AAAB/gAH//wAf/8AAAB//////wAf/8AAAA//////gAf/8AAAA//////AAf/8AAAA/////+AAf/8AAAA/////+AAf/8AAAA/////8AAf/8AAAAf////4AAf/8AAAAf////wAAf/8AAAAP////gAAf/8AAAAP////gAA//8AAAAH////AAA//8AAAAH///+AAB//8AAAAD///4AAD//8AAAAB///wAAH//8AAAAA///gAAf//8AAAAAf/+AAD///8AAAAAD/4AAP///8AAAAAAAAAAP///8AAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/gAAAAAAD8AAAAD/4AAAAAAP/gAAAP/+AAAAAA//wAAAf//AAAAAB//4AAAf//gAAAAD//8AAA///gAAAAH//8AAA///wAAAAH//8AAA///4AAAAP//8AAA///4AAAAf//8AAA///4AAAAf//8AAA///8AAAAf//8AAA///8AAAA///8AAA///8AAAA///8BwAf/j+AAAA///4BwAf/A+AAAA+D/4BwAP/AeAAAA4D/wBwAD/AeAAAB4D/gBwAAAAOAAABwAAADwAAAAOAAABwAAADwAAAAOAAABwAAADwAAAAOAAABwAAAHgAAAAOAAAB4AAAHwAAAAOAAAB4AAAP4AAAAeAAAB+AAA/4AAAAeAAAB/wAD/+AAAA+AAAB//////AAAB+AAAB//////wAAP+AAAB///////gH/+AAAB//////////8AAAA////9/////8AAAA////9/////8AAAA////8/////8AAAA////4/////4AAAAf///4/////4AAAAf///4/////4AAAAf///wf////wAAAAP///gf////wAAAAP///gP////gAAAAH///AP////gAAAAD//+AH////AAAAAB//8AD///+AAAAAAf/4AD///8AAAAAAH/AAB///4AAAAAAAAAAA///wAAAAAAAAAAAP//AAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAfAAAAAAAAAAAAAB/AAAAAAAAAAAAAH/AAAAAAAAAAAAAf/AAAAAAAAAAAAB/nAAAAAAAAAAAAD+HAAAAAAAAAAAAP8HAAAAAAAAAAAA/wHAAAAAAAAAAAD/AHAAAAAAAAAAAH8AHAAAAAAAAAAAf4AHAAAAAAAAAAB/gAHAAAAAAAAAAH+AAHAAAAAAAAAAf4AAHAAAAAAAAAA/gAAHAAAAAAAAAD/AAAHAAcAAAAAAP8AAAHAAcAAAAAA/wAAAHAAcAAAAAD/AAAAHAAcAAAAAH+AAAAHAAcAAAAAf4AAAAHAAcAAAAB/gAAAAHAAcAAAAH+AAAAAHAAcAAAAP/////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAA//////////8AAAAAAAAAAAHAAcAAAAAAAAAAAHAAcAAAAAAAAAAAHAAcAAAAAAAAAAAHAAcAAAAAAAAAAAHAAcAAAAAAAAAAAHAAcAAAAAAAAAAAHAAAAAAAAAAAAAAHAAAAAAAAAAAAAf//gAAAAAAAAAAAf//gAAAAAAAAAAAf//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/gAAAAAAAAAAAAH/8AAAAAAAAAAAAP/+AAAAAAAAAAAAf//AAAAAAAAAAAAf//gAAAAf////gA///wAAAA/////wA///wAAAA/////wA///4AAAA///4HgA///4AAAA//AAHgA///4AAAA//AAPAA///8AAAAf/gAPAA///8AAAAf/gAOAA///+AAAAf/gAeAAf/g+AAAAf/wAeAAP/geAAAAf/wAcAAH/geAAAAf/wAcAAD+AOAAAAf/wAcAAAAAOAAAAf/4AcAAAAAOAAAAf/4AcAAAAAOAAAAP/4A8AAAAAOAAAAP/4A8AAAAAOAAAAP/8A+AAAAAeAAAAP/8AfAAAAA+AAAAP/8AfgAAAB+AAAAP/8Af8AAAf+AAAAP/+Af/////+AAAAP/+Af/////8AAAAP/+Af/////8AAAAP/+Af/////8AAAAH//Af/////8AAAAH//AP/////4AAAAH//AP/////4AAAAH//AP/////4AAAAH//AH/////wAAAAH//AH/////wAAAAH//AH/////gAAAAH//AD/////AAAAAP/+AB/////AAAAA//8AA////+AAAAB//gAA////8AAAAB/wAAAP///4AAAAAAAAAAH///gAAAAAAAAAAB//+AAAAAAAAAAAAf/4AAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//wAAAAAAAAAAD////gAAAAAAAAAf////4AAAAAAAAD//////AAAAAAAAP//////gAAAAAAA///////4AAAAAAB///////8AAAAAAH///////+AAAAAAP////////AAAAAAf////////gAAAAA/////////gAAAAB/////////wAAAAD/////////wAAAAD/////////4AAAAH/////////4AAAAP/////////8AAAAP/////////8AAAAf/////////8AAAAf/////////8AAAAf//wD/gAA/+AAAA//gAH4AAAD+AAAA/8AAPgAAAA+AAAA/wAAPAAAAAeAAAA/AAAeAAAAAOAAAA+AAAcAAAAAOAAAB8AAA8AAAAAOAAAB4AAA4AAAAAOAAAB4AAB4AAAAAOAAAB4AAB8AAAAAeAAABwAAB8AAAAAeAAABwAAB+AAAAA+AAABwAAB/AAAAD+AAABwAMB/+AAD/+AAAB4D/h//////8AAAB4D/x//////8AAAB8D/5//////8AAAA///5//////8AAAA///8//////4AAAA///8//////4AAAA///8//////wAAAAf//8//////wAAAAf//8f/////gAAAAP//8f/////gAAAAP//8P/////AAAAAH//8P////+AAAAAD//4H////8AAAAAB//wD////4AAAAAA//gB////wAAAAAAP/AA////gAAAAAAAQAAP//+AAAAAAAAAAAB//wAAAAAAAAAAAAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf///AAAAAAAAAAA////AAAAAAAAAAA///+AAAAAAAAAAA///gAAAAAAAAAAA///AAAAAAAAAAAA//+AAAAAAAAAAAA//8AAAAAAAAAAAA//8AAAAAP/AAAAA//4AAAAA//gAAAA//4AAAAD//wAAAA//4AAAAP//4AAAA//4AAAAf//8AAAA//4AAAA///8AAAA//4AAAD///+AAAA//4AAAH///+AAAA//4AAAP///+AAAA//4AAA////+AAAA//4AAB////+AAAA//4AAD////+AAAA//4AAH////+AAAA//4AAP////+AAAA//4AA/////+AAAA//4AB///gD+AAAA//4AD//8AAeAAAA//4AH//gAAAAAAA//4AP/+AAAAAAAA//4Af/4AAAAAAAA//4A//gAAAAAAAA//4D/+AAAAAAAAA//4H/4AAAAAAAAA//4P/gAAAAAAAAA//4f+AAAAAAAAAA//4/8AAAAAAAAAA//5/wAAAAAAAAAA////AAAAAAAAAAA///8AAAAAAAAAAA///4AAAAAAAAAAA///gAAAAAAAAAAA//+AAAAAAAAAAAA//4AAAAAAAAAAAA//wAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAPAAAH//wAAAAAAD/8AAP//4AAAAAAP//AA///+AAAAAA///gB///+AAAAAB///wB////AAAAAD///4D////gAAAAD///8H////wAAAAH///8H////wAAAAP///+P////4AAAAP///+P////4AAAAf////P////4AAAAf////f////8AAAAf////f////8AAAA/////f////8AAAA//////////8AAAA//////////+AAAA//////////+AAAA///////8f/+AAAB//////gAAH+AAAB/4AB/+AAAA+AAAB+AAAH8AAAAeAAAB8AAAD4AAAAeAAAB4AAAD4AAAAOAAAB4AAAB4AAAAOAAABwAAABwAAAAOAAAB4AAAB4AAAAOAAAB4AAAB4AAAAOAAAB4AAAD4AAAAOAAAB8AAAH8AAAAeAAAB/gAAP8AAAA+AAAB//////AAAD+AAAA//////+AA/+AAAA//////////+AAAA//////////+AAAA//////////8AAAA/////f////8AAAAf////f////8AAAAf////f////8AAAAf////P////4AAAAP///+P////4AAAAP///+H////4AAAAH///8H////wAAAAH///4H////wAAAAD///4D////gAAAAB///wB////gAAAAA///gA////AAAAAAf//AAf//+AAAAAAH/8AAP//4AAAAAAA/AAAH//wAAAAAAAAAAAB/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAP/+AAAAAAAAAAAB///gAAfgAAAAAAH///4AD/4AAAAAAP///8AH/+AAAAAA/////AP//AAAAAA/////gf//gAAAAB/////gf//gAAAAD/////w///wAAAAH/////4///wAAAAH/////4///4AAAAP/////8///4AAAAP/////8///8AAAAf/////8///8AAAAf/////+f//8AAAAf/////+f/z8AAAA//////+P/g+AAAA//////+H/geAAAA//////+D/AeAAAA//gAH/+AAAOAAAB/gAAAD+AAAOAAAB+AAAAA+AAAOAAAB8AAAAA+AAAOAAAB4AAAAAeAAAOAAAB4AAAAAeAAAOAAABwAAAAAcAAAeAAABwAAAAAcAAAeAAABwAAAAA8AAA+AAAB4AAAAA4AAB+AAAB4AAAAB4AAH+AAAB8AAAAHwAAf8AAAB+AAAAPgAD/8AAAA/4AAD/AD//8AAAA//////////4AAAA//////////4AAAA//////////4AAAAf/////////wAAAAf/////////wAAAAf/////////gAAAAP/////////AAAAAP/////////AAAAAH////////+AAAAAH////////8AAAAAD////////4AAAAAB////////wAAAAAA////////AAAAAAAf//////+AAAAAAAH//////4AAAAAAAD//////gAAAAAAAAf////8AAAAAAAAAH////gAAAAAAAAAAP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAMAAAAAAAAB/gAAD/gAAAAAAAH/4AAH/4AAAAAAAP/8AAP/8AAAAAAAP/8AAf/8AAAAAAAf/+AAf/+AAAAAAAf/+AAf/+AAAAAAAf/+AA//+AAAAAAAf/+AA//+AAAAAAAf/+AA//+AAAAAAAf/+AA//+AAAAAAAf/+AAf/+AAAAAAAf/+AAf/+AAAAAAAP/8AAf/8AAAAAAAP/8AAP/4AAAAAAAH/4AAH/4AAAAAAAD/gAAD/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); + var scale = 1; // size multiplier for this font + this.size=90+(scale<<8)+(1<<16); + this.y_offset = -20 + */ + + } + getDimensions(hour){ + //return this.dimension_map[hour]; + switch (hour){ + case 10: + case 11: + case 12: + return DIM_49x38; + default: + return DIM_30x38; + + } + } + hour_txt(hour){ return hour.toString(); } + draw(hour_txt,x,y){ + /* going to leave this in here for future testing. + uncomment this so that it draws a box behind the string + so we can guess the digit dimensions*/ + /*var dim = [30,38]; + g.setColor(0.5,0,0); + g.fillPoly([x,y, + x+dim[0],y, + x+dim[0],y+dim[1], + x,y+dim[1] + ]); + g.setColor(1.0,1.0,1.0);*/ + g.setFontAlign(-1.0,-1.0,0); + g.setFontCustom(this.font, 46, this.widths, this.size); + g.drawString(hour_txt,x,y+this.y_offset ); + } + getName(){return "Digit";} +} + +module.exports = [DigitNumeralFont]; \ No newline at end of file diff --git a/apps/fontclock/fontclock.font.cpstc58.js b/apps/fontclock/fontclock.font.cpstc58.js new file mode 100644 index 000000000..6e91349ab --- /dev/null +++ b/apps/fontclock/fontclock.font.cpstc58.js @@ -0,0 +1,59 @@ +var NumeralFont = require("fontclock.font.js"); + +const DIM_20x58 = [20,58]; +const DIM_30x58 = [30,58]; +const DIM_40x58 = [40,58]; +const DIM_50x58 = [50,58]; +class DigitNumeralFont extends NumeralFont{ + constructor(){ + super(); + // dimension map provides the dimesions of the character for + // each number for plotting and collision detection + this.font = atob("AAAA/+AAAAAAB///wAAAAB////8AAAA/////+AAAP/////8AAD//////8AAf/8AAf/8AD/8AAAH/4Af+AAAAD/wD/gAAAAD/gf4AAAAAH+D/AAAAAAP8P4AAAAAAf5/AAAAAAA/n4AAAAAAB+/gAAAAAAH/+AAAAAAAf/wAAAAAAA//AAAAAAAD/8AAAAAAAP/4AAAAAAB//gAAAAAAH9+AAAAAAAfn8AAAAAAD+fwAAAAAAP4/gAAAAAB/D/AAAAAAP8H/AAAAAB/gP+AAAAAf8Af/AAAAH/gA//gAAD/8AB//8AH//gAB//////8AAB//////AAAB/////wAAAA////4AAAAAP//4AAAAAAAAAAAAAAGAAAAAAAAA8AAAAAAAAH8AAAAAAAA/wAAAAAAAH+AAAAAAAA/wAAAAAAAH+AAAAAAAA/wAAAAAAAH////////w/////////H////////8/////////3//////////////////8AAAAAAAAAAAAAAAAAADAAAAAAAAAcQAAAAAAAHzwAAAAAAA/PwAAAAAAH9/AAAAAAB/34AAAAAAP/fgAAAAAD//+AAAAAAf//wAAAAAH///AAAAAA///8AAAAAH///4AAAAB/4//gAAAAP/D/+AAAAD/wP34AAAAf+A/fwAAAD/wD8/gAAA/8APz/AAAH/gA/H+AAB/4AD8f8AAP/AAPw/8AD/wAA/B/+A/+AAD8D////wAAPwH///8AAA/AH///gAAD8AH//4AAAPwAH/+AAAAAAAAAAAAAAD8AAAAAAAAPwAAAAAAAA/AAgAAAAD/8AHAAAAAP/wB8AAAAA//APwAAAAD/8D/AAAAAP/wf8AAAAB//H/wAAAAH/8//gAAAAfv//+AAAAD+///8AAAAP7//fwAAAB/P/w/gAAAP8/+D/AAAB/j/wH+AAAP8P8AP8AAB/w/gAf8AAf+D4AA/8AH/wPAAB////+AwAAD////gCAAAH///8AAAAAH///AAAAAAD//wAAAAAAA/wAAAAAAAAAAAAAAAAAAAQAAAAAAAAHAAAAAAAAD8AAAAAAAA/wAAAAAAAP/AAAAAAAD/8AAAAAAB//wAAAAAAf//AAAAAAH//8AAAAAB//PwAAAAAf/w/AAAAAP/8D8AAAAD//APwAAAA//gA/AAAAP/4AD8AAAH/+AAPwAAB//gAA/AAAf/4AAD8AAH/8AAAPwAD//AAAA/AAP/wAAAD8AA/8AAAAPwAD/AAAAA/gAPgAAA/////4AAAD////+AAAAP////wAAAA/////AAAAD////8AAAAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAAAAAAAAA8AAAAAAAB/wAAAAAAD//AAAAAP///8AAAAA////wAAAAD////AAAAAP///8AAAAA//4PwAAAAH/8A/gAAAAf/wB+AAAAB+/AH4AAAAP78AfwAAAA/vwA/AAAAH8/AD+AAAA/z8AP8AAAD+PwAf4AAAf4/AA/wAAH/D8AD/gAA/4PwAH/gAf/A/AAP/8f/4AAAAf////AAAAAf///wAAAAA///8AAAAAAf//AAAAAAAH/gAAAAAAAAAAAAAAAAH/4AAAAAAP//8AAAAAD///+AAAAB////8AAAAf////8AAAH//8f/4AAA//8AD/wAAP//AAD/gAB//wAAH/AAP/+AAAH+AB//wAAAP4AP/+AAAAfwB//wAAAB/AP9/AAAAD+B/n4AAAAH4H8/gAAAAfg/j8AAAAB/H8PwAAAAH8fw/AAAAAPz+D8AAAAA/P4PwAAAAD9/A/AAAAAf38D8AAAAB/fgP4AAAAH5+A/gAAAAfv4B/AAAAD+/gH8AAAAPz+AP4AAAB/PwA/wAAAP8/AB/gAAB/gAAD/AAAP8AAAP+AAD/gAAAf+AA/8AAAA//gf/gAAAA////8AAAAB////gAAAAB///4AAAAAB//+AAAAAAA//AAAAAAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAAAAAAAfwAAAAAAAP/AAAAAAAH/8AAAAAAD//wAAAAAD///AAAAAB///8AAAAA///vwAAAA///w/AAAAP//wD8AAAP//4APwAAH//8AA/AAD//+AAD8AD//+AAAPwB///AAAA/A///gAAAD8f//wAAAAP///4AAAAA///4AAAAAD//8AAAAAAP/+AAAAAAA/+AAAAAAAD/AAAAAAAAPgAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAH//wAAAAAB///wAAAAAf///wAAAAD////wAAAAf////gAAAH/wAf/AAAA/8AAP+AAAD/AAAf8AAAf4AAAf4AAD/AAAA/gB/P4AAAB/A///AAAAH8H//8AAAAP4///gAAAAfn//+AAAAB+f//wAAAAH/+B/AAAAAf/4H8AAAAA//APwAAAAD/8A/AAAAAP/4H8AAAAB/fw/wAAAAH9///gAAAAfj//+AAAAB+P//4AAAAP4P//wAAAA/gf//gAAAH8APD/AAAA/wAAH8AAAH+AAAf8AAA/wAAA/4AAH/AAAB/4AB/4AAAD/8A//AAAAH////wAAAAP///+AAAAAP///gAAAAAP//4AAAAAAH/+AAAAAAAAAAAAAAA/wAAAAAAA//8AAAAAAP//+AAAAAD///8AAAAA////8AAAAH////4AAAA/+AD/wAAAH/AAD/gAAA/4AAD/AAAH+AAAH+AAAfwAAAP8APz+AAAAfwA/P4AAAA/gH9/AAAAD+Af34AAAAH4B+fgAAAAfwH7+AAAAA/A/v4AAAAD8D+/AAAAAPwPz8AAAAA/B/PwAAAAD8P8/gAAAAPw/j+AAAAA/H8H4AAAAH8/wfgAAAAf3+B/AAAAB+fwH8AAAAP//AP4AAAB//4A/wAAAH//AB/gAAA//4AD/AAAP//AAH+AAB//wAAf+AAf/+AAAf/AP//gAAA/////8AAAB/////AAAAB////wAAAAB///4AAAAAB//4AAAAAAAAAAAAAAA="); + this.widths = atob("Jg8dGiAaKBsoKA=="); + } + getDimensions(hour){ + switch(hour){ + case 1: + return DIM_20x58; + case 2: + case 3: + case 4: + case 5: + case 7: + return DIM_30x58; + case 6: + case 8: + case 9: + case 11: + case 12: + return DIM_40x58; + case 10: + return DIM_50x58; + default: + return DIM_30x58; + } + } + hour_txt(hour){ return hour.toString(); } + draw(hour_txt,x,y){ + /* going to leave this in here for future testing. + uncomment this so that it draws a box behind the string + so we can guess the digit dimensions + dim = [50,58]; + g.setColor(0.5,0,0); + g.fillPoly([x,y, + x+dim[0],y, + x+dim[0],y+dim[1], + x,y+dim[1] + ]); + g.setColor(1.0,1.0,1.0);*/ + //g.setFontCopasetic40x58Numeric(); + //g.setFontAlign(-1,-1,0); + g.setFontAlign(-1,-1,0); + g.setFontCustom(this.font, 48, this.widths, 58); + g.drawString(hour_txt,x,y); + } + getName(){return "Digit";} +} + +module.exports = [DigitNumeralFont]; \ No newline at end of file diff --git a/apps/fontclock/fontclock.font.js b/apps/fontclock/fontclock.font.js new file mode 100644 index 000000000..10b063ca5 --- /dev/null +++ b/apps/fontclock/fontclock.font.js @@ -0,0 +1,26 @@ +/** + * We want to be able to change the font so we set up + * pure virtual for all fonts implementtions to use + */ +class NumeralFont { + /** + * The screen dimensions of what we are going to + * display for the given hour. + */ + getDimensions(hour){return [0,0];} + /** + * The characters that are going to be returned for + * the hour. + */ + hour_txt(hour){ return ""; } + /** + * method to draw text at the required coordinates + */ + draw(hour_txt,x,y){ return "";} + /** + * Called from the settings loader to identify the font + */ + getName(){return "";} +} + +module.exports = NumeralFont; \ No newline at end of file diff --git a/apps/fontclock/fontclock.font.json b/apps/fontclock/fontclock.font.json new file mode 100644 index 000000000..3f111ba1b --- /dev/null +++ b/apps/fontclock/fontclock.font.json @@ -0,0 +1,23 @@ +{ + "name": "Vector 4", + "numerals": [12,3,6,9], + "fonts": ["vector50"], + "radius": 75, + "color_schemes" : [ + { + "name": "black", + "background" : [0.0,0.0,0.0], + "second_hand": [1.0,0.0,0.0], + }, + { + "name": "red", + "background" : [1.0,0.0,0.0], + "second_hand": [1.0,1.0,0.0] + }, + { + "name": "grey", + "background" : [0.5,0.5,0.5], + "second_hand": [0.0,0.0,0.0] + } + ] +} \ No newline at end of file diff --git a/apps/fontclock/fontclock.font.mntn25.js b/apps/fontclock/fontclock.font.mntn25.js new file mode 100644 index 000000000..e7abac8bf --- /dev/null +++ b/apps/fontclock/fontclock.font.mntn25.js @@ -0,0 +1,76 @@ +var NumeralFont = require("fontclock.font.js"); + +const DIM_25x25 = [25,25]; +const DIM_10x25 = [10,25]; +const DIM_20x25 = [20,25]; +const DIM_31x25 = [31,25]; +const DIM_15x25 = [15,25]; + +class DigitNumeralFont extends NumeralFont{ + constructor(){ + super(); + // dimension map provides the dimensions of the character for + // each number for plotting and collision detection + + /*this.dimension_map = { + 0 : [25,25], + 1 : [10,25], + 2 : [15,25], + 3 : [15,25], + 4 : [15,25], + 5 : [15,25], + 6 : [20,25], + 7 : [15,25], + 8 : [20,25], + 9 : [20,25], + 10 : [31,25], + 11 : [20,25], + 12: [25,25] + };*/ + this.widths = atob("BgsVCw8PEBEUEBQUBw=="); + this.font = atob("AAAAAAAAAAAAp9bgAAAAAAAAAAAADr+vAAAAAAAAAAAAAOv68AAAAAAAAAAAAA6/rwAAAAAAAAAAAADr+fAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAXwAAAAAAAAAAAAXz//wAAAAAAAAAXz//7q+AAAAAAAXz//8q+//wAAAAXz//8q+//yr3wAXz//8q+//yr3//ZAL/8q+//yr3//ZMAAAW+//2q3//ZQAAAAAC/2q3//pQAAAAAAAAF3//pQAAAAAAAAAAAnpQAAAAAAAAAAAAAAAAABL3//tgQAAAAAAAAj//su9//0gAAAAAC7/vv///73/gAAAAB/8/9u7u7/+34AAAA78/r/////c/+9QAAf9/P/LvLu/+///AADu/++//+7/7Pv79QAv37+/sQAAb/7978AF/f3vwAAAAD+/v+4Aj9779QAAAADs+/vwCP3vv1AAAAAOz7+/AF/P3fsAAAAC+/v94AL9+/v5AAAD/9/f/QAP3+/8/9ze/7+/v2AAj9+//Lztu+/P//AAAP/f3P////6//fcAAAL/z/y7u7vv7PoAAAAD/+z////9z/oAAAAAAK//3LvO/+QAAAAAAAAH3///6zAAAAAAAAAAAAAAAAAAAAAAC96fQAAAAAAAAAAAAL769AAAAAAAAAAAAAvvr5ZmZmZmZmZmAAC++v//////////8AAL76/bu7u7u7u7uwAAvvr/7u7u7u7u7uAAC++v/u7u7u7u7u4AAL76/KqqqqqqqqqgAAvvr///////////AAAjQlVVVVVVVVVVUAAAAAAAAAAAAAAAAAAAhTAAAAAAAAAyUlAAD7+udQAAAAHfv68AAPv777AAAAX/+/rwAC+/y/kAAAn+77+vAAb8/q9gAB79//v68ACf7frzAF/9/t+/rwAH/d+/QK/u/P/7+vAAX8/t/u/f/P7Pv68AAvv7+uzv3vz/+/rwAA/P3///z/v/Pr+vAACPv9u67939EOv68AAA/6///7/3AA6/rwAAAv/Ku+/iAADr+fAAAACu//5gAAAAAAAAAAAAAAAAAAAAAAAAAAhTAAAAAAAAAAIrIAD7+udgAAAAGo379gAPr7/rAAAAAfv935AB+vvvcjMkFQ/Pv+sAT6/d9K/r+vDs+/3QB/zvvzr+v68Nz7+/AJ/d+/Ov6/rx3Pv78Ab779+I/N/PX8+/zwAvv8/P/5/v7/z7/+AA+/z+m/r7/Kv9/PkACvv7///8+//7398gAB/9/bvvzvy8/89wAABv++/93+nf/b+gAAAALv/e/9//3v+wAAAAAASd21AVrcogAAAAAAAAAAAb753JAAAAAAAAAALP/frusAAAAAAAAE3/zO+u6wAAAAAABe/7z/367rAAAAAAf/+9/7vvrusAAAAG/+rv+s/9+u6wAAAAra//rf+5367rAAAABv/q7/q//vrusAAAAK2v/5z/w1+u6wAAAAb/6d/7IAX67rAAAACsr/+AL//vru//4AAG/+YAAaqr+u7aqgAAnUAAAD///67v//AAAAAAAABVWPruxVUAAAAAAAAAACtphgAAAAAAAAAAAAAAAAAAAAA0U3d3d3d1AADMAAAL76//////0ACr9AAAvvr9zMzMyABd/vAAC++v7u7u7qAPz79QAL76//////wPz975AAvvr8rN7Oyw+vv+wAC++vQN37/ODs+/vgAL769A6/v9wN37+/AAvvr0Dq+/3Q/Pv78AC++vQN38/vv8+/3QAL769Ar8397+7/36AAvvr0Bfv8/s/7/PMAC++vQA77+9/a+fwAAL769ABP3f///f8gAAVnSRAAb/mrzP8wAAAAAAAAAC3///wQAAAAAAAAAAAAJiAAAAAAAAAAA2ZmZiAAAAAAAAAK7//////+YAAAAAA//Lu7u7up77AAAABP+//+7u7v/5/QAAAP7fyN///+y/+/cAAH+/n/2qqqvv7vzwAA/f3+r/////v8+/cAD7+/v82rye38/e6wBPv9zrn9388fv7/NAI/O+va+/Pzw3Pv68Aj93689z7/dDc+vrwBPv+v06/z90Pz7++AA+/3vnO/Pz+/PvuwAD7+/o4/O/56/38+QAN/v5QP8/f//7PzxAAP89QAL+f3czfj6AAAK9wAAH/v///z/EAAADQAAAC79q879EAAAAAAAAAAJ3//YAAAAAAAAAAAAAAAAAAAAAL3p9AAAAAAAAAAAAAvvr0AAAAAAAAAAAAC++vQAAAAAAAAAAAAL769AAAAAAAAFrgAAvvr0AAAAAFrv/9AAC++vQAAFvv/9u98AAL769Wvv/8u9//6gAArN7//8u+//67z/AACv/8u+//27z//roAAFu+//273//rvP/wAAv/273//rvP//xxAABb3//rvP//xxAAAAAL/rvP//thAAAAAAAAXP/+thAAAAAAAAAACutgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGt/qYCvv2kAAAAAAb/69/+/+vP/AAAAAT+z//q/8//6/8QAAP8/7u9/P+7z/v7AADv36//+/v///778gAfv7/Lr/7++3/vz6AG+/7+/9+/v//Pz+0Aj8789d77+/Ds+/zwCf3Pryvuv68N36+vAJ/c+vK+6/rwzfr68An9z68r7r+vDN+vrwCPzvz1v+z78ez6+/AE+/7//fzv3+/Pv98AD7+/ne+/v57e/e/QAO7v3//9/u/v+vr2AAT9/7u9+v68uvz/AAAM/O////v///z/EAAACv+6vP/+u6z/IAAAAATP//1H3//7IAAAAAAAABAAAAEAAAAAAAAABJkwAAAAAAAAAAAAr///+gAAAAEQAAAB783dvP0QAADNAAAA37/93/n8AAC79QAAT5/c/9358wBt/vAADu/v+8/+79Afz79QAPn7+//Pv58Pv975AD+f7/zP3fjw+vv+wAf7789T+/6vTs+/vgCf3fvyP8/789z7+/AG+++/SP7Pvw+fr74AL5/e+837+/X3+v3AAPv7+//d3d797/35AA3+7/vMzMzK75+/MAA/r97//////r/fwAAAz5/7uqqqqt/d8gAAAe/N//////6v9gAAAACv/bqqqr3/4gAAAAAAOM/////aUAAAAAAAAAAAAAAAAAAAAAAAAAAQEQABARAAAAAAAABvvuoF+u6wAAAAAAAG++6gX67rAAAAAAAAb77qBfrusAAAAAAABvvuoF+u6wAAAAAAAE16pwPXunAAAAAAAAAAAAAAAAAAAA=="); + var scale = 1; // size multiplier for this font + this.size = 25+(scale<<8)+(4<<16); + this.y_offset = 0; + + } + getDimensions(hour){ + //return this.dimension_map[hour]; + switch(hour){ + case 0: + case 12: + return DIM_25x25; + case 1: + return DIM_10x25; + case 6: + case 8: + case 9: + case 11: + return DIM_20x25; + case 10: + return DIM_31x25; + default: + return DIM_15x25; + } + } + hour_txt(hour){ return hour.toString(); } + draw(hour_txt,x,y){ + /* going to leave this in here for future testing. + uncomment this so that it draws a box behind the string + so we can guess the digit dimensions*/ + /*var dim = [30,25]; + g.setColor(0.5,0,0); + g.fillPoly([x,y, + x+dim[0],y, + x+dim[0],y+dim[1], + x,y+dim[1] + ]); + g.setColor(1.0,1.0,1.0);*/ + g.setFontAlign(-1.0,-1.0,0); + g.setFontCustom(this.font, 46, this.widths, this.size); + g.drawString(hour_txt,x,y+this.y_offset ); + } + getName(){return "Digit";} +} + +module.exports = [DigitNumeralFont]; \ No newline at end of file diff --git a/apps/fontclock/fontclock.font.mntn50.js b/apps/fontclock/fontclock.font.mntn50.js new file mode 100644 index 000000000..43b8aeb9b --- /dev/null +++ b/apps/fontclock/fontclock.font.mntn50.js @@ -0,0 +1,56 @@ +var NumeralFont = require("fontclock.font.js"); + +const DIM_30x47 = [30,47]; +const DIM_49x47 = [49,47]; +const DIM_37x47 = [37,47]; +class DigitNumeralFont extends NumeralFont{ + constructor(){ + super(); + // dimension map provides the dimensions of the character for + // each number for plotting and collision detection + + /*this.dimension_map = { + 3 : [30,47], + 6 : [37,47], + 9 : [37,47], + 12: [49,47] + };*/ + this.widths = atob("DRYqFR0fHyMnICgnDQ=="); + this.font = atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAChkoAAAAAAAAAAAAAvP7wAAAAAAAAAAAAC8/vAAAAAAAAAAAAALz+8AAAAAAAAAAAAAvP7wAAAAAAAAAAAAC8/vAAAAAAAAAAAAALz+8AAAAAAAAAAAAAvP7wAAAAAAAAAAAAC8/vAAAAAAAAAAAAALz+8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAH/AAAAAAAAAAAAAB//8AAAAAAAAAAAAf///gAAAAAAAAAAH///5LAAAAAAAAAB///+S/8AAAAAAAAf///kv//wAAAAAAH///5L///4AAAAAB///+S///+G8AAAAf///kv///hv/wAAH///5L///4b///AAP//+S///+G///5AAA//kv///hv//+QAAAD5L///4b///kAAAAAC///+G///5AAAAAAA///hv//+QAAAAAAAD/4b///kAAAAAAAAAKG///5AAAAAAAAAAAv//+QAAAAAAAAAAAD//kAAAAAAAAAAAAAP5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAAAAAAAAAAC////4AAAAAAAAAAL//////gAAAAAAAAP//6Vr//8AAAAAAAH/9Gv/pH/9AAAAAAD/4v////4v/AAAAAA/8///////P/AAAAAP9v/4BUC//n/AAAAD/f/m///+b/3/AAAAv3/n/////2/3+AAAH9/3//+r//9/39AAA/v9/+G/+S/9/78AAD9/f+f///9v9/fwAAvf3/f/////f9/fgAD9/vz/4AAv/P78/AAf/39/0AAAH/f3/9AC9/f78AAAAD+/f34ALz+9/QAAAAH9+/PgA/Pvz8AAAAAPz+8/AD99/PgAAAAAvP338AP739+AAAAAC9/ffwA/ff34AAAAAL399/AD8+/PwAAAAA/P7z8APz/9/AAAAAD9//PgAvf37/AAAAA//39+AB+/Pz/AAAAP8/P70AD9/v3/wAAP/f79/AAP39/3/////3/f38AAf79/2////5/3+/QAA/f9/9r//p/9/78AAB/f9//5Rb//f9/QAAD/f9v/////n/f8AAAD/f/b////n/3/AAAAD/f/4WqlL/9/wAAAAH/X//////9f9AAAAAH/1/////9f/QAAAAAC/+H///0v/gAAAAAAB//+QAb//0AAAAAAAAf//////0AAAAAAAAAB/////QAAAAAAAAAAAAa6QAAAAAAAAAAAAAAAAAAAAAAAAClopAAAAAAAAAAAAAPvz4AAAAAAAAAAAAA+/PgAAAAAAAAAAAAD78+AAAAAAAAAAAAAPvz4AAAAAAAAAAAAA+/PgAAAAAAAAAAAAD78///////////wAAPvz///////////AAA+/P6qqqqqqqqqoAAD78///////////gAAPvz///////////AAA+/P//////////8AAD78+AAAAAAAAAAAAAPvz///////////AAA+/P//////////8AAD78/qqqqqqqqqqgAAPvz//////////+AAA+/P//////////8AAD68///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAAAAAAAAAAAAA/PQAAAAAAAG8+vAAD9+/ZAAAAAC/z+8AAP/3+9AAAAA//P7wAB+/PvwAAAAf/8/vAAL3+9/AAAAL/bz+8AA/P/z8AAAD/r/P7wAD9+/PgAAB/7/8/vAAP379+AAAv+//z+8AA/vf30AAP+/9vP7wAD+9/vQAH/v+v8/vAAP7399AD/7/f/z+8AA/fv30A/7/3//P7wAD9+/Pgv+/7/28/vAALz+9/v/v9/9/z+8AAvP3+//v/v+v/P7wAB+/f3/7/v/f/8/vAAD+/v4H/3/3/bz+8AAP39///7/2/0vP7wAAf79v/9/9/8C8/vAAA/f9G5/+v+ALz+8AAC/f/7//f/QAvP7wAAD/P///r/wAC8/vAAAH/n//n/0AALz+8AAAH/5Ab/8AAAvP7wAAAH////9AAAB8tfAAAAC///9AAAAAAAAAAAAAK/kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyQAAAAAAAAABj4AA/P7gAAAAAAAu/PwAD9+/fQAAAAH3+9/AAP73+8AAAAAfv378AB+/PvwAAAAA//P70AL3+9/AAAAAD+9/fgA/P7z8KWiloPz78+AD8+/Pg/vP7wvP/z8APz78+D+8/vC8/vPwA/fv34P7z+8L3+8/AD99/fQ/vP7wvf738AP3399D+8/vB9/ffwA/ff30P7z+8H3+9/AD9+/fg/vf30vP738APz/8/D9+/Pj8+/PwA/P77//z/9//778+AC+/f3//f3+/9/f74AD+/v3/+/v6/f7+/AAPz9/5b9/f+b/fz8AAv79////+v//3+/gAA/f9///3/f/9/38AAC/f+RR/3/Rlv9/gAAD/f////3////f8AAAD/b////3///3/AAAAH/2//X/5//n/0AAAAD/+lr///lb/8AAAAAC////9////+AAAAAAAv//9Af//+AAAAAAAABaQAAAaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7z58AAAAAAAAAAAB//P7wAAAAAAAAAAC//8/vAAAAAAAAAAC//rz+8AAAAAAAAAD//X/P7wAAAAAAAAH//X/8/vAAAAAAAAH//b//z+8AAAAAAAH//L/+vP7wAAAAAAL/+P/9f8/vAAAAAAL/+f/9f/z+8AAAAAL/9f/8v//P7wAAAAD/9f/4v/68/vAAAAAP9v/4//4vz+8AAAAA8v/5//0v/P7wAAAAAv/1//1//8/vAAAAAP/1//x///z+8AAAAA/y//i//wvP7wAAAADi//i//gC8/vAAAAAD//X//gALz+8AAAAA//X//QAAvP7wAAAAD/L//Af//8/vv/gAAOL/+AC///z+///AAAP/+AAH///P7//8AAD/9AAAAAC8/vAAAAAP9AAAB///z+///AAA4AAAAL///P7//8AAAAAAAAKqr8/vaqgAAAAAAAAAALz+8AAAAAAAAAAAAAvPrwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAA8AAAD14//////0AAL8AAAPvz//////gACf8AAA+/P/////+AAvfwAAD78+AAAAAAAD/vwAAPvz//////gA39/AAA+/P/////+AP3++AAD78/qqqqqgA/fz8AAPvz//////Qt/vvwAA+/P/////+D78/vQAD78//////4P739+AAPvz4A9ufPQ/Pvz8AA+/PgH3+9+C8+vPwAD78+Avf/z0L3+9/AAPvz4C8//fAff338AA+/PgLz7+8B9/vfwAD78+AvPv7wL3+9/AAPvz4D8+/fg/P/z8AA+/PgLz+8/D9+/PwAD78+AvP77///39+AAPvz4B+/P3/9/v/wAA+/PgD9+/3/f39/AAD78+AP38/0L/f78AAPvz4Av79///39/QAA+/PgA/f8//9//8AAD78+AB/f9L5f9/QAAPvz4AD/f/6//f8AAA+/PgAD/P///3/AAAD289AAH/j//y/wAAAAAAAAAH/9AH/8AAAAAAAAAAD////+AAAAAAAAAAAB///+AAAAAAAAAAAAAGvpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa////6QAAAAAAAAB///////+AAAAAAAB/////////gAAAAAA//kAAAABv/0AAAAAP/X//////n/0AAAAD/b///////6/0AAAA/3//6qqqv/9/wAAAL9/9a////kv9/wAAB/P+v//////P9/QAAP6/f///////P+/AAA/P3/5AAAAf/fz8AAP3+/2/////3/v74AA/f79//////79/fwAD/+/f/6qqr/3++/AAvf39/Pz799//3+9AD8/vfw/vf/w/fv38APz/8/D/9+/D8+/PwA/fvz4ff734L3/9/AD99/fS8//fQff738AP3399Lz799B9/ffwA/ff30vPv7wH3+9/AD9+/Pj8+/vQvP7z8APz68+Lz79+D8+/PwA/P338vP7z8f779+AB+/f/x+/f//+/f70AD+9/fD+9/f/7/+/AAP3+/QP3+/b2/f38AA/fz8Av/3///7//gAB/v3QA/f3///v38AAD9/gAC/v2//b+/gAAH9+AAD+/+AL/r8AAAP+wAAH+v///6/QAAAP0AAAP/f//9/4AAAAfQAAAP/lvlv+AAAAAkAAAAL//r//QAAAAAAAAAAD////wAAAAAAAAAAAAv//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPrz4AAAAAAAAAAAAA+/PgAAAAAAAAAAAAD78+AAAAAAAAAAAAAPvz4AAAAAAAAAAAAA+/PgAAAAAAAAAAAAD78+AAAAAAAAAAAAAPvz4AAAAAAAAAGAAA+/PgAAAAAAAB/8AAD78+AAAAAAAv//wAAPvz4AAAAAL///4AAA+/PgAAAC///+G8AAD78+AAAv///hv/wAAPvz4AL///4b///AAA+/Pm///+G///9EAAD79////Rv//+R/wAAPr///0f///kv//AAA///9H///5L///4AAD//R///+S///+GwAAPkf///kv///hv/AAAL///5L///4b//8AAD//+W///+G///9AAAP/hv///Rv//+QAAAAob///0f///kAAAAAC///9H///5AAAAAAAP//R///+QAAAAAAAA/kf///kAAAAAAAAAAL///5AAAAAAAAAAAP//+QAAAAAAAAAAAA//kAAAAAAAAAAAAAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//0AL//9AAAAAAAf///+L////QAAAAAP/+r////r//wAAAAD/0v5f/4r6b/wAAAA/6///n////1/wAAAP9////3////9/gAAC/f/gG/3/kB/9/AAAP7/b/9/3//+f+/AAC/f3//9/v///f79AAP39/+/9/f///f38AA/v/9uf+/v/n+/vwAL79/f/v38//38/vQA/P77//f7z///78/AD8//Pz9/vfw/Prz8AP379+H79+/D8/vfwA/vf30Pvz68L399/AD+9/fQ+/Prwff378AP7399D78+vB9/fvwA/vf30Pvz68H39+/AD+9/fQ+/Prwff378AP7399D78+vB9/fvwA/vf30Pvz+8H39+/AD9+/fg/vP7wvf338APz/8/D+8/vT8/vfwA/P77/v339//378/AC9/f7//P77/+/f34AH++/r/9/f3/r9/vQAP39/0H++v4D/f38AA/v+///39///+/fwAA/f9///39//+v39AAD/v9b5/v+b+P+/wAAD/f/6//v/6//r8AAAH/f////7///2/gAAAL/X//3/3//5/4AAAAH/5FC//9BB/+AAAAAH//////////QAAAAAB////A////QAAAAAAAK/5AAG/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//QAAAAAAAAAAAAv///4AAAAAAAAAAAf////9AAAABQAAAAH/0aR/9AAAAPQAAAB/2//+v9AAAC/AAAAf9////f8AAA3/AAAD/f/Qf/f4AAL38AAAv3/P/n/fwAAv78AAD+/r//3/fwAd/fwAAv7+///7+/AD9/vgAD9/f8pv3+/Af39/AAP7//v//v38Lf778AB+/f3/9/f/w//P70AL3++/r+9/vT99/fgA/P7z8Pz79+Pz78/AD9+/Pgvf/z4vPrz8AP3799B9/vPi9/vfwA/vf30D7+8+H399/AD9+/fQff/z4ff338AP3799C8+/fS8/vfwA/P7z4P73+8Pz/8/AD8/vfw//fvw/fvz8AL39//n3+8/P79/fgAP/39/6VVVv/f7/8AA/f7+//////3+/fwAD+/f9/////9/79/AAH9/f+FVVVRv9/P0AAP3+f///////f9/AAAf3/f//////7/P0AAA/3/W////+j/3/AAAA/7/+lVVVr/9/wAAAB/3///////+f9AAAAB/9//////+L/QAAAAB//QVVVVQv/wAAAAAA/////////4AAAAAAAf///////4AAAAAAAABv////+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB89fAHz18AAAAAAAAPz78AvP7wAAAAAAAA/PvwC8/vAAAAAAAAD8+/ALz+8AAAAAAAAPz78AvP7wAAAAAAAA/PvwC8/vAAAAAAAAD8+/ALz+8AAAAAAAAPz78AvP7wAAAAAAAA/PvwC8/vAAAAAAAAC8+vALz68AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); + var scale = 1; // size multiplier for this font + this.size = 50+(scale<<8)+(2<<16); + this.y_offset = -2; + + } + getDimensions(hour){ + switch(hour){ + case 3: + return DIM_30x47; + case 12: + return DIM_49x47; + default: + return DIM_37x47; + } + //return this.dimension_map[hour]; + } + hour_txt(hour){ return hour.toString(); } + draw(hour_txt,x,y){ + /* going to leave this in here for future testing. + uncomment this so that it draws a box behind the string + so we can guess the digit dimensions + var dim = [37,47]; + g.setColor(0.5,0,0); + g.fillPoly([x,y, + x+dim[0],y, + x+dim[0],y+dim[1], + x,y+dim[1] + ]); + g.setColor(1.0,1.0,1.0);*/ + g.setFontAlign(-1.0,-1.0,0); + g.setFontCustom(this.font, 46, this.widths, this.size); + g.drawString(hour_txt,x,y+this.y_offset ); + } + getName(){return "Digit";} +} + +module.exports = [DigitNumeralFont]; \ No newline at end of file diff --git a/apps/fontclock/fontclock.font.vector25.js b/apps/fontclock/fontclock.font.vector25.js new file mode 100644 index 000000000..0c66b1d07 --- /dev/null +++ b/apps/fontclock/fontclock.font.vector25.js @@ -0,0 +1,55 @@ +var NumeralFont = require("fontclock.font.js"); + +const DIM_14x22 = [14,22]; +const DIM_27x22 = [27,22]; +class DigitNumeralFont extends NumeralFont{ + constructor(){ + super(); + // dimension map provides the dimesions of the character for + // each number for plotting and collision detection + /*this.dimension_map = { + 1 : [14,22], + 2 : [14,22], + 3 : [14,22], + 4 : [14,22], + 5 : [14,22], + 6 : [14,22], + 7 : [14,22], + 8 : [14,22], + 9 : [14,22], + 10: [27,22], + 11: [27,22], + 12: [27,22] + };*/ + } + getDimensions(hour){ + if (hour < 10){ + return DIM_14x22; + } else { + return DIM_27x22; + } + } + hour_txt(hour){ return hour.toString(); } + draw(hour_txt,x,y){ + if(hour_txt == null) + return; + + /* going to leave this in here for future testing. + uncomment this so that it draws a box behind the string + so we can guess the digit dimensions + var dim = [14,22]; + g.setColor(0.5,0,0); + g.fillPoly([x,y, + x+dim[0],y, + x+dim[0],y+dim[1], + x,y+dim[1] + ]); + g.setColor(1.0,1.0,1.0);*/ + g.setFontAlign(-1,-1,0); + g.setFont("Vector",25); + g.drawString(hour_txt,x,y); + } + getName(){return "Digit";} +} + +module.exports = [DigitNumeralFont]; \ No newline at end of file diff --git a/apps/fontclock/fontclock.font.vector50.js b/apps/fontclock/fontclock.font.vector50.js new file mode 100644 index 000000000..85466958f --- /dev/null +++ b/apps/fontclock/fontclock.font.vector50.js @@ -0,0 +1,42 @@ +var NumeralFont = require("fontclock.font.js"); + +const DIM_28x44 = [28,44]; +const DIM_54x44 = [54,44]; + +class DigitNumeralFont extends NumeralFont{ + constructor(){ + super(); + // dimension map provides the dimesions of the character for + // each number for plotting and collision detection + } + getDimensions(hour){ + if (hour < 10){ + return DIM_28x44; + } else { + return DIM_54x44; + } + } + hour_txt(hour){ return hour.toString(); } + draw(hour_txt,x,y){ + if(hour_txt == null) + return; + + /* going to leave this in here for future testing. + uncomment this so that it draws a box behind the string + so we can guess the digit dimensions + var dim = [14,22]; + g.setColor(0.5,0,0); + g.fillPoly([x,y, + x+dim[0],y, + x+dim[0],y+dim[1], + x,y+dim[1] + ]); + g.setColor(1.0,1.0,1.0);*/ + g.setFontAlign(-1,-1,0); + g.setFont("Vector",50); + g.drawString(hour_txt,x,y); + } + getName(){return "Digit";} +} + +module.exports = [DigitNumeralFont]; \ No newline at end of file diff --git a/apps/fontclock/fontclock.hand.js b/apps/fontclock/fontclock.hand.js new file mode 100644 index 000000000..c5ab2e769 --- /dev/null +++ b/apps/fontclock/fontclock.hand.js @@ -0,0 +1,10 @@ +class Hand { + /** + * Pure virtual class for all Hand classes to extend. + * a hand class will have 1 main function + * moveTo which will move the hand to the given angle. + */ + moveTo(angle){} +} + +module.exports = Hand; \ No newline at end of file diff --git a/apps/fontclock/fontclock.hourscriber.js b/apps/fontclock/fontclock.hourscriber.js new file mode 100644 index 000000000..38f960da3 --- /dev/null +++ b/apps/fontclock/fontclock.hourscriber.js @@ -0,0 +1,137 @@ + +const TWO_PI = 2* Math.PI; + +// The problem with the trig inverse functions on +// a full circle is that the sector information will be lost +// Choosing to use arcsin because you can get back the +// sector with the help of the original coordinates +function reifyasin(x,y,asin_angle){ + if(x >= 0 && y >= 0){ + return asin_angle; + } else if(x >= 0 && y < 0){ + return Math.PI - asin_angle; + } else if(x < 0 && y < 0){ + return Math.PI - asin_angle; + } else { + return TWO_PI + asin_angle; + } +} + +// rebase and angle so be between -pi and pi +// rather than 0 to 2PI +function rebaseNegative(angle){ + if(angle > Math.PI){ + return angle - TWO_PI; + } else { + return angle; + } +} + +// rebase an angle so that it is between 0 to 2pi +// rather than -pi to pi +function rebasePositive(angle){ + if(angle < 0){ + return angle + TWO_PI; + } else { + return angle; + } +} + +/** + * The Hour Scriber is responsible for drawing the numeral + * on the screen at the requested angle. + * It allows for the font to be changed on the fly. + */ +class HourScriber { + constructor(radius, numeral_font, draw_test, bg_colour_supplier, numeral_colour_supplier, hour){ + this.radius = radius; + this.numeral_font = numeral_font; + this.draw_test = draw_test; + this.curr_numeral_font = numeral_font; + this.bg_colour_supplier = bg_colour_supplier; + this.numeral_colour_supplier = numeral_colour_supplier; + this.hours = hour; + this.curr_hour_x = -1; + this.curr_hour_y = -1; + this.curr_hours = -1; + this.curr_hour_str = null; + this.last_draw_time = null; + } + setNumeralFont(numeral_font){ + this.numeral_font = numeral_font; + } + toString(){ + return "HourScriber{numeralfont=" + this.numeral_font.getName() + ",hours=" + this.hours + "}"; + } + draw(){ + var changed = false; + if(this.curr_hours != this.hours || this.curr_numeral_font !=this.numeral_font){ + var background = this.bg_colour_supplier(); + g.setColor(background[0],background[1],background[2]); + this.curr_numeral_font.draw(this.curr_hour_str, + this.curr_hour_x, + this.curr_hour_y); + //console.log("erasing old hour"); + var hours_frac = this.hours / 12; + var angle = TWO_PI*hours_frac; + var dimensions = this.numeral_font.getDimensions(this.hours); + // we set the radial coord to be in the middle + // of the drawn text. + var width = dimensions[0]; + var height = dimensions[1]; + var delta_center_x = this.radius*Math.sin(angle) - width/2; + var delta_center_y = this.radius*Math.cos(angle) + height/2; + this.curr_hour_x = screen_center_x + delta_center_x; + this.curr_hour_y = screen_center_y - delta_center_y; + this.curr_hour_str = this.numeral_font.hour_txt(this.hours); + // now work out the angle of the beginning and the end of the + // text box so we know when to redraw + // bottom left angle + var x1 = delta_center_x; + var y1 = delta_center_y; + var r1 = Math.sqrt(x1*x1 + y1*y1); + var angle1 = reifyasin(x1,y1,Math.asin(x1/r1)); + // bottom right angle + var x2 = delta_center_x; + var y2 = delta_center_y - height; + var r2 = Math.sqrt(x2*x2 + y2*y2); + var angle2 = reifyasin(x2,y2,Math.asin(x2/r2)); + // top left angle + var x3 = delta_center_x + width; + var y3 = delta_center_y; + var r3 = Math.sqrt(x3*x3 + y3*y3); + var angle3 = reifyasin(x3,y3, Math.asin(x3/r3)); + // top right angle + var x4 = delta_center_x + width; + var y4 = delta_center_y - height; + var r4 = Math.sqrt(x4*x4 + y4*y4); + var angle4 = reifyasin(x4,y4,Math.asin(x4/r4)); + if(Math.min(angle1,angle2,angle3,angle4) < Math.PI && Math.max(angle1,angle2,angle3,angle4) > 1.5*Math.PI){ + angle1 = rebaseNegative(angle1); + angle2 = rebaseNegative(angle2); + angle3 = rebaseNegative(angle3); + angle3 = rebaseNegative(angle4); + this.angle_from = rebasePositive( Math.min(angle1,angle2,angle3,angle4) ); + this.angle_to = rebasePositive( Math.max(angle1,angle2,angle3,angle4) ); + } else { + this.angle_from = Math.min(angle1,angle2,angle3,angle4); + this.angle_to = Math.max(angle1,angle2,angle3,angle4); + } + //console.log(angle1 + "/" + angle2 + " / " + angle3 + " / " + angle4); + //console.log( this.angle_from + " to " + this.angle_to); + this.curr_hours = this.hours; + this.curr_numeral_font = this.numeral_font; + changed = true; + } + if(changed || + this.draw_test(this.angle_from, this.angle_to, this.last_draw_time) ){ + var numeral_color = this.numeral_colour_supplier(); + g.setColor(numeral_color[0],numeral_color[1],numeral_color[2]); + this.numeral_font.draw(this.curr_hour_str,this.curr_hour_x,this.curr_hour_y); + this.last_draw_time = new Date(); + //console.log("redraw digit:" + this.hours); + } + } +} + +module.exports = HourScriber; \ No newline at end of file diff --git a/apps/fontclock/fontclock.js b/apps/fontclock/fontclock.js new file mode 100644 index 000000000..25260c42c --- /dev/null +++ b/apps/fontclock/fontclock.js @@ -0,0 +1,432 @@ +/** +* Adrian Kirk 2021-03 +* Simple Clock showing 1 numeral for the hour +* with a smooth sweep second. +*/ + +var ThinHand = require("fontclock.thinhand.js"); +var ThickHand = require("fontclock.thickhand.js"); +var HourScriber = require("fontclock.hourscriber.js"); + +const screen_center_x = g.getWidth()/2; +const screen_center_y = 10 + (g.getHeight()+10)/2; +const TWO_PI = 2* Math.PI; + + +SETTING_PREFIX = "fontclock"; +// load the date formats and languages required +const FONTS_FILE = SETTING_PREFIX +".font.json"; +const DEFAULT_FONTS = [ "cpstc58" ]; +const DEFAULT_NUMERALS = [12,3,6,9]; +const DEFAULT_RADIUS = 70; +var color_schemes = [ + { + name: "black", + background : [0.0,0.0,0.0], + } +]; +var fonts = DEFAULT_NUMERALS; +var numerals = DEFAULT_NUMERALS; +var radius = DEFAULT_RADIUS; +try{ + var fonts_info = require("Storage").readJSON(FONTS_FILE); + if(fonts_info != null){ + console.log("loaded font:" + JSON.stringify(fonts_info)); + fonts = fonts_info.fonts; + numerals = fonts_info.numerals; + radius = fonts_info.radius; + color_schemes = fonts_info.color_schemes; + } else { + fonts = DEFAULT_FONTS; + numerals = DEFAULT_NUMERALS; + radius = DEFAULT_RADIUS; + console.log("no fonts loaded defaulting to:" + fonts); + } +} catch(e){ + console.log("failed to load fonts:" + e); +} +if(fonts == null || fonts.length == 0){ + fonts = DEFAULT_FONTS; + console.log("defaulting fonts to locale:" + fonts); +} + +let color_scheme_index = 0; + +// The force draw is set to true to force all objects to redraw themselves +let force_redraw = true; +let bg_colour_supplier = ()=>color_schemes[color_scheme_index].background; +var WHITE = [1.0,1.0,1.0]; +function default_white(color){ + if(color == null){ + return WHITE + } else { + return color; + } +} + +// The seconds hand is the main focus and is set to redraw on every cycle +let seconds_hand = new ThinHand(screen_center_x, + screen_center_y, + 95, + 0, + (angle, last_draw_time) => false, + bg_colour_supplier, + ()=>default_white(color_schemes[color_scheme_index].second_hand)); + +// The minute hand is set to redraw at a 250th of a circle, +// when the second hand is ontop or slighly overtaking +// or when a force_redraw is called +const minute_hand_angle_tolerance = TWO_PI/25 +let minutes_hand_redraw = function(angle, last_draw_time){ + return force_redraw || (seconds_hand.angle > angle && + Math.abs(seconds_hand.angle - angle) < minute_hand_angle_tolerance && + new Date().getTime() - last_draw_time.getTime() > 500); +}; + +let minutes_hand = new ThinHand(screen_center_x, + screen_center_y, + 80, minute_hand_angle_tolerance, + minutes_hand_redraw, + bg_colour_supplier, + ()=>default_white(color_schemes[color_scheme_index].minute_hand)); +// The hour hand is a thick hand so we have to redraw when the minute hand +// overlaps from its behind angle coverage to its ahead angle coverage. +let hour_hand_redraw = function(angle_from, angle_to, last_draw_time){ + return force_redraw || (seconds_hand.angle >= angle_from && + seconds_hand.angle <= angle_to && + new Date().getTime() - last_draw_time.getTime() > 500); +}; +let hours_hand = new ThickHand(screen_center_x, + screen_center_y, + 40, + TWO_PI/600, + hour_hand_redraw, + bg_colour_supplier, + () => default_white(color_schemes[color_scheme_index].hour_hand), + 5, + 4); + +function draw_clock(){ + var date = new Date(); + draw_background(); + draw_hour_digits(); + draw_seconds(date); + draw_mins(date); + draw_hours(date); + force_redraw = false; +} +// drawing the second the millisecond as we need the fine gradation +// for the sweep second hand. +function draw_seconds(date){ + var seconds = date.getSeconds() + date.getMilliseconds()/1000; + var seconds_frac = seconds / 60; + var seconds_angle = TWO_PI*seconds_frac; + seconds_hand.moveTo(seconds_angle); +} +// drawing the minute includes the second and millisec to make the +// movement as continuous as possible. +function draw_mins(date,seconds_angle){ + var mins = date.getMinutes() + date.getSeconds()/60 + date.getMilliseconds()/(60*1000); + var mins_frac = mins / 60; + var mins_angle = TWO_PI*mins_frac; + var redraw = minutes_hand.moveTo(mins_angle); + if(redraw){ + //console.log("redraw mins"); + } +} + +function draw_hours(date){ + var hours = (date.getHours() % 12) + date.getMinutes()/60 + date.getSeconds()/3600; + var hours_frac = hours / 12; + var hours_angle = TWO_PI*hours_frac; + var redraw = hours_hand.moveTo(hours_angle); + if(redraw){ + //console.log("redraw hours"); + } +} + + + +let numeral_fonts = []; +for(var i=0; i< fonts.length; i++) { + var file = SETTING_PREFIX +".font." + fonts[i] + ".js" + console.log("loading font set:" + fonts[i] + "->" + file); + var loaded_fonts = require(file); + for (var j = 0; j < loaded_fonts[j]; j++) { + var loaded_font = new loaded_fonts[j]; + numeral_fonts.push(loaded_font); + console.log("loaded font name:" + loaded_font.getName()) + } +} + +let numeral_fonts_index = 0; +const ONE_POINT_FIVE_PI = 1.5*Math.PI; +/** +* predicate for deciding when the digit has to be redrawn +*/ +let hour_numeral_redraw = function(angle_from, angle_to, last_draw_time){ + var seconds_hand_angle = seconds_hand.angle; + // we have to cope with the 12 problem where the + // left side of the box has a value almost 2PI and the right + // side has a small positive value. The values are rebased so + // that they can be compared + if(angle_from > angle_to && angle_from > ONE_POINT_FIVE_PI){ + angle_from = angle_from - TWO_PI; + if(seconds_hand_angle > Math.PI) + seconds_hand_angle = seconds_hand_angle - TWO_PI; + } + //console.log("initial:" + angle_from + "/" + angle_to + " seconds " + seconds_hand_angle); + var redraw = force_redraw || + (seconds_hand_angle >= angle_from && seconds_hand_angle <= angle_to && seconds_hand.last_draw_time.getTime() > last_draw_time.getTime()) || + (minutes_hand.last_draw_time.getTime() > last_draw_time.getTime()); + if(redraw){ + //console.log(angle_from + "/" + angle_to + " seconds " + seconds_hand_angle); + } + return redraw; +}; + +// now add the numbers to the clock face +var numeral_colour_supplier = () => default_white(color_schemes[color_scheme_index].numeral); +var hour_scribers = []; +console.log("numerals:" + numerals + " length:" + numerals.length) +console.log("radius:" + radius) +for(var digit_idx=0; digit_idx" + scriber); +} +//console.log("hour_scribers:" + hour_scribers ); + +/** +* Called from button 1 to change the numerals that are +* displayed on the clock face +*/ +function next_font() { + var curr_font = numeral_fonts_index; + numeral_fonts_index = numeral_fonts_index + 1; + if (numeral_fonts_index >= numeral_fonts.length) { + numeral_fonts_index = 0; + } + + if (curr_font != numeral_fonts_index) { + for (var i = 0; i < hour_scribers.length; i++) { + hour_scribers[i].setNumeralFont( + numeral_fonts[numeral_fonts_index]); + } + force_redraw = true; + return true; + } else { + return false; + } +} + +const hour_zone_angle = hour_scribers.length/TWO_PI; +function draw_hour_digits() { + if(force_redraw){ + for(var i=0; i" + scriber); + scriber.draw(); + } + } else { + var hour_scriber_idx = (0.5 + (seconds_hand.angle * hour_zone_angle)) | 0; + if (hour_scriber_idx >= hour_scribers.length) + hour_scriber_idx = 0; + + //console.log("angle:" + seconds_hand.angle + " idx:" + hour_scriber_idx); + if (hour_scriber_idx >= 0) { + hour_scribers[hour_scriber_idx].draw(); + } + } +} + + + +function draw_background(){ + if(force_redraw){ + background = color_schemes[color_scheme_index].background; + g.setColor(background[0],background[1],background[2]); + g.fillPoly([0,25, + 0,240, + 240,240, + 240,25 + ]); + } +} + +function next_colorscheme(){ + var prev_color_scheme_index = color_scheme_index; + color_scheme_index += 1; + color_scheme_index = color_scheme_index % color_schemes.length; + //console.log("color_scheme_index=" + color_scheme_index); + force_redraw = true; + if(prev_color_scheme_index == color_scheme_index){ + return true; + } else { + return false; + } +} + +/** +* called from load_settings on startup to +* set the color scheme to named value +*/ +function set_colorscheme(colorscheme_name){ + console.log("setting color scheme:" + colorscheme_name); + for (var i=0; i < color_schemes.length; i++) { + if(color_schemes[i].name == colorscheme_name){ + color_scheme_index = i; + force_redraw = true; + console.log("match"); + break; + } + } +} + +/** +* called from load_settings on startup +* to set the font to named value +*/ +function set_font(font_name){ + console.log("setting font:" + font_name); + for (var i=0; i < numeral_fonts.length; i++) { + if(numeral_fonts[i].getName() == font_name) { + numeral_fonts_index = i; + force_redraw = true; + console.log("match"); + for (var j = 0; j < hour_scribers.length; j++) { + hour_scribers[j].setNumeralFont(numeral_fonts[numeral_fonts_index]); + } + break; + } + } +} + +/** +* Called on startup to set the watch to the last preference settings +*/ +function load_settings(){ + try{ + var file = SETTING_PREFIX + ".settings.json"; + settings = require("Storage").readJSON(file); + if(settings != null){ + console.log(file + " loaded:" + JSON.stringify(settings)); + if(settings.color_scheme != null){ + set_colorscheme(settings.color_scheme); + } + if(settings.font != null){ + set_font(settings.font); + } + } else { + console.log(file + " not found - no settings to load"); + } + } catch(e){ + console.log("failed to load settings:" + e); + } +} + +/** +* Called on button press to save down the last preference settings +*/ +function save_settings(){ + var settings = { + font : numeral_fonts[numeral_fonts_index].getName(), + color_scheme : color_schemes[color_scheme_index].name, + }; + var file = SETTING_PREFIX + ".settings.json"; + console.log(file + ": saving:" + JSON.stringify(settings)); + require("Storage").writeJSON(file,settings); +} + +// Boiler plate code for setting up the clock, +// below +let intervalRef = null; + +function clearTimers(){ + if(intervalRef) { + clearInterval(intervalRef); + intervalRef = null; + } +} + +function startTimers(){ + setTimeout(scheduleDrawClock,100); + draw_clock(); +} + +// The clock redraw is set to 100ms. This is the smallest number +// that give the (my) human eye the illusion of a continious sweep +// second hand. +function scheduleDrawClock(){ + if(intervalRef) clearTimers(); + intervalRef = setInterval(draw_clock, 100); + draw_clock(); +} + +function reset_clock(){ + force_redraw = true; +} + +Bangle.on('lcdPower', (on) => { + if (on) { + console.log("lcdPower: on"); + reset_clock(); + startTimers(); + } else { + console.log("lcdPower: off"); + reset_clock(); + clearTimers(); + } +}); + +Bangle.on('faceUp',function(up){ + console.log("faceUp: " + up + " LCD: " + Bangle.isLCDOn()); + if (up && !Bangle.isLCDOn()) { + //console.log("faceUp and LCD off"); + clearTimers(); + Bangle.setLCDPower(true); + } +}); + +g.clear(); +load_settings(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +startTimers(); + +function button1pressed() { + if (next_font()) { + save_settings(); + } +} + +function button2pressed() { + clearTimers(); + // the clock is being unloaded so we clear out the big + // data structures for the launcher + hour_scribers = []; + Bangle.showLauncher(); +} + +function button3pressed(){ + if(next_colorscheme()) { + save_settings(); + } +} + +// Handle button 1 being pressed +setWatch(button1pressed, BTN1,{repeat:true,edge:"falling"}); + +// Handle button 1 being pressed +setWatch(button2pressed, BTN2,{repeat:true,edge:"falling"}); + +// Handle button 3 being pressed +setWatch(button3pressed, BTN3,{repeat:true,edge:"falling"}); + diff --git a/apps/fontclock/fontclock.png b/apps/fontclock/fontclock.png new file mode 100644 index 0000000000000000000000000000000000000000..70a1cd5327a61bc1b0d393b57e2093864e565b9c GIT binary patch literal 2669 zcmZ`*c{r478-GXk?p)c+{?6b0`1>Ob#g46*ZED8Wt*`}}=0PxoWfVXY{ zfXV;>X=+ZL9h&W6k_cEY8yi5At@8ssAaP(DTLZB_03-)+qOmo=5+wg!$AdJ!VYmPw zmJD!z!yIKx&az-{4rfbp<#BySXyk4Cp>v@3B_kEtLV#-FLzzm!eb76qq9$j;1di66$OI@1_nX{wV@Q+aTr`* zUmvE0fFTeNHUdIF?aOdyLVW4Fwu1aG4u(Ycq>-r%GR0S!6W85?;?FPygE@)5udO;6 zWUn8YeCglXVmAomcwlg-7VK9v5|jKdG>&JB_O-9AbZAa6)FB#~#4eaqmJuBNHNpSc zew4R`$CKz3Z+{Nl!I#W1LVTnA!~7GAlN)7AW|F*}Fk~N+FP)PKp`(R{{nGPGCgES1 zKY9MiG^2P^X!cZhPZFoGugQKgeM6&RoLT%do2|irwX!E~B#4H6zePrZBc{Isgchv(`i zxF%HKsg(i4gtInws%mGY)4<0qdZJy{N_E7pmFcU7E18)6HqG*yZ+zjjWgs#JK606g|s|TG?#Q19D1d+;5eF>Pv+vGdCU{;UUV% z)SZb^S-z<8dz!4|ec{%&p7~&IJxt=e2b4mx$G}`3-T%5P@!`tVD`}u}N>Sk{-Rt1Q z!!aX<8{mT3h0eTjJtEv$uCo(R>q2-I%nJ*)o2|5lgRwVs7kD4<(WW`yN8sUzdk-Qz z9)Fa`J`ywQyp5;d)=^#m|4q?xxQtWnX4Xu_uV}=%0G5y*N zf>Z>umgyU2bUdl*BNrljje9C$mFv;tbSXB)Vca$j}6@(Skd7K&84YGW61+)W)(% zuUX+kN}+^%+P0W6Jl0xgy_k0Z{}ck!;DXiExZRMzpmeQUXEE(li*bm zDGjsY4>G++N#^eG1-|)1!)>Nm(CDX^Kr2j7W(jBHHD_lW5fz4TyR1akS3c`u97cxyvnhGZ&z*n z! zB|H4m)x7F&j6->kCwk$P%j<@EF_S+ZKMIOQ8WZE}2VM~(-PI-eBd7d3L)x!q60k{j zs1V^jg~bkr(k23TDl?0U)K+jJ0`7@jZ3EAaEvjDHf8_9gzz~ybepqXDbWG#XkixdL z?ws|d8D~JPQc2?d4Lc8bqLxe|LHXhnjM?r^2FS&+&OlVA%Hd89t3pT0rc&O48^P19 z2i_+6setc2em}G~^ggMi!xm*BK5E_=?mD7EIKTHdKPe%)xY3a(>Zn{LM5ge`$%L7-nhS`xJ~7Z(*1h2WfX^!9!|e>b(_N>%l46OF^w2ee>-7Aa>hk3bd_I7B`pp|q<8Ds0JZ#^k_^x03vT^>KzyIA6-Gin$_mX}?-;uCu}@oDBVkIq zYiE(YT|`4xZ{E=ov+AV*O`{33eO%d+hrHU42)`mjy~}ZlPnCjlQN8hFE9N5UtH7>_ z#nEdAbE?m4LRQ{y(i{BMGpAgN`X_Jpwdsa#%CoAg%POjPwSC7IW+b2mmmZ&Nu+_(Y zZf$R`)l_vKo~^Gb3+0Op5lrggzp}9*%6NS`Vmn5qIVlr)cVh(Pb1~G6-=eQEpgwYG zwwIsxQcY9SfyL*B3PT|~tK@7<@7&(!=<8#JO&t%iDD*C{$Eu!VX+rZYGz05uRM!yd guW3u`ALm1XW#=8{i!Y this.tolerance || this.draw_test(this.angle - this.delta_base,this.angle + this.delta_base ,this.last_draw_time) ){ + //var background = color_schemes[color_scheme_index].background; + var background = this.color_bg_supplier; + g.setColor(background[0],background[1],background[2]); + g.fillPoly([this.last_x1, + this.last_y1, + this.last_x2, + this.last_y2, + this.last_x3, + this.last_y3, + this.last_x4, + this.last_y4 + ]); + // bottom left + var x1 = this.centerX + + this.vertex_radius_base*Math.sin(angle - this.delta_base); + var y1 = this.centerY - this.vertex_radius_base*Math.cos(angle - this.delta_base); + // bottom right + var x2 = this.centerX + + this.vertex_radius_base*Math.sin(angle + this.delta_base); + var y2 = this.centerY - this.vertex_radius_base*Math.cos(angle + this.delta_base); + // top right + var x3 = this.centerX + this.vertex_radius_top*Math.sin(angle + this.delta_top); + var y3 = this.centerY - this.vertex_radius_top*Math.cos(angle + this.delta_top); + // top left + var x4 = this.centerX + this.vertex_radius_top*Math.sin(angle - this.delta_top); + var y4 = this.centerY - this.vertex_radius_top*Math.cos(angle - this.delta_top); + //var hand_color = color_schemes[color_scheme_index][this.color_theme]; + var hand_color = this.color_fg_supplier(); + g.setColor(hand_color[0],hand_color[1],hand_color[2]); + g.fillPoly([x1,y1, + x2,y2, + x3,y3, + x4,y4 + ]); + this.last_x1 = x1; + this.last_y1 = y1; + this.last_x2 = x2; + this.last_y2 = y2; + this.last_x3 = x3; + this.last_y3 = y3; + this.last_x4 = x4; + this.last_y4 = y4; + this.angle = angle; + this.last_draw_time = new Date(); + return true; + } else { + return false; + } + } +} + +module.exports = ThickHand; \ No newline at end of file diff --git a/apps/fontclock/fontclock.thinhand.js b/apps/fontclock/fontclock.thinhand.js new file mode 100644 index 000000000..cf58d451a --- /dev/null +++ b/apps/fontclock/fontclock.thinhand.js @@ -0,0 +1,67 @@ +var Hand = require("fontclock.hand.js"); + +class ThinHand extends Hand { + /** + * The thin hand is created from a simple line, so its easy and fast + * to draw. + */ + constructor(centerX, + centerY, + length, + tolerance, + draw_test, + color_bg_supplier, + color_fg_supplier){ + super(); + this.centerX = centerX; + this.centerY = centerY; + this.length = length; + this.color_bg_supplier = color_bg_supplier; + this.color_fg_supplier = color_fg_supplier; + // The last x and y coordinates (not the centre) of the last draw + this.last_x = centerX; + this.last_y = centerY; + // tolerance is the angle tolerance (from the last draw) + // in radians for a redraw to be called. + this.tolerance = tolerance; + // draw test is a predicate (angle, time). This is called + // when the hand thinks that it does not have to draw (from its internal tests) + // to see if it has to draw because of another object. + this.draw_test = draw_test; + // The current angle of the hand. Set to -1 initially + this.angle = -1; + this.last_draw_time = null; + this.active = false; + } + // method to move the hand to a new angle + moveTo(angle){ + // first test to see of the angle called is beyond the tolerance + // for a redraw + if(Math.abs(angle - this.angle) > this.tolerance || + // and then call the predicate to see if a redraw is needed + this.draw_test(this.angle,this.last_draw_time) ){ + // rub out the old hand line + var background = this.color_bg_supplier(); + g.setColor(background[0],background[1],background[2]); + g.drawLine(this.centerX, this.centerY, this.last_x, this.last_y); + // Now draw the new hand line + var hand_color = this.color_fg_supplier(); + g.setColor(hand_color[0],hand_color[1],hand_color[2]); + var x2 = this.centerX + this.length*Math.sin(angle); + var y2 = this.centerY - this.length*Math.cos(angle); + g.drawLine(this.centerX, this.centerY, x2, y2); + // and store the last draw details for the next call + this.last_x = x2; + this.last_y = y2; + this.angle = angle; + this.last_draw_time = new Date(); + this.active = true; + return true; + } else { + this.active = false; + return false; + } + } +} + +module.exports = ThinHand; \ No newline at end of file