
    Kis                    d   d Z ddlmZ ddlZej                  dk  r> ed        edej                           e         ed        ej                  d       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  e
j"                  e      ZddZddZddZ	 	 	 	 	 	 ddZdddZddZddZy)a  CLI entry point for code-review-graph.

Usage:
    code-review-graph install
    code-review-graph init
    code-review-graph build [--base BASE]
    code-review-graph update [--base BASE]
    code-review-graph watch
    code-review-graph status
    code-review-graph serve
    code-review-graph visualize
    code-review-graph wiki
    code-review-graph detect-changes [--base BASE] [--brief]
    code-review-graph register <path> [--alias name]
    code-review-graph unregister <path_or_alias>
    code-review-graph repos
    )annotationsN)   
   z1code-review-graph requires Python 3.10 or higher.z  You are running Python z7Install Python 3.10+: https://www.python.org/downloads/   )PackageNotFoundError)version)Pathc                 r    	 t        d      S # t        $ r } t        j                  d|        Y d} ~ yd} ~ ww xY w)z"Get the installed package version.code-review-graphz7Package metadata unavailable, falling back to 'dev': %sNdev)pkg_versionr   loggerdebug)excs    a/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/code_review_graph/cli.py_get_versionr   *   s6    .// NPSTs   
 	616c                     t         j                  j                  d      ryt        t        j
                  d      syt        j
                  j                         S )z2Check if the terminal likely supports ANSI colors.NO_COLORFisatty)osenvirongethasattrsysstdoutr        r   _supports_colorr   3   s9    	zz~~j!3::x(::r   c                 F   t               } t               }| rdnd}| rdnd}| rdnd}| rdnd}| rdnd}| rdnd}t        dj                  g d| d	| d| d
| d| d| d| d| | d| d| d| d| d| d| d| d| d| d	| d| d| d| d| d| d| d| d| d| d| d| d| d| d| d | d!| d| d"| d#| d$| d%| d&| d'| d(| d)| d*| d+| d,| d| d-| d.| d/| d0| d1| d2| d3| d4| d5| d| d6| d7| d8| d9| d:| d;| d<| d;| d=| d             y>)?z?Print the startup banner with graph art and available commands.z[36m z[33mz[1mz[2mz[32mz[0m
u     ●──●──●u     │╲ │ ╱│z       r     vu     ●──u   ◆u	   ──●u     │╱ │ ╲│zStructural knowledge graph forzsmarter code reviewsz

  z	Commands:z
    installz3     Set up MCP server for AI coding platforms
    initz        Alias for install
    buildz       Full graph build z(parse all files)updatez      Incremental update z(changed files only)watchz'       Auto-update on file changes
    statusz       Show graph statistics
    	visualizez'   Generate interactive HTML graph
    wikiz4        Generate markdown wiki from communities
    detect-changesz Analyze change impact z(risk-scored review)registerz9    Register a repository in the multi-repo registry
    
