+
    �°³jF[  ã                   ó2  € R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtH	t	 ^ RIH
t
HtHt ^ RIt. ROtRR ltR tRR	 ltRR
 ltRR ltR tRR ltR tRR lt ! R R]P2                  4      t ! R R4      tRR ltR tRR/R ltR tR t RRRRRR/R lt!R# )a  
Miscellaneous Helpers for NetworkX.

These are not imported into the base networkx namespace but
can be accessed, for example, as

>>> import networkx as nx
>>> nx.utils.make_list_of_ints({1, 2, 3})
[1, 2, 3]
>>> nx.utils.arbitrary_element({5, 1, 7})  # doctest: +SKIP
1
N)Údefaultdict)ÚIterableÚIteratorÚSized)ÚchainÚteeÚzip_longestÚPythonRandomInterfaceÚPythonRandomViaNumpyBitsc                óR  € \        V \        \        ,          4      '       d   \        V \        4      '       d   V # Vf   . pV  FX  p\        V\        \        ,          4      '       d   \        V\        4      '       d   VP	                  V4       KM  \        W!4       KZ  	  \        V4      # )z>Return flattened version of (possibly nested) iterable object.)Ú
isinstancer   r   ÚstrÚappendÚflattenÚtuple)ÚobjÚresultÚitems   && ÚT/home/luca/screen-checking/.venv/lib/python3.14/site-packages/networkx/utils/misc.pyr   r   .   sw   € ä�cœ8¤eÕ+×,Ò,´
¸3Ä×0DÒ0DØˆ
Ø‚~ØˆÛˆÜ˜$¤¬5Õ 0×1Ò1´ZÀÄc×5JÒ5JØ�M‰M˜$Öä�DÖ!ñ	 ô
 �‹=Ðó    c                ó  € \        V \        4      '       gL   . pV  FA  pRV 2p \        V4      pYB8w  d   \        P
                  ! T4      hTP                  T4       KC  	  V# \        V 4       FN  w  rRRV 2p\        V\        4      '       d   K"   \        V4      pYB8w  d   \        P
                  ! T4      hY@T&   KP  	  V #   \         d    \        P
                  ! T4      Rhi ; i  \         d    \        P
                  ! T4      Rhi ; i)a  Return list of ints from sequence of integral numbers.

All elements of the sequence must satisfy int(element) == element
or a ValueError is raised. Sequence is iterated through once.

