+
    *:g                      a  0 t $ R t^ RIHt ^ RIt^ RIt^ RIHtHt ^ RI	H	t	 ^ RI
Ht ^ RIHt ^ RIHt ^ RIHt ^ R	IHt ^ R
IHt ^ RIHtHt ^ RIHt ^ RIHt ^ RIHtH t H!t!H"t" ]'       d,   ^ RI#H$t$ ]%]&]%R3,          ,          ]']%,          ,          t(R])R&   . R$Ot*R%R lt+]PX                  ! R]PZ                  4      t.R R lt/R R lt0 ! R R4      t1 ! R R]24      t3Rt4R R  lt5R&R! R" llt6 ! R# R4      t7R# )'z
babel.messages.catalog
~~~~~~~~~~~~~~~~~~~~~~

Data structures for message catalogs.

:copyright: (c) 2013-2025 by the Babel Team.
:license: BSD, see LICENSE for more details.
)annotationsN)IterableIterator)copy)SequenceMatcher)message_from_string)nlargest)	Formatter)TYPE_CHECKING)__version__)LocaleUnknownLocaleError)format_datetime)
get_plural)LOCALTZFixedOffsetTimezone_cmpdistinct)	TypeAlias.r   
_MessageIDCatalogMessageTranslationErrorc                   V^ 8  g   \        RV: 24      hRTu;8:  d   R8:  g   M \        RV: 24      h. p\        RR7      pVP                  V 4       V Fz  pVP                  V4       VP	                  4       V8  g   K+  VP                  4       V8  g   KB  VP                  4       V8  g   KY  VP                  VP                  4       V34       K|  	  \        W$4      pV UUu. uF  w  rvVNK	  	  upp# u uppi )zA modified version of ``difflib.get_close_matches``.

It just passes ``autojunk=False`` to the ``SequenceMatcher``, to work
around https://github.com/python/cpython/issues/90825.
zn must be > 0: g        g      ?zcutoff must be in [0.0, 1.0]: F)autojunk)	
ValueErrorr   set_seq2set_seq1real_quick_ratioquick_ratioratioappendr   )wordpossibilitiesncutoffresultsxscores   &&&&    8/usr/lib/python3/dist-packages/babel/messages/catalog.pyget_close_matchesr+   *   s     q5?1%011&C9&DEEF'AJJt	

