
    A>i}P                       S SK Jr  S SKJrJr  S SKrS SKJrJrJ	r	J
r
  S SKrS SKJr  S SKJr  S SKrS SKJrJr  \(       a  S SKJr  S S	KJrJr  SS
 jr\
    S           SS jj5       r\
    S           SS jj5       r    S           SS jjr          SS jrSS jr S     SS jjrSS jr\" S5             S                 S S jj5       r g)!    )annotations)abcdefaultdictN)TYPE_CHECKINGAnyDefaultDictoverloadconvert_json_to_lines)
set_module)	DataFrameSeries)Iterable)IgnoreRaiseScalarc                J    U S   S:X  d  U S   S:X  a  U $ U SS n [        U 5      $ )zB
Helper function that converts JSON lists to line delimited JSON.
r   []   r
   )ss    X/var/www/html/land-tabula/venv/lib/python3.13/site-packages/pandas/io/json/_normalize.pyconvert_to_line_delimitsr   %   s4     Q43;1R5C<	!BA ##    c                    g N dsprefixseplevel	max_levels        r   nested_to_recordr$   2   s     r   c                    g r   r   r   s        r   r$   r$   <   s     r   c                    Sn[        U [        5      (       a  U /n Sn/ nU  H  n[        R                  " U5      nUR	                  5        H  u  p[        U	[
        5      (       d  [        U	5      n	US:X  a  U	nOX-   U	-   n[        U
[        5      (       a  Ub"  X4:  a  US:w  a  UR                  U	5      n
XU'   Mo  UR                  U	5      n
UR                  [        XX#S-   U5      5        M     UR                  U5        M     U(       a  US   $ U$ )a0  
A simplified json_normalize

Converts a nested dict into a flat dict ("record"), unlike json_normalize,
it does not attempt to extract a subset of the data.

Parameters
----------
ds : dict or list of dicts
prefix: the prefix, optional, default: ""
sep : str, default '.'
    Nested records will generate names separated by sep,
    e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
level: int, optional, default: 0
    The number of levels in the json string.

max_level: int, optional, default: None
    The max depth to normalize.

Returns
-------
d - dict or list of dicts, matching `ds`

Examples
--------
>>> nested_to_record(
...     dict(flat1=1, dict1=dict(c=1, d=2), nested=dict(e=dict(c=1, d=2), d=2))
... )
{'flat1': 1, 'dict1.c': 1, 'dict1.d': 2, 'nested.e.c': 1, 'nested.e.d': 2, 'nested.d': 2}
FTr   r   )

isinstancedictcopydeepcopyitemsstrpopupdater$   append)r   r    r!   r"   r#   	singletonnew_dsdnew_dkvnewkeys               r   r$   r$   F   s   X I"dT	Fa GGIDAa%%Fz) a&&%%*<A:		!A$%&M		!ALL)!S!)YOP- . 	e3 6 ayMr   c                    [        U [        5      (       aG  U R                  5        H1  u  pEU U U 3nU(       d  UR                  U5      n[	        UUUUS9  M3     U$ XU'   U$ )a  
Main recursive function
Designed for the most basic use case of pd.json_normalize(data)
intended as a performance improvement, see #15621

Parameters
----------
data : Any
    Type dependent on types contained within nested Json
key_string : str
    New key (with separator(s) in) for data
normalized_dict : dict
    The new normalized/flattened Json dict
separator : str, default '.'
    Nested records will generate names separated by sep,
    e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
data
key_stringnormalized_dict	separator)r'   r(   r+   removeprefix_normalize_json)r9   r:   r;   r<   keyvaluenew_keys          r   r>   r>      st    . $**,JC#YKu5G!..y9" /#	 '  '+
#r   c           
     (   U R                  5        VVs0 s H  u  p#[        U[        5      (       a  M  X#_M      nnn[        U R                  5        VVs0 s H  u  p#[        U[        5      (       d  M  X#_M      snnS0 US9n0 UEUE$ s  snnf s  snnf )aK  
Order the top level keys and then recursively go to depth

Parameters
----------
data : dict or list of dicts
separator : str, default '.'
    Nested records will generate names separated by sep,
    e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar

Returns
-------
dict or list of dicts, matching `normalized_json_object`
 r8   )r+   r'   r(   r>   )r9   r<   r4   r5   	top_dict_nested_dict_s         r   _normalize_json_orderedrF      s     #'**,J,$!jD6I,IJ"#zz|C|tqz!T/Bdad|C	L )i(<(( KCs   BBB
3B
c                    0 n[        U [        5      (       a  [        XS9nU$ [        U [        5      (       a  U  Vs/ s H  n[	        X1S9PM     nnU$ U$ s  snf )a1  
An optimized basic json_normalize

Converts a nested dict into a flat dict ("record"), unlike
json_normalize and nested_to_record it doesn't do anything clever.
But for the most basic use cases it enhances performance.
E.g. pd.json_normalize(data)

Parameters
----------
ds : dict or list of dicts
sep : str, default '.'
    Nested records will generate names separated by sep,
    e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar

Returns
-------
frame : DataFrame
d - dict or list of dicts, matching `normalized_json_object`

Examples
--------
>>> _simple_json_normalize(
...     {
...         "flat1": 1,
...         "dict1": {"c": 1, "d": 2},
...         "nested": {"e": {"c": 1, "d": 2}, "d": 2},
...     }
... )
{'flat1': 1, 'dict1.c': 1, 'dict1.d': 2, 'nested.e.c': 1, 'nested.e.d': 2, 'nested.d': 2}

)r9   r<   r!   )r'   r(   rF   list_simple_json_normalize)r   r!   normalized_json_objectrownormalized_json_lists        r   rJ   rJ      si    V  "d!8b!P "! 
B		PRSPR 6s DPRS##!!  Ts   Ac                r   U c  g[        U [        5      (       a  gU  H  n[        U[        5      (       aE  U H=  n[        U[        5      (       a  M  [        S[	        U5      R
                   SU< 35      e   M]  [        U[        5      (       a  Mt  [        S[	        U5      R
                   SU< 35      e   g)a  
Validate that meta parameter contains only strings or lists of strings.
Parameters
----------
meta : str or list of str or list of list of str or None
    The meta parameter to validate.
Raises
------
TypeError
    If meta contains elements that are not strings or lists of strings.
Nz9All elements in nested meta paths must be strings. Found z: zBAll elements in 'meta' must be strings or lists of strings. Found )r'   r,   rI   	TypeErrortype__name__)metaitemsubitems      r   _validate_metarU     s     |$dD!!!'3//#!!%g!7!7 87+G    D#&&d,,-Rx9  r   pandasc                N  ^^^^^^^^^^^^ [        U5         S       SU4S jjjmSU4S jjm[        U [        5      (       a  U R                  nOSn[        U [        5      (       a  U (       d
  [        5       $ [        U [        5      (       a  U /n O[        U [        R                  5      (       ab  [        U [        5      (       dM  [	        U 5      n U  H;  n	[        U	[        5      (       a  M  S[        U	5      R                   3n
[        U
5      e   O[        eUc  Uc  Uc  Tc  Tc  [        [        U TS9US9$ UcC  [        S U  5       5      (       a  [!        U TTS9n [        XS9nTb  UR#                  U4S	 jS
9nU$ [        U[        5      (       d  U/nUc  / nO[        U[        5      (       d  U/nU Vs/ s H  n[        U[        5      (       a  UOU/PM     snm/ m/ m[%        [        5      mT Vs/ s H  nTR'                  U5      PM     snmSSUUUUUUUUUU4
S jjjmT" X0 SS9  [        T5      nTb  UR#                  U4S jS
9nTR)                  5        H  u  pUb  X>-   nX;   a  [+        SU S35      e[,        R.                  " U[0        S9nUR2                  S:  a=  [,        R4                  " [7        U5      4[0        S9n[9        U5       H  u  nnUUU'   M     UR;                  T5      X'   M     Ub  UR;                  T5      Ul        U$ s  snf s  snf )a  
Normalize semi-structured JSON data into a flat table.

This method is designed to transform semi-structured JSON data, such as nested
dictionaries or lists, into a flat table. This is particularly useful when
handling JSON-like data structures that contain deeply nested fields.

Parameters
----------
data : dict, list of dicts, or Series of dicts
    Unserialized JSON objects.
record_path : str or list of str, default None
    Path in each object to list of records. If not passed, data will be
    assumed to be an array of records.
meta : list of paths (str or list of str), default None
    Fields to use as metadata for each record in resulting table.
meta_prefix : str, default None
    String to prefix records with dotted path, e.g. foo.bar.field if
    meta is ['foo', 'bar'].
record_prefix : str, default None
    String to prefix records with dotted path, e.g. foo.bar.field if
    path to records is ['foo', 'bar'].
errors : {'raise', 'ignore'}, default 'raise'
    Configures error handling.

    * 'ignore' : will ignore KeyError if keys listed in meta are not
      always present.
    * 'raise' : will raise KeyError if keys listed in meta are not
      always present.
sep : str, default '.'
    Nested records will generate names separated by sep.
    e.g., for sep='.', {'foo': {'bar': 0}} -> foo.bar.
max_level : int, default None
    Max number of levels(depth of dict) to normalize.
    if None, normalizes all levels.

Returns
-------
DataFrame
    The normalized data, represented as a pandas DataFrame.

See Also
--------
DataFrame : Two-dimensional, size-mutable, potentially heterogeneous tabular data.
Series : One-dimensional ndarray with axis labels (including time series).

Examples
--------
>>> data = [
...     {"id": 1, "name": {"first": "Coleen", "last": "Volk"}},
...     {"name": {"given": "Mark", "family": "Regner"}},
...     {"id": 2, "name": "Faye Raker"},
... ]
>>> pd.json_normalize(data)
    id name.first name.last name.given name.family        name
0  1.0     Coleen      Volk        NaN         NaN         NaN
1  NaN        NaN       NaN       Mark      Regner         NaN
2  2.0        NaN       NaN        NaN         NaN  Faye Raker

>>> data = [
...     {
...         "id": 1,
...         "name": "Cole Volk",
...         "fitness": {"height": 130, "weight": 60},
...     },
...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
...     {
...         "id": 2,
...         "name": "Faye Raker",
...         "fitness": {"height": 130, "weight": 60},
...     },
... ]
>>> pd.json_normalize(data, max_level=0)
    id        name                        fitness
0  1.0   Cole Volk  {'height': 130, 'weight': 60}
1  NaN    Mark Reg  {'height': 130, 'weight': 60}
2  2.0  Faye Raker  {'height': 130, 'weight': 60}

Normalizes nested data up to level 1.

>>> data = [
...     {
...         "id": 1,
...         "name": "Cole Volk",
...         "fitness": {"height": 130, "weight": 60},
...     },
...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
...     {
...         "id": 2,
...         "name": "Faye Raker",
...         "fitness": {"height": 130, "weight": 60},
...     },
... ]
>>> pd.json_normalize(data, max_level=1)
    id        name  fitness.height  fitness.weight
0  1.0   Cole Volk             130              60
1  NaN    Mark Reg             130              60
2  2.0  Faye Raker             130              60

>>> data = [
...     {
...         "id": 1,
...         "name": "Cole Volk",
...         "fitness": {"height": 130, "weight": 60},
...     },
...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
...     {
...         "id": 2,
...         "name": "Faye Raker",
...         "fitness": {"height": 130, "weight": 60},
...     },
... ]
>>> series = pd.Series(data, index=pd.Index(["a", "b", "c"]))
>>> pd.json_normalize(series)
    id        name  fitness.height  fitness.weight
a  1.0   Cole Volk             130              60
b  NaN    Mark Reg             130              60
c  2.0  Faye Raker             130              60

>>> data = [
...     {
...         "state": "Florida",
...         "shortname": "FL",
...         "info": {"governor": "Rick Scott"},
...         "counties": [
...             {"name": "Dade", "population": 12345},
...             {"name": "Broward", "population": 40000},
...             {"name": "Palm Beach", "population": 60000},
...         ],
...     },
...     {
...         "state": "Ohio",
...         "shortname": "OH",
...         "info": {"governor": "John Kasich"},
...         "counties": [
...             {"name": "Summit", "population": 1234},
...             {"name": "Cuyahoga", "population": 1337},
...         ],
...     },
... ]
>>> result = pd.json_normalize(
...     data, "counties", ["state", "shortname", ["info", "governor"]]
... )
>>> result
         name  population    state shortname info.governor
0        Dade       12345   Florida    FL    Rick Scott
1     Broward       40000   Florida    FL    Rick Scott
2  Palm Beach       60000   Florida    FL    Rick Scott
3      Summit        1234   Ohio       OH    John Kasich
4    Cuyahoga        1337   Ohio       OH    John Kasich

>>> data = {"A": [1, 2]}
>>> pd.json_normalize(data, "A", record_prefix="Prefix.")
    Prefix.0
0          1
1          2

Returns normalized data with columns prefixed with the given string.
c                *  > U n [        U[        5      (       a  U H  nUc  [        U5      eX4   nM     U$ X1   n U$ ! [         aJ  nU(       a  [        SU S35      UeTS:X  a  [        R                  s SnA$ [        SU SU S35      UeSnAff = f)zInternal function to pull fieldNzKey zS not found. If specifying a record_path, all elements of data should have the path.ignorez) not found. To replace missing values of z% with np.nan, pass in errors='ignore')r'   rI   KeyErrornpnan)jsspecextract_recordresultfieldeerrorss         r   _pull_field#json_normalize.<locals>._pull_field  s     	$%%!E~&uo-#]F "(      	1# 1 2  !vv1#Fqc J6 7 	s%   0> > 
B,B4B:BBc                   > T" XSS9n[        U[        5      (       dD  [        R                  " U5      (       a  / nU$ [	        S[        U5      R                   SU< 35      eU$ )z
Internal function to pull field for records, and similar to
_pull_field, but require to return list. And will raise error
if has non iterable value.
T)r_   z(Path must contain list or null, but got z at )r'   rI   pdisnullrO   rP   rQ   )r]   r^   r`   rd   s      r   _pull_records%json_normalize.<locals>._pull_records  sr     Rd; &$''yy   	  #F|445T$C  r   Nz.All items in data must be of type dict, found rH   )indexc              3     #    U  H3  oR                  5        Vs/ s H  n[        U[        5      PM     snv   M5     g s  snf 7fr   )valuesr'   r(   ).0yxs      r   	<genexpr>!json_normalize.<locals>.<genexpr>/  s-     G$QXXZ8Z
1d#Z8$8s   A=Ar!   r#   c                   > T U  3$ r   r   rp   record_prefixs    r   <lambda> json_normalize.<locals>.<lambda>:  s    qc5Jr   )columnsr   c           
     x  >
 [        U [        5      (       a  U /n [        U5      S:  aR  U  HK  n[        T
TSS9 H&  u  pVUS-   [        U5      :X  d  M  T" XES   5      X&'   M(     T" XAS      USS  X#S-   S9  MM     g U  H  nT" XAS   5      nU Vs/ s H%  n[        U[        5      (       a  [	        UTTS9OUPM'     nnTR                  [        U5      5        [        T
TSS9 H;  u  pVUS-   [        U5      :  a  X&   n	OT" XEUS  5      n	TU   R                  U	5        M=     TR                  U5        M     g s  snf )Nr   T)strictr   r   r"   rs   )r'   r(   lenzipr$   r/   extend)r9   path	seen_metar"   objvalr?   recsrmeta_val_metard   ri   _recursive_extractlengthsr#   	meta_keys	meta_valsrecordsr!   s             r   r   *json_normalize.<locals>._recursive_extractM  sU   dD!!6Dt9q= #E9T BHCqyCH,)4Sb')B	 !C #3Aw<ab9TUIV  $Sq'2
 "	 " "!T** %QC9E "	   s4y) #E9T BHCqy3s8+#,>#.sK#@cN))(3 !C t$# s   ,D7r|   c                   > T U  3$ r   r   ru   s    r   rw   rx   p  s    M?1#1Fr   zConflicting metadata name z, need distinguishing prefix )dtyper   )F)r]   dict[str, Any]r^   
list | strr_   boolreturnzScalar | Iterable)r]   r   r^   r   r   rI   )r   )r"   intr   None)rU   r'   r   rk   rI   r   r(   r   r   r,   rP   rQ   rO   NotImplementedErrorrJ   anyr$   renamer   joinr+   
ValueErrorr[   arrayobjectndimemptyr}   	enumeraterepeat)r9   record_pathrR   meta_prefixrv   rc   r!   r#   rk   rS   msgr`   mr   r4   r5   rm   ir   rd   ri   r   r   r   r   r   s       ````          @@@@@@@@r   json_normalizer   -  s   T 4 FK",>B	 :( $

$d{	D$		v	D#,,	'	'
40E0E DzDdD))!$Z0013   n$  "! 	L!/#>eLLG$GGG $DcYGD4-$]]+J]KFT**"m|d##v8<=1*Q%%QA3.=E GG(.I*/0%3#%0I% % %< t"A6wF 'FG !"A;,QC/LM 
 !6*;;?XXs1viv6F#A,3q	 ' MM'*	% "& ||G,MI > 1s   =$L;L")r   r,   r   r,   )....)r   r(   r    r,   r!   r,   r"   r   r#   
int | Noner   r   )r   z
list[dict]r    r,   r!   r,   r"   r   r#   r   r   zlist[dict[str, Any]])rC   .r   N)r   dict | list[dict]r    r,   r!   r,   r"   r   r#   r   r   z%dict[str, Any] | list[dict[str, Any]])
r9   r   r:   r,   r;   r   r<   r,   r   r   )r9   r   r<   r,   r   r   )r   )r   r   r!   r,   r   zdict | list[dict] | Any)rR   "str | list[str | list[str]] | Noner   r   )NNNNraiser   N)r9   zdict | list[dict] | Seriesr   zstr | list | NonerR   r   r   
str | Nonerv   r   rc   r   r!   r,   r#   r   r   r   )!
__future__r   collectionsr   r   r)   typingr   r   r   r	   numpyr[   pandas._libs.writersr   pandas.util._decoratorsr   rV   rg   r   r   collections.abcr   pandas._typingr   r   r   r$   r>   rF   rJ   rU   r   r   r   r   <module>r      s>   #    6 . 
 (
$ 
  
 	
   
 
  
 	
   
  NNN 
N 	N
 N +Nb&
&& $& 	&
 &R)6 2"2"	2" 2"j> H &*/3" $! Z
$Z"Z -Z 	Z
 Z Z 
Z Z Z Zr   