If sequence is a list, the non-int values are replaced with ints.
So, no new list is created
zsequence is not all integers: N)r   ÚlistÚintÚ
ValueErrorÚnxÚNetworkXErrorr   Ú	enumerate)Úsequencer   ÚiÚerrmsgÚiiÚindxs   &     r   Úmake_list_of_intsr"   <   s  € ô �h¤×%Ò%ØˆÛˆAØ5°a°SÐ9ˆFð9Ü˜“V�ð ŒwÜ×&Ò& vÓ.Ð.Ø�M‰M˜"Öñ ð ˆä˜XÖ&‰ˆØ1°!°Ð5ˆÜ�aœ×ÒÙð	5Ü�Q“ˆBð Œ7Ü×"Ò" 6Ó*Ð*Ø�‹ñ 'ð €Oøô% ô 9Ü×&Ò& vÓ.°DÐ8ð9ûô ô 	5Ü×"Ò" 6Ó*°Ð4ð	5ús   ¤CÂC'Ã#C$Ã'#D
c                ó^   €  \        W4      #   \        \        3 d    \        Y4      u # i ; i)zLConvert a dictionary of dictionaries to a numpy array
with optional mapping.)Ú_dict_to_numpy_array2ÚAttributeErrorÚ	TypeErrorÚ_dict_to_numpy_array1)ÚdÚmappings   &&r   Údict_to_numpy_arrayr*   `   s3   € ð1Ü$ QÓ0Ð0øÜœIÐ&ô 1ô % QÓ0Ò0ð1ús   ‚
 �,«,c           
     óð  € ^ RI pVfy   \        V P                  4       4      pV P                  4        F$  w  rEVP	                  VP                  4       4       K&  	  \        \        V\        \        V4      4      4      4      p\        V4      pVP                  Wf34      pVP                  4        F2  w  r‰VP                  4        F  w  r« W,          V
,          WyV3&   K  	  K4  	  V#   \         d     K1  i ; i)zQConvert a dictionary of dictionaries to a 2d numpy array
with optional mapping.

N)ÚnumpyÚsetÚkeysÚitemsÚupdateÚdictÚzipÚrangeÚlenÚzerosÚKeyError)r(   r)   ÚnpÚsÚkÚvÚnÚaÚk1r   Úk2Újs   &&          r   r$   r$   k   sÆ   € ó
 à‚Ü�—‘“‹MˆØ—G‘G–I‰DˆAØ�H‰H�Q—V‘V“XÖñ ä”s˜1œe¤C¨£F›mÓ,Ó-ˆÜˆG‹€AØ
�‰�!�Ó€AØ—‘–‰ˆØ—]‘]–_‰EˆBðØ�% �)��Q�$“ó %ñ !ð €Høô ô Úðús   Ã	C&Ã&C5Ã4C5c           
     ó$  € ^ RI pVfA   \        V P                  4       4      p\        \	        V\        \        V4      4      4      4      p\        V4      pVP                  V4      pVP                  4        F  w  rgW,          pW,          WW&   K  	  V# )zJConvert a dictionary of numbers to a 1d numpy array with optional mapping.N)	r,   r-   r.   r1   r2   r3   r4   r5   r/   )r(   r)   r7   r8   r;   r<   r=   r   s   &&      r   r'   r'   ‚   sq   € ãà‚Ü�—‘“‹MˆÜ”s˜1œe¤C¨£F›mÓ,Ó-ˆÜˆG‹€AØ
�‰�‹€AØ—‘–‰ˆØ�KˆØ�uˆ‹ñ !ð €Hr   c                ól   € \        V \        4      '       d   \        R4      h\        \	        V 4      4      # )a
  Returns an arbitrary element of `iterable` without removing it.

This is most useful for "peeking" at an arbitrary element of a set,
but can be used for any list, dictionary, etc., as well.

Parameters
----------
iterable : `abc.collections.Iterable` instance
    Any object that implements ``__iter__``, e.g. set, dict, list, tuple,
    etc.

Returns
-------
The object that results from ``next(iter(iterable))``

Raises
------
ValueError
    If `iterable` is an iterator (because the current implementation of
    this function would consume an element from the iterator).

Examples
--------
Arbitrary elements from common Iterable objects:

>>> nx.utils.arbitrary_element([1, 2, 3])  # list
1
>>> nx.utils.arbitrary_element((1, 2, 3))  # tuple
1
>>> nx.utils.arbitrary_element({1, 2, 3})  # set
1
>>> d = {k: v for k, v in zip([1, 2, 3], [3, 2, 1])}
>>> nx.utils.arbitrary_element(d)  # dict_keys
1
>>> nx.utils.arbitrary_element(d.values())  # dict values
3

`str` is also an Iterable:

>>> nx.utils.arbitrary_element("hello")
'h'

:exc:`ValueError` is raised if `iterable` is an iterator:

>>> iterator = iter([1, 2, 3])  # Iterator, *not* Iterable
>>> nx.utils.arbitrary_element(iterator)
Traceback (most recent call last):
    ...
ValueError: cannot return an arbitrary item from an iterator

Notes
-----
This function does not return a *random* element. If `iterable` is
ordered, sequential calls will return the same value::

    >>> l = [1, 2, 3]
    >>> nx.utils.arbitrary_element(l)
    1
    >>> nx.utils.arbitrary_element(l)
    1

z0cannot return an arbitrary item from an iterator)r   r   r   ÚnextÚiter)Úiterables   &r   Úarbitrary_elementrE   ‘   s-   € ô~ �(œH×%Ò%ÜÐKÓLÐLä”�X“ÓÐr   Fc                óœ   € V'       g   \         P                  ! V 4      # \        V 4      w  r#\        VR4      p\	        V\        W434      4      # )aF  Return successive overlapping pairs taken from an input iterable.

Parameters
----------
iterable : iterable
    An iterable from which to generate pairs.

cyclic : bool, optional (default=False)
    If `True`, a pair with the last and first items is included at the end.

Returns
-------
iterator
    An iterator over successive overlapping pairs from the `iterable`.

See Also
--------
itertools.pairwise

Examples
--------
>>> list(nx.utils.pairwise([1, 2, 3, 4]))
[(1, 2), (2, 3), (3, 4)]

>>> list(nx.utils.pairwise([1, 2, 3, 4], cyclic=True))
[(1, 2), (2, 3), (3, 4), (4, 1)]
N)Ú	itertoolsÚpairwiser   rB   r2   r   )rD   Úcyclicr<   ÚbÚfirsts   &&   r   rH   rH   Ö   sB   € ÷8 Ü×!Ò! (Ó+Ð+Üˆx‹=�D€AÜ��D‹M€EÜˆq”%˜˜8Ó$Ó%Ð%r   c                ó–   € \        \        4      pV P                  4        F  w  r#W,          P                  V4       K  	  \	        V4      # )aÓ  Converts a many-to-one mapping into a one-to-many mapping.

`many_to_one` must be a dictionary whose keys and values are all
:term:`hashable`.

The return value is a dictionary mapping values from `many_to_one`
to sets of keys from `many_to_one` that have that value.

Examples
--------
>>> from networkx.utils import groups
>>> many_to_one = {"a": 1, "b": 1, "c": 2, "d": 3, "e": 3}
>>> groups(many_to_one)  # doctest: +SKIP
{1: {'a', 'b'}, 2: {'c'}, 3: {'e', 'd'}}
)r   r-   r/   Úaddr1   )Úmany_to_oneÚone_to_manyr:   r9   s   &   r   ÚgroupsrP   ù   s>   € ô  œcÓ"€KØ×!Ñ!Ö#‰ˆØ�×Ñ˜1Öñ $ä�ÓÐr   c                óŽ  € ^ RI pV e   WP                  J d!   VP                  P                  P                  # \	        WP                  P
                  4      '       d   V # \	        V \        4      '       d   VP                  P                  V 4      # \	        WP                  P                  4      '       d   V # V  R2p\        V4      h)aß  Returns a numpy.random.RandomState or numpy.random.Generator instance
depending on input.

Parameters
----------
random_state : int or NumPy RandomState or Generator instance, optional (default=None)
    If int, return a numpy.random.RandomState instance set with seed=int.
    if `numpy.random.RandomState` instance, return it.
    if `numpy.random.Generator` instance, return it.
    if None or numpy.random, return the global random number generator used
    by numpy.random.
NzW cannot be used to create a numpy.random.RandomState or
numpy.random.Generator instance)	r,   ÚrandomÚmtrandÚ_randr   ÚRandomStater   Ú	Generatorr   ©Úrandom_stater7   Úmsgs   &  r   Úcreate_random_staterZ     s¤   € ó àÒ˜|¯y©yÓ8Ø�y‰y×Ñ×%Ñ%Ð%Ü�,§	¡	× 5Ñ 5×6Ò6ØÐÜ�,¤×$Ò$Ø�y‰y×$Ñ$ \Ó2Ð2Ü�,§	¡	× 3Ñ 3×4Ò4ØÐàˆ.ð *ð 	*ð ô �S‹/Ðr   c                   óL   a € ] tR tRt o RtRR ltR tR tR tR t	R	 t
R
tV tR# )r
   i-  a�  Provide the random.random algorithms using a numpy.random bit generator

The intent is to allow people to contribute code that uses Python's random
library, but still allow users to provide a single easily controlled random
bit-stream for all work with NetworkX. This implementation is based on helpful
comments and code from Robert Kern on NumPy's GitHub Issue #24458.

This implementation supersedes that of `PythonRandomInterface` which rewrote
methods to account for subtle differences in API between `random` and
`numpy.random`. Instead this subclasses `random.Random` and overwrites
the methods `random`, `getrandbits`, `getstate`, `setstate` and `seed`.
It makes them use the rng values from an input numpy `RandomState` or `Generator`.
Those few methods allow the rest of the `random.Random` methods to provide
the API interface of `random.random` while using randomness generated by
a numpy generator.
Nc                óÚ   €  ^ RI pVf'   XP
                  P                  P                  V n        MWn        RV n	        R#   \         d!    Rp\        P                  ! T\        4        Lci ; i©é    Nz.numpy not found, only random.random available.)
r,   ÚImportErrorÚwarningsÚwarnÚImportWarningrR   rS   rT   Ú_rngÚ
gauss_next©ÚselfÚrngr7   rY   s   &&  r   Ú__init__Ú!PythonRandomViaNumpyBits.__init__?  sZ   € ð	.Ûð
 Š;ØŸ	™	×(Ñ(×.Ñ.ˆD�IàŒIð ˆŽøô ô 	.ØBˆCÜ�MŠM˜#œ}Ö-ð	.ús   ‚? ¿(A*Á)A*c                ó6   € V P                   P                  4       # )z7Get the next random number in the range 0.0 <= X < 1.0.©rc   rR   ©rf   s   &r   rR   ÚPythonRandomViaNumpyBits.randomO  s   € à�y‰y×ÑÓ!Ð!r   c                óÐ   € V^ 8  d   \        R4      hV^,           ^,          p\        P                  V P                  P	                  V4      R4      pW2^,          V,
          ,	          # )z:getrandbits(k) -> x.  Generates an int with k random bits.z#number of bits must be non-negativeÚbig)r   r   Ú
from_bytesrc   Úbytes)rf   r9   ÚnumbytesÚxs   &&  r   ÚgetrandbitsÚ$PythonRandomViaNumpyBits.getrandbitsS  sQ   € àˆqŒ5ÜÐBÓCÐCØ˜•E˜a•<ˆÜ�N‰N˜4Ÿ9™9Ÿ?™?¨8Ó4°eÓ<ˆØ •\ AÕ%Õ&Ð&r   c                ó6   € V P                   P                  4       # ©N)rc   Ú__getstate__rl   s   &r   ÚgetstateÚ!PythonRandomViaNumpyBits.getstate[  s   € Ø�y‰y×%Ñ%Ó'Ð'r   c                ó<   € V P                   P                  V4       R # rw   )rc   Ú__setstate__)rf   Ústates   &&r   ÚsetstateÚ!PythonRandomViaNumpyBits.setstate^  s   € Ø�	‰	×Ñ˜uÖ%r   c                ó   € \        R4      h)zDo nothing override method.z2seed() not implemented in PythonRandomViaNumpyBits)ÚNotImplementedError)rf   ÚargsÚkwdss   &*,r   ÚseedÚPythonRandomViaNumpyBits.seeda  s   € ä!Ð"VÓWÐWr   )rc   rd   rw   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rh   rR   rt   ry   r~   r„   Ú__static_attributes__Ú__classdictcell__©Ú__classdict__s   @r   r
   r
   -  s/   ø‡ € ñô"ò "ò'ò(ò&÷Xð Xr   c                   ót   a € ] tR tRt o RtRR ltR tR tRR ltR t	R	 t
R
 tR tR tR tR tR tRtV tR# )r	   ig  zõPythonRandomInterface is included for backward compatibility
New code should use PythonRandomViaNumpyBits instead.

Unsupported Python `random` API methods will raise an informative
AttributeError suggesting the use of `numpy.random.Generator`.
Nc                óÎ   €  ^ RI pVf(   XP
                  P                  P                  V n        R# Wn        R#   \         d!    Rp\        P                  ! T\        4        L]i ; ir]   )	r,   r_   r`   ra   rb   rR   rS   rT   rc   re   s   &&  r   rh   ÚPythonRandomInterface.__init__o  sQ   € ð	.Ûð
 Š;ØŸ	™	×(Ñ(×.Ñ.ˆDŽIàŽIøô ô 	.ØBˆCÜ�MŠM˜#œ}Ö-ð	.ús   ‚9 ¹(A$Á#A$c                ó6   € V P                   P                  4       # rw   rk   rl   s   &r   rR   ÚPythonRandomInterface.random{  s   € Ø�y‰y×ÑÓ!Ð!r   c                ó^   € WV,
          V P                   P                  4       ,          ,           # rw   rk   )rf   r<   rJ   s   &&&r   ÚuniformÚPythonRandomInterface.uniform~  s!   € Ø˜•E˜TŸY™Y×-Ñ-Ó/Õ/Õ/Ð/r   c                ó>  € ^ RI pVf   ^ Tr!VR8”  d'   \        V P                  4      pVP                  W4      # \	        V P                  VP
                  P                  4      '       d   V P                  P                  W4      # V P                  P                  W4      # ©r^   Nl   ÿÿÿÿ )	r,   r
   rc   Ú	randranger   rR   rV   ÚintegersÚrandint©rf   r<   rJ   r7   Útmp_rngs   &&&  r   r™   ÚPythonRandomInterface.randrange�  s~   € ÛàŠ9Ø�aˆqØÐ"Ô"Ü.¨t¯y©yÓ9ˆGØ×$Ñ$ QÓ*Ð*ä�d—i‘i §¡×!4Ñ!4×5Ò5Ø—9‘9×%Ñ% aÓ+Ð+Ø�y‰y× Ñ  Ó&Ð&r   c                ó  € ^ RI p\        V P                  VP                  P                  4      '       d.   V P                  P                  ^ \        V4      4      pW,          # V P                  P                  ^ \        V4      4      pW,          # )r^   N)r,   r   rc   rR   rV   rš   r4   r›   )rf   Úseqr7   Úidxs   &&  r   ÚchoiceÚPythonRandomInterface.choice�  sf   € Ûä�d—i‘i §¡×!4Ñ!4×5Ò5Ø—)‘)×$Ñ$ Q¬¨C«Ó1ˆCð �xˆð —)‘)×#Ñ# A¤s¨3£xÓ0ˆCØ�xˆr   c                ó8   € V P                   P                  W4      # rw   )rc   Únormal)rf   ÚmuÚsigmas   &&&r   ÚgaussÚPythonRandomInterface.gauss™  s   € Ø�y‰y×Ñ Ó*Ð*r   c                ó8   € V P                   P                  V4      # rw   )rc   Úshuffle)rf   r    s   &&r   r«   ÚPythonRandomInterface.shuffleœ  s   € Ø�y‰y× Ñ  Ó%Ð%r   c                óR   € V P                   P                  \        V4      V3R R7      # )F)ÚsizeÚreplace)rc   r¢   r   )rf   r    r9   s   &&&r   ÚsampleÚPythonRandomInterface.sample¢  s$   € Ø�y‰y×Ñ¤ S£	°°¸eÐÓDÐDr   c                óL  € ^ RI pVR8”  d'   \        V P                  4      pVP                  W4      # \	        V P                  VP
                  P                  4      '       d#   V P                  P                  W^,           4      # V P                  P                  W^,           4      # r˜   )r,   r
   rc   r›   r   rR   rV   rš   rœ   s   &&&  r   r›   ÚPythonRandomInterface.randint¥  sx   € ÛàÐ"Ô"Ü.¨t¯y©yÓ9ˆGØ—?‘? 1Ó(Ð(ä�d—i‘i §¡×!4Ñ!4×5Ò5Ø—9‘9×%Ñ% a¨Q­Ó/Ð/Ø�y‰y× Ñ  ¨¥EÓ*Ð*r   c                óF   € V P                   P                  ^V,          4      # )é   )rc   Úexponential)rf   Úscales   &&r   ÚexpovariateÚ!PythonRandomInterface.expovariate±  s   € Ø�y‰y×$Ñ$ Q¨¥YÓ/Ð/r   c                ó8   € V P                   P                  V4      # rw   )rc   Úpareto)rf   Úshapes   &&r   ÚparetovariateÚ#PythonRandomInterface.paretovariateµ  s   € Ø�y‰y×Ñ Ó&Ð&r   c                óª   € \        \        P                  V4      '       d   \        R V R24      h\        R\	        V 4      P
                   RV R24      h)zrandom.za is not supported when using numpy.random.RandomState. Please use numpy.random.Generator instead.Ú'z' object has no attribute ')ÚhasattrrR   ÚRandomr%   Útyper†   )rf   Únames   &&r   Ú__getattr__Ú!PythonRandomInterface.__getattr__¸  s^   € Ü”6—=‘= $×'Ò'Ü Ø˜$˜ð  =ð =óð ô Ø”�T“
×#Ñ#Ð$Ð$?À¸vÀQÐGó
ð 	
r   )rc   rw   )r†   r‡   rˆ   r‰   rŠ   rh   rR   r•   r™   r¢   r¨   r«   r°   r›   r¸   r½   rÅ   r‹   rŒ   r�   s   @r   r	   r	   g  sL   ø‡ € ñô
ò"ò0ô'òò+ò&òEò	+ò0ò'÷
ð 
r   c                óú  € V e   V \         J d   \         P                  # \        V \         P                  4      '       d   V # \        V \        4      '       d   \         P                  ! V 4      #  ^ RIp\        V \        \        ,          4      '       d   V # \        WP                   P                  4      '       d   \        V 4      # WP                   J d*   \        VP                   P                  P                  4      # \        WP                   P                  4      '       d:   WP                   P                  P                  J d   \        V 4      # \        V 4      #  V  R2p\        V4      h  \         d     Li ; i)a±  Returns a random.Random instance depending on input.

Parameters
----------
random_state : int or random number generator or None (default=None)
    - If int, return a `random.Random` instance set with seed=int.
    - If `random.Random` instance, return it.
    - If None or the `np.random` package, return the global random number
      generator used by `np.random`.
    - If an `np.random.Generator` instance, or the `np.random` package, or
      the global numpy random number generator, then return it.
      wrapped in a `PythonRandomViaNumpyBits` class.
    - If a `PythonRandomViaNumpyBits` instance, return it.
    - If a `PythonRandomInterface` instance, return it.
    - If a `np.random.RandomState` instance and not the global numpy default,
      return it wrapped in `PythonRandomInterface` for backward bit-stream
      matching with legacy code.

Notes
-----
- A diagram intending to illustrate the relationships behind our support
  for numpy random numbers is called
  `NetworkX Numpy Random Numbers <https://excalidraw.com/#room=b5303f2b03d3af7ccc6a,e5ZDIWdWWCTTsg8OqoRvPA>`_.
- More discussion about this support also appears in
  `gh-6869#comment <https://github.com/networkx/networkx/pull/6869#issuecomment-1944799534>`_.
- Wrappers of numpy.random number generators allow them to mimic the Python random
  number generation algorithms. For example, Python can create arbitrarily large
  random ints, and the wrappers use Numpy bit-streams with CPython's random module
  to choose arbitrarily large random integers too.
- We provide two wrapper classes:
  `PythonRandomViaNumpyBits` is usually what you want and is always used for
  `np.Generator` instances. But for users who need to recreate random numbers
  produced in NetworkX 3.2 or earlier, we maintain the `PythonRandomInterface`
  wrapper as well. We use it only used if passed a (non-default) `np.RandomState`
  instance pre-initialized from a seed. Otherwise the newer wrapper is used.
Nz4 cannot be used to generate a random.Random instance)rR   Ú_instr   rÂ   r   r,   r	   r
   rV   rS   rT   rU   r_   r   rW   s   &  r   Úcreate_py_random_staterÉ   Î  s+  € ðJ Ò˜|¬vÓ5Ü�|‰|ÐÜ�,¤§¡×.Ò.ØÐÜ�,¤×$Ò$Ü�}Š}˜\Ó*Ð*ð7Ûô �lÔ$9Ô<TÕ$T×UÒUØÐÜ�l§I¡I×$7Ñ$7×8Ò8Ü+¨LÓ9Ð9ØŸ9™9Ó$Ü+¨B¯I©I×,<Ñ,<×,BÑ,BÓCÐCä�l§I¡I×$9Ñ$9×:Ò:ØŸy™y×/Ñ/×5Ñ5Ó5Ü/°Ó=Ð=ä(¨Ó6Ð6ð	 ;ð ˆNÐNÐ
O€CÜ
�S‹/Ðøô# ô Ùðús   Á.E, Å,E:Å9E:c                óì   € \        V 4      p\        V4      p \        V4      p\        V4      pWE8H  #   \        \        3 d1    \        P	                  T4      p\        P	                  T4      p YE8H  # i ; i)a)  Check if nodes are equal.

Equality here means equal as Python objects.
Node data must match if included.
The order of nodes is not relevant.

Parameters
----------
nodes1, nodes2 : iterables of nodes, or (node, datadict) tuples

Returns
-------
bool
    True if nodes are equal, False otherwise.
)r   r1   r   r&   Úfromkeys)Únodes1Únodes2Únlist1Únlist2Úd1Úd2s   &&    r   Únodes_equalrÒ     so   € ô  �&‹\€FÜ�&‹\€Fð#Ü�&‹\ˆÜ�&‹\ˆð ‰8€Oøô œ	Ð"ô #Ü�]‰]˜6Ó"ˆÜ�]‰]˜6Ó"‰Ø‰8€Oð#ús   ˜2 ²;A3Á2A3Údirectedc               óž  a
a€ \        \        4      o
\        \        4      o\        WRR7       Fa  w  r4Ve   Vf    R# VS
3VS33 FE  w  rVVvrxp	WgV3,          P                  V	4       V'       d   K,  WhV3,          P                  V	4       KG  	  Kc  	  \        ;QJ d     V
V3R lS
 4       F  '       d   K   R# 	  R# ! V
