# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: koinec@users.osdn.me-20200816123821-28bi1dj4aicof96q # target_branch: http://bazaar.launchpad.net/~foxtrotgps-\ # team/foxtrotgps/trunk/ # testament_sha1: 90514bf9c532909532ae739cba20e7c07290274b # timestamp: 2020-08-16 21:39:32 +0900 # base_revision_id: pabs3@bonedaddy.net-20200806031254-\ # ii1t90q816ocwisl # # Begin patch === modified file 'src/callbacks.c' --- src/callbacks.c 2020-01-25 00:00:46 +0000 +++ src/callbacks.c 2020-08-16 12:38:21 +0000 @@ -168,6 +168,7 @@ repaint_all (); } else { + recalc_overall (selected_wp); selected_wp = NULL; } } @@ -887,24 +888,13 @@ if(gpsdata !=NULL && !global_myposition.lat && !global_myposition.lon) { - distance = 6371.0 * - acos(sin(deg2rad(gpsdata->fix.latitude)) * - sin(lat) + - - cos(deg2rad(gpsdata->fix.latitude)) * - cos(lat) * - cos(lon - deg2rad(gpsdata->fix.longitude)) ); + distance = (float)get_distance(deg2rad(gpsdata->fix.latitude), + deg2rad(gpsdata->fix.longitude), lat, lon); } else if(global_myposition.lat && global_myposition.lon) { - distance = 6371.0 * - acos(sin(deg2rad(global_myposition.lat)) * - sin(lat) + - - cos(deg2rad(global_myposition.lat)) * - cos(lat) * - cos(lon - deg2rad(global_myposition.lon)) ); - + distance = (float)get_distance(deg2rad(global_myposition.lat), + deg2rad(global_myposition.lon), lat, lon); } g_sprintf (buffer, _("Distance: %.3fkm\n"), distance); @@ -1001,25 +991,13 @@ if(distance_mode) { - distance = 6371.0 * - acos(sin(deg2rad(start_lat)) * - sin(lat) + - - cos(deg2rad(start_lat)) * - cos(lat) * - cos(lon - deg2rad(start_lon)) ); - + distance = (float)get_distance(deg2rad(start_lat), deg2rad(start_lon), lat, lon); bearing = get_bearing(deg2rad(start_lat), deg2rad(start_lon), lat, lon); } else if(gpsdata !=NULL && gpsdata->fix.latitude) { - distance = 6371.0 * - acos(sin(deg2rad(gpsdata->fix.latitude)) * - sin(lat) + - - cos(deg2rad(gpsdata->fix.latitude)) * - cos(lat) * - cos(lon - deg2rad(gpsdata->fix.longitude)) ); + distance = (float)get_distance(deg2rad(gpsdata->fix.latitude), + deg2rad(gpsdata->fix.longitude), lat, lon); } if(distance_mode) === modified file 'src/globals.h' --- src/globals.h 2018-01-02 09:22:27 +0000 +++ src/globals.h 2020-08-16 12:38:21 +0000 @@ -33,6 +33,8 @@ typedef struct { double lat; double lon; + double distance; + double overall; } waypoint_t; typedef struct { === modified file 'src/gps_functions.c' --- src/gps_functions.c 2020-01-15 05:50:03 +0000 +++ src/gps_functions.c 2020-08-16 12:38:21 +0000 @@ -258,8 +258,7 @@ if( gpsdata->valid && lat_tmp!=0 && lon_tmp!=0) { - trip_delta = 6371.0 * acos(sin(lat) * sin(lat_tmp) + - cos(lat) * cos(lat_tmp) * cos(lon_tmp-lon) ); + trip_delta = (float)get_distance(lat, lon, lat_tmp, lon_tmp); if(isnan(trip_delta)) { @@ -472,9 +471,26 @@ } } +char * +get_route_status_string() +{ + double distance; + static gchar buffer[64]; + + buffer[0] = '\0'; + if (NULL != get_total_distance( &distance )) { + g_snprintf (buffer, sizeof(buffer), + _(" Route[Total:%3.2lfkm]"), + distance); + } + + return buffer; +} + void set_label_newmsg() { + static gchar buffer[BUFSIZE]; static GtkLabel *label = NULL; if (label == NULL) @@ -482,10 +498,13 @@ label = GTK_LABEL(lookup_widget(window1, "label4")); } - gtk_label_set_label (label, - _("" + g_snprintf (buffer, BUFSIZE, + _("" "New Message arrived. Click here." - "")); + "%s"), + get_route_status_string()); + + gtk_label_set_label(label, buffer); } void @@ -504,8 +523,8 @@ g_snprintf (buffer, BUFSIZE, _("no GPSD found" " - " - "D%d"), - num_dl_threads); + "D%d%s"), + num_dl_threads, get_route_status_string()); } else if (num_dl_threads && global_tiles_in_dl_queue) g_snprintf (buffer, BUFSIZE, @@ -513,10 +532,10 @@ " - " "D%d" " - " - "[%d]"), - num_dl_threads, global_tiles_in_dl_queue); + "[%d]%s"), + num_dl_threads, global_tiles_in_dl_queue, get_route_status_string()); else - g_snprintf (buffer, BUFSIZE, _("no GPSD found")); + g_snprintf (buffer, BUFSIZE, _("no GPSD found%s"), get_route_status_string()); gtk_label_set_label(label, buffer); @@ -616,14 +635,15 @@ "trp %.2f%s " "alt %.0f%s " "hdg %.0f° " - "%d/%.1f"), + "%d/%.1f%s"), numdl_buf, dl_buf, tr_buf, ff_buf, gpsdata->fix.speed * 3.6 * unit_conv, speedunit, trip_distance * unit_conv, distunit, gpsdata->fix.altitude * unit_conv_alt, altunit, gpsdata->fix.heading, gpsdata->satellites_used, - gpsdata->hdop); + gpsdata->hdop, + get_route_status_string()); gtk_label_set_label(label, buffer); === modified file 'src/poi.c' --- src/poi.c 2018-03-06 04:18:49 +0000 +++ src/poi.c 2020-08-16 12:38:21 +0000 @@ -742,24 +742,13 @@ if(gpsdata !=NULL && !global_myposition.lat && !global_myposition.lon) { - distance = 6371.0 * - acos(sin(deg2rad(gpsdata->fix.latitude)) * - sin(lat) + - - cos(deg2rad(gpsdata->fix.latitude)) * - cos(lat) * - cos(lon - deg2rad(gpsdata->fix.longitude)) ); + distance = (float)get_distance(deg2rad(gpsdata->fix.latitude), + deg2rad(gpsdata->fix.longitude), lat, lon); } else if(global_myposition.lat && global_myposition.lon) { - distance = 6371.0 * - acos(sin(deg2rad(global_myposition.lat)) * - sin(lat) + - - cos(deg2rad(global_myposition.lat)) * - cos(lat) * - cos(lon - deg2rad(global_myposition.lon)) ); - + distance = (float)get_distance(deg2rad(global_myposition.lat), + deg2rad(global_myposition.lon), lat, lon); } label = lookup_widget(window,"label110"); === modified file 'src/route.c' --- src/route.c 2018-03-27 06:04:17 +0000 +++ src/route.c 2020-08-16 12:38:21 +0000 @@ -41,6 +41,12 @@ static int wp_icon_width = 0; static int wp_icon_height = 0; +#if GLIB_CHECK_VERSION(2,34,0) + static GMutex mutex; +#else + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; +#endif + /** * Clear the route. */ @@ -51,17 +57,114 @@ } /** + * Get Total Distance. + */ +double * +get_total_distance (double *overall) +{ + GSList *last = NULL; + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_lock (&mutex); +#else + g_static_mutex_lock (&mutex); +#endif + last = g_slist_last (route); + if (NULL != last) { + *overall = ((waypoint_t *)last->data)->distance + ((waypoint_t *)last->data)->overall; + } +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_unlock (&mutex); +#else + g_static_mutex_unlock (&mutex); +#endif + + return ((NULL != last) ? overall : NULL); +} + +/** + * Calc. all route distance & overall. + */ +void +calc_all_routedistance (GSList *list) +{ + int position; + GSList *now; + GSList *start; + waypoint_t *previous_wp; + + previous_wp = (waypoint_t *)list->data; + + for (now = list->next; now != NULL; now = now->next) { + waypoint_t *wp = now->data; + + wp->distance = get_distance( previous_wp->lat, previous_wp->lon, wp->lat, wp->lon); + wp->overall = previous_wp->overall + previous_wp->distance; + + previous_wp = wp; + } +} + +/** + * ReCalc. route distance overall. + */ +void +recalc_overall (waypoint_t *wp) +{ + int position; + GSList *list; + GSList *start; + waypoint_t *previous_wp; + + previous_wp = wp; + position = g_slist_index (route, wp); + start = g_slist_nth(route, position + 1); + + for (list = start; list != NULL; list = list->next) { + waypoint_t *tp = list->data; + + tp->overall = previous_wp->overall + previous_wp->distance; + + previous_wp = tp; + } +} + +/** * Append a new waypoint at the end of the route. */ void append_waypoint_to_route (double lat, double lon) { + GSList *last; waypoint_t *tp = g_new0 (waypoint_t,1); tp->lat = lat; tp->lon = lon; + last = g_slist_last (route); + if (NULL == last) { + tp->distance = 0.0; + tp->overall = 0.0; + } else { + tp->distance = get_distance( + ((waypoint_t *)last->data)->lat, + ((waypoint_t *)last->data)->lon, lat, lon); + tp->overall = ((waypoint_t *)last->data)->overall + ((waypoint_t *)last->data)->distance; + } + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_lock (&mutex); +#else + g_static_mutex_lock (&mutex); +#endif + route = g_slist_append (route, tp); + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_unlock (&mutex); +#else + g_static_mutex_unlock (&mutex); +#endif } /** @@ -70,8 +173,34 @@ void change_waypoint_of_route (waypoint_t *tp, double lat, double lon) { + int position; + waypoint_t *previous_wp; + waypoint_t *next_wp; + tp->lat = lat; tp->lon = lon; + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_lock (&mutex); +#else + g_static_mutex_lock (&mutex); +#endif + position = g_slist_index (route, tp); + previous_wp = g_slist_nth_data (route, position - 1); + + if (NULL != previous_wp) + tp->distance = get_distance( previous_wp->lat, previous_wp->lon, lat, lon); + + next_wp = g_slist_nth_data (route, position + 1); + if (NULL != next_wp) { + next_wp->distance = get_distance( lat, lon, next_wp->lat, next_wp->lon); + next_wp->overall = tp->distance + tp->overall; + } +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_unlock (&mutex); +#else + g_static_mutex_unlock (&mutex); +#endif } /** @@ -80,8 +209,42 @@ void delete_waypoint_of_route (waypoint_t *wp) { + int position; + waypoint_t *next_wp; + waypoint_t *previous_wp; + + position = g_slist_index (route, wp); + previous_wp = g_slist_nth_data (route, position - 1); + next_wp = g_slist_nth_data (route, position + 1); + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_lock (&mutex); +#else + g_static_mutex_lock (&mutex); +#endif + route = g_slist_remove (route, wp); + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_unlock (&mutex); +#else + g_static_mutex_unlock (&mutex); +#endif + g_free (wp); + + if (NULL == previous_wp) { + next_wp->distance = 0.0; + next_wp->overall = 0.0; + + recalc_overall (next_wp); + } else { + if (NULL != next_wp) + next_wp->distance = get_distance( + previous_wp->lat, previous_wp->lon, next_wp->lat, next_wp->lon); + + recalc_overall (previous_wp); + } } /** @@ -103,7 +266,25 @@ new_wp->lat = previous_wp->lat - (previous_wp->lat - wp->lat) / 2; new_wp->lon = previous_wp->lon - (previous_wp->lon - wp->lon) / 2; + new_wp->distance = get_distance (previous_wp->lat, previous_wp->lon, new_wp->lat, new_wp->lon); + new_wp->overall = previous_wp->overall + previous_wp->distance; + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_lock (&mutex); +#else + g_static_mutex_lock (&mutex); +#endif + route = g_slist_insert (route, new_wp, position + 0); + + wp->distance = get_distance (wp->lat, wp->lon, new_wp->lat, new_wp->lon); + wp->overall = new_wp->overall + new_wp->distance; + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_unlock (&mutex); +#else + g_static_mutex_unlock (&mutex); +#endif } } @@ -449,10 +630,9 @@ */ static GSList * -parse_gpx_routepoints (xmlNode *node) +parse_gpx_routepoints (xmlNode *node, GSList *list) { xmlNode *cur_node = NULL; - GSList *list = NULL; for (cur_node = node; cur_node; cur_node = cur_node->next) { @@ -461,6 +641,7 @@ if (xmlStrEqual (cur_node->name, BAD_CAST "rtept")) { double lat, lon; + GSList *last; waypoint_t *tp = g_new0 (waypoint_t, 1); lat = atof ((char *) xmlGetProp (cur_node, @@ -471,11 +652,22 @@ tp->lat = deg2rad (lat); tp->lon = deg2rad (lon); + last = g_slist_last (list); + if (NULL == last) { + tp->distance = 0.0; + tp->overall = 0.0; + } else { + tp->distance = get_distance( + ((waypoint_t *)last->data)->lat, + ((waypoint_t *)last->data)->lon, lat, lon); + tp->overall = ((waypoint_t *)last->data)->overall + + ((waypoint_t *)last->data)->distance; + } + list = g_slist_append (list, tp); } } - list = g_slist_concat (list, - parse_gpx_routepoints (cur_node->children)); + list = parse_gpx_routepoints (cur_node->children, list); } return list; @@ -500,7 +692,20 @@ } root_element = xmlDocGetRootElement (doc); - list = parse_gpx_routepoints (root_element); +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_lock (&mutex); +#else + g_static_mutex_lock (&mutex); +#endif + + list = parse_gpx_routepoints (root_element, list); + calc_all_routedistance (list); + +#if GLIB_CHECK_VERSION(2,34,0) + g_mutex_unlock (&mutex); +#else + g_static_mutex_unlock (&mutex); +#endif xmlFreeDoc (doc); xmlCleanupParser (); === modified file 'src/route.h' --- src/route.h 2018-03-06 03:32:21 +0000 +++ src/route.h 2020-08-16 12:38:21 +0000 @@ -20,6 +20,24 @@ get_way_bbox (GSList *ways); /** + * Get Total Distance. + */ +double * +get_total_distance (double *overall); + +/** + * Calc. all route distance & overall. + */ +void +calc_all_routedistance (GSList *list); + +/** + * ReCalc. route distance overall. + */ +void +recalc_overall (waypoint_t *wp); + +/** * Append a new waypoint at the end of the route. */ void # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWcP24pkACaL/gHpwCAB7/////+/ffr////pgD5x047Nx32z59Xqb3ynbAoFLw8983ObsfXX3t6L33GttoC2CtmpoJJKZqnplNkKZNlPTCT0nqeanqTTZQwjQDBBhBkbCBKEAjIEaaRpTyj01NM1MgAAAAaAAAyCUBBJGjU8moek9RkDQA0AAAAAAAASakQmiJtU8Kek9GUaPaFD1GjJk9Rppo0AANGjTQAiUmmk1NTak3knkUyZHiNqg/RIZ6hDQDaQNGQYajQEUiATRMmATIaAap+plNqNJo8UPU9HqjQDQaAMY9dFWENLIQMyBFiJBSKI1sD+Je4CRgsFIjFBZdlJBURkSKxkZEiRgcO+9jZx1Ra/+li0LJ+jxJi5FVR1IGf1CtuXcUwBijjuKMTXiS8BKzDOYkL6CFrxXAyPv57mFqpRjoyrNCGlJsyoH/kRpGbVq0vQ2Vb2ehz6cTbzrYlutVCdpgqQXRYPkzOHOKs4X9ri9V5/4MdO1MDwb2HJyLCCYhspkqLcwmGGTMzVV0JLvfJAIKIifgQZA8JkJil2hGmcdmIUc0JWrBeL50iy3SjSlFos1epKlzrEVQJQrVmaukFsVNXM3EK2Xtj+gLtd6RhoS8kd1F5v+favzWaxueQP8mGhMcXJNZNEg7qrRLKJDGtuUFUc5PKTjIwVVVZIKQ1Ev5gTp6vL6Z9fXLB+u3sqqx7J9l0wmXFasjTaBRZOcoJC1ItNStWorrddUvDXgmxWkIg1qRhajKjM0XYsQxgtcKPe8O9bXcvMSw92KLWrulFsr2Gsry+XLlUPm6MaP07ops5thFCQkBW2qOzjoqum0nFoMJCbCFbohdcecLk4kKj6DZdV2R0jyBgwphOWDR8aMKnIQBa+cpeVMwmhxjxIJsA7DcPCYUMBIx3e3dVMthJHqhnBy6YiAdKImg3paZaQUtfUHvjZyGLUTDMmY2wN3FioodPXbDAMd2uDPFDkE+Fom9El9FVI4ccuRzpIUhe8gEJmQvXPHg7HKianKA7jo12L/bX1NAWvzko9A/qjR3IuSBkGOiRnEJO3WinuRamAlE+TMSKa9uNr6hxUKmV4dFtRVVR7DZ6LiveIXojbmXOUl7aWm+uWlS4pjYKhzAPdvXuoGYE7Iwd5gEgT40hqx0/WhSTaNy/WvzXqtyURyWQ0UUImCQFkmcz3I8EcB7fdsI8QNpAwWIXAH4DqAECrSHgdesIiHFJRUkRha7YsSL5i1YzFkrm+bVfh86vZcaSIMgV9S/XdVrzwkEiUQQch0sEMIGBChA6B1fKOwfRPmbLLhm0BierqnUDEGkW6EhWCGqKF1b+jajeuC19/b5eGN2NLyqAGYya1eZhiqCsgwQqCDGsIjvEkIq9ApDkQ4TfNppHctSOFi5HRZKBgwiI0REkVIsQMAKpiJ62Q4htMwHPyLYfHim9AhR45GkwlVCmTI9Hij1JQqgGDBzVOtiCHTbM0G1E6ytNGoPD68gBtkXLKJv0bdnn3i0REXEXBEUeBUO7ljuxW9pjgBasjV5mDcWZOawQn28acH1cgLmJAzkH/sRqANBcSxWF5sPCl6hbdAuLKJs0TzSyUkrLNs53mmSYvsRQpsU1N1BMB1RA0oghqZ8YRojAAlBzXXOss1w8pTJ01gIlACY6KyO+IkohxNMhJXiIpWV3KRDE6GVfiuAMTlwrigPMDMcGBEceOxmeTp9gEpPI0U5Vxe173Rw2GoIjeHkMh1sIj1uXqhM57nQLjzkExkpGQiWMYHA2wJrOMwByJeeBAxKXnjcZ81DeaFwVyDTvZ5KrqOwM33zbBBLkJToBVHFTEnenTIL7FaEpe07qsxJTFgYFZs8RjRL0Me4AaspJga6PbIMQIkTiwW0xL1dtMxeRgzGRGQiON6BexiqSyL06yODiMBb67+5AvNxtuMK4GhmWduv4ZNBqTWDozo2lF0kXMJcP8x17MIlBMhngFZjlZ4pJUNRe/gauM2ydjVsm3zMStR3DADUrvOUTTyCJ14JmALmkCOOOb46taNHwR41FscICvkOHOi2u4fWTzJ49Qv42fYhNmctWcdjtdQKVNRjMzycW8+hdbAZd3Pq020ZzooOSpowQKsgHIRs+C3AHB8BbYYg4GjXmJajrjLZiITA1lPOQ4A1NO6Kan0Pa8w0E5qtjlc8dxXfTYRO8jEOmcERNSbDKT2cWv9W+k6cQB04CzxMjYoPkMMZRTOXo04lQazatWe60pldEqgUcCjOtESiBfJ7vXxpVFOU9D0bYfJQdtlsbLgXu7hcrRca9I+qqZgGB4LQMtGVoUwDvsPOybG+S49p46+WSj35OKhUIfgMgJ41oKEGqAz4tcEUc6ql3yNKqQwmjxE5Md5KKZwxnPADNECkEMnuodpA08eBnGLCxs/lH6fuRiNKljo37j/ivoR9iO7X2NlefwSn1FAoHoR4UcntZkfshpRzVI/6RvRpEr0Uf9RzYkMIbZo06EUB482dCyp4jTaKpLljLXAtVCzxoUz41Ntq5f3fZFi+WWTLVQtF7W0IV1fkN66Y0MwjclHcy1RQMqQqTJyCc8Dwgz9ByjBg4hwVS5LsnSqNzgygOBCZkxJaELzTQYhL0MFFeB+JLSpRQVS0FMqmljJDwmkk6j3jxnGbZ4jkMOo+7VL+TldSFREOgH0MJ6GZDFQQSPqzVoXgGEbk5w2AY6lTqIQ3Hg0uksdo3ZswyEW3W466RC8bKmWPOsVKTOA0qgXMWddE4tGknkOMtlkqu5Ov5oYPp7axMq4FqyeVprCrGpfAOZLQgw+gtaHvvhj4QV+gA9gfaG/qGQGYM52FPeZjEc5VUHA3FCBfcwDCYTHQnNujWbw7hBggDqM8y8ovweo+jeA5aYYANvXjtDRtsawppsB8R+LHYKZGPLMskC46FriMXFgLgFKxQRkaAnYcQyiYlhxHIRBiQyZxgyHTBmPZ90n7pkuzf08uhxKHBcjyrg7xgSHr0HCMUvai/7rrUib4B3lTrQPHcZTA7O/Kc/NgQuR8BKicEj6IQM/QCAMcIzuVSBEqJAzcJwN0AdoRRKibdkgKV8ybhGJThEWBxIS07sU0OHT2iaM0jW2qhOaRRRmA9g6Vtvh0w/WTnyuYcSExqM/iYDgcyBNJv3l6lIoCo84b502Nb1n2nQWLyQJRK1OePFY+axTm7f6I97Xkv40o7Jr/VgDbmdiWznMKQAvELbrDt34D2mdDnVthCs7IBCgDXjeQEZsAwARxLr0SbCPPk7e+UtfNHgYSeEqKTvKDprr6+s6hagFihxLEipY7gwo+j0SIqB4urIoaIm+h3x2Dwjxj/B73KvY5SyfFJNbUdIN4NVJJE7JBA/WTa7lgocppCu330WxM9U1SvL1GxD1+cwl6hYac9D25vkqoOVBNh3M6wCJuK7jQgRn1AFgYOVGKuxHKm+DejNe8qas/WISeYu+dCG8QzYxwhE0SHZJ36qrkNkBEBCw9xRyfALRD5nR5XjixRoAPqIBiAdzcfjc40LX66wDUUnl1iNVvHUhV4HgsDo03nqwPdesPWE5kUENZuwLW6RmFocFSabS9FtfI91nm5OE4w5RKmwtsL0MZQSVcd1yg59gwZBzkDjlEs9pyF+IicSkckErFLohV7oU27V6QMvSwYMWMHeNO+LGRiijU38zmZvQDg2fKL8nIZDg4AC0Yt6dZu+HHtLKl5faAxnBb60uhlWE5imCBN6BGfjISpqkWjNRcgWUoSCGSMCFImNDorGNTBI6JMgg5yta3VcDZTjsthnobG0LyIGAGtJMggDyLzRQ8+7Vm2qhufspNd/cAVvkHx6UCYDRhQwCMIEdyH5pM246IxmNCBtJO5AkAaPtaGVa1VtijAp74B3a0hNu2QkEgkRoHel8CQw5dtsWUVVhIgixqpTDVywMvTJVDAIcmC58a28PVv5uabUTstTInE1Cgfn2uQ7FhvO+Aj9EgNYZtTHiJ1w+CusX53uOOWnp5j1BpHYQR2yDR6wakJgBw6Bw/Saz5usw2t8lfeVGRR017FxcvcNQRgeUlupp1tiUCaerrgiKwcCBjQvlAaBb3D+pMpz6WDY8ECxDK4LrkA2TaFvQLADutcum1AySc0BIehC0AkOjEBy3tVM2nbcxo11DfQNTFgQYESCRIRSUCLs6jBjJhcDOBxIQOPHPOtCkBBCCIaqDdQ2jhCidwwlQYFmELwLEljWLyN2BCYYYK6cg2bo2IlBsDVEtc3AFA34CYDZEDyxQzClovbjuR4ICOQG68CTyF98IFn00ZDQBfAENT00lvIhgZuqpr1EkkhQsNLBuwDKu8ZV6VTpr1OvoHDSL8OlDF67iAuDKDQX3IUKP1IGGSgeX7yEB/J+GvCFQAZAQ4B8Zp4RQB2KbAIJY3RlTjYKdkSmZIoS2VSmLJYSkUMiScwwjcwDVwkAG7dG5COFBj3edaJqCsXILPCBZ7uzIpoDL5SlDCSg/EXckU4UJDD9uKZA=