Ë
    ;Cæj+8  ã                  ó>  — d Z ddlmZ ddlZddlZddlmZmZmZ ddl	m
Z
 ddlZddlmZmZmZmZ ddlmZ dd	lmZmZmZmZ dd
lmZmZmZmZmZ ddlm Z m!Z!m"Z"  ejF                  d«      Z$ddddœZ%e G d„ d«      «       Z&dd„Z'dd„Z(dd„Z)dd„Z*dd„Z+dd„Z,d d„Z-y)!aù  Orchestrates the layers into structured reports, one per (original track, dub track) pair.

  tracks: probe -> extract -> language-ID -> pick original + dub streams (skip passthrough copies)
  per pair:
    VAD (both) -> align lines -> timing issues
    [stems] -> background/energy issues
    ASR (both, cached per track) -> fast-speech + LLM semantic judge on aligned lines
    subtitle-vs-audio check (subtitle stream matching the dub language)
    visual mouth check on flagged windows -> severity re-weighting
    dedupe/rank -> Report

Nothing here is language specific: languages come from `lang.resolve` (declared) or Whisper LID
(detected), and per-track artefacts (audio, LID, ASR, stems) are cached so an original shared by
n dubs is processed once.
é    )ÚannotationsN)ÚasdictÚ	dataclassÚfield)ÚPathé   )ÚaudioÚspeechÚtimingÚvisual)Úsame_language)Úextract_subtitlesÚ	parse_srtÚprobe_cachedÚtc)ÚAlignedLineÚBatchReportÚIssueÚReportÚSummary)ÚTrackÚ
dub_tracksÚoriginal_trackÚdubevalg      @g      @gffffffæ?©ÚcriticalÚmajorÚminorc                  óö   — e Zd ZU dZded<    ee¬«      Zded<   dZded<   dZ	ded	<   d
Z
ded<   dZded<    ed„ ¬«      Zded<   dZded<   dZded<   dZded<   dZded<    eej$                  ¬«      Zded<   y)ÚConfigNz
str | NoneÚsrc_lang)Údefault_factoryz	list[str]Ú	tgt_langsú
int | NoneÚ
orig_audioÚ	dub_audiozgroq/whisper-large-v3Úasr_cloud_modelÚsmallÚstrÚasr_local_modelc                 ó
   — ddgS )Nzgemini-flashzauto/best-fast© r,   ó    ú4/root/repos/pocs/video-evals/src/dubeval/pipeline.pyú<lambda>zConfig.<lambda>,   s   € ¸>ÐK[Ð:\€ r-   Ú
llm_modelsFÚboolÚseparateTr   é<   ÚintÚmax_visual_windowsé   Úthreadsztiming.ThresholdsÚ
thresholds)Ú__name__Ú
__module__Ú__qualname__r!   Ú__annotations__r   Úlistr#   r%   r&   r'   r*   r0   r2   r   r5   r7   r   Ú
Thresholdsr8   r,   r-   r.   r    r    $   s’   … à€HˆjÓÙ °Ô6€IˆyÓ6Ø!€J�
Ó!Ø €IˆzÓ Ø"9€O�ZÓ9Ø"€O�SÓ"Ù!Ñ2\Ô]€J�	Ó]Ø€HˆdÓØ€FˆDÓØ Ð˜Ó Ø€GˆSÓÙ$)¸&×:KÑ:KÔ$L€JÐ!ÔLr-   r    c                ó†   — t        j                  «       }t        ||z
  d«      | |<   t        j	                  d|||z
  «       |S )Né   zstage %-10s %6.1fs)ÚtimeÚperf_counterÚroundÚlogÚinfo)ÚtimingsÚnameÚt0Únows       r.   Ú_clockrJ   4   s>   € Ü
×
Ñ
Ó
€CÜ˜# ™( AÓ&€GˆD�MÜ‡H�HÐ! 4¨¨r©Ô2Ø€Jr-   c                óÜ  — t        j                  ||t        j                  «      }g }| D ]¿  }t	        |d   t        j                  z  «      t	        t        j                  |d   t        j                  z  «      «      }}||k  s|d   |d   z
  dk  rŒht        ||| j                  «       «      }|dk  sŒŠ|j                  dddd|d   |d   d|d	›d
