
    Ki                     .   S SK r S SKrS SKrS SKJr  S SKJrJr  S SKJ	r	JrJ
r
  S SKJr  S SKJrJr  S SKJr  S SKrS SKJrJr  \ R,                  " S	5      rS
 rS rS rS rS rS rS rS rS\S\\    4S jr!S\"4S jr# " S S\5      r$S r%S r&S r'g)    N)defaultdict)asdictis_dataclass)datedatetimetimezone)Decimal)AnyOptional)UUID)tzlocaltzutcposthogc                 f    U R                   SL =(       d    U R                   R                  U 5      SL $ )z1Determines if a given datetime.datetime is naive.N)tzinfo	utcoffset)dts    O/var/www/html/dynamic-report/venv/lib/python3.13/site-packages/posthog/utils.pyis_naiver      s*    99?		 3 3B 74 ??    c                 f    U R                   U R                  U R                  S-  S-  -   S-  -   S-  $ )z2Determines total seconds with python < 2.7 compat.   i  g    .A)microsecondssecondsdays)deltas    r   total_secondsr      s6     %--%**r/D2H"HC!OOSVVVr   c                     [        U 5      (       aU  [        R                  " 5       U -
  n[        U5      S:  a  U R	                  [        5       S9$ U R	                  [        5       S9$ U $ )z:Attempts to convert a naive datetime to an aware datetime.   r   )r   r   nowr   replacer   r   )r   r   s     r   guess_timezoner#      sY    || #!# ::WY:// ::UW:--Ir   c                 <    U R                  S5      (       a  U S S $ U $ )N/)endswith)hosts    r   remove_trailing_slashr)   -   s"    }}SCRyKr   c                 p   [        U [        5      (       a  [        U 5      $ [        U [        5      (       a  [	        U 5      $ [        U [
        R                  [        [        R                  [        [        [        S 5      45      (       a  U $ [        U [        [        [        45      (       a  [!        U 5      $  [#        U S5      (       a+  [%        U R&                  5      (       a  U R'                  5       n O;[#        U S5      (       a*  [%        U R(                  5      (       a  U R)                  5       n [        U [(        5      (       a  [1        U 5      $ [3        U 5      (       a   [        U [        5      (       d  [5        U 5      $ [7        U 5      $ ! [*         a"  n[,        R/                  SU 35         S nANS nAff = f)N
model_dumpdictz)Could not serialize Pydantic-like model: )
isinstancer	   floatr   strsixstring_typesboolnumbersNumberr   r   typesetlisttuple_clean_listhasattrcallabler+   r,   	TypeErrorlogdebug_clean_dictr   _clean_dataclass_coerce_unicode)itemes     r   cleanrD   3   sE   $  T{$4ysw~~xtDzR  $dE*++4  	4&&8DOO+D+D??$DT6""x		':':99;D $4  D*T4"8"8%%4    		=aSABs   7;F	 3;F	 	
F5F00F5c                 D    U  Vs/ s H  n[        U5      PM     sn$ s  snf N)rD   )list_rB   s     r   r9   r9   P   s    $)*EDE$KE***s   c           
          0 n[         R                  " U 5       H  u  p# [        U5      X'   M     U$ ! [         a%    [        R                  SUU[        U5      5         MG  f = f)NzXDictionary values must be serializeable to JSON "%s" value %s of type %s is unsupported.)r0   	iteritemsrD   r<   r=   warningr5   )dict_datakvs       r   r?   r?   T   s`    De$	AhDG % K  	KKjQ		s   2+A! A!c                 2    [        U 5      n[        U5      nU$ rF   )r   r?   )
dataclass_rL   s     r   r@   r@   c   s    *DtDKr   cmplxreturnc                 8   Sn [        U [        5      (       a  U R                  SS5      nU$ [        U [        5      (       a  U nU$ ! [         aI  nSR                  [        [        UR                  5      5      n[        R                  SU5         SnAgSnAff = f)aR  
In theory, this method is only called
after many isinstance checks are carried out in `utils.clean`.
When we supported Python 2 it was safe to call `decode` on a `str`
but in Python 3 that will throw.
So, we check if the input is bytes and only call `decode` in that case.

Previously we would always call `decode` on the input
That would throw an error.
Then we would call `decode` on the stringified error
That would throw an error.
And then we would return `None`

To avoid a breaking change, we can maintain the behavior
that anything which did not have `decode` in Python 2
returns None.
Nzutf-8strict:zError decoding: %s)
r-   bytesdecoder/   	Exceptionjoinmapargsr=   rJ   )rQ   rB   	exceptions      r   rA   rA   i   s    $ DeU##<<2D K s##D K  xxC01($/s   'A A 
B?BBc                 f     [         R                  " U 5        g! [         R                   a     gf = f)NTF)recompileerror)values    r   is_valid_regexrb      s,    


588 s    00c                   4   ^  \ rS rSrU 4S jrU 4S jrSrU =r$ )SizeLimitedDict   c                 2   > [         TU ]  " U0 UD6  Xl        g rF   )super__init__max_size)selfri   r[   kwargs	__class__s       r   rh   SizeLimitedDict.__init__   s    $)&) r   c                 v   > [        U 5      U R                  :  a  U R                  5         [        TU ]  X5        g rF   )lenri   clearrg   __setitem__)rj   keyra   rl   s      r   rq   SizeLimitedDict.__setitem__   s)    t9%JJLC'r   )ri   )__name__
__module____qualname____firstlineno__rh   rq   __static_attributes____classcell__)rl   s   @r   rd   rd      s    !( (r   rd   c                 Z    U R                   c  U R                  [        R                  S9n U $ )Nr    )r   r"   r   utc)date_objs    r   convert_to_datetime_awarer}      s(    ##8<<#8Or   c                 h    [        U5      R                  5       [        U 5      R                  5       ;   $ )am  
Check if a string contains another string, ignoring case.

Args:
    source: The string to search within
    search: The substring to search for

Returns:
    bool: True if search is a substring of source (case-insensitive), False otherwise

Examples:
    >>> str_icontains("Hello World", "WORLD")
    True
    >>> str_icontains("Hello World", "python")
    False
r/   casefold)sourcesearchs     r   str_icontainsr      s)    " v;!S[%9%9%;;;r   c                 h    [        U 5      R                  5       [        U5      R                  5       :H  $ )ae  
Check if a string equals another string, ignoring case.

Args:
    value: The string to compare
    comparand: The string to compare with

Returns:
    bool: True if value and comparand are equal (case-insensitive), False otherwise

Examples:
    >>> str_iequals("Hello World", "hello world")
    True
    >>> str_iequals("Hello World", "hello")
    False
r   )ra   	comparands     r   str_iequalsr      s)    " u: C	N$;$;$===r   )(loggingr3   r^   collectionsr   dataclassesr   r   r   r   r   decimalr	   typingr
   r   uuidr   r0   dateutil.tzr   r   	getLoggerr=   r   r   r#   r)   rD   r9   r?   r@   r/   rA   r2   rb   rd   r}   r   r    r   r   <module>r      s      	 # , - -     
 &	"@
W"!:+3 8C= @T 	(k 	(<(>r   