
    Mj\~                       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m	Z	 ddl
mZ ddlmZ  ee      j                         j                   d   Zedz  d	z  Zed
z  Zedz  Zedz  Zedz  Zedz  Zh dZg dZg dZd0dZd1dZd2dZd3dZd4dZd5dZ d6dZ!d7dZ"d8dZ#d9dZ$d:dZ%d;dZ&d<dZ'd=dZ(d>d Z)d?d!Z*d@d"Z+dAdBd#Z,dCdBd$Z-dDd%Z.dEd&Z/dFd'Z0dGd(Z1dHd)Z2dIdJd*Z3dCdKd+Z4dLd,Z5dMd-Z6dNd.Z7e8d/k(  r e7        yy)Oa  Summarize runtime evidence from the opening battle trace.

The raw intro-battle trace is intentionally left in captures/runtime because it
is large and transient. This builder promotes the compact, useful evidence:

* phase anchors from TextOutA skill title draws,
* runtime CNS surface lifecycle and draw rectangles,
* actor/monster/effect draw sequences during the three intro attacks,
* DirectSound buffer byte lengths matched to extracted zero-based WLK files.
    )annotationsN)Counterdefaultdict)Path)Any   capturesruntimeoutwebextract_wlkz intro_battle_runtime_review.jsonz intro_battle_runtime_review.html>   aaa.cns
btl_k2.cns
map_k1.cns
map_k2.cns
status.cns
window.cns	title.cns	zs_dd.cns
btl_at.cns
btl_rs.cns
btl_sm.cnsbtl_efc.cnsbtl_etc.cnslogo_00.cns)r   r   r   r   r   r   ))u   맹호스페셜u   Ataho 맹호스페셜)u	   선렬각u   Linxiang 선렬각)u	   쾌진격u   Smash 쾌진격c                V    t        j                  | dd      S t        |       d      S )N T)quote)htmlescapestr)values    *tools/build_intro_battle_runtime_review.pyhr$   A   s%    ;;U]r$GGE
$GG    c                p    | j                         si S t        j                  | j                  d            S )Nutf-8encoding)existsjsonloads	read_text)paths    r#   	read_jsonr/   E   s*    ;;=	::dnngn677r%   c                     g } t        t        j                  d            D ]F  }|j                  d      j                  d      }|j	                         s4| j                  ||f       H | r| d   S d S )Nz*intro-battle*.manifest.jsonr   z.jsonl)sortedCAPTURESglobwith_suffixr*   append)pairsmanifestjsonls      r#   latest_intro_battle_tracer:   K   sm    E8==)GHI ,$$R(44X><<>LL(E*+, 59'4'r%   c                    g }| j                  d      5 }t        |d      D ]A  \  }}|j                         st        j                  |      }||d<   |j                  |       C 	 d d d        |S # 1 sw Y   |S xY w)Nr'   r(   r   _line)open	enumeratestripr+   r,   r6   )r.   eventsfileline_nolineevents         r#   load_eventsrE   T   s~    #%F	G	$ !&tQ/ 	!MGT::<JJt$E$E'NMM% 	!! M! Ms   AA11A;c                    | sy	 t         j                  |       j                  dd      j                  d      S # t        $ r Y yw xY w)Nr   cp949replace)errors )bytesfromhexdecoderstrip
ValueError)raws    r#   raw_to_textrQ   `   sI    }}S!(((CJJ6RR s   4: 	AAc                    | sy | j                  d      }t        |      dk7  ry 	 t        d |D              S # t        $ r Y y w xY w)N,   c              3  2   K   | ]  }t        |        y wN)int).0parts     r#   	<genexpr>zparse_rect.<locals>.<genexpr>p   s     14SY1   )splitlentuplerO   )r"   partss     r#   
parse_rectr`   i   sL    KKE
5zQ15111 s   7 	AAc                F    t        |       }|sy |\  }}}}||z
   d||z
   S )Nx)r`   )rectparsedx0y0x1y1s         r#   	rect_sizeri   u   s8    FNBB2gYaRy!!r%   c                   | si S i }dddddddj                         D ]2  \  }}t        j                  ||       }|s|j                  d      ||<   4 t        j                  d	|       }|r(|j                  d       d
