
    Zi                        S SK r S SKrS SKJr  S SKJrJrJrJrJ	r	  S SK
Jr  S SKJr  S SKJr  S SKJr  S SKJr  S S	KJr  S S
KJrJr  S SKr\R0                  " S5      r\" S/ SQ5      rS\S\4S jrS\S\4S jrS\S\\S4   4S jrS\S\\ S4   4S jr!S\S\"4S jr#S\S\ 4S jr$S\S\4S jr%S\ SS4S jr&S\'S\ 4S jr(S\S\4S jr)S\S\4S  jr*S\S\4S! jr+S"\\   S\4S# jr,  S:S"\\   S$\S%\S\\\\   \	\\\   4   4   \\   4   4S& jjr-S\'S\4S' jr.S\'S\4S( jr/S\'S\4S) jr0S*\'S+\'S\4S, jr1S;S-\'S.\'S/\ S\'4S0 jjr2 S<S1 jr3S\S\4S2 jr4S\S\4S3 jr5S"\\\\4      S\4S4 jr6S5 r7S6 r8S7 r9 " S8 S95      r:g)=    N)
namedtuple)UnionAnyListTupleDict)	codepages)Token)Tree)MalformedRtfis_codeword_with_numeric_arg)flatten_tree_to_string_array)log_text_extractionis_logger_onRTFDEfontdef)fnumcodepagecodecfontdef_treetreereturnc                 8   U R                   SS  He  n[        U[        5      (       d  M   UR                   S   n[        U[        5      (       d  MA  UR
                  R                  5       nUS:X  d  Mc  Us  $    [        S5      e! [         a  n SnAM  SnAff = f)a  Extract the font table group from the first 20 tokens of a .rtf document.

Args:
    tree (Tree): A .rtf document object parsed into a Tree object

Raises:
    ValueError: If no group with a `\fonttbl` token as its first controlword is found.

Returns:
    {'\f0': fontdef(fnum='\f0', codepage=932, codec='cp932', fontdef_tree='{\f0\fswiss\fcharset128 MS PGothic;}'),
    '\f1': fontdef(fnum='\f1', codepage=None, codec=None, fontdef_tree='{\f1\fmodern MS Gothic;}'),
    '\f2': fontdef(fnum='\f2', codepage=None, codec=None, fontdef_tree='{\f2\fnil\fcharset2 Symbol;}'),
    '\f3': fontdef(fnum='\f3', codepage=1252, codec='cp1252', fontdef_tree='{\f3\fmodern\fcharset0 Courier New;}'),
    '\f4': fontdef(fnum='\f4', codepage=932, codec='cp932', fontdef_tree='{\f4\fswiss\fcharset128 "PMingLiU";}'),
    '\f5': fontdef(fnum='\f5', codepage=None, codec=None, fontdef_tree='{\f5\fswiss "Amnesty Trade Gothic";}'),
    '\f6': fontdef(fnum='\f6', codepage=None, codec=None, fontdef_tree='{\f6\fswiss "Arial";}')}
    N      s   \fonttblzNo font table found in tree)children
isinstancer   
IndexErrorr
   valuestrip
ValueError)r   item
ctrl_value_e
table_types        o/var/www/eduai.edurigo.com/question_generate/ques_gen_env/lib/python3.13/site-packages/RTFDE/text_extraction.pyget_font_tabler(   $   s    $ cr"dD!!!]]1-
 *e,,'--335
-K # 2
33  s   B
BBtokenc                 L     [        U S5      (       a  g g! [         a     gf = f)z}Checks if an object is a "font number".

Returns:
    True if an object is a "font number" controlword `\fN`. False if not.

   \fTF)r   AttributeError)r)   s    r'   is_font_numberr-   C   s5    'v66 7   s    
##	fcharsetNc                    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._S!S"S#S!S$S._S%S&S'S%S(S._S)S*S+S)S,S._S-S.S/S-S0S._S1S2S3S1S4S._S5S6S7S5S8S._S9S:S;S9S<S._S=S>S?S=S	S._n[        S@5      SAL a  [        SBU  35        UR                  U S	5      nUb  UR                  SCS	5      nU$ g	)Da8  Return the codepage to use with a specific fcharsetN.

Args:
    fcharsetN (int): The numeric argument N for a charsetN control word.

Returns:
    (int OR None) Returns the int for a codepage if known. Returns None for unknown charsets or charsets with no corresponding codepage (such as OEM or DEFAULT.)

    r   ANSI_CHARSET0x00  )namehexdecimalidr   DEFAULT_CHARSET0x01N   SYMBOL_CHARSET0x02   SHIFTJIS_CHARSET0x80     HANGUL_CHARSET0x81     GB2312_CHARSET0x86     CHINESEBIG5_CHARSET0x88     GREEK_CHARSET0xA1     TURKISH_CHARSET0xA2     HEBREW_CHARSET0xB1     ARABIC_CHARSET0xB2     BALTIC_CHARSET0xBA     RUSSIAN_CHARSET0xCC     THAI_CHARSET0xDEj     
EE_CHARSET0xEE     OEM_CHARSET0xFFRTFDE.text_extractionTzGetting charset for r6   )r   r   get)r.   charsetscharset
charset_ids       r'   get_codepage_num_from_fcharsetrt   Q   s   )	.vt
D)	#&1$
G) 	
"!
F) 	&VcsK	)
 	$6CSI) 	$6CSI) 	)#N) 	O&3DI) 	%FSdK) 	$6CTJ) 	$6CTJ) 	$6CTJ) 	%FSdK) 	N#3G) 	LvF)  	M$G!)H$ +,429+>?ll9d+G[[t,
    c                     U R                  S 5      n[        U5      n US   nUR                  SS nSU-   $ ! [         a     gf = f)a  Extract the font number controlword default font if it exists.

If an RTF file uses a default font, the default font number is specified with the \deffN control word, which must precede the font-table group.

Args:
    tree (Tree): A lark Tree object. Should be the DeEncapsulator.full_tree object.

Returns:
    The default font control number if it exists from the first `\deffN`. None if not found.
c                     [        U S5      $ )Ns   \deffr   )vs    r'   <lambda>"get_default_font.<locals>.<lambda>   s    .q)<ru   r      Nr+   )scan_valueslistr    r   )r   deff_gendeff_optionsdeffdeff_nums        r'   get_default_fontr   x   s\     <H >LA::ab>   s   8 
AA	font_treec                    0 nU R                    GH  n[        U[        5      (       d  M  SnSnSnUR                    H  n[        US5      (       a  UR                  nM"  [        US5      (       a%  [        UR                  SS 5      n[        U5      nMX  [        US5      (       d  Mk  [        UR                  SS 5      nM     Uc  M  SnUb   [        U5      nUc  Ub   [        U5      nUb  [        U5      n	OSn	SR                  [        [        U5      5      5      n
[        X8X5      X'   GM!     U$ ! [         a    Sn Nif = f! [         a    Sn Nif = f)zCreate a font tree dictionary with appropriate codeces to decode text.

Args:
    font_tree (Tree): The .rtf font table object decoded as a tree.

Returns:
    A dictionary which maps font numbers to appropriate python codeces needed to decode text.
Nr+   s	   \fcharset	   s   \cpg   ru   )r   r   r   r   r    intrt   check_codepage_numr"   get_python_codecjoinr}   r   r   )r   parsed_font_treer   r   fcharsetcpg_numtok	fchar_numcodepage_numr   tree_strs              r'   parse_font_treer      sY    ""dD!!DHG}}/V<<99D1#}EE #CIIabM 2I=iHH1#x@@!#))AB-0G % #','9('C ")0C,'9''B  +,\:E EHHT*Ft*L%MN)0U)U &G #H ! & ,'+, & ,'+,s$   D4 E4EEEEr   c                 z    [         R                  " U 5      n[        R                  SR	                  X5      5        U$ )zReturns the python codec needed to decode bytes to unicode.

Args:
    codepage_num (int): A codepage number.

Returns:
    The name of the codec in the Python codec registry. Used as the name for enacoding/decoding.
z6Found python codec corresponding to code page {0}: {1})r	   codepage2codeclogdebugformat)r   
text_codecs     r'   r   r      s2     )),7JIIFMMlghru   c                 H    [        / SQ5      nX;   a  U $ [        SU  S35      e)a	  Provide the codepage number back to you if it is valid.

Args:
    codepage_num (int): A possible codepage number.

Returns:
    The codepage number IF it is a valid codepage number

Raises:
    ValueError: The codepage_num provided isn't a valid codepage number.

)%   i  i  i  i  i  i  i  i  iR  iT  iW  iY  iZ  i\  i]  i^  i_  i`  ia  ib  ie  if  rg   ik  r?   rG   rC   rK   i  i  it  iu  iv  iw  ix  iy  iz  i{  i|  i}  i  i  rk   rc   r2   rO   rS   rW   r[   r_   i  iQ  i'  i'  i'  i'  i'  i'  i'  i'  i'  i'  i!'  i%'  i-'  i_'  ia'  ib'  i.  i.  i N  i!N  i"N  i#N  i$N  i%N  iN  iN  iN  iN  iN  i%O  i-O  i1O  i5O  i6O  i8O  i<O  i=O  iBO  iIO  iO  iO  iO  iaQ  ifQ  iQ  iQ  iQ  iQ  iQ  iQ  iQ  iQ  i!R  i#R  ijU  io  io  io  io  io  io  io  io  io  io  io  iIq  iƖ  i,  i-  i.  i1  i3  i5  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  %Unsupported unicode codepage number `` found in the header)setr"   )r   allowed_codepage_numss     r'   r   r      s:         !v  w, <\NJ_`
aaru   headerc                      [        U R                  5       SS 5      n[        U5        g! [         a  n[	        SU  S35      UeSnAff = f)zCheck an '\ansicpgNNNN' string to see if the number NNNN is an actual codepage.

Args:
    header (str): The value from the lark `\ansicpg` CONTROLWORD Token.

Raises:
    MalformedRtf: If the value passed is not a valid ansi codepage.
   Nr   r   )r   r!   r   r"   r   )r   possible_cpg_numr%   s      r'   validate_ansi_cpgr      sT    jv||~ab12+, jB6(J_`agiijs   '* 
A	AA	r#   c                      SnU R                  U5      (       a  U [        U5      S nOU n[        U5      nUS:  a  SU-   nOUn[	        U5      $ ! [         a  n[        SU  S35      UeSnAff = f)a  Convert unicode char from it's decimal to its unicode character representation. From "\u[-]NNNNN" to the string representing the character whose Unicode code point that decimal represents.

Args:
    item (str): A RTF Escape in the format \u[-]NNNNN.

Returns:
    The unicode character representation of the identified character

Raises:
    ValueError: The escaped unicode character is not valid.
   \uN`z+` is not a valid escaped unicode character.r      )
startswithlenr   r"   chr)r#   prefixnnnnr%   ncrs        r'   unicode_escape_to_chrr      s    X??6""F%DD4y axdls8O  X1TF"MNOUWWXs   4A 
A.A))A.c                 P    [        U [        5      (       a  U R                  S:X  a  gg)zIdentify if a token contains a HEXENCODED token.
Args:
    item (token): A token to check if it is HEXENCODED.

Return:
    True if HEXENCODED. False if not.
    
HEXENCODEDTFr   r
   typer#   s    r'   is_hex_encodedr     s#     $99$ru   c                     [        U [        5      (       aA  [        U 5      (       a  gU R                  S:X  a   U R                  R                  5       (       d  gg)zIs token contain a valid ANSI representation string for a Unicode char.

Args:
    item (token): A token to check if it is a valid ANSI representation.

Return:
    True if token is an ansi representation of a unicode char. False if not.
TSTRINGF)r   r
   r   r   r    isspacer   s    r'   !is_valid_ANSI_representation_charr     sF     $$99 ::%%'' ru   c                 P    [        U [        5      (       a  U R                  S:X  a  gg)zIs token contain a unicode char.

Args:
    item (token): A token to check if contains a unicode char.

Return:
    True if token contains a unicode char. False if not.
UNICODETFr   r   s    r'   is_unicode_encodedr   7  s#     $99	!ru   r   c                 :    U  H  n[        U5      (       d  M    g   g)a  Does a list include Tokens which contain unicode characters. Not recursive.

Args:
    children (list): A Tree.children list to check to see if it includes unicode characters.

Returns:
    True if list includes tokens which contain unicode chars. False if not.
TF)r   )r   childs     r'   includes_unicode_charsr   E  s!     e$$  ru   return_ascii_map
byte_countc                 j   Sn0 n/ n/ n[        S5      SL a  [        S[        U 5       35        U  GH  n[        U5      S:  Ga  [	        U[
        5      (       aE  UR                  R                  5       (       a&  UR                  US   / 5      R                  U5        Mn  [        U5      (       a1  UR                  UR                  5       / 5      R                  U5        M  [	        U[        5      (       a  UR                  S:X  d  UR                  S:X  a  UR                  n/ n[        U5       Hy  u  p[        U
5      (       aS  [        U5      S:  a1  UR                  UR                  5       / 5      R                  U
5        MU  UR                  U
5        Mh  UR                  U
5        M{     U/ :X  a  SSKJn  U" S	S
U5      nOXl        [%        U5      (       a  ['        U5      n[)        U5      (       a#  [+        U5       H  nUR                  U5        M     UR                  U5        GM     USL a  XC4$ U$ )a  Remove all unicode replacement characters from a list of Tokens.

Args:
    children (list): A Tree.children list to remove unicode replacement characters from.
    return_ascii_map (bool): On True, have this function return a map of the ASCII token that were removed.
    byte_count (int): The number of bytes corresponding to a given \uN Unicode character.  A default of 1 should be assumed if no \uc keyword has been seen in the current or outer scopes.

Returns:
    new_children (list): The list of Tokens with all unicode replacement characters removed.
    ascii_map (dict): All the Tokens which were removed from the provided children list keyed by

r   ro   Tz!Removing unicode replacements on r   stringhexarray)make_token_replacementr   ru   )r   r   reprr   r   r
   r    r   
setdefaultappendr   popr   datar   	enumerateRTFDE.utilsr   is_unicode_char_byte_countget_unicode_char_byte_countr   range)r   r   r   	ascii_mapnew_childrenremoval_mapr   ansi_childrennew_ansi_childrenaciacr   js                r'   remove_unicode_replacementsr   T  s   " J*,IL!K+,4?X?OPQ{a%'' ;;&&((((Q<CCEJ077 $$[__%6;BB5IE4((ZZ8+z1I %$&!'6FC8<<{+a/ &001BBGNNrR .44R8 *004 7 %*B 38S%HE%6N &e,,4U;Je$$:& ""5) ' 	E"m n 4&&ru   c           	          U R                  S5      (       a  U SS n S[        [        S[        U 5      -   5      5      s=::  a  S::  a   g  S[        U 5      s=::  a  S::  a   g  gg)	a,  Check's if chr is a is in the high-surrogate code point rage. "High-surrogate code point: A Unicode code point in the range U+D800 to U+DBFF." High-surrogate also sometimes known as the leading surrogate.

item (bytes): A bytes representation of a string representing a unicode character. "\u-10179"
r   r9   N   r     TFr   ordr   r   r   s    r'   is_surrogate_high_charr     c    
 vABxSs4y)*4f4 5 
3t9	&	& 
'ru   c           	          U R                  S5      (       a  U SS n S[        [        S[        U 5      -   5      5      s=::  a  S::  a   g  S[        U 5      s=::  a  S::  a   g  gg)	a  Check's if chr is a is in the low-surrogate code point rage. "Low-surrogate code point: A Unicode code point in the range U+DC00 to U+DFFF."  Low-surrogate also sometimes known as following surrogates.

item (bytes): A bytes representation of a string representing a unicode character.
r   r9   N   r     TFr   r   s    r'   is_surrogate_low_charr     r   ru   c           	          US:X  a1  S[        [        S[        U 5      -   5      5      s=::  a  S::  a   g  g
 g
US:X  a1  S[        [        S[        U 5      -   5      5      s=::  a  S::  a   g  g
 g
[        S	5      e)ai  Checks if a unicode char is 16 bit signed integer or the raw unicode char. This should first check if it is a surrogate code using the is_surrogate_XXXX_char functions.

Args:
    item (bytes): A bytes representation of a string representing a unicode character.
    cp_range (str): ['low' OR 'high'] The code point range (low-surrogate or high-surrogate).
    lowr   r   r   Thighr   r   z'cp_range must be either 'low' or 'high'F)r   r   r   r"   )r#   cp_ranges     r'   is_surrogate_16bitr     s     5SU3t9_-.8&8 9  9  
V	SU3t9_-.8&8 9 	 9  BCCru   firstsecondc                     [        U 5      (       a5  [        U5      (       a  g[        R                  SR	                  X5      5        g)aD  Check if a pair of unicode characters are a surrogate pair. Must be passed in the correct order.

Args:
    first (bytes): A bytes representation of a string representing the high-order byte in a surrogate char.
    second (bytes): A bytes representation of a string representing the low-order byte in a surrogate char.
    T=  RTFDE encountered a standalone high-surrogate point without a corresponding low-surrogate. Standalone surrogate code points have either a high surrogate without an adjacent low surrogate, or vice versa. These code points are invalid and are not supported. Their behavior is undefined. Codepoints encountered: {0}, {1}F)r   r   r   infor   )r   r   s     r'   is_surrogate_pairr     sL     e$$ ((HH  U  \  \  ]b  k  lru   r   r   encodingc                    U R                  S5      (       a  U SS n UR                  S5      (       a  USS n[        U S5      (       a  [        S[        U 5      -   5      nO[        [        U 5      5      n[        US5      (       a  [        S[        U5      -   5      nO[        [        U5      5      n[	        U5      S-
  S-  [	        U5      S	-
  -   S-   n[        U5      R                  U5      nUR                  U5      R                  5       $ )
a  Convert a pair of surrogate chars into the corresponding utf-16 encoded text string they should represent.

Args:
        high (bytes): the high-surrogate code point
        low (bytes): the low-surrogate code point
        encoding (str): The encoding to apply to the final value. Defaults to 'utf-16-le' because:  Microsoft uses UTF-16, little endian byte order. ( https://learn.microsoft.com/en-us/windows/win32/intl/using-byte-order-marks ) The Msg format is a Microsoft standard. Therefore, man is mortal.
    r   r9   Nr   r   r   r   i   r   )r   r   r   r   r   encodedecode)r   r   r   	char_highchar_lowunicode_scalar_valueunicode_bytess          r'   decode_surrogate_pairr     s     vABx
~~f!"g$''c$i(	D	N	#u%%uSX~&s3x= ^f4=#h-RXBXY\cc,-44X>M)0022ru   c                    SnSn[        U 5       GH  u  pV[        U[        5      (       a  M  [        U5      (       d  M/  [	        UR
                  5      (       a  UnUnMO  Uc  MT  [        UR
                  5      (       a  Un [        UR
                  UR
                  5      n[        SUUR                  UR                  UR                  UR                  UR                  UR                  S9n	XU'   [        SSUR                  S-   UR                  S-   UR                  UR                  UR                  UR                  S9n
XU'   SnSnGM>  ["        R%                  SR'                  UW5      5        USL a2  SR!                  X    Vs/ s H  oUR
                  PM     sn5      X'   GM  [)        S5      e   U $ ! [         a~  nUSL ar  SR!                  X    Vs/ s H  oUR
                  PM     Os  snf sn5      X'   SR!                  X    Vs/ s H  oUR
                  PM     Os  snf sn5      U W'    SnAGM*  UeSnAff = fs  snf )	z


Raises:
    ValueError:  A Standalone high-surrogate was found. High surrogate followed by a illegal low-surrogate character.
    Nr   	start_posend_poslineend_linecolumn
end_columnru   r   Tr   z^Standalone high-surrogate found. High surrogate followed by a illegal low-surrogate character.)r   r   r   r   r   r    r   r   r
   r   r   r   r   r   r   UnicodeDecodeErrorr   r   r   r   r"   )r   r   0use_ASCII_alternatives_on_unicode_decode_failuresurrogate_startsurrogate_highicsurrogate_lowsurrogate_valuesurrogate_tok	blank_tokr%   s               r'   merge_surrogate_charsr	     s<    ON"aa  %agg.."#!" ,(11$%M%*?@T@T@M@S@S+U ).h.=8F8P8P6C6K6K3A3F3F7D7M7M5C5J5J9F9Q9Q)S 5B1$)(*-4B4L4LQ4N2?2G2G2I/=/B/B3@3I3I1?1F1F5B5M5M%O	 '0*.)- HH  ]  d  d  es  uB  C  DG4O47HHyOh=iOh!ggOh=i4j1(  *J  K  K[ #\ O . %KtS8;S\SlAmSla''SlAm8nH5*-((YE]3^E]GGE]3^*_HQKK"$H% >js=   C
F9	I
9
IH<G/. H<H$#H<:H<<Ic                     [        U [        5      (       a1  U R                  S:X  a!  U R                  R	                  S5      (       a  gg)NCONTROLWORDs   \ucTF)r   r
   r   r    r   r   s    r'   r   r   =  s6    $99%zz$$W--ru   c                 V    U R                   R                  5       n [        U SS  5      nU$ )N   )r    r   r   )r#   cur_ucs     r'   r   r   D  s(    ::Dab]FMru   c                 :    U  H  n[        U5      (       d  M    g   g)zkChecks if an tree's children includes a hexarray tree.

children (array): the children object from a tree.
TF)is_hexarray)r   r#   s     r'   has_hexarrayr  K  s!    
 t  ru   c                 d    [        U [        5      (       a  U R                  R                  S:X  a  gg)zhChecks if an item is a hexarray tree.

item (Tree or Token): an item to check to see if its a hex array
r   TF)r   r   r   r    r   s    r'   r  r  U  s'    
 $99??j(ru   c                 p    U R                  SS5      n[        R                  UR                  5       5      nU$ )zVConvert hex encoded string to bytes.

item (str): a hex encoded string in format \'XX
s   \'ru   )replacebytesfromhexr   )r#   	hexstring	hex_bytess      r'   get_bytes_from_hex_encodedr  _  s1    
 VS)Ii..01Iru   c                     [        S5      SL a  [        SR                  X5      5        Uc  SnU R                  U5      nUR	                  5       n[        S5      SL a  [        SR                  XU5      5        U$ )zDecode a bytes object using a specified codec.

item (bytes): A bytes object.
codec (str): The name of the codec to use to decode the bytes
ro   Tzdecoding char {0} with font {1}CP1252z)char {0} decoded into {1} using codec {2})r   r   r   r   r   )r#   r   decodeds      r'   decode_hex_charr  h  st     +,4=DDTQR}kk% GnnG+,4GNNt^cdeNru   c                   X    \ rS rSr  SS jrS\4S jrS\4S jrS\\	   4S jr
S	 rS
rg)TextDecoderiz  Nc                 R    Xl         X l        X0l        SU l        / U l        0 U l        g)a  
keep_fontdef: (bool) If False (default), will remove fontdef's from object tree once they are processed.
initial_byte_count: (int) The initial Unicode Character Byte Count. Does not need to be set unless you are only providing a RTF snippet which does not contain the RTF header which sets the  information.
use_ASCII_alternatives_on_unicode_decode_failure: (bool) If we encounter errors when decoding unicode chars we will use the ASCII alternative since that's what they are included for.

N)keep_fontdefucbcr   default_font
font_stack
font_table)selfr!  initial_byte_countr   s       r'   __init__TextDecoder.__init__|  s-     )&	@p= !ru   objc                     [        U5      U l        U R                  /U l        [        UR                  S   5      n[        U5      U l        [        S5      SL a  [        SU 35        gg)J

obj (Tree): A lark Tree object. Should be the DeEncapsulator.full_tree.
r   ro   TzFONT TABLE FOUND: N)	r   r#  r$  r(   r   r   r%  r   r   )r&  r*  raw_fonttbls      r'   set_font_infoTextDecoder.set_font_info  sb    
 -S1,,-$S\\!_5)+6/0D8"4[M BC 9ru   c                     U R                  U5        UR                  nU R                  U5       Vs/ s H  o3PM     snUl        gs  snf )r,  N)r.  r   iterate_on_children)r&  r*  r   r  s       r'   update_childrenTextDecoder.update_children  sA     	3<<#'#;#;H#EF#Ea#EFFs   Ar   c                     [        U5      (       a-  [        UU R                  S9u  p[        UUU R                  5      nU$ )N)r   )r   r   r"  r	  r   )r&  r   r   s      r'   prep_unicodeTextDecoder.prep_unicode  sH    !(++ #>hIM#TH
 -X-6-1-b-bdH
 ru   c              #   L  #    / n[        S5      SL a"  [        S5        [        S[        U5      -   5        U R                  U5      n[        S5      SL a  [        S[        U5      -   5        U GH  n[	        U5      (       ae  U R
                  R                  UR                  R                  5       5        UR                  UR                  5        U R                  SL a  Uv   Mw  My  [        U5      (       a  [        UR                  5      R                  5       n[        SUUR                  UR                  UR                   UR"                  UR$                  UR&                  S9n[        S5      SL a  [        SU S	U 35        Uv   GM  [)        U5      (       Ga	  S nS nS nS n	S n
S nS nUR*                   H  nUc_  UR                  nUR                  nUR                   nUR"                  n	UR$                  n
UR&                  n[-        UR                  5      nMe  UR                  nUR"                  n	UR&                  nU[-        UR                  5      -  nM     U R.                  U R
                  S
      nUR0                  n[3        X5      n[        SUUUUU	U
US9nUv   GM8  [5        U[6        5      (       a8  U R9                  UR*                  5       Vs/ s H  nUPM     snUl        Uv   GM  Uv   GM     U H  nU R
                  R;                  5         M     g s  snf 7f)Nro   Tz2Starting to iterate on text extraction children...zPREP-BEFORE: zPREP-AFTER: r   r   zUNICODE TOKEN z: )r   r   r   r5  r-   r$  r   r    r!   r!  r   r   r   r
   r   r   r   r   r   r   r  r   r  r%  r   r  r   r   r1  r   )r&  r   	set_fontsr#   r  decoded_tok_hex_start_pos_hex_end_pos_hex_start_line_hex_end_line_hex_start_column_hex_end_column
base_byteshexchildcurrent_fontdefcurrent_codecdecoded_hexdecoded_hex_tokr  s                      r'   r1  TextDecoder.iterate_on_children  s    	/0D8 TUX >?$$X./0D8tH~ =>Dd##&&tzz'7'7'9:  ,$$,J -#D))/

;BBD#H$+.2nn,0LL)--1]]+/;;/3@   78D@'.b(NO!!T""!%#"& $$(!"&!
 $H!))1););'/'7'7*2--(0(9(9,4OO)*2*=*=%?%O
'/'7'7(0(9(9*2*=*="&@&PP
 !. #'//$//"2E"F / 5 5-jH"'(32@0<-<1>/@3B#D &%D$'',0,D,DT]],S T,Sq,S T

} ~ AOO! 	 !Us   KL$L#AL$)r#  r$  r%  r!  r"  r   )FNF)__name__
__module____qualname____firstlineno__r(  r   r.  r2  r   r
   r5  r1  __static_attributes__ ru   r'   r  r  z  s?    $)Y^$
D 
DG4 GT%[  J"ru   r  )Tr   )z	utf-16-le)F);codecsrecollectionsr   typingr   r   r   r   r   oletools.commonr	   
lark.lexerr
   	lark.treer   RTFDE.exceptionsr   r   r   r   r   r   logging	getLoggerr   r   r(   boolr-   r   rt   strr   dictr   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r	  r   r   r  r  r  r  r  rM  ru   r'   <module>r[     s    	 " 0 0 %   ) 4 4 9  
Y M
N4 4$ 4>% D $c $eCHo $N4 E#d(O ..t . .b3 3 bS bS b0jc jd j" # 8 4 E d 0U t T%[ T   :>23P$u+ P26P,/P8=$)$u+tE$u+<M7N*N$O$(K%091Ph 4  $ U  $U E d 3 3E 3S 3RW 3< NS9zU t e  4eTk 23  $E" E"ru   