
    MjBV                    |   d Z ddlm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	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dZdZdZdZ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Z"d-dZ#d.dZ$d/dZ%d0dZ&d$d Z'd1d!Z(d2d"Z)e*d#k(  r e)        yy)3a  Build a focused runtime review for Rinshan's Anmen Hyakuso Ken capture.

The raw runtime capture is intentionally gitignored. This script distills the
useful evidence into a small JSON/HTML report that can be committed:

* the displayed prompt text;
* the active battle actor BltFast source rectangles resolved against btl_rs;
* result WLK plays;
* btl_etc damage-number setup points; and
* comparison against the static canonical skill timeline.
    )annotationsN)Counter)Path)Any   capturesruntimeoutwebz#battle_rs_skill_runtime_review.jsonz#battle_rs_skill_runtime_review.htmlzbattle-rs-skill-1
0x10216D78z
btl_rs.cnsrinshan0x0cc                V    t        j                  | dd      S t        |       d      S )N T)quote)htmlescapestrvalues    -tools/build_battle_rs_skill_runtime_review.pyhr   &   s%    ;;U]r$GGE
$GG    c                L    t        j                  | j                  d            S )Nutf-8encoding)jsonloads	read_text)paths    r   	read_jsonr"   *   s    ::dnngn677r   c                    g } t        t        j                  dt         d            D ]F  }|j	                  d      j	                  d      }|j                         s4| j                  ||f       H | st        dt              | d   S )N*z*.manifest.jsonr   z.jsonlzNo runtime capture found for )sortedCAPTURESglobTRACE_IDwith_suffixexistsappendFileNotFoundError)pairsmanifestjsonls      r   latest_trace_pairr1   .   s    %'E8==1XJo)FGH ,$$R(44X><<>LL(E*+, "?| LMM9r   c                z    | sy t        j                  d|       }|sy t        d |j                         D              S )Nz'srcRect=(-?\d+),(-?\d+),(-?\d+),(-?\d+)c              3  2   K   | ]  }t        |        y wN)int).0parts     r   	<genexpr>z!parse_src_rect.<locals>.<genexpr>?   s     6tT6   )researchtuplegroupsdetailmatchs     r   parse_src_rectrA   9   s6    II@&IE6u||~666r   c                    | sy t        j                  d|       }|sy t        |j                  d            t        |j                  d            fS )Nz\sat\s(-?\d+),(-?\d+)r      r:   r;   r5   groupr>   s     r   parse_dst_pointrF   B   sD    II.7Eu{{1~EKKN 333r   c                n    | sy t        j                  d|       }|sy t        |j                  d            S )Nzbytes=(\d+)r   rD   r>   s     r   parse_bytesrH   K   s1    IInf-Eu{{1~r   c                    | sy 	 t         j                  |       j                  d      j                  d      S # t        $ r Y y w xY w)Ncp949u   　 )bytesfromhexdecoderstrip	Exception)raw_hexs    r   decode_cp949rQ   T   sD    }}W%,,W5<<YGG s   28 	AAc            
     0   t        t        dz        } | j                  dg       D ]Y  }|j                  d      t        k(  s|j                  dg       D ci c]!  }|d   |d   |d   |d   z   |d   |d   z   f|# c}c S  t	        t         d	      c c}w )
Nzcns_rect_review_data.jsonrowscnsrectsxywr   z rects not found)r"   OUTget	ACTOR_CNSRuntimeError)datarowrects      r   btl_rs_rect_mapr`   ]   s    S667Dxx# 775>Y&  GGGR0 cDItCy49'<d3i$s)>STVZZ  )$45
66	s   &Bc                     t        t        dz        } i }| j                  dg       D ]E  }|j                  d      }t        |t              s%|j                  |g       j                  |       G |S )Nz intro_battle_runtime_review.json
wlkCatalog	dataBytes)r"   rY   rZ   
isinstancer5   
setdefaultr,   )r]   by_bytesr^   
data_bytess       r   wlk_catalog_by_bytesrh   h   sk    S==>D02Hxxb) <WW[)
j#&
B/66s;< Or   c                     t        t        dz        } | j                  dg       D ]7  }|j                  d      t        k(  s|j                  d      t        k(  s5|c S  t        dt         dt               )Nz$battle_skill_timeline_canonical.jsonplayerActionsownerKey
skillIdHexzcanonical skill row not found:  )r"   rY   rZ   CANONICAL_OWNERCANONICAL_SKILL_IDr\   )r]   r^   s     r   canonical_skill_rowrp   r   sq    SAABDxx, 77:/1cggl6KOa6aJ 88IK]J^_
``r   c                ,   g }| D ]  }|d   }|j                  d      |j                  d      |j                  d      |j                  d      f}|rj|d   }|j                  d      |j                  d      |j                  d      |j                  d      f}||k(  r|d   |dz
  k(  r||d<   |d	xx   dz  cc<   |j                  ||d|j                  d      |j                  d      |j                  d      |j                  d      d
        |S )Nframe
frameIndexsrcRectrV   rW   r%   	lastFramer   
drawFrames)
firstFrameru   rv   rs   rt   rV   rW   )rZ   r,   )rS   runsr^   rr   keylastlast_keys          r   
group_runsr|   z   s   !#D 
Gww|$cggi&8#''#,PSU8D.0CTXXc]TXT\T\]`TabH34#4	#A$)[!\"a'"#"!ggl3779-WWS\WWS\
	