16)==?f$779MM1779a.)  a F$%f(%Af%%%s   &C7z
    \%
        (?:\(([\w]*)\))?
        (
            [-#0\ +]?(?:\*|[\d]+)?
            (?:\.(?:\*|[\d]+))?
            [hlL]?
        )
        ([diouxXeEfFgGcrs%])
c                    V ^8  d   QhRRRR/# )   stringstrreturnbool )formats   "r*   __annotate__r4   P   s      S T     c                    R V 9  d   R# \        4       p RpVP                  V 4       F  pV^,          f   K  RpK  	  V#   \         d     R# i ; i){FT)r	   parser   )r.   fmtfield_name_seents   &   r*   _has_python_brace_formatr<   P   s^    
&
+C  6"At"& #   s   A  A   AAc                    V ^8  d   QhRRRR/# )r-   valuer/   r0   zdatetime.datetimer2   )r3   s   "r*   r4   r4   c   s      # *; r5   c                   \         P                  ! R V 4      p\        P                  P                  VP	                  R4      R4      pVP	                  R4      pVe}   V^ ,          VR,          rTVR,          VR,          rv\        V R24      p\        V4      p	\        V4      p
V	^<,          pW,          pW,          p\        V4      pVP                  VR7      pV# )	z+^(?P<datetime>.*?)(?P<tzoffset>[+-]\d{4})?$datetimez%Y-%m-%d %H:%Mtzoffset:   NN:Nr-   N:r-   NN1tzinfo)rematchr@   strptimegroupintr   replace)r>   rG   dtrA   plus_minus_sresthours_offset_smins_offset_s
plus_minushours_offsetmins_offsetnet_mins_offsets   &           r*   _parse_datetime_headerrU   c   s    HHCUKE				#	#EKK
$;=M	NB {{:&H%a[(2,d(,R$r( L>+,
>*-( '+&% '7 ZZxZ(Ir5   c                  
   ] tR t^tRtR$R R lltR R ltR R ltR	 R
 ltR R lt	R R lt
R R ltR R ltR R ltR R ltR R ltR%R R llt]R R l4       t]R R l4       t]R R  l4       t]R! R" l4       tR#tR# )&r   z0Representation of a single message in a catalog.Nc               @    V ^8  d   QhRRRRRRRRR	RR
RRRRRRRRR/
# )r-   idr   r.   _MessageID | None	locationsIterable[tuple[str, int]]flagsIterable[str]auto_commentsuser_commentsprevious_idlineno
int | Nonecontext
str | Noner0   Noner2   )r3   s   "r*   r4   Message.__annotate__   sn     1 11 "1 -	1
 1 %1 %1  1 1 1 
1r5   c
                   Wn         V'       g   V P                  '       d   RpW n        \        \	        V4      4      V n        \        V4      V n        V'       d/   V P                  '       d   V P                  P                  R4       MV P                  P                  R4       V'       d/   V P                  '       d   V P                  P                  R4       MV P                  P                  R4       \        \	        V4      4      V n        \        \	        V4      4      V n        \        V\        4      '       d
   V.V n        M\        V4      V n        Wn        Wn        R# )a  Create the message object.

:param id: the message ID, or a ``(singular, plural)`` tuple for
           pluralizable messages
:param string: the translated message string, or a
               ``(singular, plural)`` tuple for pluralizable messages
:param locations: a sequence of ``(filename, lineno)`` tuples
:param flags: a set or sequence of flags
:param auto_comments: a sequence of automatic comments for the message
:param user_comments: a sequence of user comments for the message
:param previous_id: the previous message ID, or a ``(singular, plural)``
                    tuple for pluralizable messages
:param lineno: the line number on which the msgid line was found in the
               PO file, if any
:param context: the message context
zpython-formatzpython-brace-formatN) rh   )rX   pluralizabler.   listr   rZ   setr\   python_formatadddiscardpython_brace_formatr^   r_   
isinstancer/   r`   ra   rc   )
selfrX   r.   rZ   r\   r^   r_   r`   ra   rc   s
   &&&&&&&&&&r*   __init__Message.__init__   s    8 $+++Fhy12Z
$$$$JJNN?+JJ/$***JJNN01JJ45!(="9:!(="9:k3'' +}D#K0Dr5   c                   V ^8  d   QhRR/# r-   r0   r/   r2   )r3   s   "r*   r4   rf      s     T T# Tr5   c                	~    R \        V 4      P                   RV P                  : R\        V P                  4      : R2# )< z	 (flags: z)>)type__name__rX   rj   r\   rq   s   &r*   __repr__Message.__repr__   s7    4:&&'q9T$**=M<PPRSSr5   c                    V ^8  d   QhRRRR/# )r-   otherobjectr0   rJ   r2   )r3   s   "r*   r4   rf      s     G GV G Gr5   c                8    R p\        V! V 4      V! V4      4      # )z0Compare Messages, taking into account plural idsc                    \        V \        4      '       d<   V P                  '       d*   V P                  ^ ,          V P                  ;'       g    R3# V P                  V P                  ;'       g    R3# )    rh   )rp   r   ri   rX   rc   )objs   &r*   values_to_compare*Message.__cmp__.<locals>.values_to_compare   sT    #w''C,<,<,<vvay#++"3"333663;;,,",,r5   )r   )rq   r   r   s   && r*   __cmp__Message.__cmp__   s"    	- %d+->u-EFFr5   c                    V ^8  d   QhRRRR/# r-   r   r   r0   r1   r2   )r3   s   "r*   r4   rf           ' 'F 't 'r5   c                	*    V P                  V4      ^ 8  # r   r   rq   r   s   &&r*   __gt__Message.__gt__       ||E"Q&&r5   c                    V ^8  d   QhRRRR/# r   r2   )r3   s   "r*   r4   rf      r   r5   c                	*    V P                  V4      ^ 8  # r   r   r   s   &&r*   __lt__Message.__lt__   r   r5   c                    V ^8  d   QhRRRR/# r   r2   )r3   s   "r*   r4   rf           ( (F (t (r5   c                	*    V P                  V4      ^ 8  # r   r   r   s   &&r*   __ge__Message.__ge__       ||E"a''r5   c                    V ^8  d   QhRRRR/# r   r2   )r3   s   "r*   r4   rf      r   r5   c                	*    V P                  V4      ^ 8*  # r   r   r   s   &&r*   __le__Message.__le__   r   r5   c                    V ^8  d   QhRRRR/# r   r2   )r3   s   "r*   r4   rf      r   r5   c                	*    V P                  V4      ^ 8H  # r   r   r   s   &&r*   __eq__Message.__eq__   r   r5   c                    V ^8  d   QhRRRR/# r   r2   )r3   s   "r*   r4   rf      r   r5   c                	*    V P                  V4      ^ 8g  # r   r   r   s   &&r*   __ne__Message.__ne__   r   r5   c                    V ^8  d   QhRRRR/# )r-   r   r   r0   r1   r2   )r3   s   "r*   r4   rf      s     / /' /d /r5   c                d    \        V\        4      '       g   Q hV P                  VP                  8H  # )zKChecks whether messages are identical, taking into account all
properties.
)rp   r   __dict__r   s   &&r*   is_identicalMessage.is_identical   s*     %))))}}..r5   c                   V ^8  d   QhRR/# )r-   r0   r   r2   )r3   s   "r*   r4   rf      s     @ @w @r5   c                	    \        \        \        V P                  V P                  V P
                  V P                  V P                  V P                  V P                  V P                  V P                  3	4      !  # N)r   mapr   rX   r.   rZ   r\   r^   r_   r`   ra   rc   r{   s   &r*   cloneMessage.clone   s^    D477DKK#'::t/A/A#'#5#5t7G7G#';;#> ? @ 	@r5   c                    V ^8  d   QhRRRR/# )r-   catalogzCatalog | Noner0   zlist[TranslationError]r2   )r3   s   "r*   r4   rf      s      ^ 7M r5   c                    ^ RI Hp . pV F  p V! W4       K  	  V#   \         d   pTP                  T4        Rp?K4  Rp?ii ; i)a]  Run various validation checks on the message.  Some validations
are only performed if the catalog is provided.  This method returns
a sequence of `TranslationError` objects.

:rtype: ``iterator``
:param catalog: A catalog instance that is passed to the checkers
:see: `Catalog.check` for a way to perform checks for all messages
      in a catalog.
)checkersN)babel.messages.checkersr   r   r!   )rq   r   r   errorscheckeres   &&    r*   checkMessage.check   sK     	5)+G!&  
  $ !a  !s   A?Ac                   V ^8  d   QhRR/# r-   r0   r1   r2   )r3   s   "r*   r4   rf      s     % %t %r5   c                     RV P                   9   # )zWhether the translation is fuzzy.

>>> Message('foo').fuzzy
False
>>> msg = Message('foo', 'foo', flags=['fuzzy'])
>>> msg.fuzzy
True
>>> msg
<Message 'foo' (flags: ['fuzzy'])>

