
    ,hf             /          d dl Z d dlZd dlZd dlZd dlZ	 ddlmZ 	 ddlmZ ej                  Z
ej                  ZdZdZdZdZ	 ej                   Zej*                  Zej.                  edf   Zej4                  e   Zej4                  e   Zej4                  e   Z ej4                  e   Z!ej4                  ejD                     Z#	 	 	 	 	 	 	 	 	 dd
ejH                  ddfdZ%	 	 	 	 	 	 ddefdZ&ddddd
ejH                  defdZ'd
ejH                  defdZ(ddd d	dd d	dd dd d ddZ)ddejT                  ejV                  z  ejX                  z  ejZ                  z  ddde.fdZ/ddejT                  ejX                  z  ejV                  z  ejZ                  z  dfdej`                  dedede1dededejd                  de.fdZ3	 	 	 	 dd
ejH                  dededejd                  d e1de.fd!Z4	 	 	 	 	 	 dd
ejH                  dededejd                  d e1de.fd"Z5	 	 	 	 dd
ejH                  dededejd                  def
d#Z6	 dd
ejH                  d$edejd                  defd%Z7	 	 dd
ejH                  d&ed'ededejd                  f
d(Z8	 	 	 	 	 dd
ejH                  ded)ed*ed+e1d,edejd                  fd-Z9dd
ejH                  d.e1d/e1de.fd0Z:dd
ejH                  de.fd1Z;	 	 	 	 	 	 	 dd
ejH                  d2edededejd                  d e1fd3Z<	 	 	 	 	 ddej`                  ded2edededejd                  d e1dej*                  fd4Z=ej|                  dej~                  ddd	d5d
ejH                  d6ed7ej                  ded8e1d9e1dej                  fd:ZBej|                  dej~                  ddd	d5dej`                  ded6ed7ej                  ded8e1d9e1dej                  fd;ZCddefd<ZDd
ejH                  de.fd=ZE	 ddej`                  d>e1de.fd?ZFdej`                  d@eddfdAZG	 	 	 	 	 	 	 	 ddej`                  d@edBe dCededDedEedFedGedHeddfdIZHdefdJZIddej`                  dKeddfdLZJdedMedefdNZK	 ddej`                  dOe.dPedefdQZL	 	 	 	 ddRej`                  dSej`                  dTedUedVeddfdWZM	 	 	 ddXej`                  dYej`                  dTedUedVeddfdZZNd
ejH                  d[edefd\ZOd
ejH                  d]ej                  dej                  fd^ZQd
ejH                  d[eddfd_ZRdd
ejH                  d[ed`e1ddfdaZSdbdd d dcddddd d d ddddd	ddd ded
ejH                  d$edfej.                  ee.f   dgedhediedjedkedledme#dne#doedpedqedredsedtedue#dve1dwedxedyedef.dzZTdcddbdd d dddddd d dd	ddd d{d
ejH                  d|edej.                  ee.f   dkedledgedhediedjedme#dne#dtedsedredqedue#dve1dwedxedyef(d}ZUdd dd d dd	d~defdZV	 	 	 ddej`                  dedededejH                  f
dZW	 	 	 	 	 	 	 ddej`                  dedej.                  ee.df   dkedededgedhedme#defdZX	 	 	 	 	 	 	 	 	 	 dd
ejH                  d&ed'edme#dededededve1due#dwedxedej                  fdZZ	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  d&ed'ededme#dededededve1due#dwedxedyedej                  fdZ[	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  d&ed'ededme#dededededve1due#dwedxedyedej                  fdZ\	 	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  d$edme#dne#dededededue#dve1dwedxedyedej                  fdZ]	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  dedme#dne#dededededue#dve1dwedxedyedej                  fdZ^	 	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  de.dme#dne#dededue#dededve1de1dwedxedyedej                  fdZ_	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  dededme#dne#due#dededededve1dwedxedyedej                  fdZ`	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  d$ej.                  eef   dme#dne#dedue#dedededve1dwedxedyedej                  fdZa	 	 	 	 	 	 	 	 	 	 	 	 d d
ejH                  d&ed'ededme#dne#dededue#de1dededve1dwedxedyedej                  f"dZb	 	 	 	 	 	 	 	 	 	 	 	 d d
ejH                  d&ed'edededme#dne#dededuede1dededve1dwedxedyedej                  f$dZc	 	 	 	 	 	 	 	 	 	 	 	 	 dd
ejH                  ded|ededme#dne#dede1due#dede1dededve1dwedxedyedej                  f$dZdde.fdZede.fdZfdedegfdZhdedegfdZidej`                  dedegfdZj	 ddej`                  deded@ede de.fdZk G d d      Zl	 dd
ejH                  dededede1f
dZm	 	 	 	 	 	 	 	 	 	 	 	 	 ddej`                  de1de1de1de1de1de1de1dede1de1de1de1de1ddfdZnd Zo	 	 	 	 	 	 	 	 ddej                  d$edej.                  ee.f   dedej4                  ej                     dkedledpede1de1de1degfdZrdej`                  dedefdZsdej`                  dedyeddfdZt	 	 	 	 ddej`                  dedej.                  e.df   dedej.                  e.df   defdńZudej`                  dedefdƄZv	 dǄ ZwdȄ ZxdɄ ZyddʄZzdefd˄Z{defd̄Z|dedefd΄Z}dτ Z~dЄ Zdej`                  de1fdфZdej`                  de1fd҄Zdegdedegdej                  fdքZdegdedej                  fdׄZddede.dej                  fdڄZddegdede.dej                  fd܄Zdegdededej                  fdބZddej`                  de1de1defdZdddej`                  dedede.ddf
dZy# e$ r d dlZY w xY w# e$ r d dlZY w xY w# e$ r eez  ez  ZY w xY w(      N   )pymupdf)mupdf
point_like	rect_likematrix_like	quad_likeTpagereturnc	           
         t        | t        j                        sJ |st        d      t	        |      t        j
                  u r |dk(  r||j                  | |||       y|f}|d   j                  }	t        j                         }
|
j                  | j                  j                  | j                  j                        }|D ]%  }|	|j                  z  }	|j                  |||       ' ||	}| j                  ||
d||||	|       d}
d}y)a  Write the text of one or more pymupdf.TextWriter objects.

    Args:
        rect: target rectangle. If None, the union of the text writers is used.
        writers: one or more pymupdf.TextWriter objects.
        overlay: put in foreground or background.
        keep_proportion: maintain aspect ratio of rectangle sides.
        rotate: arbitrary rotation angle.
        oc: the xref of an optional content object
    z$need at least one pymupdf.TextWriterr   N)opacitycoloroverlaywidthheight)r   r   )r   keep_proportionrotateclipoc)
isinstancer   Page
ValueErrortype
TextWriter
write_text	text_rectDocumentnew_pagerectr   r   show_pdf_page)r
   r    writersr   r   r   r   r   r   r   textdoctpagewriters                O/var/www/html/Resume-Scraper/venv/lib/python3.12/site-packages/pymupdf/utils.pyr   r   6   s   * dGLL))?@@G}***Q;4<tWE7SjG1:D G499??499;K;KLE ?   %>? |	'  	 GE    c	           
      ,   dd}	t        j                  |        | j                  }
|
j                  r|j                  st	        d      |j
                  s|j                  rt	        d      |dk  r||j                  z  }|dk  r||   }|j                         g k(  rt	        d      || j                   z  }|s|j                  n|j                  |z  }|j
                  s|j                  rt	        d      ||j                   z  } |	||||      }|
j                  | j                        D cg c]  }|d   	 }}||
j                  | j                        D cg c]  }|d	   	 c}z  }||
j                  | j                        D cg c]  }|d
   	 c}z  }d}d}|dz   }||v r|dz  }|t        |      z   }||v r|j                   }|
j                   |k(  rt	        d      |
j"                  j%                  |d      }|$t        j&                  |
      }||
j"                  |<   ||f}|
j(                  j%                  |d      }|r| j+                          | j-                  ||||||||      }||
j(                  |<   |S c c}w c c}w c c}w )a@  Show page number 'pno' of PDF 'src' in rectangle 'rect'.

    Args:
        rect: (rect-like) where to place the source image
        src: (document) source PDF
        pno: (int) source page number
        keep_proportion: (bool) do not change width-height-ratio
        overlay: (bool) put in foreground
        oc: (xref) make visibility dependent on this OCG / OCMD (which must be defined in the target PDF)
        rotate: (int) degrees (multiple of 90)
        clip: (rect-like) part of source page rectangle
    Returns:
        xref of inserted object (for reuse)
    r   c           	      J   | j                   | j                  z   dz  }|j                   |j                  z   dz  }t        j                  dddd|j                   |j
                         t        j                  |      z  }| |z  }|j                  |j                  z  }|j                  |j                  z  }	|rt        ||	      x}}	|t        j                  ||	      z  }|t        j                  dddd|j                  |j
                        z  }t        j                  |      S )a8  Calculate transformation matrix from source to target rect.

        Notes:
            The product of four matrices in this sequence: (1) translate correct
            source corner to origin, (2) rotate, (3) scale, (4) translate to
            target's top-left corner.
        Args:
            sr: source rect in PDF (!) coordinate system
            tr: target rect in PDF coordinate system
            keep: whether to keep source ratio of width to height
            rotate: rotation angle in degrees
        Returns:
            Transformation matrix.
        g       @r   r   )
tlbrr   Matrixxyr   r   minJM_TUPLE)
srtrkeepr   smptmpmsr1fwfhs
             r&   calc_matrixz"show_pdf_page.<locals>.calc_matrix   s      uuruu}#uuruu}# NN1aAvv69OO1fXX		!YY#"bk!B	W^^B##	W^^Aq!Qsuu55""r'   	is no PDF!rect must be finite and not emptyz#nothing to show - source page emptyz!clip must be finite and not empty)r3   r   r         fzFrm0z%source document must not equal targetN)r   matrixxrefr   r   graftmap_imgname)Tr   )r   CheckParentparentis_pdfr   is_emptyis_infinite
page_countget_contentstransformation_matrixr    get_page_xobjectsnumberget_page_imagesget_page_fontsstr	_graft_id	GraftmapsgetGraftmap
ShownPageswrap_contents_show_pdf_page)r
   r    srcpnor   r   r   r   r   r:   docsrc_pagetar_rectsrc_rectrA   iilstnrD   isrcgmappno_idrB   s                          r&   r!   r!   j   s   2 #D 
++C::SZZ%%}}((<==
's~~ '3xH"$>??t1111H$(x}}hmmd.BHH00<==89999H8/&QF //<=QAaD=D=3..t{{;<aQqT<<D3--dkk:;aQqT;;D 	A	A3wH
d
	Qs1v: d
 ==D
}}@AA ==T4(D|$"d C[F>>fa(D  	D "CNN6KQ ><;s   2JJJ)filenamepixmapstreamrB   c                p   | j                   }|j                  |      st        d      t        |      t        |      z   t        |      z   dk7  rt        d      | j	                  | j
                  |||      }|j                  ||       | j                         d   }|j                  |d       d| _	        y)a  Replace the image referred to by xref.

    Replace the image by changing the object definition stored under xref. This
    will leave the pages appearance instructions intact, so the new image is
    being displayed with the same bbox, rotation etc.
    By providing a small fully transparent image, an effect as if the image had
    been deleted can be achieved.
    A typical use may include replacing large images by a smaller version,
    e.g. with a lower resolution or graylevel instead of colored.

    Args:
        xref: the xref of the image to replace.
        filename, pixmap, stream: exactly one of these must be provided. The
            meaning being the same as in Page.insert_image.
    zxref not an imager   z3Exactly one of filename/stream/pixmap must be given)re   rg   rf       N)
rF   xref_is_imager   boolinsert_imager    	xref_copyrK   update_stream_image_info)r
   rB   re   rf   rg   r[   new_xreflast_contents_xrefs           r&   replace_imagers      s      ++CT",--H~V$tF|3q8NOO  		HVF ! H MM(D!**,R0 ($/Dr'   c                     t        j                  t         j                  dd      }|j                          | j	                  ||       y)zDelete the image referred to by xef.

    Actually replaces by a small transparent Pixmap using method Page.replace_image.

    Args:
        xref: xref of the image to delete.
    )r   r   r   r   r   )rf   N)r   PixmapcsGRAY
clear_withrs   )r
   rB   pixs      r&   delete_imagery   	  s7     ..q
9CNNtC(r'   ri   )alphare   r   r   maskr   r   rf   r   rg   r   rB   c                   t        j                  |        | j                  }|j                  st	        d      |dk(  r1t        |      t        |      z   t        |	      z   dk7  rt	        d      |rNt        |      t        u rn<t        |d      rt        |      }n$t        |d      r|j                  }nt	        d      |r-t        j                  j                  |      st        d|z        |r1t        |      t        t        t         j"                  fvrt	        d	      |	r&t        |	      t         j$                  urt	        d
      |r|s|st	        d      |r1t        |      t        t        t         j"                  fvrt	        d      |
dk  r|
dz  }
|
dk  r|
dk\  r|
dz  }
|
dk\  r|
dvrt	        d      t        j&                  |      }|j(                  s|j*                  rt	        d      || j,                   z  }|j/                  | j0                        D cg c]  }|d   	 }}||j3                  | j0                        D cg c]  }|d   	 c}z  }||j5                  | j0                        D cg c]  }|d   	 c}z  }d}d}|dz   }||v r|dz  }|t        |      z   }||v r|r| j7                          |j8                  }| j;                  ||	|||||||
||||||      \  }}|||_        |S c c}w c c}w c c}w )a+  Insert an image for display in a rectangle.

    Args:
        rect: (rect_like) position of image on the page.
        alpha: (int, optional) set to 0 if image has no transparency.
        filename: (str, Path, file object) image filename.
        height: (int)
        keep_proportion: (bool) keep width / height ratio (default).
        mask: (bytes, optional) image consisting of alpha values to use.
        oc: (int) xref of OCG or OCMD to declare as Optional Content.
        overlay: (bool) put in foreground (default) or background.
        pixmap: (pymupdf.Pixmap) use this as image.
        rotate: (int) rotate by 0, 90, 180 or 270 degrees.
        stream: (bytes) use this as image.
        width: (int)
        xref: (int) use this as image.

    'page' and 'rect' are positional, all other parameters are keywords.

    If 'xref' is given, that image is used. Other input options are ignored.
    Else, exactly one of pixmap, stream or filename must be given.

    'alpha=0' for non-transparent images improves performance significantly.
    Affects stream and filename only.

    Optimum transparent insertions are possible by using filename / stream in
    conjunction with a 'mask' image of alpha values.

    Returns:
        xref (int) of inserted image. Re-use as argument for multiple insertions.
    r;   r   r   z4xref=0 needs exactly one of filename, pixmap, streamabsolutenamezbad filenamezNo such file: '%s'z#stream must be bytes-like / BytesIOzpixmap must be a pymupdf.Pixmapz mask requires stream or filenamez!mask must be bytes-like / BytesIOh  )r   Z        bad rotate valuer<   r=   r>   fzImgr@   )re   rf   rg   imaskr   r   r   rB   r   r   r   r   rz   rD   digests)r   rE   rF   rG   r   rl   r   rQ   hasattrr~   ospathexistsFileNotFoundErrorbytes	bytearrayioBytesIOru   RectrH   rI   rL   rO   rN   rM   rP   rW   InsertedImages_insert_image)r
   r    rz   re   r   r   r{   r   r   rf   r   rg   r   rB   r[   rr   r_   r`   ra   rD   r   s                         r&   rm   rm     s   ` 
++C::%%qyd8ntF|3d6lBaGOPP>S Xz*8}HXv&}}H^,,x0 4x ?@@	DL	2::(FF>??	DL6:;;Vx;<<T
5)RZZ"@@<==
1*# 1*
C-# C-&&+,,TAzzQ]]<==****D --dkk:;QAaD;D;300=>aQqT>>D3--dkk:;aQqT;;DA	A3wH
d
	Qs1v: d
   G&&' ' MD'" $KC <>;s   !K>L<LF)r   quadsflagstextpagec                    |t        j                  |      }t        j                  |        |}|| j                  ||      }nt	        |d      | k7  rt        d      |j                  ||      }|~|S )a~  Search for a string on a page.

    Args:
        text: string to be searched for
        clip: restrict search to this rectangle
        quads: (bool) return quads instead of rectangles
        flags: bit switches, default: join hyphened words
        textpage: a pre-created pymupdf.TextPage
    Returns:
        a list of rectangles or quads, each containing one occurrence.
    r   r   rF   not a textpage of this page)r   )r   r   rE   get_textpagegetattrr   search)r
   textr   r   r   r   tprlists           r&   
search_forr     s    0 ||D!	B	zD6	X	$	&677IId%I(ELr'   r[   rZ   r   r   r   r   r   c                 4    | |   j                  |||||      S )a  Search for a string on a page.

    Args:
        pno: page number
        text: string to be searched for
        clip: restrict search to this rectangle
        quads: (bool) return quads instead of rectangles
        flags: bit switches, default: join hyphened words
        textpage: reuse a prepared textpage
    Returns:
        a list of rectangles or quads, each containing an occurrence.
    )r   r   r   r   )r   )r[   rZ   r   r   r   r   r   s          r&   search_page_forr     s/    4 s8   r'   sortc                    t        j                  |        |t         j                  }|}|| j                  ||      }nt	        |d      | k7  rt        d      |j                         }|~|r|j                  d        |S )a_  Return the text blocks on a page.

    Notes:
        Lines in a block are concatenated with line breaks.
    Args:
        flags: (int) control the amount of data parsed into the textpage.
    Returns:
        A list of the blocks. Each item contains the containing rectangle
        coordinates, text lines, running block number and block type.
    r   rF   r   c                     | d   | d   fS N   r    )bs    r&   <lambda>z!get_text_blocks.<locals>.<lambda>  s    1Q41, r'   key)r   rE   TEXTFLAGS_BLOCKSr   r   r   extractBLOCKSr   )r
   r   r   r   r   r   blockss          r&   get_text_blocksr     s    " }((	B	zD6	X	$	&677F./Mr'   c                    fd}t        j                  |        |t         j                  }|}|| j                  ||      }nt	        |d      | k7  rt        d      |j                  |      }	|]|[t        j                  |      }|	D 
cg c];  }
t        ||
dd z        dt        t        j                  |
dd             z  k\  s:|
= }	}
|~|	r
|r ||	      }	|	S c c}
w )a  Return the text words as a list with the bbox for each word.

    Args:
        page: pymupdf.Page
        clip: (rect-like) area on page to consider
        flags: (int) control the amount of data parsed into the textpage.
        textpage: (pymupdf.TextPage) either passed-in or None.
        sort: (bool) sort the words in reading sequence.
        delimiters: (str,list) characters to use as word delimiters.
        tolerance: (float) consider words to be part of the same line if
            top or bottom coordinate are not larger than this. Relevant
            only if sort=True.

    Returns:
        Word tuples (x0, y0, x1, y1, "word", bno, lno, wno).
    c                    | j                  d        g }| d   g}t        j                  | d   dd       }| dd D ]  }t        j                  |dd       }t        |j                  |j                  z
        k  s%t        |j
                  |j
                  z
        k  r|j                  |       ||z  }||j                  d        |j                  |       |g}|} |j                  d        |j                  |       |S )	z1Sort words line-wise, forgiving small deviations.c                     | d   | d   fS r   r   ws    r&   r   z4get_text_words.<locals>.sort_words.<locals>.<lambda>  s    !A$! r'   r   r   Nr>   r   c                     | d   S Nr   r   r   s    r&   r   z4get_text_words.<locals>.sort_words.<locals>.<lambda>)  s
    ! r'   c                     | d   S r   r   r   s    r&   r   z4get_text_words.<locals>.sort_words.<locals>.<lambda>.  s
    ! r'   )r   r   r   absy0y1appendextend)wordsnwordslinelrectr   wrect	tolerances         r&   
sort_wordsz"get_text_words.<locals>.sort_words  s    

-
.azU1Xbq\*qr 	ALL2A'EEHHuxx'(I5uxx%((*+y8A		n	-d#s	 			n	%dr'   Nr   rF   r   r>         ?)	r   rE   TEXTFLAGS_WORDSr   r   r   extractWORDSr   r   )r
   r   r   r   r   
delimitersr   r   r   r   r   s         `    r&   get_text_wordsr      s    42 }''	B	zD6	X	$	&677OOJ'E  0||D!
D1Ra5L 1S3w||AbqE?R;S5S SA
 
 5!L
s   ;C!
C!c           	      ~   d }t        | |||d|      D cg c]  }t        j                  |dd       |d   f! }}|syt        j                         }|D ]
  \  }	}
||	z  } g }|d   g}|d   d   }|dd D ]  \  }	}
|d	   \  }}t	        |j
                  |	j
                  z
        |k  s%t	        |j                  |	j                  z
        |k  r|j                  |	|