* Kr   c                P    g }| D ]  }|r	|d   |k7  s|j                  |         |S )Nr%   )r,   )values
compressedr   s      r   compress_sequencer      s:    J %Z^u4e$% r   c                  # t        |       }t               }t               }t               }t               }g }g }g }	g }
g }|j	                  d      5 }|D ]K  }|j                         st        j                  |      }|j                  d      }||xx   dz  cc<   |dk(  r|j                  |j                  d      |j                  d      |j                  d      |j                  d	      |j                  d
      |j                  d      |j                  d      d       |dk(  r|j                  d	      xs |j                  d      }|r||xx   dz  cc<   |j                  d      t        k(  rt        |j                  d            }t        |j                  d            }|j                  |xs d      }|	j                  |j                  d      |j                  d      |j                  d      |j                  d      |j                  d	      |rdj                  d |D              nd |r|j                  d      nd |rdnd|r|d   nd |r|d   nd d
       |dk(  r|j                  d      dk(  rt        |j                  d            }t        |j                  d            }|
j                  |j                  d      |j                  d      |j                  d      |rdj                  d |D              nd |r|d   nd |r|d   nd d       |dk(  r|j                  |j                  d      |j                  d      |j                  d      |j                  d       |j                  d!      t        |j                  d!            |j                  d"      |j                  d#      d$       |d%k(  spd&|j                  d'      xs d(v st        |j                  d            }|j                  |xs d)g       }|j                  |j                  d      |j                  d      |j                  d      ||D cg c]5  }|j                  d*      |j                  d+      |j                  d,      d-7 c}|j                  d      d.       N 	 d d d        t!        |	      }t#               }|j                  d/g       }t%        |      }|j                  d0g       D cg c]  }|j                  d1       }}|D cg c]  }|d2   	 }}t%        |D cg c]  }|| c}      } | r| d   dk(  r| dd  } |D cg c]2  }|j                  d3      r|j                  d4      d5k7  r|d3   d   d*   4 }!}|D cg c]K  }|j                  d3      r8|j                  d4      d5k7  r$t'        |j                  d      t(              r|d   M }"}|
D ##cg c]  #t+        #fd6|"D              r# }$}#t-        d7 |D        d       }%g d8}&| |k(  r|&j                  d9       n|&j                  d:       dd;d<t/        | j1                  t2                    t/        |j1                  t2                    d=d>|t5        |j7                               t9        |      t9        |j;                               t        |%t=        |	      t=        |      |!|t=        |
      t=        |$      t?        |$D #ch c]  }#|#d   	 c}#      | |k(  ||k(  d?||||
