
    i                        U d dl Z d dlZd dlZd dlZd dlZd dl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 d dlmZmZmZmZ d dlmZ d dlmZmZ eeeed         f                  ZdefdZ	  e            rej                            d	           d
Zn# e$ r dZY nw xY wej        j         Z!ej                            d e!          Z"dddddddddddddZ#e$e%eee%f         f         e&d<   d dddddddZ'e$e%eee%f         f         e&d<   d Z(dZ)dZ*dZ+dZ,dZ-dZ.e(e)e*e+e,fZ/e(e)e*e+e,e-fZ0e(e)e*e+e,e-e.fZ1 ej2        d          Z3 ej2        d          Z4dZ5d6                    e'7                                          Z8d6                    e#7                                          Z9 ej2        d           Z: ej2        d!e8 d"e8 d#e9 d"e9 d$	          Z; ej2        d%          Z< ej2        d&          Z= ej2        d'          Z>d(e/d)e0d*e1 e?e/          e/ e?e0          e0 e?e1          e1iZ@ e?e/          ZA e?e0          ZB e?e1          ZCd+ e@D             ZD eE            ZFd, ZGd*edefd-ZHd*ed.edefd/ZId0ej        d1ej        d2edefd3ZJd4ej        d5ej        dejK        fd6ZLd0ej        d1ej        d2edeMej        ef         fd7ZN G d8 d9eO          ZP G d: d;eQ          ZR G d< d=eP          ZS G d> d?eS          ZT G d@ dAeP          ZU G dB dCeS          ZV G dD dE          ZW	 	 	 	 	 	 dJdFZX G dG dH          ZYdIeYiZZdS )K    N)time)AnyLiteralOptionalUnion)relativedelta)datetime_existstzutc*lreturnc                      t          j        d          dz  } 	 t          j                    d         }n# t          $ r d}Y nw xY wt
          j        dk    }d}| dk    rd}n|rd	|v rd}n|rd}|S )
zu
    Detect if Python is running in 32-bit mode.
    Returns True if running on 32-bit Python, False for 64-bit.
    P   r   Nl        F    T32)structcalcsizeplatformarchitectureRuntimeErrorsysmaxsize)bitsr   is_small_maxsizeis_32s       X/home/ubuntu/.hermes/hermes-agent/venv/lib/python3.11/site-packages/croniter/croniter.pyis_32bitr      s     ?3!#D,..q1    {e+ Erzz	 $,..	 Ls   3 AAl   '\ FT                     r   	   
         )janfebmaraprmayjunjulaugsepoctnovdecM_ALPHAS)sunmontuewedthufrisat
DOW_ALPHASz^([^-]+)-([^-/]+)(/(\d+))?$z^\d+$)      r@      r@   rB   r@   r@   rB   r@   rB   r@   |z
^(\d+|\*)$z^(?P<pre>((?P<he>((z)(-(z))?)|((z))?)|\w+)#)|l)(?P<last>\d+)$z^(?:(\d+)w|w(\d+))$z[*]zW^(?P<hash_type>h|r)(\((?P<range_begin>\d+)-(?P<range_end>\d+)\))?(\/(?P<divisor>\d+))?$unixsecondyearc                 <    h | ]}t          |t                    |S  
isinstanceint).0as     r   	<setcomp>rN      s'    EEEa*Q2D2DEEEE    c                     | j         +|                     d           |                                 z
  } | t          j        ddd          z
                                  S )Ntzinfo  r    )rR   replace	utcoffsetdatetimetotal_secondsds    r   datetime_to_timestamprZ      sP    xIITI""Q[[]]2!$1---<<>>>rO   c                 8    | dz  dk    p| dz  dk    o| dz  dk    S )Ni  r   r#   d   rH   )rF   s    r   _is_leapr]      s*    #:?Atax1}@qArO   monthc                 Z    t           |dz
           }|dk    rt          |           r|dz  }|S )z=Calculate the last day of the given month (honor leap years).r    r!   )DAYSr]   )rF   r^   last_days      r   _last_day_of_monthrb      s0    EAIHzzhtnnzAOrO   dateprevious_dateis_prevc                     |r6|                      t                    |                     t                    k     S |                      t                    |                     t                    k    S )zKCheck if the given date is a successor (after/before) of the previous date.)
astimezoneUTC_DT)rc   rd   re   s      r   _is_successorri      sW      Jv&&)A)A&)I)III??6""]%=%=f%E%EEErO   date1date2c                 l    |                                  }|                                 }|J |J ||z
  S )z5Calculate the timezone difference of the given dates.)rU   )rj   rk   offset1offset2s       r   _timezone_deltaro      sC    ooGooGWrO   c                 B   t          |j        dd          }|ddl}	  || d          }n# |j        $ r@ 	 | t	          j        d          z  } 	  || d          }n# |j        $ r Y 4w xY w	 |dfcY S |j        $ r  || |           } || |          }|                    t                    |                    t                    k    |k    sJ t          |||          r|}nt          |||          sJ |}Y nw xY w|dfS | 
                    |rdnd|j        	          }t          |          s:t          |          s'|t	          j        d          z  }t          |          '|dfS | 
                    |rdnd|j        	          }|                                |                                k    rb|                    t                    |                    t                    k    |k    sJ t          |||          st          |||          sJ |}|dfS )