f       ||	z  }q |||      }|j                  ||f       |	|
fg}|	}  |||      }|j                  ||f       |j                  d
        |d   d   }
|d   d   j                  }|dd D ]Y  \  }}t        t        t        |j
                  |z
  |j                  z              d      }d|dz   z  }|
||z   z  }
|j                  }[ |
S c c}w )a  Extract plain text avoiding unacceptable line breaks.

    Text contained in clip will be sorted in reading sequence. Some effort
    is also spent to simulate layout vertically and horizontally.

    Args:
        page: pymupdf.Page
        clip: (rect-like) only consider text inside
        flags: (int) text extraction flags
        textpage: pymupdf.TextPage
        tolerance: (float) consider words to be on the same line if their top
            or bottom coordinates do not differ more than this.

    Notes:
        If a TextPage is provided, all text is checked for being inside clip
        with at least 50% of its bbox.
        This allows to use some "global" TextPage in conjunction with sub-
        selecting words in parts of the defined TextPage rectangle.

    Returns:
        A text string in reading sequence. Left indentation of each line,
        inter-line and inter-word distances strive to reflect the layout.
    c                    |j                  d        d}| j                  }t        j                         }|D ]  \  }}||z  }t	        t        t        |j                  |z
  |j                  z  t        |      z              || j                  k(  s|j                  |k  rdnd      }|d|z  |z   z  }|j                  } |S )a  Create the string of one text line.

        We are trying to simulate some horizontal layout here, too.

        Args:
            clip: (pymupdf.Rect) the area from which all text is being read.
            line: (list) word tuples (rect, text) contained in the line
        Returns:
            Text in this line. Generated from words in 'line'. Distance from
            predecessor is translated to multiple spaces, thus simulating
            text indentations and large horizontal distances.
        c                      | d   j                   S r   )x0r   s    r&   r   z4get_sorted_text.<locals>.line_text.<locals>.<lambda>{  s    ! r'   r    r   r    )
r   r   r   
EMPTY_RECTmaxintroundr   lenx1)r   r   ltextr   r   r   tdists           r&   	line_textz"get_sorted_text.<locals>.line_textn  s     			'	(WW""$ 		DAqQJEE144"9/#a&89:DGGmqttrzD
 S4Z!^#EB		 r'   T)r   r   r   r   r   Nr>   r   r   r   ri   c                      | d   j                   S r   )r   )ls    r&   r   z!get_sorted_text.<locals>.<lambda>  s    adgg r'   r      
)r   r   r   r   r   r   r   r   r   r/   r   r   r   )r
   r   r   r   r   r   r   r   totalboxwrr   linesr   r   w0r_r   r   distancebreakss                       r&   get_sorted_textr   O  s
   >@  

 
ae	ad#
E 
 !!#H DB E!H:D!HQKE !"I DbQ uxx"%% I-UXX5E1F)1SKKT
#RKE h-ELL%(J<DE h%E	LL%  
JJ&J'8A;D	q!Bab	 us5%((R-5<<!?@A1EA&XX	 Kk
s   $F:r    c                     |}|| j                         }nt        |d      | k7  rt        d      |j                  |      }|~|S )NrF   r   )r   r   r   extractTextbox)r
   r    r   r   rcs        r&   get_textboxr     sU    
 
B	z 	X	$	&677			4	 BIr'   p1p2c                     t        j                  |        |}|"| j                  |t         j                        }nt	        |d      | k7  rt        d      |j                  ||      }|~|S )Nr   rF   r   )r   rE   r   TEXT_DEHYPHENATEr   r   extractSelection)r
   r   r   r   r   r   r   s          r&   get_text_selectionr     sr     	B	zD0H0HI	X	$	&677			R	$BIr'   languagedpifulltessdatac                 <   t        j                  |        t        j                        fd}|r || |||      S | j                  |      }| j	                  dt         j
                        d   D ]`  }|d   dk7  rt        j                  |d         }	|	j                  dk  s|	j                  dk  rD	 t        j                  |d	         }
|
j                  |
j                  z
  dk7  r$t        j                  t         j                  |
      }
|
j                  rt        j                  |
d
      }
t        j                  d|
j                  |            }|j                  d
      }d}
|j                   }t        j"                  d|j                  z  d|j                  z        }||d   z  }|j%                  |d
|       |j'                          c |S # t(        t*        j,                  f$ r( 	 d}t        j2                  d        || |||      cY c S w xY w)as  Create a Textpage from combined results of normal and OCR text parsing.

    Args:
        flags: (int) control content becoming part of the result.
        language: (str) specify expected language(s). Default is "eng" (English).
        dpi: (int) resolution in dpi, default 72.
        full: (bool) whether to OCR the full page image, or only its images (default)
    c                    |dz  }t        j                  ||      }| j                  |      }t        j                  d|j	                  d|            }|j                  d      }| j                  j                  |j                  j                  z  }	t        j                  |	|	      | j                  z  }
|j                  ||
      }|j                          d }t        j                  |       |_        |S )NH   )rA   pdfF)compressr   r   r   r   rA   )r   r,   
get_pixmapr   pdfocr_tobytes	load_pager    r   derotation_matrixr   closeweakrefproxyrF   )r
   r   r   r   zoommatrx   ocr_pdfocr_pageunzoomctmr$   r   s               r&   full_ocrz"get_textpage_ocr.<locals>.full_ocr  s    RxnnT4(ooSo)"""""%% #  $$Q'8==#6#66nnVV,t/E/EE%%E#%>}}T*r'   r   dictr   r   r   bboxr   imager   r   )r   r   N	transformr   zFalling back to full page OCR)r   rE   get_tessdatar   get_textTEXT_PRESERVE_IMAGESr   r   r   ru   ra   rz   csRGBr   r   r   r    r,   extend_textpager   RuntimeErrorr   FzErrorBaseg_exceptions_verboseexception_infomessage)r
   r   r   r   r   r   r  r$   blockr
  rx   imgdocimgpageimgrectshrinkr  s        `          r&   get_textpage_ocrr    s     ##H-H, c8U33
 E*EvW-I-IJ8T 8=A||E&M*::?dkkQ.	8..w0Cuusyy A%nnW]]C8yynnS!,%%&&8&LF &&q)GCllG^^A$5q7>>7IJF5--C##E3#?LLN/8B L e//0 	8 EOO;<D#x77	8s   9DG<HHhashesxrefsc                    | j                   }|r|j                  rd}|j                  sd}t        | dd      }|r|s|S |s<| j                  t        j
                        }|j                  |      }~|r|| _        |r|j                  s|S | j                         }i }|D ]-  }|d   }	t	        j                  ||	      }
|	||
j                  <   ~
/ t        t        |            D ]&  }||   }|j                  |d   d      }	|	|d	<   |||<   ( |S )
zExtract image information only from a pymupdf.TextPage.

    Args:
        hashes: (bool) include MD5 hash for each image.
        xrefs: (bool) try to find the xref for each image. Sets hashes to true.
    TFrp   Nr  r  r   digestrB   )rF   rG   r   r   r   r  extractIMGINFOrp   
get_imagesru   r!  ranger   rT   )r
   r  r  r[   imginfor   imglistr   itemrB   rx   r_   s               r&   get_image_infor(  ;  s$    ++C::dM40GuW%A%AB##6#2&D

ooGG AwnnS$'"

	
 3w<  qz{{4>1-V
	
 Nr'   c                    t        |      t        t        fv r|d   }nkt        |      t        u r|}nW| j	                         D cg c]  }|d   |k(  s| }}|g k(  rt        d      t        |      dk7  rt        d      |d   d   }t        j                  | j                  |      }|j                  }~| j                  d      }|s0|D 	cg c]#  }	|	d   |k(  st        j                  |	d	         % }
}	|
S |D 	cg c]:  }	|	d   |k(  r0t        j                  |	d	         t        j                  |	d
         f< }
}	|
S c c}w c c}	w c c}	w )a  Return list of image positions on a page.

    Args:
        name: (str, list, int) image identification. May be reference name, an
              item of the page's image list or an xref.
        transform: (bool) whether to also return the transformation matrix.
    Returns:
        A list of pymupdf.Rect objects or tuples of (pymupdf.Rect, pymupdf.Matrix)
        for all image locations on the page.
    r   r=   zbad image namer   zmultiple image names foundTr   r!  r
  r  )r   listtupler   r#  r   r   r   ru   rF   r!  r(  r   r,   )r
   r~   r  rB   r_   r&  rx   r!  infosimbboxess              r&   get_image_rectsr/  a  sT    DzdE]"Aw	ds	"oo/@1Q44<1@@b=-..\Q9::qz!}
..d
+CZZFt,E5:Urblf>T',,r&z*UU M 
(|v% \\"V*%w~~bo'FG
 

 M% A V
s   EEEE>?Eoptionc                    t         j                  t         j                  t         j                  t         j                  t         j
                  t         j                  t         j                  t         j                  t         j                  t         j                  d
}|j                         }||v sJ ||vrd}|||   }|dk(  rt        | |||||      S |dk(  rt        | ||||      S |dk(  r|rt        | ||||      S t        j                  |        d}	|d	v r| j                  }|t        j                  |      }d}	n't!        |       t         j"                  u r| j                  }	|}
|
| j%                  ||
      }
nt'        |
d      | k7  rt)        d      |dk(  r|
j+                  |	|      }n|dk(  r|
j-                  |	|      }n|dk(  r|
j/                  |	|      }nm|dk(  r|
j1                  |	|      }nT|dk(  r|
j3                         }n>|dk(  r|
j5                         }n(|dk(  r|
j7                         }n|
j9                  |      }|~
|S )a  Extract text from a page or an annotation.

    This is a unifying wrapper for various methods of the pymupdf.TextPage class.

    Args:
        option: (str) text, words, blocks, html, dict, json, rawdict, xhtml or xml.
        clip: (rect-like) restrict output to this area.
        flags: bit switches to e.g. exclude images or decompose ligatures.
        textpage: reuse this pymupdf.TextPage and make no new one. If specified,
            'flags' and 'clip' are ignored.

    Returns:
        the output of methods get_text_words / get_text_blocks or pymupdf.TextPage
        methods extractText, extractHTML, extractDICT, extractJSON, extractRAWDICT,
        extractXHTML or etractXML respectively.
        Default and misspelling choice is "text".
    )
r   htmljsonrawjsonxmlxhtmlr	  rawdictr   r   r   Nr   )r   r   r   r   r   r   )r   r   r   r   )r   r   r   r   )r2  r5  r6  r   rF   r   r3  )cbr   r4  r	  r7  r2  r5  r6  )r   )r   TEXTFLAGS_TEXTTEXTFLAGS_HTMLTEXTFLAGS_DICTTEXTFLAGS_RAWDICTTEXTFLAGS_XMLTEXTFLAGS_XHTMLr   r   lowerr   r   r   rE   cropboxr   r   r   r   r   r   extractJSONextractRAWJSONextractDICTextractRAWDICTextractHTML
extractXMLextractXHTMLextractText)r
   r0  r   r   r   r   r   r   formatsr8  r   r   s               r&   r  r    sb   8 &&&&&&,,$$((&&,,((**G \\^FWW}!
 	
 t58$
 	
 D
 	
 	B))||||D!	dw||	#\\	B	zD6	X	$	&677NNbtN,	9	$/	6	NNbtN,	9	$/	6	NN	5MMO	7	OONNN%Hr'   c                 2    | |   j                  ||||      S )a  Extract a document page's text by page number.

    Notes:
        Convenience function calling page.get_text().
    Args:
        pno: page number
        option: (str) text, words, blocks, html, dict, json, rawdict, xhtml or xml.
    Returns:
        output from page.TextPage().
    )r   r   r   )r  )r[   rZ   r0  r   r   r   r   s          r&   get_page_textrK    s"    & s8V$e$GGr'   rA   r   
colorspacer   rz   annotsrA   rM  rz   rN  c                   |r|dz  }t        j                  ||      }t        |      t        u rX|j	                         dk(  rt         j
                  }n4|j	                         dk(  rt         j                  }nt         j                  }|j                  dvrt        d      | j                  |      }|j                  ||||      }	d}|r|	j                  ||       |	S )	a  Create pixmap of page.

    Keyword args:
        matrix: Matrix for transformation (default: Identity).
        dpi: desired dots per inch. If given, matrix is ignored.
        colorspace: (str/Colorspace) cmyk, rgb, gray - case ignored, default csRGB.
        clip: (irect-like) restrict rendering to this area.
        alpha: (bool) whether to include alpha channel
        annots: (bool) whether to also render annotations
    r   GRAYCMYK)r   r   r>   zunsupported colorspace)rN  )rA   rM  rz   r   N)r   r,   r   rQ   upperrv   csCMYKr  ra   r   get_displaylistr   set_dpi)
r
   rA   r   rM  r   rz   rN  r  dlrx   s
             r&   r   r     s    ( Rxd+J3' J6) J J||9$122			V		,B
--v*EPT-
UC	B
CJr'   c                6    | |   j                  ||||||      S )a  Create pixmap of document page by page number.

    Notes:
        Convenience function calling page.get_pixmap.
    Args:
        pno: (int) page number
        matrix: pymupdf.Matrix for transformation (default: pymupdf.Identity).
        colorspace: (str,pymupdf.Colorspace) rgb, rgb, gray - case ignored, default csRGB.
        clip: (irect-like) restrict rendering to this area.
        alpha: (bool) include alpha channel
        annots: (bool) also render annotations
    rL  )r   )r[   rZ   rA   r   rM  r   rz   rN  s           r&   get_page_pixmaprX  1  s1    . s8
   r'   c                    t        | t        j                        r| j                  |      }n;t        | t        j                        r| j
                  }nJ dt        |       d       |j                  dd}	 t        | d      r| j                  |d<   t        j                  dd      }|j                  t        j                  z  r|j                   j"                  |_        |j                  t        j$                  z  r|j                   j&                  |_        |j                  t        j(                  k(  r|j*                  |d<   |S |j                  t        j,                  k(  rS|j.                  |d	<   ||d
<   |j                  t        j0                  z  r|j2                  j"                  |d<   |S d|d<   |S |j                  t        j4                  k(  r|j6                  j9                  dd      |d<   |j.                  |d	<   |j.                  dk  r|j
                  |d
<   |S ||d
<   |j                  t        j0                  z  r|j2                  j"                  |d<   |S d|d<   |S |j                  t        j:                  k(  r!|j6                  j9                  dd      |d<   |S |j                  t        j<                  k(  ri|j>                  jA                         |jA                         z  rJ |jC                  |j>                         d
|v rt        j                  |d
         |d
<   |S |j.                  |d	<   |S # t        $ r! t        dk\  rt        j                          Y w xY w)Nr   zUnexpected type(ln)=.)kindrB   r    from   urir
   tor  g        \/file)"r   r   OutlinedestinationLinkdestr   r[  r   r    	Exceptionr  r  Pointr   LINK_FLAG_L_VALIDltr-   LINK_FLAG_T_VALIDr.   LINK_URIr^  	LINK_GOTOr
   LINK_FLAG_R_IS_ZOOMrb
LINK_GOTOR	file_specreplaceLINK_LAUNCH
LINK_NAMEDnamedkeysupdate)lndocumentrf  nlpnts        r&   getLinkDictr|  Q  s   "goo&~~h'	B	%ww,)R{!,,))Q	'B2vBvJ
 --1
CzzG---		zzG---		yyG$$$HH5	D IA 
g''	'YY6
4::333BvJ8 I5 BvJ4 I1 
g((	(^^++D#66
YY6
99q=yyBtH( I% BtHzzG777!WWYY6
  I !6
 I 
g))	)^^++D#66
 I 
g((	(JJOO%	12
		$**2:}}RX.BtH I YY6
I[  1$(>(>(@s   8L; ;&M%$M%c                    t        j                  |        | j                  }g }|r6t        || j                        }|j                  |       |j                  }|r6|g k7  r| j                  j                  rt        j                  |       D cg c]  }|d   t         j                  k(  r| }}t        |      t        |      k(  r5t        t        |            D ]  }||   d   ||   d<   ||   d   ||   d<     |S c c}w )zrCreate a list of all links contained in a PDF page.

    Notes:
        see PyMuPDF ducmentation for details.
    r   r   rB   r]  id)r   rE   
first_linkr|  rF   r   nextrG   JM_get_annot_xref_list2PDF_ANNOT_LINKr   r$  )r
   rx  linksrz  r-   	linkxrefsr_   s          r&   	get_linksr    s     	BE
T[[)RWW  {t{{)) //51 Q47111  	 
 y>SZ'3y>* 1#,Q<?a !*1aa1 Ls   C=simplec                       fd j                   rt        d       j                           j                  }|sg S d}g } |||      } j                  rs j                  |       |S )zCreate a table of contents.

    Args:
        simple: a bool to control output. Returns a list, where each entry consists of outline level, title, page number and link destination (if simple = False). For details see PyMuPDF's documentation.
    c                 0   | r| j                   j                  r| j                  r| j                  }nd}| j                  sR| j                  rC| j
                  dk(  r$j                  | j                        }|d   dz   }n| j
                  dz   }nd}nd}	s"t        |       }|j                  ||||g       n|j                  |||g       | j                  r | j                  ||dz         }| j                  } | r| j                   j                  r|S )zPRecursively follow the outline item chain and record item information in a list.r   ri   r   r   )this
m_internaltitleis_externalr^  r
   resolve_linkr|  r   downr  )
olItemlistelvlr  resolver
   linkr[   recurser  s
          r&   r  zget_toc.<locals>.recurse  s    //||%%::{{b("%"2"26::">&qzA~%{{QD"63/c5$56c5$/0{{UC!G<[[F5 //6 r'   document closedr   )	is_closedr   init_docoutlinerG   _extend_toc_items)r[   r  r  r  r  tocr  s   ``    @r&   get_tocr    sl    @ }}*++LLN[[F	
CE
&%
%C
zz&c"Jr'   idxc                 L    | j                         |   }| j                  |       y)z$Delete TOC / bookmark item by index.N)get_outline_xrefs_remove_toc_item)r[   r  rB   s      r&   del_toc_itemr    s%    
   "3'Dr'   	dest_dictr[  r^  r  r_  re   r  c
                    | j                         |   }
d}t        |      t        u rf|d   t        j                  k(  rp|d   }| j                  |      }| j                  |      j                  }|j                  dt        j                  dd            }||j                  z
  |_
        ||d<   t        ||      }|j                  d      st        d      |j                  d	      }|rNt        t        t         |            }t#        |      d
k7  st%        |      dk  st'        |      dkD  rt        d      |j                  dd      }|j                  dd      }|d|z  z   }|j                  d      }| j)                  |
|dd ||||      S |t        j*                  k(  r| j-                  |      S ||y|| j)                  |
d|      S |t        j                  k(  r||t/        d| j0                  dz         vrt        d      | j                  |dz
        }| j                  |dz
        j                  }|t        j                  d|dz
        }n)t        j                  |      }||j                  z
  |_
        ||||||	d}t        ||      }|dk(  s|j                  d      st        d      | j)                  |
|dd |      S )a  Update TOC item by index.

    It allows changing the item's title and link destination.

    Args:
        idx:
            (int) desired index of the TOC list, as created by get_toc.
        dest_dict:
            (dict) destination dictionary as created by get_toc(False).
            Outrules all other parameters. If None, the remaining parameters
            are used to make a dest dictionary.
        kind:
            (int) kind of link (pymupdf.LINK_GOTO, etc.). If None, then only
            the title will be updated. If pymupdf.LINK_NONE, the TOC item will
            be deleted.
        pno:
            (int) page number (1-based like in get_toc). Required if
            pymupdf.LINK_GOTO.
        uri:
            (str) the URL, required if pymupdf.LINK_URI.
        title:
            (str) the new title. No change if None.
        to:
            (point-like) destination on the target page. If omitted, (72, 36)
            will be used as target coordinates.
        filename:
            (str) destination filename, required for pymupdf.LINK_GOTOR and
            pymupdf.LINK_LAUNCH.
        name:
            (str) a destination name for pymupdf.LINK_NAMED.
        zoom:
            (float) a zoom factor for the target location (pymupdf.LINK_GOTO).
    r   r[  r
   r_  r   $   z/Azbad bookmark destr   r   r   zbad color valueboldFitalicr]  collapseN)actionr  r   r   r  )r  r  zbad page number)r[  r_  r^  r
   rb  r  r   )r  r   r	  r   rm  	page_xrefpage_cropboxr   rT   rh  r.   
