
    VhZ                    <   d dl mZ 	 d dlZd dlZd dlZd dlZd dlZd dlmZm	Z	 d dl
mZmZmZmZ d dlmZmZmZmZ d dlZddlmZ ddlmZ erd dlZd d	lmZ dd
lmZ ddlmZ dtdZ ej>                  e       Z!ejD                  jG                  e d      Z$ G d de%      Z& G d de&      Z' G d de&      Z( G d de(      Z) G d de(      Z* G d de(      Z+ G d de(      Z, G d de&      Z- G d de&      Z. G d  d!e&      Z/ G d" d#e&      Z0 G d$ d%e&      Z1 G d& d'e1      Z2 G d( d)e&      Z3 G d* d+e3      Z4 G d, d-e&      Z5 G d. d/e3      Z6 G d0 d1e3      Z7 G d2 d3e3      Z8 G d4 d5e3      Z9 G d6 d7e6      Z: G d8 d9e	      Z; G d: d;e3      Z< G d< d=e&      Z= G d> d?e3      Z> G d@ dAe&      Z? G dB dCe&      Z@ G dD dEeA      ZB G dF dGeA      ZC G dH dIe&      ZD G dJ dKeD      ZE G dL dMeD      ZF G dN dOeF      ZG G dP dQeF      ZH G dR dSeD      ZI G dT dUeD      ZJ G dV dWeD      ZK G dX dYeD      ZL G dZ d[eD      ZMeNeEeOeFePeGeQeIeReHeSeJe%eKeTeLeUeMi	ZVdud\ZWddd]	 	 	 	 	 	 	 	 	 dvd^ZXdwd_ZYej                  j                  j                  ej                  j                  j                  ej                  j                  j                  ej                  j                  j                  fZ`	 	 	 	 	 	 	 	 dxd`Za eb       Zcecdda	 	 	 	 	 	 	 dydbZd	 	 	 	 	 	 	 	 	 	 	 	 	 	 dzdcZe	 	 	 	 	 	 	 	 	 	 d{ddZfecdedf	 	 	 	 	 	 	 	 	 	 	 	 	 d|dgZgd}dhZh G di dj      Zid~ddkZj	 	 	 	 	 	 ddlZkddmZl	 d	 	 	 	 	 ddnZmddoZnddpZoddqZp	 	 d	 	 	 	 	 	 	 	 	 ddrZq	 	 d	 	 	 	 	 	 	 	 	 ddsZry)    )annotationsN)autoEnum)extract_stack
format_excformat_listStackSummary)AnyNoReturnOptionalTYPE_CHECKING   )config)counters)	CompileId)InstructionTranslatorBase)DynamoFrameTypec                ,    d| j                  dd      z   S )NzhFor more information about this error, see: https://pytorch.org/docs/main/generated/exportdb/index.html#_-)replace	case_names    A/home/dcms/DCMS/lib/python3.12/site-packages/torch/_dynamo/exc.pyexportdb_error_messager   5   s"    	I


C
%	&    graph_breaksc                      e Zd Zy)TorchDynamoExceptionN__name__
__module____qualname__ r   r   r   r   A       r   r   c                      e Zd Zy)InternalTorchDynamoErrorNr    r$   r   r   r'   r'   E   r%   r   r'   c                  2     e Zd ZU ded<   ddd fdZ xZS )RestartAnalysisOptional[str]restart_reasonN)r+   c               ,    || _         t        |   |  y N)r+   super__init__)selfr+   args	__class__s      r   r/   zRestartAnalysis.__init__L   s    ,$r   )r1   r
   r+   r*   returnNoner!   r"   r#   __annotations__r/   __classcell__r2   s   @r   r)   r)   I   s    !!CG    r   r)   c                      e Zd Zy)SpeculationRestartAnalysisNr    r$   r   r   r:   r:   Q   r%   r   r:   c                      e Zd Zy)UnspecializeRestartAnalysisNr    r$   r   r   r<   r<   U   r%   r   r<   c                      e Zd Zy) CompileCollectiveRestartAnalysisNr    r$   r   r   r>   r>   Y   r%   r   r>   c                      e Zd Zy)TensorifyScalarRestartAnalysisNr    r$   r   r   r@   r@   ]   r%   r   r@   c                      e Zd Zy)	SkipFrameNr    r$   r   r   rB   rB   a   r%   r   rB   c                      e Zd Zy)TorchRuntimeErrorNr    r$   r   r   rD   rD   e   r%   r   rD   c                        e Zd Zd fdZ xZS )InvalidBackendc                ,    t         |   d|d       y )NzInvalid backend: z=, see `torch._dynamo.list_backends()` for available backends.r.   r/   )r0   namer2   s     r   r/   zInvalidBackend.__init__j   s    x'de	