�d|d   dt        |d«      idœ
«       ŒÁ |S )z,Subtitle cue with no dubbed speech under it.ÚstartÚendç333333ã?g333333Ã?ÚSUBTITLE_AUDIO_DESYNCÚsubtitler   zSubtitle cue is shown but only z.0%z of it has dubbed speech.zKRe-time the subtitle cue to the dubbed audio, or the line audio is missing.ÚtextÚcoverager@   )
ÚcategoryÚsourceÚseverityÚ
confidencerL   rM   ÚdescriptionÚfix_hintÚdubbed_textÚevidence)r
   Úmaskr   ÚHOPr4   ÚnpÚceilÚfloatÚmeanÚappendrC   )	ÚcuesÚdub_segsÚdurationÚdmÚoutÚcÚaÚbÚcovs	            r.   Ú_subtitle_issuesrk   ;   sø   € ä	�‰�X˜x¬¯©Ó	4€BØ
€CØò 
\ˆÜ�1�W‘:¤§
¡
Ñ*Ó+¬S´·±¸¸5¹ÄFÇJÁJÑ9NÓ1OÓ-Pˆ1ˆØ�Š6�Q�u‘X  '¡
Ñ*¨SÒ0ØÜ�B�q˜�G—L‘L“NÓ#ˆØ�‹:Ø�J‰JÐ$;ÀzÐ_fØ&)°A°g±JÀqÈÁxØ)HÈÈSÈ	ÐQjÐ'kØ$qØ'(¨¡y¸zÌ5ÐQTÐVWË=Ð>Yñ	[õ \ð
\ð €Jr-   c                ó  — t        | j                  «      j                  }|D ]8  }t        |j	                  d«      | j
                  j                  «      sŒ3|d   c S  t        |«      dk(  r|d   j	                  d«      s|d   d   S y)z_Subtitle stream in the dub's language; a lone untagged/other stream only if it is the only one.ÚlangÚindexr   r   N)r   ÚpathÚ	subtitlesr   Úgetrm   ÚbaseÚlen)ÚdubÚsubsÚss      r.   Ú_subtitle_streamrw   M   sw   € ä˜Ÿ™Ó!×+Ñ+€DØò ˆÜ˜Ÿ™˜v›¨¯©¯©Õ6Ø�W‘:Òðô ˆ4ƒy�A‚~˜d 1™gŸk™k¨&Ô1Ø�A‰w�wÑÐØr-   c                óì  — |j                   j                  d«      |j                   j                  dd«      }}|r|dk  rg S |j                   |j                  j                  | j                  j                  dœ}t	        || j                  j
                  «      r`t	        |j                  j
                  | j                  j
                  «      s,ddd|d|d	|› d
|d›d|j                  j                  › d�d|dœ	gS t	        ||j                  j
                  «      s[ddd|d|d|› d|d›d|j                  j                  › d�d|j                  j                  › d|j                  j                  › d�|dœ	gS g S )zPSpoken language of the dub track vs what it should be (detected by Whisper LID).rm   Úprobç        ç      à?)ÚdetectedÚexpectedÚsource_languageÚUNTRANSLATEDÚlanguager   z,Dub track is spoken in the source language (z, p=ú.2fz), not ú.zOWrong audio stream was muxed or TTS ran in the source language; re-mux the dub.©	rS   rT   rU   rV   rL   rM   rW   rX   rZ   ÚWRONG_LANGUAGEzDub track sounds like 'z' (p=z) but is declared zRegenerate the dub in z (z) or fix the language label.)Úlidrq   rm   Útagr   rr   rG   )Úsrcrt   rd   Údetry   Úevs         r.   Ú_language_issuesrŠ   X   s\  € à—‘—‘˜FÓ# S§W¡W§[¡[°¸Ó%=ˆ€CÙ�$˜’*Øˆ	Ø—g‘g¨3¯8©8¯<©<ÈCÏHÉHÏLÉLÑ	Y€BÜ�S˜#Ÿ(™(Ÿ-™-Ô(´¸s¿x¹x¿}¹}ÈcÏhÉhÏmÉmÔ1\Ø+°zÈzÐimØ hØ"NÈsÈeÐSWÐX\Ð]`ÐWaÐahÐil×iqÑiq×ivÑivÐhwÐwxÐ yØnØñ	!ð "ð 	"ô
 ˜˜cŸh™hŸm™mÔ,Ø-¸ÐQ[ÐkoØ hØ"9¸#¸¸eÀDÈÀ:ÐM_Ð`c×`hÑ`h×`mÑ`mÐ_nÐnoÐ pØ5°c·h±h·m±m°_ÀBÀsÇxÁxÇ|Á|ÀnÐTpÐqØñ	!ð "ð 	"ð
 €Ir-   c                óâ   — ddddœ}| j                  d„ ¬«       g }| D ]N  }|r|d   nd}|r0|d	   |d	   k(  r%|d
   |d   dz
  k  r||d      ||d      kD  r||d<   Œ>|j                  |«       ŒP |S )z=Same category on overlapping windows -> keep the most severe.r@   r   r   r   c                ó   — | d   | d   fS )NrS   rL   r,   ©Úxs    r.   r/   z_dedupe.<locals>.<lambda>p   s   € ˜q ™}¨a°©jÐ9€ r-   ©ÚkeyéÿÿÿÿNrS   rL   rM   gš™™™™™©?rU   )Úsortra   )ÚissuesÚorderÚkeptÚitÚprevs        r.   Ú_deduper˜   m   sŸ   € à Q°Ñ3€EØ