getDestStr
startswithr   r*  mapfloatr   r/   r   _update_toc_item	LINK_NONEr  r$  rJ   )r[   r  r  r[  rZ   r^  r  r_  re   r  rB   r  page_heightr  r   r  r  r   r  ddicts                       r&   set_toc_itemr    s   Z   "3'DII$V 1 11F#Cc*I**3/66KtW]]2r%:;B%BD IdOIy1  &011g&UE*+E5zQ#e*q.CJN !233}}VU+x/T!==,##!": $ 
 	
 w   $$||##DU#CCw   ;#U1cnnq.@%AA.//MM#'*	&&sQw/66:r;#34Br"B%BD E 	5)F|6,,T2,--VABZuEEr'   c                      | d   }t        |       dkD  r| d   }nd}ddddd}||   d   ||   d   z  d	z  }||j                  z  |j                  z  S )
zUCalculate area of rectangle.
parameter is one of 'px' (default), 'in', 'cm', or 'mm'.r   r   px)r   r   )      ?      R@)gRQ@r  )gffffff9@r  )r  incmmmr]  )r   r   r   )argsr    unitufs        r&   get_arear  T  sh    7D
4y1}Aw[LQA	
4agaj	 Q&Atzz>DKK''r'   r6   c                    | j                   st        d      | j                  s| j                  rt        d      |i }nt	        |      t
        urt        d      ddddddd	d
dddd}t        |j                               }t        |j                               j                  |      }|t               k7  rd|z  }t        |      | j                  dd      \  }}|dk7  rd}nt        |j                  dd            }|i k(  r|dk(  ry|dk(  r9| j                         }| j                  |d       | j                  ddd|z         n)|i k(  r$| j                  ddd       | j                          y|j!                         D 	
cg c]  \  }	}
||	   |	|
f c}
}	D ]D  \  }}||   }t#        |      r|dv rd}nt%        j&                  |      }| j                  |||       F | j                          yc c}
}	w )zWUpdate the PDF /Info object.

    Args:
        m: a dictionary like doc.metadata.
    r;   document closed or encryptedNzbad metadataAuthorProducerCreatorTitleCreationDateModDateSubjectKeywordsTrapped)authorproducercreatorr  format
encryptioncreationDatemodDatesubjectkeywordstrappedzbad dict key(s): %sri   InforB   r   0 Rr   <<>>%i 0 Rnull)noner  )rG   r   r  is_encryptedr   r	  setrv  
differencexref_get_keyr   rr  get_new_xrefupdate_objectxref_set_keyr  itemsrl   r   get_pdf_str)r[   r6   keymap
valid_keysdiff_setmsgr   temp	info_xrefkvr   valpdf_keys                 r&   set_metadatar  `  s    ::%%
}}((788y	a	((&F V[[]#J1668}''
3H35#h.or6*GAtF{	UB/0	Bw9>A~$$&	)V,VX	%9:	
bVV,()	K1VAY5JaVK 2S+CyC#33C%%c*CGS12 LLN
 Ls   G5G5r  c                    |syd }d }d }d }d }t        |      t        t        fv r || d|d      }|S |j                  dt        j
                        }|t        j
                  k(  ry|d   t        j                  k(  rJ|j                  d	d      }	|j                  d
t	        j                  dd            }
|
\  }} || |||	      }|S |d   t        j                  k(  r  |t	        j                  |d               }|S |d   t        j                  k(  r#t	        j                  |d         } |||      }|S |d   t        j                  k(  rB|d   dk  r:t	        j                  |d         } |t	        j                  |d
         ||      }|S |d   t        j                  k(  rO|d   dk\  rGt	        j                  |d         } ||d   |d
   j                  |d
   j                  |d	   ||      }|S y)zrCalculate the PDF action string.

    Notes:
        Supports Link annotations and outline items (bookmarks).
    r   c                 ,    d|  dt        |||f       dS )Nz/A<</S/GoTo/D[z	 0 R/XYZ z]>>	_format_gar   cds       r&   r   zgetDestStr.<locals>.<lambda>  s#    N1#Yy!QPQ?S>TTW"X r'   c           	      8    d|  dt        |||f       d| d| d	S )Nz/A<</S/GoToR/D[z /XYZ z]/F<</F/UF/Type/Filespec>>>>r  r  r   r  r  er  s         r&   r   zgetDestStr.<locals>.<lambda>  s7    OA3fYPQSTVWyEYDZZabcaddghigjj|*} r'   c                     d|  d| d| dS )Nz/A<</S/GoToR/Dz/F<</Fr  r  r   )r  r   r  s      r&   r   zgetDestStr.<locals>.<lambda>  s    >!F1#SCU!V r'   c                     d|  d| dS )Nz/A<</S/Launch/F<</Fr  r  r   r  r   s     r&   r   zgetDestStr.<locals>.<lambda>  s     3A3c!<NO r'   c                     d|  dS )Nz/A<</S/URI/URI>>r   r  s    r&   r   zgetDestStr.<locals>.<lambda>  s    .2. r'   r   r[  r  r_  r^  rb  r
   )r   r   r  rT   r   r  rm  rh  rl  r  rs  rp  r-   r.   )rB   r  str_goto
str_gotor1
str_gotor2
str_launchstr_urirf  d_kindd_zoomr_  d_leftd_topfspecs                 r&   r  r    s    XH}JVJOJ.GE{sEl"a*YYvw001F"""V})))61%YYtW]]1a01feV4V}(((w**5<8:V}+++##E&M2%'V}***uV}q/@##E&M2'--eDk:E5IV}***uV}/A##E&M2&M$KMM$KMM&M
 r'   r  r  c           	         | j                   s| j                  rt        d      | j                  st        d      |st	        | j                               S t        |      t        t        fvrt        d      t	        |      }| j                  }|d   }t        |      t        t        fvrt        d      |d   dk7  rt        d      t        t        |dz
              D ]  }||   }||dz      }d|d	   cxk  r|k  sn t        d
|z        t        |      t        t        fvst	        |      dvrt        d|dz   z        t        |d         t        us|d   dk  rt        d|dz   z        |d   |d   dz   kD  st        d|dz   z         | j                         }	g }	dg|	z   }
| j                         |
d<   |t	        |	      kD  r;t        |t	        |	      z
        D ]!  }|
j                  | j                                # ddi}ddd|
d   dg}t        |      D ]  }||   }|d   }t        j                   |d         }t#        | j                  dz
  t%        d|d	   dz
              }| j'                  |      }| j)                  |      j*                  }t        j,                  d|dz
        }|t        j.                  d}|d	   dk  rt        j0                  |d<   t	        |      dkD  rt        |d         t        t2        fv r t        j,                  d||d   z
        |d<   nt        |d         t4        u r|d   j7                         n|}d|vr||d<   no| |   }t        j,                  |d         }|j8                  j*                  |j:                  z
  |_        ||j<                  z  }|j>                  |j:                  f|d<   i }d|d<   d|d<   d|d<   d|d<   d|d<   tA        ||      |d<   |d   |d<   ||d<   ||dz
     |d<   |
|dz      |d<   |jC                  d      |d<   |jC                  d d      d	|jC                  d!d      z  z   |d"<   |dz   ||<   |||dz
        }|jC                  d#      s|r||kD  r|dxx   dz  cc<   n|dxx   dz  cc<   |d   dk(  r|dz   |d<   |dz   |d<   n |d   |d<   ||d      }|dz   |d<   |dz   |d<   |j                  |        tE        |      D ]'  \  }}d$}|d   dk7  r|d%|d   z  z  }	 ||d   z  }	 |d   dkD  r|d&|
|d      z  z  }	 |d   dkD  r|d'|
|d      z  z  }	 |d   dkD  r|d(|
|d      z  z  }	 |d   dkD  r|d)|
|d      z  z  }	 |d   dkD  r|d*|
|d      z  z  }	 |d+|d   z   z  }|jC                  d      r/t	        |d         dk(  r|d,tM        t        |d                d-z  }|jC                  d"d      dkD  r|d.|d"   z  z  }|dk(  r|d/z  }|d0z  }| jO                  |
|   |       * | jQ                          |S # tF        $ r! tH        d	k\  rt        jJ                          Y Aw xY w# tF        $ r! tH        d	k\  rt        jJ                          Y Ww xY w# tF        $ r! tH        d	k\  rt        jJ                          Y mw xY w# tF        $ r! tH        d	k\  rt        jJ                          Y w xY w# tF        $ r! tH        d	k\  rt        jJ                          Y w xY w# tF        $ r! tH        d	k\  rt        jJ                          Y w xY w# tF        $ r! tH        d	k\  rt        jJ                          Y w xY w)1a  Create new outline tree (table of contents, TOC).

    Args:
        toc: (list, tuple) each entry must contain level, title, page and
            optionally top margin on the page. None or '()' remove the TOC.
        collapse: (int) collapses entries beyond this level. Zero or None
            shows all entries unfolded.
    Returns:
        the number of inserted items, or the number of removed items respectively.
    r  r;   z'toc' must be list or tupler   z'items must be sequences of 3 or 4 itemsr   z#hierarchy level of item 0 must be 1ri   r]  z row %i: page number out of range)r   r>   z
bad row %izbad hierarchy level in row %i)countfirstlastrB   r   r  )r_  r[  r[  r   r_  r  r  r  prevr  rf  topr  rF   rB   r   r  r  r   r  z<<z	/Count %iz/First %i 0 Rz/Last %i 0 Rz/Next %i 0 Rz/Parent %i 0 Rz/Prev %i 0 Rz/Titlez/C[ ]z/F %iz/Type/Outlinesr  ))r  r  r   rG   r   _delToCr   r*  r+  rJ   r$  r   _getOLRootNumberr   r  r   r  r/   r   r  r  r   rh  rm  r  r  r	  copyr@  r.   rotation_matrixr-   r  rT   	enumeraterg  r  r  r  r  r  )r[   r  r  toclenrJ   t0r_   t1t2	old_xrefsrB   lvltabolitemsor  r  rZ   r  r  r  r  r
   pointr  rF   r  oltxts                               r&   set_tocr"    s    }}((788::%%3;;=!! Cyu%677XFJ	QBBxe}$BCC	!uz>??%
#$ 
HVQZRU(j(?!CDDHT5M)c"gV.C\QU344AKs"r!uqy<AFGGa52a519<AFGG
H  I I3?D""$DGIY/1 	,AKK((*+	, VF
 RT!WEFG 6] 8Fd##AaD)#..1$c!QqTAX&67MM#&	&&s+22mmBb 01(9(9:	Q4!8 ' 1 1Ifq6A:AaDzc5\)")--K!A$4F"G	$ ,0!:+=AaDIIK9	y(&)IdOs8D#MM)D/:E"ll11EGG;EG!D$8$88E',ww&8IdO'
'
&	&	&	y)4&	T?%'
S1Wo(QK&	]]7+'
]]8Q/!immFA6N2NN'
!esa) MM*%cHn7Oq O7Oq O'?b !eF7OUF6NvAfI6&>*Dq5DLUF6Nqq8z 7# :(2g;!;G,,C	2f:C
	'{Rbk):::	&zB~RZ(888	&zB~RZ(888
	(|b '$r(|*<<<
	&zB~RZ(888
	8bk))C 66'?s2g;/14T)E"W+$678::C66'1!7R[((C6##Ct$q'3'u:(x LLNMo  	#q(G,B,B,D	  	#q(G,B,B,D	  	#q(G,B,B,D	  	#q(G,B,B,D	  	#q(G,B,B,D	  	#q(G,B,B,D	  	#q(G,B,B,D	s~   X2Y2Z	Z9 [&7\] 2&YY&Z	Z	&Z65Z69&[#"[#&&\\&\=<\= &]*)]*tarrY   	from_pageto_pagestart_atc           	        -./ |j                   syd -d /.fd..fd}d-/fd	}d }	t        j                  |       }
t        j                  |      }| j                   r |	|       }|j                  t	        j
                  d            }|j                  t	        j
                  d	            }|j                         s|j                  t	        j
                  d	      d
      }nt        j                   |	|            }|j                  t	        j
                  d             |j                  t	        j
                  d      d
       |j                  t	        j
                  d	             |j                  t	        j
                  d	      d
       t        j                  ||      }t        j                  |
|      }|j                  t	        j
                  d            }|j                  t	        j
                  d	            }|j                         }t        j                  |
|d      }t        j                  t        j                  |
      t	        j
                  d            }|j                  t	        j
                  d      |       ||k  rt!        ||dz         }nt!        ||dz
  d      }i }|D ]  }|||      }|j#                         D cg c]  \  }}}|t        j$                  k(  r| c}}}D ]S  }t        j&                  ||      }|j                  t	        j
                  d              ||      \  }}|sKd|g d||<   U  |j)                         D ]  }t        j&                  ||      }t        j                  ||      }t        j                  |
|      }  .| g       }!| j                         }"t        j                  |
|"d      }#|j+                  |#       |"||   d<   |!||   d<    |D ]S  }| ||z      }$|||      }|j#                         D cg c]  \  }}}|t        j$                  k(  r| }%}}}|%sOt        j,                  |$      }&t        j                  |&j/                         t	        j
                  d            }'t        j                  |'      s8t        j                  |&j/                         t	        j
                  d      d
      }'|%D ]f  }t        j&                  ||      }t        j0                  t        j2                  |d            }(t        j                  |j                  t	        j
                  d                  }|dk(  rt        j                  ||      })t        j                  |
|)      }*|*j                         }t        j                  |
|d      }+t        j*                  |'|+       t        j*                  ||+       nN||   }|d   j5                  |      },|d   |,   }t        j                  |
|d      }+t        j*                  |'|+       |(sQt        j*                  ||+       i V  ||
||       yc c}}}w c c}}}w )zInsert widgets of copied page range into target PDF.

    Parameter values **must** equal those of method insert_pdf() which
    must have been previously executed.
    Nc                 R   t        | j                               D ]  }| j                  |      }|j                  t	        j
                  d            }t        |j                               D ]8  }|j                  |      }|j                  t	        j
                  d      |       :  y)z3 Make sure all kids have correct "Parent" pointers.KidsParentN)r$  pdf_array_lenpdf_array_getpdf_dict_getr   PDF_NAMEpdf_dict_put)acro_fieldsr_   rF   kidsjkids         r&   clean_kid_parentsz%do_widgets.<locals>.clean_kid_parents  s    {0023 	EA ..q1F&&w'7'7'?@D4--/0 E((+  !1!1(!;VDE	Er'   c           	         d }d }t        j                  | |      }t        j                  | |      }|j                  t        j                  d            }	|j                  t        j                  d            }
|	j                         r || |||	||
       y|
j                         r || |||
||	       y || ||||||       y)a^  Called for each pair of widgets having the same name.

        Args:
            pdf: target MuPDF document
            acro_fields: object Root/AcroForm/Fields
            xref1, xref2: widget xrefs having same names
            name: (str) the name

        Result:
            Defined or updated widget parent that points to both widgets.
        c                    t        j                  | |d      }t        j                  | |d      }|j                  |      }|j                  |       |j	                         sqt        j
                  | |      }	|	j                  t        j                  d             |	j                  t        j                  d      |       |j                  |       yt        |j                               D ]n  }
|j                  |
      }|j                  t        j                  d      |       t        j                  | |j                         d      }|j                  |       p y)zMerge widget in xref2 into "Kids" list of widget xref1.

            Args:
                xref1, kids1: target widget and its "Kids" array.
                xref2, kids2: source wwidget and its "Kids" array (may be empty).
            r   Tr*  N)r   pdf_new_indirectpdf_array_findpdf_array_deletepdf_is_arraypdf_load_objectpdf_dict_delr   r.  r/  pdf_array_pushr$  r+  r,  
pdf_to_num)r   r0  xref1kids1xref2kids2w1_indw2_indr  widgetr_   r3  kid_inds                r&   	re_targetz3do_widgets.<locals>.join_widgets.<locals>.re_target  s    ++C:F++C:F,,V4C((-%%'..sE: ##G$4$4S$9:##G$4$4X$>G $$V,u2245 2A--a0C$$W%5%5h%?H#44S#..:JANG((1	2r'   c                 `   t        j                  | d      }|j                  t        j                  d      |       |j                  t        j                  d      d      }t        j                  | |      }	|	j                         }
t        j                  | |
d      }|j                  t        j                  d            }|j                  t        j                  d             |	j                  t        j                  d      |       |j                  t        j                  d            }|j                  t        j                  d             |	j                  t        j                  d      |       |j                  t        j                  d             |j                  t        j                  d      |       |j                  t        j                  d             |j                  t        j                  d      |       t        j                  | |d      }t        j                  | |d      }|j                  |       |j                  |       |j                  |      }|j                  |       |j                  |      }|j                  |       |j                  |       y	)
a  Make new "Parent" for two widgets with same name.

            Args:
                xref1, w1: first widget
                xref2, w2: second widget
                name: field name

            Result:
                Both widgets have no "Kids". We create a new object with the
                name and a "Kids" array containing the widgets.
                Original widgets must be removed from AcroForm/Fields.
            r   r7  r)  r]  r   FTAAr*  N)r   pdf_new_dictpdf_dict_put_text_stringr   r.  pdf_dict_put_arraypdf_add_objectr?  r8  r-  r=  r/  r>  r9  r:  )r   r0  r@  w1rB  w2r~   newr1  new_objnew_obj_xrefnew_indftaaind1ind2r  s                    r&   
new_targetz4do_widgets.<locals>.join_widgets.<locals>.new_target  s    $$S!,C(()9)9#)>E))'*:*:6*BAFD**34G"--/L,,S,BG !1!1$!78BOOG,,T23  !1!1$!7<!1!1$!78BOOG,,T23  !1!1$!7< OOG,,S12OOG,,X6@OOG,,S12OOG,,X6@ ))#ua8D))#ua8D%% ,,T2C((-,,T2C((-&&w/r'   r)  N)r   r<  r-  r   r.  r;  )r   r0  r@  rB  r~   rH  rZ  rP  rQ  rA  rC  s              r&   join_widgetsz do_widgets.<locals>.join_widgets  s    	2<0	0d ""3.""3. 0 0 89 0 0 89 c;ueUC!c;ueUCsKE2tDr'   c           	         t        j                  | t        j                  d            }|j	                         s|S t        |j                               D ]x  }|j                  |      }t        j                  t        j                  |t        j                  d                  r
 ||      }Z|j                  |j                                z |S )zVReturn xref list of leaf kids for a parent.

        Call with an empty list.
        r)  )r   r-  r   r.  r;  r$  r+  r,  pdf_is_dictr   r?  )rF   	kids_listr1  r_   r3  get_kidss        r&   r_  zdo_widgets.<locals>.get_kids  s    
 !!&'*:*:6*BC  "t))+, 	3A$$Q'C  !3!3C9I9I&9Q!RS$S)4	  !12	3 r'   c                     g }t        j                  | t        j                  d            }|j	                         }|dk(  r||fS  ||      }||fS )z:Get the xref of top "Parent" and the list of leaf widgets.r*  r   )r   r-  r   r.  r?  )rF  r^  rF   parent_xrefr_  s       r&   
kids_xrefszdo_widgets.<locals>.kids_xrefs,  s]    	##FG,<,<X,FG'')!	))VY/	I%%r'   c                 R   i }t        t        j                  |            D ]y  }t        j                  ||      }|j	                         }t        j
                  |t        j                  d            }|j                  |g       }|j                  |       |||<   { |j                         D ]o  \  }	}t        |      dk  r|dd \  }
}|r | ||
||	       ,|	d| dz   }t        j                  | |      }|j                  t        j                  d      |       q  |       y)z6Handle any widget name duplicates caused by the merge.r7  r]  Nz [r  )r$  r   r+  r,  r?  pdf_dict_get_text_stringr   r.  rT   r   r  r   r<  rM  )r   r0  join_duplicatesnamesr_   wobjectrB   r7  r  r~   xref0r@  newnamer4  r[  s                r&   deduplicate_namesz%do_widgets.<locals>.deduplicate_names6  s#    u**;78 	A))+q9G%%'D ..w8H8H8MNAIIa$ELLE!H	 !;;= 		QKD%5zA~ !9LE5S+ueTB2eWA.//U;001A1A#1FP		Q 	+&r'   c                 ~    t        j                  |       }t        j                  t        j                  |      d      S )z,Retrieve the AcroForm dictionary form a PDF.zRoot/AcroForm)r   pdf_document_from_fz_documentpdf_dict_getppdf_trailer)r[   r   s     r&   get_acroformz do_widgets.<locals>.get_acroformR  s0    11#6""5#4#4S#9?KKr'   FieldsCOr   r   RootAcroFormr   ri   P)rq   old_kidsnew_kidsrq   rv  AnnotszAA/Cr*  ru  )re  F)is_form_pdfr   rl  r-  r   r.  r;  rN  pdf_deep_copy_objr=  pdf_graft_mapped_objectrO  r?  r8  rn  r/  r$  annot_xrefsPDF_ANNOT_WIDGETr<  rv  r>  pdf_page_from_fz_pageobjr]  rm  index)0r#  rY   rC   r$  r%  r&  re  rb  rj  ro  tarpdfsrcpdfacror0  tar_co
acro_graftacro_tartar_xrefacro_tar_indroot	src_rangeparentsr_   r\   rB   wtyper   w_objra  ru  rF   parent_graft
parent_tarkids_xrefs_newparent_xref_new
parent_indtar_pagew_xrefstar_page_pdf
tar_annotsis_aacw_obj_graft	w_obj_tarw_obj_tar_indr  r4  r_  r[  s0                                                @@@r&   
do_widgetsr    s    ??EhET &'8L 005F005F
C ''(8(8(BC""7#3#3D#9:""$,,W-=-=d-CQGF &&|C'89 	'**845 0 0 :A>'**401 0 0 6: 228TB
 ''
;++G,<,<X,FG&&w'7'7'=> &&(--fhB!!%"3"3F";W=M=Mf=UV'**:6EG)Wq[1	)Wq["5	G  y|$ #+"6"6"8
 
eQ000 
 	D
 ))&$7Ew//45 %/u$5!K ! ( "($	&  	3&&vt444XvF))&,?
!*b1$//1++FOQG
"":.$3j!$2j!	3  4<x!|$ y|$
 #+"6"6"8
 
eQ000 
 

  228< ''(8(8(:G<L<LX<VW
!!*-11  "G$4$4X$>J  	<D))&$7E &&u':':5&'IJF  **""7#3#3H#=>K a#;;HeL!00E	$//1 % 6 6vx K$$Z?$$[-@ -Z(..t4!*-c2 % 6 6vx K$$Z? $$V];5	<54<l fk?Ke
H
s    Y$
) Y+
doc1doc2c                    d }|dk  rd}n!||j                   k\  r|j                   dz
  }n|}|dk  s||j                   k\  r|j                   dz
  }n|}|dk  rt        d      |}||k  rdnd}	t        t        |||	z   |	            }
