Ë
    Î£jYG  ã                   óÄ  — d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
  ej                  «       ZdZdZd	Zd
Ze G d„ d«      «       Zdedefd„Zdedefd„Zdededefd„Zdedededz  fd„Zdedeeef   dedz  defd„Z	 d/dededeeef   dedz  ddf
d„Z	 d/dededeeef   dedz  ddf
d„Zdeddfd„Z	 d/d ed!ededeeef   dedz  dee   fd"„Zd#ee   de ejB                  e   dz  eeef   dz  f   fd$„Z"d%ed&ejB                  e   dz  d'eeef   dz  d(edef
d)„Z#d!ed*ee   d#ee   ddfd+„Z$d!ed#ee   ddfd,„Z%efdd-œd!ededeeef   dz  defd.„Z&y)0aþ  
MDL material-directory relocation pass for the install pipeline.

For each MDL in the staged mod tree, rewrites its materialDirectories[] so the
mod's material trees live under a the console prefix, while preserving the
un-relocated original paths as fallbacks.

Pipeline (run in order):

  1. relocate_mdl_dirs       - rewrite each MDL's material_dirs (prefixed at
                                original index, original appended for vanilla
                                fallback) and physically move
                                materials/<old>/ -> materials/<prefix>/<old>/
  2. relocate_material_names - re-prefix path-rooted material name entries
                                (some MDLs bake the path into the name when
                                $cdmaterials is blank)
  3. update_vmt_refs         - rewrite $basetexture / $bumpmap / etc. references
                                inside every VMT to point at the new location
                                when the relocated VTF/VMT exists there
é    N)Ú	dataclass)ÚPath)ÚMDLFile)ÚmoveÚconsole)r   zvgui/replay/thumbnailsz[A-Za-z0-9_./\-]z[^A-Za-z0-9_./\-]c                   ó"   — e Zd ZU eed<   eed<   y)Ú
RelocationÚold_dirÚnew_dirN)Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__© ó    úOC:\Users\pivot\Documents\cueki\casual-preloader\core\operations\mdl_relocate.pyr	   r	   0   s   … àƒLØ„Lr   r	   ÚpathÚreturnc                 óB   — | j                  dd«      j                  «       S )NÚ\Ú/)ÚreplaceÚlower)r   s    r   Ú_normr   6   s   € Ø�<‰<˜˜cÓ"×(Ñ(Ó*Ð*r   Údir_strc                 ór   ‡— | j                  d«      j                  «       Št        ˆfd„t        D «       «      S )Nr   c              3   óF   •K  — | ]  }‰j                  |d z   «      –— Œ y­w)r   N)Ú
startswith)Ú.0ÚrootÚ
normalizeds     €r   Ú	<genexpr>z&_is_under_safe_root.<locals>.<genexpr><   s!   øè ø€ ÐM¹_°Tˆz×$Ñ$ T¨C¡Z×0¹_ùs   ƒ!)Úlstripr   ÚanyÚSAFE_PATH_ROOTS)r   r"   s    @r   Ú_is_under_safe_rootr'   :   s+   ø€ Ø—‘ Ó$×*Ñ*Ó,€JÜÓM½_ÓMÓMÐMr   Úprefixc                 óº   — | r@| dk(  s;t        | «      s0| j                  «       j                  |› d�j                  «       «      r| S | j                  d«      }|› d|› �S )ae  Prepend prefix to a material dir.

    Empty and lone-root entries (`/`) are left untouched. Prefixing
    them would (a) be meaningless as a search path, (b) scoop up the entire
    materials/ tree on disk if we tried to move it, and (c) generate a
    text-replace rewrite of `/` -> `console/` that catastrophically corrupts
    every VMT it touches.
    r   )r'   r   r   r$   )r   r(   Ústrippeds      r   Ú