|j                  d       |d<   t	        |j                  d            |d<   |j                         D ci c]  \  }}|	|| c}}S c c}}w )Nzcaller=(0x[0-9a-fA-F]+)zsrcRect=([0-9,\-]+)zdstRect=([0-9,\-]+)zflags=(0x[0-9a-fA-F]+)zsrcColorKey=([^ ]+)zappliedColorKey=([^ ]+))callersrcRectdstRectflagssrcColorKeyappliedColorKeyr   z\sat\s(-?\d+),(-?\d+)rS      dstPointrl   srcSize)itemsresearchgroupri   get)detailrd   keypatternmatchatr"   s          r#   parse_draw_detailr~   }   s    	F,))*-5 eg
)W 		'6*++a.F3K
) 
+V	4B	 "}Abhhqk];z!&**Y"78F9)/M:35;LCJMMMs   
CCc                p    | j                  d      xs$ | j                  d      xs | j                  d      S )NsourceResourceNamesourceLabelresourceNamerx   rD   s    r#   resource_labelr      s6    		&' 	%99]#	%99^$r%   c                   g d}|D ci c]  }|| v s|| j                  |       }}| j                  d      r!t        | j                  d            }|r||d<   t        | j                  d            }|r||d<   |S c c}w )N) seqframeticksteprD   pcrk   namer   resourceTypearchiveOffset
byteLength
imageWidthimageHeightsurfaceHandlesourcedestinationr   destinationLabelr   destinationResourceNamesourceSurfaceSizedestinationSurfaceSizerc   fontcolorrP   ry   runnerobjectstreamopcoderP   decodedTextry   rd   )rx   rQ   r~   )rD   keysrz   r   decodedrd   s         r#   compact_eventr      s    !DD +/
?3#,3		#
?C
?yyeii./!(Cuyy23FHJ @s
   	A>A>c            
        i } t         j                         s| S t        t         j                  d            D ]  }	 t	        |j
                        }t        j                  t        |      d      5 }|j                         }|j                         }|j                         }|j                         }||z  |z  }d d d        ||j                  |j                         j                   d| |<    | S # t        $ r Y w xY w# 1 sw Y   LxY w)Nz*.wavrb)wlkIndexrA   	fileBytes	dataBytesframes
sampleRatechannelssampleWidth)WLKr*   r2   r4   rW   stemrO   waver=   r!   getnchannelsgetsampwidth
getnframesgetframerater   statst_size)	r   r.   indexwavr   sample_widthr   sample_rate
data_bytess	            r#   wlk_catalogr      s   %'C::<
sxx() 
			NE YYs4y$' 	:3'')H++-L^^%F**,K(*\9J	: II,,#% '	
E

* J%  			: 	:s   C4/A	D4	D ?D D	c           
     8     g S |j                         D cg c]  }|d    k(  s| }}|r|D cg c]
  }i |ddi c}S t        |j                          fd      d d }|D cg c]  }i |ddt        |d    z
         i c}S c c}w c c}w c c}w )Nr   r|   exact-data-bytesc                &    t        | d   z
        S )Nr   )abs)rowr   s    r#   <lambda>zmatch_wlk.<locals>.<lambda>   s    CK8H:8U4V r%   rz      znearest-delta-)valuesr2   r   )r   catalogr   exactnears   `    r#   	match_wlkr      s    	#NN,OSK0@J0NSOEO@EF434!34FF'.."(VWXZYZ[D_cdX[SsSG~c#k2BZ2O.P-QRSdd	 PFds   BBB)!Bc                p    | sy t        j                  d|       }|rt        |j                  d            S d S )Nzbytes=(\d+)r   )ru   rv   rW   rw   ry   r|   s     r#   extract_sound_bytesr      s2    IInf-E"'3u{{1~1T1r%   c                ^    | sy t        j                  d|       }|r|j                  d      S d S )Nzformat=([^ ]+)r   )ru   rv   rw   r   s     r#   extract_sound_formatr      s.    II'0E"5;;q>,,r%   c                0   g }g }| D ]	  }|j                  d      dk7  rt        |j                  d            xs |j                  d      xs d}|j                  d      |j                  d      |j                  d      |j                  d	      |j                  d
      |j                  d      |j                  d      |j                  d      |d	}|j                  |       t        D ]"  \  }}||v s|j                  i |||d       $  ||fS )NrD   z	text-drawrP   textr   r   r   r   r   rc   r   r   )	r   r   r   r   rc   r   r   rP   r   )
phaseLabeltitle)rx   rQ   r6   PHASE_TITLE_HINTS)r@   rowsanchorsrD   r   r   hintlabels           r#   summarize_textr      s   DG L99W,eii./J599V3DJ99U#YYw'IIf%))D/IIf%IIf%YYw'99U#"

 	C, 	LKD%wJ#JUTJK	L!L& =r%   c                   t        | D ch c]B  }t        |      dk(  st        |j                  d      t              s2|j                  d      D c}      }|sg S g }|d   g}|dd  D ]3  }||d   dz   k  r|j                  |        |j                  |       |g}5 |j                  |       g }t        |d      D ]{  \  }}| D cg c]0  }|j                  d      t        |      v s t        |      dk(  s/|2 }	}|j                  ||d   |d   t        |      t        |	      t        |	d      d       } |S c c}w c c}w )	Nr   r   r   r   r1      limit)runIndex
firstFrame	lastFrame
frameCount	drawCounttopRects)
r2   r   
isinstancerx   rW   r6   r>   setr]   top_draw_combos)
drawsr   r   runscurrentr   r   irun	run_drawss
             r#   	logo_runsr     sa     F#.:MQ^:^cmnqnunuv}n~  AD  dESWWW%  F  GF	DaykG GBK!O#NN5!KK gG 	KK