unregisterz,  Remove a repository from the registry
    reposz(       List registered repositories
    postprocessz Run post-processing z(flows, communities, FTS)evalz&        Run evaluation benchmarks
    servez       Start MCP server

  Run z"code-review-graph <command> --helpzfor detailsN)r   r   printjoin)colorr   cybdgrs           r   _print_bannerr>   <   s   EnG 
A
A	A	A
A	A	    #c !"#456C79:;<=>EYGHcJ   c  C ! "#$ 	 	 c	 !	 "#	 $B	 CD	E	
 
 
 #
 %
 &'C
 (<
 =>3
? #  c C  c C  3 C  C ( )*s +< =>3? C  S * +, -A BCD C  C C  S C   C  3  C!  !  S!  0!  12s!  3G!  HIc! J!" C#" #" s#"#$ C%$ %$ %$%& C'& '& C'&'( C)( )( #)( +)( ,-#)( .G)( HIc)(J)* C+* +* 3+*+, C-, -, C-,-0 #10 	10 
10 10 C10 210 3410 5610 78S10 9D10 EF310G1 r   c                   ddl m}m} g }|dv rN| dz  }|j                         r(|j	                  d      }||vr#|j                  d       n|j                  d       |j                         D ]d  \  }}|d	k7  r||vr| |z  }	|	j                         r,|	j	                  d      }||vs<|j                  | d
       Q|j                  | d       f |S )zReturn the list of instruction files that ``install`` would write
    or modify, given the current state of the repo and the selected
    platform target. Used for the dry-run / confirm preview (#173).
    r   )_CLAUDE_MD_SECTION_MARKER_PLATFORM_INSTRUCTION_FILESclaudeallz	CLAUDE.mdutf-8encodingzCLAUDE.md (append)zCLAUDE.md (new)rD   z	 (append)z (new))skillsr@   rA   exists	read_textappenditems)
	repo_roottargetr@   rA   targets	claude_mdcontentfilenameownerspaths
             r   _instruction_files_to_modifyrU   e   s     OG""+	))7);G(734NN,-7==? 	0&U?vV38#;;=nngn6G(7(956NNhZv./	0 Nr   c                    t         j                  j                         s|S |rdnd}	 t        |  d| d      j	                         j                         }|s|S |dv S # t        t        f$ r t                Y yw xY w)u-  Prompt the user [Y/n] and return True for yes.

    Non-interactive environments (no TTY on stdin, e.g. an MCP wrapper
    piping the CLI) return ``default_yes`` without blocking — the
    stdio transport cannot safely read from stdin without corrupting
    the JSON-RPC stream. See: #173, #174
    z[Y/n]z[y/N]r4   F)r9   yes)	r   stdinr   inputstriplowerEOFErrorKeyboardInterruptr5   )promptdefault_yessuffixanswers       r   _confirm_yes_norb      s     99#WF&6(!,-335;;= \!! '( s   -A A98A9c                   ddl m}m} ddlm} | j
                  rt        | j
                        n |       }|st        j                         }t        | dd      }t        | dd      xs d}|dk(  rd	}t        | d
d      }t        | dd      }t        d        ||||      }	|	st        d       n)t        dt        |	       ddj                  |	              t        ||      }
|
r*t                t        d       |
D ]  }t        d|         |rt        d       t        d       y ||      }|dk(  rt        d       n|dk(  rt        d       nt        d       t        | dd      }t        | dd      }ddlm}m}m}m}m} |s ||      }t        d|        |sr|
rp|st%        d d!"      rU|d#v r ||        |||$       |
D cg c]  }|j'                  d%      d&    }}t        d'dj                  |              nt        d(       n|rt        d)       |s8|d#v r4 ||       t        d*|d+z  d,z           ||      }|rt        d-|        t                t        d.       t        d/       t        d0       yc c}w )1z3Set up MCP config for detected AI coding platforms.r   )"ensure_repo_gitignore_excludes_crgfind_repo_root)install_platform_configsdry_runFplatformrD   claude-coderC   rW   no_instructionszInstalling MCP server config...)rN   rg   zNo platforms detected.z
Configured z platform(s): , z)Graph instructions will be injected into:r"   z?
[dry-run] Would ensure .gitignore ignores .code-review-graph/.z![dry-run] No files were modified.Ncreatedz1Created .gitignore and added .code-review-graph/.updatedz,Updated .gitignore with .code-review-graph/.z0.gitignore already contains .code-review-graph/.	no_skillsno_hooks)generate_skillsinject_claude_mdinject_platform_instructionsinstall_git_hookinstall_hookszGenerated skills in z/Inject graph instructions into the files above?T)r_   rB   )rN   r4   r   z"Injected graph instructions into: z.Skipped instruction injection (user declined).z2Skipped instruction injection (--no-instructions).zInstalled hooks in z.claudezsettings.jsonz!Installed git pre-commit hook in zNext steps:z;  1. code-review-graph build    # build the knowledge graphz:  2. Restart your AI coding tool to pick up the new config)incrementalrd   re   rH   rf   repor	   cwdgetattrr5   lenr6   rU   rp   rq   rr   rs   rt   rb   split)argsrd   re   rf   rM   rg   rN   auto_yesskip_instructions
configuredinstr_targetstgitignore_stateskip_skills
skip_hooksrp   rq   rr   rs   rt   
skills_dirnamesgit_hooks                          r   _handle_initr      s   O0#'99TYY.2BIHHJ	dIu-GT:u-6FtUE*H&7?	
+,))FGTJ&'c*o.nTYYz=R<STU 1FCM9: 	ABqc(O	 PQ128CO)#AB	I	%<=@A
 $U3Kz51J  $Y/
