ó
    àÅŸgí{  ã                   ó¢  • S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	J
r
Jr  SSKJr  SSKJrJrJrJr  SrSr\R*                  " SS	5      r\R*                  " S
S5      r\" \" SSS5      \" SSS5      5      \" \" SSS5      \" SSS5      5      \" \" SSS5      \" SSS5      5      \" \" SSS 5      \" S!S"S#5      5      \" \" S$S%S&5      \" S'S(S)5      5      \" \" S*S+S,5      \" S-S.S/5      5      \" \" S0S1S25      \" S3S4S55      5      \" \" S6S7S85      \" S9S:S;5      5      4r\" S<S=S<S<S>9\" S?S@S?S?S>9\" SASBSASAS>9\" SCSDSESFS>9\" SGSSGSGS>94r\" S=SHSISJ/SK9\" SLSMSNSO/SK9\" S@SPSQSR/SK9\" SDSSST/ SUQSK9\" SVSWSX/ SYQSK9\" SZS[S\S]/SK9\" S^S_S`Sa/SK9\" SbScSdSe/SK9\" SfSgShSi/SK94	rSj rS£Sk jrSl rS¤Sm jrS¥Sn jr S¥So jr!Sp r"S¦Sq jr#S¥Sr jr$S§Ss jr%St r&Su r'Sv r(Sw r) " Sx Sy\*5      r+ " Sz S{\,5      r- " S| S}\,5      r. " S~ S\,5      r/ " S€ S�\,5      r0\" S¨0 S‚\1_SƒS„_S…S†_S‡Sˆ_S‰SŠ_S‹SŒ_S�SŽ_S�S�_S‘S’_S“S”_S•S–_S—S˜_S™Sš_S›Sœ_S�Sž_SŸS _S¡S¢_6  g)©z/The main module of the `humanfriendly` package.é    N)Ú	is_stringÚ	monotonic)Údefine_aliases)ÚconcatenateÚformatÚ	pluralizeÚtokenize)ÚCombinedUnitÚInvalidDateÚInvalidLengthÚInvalidSizeÚInvalidTimespanÚSizeUnitÚTimerÚ__version__Úcoerce_booleanÚcoerce_patternÚcoerce_secondsÚdisk_size_unitsÚformat_lengthÚformat_numberÚformat_pathÚformat_sizeÚformat_timespanÚlength_size_unitsÚ
parse_dateÚparse_lengthÚ
parse_pathÚ
parse_sizeÚparse_timespanÚround_numberÚ
time_unitsz10.0r   zdivider, symbol, namer
   zdecimal, binaryiè  ÚKBÚkilobytei   ÚKiBÚkibibytei@B ÚMBÚmegabytei   ÚMiBÚmebibytei Êš;ÚGBÚgigabytei   @ÚGiBÚgibibytel    J)£ÚTBÚterabytel        ÚTiBÚtebibytel     �Iú5 ÚPBÚpetabytel           ÚPiBÚpebibytel     ÈNÎZoÚEBÚexabytel            ÚEiBÚexbibytel     @=7M.cÚZBÚ	zettabytel            ÚZiBÚzebibytel      B¶3v^!< ÚYBÚ	yottabytel               ÚYiBÚyobibyteÚnmg•Ö&è.>)ÚprefixÚdividerÚsingularÚpluralÚmmgü©ñÒMbP?Úcmg{®Gáz„?Úmé   ÚmetreÚmetresÚkmÚ
nanosecondÚnanosecondsÚns)rE   rF   rG   Úabbreviationsg�íµ ÷Æ°>ÚmicrosecondÚmicrosecondsÚusÚmillisecondÚmillisecondsÚmsÚsecondÚseconds)ÚsÚsecÚsecsé<   ÚminuteÚminutes)rJ   ÚminÚminsi  ÚhourÚhoursÚhi€Q ÚdayÚdaysÚdi€:	 ÚweekÚweeksÚwi âßÚyearÚyearsÚyc                 ó¼   • [        U 5      (       aB  U R                  5       R                  5       nUS;   a  gUS;   a  gSn[        [	        X 5      5      e[        U 5      $ )a  
Coerce any value to a boolean.

:param value: Any Python value. If the value is a string:

              - The strings '1', 'yes', 'true' and 'on' are coerced to :data:`True`.
              - The strings '0', 'no', 'false' and 'off' are coerced to :data:`False`.
              - Other strings raise an exception.

              Other Python values are coerced using :class:`bool`.
:returns: A proper boolean value.
:raises: :exc:`exceptions.ValueError` when the value is a string but
         cannot be coerced with certainty.
)Ú1ÚyesÚtrueÚonT)Ú0ÚnoÚfalseÚoffÚ Fz(Failed to coerce string to boolean! (%r))r   ÚstripÚlowerÚ
ValueErrorr   Úbool)ÚvalueÚ
normalizedÚmsgs      ÚW/var/www/blue/EV-Temp_rev04/venv/lib/python3.13/site-packages/humanfriendly/__init__.pyr   r   [   sZ   € ô �×ÑØ—[‘[“]×(Ñ(Ó*ˆ
ØÐ3Ó3ØØÐ:Ó:Øà<ˆCÜœV CÓ/Ó0Ð0ä�E‹{Ðó    c                 óä   • [        U 5      (       a  [        R                  " X5      n U $ [        R                  " S5      n[        U5      n[	        X5      (       d  Sn[        [        X@5      5      eU $ )a†  
Coerce strings to compiled regular expressions.

:param value: A string containing a regular expression pattern
              or a compiled regular expression.
:param flags: The flags used to compile the pattern (an integer).
:returns: A compiled regular expression.
:raises: :exc:`~exceptions.ValueError` when `value` isn't a string
         and also isn't a compiled regular expression.
rx   z;Failed to coerce value to compiled regular expression! (%r))r   ÚreÚcompileÚtypeÚ
isinstancer{   r   )r}   ÚflagsÚempty_patternÚpattern_typer   s        r€   r   r   w   sb   € ô �×ÑÜ—
’
˜5Ó(ˆð €Lô Ÿ
š
 2›ˆÜ˜MÓ*ˆÜ˜%×.Ñ.ØOˆCÜœV CÓ/Ó0Ð0Ø€Lr�   c                 óÎ   • [        U [        R                  5      (       a  U R                  5       $ [        U [        R
                  5      (       d  Sn[        [        X5      5      eU $ )a9  
Coerce a value to the number of seconds.

:param value: An :class:`int`, :class:`float` or
              :class:`datetime.timedelta` object.
:returns: An :class:`int` or :class:`float` value.

When `value` is a :class:`datetime.timedelta` object the
:meth:`~datetime.timedelta.total_seconds()` method is called.
z1Failed to coerce value to number of seconds! (%r))r†   ÚdatetimeÚ	timedeltaÚtotal_secondsÚnumbersÚNumberr{   r   )r}   r   s     r€   r   r   �   sQ   € ô �%œ×+Ñ+×,Ñ,Ø×"Ñ"Ó$Ð$Ü�eœWŸ^™^×,Ñ,ØAˆÜœ Ó+Ó,Ð,Ø€Lr�   c                 óL  • [        [        5       GH  nXR                  R                  :¼  ag  U(       a`  [	        [        U 5      UR                  R                  -  US9n[        XCR                  R                  UR                  R                  5      s  $ XR                  R                  :¼  d  MŸ  U(       a  M¨  [	        [        U 5      UR                  R                  -  US9n[        XCR                  R                  UR                  R                  5      s  $    [        U S5      $ )a.  
Format a byte count as a human readable file size.

:param num_bytes: The size to format in bytes (an integer).
:param keep_width: :data:`True` if trailing zeros should not be stripped,
                   :data:`False` if they can be stripped.
:param binary: :data:`True` to use binary multiples of bytes (base-2),
               :data:`False` to use decimal multiples of bytes (base-10).
:returns: The corresponding human readable file size (a string).

This function knows how to format sizes in bytes, kilobytes, megabytes,
gigabytes, terabytes and petabytes. Some examples:

>>> from humanfriendly import format_size
>>> format_size(0)
'0 bytes'
>>> format_size(1)
'1 byte'
>>> format_size(5)
'5 bytes'
> format_size(1000)
'1 KB'
> format_size(1024, binary=True)
'1 KiB'
>>> format_size(1000 ** 3 * 4)
'4 GB'
©Ú
keep_widthÚbyte)	Úreversedr   ÚbinaryrE   r!   Úfloatr   ÚsymbolÚdecimal)Ú	num_bytesr’   r•   ÚunitÚnumbers        r€   r   r       sÌ   € ô8 œ×)ˆØŸ™×+Ñ+Ó+¶Ü!¤%¨	Ó"2°T·[±[×5HÑ5HÑ"HÐU_Ñ`ˆFÜ˜V§[¡[×%7Ñ%7¸¿¹×9KÑ9KÓLÒLØŸ,™,×.Ñ.Õ.·v°vÜ!¤%¨	Ó"2°T·\±\×5IÑ5IÑ"IÐV`ÑaˆFÜ˜V§\¡\×%8Ñ%8¸$¿,¹,×:MÑ:MÓNÒNñ *ô �Y Ó'Ð'r�   c                 ó6  • [        U 5      nU(       Gað  [        US   [        R                  5      (       GaÍ  [	        U5      S:X  a&  [        US   5      (       a  US   R                  5       OSn[	        U5      S:X  d  UR                  S5      (       a  [        US   5      $ U(       Ga[  UR                  S5      n[         GH?  nX4R                  R                  R                  5       UR                  R                  R                  5       4;   a'  [        US   UR                  R                  -  5      s  $ X4R                  R                  R                  5       UR                  R                  R                  5       4;   d=  UR                  UR                  R                  S   R                  5       5      (       d  Mþ  [        US   U(       a  UR                  R                  OUR                  R                  -  5      s  $    Sn[!        [#        XPU5      5      e)a†  
Parse a human readable data size and return the number of bytes.

:param size: The human readable file size to parse (a string).
:param binary: :data:`True` to use binary multiples of bytes (base-2) for
               ambiguous unit symbols and names, :data:`False` to use
               decimal multiples of bytes (base-10).
:returns: The corresponding size in bytes (an integer).
:raises: :exc:`InvalidSize` when the input can't be parsed.

This function knows how to parse sizes in bytes, kilobytes, megabytes,
gigabytes, terabytes and petabytes. Some examples:

>>> from humanfriendly import parse_size
>>> parse_size('42')
42
>>> parse_size('13b')
13
>>> parse_size('5 bytes')
5
>>> parse_size('1 KB')
1000
>>> parse_size('1 kilobyte')
1000
>>> parse_size('1 KiB')
1024
>>> parse_size('1 KB', binary=True)
1024
>>> parse_size('1.5 GB')
1500000000
>>> parse_size('1.5 GB', binary=True)
1610612736
r   é   rK   rx   Úbr[   z4Failed to parse size! (input %r was tokenized as %r))r	   r†   rŽ   r�   Úlenr   rz   Ú
startswithÚintÚrstripr   r•   r—   ÚnamerE   r˜   r   r   )Úsizer•   ÚtokensÚnormalized_unitrš   r   s         r€   r   r   Æ   s’  € ôD �d‹^€Fß”*˜V A™Y¬¯©×7Ò7ä/2°6«{¸aÓ/?ÄIÈfÐUVÉi×DXÑDX˜& ™)Ÿ/™/Ô+Ð^`ˆô ˆv‹;˜!Ó˜×9Ñ9¸#×>Ñ>Ü�v˜a‘y“>Ð!çð .×4Ñ4°SÓ9ˆOß'˜�ð #§{¡{×'9Ñ'9×'?Ñ'?Ó'AÀ4Ç;Á;×CSÑCS×CYÑCYÓC[Ð&\Ó\Ü˜v a™y¨4¯;©;×+>Ñ+>Ñ>Ó?Ò?ð $¯©×(;Ñ(;×(AÑ(AÓ(CÀTÇ\Á\×EVÑEV×E\ÑE\ÓE^Ð'_Ó_Ø'×2Ñ2°4·<±<×3FÑ3FÀqÑ3I×3OÑ3OÓ3Q×RÓRÜ˜v a™yÆ6¨D¯K©K×,?Ò,?ÈtÏ|É|×OcÑOcÑdÓeÒeñ (ð A€CÜ
”f˜S¨Ó/Ó
0Ð0r�   c                 ó°   • [        [        5       H8  nXS   :¼  d  M  [        [        U 5      US   -  US9n[	        X2S   US   5      s  $    [	        U S5      $ )aS  
Format a metre count as a human readable length.

:param num_metres: The length to format in metres (float / integer).
:param keep_width: :data:`True` if trailing zeros should not be stripped,
                   :data:`False` if they can be stripped.
:returns: The corresponding human readable length (a string).

This function supports ranges from nanometres to kilometres.

Some examples:

>>> from humanfriendly import format_length
>>> format_length(0)
'0 metres'
>>> format_length(1)
'1 metre'
>>> format_length(5)
'5 metres'
>>> format_length(1000)
'1 km'
>>> format_length(0.004)
'4 mm'
rE   r‘   rF   rG   rL   )r”   r   r!   r–   r   )Ú
num_metresr’   rš   r›   s       r€   r   r     s^   € ô2 Ô*Ö+ˆØ˜i™Õ(Ü!¤%¨
Ó"3°d¸9±oÑ"EÐR\Ñ]ˆFÜ˜V¨*Ñ%5°t¸H±~ÓFÒFñ ,ô �Z Ó)Ð)r�   c                 ó�  • [        U 5      nU(       až  [        US   [        R                  5      (       a|  [	        U5      S:X  a  US   $ [	        U5      S:X  aY  [        US   5      (       aF  US   R                  5       n[         H)  nUR                  US   5      (       d  M  US   US   -  s  $    Sn[        [        X@U5      5      e)a¨  
Parse a human readable length and return the number of metres.

:param length: The human readable length to parse (a string).
:returns: The corresponding length in metres (a float).
:raises: :exc:`InvalidLength` when the input can't be parsed.

Some examples:

>>> from humanfriendly import parse_length
>>> parse_length('42')
42
>>> parse_length('1 km')
1000
>>> parse_length('5mm')
0.005
>>> parse_length('15.3cm')
0.153
r   rK   r�   rD   rE   z6Failed to parse length! (input %r was tokenized as %r))r	   r†   rŽ   r�   rŸ   r   rz   r   r    r   r   )Úlengthr¥   r¦   rš   r   s        r€   r   r   &  s±   € ô( �fÓ€FÞ”*˜V A™Y¬¯©×7Ñ7äˆv‹;˜!ÓØ˜!‘9Ðäˆv‹;˜!Ó¤	¨&°©)× 4Ñ 4Ø$ Q™iŸo™oÓ/ˆOç)�Ø"×-Ñ-¨d°8©n×=Ó=Ø! !™9 t¨I¡Ñ6Ò6ñ *ð C€CÜ
œ˜s¨FÓ3Ó
4Ð4r�   c                 óÌ  • [        [        U 5      5      R                  S5      u  p#nUR                  S5      nSR	                  [        UR                  S5      5      5      n/ nU(       a"  UR                  USS 5        USS nU(       a  M"  SR	                  [        SR	                  U5      5      5      nUSU R                  S5      n	U	(       a  USU	-   -  nU(       a  SU-   nU$ )a  
Format a number as a string including thousands separators.

:param number: The number to format (a number like an :class:`int`,
               :class:`long` or :class:`float`).
:param num_decimals: The number of decimals to render (2 by default). If no
                     decimal places are required to represent the number
                     they will be omitted regardless of this argument.
:returns: The formatted number (a string).

This function is intended to make it easier to recognize the order of size
of the number being formatted.

Here's an example:

>>> from humanfriendly import format_number
>>> print(format_number(6000000))
6,000,000
> print(format_number(6000000000.42))
6,000,000,000.42
> print(format_number(6000000000.42, num_decimals=0))
6,000,000,000
Ú.Ú-rx   Né   Ú,rt   )	Ústrr–   Ú	partitionr    Újoinr”   ÚlstripÚappendr¢   )
r›   Únum_decimalsÚinteger_partÚ_Údecimal_partÚnegative_signÚreversed_digitsÚpartsÚformatted_numberÚdecimals_to_adds
             r€   r   r   K  sÛ   € ô0 %(¬¨f«Ó$6×$@Ñ$@ÀÓ$EÑ!€L�\Ø ×+Ñ+¨CÓ0€MØ—g‘gœh |×':Ñ':¸3Ó'?Ó@ÓA€OØ€EÞ
Ø�‰�_ R aÐ(Ô)Ø)¨!¨"Ð-ˆ÷ ˆ/ð —w‘wœx¨¯©°«Ó8Ó9ÐØ" = LÐ1×8Ñ8¸Ó=€OÞØ˜C /Ñ1Ñ1ÐÞØÐ!1Ñ1ÐØÐr�   c                 ó�   • S[        U 5      -  nU(       d0  [        R                  " SSU5      n[        R                  " SSU5      nU$ )a¬  
Round a floating point number to two decimal places in a human friendly format.

:param count: The number to format.
:param keep_width: :data:`True` if trailing zeros should not be stripped,
                   :data:`False` if they can be stripped.
:returns: The formatted number as a string. If no decimal places are
          required to represent the number, they will be omitted.

The main purpose of this function is to be used by functions like
:func:`format_length()`, :func:`format_size()` and
:func:`format_timespan()`.

Here are some examples:

>>> from humanfriendly import round_number
>>> round_number(1)
'1'
>>> round_number(math.pi)
'3.14'
>>> round_number(5.001)
'5'
z%.2fz0+$rx   z\.$)r–   rƒ   Úsub)Úcountr’   Útexts      r€   r!   r!   s  s>   € ð0 ”E˜%“LÑ €DÞÜ�vŠv�e˜R Ó&ˆÜ�vŠv�f˜b $Ó'ˆØ€Kr�   c           	      ó2  • [        U 5      n U S:  a  U(       d  [        [        U 5      S5      $ / n[        R                  " [        U 5      5      n [        [        [        U(       a  SOSS 5      5      nU Hu  n[        R                  " [        US   5      5      nX-  nX-  n XTS   :w  a  [        U5      nO[        U5      nUS;  d  MT  UR                  [        XuS	   US
   5      5        Mw     [        U5      S:X  a  US   $ U(       d  USU n[        U5      $ )a]  
Format a timespan in seconds as a human readable string.

:param num_seconds: Any value accepted by :func:`coerce_seconds()`.
:param detailed: If :data:`True` milliseconds are represented separately
                 instead of being represented as fractional seconds
                 (defaults to :data:`False`).
:param max_units: The maximum number of units to show in the formatted time
                  span (an integer, defaults to three).
:returns: The formatted timespan as a string.
:raise: See :func:`coerce_seconds()`.

Some examples:

>>> from humanfriendly import format_timespan
>>> format_timespan(0)
'0 seconds'
>>> format_timespan(1)
'1 second'
>>> import math
>>> format_timespan(math.pi)
'3.14 seconds'
>>> hour = 60 * 60
>>> day = hour * 24
>>> week = day * 7
>>> format_timespan(week * 52 + day * 2 + hour * 3)
'1 year, 2 days and 3 hours'
r^   rY   r   r®   NrE   éÿÿÿÿ)r   rt   rF   rG   rK   )r   r   r!   r˜   ÚDecimalr°   Úlistr”   r"   r¡   r´   rŸ   r   )Únum_secondsÚdetailedÚ	max_unitsÚresultÚrelevant_unitsrš   rE   rÀ   s           r€   r   r   ’  s  € ô: ! Ó-€KØ�RÓ¦äœ kÓ2°HÓ=Ð=ð ˆÜ—o’o¤c¨+Ó&6Ó7ˆÜœh¤z¶x±!ÀQÐ2GÐ'HÓIÓJˆÛ"ˆDä—o’o¤c¨$¨y©/Ó&:Ó;ˆGØÑ)ˆEØÑ"ˆKà bÑ)Ó)ä˜E›
‘ô % UÓ+�à˜HÕ$Ø—‘œi¨°JÑ/?ÀÀhÁÓPÖQñ #ô ˆv‹;˜!Óà˜!‘9Ðæà 
 Ð+�ä˜vÓ&Ð&r�   c                 ó²  • [        U 5      nU(       a¯  [        US   [        R                  5      (       a�  [	        U5      S:X  a  [        US   5      $ [	        U5      S:X  aa  [        US   5      (       aN  US   R                  5       n[         H1  nX#S   :X  d  X#S   :X  d
  X#S   ;   d  M  [        US   5      US   -  s  $    Sn[        [        X@U5      5      e)	a9  
Parse a "human friendly" timespan into the number of seconds.

:param value: A string like ``5h`` (5 hours), ``10m`` (10 minutes) or
              ``42s`` (42 seconds).
:returns: The number of seconds as a floating point number.
:raises: :exc:`InvalidTimespan` when the input can't be parsed.

Note that the :func:`parse_timespan()` function is not meant to be the
"mirror image" of the :func:`format_timespan()` function. Instead it's
meant to allow humans to easily and succinctly specify a timespan with a
minimal amount of typing. It's very useful to accept easy to write time
spans as e.g. command line arguments to programs.

The time units (and abbreviations) supported by this function are:

- ms, millisecond, milliseconds
- s, sec, secs, second, seconds
- m, min, mins, minute, minutes
- h, hour, hours
- d, day, days
- w, week, weeks
- y, year, years

Some examples:

>>> from humanfriendly import parse_timespan
>>> parse_timespan('42')
42.0
>>> parse_timespan('42s')
42.0
>>> parse_timespan('1m')
60.0
>>> parse_timespan('1h')
3600.0
>>> parse_timespan('1d')
86400.0
r   rK   r�   rF   rG   rR   rE   z8Failed to parse timespan! (input %r was tokenized as %r))r	   r†   rŽ   r�   rŸ   r–   r   rz   r"   r   r   )Útimespanr¥   r¦   rš   r   s        r€   r    r    Ò  sÇ   € ôN �hÓ€FÞ”*˜V A™Y¬¯©×7Ñ7äˆv‹;˜!ÓÜ˜ ™Ó#Ð#äˆv‹;˜!Ó¤	¨&°©)× 4Ñ 4Ø$ Q™iŸo™oÓ/ˆOß"�Ø#¨JÑ'7Ó7Ø'°©>Ó9Ø'°Ñ+@Õ@Ü  ¨¡Ó+¨d°9©oÑ=Ò=ñ	 #ð E€CÜ
œ& °Ó7Ó
8Ð8r�   c                 ó(  •  U R                  5        Vs/ sH  oR                  5       PM     nn[        U5      S:¼  at  [        [	        [
        US   R                  S5      5      5      SS/-   n[        [	        [
        US   R                  S5      5      5      / SQ-   n[        USS USS -   5      $ [        [	        [
        U R                  S5      5      5      SS/-   SS u  pVnXVUSSS4$ s  snf ! [         a    Sn[        [        X€5      5      ef = f)	a‹  
Parse a date/time string into a tuple of integers.

:param datestring: The date/time string to parse.
:returns: A tuple with the numbers ``(year, month, day, hour, minute,
          second)`` (all numbers are integers).
:raises: :exc:`InvalidDate` when the date cannot be parsed.

Supported date/time formats:

- ``YYYY-MM-DD``
- ``YYYY-MM-DD HH:MM:SS``

.. note:: If you want to parse date/time strings with a fixed, known
          format and :func:`parse_date()` isn't useful to you, consider
          :func:`time.strptime()` or :meth:`datetime.datetime.strptime()`,
          both of which are included in the Python standard library.
          Alternatively for more complex tasks consider using the date/time
          parsing module in the dateutil_ package.

Examples:

>>> from humanfriendly import parse_date
>>> parse_date('2013-06-17')
(2013, 6, 17, 0, 0, 0)
>>> parse_date('2013-06-17 02:47:42')
(2013, 6, 17, 2, 47, 42)

Here's how you convert the result to a number (`Unix time`_):

>>> from humanfriendly import parse_date
>>> from time import mktime
>>> mktime(parse_date('2013-06-17 02:47:42') + (-1, -1, -1))
1371430062.0

And here's how you convert it to a :class:`datetime.datetime` object:

>>> from humanfriendly import parse_date
>>> from datetime import datetime
>>> datetime(*parse_date('2013-06-17 02:47:42'))
datetime.datetime(2013, 6, 17, 2, 47, 42)

Here's an example that combines :func:`format_timespan()` and
:func:`parse_date()` to calculate a human friendly timespan since a
given date:

>>> from humanfriendly import format_timespan, parse_date
>>> from time import mktime, time
>>> unix_time = mktime(parse_date('2013-06-17 02:47:42') + (-1, -1, -1))
>>> seconds_since_then = time() - unix_time
>>> print(format_timespan(seconds_since_then))
1 year, 43 weeks and 1 day

.. _dateutil: https://dateutil.readthedocs.io/en/latest/parser.html
.. _Unix time: http://en.wikipedia.org/wiki/Unix_time
r�   r   r­   rK   Ú:)r   r   r   r®   zJInvalid date! (expected 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' but got: %r))
Úsplitry   rŸ   rÅ   Úmapr¡   ÚtupleÚ	Exceptionr   r   )	Ú
datestringÚtr¥   Ú
date_partsÚ
time_partsrl   Úmonthrf   r   s	            r€   r   r     s  € ðr3Ø%/×%5Ñ%5Ô%7Ó8Ñ%7 —'‘'–)Ñ%7ˆÐ8Üˆv‹;˜!ÓÜœc¤# v¨a¡y§¡°sÓ';Ó<Ó=ÀÀAÀÑFˆJÜœc¤# v¨a¡y§¡°sÓ';Ó<Ó=Â	ÑIˆJÜ˜ A a˜¨:°a¸¨?Ñ:Ó;Ð;ä $¤S¬¨j×.>Ñ.>¸sÓ.CÓ%DÓ EÈÈAÈÑ NÐPQÐRSÐTÑˆD˜Ø  a¨¨AÐ.Ð.ùò 9øô ó 3ØZˆÜœ& Ó1Ó2Ð2ð3ús"   ‚C0 ”C+¬BC0 Â19C0 Ã+C0 Ã0!Dc                 ót  • [         R                  R                  U 5      n [         R                  R	                  S5      nU(       ar  [         R                  R                  U5      nU R                  U5      (       a=  [         R                  R                  S[         R                  R                  X5      5      n U $ )aŒ  
Shorten a pathname to make it more human friendly.

:param pathname: An absolute pathname (a string).
:returns: The pathname with the user's home directory abbreviated.

Given an absolute pathname, this function abbreviates the user's home
directory to ``~/`` in order to shorten the pathname without losing
information. It is not an error if the pathname is not relative to the
current user's home directory.

Here's an example of its usage:

>>> from os import environ
>>> from os.path import join
>>> vimrc = join(environ['HOME'], '.vimrc')
>>> vimrc
'/home/peter/.vimrc'
>>> from humanfriendly import format_path
>>> format_path(vimrc)
'~/.vimrc'
ÚHOMEÚ~)ÚosÚpathÚabspathÚenvironÚgetr    r²   Úrelpath)ÚpathnameÚhomes     r€   r   r   R  st   € ô. �w‰w�‰˜xÓ(€HÜ�:‰:�>‰>˜&Ó!€DÞÜ�w‰w�‰˜tÓ$ˆØ×Ñ˜t×$Ñ$Ü—w‘w—|‘| C¬¯©¯©¸Ó)HÓIˆHØ€Or�   c                 ó´   • [         R                  R                  [         R                  R                  [         R                  R	                  U 5      5      5      $ )ab  
Convert a human friendly pathname to an absolute pathname.

Expands leading tildes using :func:`os.path.expanduser()` and
environment variables using :func:`os.path.expandvars()` and makes the
resulting pathname absolute using :func:`os.path.abspath()`.

:param pathname: A human friendly pathname (a string).
:returns: An absolute pathname (a string).
)rÛ   rÜ   rÝ   Ú
expanduserÚ
expandvars)rá   s    r€   r   r   r  s5   € ô �7‰7�?‰?œ2Ÿ7™7×-Ñ-¬b¯g©g×.@Ñ.@ÀÓ.JÓKÓLÐLr�   c                   ó^   • \ rS rSrSrSS jrS rSS jrS r\	S 5       r
\	S	 5       rS
 rSrg)r   i€  z<
Easy to use timer to keep track of long during operations.
Nc                 ó¾   • U(       a  SU l         SU l        SU l        SU l        gU(       a  SU l         SU l        Xl        gSU l         SU l        [        5       U l        g)a_  
Remember the time when the :class:`Timer` was created.

:param start_time: The start time (a float, defaults to the current time).
:param resumable: Create a resumable timer (defaults to :data:`False`).

When `start_time` is given :class:`Timer` uses :func:`time.time()` as a
clock source, otherwise it uses :func:`humanfriendly.compat.monotonic()`.
Tç        FN©r   Ú	resumableÚ
start_timeÚ
total_time)Úselfrë   rê   s      r€   Ú__init__ÚTimer.__init__†  sP   € ö Ø!ˆDŒNØ!ˆDŒNØ!ˆDŒOØ!ˆD�OÞØ"ˆDŒNØ"ˆDŒNØ(�Oà!ˆDŒNØ"ˆDŒNÜ'›kˆD�Or�   c                 ó\   • U R                   (       d  [        S5      e[        5       U l        U $ )z•
Start or resume counting elapsed time.

:returns: The :class:`Timer` object.
:raises: :exc:`~exceptions.ValueError` when the timer isn't resumable.
úTimer is not resumable!)rê   r{   r   rë   ©rí   s    r€   Ú	__enter__ÚTimer.__enter__ž  s%   € ð �~�~ÜÐ6Ó7Ð7Ü#›+ˆŒØˆr�   c                 óÂ   • U R                   (       d  [        S5      eU R                  (       a2  U =R                  [	        5       U R                  -
  -  sl        SU l        gg)ze
Stop counting elapsed time.

:raises: :exc:`~exceptions.ValueError` when the timer isn't resumable.
rñ   rè   N)rê   r{   rë   rì   r   )rí   Úexc_typeÚ	exc_valueÚ	tracebacks       r€   Ú__exit__ÚTimer.__exit__ª  sC   € ð �~�~ÜÐ6Ó7Ð7Ø�?�?Ø�OŠOœy›{¨T¯_©_Ñ<Ñ<�OØ!ˆD�Oð r�   c                 ó\   • [         R                  " [        SXR                  -
  5      5        g)aÎ  
Easy to use rate limiting of repeating actions.

:param seconds: The number of seconds to sleep (an
                integer or floating point number).

This method sleeps for the given number of seconds minus the
:attr:`elapsed_time`. If the resulting duration is negative
:func:`time.sleep()` will still be called, but the argument
given to it will be the number 0 (negative numbers cause
:func:`time.sleep()` to raise an exception).

The use case for this is to initialize a :class:`Timer` inside
the body of a :keyword:`for` or :keyword:`while` loop and call
:func:`Timer.sleep()` at the end of the loop body to rate limit
whatever it is that is being done inside the loop body.

For posterity: Although the implementation of :func:`sleep()` only
requires a single line of code I've added it to :mod:`humanfriendly`
anyway because now that I've thought about how to tackle this once I
never want to have to think about it again :-P (unless I find ways to
improve this).
r   N)ÚtimeÚsleepÚmaxÚelapsed_time)rí   rZ   s     r€   rý   ÚTimer.sleep¶  s    € ô0 	�
Š
”3�q˜'×$5Ñ$5Ñ5Ó6Õ7r�   c                 óì   • SnU R                   (       a  XR                  -  nU R                  (       aA  U R                  (       a
  [        5       O[        R                  " 5       nXU R                  -
  -  nU$ )z+
Get the number of seconds counted so far.
r   )rê   rì   rë   r   rü   )rí   rÿ   Úcurrent_times      r€   rÿ   ÚTimer.elapsed_timeÐ  sO   € ð
 ˆØ�>�>ØŸO™OÑ+ˆLØ�?�?Ø*.¯.¯.œ9œ;¼d¿iºi»kˆLØ¨4¯?©?Ñ:Ñ:ˆLØÐr�   c                 ó>   • [        [        U R                  5      5      $ )z6Human readable timespan rounded to seconds (a string).)r   Úroundrÿ   rò   s    r€   ÚroundedÚTimer.roundedÝ  s   € ô œu T×%6Ñ%6Ó7Ó8Ð8r�   c                 ó,   • [        U R                  5      $ )z;Show the elapsed time since the :class:`Timer` was created.)r   rÿ   rò   s    r€   Ú__str__ÚTimer.__str__â  s   € ä˜t×0Ñ0Ó1Ð1r�   ré   )NF)NNN)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rî   ró   rù   rý   Úpropertyrÿ   r  r	  Ú__static_attributes__© r�   r€   r   r   €  sH   † ñô*ò0
ô
"ò8ð4 ñ
ó ð
ð ñ9ó ð9õ2r�   r   c                   ó   • \ rS rSrSrSrg)r   iç  a~  
Raised when a string cannot be parsed into a date.

For example:

>>> from humanfriendly import parse_date
>>> parse_date('2013-06-XY')
Traceback (most recent call last):
  File "humanfriendly.py", line 206, in parse_date
    raise InvalidDate(format(msg, datestring))
humanfriendly.InvalidDate: Invalid date! (expected 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' but got: '2013-06-XY')
r  N©r  r  r  r  r  r  r  r�   r€   r   r   ç  ó   † ôr�   r   c                   ó   • \ rS rSrSrSrg)r   i÷  ap  
Raised when a string cannot be parsed into a file size.

For example:

>>> from humanfriendly import parse_size
>>> parse_size('5 Z')
Traceback (most recent call last):
  File "humanfriendly/__init__.py", line 267, in parse_size
    raise InvalidSize(format(msg, size, tokens))
humanfriendly.InvalidSize: Failed to parse size! (input '5 Z' was tokenized as [5, 'Z'])
r  Nr  r  r�   r€   r   r   ÷  r  r�   r   c                   ó   • \ rS rSrSrSrg)r   i  a{  
Raised when a string cannot be parsed into a length.

For example:

>>> from humanfriendly import parse_length
>>> parse_length('5 Z')
Traceback (most recent call last):
  File "humanfriendly/__init__.py", line 267, in parse_length
    raise InvalidLength(format(msg, length, tokens))
humanfriendly.InvalidLength: Failed to parse length! (input '5 Z' was tokenized as [5, 'Z'])
r  Nr  r  r�   r€   r   r     r  r�   r   c                   ó   • \ rS rSrSrSrg)r   i  a‘  
Raised when a string cannot be parsed into a timespan.

For example:

>>> from humanfriendly import parse_timespan
>>> parse_timespan('1 age')
Traceback (most recent call last):
  File "humanfriendly/__init__.py", line 419, in parse_timespan
    raise InvalidTimespan(format(msg, timespan, tokens))
humanfriendly.InvalidTimespan: Failed to parse timespan! (input '1 age' was tokenized as [1, 'age'])
r  Nr  r  r�   r€   r   r     r  r�   r   Úmodule_nameÚformat_tablez(humanfriendly.tables.format_pretty_tableÚcompactzhumanfriendly.text.compactr   zhumanfriendly.text.concatenateÚdedentzhumanfriendly.text.dedentr   zhumanfriendly.text.formatÚis_empty_linez humanfriendly.text.is_empty_liner   zhumanfriendly.text.pluralizer	   zhumanfriendly.text.tokenizeÚtrim_empty_linesz#humanfriendly.text.trim_empty_linesÚprompt_for_choicez'humanfriendly.prompts.prompt_for_choiceÚAutomaticSpinnerz0humanfriendly.terminal.spinners.AutomaticSpinnerÚSpinnerz'humanfriendly.terminal.spinners.SpinnerÚerase_line_codez&humanfriendly.terminal.ANSI_ERASE_LINEÚhide_cursor_codez'humanfriendly.terminal.ANSI_SHOW_CURSORÚminimum_spinner_intervalz0humanfriendly.terminal.spinners.MINIMUM_INTERVALÚshow_cursor_codez'humanfriendly.terminal.ANSI_HIDE_CURSOR)r   )FF)F)r�   )Fr®   r  )2r  Úcollectionsr‹   r˜   rŽ   rÛ   Úos.pathrƒ   rü   Úhumanfriendly.compatr   r   Úhumanfriendly.deprecationr   Úhumanfriendly.textr   r   r   r	   Ú__all__r   Ú
namedtupler   r
   r   Údictr   r"   r   r   r   r   r   r   r   r   r!   r   r    r   r   r   Úobjectr   rÒ   r   r   r   r   r  r  r�   r€   Ú<module>r/     s‘  ðñ 6ó Û Û Û Û 	Û Û 	Û ÷ 6Ý 4ß GÓ Gð€ð: €ð ×!Ò! *Ð.EÓF€Ø×%Ò% nÐ6GÓH€ñ ‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó3±X¸gÀuÈjÓ5YÓZÙ‘˜' 4¨Ó5±xÀÈÐPZÓ7[Ó\Ù‘˜' 4¨Ó5±xÀÈÐPZÓ7[Ó\ð	€ñ  ¨u¸tÈDÑQÙ ¨u¸tÈDÑQÙ ¨u¸tÈDÑQÙ ¨a¸'È(ÑSÙ ¨t¸dÈ4ÑPð	RÐ ñ ˜4¨,¸}Ð]aÐ\bÑcÙ˜4¨-ÀÐ_cÐ^dÑeÙ˜4¨-ÀÐ_cÐ^dÑeÙ˜1 x¸	ÒQeÑfÙ˜2¨¸ÒRfÑgÙ˜7¨V¸GÐTWÐSXÑYÙ˜<°%ÀÐWZÐV[Ñ\ÙÐ+°fÀWÐ]`Ð\aÑbÙÐ0¸6È'ÐbeÐafÑgði€
òô8ò,ô&#(ôL=1ô@*ò@"5ôJ%ôPô>='ò@69òrD3òNò@Môd2ˆFô d2ôN�)ô ô �)ô ô �Iô ô �iô ñ" ò Ùðñ <ðñ )ðñ 1ðñ 'ðñ 'ðñ 5ðñ -ðñ  +ð!ñ" ;ð#ñ( @ð)ñ0 Hð1ñ2 6ð3ñ4 =ð5ñ6 ?ð7ñ8 Pð9ñ: ?ò;r�   