
    UHj)@                    t   d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
mZmZ  ee      j                         j                  d   Zedz  ZddZdd	Zdd
ZddZddZ	 	 	 	 	 	 	 	 ddZddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZddZ	 d 	 	 	 	 	 	 	 	 	 	 	 d!dZd"dZd"dZefd#dZd$dZe dk(  r e        yy)%zDSummarize EXE pointer references for save-selector frontier records.    )annotationsN)Path)read_sectionsoffset_to_vava_to_offset   outc                "    | rt        | d      S d S )N   )int)values    :/home/exedev/hwanse/tools/summarize_save_selector_xrefs.py	parse_hexr      s    "3ub>,,    c                N    | D ]   }|d   }||d   z   }||cxk  r	|k  s|c S  " y )Nrawraw_size )sectionsoffsetsectionstartends        r   section_for_offsetr      sE     gj))F S N !
 r   c                    g }t        j                  d|      }d}	 | j                  ||      }|dk  r	 |S |dz   }t        ||      }t	        ||      }|r'|%|j                  |d   d|dd|dd|dd       a)	N<Ir   r   name0x08x06x)r   refVaHexfileOffsetHextargetVaHex)structpackfindr   r   append)	exer   r   refsneedlesearchhitr   ref_vas	            r   	find_refsr.      s    D[[u%FF
hhvv&7 K q$Xs3h,v)KK"6? -#%c#Y!#E#;/	  r   c                L    | j                  d       d| j                  d       S )Ngroup:slotget)rows    r   selector_labelr6   4   s&    gggq 122r   c                   i }| xs g D ]  }t        |      }|j                  d      |j                  d      df|j                  d      |j                  d      dfg}|j                  d      xs g D ]F  }|j                  d      s|j                  |j                  d	      |j                  d
      df       H |D ]1  \  }}}|r|s|j                  ||fg       j                  ||d       3  |S )NrowPointerVaHexrowPointerHexz selector-group-row-pointer-entryselectedPointerVaHexselectedPointerHexz selector-row-selected-root-entryfirstDwordspointervaHexvalueHexzselector-root-pointer-entry)selectorrole)r6   r4   r'   
setdefault)	selector_rowsindexr5   labelmetadata_refsdword
ref_va_hextarget_va_hexrA   s	            r   !build_selector_metadata_ref_indexrJ   8   s"   /1E" s# )*(2 ./,-2
 WW]+1r 	E99Y'  		'"		*%-" 	 0= 	+Jt]j-8"=DD!F 	-: Lr   c                "   |j                  | j                  d      | j                  d      f      xs g }|s
i | dd ddS t        fd|D        |d         }|d   }|j                  d	      v rd
| }i | ||j                  d	      ddS )Nr!   r#   unclassified-pointer-refF)selectorRefRoleselectorRefSelectorselectorMetadataRefc              3  J   K   | ]  }|j                  d       v s|  yw)r@   Nr3   ).0matchcurrent_selectorss     r   	<genexpr>zclassify_ref.<locals>.<genexpr>h   s"     [5		*0EIZ0Z[s   ##r   rA   r@   zcurrent-T)r4   next)refselector_metadata_indexrS   metadata_matchescurrent_matchrA   s     `   r   classify_refrZ   Z   s    
 /22CGGJ4GQ^I_3`ageg

9#'#(	
 	
 [,[M  D$(99$ 
,00<#	 r   c           	     "   t        ||      }|g S g }t        |      D ]n  }||dz  z   }|dz   t        |       kD  r |S t        ||      }| |S t	        j
                  d| |      d   }	|j                  |d|dd|	d|	dz  |	dz	  d       p |S )	N   r   r   r   r   i  r   )rD   r>   r?   u16Lou16Hi)r   rangelenr   r$   unpack_fromr'   )
r(   r   vacountr   rowsrD   item_offsetitem_var   s
             r   	dwords_atrg   v   s    (B'F~	Du uqy(?SX% K x5? K ""4k:1='#'U3K(V^b[
 	 Kr   c           
         g }|D ]k  }t        |      }|t        | ||      D cg c]  }t        |||       }	}|j                  ||	t	        d |	D              t	        d |	D              d       m |S c c}w )Nc              3  D   K   | ]  }|j                  d       sd  ywrO   r   Nr3   rQ   rV   s     r   rT   z refs_for_path.<locals>.<genexpr>   s     +`#I^A_A+`     c              3  D   K   | ]  }|j                  d       rd  ywrj   r3   rk   s     r   rT   z refs_for_path.<locals>.<genexpr>   s     &_SH]@^q&_rl   )r?   r)   selectorMetadataRefCountnonMetadataRefCount)r   r.   rZ   r'   sum)
