
    hy                     z   S r SSKJr  SSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  SSKJr  SSKJrJr  SSKrSSKJr  SS	KJr  / S
QrS rS rS r\" SSS9\R6                  " SSS9SS j5       5       r\R6                  " SSS9SS j5       r " S S\5      r " S S\5      rSr S r!S r"S S jr#\" SSS9S S j5       r$g)!a  
Read graphs in GML format.

"GML, the Graph Modelling Language, is our proposal for a portable
file format for graphs. GML's key features are portability, simple
syntax, extensibility and flexibility. A GML file consists of a
hierarchical key-value lists. Graphs can be annotated with arbitrary
data structures. The idea for a common file format was born at the
GD'95; this proposal is the outcome of many discussions. GML is the
standard file format in the Graphlet graph editor system. It has been
overtaken and adapted by several other systems for drawing graphs."

GML files are stored using a 7-bit ASCII encoding with any extended
ASCII characters (iso8859-1) appearing as HTML character entities.
You will need to give some thought into how the exported data should
interact with different languages and even different Python versions.
Re-importing from gml is also a concern.

Without specifying a `stringizer`/`destringizer`, the code is capable of
writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
specification.  For writing other data types, and for reading data other
than `str` you need to explicitly supply a `stringizer`/`destringizer`.

For additional documentation on the GML file format, please see the
`GML website <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

Several example graphs in GML format may be found on Mark Newman's
`Network data page <http://www-personal.umich.edu/~mejn/netdata/>`_.
    N)literal_eval)defaultdict)Enum)StringIO)Any