add_prefixr+   ?   s]   € ñ Ø�cŠ>Ü˜wÔ'Ø�=‰=‹?×%Ñ%¨¨° l×&8Ñ&8Ó&:Ô;àˆØ�~‰~˜cÓ"€HØˆX�Q�x�jÐ!Ð!r   r!   Úrel_pathc                 óž  ‡— t        |«      j                  d«      }|s| j                  «       r| S dS | }|j                  d«      D ]o  }|r|dk(  rŒ|dk(  r&|| k(  r y|j                  }|j                  «       s yŒ6|j                  «       Š	 t        ˆfd„|j                  «       D «       d«      }|€ y|}Œq |S # t        t        f$ r Y  yw xY w)a(  Resolve `rel_path` under `root` case-insensitively, the way the Source
    engine does on Windows. Linux is case-sensitive, but a mod authored on
    Windows can ship files whose case differs from the MDL's references; plain
    `Path.exists()` would say 'missing' and trigger spurious work.
    r   NÚ.z..c              3   ó^   •K  — | ]$  }|j                   j                  «       ‰k(  sŒ!|–— Œ& y ­w©N)Únamer   )r    ÚeÚtargets     €r   r#   zresolve_ci.<locals>.<genexpr>i   s%   øè ø€ ÐSÑ%6 ¸!¿&¹&¿,¹,».ÈFÓ:Rœ!Ñ%6ùs   ƒ"-¦-)
r   ÚstripÚexistsÚsplitÚparentr   ÚnextÚiterdirÚOSErrorÚNotADirectoryError)r!   r,   ÚrelÚcurrentÚpartÚmatchr3   s         @r   Ú
resolve_cir@   S   sÖ   ø€ ô �‹/×
Ñ
 Ó
$€CÙØ—{‘{”}ˆtÐ.¨$Ð.Ø€GØ—	‘	˜#–ˆÙ�t˜s’{ØØ�4Š<Ø˜$ŠÙØ—n‘nˆGØ—>‘>Ô#ÙØØ—‘“ˆð	ÜÓS W§_¡_Ô%6ÓSÐUYÓZˆEð ˆ=ÙØ‰ð# ð$ €Nøô Ô+Ð,ò 	Úð	ús   Â#B9Â9CÃCÚsrc_fileÚfile_originÚmdl_addon_idxc                 ó@   — |€y|j                  | «      }|du xs ||k(  S )zDTrue if src_file should move alongside the MDL being relocated.
    NT)Úget)rA   rB   rC   Úorigins       r   Ú_origin_matchesrG   r   s/   € ð
 ÐØØ�_‰_˜XÓ&€FØ�Tˆ>Ò4˜V }Ñ4Ð4r   ÚsrcÚdstc                 óp  — |€g }| j                  d«      D ]J  }|j                  «       sŒ|j                  |d«      }|€Œ)|j                  |j	                  | «      |f«       ŒL t        | |«       |D ]  \  }}||||z  <   Œ y|j                  dd¬«       t        | j                  d«      «      D ]z  }|j                  «       sŒt        |||«      sŒ"|j	                  | «      }||z  }	|	j                  j                  dd¬«       |j                  |d«      }t        ||	«       |€Œv|||	<   Œ| t        | «       y)zuMove src tree to dst (which must not exist) and migrate file_origin
    keys from the old paths to the new ones.
    NÚ*T)ÚparentsÚexist_ok)ÚrglobÚis_fileÚpopÚappendÚrelative_tor   ÚmkdirÚlistrG   r7   Ú_sweep_empty_subdirs)
