darabos commited on
Commit
d6c271c
·
1 Parent(s): 4a2c869

Let "night demo" load the data from GCS, rename to "Airlines demo".

Browse files
examples/{night demo → Airlines demo} RENAMED
The diff for this file is too large to render. See raw diff
 
lynxkite-app/web/tests/examples.spec.ts CHANGED
@@ -36,10 +36,8 @@ test.fail("RAG chatbot app", async ({ page }) => {
36
  expect(await ws.isErrorFree()).toBeTruthy();
37
  });
38
 
39
- test.fail("night demo", async ({ page }) => {
40
- // airlines.graphml file not found
41
- // requires cugraph
42
- const ws = await Workspace.open(page, "night demo");
43
  expect(await ws.isErrorFree(process.env.CI ? 10000 : 500)).toBeTruthy();
44
  });
45
 
 
36
  expect(await ws.isErrorFree()).toBeTruthy();
37
  });
38
 
39
+ test("Airlines demo", async ({ page }) => {
40
+ const ws = await Workspace.open(page, "Airlines demo");
 
 
41
  expect(await ws.isErrorFree(process.env.CI ? 10000 : 500)).toBeTruthy();
42
  });
43
 
lynxkite-core/src/lynxkite/core/workspace.py CHANGED
@@ -65,7 +65,7 @@ async def execute(ws: Workspace):
65
 
66
  def save(ws: Workspace, path: str):
67
  """Persist a workspace to a local file in JSON format."""
68
- j = ws.model_dump_json(indent=2)
69
  dirname, basename = os.path.split(path)
70
  os.makedirs(dirname, exist_ok=True)
71
  # Create temp file in the same directory to make sure it's on the same filesystem.
 
65
 
66
  def save(ws: Workspace, path: str):
67
  """Persist a workspace to a local file in JSON format."""
68
+ j = ws.model_dump_json(indent=2) + "\n"
69
  dirname, basename = os.path.split(path)
70
  os.makedirs(dirname, exist_ok=True)
71
  # Create temp file in the same directory to make sure it's on the same filesystem.
lynxkite-graph-analytics/pyproject.toml CHANGED
@@ -5,6 +5,7 @@ description = "The graph analytics executor and boxes for LynxKite"
5
  readme = "README.md"
6
  requires-python = ">=3.11"
