
    \j5g                     2   d dl Z d dlZd dlZd dlZd dlmZ d dlZd dlmZm	Z	m
Z
 d dlmZmZ d dlmZmZ d dlmZmZ d dlmZmZ d dlmZmZmZmZmZmZmZmZm Z m!Z! d d	l"m#Z#m$Z$m%Z% d d
l&m'Z' d dl(m)Z) d dl*m+Z+m,Z, 	 d dl-m.Z/ d dl0m1Z2 d dl3m4Z4 d dl0m1Z1 	 d dl5m6Z6 	 d dl5m9Z9 	 d dl:m;Z; d dl=m>Z> d dl?m@Z@mAZA d dlBmCZC d dlDmEZE d dlFmGZG d dlHmIZI e/dd dkD  rd dlJmKZK ndZKd dlLmMZM eMrTd dlLmNZN d dlLmOZO d d lLmPZP d d!lLmQZQ d d"lLmRZR d d#lLmSZS d d$lTmUZU d d%lVmWZW d d&lXmYZY d d'lZm[Z[ d d(lm\Z\ d d)l(m]Z] d d*l^m_Z_m`Z`maZambZb e/d+k  r	d,d-d.ecfd/Zdnd,d-d.ecfd0Zdd1Ze G d2 d3e$      Zfd4ag ej                         ZidJd5ZjdJd6ZkdJd7Zld8d9d:emd;d<d.dfd=ZndKd>Zod;d<d8d9d:emd.dfd?ZpdKd@ZqdJdAZr	 	 	 	 	 	 dLdBZsdMdNdCZt G dD dEe,      ZudOdFZvdJdGZw	 dM	 	 	 	 	 	 	 dPdHZxdJdIZyy# e7$ r
 d dl8m6Z6 Y Iw xY w# e7$ r
 d dl8m9Z9 Y Tw xY w# e<$ r dZ;Y [w xY w# e7$ r	  e%d      w xY w)Q    N)import_module)OPSPANDATASPANNAME)add_global_event_processorshould_send_default_pii)add_global_repr_processoradd_repr_sequence_type)SOURCE_FOR_STYLETransactionSource)add_query_sourcerecord_sql_queries)
AnnotatedValueHAS_REAL_CONTEXTVARSCONTEXTVARS_ERROR_MESSAGESENSITIVE_DATA_SUBSTITUTEloggercapture_internal_exceptionsensure_integration_enabledevent_from_exceptiontransaction_from_functionwalk_exception_chain)_check_minimum_versionIntegrationDidNotEnable)ignore_logger)SentryWsgiMiddleware)DEFAULT_HTTP_METHODS_TO_CAPTURERequestExtractor)VERSIONsettings)signals)resolve)Resolver404)ASGIRequestzDjango not installed)LEGACY_RESOLVER)!get_template_frame_from_exceptionpatch_templates)patch_django_middlewares)patch_signals)patch_tasks)patch_views   )      )patch_caching)TYPE_CHECKING)Any)Callable)Dict)Optional)Union)List)WSGIRequest)HttpResponse)	QueryDict)MultiValueDict)Span)_ScopedResponse)EventHintEventProcessorNotImplementedType)r/   
   request_userr3   returnc                 "    | j                         S Nis_authenticatedrD   s    Q/root/env/lib/python3.12/site-packages/sentry_sdk/integrations/django/__init__.pyrI   rI   _   s    ,,..    c                     | j                   S rG   rH   rJ   s    rK   rI   rI   d   s    ,,,rL   )function_nameurlc                       e Zd ZU dZdZde Zde ZdZdZdZ	dZ
g Zded<   d	d
dd
d
defdedededededdddddfdZedd       Zy)DjangoIntegrationa  
    Auto instrument a Django application.

    :param transaction_style: How to derive transaction names. Either `"function_name"` or `"url"`. Defaults to `"url"`.
    :param middleware_spans: Whether to create spans for middleware. Defaults to `False`.
    :param signals_spans: Whether to create spans for signals. Defaults to `True`.
    :param signals_denylist: A list of signals to ignore when creating spans.
    :param cache_spans: Whether to create spans for cache operations. Defaults to `False`.
    djangoz