V3R lS
 4       4      # )a†  Return whether edgelists are equal.

Equality here means equal as Python objects. Edge data must match
if included. Ordering of edges in an edgelist is not relevant;
ordering of nodes in an edge is only relevant if ``directed == True``.

Parameters
----------
edges1, edges2 : iterables of tuples
    Each tuple can be
    an edge tuple ``(u, v)``, or
    an edge tuple with data `dict` s ``(u, v, d)``, or
    an edge tuple with keys and data `dict` s ``(u, v, k, d)``.

directed : bool, optional (default=False)
    If `True`, edgelists are treated as coming from directed
    graphs.

Returns
-------
bool
    `True` if edgelists are equal, `False` otherwise.

Examples
--------
>>> G1 = nx.complete_graph(3)
>>> G2 = nx.cycle_graph(3)
>>> edges_equal(G1.edges, G2.edges)
True

Edge order is not taken into account:

>>> G1 = nx.Graph([(0, 1), (1, 2)])
>>> G2 = nx.Graph([(1, 2), (0, 1)])
>>> edges_equal(G1.edges, G2.edges)
True

The `directed` parameter controls whether edges are treated as
coming from directed graphs.

>>> DG1 = nx.DiGraph([(0, 1)])
>>> DG2 = nx.DiGraph([(1, 0)])
>>> edges_equal(DG1.edges, DG2.edges, directed=False)  # Not recommended.
True
>>> edges_equal(DG1.edges, DG2.edges, directed=True)
False