$ZL12 =
 ** +(6B /<<QWWS\!_<E<6tyy7G6HIJBC	BC&$55i #I	$9O$K#LMN#I.5hZ@A	G	-	
GH	
FG# =s   Jc                 #   t        j                  dd      } | j                  dddd       | j                  d	
      }|j	                  dd      }|j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  dddd       |j                  ddt         j
                         |j                  ddt         j
                         |j                  ddd t         j
                  !       |j                  d"g d#d$d%&       |j	                  d'd(      }|j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  dddd       |j                  ddt         j
                         |j                  ddt         j
                         |j                  ddd t         j
                  !       |j                  d"g d#d$d%&       |j	                  d)d*      }|j                  ddd       |j                  d+dd,       |j                  d-dd.       |j	                  d/d0      }|j                  d1d2d3       |j                  ddd       |j                  d+dd,       |j                  d-dd.       |j	                  d4d5      }|j                  ddd       |j                  d6dd7       |j                  d8dd9       |j                  d:dd;       |j	                  d<d=      }|j                  ddd       |j	                  d>d?      }|j                  ddd       |j	                  d@dA      }	|	j                  ddd       |	j                  dBg dCdDdE&       |	j                  dFddG       |	j                  dHg dIdJdK&       |j	                  dLdM      }