r   )rI   strr3   r4   r!   r"   r#   r/   r7   r8   s   @r   rF   rF   i   s    
 
r   rF   c                        e Zd Zd fdZ xZS )ResetRequiredc                J    t         |   t        j                  d             y )Nz
                Must call `torch._dynamo.reset()` before changing backends.  Detected two calls to
                `torch.compile()` with a different backend compiler arguments.
                )r.   r/   textwrapdedent)r0   r2   s    r   r/   zResetRequired.__init__q   s!    OO	
r   r3   r4   rK   r8   s   @r   rM   rM   p   s    
 
r   rM   c                  8     e Zd Z	 	 	 	 	 	 	 	 d fdZddZ xZS )ShortenTracebackc               2    t        |   |i | || _        y r-   )r.   r/   first_useful_frame)r0   rU   r1   kwargsr2   s       r   r/   zShortenTraceback.__init__}   s     	$)&)"4r   c                   | j                   }| j                  |t        j                  r| S |j                  | j                  ur.|j
                  }|J d       |j                  | j                  ur.| j                  |      S )Nz#internal error, please report a bug)__traceback__rU   r   verbosetb_frametb_nextwith_traceback)r0   tbs     r   remove_dynamo_framesz%ShortenTraceback.remove_dynamo_frames   sz    ""*bjFNNKkk!8!88B>H#HH> kk!8!88 ""2&&r   )r1   r
   rU   Optional[types.FrameType]rV   r
   r3   r4   )r3   ztyping.Self)r!   r"   r#   r/   r^   r7   r8   s   @r   rS   rS   |   s-    55.G5SV5	5'r   rS   c                  0     e Zd Z	 	 	 	 	 	 	 	 d fdZ xZS )BackendCompilerFailedc                    t        |dd      | _        || _        d| j                  dt        |      j                   d| }t
        |   ||       y )Nr!   ?zbackend=z	 raised:
z: )rU   )getattrbackend_nameinner_exceptiontyper!   r.   r/   )r0   
backend_fnrf   rU   msgr2   s        r   r/   zBackendCompilerFailed.__init__   s_     $J
C@.**-Z_8M8V8V7WWYZiYjk1CDr   )rh   r
   rf   	ExceptionrU   r_   r3   r4   rK   r8   s   @r   ra   ra      s9    	E	E #	E 6		E
 
	E 	Er   ra   c                  8     e Zd Zddd fdZddZdd	dZ xZS )
UnsupportedNr   c                   t         |   |       t        j                  j                  j                         | _        || _        d | _        | j                          || _
        y r-   )r.   r/   torch_guardsTracingContextr   