This function is meant to be used on edgelists (i.e. the output of a
``G.edges()`` call), and can give unexpected results on unprocessed
lists of edges:

>>> l1 = [(0, 1)]
>>> l2 = [(0, 1), (1, 0)]
>>> edges_equal(l1, l2)  # Not recommended.
False
>>> G1 = nx.Graph(l1)
>>> G2 = nx.Graph(l2)
>>> edges_equal(G1.edges, G2.edges)
True
>>> DG1 = nx.DiGraph(l1)
>>> DG2 = nx.DiGraph(l2)
>>> edges_equal(DG1.edges, DG2.edges, directed=True)
False
N)Ú	fillvalueFc              3   ó¦   <"  € T FF  pSV,           F6  pSV,          P                  V4      SV,          P                  V4      8H  x € K8  	  KH  	  R # 5irw   )Úcount)Ú.0ÚeÚdatarÐ   rÑ   s   &  €€r   Ú	<genexpr>Úedges_equal.<locals>.<genexpr>y  s@   øé € ÐT¹r¸!ÈbÐQRÏeÈeÀdˆr�!�u�{‰{˜4Ó  B q¥E§K¡K°Ó$5Ö5ÉeÑ5»rùs   ƒAAT)r   r   r   r   Úall)Úedges1Úedges2rÓ   Úe1Úe2rÙ   r(   Úur:   rÚ   rÐ   rÑ   s   &&$       @@r   Úedges_equalrã   +  s¯   ù€ ôB 
”TÓ	€BÜ	”TÓ	€Bä˜f¸×=‰ˆØŠ:˜šÚØ˜"�X  B˜xÓ(‰DˆAØˆKˆA�4Ø�ˆd�G�N‰N˜4Ô ß‘8Ø�Q�$•—‘˜tÖ$ó	 )ñ >÷ ‹3ÕT¹rÓT�3Œ3ÐTŠ3ÐTˆ3ÕT¹rÓTÓTÐTr   c                ó¸   € V P                   VP                   8H  ;'       d;    V P                  VP                  8H  ;'       d    V P                  VP                  8H  # )zôCheck if graphs are equal.

