o
    7 hnu                     @  s  d Z ddlmZ ddlZddlmZmZmZmZm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZmZ ddlmZmZmZ dd	lmZmZ dd
lmZ ddlmZ ddlm Z  erxddl!m"Z" ddlm#Z#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z* G dd dZ+G dd de+Z,G dd dZ-G dd de+Z.G dd de.Z/G dd dZ0G dd dZ1G d d! d!e	e2d"f Z3G d#d" d"Z4dS )$zFundamental Open Packaging Convention (OPC) objects.

The :mod:`pptx.packaging` module coheres around the concerns of reading and writing
presentations to and from a .pptx file.
    )annotationsN)IOTYPE_CHECKINGDefaultDictIteratorMappingSetcast)RELATIONSHIP_TARGET_MODE)RELATIONSHIP_TYPE)CT_Relationshipsserialize_part_xml)CONTENT_TYPES_URIPACKAGE_URIPackURI)PackageReaderPackageWriter)CaseInsensitiveDict)	parse_xml)lazyproperty)Self)CT_RelationshipCT_Types)BaseOxmlElement)Package)PresentationPartc                   @  sH   e Zd ZdZdddZddddZdddZdddZedddZ	dS )_RelatableMixinzHProvide relationship methods required by both the package and each part.reltypestrreturnPartc                 C     | j |S )zReturn (single) part having relationship to this package of `reltype`.

        Raises |KeyError| if no such relationship is found and |ValueError| if more than one such
        relationship is found.
        )_relspart_with_reltype)selfr    r%   X/var/www/html/figdemos/bartoux_crm/venv/lib/python3.10/site-packages/pptx/opc/package.pypart_related_by!   s   z_RelatableMixin.part_related_byFtarget
Part | stris_externalboolc                 C  s.   t |tr|s	J | j||S | j||S )zReturn rId key of relationship of `reltype` to `target`.

        If such a relationship already exists, its rId is returned. Otherwise the relationship is
        added and its new rId returned.
        )
isinstancer   r"   get_or_add_ext_rel
get_or_add)r$   r(   r   r*   r%   r%   r&   	relate_to)   s   
z_RelatableMixin.relate_torIdc                 C     | j | jS )z2Return related |Part| subtype identified by `rId`.)r"   target_partr$   r0   r%   r%   r&   related_part5      z_RelatableMixin.related_partc                 C  r1   )zGReturn URL contained in target ref of relationship identified by `rId`.)r"   
target_refr3   r%   r%   r&   r6   9   r5   z_RelatableMixin.target_ref_Relationshipsc                 C  s   t dt| j )zJ|_Relationships| object containing relationships from this part to others.z`%s` must implement `.rels`)NotImplementedErrortype__name__r$   r%   r%   r&   r"   =   s   z_RelatableMixin._relsNr   r   r   r    F)r(   r)   r   r   r*   r+   r   r   )r0   r   r   r    )r0   r   r   r   r   r7   )
r:   
__module____qualname____doc__r'   r/   r4   r6   r   r"   r%   r%   r%   r&   r      s    


r   c                   @  s   e Zd ZdZd$ddZed%dd	Zd&ddZd'ddZd(ddZ	e
d)ddZd*ddZd+ddZd,ddZed-d!d"Zd#S ).
OpcPackagezMain API class for |python-opc|.

    A new instance is constructed by calling the :meth:`open` classmethod with a path to a package
    file or file-like object containing a package (.pptx file).
    pkg_filestr | IO[bytes]c                 C  
   || _ d S N)	_pkg_filer$   rC   r%   r%   r&   __init__L      
