o
    hw%                     @   s   d Z ddlmZ ddlZddlmZ g dZedddd	d
 Zedddej	dddddd Z
ej	ddddd Zdd ZdddZdddZdS )a  
*****
Pydot
*****

Import and export NetworkX graphs in Graphviz dot format using pydot.

Either this module or nx_agraph can be used to interface with graphviz.

Examples
--------
>>> G = nx.complete_graph(5)
>>> PG = nx.nx_pydot.to_pydot(G)
>>> H = nx.nx_pydot.from_pydot(PG)

See Also
--------
 - pydot:         https://github.com/erocarrera/pydot
 - Graphviz:      https://www.graphviz.org
 - DOT Language:  http://www.graphviz.org/doc/info/lang.html
    )getpreferredencodingN)	open_file)	write_dotread_dotgraphviz_layoutpydot_layoutto_pydot
from_pydot   w)modec                 C   s   t | }||  dS )zgWrite NetworkX graph G to Graphviz dot format on path.

    Path can be a string or a file handle.
    N)r   write	to_string)GpathP r   m/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/networkx/drawing/nx_pydot.pyr   &   s   r   rpydot_read_dotT)namegraphsreturns_graphc                 C   s&   ddl }|  }||}t|d S )aO  Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
    dot file with the passed path.

    If this file contains multiple graphs, only the first such graph is
    returned. All graphs _except_ the first are silently ignored.

    Parameters
    ----------
    path : str or file
        Filename or file handle.

    Returns
    -------
    G : MultiGraph or MultiDiGraph
        A :class:`MultiGraph` or :class:`MultiDiGraph`.

    Notes
    -----
    Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
    :class:`MultiGraph`.
    r   N)pydotreadgraph_from_dot_datar	   )r   r   dataP_listr   r   r   r   1   s   
