Ë
    ÆªbôU  ã                   óÐ   — d Z ddlZddlZddlmZmZ ddlmZmZ d„ Z	d„ Z
 G d„ de«      Z G d	„ d
«      Z G d„ d«      Zdd„Z ej                   d«      Zd„ Zdd„Z	 	 	 dd„Zd„ Zy)zî
    babel.messages.pofile
    ~~~~~~~~~~~~~~~~~~~~~

    Reading and writing of files in the ``gettext`` PO (portable object)
    format.

    :copyright: (c) 2013-2022 by the Babel Team.
    :license: BSD, see LICENSE for more details.
é    N)ÚCatalogÚMessage)ÚwraptextÚ_cmpc                 óX   — d„ }t        j                  d«      j                  || dd «      S )z¿Reverse `escape` the given string.

    >>> print(unescape('"Say:\\n  \\"hello, world!\\"\\n"'))
    Say:
      "hello, world!"
    <BLANKLINE>

    :param string: the string to unescape
    c                 óL   — | j                  d«      }|dk(  ry|dk(  ry|dk(  ry|S )Né   Únú
Útú	Úrú)Úgroup)ÚmatchÚms     ú7/usr/lib/python3/dist-packages/babel/messages/pofile.pyÚreplace_escapesz!unescape.<locals>.replace_escapes   s2   € Ø�K‰K˜‹NˆØ�Š8ØØ�#ŠXØØ�#ŠXØàˆó    z\\([\\trn"])r	   éÿÿÿÿ)ÚreÚcompileÚsub)Ústringr   s     r   Úunescaper      s+   € ò	ô �:‰:�oÓ&×*Ñ*¨?¸FÀ1ÀR¸LÓIÐIr   c                 ó®   — d| v rG| j                  «       }| j                  d«      r|dd }t        t        |«      }dj	                  |«      S t        | «      S )aì  Reverse the normalization done by the `normalize` function.

    >>> print(denormalize(r'''""
    ... "Say:\n"
    ... "  \"hello, world!\"\n"'''))
    Say:
      "hello, world!"
    <BLANKLINE>

    >>> print(denormalize(r'''""
    ... "Say:\n"
    ... "  \"Lorem ipsum dolor sit "
    ... "amet, consectetur adipisicing"
    ... " elit, \"\n"'''))
    Say:
      "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
    <BLANKLINE>

    :param string: the string to denormalize
    r   ú""r	   NÚ )Ú