Equality here means equal as Python objects (not isomorphism).
Node, edge and graph data must match.

Parameters
----------
graph1, graph2 : graph

Returns
-------
bool
    True if graphs are equal, False otherwise.
)ÚadjÚnodesÚgraph)Úgraph1Úgraph2s   &&r   Úgraphs_equalrê   |  sM   € ð  	�
‰
�f—j‘jÑ ÷ 	)ð 	)Ø�L‰L˜FŸL™LÑ(÷	)ð 	)à�L‰L˜FŸL™LÑ(ðr   c                óT   € \        V RR4      ;p'       d   VP                  4        R# R# )z�Clear the cache of a graph (currently stores converted graphs).

Caching is controlled via ``nx.config.cache_converted_graphs`` configuration.
Ú__networkx_cache__N)ÚgetattrÚclear)ÚGÚcaches   & r   Ú_clear_cacherñ   ’  s'   € ô
 ˜Ð/°Ó6Ð6€uÖ6Ø�‰Žñ 7r   Ú
multigraphÚdefaultc               óZ  € Vf   \         P                  pV e   T MTp\        V\        4      '       d   VP	                  R4      MVP	                  4       p\        V\        4      '       d   VP                  R4      MVP                  4       pVeM   V'       d   V'       g   \         P                  ! R4      hV'       g   V'       d   \         P                  ! R4      hVeM   V'       d   V'       g   \         P                  ! R4      hV'       g   V'       d   \         P                  ! R4      hV# )a½  Assert that create_using has good properties