a=  Add the tzinfo from the previous date to the given date.

    In case the new date is ambiguous, determine the correct date
    based on it being closer to the previous date but still a successor
    (after/before based on `is_prev`).

    In case the date does not exist, jump forward to the next existing date.
    localizeNr   )is_dstTr    minutesF)foldrR   )getattrrR   pytzNonExistentTimeErrorrV   	timedeltaAmbiguousTimeErrorrg   rh   ri   rT   r	   rU   )rc   rd   re   rq   rw   resultcloserfarthers           r   _add_tzinfor~      s    }+Z>>H	!Xd4000FF( 	! 	! 	!*15555%Xd4888FF0   H5=   & 		! 		! 		!Xdw;777FhtG444G%%f--0B0B60J0JJwVVVVV]G<< !$WmWEEEEE 		! t|\\G2qq=;O\PPF6"" !&)) 	4h(3333F "&)) 	4u} llW 3!M<PlQQGW..0000!!&))G,>,>v,F,FF7RRRRV]G<< 	 -AAAAAF4<s:   , #DAD
A+(D*A++D5B	D Dc                       e Zd ZdZdS )CroniterErrorz)General top-level Croniter base exceptionN__name__
__module____qualname____doc__rH   rO   r   r   r      s        3333rO   r   c                       e Zd ZdZdS )CroniterBadTypeRangeError.Nr   rH   rO   r   r   r      s        GGGrO   r   c                       e Zd ZdZdS )CroniterBadCronErrorz>Syntax, unknown value, or range error within a cron expressionNr   rH   rO   r   r   r      s        HHHHrO   r   c                       e Zd ZdZdS )CroniterUnsupportedSyntaxErrorz;Valid cron syntax, but likely to produce inaccurate resultsNr   rH   rO   r   r   r      s        EEEErO   r   c                       e Zd ZdZdS )CroniterBadDateErrorz(Unable to find next/prev timestamp matchNr   rH   rO   r   r   r      s        2222rO   r   c                       e Zd ZdZdS )CroniterNotAlphaErrorz9Cron syntax contains an invalid day or month abbreviationNr   rH   rO   r   r   r     s        CCCCrO   r   c                      e Zd ZU dZdZi i ddi ej        e           ej        e          i i fZ	e
eeeeef         f         df         ed<   i i ddiddiddii i fZe
eeef         df         ed	<   d
Zdedddddddf	dedeeej        ef                  dededee         dedeeeef                  dedededdfdZed             ZdEdZdEdZdFdZ	 dGdeeej        ef                  dedefdZed ej        defd!            Z e Z!e"fd"ed#e#dej        fd$Z$e$Z%dHd%Z&dId&Z'dId'Z(d( Z)d) Z*e&xZ+Z,dedej        fd*Z-d+ej        d,e.e/         d-eee0e         f         dedej        f
d.Z1ed/             Z2ed0             Z3ed1ed2ed3ede
edf         fd4            Z4ed5             Z5ee6fd6            Z7d7d8d7d9d7d9d7d7d9d7d9d7d:Z8edJd;            Z9e	 	 	 	 	 dJdedeeeef                  ded<ee         d=ed>eeee.e         f                  de
e.e/         eee0e         f         f         fd?            Z:ed@             Z;edKdB            Z<e	 	 	 dLdC            Z=e	 	 	 dLdD            Z>dS )Mcroniterr*   )r   ;   )r      )r    r@   )r    r*   )r   r%   r   )rS   i3  r   .	ALPHACONVr   r    r&   LOWMAP)<      r@   r*   r&   r      NTFexpr_format
start_timeret_typeday_ormax_years_between_matchesre   hash_idimplement_cron_bugsecond_at_beginningexpand_from_start_timer   c                    || _         || _        || _        t          |	          | _        |
| _        |Ut          |t          t          f          st          d          t          |t                    s|
                    d          }|d u| _        |d}t          t          |          d          | _        |t                      }d | _        d| _        d| _        d| _        |                     |d           |                     ||| j        r| j        nd |	          \  | _        | _        | _        | _        t4          t7          | j                           | _        || _        d S )	N%hash_id must be bytes or UTF-8 stringUTF-82   r    g        Tforce)r   from_timestampr   )	_ret_type_day_or_implement_cron_bugboolr   _expand_from_start_timerJ   bytesstr	TypeErrorencode%_max_years_btw_matches_explicitly_setmaxrK   _max_years_between_matchesr   rR   r   dst_start_timecurset_current_expandexpandednth_weekday_of_monthexpressionsnearest_weekdayCRON_FIELDSlenfields_is_prev)selfr   r   r   r   r   re   r   r   r   r   s              r   __init__zcroniter.__init__!  sn    "#5 #'(;#<#< '=$gs|44 I GHHHgu-- 2!..115NVZ5Z2$,(*%*-c2K.L.La*P*P'J15!4000[_[g[g262NX4..TX 3	 \h \
 \
Xt0$2BDDX "#dm"4"45rO   c                     	 | j         |         |         S # t          $ r' t          dd                    |           d          w xY w)N[ z] is not acceptable)r   KeyErrorr   join)clsindexkeyr   s       r   
_alphaconvzcroniter._alphaconvR  s_    	X=',, 	X 	X 	X'(VCHH[,A,A(V(V(VWWW	Xs	    1Ac                 d    |r| j         rt          d          |                     ||d|          S )NzEstart_time is not supported when using expand_from_start_time = True.Fr   r   re   update_current)r   
ValueError	_get_nextr   r   r   r   s       r   get_nextzcroniter.get_nextY  sP     	$6 	W   ~~*eTb  
 
 	
rO   c                 4    |                      ||d|          S )NTr   )r   r   s       r   get_prevzcroniter.get_prevb  s'    ~~*dSa  
 
 	
rO   c                     |p| j         }t          |t          j                  r|                     | j                  S | j        S N)r   
issubclassrV   timestamp_to_datetimer   )r   r   s     r   get_currentzcroniter.get_currentg  s@    -t~h 122 	8--dh777xrO   r   c                     |s| j         R|Pt          |t          j                  r!|j        | _        |                     |          }|| _        || _        || _         | j         S r   )r   rJ   rV   rR   rZ   r   r   )r   r   r   s      r   r   zcroniter.set_currentm  sh      	"dh&Z-C*h&788 D(/!77
CC
(DO",D!DHxrO   rY   c                      t          |           S )zI
        Converts a `datetime` object `d` into a UNIX timestamp.
        )rZ   rX   s    r   rZ   zcroniter.datetime_to_timestampz  s    
 %Q'''rO   	timestamprR   c                 z   |t           u r| j        }t          r2t                              d          t          j        |          z   }nAt
          j                            |t                                                    d          }|r.|                    t                    
                    |          }|S )zG
        Converts a UNIX `timestamp` into a `datetime` object.
        NrQ   secondstz)MARKERrR   OVERFLOW32B_MODEEPOCHrT   rV   ry   fromtimestampr
   rh   rg   )r   r   rR   r{   s       r   r   zcroniter.timestamp_to_datetime  s     V[F 	a ]]$]//(2DY2W2W2WWFF&44Y5774KKSS[_S``F 	F^^6^22==fEEFrO   c                 l   |d}|                      |d           || j        }|| _        |p| j        }t          |t          t
          j        f          st          d          |                     |          }|                     |          }|r|| _	        t          |t
          j                  r|S |S )NTr   z;Invalid ret_type, only 'float' or 'datetime' is acceptable.)
r   r   r   r   floatrV   r   
_calc_nextrZ   r   )r   r   r   re   r   r{   r   s          r   r   zcroniter._get_next  s    !!N4000?mG-t~(UH,=$>?? 	[YZZZ))..v66	 	! DHh 122 	MrO   c              #      K   	 	 d| _         |                     |||          V  d}$# t          $ r | j        rY dS  w xY w)z
        Returns a generator yielding consecutive dates.

        May be used instead of an implicit call to __iter__ whenever a
        non-default `ret_type` needs to be specified.
        TFr   r   r   Nr   r   r   r   r   s       r   all_nextzcroniter.all_next  s      
	" %nn%*^ %      "
" $ 	 	 	9 	   %) ??c              #      K   	 	 d| _         |                     |||          V  d}$# t          $ r | j        rY dS  w xY w)z>
        Returns a generator yielding previous dates.
        Tr   Nr   r   s       r   all_prevzcroniter.all_prev  s      
	" $nn%*^ %      "
" $ 	 	 	9 	r   c                 ,    | j         r| j        n| j        S r   )r   r   r   )r   argskwargss      r   iterzcroniter.iter  s     $@t}}4=@rO   c                     | S r   rH   )r   s    r   __iter__zcroniter.__iter__  s    rO   c                    |                      | j                  }| j        d d          }| j                                        }|t
                   d         dk    r|t                   d         dk    r| j        r| j        rUt          
                    | j        t
                             s*t          
                    | j        t                             rns|t                   }dg|t          <   |                     ||||          }||t          <   dg|t
          <   |                     ||||          }|r
||k    r|n|S ||k     r|n|S |                     ||||          S )Nr   r   )r   r   r   r   copy	DAY_FIELD	DOW_FIELDr   r   re_starmatchr   _calc)r   re   currentr   r   bakt1t2s           r   r   zcroniter._calc_next  s[   ,,TX66=##8==?? Y"c))hy.A!.D.K.KQUQ].K ' -d.y9::-==!1)!<==- y)'*e#ZZ3GQQ&)#'*e#ZZ3GQQ 1!#b22b0"WWrr",zz'8-A7KKKrO   nowr   r   c                 N    r j         t          d          }n@ j        t                    t          k    rt          d          }nt          d          }|                    d           |z   }t                    t          k    r|                    d          }n|                    dd	          }|j        |j        x}fd
} fd}	 fd}
fd} fd} fd}fd}fd}fd}||	 j        r|n|
r|n||||g}t          |z
             j
        k    r?d}d}|D ]+} ||          \  }}|d} n|r|j        |j        cd} n,|rn	|rU|                    d          }|j        |S t          ||          \  }}|sPt          ||          rdt                   v r0|s.                     |          }t          ||          \  }}|.t!          ||          }|s|S |                    d           |z   }                     |          }t          ||          \  }}t          ||          s|S t          ||          r|S |S rt#          d          t#          d          )Nmicrosecondsr    r   rs   rQ   r   )microsecond)rE   r  c           
      h   t                    t          k    r	 t                                       d           nt# t          $ rg  | j        t                   d           }|d | fcY S |dk    r9r| t          |ddddd          z  } n| t          |ddddd          z  } d	| fcY S Y nw xY wd
| fS )Nr   r   r*   r@   r   r   )yearsr^   dayhourminuterE   r    TF)r   YEAR_CRON_LEN
YEAR_FIELDr   r   rF   r   )rY   	diff_yearr   re   nearest_diff_methods     r   	proc_yearz!croniter._calc.<locals>.proc_year  s	   8}}--'Z(..s3333! ' ' ' 3 3AFHZ<PRV W WI (#Qw A~~" &/rrSU^`" " " AA &/qaaPQZ[" " " A  $Qw &~' !8Os    < -B-+=B-,B-c           	         	 t                                        d           n# t          $ r  | j        t                    j                  }d}|i|dk    rcrD| t          |          z  } t          | j        | j                  }| t          |ddd          z  } n| t          ||ddd          z  } d	| fcY S Y nw xY wd
| fS )Nr   r    r   )monthsr   r   )r  r  r  rE   )r  r  r  r  rE   TF)MONTH_FIELDr   r   r^   MONTHS_IN_YEARr   rb   rF   )rY   
diff_month	reset_dayr   re   r  r   s      r   
proc_monthz"croniter._calc.<locals>.proc_month*  s   #%++C0000 # # #00GXk2D4G 
 	)jAoo ]*====$6qvqw$G$G	]yr"UWXXXX]#-91QWX     7NNN#  !8Os    $ BC ?C c                    	 t                                        d           n# t          $ r t                    }dt                    v r|| j        k    rd| fcY S rKdz
  
j        z  dz   }dk    rdz
  n}t          ||          } 	| j        t                    |          }n 	| j        t                    |          }|;|dk    r5r| t          |ddd	          z  } n| t          |ddd	          z  } d
| fcY S Y nw xY wd| fS )Nr   r   Fr!   r    r   r   r   daysr  r  rE   T)r   r   r   rb   r  r  r   )rY   r  
prev_month	prev_yeardays_in_prev_monthdiff_dayr   re   r^   r  r   rF   s         r   proc_day_of_monthz)croniter._calc.<locals>.proc_day_of_month?  s]   ##))#.... # # #)$66(9---$!%-- !8OOO U"'!)t/B!BQ!FJ,1QJJqDI);Iz)R)R&2215(9:MOabbHH2215(9:MtTTH'HMM V]r"UWXXXX]qSTUUUU7NNN%#& !8Os    $ 8DB%DDc                 D   	 t                                        d           nz# t          $ rm  |                                 dz  t                    d          }|;|dk    r5r| t	          |ddd          z  } n| t	          |ddd          z  } d| fcY S Y nw xY wd| fS )	Nr   r&   r   r   r   r  TF)r   r   r   
isoweekdayr   )rY   diff_day_of_weekr   re   r  s     r   proc_day_of_weekz(croniter._calc.<locals>.proc_day_of_weekW  s    	##))#.... # # ##6#6q||~~7I8T]K^`a#b#b #/4D4I4I ^]0@rRT]_````]0@qQR[\]]]]7NNN# !8Os    $ A2BBc                 R   dv rCd         }t          dd          D ]'}|v r|                             |           "||<   (d= g }                                D ]\  }}                    | j        | j        |          }|D ]_}|dk    r	|d         }nt          |          |k     r%||dz
           }r|| j        k    ss | j        |k    r|                    |           `|sTr| t          | j         ddd	          z  } n1t                    }	| t          |	| j        z
  dz   ddd	          z  } d
| fS |                                 r|d         n|d         | j        z
  }
|
dk    r3r| t          |
ddd	          z  } n| t          |
ddd	          z  } d
| fS d| fS )Nr   r   r&   r   r  r    r   r   r  TF)rangeupdateitems_get_nth_weekday_of_monthrF   r^   r   r  appendr   rb   sort)rY   si
candidateswdaynthcn	candidater  r   re   r^   r   r   rF   s              r   proc_day_of_week_nthz,croniter._calc.<locals>.proc_day_of_week_nthd  s,   ***(-q! 4 4A000,Q/66q999923,Q//(-J17799 
5 
5	c221617DII 5 5ACxx$%bE		Q! $%a!eH	 5I$6$6$6AEU^L^L^")))4445   \QUFBrRRRRAA-dE::DTAE\A-=QqYZ[[[[AQwOO*1D
2z!}MH1}} RH2bQSTTTTAAH1QqQQQQAQw!8OrO   c                 >   g }j         D ]R}                    | j        | j        |          }r|| j        k    ss | j        |k    r|                    |           S|sTr| t          | j         ddd          z  } n1t          	          }| t          || j        z
  dz   ddd          z  } d| fS |                                 r|d         n|d         | j        z
  }|dk    r3r| t          |ddd          z  } n| t          |ddd          z  } d| fS d| fS )	z1Process W (nearest weekday) day-of-month entries.r   r   r  r    r   Tr  F)	r   _get_nearest_weekdayrF   r^   r  r+  r   rb   r,  )
rY   r/  w_dayr4  r  r   re   r^   r   rF   s
         r   proc_nearest_weekdayz,croniter._calc.<locals>.proc_nearest_weekday  sk   J- 1 1 55afaguMM	 1	QU 2 2G 2QZHZHZ%%i000  \QUFBrRRRRAA-dE::DTAE\A-=QqYZ[[[[AQwOO*1D
2z!}MH1}} RH2bQSTTTTAAH1QqQQQQAQw!8OrO   c                     	 t                                        d           nh# t          $ r[  | j        t                    d          }|9|dk    r3r| t	          |dd          z  } n| t	          |dd          z  } d| fcY S Y nw xY wd| fS )Nr   r   r   r   )hoursr  rE   TF)
HOUR_FIELDr   r   r  r   )rY   	diff_hourr   re   r  s     r   	proc_hourz!croniter._calc.<locals>.proc_hour  s    	#$**3//// # # #//8LbQQ	(Y!^^ P]2bQQQQ]1QOOOO7NNN# !8Os    $ A B	B	c                    	 t                                        d           nf# t          $ rY  | j        t                    d          }|7|dk    r1r| t	          |d          z  } n| t	          |d          z  } d| fcY S Y nw xY wd| fS )Nr   r   r   r   )rt   rE   TF)MINUTE_FIELDr   r   r  r   )rY   diff_minr   re   r  s     r   proc_minutez#croniter._calc.<locals>.proc_minute  s    	#&,,S1111 # # #..qx,9OQSTT'HMM G]8BGGGG]8AFFFF7NNN# !8Os    $ ABBc                 B   t                    t          k    rp	 t                                       d           na# t          $ rA  | j        t                   d          }||dk    r| t          |          z  } d| fcY S Y nw xY w| t          d          z  } d| fS )Nr   r   r   r   T)rE   F)r   UNIX_CRON_LENSECOND_FIELDr   r   rE   r   )rY   diff_secr   r  s     r   proc_secondz#croniter._calc.<locals>.proc_second  s    8}}},,'\*005555! ' ' '2218Xl=SUWXXH+A]8<<<<#Qw	' ]!,,,,!8Os    < ABBFTr   zfailed to find prev datezfailed to find next date)_get_prev_nearest_diffr   _get_next_nearest_diffr   rD  rT   r^   rF   r   absr   rR   r~   ri   r<  r   ro   r   )r   r  r   r   re   offsetunaware_timecurrent_yearr  r  r!  r%  r5  r9  r>  rB  rG  procsnextstopprocchanged
aware_timeexistsoffset_deltaalternative_unaware_timealternative_aware_timer^   r  rF   s   ` ```                      @@@r   r   zcroniter._calc  s     	2"&"="333FF"&"=8}}},,&q111&q111{{${//&8x===(('//A/>>LL'//qa/HHL"*//|	 	 	 	 	 	 	*	 	 	 	 	 	 	 	*	 	 	 	 	 	 	 	 	 	0	 	 	 	 	 	 	'	 '	 '	 '	 '	 '	 '	 '	 '	R	 	 	 	 	 	 	 	4	 	 	 	 	 	 		 	 	 	 	 	 		 	 	 	 	 	 %)%9P!!?P%9O!!?O
 $%&&$*IIIDD 
 
*.$|*<*<', ?DE "."4l6GKE4DE   '//A/>>Lz!## "-\3!H!HJ 
Q!*c7;;
Q?BhzFZ?Z?Z
 ! Q#'::$h0Dg$ $L *5\3)P)P&J	 ! Q +3
;;L "!! (+{{${'?'?,'N$'+zz((4H'( ($ .99QSVX_-`-`*"F !7gFF "!!Z)?II .-- 	C&'ABBB"#=>>>rO   c                     t          |          D ]$\  }}||dk    r|}n||k    r|| k    r|| z
  c S %|dS |d         | z
  |z   S )a	  
        `range_val` is the range of a field.
        If no available time, we can move to next loop(like next month).
        `range_val` can also be set to `None` to indicate that there is no loop.
        ( Currently, should only used for `year` field )
        Nr   r   )	enumerate)xto_check	range_valr.  rY   s        r   rI  zcroniter._get_next_nearest_diff  s~     h'' 		 		DAq$88 "AA]]Avv1u  4{Q**rO   c                     |dd         }|                                  |D ]}|dk    r|| k    r|| z
  c S d|v r|  S |dS |d         }|D ]}||k    r|} n||k    r| S || z
  |z
  S )a  
        `range_val` is the range of a field.
        If no available time, we can move to previous loop(like previous month).
        Range_val can also be set to `None` to indicate that there is no loop.
        ( Currently should only used for `year` field )
        Nr   r   )reverse)rZ  r[  r\  r/  rY   r4  r2  s          r   rH  zcroniter._get_prev_nearest_diff0  s     aaa[
 	 	ACxxAFF1u*2I 4qM	 		 		A I~~	 
 y  :1}y((rO   rF   r^   day_of_weekc                     |dz   dz  }t          j        |                              | |          }|d         d         dk    r|                    d           t	          d |D                       S )zFor a given year/month return a list of days in nth-day-of-month order.
        The last weekday of the month is always [-1].
        r%   r&   r   c              3   &   K   | ]}|d          V  dS )r   NrH   )rL   r.  s     r   	<genexpr>z5croniter._get_nth_weekday_of_month.<locals>.<genexpr>]  s&      %%aQqT%%%%%%rO   )calendarCalendarmonthdayscalendarpoptuple)rF   r^   r_  wr2  s        r   r*  z"croniter._get_nth_weekday_of_monthT  so    
 1_!a  224??Q47a<<EE!HHH%%1%%%%%%rO   c                     t          | |          }t          ||          }t          j        | ||          }|dk     r|S |dk    r|dk    r|dz
  S |dz   S ||k     r|dz   S |dz
  S )a  Get the nearest weekday (Mon-Fri) to the given day in the given month.

        Rules:
        - If the day is a weekday, return it.
        - If Saturday, return Friday (day-1), unless that crosses into previous month,
          then return Monday (day+2).
        - If Sunday, return Monday (day+1), unless that crosses into next month,
          then return Friday (day-2).
        r$   r    r!   )rb   minrc  weekday)rF   r^   r  ra   rk  s        r   r7  zcroniter._get_nearest_weekday_  s     &dE22#x  "444Q;;Ja<<QwwQwQw>>7N7NrO   c                 f   t          |t          t          t          t          f          rt          |          }|| j        |         v rj|t          t          fv r|t          k    sO|t          t          fv r|t          k    s4|t          t          t          fv r|t          k    s| j        |         |         }|S r   )rJ   listdictrg  setr   r   r   r  rD  r   SECOND_CRON_LENr  )r   valfield_indexlen_expressionss       r   value_aliaszcroniter.value_aliasz  s    odE3'?@@ 	3!/22O#*[))) Y444M9Y9YY777O<^<^	;	BBB#}44 *[)#.C
rO   r@   rA   rB   )r    r!   r"   r#   r$   r%   r&   r   r'   r(   r)   r*   c                 ~   ./012 dddddddd}|                                 }|dnd	}		 ||         |	         }n# t          $ r Y nw xY w|                                0t          0          t          vrt          d
          t          0          t          k    r0|r.0                    t          0	                    d	                     g }
i }t                      }t          0          D 	]H\  1}t                                          D ](\  }} |                               |1|||          })d|v r>|dk    rt          d| d          1t          t           fvrt          d| d          d}|                    d          /g }t          /          d	k    r/	                                }d 21t           k    rt"                              t'          |                    }|r|                                }|                    dd          |                    dd          }}|rU|}	 t-          |          2d2cxk    rdk    sn J n=# t          t.          t0          f$ r t          d| d2 d          w xY w|r
|}|d         21t          k    rt2                              t'          |                    }|rt-          |                    d          p|                    d                    }|dk     s|dk    rt          d| d| d          t          /          d	k    st          |          d	k    rt          d| d          |                    |           |                    |           t;          j        dd j        1         d	          j        1         d         fz  t'          |                    }t@          !                    |          }|sQt;          j        d d! j        1         d         z  t'          |                    }t@          !                    |          }|r|                    d          |                    d          |                    d"          pd}}}1t          k    r|d#k    rd$}tD          !                    |          s$t'           #                    1|0                    }tD          !                    |          s$t'           #                    1|0                    }tD          !                    t'          |                    st          d| d%| d&1 d'          t-          |          }||fD ]E}tD          !                    t'          |                    st          d| d(| d)| d&1 d*	          F 01fd+||fD             \  }}tI          ||          tI           j        1         d	          j        1         d                   k    rt          | d,          |r1 %                    1t-          |          t-          |                    }||k    r#tM          tO           j        1         d	          j        1         d         dz   d                    }tM          tO          | j        1         d         dz   |                    }d	} |rqtM          tQ          |                    )                    |d-                   }!|)                    |d-                   }"|"|z   t          |          k    r|!|k     r||!z
  } |tM          tO           j        1         d	         | z   |dz   |                    z  }n||k    rDtM          tO           j        1         d	          j        1         d         dz   |                    }nG	 tM          tO          ||dz   |                    }n$# t.          $ r}#t          d.|#           d }#~#ww xY w1t           k    r2r2d#k    r2fd/|D             }//fd0|D             z  /nB|*                    d)          rt          d| d1          tV          !                    |          s #                    1|0          }	 t-          |          }n# t.          $ r Y nw xY w ,                    |10          }|d2vr[t-          |           j        1         d	         k     s$t-          |           j        1         d         k    rt          d| d3          |                    |           1t           k    r22r0||vrt                      ||<   ||                             2           t          /          d	k    t          |          }t[          |d4 5          }t          |           j.        1         k    r81t          k    rd0t                    vs1t           k    rd0t                   vrndg}|
                    t          |          dk    r|d	         dk    rdgn|           	J|rt          |
t                              }$|$/                    |0                                          }$|$1                    d           |$rSt          t          |
t                                         j.        t                    k    rte          d6| d7|$ d8|           |rR|
t                   }%|
tf                   }&|%dgk    r0|%d#gk    r(|&dgk    r d9 |%D             }'d: |&D             }(|'r|(rti           j5                  .d|(v rd;})|Dtm          |t,                    rto          j8        |          })nmts          d< |D                       })nSt          |
          tt          k    r;|
tt                   }*|*dgk    r'd= |*D             }+|+rts          d> |+D                       })|)rd?.d<   tw          |'          },tI          .fd@|(D                       }-|,|-k    rt          d| dA|' dB|(           |
|0|fS )CN)	0 0 * * *zh h(0-2) * * * h)z	0 * * * *zh * * * * h)rv  zh h * * * h)z	0 0 * * 0zh h * * h h)z	0 0 1 * *zh h h * * h)z	0 0 1 1 *zh h h h * h)z	@midnightz@hourlyz@dailyz@weeklyz@monthlyz@yearlyz	@annuallyr    r   zFExactly 5, 6 or 7 columns has to be specified for iterator expression.)r   r   ?r   zE] is not acceptable. Question mark can not used with other characterszO] is not acceptable. Question mark can only used in day_of_month or day_of_weekr   ,he lastr$   z1] is not acceptable. Invalid day_of_week value: ''prer!   r@   z0] is not acceptable, nearest weekday day value 'z' out of rangezY] is not acceptable. 'W' can only be used with a single day value, not in a list or rangez
^\*(\/.+)$z%d-%d\1z^(.+)\/(.+)$z\1-%d/\2r#   r   31z] step 'z' in field z is not acceptablez	] bands '-z are not acceptablec              3   `   K   | ](}                     t          |                    V  )d S r   )rt  rK   )rL   _valr   r   rr  s     r   rb  z#croniter._expand.<locals>.<genexpr>#  sM       ! !  D		;LL! ! ! ! ! !rO   z is out of bandsr  zinvalid range: c                     g | ]	}| d  
S )#rH   )rL   itemr1  s     r   
<listcomp>z$croniter._expand.<locals>.<listcomp>R  s#    ???4$???rO   c                     g | ]}|v|	S rH   rH   )rL   rM   e_lists     r   r  z$croniter._expand.<locals>.<listcomp>S  s    AAAQ&qrO   z1] is not acceptable, negative numbers not allowedr   z!] is not acceptable, out of rangec                 8    t          | t                    r| dn| S )N02rI   )r.  s    r   <lambda>z"croniter._expand.<locals>.<lambda>r  s    As9K9K,RqIIIQR rO   )r   z]day-of-week field does not support mixing literal values and nth day of week syntax.  Cron: 'z	'    dow=z vs nth=c                 <    g | ]}t          |t                    |S rH   rI   )rL   rY   s     r   r  z$croniter._expand.<locals>.<listcomp>  s'    BBB!z!S/A/ABABBBrO   c                 <    g | ]}t          |t                    |S rH   rI   )rL   ms     r   r  z$croniter._expand.<locals>.<listcomp>  s'    FFFA:a3E3EFaFFFrO   Tc              3   >   K   | ]}t          j        |          V  d S r   rc  isleaprL   ys     r   rb  z#croniter._expand.<locals>.<genexpr>  s,      3\3\1HOA4F4F3\3\3\3\3\3\rO   c                 <    g | ]}t          |t                    |S rH   rI   r  s     r   r  z$croniter._expand.<locals>.<listcomp>  s'    ,T,T,T1AsASAS,TQ,T,T,TrO   c              3   >   K   | ]}t          j        |          V  d S r   r  r  s     r   rb  z#croniter._expand.<locals>.<genexpr>  s,      7^7^q8J8J7^7^7^7^7^7^rO      c              3   (   K   | ]}|         V  d S r   rH   )rL   r  days_in_months     r   rb  z#croniter._expand.<locals>.<genexpr>  s(      &L&LA}Q'7&L&L&L&L&L&LrO   z] is not acceptable. Day(s) z can never occur in month(s) )<lowerr   splitr   VALID_LEN_EXPRESSIONr   rD  insertrE  rf  ro  rY  	EXPANDERSr)  expandr   r   special_dow_rer   r   	groupdictgetrK   r   AssertionErrornearest_weekday_regroupaddr+  resubRANGESstep_search_researchonly_int_rer   r   !_get_low_from_current_date_numberrm  r'  reversedr   
startswithstar_or_int_rert  sortedLEN_MEANS_ALL
differencekeysdiscardr   r  rn  DAYS_IN_MONTHrJ   rc  r  anyr  rj  )3r   r   r   r   r   strictstrict_yearexpr_aliaseseflhash_id_exprr   r   r   expr
expanderidexpanderresespecial_dow_remgry  r{  w_matchr8  tr  lowhighstepbandwhole_field_rangerngto_skipalready_skippedcurposexcdow_expanded_setr  r  int_days
int_monthshas_leap_yearr
  	int_yearsmin_daymax_possibler  r  r   rr  r1  s3   `                                             @@@@@r   r   zcroniter._expand  sk    ;323435
 
 !!#/qqQ	s#L1CC 	 	 	D	 iikk{#777&X   {m++0C+|[__Q-?-?@@@!%%!*;!7!7 H	Q H	QK(1(9(9  $
Hx}}++dGN ,   d{{3;;.MK M M M   y)&<<<.VK V V V  
 ZZ__FCf++//JJLL)++&4&:&:3q66&B&BO& ++5577#$55r??AEE&"4E4ED + "A"&)$ii'(C}}}}1}}}}}}}$,j.#I " " "&:%K %K %KDG%K %K %K'" '" !""
 " + $A"#E(C)++066s1vv>>G ! #GMM!$4$4$Ha8H8H I I 199

"6!UK !U !U?D!U !U !U# #  v;;??c#hhll"6!;K !; !; !;# # 
 (++E222

5)))  F!#*["9!"<cj>UVW>X!YYFF 
 #))!,, 1 sz+?VWX?Y0Z\_`a\b\bccA&--a00A h9()

AGGAJJ

a$S"i//DCKK#&--c22 Q!#..c;"O"OPP&--d33 S"3>>+t[#Q#QRR '--c$ii88 2I I IT I I)4I I I   t99D #T	  *11#d))<< "6!NK !N !N# !N !N !N !N-8!N !N !N# # ! ! ! ! ! !%($K! ! !IC
 3~~
;/2CJ{4KA4N) )   3k3S3S3STTT% !CC'TC4G4G  Tzz,0!#*["9!"<cj>UVW>X[\>\^_``- -) #5cj.Ea.H1.Ld#S#STT #$ A.28<M3N3N.O.O.U.UVYZ\V].^.^O%6%<%<SW%E%EF!'$#6G2H2H H H /$ 6 6*.*@tE#*[*A!*Dw*NPTWXPXZ^$_$_``` "!#*["9!"<cj>UVW>X[\>\^bcc P"&uS$(D'A'A"B"BCC) P P P"67N7N7N"O"OOP #i//C/C3JJ????3???AAAA#AAAAFF||C(( 2^^^^   *0033 HNN;;GGFF%    ;DDA
**AK!8!;;;s1vv
S^H_`aHb?b?b2NNNN   JJqMMM"i//C/$88869ee03,Q/33C888I f++//L c((C"R"RSSSC3xx3,[9999,,K	<R1R1R9,,K	<R1R1R%COOc#hh!mmA#SEECPPPP   
	"8I#677/::;O;T;T;V;VWW$$S))) CHY,?(@(@$A$ASEVW`Ea$a$a4P4?P P/P P9MP P    !	 I&Dk*Fu}}#6cU??BBtBBBFFFFF
 
 $():$;$;MJ(,&2)+s;; ]080L0L033\3\P[3\3\3\0\0\ ]]Z77$,Z$8E$~~,T,T,T,T,T	#, !_477^7^T]7^7^7^4^4^M( 2/1M!,!(mmG#&&L&L&L&L&L&L&L#L#LL--2I I I I I<FI I  
 -{OKKsE   ; 
AA1 I.J 7!_
_:#_55_:b
b('b(r   r  r  c                     	 |                      ||||||          \  }}}	}
||fS # t          f$ r=}t          |t                    r t	          j                    }t          |          d}~ww xY w)a  
        Expand a cron expression format into a noramlized format of
        list[list[int | 'l' | '*']]. The first list representing each element
        of the epxression, and each sub-list representing the allowed values
        for that expression component.

        A tuple is returned, the first value being the expanded epxression
        list, and the second being a `nth_weekday_of_month` mapping.

        Examples:

        # Every minute
        >>> croniter.expand('* * * * *')
        ([['*'], ['*'], ['*'], ['*'], ['*']], {})

        # On the hour
        >>> croniter.expand('0 0 * * *')
        ([[0], [0], ['*'], ['*'], ['*']], {})

        # Hours 0-5 and 10 monday through friday
        >>> croniter.expand('0-5,10 * * * mon-fri')
        ([[0, 1, 2, 3, 4, 5, 10], ['*'], ['*'], ['*'], [1, 2, 3, 4, 5]], {})

        Note that some special values such as nth day of week are expanded to a
        special mapping format for later processing:

        # Every minute on the 3rd tuesday of the month
        >>> croniter.expand('* * * * 2#3')
        ([['*'], ['*'], ['*'], ['*'], [2]], {2: {3}})

        # Every hour on the last day of the month
        >>> croniter.expand('0 * l * *')
        ([[0], ['*'], ['l'], ['*'], ['*']], {})

        # On the hour every 15 seconds
        >>> croniter.expand('0 0 * * * */15')
        ([[0], [0], ['*'], ['*'], ['*'], [0, 15, 30, 45]], {})
        )r   r   r   r  r  N)r   r   rJ   r   
_traceback
format_excr   )r   r   r   r   r   r  r  r   r   _expressions_nearest_weekdayr  traces                r   r  zcroniter.expand  s    `	.MP[[$7-' NY N NJH*L:J 111} 	. 	. 	.#}-- )++E&u---		.s   #& A.8A))A.c                 j   t           j                             |t                    }|t          k    r
|j        |z  S |t
          k    r
|j        |z  S |t          k    r|j        dz
  |z  dz   S |t          k    r
|j
        |z  S |t          k    r|                                dz   |z  S t          d          )Nr   r    z5Can't get current date number for index larger than 4)rV   r   rh   r@  r  r<  r  r   r  r  r^   r   rk  r   )r   rr  r  r   dts        r   r  z*croniter._get_low_from_current_date_number  s    ,,^,GG,&&9t##*$$7T>!)##VaZ4'1,,+%%8d?")##JJLL1$,,PQQQrO   r   c                    |rUt          |t          t          f          st          d          t          |t                    s|                    |          }	 |                     |||||           n# t          $ r Y dS w xY wdS )Nr   )r   r   r  r  FT)rJ   r   r   r   r   r  r   )r   
expressionr   encodingr   r  r  s          r   is_validzcroniter.is_valid   s     	3gs|44 I GHHHgu-- 3!..22	JJz7H[dj  yDJ  E  E  E  E 	 	 	55	ts   A4 4
BBc                 6    |                      ||||||          S r   )match_range)r   cron_expressiontestdater   r   precision_in_secondss         r   r   zcroniter.match  s)     Xx9LNb
 
 	
rO   c                     | ||t           j         ||          }|                    t           j                   }|j        s|t          d          z  }|                    |d           	 |                                }	n# t          $ r Y dS w xY w|!t          |j                  t          k    rdnd}||z
  
                                |z   }
t          ||	          t          ||	          z
  
                                |
k     S )N)r   r   r   r    r  Tr   Fr   )rV   r   r  r   r   r   r   r   r   rD  rW   r   rj  )r   r  from_datetimeto_datetimer   r   r  crontdptdtduration_in_seconds              r   r  zcroniter.match_range  s!    s& 3
 
 
 x011 	1=a0000CD)))	--//CC# 	 	 	55	'(+DM(:(:](J(J11PR )M9HHJJMaaCC-<<>>ASSSs   ,B 
BB)NNTr   )T)NNNN)NNN)NFNFN)Nr   FFN)TFN)?r   r   r   r  r  r   deepcopyr7   r?   r   rg  rn  r   r   rK   __annotations__r   r  r   r   rV   typer   r   r   classmethodr   r   r   r   r   staticmethodrZ   _datetime_to_timestampr   r   r   _timestamp_to_datetimer   r   r   r   r   __next__rO  r   rm  ExpandedExpressionro  r   rI  rH  r*  r7  rD  rt  r  r   r  r  r  r   r  rH   rO   r   r   r     s        N QF 	
	c
hj!!

9IuT#uS#X./45    +-b1a&1a&1a&"b)QFE$sCx.#%&QQQ0M
 AE37/3#($)',/  / /  U8#4e#;<=/  	/ 
 /  $,C=/  /  %s
+,/  !/  "/  !%/  
/  /  /  / b X X [X
 
 
 

 
 
 

    TX "5):E)A#BCLP	    (!2 (u ( ( ( \( 3DJ  u c xO`      3   2   *    A A A    HtL$ L8+< L L L L@[?[? )*[? #3C=1	[?
 [? 
	[? [? [? [?z + + \+. !) !) \!)F & &C &c &eTWY\T\o & & & \&   \4 ;H    [$ rbRB2"PRXZ`bhjkkM^L ^L ^L [^L@	  04$)*.7;=. =.=. %s
+,=. "	=.
 !=. =. eCcN34=. 
t&'c3s8m)<<	==. =. =. [=.~ R R [R 
 
 
 [
 
 !!

 

 

 [

  !!T T T [T T TrO   r   c	           	   #     K   |pt           }t          j        }	t          |           t                    urit          | t                              sLt          t          |                     s/t	          dt          |            dt                               t          | t
          t          f          rd | fD             \  } t
          }	||	}|s+t          d          }
| k     r| |
z  } |
z  n
| |
z  } |
z  t          j	        t          j        | j        z
                      dz   } ||| t          j        ||||          }| k     rfd}|j        }nfd	}|j        }	  |            } ||          rA|t
          u r|                    t
                    V  n|V   |            } ||          ?dS dS # t          $ r Y dS w xY w)
a  
    Generator that provides all times from start to stop matching the given cron expression.
    If the cron expression matches either 'start' and/or 'stop', those times will be returned as
    well unless 'exclude_ends=True' is passed.

    You can think of this function as sibling to the builtin range function for datetime objects.
    Like range(start,stop,step), except that here 'step' is a cron expression.
    z'The start and stop must be same type.  z != c              3      K   | ]D}t           j                             |t                                                    d           V  Ed S )NrQ   )rV   r   r
   rT   )rL   r  s     r   rb  z!croniter_range.<locals>.<genexpr>V  s[       
 
QRH++Auww77??t?LL
 
 
 
 
 
rO   Nr    r  )r   r   r   r   r   c                     | k     S r   rH   vrP  s    r   contzcroniter_range.<locals>.contq      t8OrO   c                     | k    S r   rH   r  s    r   r  zcroniter_range.<locals>.contw  r  rO   )r   rV   r  rJ   r   r   rK   r   mathfloorrJ  rF   r   r   r   r   )startrP  r   r   r   exclude_ends	_croniterr   r   auto_rtms1	year_spanicr  r  r  s    `              r   croniter_ranger  9  sv     & %XIGE{{$t**$$5$t**%% %)3D$u++)F)F % (Sd5kkSStDzzSS
 
 	
 %%&& 
 
W\^bVc
 
 
t  +++4<<SLECKDDSLECKD
3ty5:56677!;I	""+/5
 
 
B t||	 	 	 	 	 {	 	 	 	 	 {
TVVd2hh 	5  nnU++++++B d2hh 	 	 	 	 	     s   2AG
 

GGc                   ,    e Zd Zd ZddZd	dZd
dZdS )HashExpanderc                     || _         d S r   )r  )r   cronits     r   r   zHashExpander.__init__  s    			rO   hNc                     || j         j        |         d         }|| j         j        |         d         }|dk    rt          j        dd          }nt	          j        |          dz  }||z	  ||z
  dz   z  |z   S )z;Return a hashed/random integer given range/hash informationNr    r   rl    )r  r  randomrandintbinasciicrc32)r   idx	hash_typer   	range_endrange_begincrcs          r   dozHashExpander.do  s    	(-a0I)*3/2K.J//CC.))J6C	K 7! ;<KKrO   c                 6    t                               |          S r   )hash_expression_rer   )r   r  r  r  r   kws         r   r   zHashExpander.match  s    !''---rO   rz  c                    |dk    r | j         ||||fi |}|s|S |                                }|d         dk    r|t          d          |d         rC|d         r;t          |d                   t          |d                   k    rt          d          |d         r|d         r|d	         rt          |d	                   d
k    rt          d|           |                     ||d         |t          |d                   t          |d	                   dz
  t          |d                   z             }| dt          |d                    dt          |d	                    S |d         r[|d         rSt          |                     ||d         |t          |d                   t          |d                                       S |d	         rt          |d	                   d
k    rt          d|           |                     ||d         || j        j        |         d
         t          |d	                   dz
  | j        j        |         d
         z             }| d| j        j        |         d          dt          |d	                    S t          |                     ||d         |                    S )z>Expand a hashed/random expression to its normal representationrz  r  r  Nz'Hashed definitions must include hash_idr  r  z*Range end must be greater than range begindivisorr   zBad expression: r    )r  r   r  r  r  /)r  r   r  r  )r  r   )r   r  r   rK   r  r   r  r  )	r   r  r  r  r   r   r  r  rZ  s	            r   r  zHashExpander.expand  s   B;;DJsCw=="==E 	KOO[>S  W_&'PQQQ] 	Y+ 	Y1]#$$AkN(;(;;;*+WXXX] 	D+ 	D1Y< 	D1Y<  A%%*+Dd+D+DEEEK.- 011a	l++a/#a6F2G2GG   A CC#an--CCAiL0A0ACCC] 
	+ 
	n#!!K.11 #Am$4 5 5      Y< 	I1Y<  A%%*+Dd+D+DEEEK. I,S1!4a	l++a/$)2B32G2JJ   A HH$)*3/2HHS95F5FHHH 4773!K.'7JJKKKrO   )r  NNNr   )Nrz  )r   r   r   r   r  r   r  rH   rO   r   r	  r	    si          
L 
L 
L 
L. . . .6L 6L 6L 6L 6L 6LrO   r	  hash)NTFNFF)[r  rc  r   rV   r  r   r  r  r   r   	tracebackr  r   typingr   r   r   r   dateutil.relativedeltar   dateutil.tzr	   r
   rm  rK   r  r   r   r   r   OverflowErrortimezoneutcrh   r   r7   rn  r   r  r?   r@  r<  r   r  r   rE  r  UNIX_FIELDSSECOND_FIELDSYEAR_FIELDScompiler  r  r`   r   r  WEEKDAYSMONTHSr  r  r  r   r  r   r   rD  rp  r  r  objectr   rZ   r]   rb   ri   ry   ro   rg  r~   r   r   r   r   r   r   r   r   r   r  r	  r  rH   rO   r   <module>r.     s          				  



           0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . . . . . . . .%WX%6 678 $    <xzz 4''
333    
		''622 ( ($sE#s(O#
$    * *
DeCHo%&    
		
ZKKz9k9l[ :;;bj""788JOO%%&&	(--//	"	"M**<8 < < < << << < <   RZ 677 
"*U

RZ^  
 Km
KCkCCk K  #m$$K  EE;EEE 	? ? ?B3 B4 B B B BS      F

F,4,=FHLF	F F F F8, X5F 8K]    6

6,4,=6HL6
8d"#6 6 6 6r4 4 4 4 4J 4 4 4    	   I I I I I= I I IF F F F F%9 F F F3 3 3 3 3= 3 3 3D D D D D0 D D DnT nT nT nT nT nT nT nTj!  L L L L^IL IL IL IL IL IL IL ILX \"			s   +&B BB