zOpcPackage.__init__r   r   c                 C  s   | |  S )zGReturn an |OpcPackage| instance loaded with the contents of `pkg_file`._load)clsrC   r%   r%   r&   openO      zOpcPackage.openr0   r   Nonec                 C  s   | j | dS )z(Remove relationship identified by `rId`.Nr"   popr3   r%   r%   r&   drop_relT   s   zOpcPackage.drop_relIterator[Part]c                 c  sB    t  }|  D ]}|jrq|j}||v rq|V  || qdS )z;Generate exactly one reference to each part in the package.N)set	iter_relsr*   r2   add)r$   visitedrelpartr%   r%   r&   
iter_partsX   s   zOpcPackage.iter_partsIterator[_Relationship]c                 #  s,    t   d fdd| jE dH  dS )	zGenerate exactly one reference to each relationship in package.

        Performs a depth-first traversal of the rels graph.
        relsr7   r   r\   c                 3  sL    |   D ]}|V  |jrq|j}| v rq | |jE d H  qd S rF   )valuesr*   r2   rW   r]   )r]   rY   rZ   rX   	walk_relsr%   r&   r`   k   s   
z'OpcPackage.iter_rels.<locals>.walk_relsN)r]   r7   r   r\   )rU   r"   r;   r%   r_   r&   rV   d   s   zOpcPackage.iter_relsr   c                 C  s   t d| tjS )zReturn |Part| subtype serving as the main document part for this package.

        In this case it will be a |Presentation| part.
        r   )r	   r'   RTOFFICE_DOCUMENTr;   r%   r%   r&   main_document_part}   s   zOpcPackage.main_document_parttmplr   c                   sj   |d|d  d   fdd|  D }tt|d ddD ]}|| }||vr0t|  S q td	)
a  Return |PackURI| next available partname matching `tmpl`.

        `tmpl` is a printf (%)-style template string containing a single replacement item, a '%d'
        to be used to insert the integer portion of the partname. Example:
        '/ppt/slides/slide%d.xml'
        N*   42c                   s   h | ]}|j  r|j qS r%   )partname
startswith.0pprefixr%   r&   	<setcomp>   s    z+OpcPackage.next_partname.<locals>.<setcomp>   r   z0ProgrammingError: ran out of candidate_partnames)findr[   rangelenr   	Exception)r$   rd   Z	partnamesnZcandidate_partnamer%   rl   r&   next_partname   s   
zOpcPackage.next_partnamec                 C  s   t || jt|   dS )zzSave this package to `pkg_file`.

        `file` can be either a path to a file (a string) or a file-like object.
        N)r   writer"   tupler[   rH   r%   r%   r&   save   s   zOpcPackage.savec                 C  s,   t | jtd| \}}| jt|| | S )z=Return the package after loading all parts and relationships.r   )_PackageLoaderloadrG   r	   r"   load_from_xmlr   )r$   Zpkg_xml_relspartsr%   r%   r&   rL      s   zOpcPackage._loadr7   c                 C  s
   t tjS )z@|Relationships| object containing relationships of this package.)r7   r   baseURIr;   r%   r%   r&   r"         
zOpcPackage._relsN)rC   rD   )rC   rD   r   r   r0   r   r   rP   )r   rT   )r   r\   )r   r   )rd   r   r   r   )rC   rD   r   rP   )r   r   r>   )r:   r?   r@   rA   rI   classmethodrN   rS   r[   rV   propertyrc   rv   ry   rL   r   r"   r%   r%   r%   r&   rB   E   s    






rB   c                   @  st   e Zd ZdZd ddZed!d
dZd"ddZed#ddZ	ed$ddZ
ed%ddZed&ddZd'ddZdS )(rz   z@Function-object that loads a package from disk (or other store).rC   rD   packager   c                 C     || _ || _d S rF   )rG   _package)r$   rC   r   r%   r%   r&   rI         
z_PackageLoader.__init__r   ,tuple[CT_Relationships, dict[PackURI, Part]]c                 C  s   | ||  S )a	  Return (pkg_xml_rels, parts) pair resulting from loading `pkg_file`.

        The returned `parts` value is a {partname: part} mapping with each part in the package
        included and constructed complete with its relationships to other parts in the package.

        The returned `pkg_xml_rels` value is a `CT_Relationships` object containing the parsed
        package relationships. It is the caller's responsibility (the package object) to load
        those relationships into its |_Relationships| object.
        rK   )rM   rC   r   r%   r%   r&   r{      s   z_PackageLoader.loadc                 C  s<   | j | j}}| D ]\}}||| | q|t |fS )zBReturn (pkg_xml_rels, parts) pair resulting from loading pkg_file.)_parts	_xml_relsitemsload_rels_from_xmlr   )r$   r}   xml_relsrg   rZ   r%   r%   r&   rL      s   z_PackageLoader._load_ContentTypeMapc                 C  s   t | jt S )z|_ContentTypeMap| object providing content-types for items of this package.

        Provides a content-type (MIME-type) for any given partname.
        )r   from_xml_package_readerr   r;   r%   r%   r&   _content_types   s   z_PackageLoader._content_typesr   c                 C  
   t | jS )zE|PackageReader| object providing access to package-items in pkg_file.)r   rG   r;   r%   r%   r&   r      r   z_PackageLoader._package_readerdict[PackURI, Part]c                   s4   | j  | j| j fdddd | jD D S )aU  dict {partname: Part} populated with parts loading from package.

        Among other duties, this collection is passed to each relationships collection so each
        relationship can resolve a reference to its target part when required. This reference can
        only be reliably carried out once the all parts have been loaded.
        c              	     s.   i | ]}|v r|t | | | d qS ))blob)PartFactory)rj   rg   content_typesr   Zpackage_readerr%   r&   
<dictcomp>   s    	z)_PackageLoader._parts.<locals>.<dictcomp>c                 s  s    | ]	}|d kr|V  qdS )/Nr%   ri   r%   r%   r&   	<genexpr>       z(_PackageLoader._parts.<locals>.<genexpr>)r   r   r   r   r;   r%   r   r&   r      s   z_PackageLoader._partsdict[PackURI, CT_Relationships]c                   s2   i t  d fdd  tt S )	zdict {partname: xml_rels} for package and all package parts.

        This is used as the basis for other loading operations such as loading parts and
        populating their relationships.
        source_partnamer   r]   r   c                   s^   || <  |  | j}|jD ]}|jtjkrqt||j}|v r$q |	| qdS )zAPopulate `xml_rels` dict by traversing relationships depth-first.N)
rW   r~   relationship_lst
targetModeRTMEXTERNALr   from_rel_refr6   _xml_rels_for)r   r]   base_urirY   target_partname	load_relsr$   Zvisited_partnamesr   r%   r&   r      s   

z+_PackageLoader._xml_rels.<locals>.load_relsN)r   r   r]   r   )rU   r   r   r;   r%   r   r&   r      s
   z_PackageLoader._xml_relsrg   r   r   c                 C  s*   | j |}|du rt S ttt|S )a  Return CT_Relationships object formed by parsing rels XML for `partname`.

        A CT_Relationships object is returned in all cases. A part that has no relationships
        receives an "empty" CT_Relationships object, i.e. containing no `CT_Relationship` objects.
        N)r   Zrels_xml_forr   newr	   r   )r$   rg   Zrels_xmlr%   r%   r&   r     s   z_PackageLoader._xml_rels_forN)rC   rD   r   r   )rC   rD   r   r   r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )rg   r   r   r   )r:   r?   r@   rA   rI   r   r{   rL   r   r   r   r   r   r   r%   r%   r%   r&   rz      s    

	rz   c                   @  s   e Zd ZdZ	d,d-ddZed.ddZed/ddZej	d0ddZe
d1ddZd2ddZe
d3ddZed4d d!Zej	d5d"d!Ze
d6d$d%Zd7d(d)Ze
d6d*d+ZdS )8r    a   Base class for package parts.

    Provides common properties and methods, but intended to be subclassed in client code to
    implement specific part behaviors. Also serves as the default class for parts that are not yet
    given specific behaviors.
    Nrg   r   content_typer   r   r   r   bytes | Nonec                 C  s   || _ || _|| _|| _d S rF   )	_partname_content_typer   _blob)r$   rg   r   r   r   r%   r%   r&   rI   !  s   
zPart.__init__bytesr   r   c                 C  s   | ||||S )zReturn `cls` instance loaded from arguments.

        This one is a straight pass-through, but subtypes may do some pre-processing, see XmlPart
        for an example.
        r%   rM   rg   r   r   r   r%   r%   r&   r{   *  s   z	Part.loadc                 C  s
   | j pdS )zContents of this package part as a sequence of bytes.

        Intended to be overridden by subclasses. Default behavior is to return the blob initial
        loaded during `Package.open()` operation.
            r   r;   r%   r%   r&   r   3     
z	Part.blobc                 C  s
   || _ dS )zNote that not all subclasses use the part blob as their blob source.

        In particular, the |XmlPart| subclass uses its `self._element` to serialize a blob on
        demand. This works fine for binary parts though.
        Nr   )r$   r   r%   r%   r&   r   <  r   c                 C     | j S )z&Content-type (MIME-type) of this part.)r   r;   r%   r%   r&   r   E     zPart.content_typer   r   r}   r   rP   c                 C  s   | j | jj|| dS )aT  load _Relationships for this part from `xml_rels`.

        Part references are resolved using the `parts` dict that maps each partname to the loaded
        part with that partname. These relationships are loaded from a serialized package and so
        already have assigned rIds. This method is only used during package loading.
        N)r"   r|   r   r~   )r$   r   r}   r%   r%   r&   r   J  s   zPart.load_rels_from_xmlc                 C  r   )zPackage this part belongs to.)r   r;   r%   r%   r&   r   S  r   zPart.packagec                 C  r   )z@|PackURI| partname for this part, e.g. "/ppt/slides/slide1.xml".)r   r;   r%   r%   r&   rg   X  r   zPart.partnamec                 C  s&   t |tstdt|j || _d S )Nz.partname must be instance of PackURI, got '%s')r,   r   	TypeErrorr9   r:   r   r$   rg   r%   r%   r&   rg   ]  s
   

r7   c                 C  r   )z:Collection of relationships from this part to other parts.r"   r;   r%   r%   r&   r]   e  s   z	Part.relsfilerD   c                 C  s\   t |trt|d}| W  d   S 1 sw   Y  tt|dr*|d | S )zIReturn bytes of `file`, which is either a str path or a file-like object.rbNseekr   )r,   r   rN   readcallablegetattrr   )r$   r   fr%   r%   r&   _blob_from_filek  s   
 
zPart._blob_from_filec                 C  s   t | jjS )z'Relationships from this part to others.)r7   r   r~   r;   r%   r%   r&   r"   x  rO   z
Part._relsrF   )rg   r   r   r   r   r   r   r   )
rg   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   )r   r   r}   r   r   rP   )r   r   r   r   )rg   r   r>   )r   rD   r   r   )r:   r?   r@   rA   rI   r   r{   r   r   setterr   r   r   r   rg   r]   r   r"   r%   r%   r%   r&   r      s0    	
	
r    c                      s^   e Zd ZdZd fd
dZedddZedddZdddZ	edd Z
d ddZ  ZS )!XmlPartzBase class for package parts containing an XML payload, which is most of them.

    Provides additional methods to the |Part| base class that take care of parsing and
    reserializing the XML payload and managing relationships to other parts.
    rg   r   r   r   r   r   elementr   c                   s   t t| ||| || _d S rF   )superr   rI   _element)r$   rg   r   r   r   	__class__r%   r&   rI     s   
zXmlPart.__init__r   r   c                 C  s   | |||t dt|dS )z<Return instance of `cls` loaded with parsed XML from `blob`.r   )r   )r	   r   r   r%   r%   r&   r{     s   zXmlPart.loadr   c                 C  r   )z%bytes XML serialization of this part.)r   r   r;   r%   r%   r&   r     r   zXmlPart.blobr0   rP   c                 C  s"   |  |dk r| j| dS dS )zRemove relationship identified by `rId` if its reference count is under 2.

        Relationships with a reference count of 0 are implicit relationships. Note that only XML
        parts can drop relationships.
           N)_rel_ref_countr"   rR   r3   r%   r%   r&   rS     s   zXmlPart.drop_relc                 C  s   | S )zThis part.

        This is part of the parent protocol, "children" of the document will not know the part
        that contains them so must ask their parent object. That chain of delegation ends here for
        child objects.
        r%   r;   r%   r%   r&   rZ     s   zXmlPart.partintc                   s$   t  fddtd| jdD S )z;Return int count of references in this part's XML to `rId`.c                   s   g | ]}| kr|qS r%   r%   )rj   rr0   r%   r&   
<listcomp>  s    z*XmlPart._rel_ref_count.<locals>.<listcomp>z	list[str]z//@r:id)rs   r	   r   Zxpathr3   r%   r   r&   r     s   $zXmlPart._rel_ref_count)rg   r   r   r   r   r   r   r   )rg   r   r   r   r   r   r   r   r   r   )r0   r   r   r   )r:   r?   r@   rA   rI   r   r{   r   r   rS   rZ   r   __classcell__r%   r%   r   r&   r   ~  s    
	
	r   c                   @  s6   e Zd ZU dZi Zded< dddZedddZdS )r   zConstructs a registered subtype of |Part|.

    Client code can register a subclass of |Part| to be used for a package blob based on its
    content type.
    zdict[str, type[Part]]part_type_forrg   r   r   r   r   r   r   r   r   r    c                 C  s   |  |}|||||S rF   )_part_cls_forr{   )rM   rg   r   r   r   Z	PartClassr%   r%   r&   __new__  s   
zPartFactory.__new__
type[Part]c                 C  s   || j v r
| j | S tS )zReturn the custom part class registered for `content_type`.

        Returns |Part| if no custom class is registered for `content_type`.
        )r   r    )rM   r   r%   r%   r&   r     s   

zPartFactory._part_cls_forN)
rg   r   r   r   r   r   r   r   r   r    )r   r   r   r   )	r:   r?   r@   rA   r   __annotations__r   r   r   r%   r%   r%   r&   r     s   
 
r   c                   @  s2   e Zd ZdZdddZdddZedddZdS )r   zLValue type providing dict semantics for looking up content type by partname.	overridesdict[str, str]defaultsc                 C  r   rF   )
_overrides	_defaults)r$   r   r   r%   r%   r&   rI     r   z_ContentTypeMap.__init__rg   r   r   r   c                 C  sT   t |tstdt|j || jv r| j| S |j| jv r$| j|j S td| )zBReturn content-type (MIME-type) for part identified by *partname*.z4_ContentTypeMap key must be <type 'PackURI'>, got %sz8no content-type for partname '%s' in [Content_Types].xml)	r,   r   r   r9   r:   r   extr   KeyErrorr   r%   r%   r&   __getitem__  s   


z_ContentTypeMap.__getitem__content_types_xmlr   c                 C  s@   t dt|}tdd |jD }tdd |jD }| ||S )zEReturn |_ContentTypeMap| instance populated from `content_types_xml`.r   c                 s       | ]}|j  |jfV  qd S rF   )ZpartNamelowercontentType)rj   or%   r%   r&   r         
z+_ContentTypeMap.from_xml.<locals>.<genexpr>c                 s  r   rF   )	extensionr   r   )rj   dr%   r%   r&   r     r   )r	   r   r   Zoverride_lstZdefault_lst)rM   r   Z	types_elmr   r   r%   r%   r&   r     s   
z_ContentTypeMap.from_xmlN)r   r   r   r   )rg   r   r   r   )r   r   r   r   )r:   r?   r@   rA   rI   r   r   r   r%   r%   r%   r&   r     s    

r   c                   @  s   e Zd ZdZd<ddZd=d
dZd>ddZd?ddZd@ddZdAddZ	dBddZ
dCd"d#ZdDd$d%Zd>d&d'Zed(d) ZdEdFd.d/Z	*dEdGd1d2ZedHd3d4ZedId6d7ZedJd9d:Zd;S )Kr7   a  Collection of |_Relationship| instances having `dict` semantics.

    Relationships are keyed by their rId, but may also be found in other ways, such as by their
    relationship type. |Relationship| objects are keyed by their rId.

    Iterating this collection has normal mapping semantics, generating the keys (rIds) of the
    mapping. `rels.keys()`, `rels.values()`, and `rels.items() can be used as they would be for a
    `dict`.
    r   r   c                 C  rE   rF   )	_base_uri)r$   r   r%   r%   r&   rI     rJ   z_Relationships.__init__r0   objectr   r+   c                 C  s
   || j v S )z9Implement 'in' operation, like `"rId7" in relationships`.r   r3   r%   r%   r&   __contains__     