r(   r   path_hexrW   rS   result	value_hexr   rV   r)   s
             r   refs_for_pathrt      s     F 	)$= !h6
 57HI
 
 	!(++`+`(`#&&_D&_#_	
 	 M
s   A5c           
     j   g }| D ]  }|j                  d      |k7  s|j                  d      dk7  r,|j                  d      ||hvrB|j                  |j                  d      |j                  d      xs g |j                  d      |j                  d      |j                  d      xs g d	        |S )
NrE   kindfieldMapresourcepathHexr!   
sceneIdHextilesets)rx   ry   r!   rz   r{   )r4   r'   )reference_rowsrE   sourcetargetmatchesr5   s         r   matching_selector_pathsr      s    G 777u$:(E77:vv&66
+wwy)/R
+'',/
+1r
 	 Nr   c                r   g }t        |      }|D ]  }|d   }|d   }	|j                  d      xs g }
t        |
      }|
D cg c]  }t        ||||	      D ]  }|  }}}g }|D ]"  }|d   D ]  }||vs|j	                  |        $ g }|j                  d      xs g D ]  }t        |j                  d            }t        |j                  d            }t        |j                  d            }|j	                  i ||t        | ||      ng |t        | ||      ng |t        | ||      ng |t        | ||d	      ng d
        t        | ||||      }t        d |D        i       }|j	                  ||	|
||t        |      t        |j                  d      xs d      d|d	        |S c c}}w )Nr}   r~   	selectorsry   
scenePairsleafPointerHexsourceRecordVaHextargetRecordVaHex   )leafRefssourceRecordRefstargetRecordRefs
leafDwordsc              3     K   | ]<  }|j                  d       r)t        d |j                  d      xs g D              r| > yw)r?   c              3  D   K   | ]  }|j                  d       dk(    yw)rM   z(current-selector-row-selected-root-entryNr3   rk   s     r   rT   z'build_rows.<locals>.<genexpr>.<genexpr>   s(       GG-.2\\s    r)   N)r4   any)rQ   items     r   rT   zbuild_rows.<locals>.<genexpr>   sG      88J' #xx/52  s   AAro   r   blocked)	r}   r~   r   selectorPathsselectorPathRefs currentRootRefIsSelectorRowEntrycurrentRootNonMetadataRefCountroutePromotionStatusr   )rJ   r4   setr   r'   r   r.   rg   rt   rU   boolr   )r(   r   frontier_rowsselector_referencesrC   rd   rW   frontierr}   r~   selector_labelsrS   rE   pathselector_pathspath_valuesr   scene_pair_rowspairleafsource_recordtarget_recordselector_path_refscurrent_root_refs                           r   
build_rowsr      s=    D?N! 8(#(#",,{39r0 )
/0CUFTZ[
  

 

 " 	.Di .+&&u-.	. LL.4" 
	DTXX&678D%dhh/B&CDM%dhh/B&CDM"" $$>B>NIc8T:TVO\OhIc8]$KnpO\OhIc8]$KnpCGCSiXtQ?Y[$ 	
	 +#
  . 
 	(+ 2045E0F.12B2F2FG\2]2bab.c$-)

 
	]8r Ki
s   F3c                   dddddt        |        ddg}| D ]!  }|j                  d|d    d|d	    dd
dj                  |d         xs d dd|j                  d       d|j                  d       d|j                  d       ddddg       |d   D ]n  }|j	                  d|d    ddj                  |d          d|j                  d      xs d ddj                  |j                  d      xs g       xs d d	       p |j                  g d       |d    D ]<  }dj                  d! |d"   D              xs d}|j	                  d|d#    d| d       > |j                  g d$       |d%   D ]  }dj                  d& |d'   D              xs d}dj                  d( |d)   D              xs d}dj                  d* |d+   D              xs d}	|j	                  d|j                  d,       d|j                  d-       d|j                  d.       d| d| d|	 d        |j	                  d       $ d/j                  |      S )0Nz# Save Selector Xrefs zPointer-reference summary for save-selector frontier candidates. These are data-flow breadcrumbs, not confirmed gameplay transitions.zFrontier edges: .z## r}    -> r~   zSelectors: , r   -zCurrent root row-entry ref: r   z (non-metadata refs: r   z, promotion: r   z).z/| resource | selector path | scene | tilesets |z| --- | --- | --- | --- |r   z| rx   z | ry   rz   r{   z |)r   z| value | refs |z| --- | --- |r   c              3  d   K   | ](  }|d     d|d    d|j                  d      xs d d * ywr    r!   z (rM   rL   )Nr3   rk   s     r   rT   zmarkdown.<locals>.<genexpr>  sO        y>"!C
O#4 5GG-.L2LMQPs   .0r)   r?   )r   z^| leaf | source record | target record | leaf refs | source record refs | target record refs |z%| --- | --- | --- | --- | --- | --- |r   c              3  6   K   | ]  }|d     d|d      ywr   r   r!   Nr   rk   s     r   rT   zmarkdown.<locals>.<genexpr>(  s%     !dCS^$4Ac*o5F"G!d   r   c              3  6   K   | ]  }|d     d|d      ywr   r   rk   s     r   rT   zmarkdown.<locals>.<genexpr>)  %     #ncs9~&6aJ7H$I#nr   r   c              3  6   K   | ]  }|d     d|d      ywr   r   rk   s     r   rT   zmarkdown.<locals>.<genexpr>*  r   r   r   r   r   r   
)r`   extendjoinr4   r'   )
rd   linesr5   r   r   r)   r   	leaf_refssource_refstarget_refss
             r   markdownr      s   
 	P

3t9+Q'
E  *#h-S]O4$))C$45<=Q?*3773U+V*W X##&77+K#L"M N''"89:"> ='

 
	 ( 	DLLT*%&c&++d9o*F)Gs88L)0S1TYYtxx