:type:  `bool`fuzzyr\   r{   s   &r*   r   Message.fuzzy   s     $**$$r5   c                   V ^8  d   QhRR/# r   r2   )r3   s   "r*   r4   rf     s     	2 	2d 	2r5   c                B    \        V P                  \        \        34      # )zWhether the message is plurizable.

>>> Message('foo').pluralizable
False
>>> Message(('foo', 'bar')).pluralizable
True

:type:  `bool`)rp   rX   rj   tupler{   s   &r*   ri   Message.pluralizable  s     $''D%=11r5   c                   V ^8  d   QhRR/# r   r2   )r3   s   "r*   r4   rf     s     ; ;t ;r5   c                    V P                   p\        V\        \        34      '       g   V.p\        ;QJ d    R V 4       F  '       g   K   R# 	  R# ! R V 4       4      # )zWhether the message contains Python-style parameters.

>>> Message('foo %(name)s bar').python_format
True
>>> Message(('foo %(name)s', 'foo %(name)s')).python_format
True

:type:  `bool`c              3  L   "   T F  p\         P                  V4      x  K  	  R # 5ir   )PYTHON_FORMATsearch.0rX   s   & r*   	<genexpr>(Message.python_format.<locals>.<genexpr>  s     :c=''++cs   "$TFrX   rp   rj   r   anyrq   idss   & r*   rl   Message.python_format  sN     gg#e}--%Cs:c:ss:s:s:c:::r5   c                   V ^8  d   QhRR/# r   r2   )r3   s   "r*   r4   rf     s     ? ?T ?r5   c                    V P                   p\        V\        \        34      '       g   V.p\        ;QJ d    R V 4       F  '       g   K   R# 	  R# ! R V 4       4      # )zWhether the message contains Python f-string parameters.

>>> Message('Hello, {name}!').python_brace_format
True
>>> Message(('One apple', '{count} apples')).python_brace_format
True

:type:  `bool`c              3  8   "   T F  p\        V4      x  K  	  R # 5ir   )r<   r   s   & r*   r   .Message.python_brace_format.<locals>.<genexpr>+  s     >#B+B//#s   TFr   r   s   & r*   ro   Message.python_brace_format  sN     gg#e}--%Cs>#>ss>s>s>#>>>r5   )	r^   rc   r\   rX   ra   rZ   r`   r.   r_   )rh   r2   r2   r2   r2   r2   NNr   )rz   
__module____qualname____firstlineno____doc__rr   r|   r   r   r   r   r   r   r   r   r   r   propertyr   ri   rl   ro   __static_attributes__r2   r5   r*   r   r      s    :1fTG''((((/@& % % 	2 	2 ; ; ? ?r5   c                      ] tR tRtRtRtR# )r   i.  z[Exception thrown by translation checkers when invalid message
translations are encountered.r2   N)rz   r   r   r   r   r   r2   r5   r*   r   r   .  s    %r5   z# Translations template for PROJECT.
# Copyright (C) YEAR ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#c                    V ^8  d   QhRRRR/# )r-   r>   r/   r0   zdict[str, str]r2   )r3   s   "r*   r4   r4   ;  s        #  .  r5   c                V    ^ RI Hp V! 4       pWR&   \        VP                  4       4      # )r   )r   content-type)email.messager   dict
get_params)r>   r   ms   &  r*   parse_separated_headerr   ;  s%    %	Anr5   c               (    V ^8  d   QhRRRRRRRR/# )r-   r'   zstr | bytesencodingr/   r   r0   r2   )r3   s   "r*   r4   r4   C  s)      ; #  TW r5   c                    \        V \        4      '       d   V # \        V \        4      '       d   V P                  W4      # \        V 4      # r   )rp   r/   bytesdecode)r'   r   r   s   &&&r*   _force_textr   C  s9    !S!Uxx))q6Mr5   c                     ] tR tRtRtRR]RRRRRRRRRR3R R lltR R ltR	 R
 ltR R lt	]
! ]]4      t]
! ]	4      tR R ltR R lt]
! ]]RR7      tR R ltR R lt]
! ]]RR7      t]
R R l4       t]
R R l4       t]
R R l4       tR R ltR  R! ltR" R# ltR$ R% ltR& R' ltR( R) ltR* R+ ltR=R, R- lltR. R/ ltR>R0 R1 lltR>R2 R3 llt R?R4 R5 llt!R6 R7 lt"R>R8 R9 llt#R: R; lt$R<t%R# )@r   iK  z$Representation of a message catalog.NTc               P    V ^8  d   QhRRRRRRRRRRRRR	RR
RRRRRRRRRRRRR/# )r-   localeLocale | str | Nonedomainrd   header_commentprojectversioncopyright_holdermsgid_bugs_addresscreation_datezdatetime.datetime | str | Nonerevision_datez6datetime.datetime | datetime.time | float | str | Nonelast_translatorlanguage_teamcharsetr   r1   r0   re   r2   )r3   s   "r*   r4   Catalog.__annotate__N  s     D! D!#D! D! #	D!
 D! D! %D! 'D! 6D! ND! $D! "D! D! D! 
D!r5   c                   W n         Wn        W0n        / V n        T;'       g    RV n        T;'       g    RV n        T;'       g    RV n        T;'       g    RV n        T
;'       g    RV n         T;'       g    RV n	         T;'       g    RV n
        Vf%   \        P                  P                  \        4      pMH\        V\        P                  4      '       d)   VP                  '       g   VP!                  \        R	7      pWn        V	f   R
p	MH\        V	\        P                  4      '       d)   V	P                  '       g   V	P!                  \        R	7      p	Wn        Wn        / V n        RV n        RV n        R# )a  Initialize the catalog object.