z_Relationships.__contains___Relationshipc                 C  s(   z| j | W S  ty   td| w )zJImplement relationship lookup by rId using indexed access, like rels[rId].zno relationship with key '%s')r"   r   r3   r%   r%   r&   r     s
   z_Relationships.__getitem__Iterator[str]c                 C  r   )zDImplement iteration of rIds (iterating a mapping produces its keys).)iterr"   r;   r%   r%   r&   __iter__  r   z_Relationships.__iter__r   c                 C  r   )z,Return count of relationships in collection.)rs   r"   r;   r%   r%   r&   __len__
  r   z_Relationships.__len__r   r2   r    c                 C  s$   |  ||}|du r| ||S |S )zReturn str rId of `reltype` to `target_part`.

        The rId of an existing matching relationship is used if present. Otherwise, a new
        relationship is added and that rId is returned.
        N_get_matching_add_relationship)r$   r   r2   existing_rIdr%   r%   r&   r.     s
   z_Relationships.get_or_addr6   c                 C  s,   | j ||dd}|du r| j||ddS |S )zReturn str rId of external relationship of `reltype` to `target_ref`.

        The rId of an existing matching relationship is used if present. Otherwise, a new
        relationship is added and that rId is returned.
        T)r*   Nr   )r$   r   r6   r   r%   r%   r&   r-     s   z!_Relationships.get_or_add_ext_relr   r   r}   r   rP   c                   s6    fdd}| j   | j dd | D  dS )zHReplace any relationships in this collection with those from `xml_rels`.c                  3  sF    j D ]} | jtjkrt | j}|vrqt | V  qdS )z?Filter out broken relationships such as those pointing to NULL.N)	r   r   r   INTERNALr   r   r6   r   r   )Zrel_elmrg   r   r}   r   r%   r&   iter_valid_rels+  s   
