
    ިsgK(                        d Z ddlZddlmZ ddlmZmZ ddlm	Z	m
Z
 g dZd Z ej                  dd	      d
        ZddZ e
dd       ej                  dd	      d               Z e	d       e
dd      dd              Zy)aP  Functions for reading and writing graphs in the *sparse6* format.

The *sparse6* file format is a space-efficient format for large sparse
graphs. For small graphs or large dense graphs, use the *graph6* file
format.

For more information, see the `sparse6`_ homepage.

.. _sparse6: https://users.cecs.anu.edu.au/~bdm/data/formats.html

    N)NetworkXError)	data_to_n	n_to_data)not_implemented_for	open_file)from_sparse6_bytesread_sparse6to_sparse6_byteswrite_sparse6c              #     K   t        |       }|dk\  rt        d      |rd d t        |      D ]%  }t        j	                  t        |dz                ' ddz  |k  rdz  dz  |k  rfd}t        d | j                         D              }g }d	}|D ]  \  }	}
|	|k(  r)|j                  d	       |j                   ||
             4|	|dz   k(  r.|dz  }|j                  d       |j                   ||
             j|	}|j                  d       |j                   ||	             |j                  d	       |j                   ||
              d
k  rV|dz  k(  rNt        |       d
z  k\  r<||dz
  k  r4|j                  d	       |j                  dgt        |       d
z  z         n"|j                  dgt        |       d
z  z         t        d	t        |      d
      D cg c]I  }||d	z      dz  ||dz      dz  z   ||dz      dz  z   ||dz      dz  z   ||dz      dz  z   ||dz      d	z  z   K }}|D ]%  }t        j	                  t        |dz                ' d yc c}w w)a%  Yield bytes in the sparse6 encoding of a graph.

    `G` is an undirected simple graph. `nodes` is the list of nodes for
    which the node-induced subgraph will be encoded; if `nodes` is the
    list of all nodes in the graph, the entire graph will be
    encoded. `header` is a Boolean that specifies whether to generate
    the header ``b'>>sparse6<<'`` before the remaining data.

    This function generates `bytes` objects in the following order:

    1. the header (if requested),
    2. the encoding of the number of nodes,
    3. each character, one-at-a-time, in the encoding of the requested
       node-induced subgraph,
    4. a newline character.

    This function raises :exc:`ValueError` if the graph is too large for
    the graph6 format (that is, greater than ``2 ** 36`` nodes).

    l       @ z?sparse6 is only defined if number of nodes is less than 2 ** 36   >>sparse6<<   :?      c                 `    t              D cg c]  }| ddz
  |z
  z  z  rdnd c}S c c}w )zBig endian k-bit encoding of xr   r   )range)xiks     M/var/www/html/venv/lib/python3.12/site-packages/networkx/readwrite/sparse6.pyencz$_generate_sparse6_bytes.<locals>.enc;   s4    <A!HEqa!A	**2EEEs   +c              3   R   K   | ]  \  }}t        ||      t        ||      f ! y w)N)maxmin).0uvs      r   	<genexpr>z*_generate_sparse6_bytes.<locals>.<genexpr>?   s%     @daC1Is1ay)@s   %'r                     
N)len
ValueErrorr   strencodechrsortededgesappendextendr   )Gnodesheaderndr   r+   bitscurvr   r   r   datar   s                @r   _generate_sparse6_bytesr6      s    * 	AAEzM
 	
 
Jq\ &jjQV%%& 	
A
q&1*	Q q&1*F @aggi@@EDD  19KKNKKA$(]AIDKKNKKADKKNKKAKKNKKA  	1uqAvc$iZ1$4#:tq1u~
 	AQCSYJ!+,-QCSYJ!+,- q#d)Q'  
a!e	A;!	A;!	 A;!	 A;!		
 A;!	D   &jjQV%%&
Ks   A0I64E>I62AI1 6I6T)graphsreturns_graphc                 2  
 | j                  d      r| dd } | j                  d      st        d      | dd D cg c]  }|dz
  	 }}t        |      \  }
ddz  |k  rdz  dz  |k  r
fd}d	}t        j                         }|j                  t        |             d
} |       D ]I  \  }}	|dk(  r|dz  }|	|k\  s||k\  r n0|	|kD  r|	}$|j                  |	|      rd}|j                  |	|       K |st        j                  |      }|S c c}w )aV  Read an undirected graph in sparse6 format from string.

    Parameters
    ----------
    string : string
       Data in sparse6 format

    Returns
    -------
    G : Graph

    Raises
    ------
    NetworkXError
        If the string is unable to be parsed in sparse6 format

    Examples
    --------
    >>> G = nx.from_sparse6_bytes(b":A_")
    >>> sorted(G.edges())
    [(0, 1), (0, 1), (0, 1)]

    See Also
    --------
    read_sparse6, write_sparse6

    References
    ----------
    .. [1] Sparse6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    r      Nr   z!Expected leading colon in sparse6r   r   c               3   6  K   t              } d}d}	 |dk  r	 t        |       }d}|dz  }||z	  dz  }|d|z  dz
  z  }|}|k  r!	 t        |       }d}|dz  |z   }|dz  }|k  r!||z
  z	  }|z
  }||f g# t        $ r Y yw xY w# t        $ r Y yw xY ww)z6Returns stream of pairs b[i], x[i] for sparse6 format.Nr   r   r   )iternextStopIteration)chunksr2   dLenbr   xLenr5   r   s         r   	parseDataz%from_sparse6_bytes.<locals>.parseData   s     daxVA AIDdaAa4i1_%AD(VA !VqL	 ( dQhA!8DQ$J-  %  % sQ   BA; !BB
 B'B;	BBBB
	BBBBr   FT)

startswithr   r   nx
MultiGraphadd_nodes_fromr   has_edgeadd_edgeGraph)stringccharsr1   rC   r   r.   
multigraphrA   r   r5   r   s             @@r   r   r   i   s7   D (T"?@@#ABZ(QV(E(GAt	A
q&1*	Q q&1*< 	
A
AU1XJ 16FA6Q!VUAzz!Q!
JJq! HHQKHq )s   Dc                     || j                  |      } t        j                  | d      } dj                  t	        | ||            S )a  Convert an undirected graph to bytes in sparse6 format.

    Parameters
    ----------
    G : Graph (undirected)

    nodes: list or iterable
       Nodes are labeled 0...n-1 in the order provided.  If None the ordering
       given by ``G.nodes()`` is used.

    header: bool
       If True add '>>sparse6<<' bytes to head of data.

    Raises
    ------
    NetworkXNotImplemented
        If the graph is directed.

    ValueError
        If the graph has at least ``2 ** 36`` nodes; the sparse6 format
        is only defined for graphs of order less than ``2 ** 36``.

    Examples
    --------
    >>> nx.to_sparse6_bytes(nx.path_graph(2))
    b'>>sparse6<<:An\n'

    See Also
    --------
    to_sparse6_bytes, read_sparse6, write_sparse6_bytes

    Notes
    -----
    The returned bytes end with a newline character.

    The format does not support edge or node labels.

    References
    ----------
    .. [1] Graph6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    r*   ordering    )subgraphrE   convert_node_labels_to_integersjoinr6   )r.   r/   r0   s      r   r
   r
      sD    X JJu
**1x@A88+Auf=>>rR   rb)modec                     g }| D ]8  }|j                         }t        |      s|j                  t        |             : t        |      dk(  r|d   S |S )a  Read an undirected graph in sparse6 format from path.

    Parameters
    ----------
    path : file or string
       File or filename to write.

    Returns
    -------
    G : Graph/Multigraph or list of Graphs/MultiGraphs
       If the file contains multiple lines then a list of graphs is returned

    Raises
    ------
    NetworkXError
        If the string is unable to be parsed in sparse6 format

    Examples
    --------
    You can read a sparse6 file by giving the path to the file::

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(delete=False) as f:
        ...     _ = f.write(b">>sparse6<<:An\n")
        ...     _ = f.seek(0)
        ...     G = nx.read_sparse6(f.name)
        >>> list(G.edges())
        [(0, 1)]

    You can also read a sparse6 file by giving an open file-like object::

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile() as f:
        ...     _ = f.write(b">>sparse6<<:An\n")
        ...     _ = f.seek(0)
        ...     G = nx.read_sparse6(f)
        >>> list(G.edges())
        [(0, 1)]

    See Also
    --------
    read_sparse6, from_sparse6_bytes

    References
    ----------
    .. [1] Sparse6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    r   r   )stripr%   r,   r   )pathglistlines      r   r	   r	      s[    h E /zz|4y'-.	/
 5zQQxrR   directedr   wbc                     || j                  |      } t        j                  | d      } t        | ||      D ]  }|j	                  |        y)a  Write graph G to given path in sparse6 format.

    Parameters
    ----------
    G : Graph (undirected)

    path : file or string
       File or filename to write

    nodes: list or iterable
       Nodes are labeled 0...n-1 in the order provided.  If None the ordering
       given by G.nodes() is used.

    header: bool
       If True add '>>sparse6<<' string to head of data

    Raises
    ------
    NetworkXError
        If the graph is directed

    Examples
    --------
    You can write a sparse6 file by giving the path to the file::

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(delete=False) as f:
        ...     nx.write_sparse6(nx.path_graph(2), f.name)
        ...     print(f.read())
        b'>>sparse6<<:An\n'

    You can also write a sparse6 file by giving an open file-like object::

        >>> with tempfile.NamedTemporaryFile() as f:
        ...     nx.write_sparse6(nx.path_graph(2), f)
        ...     _ = f.seek(0)
        ...     print(f.read())
        b'>>sparse6<<:An\n'

    See Also
    --------
    read_sparse6, from_sparse6_bytes

    Notes
    -----
    The format does not support edge or node labels.

    References
    ----------
    .. [1] Sparse6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    Nr*   rP   )rS   rE   rT   r6   write)r.   rZ   r/   r0   rA   s        r   r   r   =  sN    p JJu
**1x@A$Qv6 

1rR   )NT)__doc__networkxrE   networkx.exceptionr   networkx.readwrite.graph6r   r   networkx.utilsr   r   __all__r6   _dispatchabler   r
   r	   r    rR   r   <module>ri      s   
  , : 9
UOd T2^ 3^B/?d 14T2; 3 ;| Z 
14:  !:rR   