code: def closed_paths(entities, vertices):
      
      # get a networkx graph of entities
      graph, closed = vertex_graph(entities)
      # add entities that are closed as single- entity paths
      entity_paths = np.reshape(closed, (-1, 1)).tolist()
      # look for cycles in the graph, or closed loops
      vertex_paths = np.array(nx.cycles.cycle_basis(graph))
  
      # loop through every vertex cycle
      for vertex_path in vertex_paths:
          # a path has no length if it has fewer than 2 vertices
          if len(vertex_path) < 2:
              continue
          # convert vertex indices to entity indices
          entity_paths.append(
              vertex_to_entity_path(vertex_path,
                                    graph,
                                    entities,
                                    vertices))
      entity_paths = np.array(entity_paths)
      return entity_paths
docs: Paths are lists of entity indices.
      We first generate vertex paths using graph cycle algorithms,
      and then convert them to entity paths.
  
      This will also change the ordering of entity.points in place
      so a path may be traversed without having to reverse the entity.
  
      Parameters
      -------------
      entities : (n,) entity objects
          Entity objects
      vertices : (m, dimension) float
          Vertex points in space
  
      Returns
      -------------
      entity_paths : sequence of (n,) int
          Ordered traversals of entities