

import json
import os
from functools import lru_cache
from typing import List, Optional, Tuple

import regex as re

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...utils import logging


lowerCAmelCase							:  Optional[int]   	=						logging.get_logger(__name__)


lowerCAmelCase							:  Optional[int]   	=						{"""vocab_file""": """vocab.json""", """merges_file""": """merges.txt"""}

# See all BART models at https://huggingface.co/models?filter=bart
lowerCAmelCase							:  int   	=						{
    """vocab_file""": {
        """facebook/bart-base""": """https://huggingface.co/facebook/bart-base/resolve/main/vocab.json""",
        """facebook/bart-large""": """https://huggingface.co/facebook/bart-large/resolve/main/vocab.json""",
        """facebook/bart-large-mnli""": """https://huggingface.co/facebook/bart-large-mnli/resolve/main/vocab.json""",
        """facebook/bart-large-cnn""": """https://huggingface.co/facebook/bart-large-cnn/resolve/main/vocab.json""",
        """facebook/bart-large-xsum""": """https://huggingface.co/facebook/bart-large-xsum/resolve/main/vocab.json""",
        """yjernite/bart_eli5""": """https://huggingface.co/yjernite/bart_eli5/resolve/main/vocab.json""",
    },
    """merges_file""": {
        """facebook/bart-base""": """https://huggingface.co/facebook/bart-base/resolve/main/merges.txt""",
        """facebook/bart-large""": """https://huggingface.co/facebook/bart-large/resolve/main/merges.txt""",
        """facebook/bart-large-mnli""": """https://huggingface.co/facebook/bart-large-mnli/resolve/main/merges.txt""",
        """facebook/bart-large-cnn""": """https://huggingface.co/facebook/bart-large-cnn/resolve/main/merges.txt""",
        """facebook/bart-large-xsum""": """https://huggingface.co/facebook/bart-large-xsum/resolve/main/merges.txt""",
        """yjernite/bart_eli5""": """https://huggingface.co/yjernite/bart_eli5/resolve/main/merges.txt""",
    },
}

lowerCAmelCase							:  List[str]   	=						{
    """facebook/bart-base""": 1024,
    """facebook/bart-large""": 1024,
    """facebook/bart-large-mnli""": 1024,
    """facebook/bart-large-cnn""": 1024,
    """facebook/bart-large-xsum""": 1024,
    """yjernite/bart_eli5""": 1024,
}







@lru_cache()
def 			A_      (    ):
						SCREAMING_SNAKE_CASE_: List[Any]  		=       (
						    list(range(ord("!"    )				,	ord("~"    ) + 1    )    ) + list(range(ord("¡"    )				,	ord("¬"    ) + 1    )    ) + list(range(ord("®"    )				,	ord("ÿ"    ) + 1    )    )
						)
						SCREAMING_SNAKE_CASE_: Optional[Any]  		=       bs[:]
						SCREAMING_SNAKE_CASE_: int  		=       0
						for b in range(2**8    ):
												if b not in bs:
																		bs.append(_UpperCAmelCase    )
																		cs.append(2**8 + n    )
																		n += 1
						SCREAMING_SNAKE_CASE_: Any  		=       [chr(_UpperCAmelCase    ) for n in cs]
						return dict(zip(_UpperCAmelCase				,	_UpperCAmelCase    )    )







def 			A_      (    _UpperCAmelCase    ):
						SCREAMING_SNAKE_CASE_: Optional[int]  		=       set()
						SCREAMING_SNAKE_CASE_: int  		=       word[0]
						for char in word[1:]:
												pairs.add((prev_char, char)    )
												SCREAMING_SNAKE_CASE_: Tuple  		=       char
						return pairs