NamedTuple)NetworkXError)	open_file)read_gml	parse_gmlgenerate_gml	write_gmlc                 z    S n[         R                  " SX5      n [        U [        5      (       a  U $ [        U 5      $ )zUse XML character references to escape characters.

Use XML character references for unprintable or non-ASCII
characters, double quotes and ampersands in a string
c                 X    U R                  S5      nS[        [        U5      5      -   S-   $ )Nr   z&#;)groupstrord)mchs     H/var/www/html/env/lib/python3.13/site-packages/networkx/readwrite/gml.pyfixupescape.<locals>.fixup6   s'    WWQZc#b'l"S((    z[^ -~]|[&"])resub
isinstancer   textr   s     r   escaper    /   s4    ) 66--DdC((47c$i7r   c                 6    S n[         R                  " SX5      $ )z?Replace XML character references with the referenced charactersc                     U R                  S5      nUS   S:X  a(  US   S:X  a  [        USS S5      nO&[        USS 5      nO [        R                  USS    n [        U5      $ ! [         a    Us $ f = f! [        [        4 a    Us $ f = f)	Nr      #   x      )r   inthtmlentitydefsname2codepointKeyErrorchr
ValueErrorOverflowError)r   r   codes      r   r   unescape.<locals>.fixupA   s    wwqz7c>Aw#~4":r*4":%44T!BZ@	t9   M* 	K	s$   A& 
A8 &A54A58BBz,&(?:[0-9A-Za-z]+|#(?:[0-9]+|x[0-9A-Fa-f]+));)r   r   r   s     r   unescaper3   >   s    & 66@%NNr   c                     [        U [        5      (       a  U n [        U 5      $ [	        U < S35      e! [         a  n[	        U< S35      UeSnAff = f)zConvert a Python literal to the value it represents.

Parameters
----------
rep : string
    A Python literal.

Returns
-------
value : object
    The value of the Python literal.

Raises
------
ValueError
    If `rep` is not a Python literal.
z is not a valid Python literalN is not a string)r   r   r   SyntaxErrorr/   )reporig_reperrs      r   literal_destringizerr:   W   sf    $ #s	U$$ C7"2344  	U|+IJKQTT	Us   
3 
AAArb)modeT)graphsreturns_graphc                 0    S n[        U" U 5      X5      nU$ )a  Read graph in GML format from `path`.

Parameters
----------
path : filename or filehandle
    The filename or filehandle to read from.

label : string, optional
    If not None, the parsed nodes will be renamed according to node
    attributes indicated by `label`. Default value: 'label'.

destringizer : callable, optional
    A `destringizer` that recovers values stored as strings in GML. If it
    cannot convert a string to a value, a `ValueError` is raised. Default
    value : None.

Returns
-------
G : NetworkX graph
    The parsed graph.

Raises
------
NetworkXError
    If the input cannot be parsed.

See Also
--------
write_gml, parse_gml
literal_destringizer

Notes
-----
GML files are stored using a 7-bit ASCII encoding with any extended
ASCII characters (iso8859-1) appearing as HTML character entities.
Without specifying a `stringizer`/`destringizer`, the code is capable of
writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
specification.  For writing other data types, and for reading data other
than `str` you need to explicitly supply a `stringizer`/`destringizer`.

For additional documentation on the GML file format, please see the
`GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

See the module docstring :mod:`networkx.readwrite.gml` for more details.

Examples
--------
>>> G = nx.path_graph(4)
>>> nx.write_gml(G, "test.gml")

GML values are interpreted as strings by default:

>>> H = nx.read_gml("test.gml")
>>> H.nodes
NodeView(('0', '1', '2', '3'))

When a `destringizer` is provided, GML values are converted to the provided type.
For example, integer nodes can be recovered as shown below:

>>> J = nx.read_gml("test.gml", destringizer=int)
>>> J.nodes
NodeView((0, 1, 2, 3))

c              3      #    U  HN  n UR                  S5      n[        U[        5      (       d  [	        U 5      n U(       a  US   S:X  a  US S nUv   MP     g ! [         a  n[        S5      UeS nAff = f7f)Nasciiinput is not ASCII-encodedr(   
)decodeUnicodeDecodeErrorr	   r   r   )linesliner9   s      r   filter_linesread_gml.<locals>.filter_lines   sz     DK{{7+ dC((E
RD(CRyJ  & K#$@AsJKs'   A6A>A6
A3"A..A33A6parse_gml_lines)pathlabeldestringizerrH   Gs        r   r   r   s   s     H
 	T*E@AHr   c                 >   ^ S mU4S jn[        U" U 5      X5      nU$ )a  Parse GML graph from a string or iterable.

Parameters
----------
lines : string or iterable of strings
   Data in GML format.

label : string, optional
    If not None, the parsed nodes will be renamed according to node
    attributes indicated by `label`. Default value: 'label'.

destringizer : callable, optional
    A `destringizer` that recovers values stored as strings in GML. If it
    cannot convert a string to a value, a `ValueError` is raised. Default
    value : None.

Returns
-------
G : NetworkX graph
    The parsed graph.

Raises
------
NetworkXError
    If the input cannot be parsed.

See Also
--------
write_gml, read_gml

Notes
-----
This stores nested GML attributes as dictionaries in the NetworkX graph,
node, and edge attribute structures.

GML files are stored using a 7-bit ASCII encoding with any extended
ASCII characters (iso8859-1) appearing as HTML character entities.
Without specifying a `stringizer`/`destringizer`, the code is capable of
writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
specification.  For writing other data types, and for reading data other
than `str` you need to explicitly supply a `stringizer`/`destringizer`.

For additional documentation on the GML file format, please see the
`GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

See the module docstring :mod:`networkx.readwrite.gml` for more details.
c                     [        U [        5      (       a   U R                  S5        [        U [
        5      (       d  [        U 5      n U $ ! [         a  n[	        S5      UeS nAff = f)NrA   rB   )r   bytesrD   rE   r	   r   )rG   r9   s     r   decode_lineparse_gml.<locals>.decode_line   s`    dE""KG$ $$$t9D	 & K#$@AsJKs   A
 

A%A  A%c              3     >#    [        U [        5      (       a#  T" U 5      n U R                  5       n U  S h  vN   g U  HD  nT" U5      nU(       a  US   S:X  a  US S nUR                  S5      S:w  a  [	        S5      eUv   MF     g  NP7f)Nr(   rC   zinput line contains newline)r   r   
splitlinesfindr	   )rF   rG   rS   s     r   rH   parse_gml.<locals>.filter_lines  s     eS!!&E$$&E"4(DH,9D99T?b('(EFF
  s   3B	BAB	rJ   )rF   rM   rN   rH   rO   rS   s        @r   r   r      s&    d 	U+UAAHr   c                   4    \ rS rSrSrSrSrSrSrSr	Sr
S	rS
rg)Patterni  z?encodes the index of each token-matching pattern in `tokenize`.r   r#   r%   r'             N)__name__
__module____qualname____firstlineno____doc__KEYSREALSINTSSTRINGS
DICT_STARTDICT_ENDCOMMENT_WHITESPACE__static_attributes__r^   r   r   rZ   rZ     s)    IDEDGJHr   rZ   c                   >    \ rS rSr% \\S'   \\S'   \\S'   \\S'   Srg)Tokeni!  categoryvaluerG   positionr^   N)	r_   r`   ra   rb   rZ   __annotations__r   r*   rk   r^   r   r   rm   rm   !  s    J
IMr   rm   _networkx_list_startc           
        ^ ^^^^^^  U 4S jnS m UU 4S jmUUUU 4S jmUU4S jmUUU 4S jnU" 5       mU" 5       nUR                  SS5      nUR                  S	S5      nU(       d2  U(       a  [        R                  " 5       O[        R                  " 5       nO1U(       a  [        R                  " 5       O[        R
                  " 5       nUR                  5        V	V
s0 s H  u  pU	S
;  d  M  X_M     nn	n
UR                  R                  U5        S nUR                  S/ 5      n0 n[        5       n[        [        U[        5      (       a  UOU/5       Hz  u  nnU" USSU5      nUU;   a  [        SU< S35      eUb=  US:w  a7  U" USUU5      nUU;   a  [        SU< S35      eUR                  U5        UUU'   UR                   " U40 UD6  M|     UR                  S/ 5      n[        [        U[        5      (       a  UOU/5       GH/  u  nnU" USSU5      nU" USSU5      nUU;  a  [        SU SU< 35      eUU;  a  [        SU SU< 35      eU(       d]  UR#                  UU5      (       d  UR$                  " UU40 UD6  M  U(       a  SOSnSU SU< U U< S3n[        R                  " U5      eUR                  SS5      nUbT  UR#                  UUU5      (       a<  U(       a  SOSnSU SU< U U< SU< S3	nSn[        R                  " US -   U-   5      eUR$                  " UUU40 UD6  GM2     Ub  US:w  a  [        R&                  " X5      nU$ s  sn
n	f )!zParse GML `lines` into a graph.c            	   3     >#    / SQn [         R                  " SR                  S U  5       5      5      nSn/ nT GH  nSnU(       aC  UR                  UR	                  5       5        US   S:X  a  SR                  U5      n/ nObUS-  nMP  UR                  S5      S:X  aF  UR	                  5       S   S:w  a/  UR	                  5       S   S:w  a  UR                  5       /nUS-  nM  [        U5      nXV:  a  UR                  XE5      nUc  S	XES   S
US-    SUS-    S3n[        U5      e[        [        U 5      5       H  n	UR                  U	S-   5      n
U
c  M  U	S:X  a  U
R                  5       nO&U	S:X  a  [        U
5      nOU	S:X  a  [        U
5      nOU
nU	S:w  a  [        [        U	5      XS-   US-   5      v   U[        U
5      -  n  O   XV:  a  M  US-  nGM     [        S S US-   S5      v   g 7f)N)z[A-Za-z][0-9A-Za-z_]*\bz>[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*|INF)(?:[Ee][+-]?[0-9]+)?z[+-]?[0-9]+z".*?"z\[z\]z#.*$|\s+|c              3   .   #    U  H  nS U S3v   M     g7f)()Nr^   ).0patterns     r   	<genexpr>4parse_gml_lines.<locals>.tokenize.<locals>.<genexpr>9  s     $L8q	^8s   r   r(   " r#   zcannot tokenize  at (, rx   r%   r]   )r   compilejoinappendstripcountrstriplenmatchr	   ranger   floatr*   rm   rZ   )patternstokenslineno
multilinesrG   poslengthr   r   ir   ro   rF   s               r   tokenize!parse_gml_lines.<locals>.tokenize.  s    	
 CHH$L8$LLM
DC
 !!$**,/8s? 88J/D!#JaKF::c?a'zz|A#-$**,r2Bc2I '+kkm_
! YF,T/=*4:,eFQJ<r#PQ'RSTA'**s8}-A!KKA.E(6$)LLNE!V$)%LE!V$'JE$)E6"'
EA:sQw"OOs5z) . ,( aKF_ ` D$
A..s   EG0A8G0G0c                 \    U u  p#pEUb  [        U5      OSn[        SU SU SU SU S3	5      e)NEOFz	expected z, found r   r   rx   )reprr	   )
curr_tokenexpectedrn   ro   r   r   s         r   
unexpected#parse_gml_lines.<locals>.unexpectedn  sD    '1$$0Ueiz%fXRPSuTUVWWr   c                 L   > U R                   U:X  a  [        T5      $ T" X5        g N)rn   next)r   rn   r   r   r   s      r   consume parse_gml_lines.<locals>.consumes  s#    (*<:(r   c                 T  > [        [        5      nU R                  [        R                  :X  Ga  U R
                  n[        T	5      n U R                  nU[        R                  :X  d  U[        R                  :X  a  U R
                  n[        T	5      n OU[        R                  :X  aD  [        U R
                  SS 5      nT(       a	   T" U5      nUS:X  a  SnUS:X  a  / n[        T	5      n OU[        R                  :X  a  T" U 5      u  pO{US;   a;   [        [        U R
                  5      5      nT(       a	   T" U5      n[        T	5      n O:U R
                  S;   a!  [        U R
                  5      n[        T	5      n O	T
" U S	5        X   R!                  W5        U R                  [        R                  :X  a  GM  S
 nUR#                  5        VVs0 s H  u  p$X&" U5      _M     nnnX4$ ! [         a     GN'f = f! [         a     Nf = f! [         a    SnT
" X5         Nf = fs  snnf )Nr#   r(   ()r^   z[])idrM   sourcetargetzQan int, float, string, '[' or string convertible ASCII value for node id or label>   INFNANzan int, float, string or '['c                     [        U [        5      (       d  U $ [        U 5      S:X  a  U S   $ U S   [        :X  a  U SS  $ U $ )Nr#   r   )r   listr   LIST_START_VALUE)ro   s    r   clean_dict_value;parse_gml_lines.<locals>.parse_kv.<locals>.clean_dict_value  sF    eT**5zQQxQx++QRy Lr   )r   r   rn   rZ   rd   ro   r   re   rf   rg   r3   r/   rh   r   	Exceptionr   r   items)r   dctkeyrn   ro   msgr   rN   
parse_dictr   r   s          r   parse_kv!parse_gml_lines.<locals>.parse_kvx  s   $!!W\\1""CfJ!**H7==(H,D"((!&\
W__, !1!1!B!78 ,U 3 D=ED=E!&\
W///$.z$:!
E ==4 (Z-=-=)> ?'%(4U(; &*&\
  %%7!*"2"23E!%fJz+IJHOOE"g !!W\\1j	 ?BiikJk
s$U++kJg & & $. % $% % 4N  #:348 KsN   G) %H
 7G: ?H
 H$)
G76G7:
HH
 HH
 
H! H!c                 ~   > T" U [         R                  S5      n T" U 5      u  pT" U [         R                  S5      n X4$ )Nz'['z']')rZ   rh   ri   )r   r   r   r   s     r   r   #parse_gml_lines.<locals>.parse_dict  s?    Z););UC
":.
Z)9)95A
r   c                     > T" [        T5      5      u  pU R                  b	  T" U S5        SU;  a  [        S5      eUS   n[        U[        5      (       a  [        S5      eU$ )Nr   graphzinput contains no graphz"input contains more than one graph)r   rn   r	   r   r   )r   r   r   r   r   r   s      r   parse_graph$parse_gml_lines.<locals>.parse_graph  sd    "4<0
*z5)# 9::GeT"" DEEr   directedF
multigraph)nodeedgec           	      v     U R                  U5      $ ! [         a  n[        U SU SU< S35      UeS nAff = f)Nz #z has no z
 attribute)popr-   r	   )r   rn   attrr   r9   s        r   pop_attr!parse_gml_lines.<locals>.pop_attr  sI    	W774=  	W8*Bqc$ LMSVV	Ws    
838r   r   znode id z is duplicatedNznode label r   r   r   zedge #z has undefined source z has undefined target z->z--z (z) is duplicatedr   r   rx   z6Hint: If multigraph add "multigraph 1" to file header.z is duplicated
)r   nxDiGraphGraphMultiDiGraph
MultiGraphr   r   updategetset	enumerater   r   r	   addadd_nodehas_edgeadd_edgerelabel_nodes)!rF   rM   rN   r   r   r   r   r   rO   kv
graph_attrr   nodesmappingnode_labelsr   r   r   
node_labeledgesr   r   r   arrowr   r   msg2r   r   r   r   r   s!   ` `                         @@@@@r   rK   rK   +  s7   >/@X
)
A AF	 ZFMEyyU+H</J$BJJL"((*!)BOOr}}#(;;=N=41A=M4M$!$=JNGGNN:W IIfb!EG%Kj&=&=UE7K4dFD!,7(2& ?@@$!$q9J[(#k*~$NOOOOJ'$GBK	

2 L IIfb!Ej&=&=UE7K4$!4$!4?&+A& LMM?&+A& LMM::ff--

662T2 (dqcF:eWVJoN&&s++((5$'C1::ffc#B#B (dqcF:eWVJbqIO&&s-?'?$'FGGJJvvs3d3+ L. Ud]Q(He Os   M/Mc                 X   ^^ UU4S jm[        5       mT" U 5        TR                  5       $ )a  Convert a `value` to a Python literal in GML representation.

Parameters
----------
value : object
    The `value` to be converted to GML representation.

Returns
-------
rep : string
    A double-quoted Python literal representing value. Unprintable
    characters are replaced by XML character references.

Raises
------
ValueError
    If `value` cannot be converted to GML.

Notes
-----
The original value can be recovered using the
:func:`networkx.readwrite.gml.literal_destringizer` function.
c                   > [        U [        [        -  5      (       d  U c[  U SL a  TR                  [	        S5      5        g U SL a  TR                  [	        S5      5        g TR                  [	        U 5      5        g [        U [        5      (       a8  [        U 5      nUS   S:w  a   U R                  S5        TR                  U5        g [        U [        [        -  [        -  [        -  5      (       a  TR                  [        U 5      5        g [        U [        5      (       aQ  TR                  S5        SnU  H&  nU(       d  TR                  S5        OSnT" U5        M(     TR                  S	5        g [        U [        5      (       a  [        U 5      S:  aQ  TR                  S
5        SnU  H&  nU(       d  TR                  S5        OSnT" U5        M(     TR                  S5        g U (       a.  TR                  S
5        T" U S   5        TR                  S5        g TR                  S5        g [        U [        5      (       az  TR                  S5        SnU R                  5        HA  u  p@U(       d  TR                  S5        OSnT" U5        TR                  S5        T" U 5        MC     TR                  S5        g [        U [         5      (       aQ  TR                  S5        SnU  H&  nU(       d  TR                  S5        OSnT" U5        M(     TR                  S5        g U < S3n[#        U5      e! [         a	    SU-   n GNf = f)NTr#   Fr   ulatin1[,]rw   rx   z,)r   {:}z* cannot be converted into a Python literal)r   r*   boolwriter   r   encodeUnicodeEncodeErrorr   complexrR   r   tupler   dictr   r   r/   )ro   r   firstitemr   r   buf	stringizes         r   r   %literal_stringizer.<locals>.stringize&  s   eS4Z((EM}		#a&!%		#a&!		#e*%s##;DAw#~&LL* IIdOuw4u<==IId5k"t$$IIcNEIIcN!E$  IIcNu%%5zA~		#!D 		# %dO " 		#		#%(#		$		$t$$IIcNE#kkm
IIcN!E#		#%  , IIcNs##IIcNEIIcN!E$  IIcNIGHCS/!q * &:D&s   &L6 6M	M	)r   getvalue)ro   r   r   s    @@r   literal_stringizerr     s'    2E"N *Ce<<>r   c           
   #     ^^^#    [         R                  " S5      mSUUU4S jjmU R                  5       nSv   U R                  5       (       a  Sv   U(       a  Sv   1 SknU R                  R                  5        H  u  pET" XEUS5       Sh  vN   M     [        [        U [        [        U 5      5      5      5      nS	S
1nU R                  R                  5        H]  u  pxSv   S[        Xg   5      -   v   T" S
USS5       Sh  vN   UR                  5        H  u  pET" XEUS5       Sh  vN   M     Sv   M_     SS1nSS0n	U(       a  UR                  S5        SU	S'   U R                  " S0 U	D6 H  n
Sv   S[        XjS      5      -   v   S[        XjS      5      -   v   U(       a  T" SU
S   SS5       Sh  vN   U
S   R                  5        H  u  pET" XEUS5       Sh  vN   M     Sv   M     Sv   g GNo N N NF N7f)a   Generate a single entry of the graph `G` in GML format.

Parameters
----------
G : NetworkX graph
    The graph to be converted to GML.

stringizer : callable, optional
    A `stringizer` which converts non-int/non-float/non-dict values into
    strings. If it cannot convert a value into a string, it should raise a
    `ValueError` to indicate that. Default value: None.

Returns
-------
lines: generator of strings
    Lines of GML data. Newlines are not appended.

Raises
------
NetworkXError
    If `stringizer` cannot convert a value into a string, or the value to
    convert is not a string while `stringizer` is None.

See Also
--------
literal_stringizer

Notes
-----
Graph attributes named 'directed', 'multigraph', 'node' or
'edge', node attributes named 'id' or 'label', edge attributes
named 'source' or 'target' (or 'key' if `G` is a multigraph)
are ignored because these attribute names are used to encode the graph
structure.

GML files are stored using a 7-bit ASCII encoding with any extended
ASCII characters (iso8859-1) appearing as HTML character entities.
Without specifying a `stringizer`/`destringizer`, the code is capable of
writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
specification.  For writing other data types, and for reading data other
than `str` you need to explicitly supply a `stringizer`/`destringizer`.

For additional documentation on the GML file format, please see the
`GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

See the module docstring :mod:`networkx.readwrite.gml` for more details.

Examples
--------
>>> G = nx.Graph()
>>> G.add_node("1")
>>> print("\n".join(nx.generate_gml(G)))
graph [
  node [
    id 0
    label "1"
  ]
]
>>> G = nx.MultiGraph([("a", "b"), ("a", "b")])
>>> print("\n".join(nx.generate_gml(G)))
graph [
  multigraph 1
  node [
    id 0
    label "a"
  ]
  node [
    id 1
    label "b"
  ]
  edge [
    source 0
    target 1
    key 0
  ]
  edge [
    source 0
    target 1
    key 1
  ]
]
z^[A-Za-z][0-9A-Za-z_]*$c              3     >#    [        U [        5      (       d  [        U < S35      eTR                  U 5      (       d  [        U < S35      e[        U [        5      (       d  [        U 5      n X;  Ga  [        U[        [
        -  5      (       ax  U S:X  a  X0-   S-   [        U5      -   S-   v   g USL a
  X0-   S-   v   g USL a
  X0-   S	-   v   g US
:  d  US:  a  X0-   S-   [        U5      -   S-   v   g X0-   S-   [        U5      -   v   g [        U[        5      (       a  [        U5      R                  5       nU[        [        S5      5      R                  5       :X  a  SU-   nO;UR                  S5      nUS:w  a$  UR                  SSU5      S:X  a  US U S-   XVS  -   nU S:X  a  X0-   S-   U-   S-   v   g X0-   S-   U-   v   g [        U[        5      (       aA  X0-   S-   v   US-   nUR                  5        H  u  pT
" XSU5       S h  vN   M     US-   v   g [        U[        5      (       a*  U S:X  a$  X0-   SSR                  S U 5       5       S3-   v   g [        U[        [        -  5      (       am  U S:w  ag  U(       d`  [!        U5      S:X  a  X0-   S-   SU< S3-   v   [!        U5      S:X  a  X0-   S-   S["         S3-   v   U H  nT
" XSUS5       S h  vN   M     g T(       a	   T" U5      n[        U[        5      (       d  [        U< S35      eX0-   S-   ['        U5      -   S-   v   g g  GN' NZ! [$         a  n	[        U< S35      U	eS n	A	ff = f7f)Nr5   z is not a valid keyrM   z "r}   Tz 1Fz 0i   l        r~   inf+Er(   .r   z [  r^   r   z "(r   c              3   8   #    U  H  n[        U5      v   M     g 7fr   )r   )ry   r   s     r   r{   2generate_gml.<locals>.stringize.<locals>.<genexpr>  s     4LeT!WWes   z)"r#   z" cannot be converted into a string)r   r   r	   r   r*   r   r   r   upperrfindrW   r   r   r   r   r   r   r   r/   r    )r   ro   ignored_keysindentin_listr   eposnext_indentvalr9   r   
stringizer
valid_keyss             r   r   generate_gml.<locals>.stringize  sU    #s##3')9 :;;$$3')< =>>#s##c(C"%t,,'> ,-E
:S@@d] ,--e^ ,--X%% ,-E
:S@@ ,,s5z99E5))E{((* 4e-3355:D
  ::c?DrzdiiQ&=&C#ET{S04;>'> ,-4s:: ,,t33E4((lT))$tm"'++-JC(REEE #0sl"E5))cWnltCHH4Le4L,L+MS%QQQE4%<00SG^Gu:? ,,5)1~==u:? ,,3C2DA/FFF C(2vtDDD ! # *5 1
 "%--'5)3C(DEElT)F5M9C??q #F F E
 & #+$i'IJ"##sI   HML+CML.M%L0 -?M.M0
M:M

MMzgraph [z  directed 1z  multigraph 1>   r   r   r   r   r   Nr   rM   z  node [z    id r^   z    z  ]r   r   dataTr   keysz  edge [z    source r   z    target r#   r%   r(   r   )F)r   r   is_multigraphis_directedr   r   r   zipr   r   r   r   r   r   )rO   r  r   r   r   ro   node_idr   attrskwargser   r  s    `         @@r   r   r   r  s    f 56J?@ ?@B "J
O 	}}=Lww}}T,=== ' 3q%A-()G'?Lww}}#gm,,,WdB777 ;;=KD lFCCC ) ' h'Ld^FvWWvc'A$-000c'A$-000 !b&999R5;;=KD lFCCC )  I9 	> 	8C :Cs\   B	HG=A6HH &H,H-BH=H>)H'H(H HHHHr#   wbc                 n    [        X5       H&  nUR                  US-   R                  S5      5        M(     g)a  Write a graph `G` in GML format to the file or file handle `path`.

Parameters
----------
G : NetworkX graph
    The graph to be converted to GML.

path : filename or filehandle
    The filename or filehandle to write. Files whose names end with .gz or
    .bz2 will be compressed.

stringizer : callable, optional
    A `stringizer` which converts non-int/non-float/non-dict values into
    strings. If it cannot convert a value into a string, it should raise a
    `ValueError` to indicate that. Default value: None.

Raises
------
NetworkXError
    If `stringizer` cannot convert a value into a string, or the value to
    convert is not a string while `stringizer` is None.

See Also
--------
read_gml, generate_gml
literal_stringizer

Notes
-----
Graph attributes named 'directed', 'multigraph', 'node' or
'edge', node attributes named 'id' or 'label', edge attributes
named 'source' or 'target' (or 'key' if `G` is a multigraph)
are ignored because these attribute names are used to encode the graph
structure.

GML files are stored using a 7-bit ASCII encoding with any extended
ASCII characters (iso8859-1) appearing as HTML character entities.
Without specifying a `stringizer`/`destringizer`, the code is capable of
writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
specification.  For writing other data types, and for reading data other
than `str` you need to explicitly supply a `stringizer`/`destringizer`.

Note that while we allow non-standard GML to be read from a file, we make
sure to write GML format. In particular, underscores are not allowed in
attribute names.
For additional documentation on the GML file format, please see the
`GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

See the module docstring :mod:`networkx.readwrite.gml` for more details.

Examples
--------
>>> G = nx.path_graph(4)
>>> nx.write_gml(G, "test.gml")

Filenames ending in .gz or .bz2 will be compressed.

>>> nx.write_gml(G, "test.gml.gz")
rC   rA   N)r   r   r   )rO   rL   r  rG   s       r   r   r   1  s/    z Q+

D4K''01 ,r   )rM   Nr   )%rc   html.entitiesentitiesr+   r   warningsastr   collectionsr   enumr   ior   typingr   r   networkxr   networkx.exceptionr	   networkx.utilsr
   __all__r    r3   r:   _dispatchabler   r   rZ   rm   r   rK   r   r   r   r^   r   r   <module>r     s   < ' 	   #   "  , $
@8O258 14T2O 3 Od T2J 3JZ	d 	J  * _DbJ|~ 14=2 =2r   