From 0a3815016a1b3e6ba26e60974e8bd57bf3a17ec2 Mon Sep 17 00:00:00 2001 From: Ned Gulley Date: Thu, 14 Nov 2024 15:49:05 -0500 Subject: [PATCH] Simplifying (with the help of ChatGPT) --- SunriseSunset.js | 272 ----------------------- clock_face.png | Bin 23953 -> 0 bytes index.html | 535 +++++++++++++++++++++++++++++++++++++++++++-- sunset-colors.json | 103 --------- sunset.css | 39 ---- sunset.js | 204 ----------------- 6 files changed, 520 insertions(+), 633 deletions(-) delete mode 100644 SunriseSunset.js delete mode 100644 clock_face.png delete mode 100644 sunset-colors.json delete mode 100644 sunset.css delete mode 100644 sunset.js diff --git a/SunriseSunset.js b/SunriseSunset.js deleted file mode 100644 index 94f4f10..0000000 --- a/SunriseSunset.js +++ /dev/null @@ -1,272 +0,0 @@ -// SunriseSunset Class (2013-04-21) -// -// OVERVIEW -// -// Implementation of http://williams.best.vwh.net/sunrise_sunset_algorithm.htm -// -// LICENSE -// -// Copyright 2011-2013 Preston Hunt -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// DESCRIPTION -// -// Provides sunrise and sunset times for specified date and position. -// All dates are UTC. Year is 4-digit. Month is 1-12. Day is 1-31. -// Longitude is positive for east, negative for west. Latitude is -// positive for north, negative for south. -// -// SAMPLE USAGE -// -// var tokyo = new SunriseSunset( 2011, 1, 19, 35+40/60, 139+45/60); -// tokyo.sunriseUtcHours() --> 21.8199 = 21:49 GMT -// tokyo.sunsetUtcHours() --> 7.9070 = 07:54 GMT -// tokyo.sunriseLocalHours(9) --> 6.8199 = 06:49 at GMT+9 -// tokyo.sunsetLocalHours(9) --> 16.9070 = 16:54 at GMT+9 -// tokyo.isDaylight(1.5) --> true -// -// var losangeles = new SunriseSunset( 2011, 1, 19, 34.05, -118.233333333 ); -// etc. - -var SunriseSunset = function( utcFullYear, utcMonth, utcDay, latitude, longitude ) { - this.zenith = 90 + 50/60; // offical = 90 degrees 50' - // civil = 96 degrees - // nautical = 102 degrees - // astronomical = 108 degrees - - this.utcFullYear = utcFullYear; - this.utcMonth = utcMonth; - this.utcDay = utcDay; - this.latitude = latitude; - this.longitude = longitude; - - this.rising = true; // set to true for sunrise, false for sunset - this.lngHour = this.longitude / 15; -}; - -SunriseSunset.prototype = { - sin: function( deg ) { return Math.sin( deg * Math.PI / 180 ); }, - cos: function( deg ) { return Math.cos( deg * Math.PI / 180 ); }, - tan: function( deg ) { return Math.tan( deg * Math.PI / 180 ); }, - asin: function( x ) { return (180/Math.PI) * Math.asin(x); }, - acos: function( x ) { return (180/Math.PI) * Math.acos(x); }, - atan: function( x ) { return (180/Math.PI) * Math.atan(x); }, - - getDOY: function() { - var month = this.utcMonth, - year = this.utcFullYear, - day = this.utcDay; - - var N1 = Math.floor( 275 * month / 9 ); - var N2 = Math.floor( (month + 9) / 12 ); - var N3 = (1 + Math.floor((year - 4 * Math.floor(year / 4 ) + 2) / 3)); - var N = N1 - (N2 * N3) + day - 30; - return N; - }, - - approximateTime: function() { - var doy = this.getDOY(); - if ( this.rising ) { - return doy + ((6 - this.lngHour) / 24); - } else { - return doy + ((18 - this.lngHour) / 24); - } - }, - - meanAnomaly: function() { - var t = this.approximateTime(); - return (0.9856 * t) - 3.289; - }, - - trueLongitude: function() { - var M = this.meanAnomaly(); - var L = M + (1.916 * this.sin(M)) + (0.020 * this.sin(2 * M)) + 282.634; - return L % 360; - }, - - rightAscension: function() { - var L = this.trueLongitude(); - var RA = this.atan(0.91764 * this.tan(L)); - RA %= 360; - - var Lquadrant = (Math.floor( L/90)) * 90; - var RAquadrant = (Math.floor(RA/90)) * 90; - RA = RA + (Lquadrant - RAquadrant); - RA /= 15; - - return RA; - }, - - sinDec: function() { - var L = this.trueLongitude(), - sinDec = 0.39782 * this.sin(L); - - return sinDec; - }, - - cosDec: function() { - return this.cos(this.asin(this.sinDec())); - }, - - localMeanTime: function() { - var cosH = (this.cos(this.zenith) - (this.sinDec() * this.sin(this.latitude))) - / (this.cosDec() * this.cos(this.latitude)); - - if (cosH > 1) { - return "the sun never rises on this location (on the specified date)"; - } else if (cosH < -1) { - return "the sun never sets on this location (on the specified date)"; - } else { - var H = this.rising ? 360 - this.acos(cosH) : this.acos(cosH); - H /= 15; - var RA = this.rightAscension(); - var t = this.approximateTime(); - var T = H + RA - (0.06571 * t) - 6.622; - return T; - } - }, - - hoursRange: function( h ) { - return (h+24) % 24; - }, - - UTCTime: function() { - var T = this.localMeanTime(); - var UT = T - this.lngHour; - return this.hoursRange( UT ); - //if ( UT < 0 ) UT += 24; - //return UT % 24; - }, - - sunriseUtcHours: function() { - this.rising = true; - return this.UTCTime(); - }, - - sunsetUtcHours: function() { - this.rising = false; - return this.UTCTime(); - }, - - sunriseLocalHours: function(gmt) { - return this.hoursRange( gmt + this.sunriseUtcHours() ); - }, - - sunsetLocalHours: function(gmt) { - return this.hoursRange( gmt + this.sunsetUtcHours() ); - }, - - // utcCurrentHours is the time that you would like to test for daylight, in hours, at UTC - // For example, to test if it's daylight in Tokyo (GMT+9) at 10:30am, pass in - // utcCurrentHours=1.5, which corresponds to 1:30am UTC. - isDaylight: function( utcCurrentHours ) { - var sunriseHours = this.sunriseUtcHours(), - sunsetHours = this.sunsetUtcHours(); - - if ( sunsetHours < sunriseHours ) { - // Either the sunrise or sunset time is for tomorrow - if ( utcCurrentHours > sunriseHours ) { - return true; - } else if ( utcCurrentHours < sunsetHours ) { - return true; - } else { - return false; - } - } - - if ( utcCurrentHours >= sunriseHours ) { - return utcCurrentHours < sunsetHours; - } - - return false; - } -}; - -function SunriseSunsetTest() { - var testcases = { - 'Los Angeles': { - 'lat': 34.05, 'lon': -118.23333333, - 'tests': [ - { 'year': 2011, 'month': 1, 'day': 22, 'utcHours': 19.6666666, 'isDaylight': true } - ] - }, - 'Berlin': { - 'lat': 52.5, 'lon': 13.366666667, - 'tests': [ - { 'year': 2011, 'month': 1, 'day': 25, 'utcHours': 1.25, 'isDaylight': false }, - { 'year': 2011, 'month': 2, 'day': 22, 'utcHours': 2.5, 'isDaylight': false } - ] - }, - 'Tokyo': { - 'lat': 35+40/60, 'lon': 139+45/60, - 'tests': [ - { 'year': 2011, 'month': 1, 'day': 23, 'utcHours': 1.5, 'isDaylight': true }, - { 'year': 2011, 'month': 1, 'day': 23, 'utcHours': 22.5, 'isDaylight': true } - ] - }, - 'Seoul': { - 'lat': 37.55, 'lon': 126.966666667, - 'tests': [ - { 'year': 2011, 'month': 4, 'day': 10, 'utcHours': 15+30/60, 'isDaylight': false } - ] - }, - 'New Delhi': { - 'lat': 35+40/60, 'lon': 139+45/60, - 'tests': [ - ] - }, - 'Sydney': { - 'lat': -(33+55/60), 'lon': 151+17/60, - 'tests': [ - { 'year': 2011, 'month': 5, 'day': 1, 'utcHours': 17+53/60, 'isDaylight': false } - ] - }, - 'Santiago': { - 'lat': -(33+26/60), 'lon': -(70+40/60), - 'tests': [ - { 'year': 2011, 'month': 5, 'day': 1, 'utcHours': 17+54/60, 'isDaylight': true } - ] - } - }; - - var tests_run = 0; - var tests_failed = 0; - - for ( var city_name in testcases ) { - var city = testcases[ city_name ]; - for ( var i=0; iptU9dsW_WV@Zmdf7bHFN9AN*j}qfL?eo(ko!2)Fp7p=t((2uKd&gGwh~EF= zc%^it=Ow33^tD^s`>W$4xys4IVZ_wKpQEYw)US5kzEp6y>XGl0yZ!+a6@9{IK_HEjSZ3y@LdsBx2ag=mRIc^sW0g{V*d6~~`&-ui zmrnId96F7jPu%8X?iDn8?G*SPZRfueaV-${+WvbXYd3T7g7%IfljqZ?6%);V4HNZl zg>4(Uy}$dCN4Dm>s`!s~2Boz8rQBEFoJ*ab|8#Cyst>sEcl+I&)Xpniq3nOoK_$hk zze$-<9v^5$s2(W1U#K`1E3K{_Z)jl8p5Jr(D4ENw*_Q(zIb4NKV8I~_L*?PKqM(ni zxBbBc;o5IZH9cBx4I$X7$*yP{=XG>?Rd29-E&otz#5ySOPq_sv3Wq|d(qW7&=*zYj zRent!>^{2&r%wIv*G5mZ3$zs{y;q9s=MIALhz)}cKB_WSxy;HGhgW2W$_DQK{U+cpAlY#Q^Av|G~d%%F$YCbWJ02DtcN!1 zGt>Gp=GQ0}zrAHtyhz+Gpv7>pGehrB^haOOG-~^l6%kIMQ_G{4FzRGNI*B;3wZY) z<(r|;9t^9?uly*EA!n7RdHkbDKu(ag`k_zXTFtamB&57pLnD=T$V1ivSzX2DPAf~Y zR$XN)RB1cNBnx}FbvPeK|F=e%1mhxQw!EUbk&q(cU4vVy0tI(zCdB;A&mJDkVdByH z@ZwvpGPPA(C}C$Tqu7wjo0ikxM6?kGDPV*A_YXn=iq_60@;dwC6Zh{P9EKF@u2wy*PU+!tVkM3 zPk0c>H<@cU{f>79!b#~L8ohKUMif~qC2`vrU3~qTDIIb%=BOizvJ-@Lm3qr;IDJ_~ zaPlZRKPIP*>GS1{JYd&4mSW-Ib&i?2hV;p*J$MIZPc{9xc5-ys%hol2=+rRDr#2XWVt?XUoGqCF@J> z$WYm;d~>(ke#g(UACH!VufDCjd2d}NUrqB(M;|Lg^ApTij|?=Qu$DL`gyrtT82Wo9 zFFlVJ(#1SVf_b?2twIgy?%HMQmV~y)OWYrpUG7d`-M@P+T(|5A;zW0q+hyxBzM{h$ zlH7%XG^5FYi!&t{Lu1|TZlxtva*k}dH|Aa9VTw0g=1+}@;)O4QacP)#XNq$ya}(t4 zo~@2)ID3EkgvoVl4=1e_jOrO*mz?+^@(Aw7V=^ImBIw=|F?VJ4k%MKbCWzJ@PL-!W zd%_$OAcP&fK@~%L9vy2tG`mX`L;P&N=0R4f8F^UlJS|xqTwaJtXR#_T z6meWo@Nuu(3g#2fUgehX*}pp#aN*aG@_kKwyPLK1acR@*4-dv_&D$SMH#afU3tHTH zd!y>%>eT+K2w^;`3|6Mo5Hfs!vzu1fC6j$H|2Y+peMnsz9&}-Iw!K=Akc>Zy&qmn? zM2bpVt1!JMJ;{C(%nEhzgK7WI%n7D1xD-k~TQlwd^M+mt1MFs7;qI$m9mO&=)5P{H@=~X84uw$(%oUu2g-({3Sim@0ZCGEk)kJm5p;O@VEHpTtP z|Cl~>q7=-w3Vc#fskF>fSc?~K$?4}w;hK){guVi}j6b*{dbK)2g zB7aWtSYDNSI_-BrOJT>iK-k)ZGp3ASVkLk65-)P{bW1ZZ8CQ&0w`k00?sk0(=RvN7 z2Ct)^@fZzZJOqxB+LiFqzi5+fa9vatTMT|x-6rrYG&fu5ZVDR8_KpvKvpOV2b3fJm z<(zf?xz+g2TMitGNO;imr%CzSE~b7*zmrS1>{3KrKLoXmn`ADR^;M0mH;<2-vJfI( zjHr&VHAjpT>e0hp9=&e4IR8l_`Yez6#4U45CTE6@+)KujoB|ni7gjlgsOc;8yrGsM znf7o!RGCNIZF6SAAhT_|QV%omxU9IFJn$#4DbXq~f+;=NsO{Q4`{5f}@n1e5XIJH+ z39JyE5o;}%L&_^tOmpfS#Bh#rJVqr-@lk2mK)S@^=&fIVXkAm&8F*k!dNxvBITdSl@}xiK!9{4R2rMb?57aZ9WZQTd%r}EU!>q`7u zVi*jKf#R$(1nBQSS>5Picbr<`J4426!ZFZ+y>tZW+$ z%2+y>IA@!+>|chaN(j${vIpM#FuRTKMm2sRPL&7YXI8W~umS+3{CHKYdU{{ z9cON(m@XK1I(f2AlYy8&m{As`Ubgo2eMna!OY#flCPCBKzNE5GL*$m~Mkp-7LEu{q?VWIKN0vY;GXTj1 zNAFE}wrduaZ6)2%fG(Qf6C0u{i${H-4D@%Gnu<4PBg+AWO;HM!#H~ZLaF>Z55~Pj? zpF>NB1=m=M-he@-2H(T0BYj%*%Pnynvpyeu`>1wZSezkYN37#?wH1f$CeA9`bpmR& zLLU-MDXo)(je8ZggC*D5#MN)^Q^Iuu&9mv7GZr%frp^c0?V`sXTh*_rzP-(UgJ`T< z|APvxt6*E&Dxnx@*B{K|wjVgugD5@5{EXMkvf(+kd*Kth>S~tnGOj*{1W_l~$yCz) zx;^k@;aEs2@%TxKM{*Z(@0SZM%bDdg zeBTtn*LnD>1g2YE%~t}Lbb};GzJGY|9m;0a`J!`uvH@2jt?LAdcmXk}v`eV=y2@)j zh6(MmydL!7LF%#(jBAd` zD~e^#GhME*?x8qCn0pjW;;qMgFxmhRXU$2{VnUY9v;!k^w$*iAi-Q*snkA>M+hGJy z4wgukVV-n*VUA|GLru(WkM&>2J^(+;>xYwgJZ=ok<#llSbEehelMV^JkcyNY9?{jA&MM?bI@dTHVedltJ*#VaUnNVsQXG+#*Og~r z-UsW&<5PYIlR+5{vm|hKht55YnXR^&iPl(8!`&ewb3-+1OnH>Q9TU#x^>1lHX_9{R z^;@0vP208Jdjr0EiqA=N`JMGS5|cfjANj?y_SdDR&=PVwx>;XAaNLPTF~&qSHOB32c~y z;t4CmV(-3*Cpv#UpzCDMBn#*VLy);n&zR?pw`8-+CobKe2z5SX6Fi^+PCSj_gczLe&uO(?RA}H)Qi~?eMW*4N4_9@ zm+xUKOs@-OiNa}?dDxEe1H3+&Ux!cq^({sPi*OG6Z~Ic9A0VqFpa+gOOHhdV>#Z~< z?;Xo1tAd)eG*+u#|K*8)?X|t|_N@QjwDn6;1tpR%N)_+|pe=~4r>bN~HYNHZarSuL zxI*h8WE?oeu-mq=egq$;11?OW&g7%MKTk{+5)3#$b*Rv@PA6$e!h=2WL9-CY>ryZ{ zACpO)#;=t$oY&CZ($0&gu*hQDOi7%adUBHMY7S`N4?^S@#hpL>Ni;)A!ef6a$(d}X z8ol0HXN+kdZG`+ViY{fP)Cm;lNDXZ^tg_en@YAVbEyeljMHf-dgH$2=v*W$3JxABO z;7T~;s4sVWtn)g^QLXrMru=&7-8Gfl$tatI_;0?H8iC>lA5`9MRcHxL_TOvY;&yD+ zbXy%OUrzT~*GTl`$fS=YcnOFNK~OX`U%?ed(LA6Ba7R_HK2d)o`=iL<6`5y955Z#9DD7WZM)G<%S8wA*xQ0jX)U10K|q&fTQ6o?5Rv6oEg4Z z=4!jTh_^<%EKAm-$8eDk&MX2-Y&b)D%`@+}@1Kx-UO)dWb+Yg) z>UzbdO@{sNM6}r1*^e0Su70%C*AsmFgMpjCtZ-%9$9L5RU8lAhst^zNQ8g2i=lKSRG@Z_Mzh7q(aHq0StrjJ!UkTs4 zB7N^FE@$T_$Rl>Mg@DcbfNtN#Zzgh20Lx_xH{T1U)*I*Cj(U-=)A)jCPk2s{(;L@7 zX&~W2uwwp!SI0K>QhGAI$Ty2*=_~7TQs=@p`Xa7>wAZ2Edqwo!BPwK~Z9c5}91_l$ zCb@8MQB$a)*;74}YKK0a-tyUBRSFIZZ@EL>4Bbx@v>*PP2orL=nQY21+qd&n8j%+= zraR|I;Ny=(Nv&t8!)Z)iMfo@e8ShT5O6%kn%TWDv}Qh_VK$k$zEZ zn~6pKxucLl;mi}C%C7l`n^57Y#J+Qfk=O4ez0)gPA|eJBWYGpi??QA)jFSw|NCp@i zN&R$_w&gQjm(;k?U>d^;fum5ETrsQFsdM9tJLxdA|Bl3 z)nLpKRETA$V^@ESyEGV(WBUAI%WAE=I2_@b_+Sm_C+&c*Pp3rrDvEAt20`(Li)*Ir z2{@~zvFZ#C<>B6_ncLxk_ug_o*r+^k51t+_O-~>cBndbxHqp6ci?`}RFXYpI4=X;7 zKh2ekqUikkUKW?%V@sU^i9=BqfvI;}AsLT&_<~MwIR#%pPtfTXO)OrvV;bSOJ_eRf znT*1%YmuN*%zcE`$B}hUSaArs32x1XAcS@s>KEw?Sb=lL#K$R37t@=>BO6Hq_x$1d zm9X4Fu8VhvkL_c`U`%l2;spkm?8a(bAUO|HMYhP_a|=DN2AbrDbJ2X2P4j(xE!u9& zn5AA<>DRJ7cY^QMG5&@x=1Ny>_IEC;?kZU>9?H!b9ZlNAk}7Rq%dB|VUtm3+hg8Q> zLhO#o$1>zos@*cFAO5(BsVX-zv2@CP85lEGY|6@TM(B}RegidABIfhujeueWtg?fk z@Jh#S1T*p8uR7P)1M||@*D+7Rlv%V7f6VYN@EG$^)=jQ21_B04q8!K32}$?W!qKO_ zPs%^E1!Gdbe^krhXpbNxdp@fsb(T}0Q+RE-PCN>`sg2};T~rm+GArbE(%ba_?INrD zOf;=HoaKrL;{$q#vMvA;pf!~ED)y=iq%q;w7{Ii3K0WM55HT5$X1F>iXt~{d4MXz~ zRts4HEr;Zkn#Y6sL=imRTgfPF6>)A-8nT)6qQgm(?6y z)9_U!$SJ#o4pWV^=>`GOY1Qew53P2678(f3&E;BD!}%Ww&8vF~pE+4xfG3t=3EUmG z>Wb}Wj=|)mi{*5(xIDcXdi$u>=V0CA3f;gGWwIPFIO? za`rWwT;eWTXGxHH)gR2w#nscpFn;ecs$wue-qr!)+{i@L;}di?tK;LbKjH6gqT+vA z%>yKzDAS|naEDJw0UO2S%w<5yVE38ijgo+oTQI(r?Z_93{{nSLgvsP=Ms^qXMuTi6 z90L(zZ9Z9V7_){8zGl_oSEWMoDUHo9cdLgxJj_?T?U zLfYP&H$WYb1{K!dq|Mn~R;6-Q#&Xy5=I-J^lP9-;03eMIqmz}6-2jRHF9L@m#pIS* z^Dhm^IPK-zhd`iB?m)GBY{JISI6$5u>F3SPH~h5?V=5tS?<7`YqerjmI?p&#^?0;_ zoVv3qQouyedCIs)^;sI7CdKy^bn?=W$T$I}q%?93o2SKsfZSLhA48X)>Qt}jx6^-5 z>1mYlorMaUKJM}SbfdptWeRYIg4FfRYv`lO+pLk@=1>Ar*Gae0eBdV( zlF;7vMPA%O>|Zgg4b;-s-;mhqpxn#wUgjb;(KU1nliLGprwxSA8g9Lkcey*B2%v2d z3Ws6FKiMYbOzL_*8A#^K$aRvgVlOCKWpT;$j;iPGBjhgPfd2Lw=l|=mXA#9u#)1RH zC}9qW&NaX{$3HDf(*7C!#$aEmqrX{CM>?6o*Pw70XKMocurq8>b(^~V&NHLqB(W5~ z=xUXN0oZhtJp*lr8`1PxaW^U;BCI>Wvw= zkGjevYV{^KW0sVd&gJdjee{-;kJ#9*$%n{SYU@Y3399}Yy&;~pRlJh|ZY!V$3HKO( z7IPm%ldln#M0Jbm$78UWPG|c+ox4txyMb{AE>#IfYDTQ4_3`+~BAz|*&p9C{rP5t; z7_V@g0=QDMCy||1!qhYl8=Z5{G0lD_uW}k|*_>L@s4AYskmyb#>t`3|XFROJEC5ho zFK7n?BrzA5Qi&E@bD!ZzVZq8DP%*I~o_MkCg`Q6^iaVg#2JO9409gq9f+t%b>P7c; z7J5qhUL5i}c?v_3v5%Wvv23Nz)pid=$hI!X0pJfj0RtQ(Dj7_MQ~=X0(xeoD4vt$H zOo~*x)CuuwS+*;qrFtNp=ztvgL!cPpn0#66&`5sh&f=in!K6nWnAW2RSrUT;4qeJi%jmP2m9zX$d;VaZFzRh;GoEdkd%6)AD|Ge|kZeW{v z8wiUNH1%F$XXWBj988`2X5V;zyb|tdp8M`=laGh*zHVdp$dJg>1!14VO^Y}=IS*U( zzBH+lU`}ExnxUk+0Goh{~N_xWo{Af{E^|!#~nbU)1Mgalduh;j60B+2a z`A!2m)<4Eyn#!Arwi=E%YE|%z3bDe!1vD?A5+ddaKfx#%RX^{jDNDC?`9Opp-d1t*+<1Uvj)O{%!&!049N2bFIT`%B+B z`?)Hl?gI*?abdEXsGGX*Ds}S(cE&*j~m&D+#T5E<_Ki10(VwXFxSL(cr!I*Cz`V zjH(^RBV!F4^&hM~H+?>)vw9VY$5y6yQex6DF;Wv*<+}S2OpfBq-A8ef$9DW5Bc5IP^YF{Jp~%IW1*Bn(R^aXuKup)1oj0X-`!znIg0%vL zmw7B~(Z~<*FMzJ~zrCX{Qfg*4QlP^#=hyY?g@_^VyB}Zat({jXkmKz5exv%8e)_*3 zmWZoJTkeT7T|yOf7H8_)giXb>MX8G@I>eW6Zwhm9s~3pNl>>L<7dVb)_ns|uC*-vf z?zicN2J@KYR6KPkJDc$Wi@v2`zBrJ!j8%-fjU<81$iBprC4?5pVI|k`UqX?IiCRQJ zq|YbQ=SGW!9L6$xUvXsvXnsxOUX{8uW|2wNjsL?58JQ-IK@fS70Z`!2G}!+r zdV37`#R%XEIwAO^ERuG1YQWhn<<>3AGxa~R39F-Xtsahd{rHm^WvJX8r%6$2+B%}s z=9dSgu16kY91l|R>RcBK3iV3m84NS2i!^he4}4qi?;}!HzdAn7WcOVha2_NMA{jK?Yb!- zL`))hak?l)^>kn9FM_?{wp+yeg9cyP*`+jtFZV)#gzveEe4Ty+Z9aIJtDE6(+Hj?S z4pwaTfmH{@doG|ixmD7MT5`_*ozddQ@sej3AACpOof+pGFRY37z=i&nqO&|?#mSzD z%EM@7%gWK$c;2hT<5L`k-LdJlMixc+B-9Wv`lDWFC9DdSg4jcZz!0x=IGiOi%-5r| z4azOUzSX-uW{f8nsBO$8zjrcEbd`RnvyFsVDN_%SD!nGtCU419E|dDoeVq=7uu2g?Zc2cTyv%$Ua{x~RD?{%zhM4_gv zc=J{mRZk!eZsh??ml^0egpa4kg+a+)rEoFxLOJ45>E;mW(!u9}Yjb^RB)o-m5`@hi z**pDF+SeybaYrZT(-Z3zl;*q}V*j2Gg=%yXvABi3QZ zNR49PBx^}{qt(%8_>_pX~r7RQXKf-lht9}O688f zm=x#L`EeISumuVQO((?E@8v%sIb&E-O-Q^zX^@0S+s3c>TKR2lY07RwvOjaP>AXb7*4Nw`L%%0A>DPe|d z*k{9jA{VIc_u1#gC6IfA%Cx^($X#@GFKJ;%9jza{YS^E8PjA%3!-Qde;p^pfnhBAg z@t`PPqiU54k`DU5Wg@owej_!`W@$*%w)8^4CRe7rV(34{O9H3l@==apKT1prcNmg* z^i&sZWd`<>O}!O?H1&2$-?8XL+cJ@L0sKWZqv*5R4-eR!WS)NDYdO{AbgbX|VYJta z73)O#ME?VkyM)O5c)B#`H}|YMN!U-0p7lQYG75TZ9w@p+r?Ujqhk9jjv{dhmy7EBT zvhO}sA7cHZ(Cq4rH(m^An%HC=Ac}>+oH%X}!WK$wy?_MSX87s0EP!q#ylK5yR=byM zVk;U;x)%A#er|)$A&=CXy!Y;d_LwLPzt<)0MB+3M8aH}s*bKZIfBFe%Lh4z6WF)6P zH>*}y;y$_|cJ-Fo8-m135Gx#wLbl;bc=R8Up2f6*i+#_O#tm58bj98p;2`Fil$|rW zp|kulqJ_bXi!wGdJ=!~MSKI#KL&OHm{8>cu8mJk>z4}e{W5-58mEmkzn~?`U!{#ry z|AI46WV(vz(OPu06pqXZ!3H<>%4if+cNN*Jtq))GG5+Q8>FDY715^paZS0nJNZ=%k zZ5YtnG38T>la7rN<>(%5|K<{(I~SUTfG!m@@)pib1|;snOT($dLkeUT^f9XBUnmkP zVc2nlDUiRpP!zi*vt`(yM!{>XQB=FaLt-}g5FBZV3SeZ`GFAjQ5*eBdMW!3~r+?YB?p)54uE{M}-JYlEkPz}Td^ z@e&B@7DgWnUG>(q7`Z*^0p!_|T(uVevuCdhntTotIW8}OdPjjmd*X~4XT;)RwkvrEk{h? zX{h+eKnL_mt<|U2*KX&i#kY94UVM288LxJpZr;8heJ$pWF~gOAtED&tPA50OVcdS+ z0n+11KnO_&Uw#Q6E{q?BvMCR|6H!wPYL5PQZUbR=aRh84ztqK#Fe=!8(=vR0=PFa9 z1@`R%VI|BniKIQvFm%$w!edEJnahC2p-|@?-;^Tb(Nk=KDhf%Ibw^)rM<7fE%ByyB zng`K|nIi>05O$wa0w3c&eV|fwmj_W$<~fhuP6%NR$IOtbmr2mVE5!Q!4&vyAe|JOA z&_PSSuIDbqamDJc^TaO<U+OB}CRLKbx?dx75@Lb%+zU3pdd z2{rQm{jmH0#U9&CLg3?sgsg)4hj?w9?2V8A-Jy|uvkJ=9PX%{o_;*ofm@!ZMtNzf+ zpiR?%EUQcoQ`L>uuz1^g^%Giz@3SVWc;w~lA-CYjV7_4P-flPb`>uGJubA|sJnp!3 zU|$mf$1$+OBvGHBo;8zc1-_bNibwHp>tCKy6==!laQE^485x(11xe>%2kmb4um$Fp zv;EZLlZ}?WF2MZMmxjE0C6eAiMC`G@6X^j>q*huR|D>>p2Az#{DH1-_qCWdYqAoLm zptW%4HthwzD_$a{=5L@QE(6!rerYJz9(3OoD8w-p09qu>HEh$OBP_+%p?+D zyy+uKAiTc&YL1*{JN>%oGc?w4J+=kdSvy-kh610LKnc6oTPo&2%<|3+^3(%ern=zR z49Rq89gVh}=bHL%eP-SshiC<=Bn{~*iQkzU`?nu5Z2X`(2c+v#!XcG=T46~U8lJK_ zz27f06b`&rTVK?nfeZDt?)(j;eG!5EI1m=hK9fi_fk>=?zK0NA;~cz9ksTmXsqlW` zp$ClXDmBvnAKQ%-E^oyuiHPN&g$vB~|4X>$QGq_flzC-D>V7s+^#7EcP|iRXjtU}a z;g|0a$ZfHmOwLmiX$W>}%@YEZA1(w#dgA(7Rc}!9nQDW#bd}K?Bls6Vd@vQUNFT}g zyw*0MW6<*V(cxtT%IA3L;|S=(&HBM<`Ud;V@6hHzC$R^T$TDbf9T6x%eBw4_UxqGJ zjhcS9&_K!oEvjgu#<}#iO>fTm*+xL2&w8B#^9!QOipVA!1fYrrSSPivy!xF1vCE!b zAac6>O#n%PhubsD9`|TA;`%UXfECB{)PHR%SH3@L{(w^)8EgRL4O*Zkb{0l{mN~hzx|<+K{j&P zcOU=w62C%UaaGy%2x!ps6qVm@m^OOet?zt{t%8BsaNmowgHBMzzVAK)pxm2@%6TGk zPj4t-CWSN$=+}H(fd7^e-kT&>#TWcPZnDkDLEp5q)@2M%67z7MpuXae(2W;2 zdKpP$GP^7Kqo!$3uG(ILm~$2dgK`YU9hV z|Ek+tOuY3?(+8v@8D=O@lB zYtQ4id;(4yF0}lngzR|`=-!5nW}}vG7GYbzTn8ToJfyj0af0BxIZ|wN@0L1i{?F)e z*rH&XG)DXF@p4R()jI*YeHJD{%tPb%GI&k4S6VW}JX9MtEcb%YOys;5S{BUIqOTX- zM-~>W`{psRuAWV(0}{sc+6XR#Cx0cF`OULlaqILx^%0K;rxwCT9e`)A2R8Luke;d6 zeIJ6tv|FRGwq2+8y}{ zIXAqga~*_k?WFhegd8VsI1II^n#ra5&P8!vm3fP*Nfxl`L~qYjVKXh}2@Fxs_&yEv z?0G(zj%5(ZItW6!0srU0TIkgts7)T3Z6oP3C_bHI)?+4?QUK#-cvgRP3mw{xY!=qdD^+XDBg~&&m$#Vv$$(9#1 zXpqxKXT#7P^8Li1ml)hQR0VStSr)_)#)S3GFN;7C!sVdt>4GGJCuHVQo~Y z;;&;sce|SPo28tRJ5(WE-0K;VPi_#XlbK;oTZn&U=_4fy*{Nsdr^C$4{Kx0Z9=06s zNcdml(N&=Wo(i^GD27Hr=0VEc{L~kZg1Jy^lhQ9Yu#C<$;LMFNlbAD;{4}<=yH>RY zZ%hh%O<>rTTXj_;MLah%&!g}@2jLQ6>whK0pvs;~6Ui%thhEamRXPj)4f5qboaf0J zm=pC+qx~s?UEevze}Ho)Ca~{YZ#L0m zDLrK4lYg<&NbXXM5-%vT!=3f}@28RiOR2h@)^TUk{(WHXhG)5sD-bu$7gX_l;mg~X zuzy$sjSPd#v0uBXk8sk@?U$=rl=-B_FRuc~NHJgYHD!7h*qt(Bs)1-9i34iq<^iaHtTq2t0>*rX1 zZsM(ffgc~Jhy$EBFRkydwTeJ^;GT(i^RVL z0|5PPd}n(v;0Nn{SAtb^uuU1IP5UYK-?GB6xh*pJUyyggeK%VP3P1;I0T5#Bfr4lc zXyP(}fJ_RrJ?BBVT0c>nHTWPUo7{C<)=o3_1Fbmrz_YXOPZ7jUsEB^H0F9nl7f%O# z;uiZ0C{H4tU&|Y?Fe82p#%tF6?siM5QH|>0PGp3Bz9zdwOKKJHmkRt&_U!>o5REAo z69l|Z8O$&Zvf8~~71ahUlOaxdz;rAC3S9jba45zk6ctq6Ob4_owm^Z7Ys?PSy=LA)|(Q^lYG;Fq6;m2_uoqLz>F(U%H)NB({xnGyzaur zHR>Iue%(`c`8N;A;OBpPBAw=hpB`?`o`QD4NLO(NrhoV3gq9%I6@K4|1I9fOvE!`| zbkX;yu-{_i#W7pvQQu-mRX4ogj8cwc#cC8mFpil-oY7DhkFHr)JQ+ zk7>tdCg2+NpM7c~BtvYogY}^xLQJ7Ax5g7@?AkI&8U*A6q%L~SQt`AS&5A>3WY zajyQ~_xzwvv&!ZdwX2Wibajz-7-#*LfEjSZCcS6FsGn_f{S)$VY!QcDQs?i#$Hg&8 z81`6VY(M^LOFq2HWY_T=()wf?E!uvUIxN?Jwk-_XTUh`+jpe$<^zW}v0ILxTq4T*c zL2Q}$WK2c)R~YiN#&m%cFp{sOKzd!$7}PF4(lkKlKaeTYLyGgtzUrrgaAg$tKlOYK z&PhJt+K-q801`kq6Iiv_!g{zuO0d;qz+R;d- z(oQ3ZQ!Sks$jf2J%e5^Q`cz0e+kMcbGwuNBo8j|WO9Wl5@P886DtX`%&e7m|i?&}^ zbo4+eC_Anl?X`oFBjW(&Kc5Hoq|u|~%XkE84^0rZBaKVz!?Oe@waTGA6b${Gjz{@g zhk^CKBpOK#rRFt;qy5637zt+0kIiRM8$lWf{=1nkIp$Za2$O5mNCF-U>g$KR-XU)* zgC?3dEVTk5#DO#Vi|H%udL$8X_6NGYx6=|nm%gYpC0yQ*Dvv1Iz9_SWDg9E~8DK}e zIOe9o$r{nO%=O?U+`rTu(MTj#0!8jo@gnkwh!?E~7`EyqSL3VMYtu#UmiJF|^-j0!%W z%xl_s_yf!h2_py^NUl#fE1gN?$>q2!i1;BB@_m;rgTUaK9 z0F*!=nSfQCKhzu#KENnu(FTh!NB<=4@H_(J7drEuG35=KKm;@(@MjQtniJedce!YC ziI8oFOwmW@Px@!ALVhD&kWV(gwu)H-lDQUW6IUm`c2k|=zP=8a9|X3w8UeAG-*IID zFgT6@dDa2rm?6JAcd#LYxs9VT45-}qF10jK9fIr_cf!w}PWuwCs3O7TE{;cADmU{? z8mf;0o^{JAbZ$P9U;9<3g;iM{$I7HZ0q2^SzFvxT>maarSKO%m4xbT?Y*KI$;Ofw4 z1D9B~PrYML519W0+gq(n@DVDa3TNi#CIf^wlVYhlP;KcQcEm5$ft!?`r(0bkpoPZm zINIf!1HN1=S>8tR)zM!Py}jjAv4l2w!9rC6lV*XR_f|#=L9e_0$T#4YU8P6~{S>L3 z;$$lRdB~Up+i>j+n(s(#smFw{IqybZiFuws=%&>HX}(#JX`|^N9SnrE zG@6pRy5Hz@{WJ@P1tw@?2R`t|2giqlvLYKyfrY7fHPcu%%my@46(O1P)W0M}o_toZ zuw|nB5nJ{Iq|Z=x^MaD)AH{{(-o!FjJJ4KRz1G$l%%C_7r;p68xy+Ql!n|)kJRmoh2b_P; z_z+AO(!ZhB;McPncuhBT&x^RNU3{TVHBFQ@Rmkx+F!L>+txb#|WZmSDUJY>bN#J!I z6Z4ogH?C8MDu95B0dAXEf#3XRfJx>6D9;i&h*aXT$xOJ0{1YZH9kn)&b)~T$Fs^IW z?pi>ndBoM)U8aZ}3E#sq)^(C1{<32XJ){|}T^>aE#RW6goU3v|z13_m%9 zvbYV30mB{S#iqHy4v(6aOy>`V%BL0cJ9`n?psyy94o9tk=hK~Ura|WC?F_eEvmKp} z+>24jcd=;6Nv>~KoP%RR?mYbRmA7%D`J_ZC`15b z0<#u>Y;G1k{yg_Nx-=haTCRTuHt_EB6JIvsKjK&ymDOt!Rg!eGd0>K)$M84s%9IWK zJXdgEEbG6=C^R75tTkn^!pk<>6<=BNG2$0dk7cN0Z@U6oRWgX{& z64R#o0*!2Wxy~SD1(<4m%SzpFkA<3KmPHV`l=Yk2XLCk+4JSwfnJ!)es9*Lpf{2=z zfopbfO{yJS zifoLO+5xgeA(npkbTaLAP^#S^=Y38~CF^;ACLgR@H6>Q5mh%eN#-A8QmOA1%rmRh7g%z3E(Er!A$fS(8V65 z<%DW!0Enq2=Dzy1+!73@&mZ_QU1ofDiug@crM4Shl?^hVg3lhm$u_KZ$Ui7=HR2hb zGxYPNS1u%T{gQis+vLjUYb@)v;V_u8!F}_9E>HvEb@hseOd%7+UiUm`#PuRdjABr7D-f*hHI<(Sq>Z}0#8){YQU^8H1~fQP*u zOcBB*0LJS-1Zp2`l^vtY!vI2`FRGz2*o;hkAjsu1!%nrPzA5cLC?11_$89nwnRuGS z5q|c1Pfg84FixLdZ(c&RMw<1xvuKUA>iBV)TxZk6cW~ArEQ4&-00xEC@$QmE(4hP! zV`YLffF2jmg#-o7KMx#q4nb>pDXrnb`sCJ;k^30(-H^PyhBBix$IZWgunkSP6j!~Q zK=<2dsn43foEX_Ton9s-YFyaYdhs;vH&O>12{J( zI|5rDQXpow30X?8=dr0$o}1?ErugT_J%j(KmnQieaj%NR$||CxQGt&v0~vW`Ov&w? z_o2FMcyOUxC5eVj(joXtjfJl~spKqQG~!=w&@CLcUZ2G@k7p9#Fp1LsUDGVTU|nTT zgu+7Vu(QWz!EgAo>WNNfJTIXQ8V3EkiZqOXy>z@WZ$gtV5W({*s^*+8sfkHz+MB0j zRV?AS#FG&l+?#0gu`&w;lbO7xXC`ZcY0ykcF8if$vCw;eS zj46_*wuioyAX119htZ{|udODxzmls-9$913eiLG`2MRh$;klguF}}cEE+9}uxYIkE_Ua;(0OTa0y zz0ADWX$b}~ca`!bgph0L8WlR&XN{zUf{~eItff1WF5$EOlG%^3-@+#H&u5d-DL-(UvoxJwvT0uV zd!^y>{Rh}L+lcv)_Yc^XX5;M+Zl?$#4$2R%gTvn%MvVIjm)Uj`B<}3~_|Z#>6i8^! zF5tau=eD=3)3>N}O#IGOTh()FThT)ND;IR(O~*Ii3NS&hw0&Vn$BSW=mPq{e=`u?e zkz6z1 zu;5-v_oh9Vd&Kf%A#-y|?8YGspnwJFD8Ig`0m!drqPALphSanz0m97#cmwJt5278^ zn#}qM!P`vTN^}TyOnmurNAbb;6|9Ia_-IIO5=_(DgXIu?CU6NRJGgOrCg0Nu+ULZ~ zCEidfmCH0}ou2Fi`Lj4Z;QXj*`yS1}pqNdg>Smi#f0h%#P}I@L9v9%&EDvU~`mR-t z4ukQwVerIMF>9)Ieq&@{HyYq5PgD$_kJu|~TJ48Ls8cgdGa8DU0`~OyO)=jd@gR0x zGdkQ9Tfj^fK4@ghllklM7mk-6yx|JY>)LVi*rlB)91hVm#!j>=Ra6%Yq>1t5)neOw z)>|(8tDeluhw@+Fcr#EhI@du3uMgKZ=wn;bc7tE(Va__=iVMiwT}rdAcru~abB;}( z#5m+M%j32g*k%rXD ze-Vz1u=fZ@PX4)Yo11xes?@RrJg>n@=V?=B8`jGeWFx}P<#5Y!C)br`XoV3p6LU_W zer+V|B_bsaUMTmJg_K=J0t*5W$Fm3YaX%g_zs{a{w|WRp!^UW-+4KkCRUd)jAtBCB z*3(#Ej%>T7m08(_K42YeSm-HU`9F@t5(IiE ztTKL1XVn*Qp8fpWAz6RW(*r`l--+A@olJ1uR~_^|bT6rlU#e;FH;{cFWN$b;j?+@w z(>$;o@UGFf6wB7|&~88&aL=Fqt2n|*5Fur&4Qv%l_<1U&x@NoV|2denqiHZ2GzNP# zI8<`Q#B=VLRs`ty=J0n_Z5^m}PkGS`=k&E&tWBQsFZ;KGb7gL<+ zo^uTDkMT9JypP7YhZ$A8@t@JP%|YlvIsC@`&gisVnJ z7H(tP%$U8TnG&o<55=aUGP+WT`qF0I70b3q!R**q7*02s%2-ao{AG$7HT-d0&AH7F!p9nL;LoumyGC=+q>-u=DlcWLvrYEx(Dv z`2Mei^Khj4|G)UX*A=p_k&%6k>@Bk^d(Vp!nUQ2=TyEsbCa$edlI)e08KJTw85vi$ z5JL8r-^=&+58Ugz_x*Z3pXWTzDOfihI0U-%D5@uAL}ITxm7c7UhA{-7%l861)@*u1 zQcx7M#b9Owm}aW~*Ur{Dp!VPUfepWb6AT8@nd9Q~e-hHQ(l#&rpkdJdX#g@hdvA+G ziG35cV&^u|19qG5%sh~^x^@mbT7gp1L4&(Y)pi67CU6R4FIj`2**q<38E|{a??gov zbj5e4@tq874K-Gg+WE5Nyagfs?K zJg-$5US3Ixg~5npwj-%IS`7_bEY~8ew3v*f9)%Rw0-MtEQpF3}#~DQZ|8K_tHW*p^ zXxxxL(x;%{oyd7i9G+zxiSkP1jOr-`OXu>5`h@Ed81q-?Gc9_BDq9?u#4od+c2YP% z*cJn~@^^T+Qz?&uqGUrvQVL@b?<4)f-?LJY?h$0Xa-#ZbY|0HtCGF- z38|UQ`w87R_$8Q&mc2BZ5fa=6)b^~IfbJ&3dOXWOG7yifW*BDO9J0E5-~EDt;Lu1~ z+xzC$MJK>5)E5f+lE(2%HC)s}Ga(ccnAIMY8nbP!_ItP%6xat~aJ4u7fP3{g;--^GBptC3Ft_Ra^Q+HWJ_(X_cWWVN zt{vww-1gOQJBafYdkX?cKnH+pfz9()B%m{=OwDt(Ay1?{W=DYr7vkdDt9e+_9pv~ zxKjnQz(sI3nWH_&I`5$6?W=YVA5PE%SX7+o_Zbi-(g$J=aN?O?yhIJ*UB|n>^QPHs zZ+#-gJo%LtP16O)YmfG(FRL1|XUqun_)S1E6ja2PP8FLLT%F3`QbH_sPR&fnYu?40 z-XpKnUDIxp>jH5oH~Jf<9eCmBkVL;>sKe=C$kF-fVSs4^Ap_18`r8?7LtOyrb}hGQ z9y*3i|r53z{VUo+{1k+2RiGCU~B|eok%iyM? z@8HfB09_SeqdCaLu2-AranrFPoFtb|zEgFJK}qS#WZx7;Z}h4-v&LG4!V`Pudf5+4aM zw`#oAoyfsK=WF;z^b3gp+q^6V2G)|c%H~al*U_7Rz#V@Qb_a-!s zf4O0)$ddagmFdFw;w4ImukCZ=rnKa?&Qk?t%|p0ewfM>{RuICg-g8JDwru?K*&~HlkMS4qy(Q$Y_$#Q8wx1dyT5P148qrd2B5Q~n% zltJXL{N0ZQ+|r71tWcIAznqIpH$<~kZ?xC=pK83W)>b#|wj*@4Tpm7WD)w(ER#(7s!rT-7KMEw42AK7YD?N2tJ}pYt^*z5rA1G=A$S za@}5B{A(3K3+12B3YOzBTWg?>)l}L)Boo5|@XZJ=eU`mXLU>$I2vQPg z@!3rBk(?#4C6@OKJCHm&&J^Kc4b5}*c$F1p4*yE`_031+^--v2lq}MqZU^T1KGsIq zB5H{c!sEeu^m)cLKow;I*NDi-Z3z2Izu7q)wQcG+@RK9qWy0ggG!!eDK`@19QFia8 zP#8Vkap1-6b;Eah<)lBeGXzG8=U0{8XO%b*)22XP#wH^%znG1b_fw(!TyY=aNTM9B zD*+u}Y7 zCELG=z26YEC5UOvv9Pax1F`U}5>nOvr4h=z1E(QoJ;VTko6`GD!$%^Z0t}Z?9Vb+C zRVA8xIL=9LGQphl`TGDz3xDs(6rdnh;OvO3oi#@lX8eSKQ`fqob~R8VS#HLApuA zyNodQpX!Ozw15#-rzlIYQcce)qLli1b`5NkW=b>bKUraEl1ltbr);8Wwia16Y(_bS zdtUt9Nxg;yeD()$t61GK7T+|jLm+hD@V|;lP&ro?F-$?o$LYWS)G{?5=h*fyGwn9T**fHIq>E@lP8#@|ci zACOH6DbG@;Y3G#DHnKSkgXdmw+W+}W4cJYRdg>}oDsm&yVel*(Otdqj-YZFK!-%d> z47QLn2-4%N#VpvY3}UgHwDK22nXhFC-Uu%qyj}!^CpsrA|ET&Pm)NTcH>Qm}r$iT3pNlv{5SfmUQ8w#P|aZT%Tg{xjyxN#UBi1NB& z%f{wp!@zGf`!$@R?~2{({JiR0TJaYvU~ViNkJOh*Z~H4+o4w_p68h4a&f}x;qd=i5 zJ^P5nwAPW+Uyq09Fxu^}QORd6jhMrGY;qo1-7XFwd3e%Kjz!GTb|AomW)EBT+TSyu zqa;ZbUd$?zQafs+-o0u(yMV>n^qPH&ovD*lzb;h12V(SGq$9~D6=3Aqmcc6KJk#UvG~@+^HOL@EAA7ONe#}+1d;JwDDA4lYe9zW&{5z5d??ovjuh<8M{eES(TYbAj zVNyUN3k7c$wNuqX{P(ge?7pW+8MR=twZ!)n^j#%UE12=2YBa%Q&W3niL~w>~M_)-u zhMb=Y$O(_&RVn9`+Z_sVTVrntYB{E%I3_`1Mg%E8bn4ODLZ8V07(7ND0>WN9)|zi3 z8)RL!1Q6P4kb|V^+>j3xzwE`s;DW?(CnqkPHcfl*)h_`#o%Gic|44Au)y#N*D#K`` z9UX3X_) zv8th{W@X26eF`N$Z!)kT{J3n_GlF=85!rgaFEI7;YURO^(zbt*9i>NVPpp=3N+ecp zUH_!-jd`ygYm*KHS(^h8Nv-x1-@5yJ{0)DaknID&9yoKF*6DeTL=Q@R=>y6^K6egr z%wlr;#9&ZlkgC0On2?NRq{ajL(FMgk8-I-X1I zpUB%F-5z2E?eni=>#Bg$W{Ki_=t90)eFT%qU(LM3r?FNh~K1g@CrOM;HtI_F$f9>Qaa z1|xpPB67Ul0sMF&{*=cGOWpdVVK&6t#kWH*ZbYl#L3|I}_shh+dN}G%Q?DX|Z^;VG zSua3PL^20W#&?Y=Z9}*RLYe_yho78=a1B4#`#tP0ROlP(>Iv>1n*&yn=WtBDM25$Q zf0rBlH6}ceeMa9Q=sVpx)m_kKN+Q{Iq|CV8R9<+zKbhH2a`R589W}A+p9y9gX0G*j z>cU%9KUZ{Q&?DK-0Nc&g<#a|5=j+gI_y>X@V4|4>-!*+nf5v7W_+-ggwRLFpE)M5r zsd}*!!uFH-;dAZnn6Q>`u`5B&a^&pjS z+!c3z!@sN}|Dt|>$O8(4zR)35z|!c#sD9q5+NKvWpf_`E7nx!pc)i^UPA;Q#QE4Aq zVVK6`sZPHfZ{eK&PqglROAKQ+ICO%in*-jMH+s#dNNzv8W~Ad&pg#WC`Y*3dNhzBA zW$?xgP@y*Nk>`Ifl%0KE$*{KpDsk&&0w*6glz`QcFviXjbTHvE3N$A)C>2S4dT7~U zQLjDq85{d^P4oCjv?MwKJ3JOw1AZ8|M&8iWw;~0F<@#XxqD$t_IPRh#QYf_{Uc27x zW0GU!Ux^a8c((l(W{;yxSaB>S&i3-!J*XNMU}^}EA<+cWr#Gxn{8+orCDWlga1l;d98hPc)9CV4hQz(Q~6Np=Y6e zR*q3cXzRm9oe7oNHaB7_D;##Hocv&?QLnu};QeS}{S^*}SK$ZLqy~z5AXy?pW?wGJ zY1iz#nwuxp7ZBM){8#6rmfLbiOYr}2`yv|DSYv{*pN=x$ywIK#@5vKzL9jhs)>nU2 zr*^(DBOV_0Iw=Z7Q!#%Uu-}a1RJ{sCz3Mc$CDbV|jd`vF+RN%%!?ho#v~qw?yv>If zU1TJHGlLiMJHFJ^o~x2)-~Y~IdOE+D55E!=&4C6q;x}$n1PUQ40l@T__10IeO1rHL zcT9cl%dD(&z;{%1jOA=$i#2X5Nw&WXc($A zp80uV2sE)`{!7&4@`Q5(1p4M)lg|xIT+9ad3ajQwh#N5Bbh){O?u-hMiR2-*K+SND z)dqsadWqlkOAQ`HATo5R7TYEG@m;-XU)zwSa_`8op`_-1;&`VNjX; z{?EdOZTwED??bG#G$=D(c~zV){LYnTpJ^yj&SR>W_=?5tooAQfY{HEeS-ojdzdZAD z(S+Ru9-KBEs7sdiwjJQWE%=~_OVVt@c<+qdckb}VmteLR1pPW^u09#{0cOj}*RhIV zPVnkADb_j(jOa>R<&U$l)7v2B`>L=v7WPb05bLAQ1;ybwBaUvNP5y0ihp^Ma=s9UW zeTxg%hBRN}vZ|^@8IqmZYP#uotBUXnCFX<5iyIn^i-6wvS`qk8G?{JW1EYX3s_eyZ zQA2BhEECiR_z=X_-AO!JsZ2F~%Amly;^-WNRPS1~dqC0Y`6wkB;&A^%-; z1CwUX3cP2+xf`JxLTZ;$d&7K7s&YihbXPATfa%{Gqi}XWy;3|y8-U0+)Vksbot1yA%mPfR4Xxdrv$gKkQ zl%TtU=K9MQhhP6PNdC~p% z!4zY7V3PpDEwQF^kAEDuF4BY4*S>C1;ohZ$J|R8ha6h4t3z9OP1U2dq9SuYEiraQ! F{|9Z>UFiS- diff --git a/index.html b/index.html index 65b9b38..2b4313f 100644 --- a/index.html +++ b/index.html @@ -1,22 +1,527 @@ - + - Sunset Times - - + Sunset Times + + + - - - + + + + + + - -
-
- + +
+
+ Sunset Times
-
-
+ +
+
+
+