‡K�KÑ9€KÔ:Ø€DØò ˆÙˆt�BŠx TˆÙ�D˜Ñ$¨¨:©Ò6¸2¸g¹;ÈÈeÉÐW[ÑI[Ò;[Ø�R˜
‘^Ñ$ u¨T°*Ñ-=Ñ'>Ò>Ø��R‘ØØ�‰�B�ðð €Kr-   c                óV  ‡‡9— |dz  | j                   › d‰j                   › �z  }|j                  dd¬«       i }g }t        j                  «       }t        j                  d| j                  j                  ‰j                  j                  ‰j                   «       t        | j                  «      t        ‰j                  «      }	}t        |j                  |	j                  «      }
t        | ‰|
«      }t        |j                  |	j                  z
  «      dkD  rV|j                  ddd	d
|
t        |j                  |	j                  «      d|j                  d›d|	j                  d›d�di dœ	«       | j!                  |j"                  |j$                  |«      \  }}}‰j!                  |j"                  |j$                  |«      \  }}}|xr |}|s3| j&                  | j&                  ‰j&                  ‰j&                  f\  }}}}t)        |d|«      }t+        j,                  |«      }t+        j,                  |«      }|j.                  }t1        j2                  t+        j4                  ||j6                  «      ||
|«      \  }}t)        |d|«      }| j9                  ||«      ‰j9                  ||«      }}t)        |d|«      }|t1        j:                  |||||
|d   |«      z  }t=        j>                  |||||
|«      \  }}||z  }|t=        j@                  |||«      z  }|�0t        |«      dkD  r"|j                  ddd	dd|
d|d›d�dd|idœ	«       t)        |d|«      }g Š9tC        ‰«      }|�8	 tE        tG        ‰j                  ||d |› d!�z  «      «      Š9|tI        ‰9||
«      z  }ˆ9ˆfd#„}g }|D ]×  } | jL                  r t        | jN                  | jP                  «      n| jP                  }!| jL                  r t        | jR                  | jT                  «      n| jT                  }"|j                  | jV                  t+        jX                  || jP                  | jT                  «      t+        jX                  ||!|"«       ||!|"«      d$œ«       ŒÙ i }#|jZ                  �r�d%d&l.m.}$  |$|D �%cg c]  }%|%d'   s|%d(   sŒ|%‘Œ c}%|jZ                  | j                  j^                  ‰j                  j^                  |d)z  |«      }#|D �]  } |#ja                  | jV                  i «      ja                  d*g «      D ]Û  }&|&ja                  d+«      tb        v r|&ja                  d+«      nd,}'|j                  |&d-   d.|'te        |&ja                  d/«      xs d0«      tg        | jP                  d1«      tg        t        | jT                  | jR                  xs | jT                  «      d1«      | jV                  |&ja                  d2d3«      |&ja                  d4d5«      i d6œ
«       ŒÝ �Œ t)        |d7|«      }| j                  ji                  «       ‰j                  ji                  «       k7  r.|tk        jl                  | j                  ‰j                  |
«      z  }|jj                  rÊ	 tk        jn                  «       }(|D �&cg c]  }&|&d8   d9k(  sŒ|&d-   d:vsŒ|&‘Œ })}&|)jq                  d;„ ¬<«       |)d |jr                   D ]b  }&|&d=   t        |&d>   |&d=   d?z   «      }}*|(ju                  | j                  |*t        ||*d@z   «      «      |&dA<   tk        jv                  |&|&dA   «       Œd 	 t)        |dA|«      }ty        |«      }|jq                  dC„ ¬<«       i }+g },|D �%ci c]  }%|%dD   |%“Œ
 }-}%t{        |«      D ]¾  \  }.}&dE|.d%z   dF›�|&dG<   |&j}                  dHd «      }/|/�d|+j                  |/g «      j                  |&dG   «       |&j                  dI|-|/   d'   xs d «       |&j                  dJ|-|/   d(   xs d «       |/|&dK   dH<   |,j                  t�        d]tƒ        |&d=   «      tƒ        |&d>   «      dLœ|&¤Ž«       ŒÀ g }0|D �]I  } |#ja                  | jV                  i «      }1|0j                  t…        | jV                  tg        | jP                  d1«      tg        | jT                  d1«      | jN                  €d ntg        | jN                  d1«      | jR                  €d ntg        | jR                  d1«      | j†                  €d ntg        | j†                  d1«      tg        | jˆ                  d1«      |-| jV                     d'   |-| jV                     d(   |1ja                  dM«      |1ja                  dN«      |+ja                  | jV                  g «      ¬O«      «       �ŒL t1        jŠ                  ||||
«      }2i }3dPdPdPdQœ}4d}5|,D ]h  }&|3ja                  |&jŒ                  dP«      d%z   |3|&jŒ                  <   |4|&jŽ                  xx   d%z  cc<   |5tb        |&jŽ                     |&j�                  z  z  }5Œj tg        dRt“        j”                  |5 t        dS|
dTz  dUz  «      z  «      z  d%«      }6t—        dV„ |,D «       «      rd}6t™        d]tg        |
d1«      ||3|4|6dWœ|2¤Ž}7t›        | j                  j                  › dX‰j                  j                  › �| j�                  «       ‰j�                  «       |dY   |dY   g|tŸ        ‰9«      |dZœi t¡        |«      j£                  «       D �.�8ci c]  \  }.}8|.d[k7  sŒ|.|8“Œ c}8}.¥d[t¡        |«      i¥|7|,|0||¬\«
      S # tJ        $ r}|j                  d"|› �«       Y d }~�ŒÊd }~ww xY wc c}%w c c}&w # tJ        $ r}|j                  dB|› �«       Y d }~�Œ_d }~ww xY wc c}%w c c}8}.w )^NÚpairsÚ__T©ÚparentsÚexist_okzpair %s -> %s (%s)r{   ÚDURATION_MISMATCHÚvideor   gffffffî?zDurations differ: original r�   z	s vs dub zs.z=Keep the dubbed mix exactly as long as the original timeline.rƒ   ÚstemsÚ	vad_alignÚasrÚwordsé(   Ú
SYNC_DRIFTr	   gš™™™™™é?rz   z'Background bed in the dub is offset by z.0fz ms from the original.zMThe whole dubbed mix is shifted; re-mux with the background aligned to video.Ú	offset_msÚdetectzsubs.sz.srtzsubtitle extraction failed: c                ó‚   •‡ ‡— ‰j                   j                  j                  ˆˆ fd„‰D «       «      j                  «       S )Nc              3  óL   •K  — | ]  }|d    ‰kD  sŒ|d   ‰k  sŒ|d   –— Œ y­w)rM   rL   rQ   Nr,   )Ú.0rg   Úerv   s     €€r.   ú	<genexpr>z.run_pair.<locals>.script_in.<locals>.<genexpr>µ   s.   øè ø€ Ò#_°!¸qÀ¹xÈ!»|ÐPQÐRYÑPZÐ]^ÓP^ A f¥IÑ#_ùs   ƒ$‘$š
$)rm   ÚjoinerÚjoinÚstrip)rv   r¬   rb   rt   s   ``€€r.   Ú	script_inzrun_pair.<locals>.script_in´   s+   ú€ Ø�x‰x�‰×#Ñ#Ô#_°tÔ#_Ó_×eÑeÓgÐgr-   )ÚiÚorigrt   Úscriptr   )Újudger³   rt   zjudge_cache.jsonr“   rU   r   rS   ÚsemanticrV   rN   r@   ÚexplanationÚ rX   zRe-translate this line.)
rS   rT   rU   rV   rL   rM   Ú
line_indexrW   rX   rZ   rµ   rT   r   )r¦   ÚFAST_SPEECHc                ó   — t         | d       S )NrU   )Ú
SEV_WEIGHTr�   s    r.   r/   zrun_pair.<locals>.<lambda>Õ   s   € ¤Z°°*±Ñ%>Ð$>€ r-   r�   rL   rM   g      è?g      @r   zvisual analysis failed: c                ó   — | d   S )NrL   r,   r�   s    r.   r/   zrun_pair.<locals>.<lambda>à   s
   € ˜a ™j€ r-   r²   ÚIÚ03dÚidr¹   Úoriginal_textrY   rZ   )Ústart_tcÚend_tcÚorig_enÚdub_en)rn   Ú