z5_Relationships.load_from_xml.<locals>.iter_valid_relsc                 s  s    | ]}|j |fV  qd S rF   r   )rj   rY   r%   r%   r&   r   9  s    z/_Relationships.load_from_xml.<locals>.<genexpr>N)r"   clearupdate)r$   r   r   r}   r   r%   r   r&   r|   &  s   
z_Relationships.load_from_xmlc                 C  sD   | j | }t|dkrtd| t|dkrtd| |d jS )zReturn target part of relationship with matching `reltype`.

        Raises |KeyError| if not found and |ValueError| if more than one matching relationship is
        found.
        r   z*no relationship of type '%s' in collectionro   z1multiple relationships of type '%s' in collection)_rels_by_reltypers   r   
ValueErrorr2   )r$   r   Zrels_of_reltyper%   r%   r&   r#   ;  s   

z _Relationships.part_with_reltypec                 C  r!   )zReturn |_Relationship| identified by `rId` after removing it from collection.

        The caller is responsible for ensuring it is no longer required.
        rQ   r3   r%   r%   r&   rR   K  s   z_Relationships.popc                   s>   t  } fdd}| D ]}||j|j|j|j q|jS )zbytes XML serialization of this relationship collection.

        This value is suitable for storage as a .rels file in an OPC package. Includes a `<?xml..`
        declaration header with encoding as UTF-8.
        c                    s(   t dd   D }  fdd| D S )Nc                 s  sB    | ]}| d r|dd  rt|dd nd|fV  qdS )r0      Nr   )rh   isdigitr   )rj   r0   r%   r%   r&   r   ^  s    ,
