
    *pj/|                     F   % S r SSKrSSKrSSKrSSKrSSKrSSKJrJ	r	J
r
JrJr  SSKJr  SSKJr  \\\\4   \\\   \\\\\4   4   4   4   r0 SS_SS_S	S
_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS _S!S"_S#S$_S%S&_S'S(S)S*S+S,S-S.S/S0S1S2S3S4.Er\\\4   \S5'   \R3                  5        V Vs0 s H  u  pX_M	     snn r\\\4   \S6'   S7\S8\4S9 jr\R:                  S8\4S: j5       r0 SS_SS_S
S_SS_SS_SS_SS_SS_SS_SS_S S_S"S_S$S_S&S_S'S_S)S_S(S_SSSSSS	SSSSSSSS;.Er\\\4   \S<'   S	r Sr!S	r"S=r#Sr$\R:                  S>\S8\4S? j5       r%S@\SA\SB\SC\S8\4
SD jr&S7\SE\SF\SG\\   SH\\\\\4   4   S8\\S-  \\\4   4SI jr'\" 5       4S7\SJ\SK\SL\\   S8\S-  4
SM jjr(S7\SE\SF\SG\\   SH\\\\\4   4   S8\S-  4SN jr)\R:                  SG\\   S8\\\4   4SO j5       r*\r+\R:                  SP\S8\\   4SQ j5       r,SE\SF\SL\\   S8\\   S-  4SR jr-SS\	ST\\\.\\S-  \\4      4   SP\SL\\   S-  S8\/4
SU jr0\" 5       4S7\SE\SF\SG\\   SL\\   S8\S-  4SV jjr1SW\SE\SF\S8\\\4   S-  4SX jr2SYr3SZr4S[r5S\r6S7\S]\.\   S8\.\   4S^ jr7gs  snn f )_a  Confusion group resolution for similar single-byte encodings.

At runtime, loads pre-computed distinguishing byte maps from confusion.bin
and uses them to resolve statistical scoring ties between similar encodings.

Build-time computation (``compute_confusion_groups``, ``compute_distinguishing_maps``,
``serialize_confusion_data``) lives in ``scripts/confusion_training.py``.

Note: ``from __future__ import annotations`` is intentionally omitted because
this module is compiled with mypyc, which does not support PEP 563 string
annotations.
    N)ART_LANGUAGEBigramProfileget_enc_indexget_idf_weightsscore_with_profile)DetectionResult)lookup_encodingLu   Ll   Lt   Lm   Lo   Mn   Mc   Me   Nd	   Nl
   No   Pc   Pd   Ps   Pe   Pi   PfPoSmScSkSoZsZlZpCcCfCsCoCn)                                       _INT_TO_CATEGORY_CATEGORY_TO_INTdatareturnc                    0 nSn[         R                  " SX5      u  nUS-  n[        U5       GH  n[         R                  " SX5      u  nUS-  nXX%-    R                  S5      nX%-  n[         R                  " SX5      u  nUS-  nXX'-    R                  S5      nX'-  n[         R                  " SX5      u  n	US-  n/ n
0 n[        U	5       Ha  n[         R                  " SX5      u  pnUS-  nU
R	                  U5        [
        R                  US	5      [
        R                  US	5      4X'   Mc     [        U
5      U4XU4'   GM     U$ )
zLoad confusion group data from raw bytes.

:param data: The raw binary content of a confusion.bin file.
:returns: A :data:`DistinguishingMaps` dictionary keyed by encoding pairs.
r   z!Hr   z!Br   zutf-8z!BBBr   r7   )structunpack_fromrangedecodeappendrE   get	frozenset)rG   resultoffset	num_pairs_
name_a_lenname_a
name_b_lenname_b	num_diffsdiff_bytes_list
categoriesbv	cat_a_int	cat_b_ints                  V/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/chardet/pipeline/confusion.py%deserialize_confusion_data_from_bytesr`   L   sa    "$FF%%dD9LY
aKF9**4>!v23::7C**4>!v23::7C))$=!%'13
y!A'-'9'9&$'O$B9aKF""2& $$Y5 $$Y5JN	 " %.o$>
#K 1 4 M    c                     [         R                  R                  S5      R                  S5      n U R	                  5       nU(       d  [
        R                  " S[        SS9  0 $  [        U5      n0 nUR                  5        H5  u  u  pgn[        U5      =(       d    Un	[        U5      =(       d    Un
XX4'   M7     U$ ! [        R                  [        4 a  nSU 3n[        U5      UeSnAff = f)zLoad confusion group data from the bundled confusion.bin file.

:returns: A :data:`DistinguishingMaps` dictionary keyed by encoding pairs.
zchardet.modelszconfusion.binuZ   chardet confusion.bin is empty — confusion resolution disabled; reinstall chardet to fixr   )
stacklevelzcorrupt confusion.bin: N)	importlib	resourcesfilesjoinpath
read_byteswarningswarnRuntimeWarningr`   rJ   errorUnicodeDecodeError
ValueErroritemsr	   )refrawraw_mapsemsg
normalizedabvaluenorm_anorm_bs              r_   load_confusion_datar{   t   s     


#
#$4
5
>
>
OC
..
C'		
 	%8=
 &(J!) #(q #(q',F#$ *  LL,- %'s+o1$%s   #B; ;C+C&&C+)r.   r/   r0   r1   r2   r4   r3   r6   r5   r7   r   r   r   _CATEGORY_PREFERENCE   encodingc                 <   [        S5      n[        S5       Hg  n [        U/5      R                  U 5      n[        U5      S:w  a  M0  [        R                  " U5      nUS:X  a  SX'   MR  US   S:X  d  US;   d  Mc  SX'   Mi     [        U5      $ ! [         a     M  f = f)u{  256-entry table: 0 = non-letter, 1 = uppercase letter, 2 = other letter.

Combining marks count as letters: in decomposed text (Vietnamese under
windows-1258) a base letter's neighbor is its diacritic, which is
word-internal, not a word boundary.  Whitespace deliberately counts as
a plain non-letter: exempting space-adjacent letters from the
isolated-letter demotion (to spare one-letter words like French ``à``)
was tried and falsified by the accuracy suite — Irish/Finnish po files
and the EBCDIC record set depend on space-adjacent demotions, so the
cross-family decisive-override gate handles the ``à`` failure mode
instead.
r}   r   r
   r   L)r   r   r   )	bytearrayrL   bytesrM   rm   lenunicodedatacategory)r~   tablerw   chcats        r_   _letter_case_tabler      s     cNE3Z	s""8,B r7a<""2&$;EHVs]c\1EH  < " 		s   B