CD!$ 
3$)sSSWWW-=S-In]`NaerNrSs	s

!!f W!#h ^+IQ?		

 J3 F ts!   D>D>D>!E*E9Ec           
        g }t        d |D              }t        t        | d             D ]  \  }}|d   }|dz   t        |       k  r| |dz      d   nd }|D cg c]  }||kD  s	|||k  s| }	}|	r	|	d   dz
  }
n|r|dz
  }
nt        d |D        |      }
|j	                  |d	   |d
   |||
|
|z
  dz   d        |S c c}w )Nc              3     K   | ]B  }t        |      d k(  r2t        |j                  d      t              r|j                  d       D yw)r   r   N)r   r   rx   rW   rX   r   s     r#   rZ   z&build_action_phases.<locals>.<genexpr>5  sA      #-/Jswww?OQT4U 	s   AA
c                    | d   S )Nr    )r   s    r#   r   z%build_action_phases.<locals>.<lambda>:  s
    s7| r%   r   r   r   r   c              3  ~   K   | ]5  }t        |j                  d       t              s#|j                  d        7 ywr   N)r   rx   rW   r   s     r#   rZ   z&build_action_phases.<locals>.<genexpr>C  s,     ^CJswwwGWY\<]swww'^s   $==)defaultr   r   )r   r   
textAnchorr   r   	frameSpan)r2   r>   r]   maxr6   )r   r   phaseslogo_framesr   anchorstartnext_anchorr   after_start_logoends              r#   build_action_phasesr   3  s   F  K
 vg3KLM 
	6w12QW1Ega!enW-4/:}eeemQ\Qdhmp{h{E}}"1%)C/C^5^hmnC-$#  5[1_		

( M# ~s   
C$C,Cc                ~   t               }i }| D ]  }t        |j                  d            }|j                  d      |j                  d      xs |j                  d      |j                  d      |j                  d      f}||xx   dz  cc<   |j                  ||        g }|j	                  |      D ]  \  }}||   }	|j                  ||d   |d   |d	   |d
   |	j                  d      |	j                  d      |	j                  d      t        |	j                  d            j                  d      d	        |S )Nry   rl   rr   rm   rs   rn   r   r   rq   r   r   r   r   rk   )	countrl   r   rs   rn   firstSeqr   r   rk   )r   r~   rx   
setdefaultmost_commonr6   )
r   r   countersamplesr   rd   rz   r   r   samples
             r#   r   r   Q  s:   NUiG[]G 	%"3778#45JJy!JJz";fjj&;JJy!JJw	
 	3$	% C))%0 

U

q6"1vq6Q"JJu-$jj1jj&+FJJx,@AEEhO
	

 Jr%   c                L   g }d }t        | d       D ]w  }t        |j                  d            }|j                  d      |j                  d      xs |j                  d      |j                  d      f}|rX|d   |k(  rP|j                  d	      |d
   dz   k  r6|dxx   dz  cc<   |j                  d	      |d
<   |j                  d      |d<   |r|j                  |       |d|j                  d      |j                  d      |j                  d	      |j                  d	      |j                  d      |j                  d      xs |j                  d      |j                  d      |j                  d      |j                  d      d}z |r|j                  |       |d | S )Nc                &    | j                  dd      S )Nr   r   r   r   s    r#   r   z(compress_draw_sequence.<locals>.<lambda>t  s    uyy/B r%   r   ry   rl   rr   rm   rn   rz   r   r   r   r   r   lastSeqrs   rk   )rz   r   r   r  r   r   rl   r   rs   rn   rk   )r2   r~   rx   r6   )r   r   r   r   r   rd   rz   s          r#   compress_draw_sequencer	  q  s   D%)Ge!BC 
"3778#45zz)$fjj&<&U

9@UW]WaWabiWjkwu~,1AW[EY\]E]1]G!#&777#3GK !$GIKK wwu~'''*)zz),!::j1JVZZ	5Jzz),ZZ(jj*

. G<r%   c                >   g }g }| D ]  }t        |j                  d            }|j                  d      }|j                  d      }|sB	 |j                  d      D cg c]  }t        |       c}\  }}	|j                  |       |j                  |	       t        |      }
|
s|
\  }}}}|j                  |||z
  z          |j                  |	||z
  z           |sy t        |      t        |      t        |      t        |      dS c c}w # t        $ r Y w xY w)Nry   rr   rl   rS   )re   rf   rg   rh   )	r~   rx   r\   rW   rO   r6   r`   minr   )r   xsysr   rd   pointrc   vrb   yparsed_rectre   rf   rg   rh   s                  r#   draw_boundsr    s   BB %"3778#45

:&zz)$	$)KK$45qCF5DAq 			!
		! &(NBBIIa27m$IIa27m$!%" b'RBs2wGG 6 		s$   
DD
/D
D	DDc                   | d   }| d   }|D cg c]#  }||j                  dd      cxk  r|k  sn n|% }}|D cg c]#  }||j                  dd      cxk  r|k  sn n|% }}g }t        D ]U  }	|D cg c]  }t        |      |	k(  s| }
}|
s%|
D cg c]+  }t        |j                  d            j                  d      - }}|
D cg c]+  }t        |j                  d            j                  d      - }}t	        d |
D              }|j                  |	t        |
      t        |D ch c]  }|s|	 c}      t        |D ch c]  }|s|	 c}      t        d	 |