auto.http.zauto.db. Nzlist[signals.Signal]signals_denylistrO   FTtransaction_stylemiddleware_spanssignals_spanscache_spansdb_transaction_spanszOptional[list[signals.Signal]]http_methods_to_captureztuple[str, ...]rE   c                     |t         vrt        d|dt         d      || _        || _        || _        |xs g | _        || _        || _        t        t        t        j                  |            | _        y )Nz%Invalid value for transaction_style: z (must be in ))TRANSACTION_STYLE_VALUES
ValueErrorrU   rV   rW   rT   rX   rY   tuplemapstrupperrZ   )selfrU   rV   rW   rX   rY   rT   rZ   s           rK   __init__zDjangoIntegration.__init__   sv     $<<$&>@  "3 0* 0 6B&$8!',S<S-T'U$rL   c                  N   t        t        t               t                t	        d       t	        d       ddlm j                  t        t              	 	 	 	 	 	 	 	 dfd       } | _        t                t                t        j                  j                  t               t        	 	 	 	 	 	 d	d       }t         	 	 	 	 	 	 d
d       }t#                t%                t'                t)                t+                t-                t/                t0        t1                y y )Nzdjango.serverzdjango.requestr   )WSGIHandlerc                 
   	j                  |       }ddlm} |j                  }t	        j
                         j                  t              }t        ||t        j                  |r|j                  nt              } |||      S )Nr   r!   )span_originrZ   )__get__django.confr"   USE_X_FORWARDED_HOST
sentry_sdk
get_clientget_integrationrQ   r   originrZ   r   )
rc   environstart_responsebound_old_appr"   use_x_forwarded_forintegration
middlewarerf   old_apps
           rK   sentry_patched_wsgi_handlerzADjangoIntegration.setup_once.<locals>.sentry_patched_wsgi_handler   sy     $OOD+>M,"*"?"?$//1AABSTK-#-44 #  778	J g~66rL   c                 ,   || S |j                  dd       }|| S | j                  dd       }|| S |j                  dd       }|| S t        t        |      t        |            D ]  \  }\  }}}t	        |      }||j                  di       j                  dg       }t        t        t        |                  D ]6  }	||	   }
|
j                  d      dv s|
j                  d      d	k(  s1|	d
z  }	 n t        |      }	|j                  |	|        | S )Nexc_info	exceptionvalues
stacktraceframesfunction)zParser.parseparserendermodulezdjango.template.baser/   )getzipreversedr   r(   rangeleninsert)eventhintry   rz   r{   _	exc_valueframer}   ifs              rK   process_django_templatesz>DjangoIntegration.setup_once.<locals>.process_django_templates   s2    |xx
D1H		+t4I ]]8T2F~03 "6x"@1 ,,	,Ay! :)D$&]]<<@@2NF%eCK&89 	("1IEE*-1TT !h3I IFA!	(  KMM!U+%,( LrL   c                     	 ddl m} t	        | |      r| j
                  rt        S d| j                  j                  | j                  t        |       fz  S # t        $ r	 t        cY S w xY w)Nr   )QuerySetz<%s from %s at 0x%x>)
django.db.models.queryr   	ExceptionNotImplemented
isinstance_result_cache	__class____name__
__module__id)valuer   r   s      rK   _django_queryset_reprz;DjangoIntegration.setup_once.<locals>._django_queryset_repr   sl    	& < eX.%2E2E%%)((  5	-    &%%&s   A A'&A')rc   r3   rp   Dict[str, str]rq   zCallable[..., Any]rE   r>   )r   r?   r   zOptional[Hint]rE   zOptional[Event])r   r3   r   zDict[str, Any]rE   zUnion[NotImplementedType, str])r   rQ   DJANGO_VERSIONinstall_sql_hookr   django.core.handlers.wsgirf   __call__r   _patch_get_response_patch_django_asgi_handlerr#   got_request_exceptionconnect_got_request_exceptionr   r	   _patch_channelsr*   r-   r)   r+   r,   "add_template_context_repr_sequencer1   )rw   r   r   rf   rv   s      @@rK   
setup_oncezDjangoIntegration.setup_once   s+   0.A 	o&&'9&&	#$5w	?	7	7"2	7DX	7	7 
@	7.  ;"$%%--.DE	#)	)	"2)	)	 
$)	V 
#		 0	-	 
#	. 	 "*,$O %rL   rE   N)r   r   __qualname____doc__
identifierro   	origin_dbrU   rV   rW   rX   rT   __annotations__r   ra   boolrd   staticmethodr    rL   rK   rQ   rQ   k   s     J*&F:,'IMK/1,1 "'!&"!%*=A5TVV V 	V
 V #V ;V "3V 