This checks for desired directedness and multi-edge properties.
It returns `create_using` unless that is `None` when it returns
the optionally specified default value.

Parameters
----------
create_using : None, graph class or instance
    The input value of create_using for a function.
directed : None or bool
    Whether to check `create_using.is_directed() == directed`.
    If None, do not assert directedness.
multigraph : None or bool
    Whether to check `create_using.is_multigraph() == multigraph`.
    If None, do not assert multi-edge property.
default : None or graph class
    The graph class to return if create_using is None.

Returns
-------
create_using : graph class or instance
    The provided graph class or instance, or if None, the `default` value.

Raises
------
NetworkXError
    When `create_using` doesn't match the properties specified by `directed`
    or `multigraph` parameters.
Nzcreate_using must be directedz!create_using must not be directedz"create_using must be a multi-graphz&create_using must not be a multi-graph)r   ÚGraphr   rÃ   Úis_directedÚis_multigraphr   )Úcreate_usingrÓ   rò   ró   rï   Ú
G_directedÚG_multigraphs   &$$$   r   Úcheck_create_usingrû   ›  sÐ   € ð> ‚Ü—(‘(ˆØ$Ò0‰°g€Aä(2°1´d×(;Ò(;�—‘˜tÔ$ÀÇÁÃ€JÜ,6°q¼$×,?Ò,?�1—?‘? 4Ô(ÀQÇ_Á_ÓEV€LàÒßŸJÜ×"Ò"Ð#BÓCÐCßŸJÜ×"Ò"Ð#FÓGÐGàÒßŸlÜ×"Ò"Ð#GÓHÐHßŸlÜ×"Ò"Ð#KÓLÐLØ€Hr   )r   r"   r*   rE   rH   rP   rZ   rÉ   r	   r
   rÒ   rã   rê   rñ   rw   )F)"rŠ   rG   rR   r`   Úcollectionsr   Úcollections.abcr   r   r   r   r   r   Únetworkxr   Ú__all__r   r"   r*   r$   r'   rE   rH   rP   rZ   rÂ   r
   r	   rÉ   rÒ   rã   rê   rñ   rû   © r   r   Ú<module>r     sÀ   ðñó Û Û Ý #ß 5Ñ 5ß -Ñ -ã ò€ô.ò!ôH1ôô.òB ôJ &òFô,ô<6X˜vŸ}™}ô 6X÷tY
ñ Y
ôN?òDð6NU¨Eô NUòbò,ð1°ð 1À$ð 1ÐPTö 1r   