real_stackri   categoryadd_to_statsr   )r0   ri   r   r2   s      r   r/   zUnsupported.__init__   sK    --66DDF'+(1r   c                    | j                   J t        | j                      | j                  xx   dz  cc<   t        | j                      | j                     dk  rt        | j                      | j                  = y y )Nr   r   rr   r   ri   r0   s    r   remove_from_statszUnsupported.remove_from_stats   sc    }}((()Q.)DMM"488,1'1 2r   c                N    || _         t        |   | j                  xx   dz  cc<   y )Nr   ru   )r0   rr   s     r   rs   zUnsupported.add_to_stats   s"     488$)$r   )ri   rJ   r   r*   r3   r4   rQ   )unimplemented)rr   rJ   r3   r4   )r!   r"   r#   r/   rw   rs   r7   r8   s   @r   rl   rl      s    ?C 22* *r   rl   c                      e Zd Zy)$UnknownPropertiesDuringBackwardTraceNr    r$   r   r   r{   r{      r%   r   r{   c                      e Zd Zy)RecompileErrorNr    r$   r   r   r}   r}      r%   r   r}   c                        e Zd Zd fdZ xZS )ArgsMismatchErrorc                $    t         |   |       y r-   rH   r0   ri   r2   s     r   r/   zArgsMismatchError.__init__       r   ri   rJ   r3   r4   rK   r8   s   @r   r   r           r   r   c                        e Zd Zd fdZ xZS )AttributeMutationErrorc                $    t         |   |       y r-   rH   r   s     r   r/   zAttributeMutationError.__init__   r   r   r   rK   r8   s   @r   r   r      r   r   r   c                        e Zd Zd fdZ xZS )InfiniteGeneratorErrorc                $    t         |   |       y r-   rH   r   s     r   r/   zInfiniteGeneratorError.__init__   r   r   r   rK   r8   s   @r   r   r      s     r   r   c                        e Zd Zd fdZ xZS )SideEffectsErrorc                $    t         |   |       y r-   rH   r   s     r   r/   zSideEffectsError.__init__   r   r   r   rK   r8   s   @r   r   r      r   r   r   c                  $     e Zd ZdZd fdZ xZS )CondOpArgsMismatchErrorz?
    Internal error from cond() due to arguments mismatch.
    c                $    t         |   |       y r-   rH   r   s     r   r/   z CondOpArgsMismatchError.__init__   r   r   r   )r!   r"   r#   __doc__r/   r7   r8   s   @r   r   r      s     r   r   c                  |    e Zd Z e       Z e       Z e       Z e       Z e       Z e       Z	 e       Z
 e       Zy)UserErrorTypeN)r!   r"   r#   r   DYNAMIC_CONTROL_FLOWANTI_PATTERNSTANDARD_LIBRARYCONSTRAINT_VIOLATIONDYNAMIC_DIMINVALID_INPUTINVALID_OUTPUT*UNSUPPORTED_ALIASED_MUTATED_DYNAMIC_INPUTSr$   r   r   r   r      s>    66Lv6&KFMVN15.r   r   c                  2     e Zd Z	 d	 	 	 	 	 	 	 d fdZ xZS )	UserErrorc                    |<t        |t              sJ |j                  d      r|dz  }n|dz  }|t        |      z  }t        |   |       || _        || _        y)aG  
        Type of errors that would be valid in Eager, but not supported in TorchDynamo.
        The error message should tell user about next actions.

        error_type: Type of user error
        msg: Actionable error message
        case_name: (Optional) Unique name (snake case) for the usage example in exportdb.
        N. 
)
isinstancerJ   endswithr   r.   r/   
error_typemessage)r0   r   ri   r   r2   s       r   r/   zUserError.__init__   sd      i---||C s
t))44C$r   r-   )r   r   ri   rJ   r   r*   r3   r4   rK   r8   s   @r   r   r      s0    NR'.1>K	 r   r   c                      e Zd Zy)SkipCodeRecursiveExceptionNr    r$   r   r   r   r      r%   r   r   c                      e Zd Zy)RecompileLimitExceededNr    r$   r   r   r   r      r%   r   r   c                      e Zd Zy)UnsafeScriptObjectErrorNr    r$   r   r   r   r      r%   r   r   c                      e Zd Zy)UncapturedHigherOrderOpErrorNr    r$   r   r   r   r     r%   r   r   c                      e Zd Zy)IncorrectUsageNr    r$   r   r   r   r     r%   r   r   c                      e Zd Zy)FailOnRecompileLimitHitNr    r$   r   r   r   r     r%   r   r   c                      e Zd Zy)ObservedExceptionNr    r$   r   r   r   r         r   r   c                  ,     e Zd ZU ded<   d fdZ xZS )ObservedUserStopIterationzOptional[Any]valuec                d    t         |   d       t        |      dkD  r|d   | _        y d | _        y )Nzunhandled `raise StopIteration`r   )r.   r/   lenr   )r0   r1   rV   r2   s      r   r/   z"ObservedUserStopIteration.__init__  s.    :;t9q=aDJDJr   )r1   r
   rV   r
   r3   r4   r5   r8   s   @r   r   r     s     r   r   c                      e Zd Zy)ObservedLookupErrorNr    r$   r   r   r   r   %  r   r   r   c                      e Zd Zy)ObservedIndexErrorNr    r$   r   r   r   r   *  r   r   r   c                      e Zd Zy)ObservedKeyErrorNr    r$   r   r   r   r   /  r   r   r   c                      e Zd Zy)ObservedGeneratorExitNr    r$   r   r   r   r   4  r%   r   r   c                      e Zd Zy)ObservedAttributeErrorNr    r$   r   r   r   r   8  r   r   r   c                      e Zd Zy)ObservedRuntimeErrorNr    r$   r   r   r   r   =  r   r   r   c                      e Zd Zy)ObservedNotImplementedErrorNr    r$   r   r   r   r   B  r%   r   r   c                      e Zd Zy)ObservedTypeErrorNr    r$   r   r   r   r   F  r   r   r   c                    | t         vr3t        | dt        |             }t        d| dt        fi       t         | <   t         |    S )Nr!   ObservedError)observed_exception_maprd   rJ   rg   r   )exc_typerI   s     r   get_dynamo_observed_exceptionr   X  sN    --xS];+/tfE"%6$8",
