
import builtins
import sys

from ...utils.imports import _is_package_available
from . import cursor, input
from .helpers import Direction, clear_line, forceWrite, linebreak, move_cursor, reset_cursor, writeColor
from .keymap import KEYMAP


__lowerCAmelCase     :	Optional[int]       			=  False
try:
    __lowerCAmelCase     :	Tuple       			=  _is_package_available('google.colab')
except ModuleNotFoundError:
    pass




@input.register
class 			UpperCAmelCase_     :


  '''simple docstring'''







  def __init__(					self     :					Union[str, Any]     ,				UpperCamelCase__     :					str = None     ,				UpperCamelCase__     :					list = []       )     ->      Any:







    """simple docstring"""






    __magic_name__								=			0
    __magic_name__								=			choices
    __magic_name__								=			prompt
    if sys.platform == "win32":
      __magic_name__								=			"""*"""
    else:
      __magic_name__								=			"""➔ """
  def 				_lowercase				(					self     :					Union[str, Any]     ,				UpperCamelCase__     :					str     ,				UpperCamelCase__     :					str = ""       )     ->      Optional[int]:







    """simple docstring"""






    if sys.platform != "win32":
      writeColor(self.choices[index]     ,				32     ,				UpperCamelCase__       )
    else:
      forceWrite(self.choices[index]     ,				UpperCamelCase__       )
  def 				_lowercase				(					self     :					Optional[int]     ,				UpperCamelCase__     :					int       )     ->      List[str]:







    """simple docstring"""






    if index == self.position:
      forceWrite(F''' {self.arrow_char} '''       )
      self.write_choice(UpperCamelCase__       )
    else:
      forceWrite(F'''    {self.choices[index]}'''       )
    reset_cursor()
  def 				_lowercase				(					self     :					Tuple     ,				UpperCamelCase__     :					Direction     ,				UpperCamelCase__     :					int = 1       )     ->      Any:







    """simple docstring"""






    __magic_name__								=			self.position
    if direction == Direction.DOWN:
      if self.position + 1 >= len(self.choices       ):
        return
      self.position += num_spaces
    else:
      if self.position - 1 < 0:
        return
      self.position -= num_spaces
    clear_line()
    self.print_choice(UpperCamelCase__       )
    move_cursor(UpperCamelCase__     ,				direction.name       )
    self.print_choice(self.position       )
  @input.mark(KEYMAP["""up"""]       )
  def 				_lowercase				(					self     :					Tuple       )     ->      Optional[Any]:







    """simple docstring"""






    self.move_direction(Direction.UP       )
  @input.mark(KEYMAP["""down"""]       )
  def 				_lowercase				(					self     :					Optional[Any]       )     ->      int:







    """simple docstring"""






    self.move_direction(Direction.DOWN       )
  @input.mark(KEYMAP["""newline"""]       )
  def 				_lowercase				(					self     :					Optional[Any]       )     ->      Tuple:







    """simple docstring"""






    move_cursor(len(self.choices       ) - self.position     ,				"""DOWN"""       )
    return self.position
  @input.mark(KEYMAP["""interrupt"""]       )
  def 				_lowercase				(					self     :					Dict       )     ->      Union[str, Any]:







    """simple docstring"""






    move_cursor(len(self.choices       ) - self.position     ,				"""DOWN"""       )
    raise KeyboardInterrupt
  @input.mark_multiple(*[KEYMAP[str(UpperCamelCase__       )] for number in range(10       )]       )
  def 				_lowercase				(					self     :					List[Any]       )     ->      Tuple:







    """simple docstring"""






    __magic_name__								=			int(chr(self.current_selection       )       )
    __magic_name__								=			index - self.position
    if index == self.position:
      return
    if index < len(self.choices       ):
      if self.position > index:
        self.move_direction(Direction.UP     ,				-movement       )
      elif self.position < index:
        self.move_direction(Direction.DOWN     ,				UpperCamelCase__       )
      else:
        return
    else:
      return





  def 				_lowercase				(					self     :					Dict     ,				UpperCamelCase__     :					int = 0       )     ->      Optional[int]:







    """simple docstring"""






    if self.prompt:
      linebreak()
      forceWrite(self.prompt     ,				"""\n"""       )
      if in_colab:
        forceWrite("""Please input a choice index (starting from 0), and press enter"""     ,				"""\n"""       )
      else:
        forceWrite("""Please select a choice using the arrow or number keys, and selecting with enter"""     ,				"""\n"""       )
    __magic_name__								=			default_choice
    for i in range(len(self.choices       )       ):
      self.print_choice(UpperCamelCase__       )
      forceWrite("""\n"""       )
    move_cursor(len(self.choices       ) - self.position     ,				"""UP"""       )
    with cursor.hide():
      while True:
        if in_colab:
          try:
            __magic_name__								=			int(builtins.input()       )
          except ValueError:
            __magic_name__								=			default_choice
        else:
          __magic_name__								=			self.handle_input()
        if choice is not None:
          reset_cursor()
          for _ in range(len(self.choices       ) + 1       ):
            move_cursor(1     ,				"""UP"""       )
            clear_line()
          self.write_choice(UpperCamelCase__     ,				"""\n"""       )
          return choice



import html

