code: def apply(self, graph):
      # Copy the graph. Don't change the original.
      graph = copy.deepcopy(graph)
  
      # Group nodes by the first matching group of the regex
      groups = {}
      for node in graph.nodes.values():
          m = self.id_regex.match(node.id)
          if not m:
              continue
  
          assert (
              m.groups()
          ), "Regular expression must have a matching group to avoid folding unrelated nodes."
          key = m.group(1)
          if key not in groups:
              groups[key] = []
          groups[key].append(node)
  
      # Fold each group of nodes together
      for key, nodes in groups.items():
          # Replace with a new node
          # TODO: Find last node in the sub-graph and get the output shape from it
          combo = Node(uid=key, name=self.name, op=self.op)
          graph.replace(nodes, combo)
      return graph
  
imports: import re
  import copy
  from .graph import Node
  from .None import ge
label_desc: Use image node_id 2 for calling the FoldId obj's underlying member method code with example usage: obj.apply(graph) and returns: graph