D              t        d
 |
D              t        |
      |rt        |j                               ndt        |
d      t        |
d      d
       X i | ||dS c c}w c c}w c c}w c c}w c c}w c c}w c c}w )Nr   r   r   r1   ry   rl   rr   c              3  >   K   | ]  }|j                  d         ywr   r   r   s     r#   rZ   z"summarize_phase.<locals>.<genexpr>  s     =CGGG,=   c              3  >   K   | ]  }|j                  d         ywr   r   r   s     r#   rZ   z"summarize_phase.<locals>.<genexpr>  s     !Cs#'''"2!Cr  c              3  >   K   | ]  }|j                  d         ywr   r   r   s     r#   rZ   z"summarize_phase.<locals>.<genexpr>  s      Bc!1 Br  r   
   r   2   )
resourcer   uniqueSourceRectsuniqueDestinationsr   r   	dstBoundsmaxDrawsPerFrame	topCombossequenceRuns)resourceSummariessoundEvents)rx   ACTION_RESOURCESr   r~   r   r6   r]   r  r   r  r   r   r	  )phaser   soundsfirstlastr   phase_drawsphase_soundsresource_summariesr  r   parsed_rectspoints	per_framer"   s                  r#   summarize_phaser.    s   ,ED"'Q35CGGGR4H+PD+P3QKQ#)SCUcgggr6J-Rd-RCSLS$ 
*NnS.AX.MNNW[\PS)#''(*;<@@K\\RVW3#CGGH$56:::FWW===	!!$ Y%(\)SEU%)S%T&)f*NU5*N&O!!Cd!CC  BT BB(.?HC	(8(8(:$;a,T< 6t2 F	

*
/# 1 RS O ]W *T*NsE    GG GG7GG0G 0G%1G*9G*G/G/c                @   g }| D ]  }|j                  d      dk7  r|j                  d      }|dvr.t        |j                  d            }t        |      }|1||d<   t        |j                  d            |d<   t	        ||      |d<   |j                  |        |S )	NrD   z	sound-apir   >
   IDirectSoundBuffer::LockIDirectSoundBuffer::StopIDirectSoundBuffer::UnlockIDirectSoundBuffer::ReleasemidiStreamOutmidiStreamOpenmidiOutShortMsgmidiStreamCloseIDirectSoundBuffer::PlayIDirectSound::CreateSoundBufferry   pcmBytesformat
wlkMatches)rx   r   r   r   r   r6   )r@   r   r   rD   r   bytes_r   s          r#   summarize_soundsr>    s    D 99W,yy  
 
 $UYYx%89E"$C
O081DECM )&' :CC/0 Kr%   c                4   | D cg c]  }|j                  d      dk(  s| }}t        |D ch c]3  }t        |j                  d      t              s#|j                  d      5 c}      }g }|rR|d   g}|dd  D ]3  }||d   dz   k  r|j	                  |        |j	                  |       |g}5 |j	                  |       t        |      t        d |D              j                  d      t        d	 |D              j                  d      t        |      D cg c]b  \  }|dz   d   d   t              t        fd
|D              t        fd|D        d       t        fdt        |      D        d       dd c}}dS c c}w c c}w c c}}w )NrD   surface-paletter   r   r   r1   c              3  >   K   | ]  }|j                  d         yw)rk   Nr   r   s     r#   rZ   z$summarize_palette.<locals>.<genexpr>  s     Bc 1Br  r   c              3  >   K   | ]  }|j                  d         yw)r   Nr   r   s     r#   rZ   z$summarize_palette.<locals>.<genexpr>  s      Jc!9 Jr  c              3  \   K   | ]#  }|j                  d       t              v s d % yw)r   r   N)rx   r   rX   r   r   s     r#   rZ   z$summarize_palette.<locals>.<genexpr>  s%     !Tswww7G3s87S!!Ts   !,,c              3  p   K   | ]-  }|j                  d       d   k(  s|j                  d       / yw)r   r   paletteHashNr   rD  s     r#   rZ   z$summarize_palette.<locals>.<genexpr>   s5     )oSTWT[T[\cTdhklmhnTn#''-*@)o   66c              3  p   K   | ]-  }|j                  d       d   k(  s|j                  d       / yw)r   r1   rF  Nr   rD  s     r#   rZ   z$summarize_palette.<locals>.<genexpr>  s5     (yC]`]d]del]mqtuwqx]x)?(yrG  )r   r   r   r   
eventCountfirstPaletteHashlastPaletteHash)rI  callerCountssurfaceCountsr   )rx   r2   r   rW   r6   r]   r   r  r>   sumnextreversed)	r@   rD   r   r   r   r   r   r   r   s	           `r#   summarize_paletterQ    s   %Qe7);?P)PEQDQTaEZ		RYHZ\_=`UYYw'abFD!9+ABZ 	"Ea'u%G$ '	" 	G$iBTBBNNqQ  JT JJVVWXY $D/
 
 3 E!!f W!#h!!Tt!TT$()oD)oqu$v#'(y8TX>(y{  $A
	  Ra