t        t	        |
            D cg c]  }||z   	 }}g }g }t        t	        |
            D ]P  }|
|   }||   }|j                  |      }| j                  |      }|j                  |       |j                  |       R t        t	        |            D ]  }||
|      }|j                         }t	        |      dk(  rd},|j                   }| ||      }g }|D ]?  }|d   t        j                  k(  r|d   |
vr! ||||
|      }|s/|j                  |       A |g k7  s|j                  t        |              yc c}w )	zInsert links contained in copied page range into destination PDF.

    Parameter values **must** equal those of method insert_pdf(), which must
    have been previously executed.
    c           	         | d   |z  }t        t        |            }| d   t        j                  k(  rWt        j                  d   }|j                  | d         }| d   |z  } |||   |j                  |j                  | d   |      }	|	S | d   t        j                  k(  r| d   dk\  rt        j                  d   }| j                  dt        j                  dd            }
t        |
      t        j                  urt        j                  dd      }
 || d   |
j                  |
j                  | d   | d	   | d	   |      }	|	S t        j                  d
   }t        j                  | d         }|dd }| d	   } ||||      }	|	S | d   t        j                  k(  r%t        j                  d   } || d	   | d	   |      }	|	S | d   t        j                  k(  r!t        j                  d   } || d   |      }	|	S d}	|	S )z5Create annotation object string for a passed-in link.r\  r[  goto1r
   r_  r  r   gotor1rb  gotor2r   ri   launchr^  r   )r  r+  r   rm  
annot_skelr  r-   r.   rp  rT   rh  r   r  rs  rl  )lnkxref_dstpno_srcr  r   r    r!  r  pannotr{  r_  r  s                r&   	cre_annotzdo_links.<locals>.cre_annot  s    K#q"v;'+++$$W-C--F,CD	CAqssACCVdCEF C [G...6{a((2ggdGMM!Q$789GMM1!--1-CKEEEEKKK6 # ((2((T3"XKB4(  [G///$$X.CFS[$7E  [G,,,$$U+CE
D)E
  Er'   r   r   z'start_at' must be >= 0ri   Nr[  r
   )rJ   r   r*  r$  r   r  r   r  rL   r   rm  _addAnnot_FromStringr+  )r  r  r$  r%  r&  r  fpr   saincrr  r_   pno_dstxref_srcr  p_srcp_dstold_xrefrq   page_srcr  r  page_dstlink_tabr   
annot_texts                             r&   do_linksr    s    ,b 1}	doo	%__q {g0__q !|233	Bb1bD 5R$Y-.G$S\23!rAv3G3 HH3w<  "

>>%(>>%(!!" 3x=! <
#""$
 u:?H---
# 	,AyG---1V9G3K"1h=J
+	, r>))5?;)< 4s   Gr  c           	      r   | j                   }| }|d   }t        t        ||z              }d}|d   t        j                  k(  r|d   dk\  rt        j
                  d   }|d   }| j                  j                  |      }	|j                  dt        j                  dd            }
| j                  |   }|j                   }| }|
|z  } ||	|j                  |j                  |j                  dd      |      }nt        j
                  d	   } |t        j                  |d         |      }n|d   t        j                  k(  r|d   dk\  rt        j
                  d
   }|j                  dt        j                  dd            }
t        |
      t        j                  urt        j                  dd      }
 ||d   |
