geo-activity-playground 0.33.3__py3-none-any.whl → 0.34.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,13 +9,14 @@ from typing import Tuple
9
9
 
10
10
  import numpy as np
11
11
  import pandas as pd
12
- import scipy.interpolate
13
12
  from PIL import Image
14
13
  from PIL import ImageEnhance
15
14
  from tqdm import tqdm
16
15
 
17
16
  from ..core.tiles import get_tile
18
17
 
18
+ # import scipy.interpolate
19
+
19
20
 
20
21
  def build_image(
21
22
  center_x: float,
@@ -146,7 +146,7 @@ def float_with_comma_or_period(x: str) -> Optional[float]:
146
146
 
147
147
  def import_from_strava_checkout() -> None:
148
148
  checkout_path = pathlib.Path("Strava Export")
149
- with open(checkout_path / "activities.csv") as f:
149
+ with open(checkout_path / "activities.csv", encoding="utf-8") as f:
150
150
  rows = parse_csv(f.read())
151
151
  header = rows[0]
152
152
 
@@ -159,9 +159,15 @@ def import_from_strava_checkout() -> None:
159
159
 
160
160
  if header[0] == EXPECTED_COLUMNS[0]:
161
161
  dayfirst = False
162
- if header[0] == "Aktivitäts-ID":
162
+ elif header[0] == "Aktivitäts-ID":
163
163
  header = EXPECTED_COLUMNS
164
164
  dayfirst = True
165
+ else:
166
+ logger.error(
167
+ f"You are trying to import a Strava checkout where the `activities.csv` contains an unexpected header format. In order to import this, we need to map these to the English ones. Unfortunately Strava often changes the number of columns. This means that the program needs to be updated to match the new Strava export format. Please go to https://github.com/martin-ueding/geo-activity-playground/issues and open a new issue and share the following output in the ticket:"
168
+ )
169
+ print(header)
170
+ sys.exit(1)
165
171
 
166
172
  table = {
167
173
  header[i]: [rows[r][i] for r in range(1, len(rows))] for i in range(len(header))
@@ -55,6 +55,13 @@ def make_activity_blueprint(
55
55
  **activity_controller.render_day(int(year), int(month), int(day)),
56
56
  )
57
57
 
58
+ @blueprint.route("/day-sharepic/<year>/<month>/<day>/sharepic.png")
59
+ def day_sharepic(year: str, month: str, day: str):
60
+ return Response(
61
+ activity_controller.render_day_sharepic(int(year), int(month), int(day)),
62
+ mimetype="image/png",
63
+ )
64
+
58
65
  @blueprint.route("/name/<name>")
59
66
  def name(name: str):
60
67
  return render_template(
@@ -170,8 +170,24 @@ class ActivityController:
170
170
  "date": datetime.date(year, month, day).isoformat(),
171
171
  "total_distance": activities_that_day["distance_km"].sum(),
172
172
  "total_elapsed_time": activities_that_day["elapsed_time"].sum(),
173
+ "day": day,
174
+ "month": month,
175
+ "year": year,
173
176
  }
174
177
 
178
+ def render_day_sharepic(self, year: int, month: int, day: int) -> bytes:
179
+ meta = self._repository.meta
180
+ selection = meta["start"].dt.date == datetime.date(year, month, day)
181
+ activities_that_day = meta.loc[selection]
182
+
183
+ time_series = [
184
+ self._repository.get_time_series(activity_id)
185
+ for activity_id in activities_that_day["id"]
186
+ ]
187
+ assert len(activities_that_day) > 0
188
+ assert len(time_series) > 0
189
+ return (make_day_sharepic(activities_that_day, time_series, self._config),)
190
+
175
191
  def render_all(self) -> dict:
176
192
  cmap = matplotlib.colormaps["Dark2"]
177
193
  fc = geojson.FeatureCollection(
@@ -452,14 +468,10 @@ def pixels_in_bounds(bounds: PixelBounds) -> int:
452
468
  return (bounds.x_max - bounds.x_min) * (bounds.y_max - bounds.y_min)
453
469
 
454
470
 
455
- def make_sharepic(
456
- activity: ActivityMeta,
457
- time_series: pd.DataFrame,
458
- sharepic_suppressed_fields: list[str],
459
- config: Config,
460
- ) -> bytes:
461
- tile_x = time_series["x"]
462
- tile_y = time_series["y"]
471
+ def make_sharepic_base(time_series_list: list[pd.DataFrame], config: Config):
472
+ all_time_series = pd.concat(time_series_list)
473
+ tile_x = all_time_series["x"]
474
+ tile_y = all_time_series["y"]
463
475
  tile_width = tile_x.max() - tile_x.min()
464
476
  tile_height = tile_y.max() - tile_y.min()
465
477
 
@@ -495,16 +507,32 @@ def make_sharepic(
495
507
  img = Image.fromarray((background * 255).astype("uint8"), "RGB")
496
508
  draw = ImageDraw.Draw(img, mode="RGBA")
497
509
 
498
- for _, group in time_series.groupby("segment_id"):
499
- yx = list(
500
- zip(
501
- (tile_xz - tile_xz_center[0]) * OSM_TILE_SIZE + target_width / 2,
502
- (tile_yz - tile_xz_center[1]) * OSM_TILE_SIZE + target_map_height / 2,
510
+ for time_series in time_series_list:
511
+ for _, group in time_series.groupby("segment_id"):
512
+ yx = list(
513
+ zip(
514
+ (tile_xz - tile_xz_center[0]) * OSM_TILE_SIZE + target_width / 2,
515
+ (tile_yz - tile_xz_center[1]) * OSM_TILE_SIZE
516
+ + target_map_height / 2,
517
+ )
503
518
  )
504
- )
505
519
 
506
- draw.line(yx, fill="red", width=4)
520
+ draw.line(yx, fill="red", width=4)
521
+
522
+ return img
523
+
507
524
 
525
+ def make_sharepic(
526
+ activity: ActivityMeta,
527
+ time_series: pd.DataFrame,
528
+ sharepic_suppressed_fields: list[str],
529
+ config: Config,
530
+ ) -> bytes:
531
+ footer_height = 100
532
+
533
+ img = make_sharepic_base([time_series], config)
534
+
535
+ draw = ImageDraw.Draw(img, mode="RGBA")
508
536
  draw.rectangle(
509
537
  [0, img.height - footer_height, img.width, img.height], fill=(0, 0, 0, 180)
510
538
  )
@@ -545,6 +573,48 @@ def make_sharepic(
545
573
  return bytes(f.getbuffer())
546
574
 
547
575
 
576
+ def make_day_sharepic(
577
+ activities: pd.DataFrame,
578
+ time_series_list: list[pd.DataFrame],
579
+ config: Config,
580
+ ) -> bytes:
581
+ footer_height = 100
582
+
583
+ img = make_sharepic_base(time_series_list, config)
584
+
585
+ draw = ImageDraw.Draw(img, mode="RGBA")
586
+ draw.rectangle(
587
+ [0, img.height - footer_height, img.width, img.height], fill=(0, 0, 0, 180)
588
+ )
589
+
590
+ date = activities.iloc[0]["start"].date()
591
+ distance_km = activities["distance_km"].sum()
592
+ elapsed_time: pd.Timedelta = activities["elapsed_time"].sum()
593
+ elapsed_time = elapsed_time.round("s")
594
+
595
+ facts = {
596
+ "date": f"{date}",
597
+ "distance_km": f"{distance_km:.1f} km",
598
+ "elapsed_time": re.sub(r"^0 days ", "", f"{elapsed_time}"),
599
+ }
600
+
601
+ draw.text(
602
+ (35, img.height - footer_height + 10),
603
+ " ".join(facts.values()),
604
+ font_size=20,
605
+ )
606
+
607
+ draw.text(
608
+ (img.width - 250, img.height - 20),
609
+ "Map: © Open Street Map Contributors",
610
+ font_size=14,
611
+ )
612
+
613
+ f = io.BytesIO()
614
+ img.save(f, format="png")
615
+ return bytes(f.getbuffer())
616
+
617
+
548
618
  def _extract_heart_rate_zones(
549
619
  time_series: pd.DataFrame, heart_rate_zone_computer: HeartRateZoneComputer
550
620
  ) -> Optional[pd.DataFrame]:
@@ -30,7 +30,7 @@
30
30
  <ol>
31
31
  {% for activity in activities %}
32
32
  <li><span style="color: {{ activity['color'] }};">█</span> <a
33
- href="{{ url_for('activity.show', id=activity.id) }}">{{
33
+ href="{{ url_for('.show', id=activity.id) }}">{{
34
34
  activity.name }}</a></li>
35
35
  {% endfor %}
36
36
  </ol>
@@ -80,4 +80,8 @@
80
80
  </div>
81
81
  </div>
82
82
 
83
+ <h2>Share picture</h2>
84
+
85
+ <p><img src="{{ url_for('.day_sharepic', year=year, month=month, day=day) }}" /></p>
86
+
83
87
  {% endblock %}
@@ -87,7 +87,7 @@ class EquipmentController:
87
87
  )
88
88
  .mark_bar()
89
89
  .encode(
90
- alt.X("kind", title="Year"),
90
+ alt.X("kind", title="Kind"),
91
91
  alt.Y("sum(distance_km)", title="Distance / km"),
92
92
  )
93
93
  .to_json(format="vega")
@@ -105,6 +105,7 @@ def embellished_activities(meta: pd.DataFrame) -> pd.DataFrame:
105
105
  df["month"] = [start.month for start in df["start"]]
106
106
  df["day"] = [start.day for start in df["start"]]
107
107
  df["week"] = [start.isocalendar().week for start in df["start"]]
108
+ df["iso_year"] = [start.isocalendar().year for start in df["start"]]
108
109
  df["hours"] = [
109
110
  elapsed_time.total_seconds() / 3600 for elapsed_time in df["elapsed_time"]
110
111
  ]
@@ -188,8 +189,8 @@ def plot_yearly_distance(year_kind_total: pd.DataFrame, kind_scale: alt.Scale) -
188
189
 
189
190
  def plot_year_cumulative(df: pd.DataFrame) -> str:
190
191
  year_cumulative = (
191
- df[["year", "week", "distance_km"]]
192
- .groupby("year")
192
+ df[["iso_year", "week", "distance_km"]]
193
+ .groupby("iso_year")
193
194
  .apply(
194
195
  lambda group: pd.DataFrame(
195
196
  {"week": group["week"], "distance_km": group["distance_km"].cumsum()}
@@ -205,10 +206,10 @@ def plot_year_cumulative(df: pd.DataFrame) -> str:
205
206
  .encode(
206
207
  alt.X("week", title="Week"),
207
208
  alt.Y("distance_km", title="Distance / km"),
208
- alt.Color("year:N", title="Year"),
209
+ alt.Color("iso_year:N", title="Year"),
209
210
  [
210
211
  alt.Tooltip("week", title="Week"),
211
- alt.Tooltip("year:N", title="Year"),
212
+ alt.Tooltip("iso_year:N", title="Year"),
212
213
  alt.Tooltip("distance_km", title="Distance / km"),
213
214
  ],
214
215
  )
@@ -234,26 +235,26 @@ def tabulate_year_kind_mean(df: pd.DataFrame) -> pd.DataFrame:
234
235
 
235
236
  def plot_weekly_distance(df: pd.DataFrame, kind_scale: alt.Scale) -> str:
236
237
  week_kind_total_distance = (
237
- df[["year", "week", "kind", "distance_km"]]
238
- .groupby(["year", "week", "kind"])
238
+ df[["iso_year", "week", "kind", "distance_km"]]
239
+ .groupby(["iso_year", "week", "kind"])
239
240
  .sum()
240
241
  .reset_index()
241
242
  )
242
243
  week_kind_total_distance["year_week"] = [
243
244
  f"{year}-{week:02d}"
244
245
  for year, week in zip(
245
- week_kind_total_distance["year"], week_kind_total_distance["week"]
246
+ week_kind_total_distance["iso_year"], week_kind_total_distance["week"]
246
247
  )
247
248
  ]
248
249
 
249
- last_year = week_kind_total_distance["year"].iloc[-1]
250
+ last_year = week_kind_total_distance["iso_year"].iloc[-1]
250
251
  last_week = week_kind_total_distance["week"].iloc[-1]
251
252
 
252
253
  return (
253
254
  alt.Chart(
254
255
  week_kind_total_distance.loc[
255
- (week_kind_total_distance["year"] == last_year)
256
- | (week_kind_total_distance["year"] == last_year - 1)
256
+ (week_kind_total_distance["iso_year"] == last_year)
257
+ | (week_kind_total_distance["iso_year"] == last_year - 1)
257
258
  & (week_kind_total_distance["week"] >= last_week)
258
259
  ],
259
260
  title="Weekly Distance",
@@ -1,17 +1,17 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geo-activity-playground
3
- Version: 0.33.3
3
+ Version: 0.34.0
4
4
  Summary: Analysis of geo data activities like rides, runs or hikes.
5
5
  License: MIT
6
6
  Author: Martin Ueding
7
7
  Author-email: mu@martin-ueding.de
8
- Requires-Python: >=3.10,<3.13
8
+ Requires-Python: >=3.10,<3.14
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: Pillow (>=10.3.0,<11.0.0)
14
+ Requires-Dist: Pillow (>=11.0.0,<12.0.0)
15
15
  Requires-Dist: altair (>=5.1.2,<6.0.0)
16
16
  Requires-Dist: appdirs (>=1.4.4,<2.0.0)
17
17
  Requires-Dist: charset-normalizer (>=3.3.2,<4.0.0)
@@ -22,12 +22,11 @@ Requires-Dist: geojson (>=3.0.1,<4.0.0)
22
22
  Requires-Dist: gpxpy (>=1.5.0,<2.0.0)
23
23
  Requires-Dist: jinja2 (>=3.1.2,<4.0.0)
24
24
  Requires-Dist: matplotlib (>=3.6.3,<4.0.0)
25
- Requires-Dist: numpy (>=1.22.4,<2.0.0)
25
+ Requires-Dist: numpy (>=2.1.3,<3.0.0)
26
26
  Requires-Dist: pandas (>=2.2,<3.0)
27
- Requires-Dist: pyarrow (>=16.1.0,<17.0.0)
27
+ Requires-Dist: pyarrow (>=18.1.0,<19.0.0)
28
28
  Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
29
29
  Requires-Dist: requests (>=2.28.1,<3.0.0)
30
- Requires-Dist: scipy (>=1.8.1,<2.0.0)
31
30
  Requires-Dist: shapely (>=2.0.5,<3.0.0)
32
31
  Requires-Dist: stravalib (>=2.0,<3.0)
33
32
  Requires-Dist: tcxreader (>=0.4.5,<0.5.0)
@@ -18,21 +18,21 @@ geo_activity_playground/core/time_conversion.py,sha256=x5mXG6Y4GtdX7CBmwucGNSWBp
18
18
  geo_activity_playground/explorer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  geo_activity_playground/explorer/grid_file.py,sha256=k6j6KBEk2a2BY-onE8SV5TJsERGGyOrlY4as__meWpA,3304
20
20
  geo_activity_playground/explorer/tile_visits.py,sha256=CSHAjgzKWe1iB-zvaqgsR5Z_lFycpWqUfxnPCAWvYaU,14173
21
- geo_activity_playground/explorer/video.py,sha256=ROAmV9shfJyqTgnXVD41KFORiwnRgVpEWenIq4hMCRM,4389
21
+ geo_activity_playground/explorer/video.py,sha256=35-mMEvD8phnc2xbWdwCHhl_uMIUogHrnFwrTfk2Yj8,4392
22
22
  geo_activity_playground/importers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  geo_activity_playground/importers/activity_parsers.py,sha256=XNQs0ziqAcVqIoiLAX5Ndmhb6v__29XdjUPvNvc7oBI,11082
24
24
  geo_activity_playground/importers/csv_parser.py,sha256=O1pP5GLhWhnWcy2Lsrr9g17Zspuibpt-GtZ3ZS5eZF4,2143
25
25
  geo_activity_playground/importers/directory.py,sha256=CA-vFOMm8G4MSM_Q09OwQKduCApL2PWaxLTVxgw_xpw,5908
26
26
  geo_activity_playground/importers/strava_api.py,sha256=cJCZsLemhOlxTtZh0z_npidgae9SD5HyEUry2uvem_A,7775
27
- geo_activity_playground/importers/strava_checkout.py,sha256=N-uGTkhBJMC7cPYjRRXHOSLwpK3wc6aaSrY2RQfSitA,9419
27
+ geo_activity_playground/importers/strava_checkout.py,sha256=dAKW1wVqlA5zRw25SvpYZZrEikJtaUluInyhJ0RfsFc,10002
28
28
  geo_activity_playground/importers/test_csv_parser.py,sha256=LXqva7GuSAfXYE2zZQrg-69lCtfy5MxLSq6BRwL_VyI,1191
29
29
  geo_activity_playground/importers/test_directory.py,sha256=ljXokx7q0OgtHvEdHftcQYEmZJUDVv3OOF5opklxdT4,724
30
30
  geo_activity_playground/importers/test_strava_api.py,sha256=4vX7wDr1a9aRh8myxNrIq6RwDBbP8ZeoXXPc10CAbW4,431
31
31
  geo_activity_playground/webui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  geo_activity_playground/webui/activity/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- geo_activity_playground/webui/activity/blueprint.py,sha256=Ub2mC9S9TII7CJaaWahnbNtT76uOGKNDWE0-j2C56CA,3893
34
- geo_activity_playground/webui/activity/controller.py,sha256=t4-9-Gxchc959AaOOflSTYhNiGBuJT2nu1UZ0Vv_nxU,19343
35
- geo_activity_playground/webui/activity/templates/activity/day.html.j2,sha256=Gitp3IR913YTjzlz_OiWIe3VSN4OmFGZVGPuMVINCg4,2693
33
+ geo_activity_playground/webui/activity/blueprint.py,sha256=2Fa_6a86Aa3Yr3hQdkRylQqqVusyyVzPd1x3il5ZXNk,4176
34
+ geo_activity_playground/webui/activity/controller.py,sha256=0HXQZAD9Muf62jV-GqQKJPq5qNgdbV-KEcPmHX_8iGo,21429
35
+ geo_activity_playground/webui/activity/templates/activity/day.html.j2,sha256=wkYmcnIsMlvE9wgKemYCNU6jwsk5IJvg8pcBA2OMh00,2795
36
36
  geo_activity_playground/webui/activity/templates/activity/edit.html.j2,sha256=ckcTTxcQOhmvvAGNTEOtWCUG4LhvO4HfQImlIa5qKs8,1530
37
37
  geo_activity_playground/webui/activity/templates/activity/lines.html.j2,sha256=_ZDg1ruW-9UMJfOudy1-uY_-IcSSaagq7tPCih5Bb8g,1079
38
38
  geo_activity_playground/webui/activity/templates/activity/name.html.j2,sha256=tKviMqMouHEGv3xBQVIsJgwj_hjwAsmGVefM3UMqlYg,2437
@@ -53,7 +53,7 @@ geo_activity_playground/webui/eddington/templates/eddington/index.html.j2,sha256
53
53
  geo_activity_playground/webui/entry_controller.py,sha256=McxbyouKWHJ3a2R9agPazZoG7VHiFO1RvnkBr08dMH8,2168
54
54
  geo_activity_playground/webui/equipment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  geo_activity_playground/webui/equipment/blueprint.py,sha256=_NIhRJuJNbXpEd_nEPo01AqnUqPgo1vawFn7E3yoeng,636
56
- geo_activity_playground/webui/equipment/controller.py,sha256=Sx9i2RCK7m4W6FgpDfRMewcH64VBQfUhHJdTSCwMqOU,4079
56
+ geo_activity_playground/webui/equipment/controller.py,sha256=lMivui3EBUnkYZf9Lgv1kHZ0c7IxRAza-ox8YOz3ONY,4079
57
57
  geo_activity_playground/webui/equipment/templates/equipment/index.html.j2,sha256=fvRaDbCuiSZ8AzJTpu1dk8FTAGZ2yfsLhprtVYHFZWo,1802
58
58
  geo_activity_playground/webui/explorer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  geo_activity_playground/webui/explorer/blueprint.py,sha256=EKnBs8llqT6Wy1uac18dF2epp3TebF9p3iGlSbj6Vl0,2337
@@ -100,7 +100,7 @@ geo_activity_playground/webui/static/web-app-manifest-192x192.png,sha256=eEImN6i
100
100
  geo_activity_playground/webui/static/web-app-manifest-512x512.png,sha256=vU9oQ4HnQerFDZVzcAT9twj4_Doc6_9v9wVvoRI-f_E,48318
101
101
  geo_activity_playground/webui/summary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
102
  geo_activity_playground/webui/summary/blueprint.py,sha256=tfA2aPF19yKwkQOb5lPQBySoQYYhTn49Iuh0SYvsGP8,593
103
- geo_activity_playground/webui/summary/controller.py,sha256=V3zBLNL_Yc_Ft-ZBaWnlLXhr8VsvTpipPUZ-G9sgUXs,9312
103
+ geo_activity_playground/webui/summary/controller.py,sha256=FyPdC98maX0P5sJ4j5Z7-ZSiirLh_jmu_PszKXqTV8A,9425
104
104
  geo_activity_playground/webui/summary/templates/summary/index.html.j2,sha256=ctOx3Qjx6nRDpUtFf1DlJhK_gtU77Vwx_S6euLz9-W4,5183
105
105
  geo_activity_playground/webui/templates/home.html.j2,sha256=IdCqI_LLcYrpUjjCO-tbXR4s05XYrPOateiJ4idF3bo,2202
106
106
  geo_activity_playground/webui/templates/page.html.j2,sha256=znTbtD2NALrhmUN_Q-F1ElGlKtecoUv8vOCcUtojrdI,11134
@@ -110,8 +110,8 @@ geo_activity_playground/webui/tile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQe
110
110
  geo_activity_playground/webui/tile/blueprint.py,sha256=q0sw_F8L367Df01yjZijikEIglFBgg9lN61sbTAEOKQ,1018
111
111
  geo_activity_playground/webui/tile/controller.py,sha256=XjUTbyAMeQET1D3mFtT8r5-xMcMOaELPZWtQ1Xp7Cuw,1428
112
112
  geo_activity_playground/webui/upload_blueprint.py,sha256=topLI9ytDUFkqCc9AlOqDkjhABUwnPJ1tX_7XrBPbxc,4412
113
- geo_activity_playground-0.33.3.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
114
- geo_activity_playground-0.33.3.dist-info/METADATA,sha256=eUVURIw-QgIO2bQUHVXXrPNf35-v_XEywE9iwQ6mfa8,1612
115
- geo_activity_playground-0.33.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
116
- geo_activity_playground-0.33.3.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
117
- geo_activity_playground-0.33.3.dist-info/RECORD,,
113
+ geo_activity_playground-0.34.0.dist-info/LICENSE,sha256=4RpAwKO8bPkfXH2lnpeUW0eLkNWglyG4lbrLDU_MOwY,1070
114
+ geo_activity_playground-0.34.0.dist-info/METADATA,sha256=36V6xU7OXmcZrN-eqQfkzaRnFKCfA4ICmVjx-dzqWP0,1573
115
+ geo_activity_playground-0.34.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
116
+ geo_activity_playground-0.34.0.dist-info/entry_points.txt,sha256=pbNlLI6IIZIp7nPYCfAtiSiz2oxJSCl7DODD6SPkLKk,81
117
+ geo_activity_playground-0.34.0.dist-info/RECORD,,