rH   rI   rB   rC   ÚcapturedÚfÚidxr<   rA   Údst_files
             r   Ú_move_with_originrZ   }   s+  € ð ÐØ+-ˆØ—‘˜3–ˆAØ�y‰y�{Ø!—o‘o a¨Ó.�Ø‘?Ø—O‘O Q§]¡]°3Ó%7¸Ð$=Õ>ð	  ô 	ˆS�#Œã ‰HˆC�Ø%(ˆK˜˜c™	Ò"ð !àà‡I�I�d T€IÔ*Ü˜Ÿ™ 3›Ö(ˆØ×ÑÔ!ØÜ˜x¨°mÔDØØ×"Ñ" 3Ó'ˆØ˜‘9ˆØ�‰×Ñ d°TÐÔ:Ø�o‰o˜h¨Ó-ˆÜˆX�xÔ Ø‰?Ø$'ˆK˜Ò!ð )ô ˜Õr   c                 óÈ  — t        | j                  d«      «      D ]º  }|j                  «       sŒt        |||«      sŒ"|j	                  | «      }||z  }|j                  |d«      }|j                  «       rJ|j                  |d«      }||kD  r"|j                  «        t        ||«       |||<   Œ“|j                  «        Œ¤t        ||«       |dk7  sŒ¶|||<   Œ¼ t        | «       y)aø  File-by-file merge of src tree into an existing dst tree.

    Per-file collisions are resolved by load order via file_origin: the file
    from the later-loaded addon wins. Files without an origin entry (e.g.
    config files copied outside the addon staging loop) are treated as
    lowest priority. This is the scenario where mod A ships content under
    `materials/console/...` and mod B ships overlapping content under the
    un-prefixed path; without merging here, mod B's content would be stranded
    at the un-prefixed location.

    When mdl_addon_idx is set, only files belonging to that addon (or with no
    recorded origin) are considered for merging; cross-addon files stay at
    src to be reached via the MDL's un-prefixed fallback dir.
    rK   éÿÿÿÿN)rT   rN   rO   rG   rR   rP   r5   rE   Úunlinkr   rU   )	rH   rI   rB   rC   rA   r<   rY   Úsrc_idxÚdst_idxs	            r   Ú_merge_intor`   £   sÑ   € ô$ ˜Ÿ™ 3›Ö(ˆØ×ÑÔ!ØÜ˜x¨°mÔDØØ×"Ñ" 3Ó'ˆØ˜‘9ˆØ—/‘/ (¨BÓ/ˆà�?‰?ÔØ!—o‘o h°Ó3ˆGØ˜Ò Ø—‘Ô!Ü�X˜xÔ(Ø(/�˜HÒ%à—‘Õ!ä�˜8Ô$Ø˜"‹}Ø(/�˜HÒ%ð) )ô, ˜Õr   c                 óÔ   — | j                  d«      D �cg c]  }|j                  «       sŒ|‘Œ }}t        |d„ d¬«      D ]  }	 |j                  «        Œ yc c}w # t        $ r Y Œ'w xY w)zÜRemove now-empty subdirectories of src, deepest first, so the caller's
    rmdir of src succeeds when all files moved out. Non-empty branches (e.g.
    cross-addon files left behind by scoped moves) are left intact.
    rK   c                 ó,   — t        | j                  «      S r0   )ÚlenÚparts©Úps    r   Ú<lambda>z&_sweep_empty_subdirs.<locals>.<lambda>Ô   s   € ¬S°·±¬\r   T©ÚkeyÚreverseN)rN   Úis_dirÚsortedÚrmdirr:   )rH   rf   ÚsubdirsÚsubs       r   rU   rU   Î   sd   € ð
 Ÿ)™) Cœ.Ó7™.�Q¨A¯H©H­JŠq˜.€GÐ7Ü�gÑ#9À4×Hˆð	Ø�I‰I�Kñ Iùò 8øô ò 	Ùð	ús   ”AªAÁAÁ	A'Á&A'Úmdl_pathÚworking_rootc           
      óÒ  — t        | «      }|dz  }g }g }g }	| j                  |«      }
t        j                  d|
› d�«       |j                  D �]â  }t        |«      j                  d«      }t        ||«      }||k(  r|j                  |«       ŒA|j                  d«      }|j                  d«      }t        ||«      }t        ||«      }||z  }|€-|€+|j                  |«       t        j                  d|› d�«       Œ¯|j                  |«       ||vr|j                  |«       |	j                  t        |j                  d«      dz   |j                  d«      dz   ¬«      «       t        j                  d|›d	|›d
|›d�«       |€t        j                  d|› d�«       �ŒQ|�+t        ||||«       t        j                  d|› d|› d�«       n*t        ||||«       t        j                  d|› d|› d�«       	 |j                  «        |j                   D ]  }||k(  r �ŒÐ	 |j                  «        Œ �Œå |j#                  ||z   «       |	S # t        $ r Y ŒNw xY w# t        $ r Y  �Œw xY w)a“  Rewrite one MDL's material_dirs to use the prefix and move on-disk
    material trees to match.

    For each relocated entry we put the prefixed path *at the original index*
    (so the engine searches mod content first within that slot) and append the
    un-relocated original to the end of the list. Keeping the original gives
    the engine a path to reach vanilla VMTs that the mod doesn't ship + the
    mod sometimes populates a directory only partially and relies on engine
    fallback for shared textures (eyeballs, masks, invuln effects, etc.).
    Without the fallback path in the search list, those vanilla materials
    become unreachable.
    Ú	materialsÚ[Ú]r   zskip: materials/z/ not present in mod)r
   r   zrewrote material_dir: ú -> z  (kept z as fallback)zon-disk: materials/z'/ already exists (moved by another MDL)zmerged on-disk: materials/z/ -> materials/zmoved on-disk: materials/)r   rR   ÚlogÚdebugÚmaterial_dirsr   r$   r+   rQ   Úrstripr@   r	   r`   rZ   rm   r:   rL   Úrewrite_material_dirs)rp   rq   r(   rB   rC   ÚmdlÚmaterials_rootÚnew_dirsÚfallback_dirsÚrelocationsÚrel_mdlÚrawÚoldÚproposedÚold_relÚnew_relrH   rI   Úcanonical_dstr7   s                       r   Ú_relocate_one_mdlrˆ   Û   ss  € ô& �(Ó
€CØ! KÑ/€Nà€HØ!€MØ$&€Kà×"Ñ" <Ó0€GÜ‡I�I��'�˜!ˆnÔà× Õ ˆô �C‹j×Ñ Ó$ˆÜ˜c 6Ó*ˆØ�(Š?Ø�O‰O˜CÔ Øà—*‘*˜S“/ˆØ—/‘/ #Ó&ˆÜ˜¨Ó1ˆÜ˜¨Ó1ˆØ&¨Ñ0ˆàˆ;˜3˜;Ø�O‰O˜CÔ Ü�I‰IÐ(¨¨	Ð1EÐFÔGØà�‰˜Ô!Ø�mÑ#Ø× Ñ  Ô%Ø×Ñœ:Ø—J‘J˜s“O cÑ)Ø—O‘O CÓ(¨3Ñ.ô
ô 	ô 	�	‰	Ð*¨3¨'°°h°\ÀÈ#ÈÐP]Ð^Ô_àˆ;ä�I‰IÐ+¨G¨9Ð4[Ð\Ô]Ùàˆ?ô
 ˜˜]¨K¸ÔGÜ�I‰IÐ2°7°)¸?È7È)ÐSTÐUÕVä˜c =°+¸}ÔMÜ�I‰IÐ1°'°¸/È'ÈÐRSÐTÔUð	Ø�I‰IŒKð —k”kˆFØ˜Ò'ÚðØ—‘•ò	 "ðo !ð~ ×Ñ˜h¨Ñ6Ô7ØÐøô ò 	Ùð	ûô ò Ûðús$   Ç6I	ÈIÉ		IÉIÉ	I&É%I&r€   c                 ó@  — t        | D �ch c]  }|j                  |j                  f’Œ c}d„ d¬«      }|sydj                  d„ |D «       «      }t	        j
                  dt        › dt        › d	|› d