zK_Relationships.xml.<locals>.iter_rels_in_numerical_order.<locals>.<genexpr>c                 3  s    | ]	\}} | V  qd S rF   r%   )rj   _r0   r;   r%   r&   r   e  r   )sortedkeys)Zsorted_num_rId_pairsr;   r%   r&   iter_rels_in_numerical_order]  s   z8_Relationships.xml.<locals>.iter_rels_in_numerical_order)r   r   Zadd_relr0   r   r6   r*   Zxml_file_bytes)r$   Zrels_elmr   rY   r%   r;   r&   xmlR  s
   

z_Relationships.xmlFr(   r)   r*   c                 C  s0   | j }t| j|||rtjntj|d| j|< |S )z6Return str rId of |_Relationship| newly added to spec.)target_moder(   )	_next_rIdr   r   r   r   r   r"   )r$   r   r(   r*   r0   r%   r%   r&   r   l  s   z _Relationships._add_relationship
str | Nonec                 C  sD   | j | D ]}|j|krq|jr|jn|j}||kr|j  S qdS )zReturn optional str rId of rel of `reltype`, `target`, and `is_external`.

        Returns `None` on no matching relationship
        N)r   r*   r6   r2   r0   )r$   r   r(   r*   rY   Z
rel_targetr%   r%   r&   r   x  s   

z_Relationships._get_matchingc                 C  s<   t t| d ddD ]}d| }|| jvr|  S q
td)zNext str rId available in collection.

        The next rId is the first unused key starting from "rId1" and making use of any gaps in
        numbering, e.g. 'rId2' for rIds ['rId1', 'rId3'].
        ro   r   rp   zrId%dzJProgrammingError: Impossible to have more distinct rIds than relationships)rr   rs   r"   rt   )r$   ru   ZrId_candidater%   r%   r&   r    s   