:param locale: the locale identifier or `Locale` object, or `None`
               if the catalog is not bound to a locale (which basically
               means it's a template)
:param domain: the message domain
:param header_comment: the header comment as string, or `None` for the
                       default header
:param project: the project's name
:param version: the project's version
:param copyright_holder: the copyright holder of the catalog
:param msgid_bugs_address: the email address or URL to submit bug
                           reports to
:param creation_date: the date the catalog was created
:param revision_date: the date the catalog was revised
:param last_translator: the name and email of the last translator
:param language_team: the name and email of the language team
:param charset: the encoding to use in the output (defaults to utf-8)
:param fuzzy: the fuzzy bit on the catalog header
PROJECTVERSIONORGANIZATIONzEMAIL@ADDRESSzFULL NAME <EMAIL@ADDRESS>zLANGUAGE <LL@li.org>utf-8NrD   zYEAR-MO-DA HO:MI+ZONE)r   r   _header_comment	_messagesr   r   r   r   r   r   r   r@   nowr   rp   rE   rK   r   r   r   obsolete_num_plurals_plural_expr)rq   r   r   r   r   r   r   r   r   r   r   r   r   r   s   &&&&&&&&&&&&&&r*   rr   Catalog.__init__N  sE   H -?A++)++) 0 B BN"4"G"G.MM2M<*DD.D:))' $--11':Mx'8'899-BVBVBV)111AM* 3Mx'8'899-BVBVBV)111AM*
 ?A  r5   c                    V ^8  d   QhRRRR/# )r-   r   r   r0   re   r2   )r3   s   "r*   r4   r     s     k k"5 k$ kr5   c                	^   Vf   R V n         R V n        R # \        V\        4      '       d   \	        V4      V n         Wn        R # \        V\        4      '       d/   \	        V4      V n          \        P
                  ! V4      V n        R # \        RV: 24      h  \         d    R T n         R # i ; i)NzD`locale` must be a Locale, a locale identifier string, or None; got )_locale_identifier_localerp   r   r/   r8   r   	TypeErrorrq   r   s   &&r*   _set_localeCatalog._set_locale  s    >&*D#DLff%%&)&kD#!Lfc""&)&kD#$%||F3 ^_e^hijj	 & $#$s   *B B,+B,c                   V ^8  d   QhRR/# )r-   r0   zLocale | Noner2   )r3   s   "r*   r4   r     s      ] r5   c                	    V P                   # r   )r  r{   s   &r*   _get_localeCatalog._get_locale  s    ||r5   c                   V ^8  d   QhRR/# )r-   r0   rd   r2   )r3   s   "r*   r4   r     s     ' '
 'r5   c                	    V P                   # r   )r  r{   s   &r*   _get_locale_identifierCatalog._get_locale_identifier  s    &&&r5   c                   V ^8  d   QhRR/# ru   r2   )r3   s   "r*   r4   r     s      S r5   c                	R   V P                   p\        P                  P                  \        4      P	                  R 4      p\        V P                  R4      '       d   V P                  P	                  R 4      pVP                  RV P                  4      P                  RV P                  4      P                  RV4      P                  RV P                  4      pV P                  '       d   V P                  P                  MV P                  pV'       d   VP                  RV R24      pV# )z%Ystrftimer  r  YEARr  zTranslations templatez translations)r  r@   r  r   r  hasattrr   rK   r   r   r   r   english_namelocale_identifier)rq   commentyearlocale_names   &   r*   _get_header_commentCatalog._get_header_comment  s    &&  $$W-66t<4%%z22%%..t4D//)T\\:!')T\\:!'&$/!'.$2G2GH 	 48;;;t{{//DDZDZoo&=+m?\]Gr5   c                    V ^8  d   QhRRRR/# )r-   r.   rd   r0   re   r2   )r3   s   "r*   r4   r     s     & &* & &r5   c                	    Wn         R # r   )r  )rq   r.   s   &&r*   _set_header_commentCatalog._set_header_comment  s    %r5   a      The header comment for the catalog.

    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   copyright_holder='Foo Company')
    >>> print(catalog.header_comment) #doctest: +ELLIPSIS
    # Translations template for Foobar.
    # Copyright (C) ... Foo Company
    # This file is distributed under the same license as the Foobar project.
    # FIRST AUTHOR <EMAIL@ADDRESS>, ....
    #

    The header can also be set from a string. Any known upper-case variables
    will be replaced when the header is retrieved again:

    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   copyright_holder='Foo Company')
    >>> catalog.header_comment = '''\
    ... # The POT for my really cool PROJECT project.
    ... # Copyright (C) 1990-2003 ORGANIZATION
    ... # This file is distributed under the same license as the PROJECT
    ... # project.
    ... #'''
    >>> print(catalog.header_comment)
    # The POT for my really cool Foobar project.
    # Copyright (C) 1990-2003 Foo Company
    # This file is distributed under the same license as the Foobar
    # project.
    #

    :type: `unicode`
    )docc                   V ^8  d   QhRR/# )r-   r0   zlist[tuple[str, str]]r2   )r3   s   "r*   r4   r     s      #8 r5   c           	     	L   \        V P                  \        P                  \        P                  \        \
        34      '       d   \        V P                  R RR7      pMV P                  pV P                  pV P                  '       d-   RV9   d&   VP                  R\        V P                  4      4      pRV P                   RV P                   23RV P                  3R\        V P                  R RR7      3RV3R	V P                  3.pV P                  '       d'   VP!                  R