t        › d�	t        j                  «      }t        |«      }||fS c c}w )a;  Build a single-pass regex + mapping from a list of relocations.

    Prefixes are sorted longest-first so a more specific rule wins. The
    path-char lookbehind anchors the match to a path-token boundary;
    without it, an already-prefixed path would match an inner rule and
    get a doubled prefix. The extra `(?<=materials/)` alternative carves
    out the one place where matching after a `/` is desirable: Patch VMT
    `include "materials/..."` directives. Without that carve-out, those
    includes never get rewritten when their target file gets relocated.
    c                 ó   — t        | d   «      S ©Nr   ©rc   re   s    r   rg   z&_build_rewrite_regex.<locals>.<lambda>J  ó   € ”c˜!˜A™$”ir   Trh   )NNÚ|c              3   óL   K  — | ]  \  }}t        j                  |«      –— Œ y ­wr0   )ÚreÚescape)r    rƒ   Ú_s      r   r#   z'_build_rewrite_regex.<locals>.<genexpr>O  s   è ø€ Ð=±u©V¨S°!œ"Ÿ)™) CŸ.±uùs   ‚"$z(?:(?<=materials/)|(?<=z/)|(?<!z))(?P<prefix>z
)(?P<tail>z*))
rl   r
   r   Újoinr�   ÚcompileÚ_PATH_BOUNDARY_CHARSÚ_PATH_TAIL_CHARSÚ