V4 { {rL   rQ   Fc                     t         ryt        5  t         r
	 ddd       yda t               5  	 ddlm}  | j
                  	 	 	 	 	 	 	 	 	 	 dfd}|| _        ddd       ddd       y# t        $ r Y w xY w# 1 sw Y   !xY w# 1 sw Y   yxY w)a  
    Patch Django Rest Framework for more/better request data. DRF's request
    type is a wrapper around Django's request type. The attribute we're
    interested in is `request.data`, which is a cached property containing a
    parsed request body. Reading a request body from that property is more
    reliable than reading from any of Django's own properties, as those don't
    hold payloads in memory and therefore can only be accessed once.

    We patch the Django request object to include a weak backreference to the
    DRF request object, such that we can later use either in
    `DjangoRequestExtractor`.

    This function is not called directly on SDK setup, because importing almost
    any part of Django Rest Framework will try to access Django settings (where
    `sentry_sdk.init()` might be called from in the first place). Instead we
    run this function on every request and do the patching on the first
    request.
    NTr   )APIViewc                     t               5  t        j                  |      |j                  _        	 d d d         | |g|i |S # 1 sw Y   xY wrG   )r   weakrefref_request_sentry_drf_request_backref)rc   requestargskwargsold_drf_initials       rK   sentry_patched_drf_initialz._patch_drf.<locals>.sentry_patched_drf_initialG  sY     56 GN{{#H((D 	
 +4J4J6JJ s   %AA)
rc   r   r   r3   r   r3   r   r3   rE   r3   )_DRF_PATCHED_DRF_PATCH_LOCKr   rest_framework.viewsr   initialImportError)r   r   r   s     @rK   
_patch_drfr     s    , 	 == = (* 	==8 #*//K#K.3K<AKMRKK #=%	== =  	= 	== =sI   BBA7A(#A7B(	A41A73A44A77B 	<BBc                      	 ddl m}  t        st	        j
                  dt        z          ddlm}  ||        y # t        $ r Y y w xY w)Nr   )AsgiHandlerz3We detected that you are using Django channels 2.0.) patch_channels_asgi_handler_impl)	channels.httpr   r   r   r   warningr   #sentry_sdk.integrations.django.asgir   )r   r   s     rK   r   r   T  sJ    -   	A'(	

 U$[1%     9 	AAc                      	 ddl m}  t        st	        j
                  dt        z          ddlm}  ||        y # t        $ r Y y w xY w)Nr   )ASGIHandlerz(We detected that you are using Django 3.)patch_django_asgi_handler_impl)	django.core.handlers.asgir   r   r   r   r   r   r   r   )r   r   s     rK   r   r   l  sH    9   	69RR	
 S";/  r   scopezsentry_sdk.ScoperU   r   r9   c                    	 d }|dk(  r6t        |j                        j                  }t        t	        |d|            }n\|dk(  rWt        |d      r,t        j                   |j                  |j                        }nt        j                   |j                        }||j                  }t        j                  }n	t        |   }| j                  ||       y # t        $ rj t        t        j                         }t        |d      rB|j"                  }t%        |t&              r	|| _        Y y t        t	        |d|            | _        Y y Y y t*        $ r Y y w xY w)NrN   