7
  dependencies = [
 
8
  "grand-cypher>=0.12.0",
9
  "joblib>=1.4.2",
10
  "lynxkite-core",
 
5
  readme = "README.md"
6
  requires-python = ">=3.11"
7
  dependencies = [
8
+ "fsspec>=2025.2.0",
9
  "grand-cypher>=0.12.0",
10
  "joblib>=1.4.2",
11
  "lynxkite-core",
lynxkite-graph-analytics/src/lynxkite_graph_analytics/lynxkite_ops.py CHANGED
@@ -1,7 +1,8 @@
1
  """Graph analytics operations. To be split into separate files when we have more."""
2
 
3
  import os
4
- from lynxkite.core import ops, workspace
 
5
  from collections import deque
6
  import dataclasses
7
  import functools
@@ -13,7 +14,6 @@ import pandas as pd
13
  import polars as pl
14
  import traceback
15
  import typing
16
- import zipfile
17
 
18
  mem = joblib.Memory("../joblib-cache")
19
  ENV = "LynxKite Graph Analytics"
@@ -178,6 +178,7 @@ def import_parquet(*, filename: str):
178
  return pd.read_parquet(filename)
179
 
180
 
 
181
  @op("Import CSV")
182
  def import_csv(
183
  *, filename: str, columns: str = "<from file>", separator: str = "<auto>"
@@ -192,26 +193,20 @@ def import_csv(
192
  )
193
 
194
 
195
- @op("Import GraphML")
196
  @mem.cache
 
197
  def import_graphml(*, filename: str):
198
  """Imports a GraphML file."""
199
- if filename.endswith(".zip"):
200
- with zipfile.ZipFile(filename, "r") as z:
201
- for fn in z.namelist():
202
- if fn.endswith(".graphml"):
203
- with z.open(fn) as f:
204
- G = nx.read_graphml(f)
205
- break
206
- else:
207
- raise ValueError("No GraphML file found in the ZIP archive.")
208
- else:
209
- G = nx.read_graphml(filename)
210
- return G
211
 
212
 
213
- @op("Graph from OSM")
214
  @mem.cache
 
215
  def import_osm(*, location: str):
216
  import osmnx as ox
217
 
 
1
  """Graph analytics operations. To be split into separate files when we have more."""
2
 
3
  import os
4
+ import fsspec
5
+ from lynxkite.core import ops
6
  from collections import deque
7
  import dataclasses
8
  import functools
 
14
  import polars as pl
15
  import traceback
16
  import typing
 
17
 
18
  mem = joblib.Memory("../joblib-cache")
19
  ENV = "LynxKite Graph Analytics"
 
178
  return pd.read_parquet(filename)
179
 
180
 
181
+ @mem.cache
182
  @op("Import CSV")
183
  def import_csv(
184
  *, filename: str, columns: str = "<from file>", separator: str = "<auto>"
 
193
  )
194
 
195
 
 
196
  @mem.cache
197
+ @op("Import GraphML")
198
  def import_graphml(*, filename: str):
199
  """Imports a GraphML file."""
200
+ files = fsspec.open_files(filename, compression="infer")
201
+ for f in files:
202
+ if ".graphml" in f.path:
203
+ with f as f:
204
+ return nx.read_graphml(f)
205
+ raise ValueError(f"No .graphml file found at {filename}")
 
 
 
 
 
 
206
 
207
 
 
208
  @mem.cache
209
+ @op("Graph from OSM")
210
  def import_osm(*, location: str):
211
  import osmnx as ox
212
 
lynxkite-graph-analytics/uv.lock CHANGED
@@ -66,6 +66,15 @@ wheels = [
66
  { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
67
  ]
68
 
 
 
 
 
 
 
 
 
 
69
  [[package]]
70
  name = "contourpy"
71
  version = "1.3.1"
@@ -229,6 +238,15 @@ wheels = [
229
  { url = "https://files.pythonhosted.org/packages/99/3b/406d17b1f63e04a82aa621936e6e1c53a8c05458abd66300ac85ea7f9ae9/fonttools-4.55.3-py3-none-any.whl", hash = "sha256:f412604ccbeee81b091b420272841e5ec5ef68967a9790e80bffd0e30b8e2977", size = 1111638 },
230
  ]
231
 
 
 
 
 
 
 
 
 
 
232
  [[package]]
233
  name = "geopandas"
234
  version = "1.0.1"
@@ -275,6 +293,15 @@ wheels = [
275
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
276
  ]
277
 
 
 
 
 
 
 
 
 
 
278
  [[package]]
279
  name = "joblib"
280
  version = "1.4.2"
@@ -404,37 +431,48 @@ name = "lynxkite-core"
404
  version = "0.1.0"
405
  source = { virtual = "../lynxkite-core" }
406
 
 
 
 
407
  [[package]]
408
  name = "lynxkite-graph-analytics"
409
  version = "0.1.0"
410
  source = { virtual = "." }
411
  dependencies = [
 
412
  { name = "grand-cypher" },
413
  { name = "joblib" },
414
  { name = "lynxkite-core" },
415
  { name = "matplotlib" },
416
- { name = "networkx" },
417
  { name = "osmnx" },
418
  { name = "pandas" },
419
  { name = "polars", extra = ["gpu"] },
420
  ]
421
 
422
  [package.optional-dependencies]
 
 
 
 
423
  gpu = [
424
  { name = "nx-cugraph-cu12" },
425
  ]
426
 
427
  [package.metadata]
428
  requires-dist = [
 
429
  { name = "grand-cypher", specifier = ">=0.12.0" },
430
  { name = "joblib", specifier = ">=1.4.2" },
431
  { name = "lynxkite-core", virtual = "../lynxkite-core" },
432
  { name = "matplotlib", specifier = ">=3.10.0" },
433
- { name = "networkx", specifier = ">=3.4.2" },
434
  { name = "nx-cugraph-cu12", marker = "extra == 'gpu'", specifier = ">=24.12.0" },
435
  { name = "osmnx", specifier = ">=2.0.1" },
436
  { name = "pandas", specifier = ">=2.2.3" },
437
  { name = "polars", extras = ["gpu"], specifier = ">=1.14.0" },
 
 
438
  ]
439
 
440
  [[package]]
@@ -489,6 +527,14 @@ wheels = [
489
  { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 },
490
  ]
491
 
 
 
 
 
 
 
 
 
492
  [[package]]
493
  name = "numba"
494
  version = "0.60.0"
@@ -747,6 +793,15 @@ wheels = [
747
  { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 },
748
  ]
749
 
 
 
 
 
 
 
 
 
 
750
  [[package]]
751
  name = "polars"
752
  version = "1.14.0"
@@ -918,6 +973,33 @@ wheels = [
918
  { url = "https://files.pythonhosted.org/packages/f8/33/3c8c6302717096b54aa14ccbb271045ba04629e21cbf348f2f2dc94f69b4/pyproj-3.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:10a8dc6ec61af97c89ff032647d743f8dc023645773da42ef43f7ae1125b3509", size = 6218036 },
919
  ]
920
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
921
  [[package]]
922
  name = "python-dateutil"
923
  version = "2.9.0.post0"
@@ -970,6 +1052,53 @@ wheels = [
970
  { url = "https://files.pythonhosted.org/packages/1d/f2/56faa578aefdab498f6eb73dde3316f99390769786e0cdbb6c7a6abbbf86/rmm_cu12-24.12.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9460a386e34f1921c8d06204f320d705511de899ababb45302d314da036da5a", size = 1975053 },
971
  ]
972
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
973
  [[package]]
974
  name = "shapely"
975
  version = "2.0.7"
 
66
  { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
67
  ]
68
 
69
+ [[package]]
70
+ name = "colorama"
71
+ version = "0.4.6"
72
+ source = { registry = "https://pypi.org/simple" }
73
+ sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
74
+ wheels = [
75
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
76
+ ]
77
+
78
  [[package]]
79
  name = "contourpy"
80
  version = "1.3.1"
 
238
  { url = "https://files.pythonhosted.org/packages/99/3b/406d17b1f63e04a82aa621936e6e1c53a8c05458abd66300ac85ea7f9ae9/fonttools-4.55.3-py3-none-any.whl", hash = "sha256:f412604ccbeee81b091b420272841e5ec5ef68967a9790e80bffd0e30b8e2977", size = 1111638 },
239
  ]
240
 
241
+ [[package]]
242
+ name = "fsspec"
243
+ version = "2025.2.0"
244
+ source = { registry = "https://pypi.org/simple" }
245
+ sdist = { url = "https://files.pythonhosted.org/packages/b5/79/68612ed99700e6413de42895aa725463e821a6b3be75c87fcce1b4af4c70/fsspec-2025.2.0.tar.gz", hash = "sha256:1c24b16eaa0a1798afa0337aa0db9b256718ab2a89c425371f5628d22c3b6afd", size = 292283 }
246
+ wheels = [
247
+ { url = "https://files.pythonhosted.org/packages/e2/94/758680531a00d06e471ef649e4ec2ed6bf185356a7f9fbfbb7368a40bd49/fsspec-2025.2.0-py3-none-any.whl", hash = "sha256:9de2ad9ce1f85e1931858535bc882543171d197001a0a5eb2ddc04f1781ab95b", size = 184484 },
248
+ ]
249
+
250
  [[package]]
251
  name = "geopandas"
252
  version = "1.0.1"
 
293
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
294
  ]
295
 
296
+ [[package]]
297
+ name = "iniconfig"
298
+ version = "2.0.0"
299
+ source = { registry = "https://pypi.org/simple" }
300
+ sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 }
301
+ wheels = [
302
+ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 },
303
+ ]
304
+
305
  [[package]]