splitlinesÚ
startswithÚmapr   Újoin)r   Úescaped_linesÚliness      r   Údenormalizer%   *   sX   € ð* ˆv�~Ø×)Ñ)Ó+ˆØ×Ñ˜TÔ"Ø)¨!¨"Ð-ˆMÜ”H˜mÓ,ˆØ�w‰w�u‹~Ðä˜ÓÐr   c                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )ÚPoFileErrorzDException thrown by PoParser when an invalid po file is encountered.c                 óX   •— t         ‰| �  |› d|› �«       || _        || _        || _        y )Nz on )ÚsuperÚ__init__ÚcatalogÚlineÚlineno)ÚselfÚmessager+   r,   r-   Ú	__class__s        €r   r*   zPoFileError.__init__K   s0   ø€ Ü‰Ñ˜G˜9 D¨¨Ð1Ô2ØˆŒØˆŒ	Øˆ�r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r*   Ú__classcell__)r0   s   @r   r'   r'   I   s   ø„ ÙN÷ð r   r'   c                   óX   — e Zd Zd„ Zd„ Zd„ Zd„ ZeZd„ Zd„ Z	d„ Z
d„ Zd	„ Zd
„ Zd„ Zd„ Zy)Ú_NormalizedStringc                 óB   — g | _         |D ]  }| j                  |«       Œ y ©N)Ú_strsÚappend)r.   ÚargsÚargs      r   r*   z_NormalizedString.__init__T   s$   € ØˆŒ
Øò 	ˆCØ�K‰K˜Õñ	r   c                 óV   — | j                   j                  |j                  «       «       y r9   )r:   r;   Ústrip)r.   Úss     r   r;   z_NormalizedString.appendY   s   € Ø�
‰
×Ñ˜!Ÿ'™'›)Õ$r   c                 óT   — dj                  t        t        | j                  «      «      S )Nr   )r"   r!   r   r:   ©r.   s    r   r%   z_NormalizedString.denormalize\   s   € Ø�w‰w”sœ8 T§Z¡ZÓ0Ó1Ð1r   c                 ó,   — t        | j                  «      S r9   )Úboolr:   rB   s    r   Ú__nonzero__z_NormalizedString.__nonzero___   s   € Ü�D—J‘JÓÐr   c                 óT   — t         j                  j                  | j                  «      S r9   )ÚosÚlinesepr"   r:   rB   s    r   Ú__repr__z_NormalizedString.__repr__d   s   € Ü�z‰z�‰˜tŸz™zÓ*Ð*r   c                 óD   — |syt        t        | «      t        |«      «      S )Nr	   )r   Ústr©r.   Úothers     r   Ú__cmp__z_NormalizedString.__cmp__g   s   € ÙØä”C˜“Iœs 5›zÓ*Ð*r   c                 ó*   — | j                  |«      dkD  S ©Nr   ©rN   rL   s     r   Ú__gt__z_NormalizedString.__gt__m   ó   € Ø�|‰|˜EÓ" QÑ&Ð&r   c                 ó*   — | j                  |«      dk  S rP   rQ   rL   s     r   Ú__lt__z_NormalizedString.__lt__p   rS   r   c                 ó*   — | j                  |«      dk\  S rP   rQ   rL   s     r   Ú__ge__z_NormalizedString.__ge__s   ó   € Ø�|‰|˜EÓ" aÑ'Ð'r   c                 ó*   — | j                  |«      dk  S rP   rQ   rL   s     r   Ú__le__z_NormalizedString.__le__v   rX   r   c                 ó*   — | j                  |«      dk(  S rP   rQ   rL   s     r   Ú__eq__z_NormalizedString.__eq__y   rX   r   c                 ó*   — | j                  |«      dk7  S rP   rQ   rL   s     r   Ú__ne__z_NormalizedString.__ne__|   rX   r   N)r1   r2   r3   r*   r;   r%   rE   Ú__bool__rI   rN   rR   rU   rW   rZ   r\   r^   © r   r   r7   r7   R   sE   „ òò
%ò2ò ð €Hò+ò+ò'ò'ò(ò(ò(ó(r   r7   c                   óZ   — e Zd ZdZg d¢Zdd„Zd„ Zd„ Zd„ Zdd„Z	dd„Z
d	„ Zd
„ Zd„ Zd„ Zy)ÚPoFileParserz–Support class to  read messages from a ``gettext`` PO (portable object) file
    and add them to a `Catalog`

    See `read_po` for simple cases.
    )ÚmsgidÚmsgstrÚmsgctxtÚmsgid_pluralc                 ój   — || _         || _        d| _        d| _        || _        | j                  «        y rP   )r+   Úignore_obsoleteÚcounterÚoffsetÚabort_invalidÚ_reset_message_state)r.   r+   rh   rk   s       r   r*   zPoFileParser.__init__�   s3   € ØˆŒØ.ˆÔØˆŒØˆŒØ*ˆÔØ×!Ñ!Õ#r   c                 óž   — g | _         g | _        g | _        g | _        g | _        g | _        d | _        d| _        d| _        d| _	        d| _
        y )NF)ÚmessagesÚtranslationsÚ	locationsÚflagsÚuser_commentsÚauto_commentsÚcontextÚobsoleteÚin_msgidÚ	in_msgstrÚ
in_msgctxtrB   s    r   rl   z!PoFileParser._reset_message_state—   sR   € ØˆŒØˆÔØˆŒØˆŒ
ØˆÔØˆÔØˆŒØˆŒØˆŒØˆŒØˆ�r   c           
      óP  — | j                   j                  «        t        | j                  «      dkD  rt	        d„ | j                  D «       «      }n| j                  d   j                  «       }t        |t        t        f«      r–t        | j                  j                  «      D �cg c]  }d‘Œ }}| j                   D ]O  \  }}|| j                  j                  k\  r| j                  d| j                  d«       Œ=|j                  «       ||<   ŒQ t	        |«      }n | j                   d   d   j                  «       }| j                  r| j                  j                  «       }nd}t        ||t        | j                  «      t!        | j"                  «      | j$                  | j&                  | j                  dz   |¬«      }| j(                  r&| j*                  s)|| j                  j(                  |<   n|| j                  |<   | xj,                  dz  c_        | j/                  «        yc c}w )z�
        Add a message to the catalog based on the current parser state and
        clear the state ready to process the next message.
        r	   c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wr9   )r%   )Ú.0r   s     r   ú	<genexpr>z,PoFileParser._add_message.<locals>.<genexpr>«   s   è ø€ ÒA¨a˜!Ÿ-™-Ÿ/ÑAùs   ‚r   r   z5msg has more translations than num_plurals of catalogN)r-   rt   )ro   ÚsortÚlenrn   Útupler%   Ú
