
    p:ig                        d 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	 ddl
mZmZ ddlT ddlmZmZmZmZmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZ ddl m!Z! ddl"m#Z#m$Z$m%Z% ddl&m'Z' d Z(d Z)d Z*d Z+d Z,d Z-d Z.d Z/d Z0d'dZ1d Z2 G d de          Z3 G d de4          Z5 G d de          Z6 G d  d!e          Z7 G d" d#e          Z8d$ Z9 G d% d&e:          Z;dS )(a  

Note about Unicode
------------------

The Subversion bindings are not unicode-aware and they expect to
receive UTF-8 encoded `string` parameters,

On the other hand, all paths manipulated by Trac are `str` objects.

Therefore:

 * before being handed out to SVN, the Trac paths have to be encoded
   to UTF-8, using `_to_svn()`

 * before being handed out to Trac, a SVN path has to be decoded from
   UTF-8, using `_from_svn()`

Whenever a value has to be stored as utf8, we explicitly mark the
variable name with "_utf8", in order to avoid any possible confusion.

Warning:
  `SubversionNode.get_content()` returns an object from which one can
  read a stream of bytes. NO guarantees can be given about what that
  stream of bytes represents. It might be some text, encoded in some
  way or another.  SVN properties *might* give some hints about the
  content, but they actually only reflect the beliefs of whomever set
  those properties...
    N)quote)ISystemInfoProvider)
ListOptionChoiceOption)*)	ChangesetNode
RepositoryIRepositoryConnectorInvalidRepositoryNoSuchChangeset
NoSuchNode)CachedRepository)embedded_numbers)	threading)exception_to_unicode
to_unicodeto_utf8)_)from_utimestampto_datetimeutc)Hrefc                  z    ddl mamamama t          j        t          j        t          j        t          j	        ia
d S )Nr   )fsreposcoredelta)svnr   r   r   r   svn_node_dirr	   	DIRECTORYsvn_node_fileFILE_kindmap     Y/var/www/html/trac/venv/lib/python3.11/site-packages/tracopt/versioncontrol/svn/svn_fs.py_import_svnr(   F   sE    ************!4>"DI/HHHr&   c                     t                               d                    |                              d                              d          |           S )zExpect a pool and a list of `str` path components.

    Returns an UTF-8 encoded string suitable for the Subversion python
    bindings (the returned path never starts with a leading "/")
    /utf-8)r   svn_path_canonicalizejoinlstripencode)poolargss     r'   _to_svnr2   L   sD     %%chhtnn&;&;C&@&@5;VG__&*, , ,r&   c                 P    t          | t                    rt          | d          } | S )zExpect an UTF-8 encoded string and transform it to a `str` object

    But Subversion repositories built from conversion utilities can have
    non-UTF-8 byte strings, so we have to convert using `to_unicode`.
    r+   )
isinstancebytesr   paths    r'   	_from_svnr8   V   s*     $ )$((Kr&   c                 F    t          |                               d          S )Nascii)r   r/   )values    r'   _quote_br<   `   s    <<w'''r&   c                 4    | r|                      d          pdS )z(Remove leading "/", except for the root.r*   )stripr6   s    r'   _normalize_pathr?   e   s    #DJJsOO*s*r&   c                     |v|                     d          }| dk    rt          |          S |                     d          } |dz                       | dz             r|t	          |           dz   d         pdS dS dS )zdRemove the leading scope from repository paths.

    Return `None` if the path is not is scope.
    Nr*      )r.   r?   r>   
startswithlenscopefullpaths     r'   _path_within_scoperG   i   s    
 ??3''C<<"8,,,C  sN&&us{33 	4CJJNOO,33 
	4 	4r&   c                     | dk    r|duS |r|                     d          nd}|                     d          } |dz                       | dz             S )z>Check whether the given `fullpath` is within the given `scope`r*   N )r.   r>   rB   rD   s     r'   _is_path_within_scoperJ   v   s^    ||t##'/7xs###RHKKEsN&&us{333r&   c                     t                                           }| |_        t                                           }t           j        |_        ||_        |S N)r   svn_opt_revision_value_tnumbersvn_opt_revision_tsvn_opt_revision_numberkindr;   )numr;   revisions      r'   _svn_revrT      sA    ))++EEL&&((H0HMHNOr&   c                  Z    t                                           } t           j        | _        | S rL   )r   rO   svn_opt_revision_headrQ   )rS   s    r'   	_svn_headrW      s"    &&((H.HMOr&   c                 N    t                               | pt           j                  S rL   )r   Poolapplication_pool)parents    r'   rY   rY      s    99V4t4555r&   c                 b    | r*|                                  r|                                  d S d S d S rL   )validdestroyr0   s    r'   _pool_destroyr`      s>     

    r&   c                   (    e Zd ZdZdZd Zd Zd ZdS )SvnCachedRepositoryz_Subversion-specific cached repository, zero-pads revision numbers
    in the cache tables.
    Tc                     d|z  S )Nz%010dr%   selfrevs     r'   db_revzSvnCachedRepository.db_rev   s    }r&   c                 $    t          |pd          S Nr   )intrd   s     r'   rev_dbzSvnCachedRepository.rev_db   s    38!}}r&   c                 6    | j                             |          S rL   )r   normalize_revrd   s     r'   rm   z!SvnCachedRepository.normalize_rev   s    z'',,,r&   N)__name__
