code: def search(self, ctext: Any) -> Optional[SearchResult]:
      logging.debug(
          f"""Beginning AuSearch with {"inverted" if self.invert_priority else "normal"} priority"""
      )
  
      try:
          root = Node.root(self._config(), ctext)
      except DuplicateNode:
          return None
  
      check_res = self._config().objs["checker"](ctext)
      if check_res is not None:
          return SearchResult(check_res=check_res, path=[root.level])
  
      try:
          self.recursive_expand(root, False)
  
          while True:
              if self.work.empty():
                  break
              # Get the highest level result
              chunk = self.work.get_work_chunk()
              chunk.sort(key=lambda i: i.score)
              # Work through all of this level's results
              while len(chunk) != 0:
                  logging.debug(f"{len(chunk)} remaining on this level")
                  # TODO Cyclic uses some tricky C++ here
                  # I know because it's sorted the one at the back (the anti-weight)
                  # is the most likely
  
                  edge: Edge = chunk.pop(-1)
  
                  # Expand the node
                  res = edge.route(edge.source.level.result.value)
                  if res is None:
                      continue
                  for i in res:
                      try:
                          node = Node.cracker(
                              config=self._config(),
                              edge_template=edge,
                              result=i,
                          )
                          self.recursive_expand(node)
                      except DuplicateNode:
                          continue
  
      except AuSearchSuccessful as e:
          logging.info("AuSearch succeeded")
          return SearchResult(
              path=e.target.get_path(), check_res=e.info
          )
  
      logging.info("AuSearch failed")
  
imports: import bisect
  import distutils
  import math
  from copy import copy
  from dataclasses import dataclass
  from functools import lru_cache
  from typing import Any, Dict, Generic, List, Optional, TypeVar, Union
  import logging
  from rich.logging import RichHandler
  from ciphey.iface import Checker, Config, Cracker, CrackInfo, CrackResult, Decoder, ParamSpec, Searcher, SearchLevel, SearchResult, T, registry
label_desc: Use image node_id 6 for calling the AuSearch obj's underlying member method code with example usage: obj.search(ctext) and returns: SearchResult, None, SearchResult