|$i d@|j                  d@      dA|j                  dA      dB|j                  dB      dC|j                  dC      dD|j                  dD      dE|j                  dE      dF|j                  dF      dG|j                  dG      dH|j                  dH      d/|dI|dJ|j                  dJg       dK|j                  dKg       d0|j                  d0g       dL|j                  dL      dM|j                  dMg       |&g dNdOS c c}w # 1 sw Y   xY wc c}w c c}w c c}w c c}w c c}w c c}#w c c}#w )PNr   r   eventr   zresource-surface-labelrr   surfaceHandlesourceLabelsourceResourceNamesourceSurfaceSizearchiveOffset	pixelHash)rr   r   r   r   r   r   r   zdraw-surfacesourcer?    seqpc,c              3  2   K   | ]  }t        |        y wr4   r   r6   vs     r   r8   z"collect_runtime.<locals>.<genexpr>        /I1A/Ir9   indexzmapped-to-btl-rsunmappedr   )
r   rr   r   r   r   rt   rs   frameStatusrV   rW   zbtl_etc.cns
0x10297DD8c              3  2   K   | ]  }t        |        y wr4   r   r   s     r   r8   z"collect_runtime.<locals>.<genexpr>   r   r9   )r   rr   r   rt   rV   rW   z	text-drawr_   rawfontcolor)r   rr   r   r_   r   decodedCp949r   r   z	sound-apiPlaynamer   r%   wlkIndexfile
sampleRate)r   r   r   )r   rr   r   rc   
wlkMatchesr?   frameSequenceresultSoundswlkNors   r   rc   i  c              3  L   K   | ]  }j                  d       |dz   k(    yw)rr   r   NrZ   )r6   sound_framedraws     r   r8   z"collect_runtime.<locals>.<genexpr>"  s#     Xtxx K!O3Xs   !$c              3  R   K   | ]  }|j                  d       t        k(  s| ! yw)r   N)rZ   ACTOR_SURFACE)r6   labels     r   r8   z"collect_runtime.<locals>.<genexpr>&  s      Z5eii.HM.YZs   '')zRuntime draw srcRect values map cleanly to btl_rs.cns frames even though the traced surface label is cara_sm1.cns; treat the label as a derived-surface naming artifact.zAnmen Hyakuso Ken lv4 runtime shows the early 6-7-8-9 and 16-17-18-19 clusters before the late 33/34/35/36/37/42/41/40 cluster, so the old missing-hit preview is a browser binding/start-fragment problem, not missing EXE data.zfRuntime result sounds are WLK #03, #03, #04, #05, matching the canonical static result-sound sequence.z`Damage-number setup draws occur after each result sound, giving four runtime hit/result windows.zmActor frame run sequence exactly matches the canonical EXE timeline row after adjacent duplicate compression.zActor frame order matches the canonical row after run compression, but runtime draw holds are longer around hit/result windows than raw gate-only rows.z%hwanse-battle-rs-skill-runtime-reviewzruntime-evidence-promotedzPcaptures/runtime is gitignored; this report is the committed distilled evidence.)r/   r0   rawCaptureGitPolicy)
eventCounteventCountsresourceDrawCountsactorSurfaceactorSurfaceLabelactorDrawCountactorRunCountruntimeHitSoundsexpectedResultSoundsruntimeDamageSetupCountruntimeHitDamageSetupCountruntimeHitDamageSetupFramesframeRunSequenceExactframeSequenceExactry   	ownerName	skillNamerl   levelOrFixeddisplayVmStartVaHexdisplayStartSourcetimelineStatus
sourceNoteframeRunSequenceframeEvents	hitEventsdurationGatemovementEvents)zxKeep srcRect logging enabled for BltFast/Blt. It is now sufficient to prove exact actor frame indices for battle skills.zImprove derived-surface labels so the 0x10216D78 actor sheet is identified as the active btl_rs battle sheet instead of cara_sm1.cns.zIf helper/effect validation is needed, capture the same srcRect detail for btl_efc.cns helper draws and object +0x28 frame/state writes.)versionkindstatusr   r/   summary	textDrawssoundEventsactorFrameRunsdamageSetupDrawshitDamageSetupDraws	canonicalconclusionsnextTracerRequests) r"   r`   rh   r   openstripr   r   rZ   r,   r   rA   rF   joinrQ   rH   r|   rp   r   rd   r5   anynextr   relative_toROOTsumr~   dictmost_commonlenr&   )'manifest_path
jsonl_pathr/   rect_mapwlk_by_bytesevent_countsresource_draw_counts
text_drawssound_eventsactor_drawsdamage_setup_drawssurface_labelsr   liner   
event_nameresource_namesrc_rectdstr_   rg   matchesr@   
actor_runsr   expected_frame_sequenceexpected_run_sequencer^   expected_result_soundsrunruntime_actor_sequencerr   runtime_skill_run_sequenceruntime_hit_soundshit_sound_framesr   hit_damage_setup_drawsactor_surface_labelr   s'                                      `   r   collect_runtimer      sx   'H H')L!(L)0')J)+L(*K/1+-N	'	* \d [	D::<JJt$E7+J$)$55%%!&7!3).?)C',yy'?.3ii8L.M-2YY7J-K).?)C%*YY{%;
 ^+ %		*> ? [599]C[ (71<799X&-7-eii.ABH)%))H*=>C#<<B7D&&#(99U#3%*YYw%7"'))D/+099]+C27))<P2QMUsxx/I/I'I[_?C$((7*;AE+=:+.QD+.QD !M1eiio6U-eii.ABH)%))H*=>C&--#(99U#3%*YYw%7"'))D/MUsxx/I/I'I[_+.QD+.QD	 [(!!$yy/!&7!3#iio %		& 1$yy/(4UYYu5E(F %		& 1!&7!3	 [(V		&8I8OR-P(8)<=