z_Relationships._next_rIddict[str, _Relationship]c                 C  s   i S )zFdict {rId: _Relationship} containing relationships of this collection.r%   r;   r%   r%   r&   r"     s   z_Relationships._relsdict[str, list[_Relationship]]c                 C  s,   t t}|  D ]
}||j | q	|S )zBdefaultdict {reltype: [rels]} for all relationships in collection.)collectionsdefaultdictlistr^   r   append)r$   DrY   r%   r%   r&   r     s   
z_Relationships._rels_by_reltypeN)r   r   )r0   r   r   r+   )r0   r   r   r   )r   r   )r   r   )r   r   r2   r    r   r   )r   r   r6   r   r   r   )r   r   r   r   r}   r   r   rP   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@   rA   rI   r   r   r   r   r.   r-   r|   r#   rR   r   r   r   r   r  r   r"   r   r%   r%   r%   r&   r7     s.    











r7   r   c                   @  s|   e Zd ZdZd"d	d
Zed#ddZed$ddZed%ddZ	ed%ddZ
ed&ddZed'ddZed%dd Zd!S )(r   zDValue object describing link from a part or package to another part.r   r   r0   r   r   r(   r)   c                 C  s"   || _ || _|| _|| _|| _d S rF   )r   _rId_reltype_target_mode_target)r$   r   r0   r   r   r(   r%   r%   r&   rI     s
   