IGNORECASEÚdict)r€   ÚrÚpairsÚ
prefix_altÚpatternÚmappings         r   Ú_build_rewrite_regexrž   ;  s«   € ô Ù)4Ó5© Aˆ!�)‰)�Q—Y‘YÒ	¨Ñ5ÙØô€Eñ
 ØØ—‘Ñ=±uÓ=Ó=€JÜ�j‰jØ
!Ô"6Ð!7°wÔ?OÐ>Pð QØ �\ Ô,<Ð+=¸Rð	Aä
�‰ó€Gô
 �5‹k€GØ�GÐÐùò 	6s   ŠBÚtextrœ   r�   r}   c                 ó~   ‡‡— |�‰€| S dt         j                  t           dt        fˆˆfd„}|j                  || «      S )z�Rewrite path refs whose target file exists at the new location; leave
    refs that don't (they're relying on engine fallback to vanilla).
    Úmr   c                 ó  •— | j                  d«      }| j                  d«      }‰|j                  «          }|s|S ||z   }|j                  dd«      d   }d|v r|f}n|dz   f}t        ˆfd„|D «       «      r||z   S | j                  d	«      S )
Nr(   Útailr   é   r\   r.   z.vtfc              3   ó:   •K  — | ]  }t        ‰|«      d u–— Œ y ­wr0   )r@   )r    Úcr}   s     €r   r#   z8_apply_path_rewrites.<locals>.replace.<locals>.<genexpr>q  s   øè ø€ ÐMÁ*¸QŒz˜.¨!Ó,°DÔ8Á*ùs   ƒr   )Úgroupr   Úrsplitr%   )	r¡   r(   r£   Ú
new_prefixÚfull_newÚlast_segmentÚ
candidatesr�   r}   s	          €€r   r   z%_apply_path_rewrites.<locals>.replacee  s™   ø€ Ø—‘˜Ó"ˆØ�w‰w�v‹ˆØ˜VŸ\™\›^Ñ,ˆ
ÙØÐØ Ñ$ˆØ—{‘{ 3¨Ó*¨2Ñ.ˆØ�,ÑØ"˜‰Jà" VÑ+Ð-ˆJÜÓMÁ*ÓMÔMØ Ñ$Ð$Ø�w‰w�q‹zÐr   )r�   ÚMatchr   ro   )rŸ   rœ   r�   r}   r   s     `` r   Ú_apply_path_rewritesr®   Y  sA   ù€ ð €˜'˜/Øˆð”2—8‘8œC‘=ð ¤Sö ð  �;‰;�w Ó%Ð%r   Ú	mdl_pathsc           
      óô  ‡‡— |syt        |D �ch c]  }|j                  |j                  f’Œ c}d„ d¬«      Š| dz  Šdt        dt        fˆˆfd„}|D ]™  }t	        |«      }|j
                  D �cg c]
  } ||«      ‘Œ }}||j
                  k(  rŒ=|j                  |«       t        |j
                  |«      D ]3  \  }	}
