topologicpy 0.7.96__py3-none-any.whl → 0.7.97__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.
topologicpy/Graph.py CHANGED
@@ -750,102 +750,6 @@ class Graph:
750
750
  _ = graph.AllPaths(vertexA, vertexB, True, timeLimit, paths) # Hook to Core
751
751
  return paths
752
752
 
753
- @staticmethod
754
- def IsIsomorphic(graphA, graphB, maxIterations=10, silent=False):
755
- """
756
- Tests if the two input graphs are isomorphic according to the Weisfeiler Lehman graph isomorphism test. See https://en.wikipedia.org/wiki/Weisfeiler_Leman_graph_isomorphism_test
757
-
758
- Parameters
759
- ----------
760
- graphA : topologic_core.Graph
761
- The first input graph.
762
- graphB : topologic_core.Graph
763
- The second input graph.
764
- maxIterations : int , optional
765
- This number limits the number of iterations to prevent the function from running indefinitely, particularly for very large or complex graphs.
766
- silent : bool , optional
767
- If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
768
-
769
- Returns
770
- -------
771
- bool
772
- True if the two input graphs are isomorphic. False otherwise
773
-
774
- """
775
-
776
- from topologicpy.Topology import Topology
777
-
778
- def weisfeiler_lehman_test(graph1, graph2, max_iterations=10):
779
- """
780
- Test if two graphs are isomorphic using the Weisfeiler-Leman (WL) algorithm with early stopping.
781
-
782
- Parameters:
783
- graph1 (dict): Adjacency list representation of the first graph.
784
- graph2 (dict): Adjacency list representation of the second graph.
785
- max_iterations (int): Maximum WL iterations allowed (default is 10).
786
-
787
- Returns:
788
- bool: True if the graphs are WL-isomorphic, False otherwise.
789
- """
790
-
791
- def wl_iteration(labels, graph):
792
- """Perform one WL iteration and return updated labels."""
793
- new_labels = {}
794
- for node in graph:
795
- neighborhood_labels = sorted([labels[neighbor] for neighbor in graph[node]])
796
- new_labels[node] = (labels[node], tuple(neighborhood_labels))
797
- unique_labels = {}
798
- count = 0
799
- for node in sorted(new_labels):
800
- if new_labels[node] not in unique_labels:
801
- unique_labels[new_labels[node]] = count
802
- count += 1
803
- new_labels[node] = unique_labels[new_labels[node]]
804
- return new_labels
805
-
806
- # Initialize labels
807
- labels1 = {node: 1 for node in graph1}
808
- labels2 = {node: 1 for node in graph2}
809
-
810
- for i in range(max_iterations):
811
- # Perform WL iteration for both graphs
812
- new_labels1 = wl_iteration(labels1, graph1)
813
- new_labels2 = wl_iteration(labels2, graph2)
814
-
815
- # Check if the label distributions match
816
- if sorted(new_labels1.values()) != sorted(new_labels2.values()):
817
- return False
818
-
819
- # Check for stability (early stopping)
820
- if new_labels1 == labels1 and new_labels2 == labels2:
821
- break
822
-
823
- # Update labels for next iteration
824
- labels1, labels2 = new_labels1, new_labels2
825
-
826
- return True
827
-
828
- if not Topology.IsInstance(graphA, "Graph") and not Topology.IsInstance(graphB, "Graph"):
829
- if not silent:
830
- print("Graph.IsIsomorphic - Error: The input graph parameters are not valid graphs. Returning None.")
831
- return None
832
- if not Topology.IsInstance(graphA, "Graph"):
833
- if not silent:
834
- print("Graph.IsIsomorphic - Error: The input graphA parameter is not a valid graph. Returning None.")
835
- return None
836
- if not Topology.IsInstance(graphB, "Graph"):
837
- if not silent:
838
- print("Graph.IsIsomorphic - Error: The input graphB parameter is not a valid graph. Returning None.")
839
- return None
840
- if maxIterations <= 0:
841
- if not silent:
842
- print("Graph.IsIsomorphic - Error: The input maxIterations parameter is not within a valid range. Returning None.")
843
- return None
844
-
845
- g1 = Graph.AdjacencyDictionary(graphA)
846
- g2 = Graph.AdjacencyDictionary(graphB)
847
- return weisfeiler_lehman_test(g1, g2, max_iterations=maxIterations)
848
-
849
753
  @staticmethod