__module____qualname____doc__has_linear_changesetsrg   rk   rm   r%   r&   r'   rb   rb      sS          !    - - - - -r&   rb   c                       e Zd Z eee            edddd          Z edddd          Z e	dd	g d
d          Z
dZd Zd Zd Zd ZdS )SubversionConnectorr   branchesztrunk, branches/*zComma separated list of paths categorized as branches.
        If a path ends with '*', then all the directory entries found below
        that path will be included.
        Example: `/trunk, /branches/*, /projectAlpha/trunk, /sandbox/*`
        )doctagsztags/*zComma separated list of paths categorized as tags.

        If a path ends with '*', then all the directory entries found below
        that path will be included.
        Example: `/tags/*, /projectAlpha/tags/A-1.0, /projectAlpha/tags/A-v1.1`
        	eol_style)nativeLFCRLFCRa  End-of-Line character sequences when `svn:eol-style` property is
        `native`.

        If `native`, substitute with the native EOL marker on the server.
        Otherwise, if `LF`, `CRLF` or `CR`, substitute with the specified
        EOL marker.

        (''since 1.0.2'')Nc                    d | _         	 t                       | j                            d           t          j        t          j        t          j        f}t          d|z  t          j	        z   d          | _         |d         dk     rt          d| j                   | _        d S d S # t          $ r.}|| _        | j                            dd	
           Y d }~d S d }~ww xY w)NzSubversion bindings importeds   %d.%d.%dr+   r   rA   z-Subversion >= 1.0 required, found %(version)s)versionz"Failed to load Subversion bindingsT)exc_info)_versionr(   logdebugr   SVN_VER_MAJORSVN_VER_MINORSVN_VER_MICROstrSVN_VER_TAGr   errorImportErrorinfo)re   r~   es      r'   __init__zSubversionConnector.__init__   s    	6MMM
 HNN9:::)4+=)+Gg 58H H ') )DMqzA~~N'+}6 6 6


 ~  	O 	O 	ODJHMM>MNNNNNNNNN	Os   B$ $
C.#CCc              #   2   K   | j         rd| j         fV  d S d S )N
Subversion)r   re   s    r'   get_system_infoz#SubversionConnector.get_system_info   s3      = 	.------	. 	.r&   c              #   V   K   d}| j         rd}d|dz  fV  d|dz  fV  d|dz  fV  d S )NrA   direct-svnfs   svnfsr      )r   )re   prios     r'   get_supported_typesz'SubversionConnector.get_supported_types   s_      : 	Dtax((((q!!!!dQhr&   c                     |                     | j        | j                   |                    d| j                   t          ||| j                  }|dk    rt          | j        || j                  }|S )zReturn a `SubversionRepository`.

        The repository is wrapped in a `CachedRepository`, unless `type` is
        'direct-svnfs'.
        )rw   ru   rx   r   )	updaterw   ru   
setdefaultrx   SubversionRepositoryr   rb   env)re   typedirparamsr   s        r'   get_repositoryz"SubversionConnector.get_repository   sn     	49t}===+t~666$S&$(;;>!!'%BBEr&   )rn   ro   rp   
implementsr   r   r   ru   rw   r   rx   r   r   r   r   r   r%   r&   r'   rt   rt      s        J"$8999z%-@	  H :eVX	  D {:::		 	 	I E6 6 6&. . .         r&   rt   c                       e Zd ZdZdZd ZddZd dZd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd ZddZd dZd Zd Zd!dZd Zd Zd"dZd#dZd Zd dZ	 d$dZdS )%r   z2Repository implementation based on the svn.fs API.Tc           
      l   || _         t                      | _        t          |t                    rt          |          }t          j        |                    dd                    }t          
                    |                    d                    }t          |d          }t                              || j                  }|t          t!          d|                    t          |d          }|| _        	 t                              || j                  | _        nC# t          j        $ r1}t          t!          d|t)          |                              d }~ww xY wt                              | j                  | _        t/          t0                              | j        | j                            | _        d| j        d	|| _        d| j        d	|}t9          j        | |||           ||k    r>|t=          |          d          | _        | j        d
         dk    s| xj        dz  c_        nd| _        | j                             d          sJ tB          j"        dk    rdnd}	t          #                    |	tI          |          z             | _%        | &                                 d S )N\r*   r+   z7%(path)s does not appear to be a Subversion repository.r6   z;Couldn't open Subversion repository %(path)s: %(svn_error)s)r7   	svn_errorzsvn::r   nts   file:///s   file://)'r   rY   r0   r4   r5   r   	posixpathnormpathreplacer   r,   r/   r   r   svn_repos_find_root_pathr   r   r7   svn_repos_openSubversionExceptionr   svn_repos_fsfs_ptrr8   r   get_uuiduuidbaser
   r   rC   rE   rB   osnamesvn_uri_canonicalizer<   ra_url_utf8clear)
re   r7   r   r   	path_utf8root_path_utf8	root_pathr   r   	ra_prefixs
             r'   r   zSubversionRepository.__init__   s   FF	 dE"" 	$d##D!$,,tS"9"9::..t{{7/C/CDD	9g&&77	49MM!#K     00			6--ndiHHDJJ' 	6 	6 	6# "(,0335 5 56 6 6	6
 ((44bkk$+tyAABB		#'999ii8		"iii.D$444 c)nnoo.DJ:b>S((

c!

DJz$$S))))) $&7d??KK
	44Y5=n5M5M6N O O

s   <%D" "E"1,EE"Nc                 Z    d| _         ||                     |          | _         d| _        dS )z'Reset notion of `youngest` and `oldest`N)youngestrm   oldest)re   youngest_revs     r'   r   zSubversionRepository.clear,  s/    # ..|<<DMr&   c                     |s| j         }|                     |          }t                              | j        ||          }t                              |t          || j        |          |          }|t          v S )z:Check if `path` exists at `rev` (or latest if unspecified))	r0   rm   r   revision_rootr   
check_pathr2   rE   r$   )re   r7   rf   r0   rev_root	node_types         r'   has_nodezSubversionRepository.has_node3  sp     	9D  %%##DKd;;MM(GD$*d,K,K"&( (	H$$r&   c                      t          |          S )z`Take any path specification and produce a path suitable for
        the rest of the API
        )r?   )re   r7   s     r'   normalize_pathz#SubversionRepository.normalize_path=  s     t$$$r&   c           	         |+t          |t                    r|                                dv r| j        S 	 t	          |          }d|cxk    r| j        k    rn n|S | j                            d|| j        pd| j                   nO# t          t          f$ r;}| j                            d|| j        pdt          |                     Y d}~nd}~ww xY wt          |          )zhTake any revision specification and produce a revision suitable
        for the rest of the API
        N)rI   headlatestr   r   z-%r cannot be normalized in %s: out of [0, %r]z	(default)z!%r cannot be normalized in %s: %s)r4   r   lowerr   rj   r   r   reponame
ValueError	TypeErrorr   r   )re   rf   normrevr   s       r'   rm   z"SubversionRepository.normalize_revC  s#    ;*S#..;yy{{@@@$$8c((44444#444444"NHNN $)*-t}/K#'#46 6 6 6 	* 8 8 8BC#};3A668 8 8 8 8 8 8 88 "#&&&s   %B )B C1CCc                 X    d| _         d| _        t          | j                   d| _        dS )z=Dispose of low-level resources associated to this repository.N)r   r   r`   r0   r   s    r'   closezSubversionRepository.closeY  s+    
di   			r&   c                     | j         S )zRetrieve the base path corresponding to the Subversion
        repository itself.

        This is the same as the `.path` property minus the
        intra-repository scope, if one was specified.
        )r   r   s    r'   get_basezSubversionRepository.get_base`  s     yr&   c              #     K   | j                             |g           D ]}|                    d          rt          j        |          }	 d |                     |                                          D             }t          |d           D ]}|j        t          j
        k    r|V  # t          $ r Y w xY w	 |                     |          V  # t          $ r Y w xY wdS )z Retrieve known branches or tags.r   c                     g | ]}|S r%   r%   ).0ns     r'   
<listcomp>z>SubversionRepository._get_tags_or_branches.<locals>.<listcomp>o  s    NNNQqNNNr&   c                 N    t          | j                                                  S rL   )r   r7   r   )r   s    r'   <lambda>z<SubversionRepository._get_tags_or_branches.<locals>.<lambda>p  s    '7'G'G r&   keyN)r   getendswithr   dirnameget_nodeget_entriessortedrQ   r	   r!   	Exception)re   pathsr7   folderentriesnodes         r'   _get_tags_or_branchesz*SubversionRepository._get_tags_or_branchesi  s2     KOOE2.. 	 	D}}S!! "*400NN$--*?*?*K*K*M*MNNNG &w 5H 5H !I !I !I ' '966"&JJJ' !   D--------    D	 	s%   
AB**
B76B7;C
C C c              #      K   |                      d          D ]}d|j        |j        dfV  |                      d          D ]}d|j        |j        |j        fV  dS )z{Retrieve known branches, as (name, id) pairs.

        Purposely ignores `rev` and always takes the last revision.
        ru   Nrw   )r   r7   created_pathcreated_rev)re   rf   r   s      r'   get_quickjump_entriesz*SubversionRepository.get_quickjump_entries|  s      
 ++J77 	3 	3Aafafd22222++F33 	@ 	@A!&!.!-?????	@ 	@r&   c                     | j                             dd                              d          }|r1t          |          }|r|                    d          } ||          S dS )zkRetrieve the "native" URL from which this repository is reachable
        from Subversion clients.
        urlrI   r*   N)r   r   rstripr   r.   )re   r7   rf   r   hrefs        r'   get_path_urlz!SubversionRepository.get_path_url  sk     kooeR((//44 	99D ({{3''4::		 	r&   c                 d    |                      |          }t          | || j        | j                  S )zIProduce a `SubversionChangeset` from given revision
        specification)rm   SubversionChangesetrE   r0   rd   s     r'   get_changesetz"SubversionRepository.get_changeset  s/       %%"4dj$)DDDr&   c                     | j         |fS )z7Build a value identifying the `rev` in this repository.)r   rd   s     r'   get_changeset_uidz&SubversionRepository.get_changeset_uid  s    y#~r&   c                     |pd}|r|dk    r|d         dk    r
|dd         }|                      |          p| j        }t          ||| | j                  S )zProduce a `SubversionNode` from given path and optionally revision
        specifications. No revision given means use the latest.
        rI   r*   r   N)rm   r   SubversionNoder0   re   r7   rf   s      r'   r   zSubversionRepository.get_node  sg     zr 	DCKKDHOO9D  %%:):dCty999r&   c                     |                      ||          }g }|                                D ]+\  }}}||k    s|r||k     r n|                    |           ,|S )zReturn the revisions affecting `path` between `first` and `last`
        revs. If `first` is not given, it goes down to the revision in which
        the branch was created.
        )r   get_historyappend)	re   r7   lastfirstr   revsprchgs	            r'   _get_node_revsz#SubversionRepository._get_node_revs  sm    
 }}T4((++-- 	 	KQ3DyyUyq5yyKKNNNNr&   c                     i }|D ]Q\  }}|j         }g }|                                D ])\  }}}	||k    s||k     r n|                    |           *|||<   R|S rL   )r7   r   r   )
re   
node_infos	path_revsr   r   r7   r   r  r  r  s
             r'   _get_changed_revsz&SubversionRepository._get_changed_revs  s    	% 	# 	#KD%9DD!--//  	1c99E		EA"IdOOr&   c              #     K   t          || j        |          }||k     r||}}||fdk    rdS t                              | j        ||          }t                              |||          t          j        k    rdS t          |          }t          |          }t          	                    |||          }	d}
|	rt          
                    |	|
|          }	|                                 ||}}|	rNt                              |	|          \  }}|                                 ||k     rnt          |          }||fV  |	~~dS )z`path` is a str path in the scope.

        Generator yielding `(path, rev)` pairs, where `path` is a `str`
        object. Must start with `(path, created rev)`.

        (wraps ``fs.node_history``)
        )rA   r   NrA   )r2   rE   r   r   r   r   r   svn_node_nonerY   node_historyhistory_prevr   history_locationr8   )re   r7   startendr0   r   roottmp1tmp2history_ptrcross_copiesrf   s               r'   _historyzSubversionRepository._history  sJ      D$*d33	3;;e3E3<6!!FUD99==y$//43EEEFDzzDzzoodIt<< 
	 //+|TJJKJJLLLt$D  !#!4!4[$!G!G	3

99 ++Ci  
	  DDr&   rI   c                 h    |dk    r+|                      |d|dz
  |p| j                  D ]\  }}|c S d S NrA   )r  r0   )re   rf   r7   r0   r   prevs         r'   _previous_revz"SubversionRepository._previous_rev  sI    77==q#a%9JKK  4tr&   c                 ,    | j         d| _         | j         S )z.Gives an approximation of the oldest revision.NrA   )r   r   s    r'   get_oldest_revz#SubversionRepository.get_oldest_rev  s    ;DK
 {r&   c                     | j         sdt                              | j        | j                  | _         | j        dk    r/|                     dd| j         | j                  D ]\  }}|| _          | j         S )z]Retrieve the latest revision in the repository.

        (wraps ``fs.youngest_rev``)
        r*   rI   rA   )r   r   r   r   r0   rE   r  r   s      r'   get_youngest_revz%SubversionRepository.get_youngest_rev  so    
 } 	OODKCCDMzS  !%r1dmTY!O!O  ID#$'DM}r&   c                 X    |                      |          }|                     ||          S )zhReturn revision immediately preceding `rev`, eventually below
        given `path` or globally.
        )rm   r  )re   rf   r7   s      r'   previous_revz!SubversionRepository.previous_rev  s-    
   %%!!#t,,,r&   Fc                 8   |                      |          }|dz   }| j        }t          | j                  }||k    r^|                                 |                     ||dz   ||          D ]\  }}|c S |s|                     |||          s|S |dz  }||k    ^dS )zhReturn revision immediately following `rev`, eventually below
        given `path` or globally.
        rA   N)rm   r   rY   r0   r   r  r   )re   rf   r7   find_initial_revnextr   subpoolr   s           r'   next_revzSubversionRepository.next_rev  s       %%Qw$ty//hMMOOO==s1udGDD    4'  !]]4w?? KAID h tr&   c                 Z    |                      |          |                      |          k     S )z9Check relative order between two revision specifications.)rm   )re   rev1rev2s      r'   rev_older_thanz#SubversionRepository.rev_older_than  s)    !!$''$*<*<T*B*BBBr&   c              #   X  K   |                      |          }|                     |          }d}t          | j                  }d}|r^|r||k     rW|                                 |                     |||          r|r|dz  }||dz   t          j        fV  d}d}|                     |d||          D ]\  }	}
t          | j
        |	          |
t          j        f}|                     |
|          }|r||dz  }|d         |k    r|d         |d         t          j        fV  nM|                     |d         |          }|d         |d         t          j        fV  |d         |d         df} n|}|r	|dz  }|V  nd}|                     ||          }|r|L||k     SdS dS dS dS )zURetrieve creation and deletion events that happened on
        given `path`.
        Fr   rA   Nr_   unknownT)r   rm   rY   r0   r   r   r   DELETEr  rG   rE   ADDr  EDITCOPY)re   r7   rf   limitexpect_deletionr#  numrevsnewerolderr  r  s              r'   get_path_historyz%SubversionRepository.get_path_history  s      ""4((  %%ty// !	<5 !	<GeOOMMOOO}}T300 <" 8 qLGAy'77777 MM$3@@ " "DAq/
A>>&],E,,QW,==C "1 8t++"'(E!Hin"DDDDD #'"4"4U1XG"4"L"LC"'(E!Hin"DDDD%*1XuQx$CE!E!EE  qLGKKK"&((7(;;C  !	<5 !	<GeOOOO !	< !	<OO !	< !	<r&   r   c              #     K   dx}}|                      |          }|                      |          }|                     ||          r|                     ||          }nt          ||d          |                     ||          r|                     ||          }nt          ||d          |j        |j        k    r-t          t          d|j        |||j        ||                    t          | j                  }|j	        rt                      }	t                              |	|          \  }
}t                              | j        ||          }t                              | j        ||          }d }d}d}t                               |t%          || j        |          d|t%          || j        |          |
|||d	|||           t)          d
 |	j        D             d           }|	j                                         |D ]\  }}}dx}}|t0          j        k    r)|                     t5          j        ||          |          }|t0          j        k    r*|                     t5          j        ||          |          }n@t:          t                              |t%          || j        |j                  |                   }||||fV  dS t                              | j        ||          }t                              | j        ||          }t                               |t%          || j        |          |t%          || j        |          |          r||tB          j"        t0          j#        fV  dS dS )zDetermine differences between two arbitrary pairs of paths
        and revisions.

        (wraps ``repos.svn_repos_dir_delta``)
        NzThe Base for Diff is invalidzThe Target for Diff is invalidzDiff mismatch: Base is a %(oldnode)s (%(oldpath)s in revision %(oldrev)s) and Target is a %(newnode)s (%(newpath)s in revision %(newrev)s).)oldnodeoldpatholdrevnewnodenewpathnewrevc                     dS r  r%   )r  r7   r0   s      r'   authz_cbz2SubversionRepository.get_changes.<locals>.authz_cbk  s    qr&   r   rI   rA   c              3   B   K   | ]\  }}}t          |          ||fV  d S rL   r8   )r   r7   rQ   changes       r'   	<genexpr>z3SubversionRepository.get_changes.<locals>.<genexpr>{  sQ       F F!3tV (ootV< F F F F F Fr&   c                     | d         S ri   r%   )entrys    r'   r   z2SubversionRepository.get_changes.<locals>.<lambda>}  s
    eAh r&   r   )$rm   r   r   r   rQ   	TracErrorr   rY   r0   isdirDiffChangeEditorr   make_editorr   r   r   r   svn_repos_dir_deltar2   rE   r   deltas__dict__r   r   r,  r   r-   r+  r$   r   r7   contents_changedr	   r#   r-  )re   old_pathold_revnew_pathnew_revignore_ancestryold_nodenew_noder#  editore_ptre_batonold_rootnew_rootr=  text_deltasentry_propsrI  r7   rQ   r@  s                        r'   get_changesz SubversionRepository.get_changesJ  s      #"8$$W--$$W--==7++ 	P}}Xw77HHXw0NOOO==7++ 	?}}Xw77HHXw=? ? ?=HM))A 6 @H}&.w&.mX%,. . . / / / ty//> 3	F%''F"..vw??NE7''WgFFH''WgFFH  KK%%h&-gtz8&L&L&((&-gtz8&L&L&+Wh&1&'&1&5&-	/ 	/ 	/  F F7=}F F F 6 68 8 8F
 O!!###&, : :"dF&**8Y]**#}}Y^Hd-K-K-4 6  6HY---#}}Y^Hd-K-K-4 6  6HH $BMM(29':>*:B-3I 3I 3:	%; %; <D
 !(D&99999: :  ''WgFFH''WgFFH""8#*7DJ#I#I#+#*7DJ#I#I#*	, , F
  49inEEEEEEF Fr&   rL   NN)rI   N)rI   )rI   F)r   )rn   ro   rp   rq   rr   r   r   r   r   rm   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r$  r(  r4  rZ  r%   r&   r'   r   r      s       << 1 1 1f   % % % %% % %' ' ',      &@ @ @	 	 	E E E  : : : :   
 
 
! ! !F       - - - -   &C C C*< *< *< *<Z %&OF OF OF OF OF OFr&   r   c                   b    e Zd ZddZd ZddZd ZddZd Zd	 Z	d
 Z
d Zd Zd Zd Zd ZdS )r   Nc                 x   |j         | _         |j        | _        t          |          | _        | j        }t	          || j        |          | _        |r|| _        n^	 t                              | j         ||          | _        n6# t          j
        $ r$}t          ||t          |                    |d }~ww xY wt                              | j        | j        |          }|t          vrt          ||          t                              | j        | j        |          }t!          |          }	t                              | j        | j        |          }
t%          | j        |	          r"|
| _        t)          | j        |	          | _        n||c| _        | _        t-          j        | |||t          |                    d S rL   )r   rE   rY   r0   r2   _scoped_path_utf8r  r   r   r   r   r   r   r   r$   node_created_pathr8   node_created_revrJ   r   rG   r   r	   r   )re   r7   rf   r   r0   parent_rootr   r   cp_utf8cpcrs              r'   r   zSubversionNode.__init__  s   l[
JJ	y!(tz4!@!@ 	L#DIIL,,T[#tDD		+ L L L s,@,C,CDD!KLMM$)T-CTJJ	H$$T3'''&&ty$2H$OOw  D,BDII !R00 	<!D 24:r B BD25t/Dd/dE4hy.ABBBBBs   &B B4B//B4c                 2    | j         rdS t          |           S )z.Retrieve raw content as a "read()"able object.N)rE  FileContentStreamr   s    r'   get_contentzSubversionNode.get_content  s    : 	4 &&&r&   Tc                 |    | j         rdS || j        j                            d          n|}t	          | ||          S )z4Retrieve processed content as a "read()"able object.Nrx   )rE  r   r   r   rf  )re   keyword_substitutioneol_hintrx   s       r'   get_processed_contentz$SubversionNode.get_processed_content  sJ    : 	4:B:JDJ%))+666 	 ';YGGGr&   c              #   :  K   | j         rdS t          | j                  }t                              | j        | j        |          }|D ]R}t          j        | j	        t          |                    }t          || j        | j        | j        | j                  V  SdS )zoYield `SubversionNode` corresponding to entries in this directory.

        (wraps ``fs.dir_entries``)
        N)isfilerY   r0   r   dir_entriesr  r^  r   r-   r7   r8   r   rf   r   )re   r0   r   itemr7   s        r'   r   zSubversionNode.get_entries  s      
 ; 	FDI..D,BDII 	, 	,D>$)Yt__==D txTY!%, , , , , ,	, 	,r&   c              #     K   d}d}t          | j                  }d}| j                            | j        d| j        |          D ]\  }}t          | j        |          }|dk    rZ|rX||t          j	        f}|rE|d         |d         k    rt          j
        }nt          j        }|d         |d         |f}|dz  }|V  |}|r||k    r n|r|r||k     r|V  dS dS dS )z.Yield change events that happened on this pathNr   rA   )rY   r0   r   r  r7   rf   rG   rE   r   r,  r-  r.  )	re   r/  r2  r3  r0   r1  r7   rf   r@  s	            r'   r   zSubversionNode.get_history  s     DI,,TY48TJJ 	 	ID#%dj$77DQww4wsIM2  Qx58++!*!*"1XuQx8EqLGKKK E)) 	% 	7U??KKKKK	 	??r&   c           
      V   g | j         rfd}	 t          | j                  }t          d          }t          j        | j        j        t          | j                            }t          
                    |          }| j        j                            d|           ddlm} |                    ||||||                                | j                   nP# t          j        t&          f$ r7}t)          t+          d| j        t/          |                              |d}~ww xY wS )zaReturn a list the last changed revision for each line.
        (wraps ``client.blame2``)
        c                 2                         |           d S rL   )r   )line_norS   authordateliner0   annotationss         r'   blame_receiverz6SubversionNode.get_annotations.<locals>.blame_receiver  s    ""8,,,,,r&   r   zopening ra_local session to %r)clientz'svn blame failed on %(path)s: %(error)s)r7   r   N)rm  rT   rf   r   r-   r   r   r<   r^  r   r   r   r   r   ry  blame2create_contextr0   r   AttributeErrorrD  r   r7   r   )re   rx  rf   r  file_url_utf8ry  r   rw  s          @r'   get_annotationszSubversionNode.get_annotations  sj    ; 	O- - - - -Otx((  )J*HT5K,L,L!N !N !% 9 9- H H
##$D$13 3 3&&&&&&mS%n$3355tyB B B B,n= O O O"K'+y
1!G !G !G H HMNOO s   CC D&/2D!!D&c                     t                               | j        | j        | j                  }d |                                D             S )zdReturn `dict` of node properties at current revision.

        (wraps ``fs.node_proplist``)
        c                 N    i | ]"\  }}t          |          t          |          #S r%   r?  )r   r   r;   s      r'   
<dictcomp>z1SubversionNode.get_properties.<locals>.<dictcomp>  s<     2 2 2D% $5!1!1 2 2 2r&   )r   node_proplistr  r^  r0   itemsre   propss     r'   get_propertieszSubversionNode.get_properties  sK    
   D,BDINN2 2#(;;==2 2 2 	2r&   c                 j    | j         rdS t                              | j        | j        | j                  S )zfRetrieve byte size of a file.

        Return `None` for a folder. (wraps ``fs.file_length``)
        N)rE  r   file_lengthr  r^  r0   r   s    r'   get_content_lengthz!SubversionNode.get_content_length  s0    
 : 	4~~di)?KKKr&   c                 R    | j         rdS |                     t          j                  S )zqRetrieve mime-type property of a file.

        Return `None` for a folder. (wraps ``fs.revision_prop``)
        N)rE  	_get_propr   SVN_PROP_MIME_TYPEr   s    r'   get_content_typezSubversionNode.get_content_type'  s(    
 : 	4~~d5666r&   c                     t                               | j        | j        t          j        | j                  }|sdS t          t                              || j                            S )ziRetrieve timestamp of last modification, in micro-seconds.

        (wraps ``fs.revision_prop``)
        N)	r   revision_propr   r   r   SVN_PROP_REVISION_DATEr0   r   svn_time_from_cstring)re   _dates     r'   get_last_modifiedz SubversionNode.get_last_modified0  s[    
   d.>!%!<diI I 	4t99%KKLLLr&   c                 x    t                               | j        | j        || j                  }t          |          S rL   )r   	node_propr  r^  r0   r8   )re   r   r;   s      r'   r  zSubversionNode._get_prop;  s3    TY(>!Y( (r&   c                     t                               | j        | j                  }|r t                               |d                   S dS )zReturn the revision in which the node's path was created.

        (wraps ``fs.revision_root_revision(fs.closest_copy)``)
        r   N)r   closest_copyr  r^  revision_root_revision)re   root_and_paths     r'   get_branch_originz SubversionNode.get_branch_origin@  sG    
 	43IJJ 	?,,]1-=>>>	? 	?r&   c                    g }| j         | j        | j        f}|r6|\  }}}d}t                              ||          }|r|\  }}|                    d          }t                              |          }	d}
||k    r*|t          |          d                             d          }
t          	                    ||          }|r|\  }	}|                    d          }t          
                    | j        |	| j                  }|
r|d|
z   z  }t          | j        t          |                    }|r|                    ||	f           ||	|f}|6|S )a   Retrieve the list of `(path,rev)` copy ancestors of this node.
        Most recent ancestor first. Each ancestor `(path, rev)` corresponds
        to the path and revision of the source at the time the copy or move
        operation was performed.
        N   /)r^  rf   r  r   r  r.   r  rC   r>   copied_fromr   r   r0   rG   rE   r8   r   )re   	ancestorspreviousprevious_pathr  previous_rootr   r  r7   rf   relpathr  ui_paths                r'   get_copy_ancestryz SubversionNode.get_copy_ancestryI  sl    	*DHdi@ 	1;C8]L-H}EEI 1(t{{4((//55=(( ,CIIJJ7==dCCG nnT488 	1"-KS$;;t,,D++DKdiHHD /w.0Yt__MMG 9!(('3888 $c40H/  	10 r&   r[  )TNrL   )rn   ro   rp   r   rg  rk  r   r   r~  r  r  r  r  r  r  r  r%   r&   r'   r   r     s        !C !C !C !CF' ' 'H H H H, , ,   0  <	2 	2 	2L L L7 7 7	M 	M 	M     
? ? ?         r&   r   c                   (    e Zd ZddZd Zd Zd ZdS )r   Nc                 R   |j         | _         || _        || _        |j        | _        t	          |          | _        	 |                     t          j                  }n"# t          j	        $ r t          |          w xY w|                     t          j                  }t          |          }t          |          }|                     t          j                  }|r0t                              || j                  }t          |          }	nd }	t!          j        | |||||	           d S rL   )r   rf   rE   r   rY   r0   _get_revpropr   SVN_PROP_REVISION_LOGr   r   SVN_PROP_REVISION_AUTHORr8   r  r  r   r   r   )
re   r   rf   rE   r0   messagert  r  tsru  s
             r'   r   zSubversionChangeset.__init__n  s   9
lJJ		'''(BCCGG' 	' 	' 	'!#&&&	'""4#@AAG$$6""!!$"=>> 	++E49==B"2&&DDD4WfdCCCCCs   A A;c                     t                               | j        | j        | j                  }d |                                D             S )zVRetrieve `dict` of Subversion properties for this revision
        (revprops)
        c                     i | ]G\  }}|t           j        t           j        t           j        fv*t	          |          t	          |          HS r%   )r   r  r  r  r8   )r   kvs      r'   r  z6SubversionChangeset.get_properties.<locals>.<dictcomp>  s]     ; ; ;AqT7!:!8: : : !ill: : :r&   )r   revision_proplistr   rf   r0   r  r  s     r'   r  z"SubversionChangeset.get_properties  sJ     $$T[$(DIFF; ;!KKMM; ; ; 	;r&   c              #     K   t          | j                  }t          |          }t                              | j        | j        |          }	 t                              | j        ||          }n6# t          $ r) t          	                    | j        | j        |          }Y nw xY wt                              ||          \  }}t                              ||||           d}i i }	}g }
i }|j                                        D ].\  }}t          |          }t!          | j        |          s+|j        }|j        }t          |          }t          |          }|j        }t+          |dd          }t!          | j        |          sd\  }}|s|s| j        dk    rt,          j        }n+|r|t          j        k    r(|r%t,          j        }||	|                    d          <   n|j        s|s5t,          j        }|r&|r$t,          j        }|||                    d          <   nt,          j        }||v r	||         }n&t                              | j        ||          }|||<   |                                 t                              |||          }t          |          }t                               |||          }t!          | j        |          r||}}tB          |j"                 }tG          | j        |p|          }tG          | j        |          }|
$                    |||||g           |dz  }0|j%                                         tM                      |                                D ]9\  }}||	v r0t,          j'        |
|         d<   (                    |	|                    :fdtS          |
          D             }
|
*                                 |
D ]}tW          |          V  dS )	z`Retrieve file changes for a given revision.

        (wraps ``repos.svn_repos_replay``)
        r   actionN)Nr   r*   rA   r   c                 "    g | ]\  }}|v	|S r%   r%   )r   ir@  movess      r'   r   z3SubversionChangeset.get_changes.<locals>.<listcomp>  s-     - - -iae^^ +^^r&   ),rY   r0   r   r   r   rf   r   ChangeCollectorr|  RevisionChangeCollectorr   rG  svn_repos_replaychangesr  r8   rJ   rE   r7   	base_pathbase_revgetattrr   r-  CHANGE_ACTION_DELETEr+  r.   addedr,  r.  r   r_  r`  r$   	item_kindrG   r   rJ  setMOVEadd	enumeratesorttuple)re   r0   tmpr  rS  rT  rU  idxcopies	deletionsr  revrootsr   r@  rN  base_path_utf8r7   r  r  change_actionr  b_rootcbase_path_utf8
cbase_path	cbase_revrQ   r  r  r  s                               @r'   rZ  zSubversionChangeset.get_changes  s#     
 DI4jjTXt<<	P**4;dCCFF 	P 	P 	P224;$OOFFF	P**6488wtUGT:::	!'!5!5!7!7 6	 6	Iv ++H )X>> I#-NY''D!.11IH#FHd;;M )Y?? /&.#	8  @ @TZ3->->" @]e.HHH &-F69Ihooc2233 @Y @" 8 8&^F47F9++C001" x''%h/FF--dk8TJJF)/HX&		"$"6"6v~7:#< #<&77
//LL	(Z@@ @*4ixIF,-D%dj(2GiHHD*4:yAAINND$	8DEEE1HCC 	 LLNN 	( 	(DAqI~~ )
1		)A,'''- - - -9W+=+= - - - 	 	  	 F--	  	 s   !A0 00B#"B#c                     	 t                               | j        | j        || j                  S # t
          j        $ r'}| j                            d|| j                    d }~ww xY w)Nz %r of the %r cannot be retrieved)	r   r  r   rf   r0   r   r   r   r   )re   r   r   s      r'   r  z SubversionChangeset._get_revprop  sg    	##DK4KKK' 	 	 	HNN=tTXNNN	s   +. A$"AA$rL   )rn   ro   rp   r   r  rZ  r  r%   r&   r'   r   r   l  s]        D D D D,; ; ;Z  Z  Z x    r&   r   c                  F     G d dt           j                  }  |             S )Nc                   >    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	S )
*DiffChangeEditor.<locals>.DiffChangeEditorc                     g | _         d S rL   )rI  r   s    r'   r   z3DiffChangeEditor.<locals>.DiffChangeEditor.__init__  s    DKKKr&   c                     dt           j        fS )Nr*   )r   r-  )re   base_revisiondir_pools      r'   	open_rootz4DiffChangeEditor.<locals>.DiffChangeEditor.open_root  s    	&&r&   c                     | j                             |t          j        t          j        f           |t          j        fS rL   )rI  r   r	   r!   r   r,  )re   r7   	dir_batoncopyfrom_pathcopyfrom_revr  s         r'   add_directoryz8DiffChangeEditor.<locals>.DiffChangeEditor.add_directory  s0    KdnimDEEE&&r&   c                     ||d         fS r  r%   )re   r7   r  r  r  s        r'   open_directoryz9DiffChangeEditor.<locals>.DiffChangeEditor.open_directory  s    1%%r&   c                     |\  }}|t           j        k    r)| j                            |t          j        |f           d S d S rL   )r   r,  rI  r   r	   r!   )re   r  r   r;   r0   r7   r@  s          r'   change_dir_propz:DiffChangeEditor.<locals>.DiffChangeEditor.change_dir_prop  sE    $LD&&&""D$.&#ABBBBB '&r&   c                 T    | j                             |d t          j        f           d S rL   )rI  r   r   r+  )re   r7   rS   r  r0   s        r'   delete_entryz7DiffChangeEditor.<locals>.DiffChangeEditor.delete_entry  s(    KdI,<=>>>>>r&   c                 h    | j                             |t          j        t          j        f           d S rL   )rI  r   r	   r#   r   r,  )re   r7   r  r  copyfrom_revisionr  s         r'   add_filez3DiffChangeEditor.<locals>.DiffChangeEditor.add_file  s)    Kdi?@@@@@r&   c                 h    | j                             |t          j        t          j        f           d S rL   )rI  r   r	   r#   r   r-  )re   r7   r  	dummy_rev	file_pools        r'   	open_filez4DiffChangeEditor.<locals>.DiffChangeEditor.open_file  s)    Kdi@AAAAAr&   N)rn   ro   rp   r   r  r  r  r  r  r  r  r%   r&   r'   rF  r    s        	 	 	
	' 	' 	'	' 	' 	'
	& 	& 	&	C 	C 	C
	? 	? 	?	A 	A 	A	B 	B 	B 	B 	Br&   rF  )r   Editor)rF  s    r'   rF  rF    sH    B B B B B5< B B BB r&   c                   l   e Zd Zg dddgddgddgdgd	gd
Z ej        ej         eee	                                                    Z
 ej        d          Z ej        d          Zdddej        dk    rdnddZdZdZdZdZdZd#dZd Zd Zd Zd$dZd Zd Zd Zd Zd Z d Z!d  Z"d! Z#d" Z$dS )%rf  )LastChangedRevisionRevRevisionLastChangedDateDateLastChangedByAuthorHeadURLURLIdHeader)rf   ru  rt  r   idheaderz[ \t\v\n\b\r\f]+z%[abdDPrRu_%HI]   
s   
   r   )rz   r{   r|   ry      i   Nc                 |   d| _         d| _        |j        | _        || _        |j        | _        t                      | _        |rV|                     |                    t          j
                            | _        |                     | j                  | _        | j                            |d          dk    r<|                    t          j                  dk    rd| _        | j        |         | _        t                              t(                              |j        |j        | j                            | _        d S )Nr&   
ry   T)
translatedbufferr   r   r   rY   r0   _get_keyword_valuesr  r   SVN_PROP_KEYWORDSkeywords_build_keywords_rekeywords_reNEWLINESr   SVN_PROP_EOL_STYLE
native_eolnewlineStreamr   file_contentsr  r^  stream)re   r   ri  eols       r'   r   zFileContentStream.__init__;  s   Z
	kFF	   	F 44(,t7M(N(NP PDM#66t}EED=S$''4//t6778CC"DO=-DLkk""2"249373I379#> #> ? ?r&   c                     | S rL   r%   r   s    r'   	__enter__zFileContentStream.__enter__P  s    r&   c                 .    |                                   d S rL   )r   )re   etevtbs       r'   __exit__zFileContentStream.__exit__S  s    

r&   c                 X    d | _         d | _        t          | j                   d | _        d S rL   )r  r   r`   r0   r   s    r'   r   zFileContentStream.closeV  s+    di   			r&   c                     | j         t          d          | j        "| j        s|                     | j         |          S |                     | j         |          S )NzI/O operation on closed file)r  r   r  r	  
_read_dumb_read_substitute)re   r   s     r'   readzFileContentStream.read\  sW    ;;<<<#DO#??4;222((a888r&   c                 P    t                               | j        ||| j                  S rL   )r   r  r   r0   )re   r   rf   s      r'   r  zFileContentStream._get_revpropd  s     S$	BBBr&   c                    sd S t          t          d | j                                                          sd S | j        }t          |j        t                    }|                     |          }| 	                    |          }t          |j                  }t          |                     t          j        |j                            }|j                            d          }|j                            ||j                  p|}	|j                            d|j                  pd}
d                    |j        |||f          }i d|d|d|	d|d|d	d                    |	|||f          d
|d|j        d|d|d|d|d|
d|	ddddd|dd                    ||||f          ifd}i }| j                                        D ]B\  }t3          fd|D                       r"|                    fd|D                        CD ]G}d|vr|                    dd          \  }| j        vr| j                            ||          |<   H|rd |                                D             S d S )Nr*   rI    rf   rt  r   ru  r  r  z%az%bz%dz%Dz%Pz%rz%Rz%uz%_z%%%z%Iz%Hc                 Z    |                      d          }                     | |           S ri   )groupr   )matchdatas    r'   expandz5FileContentStream._get_keyword_values.<locals>.expand  s&    KKNNE88E5)))r&   c              3       K   | ]}|v V  	d S rL   r%   )r   kwr  s     r'   rA  z8FileContentStream._get_keyword_values.<locals>.<genexpr>  s'      44b2>444444r&   c              3   ,   K   | ]}|         fV  d S rL   r%   )r   r%  r"  r   s     r'   rA  z8FileContentStream._get_keyword_values.<locals>.<genexpr>  s,      AA2r4:.AAAAAAr&   =rA   c                     i | ];\  }}|                     d           t          |                               d           <S )r+   )r/   r   )r   r   r;   s      r'   r  z9FileContentStream._get_keyword_values.<locals>.<dictcomp>  sN     6 6 6"U JJw''U):):7)C)C 6 6 6r&   )listfilterKEYWORD_SPLIT_REsplitr   r   last_modifiedr   _format_shortdate_format_longdater   r   r8   r  r   r  r7   r.   r   r   rf   r-   r   KEYWORD_GROUPSr  anyr   KEYWORDSKEYWORD_EXPAND_REsub)re   r  r   mtime	shortdatelongdater   rt  r7   r   root_urlid_r#  valuesaliaseskeyword
definitionr"  r   s    `               @@r'   r  z%FileContentStream._get_keyword_valuesg  si    	4tT%:%@%@%J%JKKLL 	4yD.44**511	((//$*++ 4,,T-J-1-=? ? @ @y$$j%%dDH55=:**2tx88?Chh	;	6BCC
;
 (&
27
>Dh
#
 chh[)VDEE
 &	
 		
 ,0	
 =A(	

 $

 k

 ,0

 <@
 #
 S
 #'
 #((D+y&ABB
 
	* 	* 	* 	* 	* !06688 	B 	BMD'4444G44444 BAAAAAAAAAAA 	N 	NG'!!&}}S!44D*4=((#599&*MMt 	6 6&,llnn6 6 6 6 4r&   c           	          |rMt          j        dd                    t          t           j        |                    z  t           j                  S d S )Ns   
                [$]
                (?P<keyword>%s)
                (?:
                    :[ ][^$
]+?[ ]   |
                    ::[ ](?P<fixed>[^$
]+?)[ #]
                )?
                [$]   |)recompiler-   mapescapeVERBOSE)re   r  s     r'   r  z$FileContentStream._build_keywords_re  sS     	:  3ry(#;#;<<= 
   4r&   c                 ,    |                     d          S )Nz%Y-%m-%d %H:%M:%SZ)strftime)re   r5  s     r'   r.  z#FileContentStream._format_shortdate  s    ~~2333r&   c                     |                     d          }d}d}|||                                         ||j        dz
           dz  S )Nz.%Y-%m-%d %H:%M:%S +0000 (%%(a)s, %d %%(b)s %Y))MonTueWedThuFriSatSun)JanFebMarAprMayJunJulAugSepOctNovDecrA   )ab)rF  weekdaymonth)re   r5  textweekdaysmonthss        r'   r/  z"FileContentStream._format_longdate  sT    ~~NOOD<HU]]__5"5;?35 5 5 	5r&   c                 ,    |                     |          S rL   )r  )re   r  r   s      r'   r  zFileContentStream._read_dumb  s    {{1~~r&   c                    |d}| j         }| j        }	 d|cxk    rt          |          k    r#n n || _         ||d          | _        |d |         S t          |          | j        k     r1||                    | j                  pdz  }|s|| _         d| _        |S | j        r|                    d          nd}|dk    r||                     |          z  }d}|dk    r*||                     |d |                   z  }||d          }d }	 |                    dd          }|dk    r||                     |          z  }d}nS|| j        k     r| j        	                    |          }|rn+||                     |d |                   z  }||d          }|dk    s|s|dz  }|| 
                    |d |         |          z  }||d          })Nr   Tr   r&      $rA   )r  r   rC   KEYWORD_MAX_SIZEr  
CHUNK_SIZEr  find_translate_newliner!  _translate_keyword)re   r  r   r  r   posr!  s          r'   r  z"FileContentStream._read_substitute  s-   9A_
.	A((((Z((((($",QRR.!"1"~%6{{T222&++do66=#= &"(DK&)DO%% (,'7?&++d###RCbyyd55f===
Qwwd55fTcTlCCC
E&kk$**"99$"9"9&"A"AAJ F... ,226::E d55fTcTlCCC
& byyy 1HC$11&#,FFFJCDD\Fr&   c                 J    | j         r|                    d| j                  }|S )Nr  )r	  r   r
  )re   r"  s     r'   rh  z$FileContentStream._translate_newline  s&    ? 	5<<t|44Dr&   c           	      F   |                     d          }| j                            |          }||S |                     d          }|*| j        t	          |          z
  dz
  }|dk    rd|||fz  n|S t	          |          }d|||||t	          |          k     rdndfz  S )	Nr<  fixed   r   s   $%s: %.*s $s   $%s:: %-*.*s%s$   #    )r   r  r   re  rC   )re   r_  r!  r<  r;   rm  r   s          r'   ri  z$FileContentStream._translate_keyword  s    ++i((!!'**=KG$$=%G4q8A;<66>Wa$777tKE

A%Q5!c%jj..$$dKL Lr&   r[  rL   )%rn   ro   rp   r0  	functoolsreducer  unionrB  r:  r2  r@  rA  r+  r3  r   r   r  re  rf  r  r	  r
  r   r  r  r   r  r  r  r  r.  r/  r  r  rh  ri  r%   r&   r'   rf  rf  %  s        :99"F+"H-5!f*
 
N  y	33sN4I4I4K4K+L+LMMH!rz"566"
#566WE%'W__''%A AHJKJG? ? ? ?*      9 9 9 9C C C1 1 1f  4 4 45 5 5  4 4 4l  
L L L L Lr&   rf  rL   )<rq   rq  os.pathr   r@  r   urllib.parser   trac.apir   trac.configr   r   	trac.coretrac.versioncontrolr   r	   r
   r   r   r   r   trac.versioncontrol.cacher   	trac.utilr   trac.util.concurrencyr   trac.util.textr   r   r   trac.util.translationr   trac.util.datefmtr   r   r   trac.web.hrefr   r(   r2   r8   r<   r?   rG   rJ   rT   rW   rY   r`   rb   	Componentrt   r   r   r   rF  objectrf  r%   r&   r'   <module>r     sv  & <      				           ( ( ( ( ( ( 0 0 0 0 0 0 0 0    < < < < < < < < < < < < < < < < < < 7 6 6 6 6 6 & & & & & & + + + + + + D D D D D D D D D D # # # # # # ? ? ? ? ? ? ? ? ? ?      / / /, , ,  ( ( (
+ + +4 4 44 4 4    
6 6 6 6  
- - - - -* - - - L L L L L) L L L^eF eF eF eF eF: eF eF eFPM M M M MT M M M`F F F F F) F F Ff# # #LXL XL XL XL XL XL XL XL XL XLr&   