from ...feature_extraction_utils import BatchFeature, FeatureExtractionMixin
from ...utils import is_bsa_available, logging, requires_backends


if is_bsa_available():
    import bsa
    from bsa import BeautifulSoup


__lowerCAmelCase     :	int       			=  logging.get_logger(__name__)




class 			UpperCAmelCase_     (					_A	):


  '''simple docstring'''







  def __init__(					self     :					Union[str, Any]     ,				**UpperCamelCase__     :					Union[str, Any]       )     ->      Union[str, Any]:







    """simple docstring"""






    requires_backends(self     ,				["""bs4"""]       )
    super().__init__(**UpperCamelCase__       )
  def 				_lowercase				(					self     :					Dict     ,				UpperCamelCase__     :					Union[str, Any]       )     ->      Optional[Any]:







    """simple docstring"""






    __magic_name__								=			[]
    __magic_name__								=			[]
    __magic_name__								=			element if element.name else element.parent
    for parent in child.parents:  # type: bs4.element.Tag
      __magic_name__								=			parent.find_all(child.name     ,				recursive=UpperCamelCase__       )
      xpath_tags.append(child.name       )
      xpath_subscripts.append(
          0 if 1 == len(UpperCamelCase__       ) else next(i for i, s in enumerate(UpperCamelCase__     ,				1       ) if s is child       )       )
      __magic_name__								=			parent
    xpath_tags.reverse()
    xpath_subscripts.reverse()
    return xpath_tags, xpath_subscripts
  def 				_lowercase				(					self     :					Union[str, Any]     ,				UpperCamelCase__     :					List[Any]       )     ->      str:







    """simple docstring"""






    __magic_name__								=			BeautifulSoup(UpperCamelCase__     ,				"""html.parser"""       )

    __magic_name__								=			[]
    __magic_name__								=			[]
    __magic_name__								=			[]

    for element in html_code.descendants:
      if type(UpperCamelCase__       ) == bsa.element.NavigableString:
        if type(element.parent       ) != bsa.element.Tag:
          continue

        __magic_name__								=			html.unescape(UpperCamelCase__       ).strip()
        if not text_in_this_tag:
          continue

        all_doc_strings.append(UpperCamelCase__       )

        __magic_name__	,       __magic_name__								=			self.xpath_soup(UpperCamelCase__       )
        stringaxtag_seq.append(UpperCamelCase__       )
        stringaxsubs_seq.append(UpperCamelCase__       )

    if len(UpperCamelCase__       ) != len(UpperCamelCase__       ):
      raise ValueError("""Number of doc strings and xtags does not correspond"""       )
    if len(UpperCamelCase__       ) != len(UpperCamelCase__       ):
      raise ValueError("""Number of doc strings and xsubs does not correspond"""       )

    return all_doc_strings, stringaxtag_seq, stringaxsubs_seq
  def 				_lowercase				(					self     :					List[Any]     ,				UpperCamelCase__     :					Dict     ,				UpperCamelCase__     :					List[Any]       )     ->      Optional[Any]:







    """simple docstring"""






    __magic_name__								=			""""""
    for tagname, subs in zip(UpperCamelCase__     ,				UpperCamelCase__       ):
      xpath += F'''/{tagname}'''
      if subs != 0:
        xpath += F'''[{subs}]'''
    return xpath





  def __call__(					self     :					str     ,				UpperCamelCase__     :					Tuple       )     ->      BatchFeature:







    """simple docstring"""






    __magic_name__								=			False

    # Check that strings has a valid type
    if isinstance(UpperCamelCase__     ,				UpperCamelCase__       ):
      __magic_name__								=			True
    elif isinstance(UpperCamelCase__     ,				(list, tuple)       ):
      if len(UpperCamelCase__       ) == 0 or isinstance(html_strings[0]     ,				UpperCamelCase__       ):
        __magic_name__								=			True

    if not valid_strings:
      raise ValueError(
          """HTML strings must of type `str`, `List[str]` (batch of examples), """
          F'''but is of type {type(UpperCamelCase__       )}.'''       )

    __magic_name__								=			bool(isinstance(UpperCamelCase__     ,				(list, tuple)       ) and (isinstance(html_strings[0]     ,				UpperCamelCase__       ))       )

    if not is_batched:
      __magic_name__								=			[html_strings]

    # Get nodes + xpaths
    __magic_name__								=			[]
    __magic_name__								=			[]
    for html_string in html_strings:
      __magic_name__	,       __magic_name__	,       __magic_name__								=			self.get_three_from_single(UpperCamelCase__       )
      nodes.append(UpperCamelCase__       )
      __magic_name__								=			[]
      for node, tag_list, sub_list in zip(UpperCamelCase__     ,				UpperCamelCase__     ,				UpperCamelCase__       ):
        __magic_name__								=			self.construct_xpath(UpperCamelCase__     ,				UpperCamelCase__       )
        xpath_strings.append(UpperCamelCase__       )
      xpaths.append(UpperCamelCase__       )

    # return as Dict
    __magic_name__								=			{"""nodes""": nodes, """xpaths""": xpaths}
    __magic_name__								=			BatchFeature(data=UpperCamelCase__     ,				tensor_type=UpperCamelCase__       )

    return encoded_inputs