\        V P                  4      34       VP!                  RV34       V P"                  e   VP!                  RV P$                  34       VRRRV P&                   23RRR\(         R23.,          pV# )zyyyy-MM-dd HH:mmZen)r   LANGUAGEzProject-Id-Versionrx   zReport-Msgid-Bugs-TozPOT-Creation-DatezPO-Revision-DatezLast-TranslatorLanguagezLanguage-TeamzPlural-FormszContent-Typeztext/plain; charset=zGenerated-ByzBabel 
)zMIME-Versionz1.0)zContent-Transfer-Encoding8bit)rp   r   r@   timerJ   floatr   r   r"  rK   r/   r   r   r   r   r   r!   r   plural_formsr   r  )rq   r   r   headerss   &   r*   _get_mime_headersCatalog._get_mime_headers  s   d((8+<+<hmmSRW*XYY+D,>,>@S\`aM ..M**!!!jM&A)11*c$BXBX>YZM "dll^1T\\N#CD#T%<%<= /$2D2DFYbf"gh/ 4 45*
 !!!NNJD,B,B(CDE78;;"NNND,=,=>?#3DLL>BC1vgYb12	
 	
 r5   c                    V ^8  d   QhRRRR/# )r-   r7  zIterable[tuple[str, str]]r0   re   r2   )r3   s   "r*   r4   r     s     "G "G)B "Gt "Gr5   c                	n   V EF  w  r#\        VP                  4       V P                  R 7      p\        W0P                  R 7      pVR8X  d;   VP                  R4      pRP	                  VRR 4      V n        VR,          V n        K  VR8X  d	   W0n        K  VR8X  d	   W0n        K  VR8X  d0   VP                  RR4      pT P                  T;'       g    R4       K  VR	8X  d	   W0n        K  VR
8X  d5   \        V4      pRV9   d    VR,          P                  4       V n        EK  EK   VR8X  dI   \        RV 24      p\        VP                  R^4      4      V n        VP                  RR4      V n        EKo  VR8X  d   \#        V4      V n        EK  VR8X  g   EK  RV9  g   EK  \#        V4      V n        EK  	  R# ))r   zproject-id-versionrx   Nzreport-msgid-bugs-tozlast-translatorlanguage-_zlanguage-teamr   r   zplural-formsz ;npluralsplural(n != 1)zpot-creation-datezpo-revision-dater  )r   lowerr   splitjoinr   r   r   r   rK   r  r   r   rJ   getr	  r
  rU   r   r   )rq   r7  namer>   partsparamss   &&    r*   _set_mime_headersCatalog._set_mime_headers  sp   "KDtzz|dllCD=E++C("xxcr
3$Ry//*/'**',$#c3/
   $/(%*"'/6&#))#4#:#:#<DL ''/"UG=$'

:q(A$B!$*JJx$D!,,%;E%B"++&)?)FD&C #r5   a      The MIME headers of the catalog, used for the special ``msgid ""`` entry.

    The behavior of this property changes slightly depending on whether a locale
    is set or not, the latter indicating that the catalog is actually a template
    for actual translations.

    Here's an example of the output for such a catalog template:

    >>> from babel.dates import UTC
    >>> from datetime import datetime
    >>> created = datetime(1990, 4, 1, 15, 30, tzinfo=UTC)
    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   creation_date=created)
    >>> for name, value in catalog.mime_headers:
    ...     print('%s: %s' % (name, value))
    Project-Id-Version: Foobar 1.0
    Report-Msgid-Bugs-To: EMAIL@ADDRESS
    POT-Creation-Date: 1990-04-01 15:30+0000
    PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
    Last-Translator: FULL NAME <EMAIL@ADDRESS>
    Language-Team: LANGUAGE <LL@li.org>
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    Generated-By: Babel ...

    And here's an example of the output when the locale is set:

    >>> revised = datetime(1990, 8, 3, 12, 0, tzinfo=UTC)
    >>> catalog = Catalog(locale='de_DE', project='Foobar', version='1.0',
    ...                   creation_date=created, revision_date=revised,
    ...                   last_translator='John Doe <jd@example.com>',
    ...                   language_team='de_DE <de@example.com>')
    >>> for name, value in catalog.mime_headers:
    ...     print('%s: %s' % (name, value))
    Project-Id-Version: Foobar 1.0
    Report-Msgid-Bugs-To: EMAIL@ADDRESS
    POT-Creation-Date: 1990-04-01 15:30+0000
    PO-Revision-Date: 1990-08-03 12:00+0000
    Last-Translator: John Doe <jd@example.com>
    Language: de_DE
    Language-Team: de_DE <de@example.com>
    Plural-Forms: nplurals=2; plural=(n != 1);
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    Generated-By: Babel ...

    :type: `list`
    c                   V ^8  d   QhRR/# r-   r0   rJ   r2   )r3   s   "r*   r4   r   [  s     ! !S !r5   c                    V P                   f7   ^pV P                  '       d   \        V P                  4      ^ ,          pWn         V P                   # )zThe number of plurals used by the catalog or locale.

>>> Catalog(locale='en').num_plurals
2
>>> Catalog(locale='ga').num_plurals
5

:type: `int`)r	  r   r   )rq   nums   & r*   num_pluralsCatalog.num_pluralsZ  sC     $C{{{ -a0 #   r5   c                   V ^8  d   QhRR/# ru   r2   )r3   s   "r*   r4   r   l  s     ! !S !r5   c                    V P                   f7   RpV P                  '       d   \        V P                  4      ^,          pWn         V P                   # )a  The plural expression used by the catalog or locale.

>>> Catalog(locale='en').plural_expr
'(n != 1)'
>>> Catalog(locale='ga').plural_expr
'(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'
>>> Catalog(locale='ding').plural_expr  # unknown locale
'(n != 1)'

:type: `str`rA  )r
  r   r   )rq   exprs   & r*   plural_exprCatalog.plural_exprk  sC     $D{{{!$++.q1 $   r5   c                   V ^8  d   QhRR/# ru   r2   )r3   s   "r*   r4   r     s     	J 	Jc 	Jr5   c                <    RV P                    RV P                   R2# )zReturn the plural forms declaration for the locale.

>>> Catalog(locale='en').plural_forms
'nplurals=2; plural=(n != 1);'
>>> Catalog(locale='pt_BR').plural_forms
'nplurals=2; plural=(n > 1);'

:type: `str`z	nplurals=z	; plural=;)rP  rU  r{   s   &r*   r6  Catalog.plural_forms~  s'     4++,Id6F6F5GqIIr5   c                    V ^8  d   QhRRRR/# )r-   rX   r   r0   r1   r2   )r3   s   "r*   r4   r     s     3 3z 3d 3r5   c                >    V P                  V4      V P                  9   # )z?Return whether the catalog has a message with the specified ID._key_forr  rq   rX   s   &&r*   __contains__Catalog.__contains__  s    }}R DNN22r5   c                   V ^8  d   QhRR/# rM  r2   )r3   s   "r*   r4   r     s     # # #r5   c                ,    \        V P                  4      # )z]The number of messages in the catalog.

This does not include the special ``msgid ""`` entry.)lenr  r{   s   &r*   __len__Catalog.__len__  s     4>>""r5   c                   V ^8  d   QhRR/# )r-   r0   zIterator[Message]r2   )r3   s   "r*   r4   r     s     & &+ &r5   c              #  B  "   . pV P                    F  w  r#VP                  V RV 24       K  	  \        4       pV P                  '       d   VR0,          p\	        RRP                  V4      VR7      x  V P                   F  pV P                  V,          x  K  	  R# 5i)zIterates through all the entries in the catalog, in the order they
were added, yielding a `Message` object for every entry.

:rtype: ``iterator``z: r   rh   r2  r   N)mime_headersr!   rk   r   r   rE  r  )rq   bufrG  r>   r\   keys   &     r*   __iter__Catalog.__iter__  s     
 ,,KDJJ$r%)* -:::gYEb$))C.66>>C..%% "s   BBc                   V ^8  d   QhRR/# ru   r2   )r3   s   "r*   r4   r     s     B B# Br5   c                	    R pV P                   '       d   RV P                    2pR\        V 4      P                   RV P                  : V R2# )rh   rx   rw   >)r   ry   rz   r   r  s   & r*   r|   Catalog.__repr__  sH    ;;;&F4:&&'qxqAAr5   c                    V ^8  d   QhRRRR/# )r-   rX   r   r0   re   r2   )r3   s   "r*   r4   r     s      j T r5   c                (    V P                  V4       R# )z)Delete the message with the specified ID.N)deleter_  s   &&r*   __delitem__Catalog.__delitem__  s    Br5   c                    V ^8  d   QhRRRR/# )r-   rX   r   r0   r   r2   )r3   s   "r*   r4   r     s      j W r5   c                $    V P                  V4      # )zEReturn the message with the specified ID.