x( "(++r   )r1   rV   c                   ddl m}  ||       j                  ||xs g |xs i       }|j                  j	                  |       t
        |    )Nr   )BuiltinVariable)	variablesr   call_functionexn_vt_stackset_current_exceptionr   )r   txr1   rV   r   exception_vts         r   raise_observed_exceptionr   a  sH     + #8,::2tzr6<UWXLOO)),7
 
**r   c                8    | j                   j                          y r-   )r   clear_current_exception)r   s    r   handle_observed_exceptionr   q  s    2 OO++-r   c                    t        | |      t        j                  j                  dd fd       t        j                  d       t        j                  |       t        ||        y )Nartifactc                     dddS Ndynamo_graph_break_reasonstring)rI   encodingr$   r$   r   r   <lambda>z,unimplemented_with_warning.<locals>.<lambda>      / 
 r   c                      S r-   r$   graph_break_msgs   r   r   z,unimplemented_with_warning.<locals>.<lambda>      ? r   metadata_fn
payload_fn%s)from_exc)	format_error_msg_verbosern   _loggingtrace_structuredgraph_breaks_logdebuglogwarningry   )ecoderi   r   s      @r   unimplemented_with_warningr     s]     /q$7O	NN##
 + $  41KK#"r   )r   r   c                   | t         j                  j                  dd      k7  sJ |t        urt	        | |      |t	        | |      )NBREAKFr   )osenvironget_NOTHINGrl   )ri   r   r   s      r   ry   ry     sE     "**..%0000x#3A
cY
//r   c                    t        | |      t        j                  j                  dd fd       t        j                  d       t        ||||| d       y )Nr   c                     dddS r   r$   r$   r   r   r   z/unimplemented_v2_with_warning.<locals>.<lambda>  r   r   c                      S r-   r$   r   s   r   r   z/unimplemented_v2_with_warning.<locals>.<lambda>  r   r   r   r   Tr   log_warning)r   rn   r   r   r   r   unimplemented_v2)r   r   gb_typecontextexplanationhintsr   s         @r   unimplemented_v2_with_warningr    sZ     /q$7O	NN##
 + $  41Wg{EASWXr   c                    t        j                  |d      j                         }dj                  d |D              }t        j                  |d      j                         }|  d| d| d| d}|S )N    r   c              3  j   K   | ]+  }d t        j                  |d      j                         z    - yw)z  Hint: r
  N)rO   indentlstrip).0hints     r   	<genexpr>z-format_graph_break_message.<locals>.<genexpr>  s.      @D
X__T6299;;s   13z
  Explanation: z

  Developer debug context: )rO   r  r  join)r  r  r  r  	hints_strri   s         r   format_graph_break_messager    s     //+v6==?K		 HM I oogv.557G 		 
} 
 #9 %C Jr   Fr  c                   t        | |||      }|rt        j                  |       |t        urt	        |      |t	        |      )a  
    Called within dynamo to cause a graph break.
    Args:
        gb_type: Context-free graph break type. It should be a short string without any
                 information specific to the tracing context (i.e. no dynamically-generated strings)
        context: Developer context for the graph break. It can contain tracing context/dynamic strings.
        explanation: User-facing context-dependent explanation for the graph break. Can be dynamic.
        hints: List of user-facing hints for the graph break.
    )r  r   r   r   rl   )r  r  r  r  r   r  ri   s          r   r  r    sC    & %Wg{E
JCCx#H,
c
r   c                v    t         d   | xx   dz  cc<   | t        j                  j                  dd      k7  sJ y )Nwarningsr   r   F)r   r   r   r   )ri   s    r   r   r     s4    Z""**..%0000r   c                  $    e Zd ZddZddZddZy)KeyErrorMsgc                    || _         y r-   )r   )r0   r   s     r   r/   zKeyErrorMsg.__init__  s	    
r   c                ,    t        | j                        S r-   )rJ   r   rv   s    r   __str__zKeyErrorMsg.__str__  s    4::r   c                "    | j                         S r-   )r  rv   s    r   __repr__zKeyErrorMsg.__repr__  s    ||~r   N)r   r
   r3   r4   )r3   rJ   )r!   r"   r#   r/   r  r  r$   r   r   r  r    s    r   r  c                   dd l }d | _        t        |       }|>t        |      dkD  r0|d   | _        |ddj	                  |j                  |             z  }t        j                  r,t        | d      r |d| j                   d| j                   dz  }t        j                  st        | d	      r|d