Sunset Clock

+
+
+ +
+
+
+
- - \ No newline at end of file + diff --git a/sunset-colors.json b/sunset-colors.json deleted file mode 100644 index 0c7eefa..0000000 --- a/sunset-colors.json +++ /dev/null @@ -1,103 +0,0 @@ -{"sunset_colors": [ - {"color":"#FFFFFE"}, - {"color":"#FFFFFD"}, - {"color":"#FFFFFB"}, - {"color":"#FFFFFB"}, - {"color":"#FFFFFB"}, - {"color":"#FFFEF9"}, - {"color":"#FFFEF8"}, - {"color":"#FFFFF7"}, - {"color":"#FFFFF5"}, - {"color":"#FFFFF4"}, - {"color":"#FFFFF2"}, - {"color":"#FFFEEF"}, - {"color":"#FFFEEE"}, - {"color":"#FFFFEC"}, - {"color":"#FFFFEB"}, - {"color":"#FFFFEA"}, - {"color":"#FFFFE8"}, - {"color":"#FFFFE6"}, - {"color":"#FFFEE4"}, - {"color":"#FFFFE1"}, - {"color":"#FFFFE0"}, - {"color":"#FFFEDE"}, - {"color":"#FFFFDC"}, - {"color":"#FFFFDA"}, - {"color":"#FFFFD8"}, - {"color":"#FFFED7"}, - {"color":"#FFFED1"}, - {"color":"#FFFEC9"}, - {"color":"#FEFEC0"}, - {"color":"#FEFEB7"}, - {"color":"#FEFEAD"}, - {"color":"#FEFEA3"}, - {"color":"#FFFE9A"}, - {"color":"#FEFB92"}, - {"color":"#FEF88A"}, - {"color":"#FEF480"}, - {"color":"#FEEF77"}, - {"color":"#FEE96C"}, - {"color":"#FEE462"}, - {"color":"#FEDE57"}, - {"color":"#FED84C"}, - {"color":"#FED141"}, - {"color":"#FEC833"}, - {"color":"#FEBD22"}, - {"color":"#FEB216"}, - {"color":"#FEA80B"}, - {"color":"#FE9E04"}, - {"color":"#FF9500"}, - {"color":"#FE8C01"}, - {"color":"#FF840A"}, - {"color":"#FE7B16"}, - {"color":"#FF7126"}, - {"color":"#FE6938"}, - {"color":"#FE5E56"}, - {"color":"#FF5374"}, - {"color":"#FE4C89"}, - {"color":"#FC4897"}, - {"color":"#F846A5"}, - {"color":"#F446B2"}, - {"color":"#F046BE"}, - {"color":"#E946C8"}, - {"color":"#E144D0"}, - {"color":"#DA41D7"}, - {"color":"#D43DD9"}, - {"color":"#CE39D8"}, - {"color":"#C933D9"}, - {"color":"#C12CD9"}, - {"color":"#BA26D8"}, - {"color":"#B31FD8"}, - {"color":"#AC18D7"}, - {"color":"#A412D5"}, - {"color":"#9D0BD2"}, - {"color":"#9606D0"}, - {"color":"#8F03CE"}, - {"color":"#8900CC"}, - {"color":"#8000C9"}, - {"color":"#7802C6"}, - {"color":"#6F09C3"}, - {"color":"#6712BF"}, - {"color":"#5F1ABB"}, - {"color":"#5820B6"}, - {"color":"#5024B0"}, - {"color":"#4825A9"}, - {"color":"#4226A4"}, - {"color":"#3A259D"}, - {"color":"#322595"}, - {"color":"#2C268D"}, - {"color":"#272682"}, - {"color":"#25257B"}, - {"color":"#232476"}, - {"color":"#222470"}, - {"color":"#202368"}, - {"color":"#202261"}, - {"color":"#1F215A"}, - {"color":"#1E2052"}, - {"color":"#1D204A"}, - {"color":"#1B1E40"}, - {"color":"#1B1D35"}, - {"color":"#1B1B2B"}, - {"color":"#1A1A23"} -] -} \ No newline at end of file diff --git a/sunset.css b/sunset.css deleted file mode 100644 index a8b5f19..0000000 --- a/sunset.css +++ /dev/null @@ -1,39 +0,0 @@ -body { - font-family: 'Raleway', sans-serif; - background-color: #FFFFF0; -} - -div { - margin: 20px; -} - -table { - border-collapse:collapse; - width: 400px; - background-color: #FFFFFF; -} - -table, th, td { - font-size: 20px; - border: 1px solid black; -} - -th, td { - padding: 10px; -} - -.content { - display: table-row; -} - -.clock { - background: transparent url('clock_face.png') top left no-repeat; - display: table-cell; - vertical-align: top; -} - -.time { - display: table-cell; - vertical-align: top; - padding-left: 15px; -} diff --git a/sunset.js b/sunset.js deleted file mode 100644 index 714b232..0000000 --- a/sunset.js +++ /dev/null @@ -1,204 +0,0 @@ -// requires jQuery - -var SC = SC || {}; -var defaultLat = 42.3653766; -var defaultLon = -71.1853512; - -SC.Sunset = { - - draw : { - - hand : function(ctx, angle, color, length, width) { - var mid = 200; - ctx.beginPath(); - ctx.moveTo(mid, mid); - ctx.lineTo(mid + length * Math.cos(angle), mid + length * Math.sin(angle)); - ctx.lineWidth = width; - ctx.strokeStyle = color; - ctx.stroke(); - }, - - minuteHand : function(ctx, tIn, color, width) { - var hours = Math.floor(tIn); - var minutes = Math.floor((tIn - hours) * 60); - var angle = 2 * Math.PI * (tIn - hours); - // Correct for the fact that east corresponds to 0 degrees, whereas north is 12:00 - angle -= Math.PI / 2; - var length = 180; - SC.Sunset.draw.hand(ctx, angle, color, length, width); - }, - - hourHand : function(ctx, tIn, color, width) { - var hours = Math.floor(tIn); - var minutes = Math.floor((tIn - hours) * 60); - var angle = 2 * Math.PI * ((hours + minutes / 60.0) / 12.0); - // Correct for the fact that east corresponds to 0 degrees, whereas north is 12:00 - angle -= Math.PI / 2; - SC.Sunset.draw.hand(ctx, angle, "#000000", 100, 10); - }, - - clockFace : function(ctx, option) { - // Draw the circle to make the clock face - var mid = ctx.canvas.getAttribute("width") / 2; - - if (option === "face") { - ctx.lineWidth = 2; - ctx.beginPath(); - ctx.arc(mid, mid, 195, 0, Math.PI * 2, true); - ctx.closePath(); - ctx.fillStyle = "#FFFFFF"; - ctx.fill(); - ctx.stroke(); - } - - if (option === "nose") { - ctx.beginPath(); - ctx.arc(mid, mid, 15, 0, Math.PI * 2, true); - ctx.closePath(); - ctx.fillStyle = "#000000"; - ctx.fill(); - } - } - }, - - dec : { - - toHex : function(val, numDigits) { - var str = val.toString(16); - while (str.length < numDigits) { - str = "0" + str; - } - return str - }, - - toHms : function(tIn) { - var hours = Math.floor(tIn); - var minutes = Math.floor((tIn - hours) * 60); - var seconds = Math.floor((tIn - hours - minutes / 60) * 60 * 60); - var pmStr = " AM"; - if (hours > 12) { - hours -= 12; - pmStr = " PM"; - } - return hours + ":" + SC.Sunset.pad(minutes) + ":" + SC.Sunset.pad(seconds) + pmStr; - }, - - toMs : function(tIn) { - var minutes = Math.floor(tIn * 60); - var seconds = Math.floor((tIn - minutes / 60) * 60 * 60); - var minStr = minutes + " minute"; - if (minutes > 1) { - minStr += "s"; - } else if (minutes < 1) { - minStr = ""; - }; - var secStr = seconds + " second"; - if (seconds != 1) { - secStr += "s"; - } - return minStr + " " + secStr; - } - - }, - - getEarliestSunset : function(lat, lon) { - var day = new Date(); - var earliestDay = day; - var latestDay = day; - var t = 0.0; - var max = 0.0; - var min = 24.0; - // Cycle through 365 days and find the minimum - for (i=0;i<365;i++) { - t = SC.Sunset.getSunsetTime(day, lat, lon); - if (t < min) { - min = t; - earliestDay = new Date(day); - } else if (t > max) { - max = t; - latestDay = new Date(day); - } - day.setDate(day.getDate() + 1); - } - return earliestDay; - }, - - getSunsetTime : function(d, lat, lon) { - var sunsetObj = new SunriseSunset( - d.getFullYear(), - d.getMonth() + 1, - d.getDate(), - lat, lon); - var tzCorrection = -1 * d.getTimezoneOffset() / 60; - return sunsetObj.sunsetLocalHours(tzCorrection); - }, - - pad : function(n) { - return (n < 10) ? ("0" + n) : n; - }, - - startUp : function() { - if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition(SC.Sunset.setLatLon, SC.Sunset.showDefault); - } else { - SC.Sunset.showDefault(); - } - }, - - showDefault : function() { - SC.Sunset.showTime(defaultLat,defaultLon); - }, - - setLatLon : function(position) { - var lat = position.coords.latitude; - var lon = position.coords.longitude; - SC.Sunset.showTime(lat,lon); - }, - - showTime : function(lat,lon) { - var td = new Date(); - - var ctx = $('#canvas')[0].getContext("2d"); - // SC.Sunset.draw.clockFace(ctx, "face"); - - d = new Date(); - var clr = ""; - var val = 0; - var max = 14; - var wid = 1; - for (i = 0; i < max; i++) { - val = Math.floor(255 * (i / max)); - clr = "#" + SC.Sunset.dec.toHex(val, 2) + SC.Sunset.dec.toHex(val, 2) + "FF"; - d.setDate(d.getDate() + 1); - SC.Sunset.draw.minuteHand(ctx, SC.Sunset.getSunsetTime(d, lat, lon), clr, wid); - } - - var sunsetToday = SC.Sunset.getSunsetTime(td, lat, lon) - var tm = new Date(); - tm.setDate(tm.getDate() + 1); - var sunsetTomorrow = SC.Sunset.getSunsetTime(tm, lat, lon) - - SC.Sunset.draw.minuteHand(ctx, sunsetToday, "#000000", 6); - SC.Sunset.draw.hourHand(ctx, sunsetToday); - - SC.Sunset.draw.clockFace(ctx, "nose"); - - var earliestSunset = SC.Sunset.getEarliestSunset(lat, lon); - - var diff = Math.abs(sunsetToday - sunsetTomorrow); - var daysBetween = Math.floor((earliestSunset - new Date()) / (1000 * 60 * 60 * 24)) + 1; - - $(".time").html( - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
" + "Sunset for " + td.toDateString() + "
" + - "at this location
Today" + SC.Sunset.dec.toHms(sunsetToday) + "
Tomorrow" + SC.Sunset.dec.toHms(sunsetTomorrow) + "
Difference" + SC.Sunset.dec.toMs(diff) + "
Earliest Sunset
Date" + earliestSunset.toDateString() + "
Time" + SC.Sunset.dec.toHms(SC.Sunset.getSunsetTime(earliestSunset, lat, lon)) + "
Days from Now" + daysBetween + "
"); - } -}