850
754
  def AverageClusteringCoefficient(graph, mantissa: int = 6, silent: bool = False):
851
755
  """
@@ -1345,7 +1249,7 @@ class Graph:
1345
1249
  graph : topologic_core.Graph
1346
1250
  The input graph.
1347
1251
  key : str , optional
1348
- The dictionary key under which to save the betweeness centrality score. The default is "betweenness_centrality".
1252
+ The dictionary key under which to store the betweeness centrality score. The default is "betweenness_centrality".
1349
1253
  mantissa : int , optional
1350
1254
  The desired length of the mantissa. The default is 6.
1351
1255
  tolerance : float , optional
@@ -1427,7 +1331,75 @@ class Graph:
1427
1331
  return_betweenness[int(i)] = v
1428
1332
 
1429
1333
  return return_betweenness
1430
-
1334
+
1335
+ @staticmethod
1336
+ def Bridges(graph, key: str = "bridge", silent: bool = False):
1337
+ """
1338
+ Returns the list of bridge edges in the input graph. See: https://en.wikipedia.org/wiki/Bridge_(graph_theory)
1339
+
1340
+ Parameters
1341
+ ----------
1342
+ graph : topologic_core.Graph
1343
+ The input graph.
1344
+ key : str , optional
1345
+ The edge dictionary key under which to store the bridge status. 0 means the edge is NOT a bridge. 1 means that the edge IS a bridge. The default is "bridge".
1346
+ silent : bool , optional
1347
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
1348
+
1349
+ Returns
1350
+ -------
1351
+ list
1352
+ The list of bridge edges in the input graph.
1353
+
1354
+ """
1355
+ import os
1356
+ import warnings
1357
+ from topologicpy.Topology import Topology
1358
+ from topologicpy.Dictionary import Dictionary
1359
+
1360
+ try:
1361
+ import igraph as ig
1362
+ except:
1363
+ print("Graph.Bridges - Installing required pyhon-igraph library.")
1364
+ try:
1365
+ os.system("pip install python-igraph")
1366
+ except:
1367
+ os.system("pip install python-igraph --user")
1368
+ try:
1369
+ import igraph as ig
1370
+ print("Graph.Bridges - python-igraph library installed correctly.")
1371
+ except:
1372
+ warnings.warn("Graph.Bridges - Error: Could not import python-igraph. Please install manually.")
1373
+
1374
+ if not Topology.IsInstance(graph, "graph"):
1375
+ if not silent:
1376
+ print("Graph.Bridges - Error: The input graph parameter is not a valid topologic graph. Returning None")
1377
+ return None
1378
+
1379
+ edges = Graph.Edges(graph)
1380
+ if len(edges) < 1:
1381
+ return []
1382
+ if len(edges) == 1:
1383
+ d = Topology.Dictionary(edge)
1384
+ d = Dictionary.SetValueAtKey(d, key, 1)
1385
+ edge = Topology.SetDictionary(edge, d)
1386
+ return [edge]
1387
+ mesh_data = Graph.MeshData(graph)
1388
+ graph_edges = mesh_data['edges']
1389
+ ig_graph = ig.Graph(edges=graph_edges)
1390
+
1391
+ bridges = ig_graph.bridges()
1392
+ bridge_edges = []
1393
+ for i, edge in enumerate(edges):
1394
+ d = Topology.Dictionary(edge)
1395
+ if i in bridges:
1396
+ d = Dictionary.SetValueAtKey(d, key, 1)
1397
+ bridge_edges.append(edge)
1398
+ else:
1399
+ d = Dictionary.SetValueAtKey(d, key, 0)
1400
+ edge = Topology.SetDictionary(edge, d)
1401
+ return bridge_edges
1402
+
1431
1403
  @staticmethod
1432
1404
  def ByAdjacencyMatrixCSVPath(path: str, dictionaries: list = None, silent: bool = False):
1433
1405
  """