|
j                  ddd       |
j                  dNddO       |j	                  dPdQ      }|j                  dRdS       |j                  dTddU       |j	                  dVdW      }|j                  dXdY       |j	                  dZd[       |j	                  d\d]      }|j                  d^dd_       |j                  ddd`       |j                  dddadb!       |j                  dcddd       |j                  deddf       |j	                  dgdh      }|j                  d1d2d3       |j                  diddj       |j                  ddd       |j	                  dkdl      }|j                  ddd       | j                         }|j                  rt        dmt                       y|j                  st                y|j                  dkk(  rdndolm}  ||j                  p       y|j                  d\k(  rdndqlm}m} dndrlm} t'        |dsdt      rt)        t'        |dud      xs dv      } ||      }t)        dw      }|j*                  j-                  dxdxy       |j/                  |dz{       t        d||         ||      }t        d}       t        |       yt'        |d~d      r7|j                  j1                  d      D cg c]  }|j3                          c}nd}t'        |dd      r7|j4                  j1                  d      D cg c]  }|j3                          c}nd}|s|st'        |dadt      st        d       y |||t'        |dud            }t        dt7        |       d       t        d       y|j                  dv rt9        |       y|j                  dv ryt;        j<                  t:        j>                  d       dndl m!}  |       }|j                  dPk(  rX	 |jE                  |jF                  |jH                        } | jK                  d      r	d| d    dnd}!t        d| dR    |!        y|j                  dVk(  rb|jW                  |jX                        rt        d|jX                          yt        d|jX                          tS        jT                  dn       y|j                  dZk(  r_|j[                         }|st        d       t        d       y|D ]1  } | jK                  dd      }#|#rd|# dnd}$t        d| dR    |$        3 yt;        j<                  t:        j>                  d       dndl.m/}% dndl0m1}&m2}'m3}(m4}) |j                  d4k(  r$|j                  rt)        |j                        n |&       }* |(|*      }+ |%|+      },	 dndl5m6}-  |-t'        |ddt       t'        |ddt       t'        |ddt       tQ        |*            }.g }/|.jK                  d      r|/jo                  |.d    d       |.jK                  d      r|/jo                  |.d    d       |.jK                  d      r|/jo                  |.d    d       t        ddjq                  |/      xs d        |,js                          y|j                  dv ru|j                  rt)        |j                        n |'       }*|*sst;        jN                  d|j                         t;        jN                  d       tS        jT                  dn       n(|j                  rt)        |j                        n |&       }* |(|*      }+ |%|+      },	 |j                  d)k(  rt'        |ddt      rdnt'        |ddt      rdnd}0dndl5m:}1  |1dxtQ        |*      |0      }.|.jK                  dd      }2|.jK                  dd      }3|.jK                  dd      }4t        d|2 d|3 d|4 d|0 d	       |.jK                  d      rt        dt7        |.d                 n|j                  d/k(  rt'        |ddt      rdnt'        |ddt      rdnd}0dndl5m:}1  |1dttQ        |*      |jv                  |0      }.|.jK                  dd      }5|.jK                  dd      }3|.jK                  dd      }4t        d|5 d|3 d|4 d|0 d	       n"|j                  d>k(  r|,jy                         }6t        d|6jz                          t        d|6j|                          t        d|6j~                          t        ddjq                  |6j                                t        d|6j                  xs dě        |,j                  dū      }7|,j                  dƫ      }8|7rt        d|7        |8rt        d|8dd         dndl0mC}9  |9|*      \  }:};|7r|:r|7|:k7  rt        d|7 d|: d͝       n|j                  d<k(  r |)|*|,       n|j                  d@k(  rdndl0mD}<  |<|*      }=t'        |ddJ      xs dJ}>|>dk(  r$dndlEmF}? |=dz  }@ |?|,|@       t        d|@        n|>dk(  r$dndlEmG}A |=dz  }@ |A|,|@       t        d|@        nf|>dk(  r$dndlEmH}B |=dz  }@ |B|,|@       t        d|@        n=|>dk(  r$dndlEmI}C |=dz  }@ |C|,|@       t        d|@        ndndlJmK}D |=dz  }Et'        |ddD      xs dD}F D|,E|F       t        d|F d|E        t'        |dkdt      rddlL}GddlM}HEj*                  }Id}J|Gj                  |Hj                  j                  tQ        |I            }Kt        d|J d       t        d       |Hj                  j                  d|Jf|K      5 }L	 Lj                          ddd       n5t        d       n(|j                  dLk(  rmdndl0mD}< dndlTmU}M  |<|*      dLz  }N |M|,|N|j                        }.|.d   |.d   z   |.d   z   }Ot        d|.d    d|.d    d|.d    d|O d	       t        d|N        n|j                  dgk(  rdndlWmX}P dndl0mY}QmZ}R |jv                  }S |Q|*|S      }T|Ts R|*      }TTst        d       nb P|,TtQ        |*      S      }.|j                  rt        |.jK                  dd             n%t        t        j                  |.dtP                     |,js                          yc c}w c c}w # tL        $ r=}"t;        jN                  tQ        |"             tS        jT                  dn       Y d}"~"yd}"~"ww xY w# |,js                          w xY w# t        $ r t        d       Y w xY w# 1 sw Y   xY w# |,js                          w xY w(   zMain CLI entry point.r   z7Persistent incremental knowledge graph for code reviews)progdescriptionz-vz	--version
store_truezShow version and exit)actionhelpcommand)destr$   z,Register MCP server with AI coding platforms)r   z--repoNzRepository root (auto-detected))defaultr   z	--dry-runz-Show what would be done without writing filesz--no-skillsz'Skip generating Claude Code skill filesz
--no-hooksz!Skip installing Claude Code hooksz--no-instructionszCSkip injecting graph instructions into CLAUDE.md / AGENTS.md / etc.z-yz--yesz@Auto-confirm instruction injection without an interactive promptz--skillsz--hooksz--allinstall_all)r   r   r   z
--platform)codexrC   ri   cursorwindsurfzedcontinueopencodeantigravityqwenkirorD   rD   z6Target platform for MCP config (default: all detected))choicesr   r   r%   zAlias for installr&   z%Full graph build (re-parse all files)z--skip-flowsz5Skip flow/community detection (signatures + FTS only)z--skip-postprocessz)Skip all post-processing (raw parse only)r'   z'Incremental update (only changed files)z--basezHEAD~1zGit diff base (default: HEAD~1)r0   z?Run post-processing on existing graph (flows, communities, FTS)z
--no-flowszSkip flow detectionz--no-communitieszSkip community detectionz--no-ftszSkip FTS rebuildr(   z!Watch for changes and auto-updater)   zShow graph statisticsr*   z-Generate interactive HTML graph visualizationz--mode)autofull	communityfiler   z8Rendering mode: auto (default), full, community, or filez--servezDStart a local HTTP server to view the visualization (localhost:8765)z--format)htmlgraphmlcypherobsidiansvgr   zExport format (default: html)r+   z/Generate markdown wiki from community structurez--forcez.Regenerate all pages even if content unchangedr-   z0Register a repository in the multi-repo registryrT   zPath to the repository rootz--aliaszShort alias for the repositoryr.   z0Remove a repository from the multi-repo registrypath_or_aliasz"Repository path or alias to remover/   zList registered repositoriesr1   zRun evaluation benchmarksz--benchmarkz{Comma-separated benchmarks to run (token_efficiency, impact_accuracy, flow_completeness, search_quality, build_performance)z!Comma-separated repo config namesrun_allzRun all benchmarksz--reportzGenerate report from resultsz--output-dirzOutput directory for resultsr,   zAnalyze change impactz--briefzShow brief summary onlyr2   z"Start MCP server (stdio transport)zcode-review-graph r   )main)rM   )generate_full_reportgenerate_readme_tables)run_evalreportF
output_dirzevaluate/resultszevaluate/reports/summary.mdT)parentsexist_okrE   rF   zReport written to z$
--- README Tables (copy-paste) ---
rv   ,	benchmarkz2Specify --all, --repo, or --benchmark. See --help.)r/   
benchmarksr   z
Completed z benchmark(s).z9Run 'code-review-graph eval --report' to generate tables.)r%   r$   )r-   r.   r/   z%(levelname)s: %(message)s)levelformat)Registry)aliasr   z	 (alias: )r    zRegistered: zUnregistered: zNot found: zNo repositories registered.z5Use: code-review-graph register <path> [--alias name]z  (r"   )
GraphStore)find_project_rootre   get_db_pathr(   )run_postprocessno_flowsno_communitiesno_fts)flowscommunitiesftsrM   flows_detectedz flowscommunities_detectedz communitiesfts_indexedz FTS entrieszPost-processing: rk   done)r'   r,   z7Not in a git repository. '%s' requires git for diffing.z6Use 'build' for a full parse, or run 'git init' first.skip_postprocessnone
skip_flowsminimalr   )build_or_update_graph)full_rebuildrM   r0   files_parsedr   total_nodestotal_edgeszFull build: z files, z nodes, z edges (postprocess=errorszErrors: )r   rM   baser0   files_updatedzIncremental: z files updated, zNodes: zEdges: zFiles: zLanguages: zLast updated: never
git_branchgit_head_shazBuilt on branch: zBuilt at commit:    )_git_branch_infozWARNING: Graph was built on 'z' but you are now on 'z,'. Run 'code-review-graph build' to rebuild.)get_data_dirr   r   )export_graphmlzgraph.graphmlzGraphML exported: r   )export_neo4j_cypherzgraph.cypherzNeo4j Cypher exported: r   )export_obsidian_vaultzObsidian vault exported: r   )
export_svgz	graph.svgzSVG exported: )generate_htmlz
graph.htmlmode)r   zVisualization (z): i="  )	directoryzServing at http://localhost:z/graph.htmlzPress Ctrl+C to stop.	localhostz
Server stopped.zOpen in browser to explore.)generate_wiki)forcepages_generatedpages_updatedpages_unchangedzWiki: z new, z
 updated, z unchanged (z total pages)zOutput: )analyze_changes)get_changed_filesget_staged_and_unstagedzNo changes detected.)rM   r   summaryzNo summary available.   )indentr   )^argparseArgumentParseradd_argumentadd_subparsers
add_parserSUPPRESS
parse_argsr   r5   r   r   r>   r   rv   eval.reporterr   r   eval.runnerr   rx   r	   parentmkdir
write_textrz   rZ   r   ry   r   loggingbasicConfigINFOregistryr   r-   rT   r   r   
ValueErrorerrorstrr   exitr.   r   
list_reposgraphr   ru   r   re   r   r(   tools.buildr   rK   r6   closer   r   	get_statsr   r   files_count	languageslast_updatedget_metadatar   r   exportsr   r   r   r   visualizationr   	functoolshttp.serverpartialserverSimpleHTTPRequestHandler
HTTPServerserve_foreverr]   r+   r   r   changesr   r   r   briefjsondumps)Uapsubinstall_cmdinit_cmd	build_cmd
update_cmdpp_cmd	watch_cmd
status_cmdvis_cmdwiki_cmdregister_cmdunregister_cmdeval_cmd
detect_cmd	serve_cmdr{   
serve_mainr   r   r   r   r   report_pathtablesr=   r/   r:   r   resultsr   r   entry
alias_infor   r   	alias_strr   r   re   r   r(   rM   db_pathstorer   resultpartsppr   parsednodesedgesrm   statsstored_branch
stored_shar   current_branchcurrent_shar   data_dirfmtr   outr   r   r   r   	html_pathvis_moder	  http	serve_dirporthandlerhttpdr   wiki_dirtotalr   r   r   r   changedsU                                                                                        r   r   r      s   		 	  M
B OOk,5L   



+C ..F ! K Xt:[\L<   l6   \0   LR   glO  
 Z8CTCTUY|(BSBSTW\"*"3"3  5
 E   ~~(  H (D7XYL<   l6   \0   LR   glO   *\@Q@QR)Lx?P?PQ',]"*"3"3  5
 E   w-TUI8T8YZ|D   \8   /XYJHh=^_Hd9Z[|D   \8   ^^N  F $5VW
\@UV
*<F`a

