





"""simple docstring"""






from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import (
    center_crop,
    get_resize_output_image_size,
    normalize,
    rescale,
    resize,
    to_channel_dimension_format,
)
from ...image_utils import (
    IMAGENET_STANDARD_MEAN,
    IMAGENET_STANDARD_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, is_vision_available, logging


if is_vision_available():
		import PIL


A 			=  logging.get_logger(__name__)




class 				__lowercase			(			_UpperCamelCase							):







					'''simple docstring'''




					__lowerCAmelCase  =  ['''pixel_values''']







					def __init__(						self	,			_UpperCAmelCase = True	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = PILImageResampling.BILINEAR	,			_UpperCAmelCase = True	,			_UpperCAmelCase = 1 / 255	,			_UpperCAmelCase = True	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			**_UpperCAmelCase	,			):
									super().__init__(**_UpperCAmelCase     )
									__a :						str			       =  size if size is not None else {'''shortest_edge''': 384}
									__a :						str			       =  get_size_dict(_UpperCAmelCase	,			default_to_square=_UpperCAmelCase     )

									__a :						Optional[Any]			       =  do_resize
									__a :						Optional[int]			       =  size
									# Default value set here for backwards compatibility where the value in config is None
									__a :						str			       =  crop_pct if crop_pct is not None else 224 / 256
									__a :						Any			       =  resample
									__a :						int			       =  do_rescale
									__a :						int			       =  rescale_factor
									__a :						int			       =  do_normalize
									__a :						Dict			       =  image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN
									__a :						int			       =  image_std if image_std is not None else IMAGENET_STANDARD_STD







					def  _lowerCamelCase		(						self	,			_UpperCAmelCase	,			_UpperCAmelCase	,			_UpperCAmelCase	,			_UpperCAmelCase = PILImageResampling.BICUBIC	,			_UpperCAmelCase = None	,			**_UpperCAmelCase	,			):
									__a :						Optional[int]			       =  get_size_dict(_UpperCAmelCase	,			default_to_square=_UpperCAmelCase     )
									if "shortest_edge" not in size:
													raise ValueError(f"""Size dictionary must contain 'shortest_edge' key. Got {size.keys()}"""     )
									__a :						Any			       =  size['''shortest_edge''']

									if shortest_edge < 384:
													# maintain same ratio, resizing shortest edge to shortest_edge/crop_pct
													__a :						Optional[int]			       =  int(shortest_edge / crop_pct     )
													__a :						Optional[Any]			       =  get_resize_output_image_size(_UpperCAmelCase	,			size=_UpperCAmelCase	,			default_to_square=_UpperCAmelCase     )
													__a :						Optional[Any]			       =  resize(image=_UpperCAmelCase	,			size=_UpperCAmelCase	,			resample=_UpperCAmelCase	,			data_format=_UpperCAmelCase	,			**_UpperCAmelCase     )
													# then crop to (shortest_edge, shortest_edge)
													return center_crop(image=_UpperCAmelCase	,			size=(shortest_edge, shortest_edge)	,			data_format=_UpperCAmelCase	,			**_UpperCAmelCase     )
									else:
													# warping (no cropping) when evaluated at 384 or larger
													return resize(
													    _UpperCAmelCase	,			size=(shortest_edge, shortest_edge)	,			resample=_UpperCAmelCase	,			data_format=_UpperCAmelCase	,			**_UpperCAmelCase     )







					def  _lowerCamelCase		(						self	,			_UpperCAmelCase	,			_UpperCAmelCase	,			_UpperCAmelCase = None	,			**_UpperCAmelCase	,			):
									return rescale(_UpperCAmelCase	,			scale=_UpperCAmelCase	,			data_format=_UpperCAmelCase	,			**_UpperCAmelCase     )







					def  _lowerCamelCase		(						self	,			_UpperCAmelCase	,			_UpperCAmelCase	,			_UpperCAmelCase	,			_UpperCAmelCase = None	,			**_UpperCAmelCase	,			):
									return normalize(_UpperCAmelCase	,			mean=_UpperCAmelCase	,			std=_UpperCAmelCase	,			data_format=_UpperCAmelCase	,			**_UpperCAmelCase     )







					def  _lowerCamelCase		(						self	,			_UpperCAmelCase	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = None	,			_UpperCAmelCase = ChannelDimension.FIRST	,			**_UpperCAmelCase	,			):
									__a :						str			       =  do_resize if do_resize is not None else self.do_resize
									__a :						List[Any]			       =  crop_pct if crop_pct is not None else self.crop_pct
									__a :						Tuple			       =  resample if resample is not None else self.resample
									__a :						List[str]			       =  do_rescale if do_rescale is not None else self.do_rescale
									__a :						List[Any]			       =  rescale_factor if rescale_factor is not None else self.rescale_factor
									__a :						Dict			       =  do_normalize if do_normalize is not None else self.do_normalize
									__a :						Any			       =  image_mean if image_mean is not None else self.image_mean
									__a :						int			       =  image_std if image_std is not None else self.image_std

									__a :						List[str]			       =  size if size is not None else self.size
									__a :						Optional[int]			       =  get_size_dict(_UpperCAmelCase	,			default_to_square=_UpperCAmelCase     )

									__a :						Optional[int]			       =  make_list_of_images(_UpperCAmelCase     )

									if not valid_images(_UpperCAmelCase     ):
													raise ValueError(
													    '''Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, '''
													    '''torch.Tensor, tf.Tensor or jax.ndarray.'''     )

									if do_resize and size is None or resample is None:
													raise ValueError('''Size and resample must be specified if do_resize is True.'''     )

									if do_resize and size["shortest_edge"] < 384 and crop_pct is None:
													raise ValueError('''crop_pct must be specified if size < 384.'''     )

									if do_rescale and rescale_factor is None:
													raise ValueError('''Rescale factor must be specified if do_rescale is True.'''     )

									if do_normalize and (image_mean is None or image_std is None):
													raise ValueError('''Image mean and std must be specified if do_normalize is True.'''     )

									# All transformations expect numpy arrays.
									__a :						Tuple			       =  [to_numpy_array(_UpperCAmelCase     ) for image in images]

									if do_resize:
													__a :						Dict			       =  [self.resize(image=_UpperCAmelCase	,			size=_UpperCAmelCase	,			crop_pct=_UpperCAmelCase	,			resample=_UpperCAmelCase     ) for image in images]

									if do_rescale:
													__a :						str			       =  [self.rescale(image=_UpperCAmelCase	,			scale=_UpperCAmelCase     ) for image in images]

									if do_normalize:
													__a :						Dict			       =  [self.normalize(image=_UpperCAmelCase	,			mean=_UpperCAmelCase	,			std=_UpperCAmelCase     ) for image in images]

									__a :						str			       =  [to_channel_dimension_format(_UpperCAmelCase	,			_UpperCAmelCase     ) for image in images]

									__a :						Dict			       =  {'''pixel_values''': images}
									return BatchFeature(data=_UpperCAmelCase	,			tensor_type=_UpperCAmelCase     )






"""simple docstring"""






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


A 			=  logging.get_logger(__name__)




class 				__lowercase			(			_UpperCamelCase							):







					'''simple docstring'''




					def __init__(						self	,			**_UpperCAmelCase     ):
									requires_backends(self	,			['''bs4''']     )
									super().__init__(**_UpperCAmelCase     )







					def  _lowerCamelCase		(						self	,			_UpperCAmelCase     ):
									__a :						Tuple			       =  []
									__a :						Dict			       =  []
									__a :						int			       =  element if element.name else element.parent
									for parent in child.parents:  # type: bs4.element.Tag
													__a :						Dict			       =  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     )     )
													__a :						Any			       =  parent
									xpath_tags.reverse()
									xpath_subscripts.reverse()
									return xpath_tags, xpath_subscripts







					def  _lowerCamelCase		(						self	,			_UpperCAmelCase     ):
									__a :						Dict			       =  BeautifulSoup(_UpperCAmelCase	,			'''html.parser'''     )

									__a :						Any			       =  []
									__a :						Dict			       =  []
									__a :						Optional[int]			       =  []

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

																	__a :						Dict			       =  html.unescape(_UpperCAmelCase     ).strip()
																	if not text_in_this_tag:
																					continue

																	all_doc_strings.append(_UpperCAmelCase     )

																	__a       ,						__a :						List[Any]			       =  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  _lowerCamelCase		(						self	,			_UpperCAmelCase	,			_UpperCAmelCase     ):
									__a :						List[str]			       =  ''''''
									for tagname, subs in zip(_UpperCAmelCase	,			_UpperCAmelCase     ):
													xpath += f"""/{tagname}"""
													if subs != 0:
																	xpath += f"""[{subs}]"""
									return xpath







					def __call__(						self	,			_UpperCAmelCase     ):
									__a :						Optional[Any]			       =  False

									# Check that strings has a valid type
									if isinstance(_UpperCAmelCase	,			_UpperCAmelCase     ):
													__a :						str			       =  True
									elif isinstance(_UpperCAmelCase	,			(list, tuple)     ):
													if len(_UpperCAmelCase     ) == 0 or isinstance(html_strings[0]	,			_UpperCAmelCase     ):
																	__a :						Optional[Any]			       =  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     )}."""     )

									__a :						List[str]			       =  bool(isinstance(_UpperCAmelCase	,			(list, tuple)     ) and (isinstance(html_strings[0]	,			_UpperCAmelCase     ))     )

									if not is_batched:
													__a :						List[Any]			       =  [html_strings]

									# Get nodes + xpaths
									__a :						Tuple			       =  []
									__a :						int			       =  []
									for html_string in html_strings:
													__a       ,						__a       ,						__a :						Any			       =  self.get_three_from_single(_UpperCAmelCase     )
													nodes.append(_UpperCAmelCase     )
													__a :						List[Any]			       =  []
													for node, tag_list, sub_list in zip(_UpperCAmelCase	,			_UpperCAmelCase	,			_UpperCAmelCase     ):
																	__a :						Optional[int]			       =  self.construct_xpath(_UpperCAmelCase	,			_UpperCAmelCase     )
																	xpath_strings.append(_UpperCAmelCase     )
													xpaths.append(_UpperCAmelCase     )

									# return as Dict
									__a :						int			       =  {'''nodes''': nodes, '''xpaths''': xpaths}
									__a :						Any			       =  BatchFeature(data=_UpperCAmelCase	,			tensor_type=_UpperCAmelCase     )

									return encoded_inputs