r   )r   r   c              	   C   s  |  drd}nd}|  dkr|rt }nt }n|r#t }nt }|  d}|dkr5||_	| 
 D ]}| d}|dv rGq9|j|fi |  q9|  D ]`}| }| }| }	g }
g }t|trw|
|d n|d D ]
}|
|d q{t|tr||d n|d D ]
}||d q|
D ]}|D ]}|j||fi |	 qqqW|  }|r||jd< z|  d	 |jd
< W n ttfy   Y nw z|  d	 |jd< W |S  ttfy   Y |S w )a  Returns a NetworkX graph from a Pydot graph.

    Parameters
    ----------
    P : Pydot graph
      A graph created with Pydot

    Returns
    -------
    G : NetworkX multigraph
        A MultiGraph or MultiDiGraph.

    Examples
    --------
    >>> K5 = nx.complete_graph(5)
    >>> A = nx.nx_pydot.to_pydot(K5)
    >>> G = nx.nx_pydot.from_pydot(A)  # return MultiGraph

    # make a Graph instead of MultiGraph
    >>> G = nx.Graph(nx.nx_pydot.from_pydot(A))

    NFTgraph" )noder   edgenodesr   r!   r"   )
get_strictget_typenx
MultiGraphGraphMultiDiGraphDiGraphget_namestripr   get_node_listadd_nodeget_attributesget_edge_list
get_sourceget_destination
isinstancestrappendadd_edger   get_node_defaults
IndexError	TypeErrorget_edge_defaults)r   
multiedgesNr   pneuvattrsdunodesvnodessource_nodedestination_nodepattrr   r   r   r	   T   sh   






r	   c                 C   s  ddl }|  rd}nd}t| dko|   }| j}| jdi }|dkr3|jd||d|}n|jd| df||d|}z|j	di | jd  W n	 t
yY   Y nw z|jdi | jd	  W n	 t
yp   Y nw | jd
dD ]\}}dd | D }	t|}|j|fi |	}
||
 qw|  r| jd
d
dD ]+\}}}}dd | D }t|t|}}|j||fdt|i|}|| q|S | jd
dD ]&\}}}dd | D }t|t|}}|j||fi |}|| q|S )a  Returns a pydot graph from a NetworkX graph N.

    Parameters
    ----------
    N : NetworkX graph
      A graph created with NetworkX

    Examples
    --------
    >>> K5 = nx.complete_graph(5)
    >>> P = nx.nx_pydot.to_pydot(K5)

    Notes
    -----

    r   Ndigraphr   r    )
graph_typestrictr   r!   r"   T)r   c                 S      i | ]\}}t |t |qS r   r4   .0krA   r   r   r   
<dictcomp>       zto_pydot.<locals>.<dictcomp>)r   keysc                 S   s&   i | ]\}}|d krt |t |qS )keyrN   rO   r   r   r   rR      s   & rU   c                 S   rM   r   rN   rO   r   r   r   rR      rS   )r    r   )r   is_directedr&   number_of_selfloopsis_multigraphr   r   getDotset_node_defaultsKeyErrorset_edge_defaultsr#   itemsr4   Noder.   edgesEdger6   )r<   r   rK   rL   r   graph_defaultsr   r>   nodedatastr_nodedatar=   r@   rA   rU   edgedatastr_edgedatar"   r   r   r   r      sX   
r   neatoc                 C   s   t | ||dS )a=  Create node positions using Pydot and Graphviz.

    Returns a dictionary of positions keyed by node.

    Parameters
    ----------
    G : NetworkX Graph
        The graph for which the layout is computed.
    prog : string (default: 'neato')
        The name of the GraphViz program to use for layout.
        Options depend on GraphViz version but may include:
        'dot', 'twopi', 'fdp', 'sfdp', 'circo'
    root : Node from G or None (default: None)
        The node of G from which to start some layout algorithms.

    Returns
    -------
      Dictionary of (x, y) positions keyed by node.

    Examples
    --------
    >>> G = nx.complete_graph(4)
    >>> pos = nx.nx_pydot.graphviz_layout(G)
    >>> pos = nx.nx_pydot.graphviz_layout(G, prog="dot")

    Notes
    -----
    This is a wrapper for pydot_layout.
    r   progroot)r   rh   r   r   r   r      s   r   c                 C   s(  ddl }t| }|dur|dt| |j|d}t|t d}|dkrFtd| d t  td	 td
 td td| d dS ||}t|dksSJ |d }i }	| 	 D ]4}
t|
}|
||}t|trt|d }| dd }|dur|d\}}t|t|f|	|
< q]|	S )a  Create node positions using :mod:`pydot` and Graphviz.

    Parameters
    ----------
    G : Graph
        NetworkX graph to be laid out.
    prog : string  (default: 'neato')
        Name of the GraphViz command to use for layout.
        Options depend on GraphViz version but may include:
        'dot', 'twopi', 'fdp', 'sfdp', 'circo'
    root : Node from G or None (default: None)
        The node of G from which to start some layout algorithms.

    Returns
    -------
    dict
        Dictionary of positions keyed by node.

    Examples
    --------
    >>> G = nx.complete_graph(4)
    >>> pos = nx.nx_pydot.pydot_layout(G)
    >>> pos = nx.nx_pydot.pydot_layout(G, prog="dot")

    Notes
    -----
    If you use complex node objects, they may have the same string
    representation and GraphViz could treat them as the same node.
    The layout may assign both nodes a single location. See Issue #1568
    If this occurs in your case, consider relabeling the nodes just
    for the layout computation using something similar to::

        H = nx.convert_node_labels_to_integers(G, label_attribute="node_label")
        H_layout = nx.nx_pydot.pydot_layout(H, prog="dot")
        G_layout = {H.nodes[n]["node_label"]: p for n, p in H_layout.items()}

    r   Nrj   )ri   )encodingr    zGraphviz layout with z failedzTo debug what happened try:zP = nx.nx_pydot.to_pydot(G)zP.write_dot("file.dot")zAnd then run z on file.dotr
   ,)r   r   setr4   
create_dotr   printr   lenr#   get_nodequote_id_if_necessaryr3   listget_possplitfloat)r   ri   rj   r   r   D_bytesDQ_listQnode_posr>   str_nr!   posxxyyr   r   r   r     s:   &

r   )rg   N)__doc__localer   networkxr&   networkx.utilsr   __all__r   _dispatchabler   r	   r   r   r   r   r   r   r   <module>   s    




!
[
A!