@@ -4410,7 +4382,7 @@ class Graph:
4410
4382
  vertices : list , optional
4411
4383
  The input list of vertices. The default is None.
4412
4384
  key : str , optional
4413
- The dictionary key under which to save the closeness centrality score. The default is "closeness_centrality".
4385
+ The dictionary key under which to store the closeness centrality score. The default is "closeness_centrality".
4414
4386
  mantissa : int , optional
4415
4387
  The desired length of the mantissa. The default is 6.
4416
4388
  tolerance : float , optional
@@ -4498,7 +4470,7 @@ class Graph:
4498
4470
  graph : topologicp.Graph
4499
4471
  The input topologic graph.
4500
4472
  key : str , optional
4501
- The dictionary key under which to save the closeness centrality score. The default is "community".
4473
+ The dictionary key under which to store the closeness centrality score. The default is "community".
4502
4474
  mantissa : int , optional
4503
4475
  The desired length of the mantissa. The default is 6.
4504
4476
  tolerance : float , optional
@@ -4610,7 +4582,7 @@ class Graph:
4610
4582
  vertices : list , optional
4611
4583
  The input list of vertices. The default is None.
4612
4584
  key : str , optional
4613
- The dictionary key under which to save the connectivity score. The default is "connectivity".
4585
+ The dictionary key under which to store the connectivity score. The default is "connectivity".
4614
4586
  edgeKey : str , optional
4615
4587
  If specified, the value in the connected edges' dictionary specified by the edgeKey string will be aggregated to calculate
4616
4588
  the vertex degree. If a numeric value cannot be retrieved from an edge, a value of 1 is used instead. This is used in weighted graphs.
@@ -4705,6 +4677,67 @@ class Graph:
4705
4677
  return None
4706
4678
  return graph.ContainsVertex(vertex, tolerance) # Hook to Core
4707
4679
 
4680
+ @staticmethod
4681
+ def CutVertices(graph, key: str = "cut", silent: bool = False):
4682
+ """
4683
+ Returns the list of cut vertices in the input graph. See: https://en.wikipedia.org/wiki/Bridge_(graph_theory)
4684
+
4685
+ Parameters
4686
+ ----------
4687
+ graph : topologic_core.Graph
4688
+ The input graph.
4689
+ key : str , optional
4690
+ The vertex dictionary key under which to store the cut status. 0 means the vertex is NOT a cut vertex. 1 means that the vertex IS a cut vertex. The default is "cut".
4691
+ silent : bool , optional
4692
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
4693
+
4694
+ Returns
4695
+ -------
4696
+ list
4697
+ The list of bridge edges in the input graph.
4698
+
4699
+ """
4700
+ import os
4701
+ import warnings
4702
+ from topologicpy.Topology import Topology
4703
+ from topologicpy.Dictionary import Dictionary
4704
+
4705
+ try:
4706
+ import igraph as ig
4707
+ except:
4708
+ print("Graph.CutVertices - Installing required pyhon-igraph library.")
4709
+ try:
4710
+ os.system("pip install python-igraph")
4711
+ except:
4712
+ os.system("pip install python-igraph --user")
4713
+ try:
4714
+ import igraph as ig
4715
+ print("Graph.CutVertices - python-igraph library installed correctly.")
4716
+ except:
4717
+ warnings.warn("Graph.CutVertices - Error: Could not import python-igraph. Please install manually.")
4718
+
4719
+ if not Topology.IsInstance(graph, "graph"):
4720
+ if not silent:
4721
+ print("Graph.CutVertices - Error: The input graph parameter is not a valid topologic graph. Returning None")
4722
+ return None
4723
+
4724
+ vertices = Graph.Vertices(graph)
4725
+ mesh_data = Graph.MeshData(graph)
4726
+ graph_edges = mesh_data['edges']
4727
+ ig_graph = ig.Graph(edges=graph_edges)
4728
+ articulation_points = ig_graph.vs[ig_graph.articulation_points()]
4729
+ articulation_points_list = [v.index for v in articulation_points]
4730
+ cut_vertices = []
4731
+ for i, vertex in enumerate(vertices):
4732
+ d = Topology.Dictionary(vertex)
4733
+ if i in articulation_points_list:
4734
+ d = Dictionary.SetValueAtKey(d, key, 1)
4735
+ cut_vertices.append(vertex)
4736
+ else:
4737
+ d = Dictionary.SetValueAtKey(d, key, 0)
4738
+ vertex = Topology.SetDictionary(vertex, d)
4739
+
4740
+ return cut_vertices
4708
4741
 