|	|
k7  sŒt        j                  d	|j                  › d
|	›d|
›�«       Œ5 Œ› yc c}w c c}w )a  Rewrite per-material name strings whose path-rooted prefix matches a
    relocation. Some MDLs reference materials by full path (e.g. material name
    'models/weapons/c_items/c_buffbanner' paired with an empty material_dir);
    the engine resolves these via 'materials/<name>.vmt'. When that on-disk
    location has been moved, the name itself must be re-prefixed.

    Each rewrite is gated on the candidate VMT existing at the new location.
    Without that check, an MDL that references both a mod-shipped material
    *and* a vanilla material under the same prefix would have both names
    re-prefixed; the vanilla one would then point at materials/console/...
    where nothing was shipped, and the engine has no path back to the
    original vanilla VMT.
    Nc                 ó   — t        | d   «      S r‹   rŒ   re   s    r   rg   z*_relocate_material_names.<locals>.<lambda>Š  r�   r   Trh   rs   r1   r   c                 óì   •— t        | «      j                  d«      }d|vr| S ‰D ]M  \  }}|j                  |«      sŒ||t        |«      d  z   dz   }t	        ‰|«      €| c S ||t        |«      d  z   c S  | S )Nr   z.vmt)r   r$   r   rc   r@   )r1   r"   rƒ   ÚnewÚ	candidater}   rš   s        €€r   Úrewrite_namez._relocate_material_names.<locals>.rewrite_name�  s‰   ø€ Ü˜4“[×'Ñ'¨Ó,ˆ
Ø�jÑ ØˆKÛ‰HˆC�Ø×$Ñ$ SÕ)Ø *¬S°«X¨YÐ"7Ñ7¸&Ñ@�	Ü˜n¨iÓ8Ð@Ø’KØ˜Z¬¨C«¨	Ð2Ñ2Ò2ð ð ˆr   rt   z] rewrote material name: rv   )rl   r
   r   r   r   rs   Úrewrite_materialsÚziprw   rx   r1   )rq   r¯   r€   r™   rµ   rp   r|   r¡   Ú	new_namesrƒ   r³   r}   rš   s              @@r   Ú_relocate_material_namesr¹   x  sø   ù€ ñ ØÜÙ)4Ó5© Aˆ!�)‰)�Q—Y‘YÒ	¨Ñ5ÙØô€Eð
 " KÑ/€Nð
œ3ð 
¤3ö 
ó ˆÜ�hÓˆØ.1¯mªmÓ<©m¨‘\ !•_¨mˆ	Ð<Ø˜Ÿ™Ò%ØØ×Ñ˜iÔ(Ü˜CŸM™M¨9Ö5‰HˆC�Ø�c‹zÜ—	‘	˜A˜hŸm™m˜_Ð,EÀcÀWÈDÐQTÐPWÐXÕYñ 6ñ ùò% 	6ùò( =s   �C0Á/C5c                 ód  — t        |«      \  }}|€y| dz  }|j                  «       sy|j                  d«      D ]u  }|j                  dd¬«      }|j	                  dd«      }t        ||||«      }||k7  sŒ<|j                  |d¬	«       t        j                  d
|j                  |«      › �«       Œw y)zÌWalk every VMT and rewrite references to any relocated path. Each
    candidate rewrite is gated on the target file existing at the new
    location, so refs that fall through to vanilla stay intact.
    Nrs   z*.vmtzutf-8r   )ÚencodingÚerrorsr   r   )r»   zrewrote refs in materials/)
rž   r5   rN   Ú	read_textr   r®   Ú
write_textrw   rx   rR   )	rq   r€   rœ   r�   r}   ÚvmtÚoriginalrŸ   Únew_texts	            r   Ú_update_vmt_refsrÂ   ¦  s³   € ô
 ,¨KÓ8Ñ€GˆWØ€ØØ! KÑ/€NØ× Ñ Ô"ØØ×#Ñ# GÖ,ˆØ—=‘=¨'¸)�=ÓDˆØ×Ñ  cÓ*ˆÜ'¨¨g°wÀÓOˆØ�xÓØ�N‰N˜8¨gˆNÔ6Ü�I‰IÐ2°3·?±?À>Ó3RÐ2SÐTÕUñ -r   )rB   c          
      ó@  — t        | j                  d«      «      }|sy|€i }t        j                  dt	        |«      › d|› d�«       g }|D ]2  }|j                  |«      }	 |j                  t        || |||«      «       Œ4 	 t        | ||«       	 t        | |«       t	        |«      S # t        $ r t        j                  d|› d�«       Y Œw xY w# t        $ r t        j                  d«       Y Œ`w xY w# t        $ r" t        j                  d	«       Y t	        |«      S w xY w)