view_classrO   urlconf)r   )source
handler404)r$   pathfuncr   getattrhasattrr'   	path_infor   r   URLr   set_transaction_namer%   r   r"   ROOT_URLCONFr   r   ra   transactionr   )r   rU   r   transaction_namefnr   r   handlers           rK    _set_transaction_name_and_sourcer     s?   %/&++B8\SU9VW%'w	*#2#:#:%%w$  $3#:#:7;L;L#M #&00&**F%&78F"" 	# 	
   5 56 7L)((G'3'$+!$=G\7;%! *  s   CC AE*E	EEc                    t        j                         j                  t              }|y t	                t        j
                         }t        ||j                  |        |j                  t        t        j                  |       |             y rG   )rl   rm   rn   rQ   r   get_current_scoper   rU   add_event_processor"_make_wsgi_request_event_processorr   r   r   rt   r   s      rK   _before_get_responser     sk    '')99:KLKL((*E$UK,I,I7S	*7;;w+?MrL   c                 8    t        | d      syt        |||        y)z
    Some django middlewares overwrite request.urlconf
    so we need to respect that contract,
    so we try to resolve the url again.
    r   N)r   r   )r   r   rU   s      rK   _attempt_resolve_againr     s     7I&$U,=wGrL   c                     t        j                         j                  t              }||j                  dk7  ry t        j
                         }t        | ||j                         y )NrO   )rl   rm   rn   rQ   rU   r   r   r   s      rK   _after_get_responser     sR    '')99:KLKk;;uD((*E7E;+H+HIrL   c                      ddl m}  | j                  	 	 	 	 	 	 dfd}|| _        t        | d      rddlm}  || t               yy)zU
    patch get_response, because at that point we have the Django request object
    r   )BaseHandlerc                 F    t        |        | |      }t        |       |S rG   )r   r   )rc   r   rvold_get_responses      rK   sentry_patched_get_responsez8_patch_get_response.<locals>.sentry_patched_get_response  s&     	W%dG,G$	rL   get_response_async)patch_get_response_asyncN)rc   r3   r   r9   rE   z"Union[HttpResponse, BaseException])django.core.handlers.baser   get_responser   r   r   r   )r   r   r   r   s      @rK   r   r     sY     6"//+	-  ;K{01P .BC 2rL   c                      d fd}|S )Nc                 <           }|| S t         d u}|rt        |      t         k(  r| S t               5  t        |      j	                  |        d d d        t               r!t               5  t        ||        d d d        | S | S # 1 sw Y   6xY w# 1 sw Y   | S xY wrG   )r&   typer   DjangoRequestExtractorextract_into_eventr   _set_user_info)r   r   r   django_3weak_requests       rK   wsgi_request_event_processorzH_make_wsgi_request_event_processor.<locals>.wsgi_request_event_processor  s     .?Ld*W4L(* 	F"7+>>uE	F #$,. /w./ u	F 	F/ s   B,BBB)r   r?   r   zdict[str, Any]rE   r?   r   )r   rt   r   s   `  rK   r   r     s    , ('rL   c                 b   t        j                         }|j                  t              }|y | :|j                  dk(  r+t        j
                         }t        | ||j                         t        t        j                         |j                  ddd      \  }}t        j                  ||       y )NrO   rR   F)r   handled)client_options	mechanism)r   )rl   rm   rn   rQ   rU   r   r   r   sysry   optionscapture_event)r   r   clientrt   r   r   r   s          rK   r   r     s    ""$F(():;K{<<E,,.w{/L/LM&~~#6KE4
 U.rL   c                   X    e Zd ZddZddZddZdefdZddZddZ	d	d
de
fdZddZy)r   rE   Nc                 h    	 |j                         }||}|| _        y # t        $ r
 Y || _        y w xY wrG   )r   AttributeErrorr   )rc   r   drf_requests      rK   rd   zDjangoRequestExtractor.__init__  sD    	!==?K&%   		s    	11c                 .    | j                   j                  S rG   )r   METArc   s    rK   envzDjangoRequestExtractor.env#      ||   rL   c                     t         j                  t         j                  g}i }| j                  j                  j                         D ]  \  }}||v r
t        ||<   |||<    |S rG   )django_settingsCSRF_COOKIE_NAMESESSION_COOKIE_NAMEr   COOKIESitemsr   )rc   privacy_cookiesclean_cookieskeyvals        rK   cookieszDjangoRequestExtractor.cookies&  sn    ,,//

 BD,,224 	)HCo%%>c"%(c"		) rL   c                 .    | j                   j                  S rG   )r   bodyr  s    rK   raw_datazDjangoRequestExtractor.raw_data5  r  rL   c                 .    | j                   j                  S rG   )r   POSTr  s    rK   formzDjangoRequestExtractor.form8  r  rL   c                 .    | j                   j                  S rG   )r   FILESr  s    rK   fileszDjangoRequestExtractor.files;  s    ||!!!rL   filer3   c                     |j                   S rG   )size)rc   r%  s     rK   size_of_filez#DjangoRequestExtractor.size_of_file>  s    yyrL   c                 x    	 | j                   j                  S # t        $ r t        j                  |       cY S w xY wrG   )r   datar   r   parsed_bodyr  s    rK   r+  z"DjangoRequestExtractor.parsed_bodyA  s7    	6<<$$$ 	6#//55	6s    99)r   zUnion[WSGIRequest, ASGIRequest]rE   N)rE   r   )rE   z%Dict[str, Union[str, AnnotatedValue]])rE   r;   )rE   r<   )rE   zOptional[Dict[str, Any]])r   r   r   rd   r  r  bytesr  r!  r$  intr(  r+  r   rL   rK   r   r     s?    !!% !!" 3 6rL   r   c                    |j                  di       }t        | dd       }|t        |      sy 	 |j                  dt        |j                               	 |j                  d|j                         	 |j                  d|j                                y # t
        $ r Y Jw xY w# t
        $ r Y <w xY w# t
        $ r Y y w xY w)Nuserr   emailusername)
