
    h,                     x   S r SSKJr  SSKrSSKJr  SSKJrJ	r	  / SQr
S r\R                  " SSS	9S
 5       r\" S5      \" S5      SS j5       5       r\	" SSS9\R                  " SSS	9S 5       5       r\" S5      \" S5      \	" SSS9SS j5       5       5       r\" S5      \" S5      SS j5       5       rS rS rg)a7  Functions for reading and writing graphs in the *graph6* format.

The *graph6* file format is suitable for small graphs or large dense
graphs. For large sparse graphs, use the *sparse6* format.

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

.. _graph6: http://users.cecs.anu.edu.au/~bdm/data/formats.html

    )isliceN)NetworkXError)not_implemented_for	open_file)from_graph6_bytesread_graph6to_graph6_byteswrite_graph6c              #     ^ ^#    [        T 5      nUS:  a  [        S5      eU(       a  Sv   [        U5       H&  n[        R	                  [        US-   5      5      v   M(     U U4S j[        SU5       5       n[        [        US5      5      nU(       a\  [        S [        U5       5       5      n[        R	                  [        US-   5      5      v   [        [        US5      5      nU(       a  M\  S	v   g
7f)a  Yield bytes in the graph6 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'>>graph6<<'`` 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>graph6 is only defined if number of nodes is less than 2 ** 36
   >>graph6<<?   c              3   f   >#    U  H&  n[        U5        H  nTU   TTU      ;   v   M     M(     g 7fNrange).0jiGnodess      K/var/www/html/env/lib/python3.13/site-packages/networkx/readwrite/graph6.py	<genexpr>)_generate_graph6_bytes.<locals>.<genexpr>7   s/     K[%(QE!H%(#(#[s   .1      c              3   6   #    U  H  u  pUS U-
  -  v   M     g7f)   N )r   r   bs      r   r   r   :   s     8'7tqQU