306
  name = "joblib"
307
  version = "1.4.2"
 
431
  version = "0.1.0"
432
  source = { virtual = "../lynxkite-core" }
433
 
434
+ [package.metadata]
435
+ requires-dist = [{ name = "pytest", marker = "extra == 'dev'" }]
436
+
437
  [[package]]
438
  name = "lynxkite-graph-analytics"
439
  version = "0.1.0"
440
  source = { virtual = "." }
441
  dependencies = [
442
+ { name = "fsspec" },
443
  { name = "grand-cypher" },
444
  { name = "joblib" },
445
  { name = "lynxkite-core" },
446
  { name = "matplotlib" },
447
+ { name = "networkx", extra = ["default"] },
448
  { name = "osmnx" },
449
  { name = "pandas" },
450
  { name = "polars", extra = ["gpu"] },
451
  ]
452
 
453
  [package.optional-dependencies]
454
+ dev = [
455
+ { name = "pytest" },
456
+ { name = "pytest-asyncio" },
457
+ ]
458
  gpu = [
459
  { name = "nx-cugraph-cu12" },
460
  ]
461
 
462
  [package.metadata]
463
  requires-dist = [
464
+ { name = "fsspec", specifier = ">=2025.2.0" },
465
  { name = "grand-cypher", specifier = ">=0.12.0" },
466
  { name = "joblib", specifier = ">=1.4.2" },
467
  { name = "lynxkite-core", virtual = "../lynxkite-core" },
468
  { name = "matplotlib", specifier = ">=3.10.0" },
469
+ { name = "networkx", extras = ["default"], specifier = ">=3.4.2" },
470
  { name = "nx-cugraph-cu12", marker = "extra == 'gpu'", specifier = ">=24.12.0" },
471
  { name = "osmnx", specifier = ">=2.0.1" },
472
  { name = "pandas", specifier = ">=2.2.3" },
473
  { name = "polars", extras = ["gpu"], specifier = ">=1.14.0" },
474
+ { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.4" },
475
+ { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.25.3" },
476
  ]
477
 
478
  [[package]]
 
527
  { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 },
528
  ]
529
 
530
+ [package.optional-dependencies]
531
+ default = [
532
+ { name = "matplotlib" },
533
+ { name = "numpy" },
534
+ { name = "pandas" },
535
+ { name = "scipy" },
536
+ ]
537
+
538
  [[package]]
539
  name = "numba"
540
  version = "0.60.0"
 
793
  { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 },
794
  ]