isinstanceÚlistÚranger+   Únum_pluralsÚ_invalid_pofilerj   rt   r   rp   Úsetrq   rs   rr   ru   rh   ri   rl   )r.   rc   Ú_r   ÚidxÚtranslationre   r/   s           r   Ú_add_messagezPoFileParser._add_message¤   s·  € ð
 	×Ñ×ÑÔ Üˆt�}‰}Ó Ò!ÜÑA°4·=±=ÔAÓA‰Eà—M‘M !Ñ$×0Ñ0Ó2ˆEÜ�eœd¤E˜]Ô+Ü"'¨¯©×(@Ñ(@Ó"AÖB˜Q’bÐBˆFÐBØ$(×$5Ñ$5ò 8Ñ ��[Ø˜$Ÿ,™,×2Ñ2Ò2Ø×(Ñ(¨¨d¯k©kÐ;rÔsØØ)×5Ñ5Ó7��s’ð	8ô
 ˜6“]‰Fà×&Ñ& qÑ)¨!Ñ,×8Ñ8Ó:ˆFØ�<Š<Ø—l‘l×.Ñ.Ó0‰GàˆGÜ˜% ¬¨d¯n©nÓ)=¼sÀ4Ç:Á:»Ø×,Ñ,¨d×.@Ñ.@ÈÏÉÐWXÉØ")ô+ˆð �=Š=Ø×'Ò'Ø/6�—‘×%Ñ% eÒ,à")ˆD�L‰L˜ÑØ�Š˜Ñ�Ø×!Ñ!Õ#ùò- Cs   Â$	H#c                 ó>   — | j                   r| j                  «        y y r9   )rn   r‰   rB   s    r   Ú_finish_current_messagez$PoFileParser._finish_current_messageÇ   s   € Ø�=Š=Ø×ÑÕð r   c                 ór   — |j                  d«      r| j                  ||«       y | j                  |||«       y )Nú")r    Ú!_process_string_continuation_lineÚ_process_keyword_line)r.   r-   r,   ru   s       r   Ú_process_message_linez"PoFileParser._process_message_lineË   s0   € Ø�?‰?˜3ÔØ×2Ñ2°4¸Õ@à×&Ñ& v¨t°XÕ>r   c                 ó  — | j                   D ]4  }	 |j                  |«      r |t        |«         dv r|t        |«      d  } nŒ6 | j	                  ||d«       y |dv r| j                  «        || _        |dk(  r|| _        |dv r3d| _        d| _	        | j                  j                  t        |«      «       y |d	k(  rŽd| _	        d| _        |j                  d