'7s      
N)len
ValueError	n_to_datastrencodechrr   listr   sum	enumerate)r   r   headerndbitschunks   ``     r   _generate_graph6_bytesr/      s     * 	AAEzL
 	
 q\jjQV%%  LU1a[KDa!E
8y'788jjQV%%VD!_% % Ks   C*C50C5T)graphsreturns_graphc                 V  ^	 U	4S jnU R                  S5      (       a  U SS n U  Vs/ s H  o"S-
  PM	     snm	[        S T	 5       5      (       a  [        S5      e[        T	5      u  nm	X3S-
  -  S	-  S
-   S-  n[	        T	5      U:w  a&  [        SX3S-
  -  S	-   S[	        T	5      S-   S35      e[        R                  " 5       nUR                  [        U5      5        [        S [        SU5       5       U" 5       5       H"  u  u  pgnU(       d  M  UR                  Xg5        M$     U$ s  snf )a^  Read a simple undirected graph in graph6 format from bytes.

Parameters
----------
bytes_in : bytes
   Data in graph6 format, without a trailing newline.

Returns
-------
G : Graph

Raises
------
NetworkXError
    If bytes_in is unable to be parsed in graph6 format

ValueError
    If any character ``c`` in bytes_in does not satisfy
    ``63 <= ord(c) < 127``.

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

See Also
--------
read_graph6, write_graph6

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

c               3   D   >#    T H  n S H  nX-	  S-  v   M     M     g7f)zMReturns sequence of individual bits from 6-bit-per-value
list of data values.)r            r   r   r   Nr   )r,   r   datas     r   r-   from_graph6_bytes.<locals>.bitsg   s(      A'vl" ( s    r   
   Nr   c              3   *   #    U  H	  oS :  v   M     g7f)r   Nr   )r   cs     r   r   $from_graph6_bytes.<locals>.<genexpr>r   s     
 4ar64s   z.each input character must be in range(63, 127)r   r6   r   r   z	Expected z bits but got z
 in graph6c              3   N   #    U  H  n[        U5        H  o"U4v   M
     M     g 7fr   r   )r   r   r   s      r   r   r<   ~   s     H+QuQx!a&x&+s   #%)
startswithanyr"   	data_to_nr!   r   nxGraphadd_nodes_fromr   zipadd_edge)
bytes_inr-   r;   r+   ndr   r   r   r   r7   s
            @r   r   r   @   s!   N# =))BC=$%HqFH%D

 4
   IJJoGAt
1u+
Q
1	$B
4yBUq()D	AjQ
 	
 	
AU1XH%1+H$&Q	1JJq R H# &s   D&directed
multigraphc                     Ub  U R                  U5      n [        R                  " U 5      n[        UR	                  5       5      nSR                  [        X1U5      5      $ )a  Convert a simple undirected graph to bytes in graph6 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 '>>graph6<<' bytes to head of data.

Raises
------
NetworkXNotImplemented
    If the graph is directed or is a multigraph.

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

Examples
--------
>>> nx.to_graph6_bytes(nx.path_graph(2))
b'>>graph6<<A_\n'

See Also
--------
from_graph6_bytes, read_graph6, write_graph6_bytes

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

The format does not support edge or node labels, parallel edges or
self loops. If self loops are present they are silently ignored.

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

    )subgraphrA   convert_node_labels_to_integerssortedr   joinr/   )r   r   r*   Hs       r   r	   r	      sP    ^ JJu
**1-A1779E88*1V<==rK   rb)modec                     / nU  H?  nUR                  5       n[        U5      (       d  M%  UR                  [        U5      5        MA     [        U5      S:X  a  US   $ U$ )aH  Read simple undirected graphs in graph6 format from path.

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

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

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

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

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

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

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

See Also
--------
from_graph6_bytes, write_graph6

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

r   r   )stripr!   appendr   )pathglistlines      r   r   r      sX    h Ezz|4yy&t,-	 
 5zQQxrK   r   wbc                     [        XX#S9$ )a  Write a simple undirected graph to a path in graph6 format.

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

path : str
   The path naming the file to which to write the graph.

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 '>>graph6<<' string to head of data

Raises
------
NetworkXNotImplemented
    If the graph is directed or is a multigraph.

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

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

    >>> import tempfile
    >>> with tempfile.NamedTemporaryFile(delete=False) as f:
    ...     nx.write_graph6(nx.path_graph(2), f.name)
    ...     _ = f.seek(0)
    ...     print(f.read())
    b'>>graph6<<A_\n'

See Also
--------
from_graph6_bytes, read_graph6

Notes
-----
The function writes a newline character after writing the encoding
of the graph.

The format does not support edge or node labels, parallel edges or
self loops.  If self loops are present they are silently ignored.

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

)r   r*   )write_graph6_file)r   rV   r   r*   s       r   r
   r
      s    t QEAArK   c                     Ub  U R                  U5      n [        R                  " U 5      n[        UR	                  5       5      n[        XBU5       H  nUR                  U5        M     g)a  Write a simple undirected graph to a file-like object in graph6 format.

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

f : file-like object
   The file 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 '>>graph6<<' string to head of data

Raises
------
NetworkXNotImplemented
    If the graph is directed or is a multigraph.

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

Examples
--------
You can write a graph6 file by giving an open file-like object::

    >>> import tempfile
    >>> with tempfile.NamedTemporaryFile() as f:
    ...     nx.write_graph6(nx.path_graph(2), f)
    ...     _ = f.seek(0)
    ...     print(f.read())
    b'>>graph6<<A_\n'

See Also
--------
from_graph6_bytes, read_graph6

Notes
-----
The function writes a newline character after writing the encoding
of the graph.

The format does not support edge or node labels, parallel edges or
self loops.  If self loops are present they are silently ignored.

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

N)rL   rA   rM   rN   r   r/   write)r   fr   r*   rP   r   s         r   r[   r[   8  sU    r JJu
**1-A1779E#Af5	
 6rK   c                     U S   S::  a
  U S   U SS 4$ U S   S::  a  U S   S-  U S   S-  -   U S   -   U S	S 4$ U S   S
-  U S   S-  -   U S	   S-  -   U S   S-  -   U S   S-  -   U S   -   U SS 4$ )zhRead initial one-, four- or eight-unit value from graph6
integer sequence.

Return (value, rest of seq.)r   >   r   N   r6   r   r5   r4            r         r   )r7   s    r   r@   r@   y  s    
 Aw"}AwQR  Aw"}Q2$q'Q,/$q'948CC	aB7b=	7b=	 7b=	 7a<		
 q'	 	QR rK   c           	          U S::  a  U /$ U S::  a  SU S-	  S-  U S-	  S-  U S-  /$ SSU S-	  S-  U S-	  S-  U S-	  S-  U S-	  S-  U S-	  S-  U S-  /$ )	zConvert an integer to one-, four- or eight-unit graph6 sequence.

This function is undefined if `n` is not in ``range(2 ** 36)``.

r`   i r   ra   r   rb   rc   rd   r   )r+   s    r   r#   r#     s     	Bws
	
fQ"W$qAvoq4x@@ "W"W"W"W!VtOH	
 		
rK   )NT)__doc__	itertoolsr   networkxrA   networkx.exceptionr   networkx.utilsr   r   __all__r/   _dispatchabler   r	   r   r
   r[   r@   r#   r   rK   r   <module>ro      s  	   , 9
Q&R T2A 3AH Z \"1> # !1>h 14T2; 3 ;| Z \"
147B  # !7Bt Z \"< # !<~(
rK   