a‘  Run the full MDL-relocation pipeline against a staged mod tree.

    `file_origin` maps each staged file path to its source addon's load-order
    index; the merge step uses it to resolve per-file collisions when two
    mods ship overlapping content (one pre-prefixed under `console/`, the
    other not). If omitted, collisions silently keep the dst file.

    Returns the number of MDLs found.
    z*.mdlr   zRelocating material paths for z MDL(s) under prefix 'Ú'zMDL relocation failed for z; leaving as-isz MDL material-name rewrite failedzVMT reference rewrite failed)rl   rN   rw   Úinforc   rE   Úextendrˆ   Ú	ExceptionÚ	exceptionr¹   rÂ   )rq   r(   rB   r¯   Úall_relocationsrp   rC   s          r   Úrelocate_mdl_pathsrÊ   º  s)  € ô �|×)Ñ)¨'Ó2Ó3€IÙØàÐØˆä‡H�HÐ-¬c°)«nÐ-=Ð=SÐTZÐS[Ð[\Ð]Ô^à(*€OÛˆØ#Ÿ™¨Ó1ˆð	RØ×"Ñ"Ü! (¨L¸&À+È}Ó]õð ð:Ü  ¨y¸/ÔJð6Ü˜ Ô7ô ˆy‹>Ðøô ò 	RÜ�M‰MÐ6°x°jÀÐPÖQð	Rûô
 ò :Ü�‰Ð8Ö9ð:ûô
 ò 6Ü�‰Ð4Õ5äˆy‹>Ðð6ús6   Á B&ÂC ÂC2 Â&"CÃ
CÃC/Ã.C/Ã2DÄDr0   )'Ú__doc__Úloggingr�   Údataclassesr   Úpathlibr   Úvalve_parsersr   Úcore.util.filer   Ú	getLoggerrw   ÚDEFAULT_PREFIXr&   r–   r•   r	   r   r   Úboolr'   r+   r@   r˜   ÚintrG   rZ   r`   rU   rT   rˆ   ÚtupleÚPatternrž   r®   r¹   rÂ   rÊ   r   r   r   Ú<module>r×      s  ðñó( Û 	Ý !Ý å !å à€g×ÑÓ€à€ð
 8€ð
 'Ð ð ,Ð ð ÷ð ó ðð
+�ð +˜ó +ðN ð N¨ó Nð
"˜ð " Sð "¨Só "ð(�Tð  Sð ¨T°D©[ó ð>5Øð5Ø!% d¨C i¡ð5ØADÀtÁð5à	ó5ð !%ñ#Ø	ð#Øð#Ø'+¨D°#¨I¡ð#à˜‘:ð#ð 
ó#ðP !%ñ(Ø	ð(Øð(Ø'+¨D°#¨I¡ð(à˜‘:ð(ð 
ó(ðV
˜dð 
 tó 
ð$ !%ñ]Øð]àð]ð ð]ð �d˜C�i‘ð	]ð
 ˜‘:ð]ð 
ˆ*Ñó]ð@Ø�jÑ!ðà
ˆ2�:‰:�c‰?˜TÑ! 4¨¨S¨¡>°DÑ#8Ð8Ñ9óð<&Ø
ð&à�Z‰Z˜‰_˜tÑ#ð&ð �#�s�(‰^˜dÑ"ð&ð ð	&ð
 	ó&ð>+Z¨4ð +Z¸DÀ¹Jð +ZÐUYÐZdÑUeð +ZÐjnó +Zð\V 4ð V°d¸:Ñ6Fð VÈ4ó Vð, !ð,ð +/ò	,Øð,àð,ð �d˜C�i‘ 4Ñ'ð	,ð
 	ô,r   