class   __lowercase				( UpperCAmelCase_	):




			"""simple docstring"""







			_UpperCAmelCase   :							Tuple										=     VOCAB_FILES_NAMES
			_UpperCAmelCase   :							Any										=     PRETRAINED_VOCAB_FILES_MAP
			_UpperCAmelCase   :							Union[str, Any]										=     PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
			_UpperCAmelCase   :							str										=     ['''input_ids''', '''attention_mask''']



			def __init__( self  :     Optional[int]   ,						lowerCAmelCase__  :     Optional[Any]   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     Optional[int]="replace"   ,						lowerCAmelCase__  :     List[Any]="<s>"   ,						lowerCAmelCase__  :     List[Any]="</s>"   ,						lowerCAmelCase__  :     str="</s>"   ,						lowerCAmelCase__  :     Dict="<s>"   ,						lowerCAmelCase__  :     int="<unk>"   ,						lowerCAmelCase__  :     Union[str, Any]="<pad>"   ,						lowerCAmelCase__  :     str="<mask>"   ,						lowerCAmelCase__  :     Optional[int]=False   ,						**lowerCAmelCase__  :     Optional[int]   ,						):
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       AddedToken(lowerCAmelCase__   ,						lstrip=lowerCAmelCase__   ,						rstrip=lowerCAmelCase__) if isinstance(lowerCAmelCase__   ,						lowerCAmelCase__) else bos_token
									SCREAMING_SNAKE_CASE_: str  		=       AddedToken(lowerCAmelCase__   ,						lstrip=lowerCAmelCase__   ,						rstrip=lowerCAmelCase__) if isinstance(lowerCAmelCase__   ,						lowerCAmelCase__) else eos_token
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       AddedToken(lowerCAmelCase__   ,						lstrip=lowerCAmelCase__   ,						rstrip=lowerCAmelCase__) if isinstance(lowerCAmelCase__   ,						lowerCAmelCase__) else sep_token
									SCREAMING_SNAKE_CASE_: Any  		=       AddedToken(lowerCAmelCase__   ,						lstrip=lowerCAmelCase__   ,						rstrip=lowerCAmelCase__) if isinstance(lowerCAmelCase__   ,						lowerCAmelCase__) else cls_token
									SCREAMING_SNAKE_CASE_: Any  		=       AddedToken(lowerCAmelCase__   ,						lstrip=lowerCAmelCase__   ,						rstrip=lowerCAmelCase__) if isinstance(lowerCAmelCase__   ,						lowerCAmelCase__) else unk_token
									SCREAMING_SNAKE_CASE_: str  		=       AddedToken(lowerCAmelCase__   ,						lstrip=lowerCAmelCase__   ,						rstrip=lowerCAmelCase__) if isinstance(lowerCAmelCase__   ,						lowerCAmelCase__) else pad_token

									# Mask token behave like a normal word, i.e. include the space before it
									SCREAMING_SNAKE_CASE_: Any  		=       AddedToken(lowerCAmelCase__   ,						lstrip=lowerCAmelCase__   ,						rstrip=lowerCAmelCase__) if isinstance(lowerCAmelCase__   ,						lowerCAmelCase__) else mask_token

									super().__init__(
									    errors=lowerCAmelCase__   ,						bos_token=lowerCAmelCase__   ,						eos_token=lowerCAmelCase__   ,						unk_token=lowerCAmelCase__   ,						sep_token=lowerCAmelCase__   ,						cls_token=lowerCAmelCase__   ,						pad_token=lowerCAmelCase__   ,						mask_token=lowerCAmelCase__   ,						add_prefix_space=lowerCAmelCase__   ,						**lowerCAmelCase__   ,						)

									with open(lowerCAmelCase__   ,						encoding="utf-8") as vocab_handle:
															SCREAMING_SNAKE_CASE_: str  		=       json.load(lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: Dict  		=       {v: k for k, v in self.encoder.items()}
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       errors  # how to handle errors in decoding
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       bytes_to_unicode()
									SCREAMING_SNAKE_CASE_: List[Any]  		=       {v: k for k, v in self.byte_encoder.items()}
									with open(lowerCAmelCase__   ,						encoding="utf-8") as merges_handle:
															SCREAMING_SNAKE_CASE_: Any  		=       merges_handle.read().split("\n")[1:-1]
									SCREAMING_SNAKE_CASE_: List[Any]  		=       [tuple(merge.split()) for merge in bpe_merges]
									SCREAMING_SNAKE_CASE_: List[str]  		=       dict(zip(lowerCAmelCase__   ,						range(len(lowerCAmelCase__))))
									SCREAMING_SNAKE_CASE_: str  		=       {}
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       add_prefix_space

									# Should have added re.IGNORECASE so BPE merges can happen for capitalized versions of contractions
									SCREAMING_SNAKE_CASE_: List[str]  		=       re.compile(R"'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+")



			@property
			def        _SCREAMING_SNAKE_CASE			( self  :     str):
									return len(self.encoder)



			def        _SCREAMING_SNAKE_CASE			( self  :     int):
									return dict(self.encoder   ,						**self.added_tokens_encoder)



			def        _SCREAMING_SNAKE_CASE			( self  :     Optional[Any]   ,						lowerCAmelCase__  :     Dict):
									if token in self.cache:
															return self.cache[token]
									SCREAMING_SNAKE_CASE_: str  		=       tuple(lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: str  		=       get_pairs(lowerCAmelCase__)

									if not pairs:
															return token

									while True:
															SCREAMING_SNAKE_CASE_: str  		=       min(lowerCAmelCase__   ,						key=lambda lowerCAmelCase__: self.bpe_ranks.get(lowerCAmelCase__   ,						float("inf")))
															if bigram not in self.bpe_ranks:
																					break
															SCREAMING_SNAKE_CASE_		,    SCREAMING_SNAKE_CASE_: Tuple  		=       bigram
															SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       []
															SCREAMING_SNAKE_CASE_: Any  		=       0
															while i < len(lowerCAmelCase__):
																					try:
																											SCREAMING_SNAKE_CASE_: Optional[Any]  		=       word.index(lowerCAmelCase__   ,						lowerCAmelCase__)
																					except ValueError:
																											new_word.extend(word[i:])
																											break
																					else:
																											new_word.extend(word[i:j])
																											SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       j

																					if word[i] == first and i < len(lowerCAmelCase__) - 1 and word[i + 1] == second:
																											new_word.append(first + second)
																											i += 2
																					else:
																											new_word.append(word[i])
																											i += 1
															SCREAMING_SNAKE_CASE_: Tuple  		=       tuple(lowerCAmelCase__)
															SCREAMING_SNAKE_CASE_: int  		=       new_word
															if len(lowerCAmelCase__) == 1:
																					break
															else:
																					SCREAMING_SNAKE_CASE_: int  		=       get_pairs(lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       " ".join(lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: Any  		=       word
									return word



			def        _SCREAMING_SNAKE_CASE			( self  :     Optional[Any]   ,						lowerCAmelCase__  :     List[Any]):
									SCREAMING_SNAKE_CASE_: List[Any]  		=       []
									for token in re.findall(self.pat   ,						lowerCAmelCase__):
															SCREAMING_SNAKE_CASE_: Optional[Any]  		=       "".join(
															    self.byte_encoder[b] for b in token.encode("utf-8"))  # Maps all our bytes to unicode strings, avoiding control tokens of the BPE (spaces in our case)
															bpe_tokens.extend(bpe_token for bpe_token in self.bpe(lowerCAmelCase__).split(" "))
									return bpe_tokens



			def        _SCREAMING_SNAKE_CASE			( self  :     Tuple   ,						lowerCAmelCase__  :     List[Any]):
									return self.encoder.get(lowerCAmelCase__   ,						self.encoder.get(self.unk_token))



			def        _SCREAMING_SNAKE_CASE			( self  :     Optional[Any]   ,						lowerCAmelCase__  :     Dict):
									return self.decoder.get(lowerCAmelCase__)



			def        _SCREAMING_SNAKE_CASE			( self  :     Any   ,						lowerCAmelCase__  :     int):
									SCREAMING_SNAKE_CASE_: Optional[Any]  		=       "".join(lowerCAmelCase__)
									SCREAMING_SNAKE_CASE_: Optional[int]  		=       bytearray([self.byte_decoder[c] for c in text]).decode("utf-8"   ,						errors=self.errors)
									return text



			def        _SCREAMING_SNAKE_CASE			( self  :     List[str]   ,						lowerCAmelCase__  :     str   ,						lowerCAmelCase__  :     Optional[str] = None):
									if not os.path.isdir(lowerCAmelCase__):
															logger.error(F"Vocabulary path ({save_directory}) should be a directory")
															return
									SCREAMING_SNAKE_CASE_: List[Any]  		=       os.path.join(
									    lowerCAmelCase__   ,						(filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"])
									SCREAMING_SNAKE_CASE_: Any  		=       os.path.join(
									    lowerCAmelCase__   ,						(filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["merges_file"])

									with open(lowerCAmelCase__   ,						"w"   ,						encoding="utf-8") as f:
															f.write(json.dumps(self.encoder   ,						indent=2   ,						sort_keys=lowerCAmelCase__   ,						ensure_ascii=lowerCAmelCase__) + "\n")

									SCREAMING_SNAKE_CASE_: Union[str, Any]  		=       0
									with open(lowerCAmelCase__   ,						"w"   ,						encoding="utf-8") as writer:
															writer.write("#version: 0.2\n")
															for bpe_tokens, token_index in sorted(self.bpe_ranks.items()   ,						key=lambda lowerCAmelCase__: kv[1]):
																					if index != token_index:
																											logger.warning(
																											    F"Saving vocabulary to {merge_file}: BPE merge indices are not consecutive."
																											    " Please check that the tokenizer is not corrupted!")
																											SCREAMING_SNAKE_CASE_: str  		=       token_index
																					writer.write(" ".join(lowerCAmelCase__) + "\n")
																					index += 1

									return vocab_file, merge_file



			def        _SCREAMING_SNAKE_CASE			( self  :     str   ,						lowerCAmelCase__  :     List[int]   ,						lowerCAmelCase__  :     Optional[List[int]] = None):
									if token_ids_a is None:
															return [self.cls_token_id] + token_ids_a + [self.sep_token_id]
									SCREAMING_SNAKE_CASE_: List[Any]  		=       [self.cls_token_id]
									SCREAMING_SNAKE_CASE_: Dict  		=       [self.sep_token_id]
									return cls + token_ids_a + sep + sep + token_ids_a + sep



			def        _SCREAMING_SNAKE_CASE			( self  :     str   ,						lowerCAmelCase__  :     List[int]   ,						lowerCAmelCase__  :     Optional[List[int]] = None   ,						lowerCAmelCase__  :     bool = False):
									if already_has_special_tokens:
															return super().get_special_tokens_mask(
															    token_ids_a=lowerCAmelCase__   ,						token_ids_a=lowerCAmelCase__   ,						already_has_special_tokens=lowerCAmelCase__)

									if token_ids_a is None:
															return [1] + ([0] * len(lowerCAmelCase__)) + [1]
									return [1] + ([0] * len(lowerCAmelCase__)) + [1, 1] + ([0] * len(lowerCAmelCase__)) + [1]



			def        _SCREAMING_SNAKE_CASE			( self  :     Tuple   ,						lowerCAmelCase__  :     List[int]   ,						lowerCAmelCase__  :     Optional[List[int]] = None):
									SCREAMING_SNAKE_CASE_: Any  		=       [self.sep_token_id]
									SCREAMING_SNAKE_CASE_: str  		=       [self.cls_token_id]

									if token_ids_a is None:
															return len(cls + token_ids_a + sep) * [0]
									return len(cls + token_ids_a + sep + sep + token_ids_a + sep) * [0]




			def        _SCREAMING_SNAKE_CASE			( self  :     Any   ,						lowerCAmelCase__  :     Dict   ,						lowerCAmelCase__  :     Union[str, Any]=False   ,						**lowerCAmelCase__  :     Optional[Any]):
									SCREAMING_SNAKE_CASE_: List[Any]  		=       kwargs.pop("add_prefix_space"   ,						self.add_prefix_space)
									if (is_split_into_words or add_prefix_space) and (len(lowerCAmelCase__) > 0 and not text[0].isspace()):
															SCREAMING_SNAKE_CASE_: Optional[int]  		=       " " + text
									return (text, kwargs)











'''simple docstring'''

from typing import Any

class 	__magic_name__						:







							def __init__(							self					:       List[Any]	,_UpperCAmelCase					:       Any		):
									_a     :      List[Any]        =							data
									_a     :      Union[str, Any]        =							None







							def __repr__(							self					:       Any		):
									return F"""Node({self.data})"""

class 	__magic_name__						:







							def __init__(							self					:       int		):
									_a     :      Tuple        =							None







							def __iter__(							self					:       str		):
									_a     :      int        =							self.head
									while node:
											yield node.data
											_a     :      Union[str, Any]        =							node.next







							def __len__(							self					:       Optional[Any]		):
									return sum(1 for _ in self		)







							def __repr__(							self					:       str		):
									return "->".join([str(_UpperCAmelCase		) for item in self]		)







							def __getitem__(							self					:       Tuple	,_UpperCAmelCase					:       int		):
									if not 0 <= index < len(self		):
											raise ValueError('list index out of range.'		)
									for i, node in enumerate(self		):
											if i == index:
													return node
									return None







							def __setitem__(							self					:       Union[str, Any]	,_UpperCAmelCase					:       int	,_UpperCAmelCase					:       Any		):
									if not 0 <= index < len(self		):
											raise ValueError('list index out of range.'		)
									_a     :      Any        =							self.head
									for _ in range(_UpperCAmelCase		):
											_a     :      Optional[Any]        =							current.next
									_a     :      Optional[int]        =							data







							def 							__lowercase			(							self					:       Optional[int]	,_UpperCAmelCase					:       Any		):
									self.insert_nth(len(self		)	,_UpperCAmelCase		)







							def 							__lowercase			(							self					:       Union[str, Any]	,_UpperCAmelCase					:       Any		):
									self.insert_nth(0	,_UpperCAmelCase		)







							def 							__lowercase			(							self					:       str	,_UpperCAmelCase					:       int	,_UpperCAmelCase					:       Any		):
									if not 0 <= index <= len(self		):
											raise IndexError('list index out of range'		)
									_a     :      int        =							Node(_UpperCAmelCase		)
									if self.head is None:
											_a     :      str        =							new_node
									elif index == 0:
											_a     :      List[str]        =							self.head  # link new_node to head
											_a     :      Union[str, Any]        =							new_node
									else:
											_a     :      int        =							self.head
											for _ in range(index - 1		):
													_a     :      Union[str, Any]        =							temp.next
											_a     :      List[str]        =							temp.next
											_a     :      Optional[int]        =							new_node







							def 							__lowercase			(							self					:       Optional[int]		):  # print every node data
									print(self		)







							def 							__lowercase			(							self					:       str		):
									return self.delete_nth(0		)







							def 							__lowercase			(							self					:       str		):  # delete from tail
									return self.delete_nth(len(self		) - 1		)







							def 							__lowercase			(							self					:       List[str]	,_UpperCAmelCase					:       int = 0		):
									if not 0 <= index <= len(self		) - 1:  # test if index is valid
											raise IndexError('List index out of range.'		)
									_a     :      Optional[Any]        =							self.head  # default first node
									if index == 0:
											_a     :      int        =							self.head.next
									else:
											_a     :      int        =							self.head
											for _ in range(index - 1		):
													_a     :      str        =							temp.next
											_a     :      str        =							temp.next
											_a     :      int        =							temp.next.next
									return delete_node.data







							def 							__lowercase			(							self					:       List[Any]		):
									return self.head is None







							def 							__lowercase			(							self					:       Tuple		):
									_a     :      List[Any]        =							None
									_a     :      Tuple        =							self.head

									while current:
											# Store the current node's next node.
											_a     :      Dict        =							current.next
											# Make the current node's next point backwards
											_a     :      str        =							prev
											# Make the previous node be the current node
											_a     :      Tuple        =							current
											# Make the current node the next node (to progress iteration)
											_a     :      Optional[Any]        =							next_node
									# Return prev in order to put the head at the end
									_a     :      int        =							prev



def      __lowerCamelCase     (      )			->      None:
		_a     :      List[str]        =							LinkedList()
		assert linked_list.is_empty() is True
		assert str(lowerCAmelCase_  ) == ""

		try:
				linked_list.delete_head()
				raise AssertionError  # This should not happen.
		except IndexError:
				assert True  # This should happen.

		try:
				linked_list.delete_tail()
				raise AssertionError  # This should not happen.
		except IndexError:
				assert True  # This should happen.

		for i in range(10  ):
				assert len(lowerCAmelCase_  ) == i
				linked_list.insert_nth(lowerCAmelCase_						,			i + 1  )
		assert str(lowerCAmelCase_  ) == "->".join(str(lowerCAmelCase_  ) for i in range(1						,			11  )  )

		linked_list.insert_head(0  )
		linked_list.insert_tail(11  )
		assert str(lowerCAmelCase_  ) == "->".join(str(lowerCAmelCase_  ) for i in range(0						,			12  )  )

		assert linked_list.delete_head() == 0
		assert linked_list.delete_nth(9  ) == 10
		assert linked_list.delete_tail() == 11
		assert len(lowerCAmelCase_  ) == 9
		assert str(lowerCAmelCase_  ) == "->".join(str(lowerCAmelCase_  ) for i in range(1						,			10  )  )

		assert all(linked_list[i] == i + 1 for i in range(0						,			9  )  ) is True

		for i in range(0						,			9  ):
				_a     :      Union[str, Any]        =							-i
		assert all(linked_list[i] == -i for i in range(0						,			9  )  ) is True

		linked_list.reverse()
		assert str(lowerCAmelCase_  ) == "->".join(str(lowerCAmelCase_  ) for i in range(-8						,			1  )  )



def      __lowerCamelCase     (      )			->      None:
		_a     :      Dict        =							[
		    -9,
		    100,
		    Node(77345112  ),
		    'dlrow olleH',
		    7,
		    5555,
		    0,
		    -192.55_555,
		    'Hello, world!',
		    77.9,
		    Node(10  ),
		    None,
		    None,
		    12.20,
		]
		_a     :      List[Any]        =							LinkedList()

		for i in test_input:
				linked_list.insert_tail(lowerCAmelCase_  )

		# Check if it's empty or not
		assert linked_list.is_empty() is False
		assert (
		    str(lowerCAmelCase_  ) == "-9->100->Node(77345112)->dlrow olleH->7->5555->0->"
		    "-192.55555->Hello, world!->77.9->Node(10)->None->None->12.2"
		)

		# Delete the head
		_a     :      List[str]        =							linked_list.delete_head()
		assert result == -9
		assert (
		    str(lowerCAmelCase_  ) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
		    "Hello, world!->77.9->Node(10)->None->None->12.2"
		)

		# Delete the tail
		_a     :      Dict        =							linked_list.delete_tail()
		assert result == 12.2
		assert (
		    str(lowerCAmelCase_  ) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
		    "Hello, world!->77.9->Node(10)->None->None"
		)

		# Delete a node in specific location in linked list
		_a     :      Optional[Any]        =							linked_list.delete_nth(10  )
		assert result is None
		assert (
		    str(lowerCAmelCase_  ) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
		    "Hello, world!->77.9->Node(10)->None"
		)

		# Add a Node instance to its head
		linked_list.insert_head(Node('Hello again, world!'  )  )
		assert (
		    str(lowerCAmelCase_  )
		    == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
		    "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None"
		)

		# Add None to its tail
		linked_list.insert_tail(lowerCAmelCase_  )
		assert (
		    str(lowerCAmelCase_  )
		    == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
		    "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None->None"
		)

		# Reverse the linked list
		linked_list.reverse()
		assert (
		    str(lowerCAmelCase_  )
		    == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->"
		    "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)"
		)



def      __lowerCamelCase     (      )			->      Union[str, Any]:
		from doctest import testmod

		testmod()

		_a     :      Optional[int]        =							LinkedList()
		linked_list.insert_head(input('Inserting 1st at head '  ).strip()  )
		linked_list.insert_head(input('Inserting 2nd at head '  ).strip()  )
		print('\nPrint list:'  )
		linked_list.print_list()
		linked_list.insert_tail(input('\nInserting 1st at tail '  ).strip()  )
		linked_list.insert_tail(input('Inserting 2nd at tail '  ).strip()  )
		print('\nPrint list:'  )
		linked_list.print_list()
		print('\nDelete head'  )
		linked_list.delete_head()
		print('Delete tail'  )
		linked_list.delete_tail()
		print('\nPrint list:'  )
		linked_list.print_list()
		print('\nReverse linked list'  )
		linked_list.reverse()
		print('\nPrint list:'  )
		linked_list.print_list()
		print('\nString representation of linked list:'  )
		print(lowerCAmelCase_  )
		print('\nReading/changing Node data using indexing:'  )
		print(f"""Element at Position 1: {linked_list[1]}"""  )
		_a     :      Optional[Any]        =							input('Enter New Value: '  ).strip()
		print('New list:'  )
		print(lowerCAmelCase_  )
		print(f"""length of linked_list is : {len(lowerCAmelCase_  )}"""  )


if __name__ == "__main__":
							main()