:param id: the message ID
)rF  r_  s   &&r*   __getitem__Catalog.__getitem__  s    
 xx|r5   c               $    V ^8  d   QhRRRRRR/# )r-   rX   r   messager   r0   re   r2   )r3   s   "r*   r4   r     s!     .* .*j .*7 .*t .*r5   c                   \        V\        4      '       g   Q R4       hV P                  WP                  4      pV P                  P                  V4      pV'       Ed   VP                  '       d5   VP                  '       g#   VP                  Vn        VP                  Vn        \        \        VP                  VP                  ,           4      4      Vn        \        \        VP                  VP                  ,           4      4      Vn        \        \        VP                  VP                  ,           4      4      Vn        V;P                  VP                  ,          un        R# VR8X  d}   \        VP                  4      P!                  4       V n        RP%                  VP                   Uu. uF  pRV 2P'                  4       NK  	  up4      V n        VP*                  V n        R# \        V\        \,        34      '       dD   \        VP                  \        \,        34      '       g   Q R\/        VP                  4       24       hW P                  V&   R# u upi )ai  Add or update the message with the specified ID.

>>> catalog = Catalog()
>>> catalog[u'foo'] = Message(u'foo')
>>> catalog[u'foo']
<Message u'foo' (flags: [])>

If a message with that ID is already in the catalog, it is updated
to include the locations and flags of the new message.

>>> catalog = Catalog()
>>> catalog[u'foo'] = Message(u'foo', locations=[('main.py', 1)])
>>> catalog[u'foo'].locations
[('main.py', 1)]
>>> catalog[u'foo'] = Message(u'foo', locations=[('utils.py', 5)])
>>> catalog[u'foo'].locations
[('main.py', 1), ('utils.py', 5)]

:param id: the message ID
:param message: the `Message` object
zexpected a Message objectrh   r2  z# zExpected sequence but got N)rp   r   r^  rc   r  rF  ri   rX   r.   rj   r   rZ   r^   r_   r\   r   itemsri  rE  rstripr   r   r   ry   )rq   rX   r|  rk  currentcs   &&&   r*   __setitem__Catalog.__setitem__  s   , '7++H-HH+mmB0..$$S)7###G,@,@,@$ZZ
!( $Xg.?.?.5.?.?/@ &A !BG$('2G2G292G2G3H *I %JG!$('2G2G292G2G3H *I %JG!MMW]]*M2X 3GNN C I I KD"&))H]H],^H]1r!X__->H],^"_D DJ"tUm,,!'..4-@@ H0gnn1E0FGH@")NN3 -_s   ,Ic               @    V ^8  d   QhRRRRRRRRR	RR
RRRRRRRRR/
# )r-   rX   r   r.   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   r0   r   r2   )r3   s   "r*   r4   r     sn     ) )) ") -	)
 ) %) %)  ) ) ) 
)r5   c
                B    \        W\        V4      WEWgVV	R7	      p