z  }t        | d      r~t        | j                  d      rht        | j                  d      r5|d| j                  j                   d| j                  j                   dz  }n|d| j                  j                   dz  }t        | j                        dk(  rdnt        | j                  d         }t!        | t"              r%t%        ||z         f| j                  dd  z   | _        y ||z   }|f| j                  dd  z   | _        y )Nr   z
from user code:
  record_filenamez!
Last frame execution written to zD. To run only this frame while debugging, run torch._dynamo.replay('z').
rq   z
Set TORCHDYNAMO_VERBOSE=1 for the internal stack trace (please do this especially if you're reporting a bug to PyTorch). For even more developer context, set TORCH_LOGS="+dynamo"
rf   minifier_pathbuck_commandz
Minifier script written to zW. Run this buck command to find the smallest traced graph which reproduces this error: r   zQ. Run this script to find the smallest traced graph which reproduces this error.
r   )	tracebackinnermost_user_frame_summaryget_real_stackr   r  r   r   replay_record_enabledhasattrr!  rY   rf   r"  r#  r1   rJ   r   KeyErrorr  )excri   exportr$  rq   old_msgnew_msgs          r   augment_exc_messager.    s   '+C$$J#j/A"5+5b>(%bggi.C.CJ.O&P%QRR##5F(G01D1D0E F++,E3	

 >>gc<8J	
 s%&7_, 3&&7/0C0C0Q0Q/R S0030C0C0P0P/QQSUC /0C0C0Q0Q/R S_ _C
 MQ&bC,<G#x #.0388AB<?C-:,r   c                    d }d }| j                   ,| j                   j                  }| j                   j                  }|| _        ||fS r-   )r%  filenamelineno
compile_id)r   r2  r0  r1  s       r   get_exc_messager3  I  sN     HF%%111:://66ALVr   c                 (    t        t                     S r-   )filter_stackr   r$   r   r   get_stack_above_dynamor6  U  s    ((r   c                    t        | dd       }|y |t               }n
t               }t        j                  ||z         S )Nrq   )rd   r6  r	   	from_list)r*  framerq   stack_above_dynamos       r   r&  r&  Y  sM     lD1J  45)^!!"4z"ABBr   c                    t               }| D ]Z  }|j                  d|j                  v r |S d|j                  v s|j                  rd|j                  v rJ|j                  |       \ |S )Nconvert_frame
eval_frameztorch._dynamo.optimize()r	   r0  lineappend)stack
user_stackr9  s      r   r5  r5  z  sv    J 	!>>!enn,  5>>)JJ4