&**:+;R@##$yy/!&7!3#iio%/ *1' !&	 -2IIj,A(-		&(9.3ii.E' #())H"5W[	\| K(J#%I'mmOR@-.EF:C--XZ:[\3cggg.\\;EFCc,/FF!2 0	
  	
" "&@&Cq&H%?%C" "99\"uyy'='E 	lAz*  "99\"uyy'='E*UZU^U^_fUgilJm 	g  'XGWXX 	  ZNZK "%::  K  	L f	

 7-M55d;<//56#u

 l1134-"&';'G'G'I"J)!4!+. _ 2$:'*+='>*-.D*E+1Mc2dT4=2d+e%?CX%X"8<S"S
   #$.5
9=='
{3
 {3
 )--5	

 IMM.9
 "9==1F#G
 !)--0D"E
 imm,<=
 )--5
 4
  5
 9==;
 {B7
 IMM."=
 IMM.9
  imm,<bA!
$ #
e7 7y'e\ \D ]F	


Z 3esW   M1`&`&A0`&:`!`&2`3`8'`=7a	Aa a2a(!`&&`0c                     dt        |        dS )Nz<td>z</td>r   r   s    r   tdr   p  s    !E(5!!r   c           
        | d   }dj                  d | d   D              }dj                  d | d   D              }dj                  d | d   D              }dj                  d	 | d
   D              }dj                  d | d   D              }dj                  d | d   d   D              }dj                  d | d   d   D              }dj                  d | d   D              }	dj                  d t        |d   j                               d d D              }
dj                  g dt        | d   d          dt        | d          dt        |d          d t        |d!          d"t        dj                  d# |d$   D                     d%|d&   rd'nd( d)t        |d&          d*| d+t        | d   d,          d-t        | d   d.          d/t        | d   d0          d1t        | d   d2          d3t        | d   d4          d5t        |       d6t        |       d7t        | d   d8          d9|	 d:t        |d;          d<t        |d=   xs i j	                  d>             d?t
         d@| dA| dB| dCt        |
       dDt        | dE   dF          dG| dH      S )INr   
c           	   3  ^  K   | ]  }d t        |d         z   t        |d         z   t        |d         z   t        |j                  d      d|d    nd      z   t        |j                  d            z   t        |j                  d	       d
|j                  d             z   dz     yw)<tr>rw   ru   rv   rs   N#r   rt   rV   r   rW   </tr>r   rZ   r6   r^   s     r   r8   zrender_html.<locals>.<genexpr>v  s      
  	
S
	 
S
	 S
	  (=(Iq\"#$r
R		S
 SWWY
 	! ~Qswws|n-
.	/ 	
s   B+B-r   c              3  J  K   | ]  }d t        |d         z   t        |j                  d            z   t        |j                  d            z   t        dj                  d |j                  dg       D                    z   t        |j                  d            z   dz     y	w)
r  rr   r   rc   , c              3  .   K   | ]  }d |d   d  yw)r  r   02dNr   )r6   ms     r   r8   z(render_html.<locals>.<genexpr>.<genexpr>  s     R11Z=-.Rs   r   r?   r  N)r   rZ   r   r  s     r   r8   zrender_html.<locals>.<genexpr>  s      	  	
S\
	