z_Relationship.__init__rY   r   r}   r   r   c                 C  s:   |j tjkr	|jn|t||j }| ||j|j|j |S )zEReturn |_Relationship| object based on CT_Relationship element `rel`.)r   r   r   r6   r   r   r0   r   )rM   r   rY   r}   r(   r%   r%   r&   r     s
   z_Relationship.from_xmlr+   c                 C  s   | j tjkS )zTrue if target_mode is `RTM.EXTERNAL`.

        An external relationship is a link to a resource outside the package, such as a
        web-resource (URL).
        )r  r   r   r;   r%   r%   r&   r*     s   z_Relationship.is_externalc                 C  r   )zHMember of RELATIONSHIP_TYPE describing relationship of target to source.)r  r;   r%   r%   r&   r     r   z_Relationship.reltypec                 C  r   )zstr relationship-id, like 'rId9'.

        Corresponds to the `Id` attribute on the `CT_Relationship` element and uniquely identifies
        this relationship within its peers for the source-part or package.
        )r
  r;   r%   r%   r&   r0     s   z_Relationship.rIdr    c                 C  s$   | j rtdt| jtsJ | jS )z3|Part| or subtype referred to by this relationship.zR`.target_part` property on _Relationship is undefined when target-mode is external)r*   r   r,   r  r    r;   r%   r%   r&   r2     s   z_Relationship.target_partr   c                 C  s&   | j rtdt| jtsJ | jjS )z|PackURI| instance containing partname targeted by this relationship.

        Raises `ValueError` on reference if target_mode is external. Use :attr:`target_mode` to
        check before referencing.
        zV`.target_partname` property on _Relationship is undefined when target-mode is external)r*   r   r,   r  r    rg   r;   r%   r%   r&   r     s   z_Relationship.target_partnamec                 C  s*   | j rt| jtsJ | jS | j| jS )zstr reference to relationship target.

        For internal relationships this is the relative partname, suitable for serialization
        purposes. For an external relationship it is typically a URL.
        )r*   r,   r  r   r   Zrelative_refr   r;   r%   r%   r&   r6     s   z_Relationship.target_refN)
r   r   r0   r   r   r   r   r   r(   r)   )r   r   rY   r   r}   r   r   r   )r   r+   r   )r   r    r   )r:   r?   r@   rA   rI   r   r   r   r*   r   r0   r2   r   r6   r%   r%   r%   r&   r     s"    

)5rA   
__future__r   r  typingr   r   r   r   r   r   r	   pptx.opc.constantsr
   r   r   ra   Zpptx.opc.oxmlr   r   pptx.opc.packurir   r   r   Zpptx.opc.serializedr   r   Zpptx.opc.sharedr   Z	pptx.oxmlr   	pptx.utilr   typing_extensionsr   r   r   Zpptx.oxml.xmlchemyr   pptx.packager   pptx.parts.presentationr   r   rB   rz   r    r   r   r   r   r7   r   r%   r%   r%   r&   <module>   s8    $'eoe3$ <