j                  |
j                  |j                  dd      |d   |d   |      }nt        j
                  d   } |t        j                  |d         |d   |      }n|d   t        j                  k(  r$t        j
                  d   } ||d   |d   |      }n|d   t        j                   k(  r t        j
                  d   } ||d   |      }nJ|d   t        j"                  k(  r4t        j
                  d   }|j                  d      }||d   } |||      }|s|S t%        | j'                         D cg c]#  }|d   t        j(                  k(  s|d   |d   f% c}      }|j                  dd      }|r|d   |f|j+                         v r|}nBd}t        j,                  j/                         dz   }	 ||z  }||j1                         vrn|dz  }|j3                  dd|z        }|S c c}w )Nr\  r   r[  r
   r   r  r_  r  goto2r  rb  r  r  r^  ru  r~   	nameddestr   r]  r~  rB   z-L%iz/Linkz/Link/NM(%s))rL   r  r+  r   rm  r  rF   r  rT   rh  r-   r.   r  rp  r   rs  rl  rt  r	  r|  r  r  TOOLSset_annot_stemvaluesrr  )r
   r  r  ictmr   r    r  r!  rZ   rB   r{  	dest_pagedest_ctm	dest_ictmipntlnamer-   
link_namesold_namer~   r_   stems                         r&   getLinkTextr  U  s    
$
$C4DFAU1t8_%DE
6{g'''v;!$$W-Cf+C;;((-D''$a 34CC(I 66H!	I?Ddffdffcggfa.@$GE$$W-C++CI6=E	V**	*v;!$$X.C''$a 34CCy-mmAq)F"FFE $$X.C++CI6FTJE	V++	+  *CKVd3	V((	(  'CJ%	V**	*  )=$EE4  #//1T!QqTW=S=S5S!A$!TJ wwtR HS[(+z/?/?/AA}}++-6!8D:,,..FA	  MM'>D#89EL# 	Us   >N4N4rF  c                 .   t        j                  |        t        |dd      }|t        d      |j                  }| j                  |       d|j                  _        t        |j                  j                               }|D ]  }|j                  |=  |S )z0Delete widget from page and return the next one._annotNzbad type: widget)r   rE   r   r   r  delete_annotr  rF   r*  __dict__rv  )r
   rF  r  
nextwidgetkeylistr   s         r&   delete_widgetr    s    FHd+E}+,,JeFMM6??'')*G !OOC !r'   c                     t        j                  |        t        | |      }|dk(  rt        d      | j                  j                  |d   ||        y)z"Update a link on the current page.r   link kind not supportedrB   )r
   N)r   rE   r  r   rF   r  )r
   r  r  s      r&   update_linkr    sL    c"E{233KKc&k5t<r'   markc                     t        j                  |        t        | |      }|dk(  rt        d      | j	                  |f       y)z'Insert a new link for the current page.r   r  N)r   rE   r  r   r  )r
   r  r  r  s       r&   insert_linkr    s?    c"E{233uh'r'   helv   皙?)fontnamefontfile
set_simpleencodingfontsize
lineheightr   fill
expandtabsalignr   render_modemiter_limitborder_widthmorphr   stroke_opacityfill_opacityr   bufferr  r  r  r  r  r  r   r  r  r  r   r  r  r  r  r   r  r  r   c                    | j                         }|j                  |||||||||	|
||||||||||      }|dk\  r|j                  |       |S )a  Insert text into a given rectangle.

    Notes:
        Creates a Shape object, uses its same-named method and commits it.
    Parameters:
        rect: (rect-like) area to use for text.
        buffer: text to be inserted
        fontname: a Base-14 font, font name or '/name'
        fontfile: name of a font file
        fontsize: font size
        lineheight: overwrite the font property
        color: RGB color triple
        expandtabs: handles tabulators with string function
        align: left, center, right, justified
        rotate: 0, 90, 180, or 270 degrees
        morph: morph box with a matrix and a fixpoint
        overlay: put text in foreground or background
    Returns:
        unused or deficit rectangle area (float)
    )r  r  r  r  r  r  r   r  r  r  r  r  r  r   r  r  r  r   r   )	new_shapeinsert_textboxcommit)r
   r    r  r  r  r  r  r  r  r   r  r  r  r   r  r  r  r  r   r  r  r   imgr   s                           r&   r  r    s|    Z ..
C			!%!) 
 
B, 
Qw

7Ir'   )r  r  r  r  r  r  r   r  r  r  r  r   r  r   r  r  r   r  c                    | j                         }|j                  |||||||||	|
||||||||      }|dk\  r|j                  |       |S )N)r  r  r  r  r  r  r   r  r  r  r  r   r  r  r  r   r   )r  insert_textr  )r
   r  r   r  r  r  r  r  r  r   r  r  r  r  r   r  r   r  r  r   r  r   s                         r&   r  r  	  ss    0 ..
C	!%!% 
 
B( 
Qw

7Ir'   )css	scale_lowarchiver   r   r   r   c          	      :   |dz  dk(  st        d      |dk  r|dz  }|dk  r|dk\  r|dz  }|dk\  rd|cxk  rdk  st        d       t        d      |d}t        j                  |      }|d	v r-t        j                  dd|j                  |j                        }
n,t        j                  dd|j                  |j                        }
d
|z   }t        |t              rt        j                  |||      }n(t        |t        j                        r|}nt        d      |dk(  rdnd|z  }|j                  |
d|      j                  sd|fS j                  }dj                  z  }j                  j                  |d   z
  }|dk7  s|dk  rd}fd}|j                  |      }d|cxk  rdk  rPn nM|d   }|j                  ||      }d| d}t        j                   j#                  ||j%                         d       | j'                  ||d|||	       j                  j(                  j                  j*                  z   dz  |z  }|j(                  |j*                  z   dz  }t        j,                  |dd||j.                   |j0                         t        j,                  |       z  t        j,                  dddd|j.                  |j0                        z  }|d   j3                         D ]   }|dxx   |z  cc<   | j5                  |       " ||fS )a  Insert text with optional HTML tags and stylings into a rectangle.

    Args:
        rect: (rect-like) rectangle into which the text should be placed.
        text: (str) text with optional HTML tags and stylings.
        css: (str) CSS styling commands.
        scale_low: (float) force-fit content by scaling it down. Must be in
            range [0, 1]. If 1, no scaling will take place. If 0, arbitrary
            down-scaling is acceptable. A value of 0.1 would mean that content
            may be scaled down by at most 90%.
        archive: Archive object pointing to locations of used fonts or images
        rotate: (int) rotate the text in the box by a multiple of 90 degrees.
        oc: (int) the xref of an OCG / OCMD (Optional Content).
        opacity: (float) set opacity of inserted content.
        overlay: (bool) put text on top of page content.
    Returns:
        A tuple of floats (spare_height, scale).
        spare_height: -1 if content did not fit, else >= 0. It is the height of the
               unused (still available) rectangle stripe. Positive only if
               scale_min = 1 (no down scaling).
        scale: downscaling factor, 0 < scale <= 1. Set to 0 if spare_height = -1 (no fit).
    r   r   zbad rotation angler   r   z'scale_low' must be in [0, 1]Nr   )r   r   zbody {margin:1px;})r2  user_cssr  z"'text' must be a string or a Story)	scale_min	scale_maxri   r   c                  R    j                   j                   t        j                  fS N)r    r   Identity)r  fits    r&   rect_functionz%insert_htmlbox.<locals>.rect_function	  s    xx7#3#333r'   CAcara  z gs
)r   r   r   r]  r\  )r   r   r   r   r   r   rQ   Story	fit_scale
big_enoughfilled	parameterr    r   write_with_links_set_opacityr  _insert_contentsencoder!   r*   r+   r,   r-   r.   r  r  )r
   r    r   r  r  r  r   r   r   r   	temp_rectmycssstoryr  r  scalespare_heightr  r[   r$   alp0smp1mp2r  r  r  s                             @r&   insert_htmlboxr  E	  s   J B;!-..
1*# 1*
C-# C- 	Q899 899
{<<DLLAt{{DJJ?	LLAtzz4;;?	 !3&E $4%I	D'--	(=>> "QA	MI
//)qI/
FC>>IZZFE88;;*Lz\A%4 
 
 
/C 	GaA!!W!9vUO&&uahhj!< 	tS!Fr7K 88;;$
)E
1C 77TWW
!C 	uaECEE6CEE6:
..&
!	"
..Aq!SUUCEE
2	3  A  " V r'   r   r   c                 4    | j                  |||       | |   S )a<  Create and return a new page object.

    Args:
        pno: (int) insert before this page. Default: after last page.
        width: (float) page width in points. Default: 595 (ISO A4 width).
        height: (float) page height in points. Default 842 (ISO A4 height).
    Returns:
        A pymupdf.Page object.
    r   )_newPage)r[   rZ   r   r   s       r&   r   r   	  s     LLE&L1s8Or'   c	                 t    | j                  |||      }	t        |      sy|	j                  d|||||      }
|
S )zCreate a new PDF page and insert some text.

    Notes:
        Function combining pymupdf.Document.new_page() and pymupdf.Page.insert_text().
        For parameter details see these methods.
    )rZ   r   r   r   )2   r   )r  r  r  r   )r   rl   r  )r[   rZ   r   r  r   r   r  r  r   r
   r   s              r&   insert_pager  	  sP    " <<CuV<<D:			 
 
B Ir'   dasheslineCaplineJoinc                     | j                         }|j                  t        j                  |      t        j                  |            }|j	                  |||d|||	|
||
       |j                  |       |S )z&Draw a line from point p1 to point p2.F
r   r  r   	closePathr  r  r  r  r  r   )r  	draw_liner   rh  finishr  )r
   r   r   r   r  r   r  r  r   r  r  r  r   r  r  s                  r&   r  r  	  st      ..
CgmmB'r):;AJJ%!   JJwHr'   breadthc                     | j                         }|j                  t        j                  |      t        j                  |      |      }|j	                  |||d|||
|||
       |j                  |	       |S )z/Draw a squiggly line from point p1 to point p2.r  Fr  )r  draw_squiggler   rh  r  r  r
   r   r   r  r   r  r   r  r  r   r  r  r  r   r  r  s                   r&   r"  r"  
  s{    " ..
C'--+W]]2->PAJJ%!   JJwHr'   c                     | j                         }|j                  t        j                  |      t        j                  |      |      }|j	                  |||d|||
|||
       |j                  |	       |S )z-Draw a zigzag line from point p1 to point p2.r!  Fr  )r  draw_zigzagr   rh  r  r  r#  s                   r&   r%  r%  >
  sx    " ..
Cb)7==+<gNAJJ%!   JJwHr'   c                     | j                         }|j                  t        j                  |      |      }|j	                  ||||||||
||
       |j                  |	       |S )z?
    Draw a rectangle. See Shape class method for details.
    radius
r   r  r  r   r  r  r  r  r  r   )r  	draw_rectr   r   r  r  )r
   r    r   r  r  r   r  r  r  r   r  r  r   r(  r  Qs                   r&   r*  r*  b
  sm    & ..
Cgll4(8AJJ%!   JJwHr'   quadc                     | j                         }|j                  t        j                  |            }|j	                  ||||||||
||
       |j                  |	       |S )zDraw a quadrilateral.r)  )r  	draw_quadr   Quadr  r  )r
   r,  r   r  r  r   r  r  r  r   r  r  r   r  r+  s                  r&   r.  r.  
  si      ..
Cgll4()AJJ%!   JJwHr'   pointsr  c                     | j                         }|j                  |      }|j                  ||||||||
|||       |j                  |	       |S )z&Draw multiple connected line segments.r   r  r  r   r  r  r  r  r  r  r   )r  draw_polyliner  r  )r
   r0  r   r  r  r   r  r  r  r   r  r  r  r   r  r+  s                   r&   r3  r3  
  se    " ..
C&!AJJ%!   JJwHr'   centerr(  c                     | j                         }|j                  t        j                  |      |      }|j	                  ||||||	||||
       |j                  |
       |S )*Draw a circle given its center and radius.r)  )r  draw_circler   rh  r  r  )r
   r4  r(  r   r  r  r  r   r  r  r   r  r  r   r  r+  s                   r&   r7  r7  
  sk    " ..
Cf-v6AJJ%!   JJwHr'   c                     | j                         }|j                  |      }|j                  ||||||||
||
       |j                  |	       |S )z4Draw an oval given its containing rectangle or quad.r)  )r  	draw_ovalr  r  )r
   r    r   r  r  r  r   r  r  r   r  r  r   r  r+  s                  r&   r9  r9  
  s`      ..
CdAJJ%!   JJwHr'   p3c                    | j                         }|j                  t        j                  |      t        j                  |      t        j                  |            }|j	                  |||||
|||	|||       |j                  |       |S )zdDraw a special Bezier curve from p1 to p3, generating control points on lines p1 to p2 and p2 to p3.r2  )r  
draw_curver   rh  r  r  )r
   r   r   r:  r   r  r  r   r  r  r  r  r   r  r  r   r  r+  s                     r&   r<  r<    s    & ..
Cw}}R('--*;W]]2=NOAJJ%!   JJwHr'   p4c                 @   | j                         }|j                  t        j                  |      t        j                  |      t        j                  |      t        j                  |            }|j	                  |||||||	|
|||       |j                  |       |S )zODraw a general cubic Bezier curve from p1 to p4 using control points p2 and p3.r2  )r  draw_bezierr   rh  r  r  )r
   r   r   r:  r=  r   r  r  r   r  r  r  r  r   r  r  r   r  r+  s                      r&   r?  r?  =  s    ( ..
Cb)7==+<gmmB>OQXQ^Q^_aQbcAJJ%!   JJwHr'   beta
fullSectorc                     | j                         }|j                  t        j                  |      t        j                  |      ||      }|j	                  ||||	||||
|||       |j                  |       |S )a  Draw a circle sector given circle center, one arc end point and the angle of the arc.

    Parameters:
        center -- center of circle
        point -- arc end point
        beta -- angle of arc (degrees)
        fullSector -- connect arc ends with center
    rA  r2  )r  draw_sectorr   rh  r  r  )r
   r4  r  r@  r   r  r  rA  r  r   r  r  r  r   r  r  r   r  r+  s                      r&   rD  rD  e  s~    6 ..
Cf-w}}U/CTV`aAJJ%!   JJwHr'   c            
      l    t        j                         D  cg c]	  \  } }}}|  c}}}} S c c}}}} w )zP
    Returns a list of upper-case colour names.
    :rtype: list of strings
    r   colors_wx_list)r~   r   gr   s       r&   getColorListrI    s,    
 '.&<&<&>??]T1aD???s   .
c                  *    t        j                         S )z
    Returns list of (name, red, gree, blue) tuples, where:
        name: upper-case color name.
        read, green, blue: integers in range 0..255.
    :rtype: list of tuples
    rF  r   r'   r&   getColorInfoListrK    s     !!##r'   r~   c                 f    t        j                         j                  | j                         d      S )zRetrieve RGB color in PDF format by name.

    Returns:
        a triple of floats in range 0 to 1. In case of name-not-found, "white" is returned.
    )r   r   r   )r   colors_pdf_dictrT   r?  )r~   s    r&   getColorrN    s&     ""$((yAAr'   c                 <   	 t               t               j                  | j                                  }|d   dz  }|d   dz  }|d   dz  }t        |||      }t        |dz  d      }t        |||      }||z
  }|dk(  rd}	n6||k(  rd||z
  |z  d	z  z  }	n"||k(  rd||z
  |z  dz   z  }	nd||z
  |z  d
z   z  }	t        t        |	            }
|dk(  rd}n||z  }t        t        |dz              }|
||fS # t        $ r t
        rt        j                          Y yw xY w)zRetrieve the hue, saturation, value triple of a color name.

    Returns:
        a triple (degree, percent, percent). If not found (-1, -1, -1) is returned.
    ri   ri   ri   r   g     o@r]  r   d   r   g      N@   r>   )rK  rI  r  rR  rg  r  r   r  r   r   r/   r   )r~   r-   r   rH  r   cmaxVcmindeltahueHsatSs                r&   getColorHSVr[    sE   |~33DJJLAB
 	
!uA	!uA	!uAq!Q<DdSj!Aq!Q<D4KEz	A!+,	A!+,A!+,E#JAqydlE#)Aq!99  G$:$:$<s   2C5 5#DDc                 d   | j                  |      \  }}}}d}d}|dk(  r|||||fS |rj	 t        j                  |      }|j                  }|j                  }|j
                  }	||z
  dk  r |	j                  |k  r|	j                  }d|z
  }|||||fS |dk7  r/	 t        j                  |      }|j                  }|j                  }n
|dz  }|dz  }|||||fS # t        $ r! t        j                          |dz  }|dz  }Y uw xY w# t        $ r! t        j                          |dz  }|dz  }Y ]w xY w)Ng?gɿr   
fontbufferr   333333?zn/a)	extract_fontr   Fontascender	descenderr
  r   rg  r  )
r[   rB   r  extstyper  ascdscfontr
  s
             r&   _get_font_propertiesri    sW   #&#3#3D#9 Hc5&
C
C
byeS#--	<<62D--C..C99DSy1}77S=''C#g
 eS#--
e|	<<)D--C..C 	s
s
S%c))#  	""$3JC3JC	  	""$3JC3JC	s$   A"C -D 'DD'D/.D/limitfontdictc                    t        j                  | |      }||t        | |      \  }}}}	}
||||	|
d}n|d   }|d   }|d   }|d   }|d   }|dk(  rt        d	      |d
v rd}nd}|dv rd}n|dv rd}n|dv rd}n	|dv rd}nd}||d<   |dk(  rt         j                  }n|dk(  rt         j
                  }nd}||d<   ||d<   ||g}| j                  j                  |       n|d   }|d   }|d   }|d   }|d}nt        |      }t        d|      }||k  r|S |dk  r | j                  ||d   |d   |d   ||      }nd}||d<   ||d<   t        j                  | |       |S )a  Get list of glyph information of a font.

    Notes:
        Must be provided by its XREF number. If we already dealt with the
        font, it will be recorded in doc.FontInfos. Otherwise we insert an
        entry there.
        Finally we return the glyphs for the font. This is a list of
        (glyph, width) where glyph is an integer controlling the char
        appearance, and width is a float controlling the char's spacing:
        width * fontsize is the actual space.
        For 'simple' fonts, glyph == ord(char) will usually be true.
        Exceptions are 'Symbol' and 'ZapfDingbats'. We are providing data for these directly here.
    N)r~   r   rd  rb  rc  r~   rd  r   orderingr  r   zxref is not a font)Type1MMType1TrueTypeTF)FangtiMingr   )HeitiSongr   )GothicMinchor]  )DotumBatangr   ri   ZapfDingbatsSymbolglyphs   )r   CheckFontInfori  r   zapf_glyphssymbol_glyphs	FontInfosr   r   r   _get_char_widthsUpdateFontInfo)r[   rB   rj  r  rk  fontinfor~   rd  re  rf  rg  rm  r  r{  oldlimitmylimits                   r&   get_char_widthsr  	  s     $$S$/H)=c4)H&D#uc3 H F#D5/CV$E
+Hh'F"9122 44FF %%H&&H))H((HH#>!((FX**FF#'(#X&A;(#(#J'~v;#uoG(!|%%(6"HUOXj5I7TW
 HXHQK3)Mr'   c            +          e Zd ZdZed        Zdej                  fdZd Z	de
de
dej                  fd	Zd
edej                  fdZde
de
de
de
dej                  f
dZdej"                  eef   dej                  fdZde
dedej                  fdZde
de
de
dej                  fdZ	 dGde
de
dededej                  f
dZdddedej                  fdZdedej                  fdZ	 dHde
de
dedej                  fd Z	 dHde
de
dej                  fd!Zd"dd#dd$d$ddd$d%d&d$dd&d&d$d'de
d(ej"                  eef   d)ed*ed+ed,e d-ed.e!d/e"d0e"d1e!d2ed3ed4e!d5e"d6ed7ed8e!de!f&d9Z#d#dd"dd$d$ddd&d%d&d$d$d$dd&d&d$d:ded(ej"                  eef   d+e d,e d)ed*ed-ed.e!d/e"d0e"d;e!d2ed3ed<e!d1e!d4e!d5e"d6ed7ed8e!def*d=Z$	 	 	 	 	 	 	 	 	 	 	 	 dId>ed/e"d0e"d?e!d@e!dAe dBed5e"dCed7ed6ed8e!ddfdDZ%dGdEeddfdFZ&y)JShapezCreate a new shape.c                 V   t        j                  || z
        j                  }t        j                  t        |j                              }|j                  dk  r:|j                  dk  rt        j                  |z
   }|S t        j                  |z
  }|S |j                  dk\  r	 |S | }|S )zReturn the angle to the horizontal for the connection from C to P.
        This uses the arcus sine function and resolves its inherent ambiguity by
        looking up in which quadrant vector S = P - C is located.
        r   )	r   rh  r  mathasinr   r.   r-   pi)Crt  rZ  alfas       r&   horizontal_anglezShape.horizontal_anglen  s     MM!a% %%yyQSS"337ssax4(  ww~ 	 ssax  ur'   r
   c                    t        j                  |       || _        |j                  | _        | j                  j
                  st        d      |j                  j                  | _	        |j                  j                  | _        |j                  j                  | _
        |j                  j                  | _        |j                  | _        | j                   | _        d| _        d| _        d| _        d | _        d | _        y )Nr;   r   )r   rE   r
   rF   r[   rG   r   mediabox_sizer.   r   r-   r   cropbox_positionrL   pctmipctm	draw_cont	text_cont	totalcont
last_pointr    )selfr
   s     r&   __init__zShape.__init__  s    D!	;;xx[))((**''))
&&((&&((..	iiZ
	r'   c                    | j                   Et        |      dk(  rt        j                  ||      | _         y t        j                  |      | _         y t        |      dk(  rt        j                  |      }t        | j                   j                  |j                        | j                   _        t        | j                   j                  |j                        | j                   _        t        | j                   j                  |j                        | j                   _        t        | j                   j                  |j                        | j                   _        y t        j                  |      }t        | j                   j                  |j                        | j                   _        t        | j                   j                  |j                        | j                   _        t        | j                   j                  |j                        | j                   _        t        | j                   j                  |j                        | j                   _        y )Nr]  )r    r   r   r   rh  r/   r   r-   r   r.   r   r   r   )r  r-   s     r&   
updateRectzShape.updateRect  sP   991v{#LLA.	#LLO	 1v{MM!$"499<<5		"499<<5		"499<<5		"499<<5		LLO"499<<6		"499<<6		"499<<6		"499<<6		r'   r   r   r   c                    t        j                  |      }t        j                  |      }| j                  |k(  sY| xj                  t	        t        j
                  || j                  z              dz   z  c_        || _        | j                  |       | xj                  t	        t        j
                  || j                  z              dz   z  c_        | j                  |       || _        | j                  S )zDraw a line between two points. m
 l
)r   rh  r  r  r  r0   r  r  )r  r   r   s      r&   r  zShape.draw_line  s    ]]2]]22%NNi(8(8djj(IJVSSN DOOOB)G$4$4R$**_$EFOOr'   r0  c           
      t   t        |      D ]  \  }}|dk(  r| j                  t        j                  |      k(  s| xj                  t        t        j                  t        j                  |      | j                  z              dz   z  c_        t        j                  |      | _        nT| xj                  t        t        j                  t        j                  |      | j                  z              dz   z  c_        | j                  |        t        j                  |d         | _        | j                  S )z%Draw several connected line segments.r   r  r  ri   )	r  r  r   rh  r  r  r0   r  r  )r  r0  r_   r  s       r&   r3  zShape.draw_polyline  s    f% 	DAqAv7==+;;NNi0@0@qAQTXT^T^A^0_&`ci&iiN&-mmA&6DO)G,<,<W]]1=MPTPZPZ=Z,["\_e"eeOOA	 "--r
3r'   r:  r=  c                    t        j                  |      }t        j                  |      }t        j                  |      }t        j                  |      }| j                  |k(  sA| xj                  t	        t        j
                  || j                  z              dz   z  c_        t        j
                  t        || j                  z        t        || j                  z        z   t        || j                  z        z         }| xj                  t	        |      dz   z  c_        | j                  |       | j                  |       | j                  |       | j                  |       || _        | j                  S )z#Draw a standard cubic Bezier curve.r   c
)	r   rh  r  r  r  r0   r  r*  r  )r  r   r   r:  r=  r  s         r&   r?  zShape.draw_bezier  s    ]]2]]2]]2]]22%NNi(8(8djj(IJVSSNR$**_ 5R$**_8M MPTUWZ^ZdZdUdPe ef)D/F22r'   tetrac                    t        |      dk7  rt        d      t        |d   d      r t        j                  |      j
                  }nt        j                  |      }|j                  |j                  |j                  z
  dz  z   }|j                  |j                  |j                  z
  dz  z   }|j                  |j                  |j                  z
  dz  z   }|j                  |j                  |j                  z
  dz  z   }| j                  |k(  sH| xj                  t        t        j                  || j                  z              dz   z  c_        || _        | j!                  ||j                  |       | j!                  ||j                  |       | j!                  ||j                  |       | j!                  ||j                  |       | j#                  |j$                         || _        | j                  S )z"Draw an ellipse inside a tetrapod.r>   zinvalid arg lengthr   	__float__r   r  )r   r   r   r   r   r,  r/  ulurlrllr  r  r  r0   r  r<  r  r    )r  r  qmtmrmbmls          r&   r9  zShape.draw_oval  st   u:?12258[)U#((AU#ATTQTTADD[C''TTQTTADD[C''TTQTTADD[C''TTQTTADD[C''2%NNi(8(8djj(IJVSSN DOADD"%ADD"%ADD"%ADD"%r'   r4  r(  c                     |t         j                  kD  st        d      t        j                  |      }||dfz
  }| j	                  ||dd      S )r6  radius must be positiver   r   FrC  )r   EPSILONr   rh  rD  )r  r4  r(  r   s       r&   r7  zShape.draw_circle  sP    '677v&vqk!CEBBr'   c                     d}t        j                  |      }t        j                  |      }t        j                  |      }|||z
  |z  z   }|||z
  |z  z   }| j                  ||||      S )z4Draw a curve between points using one control point.g7.SQ?)r   rh  r?  )r  r   r   r:  kappak1k2s          r&   r<  zShape.draw_curve  sp     ]]2]]2]]227e##27e##BB//r'   r  r@  rA  c                 j   t        j                  |      }t        j                  |      }d }d }d }t        j                  |       }t        j                  t        j                  d|            dz  }	t        j                  t        j                  d|            }
|
dz  }t        |      dt        j                  z  kD  r%||	z  }t        |      dt        j                  z  kD  r%| j                  |k(  s?| xj                   |t        j                  || j                  z         z  c_        || _        t        j                  dd      }|}|}||z
  }t        |      }|t         j                  kD  st        d	      | j                  ||      }t        |      t        |
      kD  r|j                  t        j                  ||
z         |z  z   }|j                   t        j"                  ||
z         |z  z   }t        j                  ||      }|j                  t        j                  ||z         |z  t        j                  |      z  z   }|j                   t        j"                  ||z         |z  t        j                  |      z  z   }t        j                  ||      }d
t        j                  |      z
  dz  dz  t        ||z
        z  }|t        ||z
        z  }|||z
  |z  z   }|||z
  |z  z   }| xj                   |t        j                  t%        || j                  z        t%        || j                  z        z   t%        || j                  z        z          z  c_        ||
z  }||
z  }|}t        |      t        |
      kD  rt        |      dkD  r|dz  }|j                  t        j                  ||z         |z  z   }|j                   t        j"                  ||z         |z  z   }t        j                  ||      }|j                  t        j                  ||z         |z  t        j                  |      z  z   }|j                   t        j"                  ||z         |z  t        j                  |      z  z   }t        j                  ||      }d
t        j                  |      z
  dz  dz  t        ||z
        z  }|t        ||z
        z  d
t        j                  |      z
  z  }|||z
  |z  z   }|||z
  |z  z   }| xj                   |t        j                  t%        || j                  z        t%        || j                  z        z   t%        || j                  z        z          z  c_        |r| xj                   |t        j                  || j                  z         z  c_        | xj                   |t        j                  || j                  z         z  c_        | xj                   |t        j                  || j                  z         z  c_        || _        | j                  S )zDraw a circle sector.c                 "    t        | |f      dz   S )Nr  r  r  s     r&   r   z#Shape.draw_sector.<locals>.<lambda>      )QF+f4 r'   c                 *    t        | |||||f      dz   S )Nr  r  r  s         r&   r   z#Shape.draw_sector.<locals>.<lambda>  s    iAq!Q0B&Cf&L r'   c                 "    t        | |f      dz   S )Nr  r  r  s     r&   r   z#Shape.draw_sector.<locals>.<lambda>  r  r'   r   ri   r   r]  r   r  r   r>   r   gMbP?)r   rh  r  radianscopysignr   r  r  r  r0   r  r  r   r  r-   cosr.   sinr*  )r  r4  r  r@  rA  l3l4l5betarw360w90w45r+  r  rt  rZ  radr  q1q2r1r2Rkappahr  cp1cp2beta2s                               r&   rD  zShape.draw_sector  s    v&e$4L4dU#||DMM#u56"=ll4==U34Ag%j1tww;&TME %j1tww;&5(NNb'"2"254::3E"FGGN#DOMM!QE!fW__$677$$VU3%j3s8#txxs
+c11Btxxs
+c11Bb"%Atxxs
+c1DHHSMAABtxxs
+c1DHHSMAABb"%A$((3-'1,q03q1u:=FSQZ'Eq1uo%Cq1uo%CNNb'"2"2S4::%&cDJJ.>)??$q4::~BVV#  N SLECKDA# %j3s8#& u:AIEtxxu-33Btxxu-33Bb"%Atxxu-3dhhuoEEBtxxu-3dhhuoEEBb"%A$((5/)Q.2SQZ?FSQZ'1txx+>?Eq1uo%Cq1uo%CNNb'"2"2S4::%&cDJJ.>)??$q4::~BVV#  N NNb'"2"254::3E"FGGNNNb'"2"26DJJ3F"GHHNNNb'"2"21tzz>"BCCNr'   Nr'  r    c          
         t        j                  |      }|| xj                  t        t        j                  t        |j                  | j                  z        |j                  |j                  gz               dz   z  c_        | j                  |       |j                  | _        | j                  S t        |d      rE|dk  s|dkD  rt        d| d      t        |j                  |j                        |z  }|df}d|f}n}t        |d      rbt!        |      dk(  rT|\  }}||j                  z  df}d||j                  z  f}t        ||      dk  st#        ||      dkD  rt        d| d      t        d| d      | j%                  |j                  |z   |j                  |z
        }	| j'                  |	|j                  |j                  |z         }	| j%                  |	|j(                  |z
        }	| j'                  |	|j(                  |j(                  |z
        }	| j%                  |	|j*                  |z         }	| j'                  |	|j*                  |j*                  |z
        }	| j%                  |	|j                  |z         }	| j'                  |	|j                  |j                  |z         | _        | j                  |       | j                  S )	a  Draw a rectangle.

        Args:
            radius: if not None, the rectangle will have rounded corners.
                This is the radius of the curvature, given as percentage of
                the rectangle width or height. Valid are values 0 < v <= 0.5.
                For a sequence of two values, the corners will have different
                radii. Otherwise, the percentage will be computed from the
                shorter side. A value of (0.5, 0.5) will draw an ellipse.
        z re
r  r   r   zbad radius value rZ  __len__r]  )r   r   r  r  r0   r*  blr  r   r   r  r*   r  r   r   r/   r   r   r  r<  r+   r2   )
r  r    r(  r   r  r  pyrxrylps
             r&   r*  zShape.draw_rectW  sc    LL>NNi(8(8QTTDJJ&'177AHH*==)  N OOAddDO??" 6;'{fsl #4VHA!>??AGGQXX&/AQBQBVY'CK1,<FBqww,"BR!((]#B2r{a3r2;#4 #4VHA!>??0:;;^^ADD2Iqttby1__Rqttby1^^Br	*__Rqttby1^^Br	*__Rqttby1^^Br	*//"addADD2I>r'   r,  c                     t        j                  |      }| j                  |j                  |j                  |j
                  |j                  |j                  g      S )zDraw a Quad.)r   r/  r3  r  r  r  r  )r  r,  r  s      r&   r.  zShape.draw_quad  s@    LL!!144qttQTT144"@AAr'   r  c                 B   t        j                  |      }t        j                  |      }||z
  }t        |      }dt        t	        |d|z  z  d            z  }|dk  rt        d      ||z  }t        j                  t        j                  ||            }| }	g }
t        d|      D ][  }|dz  dk(  rt        j                  |d      |z  }n#|dz  dk(  rt        j                  |d      |z  }nH|
j                  ||	z         ] | j                  |g|
z   |gz          |S )z%Draw a zig-zagged line from p1 to p2.r>   r   points too closer   ri   r   )r   rh  r   r   r   r   r,   util_hor_matrixr$  r   r3  )r  r   r   r  rZ  r  cntr  rA   i_matr0  r_   r  s                r&   r%  zShape.draw_zigzag  s    ]]2]]2G!f#eC1w;/3447/003Y 7 7B ?@q# 	%A1uzMM!R(2-Q!MM!Q'",MM!e)$	% 	B4&=B4/0	r'   c                    t        j                  |      }t        j                  |      }||z
  }t        |      }dt        t	        |d|z  z  d            z  }|dk  rt        d      ||z  }t        j                  t        j                  ||            }| }	d}
g }t        d|      D ]t  }|dz  dk(  rt        j                  ||
       |z  }n;|dz  dk(  rt        j                  ||
      |z  }nt        j                  |d      |z  }|j                  ||	z         v |g|z   |gz   }t        |      }d}|dz   |k  r0| j                  ||   ||dz      ||dz             |dz  }|dz   |k  r0|S )z#Draw a squiggly line from p1 to p2.r>   r   r  gh?3OP@r   r   r]  )r   rh  r   r   r   r   r,   r  r$  r   r   r<  )r  r   r   r  rZ  r  r  r  rA   r  r  r0  r_   r  s                 r&   r"  zShape.draw_squiggle  s    ]]2]]2G!f#eC1w;/3447/003Y 7 7B ?@q# 	%A1uzMM!aR(2-Q!MM!Q'",MM!Q'",MM!e)$	% "%&k!eckOOF1Iva!e}fQUmDFA !eck 	r'   r  r  r   r  r   )r  r  r  r  r  r  r   r  r  r  r  r   r  r  r  r   r  r  r  r  r  r  r  r   r  r  r  r  r   r  r  r  r   c          
      z
   t        |      syt        |      t        t        fvr|j	                         }n|}t        |      dkD  syt        j                  |      }	 t        dj                  |      D cg c]  }t        |       c}      }|}|j                  d      r|dd  }| j                  j                  ||||      }t        j                   | j"                  |      }|d   }|d   }|d   }|d   }|d	   }|d
   }|r||z  }n||z
  dk  r|dz  }n|||z
  z  }|dkD  r | j"                  j%                  ||dz         } n|d   } g }!|D ]4  }"|r|dvrd }#n| }#|!j'                  t        j(                  |"|#||             6 |!}t        j*                  |	d      }$t        j*                  |
d      }%|
s|dk(  r|	}
t        j*                  |	d      }%t        j,                  |      }&|}'|'dz  dk7  rt/        d      |'dk  r|'dz  }'|'dk  r|'dz  }'d }(d })d}*d}+d},| j0                  }-| j2                  }.|&rt        j4                  dddd|d   j6                  | j6                  z   |-|d   j8                  z
  | j8                  z
        }/|/ |d   z  |/z  }0t;        t        j<                  |0            dz   }1nd}1|-|j8                  z
  | j8                  z
  }2|j6                  | j6                  z   }3|2}4|'dk(  rJ|-|j8                  z
  | j8                  z
  }3|j6                   | j6                  z
  }2|1|*z  }1|.t?        |2      z
  }4n|'dk(  rG|- |j8                  z   | j8                  z   }3|j6                  | j6                  z   }2|1|+z  }1t?        |2      }4nc|'dk(  r^|j6                   | j6                  z
  }3|- |j8                  z   | j8                  z   }2|1|,z  }1t?        |j8                  | j8                  z         }4| j                  jA                  |      }5|5d|5z  }6d}7ndx}6}7| j                  jC                  ||      }8|8d}8nd |8z  }8 |(|6|8|1|3|2||      }9|dkD  r/|9d!|z  z  }9|9t;        ||z        d"z   z  }9||9t;        |      d#z   z  }9|	|9|$z  }9|
|9|%z  }9|9|d   z  }9d}:t        |      dkD  r|9 |)|      z  }9n|9d$z  }9tE        dt        |            D ](  };|4|k  r n!|;dkD  r|9d%z  }9|9||;   d$z   z  }9|4|z  }4|:dz  }:* |9d&|7z  z  }9| xjF                  |9z  c_#        |:S c c}w # t        $ r t        j                          Y yw xY w)'Nr   r   ra  r   r  r  r  r  rm  r  r~   rb  rc  r_     r{  rz  ry  r  r  r   r   r   c                 R    d|  | d| dt        ||f       d| dt        |       dS )N
q
BT
1 0 0 1 z Tm
/r    Tf r  )r  r   r  r  r  r  rH  s          r&   r   z#Shape.insert_text.<locals>.<lambda>2  sE    uQCs$qc)UVXYTZJ[I\\bcdbeefgpqrgsfttx-y r'   c                      dt        |        dS )NzTJ
0 -z TD
r  r   s    r&   r   z#Shape.insert_text.<locals>.<lambda>3  s    WYq\N%8 r'   0 1 -1 0 0 0 cm
0 -1 1 0 0 0 cm
-1 0 0 -1 0 0 cm
 cm
r   r   r   /OC /%s BDC
EMC
r  /%s gs
%i Tr  w  M TJz
T* z
ET
%sQ
)$rl   r   r*  r+  
splitlinesr   r   rh  r   joinordrg  r  r  r
   insert_fontr}  r[   r  r   getTJstr	ColorCode
CheckMorphr   r   r   r,   r-   r.   r  r0   r   _get_optional_contentr  r$  r  )<r  r  r  r  r  r  r  r  r  r   r  r  r  r  r   r  r  r  r   r   r  maxcodefnamerB   r  rk  rm  r  bfnamerb  rc  lheightr{  tabr   rH  	color_strfill_strmorphingrottempl1templ2cmp90cmm90cm180r   r   m1r  r  r  leftspaceoptcontbdcemcrz   nresnlinesr_   s<                                                               r&   r  zShape.insert_text  s   0 F|<e},$$&DD4y1}e$	388D>:a3q6:;G C !"IEyy$$XZ % 
 ((48A;J'(#&!J'[)	+G	!Q&nG(Y"67GS=XX--dGaK@Fh'F 	AA&(BBJJw''1fh?@	A %%eS1	$$T3/q(D((4H%%e,8q=/00Ag3JC AgCiy8##$

 1aE!HJJ,?%PQ(**ATW[W]W]A]^B#a.2%C7++C01G;BBuww'ww"9EGG#dff,D77(TVV#C%KBCH$E CZ7UWW$tvv-D''DFF"C%KBHE CZGG8dff$D'EGG#dff,C%KB$&&()E ))11"5!G+CCNC#		&&.\&J=E&Ec5"dCA?H{**DIlX56>>D&	+.66IDHD
 	Qt9q=F7O#DDLDq#d)$ 	Aw1uDGdN"DWEaKF	 	## 	$g ; 	""$	s$   T 4TT T T:9T:)r  r  r  r  r  r  r   r  r  r  r  r  r  r   r  r  r  r   r  r  c          
        PQ t        j                  |      }|j                  s|j                  rt	        d      t        j
                  |	d      }t        j
                  |
d      }|
|dk(  r|	}
t        j
                  |	d      }| j                  j                  |      }|d|z  }d}ndx}}| j                  j                  ||	      }|d}nd
|z  }|dz  dk7  rt	        d      |}|dk  r|dz  }|dk  r|dz  }t        |      s|dv r|j                  S |j                  S d}d}d}| j                  }|} | j                  d      r| dd } | j                  j                  | |||      }!t        j                  | j                  |!      }"|"d   }#|#d   Q|#d   }$|#d   P|#d   }%|#d   }&|#d   }'|r|}(n|&|'z
  dk  rd}(n|&|'z
  }(|(z  })t!        |      t"        t$        fv rdj'                  |      }*n|}*t)        |*D +cg c]  }+t+        |+       c}+      },|$r4|,dkD  r/dj'                  |*D +cg c]  }+t+        |+      dk  r|+nd c}+      }*|*j-                         }*| j                  j/                  |!|,dz         P|$r|%d vrd}-nP}-PQfd!}.Qdk  rPd"   d   z  }/n}/d}0t        j0                  |      rt        j2                  dddd|d   j4                  | j4                  z   | j                  |d   j6                  z
  | j6                  z
        }1|1 |d   z  |1z  }2t9        t        j:                  |2            d#z   }3nd}3d}4t        j<                  d|&z        }5|dk(  r(|j>                  |5z   }6|j                  }7|j                  }8n|dk(  rFt        j<                  |&z  d      }5|j@                  |5z   }6|j                  }7|j                  }8|3|z  }3n|d$k(  rIt        j<                  d|&z         }5|jB                  |5z   }6|j                  }7d%}4|j                  }8|3|z  }3nHt        j<                  |&z  d       }5|jD                  |5z   }6|j                  }7d%}4|j                  }8|3|z  }3g }9tG        |*      D ]I  \  }:};|;jI                  |      jK                  d&      }<tM        |<      }=d}>|7}?tO        |=      D ]  }@|<|@   }A |.|A      }B|?|Bk\  r|>Ad&z   z  }>|?B|/z   z  }?&|>r)|>jQ                         dz   }>|0|>z  }0|9jS                  d'       d}>|7}?B|7k  rAd&z   }>|7Bz
  |/z
  }?htM        |9      dkD  rd(|9d%<   AD ]9  }+ |.|>      |7 |.|+      z
  k  r|>|+z  }>|>dz  }>|0|>z  }0|9jS                  d(       |+}>; |>d&z  }>|7 |.|>      z
  }? |>r$|0|>jQ                         z  }0|9jS                  d(       |:tM        |*      dz
  k  sE|0dz  }0L |0jU                  d      r|0dd% }0|0jW                  d      dz   }C|)|Cz  |'z  z
  }D|D|8z
  }E|Et         jX                  kD  rd%Ez  S t[        E      }E|Et         jX                  k  rd}Ed)||d*|3z   }Fd+ }G|0j-                         }Hd(|9d%<   tG        |H      D ]?  \  }:}Id}J|7 |.|I      z
  }K|6|5|:|(z  z  z   }L|dk(  rD|dv r Lt        j<                  Kd,z  d      |4z  z   }LnLt        j<                  dKd,z        |4z  z
  }Lnk|d,k(  r>|dv rLt        j<                  Kd      |4z  z   }LnELt        j<                  dK      |4z  z
  }Ln(|d-k(  r#IjW                  d&      }M|MdkD  r|9|:   rKMz  }Jnd}J|Lj6                  z
  | j6                  z
  }N|Lj4                  | j4                  z   }O|dk(  r7|Lj6                  z
  | j6                  z
  }O|Lj4                   | j4                  z
  }Nnx|d.k(  r7| Lj6                  z   | j6                  z   }O|Lj4                  | j4                  z   }Nn<|d$k(  r7Lj4                   | j4                  z
  }O| |Lj6                  z   | j6                  z   }NF GON|       z  }F|dkD  r/Fd/|z  z  }F|Ft9        |z        d0z   z  }F|Ft9        |      d1z   z  }F|d-k(  rFt9        J      d2z   z  }F|	F|z  }F|
F|z  }FFd3t        j\                  I|-|$Q      z  z  }FB Fd4|z  z  }F| xj^                  |Fz  c_/        | ja                  |       ES c c}+w c c}+w )5aQ  Insert text into a given rectangle.

        Args:
            rect -- the textbox to fill
            buffer -- text to be inserted
            fontname -- a Base-14 font, font name or '/name'
            fontfile -- name of a font file
            fontsize -- font size
            lineheight -- overwrite the font property
            color -- RGB stroke color triple
            fill -- RGB fill color triple
            render_mode -- text rendering control
            border_width -- thickness of glyph borders as percentage of fontsize
            expandtabs -- handles tabulators with string function
            align -- left, center, right, justified
            rotate -- 0, 90, 180, or 270 degrees
            morph -- morph box with a matrix and a fixpoint
        Returns:
            unused or deficit rectangle area (float)
        z%text box must be finite and not emptyr  r  Nr   r  r  r   r  r  r   zrotate must be multiple of 90r   )r   r   r  r  r  ra  r   r  rm  r  r{  r~   rb  rc  r_  r   r  r|  ?r  c           	          dk  r+t        | D cg c]  }t        |         d    c}      z  S t        |       z  S c c}w )zCalculate pixel length of x.r   r   )sumr  r   )r-   r  r  r{  rm  s     r&   pixlenz$Shape.insert_textbox.<locals>.pixlen  sF    !|q9!F3q6N1-9:XEE1v(( :s   A     r  r   ri   r   TFr  r  c                 B    dt        | |f       d| dt        |       dS )Nr  z Tm /r   r  r  r  s       r&   r   z&Shape.insert_textbox.<locals>.<lambda>  s+    XiA.?-@aS)TU,W[#\ r'   r]  r   r   r  r  r  z Tw z%sTJ
zET
%sQ
)1r   r   rH   rI   r   r  r
   r  r  rl   r   r   r  r  r}  r[   r   r*  r+  r  r   r  r  r  r  r,   r-   r.   r  r0   rh  r*   r  r+   r2   r  r  splitr   r$  rstripr   endswithr  r  r   r  r  r  )Rr  r    r  r  r  r  r  r  r  r   r  r  r  r  r  r  r   r  r  r  r   r   r  r  r  r  rz   r  r  r  r  r   r  rB   r  rk  r  r  rb  rc  lheight_factorr  r  r  r  	tj_glyphsr  blenr   r	  r  r  progrc_pntr  maxwidth	maxheightjust_tabr_   r   line_t	num_wordslbuffrestr2  wordpl_wlb_counttext_heightmorer  templtext_tr   spacingplr{  spacesr  r
  r{  rm  sR        `                                                                          @@r&   r  zShape.insert_textbox  s	   X ||D!==D,,DEE%%eS1	$$T3/<K1,D((4H))11"5!G+CCNC# 		&&.\&J=E&EB;!<==Ag3JC AgCi F|"%/4;;AtzzA##$C !"IEyy$$XZ % 
 ((48A;J'(#(#&!J'[)	'N	!Q& N%	1N^+ <D%=(6"BBr*!s1v*+gmbAs1v|!4ABB]]_))$!<f$>>II
	) a<":a=8+DDe$1aE!HJJ/uQxzz1IDFF1RB #a.2%C7++C01G;BB
 aH!45!8GGeOEzzHIBYMM(X"5q9EGGeOE{{H

I%KBCZ]]1h&9::EGGeOEzzHE{{I%KB ]]8h#6::EGGeOE{{HE

I%KB
  } 2	GAt__Z066s;FFIED 9% #0ayd|4<TCZ'ED4K'D !LLNT1EEMDOOD)8# 3JE#d?T1D x=1$#(HRL "Ae}6!9(<<
 . !" &-/G#0J &&3r7Q;e2	j ==9D::d#a' (9x+??Y&'//!$;4y'//!D"%u-2\"f% /	PDAqGF1I%B%1~#566Cz(?b1fa 85 @@Caa 85 @@C!(?b! 4u <<Ca 4u <<C!A:(1+ 6kGG355.466)C55466>Dby~.uuftvvow/eedffnvgo.E$UH55DQ;..	,"9:UBB*Ik2U::Dz	'*V33 	! Hw//9fhOOOD_/	Pb 	c!!$] + Bs   c1c"r   r  r  r  even_oddr  c           
         | j                   dk(  ry|dk(  rd}n|d}t        j                  |d      }t        j                  |d      }| j                  j	                  |      }|d|z  | j                   z   | _         d}nd}| j                  j                  ||
      }|d	|z  | j                   z   | _         |d
k7  r&|dk7  r!| xj                   t        |      dz   z  c_         |dk7  rd|z  | j                   z   | _         |dk7  rd|z  | j                   z   | _         |dvrd|z  | j                   z   | _         |	r| xj                   dz  c_         d| _        || xj                   |z  c_         |s| xj                   |z  c_         |.|s| xj                   dz  c_         nY| xj                   dz  c_         nC|s| xj                   dz  c_         n+| xj                   dz  c_         n| xj                   dz  c_         | xj                   |z  c_         t        j                  |      rt        j                  d
ddd
|d   j                  | j                  z   | j                  |d   j                  z
  | j                  z
        }| |d
   z  |z  }t        t        j                  |            dz   | j                   z   | _         | xj                  d| j                   z   dz   z  c_        d| _         d| _        y)zFinish the current drawing segment.

        Notes:
            Apply colors, opacity, dashes, line style and width, or
            morphing. Also whether to close the path
            by connecting last to first point.
        r   Nr   r  r  r  r  r  r  r   z w
z%i J
z%i j
)Nr   z[] 0z%s d
zh
zB
zB*
zf
zf*
zS
r  r  zQ
)r  r   r  r
   r  r  r  r  r  r,   r-   r   r.   r0   r  )r  r   r   r  r  r  r  r1  r  r  r  r  r   r   r  r  r  rz   r	  r  s                       r&   r  zShape.finish  s   , >>RA:E]E %%eS1	$$T3/))11"5,w6GDNCC		&&.\&J'%/$..@DNA:%1*NNi.77Na<%/$..@DNq=%04>>ADN++%.?DNNNe#N"DONNi'NNNh&N NNe+NNNf,NNNe+NNNf,NNNe#N#e$1aE!HJJ/uQxzz1IDFF1RB #a.2%C&w'7'7'<=G$..XDN'DNN2U::r'   r   c                    t        j                  | j                         | xj                  | j                  z  c_        | j                  j                         | _        | j                  rm|r| j                  j                          t         j                  j                  | j                  d|      }| j                  j                  || j                         d| _        d| _        d| _        d| _        d| _        y)zUpdate the page's /Contents object with Shape data.

        The argument controls whether data appear in foreground (default)
        or background.
        rj   Nr   )r   rE   r
   r  r  r  rW   r  r  r[   ro   r  r    r  )r  r   rB   s      r&   r  zShape.commit0  s     	DII&$..(..0>>		'')==11$))T7KDHH""48	r'   T)r]  )r   r   Nr   r   NFNTr   r   r   )'__name__
__module____qualname____doc__staticmethodr  r   r   r  r  r   rh  r  r*  r3  r?  typingUnionr	   r   r9  r  r7  r<  rl   rD  r*  r.  r%  r"  rQ   OptFloatOptStrr   OptSeqr  r  r  r  r   r'   r&   r  r  k  s    &W\\ (7*J J 7== D W]]   	
  
.v||Iy,@A gmm 0C* Ce C C00 0 	0
 
0(  HH H 	H
 H 
HT 48 1i 1GMM 1fBi BGMM B 	  	
 
B 	## #
 
#Z #" !)xx S$Y'x
 x x x x x x x x x x x  !x" #x$ %x& 'x( )x* 
+xD "#" !-BB S$Y'B
 B B B B B B B B B B B  !B" #B$ %B& 'B( )B* +B, -B. 
/BL
  !YY Y 	Y
 Y Y Y Y Y Y Y Y Y 
Yvd d r'   r  imagesgraphicsc           	      <   d }t        j                  |        | j                  }|j                  s|j                  rt        d      |j                  st        d      g }| j                  t         j                  f      D ]!  }|j                  |j                                # |g k(  ry| j                  |||      }|st        d      | j                         }	|D ]  }
|
d   }|
d   }|r$|	j                  |       |	j                  ||	       d
|
j                         v sF|
d
   }|
j!                  dd      }|
d   }|
d   }|
d   } |||||      }d}|dk  s|dk\  s|	j#                  ||||||      }|dz  }|dk  s|dk\  r( |	j%                          y)a  Apply the redaction annotations of the page.

    Args:
        page: the PDF page.
        images:
              0 - ignore images
              1 - remove all overlapping images
              2 - blank out overlapping image parts
              3 - remove image unless invisible
        graphics:
              0 - ignore graphics
              1 - remove graphics if contained in rectangle
              2 - remove all overlapping graphics
        text:
              0 - remove text
              1 - ignore text
    c                    |r| j                   t        j                  k  r| S 	 t        j                  |||      }|dz  }| j                   }t        j                  ||z        |z  }|| j                  k\  r| S | }| j                  j                  | j                  j                  z   |z
  dz  }	|	|_        |S # t        t
        j                  f$ r t        rt        j                          | cY S w xY w)a  Calculate minimal sub-rectangle for the overlay text.

        Notes:
            Because 'insert_textbox' supports no vertical text centering,
            we calculate an approximate number of lines here and return a
            sub-rect with smaller height, which should still be sufficient.
        Args:
            annot_rect: the annotation rectangle
            new_text: the text to insert.
            font: the fontname. Must be one of the CJK or Base-14 set, else
                the rectangle is returned unchanged.
            fsize: the fontsize
        Returns:
            A rectangle to use instead of the annot rectangle.
        r_  r   )r   r   r  get_text_lengthr   r   r  r  r  r  ceilr   r*   r.   r  r   )

annot_rectnew_textrh  fsize
text_widthline_heightrj  hr   r.   s
             r&   center_rectz%apply_redactions.<locals>.center_rect^  s      :++w>	 004GJ
 ck  IIj5()K7
!!!]]__z}}.2c9 E--. 	#&&(	s   B5 55C-,C-r  r;   )typesFzError applying redactions.r    r  )r  r   r   r  r   r  r  
text_colorri   r>   )r  r  r   r  r   T)r   rE   rF   r  r  r   rG   rN  PDF_ANNOT_REDACTr   _get_redact_values_apply_redactionsr  r*  r  rv  rT   r  r  )r
   r@  rA  r   rL  r[   redact_annotsr  r   shaperedactrF  r  rG  r  r  rH  r   trects                      r&   apply_redactionsrV  I  s   * D 
++C
3==788::%%M'')   9 	U5578	9 			fh	7B566 NNE F^
f~OOJ'LLd$L/V[[]"f~HJJw*E:&E:&E<(E
HeUCEBq&UaZ))"" *   q&UaZ!6 
LLNr'   attached_filesclean_pagesembedded_fileshidden_text
javascriptmetadata
redactionsredact_imagesremove_linksreset_fieldsreset_responses
thumbnailsxml_metadatac                 j   d }| j                   st        d      | j                  s| j                  rt        d      |sd}d}|r| j	                  i        | D ]  }|
r%|j                         D ]  }|j                           |	r(|j                         }|D ]  }|j                  |        d}|j                         D ]k  }|j                  d   t        j                  k(  r|r|j                  d       |r|j                          |j                  d   t        j                   k(  sjd}m |r|r|j#                  |	       |s|s|j%                          |j'                         s|r_|j'                         d   }| j)                  |      } ||j+                               }|r#d
j-                  |      }| j/                  ||       |sw| j1                  |j2                  d      d   dk7  s| j5                  |j2                  dd        |r&| j7                         D ]  }| j9                  |        |r| j;                          |s|sd}n| j=                         }t?        d|      D ]  }| jA                  |      sd|z  }t        |      |r-| j1                  |d      d   dk(  rd}| jC                  ||       S|sV| j1                  |d      d   dk(  r'| jC                  |d       | j/                  |dd       | j1                  |d      d   dk7  s| j5                  |dd        y )Nc                 H   g }d}d}d}| D ]  }|dk(  rd}|j                  |       |dk(  rd}|j                  |       5|dk(  rd}d}?|dd dk(  r|d	   d
k7  rd}|j                  |       c|dk(  rd}|j                  |       ||r|r|j                  |        |r|S y)a_  Remove hidden text from a PDF page.

        Args:
            cont_lines: list of lines with /Contents content. Should have status
                from after page.cleanContents().

        Returns:
            List of /Contents lines from which hidden text has been removed.

        Notes:
            The input must have been created after the page's /Contents object(s)
            have been cleaned with page.cleanContents(). This ensures a standard
            formatting: one command per line, single spaces between operators.
            This allows for drastic simplification of this code.
        Fs   BTTs   ETs   3 TrNs   Trr      3   Qr   )
cont_lines	out_linesin_textsuppressmake_returnr   s         r&   remove_hiddenzscrub.<locals>.remove_hidden  s      	 	#Du}  &u}  &w"BCyE!d1go   &t|   &GT"/	#0 r'   r;   zclosed or encrypted docFr   rj   )r  T)r@     
Thumbr  r   z(bad xref %i - clean PDF before scrubbingrZ  z/JavaScriptz<</S/JavaScript/JS()>>Typez	/Metadatar  s   deleted)rR  Metadata)"rG   r   r  r  r  widgetsresetr  delete_linkrN  r   r   PDF_ANNOT_FILE_ATTACHMENTupdate_filedelete_responsesr   rO  rV  clean_contentsrK   xref_streamr  r  ro   r  rB   r  embfile_namesembfile_deldel_xml_metadataxref_lengthr$  xref_objectr  )r[   rW  rX  rY  rZ  r[  r\  r]  r^  r_  r`  ra  rb  rc  ro  r
   rF  r  r  found_redactsr  rB   contrj  r~   
xref_limitr  r  s                               r&   scrubr    s    /b ::%%
3==233
 '=,,.  NN$E '  &' [[] 	%Ezz!} ? ??N!!!.&&(zz!} 8 88 $	% -!!!7{  "$$&q)D??4(D&t'89Jzz*-!!$-		73A6&@  GV<O'=V %%' 	"DOOD!	" J
__&
a$ 7t$<tCCS/!#**45a8MI*CdC(D&)!,;dF+dJD9D*-a0F:T:v6)7r'   c                     d}d}| j                   j                  }	 |sn!|dz  }||j                  z  }|j                  }$d| d| S )Nr   r   z
num_spans=z num_chars=)r  headr   r  )r   	num_spans	num_charsspans       r&   _show_fz_textr  S  s`    
 II??D
Q	TXX	yy  	{+i[99r'   r%   posrh  warnright_to_left
small_capsc                 Z	   
%&'( t        j                  |      }|j                  rt        d      t	              t         j
                  urt        j
                  d      
fd(
fd&
 fd%dz  } (d      }|j                  |z
  '|j                  |z   }&fd}%'(fd	}j                  }j                  }|s||z
  d
k  rd}n||z
  }n|}|z  }'}|t        j                  |      }n|j                  ||z  fz   }||vrt        d      |t         j                  k(  rd}n|t         j                  k(  rd}nd}t	        |      t        u r|j                         }n(g }|D ]!  }|j!                  |j                                # t#        |j$                  |j&                  z
  |z        d
z   }g }g }t)        |      D ]e  \  }}|dv r@|j+                  ||f       |j                  |z
  }|j+                  t-        |      d
z
         K|dk(  r|j.                  |j0                  z
  }n|j                  |z
  }|	r j3                  |      } (|      }||k  r1|j+                  ||f       |j+                  t-        |      d
z
         |j5                  d      } |||      \  }}t-        |      }	 dj7                  |d|       } t9        |d|       ||d
z
  z  z   }!|!|k  r+|j+                  | |!f       ||d }||d }t-        |      }d} n|d
z  }t-        |      dk(  rc|sJ u t-        |      }"|"|kD  r0d||"fz  }#|n&|rt        j:                  d|#z          nt        |#      t        j                         }$|t-        |      d
z
  gz  }t=        |      D ]  }	 |j?                  d      \  }}|	rdj7                  tG        |            }|dk(  r|}$|t         jH                  k(  r/||vr+|'k  r& ||$|       ||$_        |$xj&                  |z  c_        }|dkD  s|j0                  |k(  r|$xj0                  ||z
  |z  z  c_         %|$|       ||$_        |$xj&                  |z  c_         |S # t@        $ r" tB        dk\  rt        jD                          Y  |S w xY w)aI  Fill a rectangle with text.

    Args:
        writer: pymupdf.TextWriter object (= "self")
        rect: rect-like to receive the text.
        text: string or list/tuple of strings.
        pos: point-like start position of first word.
        font: pymupdf.Font object (default pymupdf.Font('helv')).
        fontsize: the fontsize.
        lineheight: overwrite the font property
        align: (int) 0 = left, 1 = center, 2 = right, 3 = justify
        warn: (bool) text overflow action: none, warn, or exception
        right_to_left: (bool) indicate right-to-left language.
    zfill rect must not empty.r  c                 ,    j                  |       S )zReturn length of a string.r  r  )text_lengthr-   rh  r  r  s    r&   textlenzfill_textbox.<locals>.textlen  s"    Z   
 	
r'   c                 ,    j                  |       S )z5Return list of single character lengths for a string.r  )char_lengthsr  s    r&   r  z"fill_textbox.<locals>.char_lengths  s      X* MMr'   c                 4    j                  | |      }|S )N)rh  r  r  ri  )r  r   retrh  r  r  r%   s      r&   append_thisz!fill_textbox.<locals>.append_this  s(    mmTxJ   
r'   g?r   c                 l   g }g }|D ]  } |      }t        |      }|| k  r#|j                  |       |j                  |       >t        |      }|dkD  sOt        |d|       }|| k  r;|j                  |d|        |j                  |       ||d }||d }t        |      }n|dz  }|dkD  rY ||fS )z.Cut any word in pieces no longer than 'width'.r   Nr   )r  r   r   )	r   r   r   word_lengthsr   wl_lstwlra   r  s	           r&   
norm_wordsz fill_textbox.<locals>.norm_words  s     	A!!_FVBU{a ##B' FAa%_;MM!BQ%( ''+!"A#ABZFFAFA a%	( |##r'   c                 N   |j                  d      D cg c]
  }|dk7  s	| }}t        |      }|dk(  ry|dk(  r 
| |d          yt        |D cg c]
  } |       c}      }|dz
  }|z
  |z  }|D ]"  } 
| |      \  }}	|	j                  |z   | _        $ yc c}w c c}w )zJustified output of a line.r   r   r   Nr   )r  r   r  r-   )startr   r   r   r   r*   gapsgaplr   r  r  	std_widthr  s             r&   output_justifyz$fill_textbox.<locals>.output_justify  s     !JJsO7qqBw77UQ;Q;uQx(e,'!*,-zB$& 	"Aq)EArddTkEG	" 	 8 -s   
BBB"r   r_  NzText must start in rectangle.r   r  r   )r   r   zOnly fitting %i of %i lines.z	Warning: r]  r   )%r   r   rH   r   r   ra  r   r   rb  rc  rh  r*   TEXT_ALIGN_CENTERTEXT_ALIGN_RIGHTrQ   r  r   r   r   r.   r  r   r   r   r-   	clean_rtlr  r  r  r  r$  pop
IndexErrorr  r  reversedTEXT_ALIGN_JUSTIFY))r%   r    r   r  rh  r  r  r  r  r  r  r   	space_len	std_startr  r  rf  rg  r  
LINEHEIGHTr   factor	textlinesr   	max_lines	new_lines
no_justifyr_   r*   r   r  ra   line0r  r  r  r  r  r  r  r  s)   `   ``    `                          @@@@r&   fill_textboxr  c  s   6 <<D}}455Dz%||F#
N 3II

Y&I)#I$4$ --C
..C9>GCiGG#JE mmC ggHsN33
$899 )))	'**	* DzSOO%		 	0DT__./	0 TWWsuu_
23a7IIJY' (49dI./JJ*Es9~136GGceeOEJJ*E##D)DT];dBZ(s9~13 

3 )6|JHHU2AY'E\"1%&a!e)<<BU{  %-ab	+AB/JQ5zQH 5(^ ^F	,	6/BB<OOK#-.S/!MMOE3y>A%&&J9 	 }}Q'HD"
 778D>*D6EG...1J3F2PY>5$'EGGGz!Gq5CEEY&GG
f,,GE4 :14 /  	#q(G,B,B,D* /	s   .Q??&R*)R*c                    | j                   s| j                  rt        d      | j                  |d      \  }}|dk7  s|dvrt        d|z        | j                  |d      \  }}|dk7  ryt	        |j                  d	d
            }|S )zReturn optional content object xref for an image or form xobject.

    Args:
        xref: (int) xref number of an image or form xobject.
    document close or encryptedSubtyper~   z/Imagez/Formbad object type at xref %iOCrB   r   r  r   )r  r  r   r  r   rr  )r[   rB   r   r~   r   r   s         r&   get_ocr  I  s     }}((677tY/GAtF{d"555<==T4(EArF{	RZZr"	#BIr'   c                    | j                   s| j                  rt        d      | j                  |d      \  }}|dk7  s|dvrt        d|z        |dkD  r,| j                  |d      \  }}|dk7  s|dvrt        d|z        |dk(  r'd	| j	                  |      v r| j                  |d	d
       y| j                  |d	d|z         y)zAttach optional content object to image or form xobject.

    Args:
        xref: (int) xref number of an image or form xobject
        oc: (int) xref number of an OCG or OCMD
    r  r  r~   r  r  r   rr  )z/OCGz/OCMDr  r  Nr  )r  r  r   r  xref_get_keysr  )r[   rB   r   r   r~   s        r&   set_ocr  [  s     }}((677tY/GAtF{d"555<==	Av""2v.4;$&779B>??	Qw43,,T22tV,T4B/r'   ocgspolicyvec                   	
 t        | j                         j                               		
fd
d}|rst        |      t        t
        fv r\t        |      j                  	      }|t               k7  rd|z  }t        |      |ddj                  t        d |            z   dz   z  }|r=t        |      j                         }dd	d
dd}|dvrt        d|z        |d||   z  z  }|r|d 
|      z  z  }|dz  }|dk(  r| j                         }n d| j                  |d      vrt        d      | j                  ||       |S )a  Create or update an OCMD object in a PDF document.

    Args:
        xref: (int) 0 for creating a new object, otherwise update existing one.
        ocgs: (list) OCG xref numbers, which shall be subject to 'policy'.
        policy: one of 'AllOn', 'AllOff', 'AnyOn', 'AnyOff' (any casing).
        ve: (list) visibility expression. Use instead of 'ocgs' with 'policy'.

    Returns:
        Xref of the created or updated OCMD.
    c                    t        |       t        t        fvst        |       dk  rt	        d| z        | d   j                         dvrt	        d| d   z        | d   j                         dk(  rt        |       dk7  rt	        d| z        d| d   j                         z  }| dd  D ]<  }t        |      t        u r|vrt	        d	|z        |d
|z  z  }/|d |      z  z  }> |dz  }|S )Nr]  zbad 've' format: %sr   )andornotzbad operand: %sr  z[/%sr   z
bad OCG %iz %i 0 Rz %sr  )r   r*  r+  r   r   r?  r  r   )r  r'  r-   all_ocgsve_makers      r&   r  zset_ocmd.<locals>.ve_maker  s    8D%=(CGaK2R788a5;;= 44.A677a5;;=E!c"gl2R7881%AB 	,AAw#~H$$\A%566	A%++	, 	r'   z<</Type/OCMDzbad OCGs: %s/OCGs[r   c                     d| z  S )Nr  r   r-   s    r&   r   zset_ocmd.<locals>.<lambda>  s
    (Q, r'   r  AnyOnAllOnAnyOffAllOff)anyonallonanyoffalloffzbad policy: %sz/P/%sz/VE%sr  r   
/Type/OCMDT
compressedzbad xref or not an OCMD)r  get_ocgsrv  r   r*  r+  r  r   r  r  rQ   r?  r  r  r  )r[   rB   r  r  r  r   r  r  polsr  r  s            @@r&   set_ocmdr  r  sU   & 3<<>&&()H$ DT
tUm+I  *: 1$CS/!388C(>$EFFLLV""$	
 ??-677$v,&&	(2,&&DLD qy!	S__Td_C	C233dD!Kr'   c                    |t        | j                               vrt        d      | j                  |d      }d|vrt        d      t	        |      }|j                  d      }|j                  d|      }|dk  s|dk  rd	}n?||d
z   | j                  dd      j                         }t        t        t        |            }|j                  d      }|dk  rd	}nD|j                  d|      }|dk  r|j                  d|      }|dk  rt        d      ||dz   |dz    }|j                  d      }|dk  rd	}ndx}	}
|}|	dk  s|	|
k7  r;|dz  }||k  st        d      ||   dk(  r|	dz  }	||   dk(  r|
dz  }
|	dk  r5|	|
k7  r;||dz   |dz    }|j                  dd      j                  dd      j                  dd      }|j                  dd      j                  dd      j                  dd       }dd	l}	 |j                  |      }||||d"S # t        $ r. t        j                          t        j                   d!|        w xY w)#at  Return the definition of an OCMD (optional content membership dictionary).

    Recognizes PDF dict keys /OCGs (PDF array of OCGs), /P (policy string) and
    /VE (visibility expression, PDF array). Via string manipulation, this
    info is converted to a Python dictionary with keys "xref", "ocgs", "policy"
    and "ve" - ready to recycle as input for 'set_ocmd()'.
    zbad xrefTr  r  zbad object typer  r  r   NrR  r  r   z/P/ffonzbad object at xrefr   r]  z/VE[r   [z/Andz"and",z/Notz"not",z/Orz"or",z 0 R] 0 R,z][z],[zbad /VE key: )rB   r  r  r  )r$  r  r   r  r   findrr  r  r*  r  r   r3  loadsrg  r   r  r  )r[   rB   r   r  p0r   r  r  r  r  rpr3  s               r&   get_ocmdr    sn    5*++$$??4D?1D4*++$iG	8	B	3	B	AvaBFR ((4::<CTN#	5	B	AvYYtR 64$B6122"q&26*F	6	B	AvR1fb!GB< !566Bx3aBx3a 1fb "q&26"JJvx(WVX&WUG$ 	
 ZZ%--fc:BB4O	BB
 $&CC	  	""$OOmB623	s   8H 7Ic                 f   | \  }}|dd j                  d      dd }|ddd}d}t        |      D ]~  \  }} |rd}| d	k(  r||dz      |d
<   d}| j                  d      r+| dd j                  dd      j                  dd      }||d<   Z| j                  d      slt	        | dd       }||d<    |S )a"  Make a Python dict from a PDF page label rule.

    Args:
        item -- a tuple (pno, rule) with the start page number and the rule
                string like <</S/D...>>.
    Returns:
        A dict like
        {'startpage': int, 'prefix': str, 'style': str, 'firstpagenum': int}.
    r]  rf  ra  r   Nr   )	startpageprefixfirstpagenumFrZ  styleTrt  ()r  Str  )r  r  r  rr  r   )r'  rZ   ruler  skipr_   r-   s          r&   	rule_dictr    s     IC":C $DR;ADT? "4D3;a!eAgJD??3QR  b)11#r:AAhK??4 DHA !An" Hr'   c                     |D cg c]  }|d   | k  s| c}d   }t        |      }|j                  dd      }|j                  dd      }|dv rdnd}| |d   z
  |d   z   |z   }t        |||      S c c}w )	zReturn the label for this page number.

    Args:
        pgNo: page number, 0-based.
        labels: result of doc._get_page_labels().
    Returns:
        The label (str) of the page number. Errors return an empty string.
    r   ri   r  r   r  )r  Ar  r  )r  rT   construct_label)	pgNolabelsr-   r'  r  r  r  rV  
pagenumbers	            r&   get_label_pnor  4  s     .!1A.r2DT?DXXh#FHHWb!E:%B1E[))D,@@5HJ5&*55 /s
   A2A2c                     | j                   j                         }|sy|j                          t        | j                  |      S )zReturn the label for this PDF page.

    Args:
        page: page object.
    Returns:
        The label (str) of the page. Errors return an empty string.
    r   )rF   _get_page_labelsr   r  rN   )r
   r  s     r&   	get_labelr  I  s6     [[))+F
KKMf--r'   c                     g }|s|S | j                         }|g k(  r|S t        | j                        D ]*  }t        ||      }||k(  s|j	                  |       |s) |S  |S )a  Return a list of page numbers with the given label.

    Args:
        doc: PDF document object (resp. 'self').
        label: (str) label.
        only_one: (bool) stop searching after first hit.
    Returns:
        List of page numbers having this label.
    )r  r$  rJ   r  r   )r[   labelonly_onenumbersr  r_   plabels          r&   get_page_numbersr   Z  st     G!!#F|3>>" q&)U?NN1N Nr'   c                 ,   d}| dk(  rt        |      }n{| dk(  rt        |      j                         }n\| dk(  rt        |      j                         }n=| dk(  rt	        |      j                         }n| dk(  rt	        |      j                         }||z   }|S )z9Construct a label based on style, prefix and page number.r   Dr   r  r  r  )rQ   integerToRomanr?  rR  integerToLetter)r  r  rZ   n_strresults        r&   r  r  u  s     E|C	#s#))+	#s#))+	#$**,	#$**,e^FMr'   c           
      \   ddl }|j                  }d| }}t        d|      |k  r7|t        t	        j                  d|            z  }|dz  }t        d|      |k  r7d}t        t        |            D ]8  }t        |t        t	        j                  d|                  \  }}|||   z  }|}: |S )z-Returns letter sequence string for integer i.r   Nr      r   )stringascii_uppercasepowr   r  r  r$  divmod)	r_   r	  lsra   r  str_tr2  r  rH  s	            r&   r  r    s     			BaqA
b!*/	S"a!!	Q b!*/ EeAh aTXXb!_-.1A Lr'   numc                 f    dfd}dj                   ||       D cg c]  }| c}      S c c}w )z$Return roman numeral for an integer.))i  M)i  CM)i  r  )i  CD)rQ  r  )r   XC)r  L)(   XL)
   X)	   IX)r   rT  )r>   IV)r   Ic              3   l   K   D ]*  \  }}t        | |      \  }}||z   | ||z  z  } | dk  s* y  y wr   )r  )r  r   ltrr-   r   romans        r&   	roman_numz!integerToRoman.<locals>.roman_num  sI      	FAs#q>DAq'M1q5LCax	s   ,44r   )r  )r  r!  r  r   s      @r&   r  r    s2    E  77y~.!A.//.s   	.c                 Z    | j                         D cg c]  }t        |       c}S c c}w )zReturn page label definitions in PDF document.

    Args:
        doc: PDF document (resp. 'self').
    Returns:
        A list of dictionaries with the following format:
        {'startpage': int, 'prefix': str, 'style': str, 'firstpagenum': int}.
    )r  r  )r[   r'  s     r&   get_page_labelsr#    s%     ),(<(<(>?IdO???s   (c                 D    d fd}| j                   ||             y)a  Add / replace page label definitions in PDF document.

    Args:
        doc: PDF document (resp. 'self').
        labels: list of label dictionaries like:
        {'startpage': int, 'prefix': str, 'style': str, 'firstpagenum': int},
        as returned by get_page_labels().
    c                     d| d   z  }| j                  dd      dk7  r|d| d   z  z  }| j                  dd      dk7  r|d| d   z  z  }| j                  dd	      d	kD  r|d
| d   z  z  }|dz  }|S )zConvert Python label dict to corresponding PDF rule string.

        Args:
            label: (dict) build rule for the label.
        Returns:
            PDF label rule string wrapped in "<<", ">>".
        z%i<<r  r  r   z/P(%s)r  z/S/%sr  r   z/St %ir  )rT   )r  r  s     r&   create_label_strz)set_page_labels.<locals>.create_label_str  s     U;''99Xr"b(E(O++A99Wb!R'5>))A99^Q'!+E.111A	T	r'   c                     | j                  d        dj                  | D cg c]
  } |       c}      }|S c c}w )a  Return concatenated string of all labels rules.

        Args:
            labels: (list) dictionaries as created by function 'rule_dict'.
        Returns:
            PDF compatible string for page label definitions, ready to be
            enclosed in PDF array 'Nums[...]'.
        c                     | d   S )Nr  r   r  s    r&   r   z6set_page_labels.<locals>.create_nums.<locals>.<lambda>  s
    !K. r'   r   r   )r   r  )r  r  r  r&  s      r&   create_numsz$set_page_labels.<locals>.create_nums  s>     	01GG&A%e,AB Bs   <N)_set_page_labels)r[   r  r)  r&  s      @r&   set_page_labelsr+    s"    $ V,-r'   c                     | j                   rt        d      | j                  st        d      t        | j                        D ]1  }| j                  |      D ]  }|d   t        j                  k(  s  y 3 y)z*Check whether there are links on any page.r  r;   r   TF)r  r   rG   r$  rJ   page_annot_xrefsr   r  r[   r_   r'  s      r&   	has_linksr/    ss    
}}*++::%%3>>" ((+ 	DAw'000	 r'   c                     | j                   rt        d      | j                  st        d      t        | j                        D ]H  }| j                  |      D ]2  }|d   t        j                  k(  r|d   t        j                  k(  r1  y J y)z0Check whether there are annotations on any page.r  r;   r   TF)	r  r   rG   r$  rJ   r-  r   r  r}  r.  s      r&   
has_annotsr1    s    
}}*++::%%3>>" ((+ 	DGw555aGD\D\9\	
 r'   line_dirr  r
  c                 R   | |d   } | \  }}t        j                  |      }t         j                  j                         rd}n|d   |d   z
  }||d   z  }||z  }||z  }|dk\  rJ|dk  rE|j                  d|fz
  }	|j
                  |dfz   }
|j                  |dfz
  }|j
                  d|fz   }n|dk  rJ|dk  rE|j                  |dfz   }	|j                  d|fz
  }
|j                  d|fz   }|j                  |dfz
  }n|dk  rJ|dk\  rE|j
                  d|fz
  }	|j                  |dfz   }
|j
                  |dfz
  }|j                  d|fz   }nD|j                  |dfz   }	|j                  d|fz
  }
|j                  d|fz   }|j                  |dfz
  }t        j                  |	|
||      S )a  Compute the quad located inside the bbox.

    The bbox may be any of the resp. tuples occurring inside the given span.

    Args:
        line_dir: (tuple) 'line["dir"]' of the owning line or None.
        span: (dict) the span. May be from get_texttrace() method.
        bbox: (tuple) the bbox of the span or any of its characters.
    Returns:
        The quad which is wrapped by the bbox.
    dirr   rb  rc  sizer   )	r   r   r  set_small_glyph_heightsr  r2   r+   r*   r/  )r2  r  r
  r  r  r  r   hshcr  r  r  r  s                r&   recover_bbox_quadr9    s    ;HC<<D}},,.tK00fF 
#B	#B	Qw27WW2wWWAwWWAwWW2w	qR1WWWAwWW2wWW2wWWAw	qR1WWW2wWWAwWWAwWW2wWWAwWW2wWW2wWWAw<<BB''r'   c                     t        |       t        ust        |       dk7  rt        d      t        |      t        urt        d      t        | ||d         S )zRecover the quadrilateral of a text span.

    Args:
        line_dir: (tuple) 'line["dir"]' of the owning line.
        span: the span.
    Returns:
        The quadrilateral enveloping the span's text.
    r]  bad line dir argumentbad span argumentr
  )r   r+  r   r   r	  r9  )r2  r  s     r&   recover_quadr=  F  sR     H~U"c(mq&8011Dz,--XtT&\::r'   r   spansc           	      &   || d   }t        |      dk(  rt        d      | d   }|\  }}t        ||d         }t        |      dkD  rt        ||d         }n|}|j                  }|j                  }t        j                  ||      }	||	z  }
t
        j                  j                         }t        |D cg c]  }|d   |rdn
|d   |d	   z
  z   c}      }t        j                  d| |
j                  d      }|j                  }||	 z  }|S c c}w )
a  Calculate the line quad for 'dict' / 'rawdict' text extractions.

    The lower quad points are those of the first, resp. last span quad.
    The upper points are determined by the maximum span quad height.
    From this, compute a rect with bottom-left in (0, 0), convert this to a
    quad and rotate and shift back to cover the text of the spans.

    Args:
        spans: (list, optional) sub-list of spans to consider.
    Returns:
        pymupdf.Quad covering selected spans.
    r>  r   zbad span listr4  r   ri   r5  rb  rc  )r   r   r=  r  r  r   planish_liner  r6  r   r   r-   r,  )r   r>  r2  r  r  q0r  line_llline_lrmat0x_lrsmallr  rK  	line_rect	line_quads                   r&   recover_line_quadrI  V  s    }W
5zQ))E{HHC	ha	)B
5zA~(E"I.eeGeeG1D T>DMM113EQVWA65aq}q~'E	GW	A QDFFA.II$I 	Xs   4Dcharsc                    | |d   } |t        | |      S d|j                         vrt        d      t        | ||d         }t	        |      dkD  rt        | ||d         }n|}|j
                  }|j                  }t        j                  ||      }||z  }t        j                  j                         }	|d   |	rdn
|d   |d	   z
  z  }
t        j                  d|
 |j                  d      }|j                  }|| z  }|S )
a^  Calculate the span quad for 'dict' / 'rawdict' text extractions.

    Notes:
        There are two execution paths:
        1. For the full span quad, the result of 'recover_quad' is returned.
        2. For the quad of a sub-list of characters, the char quads are
           computed and joined. This is only supported for the "rawdict"
           extraction option.

    Args:
        line_dir: (tuple) 'line["dir"]' of the owning line.
        span: (dict) the span.
        chars: (list, optional) sub-list of characters to consider.
    Returns:
        pymupdf.Quad covering selected characters.
    r4  rJ  z)need 'rawdict' option to sub-select charsr   r   ri   r5  rb  rc  )r=  rv  r   recover_char_quadr   r  r  r   r@  r  r6  r   r-   r,  )r2  r  rJ  rA  r  span_llspan_lrrD  rE  rF  rK  	span_rect	span_quads                r&   recover_span_quadrQ    s   " ;}Hd++diik!DEE	8T58	4B
5zA~xuRy9eeGeeG1DT>DMM113EVUj)9D<M)MOAQDFFA.II$Ir'   charc                 t   | |d   } t        |       t        ust        |       dk7  rt        d      t        |      t        urt        d      t        |      t        u rt        j                  |d         }n5t        |      t        u rt        j                  |d         }nt        d      t        | ||      S )aD  Recover the quadrilateral of a text character.

    This requires the "rawdict" option of text extraction.

    Args:
        line_dir: (tuple) 'line["dir"]' of the span's line.
        span: (dict) the span dict.
        char: (dict) the character dict.
    Returns:
        The quadrilateral enveloping the character.
    r4  r]  r;  r<  r
  r   )r   r+  r   r   r	  r   r   r9  )r2  r  rR  r
  s       r&   rL  rL    s     ;H~U"c(mq&8011Dz,--DzT||DL)	du	||DG$,--XtT22r'   verbosefallbackc                 ~    |sHt        j                         }t        j                  |t        t	         j
                                     yi  fd} fd} fd}d }fd}fd}	 |        s|rt        j                  d       y	d	}
d	}j                         D ]  }|
t        |      z  }
  D ]  }|j                         D ]o  }t        |      t        ur|d
   dd } |	|      }|(|   \  }}\  }}|d   D ]*  }|j                  |d	          |j                  |d          , ||||ff|<   q  j                         D ]  \  }\  }}} |||d	   |d         }t        |      d	   }|t        |      t        |      k\  r|rt        j                  d|d       ]|rt        j                  d|d        j                  |      }|d	   } ||        j!                  |d      }|D ].  } ||      \  }} j#                  ||       |s|s% ||||       0 |t        |      z  } |
|z
  S )at  Build font subsets in a PDF.

    Eligible fonts are potentially replaced by smaller versions. Page text is
    NOT rewritten and thus should retain properties like being hidden or
    controlled by optional content.

    This method by default uses MuPDF's own internal feature to create subset
    fonts. As this is a new function, errors may still occur. In this case,
    please fall back to using the previous version by using "fallback=True".
    Fallback mode requires the external package 'fontTools'.

    Args:
        fallback: use the older deprecated implementation.
        verbose: only used by fallback mode.

    Returns:
        The new MuPDF-based code returns None.  The deprecated fallback
        mode returns 0 if there are no fonts to subset.  Otherwise, it
        returns the decrease in fontsize (the difference in fontsize),
        measured in bytes.
    Nc                    j                  | d      }|d   dk7  ryt        |d   dd j                  dd            }j                  |d	      }|d   dk7  rd
}n|d   }j                  |d      }|d   dk7  rd
}||fS |d   }||fS )z(Retrieve old font '/W' and '/DW' values.DescendantFontsr   arrayNNr   ri   r  r   WNDWr   )r  r   rr  )rB   dfdf_xrefwidthsdwidthsr[   s        r&   get_old_widthsz$subset_fonts.<locals>.get_old_widths  s    d$56a5GbeAbk))%45!!'3/!9FAYF""7D11:G w ajGwr'   c                    j                  | d      }|d   dk7  ryt        |d   dd j                  dd            }t        |      t        us|s,j                  |d	      d   d
k7  rj                  |d	d
       nj                  |d	|       t        |      t        us|s,j                  |d      d   d
k7  rj                  |dd
       yj                  |d|       y)zRestore the old '/W' and '/DW' in subsetted font.

        If either parameter is None or evaluates to False, the corresponding
        dictionary key will be set to null.
        rX  r   rY  Nr   ri   r  r   r[  r  r\  )r  r   rr  r   rQ   r  )rB   r_  r`  r]  r^  r[   s        r&   set_old_widthsz$subset_fonts.<locals>.set_old_widths  s     d$56a5GbeAbk))%45L#6s7G7GQT7U8
8 Wc62Wc62M$G9I9IT:

:: WdF3  WdG4r'   c                 T   ddl }ddl}dj                  |j                  t	        |j
                        d            dz   }
j                  | d      }|j                  d	d	|z         }
j                  | d
      }|d   dk(  rt        |d   dd j                  dd            }
j                  |d      }|d   dk(  rXt        |d   j                  dd            }
j                  |d      }	|	j                  dd|z         }	
j                  ||	       
j                  | |       y)a  Generate a name prefix to tag a font as subset.

        We use a random generator to select 6 upper case ASCII characters.
        The prefixed name must be put in the font xref as the "/BaseFont" value
        and in the FontDescriptor object as the '/FontName' value.
        r   Nr   rR  )r  +Tr  z
/BaseFont/rX  rY  r   ri   r  FontDescriptorrB   z
/FontName/)randomr	  r  choicesr+  r
  r  rr  r  r   r  )rq   rg  r	  r  font_strr]  r^  fdfd_xreffd_strr[   s             r&   set_subset_fontnamez)subset_fonts.<locals>.set_subset_fontname  s    	f.D.D(EKLsR??8?=##L,2GHh(9:a5G"Q%"+--eR89G!!'+;<B!ubemmE267TBlV6KL!!'62(H-r'   c           	         	 ddl m} ddl}|j                         5 }| d}| d}| d}|dd| d	d
dddg}	t        | ddd      5 }
d|v rL|	j                  d|        |j                  d       t        |      }|D ]  }|
j                  d|z          nK|	j                  d|        |j                  d       t        |      }|D ]  }|
j                  d|z          ddd       t        |d      5 }|j                  |        ddd       	 t        j                  |       	 |j#                  |	       t	        j$                  |      }|j&                  }|j(                  dk(  rd}ddd       |S # t        $ r1 t        rt	        j
                          t	        j                  d        w xY w# 1 sw Y   xY w# 1 sw Y   xY w# t         $ r Y w xY w# t         $ r t	        j
                          d}Y w xY w# 1 sw Y   S xY w)a
  Build font subset using fontTools.

        Args:
            buffer: (bytes) the font given as a binary buffer.
            unc_set: (set) required glyph ids.
        Returns:
            Either None if subsetting is unsuccessful or the subset font buffer.
        r   Nz/This method requires fontTools to be installed.z/oldfont.ttfz/newfont.ttfz/uncfile.txtz--retain-gidsz--output-file=z--layout-features=*z--passthrough-tablesz--ignore-missing-glyphsz--ignore-missing-unicodesz--symbol-cmapr   utf8)r  i  z--gids-file=   z%i
z--unicodes-file=r  z%04x
wb)r  )fontTools.subsetsubsetImportErrorr  r   r  r  tempfileTemporaryDirectoryopenr   addr*  writer   removerg  mainra  r  glyph_count)r  unc_setgid_setftsru  tmp_diroldfont_pathnewfont_pathuncfile_pathr  unc_fileunc_listuncr  rh  
new_buffers                   r&   build_subsetz"subset_fonts.<locals>.build_subset4  s.   	*
 	((* -	"g%Yl3L%Yl3L%Yl3L /%&)+	D 	.fE 7W$KK,|n =>KK$#G}H' 5 v|45 KK"2<. ABKK$#G}H' 7 x#~677 lD) 'Xv&'		,'"||\:![[
##q(!%JU-	"\ g  	#(>(>(@OOMN	*7 7' '    "&&(!
"W-	"\ s   E9 .H
BF6&H:GHG+AG9:F36F?	;HG	H	GHGHG?<H>G??HHc           
      P   d fd}t        | j                        D ]  }| j                  |d      D ]  }|d   }|d   }|d   }|dvrt        |      d	kD  r	|d	   d
k(  r.| j	                  |      }|d   } || |      }	j                  |t               t               t               t               ff      \  }
}}|j                  |       |	D ]  }|
j                  |        t        j                  |      }|
j                  |j                         ~|
||f|<     y)zPopulate 'font_buffers'.

        For each font candidate, store its xref and the list of names
        by which PDF text may refer to it (there may be multiple).
        c                     d| v rL| j                  d      }t        | |dz   |dz    d      }| j                  | ||dz    t        |            } d| v rL| S )zdRecreate font name that contains PDF hex codes.

            E.g. #20 -> space, chr(32)
            #r   r      )r  r   rr  chr)r~   r  r  s      r&   	norm_namez7subset_fonts.<locals>.repl_fontnames.<locals>.norm_name{  sa    
 +IIcNQUQU+R0||DQUOSV< + Kr'   c                 >   |d   }|g}| j                  |d   d      d   dd } |      }||vr|j                  |       | j                  |d   d      }|d   dk7  r|S |d   dd }|j                  d	      r!t        |dd
       }| j	                  |d      }|j                  d      }|dk\  rl|j                  d|dz         }t        |j                  d|dz         |j                  d|dz               }||dz   | } |      }||vr|j                  |       |S )zReturn a list of fontnames for an item of page.get_fonts().

            There may be multiple names e.g. for Type0 fonts.
            r   r   BaseFontr   NrX  rY  ri   r  Tr  z	/BaseFontra  r  )r  r   r  r   r  r  r/   )	r[   r'  r  rf  descendentsrB   r   r   r  s	           r&   get_fontnamesz;subset_fonts.<locals>.repl_fontnames.<locals>.get_fontnames  sM   
 AwHJE''Q<Q?CH *Hu$X&**474EFK1~(%a.2.K##F+;s+,!oodtoD!!+.BQw %%c262))#rAv68H8HrTUv8VW&rAv3$X.5(LL*Lr'   T)r   r   r   r   )otfttfwoffwoff2rR  re  ri   r]  N)r$  rJ   rP   r   r`  rT   r  rx  r   ra  r~   )r[   r  r_   r  	font_xreffont_extbasenameextrr^  rf  name_setxref_setsubsetsr~   rh  r  font_bufferss                  @r&   repl_fontnamesz$subset_fonts.<locals>.repl_fontnamest  s@   			8 s~~& 	IA'''5 IaD	Q4Q4 $  x=1$!);''	2!"X
%c1-.:.>.>su~ >/+(G Y'! 'DLL&'||z:TYY',4h+HZ(9I	Ir'   c                 N    j                         D ]  \  }\  }}}| |v s|c S  y r  )r  )r~   r  r  r   r  s       r&   find_buffer_by_namez)subset_fonts.<locals>.find_buffer_by_name  s9    (4(:(:(< 	$F$Xq!x	 r'   zNo fonts to subset.r   rh  !   rJ  r   zCannot subset rZ  zBuilt subset of font r]  Tr  )r   rl  pdf_subset_fonts2r*  r$  rJ   r   r  rv  r   get_texttracer   r	  rx  r  _insert_fontr  r  ) r[   rT  rU  r   ra  rc  rm  r  r  r  old_fontsizenew_fontsizer^  r
   r  r  r  r  r  set_ucsset_gidr  
old_bufferr  r  r  rq   ri  r  width_table	def_widthr  s    `                              @r&   subset_fontsr    s   8 11#6T%*?%@AL$0.0>@KIZ 3OO13LL"'') (
J'(  L &&( 	LDDz%F|CR(H(2F~5A&5I2Hh 2''] "AaD!AaD!" %-h'8J#KL 	LL" 6B5G5G5I (1
1Xx!*gaj'!*E
>!$ZC
O!C.A >?OO3H<qAB*5q6H%?? # 

 " 	BI%3I%>"Ki2iy+yA	B 	J'9(< ,&&r'   )r3   sourcetargetr3   c                R   | j                  |      r&| j                  |      }| j                  ||dd       |g }| j                  |      D ]  }||v r| j	                  ||d        | j                  |      D ]*  }| j                  ||      }| j	                  |||d          , y)a  Copy a PDF dictionary object to another one given their xref numbers.

    Args:
        doc: PDF document object
        source: source xref number
        target: target xref number, the xref must already exist
        keep: an optional list of 1st level keys in target that should not be
              removed before copying.
    Notes:
        This works similar to the copy() method of dictionaries in Python. The
        source may be a stream object.
    FT)r   rR  Nr  r   )xref_is_streamxref_stream_rawro   r  r  r  )r[   r  r  r3   rg   r   r'  s          r&   rn   rn     s     &!$$V,	 	 	
 |  ( .$;f-.
   ( /,d1g./r'   )NNTNNTr   r   )r   TTr   r   N)NNNF)NNNFNr   )NNNr   r  rZ  )r   engr   FN)FFrx  )r   NNNFNr   )r   NNNFr4  )NNNNNNNr   )r   )ri   ri   ri   r   rP  )ri   S  J  )Nr  r  r  r  Nr5  )
r5  Nr   r   r   TNr   r   r   )r]  r5  Nr   r   r   TNr   r   r   )r5  NNr   r   r   NTr   r   r   N)r5  NNr   r   r   NTr   r   r   )r5  NNr   Nr   r   TFr   r   r   )r5  NNNr   r   r   Tr   r   r   )r5  NNr   NFr   r   Tr   r   r   )r5  NNTNr   Fr   r   Tr   r   r   )r|  r   N)r]  r   r   )TTTTTTTr   TTTTT)NNr  Nr   NFF)r   NNN)r   r  r   r;  r   r   r   rg  r   format_gr  r  r   r   r   r	   
ByteStringAttributeErrorr   r   
memoryviewAnyAnyTyper<  r   OptIntOptionalr  r=  rQ   r>  r	  OptDictOptBytesSequencer?  r   r   r!   rs   ry   rm   r   TEXT_PRESERVE_WHITESPACETEXT_PRESERVE_LIGATURESTEXT_MEDIABOX_CLIPr*  r   r   rl   TextPager   r   r   r   r   r   r  r(  r/  r  rK  r  r  
Colorspaceru   r   rX  r|  r  r  r  r  r  r  r  r"  r  r  r  Widgetr  r  r  r  r  r  r   r  rh  r  r"  r%  r*  r.  r3  r7  r9  r<  r?  rD  rI  rK  r+  rN  r[  ri  r  r  rV  r  r  r   ra  r  r  r  r  r  r  r  r  r   r  r  r  r#  r+  r/  r1  r/  r9  r=  rI  rQ  rL  r  rn   r   r'   r&   <module>r     s   
  	   	33 
		0""J
 **	c4i	 ??5!		
//$
??:&		) 1ll1 1p | |~ >B$W[  C @)w|| )3 )$ zB &&../--. (()
 $ $V ))--.../ (()
 "& 			 	    	 
       
 J !%
,,
  	
  
H !%L
,,L
L L 	L
 L 
Lb !%r
,,r
r r 	r 	rp "&
,,
  		( !%
,, 	 	
 * Q
,,QQ Q 
	Q
 Q Q Qh# #t #D #UY #L"',, "$ "N !%i
,,ii i 	i
 i i^ !%H			H	H H 	H
 H H H ZZH0 $,,'.}}'ll' '
 &&' ' ' ' ^^'\ "**%,]]				 	 ""    ^^@8d 8vGLL T : 4			44 
4n				 
 jF			jF	jF jF 	jF
 
jF 
jF jF 	jF jF jF 
jFZ	(u 	(;g&& ;4 ;4 ;|7S 7 7# 7z }			}	} } 		}H @L			@L			@L 	@L
 @L @L 
@LJ
 w<


w<


w< w< 	w<
 w< 
w<vPgll P P# Pf gnn  =gll = =$ =(gll ( (T (T ( /F
,,F
F LLd#F
 F F F F F F F F F F F  !F" #F$ %F& 'F( )F* +F, -F. 	/F0 1F\ +/
,,// ,,sDy
!/
 / / / / / / / / / / /  !/" #/$ %/& '/( )/* 	+/n 	} }D 					  	
 \\, +/				 ,,sD$
' 	
      	F  
,,   	  	 
                 ]] N !
,,!! 	! 	!
 ! ! ! ! ! ! ! ! ! 	! ]]!P !
,,!! 	! 	!
 ! ! ! ! ! ! ! ! ! 	! ]]!N  !#ll## # 	#
 # # # # # # # # # ]]#R  
,, 
    	 
                 	  ]] L "
,,"" " 	"
 " " " " " " " " " 	" ]]"R  
,,     	 
                   	  ]] L  
,, 
,,y)+
,    	 
                 	  ]] P !$
,,$$ 	$ 		$
 $ $ $ $ $ $ $ $ $ $ $  	!$" ]]#$Z #%
,,%% 	% 		%
 	% % % % % % % % % % %  !%" 	#%$ ]]%%Z #,
,,,, , 	,
 , , , , , , , , , , ,  !," 	#,$ ]]%,z@d @$$ $B3 B5 B$c $e $N"*g.. "*c "*e "*L [__			_!$_-0_=@_PW_	_D[ [~ IJj
,,j #j36jBEj	jf   V7			V7V7 V7 	V7
 V7 V7 V7 V7 V7 V7 V7 V7 V7 V7 
V7r:( *.``
` ,,sDy
!` 
	`
 //',,
'` ` ` ` ` ` ` `L     $      2 %)#'G			G
G ,,tTz
"G 	G
 	T4Z G 	GTAD'"" AD# AD$ ADH$D6*."63 &# $0 0 0>
@*.`
7## 
 
G$$  "/( /(T /( /(7<< /(d;5 ; ; ; *D * * *Z* *T *$ *',, *Z3 3T 3 3',, 3>v'g&& v' v' v'Z` v'x	 PT !/7## !/S !/# !/ !/X\ !/uo       0"Z/J0s4   o o o' 	oo	o$#o$'o87o8