






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


snake_case__   :						Optional[Any]													=   logging.get_logger(__name__)


snake_case__   :						List[str]													=   {"""vocab_file""": """vocab.json""", """merges_file""": """merges.txt"""}

# See all BART models at https://huggingface.co/models?filter=bart
snake_case__   :						str													=   {
    """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""",
    },
}

snake_case__   :						List[Any]													=   {
    """facebook/bart-base""": 1_0_2_4,
    """facebook/bart-large""": 1_0_2_4,
    """facebook/bart-large-mnli""": 1_0_2_4,
    """facebook/bart-large-cnn""": 1_0_2_4,
    """facebook/bart-large-xsum""": 1_0_2_4,
    """yjernite/bart_eli5""": 1_0_2_4,
}






@lru_cache()
def      _snake_case     ():
   UpperCamelCase_						=  (
       list(range(ord('!')     ,   ord('~') + 1)) + list(range(ord('¡')     ,   ord('¬') + 1)) + list(range(ord('®')     ,   ord('ÿ') + 1))
   )
   UpperCamelCase_						=  bs[:]
   UpperCamelCase_						=  0
   for b in range(2**8):
      if b not in bs:
         bs.append(__lowercase)
         cs.append(2**8 + n)
         n += 1
   UpperCamelCase_						=  [chr(__lowercase) for n in cs]
   return dict(zip(__lowercase     ,   __lowercase))






def      _snake_case     (__lowercase):
   UpperCamelCase_						=  set()
   UpperCamelCase_						=  word[0]
   for char in word[1:]:
      pairs.add((prev_char, char))
      UpperCamelCase_						=  char
   return pairs