SWWT]
	 SWW[!
"	# TYYRb8QRR
S		T
 SWWX
	  		s   B!B#r   c           	   3    K   | ]}  }d t        |d         z   t        |j                  d            z   t        |j                  d            z   t        |j                  d       d|j                  d             z   dz     yw)	r  rr   r   rt   rV   r   rW   r  Nr  r  s     r   r8   zrender_html.<locals>.<genexpr>  s       	CL!!Bswwt}$553779;M8NNQSWZW^W^_bWcVddefifmfmnqfresTtQuuxs   BBr   c              3  :   K   | ]  }d t        |       d  ywz<li>z</li>Nr   r6   r   s     r   r8   zrender_html.<locals>.<genexpr>  s      W44$y!6 W   r   c              3  :   K   | ]  }d t        |       d  ywr  r   r  s     r   r8   zrender_html.<locals>.<genexpr>  s     ZttAdG9E2Zr  r   r  c              3  &   K   | ]	  }d |   yw)r  Nr   )r6   rr   s     r   r8   zrender_html.<locals>.<genexpr>  s     \!E7\s   r   r   c              3  F   K   | ]  }d |j                  d      d  yw)r  r   r	  Nr   r  s     r   r8   zrender_html.<locals>.<genexpr>  s#     hs!CGGG$4S#9 :hs   !r   c              3    K   | ]  }d t        |d         z   t        |j                  d            z   t        |j                  d            z   t        |j                  d            z   t        |j                  d            z   dz     yw)r  rr   r   r_   r   r   r  Nr  r  s     r   r8   zrender_html.<locals>.<genexpr>  s      	  	
S\
	
SWWT]
	 SWWV_
	 SWW^$
%		&
 SWWU^
	 		s   B