?S?YWY5Z5a^a4bbdf	
 	 
 	
 *+ 	=D99   <   	 
 LL2d:./s4&;<	= 	 
 	
 % 	D		!dSWXbSc!ddkhkI))#nUYZlUm#nnuruK))#nUYZlUm#nnuruKLLTXX./0DHH=P4Q3RRUVZV^V^_rVsUttw+SSRA		 	RU*V 99Ur   c                H   g }| D ]r  }g }|d   D ]  }|j                  dt        j                  |d          dt        j                  dj                  |d                dt        j                  |j	                  d      xs d       dt        j                  d	j                  |j	                  d
      xs g       xs d       d	        g }|d   D ]O  }dj                  d |d   D              xs d}|j                  dt        j                  |d          d| d       Q g }|d   D ]  }	dj                  d |	d   D              xs d}
dj                  d |	d   D              xs d}dj                  d |	d   D              xs d}|j                  dt        j                  |	j	                  d      xs d       dt        j                  |	j	                  d      xs d       dt        j                  |	j	                  d      xs d       d|
 d| d| d        |j                  dj                  dt        j                  |d          dt        j                  |d          dd t        j                  d	j                  |d!         xs d       d"d#t        j                  t        |j	                  d$                   d%t        j                  t        |j	                  d&                   d't        j                  t        |j	                  d(                   d"d)d*dj                  |      xs d+d,d-d.dj                  |      xs d/d,d0d1dj                  |      xs d2d,g             u dj                  d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBg|dCdDdE      S )FNr   z<tr><td>rx   z	</td><td>r   ry   rz   r   r   r{   z
</td></tr>r   z<br>c           
   3     K   | ];  }t        j                  |d     d|d    d|j                  d      xs d d       = ywr   )htmlescaper4   rk   s     r   rT   zhtml_page.<locals>.<genexpr>B  s\      
 	 9~&aJ'8 9 12P6PQQRTs   AAr)   r?   r   c              3  \   K   | ]$  }t        j                  |d     d|d           & ywr   r   r   rk   s     r   rT   zhtml_page.<locals>.<genexpr>L  s/     #s[^DKK3y>2B!C
OCT0U$V#s   *,r   c              3  \   K   | ]$  }t        j                  |d     d|d           & ywr   r   rk   s     r   rT   zhtml_page.<locals>.<genexpr>M  /     %}]`dkkS^4DAc*oEV2W&X%}r   r   c              3  \   K   | ]$  }t        j                  |d     d|d           & ywr   r   rk   s     r   rT   zhtml_page.<locals>.<genexpr>N  r   r   r   r   r   r   r   z<h2>r}   r~   z</h2>z<p>Selectors: r   z.</p>z<p>Current root row-entry ref: r   z; non-metadata refs: r   z; promotion: r   z<h3>Selector Paths</h3>zl<table><thead><tr><th>resource</th><th>selector path</th><th>scene</th><th>tilesets</th></tr></thead><tbody>z<tr><td colspan="4">-</td></tr>z</tbody></table>z<h3>Path References</h3>zA<table><thead><tr><th>value</th><th>refs</th></tr></thead><tbody>z<tr><td colspan="2">-</td></tr>z<h3>Scene Pair References</h3>z<table><thead><tr><th>leaf</th><th>source record</th><th>target record</th><th>leaf refs</th><th>source record refs</th><th>target record refs</th></tr></thead><tbody>z<tr><td colspan="6">-</td></tr>z<!doctype html>z<html lang="en">z<head>z  <meta charset="utf-8">zF  <meta name="viewport" content="width=device-width, initial-scale=1">z$  <title>Save Selector Xrefs</title>z	  <style>z^    body { margin: 24px; background: #101010; color: #eee; font: 14px system-ui, sans-serif; }zJ    table { border-collapse: collapse; width: 100%; margin: 12px 0 24px; }zM    th, td { border: 1px solid #333; padding: 6px 8px; vertical-align: top; }z9    th { background: #1d1d1d; position: sticky; top: 0; }z
  </style>z</head>z<body>z  <h1>Save Selector Xrefs</h1>z  <p>Pointer-reference summary for save-selector frontier candidates. These are data-flow breadcrumbs, not confirmed gameplay transitions.</p>z</body>z</html>r   )r'   r   r   r   r4   str)rd   r   r5   	path_rowsr   ref_rowsr   r)   	pair_rowsr   r   r   r   s                r   	html_pager   3  s,   H 6	( 	D{{4