«      rH|dd  j                  dd«      \  }}| j                  j                  t!        |«      t        |«      g«       y | j                  j                  dt        |«      g«       y |dk(  rd| _        t        |«      | _        y y # t        $ r | j	                  ||d«       Y �Œyw xY w)N)ú ú[z$Keyword must be followed by a stringz0Start of line didn't match any expected keyword.)rc   re   rc   )rc   rf   FTrd   r“   r	   ú]r   re   )Ú	_keywordsr    r~   Ú
IndexErrorr„   r‹   ru   rj   rx   rv   rn   r;   r7   rw   Úsplitro   Úintrt   )r.   r-   r,   ru   Úkeywordr=   r‡   Úmsgs           r   r�   z"PoFileParser._process_keyword_lineÑ   sƒ  € à—~‘~ò 		ˆGð[Ø—?‘? 7Ô+°´S¸³\Ñ0BÀjÑ0PØœs 7›|˜}Ð-�CÙøð			ð × Ñ   vÐ/aÔbØàÐ*Ñ*Ø×(Ñ(Ô*à ˆŒð �gÒØ ˆDŒKàÐ/Ñ/Ø#ˆDŒOØ ˆDŒMØ�M‰M× Ñ Ô!2°3Ó!7Õ8à˜Ò Ø!ˆDŒMØ!ˆDŒNØ�~‰~˜cÔ"Ø˜q˜r˜7Ÿ=™=¨¨aÓ0‘��SØ×!Ñ!×(Ñ(¬#¨c«(Ô4EÀcÓ4JÐ)KÕLà×!Ñ!×(Ñ(¨!Ô->¸sÓ-CÐ)DÕEà˜	Ò!Ø"ˆDŒOÜ,¨SÓ1ˆD�Lð "øô= ò [Ø×$Ñ$ T¨6Ð3Y×Zð[ús   ‘/E'Å'FÆFc                 óö   — | j                   r| j                  d   }nL| j                  r| j                  d   d   }n-| j                  r| j
                  }n| j                  ||d«       y |j                  |«       y )Nr   r	   z<Got line starting with " but not in msgid, msgstr or msgctxt)rv   rn   rw   ro   rx   rt   r„   r;   )r.   r,   r-   r@   s       r   rŽ   z.PoFileParser._process_string_continuation_lineú   sd   € Ø�=Š=Ø—‘˜bÑ!‰AØ�^Š^Ø×!Ñ! "Ñ% aÑ(‰AØ�_Š_Ø—‘‰Aà× Ñ   vÐ/nÔoØØ	�‰��r   c                 ó4  — | j                  «        |dd  j                  d«      r�|dd  j                  «       j                  «       D ]h  }|j	                  d«      }|dk\  r3	 t        ||dz   d  «      }| j                  j                  |d | |f«       ŒL| j                  j                  |d f«       Œj y |dd  j                  d«      rQ|dd  j                  «       j                  d«      D ]+  }| j                  j                  |j                  «       «       Œ- y |dd  j                  d«      r2|dd  j                  «       }|r| j                  j                  |«       y y | j                  j                  |dd  j                  «       «       y # t        $ r Y �ŒPw xY w)Nr	   ú:é   r   ú,ú.)r‹   r    Úlstripr—   Úrfindr˜   Ú