WV&   V
# )a  Add or update the message with the specified ID.

>>> catalog = Catalog()
>>> catalog.add(u'foo')
<Message ...>
>>> catalog[u'foo']
<Message u'foo' (flags: [])>

This method simply constructs a `Message` object with the given
arguments and invokes `__setitem__` with that object.

:param id: the message ID, or a ``(singular, plural)`` tuple for
           pluralizable messages
:param string: the translated message string, or a
               ``(singular, plural)`` tuple for pluralizable messages
:param locations: a sequence of ``(filename, lineno)`` tuples
:param flags: a set or sequence of flags
:param auto_comments: a sequence of automatic comments
:param user_comments: a sequence of user comments
:param previous_id: the previous message ID, or a ``(singular, plural)``
                    tuple for pluralizable messages
:param lineno: the line number on which the msgid line was found in the
               PO file, if any
:param context: the message context
)ra   rc   )r   rj   )rq   rX   r.   rZ   r\   r^   r_   r`   ra   rc   r|  s   &&&&&&&&&& r*   rm   Catalog.add  s/    J "d9ou'V")+ Rr5   c                   V ^8  d   QhRR/# )r-   r0   z0Iterable[tuple[Message, list[TranslationError]]]r2   )r3   s   "r*   r4   r     s     & &G &r5   c              #     "   V P                   P                  4        F$  pVP                  V R7      pV'       g   K  W3x  K&  	  R# 5i)a4  Run various validation checks on the translations in the catalog.

For every message which fails validation, this method yield a
``(message, errors)`` tuple, where ``message`` is the `Message` object
and ``errors`` is a sequence of `TranslationError` objects.

:rtype: ``generator`` of ``(message, errors)``
)r   N)r  valuesr   )rq   r|  r   s   &  r*   r   Catalog.check  s;      ~~,,.G]]4]0Fvo% /s
   5AAc               $    V ^8  d   QhRRRRRR/# )r-   rX   r   rc   rd   r0   zMessage | Noner2   )r3   s   "r*   r4   r     s!     > >j >: > >r5   c                V    V P                   P                  V P                  W4      4      # )zReturn the message with the specified ID and context.

:param id: the message ID
:param context: the message context, or ``None`` for no context
)r  rF  r^  )rq   rX   rc   s   &&&r*   rF  Catalog.get  s"     ~~!!$--"<==r5   c               $    V ^8  d   QhRRRRRR/# )r-   rX   r   rc   rd   r0   re   r2   )r3   s   "r*   r4   r   %  s!     $ $ $j $D $r5   c                f    V P                  W4      pW0P                  9   d   V P                  V R# R# )zDelete the message with the specified ID and context.

:param id: the message ID
:param context: the message context, or ``None`` for no context
Nr]  rq   rX   rc   rk  s   &&& r*   rt  Catalog.delete%  s-     mmB(.. s# !r5   c               0    V ^8  d   QhRRRRRRRRRRRR	/# )
r-   templater   no_fuzzy_matchingr1   update_header_commentkeep_user_commentsupdate_creation_dater0   re   r2   )r3   s   "r*   r4   r   /  sN     U8 U8U8  U8  $	U8
 !U8 #U8 
U8r5   c                  a aaaa S P                   oSP                  4       o/ S n         / pV'       gh   S Fa  pV'       g   K  SV,          P                  '       g   K(  S P                  V4      pSV,          P                  p	W3VS P                  V4      &   Kc  	  \        4       oR VVVVV 3R llp
V F  pVP                  '       g   K  S P                  VP                  VP                  4      pVS9   d   V
! WV4       KO  V'       gX   \        S P                  V4      VP                  4       ^4      pV'       d&   V^ ,          pWm,          w  rVe   W3pV
! WV4       K  VS VP                  &   K  	  S F*  pV'       g
   VS9  g   K  SV,          S P                  V&   K,  	  V'       d   VP                  S n        V'       d   VP                  S n        R# R# )aB  Update the catalog based on the given template catalog.

>>> from babel.messages import Catalog
>>> template = Catalog()
>>> template.add('green', locations=[('main.py', 99)])
<Message ...>
>>> template.add('blue', locations=[('main.py', 100)])
<Message ...>
>>> template.add(('salad', 'salads'), locations=[('util.py', 42)])
<Message ...>
>>> catalog = Catalog(locale='de_DE')
>>> catalog.add('blue', u'blau', locations=[('main.py', 98)])
<Message ...>
>>> catalog.add('head', u'Kopf', locations=[('util.py', 33)])
<Message ...>
>>> catalog.add(('salad', 'salads'), (u'Salat', u'Salate'),
...             locations=[('util.py', 38)])
<Message ...>

>>> catalog.update(template)
>>> len(catalog)
3

>>> msg1 = catalog['green']
>>> msg1.string
>>> msg1.locations
[('main.py', 99)]

>>> msg2 = catalog['blue']
>>> msg2.string
u'blau'
>>> msg2.locations
[('main.py', 100)]

>>> msg3 = catalog['salad']
>>> msg3.string
(u'Salat', u'Salate')
>>> msg3.locations
[('util.py', 42)]

Messages that are in the catalog but not in the template are removed
from the main collection, but can still be accessed via the `obsolete`
member:

>>> 'head' in catalog
False
>>> list(catalog.obsolete.values())
[<Message 'head' (flags: [])>]

:param template: the reference catalog, usually read from a POT file
:param no_fuzzy_matching: whether to use fuzzy matching of message IDs
:param update_header_comment: whether to copy the header comment from the template
:param keep_user_comments: whether to keep user comments from the old catalog
:param update_creation_date: whether to copy the creation date from the template
c               (    V ^8  d   QhRRRRRRRR/# )r-   r|  r   oldkeytuple[str, str] | strnewkeyr0   re   r2   )r3   s   "r*   r4   $Catalog.update.<locals>.__annotate__|  s+     #	' #	'G #	'-B #	'La #	'fj #	'r5   c                  < V P                  4       p R pW8w  dy   RpSP                  V4       SP                  V4      pVf   Q h\        VP                  \
        4      '       d   VP                  .V n        M3\        VP                  4      V n        MSP                  VR4      pVf   Q hVP                  V n	        S'       d$   \        \        VP                  4      4      V n        \        V P                  \        \        34      '       d   \        V P                  \        \        34      '       gH   Rp\        V P                  .R.\        V P                  4      ^,
          ,          ,           4      V n	        M\        V P                  4      S	P                  8w  d3   Rp\        V P                  R\        VP                  4       4      V n	        M@\        V P                  \        \        34      '       d   RpV P                  ^ ,          V n	        V ;P                  VP                  ,          un        V'       d   V ;P                  R0,          un        V S	V P                  &   R# )FTNrh   r   )r   rm   rF  rp   rX   r/   r`   rj   popr.   r   r_   r   rd  rP  r\   )