#345 6{{6;;tI#?@A B{{488L#9#@SAB C{{499TXXj-A-GR#H#OCPQ R		 *+ 	aD;; 
  <     OOht{{4
3C'D&EYtfT^_`	a 	% 	D#sbfgqbr#sszwzI ++%}dhi{d|%}}  E  BEK ++%}dhi{d|%}}  E  BEK{{488,<#=#DEF G{{488,?#@#GCHI J{{488,?#@#GCHI J k;-y N			 			4;;s8}-.d4;;s8}3M2NeTT[[3{3C)D)KLMUS++/;;s377Ce;f7g+h*i j""&++c#'':Z2[.\"]!^ _++c#''2H*I&JKL M
 &zIIi E$E&OIIhD#D, vIIi E$E'#
  	E6n 99"P.hTWC( 	Y!" 
#$ 	%& 	'( 	)  r   c                    |j                  dd       |dz  j                  t        j                  | dd      dz   d	       |d
z  j                  t	        |       d	       y )NT)parentsexist_okzsave_selector_xrefs.jsonF   )ensure_asciiindentr   utf-8encodingsave_selector_xrefs.html)mkdir
write_textjsondumpsr   )rd   out_dirs     r   write_outputsr     sc    MM$M.))55

4eA6= 6  ))55ioPW5Xr   c                 x   t        j                  t              } | j                  dt        t
        dz         | j                  dt        t        dz         | j                  dt        t        dz         | j                  d	t        t        d
z         | j                  dt        t               | j                         }|j                  j                         }t        |      }t        ||t        j                  |j                  j                  d            t        j                  |j                   j                  d            t        j                  |j"                  j                  d                  }t%        ||j&                         t)        dt+        |       d|j&                  dz          y )N)descriptionz--exezHwanse2.exe)typedefaultz
--frontierzsave_selector_frontier.jsonz--selector-referencesz#save_scene_selector_references.jsonz--selectorszsave_scene_selectors.jsonz	--out-dirr   r   zwrote z save selector xref rows -> r   )argparseArgumentParser__doc__add_argumentr   ROOTOUT
parse_argsr(   
read_bytesr   r   r   loadsr   	read_textr   r   r   r   printr`   )parserargsr(   r   rd   s        r   mainr     s^   $$9F
dD=4HI
4?\9\]
/dCJoDop
D#@[:[\
$<D
((


CS!H

4==**G*<=

4++55w5GH

4>>++W+=>D $%	F3t9+9$,,Ic:c9d
efr   __main__)r   z
str | Nonereturnz
int | None)r   
list[dict]r   r   r   zdict | None)r(   bytesr   r   r   r   r   r   )r5   dictr   r   )rC   list[dict] | Noner   !dict[tuple[str, str], list[dict]])rV   r   rW   r   rS   set[str]r   r   )
r(   r   r   r   rb   r   rc   r   r   r   )r(   r   r   r   rq   z	list[str]rW   r   rS   r   r   r   )
r|   r   rE   r   r}   r   r~   r   r   r   )N)r(   r   r   r   r   r   r   r   rC   r   r   r   )rd   r   r   r   )rd   r   r   r   r   None)r   r   )!r   
__future__r   r   r   r   r$   pathlibr   probe_exe_scene_tablesr   r   r   __file__resolver   r   r   r   r   r.   r6   rJ   rZ   rg   rt   r   r   r   r   r   r   __name__r   r   r   <module>r      sN   J "      L L H~''*
Ul-*3D	>   
	8.	  ?	
   2, (,B	BB B $	B
 %B BJ4nNb 58 Yg, zF r   