ValueErrorrp   r;   rq   r?   rs   rr   )r.   r,   ÚlocationÚposr-   ÚflagÚcomments          r   Ú_process_commentzPoFileParser._process_comment  sz  € à×$Ñ$Ô&à��ˆ8×Ñ˜sÔ#Ø   ˜HŸO™OÓ-×3Ñ3Ó5ò 	<�Ø—n‘n SÓ)�Ø˜!’8ð!Ü!$ X¨c°A©g¨hÐ%7Ó!8˜ð —N‘N×)Ñ)¨8°D°S¨>¸6Ð*BÕCà—N‘N×)Ñ)¨8°TÐ*:Õ;ñ	<ð �!�"ˆX× Ñ  Ô%Ø˜Q˜R˜Ÿ™Ó)×/Ñ/°Ó4ò 0�Ø—
‘
×!Ñ! $§*¡*£,Õ/ñ0à�!�"ˆX× Ñ  Ô%à˜1˜2�h—n‘nÓ&ˆGÙØ×"Ñ"×)Ñ)¨'Õ2ð ð ×Ñ×%Ñ% d¨1¨2 h§n¡nÓ&6Õ7øô &ò !Ú ð!ús   Á F
Æ
	FÆFc                 óÐ  — t        |«      D ]¼  \  }}|j                  «       }t        |t        «      s%|j	                  | j
                  j                  «      }|sŒN|j                  d«      rL|dd j                  d«      r&| j                  ||dd j                  «       d¬«       Œ™| j                  |«       Œ«| j                  ||«       Œ¾ | j                  «        | j                  s€| j                  s| j                  s| j                  r[| j                   j#                  t%        d«      «       | j&                  j#                  d	t%        d«      g«       | j)                  «        yyy)
z˜
        Reads from the file-like object `fileobj` and adds any po file
        units found in it to the `Catalog` supplied to the constructor.
        ú#r	   Nú~rž   T)ru   r   r   )Ú	enumerater?   r€   rK   Údecoder+   Úcharsetr    r�   r¡   r¨   r‹   ri   rq   rr   rs   rn   r;   r7   ro   r‰   )r.   Úfileobjr-   r,   s       r   ÚparsezPoFileParser.parse!  s)  € ô & gÓ.ò 	9‰LˆF�DØ—:‘:“<ˆDÜ˜d¤CÔ(Ø—{‘{ 4§<¡<×#7Ñ#7Ó8�ÙØØ�‰˜sÔ#Ø˜˜�8×&Ñ& sÔ+Ø×.Ñ.¨v°t¸A¸B°x·±Ó7HÐSWÐ.ÕXà×)Ñ)¨$Õ/à×*Ñ*¨6°4Õ8ð	9ð 	×$Ñ$Ô&ð �|Š| §¢¨t×/AÒ/AÀT×EWÒEWØ�M‰M× Ñ Ô!2°5Ó!9Ô:Ø×Ñ×$Ñ$ aÔ):¸5Ó)AÐ%BÔCØ×ÑÕð FXˆ|r   c                 óÖ   — t        |t        «      sJ ‚| j                  rt        || j                  ||«      ‚t        d|«       t        dj                  |dz   t        |«      «      «       y )NzWARNING:z!WARNING: Problem on line {0}: {1}r	   )r€   rK   rk   r'   r+   ÚprintÚformatÚrepr)r.   r,   r-   rš   s       r   r„   zPoFileParser._invalid_pofile>  sZ   € Ü˜$¤Ô$Ð$Ð$Ø×ÒÜ˜c 4§<¡<°°vÓ>Ð>Üˆj˜#Ôô 	Ð2×9Ñ9¸&À1¹*ÄdÈ4ÃjÓQÕRr   N)FF)F)r1   r2   r3   r4   r•   r*   rl   r‰   r‹   r�   r�   rŽ   r¨   r°   r„   r`   r   r   rb   rb   �   sC   „ ñò€Ió$ò ò!$òF ó?ó'2òR
ò8ò6 ó:Sr   rb   c                 ó`   — t        |||¬«      }t        |||¬«      }|j                  | «       |S )a„  Read messages from a ``gettext`` PO (portable object) file from the given
    file-like object and return a `Catalog`.

    >>> from datetime import datetime
    >>> from io import StringIO
    >>> buf = StringIO('''
    ... #: main.py:1
    ... #, fuzzy, python-format
    ... msgid "foo %(name)s"
    ... msgstr "quux %(name)s"
    ...
    ... # A user comment
    ... #. An auto comment
    ... #: main.py:3
    ... msgid "bar"
    ... msgid_plural "baz"
    ... msgstr[0] "bar"
    ... msgstr[1] "baaz"
    ... ''')
    >>> catalog = read_po(buf)
    >>> catalog.revision_date = datetime(2007, 4, 1)

    >>> for message in catalog:
    ...     if message.id:
    ...         print((message.id, message.string))
    ...         print(' ', (message.locations, sorted(list(message.flags))))
    ...         print(' ', (message.user_comments, message.auto_comments))
    (u'foo %(name)s', u'quux %(name)s')
      ([(u'main.py', 1)], [u'fuzzy', u'python-format'])
      ([], [])
    ((u'bar', u'baz'), (u'bar', u'baaz'))
      ([(u'main.py', 3)], [])
      ([u'A user comment'], [u'An auto comment'])

    .. versionadded:: 1.0
       Added support for explicit charset argument.

    :param fileobj: the file-like object to read the PO file from
    :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 ignore_obsolete: whether to ignore obsolete messages in the input
    :param charset: the character set of the catalog.
    :param abort_invalid: abort read if po file is invalid
    )ÚlocaleÚdomainr®   )rk   )r   rb   r°   )r¯   r¶   r·   rh   r®   rk   r+   Úparsers           r   Úread_por¹   I  s2   € ô^ ˜V¨F¸GÔD€GÜ˜' ?À-ÔP€FØ
‡L�L�ÔØ€Nr   zL(\s+|[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))c                 ó¬   — d| j                  dd«      j                  dd«      j                  dd«      j                  dd	«      j                  d
d«      z  S )zõEscape the given string so that it can be included in double-quoted
    strings in ``PO`` files.

    >>> escape('''Say:
    ...   "hello, world!"
    ... ''')
    '"Say:\\n  \\"hello, world!\\"\\n"'

    :param string: the string to escape
    z"%s"ú\z\\r   z\tr   z\rr   z\nr�   z\")Úreplace)r   s    r   Úescaper½   …  sN   € ð �F—N‘N 4¨Ó0ß"™7 4¨Ó/ß"™7 4¨Ó/ß"™7 4¨Ó/ß"™7 4¨Ó/ñ	0ð 0r   c           
      ó  — |�r|dkD  �rt        |«      }g }| j                  d«      D ]î  }t        t        |«      «      |z   |kD  rÁt        j	                  |«      }|j                  «        |sŒEg }d}|rot        t        |d   «      «      dz
  |z   }	||	z   |k  r%|j                  |j                  «       «       ||	z  }n"|s|j                  |j                  «       «       n|rŒo|j                  dj                  |«      «       |rŒ˜ŒÞ|j                  |«       Œð n| j                  d«      }t        |«      dk  rt        | «      S |r|d   s|d= |dxx   dz  cc<   ddj                  |D �cg c]  }|t        |«      z   ‘Œ c}«      z   S c c}w )	a©  Convert a string into a format that is appropriate for .po files.

    >>> print(normalize('''Say:
    ...   "hello, world!"
    ... ''', width=None))
    ""
    "Say:\n"
    "  \"hello, world!\"\n"

    >>> print(normalize('''Say:
    ...   "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
    ... ''', width=32))
    ""
    "Say:\n"
    "  \"Lorem ipsum dolor sit "
    "amet, consectetur adipisicing"
    " elit, \"\n"

    :param string: the string to normalize
    :param prefix: a string that should be prepended to every line
    :param width: the maximum line width; use `None`, 0, or a negative number
                  to completely disable line wrapping
    r   Trž   r   r   r	   r   z""
)	r~   r   r½   ÚWORD_SEPr—   Úreverser;   Úpopr"   )
r   ÚprefixÚwidthÚ	prefixlenr$   r,   ÚchunksÚbufÚsizeÚls
             r   Ú	normalizerÉ   —  sq  € ò0 �˜“Ü˜“Kˆ	ØˆØ×%Ñ% dÓ+ò 	#ˆDÜ”6˜$“<Ó  9Ñ,¨uÒ4Ü!Ÿ™¨Ó-�Ø—‘Ô ÚØ�CØ�DÙ Ü¤ v¨b¡zÓ 2Ó3°aÑ7¸)ÑC˜Ø !™8 eÒ+ØŸJ™J v§z¡z£|Ô4Ø  A™I™Dá#&ð !$§
¡
¨6¯:©:«<Ô 8Ø!ò !ð —L‘L §¡¨#£Ô/ó ð  —‘˜TÕ"ñ)	#ð, ×!Ñ! $Ó'ˆä
ˆ5ƒz�Q‚Ü�f‹~Ðñ �U˜2’YØ�"ˆIØˆb‹	�TÑ‹	Ø�U—Z‘ZÀUÖ K¸T &¬6°$«<Ó"7Ò KÓLÑLÐLùÒ Ks   Å+F	
c
           
      óJ  ‡ ‡‡‡‡— dˆfd„	Šˆˆ fd„Šdˆˆfd„	}
dˆˆˆfd„	}d}|rd}n|rd}t        ‰|¬	«      D �]ó  }|j                  sZ|rŒ‰j                  }‰r>‰d
kD  r9g }|j                  «       D ]  }|t	        |‰d¬«      z  }Œ dj                  |«      } ‰|dz   «       |j                  D ]
  } |
|«       Œ |j                  D ]  } |
|d¬«       Œ |s¡g }	 t        |j                  d„ ¬«      }|D ]h  \  }}|r(|	r&d|j                  t        j                  d«      |fz  }n#d|j                  t        j                  d«      z  }||vsŒX|j                  |«       Œj  |
dj                  |«      d¬«       |j                  r1 ‰ddj                  dgt        |j                  «      z   «      z  «       |j                   rZ|rX |
d ‰|j                   d
   «      z  d¬«       t#        |j                   «      dkD  r  |
d ‰|j                   d   «      z  d¬«        ||«        ‰d«       �Œö |sVt        ‰j$                  j'                  «       |¬	«      D ]-  }|j                  D ]
  } |
|«       Œ  ||d¬«        ‰d«       Œ/ yy# t        $ r |j                  }Y �Œ­w xY w)aÍ  Write a ``gettext`` PO (portable object) template file for a given
    message catalog to the provided file-like object.

    >>> catalog = Catalog()
    >>> catalog.add(u'foo %(name)s', locations=[('main.py', 1)],
    ...             flags=('fuzzy',))
    <Message...>
    >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)])
    <Message...>
    >>> from io import BytesIO
    >>> buf = BytesIO()
    >>> write_po(buf, catalog, omit_header=True)
    >>> print(buf.getvalue().decode("utf8"))
    #: main.py:1
    #, fuzzy, python-format
    msgid "foo %(name)s"
    msgstr ""
    <BLANKLINE>
    #: main.py:3
    msgid "bar"
    msgid_plural "baz"
    msgstr[0] ""
    msgstr[1] ""
    <BLANKLINE>
    <BLANKLINE>

    :param fileobj: the file-like object to write to
    :param catalog: the `Catalog` instance
    :param width: the maximum line width for the generated output; use `None`,
                  0, or a negative number to completely disable line wrapping
    :param no_location: do not emit a location comment for every message
    :param omit_header: do not include the ``msgid ""`` entry at the top of the
                        output
    :param sort_output: whether to sort the messages in the output by msgid
    :param sort_by_file: whether to sort the messages in the output by their
                         locations
    :param ignore_obsolete: whether to ignore obsolete messages and not include
                            them in the output; by default they are included as
                            comments
    :param include_previous: include the old msgid as a comment when
                             updating the catalog
    :param include_lineno: include line number in the location comment
    r   c                 ó    •— t        | |‰¬«      S )N)rÂ   rÃ   )rÉ   )ÚkeyrÂ   rÃ   s     €r   Ú
_normalizezwrite_po.<locals>._normalize  s   ø€ Ü˜ V°5Ô9Ð9r   c                 ó€   •— t        | t        «      r| j                  ‰j                  d«      } ‰j	                  | «       y )NÚbackslashreplace)r€   rK   Úencoder®   Úwrite)Útextr+   r¯   s    €€r   Ú_writezwrite_po.<locals>._write  s.   ø€ Ü�dœCÔ Ø—;‘;˜wŸ™Ð0BÓCˆDØ�‰�dÕr   c                 óz   •— ‰r‰dkD  r‰}nd}t        | |«      D ]  } ‰d|›d|j                  «       ›d�«       Œ! y )Nr   éL   rª   r’   r   )r   r?   )r§   rÂ   Ú_widthr,   rÓ   rÃ   s       €€r   Ú_write_commentz write_po.<locals>._write_comment
  sA   ø€ ñ �U˜Q’YØ‰FàˆFÜ˜W fÓ-ò 	8ˆDÚ¢¨¯©­Ð6Õ7ñ	8r   c           
      ó   •— t        | j                  t        t        f«      r¯| j                  r ‰|›d ‰| j                  |«      ›d�«        ‰|›d ‰| j                  d   |«      ›d�«        ‰|›d ‰| j                  d   |«      ›d�«       t        ‰j                  «      D ]'  }	 | j                  |   } ‰d|| ‰||«      fz  «       Œ) y | j                  r ‰|›d ‰| j                  |«      ›d�«        ‰|›d ‰| j                  |«      ›d�«        ‰|›d	 ‰| j                  xs d|«      ›d�«       y # t        $ r d}Y Œ“w xY w)
Nzmsgctxt r   zmsgid r   zmsgid_plural r	   r   z%smsgstr[%d] %s
zmsgstr )	r€   Úidr�   r   rt   r‚   rƒ   r   r–   )r/   rÂ   r‡   r   rÍ   rÓ   r+   s       €€€r   Ú_write_messagez write_po.<locals>._write_message  sD  ø€ Ü�g—j‘j¤4¬ -Ô0Ø�ŠÙª6Ù+5°g·o±oÀvÕ+NðPô Qá¢V©Z¸¿
¹
À1¹ÀvÕ-NÐOÔPÙÚ™
 7§:¡:¨a¡=°&Õ9ðô ô ˜W×0Ñ0Ó1ò �ð Ø$Ÿ^™^¨CÑ0�Fñ Ð*Ø˜C¡¨F°FÓ!;ð.ñ õ ñð �ŠÙª6Ù+5°g·o±oÀvÕ+NðPô Qá¢V©Z¸¿
¹
ÀFÕ-KÐLÔMÙÚ™
 7§>¡>Ò#7°R¸Õ@ðõ øô "ò  Ø’Fð ús   Â*D?Ä?EÅENr/   r¤   )Úsort_byr   z# )rÃ   Úsubsequent_indentr   r    )rÂ   c                 óH   — | d   t        | d   t        «      xr | d   xs dfS )Nr   r	   r   )r€   r˜   )Úxs    r   ú<lambda>zwrite_po.<locals>.<lambda>P  s,   € °!°A±$¼
À1ÀQÁ4ÌÓ8MÒ8VÐRSÐTUÑRVÒ8\ÐZ\Ð1]€ r   ©rÌ   z%s:%dú/z%sr’   r�   z#%s
z, zmsgid %sú|r	   zmsgid_plural %sz#~ )r   )Ú_sort_messagesrÙ   Úheader_commentr   r   r"   rr   rs   Úsortedrp   Ú	TypeErrorr¼   rG   Úsepr;   rq   Úprevious_idr~   ru   Úvalues)r¯   r+   rÃ   Úno_locationÚomit_headerÚsort_outputÚsort_by_filerh   Úinclude_previousÚinclude_linenor×   rÚ   rÛ   r/   Úcomment_headerr$   r,   r§   Úlocsrp   Úfilenamer-   r¤   rÍ   rÓ   s   ```                    @@r   Úwrite_poró   Ô  s¿  ü€ õ\:õö
8÷ð6 €GÙØ‰Ù	Øˆä! '°7Ô;ó 3ˆØ�zŠzÙØØ$×3Ñ3ˆNÙ˜ šØ�Ø*×5Ñ5Ó7ò >�DØœX d°%Ø8<ô>ñ >‘Eð>ð "'§¡¨EÓ!2�Ù�> EÑ)Ô*à×,Ñ,ò 	$ˆGÙ˜7Õ#ð	$à×,Ñ,ò 	0ˆGÙ˜7¨3Ö/ð	0ñ ØˆDð.Ü" 7×#4Ñ#4Ù']ô_�	ð
 %.ò *Ñ �˜&Ù™nØ'¨8×+;Ñ+;¼B¿F¹FÀCÓ+HÈ&Ð*QÑQ‘Hà$ x×'7Ñ'7¼¿¹ÀÓ'DÑD�HØ 4Ò'Ø—K‘K Õ)ð*ñ ˜3Ÿ8™8 D›>°#Õ6Ø�=Š=Ù�7˜TŸY™Y¨ t¬f°W·]±]Ó.CÑ'CÓDÑDÔEà×ÒÑ#3Ù˜:©
