text: import json
  from unicodedata import normalize
  import string
  import os
  from config import CUSTOM_CONFUSABLE_PATH, CONFUSABLES_PATH, CONFUSABLE_MAPPING_PATH, MAX_SIMILARITY_DEPTH
  
  def _asciify(char):
      return normalize('NFD',char).encode('ascii', 'ignore').decode('ascii')
  
  def _get_accented_characters(char):
      return [u for u in (chr(i) for i in range(65536)) if u != char and _asciify(u) == char]
  
  def _get_confusable_chars(character, unicode_confusable_map, depth):
      mapped_chars = unicode_confusable_map[character]
  
      group = set([character])
      if depth <= MAX_SIMILARITY_DEPTH:
          for mapped_char in mapped_chars:
              group.update(_get_confusable_chars(mapped_char, unicode_confusable_map, depth + 1))
      return group
  
  def parse_new_mapping_file():
      unicode_confusable_map = {}
  
      with open(os.path.join(os.path.dirname(__file__), CONFUSABLES_PATH), "r") as unicode_mappings:
          with open(os.path.join(os.path.dirname(__file__), CUSTOM_CONFUSABLE_PATH), "r") as custom_mappings:
              mappings = unicode_mappings.readlines()
              mappings.extend(custom_mappings)
  
              for mapping_line in mappings:
                  if not mapping_line.strip() or mapping_line[0] == '#' or mapping_line[1] == '#':
                      continue
  
                  mapping = mapping_line.split(";")[:2]
                  str1 = chr(int(mapping[0].strip(), 16))
                  mapping[1] = mapping[1].strip().split(" ")
                  mapping[1] = [chr(int(x, 16)) for x in mapping[1]]
                  str2 = "".join(mapping[1])
  
                  if unicode_confusable_map.get(str1):
                      unicode_confusable_map[str1].add(str2)
                  else:
                      unicode_confusable_map[str1] = set([str2])
  
                  if unicode_confusable_map.get(str2):
                      unicode_confusable_map[str2].add(str1)
                  else:
                      unicode_confusable_map[str2] = set([str1])
  
                  if len(str1) == 1:
                      case_change = str1.lower() if str1.isupper() else str1.upper()
                      if case_change != str1:
                          unicode_confusable_map[str1].add(case_change)
                          if unicode_confusable_map.get(case_change) is not None:
                              unicode_confusable_map[case_change].add(str1)
                          else:
                              unicode_confusable_map[case_change] = set([str1])
  
                  if len(str2) == 1:
                      case_change = str2.lower() if str2.isupper() else str2.upper()
                      if case_change != str2:
                          unicode_confusable_map[str2].add(case_change)
                          if unicode_confusable_map.get(case_change) is not None:
                              unicode_confusable_map[case_change].add(str2)
                          else:
                              unicode_confusable_map[case_change] = set([str2])
  
      for char in string.ascii_lowercase:
          accented = _get_accented_characters(char)
          unicode_confusable_map[char].update(accented)
          for accent in accented:
              if unicode_confusable_map.get(accent):
                  unicode_confusable_map[accent].add(char)
              else:
                  unicode_confusable_map[accent] = set([char])
  
      for char in string.ascii_uppercase:
          accented = _get_accented_characters(char)
          unicode_confusable_map[char].update(accented)
          for accent in accented:
              if unicode_confusable_map.get(accent):
                  unicode_confusable_map[accent].add(char)
              else:
                  unicode_confusable_map[accent] = set([char])
  
      CONFUSABLE_MAP = {}
      characters_to_map = list(unicode_confusable_map.keys())
      for character in list(unicode_confusable_map.keys()):
          char_group = _get_confusable_chars(character, unicode_confusable_map, 0)
  
          CONFUSABLE_MAP[character] = list(char_group)
  
      mapping_file = open(os.path.join(os.path.dirname(__file__), CONFUSABLE_MAPPING_PATH), "w")
      mapping_file.write(json.dumps(CONFUSABLE_MAP))
      mapping_file.close()
  
  parse_new_mapping_file()