setdefaultr   rI   ra   pkr   r0  get_username)r   r   	user_infor/  s       rK   r   r   H  s      ,I7FD)D|+D1T3tww<0Wdjj1Z):):)<=  
  
  s5   %B B" 2 B1 	BB"	B.-B.1	B=<B=c                  B  	
 	 ddl m}  	 ddlm} 	 | j                  	| j                  
|j                  |j                  |j                  t        t        	      	 d	 	 	 	 	 	 	 d	fd       }t        t        
      	 	 	 	 	 	 	 	 d
fd       }t        t              dfd       }dfd}dfd	}|| _        || _        ||_	        ||_
        ||_        t        d
       y# t        $ r	 ddlm}  Y w xY w# t        $ r	 ddlm} Y w xY w# t        $ r Y yw xY w)z9If installed this causes Django's queries to be captured.r   )CursorWrapper)BaseDatabaseWrapperNc                    t        | j                  ||ddt        j                        5 }t	        ||         | ||      }d d d        t               5  t               d d d        S # 1 sw Y   )xY w# 1 sw Y   S xY w)NformatFcursorqueryparams_list
paramstyleexecutemanyrh   r   r<  rQ   r   _set_db_datar   r   )rc   sqlparamsspanresultreal_executes        rK   executez!install_sql_hook.<locals>.executex  s      ;;)33
 		5 t$!$V4F		5 )* 	#T"	# 		5 		5	#    A*A6*A36B c                    t        | j                  ||ddt        j                        5 }t	        ||         | ||      }d d d        t               5  t               d d d        S # 1 sw Y   )xY w# 1 sw Y   S xY w)Nr:  Tr;  rA  )rc   rC  
param_listrE  rF  real_executemanys        rK   r@  z%install_sql_hook.<locals>.executemany  s      ;;")33
 
	= t$%dC<F
	= )* 	#T"	# 
	= 
	=	# rI  c                 ,   t               5  t        j                  dd       d d d        t        j                  t        j
                  dt        j                        5 }t        ||         |       cd d d        S # 1 sw Y   [xY w# 1 sw Y   y xY w)Nr   r=  )messagecategoryopnamero   )	r   rl   add_breadcrumb