orig_startÚorig_endÚ	dub_startÚdub_endÚonset_deltaÚdub_coveragerÁ   rY   Úoriginal_enÚ	dubbed_enÚ	issue_idsr   r   éd   g      ð?r3   é   c              3  ó\   K  — | ]$  }|j                   d k(  xr |j                  dk(  –— Œ& y­w)r€   r   N)rT   rU   )r«   rŽ   s     r.   r­   zrun_pair.<locals>.<genexpr>  s*   è ø€ Ò
NÀ1ˆ1�8‰8�zÑ!Ò> a§j¡j°JÑ&>Ó>Ñ
Nùs   ‚*,)rd   Úbackground_offset_msÚissue_countsÚseverity_countsÚscorez->Úengine)Úasr_enginesÚsubtitle_streamÚsubtitle_cuesr¡   r8   )
ÚpairrT   ÚtargetÚinputsÚconfigÚsummaryr“   Úaligned_linesÚstage_timingsÚwarningsr,   )RÚslugÚmkdirrA   rB   rD   rE   rm   r†   r   ro   Úminrd   rŠ   Úabsra   Úmaxr¡   r2   r7   rŽ   rJ   r
   Úvad_segmentsr8   r   ÚalignÚmergeÚline_merge_gapr£   r¨   r	   Úbackground_checkÚenergy_mismatchrw   r   r   rk   Ú	Exceptionrt   rÈ   rL   rÉ   rM   rn   Útext_inr0   rµ   rG   rq   r¼   r_   rC   Úresolver   Úvideo_identityÚMouthAnalyzerr’   r5   ÚanalyzeÚadjustr˜   Ú	enumerateÚpopÚ