4709
4742
  @staticmethod
4710
4743
  def Degree(graph, vertices=None, key: str = "degree", edgeKey: str = None, mantissa: int = 6, tolerance = 0.0001):
@@ -4718,7 +4751,7 @@ class Graph:
4718
4751
  vertices : list , optional
4719
4752
  The input list of vertices. The default is None.
4720
4753
  key : str , optional
4721
- The dictionary key under which to save the closeness centrality score. The default is "degree".
4754
+ The dictionary key under which to store the closeness centrality score. The default is "degree".
4722
4755
  edgeKey : str , optional
4723
4756
  If specified, the value in the connected edges' dictionary specified by the edgeKey string will be aggregated to calculate
4724
4757
  the vertex degree. If a numeric value cannot be retrieved from an edge, a value of 1 is used instead. This is used in weighted graphs.
@@ -4874,7 +4907,7 @@ class Graph:
4874
4907
  vertices : list , optional
4875
4908
  The input list of vertices. The default is None.
4876
4909
  key : str , optional
4877
- The dictionary key under which to save the depth score. The default is "depth".
4910
+ The dictionary key under which to store the depth score. The default is "depth".
4878
4911
  type : str , optional
4879
4912
  The type of depth distance to calculate. The options are "topological" or "metric". The default is "topological". See https://www.spacesyntax.online/overview-2/analysis-of-spatial-relations/.
4880
4913
  mantissa : int , optional
@@ -6127,7 +6160,103 @@ class Graph:
6127
6160
  f.close()
6128
6161
  return False
6129
6162
  return False