BBr   leftright
case_tablec                     [         R                  U S5      nU S   S:w  a  U$ X1   nX2   nUS:X  a  US:X  a  [        $ U S:X  a  US:X  a  [        $ U$ )a  Preference for reading a byte as *cat*, adjusted for word shape.

A letter reading only deserves its high preference when its neighbors
make it look like part of a word under the same encoding: a letter with
no letter neighbors is quoted/isolated punctuation in disguise, and a
lowercase letter immediately followed by an uppercase one is not a word
shape any of the supported languages produce.
r   r   r   r   )r|   rO   _IMPLAUSIBLE_LETTER_PREFERENCE)r   r   r   r   pref	left_kind
right_kinds          r_   _context_preferencer      sa      ##C+D
1v} I"JA~*/--
d{zQ--Kra   enc_aenc_b
diff_bytesr[   c                 \   [        U5      u  pV[        U R                  SU5      5      nU(       d  g[        U5      n[        U5      n	Sn
SnSnSnSnSn[	        U 5      S-
  nU GH-  nUU   u  nn[        U45      nU R                  U5      nSnUS:  d  M3  U[        :  d  M?  US:  a  U US-
     OSnUU:  a  U US-      OSn[        UUUU5      n[        UUUU	5      nUU:  a<  US   S:X  a
  US   S:X  a  OjU
UU-
  -  n
US   S:X  a  U[        :X  a  UUU-
  -  nUS-  nOAUU:  a;  US   S:X  a
  US   S:X  a  O(UUU-
  -  nUS   S:X  a  U[        :X  a  UUU-
  -  nUS-  nUS-  nU R                  UUS-   5      nUS:  d  GM!  U[        :  a  M  GM0     X:  a  XU-
  X4$ X:  a  X+U
-
  X4$ g)u  Context-aware category voting.

Returns ``(winner, margin, demotion_margin, demotion_events)``.

For each occurrence of a distinguishing byte, compare the two
encodings' readings: Unicode category preference, adjusted for word
shape (see :func:`_context_preference`).  The reading that makes more
linguistic sense of the byte *in its context* collects the vote;
occurrences vote independently, so repeated evidence counts.

``demotion_margin`` counts only the winner's votes earned where the
*losing* side's letter reading was word-shape-implausible — evidence
against an impossible reading, which is far stronger than the naive
letters-beat-symbols preference.  ``demotion_events`` counts how many
distinct occurrences contributed to it, so callers can tell repeated
evidence from one loud byte.
N)Nr   r   r   r   r   r   P)
_pair_byte_tablesrP   	translater   r   r   find_MAX_VOTE_OCCURRENCESr   r   )rG   r   r   r   r[   non_diffrT   relevanttable_atable_bvotes_avotes_b
demotion_a
demotion_bevents_aevents_bendr\   cat_acat_bneedleposexaminedr   r   pref_apref_bs                              r_   _vote_with_marginr     s   8 $J/KHh78H 'G 'GGGJJHH
d)a-C!"~uuiiQh8&;;$'!G4a=D%(3YDqMAE(eWEF(eWEF 8s?uQx3v.GQx365S+S"fvo5
 A&8s?uQx3v.GQx365S+S"fvo5
 AMH))FC!G,C; Qh8&;;; F '=='==ra   enc_xenc_y	languagesc                 &   [        5       n[        XAU5      nUc  gXE   u  pgUu  p[        XXU5      u  ppU
b)  U[        :  a  U[        :  a  [        U5      [        :  a  U
$ [        XXU5      n[        U5      [        :  a  Ub  X:X  a  U$ gUb  U$ U
$ )u  Return the byte-evidence winner between two encodings, or ``None``.

Mirrors the in-band pairwise rule of :func:`resolve_confusion_groups`
(decisive demotion vote, else bigram rescore, else category vote) for
callers outside the ranked-results scan — e.g. the classic-Mac
line-ending promotion, whose platform prior must not override
distinguishing-byte evidence.  Returns ``None`` when the pair has no
distinguishing map or the evidence is inconclusive.

*languages* must carry what the two results being compared report, or
the mirror breaks: the rescore would arbitrate the same pair under a
different rule than the confusion stage just did, and a veto built on
that answer can reverse a promotion the stage had settled.
N)r{   _find_pair_keyr   _DECISIVE_VOTE_MARGIN_DECISIVE_MIN_EVENTSr   _CROSS_FAMILY_MIN_DIFFSresolve_by_bigram_rescore)rG   r   r   r   mapspair_keyr   r[   r   r   
cat_winner_margindemotion_margindemotion_eventsbigram_winners                  r_   confusion_pair_winnerr   ^  s    (  Dd51H!^JLE<MU
=9J 	4433
O55-d5iXM
:11 $)D  )5=E:Era   c                 &    [        XX#U5      u  pVpxU$ )z~Resolve between two encodings using context-aware category voting.

:returns: The winning encoding name, or ``None`` if tied.
)r   )	rG   r   r   r   r[   winnerr   	_demotion_eventss	            r_   resolve_by_category_votingr     s!     +<U
+'FY Mra   c                    ^ [        S5      mU  H  nSTU'   M
     [        U4S j[        S5       5       5      nU[        T5      4$ )a  Return ``(non_diff_delete, membership)`` byte tables for a pair.

``non_diff_delete`` holds every byte value *not* in *diff_bytes* (for
``bytes.translate`` deletion) and ``membership`` is a 256-entry table
with 1 at each distinguishing byte (native indexing under mypyc, where
frozenset probes are boxed).  Cached because *diff_bytes* comes from
the fixed per-pair confusion maps loaded once per process.
r}   r   c              3   @   >#    U  H  nTU   (       a  M  Uv   M     g 7fN ).0rw   members     r_   	<genexpr>$_pair_byte_tables.<locals>.<genexpr>  s     <
1&)QQ
s   	)r   r   rL   )r   rw   r   r   s      @r_   r   r     sD     s^Fq	 <c
<<HU6]""ra   encc                 V    [        S [        5       R                  U / 5       5       5      $ )z'Languages *enc* has a bigram model for.c              3   6   #    U  H  u  n  o!c  M  Uv   M     g 7fr   r   )r   langrT   s      r_   r   &_modelled_languages.<locals>.<genexpr>  s      ;q!;s   
	)rP   r   rO   )r   s    r_   _modelled_languagesr     s-      ,223;  ra   c                     U(       d  g[        U 5      n[        U5      nX4-  nX%::  d  g[        U;   d
  [        U;   a
  U[        1-  $ U$ )u9  Languages to score *enc_a* and *enc_b* under, or ``None`` for all.

``None`` means *unrestricted* — score every variant, the original
max-over-models comparison.  It is not an abstention.

An encoding should not win on language coverage the other side lacks.
On a Hungarian document the u-double-acute bytes score 0.014 against
iso8859-2's *Czech* model (which reads them as a common r-hacek) and
only 0.006 against iso8859-16's Hungarian one, so max-over-variants
hands Hungarian text to the Czech reading.  Dropping the languages
only one side models removes that particular unfairness.

This is deliberately a narrow rule, and two tempting generalisations
were measured and rejected against the accuracy suite:

* Restricting to *languages* themselves rather than the shared set
  costs 12 tests.  As a consequence the restriction is a no-op for
  pairs whose language coverage already matches (67 of the 236
  confusion pairs), which is accepted — those pairs have no coverage
  asymmetry to correct in the first place.
* Restricting when *languages* is not wholly inside the shared set
  costs 6 tests: cp1125 models only Ukrainian, so a Belarusian cp866
  document shares just ``uk`` with it, and scoring the *right*
  encoding under the *wrong* language loses to cp1125.  Falling back
  to unrestricted is also what keeps a Vietnamese windows-1258
  document, whose rival cp1252 models no Vietnamese, resolving
  correctly.  The cost is that pairs modelling disjoint languages
  (koi8-r/koi8-u, mac-roman/mac-turkish) never restrict at all —
  about 20% of calls over the corpus.
N)r   _ART_LANGUAGE)r   r   r   langs_alangs_bshareds         r_   _comparable_languagesr     sS    F !%(G!%(GF =G#;''Mra   profileindexc                 b   ^ ^ UR                  U5      nU(       d  g[        UU 4S jU 5       SS9$ )ar  Return the best bigram score for *enc*, restricted to *languages*.

*languages* of ``None`` means every variant, the unrestricted
max-over-models comparison.  The ``default`` guards a caller-supplied
set that names no variant of *enc*; note that scoring 0.0 hands the
comparison to the rival rather than abstaining, so callers wanting an
abstention must not rely on it.
g        c              3   X   >#    U  H  u  pnTb  UT;   d  M  [        TX#5      v   M!     g 7fr   )r   )r   r   model	model_keyr   r   s       r_   r   &_best_variant_score.<locals>.<genexpr>  s7      	
*2&Y DI$5 :w99*2s   **)default)rO   max)r   r   r   r   variantss   `  ` r_   _best_variant_scorer     s7     yy~H	
*2	

  ra   c                    [        U 5      S:  a  g[        U5      u  pV[        U R                  SU5      5      nU(       d  g[        XU5      n[	        5       n	0 n
[        U 5      S-
  nU[
        -  [        U 5      :  a  [        5       n[        U R                  SU5      5       Hu  n[        U45      nU R                  U5      nUS:  d  M(  U(       a  UR                  US-
  5        X:  a  UR                  U5        U R                  XS-   5      nUS:  a  MM  Mw     U H/  nU U   S-  U US-      -  nU
R                  US5      U	U   -   U
U'   M1     OT[        U5       HE  nU U   nU US-      nUU   UU   -  (       d  M"  US-  U-  nU
R                  US5      U	U   -   U
U'   MG     U
(       d  g[        R                  " U
5      n[        5       n[!        UUX5      n[!        UUX(5      nUU:  a  U$ UU:  a  U$ g)u  Resolve between two encodings by re-scoring only distinguishing bigrams.

Builds a focused bigram profile containing only bigrams where at least one
byte is a distinguishing byte, then scores both encodings under the
languages they can be compared in (see :func:`_comparable_languages`).

There is no abstention path here: when the pair has no comparable
language the comparison widens to every variant rather than declining
to answer.  That is why a Danish mac-roman/mac-turkish document, whose
pair models disjoint languages, is still decided by the Turkish model
the rescore has no business consulting — the caller's category vote is
better placed on such evidence, and overriding this to abstain was
measured as costing more accuracy than it recovers.

:param data: The raw byte data to examine.
:param enc_a: First encoding name.
:param enc_b: Second encoding name.
:param diff_bytes: Byte values where the two encodings differ.
:param languages: Languages the ranked results report for this pair;
    empty when the caller has no ranking to draw on, which scores
    every variant.
:returns: The winning encoding name, or ``None`` if tied or if no
    distinguishing byte occurs in *data*.
r   Nr   r   r   )r   r   r   r   r   _DENSE_HIT_DIVISORsetrP   r   r   addrO   rL   r   from_weighted_freqr   r   )rG   r   r   r   r   r   is_diffhits
comparableidffreqlimitstartsr\   r   r   iidxb1b2r   r   best_abest_bs                           r_   r   r     s   > 4y1} **5Ht~~dH-.D&uY?J

CDIME  3t9, 5DNN4:;BB5\F))F#C(JJsQw';JJsOiia0 ( < A7a<4A;.Ca(3s83DI  uAaBa!eBBK'"+-7b.Ca(3s83DI  ..t4GOE %CF %CFra   r   c                 ,    X4U ;   a  X4$ X!4U ;   a  X!4$ g)zEFind the canonical key for a pair of encodings in the confusion maps.Nr   )r   r   r   s      r_   r   r   h  s+     	~~~~ra   4   g{Gzt?g      ?g?resultsc                 :   [        U5      S:  a  U$ US   nUR                  c  U$ UR                  S:X  a  U$ [        5       nUR                  nU[
        -  nSnUnUR                  n[        S[        U5      5       GH  n	X   n
U
R                  c  M  U	S:H  =(       d    XJR                  -
  [        :*  nU(       d  U[        :  d  U
R                  U:  a    GOX[        X8U
R                  5      nUc  Mw  X<   u  pUu  nn[        XUX5      u  nnnnUb*  U[        :  a   U[        :  a  [        U5      [        :  a  UnOf[        S UR                  U
R                  4 5       5      n[        XUUU5      nU(       a  [        U5      [        :  a  Ub  UOUnOUb	  UU:X  a  UnOSnUb  UU
R                  :w  a  GM=  U(       a[  [!        U
R                  UU
R                  U
R"                  5      n[%        U5       VVs/ s H  u  nnUU	:w  d  M  UPM     nnnU/UQs  $ U	nU
nU
R                  nGM     US:X  a  U$ [!        UR                  UUR                  UR"                  5      n[%        U5       VVs/ s H  u  nnUU:w  d  M  UPM     nnnU/UQ$ s  snnf s  snnf )a  Resolve confusion between similar encodings in the top results.

Checks the top result against each candidate within a confidence band.
Always checks position 1 (preserving original top-2 behavior); for
positions 2+ only checks within the band.  Uses bigram re-scoring
with category voting as fallback.

:param data: The raw byte data to examine.
:param results: Detection results sorted by confidence descending.
:returns: A reordered list of :class:`DetectionResult` with the winner first.
r   r   Nzxxr   c              3   0   #    U  H  nUc  M  Uv   M     g 7fr   r   )r   r   s     r_   r   +resolve_confusion_groups.<locals>.<genexpr>  s      CD Cs   	)r   r~   languager{   
confidence_CONFUSION_FLOOR_RATIOrL   _CONFUSION_BAND_STRICT_TIER_MAX_CONFr   r   r   r   r   rP   r   r   	mime_type	enumerate)rG   r   topr   top_conffloorchampion_idxchampionchampion_encr   	candidatein_bandr   r   r[   r   r   r   _vote_marginr   r   r   langsr   promotedjrrests                               r_   resolve_confusion_groupsr    s    7|a
!*C
|| ||u D~~H--ELH
 <<L1c'l#J	% q&NH';';;N--1E1E1M!$i6H6HI!%
uEV
F
B
L/?( "#88#77J"99F
  %..	0B0BC E
 6UJM 3z?-DD*7*C
 *}
/J&>Vy'9'99 '""""##	H #,G"4?"4$!QQA"4D?$t$$  ))y $| q 	H $G,B,$!Q\0AA,DBt5 @2 Cs   :JJ2JJ)8__doc__	functoolsimportlib.resourcesrd   rJ   r   ri   chardet.modelsr   r   r   r   r   chardet.pipeliner   chardet.registryr	   dicttuplestrrP   intDistinguishingMapsrE   __annotations__ro   rF   r   r`   cacher{   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   listfloatr   r   r   r   r   r   r  r  )kvs   00r_   <module>r$     sN         - , 	#s(O	)C.$sE#s(O34
457 $t$t$ t$ t	$
 t$ t$ t$ t$ t$ t$ $ $ $ $ $  !$" #$$ 	=$ $sCx. D 6F5K5K5M#N5MTQAD5M#N $sCx. N% %:L %P /  >("("( 	"( 	!	(
 	!( 	!( 	!( 	!( 	!( 	!( 	!( 	!( 	!( 	!( 	!(  	!!(" 	!#($ 











=( d38n H "#             @S  C U s *P
PP P #	P
 S%S/)*P 3:sC$%Pn !*	+F
+F+F +F ~	+F
 	4Z+F\
  #	
 S%S/)* 	4Z" #)C. #U5%<5H # #&  S Ys^  222 ~2 s^d	2jT%d
E3 67889 
 ~$	
 @ !*Y
YY Y #	Y
 ~Y 	4ZYx



 
 38_t	
(       W
W/"W 
/WY $Os   2J