start_spanr   DBrQ   r   rB  )rc   rE  real_connects     rK   r   z!install_sql_hook.<locals>.connect  s    (* 	K%%i'J	K ""uu$..
 	& t$%	& 	&	K 	K	& 	&s   A> B
>B
Bc                 t   t        j                         j                  t              }||j                  s |       S t        j
                  t        j                  t        j                  t        j                        5 }t        || t        j                          |       cd d d        S # 1 sw Y   y xY wNrP  )rl   rm   rn   rQ   rY   rT  r   rU  r   	DB_COMMITr   rB  )rc   rt   rE  real_commits      rK   _commitz!install_sql_hook.<locals>._commit  s     ++-==>OPk&F&Ft$$""uu##$..
 	% tX%7%78t$	% 	% 	%   #B..B7c                 t   t        j                         j                  t              }||j                  s |       S t        j
                  t        j                  t        j                  t        j                        5 }t        || t        j                          |       cd d d        S # 1 sw Y   y xY wrX  )rl   rm   rn   rQ   rY   rT  r   rU  r   DB_ROLLBACKr   rB  )rc   rt   rE  real_rollbacks      rK   	_rollbackz#install_sql_hook.<locals>._rollback  s     ++-==>OPk&F&F &&""uu%%$..
 	' tX%9%9: &	' 	' 	'r\  zdjango.db.backendsrG   )rc   r7  rC  r3   rD  zOptional[Any]rE   r3   )rc   r7  rC  r3   rK  z	List[Any]rE   r3   )rc   r8  rE   N)django.db.backends.utilsr7  r   django.db.backends.utildjango.db.backendsr8  django.db.backends.base.baserH  r@  r   r[  r`  r
  r   rQ   r   )r7  r8  rH  r@  r   r[  r`  rZ  rV  rG  rL  r_  s          @@@@@rK   r   r   `  si   ::E:
$,,(44*22)11+55
   1<@EI$)3B	 A&   13CD$)7B	 E(   1<@
& A
&%' $M +M")")$-!&'W  :9:  EDE  s3   C( C= <D (C:9C:=DD	DDc                    t        |d      r|j                  n|}|j                  }| j                  t        j
                  |       | | j                  t        j                  |       t        |d      xrA t        |j                  d      xr) t        j                  |j                  j                        }|r|j                  j                         }nz	 |j                  j                  j                  |j                  j                  j                  d}|j                  j                  j                  }|r|j                  d      s||d<   |j%                  d      xs |j%                  d      }| | j                  t        j&                  |       |j%                  d      }	|	 | j                  t        j(                  |	       |j%                  d	      }
|
)| j                  t        j*                  t-        |
             |j%                  d
      }|!| j                  t        j.                  |       y y # t         $ r |j#                         }Y w xY w)Ndb
connectionget_dsn_parameters)dbnameport/hostri  databaserj  unix_socket)r   rf  vendorset_datar   	DB_SYSTEMDB_OPERATIONrg  inspect	isroutinerh  infori  rj  rl  
startswithr   get_connection_paramsr   DB_NAMESERVER_ADDRESSSERVER_PORTra   SERVER_SOCKET_ADDRESS)rE  cursor_or_dbdb_operationrf  ro  is_psycopg2connection_paramspg_hostdb_nameserver_addressserver_portserver_socket_addresss               rK   rB  rB    s    $L$7\BYYFMM($$f-h++\: 	l+ 	JL++-AB	Jl55HHI 
 (33FFH	;
 '1166==$//4499! #--2277Gw11#6,3!&)  ##H-R1B1F1Fz1RGh&&0&**62N!h--~>#''/Kh**C,<=-11-@(h446KL )!  	; " 8 8 :	;s   A9H9 9IIc                  F    	 ddl m}  t        |        y # t        $ r Y y w xY w)Nr   BaseContext)django.template.contextr  r
   r   r  s    rK   r   r   
  s$    7{+ s    	  r   )r   r9   rE   N)r   zCallable[[], WSGIRequest]rt   rQ   rE   rA   rG   )r   r9   r   r3   rE   N)r   r9   r   r?   rE   N)rE  r=   r|  r3   r}  zOptional[str]rE   N)zrs  r  	threadingr   	importlibr   rl   sentry_sdk.constsr   r   r   sentry_sdk.scoper   r   sentry_sdk.serializerr	   r
   sentry_sdk.tracingr   r   sentry_sdk.tracing_utilsr   r   sentry_sdk.utilsr   r   r   r   r   r   r   r   r   r   sentry_sdk.integrationsr   r   r   sentry_sdk.integrations.loggingr   sentry_sdk.integrations.wsgir   $sentry_sdk.integrations._wsgi_commonr   r   rR   r    r   rj   r"   r  django.corer#   django.urlsr$   r   django.core.urlresolversr%   r   r&   r   +sentry_sdk.integrations.django.transactionsr'   (sentry_sdk.integrations.django.templatesr(   r)   )sentry_sdk.integrations.django.middlewarer*   /sentry_sdk.integrations.django.signals_handlersr+   $sentry_sdk.integrations.django.tasksr,   $sentry_sdk.integrations.django.viewsr-   &sentry_sdk.integrations.django.cachingr1   typingr2   r3   r4   r5   r6   r7   r8   r   r9   django.http.responser:   django.http.requestr;   django.utils.datastructuresr<   r=   r>   sentry_sdk._typesr?   r@   rA   rB   r   rI   r]   rQ   r   Lockr   r   r   r   ra   r   r   r   r   r   r   r   r   r   r   rB  r   r   rL   rK   <module>r     su    
   #  4 4 P S B I   V U 9 =
/07#$5'9+
9 H O I < <"1DM  51-:'<QQ G/u / /
-u - - 4 k k\  ).."4=n200*((25(@M(	(V HH#5HJMH	HJD0(-(<O((8/$,6- ,6^0o(f HL5M
5M %5M5D5M	5MpC  5445
  9889    /
-
../sf   <H G G( #G: G%!H $G%%H (G73H 6G77H :HH HH H