795
 
796
+ [[package]]
797
+ name = "pluggy"
798
+ version = "1.5.0"
799
+ source = { registry = "https://pypi.org/simple" }
800
+ sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 }
801
+ wheels = [
802
+ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 },
803
+ ]
804
+
805
  [[package]]
806
  name = "polars"
807
  version = "1.14.0"
 
973
  { url = "https://files.pythonhosted.org/packages/f8/33/3c8c6302717096b54aa14ccbb271045ba04629e21cbf348f2f2dc94f69b4/pyproj-3.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:10a8dc6ec61af97c89ff032647d743f8dc023645773da42ef43f7ae1125b3509", size = 6218036 },
974
  ]
975
 
976
+ [[package]]
977
+ name = "pytest"
978
+ version = "8.3.4"
979
+ source = { registry = "https://pypi.org/simple" }
980
+ dependencies = [
981
+ { name = "colorama", marker = "sys_platform == 'win32'" },
982
+ { name = "iniconfig" },
983
+ { name = "packaging" },
984
+ { name = "pluggy" },
985
+ ]
986
+ sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 }
987
+ wheels = [
988
+ { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 },
989
+ ]
990
+
991
+ [[package]]
992
+ name = "pytest-asyncio"
993
+ version = "0.25.3"
994
+ source = { registry = "https://pypi.org/simple" }
995
+ dependencies = [
996
+ { name = "pytest" },
997
+ ]
998
+ sdist = { url = "https://files.pythonhosted.org/packages/f2/a8/ecbc8ede70921dd2f544ab1cadd3ff3bf842af27f87bbdea774c7baa1d38/pytest_asyncio-0.25.3.tar.gz", hash = "sha256:fc1da2cf9f125ada7e710b4ddad05518d4cee187ae9412e9ac9271003497f07a", size = 54239 }
999
+ wheels = [
1000
+ { url = "https://files.pythonhosted.org/packages/67/17/3493c5624e48fd97156ebaec380dcaafee9506d7e2c46218ceebbb57d7de/pytest_asyncio-0.25.3-py3-none-any.whl", hash = "sha256:9e89518e0f9bd08928f97a3482fdc4e244df17529460bc038291ccaf8f85c7c3", size = 19467 },
1001
+ ]
1002
+
1003
  [[package]]
1004
  name = "python-dateutil"
1005
  version = "2.9.0.post0"
 
1052
  { url = "https://files.pythonhosted.org/packages/1d/f2/56faa578aefdab498f6eb73dde3316f99390769786e0cdbb6c7a6abbbf86/rmm_cu12-24.12.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9460a386e34f1921c8d06204f320d705511de899ababb45302d314da036da5a", size = 1975053 },
