o
    	'fu                     @  sV   d Z ddlmZ ddlmZmZ ddlmZ G dd deedf Z	G dd dZ
d	S )
zRelationship-related objects.    )annotations)AnyDict)CT_Relationshipsc                      s~   e Zd ZdZd! fddZ	d"d#ddZdd Zdd Zdd Ze	dd Z
e	dd Zd"ddZdd Ze	dd  Z  ZS )$RelationshipszGCollection object for |_Relationship| instances, having list semantics.baseURIstrc                   s   t t|   || _i | _d S N)superr   __init___baseURI_target_parts_by_rId)selfr   	__class__ D/home/ubuntu/flask/venv/lib/python3.10/site-packages/docx/opc/rel.pyr      s   
zRelationships.__init__Freltypetarget	str | AnyrIdis_externalboolreturn'_Relationship'c                 C  s,   t |||| j|}|| |< |s|| j|< |S )z.Return a newly added |_Relationship| instance.)_Relationshipr   r   )r   r   r   r   r   relr   r   r   add_relationship   s
   
zRelationships.add_relationshipc                 C  s,   |  ||}|du r| j}| |||}|S )zlReturn relationship of `reltype` to `target_part`, newly added if not already
        present in collection.N)_get_matching	_next_rIdr   )r   r   target_partr   r   r   r   r   
get_or_add   s
   zRelationships.get_or_addc                 C  s6   | j ||dd}|du r| j}| j|||dd}|jS )z{Return rId of external relationship of `reltype` to `target_ref`, newly added
        if not already present in collection.T)r   N)r   r   r   r   )r   r   
target_refr   r   r   r   r   get_or_add_ext_rel%   s
   z Relationships.get_or_add_ext_relc                 C  s   |  |}|jS )zReturn target part of rel with matching `reltype`, raising |KeyError| if not
        found and |ValueError| if more than one matching relationship is found.)_get_rel_of_typer    )r   r   r   r   r   r   part_with_reltype.   s   
zRelationships.part_with_reltypec                 C     | j S )z_Dict mapping rIds to target parts for all the internal relationships in the
        collection.)r   r   r   r   r   related_parts4   s   zRelationships.related_partsc                 C  s4   t  }|  D ]}||j|j|j|j q|jS )zoSerialize this relationship collection into XML suitable for storage as a
        .rels file in an OPC package.)	r   newvaluesadd_relr   r   r"   r   xml)r   rels_elmr   r   r   r   r,   :   s   zRelationships.xmlc                 C  s0   dd }|   D ]}|||||r|  S qdS )zuReturn relationship of matching `reltype`, `target`, and `is_external` from
        collection, or None if not found.c                 S  s>   | j |krdS | j|krdS | jr| jn| j}||krdS dS )NFT)r   r   r"   r    )r   r   r   r   
rel_targetr   r   r   matchesG   s   

z,Relationships._get_matching.<locals>.matchesN)r*   )r   r   r   r   r/   r   r   r   r   r   C   s   
zRelationships._get_matchingc                   sV    fdd|   D }t|dkrd}t|  t|dkr'd}t|  |d S )zReturn single relationship of type `reltype` from the collection.

        Raises |KeyError| if no matching relationship is found. Raises |ValueError| if
        more than one matching relationship is found.
        c                   s   g | ]	}|j  kr|qS r   r   ).0r   r0   r   r   
<listcomp>\   s    z2Relationships._get_rel_of_type.<locals>.<listcomp>r   z*no relationship of type '%s' in collection   z1multiple relationships of type '%s' in collection)r*   lenKeyError
ValueError)r   r   matchingtmplr   r0   r   r$   V   s   zRelationships._get_rel_of_typec                 C  s4   t dt| d D ]}d| }|| vr|  S q	dS )zNext available rId in collection, starting from 'rId1' and making use of any
        gaps in numbering, e.g. 'rId2' for rIds ['rId1', 'rId3'].r3      zrId%dN)ranger4   )r   nrId_candidater   r   r   r   e   s   zRelationships._next_rId)r   r   F)
r   r   r   r   r   r   r   r   r   r   )__name__
__module____qualname____doc__r   r   r!   r#   r%   propertyr(   r,   r   r$   r   __classcell__r   r   r   r   r   
   s     
		


r   r   c                      sb   e Zd ZdZdd fddZedd Zed	d
 Zedd Zedd Z	edddZ
  ZS )r   z&Value object for relationship to part.Fr   r   c                   s4   t t|   || _|| _|| _|| _t|| _d S r	   )	r
   r   r   _rId_reltype_targetr   r   _is_external)r   r   r   r   r   externalr   r   r   r   r   s   z_Relationship.__init__c                 C  r&   r	   )rG   r'   r   r   r   r   z      z_Relationship.is_externalc                 C  r&   r	   )rE   r'   r   r   r   r   ~   rI   z_Relationship.reltypec                 C  r&   r	   )rD   r'   r   r   r   r      rI   z_Relationship.rIdc                 C  s   | j rtd| jS )NzOtarget_part property on _Relationship is undefined when target mode is External)rG   r6   rF   r'   r   r   r   r       s
   z_Relationship.target_partr   c                 C  s   | j r| jS | jj| jS r	   )rG   rF   partnamerelative_refr   r'   r   r   r   r"      s   z_Relationship.target_refr=   )r   r   )r   r   )r>   r?   r@   rA   r   rB   r   r   r   r    r"   rC   r   r   r   r   r   o   s    



N)rA   
__future__r   typingr   r   docx.opc.oxmlr   r   r   r   r   r   r   r   <module>   s    e