6130
-
6163
+
6164
+ @staticmethod
6165
+ def IsIsomorphic(graphA, graphB, maxIterations=10, silent=False):
6166
+ """
6167
+ Tests if the two input graphs are isomorphic according to the Weisfeiler Lehman graph isomorphism test. See https://en.wikipedia.org/wiki/Weisfeiler_Leman_graph_isomorphism_test
6168
+
6169
+ Parameters
6170
+ ----------
6171
+ graphA : topologic_core.Graph
6172
+ The first input graph.
6173
+ graphB : topologic_core.Graph
6174
+ The second input graph.
6175
+ maxIterations : int , optional
6176
+ This number limits the number of iterations to prevent the function from running indefinitely, particularly for very large or complex graphs.
6177
+ silent : bool , optional
6178
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
6179
+
6180
+ Returns
6181
+ -------
6182
+ bool
6183
+ True if the two input graphs are isomorphic. False otherwise
6184
+
6185
+ """
6186
+
6187
+ from topologicpy.Topology import Topology
6188
+
6189
+ def weisfeiler_lehman_test(graph1, graph2, max_iterations=10):
6190
+ """
6191
+ Test if two graphs are isomorphic using the Weisfeiler-Leman (WL) algorithm with early stopping.
6192
+
6193
+ Parameters:
6194
+ graph1 (dict): Adjacency list representation of the first graph.
6195
+ graph2 (dict): Adjacency list representation of the second graph.
6196
+ max_iterations (int): Maximum WL iterations allowed (default is 10).
6197
+
6198
+ Returns:
6199
+ bool: True if the graphs are WL-isomorphic, False otherwise.
6200
+ """
6201
+
6202
+ def wl_iteration(labels, graph):
6203
+ """Perform one WL iteration and return updated labels."""
6204
+ new_labels = {}
6205
+ for node in graph:
6206
+ neighborhood_labels = sorted([labels[neighbor] for neighbor in graph[node]])
6207
+ new_labels[node] = (labels[node], tuple(neighborhood_labels))
6208
+ unique_labels = {}
6209
+ count = 0
6210
+ for node in sorted(new_labels):
6211
+ if new_labels[node] not in unique_labels:
6212
+ unique_labels[new_labels[node]] = count
6213
+ count += 1
6214
+ new_labels[node] = unique_labels[new_labels[node]]
6215
+ return new_labels
6216
+
6217
+ # Initialize labels
6218
+ labels1 = {node: 1 for node in graph1}
6219
+ labels2 = {node: 1 for node in graph2}
6220
+
6221
+ for i in range(max_iterations):
6222
+ # Perform WL iteration for both graphs
6223
+ new_labels1 = wl_iteration(labels1, graph1)
6224
+ new_labels2 = wl_iteration(labels2, graph2)
6225
+
6226
+ # Check if the label distributions match
6227
+ if sorted(new_labels1.values()) != sorted(new_labels2.values()):
6228
+ return False
6229
+
6230
+ # Check for stability (early stopping)
6231
+ if new_labels1 == labels1 and new_labels2 == labels2:
6232
+ break
6233
+
6234
+ # Update labels for next iteration
6235
+ labels1, labels2 = new_labels1, new_labels2
6236
+
6237
+ return True
6238
+
6239
+ if not Topology.IsInstance(graphA, "Graph") and not Topology.IsInstance(graphB, "Graph"):
6240
+ if not silent:
6241
+ print("Graph.IsIsomorphic - Error: The input graph parameters are not valid graphs. Returning None.")
6242
+ return None
6243
+ if not Topology.IsInstance(graphA, "Graph"):
6244
+ if not silent:
6245
+ print("Graph.IsIsomorphic - Error: The input graphA parameter is not a valid graph. Returning None.")
6246
+ return None
6247
+ if not Topology.IsInstance(graphB, "Graph"):
6248
+ if not silent:
6249
+ print("Graph.IsIsomorphic - Error: The input graphB parameter is not a valid graph. Returning None.")
6250
+ return None
6251
+ if maxIterations <= 0:
6252
+ if not silent:
6253
+ print("Graph.IsIsomorphic - Error: The input maxIterations parameter is not within a valid range. Returning None.")
6254
+ return None
6255
+
6256
+ g1 = Graph.AdjacencyDictionary(graphA)
6257
+ g2 = Graph.AdjacencyDictionary(graphB)
6258
+ return weisfeiler_lehman_test(g1, g2, max_iterations=maxIterations)
6259
+
6131
6260
  @staticmethod