°7×3FÑ3FÀqÑ3IÓ(JÑJØ"%õ'ä�7×&Ñ&Ó'¨!Ò+ÙÐ0±:Ø×'Ñ'¨Ñ*ó4ñ  àõñ 	�wÔÙˆtŽðg3ñj Ü%Ø×Ñ×#Ñ#Ó%Øô
ò 	ˆGð #×0Ñ0ò (�Ù˜wÕ'ð(á˜7¨5Õ1Ù�4�Lñ	ð øô3 ò .Ø#×-Ñ-“	ð.ús   ÃJ	Ê	J"Ê!J"c                 óz   — t        | «      } |dk(  r| j                  «        | S |dk(  r| j                  d„ ¬«       | S )zø
    Sort the given message iterable by the given criteria.

    Always returns a list.

    :param messages: An iterable of Messages.
    :param sort_by: Sort by which criteria? Options are `message` and `location`.
    :return: list[Message]
    r/   r¤   c                 ó   — | j                   S r9   )rp   )r   s    r   rß   z _sort_messages.<locals>.<lambda>ƒ  s
   €  A§K¡K€ r   rà   )r�   r}   )rn   rÛ   s     r   rã   rã   u  sC   € ô �H‹~€HØ�)ÒØ�‰Œð €Oð 
�JÒ	Ø�‰Ñ/ˆÔ0Ø€Or   )NNFNF)r   rÕ   )rÕ   FFFFFFT)r4   rG   r   Úbabel.messages.catalogr   r   Ú
babel.utilr   r   r   r%   Ú	Exceptionr'   r7   rb   r¹   r   r¿   r½   rÉ   ró   rã   r`   r   r   ú<module>rù      s‹   ðñ	ó 
Û 	ç 3ß %òJò. ô>�)ô ÷+(ñ +(÷^ESñ ESóP2ðj ˆ2�:‰:ð ó €ò0ó$:Mðz INØDIØ48ó^óBr   