ó
    �®žjZê  ã                  ó´  • % S SK Jr  S SKrS SKrS SKrS SKJr  S SKJr  S SK	J
r
  S SKJrJrJrJrJrJrJr  S SKJrJrJrJrJrJrJrJrJrJrJrJrJ r J!r!J"r"J#r#  S SK$J%r%  S S	K&J'r'  S S
K(J)r)J*r*  S SK+J,r,  S SK-J.r.J/r/  S SK0J1r1  S SK2J3r3  S SK4J5r5J6r6  S SK7J8r8  S SK9J:r:  \Rv                  " \<5      r=Sr>S\?S'   Sr@S\?S'    S SKAJBrBJCrC  S SKDJErEJFrF  S SKGJHrH  S SKIJJrJ  Sr>SrMS\?S'    S SKNrNS SK0JOrOJPrP  SrMSrQSrRS rSS!rTS"\?S#'   S$rUS"\?S%'   S&rVS"\?S''   \'R®                  " SSSSS(9rXS"\?S)'    S-S* jrY " S+ S,\.\/5      rZg! \K a  rL\Lr@ SrLCLNiSrLCLff = f! \K a     Ncf = f).é    )ÚannotationsN)ÚBytesIO)ÚPath)Úmkdtemp)ÚAnyÚCallableÚFinalÚIterableÚIteratorÚOptionalÚUnion)ÚBoundingBoxÚCoordOriginÚDocItemLabelÚDoclingDocumentÚDocumentOriginÚ
GroupLabelÚImageRefÚPictureClassificationLabelÚPictureClassificationMetaFieldÚPictureClassificationPredictionÚPictureMetaÚProvenanceItemÚSizeÚ	TableCellÚ	TableDataÚTabularChartMetaField)ÚContentLayer)Úetree)ÚImageÚUnidentifiedImageError)Úoverride)ÚDeclarativeDocumentBackendÚPaginatedDocumentBackend)Úconvert_to_modern_format)ÚMsPowerpointBackendOptions)ÚFormatToMimeTypeÚInputFormat)ÚInputDocument)ÚDocumentLoadErrorFÚboolÚ_PPTX_AVAILABLEzImportError | NoneÚ_PPTX_IMPORT_ERROR)ÚPresentationÚpresentation)ÚMSO_SHAPE_TYPEÚPP_PLACEHOLDER)ÚInvalidXmlError)ÚCT_TextLineBreakTÚ_CHART_RENDER_AVAILABLE)Úcrop_whitespaceÚget_docx_to_pdf_converterz}The 'python-pptx' package is required to process PowerPoint files. Install it with `pip install 'docling-slim[format-pptx]'`.zãLibreOffice is required to render PowerPoint charts as images (render_chart_images=True). Install LibreOffice and make sure `soffice` is on PATH. Charts still keep their classification and reconstructed tabular data without it.zèLibreOffice is required to rasterize EMF/WMF pictures embedded in slides. Install LibreOffice and make sure `soffice` is on PATH. Such pictures are still recorded with their position on the slide without it, but carry no image data.s   ×ÍÆšr	   Ú_WMF_PLACEABLE_MAGICs    EMFÚ_EMF_SIGNATUREé(   Ú_EMF_SIGNATURE_OFFSET)Úresolve_entitiesÚload_dtdÚ
no_networkÚdtd_validationÚ_SAFE_XML_PARSERc                óV   • U SS [         :H  =(       d    U [        [        S-    [        :H  $ )aá  Return True when the bytes are a Windows metafile (WMF or EMF).

Pillow renders metafiles only on Windows, where it delegates to the GDI
``PlayEnhMetaFile`` API; the wheels for every other platform carry a stub
that raises on load. Telling a metafile apart from a genuinely broken
image decides whether a picture is worth rasterizing externally.

Args:
    image_bytes: Raw bytes of an embedded picture.

Returns:
    True when the bytes carry a placeable WMF or an EMF signature.
Né   )r7   r:   r8   )Úimage_bytess    Úa/home/mande/repo/quber/.venv/lib/python3.13/site-packages/docling/backend/mspowerpoint_backend.pyÚ_is_metafilerD   r   s3   € ð �r˜ˆ?Ô2Ñ2÷ ØÔ)Ô,AÀAÑ,EÐFÌ.ÑXðó    c                  óŠ  ^ • \ rS rSr% SrSSSS.rS\S'   S	rS
\S'    SrSr	 S4       S5U 4S jjjr
S6S jr\S7S j5       r\\S7S j5       5       r\S 5       r\\S8S j5       5       r\S9S j5       rS\" SSS94S jrS6S jr  S:S jrS;S jr    S<S jr  S=S jr    S<S jrS>S jrS?S  jrS@S! jrSAS" jr  SBS# jrS$ r SCS% jr!S& r"S' r#\$SDS( j5       r%\$SES) j5       r&\$SFS* j5       r'SGS+ jr(S, r)SHS- jr*        SIS. jr+      SJS/ jr,  SK           SLS0 jjr-    SMS1 jr.        SNS2 jr/S3r0U =r1$ )OÚMsPowerpointDocumentBackendé…   a•  Backend for parsing PowerPoint presentations (PPTX and PPT files).

Converts presentations into structured DoclingDocument format, extracting
text, tables, images, lists, and comments from slides.

Legacy ``.ppt`` files (binary PowerPoint 97-2003 format) are first converted
to ``.pptx`` via LibreOffice before parsing.

Note:
    Comments are extracted and added to the NOTES content layer. Unlike Word documents,
        PPTX comments only contain position coordinates (x, y) and do not directly reference
        specific shapes or text ranges. Therefore, comments are associated with their parent
        slide group rather than specific document elements.
z5http://schemas.openxmlformats.org/drawingml/2006/mainz6http://schemas.openxmlformats.org/drawingml/2006/chartz:http://schemas.openxmlformats.org/presentationml/2006/main)ÚaÚcÚpzFinal[dict[str, str]]Ú
NAMESPACESi˜²  z
Final[int]Ú_SHAPE_ROW_TOLERANCE_EMUzLhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/commentszRhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthorsc                óÈ  >• [         (       d  [        [        5      [        eUR                  [
        R                  :X  a  [        USS5      nUc
  [        5       n[        TU ])  XU5        X l        UR                  R                  U l        S U l        SU l        SU l        SU l        S U l        SU l         [)        U R                  [*        5      (       a  [-        U R                  5      U l        OB[)        U R                  [.        5      (       a#  [-        [1        U R                  5      5      U l        SU l        g ! [2         a  n[5        SU R6                   35      UeS nAff = f)NÚpptÚpptxFTz>MsPowerpointDocumentBackend could not load document with hash )r,   ÚImportErrorÚ_INSTALL_HINTr-   Úformatr(   ÚPPTr%   r&   ÚsuperÚ__init__Úpath_or_streamÚlimitsÚ
page_rangeÚpptx_to_pdf_converterÚpptx_to_pdf_converter_initÚ_render_chartsÚ_metafile_hint_emittedÚpptx_objÚvalidÚ
isinstancer   r.   r   ÚstrÚ	Exceptionr*   Údocument_hash)ÚselfÚin_docrW   ÚoptionsÚeÚ	__class__s        €rC   rV   Ú$MsPowerpointDocumentBackend.__init__®   s+  ø€ ÷ ŠÜœmÓ,Ô2DÐDØ�=‰=œKŸO™OÓ+Ü5°nÀeÈVÓTˆNØ‰?Ü0Ó2ˆGÜ‰Ñ˜°Ô9Ø4BÔØ Ÿ-™-×2Ñ2ˆŒà9=ˆÔ"Ø05ˆÔ'Ø$)ˆÔØ,1ˆÔ#à=AˆŒØ ˆŒ
ð
	Ü˜$×-Ñ-¬w×7Ñ7Ü ,¨T×-@Ñ-@Ó A�•Ü˜D×/Ñ/´×6Ñ6Ü ,¬S°×1DÑ1DÓ-EÓ F�”àˆDŒJð 	øô ó 	Ü#ØPÐQU×QcÑQcÐPdÐeóàðûð	ús   Â5BD9 Ä9
E!ÅEÅE!c                óŠ   • U R                  5       (       a.  U R                  c   e[        U R                  R                  5      $ g)Nr   )Úis_validr^   ÚlenÚslides©rd   s    rC   Ú
page_countÚ&MsPowerpointDocumentBackend.page_countÓ   s5   € Ø�=‰=�?‰?Ø—=‘=Ñ,Ð,Ð,Ü�t—}‘}×+Ñ+Ó,Ð,àrE   c                ó   • U R                   $ ©N)r_   rn   s    rC   rk   Ú$MsPowerpointDocumentBackend.is_validÚ   s   € à�z‰zÐrE   c                ó   • g)NT© ©Úclss    rC   Úsupports_paginationÚ/MsPowerpointDocumentBackend.supports_paginationÞ   s   € ð rE   c                ó„   • [        U R                  [        5      (       a  U R                  R                  5         S U l        g rr   )r`   rW   r   Úclosern   s    rC   ÚunloadÚ"MsPowerpointDocumentBackend.unloadã   s/   € ä�d×)Ñ)¬7×3Ñ3Ø×Ñ×%Ñ%Ô'à"ˆÕrE   c                óB   • [         R                  [         R                  1$ rr   )r(   ÚPPTXrT   rv   s    rC   Úsupported_formatsÚ-MsPowerpointDocumentBackend.supported_formatsê   s   € ô × Ñ ¤+§/¡/Ð2Ð2rE   c                óŠ  • [        U R                  R                  =(       d    S[        U R                     S   U R
                  S9n[        U R                  R                  =(       d    SUS9nU R                  (       aD  U R                  U R                  5      nU R                  u  pEU R                  U R                  X#XES9nU$ )zTParse the PPTX into a structured document model.

Returns:
    The parsed document.
Úfiler   )ÚfilenameÚmimetypeÚbinary_hash)ÚnameÚorigin)Ú
start_pageÚend_page)r   rƒ   r‡   r'   Úinput_formatrc   r   Ústemr^   Ú_build_comment_author_maprY   Ú_walk_linear)rd   rˆ   ÚdocÚ
author_mapr‰   rŠ   s         rC   ÚconvertÚ#MsPowerpointDocumentBackend.convertï   s£   € ô  Ø—Y‘Y—^‘^×- vÜ% d×&7Ñ&7Ñ8¸Ñ;Ø×*Ñ*ñ
ˆô  4§9¡9§>¡>×#;°VÀFÑKˆØ�=�=à×7Ñ7¸¿¹ÓFˆJà#'§?¡?Ñ ˆJØ×#Ñ#Ø—‘˜s¸:ð $ð ˆCð ˆ
rE   Ú é   ©ÚwidthÚheightc                óŽ  • S UR                   UR                  UR                  UR                  4;  a1  UR                   nUR                  nUR                  nUR                  nOSnSnUR                  nUR                  nXVXW-   Xh-   /n	[        R
                  " U	[        R                  S9n	[        US-   S[        U5      /U	S9n
U
$ )Nr   )rˆ   r”   ©Úpage_noÚcharspanÚbbox)
ÚleftÚtopr–   r—   r   Ú
from_tupler   Ú
BOTTOMLEFTr   rl   )rd   ÚshapeÚ	slide_indÚtextÚ
slide_sizer�   rž   r–   r—   Ú
shape_bboxÚprovs              rC   Ú_generate_provÚ*MsPowerpointDocumentBackend._generate_prov  sµ   € ð ˜Ÿ
™
 E§I¡I¨u¯{©{¸E¿L¹LÐIÓIØ—:‘:ˆDØ—)‘)ˆCØ—K‘KˆEØ—\‘\‰FàˆDØˆCØ×$Ñ$ˆEØ×&Ñ&ˆFØ ¡¨s©|Ð<ˆ
Ü ×+Ò+¨J¼{×?UÑ?UÑVˆ
ÜØ ‘M¨Q´°D³	¨NÀñ
ˆð ˆrE   c                ó´   • UR                  SU R                  S9nUb+  SUR                  ;   a   [        UR	                  S5      5      $ g! [
         a     gf = f)aÌ  Return the indentation level of a paragraph XML element.

Paragraphs can have different indentation levels (0-8). The level is
stored in the `lvl` attribute of the `a:pPr` element (paragraph properties).

Args:
    paragraph: Paragraph XML element whose level should be extracted.

Returns:
    Paragraph level in the range (0, 8). Returns 0 when no `a:pPr` element is
        found, no `lvl` attribute exists, or the `lvl` attribute value is
        invalid.
úa:pPr©Ú
namespacesÚlvlr   )ÚfindrL   ÚattribÚintÚgetÚ
ValueError)rd   Ú	paragraphÚpPrs      rC   Ú_get_paragraph_levelÚ0MsPowerpointDocumentBackend._get_paragraph_level  s^   € ð �n‰n˜W°·±ˆnÐAˆØ‰?˜u¨¯
©
Ó2ðÜ˜3Ÿ7™7 5›>Ó*Ð*ð øô ó ØØðús   ¯A
 Á

AÁAc                óD  • Uc  gUR                  SU R                  S9b  gUR                  SU R                  S9nUb  SSUR                  S5      4$ UR                  S	U R                  S9nUb  SS
UR                  S5      4$ UR                  SU R                  S9nUb  gg)a”  Parse bullet or numbering information from a paragraph properties node.

This inspects the `a:pPr` or `a:lvlXpPr` element and extracts
information about the bullet character, automatic numbering, picture
bullets, or explicit `buNone` markers.

Args:
    pPr: Paragraph properties XML element (`a:pPr` or `a:lvlXpPr`).

Returns:
    A 3-tuple (`is_list`, `kind`, `detail`) where: `is_list` is True/False/None
        indicating whether this is a list item; `kind` is one of `buChar`,
        `buAutoNum`, `buBlip`, `buNone` or None, describing the marker type;
        `detail` is the bullet character, numbering type string, or None if not
        applicable.
©NNNza:buNoner«   )FÚbuNoneNza:buCharTÚbuCharÚcharza:buAutoNumÚ	buAutoNumÚtypeza:buBlip)TÚbuBlipÚimage)r®   rL   r±   )rd   r´   rº   ÚbuAutor¾   s        rC   Ú'_parse_bullet_from_paragraph_propertiesÚCMsPowerpointDocumentBackend._parse_bullet_from_paragraph_properties3  s´   € ð& ‰;Ø%ð �8‰8�J¨4¯?©?ˆ8Ð;ÑGØ*ð —‘˜*°·±�ÐAˆØÑØ˜( F§J¡J¨vÓ$6Ð7Ð7ð —‘˜-°D·O±O�ÐDˆØÑØ˜+ v§z¡z°&Ó'9Ð:Ð:ð —‘˜*°·±�ÐAˆØÑØ,à!rE   c                óN   • Uc  gSUS-    S3nUR                  X0R                  S9$ )a«  Find the level-specific paragraph properties node from a list style.

This looks for an `a:lvl{lvl+1}pPr` node inside an `a:lstStyle` element, where
`a:lvl1pPr` corresponds to level 0, `a:lvl2pPr` to level 1, and so on.

Args:
    lstStyle: List style XML element `a:lstStyle`.
    lvl: Paragraph level in the range (0, 8).

Returns:
    Matching `a:lvl{lvl+1}pPr` XML element, or None if no matching element is
        found.
Nza:lvlr”   r´   r«   )r®   rL   )rd   ÚlstStyler­   Útags       rC   Ú$_find_level_properties_in_list_styleÚ@MsPowerpointDocumentBackend._find_level_properties_in_list_style^  s4   € ð ÑØØ�c˜A‘g�Y˜cÐ"ˆØ�}‰}˜S¯_©_ˆ}Ð=Ð=rE   c                ó�   • Uc  gUR                  SU R                  S9nU R                  X25      nU R                  U5      u  pVnXVU4$ )a›  Parse bullet or numbering information from a text body's list style.

This searches for `a:lstStyle/a:lvl{lvl+1}pPr` under a `txBody` and uses the
level-specific paragraph properties to deduce bullet or numbering information.

Args:
    txBody: Text body XML element `p:txBody`.
    lvl: Paragraph level in the range (0, 8).

Returns:
    A 3-tuple (`is_list`, `kind`, `detail`) where: `is_list` is True/False/None
        indicating whether this is a list item; `kind` is one of `buChar`,
        `buAutoNum`, `buBlip`, `buNone` or None, describing the marker type;
        `detail` is the bullet character, numbering type string, or None if not
        applicable.
r¸   z
a:lstStyler«   )r®   rL   rÆ   rÁ   )rd   ÚtxBodyr­   rÄ   Úlvl_pPrÚis_listÚkindÚdetails           rC   Ú'_parse_bullet_from_text_body_list_styleÚCMsPowerpointDocumentBackend._parse_bullet_from_text_body_list_styleq  sR   € ð& ‰>Ø%Ø—;‘;˜|¸¿¹�;ÐHˆØ×;Ñ;¸HÓJˆØ $× LÑ LÈWÓ UÑˆ�vØ˜vÐ&Ð&rE   c                ó^  • UR                   R                  SU R                  S9nUc  gU[        R                  [        R
                  4;   a  UR                  SU R                  S9$ U[        R                  :X  a  UR                  SU R                  S9$ UR                  SU R                  S9$ )aù  Get the appropriate master text style node for a placeholder.

Most content placeholders (BODY/OBJECT) use `p:bodyStyle`, while titles use
`p:titleStyle`. All other placeholders default to `p:otherStyle`.

Args:
    slide_master: Slide master object associated with the current slide.
    placeholder_type: Placeholder type enum from `PP_PLACEHOLDER`.

Returns:
    Matching style node from master `p:txStyles` (`p:bodyStyle`, `p:titleStyle`
        or `p:otherStyle`) or None when no styles are defined.
z.//p:txStylesr«   Nzp:bodyStylezp:titleStylezp:otherStyle)Ú_elementr®   rL   r1   ÚBODYÚOBJECTÚTITLE)rd   Úslide_masterÚplaceholder_typeÚtxStyless       rC   Ú_get_master_text_style_nodeÚ7MsPowerpointDocumentBackend._get_master_text_style_node‹  sŸ   € ð   ×(Ñ(×-Ñ-Ø¨¯©ð .ð 
ˆð ÑØà¤× 3Ñ 3´^×5JÑ5JÐKÓKØ—=‘= ¸4¿?¹?�=ÐKÐKàœ~×3Ñ3Ó3Ø—=‘= ¸D¿O¹O�=ÐLÐLà�}‰}˜^¸¿¹ˆ}ÐHÐHrE   c                óž   • U R                  X5      nUc  gUR                  SUS-    S3U R                  S9nU R                  U5      u  pgnXgU4$ )a  Parse bullet or numbering information from the slide master text styles.

This looks up the appropriate style bucket in the slide master's `p:txStyles`
(`titleStyle`, `bodyStyle` or `otherStyle`) and extracts bullet or numbering
information for the given level.

Args:
    slide_master: Slide master object associated with the current slide.
    placeholder_type: Placeholder type enum from `PP_PLACEHOLDER`.
    lvl: Paragraph level in the range (0, 8).

Returns:
    A 3-tuple (`is_list`, `kind`, `detail`) where: `is_list` is True/False/None
        indicating whether this is a list item; `kind` is one of `buChar`,
        `buAutoNum`, `buBlip`, `buNone` or None, describing the marker type;
        `detail` is the bullet character, numbering type string, or None if not
        applicable.
r¸   z.//a:lvlr”   r´   r«   )rØ   r®   rL   rÁ   )	rd   rÕ   rÖ   r­   ÚstylerÊ   rË   rÌ   rÍ   s	            rC   Ú%_parse_bullet_from_master_text_stylesÚAMsPowerpointDocumentBackend._parse_bullet_from_master_text_styles©  s_   € ð* ×0Ñ0°ÓPˆØ‰=Ø%à—*‘*˜x¨¨a© y°Ð4ÀÇÁ�*ÐQˆØ $× LÑ LÈWÓ UÑˆ�vØ˜vÐ&Ð&rE   c                óÂ  • UR                   nSn UR                  nUR                  nUbR  U R                  X15      nUS   SL d	  US   S;   a  US   S:X  a  gUS   S:X  a  g	g
US   SL a  gUR                  S:”  a  g
gUR                  SSU R                  S   0S9b  gUR                  SSU R                  S   0S9b  g	UR                  S:”  a  g
g! [         a     Nµf = f)a6  Determine whether a paragraph should be treated as a list item.

The method first tries to resolve list style information via the shape that
owns the paragraph. If that is not possible, it falls back to simpler checks
based on paragraph properties and level.

Args:
    paragraph: `python-pptx` paragraph object to inspect.

Returns:
    A 2-tuple (`is_list`, `bullet_type`) where: `is_list` is True if the
        paragraph is considered a list item, otherwise False; `bullet_type` is
        one of `Bullet`, `Numbered` or `None`, describing the list marker type.
NrË   TrÌ   ©rº   r¼   r¾   rº   )TÚBulletr¼   )TÚNumbered)TÚNoneF)Frâ   r   z.//a:buCharrI   r«   z.//a:buAutoNum)rÑ   Ú_parentÚAttributeErrorÚ_get_effective_list_markerÚlevelr®   rL   )rd   r³   rK   r¡   Ú
text_frameÚmarker_infos         rC   Ú_is_list_itemÚ)MsPowerpointDocumentBackend._is_list_itemÆ  s)  € ð ×Ñˆð ˆð	ð #×*Ñ*ˆJà×&Ñ&ˆEð ÑØ×9Ñ9¸%ÓKˆKð ˜9Ñ%¨Ò-°¸VÑ1Dð Ió 2ð
 ˜vÑ&¨(Ó2Ø+Ø  Ñ(¨KÓ7Ø-à)ð ˜9Ñ%¨Ò.Ø&ð �‰ Ó"Ø%à"ð �6‰6�-¨S°$·/±/À#Ñ2FÐ,Gˆ6ÐHÑTØ#à�F‰FÐ#°°d·o±oÀcÑ6JÐ0KˆFÐLÑXà%Ø�_‰_˜qÓ à!à"øôQ ó 	Ùð	ús   �C Ã
CÃCc                óž  • UR                   nU R                  U5      nUR                  SU R                  S9nU R	                  U5      u  pgnUb  UUUUS.$ UR                   R                  SU R                  S9n	U R                  X”5      u  pgnUb  UUUUS.$ Sn
UR                  (       Ga
  UR                  R                  nUR                  R                  R                  nSn UR                  R                  U5      nUb®  UR                   R                  SU R                  S9nU R                  Xä5      u  pgnUb  UUUUS.n
UR                  R                  nUR                  R                  R                  R                   nU R#                  UXô5      u  pgnUS;   a  SUUUS.$ Ub  UUUUS.$ U
b  U
$ SSSUS.$ ! [         a    Sn NËf = f)aW  Return a dictionary describing the effective list marker for a paragraph.

List marker information can come from several sources: direct paragraph
properties, shape-level list styles, layout placeholders, or slide master text
styles. This helper resolves all of these layers and returns a unified view of
the effective marker.

Args:
    shape: Shape object that contains the paragraph.
    paragraph: `python-pptx` paragraph object to inspect.

Returns:
    Information about the list marker in a dictionary, where: `is_list` is
        True/False/None indicating if this is a list item; `kind` is one of
        `buChar`, `buAutoNum`, `buBlip`, `buNone` or None, describing the
        marker type; `detail` is the bullet character or numbering type string,
        or None if not applicable; `level` is the paragraph level in the range
        (0, 8).
rª   r«   N)rË   rÌ   rÍ   ræ   z.//p:txBodyrß   T)rÑ   rµ   r®   rL   rÁ   rÎ   Úis_placeholderÚplaceholder_formatÚidxÚpartÚslideÚslide_layoutÚplaceholdersr±   rb   r½   rÕ   rÜ   )rd   r¡   r³   rK   r­   r´   rË   rÌ   rÍ   rÉ   Úlayout_resultrî   ÚlayoutÚ	layout_phÚ	layout_txÚph_typeÚmasters                    rC   rå   Ú6MsPowerpointDocumentBackend._get_effective_list_marker	  s;  € ð( ×ÑˆØ×'Ñ'¨Ó*ˆð �f‰f�W¨¯©ˆfÐ9ˆØ $× LÑ LÈSÓ QÑˆ�vØÑà"ØØ Øñ	ð ð —‘×$Ñ$ ]¸t¿¹Ð$ÐOˆØ $× LÑ LØó!
Ñˆ�vð Ñà"ØØ Øñ	ð ð ˆØ××ÐØ×*Ñ*×.Ñ.ˆCØ—Z‘Z×%Ñ%×2Ñ2ˆFØˆIð!Ø"×/Ñ/×3Ñ3°CÓ8�	ð Ñ$Ø%×.Ñ.×3Ñ3Ø!¨d¯o©oð 4ð �	ð )-×(TÑ(TØó)Ñ%�˜vð
 Ñ&à#*Ø $Ø"(Ø!$ñ	%�Mð  ×2Ñ2×7Ñ7�ØŸ™×)Ñ)×6Ñ6×CÑC�Ø(,×(RÑ(RØ˜Gó)Ñ%�˜vð
 Ð<Ó<à#'Ø $Ø"(Ø!$ñ	ð ð Ñ(à#*Ø $Ø"(Ø!$ñ	ð ð Ñ(Ø$Ð$ð ØØØñ	
ð 	
øôa ó !Ø ’	ð!ús   Ã%F= Æ=GÇGc                ón   •  [        X5      nUc  g[	        U5      $ ! [        [        [        4 a     gf = f)a$  Return a shape position attribute as an integer for ordering.

Args:
    shape: A python-pptx shape object. Position attributes such as
        ``top`` and ``left`` are accessed via ``getattr``; property
        getters that raise are silently treated as absent.
    attr: Name of the position attribute to read, typically ``"top"``
        or ``"left"``.

Returns:
    The attribute value cast to ``int``, or ``None`` if the attribute
    is missing, ``None``-valued, or its getter raises
    ``AttributeError``, ``ValueError``, or ``TypeError``.
N)Úgetattrrä   r²   Ú	TypeErrorr°   )rd   r¡   ÚattrÚvalues       rC   Ú_get_shape_positionÚ/MsPowerpointDocumentBackend._get_shape_positionw  s@   € ð	Ü˜EÓ(ˆEð ‰=Øä�5‹zÐøô ¤
¬IÐ6ó 	Ùð	ús   ‚ œ4³4c           
   #  ól  #   • SSK Jn   " S SU5      nU R                  nSn/ n[        U5       HK  u  pxU R	                  US5      n	U R	                  US5      n
UR                  U" UUU	b  U	OUU
b  U
OUS	95        MM     UR                  S
 S9  / n/ nSnU HX  nUb  UR                  U-
  U::  a  UR                  U5        UR                  nM8  UR                  U5        U/nUR                  nMZ     U(       a  UR                  U5        U H#  n[        US S9 H  nUR                  v •  M     M%     g7f)a%  Iterate shapes in visual top-to-bottom, left-to-right order.

PowerPoint stores shapes in creation/z-order, which can differ from the
way content is visually read on a slide. Sorting by position keeps split
text boxes, such as a subheading followed by its bullet text box, adjacent
in the extracted document.

Shapes that share a top-edge within ``row_tolerance`` EMUs of their
immediate predecessor (after sorting by ``top``) are placed in the same
row and then sorted left-to-right within that row. Adjacency is evaluated
against the previous shape's ``top``, not the row's first anchor, so that
a row can span more than one tolerance step when shapes form a contiguous
band. Shapes whose position attributes are unavailable or raise an
exception are placed at the end in their original relative order.

Args:
    shapes: Iterable of python-pptx shape objects to sort. May be a
        slide's top-level shape collection or the children of a group
        shape.

Yields:
    Shapes from ``shapes`` in visual reading order (top-to-bottom,
    left-to-right).
r   )Ú
NamedTuplec                  ó>   • \ rS rSr% S\S'   S\S'   S\S'   S\S'   Srg	)
ÚHMsPowerpointDocumentBackend._iter_shapes_by_position.<locals>._ShapeInfoi«  r°   ÚindexÚobjectr¡   rž   r�   ru   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__Ú__static_attributes__ru   rE   rC   Ú
_ShapeInfor  «  s   ‡ Ø‹JØ‹MØ‹HØŽIrE   r  l   ÿÿÿÿ rž   r�   N)r  r¡   rž   r�   c                ó2   • U R                   U R                  4$ rr   )rž   r  ©Úsis    rC   Ú<lambda>ÚFMsPowerpointDocumentBackend._iter_shapes_by_position.<locals>.<lambda>Á  s   €  R§V¡V¨R¯X©XÑ$6rE   )Úkeyc                ó2   • U R                   U R                  4$ rr   )r�   r  r  s    rC   r  r  Ô  s   € °"·'±'¸2¿8¹8Ñ1DrE   )
Útypingr  rM   Ú	enumeraterÿ   ÚappendÚsortrž   Úsortedr¡   )rd   Úshapesr  r  Úrow_toleranceÚfallback_positionÚentriesr  r¡   rž   r�   ÚrowsÚcurrent_rowÚprev_topÚentryÚrowr  s                    rC   Ú_iter_shapes_by_positionÚ4MsPowerpointDocumentBackend._iter_shapes_by_position�  s<  é € õ2 	&ô	˜ô 	ð ×5Ñ5ˆØ%Ðà$&ˆÜ% fÖ-‰LˆEØ×*Ñ*¨5°%Ó8ˆCØ×+Ñ+¨E°6Ó:ˆDØ�N‰NÙØØØ"™™Ð4EØ!%Ñ!1™Ð7Hñ	öñ .ð 	�‰Ñ6ˆÑ7à')ˆØ(*ˆØˆãˆEØÑ 5§9¡9¨xÑ#7¸=Ó#HØ×"Ñ" 5Ô)Ø Ÿ9™9’à—‘˜KÔ(Ø$˜g�Ø Ÿ9™9’ñ ö Ø�K‰K˜Ô$ãˆCÜ˜SÑ&DÔE�Ø—h‘h”ó Fò ùs   ‚D2D4c           	     óF  • SnSnS n[         R                  n	U R                  XUR                  R	                  5       U5      n
UR
                  R                   GHE  nU R                  U5      u  pÍUR                  nSnUR                   H.  n[        U[        5      (       a  US-  nM  UUR                  -  nM0     U(       aQ  SnUS:H  nU(       d  UR                  SUS9nSnSnU(       a  US	-  n[        U5      S
-   nUR                  UUUUU
S9  M»  U(       a  SnS nSn[         R                  n	UR                   (       aJ  UR"                  R$                  nU[&        R(                  [&        R*                  4;   a  [         R*                  n	UR-                  U	UUU
S9  GMH     g )NFr   r“   Ú rá   Úlist)r‡   ÚparentTr”   Ú.)ÚmarkerÚ
enumeratedr(  r£   r¦   ©Úlabelr(  r£   r¦   )r   Ú	LIST_ITEMr§   r£   Ústriprç   Ú
paragraphsré   rÑ   Úcontent_childrenr`   r3   Úadd_list_groupra   Úadd_list_itemÚ	PARAGRAPHrì   rí   r½   r1   ÚCENTER_TITLErÔ   Úadd_text)rd   r¡   Úparent_slider¢   r�   r¤   Úis_list_group_createdÚenum_list_item_valueÚnew_listÚ	doc_labelr¦   r³   Ú	is_a_listÚbullet_typerK   Úp_textrg   Úenum_markerr+  rÖ   s                       rC   Ú_handle_text_elementsÚ1MsPowerpointDocumentBackend._handle_text_elements×  sÃ  € ð !&ÐØ ÐØˆÜ ×*Ñ*ˆ	Ø×"Ñ" 5°U·Z±Z×5EÑ5EÓ5GÈÓTˆð ×)Ñ)×4Õ4ˆIØ%)×%7Ñ%7¸	Ó%BÑ"ˆIØ×"Ñ"ˆAð ˆFØ×'Ô'�Ü˜aÔ!1×2Ñ2Ø˜c‘M’Fà˜aŸf™fÑ$’Fñ	 (ö Ø �Ø(¨JÑ6�
æ,Ø"×1Ñ1Ø#Ø+ð  2ð  �Hð -1Ð)Ø+,Ð(æØ(¨AÑ-Ð(Ü"%Ð&:Ó";¸cÑ"A�Kà×!Ñ!Ø&Ø)Ø#ØØð "ó ö )Ø,1Ð)Ø#�HØ+,Ð(ô )×2Ñ2�	Ø×'×'Ø',×'?Ñ'?×'DÑ'DÐ$Ø'Ü&×3Ñ3Ü&×,Ñ,ð,ó ô
 %1×$6Ñ$6˜	ð —‘Ø#Ø'ØØð	 ô ñk 5ðv 	rE   c                ó:  • UR                   R                  nUR                  R                  5       nU R	                  XU5      n[        UR                  5       5      S:”  a¼  U[        R                  [        R                  4;   aB  [        R                  SUR                   35        UR                  [        R                  X&US9  g U[        R                  :X  aB  [        R                  SUR                   35        UR                  [        R                  UUUS9  g )Nr   zTitle found: r,  zSubtitle found: )rí   r½   r£   r/  r§   rl   r1   r5  rÔ   Ú_logÚinfor6  r   ÚSUBTITLEÚSECTION_HEADER)rd   r¡   r7  r¢   r�   rÖ   Útxtr¦   s           rC   Ú_handle_titleÚ)MsPowerpointDocumentBackend._handle_title  sï   € Ø ×3Ñ3×8Ñ8ÐØ�j‰j×ÑÓ ˆØ×"Ñ" 5°SÓ9ˆäˆs�y‰y‹{Ó˜aÓà¤N×$?Ñ$?Ä×AUÑAUÐ#VÓVÜ—	‘	˜M¨%¯*©*¨Ð6Ô7Ø—‘Ü&×,Ñ,°\ÐRVð ñ ð 	ð "¤^×%<Ñ%<Ó<Ü—	‘	Ð,¨U¯Z©Z¨LÐ9Ô:à—‘Ü&×5Ñ5Ø'ØØð	 ñ ð 	rE   c                ót  • U R                  5       nUc2  U R                  (       d   SU l        [        R                  [        5        gUSS [
        :X  a  SOSn[        [        5       5      n USU 3-  nUS-  nUR                  U5        U" XV5        UR                  5       (       d7  [        R                  SUR                  5         [        R                  " USS	9  g[        R                  " [!        U5      5      nUS
   n[#        UR%                  SS9R'                  5       5      n	UR)                  5         UR)                  5         U	[        R                  " USS	9  $ ! [*         a5  n
[        R                  SU
5         Sn
A
[        R                  " USS	9  gSn
A
ff = f! [        R                  " USS	9  f = f)a§  Rasterize a raw EMF or WMF picture via LibreOffice.

LibreOffice converts a standalone ``.emf``/``.wmf`` to PDF directly, so
no wrapper document is needed; the first page is then rendered with
pypdfium2. This is the same route ``_render_chart_image`` already takes
for native charts.

Args:
    image_bytes: Raw metafile data.

Returns:
    A PIL Image, or None when LibreOffice is unavailable or the
    conversion fails.
NTrA   z.wmfz.emfr¿   z	image.pdfz)LibreOffice produced no PDF output for %s©Úignore_errorsr   é   ©Úscalez0EMF/WMF rasterization via LibreOffice failed: %s)Ú_get_libreoffice_converterr]   rC  ÚwarningÚ_IMAGE_RENDER_HINTr7   r   r   Úwrite_bytesÚexistsÚdebugr‡   ÚshutilÚrmtreeÚ	pypdfium2ÚPdfDocumentra   r5   ÚrenderÚto_pilr{   rb   )rd   rB   Ú	converterÚsuffixÚtemp_dirÚ
input_pathÚoutput_pathÚpdfÚpageÚ	pil_imageÚexcs              rC   Ú_rasterize_metafileÚ/MsPowerpointDocumentBackend._rasterize_metafile5  sj  € ð ×3Ñ3Ó5ˆ	ØÑØ×.×.Ø.2�Ô+Ü—‘Ô/Ô0Øà& r¨˜?Ô.BÓB‘ÈˆÜœ›	“?ˆð	8Ø! e¨F¨8Ð$4Ñ4ˆJØ" [Ñ0ˆKØ×"Ñ" ;Ô/Ù�jÔ.Ø×%Ñ%×'Ñ'Ü—
‘
ÐFÈ
ÏÉÔXØô �MŠM˜(°$Ó7ô ×'Ò'¬¨KÓ(8Ó9ˆCØ�q‘6ˆDÜ'¨¯©¸!¨Ð(<×(CÑ(CÓ(EÓFˆIØ�J‰JŒLØ�I‰IŒKØô
 �MŠM˜(°$Ó7øô	 ó 	Ü�J‰JÐIÈ3ÔOÛä�MŠM˜(°$Ó7ûð		ûô �MŠM˜(°$Ó7ús2   Á+AE ÃA+E Å
FÅ(FÅ>F  ÆFÆF  Æ F7c                óÊ  •  UR                   nUR                  nUR                  u  p‰U R                  XSU5      n
S n [        R                  " [        U5      5      n[         R"                  " XØS9nUR-                  UUS U
S9  g ! [        [
        [        [        [        [        4 a'  n[        R                  " SU 3[        SS9   S nAg S nAff = f! [        [        [        4 a{  n[%        U5      (       d"  [        R                  " SU 3[        SS9   S nAg [&        R)                  SU5        U R+                  U5      nUb  [         R"                  " USS9n S nANìS nAff = f)	Nr“   z"Skipping malformed picture shape: rM  ©Ú
stacklevel©r¿   Údpiz&Pillow cannot render this metafile: %séH   ©r(  r¿   Úcaptionr¦   )r¿   Úblobrk  r§   r!   r2   ÚKeyErrorrä   r²   ÚOSErrorÚwarningsÚwarnÚUserWarningr    Úopenr   r   Úfrom_pilrD   rC  rU  re  Úadd_picture)rd   r¡   r7  r¢   r�   r¤   r¿   rB   Úim_dpiÚ_r¦   rg   Ú	image_refrc  Ú
rasterizeds                  rC   Ú_handle_picturesÚ,MsPowerpointDocumentBackend._handle_picturesa  sX  € ð	Ø—K‘KˆEØŸ*™*ˆKØŸ	™	‰IˆFØ×&Ñ& u¸¸ZÓHˆDð" )-ˆ	ð	HÜŸ
š
¤7¨;Ó#7Ó8ˆIÜ ×)Ò)°	ÑFˆIð( 	�‰ØØØØð	 	ñ 	
ð 	øôY #ÜÜÜÜÜð
ó 	ô �MŠMØ4°Q°CÐ8ÜØòô
 ûð	ûô( '¬´Ð<ó 	HÜ ×,Ñ,Ü—’Ø8¸¸Ð<ÜØ òô
 ô �J‰JÐ?ÀÔCØ×1Ñ1°+Ó>ˆJØÑ%ô %×-Ò-°JÀBÑG�	ÿøð#	Hús4   ‚9B ¾3C Â$CÂ(C
Ã
CÃE"Ã'-EÄ?EÅE"c                óô  • UR                   (       Gaæ  UR                  nUR                  nU R                  XSU5      nSn	[	        UR
                  5      n
/ nUR                  n[        UR
                  5       GH.  u  pÍ[	        UR                  5      U	:”  a  [	        UR                  5      n	[        UR                  5       Há  u  pïUR                  SUS-    SUS-    S35      nU(       d  M,  US   nUR                  S5      nUR                  S5      nUc  SnO[        U5      nUc  SnO[        U5      n[        UR                  R                  5       UUUUU-   UUU-   US:H  S	S
9	n[	        UR                  R                  5       5      S:”  d  MÐ  UR                  U5        Mã     GM1     [        X©/ S9nU H  nUR                   R                  U5        M      [	        U5      S:”  a  UR#                  UUUS9  g )Nr“   r   z.//a:tbl/a:tr[r”   z]/a:tc[Ú]ÚrowSpanÚgridSpanF©	r£   Úrow_spanÚcol_spanÚstart_row_offset_idxÚend_row_offset_idxÚstart_col_offset_idxÚend_col_offset_idxÚcolumn_headerÚ
row_header©Únum_rowsÚnum_colsÚtable_cells)r(  Údatar¦   )Ú	has_tableÚtablerÑ   r§   rl   r  r  ÚcellsÚxpathr±   r°   r   r£   r/  r  r   rŽ  Ú	add_table)rd   r¡   r7  r¢   r�   r¤   r‘  Ú	table_xmlr¦   r�  rŒ  ÚtcellsÚrow_idxr"  Úcol_idxÚcellÚcell_xmlrƒ  r„  Úicellr�  Útcells                         rC   Ú_handle_tablesÚ*MsPowerpointDocumentBackend._handle_tables˜  sÉ  € à�?�?ˆ?Ø—K‘KˆEØŸ™ˆIà×&Ñ& u¸¸ZÓHˆDàˆHÜ˜5Ÿ:™:“ˆHØˆFàŸ™ˆIä )¨%¯*©*× 5‘�Ü�s—y‘y“> HÓ,Ü" 3§9¡9›~�HÜ%.¨s¯y©yÖ%9‘M�Gà(Ÿ™Ø(¨°1©¨°W¸WÀq¹[¸MÈÐKó �Hö $Ù à'¨™{�HØ'Ÿ|™|¨IÓ6�HØ'Ÿ|™|¨JÓ7�HàÑ'Ø#$™ä#& x£=˜àÑ'Ø#$™ä#& x£=˜ä%Ø!ŸY™YŸ_™_Ó.Ø!)Ø!)Ø-4Ø+2°XÑ+=Ø-4Ø+2°XÑ+=Ø&-°¡lØ#(ñ
�Eô ˜4Ÿ9™9Ÿ?™?Ó,Ó-°Õ1ØŸ™ eÖ,ôG &:ñ !6ôP  hÈrÑRˆDã�Ø× Ñ ×'Ñ'¨Ö.ñ  ä�6‹{˜Q‹ð —‘ \¸À4�ÑHØrE   c                ó  • U b  U R                   OSnSU;   d  SU;   a  [        R                  $ SU;   a  [        R                  $ SU;   a  [        R                  $ SU;   d  SU;   a  [        R
                  $ [        R                  $ )aô  Map a python-pptx ``XL_CHART_TYPE`` to a docling classification label.

``chart.chart_type`` is a granular enum (``COLUMN_CLUSTERED``,
``XY_SCATTER_LINES``, ``THREE_D_PIE``, ...). Rather than enumerate every
member, we match on the enum member's name by family, mirroring the
Excel backend's tagname mapping: column/bar variants become BAR_CHART,
line variants LINE_CHART, pie/doughnut PIE_CHART, scatter SCATTER_CHART,
and everything else (area, radar, stock, surface, ...) OTHER_CHART.
SCATTER is matched before LINE because ``XY_SCATTER_LINES`` contains both.

Args:
    chart_type: An ``XL_CHART_TYPE`` member, or None when python-pptx
        cannot determine the type (e.g. combination charts).

Returns:
    The matching PictureClassificationLabel.
r“   ÚPIEÚDOUGHNUTÚSCATTERÚLINEÚBARÚCOL)r‡   r   Ú	PIE_CHARTÚSCATTER_CHARTÚ
LINE_CHARTÚ	BAR_CHARTÚOTHER_CHART)Ú
chart_typer‡   s     rC   Ú_chart_type_to_classificationÚ9MsPowerpointDocumentBackend._chart_type_to_classificationØ  sz   € ð& #-Ñ"8ˆz�Š¸bˆØ�D‹=˜J¨$Ó.Ü-×7Ñ7Ð7Ø˜ÓÜ-×;Ñ;Ð;Ø�T‹>Ü-×8Ñ8Ð8Ø�D‹=˜E T›MÜ-×7Ñ7Ð7Ü)×5Ñ5Ð5rE   c                ó˜   • U R                   (       d  gU R                  R                  R                  R	                  5       nU=(       d    S$ )zŸReturn the chart's title text, or None when it has no title.

Args:
    chart: A python-pptx ``Chart`` object.

Returns:
    The stripped title text, or None.
N)Ú	has_titleÚchart_titlerç   r£   r/  )Úchartr£   s     rC   Ú_chart_title_textÚ-MsPowerpointDocumentBackend._chart_title_textö  s8   € ð ��ØØ× Ñ ×+Ñ+×0Ñ0×6Ñ6Ó8ˆØ�|�tÐrE   c                óœ   • U c  g[        U [        5      (       a)  U R                  5       (       a  [        [	        U 5      5      $ [        U 5      $ )a•  Format a chart category label or data value as cell text.

python-pptx returns numeric series values as floats and empty points as
None. Integer-valued floats are rendered without a trailing ``.0`` so the
reconstructed table reads like the source data (``120`` not ``120.0``).

Args:
    value: A category label or data point (str, float, int, or None).

Returns:
    The value as a string ("" for None).
r“   )r`   ÚfloatÚ
is_integerra   r°   )rþ   s    rC   Ú
_cell_textÚ&MsPowerpointDocumentBackend._cell_text  s?   € ð ‰=ØÜ�eœU×#Ñ#¨×(8Ñ(8×(:Ñ(:Ü”s˜5“z“?Ð"Ü�5‹zÐrE   c                ó€  • [        UR                  5      nU(       d  g[        UR                  5      nU(       a.  US   R                   Vs/ s H  o@R	                  U5      PM     snO/ n/ nU Hi  nUR
                  b  U R	                  UR
                  5      OSnUR                   V	s/ s H  o�R	                  U	5      PM     n
n	UR                  XŠ45        Mk     [        [        U5      /U VV
s/ s H  u  pº[        U
5      PM     sn
n-   5      nUS:X  a  gUS-   nS[        U5      -   n/ nS/U VVs/ s H  u  p‹UPM	     snn-   n[        U5       H)  u  nnUR                  [        USSSSUUS-   SSS9	5        M+     [        U5       H‹  nUS-   nU[        U5      :  a  UU   OSnU/U VV
s/ s H  u  pºU[        U
5      :  a  U
U   OSPM     sn
n-   n[        U5       H/  u  nnUR                  [        USSUUS-   UUS-   SUS:H  S9	5        M1     M�     [        XÞUS9$ s  snf s  sn	f s  sn
nf s  snnf s  sn
nf )	uŒ  Reconstruct a chart's underlying data grid as a TableData.

Layout produced (categories down the first column, one column per series):

    | <blank> | <series 0 name> | <series 1 name> | ...
    | cat_0   | val_0,0         | val_1,0         | ...
    | cat_1   | val_0,1         | val_1,1         | ...

Unlike the Excel backend, python-pptx exposes the plotted numbers
directly on each series (``series.values``) and the shared category
labels on the plot (``plot.categories``) â€” no workbook reference
resolution is needed.

Args:
    chart: A python-pptx ``Chart`` object.

Returns:
    A TableData, or None if the chart exposes no usable series.
Nr   r“   r”   TFr‚  r‹  )r'  ÚseriesÚplotsÚ
categoriesr·  r‡   Úvaluesr  Úmaxrl   r  r   Úranger   )rd   r±  Úseries_listr»  Úcatr¼  Úcolumnsrº  r‡   Úvr½  ry  Únum_data_rowsrŒ  r�  r’  Úheader_labelsr˜  r-  Údata_rowr—  ÚcategoryÚ	row_textsr£   s                           rC   Ú_chart_to_table_dataÚ0MsPowerpointDocumentBackend._chart_to_table_data  sT  € ô( ˜5Ÿ<™<Ó(ˆÞØä�U—[‘[Ó!ˆæEJ¨U°1©X×-@Ò-@ÓAÒ-@ c�_‰_˜SÖ!Ñ-@ÒAÐPRð 	ð 02ˆÛ!ˆFØ39·;±;Ñ3J�4—?‘? 6§;¡;Ô/ÐPRˆDØ28·-²-Ó@²-¨Q—o‘o aÖ(±-ˆFÐ@Ø�N‰N˜D˜>Ö*ñ "ô
 œS ›_Ð-ÉgÔ0VÊgÁÀ´°V¶ÉgÒ0VÑVÓWˆØ˜AÓØà  1Ñ$ˆØ”s˜7“|Ñ#ˆØ!#ˆà˜±GÔ<²G©¨£±GÒ<Ñ<ˆÜ'¨Ö6‰NˆG�UØ�L‰LÜØØØØ)*Ø'(Ø)0Ø'.°¡{Ø"&Ø$ñ
öñ 7ô ˜mÖ,ˆHØ ‘lˆGØ/7¼#¸j»/Ó/I�z (Ò+ÈrˆHØ!˜
á!(ô&â!(‘I�Að &.´°F³Ó%;�˜Ò!ÀÒCÙ!(ò&ñ ˆIô "+¨9Ö!5‘�˜Ø—‘ÜØ!Ø!"Ø!"Ø-4Ø+2°Q©;Ø-4Ø+2°Q©;Ø&+Ø$+¨q¡Lñ
öó "6ñ -ô,  (È5ÑQÐQùòm Bùò Aùó 1Wùó  =ùó$&s   ÁH$Â)H)Ã0H.Ä4H4Æ0"H:
c                óŠ  •  UR                   n UR                  nU R                  U5      n	U R                  U5      n
 U R                  U5      nU R                  XSU5      nSnU R                   (       a4   U R#                  X1R$                  5      nUb  [&        R(                  " USS9nU
(       a  UR-                  [.        R0                  U
S9OSnUR3                  UUUUS9n[5        [7        [9        U	S9/S9Ub	  [;        US9OSS9Ul        g! [        [        [        4 a'  n[        R
                  " SU 3[        SS9   SnAgSnAff = f! [        [        4 a    Sn GNFf = f! [        [        [        4 a#  n[        R                  SU5        Sn SnAGNISnAff = f! [*         a    [        R                  S	S
S9   GNf = f)aÇ  Add a native chart shape as a classified PictureItem with its data.

Each chart becomes a PictureItem whose meta carries (a) the chart-type
classification and (b) the chart's plotted numbers reconstructed as a
TableData. The chart title, if any, becomes the picture caption. When
``render_chart_images`` is enabled and LibreOffice is available, a
rendered image is attached; on any rendering failure the picture keeps
its classification and data without an image.

Args:
    shape: The python-pptx graphic-frame shape holding the chart.
    parent_slide: The parent slide group.
    slide_ind: Zero-based slide index.
    doc: The DoclingDocument to update.
    slide_size: The slide size, used for provenance.
z Skipping malformed chart shape: rM  rh  Nz Could not extract chart data: %sr“   rl  rj  z@could not render a chart image; keeping chart data without imageT)Úexc_info)r-  r£   rm  )Ú
class_name)Úpredictions)Ú
chart_data)ÚclassificationÚtabular_chart)r±  r²   rp  r2   rr  rs  rt  r«  ÚNotImplementedErrorr¬  r²  rÉ  rä   rC  rQ  r§   r\   Ú_render_chart_imageÚshape_idr   rv  rb   r6  r   ÚCAPTIONrw  r   r   r   r   Úmeta)rd   r¡   r7  r¢   r�   r¤   r±  rd  r«  rÐ  Úcaption_textÚ
table_datar¦   rz  Úchart_imageÚcaption_itemÚpictures                    rC   Ú_handle_chartÚ)MsPowerpointDocumentBackend._handle_chartk  sÖ  € ð"	Ø—K‘KˆEð	Ø×)Ñ)ˆJð ×;Ñ;¸JÓGˆØ×-Ñ-¨eÓ4ˆð	Ø×2Ñ2°5Ó9ˆJð
 ×"Ñ" 5°R¸ÓDˆàˆ	Ø××ðØ"×6Ñ6°yÇ.Á.ÓQ�ØÑ*Ü (× 1Ò 1¸ÈÑ L�Iö ð �L‰Lœ|×3Ñ3¸,ˆLÑGàð 	ð —/‘/ØØØ Øð	 "ð 
ˆô #Ü9Ü<ÈÑWÐXñð
 Ñ)ô &°Ò<àñ	
ˆŒð 	øôq œH¤oÐ6ó 	Ü�MŠMØ2°3°%Ð8ÜØòô
 ûð	ûô Ô/Ð0ó 	Ø‹Jð	ûô ¤
¬HÐ5ó 	Ü�L‰LÐ;¸SÔAØŽJûð	ûô ó Ü—‘ØVØ!ð ô ðúsQ   ‚D �E ¾E% Á63F  ÄE	Ä"EÅE	ÅE"Å!E"Å%FÅ:FÆFÆ GÇGc                óÚ   • U R                   (       a  U R                  $ SU l         [        (       a  [        5       U l        U R                  c  [        R                  S5        U R                  $ )zÈLazily initialize and return a LibreOffice converter callable.

The converter accepts ``(input_path, output_path)`` and converts the
input file to PDF. Returns None when LibreOffice is not available.
Tu;   LibreOffice not found â€” PPTX charts will not be rendered.)r[   rZ   r4   r6   rC  rU  rn   s    rC   rP  Ú6MsPowerpointDocumentBackend._get_libreoffice_converter¸  sW   € ð ×*×*Ø×-Ñ-Ð-à*.ˆÔ'ß"Ò"Ü)BÓ)DˆDÔ&Ø×%Ñ%Ñ-Ü�J‰JÐTÔUØ×)Ñ)Ð)rE   c                óp  • U R                   c  g[        5       nU R                   R                  U5        UR                  S5        [	        U5      nUR
                  R                  n[        U5      nU[        U5      :¼  a  gUR
                  U   n[        U5       H  u  pšX‘:w  d  M  UR                  U
5        M     [        UR                  5       HH  nUR                  U:w  d  M  UR                  R                  5       R                  UR                  5        MJ     UR                  [        U5      5        g)uä  Save a copy of the presentation holding only the target chart.

A fresh copy of the loaded presentation is reopened, every slide except
the chart's is removed, and on that slide every shape except the chart
is removed. LibreOffice then renders a single-chart page. When the chart
is not a top-level shape (e.g. nested in a group) its ``shape_id`` is not
found among the slide's shapes, so the slide is left intact and the whole
slide is rendered instead â€” a best-effort fallback.

Args:
    slide_ind: Zero-based index of the slide holding the chart.
    chart_shape_id: The ``shape_id`` of the chart's graphic frame.
    out_path: Destination path for the trimmed ``.pptx``.

Returns:
    True when the trimmed presentation was written.
Fr   T)r^   r   ÚsaveÚseekr.   rm   Ú	_sldIdLstr'  rl   r  Úremover  rÔ  rÑ   Ú	getparentra   )rd   r¢   Úchart_shape_idÚout_pathÚbufÚprsÚslide_id_listÚ	slide_idsÚtarget_sliderî   Úslide_idÚshps               rC   Ú_isolate_chart_presentationÚ7MsPowerpointDocumentBackend._isolate_chart_presentationÈ  sñ   € ð( �=‰=Ñ Øä‹iˆØ�‰×Ñ˜3ÔØ�‰�ŒÜ˜3ÓˆàŸ
™
×,Ñ,ˆÜ˜Ó'ˆ	Øœ˜I›Ó&ØØ—z‘z )Ñ,ˆä& yÖ1‰MˆCØÕØ×$Ñ$ XÖ.ñ 2ô ˜×+Ñ+Ö,ˆCØ�|‰|˜~Õ-Ø—‘×&Ñ&Ó(×/Ñ/°·±Ö=ñ -ð 	�‰”�X“ÔØrE   c                ó  • U R                  5       nUc  g[        [        5       5      n US-  nUS-  nU R                  XU5      (       d   [        R
                  " USS9  gU" XV5        UR                  5       (       d,  [        R                  S5         [        R
                  " USS9  g[        R                  " [        U5      5      nUS   n[        UR                  SS	9R                  5       5      n	UR                  5         UR                  5         U	[        R
                  " USS9  $ ! [          a5  n
[        R                  S
U
5         Sn
A
[        R
                  " USS9  gSn
A
ff = f! [        R
                  " USS9  f = f)uk  Render a native chart to an image via LibreOffice.

PPTX stores charts as vector definitions with no embedded raster. To
obtain a picture we isolate the chart onto a throwaway single-slide
presentation, convert that to PDF with LibreOffice â€” the same external
tool already used for EMF/WMF images â€” and rasterize the first page with
pypdfium2, trimming the surrounding whitespace.

Args:
    slide_ind: Zero-based index of the slide holding the chart.
    chart_shape_id: The ``shape_id`` of the chart's graphic frame.

Returns:
    A PIL Image, or None when LibreOffice is unavailable or the
    conversion fails.
Nz
chart.pptxz	chart.pdfTrK  z.LibreOffice produced no PDF output for a chartr   rM  rN  z*Chart rendering via LibreOffice failed: %s)rP  r   r   rï  rV  rW  rT  rC  rU  rX  rY  ra   r5   rZ  r[  r{   rb   )rd   r¢   ræ  r\  r^  r_  r`  ra  rb  rc  rd  s              rC   rÓ  Ú/MsPowerpointDocumentBackend._render_chart_imageõ  sK  € ð& ×3Ñ3Ó5ˆ	ØÑØäœ›	“?ˆð	8Ø! LÑ0ˆJØ" [Ñ0ˆKØ×3Ñ3Ø¨:÷ñ ð ô �MŠM˜(°$Ó7ñ �jÔ.Ø×%Ñ%×'Ñ'Ü—
‘
ÐKÔLØô �MŠM˜(°$Ó7ô ×'Ò'¬¨KÓ(8Ó9ˆCØ�q‘6ˆDÜ'¨¯©¸!¨Ð(<×(CÑ(CÓ(EÓFˆIØ�J‰JŒLØ�I‰IŒKØô
 �MŠM˜(°$Ó7øô	 ó 	Ü�J‰JÐCÀSÔIÛä�MŠM˜(°$Ó7ûð		ûô �MŠM˜(°$Ó7ús6   ©!D+ Á!2D+ Â*A+D+ Ä+
E*Ä5E%ÅE- Å%E*Å*E- Å-Fc           	     óH  ^ ^^^• UR                   nUR                  n[        T R                  [        5      =(       a    T R                  R
                  T l        T R                  (       a1  T R                  5       c   [        R                  [        5        ST l        Sn0 n	[        U5       H  n
S Xš'   M	     [        [        UR                  5      5      US-
  U nU GHB  u  pÍUR                  SU 3[         R"                  U	S   S9n[%        XgS9nUR'                  US-   US9  S	 mUUU 4S
 jmUUU 4S jmT R)                  UR*                  5       H  nT" UXìX/5        M     UR,                  (       a˜  UR.                  nUR0                  b  UR0                  R2                  R5                  5       nU(       aT  [7        SSSSS9n[9        US-   S[;        U5      /US9nUR=                  [>        R@                  UUU[B        RD                  S9  T RG                  XÜX2U5        GME     U$ )NFé
   r”   zslide-r   )r‡   r-  r(  r•   )rš   Úsizec                ó|   •  U R                   $ ! [         a#    [        R                  SU R                  5         gf = f)zÅReturn shape.shape_type, or None if unrecognized.

python-pptx raises NotImplementedError for <p:sp> elements
that don't match any known shape category (placeholder,
freeform, autoshape, textbox).
z)Skipping shape with unrecognized type: %sN)Ú
shape_typerÒ  rC  rU  r‡   )r¡   s    rC   Ú_safe_shape_typeÚBMsPowerpointDocumentBackend._walk_linear.<locals>._safe_shape_typeG  s8   € ð Ø ×+Ñ+Ð+øÜ*ó  Ü—J‘JÐJÈEÏJÉJÔWÙð ús   ‚ Ž*;º;c                ó  >• T" XX#U5        U R                   (       a  TR                  XX#U5        U R                  (       a  TR                  XX#U5        T" U 5      [        R
                  :X  a  TR                  XX#U5        [        U S5      (       d  g U R                  c  g [        U R                  R                  5       5      S:X  a  g U R                  (       d  [        R                  S5        g TR                  XX#U5        g )Nr£   r   z*Warning: shape has text but not text_frame)r�  r�  Ú	has_chartrÜ  r0   ÚPICTUREr|  Úhasattrr£   rl   r/  Úhas_text_framerC  rQ  r@  )r¡   r7  r¢   r�   r¤   rø  Úhandle_groupsrd   s        €€€rC   Úhandle_shapesÚ?MsPowerpointDocumentBackend._walk_linear.<locals>.handle_shapesT  sÚ   ø€ Ù˜e°9À:ÔNØ—?—?à×'Ñ'¨¸YÈZÔXØ—?—?Ø×&Ñ& u¸IÈJÔWÙ# EÓ*¬n×.DÑ.DÓDà×)Ñ)Ø¨Y¸Zôô ˜u f×-Ñ-ØØ—:‘:Ñ%ØÜ�u—z‘z×'Ñ'Ó)Ó*¨aÓ/ØØ×+×+Ü—L‘LÐ!MÔNØð ×*Ñ*Ø¨¸ôð rE   c                ó”   >• T" U 5      [         R                  :X  a-  TR                  U R                  5       H  nT" XQX#U5        M     g g rr   )r0   ÚGROUPr#  r  )	r¡   r7  r¢   r�   r¤   Úgroupedshaperø  r   rd   s	         €€€rC   rÿ  Ú?MsPowerpointDocumentBackend._walk_linear.<locals>.handle_groupsq  sE   ø€ Ù# EÓ*¬n×.BÑ.BÓBØ(,×(EÑ(EÀeÇlÁlÖ(S˜Ù%Ø(¸	È
öò )Tð CrE   )ÚlÚtÚrÚbr™   )r-  r(  r£   r¦   Úcontent_layer)$Úslide_widthÚslide_heightr`   rf   r&   Úrender_chart_imagesr\   rP  rC  rQ  Ú_CHART_RENDER_HINTr¿  r'  r  rm   Ú	add_groupr   ÚCHAPTERr   Úadd_pager#  r  Úhas_notes_slideÚnotes_slideÚnotes_text_framer£   r/  r   r   rl   r6  r   ÚTEXTr   ÚNOTESÚ_extract_slide_comments)rd   r^   r�   r�   r‰   rŠ   r  r  Ú
max_levelsÚparentsÚiÚselected_slidesr¢   rð   r7  r¤   r¡   r  Ú
notes_textrœ   r¦   rø  rÿ  r   s   `                    @@@rC   rŽ   Ú(MsPowerpointDocumentBackend._walk_linear$  s  û€ ð ×*Ñ*ˆØ×,Ñ,ˆô �t—|‘|Ô%?Ó@÷ 1Ø—‘×0Ñ0ð 	Ôð ×× 4×#BÑ#BÓ#DÑ#LÜ�L‰LÔ+Ô,Ø"'ˆDÔàˆ
ØˆÜ�zÖ"ˆAØˆG‹Jñ #ô œy¨¯©Ó9Ó:¸:È¹>ÈHÐUˆÜ /ÑˆIØŸ=™=Ø˜i˜[Ð)´×1CÑ1CÈGÐTUÉJð )ð ˆLô  KÑEˆJØ�L‰L ¨Q¡°ZˆLÑ@ò ÷÷:ð ×6Ñ6°u·|±|ÖD�Ù˜e \¸cÖNñ Eð ×$×$Ø#×/Ñ/�Ø×/Ñ/Ñ;Ø!,×!=Ñ!=×!BÑ!B×!HÑ!HÓ!J�JÞ!Ü*¨Q°!°q¸AÑ>˜Ü-Ø$-°¡MØ&'¬¨Z«Ð%9Ø!%ñ ˜ð
 Ÿ™Ü".×"3Ñ"3Ø#/Ø!+Ø!%Ü*6×*<Ñ*<ð %ñ ð ×(Ñ(Ø *°<÷ñe !0ðl ˆ
rE   c           
     ó  • 0 n UR                   R                  R                  5        H©  nUR                  U R                  :X  d  M  [
        R                  " UR                  R                  [        S9nUR                  SU R                  S9 Vs0 s H8  nUR                  SS5      UR                  SS5      UR                  SS5      4_M:     nnM«     U$ s  snf ! [         a#  n[        R                  SU 35         S	nAU$ S	nAff = f)
z¶Build a map of comment author IDs to (name, initials).

Args:
    pptx_obj: The PowerPoint presentation object.

Returns:
    Dictionary mapping author ID to (name, initials) tuple.
©Úparserz
p:cmAuthorr«   Úidr“   r‡   Úinitialsz&Could not parse PPTX comment authors: N)rï   Úrelsr½  ÚreltypeÚCOMMENT_AUTHORS_RELr   Ú
fromstringÚtarget_partro  r?   ÚfindallrL   r±   rb   rC  rU  )rd   r^   r�   ÚrelÚrootÚ	author_elrg   s          rC   r�   Ú5MsPowerpointDocumentBackend._build_comment_author_map—  s  € ð 24ˆ
ð	EØ—}‘}×)Ñ)×0Ñ0Ö2�Ø—;‘; $×":Ñ":Õ:Ü ×+Ò+ØŸ™×,Ñ,Ô5Eñ�Dð *.¯©Ø(°T·_±_ð *6ñ *ó"ò
*˜Ið	 "Ÿ™ d¨BÓ/Ø%ŸM™M¨&°"Ó5Ø%ŸM™M¨*°bÓ9ð2ò ñ*ð ð "‘Jñ 3ð  Ðùò"øô ó 	EÜ�J‰JÐ?À¸sÐC×DÐDØÐûð	Eús0   „?C ÁA	C Â?CÃC ÃC Ã
D	Ã&DÄD	c           	     óð  •  UR                   nUR                  R                  5        GHá  nUR                  U R                  :w  a  M    [        R                  " UR                  R                  [        S9n	U	R                  SU R                  S9 GHt  n
U
R                  SS	5      nU
R                  S
S	5      nU
R!                  SU R                  S9nUb#  UR"                  =(       d    S	R%                  5       OS	nU(       d  Ms  UR                  US5      u  nn/ nU(       a&  SU 3nU(       a	  USU S3-  nUR'                  U5        U(       a  UR'                  SU 35        SR)                  U5      nU(       a  SU SU 3OUnU
R                  S[+        U5      5      nUR-                  [.        R0                  SUS-    SU 3[2        R4                  S9nUR7                  USUS9  [        R                  SUS-    SU 35        GMw     GMä     g! [         a(  n[        R                  SUS-    SU 35         SnAgSnAff = f! [         a'  n[        R                  SU SU 35         SnAGMH  SnAff = f)aD  Extract and add comments for a specific slide.

Args:
    slide: The slide object to extract comments from.
    slide_idx: Zero-based slide index.
    author_map: Dictionary mapping author ID to (name, initials).
    doc: The DoclingDocument to add comments to.
    parent_slide: The parent slide group to link comments to.
z&Could not access slide part for slide r”   z, skipping comment extraction: Nr  zp:cmr«   ÚauthorIdr“   Údtzp:text)r“   r“   zauthor: z (Ú)ztime: z, Ú[z]: rî   zcomment-slideÚ-)r-  r‡   r
  )r£   Útargetsr(  zAdded PPTX comment slide z idx=z#Could not parse comments for slide z: )rï   rb   rC  rU  r#  r½  r$  ÚCOMMENT_RELr   r&  r'  ro  r?   r(  rL   r±   r®   r£   r/  r  Újoinra   r  r   ÚCOMMENT_SECTIONr   r  Úadd_comment)rd   rð   Ú	slide_idxr�   r�   r7  Ú
slide_partrg   r)  r*  ÚcmÚ	author_idr/  Útext_elÚraw_textr‡   r"  Úmetadata_partsÚ
author_strÚprefixÚ	full_textÚcomment_idxÚcomment_groups                          rC   r  Ú3MsPowerpointDocumentBackend._extract_slide_comments¶  s_  € ð"	ØŸ™ˆJð —?‘?×)Ñ)×+ˆCØ�{‰{˜d×.Ñ.Ó.Ùð'SÜ×'Ò'¨¯©×(<Ñ(<ÔEUÑV�ØŸ,™, v¸$¿/¹/˜,ÔJ�BØ "§¡ z°2Ó 6�IØŸ™  bÓ)�BØ Ÿg™g h¸4¿?¹?˜gÐK�Gà8?Ñ8K˜Ÿ™×+¨×2Ñ2Ô4ÐQSð ö $Ù à%/§^¡^°I¸xÓ%H‘N�D˜(Ø%'�NÞØ'/°¨vÐ%6˜
Þ#Ø&¨B¨x¨j¸Ð*:Ñ:˜JØ&×-Ñ-¨jÔ9ÞØ&×-Ñ-°°r°d¨mÔ<Ø!ŸY™Y ~Ó6�FÞ=C ! F 8¨3¨x¨jÑ 9È�Ià"$§&¡&¨´°I³Ó"?�KØ$'§M¡MÜ(×8Ñ8Ø,¨Y¸©]¨O¸1¸[¸MÐJÜ&2×&8Ñ&8ð %2ð %�Mð
 —O‘OØ&Ø $Ø,ð $ñ ô
 —J‘JØ3°IÀ±M°?À%ÈÀ}ÐU÷ôC Kò ,øô ó 	Ü�J‰JØ8¸ÀQ¹¸ð H0Ø01¨sð4ôô ûð	ûô` ó SÜ—
‘
Ð@ÀÀÈ2ÈaÈSÐQ×RÓRûðSús0   ‚H Á	G IÈ
IÈH<È<IÉ
I5ÉI0É0I5)r]   r\   rY   rW   r^   rZ   r[   r_   rr   )re   r)   rW   zUnion[BytesIO, Path]rf   z$Optional[MsPowerpointBackendOptions]Úreturnrâ   )rE  r°   )rE  r+   )rE  zset[InputFormat])rE  r   )rE  ú3tuple[Optional[bool], Optional[str], Optional[str]])r­   r°   )r­   r°   rE  rF  )rE  zOptional[etree._Element])rE  ztuple[bool, str])rE  Údict)r¡   r  rý   ra   rE  úOptional[int])r  zIterable[object]rE  zIterator[object])r�   r   )rB   ÚbytesrE  úOptional[Image.Image])r«  r   rE  r   )r±  r   rE  zOptional[str])rþ   r   rE  ra   )r±  r   rE  zOptional[TableData])rE  zOptional[Callable])r¢   r°   ræ  r°   rç  r   rE  r+   )r¢   r°   ræ  r°   rE  rJ  )r”   N)r^   úpresentation.Presentationr�   r   r�   údict[str, tuple[str, str]]r‰   r°   rŠ   rH  rE  r   )r^   rK  rE  rL  )r8  r°   r�   rL  r�   r   rE  râ   )2r  r  r	  r
  Ú__doc__rL   r  rM   r4  r%  rV   ro   r"   rk   Úclassmethodrx   r|   r€   r‘   r   r§   rµ   rÁ   rÆ   rÎ   rØ   rÜ   ré   rå   rÿ   r#  r@  rH  re  r|  r�  Ústaticmethodr¬  r²  r·  rÉ  rÜ  rP  rï  rÓ  rŽ   r�   r  r  Ú__classcell__)rh   s   @rC   rG   rG   …   sÔ  ø‡ ñð" EØEØIñ)€JÐ%ó ð
 ,1Ð˜jÓ0ðð 	Wð ð	ð ð 9=ð	#àð#ð -ð#ð 6ð	#ð
 
÷#ð #ôJð óó ðð Øóó ó ðð ñ#ó ð#ð Øó3ó ó ð3ð óó ðð2 &(±D¸qÈÑ4Kôô*ð,)"à	<ô)"ôV>ð&'Øð'à	<ô'ð4Ià	!ôIð<'Ø36ð'à	<ô'ô:A#ôFl
ô\ô2EðNEØ3BôEòNô.*8òX5òn>ð@ ó6ó ð6ð: óó ðð óó ðô&PRòdKôZ*ð +Øð+Ø.1ð+Ø=Að+à	ô+ðZ-8Øð-8Ø.1ð-8à	ô-8ðh Ø"&ðqà+ðqð ðqð /ð	qð
 ðqð  ðqð 
õqðfØ1ðà	#ôð>DSð ðDSð /ð	DSð
 ðDSð 
÷DSò DSrE   rG   )rB   rI  rE  r+   )[Ú
__future__r   ÚloggingrV  rr  Úior   Úpathlibr   Útempfiler   r  r   r   r	   r
   r   r   r   Údocling_core.types.docr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Údocling_core.types.doc.documentr   Úlxmlr   ÚPILr    r!   Útyping_extensionsr"   Ú docling.backend.abstract_backendr#   r$   Ú$docling.backend.docx.drawingml.utilsr%   Ú!docling.datamodel.backend_optionsr&   Údocling.datamodel.base_modelsr'   r(   Údocling.datamodel.documentr)   Údocling.exceptionsr*   Ú	getLoggerr  rC  r,   r  r-   rP   r.   r/   Úpptx.enum.shapesr0   r1   Úpptx.excr2   Úpptx.oxml.textr3   rQ   rg   r4   rX  r5   r6   rR   r  rR  r7   r8   r:   Ú	XMLParserr?   rD   rG   ru   rE   rC   Ú<module>rf     sq  ðö #ã Û Û Ý Ý Ý ß L× LÑ L÷÷ ÷ ÷ ó õ$ 9Ý ß -Ý &÷õ JÝ Hß GÝ 4Ý 0à×Ò˜Ó"€à€�Ó Ø)-Ð Ð&Ó -ðß/ß?Ý(Ý/à€Oð !&Ð ˜Ó %ð
	Û÷ð
 #Ðð
Að ðð ðð ð 2Ð �eÓ 1Ø€�Ó Ø!Ð �uÓ !ð  Ÿ/š/ØØØØñ	Ð �%ó ð Uôô&uSÐ"<Ð>Võ uSøðW ó ØÕûðûð" ó 	Ùð	ús*   Â?D9 Ã%E Ä9EÄ?EÅEÅEÅE