<>PQ w-PQI8T8YZ /FGJHd9Z[ nn[/^n_G46WX5G	   ,S   @,	   ~~f+\~]H(D7XY,=   >>K " L f+HIi<\] ^^M $ N 6Z[ NN7!?N@ ~~f+F~GHtE  
 (D7Z[',YMab*\@^_.$=[\  07NOJ()J   ,-F   Hd9Z[ w-QRI8T8YZ==?D||"<>"234<<||w,TYY'||vO)45)lD1G5GJ **5F<=K$$TD$A""6G"<&{m45+J7F:;&M0 	) 4. %)IIOOC$89q9  4d3 %)NN$8$8$=>q>  GD)U4SJK%"4t<G
 LWn=>MN||**T||::',,7ST&:<<:% ))$))4::)F>Cii>Pyw(8:VX
U6]OJ<@A( 	! \\\)""4#5#56t'9'9&:;< 	 D$6$6#789 	 \\W$'')E34MN 		 # ;E!IIgr2E27#eWARIBuV}oi[9:; 	gll3OP!  ||}$'+yyDO6G6I	i(7#	4$!$
E:: '.> FFh66i.	F Ezz*+'7 89@Azz01'= >?|LMzz-(} 56lCD%dii&6&@&%ABCKKM||33'+yyDOn6F	MMI MMRSHHQK'+yyDO6G6I	)$GwE]<<7""4);UC$T<?	V  ;*!S^F ZZ2FJJ}a0EJJ}a0Evhh'% )!!#A'
 zz(#VH%5!6 789\\X%"4);UC$T<?	V  ;*"c)nYYBF jj!4GJJ}a0EJJ}a0Ey(8'% )!!#A' \\X%OO%EGE--./0GE--./0GE--./0K		%// :;<=N5#5#5#@"ABC!..|<M++N;J)-9:)*Sb/):;<5*:9*E'NKM^4S3M? C++9*: ;@A \\W$)U#\\[(1#I.H$&1;VCi30uc**3%018/#E3//u56
":+%eS11#78/,5#&se,-8$|3	"48BFeYX>zYK@A4%0$& ) 0 0ID'//<<"%i. 0 G 6tf%' 12//$d+W 77!//1	7 7 78\\V#1+#I.7H"5($**EF,-0GG&QbJccE 1236/*+:+,- .7-) HXJ'(\\--0O99D'	48G1)<,-(!)n	 ::&**Y0GHI$**VAsCD 	S :
 ?@  c#h'" 	'h KKMJ  1 7!"5677 7` 	s   AD+AD01AAD5 (CAE> P:AF: 	AF.AFD?AF: D5	AE;D>3AE6E6AE;E>AFFAF+F'AF.F*AF+F+AF.F.AF7F3AF: F:AG)returnr   )rE  bool)rE  None)rM   r	   rN   r   rE  z	list[str])T)r^   r   r_   rF  rE  rF  )r{   zargparse.NamespacerE  rG  )__doc__
__future__r   r   version_infor5   r   r   r   r  r   r   importlib.metadatar   r   pathlibr	   	getLogger__name__r   r   r   r>   rU   rb   r   r   r   r   r   <module>rO     s   $ # 
 g	
=>	%ckk]
34	G	
CDCHHQK    	 3 5 			8	$&R D"*^HBur   