s   F
F
$FFA'Fc                 0   t               } | sddddidS | \  }}t        |      }t        |      }t               }t	        d |D              }|D cg c]  }|j                  d      dk(  s| }}t        |      \  }	}
t        ||      }|D cg c]  }|j                  d	      d
v r| }}t        |
|      }|D cg c]N  }|j                  d      dv r9|j                  d      t        v s|j                  d      t        v rt        |      P }}t	        d |D              }|D cg c]   }|j                  d      dv rt        |      " }}t	        d |D              }|D cg c]  }t        |||       }}t        |      }|D cg c]  }t        |      dk(  st        |       }}i dddddddt        |j                  t                     t        |j                  t                     |j#                         j$                  ddd|dt'        |      |j)                         |j)                  d      t'        |
      t'        |      t'        |      t+        d |D              |j                  dd      d d!|	d"|
d#|d$t-        |      d%|d&|d'|d(|d)t/        |j1                               d*|d d+ |j)                  d,      D cg c]  \  }}|d   |d   |d- c}}d.d/g d0S c c}w c c}w c c}w c c}w c c}w c c}w c c}}w )1Nz"hwanse-intro-battle-runtime-reviewzmissing-runtime-trace
traceFoundF)kindstatussummaryc              3  >   K   | ]  }|j                  d         yw)rD   Nr   rX   rD   s     r#   rZ   zbuild.<locals>.<genexpr>  s     B%599W-Br  rD   zdraw-surfacer      r8  r9  >   resource-openresource-readsurface-createsurface-uploadresource-decodesurface-colorkeyresource-surface-labelr   r   c              3  2   K   | ]  }t        |        y wrV   )r   r   s     r#   rZ   zbuild.<locals>.<genexpr>0  s     "L3>##6"Lr[   >   vm-op-transitionobject-stream-changevm-opc              3     K   | ]:  }|j                  d       dk(  r$|j                  d      |j                  d      f < yw)rD   rd  r   r   Nr   rX  s     r#   rZ   zbuild.<locals>.<genexpr>6  s@      99W( 
8	eii12s   A Ar   versionr   rT  rU  zruntime-evidence-promotedr   zFcaptures/runtime is ignored; compact evidence is promoted into out/web)r8   r9   
jsonlBytesrawCaptureGitPolicyr8   rV     c              3  v   K   | ]1  }|j                  d       r|d    d   j                  d      dk(  rd 3 yw)r<  r   r|   r   r   Nr   r   s     r#   rZ   zbuild.<locals>.<genexpr>R  sA      (77<(S->q-A-E-Eg-NRd-d (s   79r@  r   )rI  eventCountsresourceDrawCountstextAnchorCountactionPhaseCountdirectSoundCreateOrPlayCountexactWlkSoundMatchespaletteEventCount	textDrawstextAnchorsresourceLifecyclepaletteactionPhaseslogoRuns
titleDrawsr"  
wlkCatalog	vmSummaryP      )r   r   r   )
sampleRowstopStreamOpcodesconclusions)u   aaa.cns fade 이후 배틀 구간에서 logo_00.cns, map_k1/k2, btl_k2, btl_at/btl_rs/btl_sm, zs_dd, btl_efc, btl_etc 로드와 draw가 런타임으로 관측됐다.u   기술명 TextOutA가 맹호스페셜/선렬각/쾌진격 phase anchor를 직접 제공하므로, 해당 구간의 actor frame/destination은 수동 추정이 아니라 런타임 근거로 분리할 수 있다.u   DirectSound PCM bytes는 extract_wlk/*.wav의 data chunk 길이와 exact match되어 0-base WLK index 매칭 근거가 생겼다.u   btl_efc.cns는 각 공격 phase에서 수백 개의 BltFast draw를 발생시켜 입자/이펙트 scatter가 실제 런타임에 존재함을 확인한다. 개별 helper opcode 의미는 별도 해석 대상이다.u   zs_dd.cns는 normal frame과 hit frame 사이에서 좌우 흔들림/clip 변형 destination이 반복되며, 피격 흔들림은 actor frame 변경이 아니라 draw 위치/rect 변형으로 관측된다.)r:   r/   rE   r   r   rx   r   r>  r   INTERESTING_RESOURCESr   r.  r   r   r!   relative_toROOTr   r   r]   r  rN  rQ  listr   )tracemanifest_path
jsonl_pathr8   r@   r   event_countsrD   	draw_rows	text_rowstext_anchors
sound_rowsr   create_or_play_soundsaction_phasesresource_lifecycleresource_draw_countsvm_rowsvm_opcode_countsr$  phase_summarieslogo_run_rowstitle_drawsrz   r   s                            r#   buildr    s   %'E8-$e,
 	

 !&M:'H$FmGB6BBL$*S5eii.@N.RSIS,V4I|!&'2J 776?]] 	 
 (i@M 99W
	
 YY~&*??599MaCbf{C{ 	e   #"L)"LL 99W!VV 	eG 
    ^kkTYui9NOkOki(M1:a#nS>QU`>`=%aKa01040 	-0 	M55d;<//56$//+33#k	
	0 	H0 	f+'335"6"B"B2"F"<0 #O 4,/0E,F$' (0( %
 ".!1!12CQ!G
02 	Y304 	|506 	/708 	$V,90: 	;0< 	M=0> 	k?0@ 	zA0B 	d7>>+,C0D 	!#2, #3">">r"B!C q6SVeD!
E0R 	 
S0 0U T" laL!s7   K4*K4K9<AK>'%L$L	LLLc           	         g }| d | D ]/  \  }}|j                  dt        |       dt        |       d       1 dt        |d          dt        |d          dd	j                  |       d
S )Nz<tr><td><code></code></td><td>
</td></tr>z<table><thead><tr><th>r   z	</th><th>r   z</th></tr></thead><tbody>r   </tbody></table>)r6   r$   join)r   headersr   bodyrz   r   s         r#   render_counterr  s  s    D6El S
UnQsVH,<QuXJjQRS#AgajM?)AgajM?Jcdfdkdklpdqcr  sC  D  Dr%   c                \   g }| d | D ]  }|j                  d      xs g }|r|d   ni }|j                  dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d	             d
t        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             d        ddj                  |      z   dz   S )Nr<  r   <tr><td>r   	</td><td>r   r:  </td><td><code>rA   z</code> <span class="muted">#r    r|   z</span></td><td>r;  r   </code></td></tr>z~<table><thead><tr><th>frame</th><th>api</th><th>PCM bytes</th><th>WLK match</th><th>format</th><th>pc</th></tr></thead><tbody>r   r  )rx   r6   r$   r  )r   r   r  r   matchesr|   s         r#   render_sound_tabler  z  s^   DFU| 
'','-2%
2SWWW%&' (SWWV_%& 'SWWZ()* +599V,-..MaPUPYPYZdPeNfMgghijkpktktu|k}i~h @SWWX&'( )3774=)* +		

 L  OQ  OV  OV  W[  O\  \  _q  q  qr%   c                   g }| j                  dg       D ]^  }dj                  d |j                  dg       d d D              }dj                  d |j                  dg       d d D              }|j                  d	      xs i }|j                  d
t        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             d| d| d       a dt        | j                  d             dt        | j                  d             dt        | j                  d              d!t        | j                  d"             d#t        | j                  d$      xs i j                  d%             d&dj                  |      z   d'z   t	        | j                  d(g       d)*      z   d+z   S ),Nr!  r   c              3  0  K   | ]  }d t        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             d	  y
w)r  r   r  rl   </code></td><td><code>r   r  rs   rk   r  Nr$   rx   r   s     r#   rZ   zrender_phase.<locals>.<genexpr>  s      	
 SWWW%&' (3779-./ 0377=123 4SWWY'() *3778,-. /	
s   BBr  r   c              3  f  K   | ]  }d t        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d	             d
t        |j                  d             d  yw)r  r   ..r   r  r   r  rl   r  r   r  rs   r  Nr  )rX   r   s     r#   rZ   zrender_phase.<locals>.<genexpr>  s      	 
 SWW\*+,Bq1E/F.G HSWWW%&' (3779-./ 0377=123 4SWWY'() *	 
   B/B1r      r  zL
            <details class="resource-card">
              <summary><strong>r  z.</strong>
                <span class="badge">r   z2 draws</span>
                <span class="badge">r  z5 srcRects</span>
                <span class="badge">r  z7 dst</span>
                <span class="muted">bounds re   rS   rf   r  rg   rh   z</span>
              </summary>
              <h4>Top source/destination combos</h4>
              <table><thead><tr><th>count</th><th>srcRect</th><th>dst</th><th>size</th><th>caller</th></tr></thead><tbody>z</tbody></table>
              <h4>First compressed draw sequence</h4>
              <table><thead><tr><th>frames</th><th>count</th><th>srcRect</th><th>dst</th><th>size</th></tr></thead><tbody>z4</tbody></table>
            </details>
            z<section class="phase"><h3>r   z</h3><p class="muted">frames r   r   z, span r   z; TextOutA anchor rect <code>r   rc   z</code></p>z<h4>Phase sounds</h4>r"  (   r   z
</section>)rx   r  r6   r$   r  )r$  resource_cardsr  top_rowssequence_rowsboundss         r#   render_phaser    s   NII126 %
77 	
  ||K4Ra8	
 	
  	 
  ||NB7<	 
 	
 k*0b  !(,,z": ;< =%%&x||K'@%A$B C%%&x||4G'H%I$J K%%&x||4H'I%J$K L,,-fjj.>,?+@!FJJtDTBUAVVXYZ[a[e[efj[kYlXmmnopqwq{q{  }A  rB  pC  oD D{ |D  {E E{ |I  {J J	
-%
N (%))G*<(='> ?%%&uyy'>%?$@1UYY{E[C\B]]defglgpgpq|g}e~d @&&'<)@)FB(K(KF(S&T%UU`	b ''.
!	" "		"
 UYY}b9
D	E 	r%   c                   | j                  di       }dj                  d | j                  dg       D              }dj                  d | j                  dg       D              }dj                  d | j                  dg       D              }dj                  d	 | j                  d
g       D              }dj                  d | j                  d      xs i j                  dg       D              }dj                  g dt        | j                  di       j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             d| dt        |j                  dg       d d!       d"t        |j                  d#g       d$d!       d%| d&| d'| d(| d)t	        | j                  d*g       D cg c]  }|j                  d+      d,v s| c}d-.       d/      S c c}w )0NrV  r   c              3    K   | ]  }d t        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d	             dt        |j                  d
             dt        |j                  d             d  yw)r  r   r  r   r  r   r  rc   r  r   rP   r   r  Nr  r   s     r#   rZ   zrender_html.<locals>.<genexpr>  s       	!"# $&'( )swwt}%& 'swwv'( )!" #swwu~&' ('() *	s   C
Crs  c              3    K   | ]  }d t        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        dj                  d	 |j                  d
g       dd D                     d  yw)r  r   r  r   r  r   r   r   z, c              3  F   K   | ]  }|j                  d       xs d  yw)rl   -Nr   )rX   rc   s     r#   rZ   z(render_html.<locals>.<genexpr>.<genexpr>  s!     `DDHHY/636`s   !r   NrT   r  )r$   rx   r  r   s     r#   rZ   zrender_html.<locals>.<genexpr>  s      	 	$%& '&'(1SWW[-A+B*C D&'( )%&' (`CGGJXZD[\^]^D_``ab c		s   C	Crw  c              3  :   K   | ]  }d t        |       d  yw)z<li>z</li>N)r$   r   s     r#   rZ   zrender_html.<locals>.<genexpr>  s     V3D3.Vs   r  c              3  2   K   | ]  }t        |        y wrV   )r  )rX   r$  s     r#   rZ   zrender_html.<locals>.<genexpr>  s     SU\%(Sr[   rv  c              3  f  K   | ]  }d t        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d             d	t        |j                  d
             d  yw)r  r   r  r   r  r   rI  r  rJ  z</code> -> <code>rK  r  Nr  r   s     r#   rZ   zrender_html.<locals>.<genexpr>  s       	$%& '&'(1SWW[-A+B*C D&'( )sww12344EaPaHbFcEd e		r  ru  r   u  <!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Intro Battle Runtime Review</title>
  <style>
    :root { color-scheme: dark; --bg:#101214; --panel:#181c20; --line:#303840; --text:#e8edf2; --muted:#98a4ad; --accent:#80cbc4; }
    body { margin:0; background:var(--bg); color:var(--text); font-family:system-ui,-apple-system,Segoe UI,sans-serif; }
    main { max-width:1280px; margin:0 auto; padding:24px; }
    a { color:var(--accent); }
    h1, h2, h3, h4 { margin:0 0 10px; }
    section, details.resource-card { background:var(--panel); border:1px solid var(--line); border-radius:8px; padding:16px; margin:14px 0; }
    details.resource-card summary { cursor:pointer; }
    .summary-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:10px; }
    .metric { background:#11161a; border:1px solid var(--line); border-radius:8px; padding:12px; }
    .metric strong { display:block; font-size:24px; }
    .muted { color:var(--muted); }
    .badge { display:inline-block; margin-left:8px; padding:2px 7px; border-radius:999px; background:#263238; color:#cfd8dc; font-size:12px; }
    code { color:#d7e8ff; }
    table { width:100%; border-collapse:collapse; margin:10px 0 0; font-size:13px; }
    th,td { border-bottom:1px solid var(--line); padding:6px 8px; text-align:left; vertical-align:top; }
    th { color:#c8d2dc; background:#15191d; position:sticky; top:0; }
    .table-wrap { overflow:auto; }
    ol { margin-top:6px; }
  </style>
</head>
<body>
<main>
  <h1>Intro Battle Runtime Review</h1>
  <p class="muted">aaa.cns 페이드 직후부터 배틀 연출, logo_00/title 최초 화면까지의 런타임 draw/sound/text 근거 요약입니다. 원본 대용량 로그는 <code>r   r9   u   </code>에 있고, 이 페이지는 승격된 요약만 표시합니다.</p>
  <section>
    <h2>Summary</h2>
    <div class="summary-grid">
      <div class="metric"><span>events</span><strong>rI  zM</strong></div>
      <div class="metric"><span>action anchors</span><strong>rm  zL</strong></div>
      <div class="metric"><span>action phases</span><strong>rn  zQ</strong></div>
      <div class="metric"><span>DSound create/play</span><strong>ro  zP</strong></div>
      <div class="metric"><span>exact WLK matches</span><strong>rp  zM</strong></div>
      <div class="metric"><span>palette events</span><strong>rq  zZ</strong></div>
    </div>
  </section>
  <section>
    <h2>Core Conclusions</h2>
    <ol>zU</ol>
  </section>
  <section>
    <h2>Event Counts</h2>
    <div class="table-wrap">rk  )rD   r   ri  z\</div>
  </section>
  <section>
    <h2>Top Draw Resources</h2>
    <div class="table-wrap">rl  )r  z
draw countz</div>
  </section>
  <section>
    <h2>Text Anchors</h2>
    <div class="table-wrap"><table><thead><tr><th>frame</th><th>phase</th><th>pc</th><th>rect</th><th>font</th><th>raw CP949</th><th>decoded</th></tr></thead><tbody>uK  </tbody></table></div>
  </section>
  <section>
    <h2>Palette Runs</h2>
    <p class="muted">로고/섬광성 전환은 alpha draw가 아니라 primary surface palette 변경으로 관측됩니다.</p>
    <div class="table-wrap"><table><thead><tr><th>#</th><th>frames</th><th>events</th><th>palette hash</th></tr></thead><tbody>z</tbody></table></div>
  </section>
  <section>
    <h2>Logo Runs</h2>
    <div class="table-wrap"><table><thead><tr><th>#</th><th>frames</th><th>frame count</th><th>draws</th><th>top source rects</th></tr></thead><tbody>z&</tbody></table></div>
  </section>
  u   
  <section>
    <h2>Sound Events</h2>
    <p class="muted">PCM bytes가 WLK WAV data chunk와 exact match될 때만 zero-based WLK 번호를 확정 근거로 표시합니다.</p>
    <div class="table-wrap">r"  r   rY  x   r   z</div>
  </section>
  <section>
    <h2>JSON</h2>
    <p><a href="../out/intro_battle_runtime_review.json">out/intro_battle_runtime_review.json</a></p>
  </section>
</main>
</body>
</html>
)rx   r  r$   r  r  )datarV  text_anchor_rows	logo_rowsr  r   palette_rowsr   s           r#   render_htmlr    s   hhy"%Gww  88M2.   	 88J+	 	I ''V$((=RT:UVVKWWSdhh~r6RSSF77  HHY'-22262> LP P z P< {|  }A  }E  }E  FN  PR  }S  }W  }W  X_  }`  {a  zb=P<b6=PD 78L8Q6R5SEPDT>EPF ?@L]@^>_=`GPFa=GPH >?w{{K]?^=_<`IPHaBIPJ CDGKKPnDoBpAqKPJrAKPL BC7;;OeCfAg@hMPLi>MPN ?@L_@`>a=bOPNc	OPX 
YPXYP` ,GKKr,JL]_abcaP`daPh ,GKK8Lb,QSlnpqriPhsfiPp gw  fxqPpx@qPz AM  @N{PzNW{PB Xa  WbCPBbCPF 
(GPFGPN 0XZ@[  1r_b_f_fgm_n  sq  `q  1r  z}  ~  OPN	OP PN 1rs   	I7"I7c                    t         j                  d       t        j                  d       t               } t        j                  t        j                  | dd      d       t        j                  t        |       d       t        dt        j                  t                      t        dt        j                  t                      y )	NT)exist_okFrq   )ensure_asciiindentr'   r(   zwrote )OUTmkdirWEBr  JSON_OUT
write_textr+   dumpsHTML_OUTr  printr  r  )r  s    r#   mainr  5  s    IItIIItI7D

4eAFQXYD)G<	F8''-.
/0	F8''-.
/0r%   __main__)r"   r   returnr!   )r.   r   r  dict[str, Any])r  ztuple[Path, Path] | None)r.   r   r  list[dict[str, Any]])rP   
str | Noner  r!   )r"   r  r  z tuple[int, int, int, int] | None)rc   r  r  r  )ry   r  r  r  )rD   r  r  r  )rD   r  r  r  )r  dict[int, dict[str, Any]])r   
int | Noner   r  r  r  )ry   r  r  r  )ry   r  r  r  )r@   r  r  z1tuple[list[dict[str, Any]], list[dict[str, Any]]])r   r  r  r  )r   r  r   r  r  r  )   )r   r  r   rW   r  r  )r{  )r   r  r  zdict[str, Any] | None)r$  r  r   r  r%  r  r  r  )r@   r  r   r  r  r  )r@   r  r  r  )r  r  )   )r   z	list[Any]r  ztuple[str, str]r   rW   r  r!   )r   r  r   rW   r  r!   )r$  r  r  r!   )r  r  r  r!   )r  None)9__doc__
__future__r   r   r+   ru   r   collectionsr   r   pathlibr   typingr   __file__resolveparentsr  r3   r  r  r   r  r  r  r#  r   r$   r/   r:   rE   rQ   r`   ri   r~   r   r   r   r   r   r   r   r   r   r   r	  r  r.  r>  rQ  r  r  r  r  r  r  __name__r   r%   r#   <module>r     sP  	 #   	  ,   H~''**y(
Ul
Ul
]3333 "  H8(		"N,+\8e2-2:<@>H2D:@hVDq$0fsl1 zF r%   