r|  r  r  r   oldmsgfuzzy_matchesr  messages	remainingrq   s
   &&&  r*   _mergeCatalog.update.<locals>._merge|  s   mmoGE!!&)!f-)))fii--+199+G'*.vyy/G'"vt4)))#]]GN!(,Xf6J6J-K(L%'**tUm44!'..4-@@ E%* (RDC

Oa4G,HI&GN (D,<,<< E%*7>>:M3v}};M+N%OGNGNNT5M::!(!2MMV\\)M'*&Dr5   N)r  r   r.   r^  rc   _to_fuzzy_match_keyrk   rX   r+   keysr  r   r   )rq   r  r  r  r  r  fuzzy_candidatesmsgidrk  ctxtr  r|  matchesmodified_keyr  newctxtr  r  r  s   f&&&f&          @@@r*   updateCatalog.update/  s   ~ >>MMO	  !5Xe_333--.C#E?22DGJk$T%=%=c%BC	 "
 #	' #	'J  GzzzmmGJJ@(?7-,"3 44S9,113#
 #+21:L.>.LOF&2)/"7C8$'.D$+  . E E$>'0'7e$  ! #+"9"9D  !)!7!7D  r5   c                    V ^8  d   QhRRRR/# )r-   rk  r  r0   r/   r2   )r3   s   "r*   r4   r     s     ( ('< ( (r5   c                    \        V\        4      '       d   V^ ,          pMTpVP                  4       P                  4       # )z?Converts a message key to a string suitable for fuzzy matching.)rp   r   rC  strip)rq   rk  matchkeys   && r*   r  Catalog._to_fuzzy_match_key  s3    c5!!1vHH~~%%''r5   c               $    V ^8  d   QhRRRRRR/# )r-   rX   r   rc   rd   r0   r  r2   )r3   s   "r*   r4   r     s"     
 
: 

 
F[ 
r5   c                b    Tp\        V\        \        34      '       d
   V^ ,          pVe   W23pV# )zThe key for a message is just the singular ID even for pluralizable
messages, but is a ``(msgid, msgctxt)`` tuple for context-specific
messages.
)rp   rj   r   r  s   &&& r*   r^  Catalog._key_for  s5    
 cD%=))Q%C.C
r5   c                    V ^8  d   QhRRRR/# )r-   r   r   r0   r1   r2   )r3   s   "r*   r4   r     s     C C' Cd Cr5   c                   \        V\        4      '       g   Q hV P                  P                  4       VP                  P                  4       ,           FG  pV P	                  V4      pVP	                  V4      pVe   Ve   VP                  V4      '       d   KF   R# 	  \        V P                  4      \        VP                  4      8H  # )zLChecks if catalogs are identical, taking into account messages and
headers.
F)rp   r   r  r  rF  r   r   ri  )rq   r   rk  	message_1	message_2s   &&   r*   r   Catalog.is_identical  s     %))))>>&&(5??+?+?+AAACI		#I!$ --i88 B D%%&$u/A/A*BBBr5   )r  r  r  r  r	  r
  r   r   r   r   r   r   r   r   r   ri  r   r  r   r   r   )Nr2   r2   r2   r2   r2   NNr   )FFTT)&rz   r   r   r   r   DEFAULT_HEADERrr   r  r  r  r   r   r"  r&  r*  r   r8  rJ  ri  rP  rU  r6  r`  re  rl  r|   ru  ry  r  rm   r   rF  rt  r  r  r^  r   r   r2   r5   r*   r   r   K  s<   . '+!%3""'+)-8<PT&*$("D!Lk*' k;/F !78& 13F M 	NB<"GH -/@ 2G 2	Lh ! !  ! !$ 	J 	J3#&B.*`)V&>$U8n(
C Cr5   )r  r   r   r   r   )   g333333?)r  strict)8__conditional_annotations__r   
__future__r   r@   rF   collections.abcr   r   r   difflibr   emailr   heapqr   r.   r	   typingr
   babelr   r  
babel.corer   r   babel.datesr   babel.messages.pluralsr   
babel.utilr   r   r   r   typing_extensionsr   r/   r   rj   r   __annotations____all__r+   compileVERBOSEr   r<   rU   r   	Exceptionr   r  r   r   r   )r  s   @r*   <module>r     s    #  	 .  # %     ( 1 ' - C C+%S/1DI=J	=&4 

 	 ZZ	&<j? j?Z%y %
 ]
C ]
Cr5   