6132
6261
  def Reshape(graph,
6133
6262
  shape="spring 2D",
@@ -7767,7 +7896,7 @@ class Graph:
7767
7896
  vertices : list , optional
7768
7897
  The input list of vertices. If set to None, the local clustering coefficient of all vertices will be computed. The default is None.
7769
7898
  key : str , optional
7770
- The dictionary key under which to save the local clustering coefficient score. The default is "lcc".
7899
+ The dictionary key under which to store the local clustering coefficient score. The default is "lcc".
7771
7900
  mantissa : int , optional
7772
7901
  The desired length of the mantissa. The default is 6.
7773
7902
  tolerance : float , optional
@@ -8424,11 +8553,11 @@ class Graph:
8424
8553
  graph : topologic_core.Graph
8425
8554
  The input graph.
8426
8555
  xKey : str , optional
8427
- The dictionary key under which to save the X-Coordinate of the vertex. The default is 'x'.
8556
+ The dictionary key under which to store the X-Coordinate of the vertex. The default is 'x'.
8428
8557
  yKey : str , optional
8429
- The dictionary key under which to save the Y-Coordinate of the vertex. The default is 'y'.
8558
+ The dictionary key under which to store the Y-Coordinate of the vertex. The default is 'y'.
8430
8559
  zKey : str , optional
8431
- The dictionary key under which to save the Z-Coordinate of the vertex. The default is 'z'.
8560
+ The dictionary key under which to store the Z-Coordinate of the vertex. The default is 'z'.
8432
8561
  mantissa : int , optional
8433
8562
  The desired length of the mantissa. The default is 6.
8434
8563
  tolerance : float , optional
@@ -8627,7 +8756,7 @@ class Graph:
8627
8756
  directed : bool , optional
8628
8757
  If set to True, the graph is considered as a directed graph. Otherwise, it will be considered as an undirected graph. The default is False.
8629
8758
  key : str , optional
8630
- The dictionary key under which to save the page_rank score. The default is "page_rank"
8759
+ The dictionary key under which to store the page_rank score. The default is "page_rank"
8631
8760
  mantissa : int , optional
8632
8761
  The desired length of the mantissa.
8633
8762
  tolerance : float , optional
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.96'
1
+ __version__ = '0.7.97'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.96
3
+ Version: 0.7.97
4
4
  Summary: An AI-Powered Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: AGPL v3 License
@@ -11,7 +11,7 @@ topologicpy/Dictionary.py,sha256=t0O7Du-iPq46FyKqZfcjHfsUK1E8GS_e67R2V5cpkbw,331
11
11
  topologicpy/Edge.py,sha256=gaLqyjFOqFHpw69Ftr4rc-kvakYpauQwhOK4ZO-V35g,67287
12
12
  topologicpy/EnergyModel.py,sha256=UoQ9Jm-hYsN383CbcLKw-y6BKitRHj0uyh84yQ-8ACg,53856
13
13
  topologicpy/Face.py,sha256=wczXpMcfub8Eb10lA4rrXksvi5YYCbRjBdp3lOTUwK0,172618
14
- topologicpy/Graph.py,sha256=Zx4dzSTynaJP1dEZ1j5WuneaTv2N2fbeNTyMwaI947c,455395
14
+ topologicpy/Graph.py,sha256=tAm-kvvHAgadPJIcXvqgEoMuAdAo3RS3mu9uhhgx7TI,460497
15
15
  topologicpy/Grid.py,sha256=2s9cSlWldivn1i9EUz4OOokJyANveqmRe_vR93CAndI,18245
16
16
  topologicpy/Helper.py,sha256=F3h4_qcOD_PHAoVe0tEbEE7_jYyVcaHjtwVs4QHOZuI,23978
17
17
  topologicpy/Honeybee.py,sha256=Y_El6M8x3ixvvIe_VcRiwj_4C89ZZg5_WlT7adbCkpw,21849
@@ -28,9 +28,9 @@ topologicpy/Vector.py,sha256=Cl7besf20cAGmyNPh-9gbFAHnRU5ZWSMChJ3VyFIDs4,35416
28
28
  topologicpy/Vertex.py,sha256=QkeNPFTX-adKhEHMole0et9FCy0xXmTHVcmsYqqotSw,73904
29
29
  topologicpy/Wire.py,sha256=bX8wO96gFa7HZPY0CFlmYQBOUP_1e0jCb02BPxaY-ao,222981
30
30
  topologicpy/__init__.py,sha256=vlPCanUbxe5NifC4pHcnhSzkmmYcs_UrZrTlVMsxcFs,928
31
- topologicpy/version.py,sha256=a9u4mrbOh52xm2kgTG2gE8Y-NjoOtc82edCsxZY1Zs0,23
32
- topologicpy-0.7.96.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
- topologicpy-0.7.96.dist-info/METADATA,sha256=nVJinnZ504srDkDfjHbmyKZWpWEy6TchQp9nfijkKUY,10513
34
- topologicpy-0.7.96.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
- topologicpy-0.7.96.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
- topologicpy-0.7.96.dist-info/RECORD,,
31
+ topologicpy/version.py,sha256=eF2oD9YC4qAbKpy4BgX03mi3PRuOcHb_V4K8lN5jAn0,23
32
+ topologicpy-0.7.97.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
+ topologicpy-0.7.97.dist-info/METADATA,sha256=pingqvbKxBUf-eX6CrZQCoIyEV1tduXqvZwpol4DDuQ,10513
34
+ topologicpy-0.7.97.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
+ topologicpy-0.7.97.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.7.97.dist-info/RECORD,,