B% 	! r   c                h    ddl m} t        j                  | d|       }|r|j	                  d      S y )Nr   )TORCH_DYNAMO_RESUME_IN_PREFIXz_(\w+)_at_\d+)resume_executionrC  rematchgroup)rI   rC  rF  s      r   remove_resume_prefixrH    s2    ?HH56oFME{{1~r   c                    t               }| D ]X  }|j                  t        |j                        }|r!|r|d   j                  |k(  r||d<   ||_        H|j	                  |       Z |S )a1  
    When we graph break, we create a resume function and make a regular Python call
    to it, which gets intercepted by Dynamo. This behavior is normally shown in the
    traceback, which can be confusing to a user. So we can filter out resume frames
    for better traceback clarity.

    Example:
    File "..." line 3, in f
        <line 3>
    File "..." line 5, in torch_dynamo_resume_in_f_at_80
        <line 5>
    File "..." line 10, in torch_dynamo_resume_in_f_at_120
        <line 10>

    becomes
    File "..." line 10, in f
        <line 10>
    r  )r	   r0  rH  rI   r?  )r@  	new_stackr9  rI   s       r   collapse_resume_framesrK    sq    ( I $>>!#EJJ/)B-"4"4"<!IbMEJU#$ r   c                    d|j                    d|j                   d|j                   d}|dz  }|t               z  }t	        | |      }|,|dz  }|dj                  t        |            z  }|dz  }|dz  }|S )	NWON'T CONVERT r    line r   z.========== TorchDynamo Stack Trace ==========
zY
========== The above exception occurred while processing the following code ==========

r   z
==========)co_nameco_filenameco_firstlinenor   r&  r  r   )r*  r   r!  r9  ri   rq   s         r   r   r     s     a(8(8'9@S@S?TTVW  CCC:<CU+J	
 	rww{:.//txJr   c           	         t         j                  rt        | |||      S d|j                   d|j                   d|j
                   dt                S )NrM  r   rN  z 
due to: 
)r   rY   r   rO  rP  rQ  r   )r*  r   r!  r9  s       r   format_error_msgrS    sW     ~~'T?EJJDLL>4+;+;*< ==8 8r   )r   rJ   r3   rJ   )r   type[Exception]r3   ztype[ObservedException])
r   rT  r   r   r1   zOptional[list[Any]]rV   zOptional[dict[str, Any]]r3   r   )r   r
   r3   r4   )r   rj   r   types.CodeTyperi   rJ   r3   r   )ri   rJ   r   r
   r   r*   r3   r   )r   rj   r   rU  r  rJ   r  rJ   r  rJ   r  	list[str]r3   r   )
r  rJ   r  rJ   r  rJ   r  rV  r3   rJ   )r  rJ   r  rJ   r  rJ   r  rV  r   r
   r  boolr3   r   r   )r   F)r*  rj   ri   rJ   r+  rW  r3   r4   )r   rj   r2  r   r3   z#tuple[Optional[str], Optional[int]])r3   r	   r-   )r*  rj   r9  Optional[DynamoFrameType]r3   zOptional[StackSummary])r@  r	   r3   r	   )rI   rJ   r3   r*   )NN)
r*  rj   r   rU  r!  r*   r9  rX  r3   rJ   )s
__future__r   loggingr   rE  rO   typingenumr   r   r$  r   r   r   r	   r
   r   r   r   torch._guardsrn   r   r   utilsr   typesr   symbolic_convertr   r   r   	getLoggerr!   r   r   getArtifactLoggerr   RuntimeErrorr   r'   r)   r:   r<   r>   r@   rB   rD   rF   rM   rS   ra   rl   r{   r}   r   r   r   r   r   r   r   r   r   r   r   rj   r   r   r   r   r   r   r   r   r   r   r   r   StopIterationLookupError
IndexErrorGeneratorExitr)  AttributeErrorNotImplementedError	TypeErrorr   r   r   r   _subclassesfake_tensorDataDependentOutputExceptionDynamicOutputShapeExceptionUnsupportedOperatorExceptionUnsupportedFakeTensorException!exceptions_allowed_to_be_fallbackr   objectr   ry   r  r  r  r   r  r.  r3  r6  r&  r5  rH  rK  r   rS  r$   r   r   <module>rs     sW   "2  	 	    J J 9 9    ';& g!>>33HnM 	< 		3 	 *  	 		/ 		 		_ 		$ 		, 	
) 
	
( 	
'+ '"
E, 
E*& *(	; 		) 	 
[ 
[ { 
/ 8D 8 0	!5 		[ 		2 		#7 		Y 		i 		, 	
 1 	+ 	
	, 	
	* 	
	- 		. 	
	, 	
	"3 		) 	 ,$"(*&4 
 , !%'+++!+ 	+
 %+ + .< 
!!>>	!!==	!!>>	!!@@	% !##&#-0##0 8 "*d0	006C00YY
Y Y 	Y
 Y Y Y8  	
 	:   	   61 ,-^		'	(	)
 8<C	C4CCB J &*'+		
 # %	
 	< &*'+		8		8
	8 #	8 %		8
 		8r   