class     _a							(	UpperCAmelCase__     ):






  """simple docstring"""





  A_						       = VOCAB_FILES_NAMES
  A_						       = PRETRAINED_VOCAB_FILES_MAP
  A_						       = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
  A_						       = ["""input_ids""", """attention_mask"""]




  def __init__(  self		,		_UpperCAmelCase		,		_UpperCAmelCase		,		_UpperCAmelCase="replace"		,		_UpperCAmelCase="<s>"		,		_UpperCAmelCase="</s>"		,		_UpperCAmelCase="</s>"		,		_UpperCAmelCase="<s>"		,		_UpperCAmelCase="<unk>"		,		_UpperCAmelCase="<pad>"		,		_UpperCAmelCase="<mask>"		,		_UpperCAmelCase=False		,		**_UpperCAmelCase		,		)      ->			Optional[int]:
     UpperCamelCase_						=  AddedToken(_UpperCAmelCase		,		lstrip=_UpperCAmelCase		,		rstrip=_UpperCAmelCase			) if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			) else bos_token
     UpperCamelCase_						=  AddedToken(_UpperCAmelCase		,		lstrip=_UpperCAmelCase		,		rstrip=_UpperCAmelCase			) if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			) else eos_token
     UpperCamelCase_						=  AddedToken(_UpperCAmelCase		,		lstrip=_UpperCAmelCase		,		rstrip=_UpperCAmelCase			) if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			) else sep_token
     UpperCamelCase_						=  AddedToken(_UpperCAmelCase		,		lstrip=_UpperCAmelCase		,		rstrip=_UpperCAmelCase			) if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			) else cls_token
     UpperCamelCase_						=  AddedToken(_UpperCAmelCase		,		lstrip=_UpperCAmelCase		,		rstrip=_UpperCAmelCase			) if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			) else unk_token
     UpperCamelCase_						=  AddedToken(_UpperCAmelCase		,		lstrip=_UpperCAmelCase		,		rstrip=_UpperCAmelCase			) if isinstance(_UpperCAmelCase		,		_UpperCAmelCase			) else pad_token

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

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

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

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




  @property
  def  _UpperCAmelCase  (  self			)      ->			int:
     return len(self.encoder			)




  def  _UpperCAmelCase  (  self			)      ->			str:
     return dict(self.encoder		,		**self.added_tokens_encoder			)




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			str:
     if token in self.cache:
        return self.cache[token]
     UpperCamelCase_						=  tuple(_UpperCAmelCase			)
     UpperCamelCase_						=  get_pairs(_UpperCAmelCase			)

     if not pairs:
        return token

     while True:
        UpperCamelCase_						=  min(_UpperCAmelCase		,		key=lambda _UpperCAmelCase			: self.bpe_ranks.get(_UpperCAmelCase		,		float('inf'			)			)			)
        if bigram not in self.bpe_ranks:
           break
        UpperCamelCase_		,   UpperCamelCase_						=  bigram
        UpperCamelCase_						=  []
        UpperCamelCase_						=  0
        while i < len(_UpperCAmelCase			):
           try:
              UpperCamelCase_						=  word.index(_UpperCAmelCase		,		_UpperCAmelCase			)
           except ValueError:
              new_word.extend(word[i:]			)
              break
           else:
              new_word.extend(word[i:j]			)
              UpperCamelCase_						=  j

           if word[i] == first and i < len(_UpperCAmelCase			) - 1 and word[i + 1] == second:
              new_word.append(first + second			)
              i += 2
           else:
              new_word.append(word[i]			)
              i += 1
        UpperCamelCase_						=  tuple(_UpperCAmelCase			)
        UpperCamelCase_						=  new_word
        if len(_UpperCAmelCase			) == 1:
           break
        else:
           UpperCamelCase_						=  get_pairs(_UpperCAmelCase			)
     UpperCamelCase_						=  ' '.join(_UpperCAmelCase			)
     UpperCamelCase_						=  word
     return word




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			Any:
     UpperCamelCase_						=  []
     for token in re.findall(self.pat		,		_UpperCAmelCase			):
        UpperCamelCase_						=  ''.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(_UpperCAmelCase			).split(' '			)			)
     return bpe_tokens




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			List[str]:
     return self.encoder.get(_UpperCAmelCase		,		self.encoder.get(self.unk_token			)			)




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			List[Any]:
     return self.decoder.get(_UpperCAmelCase			)




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase			)      ->			Union[str, Any]:
     UpperCamelCase_						=  ''.join(_UpperCAmelCase			)
     UpperCamelCase_						=  bytearray([self.byte_decoder[c] for c in text]			).decode('utf-8'		,		errors=self.errors			)
     return text




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase = None			)      ->			Tuple[str]:
     if not os.path.isdir(_UpperCAmelCase			):
        logger.error(f"""Vocabulary path ({save_directory}) should be a directory"""			)
        return
     UpperCamelCase_						=  os.path.join(
         _UpperCAmelCase		,		(filename_prefix + '-' if filename_prefix else '') + VOCAB_FILES_NAMES['vocab_file']			)
     UpperCamelCase_						=  os.path.join(
         _UpperCAmelCase		,		(filename_prefix + '-' if filename_prefix else '') + VOCAB_FILES_NAMES['merges_file']			)

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

     UpperCamelCase_						=  0
     with open(_UpperCAmelCase		,		'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 _UpperCAmelCase			: 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!'			)
              UpperCamelCase_						=  token_index
           writer.write(' '.join(_UpperCAmelCase			) + '\n'			)
           index += 1

     return vocab_file, merge_file




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase = None			)      ->			List[int]:
     if token_ids_a is None:
        return [self.cls_token_id] + token_ids_a + [self.sep_token_id]
     UpperCamelCase_						=  [self.cls_token_id]
     UpperCamelCase_						=  [self.sep_token_id]
     return cls + token_ids_a + sep + sep + token_ids_a + sep




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase = None		,		_UpperCAmelCase = False			)      ->			List[int]:
     if already_has_special_tokens:
        return super().get_special_tokens_mask(
            token_ids_a=_UpperCAmelCase		,		token_ids_a=_UpperCAmelCase		,		already_has_special_tokens=_UpperCAmelCase			)

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




  def  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase = None			)      ->			List[int]:
     UpperCamelCase_						=  [self.sep_token_id]
     UpperCamelCase_						=  [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  _UpperCAmelCase  (  self		,		_UpperCAmelCase		,		_UpperCAmelCase=False		,		**_UpperCAmelCase			)      ->			List[str]:
     UpperCamelCase_						=  kwargs.pop('add_prefix_space'		,		self.add_prefix_space			)
     if (is_split_into_words or add_prefix_space) and (len(_UpperCAmelCase			) > 0 and not text[0].isspace()):
        UpperCamelCase_						=  ' ' + text
     return (text, kwargs)













import math
from datetime import datetime, timedelta






def      _snake_case     (__lowercase):
   UpperCamelCase_						=  year % 19
   UpperCamelCase_						=  year % 4
   UpperCamelCase_						=  year % 7
   UpperCamelCase_						=  math.floor(year / 100)
   UpperCamelCase_						=  math.floor((13 + 8 * leap_day_inhibits) / 25)
   UpperCamelCase_						=  leap_day_inhibits / 4
   UpperCamelCase_						=  (
       15 - lunar_orbit_correction + leap_day_inhibits - leap_day_reinstall_number
   ) % 30
   UpperCamelCase_						=  (4 + leap_day_inhibits - leap_day_reinstall_number) % 7

   # days to be added to March 21
   UpperCamelCase_						=  (19 * metonic_cycle + secular_moon_shift) % 30

   # PHM -> Paschal Full Moon
   UpperCamelCase_						=  (
       2 * julian_leap_year
       + 4 * non_leap_year
       + 6 * days_to_add
       + century_starting_point
   ) % 7

   if days_to_add == 29 and days_from_phm_to_sunday == 6:
      return datetime(__lowercase     ,   4     ,   19)
   elif days_to_add == 28 and days_from_phm_to_sunday == 6:
      return datetime(__lowercase     ,   4     ,   18)
   else:
      return datetime(__lowercase     ,   3     ,   22) + timedelta(
          days=int(days_to_add + days_from_phm_to_sunday))


if __name__ == "__main__":
 for year in (1_9_9_4, 2_0_0_0, 2_0_1_0, 2_0_2_1, 2_0_2_3):
  snake_case__   :						Dict													=   """will be""" if year > datetime.now().year else """was"""
  print(f'Easter in {year} {tense} {gauss_easter(year)}')