1053
  ]
1054
 
1055
+ [[package]]
1056
+ name = "scipy"
1057
+ version = "1.15.2"
1058
+ source = { registry = "https://pypi.org/simple" }
1059
+ dependencies = [
1060
+ { name = "numpy" },
1061
+ ]
1062
+ sdist = { url = "https://files.pythonhosted.org/packages/b7/b9/31ba9cd990e626574baf93fbc1ac61cf9ed54faafd04c479117517661637/scipy-1.15.2.tar.gz", hash = "sha256:cd58a314d92838f7e6f755c8a2167ead4f27e1fd5c1251fd54289569ef3495ec", size = 59417316 }
1063
+ wheels = [
1064
+ { url = "https://files.pythonhosted.org/packages/40/1f/bf0a5f338bda7c35c08b4ed0df797e7bafe8a78a97275e9f439aceb46193/scipy-1.15.2-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:92233b2df6938147be6fa8824b8136f29a18f016ecde986666be5f4d686a91a4", size = 38703651 },
1065
+ { url = "https://files.pythonhosted.org/packages/de/54/db126aad3874601048c2c20ae3d8a433dbfd7ba8381551e6f62606d9bd8e/scipy-1.15.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:62ca1ff3eb513e09ed17a5736929429189adf16d2d740f44e53270cc800ecff1", size = 30102038 },
1066
+ { url = "https://files.pythonhosted.org/packages/61/d8/84da3fffefb6c7d5a16968fe5b9f24c98606b165bb801bb0b8bc3985200f/scipy-1.15.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4c6676490ad76d1c2894d77f976144b41bd1a4052107902238047fb6a473e971", size = 22375518 },
1067
+ { url = "https://files.pythonhosted.org/packages/44/78/25535a6e63d3b9c4c90147371aedb5d04c72f3aee3a34451f2dc27c0c07f/scipy-1.15.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a8bf5cb4a25046ac61d38f8d3c3426ec11ebc350246a4642f2f315fe95bda655", size = 25142523 },
1068
+ { url = "https://files.pythonhosted.org/packages/e0/22/4b4a26fe1cd9ed0bc2b2cb87b17d57e32ab72c346949eaf9288001f8aa8e/scipy-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a8e34cf4c188b6dd004654f88586d78f95639e48a25dfae9c5e34a6dc34547e", size = 35491547 },
1069
+ { url = "https://files.pythonhosted.org/packages/32/ea/564bacc26b676c06a00266a3f25fdfe91a9d9a2532ccea7ce6dd394541bc/scipy-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28a0d2c2075946346e4408b211240764759e0fabaeb08d871639b5f3b1aca8a0", size = 37634077 },
1070
+ { url = "https://files.pythonhosted.org/packages/43/c2/bfd4e60668897a303b0ffb7191e965a5da4056f0d98acfb6ba529678f0fb/scipy-1.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:42dabaaa798e987c425ed76062794e93a243be8f0f20fff6e7a89f4d61cb3d40", size = 37231657 },
1071
+ { url = "https://files.pythonhosted.org/packages/4a/75/5f13050bf4f84c931bcab4f4e83c212a36876c3c2244475db34e4b5fe1a6/scipy-1.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f5e296ec63c5da6ba6fa0343ea73fd51b8b3e1a300b0a8cae3ed4b1122c7462", size = 40035857 },
1072
+ { url = "https://files.pythonhosted.org/packages/b9/8b/7ec1832b09dbc88f3db411f8cdd47db04505c4b72c99b11c920a8f0479c3/scipy-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:597a0c7008b21c035831c39927406c6181bcf8f60a73f36219b69d010aa04737", size = 41217654 },
1073
+ { url = "https://files.pythonhosted.org/packages/4b/5d/3c78815cbab499610f26b5bae6aed33e227225a9fa5290008a733a64f6fc/scipy-1.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c4697a10da8f8765bb7c83e24a470da5797e37041edfd77fd95ba3811a47c4fd", size = 38756184 },
1074
+ { url = "https://files.pythonhosted.org/packages/37/20/3d04eb066b471b6e171827548b9ddb3c21c6bbea72a4d84fc5989933910b/scipy-1.15.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:869269b767d5ee7ea6991ed7e22b3ca1f22de73ab9a49c44bad338b725603301", size = 30163558 },
1075
+ { url = "https://files.pythonhosted.org/packages/a4/98/e5c964526c929ef1f795d4c343b2ff98634ad2051bd2bbadfef9e772e413/scipy-1.15.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bad78d580270a4d32470563ea86c6590b465cb98f83d760ff5b0990cb5518a93", size = 22437211 },
1076
+ { url = "https://files.pythonhosted.org/packages/1d/cd/1dc7371e29195ecbf5222f9afeedb210e0a75057d8afbd942aa6cf8c8eca/scipy-1.15.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:b09ae80010f52efddb15551025f9016c910296cf70adbf03ce2a8704f3a5ad20", size = 25232260 },
1077
+ { url = "https://files.pythonhosted.org/packages/f0/24/1a181a9e5050090e0b5138c5f496fee33293c342b788d02586bc410c6477/scipy-1.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a6fd6eac1ce74a9f77a7fc724080d507c5812d61e72bd5e4c489b042455865e", size = 35198095 },
1078
+ { url = "https://files.pythonhosted.org/packages/c0/53/eaada1a414c026673eb983f8b4a55fe5eb172725d33d62c1b21f63ff6ca4/scipy-1.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b871df1fe1a3ba85d90e22742b93584f8d2b8e6124f8372ab15c71b73e428b8", size = 37297371 },
1079
+ { url = "https://files.pythonhosted.org/packages/e9/06/0449b744892ed22b7e7b9a1994a866e64895363572677a316a9042af1fe5/scipy-1.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:03205d57a28e18dfd39f0377d5002725bf1f19a46f444108c29bdb246b6c8a11", size = 36872390 },
1080
+ { url = "https://files.pythonhosted.org/packages/6a/6f/a8ac3cfd9505ec695c1bc35edc034d13afbd2fc1882a7c6b473e280397bb/scipy-1.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:601881dfb761311045b03114c5fe718a12634e5608c3b403737ae463c9885d53", size = 39700276 },
1081
+ { url = "https://files.pythonhosted.org/packages/f5/6f/e6e5aff77ea2a48dd96808bb51d7450875af154ee7cbe72188afb0b37929/scipy-1.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:e7c68b6a43259ba0aab737237876e5c2c549a031ddb7abc28c7b47f22e202ded", size = 40942317 },
1082
+ { url = "https://files.pythonhosted.org/packages/53/40/09319f6e0f276ea2754196185f95cd191cb852288440ce035d5c3a931ea2/scipy-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01edfac9f0798ad6b46d9c4c9ca0e0ad23dbf0b1eb70e96adb9fa7f525eff0bf", size = 38717587 },
1083
+ { url = "https://files.pythonhosted.org/packages/fe/c3/2854f40ecd19585d65afaef601e5e1f8dbf6758b2f95b5ea93d38655a2c6/scipy-1.15.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:08b57a9336b8e79b305a143c3655cc5bdbe6d5ece3378578888d2afbb51c4e37", size = 30100266 },
1084
+ { url = "https://files.pythonhosted.org/packages/dd/b1/f9fe6e3c828cb5930b5fe74cb479de5f3d66d682fa8adb77249acaf545b8/scipy-1.15.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:54c462098484e7466362a9f1672d20888f724911a74c22ae35b61f9c5919183d", size = 22373768 },
1085
+ { url = "https://files.pythonhosted.org/packages/15/9d/a60db8c795700414c3f681908a2b911e031e024d93214f2d23c6dae174ab/scipy-1.15.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:cf72ff559a53a6a6d77bd8eefd12a17995ffa44ad86c77a5df96f533d4e6c6bb", size = 25154719 },
1086
+ { url = "https://files.pythonhosted.org/packages/37/3b/9bda92a85cd93f19f9ed90ade84aa1e51657e29988317fabdd44544f1dd4/scipy-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9de9d1416b3d9e7df9923ab23cd2fe714244af10b763975bea9e4f2e81cebd27", size = 35163195 },
1087
+ { url = "https://files.pythonhosted.org/packages/03/5a/fc34bf1aa14dc7c0e701691fa8685f3faec80e57d816615e3625f28feb43/scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb530e4794fc8ea76a4a21ccb67dea33e5e0e60f07fc38a49e821e1eae3b71a0", size = 37255404 },
1088
+ { url = "https://files.pythonhosted.org/packages/4a/71/472eac45440cee134c8a180dbe4c01b3ec247e0338b7c759e6cd71f199a7/scipy-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5ea7ed46d437fc52350b028b1d44e002646e28f3e8ddc714011aaf87330f2f32", size = 36860011 },
1089
+ { url = "https://files.pythonhosted.org/packages/01/b3/21f890f4f42daf20e4d3aaa18182dddb9192771cd47445aaae2e318f6738/scipy-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11e7ad32cf184b74380f43d3c0a706f49358b904fa7d5345f16ddf993609184d", size = 39657406 },
1090
+ { url = "https://files.pythonhosted.org/packages/0d/76/77cf2ac1f2a9cc00c073d49e1e16244e389dd88e2490c91d84e1e3e4d126/scipy-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:a5080a79dfb9b78b768cebf3c9dcbc7b665c5875793569f48bf0e2b1d7f68f6f", size = 40961243 },
1091
+ { url = "https://files.pythonhosted.org/packages/4c/4b/a57f8ddcf48e129e6054fa9899a2a86d1fc6b07a0e15c7eebff7ca94533f/scipy-1.15.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:447ce30cee6a9d5d1379087c9e474628dab3db4a67484be1b7dc3196bfb2fac9", size = 38870286 },
1092
+ { url = "https://files.pythonhosted.org/packages/0c/43/c304d69a56c91ad5f188c0714f6a97b9c1fed93128c691148621274a3a68/scipy-1.15.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:c90ebe8aaa4397eaefa8455a8182b164a6cc1d59ad53f79943f266d99f68687f", size = 30141634 },
1093
+ { url = "https://files.pythonhosted.org/packages/44/1a/6c21b45d2548eb73be9b9bff421aaaa7e85e22c1f9b3bc44b23485dfce0a/scipy-1.15.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:def751dd08243934c884a3221156d63e15234a3155cf25978b0a668409d45eb6", size = 22415179 },
1094
+ { url = "https://files.pythonhosted.org/packages/74/4b/aefac4bba80ef815b64f55da06f62f92be5d03b467f2ce3668071799429a/scipy-1.15.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:302093e7dfb120e55515936cb55618ee0b895f8bcaf18ff81eca086c17bd80af", size = 25126412 },
1095
+ { url = "https://files.pythonhosted.org/packages/b1/53/1cbb148e6e8f1660aacd9f0a9dfa2b05e9ff1cb54b4386fe868477972ac2/scipy-1.15.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd5b77413e1855351cdde594eca99c1f4a588c2d63711388b6a1f1c01f62274", size = 34952867 },
1096
+ { url = "https://files.pythonhosted.org/packages/2c/23/e0eb7f31a9c13cf2dca083828b97992dd22f8184c6ce4fec5deec0c81fcf/scipy-1.15.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d0194c37037707b2afa7a2f2a924cf7bac3dc292d51b6a925e5fcb89bc5c776", size = 36890009 },
1097
+ { url = "https://files.pythonhosted.org/packages/03/f3/e699e19cabe96bbac5189c04aaa970718f0105cff03d458dc5e2b6bd1e8c/scipy-1.15.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:bae43364d600fdc3ac327db99659dcb79e6e7ecd279a75fe1266669d9a652828", size = 36545159 },
1098
+ { url = "https://files.pythonhosted.org/packages/af/f5/ab3838e56fe5cc22383d6fcf2336e48c8fe33e944b9037fbf6cbdf5a11f8/scipy-1.15.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f031846580d9acccd0044efd1a90e6f4df3a6e12b4b6bd694a7bc03a89892b28", size = 39136566 },
1099
+ { url = "https://files.pythonhosted.org/packages/0a/c8/b3f566db71461cabd4b2d5b39bcc24a7e1c119535c8361f81426be39bb47/scipy-1.15.2-cp313-cp313t-win_amd64.whl", hash = "sha256:fe8a9eb875d430d81755472c5ba75e84acc980e4a8f6204d402849234d3017db", size = 40477705 },
1100
+ ]
1101
+
1102
  [[package]]
1103
  name = "shapely"
1104
  version = "2.0.7"