From b8e191b615954d9d3b254f9efa8a7f8bf07ca0cc Mon Sep 17 00:00:00 2001 From: David Keck Date: Tue, 22 Feb 2022 21:37:16 -0600 Subject: [PATCH 01/45] Updated function brief --- watch-library/shared/watch/watch_utility.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch-library/shared/watch/watch_utility.h b/watch-library/shared/watch/watch_utility.h index f4411ce..4c50cb5 100644 --- a/watch-library/shared/watch/watch_utility.h +++ b/watch-library/shared/watch/watch_utility.h @@ -74,7 +74,7 @@ uint32_t watch_utility_date_time_to_unix_time(watch_date_time date_time, uint32_ */ watch_duration_t watch_utility_seconds_to_duration(uint32_t seconds); -/** @brief Returns the UNIX time (seconds since 1970) for a given watch_date_time struct. +/** @brief Returns a watch_date_time struct for a given UNIX time and UTC offset. * @param timestamp The UNIX timestamp that you wish to convert. * @param utc_offset The number of seconds that you wish date_time to be offset from UTC. * @return A watch_date_time for the given UNIX timestamp and UTC offset, or if outside the range that From a01ae5a232eeb9ea81ccc18a78595cd2f4ebbc2f Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 23 Feb 2022 10:04:19 -0500 Subject: [PATCH 02/45] fatten GND wire to USB port --- PCB/Main Boards/OSO-SWAT-A1-05.brd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PCB/Main Boards/OSO-SWAT-A1-05.brd b/PCB/Main Boards/OSO-SWAT-A1-05.brd index b6bbda2..9712ae5 100644 --- a/PCB/Main Boards/OSO-SWAT-A1-05.brd +++ b/PCB/Main Boards/OSO-SWAT-A1-05.brd @@ -3302,6 +3302,10 @@ Please make sure your boards conform to these design rules. + + + + From f5b68005829a795d757e9fd8c0386fbef9ae65d6 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 3 Mar 2022 10:17:18 -0600 Subject: [PATCH 03/45] movement: fix hang when using voltage face with temperature log --- movement/watch_faces/demo/voltage_face.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/movement/watch_faces/demo/voltage_face.c b/movement/watch_faces/demo/voltage_face.c index 24346aa..147ec01 100644 --- a/movement/watch_faces/demo/voltage_face.c +++ b/movement/watch_faces/demo/voltage_face.c @@ -29,7 +29,11 @@ static void _voltage_face_update_display(void) { char buf[14]; + + watch_enable_adc(); float voltage = (float)watch_get_vcc_voltage() / 1000.0; + watch_disable_adc(); + sprintf(buf, "BA %4.2f V", voltage); // printf("%s\n", buf); watch_display_string(buf, 0); @@ -44,9 +48,6 @@ void voltage_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void voltage_face_activate(movement_settings_t *settings, void *context) { (void) settings; (void) context; - watch_enable_adc(); - // if we set the reference voltage here, watch_get_vcc_voltage won't do it over and over - watch_set_analog_reference_voltage(ADC_REFERENCE_INTREF); } bool voltage_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { @@ -85,7 +86,4 @@ bool voltage_face_loop(movement_event_t event, movement_settings_t *settings, vo void voltage_face_resign(movement_settings_t *settings, void *context) { (void) settings; (void) context; - // make sure to restore the default in the end. - watch_set_analog_reference_voltage(ADC_REFERENCE_VCC); - watch_disable_adc(); } From ea988208e10dbcf62eff65522ec9f92231d880e9 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 3 Mar 2022 11:41:48 -0600 Subject: [PATCH 04/45] battery monitor: hide signal indicator in sleep --- movement/watch_faces/demo/voltage_face.c | 1 + 1 file changed, 1 insertion(+) diff --git a/movement/watch_faces/demo/voltage_face.c b/movement/watch_faces/demo/voltage_face.c index 147ec01..2a568d2 100644 --- a/movement/watch_faces/demo/voltage_face.c +++ b/movement/watch_faces/demo/voltage_face.c @@ -74,6 +74,7 @@ bool voltage_face_loop(movement_event_t event, movement_settings_t *settings, vo } break; case EVENT_LOW_ENERGY_UPDATE: + watch_clear_indicator(WATCH_INDICATOR_SIGNAL); watch_display_string("BA SLEEP ", 0); break; default: From ccdf08da876d2c66bbc54cc246443676c4f9bf2e Mon Sep 17 00:00:00 2001 From: joeycastillo Date: Fri, 4 Mar 2022 14:52:49 -0600 Subject: [PATCH 05/45] Movement: Astronomy and Orrery watch faces (#55) --- movement/lib/astrolib/LICENSE.txt | 9 + movement/lib/astrolib/README.md | 9 + movement/lib/astrolib/astrolib.c | 555 +++++ movement/lib/astrolib/astrolib.h | 87 + movement/lib/sunriset/sunriset.c | 3 +- movement/lib/sunriset/sunriset.h | 2 - movement/lib/vsop87/LICENSE.txt | 5 + movement/lib/vsop87/README.md | 143 ++ movement/lib/vsop87/vsop87a_micro.c | 1019 ++++++++ movement/lib/vsop87/vsop87a_micro.h | 17 + movement/lib/vsop87/vsop87a_milli.c | 2048 +++++++++++++++++ movement/lib/vsop87/vsop87a_milli.h | 17 + movement/make/Makefile | 6 + movement/movement_faces.h | 2 + .../watch_faces/complication/astronomy_face.c | 280 +++ .../watch_faces/complication/astronomy_face.h | 68 + .../watch_faces/complication/orrery_face.c | 232 ++ .../watch_faces/complication/orrery_face.h | 59 + .../shared/watch/watch_private_display.c | 1 + 19 files changed, 4559 insertions(+), 3 deletions(-) create mode 100755 movement/lib/astrolib/LICENSE.txt create mode 100644 movement/lib/astrolib/README.md create mode 100644 movement/lib/astrolib/astrolib.c create mode 100644 movement/lib/astrolib/astrolib.h create mode 100755 movement/lib/vsop87/LICENSE.txt create mode 100755 movement/lib/vsop87/README.md create mode 100755 movement/lib/vsop87/vsop87a_micro.c create mode 100755 movement/lib/vsop87/vsop87a_micro.h create mode 100755 movement/lib/vsop87/vsop87a_milli.c create mode 100755 movement/lib/vsop87/vsop87a_milli.h create mode 100644 movement/watch_faces/complication/astronomy_face.c create mode 100644 movement/watch_faces/complication/astronomy_face.h create mode 100644 movement/watch_faces/complication/orrery_face.c create mode 100644 movement/watch_faces/complication/orrery_face.h diff --git a/movement/lib/astrolib/LICENSE.txt b/movement/lib/astrolib/LICENSE.txt new file mode 100755 index 0000000..26356b0 --- /dev/null +++ b/movement/lib/astrolib/LICENSE.txt @@ -0,0 +1,9 @@ +Public domain + +THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/movement/lib/astrolib/README.md b/movement/lib/astrolib/README.md new file mode 100644 index 0000000..d63bc46 --- /dev/null +++ b/movement/lib/astrolib/README.md @@ -0,0 +1,9 @@ +# Astrolib + +This is a relatively straightforward C port of Greg Miller's [JavaScript astro library](https://github.com/gmiller123456/astrogreg), done by Joey Castillo, for the Sensor Watch Astronomy watch face. + +He released his work into the public domain and so I release this into the public domain as well. + +I have tested the output of this library against [NASA's Horizons system](https://ssd.jpl.nasa.gov/horizons/app.html#/) and found the results to match (within reason, as we're using a truncated version of VSOP87). Moon calculations still seem a bit iffy, but it doesn't surprise me seeing as there are three calculations involved and the error could stack up. + +THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/movement/lib/astrolib/astrolib.c b/movement/lib/astrolib/astrolib.c new file mode 100644 index 0000000..f1bacc5 --- /dev/null +++ b/movement/lib/astrolib/astrolib.c @@ -0,0 +1,555 @@ +/* + * Partial C port of Greg Miller's public domain astro library (gmiller@gregmiller.net) 2019 + * https://github.com/gmiller123456/astrogreg + * + * Ported by Joey Castillo for Sensor Watch + * https://github.com/joeycastillo/Sensor-Watch/ + * + * Public Domain + * + * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include "astrolib.h" +#include "vsop87a_milli.h" + +double astro_convert_utc_to_tt(double jd) ; +double astro_get_GMST(double ut1); +astro_cartesian_coordinates_t astro_subtract_cartesian(astro_cartesian_coordinates_t a, astro_cartesian_coordinates_t b); +astro_cartesian_coordinates_t astro_rotate_from_vsop_to_J2000(astro_cartesian_coordinates_t c); +astro_matrix_t astro_get_x_rotation_matrix(double r); +astro_matrix_t astro_get_y_rotation_matrix(double r); +astro_matrix_t astro_get_z_rotation_matrix(double r); +astro_matrix_t astro_transpose_matrix(astro_matrix_t m); +astro_matrix_t astro_dot_product(astro_matrix_t a, astro_matrix_t b); +astro_matrix_t astro_get_precession_matrix(double jd); +astro_cartesian_coordinates_t astro_matrix_multiply(astro_cartesian_coordinates_t v, astro_matrix_t m); +astro_cartesian_coordinates_t astro_convert_geodedic_latlon_to_ITRF_XYZ(double lat, double lon, double height); +astro_cartesian_coordinates_t astro_convert_ITRF_to_GCRS(astro_cartesian_coordinates_t r, double ut1); +astro_cartesian_coordinates_t astro_convert_coordinates_from_meters_to_AU(astro_cartesian_coordinates_t c); +astro_cartesian_coordinates_t astro_get_observer_geocentric_coords(double jd, double lat, double lon); +astro_cartesian_coordinates_t astro_get_body_coordinates(astro_body_t bodyNum, double et); +astro_cartesian_coordinates_t astro_get_body_coordinates_light_time_adjusted(astro_body_t body, astro_cartesian_coordinates_t origin, double t); +astro_equatorial_coordinates_t astro_convert_cartesian_to_polar(astro_cartesian_coordinates_t xyz); + +//Special "Math.floor()" function used by convertDateToJulianDate() +static double _astro_special_floor(double d) { + if(d > 0) { + return floor(d); + } + return floor(d) - 1; +} + +double astro_convert_date_to_julian_date(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + if (month < 3){ + year = year - 1; + month = month + 12; + } + + double b = 0; + if (!(year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day < 5))))) { + double a = _astro_special_floor(year / 100.0); + b = 2 - a + _astro_special_floor(a / 4.0); + } + + double jd = _astro_special_floor(365.25 * (year + 4716)) + _astro_special_floor(30.6001 * (month + 1)) + day + b - 1524.5; + jd += hour / 24.0; + jd += minute / 24.0 / 60.0; + jd += second / 24.0 / 60.0 / 60.0; + + return jd; +} + +//Return all values in radians. +//The positions are adjusted for the parallax of the Earth, and the offset of the observer from the Earth's center +//All input and output angles are in radians! +astro_equatorial_coordinates_t astro_get_ra_dec(double jd, astro_body_t body, double lat, double lon, bool calculate_precession) { + double jdTT = astro_convert_utc_to_tt(jd); + double t = astro_convert_jd_to_julian_millenia_since_j2000(jdTT); + + // Get current position of Earth and the target body + astro_cartesian_coordinates_t earth_coords = astro_get_body_coordinates(ASTRO_BODY_EARTH, t); + astro_cartesian_coordinates_t body_coords = astro_get_body_coordinates_light_time_adjusted(body, earth_coords, t); + + // Convert to Geocentric coordinate + body_coords = astro_subtract_cartesian(body_coords, earth_coords); + + //Rotate ecliptic coordinates to J2000 coordinates + body_coords = astro_rotate_from_vsop_to_J2000(body_coords); + + astro_matrix_t precession; + // TODO: rotate body for precession, nutation and bias + if(calculate_precession) { + precession = astro_get_precession_matrix(jdTT); + body_coords = astro_matrix_multiply(body_coords, precession); + } + + //Convert to topocentric + astro_cartesian_coordinates_t observerXYZ = astro_get_observer_geocentric_coords(jdTT, lat, lon); + + if(calculate_precession) { + //TODO: rotate observerXYZ for precession, nutation and bias + astro_matrix_t precessionInv = astro_transpose_matrix(precession); + observerXYZ = astro_matrix_multiply(observerXYZ, precessionInv); + } + + body_coords = astro_subtract_cartesian(body_coords, observerXYZ); + + //Convert to topocentric RA DEC by converting from cartesian coordinates to polar coordinates + astro_equatorial_coordinates_t retval = astro_convert_cartesian_to_polar(body_coords); + + retval.declination = M_PI/2.0 - retval.declination; //Dec. Offset to make 0 the equator, and the poles +/-90 deg + if(retval.right_ascension < 0) retval.right_ascension += 2*M_PI; //Ensure RA is positive + + return retval; +} + +//Converts a Julian Date in UTC to Terrestrial Time (TT) +double astro_convert_utc_to_tt(double jd) { + //Leap seconds are hard coded, should be updated from the IERS website for other times + + //TAI = UTC + leap seconds (e.g. 32) + //TT=TAI + 32.184 + + //return jd + (32.0 + 32.184) / 24.0 / 60.0 / 60.0; + return jd + (37.0 + 32.184) / 24.0 / 60.0 / 60.0; + + /* + https://data.iana.org/time-zones/tzdb-2018a/leap-seconds.list + 2272060800 10 # 1 Jan 1972 + 2287785600 11 # 1 Jul 1972 + 2303683200 12 # 1 Jan 1973 + 2335219200 13 # 1 Jan 1974 + 2366755200 14 # 1 Jan 1975 + 2398291200 15 # 1 Jan 1976 + 2429913600 16 # 1 Jan 1977 + 2461449600 17 # 1 Jan 1978 + 2492985600 18 # 1 Jan 1979 + 2524521600 19 # 1 Jan 1980 + 2571782400 20 # 1 Jul 1981 + 2603318400 21 # 1 Jul 1982 + 2634854400 22 # 1 Jul 1983 + 2698012800 23 # 1 Jul 1985 + 2776982400 24 # 1 Jan 1988 + 2840140800 25 # 1 Jan 1990 + 2871676800 26 # 1 Jan 1991 + 2918937600 27 # 1 Jul 1992 + 2950473600 28 # 1 Jul 1993 + 2982009600 29 # 1 Jul 1994 + 3029443200 30 # 1 Jan 1996 + 3076704000 31 # 1 Jul 1997 + 3124137600 32 # 1 Jan 1999 + 3345062400 33 # 1 Jan 2006 + 3439756800 34 # 1 Jan 2009 + 3550089600 35 # 1 Jul 2012 + 3644697600 36 # 1 Jul 2015 + 3692217600 37 # 1 Jan 2017 + */ +} + +double astro_convert_jd_to_julian_millenia_since_j2000(double jd) { + return (jd - 2451545.0) / 365250.0; +} + +astro_cartesian_coordinates_t astro_subtract_cartesian(astro_cartesian_coordinates_t a, astro_cartesian_coordinates_t b) { + astro_cartesian_coordinates_t retval; + + retval.x = a.x - b.x; + retval.y = a.y - b.y; + retval.z = a.z - b.z; + + return retval; +} + +// Performs the rotation from ecliptic coordinates to J2000 coordinates for the given vector x +astro_cartesian_coordinates_t astro_rotate_from_vsop_to_J2000(astro_cartesian_coordinates_t c) { + /* From VSOP87.doc + X +1.000000000000 +0.000000440360 -0.000000190919 X + Y = -0.000000479966 +0.917482137087 -0.397776982902 Y + Z FK5 0.000000000000 +0.397776982902 +0.917482137087 Z VSOP87A + */ + astro_cartesian_coordinates_t t; + t.x = c.x + c.y * 0.000000440360 + c.z * -0.000000190919; + t.y = c.x * -0.000000479966 + c.y * 0.917482137087 + c.z * -0.397776982902; + t.z = c.y * 0.397776982902 + c.z * 0.917482137087; + + return t; +} + +double astro_get_GMST(double ut1) { + double D = ut1 - 2451545.0; + double T = D/36525.0; + double gmst = fmod((280.46061837 + 360.98564736629*D + 0.000387933*T*T - T*T*T/38710000.0), 360.0); + + if(gmst<0) { + gmst+=360; + } + + return gmst/15; +} + +static astro_matrix_t _astro_get_empty_matrix() { + astro_matrix_t t; + for(uint8_t i = 0; i < 3 ; i++) { + for(uint8_t j = 0 ; j < 3 ; j++) { + t.elements[i][j] = 0; + } + } + return t; +} + +//Gets a rotation matrix about the x axis. Angle R is in radians +astro_matrix_t astro_get_x_rotation_matrix(double r) { + astro_matrix_t t = _astro_get_empty_matrix(); + + t.elements[0][0]=1; + t.elements[0][1]=0; + t.elements[0][2]=0; + t.elements[1][0]=0; + t.elements[1][1]=cos(r); + t.elements[1][2]=sin(r); + t.elements[2][0]=0; + t.elements[2][1]=-sin(r); + t.elements[2][2]=cos(r); + + return t; +} + +//Gets a rotation matrix about the y axis. Angle R is in radians +astro_matrix_t astro_get_y_rotation_matrix(double r) { + astro_matrix_t t = _astro_get_empty_matrix(); + + t.elements[0][0]=cos(r); + t.elements[0][1]=0; + t.elements[0][2]=-sin(r); + t.elements[1][0]=0; + t.elements[1][1]=1; + t.elements[1][2]=0; + t.elements[2][0]=sin(r); + t.elements[2][1]=0; + t.elements[2][2]=cos(r); + + return t; +} + +//Gets a rotation matrix about the z axis. Angle R is in radians +astro_matrix_t astro_get_z_rotation_matrix(double r) { + astro_matrix_t t = _astro_get_empty_matrix(); + + t.elements[0][0]=cos(r); + t.elements[0][1]=sin(r); + t.elements[0][2]=0; + t.elements[1][0]=-sin(r); + t.elements[1][1]=cos(r); + t.elements[1][2]=0; + t.elements[2][0]=0; + t.elements[2][1]=0; + t.elements[2][2]=1; + + return t; +} + +void astro_print_matrix(char * title, astro_matrix_t matrix); +void astro_print_matrix(char * title, astro_matrix_t matrix) { + printf("%s\n", title); + for(uint8_t i = 0; i < 3 ; i++) { + printf("\t"); + for(uint8_t j = 0 ; j < 3 ; j++) { + printf("%12f", matrix.elements[i][j]); + } + printf("\n"); + } + printf("\n"); +} + +astro_matrix_t astro_dot_product(astro_matrix_t a, astro_matrix_t b) { + astro_matrix_t retval; + + for(uint8_t i = 0; i < 3 ; i++) { + for(uint8_t j = 0 ; j < 3 ; j++) { + double temp = 0; + for(uint8_t k = 0; k < 3 ; k++) { + temp += a.elements[i][k] * b.elements[k][j]; + } + retval.elements[i][j]=temp; + } + } + + return retval; +} + +astro_matrix_t astro_transpose_matrix(astro_matrix_t m) { + astro_matrix_t retval; + for(uint8_t i = 0; i < 3 ; i++) { + for(uint8_t j = 0 ; j < 3 ; j++) { + retval.elements[i][j] = m.elements[j][i]; + } + } + return retval; +} + +astro_matrix_t astro_get_precession_matrix(double jd) { + //2006 IAU Precession. Implemented from IERS Technical Note No 36 ch5. + //https://www.iers.org/SharedDocs/Publikationen/EN/IERS/Publications/tn/TechnNote36/tn36_043.pdf?__blob=publicationFile&v=1 + + double t = (jd - 2451545.0) / 36525.0; //5.2 + const double Arcsec2Radians = M_PI/180.0/60.0/60.0; //Converts arc seconds used in equations below to radians + + double e0 = 84381.406 * Arcsec2Radians; //5.6.4 + double omegaA = e0 + ((-0.025754 + (0.0512623 + (-0.00772503 + (-0.000000467 + 0.0000003337*t) * t) * t) * t) * t) * Arcsec2Radians; //5.39 + double psiA = ((5038.481507 + (-1.0790069 + (-0.00114045 + (0.000132851 - 0.0000000951*t) * t) * t) * t) * t) * Arcsec2Radians; //5.39 + double chiA = ((10.556403 + (-2.3814292 + (-0.00121197 + (0.000170663 - 0.0000000560*t) * t) * t) * t) * t) * Arcsec2Radians; //5.40 + //Rotation matrix from 5.4.5 + //(R1(−e0) · R3(psiA) · R1(omegaA) · R3(−chiA)) + //Above eq rotates from "of date" to J2000, so we reverse the signs to go from J2000 to "of date" + astro_matrix_t m1 = astro_get_x_rotation_matrix(e0); + astro_matrix_t m2 = astro_get_z_rotation_matrix(-psiA); + astro_matrix_t m3 = astro_get_x_rotation_matrix(-omegaA); + astro_matrix_t m4 = astro_get_z_rotation_matrix(chiA); + + astro_matrix_t m5 = astro_dot_product(m4, m3); + astro_matrix_t m6 = astro_dot_product(m5, m2); + astro_matrix_t precessionMatrix = astro_dot_product(m6, m1); + + return precessionMatrix; +} + +astro_cartesian_coordinates_t astro_matrix_multiply(astro_cartesian_coordinates_t v, astro_matrix_t m) { + astro_cartesian_coordinates_t t; + + t.x = v.x*m.elements[0][0] + v.y*m.elements[0][1] + v.z*m.elements[0][2]; + t.y = v.x*m.elements[1][0] + v.y*m.elements[1][1] + v.z*m.elements[1][2]; + t.z = v.x*m.elements[2][0] + v.y*m.elements[2][1] + v.z*m.elements[2][2]; + + return t; +} + +//Converts cartesian XYZ coordinates to polar (e.g. J2000 xyz to Right Accention and Declication) +astro_equatorial_coordinates_t astro_convert_cartesian_to_polar(astro_cartesian_coordinates_t xyz) { + astro_equatorial_coordinates_t t; + + t.distance = sqrt(xyz.x * xyz.x + xyz.y * xyz.y + xyz.z * xyz.z); + t.declination = acos(xyz.z / t.distance); + t.right_ascension = atan2(xyz.y, xyz.x); + + if(t.declination < 0) t.declination += 2 * M_PI; + + if(t.right_ascension < 0) t.right_ascension += 2 * M_PI; + + return t; +} + +//Convert Geodedic Lat Lon to geocentric XYZ position vector +//All angles are input as radians +astro_cartesian_coordinates_t astro_convert_geodedic_latlon_to_ITRF_XYZ(double lat, double lon, double height) { + //Algorithm from Explanatory Supplement to the Astronomical Almanac 3rd ed. P294 + const double a = 6378136.6; + const double f = 1 / 298.25642; + + const double C = sqrt(((cos(lat)*cos(lat)) + (1.0-f)*(1.0-f) * (sin(lat)*sin(lat)))); + + const double S = (1-f)*(1-f)*C; + + double h = height; + + astro_cartesian_coordinates_t r; + r.x = (a*C+h) * cos(lat) * cos(lon); + r.y = (a*C+h) * cos(lat) * sin(lon); + r.z = (a*S+h) * sin(lat); + + return r; +} + +//Convert position vector to celestial "of date" system. +//g(t)=R3(-GAST) r +//(Remember to use UT1 for GAST, not ET) +//All angles are input and output as radians +astro_cartesian_coordinates_t astro_convert_ITRF_to_GCRS(astro_cartesian_coordinates_t r, double ut1) { + //This is a simple rotation matrix implemenation about the Z axis, rotation angle is -GMST + + double GMST = astro_get_GMST(ut1); + GMST =- GMST * 15.0 * M_PI / 180.0; + + astro_matrix_t m = astro_get_z_rotation_matrix(GMST); + astro_cartesian_coordinates_t t = astro_matrix_multiply(r, m); + + return t; +} + +astro_cartesian_coordinates_t astro_convert_coordinates_from_meters_to_AU(astro_cartesian_coordinates_t c) { + astro_cartesian_coordinates_t t; + + t.x = c.x / 1.49597870691E+11; + t.y = c.y / 1.49597870691E+11; + t.z = c.z / 1.49597870691E+11; + + return t; +} + +astro_cartesian_coordinates_t astro_get_observer_geocentric_coords(double jd, double lat, double lon) { + astro_cartesian_coordinates_t r = astro_convert_geodedic_latlon_to_ITRF_XYZ(lat, lon,0); + r = astro_convert_ITRF_to_GCRS(r, jd); + r = astro_convert_coordinates_from_meters_to_AU(r); + + return r; +} + +//Returns a body's cartesian coordinates centered on the Sun. +//Requires vsop87a_milli_js, if you wish to use a different version of VSOP87, replace the class name vsop87a_milli below +astro_cartesian_coordinates_t astro_get_body_coordinates(astro_body_t body, double et) { + astro_cartesian_coordinates_t retval = {0}; + double coords[3]; + switch(body) { + case ASTRO_BODY_SUN: + return retval; //Sun is at the center for vsop87a + case ASTRO_BODY_MERCURY: + vsop87a_milli_getMercury(et, coords); + break; + case ASTRO_BODY_VENUS: + vsop87a_milli_getVenus(et, coords); + break; + case ASTRO_BODY_EARTH: + vsop87a_milli_getEarth(et, coords); + break; + case ASTRO_BODY_MARS: + vsop87a_milli_getMars(et, coords); + break; + case ASTRO_BODY_JUPITER: + vsop87a_milli_getJupiter(et, coords); + break; + case ASTRO_BODY_SATURN: + vsop87a_milli_getSaturn(et, coords); + break; + case ASTRO_BODY_URANUS: + vsop87a_milli_getUranus(et, coords); + break; + case ASTRO_BODY_NEPTUNE: + vsop87a_milli_getNeptune(et, coords); + break; + case ASTRO_BODY_EMB: + vsop87a_milli_getEmb(et, coords); + break; + case ASTRO_BODY_MOON: + { + double earth_coords[3]; + double emb_coords[3]; + vsop87a_milli_getEarth(et, earth_coords); + vsop87a_milli_getEmb(et, emb_coords); + vsop87a_milli_getMoon(earth_coords, emb_coords, coords); + } + break; + } + + retval.x = coords[0]; + retval.y = coords[1]; + retval.z = coords[2]; + + return retval; +} + +astro_cartesian_coordinates_t astro_get_body_coordinates_light_time_adjusted(astro_body_t body, astro_cartesian_coordinates_t origin, double t) { + //Get current position of body + astro_cartesian_coordinates_t body_coords = astro_get_body_coordinates(body, t); + + double newT = t; + + for(uint8_t i = 0 ; i < 2 ; i++) { + //Calculate light time to body + body_coords = astro_subtract_cartesian(body_coords, origin); + double distance = sqrt(body_coords.x*body_coords.x + body_coords.y*body_coords.y + body_coords.z*body_coords.z); + distance *= 1.496e+11; //Convert from AU to meters + double lightTime = distance / 299792458.0; + + //Convert light time to Julian Millenia, and subtract it from the original value of t + newT -= lightTime / 24.0 / 60.0 / 60.0 / 365250.0; + //Recalculate body position adjusted for light time + body_coords = astro_get_body_coordinates(body, newT); + } + + return body_coords; +} + +astro_horizontal_coordinates_t astro_ra_dec_to_alt_az(double jd, double lat, double lon, double ra, double dec) { + double GMST = astro_get_GMST(jd) * M_PI/180.0 * 15.0; + double h = GMST + lon - ra; + + double sina = sin(dec)*sin(lat) + cos(dec)*cos(h)*cos(lat); + double a = asin(sina); + + double cosAz = (sin(dec)*cos(lat) - cos(dec)*cos(h)*sin(lat)) / cos(a); + double Az = acos(cosAz); + + if(sin(h) > 0) Az = 2.0*M_PI - Az; + + astro_horizontal_coordinates_t retval; + retval.altitude = a; + retval.azimuth = Az; + + return retval; +} + +double astro_degrees_to_radians(double degrees) { + return degrees * M_PI / 180; +} + +double astro_radians_to_degrees(double radians) { + return radians * 180.0 / M_PI; +} + +astro_angle_dms_t astro_radians_to_dms(double radians) { + astro_angle_dms_t retval; + int8_t sign = (radians < 0) ? -1 : 1; + double degrees = fabs(astro_radians_to_degrees(radians)); + + retval.degrees = (uint16_t)degrees; + double temp = 60.0 * (degrees - retval.degrees); + retval.minutes = (uint8_t)temp; + retval.seconds = (uint8_t)round(60.0 * (temp - retval.minutes)); + + if (retval.seconds > 59) { + retval.seconds = 0.0; + retval.minutes++; + } + + if (retval.minutes > 59) { + retval.minutes = 0; + retval.degrees++; + } + + degrees *= sign; + + return retval; +} + +astro_angle_hms_t astro_radians_to_hms(double radians) { + astro_angle_hms_t retval; + double degrees = astro_radians_to_degrees(radians); + double temp = degrees / 15.0; + + retval.hours = (uint8_t)temp; + temp = 60.0 * (temp - retval.hours); + retval.minutes = (uint8_t)temp; + retval.seconds = (uint8_t)round(60.0 * (temp - retval.minutes)); + + if (retval.seconds > 59) { + retval.seconds = 0; + retval.minutes++; + } + + if (retval.minutes > 59) { + retval.minutes = 0; + retval.hours++; + } + + return retval; +} diff --git a/movement/lib/astrolib/astrolib.h b/movement/lib/astrolib/astrolib.h new file mode 100644 index 0000000..2523ead --- /dev/null +++ b/movement/lib/astrolib/astrolib.h @@ -0,0 +1,87 @@ +/* + * Partial C port of Greg Miller's public domain astro library (gmiller@gregmiller.net) 2019 + * https://github.com/gmiller123456/astrogreg + * + * Ported by Joey Castillo for Sensor Watch + * https://github.com/joeycastillo/Sensor-Watch/ + * + * Public Domain + * + * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef ASTROLIB_H_ +#define ASTROLIB_H_ + +typedef enum { + ASTRO_BODY_SUN = 0, + ASTRO_BODY_MERCURY, + ASTRO_BODY_VENUS, + ASTRO_BODY_EARTH, + ASTRO_BODY_MARS, + ASTRO_BODY_JUPITER, + ASTRO_BODY_SATURN, + ASTRO_BODY_URANUS, + ASTRO_BODY_NEPTUNE, + ASTRO_BODY_EMB, + ASTRO_BODY_MOON +} astro_body_t; + +typedef struct { + double elements[3][3]; +} astro_matrix_t; + +typedef struct { + double x; + double y; + double z; +} astro_cartesian_coordinates_t; + +typedef struct { + double right_ascension; + double declination; + double distance; +} astro_equatorial_coordinates_t; + +typedef struct { + double altitude; + double azimuth; +} astro_horizontal_coordinates_t; + +typedef struct { + int16_t degrees; + uint8_t minutes; + uint8_t seconds; // you may want this to be a float, watch just can't display any more digits +} astro_angle_dms_t; + +typedef struct { + uint8_t hours; + uint8_t minutes; + uint8_t seconds; // you may want this to be a float, watch just can't display any more digits +} astro_angle_hms_t; + +// Convert a date to a julian date. Must be in UTC+0 time zone! +double astro_convert_date_to_julian_date(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second); + +// Converts a Julan Date to Julian Millenia since J2000, which is what VSOP87 expects as input. +double astro_convert_jd_to_julian_millenia_since_j2000(double jd); + +// Get right ascension / declination for a given body in the list above. +astro_equatorial_coordinates_t astro_get_ra_dec(double jd, astro_body_t bodyNum, double lat, double lon, bool calculate_precession); + +// Convert right ascension / declination to altitude/azimuth for a given location. +astro_horizontal_coordinates_t astro_ra_dec_to_alt_az(double jd, double lat, double lon, double ra, double dec); + +// these are self-explanatory +double astro_degrees_to_radians(double degrees); +double astro_radians_to_degrees(double radians); +astro_angle_dms_t astro_radians_to_dms(double radians); +astro_angle_hms_t astro_radians_to_hms(double radians); + +#endif // ASTROLIB_H_ diff --git a/movement/lib/sunriset/sunriset.c b/movement/lib/sunriset/sunriset.c index 9126c3b..178f2ff 100644 --- a/movement/lib/sunriset/sunriset.c +++ b/movement/lib/sunriset/sunriset.c @@ -17,6 +17,7 @@ Released to the public domain by Paul Schlyter, December 1992 #include #include "sunriset.h" +static void sunpos( double d, double *lon, double *r ); /* A macro to compute the number of days elapsed since 2000 Jan 0.0 */ /* (which is equal to 1999 Dec 31, 0h UT) */ @@ -199,7 +200,7 @@ double __daylen__( int year, int month, int day, double lon, double lat, /* This function computes the Sun's position at any instant */ -void sunpos( double d, double *lon, double *r ) +static void sunpos( double d, double *lon, double *r ) /******************************************************/ /* Computes the Sun's ecliptic longitude and distance */ /* at an instant given in d, number of days since */ diff --git a/movement/lib/sunriset/sunriset.h b/movement/lib/sunriset/sunriset.h index f8b97e3..7b2b6c8 100644 --- a/movement/lib/sunriset/sunriset.h +++ b/movement/lib/sunriset/sunriset.h @@ -24,8 +24,6 @@ double __daylen__( int year, int month, int day, double lon, double lat, int __sunriset__( int year, int month, int day, double lon, double lat, double altit, int upper_limb, double *rise, double *set ); -void sunpos( double d, double *lon, double *r ); - void sun_RA_dec( double d, double *RA, double *dec, double *r ); double revolution( double x ); diff --git a/movement/lib/vsop87/LICENSE.txt b/movement/lib/vsop87/LICENSE.txt new file mode 100755 index 0000000..cc8be27 --- /dev/null +++ b/movement/lib/vsop87/LICENSE.txt @@ -0,0 +1,5 @@ +Author: Greg A Miller (gmiller@gregmiller.net) +I release all of my work in this project to the public domain. + +Note, though, not everything here can be considered my work. The VSOP87 theory is the work of +Bureau des Longitudes. \ No newline at end of file diff --git a/movement/lib/vsop87/README.md b/movement/lib/vsop87/README.md new file mode 100755 index 0000000..6ec7cbb --- /dev/null +++ b/movement/lib/vsop87/README.md @@ -0,0 +1,143 @@ +# Example + +An example in JavaScript showing computations is available at http://www.celestialprogramming.com/vsop87-multilang/ + +### Current Stauts +Versions for many different languages and environments have been created. These have passed all test cases provided by the +VSOP87 authors, a validation program is also included for each language. They are ready for use. See the "Languages" directory for the status +of each language. + +Still to come: more languages, documentation, and examples. + +# About this Project +The purpose of this project is to create versions of VSOP87 in many different languages. The plan is to generate a initial version in C# truncated to different +precisions, then convert the resulting files into other languages. This project was inspired by the [Neoprogrammics Source Code Generator Tool](http://www.neoprogrammics.com/vsop87/source_code_generator_tool/). +The goal of this project is to provide easier to use (readymade source files), include all data (e.g. the Moon and velocities), are truncated to different accuracy levels, +, for more languages, and have a more permissive license (public domain). It will provide tests against the original VSOP87 test data for each programming language to validate correctness, as well as examples to show common useage. + +# Language Status + +Below is a list of the planned languages and their current status. + + +Language |Inline|JSON|CSV|CSV Low Mem|Validation Tests|Alt Az Reduction Example +-------------|------|----|---|-----------|----------------|-------------- +Java |Yes | |Yes| |Pass | +C |Yes | | |Yes |Pass | +C# |Yes | |Yes| |Pass | +Python |Yes |Yes |Yes| |Pass | +C++ |Yes | | | |Pass | +VB.Net |Yes | | | |Pass | +JavaScript |Yes |Yes | | |Pass |Yes +PHP |Yes | | | |Pass | +Ruby |Yes | | | |Pass | +Swift |Yes | | | |Pass | +Matlab/Octave|Yes | | | |Pass | +Groovy | | |Yes| |Pass | +Go |Yes | | | |Pass | +Pascal |Yes | | | |0.000009au | +Perl |Yes | | |Yes |Pass | +R |Fail! | | | |Fail! | +Cobol | | | | | | +Fortran | | | | | | +Rust |Yes | | | |Pass | +Arduino |Yes | | | |0.000009au | + +# What is VSOP87? Why use it? +VSOP87 is one of many solutions available for predicting the positions of the planets (plus the Sun and the Moon) in our solar system. The actual name is +Variations S�culaires des Orbites Plan�taires, and it was published in 1987 by the Bureau des Longitudes. Even though there have been many other methods +developed before and after VSOP87, it remains one of the most popular methods among amatuers. It provides better accuracy than most amatuers require (.1 arcseconds) +over a period of a few thousand years before and after the year 2000. + +# Implementation Types +There are a few different types of implementations: Inline, JSON, CSV, and CSV Low Memory. The inline versions are generally the easiest to use as they will have no +external requirements, they are also the easiest to generate, so they're available for more languages. The JSON versions require a JSON file (located in the +languages/JSON folder) which is loaded into memory. The advantages of the JSON versions are you can compute the velocities with the same data the positions +are generated from, and you can load and dispose of the memory used by the data when you need it. The CSV implementations are similar to the JSON implementations, +but, obviously, read from a CSV file (located in the languages/CSV folder). And the Low Memory CSV implementations read the same CSV files, but the +data is not retained in memory. The JSON versions are located in the Languages/JSON directory, as well as the required JSON files, and the CSV implementations +are in the languages/CSV folder. + +# Which Version Should I Use? +For the overwhelming majority of users, the VSOP87A_full version will be all that you need. This is the full version, but should still be fast enough and small enough +for most use cases. Using the full version eliminates any questions of whether it will be accurate enough. If, after trying the full version, the computation isn't +fast enough, from there you should experiment with truncated versions. The VSOP87A versions are the only versions which include both the Earth and Moon. VSOP87A doesn't include the moon directly, but does include the Earth and the Earth-Moon Barrycenter, and all provided code for the VSOP87A versions include a function to compute the Moon's position from the Earth and EMB. Using the versions that provide the velocities is necessary if you want to account for relativistic effects do to the motion of the observer. + +There are several versions of the main theory. The first is just called VSOP87, the remainder of them are appended with the letters A, B, C, D, E. Each version +provides the data in a slightly different form. + +Version|Mercury|Venus|Earth|EMB|Mars|Jupiter|Saturn|Uranus|Neptune|Sun|Coordinates +-------|-------|-----|-----|---|----|-------|------|------|-------|---|----------- +VSOP87|Yes|Yes|No|Yes|Yes|Yes|Yes|Yes|Yes|No|Keperian Orbital Elements +VSOP87A|Yes|Yes|Yes|Yes|Yes|Yes|Yes|Yes|Yes|No|Heliocentric J2000 Ecliptic Rectangular XYZ +VSOP87B|Yes|Yes|Yes|No|Yes|Yes|Yes|Yes|Yes|No|Heliocentric J2000 Ecliptic Spherical LBR +VSOP87C|Yes|Yes|Yes|No|Yes|Yes|Yes|Yes|Yes|No|Heliocentric Ecliptic of date Rectangular XYZ +VSOP87D|Yes|Yes|Yes|No|Yes|Yes|Yes|Yes|Yes|No|Heliocentric Ecliptic of date Spherical LBR +VSOP87E|Yes|Yes|Yes|No|Yes|Yes|Yes|Yes|Yes|Yes|Barycentric J2000 Ecliptic Rectangular XYZ + +# Truncated versions +Since the full VSOP87 provides more accuracy than most amateurs require, the algorithm can be shortened by eliminating terms. This speeds up the computations, and +reduces the overall size of the code at the cost of accuracy. For each programming language, this project supplies VSOP87 truncated at ten different levels. The +effects of accuracy are detailed in the graphs below. Each level of truncation eliminates any terms with a coefficient 1/10 the previous truncation level. + +Trunaction Level|Total Terms|Skipped Terms|Percent Skipped +----------------|-----------|-------------|--------------- +full |269949|0 |0 % +xx large |269949|20998 |7.7 % +x large |269949|67848 |25.1 % +large |269949|145031|53.7 % +small |269949|218559|80.9 % +x small |269949|250204|92.6 % +milli |269949|262369|97.1 % +micro |269949|266975|98.8 % +nano |269949|268686|99.5 % +pico |269949|269464|99.8 % + +# Accuracy + +Accuracy graphs are below. They show the error in degrees of each body as viewed from Earth. Each graph shows the error for one body for all truncated versions of +VSOP87. The error is vs. the full version of VSOP87, so the inherent error in VSOP87 also has to be added. Some bodies appear twice, to zoom in on the lower portion +of the graph, as the error of the pico version makes it difficult to see errors amongst the larger versions. The Python script and data to reproduce the graphs is +in the Accuracy folder, by regenerating them you can use the Matplotlib interface to explore the graphs further. + +Since the error is computed from the geocenter, the Earth does not appear in the graphs below, nor does the Sun. Graphs are also not present for the Moon, but graphs +are available for the Earth-Moon Barrycenter (EMB), the error for the Moon will be a linear function of the EMB error. + +The full VSOP87 accuracy is .1 arcseconds for Saturn, and better for all others. For more details on accuracy of the full theory consult +[Planetary theories in rectangular and spherical variables - VSOP 87 solutions](http://articles.adsabs.harvard.edu/full/1988A%26A...202..309B). + +### Mercury +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/mercury.png) + +### Venus +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/venus.png) + +### Earth-Moon Barrycenter +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/emb.png) + +### Earth-Moon Barrycenter (zoomed) +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/emb2.png) + +### Mars +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/mars.png) + +### Jupiter +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/jupiter.png) + +### Saturn +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/saturn.png) + +### Saturn (zoomed) +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/saturn2.png) + +### Uranus +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/uranus.png) + +### Uranus (zoomed) +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/uranus2.png) + +### Neptune +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/neptune.png) + +### Neptune (zoomed) +![Mercury](https://raw.githubusercontent.com/gmiller123456/vsop87-multilang/master/utility/Accuracy/neptune2.png) diff --git a/movement/lib/vsop87/vsop87a_micro.c b/movement/lib/vsop87/vsop87a_micro.c new file mode 100755 index 0000000..7e69fea --- /dev/null +++ b/movement/lib/vsop87/vsop87a_micro.c @@ -0,0 +1,1019 @@ +//VSOP87-Multilang http://www.astrogreg.com/vsop87-multilang/index.html +//Greg Miller (gmiller@gregmiller.net) 2019. Released as Public Domain + +#include +#include "vsop87a_micro.h" +double vsop87a_micro_earth_x(double t); +double vsop87a_micro_earth_y(double t); +double vsop87a_micro_earth_z(double t); +double vsop87a_micro_emb_x(double t); +double vsop87a_micro_emb_y(double t); +double vsop87a_micro_emb_z(double t); +double vsop87a_micro_jupiter_x(double t); +double vsop87a_micro_jupiter_y(double t); +double vsop87a_micro_jupiter_z(double t); +double vsop87a_micro_mars_x(double t); +double vsop87a_micro_mars_y(double t); +double vsop87a_micro_mars_z(double t); +double vsop87a_micro_mercury_x(double t); +double vsop87a_micro_mercury_y(double t); +double vsop87a_micro_mercury_z(double t); +double vsop87a_micro_neptune_x(double t); +double vsop87a_micro_neptune_y(double t); +double vsop87a_micro_neptune_z(double t); +double vsop87a_micro_saturn_x(double t); +double vsop87a_micro_saturn_y(double t); +double vsop87a_micro_saturn_z(double t); +double vsop87a_micro_uranus_x(double t); +double vsop87a_micro_uranus_y(double t); +double vsop87a_micro_uranus_z(double t); +double vsop87a_micro_venus_x(double t); +double vsop87a_micro_venus_y(double t); +double vsop87a_micro_venus_z(double t); + + +void vsop87a_micro_getEarth(double t,double temp[]){ + temp[0]=vsop87a_micro_earth_x(t); + temp[1]=vsop87a_micro_earth_y(t); + temp[2]=vsop87a_micro_earth_z(t); +} + +void vsop87a_micro_getEmb(double t,double temp[]){ + temp[0]=vsop87a_micro_emb_x(t); + temp[1]=vsop87a_micro_emb_y(t); + temp[2]=vsop87a_micro_emb_z(t); +} + +void vsop87a_micro_getJupiter(double t,double temp[]){ + temp[0]=vsop87a_micro_jupiter_x(t); + temp[1]=vsop87a_micro_jupiter_y(t); + temp[2]=vsop87a_micro_jupiter_z(t); +} + +void vsop87a_micro_getMars(double t,double temp[]){ + temp[0]=vsop87a_micro_mars_x(t); + temp[1]=vsop87a_micro_mars_y(t); + temp[2]=vsop87a_micro_mars_z(t); +} + +void vsop87a_micro_getMercury(double t,double temp[]){ + temp[0]=vsop87a_micro_mercury_x(t); + temp[1]=vsop87a_micro_mercury_y(t); + temp[2]=vsop87a_micro_mercury_z(t); +} + +void vsop87a_micro_getNeptune(double t,double temp[]){ + temp[0]=vsop87a_micro_neptune_x(t); + temp[1]=vsop87a_micro_neptune_y(t); + temp[2]=vsop87a_micro_neptune_z(t); +} + +void vsop87a_micro_getSaturn(double t,double temp[]){ + temp[0]=vsop87a_micro_saturn_x(t); + temp[1]=vsop87a_micro_saturn_y(t); + temp[2]=vsop87a_micro_saturn_z(t); +} + +void vsop87a_micro_getUranus(double t,double temp[]){ + temp[0]=vsop87a_micro_uranus_x(t); + temp[1]=vsop87a_micro_uranus_y(t); + temp[2]=vsop87a_micro_uranus_z(t); +} + +void vsop87a_micro_getVenus(double t,double temp[]){ + temp[0]=vsop87a_micro_venus_x(t); + temp[1]=vsop87a_micro_venus_y(t); + temp[2]=vsop87a_micro_venus_z(t); +} + +void vsop87a_micro_getMoon(double earth[], double emb[],double temp[]){ + temp[0]=(emb[0]-earth[0])*(1 + 1 / 0.01230073677); + temp[1]=(emb[1]-earth[1])*(1 + 1 / 0.01230073677); + temp[2]=(emb[2]-earth[2])*(1 + 1 / 0.01230073677); + temp[0]=temp[0]+earth[0]; + temp[1]=temp[1]+earth[1]; + temp[2]=temp[2]+earth[2]; +} + +double vsop87a_micro_earth_x(double t){ + double earth_x_0=0.0; + earth_x_0+= 0.99982928844 * cos( 1.75348568475 + 6283.07584999140*t); + earth_x_0+= 0.00835257300 * cos( 1.71034539450 + 12566.15169998280*t); + earth_x_0+= 0.00561144206 * cos( 0.00000000000 + 0.00000000000*t); + earth_x_0+= 0.00010466628 * cos( 1.66722645223 + 18849.22754997420*t); + + double earth_x_1=0.0; + earth_x_1+= 0.00123403056 * cos( 0.00000000000 + 0.00000000000*t); + earth_x_1+= 0.00051500156 * cos( 6.00266267204 + 12566.15169998280*t); + earth_x_1=earth_x_1 * t; + + return earth_x_0+earth_x_1; +} + +double vsop87a_micro_earth_y(double t){ + double earth_y_0=0.0; + earth_y_0+= 0.99989211030 * cos( 0.18265890456 + 6283.07584999140*t); + earth_y_0+= 0.02442699036 * cos( 3.14159265359 + 0.00000000000*t); + earth_y_0+= 0.00835292314 * cos( 0.13952878991 + 12566.15169998280*t); + earth_y_0+= 0.00010466965 * cos( 0.09641690558 + 18849.22754997420*t); + + double earth_y_1=0.0; + earth_y_1+= 0.00093046324 * cos( 0.00000000000 + 0.00000000000*t); + earth_y_1+= 0.00051506609 * cos( 4.43180499286 + 12566.15169998280*t); + earth_y_1=earth_y_1 * t; + + return earth_y_0+earth_y_1; +} + +double vsop87a_micro_earth_z(double t){ + double earth_z_1=0.0; + earth_z_1+= 0.00227822442 * cos( 3.41372504278 + 6283.07584999140*t); + earth_z_1=earth_z_1 * t; + + return earth_z_1; +} + +double vsop87a_micro_emb_x(double t){ + double emb_x_0=0.0; + emb_x_0+= 0.99982927460 * cos( 1.75348568475 + 6283.07584999140*t); + emb_x_0+= 0.00835257300 * cos( 1.71034539450 + 12566.15169998280*t); + emb_x_0+= 0.00561144161 * cos( 0.00000000000 + 0.00000000000*t); + emb_x_0+= 0.00010466628 * cos( 1.66722645223 + 18849.22754997420*t); + + double emb_x_1=0.0; + emb_x_1+= 0.00123403046 * cos( 0.00000000000 + 0.00000000000*t); + emb_x_1+= 0.00051500156 * cos( 6.00266267204 + 12566.15169998280*t); + emb_x_1=emb_x_1 * t; + + return emb_x_0+emb_x_1; +} + +double vsop87a_micro_emb_y(double t){ + double emb_y_0=0.0; + emb_y_0+= 0.99989209645 * cos( 0.18265890456 + 6283.07584999140*t); + emb_y_0+= 0.02442698841 * cos( 3.14159265359 + 0.00000000000*t); + emb_y_0+= 0.00835292314 * cos( 0.13952878991 + 12566.15169998280*t); + emb_y_0+= 0.00010466965 * cos( 0.09641690558 + 18849.22754997420*t); + + double emb_y_1=0.0; + emb_y_1+= 0.00093046317 * cos( 0.00000000000 + 0.00000000000*t); + emb_y_1+= 0.00051506609 * cos( 4.43180499286 + 12566.15169998280*t); + emb_y_1=emb_y_1 * t; + + return emb_y_0+emb_y_1; +} + +double vsop87a_micro_emb_z(double t){ + double emb_z_1=0.0; + emb_z_1+= 0.00227822442 * cos( 3.41372504278 + 6283.07584999140*t); + emb_z_1=emb_z_1 * t; + + return emb_z_1; +} + +double vsop87a_micro_jupiter_x(double t){ + double jupiter_x_0=0.0; + jupiter_x_0+= 5.19663470114 * cos( 0.59945082355 + 529.69096509460*t); + jupiter_x_0+= 0.36662642320 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_x_0+= 0.12593937922 * cos( 0.94911583701 + 1059.38193018920*t); + jupiter_x_0+= 0.01500672056 * cos( 0.73175134610 + 522.57741809380*t); + jupiter_x_0+= 0.01476224578 * cos( 3.61736921122 + 536.80451209540*t); + jupiter_x_0+= 0.00457752736 * cos( 1.29883700755 + 1589.07289528380*t); + jupiter_x_0+= 0.00301689798 * cos( 5.17372551148 + 7.11354700080*t); + jupiter_x_0+= 0.00385975375 * cos( 2.01229910687 + 103.09277421860*t); + jupiter_x_0+= 0.00194025405 * cos( 5.02580363996 + 426.59819087600*t); + jupiter_x_0+= 0.00150678793 * cos( 6.12003027739 + 110.20632121940*t); + jupiter_x_0+= 0.00144867641 * cos( 5.55980577080 + 632.78373931320*t); + jupiter_x_0+= 0.00134226996 * cos( 0.87648567011 + 213.29909543800*t); + jupiter_x_0+= 0.00103494641 * cos( 6.19324769120 + 1052.26838318840*t); + jupiter_x_0+= 0.00114201562 * cos( 0.01567084269 + 1162.47470440780*t); + jupiter_x_0+= 0.00072095575 * cos( 3.96117430643 + 1066.49547719000*t); + jupiter_x_0+= 0.00059486083 * cos( 4.45769374358 + 949.17560896980*t); + jupiter_x_0+= 0.00068284021 * cos( 3.44051122631 + 846.08283475120*t); + jupiter_x_0+= 0.00047092251 * cos( 1.44612636451 + 419.48464387520*t); + jupiter_x_0+= 0.00030623417 * cos( 2.99132321427 + 206.18554843720*t); + jupiter_x_0+= 0.00026613459 * cos( 4.85169906494 + 323.50541665740*t); + jupiter_x_0+= 0.00019727457 * cos( 1.64891626213 + 2118.76386037840*t); + jupiter_x_0+= 0.00016481594 * cos( 1.95150056568 + 316.39186965660*t); + jupiter_x_0+= 0.00016101974 * cos( 0.87973155980 + 515.46387109300*t); + jupiter_x_0+= 0.00014209487 * cos( 2.07769621413 + 742.99006053260*t); + jupiter_x_0+= 0.00015192516 * cos( 6.25820127906 + 735.87651353180*t); + jupiter_x_0+= 0.00011423199 * cos( 3.48146108929 + 543.91805909620*t); + jupiter_x_0+= 0.00012155285 * cos( 3.75229924999 + 525.75881183150*t); + jupiter_x_0+= 0.00011996271 * cos( 0.58568573729 + 533.62311835770*t); + + double jupiter_x_1=0.0; + jupiter_x_1+= 0.00882389251 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_x_1+= 0.00635297172 * cos( 0.10662156868 + 1059.38193018920*t); + jupiter_x_1+= 0.00599720482 * cos( 2.42996678275 + 522.57741809380*t); + jupiter_x_1+= 0.00589157060 * cos( 1.91556314637 + 536.80451209540*t); + jupiter_x_1+= 0.00081697204 * cos( 3.46668108797 + 7.11354700080*t); + jupiter_x_1+= 0.00046201898 * cos( 0.45714214032 + 1589.07289528380*t); + jupiter_x_1+= 0.00032508590 * cos( 1.74648849928 + 1052.26838318840*t); + jupiter_x_1+= 0.00033891193 * cos( 4.10113482752 + 529.69096509460*t); + jupiter_x_1+= 0.00031234303 * cos( 2.34698051502 + 1066.49547719000*t); + jupiter_x_1+= 0.00021244363 * cos( 4.36576178953 + 110.20632121940*t); + jupiter_x_1+= 0.00018156701 * cos( 4.00572238779 + 426.59819087600*t); + jupiter_x_1+= 0.00013577576 * cos( 0.30008010246 + 632.78373931320*t); + jupiter_x_1+= 0.00012889505 * cos( 2.57489294062 + 515.46387109300*t); + jupiter_x_1=jupiter_x_1 * t; + + double jupiter_x_2=0.0; + jupiter_x_2+= 0.00123864644 * cos( 4.13563277513 + 522.57741809380*t); + jupiter_x_2+= 0.00121521296 * cos( 0.21155109275 + 536.80451209540*t); + jupiter_x_2+= 0.00085355503 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_x_2+= 0.00077685547 * cos( 5.29776154458 + 529.69096509460*t); + jupiter_x_2+= 0.00041410887 * cos( 5.12291589939 + 1059.38193018920*t); + jupiter_x_2+= 0.00011423070 * cos( 1.72917878238 + 7.11354700080*t); + jupiter_x_2=jupiter_x_2 * t * t; + + double jupiter_x_3=0.0; + jupiter_x_3+= 0.00017071323 * cos( 5.86133022278 + 522.57741809380*t); + jupiter_x_3+= 0.00016713548 * cos( 4.77458794485 + 536.80451209540*t); + jupiter_x_3=jupiter_x_3 * t * t * t; + + return jupiter_x_0+jupiter_x_1+jupiter_x_2+jupiter_x_3; +} + +double vsop87a_micro_jupiter_y(double t){ + double jupiter_y_0=0.0; + jupiter_y_0+= 5.19520046589 * cos( 5.31203162731 + 529.69096509460*t); + jupiter_y_0+= 0.12592862602 * cos( 5.66160227728 + 1059.38193018920*t); + jupiter_y_0+= 0.09363670616 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_y_0+= 0.01508275299 * cos( 5.43934968102 + 522.57741809380*t); + jupiter_y_0+= 0.01475809370 * cos( 2.04679566495 + 536.80451209540*t); + jupiter_y_0+= 0.00457750806 * cos( 6.01129093501 + 1589.07289528380*t); + jupiter_y_0+= 0.00300686679 * cos( 3.60948050740 + 7.11354700080*t); + jupiter_y_0+= 0.00378285578 * cos( 3.53006782383 + 103.09277421860*t); + jupiter_y_0+= 0.00192333128 * cos( 3.45690564771 + 426.59819087600*t); + jupiter_y_0+= 0.00146104656 * cos( 4.62267224431 + 110.20632121940*t); + jupiter_y_0+= 0.00139480058 * cos( 4.00075307706 + 632.78373931320*t); + jupiter_y_0+= 0.00132696764 * cos( 5.62184581859 + 213.29909543800*t); + jupiter_y_0+= 0.00101999807 * cos( 4.57594598884 + 1052.26838318840*t); + jupiter_y_0+= 0.00114043110 * cos( 4.72982262969 + 1162.47470440780*t); + jupiter_y_0+= 0.00072091178 * cos( 2.39048659148 + 1066.49547719000*t); + jupiter_y_0+= 0.00059051769 * cos( 2.89529070968 + 949.17560896980*t); + jupiter_y_0+= 0.00068374489 * cos( 1.86537074374 + 846.08283475120*t); + jupiter_y_0+= 0.00029807369 * cos( 4.52105772740 + 206.18554843720*t); + jupiter_y_0+= 0.00026933579 * cos( 3.86233956827 + 419.48464387520*t); + jupiter_y_0+= 0.00026619714 * cos( 3.28203174951 + 323.50541665740*t); + jupiter_y_0+= 0.00020873780 * cos( 3.79369881757 + 735.87651353180*t); + jupiter_y_0+= 0.00019727397 * cos( 0.07818534532 + 2118.76386037840*t); + jupiter_y_0+= 0.00018639846 * cos( 0.38751972138 + 316.39186965660*t); + jupiter_y_0+= 0.00016355726 * cos( 5.56997881604 + 515.46387109300*t); + jupiter_y_0+= 0.00014606858 * cos( 0.47759399145 + 742.99006053260*t); + jupiter_y_0+= 0.00011419853 * cos( 1.91089341468 + 543.91805909620*t); + jupiter_y_0+= 0.00012153427 * cos( 2.18151972499 + 525.75881183150*t); + jupiter_y_0+= 0.00011988875 * cos( 5.29687602089 + 533.62311835770*t); + + double jupiter_y_1=0.0; + jupiter_y_1+= 0.01694798253 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_y_1+= 0.00634859798 * cos( 4.81903199650 + 1059.38193018920*t); + jupiter_y_1+= 0.00601160431 * cos( 0.85811249940 + 522.57741809380*t); + jupiter_y_1+= 0.00588928504 * cos( 0.34491576890 + 536.80451209540*t); + jupiter_y_1+= 0.00081187145 * cos( 1.90914316532 + 7.11354700080*t); + jupiter_y_1+= 0.00046888090 * cos( 1.91294535618 + 529.69096509460*t); + jupiter_y_1+= 0.00046194129 * cos( 5.16955994561 + 1589.07289528380*t); + jupiter_y_1+= 0.00032503453 * cos( 0.17640743623 + 1052.26838318840*t); + jupiter_y_1+= 0.00031231694 * cos( 0.77623645597 + 1066.49547719000*t); + jupiter_y_1+= 0.00019462096 * cos( 3.00957119470 + 110.20632121940*t); + jupiter_y_1+= 0.00017738615 * cos( 2.46531787101 + 426.59819087600*t); + jupiter_y_1+= 0.00013701692 * cos( 5.02070197804 + 632.78373931320*t); + jupiter_y_1+= 0.00013034616 * cos( 0.98979834442 + 515.46387109300*t); + jupiter_y_1=jupiter_y_1 * t; + + double jupiter_y_2=0.0; + jupiter_y_2+= 0.00124032509 * cos( 2.56495576833 + 522.57741809380*t); + jupiter_y_2+= 0.00121455991 * cos( 4.92398766380 + 536.80451209540*t); + jupiter_y_2+= 0.00076523263 * cos( 3.75913371793 + 529.69096509460*t); + jupiter_y_2+= 0.00076943042 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_y_2+= 0.00041357600 * cos( 3.55228440457 + 1059.38193018920*t); + jupiter_y_2+= 0.00011277667 * cos( 0.18559902389 + 7.11354700080*t); + jupiter_y_2=jupiter_y_2 * t * t; + + double jupiter_y_3=0.0; + jupiter_y_3+= 0.00017085516 * cos( 4.29096904063 + 522.57741809380*t); + jupiter_y_3+= 0.00016701353 * cos( 3.20365737109 + 536.80451209540*t); + jupiter_y_3=jupiter_y_3 * t * t * t; + + return jupiter_y_0+jupiter_y_1+jupiter_y_2+jupiter_y_3; +} + +double vsop87a_micro_jupiter_z(double t){ + double jupiter_z_0=0.0; + jupiter_z_0+= 0.11823100489 * cos( 3.55844646343 + 529.69096509460*t); + jupiter_z_0+= 0.00859031952 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_z_0+= 0.00286562094 * cos( 3.90812238338 + 1059.38193018920*t); + jupiter_z_0+= 0.00042388592 * cos( 3.60144191032 + 522.57741809380*t); + jupiter_z_0+= 0.00033295491 * cos( 0.30297050585 + 536.80451209540*t); + jupiter_z_0+= 0.00010416160 * cos( 4.25764593061 + 1589.07289528380*t); + + double jupiter_z_1=0.0; + jupiter_z_1+= 0.00407072175 * cos( 1.52699353482 + 529.69096509460*t); + jupiter_z_1+= 0.00020307341 * cos( 2.59878269248 + 1059.38193018920*t); + jupiter_z_1+= 0.00014424953 * cos( 4.85400155025 + 536.80451209540*t); + jupiter_z_1+= 0.00015474611 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_z_1+= 0.00012730364 * cos( 5.45536715732 + 522.57741809380*t); + jupiter_z_1=jupiter_z_1 * t; + + double jupiter_z_2=0.0; + jupiter_z_2+= 0.00028635326 * cos( 3.01374166973 + 529.69096509460*t); + jupiter_z_2=jupiter_z_2 * t * t; + + return jupiter_z_0+jupiter_z_1+jupiter_z_2; +} + +double vsop87a_micro_mars_x(double t){ + double mars_x_0=0.0; + mars_x_0+= 1.51769936383 * cos( 6.20403346548 + 3340.61242669980*t); + mars_x_0+= 0.19502945246 * cos( 3.14159265359 + 0.00000000000*t); + mars_x_0+= 0.07070919655 * cos( 0.25870338558 + 6681.22485339960*t); + mars_x_0+= 0.00494196914 * cos( 0.59669127768 + 10021.83728009940*t); + mars_x_0+= 0.00040938237 * cos( 0.93473307419 + 13362.44970679920*t); + mars_x_0+= 0.00021067199 * cos( 1.80435656154 + 3337.08930835080*t); + mars_x_0+= 0.00021041626 * cos( 1.17895619474 + 3344.13554504880*t); + mars_x_0+= 0.00011370375 * cos( 4.83265211109 + 1059.38193018920*t); + mars_x_0+= 0.00013527976 * cos( 0.63010765169 + 529.69096509460*t); + + double mars_x_1=0.0; + mars_x_1+= 0.00861441374 * cos( 3.14159265359 + 0.00000000000*t); + mars_x_1+= 0.00552437949 * cos( 5.09565872891 + 6681.22485339960*t); + mars_x_1+= 0.00077184977 * cos( 5.43315636209 + 10021.83728009940*t); + mars_x_1+= 0.00020467294 * cos( 5.57051812369 + 3340.61242669980*t); + mars_x_1=mars_x_1 * t; + + double mars_x_2=0.0; + mars_x_2+= 0.00056323939 * cos( 0.00000000000 + 0.00000000000*t); + mars_x_2+= 0.00022122528 * cos( 3.54372113272 + 6681.22485339960*t); + mars_x_2=mars_x_2 * t * t; + + return mars_x_0+mars_x_1+mars_x_2; +} + +double vsop87a_micro_mars_y(double t){ + double mars_y_0=0.0; + mars_y_0+= 1.51558976277 * cos( 4.63212206588 + 3340.61242669980*t); + mars_y_0+= 0.07064550239 * cos( 4.97051892902 + 6681.22485339960*t); + mars_y_0+= 0.08655481102 * cos( 0.00000000000 + 0.00000000000*t); + mars_y_0+= 0.00493872848 * cos( 5.30877806694 + 10021.83728009940*t); + mars_y_0+= 0.00040917422 * cos( 5.64698263703 + 13362.44970679920*t); + mars_y_0+= 0.00021036784 * cos( 0.23240270955 + 3337.08930835080*t); + mars_y_0+= 0.00021012921 * cos( 5.89022773653 + 3344.13554504880*t); + mars_y_0+= 0.00011370034 * cos( 3.26131408801 + 1059.38193018920*t); + mars_y_0+= 0.00013324177 * cos( 5.34259389724 + 529.69096509460*t); + + double mars_y_1=0.0; + mars_y_1+= 0.01427324210 * cos( 3.14159265359 + 0.00000000000*t); + mars_y_1+= 0.00551063753 * cos( 3.52128320402 + 6681.22485339960*t); + mars_y_1+= 0.00077091913 * cos( 3.86082685753 + 10021.83728009940*t); + mars_y_1+= 0.00037310491 * cos( 1.16016958445 + 3340.61242669980*t); + mars_y_1=mars_y_1 * t; + + double mars_y_2=0.0; + mars_y_2+= 0.00035396765 * cos( 3.14159265359 + 0.00000000000*t); + mars_y_2+= 0.00021950759 * cos( 1.96291594946 + 6681.22485339960*t); + mars_y_2=mars_y_2 * t * t; + + return mars_y_0+mars_y_1+mars_y_2; +} + +double vsop87a_micro_mars_z(double t){ + double mars_z_0=0.0; + mars_z_0+= 0.04901207220 * cos( 3.76712324286 + 3340.61242669980*t); + mars_z_0+= 0.00660669541 * cos( 0.00000000000 + 0.00000000000*t); + mars_z_0+= 0.00228333904 * cos( 4.10544022266 + 6681.22485339960*t); + mars_z_0+= 0.00015958402 * cos( 4.44367058261 + 10021.83728009940*t); + + double mars_z_1=0.0; + mars_z_1+= 0.00331842958 * cos( 6.05027773492 + 3340.61242669980*t); + mars_z_1+= 0.00047930411 * cos( 3.14159265359 + 0.00000000000*t); + mars_z_1=mars_z_1 * t; + + double mars_z_2=0.0; + mars_z_2+= 0.00013705360 * cos( 1.04212852598 + 3340.61242669980*t); + mars_z_2=mars_z_2 * t * t; + + return mars_z_0+mars_z_1+mars_z_2; +} + +double vsop87a_micro_mercury_x(double t){ + double mercury_x_0=0.0; + mercury_x_0+= 0.37546291728 * cos( 4.39651506942 + 26087.90314157420*t); + mercury_x_0+= 0.03825746672 * cos( 1.16485604339 + 52175.80628314840*t); + mercury_x_0+= 0.02625615963 * cos( 3.14159265359 + 0.00000000000*t); + mercury_x_0+= 0.00584261333 * cos( 4.21599394757 + 78263.70942472259*t); + mercury_x_0+= 0.00105716695 * cos( 0.98379033182 + 104351.61256629678*t); + mercury_x_0+= 0.00021011730 * cos( 4.03469353923 + 130439.51570787099*t); + + double mercury_x_1=0.0; + mercury_x_1+= 0.00318848034 * cos( 0.00000000000 + 0.00000000000*t); + mercury_x_1+= 0.00105289019 * cos( 5.91600475006 + 52175.80628314840*t); + mercury_x_1+= 0.00032316001 * cos( 2.68247273347 + 78263.70942472259*t); + mercury_x_1+= 0.00011992889 * cos( 5.81575112963 + 26087.90314157420*t); + mercury_x_1=mercury_x_1 * t; + + return mercury_x_0+mercury_x_1; +} + +double vsop87a_micro_mercury_y(double t){ + double mercury_y_0=0.0; + mercury_y_0+= 0.37953642888 * cos( 2.83780617820 + 26087.90314157420*t); + mercury_y_0+= 0.11626131831 * cos( 3.14159265359 + 0.00000000000*t); + mercury_y_0+= 0.03854668215 * cos( 5.88780608966 + 52175.80628314840*t); + mercury_y_0+= 0.00587711268 * cos( 2.65498896201 + 78263.70942472259*t); + mercury_y_0+= 0.00106235493 * cos( 5.70550616735 + 104351.61256629678*t); + mercury_y_0+= 0.00021100828 * cos( 2.47291315849 + 130439.51570787099*t); + + double mercury_y_1=0.0; + mercury_y_1+= 0.00107803852 * cos( 4.34964793883 + 52175.80628314840*t); + mercury_y_1+= 0.00080651544 * cos( 3.14159265359 + 0.00000000000*t); + mercury_y_1+= 0.00032715354 * cos( 1.11763734425 + 78263.70942472259*t); + mercury_y_1+= 0.00011914709 * cos( 1.22139986340 + 26087.90314157420*t); + mercury_y_1=mercury_y_1 * t; + + return mercury_y_0+mercury_y_1; +} + +double vsop87a_micro_mercury_z(double t){ + double mercury_z_0=0.0; + mercury_z_0+= 0.04607665326 * cos( 1.99295081967 + 26087.90314157420*t); + mercury_z_0+= 0.00708734365 * cos( 3.14159265359 + 0.00000000000*t); + mercury_z_0+= 0.00469171617 * cos( 5.04215742764 + 52175.80628314840*t); + mercury_z_0+= 0.00071626395 * cos( 1.80894256071 + 78263.70942472259*t); + mercury_z_0+= 0.00012957446 * cos( 4.85922032010 + 104351.61256629678*t); + + double mercury_z_1=0.0; + mercury_z_1+= 0.00108722177 * cos( 3.91134750825 + 26087.90314157420*t); + mercury_z_1+= 0.00057826621 * cos( 3.14159265359 + 0.00000000000*t); + mercury_z_1=mercury_z_1 * t; + + return mercury_z_0+mercury_z_1; +} + +double vsop87a_micro_neptune_x(double t){ + double neptune_x_0=0.0; + neptune_x_0+= 30.05890004476 * cos( 5.31211340029 + 38.13303563780*t); + neptune_x_0+= 0.27080164222 * cos( 3.14159265359 + 0.00000000000*t); + neptune_x_0+= 0.13505661755 * cos( 3.50078975634 + 76.26607127560*t); + neptune_x_0+= 0.15726094556 * cos( 0.11319072675 + 36.64856292950*t); + neptune_x_0+= 0.14935120126 * cos( 1.08499403018 + 39.61750834610*t); + neptune_x_0+= 0.02597313814 * cos( 1.99590301412 + 1.48447270830*t); + neptune_x_0+= 0.01074040708 * cos( 5.38502938672 + 74.78159856730*t); + neptune_x_0+= 0.00823793287 * cos( 1.43221581862 + 35.16409022120*t); + neptune_x_0+= 0.00817588813 * cos( 0.78180174031 + 2.96894541660*t); + neptune_x_0+= 0.00565534918 * cos( 5.98964907613 + 41.10198105440*t); + neptune_x_0+= 0.00495719107 * cos( 0.59948143567 + 529.69096509460*t); + neptune_x_0+= 0.00307525907 * cos( 0.40023311011 + 73.29712585900*t); + neptune_x_0+= 0.00272253551 * cos( 0.87443494387 + 213.29909543800*t); + neptune_x_0+= 0.00135887219 * cos( 5.54676577816 + 77.75054398390*t); + neptune_x_0+= 0.00090965704 * cos( 1.68910246115 + 114.39910691340*t); + neptune_x_0+= 0.00069040539 * cos( 5.83469123520 + 4.45341812490*t); + neptune_x_0+= 0.00060813556 * cos( 2.62589958380 + 33.67961751290*t); + neptune_x_0+= 0.00054690827 * cos( 1.55799996661 + 71.81265315070*t); + neptune_x_0+= 0.00028889260 * cos( 4.78966826027 + 42.58645376270*t); + neptune_x_0+= 0.00012614732 * cos( 3.57002516434 + 112.91463420510*t); + neptune_x_0+= 0.00012749153 * cos( 2.73719269645 + 111.43016149680*t); + neptune_x_0+= 0.00012013994 * cos( 0.94912933496 + 1059.38193018920*t); + + double neptune_x_1=0.0; + neptune_x_1+= 0.00255840261 * cos( 2.01935686795 + 36.64856292950*t); + neptune_x_1+= 0.00243125299 * cos( 5.46214902873 + 39.61750834610*t); + neptune_x_1+= 0.00118398168 * cos( 2.88251845061 + 76.26607127560*t); + neptune_x_1+= 0.00037965449 * cos( 3.14159265359 + 0.00000000000*t); + neptune_x_1+= 0.00021924705 * cos( 3.20156164152 + 35.16409022120*t); + neptune_x_1+= 0.00017459808 * cos( 4.26349398817 + 41.10198105440*t); + neptune_x_1+= 0.00013130617 * cos( 5.36424961848 + 2.96894541660*t); + neptune_x_1=neptune_x_1 * t; + + return neptune_x_0+neptune_x_1; +} + +double vsop87a_micro_neptune_y(double t){ + double neptune_y_0=0.0; + neptune_y_0+= 30.06056351665 * cos( 3.74086294714 + 38.13303563780*t); + neptune_y_0+= 0.30205857683 * cos( 3.14159265359 + 0.00000000000*t); + neptune_y_0+= 0.13506391797 * cos( 1.92953034883 + 76.26607127560*t); + neptune_y_0+= 0.15706589373 * cos( 4.82539970129 + 36.64856292950*t); + neptune_y_0+= 0.14936165806 * cos( 5.79694900665 + 39.61750834610*t); + neptune_y_0+= 0.02584250749 * cos( 0.42549700754 + 1.48447270830*t); + neptune_y_0+= 0.01073739772 * cos( 3.81371728533 + 74.78159856730*t); + neptune_y_0+= 0.00815187583 * cos( 5.49429775826 + 2.96894541660*t); + neptune_y_0+= 0.00582199295 * cos( 6.19633718936 + 35.16409022120*t); + neptune_y_0+= 0.00565576412 * cos( 4.41843009015 + 41.10198105440*t); + neptune_y_0+= 0.00495581047 * cos( 5.31205825784 + 529.69096509460*t); + neptune_y_0+= 0.00304525203 * cos( 5.11048113661 + 73.29712585900*t); + neptune_y_0+= 0.00272640298 * cos( 5.58603690785 + 213.29909543800*t); + neptune_y_0+= 0.00135897385 * cos( 3.97553750964 + 77.75054398390*t); + neptune_y_0+= 0.00090970871 * cos( 0.11783619888 + 114.39910691340*t); + neptune_y_0+= 0.00068790261 * cos( 4.26391997151 + 4.45341812490*t); + neptune_y_0+= 0.00028893355 * cos( 3.21848975032 + 42.58645376270*t); + neptune_y_0+= 0.00020081559 * cos( 1.19787916085 + 33.67961751290*t); + neptune_y_0+= 0.00012613583 * cos( 1.99777332934 + 112.91463420510*t); + neptune_y_0+= 0.00012828708 * cos( 1.16740053443 + 111.43016149680*t); + neptune_y_0+= 0.00012012961 * cos( 5.66157563804 + 1059.38193018920*t); + + double neptune_y_1=0.0; + neptune_y_1+= 0.00352947493 * cos( 3.14159265359 + 0.00000000000*t); + neptune_y_1+= 0.00256125493 * cos( 0.44757496817 + 36.64856292950*t); + neptune_y_1+= 0.00243147725 * cos( 3.89099798696 + 39.61750834610*t); + neptune_y_1+= 0.00118427205 * cos( 1.31128027037 + 76.26607127560*t); + neptune_y_1+= 0.00021936702 * cos( 1.63124087591 + 35.16409022120*t); + neptune_y_1+= 0.00017462332 * cos( 2.69229902966 + 41.10198105440*t); + neptune_y_1+= 0.00012992380 * cos( 3.79578633002 + 2.96894541660*t); + neptune_y_1=neptune_y_1 * t; + + return neptune_y_0+neptune_y_1; +} + +double vsop87a_micro_neptune_z(double t){ + double neptune_z_0=0.0; + neptune_z_0+= 0.92866054405 * cos( 1.44103930278 + 38.13303563780*t); + neptune_z_0+= 0.01245978462 * cos( 0.00000000000 + 0.00000000000*t); + neptune_z_0+= 0.00474333567 * cos( 2.52218774238 + 36.64856292950*t); + neptune_z_0+= 0.00451987936 * cos( 3.50949720541 + 39.61750834610*t); + neptune_z_0+= 0.00417558068 * cos( 5.91310695421 + 76.26607127560*t); + neptune_z_0+= 0.00084104329 * cos( 4.38928900096 + 1.48447270830*t); + neptune_z_0+= 0.00032704958 * cos( 1.52048692001 + 74.78159856730*t); + neptune_z_0+= 0.00030873335 * cos( 3.29017611456 + 35.16409022120*t); + neptune_z_0+= 0.00025812584 * cos( 3.19303128782 + 2.96894541660*t); + neptune_z_0+= 0.00016865319 * cos( 2.13251104425 + 41.10198105440*t); + neptune_z_0+= 0.00011789909 * cos( 3.60001877675 + 213.29909543800*t); + neptune_z_0+= 0.00011279680 * cos( 3.55816676334 + 529.69096509460*t); + + double neptune_z_1=0.0; + neptune_z_1+= 0.00154885971 * cos( 2.14239039664 + 38.13303563780*t); + neptune_z_1=neptune_z_1 * t; + + return neptune_z_0+neptune_z_1; +} + +double vsop87a_micro_saturn_x(double t){ + double saturn_x_0=0.0; + saturn_x_0+= 9.51638335797 * cos( 0.87441380794 + 213.29909543800*t); + saturn_x_0+= 0.26412374238 * cos( 0.12390892620 + 426.59819087600*t); + saturn_x_0+= 0.06760430339 * cos( 4.16767145778 + 206.18554843720*t); + saturn_x_0+= 0.06624260115 * cos( 0.75094737780 + 220.41264243880*t); + saturn_x_0+= 0.04244797817 * cos( 0.00000000000 + 0.00000000000*t); + saturn_x_0+= 0.02336340488 * cos( 2.02227784673 + 7.11354700080*t); + saturn_x_0+= 0.01255372247 * cos( 2.17338917731 + 110.20632121940*t); + saturn_x_0+= 0.01115684467 * cos( 3.15686878377 + 419.48464387520*t); + saturn_x_0+= 0.01097683232 * cos( 5.65753337256 + 639.89728631400*t); + saturn_x_0+= 0.00716328481 * cos( 2.71149993708 + 316.39186965660*t); + saturn_x_0+= 0.00509313365 * cos( 4.95865624780 + 103.09277421860*t); + saturn_x_0+= 0.00433994439 * cos( 0.72012820974 + 529.69096509460*t); + saturn_x_0+= 0.00372894461 * cos( 0.00137195497 + 433.71173787680*t); + saturn_x_0+= 0.00097843523 * cos( 1.01485750417 + 323.50541665740*t); + saturn_x_0+= 0.00080600536 * cos( 5.62103979796 + 11.04570026390*t); + saturn_x_0+= 0.00083782316 * cos( 0.62038893702 + 227.52618943960*t); + saturn_x_0+= 0.00074150224 * cos( 2.38206066655 + 632.78373931320*t); + saturn_x_0+= 0.00070219382 * cos( 0.88789752415 + 209.36694217490*t); + saturn_x_0+= 0.00068855792 * cos( 4.01788097627 + 217.23124870110*t); + saturn_x_0+= 0.00065620467 * cos( 2.69728593339 + 202.25339517410*t); + saturn_x_0+= 0.00058297911 * cos( 2.16155251399 + 224.34479570190*t); + saturn_x_0+= 0.00054022837 * cos( 4.90928184374 + 853.19638175200*t); + saturn_x_0+= 0.00045550446 * cos( 1.88235037830 + 14.22709400160*t); + saturn_x_0+= 0.00038345667 * cos( 4.39815501478 + 199.07200143640*t); + saturn_x_0+= 0.00044551703 * cos( 5.60763553535 + 63.73589830340*t); + saturn_x_0+= 0.00025165185 * cos( 0.37800582257 + 216.48048917570*t); + saturn_x_0+= 0.00024554499 * cos( 4.53150598095 + 210.11770170030*t); + saturn_x_0+= 0.00024673219 * cos( 5.90891573850 + 522.57741809380*t); + saturn_x_0+= 0.00024677050 * cos( 5.60389382420 + 415.55249061210*t); + saturn_x_0+= 0.00025491374 * cos( 1.63922423181 + 117.31986822020*t); + saturn_x_0+= 0.00031253049 * cos( 4.62976601833 + 735.87651353180*t); + saturn_x_0+= 0.00023372467 * cos( 5.53491987276 + 647.01083331480*t); + saturn_x_0+= 0.00023355468 * cos( 0.18791490124 + 149.56319713460*t); + saturn_x_0+= 0.00024805815 * cos( 5.50327676733 + 74.78159856730*t); + saturn_x_0+= 0.00014731703 * cos( 4.67981909838 + 277.03499374140*t); + saturn_x_0+= 0.00012427525 * cos( 1.02995545746 + 1059.38193018920*t); + saturn_x_0+= 0.00012393514 * cos( 4.19747622821 + 490.33408917940*t); + saturn_x_0+= 0.00012026472 * cos( 5.66372282839 + 351.81659230870*t); + + double saturn_x_1=0.0; + saturn_x_1+= 0.07575103962 * cos( 0.00000000000 + 0.00000000000*t); + saturn_x_1+= 0.03085041716 * cos( 4.27565749128 + 426.59819087600*t); + saturn_x_1+= 0.02714918399 * cos( 5.85229412397 + 206.18554843720*t); + saturn_x_1+= 0.02643100909 * cos( 5.33291950584 + 220.41264243880*t); + saturn_x_1+= 0.00627104520 * cos( 0.32898307969 + 7.11354700080*t); + saturn_x_1+= 0.00256560953 * cos( 3.52478934343 + 639.89728631400*t); + saturn_x_1+= 0.00312356512 * cos( 4.83001724941 + 419.48464387520*t); + saturn_x_1+= 0.00189196274 * cos( 4.48642453552 + 433.71173787680*t); + saturn_x_1+= 0.00203646570 * cos( 1.10998681782 + 213.29909543800*t); + saturn_x_1+= 0.00119531145 * cos( 1.14735096078 + 110.20632121940*t); + saturn_x_1+= 0.00066764238 * cos( 3.72346596928 + 316.39186965660*t); + saturn_x_1+= 0.00066901225 * cos( 5.20257500380 + 227.52618943960*t); + saturn_x_1+= 0.00031000840 * cos( 6.06067919437 + 199.07200143640*t); + saturn_x_1+= 0.00030418100 * cos( 0.18746903351 + 14.22709400160*t); + saturn_x_1+= 0.00022275210 * cos( 6.19530878014 + 103.09277421860*t); + saturn_x_1+= 0.00018939377 * cos( 2.77618306725 + 853.19638175200*t); + saturn_x_1+= 0.00018093009 * cos( 5.09162723865 + 209.36694217490*t); + saturn_x_1+= 0.00017777854 * cos( 6.10381593351 + 217.23124870110*t); + saturn_x_1+= 0.00016296201 * cos( 4.86945681437 + 216.48048917570*t); + saturn_x_1+= 0.00017120250 * cos( 4.59611664188 + 632.78373931320*t); + saturn_x_1+= 0.00015894491 * cos( 0.03653502304 + 210.11770170030*t); + saturn_x_1+= 0.00016192653 * cos( 5.60798014450 + 323.50541665740*t); + saturn_x_1+= 0.00014466010 * cos( 3.67449380090 + 647.01083331480*t); + saturn_x_1+= 0.00011061528 * cos( 0.03163071461 + 117.31986822020*t); + saturn_x_1=saturn_x_1 * t; + + double saturn_x_2=0.0; + saturn_x_2+= 0.00560746334 * cos( 1.26401632282 + 206.18554843720*t); + saturn_x_2+= 0.00545834518 * cos( 3.62343709657 + 220.41264243880*t); + saturn_x_2+= 0.00443342186 * cos( 3.14159265359 + 0.00000000000*t); + saturn_x_2+= 0.00336109713 * cos( 2.42547432460 + 213.29909543800*t); + saturn_x_2+= 0.00224302269 * cos( 2.49151203519 + 426.59819087600*t); + saturn_x_2+= 0.00087170924 * cos( 4.89048951691 + 7.11354700080*t); + saturn_x_2+= 0.00050028094 * cos( 2.70119046081 + 433.71173787680*t); + saturn_x_2+= 0.00045122590 * cos( 0.36735068943 + 419.48464387520*t); + saturn_x_2+= 0.00032847824 * cos( 1.59210153669 + 639.89728631400*t); + saturn_x_2+= 0.00027153555 * cos( 3.49804002218 + 227.52618943960*t); + saturn_x_2+= 0.00012676167 * cos( 1.45465729530 + 199.07200143640*t); + saturn_x_2+= 0.00010330738 * cos( 4.76949531290 + 14.22709400160*t); + saturn_x_2=saturn_x_2 * t * t; + + double saturn_x_3=0.0; + saturn_x_3+= 0.00077115952 * cos( 2.97714385362 + 206.18554843720*t); + saturn_x_3+= 0.00075340436 * cos( 1.89208005248 + 220.41264243880*t); + saturn_x_3+= 0.00018450895 * cos( 3.14159265359 + 0.00000000000*t); + saturn_x_3+= 0.00010527244 * cos( 0.66368256891 + 426.59819087600*t); + saturn_x_3=saturn_x_3 * t * t * t; + + return saturn_x_0+saturn_x_1+saturn_x_2+saturn_x_3; +} + +double vsop87a_micro_saturn_y(double t){ + double saturn_y_0=0.0; + saturn_y_0+= 9.52986882699 * cos( 5.58600556665 + 213.29909543800*t); + saturn_y_0+= 0.79387988806 * cos( 3.14159265359 + 0.00000000000*t); + saturn_y_0+= 0.26441781302 * cos( 4.83528061849 + 426.59819087600*t); + saturn_y_0+= 0.06916653915 * cos( 2.55279408706 + 206.18554843720*t); + saturn_y_0+= 0.06633570703 * cos( 5.46258848288 + 220.41264243880*t); + saturn_y_0+= 0.02345609742 * cos( 0.44652132519 + 7.11354700080*t); + saturn_y_0+= 0.01183874652 * cos( 1.34638298371 + 419.48464387520*t); + saturn_y_0+= 0.01245790434 * cos( 0.60367177975 + 110.20632121940*t); + saturn_y_0+= 0.01098751131 * cos( 4.08608782813 + 639.89728631400*t); + saturn_y_0+= 0.00700849336 * cos( 1.13611298025 + 316.39186965660*t); + saturn_y_0+= 0.00434466176 * cos( 5.42474696262 + 529.69096509460*t); + saturn_y_0+= 0.00373327342 * cos( 4.71308726958 + 433.71173787680*t); + saturn_y_0+= 0.00335162363 * cos( 0.66422253983 + 103.09277421860*t); + saturn_y_0+= 0.00097837745 * cos( 5.72844290173 + 323.50541665740*t); + saturn_y_0+= 0.00080571808 * cos( 4.05295449910 + 11.04570026390*t); + saturn_y_0+= 0.00083899691 * cos( 5.33204070267 + 227.52618943960*t); + saturn_y_0+= 0.00070158491 * cos( 5.59777963629 + 209.36694217490*t); + saturn_y_0+= 0.00065937657 * cos( 1.25969608208 + 202.25339517410*t); + saturn_y_0+= 0.00070957225 * cos( 0.88888207567 + 632.78373931320*t); + saturn_y_0+= 0.00068985859 * cos( 2.44460312617 + 217.23124870110*t); + saturn_y_0+= 0.00058382264 * cos( 0.58978766922 + 224.34479570190*t); + saturn_y_0+= 0.00054049836 * cos( 3.33757904879 + 853.19638175200*t); + saturn_y_0+= 0.00045790930 * cos( 0.30331527632 + 14.22709400160*t); + saturn_y_0+= 0.00041976402 * cos( 2.62591355948 + 199.07200143640*t); + saturn_y_0+= 0.00044697175 * cos( 0.90661238256 + 63.73589830340*t); + saturn_y_0+= 0.00025199575 * cos( 5.08963506006 + 216.48048917570*t); + saturn_y_0+= 0.00024640836 * cos( 2.95445247282 + 210.11770170030*t); + saturn_y_0+= 0.00024835151 * cos( 4.02630190571 + 415.55249061210*t); + saturn_y_0+= 0.00025545907 * cos( 0.06626229252 + 117.31986822020*t); + saturn_y_0+= 0.00029666833 * cos( 6.09910638345 + 735.87651353180*t); + saturn_y_0+= 0.00023396742 * cos( 3.96337393635 + 647.01083331480*t); + saturn_y_0+= 0.00023380691 * cos( 4.90051072276 + 149.56319713460*t); + saturn_y_0+= 0.00020272215 * cos( 2.34319548198 + 309.27832265580*t); + saturn_y_0+= 0.00020099552 * cos( 0.98365186365 + 522.57741809380*t); + saturn_y_0+= 0.00024827950 * cos( 3.92681428900 + 74.78159856730*t); + saturn_y_0+= 0.00015383927 * cos( 3.10227822627 + 277.03499374140*t); + saturn_y_0+= 0.00011629210 * cos( 5.74108283772 + 1059.38193018920*t); + saturn_y_0+= 0.00012422966 * cos( 2.62557865743 + 490.33408917940*t); + saturn_y_0+= 0.00012048048 * cos( 4.09265980116 + 351.81659230870*t); + + double saturn_y_1=0.0; + saturn_y_1+= 0.05373889135 * cos( 0.00000000000 + 0.00000000000*t); + saturn_y_1+= 0.03090575152 * cos( 2.70346890906 + 426.59819087600*t); + saturn_y_1+= 0.02741594312 * cos( 4.26667636015 + 206.18554843720*t); + saturn_y_1+= 0.02647489677 * cos( 3.76132298889 + 220.41264243880*t); + saturn_y_1+= 0.00631520527 * cos( 5.03245505280 + 7.11354700080*t); + saturn_y_1+= 0.00256799701 * cos( 1.95351819758 + 639.89728631400*t); + saturn_y_1+= 0.00312271930 * cos( 3.25850205023 + 419.48464387520*t); + saturn_y_1+= 0.00189433319 * cos( 2.91501840819 + 433.71173787680*t); + saturn_y_1+= 0.00164133553 * cos( 5.29239290066 + 213.29909543800*t); + saturn_y_1+= 0.00116791227 * cos( 5.89146675760 + 110.20632121940*t); + saturn_y_1+= 0.00067210919 * cos( 2.17042636344 + 316.39186965660*t); + saturn_y_1+= 0.00067003292 * cos( 3.63101075514 + 227.52618943960*t); + saturn_y_1+= 0.00033002406 * cos( 4.35527405801 + 199.07200143640*t); + saturn_y_1+= 0.00030628998 * cos( 4.88861760772 + 14.22709400160*t); + saturn_y_1+= 0.00022234714 * cos( 4.62212779231 + 103.09277421860*t); + saturn_y_1+= 0.00018945004 * cos( 1.20412493845 + 853.19638175200*t); + saturn_y_1+= 0.00018079959 * cos( 3.51566153251 + 209.36694217490*t); + saturn_y_1+= 0.00017791543 * cos( 4.53214140649 + 217.23124870110*t); + saturn_y_1+= 0.00016320701 * cos( 3.29784030970 + 216.48048917570*t); + saturn_y_1+= 0.00015944258 * cos( 4.74503265169 + 210.11770170030*t); + saturn_y_1+= 0.00016717122 * cos( 3.00270792752 + 632.78373931320*t); + saturn_y_1+= 0.00016149947 * cos( 4.04186432517 + 323.50541665740*t); + saturn_y_1+= 0.00014481431 * cos( 2.10298298650 + 647.01083331480*t); + saturn_y_1+= 0.00011084040 * cos( 4.74073871754 + 117.31986822020*t); + saturn_y_1=saturn_y_1 * t; + + double saturn_y_2=0.0; + saturn_y_2+= 0.00563706537 * cos( 5.97115878242 + 206.18554843720*t); + saturn_y_2+= 0.00547012116 * cos( 2.05154973426 + 220.41264243880*t); + saturn_y_2+= 0.00458518613 * cos( 0.00000000000 + 0.00000000000*t); + saturn_y_2+= 0.00362294249 * cos( 0.89540100509 + 213.29909543800*t); + saturn_y_2+= 0.00225521642 * cos( 0.91699821445 + 426.59819087600*t); + saturn_y_2+= 0.00088390611 * cos( 3.30289449917 + 7.11354700080*t); + saturn_y_2+= 0.00050101314 * cos( 1.12976163835 + 433.71173787680*t); + saturn_y_2+= 0.00045516403 * cos( 5.07669466539 + 419.48464387520*t); + saturn_y_2+= 0.00032896745 * cos( 0.02089057938 + 639.89728631400*t); + saturn_y_2+= 0.00027199743 * cos( 1.92638417640 + 227.52618943960*t); + saturn_y_2+= 0.00013251505 * cos( 6.07693099404 + 199.07200143640*t); + saturn_y_2+= 0.00010425984 * cos( 3.18246869028 + 14.22709400160*t); + saturn_y_2=saturn_y_2 * t * t; + + double saturn_y_3=0.0; + saturn_y_3+= 0.00077376615 * cos( 1.40391048961 + 206.18554843720*t); + saturn_y_3+= 0.00075564351 * cos( 0.31962896379 + 220.41264243880*t); + saturn_y_3+= 0.00022843837 * cos( 3.14159265359 + 0.00000000000*t); + saturn_y_3+= 0.00010672263 * cos( 5.36495663820 + 426.59819087600*t); + saturn_y_3=saturn_y_3 * t * t * t; + + return saturn_y_0+saturn_y_1+saturn_y_2+saturn_y_3; +} + +double vsop87a_micro_saturn_z(double t){ + double saturn_z_0=0.0; + saturn_z_0+= 0.41356950940 * cos( 3.60234142982 + 213.29909543800*t); + saturn_z_0+= 0.01148283576 * cos( 2.85128367469 + 426.59819087600*t); + saturn_z_0+= 0.01214249867 * cos( 0.00000000000 + 0.00000000000*t); + saturn_z_0+= 0.00329280791 * cos( 0.57121407104 + 206.18554843720*t); + saturn_z_0+= 0.00286934048 * cos( 3.48073526693 + 220.41264243880*t); + saturn_z_0+= 0.00099076584 * cos( 4.73369511264 + 7.11354700080*t); + saturn_z_0+= 0.00057361820 * cos( 4.92611225093 + 110.20632121940*t); + saturn_z_0+= 0.00047738127 * cos( 2.10039779728 + 639.89728631400*t); + saturn_z_0+= 0.00043458803 * cos( 5.84904978051 + 419.48464387520*t); + saturn_z_0+= 0.00034565673 * cos( 5.42614229590 + 316.39186965660*t); + saturn_z_0+= 0.00016185391 * cos( 2.72987173675 + 433.71173787680*t); + saturn_z_0+= 0.00011433574 * cos( 3.71662021072 + 529.69096509460*t); + + double saturn_z_1=0.0; + saturn_z_1+= 0.01906503283 * cos( 4.94544746116 + 213.29909543800*t); + saturn_z_1+= 0.00528301265 * cos( 3.14159265359 + 0.00000000000*t); + saturn_z_1+= 0.00130262284 * cos( 2.26140980879 + 206.18554843720*t); + saturn_z_1+= 0.00101466332 * cos( 1.79095829545 + 220.41264243880*t); + saturn_z_1+= 0.00085947578 * cos( 0.51612788497 + 426.59819087600*t); + saturn_z_1+= 0.00022257446 * cos( 3.07684015656 + 7.11354700080*t); + saturn_z_1+= 0.00016179946 * cos( 1.19987517506 + 419.48464387520*t); + saturn_z_1=saturn_z_1 * t; + + double saturn_z_2=0.0; + saturn_z_2+= 0.00131275155 * cos( 0.08868998101 + 213.29909543800*t); + saturn_z_2+= 0.00030147649 * cos( 3.91396203887 + 206.18554843720*t); + saturn_z_2+= 0.00019322173 * cos( 0.09228748624 + 220.41264243880*t); + saturn_z_2=saturn_z_2 * t * t; + + return saturn_z_0+saturn_z_1+saturn_z_2; +} + +double vsop87a_micro_uranus_x(double t){ + double uranus_x_0=0.0; + uranus_x_0+= 19.17370730359 * cos( 5.48133416489 + 74.78159856730*t); + uranus_x_0+= 1.32272523872 * cos( 0.00000000000 + 0.00000000000*t); + uranus_x_0+= 0.44402496796 * cos( 1.65967519586 + 149.56319713460*t); + uranus_x_0+= 0.14668209481 * cos( 3.42395862804 + 73.29712585900*t); + uranus_x_0+= 0.14130269479 * cos( 4.39572927934 + 76.26607127560*t); + uranus_x_0+= 0.06201106178 * cos( 5.14043574125 + 1.48447270830*t); + uranus_x_0+= 0.01542951343 * cos( 4.12121838072 + 224.34479570190*t); + uranus_x_0+= 0.01444216660 * cos( 2.65117115201 + 148.07872442630*t); + uranus_x_0+= 0.00944995563 * cos( 1.65869338757 + 11.04570026390*t); + uranus_x_0+= 0.00657524815 * cos( 0.57595170636 + 151.04766984290*t); + uranus_x_0+= 0.00621624676 * cos( 3.05882246638 + 77.75054398390*t); + uranus_x_0+= 0.00585182542 * cos( 4.79934779678 + 71.81265315070*t); + uranus_x_0+= 0.00634000270 * cos( 4.09556589724 + 63.73589830340*t); + uranus_x_0+= 0.00547699056 * cos( 3.63127725056 + 85.82729883120*t); + uranus_x_0+= 0.00458219984 * cos( 3.90788284112 + 2.96894541660*t); + uranus_x_0+= 0.00496087649 * cos( 0.59947400861 + 529.69096509460*t); + uranus_x_0+= 0.00383625535 * cos( 6.18762010576 + 138.51749687070*t); + uranus_x_0+= 0.00267938156 * cos( 0.96885660137 + 213.29909543800*t); + uranus_x_0+= 0.00215368005 * cos( 5.30877641428 + 38.13303563780*t); + uranus_x_0+= 0.00145505389 * cos( 2.31759757085 + 70.84944530420*t); + uranus_x_0+= 0.00135340032 * cos( 5.51062460816 + 78.71375183040*t); + uranus_x_0+= 0.00119593859 * cos( 4.10138544267 + 39.61750834610*t); + uranus_x_0+= 0.00125105686 * cos( 2.51455273063 + 111.43016149680*t); + uranus_x_0+= 0.00111260244 * cos( 5.12252784325 + 222.86032299360*t); + uranus_x_0+= 0.00104619827 * cos( 3.90538916334 + 146.59425171800*t); + uranus_x_0+= 0.00110125387 * cos( 4.45473528724 + 35.16409022120*t); + uranus_x_0+= 0.00063584588 * cos( 0.29966233158 + 299.12639426920*t); + uranus_x_0+= 0.00053904041 * cos( 3.92590422507 + 3.93215326310*t); + uranus_x_0+= 0.00065066905 * cos( 3.73008452906 + 109.94568878850*t); + uranus_x_0+= 0.00039181662 * cos( 2.68841280769 + 4.45341812490*t); + uranus_x_0+= 0.00034341683 * cos( 3.03781661928 + 225.82926841020*t); + uranus_x_0+= 0.00033134636 * cos( 2.54201591218 + 65.22037101170*t); + uranus_x_0+= 0.00034555652 * cos( 1.84699329257 + 79.23501669220*t); + uranus_x_0+= 0.00033867050 * cos( 5.98418436103 + 70.32818044240*t); + uranus_x_0+= 0.00028371614 * cos( 2.58026657123 + 127.47179660680*t); + uranus_x_0+= 0.00035943348 * cos( 4.08754543016 + 202.25339517410*t); + uranus_x_0+= 0.00025208833 * cos( 5.30272144657 + 9.56122755560*t); + uranus_x_0+= 0.00023467802 * cos( 4.09729860322 + 145.63104387150*t); + uranus_x_0+= 0.00022963939 * cos( 5.51475073655 + 84.34282612290*t); + uranus_x_0+= 0.00031823951 * cos( 5.53948583244 + 152.53214255120*t); + uranus_x_0+= 0.00028384953 * cos( 6.01785430306 + 184.72728735580*t); + uranus_x_0+= 0.00026657176 * cos( 6.11027939727 + 160.60889739850*t); + uranus_x_0+= 0.00019676762 * cos( 5.53431398332 + 74.66972398270*t); + uranus_x_0+= 0.00019653873 * cos( 2.28660913421 + 74.89347315190*t); + uranus_x_0+= 0.00019954280 * cos( 0.57450958037 + 12.53017297220*t); + uranus_x_0+= 0.00018565067 * cos( 0.62225019017 + 52.69019803950*t); + uranus_x_0+= 0.00020084756 * cos( 4.47297488471 + 22.09140052780*t); + uranus_x_0+= 0.00019926329 * cos( 1.39878194708 + 112.91463420510*t); + uranus_x_0+= 0.00018575632 * cos( 5.70217475790 + 33.67961751290*t); + uranus_x_0+= 0.00016587870 * cos( 4.86920309163 + 108.46121608020*t); + uranus_x_0+= 0.00015171194 * cos( 2.88415453399 + 41.10198105440*t); + uranus_x_0+= 0.00011245800 * cos( 6.11597016146 + 71.60020482960*t); + uranus_x_0+= 0.00013948521 * cos( 6.27545694160 + 221.37585028530*t); + uranus_x_0+= 0.00010798350 * cos( 1.70031857078 + 77.96299230500*t); + uranus_x_0+= 0.00013593955 * cos( 2.55407820633 + 87.31177153950*t); + uranus_x_0+= 0.00011997848 * cos( 0.94875212305 + 1059.38193018920*t); + uranus_x_0+= 0.00012884351 * cos( 5.08737999470 + 145.10977900970*t); + uranus_x_0+= 0.00012394786 * cos( 6.21892878850 + 72.33391801250*t); + uranus_x_0+= 0.00012253318 * cos( 0.19452856525 + 36.64856292950*t); + uranus_x_0+= 0.00011538642 * cos( 1.77241794539 + 77.22927912210*t); + + double uranus_x_1=0.0; + uranus_x_1+= 0.00739730021 * cos( 6.01067825116 + 149.56319713460*t); + uranus_x_1+= 0.00526878306 * cos( 3.14159265359 + 0.00000000000*t); + uranus_x_1+= 0.00239840801 * cos( 5.33657762707 + 73.29712585900*t); + uranus_x_1+= 0.00229676787 * cos( 2.48204455775 + 76.26607127560*t); + uranus_x_1+= 0.00111045158 * cos( 5.57157235960 + 11.04570026390*t); + uranus_x_1+= 0.00096352822 * cos( 0.35070389084 + 63.73589830340*t); + uranus_x_1+= 0.00081511870 * cos( 1.21058618039 + 85.82729883120*t); + uranus_x_1+= 0.00045687564 * cos( 2.29216583843 + 138.51749687070*t); + uranus_x_1+= 0.00051382501 * cos( 2.18935125260 + 224.34479570190*t); + uranus_x_1+= 0.00038844330 * cos( 0.30724575951 + 70.84944530420*t); + uranus_x_1+= 0.00036158493 * cos( 1.23634798757 + 78.71375183040*t); + uranus_x_1+= 0.00032333094 * cos( 5.06666556704 + 74.78159856730*t); + uranus_x_1+= 0.00021685656 * cos( 4.93710968392 + 151.04766984290*t); + uranus_x_1+= 0.00019441970 * cos( 1.30617490304 + 77.75054398390*t); + uranus_x_1+= 0.00017376241 * cos( 0.24607221230 + 71.81265315070*t); + uranus_x_1+= 0.00015211071 * cos( 5.53141633140 + 3.93215326310*t); + uranus_x_1=uranus_x_1 * t; + + double uranus_x_2=0.0; + uranus_x_2+= 0.00016015732 * cos( 3.83700026619 + 74.78159856730*t); + uranus_x_2+= 0.00010915299 * cos( 3.02987776270 + 149.56319713460*t); + uranus_x_2=uranus_x_2 * t * t; + + return uranus_x_0+uranus_x_1+uranus_x_2; +} + +double vsop87a_micro_uranus_y(double t){ + double uranus_y_0=0.0; + uranus_y_0+= 19.16518231584 * cos( 3.91045677002 + 74.78159856730*t); + uranus_y_0+= 0.44390465203 * cos( 0.08884111329 + 149.56319713460*t); + uranus_y_0+= 0.16256125476 * cos( 3.14159265359 + 0.00000000000*t); + uranus_y_0+= 0.14755940186 * cos( 1.85423280679 + 73.29712585900*t); + uranus_y_0+= 0.14123958128 * cos( 2.82486076549 + 76.26607127560*t); + uranus_y_0+= 0.06250078231 * cos( 3.56960243857 + 1.48447270830*t); + uranus_y_0+= 0.01542668264 * cos( 2.55040539213 + 224.34479570190*t); + uranus_y_0+= 0.01442356575 * cos( 1.08004542712 + 148.07872442630*t); + uranus_y_0+= 0.00938975501 * cos( 0.09275714761 + 11.04570026390*t); + uranus_y_0+= 0.00650331846 * cos( 2.76142680222 + 63.73589830340*t); + uranus_y_0+= 0.00657343120 * cos( 5.28830704469 + 151.04766984290*t); + uranus_y_0+= 0.00621326770 * cos( 1.48795811387 + 77.75054398390*t); + uranus_y_0+= 0.00541961958 * cos( 3.24476486661 + 71.81265315070*t); + uranus_y_0+= 0.00547472694 * cos( 2.06037924573 + 85.82729883120*t); + uranus_y_0+= 0.00459589120 * cos( 2.33745536070 + 2.96894541660*t); + uranus_y_0+= 0.00495936105 * cos( 5.31205753740 + 529.69096509460*t); + uranus_y_0+= 0.00387922853 * cos( 4.62026923885 + 138.51749687070*t); + uranus_y_0+= 0.00268363417 * cos( 5.68085299020 + 213.29909543800*t); + uranus_y_0+= 0.00216239629 * cos( 3.73800767580 + 38.13303563780*t); + uranus_y_0+= 0.00144032475 * cos( 0.75015700920 + 70.84944530420*t); + uranus_y_0+= 0.00135290820 * cos( 3.93970260616 + 78.71375183040*t); + uranus_y_0+= 0.00119670613 * cos( 2.53058783780 + 39.61750834610*t); + uranus_y_0+= 0.00124868545 * cos( 0.94315917319 + 111.43016149680*t); + uranus_y_0+= 0.00111204860 * cos( 3.55163219419 + 222.86032299360*t); + uranus_y_0+= 0.00104507929 * cos( 2.33345675603 + 146.59425171800*t); + uranus_y_0+= 0.00108584454 * cos( 6.02234848388 + 35.16409022120*t); + uranus_y_0+= 0.00063573747 * cos( 5.01204967920 + 299.12639426920*t); + uranus_y_0+= 0.00053289771 * cos( 2.38437587876 + 3.93215326310*t); + uranus_y_0+= 0.00063774261 * cos( 2.15607602904 + 109.94568878850*t); + uranus_y_0+= 0.00039218598 * cos( 1.11841109252 + 4.45341812490*t); + uranus_y_0+= 0.00034205426 * cos( 0.92405922576 + 65.22037101170*t); + uranus_y_0+= 0.00034334377 * cos( 1.46696169843 + 225.82926841020*t); + uranus_y_0+= 0.00034538316 * cos( 0.27613780697 + 79.23501669220*t); + uranus_y_0+= 0.00039256771 * cos( 5.75956853703 + 202.25339517410*t); + uranus_y_0+= 0.00026157754 * cos( 3.74097610798 + 9.56122755560*t); + uranus_y_0+= 0.00023427328 * cos( 2.52740125551 + 145.63104387150*t); + uranus_y_0+= 0.00022933138 * cos( 3.94455540350 + 84.34282612290*t); + uranus_y_0+= 0.00031816303 * cos( 3.96860170484 + 152.53214255120*t); + uranus_y_0+= 0.00025237176 * cos( 4.45141413666 + 70.32818044240*t); + uranus_y_0+= 0.00028372491 * cos( 4.44714627097 + 184.72728735580*t); + uranus_y_0+= 0.00026652859 * cos( 4.53944395347 + 160.60889739850*t); + uranus_y_0+= 0.00019666208 * cos( 3.96350065335 + 74.66972398270*t); + uranus_y_0+= 0.00019643845 * cos( 0.71577796385 + 74.89347315190*t); + uranus_y_0+= 0.00019838981 * cos( 5.29113397354 + 12.53017297220*t); + uranus_y_0+= 0.00021523908 * cos( 4.93565132068 + 36.64856292950*t); + uranus_y_0+= 0.00015537967 * cos( 1.87863275460 + 52.69019803950*t); + uranus_y_0+= 0.00020115100 * cos( 3.45473780762 + 127.47179660680*t); + uranus_y_0+= 0.00020051641 * cos( 2.90386352937 + 22.09140052780*t); + uranus_y_0+= 0.00019901477 * cos( 6.11075402434 + 112.91463420510*t); + uranus_y_0+= 0.00018126776 * cos( 0.98478853787 + 33.67961751290*t); + uranus_y_0+= 0.00015174962 * cos( 1.31314034959 + 41.10198105440*t); + uranus_y_0+= 0.00011239020 * cos( 4.54508334011 + 71.60020482960*t); + uranus_y_0+= 0.00013948849 * cos( 4.70474945682 + 221.37585028530*t); + uranus_y_0+= 0.00010819728 * cos( 0.12807029856 + 77.96299230500*t); + uranus_y_0+= 0.00013589665 * cos( 0.98313719930 + 87.31177153950*t); + uranus_y_0+= 0.00011996772 * cos( 5.66129275335 + 1059.38193018920*t); + uranus_y_0+= 0.00012407787 * cos( 4.64945783340 + 72.33391801250*t); + uranus_y_0+= 0.00011531140 * cos( 0.20190074645 + 77.22927912210*t); + + double uranus_y_1=0.0; + uranus_y_1+= 0.02157896385 * cos( 0.00000000000 + 0.00000000000*t); + uranus_y_1+= 0.00739227349 * cos( 4.43963890935 + 149.56319713460*t); + uranus_y_1+= 0.00238545685 * cos( 3.76882493145 + 73.29712585900*t); + uranus_y_1+= 0.00229396424 * cos( 0.91090183978 + 76.26607127560*t); + uranus_y_1+= 0.00110137111 * cos( 4.00844441616 + 11.04570026390*t); + uranus_y_1+= 0.00094979054 * cos( 5.07141537066 + 63.73589830340*t); + uranus_y_1+= 0.00081474163 * cos( 5.92275367106 + 85.82729883120*t); + uranus_y_1+= 0.00045457174 * cos( 0.73292241207 + 138.51749687070*t); + uranus_y_1+= 0.00051366974 * cos( 0.61844114994 + 224.34479570190*t); + uranus_y_1+= 0.00038296005 * cos( 5.01873578671 + 70.84944530420*t); + uranus_y_1+= 0.00036146116 * cos( 5.94859452787 + 78.71375183040*t); + uranus_y_1+= 0.00032420558 * cos( 4.32617271732 + 74.78159856730*t); + uranus_y_1+= 0.00021673269 * cos( 3.36607263522 + 151.04766984290*t); + uranus_y_1+= 0.00019425087 * cos( 6.01842187783 + 77.75054398390*t); + uranus_y_1+= 0.00017393206 * cos( 4.96098895488 + 71.81265315070*t); + uranus_y_1+= 0.00014991169 * cos( 3.97176856758 + 3.93215326310*t); + uranus_y_1=uranus_y_1 * t; + + double uranus_y_2=0.0; + uranus_y_2+= 0.00034812647 * cos( 3.14159265359 + 0.00000000000*t); + uranus_y_2+= 0.00016589194 * cos( 2.29556740620 + 74.78159856730*t); + uranus_y_2+= 0.00010905147 * cos( 1.45737963668 + 149.56319713460*t); + uranus_y_2=uranus_y_2 * t * t; + + return uranus_y_0+uranus_y_1+uranus_y_2; +} + +double vsop87a_micro_uranus_z(double t){ + double uranus_z_0=0.0; + uranus_z_0+= 0.25878127698 * cos( 2.61861272578 + 74.78159856730*t); + uranus_z_0+= 0.01774318778 * cos( 3.14159265359 + 0.00000000000*t); + uranus_z_0+= 0.00599316131 * cos( 5.08119500585 + 149.56319713460*t); + uranus_z_0+= 0.00190281890 * cos( 1.61643841193 + 76.26607127560*t); + uranus_z_0+= 0.00190881685 * cos( 0.57869575952 + 73.29712585900*t); + uranus_z_0+= 0.00084626761 * cos( 2.26030150166 + 1.48447270830*t); + uranus_z_0+= 0.00030734257 * cos( 0.23571721555 + 63.73589830340*t); + uranus_z_0+= 0.00020842052 * cos( 1.26054208091 + 224.34479570190*t); + uranus_z_0+= 0.00019734273 * cos( 6.04314677688 + 148.07872442630*t); + uranus_z_0+= 0.00012537530 * cos( 5.17169051466 + 11.04570026390*t); + uranus_z_0+= 0.00014582864 * cos( 6.14852037212 + 71.81265315070*t); + uranus_z_0+= 0.00010407529 * cos( 3.65320417038 + 213.29909543800*t); + uranus_z_0+= 0.00011261541 * cos( 3.55973769686 + 529.69096509460*t); + + double uranus_z_1=0.0; + uranus_z_1+= 0.00655916626 * cos( 0.01271947660 + 74.78159856730*t); + uranus_z_1+= 0.00049648951 * cos( 0.00000000000 + 0.00000000000*t); + uranus_z_1+= 0.00023874178 * cos( 2.73870491220 + 149.56319713460*t); + uranus_z_1=uranus_z_1 * t; + + double uranus_z_2=0.0; + uranus_z_2+= 0.00014697858 * cos( 1.75149165003 + 74.78159856730*t); + uranus_z_2=uranus_z_2 * t * t; + + return uranus_z_0+uranus_z_1+uranus_z_2; +} + +double vsop87a_micro_venus_x(double t){ + double venus_x_0=0.0; + venus_x_0+= 0.72211281391 * cos( 3.17575836361 + 10213.28554621100*t); + venus_x_0+= 0.00486448018 * cos( 0.00000000000 + 0.00000000000*t); + venus_x_0+= 0.00244500474 * cos( 4.05566613861 + 20426.57109242200*t); + + double venus_x_1=0.0; + venus_x_1+= 0.00033862636 * cos( 3.14159265359 + 0.00000000000*t); + venus_x_1+= 0.00017234992 * cos( 0.92721124604 + 20426.57109242200*t); + venus_x_1=venus_x_1 * t; + + return venus_x_0+venus_x_1; +} + +double vsop87a_micro_venus_y(double t){ + double venus_y_0=0.0; + venus_y_0+= 0.72324820731 * cos( 1.60573808356 + 10213.28554621100*t); + venus_y_0+= 0.00549506273 * cos( 3.14159265359 + 0.00000000000*t); + venus_y_0+= 0.00244884790 * cos( 2.48564954004 + 20426.57109242200*t); + + double venus_y_1=0.0; + venus_y_1+= 0.00039231430 * cos( 0.00000000000 + 0.00000000000*t); + venus_y_1+= 0.00017282326 * cos( 5.63824735900 + 20426.57109242200*t); + venus_y_1=venus_y_1 * t; + + return venus_y_0+venus_y_1; +} + +double vsop87a_micro_venus_z(double t){ + double venus_z_0=0.0; + venus_z_0+= 0.04282990302 * cos( 0.26703856476 + 10213.28554621100*t); + venus_z_0+= 0.00035588343 * cos( 3.14159265359 + 0.00000000000*t); + venus_z_0+= 0.00014501879 * cos( 1.14696911390 + 20426.57109242200*t); + + double venus_z_1=0.0; + venus_z_1+= 0.00208096402 * cos( 1.88967278742 + 10213.28554621100*t); + venus_z_1=venus_z_1 * t; + + return venus_z_0+venus_z_1; +} + diff --git a/movement/lib/vsop87/vsop87a_micro.h b/movement/lib/vsop87/vsop87a_micro.h new file mode 100755 index 0000000..87515f5 --- /dev/null +++ b/movement/lib/vsop87/vsop87a_micro.h @@ -0,0 +1,17 @@ +//VSOP87-Multilang http://www.astrogreg.com/vsop87-multilang/index.html +//Greg Miller (gmiller@gregmiller.net) 2019. Released as Public Domain + +#ifndef VSOP87A_MICRO +#define VSOP87A_MICRO + + void vsop87a_micro_getEarth(double t,double temp[]); + void vsop87a_micro_getEmb(double t,double temp[]); + void vsop87a_micro_getJupiter(double t,double temp[]); + void vsop87a_micro_getMars(double t,double temp[]); + void vsop87a_micro_getMercury(double t,double temp[]); + void vsop87a_micro_getNeptune(double t,double temp[]); + void vsop87a_micro_getSaturn(double t,double temp[]); + void vsop87a_micro_getUranus(double t,double temp[]); + void vsop87a_micro_getVenus(double t,double temp[]); + void vsop87a_micro_getMoon(double earth[], double emb[],double temp[]); +#endif diff --git a/movement/lib/vsop87/vsop87a_milli.c b/movement/lib/vsop87/vsop87a_milli.c new file mode 100755 index 0000000..b187572 --- /dev/null +++ b/movement/lib/vsop87/vsop87a_milli.c @@ -0,0 +1,2048 @@ +//VSOP87-Multilang http://www.astrogreg.com/vsop87-multilang/index.html +//Greg Miller (gmiller@gregmiller.net) 2019. Released as Public Domain + +#include +#include "vsop87a_milli.h" +double vsop87a_milli_earth_x(double t); +double vsop87a_milli_earth_y(double t); +double vsop87a_milli_earth_z(double t); +double vsop87a_milli_emb_x(double t); +double vsop87a_milli_emb_y(double t); +double vsop87a_milli_emb_z(double t); +double vsop87a_milli_jupiter_x(double t); +double vsop87a_milli_jupiter_y(double t); +double vsop87a_milli_jupiter_z(double t); +double vsop87a_milli_mars_x(double t); +double vsop87a_milli_mars_y(double t); +double vsop87a_milli_mars_z(double t); +double vsop87a_milli_mercury_x(double t); +double vsop87a_milli_mercury_y(double t); +double vsop87a_milli_mercury_z(double t); +double vsop87a_milli_neptune_x(double t); +double vsop87a_milli_neptune_y(double t); +double vsop87a_milli_neptune_z(double t); +double vsop87a_milli_saturn_x(double t); +double vsop87a_milli_saturn_y(double t); +double vsop87a_milli_saturn_z(double t); +double vsop87a_milli_uranus_x(double t); +double vsop87a_milli_uranus_y(double t); +double vsop87a_milli_uranus_z(double t); +double vsop87a_milli_venus_x(double t); +double vsop87a_milli_venus_y(double t); +double vsop87a_milli_venus_z(double t); + + +void vsop87a_milli_getEarth(double t,double temp[]){ + temp[0]=vsop87a_milli_earth_x(t); + temp[1]=vsop87a_milli_earth_y(t); + temp[2]=vsop87a_milli_earth_z(t); +} + +void vsop87a_milli_getEmb(double t,double temp[]){ + temp[0]=vsop87a_milli_emb_x(t); + temp[1]=vsop87a_milli_emb_y(t); + temp[2]=vsop87a_milli_emb_z(t); +} + +void vsop87a_milli_getJupiter(double t,double temp[]){ + temp[0]=vsop87a_milli_jupiter_x(t); + temp[1]=vsop87a_milli_jupiter_y(t); + temp[2]=vsop87a_milli_jupiter_z(t); +} + +void vsop87a_milli_getMars(double t,double temp[]){ + temp[0]=vsop87a_milli_mars_x(t); + temp[1]=vsop87a_milli_mars_y(t); + temp[2]=vsop87a_milli_mars_z(t); +} + +void vsop87a_milli_getMercury(double t,double temp[]){ + temp[0]=vsop87a_milli_mercury_x(t); + temp[1]=vsop87a_milli_mercury_y(t); + temp[2]=vsop87a_milli_mercury_z(t); +} + +void vsop87a_milli_getNeptune(double t,double temp[]){ + temp[0]=vsop87a_milli_neptune_x(t); + temp[1]=vsop87a_milli_neptune_y(t); + temp[2]=vsop87a_milli_neptune_z(t); +} + +void vsop87a_milli_getSaturn(double t,double temp[]){ + temp[0]=vsop87a_milli_saturn_x(t); + temp[1]=vsop87a_milli_saturn_y(t); + temp[2]=vsop87a_milli_saturn_z(t); +} + +void vsop87a_milli_getUranus(double t,double temp[]){ + temp[0]=vsop87a_milli_uranus_x(t); + temp[1]=vsop87a_milli_uranus_y(t); + temp[2]=vsop87a_milli_uranus_z(t); +} + +void vsop87a_milli_getVenus(double t,double temp[]){ + temp[0]=vsop87a_milli_venus_x(t); + temp[1]=vsop87a_milli_venus_y(t); + temp[2]=vsop87a_milli_venus_z(t); +} + +void vsop87a_milli_getMoon(double earth[], double emb[],double temp[]){ + temp[0]=(emb[0]-earth[0])*(1 + 1 / 0.01230073677); + temp[1]=(emb[1]-earth[1])*(1 + 1 / 0.01230073677); + temp[2]=(emb[2]-earth[2])*(1 + 1 / 0.01230073677); + temp[0]=temp[0]+earth[0]; + temp[1]=temp[1]+earth[1]; + temp[2]=temp[2]+earth[2]; +} + +double vsop87a_milli_earth_x(double t){ + double earth_x_0=0.0; + earth_x_0+= 0.99982928844 * cos( 1.75348568475 + 6283.07584999140*t); + earth_x_0+= 0.00835257300 * cos( 1.71034539450 + 12566.15169998280*t); + earth_x_0+= 0.00561144206 * cos( 0.00000000000 + 0.00000000000*t); + earth_x_0+= 0.00010466628 * cos( 1.66722645223 + 18849.22754997420*t); + earth_x_0+= 0.00003110838 * cos( 0.66875185215 + 83996.84731811189*t); + earth_x_0+= 0.00002552498 * cos( 0.58310207301 + 529.69096509460*t); + earth_x_0+= 0.00002137256 * cos( 1.09235189672 + 1577.34354244780*t); + earth_x_0+= 0.00001709103 * cos( 0.49540223397 + 6279.55273164240*t); + earth_x_0+= 0.00001707882 * cos( 6.15315547484 + 6286.59896834040*t); + earth_x_0+= 0.00001445242 * cos( 3.47272783760 + 2352.86615377180*t); + earth_x_0+= 0.00001091006 * cos( 3.68984782465 + 5223.69391980220*t); + + double earth_x_1=0.0; + earth_x_1+= 0.00123403056 * cos( 0.00000000000 + 0.00000000000*t); + earth_x_1+= 0.00051500156 * cos( 6.00266267204 + 12566.15169998280*t); + earth_x_1+= 0.00001290726 * cos( 5.95943124583 + 18849.22754997420*t); + earth_x_1+= 0.00001068627 * cos( 2.01554176551 + 6283.07584999140*t); + earth_x_1=earth_x_1 * t; + + double earth_x_2=0.0; + earth_x_2+= 0.00004143217 * cos( 3.14159265359 + 0.00000000000*t); + earth_x_2+= 0.00002175695 * cos( 4.39999849572 + 12566.15169998280*t); + earth_x_2=earth_x_2 * t * t; + + return earth_x_0+earth_x_1+earth_x_2; +} + +double vsop87a_milli_earth_y(double t){ + double earth_y_0=0.0; + earth_y_0+= 0.99989211030 * cos( 0.18265890456 + 6283.07584999140*t); + earth_y_0+= 0.02442699036 * cos( 3.14159265359 + 0.00000000000*t); + earth_y_0+= 0.00835292314 * cos( 0.13952878991 + 12566.15169998280*t); + earth_y_0+= 0.00010466965 * cos( 0.09641690558 + 18849.22754997420*t); + earth_y_0+= 0.00003110838 * cos( 5.38114091484 + 83996.84731811189*t); + earth_y_0+= 0.00002570338 * cos( 5.30103973360 + 529.69096509460*t); + earth_y_0+= 0.00002147473 * cos( 2.66253538905 + 1577.34354244780*t); + earth_y_0+= 0.00001709219 * cos( 5.20780401071 + 6279.55273164240*t); + earth_y_0+= 0.00001707987 * cos( 4.58232858766 + 6286.59896834040*t); + earth_y_0+= 0.00001440265 * cos( 1.90068164664 + 2352.86615377180*t); + earth_y_0+= 0.00001135092 * cos( 5.27313415220 + 5223.69391980220*t); + + double earth_y_1=0.0; + earth_y_1+= 0.00093046324 * cos( 0.00000000000 + 0.00000000000*t); + earth_y_1+= 0.00051506609 * cos( 4.43180499286 + 12566.15169998280*t); + earth_y_1+= 0.00001290800 * cos( 4.38860548540 + 18849.22754997420*t); + earth_y_1=earth_y_1 * t; + + double earth_y_2=0.0; + earth_y_2+= 0.00005080208 * cos( 0.00000000000 + 0.00000000000*t); + earth_y_2+= 0.00002178016 * cos( 2.82957544235 + 12566.15169998280*t); + earth_y_2+= 0.00001020487 * cos( 4.63746718598 + 6283.07584999140*t); + earth_y_2=earth_y_2 * t * t; + + return earth_y_0+earth_y_1+earth_y_2; +} + +double vsop87a_milli_earth_z(double t){ + double earth_z_1=0.0; + earth_z_1+= 0.00227822442 * cos( 3.41372504278 + 6283.07584999140*t); + earth_z_1+= 0.00005429282 * cos( 0.00000000000 + 0.00000000000*t); + earth_z_1+= 0.00001903183 * cos( 3.37061270964 + 12566.15169998280*t); + earth_z_1=earth_z_1 * t; + + double earth_z_2=0.0; + earth_z_2+= 0.00009721989 * cos( 5.15233725915 + 6283.07584999140*t); + earth_z_2=earth_z_2 * t * t; + + return earth_z_1+earth_z_2; +} + +double vsop87a_milli_emb_x(double t){ + double emb_x_0=0.0; + emb_x_0+= 0.99982927460 * cos( 1.75348568475 + 6283.07584999140*t); + emb_x_0+= 0.00835257300 * cos( 1.71034539450 + 12566.15169998280*t); + emb_x_0+= 0.00561144161 * cos( 0.00000000000 + 0.00000000000*t); + emb_x_0+= 0.00010466628 * cos( 1.66722645223 + 18849.22754997420*t); + emb_x_0+= 0.00002552498 * cos( 0.58310207301 + 529.69096509460*t); + emb_x_0+= 0.00002137256 * cos( 1.09235189672 + 1577.34354244780*t); + emb_x_0+= 0.00001709103 * cos( 0.49540223397 + 6279.55273164240*t); + emb_x_0+= 0.00001707882 * cos( 6.15315547484 + 6286.59896834040*t); + emb_x_0+= 0.00001445242 * cos( 3.47272783760 + 2352.86615377180*t); + emb_x_0+= 0.00001091006 * cos( 3.68984782465 + 5223.69391980220*t); + + double emb_x_1=0.0; + emb_x_1+= 0.00123403046 * cos( 0.00000000000 + 0.00000000000*t); + emb_x_1+= 0.00051500156 * cos( 6.00266267204 + 12566.15169998280*t); + emb_x_1+= 0.00001290726 * cos( 5.95943124583 + 18849.22754997420*t); + emb_x_1+= 0.00001068627 * cos( 2.01554176551 + 6283.07584999140*t); + emb_x_1=emb_x_1 * t; + + double emb_x_2=0.0; + emb_x_2+= 0.00004143217 * cos( 3.14159265359 + 0.00000000000*t); + emb_x_2+= 0.00002175695 * cos( 4.39999849572 + 12566.15169998280*t); + emb_x_2=emb_x_2 * t * t; + + return emb_x_0+emb_x_1+emb_x_2; +} + +double vsop87a_milli_emb_y(double t){ + double emb_y_0=0.0; + emb_y_0+= 0.99989209645 * cos( 0.18265890456 + 6283.07584999140*t); + emb_y_0+= 0.02442698841 * cos( 3.14159265359 + 0.00000000000*t); + emb_y_0+= 0.00835292314 * cos( 0.13952878991 + 12566.15169998280*t); + emb_y_0+= 0.00010466965 * cos( 0.09641690558 + 18849.22754997420*t); + emb_y_0+= 0.00002570338 * cos( 5.30103973360 + 529.69096509460*t); + emb_y_0+= 0.00002147473 * cos( 2.66253538905 + 1577.34354244780*t); + emb_y_0+= 0.00001709219 * cos( 5.20780401071 + 6279.55273164240*t); + emb_y_0+= 0.00001707987 * cos( 4.58232858766 + 6286.59896834040*t); + emb_y_0+= 0.00001440265 * cos( 1.90068164664 + 2352.86615377180*t); + emb_y_0+= 0.00001135092 * cos( 5.27313415220 + 5223.69391980220*t); + + double emb_y_1=0.0; + emb_y_1+= 0.00093046317 * cos( 0.00000000000 + 0.00000000000*t); + emb_y_1+= 0.00051506609 * cos( 4.43180499286 + 12566.15169998280*t); + emb_y_1+= 0.00001290800 * cos( 4.38860548540 + 18849.22754997420*t); + emb_y_1=emb_y_1 * t; + + double emb_y_2=0.0; + emb_y_2+= 0.00005080208 * cos( 0.00000000000 + 0.00000000000*t); + emb_y_2+= 0.00002178016 * cos( 2.82957544235 + 12566.15169998280*t); + emb_y_2+= 0.00001020487 * cos( 4.63746718598 + 6283.07584999140*t); + emb_y_2=emb_y_2 * t * t; + + return emb_y_0+emb_y_1+emb_y_2; +} + +double vsop87a_milli_emb_z(double t){ + double emb_z_1=0.0; + emb_z_1+= 0.00227822442 * cos( 3.41372504278 + 6283.07584999140*t); + emb_z_1+= 0.00005429282 * cos( 0.00000000000 + 0.00000000000*t); + emb_z_1+= 0.00001903183 * cos( 3.37061270964 + 12566.15169998280*t); + emb_z_1=emb_z_1 * t; + + double emb_z_2=0.0; + emb_z_2+= 0.00009721989 * cos( 5.15233725915 + 6283.07584999140*t); + emb_z_2=emb_z_2 * t * t; + + return emb_z_1+emb_z_2; +} + +double vsop87a_milli_jupiter_x(double t){ + double jupiter_x_0=0.0; + jupiter_x_0+= 5.19663470114 * cos( 0.59945082355 + 529.69096509460*t); + jupiter_x_0+= 0.36662642320 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_x_0+= 0.12593937922 * cos( 0.94911583701 + 1059.38193018920*t); + jupiter_x_0+= 0.01500672056 * cos( 0.73175134610 + 522.57741809380*t); + jupiter_x_0+= 0.01476224578 * cos( 3.61736921122 + 536.80451209540*t); + jupiter_x_0+= 0.00457752736 * cos( 1.29883700755 + 1589.07289528380*t); + jupiter_x_0+= 0.00301689798 * cos( 5.17372551148 + 7.11354700080*t); + jupiter_x_0+= 0.00385975375 * cos( 2.01229910687 + 103.09277421860*t); + jupiter_x_0+= 0.00194025405 * cos( 5.02580363996 + 426.59819087600*t); + jupiter_x_0+= 0.00150678793 * cos( 6.12003027739 + 110.20632121940*t); + jupiter_x_0+= 0.00144867641 * cos( 5.55980577080 + 632.78373931320*t); + jupiter_x_0+= 0.00134226996 * cos( 0.87648567011 + 213.29909543800*t); + jupiter_x_0+= 0.00103494641 * cos( 6.19324769120 + 1052.26838318840*t); + jupiter_x_0+= 0.00114201562 * cos( 0.01567084269 + 1162.47470440780*t); + jupiter_x_0+= 0.00072095575 * cos( 3.96117430643 + 1066.49547719000*t); + jupiter_x_0+= 0.00059486083 * cos( 4.45769374358 + 949.17560896980*t); + jupiter_x_0+= 0.00068284021 * cos( 3.44051122631 + 846.08283475120*t); + jupiter_x_0+= 0.00047092251 * cos( 1.44612636451 + 419.48464387520*t); + jupiter_x_0+= 0.00030623417 * cos( 2.99132321427 + 206.18554843720*t); + jupiter_x_0+= 0.00026613459 * cos( 4.85169906494 + 323.50541665740*t); + jupiter_x_0+= 0.00019727457 * cos( 1.64891626213 + 2118.76386037840*t); + jupiter_x_0+= 0.00016481594 * cos( 1.95150056568 + 316.39186965660*t); + jupiter_x_0+= 0.00016101974 * cos( 0.87973155980 + 515.46387109300*t); + jupiter_x_0+= 0.00014209487 * cos( 2.07769621413 + 742.99006053260*t); + jupiter_x_0+= 0.00015192516 * cos( 6.25820127906 + 735.87651353180*t); + jupiter_x_0+= 0.00011423199 * cos( 3.48146108929 + 543.91805909620*t); + jupiter_x_0+= 0.00012155285 * cos( 3.75229924999 + 525.75881183150*t); + jupiter_x_0+= 0.00011996271 * cos( 0.58568573729 + 533.62311835770*t); + jupiter_x_0+= 0.00008468556 * cos( 3.47248751739 + 639.89728631400*t); + jupiter_x_0+= 0.00008223302 * cos( 5.56680447143 + 1478.86657406440*t); + jupiter_x_0+= 0.00008694124 * cos( 0.38262009411 + 1692.16566950240*t); + jupiter_x_0+= 0.00007427517 * cos( 5.98380751196 + 956.28915597060*t); + jupiter_x_0+= 0.00007516470 * cos( 0.92896448412 + 1265.56747862640*t); + jupiter_x_0+= 0.00007655867 * cos( 0.14178789086 + 1581.95934828300*t); + jupiter_x_0+= 0.00005318791 * cos( 1.10494016349 + 526.50957135690*t); + jupiter_x_0+= 0.00005218492 * cos( 3.23235129224 + 532.87235883230*t); + jupiter_x_0+= 0.00005777311 * cos( 5.03726165628 + 14.22709400160*t); + jupiter_x_0+= 0.00004622685 * cos( 3.75817086099 + 1375.77379984580*t); + jupiter_x_0+= 0.00003939864 * cos( 4.30892687511 + 1596.18644228460*t); + jupiter_x_0+= 0.00004569444 * cos( 2.15087281710 + 95.97922721780*t); + jupiter_x_0+= 0.00002952712 * cos( 3.85988483947 + 309.27832265580*t); + jupiter_x_0+= 0.00002857935 * cos( 6.01118473739 + 117.31986822020*t); + jupiter_x_0+= 0.00002440094 * cos( 4.23995765702 + 433.71173787680*t); + jupiter_x_0+= 0.00002438257 * cos( 3.88808463822 + 220.41264243880*t); + jupiter_x_0+= 0.00002675112 * cos( 3.18723449094 + 1169.58825140860*t); + jupiter_x_0+= 0.00002386425 * cos( 5.96354994324 + 1045.15483618760*t); + jupiter_x_0+= 0.00001870097 * cos( 0.52019313301 + 1155.36115740700*t); + jupiter_x_0+= 0.00001939060 * cos( 5.91883412864 + 625.67019231240*t); + jupiter_x_0+= 0.00001631500 * cos( 4.41910383466 + 942.06206196900*t); + jupiter_x_0+= 0.00001451667 * cos( 5.76112706040 + 853.19638175200*t); + jupiter_x_0+= 0.00001361286 * cos( 1.34792748837 + 1368.66025284500*t); + jupiter_x_0+= 0.00001663331 * cos( 1.94010629194 + 838.96928775040*t); + jupiter_x_0+= 0.00001611229 * cos( 5.49324974845 + 74.78159856730*t); + jupiter_x_0+= 0.00001033570 * cos( 0.08907208789 + 1795.25844372100*t); + jupiter_x_0+= 0.00001088284 * cos( 1.13406104190 + 527.24328453980*t); + jupiter_x_0+= 0.00001080643 * cos( 3.20528362573 + 532.13864564940*t); + + double jupiter_x_1=0.0; + jupiter_x_1+= 0.00882389251 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_x_1+= 0.00635297172 * cos( 0.10662156868 + 1059.38193018920*t); + jupiter_x_1+= 0.00599720482 * cos( 2.42996678275 + 522.57741809380*t); + jupiter_x_1+= 0.00589157060 * cos( 1.91556314637 + 536.80451209540*t); + jupiter_x_1+= 0.00081697204 * cos( 3.46668108797 + 7.11354700080*t); + jupiter_x_1+= 0.00046201898 * cos( 0.45714214032 + 1589.07289528380*t); + jupiter_x_1+= 0.00032508590 * cos( 1.74648849928 + 1052.26838318840*t); + jupiter_x_1+= 0.00033891193 * cos( 4.10113482752 + 529.69096509460*t); + jupiter_x_1+= 0.00031234303 * cos( 2.34698051502 + 1066.49547719000*t); + jupiter_x_1+= 0.00021244363 * cos( 4.36576178953 + 110.20632121940*t); + jupiter_x_1+= 0.00018156701 * cos( 4.00572238779 + 426.59819087600*t); + jupiter_x_1+= 0.00013577576 * cos( 0.30008010246 + 632.78373931320*t); + jupiter_x_1+= 0.00012889505 * cos( 2.57489294062 + 515.46387109300*t); + jupiter_x_1+= 0.00009125875 * cos( 1.78082469962 + 543.91805909620*t); + jupiter_x_1+= 0.00008085991 * cos( 6.16136518902 + 949.17560896980*t); + jupiter_x_1+= 0.00007142547 * cos( 3.17267801203 + 323.50541665740*t); + jupiter_x_1+= 0.00004292240 * cos( 4.74970626655 + 206.18554843720*t); + jupiter_x_1+= 0.00004393977 * cos( 1.14770788063 + 735.87651353180*t); + jupiter_x_1+= 0.00003399164 * cos( 2.90091450747 + 526.50957135690*t); + jupiter_x_1+= 0.00003333344 * cos( 1.43691652967 + 532.87235883230*t); + jupiter_x_1+= 0.00003873467 * cos( 3.33648870101 + 14.22709400160*t); + jupiter_x_1+= 0.00003044408 * cos( 1.65428048669 + 525.75881183150*t); + jupiter_x_1+= 0.00003001874 * cos( 2.68376982746 + 533.62311835770*t); + jupiter_x_1+= 0.00002933359 * cos( 2.61899855005 + 419.48464387520*t); + jupiter_x_1+= 0.00002438199 * cos( 3.60655644537 + 316.39186965660*t); + jupiter_x_1+= 0.00002804218 * cos( 4.89742591320 + 103.09277421860*t); + jupiter_x_1+= 0.00002990245 * cos( 0.80692155639 + 2118.76386037840*t); + jupiter_x_1+= 0.00001977572 * cos( 5.08915489088 + 956.28915597060*t); + jupiter_x_1+= 0.00001853679 * cos( 2.76941001747 + 1596.18644228460*t); + jupiter_x_1+= 0.00001772800 * cos( 0.72631739446 + 742.99006053260*t); + jupiter_x_1+= 0.00001812965 * cos( 3.84602148747 + 95.97922721780*t); + jupiter_x_1+= 0.00001532945 * cos( 4.31556714501 + 117.31986822020*t); + jupiter_x_1+= 0.00001904067 * cos( 1.85937873703 + 1581.95934828300*t); + jupiter_x_1+= 0.00001539212 * cos( 1.47899172821 + 639.89728631400*t); + jupiter_x_1+= 0.00001632362 * cos( 1.41504212408 + 1045.15483618760*t); + jupiter_x_1+= 0.00001023812 * cos( 2.57182697715 + 433.71173787680*t); + jupiter_x_1+= 0.00001055422 * cos( 2.50844222977 + 1265.56747862640*t); + jupiter_x_1=jupiter_x_1 * t; + + double jupiter_x_2=0.0; + jupiter_x_2+= 0.00123864644 * cos( 4.13563277513 + 522.57741809380*t); + jupiter_x_2+= 0.00121521296 * cos( 0.21155109275 + 536.80451209540*t); + jupiter_x_2+= 0.00085355503 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_x_2+= 0.00077685547 * cos( 5.29776154458 + 529.69096509460*t); + jupiter_x_2+= 0.00041410887 * cos( 5.12291589939 + 1059.38193018920*t); + jupiter_x_2+= 0.00011423070 * cos( 1.72917878238 + 7.11354700080*t); + jupiter_x_2+= 0.00007051587 * cos( 0.74163703419 + 1066.49547719000*t); + jupiter_x_2+= 0.00005711029 * cos( 3.63172846494 + 1052.26838318840*t); + jupiter_x_2+= 0.00005242644 * cos( 4.27482379441 + 515.46387109300*t); + jupiter_x_2+= 0.00004039540 * cos( 5.58417732117 + 1589.07289528380*t); + jupiter_x_2+= 0.00003706457 * cos( 0.07769981349 + 543.91805909620*t); + jupiter_x_2+= 0.00001698817 * cos( 2.44284418066 + 110.20632121940*t); + jupiter_x_2+= 0.00001134598 * cos( 2.35807061809 + 426.59819087600*t); + jupiter_x_2+= 0.00001322673 * cos( 1.63142549980 + 14.22709400160*t); + jupiter_x_2=jupiter_x_2 * t * t; + + double jupiter_x_3=0.0; + jupiter_x_3+= 0.00017071323 * cos( 5.86133022278 + 522.57741809380*t); + jupiter_x_3+= 0.00016713548 * cos( 4.77458794485 + 536.80451209540*t); + jupiter_x_3+= 0.00003348610 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_x_3+= 0.00001787838 * cos( 3.56550298031 + 1059.38193018920*t); + jupiter_x_3+= 0.00001435449 * cos( 5.98502036587 + 515.46387109300*t); + jupiter_x_3+= 0.00001080194 * cos( 5.42530305914 + 1066.49547719000*t); + jupiter_x_3+= 0.00001014206 * cos( 4.64773902077 + 543.91805909620*t); + jupiter_x_3+= 0.00001073175 * cos( 6.22314467964 + 7.11354700080*t); + jupiter_x_3=jupiter_x_3 * t * t * t; + + double jupiter_x_4=0.0; + jupiter_x_4+= 0.00001762402 * cos( 1.32863039757 + 522.57741809380*t); + jupiter_x_4+= 0.00001717846 * cos( 3.03331531843 + 536.80451209540*t); + jupiter_x_4=jupiter_x_4 * t * t * t * t; + + return jupiter_x_0+jupiter_x_1+jupiter_x_2+jupiter_x_3+jupiter_x_4; +} + +double vsop87a_milli_jupiter_y(double t){ + double jupiter_y_0=0.0; + jupiter_y_0+= 5.19520046589 * cos( 5.31203162731 + 529.69096509460*t); + jupiter_y_0+= 0.12592862602 * cos( 5.66160227728 + 1059.38193018920*t); + jupiter_y_0+= 0.09363670616 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_y_0+= 0.01508275299 * cos( 5.43934968102 + 522.57741809380*t); + jupiter_y_0+= 0.01475809370 * cos( 2.04679566495 + 536.80451209540*t); + jupiter_y_0+= 0.00457750806 * cos( 6.01129093501 + 1589.07289528380*t); + jupiter_y_0+= 0.00300686679 * cos( 3.60948050740 + 7.11354700080*t); + jupiter_y_0+= 0.00378285578 * cos( 3.53006782383 + 103.09277421860*t); + jupiter_y_0+= 0.00192333128 * cos( 3.45690564771 + 426.59819087600*t); + jupiter_y_0+= 0.00146104656 * cos( 4.62267224431 + 110.20632121940*t); + jupiter_y_0+= 0.00139480058 * cos( 4.00075307706 + 632.78373931320*t); + jupiter_y_0+= 0.00132696764 * cos( 5.62184581859 + 213.29909543800*t); + jupiter_y_0+= 0.00101999807 * cos( 4.57594598884 + 1052.26838318840*t); + jupiter_y_0+= 0.00114043110 * cos( 4.72982262969 + 1162.47470440780*t); + jupiter_y_0+= 0.00072091178 * cos( 2.39048659148 + 1066.49547719000*t); + jupiter_y_0+= 0.00059051769 * cos( 2.89529070968 + 949.17560896980*t); + jupiter_y_0+= 0.00068374489 * cos( 1.86537074374 + 846.08283475120*t); + jupiter_y_0+= 0.00029807369 * cos( 4.52105772740 + 206.18554843720*t); + jupiter_y_0+= 0.00026933579 * cos( 3.86233956827 + 419.48464387520*t); + jupiter_y_0+= 0.00026619714 * cos( 3.28203174951 + 323.50541665740*t); + jupiter_y_0+= 0.00020873780 * cos( 3.79369881757 + 735.87651353180*t); + jupiter_y_0+= 0.00019727397 * cos( 0.07818534532 + 2118.76386037840*t); + jupiter_y_0+= 0.00018639846 * cos( 0.38751972138 + 316.39186965660*t); + jupiter_y_0+= 0.00016355726 * cos( 5.56997881604 + 515.46387109300*t); + jupiter_y_0+= 0.00014606858 * cos( 0.47759399145 + 742.99006053260*t); + jupiter_y_0+= 0.00011419853 * cos( 1.91089341468 + 543.91805909620*t); + jupiter_y_0+= 0.00012153427 * cos( 2.18151972499 + 525.75881183150*t); + jupiter_y_0+= 0.00011988875 * cos( 5.29687602089 + 533.62311835770*t); + jupiter_y_0+= 0.00008443107 * cos( 1.91435801697 + 639.89728631400*t); + jupiter_y_0+= 0.00008163163 * cos( 4.00303742375 + 1478.86657406440*t); + jupiter_y_0+= 0.00008732789 * cos( 5.09607066097 + 1692.16566950240*t); + jupiter_y_0+= 0.00007414115 * cos( 4.41141990461 + 956.28915597060*t); + jupiter_y_0+= 0.00007619486 * cos( 5.59554151997 + 1265.56747862640*t); + jupiter_y_0+= 0.00007779184 * cos( 4.83346300662 + 1581.95934828300*t); + jupiter_y_0+= 0.00005322882 * cos( 5.81740472645 + 526.50957135690*t); + jupiter_y_0+= 0.00005217025 * cos( 1.66178643542 + 532.87235883230*t); + jupiter_y_0+= 0.00005772132 * cos( 3.46915716927 + 14.22709400160*t); + jupiter_y_0+= 0.00004528355 * cos( 2.18377558038 + 1375.77379984580*t); + jupiter_y_0+= 0.00003939875 * cos( 2.73830531054 + 1596.18644228460*t); + jupiter_y_0+= 0.00004567181 * cos( 3.71300776935 + 95.97922721780*t); + jupiter_y_0+= 0.00003235419 * cos( 4.76600347062 + 625.67019231240*t); + jupiter_y_0+= 0.00003140740 * cos( 5.59566796922 + 309.27832265580*t); + jupiter_y_0+= 0.00002855423 * cos( 4.44478286006 + 117.31986822020*t); + jupiter_y_0+= 0.00002445625 * cos( 2.67036952230 + 433.71173787680*t); + jupiter_y_0+= 0.00002253545 * cos( 4.28462825722 + 838.96928775040*t); + jupiter_y_0+= 0.00002672262 * cos( 1.61857897069 + 1169.58825140860*t); + jupiter_y_0+= 0.00002423639 * cos( 2.32942339839 + 220.41264243880*t); + jupiter_y_0+= 0.00002362662 * cos( 4.60417580207 + 1155.36115740700*t); + jupiter_y_0+= 0.00002409581 * cos( 4.33196301609 + 1045.15483618760*t); + jupiter_y_0+= 0.00001458169 * cos( 4.18761881277 + 853.19638175200*t); + jupiter_y_0+= 0.00001432195 * cos( 3.24824554500 + 942.06206196900*t); + jupiter_y_0+= 0.00001646568 * cos( 3.91965876562 + 74.78159856730*t); + jupiter_y_0+= 0.00001050270 * cos( 4.83706014327 + 1795.25844372100*t); + jupiter_y_0+= 0.00001002355 * cos( 1.50931939870 + 1272.68102562720*t); + jupiter_y_0+= 0.00001087727 * cos( 5.84673086939 + 527.24328453980*t); + jupiter_y_0+= 0.00001079512 * cos( 1.63448507346 + 532.13864564940*t); + + double jupiter_y_1=0.0; + jupiter_y_1+= 0.01694798253 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_y_1+= 0.00634859798 * cos( 4.81903199650 + 1059.38193018920*t); + jupiter_y_1+= 0.00601160431 * cos( 0.85811249940 + 522.57741809380*t); + jupiter_y_1+= 0.00588928504 * cos( 0.34491576890 + 536.80451209540*t); + jupiter_y_1+= 0.00081187145 * cos( 1.90914316532 + 7.11354700080*t); + jupiter_y_1+= 0.00046888090 * cos( 1.91294535618 + 529.69096509460*t); + jupiter_y_1+= 0.00046194129 * cos( 5.16955994561 + 1589.07289528380*t); + jupiter_y_1+= 0.00032503453 * cos( 0.17640743623 + 1052.26838318840*t); + jupiter_y_1+= 0.00031231694 * cos( 0.77623645597 + 1066.49547719000*t); + jupiter_y_1+= 0.00019462096 * cos( 3.00957119470 + 110.20632121940*t); + jupiter_y_1+= 0.00017738615 * cos( 2.46531787101 + 426.59819087600*t); + jupiter_y_1+= 0.00013701692 * cos( 5.02070197804 + 632.78373931320*t); + jupiter_y_1+= 0.00013034616 * cos( 0.98979834442 + 515.46387109300*t); + jupiter_y_1+= 0.00009122660 * cos( 0.21022587969 + 543.91805909620*t); + jupiter_y_1+= 0.00008109050 * cos( 4.58123811601 + 949.17560896980*t); + jupiter_y_1+= 0.00007145229 * cos( 1.60381236094 + 323.50541665740*t); + jupiter_y_1+= 0.00003957592 * cos( 6.18550697817 + 206.18554843720*t); + jupiter_y_1+= 0.00004347346 * cos( 5.85522835488 + 735.87651353180*t); + jupiter_y_1+= 0.00003401735 * cos( 1.33033225252 + 526.50957135690*t); + jupiter_y_1+= 0.00003331887 * cos( 6.14951835712 + 532.87235883230*t); + jupiter_y_1+= 0.00003866147 * cos( 1.76877582038 + 14.22709400160*t); + jupiter_y_1+= 0.00003094257 * cos( 1.00670454701 + 419.48464387520*t); + jupiter_y_1+= 0.00003044205 * cos( 0.08329779827 + 525.75881183150*t); + jupiter_y_1+= 0.00003001484 * cos( 1.11280606283 + 533.62311835770*t); + jupiter_y_1+= 0.00002977284 * cos( 3.35507028507 + 103.09277421860*t); + jupiter_y_1+= 0.00002347100 * cos( 2.06781775390 + 316.39186965660*t); + jupiter_y_1+= 0.00002990192 * cos( 5.51944830506 + 2118.76386037840*t); + jupiter_y_1+= 0.00001875464 * cos( 5.32657356489 + 742.99006053260*t); + jupiter_y_1+= 0.00001854067 * cos( 1.19908734197 + 1596.18644228460*t); + jupiter_y_1+= 0.00001968401 * cos( 3.51896739844 + 956.28915597060*t); + jupiter_y_1+= 0.00001808627 * cos( 5.40287543026 + 95.97922721780*t); + jupiter_y_1+= 0.00001530472 * cos( 2.75094722237 + 117.31986822020*t); + jupiter_y_1+= 0.00001885393 * cos( 0.29905973710 + 1581.95934828300*t); + jupiter_y_1+= 0.00001516541 * cos( 6.21684203571 + 639.89728631400*t); + jupiter_y_1+= 0.00001636913 * cos( 6.09270756447 + 1045.15483618760*t); + jupiter_y_1+= 0.00001260123 * cos( 0.07143173954 + 625.67019231240*t); + jupiter_y_1+= 0.00001028165 * cos( 1.00301485824 + 433.71173787680*t); + jupiter_y_1+= 0.00001035933 * cos( 0.98273794152 + 1265.56747862640*t); + jupiter_y_1=jupiter_y_1 * t; + + double jupiter_y_2=0.0; + jupiter_y_2+= 0.00124032509 * cos( 2.56495576833 + 522.57741809380*t); + jupiter_y_2+= 0.00121455991 * cos( 4.92398766380 + 536.80451209540*t); + jupiter_y_2+= 0.00076523263 * cos( 3.75913371793 + 529.69096509460*t); + jupiter_y_2+= 0.00076943042 * cos( 3.14159265359 + 0.00000000000*t); + jupiter_y_2+= 0.00041357600 * cos( 3.55228440457 + 1059.38193018920*t); + jupiter_y_2+= 0.00011277667 * cos( 0.18559902389 + 7.11354700080*t); + jupiter_y_2+= 0.00007051103 * cos( 5.45404368570 + 1066.49547719000*t); + jupiter_y_2+= 0.00005719440 * cos( 2.05970000230 + 1052.26838318840*t); + jupiter_y_2+= 0.00005286157 * cos( 2.69490465064 + 515.46387109300*t); + jupiter_y_2+= 0.00004039038 * cos( 4.01341034637 + 1589.07289528380*t); + jupiter_y_2+= 0.00003704528 * cos( 4.79029292271 + 543.91805909620*t); + jupiter_y_2+= 0.00001280283 * cos( 1.47574006861 + 110.20632121940*t); + jupiter_y_2+= 0.00001059783 * cos( 0.89610748176 + 426.59819087600*t); + jupiter_y_2+= 0.00001320627 * cos( 0.05786048417 + 14.22709400160*t); + jupiter_y_2=jupiter_y_2 * t * t; + + double jupiter_y_3=0.0; + jupiter_y_3+= 0.00017085516 * cos( 4.29096904063 + 522.57741809380*t); + jupiter_y_3+= 0.00016701353 * cos( 3.20365737109 + 536.80451209540*t); + jupiter_y_3+= 0.00004006038 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_y_3+= 0.00001782451 * cos( 1.99283071153 + 1059.38193018920*t); + jupiter_y_3+= 0.00001443816 * cos( 4.40866555269 + 515.46387109300*t); + jupiter_y_3+= 0.00001079405 * cos( 3.85450799252 + 1066.49547719000*t); + jupiter_y_3+= 0.00001013157 * cos( 3.07729621279 + 543.91805909620*t); + jupiter_y_3+= 0.00001055565 * cos( 4.70184773789 + 7.11354700080*t); + jupiter_y_3=jupiter_y_3 * t * t * t; + + double jupiter_y_4=0.0; + jupiter_y_4+= 0.00001762645 * cos( 6.04159386554 + 522.57741809380*t); + jupiter_y_4+= 0.00001716045 * cos( 1.46206285710 + 536.80451209540*t); + jupiter_y_4=jupiter_y_4 * t * t * t * t; + + return jupiter_y_0+jupiter_y_1+jupiter_y_2+jupiter_y_3+jupiter_y_4; +} + +double vsop87a_milli_jupiter_z(double t){ + double jupiter_z_0=0.0; + jupiter_z_0+= 0.11823100489 * cos( 3.55844646343 + 529.69096509460*t); + jupiter_z_0+= 0.00859031952 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_z_0+= 0.00286562094 * cos( 3.90812238338 + 1059.38193018920*t); + jupiter_z_0+= 0.00042388592 * cos( 3.60144191032 + 522.57741809380*t); + jupiter_z_0+= 0.00033295491 * cos( 0.30297050585 + 536.80451209540*t); + jupiter_z_0+= 0.00010416160 * cos( 4.25764593061 + 1589.07289528380*t); + jupiter_z_0+= 0.00007449294 * cos( 5.24213104150 + 103.09277421860*t); + jupiter_z_0+= 0.00006910102 * cos( 1.75032945752 + 7.11354700080*t); + jupiter_z_0+= 0.00005292012 * cos( 1.68231447192 + 426.59819087600*t); + jupiter_z_0+= 0.00004313598 * cos( 3.70673689841 + 213.29909543800*t); + jupiter_z_0+= 0.00003784265 * cos( 2.71522544491 + 110.20632121940*t); + jupiter_z_0+= 0.00003798016 * cos( 2.16715743175 + 632.78373931320*t); + jupiter_z_0+= 0.00002455385 * cos( 2.96904135659 + 1052.26838318840*t); + jupiter_z_0+= 0.00002461547 * cos( 2.99889460411 + 1162.47470440780*t); + jupiter_z_0+= 0.00002001451 * cos( 2.68535838309 + 419.48464387520*t); + jupiter_z_0+= 0.00002163471 * cos( 6.26718259854 + 846.08283475120*t); + jupiter_z_0+= 0.00001633653 * cos( 0.64194743493 + 1066.49547719000*t); + jupiter_z_0+= 0.00001450672 * cos( 1.17108416193 + 949.17560896980*t); + + double jupiter_z_1=0.0; + jupiter_z_1+= 0.00407072175 * cos( 1.52699353482 + 529.69096509460*t); + jupiter_z_1+= 0.00020307341 * cos( 2.59878269248 + 1059.38193018920*t); + jupiter_z_1+= 0.00014424953 * cos( 4.85400155025 + 536.80451209540*t); + jupiter_z_1+= 0.00015474611 * cos( 0.00000000000 + 0.00000000000*t); + jupiter_z_1+= 0.00012730364 * cos( 5.45536715732 + 522.57741809380*t); + jupiter_z_1+= 0.00002100882 * cos( 0.09538864287 + 7.11354700080*t); + jupiter_z_1+= 0.00001230425 * cos( 3.14222500244 + 1589.07289528380*t); + jupiter_z_1=jupiter_z_1 * t; + + double jupiter_z_2=0.0; + jupiter_z_2+= 0.00028635326 * cos( 3.01374166973 + 529.69096509460*t); + jupiter_z_2+= 0.00003114752 * cos( 3.13228646176 + 536.80451209540*t); + jupiter_z_2+= 0.00002379765 * cos( 0.95574345340 + 522.57741809380*t); + jupiter_z_2+= 0.00001310111 * cos( 2.05263704913 + 1059.38193018920*t); + jupiter_z_2=jupiter_z_2 * t * t; + + return jupiter_z_0+jupiter_z_1+jupiter_z_2; +} + +double vsop87a_milli_mars_x(double t){ + double mars_x_0=0.0; + mars_x_0+= 1.51769936383 * cos( 6.20403346548 + 3340.61242669980*t); + mars_x_0+= 0.19502945246 * cos( 3.14159265359 + 0.00000000000*t); + mars_x_0+= 0.07070919655 * cos( 0.25870338558 + 6681.22485339960*t); + mars_x_0+= 0.00494196914 * cos( 0.59669127768 + 10021.83728009940*t); + mars_x_0+= 0.00040938237 * cos( 0.93473307419 + 13362.44970679920*t); + mars_x_0+= 0.00021067199 * cos( 1.80435656154 + 3337.08930835080*t); + mars_x_0+= 0.00021041626 * cos( 1.17895619474 + 3344.13554504880*t); + mars_x_0+= 0.00011370375 * cos( 4.83265211109 + 1059.38193018920*t); + mars_x_0+= 0.00013527976 * cos( 0.63010765169 + 529.69096509460*t); + mars_x_0+= 0.00006774107 * cos( 3.61785048282 + 3340.59517304760*t); + mars_x_0+= 0.00006774060 * cos( 5.64862211431 + 3340.62968035200*t); + mars_x_0+= 0.00008226069 * cos( 1.86843519535 + 2281.23049651060*t); + mars_x_0+= 0.00005469046 * cos( 1.13324429003 + 2942.46342329160*t); + mars_x_0+= 0.00004817134 * cos( 1.85091045536 + 3738.76143010800*t); + mars_x_0+= 0.00004937579 * cos( 4.43241440654 + 5621.84292321040*t); + mars_x_0+= 0.00005276260 * cos( 2.33148083116 + 6151.53388830500*t); + mars_x_0+= 0.00003636667 * cos( 6.11397592106 + 796.29800681640*t); + mars_x_0+= 0.00003725823 * cos( 1.27280182943 + 16703.06213349900*t); + mars_x_0+= 0.00003729746 * cos( 1.21398323637 + 398.14900340820*t); + mars_x_0+= 0.00002368513 * cos( 2.96841895360 + 2544.31441988340*t); + mars_x_0+= 0.00002397865 * cos( 0.63553674054 + 3149.16416058820*t); + mars_x_0+= 0.00002274646 * cos( 2.35708328853 + 3532.06069281140*t); + mars_x_0+= 0.00001977579 * cos( 2.14087826110 + 6677.70173505060*t); + mars_x_0+= 0.00002229176 * cos( 1.69588962513 + 3340.54511639700*t); + mars_x_0+= 0.00002229117 * cos( 1.28739323821 + 3340.67973700260*t); + mars_x_0+= 0.00002182206 * cos( 1.69655112969 + 6283.07584999140*t); + mars_x_0+= 0.00002241010 * cos( 4.82218655311 + 8962.45534991020*t); + mars_x_0+= 0.00001677693 * cos( 3.14442612046 + 5884.92684658320*t); + mars_x_0+= 0.00001630482 * cos( 0.24117974845 + 4136.91043351620*t); + mars_x_0+= 0.00001958162 * cos( 1.51914544555 + 6684.74797174860*t); + mars_x_0+= 0.00001378470 * cos( 2.18011900021 + 1751.53953141600*t); + mars_x_0+= 0.00001289804 * cos( 4.70970778621 + 1194.44701022460*t); + mars_x_0+= 0.00001468124 * cos( 1.87869730543 + 3870.30339179440*t); + mars_x_0+= 0.00001290170 * cos( 0.43596325296 + 2810.92146160520*t); + mars_x_0+= 0.00001572540 * cos( 4.84809921789 + 1589.07289528380*t); + + double mars_x_1=0.0; + mars_x_1+= 0.00861441374 * cos( 3.14159265359 + 0.00000000000*t); + mars_x_1+= 0.00552437949 * cos( 5.09565872891 + 6681.22485339960*t); + mars_x_1+= 0.00077184977 * cos( 5.43315636209 + 10021.83728009940*t); + mars_x_1+= 0.00020467294 * cos( 5.57051812369 + 3340.61242669980*t); + mars_x_1+= 0.00009589581 * cos( 5.77107234791 + 13362.44970679920*t); + mars_x_1+= 0.00002620610 * cos( 6.22441295122 + 3344.13554504880*t); + mars_x_1+= 0.00002620537 * cos( 3.04172154436 + 3337.08930835080*t); + mars_x_1+= 0.00001163612 * cos( 6.10909257097 + 16703.06213349900*t); + mars_x_1=mars_x_1 * t; + + double mars_x_2=0.0; + mars_x_2+= 0.00056323939 * cos( 0.00000000000 + 0.00000000000*t); + mars_x_2+= 0.00022122528 * cos( 3.54372113272 + 6681.22485339960*t); + mars_x_2+= 0.00006091409 * cos( 3.93272649649 + 10021.83728009940*t); + mars_x_2+= 0.00001451998 * cos( 3.64655666460 + 3340.61242669980*t); + mars_x_2+= 0.00001130613 * cos( 4.28827023222 + 13362.44970679920*t); + mars_x_2=mars_x_2 * t * t; + + return mars_x_0+mars_x_1+mars_x_2; +} + +double vsop87a_milli_mars_y(double t){ + double mars_y_0=0.0; + mars_y_0+= 1.51558976277 * cos( 4.63212206588 + 3340.61242669980*t); + mars_y_0+= 0.07064550239 * cos( 4.97051892902 + 6681.22485339960*t); + mars_y_0+= 0.08655481102 * cos( 0.00000000000 + 0.00000000000*t); + mars_y_0+= 0.00493872848 * cos( 5.30877806694 + 10021.83728009940*t); + mars_y_0+= 0.00040917422 * cos( 5.64698263703 + 13362.44970679920*t); + mars_y_0+= 0.00021036784 * cos( 0.23240270955 + 3337.08930835080*t); + mars_y_0+= 0.00021012921 * cos( 5.89022773653 + 3344.13554504880*t); + mars_y_0+= 0.00011370034 * cos( 3.26131408801 + 1059.38193018920*t); + mars_y_0+= 0.00013324177 * cos( 5.34259389724 + 529.69096509460*t); + mars_y_0+= 0.00006764653 * cos( 4.07671230062 + 3340.62968035200*t); + mars_y_0+= 0.00006764700 * cos( 2.04594066912 + 3340.59517304760*t); + mars_y_0+= 0.00008346220 * cos( 3.42464704002 + 2281.23049651060*t); + mars_y_0+= 0.00005400042 * cos( 5.81507793194 + 2942.46342329160*t); + mars_y_0+= 0.00004809528 * cos( 0.27875310553 + 3738.76143010800*t); + mars_y_0+= 0.00004849523 * cos( 2.85190987550 + 5621.84292321040*t); + mars_y_0+= 0.00005263268 * cos( 0.75811089992 + 6151.53388830500*t); + mars_y_0+= 0.00003609527 * cos( 4.53244488294 + 796.29800681640*t); + mars_y_0+= 0.00003724293 * cos( 5.98516013322 + 16703.06213349900*t); + mars_y_0+= 0.00003805073 * cos( 5.94234296399 + 398.14900340820*t); + mars_y_0+= 0.00002394490 * cos( 5.34678816191 + 3149.16416058820*t); + mars_y_0+= 0.00002251027 * cos( 0.76938193892 + 3532.06069281140*t); + mars_y_0+= 0.00001975769 * cos( 0.56949816579 + 6677.70173505060*t); + mars_y_0+= 0.00002226030 * cos( 5.99867316288 + 3340.67973700260*t); + mars_y_0+= 0.00002226089 * cos( 0.12398424247 + 3340.54511639700*t); + mars_y_0+= 0.00002177591 * cos( 0.12334436516 + 6283.07584999140*t); + mars_y_0+= 0.00001690439 * cos( 1.58331163985 + 5884.92684658320*t); + mars_y_0+= 0.00002234121 * cos( 3.24909113765 + 8962.45534991020*t); + mars_y_0+= 0.00001628395 * cos( 4.95250906888 + 4136.91043351620*t); + mars_y_0+= 0.00001956411 * cos( 6.23095843554 + 6684.74797174860*t); + mars_y_0+= 0.00001697214 * cos( 0.81869636263 + 2544.31441988340*t); + mars_y_0+= 0.00001385946 * cos( 3.73437191158 + 1751.53953141600*t); + mars_y_0+= 0.00001439619 * cos( 5.19505958438 + 2810.92146160520*t); + mars_y_0+= 0.00001281890 * cos( 3.13035275682 + 1194.44701022460*t); + mars_y_0+= 0.00001469783 * cos( 0.30415060688 + 3870.30339179440*t); + mars_y_0+= 0.00001571880 * cos( 3.27679498650 + 1589.07289528380*t); + mars_y_0+= 0.00001575854 * cos( 2.78266835243 + 5092.15195811580*t); + + double mars_y_1=0.0; + mars_y_1+= 0.01427324210 * cos( 3.14159265359 + 0.00000000000*t); + mars_y_1+= 0.00551063753 * cos( 3.52128320402 + 6681.22485339960*t); + mars_y_1+= 0.00077091913 * cos( 3.86082685753 + 10021.83728009940*t); + mars_y_1+= 0.00037310491 * cos( 1.16016958445 + 3340.61242669980*t); + mars_y_1+= 0.00009582122 * cos( 4.19942354479 + 13362.44970679920*t); + mars_y_1+= 0.00002617695 * cos( 1.47284555520 + 3337.08930835080*t); + mars_y_1+= 0.00002611572 * cos( 4.65030772498 + 3344.13554504880*t); + mars_y_1+= 0.00001162955 * cos( 4.53778503576 + 16703.06213349900*t); + mars_y_1=mars_y_1 * t; + + double mars_y_2=0.0; + mars_y_2+= 0.00035396765 * cos( 3.14159265359 + 0.00000000000*t); + mars_y_2+= 0.00021950759 * cos( 1.96291594946 + 6681.22485339960*t); + mars_y_2+= 0.00006075990 * cos( 2.35864321001 + 10021.83728009940*t); + mars_y_2+= 0.00002571425 * cos( 5.64795745327 + 3340.61242669980*t); + mars_y_2+= 0.00001129099 * cos( 2.71576248963 + 13362.44970679920*t); + mars_y_2=mars_y_2 * t * t; + + double mars_y_3=0.0; + mars_y_3+= 0.00001448778 * cos( 0.00000000000 + 0.00000000000*t); + mars_y_3=mars_y_3 * t * t * t; + + return mars_y_0+mars_y_1+mars_y_2+mars_y_3; +} + +double vsop87a_milli_mars_z(double t){ + double mars_z_0=0.0; + mars_z_0+= 0.04901207220 * cos( 3.76712324286 + 3340.61242669980*t); + mars_z_0+= 0.00660669541 * cos( 0.00000000000 + 0.00000000000*t); + mars_z_0+= 0.00228333904 * cos( 4.10544022266 + 6681.22485339960*t); + mars_z_0+= 0.00015958402 * cos( 4.44367058261 + 10021.83728009940*t); + mars_z_0+= 0.00001321976 * cos( 4.78186604114 + 13362.44970679920*t); + + double mars_z_1=0.0; + mars_z_1+= 0.00331842958 * cos( 6.05027773492 + 3340.61242669980*t); + mars_z_1+= 0.00047930411 * cos( 3.14159265359 + 0.00000000000*t); + mars_z_1+= 0.00009896501 * cos( 1.61155844715 + 6681.22485339960*t); + mars_z_1+= 0.00001700147 * cos( 2.63703242065 + 10021.83728009940*t); + mars_z_1=mars_z_1 * t; + + double mars_z_2=0.0; + mars_z_2+= 0.00013705360 * cos( 1.04212852598 + 3340.61242669980*t); + mars_z_2+= 0.00005931596 * cos( 3.14159265359 + 0.00000000000*t); + mars_z_2=mars_z_2 * t * t; + + return mars_z_0+mars_z_1+mars_z_2; +} + +double vsop87a_milli_mercury_x(double t){ + double mercury_x_0=0.0; + mercury_x_0+= 0.37546291728 * cos( 4.39651506942 + 26087.90314157420*t); + mercury_x_0+= 0.03825746672 * cos( 1.16485604339 + 52175.80628314840*t); + mercury_x_0+= 0.02625615963 * cos( 3.14159265359 + 0.00000000000*t); + mercury_x_0+= 0.00584261333 * cos( 4.21599394757 + 78263.70942472259*t); + mercury_x_0+= 0.00105716695 * cos( 0.98379033182 + 104351.61256629678*t); + mercury_x_0+= 0.00021011730 * cos( 4.03469353923 + 130439.51570787099*t); + mercury_x_0+= 0.00004433373 * cos( 0.80236674527 + 156527.41884944518*t); + + double mercury_x_1=0.0; + mercury_x_1+= 0.00318848034 * cos( 0.00000000000 + 0.00000000000*t); + mercury_x_1+= 0.00105289019 * cos( 5.91600475006 + 52175.80628314840*t); + mercury_x_1+= 0.00032316001 * cos( 2.68247273347 + 78263.70942472259*t); + mercury_x_1+= 0.00011992889 * cos( 5.81575112963 + 26087.90314157420*t); + mercury_x_1+= 0.00008783200 * cos( 5.73285747425 + 104351.61256629678*t); + mercury_x_1+= 0.00002329042 * cos( 2.50023793407 + 130439.51570787099*t); + mercury_x_1=mercury_x_1 * t; + + double mercury_x_2=0.0; + mercury_x_2+= 0.00001484185 * cos( 4.35401210269 + 52175.80628314840*t); + mercury_x_2+= 0.00001214995 * cos( 0.00000000000 + 0.00000000000*t); + mercury_x_2=mercury_x_2 * t * t; + + return mercury_x_0+mercury_x_1+mercury_x_2; +} + +double vsop87a_milli_mercury_y(double t){ + double mercury_y_0=0.0; + mercury_y_0+= 0.37953642888 * cos( 2.83780617820 + 26087.90314157420*t); + mercury_y_0+= 0.11626131831 * cos( 3.14159265359 + 0.00000000000*t); + mercury_y_0+= 0.03854668215 * cos( 5.88780608966 + 52175.80628314840*t); + mercury_y_0+= 0.00587711268 * cos( 2.65498896201 + 78263.70942472259*t); + mercury_y_0+= 0.00106235493 * cos( 5.70550616735 + 104351.61256629678*t); + mercury_y_0+= 0.00021100828 * cos( 2.47291315849 + 130439.51570787099*t); + mercury_y_0+= 0.00004450056 * cos( 5.52354907071 + 156527.41884944518*t); + + double mercury_y_1=0.0; + mercury_y_1+= 0.00107803852 * cos( 4.34964793883 + 52175.80628314840*t); + mercury_y_1+= 0.00080651544 * cos( 3.14159265359 + 0.00000000000*t); + mercury_y_1+= 0.00032715354 * cos( 1.11763734425 + 78263.70942472259*t); + mercury_y_1+= 0.00008858158 * cos( 4.16852401867 + 104351.61256629678*t); + mercury_y_1+= 0.00011914709 * cos( 1.22139986340 + 26087.90314157420*t); + mercury_y_1+= 0.00002344469 * cos( 0.93615372641 + 130439.51570787099*t); + mercury_y_1=mercury_y_1 * t; + + double mercury_y_2=0.0; + mercury_y_2+= 0.00004612157 * cos( 0.00000000000 + 0.00000000000*t); + mercury_y_2+= 0.00001575670 * cos( 2.81172733349 + 52175.80628314840*t); + mercury_y_2=mercury_y_2 * t * t; + + return mercury_y_0+mercury_y_1+mercury_y_2; +} + +double vsop87a_milli_mercury_z(double t){ + double mercury_z_0=0.0; + mercury_z_0+= 0.04607665326 * cos( 1.99295081967 + 26087.90314157420*t); + mercury_z_0+= 0.00708734365 * cos( 3.14159265359 + 0.00000000000*t); + mercury_z_0+= 0.00469171617 * cos( 5.04215742764 + 52175.80628314840*t); + mercury_z_0+= 0.00071626395 * cos( 1.80894256071 + 78263.70942472259*t); + mercury_z_0+= 0.00012957446 * cos( 4.85922032010 + 104351.61256629678*t); + mercury_z_0+= 0.00002575002 * cos( 1.62646731545 + 130439.51570787099*t); + + double mercury_z_1=0.0; + mercury_z_1+= 0.00108722177 * cos( 3.91134750825 + 26087.90314157420*t); + mercury_z_1+= 0.00057826621 * cos( 3.14159265359 + 0.00000000000*t); + mercury_z_1+= 0.00004297352 * cos( 2.56373047177 + 52175.80628314840*t); + mercury_z_1+= 0.00002435833 * cos( 0.05112640506 + 78263.70942472259*t); + mercury_z_1=mercury_z_1 * t; + + double mercury_z_2=0.0; + mercury_z_2+= 0.00001053118 * cos( 5.37979214357 + 26087.90314157420*t); + mercury_z_2+= 0.00001185024 * cos( 0.00000000000 + 0.00000000000*t); + mercury_z_2=mercury_z_2 * t * t; + + return mercury_z_0+mercury_z_1+mercury_z_2; +} + +double vsop87a_milli_neptune_x(double t){ + double neptune_x_0=0.0; + neptune_x_0+= 30.05890004476 * cos( 5.31211340029 + 38.13303563780*t); + neptune_x_0+= 0.27080164222 * cos( 3.14159265359 + 0.00000000000*t); + neptune_x_0+= 0.13505661755 * cos( 3.50078975634 + 76.26607127560*t); + neptune_x_0+= 0.15726094556 * cos( 0.11319072675 + 36.64856292950*t); + neptune_x_0+= 0.14935120126 * cos( 1.08499403018 + 39.61750834610*t); + neptune_x_0+= 0.02597313814 * cos( 1.99590301412 + 1.48447270830*t); + neptune_x_0+= 0.01074040708 * cos( 5.38502938672 + 74.78159856730*t); + neptune_x_0+= 0.00823793287 * cos( 1.43221581862 + 35.16409022120*t); + neptune_x_0+= 0.00817588813 * cos( 0.78180174031 + 2.96894541660*t); + neptune_x_0+= 0.00565534918 * cos( 5.98964907613 + 41.10198105440*t); + neptune_x_0+= 0.00495719107 * cos( 0.59948143567 + 529.69096509460*t); + neptune_x_0+= 0.00307525907 * cos( 0.40023311011 + 73.29712585900*t); + neptune_x_0+= 0.00272253551 * cos( 0.87443494387 + 213.29909543800*t); + neptune_x_0+= 0.00135887219 * cos( 5.54676577816 + 77.75054398390*t); + neptune_x_0+= 0.00090965704 * cos( 1.68910246115 + 114.39910691340*t); + neptune_x_0+= 0.00069040539 * cos( 5.83469123520 + 4.45341812490*t); + neptune_x_0+= 0.00060813556 * cos( 2.62589958380 + 33.67961751290*t); + neptune_x_0+= 0.00054690827 * cos( 1.55799996661 + 71.81265315070*t); + neptune_x_0+= 0.00028889260 * cos( 4.78966826027 + 42.58645376270*t); + neptune_x_0+= 0.00012614732 * cos( 3.57002516434 + 112.91463420510*t); + neptune_x_0+= 0.00012749153 * cos( 2.73719269645 + 111.43016149680*t); + neptune_x_0+= 0.00012013994 * cos( 0.94912933496 + 1059.38193018920*t); + neptune_x_0+= 0.00007540650 * cos( 2.77783477855 + 70.32818044240*t); + neptune_x_0+= 0.00007573383 * cos( 0.10011329853 + 426.59819087600*t); + neptune_x_0+= 0.00008004318 * cos( 1.63965626260 + 108.46121608020*t); + neptune_x_0+= 0.00006464842 * cos( 4.62580066013 + 5.93789083320*t); + neptune_x_0+= 0.00005565860 * cos( 3.82502185953 + 32.19514480460*t); + neptune_x_0+= 0.00004654361 * cos( 0.10385887980 + 37.61177077600*t); + neptune_x_0+= 0.00004732434 * cos( 4.09723977191 + 79.23501669220*t); + neptune_x_0+= 0.00004557247 * cos( 1.09712669317 + 38.65430049960*t); + neptune_x_0+= 0.00004322550 * cos( 2.37744780188 + 38.08485152800*t); + neptune_x_0+= 0.00004315539 * cos( 5.10473142056 + 38.18121974760*t); + neptune_x_0+= 0.00004089036 * cos( 1.99429048244 + 37.16982779130*t); + neptune_x_0+= 0.00004249674 * cos( 5.63324475823 + 28.57180808220*t); + neptune_x_0+= 0.00003920412 * cos( 5.49263784865 + 39.09624348430*t); + neptune_x_0+= 0.00003951848 * cos( 2.29996934110 + 98.89998852460*t); + neptune_x_0+= 0.00003322735 * cos( 4.68798591938 + 4.19278569400*t); + neptune_x_0+= 0.00003108292 * cos( 1.84434543409 + 47.69426319340*t); + neptune_x_0+= 0.00003260095 * cos( 1.81839652878 + 145.10977900970*t); + neptune_x_0+= 0.00002723442 * cos( 3.82296285941 + 109.94568878850*t); + neptune_x_0+= 0.00002522938 * cos( 4.66296126912 + 312.19908396260*t); + neptune_x_0+= 0.00001887430 * cos( 3.20485417792 + 35.68535508300*t); + neptune_x_0+= 0.00001648985 * cos( 4.06990666591 + 30.05628079050*t); + neptune_x_0+= 0.00001826700 * cos( 3.58024318649 + 44.07092647100*t); + neptune_x_0+= 0.00001945462 * cos( 4.15326825288 + 206.18554843720*t); + neptune_x_0+= 0.00001681255 * cos( 4.27560304282 + 40.58071619260*t); + neptune_x_0+= 0.00001533383 * cos( 1.17732211665 + 38.02116105320*t); + neptune_x_0+= 0.00001891892 * cos( 0.74998855536 + 220.41264243880*t); + neptune_x_0+= 0.00001527526 * cos( 0.02173640246 + 38.24491022240*t); + neptune_x_0+= 0.00002084477 * cos( 1.56821671369 + 149.56319713460*t); + neptune_x_0+= 0.00002083682 * cos( 2.83676961811 + 137.03302416240*t); + neptune_x_0+= 0.00001615063 * cos( 2.91063835010 + 106.97674337190*t); + neptune_x_0+= 0.00001265797 * cos( 3.42037275447 + 46.20979048510*t); + neptune_x_0+= 0.00001560429 * cos( 0.55865739143 + 37.87240320690*t); + neptune_x_0+= 0.00001545705 * cos( 0.64028780672 + 38.39366806870*t); + neptune_x_0+= 0.00001434798 * cos( 0.72658718863 + 522.57741809380*t); + neptune_x_0+= 0.00001271543 * cos( 2.74412981229 + 33.94024994380*t); + neptune_x_0+= 0.00001407422 * cos( 3.61743288666 + 536.80451209540*t); + neptune_x_0+= 0.00001387922 * cos( 3.71814330952 + 115.88357962170*t); + neptune_x_0+= 0.00001228939 * cos( 2.78878211792 + 72.07328558160*t); + neptune_x_0+= 0.00001448439 * cos( 1.98814317259 + 181.75834193920*t); + neptune_x_0+= 0.00001170078 * cos( 3.98594689041 + 8.07675484730*t); + neptune_x_0+= 0.00001080795 * cos( 4.75485636019 + 42.32582133180*t); + neptune_x_0+= 0.00001220341 * cos( 2.64791449584 + 148.07872442630*t); + + double neptune_x_1=0.0; + neptune_x_1+= 0.00255840261 * cos( 2.01935686795 + 36.64856292950*t); + neptune_x_1+= 0.00243125299 * cos( 5.46214902873 + 39.61750834610*t); + neptune_x_1+= 0.00118398168 * cos( 2.88251845061 + 76.26607127560*t); + neptune_x_1+= 0.00037965449 * cos( 3.14159265359 + 0.00000000000*t); + neptune_x_1+= 0.00021924705 * cos( 3.20156164152 + 35.16409022120*t); + neptune_x_1+= 0.00017459808 * cos( 4.26349398817 + 41.10198105440*t); + neptune_x_1+= 0.00013130617 * cos( 5.36424961848 + 2.96894541660*t); + neptune_x_1+= 0.00005086527 * cos( 1.92377354729 + 38.13303563780*t); + neptune_x_1+= 0.00004899718 * cos( 2.09349497813 + 73.29712585900*t); + neptune_x_1+= 0.00002745267 * cos( 4.06252818667 + 77.75054398390*t); + neptune_x_1+= 0.00002204414 * cos( 4.38855639521 + 33.67961751290*t); + neptune_x_1+= 0.00002168719 * cos( 4.11768012563 + 4.45341812490*t); + neptune_x_1+= 0.00001572202 * cos( 1.07606611589 + 114.39910691340*t); + neptune_x_1+= 0.00001344022 * cos( 3.03802059051 + 42.58645376270*t); + neptune_x_1+= 0.00001285542 * cos( 6.02367554997 + 74.78159856730*t); + neptune_x_1=neptune_x_1 * t; + + double neptune_x_2=0.0; + neptune_x_2+= 0.00005371138 * cos( 0.00000000000 + 0.00000000000*t); + neptune_x_2+= 0.00004536283 * cos( 5.02700751836 + 36.64856292950*t); + neptune_x_2+= 0.00004350766 * cos( 2.45420254304 + 39.61750834610*t); + neptune_x_2+= 0.00003092965 * cos( 0.62250463031 + 38.13303563780*t); + neptune_x_2+= 0.00002163703 * cos( 1.79218168368 + 76.26607127560*t); + neptune_x_2=neptune_x_2 * t * t; + + return neptune_x_0+neptune_x_1+neptune_x_2; +} + +double vsop87a_milli_neptune_y(double t){ + double neptune_y_0=0.0; + neptune_y_0+= 30.06056351665 * cos( 3.74086294714 + 38.13303563780*t); + neptune_y_0+= 0.30205857683 * cos( 3.14159265359 + 0.00000000000*t); + neptune_y_0+= 0.13506391797 * cos( 1.92953034883 + 76.26607127560*t); + neptune_y_0+= 0.15706589373 * cos( 4.82539970129 + 36.64856292950*t); + neptune_y_0+= 0.14936165806 * cos( 5.79694900665 + 39.61750834610*t); + neptune_y_0+= 0.02584250749 * cos( 0.42549700754 + 1.48447270830*t); + neptune_y_0+= 0.01073739772 * cos( 3.81371728533 + 74.78159856730*t); + neptune_y_0+= 0.00815187583 * cos( 5.49429775826 + 2.96894541660*t); + neptune_y_0+= 0.00582199295 * cos( 6.19633718936 + 35.16409022120*t); + neptune_y_0+= 0.00565576412 * cos( 4.41843009015 + 41.10198105440*t); + neptune_y_0+= 0.00495581047 * cos( 5.31205825784 + 529.69096509460*t); + neptune_y_0+= 0.00304525203 * cos( 5.11048113661 + 73.29712585900*t); + neptune_y_0+= 0.00272640298 * cos( 5.58603690785 + 213.29909543800*t); + neptune_y_0+= 0.00135897385 * cos( 3.97553750964 + 77.75054398390*t); + neptune_y_0+= 0.00090970871 * cos( 0.11783619888 + 114.39910691340*t); + neptune_y_0+= 0.00068790261 * cos( 4.26391997151 + 4.45341812490*t); + neptune_y_0+= 0.00028893355 * cos( 3.21848975032 + 42.58645376270*t); + neptune_y_0+= 0.00020081559 * cos( 1.19787916085 + 33.67961751290*t); + neptune_y_0+= 0.00012613583 * cos( 1.99777332934 + 112.91463420510*t); + neptune_y_0+= 0.00012828708 * cos( 1.16740053443 + 111.43016149680*t); + neptune_y_0+= 0.00012012961 * cos( 5.66157563804 + 1059.38193018920*t); + neptune_y_0+= 0.00008768580 * cos( 3.23487156950 + 108.46121608020*t); + neptune_y_0+= 0.00007581788 * cos( 4.81169168396 + 426.59819087600*t); + neptune_y_0+= 0.00006439265 * cos( 3.05453259951 + 5.93789083320*t); + neptune_y_0+= 0.00005297978 * cos( 0.79002313990 + 71.81265315070*t); + neptune_y_0+= 0.00004650708 * cos( 4.81540983294 + 37.61177077600*t); + neptune_y_0+= 0.00004733483 * cos( 2.52620194642 + 79.23501669220*t); + neptune_y_0+= 0.00004557247 * cos( 5.80951552318 + 38.65430049960*t); + neptune_y_0+= 0.00004322550 * cos( 0.80665145881 + 38.08485152800*t); + neptune_y_0+= 0.00004315539 * cos( 3.53393506841 + 38.18121974760*t); + neptune_y_0+= 0.00004089036 * cos( 0.42349446479 + 37.16982779130*t); + neptune_y_0+= 0.00004247643 * cos( 4.06355336504 + 28.57180808220*t); + neptune_y_0+= 0.00003932515 * cos( 3.91607592815 + 39.09624348430*t); + neptune_y_0+= 0.00003930135 * cos( 3.86614178174 + 98.89998852460*t); + neptune_y_0+= 0.00003323991 * cos( 3.11674274385 + 4.19278569400*t); + neptune_y_0+= 0.00003112636 * cos( 0.27319642944 + 47.69426319340*t); + neptune_y_0+= 0.00003373281 * cos( 3.39616255650 + 145.10977900970*t); + neptune_y_0+= 0.00002670944 * cos( 2.31235275416 + 109.94568878850*t); + neptune_y_0+= 0.00002523042 * cos( 6.23400745185 + 312.19908396260*t); + neptune_y_0+= 0.00001888827 * cos( 1.63364331324 + 35.68535508300*t); + neptune_y_0+= 0.00001647474 * cos( 2.50010254963 + 30.05628079050*t); + neptune_y_0+= 0.00001826390 * cos( 2.00938305966 + 44.07092647100*t); + neptune_y_0+= 0.00001967147 * cos( 2.56634772532 + 206.18554843720*t); + neptune_y_0+= 0.00001681258 * cos( 2.70480318579 + 40.58071619260*t); + neptune_y_0+= 0.00001533383 * cos( 5.88971113590 + 38.02116105320*t); + neptune_y_0+= 0.00001894261 * cos( 5.46274825258 + 220.41264243880*t); + neptune_y_0+= 0.00001527526 * cos( 4.73412534395 + 38.24491022240*t); + neptune_y_0+= 0.00002086907 * cos( 6.28313624461 + 149.56319713460*t); + neptune_y_0+= 0.00002057794 * cos( 4.38552505781 + 137.03302416240*t); + neptune_y_0+= 0.00001720954 * cos( 4.49400805134 + 106.97674337190*t); + neptune_y_0+= 0.00001314116 * cos( 1.80386443362 + 46.20979048510*t); + neptune_y_0+= 0.00001732739 * cos( 4.14518500834 + 70.32818044240*t); + neptune_y_0+= 0.00001559193 * cos( 5.27114846878 + 37.87240320690*t); + neptune_y_0+= 0.00001545705 * cos( 5.35267669439 + 38.39366806870*t); + neptune_y_0+= 0.00001435274 * cos( 5.44292013172 + 522.57741809380*t); + neptune_y_0+= 0.00001404991 * cos( 2.04611088339 + 536.80451209540*t); + neptune_y_0+= 0.00001242929 * cos( 1.10242173566 + 33.94024994380*t); + neptune_y_0+= 0.00001388024 * cos( 2.14792830412 + 115.88357962170*t); + neptune_y_0+= 0.00001467042 * cos( 3.56226463770 + 181.75834193920*t); + neptune_y_0+= 0.00001227926 * cos( 1.21334651843 + 72.07328558160*t); + neptune_y_0+= 0.00001080807 * cos( 3.18401661435 + 42.32582133180*t); + neptune_y_0+= 0.00001111708 * cos( 5.51669920239 + 8.07675484730*t); + neptune_y_0+= 0.00001237027 * cos( 1.08622199668 + 148.07872442630*t); + + double neptune_y_1=0.0; + neptune_y_1+= 0.00352947493 * cos( 3.14159265359 + 0.00000000000*t); + neptune_y_1+= 0.00256125493 * cos( 0.44757496817 + 36.64856292950*t); + neptune_y_1+= 0.00243147725 * cos( 3.89099798696 + 39.61750834610*t); + neptune_y_1+= 0.00118427205 * cos( 1.31128027037 + 76.26607127560*t); + neptune_y_1+= 0.00021936702 * cos( 1.63124087591 + 35.16409022120*t); + neptune_y_1+= 0.00017462332 * cos( 2.69229902966 + 41.10198105440*t); + neptune_y_1+= 0.00012992380 * cos( 3.79578633002 + 2.96894541660*t); + neptune_y_1+= 0.00004945117 * cos( 0.51727080684 + 73.29712585900*t); + neptune_y_1+= 0.00002745921 * cos( 2.49178311082 + 77.75054398390*t); + neptune_y_1+= 0.00002145481 * cos( 2.54768447291 + 4.45341812490*t); + neptune_y_1+= 0.00001572289 * cos( 5.78853350711 + 114.39910691340*t); + neptune_y_1+= 0.00001565725 * cos( 2.89846266272 + 33.67961751290*t); + neptune_y_1+= 0.00001458269 * cos( 1.61835542699 + 38.13303563780*t); + neptune_y_1+= 0.00001293459 * cos( 4.45868061082 + 74.78159856730*t); + neptune_y_1+= 0.00001343731 * cos( 1.46712622109 + 42.58645376270*t); + neptune_y_1=neptune_y_1 * t; + + double neptune_y_2=0.0; + neptune_y_2+= 0.00004539421 * cos( 3.45613207922 + 36.64856292950*t); + neptune_y_2+= 0.00004347956 * cos( 0.88317230351 + 39.61750834610*t); + neptune_y_2+= 0.00003595394 * cos( 3.14159265359 + 0.00000000000*t); + neptune_y_2+= 0.00003058647 * cos( 5.31956613665 + 38.13303563780*t); + neptune_y_2+= 0.00002163809 * cos( 0.22086532214 + 76.26607127560*t); + neptune_y_2=neptune_y_2 * t * t; + + return neptune_y_0+neptune_y_1+neptune_y_2; +} + +double vsop87a_milli_neptune_z(double t){ + double neptune_z_0=0.0; + neptune_z_0+= 0.92866054405 * cos( 1.44103930278 + 38.13303563780*t); + neptune_z_0+= 0.01245978462 * cos( 0.00000000000 + 0.00000000000*t); + neptune_z_0+= 0.00474333567 * cos( 2.52218774238 + 36.64856292950*t); + neptune_z_0+= 0.00451987936 * cos( 3.50949720541 + 39.61750834610*t); + neptune_z_0+= 0.00417558068 * cos( 5.91310695421 + 76.26607127560*t); + neptune_z_0+= 0.00084104329 * cos( 4.38928900096 + 1.48447270830*t); + neptune_z_0+= 0.00032704958 * cos( 1.52048692001 + 74.78159856730*t); + neptune_z_0+= 0.00030873335 * cos( 3.29017611456 + 35.16409022120*t); + neptune_z_0+= 0.00025812584 * cos( 3.19303128782 + 2.96894541660*t); + neptune_z_0+= 0.00016865319 * cos( 2.13251104425 + 41.10198105440*t); + neptune_z_0+= 0.00011789909 * cos( 3.60001877675 + 213.29909543800*t); + neptune_z_0+= 0.00009770125 * cos( 2.80133971586 + 73.29712585900*t); + neptune_z_0+= 0.00011279680 * cos( 3.55816676334 + 529.69096509460*t); + neptune_z_0+= 0.00004119873 * cos( 1.67934316836 + 77.75054398390*t); + neptune_z_0+= 0.00002818034 * cos( 4.10661077794 + 114.39910691340*t); + neptune_z_0+= 0.00002868677 * cos( 4.27011526203 + 33.67961751290*t); + neptune_z_0+= 0.00002213464 * cos( 1.96045135168 + 4.45341812490*t); + neptune_z_0+= 0.00001865650 * cos( 5.05540709577 + 71.81265315070*t); + + double neptune_z_1=0.0; + neptune_z_1+= 0.00154885971 * cos( 2.14239039664 + 38.13303563780*t); + neptune_z_1+= 0.00007783708 * cos( 4.40146905905 + 36.64856292950*t); + neptune_z_1+= 0.00006862414 * cos( 1.65930160610 + 39.61750834610*t); + neptune_z_1+= 0.00009464276 * cos( 0.00000000000 + 0.00000000000*t); + neptune_z_1+= 0.00003891873 * cos( 5.46761139427 + 76.26607127560*t); + neptune_z_1=neptune_z_1 * t; + + double neptune_z_2=0.0; + neptune_z_2+= 0.00001264840 * cos( 1.91401498992 + 38.13303563780*t); + neptune_z_2=neptune_z_2 * t * t; + + return neptune_z_0+neptune_z_1+neptune_z_2; +} + +double vsop87a_milli_saturn_x(double t){ + double saturn_x_0=0.0; + saturn_x_0+= 9.51638335797 * cos( 0.87441380794 + 213.29909543800*t); + saturn_x_0+= 0.26412374238 * cos( 0.12390892620 + 426.59819087600*t); + saturn_x_0+= 0.06760430339 * cos( 4.16767145778 + 206.18554843720*t); + saturn_x_0+= 0.06624260115 * cos( 0.75094737780 + 220.41264243880*t); + saturn_x_0+= 0.04244797817 * cos( 0.00000000000 + 0.00000000000*t); + saturn_x_0+= 0.02336340488 * cos( 2.02227784673 + 7.11354700080*t); + saturn_x_0+= 0.01255372247 * cos( 2.17338917731 + 110.20632121940*t); + saturn_x_0+= 0.01115684467 * cos( 3.15686878377 + 419.48464387520*t); + saturn_x_0+= 0.01097683232 * cos( 5.65753337256 + 639.89728631400*t); + saturn_x_0+= 0.00716328481 * cos( 2.71149993708 + 316.39186965660*t); + saturn_x_0+= 0.00509313365 * cos( 4.95865624780 + 103.09277421860*t); + saturn_x_0+= 0.00433994439 * cos( 0.72012820974 + 529.69096509460*t); + saturn_x_0+= 0.00372894461 * cos( 0.00137195497 + 433.71173787680*t); + saturn_x_0+= 0.00097843523 * cos( 1.01485750417 + 323.50541665740*t); + saturn_x_0+= 0.00080600536 * cos( 5.62103979796 + 11.04570026390*t); + saturn_x_0+= 0.00083782316 * cos( 0.62038893702 + 227.52618943960*t); + saturn_x_0+= 0.00074150224 * cos( 2.38206066655 + 632.78373931320*t); + saturn_x_0+= 0.00070219382 * cos( 0.88789752415 + 209.36694217490*t); + saturn_x_0+= 0.00068855792 * cos( 4.01788097627 + 217.23124870110*t); + saturn_x_0+= 0.00065620467 * cos( 2.69728593339 + 202.25339517410*t); + saturn_x_0+= 0.00058297911 * cos( 2.16155251399 + 224.34479570190*t); + saturn_x_0+= 0.00054022837 * cos( 4.90928184374 + 853.19638175200*t); + saturn_x_0+= 0.00045550446 * cos( 1.88235037830 + 14.22709400160*t); + saturn_x_0+= 0.00038345667 * cos( 4.39815501478 + 199.07200143640*t); + saturn_x_0+= 0.00044551703 * cos( 5.60763553535 + 63.73589830340*t); + saturn_x_0+= 0.00025165185 * cos( 0.37800582257 + 216.48048917570*t); + saturn_x_0+= 0.00024554499 * cos( 4.53150598095 + 210.11770170030*t); + saturn_x_0+= 0.00024673219 * cos( 5.90891573850 + 522.57741809380*t); + saturn_x_0+= 0.00024677050 * cos( 5.60389382420 + 415.55249061210*t); + saturn_x_0+= 0.00025491374 * cos( 1.63922423181 + 117.31986822020*t); + saturn_x_0+= 0.00031253049 * cos( 4.62976601833 + 735.87651353180*t); + saturn_x_0+= 0.00023372467 * cos( 5.53491987276 + 647.01083331480*t); + saturn_x_0+= 0.00023355468 * cos( 0.18791490124 + 149.56319713460*t); + saturn_x_0+= 0.00024805815 * cos( 5.50327676733 + 74.78159856730*t); + saturn_x_0+= 0.00014731703 * cos( 4.67981909838 + 277.03499374140*t); + saturn_x_0+= 0.00012427525 * cos( 1.02995545746 + 1059.38193018920*t); + saturn_x_0+= 0.00009943329 * cos( 0.84628387596 + 3.93215326310*t); + saturn_x_0+= 0.00012393514 * cos( 4.19747622821 + 490.33408917940*t); + saturn_x_0+= 0.00012026472 * cos( 5.66372282839 + 351.81659230870*t); + saturn_x_0+= 0.00008222014 * cos( 2.47875301104 + 742.99006053260*t); + saturn_x_0+= 0.00009087093 * cos( 4.33505326762 + 1052.26838318840*t); + saturn_x_0+= 0.00006717741 * cos( 5.51897460997 + 838.96928775040*t); + saturn_x_0+= 0.00006232999 * cos( 2.45837758015 + 846.08283475120*t); + saturn_x_0+= 0.00007161671 * cos( 2.18152751738 + 95.97922721780*t); + saturn_x_0+= 0.00006321101 * cos( 0.83915408770 + 309.27832265580*t); + saturn_x_0+= 0.00006074958 * cos( 6.15905897331 + 440.82528487760*t); + saturn_x_0+= 0.00005343894 * cos( 3.60046273598 + 412.37109687440*t); + saturn_x_0+= 0.00004860582 * cos( 0.26461045175 + 536.80451209540*t); + saturn_x_0+= 0.00005775802 * cos( 5.30717695229 + 38.13303563780*t); + saturn_x_0+= 0.00005194178 * cos( 4.54584467686 + 210.85141488320*t); + saturn_x_0+= 0.00005152474 * cos( 0.34669517150 + 215.74677599280*t); + saturn_x_0+= 0.00003792540 * cos( 5.99766568983 + 422.66603761290*t); + saturn_x_0+= 0.00003762834 * cos( 3.72112920226 + 212.33588759150*t); + saturn_x_0+= 0.00003747433 * cos( 1.16965137714 + 214.26230328450*t); + saturn_x_0+= 0.00003114576 * cos( 0.84631897292 + 213.25091132820*t); + saturn_x_0+= 0.00003113641 * cos( 4.04410367190 + 213.34727954780*t); + saturn_x_0+= 0.00002990421 * cos( 0.04148806852 + 625.67019231240*t); + saturn_x_0+= 0.00004111695 * cos( 5.96153153046 + 137.03302416240*t); + saturn_x_0+= 0.00002966450 * cos( 5.39568820046 + 138.51749687070*t); + saturn_x_0+= 0.00002827527 * cos( 0.73252555642 + 330.61896365820*t); + saturn_x_0+= 0.00003363323 * cos( 1.42089586686 + 437.64389113990*t); + saturn_x_0+= 0.00002886599 * cos( 1.14057922619 + 85.82729883120*t); + saturn_x_0+= 0.00002634075 * cos( 5.40645201521 + 288.08069400530*t); + saturn_x_0+= 0.00002713354 * cos( 0.96812639712 + 203.73786788240*t); + saturn_x_0+= 0.00003169390 * cos( 5.76640408988 + 76.26607127560*t); + saturn_x_0+= 0.00002618634 * cos( 5.49334837098 + 127.47179660680*t); + saturn_x_0+= 0.00002527746 * cos( 5.09752068381 + 628.85158605010*t); + saturn_x_0+= 0.00002989778 * cos( 4.15673836604 + 1066.49547719000*t); + saturn_x_0+= 0.00002507415 * cos( 1.49447138038 + 9.56122755560*t); + saturn_x_0+= 0.00002470181 * cos( 5.27435870056 + 1155.36115740700*t); + saturn_x_0+= 0.00002427626 * cos( 3.97311214231 + 222.86032299360*t); + saturn_x_0+= 0.00003128325 * cos( 4.05483976553 + 1368.66025284500*t); + saturn_x_0+= 0.00002309076 * cos( 3.67821438247 + 430.53034413910*t); + saturn_x_0+= 0.00002162629 * cos( 3.26951119901 + 340.77089204480*t); + saturn_x_0+= 0.00002912676 * cos( 1.76893577106 + 3.18139373770*t); + saturn_x_0+= 0.00002095366 * cos( 3.55759089756 + 423.41679713830*t); + saturn_x_0+= 0.00002335270 * cos( 5.86791072516 + 388.46515523820*t); + saturn_x_0+= 0.00001634262 * cos( 4.54357767539 + 12.53017297220*t); + saturn_x_0+= 0.00001635975 * cos( 2.19968869780 + 212.77783057620*t); + saturn_x_0+= 0.00001632759 * cos( 2.69164822165 + 213.82036029980*t); + saturn_x_0+= 0.00001498689 * cos( 3.60168057129 + 52.69019803950*t); + saturn_x_0+= 0.00001461217 * cos( 5.92456743836 + 429.77958461370*t); + saturn_x_0+= 0.00001963947 * cos( 2.05086487180 + 1.48447270830*t); + saturn_x_0+= 0.00001538425 * cos( 4.78544077085 + 860.30992875280*t); + saturn_x_0+= 0.00001485856 * cos( 5.65501463408 + 949.17560896980*t); + saturn_x_0+= 0.00001418116 * cos( 5.41419993599 + 350.33211960040*t); + saturn_x_0+= 0.00001147607 * cos( 0.19147238521 + 942.06206196900*t); + saturn_x_0+= 0.00001111703 * cos( 0.47907488492 + 234.63973644040*t); + saturn_x_0+= 0.00001019566 * cos( 5.00707811029 + 1471.75302706360*t); + saturn_x_0+= 0.00001009190 * cos( 1.34289487761 + 265.98929347750*t); + saturn_x_0+= 0.00001089450 * cos( 5.82690672710 + 362.86229257260*t); + saturn_x_0+= 0.00001092244 * cos( 1.13561107749 + 173.94221952280*t); + saturn_x_0+= 0.00001173456 * cos( 3.79591687208 + 1685.05212250160*t); + saturn_x_0+= 0.00001118369 * cos( 3.46624149583 + 703.63318461740*t); + saturn_x_0+= 0.00001150595 * cos( 3.74707160019 + 200.76892246580*t); + saturn_x_0+= 0.00001007761 * cos( 1.08964371328 + 225.82926841020*t); + + double saturn_x_1=0.0; + saturn_x_1+= 0.07575103962 * cos( 0.00000000000 + 0.00000000000*t); + saturn_x_1+= 0.03085041716 * cos( 4.27565749128 + 426.59819087600*t); + saturn_x_1+= 0.02714918399 * cos( 5.85229412397 + 206.18554843720*t); + saturn_x_1+= 0.02643100909 * cos( 5.33291950584 + 220.41264243880*t); + saturn_x_1+= 0.00627104520 * cos( 0.32898307969 + 7.11354700080*t); + saturn_x_1+= 0.00256560953 * cos( 3.52478934343 + 639.89728631400*t); + saturn_x_1+= 0.00312356512 * cos( 4.83001724941 + 419.48464387520*t); + saturn_x_1+= 0.00189196274 * cos( 4.48642453552 + 433.71173787680*t); + saturn_x_1+= 0.00203646570 * cos( 1.10998681782 + 213.29909543800*t); + saturn_x_1+= 0.00119531145 * cos( 1.14735096078 + 110.20632121940*t); + saturn_x_1+= 0.00066764238 * cos( 3.72346596928 + 316.39186965660*t); + saturn_x_1+= 0.00066901225 * cos( 5.20257500380 + 227.52618943960*t); + saturn_x_1+= 0.00031000840 * cos( 6.06067919437 + 199.07200143640*t); + saturn_x_1+= 0.00030418100 * cos( 0.18746903351 + 14.22709400160*t); + saturn_x_1+= 0.00022275210 * cos( 6.19530878014 + 103.09277421860*t); + saturn_x_1+= 0.00018939377 * cos( 2.77618306725 + 853.19638175200*t); + saturn_x_1+= 0.00018093009 * cos( 5.09162723865 + 209.36694217490*t); + saturn_x_1+= 0.00017777854 * cos( 6.10381593351 + 217.23124870110*t); + saturn_x_1+= 0.00016296201 * cos( 4.86945681437 + 216.48048917570*t); + saturn_x_1+= 0.00017120250 * cos( 4.59611664188 + 632.78373931320*t); + saturn_x_1+= 0.00015894491 * cos( 0.03653502304 + 210.11770170030*t); + saturn_x_1+= 0.00016192653 * cos( 5.60798014450 + 323.50541665740*t); + saturn_x_1+= 0.00014466010 * cos( 3.67449380090 + 647.01083331480*t); + saturn_x_1+= 0.00011061528 * cos( 0.03163071461 + 117.31986822020*t); + saturn_x_1+= 0.00009873183 * cos( 5.20065307357 + 202.25339517410*t); + saturn_x_1+= 0.00008707608 * cos( 6.03511731637 + 224.34479570190*t); + saturn_x_1+= 0.00005499109 * cos( 4.40350603415 + 440.82528487760*t); + saturn_x_1+= 0.00005512222 * cos( 2.60556642348 + 11.04570026390*t); + saturn_x_1+= 0.00004008257 * cos( 1.48942966807 + 522.57741809380*t); + saturn_x_1+= 0.00003571196 * cos( 5.10821908379 + 412.37109687440*t); + saturn_x_1+= 0.00002731381 * cos( 4.10892223660 + 149.56319713460*t); + saturn_x_1+= 0.00002763786 * cos( 3.96253590209 + 95.97922721780*t); + saturn_x_1+= 0.00001875862 * cos( 2.52384080586 + 3.93215326310*t); + saturn_x_1+= 0.00001765816 * cos( 0.75684544353 + 277.03499374140*t); + saturn_x_1+= 0.00001688957 * cos( 3.98270950731 + 422.66603761290*t); + saturn_x_1+= 0.00001544787 * cos( 5.30283923836 + 330.61896365820*t); + saturn_x_1+= 0.00001449143 * cos( 6.26507179861 + 529.69096509460*t); + saturn_x_1+= 0.00001395551 * cos( 2.03533642541 + 1066.49547719000*t); + saturn_x_1+= 0.00001330413 * cos( 5.06312203212 + 234.63973644040*t); + saturn_x_1+= 0.00001511648 * cos( 6.23274598777 + 3.18139373770*t); + saturn_x_1+= 0.00001271050 * cos( 2.40338468675 + 415.55249061210*t); + saturn_x_1+= 0.00001171680 * cos( 4.59341412127 + 536.80451209540*t); + saturn_x_1+= 0.00001129056 * cos( 5.45794529295 + 423.41679713830*t); + saturn_x_1+= 0.00001126400 * cos( 2.88173213734 + 860.30992875280*t); + saturn_x_1+= 0.00001101245 * cos( 4.07698108824 + 429.77958461370*t); + saturn_x_1+= 0.00001273315 * cos( 0.09572429396 + 742.99006053260*t); + saturn_x_1+= 0.00001342277 * cos( 2.98929557875 + 210.85141488320*t); + saturn_x_1+= 0.00001331045 * cos( 1.90899526877 + 215.74677599280*t); + saturn_x_1=saturn_x_1 * t; + + double saturn_x_2=0.0; + saturn_x_2+= 0.00560746334 * cos( 1.26401632282 + 206.18554843720*t); + saturn_x_2+= 0.00545834518 * cos( 3.62343709657 + 220.41264243880*t); + saturn_x_2+= 0.00443342186 * cos( 3.14159265359 + 0.00000000000*t); + saturn_x_2+= 0.00336109713 * cos( 2.42547432460 + 213.29909543800*t); + saturn_x_2+= 0.00224302269 * cos( 2.49151203519 + 426.59819087600*t); + saturn_x_2+= 0.00087170924 * cos( 4.89048951691 + 7.11354700080*t); + saturn_x_2+= 0.00050028094 * cos( 2.70119046081 + 433.71173787680*t); + saturn_x_2+= 0.00045122590 * cos( 0.36735068943 + 419.48464387520*t); + saturn_x_2+= 0.00032847824 * cos( 1.59210153669 + 639.89728631400*t); + saturn_x_2+= 0.00027153555 * cos( 3.49804002218 + 227.52618943960*t); + saturn_x_2+= 0.00012676167 * cos( 1.45465729530 + 199.07200143640*t); + saturn_x_2+= 0.00010330738 * cos( 4.76949531290 + 14.22709400160*t); + saturn_x_2+= 0.00007249149 * cos( 5.70264553247 + 110.20632121940*t); + saturn_x_2+= 0.00004653214 * cos( 1.83710048213 + 647.01083331480*t); + saturn_x_2+= 0.00004923585 * cos( 3.08463039042 + 216.48048917570*t); + saturn_x_2+= 0.00004777358 * cos( 1.81695155349 + 210.11770170030*t); + saturn_x_2+= 0.00004166633 * cos( 5.32887874226 + 316.39186965660*t); + saturn_x_2+= 0.00003508385 * cos( 0.78251653369 + 853.19638175200*t); + saturn_x_2+= 0.00002660470 * cos( 3.16731393212 + 209.36694217490*t); + saturn_x_2+= 0.00002538027 * cos( 2.65097612407 + 440.82528487760*t); + saturn_x_2+= 0.00002568114 * cos( 1.74024228572 + 217.23124870110*t); + saturn_x_2+= 0.00002503277 * cos( 4.69450368911 + 117.31986822020*t); + saturn_x_2+= 0.00002506986 * cos( 1.74781817701 + 103.09277421860*t); + saturn_x_2+= 0.00002129256 * cos( 0.28453141367 + 632.78373931320*t); + saturn_x_2+= 0.00001841989 * cos( 3.99269872894 + 323.50541665740*t); + saturn_x_2+= 0.00001228511 * cos( 0.42906039519 + 412.37109687440*t); + saturn_x_2=saturn_x_2 * t * t; + + double saturn_x_3=0.0; + saturn_x_3+= 0.00077115952 * cos( 2.97714385362 + 206.18554843720*t); + saturn_x_3+= 0.00075340436 * cos( 1.89208005248 + 220.41264243880*t); + saturn_x_3+= 0.00018450895 * cos( 3.14159265359 + 0.00000000000*t); + saturn_x_3+= 0.00010527244 * cos( 0.66368256891 + 426.59819087600*t); + saturn_x_3+= 0.00008994946 * cos( 0.91696559755 + 433.71173787680*t); + saturn_x_3+= 0.00007403594 * cos( 1.78627385870 + 227.52618943960*t); + saturn_x_3+= 0.00008045160 * cos( 3.12864412887 + 7.11354700080*t); + saturn_x_3+= 0.00004505149 * cos( 2.24531319187 + 419.48464387520*t); + saturn_x_3+= 0.00003468010 * cos( 3.14590544446 + 199.07200143640*t); + saturn_x_3+= 0.00002974601 * cos( 6.00030641555 + 639.89728631400*t); + saturn_x_3+= 0.00002342089 * cos( 3.06091771643 + 14.22709400160*t); + saturn_x_3+= 0.00001230715 * cos( 4.38196130069 + 213.29909543800*t); + saturn_x_3+= 0.00001023888 * cos( 0.01138655869 + 647.01083331480*t); + saturn_x_3=saturn_x_3 * t * t * t; + + double saturn_x_4=0.0; + saturn_x_4+= 0.00007959921 * cos( 4.70523623364 + 206.18554843720*t); + saturn_x_4+= 0.00007836652 * cos( 0.13981693631 + 220.41264243880*t); + saturn_x_4+= 0.00001511196 * cos( 0.06561560462 + 227.52618943960*t); + saturn_x_4+= 0.00001223066 * cos( 5.41618485361 + 433.71173787680*t); + saturn_x_4=saturn_x_4 * t * t * t * t; + + return saturn_x_0+saturn_x_1+saturn_x_2+saturn_x_3+saturn_x_4; +} + +double vsop87a_milli_saturn_y(double t){ + double saturn_y_0=0.0; + saturn_y_0+= 9.52986882699 * cos( 5.58600556665 + 213.29909543800*t); + saturn_y_0+= 0.79387988806 * cos( 3.14159265359 + 0.00000000000*t); + saturn_y_0+= 0.26441781302 * cos( 4.83528061849 + 426.59819087600*t); + saturn_y_0+= 0.06916653915 * cos( 2.55279408706 + 206.18554843720*t); + saturn_y_0+= 0.06633570703 * cos( 5.46258848288 + 220.41264243880*t); + saturn_y_0+= 0.02345609742 * cos( 0.44652132519 + 7.11354700080*t); + saturn_y_0+= 0.01183874652 * cos( 1.34638298371 + 419.48464387520*t); + saturn_y_0+= 0.01245790434 * cos( 0.60367177975 + 110.20632121940*t); + saturn_y_0+= 0.01098751131 * cos( 4.08608782813 + 639.89728631400*t); + saturn_y_0+= 0.00700849336 * cos( 1.13611298025 + 316.39186965660*t); + saturn_y_0+= 0.00434466176 * cos( 5.42474696262 + 529.69096509460*t); + saturn_y_0+= 0.00373327342 * cos( 4.71308726958 + 433.71173787680*t); + saturn_y_0+= 0.00335162363 * cos( 0.66422253983 + 103.09277421860*t); + saturn_y_0+= 0.00097837745 * cos( 5.72844290173 + 323.50541665740*t); + saturn_y_0+= 0.00080571808 * cos( 4.05295449910 + 11.04570026390*t); + saturn_y_0+= 0.00083899691 * cos( 5.33204070267 + 227.52618943960*t); + saturn_y_0+= 0.00070158491 * cos( 5.59777963629 + 209.36694217490*t); + saturn_y_0+= 0.00065937657 * cos( 1.25969608208 + 202.25339517410*t); + saturn_y_0+= 0.00070957225 * cos( 0.88888207567 + 632.78373931320*t); + saturn_y_0+= 0.00068985859 * cos( 2.44460312617 + 217.23124870110*t); + saturn_y_0+= 0.00058382264 * cos( 0.58978766922 + 224.34479570190*t); + saturn_y_0+= 0.00054049836 * cos( 3.33757904879 + 853.19638175200*t); + saturn_y_0+= 0.00045790930 * cos( 0.30331527632 + 14.22709400160*t); + saturn_y_0+= 0.00041976402 * cos( 2.62591355948 + 199.07200143640*t); + saturn_y_0+= 0.00044697175 * cos( 0.90661238256 + 63.73589830340*t); + saturn_y_0+= 0.00025199575 * cos( 5.08963506006 + 216.48048917570*t); + saturn_y_0+= 0.00024640836 * cos( 2.95445247282 + 210.11770170030*t); + saturn_y_0+= 0.00024835151 * cos( 4.02630190571 + 415.55249061210*t); + saturn_y_0+= 0.00025545907 * cos( 0.06626229252 + 117.31986822020*t); + saturn_y_0+= 0.00029666833 * cos( 6.09910638345 + 735.87651353180*t); + saturn_y_0+= 0.00023396742 * cos( 3.96337393635 + 647.01083331480*t); + saturn_y_0+= 0.00023380691 * cos( 4.90051072276 + 149.56319713460*t); + saturn_y_0+= 0.00020272215 * cos( 2.34319548198 + 309.27832265580*t); + saturn_y_0+= 0.00020099552 * cos( 0.98365186365 + 522.57741809380*t); + saturn_y_0+= 0.00024827950 * cos( 3.92681428900 + 74.78159856730*t); + saturn_y_0+= 0.00015383927 * cos( 3.10227822627 + 277.03499374140*t); + saturn_y_0+= 0.00011629210 * cos( 5.74108283772 + 1059.38193018920*t); + saturn_y_0+= 0.00012422966 * cos( 2.62557865743 + 490.33408917940*t); + saturn_y_0+= 0.00012048048 * cos( 4.09265980116 + 351.81659230870*t); + saturn_y_0+= 0.00009551796 * cos( 3.48788042094 + 95.97922721780*t); + saturn_y_0+= 0.00007670379 * cos( 1.16594276164 + 742.99006053260*t); + saturn_y_0+= 0.00006919946 * cos( 1.17090063883 + 412.37109687440*t); + saturn_y_0+= 0.00009034877 * cos( 5.86816144198 + 1052.26838318840*t); + saturn_y_0+= 0.00006536751 * cos( 0.84246459392 + 838.96928775040*t); + saturn_y_0+= 0.00006082097 * cos( 4.58758280729 + 440.82528487760*t); + saturn_y_0+= 0.00005027211 * cos( 0.93213690546 + 846.08283475120*t); + saturn_y_0+= 0.00004838146 * cos( 4.98563812475 + 536.80451209540*t); + saturn_y_0+= 0.00005768897 * cos( 3.73776690402 + 38.13303563780*t); + saturn_y_0+= 0.00005201849 * cos( 2.97482802430 + 210.85141488320*t); + saturn_y_0+= 0.00005156578 * cos( 5.05796998564 + 215.74677599280*t); + saturn_y_0+= 0.00003792348 * cos( 4.41806046981 + 422.66603761290*t); + saturn_y_0+= 0.00003881104 * cos( 3.38026646963 + 3.93215326310*t); + saturn_y_0+= 0.00003768751 * cos( 2.14954247360 + 212.33588759150*t); + saturn_y_0+= 0.00003752010 * cos( 5.88125434018 + 214.26230328450*t); + saturn_y_0+= 0.00003118938 * cos( 5.55799397159 + 213.25091132820*t); + saturn_y_0+= 0.00003118056 * cos( 2.47259780102 + 213.34727954780*t); + saturn_y_0+= 0.00003815691 * cos( 2.44166851155 + 625.67019231240*t); + saturn_y_0+= 0.00004042463 * cos( 1.24471211016 + 137.03302416240*t); + saturn_y_0+= 0.00002829944 * cos( 5.44434225998 + 330.61896365820*t); + saturn_y_0+= 0.00003367270 * cos( 6.13298847057 + 437.64389113990*t); + saturn_y_0+= 0.00002891352 * cos( 5.85313497106 + 85.82729883120*t); + saturn_y_0+= 0.00002774595 * cos( 5.61594351302 + 203.73786788240*t); + saturn_y_0+= 0.00002638715 * cos( 3.83678156812 + 288.08069400530*t); + saturn_y_0+= 0.00003171680 * cos( 4.19553075395 + 76.26607127560*t); + saturn_y_0+= 0.00002532374 * cos( 3.52629372341 + 628.85158605010*t); + saturn_y_0+= 0.00002533632 * cos( 3.89788590926 + 138.51749687070*t); + saturn_y_0+= 0.00002982174 * cos( 2.58535107213 + 1066.49547719000*t); + saturn_y_0+= 0.00002620642 * cos( 0.69751279148 + 127.47179660680*t); + saturn_y_0+= 0.00002501775 * cos( 6.19929274396 + 9.56122755560*t); + saturn_y_0+= 0.00002448467 * cos( 0.54179432209 + 1155.36115740700*t); + saturn_y_0+= 0.00002431496 * cos( 2.40122451395 + 222.86032299360*t); + saturn_y_0+= 0.00003138628 * cos( 5.63058455924 + 1368.66025284500*t); + saturn_y_0+= 0.00002269226 * cos( 2.12401905105 + 430.53034413910*t); + saturn_y_0+= 0.00002078049 * cos( 1.95682348964 + 423.41679713830*t); + saturn_y_0+= 0.00002670750 * cos( 0.18165311734 + 3.18139373770*t); + saturn_y_0+= 0.00002339764 * cos( 4.29619053852 + 388.46515523820*t); + saturn_y_0+= 0.00001636580 * cos( 2.97440139727 + 12.53017297220*t); + saturn_y_0+= 0.00001639181 * cos( 0.62823227849 + 212.77783057620*t); + saturn_y_0+= 0.00001634235 * cos( 1.12043073218 + 213.82036029980*t); + saturn_y_0+= 0.00001499665 * cos( 5.16865990579 + 52.69019803950*t); + saturn_y_0+= 0.00001462908 * cos( 4.35285690993 + 429.77958461370*t); + saturn_y_0+= 0.00001678952 * cos( 2.07211719214 + 949.17560896980*t); + saturn_y_0+= 0.00001989253 * cos( 0.42496478369 + 1.48447270830*t); + saturn_y_0+= 0.00001540242 * cos( 3.21449770483 + 860.30992875280*t); + saturn_y_0+= 0.00001437063 * cos( 3.84293543293 + 350.33211960040*t); + saturn_y_0+= 0.00001276377 * cos( 2.98728987770 + 340.77089204480*t); + saturn_y_0+= 0.00001152164 * cos( 1.78736848302 + 942.06206196900*t); + saturn_y_0+= 0.00001112617 * cos( 5.19114183145 + 234.63973644040*t); + saturn_y_0+= 0.00001011023 * cos( 0.27242160432 + 1471.75302706360*t); + saturn_y_0+= 0.00001162807 * cos( 2.35040840317 + 200.76892246580*t); + saturn_y_0+= 0.00001091025 * cos( 4.25638370205 + 362.86229257260*t); + saturn_y_0+= 0.00001090678 * cos( 5.85086226218 + 173.94221952280*t); + saturn_y_0+= 0.00001186647 * cos( 5.38323620554 + 1685.05212250160*t); + saturn_y_0+= 0.00001120819 * cos( 1.89478696683 + 703.63318461740*t); + saturn_y_0+= 0.00001008898 * cos( 5.80110302450 + 225.82926841020*t); + + double saturn_y_1=0.0; + saturn_y_1+= 0.05373889135 * cos( 0.00000000000 + 0.00000000000*t); + saturn_y_1+= 0.03090575152 * cos( 2.70346890906 + 426.59819087600*t); + saturn_y_1+= 0.02741594312 * cos( 4.26667636015 + 206.18554843720*t); + saturn_y_1+= 0.02647489677 * cos( 3.76132298889 + 220.41264243880*t); + saturn_y_1+= 0.00631520527 * cos( 5.03245505280 + 7.11354700080*t); + saturn_y_1+= 0.00256799701 * cos( 1.95351819758 + 639.89728631400*t); + saturn_y_1+= 0.00312271930 * cos( 3.25850205023 + 419.48464387520*t); + saturn_y_1+= 0.00189433319 * cos( 2.91501840819 + 433.71173787680*t); + saturn_y_1+= 0.00164133553 * cos( 5.29239290066 + 213.29909543800*t); + saturn_y_1+= 0.00116791227 * cos( 5.89146675760 + 110.20632121940*t); + saturn_y_1+= 0.00067210919 * cos( 2.17042636344 + 316.39186965660*t); + saturn_y_1+= 0.00067003292 * cos( 3.63101075514 + 227.52618943960*t); + saturn_y_1+= 0.00033002406 * cos( 4.35527405801 + 199.07200143640*t); + saturn_y_1+= 0.00030628998 * cos( 4.88861760772 + 14.22709400160*t); + saturn_y_1+= 0.00022234714 * cos( 4.62212779231 + 103.09277421860*t); + saturn_y_1+= 0.00018945004 * cos( 1.20412493845 + 853.19638175200*t); + saturn_y_1+= 0.00018079959 * cos( 3.51566153251 + 209.36694217490*t); + saturn_y_1+= 0.00017791543 * cos( 4.53214140649 + 217.23124870110*t); + saturn_y_1+= 0.00016320701 * cos( 3.29784030970 + 216.48048917570*t); + saturn_y_1+= 0.00015944258 * cos( 4.74503265169 + 210.11770170030*t); + saturn_y_1+= 0.00016717122 * cos( 3.00270792752 + 632.78373931320*t); + saturn_y_1+= 0.00016149947 * cos( 4.04186432517 + 323.50541665740*t); + saturn_y_1+= 0.00014481431 * cos( 2.10298298650 + 647.01083331480*t); + saturn_y_1+= 0.00011084040 * cos( 4.74073871754 + 117.31986822020*t); + saturn_y_1+= 0.00009905491 * cos( 3.60258599375 + 202.25339517410*t); + saturn_y_1+= 0.00008726051 * cos( 4.46341342877 + 224.34479570190*t); + saturn_y_1+= 0.00006585597 * cos( 4.07326320487 + 309.27832265580*t); + saturn_y_1+= 0.00005505978 * cos( 2.83207390240 + 440.82528487760*t); + saturn_y_1+= 0.00005424041 * cos( 1.03197684410 + 11.04570026390*t); + saturn_y_1+= 0.00004178266 * cos( 3.01038512076 + 412.37109687440*t); + saturn_y_1+= 0.00004049905 * cos( 5.17488767645 + 95.97922721780*t); + saturn_y_1+= 0.00002735256 * cos( 2.53975850409 + 149.56319713460*t); + saturn_y_1+= 0.00002369024 * cos( 2.40497927917 + 522.57741809380*t); + saturn_y_1+= 0.00001745258 * cos( 5.50576015456 + 277.03499374140*t); + saturn_y_1+= 0.00001692790 * cos( 2.39926502529 + 422.66603761290*t); + saturn_y_1+= 0.00001546006 * cos( 3.73156925599 + 330.61896365820*t); + saturn_y_1+= 0.00001389354 * cos( 0.46207025895 + 1066.49547719000*t); + saturn_y_1+= 0.00001332553 * cos( 3.49199812296 + 234.63973644040*t); + saturn_y_1+= 0.00001300934 * cos( 0.83727681906 + 415.55249061210*t); + saturn_y_1+= 0.00001393622 * cos( 4.62214277175 + 3.18139373770*t); + saturn_y_1+= 0.00001174319 * cos( 2.72609984335 + 846.08283475120*t); + saturn_y_1+= 0.00001148010 * cos( 3.04374738882 + 536.80451209540*t); + saturn_y_1+= 0.00001314125 * cos( 4.38891656600 + 625.67019231240*t); + saturn_y_1+= 0.00001127952 * cos( 3.87309692307 + 423.41679713830*t); + saturn_y_1+= 0.00001127646 * cos( 1.31088906213 + 860.30992875280*t); + saturn_y_1+= 0.00001519732 * cos( 6.12880664637 + 3.93215326310*t); + saturn_y_1+= 0.00001102361 * cos( 2.50535306014 + 429.77958461370*t); + saturn_y_1+= 0.00001344891 * cos( 1.41793593685 + 210.85141488320*t); + saturn_y_1+= 0.00001331786 * cos( 0.33834520814 + 215.74677599280*t); + saturn_y_1=saturn_y_1 * t; + + double saturn_y_2=0.0; + saturn_y_2+= 0.00563706537 * cos( 5.97115878242 + 206.18554843720*t); + saturn_y_2+= 0.00547012116 * cos( 2.05154973426 + 220.41264243880*t); + saturn_y_2+= 0.00458518613 * cos( 0.00000000000 + 0.00000000000*t); + saturn_y_2+= 0.00362294249 * cos( 0.89540100509 + 213.29909543800*t); + saturn_y_2+= 0.00225521642 * cos( 0.91699821445 + 426.59819087600*t); + saturn_y_2+= 0.00088390611 * cos( 3.30289449917 + 7.11354700080*t); + saturn_y_2+= 0.00050101314 * cos( 1.12976163835 + 433.71173787680*t); + saturn_y_2+= 0.00045516403 * cos( 5.07669466539 + 419.48464387520*t); + saturn_y_2+= 0.00032896745 * cos( 0.02089057938 + 639.89728631400*t); + saturn_y_2+= 0.00027199743 * cos( 1.92638417640 + 227.52618943960*t); + saturn_y_2+= 0.00013251505 * cos( 6.07693099404 + 199.07200143640*t); + saturn_y_2+= 0.00010425984 * cos( 3.18246869028 + 14.22709400160*t); + saturn_y_2+= 0.00006673556 * cos( 4.24747633887 + 110.20632121940*t); + saturn_y_2+= 0.00004658591 * cos( 0.26557833758 + 647.01083331480*t); + saturn_y_2+= 0.00004934094 * cos( 1.51301179516 + 216.48048917570*t); + saturn_y_2+= 0.00004789554 * cos( 0.24337901916 + 210.11770170030*t); + saturn_y_2+= 0.00004167268 * cos( 3.73203671391 + 316.39186965660*t); + saturn_y_2+= 0.00003509537 * cos( 5.49281440568 + 853.19638175200*t); + saturn_y_2+= 0.00002743470 * cos( 6.21939083886 + 103.09277421860*t); + saturn_y_2+= 0.00002661172 * cos( 1.58795412736 + 209.36694217490*t); + saturn_y_2+= 0.00002541191 * cos( 1.07964653574 + 440.82528487760*t); + saturn_y_2+= 0.00002568018 * cos( 0.16811216098 + 217.23124870110*t); + saturn_y_2+= 0.00002507738 * cos( 3.11882746290 + 117.31986822020*t); + saturn_y_2+= 0.00002159089 * cos( 4.99912567024 + 632.78373931320*t); + saturn_y_2+= 0.00001828412 * cos( 2.43368650590 + 323.50541665740*t); + saturn_y_2+= 0.00001351629 * cos( 4.81673889364 + 412.37109687440*t); + saturn_y_2+= 0.00001177305 * cos( 5.84484412189 + 309.27832265580*t); + saturn_y_2=saturn_y_2 * t * t; + + double saturn_y_3=0.0; + saturn_y_3+= 0.00077376615 * cos( 1.40391048961 + 206.18554843720*t); + saturn_y_3+= 0.00075564351 * cos( 0.31962896379 + 220.41264243880*t); + saturn_y_3+= 0.00022843837 * cos( 3.14159265359 + 0.00000000000*t); + saturn_y_3+= 0.00010672263 * cos( 5.36495663820 + 426.59819087600*t); + saturn_y_3+= 0.00009010175 * cos( 5.62865146645 + 433.71173787680*t); + saturn_y_3+= 0.00007418018 * cos( 0.21442310101 + 227.52618943960*t); + saturn_y_3+= 0.00008298723 * cos( 1.52262563519 + 7.11354700080*t); + saturn_y_3+= 0.00004507061 * cos( 0.67248969480 + 419.48464387520*t); + saturn_y_3+= 0.00003581682 * cos( 1.51466786030 + 199.07200143640*t); + saturn_y_3+= 0.00002981969 * cos( 4.42868951627 + 639.89728631400*t); + saturn_y_3+= 0.00002376221 * cos( 1.46232779180 + 14.22709400160*t); + saturn_y_3+= 0.00001024263 * cos( 4.72337917196 + 647.01083331480*t); + saturn_y_3=saturn_y_3 * t * t * t; + + double saturn_y_4=0.0; + saturn_y_4+= 0.00007978886 * cos( 3.13229268011 + 206.18554843720*t); + saturn_y_4+= 0.00007868379 * cos( 4.84940260021 + 220.41264243880*t); + saturn_y_4+= 0.00001514835 * cos( 4.77675733867 + 227.52618943960*t); + saturn_y_4+= 0.00001225569 * cos( 3.84500138574 + 433.71173787680*t); + saturn_y_4=saturn_y_4 * t * t * t * t; + + return saturn_y_0+saturn_y_1+saturn_y_2+saturn_y_3+saturn_y_4; +} + +double vsop87a_milli_saturn_z(double t){ + double saturn_z_0=0.0; + saturn_z_0+= 0.41356950940 * cos( 3.60234142982 + 213.29909543800*t); + saturn_z_0+= 0.01148283576 * cos( 2.85128367469 + 426.59819087600*t); + saturn_z_0+= 0.01214249867 * cos( 0.00000000000 + 0.00000000000*t); + saturn_z_0+= 0.00329280791 * cos( 0.57121407104 + 206.18554843720*t); + saturn_z_0+= 0.00286934048 * cos( 3.48073526693 + 220.41264243880*t); + saturn_z_0+= 0.00099076584 * cos( 4.73369511264 + 7.11354700080*t); + saturn_z_0+= 0.00057361820 * cos( 4.92611225093 + 110.20632121940*t); + saturn_z_0+= 0.00047738127 * cos( 2.10039779728 + 639.89728631400*t); + saturn_z_0+= 0.00043458803 * cos( 5.84904978051 + 419.48464387520*t); + saturn_z_0+= 0.00034565673 * cos( 5.42614229590 + 316.39186965660*t); + saturn_z_0+= 0.00016185391 * cos( 2.72987173675 + 433.71173787680*t); + saturn_z_0+= 0.00009001270 * cos( 1.38140102737 + 103.09277421860*t); + saturn_z_0+= 0.00011433574 * cos( 3.71662021072 + 529.69096509460*t); + saturn_z_0+= 0.00005398708 * cos( 5.13204892363 + 202.25339517410*t); + saturn_z_0+= 0.00003902467 * cos( 3.71499738796 + 323.50541665740*t); + saturn_z_0+= 0.00003709212 * cos( 5.05549348785 + 632.78373931320*t); + saturn_z_0+= 0.00003614100 * cos( 3.35210451276 + 227.52618943960*t); + saturn_z_0+= 0.00003379953 * cos( 2.13868919206 + 11.04570026390*t); + saturn_z_0+= 0.00003089874 * cos( 3.62572857085 + 209.36694217490*t); + saturn_z_0+= 0.00002683064 * cos( 4.87689555581 + 224.34479570190*t); + saturn_z_0+= 0.00002963493 * cos( 0.46490184985 + 217.23124870110*t); + saturn_z_0+= 0.00002343367 * cos( 1.34558278340 + 853.19638175200*t); + saturn_z_0+= 0.00002423663 * cos( 2.92907094760 + 63.73589830340*t); + saturn_z_0+= 0.00001701916 * cos( 1.89892525654 + 735.87651353180*t); + saturn_z_0+= 0.00001941205 * cos( 4.59421314662 + 14.22709400160*t); + saturn_z_0+= 0.00001990145 * cos( 0.73166053611 + 199.07200143640*t); + saturn_z_0+= 0.00001460265 * cos( 3.12851339724 + 522.57741809380*t); + saturn_z_0+= 0.00001148341 * cos( 4.41139213915 + 117.31986822020*t); + saturn_z_0+= 0.00001092809 * cos( 3.10679381209 + 216.48048917570*t); + saturn_z_0+= 0.00001015179 * cos( 1.97897195994 + 647.01083331480*t); + saturn_z_0+= 0.00001098254 * cos( 0.96097709156 + 210.11770170030*t); + saturn_z_0+= 0.00001028743 * cos( 2.11933059243 + 415.55249061210*t); + + double saturn_z_1=0.0; + saturn_z_1+= 0.01906503283 * cos( 4.94544746116 + 213.29909543800*t); + saturn_z_1+= 0.00528301265 * cos( 3.14159265359 + 0.00000000000*t); + saturn_z_1+= 0.00130262284 * cos( 2.26140980879 + 206.18554843720*t); + saturn_z_1+= 0.00101466332 * cos( 1.79095829545 + 220.41264243880*t); + saturn_z_1+= 0.00085947578 * cos( 0.51612788497 + 426.59819087600*t); + saturn_z_1+= 0.00022257446 * cos( 3.07684015656 + 7.11354700080*t); + saturn_z_1+= 0.00016179946 * cos( 1.19987517506 + 419.48464387520*t); + saturn_z_1+= 0.00009117402 * cos( 6.17205626814 + 639.89728631400*t); + saturn_z_1+= 0.00007470703 * cos( 0.93135621171 + 433.71173787680*t); + saturn_z_1+= 0.00004966668 * cos( 0.19044864213 + 316.39186965660*t); + saturn_z_1+= 0.00003816564 * cos( 4.38284565245 + 110.20632121940*t); + saturn_z_1+= 0.00002724120 * cos( 1.65580138665 + 227.52618943960*t); + saturn_z_1+= 0.00001734540 * cos( 3.51628075636 + 103.09277421860*t); + saturn_z_1+= 0.00001541995 * cos( 2.42323572812 + 199.07200143640*t); + saturn_z_1+= 0.00001209302 * cos( 2.91140089093 + 14.22709400160*t); + saturn_z_1=saturn_z_1 * t; + + double saturn_z_2=0.0; + saturn_z_2+= 0.00131275155 * cos( 0.08868998101 + 213.29909543800*t); + saturn_z_2+= 0.00030147649 * cos( 3.91396203887 + 206.18554843720*t); + saturn_z_2+= 0.00019322173 * cos( 0.09228748624 + 220.41264243880*t); + saturn_z_2+= 0.00006868926 * cos( 5.48420255395 + 426.59819087600*t); + saturn_z_2+= 0.00002826107 * cos( 1.36583318555 + 7.11354700080*t); + saturn_z_2+= 0.00002646332 * cos( 2.94607395955 + 419.48464387520*t); + saturn_z_2+= 0.00003138233 * cos( 0.00000000000 + 0.00000000000*t); + saturn_z_2+= 0.00001844798 * cos( 5.43612062856 + 433.71173787680*t); + saturn_z_2+= 0.00001055383 * cos( 6.23890785179 + 227.52618943960*t); + saturn_z_2+= 0.00001036435 * cos( 4.33916308552 + 639.89728631400*t); + saturn_z_2=saturn_z_2 * t * t; + + double saturn_z_3=0.0; + saturn_z_3+= 0.00004559419 * cos( 1.70646871501 + 213.29909543800*t); + saturn_z_3+= 0.00004779074 * cos( 5.57723756330 + 206.18554843720*t); + saturn_z_3+= 0.00003965402 * cos( 0.00000000000 + 0.00000000000*t); + saturn_z_3+= 0.00002508242 * cos( 4.64959056313 + 220.41264243880*t); + saturn_z_3=saturn_z_3 * t * t * t; + + return saturn_z_0+saturn_z_1+saturn_z_2+saturn_z_3; +} + +double vsop87a_milli_uranus_x(double t){ + double uranus_x_0=0.0; + uranus_x_0+= 19.17370730359 * cos( 5.48133416489 + 74.78159856730*t); + uranus_x_0+= 1.32272523872 * cos( 0.00000000000 + 0.00000000000*t); + uranus_x_0+= 0.44402496796 * cos( 1.65967519586 + 149.56319713460*t); + uranus_x_0+= 0.14668209481 * cos( 3.42395862804 + 73.29712585900*t); + uranus_x_0+= 0.14130269479 * cos( 4.39572927934 + 76.26607127560*t); + uranus_x_0+= 0.06201106178 * cos( 5.14043574125 + 1.48447270830*t); + uranus_x_0+= 0.01542951343 * cos( 4.12121838072 + 224.34479570190*t); + uranus_x_0+= 0.01444216660 * cos( 2.65117115201 + 148.07872442630*t); + uranus_x_0+= 0.00944995563 * cos( 1.65869338757 + 11.04570026390*t); + uranus_x_0+= 0.00657524815 * cos( 0.57595170636 + 151.04766984290*t); + uranus_x_0+= 0.00621624676 * cos( 3.05882246638 + 77.75054398390*t); + uranus_x_0+= 0.00585182542 * cos( 4.79934779678 + 71.81265315070*t); + uranus_x_0+= 0.00634000270 * cos( 4.09556589724 + 63.73589830340*t); + uranus_x_0+= 0.00547699056 * cos( 3.63127725056 + 85.82729883120*t); + uranus_x_0+= 0.00458219984 * cos( 3.90788284112 + 2.96894541660*t); + uranus_x_0+= 0.00496087649 * cos( 0.59947400861 + 529.69096509460*t); + uranus_x_0+= 0.00383625535 * cos( 6.18762010576 + 138.51749687070*t); + uranus_x_0+= 0.00267938156 * cos( 0.96885660137 + 213.29909543800*t); + uranus_x_0+= 0.00215368005 * cos( 5.30877641428 + 38.13303563780*t); + uranus_x_0+= 0.00145505389 * cos( 2.31759757085 + 70.84944530420*t); + uranus_x_0+= 0.00135340032 * cos( 5.51062460816 + 78.71375183040*t); + uranus_x_0+= 0.00119593859 * cos( 4.10138544267 + 39.61750834610*t); + uranus_x_0+= 0.00125105686 * cos( 2.51455273063 + 111.43016149680*t); + uranus_x_0+= 0.00111260244 * cos( 5.12252784325 + 222.86032299360*t); + uranus_x_0+= 0.00104619827 * cos( 3.90538916334 + 146.59425171800*t); + uranus_x_0+= 0.00110125387 * cos( 4.45473528724 + 35.16409022120*t); + uranus_x_0+= 0.00063584588 * cos( 0.29966233158 + 299.12639426920*t); + uranus_x_0+= 0.00053904041 * cos( 3.92590422507 + 3.93215326310*t); + uranus_x_0+= 0.00065066905 * cos( 3.73008452906 + 109.94568878850*t); + uranus_x_0+= 0.00039181662 * cos( 2.68841280769 + 4.45341812490*t); + uranus_x_0+= 0.00034341683 * cos( 3.03781661928 + 225.82926841020*t); + uranus_x_0+= 0.00033134636 * cos( 2.54201591218 + 65.22037101170*t); + uranus_x_0+= 0.00034555652 * cos( 1.84699329257 + 79.23501669220*t); + uranus_x_0+= 0.00033867050 * cos( 5.98418436103 + 70.32818044240*t); + uranus_x_0+= 0.00028371614 * cos( 2.58026657123 + 127.47179660680*t); + uranus_x_0+= 0.00035943348 * cos( 4.08754543016 + 202.25339517410*t); + uranus_x_0+= 0.00025208833 * cos( 5.30272144657 + 9.56122755560*t); + uranus_x_0+= 0.00023467802 * cos( 4.09729860322 + 145.63104387150*t); + uranus_x_0+= 0.00022963939 * cos( 5.51475073655 + 84.34282612290*t); + uranus_x_0+= 0.00031823951 * cos( 5.53948583244 + 152.53214255120*t); + uranus_x_0+= 0.00028384953 * cos( 6.01785430306 + 184.72728735580*t); + uranus_x_0+= 0.00026657176 * cos( 6.11027939727 + 160.60889739850*t); + uranus_x_0+= 0.00019676762 * cos( 5.53431398332 + 74.66972398270*t); + uranus_x_0+= 0.00019653873 * cos( 2.28660913421 + 74.89347315190*t); + uranus_x_0+= 0.00019954280 * cos( 0.57450958037 + 12.53017297220*t); + uranus_x_0+= 0.00018565067 * cos( 0.62225019017 + 52.69019803950*t); + uranus_x_0+= 0.00020084756 * cos( 4.47297488471 + 22.09140052780*t); + uranus_x_0+= 0.00019926329 * cos( 1.39878194708 + 112.91463420510*t); + uranus_x_0+= 0.00018575632 * cos( 5.70217475790 + 33.67961751290*t); + uranus_x_0+= 0.00016587870 * cos( 4.86920309163 + 108.46121608020*t); + uranus_x_0+= 0.00015171194 * cos( 2.88415453399 + 41.10198105440*t); + uranus_x_0+= 0.00011245800 * cos( 6.11597016146 + 71.60020482960*t); + uranus_x_0+= 0.00013948521 * cos( 6.27545694160 + 221.37585028530*t); + uranus_x_0+= 0.00010798350 * cos( 1.70031857078 + 77.96299230500*t); + uranus_x_0+= 0.00013593955 * cos( 2.55407820633 + 87.31177153950*t); + uranus_x_0+= 0.00011997848 * cos( 0.94875212305 + 1059.38193018920*t); + uranus_x_0+= 0.00012884351 * cos( 5.08737999470 + 145.10977900970*t); + uranus_x_0+= 0.00012394786 * cos( 6.21892878850 + 72.33391801250*t); + uranus_x_0+= 0.00012253318 * cos( 0.19452856525 + 36.64856292950*t); + uranus_x_0+= 0.00011538642 * cos( 1.77241794539 + 77.22927912210*t); + uranus_x_0+= 0.00008738409 * cos( 4.96956808452 + 186.21176006410*t); + uranus_x_0+= 0.00007095608 * cos( 1.30384750044 + 297.64192156090*t); + uranus_x_0+= 0.00006262602 * cos( 1.71385983783 + 153.49535039770*t); + uranus_x_0+= 0.00007487302 * cos( 0.11408470667 + 426.59819087600*t); + uranus_x_0+= 0.00007798974 * cos( 5.82410372587 + 340.77089204480*t); + uranus_x_0+= 0.00006669249 * cos( 5.08626589612 + 62.25142559510*t); + uranus_x_0+= 0.00005505358 * cos( 3.31282108025 + 140.00196957900*t); + uranus_x_0+= 0.00005372927 * cos( 4.12498282863 + 75.30286342910*t); + uranus_x_0+= 0.00005354242 * cos( 3.69263973447 + 74.26033370550*t); + uranus_x_0+= 0.00004478123 * cos( 1.11838191479 + 66.70484372000*t); + uranus_x_0+= 0.00004233075 * cos( 3.94913608184 + 265.98929347750*t); + uranus_x_0+= 0.00005038353 * cos( 4.68664376918 + 18.15924726470*t); + uranus_x_0+= 0.00004570470 * cos( 0.97536665751 + 183.24281464750*t); + uranus_x_0+= 0.00004751325 * cos( 4.95762395337 + 73.81839072080*t); + uranus_x_0+= 0.00004448651 * cos( 0.29436142982 + 114.39910691340*t); + uranus_x_0+= 0.00003312340 * cos( 0.52418923788 + 82.85835341460*t); + uranus_x_0+= 0.00004515952 * cos( 2.88576303120 + 75.74480641380*t); + uranus_x_0+= 0.00003559276 * cos( 1.47627607503 + 5.93789083320*t); + uranus_x_0+= 0.00003268117 * cos( 0.51827231333 + 220.41264243880*t); + uranus_x_0+= 0.00003578235 * cos( 1.11528903208 + 137.03302416240*t); + uranus_x_0+= 0.00003004737 * cos( 5.12122132051 + 7.11354700080*t); + uranus_x_0+= 0.00002882392 * cos( 2.76136583899 + 373.90799283650*t); + uranus_x_0+= 0.00002579454 * cos( 3.84784330333 + 277.03499374140*t); + uranus_x_0+= 0.00002597765 * cos( 0.22409539936 + 96.87299909510*t); + uranus_x_0+= 0.00002560744 * cos( 4.44236223450 + 80.19822453870*t); + uranus_x_0+= 0.00002722745 * cos( 6.09456175016 + 106.97674337190*t); + uranus_x_0+= 0.00002528025 * cos( 0.89508396542 + 68.84370773410*t); + uranus_x_0+= 0.00002631138 * cos( 0.04831552531 + 305.34616939270*t); + uranus_x_0+= 0.00002541716 * cos( 0.64495056482 + 32.19514480460*t); + uranus_x_0+= 0.00002241129 * cos( 5.22377697501 + 3.18139373770*t); + uranus_x_0+= 0.00001965145 * cos( 0.09207526632 + 20.60692781950*t); + uranus_x_0+= 0.00002232022 * cos( 0.63571664756 + 80.71948940050*t); + uranus_x_0+= 0.00001933814 * cos( 5.75490033864 + 74.73341445750*t); + uranus_x_0+= 0.00001933817 * cos( 2.06557585395 + 74.82978267710*t); + uranus_x_0+= 0.00002138391 * cos( 4.20897429922 + 74.52096613640*t); + uranus_x_0+= 0.00002126427 * cos( 3.61171465436 + 75.04223099820*t); + uranus_x_0+= 0.00002215516 * cos( 2.18613112875 + 259.50888592310*t); + uranus_x_0+= 0.00001891213 * cos( 5.49941424248 + 300.61086697750*t); + uranus_x_0+= 0.00001927679 * cos( 1.29228021932 + 159.12442469020*t); + uranus_x_0+= 0.00001796558 * cos( 5.73271543335 + 74.62153987290*t); + uranus_x_0+= 0.00001792522 * cos( 2.08789166984 + 74.94165726170*t); + uranus_x_0+= 0.00001873542 * cos( 4.23391867169 + 206.18554843720*t); + uranus_x_0+= 0.00002182901 * cos( 1.23755478345 + 479.28838891550*t); + uranus_x_0+= 0.00001860591 * cos( 1.67536711716 + 42.58645376270*t); + uranus_x_0+= 0.00002075591 * cos( 3.15586933464 + 131.40394986990*t); + uranus_x_0+= 0.00001912582 * cos( 5.83091918696 + 14.97785352700*t); + uranus_x_0+= 0.00001529180 * cos( 2.05204104820 + 191.20769491020*t); + uranus_x_0+= 0.00002064173 * cos( 3.60208606410 + 835.03713448730*t); + uranus_x_0+= 0.00001768763 * cos( 1.19254481620 + 219.89137757700*t); + uranus_x_0+= 0.00001892359 * cos( 4.32128621847 + 154.01661525950*t); + uranus_x_0+= 0.00001797047 * cos( 1.73417465594 + 227.31374111850*t); + uranus_x_0+= 0.00001558489 * cos( 6.16891070489 + 59.80374504030*t); + uranus_x_0+= 0.00001672893 * cos( 0.01232646186 + 143.62530630140*t); + uranus_x_0+= 0.00001467268 * cos( 2.10975578758 + 2.44768055480*t); + uranus_x_0+= 0.00001677659 * cos( 0.42525121334 + 8.07675484730*t); + uranus_x_0+= 0.00001347303 * cos( 5.46763140224 + 288.08069400530*t); + uranus_x_0+= 0.00001744555 * cos( 0.82022450313 + 56.62235130260*t); + uranus_x_0+= 0.00001427180 * cos( 0.38786175669 + 92.94084583200*t); + uranus_x_0+= 0.00001263032 * cos( 5.63689596853 + 404.50679034820*t); + uranus_x_0+= 0.00001221506 * cos( 5.20012455894 + 54.17467074780*t); + uranus_x_0+= 0.00001574905 * cos( 5.72297800263 + 39.35687591520*t); + uranus_x_0+= 0.00001269686 * cos( 2.66330104031 + 142.44965013380*t); + uranus_x_0+= 0.00001438869 * cos( 0.72633739717 + 522.57741809380*t); + uranus_x_0+= 0.00001408997 * cos( 3.61751904356 + 536.80451209540*t); + uranus_x_0+= 0.00001418300 * cos( 2.29718712012 + 235.39049596580*t); + uranus_x_0+= 0.00001040948 * cos( 2.74644165501 + 5.41662597140*t); + uranus_x_0+= 0.00001256867 * cos( 5.61684736425 + 67.66805156650*t); + uranus_x_0+= 0.00001164218 * cos( 2.08302637541 + 81.89514556810*t); + uranus_x_0+= 0.00001009252 * cos( 2.02320517037 + 74.03083904190*t); + uranus_x_0+= 0.00001077810 * cos( 1.05685900920 + 128.95626931510*t); + uranus_x_0+= 0.00001212025 * cos( 3.41577832660 + 211.81462272970*t); + uranus_x_0+= 0.00001223648 * cos( 3.84373514640 + 187.69623277240*t); + uranus_x_0+= 0.00001334371 * cos( 2.17621743689 + 380.12776796000*t); + uranus_x_0+= 0.00001144565 * cos( 2.42148845239 + 296.15744885260*t); + uranus_x_0+= 0.00001241589 * cos( 1.81282962357 + 134.58534360760*t); + uranus_x_0+= 0.00001192274 * cos( 5.58661990233 + 50.40257617910*t); + uranus_x_0+= 0.00001093678 * cos( 3.94451812233 + 230.56457082540*t); + uranus_x_0+= 0.00001077916 * cos( 5.01417740021 + 181.75834193920*t); + uranus_x_0+= 0.00001166898 * cos( 2.02955848543 + 110.20632121940*t); + uranus_x_0+= 0.00001056848 * cos( 5.53440854164 + 14.01464568050*t); + + double uranus_x_1=0.0; + uranus_x_1+= 0.00739730021 * cos( 6.01067825116 + 149.56319713460*t); + uranus_x_1+= 0.00526878306 * cos( 3.14159265359 + 0.00000000000*t); + uranus_x_1+= 0.00239840801 * cos( 5.33657762707 + 73.29712585900*t); + uranus_x_1+= 0.00229676787 * cos( 2.48204455775 + 76.26607127560*t); + uranus_x_1+= 0.00111045158 * cos( 5.57157235960 + 11.04570026390*t); + uranus_x_1+= 0.00096352822 * cos( 0.35070389084 + 63.73589830340*t); + uranus_x_1+= 0.00081511870 * cos( 1.21058618039 + 85.82729883120*t); + uranus_x_1+= 0.00045687564 * cos( 2.29216583843 + 138.51749687070*t); + uranus_x_1+= 0.00051382501 * cos( 2.18935125260 + 224.34479570190*t); + uranus_x_1+= 0.00038844330 * cos( 0.30724575951 + 70.84944530420*t); + uranus_x_1+= 0.00036158493 * cos( 1.23634798757 + 78.71375183040*t); + uranus_x_1+= 0.00032333094 * cos( 5.06666556704 + 74.78159856730*t); + uranus_x_1+= 0.00021685656 * cos( 4.93710968392 + 151.04766984290*t); + uranus_x_1+= 0.00019441970 * cos( 1.30617490304 + 77.75054398390*t); + uranus_x_1+= 0.00017376241 * cos( 0.24607221230 + 71.81265315070*t); + uranus_x_1+= 0.00015211071 * cos( 5.53141633140 + 3.93215326310*t); + uranus_x_1+= 0.00007735984 * cos( 1.61349552789 + 71.60020482960*t); + uranus_x_1+= 0.00007425078 * cos( 6.20357977116 + 77.96299230500*t); + uranus_x_1+= 0.00006995857 * cos( 2.40633283814 + 145.63104387150*t); + uranus_x_1+= 0.00007291691 * cos( 2.23597571444 + 2.96894541660*t); + uranus_x_1+= 0.00007585264 * cos( 2.76074218330 + 148.07872442630*t); + uranus_x_1+= 0.00004378335 * cos( 3.74296322240 + 160.60889739850*t); + uranus_x_1+= 0.00004127713 * cos( 1.48475181305 + 22.09140052780*t); + uranus_x_1+= 0.00003933541 * cos( 4.73864204208 + 65.22037101170*t); + uranus_x_1+= 0.00002910312 * cos( 5.91941333050 + 127.47179660680*t); + uranus_x_1+= 0.00002788434 * cos( 4.90117297196 + 213.29909543800*t); + uranus_x_1+= 0.00002802392 * cos( 3.76505436434 + 52.69019803950*t); + uranus_x_1+= 0.00002545264 * cos( 3.36768337628 + 9.56122755560*t); + uranus_x_1+= 0.00002647073 * cos( 4.53813176345 + 12.53017297220*t); + uranus_x_1+= 0.00003177614 * cos( 4.65226634926 + 299.12639426920*t); + uranus_x_1+= 0.00002228396 * cos( 0.18087986338 + 87.31177153950*t); + uranus_x_1+= 0.00002824668 * cos( 3.40143685673 + 84.34282612290*t); + uranus_x_1+= 0.00002525203 * cos( 2.83821144961 + 18.15924726470*t); + uranus_x_1+= 0.00002216987 * cos( 4.78338909951 + 72.33391801250*t); + uranus_x_1+= 0.00001624493 * cos( 3.75817281127 + 153.49535039770*t); + uranus_x_1+= 0.00001928881 * cos( 2.39940180311 + 39.61750834610*t); + uranus_x_1+= 0.00001555444 * cos( 4.13741667297 + 73.81839072080*t); + uranus_x_1+= 0.00001600865 * cos( 0.08376247543 + 79.23501669220*t); + uranus_x_1+= 0.00001476317 * cos( 3.67283851029 + 75.74480641380*t); + uranus_x_1+= 0.00001427088 * cos( 1.45690759014 + 70.32818044240*t); + uranus_x_1+= 0.00001533469 * cos( 3.71776498048 + 152.53214255120*t); + uranus_x_1+= 0.00001747266 * cos( 3.24870046809 + 77.22927912210*t); + uranus_x_1+= 0.00001716831 * cos( 3.39415662657 + 222.86032299360*t); + uranus_x_1+= 0.00001707504 * cos( 1.11296012106 + 225.82926841020*t); + uranus_x_1+= 0.00001734228 * cos( 5.39619902298 + 146.59425171800*t); + uranus_x_1+= 0.00001476617 * cos( 3.53047075439 + 3.18139373770*t); + uranus_x_1+= 0.00001179645 * cos( 5.13953276367 + 220.41264243880*t); + uranus_x_1+= 0.00001239315 * cos( 0.98221206501 + 4.45341812490*t); + uranus_x_1+= 0.00001099691 * cos( 1.35138854505 + 62.25142559510*t); + uranus_x_1+= 0.00001061312 * cos( 5.00125105380 + 131.40394986990*t); + uranus_x_1+= 0.00001029261 * cos( 5.42434597865 + 109.94568878850*t); + uranus_x_1=uranus_x_1 * t; + + double uranus_x_2=0.0; + uranus_x_2+= 0.00016015732 * cos( 3.83700026619 + 74.78159856730*t); + uranus_x_2+= 0.00010915299 * cos( 3.02987776270 + 149.56319713460*t); + uranus_x_2+= 0.00007497619 * cos( 3.83429136661 + 11.04570026390*t); + uranus_x_2+= 0.00008053623 * cos( 2.54646146122 + 63.73589830340*t); + uranus_x_2+= 0.00005408033 * cos( 4.78033642303 + 70.84944530420*t); + uranus_x_2+= 0.00005021971 * cos( 3.04632772928 + 78.71375183040*t); + uranus_x_2+= 0.00006717313 * cos( 5.31264214501 + 85.82729883120*t); + uranus_x_2+= 0.00005284684 * cos( 2.11901942097 + 73.29712585900*t); + uranus_x_2+= 0.00004874936 * cos( 5.68616132176 + 76.26607127560*t); + uranus_x_2+= 0.00003002124 * cos( 4.07944398452 + 138.51749687070*t); + uranus_x_2+= 0.00002521797 * cos( 3.36028253173 + 71.60020482960*t); + uranus_x_2+= 0.00002413832 * cos( 4.45865225690 + 77.96299230500*t); + uranus_x_2+= 0.00002221373 * cos( 0.87427485235 + 3.93215326310*t); + uranus_x_2+= 0.00002291767 * cos( 0.00000000000 + 0.00000000000*t); + uranus_x_2+= 0.00001040250 * cos( 0.73133408837 + 145.63104387150*t); + uranus_x_2+= 0.00001046100 * cos( 5.85311910228 + 224.34479570190*t); + uranus_x_2=uranus_x_2 * t * t; + + double uranus_x_3=0.0; + uranus_x_3+= 0.00001307049 * cos( 0.00000000000 + 0.00000000000*t); + uranus_x_3=uranus_x_3 * t * t * t; + + return uranus_x_0+uranus_x_1+uranus_x_2+uranus_x_3; +} + +double vsop87a_milli_uranus_y(double t){ + double uranus_y_0=0.0; + uranus_y_0+= 19.16518231584 * cos( 3.91045677002 + 74.78159856730*t); + uranus_y_0+= 0.44390465203 * cos( 0.08884111329 + 149.56319713460*t); + uranus_y_0+= 0.16256125476 * cos( 3.14159265359 + 0.00000000000*t); + uranus_y_0+= 0.14755940186 * cos( 1.85423280679 + 73.29712585900*t); + uranus_y_0+= 0.14123958128 * cos( 2.82486076549 + 76.26607127560*t); + uranus_y_0+= 0.06250078231 * cos( 3.56960243857 + 1.48447270830*t); + uranus_y_0+= 0.01542668264 * cos( 2.55040539213 + 224.34479570190*t); + uranus_y_0+= 0.01442356575 * cos( 1.08004542712 + 148.07872442630*t); + uranus_y_0+= 0.00938975501 * cos( 0.09275714761 + 11.04570026390*t); + uranus_y_0+= 0.00650331846 * cos( 2.76142680222 + 63.73589830340*t); + uranus_y_0+= 0.00657343120 * cos( 5.28830704469 + 151.04766984290*t); + uranus_y_0+= 0.00621326770 * cos( 1.48795811387 + 77.75054398390*t); + uranus_y_0+= 0.00541961958 * cos( 3.24476486661 + 71.81265315070*t); + uranus_y_0+= 0.00547472694 * cos( 2.06037924573 + 85.82729883120*t); + uranus_y_0+= 0.00459589120 * cos( 2.33745536070 + 2.96894541660*t); + uranus_y_0+= 0.00495936105 * cos( 5.31205753740 + 529.69096509460*t); + uranus_y_0+= 0.00387922853 * cos( 4.62026923885 + 138.51749687070*t); + uranus_y_0+= 0.00268363417 * cos( 5.68085299020 + 213.29909543800*t); + uranus_y_0+= 0.00216239629 * cos( 3.73800767580 + 38.13303563780*t); + uranus_y_0+= 0.00144032475 * cos( 0.75015700920 + 70.84944530420*t); + uranus_y_0+= 0.00135290820 * cos( 3.93970260616 + 78.71375183040*t); + uranus_y_0+= 0.00119670613 * cos( 2.53058783780 + 39.61750834610*t); + uranus_y_0+= 0.00124868545 * cos( 0.94315917319 + 111.43016149680*t); + uranus_y_0+= 0.00111204860 * cos( 3.55163219419 + 222.86032299360*t); + uranus_y_0+= 0.00104507929 * cos( 2.33345675603 + 146.59425171800*t); + uranus_y_0+= 0.00108584454 * cos( 6.02234848388 + 35.16409022120*t); + uranus_y_0+= 0.00063573747 * cos( 5.01204967920 + 299.12639426920*t); + uranus_y_0+= 0.00053289771 * cos( 2.38437587876 + 3.93215326310*t); + uranus_y_0+= 0.00063774261 * cos( 2.15607602904 + 109.94568878850*t); + uranus_y_0+= 0.00039218598 * cos( 1.11841109252 + 4.45341812490*t); + uranus_y_0+= 0.00034205426 * cos( 0.92405922576 + 65.22037101170*t); + uranus_y_0+= 0.00034334377 * cos( 1.46696169843 + 225.82926841020*t); + uranus_y_0+= 0.00034538316 * cos( 0.27613780697 + 79.23501669220*t); + uranus_y_0+= 0.00039256771 * cos( 5.75956853703 + 202.25339517410*t); + uranus_y_0+= 0.00026157754 * cos( 3.74097610798 + 9.56122755560*t); + uranus_y_0+= 0.00023427328 * cos( 2.52740125551 + 145.63104387150*t); + uranus_y_0+= 0.00022933138 * cos( 3.94455540350 + 84.34282612290*t); + uranus_y_0+= 0.00031816303 * cos( 3.96860170484 + 152.53214255120*t); + uranus_y_0+= 0.00025237176 * cos( 4.45141413666 + 70.32818044240*t); + uranus_y_0+= 0.00028372491 * cos( 4.44714627097 + 184.72728735580*t); + uranus_y_0+= 0.00026652859 * cos( 4.53944395347 + 160.60889739850*t); + uranus_y_0+= 0.00019666208 * cos( 3.96350065335 + 74.66972398270*t); + uranus_y_0+= 0.00019643845 * cos( 0.71577796385 + 74.89347315190*t); + uranus_y_0+= 0.00019838981 * cos( 5.29113397354 + 12.53017297220*t); + uranus_y_0+= 0.00021523908 * cos( 4.93565132068 + 36.64856292950*t); + uranus_y_0+= 0.00015537967 * cos( 1.87863275460 + 52.69019803950*t); + uranus_y_0+= 0.00020115100 * cos( 3.45473780762 + 127.47179660680*t); + uranus_y_0+= 0.00020051641 * cos( 2.90386352937 + 22.09140052780*t); + uranus_y_0+= 0.00019901477 * cos( 6.11075402434 + 112.91463420510*t); + uranus_y_0+= 0.00018126776 * cos( 0.98478853787 + 33.67961751290*t); + uranus_y_0+= 0.00015174962 * cos( 1.31314034959 + 41.10198105440*t); + uranus_y_0+= 0.00011239020 * cos( 4.54508334011 + 71.60020482960*t); + uranus_y_0+= 0.00013948849 * cos( 4.70474945682 + 221.37585028530*t); + uranus_y_0+= 0.00010819728 * cos( 0.12807029856 + 77.96299230500*t); + uranus_y_0+= 0.00013589665 * cos( 0.98313719930 + 87.31177153950*t); + uranus_y_0+= 0.00011996772 * cos( 5.66129275335 + 1059.38193018920*t); + uranus_y_0+= 0.00012407787 * cos( 4.64945783340 + 72.33391801250*t); + uranus_y_0+= 0.00011531140 * cos( 0.20190074645 + 77.22927912210*t); + uranus_y_0+= 0.00008736150 * cos( 3.39874828293 + 186.21176006410*t); + uranus_y_0+= 0.00007093587 * cos( 6.01613487245 + 297.64192156090*t); + uranus_y_0+= 0.00006408245 * cos( 3.93246367895 + 62.25142559510*t); + uranus_y_0+= 0.00006261153 * cos( 0.14258542752 + 153.49535039770*t); + uranus_y_0+= 0.00007494000 * cos( 4.82565771386 + 426.59819087600*t); + uranus_y_0+= 0.00007856014 * cos( 1.12354254831 + 340.77089204480*t); + uranus_y_0+= 0.00005516018 * cos( 1.73758326119 + 140.00196957900*t); + uranus_y_0+= 0.00005556643 * cos( 3.68095215063 + 145.10977900970*t); + uranus_y_0+= 0.00005368405 * cos( 2.55422957958 + 75.30286342910*t); + uranus_y_0+= 0.00005350948 * cos( 2.12171493922 + 74.26033370550*t); + uranus_y_0+= 0.00004508794 * cos( 5.82224064821 + 66.70484372000*t); + uranus_y_0+= 0.00004290374 * cos( 5.54490766551 + 265.98929347750*t); + uranus_y_0+= 0.00005013871 * cos( 3.11907749268 + 18.15924726470*t); + uranus_y_0+= 0.00004326138 * cos( 5.70135056853 + 183.24281464750*t); + uranus_y_0+= 0.00004750018 * cos( 3.38678300054 + 73.81839072080*t); + uranus_y_0+= 0.00004445347 * cos( 5.00638490308 + 114.39910691340*t); + uranus_y_0+= 0.00003314154 * cos( 5.23054574329 + 82.85835341460*t); + uranus_y_0+= 0.00004509054 * cos( 1.31254342829 + 75.74480641380*t); + uranus_y_0+= 0.00003553107 * cos( 6.18906516846 + 5.93789083320*t); + uranus_y_0+= 0.00003265634 * cos( 5.23063560176 + 220.41264243880*t); + uranus_y_0+= 0.00003575435 * cos( 5.83994849224 + 137.03302416240*t); + uranus_y_0+= 0.00002880734 * cos( 1.19038424330 + 373.90799283650*t); + uranus_y_0+= 0.00002885443 * cos( 3.50279993038 + 7.11354700080*t); + uranus_y_0+= 0.00002594155 * cos( 4.93691413537 + 96.87299909510*t); + uranus_y_0+= 0.00002559357 * cos( 2.87184237678 + 80.19822453870*t); + uranus_y_0+= 0.00002676616 * cos( 1.61805362044 + 305.34616939270*t); + uranus_y_0+= 0.00002246530 * cos( 5.80081898763 + 108.46121608020*t); + uranus_y_0+= 0.00002474483 * cos( 2.21173751117 + 32.19514480460*t); + uranus_y_0+= 0.00002060991 * cos( 6.24178596384 + 56.62235130260*t); + uranus_y_0+= 0.00001958711 * cos( 4.80807045815 + 20.60692781950*t); + uranus_y_0+= 0.00002227451 * cos( 5.34765264557 + 80.71948940050*t); + uranus_y_0+= 0.00001937874 * cos( 0.49529839431 + 74.82978267710*t); + uranus_y_0+= 0.00001937871 * cos( 4.18462288684 + 74.73341445750*t); + uranus_y_0+= 0.00002164382 * cos( 0.47581392325 + 3.18139373770*t); + uranus_y_0+= 0.00002138407 * cos( 2.63817804331 + 74.52096613640*t); + uranus_y_0+= 0.00002130909 * cos( 2.04143912495 + 75.04223099820*t); + uranus_y_0+= 0.00001787737 * cos( 0.32096699926 + 2.44768055480*t); + uranus_y_0+= 0.00002212861 * cos( 0.61491281306 + 259.50888592310*t); + uranus_y_0+= 0.00001889369 * cos( 3.92852240171 + 300.61086697750*t); + uranus_y_0+= 0.00002275258 * cos( 1.55666401505 + 131.40394986990*t); + uranus_y_0+= 0.00001925946 * cos( 6.00527473515 + 159.12442469020*t); + uranus_y_0+= 0.00001802494 * cos( 4.16218259902 + 74.62153987290*t); + uranus_y_0+= 0.00001796292 * cos( 0.51761494342 + 74.94165726170*t); + uranus_y_0+= 0.00002240648 * cos( 0.47739127862 + 181.75834193920*t); + uranus_y_0+= 0.00001924499 * cos( 2.64284880495 + 206.18554843720*t); + uranus_y_0+= 0.00001626134 * cos( 3.70023731184 + 191.20769491020*t); + uranus_y_0+= 0.00001860824 * cos( 0.10445996392 + 42.58645376270*t); + uranus_y_0+= 0.00002177437 * cos( 2.80437422101 + 479.28838891550*t); + uranus_y_0+= 0.00001896184 * cos( 4.26975898003 + 14.97785352700*t); + uranus_y_0+= 0.00002045249 * cos( 5.17400788104 + 835.03713448730*t); + uranus_y_0+= 0.00001887812 * cos( 2.75000237791 + 154.01661525950*t); + uranus_y_0+= 0.00001794754 * cos( 0.16290844853 + 227.31374111850*t); + uranus_y_0+= 0.00001347410 * cos( 3.89237011696 + 288.08069400530*t); + uranus_y_0+= 0.00001572826 * cos( 5.93367812903 + 219.89137757700*t); + uranus_y_0+= 0.00001424804 * cos( 5.10004758033 + 92.94084583200*t); + uranus_y_0+= 0.00001267766 * cos( 0.92771324396 + 404.50679034820*t); + uranus_y_0+= 0.00001588897 * cos( 4.15115668974 + 39.35687591520*t); + uranus_y_0+= 0.00001269786 * cos( 1.09685727529 + 142.44965013380*t); + uranus_y_0+= 0.00001291065 * cos( 5.67425699047 + 68.84370773410*t); + uranus_y_0+= 0.00001436850 * cos( 5.44312198350 + 522.57741809380*t); + uranus_y_0+= 0.00001405564 * cos( 2.04677392527 + 536.80451209540*t); + uranus_y_0+= 0.00001416917 * cos( 0.72597245494 + 235.39049596580*t); + uranus_y_0+= 0.00001165315 * cos( 0.51071041452 + 81.89514556810*t); + uranus_y_0+= 0.00001035262 * cos( 1.20639876458 + 5.41662597140*t); + uranus_y_0+= 0.00001009454 * cos( 0.45375065997 + 74.03083904190*t); + uranus_y_0+= 0.00001220696 * cos( 1.84988185963 + 211.81462272970*t); + uranus_y_0+= 0.00001222886 * cos( 2.27306099902 + 187.69623277240*t); + uranus_y_0+= 0.00001336792 * cos( 3.74888989756 + 380.12776796000*t); + uranus_y_0+= 0.00001151803 * cos( 0.46579056125 + 128.95626931510*t); + uranus_y_0+= 0.00001149114 * cos( 0.85101218281 + 296.15744885260*t); + uranus_y_0+= 0.00001163762 * cos( 5.51157783762 + 230.56457082540*t); + uranus_y_0+= 0.00001192292 * cos( 0.68084398426 + 99.16062095550*t); + uranus_y_0+= 0.00001151286 * cos( 4.01147735438 + 67.66805156650*t); + uranus_y_0+= 0.00001189801 * cos( 4.01778306134 + 50.40257617910*t); + uranus_y_0+= 0.00001015998 * cos( 1.00290501307 + 35.42472265210*t); + uranus_y_0+= 0.00001174953 * cos( 0.45683512473 + 110.20632121940*t); + uranus_y_0+= 0.00001051606 * cos( 3.96907647535 + 14.01464568050*t); + + double uranus_y_1=0.0; + uranus_y_1+= 0.02157896385 * cos( 0.00000000000 + 0.00000000000*t); + uranus_y_1+= 0.00739227349 * cos( 4.43963890935 + 149.56319713460*t); + uranus_y_1+= 0.00238545685 * cos( 3.76882493145 + 73.29712585900*t); + uranus_y_1+= 0.00229396424 * cos( 0.91090183978 + 76.26607127560*t); + uranus_y_1+= 0.00110137111 * cos( 4.00844441616 + 11.04570026390*t); + uranus_y_1+= 0.00094979054 * cos( 5.07141537066 + 63.73589830340*t); + uranus_y_1+= 0.00081474163 * cos( 5.92275367106 + 85.82729883120*t); + uranus_y_1+= 0.00045457174 * cos( 0.73292241207 + 138.51749687070*t); + uranus_y_1+= 0.00051366974 * cos( 0.61844114994 + 224.34479570190*t); + uranus_y_1+= 0.00038296005 * cos( 5.01873578671 + 70.84944530420*t); + uranus_y_1+= 0.00036146116 * cos( 5.94859452787 + 78.71375183040*t); + uranus_y_1+= 0.00032420558 * cos( 4.32617271732 + 74.78159856730*t); + uranus_y_1+= 0.00021673269 * cos( 3.36607263522 + 151.04766984290*t); + uranus_y_1+= 0.00019425087 * cos( 6.01842187783 + 77.75054398390*t); + uranus_y_1+= 0.00017393206 * cos( 4.96098895488 + 71.81265315070*t); + uranus_y_1+= 0.00014991169 * cos( 3.97176856758 + 3.93215326310*t); + uranus_y_1+= 0.00007732367 * cos( 0.04256630122 + 71.60020482960*t); + uranus_y_1+= 0.00007438492 * cos( 4.63165436478 + 77.96299230500*t); + uranus_y_1+= 0.00006979238 * cos( 0.83723520791 + 145.63104387150*t); + uranus_y_1+= 0.00007321559 * cos( 0.66348425538 + 2.96894541660*t); + uranus_y_1+= 0.00007595636 * cos( 1.19807643487 + 148.07872442630*t); + uranus_y_1+= 0.00004376824 * cos( 2.17182724016 + 160.60889739850*t); + uranus_y_1+= 0.00003962568 * cos( 3.18042711824 + 65.22037101170*t); + uranus_y_1+= 0.00004117202 * cos( 6.19931612790 + 22.09140052780*t); + uranus_y_1+= 0.00002830313 * cos( 3.34365222278 + 213.29909543800*t); + uranus_y_1+= 0.00002690065 * cos( 1.78946471198 + 9.56122755560*t); + uranus_y_1+= 0.00002628159 * cos( 2.97459067399 + 12.53017297220*t); + uranus_y_1+= 0.00003174617 * cos( 3.08131638838 + 299.12639426920*t); + uranus_y_1+= 0.00002227510 * cos( 4.89407437055 + 87.31177153950*t); + uranus_y_1+= 0.00002821206 * cos( 1.83130010947 + 84.34282612290*t); + uranus_y_1+= 0.00002510693 * cos( 1.27166561854 + 18.15924726470*t); + uranus_y_1+= 0.00002224655 * cos( 3.21541108798 + 72.33391801250*t); + uranus_y_1+= 0.00001929662 * cos( 4.68383962079 + 52.69019803950*t); + uranus_y_1+= 0.00001707606 * cos( 5.60415260609 + 127.47179660680*t); + uranus_y_1+= 0.00001620819 * cos( 2.18676505386 + 153.49535039770*t); + uranus_y_1+= 0.00001926926 * cos( 0.82821252139 + 39.61750834610*t); + uranus_y_1+= 0.00001555611 * cos( 2.56681954823 + 73.81839072080*t); + uranus_y_1+= 0.00001595703 * cos( 4.79558057860 + 79.23501669220*t); + uranus_y_1+= 0.00001476550 * cos( 2.10111459539 + 75.74480641380*t); + uranus_y_1+= 0.00001531355 * cos( 2.14701519407 + 152.53214255120*t); + uranus_y_1+= 0.00001744564 * cos( 1.67897185084 + 77.22927912210*t); + uranus_y_1+= 0.00001713945 * cos( 1.82334975258 + 222.86032299360*t); + uranus_y_1+= 0.00001705184 * cos( 5.82532917611 + 225.82926841020*t); + uranus_y_1+= 0.00001739019 * cos( 3.82452086292 + 146.59425171800*t); + uranus_y_1+= 0.00001291753 * cos( 6.19666243545 + 70.32818044240*t); + uranus_y_1+= 0.00001458526 * cos( 5.10147126404 + 3.18139373770*t); + uranus_y_1+= 0.00001179966 * cos( 3.56807126055 + 220.41264243880*t); + uranus_y_1+= 0.00001234914 * cos( 5.69239889831 + 4.45341812490*t); + uranus_y_1+= 0.00001075108 * cos( 1.76286452034 + 56.62235130260*t); + uranus_y_1+= 0.00001035661 * cos( 6.12642568708 + 62.25142559510*t); + uranus_y_1+= 0.00001114523 * cos( 3.41304662369 + 131.40394986990*t); + uranus_y_1+= 0.00001050191 * cos( 3.84176879347 + 109.94568878850*t); + uranus_y_1=uranus_y_1 * t; + + double uranus_y_2=0.0; + uranus_y_2+= 0.00034812647 * cos( 3.14159265359 + 0.00000000000*t); + uranus_y_2+= 0.00016589194 * cos( 2.29556740620 + 74.78159856730*t); + uranus_y_2+= 0.00010905147 * cos( 1.45737963668 + 149.56319713460*t); + uranus_y_2+= 0.00007484633 * cos( 2.27968076918 + 11.04570026390*t); + uranus_y_2+= 0.00007964298 * cos( 0.97230247087 + 63.73589830340*t); + uranus_y_2+= 0.00005307100 * cos( 3.20519221878 + 70.84944530420*t); + uranus_y_2+= 0.00005018595 * cos( 1.47518527303 + 78.71375183040*t); + uranus_y_2+= 0.00006713255 * cos( 3.74148881189 + 85.82729883120*t); + uranus_y_2+= 0.00005265170 * cos( 0.54901216905 + 73.29712585900*t); + uranus_y_2+= 0.00004864822 * cos( 4.11367426823 + 76.26607127560*t); + uranus_y_2+= 0.00002995853 * cos( 2.49432193549 + 138.51749687070*t); + uranus_y_2+= 0.00002519021 * cos( 1.78896824345 + 71.60020482960*t); + uranus_y_2+= 0.00002418371 * cos( 2.88675006488 + 77.96299230500*t); + uranus_y_2+= 0.00002185856 * cos( 5.58862614977 + 3.93215326310*t); + uranus_y_2+= 0.00001035578 * cos( 5.44752448275 + 145.63104387150*t); + uranus_y_2+= 0.00001044459 * cos( 4.27972239360 + 224.34479570190*t); + uranus_y_2=uranus_y_2 * t * t; + + double uranus_y_3=0.0; + uranus_y_3+= 0.00001211380 * cos( 0.00000000000 + 0.00000000000*t); + uranus_y_3=uranus_y_3 * t * t * t; + + return uranus_y_0+uranus_y_1+uranus_y_2+uranus_y_3; +} + +double vsop87a_milli_uranus_z(double t){ + double uranus_z_0=0.0; + uranus_z_0+= 0.25878127698 * cos( 2.61861272578 + 74.78159856730*t); + uranus_z_0+= 0.01774318778 * cos( 3.14159265359 + 0.00000000000*t); + uranus_z_0+= 0.00599316131 * cos( 5.08119500585 + 149.56319713460*t); + uranus_z_0+= 0.00190281890 * cos( 1.61643841193 + 76.26607127560*t); + uranus_z_0+= 0.00190881685 * cos( 0.57869575952 + 73.29712585900*t); + uranus_z_0+= 0.00084626761 * cos( 2.26030150166 + 1.48447270830*t); + uranus_z_0+= 0.00030734257 * cos( 0.23571721555 + 63.73589830340*t); + uranus_z_0+= 0.00020842052 * cos( 1.26054208091 + 224.34479570190*t); + uranus_z_0+= 0.00019734273 * cos( 6.04314677688 + 148.07872442630*t); + uranus_z_0+= 0.00012537530 * cos( 5.17169051466 + 11.04570026390*t); + uranus_z_0+= 0.00014582864 * cos( 6.14852037212 + 71.81265315070*t); + uranus_z_0+= 0.00010407529 * cos( 3.65320417038 + 213.29909543800*t); + uranus_z_0+= 0.00011261541 * cos( 3.55973769686 + 529.69096509460*t); + uranus_z_0+= 0.00008855669 * cos( 4.03774505739 + 151.04766984290*t); + uranus_z_0+= 0.00008239460 * cos( 0.34225652715 + 77.75054398390*t); + uranus_z_0+= 0.00007950169 * cos( 0.72564903051 + 85.82729883120*t); + uranus_z_0+= 0.00006867469 * cos( 0.81417174224 + 2.96894541660*t); + uranus_z_0+= 0.00005648720 * cos( 3.45324719543 + 138.51749687070*t); + uranus_z_0+= 0.00004581938 * cos( 1.69668682344 + 38.13303563780*t); + uranus_z_0+= 0.00002578399 * cos( 5.19696447390 + 111.43016149680*t); + uranus_z_0+= 0.00002964070 * cos( 6.14338802239 + 35.16409022120*t); + uranus_z_0+= 0.00001884104 * cos( 2.61192472648 + 78.71375183040*t); + uranus_z_0+= 0.00002330304 * cos( 5.72640226150 + 70.84944530420*t); + uranus_z_0+= 0.00001985215 * cos( 0.76408839812 + 39.61750834610*t); + uranus_z_0+= 0.00001743154 * cos( 1.20586281789 + 146.59425171800*t); + uranus_z_0+= 0.00002037011 * cos( 0.95353587037 + 70.32818044240*t); + uranus_z_0+= 0.00001508924 * cos( 2.26195448553 + 222.86032299360*t); + uranus_z_0+= 0.00001082736 * cos( 2.62872874057 + 108.46121608020*t); + uranus_z_0+= 0.00001051968 * cos( 0.75560753840 + 109.94568878850*t); + + double uranus_z_1=0.0; + uranus_z_1+= 0.00655916626 * cos( 0.01271947660 + 74.78159856730*t); + uranus_z_1+= 0.00049648951 * cos( 0.00000000000 + 0.00000000000*t); + uranus_z_1+= 0.00023874178 * cos( 2.73870491220 + 149.56319713460*t); + uranus_z_1+= 0.00007552177 * cos( 5.49304207700 + 76.26607127560*t); + uranus_z_1+= 0.00005941304 * cos( 3.61254073304 + 73.29712585900*t); + uranus_z_1+= 0.00002868429 * cos( 4.17954157878 + 63.73589830340*t); + uranus_z_1+= 0.00002087455 * cos( 5.97858625817 + 1.48447270830*t); + uranus_z_1+= 0.00001827697 * cos( 2.71810813335 + 11.04570026390*t); + uranus_z_1+= 0.00001305063 * cos( 4.52337002195 + 85.82729883120*t); + uranus_z_1+= 0.00001158250 * cos( 5.31913504112 + 224.34479570190*t); + uranus_z_1=uranus_z_1 * t; + + double uranus_z_2=0.0; + uranus_z_2+= 0.00014697858 * cos( 1.75149165003 + 74.78159856730*t); + uranus_z_2+= 0.00001600044 * cos( 3.14159265359 + 0.00000000000*t); + uranus_z_2=uranus_z_2 * t * t; + + return uranus_z_0+uranus_z_1+uranus_z_2; +} + +double vsop87a_milli_venus_x(double t){ + double venus_x_0=0.0; + venus_x_0+= 0.72211281391 * cos( 3.17575836361 + 10213.28554621100*t); + venus_x_0+= 0.00486448018 * cos( 0.00000000000 + 0.00000000000*t); + venus_x_0+= 0.00244500474 * cos( 4.05566613861 + 20426.57109242200*t); + venus_x_0+= 0.00002800281 * cos( 0.33147492492 + 2352.86615377180*t); + venus_x_0+= 0.00001949669 * cos( 4.23196016801 + 1577.34354244780*t); + venus_x_0+= 0.00001241717 * cos( 4.93573787058 + 30639.85663863300*t); + venus_x_0+= 0.00001162258 * cos( 2.87958246189 + 18073.70493865020*t); + venus_x_0+= 0.00001046690 * cos( 1.75434920413 + 6283.07584999140*t); + + double venus_x_1=0.0; + venus_x_1+= 0.00033862636 * cos( 3.14159265359 + 0.00000000000*t); + venus_x_1+= 0.00017234992 * cos( 0.92721124604 + 20426.57109242200*t); + venus_x_1+= 0.00006510416 * cos( 2.19289889733 + 10213.28554621100*t); + venus_x_1=venus_x_1 * t; + + return venus_x_0+venus_x_1; +} + +double vsop87a_milli_venus_y(double t){ + double venus_y_0=0.0; + venus_y_0+= 0.72324820731 * cos( 1.60573808356 + 10213.28554621100*t); + venus_y_0+= 0.00549506273 * cos( 3.14159265359 + 0.00000000000*t); + venus_y_0+= 0.00244884790 * cos( 2.48564954004 + 20426.57109242200*t); + venus_y_0+= 0.00002789807 * cos( 5.04214523606 + 2352.86615377180*t); + venus_y_0+= 0.00001933868 * cos( 5.80597990261 + 1577.34354244780*t); + venus_y_0+= 0.00001243658 * cos( 3.36573697344 + 30639.85663863300*t); + venus_y_0+= 0.00001164480 * cos( 1.30970620277 + 18073.70493865020*t); + venus_y_0+= 0.00001041872 * cos( 0.18129136925 + 6283.07584999140*t); + + double venus_y_1=0.0; + venus_y_1+= 0.00039231430 * cos( 0.00000000000 + 0.00000000000*t); + venus_y_1+= 0.00017282326 * cos( 5.63824735900 + 20426.57109242200*t); + venus_y_1+= 0.00005968075 * cos( 3.60854944086 + 10213.28554621100*t); + venus_y_1=venus_y_1 * t; + + double venus_y_2=0.0; + venus_y_2+= 0.00002007155 * cos( 3.14159265359 + 0.00000000000*t); + venus_y_2=venus_y_2 * t * t; + + return venus_y_0+venus_y_1+venus_y_2; +} + +double vsop87a_milli_venus_z(double t){ + double venus_z_0=0.0; + venus_z_0+= 0.04282990302 * cos( 0.26703856476 + 10213.28554621100*t); + venus_z_0+= 0.00035588343 * cos( 3.14159265359 + 0.00000000000*t); + venus_z_0+= 0.00014501879 * cos( 1.14696911390 + 20426.57109242200*t); + + double venus_z_1=0.0; + venus_z_1+= 0.00208096402 * cos( 1.88967278742 + 10213.28554621100*t); + venus_z_1+= 0.00001264989 * cos( 3.71037501321 + 20426.57109242200*t); + venus_z_1+= 0.00001364144 * cos( 0.00000000000 + 0.00000000000*t); + venus_z_1=venus_z_1 * t; + + double venus_z_2=0.0; + venus_z_2+= 0.00009148044 * cos( 3.34791005272 + 10213.28554621100*t); + venus_z_2=venus_z_2 * t * t; + + return venus_z_0+venus_z_1+venus_z_2; +} + diff --git a/movement/lib/vsop87/vsop87a_milli.h b/movement/lib/vsop87/vsop87a_milli.h new file mode 100755 index 0000000..4c820e8 --- /dev/null +++ b/movement/lib/vsop87/vsop87a_milli.h @@ -0,0 +1,17 @@ +//VSOP87-Multilang http://www.astrogreg.com/vsop87-multilang/index.html +//Greg Miller (gmiller@gregmiller.net) 2019. Released as Public Domain + +#ifndef VSOP87A_MILLI +#define VSOP87A_MILLI + + void vsop87a_milli_getEarth(double t,double temp[]); + void vsop87a_milli_getEmb(double t,double temp[]); + void vsop87a_milli_getJupiter(double t,double temp[]); + void vsop87a_milli_getMars(double t,double temp[]); + void vsop87a_milli_getMercury(double t,double temp[]); + void vsop87a_milli_getNeptune(double t,double temp[]); + void vsop87a_milli_getSaturn(double t,double temp[]); + void vsop87a_milli_getUranus(double t,double temp[]); + void vsop87a_milli_getVenus(double t,double temp[]); + void vsop87a_milli_getMoon(double earth[], double emb[],double temp[]); +#endif diff --git a/movement/make/Makefile b/movement/make/Makefile index 9231d5c..cd4471b 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -18,6 +18,8 @@ INCLUDES += \ -I../watch_faces/demo/ \ -I../lib/TOTP-MCU/ \ -I../lib/sunriset/ \ + -I../lib/vsop87/ \ + -I../lib/astrolib/ \ # If you add any other source files you wish to compile, add them after ../app.c # Note that you will need to add a backslash at the end of any line you wish to continue, i.e. @@ -29,6 +31,8 @@ SRCS += \ ../lib/TOTP-MCU/sha1.c \ ../lib/TOTP-MCU/TOTP.c \ ../lib/sunriset/sunriset.c \ + ../lib/vsop87/vsop87a_milli.c \ + ../lib/astrolib/astrolib.c \ ../movement.c \ ../watch_faces/clock/simple_clock_face.c \ ../watch_faces/clock/world_clock_face.c \ @@ -50,6 +54,8 @@ SRCS += \ ../watch_faces/complication/countdown_face.c \ ../watch_faces/complication/blinky_face.c \ ../watch_faces/complication/moon_phase_face.c \ + ../watch_faces/complication/orrery_face.c \ + ../watch_faces/complication/astronomy_face.c \ # New watch faces go above this line. # Leave this line at the bottom of the file; it has all the targets for making your project. diff --git a/movement/movement_faces.h b/movement/movement_faces.h index ae94efa..b093ebf 100644 --- a/movement/movement_faces.h +++ b/movement/movement_faces.h @@ -45,6 +45,8 @@ #include "countdown_face.h" #include "blinky_face.h" #include "moon_phase_face.h" +#include "orrery_face.h" +#include "astronomy_face.h" // New includes go above this line. #endif // MOVEMENT_FACES_H_ diff --git a/movement/watch_faces/complication/astronomy_face.c b/movement/watch_faces/complication/astronomy_face.c new file mode 100644 index 0000000..50e5221 --- /dev/null +++ b/movement/watch_faces/complication/astronomy_face.c @@ -0,0 +1,280 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include "astronomy_face.h" +#include "watch_utility.h" + +#if __EMSCRIPTEN__ +#include +#endif + +#define NUM_AVAILABLE_BODIES 9 + +static const char astronomy_available_celestial_bodies[NUM_AVAILABLE_BODIES] = { + ASTRO_BODY_SUN, + ASTRO_BODY_MERCURY, + ASTRO_BODY_VENUS, + ASTRO_BODY_MOON, + ASTRO_BODY_MARS, + ASTRO_BODY_JUPITER, + ASTRO_BODY_SATURN, + ASTRO_BODY_URANUS, + ASTRO_BODY_NEPTUNE +}; + +static const char astronomy_celestial_body_names[NUM_AVAILABLE_BODIES][3] = { + "SO", // Sol + "ME", // Mercury + "VE", // Venus + "LU", // Moon (Luna) + "MA", // Mars + "JU", // Jupiter + "SA", // Saturn + "UR", // Uranus + "NE" // Neptune +}; + +static void _astronomy_face_recalculate(movement_settings_t *settings, astronomy_state_t *state) { +#if __EMSCRIPTEN__ + int16_t browser_lat = EM_ASM_INT({ + return lat; + }); + int16_t browser_lon = EM_ASM_INT({ + return lon; + }); + if ((watch_get_backup_data(1) == 0) && (browser_lat || browser_lon)) { + movement_location_t browser_loc; + browser_loc.bit.latitude = browser_lat; + browser_loc.bit.longitude = browser_lon; + watch_store_backup_data(browser_loc.reg, 1); + double lat = (double)browser_lat / 100.0; + double lon = (double)browser_lon / 100.0; + state->latitude_radians = astro_degrees_to_radians(lat); + state->longitude_radians = astro_degrees_to_radians(lon); + } +#endif + + watch_date_time date_time = watch_rtc_get_date_time(); + uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60); + date_time = watch_utility_date_time_from_unix_time(timestamp, 0); + double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second); + + astro_equatorial_coordinates_t radec_precession = astro_get_ra_dec(jd, astronomy_available_celestial_bodies[state->active_body_index], state->latitude_radians, state->longitude_radians, true); + printf("\nParams to convert: %f %f %f %f %f\n", + jd, + astro_radians_to_degrees(state->latitude_radians), + astro_radians_to_degrees(state->longitude_radians), + astro_radians_to_degrees(radec_precession.right_ascension), + astro_radians_to_degrees(radec_precession.declination)); + + astro_horizontal_coordinates_t horiz = astro_ra_dec_to_alt_az(jd, state->latitude_radians, state->longitude_radians, radec_precession.right_ascension, radec_precession.declination); + astro_equatorial_coordinates_t radec = astro_get_ra_dec(jd, astronomy_available_celestial_bodies[state->active_body_index], state->latitude_radians, state->longitude_radians, false); + state->altitude = astro_radians_to_degrees(horiz.altitude); + state->azimuth = astro_radians_to_degrees(horiz.azimuth); + state->right_ascension = astro_radians_to_hms(radec.right_ascension); + state->declination = astro_radians_to_dms(radec.declination); + state->distance = radec.distance; + + printf("Calculated coordinates for %s on %f: \n\tRA = %f / %2dh %2dm %2ds\n\tDec = %f / %3d° %3d' %3d\"\n\tAzi = %f\n\tAlt = %f\n\tDst = %f AU\n", + astronomy_celestial_body_names[state->active_body_index], + jd, + astro_radians_to_degrees(radec.right_ascension), + state->right_ascension.hours, + state->right_ascension.minutes, + state->right_ascension.seconds, + astro_radians_to_degrees(radec.declination), + state->declination.degrees, + state->declination.minutes, + state->declination.seconds, + state->altitude, + state->azimuth, + state->distance); +} + +static void _astronomy_face_update(movement_event_t event, movement_settings_t *settings, astronomy_state_t *state) { + char buf[16]; + switch (state->mode) { + case ASTRONOMY_MODE_SELECTING_BODY: + watch_clear_colon(); + watch_display_string(" Astro", 4); + if (event.subsecond % 2) { + watch_display_string((char *)astronomy_celestial_body_names[state->active_body_index], 0); + } else { + watch_display_string(" ", 0); + } + if (event.subsecond == 0) { + watch_display_string(" ", 2); + switch (state->animation_state) { + case 0: + watch_set_pixel(0, 7); + watch_set_pixel(2, 6); + break; + case 1: + watch_set_pixel(1, 7); + watch_set_pixel(2, 9); + break; + case 2: + watch_set_pixel(2, 7); + watch_set_pixel(0, 9); + break; + } + state->animation_state = (state->animation_state + 1) % 3; + } + break; + case ASTRONOMY_MODE_CALCULATING: + watch_clear_display(); + // this takes a moment and locks the UI, flash C for "Calculating" + watch_start_character_blink('C', 100); + _astronomy_face_recalculate(settings, state); + watch_stop_blink(); + state->mode = ASTRONOMY_MODE_DISPLAYING_ALT; + // fall through + case ASTRONOMY_MODE_DISPLAYING_ALT: + sprintf(buf, "%saL%6d", astronomy_celestial_body_names[state->active_body_index], (int16_t)round(state->altitude * 100)); + watch_display_string(buf, 0); + break; + case ASTRONOMY_MODE_DISPLAYING_AZI: + sprintf(buf, "%saZ%6d", astronomy_celestial_body_names[state->active_body_index], (int16_t)round(state->azimuth * 100)); + watch_display_string(buf, 0); + break; + case ASTRONOMY_MODE_DISPLAYING_RA: + watch_set_colon(); + sprintf(buf, "ra H%02d%02d%02d", state->right_ascension.hours, state->right_ascension.minutes, state->right_ascension.seconds); + watch_display_string(buf, 0); + break; + case ASTRONOMY_MODE_DISPLAYING_DEC: + watch_clear_colon(); + sprintf(buf, "de %3d%2d%2d", state->declination.degrees, state->declination.minutes, state->declination.seconds); + watch_display_string(buf, 0); + break; + case ASTRONOMY_MODE_DISPLAYING_DIST: + if (state->distance >= 0.00668456) { + // if >= 1,000,000 kilometers (all planets), we display distance in AU. + sprintf(buf, "diAU%6d", (uint16_t)round(state->distance * 100)); + } else { + // otherwise distance in kilometers fits in 6 digits. This mode will only happen for Luna. + sprintf(buf, "di K%6ld", (uint32_t)round(state->distance * 149597871.0)); + } + watch_display_string(buf, 0); + break; + case ASTRONOMY_MODE_NUM_MODES: + // this case does not happen, but we need it to silence a warning. + break; + } +} + +void astronomy_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(astronomy_state_t)); + memset(*context_ptr, 0, sizeof(astronomy_state_t)); + } +} + +void astronomy_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + astronomy_state_t *state = (astronomy_state_t *)context; + movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1); + int16_t lat_centi = (int16_t)movement_location.bit.latitude; + int16_t lon_centi = (int16_t)movement_location.bit.longitude; + double lat = (double)lat_centi / 100.0; + double lon = (double)lon_centi / 100.0; + state->latitude_radians = astro_degrees_to_radians(lat); + state->longitude_radians = astro_degrees_to_radians(lon); + + movement_request_tick_frequency(4); +} + +bool astronomy_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + astronomy_state_t *state = (astronomy_state_t *)context; + + switch (event.event_type) { + case EVENT_ACTIVATE: + case EVENT_TICK: + _astronomy_face_update(event, settings, state); + break; + case EVENT_MODE_BUTTON_UP: + // You shouldn't need to change this case; Mode almost always moves to the next watch face. + movement_move_to_next_face(); + break; + case EVENT_LIGHT_BUTTON_UP: + // If you have other uses for the Light button, you can opt not to illuminate the LED for this event. + movement_illuminate_led(); + break; + case EVENT_ALARM_BUTTON_UP: + switch (state->mode) { + case ASTRONOMY_MODE_SELECTING_BODY: + // advance to next celestial body (move to calculations with a long press) + state->active_body_index = (state->active_body_index + 1) % NUM_AVAILABLE_BODIES; + break; + case ASTRONOMY_MODE_CALCULATING: + // ignore button press during calculations + break; + case ASTRONOMY_MODE_DISPLAYING_DIST: + // at last mode, wrap around + state->mode = ASTRONOMY_MODE_DISPLAYING_ALT; + break; + default: + // otherwise, advance to next mode + state->mode++; + break; + } + _astronomy_face_update(event, settings, state); + break; + case EVENT_ALARM_LONG_PRESS: + if (state->mode == ASTRONOMY_MODE_SELECTING_BODY) { + // celestial body selected! this triggers a calculation in the update method. + state->mode = ASTRONOMY_MODE_CALCULATING; + movement_request_tick_frequency(1); + _astronomy_face_update(event, settings, state); + } else if (state->mode != ASTRONOMY_MODE_CALCULATING) { + // in all modes except "doing a calculation", return to the selection screen. + state->mode = ASTRONOMY_MODE_SELECTING_BODY; + movement_request_tick_frequency(4); + _astronomy_face_update(event, settings, state); + } + break; + case EVENT_TIMEOUT: + movement_move_to_face(0); + break; + case EVENT_LOW_ENERGY_UPDATE: + // TODO? + break; + default: + break; + } + + return true; +} + +void astronomy_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + astronomy_state_t *state = (astronomy_state_t *)context; + state->mode = ASTRONOMY_MODE_SELECTING_BODY; +} diff --git a/movement/watch_faces/complication/astronomy_face.h b/movement/watch_faces/complication/astronomy_face.h new file mode 100644 index 0000000..f956955 --- /dev/null +++ b/movement/watch_faces/complication/astronomy_face.h @@ -0,0 +1,68 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef ASTRONOMY_FACE_H_ +#define ASTRONOMY_FACE_H_ + +#include "movement.h" +#include "astrolib.h" + +typedef enum { + ASTRONOMY_MODE_SELECTING_BODY = 0, + ASTRONOMY_MODE_CALCULATING, + ASTRONOMY_MODE_DISPLAYING_ALT, + ASTRONOMY_MODE_DISPLAYING_AZI, + ASTRONOMY_MODE_DISPLAYING_RA, + ASTRONOMY_MODE_DISPLAYING_DEC, + ASTRONOMY_MODE_DISPLAYING_DIST, + ASTRONOMY_MODE_NUM_MODES +} astronomy_mode_t; + +typedef struct { + astronomy_mode_t mode; + uint8_t active_body_index; + uint8_t animation_state; + double latitude_radians; // this is the user location + double longitude_radians; // but in radians + astro_angle_hms_t right_ascension; + astro_angle_dms_t declination; + double altitude; // in decimal degrees + double azimuth; // in decimal degrees + double distance; // in AU +} astronomy_state_t; + +void astronomy_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void astronomy_face_activate(movement_settings_t *settings, void *context); +bool astronomy_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void astronomy_face_resign(movement_settings_t *settings, void *context); + +#define astronomy_face ((const watch_face_t){ \ + astronomy_face_setup, \ + astronomy_face_activate, \ + astronomy_face_loop, \ + astronomy_face_resign, \ + NULL, \ +}) + +#endif // ASTRONOMY_FACE_H_ diff --git a/movement/watch_faces/complication/orrery_face.c b/movement/watch_faces/complication/orrery_face.c new file mode 100644 index 0000000..3afced9 --- /dev/null +++ b/movement/watch_faces/complication/orrery_face.c @@ -0,0 +1,232 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include +#include +#include +#include "orrery_face.h" +#include "watch.h" +#include "watch_utility.h" +#include "vsop87a_micro.h" // smaller size, less accurate +#include "vsop87a_milli.h" +#include "astrolib.h" + +#define NUM_AVAILABLE_BODIES 9 + +static const char orrery_celestial_body_names[NUM_AVAILABLE_BODIES][3] = { + "ME", // Mercury + "VE", // Venus + "EA", // Earth + "LU", // Moon (Luna) + "MA", // Mars + "JU", // Jupiter + "SA", // Saturn + "UR", // Uranus + "NE" // Neptune +}; + +static void _orrery_face_recalculate(movement_settings_t *settings, orrery_state_t *state) { + watch_date_time date_time = watch_rtc_get_date_time(); + uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60); + date_time = watch_utility_date_time_from_unix_time(timestamp, 0); + double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second); + double et = astro_convert_jd_to_julian_millenia_since_j2000(jd); + double r[3] = {0}; + + switch(state->active_body_index) { + case 0: + vsop87a_milli_getMercury(et, r); + break; + case 1: + vsop87a_milli_getVenus(et, r); + break; + case 2: + vsop87a_milli_getEarth(et, r); + break; + case 3: + { + double earth[3]; + double emb[3]; + vsop87a_milli_getEarth(et, earth); + vsop87a_milli_getEmb(et, emb); + vsop87a_milli_getMoon(earth, emb, r); + } + break; + case 4: + vsop87a_milli_getMars(et, r); + break; + case 5: + vsop87a_milli_getJupiter(et, r); + break; + case 6: + vsop87a_milli_getSaturn(et, r); + break; + case 7: + vsop87a_milli_getUranus(et, r); + break; + case 8: + vsop87a_milli_getNeptune(et, r); + break; + } + state->coords[0] = r[0]; + state->coords[1] = r[1]; + state->coords[2] = r[2]; +} + +static void _orrery_face_update(movement_event_t event, movement_settings_t *settings, orrery_state_t *state) { + char buf[11]; + switch (state->mode) { + case ORRERY_MODE_SELECTING_BODY: + watch_display_string("Orrery", 4); + if (event.subsecond % 2) { + watch_display_string((char *)orrery_celestial_body_names[state->active_body_index], 0); + } else { + watch_display_string(" ", 0); + } + if (event.subsecond == 0) { + watch_display_string(" ", 2); + switch (state->animation_state) { + case 0: + watch_set_pixel(0, 7); + watch_set_pixel(2, 6); + break; + case 1: + watch_set_pixel(1, 7); + watch_set_pixel(2, 9); + break; + case 2: + watch_set_pixel(2, 7); + watch_set_pixel(0, 9); + break; + } + state->animation_state = (state->animation_state + 1) % 3; + } + break; + case ORRERY_MODE_CALCULATING: + watch_clear_display(); + // this takes a moment and locks the UI, flash C for "Calculating" + watch_start_character_blink('C', 100); + _orrery_face_recalculate(settings, state); + watch_stop_blink(); + state->mode = ORRERY_MODE_DISPLAYING_X; + // fall through + case ORRERY_MODE_DISPLAYING_X: + sprintf(buf, "%s X%6d", orrery_celestial_body_names[state->active_body_index], (int16_t)round(state->coords[0] * 100)); + watch_display_string(buf, 0); + break; + case ORRERY_MODE_DISPLAYING_Y: + sprintf(buf, "%s Y%6d", orrery_celestial_body_names[state->active_body_index], (int16_t)round(state->coords[1] * 100)); + watch_display_string(buf, 0); + break; + case ORRERY_MODE_DISPLAYING_Z: + sprintf(buf, "%s Z%6d", orrery_celestial_body_names[state->active_body_index], (int16_t)round(state->coords[2] * 100)); + watch_display_string(buf, 0); + break; + case ORRERY_MODE_NUM_MODES: + // this case does not happen, but we need it to silence a warning. + break; + } +} + +void orrery_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(orrery_state_t)); + memset(*context_ptr, 0, sizeof(orrery_state_t)); + } +} + +void orrery_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; + movement_request_tick_frequency(4); +} + +bool orrery_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + (void) settings; + orrery_state_t *state = (orrery_state_t *)context; + + switch (event.event_type) { + case EVENT_ACTIVATE: + case EVENT_TICK: + _orrery_face_update(event, settings, state); + break; + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_LIGHT_BUTTON_DOWN: + movement_illuminate_led(); + break; + case EVENT_LIGHT_BUTTON_UP: + break; + case EVENT_ALARM_BUTTON_UP: + switch (state->mode) { + case ORRERY_MODE_SELECTING_BODY: + // advance to next celestial body (move to calculations with a long press) + state->active_body_index = (state->active_body_index + 1) % NUM_AVAILABLE_BODIES; + break; + case ORRERY_MODE_CALCULATING: + // ignore button press during calculations + break; + case ORRERY_MODE_DISPLAYING_Z: + // at last mode, wrap around + state->mode = ORRERY_MODE_DISPLAYING_X; + break; + default: + // otherwise, advance to next mode + state->mode++; + break; + } + _orrery_face_update(event, settings, state); + break; + case EVENT_ALARM_LONG_PRESS: + if (state->mode == ORRERY_MODE_SELECTING_BODY) { + // celestial body selected! this triggers a calculation in the update method. + state->mode = ORRERY_MODE_CALCULATING; + movement_request_tick_frequency(1); + _orrery_face_update(event, settings, state); + } else if (state->mode != ORRERY_MODE_CALCULATING) { + // in all modes except "doing a calculation", return to the selection screen. + state->mode = ORRERY_MODE_SELECTING_BODY; + movement_request_tick_frequency(4); + _orrery_face_update(event, settings, state); + } + break; + case EVENT_TIMEOUT: + movement_move_to_face(0); + break; + default: + break; + } + + return true; +} + +void orrery_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + orrery_state_t *state = (orrery_state_t *)context; + state->mode = ORRERY_MODE_SELECTING_BODY; +} diff --git a/movement/watch_faces/complication/orrery_face.h b/movement/watch_faces/complication/orrery_face.h new file mode 100644 index 0000000..98060d9 --- /dev/null +++ b/movement/watch_faces/complication/orrery_face.h @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef ORRERY_FACE_H_ +#define ORRERY_FACE_H_ + +#include "movement.h" + +typedef enum { + ORRERY_MODE_SELECTING_BODY = 0, + ORRERY_MODE_CALCULATING, + ORRERY_MODE_DISPLAYING_X, + ORRERY_MODE_DISPLAYING_Y, + ORRERY_MODE_DISPLAYING_Z, + ORRERY_MODE_NUM_MODES +} orrery_mode_t; + +typedef struct { + orrery_mode_t mode; + uint8_t active_body_index; + double coords[3]; + uint8_t animation_state; +} orrery_state_t; + +void orrery_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void orrery_face_activate(movement_settings_t *settings, void *context); +bool orrery_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void orrery_face_resign(movement_settings_t *settings, void *context); + +#define orrery_face ((const watch_face_t){ \ + orrery_face_setup, \ + orrery_face_activate, \ + orrery_face_loop, \ + orrery_face_resign, \ + NULL, \ +}) + +#endif // ORRERY_FACE_H_ diff --git a/watch-library/shared/watch/watch_private_display.c b/watch-library/shared/watch/watch_private_display.c index 87e3f1a..1454a3b 100644 --- a/watch-library/shared/watch/watch_private_display.c +++ b/watch-library/shared/watch/watch_private_display.c @@ -52,6 +52,7 @@ void watch_display_character(uint8_t character, uint8_t position) { if (character == 'T') character = 't'; // uppercase T only works in positions 0 and 1 } if (position == 1) { + if (character == 'a') character = 'A'; // A needs to be uppercase if (character == 'o') character = 'O'; // O needs to be uppercase if (character == 'i') character = 'l'; // I needs to be uppercase (use an l, it looks the same) if (character == 'n') character = 'N'; // N needs to be uppercase From 3025984eb558442e86edf0c99f5d7fbb0d619f10 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Fri, 4 Mar 2022 14:44:42 -0600 Subject: [PATCH 06/45] movement: first pass at mars clock --- movement/make/Makefile | 1 + movement/movement_faces.h | 1 + movement/watch_faces/clock/mars_time_face.c | 112 ++++++++++++++++++++ movement/watch_faces/clock/mars_time_face.h | 48 +++++++++ 4 files changed, 162 insertions(+) create mode 100644 movement/watch_faces/clock/mars_time_face.c create mode 100644 movement/watch_faces/clock/mars_time_face.h diff --git a/movement/make/Makefile b/movement/make/Makefile index 9231d5c..415bc15 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -50,6 +50,7 @@ SRCS += \ ../watch_faces/complication/countdown_face.c \ ../watch_faces/complication/blinky_face.c \ ../watch_faces/complication/moon_phase_face.c \ + ../watch_faces/clock/mars_time_face.c \ # New watch faces go above this line. # Leave this line at the bottom of the file; it has all the targets for making your project. diff --git a/movement/movement_faces.h b/movement/movement_faces.h index ae94efa..1518628 100644 --- a/movement/movement_faces.h +++ b/movement/movement_faces.h @@ -45,6 +45,7 @@ #include "countdown_face.h" #include "blinky_face.h" #include "moon_phase_face.h" +#include "mars_time_face.h" // New includes go above this line. #endif // MOVEMENT_FACES_H_ diff --git a/movement/watch_faces/clock/mars_time_face.c b/movement/watch_faces/clock/mars_time_face.c new file mode 100644 index 0000000..cf3ab5b --- /dev/null +++ b/movement/watch_faces/clock/mars_time_face.c @@ -0,0 +1,112 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include "watch_utility.h" +#include "mars_time_face.h" + +typedef struct { + uint8_t hour; + uint8_t minute; + uint8_t second; +} mars_clock_hms_t; + +static void _h_to_hms(mars_clock_hms_t *date_time, double h) { + unsigned int seconds = (unsigned int)(h * 3600.0); + date_time->hour = seconds / 3600; + seconds = seconds % 3600; + date_time->minute = floor(seconds / 60); + date_time->second = round(seconds % 60); +} + +static void _update(movement_settings_t *settings) { + char buf[11]; + watch_date_time date_time = watch_rtc_get_date_time(); + uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60); + double jdut = 2440587.5 + ((double)now / 86400.0); + double jdtt = jdut + ((37.0 + 32.184) / 86400.0); + double jd2k = jdtt - 2451545.0; + double msd = ((jd2k - 4.5) / 1.0274912517) + 44796.0 - 0.0009626; + double mtc = fmod(24 * msd, 24); + mars_clock_hms_t mars_time; + _h_to_hms(&mars_time, mtc); + sprintf(&buf[0], "MC %02d%02d%02d", mars_time.hour, mars_time.minute, mars_time.second); + watch_set_colon(); + watch_set_indicator(WATCH_INDICATOR_24H); + watch_display_string(buf, 0); +} + +void mars_time_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(mars_time_state_t)); + memset(*context_ptr, 0, sizeof(mars_time_state_t)); + } +} + +void mars_time_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + mars_time_state_t *state = (mars_time_state_t *)context; + (void) state; +} + +bool mars_time_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + mars_time_state_t *state = (mars_time_state_t *)context; + (void) state; + + switch (event.event_type) { + case EVENT_ACTIVATE: + case EVENT_TICK: + _update(settings); + break; + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_LIGHT_BUTTON_UP: + movement_illuminate_led(); + break; + case EVENT_ALARM_BUTTON_UP: + break; + case EVENT_TIMEOUT: + // TODO: make this lower power so we can avoid timeout + movement_move_to_face(0); + break; + case EVENT_LOW_ENERGY_UPDATE: + // TODO: low energy update + // watch_start_tick_animation(500); + break; + default: + break; + } + + return true; +} + +void mars_time_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} + diff --git a/movement/watch_faces/clock/mars_time_face.h b/movement/watch_faces/clock/mars_time_face.h new file mode 100644 index 0000000..864169a --- /dev/null +++ b/movement/watch_faces/clock/mars_time_face.h @@ -0,0 +1,48 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MARS_TIME_FACE_H_ +#define MARS_TIME_FACE_H_ + +#include "movement.h" + +typedef struct { + uint8_t unused; +} mars_time_state_t; + +void mars_time_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void mars_time_face_activate(movement_settings_t *settings, void *context); +bool mars_time_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void mars_time_face_resign(movement_settings_t *settings, void *context); + +#define mars_time_face ((const watch_face_t){ \ + mars_time_face_setup, \ + mars_time_face_activate, \ + mars_time_face_loop, \ + mars_time_face_resign, \ + NULL, \ +}) + +#endif // MARS_TIME_FACE_H_ + From 08af2ed398721a413a9d6fd05f8e749deeccda56 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Fri, 4 Mar 2022 16:30:18 -0600 Subject: [PATCH 07/45] mars clock: adding additional sites --- movement/watch_faces/clock/mars_time_face.c | 38 ++++++++++++++++++--- movement/watch_faces/clock/mars_time_face.h | 11 +++++- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/movement/watch_faces/clock/mars_time_face.c b/movement/watch_faces/clock/mars_time_face.c index cf3ab5b..510cc75 100644 --- a/movement/watch_faces/clock/mars_time_face.c +++ b/movement/watch_faces/clock/mars_time_face.c @@ -28,6 +28,23 @@ #include "watch_utility.h" #include "mars_time_face.h" +// note: lander coordinates come from Mars24's `marslandmarks.xml` file +static double site_longitudes[MARS_TIME_NUM_SITES] = { + 0, // Mars Coordinated Time, at the meridian + 360.0 - 137.441635, // Curiosity lander site + 360.0 - 135.623447, // InSight lander site + 360.0 - 77.45088572, // Perseverance lander site + 360.0 - 109.9 // Zhurong lander site +}; + +static char site_names[MARS_TIME_NUM_SITES][3] = { + "MC", + "CU", + "IN", + "PE", + "ZH" +}; + typedef struct { uint8_t hour; uint8_t minute; @@ -42,7 +59,7 @@ static void _h_to_hms(mars_clock_hms_t *date_time, double h) { date_time->second = round(seconds % 60); } -static void _update(movement_settings_t *settings) { +static void _update(movement_settings_t *settings, mars_time_state_t *state) { char buf[11]; watch_date_time date_time = watch_rtc_get_date_time(); uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60); @@ -51,9 +68,19 @@ static void _update(movement_settings_t *settings) { double jd2k = jdtt - 2451545.0; double msd = ((jd2k - 4.5) / 1.0274912517) + 44796.0 - 0.0009626; double mtc = fmod(24 * msd, 24); + double lmt; + + if (state->current_site == 0) { + lmt = mtc; + } else { + double longitude = site_longitudes[state->current_site]; + double lmst = mtc - ((longitude * 24.0) / 360.0); + lmt = fmod(lmst + 24, 24); + } + mars_clock_hms_t mars_time; - _h_to_hms(&mars_time, mtc); - sprintf(&buf[0], "MC %02d%02d%02d", mars_time.hour, mars_time.minute, mars_time.second); + _h_to_hms(&mars_time, lmt); + sprintf(&buf[0], "%s %02d%02d%02d", site_names[state->current_site], mars_time.hour, mars_time.minute, mars_time.second); watch_set_colon(); watch_set_indicator(WATCH_INDICATOR_24H); watch_display_string(buf, 0); @@ -75,12 +102,11 @@ void mars_time_face_activate(movement_settings_t *settings, void *context) { bool mars_time_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { mars_time_state_t *state = (mars_time_state_t *)context; - (void) state; switch (event.event_type) { case EVENT_ACTIVATE: case EVENT_TICK: - _update(settings); + _update(settings, state); break; case EVENT_MODE_BUTTON_UP: movement_move_to_next_face(); @@ -89,6 +115,8 @@ bool mars_time_face_loop(movement_event_t event, movement_settings_t *settings, movement_illuminate_led(); break; case EVENT_ALARM_BUTTON_UP: + state->current_site = (state->current_site + 1) % MARS_TIME_NUM_SITES; + _update(settings, state); break; case EVENT_TIMEOUT: // TODO: make this lower power so we can avoid timeout diff --git a/movement/watch_faces/clock/mars_time_face.h b/movement/watch_faces/clock/mars_time_face.h index 864169a..d41c0da 100644 --- a/movement/watch_faces/clock/mars_time_face.h +++ b/movement/watch_faces/clock/mars_time_face.h @@ -27,8 +27,17 @@ #include "movement.h" +typedef enum { + MARS_TIME_MERIDIAN, + MARS_TIME_CURIOSITY_SITE, + MARS_TIME_INSIGHT_SITE, + MARS_TIME_PERSEVERANCE_SITE, + MARS_TIME_ZHURONG_SITE, + MARS_TIME_NUM_SITES, +} mars_time_site_t; + typedef struct { - uint8_t unused; + mars_time_site_t current_site; } mars_time_state_t; void mars_time_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); From 3ad093715d731efd2cfb094fd6fdfbb81691005d Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 5 Mar 2022 09:59:32 -0500 Subject: [PATCH 08/45] mars clock: add support for sols --- movement/watch_faces/clock/mars_time_face.c | 46 ++++++++++++++++----- movement/watch_faces/clock/mars_time_face.h | 7 ++-- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/movement/watch_faces/clock/mars_time_face.c b/movement/watch_faces/clock/mars_time_face.c index 510cc75..264f714 100644 --- a/movement/watch_faces/clock/mars_time_face.c +++ b/movement/watch_faces/clock/mars_time_face.c @@ -31,18 +31,26 @@ // note: lander coordinates come from Mars24's `marslandmarks.xml` file static double site_longitudes[MARS_TIME_NUM_SITES] = { 0, // Mars Coordinated Time, at the meridian - 360.0 - 137.441635, // Curiosity lander site - 360.0 - 135.623447, // InSight lander site + 360.0 - 109.9, // Zhurong lander site 360.0 - 77.45088572, // Perseverance lander site - 360.0 - 109.9 // Zhurong lander site + 360.0 - 135.623447, // InSight lander site + 360.0 - 137.441635, // Curiosity lander site }; static char site_names[MARS_TIME_NUM_SITES][3] = { "MC", - "CU", - "IN", + "ZH", "PE", - "ZH" + "IN", + "CU", +}; + +static uint16_t landing_sols[MARS_TIME_NUM_SITES] = { + 0, + 52387, + 52304, + 51511, + 49269, }; typedef struct { @@ -63,6 +71,8 @@ static void _update(movement_settings_t *settings, mars_time_state_t *state) { char buf[11]; watch_date_time date_time = watch_rtc_get_date_time(); uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60); + // TODO: I'm skipping over some steps here. + // https://www.giss.nasa.gov/tools/mars24/help/algorithm.html double jdut = 2440587.5 + ((double)now / 86400.0); double jdtt = jdut + ((37.0 + 32.184) / 86400.0); double jd2k = jdtt - 2451545.0; @@ -78,11 +88,21 @@ static void _update(movement_settings_t *settings, mars_time_state_t *state) { lmt = fmod(lmst + 24, 24); } - mars_clock_hms_t mars_time; - _h_to_hms(&mars_time, lmt); - sprintf(&buf[0], "%s %02d%02d%02d", site_names[state->current_site], mars_time.hour, mars_time.minute, mars_time.second); - watch_set_colon(); - watch_set_indicator(WATCH_INDICATOR_24H); + if (state->displaying_sol) { + // TODO: this is not right, mission sol should turn over at midnight local time? + uint16_t sol = floor(msd) - landing_sols[state->current_site]; + if (sol < 1000) sprintf(&buf[0], "%s Sol%3d", site_names[state->current_site], sol); + else sprintf(&buf[0], "%s s%6d", site_names[state->current_site], sol); + watch_clear_colon(); + watch_clear_indicator(WATCH_INDICATOR_24H); + } else { + mars_clock_hms_t mars_time; + _h_to_hms(&mars_time, lmt); + sprintf(&buf[0], "%s %02d%02d%02d", site_names[state->current_site], mars_time.hour, mars_time.minute, mars_time.second); + watch_set_colon(); + watch_set_indicator(WATCH_INDICATOR_24H); + } + watch_display_string(buf, 0); } @@ -112,6 +132,10 @@ bool mars_time_face_loop(movement_event_t event, movement_settings_t *settings, movement_move_to_next_face(); break; case EVENT_LIGHT_BUTTON_UP: + state->displaying_sol = !state->displaying_sol; + _update(settings, state); + break; + case EVENT_LIGHT_LONG_PRESS: movement_illuminate_led(); break; case EVENT_ALARM_BUTTON_UP: diff --git a/movement/watch_faces/clock/mars_time_face.h b/movement/watch_faces/clock/mars_time_face.h index d41c0da..d34792e 100644 --- a/movement/watch_faces/clock/mars_time_face.h +++ b/movement/watch_faces/clock/mars_time_face.h @@ -29,15 +29,16 @@ typedef enum { MARS_TIME_MERIDIAN, - MARS_TIME_CURIOSITY_SITE, - MARS_TIME_INSIGHT_SITE, - MARS_TIME_PERSEVERANCE_SITE, MARS_TIME_ZHURONG_SITE, + MARS_TIME_PERSEVERANCE_SITE, + MARS_TIME_INSIGHT_SITE, + MARS_TIME_CURIOSITY_SITE, MARS_TIME_NUM_SITES, } mars_time_site_t; typedef struct { mars_time_site_t current_site; + bool displaying_sol; } mars_time_state_t; void mars_time_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); From 2cba47996ed08c83b7c9b2ba521b68fb8a62f666 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 13 Mar 2022 16:37:26 -0400 Subject: [PATCH 09/45] make lowercase s look distinct --- watch-library/shared/watch/watch_private_display.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch-library/shared/watch/watch_private_display.h b/watch-library/shared/watch/watch_private_display.h index 0859784..c55ea33 100644 --- a/watch-library/shared/watch/watch_private_display.h +++ b/watch-library/shared/watch/watch_private_display.h @@ -112,7 +112,7 @@ static const uint8_t Character_Set[] = 0b01110011, // p 0b01100111, // q 0b01010000, // r - 0b01101101, // s + 0b00101101, // s (removes middle segment to distinguish from 5) 0b01111000, // t 0b01100010, // u (appears in (u)pper half to work in more positions) 0b00011100, // v (looks like u but in the lower half) From 8d2dc42d7fd7e1d52b7ad497e2ac1223de333ad3 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 13 Mar 2022 18:03:42 -0400 Subject: [PATCH 10/45] add beginnings of a uart-controlled prototyping app --- apps/uart-display/Makefile | 10 ++++ apps/uart-display/app.c | 104 +++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100755 apps/uart-display/Makefile create mode 100644 apps/uart-display/app.c diff --git a/apps/uart-display/Makefile b/apps/uart-display/Makefile new file mode 100755 index 0000000..5534c17 --- /dev/null +++ b/apps/uart-display/Makefile @@ -0,0 +1,10 @@ +TOP = ../.. +include $(TOP)/make.mk + +INCLUDES += \ + -I./ + +SRCS += \ + ./app.c + +include $(TOP)/rules.mk diff --git a/apps/uart-display/app.c b/apps/uart-display/app.c new file mode 100644 index 0000000..e0d6acf --- /dev/null +++ b/apps/uart-display/app.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include "watch.h" + +/* +Beginnings of a program to take UART input and update the screen accordingly. +Use alongside a prpgram that communicates with the watch over the UART pins. +This CircuitPython script turns the LED red in response to pressing the LIGHT button, +and turns it off when the MODE button is pressed: + +``` +import board +import busio + +uart = busio.UART(board.TX, board.RX, baudrate=19200) + +while True: + uart.write(b"\x00") + data = uart.read(1) + + if data is not None: + data_string = ''.join([chr(b) for b in data]) + print(data_string, end="") + if data_string[0] == 'L': + uart.write(b"R") + elif data_string[0] == 'M': + uart.write(b"O") +``` +*/ + + +char button_pressed = 0; + +static void cb_light_pressed(void) { + button_pressed = 'L'; +} + +static void cb_mode_pressed(void) { + button_pressed = 'M'; +} + +static void cb_alarm_pressed(void) { + button_pressed = 'A'; +} + +void app_init(void) { + watch_enable_leds(); + watch_enable_buzzer(); + + watch_enable_external_interrupts(); + watch_register_interrupt_callback(BTN_MODE, cb_mode_pressed, INTERRUPT_TRIGGER_RISING); + watch_register_interrupt_callback(BTN_LIGHT, cb_light_pressed, INTERRUPT_TRIGGER_RISING); + watch_register_interrupt_callback(BTN_ALARM, cb_alarm_pressed, INTERRUPT_TRIGGER_RISING); + + watch_enable_display(); + + watch_enable_uart(A2, A1, 19200); +} + +void app_wake_from_backup(void) { +} + +void app_setup(void) { +} + +void app_prepare_for_standby(void) { +} + +void app_wake_from_standby(void) { +} + +bool app_loop(void) { + char buf[3]; + + if (button_pressed) { + sprintf(buf, "%c", button_pressed); + printf("%s\n", buf); + watch_uart_puts(buf); + button_pressed = 0; + } + char char_received = watch_uart_getc(); + if (char_received) { + switch (char_received) { + case 'R': + watch_set_led_red(); + break; + case 'G': + watch_set_led_green(); + break; + case 'Y': + watch_set_led_yellow(); + break; + case 'O': + watch_set_led_off(); + break; + case 'U': + // receive a display update? + break; + } + } + + return false; +} From f7e62668721401503de3168f6e81e0b1ed775088 Mon Sep 17 00:00:00 2001 From: Shogo Okamoto Date: Mon, 21 Mar 2022 03:04:30 +0900 Subject: [PATCH 11/45] append counter_face to complication directory. (#58) * append counter_face to complication directory. * Remove invalid configurations for faces * remove faces from main firmware. Co-authored-by: Shogo Okamoto Co-authored-by: joeycastillo --- .../watch_faces/complication/counter_face.c | 90 +++++++++++++++++++ .../watch_faces/complication/counter_face.h | 51 +++++++++++ 2 files changed, 141 insertions(+) create mode 100644 movement/watch_faces/complication/counter_face.c create mode 100644 movement/watch_faces/complication/counter_face.h diff --git a/movement/watch_faces/complication/counter_face.c b/movement/watch_faces/complication/counter_face.c new file mode 100644 index 0000000..ac0388a --- /dev/null +++ b/movement/watch_faces/complication/counter_face.c @@ -0,0 +1,90 @@ +/* + * MIT License + * + * Copyright (c) 2022 Shogo Okamoto + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include "counter_face.h" +#include "watch.h" + +void counter_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(counter_state_t)); + memset(*context_ptr, 0, sizeof(counter_state_t)); + } +} + +void counter_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} + +bool counter_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + (void) settings; + + counter_state_t *state = (counter_state_t *)context; + + switch (event.event_type) { + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_LIGHT_BUTTON_DOWN: + movement_illuminate_led(); + break; + case EVENT_ALARM_BUTTON_UP: + state->counter_idx++; // increment counter index + if (state->counter_idx>99) { //0-99 + state->counter_idx=0;//reset counter index + } + print_counter(state); + break; + case EVENT_ALARM_LONG_PRESS: + state->counter_idx=0; // reset counter index + print_counter(state); + break; + case EVENT_ACTIVATE: + print_counter(state); + break; + case EVENT_TIMEOUT: + // ignore timeout + break; + default: + break; + } + + return true; +} + +// print counter index at the center of display. +void print_counter(counter_state_t *state) { + char buf[14]; + sprintf(buf, "CO %02d", state->counter_idx); // center of LCD display + watch_display_string(buf, 0); +} + +void counter_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} diff --git a/movement/watch_faces/complication/counter_face.h b/movement/watch_faces/complication/counter_face.h new file mode 100644 index 0000000..2d389a1 --- /dev/null +++ b/movement/watch_faces/complication/counter_face.h @@ -0,0 +1,51 @@ +/* + * MIT License + * + * Copyright (c) 2022 Shogo Okamoto + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef COUNTER_FACE_H_ +#define COUNTER_FACE_H_ + +#include "movement.h" + +// Counter face is designed to count the number of running laps during excercises. +typedef struct { + uint8_t counter_idx; +} counter_state_t; + + +void counter_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void counter_face_activate(movement_settings_t *settings, void *context); +bool counter_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void counter_face_resign(movement_settings_t *settings, void *context); + +void print_counter(counter_state_t *state); + +#define counter_face ((const watch_face_t){ \ + counter_face_setup, \ + counter_face_activate, \ + counter_face_loop, \ + counter_face_resign, \ + NULL, \ +}) + +#endif // COUNTER_FACE_H_ From ef8801947c42f1a795f36c0289701ff2fbf2dcdf Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Mon, 28 Mar 2022 15:48:21 -0400 Subject: [PATCH 12/45] update bootloader with 60 second timeout --- utils/flash_watch_pyruler/bootloader.h | 1144 ++++++++++++------------ 1 file changed, 572 insertions(+), 572 deletions(-) diff --git a/utils/flash_watch_pyruler/bootloader.h b/utils/flash_watch_pyruler/bootloader.h index d0fc834..939b60c 100644 --- a/utils/flash_watch_pyruler/bootloader.h +++ b/utils/flash_watch_pyruler/bootloader.h @@ -58,17 +58,17 @@ static const uint8_t binfile[] = { 0x10, 0xb5, 0x00, 0xf0, 0x01, 0xf9, 0x10, 0xbd, 0xfe, 0xe7, 0xfe, 0xe7, 0x23, 0x49, 0x24, 0x48, 0x70, 0xb5, 0x81, 0x42, 0x0a, 0xd0, 0x23, 0x4b, 0xc4, 0x1e, 0x00, 0x22, 0xa3, 0x42, 0x03, 0xd3, 0x03, 0x33, 0x1a, 0x1a, - 0x92, 0x08, 0x92, 0x00, 0x01, 0xf0, 0x30, 0xfc, 0x1e, 0x48, 0x1f, 0x4b, + 0x92, 0x08, 0x92, 0x00, 0x01, 0xf0, 0x38, 0xfc, 0x1e, 0x48, 0x1f, 0x4b, 0xc1, 0x1e, 0x00, 0x22, 0x99, 0x42, 0x03, 0xd8, 0x03, 0x33, 0x1a, 0x1a, - 0x92, 0x08, 0x92, 0x00, 0x00, 0x21, 0x01, 0xf0, 0x2c, 0xfc, 0xff, 0x22, + 0x92, 0x08, 0x92, 0x00, 0x00, 0x21, 0x01, 0xf0, 0x34, 0xfc, 0xff, 0x22, 0x82, 0x20, 0x19, 0x4b, 0x03, 0x21, 0x93, 0x43, 0x18, 0x4a, 0x0c, 0x25, 0x93, 0x60, 0x02, 0x22, 0x08, 0x24, 0x30, 0x26, 0xc0, 0x05, 0xc3, 0x78, 0x8b, 0x43, 0x13, 0x43, 0xc3, 0x70, 0xc3, 0x78, 0xab, 0x43, 0x23, 0x43, 0xc3, 0x70, 0x12, 0x4b, 0x98, 0x7b, 0xb0, 0x43, 0x06, 0x00, 0x20, 0x20, 0x30, 0x43, 0x98, 0x73, 0x98, 0x7b, 0xa8, 0x43, 0x04, 0x43, 0x9c, 0x73, 0x98, 0x7b, 0x88, 0x43, 0x02, 0x43, 0x9a, 0x73, 0x80, 0x23, 0x0b, 0x4a, - 0x51, 0x68, 0x0b, 0x43, 0x53, 0x60, 0x00, 0xf0, 0x77, 0xfe, 0xfe, 0xe7, - 0x38, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xd0, 0x01, 0x00, 0x20, + 0x51, 0x68, 0x0b, 0x43, 0x53, 0x60, 0x00, 0xf0, 0x7f, 0xfe, 0xfe, 0xe7, + 0x48, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xd0, 0x01, 0x00, 0x20, 0xd0, 0x01, 0x00, 0x20, 0xdc, 0x0d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0xe0, 0x00, 0x80, 0x00, 0x41, 0x00, 0x40, 0x00, 0x41, 0xf7, 0xb5, 0x13, 0x4d, 0x01, 0x90, 0x6b, 0x88, 0x00, 0x2b, 0x18, 0xd1, @@ -98,572 +98,574 @@ static const uint8_t binfile[] = { 0x05, 0x4b, 0x06, 0x4a, 0x1a, 0x60, 0xbf, 0xf3, 0x4f, 0x8f, 0x05, 0x4b, 0x05, 0x4a, 0xda, 0x60, 0xbf, 0xf3, 0x4f, 0x8f, 0xfe, 0xe7, 0xc0, 0x46, 0xfc, 0x7f, 0x00, 0x20, 0xef, 0x69, 0x16, 0xf0, 0x00, 0xed, 0x00, 0xe0, - 0x04, 0x00, 0xfa, 0x05, 0x01, 0x22, 0x10, 0xb5, 0x19, 0x4b, 0x1a, 0x49, - 0x1a, 0x70, 0x1a, 0x4a, 0x13, 0x68, 0x01, 0x33, 0x13, 0x60, 0x0a, 0x68, - 0x00, 0x2a, 0x0c, 0xd0, 0x17, 0x48, 0x10, 0x18, 0x83, 0x42, 0x03, 0xd1, - 0x80, 0x24, 0x16, 0x48, 0x64, 0x03, 0x84, 0x61, 0x93, 0x42, 0x01, 0xd1, - 0x00, 0x23, 0x0b, 0x60, 0x10, 0xbd, 0x13, 0x48, 0xdb, 0xb2, 0x02, 0x78, - 0x00, 0x2b, 0x10, 0xd1, 0x80, 0x21, 0x0f, 0x4b, 0x49, 0x03, 0x99, 0x61, - 0x11, 0x00, 0x0a, 0x39, 0xc9, 0xb2, 0x0e, 0x4b, 0xf0, 0x29, 0x02, 0xd9, - 0x19, 0x78, 0x49, 0x42, 0x19, 0x70, 0x1b, 0x78, 0xd2, 0x18, 0x02, 0x70, - 0xe8, 0xe7, 0x93, 0x42, 0xe6, 0xd1, 0x80, 0x22, 0x05, 0x4b, 0x52, 0x03, - 0x5a, 0x61, 0xe1, 0xe7, 0xd0, 0x03, 0x00, 0x20, 0xdc, 0x03, 0x00, 0x20, - 0xd4, 0x03, 0x00, 0x20, 0x18, 0xfc, 0xff, 0xff, 0x00, 0x60, 0x00, 0x41, - 0x05, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, 0x07, 0x4b, 0x08, 0x4a, - 0x1b, 0x68, 0x11, 0x68, 0x99, 0x42, 0x07, 0xd2, 0xfa, 0x21, 0xc9, 0x00, - 0x5b, 0x18, 0x13, 0x60, 0x80, 0x22, 0x04, 0x4b, 0x52, 0x03, 0x5a, 0x61, - 0x70, 0x47, 0xc0, 0x46, 0xd4, 0x03, 0x00, 0x20, 0xdc, 0x03, 0x00, 0x20, - 0x00, 0x60, 0x00, 0x41, 0x80, 0x22, 0x02, 0x4b, 0x52, 0x03, 0x9a, 0x60, - 0x9a, 0x61, 0x70, 0x47, 0x00, 0x60, 0x00, 0x41, 0x70, 0x47, 0x00, 0x00, - 0x01, 0x22, 0x70, 0xb5, 0x0f, 0x24, 0x3a, 0x49, 0x0b, 0x78, 0x13, 0x43, - 0x0b, 0x70, 0x39, 0x4b, 0x18, 0x78, 0xa0, 0x43, 0x18, 0x70, 0x06, 0x20, - 0x19, 0x78, 0x08, 0x43, 0x36, 0x49, 0x18, 0x70, 0x08, 0x78, 0x10, 0x43, - 0x08, 0x70, 0x19, 0x78, 0x21, 0x40, 0x19, 0x70, 0x60, 0x21, 0x18, 0x78, - 0x01, 0x43, 0x19, 0x70, 0x40, 0x21, 0x31, 0x4b, 0x19, 0x60, 0x31, 0x4b, - 0x30, 0x39, 0x18, 0x69, 0x01, 0x43, 0x19, 0x61, 0x99, 0x69, 0x0a, 0x43, - 0x9a, 0x61, 0x2e, 0x4a, 0x53, 0x68, 0x5b, 0x07, 0xfc, 0xd4, 0x82, 0x23, - 0x01, 0x22, 0xdb, 0x05, 0x19, 0x78, 0x0a, 0x43, 0x1a, 0x70, 0x9a, 0x78, - 0xd2, 0x07, 0xfc, 0xd4, 0x1f, 0x20, 0x28, 0x4a, 0x13, 0x68, 0x5b, 0x0b, - 0x03, 0x40, 0x83, 0x42, 0x00, 0xd1, 0x05, 0x23, 0x82, 0x21, 0xc9, 0x05, - 0x0c, 0x8d, 0x24, 0x4d, 0x03, 0x40, 0x9b, 0x01, 0x2c, 0x40, 0x23, 0x43, - 0x0b, 0x85, 0x13, 0x68, 0x9b, 0x0c, 0x03, 0x40, 0x1f, 0x2b, 0x00, 0xd1, - 0x02, 0x3b, 0x1f, 0x24, 0x08, 0x8d, 0x23, 0x40, 0xa0, 0x43, 0x03, 0x43, - 0x07, 0x20, 0x0b, 0x85, 0x12, 0x68, 0xd2, 0x0d, 0x02, 0x40, 0x82, 0x42, - 0x00, 0xd1, 0x03, 0x22, 0x82, 0x23, 0xdb, 0x05, 0x19, 0x8d, 0x02, 0x40, - 0x16, 0x48, 0x12, 0x03, 0x01, 0x40, 0x0a, 0x43, 0x7f, 0x21, 0x1a, 0x85, - 0x1a, 0x78, 0x14, 0x48, 0x0a, 0x40, 0x1a, 0x70, 0x04, 0x22, 0x19, 0x78, - 0x0a, 0x43, 0x0c, 0x21, 0x1a, 0x70, 0x58, 0x62, 0x1a, 0x89, 0x8a, 0x43, - 0x1a, 0x81, 0x1a, 0x89, 0x0b, 0x39, 0x8a, 0x43, 0x1a, 0x81, 0x80, 0x22, - 0x00, 0x21, 0x52, 0x00, 0x01, 0xf0, 0x71, 0xfa, 0x70, 0xbd, 0xc0, 0x46, - 0x58, 0x60, 0x00, 0x41, 0x3c, 0x60, 0x00, 0x41, 0x59, 0x60, 0x00, 0x41, - 0x98, 0x1c, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 0x1c, 0x00, 0x40, - 0x20, 0x60, 0x80, 0x00, 0x3f, 0xf8, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, - 0x74, 0x06, 0x00, 0x20, 0xf7, 0xb5, 0x1c, 0x00, 0x82, 0x23, 0xdb, 0x05, - 0x5b, 0x6a, 0x06, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x01, 0x93, 0x00, 0x2c, - 0x05, 0xd1, 0x44, 0x34, 0x54, 0x43, 0x2d, 0x4b, 0xe4, 0x18, 0xff, 0xf7, - 0xcb, 0xfe, 0x63, 0x78, 0x22, 0x78, 0x93, 0x42, 0x10, 0xd2, 0xd5, 0x1a, - 0xbd, 0x42, 0x00, 0xd9, 0x3d, 0x00, 0x00, 0x2e, 0x08, 0xd0, 0x21, 0x1d, - 0xc9, 0x18, 0x2a, 0x00, 0x30, 0x00, 0x01, 0xf0, 0x31, 0xfa, 0x63, 0x78, - 0x5b, 0x19, 0x63, 0x70, 0x28, 0x00, 0xfe, 0xbd, 0x01, 0x9b, 0xa1, 0x78, - 0x6a, 0x01, 0xd3, 0x18, 0x00, 0x29, 0x11, 0xd1, 0x21, 0x1d, 0x19, 0x60, - 0x59, 0x68, 0x1d, 0x48, 0x89, 0x0b, 0x89, 0x03, 0x59, 0x60, 0x59, 0x68, - 0x01, 0x40, 0x59, 0x60, 0x1a, 0x49, 0x55, 0x18, 0x40, 0x21, 0x28, 0x79, - 0x01, 0x43, 0x29, 0x71, 0x01, 0x21, 0xa1, 0x70, 0x82, 0x21, 0xc9, 0x05, - 0x51, 0x18, 0x01, 0x91, 0x15, 0x49, 0x00, 0x25, 0x52, 0x18, 0x12, 0x7a, - 0xd2, 0x07, 0xdb, 0xd5, 0x5d, 0x68, 0xa2, 0x78, 0xed, 0xb2, 0x25, 0x70, - 0x02, 0x2a, 0x04, 0xd1, 0x2a, 0x00, 0x19, 0x68, 0x20, 0x1d, 0x01, 0xf0, - 0xff, 0xf9, 0xbd, 0x42, 0x00, 0xd9, 0x3d, 0x00, 0x00, 0x2e, 0x0c, 0xd0, - 0x2a, 0x00, 0x30, 0x00, 0x65, 0x70, 0x21, 0x1d, 0x01, 0xf0, 0xf4, 0xf9, - 0x01, 0x22, 0x01, 0x9b, 0xff, 0x33, 0x1a, 0x72, 0x00, 0x23, 0xa3, 0x70, - 0xbe, 0xe7, 0x66, 0x70, 0xf6, 0xe7, 0xc0, 0x46, 0x30, 0x04, 0x00, 0x20, - 0xff, 0x3f, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x41, 0xff, 0x00, 0x00, 0x41, - 0x10, 0xb5, 0x00, 0x23, 0xff, 0xf7, 0x8c, 0xff, 0x10, 0xbd, 0xf8, 0xb5, - 0x05, 0x00, 0x0c, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x00, 0x2c, 0x00, 0xd1, - 0xf8, 0xbd, 0x21, 0x00, 0x28, 0x00, 0x3b, 0x00, 0x32, 0x00, 0xff, 0xf7, - 0x7d, 0xff, 0x24, 0x1a, 0x2d, 0x18, 0xf3, 0xe7, 0xf8, 0xb5, 0x0d, 0x00, - 0x82, 0x21, 0xc9, 0x05, 0x4c, 0x6a, 0x56, 0x01, 0x34, 0x19, 0x00, 0x2b, - 0x1b, 0xd0, 0x63, 0x69, 0x5b, 0x00, 0x5b, 0x08, 0x63, 0x61, 0x20, 0x61, - 0x63, 0x69, 0xaa, 0x04, 0x9b, 0x0b, 0x92, 0x0c, 0x9b, 0x03, 0x13, 0x43, - 0x63, 0x61, 0x63, 0x69, 0x16, 0x4a, 0x17, 0x48, 0x13, 0x40, 0x63, 0x61, - 0x32, 0x18, 0x02, 0x23, 0x80, 0x21, 0x16, 0x00, 0x13, 0x72, 0x91, 0x71, - 0x32, 0x7a, 0x1a, 0x42, 0xfc, 0xd0, 0x28, 0x00, 0xf8, 0xbd, 0x01, 0x21, - 0x63, 0x69, 0x5b, 0x00, 0x5b, 0x0f, 0x03, 0x33, 0x99, 0x40, 0xa9, 0x42, - 0x09, 0xd8, 0x04, 0x3a, 0x53, 0x1e, 0x9a, 0x41, 0x63, 0x69, 0xd1, 0x07, - 0x5b, 0x00, 0x5a, 0x08, 0x0a, 0x43, 0x62, 0x61, 0xd5, 0xe7, 0x44, 0x27, - 0x57, 0x43, 0x07, 0x4a, 0x04, 0x37, 0xbf, 0x18, 0x01, 0x00, 0x2a, 0x00, - 0x38, 0x00, 0x01, 0xf0, 0x8b, 0xf9, 0x38, 0x00, 0xc9, 0xe7, 0xc0, 0x46, - 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x41, 0x30, 0x04, 0x00, 0x20, - 0x10, 0xb5, 0x00, 0x23, 0xff, 0xf7, 0xb2, 0xff, 0x10, 0xbd, 0x00, 0x00, - 0x10, 0xb5, 0x05, 0x4a, 0x0b, 0x00, 0x11, 0x88, 0x99, 0x42, 0x00, 0xd9, - 0x19, 0x00, 0x00, 0x22, 0xff, 0xf7, 0xf0, 0xff, 0x10, 0xbd, 0xc0, 0x46, - 0x74, 0x07, 0x00, 0x20, 0x07, 0xb5, 0x00, 0x22, 0x6b, 0x46, 0x11, 0x00, - 0xd8, 0x1d, 0xff, 0xf7, 0xe5, 0xff, 0x07, 0xbd, 0xf0, 0xb5, 0x82, 0x24, - 0x9b, 0xb0, 0xe4, 0x05, 0xff, 0xf7, 0xea, 0xfd, 0xa3, 0x8b, 0x08, 0x21, - 0x1a, 0x00, 0x0a, 0x40, 0x03, 0x92, 0xb5, 0x4a, 0x0b, 0x42, 0x2e, 0xd0, - 0x80, 0x23, 0x40, 0x20, 0xa1, 0x83, 0xa3, 0x72, 0xc0, 0x24, 0x09, 0x31, - 0x51, 0x70, 0x90, 0x71, 0x53, 0x71, 0xb0, 0x4b, 0xb0, 0x4d, 0x59, 0x68, - 0xa4, 0x05, 0x29, 0x40, 0x21, 0x43, 0x59, 0x60, 0x59, 0x69, 0x29, 0x40, - 0x0c, 0x43, 0xad, 0x49, 0x5c, 0x61, 0x04, 0x31, 0x19, 0x60, 0xac, 0x49, - 0xac, 0x4c, 0x19, 0x61, 0x59, 0x68, 0x0c, 0x40, 0x80, 0x21, 0x89, 0x02, - 0x21, 0x43, 0x59, 0x60, 0x59, 0x68, 0x89, 0x0b, 0x89, 0x03, 0x59, 0x60, - 0x50, 0x71, 0x00, 0x22, 0xa6, 0x4b, 0x1a, 0x70, 0xa5, 0x4b, 0x18, 0x78, - 0x43, 0x1e, 0x98, 0x41, 0xc0, 0xb2, 0x1b, 0xb0, 0xf0, 0xbd, 0x10, 0x20, - 0x13, 0x7a, 0x03, 0x42, 0xf4, 0xd0, 0x9d, 0x4d, 0x10, 0x72, 0x6d, 0x89, - 0x9b, 0x48, 0xac, 0x46, 0x66, 0x46, 0x80, 0x79, 0x9d, 0x4d, 0x02, 0x90, - 0x98, 0x48, 0x98, 0x4b, 0xc7, 0x88, 0xc0, 0x79, 0x2e, 0x80, 0x40, 0x25, - 0x01, 0x90, 0x9b, 0x88, 0x94, 0x48, 0x99, 0x4e, 0x00, 0x89, 0x55, 0x71, - 0xb3, 0x42, 0x00, 0xd1, 0xb1, 0xe1, 0x36, 0xdc, 0x81, 0x24, 0x64, 0x00, - 0xa3, 0x42, 0x00, 0xd1, 0xc1, 0xe1, 0x15, 0xdc, 0x82, 0x2b, 0x00, 0xd1, - 0x8f, 0xe1, 0x06, 0xdc, 0x80, 0x3b, 0x01, 0x2b, 0x00, 0xd8, 0x85, 0xe1, - 0x20, 0x23, 0x93, 0x71, 0xca, 0xe7, 0x80, 0x21, 0x49, 0x00, 0x8b, 0x42, - 0xf8, 0xd0, 0x02, 0x21, 0xff, 0x31, 0x8b, 0x42, 0xf4, 0xd1, 0xff, 0xf7, - 0x83, 0xff, 0xbf, 0xe7, 0xb0, 0x21, 0x89, 0x00, 0x8b, 0x42, 0x00, 0xd1, - 0x6c, 0xe1, 0x0e, 0xdc, 0x01, 0x39, 0xff, 0x39, 0x8b, 0x42, 0xe7, 0xd0, - 0xa2, 0x3b, 0x83, 0x49, 0xff, 0x3b, 0x0b, 0x42, 0xe2, 0xd1, 0x00, 0x23, - 0x08, 0x21, 0x08, 0x93, 0x09, 0x93, 0x08, 0xa8, 0xc6, 0xe0, 0xc0, 0x21, - 0x89, 0x00, 0x8b, 0x42, 0xd8, 0xd0, 0x7d, 0x49, 0xdf, 0xe7, 0x7d, 0x48, - 0x83, 0x42, 0xde, 0xd0, 0x00, 0xdd, 0x98, 0xe0, 0x7b, 0x49, 0x8b, 0x42, - 0x14, 0xdc, 0x01, 0x39, 0x8b, 0x42, 0x00, 0xdb, 0xae, 0xe0, 0x79, 0x49, - 0x8b, 0x42, 0xe4, 0xd0, 0x60, 0x31, 0xff, 0x31, 0x8b, 0x42, 0xc3, 0xd1, - 0xff, 0xf7, 0x52, 0xff, 0x80, 0x23, 0x82, 0x22, 0x5b, 0x42, 0x3b, 0x43, - 0xdb, 0xb2, 0xd2, 0x05, 0x93, 0x72, 0x87, 0xe7, 0x88, 0x21, 0x69, 0x48, - 0x09, 0x01, 0x8b, 0x42, 0x00, 0xd1, 0x95, 0xe0, 0x80, 0x31, 0x8b, 0x42, - 0xb0, 0xd1, 0x07, 0x70, 0xff, 0xf7, 0x3e, 0xff, 0xa0, 0x23, 0x03, 0x22, - 0x5b, 0x00, 0xe2, 0x54, 0xc0, 0x22, 0x5c, 0x4b, 0x5c, 0x49, 0x58, 0x6c, - 0x92, 0x05, 0x08, 0x40, 0x10, 0x43, 0x58, 0x64, 0x46, 0x20, 0xff, 0x30, - 0x25, 0x54, 0x64, 0x48, 0x30, 0x27, 0x18, 0x64, 0x90, 0x20, 0x40, 0x00, - 0x27, 0x54, 0x58, 0x6b, 0x80, 0x26, 0x08, 0x40, 0x10, 0x43, 0x58, 0x63, - 0x92, 0x20, 0x40, 0x00, 0x26, 0x54, 0x5e, 0x48, 0x18, 0x63, 0xb0, 0x20, - 0x40, 0x00, 0x25, 0x54, 0x58, 0x6f, 0x08, 0x40, 0x58, 0x67, 0xb2, 0x20, - 0x40, 0x00, 0x26, 0x54, 0x3c, 0x30, 0x7d, 0x3e, 0x26, 0x54, 0xfc, 0x38, - 0x84, 0x46, 0x9c, 0x44, 0x60, 0x46, 0x06, 0x68, 0x0e, 0x40, 0x16, 0x43, - 0x06, 0x60, 0xa6, 0x26, 0xff, 0x36, 0xa5, 0x55, 0x1e, 0x00, 0x52, 0x48, - 0xa0, 0x36, 0x30, 0x60, 0xc0, 0x26, 0x76, 0x00, 0xa7, 0x55, 0x1f, 0x00, - 0x94, 0x37, 0x3e, 0x68, 0x80, 0x20, 0x0e, 0x40, 0x16, 0x43, 0x3e, 0x60, - 0xc2, 0x26, 0x76, 0x00, 0xa0, 0x55, 0x1e, 0x00, 0x4a, 0x4f, 0x90, 0x36, - 0x37, 0x60, 0xe0, 0x26, 0x44, 0x27, 0x76, 0x00, 0xa7, 0x55, 0x04, 0x36, - 0xa5, 0x55, 0xa0, 0x55, 0xc0, 0x19, 0x84, 0x46, 0x9c, 0x44, 0x60, 0x46, - 0x06, 0x68, 0x0e, 0x40, 0x16, 0x43, 0x06, 0x60, 0xd4, 0x20, 0x84, 0x46, + 0x04, 0x00, 0xfa, 0x05, 0x01, 0x22, 0x10, 0xb5, 0x1c, 0x4b, 0x1a, 0x70, + 0x1c, 0x4a, 0x13, 0x68, 0x01, 0x33, 0x13, 0x60, 0x1b, 0x4a, 0x93, 0x42, + 0x01, 0xd9, 0xff, 0xf7, 0xab, 0xff, 0x1a, 0x49, 0x0a, 0x68, 0x00, 0x2a, + 0x0c, 0xd0, 0x19, 0x48, 0x10, 0x18, 0x83, 0x42, 0x03, 0xd1, 0x80, 0x24, + 0x17, 0x48, 0x64, 0x03, 0x84, 0x61, 0x93, 0x42, 0x01, 0xd1, 0x00, 0x23, + 0x0b, 0x60, 0x10, 0xbd, 0x14, 0x48, 0xdb, 0xb2, 0x02, 0x78, 0x00, 0x2b, + 0x10, 0xd1, 0x80, 0x21, 0x10, 0x4b, 0x49, 0x03, 0x99, 0x61, 0x11, 0x00, + 0x0a, 0x39, 0xc9, 0xb2, 0x0f, 0x4b, 0xf0, 0x29, 0x02, 0xd9, 0x19, 0x78, + 0x49, 0x42, 0x19, 0x70, 0x1b, 0x78, 0xd2, 0x18, 0x02, 0x70, 0xe8, 0xe7, + 0x93, 0x42, 0xe6, 0xd1, 0x80, 0x22, 0x07, 0x4b, 0x52, 0x03, 0x5a, 0x61, + 0xe1, 0xe7, 0xc0, 0x46, 0xd0, 0x03, 0x00, 0x20, 0xd4, 0x03, 0x00, 0x20, + 0x00, 0xf2, 0x2b, 0x00, 0xdc, 0x03, 0x00, 0x20, 0x18, 0xfc, 0xff, 0xff, + 0x00, 0x60, 0x00, 0x41, 0x05, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, + 0x07, 0x4b, 0x08, 0x4a, 0x1b, 0x68, 0x11, 0x68, 0x99, 0x42, 0x07, 0xd2, + 0xfa, 0x21, 0xc9, 0x00, 0x5b, 0x18, 0x13, 0x60, 0x80, 0x22, 0x04, 0x4b, + 0x52, 0x03, 0x5a, 0x61, 0x70, 0x47, 0xc0, 0x46, 0xd4, 0x03, 0x00, 0x20, + 0xdc, 0x03, 0x00, 0x20, 0x00, 0x60, 0x00, 0x41, 0x80, 0x22, 0x02, 0x4b, + 0x52, 0x03, 0x9a, 0x60, 0x9a, 0x61, 0x70, 0x47, 0x00, 0x60, 0x00, 0x41, + 0x70, 0x47, 0x00, 0x00, 0x01, 0x22, 0x70, 0xb5, 0x0f, 0x24, 0x3a, 0x49, + 0x0b, 0x78, 0x13, 0x43, 0x0b, 0x70, 0x39, 0x4b, 0x18, 0x78, 0xa0, 0x43, + 0x18, 0x70, 0x06, 0x20, 0x19, 0x78, 0x08, 0x43, 0x36, 0x49, 0x18, 0x70, + 0x08, 0x78, 0x10, 0x43, 0x08, 0x70, 0x19, 0x78, 0x21, 0x40, 0x19, 0x70, + 0x60, 0x21, 0x18, 0x78, 0x01, 0x43, 0x19, 0x70, 0x40, 0x21, 0x31, 0x4b, + 0x19, 0x60, 0x31, 0x4b, 0x30, 0x39, 0x18, 0x69, 0x01, 0x43, 0x19, 0x61, + 0x99, 0x69, 0x0a, 0x43, 0x9a, 0x61, 0x2e, 0x4a, 0x53, 0x68, 0x5b, 0x07, + 0xfc, 0xd4, 0x82, 0x23, 0x01, 0x22, 0xdb, 0x05, 0x19, 0x78, 0x0a, 0x43, + 0x1a, 0x70, 0x9a, 0x78, 0xd2, 0x07, 0xfc, 0xd4, 0x1f, 0x20, 0x28, 0x4a, + 0x13, 0x68, 0x5b, 0x0b, 0x03, 0x40, 0x83, 0x42, 0x00, 0xd1, 0x05, 0x23, + 0x82, 0x21, 0xc9, 0x05, 0x0c, 0x8d, 0x24, 0x4d, 0x03, 0x40, 0x9b, 0x01, + 0x2c, 0x40, 0x23, 0x43, 0x0b, 0x85, 0x13, 0x68, 0x9b, 0x0c, 0x03, 0x40, + 0x1f, 0x2b, 0x00, 0xd1, 0x02, 0x3b, 0x1f, 0x24, 0x08, 0x8d, 0x23, 0x40, + 0xa0, 0x43, 0x03, 0x43, 0x07, 0x20, 0x0b, 0x85, 0x12, 0x68, 0xd2, 0x0d, + 0x02, 0x40, 0x82, 0x42, 0x00, 0xd1, 0x03, 0x22, 0x82, 0x23, 0xdb, 0x05, + 0x19, 0x8d, 0x02, 0x40, 0x16, 0x48, 0x12, 0x03, 0x01, 0x40, 0x0a, 0x43, + 0x7f, 0x21, 0x1a, 0x85, 0x1a, 0x78, 0x14, 0x48, 0x0a, 0x40, 0x1a, 0x70, + 0x04, 0x22, 0x19, 0x78, 0x0a, 0x43, 0x0c, 0x21, 0x1a, 0x70, 0x58, 0x62, + 0x1a, 0x89, 0x8a, 0x43, 0x1a, 0x81, 0x1a, 0x89, 0x0b, 0x39, 0x8a, 0x43, + 0x1a, 0x81, 0x80, 0x22, 0x00, 0x21, 0x52, 0x00, 0x01, 0xf0, 0x71, 0xfa, + 0x70, 0xbd, 0xc0, 0x46, 0x58, 0x60, 0x00, 0x41, 0x3c, 0x60, 0x00, 0x41, + 0x59, 0x60, 0x00, 0x41, 0x98, 0x1c, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, + 0x00, 0x1c, 0x00, 0x40, 0x20, 0x60, 0x80, 0x00, 0x3f, 0xf8, 0xff, 0xff, + 0xff, 0x8f, 0xff, 0xff, 0x74, 0x06, 0x00, 0x20, 0xf7, 0xb5, 0x1c, 0x00, + 0x82, 0x23, 0xdb, 0x05, 0x5b, 0x6a, 0x06, 0x00, 0x0f, 0x00, 0x15, 0x00, + 0x01, 0x93, 0x00, 0x2c, 0x05, 0xd1, 0x44, 0x34, 0x54, 0x43, 0x2d, 0x4b, + 0xe4, 0x18, 0xff, 0xf7, 0xc3, 0xfe, 0x63, 0x78, 0x22, 0x78, 0x93, 0x42, + 0x10, 0xd2, 0xd5, 0x1a, 0xbd, 0x42, 0x00, 0xd9, 0x3d, 0x00, 0x00, 0x2e, + 0x08, 0xd0, 0x21, 0x1d, 0xc9, 0x18, 0x2a, 0x00, 0x30, 0x00, 0x01, 0xf0, + 0x31, 0xfa, 0x63, 0x78, 0x5b, 0x19, 0x63, 0x70, 0x28, 0x00, 0xfe, 0xbd, + 0x01, 0x9b, 0xa1, 0x78, 0x6a, 0x01, 0xd3, 0x18, 0x00, 0x29, 0x11, 0xd1, + 0x21, 0x1d, 0x19, 0x60, 0x59, 0x68, 0x1d, 0x48, 0x89, 0x0b, 0x89, 0x03, + 0x59, 0x60, 0x59, 0x68, 0x01, 0x40, 0x59, 0x60, 0x1a, 0x49, 0x55, 0x18, + 0x40, 0x21, 0x28, 0x79, 0x01, 0x43, 0x29, 0x71, 0x01, 0x21, 0xa1, 0x70, + 0x82, 0x21, 0xc9, 0x05, 0x51, 0x18, 0x01, 0x91, 0x15, 0x49, 0x00, 0x25, + 0x52, 0x18, 0x12, 0x7a, 0xd2, 0x07, 0xdb, 0xd5, 0x5d, 0x68, 0xa2, 0x78, + 0xed, 0xb2, 0x25, 0x70, 0x02, 0x2a, 0x04, 0xd1, 0x2a, 0x00, 0x19, 0x68, + 0x20, 0x1d, 0x01, 0xf0, 0xff, 0xf9, 0xbd, 0x42, 0x00, 0xd9, 0x3d, 0x00, + 0x00, 0x2e, 0x0c, 0xd0, 0x2a, 0x00, 0x30, 0x00, 0x65, 0x70, 0x21, 0x1d, + 0x01, 0xf0, 0xf4, 0xf9, 0x01, 0x22, 0x01, 0x9b, 0xff, 0x33, 0x1a, 0x72, + 0x00, 0x23, 0xa3, 0x70, 0xbe, 0xe7, 0x66, 0x70, 0xf6, 0xe7, 0xc0, 0x46, + 0x30, 0x04, 0x00, 0x20, 0xff, 0x3f, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x41, + 0xff, 0x00, 0x00, 0x41, 0x10, 0xb5, 0x00, 0x23, 0xff, 0xf7, 0x8c, 0xff, + 0x10, 0xbd, 0xf8, 0xb5, 0x05, 0x00, 0x0c, 0x00, 0x16, 0x00, 0x1f, 0x00, + 0x00, 0x2c, 0x00, 0xd1, 0xf8, 0xbd, 0x21, 0x00, 0x28, 0x00, 0x3b, 0x00, + 0x32, 0x00, 0xff, 0xf7, 0x7d, 0xff, 0x24, 0x1a, 0x2d, 0x18, 0xf3, 0xe7, + 0xf8, 0xb5, 0x0d, 0x00, 0x82, 0x21, 0xc9, 0x05, 0x4c, 0x6a, 0x56, 0x01, + 0x34, 0x19, 0x00, 0x2b, 0x1b, 0xd0, 0x63, 0x69, 0x5b, 0x00, 0x5b, 0x08, + 0x63, 0x61, 0x20, 0x61, 0x63, 0x69, 0xaa, 0x04, 0x9b, 0x0b, 0x92, 0x0c, + 0x9b, 0x03, 0x13, 0x43, 0x63, 0x61, 0x63, 0x69, 0x16, 0x4a, 0x17, 0x48, + 0x13, 0x40, 0x63, 0x61, 0x32, 0x18, 0x02, 0x23, 0x80, 0x21, 0x16, 0x00, + 0x13, 0x72, 0x91, 0x71, 0x32, 0x7a, 0x1a, 0x42, 0xfc, 0xd0, 0x28, 0x00, + 0xf8, 0xbd, 0x01, 0x21, 0x63, 0x69, 0x5b, 0x00, 0x5b, 0x0f, 0x03, 0x33, + 0x99, 0x40, 0xa9, 0x42, 0x09, 0xd8, 0x04, 0x3a, 0x53, 0x1e, 0x9a, 0x41, + 0x63, 0x69, 0xd1, 0x07, 0x5b, 0x00, 0x5a, 0x08, 0x0a, 0x43, 0x62, 0x61, + 0xd5, 0xe7, 0x44, 0x27, 0x57, 0x43, 0x07, 0x4a, 0x04, 0x37, 0xbf, 0x18, + 0x01, 0x00, 0x2a, 0x00, 0x38, 0x00, 0x01, 0xf0, 0x8b, 0xf9, 0x38, 0x00, + 0xc9, 0xe7, 0xc0, 0x46, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x41, + 0x30, 0x04, 0x00, 0x20, 0x10, 0xb5, 0x00, 0x23, 0xff, 0xf7, 0xb2, 0xff, + 0x10, 0xbd, 0x00, 0x00, 0x10, 0xb5, 0x05, 0x4a, 0x0b, 0x00, 0x11, 0x88, + 0x99, 0x42, 0x00, 0xd9, 0x19, 0x00, 0x00, 0x22, 0xff, 0xf7, 0xf0, 0xff, + 0x10, 0xbd, 0xc0, 0x46, 0x74, 0x07, 0x00, 0x20, 0x07, 0xb5, 0x00, 0x22, + 0x6b, 0x46, 0x11, 0x00, 0xd8, 0x1d, 0xff, 0xf7, 0xe5, 0xff, 0x07, 0xbd, + 0xf0, 0xb5, 0x82, 0x24, 0x9b, 0xb0, 0xe4, 0x05, 0xff, 0xf7, 0xe2, 0xfd, + 0xa3, 0x8b, 0x08, 0x21, 0x1a, 0x00, 0x0a, 0x40, 0x03, 0x92, 0xb5, 0x4a, + 0x0b, 0x42, 0x2e, 0xd0, 0x80, 0x23, 0x40, 0x20, 0xa1, 0x83, 0xa3, 0x72, + 0xc0, 0x24, 0x09, 0x31, 0x51, 0x70, 0x90, 0x71, 0x53, 0x71, 0xb0, 0x4b, + 0xb0, 0x4d, 0x59, 0x68, 0xa4, 0x05, 0x29, 0x40, 0x21, 0x43, 0x59, 0x60, + 0x59, 0x69, 0x29, 0x40, 0x0c, 0x43, 0xad, 0x49, 0x5c, 0x61, 0x04, 0x31, + 0x19, 0x60, 0xac, 0x49, 0xac, 0x4c, 0x19, 0x61, 0x59, 0x68, 0x0c, 0x40, + 0x80, 0x21, 0x89, 0x02, 0x21, 0x43, 0x59, 0x60, 0x59, 0x68, 0x89, 0x0b, + 0x89, 0x03, 0x59, 0x60, 0x50, 0x71, 0x00, 0x22, 0xa6, 0x4b, 0x1a, 0x70, + 0xa5, 0x4b, 0x18, 0x78, 0x43, 0x1e, 0x98, 0x41, 0xc0, 0xb2, 0x1b, 0xb0, + 0xf0, 0xbd, 0x10, 0x20, 0x13, 0x7a, 0x03, 0x42, 0xf4, 0xd0, 0x9d, 0x4d, + 0x10, 0x72, 0x6d, 0x89, 0x9b, 0x48, 0xac, 0x46, 0x66, 0x46, 0x80, 0x79, + 0x9d, 0x4d, 0x02, 0x90, 0x98, 0x48, 0x98, 0x4b, 0xc7, 0x88, 0xc0, 0x79, + 0x2e, 0x80, 0x40, 0x25, 0x01, 0x90, 0x9b, 0x88, 0x94, 0x48, 0x99, 0x4e, + 0x00, 0x89, 0x55, 0x71, 0xb3, 0x42, 0x00, 0xd1, 0xb1, 0xe1, 0x36, 0xdc, + 0x81, 0x24, 0x64, 0x00, 0xa3, 0x42, 0x00, 0xd1, 0xc1, 0xe1, 0x15, 0xdc, + 0x82, 0x2b, 0x00, 0xd1, 0x8f, 0xe1, 0x06, 0xdc, 0x80, 0x3b, 0x01, 0x2b, + 0x00, 0xd8, 0x85, 0xe1, 0x20, 0x23, 0x93, 0x71, 0xca, 0xe7, 0x80, 0x21, + 0x49, 0x00, 0x8b, 0x42, 0xf8, 0xd0, 0x02, 0x21, 0xff, 0x31, 0x8b, 0x42, + 0xf4, 0xd1, 0xff, 0xf7, 0x83, 0xff, 0xbf, 0xe7, 0xb0, 0x21, 0x89, 0x00, + 0x8b, 0x42, 0x00, 0xd1, 0x6c, 0xe1, 0x0e, 0xdc, 0x01, 0x39, 0xff, 0x39, + 0x8b, 0x42, 0xe7, 0xd0, 0xa2, 0x3b, 0x83, 0x49, 0xff, 0x3b, 0x0b, 0x42, + 0xe2, 0xd1, 0x00, 0x23, 0x08, 0x21, 0x08, 0x93, 0x09, 0x93, 0x08, 0xa8, + 0xc6, 0xe0, 0xc0, 0x21, 0x89, 0x00, 0x8b, 0x42, 0xd8, 0xd0, 0x7d, 0x49, + 0xdf, 0xe7, 0x7d, 0x48, 0x83, 0x42, 0xde, 0xd0, 0x00, 0xdd, 0x98, 0xe0, + 0x7b, 0x49, 0x8b, 0x42, 0x14, 0xdc, 0x01, 0x39, 0x8b, 0x42, 0x00, 0xdb, + 0xae, 0xe0, 0x79, 0x49, 0x8b, 0x42, 0xe4, 0xd0, 0x60, 0x31, 0xff, 0x31, + 0x8b, 0x42, 0xc3, 0xd1, 0xff, 0xf7, 0x52, 0xff, 0x80, 0x23, 0x82, 0x22, + 0x5b, 0x42, 0x3b, 0x43, 0xdb, 0xb2, 0xd2, 0x05, 0x93, 0x72, 0x87, 0xe7, + 0x88, 0x21, 0x69, 0x48, 0x09, 0x01, 0x8b, 0x42, 0x00, 0xd1, 0x95, 0xe0, + 0x80, 0x31, 0x8b, 0x42, 0xb0, 0xd1, 0x07, 0x70, 0xff, 0xf7, 0x3e, 0xff, + 0xa0, 0x23, 0x03, 0x22, 0x5b, 0x00, 0xe2, 0x54, 0xc0, 0x22, 0x5c, 0x4b, + 0x5c, 0x49, 0x58, 0x6c, 0x92, 0x05, 0x08, 0x40, 0x10, 0x43, 0x58, 0x64, + 0x46, 0x20, 0xff, 0x30, 0x25, 0x54, 0x64, 0x48, 0x30, 0x27, 0x18, 0x64, + 0x90, 0x20, 0x40, 0x00, 0x27, 0x54, 0x58, 0x6b, 0x80, 0x26, 0x08, 0x40, + 0x10, 0x43, 0x58, 0x63, 0x92, 0x20, 0x40, 0x00, 0x26, 0x54, 0x5e, 0x48, + 0x18, 0x63, 0xb0, 0x20, 0x40, 0x00, 0x25, 0x54, 0x58, 0x6f, 0x08, 0x40, + 0x58, 0x67, 0xb2, 0x20, 0x40, 0x00, 0x26, 0x54, 0x3c, 0x30, 0x7d, 0x3e, + 0x26, 0x54, 0xfc, 0x38, 0x84, 0x46, 0x9c, 0x44, 0x60, 0x46, 0x06, 0x68, + 0x0e, 0x40, 0x16, 0x43, 0x06, 0x60, 0xa6, 0x26, 0xff, 0x36, 0xa5, 0x55, + 0x1e, 0x00, 0x52, 0x48, 0xa0, 0x36, 0x30, 0x60, 0xc0, 0x26, 0x76, 0x00, + 0xa7, 0x55, 0x1f, 0x00, 0x94, 0x37, 0x3e, 0x68, 0x80, 0x20, 0x0e, 0x40, + 0x16, 0x43, 0x3e, 0x60, 0xc2, 0x26, 0x76, 0x00, 0xa0, 0x55, 0x1e, 0x00, + 0x4a, 0x4f, 0x90, 0x36, 0x37, 0x60, 0xe0, 0x26, 0x44, 0x27, 0x76, 0x00, + 0xa7, 0x55, 0x04, 0x36, 0xa5, 0x55, 0xa0, 0x55, 0xc0, 0x19, 0x84, 0x46, 0x9c, 0x44, 0x60, 0x46, 0x06, 0x68, 0x0e, 0x40, 0x16, 0x43, 0x06, 0x60, - 0xf0, 0x26, 0x80, 0x20, 0x76, 0x00, 0xa7, 0x55, 0x04, 0x36, 0xa5, 0x55, - 0xa0, 0x55, 0x1c, 0x00, 0xe4, 0x34, 0x20, 0x68, 0xf4, 0x33, 0x08, 0x40, - 0x10, 0x43, 0x20, 0x60, 0x18, 0x68, 0x01, 0x40, 0x0a, 0x43, 0x1a, 0x60, - 0x06, 0xe7, 0x35, 0x48, 0x83, 0x42, 0x00, 0xd1, 0x24, 0xe1, 0x0a, 0xdc, - 0x33, 0x49, 0x8b, 0x42, 0x00, 0xd1, 0x3a, 0xe7, 0x32, 0x49, 0x33, 0x48, - 0x0b, 0x40, 0x83, 0x42, 0x00, 0xd1, 0x34, 0xe7, 0x28, 0xe7, 0x31, 0x49, - 0x8b, 0x42, 0x00, 0xd1, 0x2f, 0xe7, 0x30, 0x49, 0x8b, 0x42, 0x00, 0xd0, - 0x20, 0xe7, 0x00, 0x23, 0x08, 0xa8, 0x03, 0x80, 0x01, 0x21, 0x05, 0xe0, - 0x80, 0x23, 0x5b, 0x00, 0x9f, 0x42, 0x04, 0xd1, 0x12, 0x21, 0x2a, 0x48, - 0xff, 0xf7, 0x96, 0xfe, 0xe0, 0xe6, 0x80, 0x23, 0x9b, 0x00, 0x9f, 0x42, - 0x02, 0xd1, 0x99, 0x21, 0x26, 0x48, 0xf5, 0xe7, 0x01, 0x9b, 0x03, 0x2b, - 0x75, 0xd1, 0x02, 0x9b, 0x03, 0x2b, 0x00, 0xd9, 0x04, 0xe7, 0x08, 0xac, - 0x48, 0x22, 0x00, 0x21, 0x20, 0x00, 0x01, 0xf0, 0x06, 0xf8, 0x01, 0x9b, - 0x63, 0x70, 0x02, 0x9b, 0x00, 0x2b, 0x3b, 0xd1, 0x09, 0x22, 0x04, 0x33, - 0x23, 0x70, 0xa2, 0x70, 0xe3, 0x70, 0x20, 0x00, 0x21, 0x78, 0xdb, 0xe7, - 0xff, 0x00, 0x00, 0x41, 0x74, 0x06, 0x00, 0x20, 0xff, 0xff, 0xff, 0x8f, - 0xe8, 0x03, 0x00, 0x20, 0x34, 0x04, 0x00, 0x20, 0xff, 0x3f, 0x00, 0xf0, - 0x2c, 0x04, 0x00, 0x20, 0x74, 0x07, 0x00, 0x20, 0x02, 0x03, 0x00, 0x00, - 0xff, 0xfe, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x21, 0x09, 0x00, 0x00, - 0x81, 0x06, 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0xbc, 0x04, 0x00, 0x20, - 0x78, 0x04, 0x00, 0x20, 0x88, 0x05, 0x00, 0x20, 0x44, 0x05, 0x00, 0x20, - 0xa1, 0x21, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, - 0x21, 0x0a, 0x00, 0x00, 0x21, 0x22, 0x00, 0x00, 0xa1, 0xfe, 0x00, 0x00, - 0x70, 0x1b, 0x00, 0x00, 0x44, 0x00, 0x00, 0x20, 0x04, 0xae, 0x32, 0x00, - 0x56, 0x4b, 0x23, 0xcb, 0x23, 0xc2, 0x00, 0x25, 0x2f, 0x00, 0x1b, 0x68, - 0x13, 0x60, 0xab, 0x00, 0x53, 0x4a, 0xf3, 0x58, 0xd0, 0x19, 0x19, 0x68, - 0x01, 0x22, 0xff, 0xf7, 0x05, 0xfc, 0x01, 0x35, 0x3f, 0x18, 0x04, 0x2d, - 0xf3, 0xd1, 0x00, 0x23, 0x4d, 0x4a, 0xd3, 0x55, 0x4d, 0x4b, 0x4e, 0x4a, - 0x9b, 0x79, 0x9b, 0x00, 0x9d, 0x58, 0x28, 0x00, 0x00, 0xf0, 0xad, 0xff, - 0x23, 0x00, 0x01, 0x30, 0x40, 0x00, 0x20, 0x70, 0x2a, 0x78, 0x02, 0x33, - 0x01, 0x35, 0x00, 0x2a, 0x9f, 0xd0, 0x1a, 0x70, 0xf8, 0xe7, 0x01, 0x9b, - 0x0f, 0x2b, 0x02, 0xd1, 0x39, 0x21, 0x44, 0x48, 0x76, 0xe7, 0x01, 0x9b, - 0x21, 0x2b, 0x02, 0xd1, 0x09, 0x21, 0x42, 0x48, 0x70, 0xe7, 0x01, 0x9b, - 0x22, 0x2b, 0x00, 0xd0, 0x82, 0xe6, 0x21, 0x21, 0x3f, 0x48, 0x69, 0xe7, - 0x07, 0x28, 0x00, 0xd0, 0x7c, 0xe6, 0xaa, 0x21, 0x3d, 0x48, 0x63, 0xe7, - 0x03, 0x9b, 0x08, 0xa8, 0x02, 0x21, 0x03, 0x80, 0x5e, 0xe7, 0x08, 0x42, - 0x00, 0xd0, 0x71, 0xe6, 0x0f, 0x23, 0x50, 0x22, 0x03, 0x40, 0x08, 0x33, - 0x5b, 0x01, 0x10, 0x42, 0x07, 0xd0, 0x82, 0x22, 0xd2, 0x05, 0x9b, 0x18, - 0x9b, 0x79, 0x9b, 0x06, 0xdb, 0x0f, 0x08, 0xa8, 0xea, 0xe7, 0x82, 0x22, - 0xd2, 0x05, 0x9b, 0x18, 0x9b, 0x79, 0xdb, 0x06, 0xf6, 0xe7, 0x0f, 0x24, - 0x03, 0x00, 0x23, 0x40, 0x20, 0x42, 0x00, 0xd1, 0x56, 0xe6, 0x01, 0x40, - 0x39, 0x43, 0x00, 0xd0, 0x52, 0xe6, 0x82, 0x22, 0x08, 0x33, 0x5b, 0x01, - 0xd2, 0x05, 0x9b, 0x18, 0x02, 0x06, 0x02, 0xd5, 0x20, 0x22, 0x5a, 0x71, - 0x53, 0xe6, 0x10, 0x22, 0xfb, 0xe7, 0x0f, 0x24, 0x03, 0x00, 0x23, 0x40, - 0x20, 0x42, 0x00, 0xd1, 0x40, 0xe6, 0x01, 0x40, 0x39, 0x43, 0x00, 0xd0, - 0x3c, 0xe6, 0x5b, 0x01, 0x02, 0x06, 0x14, 0xd5, 0x82, 0x22, 0x1d, 0x49, - 0xd2, 0x05, 0x9a, 0x18, 0x5b, 0x18, 0x20, 0x21, 0xd8, 0x79, 0x08, 0x42, - 0x00, 0xd1, 0x3a, 0xe6, 0x59, 0x71, 0x1b, 0x7a, 0x2b, 0x42, 0x00, 0xd1, - 0x35, 0xe6, 0x13, 0x00, 0x40, 0x22, 0xff, 0x33, 0x1a, 0x72, 0x3e, 0x3a, - 0xd9, 0xe7, 0x82, 0x22, 0x10, 0x20, 0x12, 0x49, 0xd2, 0x05, 0x9a, 0x18, - 0x5b, 0x18, 0xd9, 0x79, 0x01, 0x42, 0x00, 0xd1, 0x25, 0xe6, 0x58, 0x71, - 0x1b, 0x7a, 0x01, 0x18, 0x0b, 0x42, 0x00, 0xd1, 0x1f, 0xe6, 0x13, 0x00, - 0xff, 0x33, 0x01, 0x22, 0x19, 0x72, 0xc4, 0xe7, 0x09, 0x48, 0xf7, 0xe6, - 0x60, 0x1b, 0x00, 0x00, 0x50, 0x06, 0x00, 0x20, 0xe8, 0x03, 0x00, 0x20, - 0xa8, 0x1b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0xe0, 0x00, 0x00, 0x20, - 0x84, 0x1b, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x20, 0xff, 0x00, 0x00, 0x41, - 0xec, 0x00, 0x00, 0x20, 0x10, 0xb5, 0xff, 0xf7, 0x17, 0xfc, 0x00, 0x22, - 0x04, 0x4b, 0x1a, 0x70, 0x82, 0x22, 0x02, 0x23, 0xd2, 0x05, 0x11, 0x78, - 0x0b, 0x43, 0x13, 0x70, 0x10, 0xbd, 0xc0, 0x46, 0x2c, 0x04, 0x00, 0x20, - 0x10, 0xb5, 0x0c, 0x00, 0x01, 0x22, 0xff, 0xf7, 0x61, 0xfd, 0x20, 0x00, - 0x10, 0xbd, 0x10, 0xb5, 0x0c, 0x00, 0x01, 0x22, 0xff, 0xf7, 0x5a, 0xfd, - 0x20, 0x00, 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x00, 0x0d, 0x00, 0xff, 0xf7, - 0x6f, 0xfd, 0x03, 0x00, 0x00, 0x20, 0x83, 0x42, 0x04, 0xd0, 0x02, 0x22, - 0x29, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xea, 0xfc, 0x70, 0xbd, 0x70, 0xb5, - 0x05, 0x00, 0x0c, 0x00, 0xff, 0xf7, 0x60, 0xfd, 0x00, 0x28, 0x07, 0xd0, - 0x00, 0x23, 0x02, 0x22, 0x21, 0x00, 0x28, 0x00, 0xff, 0xf7, 0xe1, 0xfc, - 0x20, 0x00, 0x70, 0xbd, 0x04, 0x00, 0xfb, 0xe7, 0x30, 0xb5, 0x00, 0x23, - 0x20, 0x25, 0x93, 0x42, 0x00, 0xdb, 0x30, 0xbd, 0x0c, 0x78, 0x00, 0x2c, - 0x03, 0xd0, 0x01, 0x31, 0xc4, 0x54, 0x01, 0x33, 0xf5, 0xe7, 0x2c, 0x00, - 0xfa, 0xe7, 0x00, 0x00, 0xf8, 0xb5, 0x80, 0x22, 0x0c, 0x00, 0x05, 0x00, - 0x00, 0x21, 0x20, 0x00, 0x92, 0x00, 0x00, 0xf0, 0xaa, 0xfe, 0x00, 0x2d, - 0x0c, 0xd1, 0x3e, 0x22, 0x20, 0x00, 0x4a, 0x49, 0x00, 0xf0, 0x9a, 0xfe, - 0xff, 0x23, 0x55, 0x22, 0x5b, 0x00, 0xe2, 0x54, 0x47, 0x4b, 0x92, 0x18, - 0xe2, 0x54, 0xf8, 0xbd, 0x7e, 0x2d, 0x23, 0xd8, 0x6e, 0x1e, 0x3e, 0x2e, - 0x01, 0xd9, 0x40, 0x3d, 0x2e, 0x00, 0x00, 0x2e, 0x12, 0xd0, 0x80, 0x25, - 0x33, 0x02, 0x58, 0x1c, 0x40, 0x4e, 0xff, 0x30, 0xed, 0x00, 0x1a, 0x1f, - 0x59, 0x1c, 0xaa, 0x42, 0x03, 0xd2, 0xb3, 0x42, 0x0e, 0xd0, 0x8b, 0xb2, - 0x23, 0x80, 0x0b, 0x00, 0x02, 0x34, 0x81, 0x42, 0xf3, 0xd1, 0xe2, 0xe7, - 0xf0, 0x23, 0x09, 0x22, 0xff, 0x21, 0x23, 0x70, 0x60, 0x1c, 0x00, 0xf0, - 0x78, 0xfe, 0xe4, 0xe7, 0x35, 0x4b, 0xef, 0xe7, 0x82, 0x2d, 0x31, 0xd8, - 0x7f, 0x2d, 0xd4, 0xd1, 0x2f, 0x49, 0x0b, 0x22, 0x20, 0x00, 0x2b, 0x31, - 0xff, 0xf7, 0xa8, 0xff, 0x80, 0x27, 0x28, 0x23, 0x2f, 0x4e, 0xe3, 0x72, - 0x7d, 0x3d, 0x3f, 0x03, 0xf0, 0x68, 0x3b, 0x00, 0x20, 0x34, 0x00, 0x28, - 0x02, 0xd0, 0x00, 0xf0, 0x66, 0xfe, 0x03, 0x00, 0x1a, 0x0a, 0x23, 0x77, - 0x62, 0x77, 0x1a, 0x0c, 0x1b, 0x0e, 0xe3, 0x77, 0x2b, 0x0a, 0x31, 0x00, - 0xa2, 0x77, 0xa5, 0x76, 0x0b, 0x22, 0xe3, 0x76, 0x20, 0x00, 0xff, 0xf7, - 0x8b, 0xff, 0x67, 0x22, 0x4d, 0x23, 0x01, 0x35, 0x52, 0x42, 0xad, 0xb2, - 0x22, 0x74, 0x63, 0x74, 0x22, 0x76, 0x63, 0x76, 0x10, 0x36, 0x05, 0x2d, - 0xdc, 0xd1, 0xa4, 0xe7, 0x2b, 0x00, 0x83, 0x3b, 0x01, 0x2b, 0x0c, 0xd8, - 0x19, 0x4a, 0x1b, 0x01, 0xd3, 0x18, 0xdd, 0x68, 0x28, 0x00, 0x00, 0xf0, - 0x3e, 0xfe, 0x29, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0xf0, 0x28, 0xfe, - 0x93, 0xe7, 0x80, 0x23, 0x85, 0x3d, 0x29, 0x02, 0xdb, 0x02, 0x99, 0x42, - 0x00, 0xd3, 0x8c, 0xe7, 0x10, 0x4b, 0x11, 0x4a, 0x23, 0x60, 0x11, 0x4b, - 0x20, 0x00, 0x63, 0x60, 0xfe, 0x23, 0x5b, 0x00, 0xe2, 0x50, 0x80, 0x23, - 0xdb, 0x00, 0xa3, 0x61, 0x80, 0x23, 0x80, 0x22, 0x9b, 0x01, 0xa3, 0x60, - 0x0b, 0x4b, 0x52, 0x00, 0x65, 0x61, 0xe1, 0x60, 0x22, 0x61, 0xe3, 0x61, - 0x20, 0x30, 0xdd, 0xe7, 0xb8, 0x1b, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, - 0x03, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x64, 0x1c, 0x00, 0x00, - 0x55, 0x46, 0x32, 0x0a, 0x30, 0x6f, 0xb1, 0x0a, 0x57, 0x51, 0x5d, 0x9e, - 0x2f, 0x47, 0x29, 0x2c, 0x70, 0xb5, 0x16, 0x00, 0x1d, 0x00, 0x0a, 0x68, - 0x2f, 0x4b, 0x0c, 0x00, 0x9a, 0x42, 0x52, 0xd1, 0x2e, 0x4b, 0x4a, 0x68, - 0x9a, 0x42, 0x4e, 0xd1, 0xfe, 0x22, 0x52, 0x00, 0x2c, 0x4b, 0x8a, 0x58, - 0x9a, 0x42, 0x48, 0xd1, 0x8b, 0x68, 0x9a, 0x04, 0x03, 0xd5, 0x2a, 0x4a, - 0xc9, 0x69, 0x91, 0x42, 0x41, 0xd1, 0xdb, 0x07, 0x12, 0xd4, 0x80, 0x23, - 0x22, 0x69, 0x5b, 0x00, 0x9a, 0x42, 0x0d, 0xd1, 0xe0, 0x68, 0xc3, 0xb2, - 0x00, 0x2b, 0x09, 0xd1, 0xf8, 0x22, 0x23, 0x4b, 0x92, 0x02, 0xc3, 0x18, - 0x93, 0x42, 0x03, 0xd2, 0x21, 0x00, 0x20, 0x31, 0xff, 0xf7, 0xee, 0xf8, - 0x00, 0x2d, 0x2b, 0xd0, 0xa3, 0x69, 0x00, 0x2b, 0x28, 0xd0, 0x29, 0x68, - 0x1c, 0x4a, 0x8b, 0x42, 0x06, 0xd0, 0x93, 0x42, 0x01, 0xd8, 0x00, 0x29, - 0x01, 0xd0, 0x01, 0x23, 0x5b, 0x42, 0x2b, 0x60, 0x63, 0x69, 0x93, 0x42, - 0x19, 0xd8, 0x07, 0x22, 0x01, 0x21, 0x1a, 0x40, 0x91, 0x40, 0xdb, 0x08, - 0xeb, 0x18, 0x1a, 0x7a, 0xc8, 0xb2, 0x11, 0x42, 0x04, 0xd1, 0x69, 0x68, - 0x02, 0x43, 0x01, 0x31, 0x1a, 0x72, 0x69, 0x60, 0x6a, 0x68, 0x2b, 0x68, - 0x9a, 0x42, 0x06, 0xd3, 0x00, 0x2e, 0x04, 0xd1, 0x0c, 0x4b, 0x1b, 0x68, - 0x1e, 0x33, 0x0c, 0x4a, 0x13, 0x60, 0x70, 0xbd, 0x00, 0x2e, 0xfc, 0xd1, - 0x08, 0x4b, 0x1b, 0x68, 0x2d, 0x33, 0xff, 0x33, 0xf5, 0xe7, 0xc0, 0x46, - 0x55, 0x46, 0x32, 0x0a, 0x57, 0x51, 0x5d, 0x9e, 0x30, 0x6f, 0xb1, 0x0a, - 0x2f, 0x47, 0x29, 0x2c, 0x00, 0xe0, 0xff, 0xff, 0x63, 0x04, 0x00, 0x00, - 0xe0, 0x03, 0x00, 0x20, 0xd8, 0x03, 0x00, 0x20, 0xf8, 0xb5, 0x5a, 0x4e, - 0xb2, 0x68, 0x00, 0x2a, 0x00, 0xd0, 0xfe, 0xe7, 0x58, 0x4b, 0x1a, 0x70, - 0x9a, 0x68, 0x00, 0x2a, 0xfc, 0xd1, 0x57, 0x4c, 0x02, 0x32, 0x23, 0x69, - 0x93, 0x43, 0x23, 0x61, 0xe3, 0x68, 0x5b, 0x07, 0xfc, 0xd5, 0x23, 0x69, - 0x53, 0x4a, 0x1a, 0x40, 0x80, 0x23, 0x1b, 0x03, 0x13, 0x43, 0x18, 0x22, - 0x23, 0x61, 0x23, 0x69, 0x93, 0x43, 0x23, 0x61, 0x02, 0x23, 0x22, 0x69, - 0x13, 0x43, 0x23, 0x61, 0xe3, 0x68, 0xdb, 0x07, 0xfc, 0xd5, 0xe3, 0x68, - 0x9b, 0x07, 0xfc, 0xd4, 0x4a, 0x4d, 0x2b, 0x78, 0xdb, 0x07, 0x02, 0xd4, - 0x2b, 0x78, 0x5b, 0x07, 0x05, 0xd5, 0x64, 0x20, 0xff, 0xf7, 0x96, 0xf9, - 0xe3, 0x68, 0x9b, 0x07, 0xf9, 0xd4, 0x02, 0x22, 0x23, 0x69, 0x93, 0x43, - 0x23, 0x61, 0xe3, 0x68, 0x5b, 0x07, 0xfc, 0xd5, 0x18, 0x22, 0x23, 0x69, - 0x93, 0x43, 0x1a, 0x00, 0x08, 0x23, 0x13, 0x43, 0x23, 0x61, 0x02, 0x23, - 0x22, 0x69, 0x13, 0x43, 0x23, 0x61, 0xff, 0xf7, 0x51, 0xfa, 0x3b, 0x4b, - 0x1f, 0x68, 0x3b, 0x4b, 0xfa, 0x18, 0xf8, 0x23, 0x9b, 0x02, 0x9a, 0x42, - 0x12, 0xd8, 0x39, 0x4a, 0x39, 0x4b, 0x12, 0x68, 0x39, 0x4c, 0x9a, 0x42, - 0x32, 0xd1, 0x2a, 0x78, 0x38, 0x4b, 0xd2, 0x07, 0x02, 0xd4, 0x22, 0x68, - 0x9a, 0x42, 0x2b, 0xd0, 0x23, 0x60, 0x36, 0x4b, 0x36, 0x4a, 0x1b, 0x68, - 0x32, 0x33, 0x13, 0x60, 0xff, 0xf7, 0x5a, 0xf8, 0xbf, 0xf3, 0x5f, 0x8f, - 0x62, 0xb6, 0xff, 0xf7, 0x1f, 0xfe, 0x40, 0x20, 0xff, 0xf7, 0x34, 0xfa, - 0x80, 0x27, 0x0a, 0x23, 0x01, 0x26, 0x2f, 0x4d, 0xff, 0x01, 0x2b, 0x70, - 0xff, 0xf7, 0xa6, 0xfb, 0x2d, 0x4c, 0x00, 0x28, 0x0a, 0xd0, 0x23, 0x78, - 0xda, 0xb2, 0x00, 0x2b, 0x05, 0xd1, 0x28, 0x4b, 0x38, 0x00, 0x1a, 0x60, - 0xff, 0xf7, 0x20, 0xfa, 0x2e, 0x70, 0x26, 0x70, 0x23, 0x78, 0x00, 0x2b, - 0x25, 0xd0, 0x00, 0xf0, 0xbf, 0xfa, 0xfc, 0xe7, 0x2b, 0x78, 0xdb, 0x07, - 0xda, 0x0f, 0x00, 0x2b, 0x0d, 0xd0, 0x00, 0x23, 0x80, 0x22, 0x23, 0x60, - 0x20, 0x4b, 0x52, 0x03, 0x5a, 0x61, 0x80, 0x23, 0x9b, 0x01, 0x1a, 0x68, - 0x82, 0xf3, 0x08, 0x88, 0xb3, 0x60, 0x38, 0x47, 0xc6, 0xe7, 0x21, 0x68, - 0x1b, 0x4b, 0x99, 0x42, 0x01, 0xd1, 0x22, 0x60, 0xc0, 0xe7, 0x21, 0x68, - 0x12, 0x4a, 0x91, 0x42, 0xe7, 0xd0, 0xfa, 0x20, 0x23, 0x60, 0x40, 0x00, - 0xff, 0xf7, 0x1c, 0xf9, 0xe1, 0xe7, 0x23, 0x78, 0x00, 0x2b, 0xc3, 0xd1, - 0xff, 0x33, 0xc0, 0x46, 0x01, 0x3b, 0x00, 0x2b, 0xfb, 0xd1, 0xbd, 0xe7, - 0x00, 0xed, 0x00, 0xe0, 0x00, 0x20, 0x00, 0x40, 0x00, 0x18, 0x00, 0x40, - 0xff, 0xff, 0xc0, 0xff, 0x00, 0x0c, 0x00, 0x40, 0x04, 0x20, 0x00, 0x00, - 0x00, 0xe0, 0xff, 0xff, 0xa8, 0x20, 0x00, 0x00, 0x7c, 0xb0, 0xee, 0x87, - 0xfc, 0x7f, 0x00, 0x20, 0xef, 0x69, 0x26, 0xf0, 0xe0, 0x03, 0x00, 0x20, - 0xd8, 0x03, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, 0x76, 0x07, 0x00, 0x20, - 0x00, 0x60, 0x00, 0x41, 0xef, 0x69, 0x16, 0xf0, 0x10, 0xb5, 0x05, 0x4c, - 0x12, 0x22, 0x00, 0x21, 0x20, 0x00, 0x00, 0xf0, 0xac, 0xfc, 0xf0, 0x23, - 0x23, 0x70, 0xe6, 0x3b, 0xe3, 0x71, 0x10, 0xbd, 0xb3, 0x09, 0x00, 0x20, - 0x10, 0xb5, 0xff, 0xf7, 0xef, 0xff, 0x00, 0x22, 0x01, 0x4b, 0x1a, 0x73, - 0x10, 0xbd, 0xc0, 0x46, 0x9e, 0x01, 0x00, 0x20, 0xf7, 0xb5, 0x80, 0x27, - 0x04, 0x00, 0x16, 0x00, 0x00, 0x25, 0x01, 0x91, 0xbf, 0x00, 0xa3, 0x68, - 0xab, 0x42, 0x00, 0xd8, 0xf7, 0xbd, 0x39, 0x00, 0xa2, 0x78, 0x01, 0x9b, - 0xe0, 0x68, 0xff, 0xf7, 0xa4, 0xfa, 0x80, 0x23, 0x5b, 0x01, 0xe8, 0x18, - 0x01, 0x22, 0x33, 0x00, 0xe1, 0x68, 0xff, 0xf7, 0x83, 0xfe, 0x01, 0x35, - 0xeb, 0xe7, 0x70, 0xb5, 0x13, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x15, 0x00, - 0x00, 0x20, 0x0a, 0x00, 0x01, 0x21, 0xff, 0xf7, 0x1b, 0xfa, 0x00, 0x23, - 0x98, 0x42, 0x06, 0xd0, 0x2b, 0x00, 0x22, 0x00, 0x1f, 0x21, 0x30, 0x00, - 0xff, 0xf7, 0x12, 0xfa, 0x01, 0x23, 0x18, 0x00, 0x70, 0xbd, 0x00, 0x00, - 0x10, 0xb5, 0x04, 0x22, 0x0d, 0x21, 0x02, 0x48, 0xff, 0xf7, 0xd8, 0xfa, - 0x10, 0xbd, 0xc0, 0x46, 0x9e, 0x01, 0x00, 0x20, 0x10, 0xb5, 0x0b, 0x4c, - 0x0b, 0x48, 0x61, 0x79, 0x23, 0x79, 0xa2, 0x79, 0x09, 0x02, 0x19, 0x43, - 0xe3, 0x79, 0x12, 0x04, 0x11, 0x43, 0x1b, 0x06, 0x0b, 0x43, 0x1a, 0x0a, - 0x03, 0x71, 0x42, 0x71, 0x1a, 0x0c, 0x1b, 0x0e, 0x82, 0x71, 0xc3, 0x71, - 0xff, 0xf7, 0xe0, 0xff, 0x10, 0xbd, 0xc0, 0x46, 0x94, 0x09, 0x00, 0x20, - 0x9e, 0x01, 0x00, 0x20, 0x70, 0xb5, 0x04, 0x22, 0x0d, 0x00, 0xff, 0xf7, - 0xb3, 0xfa, 0x15, 0x4c, 0x85, 0x42, 0x0f, 0xd0, 0xff, 0xf7, 0x86, 0xff, - 0x01, 0x23, 0x04, 0x22, 0x23, 0x73, 0x12, 0x4b, 0x9a, 0x70, 0x00, 0x22, - 0xda, 0x70, 0x1a, 0x71, 0x5a, 0x71, 0x9a, 0x71, 0x1a, 0x73, 0x5a, 0x73, - 0xff, 0xf7, 0xcc, 0xff, 0xff, 0xf7, 0x84, 0xff, 0x63, 0x7a, 0x21, 0x7a, - 0x1b, 0x02, 0x0b, 0x43, 0xa1, 0x7a, 0xe2, 0x7a, 0x09, 0x04, 0x12, 0x06, - 0x19, 0x43, 0x11, 0x43, 0x49, 0x1b, 0x0b, 0x0a, 0x21, 0x72, 0x63, 0x72, - 0x0b, 0x0c, 0x09, 0x0e, 0xa3, 0x72, 0xe1, 0x72, 0xff, 0xf7, 0xb6, 0xff, - 0x70, 0xbd, 0xc0, 0x46, 0x9e, 0x01, 0x00, 0x20, 0xb3, 0x09, 0x00, 0x20, - 0x70, 0xb5, 0x18, 0x4c, 0x14, 0x22, 0x05, 0x00, 0x00, 0x21, 0x20, 0x00, - 0x00, 0xf0, 0x07, 0xfc, 0x15, 0x4a, 0x00, 0x2d, 0x1f, 0xd0, 0x21, 0x00, - 0x08, 0x23, 0xd0, 0x7d, 0x08, 0x31, 0x3f, 0x26, 0x52, 0x7c, 0x32, 0x40, - 0x1c, 0x2a, 0x01, 0xd0, 0xb2, 0x42, 0x05, 0xd1, 0x0f, 0x4a, 0x0c, 0x33, - 0x0a, 0x80, 0x05, 0x22, 0xdb, 0xb2, 0xca, 0x70, 0x19, 0x1c, 0x83, 0x42, - 0x00, 0xd9, 0x01, 0x1c, 0xc9, 0xb2, 0x00, 0x2d, 0x0b, 0xd0, 0x02, 0x3b, - 0x9b, 0xb2, 0x1b, 0x02, 0x23, 0x80, 0x20, 0x00, 0xff, 0xf7, 0xa2, 0xff, - 0x70, 0xbd, 0x04, 0x23, 0xd0, 0x7c, 0x21, 0x1d, 0xdf, 0xe7, 0x01, 0x3b, - 0x23, 0x70, 0xf4, 0xe7, 0x78, 0x09, 0x00, 0x20, 0x94, 0x09, 0x00, 0x20, - 0x1c, 0x0a, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x00, 0x00, 0x25, 0x2a, 0x4b, - 0x85, 0xb0, 0x59, 0x7c, 0x03, 0xaa, 0xd1, 0x70, 0x99, 0x7c, 0x91, 0x70, - 0xd9, 0x7c, 0x51, 0x70, 0x19, 0x7d, 0x11, 0x70, 0x99, 0x7d, 0x02, 0xaa, - 0xd1, 0x70, 0xdb, 0x7d, 0x93, 0x70, 0x53, 0x88, 0x01, 0x93, 0x01, 0x9b, - 0xab, 0x42, 0x05, 0xd8, 0xff, 0xf7, 0x18, 0xff, 0xff, 0xf7, 0x5c, 0xff, - 0x05, 0xb0, 0xf0, 0xbd, 0xff, 0xf7, 0x48, 0xfa, 0x00, 0x28, 0xf9, 0xd0, - 0x03, 0x9b, 0x1b, 0x4f, 0xee, 0x18, 0x00, 0x2c, 0x1f, 0xd0, 0x39, 0x00, - 0x30, 0x00, 0xff, 0xf7, 0xf9, 0xfc, 0x80, 0x21, 0x04, 0x22, 0x38, 0x00, - 0x89, 0x00, 0xff, 0xf7, 0x1b, 0xfa, 0x15, 0x4a, 0x01, 0x35, 0x50, 0x7a, - 0x13, 0x7a, 0x91, 0x7a, 0x00, 0x02, 0x18, 0x43, 0xd3, 0x7a, 0x09, 0x04, - 0x08, 0x43, 0x1b, 0x06, 0x10, 0x49, 0x03, 0x43, 0x5b, 0x18, 0x19, 0x0a, - 0x13, 0x72, 0x51, 0x72, 0x19, 0x0c, 0x1b, 0x0e, 0x91, 0x72, 0xd3, 0x72, - 0xcd, 0xe7, 0x80, 0x21, 0x23, 0x00, 0x38, 0x00, 0x05, 0x22, 0x89, 0x00, - 0xff, 0xf7, 0xa3, 0xf9, 0x22, 0x00, 0x39, 0x00, 0x30, 0x00, 0x07, 0x4b, - 0xff, 0xf7, 0x84, 0xfd, 0xff, 0xf7, 0x7a, 0xf8, 0xd9, 0xe7, 0xc0, 0x46, - 0x94, 0x09, 0x00, 0x20, 0x78, 0x07, 0x00, 0x20, 0x9e, 0x01, 0x00, 0x20, - 0x00, 0xfe, 0xff, 0xff, 0xc8, 0x09, 0x00, 0x20, 0x7f, 0xb5, 0x00, 0xf0, - 0x2f, 0xfb, 0x44, 0x4e, 0x00, 0x22, 0x05, 0x21, 0x30, 0x00, 0xff, 0xf7, - 0xec, 0xfe, 0x00, 0x28, 0x49, 0xd0, 0x73, 0x7a, 0x32, 0x7a, 0xb5, 0x7a, - 0x1b, 0x02, 0x1a, 0x43, 0xf3, 0x7a, 0x2d, 0x04, 0x1b, 0x06, 0x15, 0x43, - 0x3c, 0x4c, 0x1d, 0x43, 0x2b, 0x0a, 0x63, 0x72, 0x2b, 0x0c, 0xa3, 0x72, - 0x2b, 0x0e, 0x25, 0x72, 0xe3, 0x72, 0xf0, 0x7b, 0x2f, 0x28, 0x27, 0xd8, - 0x19, 0x28, 0x15, 0xd8, 0x03, 0x28, 0x27, 0xd0, 0x12, 0x28, 0x2f, 0xd0, - 0x00, 0x28, 0x40, 0xd0, 0xff, 0xf7, 0x98, 0xfe, 0x01, 0x23, 0x05, 0x22, - 0x23, 0x73, 0x31, 0x4b, 0x9a, 0x70, 0x00, 0x22, 0xda, 0x70, 0x1a, 0x71, - 0x5a, 0x71, 0x9a, 0x71, 0x1a, 0x73, 0x20, 0x32, 0x5a, 0x73, 0x32, 0xe0, - 0x1a, 0x38, 0x15, 0x28, 0xec, 0xd8, 0x00, 0xf0, 0x1b, 0xfb, 0x28, 0x2c, - 0xeb, 0xeb, 0x2c, 0xeb, 0xeb, 0xeb, 0xeb, 0x3f, 0xeb, 0x31, 0xeb, 0xeb, - 0x39, 0xeb, 0x3d, 0xeb, 0xeb, 0xeb, 0xeb, 0x2c, 0x5a, 0x28, 0xdd, 0xd1, - 0x01, 0x20, 0x19, 0xe0, 0xf3, 0x7c, 0x19, 0x1c, 0x12, 0x2b, 0x00, 0xd9, - 0x12, 0x21, 0x1f, 0x48, 0xc9, 0xb2, 0xff, 0xf7, 0xdd, 0xfe, 0x7f, 0xbd, - 0x1d, 0x4c, 0x1e, 0x49, 0x20, 0x00, 0x18, 0x22, 0x08, 0x30, 0xff, 0xf7, - 0x55, 0xfc, 0xf3, 0x7c, 0x19, 0x1c, 0x24, 0x2b, 0x00, 0xd9, 0x24, 0x21, - 0x20, 0x00, 0xc9, 0xb2, 0xed, 0xe7, 0x00, 0x20, 0xff, 0xf7, 0xfe, 0xfe, - 0xeb, 0xe7, 0xff, 0xf7, 0x65, 0xfe, 0xff, 0xf7, 0xa9, 0xfe, 0xe6, 0xe7, - 0x80, 0x23, 0x13, 0x48, 0x9b, 0x02, 0x43, 0x60, 0x12, 0x4b, 0x08, 0x21, - 0x03, 0x60, 0xdc, 0xe7, 0x01, 0x20, 0xff, 0xf7, 0x25, 0xff, 0xda, 0xe7, - 0x00, 0x20, 0xfa, 0xe7, 0x0c, 0x26, 0x0e, 0x49, 0x32, 0x00, 0x01, 0xa8, - 0x00, 0xf0, 0xea, 0xfa, 0xb5, 0x42, 0x04, 0xd9, 0x00, 0x23, 0x26, 0x72, - 0x63, 0x72, 0xa3, 0x72, 0xe3, 0x72, 0x0c, 0x21, 0x01, 0xa8, 0xc6, 0xe7, - 0x94, 0x09, 0x00, 0x20, 0x9e, 0x01, 0x00, 0x20, 0xb3, 0x09, 0x00, 0x20, - 0xac, 0x01, 0x00, 0x20, 0x4f, 0x1b, 0x00, 0x00, 0x8c, 0x09, 0x00, 0x20, - 0x00, 0x00, 0x3e, 0x7f, 0xef, 0x1c, 0x00, 0x00, 0x72, 0xb6, 0xbf, 0xf3, - 0x5f, 0x8f, 0x82, 0x23, 0x03, 0x4a, 0xdb, 0x05, 0x9a, 0x82, 0x9a, 0x83, - 0x00, 0x22, 0x02, 0x4b, 0x9a, 0x60, 0x70, 0x47, 0xff, 0x03, 0x00, 0x00, - 0x00, 0xed, 0x00, 0xe0, 0xf0, 0xb5, 0xc5, 0xb0, 0x0d, 0xaf, 0x04, 0x00, - 0xff, 0xf7, 0xea, 0xff, 0x44, 0x22, 0x00, 0x21, 0x38, 0x00, 0x00, 0xf0, - 0xbe, 0xfa, 0x98, 0x22, 0x00, 0x21, 0x1e, 0xa8, 0x00, 0xf0, 0xb9, 0xfa, - 0x02, 0x23, 0x0f, 0x21, 0xbb, 0x70, 0xa3, 0x78, 0x62, 0x78, 0x0b, 0x40, - 0xa3, 0x70, 0x26, 0x4b, 0x0a, 0x40, 0x05, 0x93, 0x63, 0x68, 0x05, 0xad, - 0x06, 0x93, 0x00, 0x23, 0xe1, 0x68, 0x07, 0x93, 0x22, 0x48, 0x62, 0x70, - 0x2b, 0x73, 0x01, 0x22, 0x1e, 0xab, 0xff, 0xf7, 0xa3, 0xfc, 0x39, 0x00, - 0x20, 0x00, 0x1e, 0xaa, 0xff, 0xf7, 0x02, 0xfe, 0x28, 0x00, 0x01, 0x23, - 0x0d, 0x21, 0x62, 0x78, 0xff, 0xf7, 0xc2, 0xf8, 0x00, 0x25, 0x05, 0xae, - 0x3a, 0x00, 0x30, 0x00, 0xa1, 0x78, 0xff, 0xf7, 0x10, 0xfe, 0x00, 0x28, - 0x1e, 0xd0, 0x14, 0x4b, 0x01, 0xad, 0x01, 0x93, 0x06, 0x9b, 0x6b, 0x60, - 0x07, 0x9b, 0xab, 0x60, 0x00, 0x23, 0x2b, 0x73, 0xf3, 0x7b, 0x00, 0x2b, - 0xe4, 0xd0, 0x2a, 0x2b, 0x17, 0xd1, 0x6b, 0x46, 0xb2, 0x7d, 0x39, 0x00, - 0xda, 0x70, 0xf2, 0x7d, 0x20, 0x00, 0x9a, 0x70, 0x5e, 0x88, 0x1e, 0xaa, - 0xa6, 0x60, 0xff, 0xf7, 0xd9, 0xfd, 0xab, 0x68, 0x76, 0x02, 0x9e, 0x1b, - 0xae, 0x60, 0xd1, 0xe7, 0x06, 0x4b, 0x9d, 0x42, 0x01, 0xd9, 0xfe, 0xf7, - 0xd7, 0xfe, 0x01, 0x35, 0xd1, 0xe7, 0xfe, 0xf7, 0x07, 0xff, 0xc7, 0xe7, - 0x53, 0x42, 0x53, 0x55, 0xff, 0x0f, 0x00, 0x00, 0xf8, 0x24, 0x01, 0x00, - 0x30, 0xb5, 0xef, 0xf3, 0x08, 0x83, 0x05, 0x4c, 0x23, 0x60, 0x03, 0x68, - 0x83, 0xf3, 0x08, 0x88, 0x45, 0x68, 0xa8, 0x47, 0x23, 0x68, 0x83, 0xf3, - 0x08, 0x88, 0x30, 0xbd, 0xc0, 0x0a, 0x00, 0x20, 0x07, 0xb5, 0x01, 0x00, - 0x01, 0x22, 0x68, 0x46, 0xfe, 0xf7, 0x9a, 0xfe, 0x08, 0x21, 0x68, 0x46, - 0xff, 0xf7, 0x54, 0xfb, 0x07, 0xbd, 0x00, 0x00, 0xf8, 0xb5, 0x00, 0x23, - 0x7a, 0x22, 0x7f, 0x4c, 0x23, 0x60, 0x7f, 0x4b, 0x1a, 0x70, 0xff, 0xf7, - 0xc5, 0xfe, 0x7e, 0x4d, 0x40, 0x21, 0x28, 0x00, 0xff, 0xf7, 0x52, 0xfb, - 0x7c, 0x4b, 0x18, 0x60, 0x00, 0x23, 0x2b, 0x54, 0x98, 0x42, 0x01, 0xd0, - 0xfe, 0xf7, 0x26, 0xff, 0x00, 0x22, 0x79, 0x4b, 0x1d, 0x60, 0x79, 0x4b, - 0x1a, 0x60, 0x78, 0x48, 0x75, 0x4b, 0x02, 0x68, 0x1f, 0x68, 0xba, 0x42, - 0xe5, 0xd2, 0x74, 0x4e, 0x31, 0x68, 0x0b, 0x78, 0xff, 0x2b, 0x36, 0xd0, - 0x73, 0x4d, 0x23, 0x2b, 0x00, 0xd0, 0xb3, 0xe0, 0x6c, 0x4b, 0x1b, 0x78, - 0x53, 0x2b, 0x33, 0xd1, 0x2b, 0x68, 0x01, 0x32, 0x01, 0x31, 0x02, 0x60, - 0x31, 0x60, 0xba, 0x1a, 0x9a, 0x42, 0x00, 0xd9, 0x1a, 0x00, 0x6c, 0x4d, - 0x20, 0x68, 0x2a, 0x60, 0x00, 0xf0, 0xfe, 0xf9, 0x67, 0x48, 0x29, 0x68, - 0x03, 0x68, 0x65, 0x4a, 0xcb, 0x18, 0x01, 0x3b, 0x03, 0x60, 0x10, 0x68, - 0x4b, 0x1e, 0xc3, 0x18, 0x13, 0x60, 0x63, 0x4b, 0x64, 0x4d, 0x1b, 0x68, - 0x29, 0x70, 0xc9, 0xb2, 0x8b, 0x42, 0x03, 0xd9, 0x20, 0x68, 0x59, 0x1a, - 0xff, 0xf7, 0x1d, 0xfb, 0xc0, 0x46, 0x7a, 0x22, 0x57, 0x4b, 0x1a, 0x70, - 0x00, 0x22, 0x5b, 0x4b, 0x1a, 0x60, 0x58, 0x4a, 0x13, 0x68, 0x01, 0x33, - 0x13, 0x60, 0x57, 0x4a, 0x13, 0x68, 0x01, 0x33, 0x13, 0x60, 0xb8, 0xe7, - 0x52, 0x2b, 0x04, 0xd1, 0x29, 0x68, 0x20, 0x68, 0xff, 0xf7, 0xf1, 0xfa, - 0xe9, 0xe7, 0x4f, 0x2b, 0x03, 0xd1, 0x2b, 0x68, 0x22, 0x68, 0x13, 0x70, - 0xe3, 0xe7, 0x48, 0x2b, 0x03, 0xd1, 0x2b, 0x68, 0x22, 0x68, 0x13, 0x80, - 0xdd, 0xe7, 0x57, 0x2b, 0x0a, 0xd1, 0x4e, 0x4b, 0x22, 0x68, 0x9a, 0x42, - 0x02, 0xd1, 0x4d, 0x48, 0xfe, 0xf7, 0xdc, 0xfe, 0x23, 0x68, 0x2a, 0x68, - 0x1a, 0x60, 0xd0, 0xe7, 0x6f, 0x2b, 0x04, 0xd1, 0x01, 0x21, 0x20, 0x68, - 0xff, 0xf7, 0xca, 0xfa, 0xc9, 0xe7, 0x68, 0x2b, 0x05, 0xd1, 0x02, 0x21, - 0x23, 0x68, 0x1b, 0x88, 0x2b, 0x60, 0x28, 0x00, 0xf4, 0xe7, 0x77, 0x2b, - 0x04, 0xd1, 0x23, 0x68, 0x04, 0x21, 0x1b, 0x68, 0x2b, 0x60, 0xf6, 0xe7, - 0x47, 0x2b, 0x09, 0xd1, 0x28, 0x68, 0xff, 0xf7, 0x47, 0xff, 0x3d, 0x4b, - 0x1b, 0x78, 0x00, 0x2b, 0xb1, 0xd0, 0x01, 0x21, 0x3b, 0x48, 0xe1, 0xe7, - 0x54, 0x2b, 0xac, 0xd0, 0x4e, 0x2b, 0xaa, 0xd0, 0x56, 0x2b, 0x02, 0xd1, - 0x2a, 0x21, 0x38, 0x48, 0xd8, 0xe7, 0x58, 0x2b, 0x05, 0xd1, 0x28, 0x68, - 0xfe, 0xf7, 0x6c, 0xfc, 0x03, 0x21, 0x35, 0x48, 0xd0, 0xe7, 0x59, 0x2b, - 0x0d, 0xd1, 0x2a, 0x68, 0x20, 0x68, 0x33, 0x4b, 0x00, 0x2a, 0x03, 0xd1, - 0x18, 0x60, 0x03, 0x21, 0x31, 0x48, 0xc5, 0xe7, 0x19, 0x68, 0x92, 0x08, - 0xfe, 0xf7, 0x72, 0xfc, 0xf7, 0xe7, 0x5a, 0x2b, 0x8b, 0xd1, 0x2f, 0x68, - 0x00, 0x25, 0x26, 0x68, 0xf7, 0x19, 0xb7, 0x42, 0x09, 0xd1, 0x01, 0x21, - 0x2a, 0x48, 0xff, 0xf7, 0x81, 0xfa, 0x28, 0x00, 0xff, 0xf7, 0x20, 0xff, - 0x03, 0x21, 0x28, 0x48, 0xae, 0xe7, 0x29, 0x00, 0x30, 0x78, 0xfe, 0xf7, - 0x79, 0xfd, 0x01, 0x36, 0x05, 0x00, 0xec, 0xe7, 0x1a, 0x00, 0x30, 0x3a, - 0xd1, 0xb2, 0x09, 0x29, 0x04, 0xd8, 0x2b, 0x68, 0x1b, 0x01, 0x13, 0x43, - 0x2b, 0x60, 0x70, 0xe7, 0x1a, 0x00, 0x41, 0x3a, 0x05, 0x2a, 0x03, 0xd8, - 0x2a, 0x68, 0x37, 0x3b, 0x12, 0x01, 0xf4, 0xe7, 0x1a, 0x00, 0x61, 0x3a, - 0x05, 0x2a, 0x03, 0xd8, 0x2a, 0x68, 0x57, 0x3b, 0x12, 0x01, 0xec, 0xe7, - 0x2c, 0x2b, 0x03, 0xd1, 0x2b, 0x68, 0x23, 0x60, 0x00, 0x23, 0xe7, 0xe7, - 0x02, 0x4a, 0x13, 0x70, 0xfa, 0xe7, 0xc0, 0x46, 0xbc, 0x0a, 0x00, 0x20, - 0x61, 0x0a, 0x00, 0x20, 0x68, 0x0a, 0x00, 0x20, 0xb4, 0x0a, 0x00, 0x20, - 0xb8, 0x0a, 0x00, 0x20, 0xac, 0x0a, 0x00, 0x20, 0x64, 0x0a, 0x00, 0x20, - 0xc8, 0x0a, 0x00, 0x20, 0xb0, 0x0a, 0x00, 0x20, 0x0c, 0xed, 0x00, 0xe0, - 0x40, 0x00, 0x40, 0x00, 0x60, 0x0a, 0x00, 0x20, 0xfb, 0x1c, 0x00, 0x00, - 0x0b, 0x1d, 0x00, 0x00, 0xfd, 0x1c, 0x00, 0x00, 0xc4, 0x0a, 0x00, 0x20, - 0x01, 0x1d, 0x00, 0x00, 0x05, 0x1d, 0x00, 0x00, 0x07, 0x1d, 0x00, 0x00, - 0x03, 0x00, 0xf7, 0xb5, 0x47, 0x33, 0x04, 0x00, 0x1a, 0x78, 0x40, 0x21, - 0x03, 0x00, 0x00, 0x20, 0xfe, 0xf7, 0xb6, 0xfe, 0x00, 0x28, 0x01, 0xd1, - 0x00, 0x20, 0xfe, 0xbd, 0x00, 0x23, 0x23, 0x70, 0x23, 0x79, 0x01, 0x93, - 0x04, 0x23, 0xe3, 0x56, 0x00, 0x2b, 0xf5, 0xdb, 0x3f, 0x26, 0x20, 0x00, - 0x01, 0x9f, 0xa5, 0x1d, 0xeb, 0x8f, 0x37, 0x40, 0x48, 0x30, 0xc0, 0x18, - 0x3a, 0x00, 0x61, 0x1d, 0x00, 0xf0, 0xf0, 0xf8, 0xe8, 0x8f, 0x01, 0x9b, - 0xc0, 0x19, 0x80, 0xb2, 0xb3, 0x43, 0x01, 0xd1, 0xe8, 0x87, 0xe1, 0xe7, - 0x00, 0x23, 0xeb, 0x87, 0xdf, 0xe7, 0xf0, 0xb5, 0x06, 0x00, 0x0c, 0x00, - 0x1f, 0x00, 0x93, 0xb0, 0x01, 0x92, 0x3f, 0x25, 0xac, 0x42, 0x03, 0xdc, - 0x25, 0x00, 0x00, 0x2f, 0x00, 0xd1, 0x40, 0x37, 0x3b, 0x00, 0x02, 0xaa, - 0x2b, 0x43, 0x13, 0x70, 0x02, 0xab, 0x31, 0x00, 0x2a, 0x00, 0x58, 0x1c, - 0x00, 0xf0, 0xce, 0xf8, 0x6b, 0x46, 0x40, 0x21, 0x1a, 0x79, 0x02, 0xa8, - 0x01, 0x23, 0xfe, 0xf7, 0xfb, 0xfe, 0x76, 0x19, 0x64, 0x1b, 0xe4, 0xd1, - 0x13, 0xb0, 0xf0, 0xbd, 0x03, 0x00, 0x10, 0xb5, 0x47, 0x33, 0x1a, 0x78, - 0x04, 0x31, 0x00, 0x23, 0x48, 0x30, 0xff, 0xf7, 0xd4, 0xff, 0x10, 0xbd, - 0xf7, 0xb5, 0x04, 0x00, 0xff, 0xf7, 0xa2, 0xff, 0x00, 0x28, 0x42, 0xd0, - 0x23, 0x00, 0x48, 0x33, 0x9a, 0x88, 0xa0, 0x6c, 0x1a, 0x80, 0x00, 0x22, - 0x01, 0x38, 0x5a, 0x80, 0x08, 0x28, 0x65, 0xd8, 0x00, 0xf0, 0x9c, 0xf8, - 0x15, 0x05, 0x23, 0x27, 0x25, 0x2a, 0x48, 0x3f, 0x38, 0x00, 0x31, 0x4e, - 0x30, 0x00, 0x00, 0xf0, 0xae, 0xf8, 0x05, 0x00, 0x20, 0x00, 0x31, 0x00, - 0x2a, 0x00, 0x4c, 0x30, 0x00, 0xf0, 0x96, 0xf8, 0x29, 0x00, 0x20, 0x00, - 0xff, 0xf7, 0xd0, 0xff, 0x21, 0xe0, 0x01, 0x23, 0xe3, 0x64, 0xff, 0x33, - 0x23, 0x65, 0x80, 0x23, 0xdb, 0x00, 0x63, 0x65, 0xa0, 0x23, 0x5b, 0x00, - 0xa3, 0x65, 0x25, 0x4b, 0x14, 0x21, 0xe3, 0x65, 0xed, 0xe7, 0xfe, 0xf7, - 0xf7, 0xfc, 0x00, 0x21, 0xe9, 0xe7, 0xfe, 0xf7, 0x27, 0xfd, 0xfa, 0xe7, - 0x20, 0x00, 0x00, 0x21, 0xff, 0xf7, 0xb6, 0xff, 0x80, 0x23, 0x20, 0x6d, - 0x9b, 0x01, 0x98, 0x42, 0x03, 0xd3, 0x21, 0x00, 0x54, 0x31, 0xfe, 0xf7, - 0x95, 0xfb, 0xf7, 0xbd, 0x21, 0x00, 0x62, 0x6d, 0x20, 0x6d, 0x58, 0x31, - 0xfe, 0xf7, 0x59, 0xfb, 0xe5, 0xe7, 0x20, 0x00, 0x65, 0x6d, 0x21, 0x6d, - 0x2a, 0x00, 0x4c, 0x30, 0xfe, 0xf7, 0x51, 0xfb, 0xa9, 0x00, 0xc8, 0xe7, - 0x00, 0x26, 0x63, 0x6d, 0x27, 0x6d, 0x01, 0x93, 0x01, 0x9b, 0xb3, 0x42, - 0x01, 0xdc, 0x59, 0x00, 0xbf, 0xe7, 0x3d, 0x00, 0x00, 0x21, 0x2b, 0x00, - 0x18, 0x78, 0xfe, 0xf7, 0x69, 0xfc, 0x7b, 0x1c, 0x01, 0x35, 0xff, 0x33, - 0x01, 0x00, 0x9d, 0x42, 0xf5, 0xd1, 0x23, 0x00, 0x72, 0x00, 0x4c, 0x33, - 0x2f, 0x00, 0x98, 0x52, 0x01, 0x36, 0xe7, 0xe7, 0x01, 0x22, 0x5a, 0x80, - 0xbd, 0xe7, 0xc0, 0x46, 0x94, 0x1c, 0x00, 0x00, 0x2f, 0x47, 0x29, 0x2c, - 0x07, 0x48, 0x06, 0x22, 0x03, 0x00, 0x10, 0xb5, 0x47, 0x33, 0x1a, 0x70, - 0xff, 0xf7, 0x7a, 0xff, 0x04, 0x48, 0x07, 0x22, 0x03, 0x00, 0x47, 0x33, - 0x1a, 0x70, 0xff, 0xf7, 0x73, 0xff, 0x10, 0xbd, 0xcc, 0x0a, 0x00, 0x20, - 0x54, 0x0c, 0x00, 0x20, 0x10, 0xb5, 0xe2, 0xb0, 0x04, 0x00, 0xff, 0xf7, - 0x51, 0xfd, 0xc4, 0x22, 0x00, 0x21, 0x68, 0x46, 0x52, 0x00, 0x00, 0xf0, - 0x24, 0xf8, 0x47, 0x23, 0x6b, 0x44, 0x1c, 0x70, 0x68, 0x46, 0xff, 0xf7, - 0x5d, 0xff, 0xfb, 0xe7, 0x02, 0xb4, 0x71, 0x46, 0x49, 0x08, 0x49, 0x00, - 0x09, 0x56, 0x49, 0x00, 0x8e, 0x44, 0x02, 0xbc, 0x70, 0x47, 0xc0, 0x46, - 0x02, 0xb4, 0x71, 0x46, 0x49, 0x08, 0x49, 0x00, 0x09, 0x5c, 0x49, 0x00, - 0x8e, 0x44, 0x02, 0xbc, 0x70, 0x47, 0xc0, 0x46, 0x00, 0x23, 0x10, 0xb5, - 0x9a, 0x42, 0x00, 0xd1, 0x10, 0xbd, 0xcc, 0x5c, 0xc4, 0x54, 0x01, 0x33, - 0xf8, 0xe7, 0x03, 0x00, 0x82, 0x18, 0x93, 0x42, 0x00, 0xd1, 0x70, 0x47, - 0x19, 0x70, 0x01, 0x33, 0xf9, 0xe7, 0x00, 0x23, 0xc2, 0x5c, 0x01, 0x33, - 0x00, 0x2a, 0xfb, 0xd1, 0x58, 0x1e, 0x70, 0x47, 0x4f, 0x64, 0x64, 0x6c, - 0x79, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x53, 0x65, 0x6e, 0x73, 0x6f, - 0x72, 0x20, 0x57, 0x61, 0x74, 0x63, 0x68, 0x20, 0x4d, 0x30, 0x00, 0x00, - 0x0c, 0xa0, 0x80, 0x00, 0x40, 0xa0, 0x80, 0x00, 0x44, 0xa0, 0x80, 0x00, - 0x48, 0xa0, 0x80, 0x00, 0x12, 0x01, 0x10, 0x02, 0xef, 0x02, 0x01, 0x40, - 0x09, 0x12, 0x50, 0x21, 0x01, 0x42, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, - 0x06, 0x97, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x15, 0x00, 0x26, 0xff, 0x00, - 0x75, 0x08, 0x95, 0x40, 0x09, 0x01, 0x81, 0x02, 0x95, 0x40, 0x09, 0x01, - 0x91, 0x02, 0x95, 0x01, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x1b, 0x00, 0x00, 0x4f, 0x1b, 0x00, 0x00, - 0x50, 0x06, 0x00, 0x20, 0xeb, 0x3c, 0x90, 0x55, 0x46, 0x32, 0x20, 0x55, - 0x46, 0x32, 0x20, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x40, 0x00, 0x7e, - 0x3e, 0xf8, 0x3f, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x42, 0x00, 0x42, 0x00, 0x57, - 0x41, 0x54, 0x43, 0x48, 0x42, 0x4f, 0x4f, 0x54, 0x00, 0x00, 0x46, 0x41, - 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, 0x3c, 0x21, 0x64, 0x6f, 0x63, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x3c, 0x68, - 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, - 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x64, 0x64, 0x6c, - 0x79, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2e, 0x6f, 0x72, - 0x67, 0x2f, 0x22, 0x29, 0x3b, 0x0a, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, - 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x00, 0x00, 0x49, 0x4e, 0x46, 0x4f, - 0x5f, 0x55, 0x46, 0x32, 0x54, 0x58, 0x54, 0x00, 0x94, 0x1c, 0x00, 0x00, - 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4d, 0x00, - 0xf6, 0x1b, 0x00, 0x00, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x20, - 0x55, 0x46, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x46, 0x32, 0x20, - 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x20, 0x76, - 0x33, 0x2e, 0x37, 0x2e, 0x30, 0x2d, 0x31, 0x37, 0x30, 0x2d, 0x67, 0x66, - 0x39, 0x32, 0x65, 0x37, 0x64, 0x63, 0x20, 0x53, 0x46, 0x48, 0x57, 0x52, - 0x4f, 0x0d, 0x0a, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x3a, 0x20, 0x53, 0x65, - 0x6e, 0x73, 0x6f, 0x72, 0x20, 0x57, 0x61, 0x74, 0x63, 0x68, 0x20, 0x4d, - 0x30, 0x0d, 0x0a, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x2d, 0x49, 0x44, 0x3a, - 0x20, 0x4f, 0x53, 0x4f, 0x2d, 0x53, 0x57, 0x41, 0x54, 0x2d, 0x41, 0x31, - 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x3e, 0x80, 0x02, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x58, 0x0a, 0x0d, 0x00, 0x59, 0x0a, 0x0d, - 0x00, 0x5a, 0x00, 0x23, 0x0a, 0x0d, 0x00, 0x76, 0x31, 0x2e, 0x31, 0x20, - 0x5b, 0x41, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x3a, 0x58, 0x59, 0x5a, - 0x5d, 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x31, 0x31, 0x20, 0x32, 0x30, 0x32, - 0x31, 0x20, 0x30, 0x36, 0x3a, 0x33, 0x37, 0x3a, 0x30, 0x35, 0x0a, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, - 0x05, 0x0f, 0x39, 0x00, 0x02, 0x18, 0x10, 0x05, 0x00, 0x38, 0xb6, 0x08, - 0x34, 0xa9, 0x09, 0xa0, 0x47, 0x8b, 0xfd, 0xa0, 0x76, 0x88, 0x15, 0xb6, - 0x65, 0x00, 0x01, 0x01, 0x00, 0x1c, 0x10, 0x05, 0x00, 0xdf, 0x60, 0xdd, - 0xd8, 0x89, 0x45, 0xc7, 0x4c, 0x9c, 0xd2, 0x65, 0x9d, 0x9e, 0x64, 0x8a, - 0x9f, 0x00, 0x00, 0x03, 0x06, 0xaa, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x02, 0x99, 0x00, 0x05, 0x01, 0x00, 0x80, 0xfa, 0x08, 0x0b, 0x00, - 0x02, 0x02, 0x02, 0x01, 0x00, 0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, - 0x01, 0x00, 0x05, 0x24, 0x00, 0x10, 0x01, 0x04, 0x24, 0x02, 0x06, 0x05, - 0x24, 0x06, 0x00, 0x01, 0x05, 0x24, 0x01, 0x03, 0x01, 0x07, 0x05, 0x83, - 0x03, 0x08, 0x00, 0xff, 0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, - 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, - 0x40, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00, 0x02, 0x08, 0x06, 0x50, 0x00, - 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, - 0x00, 0x00, 0x09, 0x04, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x09, - 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, 0x21, 0x00, 0x07, 0x05, 0x86, 0x03, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x06, 0x03, 0x40, 0x00, 0x01, 0x09, 0x04, - 0x04, 0x00, 0x02, 0xff, 0x2a, 0x01, 0x00, 0x07, 0x05, 0x87, 0x03, 0x40, - 0x00, 0x01, 0x07, 0x05, 0x07, 0x03, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x09, 0x04, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x06, 0xaa, 0x00, 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, - 0xa0, 0x00, 0x14, 0x00, 0x03, 0x00, 0x57, 0x49, 0x4e, 0x55, 0x53, 0x42, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, - 0x04, 0x00, 0x07, 0x00, 0x2a, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, - 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, - 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, - 0x47, 0x00, 0x55, 0x00, 0x49, 0x00, 0x44, 0x00, 0x73, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x7b, 0x00, 0x39, 0x00, 0x32, 0x00, 0x43, 0x00, 0x45, 0x00, - 0x36, 0x00, 0x34, 0x00, 0x36, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x39, 0x00, - 0x43, 0x00, 0x37, 0x00, 0x37, 0x00, 0x2d, 0x00, 0x34, 0x00, 0x36, 0x00, - 0x46, 0x00, 0x45, 0x00, 0x2d, 0x00, 0x39, 0x00, 0x33, 0x00, 0x33, 0x00, - 0x42, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x31, 0x00, 0x43, 0x00, 0x42, 0x00, - 0x39, 0x00, 0x43, 0x00, 0x35, 0x00, 0x42, 0x00, 0x42, 0x00, 0x33, 0x00, - 0x42, 0x00, 0x39, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x42, - 0x53, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd4, 0x20, 0x84, 0x46, 0x9c, 0x44, 0x60, 0x46, 0x06, 0x68, 0x0e, 0x40, + 0x16, 0x43, 0x06, 0x60, 0xf0, 0x26, 0x80, 0x20, 0x76, 0x00, 0xa7, 0x55, + 0x04, 0x36, 0xa5, 0x55, 0xa0, 0x55, 0x1c, 0x00, 0xe4, 0x34, 0x20, 0x68, + 0xf4, 0x33, 0x08, 0x40, 0x10, 0x43, 0x20, 0x60, 0x18, 0x68, 0x01, 0x40, + 0x0a, 0x43, 0x1a, 0x60, 0x06, 0xe7, 0x35, 0x48, 0x83, 0x42, 0x00, 0xd1, + 0x24, 0xe1, 0x0a, 0xdc, 0x33, 0x49, 0x8b, 0x42, 0x00, 0xd1, 0x3a, 0xe7, + 0x32, 0x49, 0x33, 0x48, 0x0b, 0x40, 0x83, 0x42, 0x00, 0xd1, 0x34, 0xe7, + 0x28, 0xe7, 0x31, 0x49, 0x8b, 0x42, 0x00, 0xd1, 0x2f, 0xe7, 0x30, 0x49, + 0x8b, 0x42, 0x00, 0xd0, 0x20, 0xe7, 0x00, 0x23, 0x08, 0xa8, 0x03, 0x80, + 0x01, 0x21, 0x05, 0xe0, 0x80, 0x23, 0x5b, 0x00, 0x9f, 0x42, 0x04, 0xd1, + 0x12, 0x21, 0x2a, 0x48, 0xff, 0xf7, 0x96, 0xfe, 0xe0, 0xe6, 0x80, 0x23, + 0x9b, 0x00, 0x9f, 0x42, 0x02, 0xd1, 0x99, 0x21, 0x26, 0x48, 0xf5, 0xe7, + 0x01, 0x9b, 0x03, 0x2b, 0x75, 0xd1, 0x02, 0x9b, 0x03, 0x2b, 0x00, 0xd9, + 0x04, 0xe7, 0x08, 0xac, 0x48, 0x22, 0x00, 0x21, 0x20, 0x00, 0x01, 0xf0, + 0x06, 0xf8, 0x01, 0x9b, 0x63, 0x70, 0x02, 0x9b, 0x00, 0x2b, 0x3b, 0xd1, + 0x09, 0x22, 0x04, 0x33, 0x23, 0x70, 0xa2, 0x70, 0xe3, 0x70, 0x20, 0x00, + 0x21, 0x78, 0xdb, 0xe7, 0xff, 0x00, 0x00, 0x41, 0x74, 0x06, 0x00, 0x20, + 0xff, 0xff, 0xff, 0x8f, 0xe8, 0x03, 0x00, 0x20, 0x34, 0x04, 0x00, 0x20, + 0xff, 0x3f, 0x00, 0xf0, 0x2c, 0x04, 0x00, 0x20, 0x74, 0x07, 0x00, 0x20, + 0x02, 0x03, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x21, 0x09, 0x00, 0x00, 0x81, 0x06, 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, + 0xbc, 0x04, 0x00, 0x20, 0x78, 0x04, 0x00, 0x20, 0x88, 0x05, 0x00, 0x20, + 0x44, 0x05, 0x00, 0x20, 0xa1, 0x21, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, + 0xff, 0xfe, 0xff, 0xff, 0x21, 0x0a, 0x00, 0x00, 0x21, 0x22, 0x00, 0x00, + 0xa1, 0xfe, 0x00, 0x00, 0x80, 0x1b, 0x00, 0x00, 0x44, 0x00, 0x00, 0x20, + 0x04, 0xae, 0x32, 0x00, 0x56, 0x4b, 0x23, 0xcb, 0x23, 0xc2, 0x00, 0x25, + 0x2f, 0x00, 0x1b, 0x68, 0x13, 0x60, 0xab, 0x00, 0x53, 0x4a, 0xf3, 0x58, + 0xd0, 0x19, 0x19, 0x68, 0x01, 0x22, 0xff, 0xf7, 0xfd, 0xfb, 0x01, 0x35, + 0x3f, 0x18, 0x04, 0x2d, 0xf3, 0xd1, 0x00, 0x23, 0x4d, 0x4a, 0xd3, 0x55, + 0x4d, 0x4b, 0x4e, 0x4a, 0x9b, 0x79, 0x9b, 0x00, 0x9d, 0x58, 0x28, 0x00, + 0x00, 0xf0, 0xad, 0xff, 0x23, 0x00, 0x01, 0x30, 0x40, 0x00, 0x20, 0x70, + 0x2a, 0x78, 0x02, 0x33, 0x01, 0x35, 0x00, 0x2a, 0x9f, 0xd0, 0x1a, 0x70, + 0xf8, 0xe7, 0x01, 0x9b, 0x0f, 0x2b, 0x02, 0xd1, 0x39, 0x21, 0x44, 0x48, + 0x76, 0xe7, 0x01, 0x9b, 0x21, 0x2b, 0x02, 0xd1, 0x09, 0x21, 0x42, 0x48, + 0x70, 0xe7, 0x01, 0x9b, 0x22, 0x2b, 0x00, 0xd0, 0x82, 0xe6, 0x21, 0x21, + 0x3f, 0x48, 0x69, 0xe7, 0x07, 0x28, 0x00, 0xd0, 0x7c, 0xe6, 0xaa, 0x21, + 0x3d, 0x48, 0x63, 0xe7, 0x03, 0x9b, 0x08, 0xa8, 0x02, 0x21, 0x03, 0x80, + 0x5e, 0xe7, 0x08, 0x42, 0x00, 0xd0, 0x71, 0xe6, 0x0f, 0x23, 0x50, 0x22, + 0x03, 0x40, 0x08, 0x33, 0x5b, 0x01, 0x10, 0x42, 0x07, 0xd0, 0x82, 0x22, + 0xd2, 0x05, 0x9b, 0x18, 0x9b, 0x79, 0x9b, 0x06, 0xdb, 0x0f, 0x08, 0xa8, + 0xea, 0xe7, 0x82, 0x22, 0xd2, 0x05, 0x9b, 0x18, 0x9b, 0x79, 0xdb, 0x06, + 0xf6, 0xe7, 0x0f, 0x24, 0x03, 0x00, 0x23, 0x40, 0x20, 0x42, 0x00, 0xd1, + 0x56, 0xe6, 0x01, 0x40, 0x39, 0x43, 0x00, 0xd0, 0x52, 0xe6, 0x82, 0x22, + 0x08, 0x33, 0x5b, 0x01, 0xd2, 0x05, 0x9b, 0x18, 0x02, 0x06, 0x02, 0xd5, + 0x20, 0x22, 0x5a, 0x71, 0x53, 0xe6, 0x10, 0x22, 0xfb, 0xe7, 0x0f, 0x24, + 0x03, 0x00, 0x23, 0x40, 0x20, 0x42, 0x00, 0xd1, 0x40, 0xe6, 0x01, 0x40, + 0x39, 0x43, 0x00, 0xd0, 0x3c, 0xe6, 0x5b, 0x01, 0x02, 0x06, 0x14, 0xd5, + 0x82, 0x22, 0x1d, 0x49, 0xd2, 0x05, 0x9a, 0x18, 0x5b, 0x18, 0x20, 0x21, + 0xd8, 0x79, 0x08, 0x42, 0x00, 0xd1, 0x3a, 0xe6, 0x59, 0x71, 0x1b, 0x7a, + 0x2b, 0x42, 0x00, 0xd1, 0x35, 0xe6, 0x13, 0x00, 0x40, 0x22, 0xff, 0x33, + 0x1a, 0x72, 0x3e, 0x3a, 0xd9, 0xe7, 0x82, 0x22, 0x10, 0x20, 0x12, 0x49, + 0xd2, 0x05, 0x9a, 0x18, 0x5b, 0x18, 0xd9, 0x79, 0x01, 0x42, 0x00, 0xd1, + 0x25, 0xe6, 0x58, 0x71, 0x1b, 0x7a, 0x01, 0x18, 0x0b, 0x42, 0x00, 0xd1, + 0x1f, 0xe6, 0x13, 0x00, 0xff, 0x33, 0x01, 0x22, 0x19, 0x72, 0xc4, 0xe7, + 0x09, 0x48, 0xf7, 0xe6, 0x70, 0x1b, 0x00, 0x00, 0x50, 0x06, 0x00, 0x20, + 0xe8, 0x03, 0x00, 0x20, 0xb8, 0x1b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, + 0xe0, 0x00, 0x00, 0x20, 0x94, 0x1b, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x20, + 0xff, 0x00, 0x00, 0x41, 0xec, 0x00, 0x00, 0x20, 0x10, 0xb5, 0xff, 0xf7, + 0x17, 0xfc, 0x00, 0x22, 0x04, 0x4b, 0x1a, 0x70, 0x82, 0x22, 0x02, 0x23, + 0xd2, 0x05, 0x11, 0x78, 0x0b, 0x43, 0x13, 0x70, 0x10, 0xbd, 0xc0, 0x46, + 0x2c, 0x04, 0x00, 0x20, 0x10, 0xb5, 0x0c, 0x00, 0x01, 0x22, 0xff, 0xf7, + 0x61, 0xfd, 0x20, 0x00, 0x10, 0xbd, 0x10, 0xb5, 0x0c, 0x00, 0x01, 0x22, + 0xff, 0xf7, 0x5a, 0xfd, 0x20, 0x00, 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x00, + 0x0d, 0x00, 0xff, 0xf7, 0x6f, 0xfd, 0x03, 0x00, 0x00, 0x20, 0x83, 0x42, + 0x04, 0xd0, 0x02, 0x22, 0x29, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xea, 0xfc, + 0x70, 0xbd, 0x70, 0xb5, 0x05, 0x00, 0x0c, 0x00, 0xff, 0xf7, 0x60, 0xfd, + 0x00, 0x28, 0x07, 0xd0, 0x00, 0x23, 0x02, 0x22, 0x21, 0x00, 0x28, 0x00, + 0xff, 0xf7, 0xe1, 0xfc, 0x20, 0x00, 0x70, 0xbd, 0x04, 0x00, 0xfb, 0xe7, + 0x30, 0xb5, 0x00, 0x23, 0x20, 0x25, 0x93, 0x42, 0x00, 0xdb, 0x30, 0xbd, + 0x0c, 0x78, 0x00, 0x2c, 0x03, 0xd0, 0x01, 0x31, 0xc4, 0x54, 0x01, 0x33, + 0xf5, 0xe7, 0x2c, 0x00, 0xfa, 0xe7, 0x00, 0x00, 0xf8, 0xb5, 0x80, 0x22, + 0x0c, 0x00, 0x05, 0x00, 0x00, 0x21, 0x20, 0x00, 0x92, 0x00, 0x00, 0xf0, + 0xaa, 0xfe, 0x00, 0x2d, 0x0c, 0xd1, 0x3e, 0x22, 0x20, 0x00, 0x4a, 0x49, + 0x00, 0xf0, 0x9a, 0xfe, 0xff, 0x23, 0x55, 0x22, 0x5b, 0x00, 0xe2, 0x54, + 0x47, 0x4b, 0x92, 0x18, 0xe2, 0x54, 0xf8, 0xbd, 0x7e, 0x2d, 0x23, 0xd8, + 0x6e, 0x1e, 0x3e, 0x2e, 0x01, 0xd9, 0x40, 0x3d, 0x2e, 0x00, 0x00, 0x2e, + 0x12, 0xd0, 0x80, 0x25, 0x33, 0x02, 0x58, 0x1c, 0x40, 0x4e, 0xff, 0x30, + 0xed, 0x00, 0x1a, 0x1f, 0x59, 0x1c, 0xaa, 0x42, 0x03, 0xd2, 0xb3, 0x42, + 0x0e, 0xd0, 0x8b, 0xb2, 0x23, 0x80, 0x0b, 0x00, 0x02, 0x34, 0x81, 0x42, + 0xf3, 0xd1, 0xe2, 0xe7, 0xf0, 0x23, 0x09, 0x22, 0xff, 0x21, 0x23, 0x70, + 0x60, 0x1c, 0x00, 0xf0, 0x78, 0xfe, 0xe4, 0xe7, 0x35, 0x4b, 0xef, 0xe7, + 0x82, 0x2d, 0x31, 0xd8, 0x7f, 0x2d, 0xd4, 0xd1, 0x2f, 0x49, 0x0b, 0x22, + 0x20, 0x00, 0x2b, 0x31, 0xff, 0xf7, 0xa8, 0xff, 0x80, 0x27, 0x28, 0x23, + 0x2f, 0x4e, 0xe3, 0x72, 0x7d, 0x3d, 0x3f, 0x03, 0xf0, 0x68, 0x3b, 0x00, + 0x20, 0x34, 0x00, 0x28, 0x02, 0xd0, 0x00, 0xf0, 0x66, 0xfe, 0x03, 0x00, + 0x1a, 0x0a, 0x23, 0x77, 0x62, 0x77, 0x1a, 0x0c, 0x1b, 0x0e, 0xe3, 0x77, + 0x2b, 0x0a, 0x31, 0x00, 0xa2, 0x77, 0xa5, 0x76, 0x0b, 0x22, 0xe3, 0x76, + 0x20, 0x00, 0xff, 0xf7, 0x8b, 0xff, 0x67, 0x22, 0x4d, 0x23, 0x01, 0x35, + 0x52, 0x42, 0xad, 0xb2, 0x22, 0x74, 0x63, 0x74, 0x22, 0x76, 0x63, 0x76, + 0x10, 0x36, 0x05, 0x2d, 0xdc, 0xd1, 0xa4, 0xe7, 0x2b, 0x00, 0x83, 0x3b, + 0x01, 0x2b, 0x0c, 0xd8, 0x19, 0x4a, 0x1b, 0x01, 0xd3, 0x18, 0xdd, 0x68, + 0x28, 0x00, 0x00, 0xf0, 0x3e, 0xfe, 0x29, 0x00, 0x02, 0x00, 0x20, 0x00, + 0x00, 0xf0, 0x28, 0xfe, 0x93, 0xe7, 0x80, 0x23, 0x85, 0x3d, 0x29, 0x02, + 0xdb, 0x02, 0x99, 0x42, 0x00, 0xd3, 0x8c, 0xe7, 0x10, 0x4b, 0x11, 0x4a, + 0x23, 0x60, 0x11, 0x4b, 0x20, 0x00, 0x63, 0x60, 0xfe, 0x23, 0x5b, 0x00, + 0xe2, 0x50, 0x80, 0x23, 0xdb, 0x00, 0xa3, 0x61, 0x80, 0x23, 0x80, 0x22, + 0x9b, 0x01, 0xa3, 0x60, 0x0b, 0x4b, 0x52, 0x00, 0x65, 0x61, 0xe1, 0x60, + 0x22, 0x61, 0xe3, 0x61, 0x20, 0x30, 0xdd, 0xe7, 0xc8, 0x1b, 0x00, 0x00, + 0xff, 0x01, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x74, 0x1c, 0x00, 0x00, 0x55, 0x46, 0x32, 0x0a, 0x30, 0x6f, 0xb1, 0x0a, + 0x57, 0x51, 0x5d, 0x9e, 0x2f, 0x47, 0x29, 0x2c, 0x70, 0xb5, 0x16, 0x00, + 0x1d, 0x00, 0x0a, 0x68, 0x2f, 0x4b, 0x0c, 0x00, 0x9a, 0x42, 0x52, 0xd1, + 0x2e, 0x4b, 0x4a, 0x68, 0x9a, 0x42, 0x4e, 0xd1, 0xfe, 0x22, 0x52, 0x00, + 0x2c, 0x4b, 0x8a, 0x58, 0x9a, 0x42, 0x48, 0xd1, 0x8b, 0x68, 0x9a, 0x04, + 0x03, 0xd5, 0x2a, 0x4a, 0xc9, 0x69, 0x91, 0x42, 0x41, 0xd1, 0xdb, 0x07, + 0x12, 0xd4, 0x80, 0x23, 0x22, 0x69, 0x5b, 0x00, 0x9a, 0x42, 0x0d, 0xd1, + 0xe0, 0x68, 0xc3, 0xb2, 0x00, 0x2b, 0x09, 0xd1, 0xf8, 0x22, 0x23, 0x4b, + 0x92, 0x02, 0xc3, 0x18, 0x93, 0x42, 0x03, 0xd2, 0x21, 0x00, 0x20, 0x31, + 0xff, 0xf7, 0xe6, 0xf8, 0x00, 0x2d, 0x2b, 0xd0, 0xa3, 0x69, 0x00, 0x2b, + 0x28, 0xd0, 0x29, 0x68, 0x1c, 0x4a, 0x8b, 0x42, 0x06, 0xd0, 0x93, 0x42, + 0x01, 0xd8, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x23, 0x5b, 0x42, 0x2b, 0x60, + 0x63, 0x69, 0x93, 0x42, 0x19, 0xd8, 0x07, 0x22, 0x01, 0x21, 0x1a, 0x40, + 0x91, 0x40, 0xdb, 0x08, 0xeb, 0x18, 0x1a, 0x7a, 0xc8, 0xb2, 0x11, 0x42, + 0x04, 0xd1, 0x69, 0x68, 0x02, 0x43, 0x01, 0x31, 0x1a, 0x72, 0x69, 0x60, + 0x6a, 0x68, 0x2b, 0x68, 0x9a, 0x42, 0x06, 0xd3, 0x00, 0x2e, 0x04, 0xd1, + 0x0c, 0x4b, 0x1b, 0x68, 0x1e, 0x33, 0x0c, 0x4a, 0x13, 0x60, 0x70, 0xbd, + 0x00, 0x2e, 0xfc, 0xd1, 0x08, 0x4b, 0x1b, 0x68, 0x2d, 0x33, 0xff, 0x33, + 0xf5, 0xe7, 0xc0, 0x46, 0x55, 0x46, 0x32, 0x0a, 0x57, 0x51, 0x5d, 0x9e, + 0x30, 0x6f, 0xb1, 0x0a, 0x2f, 0x47, 0x29, 0x2c, 0x00, 0xe0, 0xff, 0xff, + 0x63, 0x04, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x20, 0xd8, 0x03, 0x00, 0x20, + 0xf8, 0xb5, 0x5a, 0x4e, 0xb2, 0x68, 0x00, 0x2a, 0x00, 0xd0, 0xfe, 0xe7, + 0x58, 0x4b, 0x1a, 0x70, 0x9a, 0x68, 0x00, 0x2a, 0xfc, 0xd1, 0x57, 0x4c, + 0x02, 0x32, 0x23, 0x69, 0x93, 0x43, 0x23, 0x61, 0xe3, 0x68, 0x5b, 0x07, + 0xfc, 0xd5, 0x23, 0x69, 0x53, 0x4a, 0x1a, 0x40, 0x80, 0x23, 0x1b, 0x03, + 0x13, 0x43, 0x18, 0x22, 0x23, 0x61, 0x23, 0x69, 0x93, 0x43, 0x23, 0x61, + 0x02, 0x23, 0x22, 0x69, 0x13, 0x43, 0x23, 0x61, 0xe3, 0x68, 0xdb, 0x07, + 0xfc, 0xd5, 0xe3, 0x68, 0x9b, 0x07, 0xfc, 0xd4, 0x4a, 0x4d, 0x2b, 0x78, + 0xdb, 0x07, 0x02, 0xd4, 0x2b, 0x78, 0x5b, 0x07, 0x05, 0xd5, 0x64, 0x20, + 0xff, 0xf7, 0x8e, 0xf9, 0xe3, 0x68, 0x9b, 0x07, 0xf9, 0xd4, 0x02, 0x22, + 0x23, 0x69, 0x93, 0x43, 0x23, 0x61, 0xe3, 0x68, 0x5b, 0x07, 0xfc, 0xd5, + 0x18, 0x22, 0x23, 0x69, 0x93, 0x43, 0x1a, 0x00, 0x08, 0x23, 0x13, 0x43, + 0x23, 0x61, 0x02, 0x23, 0x22, 0x69, 0x13, 0x43, 0x23, 0x61, 0xff, 0xf7, + 0x51, 0xfa, 0x3b, 0x4b, 0x1f, 0x68, 0x3b, 0x4b, 0xfa, 0x18, 0xf8, 0x23, + 0x9b, 0x02, 0x9a, 0x42, 0x12, 0xd8, 0x39, 0x4a, 0x39, 0x4b, 0x12, 0x68, + 0x39, 0x4c, 0x9a, 0x42, 0x32, 0xd1, 0x2a, 0x78, 0x38, 0x4b, 0xd2, 0x07, + 0x02, 0xd4, 0x22, 0x68, 0x9a, 0x42, 0x2b, 0xd0, 0x23, 0x60, 0x36, 0x4b, + 0x36, 0x4a, 0x1b, 0x68, 0x32, 0x33, 0x13, 0x60, 0xff, 0xf7, 0x52, 0xf8, + 0xbf, 0xf3, 0x5f, 0x8f, 0x62, 0xb6, 0xff, 0xf7, 0x1f, 0xfe, 0x40, 0x20, + 0xff, 0xf7, 0x34, 0xfa, 0x80, 0x27, 0x0a, 0x23, 0x01, 0x26, 0x2f, 0x4d, + 0xff, 0x01, 0x2b, 0x70, 0xff, 0xf7, 0xa6, 0xfb, 0x2d, 0x4c, 0x00, 0x28, + 0x0a, 0xd0, 0x23, 0x78, 0xda, 0xb2, 0x00, 0x2b, 0x05, 0xd1, 0x28, 0x4b, + 0x38, 0x00, 0x1a, 0x60, 0xff, 0xf7, 0x20, 0xfa, 0x2e, 0x70, 0x26, 0x70, + 0x23, 0x78, 0x00, 0x2b, 0x25, 0xd0, 0x00, 0xf0, 0xbf, 0xfa, 0xfc, 0xe7, + 0x2b, 0x78, 0xdb, 0x07, 0xda, 0x0f, 0x00, 0x2b, 0x0d, 0xd0, 0x00, 0x23, + 0x80, 0x22, 0x23, 0x60, 0x20, 0x4b, 0x52, 0x03, 0x5a, 0x61, 0x80, 0x23, + 0x9b, 0x01, 0x1a, 0x68, 0x82, 0xf3, 0x08, 0x88, 0xb3, 0x60, 0x38, 0x47, + 0xc6, 0xe7, 0x21, 0x68, 0x1b, 0x4b, 0x99, 0x42, 0x01, 0xd1, 0x22, 0x60, + 0xc0, 0xe7, 0x21, 0x68, 0x12, 0x4a, 0x91, 0x42, 0xe7, 0xd0, 0xfa, 0x20, + 0x23, 0x60, 0x40, 0x00, 0xff, 0xf7, 0x14, 0xf9, 0xe1, 0xe7, 0x23, 0x78, + 0x00, 0x2b, 0xc3, 0xd1, 0xff, 0x33, 0xc0, 0x46, 0x01, 0x3b, 0x00, 0x2b, + 0xfb, 0xd1, 0xbd, 0xe7, 0x00, 0xed, 0x00, 0xe0, 0x00, 0x20, 0x00, 0x40, + 0x00, 0x18, 0x00, 0x40, 0xff, 0xff, 0xc0, 0xff, 0x00, 0x0c, 0x00, 0x40, + 0x04, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xa8, 0x20, 0x00, 0x00, + 0x7c, 0xb0, 0xee, 0x87, 0xfc, 0x7f, 0x00, 0x20, 0xef, 0x69, 0x26, 0xf0, + 0xe0, 0x03, 0x00, 0x20, 0xd8, 0x03, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, + 0x76, 0x07, 0x00, 0x20, 0x00, 0x60, 0x00, 0x41, 0xef, 0x69, 0x16, 0xf0, + 0x10, 0xb5, 0x05, 0x4c, 0x12, 0x22, 0x00, 0x21, 0x20, 0x00, 0x00, 0xf0, + 0xac, 0xfc, 0xf0, 0x23, 0x23, 0x70, 0xe6, 0x3b, 0xe3, 0x71, 0x10, 0xbd, + 0xb3, 0x09, 0x00, 0x20, 0x10, 0xb5, 0xff, 0xf7, 0xef, 0xff, 0x00, 0x22, + 0x01, 0x4b, 0x1a, 0x73, 0x10, 0xbd, 0xc0, 0x46, 0x9e, 0x01, 0x00, 0x20, + 0xf7, 0xb5, 0x80, 0x27, 0x04, 0x00, 0x16, 0x00, 0x00, 0x25, 0x01, 0x91, + 0xbf, 0x00, 0xa3, 0x68, 0xab, 0x42, 0x00, 0xd8, 0xf7, 0xbd, 0x39, 0x00, + 0xa2, 0x78, 0x01, 0x9b, 0xe0, 0x68, 0xff, 0xf7, 0xa4, 0xfa, 0x80, 0x23, + 0x5b, 0x01, 0xe8, 0x18, 0x01, 0x22, 0x33, 0x00, 0xe1, 0x68, 0xff, 0xf7, + 0x83, 0xfe, 0x01, 0x35, 0xeb, 0xe7, 0x70, 0xb5, 0x13, 0x00, 0x06, 0x00, + 0x0c, 0x00, 0x15, 0x00, 0x00, 0x20, 0x0a, 0x00, 0x01, 0x21, 0xff, 0xf7, + 0x1b, 0xfa, 0x00, 0x23, 0x98, 0x42, 0x06, 0xd0, 0x2b, 0x00, 0x22, 0x00, + 0x1f, 0x21, 0x30, 0x00, 0xff, 0xf7, 0x12, 0xfa, 0x01, 0x23, 0x18, 0x00, + 0x70, 0xbd, 0x00, 0x00, 0x10, 0xb5, 0x04, 0x22, 0x0d, 0x21, 0x02, 0x48, + 0xff, 0xf7, 0xd8, 0xfa, 0x10, 0xbd, 0xc0, 0x46, 0x9e, 0x01, 0x00, 0x20, + 0x10, 0xb5, 0x0b, 0x4c, 0x0b, 0x48, 0x61, 0x79, 0x23, 0x79, 0xa2, 0x79, + 0x09, 0x02, 0x19, 0x43, 0xe3, 0x79, 0x12, 0x04, 0x11, 0x43, 0x1b, 0x06, + 0x0b, 0x43, 0x1a, 0x0a, 0x03, 0x71, 0x42, 0x71, 0x1a, 0x0c, 0x1b, 0x0e, + 0x82, 0x71, 0xc3, 0x71, 0xff, 0xf7, 0xe0, 0xff, 0x10, 0xbd, 0xc0, 0x46, + 0x94, 0x09, 0x00, 0x20, 0x9e, 0x01, 0x00, 0x20, 0x70, 0xb5, 0x04, 0x22, + 0x0d, 0x00, 0xff, 0xf7, 0xb3, 0xfa, 0x15, 0x4c, 0x85, 0x42, 0x0f, 0xd0, + 0xff, 0xf7, 0x86, 0xff, 0x01, 0x23, 0x04, 0x22, 0x23, 0x73, 0x12, 0x4b, + 0x9a, 0x70, 0x00, 0x22, 0xda, 0x70, 0x1a, 0x71, 0x5a, 0x71, 0x9a, 0x71, + 0x1a, 0x73, 0x5a, 0x73, 0xff, 0xf7, 0xcc, 0xff, 0xff, 0xf7, 0x84, 0xff, + 0x63, 0x7a, 0x21, 0x7a, 0x1b, 0x02, 0x0b, 0x43, 0xa1, 0x7a, 0xe2, 0x7a, + 0x09, 0x04, 0x12, 0x06, 0x19, 0x43, 0x11, 0x43, 0x49, 0x1b, 0x0b, 0x0a, + 0x21, 0x72, 0x63, 0x72, 0x0b, 0x0c, 0x09, 0x0e, 0xa3, 0x72, 0xe1, 0x72, + 0xff, 0xf7, 0xb6, 0xff, 0x70, 0xbd, 0xc0, 0x46, 0x9e, 0x01, 0x00, 0x20, + 0xb3, 0x09, 0x00, 0x20, 0x70, 0xb5, 0x18, 0x4c, 0x14, 0x22, 0x05, 0x00, + 0x00, 0x21, 0x20, 0x00, 0x00, 0xf0, 0x07, 0xfc, 0x15, 0x4a, 0x00, 0x2d, + 0x1f, 0xd0, 0x21, 0x00, 0x08, 0x23, 0xd0, 0x7d, 0x08, 0x31, 0x3f, 0x26, + 0x52, 0x7c, 0x32, 0x40, 0x1c, 0x2a, 0x01, 0xd0, 0xb2, 0x42, 0x05, 0xd1, + 0x0f, 0x4a, 0x0c, 0x33, 0x0a, 0x80, 0x05, 0x22, 0xdb, 0xb2, 0xca, 0x70, + 0x19, 0x1c, 0x83, 0x42, 0x00, 0xd9, 0x01, 0x1c, 0xc9, 0xb2, 0x00, 0x2d, + 0x0b, 0xd0, 0x02, 0x3b, 0x9b, 0xb2, 0x1b, 0x02, 0x23, 0x80, 0x20, 0x00, + 0xff, 0xf7, 0xa2, 0xff, 0x70, 0xbd, 0x04, 0x23, 0xd0, 0x7c, 0x21, 0x1d, + 0xdf, 0xe7, 0x01, 0x3b, 0x23, 0x70, 0xf4, 0xe7, 0x78, 0x09, 0x00, 0x20, + 0x94, 0x09, 0x00, 0x20, 0x1c, 0x0a, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x00, + 0x00, 0x25, 0x2a, 0x4b, 0x85, 0xb0, 0x59, 0x7c, 0x03, 0xaa, 0xd1, 0x70, + 0x99, 0x7c, 0x91, 0x70, 0xd9, 0x7c, 0x51, 0x70, 0x19, 0x7d, 0x11, 0x70, + 0x99, 0x7d, 0x02, 0xaa, 0xd1, 0x70, 0xdb, 0x7d, 0x93, 0x70, 0x53, 0x88, + 0x01, 0x93, 0x01, 0x9b, 0xab, 0x42, 0x05, 0xd8, 0xff, 0xf7, 0x18, 0xff, + 0xff, 0xf7, 0x5c, 0xff, 0x05, 0xb0, 0xf0, 0xbd, 0xff, 0xf7, 0x48, 0xfa, + 0x00, 0x28, 0xf9, 0xd0, 0x03, 0x9b, 0x1b, 0x4f, 0xee, 0x18, 0x00, 0x2c, + 0x1f, 0xd0, 0x39, 0x00, 0x30, 0x00, 0xff, 0xf7, 0xf9, 0xfc, 0x80, 0x21, + 0x04, 0x22, 0x38, 0x00, 0x89, 0x00, 0xff, 0xf7, 0x1b, 0xfa, 0x15, 0x4a, + 0x01, 0x35, 0x50, 0x7a, 0x13, 0x7a, 0x91, 0x7a, 0x00, 0x02, 0x18, 0x43, + 0xd3, 0x7a, 0x09, 0x04, 0x08, 0x43, 0x1b, 0x06, 0x10, 0x49, 0x03, 0x43, + 0x5b, 0x18, 0x19, 0x0a, 0x13, 0x72, 0x51, 0x72, 0x19, 0x0c, 0x1b, 0x0e, + 0x91, 0x72, 0xd3, 0x72, 0xcd, 0xe7, 0x80, 0x21, 0x23, 0x00, 0x38, 0x00, + 0x05, 0x22, 0x89, 0x00, 0xff, 0xf7, 0xa3, 0xf9, 0x22, 0x00, 0x39, 0x00, + 0x30, 0x00, 0x07, 0x4b, 0xff, 0xf7, 0x84, 0xfd, 0xff, 0xf7, 0x7a, 0xf8, + 0xd9, 0xe7, 0xc0, 0x46, 0x94, 0x09, 0x00, 0x20, 0x78, 0x07, 0x00, 0x20, + 0x9e, 0x01, 0x00, 0x20, 0x00, 0xfe, 0xff, 0xff, 0xc8, 0x09, 0x00, 0x20, + 0x7f, 0xb5, 0x00, 0xf0, 0x2f, 0xfb, 0x44, 0x4e, 0x00, 0x22, 0x05, 0x21, + 0x30, 0x00, 0xff, 0xf7, 0xec, 0xfe, 0x00, 0x28, 0x49, 0xd0, 0x73, 0x7a, + 0x32, 0x7a, 0xb5, 0x7a, 0x1b, 0x02, 0x1a, 0x43, 0xf3, 0x7a, 0x2d, 0x04, + 0x1b, 0x06, 0x15, 0x43, 0x3c, 0x4c, 0x1d, 0x43, 0x2b, 0x0a, 0x63, 0x72, + 0x2b, 0x0c, 0xa3, 0x72, 0x2b, 0x0e, 0x25, 0x72, 0xe3, 0x72, 0xf0, 0x7b, + 0x2f, 0x28, 0x27, 0xd8, 0x19, 0x28, 0x15, 0xd8, 0x03, 0x28, 0x27, 0xd0, + 0x12, 0x28, 0x2f, 0xd0, 0x00, 0x28, 0x40, 0xd0, 0xff, 0xf7, 0x98, 0xfe, + 0x01, 0x23, 0x05, 0x22, 0x23, 0x73, 0x31, 0x4b, 0x9a, 0x70, 0x00, 0x22, + 0xda, 0x70, 0x1a, 0x71, 0x5a, 0x71, 0x9a, 0x71, 0x1a, 0x73, 0x20, 0x32, + 0x5a, 0x73, 0x32, 0xe0, 0x1a, 0x38, 0x15, 0x28, 0xec, 0xd8, 0x00, 0xf0, + 0x1b, 0xfb, 0x28, 0x2c, 0xeb, 0xeb, 0x2c, 0xeb, 0xeb, 0xeb, 0xeb, 0x3f, + 0xeb, 0x31, 0xeb, 0xeb, 0x39, 0xeb, 0x3d, 0xeb, 0xeb, 0xeb, 0xeb, 0x2c, + 0x5a, 0x28, 0xdd, 0xd1, 0x01, 0x20, 0x19, 0xe0, 0xf3, 0x7c, 0x19, 0x1c, + 0x12, 0x2b, 0x00, 0xd9, 0x12, 0x21, 0x1f, 0x48, 0xc9, 0xb2, 0xff, 0xf7, + 0xdd, 0xfe, 0x7f, 0xbd, 0x1d, 0x4c, 0x1e, 0x49, 0x20, 0x00, 0x18, 0x22, + 0x08, 0x30, 0xff, 0xf7, 0x55, 0xfc, 0xf3, 0x7c, 0x19, 0x1c, 0x24, 0x2b, + 0x00, 0xd9, 0x24, 0x21, 0x20, 0x00, 0xc9, 0xb2, 0xed, 0xe7, 0x00, 0x20, + 0xff, 0xf7, 0xfe, 0xfe, 0xeb, 0xe7, 0xff, 0xf7, 0x65, 0xfe, 0xff, 0xf7, + 0xa9, 0xfe, 0xe6, 0xe7, 0x80, 0x23, 0x13, 0x48, 0x9b, 0x02, 0x43, 0x60, + 0x12, 0x4b, 0x08, 0x21, 0x03, 0x60, 0xdc, 0xe7, 0x01, 0x20, 0xff, 0xf7, + 0x25, 0xff, 0xda, 0xe7, 0x00, 0x20, 0xfa, 0xe7, 0x0c, 0x26, 0x0e, 0x49, + 0x32, 0x00, 0x01, 0xa8, 0x00, 0xf0, 0xea, 0xfa, 0xb5, 0x42, 0x04, 0xd9, + 0x00, 0x23, 0x26, 0x72, 0x63, 0x72, 0xa3, 0x72, 0xe3, 0x72, 0x0c, 0x21, + 0x01, 0xa8, 0xc6, 0xe7, 0x94, 0x09, 0x00, 0x20, 0x9e, 0x01, 0x00, 0x20, + 0xb3, 0x09, 0x00, 0x20, 0xac, 0x01, 0x00, 0x20, 0x5f, 0x1b, 0x00, 0x00, + 0x8c, 0x09, 0x00, 0x20, 0x00, 0x00, 0x3e, 0x7f, 0xff, 0x1c, 0x00, 0x00, + 0x72, 0xb6, 0xbf, 0xf3, 0x5f, 0x8f, 0x82, 0x23, 0x03, 0x4a, 0xdb, 0x05, + 0x9a, 0x82, 0x9a, 0x83, 0x00, 0x22, 0x02, 0x4b, 0x9a, 0x60, 0x70, 0x47, + 0xff, 0x03, 0x00, 0x00, 0x00, 0xed, 0x00, 0xe0, 0xf0, 0xb5, 0xc5, 0xb0, + 0x0d, 0xaf, 0x04, 0x00, 0xff, 0xf7, 0xea, 0xff, 0x44, 0x22, 0x00, 0x21, + 0x38, 0x00, 0x00, 0xf0, 0xbe, 0xfa, 0x98, 0x22, 0x00, 0x21, 0x1e, 0xa8, + 0x00, 0xf0, 0xb9, 0xfa, 0x02, 0x23, 0x0f, 0x21, 0xbb, 0x70, 0xa3, 0x78, + 0x62, 0x78, 0x0b, 0x40, 0xa3, 0x70, 0x26, 0x4b, 0x0a, 0x40, 0x05, 0x93, + 0x63, 0x68, 0x05, 0xad, 0x06, 0x93, 0x00, 0x23, 0xe1, 0x68, 0x07, 0x93, + 0x22, 0x48, 0x62, 0x70, 0x2b, 0x73, 0x01, 0x22, 0x1e, 0xab, 0xff, 0xf7, + 0xa3, 0xfc, 0x39, 0x00, 0x20, 0x00, 0x1e, 0xaa, 0xff, 0xf7, 0x02, 0xfe, + 0x28, 0x00, 0x01, 0x23, 0x0d, 0x21, 0x62, 0x78, 0xff, 0xf7, 0xc2, 0xf8, + 0x00, 0x25, 0x05, 0xae, 0x3a, 0x00, 0x30, 0x00, 0xa1, 0x78, 0xff, 0xf7, + 0x10, 0xfe, 0x00, 0x28, 0x1e, 0xd0, 0x14, 0x4b, 0x01, 0xad, 0x01, 0x93, + 0x06, 0x9b, 0x6b, 0x60, 0x07, 0x9b, 0xab, 0x60, 0x00, 0x23, 0x2b, 0x73, + 0xf3, 0x7b, 0x00, 0x2b, 0xe4, 0xd0, 0x2a, 0x2b, 0x17, 0xd1, 0x6b, 0x46, + 0xb2, 0x7d, 0x39, 0x00, 0xda, 0x70, 0xf2, 0x7d, 0x20, 0x00, 0x9a, 0x70, + 0x5e, 0x88, 0x1e, 0xaa, 0xa6, 0x60, 0xff, 0xf7, 0xd9, 0xfd, 0xab, 0x68, + 0x76, 0x02, 0x9e, 0x1b, 0xae, 0x60, 0xd1, 0xe7, 0x06, 0x4b, 0x9d, 0x42, + 0x01, 0xd9, 0xfe, 0xf7, 0xcf, 0xfe, 0x01, 0x35, 0xd1, 0xe7, 0xfe, 0xf7, + 0xff, 0xfe, 0xc7, 0xe7, 0x53, 0x42, 0x53, 0x55, 0xff, 0x0f, 0x00, 0x00, + 0xf8, 0x24, 0x01, 0x00, 0x30, 0xb5, 0xef, 0xf3, 0x08, 0x83, 0x05, 0x4c, + 0x23, 0x60, 0x03, 0x68, 0x83, 0xf3, 0x08, 0x88, 0x45, 0x68, 0xa8, 0x47, + 0x23, 0x68, 0x83, 0xf3, 0x08, 0x88, 0x30, 0xbd, 0xc0, 0x0a, 0x00, 0x20, + 0x07, 0xb5, 0x01, 0x00, 0x01, 0x22, 0x68, 0x46, 0xfe, 0xf7, 0x92, 0xfe, + 0x08, 0x21, 0x68, 0x46, 0xff, 0xf7, 0x54, 0xfb, 0x07, 0xbd, 0x00, 0x00, + 0xf8, 0xb5, 0x00, 0x23, 0x7a, 0x22, 0x7f, 0x4c, 0x23, 0x60, 0x7f, 0x4b, + 0x1a, 0x70, 0xff, 0xf7, 0xc5, 0xfe, 0x7e, 0x4d, 0x40, 0x21, 0x28, 0x00, + 0xff, 0xf7, 0x52, 0xfb, 0x7c, 0x4b, 0x18, 0x60, 0x00, 0x23, 0x2b, 0x54, + 0x98, 0x42, 0x01, 0xd0, 0xfe, 0xf7, 0x26, 0xff, 0x00, 0x22, 0x79, 0x4b, + 0x1d, 0x60, 0x79, 0x4b, 0x1a, 0x60, 0x78, 0x48, 0x75, 0x4b, 0x02, 0x68, + 0x1f, 0x68, 0xba, 0x42, 0xe5, 0xd2, 0x74, 0x4e, 0x31, 0x68, 0x0b, 0x78, + 0xff, 0x2b, 0x36, 0xd0, 0x73, 0x4d, 0x23, 0x2b, 0x00, 0xd0, 0xb3, 0xe0, + 0x6c, 0x4b, 0x1b, 0x78, 0x53, 0x2b, 0x33, 0xd1, 0x2b, 0x68, 0x01, 0x32, + 0x01, 0x31, 0x02, 0x60, 0x31, 0x60, 0xba, 0x1a, 0x9a, 0x42, 0x00, 0xd9, + 0x1a, 0x00, 0x6c, 0x4d, 0x20, 0x68, 0x2a, 0x60, 0x00, 0xf0, 0xfe, 0xf9, + 0x67, 0x48, 0x29, 0x68, 0x03, 0x68, 0x65, 0x4a, 0xcb, 0x18, 0x01, 0x3b, + 0x03, 0x60, 0x10, 0x68, 0x4b, 0x1e, 0xc3, 0x18, 0x13, 0x60, 0x63, 0x4b, + 0x64, 0x4d, 0x1b, 0x68, 0x29, 0x70, 0xc9, 0xb2, 0x8b, 0x42, 0x03, 0xd9, + 0x20, 0x68, 0x59, 0x1a, 0xff, 0xf7, 0x1d, 0xfb, 0xc0, 0x46, 0x7a, 0x22, + 0x57, 0x4b, 0x1a, 0x70, 0x00, 0x22, 0x5b, 0x4b, 0x1a, 0x60, 0x58, 0x4a, + 0x13, 0x68, 0x01, 0x33, 0x13, 0x60, 0x57, 0x4a, 0x13, 0x68, 0x01, 0x33, + 0x13, 0x60, 0xb8, 0xe7, 0x52, 0x2b, 0x04, 0xd1, 0x29, 0x68, 0x20, 0x68, + 0xff, 0xf7, 0xf1, 0xfa, 0xe9, 0xe7, 0x4f, 0x2b, 0x03, 0xd1, 0x2b, 0x68, + 0x22, 0x68, 0x13, 0x70, 0xe3, 0xe7, 0x48, 0x2b, 0x03, 0xd1, 0x2b, 0x68, + 0x22, 0x68, 0x13, 0x80, 0xdd, 0xe7, 0x57, 0x2b, 0x0a, 0xd1, 0x4e, 0x4b, + 0x22, 0x68, 0x9a, 0x42, 0x02, 0xd1, 0x4d, 0x48, 0xfe, 0xf7, 0xdc, 0xfe, + 0x23, 0x68, 0x2a, 0x68, 0x1a, 0x60, 0xd0, 0xe7, 0x6f, 0x2b, 0x04, 0xd1, + 0x01, 0x21, 0x20, 0x68, 0xff, 0xf7, 0xca, 0xfa, 0xc9, 0xe7, 0x68, 0x2b, + 0x05, 0xd1, 0x02, 0x21, 0x23, 0x68, 0x1b, 0x88, 0x2b, 0x60, 0x28, 0x00, + 0xf4, 0xe7, 0x77, 0x2b, 0x04, 0xd1, 0x23, 0x68, 0x04, 0x21, 0x1b, 0x68, + 0x2b, 0x60, 0xf6, 0xe7, 0x47, 0x2b, 0x09, 0xd1, 0x28, 0x68, 0xff, 0xf7, + 0x47, 0xff, 0x3d, 0x4b, 0x1b, 0x78, 0x00, 0x2b, 0xb1, 0xd0, 0x01, 0x21, + 0x3b, 0x48, 0xe1, 0xe7, 0x54, 0x2b, 0xac, 0xd0, 0x4e, 0x2b, 0xaa, 0xd0, + 0x56, 0x2b, 0x02, 0xd1, 0x2a, 0x21, 0x38, 0x48, 0xd8, 0xe7, 0x58, 0x2b, + 0x05, 0xd1, 0x28, 0x68, 0xfe, 0xf7, 0x64, 0xfc, 0x03, 0x21, 0x35, 0x48, + 0xd0, 0xe7, 0x59, 0x2b, 0x0d, 0xd1, 0x2a, 0x68, 0x20, 0x68, 0x33, 0x4b, + 0x00, 0x2a, 0x03, 0xd1, 0x18, 0x60, 0x03, 0x21, 0x31, 0x48, 0xc5, 0xe7, + 0x19, 0x68, 0x92, 0x08, 0xfe, 0xf7, 0x6a, 0xfc, 0xf7, 0xe7, 0x5a, 0x2b, + 0x8b, 0xd1, 0x2f, 0x68, 0x00, 0x25, 0x26, 0x68, 0xf7, 0x19, 0xb7, 0x42, + 0x09, 0xd1, 0x01, 0x21, 0x2a, 0x48, 0xff, 0xf7, 0x81, 0xfa, 0x28, 0x00, + 0xff, 0xf7, 0x20, 0xff, 0x03, 0x21, 0x28, 0x48, 0xae, 0xe7, 0x29, 0x00, + 0x30, 0x78, 0xfe, 0xf7, 0x71, 0xfd, 0x01, 0x36, 0x05, 0x00, 0xec, 0xe7, + 0x1a, 0x00, 0x30, 0x3a, 0xd1, 0xb2, 0x09, 0x29, 0x04, 0xd8, 0x2b, 0x68, + 0x1b, 0x01, 0x13, 0x43, 0x2b, 0x60, 0x70, 0xe7, 0x1a, 0x00, 0x41, 0x3a, + 0x05, 0x2a, 0x03, 0xd8, 0x2a, 0x68, 0x37, 0x3b, 0x12, 0x01, 0xf4, 0xe7, + 0x1a, 0x00, 0x61, 0x3a, 0x05, 0x2a, 0x03, 0xd8, 0x2a, 0x68, 0x57, 0x3b, + 0x12, 0x01, 0xec, 0xe7, 0x2c, 0x2b, 0x03, 0xd1, 0x2b, 0x68, 0x23, 0x60, + 0x00, 0x23, 0xe7, 0xe7, 0x02, 0x4a, 0x13, 0x70, 0xfa, 0xe7, 0xc0, 0x46, + 0xbc, 0x0a, 0x00, 0x20, 0x61, 0x0a, 0x00, 0x20, 0x68, 0x0a, 0x00, 0x20, + 0xb4, 0x0a, 0x00, 0x20, 0xb8, 0x0a, 0x00, 0x20, 0xac, 0x0a, 0x00, 0x20, + 0x64, 0x0a, 0x00, 0x20, 0xc8, 0x0a, 0x00, 0x20, 0xb0, 0x0a, 0x00, 0x20, + 0x0c, 0xed, 0x00, 0xe0, 0x40, 0x00, 0x40, 0x00, 0x60, 0x0a, 0x00, 0x20, + 0x0b, 0x1d, 0x00, 0x00, 0x1b, 0x1d, 0x00, 0x00, 0x0d, 0x1d, 0x00, 0x00, + 0xc4, 0x0a, 0x00, 0x20, 0x11, 0x1d, 0x00, 0x00, 0x15, 0x1d, 0x00, 0x00, + 0x17, 0x1d, 0x00, 0x00, 0x03, 0x00, 0xf7, 0xb5, 0x47, 0x33, 0x04, 0x00, + 0x1a, 0x78, 0x40, 0x21, 0x03, 0x00, 0x00, 0x20, 0xfe, 0xf7, 0xb6, 0xfe, + 0x00, 0x28, 0x01, 0xd1, 0x00, 0x20, 0xfe, 0xbd, 0x00, 0x23, 0x23, 0x70, + 0x23, 0x79, 0x01, 0x93, 0x04, 0x23, 0xe3, 0x56, 0x00, 0x2b, 0xf5, 0xdb, + 0x3f, 0x26, 0x20, 0x00, 0x01, 0x9f, 0xa5, 0x1d, 0xeb, 0x8f, 0x37, 0x40, + 0x48, 0x30, 0xc0, 0x18, 0x3a, 0x00, 0x61, 0x1d, 0x00, 0xf0, 0xf0, 0xf8, + 0xe8, 0x8f, 0x01, 0x9b, 0xc0, 0x19, 0x80, 0xb2, 0xb3, 0x43, 0x01, 0xd1, + 0xe8, 0x87, 0xe1, 0xe7, 0x00, 0x23, 0xeb, 0x87, 0xdf, 0xe7, 0xf0, 0xb5, + 0x06, 0x00, 0x0c, 0x00, 0x1f, 0x00, 0x93, 0xb0, 0x01, 0x92, 0x3f, 0x25, + 0xac, 0x42, 0x03, 0xdc, 0x25, 0x00, 0x00, 0x2f, 0x00, 0xd1, 0x40, 0x37, + 0x3b, 0x00, 0x02, 0xaa, 0x2b, 0x43, 0x13, 0x70, 0x02, 0xab, 0x31, 0x00, + 0x2a, 0x00, 0x58, 0x1c, 0x00, 0xf0, 0xce, 0xf8, 0x6b, 0x46, 0x40, 0x21, + 0x1a, 0x79, 0x02, 0xa8, 0x01, 0x23, 0xfe, 0xf7, 0xfb, 0xfe, 0x76, 0x19, + 0x64, 0x1b, 0xe4, 0xd1, 0x13, 0xb0, 0xf0, 0xbd, 0x03, 0x00, 0x10, 0xb5, + 0x47, 0x33, 0x1a, 0x78, 0x04, 0x31, 0x00, 0x23, 0x48, 0x30, 0xff, 0xf7, + 0xd4, 0xff, 0x10, 0xbd, 0xf7, 0xb5, 0x04, 0x00, 0xff, 0xf7, 0xa2, 0xff, + 0x00, 0x28, 0x42, 0xd0, 0x23, 0x00, 0x48, 0x33, 0x9a, 0x88, 0xa0, 0x6c, + 0x1a, 0x80, 0x00, 0x22, 0x01, 0x38, 0x5a, 0x80, 0x08, 0x28, 0x65, 0xd8, + 0x00, 0xf0, 0x9c, 0xf8, 0x15, 0x05, 0x23, 0x27, 0x25, 0x2a, 0x48, 0x3f, + 0x38, 0x00, 0x31, 0x4e, 0x30, 0x00, 0x00, 0xf0, 0xae, 0xf8, 0x05, 0x00, + 0x20, 0x00, 0x31, 0x00, 0x2a, 0x00, 0x4c, 0x30, 0x00, 0xf0, 0x96, 0xf8, + 0x29, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xd0, 0xff, 0x21, 0xe0, 0x01, 0x23, + 0xe3, 0x64, 0xff, 0x33, 0x23, 0x65, 0x80, 0x23, 0xdb, 0x00, 0x63, 0x65, + 0xa0, 0x23, 0x5b, 0x00, 0xa3, 0x65, 0x25, 0x4b, 0x14, 0x21, 0xe3, 0x65, + 0xed, 0xe7, 0xfe, 0xf7, 0xef, 0xfc, 0x00, 0x21, 0xe9, 0xe7, 0xfe, 0xf7, + 0x1f, 0xfd, 0xfa, 0xe7, 0x20, 0x00, 0x00, 0x21, 0xff, 0xf7, 0xb6, 0xff, + 0x80, 0x23, 0x20, 0x6d, 0x9b, 0x01, 0x98, 0x42, 0x03, 0xd3, 0x21, 0x00, + 0x54, 0x31, 0xfe, 0xf7, 0x8d, 0xfb, 0xf7, 0xbd, 0x21, 0x00, 0x62, 0x6d, + 0x20, 0x6d, 0x58, 0x31, 0xfe, 0xf7, 0x51, 0xfb, 0xe5, 0xe7, 0x20, 0x00, + 0x65, 0x6d, 0x21, 0x6d, 0x2a, 0x00, 0x4c, 0x30, 0xfe, 0xf7, 0x49, 0xfb, + 0xa9, 0x00, 0xc8, 0xe7, 0x00, 0x26, 0x63, 0x6d, 0x27, 0x6d, 0x01, 0x93, + 0x01, 0x9b, 0xb3, 0x42, 0x01, 0xdc, 0x59, 0x00, 0xbf, 0xe7, 0x3d, 0x00, + 0x00, 0x21, 0x2b, 0x00, 0x18, 0x78, 0xfe, 0xf7, 0x61, 0xfc, 0x7b, 0x1c, + 0x01, 0x35, 0xff, 0x33, 0x01, 0x00, 0x9d, 0x42, 0xf5, 0xd1, 0x23, 0x00, + 0x72, 0x00, 0x4c, 0x33, 0x2f, 0x00, 0x98, 0x52, 0x01, 0x36, 0xe7, 0xe7, + 0x01, 0x22, 0x5a, 0x80, 0xbd, 0xe7, 0xc0, 0x46, 0xa4, 0x1c, 0x00, 0x00, + 0x2f, 0x47, 0x29, 0x2c, 0x07, 0x48, 0x06, 0x22, 0x03, 0x00, 0x10, 0xb5, + 0x47, 0x33, 0x1a, 0x70, 0xff, 0xf7, 0x7a, 0xff, 0x04, 0x48, 0x07, 0x22, + 0x03, 0x00, 0x47, 0x33, 0x1a, 0x70, 0xff, 0xf7, 0x73, 0xff, 0x10, 0xbd, + 0xcc, 0x0a, 0x00, 0x20, 0x54, 0x0c, 0x00, 0x20, 0x10, 0xb5, 0xe2, 0xb0, + 0x04, 0x00, 0xff, 0xf7, 0x51, 0xfd, 0xc4, 0x22, 0x00, 0x21, 0x68, 0x46, + 0x52, 0x00, 0x00, 0xf0, 0x24, 0xf8, 0x47, 0x23, 0x6b, 0x44, 0x1c, 0x70, + 0x68, 0x46, 0xff, 0xf7, 0x5d, 0xff, 0xfb, 0xe7, 0x02, 0xb4, 0x71, 0x46, + 0x49, 0x08, 0x49, 0x00, 0x09, 0x56, 0x49, 0x00, 0x8e, 0x44, 0x02, 0xbc, + 0x70, 0x47, 0xc0, 0x46, 0x02, 0xb4, 0x71, 0x46, 0x49, 0x08, 0x49, 0x00, + 0x09, 0x5c, 0x49, 0x00, 0x8e, 0x44, 0x02, 0xbc, 0x70, 0x47, 0xc0, 0x46, + 0x00, 0x23, 0x10, 0xb5, 0x9a, 0x42, 0x00, 0xd1, 0x10, 0xbd, 0xcc, 0x5c, + 0xc4, 0x54, 0x01, 0x33, 0xf8, 0xe7, 0x03, 0x00, 0x82, 0x18, 0x93, 0x42, + 0x00, 0xd1, 0x70, 0x47, 0x19, 0x70, 0x01, 0x33, 0xf9, 0xe7, 0x00, 0x23, + 0xc2, 0x5c, 0x01, 0x33, 0x00, 0x2a, 0xfb, 0xd1, 0x58, 0x1e, 0x70, 0x47, + 0x4f, 0x64, 0x64, 0x6c, 0x79, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, + 0x69, 0x63, 0x20, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x53, + 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x20, 0x57, 0x61, 0x74, 0x63, 0x68, 0x20, + 0x4d, 0x30, 0x00, 0x00, 0x0c, 0xa0, 0x80, 0x00, 0x40, 0xa0, 0x80, 0x00, + 0x44, 0xa0, 0x80, 0x00, 0x48, 0xa0, 0x80, 0x00, 0x12, 0x01, 0x10, 0x02, + 0xef, 0x02, 0x01, 0x40, 0x09, 0x12, 0x50, 0x21, 0x01, 0x42, 0x01, 0x02, + 0x03, 0x01, 0x00, 0x00, 0x06, 0x97, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x15, + 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40, 0x09, 0x01, 0x81, 0x02, + 0x95, 0x40, 0x09, 0x01, 0x91, 0x02, 0x95, 0x01, 0x09, 0x01, 0xb1, 0x02, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1b, 0x00, 0x00, + 0x5f, 0x1b, 0x00, 0x00, 0x50, 0x06, 0x00, 0x20, 0xeb, 0x3c, 0x90, 0x55, + 0x46, 0x32, 0x20, 0x55, 0x46, 0x32, 0x20, 0x00, 0x02, 0x01, 0x01, 0x00, + 0x02, 0x40, 0x00, 0x7e, 0x3e, 0xf8, 0x3f, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x42, + 0x00, 0x42, 0x00, 0x57, 0x41, 0x54, 0x43, 0x48, 0x42, 0x4f, 0x4f, 0x54, + 0x00, 0x00, 0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, 0x3c, 0x21, + 0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x74, 0x6d, 0x6c, + 0x3e, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x28, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6f, 0x64, 0x64, 0x6c, 0x79, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x29, 0x3b, 0x0a, 0x3c, 0x2f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x00, 0x00, + 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x46, 0x32, 0x54, 0x58, 0x54, 0x00, + 0xa4, 0x1c, 0x00, 0x00, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x20, 0x20, + 0x48, 0x54, 0x4d, 0x00, 0x06, 0x1c, 0x00, 0x00, 0x43, 0x55, 0x52, 0x52, + 0x45, 0x4e, 0x54, 0x20, 0x55, 0x46, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x46, 0x32, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x76, 0x33, 0x2e, 0x37, 0x2e, 0x30, 0x2d, 0x31, 0x37, + 0x35, 0x2d, 0x67, 0x34, 0x39, 0x38, 0x62, 0x62, 0x31, 0x63, 0x20, 0x53, + 0x46, 0x48, 0x57, 0x52, 0x4f, 0x0d, 0x0a, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x3a, 0x20, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x20, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x20, 0x4d, 0x30, 0x0d, 0x0a, 0x42, 0x6f, 0x61, 0x72, 0x64, + 0x2d, 0x49, 0x44, 0x3a, 0x20, 0x4f, 0x53, 0x4f, 0x2d, 0x53, 0x57, 0x41, + 0x54, 0x2d, 0x41, 0x31, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x3e, 0x80, 0x02, 0x00, 0x02, 0x00, 0x06, 0x00, 0x58, 0x0a, 0x0d, + 0x00, 0x59, 0x0a, 0x0d, 0x00, 0x5a, 0x00, 0x23, 0x0a, 0x0d, 0x00, 0x76, + 0x31, 0x2e, 0x31, 0x20, 0x5b, 0x41, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x3a, 0x58, 0x59, 0x5a, 0x5d, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x32, 0x38, + 0x20, 0x32, 0x30, 0x32, 0x32, 0x20, 0x31, 0x34, 0x3a, 0x35, 0x31, 0x3a, + 0x30, 0x38, 0x0a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0xc8, 0x00, 0x00, 0x05, 0x0f, 0x39, 0x00, 0x02, 0x18, 0x10, 0x05, + 0x00, 0x38, 0xb6, 0x08, 0x34, 0xa9, 0x09, 0xa0, 0x47, 0x8b, 0xfd, 0xa0, + 0x76, 0x88, 0x15, 0xb6, 0x65, 0x00, 0x01, 0x01, 0x00, 0x1c, 0x10, 0x05, + 0x00, 0xdf, 0x60, 0xdd, 0xd8, 0x89, 0x45, 0xc7, 0x4c, 0x9c, 0xd2, 0x65, + 0x9d, 0x9e, 0x64, 0x8a, 0x9f, 0x00, 0x00, 0x03, 0x06, 0xaa, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x99, 0x00, 0x05, 0x01, 0x00, 0x80, + 0xfa, 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x01, 0x00, 0x09, 0x04, 0x00, + 0x00, 0x01, 0x02, 0x02, 0x01, 0x00, 0x05, 0x24, 0x00, 0x10, 0x01, 0x04, + 0x24, 0x02, 0x06, 0x05, 0x24, 0x06, 0x00, 0x01, 0x05, 0x24, 0x01, 0x03, + 0x01, 0x07, 0x05, 0x83, 0x03, 0x08, 0x00, 0xff, 0x09, 0x04, 0x01, 0x00, + 0x02, 0x0a, 0x00, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, + 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00, 0x02, + 0x08, 0x06, 0x50, 0x00, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x00, 0x07, + 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x09, 0x04, 0x03, 0x00, 0x02, 0x03, + 0x00, 0x00, 0x00, 0x09, 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, 0x21, 0x00, + 0x07, 0x05, 0x86, 0x03, 0x40, 0x00, 0x01, 0x07, 0x05, 0x06, 0x03, 0x40, + 0x00, 0x01, 0x09, 0x04, 0x04, 0x00, 0x02, 0xff, 0x2a, 0x01, 0x00, 0x07, + 0x05, 0x87, 0x03, 0x40, 0x00, 0x01, 0x07, 0x05, 0x07, 0x03, 0x40, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0xaa, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x04, 0x00, 0xa0, 0x00, 0x14, 0x00, 0x03, 0x00, 0x57, 0x49, + 0x4e, 0x55, 0x53, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x84, 0x00, 0x04, 0x00, 0x07, 0x00, 0x2a, 0x00, 0x44, 0x00, + 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x49, 0x00, + 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, + 0x63, 0x00, 0x65, 0x00, 0x47, 0x00, 0x55, 0x00, 0x49, 0x00, 0x44, 0x00, + 0x73, 0x00, 0x00, 0x00, 0x50, 0x00, 0x7b, 0x00, 0x39, 0x00, 0x32, 0x00, + 0x43, 0x00, 0x45, 0x00, 0x36, 0x00, 0x34, 0x00, 0x36, 0x00, 0x32, 0x00, + 0x2d, 0x00, 0x39, 0x00, 0x43, 0x00, 0x37, 0x00, 0x37, 0x00, 0x2d, 0x00, + 0x34, 0x00, 0x36, 0x00, 0x46, 0x00, 0x45, 0x00, 0x2d, 0x00, 0x39, 0x00, + 0x33, 0x00, 0x33, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x31, 0x00, + 0x43, 0x00, 0x42, 0x00, 0x39, 0x00, 0x43, 0x00, 0x35, 0x00, 0x42, 0x00, + 0x42, 0x00, 0x33, 0x00, 0x42, 0x00, 0x39, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x53, 0x42, 0x53, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x30, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x2e, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -681,10 +683,8 @@ static const uint8_t binfile[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x1a, 0x00, 0x00, - 0x89, 0x15, 0x00, 0x00, 0x94, 0x1c, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x1a, 0x00, 0x00, + 0x99, 0x15, 0x00, 0x00, 0xa4, 0x1c, 0x00, 0x00 }; #endif From 4ebc4e97ce3aa46909907f8b50a23ceb520326e0 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Fri, 1 Apr 2022 15:42:49 -0400 Subject: [PATCH 13/45] movement: add thermistor testing watch face --- movement/make/Makefile | 1 + movement/movement_faces.h | 1 + .../sensor/thermistor_testing_face.c | 88 +++++++++++++++++++ .../sensor/thermistor_testing_face.h | 43 +++++++++ 4 files changed, 133 insertions(+) create mode 100644 movement/watch_faces/sensor/thermistor_testing_face.c create mode 100644 movement/watch_faces/sensor/thermistor_testing_face.h diff --git a/movement/make/Makefile b/movement/make/Makefile index cd4471b..1e52995 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -41,6 +41,7 @@ SRCS += \ ../watch_faces/settings/set_time_face.c \ ../watch_faces/sensor/thermistor_readout_face.c \ ../watch_faces/sensor/thermistor_logging_face.c \ + ../watch_faces/sensor/thermistor_testing_face.c \ ../watch_faces/demo/character_set_face.c \ ../watch_faces/demo/voltage_face.c \ ../watch_faces/demo/lis2dh_logging_face.c \ diff --git a/movement/movement_faces.h b/movement/movement_faces.h index b093ebf..50df00d 100644 --- a/movement/movement_faces.h +++ b/movement/movement_faces.h @@ -32,6 +32,7 @@ #include "pulsometer_face.h" #include "thermistor_readout_face.h" #include "thermistor_logging_face.h" +#include "thermistor_testing_face.h" #include "character_set_face.h" #include "beats_face.h" #include "day_one_face.h" diff --git a/movement/watch_faces/sensor/thermistor_testing_face.c b/movement/watch_faces/sensor/thermistor_testing_face.c new file mode 100644 index 0000000..f50e056 --- /dev/null +++ b/movement/watch_faces/sensor/thermistor_testing_face.c @@ -0,0 +1,88 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include "thermistor_testing_face.h" +#include "thermistor_driver.h" +#include "watch.h" + +// This watch face is designed for testing temperature sensor boards. +// It displays temperature readings at a relatively fast rate of 8 Hz, +// and disables low energy mode so my testing device doesn't sleep. +// You more than likely want to use thermistor_readout_face instead. + +static void _thermistor_testing_face_update_display(bool in_fahrenheit) { + thermistor_driver_enable(); + float temperature_c = thermistor_driver_get_temperature(); + char buf[14]; + if (in_fahrenheit) { + sprintf(buf, "%4.1f#F", temperature_c * 1.8 + 32.0); + } else { + sprintf(buf, "%4.1f#C", temperature_c); + } + watch_display_string(buf, 4); + thermistor_driver_disable(); +} + +void thermistor_testing_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) watch_face_index; + (void) context_ptr; + // force one setting: never enter low energy mode. + // I'm using this watch face to test the temperature sensor boards; there's no need for it. + settings->bit.le_interval = 0; +} + +void thermistor_testing_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; + watch_display_string("TE", 0); + movement_request_tick_frequency(8); +} + +bool thermistor_testing_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + (void) context; + switch (event.event_type) { + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_ALARM_BUTTON_DOWN: + settings->bit.use_imperial_units = !settings->bit.use_imperial_units; + _thermistor_testing_face_update_display(settings->bit.use_imperial_units); + break; + case EVENT_ACTIVATE: + case EVENT_TICK: + _thermistor_testing_face_update_display(settings->bit.use_imperial_units); + break; + default: + break; + } + + return true; +} + +void thermistor_testing_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} diff --git a/movement/watch_faces/sensor/thermistor_testing_face.h b/movement/watch_faces/sensor/thermistor_testing_face.h new file mode 100644 index 0000000..656f58d --- /dev/null +++ b/movement/watch_faces/sensor/thermistor_testing_face.h @@ -0,0 +1,43 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef THERMISTOR_TESTING_FACE_H_ +#define THERMISTOR_TESTING_FACE_H_ + +#include "movement.h" + +void thermistor_testing_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void thermistor_testing_face_activate(movement_settings_t *settings, void *context); +bool thermistor_testing_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void thermistor_testing_face_resign(movement_settings_t *settings, void *context); + +#define thermistor_testing_face ((const watch_face_t){ \ + thermistor_testing_face_setup, \ + thermistor_testing_face_activate, \ + thermistor_testing_face_loop, \ + thermistor_testing_face_resign, \ + NULL, \ +}) + +#endif // THERMISTOR_TESTING_FACE_H_ From fa0a424857fc3cdda56057f9e0201eaa30044489 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Fri, 1 Apr 2022 15:43:19 -0400 Subject: [PATCH 14/45] thermistor readout: fix change in units when waking from sleep --- movement/watch_faces/sensor/thermistor_readout_face.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/movement/watch_faces/sensor/thermistor_readout_face.c b/movement/watch_faces/sensor/thermistor_readout_face.c index b97c843..2810602 100644 --- a/movement/watch_faces/sensor/thermistor_readout_face.c +++ b/movement/watch_faces/sensor/thermistor_readout_face.c @@ -63,7 +63,7 @@ bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *s case EVENT_LIGHT_BUTTON_DOWN: movement_illuminate_led(); break; - case EVENT_ALARM_BUTTON_UP: + case EVENT_ALARM_BUTTON_DOWN: settings->bit.use_imperial_units = !settings->bit.use_imperial_units; _thermistor_readout_face_update_display(settings->bit.use_imperial_units); break; From 51e357d8224e3d740f4ab9ed6d6fc0de4fdb9d4c Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 2 Apr 2022 10:06:08 -0400 Subject: [PATCH 15/45] movement: final list of watch faces for stock firmware --- make.mk | 1 + movement/movement_config.h | 6 ++++-- watch-library/simulator/watch/watch_adc.c | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/make.mk b/make.mk index 98e46c1..851e7e9 100644 --- a/make.mk +++ b/make.mk @@ -161,6 +161,7 @@ SRCS += \ $(TOP)/watch-library/simulator/watch/watch_deepsleep.c \ $(TOP)/watch-library/simulator/watch/watch_private.c \ $(TOP)/watch-library/simulator/watch/watch.c \ + $(TOP)/watch-library/shared/driver/thermistor_driver.c \ $(TOP)/watch-library/shared/watch/watch_private_buzzer.c \ $(TOP)/watch-library/shared/watch/watch_private_display.c \ $(TOP)/watch-library/shared/watch/watch_utility.c \ diff --git a/movement/movement_config.h b/movement/movement_config.h index e68fcc9..9445677 100644 --- a/movement/movement_config.h +++ b/movement/movement_config.h @@ -29,8 +29,10 @@ const watch_face_t watch_faces[] = { simple_clock_face, - beats_face, - voltage_face, + world_clock_face, + sunrise_sunset_face, + moon_phase_face, + thermistor_readout_face, preferences_face, set_time_face, }; diff --git a/watch-library/simulator/watch/watch_adc.c b/watch-library/simulator/watch/watch_adc.c index 364e211..b03d68c 100644 --- a/watch-library/simulator/watch/watch_adc.c +++ b/watch-library/simulator/watch/watch_adc.c @@ -29,7 +29,7 @@ void watch_enable_adc(void) {} void watch_enable_analog_input(const uint8_t pin) {} uint16_t watch_get_analog_pin_level(const uint8_t pin) { - return 0; + return 32767; // pretend it's half of VCC } void watch_set_analog_num_samples(uint16_t samples) {} From dd3e6c5fc37fe2dd42808797400406867e204d7d Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 2 Apr 2022 10:12:26 -0400 Subject: [PATCH 16/45] time set: fix PM not appearing at noon in 12h mode --- movement/watch_faces/settings/set_time_face.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/movement/watch_faces/settings/set_time_face.c b/movement/watch_faces/settings/set_time_face.c index f0e7dc6..af5421f 100644 --- a/movement/watch_faces/settings/set_time_face.c +++ b/movement/watch_faces/settings/set_time_face.c @@ -102,8 +102,8 @@ bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, v sprintf(buf, "%s %2d%02d%02d", set_time_face_titles[current_page], date_time.unit.hour, date_time.unit.minute, date_time.unit.second); } else { sprintf(buf, "%s %2d%02d%02d", set_time_face_titles[current_page], (date_time.unit.hour % 12) ? (date_time.unit.hour % 12) : 12, date_time.unit.minute, date_time.unit.second); - if (date_time.unit.hour > 12) watch_set_indicator(WATCH_INDICATOR_PM); - else watch_clear_indicator(WATCH_INDICATOR_PM); + if (date_time.unit.hour < 12) watch_clear_indicator(WATCH_INDICATOR_PM); + else watch_set_indicator(WATCH_INDICATOR_PM); } } else if (current_page < 6) { watch_clear_colon(); From f7ab99bb69baccee092b93f653e087364938f26b Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 3 Apr 2022 15:47:26 -0400 Subject: [PATCH 17/45] moon phase: light LED on press like other faces --- movement/watch_faces/complication/moon_phase_face.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/movement/watch_faces/complication/moon_phase_face.c b/movement/watch_faces/complication/moon_phase_face.c index 0ff7b25..eb91937 100644 --- a/movement/watch_faces/complication/moon_phase_face.c +++ b/movement/watch_faces/complication/moon_phase_face.c @@ -158,7 +158,7 @@ bool moon_phase_face_loop(movement_event_t event, movement_settings_t *settings, case EVENT_MODE_BUTTON_UP: movement_move_to_next_face(); break; - case EVENT_LIGHT_BUTTON_UP: + case EVENT_LIGHT_BUTTON_DOWN: movement_illuminate_led(); break; case EVENT_ALARM_BUTTON_UP: From 1ec1f2e4207405d55c34c936e2c458cb4a7e8806 Mon Sep 17 00:00:00 2001 From: Wesley Ellis Date: Wed, 6 Apr 2022 14:33:24 -0400 Subject: [PATCH 18/45] Add tomato face: a pomodoro style timer (#61) --- movement/make/Makefile | 1 + movement/movement_faces.h | 1 + .../watch_faces/complication/countdown_face.c | 10 +- .../watch_faces/complication/tomato_face.c | 191 ++++++++++++++++++ .../watch_faces/complication/tomato_face.h | 63 ++++++ watch-library/shared/watch/watch_utility.c | 8 + watch-library/shared/watch/watch_utility.h | 8 + 7 files changed, 273 insertions(+), 9 deletions(-) create mode 100644 movement/watch_faces/complication/tomato_face.c create mode 100644 movement/watch_faces/complication/tomato_face.h diff --git a/movement/make/Makefile b/movement/make/Makefile index 1e52995..0f1e711 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -57,6 +57,7 @@ SRCS += \ ../watch_faces/complication/moon_phase_face.c \ ../watch_faces/complication/orrery_face.c \ ../watch_faces/complication/astronomy_face.c \ + ../watch_faces/complication/tomato_face.c \ # New watch faces go above this line. # Leave this line at the bottom of the file; it has all the targets for making your project. diff --git a/movement/movement_faces.h b/movement/movement_faces.h index 50df00d..66fca61 100644 --- a/movement/movement_faces.h +++ b/movement/movement_faces.h @@ -48,6 +48,7 @@ #include "moon_phase_face.h" #include "orrery_face.h" #include "astronomy_face.h" +#include "tomato_face.h" // New includes go above this line. #endif // MOVEMENT_FACES_H_ diff --git a/movement/watch_faces/complication/countdown_face.c b/movement/watch_faces/complication/countdown_face.c index a910e96..81836f3 100644 --- a/movement/watch_faces/complication/countdown_face.c +++ b/movement/watch_faces/complication/countdown_face.c @@ -35,14 +35,6 @@ #define DEFAULT_MINUTES 3 -static uint32_t offset_date_time(uint32_t now, int8_t hours, int8_t minutes, int8_t seconds) { - uint32_t new = now; - new += hours * 60 * 60; - new += minutes * 60; - new += seconds; - return new; -} - static inline int32_t get_tz_offset(movement_settings_t *settings) { return movement_timezone_offsets[settings->bit.time_zone] * 60; } @@ -52,7 +44,7 @@ static void start(countdown_state_t *state, movement_settings_t *settings) { state->mode = cd_running; state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings)); - state->target_ts = offset_date_time(state->now_ts, 0, state->minutes, state->seconds); + state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, state->minutes, state->seconds); watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, get_tz_offset(settings)); movement_schedule_background_task(target_dt); watch_set_indicator(WATCH_INDICATOR_BELL); diff --git a/movement/watch_faces/complication/tomato_face.c b/movement/watch_faces/complication/tomato_face.c new file mode 100644 index 0000000..37798da --- /dev/null +++ b/movement/watch_faces/complication/tomato_face.c @@ -0,0 +1,191 @@ +/* + * MIT License + * + * Copyright (c) 2022 Wesley Ellis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFtomato_ringEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include "tomato_face.h" +#include "watch_utility.h" + +static uint8_t focus_min = 25; +static uint8_t break_min = 5; + +static inline int32_t get_tz_offset(movement_settings_t *settings) { + return movement_timezone_offsets[settings->bit.time_zone] * 60; +} + +static uint8_t get_length(tomato_state_t *state) { + uint8_t length; + if (state->kind == tomato_focus) { + length = focus_min; + } else { + length = break_min; + } + + return length; +} + +static void tomato_start(tomato_state_t *state, movement_settings_t *settings) { + watch_date_time now = watch_rtc_get_date_time(); + int8_t length = (int8_t) get_length(state); + + state->mode = tomato_run; + state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings)); + state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, length, 0); + watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, get_tz_offset(settings)); + movement_schedule_background_task(target_dt); + watch_set_indicator(WATCH_INDICATOR_BELL); +} + +static void tomato_draw(tomato_state_t *state) { + char buf[16]; + + uint32_t delta; + div_t result; + uint8_t min = 0; + uint8_t sec = 0; + char kind; + + if (state->kind == tomato_break) { + kind = 'b'; + } else { + kind = 'f'; + } + + switch (state->mode) { + case tomato_run: + delta = state->target_ts - state->now_ts; + result = div(delta, 60); + min = result.quot; + sec = result.rem; + break; + case tomato_ready: + min = get_length(state); + sec = 0; + break; + } + sprintf(buf, "TO %c%2d%02d%2d", kind, min, sec, state->done_count); + watch_display_string(buf, 0); +} + +static void tomato_reset(tomato_state_t *state) { + state->mode = tomato_ready; + movement_cancel_background_task(); + watch_clear_indicator(WATCH_INDICATOR_BELL); +} + +static void tomato_ring(tomato_state_t *state) { + movement_play_signal(); + tomato_reset(state); + if (state->kind == tomato_focus) { + state->kind = tomato_break; + state->done_count++; + } else { + state->kind = tomato_focus; + } +} + +void tomato_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(tomato_state_t)); + tomato_state_t *state = (tomato_state_t*)*context_ptr; + memset(*context_ptr, 0, sizeof(tomato_state_t)); + state->mode=tomato_ready; + state->kind= tomato_focus; + state->done_count = 0; + } +} + +void tomato_face_activate(movement_settings_t *settings, void *context) { + tomato_state_t *state = (tomato_state_t *)context; + if (state->mode == tomato_run) { + watch_date_time now = watch_rtc_get_date_time(); + state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings)); + } + watch_set_colon(); +} + +bool tomato_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + tomato_state_t *state = (tomato_state_t *)context; + + switch (event.event_type) { + case EVENT_ACTIVATE: + tomato_draw(state); + break; + case EVENT_TICK: + if (state->mode == tomato_run) { + state->now_ts++; + } + tomato_draw(state); + break; + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_LIGHT_BUTTON_UP: + movement_illuminate_led(); + if (state->mode == tomato_ready) { + if (state->kind == tomato_break) { + state->kind = tomato_focus; + } else { + state->kind = tomato_break; + } + } + tomato_draw(state); + break; + case EVENT_ALARM_BUTTON_UP: + switch(state->mode) { + case tomato_run: + tomato_reset(state); + break; + case tomato_ready: + tomato_start(state, settings); + break; + } + tomato_draw(state); + + break; + case EVENT_ALARM_LONG_PRESS: + state->done_count = 0; + break; + case EVENT_BACKGROUND_TASK: + tomato_ring(state); + tomato_draw(state); + break; + case EVENT_TIMEOUT: + movement_move_to_face(0); + break; + default: + break; + } + + return true; +} + +void tomato_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} + diff --git a/movement/watch_faces/complication/tomato_face.h b/movement/watch_faces/complication/tomato_face.h new file mode 100644 index 0000000..5404ad1 --- /dev/null +++ b/movement/watch_faces/complication/tomato_face.h @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2022 Wesley Ellis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef TOMATO_FACE_H_ +#define TOMATO_FACE_H_ + +#include "movement.h" + +typedef enum { + tomato_ready, + tomato_run, + // to_pause, // TODO implement pausing +} tomato_mode; + +typedef enum { + tomato_break, + tomato_focus, +} tomato_kind; + +typedef struct { + uint32_t target_ts; + uint32_t now_ts; + tomato_mode mode; + tomato_kind kind; + uint8_t done_count; +} tomato_state_t; + +void tomato_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void tomato_face_activate(movement_settings_t *settings, void *context); +bool tomato_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void tomato_face_resign(movement_settings_t *settings, void *context); + +#define tomato_face ((const watch_face_t){ \ + tomato_face_setup, \ + tomato_face_activate, \ + tomato_face_loop, \ + tomato_face_resign, \ + NULL, \ +}) + +#endif // TOMATO_FACE_H_ + diff --git a/watch-library/shared/watch/watch_utility.c b/watch-library/shared/watch/watch_utility.c index 3f8aa61..252624b 100644 --- a/watch-library/shared/watch/watch_utility.c +++ b/watch-library/shared/watch/watch_utility.c @@ -188,3 +188,11 @@ float watch_utility_thermistor_temperature(uint16_t value, bool highside, float return reading; } + +uint32_t watch_utility_offset_timestamp(uint32_t now, int8_t hours, int8_t minutes, int8_t seconds) { + uint32_t new = now; + new += hours * 60 * 60; + new += minutes * 60; + new += seconds; + return new; +} diff --git a/watch-library/shared/watch/watch_utility.h b/watch-library/shared/watch/watch_utility.h index 4c50cb5..57bcbed 100644 --- a/watch-library/shared/watch/watch_utility.h +++ b/watch-library/shared/watch/watch_utility.h @@ -124,4 +124,12 @@ watch_date_time watch_utility_date_time_convert_zone(watch_date_time date_time, */ float watch_utility_thermistor_temperature(uint16_t value, bool highside, float b_coefficient, float nominal_temperature, float nominal_resistance, float series_resistance); +/** @brief Offset a timestamp by a given amount + * @param now Timestamp to offset from + * @param hours Number of hours to offset + * @param minutes Nmber of minutes to offset + * @param seconds Number of secodns to offset + */ +uint32_t watch_utility_offset_timestamp(uint32_t now, int8_t hours, int8_t minutes, int8_t seconds); + #endif From 8b0ebab65bcc82d45201bdef4b9c4e145b54b7d7 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 6 Apr 2022 15:12:37 -0400 Subject: [PATCH 19/45] Revert "make lowercase s look distinct" This reverts commit 2cba47996ed08c83b7c9b2ba521b68fb8a62f666. --- watch-library/shared/watch/watch_private_display.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch-library/shared/watch/watch_private_display.h b/watch-library/shared/watch/watch_private_display.h index c55ea33..0859784 100644 --- a/watch-library/shared/watch/watch_private_display.h +++ b/watch-library/shared/watch/watch_private_display.h @@ -112,7 +112,7 @@ static const uint8_t Character_Set[] = 0b01110011, // p 0b01100111, // q 0b01010000, // r - 0b00101101, // s (removes middle segment to distinguish from 5) + 0b01101101, // s 0b01111000, // t 0b01100010, // u (appears in (u)pper half to work in more positions) 0b00011100, // v (looks like u but in the lower half) From 5f0ebd8c66b3512d67efc8174c5f65a86488a4ea Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 6 Apr 2022 15:51:06 -0400 Subject: [PATCH 20/45] character map tweaks: add some ligatures and symbols --- movement/watch_faces/complication/pulsometer_face.c | 2 +- .../watch_faces/complication/sunrise_sunset_face.c | 4 ++-- watch-library/shared/watch/watch_private_display.h | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/movement/watch_faces/complication/pulsometer_face.c b/movement/watch_faces/complication/pulsometer_face.c index 28ca1a5..1d6f208 100644 --- a/movement/watch_faces/complication/pulsometer_face.c +++ b/movement/watch_faces/complication/pulsometer_face.c @@ -73,7 +73,7 @@ bool pulsometer_face_loop(movement_event_t event, movement_settings_t *settings, watch_display_string(" Alarn", 4); break; case 2: - watch_display_string("+ Count ", 0); + watch_display_string("* Count ", 0); break; case 3: watch_display_string(" 30Beats ", 0); diff --git a/movement/watch_faces/complication/sunrise_sunset_face.c b/movement/watch_faces/complication/sunrise_sunset_face.c index fef9b4d..8dea812 100644 --- a/movement/watch_faces/complication/sunrise_sunset_face.c +++ b/movement/watch_faces/complication/sunrise_sunset_face.c @@ -188,10 +188,10 @@ static void _sunrise_sunset_face_update_settings_display(movement_event_t event, switch (state->page) { case 1: - sprintf(buf, "LA %c %04d", state->working_latitude.sign ? '-' : 'F', abs(_sunrise_sunset_face_latlon_from_struct(state->working_latitude))); // F looks sorta like a plus sign in position 1 + sprintf(buf, "LA %c %04d", state->working_latitude.sign ? '-' : '+', abs(_sunrise_sunset_face_latlon_from_struct(state->working_latitude))); break; case 2: - sprintf(buf, "LO %c%05d", state->working_longitude.sign ? '-' : 'F', abs(_sunrise_sunset_face_latlon_from_struct(state->working_longitude))); + sprintf(buf, "LO %c%05d", state->working_longitude.sign ? '-' : '+', abs(_sunrise_sunset_face_latlon_from_struct(state->working_longitude))); break; } if (event.subsecond % 2) { diff --git a/watch-library/shared/watch/watch_private_display.h b/watch-library/shared/watch/watch_private_display.h index 0859784..11219cf 100644 --- a/watch-library/shared/watch/watch_private_display.h +++ b/watch-library/shared/watch/watch_private_display.h @@ -33,14 +33,14 @@ static const uint8_t Character_Set[] = 0b01100000, // ! (L in the top half for positions 4 and 6) 0b00100010, // " 0b01100011, // # (degree symbol, hash mark doesn't fit) - 0b00000000, // $ (unused) + 0b00101101, // $ (S without the center segment) 0b00000000, // % (unused) 0b01000100, // & ("lowercase 7" for positions 4 and 6) 0b00100000, // ' 0b00111001, // ( 0b00001111, // ) - 0b00000000, // * (unused) - 0b11000000, // + (only works in position 0) + 0b11000000, // * (The + sign for use in position 0) + 0b01110000, // + (segments E, F and G; looks like ┣╸) 0b00000100, // , 0b01000000, // - 0b01000000, // . (same as -, semantically most useful) @@ -120,9 +120,9 @@ static const uint8_t Character_Set[] = 0b01111110, // x 0b01101110, // y 0b00011011, // z - 0b00111001, // { - 0b00110000, // | - 0b00001111, // } + 0b00010110, // { (open brace doesn't really work; overriden to represent the two character ligature "il") + 0b00110110, // | (overriden to represent the two character ligature "ll") + 0b00110100, // } (overriden to represent the two character ligature "li") 0b00000001, // ~ }; From cb609389ebb983cff60af99f7380431d77eaa046 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 6 Apr 2022 15:54:31 -0400 Subject: [PATCH 21/45] mars clock: use S without cross-stroke for clarity --- movement/watch_faces/clock/mars_time_face.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/movement/watch_faces/clock/mars_time_face.c b/movement/watch_faces/clock/mars_time_face.c index 609d461..8695ecf 100644 --- a/movement/watch_faces/clock/mars_time_face.c +++ b/movement/watch_faces/clock/mars_time_face.c @@ -92,7 +92,7 @@ static void _update(movement_settings_t *settings, mars_time_state_t *state) { // TODO: this is not right, mission sol should turn over at midnight local time? uint16_t sol = floor(msd) - landing_sols[state->current_site]; if (sol < 1000) sprintf(&buf[0], "%s Sol%3d", site_names[state->current_site], sol); - else sprintf(&buf[0], "%s s%6d", site_names[state->current_site], sol); + else sprintf(&buf[0], "%s $%6d", site_names[state->current_site], sol); watch_clear_colon(); watch_clear_indicator(WATCH_INDICATOR_24H); } else { From c4de155083d1f5574138976d7d697e572dc12a03 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 6 Apr 2022 15:55:06 -0400 Subject: [PATCH 22/45] mars clock: formatting --- movement/watch_faces/clock/mars_time_face.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/movement/watch_faces/clock/mars_time_face.c b/movement/watch_faces/clock/mars_time_face.c index 8695ecf..7753ae7 100644 --- a/movement/watch_faces/clock/mars_time_face.c +++ b/movement/watch_faces/clock/mars_time_face.c @@ -94,13 +94,13 @@ static void _update(movement_settings_t *settings, mars_time_state_t *state) { if (sol < 1000) sprintf(&buf[0], "%s Sol%3d", site_names[state->current_site], sol); else sprintf(&buf[0], "%s $%6d", site_names[state->current_site], sol); watch_clear_colon(); - watch_clear_indicator(WATCH_INDICATOR_24H); + watch_clear_indicator(WATCH_INDICATOR_24H); } else { mars_clock_hms_t mars_time; _h_to_hms(&mars_time, lmt); sprintf(&buf[0], "%s %02d%02d%02d", site_names[state->current_site], mars_time.hour, mars_time.minute, mars_time.second); watch_set_colon(); - watch_set_indicator(WATCH_INDICATOR_24H); + watch_set_indicator(WATCH_INDICATOR_24H); } watch_display_string(buf, 0); From 092e760d22c1a8e70a86d16fd3fe3d9d4819d922 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 12:45:21 -0400 Subject: [PATCH 23/45] add rule for static analysis --- rules.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rules.mk b/rules.mk index 1aa135a..2f2f392 100644 --- a/rules.mk +++ b/rules.mk @@ -4,6 +4,8 @@ OBJS = $(addprefix $(BUILD)/, $(notdir %/$(subst .c,.o, $(SRCS)))) SUBMODULES = tinyusb +COBRA = cobra -f + ifndef EMSCRIPTEN all: directory $(SUBMODULES) $(BUILD)/$(BIN).elf $(BUILD)/$(BIN).hex $(BUILD)/$(BIN).bin $(BUILD)/$(BIN).uf2 size else @@ -54,4 +56,7 @@ clean: @echo clean @-rm -rf $(BUILD) +analyze: + @$(COBRA) basic $(INCLUDES) $(DEFINES) $(SRCS) + -include $(wildcard $(BUILD)/*.d) From d502a030e1f17b7f805c4e0144dcde5aaec79a66 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 14:38:15 -0400 Subject: [PATCH 24/45] charset tweaks: no need to run deeper checks --- .../shared/watch/watch_private_display.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/watch-library/shared/watch/watch_private_display.c b/watch-library/shared/watch/watch_private_display.c index 1454a3b..474e5ff 100644 --- a/watch-library/shared/watch/watch_private_display.c +++ b/watch-library/shared/watch/watch_private_display.c @@ -53,14 +53,14 @@ void watch_display_character(uint8_t character, uint8_t position) { } if (position == 1) { if (character == 'a') character = 'A'; // A needs to be uppercase - if (character == 'o') character = 'O'; // O needs to be uppercase - if (character == 'i') character = 'l'; // I needs to be uppercase (use an l, it looks the same) - if (character == 'n') character = 'N'; // N needs to be uppercase - if (character == 'r') character = 'R'; // R needs to be uppercase - if (character == 'd') character = 'D'; // D needs to be uppercase - if (character == 'v' || character == 'V' || character == 'u') character = 'U'; // side segments shared, make uppercase - if (character == 'b') character = 'B'; // B needs to be uppercase - if (character == 'c') character = 'C'; // C needs to be uppercase + else if (character == 'o') character = 'O'; // O needs to be uppercase + else if (character == 'i') character = 'l'; // I needs to be uppercase (use an l, it looks the same) + else if (character == 'n') character = 'N'; // N needs to be uppercase + else if (character == 'r') character = 'R'; // R needs to be uppercase + else if (character == 'd') character = 'D'; // D needs to be uppercase + else if (character == 'v' || character == 'V' || character == 'u') character = 'U'; // side segments shared, make uppercase + else if (character == 'b') character = 'B'; // B needs to be uppercase + else if (character == 'c') character = 'C'; // C needs to be uppercase } else { if (character == 'R') character = 'r'; // R needs to be lowercase almost everywhere } From 5cb68923b9cf27e72a55f5533b9f4045c75eda72 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 14:45:21 -0400 Subject: [PATCH 25/45] static analysis: use parentheses around binary operators --- movement/watch_faces/clock/simple_clock_face.c | 4 ++-- movement/watch_faces/clock/world_clock_face.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/movement/watch_faces/clock/simple_clock_face.c b/movement/watch_faces/clock/simple_clock_face.c index ac9e2a1..23f3667 100644 --- a/movement/watch_faces/clock/simple_clock_face.c +++ b/movement/watch_faces/clock/simple_clock_face.c @@ -82,11 +82,11 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting // ...and set the LAP indicator if low. if (state->battery_low) watch_set_indicator(WATCH_INDICATOR_LAP); - if (date_time.reg >> 6 == previous_date_time >> 6 && event.event_type != EVENT_LOW_ENERGY_UPDATE) { + if ((date_time.reg >> 6) == (previous_date_time >> 6) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { // everything before seconds is the same, don't waste cycles setting those segments. pos = 8; sprintf(buf, "%02d", date_time.unit.second); - } else if (date_time.reg >> 12 == previous_date_time >> 12 && event.event_type != EVENT_LOW_ENERGY_UPDATE) { + } else if ((date_time.reg >> 12) == (previous_date_time >> 12) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { // everything before minutes is the same. pos = 6; sprintf(buf, "%02d%02d", date_time.unit.minute, date_time.unit.second); diff --git a/movement/watch_faces/clock/world_clock_face.c b/movement/watch_faces/clock/world_clock_face.c index f0f7e95..1d09a4c 100644 --- a/movement/watch_faces/clock/world_clock_face.c +++ b/movement/watch_faces/clock/world_clock_face.c @@ -71,11 +71,11 @@ static bool world_clock_face_do_display_mode(movement_event_t event, movement_se previous_date_time = state->previous_date_time; state->previous_date_time = date_time.reg; - if (date_time.reg >> 6 == previous_date_time >> 6 && event.event_type != EVENT_LOW_ENERGY_UPDATE) { + if ((date_time.reg >> 6) == (previous_date_time >> 6) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { // everything before seconds is the same, don't waste cycles setting those segments. pos = 8; sprintf(buf, "%02d", date_time.unit.second); - } else if (date_time.reg >> 12 == previous_date_time >> 12 && event.event_type != EVENT_LOW_ENERGY_UPDATE) { + } else if ((date_time.reg >> 12) == (previous_date_time >> 12) && event.event_type != EVENT_LOW_ENERGY_UPDATE) { // everything before minutes is the same. pos = 6; sprintf(buf, "%02d%02d", date_time.unit.minute, date_time.unit.second); From 7b06d7d6fdbbf282ea32cfd0871e6b0310a08d0c Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 14:51:13 -0400 Subject: [PATCH 26/45] static analysis: make __write static to avoid confusion --- movement/lib/TOTP-MCU/sha1.c | 12 ++++++------ movement/lib/TOTP-MCU/sha1.h | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/movement/lib/TOTP-MCU/sha1.c b/movement/lib/TOTP-MCU/sha1.c index 21a24fa..3dc0219 100644 --- a/movement/lib/TOTP-MCU/sha1.c +++ b/movement/lib/TOTP-MCU/sha1.c @@ -84,7 +84,7 @@ static void addUncounted(uint8_t data) { } } -void write(uint8_t data) { +static void __write(uint8_t data) { ++byteCount; addUncounted(data); @@ -93,7 +93,7 @@ void write(uint8_t data) { void writeArray(uint8_t *buffer, uint8_t size){ while (size--) { - write(*buffer++); + __write(*buffer++); } } @@ -144,7 +144,7 @@ void initHmac(const uint8_t* key, uint8_t keyLength) { if (keyLength > BLOCK_LENGTH) { // Hash long keys init(); - for (;keyLength--;) write(*key++); + for (;keyLength--;) __write(*key++); memcpy(keyBuffer,result(),HASH_LENGTH); } else { // Block length keys are used as is @@ -153,7 +153,7 @@ void initHmac(const uint8_t* key, uint8_t keyLength) { // Start inner hash init(); for (i=0; i Date: Sun, 10 Apr 2022 15:07:58 -0400 Subject: [PATCH 27/45] static analysis: add comments to empty while loops --- watch-library/hardware/watch/watch_adc.c | 2 +- watch-library/hardware/watch/watch_deepsleep.c | 2 +- watch-library/hardware/watch/watch_private.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/watch-library/hardware/watch/watch_adc.c b/watch-library/hardware/watch/watch_adc.c index c8c4d65..476f0cb 100644 --- a/watch-library/hardware/watch/watch_adc.c +++ b/watch-library/hardware/watch/watch_adc.c @@ -36,7 +36,7 @@ static uint16_t _watch_get_analog_value(uint16_t channel) { } ADC->SWTRIG.bit.START = 1; - while (!ADC->INTFLAG.bit.RESRDY); + while (!ADC->INTFLAG.bit.RESRDY); // wait for "result ready" flag return ADC->RESULT.reg; } diff --git a/watch-library/hardware/watch/watch_deepsleep.c b/watch-library/hardware/watch/watch_deepsleep.c index e3f654f..b1b5b2c 100644 --- a/watch-library/hardware/watch/watch_deepsleep.c +++ b/watch-library/hardware/watch/watch_deepsleep.c @@ -69,7 +69,7 @@ void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool le // disable the RTC RTC->MODE2.CTRLA.bit.ENABLE = 0; - while (RTC->MODE2.SYNCBUSY.bit.ENABLE); + while (RTC->MODE2.SYNCBUSY.bit.ENABLE); // wait for RTC to be disabled // update the configuration RTC->MODE2.TAMPCTRL.reg = config; diff --git a/watch-library/hardware/watch/watch_private.c b/watch-library/hardware/watch/watch_private.c index 241ff40..2bb3d81 100644 --- a/watch-library/hardware/watch/watch_private.c +++ b/watch-library/hardware/watch/watch_private.c @@ -35,7 +35,7 @@ void _watch_init(void) { // Use switching regulator for lower power consumption. SUPC->VREG.bit.SEL = 1; - while(!SUPC->STATUS.bit.VREGRDY); + while(!SUPC->STATUS.bit.VREGRDY); // wait for voltage regulator to become ready // check the battery voltage... watch_enable_adc(); @@ -63,7 +63,7 @@ void _watch_init(void) { SUPC->BOD33.bit.LEVEL = 34; // Detect brownout at 2.6V (1.445V + level * 34mV) SUPC->BOD33.bit.ACTION = 0x2; // Generate an interrupt when BOD33 is triggered SUPC->BOD33.bit.HYST = 0; // Disable hysteresis - while(!SUPC->STATUS.bit.B33SRDY); + while(!SUPC->STATUS.bit.B33SRDY); // wait for BOD33 to sync // Enable interrupt on BOD33 detect SUPC->INTENSET.bit.BOD33DET = 1; @@ -198,7 +198,7 @@ void _watch_enable_usb(void) { // assign DFLL to GCLK1 GCLK->GENCTRL[1].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL48M) | GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_GENEN;// | GCLK_GENCTRL_OE; - while (GCLK->SYNCBUSY.bit.GENCTRL1); + while (GCLK->SYNCBUSY.bit.GENCTRL1); // wait for generator control 1 to sync // assign GCLK1 to USB hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); From 35172ce11a184daf409f8d6c03c6844cc5382b71 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 15:18:36 -0400 Subject: [PATCH 28/45] world clock: fix glitch when exiting settings mode --- movement/watch_faces/clock/world_clock_face.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/movement/watch_faces/clock/world_clock_face.c b/movement/watch_faces/clock/world_clock_face.c index 1d09a4c..4004bab 100644 --- a/movement/watch_faces/clock/world_clock_face.c +++ b/movement/watch_faces/clock/world_clock_face.c @@ -44,14 +44,11 @@ void world_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_in } void world_clock_face_activate(movement_settings_t *settings, void *context) { + (void) settings; world_clock_state_t *state = (world_clock_state_t *)context; state->current_screen = 0; - state->previous_date_time = 0xFFFFFFFF; if (watch_tick_animation_is_running()) watch_stop_tick_animation(); - if (settings->bit.clock_mode_24h) watch_set_indicator(WATCH_INDICATOR_24H); - - watch_set_colon(); } static bool world_clock_face_do_display_mode(movement_event_t event, movement_settings_t *settings, world_clock_state_t *state) { @@ -63,6 +60,10 @@ static bool world_clock_face_do_display_mode(movement_event_t event, movement_se watch_date_time date_time; switch (event.event_type) { case EVENT_ACTIVATE: + if (settings->bit.clock_mode_24h) watch_set_indicator(WATCH_INDICATOR_24H); + watch_set_colon(); + state->previous_date_time = 0xFFFFFFFF; + // fall through case EVENT_TICK: case EVENT_LOW_ENERGY_UPDATE: date_time = watch_rtc_get_date_time(); @@ -140,9 +141,9 @@ static bool _world_clock_face_do_settings_mode(movement_event_t event, movement_ if (state->current_screen > 3) { movement_request_tick_frequency(1); state->current_screen = 0; - state->previous_date_time = 0xFFFFFFFF; if (state->backup_register) watch_store_backup_data(state->settings.reg, state->backup_register); - world_clock_face_do_display_mode(event, settings, state); + event.event_type = EVENT_ACTIVATE; + return world_clock_face_do_display_mode(event, settings, state); } break; case EVENT_ALARM_BUTTON_DOWN: From 6bdaff5d2abaeb614e98de2c9e5d0a02b439fa8f Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 15:56:45 -0400 Subject: [PATCH 29/45] remove all deprecated functions --- .../hardware/watch/watch_deepsleep.c | 12 ---- watch-library/hardware/watch/watch_extint.c | 8 --- watch-library/hardware/watch/watch_led.c | 10 --- watch-library/hardware/watch/watch_private.c | 9 --- watch-library/hardware/watch/watch_rtc.c | 37 ---------- watch-library/hardware/watch/watch_uart.c | 67 ------------------- watch-library/shared/watch/watch_deepsleep.h | 5 -- watch-library/shared/watch/watch_extint.h | 5 -- watch-library/shared/watch/watch_led.h | 5 -- watch-library/shared/watch/watch_rtc.h | 19 ------ watch-library/shared/watch/watch_uart.h | 19 ------ .../simulator/watch/watch_deepsleep.c | 12 ---- watch-library/simulator/watch/watch_extint.c | 8 --- watch-library/simulator/watch/watch_led.c | 10 --- watch-library/simulator/watch/watch_private.c | 9 --- watch-library/simulator/watch/watch_rtc.c | 29 -------- watch-library/simulator/watch/watch_uart.c | 11 --- 17 files changed, 275 deletions(-) diff --git a/watch-library/hardware/watch/watch_deepsleep.c b/watch-library/hardware/watch/watch_deepsleep.c index b1b5b2c..ae2ad31 100644 --- a/watch-library/hardware/watch/watch_deepsleep.c +++ b/watch-library/hardware/watch/watch_deepsleep.c @@ -192,15 +192,3 @@ void watch_enter_backup_mode(void) { // go into backup sleep mode (5). when we exit, the reset controller will take over. sleep(5); } - -// deprecated -void watch_enter_shallow_sleep(bool display_on) { - if (display_on) watch_enter_sleep_mode(); - else watch_enter_deep_sleep_mode(); -} - -// deprecated -void watch_enter_deep_sleep(void) { - watch_register_extwake_callback(BTN_ALARM, NULL, true); - watch_enter_backup_mode(); -} diff --git a/watch-library/hardware/watch/watch_extint.c b/watch-library/hardware/watch/watch_extint.c index 5924b64..13e8eaa 100644 --- a/watch-library/hardware/watch/watch_extint.c +++ b/watch-library/hardware/watch/watch_extint.c @@ -101,11 +101,3 @@ void watch_register_interrupt_callback(const uint8_t pin, ext_irq_cb_t callback, ext_irq_register(pin, callback); } - -inline void watch_register_button_callback(const uint8_t pin, ext_irq_cb_t callback) { - watch_register_interrupt_callback(pin, callback, INTERRUPT_TRIGGER_RISING); -} - -inline void watch_enable_buttons(void) { - watch_enable_external_interrupts(); -} diff --git a/watch-library/hardware/watch/watch_led.c b/watch-library/hardware/watch/watch_led.c index 52174b5..5e2d8ec 100644 --- a/watch-library/hardware/watch/watch_led.c +++ b/watch-library/hardware/watch/watch_led.c @@ -34,16 +34,6 @@ void watch_disable_leds(void) { _watch_disable_tcc(); } -void watch_enable_led(bool unused) { - (void)unused; - watch_enable_leds(); -} - -void watch_disable_led(bool unused) { - (void)unused; - watch_disable_leds(); -} - void watch_set_led_color(uint8_t red, uint8_t green) { if (hri_tcc_get_CTRLA_reg(TCC0, TCC_CTRLA_ENABLE)) { uint32_t period = hri_tcc_get_PER_reg(TCC0, TCC_PER_MASK); diff --git a/watch-library/hardware/watch/watch_private.c b/watch-library/hardware/watch/watch_private.c index 2bb3d81..e4a0392 100644 --- a/watch-library/hardware/watch/watch_private.c +++ b/watch-library/hardware/watch/watch_private.c @@ -260,15 +260,6 @@ int _read(void) { return 0; } -// Alternate function that outputs to the debug UART. useful for debugging USB issues. -// int _write(int file, char *ptr, int len) { -// (void)file; -// int pos = 0; -// while(pos < len) watch_debug_putc(ptr[pos++]); - -// return 0; -// } - void USB_Handler(void) { tud_int_handler(0); } diff --git a/watch-library/hardware/watch/watch_rtc.c b/watch-library/hardware/watch/watch_rtc.c index 2836052..8382e57 100644 --- a/watch-library/hardware/watch/watch_rtc.c +++ b/watch-library/hardware/watch/watch_rtc.c @@ -160,40 +160,3 @@ void RTC_Handler(void) { RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM0; } } - -/////////////////////// -// Deprecated functions - -void watch_set_date_time(struct calendar_date_time date_time) { - RTC_MODE2_CLOCK_Type val; - - val.bit.SECOND = date_time.time.sec; - val.bit.MINUTE = date_time.time.min; - val.bit.HOUR = date_time.time.hour; - val.bit.DAY = date_time.date.day; - val.bit.MONTH = date_time.date.month; - val.bit.YEAR = (uint8_t)(date_time.date.year - WATCH_RTC_REFERENCE_YEAR); - - RTC->MODE2.CLOCK.reg = val.reg; - - _sync_rtc(); -} - -void watch_get_date_time(struct calendar_date_time *date_time) { - _sync_rtc(); - RTC_MODE2_CLOCK_Type val = RTC->MODE2.CLOCK; - - date_time->time.sec = val.bit.SECOND; - date_time->time.min = val.bit.MINUTE; - date_time->time.hour = val.bit.HOUR; - date_time->date.day = val.bit.DAY; - date_time->date.month = val.bit.MONTH; - date_time->date.year = val.bit.YEAR + WATCH_RTC_REFERENCE_YEAR; -} - -void watch_register_tick_callback(ext_irq_cb_t callback) { - tick_callbacks[7] = callback; - NVIC_ClearPendingIRQ(RTC_IRQn); - NVIC_EnableIRQ(RTC_IRQn); - RTC->MODE2.INTENSET.reg = RTC_MODE2_INTENSET_PER7; -} diff --git a/watch-library/hardware/watch/watch_uart.c b/watch-library/hardware/watch/watch_uart.c index c8e0600..3aee7e3 100644 --- a/watch-library/hardware/watch/watch_uart.c +++ b/watch-library/hardware/watch/watch_uart.c @@ -116,70 +116,3 @@ char watch_uart_getc(void) { io_read(uart_io, &retval, 1); return retval; } - -// Begin deprecated functions - - /* - * UART methods are Copyright (c) 2014-2017, Alex Taradov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "peripheral_clk_config.h" - -void watch_enable_debug_uart(uint32_t baud) { - uint64_t br = (uint64_t)65536 * ((CONF_CPU_FREQUENCY * 4) - 16 * baud) / (CONF_CPU_FREQUENCY * 4); - - gpio_set_pin_direction(A2, GPIO_DIRECTION_OUT); - gpio_set_pin_function(A2, PINMUX_PB02C_SERCOM3_PAD0); - - MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3; - - GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN; - while (0 == (GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN)); - - SERCOM3->USART.CTRLA.reg = - SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*USART_INT_CLK*/) | - SERCOM_USART_CTRLA_RXPO(1/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(0/*PAD0*/); - - SERCOM3->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | - SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/); - - SERCOM3->USART.BAUD.reg = (uint16_t)br; - - SERCOM3->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; -} - -void watch_debug_putc(char c) { - while (!(SERCOM3->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)); - SERCOM3->USART.DATA.reg = c; -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -void watch_debug_puts(char *s) { - while (*s) watch_debug_putc(*s++); -} -#pragma GCC diagnostic pop diff --git a/watch-library/shared/watch/watch_deepsleep.h b/watch-library/shared/watch/watch_deepsleep.h index f3ba709..75a0a3d 100644 --- a/watch-library/shared/watch/watch_deepsleep.h +++ b/watch-library/shared/watch/watch_deepsleep.h @@ -151,10 +151,5 @@ void watch_enter_deep_sleep_mode(void); */ void watch_enter_backup_mode(void); -__attribute__((deprecated("Use watch_enter_sleep_mode or watch_enter_deep_sleep_mode instead"))) -void watch_enter_shallow_sleep(bool display_on); - -__attribute__((deprecated("Use watch_enter_backup_mode instead"))) -void watch_enter_deep_sleep(void); /// @} #endif diff --git a/watch-library/shared/watch/watch_extint.h b/watch-library/shared/watch/watch_extint.h index 452461b..84194e9 100644 --- a/watch-library/shared/watch/watch_extint.h +++ b/watch-library/shared/watch/watch_extint.h @@ -76,10 +76,5 @@ void watch_disable_external_interrupts(void); */ void watch_register_interrupt_callback(const uint8_t pin, ext_irq_cb_t callback, watch_interrupt_trigger trigger); -__attribute__((deprecated("Use watch_register_interrupt_callback or watch_register_extwake_callback instead"))) -void watch_register_button_callback(const uint8_t pin, ext_irq_cb_t callback); - -__attribute__((deprecated("Use watch_enable_external_interrupts instead"))) -void watch_enable_buttons(void); /// @} #endif diff --git a/watch-library/shared/watch/watch_led.h b/watch-library/shared/watch/watch_led.h index 9e9f564..7e2dea2 100644 --- a/watch-library/shared/watch/watch_led.h +++ b/watch-library/shared/watch/watch_led.h @@ -84,10 +84,5 @@ void watch_set_led_yellow(void); /** @brief Turns both the red and the green LEDs off. */ void watch_set_led_off(void); -__attribute__((deprecated("Use watch_enable_leds instead"))) -void watch_enable_led(bool unused); - -__attribute__((deprecated("Use watch_disable_leds instead"))) -void watch_disable_led(bool unused); /// @} #endif diff --git a/watch-library/shared/watch/watch_rtc.h b/watch-library/shared/watch/watch_rtc.h index 183e6dd..6609e6b 100644 --- a/watch-library/shared/watch/watch_rtc.h +++ b/watch-library/shared/watch/watch_rtc.h @@ -147,24 +147,5 @@ void watch_rtc_disable_matching_periodic_callbacks(uint8_t mask); */ void watch_rtc_disable_all_periodic_callbacks(void); -/** @brief Sets the system date and time. - * @param date_time A struct representing the date and time you wish to set. - */ -__attribute__((deprecated("Use watch_rtc_set_date_time function instead"))) -void watch_set_date_time(struct calendar_date_time date_time); - -/** @brief Returns the system date and time in the provided struct. - * @param date_time A pointer to a calendar_date_time struct. It will have with the correct date and time on return. - */ -__attribute__((deprecated("Use the watch_rtc_get_date_time function instead"))) -void watch_get_date_time(struct calendar_date_time *date_time); - -/** @brief Registers a "tick" callback that will be called once per second. - * @param callback The function you wish to have called when the clock ticks. If you pass in NULL, the tick - * interrupt will still be enabled, but no callback function will be called. - */ -__attribute__((deprecated("Use the watch_rtc_register_tick_callback function instead"))) -void watch_register_tick_callback(ext_irq_cb_t callback); - /// @} #endif diff --git a/watch-library/shared/watch/watch_uart.h b/watch-library/shared/watch/watch_uart.h index 79fcd53..3d7ee77 100644 --- a/watch-library/shared/watch/watch_uart.h +++ b/watch-library/shared/watch/watch_uart.h @@ -52,24 +52,5 @@ void watch_uart_puts(char *s); */ char watch_uart_getc(void); -// Begin deprecated functions: - -/** @brief Initializes the debug UART. - * @param baud The baud rate - */ -__attribute__((deprecated("Use watch_enable_uart to enable the UART."))) -void watch_enable_debug_uart(uint32_t baud); - -/** @brief Outputs a single character on the debug UART. - * @param c The character you wish to output. - */ -__attribute__((deprecated("Use watch_uart_puts to print to the UART, or printf to log debug messages over USB."))) -void watch_debug_putc(char c); - -/** @brief Outputs a string on the debug UART. - * @param s A null-terminated string. - */ -__attribute__((deprecated("Use watch_uart_puts to print to the UART, or printf to log debug messages over USB."))) -void watch_debug_puts(char *s); /// @} #endif diff --git a/watch-library/simulator/watch/watch_deepsleep.c b/watch-library/simulator/watch/watch_deepsleep.c index a12cf2a..5add05e 100644 --- a/watch-library/simulator/watch/watch_deepsleep.c +++ b/watch-library/simulator/watch/watch_deepsleep.c @@ -86,15 +86,3 @@ void watch_enter_backup_mode(void) { // go into backup sleep mode (5). when we exit, the reset controller will take over. // sleep(5); } - -// deprecated -void watch_enter_shallow_sleep(bool display_on) { - if (display_on) watch_enter_sleep_mode(); - else watch_enter_deep_sleep_mode(); -} - -// deprecated -void watch_enter_deep_sleep(void) { - watch_register_extwake_callback(BTN_ALARM, NULL, true); - watch_enter_backup_mode(); -} diff --git a/watch-library/simulator/watch/watch_extint.c b/watch-library/simulator/watch/watch_extint.c index 03abe42..cbba4c3 100644 --- a/watch-library/simulator/watch/watch_extint.c +++ b/watch-library/simulator/watch/watch_extint.c @@ -181,11 +181,3 @@ void watch_register_interrupt_callback(const uint8_t pin, ext_irq_cb_t callback, external_interrupt_alarm_trigger = trigger; } } - -void watch_register_button_callback(const uint8_t pin, ext_irq_cb_t callback) { - watch_register_interrupt_callback(pin, callback, INTERRUPT_TRIGGER_RISING); -} - -void watch_enable_buttons(void) { - watch_enable_external_interrupts(); -} diff --git a/watch-library/simulator/watch/watch_led.c b/watch-library/simulator/watch/watch_led.c index 173f1b0..068da8b 100644 --- a/watch-library/simulator/watch/watch_led.c +++ b/watch-library/simulator/watch/watch_led.c @@ -30,16 +30,6 @@ void watch_enable_leds(void) {} void watch_disable_leds(void) {} -void watch_enable_led(bool unused) { - (void)unused; - watch_enable_leds(); -} - -void watch_disable_led(bool unused) { - (void)unused; - watch_disable_leds(); -} - void watch_set_led_color(uint8_t red, uint8_t green) { EM_ASM({ document.getElementById('light').style.opacity = $1 / 255; diff --git a/watch-library/simulator/watch/watch_private.c b/watch-library/simulator/watch/watch_private.c index b852893..4ddc218 100644 --- a/watch-library/simulator/watch/watch_private.c +++ b/watch-library/simulator/watch/watch_private.c @@ -67,12 +67,3 @@ int _write(int file, char *ptr, int len) { int _read(void) { return 0; } - -// Alternate function that outputs to the debug UART. useful for debugging USB issues. -// int _write(int file, char *ptr, int len) { -// (void)file; -// int pos = 0; -// while(pos < len) watch_debug_putc(ptr[pos++]); - -// return 0; -// } diff --git a/watch-library/simulator/watch/watch_rtc.c b/watch-library/simulator/watch/watch_rtc.c index ea8659d..107ae56 100644 --- a/watch-library/simulator/watch/watch_rtc.c +++ b/watch-library/simulator/watch/watch_rtc.c @@ -197,32 +197,3 @@ void watch_rtc_disable_alarm_callback(void) { alarm_interval_id = -1; } } - -/////////////////////// -// Deprecated functions - -void watch_set_date_time(struct calendar_date_time date_time) { - watch_date_time val; - val.unit.second = date_time.time.sec; - val.unit.minute = date_time.time.min; - val.unit.hour = date_time.time.hour; - val.unit.day = date_time.date.day; - val.unit.month = date_time.date.month; - val.unit.year = date_time.date.year - WATCH_RTC_REFERENCE_YEAR; - watch_rtc_set_date_time(val); -} - -void watch_get_date_time(struct calendar_date_time *date_time) { - if (date_time == NULL) return; - watch_date_time val = watch_rtc_get_date_time(); - date_time->time.sec = val.unit.second; - date_time->time.min = val.unit.minute; - date_time->time.hour = val.unit.hour; - date_time->date.day = val.unit.day; - date_time->date.month = val.unit.month; - date_time->date.year = val.unit.year + WATCH_RTC_REFERENCE_YEAR; -} - -void watch_register_tick_callback(ext_irq_cb_t callback) { - watch_rtc_register_tick_callback(callback); -} diff --git a/watch-library/simulator/watch/watch_uart.c b/watch-library/simulator/watch/watch_uart.c index 7043383..80c6a81 100644 --- a/watch-library/simulator/watch/watch_uart.c +++ b/watch-library/simulator/watch/watch_uart.c @@ -45,14 +45,3 @@ char watch_uart_getc(void) { } return 0; } - -void watch_enable_debug_uart(uint32_t baud) {} - -void watch_debug_putc(char c) {} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -void watch_debug_puts(char *s) { - while (*s) watch_debug_putc(*s++); -} -#pragma GCC diagnostic pop From 3eb38210090b9d9bbf2ff869c43e670038fe2af3 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 15:57:13 -0400 Subject: [PATCH 30/45] make A1-05 the default board (final hardware) --- make.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make.mk b/make.mk index 851e7e9..528b098 100644 --- a/make.mk +++ b/make.mk @@ -3,7 +3,7 @@ BUILD = ./build BIN = watch ifndef BOARD -override BOARD = OSO-SWAT-A1-04 +override BOARD = OSO-SWAT-A1-05 endif ############################################################################## From d91274e782b17b49bfa639de09dbd988777fec97 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 16:21:12 -0400 Subject: [PATCH 31/45] remove old lis2dh driver --- movement/make/Makefile | 1 - movement/movement_faces.h | 1 - watch-library/shared/driver/lis2dh.c | 143 ----------------- watch-library/shared/driver/lis2dh.h | 222 --------------------------- 4 files changed, 367 deletions(-) delete mode 100644 watch-library/shared/driver/lis2dh.c delete mode 100644 watch-library/shared/driver/lis2dh.h diff --git a/movement/make/Makefile b/movement/make/Makefile index 0f1e711..a773fee 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -44,7 +44,6 @@ SRCS += \ ../watch_faces/sensor/thermistor_testing_face.c \ ../watch_faces/demo/character_set_face.c \ ../watch_faces/demo/voltage_face.c \ - ../watch_faces/demo/lis2dh_logging_face.c \ ../watch_faces/demo/demo_face.c \ ../watch_faces/demo/hello_there_face.c \ ../watch_faces/complication/pulsometer_face.c \ diff --git a/movement/movement_faces.h b/movement/movement_faces.h index 66fca61..d90bf02 100644 --- a/movement/movement_faces.h +++ b/movement/movement_faces.h @@ -39,7 +39,6 @@ #include "voltage_face.h" #include "stopwatch_face.h" #include "totp_face.h" -#include "lis2dh_logging_face.h" #include "demo_face.h" #include "hello_there_face.h" #include "sunrise_sunset_face.h" diff --git a/watch-library/shared/driver/lis2dh.c b/watch-library/shared/driver/lis2dh.c deleted file mode 100644 index 20702bf..0000000 --- a/watch-library/shared/driver/lis2dh.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2021 Joey Castillo - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "lis2dh.h" -#include "watch.h" - -bool lis2dh_begin(void) { - if (lis2dh_get_device_id() != LIS2DH_WHO_AM_I_VAL) { - return false; - } - // Enable all axes, start at lowest possible data rate - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL1, LIS2DH_CTRL1_VAL_XEN | - LIS2DH_CTRL1_VAL_YEN | - LIS2DH_CTRL1_VAL_ZEN | - LIS2DH_CTRL1_VAL_ODR_1HZ); - // Set range to ±2G and enable block data update (output registers not updated until MSB and LSB have been read) - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL4, LIS2DH_CTRL4_VAL_BDU | LIS2DH_RANGE_2_G); - - return true; -} - -uint8_t lis2dh_get_device_id(void) { - return watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_WHO_AM_I); -} - -bool lis2dh_have_new_data(void) { - uint8_t retval = watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_STATUS); - return !!retval; // return true if any bit is set -} - -lis2dh_reading lis2dh_get_raw_reading(void) { - uint8_t buffer[6]; - uint8_t reg = LIS2DH_REG_OUT_X_L | 0x80; // set high bit for consecutive reads - lis2dh_reading retval; - - watch_i2c_send(LIS2DH_ADDRESS, ®, 1); - watch_i2c_receive(LIS2DH_ADDRESS, (uint8_t *)&buffer, 6); - - retval.x = buffer[0]; - retval.x |= ((uint16_t)buffer[1]) << 8; - retval.y = buffer[2]; - retval.y |= ((uint16_t)buffer[3]) << 8; - retval.z = buffer[4]; - retval.z |= ((uint16_t)buffer[5]) << 8; - - return retval; -} - - lis2dh_acceleration_measurement lis2dh_get_acceleration_measurement(lis2dh_reading *out_reading) { - lis2dh_reading reading = lis2dh_get_raw_reading(); - uint8_t range = lis2dh_get_range(); - if (out_reading != NULL) *out_reading = reading; - - // this bit is cribbed from Adafruit's LIS3DH driver; from their notes, the magic number below - // converts from 16-bit lsb to 10-bit and divides by 1k to convert from milli-gs. - // final value is raw_lsb => 10-bit lsb -> milli-gs -> gs - uint8_t lsb_value = 1; - if (range == LIS2DH_RANGE_2_G) lsb_value = 4; - if (range == LIS2DH_RANGE_4_G) lsb_value = 8; - if (range == LIS2DH_RANGE_8_G) lsb_value = 16; - if (range == LIS2DH_RANGE_16_G) lsb_value = 48; - - lis2dh_acceleration_measurement retval; - - retval.x = lsb_value * ((float)reading.x / 64000.0); - retval.y = lsb_value * ((float)reading.y / 64000.0); - retval.z = lsb_value * ((float)reading.z / 64000.0); - - return retval; -} - -void lis2dh_set_range(lis2dh_range_t range) { - uint8_t val = watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL4) & 0xCF; - uint8_t bits = range << 4; - - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL4, val | bits); -} - -lis2dh_range_t lis2dh_get_range(void) { - uint8_t retval = watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL4) & 0x30; - retval >>= 4; - return (lis2dh_range_t)retval; -} - - -void lis2dh_set_data_rate(lis2dh_data_rate_t dataRate) { - uint8_t val = watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL1) & 0x0F; - uint8_t bits = dataRate << 4; - - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL1, val | bits); -} - -lis2dh_data_rate_t lis2dh_get_data_rate(void) { - return watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL1) >> 4; -} - -void lis2dh_configure_aoi_int1(lis2dh_interrupt_configuration configuration, uint8_t threshold, uint8_t duration, bool latch) { - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL3, LIS2DH_CTRL3_VAL_I1_AOI1); - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_INT1_CFG, configuration); - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_INT1_THS, threshold); - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_INT1_DUR, duration); - uint8_t val = watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL5) & 0xF7; - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL5, val | latch ? LIS2DH_CTRL5_VAL_LIR_INT1 : 0); -} - -lis2dh_interrupt_state lis2dh_get_int1_state(void) { - return (lis2dh_interrupt_state) watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_INT1_SRC); -} - -void lis2dh_configure_aoi_int2(lis2dh_interrupt_configuration configuration, uint8_t threshold, uint8_t duration, bool latch) { - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL6, LIS2DH_CTRL6_VAL_I2_INT2); - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_INT2_CFG, configuration); - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_INT2_THS, threshold); - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_INT2_DUR, duration); - uint8_t val = watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL5) & 0xFD; - watch_i2c_write8(LIS2DH_ADDRESS, LIS2DH_REG_CTRL5, val | latch ? LIS2DH_CTRL5_VAL_LIR_INT2 : 0); -} - -lis2dh_interrupt_state lis2dh_get_int2_state(void) { - return (lis2dh_interrupt_state) watch_i2c_read8(LIS2DH_ADDRESS, LIS2DH_REG_INT2_SRC); -} - diff --git a/watch-library/shared/driver/lis2dh.h b/watch-library/shared/driver/lis2dh.h deleted file mode 100644 index 6883151..0000000 --- a/watch-library/shared/driver/lis2dh.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2021 Joey Castillo - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef LIS2DH_H -#define LIS2DH_H - -#include -#include - -typedef struct { - int16_t x; - int16_t y; - int16_t z; -} lis2dh_reading; - -typedef struct { - float x; - float y; - float z; -} lis2dh_acceleration_measurement; - -typedef enum { - LIS2DH_RANGE_16_G = 0b11, // +/- 16g - LIS2DH_RANGE_8_G = 0b10, // +/- 8g - LIS2DH_RANGE_4_G = 0b01, // +/- 4g - LIS2DH_RANGE_2_G = 0b00 // +/- 2g (default value) -} lis2dh_range_t; - -typedef enum { - LIS2DH_DATA_RATE_POWERDOWN = 0, - LIS2DH_DATA_RATE_1_HZ = 0b0001, - LIS2DH_DATA_RATE_10_HZ = 0b0010, - LIS2DH_DATA_RATE_25_HZ = 0b0011, - LIS2DH_DATA_RATE_50_HZ = 0b0100, - LIS2DH_DATA_RATE_100_HZ = 0b0101, - LIS2DH_DATA_RATE_200_HZ = 0b0110, - LIS2DH_DATA_RATE_400_HZ = 0b0111, - LIS2DH_DATA_RATE_LP1620HZ = 0b1000, - LIS2DH_DATA_RATE_LP5376HZ = 0b1001, - -} lis2dh_data_rate_t; - -typedef enum { - LIS2DH_INTERRUPT_CONFIGURATION_OR = 0b00000000, - LIS2DH_INTERRUPT_CONFIGURATION_AND = 0b10000000, - LIS2DH_INTERRUPT_CONFIGURATION_6D_MOVEMENT = 0b01000000, - LIS2DH_INTERRUPT_CONFIGURATION_6D_POSITION = 0b11000000, // in 6D mode, these have an alternate meaning: - LIS2DH_INTERRUPT_CONFIGURATION_Z_HIGH_ENABLE = 0b00100000, // Z up enable - LIS2DH_INTERRUPT_CONFIGURATION_Z_LOW_ENABLE = 0b00010000, // Z down enable - LIS2DH_INTERRUPT_CONFIGURATION_Y_HIGH_ENABLE = 0b00001000, // Y up enable - LIS2DH_INTERRUPT_CONFIGURATION_Y_LOW_ENABLE = 0b00000100, // Y down enable - LIS2DH_INTERRUPT_CONFIGURATION_X_HIGH_ENABLE = 0b00000010, // X up enable - LIS2DH_INTERRUPT_CONFIGURATION_X_LOW_ENABLE = 0b00000001, // X down enable -} lis2dh_interrupt_configuration; - -typedef enum { - LIS2DH_INTERRUPT_STATE_ACTIVE = 0b01000000, - LIS2DH_INTERRUPT_STATE_Z_HIGH = 0b00100000, // Z up - LIS2DH_INTERRUPT_STATE_Z_LOW = 0b00010000, // Z down - LIS2DH_INTERRUPT_STATE_Y_HIGH = 0b00001000, // Y up - LIS2DH_INTERRUPT_STATE_Y_LOW = 0b00000100, // Y down - LIS2DH_INTERRUPT_STATE_X_HIGH = 0b00000010, // X up - LIS2DH_INTERRUPT_STATE_X_LOW = 0b00000001, // X down -} lis2dh_interrupt_state; - -bool lis2dh_begin(void); - -uint8_t lis2dh_get_device_id(void); - -bool lis2dh_have_new_data(void); - -lis2dh_reading lis2dh_get_raw_reading(void); - -lis2dh_acceleration_measurement lis2dh_get_acceleration_measurement(lis2dh_reading *out_reading); - -void lis2dh_set_range(lis2dh_range_t range); - -lis2dh_range_t lis2dh_get_range(void); - -void lis2dh_set_data_rate(lis2dh_data_rate_t dataRate); - -lis2dh_data_rate_t lis2dh_get_data_rate(void); - -void lis2dh_configure_aoi_int1(lis2dh_interrupt_configuration configuration, uint8_t threshold, uint8_t duration, bool latch); - -lis2dh_interrupt_state lis2dh_get_int1_state(void); - -void lis2dh_configure_aoi_int2(lis2dh_interrupt_configuration configuration, uint8_t threshold, uint8_t duration, bool latch); - -lis2dh_interrupt_state lis2dh_get_int2_state(void); - -// Assumes SA0 is high; if low, its 0x18 -#define LIS2DH_ADDRESS (0x19) - -#define LIS2DH_REG_STATUS_AUX 0x07 ///< Auxiliary status register -#define LIS2DH_REG_STATUS_AUX_TDA (1 << 2) ///< Temperature data available -#define LIS2DH_REG_STATUS_AUX_TOR (1 << 6) ///< Temperature data overrun - -#define LIS2DH_REG_OUT_TEMP_L 0x0C ///< Temperature data low bit -#define LIS2DH_REG_OUT_TEMP_H 0x0D ///< Temperature data high bit - -#define LIS2DH_REG_INT_COUNTER 0x0E - -#define LIS2DH_REG_WHO_AM_I 0x0F ///< Device identification, will read 0x33 -#define LIS2DH_WHO_AM_I_VAL 0x33 ///< Expected value of the WHO_AM_I register - -#define LIS2DH_REG_TEMP_CFG 0x1F ///< Temperature configuration; 0 to disable, 0xC0 to enable. -#define LIS2DH_TEMP_CFG_VAL_ENABLE 0xC0 ///< Value for LIS2DH_REG_TEMP_CFG that enables temperature sensing. -#define LIS2DH_TEMP_CFG_VAL_DISABLE 0x00 ///< Value for LIS2DH_REG_TEMP_CFG that disables temperature sensing. - -#define LIS2DH_REG_CTRL1 0x20 ///< CTRL_REG1 in the data sheet. -#define LIS2DH_CTRL1_VAL_XEN 0b00000001 ///< Enable X-axis -#define LIS2DH_CTRL1_VAL_YEN 0b00000010 ///< Enable Y-axis -#define LIS2DH_CTRL1_VAL_ZEN 0b00000100 ///< Enable Z-axis -#define LIS2DH_CTRL1_VAL_LPEN 0b00001000 ///< Enable low power mode -#define LIS2DH_CTRL1_VAL_ODR_POWERDOWN 0 ///< Power down -#define LIS2DH_CTRL1_VAL_ODR_1HZ (LIS2DH_DATA_RATE_1_HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_10HZ (LIS2DH_DATA_RATE_10_HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_25HZ (LIS2DH_DATA_RATE_25_HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_50HZ (LIS2DH_DATA_RATE_50_HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_100HZ (LIS2DH_DATA_RATE_100_HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_200HZ (LIS2DH_DATA_RATE_200_HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_400HZ (LIS2DH_DATA_RATE_400_HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_LP1620HZ (LIS2DH_DATA_RATE_LP1620HZ << 4) -#define LIS2DH_CTRL1_VAL_ODR_LP5376HZ (LIS2DH_DATA_RATE_LP5376HZ << 4) - -#define LIS2DH_REG_CTRL2 0x21 - -#define LIS2DH_REG_CTRL3 0x22 -#define LIS2DH_CTRL3_VAL_I1_CLICK 0b10000000 -#define LIS2DH_CTRL3_VAL_I1_AOI1 0b01000000 -#define LIS2DH_CTRL3_VAL_I1_AOI2 0b00100000 -#define LIS2DH_CTRL3_VAL_I1_DRDY1 0b00010000 -#define LIS2DH_CTRL3_VAL_I1_DRDY2 0b00001000 -#define LIS2DH_CTRL3_VAL_I1_WTM 0b00000100 -#define LIS2DH_CTRL3_VAL_I1_OVERRUN 0b00000010 - -#define LIS2DH_REG_CTRL4 0x23 -#define LIS2DH_CTRL4_VAL_BDU 0b10000000 -#define LIS2DH_CTRL4_VAL_BLE 0b01000000 -#define LIS2DH_CTRL4_VAL_RANGE_2G (LIS2DH_RANGE_2_G << 4) -#define LIS2DH_CTRL4_VAL_RANGE_4G (LIS2DH_RANGE_4_G << 4) -#define LIS2DH_CTRL4_VAL_RANGE_8G (LIS2DH_RANGE_8_G << 4) -#define LIS2DH_CTRL4_VAL_RANGE_16G (LIS2DH_RANGE_16_G << 4) -#define LIS2DH_CTRL4_VAL_HR 0b00001000 -#define LIS2DH_CTRL4_VAL_ST0 0b00000000 -#define LIS2DH_CTRL4_VAL_ST1 0b00000000 - -#define LIS2DH_REG_CTRL5 0x24 -#define LIS2DH_CTRL5_VAL_BOOT 0b10000000 -#define LIS2DH_CTRL5_VAL_FIFO_EN 0b01000000 -#define LIS2DH_CTRL5_VAL_LIR_INT1 0b00001000 -#define LIS2DH_CTRL5_VAL_D4D_INT1 0b00000100 -#define LIS2DH_CTRL5_VAL_LIR_INT2 0b00000010 -#define LIS2DH_CTRL5_VAL_D4D_INT2 0b00000001 - -#define LIS2DH_REG_CTRL6 0x25 -#define LIS2DH_CTRL6_VAL_I2_CLICK 0b10000000 -#define LIS2DH_CTRL6_VAL_I2_INT1 0b01000000 -#define LIS2DH_CTRL6_VAL_I2_INT2 0b00100000 -#define LIS2DH_CTRL6_VAL_BOOT_I2 0b00010000 -#define LIS2DH_CTRL6_VAL_P2_ACT 0b00001000 -#define LIS2DH_CTRL6_VAL_H_L_ACTIVE 0b00000000 - -#define LIS2DH_REG_REFERENCE 0x26 - -#define LIS2DH_REG_STATUS 0x27 -#define LIS2DH_STATUS_VAL_ZYXOR 0b10000000 -#define LIS2DH_STATUS_VAL_ZOR 0b01000000 -#define LIS2DH_STATUS_VAL_YOR 0b00100000 -#define LIS2DH_STATUS_VAL_XOR 0b00010000 -#define LIS2DH_STATUS_VAL_ZYXDA 0b00001000 -#define LIS2DH_STATUS_VAL_ZDA 0b00000100 -#define LIS2DH_STATUS_VAL_YDA 0b00000010 -#define LIS2DH_STATUS_VAL_XDA 0b00000001 - -#define LIS2DH_REG_OUT_X_L 0x28 -#define LIS2DH_REG_OUT_X_H 0x29 -#define LIS2DH_REG_OUT_Y_L 0x2A -#define LIS2DH_REG_OUT_Y_H 0x2B -#define LIS2DH_REG_OUT_Z_L 0x2C -#define LIS2DH_REG_OUT_Z_H 0x2D - -#define LIS2DH_REG_FIFO_CTRL 0x2E -#define LIS2DH_REG_FIFO_SRC 0x2F -#define LIS2DH_REG_INT1_CFG 0x30 -#define LIS2DH_REG_INT1_SRC 0x31 -#define LIS2DH_REG_INT1_THS 0x32 -#define LIS2DH_REG_INT1_DUR 0x33 -#define LIS2DH_REG_INT2_CFG 0x34 -#define LIS2DH_REG_INT2_SRC 0x35 -#define LIS2DH_REG_INT2_THS 0x36 -#define LIS2DH_REG_INT2_DUR 0x37 -#define LIS2DH_REG_CLICK_CFG 0x38 -#define LIS2DH_REG_CLICK_SRC 0x39 -#define LIS2DH_REG_CLICK_THS 0x3A -#define LIS2DH_REG_TIME_LIMIT 0x3B -#define LIS2DH_REG_TIME_LATENCY 0x3C -#define LIS2DH_REG_TIME_WINDOW 0x3D - -#endif // LIS2DH_H From 6e9e264c65f30e4046efbf27ebe801cd1f338122 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sun, 10 Apr 2022 18:08:37 -0400 Subject: [PATCH 32/45] rewrite lis2dh logger for lis2dw --- movement/make/Makefile | 1 + movement/movement_faces.h | 1 + ...h_logging_face.c => lis2dw_logging_face.c} | 83 +++++++++---------- ...h_logging_face.h => lis2dw_logging_face.h} | 36 ++++---- watch-library/shared/driver/lis2dw.c | 29 +++++++ watch-library/shared/driver/lis2dw.h | 36 +++++++- 6 files changed, 122 insertions(+), 64 deletions(-) rename movement/watch_faces/demo/{lis2dh_logging_face.c => lis2dw_logging_face.c} (73%) rename movement/watch_faces/demo/{lis2dh_logging_face.h => lis2dw_logging_face.h} (73%) diff --git a/movement/make/Makefile b/movement/make/Makefile index a773fee..03b1819 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -44,6 +44,7 @@ SRCS += \ ../watch_faces/sensor/thermistor_testing_face.c \ ../watch_faces/demo/character_set_face.c \ ../watch_faces/demo/voltage_face.c \ + ../watch_faces/demo/lis2dw_logging_face.c \ ../watch_faces/demo/demo_face.c \ ../watch_faces/demo/hello_there_face.c \ ../watch_faces/complication/pulsometer_face.c \ diff --git a/movement/movement_faces.h b/movement/movement_faces.h index d90bf02..d2c57ed 100644 --- a/movement/movement_faces.h +++ b/movement/movement_faces.h @@ -39,6 +39,7 @@ #include "voltage_face.h" #include "stopwatch_face.h" #include "totp_face.h" +#include "lis2dw_logging_face.h" #include "demo_face.h" #include "hello_there_face.h" #include "sunrise_sunset_face.h" diff --git a/movement/watch_faces/demo/lis2dh_logging_face.c b/movement/watch_faces/demo/lis2dw_logging_face.c similarity index 73% rename from movement/watch_faces/demo/lis2dh_logging_face.c rename to movement/watch_faces/demo/lis2dw_logging_face.c index 31d1cad..0e63e41 100644 --- a/movement/watch_faces/demo/lis2dh_logging_face.c +++ b/movement/watch_faces/demo/lis2dw_logging_face.c @@ -24,8 +24,8 @@ #include #include -#include "lis2dh_logging_face.h" -#include "lis2dh.h" +#include "lis2dw_logging_face.h" +#include "lis2dw.h" #include "watch.h" // This watch face is just for testing; if we want to build accelerometer support, it will likely have to be part of Movement itself. @@ -36,14 +36,14 @@ // Pressing the alarm button enters the log mode, where the main display shows the number of interrupts detected in each of the last // 24 hours (the hour is shown in the top right digit and AM/PM indicator, if the clock is set to 12 hour mode) -static void _lis2dh_logging_face_update_display(movement_settings_t *settings, lis2dh_logger_state_t *logger_state, lis2dh_interrupt_state interrupt_state) { +static void _lis2dw_logging_face_update_display(movement_settings_t *settings, lis2dw_logger_state_t *logger_state, lis2dw_wakeup_source wakeup_source) { char buf[14]; char time_indication_character; int8_t pos; watch_date_time date_time; if (logger_state->log_ticks) { - pos = (logger_state->data_points - 1 - logger_state->display_index) % LIS2DH_LOGGING_NUM_DATA_POINTS; + pos = (logger_state->data_points - 1 - logger_state->display_index) % LIS2DW_LOGGING_NUM_DATA_POINTS; if (pos < 0) { watch_clear_colon(); sprintf(buf, "NO data "); @@ -80,9 +80,9 @@ static void _lis2dh_logging_face_update_display(movement_settings_t *settings, l if ((59 - date_time.unit.second) < 10) time_indication_character = '0' + (59 - date_time.unit.second); else time_indication_character = (date_time.unit.second % 2) ? 'i' : '_'; sprintf(buf, "%c%c%c%c%2d%2d%2d", - (interrupt_state & LIS2DH_INTERRUPT_STATE_Y_HIGH) ? 'Y' : ' ', - (interrupt_state & LIS2DH_INTERRUPT_STATE_X_HIGH) ? 'X' : ' ', - (interrupt_state & LIS2DH_INTERRUPT_STATE_Z_HIGH) ? 'Z' : ' ', + (wakeup_source & LIS2DW_WAKEUP_SRC_WAKEUP_Y) ? 'Y' : ' ', + (wakeup_source & LIS2DW_WAKEUP_SRC_WAKEUP_X) ? 'X' : ' ', + (wakeup_source & LIS2DW_WAKEUP_SRC_WAKEUP_Z) ? 'Z' : ' ', time_indication_character, logger_state->interrupts[0], logger_state->interrupts[1], @@ -91,7 +91,7 @@ static void _lis2dh_logging_face_update_display(movement_settings_t *settings, l watch_display_string(buf, 0); } -static void _lis2dh_logging_face_log_data(lis2dh_logger_state_t *logger_state) { +static void _lis2dw_logging_face_log_data(lis2dw_logger_state_t *logger_state) { watch_date_time date_time = watch_rtc_get_date_time(); // we get this call 15 minutes late; i.e. at 6:15 we're logging events for 6:00. // so: if we're at the top of the hour, roll the hour back too (7:00 task logs data for 6:45) @@ -100,7 +100,7 @@ static void _lis2dh_logging_face_log_data(lis2dh_logger_state_t *logger_state) { // // then roll the minute back. date_time.unit.minute = (date_time.unit.minute + 45) % 60; - size_t pos = logger_state->data_points % LIS2DH_LOGGING_NUM_DATA_POINTS; + size_t pos = logger_state->data_points % LIS2DW_LOGGING_NUM_DATA_POINTS; logger_state->data[pos].timestamp.reg = date_time.reg; logger_state->data[pos].x_interrupts = logger_state->x_interrupts_this_hour; logger_state->data[pos].y_interrupts = logger_state->y_interrupts_this_hour; @@ -111,28 +111,25 @@ static void _lis2dh_logging_face_log_data(lis2dh_logger_state_t *logger_state) { logger_state->z_interrupts_this_hour = 0; } -void lis2dh_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { +void lis2dw_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; (void) watch_face_index; if (*context_ptr == NULL) { - *context_ptr = malloc(sizeof(lis2dh_logger_state_t)); - memset(*context_ptr, 0, sizeof(lis2dh_logger_state_t)); - gpio_set_pin_direction(A0, GPIO_DIRECTION_OUT); - gpio_set_pin_function(A0, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_level(A0, true); + *context_ptr = malloc(sizeof(lis2dw_logger_state_t)); + memset(*context_ptr, 0, sizeof(lis2dw_logger_state_t)); watch_enable_i2c(); - lis2dh_begin(); - lis2dh_set_data_rate(LIS2DH_DATA_RATE_10_HZ); - lis2dh_configure_aoi_int1( - LIS2DH_INTERRUPT_CONFIGURATION_OR | - LIS2DH_INTERRUPT_CONFIGURATION_X_HIGH_ENABLE | - LIS2DH_INTERRUPT_CONFIGURATION_Y_HIGH_ENABLE | - LIS2DH_INTERRUPT_CONFIGURATION_Z_HIGH_ENABLE, 96, 0, true); + lis2dw_begin(); + lis2dw_set_low_power_mode(LIS2DW_LP_MODE_2); // lowest power 14-bit mode, 25 Hz is 3.5 µA @ 1.8V w/ low noise, 3µA without + lis2dw_set_low_noise_mode(true); // consumes a little more power + lis2dw_set_range(LIS2DW_CTRL6_VAL_RANGE_4G); + lis2dw_set_data_rate(LIS2DW_DATA_RATE_25_HZ); // is this enough for training? + // threshold is 1/64th of full scale, so for a FS of ±4G this is 1.25G + lis2dw_configure_wakeup_int1(10, true, false); } } -void lis2dh_logging_face_activate(movement_settings_t *settings, void *context) { - lis2dh_logger_state_t *logger_state = (lis2dh_logger_state_t *)context; +void lis2dw_logging_face_activate(movement_settings_t *settings, void *context) { + lis2dw_logger_state_t *logger_state = (lis2dw_logger_state_t *)context; // force two settings: never enter low energy mode, and always snap back to screen 0. // this assumes the accelerometer face is first in the watch_faces list. settings->bit.le_interval = 0; @@ -140,12 +137,13 @@ void lis2dh_logging_face_activate(movement_settings_t *settings, void *context) logger_state->display_index = 0; logger_state->log_ticks = 0; - watch_enable_digital_input(A1); + watch_enable_digital_input(A0); } -bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { - lis2dh_logger_state_t *logger_state = (lis2dh_logger_state_t *)context; - lis2dh_interrupt_state interrupt_state = 0; +bool lis2dw_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + lis2dw_logger_state_t *logger_state = (lis2dw_logger_state_t *)context; + lis2dw_wakeup_source wakeup_source = 0; + lis2dw_interrupt_source interrupt_source = 0; switch (event.event_type) { case EVENT_MODE_BUTTON_UP: @@ -157,13 +155,13 @@ bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *setti case EVENT_LIGHT_BUTTON_DOWN: logger_state->axis_index = (logger_state->axis_index + 1) % 4; logger_state->log_ticks = 255; - _lis2dh_logging_face_update_display(settings, logger_state, interrupt_state); + _lis2dw_logging_face_update_display(settings, logger_state, wakeup_source); break; case EVENT_ALARM_BUTTON_UP: - if (logger_state->log_ticks) logger_state->display_index = (logger_state->display_index + 1) % LIS2DH_LOGGING_NUM_DATA_POINTS; + if (logger_state->log_ticks) logger_state->display_index = (logger_state->display_index + 1) % LIS2DW_LOGGING_NUM_DATA_POINTS; logger_state->log_ticks = 255; logger_state->axis_index = 0; - _lis2dh_logging_face_update_display(settings, logger_state, interrupt_state); + _lis2dw_logging_face_update_display(settings, logger_state, wakeup_source); break; case EVENT_ACTIVATE: case EVENT_TICK: @@ -172,20 +170,21 @@ bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *setti } else { logger_state->display_index = 0; } - if (watch_get_pin_level(A1)) { + interrupt_source = lis2dw_get_interrupt_source(); + if (interrupt_source) { watch_set_indicator(WATCH_INDICATOR_SIGNAL); - interrupt_state = lis2dh_get_int1_state(); + wakeup_source = lis2dw_get_wakeup_source(); logger_state->interrupts[0]++; - if (interrupt_state & LIS2DH_INTERRUPT_STATE_X_HIGH) logger_state->x_interrupts_this_hour++; - if (interrupt_state & LIS2DH_INTERRUPT_STATE_Y_HIGH) logger_state->y_interrupts_this_hour++; - if (interrupt_state & LIS2DH_INTERRUPT_STATE_Z_HIGH) logger_state->z_interrupts_this_hour++; + if (wakeup_source & LIS2DW_WAKEUP_SRC_WAKEUP_X) logger_state->x_interrupts_this_hour++; + if (wakeup_source & LIS2DW_WAKEUP_SRC_WAKEUP_Y) logger_state->y_interrupts_this_hour++; + if (wakeup_source & LIS2DW_WAKEUP_SRC_WAKEUP_Z) logger_state->z_interrupts_this_hour++; } else { watch_clear_indicator(WATCH_INDICATOR_SIGNAL); } - _lis2dh_logging_face_update_display(settings, logger_state, interrupt_state); + _lis2dw_logging_face_update_display(settings, logger_state, wakeup_source); break; case EVENT_BACKGROUND_TASK: - _lis2dh_logging_face_log_data(logger_state); + _lis2dw_logging_face_log_data(logger_state); break; default: break; @@ -194,15 +193,15 @@ bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *setti return true; } -void lis2dh_logging_face_resign(movement_settings_t *settings, void *context) { +void lis2dw_logging_face_resign(movement_settings_t *settings, void *context) { (void) settings; (void) context; - watch_disable_digital_input(A1); + watch_disable_digital_input(A0); } -bool lis2dh_logging_face_wants_background_task(movement_settings_t *settings, void *context) { +bool lis2dw_logging_face_wants_background_task(movement_settings_t *settings, void *context) { (void) settings; - lis2dh_logger_state_t *logger_state = (lis2dh_logger_state_t *)context; + lis2dw_logger_state_t *logger_state = (lis2dw_logger_state_t *)context; watch_date_time date_time = watch_rtc_get_date_time(); // this is kind of an abuse of the API, but, let's use the 1 minute tick to shift all our data over. diff --git a/movement/watch_faces/demo/lis2dh_logging_face.h b/movement/watch_faces/demo/lis2dw_logging_face.h similarity index 73% rename from movement/watch_faces/demo/lis2dh_logging_face.h rename to movement/watch_faces/demo/lis2dw_logging_face.h index 4936654..f6ea85e 100644 --- a/movement/watch_faces/demo/lis2dh_logging_face.h +++ b/movement/watch_faces/demo/lis2dw_logging_face.h @@ -22,20 +22,20 @@ * SOFTWARE. */ -#ifndef LIS2DH_LOGGING_FACE_H_ -#define LIS2DH_LOGGING_FACE_H_ +#ifndef LIS2DW_LOGGING_FACE_H_ +#define LIS2DW_LOGGING_FACE_H_ #include "movement.h" #include "watch.h" -#define LIS2DH_LOGGING_NUM_DATA_POINTS (96) +#define LIS2DW_LOGGING_NUM_DATA_POINTS (96) typedef struct { watch_date_time timestamp; uint32_t x_interrupts; uint32_t y_interrupts; uint32_t z_interrupts; -} lis2dh_logger_data_point_t; +} lis2dw_logger_data_point_t; typedef struct { uint8_t display_index; // the index we are displaying on screen @@ -46,21 +46,21 @@ typedef struct { uint32_t x_interrupts_this_hour; // the number of interrupts we have logged in the last hour uint32_t y_interrupts_this_hour; // the number of interrupts we have logged in the last hour uint32_t z_interrupts_this_hour; // the number of interrupts we have logged in the last hour - lis2dh_logger_data_point_t data[LIS2DH_LOGGING_NUM_DATA_POINTS]; -} lis2dh_logger_state_t; + lis2dw_logger_data_point_t data[LIS2DW_LOGGING_NUM_DATA_POINTS]; +} lis2dw_logger_state_t; -void lis2dh_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); -void lis2dh_logging_face_activate(movement_settings_t *settings, void *context); -bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context); -void lis2dh_logging_face_resign(movement_settings_t *settings, void *context); -bool lis2dh_logging_face_wants_background_task(movement_settings_t *settings, void *context); +void lis2dw_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void lis2dw_logging_face_activate(movement_settings_t *settings, void *context); +bool lis2dw_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void lis2dw_logging_face_resign(movement_settings_t *settings, void *context); +bool lis2dw_logging_face_wants_background_task(movement_settings_t *settings, void *context); -#define lis2dh_logging_face ((const watch_face_t){ \ - lis2dh_logging_face_setup, \ - lis2dh_logging_face_activate, \ - lis2dh_logging_face_loop, \ - lis2dh_logging_face_resign, \ - lis2dh_logging_face_wants_background_task, \ +#define lis2dw_logging_face ((const watch_face_t){ \ + lis2dw_logging_face_setup, \ + lis2dw_logging_face_activate, \ + lis2dw_logging_face_loop, \ + lis2dw_logging_face_resign, \ + lis2dw_logging_face_wants_background_task, \ }) -#endif // LIS2DH_LOGGING_FACE_H_ +#endif // LIS2DW_LOGGING_FACE_H_ diff --git a/watch-library/shared/driver/lis2dw.c b/watch-library/shared/driver/lis2dw.c index fce266b..4d60fcf 100644 --- a/watch-library/shared/driver/lis2dw.c +++ b/watch-library/shared/driver/lis2dw.c @@ -164,3 +164,32 @@ void lis2dw_clear_fifo(void) { watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_OFF); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_COLLECT_AND_STOP | LIS2DW_FIFO_CTRL_FTH); } + +void lis2dw_configure_wakeup_int1(uint8_t threshold, bool latch, bool active_state) { + uint8_t configuration; + + // enable wakeup interrupt on INT1 pin + configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL4_INT1); + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL4_INT1, configuration | LIS2DW_CTRL4_INT1_WU); + + // set threshold + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS, threshold | LIS2DW_WAKE_UP_THS_VAL_SLEEP_ON); + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_INT1_DUR, 0b01111111); + + configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL3) & ~(LIS2DW_CTRL3_VAL_LIR); + if (!active_state) configuration |= LIS2DW_CTRL3_VAL_H_L_ACTIVE; + if (latch) configuration |= LIS2DW_CTRL3_VAL_LIR; + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL3, configuration); + + // enable interrupts + configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7); + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7, configuration | LIS2DW_CTRL7_VAL_INTERRUPTS_ENABLE); +} + +lis2dw_wakeup_source lis2dw_get_wakeup_source() { + return (lis2dw_wakeup_source) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_SRC); +} + +lis2dw_interrupt_source lis2dw_get_interrupt_source(void) { + return (lis2dw_interrupt_source) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_ALL_INT_SRC); +} diff --git a/watch-library/shared/driver/lis2dw.h b/watch-library/shared/driver/lis2dw.h index 4161117..f9373e0 100644 --- a/watch-library/shared/driver/lis2dw.h +++ b/watch-library/shared/driver/lis2dw.h @@ -94,6 +94,24 @@ typedef enum { LIS2DW_RANGE_2_G = 0b00 // +/- 2g (default value) } lis2dw_range_t; +typedef enum { + LIS2DW_INTERRUPT_SRC_SLEEP_CHANGE = 0b00100000, + LIS2DW_INTERRUPT_SRC_6D = 0b00010000, + LIS2DW_INTERRUPT_SRC_DOUBLE_TAP = 0b00001000, + LIS2DW_INTERRUPT_SRC_SINGLE_TAP = 0b00000100, + LIS2DW_INTERRUPT_SRC_WU = 0b00000010, + LIS2DW_INTERRUPT_SRC_FF = 0b00000001 +} lis2dw_interrupt_source; + +typedef enum { + LIS2DW_WAKEUP_SRC_FREEFALL = 0b00100000, + LIS2DW_WAKEUP_SRC_SLEEP_STATE = 0b00010000, + LIS2DW_WAKEUP_SRC_WAKEUP = 0b00001000, + LIS2DW_WAKEUP_SRC_WAKEUP_X = 0b00000100, + LIS2DW_WAKEUP_SRC_WAKEUP_Y = 0b00000010, + LIS2DW_WAKEUP_SRC_WAKEUP_Z = 0b00000001 +} lis2dw_wakeup_source; + // Assumes SA0 is high; if low, its 0x18 #define LIS2DW_ADDRESS (0x19) @@ -130,15 +148,15 @@ typedef enum { #define LIS2DW_CTRL2_VAL_IF_ADD_INC 0b00000100 #define LIS2DW_REG_CTRL3 0x22 -#define LIS2DW_CTRL4_VAL_SELF_TEST_POS 0b10000000 -#define LIS2DW_CTRL4_VAL_SELF_TEST_NEG 0b01000000 +#define LIS2DW_CTRL3_VAL_SELF_TEST_POS 0b10000000 +#define LIS2DW_CTRL3_VAL_SELF_TEST_NEG 0b01000000 #define LIS2DW_CTRL3_VAL_PP_OD 0b00100000 #define LIS2DW_CTRL3_VAL_LIR 0b00010000 #define LIS2DW_CTRL3_VAL_H_L_ACTIVE 0b00001000 #define LIS2DW_CTRL3_VAL_SLP_MODE_SEL 0b00000010 #define LIS2DW_CTRL3_VAL_SLP_MODE_1 0b00000001 -#define LIS2DW_REG_CTRL4 0x23 +#define LIS2DW_REG_CTRL4_INT1 0x23 #define LIS2DW_CTRL4_INT1_6D 0b10000000 #define LIS2DW_CTRL4_INT1_SINGLE_TAP 0b01000000 #define LIS2DW_CTRL4_INT1_WU 0b00100000 @@ -148,7 +166,7 @@ typedef enum { #define LIS2DW_CTRL4_INT1_FTH 0b00000010 #define LIS2DW_CTRL4_INT1_DRDY 0b00000001 -#define LIS2DW_REG_CTRL5 0x24 +#define LIS2DW_REG_CTRL5_INT2 0x24 #define LIS2DW_CTRL5_INT2_SLEEP_STATE 0b10000000 #define LIS2DW_CTRL5_INT2_SLEEP_CHG 0b01000000 #define LIS2DW_CTRL5_INT2_BOOT 0b00100000 @@ -206,7 +224,11 @@ typedef enum { #define LIS2DW_REG_TAP_THS_Y 0x31 #define LIS2DW_REG_TAP_THS_Z 0x32 #define LIS2DW_REG_INT1_DUR 0x33 + #define LIS2DW_REG_WAKE_UP_THS 0x34 +#define LIS2DW_WAKE_UP_THS_VAL_TAP_EVENT_ENABLED 0b10000000 +#define LIS2DW_WAKE_UP_THS_VAL_SLEEP_ON 0b01000000 + #define LIS2DW_REG_WAKE_UP_DUR 0x35 #define LIS2DW_REG_FREE_FALL 0x36 #define LIS2DW_REG_STATUS_DUP 0x37 @@ -293,4 +315,10 @@ bool lis2dw_read_fifo(lis2dw_fifo_t *fifo_data); void lis2dw_clear_fifo(void); +void lis2dw_configure_wakeup_int1(uint8_t threshold, bool latch, bool active_state); + +lis2dw_interrupt_source lis2dw_get_interrupt_source(void); + +lis2dw_wakeup_source lis2dw_get_wakeup_source(void); + #endif // LIS2DW_H From 81b27b7f16312469902798ab3c2a5bda72a8afa3 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 20 Apr 2022 08:38:39 -0400 Subject: [PATCH 33/45] update checkout action (unsafe directory fix) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4b1f6fa..4179e1d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Compile starter-project app run: make working-directory: 'apps/starter-project' @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Compile movement run: emmake make working-directory: 'movement/make' From 8019563072d4be485ca69359ff0c3863cb03b6e7 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 20 Apr 2022 08:50:25 -0400 Subject: [PATCH 34/45] work around CVE-2022-24765 --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4179e1d..909d9a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + - name: Work around CVE-2022-24765 + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Compile starter-project app run: make working-directory: 'apps/starter-project' From 949ca2227ffca6a3f05c5ae0972fbc2c1a54d255 Mon Sep 17 00:00:00 2001 From: Spencer Bywater Date: Wed, 20 Apr 2022 08:40:55 -0700 Subject: [PATCH 35/45] Add break statement for EVENT_TICK in watch_face template (#64) --- movement/template/template.c | 1 + 1 file changed, 1 insertion(+) diff --git a/movement/template/template.c b/movement/template/template.c index c9c174b..91611d0 100644 --- a/movement/template/template.c +++ b/movement/template/template.c @@ -52,6 +52,7 @@ bool <#watch_face_name#>_face_loop(movement_event_t event, movement_settings_t * break; case EVENT_TICK: // If needed, update your display here. + break; case EVENT_MODE_BUTTON_UP: // You shouldn't need to change this case; Mode almost always moves to the next watch face. movement_move_to_next_face(); From 263e7c6543ab580bed0567b018d1f198f918a64b Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 20 Apr 2022 11:44:21 -0400 Subject: [PATCH 36/45] add counter face to movement build --- movement/make/Makefile | 1 + movement/movement_faces.h | 1 + 2 files changed, 2 insertions(+) diff --git a/movement/make/Makefile b/movement/make/Makefile index 3bed196..5bed6bd 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -53,6 +53,7 @@ SRCS += \ ../watch_faces/complication/totp_face.c \ ../watch_faces/complication/sunrise_sunset_face.c \ ../watch_faces/complication/countdown_face.c \ + ../watch_faces/complication/counter_face.c \ ../watch_faces/complication/blinky_face.c \ ../watch_faces/complication/moon_phase_face.c \ ../watch_faces/clock/mars_time_face.c \ diff --git a/movement/movement_faces.h b/movement/movement_faces.h index e279683..f27d9f9 100644 --- a/movement/movement_faces.h +++ b/movement/movement_faces.h @@ -44,6 +44,7 @@ #include "hello_there_face.h" #include "sunrise_sunset_face.h" #include "countdown_face.h" +#include "counter_face.h" #include "blinky_face.h" #include "moon_phase_face.h" #include "mars_time_face.h" From b0bdf35d8f6340be04aebe7fbd368418d8c15043 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 20 Apr 2022 17:18:58 -0400 Subject: [PATCH 37/45] add mechanism for building alternate firmware images --- make.mk | 5 ++++ movement/alt_fw/alt_time.h | 41 ++++++++++++++++++++++++++++ movement/alt_fw/deep_space_now.h | 44 ++++++++++++++++++++++++++++++ movement/alt_fw/focus.h | 42 ++++++++++++++++++++++++++++ movement/alt_fw/the_athlete.h | 43 +++++++++++++++++++++++++++++ movement/alt_fw/the_backpacker.h | 44 ++++++++++++++++++++++++++++++ movement/alt_fw/the_stargazer.h | 42 ++++++++++++++++++++++++++++ movement/make/.gitignore | 1 + movement/make/make_alternate_fw.sh | 36 ++++++++++++++++++++++++ movement/movement.c | 17 ++++++++++++ 10 files changed, 315 insertions(+) create mode 100644 movement/alt_fw/alt_time.h create mode 100644 movement/alt_fw/deep_space_now.h create mode 100644 movement/alt_fw/focus.h create mode 100644 movement/alt_fw/the_athlete.h create mode 100644 movement/alt_fw/the_backpacker.h create mode 100644 movement/alt_fw/the_stargazer.h create mode 100755 movement/make/make_alternate_fw.sh diff --git a/make.mk b/make.mk index 528b098..ac5be77 100644 --- a/make.mk +++ b/make.mk @@ -172,6 +172,11 @@ ifeq ($(LED), BLUE) CFLAGS += -DWATCH_SWAP_LED_PINS endif +ifdef FIRMWARE +CFLAGS += -DMOVEMENT_FIRMWARE_$(FIRMWARE)=1 +CFLAGS += -DMOVEMENT_FIRMWARE=MOVEMENT_FIRMWARE_$(FIRMWARE) +endif + ifeq ($(BOARD), OSO-FEAL-A1-00) CFLAGS += -DCRYSTALLESS endif diff --git a/movement/alt_fw/alt_time.h b/movement/alt_fw/alt_time.h new file mode 100644 index 0000000..8108bcf --- /dev/null +++ b/movement/alt_fw/alt_time.h @@ -0,0 +1,41 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MOVEMENT_CONFIG_H_ +#define MOVEMENT_CONFIG_H_ + +#include "movement_faces.h" + +const watch_face_t watch_faces[] = { + simple_clock_face, + beats_face, + day_one_face, + + preferences_face, + set_time_face, +}; + +#define MOVEMENT_NUM_FACES (sizeof(watch_faces) / sizeof(watch_face_t)) + +#endif // MOVEMENT_CONFIG_H_ diff --git a/movement/alt_fw/deep_space_now.h b/movement/alt_fw/deep_space_now.h new file mode 100644 index 0000000..1d395fc --- /dev/null +++ b/movement/alt_fw/deep_space_now.h @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MOVEMENT_CONFIG_H_ +#define MOVEMENT_CONFIG_H_ + +#include "movement_faces.h" + +const watch_face_t watch_faces[] = { + simple_clock_face, + mars_time_face, + world_clock_face, + world_clock_face, + world_clock_face, + day_one_face, + + preferences_face, + set_time_face, +}; + +#define MOVEMENT_NUM_FACES (sizeof(watch_faces) / sizeof(watch_face_t)) + +#endif // MOVEMENT_CONFIG_H_ diff --git a/movement/alt_fw/focus.h b/movement/alt_fw/focus.h new file mode 100644 index 0000000..865459e --- /dev/null +++ b/movement/alt_fw/focus.h @@ -0,0 +1,42 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MOVEMENT_CONFIG_H_ +#define MOVEMENT_CONFIG_H_ + +#include "movement_faces.h" + +const watch_face_t watch_faces[] = { + simple_clock_face, + tomato_face, + stopwatch_face, + countdown_face, + + preferences_face, + set_time_face, +}; + +#define MOVEMENT_NUM_FACES (sizeof(watch_faces) / sizeof(watch_face_t)) + +#endif // MOVEMENT_CONFIG_H_ diff --git a/movement/alt_fw/the_athlete.h b/movement/alt_fw/the_athlete.h new file mode 100644 index 0000000..5d9d952 --- /dev/null +++ b/movement/alt_fw/the_athlete.h @@ -0,0 +1,43 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MOVEMENT_CONFIG_H_ +#define MOVEMENT_CONFIG_H_ + +#include "movement_faces.h" + +const watch_face_t watch_faces[] = { + simple_clock_face, + stopwatch_face, + countdown_face, + counter_face, + pulsometer_face, + + preferences_face, + set_time_face, +}; + +#define MOVEMENT_NUM_FACES (sizeof(watch_faces) / sizeof(watch_face_t)) + +#endif // MOVEMENT_CONFIG_H_ diff --git a/movement/alt_fw/the_backpacker.h b/movement/alt_fw/the_backpacker.h new file mode 100644 index 0000000..01af7b0 --- /dev/null +++ b/movement/alt_fw/the_backpacker.h @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MOVEMENT_CONFIG_H_ +#define MOVEMENT_CONFIG_H_ + +#include "movement_faces.h" + +const watch_face_t watch_faces[] = { + simple_clock_face, + sunrise_sunset_face, + moon_phase_face, + thermistor_readout_face, + thermistor_logging_face, + blinky_face, + + preferences_face, + set_time_face, +}; + +#define MOVEMENT_NUM_FACES (sizeof(watch_faces) / sizeof(watch_face_t)) + +#endif // MOVEMENT_CONFIG_H_ diff --git a/movement/alt_fw/the_stargazer.h b/movement/alt_fw/the_stargazer.h new file mode 100644 index 0000000..320436a --- /dev/null +++ b/movement/alt_fw/the_stargazer.h @@ -0,0 +1,42 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MOVEMENT_CONFIG_H_ +#define MOVEMENT_CONFIG_H_ + +#include "movement_faces.h" + +const watch_face_t watch_faces[] = { + simple_clock_face, + astronomy_face, + sunrise_sunset_face, + moon_phase_face, + + preferences_face, + set_time_face, +}; + +#define MOVEMENT_NUM_FACES (sizeof(watch_faces) / sizeof(watch_face_t)) + +#endif // MOVEMENT_CONFIG_H_ diff --git a/movement/make/.gitignore b/movement/make/.gitignore index 3722ac6..45eba6e 100755 --- a/movement/make/.gitignore +++ b/movement/make/.gitignore @@ -1 +1,2 @@ build/ +firmware/ diff --git a/movement/make/make_alternate_fw.sh b/movement/make/make_alternate_fw.sh new file mode 100755 index 0000000..575c9e5 --- /dev/null +++ b/movement/make/make_alternate_fw.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +fw_dir="firmware/download" +sim_dir="firmware/simulate" +colors=("green" "blue") +variants=("standard" "alt_time" "deep_space_now" "focus" "the_athlete" "the_backpacker" "the_stargazer") + +if [ -d "$fw_dir" ] ; then + rm -r "$fw_dir" +fi +if [ -d "$sim_dir" ] ; then + rm -r "$sim_dir" +fi + +mkdir -p "$fw_dir" +mkdir -p "$sim_dir" + +for variant in "${variants[@]}" +do + VARIANT=$(echo "$variant" | tr '[:lower:]' '[:upper:]') + for color in "${colors[@]}" + do + COLOR=$(echo "$color" | tr '[:lower:]' '[:upper:]') + make clean + make LED=$COLOR FIRMWARE=$VARIANT + mv "build/watch.uf2" "$fw_dir/$variant-$color.uf2" + done + make clean + emmake make FIRMWARE=$VARIANT + mkdir "$sim_dir/$variant/" + mv "build/watch.wasm" "$sim_dir/$variant/" + mv "build/watch.js" "$sim_dir/$variant/" + mv "build/watch.html" "$sim_dir/$variant/index.html" +done + +echo "Done." diff --git a/movement/movement.c b/movement/movement.c index 13cef97..d61c90c 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -27,7 +27,24 @@ #include #include "watch.h" #include "movement.h" + +#ifndef MOVEMENT_FIRMWARE #include "movement_config.h" +#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_STANDARD +#include "movement_config.h" +#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_ALT_TIME +#include "alt_fw/alt_time.h" +#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_FOCUS +#include "alt_fw/focus.h" +#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_THE_BACKPACKER +#include "alt_fw/the_backpacker.h" +#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_THE_ATHLETE +#include "alt_fw/the_athlete.h" +#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_THE_STARGAZER +#include "alt_fw/the_stargazer.h" +#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_DEEP_SPACE_NOW +#include "alt_fw/deep_space_now.h" +#endif #if __EMSCRIPTEN__ #include From 19dac66a3bd84cf7868d2a27225e92a5a486c03d Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 21 Apr 2022 11:26:02 -0400 Subject: [PATCH 38/45] freeze snapshot of standard firmware in alt_fw --- movement/alt_fw/standard.h | 43 ++++++++++++++++++++++++++++++++++++++ movement/movement.c | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 movement/alt_fw/standard.h diff --git a/movement/alt_fw/standard.h b/movement/alt_fw/standard.h new file mode 100644 index 0000000..3abcf45 --- /dev/null +++ b/movement/alt_fw/standard.h @@ -0,0 +1,43 @@ +/* + * MIT License + * + * Copyright (c) 2022 Joey Castillo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MOVEMENT_CONFIG_H_ +#define MOVEMENT_CONFIG_H_ + +#include "movement_faces.h" + +const watch_face_t watch_faces[] = { + simple_clock_face, + world_clock_face, + sunrise_sunset_face, + moon_phase_face, + thermistor_readout_face, + + preferences_face, + set_time_face, +}; + +#define MOVEMENT_NUM_FACES (sizeof(watch_faces) / sizeof(watch_face_t)) + +#endif // MOVEMENT_CONFIG_H_ diff --git a/movement/movement.c b/movement/movement.c index d61c90c..22175ef 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -31,7 +31,7 @@ #ifndef MOVEMENT_FIRMWARE #include "movement_config.h" #elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_STANDARD -#include "movement_config.h" +#include "alt_fw/standard.h" #elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_ALT_TIME #include "alt_fw/alt_time.h" #elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_FOCUS From a6024e9fdae3d41fc12c40920bc16899f73efd63 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 21 Apr 2022 11:46:56 -0400 Subject: [PATCH 39/45] stargazer firmware: make LED red by default --- movement/alt_fw/the_stargazer.h | 5 +++++ movement/movement.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/movement/alt_fw/the_stargazer.h b/movement/alt_fw/the_stargazer.h index 320436a..edf49ff 100644 --- a/movement/alt_fw/the_stargazer.h +++ b/movement/alt_fw/the_stargazer.h @@ -27,6 +27,11 @@ #include "movement_faces.h" +#define MOVEMENT_CUSTOM_BOOT_COMMANDS() { \ + movement_state.settings.bit.led_green_color = 0x0;\ + movement_state.settings.bit.led_red_color = 0xF;\ +} + const watch_face_t watch_faces[] = { simple_clock_face, astronomy_face, diff --git a/movement/movement.c b/movement/movement.c index 22175ef..c3beec8 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -268,6 +268,10 @@ void app_wake_from_backup(void) { } void app_setup(void) { + #ifdef MOVEMENT_CUSTOM_BOOT_COMMANDS + MOVEMENT_CUSTOM_BOOT_COMMANDS() + #endif + watch_store_backup_data(movement_state.settings.reg, 0); static bool is_first_launch = true; From cedfe72ced5ab185d580d21d5766b0ba37cbc2ce Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 21 Apr 2022 13:34:49 -0400 Subject: [PATCH 40/45] deep space firmware: prepopulate time zones --- movement/alt_fw/deep_space_now.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/movement/alt_fw/deep_space_now.h b/movement/alt_fw/deep_space_now.h index 1d395fc..4cd9757 100644 --- a/movement/alt_fw/deep_space_now.h +++ b/movement/alt_fw/deep_space_now.h @@ -27,6 +27,21 @@ #include "movement_faces.h" +// Preset Goldstone (GO), Madrid (MA), and Canberra (CA) time zones. + +#define MOVEMENT_CUSTOM_BOOT_COMMANDS() { \ + /* Standard Time */\ + /*\ + watch_store_backup_data(0x1e0c0c, 4);\ + watch_store_backup_data(0x010115, 5);\ + watch_store_backup_data(0x130105, 6);\ + */\ + /* Daylight Saving Time */\ + watch_store_backup_data(0x1f0c0c, 4);\ + watch_store_backup_data(0x020115, 5);\ + watch_store_backup_data(0x110105, 6);\ +} + const watch_face_t watch_faces[] = { simple_clock_face, mars_time_face, From 9c2b3b7c175f87bf5af5746a5ba0ecd8c4089293 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 21 Apr 2022 14:12:16 -0400 Subject: [PATCH 41/45] make 2022 the default year --- watch-library/hardware/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/watch-library/hardware/main.c b/watch-library/hardware/main.c index eb372cc..d1eee16 100755 --- a/watch-library/hardware/main.c +++ b/watch-library/hardware/main.c @@ -66,6 +66,13 @@ int main(void) { // Watch library code. Set initial parameters for the device and enable the RTC. _watch_init(); + // if date/time register is 0 (power on reset state), default year to 2022. + watch_date_time date_time = watch_rtc_get_date_time(); + if (date_time.reg == 0) { + date_time.unit.year = 2; + watch_rtc_set_date_time(date_time); + } + // User code. Give the app a chance to enable and set up peripherals. app_setup(); From c78b8d4570436fbbad3be66ec5801736dc462895 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 21 Apr 2022 14:33:59 -0400 Subject: [PATCH 42/45] deep space firmware: show voyager 1 mission day --- movement/alt_fw/deep_space_now.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/movement/alt_fw/deep_space_now.h b/movement/alt_fw/deep_space_now.h index 4cd9757..f07fe2c 100644 --- a/movement/alt_fw/deep_space_now.h +++ b/movement/alt_fw/deep_space_now.h @@ -28,6 +28,7 @@ #include "movement_faces.h" // Preset Goldstone (GO), Madrid (MA), and Canberra (CA) time zones. +// Also prepopulate the Day One register with Voyager 1's launch (September 5, 1977) #define MOVEMENT_CUSTOM_BOOT_COMMANDS() { \ /* Standard Time */\ @@ -40,6 +41,7 @@ watch_store_backup_data(0x1f0c0c, 4);\ watch_store_backup_data(0x020115, 5);\ watch_store_backup_data(0x110105, 6);\ + watch_store_backup_data(0x0597b9, 2);\ } const watch_face_t watch_faces[] = { From e36af0e5a368290848cec413c799d499e266a0c4 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 21 Apr 2022 15:37:12 -0400 Subject: [PATCH 43/45] movement: only run custom commands at first launch --- movement/alt_fw/the_stargazer.h | 1 + movement/movement.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/movement/alt_fw/the_stargazer.h b/movement/alt_fw/the_stargazer.h index edf49ff..50a89aa 100644 --- a/movement/alt_fw/the_stargazer.h +++ b/movement/alt_fw/the_stargazer.h @@ -30,6 +30,7 @@ #define MOVEMENT_CUSTOM_BOOT_COMMANDS() { \ movement_state.settings.bit.led_green_color = 0x0;\ movement_state.settings.bit.led_red_color = 0xF;\ + watch_store_backup_data(movement_state.settings.reg, 0);\ } const watch_face_t watch_faces[] = { diff --git a/movement/movement.c b/movement/movement.c index c3beec8..4a5bc04 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -268,15 +268,15 @@ void app_wake_from_backup(void) { } void app_setup(void) { - #ifdef MOVEMENT_CUSTOM_BOOT_COMMANDS - MOVEMENT_CUSTOM_BOOT_COMMANDS() - #endif - watch_store_backup_data(movement_state.settings.reg, 0); static bool is_first_launch = true; if (is_first_launch) { + #ifdef MOVEMENT_CUSTOM_BOOT_COMMANDS + MOVEMENT_CUSTOM_BOOT_COMMANDS() + #endif + for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) { watch_face_contexts[i] = NULL; scheduled_tasks[i].reg = 0; From aa94739e7e17bbc5105f983025814e87eb1e171c Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Thu, 21 Apr 2022 17:04:54 -0400 Subject: [PATCH 44/45] milestone: watch library 0.0.1 --- Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index 1d9b2bd..5d4a1fd 100644 --- a/Doxyfile +++ b/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "Sensor Watch" -PROJECT_NUMBER = "0.0.0" +PROJECT_NUMBER = "0.0.1" PROJECT_BRIEF = "A board replacement for the classic Casio F-91W wristwatch, powered by a Microchip SAM L22 microcontroller." PROJECT_LOGO = OUTPUT_DIRECTORY = "." From 35d1f5e647ac1b5fcccdb43ec58058587dd5301b Mon Sep 17 00:00:00 2001 From: joeycastillo Date: Sat, 30 Apr 2022 08:35:30 -0500 Subject: [PATCH 45/45] add CVE-2022-24765 to build-simulator --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 909d9a2..3ed1ff2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,6 +38,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + - name: Work around CVE-2022-24765 + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Compile movement run: emmake make working-directory: 'movement/make'