code: def getInfo(self, ctext: str) -> CrackInfo:
      if self.keysize is not None:
          analysis = self.cache.get_or_update(
              ctext,
              f"vigenere::{self.keysize}",
              lambda: cipheycore.analyse_string(
                  ctext.lower(), self.keysize, self.group
              ),
          )
  
          val = cipheycore.vigenere_detect(analysis, self.expected)
  
          logging.info(f"Vigenere has likelihood {val}")
  
          return CrackInfo(
              success_likelihood=val,
              # TODO: actually calculate runtimes
              success_runtime=1e-3,
              failure_runtime=1e-2,
          )
  
      likely_lens = self.cache.get_or_update(
          ctext,
          "vigenere::likely_lens",
          lambda: cipheycore.vigenere_likely_key_lens(
              ctext.lower(),
              self.expected,
              self.group,
              self.detect_p_value,
          ),
      )
  
      # Filter out the lens that make no sense
      likely_lens = [
          i for i in likely_lens if i.len <= self.max_key_length
      ]
  
      for keysize in likely_lens:
          # Store the analysis
          analysis = self.cache.get_or_update(
              ctext, f"vigenere::{keysize.len}", lambda: keysize.tab
          )
      if len(likely_lens) == 0:
          return CrackInfo(
              success_likelihood=0,
              # TODO: actually calculate runtimes
              success_runtime=2e-3,
              failure_runtime=2e-2,
          )
  
      logging.info(
          f"Vigenere has likelihood {likely_lens[0].p_value} with lens {[i.len for i in likely_lens]}"
      )
  
      return CrackInfo(
          success_likelihood=likely_lens[0].p_value,
          # TODO: actually calculate runtimes
          success_runtime=2e-4,
          failure_runtime=2e-4,
      )
  
file_path: Ciphey/ciphey/basemods/Crackers/vigenere.py
imports: from distutils import util
  from typing import Dict, List, Optional, Union
  import cipheycore
  import logging
  from rich.logging import RichHandler
  from ciphey.common import fix_case
  from ciphey.iface import Config, Cracker, CrackInfo, CrackResult, ParamSpec, registry
label_desc: Use image node_id 1 for calling the Vigenere obj's underlying member method code with example usage: obj.getInfo(ctext) and returns: CrackInfo, CrackInfo, CrackInfo