Br   c              3  0   K   | ]  \  }}| d |   yw)rm   Nr   )r6   r   counts      r   r8   zrender_html.<locals>.<genexpr>  s'      D% &%s   r      r   u}  <!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Rinshan Skill Runtime Review</title>
  <style>
    body { margin: 0; font-family: system-ui, sans-serif; background: #111418; color: #e8edf2; }
    main { max-width: 1180px; margin: 0 auto; padding: 24px; }
    a { color: #9ed8ff; }
    .panel { background: #1b2027; border: 1px solid #313944; border-radius: 8px; padding: 16px; margin: 14px 0; }
    .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
    .metric { background: #13171d; border: 1px solid #2d3540; border-radius: 6px; padding: 12px; }
    .label { color: #a9b5c2; font-size: 12px; }
    .value { font-size: 18px; font-weight: 700; margin-top: 4px; }
    table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 13px; }
    th, td { border-bottom: 1px solid #303844; padding: 7px 8px; vertical-align: top; text-align: left; }
    th { color: #d8e8ff; background: #222934; position: sticky; top: 0; }
    code { color: #ffd69a; }
    .scroll { overflow: auto; max-height: 520px; border: 1px solid #303844; border-radius: 6px; }
    .ok { color: #7ee787; }
    .warn { color: #ffd36e; }
  </style>
</head>
<body>
<main>
  <p><a href="index.html">← index</a></p>
  <h1>린샹 안면백조권 Runtime Review</h1>
  <p>캡처 <code>r/   trace_idu   </code>를 canonical EXE timeline과 대조한 증거 페이지입니다.</p>

  <section class="panel grid">
    <div class="metric"><div class="label">status</div><div class="value ok">r   z\</div></div>
    <div class="metric"><div class="label">actor draws</div><div class="value">r   z / r   ze runs</div></div>
    <div class="metric"><div class="label">runtime hit WLK</div><div class="value">c              3  (   K   | ]
  }d |d  yw)r  r	  Nr   )r6   ns     r   r8   zrender_html.<locals>.<genexpr>  s&       fXvwhijkloipfq  fXs   r   zc</div></div>
    <div class="metric"><div class="label">canonical run exact</div><div class="value r   okwarnz">uX   </div></div>
  </section>

  <section class="panel">
    <h2>핵심 결론</h2>
    <ul>uV   </ul>
  </section>

  <section class="panel">
    <h2>Canonical 비교</h2>
    <p><b>r   z</b> / r   z lvr   u   
      · start <code>r   u   </code>
      · r   z#</p>
    <p>Expected frames: <code>z.</code></p>
    <p>Expected result WLK: <code>z</code></p>
    <p>r   z</p>
  </section>

  <section class="panel">
    <h2>Prompt Text</h2>
    <table><thead><tr><th>frame</th><th>pc</th><th>rect</th><th>decoded</th><th>raw</th></tr></thead><tbody>zr</tbody></table>
  </section>

  <section class="panel">
    <h2>Actor Frame Runs</h2>
    <p>Trace surface <code>r   z</code> is labeled <code>r   r   z7</code>, but every source rect below resolves to <code>z</code>.</p>
    <div class="scroll"><table><thead><tr><th>first</th><th>last</th><th>draw frames</th><th>btl_rs frame</th><th>srcRect</th><th>dst</th></tr></thead><tbody>z</tbody></table></div>
  </section>

  <section class="panel">
    <h2>Sound Events</h2>
    <div class="scroll"><table><thead><tr><th>frame</th><th>pc</th><th>bytes</th><th>WLK match</th><th>detail</th></tr></thead><tbody>at  </tbody></table></div>
  </section>

  <section class="panel">
    <h2>Damage Setup Draws</h2>
    <p>Four pairs of <code>btl_etc.cns</code> setup draws appear one frame after the four result sounds. Later non-hit numeric setup draws are excluded here.</p>
    <div class="scroll"><table><thead><tr><th>frame</th><th>pc</th><th>srcRect</th><th>dst</th></tr></thead><tbody>zw</tbody></table></div>
  </section>

  <section class="panel">
    <h2>Capture Summary</h2>
    <p>Top resource draws: zC</p>
    <p>Raw capture path is intentionally not committed: <code>r   r0   z^</code></p>
  </section>

  <section class="panel">
    <h2>Next Tracer Requests</h2>
    <ul>z+</ul>
  </section>
</main>
</body>
</html>
)r   listitemsr   rZ   r[   )r]   r   
actor_rows
sound_rowsdamage_rowsconclusion_itemstracer_itemsexpected_framesexpected_sounds	text_rows	resourcess              r   render_htmlr'  t  s	   9oG 
 ()
 
J  	 &	 	J )) -. K yy W4CV WW99ZtDX?YZZLii\k9J?9[\\Oiihd;FWXfFghhO		 	 $	 	I 		 (< = C C EFrJ IW W  W8 T*%j1239W84T9W> UVVZ[cVdTeSf?W>gV?W@ WXX_`pXqVrUsAW@ twAW@ xy  zA  BQ  zR  xS  wTAW@TZAWB [\\`\e\e  fX  |C  DV  |W  fX  ]X  [Y  ZZCWBZ\CWD el  mD  eE\`  KQ  \REWD RUEWD VW  X_  `w  Xx  Vy  UzEWDz	EWN 
OWNOWX T+{+,
-YWX .5YWX 67tK7H7U5V4WYWX X[YWX \]]abm]no}]~[  [AYWXAYWZ [)*?@AB[WZC
[W\ D23
4	5]W\6]W^  !12_W^3#_W` $%_#5"6aW`7aWb 	
${
L
)*+cWb,mcWl nwlwmWlxmWv gn567wWv 8QwWv RST[\oTpTvtvS{S{  }J  TK  RL  QMwWv MDwWv EN  DOwWvOawWx bl  amyWxmIyWB JT  IUCWBUvCWN wB  vCOWNCOWX iL>YWX*?YWZ @AhPWAX?Y>Z[WZ[	[Wd 
eWdeW Wr   c                    t               \  } }t        | |      }t        j                  t	        j
                  |dd      dz   d       t        j                  t        |      d       t        t               t        t               y )NFrC   )ensure_asciiindentr   r   r   )	r1   r   JSON_OUT
write_textr   dumpsHTML_OUTr'  print)r/   r0   r]   s      r   mainr0    sf    ')OHe8U+D

4eAFMX_`D)G<	(O	(Or   __main__)r   r   returnr   )r!   r   r2  dict[str, Any])r2  ztuple[Path, Path])r?   
str | Noner2  z tuple[int, int, int, int] | None)r?   r4  r2  ztuple[int, int] | None)r?   r4  r2  z
int | None)rP   r4  r2  r4  )r2  z/dict[tuple[int, int, int, int], dict[str, Any]])r2  zdict[int, list[dict[str, Any]]])r2  r3  )rS   list[dict[str, Any]]r2  r5  )r~   	list[Any]r2  r6  )r   r   r   r   r2  r3  )r]   r3  r2  r   )r2  None)+__doc__
__future__r   r   r   r:   collectionsr   pathlibr   typingr   __file__resolveparentsr   r'   rY   WEBr+  r.  r)   r   r[   rn   ro   r   r"   r1   rA   rF   rH   rQ   r`   rh   rp   r|   r   r   r   r'  r0  __name__r   r   r   <module>rB     s   
 #   	    H~''**y(
Ul
Ul6666	 H8747a4Qh"DN zF r   