setdefaultr   r   r   ÚonsetrR   ÚstatsrS   rU   rV   r]   ÚexpÚanyr   r   Údescribers   r   Úitems):r‡   rt   ÚworkÚcfgÚpair_dirrF   rá   ÚtÚpoÚpdrd   r“   ÚovÚobÚs1ÚdvÚdbÚs2r¡   Úo_rawÚd_rawÚttÚlinesÚ	unmatchedÚasr_oÚasr_dÚbgÚ	bg_offsetÚsir¬   r±   ÚrowsÚlnÚloÚhiÚjudgedrµ   ÚrrŽ   ÚsevÚanaÚcandrv   Úby_lineÚfinalÚtextsÚkÚliÚalignedÚjÚstÚcountsÚsevsÚpenaltyrÕ   rÞ   Úvrb   s:    `                                                       @r.   Úrun_pairr(  |   s«
  ù€ Ø�g‰~ 3§8¡8 *¨B¨s¯x©x¨jÐ 9Ñ9€HØ‡N�N˜4¨$€NÔ/Ø "€GØ€HÜ×ÑÓ€AÜ‡H�HÐ! 3§8¡8§<¡<°·±·±¸s¿x¹xÔHä˜#Ÿ(™(Ó#¤\°#·(±(Ó%;ˆ€BÜ�2—;‘; §¡Ó,€HÜ)¨#¨s°HÓ=€FÜ
ˆ2�;‰;˜Ÿ™Ñ$Ó%¨Ò+Ø�‰Ð#6À'ÐW^ÐnrØ (´°R·[±[À"Ç+Á+Ó1NØ(CÀBÇKÁKÐPSÐCTÐT]Ð^`×^iÑ^iÐjmÐ]nÐnpÐ&qØ#bÐprñtô 	uð —‘˜3Ÿ<™<¨¯©°hÓ?�J€BˆˆBØ—‘˜3Ÿ<™<¨¯©°hÓ?�J€BˆˆBØŠI�2€EÙØŸ™ §¡ s§u¡u¨c¯e©eÐ3‰ˆˆB��BÜˆw˜ Ó#€AÜ×Ñ Ó#€EÜ×Ñ Ó#€EØ	�‰€BÜ—|‘|¤F§L¡L°¸×8IÑ8IÓ$JÈEÐS[Ð]_Ó`Ñ€Eˆ9Üˆw˜ QÓ'€Aà—7‘7˜3 Ó)¨3¯7©7°3¸Ó+Aˆ5€EÜˆw˜˜qÓ!€Að Œf�m‰m˜E 9¨e°U¸HÀeÈGÁnÐVXÓYÑY€FÜ×*Ñ*¨2¨r°5¸%ÀÈ5ÓQ�M€Bˆ	Ø
ˆb�L€FØ
Œe×#Ñ# E¨2¨rÓ2Ñ2€FØÐ¤ Y£°"Ò!4Ø�‰ <¸7ÐPWÐgjØ #¨HØ(OÐPYÐZ]ÈÐ^tÐ&uØ#rØ$/°Ð#;ñ	=ô 	>ô
 	ˆw˜ !Ó$€Að €DÜ	˜#Ó	€BØ	€~ð	@ÜÔ.¨s¯x©x¸¸XÈ&ÐQSÐPTÐTXÐHYÑ=YÓZÓ[ˆDØÔ& t¨U°HÓ=Ñ=ˆFõhð €DØò YˆØ,.¯FªFŒS�—‘˜rŸx™xÔ(¸¿¹ˆØ(*¯ªŒS�—‘˜RŸV™VÔ$°B·F±FˆØ�‰˜"Ÿ(™(¬F¯N©N¸5À"Ç(Á(ÈBÏFÉFÓ,SÜ"ŸN™N¨5°"°bÓ9ÁYÈrÐSUÓEVñXõ 	YðYð
 !€FØ
‡~ƒ~Ý á 4ÖA˜a¨1¨Vª9¸¸%»šÒAÀ3Ç>Á>ÐSV×S[ÑS[×S`ÑS`Ðbe×bjÑbj×boÑboØÐ"4Ñ4°hó@ˆàó 	jˆBØ—Z‘Z §¡¨"Ó-×1Ñ1°(¸BÓ?ò j�Ø+,¯5©5°Ó+<Ä
Ñ+J�a—e‘e˜JÔ'ÐPW�Ø—‘¨1¨Z©=ÀJÐ\_Ü-2°1·5±5¸Ó3FÒ3MÈ#Ó-NÜ(-¨b¯h©h¸Ó(:Ä5ÌÈRÏVÉVÐUW×U_ÑU_ÒUiÐce×ciÑciÓIjÐlmÓCnØ-/¯X©XÀaÇeÁeÈMÐ[]ÓF^Ø+,¯5©5°Ð=VÓ+WÐegñ	iõ jòjð	jô �7˜G QÓ'ˆð ‡x�x×ÑÓ˜SŸX™X×-Ñ-Ó/Ò/Ø”&×'Ñ'¨¯©°#·(±(¸HÓEÑEˆØ
‡z‚zð		<Ü×&Ñ&Ó(ˆCØ%Öx˜!¨¨8©¸Ó)@ÀQÀzÁ]ÐZwÒEw’AÐxˆDÐxØ�I‰IÑ>ˆIÔ?ØÐ2˜C×2Ñ2Ð3ò .�Ø˜‘z¤3 q¨¡x°°7±¸dÑ1BÓ#C�1�Ø!Ÿk™k¨#¯(©(°A´s¸1¸aÀ#¹g³ÓG��(‘Ü—‘˜a  8¡Õ-ñ.ô �7˜H aÓ(ˆô �V‹_€FØ
‡K�KÑ(€KÔ)Ø$&€GØ€EØ $Ö%˜1ˆQˆs‰V�Q‰YÐ%€EÐ%Ü˜&Ó!ò O‰ˆˆ1Ø�a˜!‘e˜C�[�/ˆˆ$‰Ø�U‰U�< Ó&ˆØˆ>Ø×Ñ˜r 2Ó&×-Ñ-¨a°©gÔ6Ø�L‰L˜¨%°©)°FÑ*;Ò*C¸tÔDØ�L‰L˜¨¨b©	°%Ñ(8Ò(@¸DÔAØ*,ˆAˆj‰M˜,Ñ'Ø�‰”UÐM¤B q¨¡z£N¼2¸aÀ¹h»<ÑMÈ1ÑMÕNðOð €GØó kˆØ�J‰J�r—x‘x Ó$ˆØ�‰”{Ø—(‘(¤u¨R¯X©X°qÓ'9ÄEÈ"Ï&É&ÐRSÓDTØ Ÿl™lÐ2‘d¼¸b¿l¹lÈAÓ8NØŸJ™JÐ.‘D´E¸"¿*¹*ÀaÓ4HØ "§¡Ð 0™´e¸B¿H¹HÀaÓ6HÔW\Ð]_×]hÑ]hÐjkÓWlØ §¡™/¨&Ñ1¸uÀRÇXÁX¹ÈuÑ?UØŸ™˜iÓ(°A·E±E¸(³OÈwÏ{É{Ð[]×[cÑ[cÐegÓOhôjö 	kðkô 
�‰�e˜U E¨8Ó	4€BØ€FØ A°Ñ2€DØ€GØò 9ˆØ#ŸZ™Z¨¯
©
°AÓ6¸Ñ:ˆˆq�z‰zÑØˆQ�Z‰ZÓ˜AÑÓØ”:˜aŸj™jÑ)¨A¯L©LÑ8Ñ8‰ð9ô �#œŸ™ ˜x¬#¨c°8¸b±=À2Ñ3EÓ*FÑFÓGÑGÈÓK€EÜ
Ñ
NÈÔ
NÔNØˆÜð ?œu X¨qÓ1È	Ð`fØ&*°%ñ?Ø;=ñ?€GäØ—‘—‘ˆ~˜R §¡§¡˜~Ð.°s·|±|³~ÈcÏlÉlËnØ % h¡°°x±ÐAÐVXÜ!$ T£°Uñ<àh¤F¨3£K×$5Ñ$5Ó$7×M™D˜A˜q¸1ÀÓ;L�1�a‘4ÓMÐhÈ|Ô]cÐdfÓ]gÑhØ °WÈGÐ^fôhð høôk ò 	@Ø�O‰OÐ:¸1¸#Ð>×?Ò?ûð	@üò" Bùò$ yøô ò 	<Ø�O‰OÐ6°q°cÐ:×;Ò;ûð	<üò &ùóN Nsm   Í"7m  Òm+Ò(m+Ù=m5 Úm0Ú#m0Ú+m0Ú/B	m5 Ý,n ìn%ìn%í 	m(í	m#í#m(í0m5 í5	ní>nînc           
     óÌ  — |j                  dd¬«       t        | ||«      }t        j                  d| j                  |j
                  |j                  j                  |j                  «       g g g }}}|D ]\  }t        ||||«      \  }	}
||
z  }|	s|j                  t        |«      ddœ«       |	D ]   }	 |j                  t        ||||«      «       Œ" Œ^ t%        |j'                  «       |||¬
«      S # t        $ rj}t        j                  d|j                  «       |j                  t        |«      |j
                  t!        |«      j"                  › d|› �dœ«       Y d	}~Œ°d	}~ww xY w)zMOne original, any number of dub files, each with any number of audio streams.Trœ   zoriginal %s audio %d: %s (%s)z2no evaluable dub audio stream (see skipped_tracks))rt   Úerrorzpair %s failedz: )rt   Úaudio_indexr*  N)ÚoriginalÚreportsÚskipped_tracksÚfailed)rã   r   rD   rE   rG   rn   rm   r†   Úlang_sourcer   ra   r)   r(  rí   Ú	exceptionrâ   Útyper9   r   rû   )r,  Údubsrý   rþ   r‡   r-  Úskippedr/  ro   ÚtracksÚskipÚdr¬   s                r.   Úrunr8    sJ  € à‡J�J�t d€JÔ+Ü
˜ 3¨Ó
-€CÜ‡H�HÐ,¨h¯m©m¸S¿Y¹YÈÏÉÏÉÐVY×VeÑVeÔfØ! 2 r�fˆW€GØò 
oˆÜ! $¨¨S°$Ó7‰ˆ�Ø�4‰ˆÙØ�M‰M¤# d£)Ð6jÑkÔlØò 	oˆAðoØ—‘œx¨¨Q°°cÓ:Õ;ñ	oð
oô  §¡£¸ÐPWÐ`fÔgÐgøô ò oÜ—‘Ð.°·±Ô7Ø—‘¤c¨$£iÀÇÁÔUYÐZ[ÓU\×UeÑUeÐTfÐfhÐijÐhkÐRlÑm×nÑnûðoús   Â2C0Ã0	E#Ã9A EÅE#)rF   ÚdictrG   r)   rH   r_   Úreturnr_   )rb   ú
list[dict]rd   r_   r:  r;  )rt   r   r:  r$   )r‡   r   rt   r   rd   r_   r:  r;  )r“   r;  r:  r;  )
r‡   r   rt   r   rý   r   rþ   r    r:  r   )
r,  r   r3  z
list[Path]rý   r   rþ   r    r:  r   ).Ú__doc__Ú
__future__r   ÚloggingrA   Údataclassesr   r   r   Úpathlibr   Únumpyr]   r¸   r	   r
   r   r   rm   r   Úmediar   r   r   r   Úschemar   r   r   r   r   r5  r   r   r   Ú	getLoggerrD   r¼   r    rJ   rk   rw   rŠ   r˜   r(  r8  r,   r-   r.   ú<module>rE     s�   ðñõ #ã Û ß 0Ñ 0Ý ã ç +Ó +Ý ß AÓ Aß DÕ Dß 5Ñ 5à€g×Ñ˜	Ó"€à¨°cÑ:€
ð ÷Mð Mó ðMóóó$óó*óOhôdhr-   