
    HR-eg                        d Z ddlZddlZddlmZ ddlmZ ddlZ	ddlm
Z
 ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z  g d	Z! ej"        d
          Z# ej"        d          Z$	 dZ%dZ&dZ'eZ(eZ)ej*        dk    rd Z+nd Z+d Z,d Z-d Z. G d d          Z/ G d de/          Z0 G d de/          Z1 G d de/          Z2 G d de2          Z3 G d d e3          Z4 G d! d"e3          Z5 G d# d$e2          Z6 G d% d&e/          Z7 G d' d(e7          Z8 G d) d*e8          Z9 G d+ d,e8          Z: G d- d.e7          Z; G d/ d0e;          Z< G d1 d2e;          Z= G d3 d4e;          Z> G d5 d6e;          Z? G d7 d8e3          Z@ G d9 d:e3          ZA G d; d<e6          ZB G d= d>e8e2          ZC G d? d@eC          ZD G dA dBeC          ZE G dC dDe6          ZF G dE dFe/          ZG G dG dHe6          ZH G dI dJe/          ZIe9e:eGeIe<e=e>e?eDeEe0e1dKZJd[dLZK e	jL                    jM        jN        dM e	jO                    jM        jN        dN e	jP                    jM        jN        dO e	jQ                    jM        jN        dP e	jR                    jM        jN        dQ e	jS                    jM        jN        dR e	jT                    jM        jN        dS e	jU                    jM        jN        dT e	jV                    jM        jN        dU e	jW                    jM        jN        dVi
ZXdWeX e	jY                    jM        jN        <   dX ZZdY Z[dZ Z\dS )\zi
This module handles the conversion of various VOTABLE datatypes
to/from TABLEDATA_ and BINARY_ formats.
    N)pack)unpack)ma)xml_escape_cdata   )E01E02E03E04E05E06E24W01W30W31W39W46W47W49W51W55vo_raisevo_warnwarn_or_raise)get_converter	Converter table_column_to_votable_datatypez +z\s+|(?:\s*,\s*)s               littlec                 N    | j         j        dk    r|                                 S | S )N>dtype	byteorderbyteswapxs    =lib/python3.11/site-packages/astropy/io/votable/converters.py_ensure_bigendianr*   C   %    7##::<<r   c                 N    | j         j        dk    r|                                 S | S )N<r#   r'   s    r)   r*   r*   J   r+   r   c                     t          |           r<t          j        t          j        |           t          j        |d                    S t          j        t          j        |                     S )z
    Masked arrays of zero length that also have a mask of zero length
    cause problems in Numpy (at least in 1.6.2).  This function
    creates a masked array from data and a mask, unless it is zero
    length.
    boolr$   )mask)lenr   arraynp)datar1   s     r)   _make_masked_arrayr6   P   sV     4yy (xRXd&-I-I-IJJJJx'''r   c                     g }| D ]c}t          ddd          D ]:}|d|z  z  }|dk    }|                    |           t          |          |k    r n;t          |          |k    r ndt          j        |d          S )a  
    Converts a bit array (a string of bits in a bytes object) to a
    boolean Numpy array.

    Parameters
    ----------
    data : bytes
        The bit array.  The most significant byte is read first.

    length : int
        The number of bits to read.  The least significant bits in the
        data bytes beyond length will be ignored.

    Returns
    -------
    array : numpy bool array
       r   r   b1r0   )rangeappendr2   r4   r3   )r5   lengthresultsbytebit_nobits         r)   bitarray_to_boolrB   ^   s    $ G  Ar2&& 	 	F!v+&C(CNN37||v%% &w<<6!!E " 8G4((((r   c                     | j         } d}d}g }| D ]1}|r|d|z  z  }|dk    r|                    |           d}d},|dz  }2|dk    r|                    |           t          t          |           dg|R  S )a  
    Converts a numpy boolean array to a bit array (a string of bits in
    a bytes object).

    Parameters
    ----------
    value : numpy bool array

    Returns
    -------
    bit_array : bytes
        The first value in the input array will be the most
        significant bit in the result.  The length will be `floor((N +
        7) / 8)` where `N` is the length of `value`.
    r8   r   r   B)flatr<   struct_packr2   )valuer@   r?   bytesvs        r)   bool_to_bitarrayrJ   ~   s      JEFDE   	 AKDQ;;LLFDDaKFF{{T#e**'''0%0000r   c                   n    e Zd ZdZddZed             Zed             Zd ZddZ	ddZ
d	 Zd
 Zd ZdS )r   a  
    The base class for all converters.  Each subclass handles
    converting a specific VOTABLE data type to/from the TABLEDATA_ and
    BINARY_ on-disk representations.

    Parameters
    ----------
    field : `~astropy.io.votable.tree.Field`
        object describing the datatype

    config : dict
        The parser configuration dictionary

    pos : tuple
        The position in the XML file where the FIELD object was
        found.  Used for error messages.

    Nc                     d S N selffieldconfigposs       r)   __init__zConverter.__init__   s    r   c                 @    t          d | d                    d         S )N>I   r   )struct_unpack)reads    r)   _parse_lengthzConverter._parse_length   s    T4477++A..r   c                 <    t          dt          |                     S )NrV   )rF   int)r=   s    r)   _write_lengthzConverter._write_length   s    4V---r   c                 ,    |                     d          S )zF
        Returns True when the field can be completely empty.
        version_1_3_or_later)getrP   rR   s     r)   supports_empty_valueszConverter.supports_empty_values   s     zz0111r   c                      t          d          )a  
        Convert the string *value* from the TABLEDATA_ format into an
        object with the correct native in-memory datatype and mask flag.

        Parameters
        ----------
        value : str
            value in TABLEDATA format

        Returns
        -------
        native : tuple
            A two-element tuple of: value, mask.
            The value as a Numpy array or scalar, and *mask* is True
            if the value is missing.
        z.This datatype must implement a 'parse' method.NotImplementedErrorrP   rG   rR   rS   s       r)   parsezConverter.parse   s    " ""RSSSr   c                 0    |                      |||          S )a  
        Parse a single scalar of the underlying type of the converter.
        For non-array converters, this is equivalent to parse.  For
        array converters, this is used to parse a single
        element of the array.

        Parameters
        ----------
        value : str
            value in TABLEDATA format

        Returns
        -------
        native : (2,) tuple
            (value, mask)
            The value as a Numpy array or scalar, and *mask* is True
            if the value is missing.
        )rg   rf   s       r)   parse_scalarzConverter.parse_scalar   s    & zz%---r   c                      t          d          )a  
        Convert the object *value* (in the native in-memory datatype)
        to a unicode string suitable for serializing in the TABLEDATA_
        format.

        Parameters
        ----------
        value
            The value, the native type corresponding to this converter

        mask : bool
            If `True`, will return the string representation of a
            masked value.

        Returns
        -------
        tabledata_repr : unicode
        z/This datatype must implement a 'output' method.rd   rP   rG   r1   s      r)   outputzConverter.output   s    & ""STTTr   c                      t          d          )a3  
        Reads some number of bytes from the BINARY_ format
        representation by calling the function *read*, and returns the
        native in-memory object representation for the datatype
        handled by *self*.

        Parameters
        ----------
        read : function
            A function that given a number of bytes, returns a byte
            string.

        Returns
        -------
        native : (2,) tuple
            (value, mask). The value as a Numpy array or scalar, and *mask* is
            True if the value is missing.
        z1This datatype must implement a 'binparse' method.rd   )rP   rY   s     r)   binparsezConverter.binparse  s    & ""UVVVr   c                      t          d          )a:  
        Convert the object *value* in the native in-memory datatype to
        a string of bytes suitable for serialization in the BINARY_
        format.

        Parameters
        ----------
        value
            The value, the native type corresponding to this converter

        mask : bool
            If `True`, will return the string representation of a
            masked value.

        Returns
        -------
        bytes : bytes
            The binary representation of the value, suitable for
            serialization in the BINARY_ format.
        z2This datatype must implement a 'binoutput' method.rd   rk   s      r)   	binoutputzConverter.binoutput  s    * ""VWWWr   NN)__name__
__module____qualname____doc__rT   staticmethodrZ   r]   rb   rg   ri   rl   rn   rp   rN   r   r)   r   r      s         &    / / \/ . . \.2 2 2T T T T&. . . .*U U U*W W W*X X X X Xr   r   c                   J    e Zd ZdZeZddZd ZddZd Z	d Z
d Zd	 Zd
 ZdS )Charz
    Handles the char datatype. (7-bit unsigned characters).

    Missing values are not handled for string or unicode types.
    Nc                 z   |i }t                               | |||           |j        | _        |j        t          t          d||           d|_        |j        dk    r(d| _        | j        | _	        | j
        | _        d| _        d S |j                            d          r|j        d d         |_        	 t          |j                  | _        n3# t          $ r& t          t           |j        d|j        f|           Y nw xY wd| j        d| _        | j        | _	        | j        | _        d	| j        dd
| _        d S )NrN   1*Or9   charUdr"   s)r   rT   name
field_name	arraysizer   r   format_binparse_varrn   _binoutput_varrp   endswithr\   
ValueErrorr   r   ID_binparse_fixed_binoutput_fixed_struct_formatrO   s       r)   rT   zChar.__init__9  sP   >F4444*?"CVS)))!EO?c!!DK .DM!0DN DNNN'',, 7"'/#2#"6K!$U_!5!5 K K KuA6JJJJJK0dn000DK 0DM!2DN"9dn"9"9"9"9Ds   5C -C?>C?c                     dS NTrN   ra   s     r)   rb   zChar.supports_empty_valuesV      tr   c                    | j         dk    r6t          |          | j         k    rt          t          d| j         f||           	 |                    d           n.# t
          $ r! t          t          | j        |f||           Y nw xY w|dfS )Nr{   r}   asciiF)r   r2   r   r   encodeUnicodeEncodeErrorr   r   rf   s       r)   rg   z
Char.parseY  s    >S  SZZ$.%@%@C&$.163???	@LL!!!!! 	@ 	@ 	@C$/5163?????	@e|s   A (BBc                    |rdS 	 t          |t                    r|                    d           n|                    d          }n9# t          t
          f$ r% t          t          t
          || j        f           Y nw xY wt          |t                    r|                    d          }n/# t          |t                    r|                    d          }w xY wt          |          S )N r   zutf-8)
isinstancestrr   decoder   r   r   r   r   rH   r   rk   s      r)   rl   zChar.outputd  s     	2
	.%%% .W%%%% W--./ 	M 	M 	M#1E4?3KLLLLL	M %'' .W-- %'' .W------&&&s*   A A B+ 3A=:B+ <A==B+ +,Cc                 l    |                      |          } ||                              d          dfS )Nr   FrZ   r   rP   rY   r=   s      r)   r   zChar._binparse_varz  s6    ##D))tF||""7++U22r   c                     t          | j         || j                            d         }|                    t                    }|                    d          }|dk    r|d |         dfS |dfS )Nr   r   r9   F)rX   r   r   find
_zero_byter   rP   rY   r   ends       r)   r   zChar._binparse_fixed~  sk    $-ttDN/C/CDDQGffZ  HHW"99TcT7E>!%xr   c                    |s||dk    rt           S t          |t                    rC	 |                    d          }n,# t          $ r t          t          || j        f           Y nw xY w|                     t          |                    |z   S )Nr   r   )
	_zero_intr   r   r   r   r   r   r   r]   r2   rk   s      r)   r   zChar._binoutput_var  s     	5=ERKKeS!! 	88W-- 8 8 8udo6777778!!#e**--55s   > &A'&A'c                     |rt           }nXt          |t                    rC	 |                    d          }n,# t          $ r t          t          || j        f           Y nw xY wt          | j	        |          S )Nr   )
_empty_bytesr   r   r   r   r   r   r   rF   r   rk   s      r)   r   zChar._binoutput_fixed  s     	8 EEs## 	88W-- 8 8 8udo67777784.666s   7 &A A rq   )rr   rs   rt   ru   r   defaultrT   rb   rg   rl   r   r   r   r   rN   r   r)   rx   rx   0  s          G: : : ::  	 	 	 	' ' ',3 3 3  6 6 67 7 7 7 7r   rx   c                   D    e Zd ZdZdZddZddZd Zd Zd Z	d	 Z
d
 ZdS )UnicodeCharzx
    Handles the unicodeChar data type. UTF-16-BE.

    Missing values are not handled for string or unicode types.
    r   Nc                    t                               | |||           |j        t          t          d||           d|_        |j        dk    r(d| _        | j        | _        | j        | _	        d| _        d S 	 t          |j                  | _        n3# t          $ r& t          t          |j        d|j        f|           Y nw xY wd| j        d| _        | j        | _        | j        | _	        d| j        d	z  dd
| _        d S )NrN   rz   r{   r|   unicoder~   r   r"      r   )r   rT   r   r   r   r   r   rn   r   rp   r\   r   r   r   r   r   r   r   rO   s       r)   rT   zUnicodeChar.__init__  s   4444?"CVS)))!EO?c!!DK .DM!0DN DNNNN!$U_!5!5 N N Nu	58DfMMMMMN0dn000DK 0DM!2DN";dnQ&6";";";";Ds   7B -C Cc                     | j         dk    r6t          |          | j         k    rt          t          d| j         f||           |dfS )Nr{   unicodeCharF)r   r2   r   r   rf   s       r)   rg   zUnicodeChar.parse  sF    >S  SZZ$.%@%@C-8&#FFFe|r   c                 B    |rdS t          t          |                    S Nr   )r   r   rk   s      r)   rl   zUnicodeChar.output  s#     	2E

+++r   c                 r    |                      |          } ||dz                                d          dfS )Nr   	utf_16_beFr   r   s      r)   r   zUnicodeChar._binparse_var  s<    ##D))tFQJ&&{33U::r   c                     t          | j         || j        dz                      d         }|                    d          }|                    d          }|dk    r|d |         dfS |dfS )Nr   r   r    r9   F)rX   r   r   r   r   r   s       r)   r   zUnicodeChar._binparse_fixed  sn    $-ttDNQ4F/G/GHHKHH[!!ffTll"99TcT7E>!%xr   c                     |s||dk    rt           S |                    d          }|                     t          |          dz            |z   S )Nr   r   r   )r   r   r]   r2   )rP   rG   r1   encodeds       r)   r   zUnicodeChar._binoutput_var  sQ     	5=ERKK,,{++!!#g,,"233g==r   c                 Z    |rd}t          | j        |                    d                    S )Nr   r   )rF   r   r   rk   s      r)   r   zUnicodeChar._binoutput_fixed  s.     	E4.[0I0IJJJr   rq   )rr   rs   rt   ru   r   rT   rg   rl   r   r   r   r   rN   r   r)   r   r     s          G< < < <,   
, , ,
; ; ;  > > >K K K K Kr   r   c                   R    e Zd ZdZddZd	dZedd            Zedd            ZdS )
Arrayz9
    Handles both fixed and variable-lengths arrays.
    Nc                     |i }t                               | |||           |                    dd          dk    r| j        | _        d S | j        | _        d S )Nverifyignore	exception)r   rT   r`   _splitter_pedantic	_splitter_splitter_laxrO   s       r)   rT   zArray.__init__  s[    >F4444::h))[88!4DNNN!/DNNNr   r   c                 :    | j                             |||          S rM   )_baseri   rf   s       r)   ri   zArray.parse_scalar  s    z&&ufc:::r   c                 6    t                               |           S rM   )pedantic_array_splittersplitrG   rR   rS   s      r)   r   zArray._splitter_pedantic  s    &,,U333r   c                 l    d| v rt          t          d||           t                              |           S )N,rN   )r   r   array_splitterr   r   s      r)   r   zArray._splitter_lax  s3    %<<CVS)))##E***r   rq   Nr   )	rr   rs   rt   ru   rT   ri   rv   r   r   rN   r   r)   r   r     s         0 0 0 0; ; ; ; 4 4 4 \4 + + + \+ + +r   r   c                   0    e Zd ZdZdZddZd Zd Zd ZdS )	VarArrayzJ
    Handles variable lengths arrays (i.e. where *arraysize* is '*').
    r|   Nc                     t                               | ||           || _        t          j        g | j        j                  | _        d S )Nr0   )r   rT   r   r4   r3   r   r   rP   rQ   baser   rR   rS   s         r)   rT   zVarArray.__init__  s>    tUF+++
x$**;<<<r   c                     | j         j        fdt          j        ||          D             }d                    |          S )Nc                 .    g | ]\  }} ||          S rN   rN   ).0r(   mrl   s      r)   
<listcomp>z#VarArray.output.<locals>.<listcomp>  s'    EEE41a&&A,,EEEr    )r   rl   r4   	broadcastjoin)rP   rG   r1   resultrl   s       @r)   rl   zVarArray.output  sD    "EEEE2<t+D+DEEExxr   c                    |                      |          }g }g }| j        j        }t          |          D ]:} ||          \  }}|                    |           |                    |           ;t          ||          dfS )NF)rZ   r   rn   r;   r<   r6   )	rP   rY   r=   r   result_maskrn   ivalr1   s	            r)   rn   zVarArray.binparse
  s    ##D)):&v 	% 	%A ICMM#t$$$$!&+66==r   c                 D   |t          |          dk    rt          S t          |          }|                     |          g}| j        j        }t          ||j                  D ]$\  }}|                     |||                     %t          	                    |          S r   )
r2   r   r]   r   rp   zipr1   r<   r   r   )rP   rG   r1   r=   r   rp   r(   r   s           r)   rp   zVarArray.binoutput  s    =CJJ!OOU$$V,,-J(	uz** 	+ 	+DAqMM))Aq//****  (((r   rq   )	rr   rs   rt   ru   r   rT   rl   rn   rp   rN   r   r)   r   r     sf          F= = = =     
> > >	) 	) 	) 	) 	)r   r   c                       e Zd ZdZddZdS )ArrayVarArrayz]
    Handles an array of variable-length arrays, i.e. where *arraysize*
    ends in '*'.
    Nc                 ,   |                                 dk    rt          j        g           dfS |                     |||          }| j        j        }| j        j        }t          |          |z  dk    r&t          t          |t          |          f||           g }g }t          dt          |          |          D ]G}	 |||	|	|z            ||          \  }}
|                    |           |                    |
           Ht          ||          dfS )Nr   Fr   stripr   r3   r   r   _itemsparse_partsr2   r   r	   r;   r<   r6   rP   rG   rR   rS   partsitemsr   r   r   r   r1   s              r)   rg   zArrayVarArray.parse)  s   ;;==B8B<<&&ufc22
!j,u::""S5#e**-vs;;;q#e**e,, 	% 	%A%+eAE	M&:FCHHKE4MM%   t$$$$!&+66==r   rq   rr   rs   rt   ru   rg   rN   r   r)   r   r   #  s2         
> > > > > >r   r   c                       e Zd ZdZddZdS )ScalarVarArrayz=
    Handles a variable-length array of numeric scalars.
    Nc                 N   |                                 dk    rt          j        g           dfS |                     |||          }| j        j        }g }g }|D ]<} ||||          \  }}	|                    |           |                    |	           =t          ||          dfS )Nr   F)r   r   r3   r   r   rg   r<   r6   )
rP   rG   rR   rS   r   rg   r   r   r(   r1   s
             r)   rg   zScalarVarArray.parseA  s    ;;==B8B<<&&ufc22
  	% 	%A%63//KE4MM%   t$$$$!&+66==r   rq   r   rN   r   r)   r   r   <  s2         > > > > > >r   r   c                   @    e Zd ZdZeZd	dZd	dZd	dZd Z	d Z
d ZdS )
NumericArrayz:
    Handles a fixed-length array of numeric scalars.
    Nc                    t                               | |||           || _        || _        t	          |           |j         | _        d| _        |D ]}| xj        |z  c_        t          j        | j                  j	        | _
        d| j        z   | _        t          j        || j        j                  | _        | j        j        | j        d<   d S )Nr   r"   r0   .)r   rT   r   
_arraysizetupler   r   r4   r$   itemsize_memsize_bigendian_formatemptyr   )rP   rQ   r   r   rR   rS   dims          r)   rT   zNumericArray.__init__Y  s    tUFC000
#y))84;88 	 	CKK3KKK--6!$t{!2x	1BCCC J.Sr   c                    |i }n5|d         r-|dk    r't          j        | j        | j        j                  dfS |                     |||          }t          |          | j        k    r1t          t          t          | j        t          |          f||           |
                    dd          dk    r|                     |||          S t          |          | j        k    rnPt          |          | j        k    r|d | j                 }n(|| j        j        g| j        t          |          z
  z  z   }|                     |||          S )Nr_   r   r0   Tr   r   r   )r4   zerosr   r   r   r   r2   r   r   r	   r`   r   r   rP   rG   rR   rS   r   s        r)   rg   zNumericArray.parsej  s9   >FF*+ 	L8DO4:3DEEEtKKufc22u::$$#sT[#e**$=vsKKK::h))[88##E637775zzT[((Udk))mm,$*"4!5s5zz9Q!RS##E63777r   c                 t   | j         j        }g }g }|D ]<} ||||          \  }}	|                    |           |                    |	           =t          j        || j         j                                      | j                  }t          j        |d                              | j                  }||fS )Nr0   r/   )r   rg   r<   r4   r3   r   reshaper   )
rP   r   rR   rS   
base_parser   r   r(   rG   r1   s
             r)   r   zNumericArray.parse_parts}  s    Z%
 	% 	%A$*Q44KE4MM%   t$$$$&
(9:::BB4?SSh{&999AA$/RR{""r   c                    | j         j        t          j        |          }t          j        |          }|j        dk    rt          j        }nt          }d                    fd ||j        |j                  D                       S )Nr   r   c              3   6   K   | ]\  }} ||          V  d S rM   rN   )r   r(   r   base_outputs      r)   	<genexpr>z&NumericArray.output.<locals>.<genexpr>  s3      RRdaAq))RRRRRRr   )	r   rl   r4   asarraysizer   r   r   rE   )rP   rG   r1   funcr   s       @r)   rl   zNumericArray.output  s{    j'
5!!z$9>><DDDxxRRRRdd5:ty6Q6QRRRRRRr   c                     t          j         || j                  | j                  d         }| j                            |          }||fS Nr0   r   )r4   
frombufferr   r   r   is_null)rP   rY   r   r   s       r)   rn   zNumericArray.binparse  sK    ttDM22$:PQQQRSTj((00{""r   c                 ~    | j                             ||          }t          |          }|                                S rM   )r   filter_arrayr*   tobytes)rP   rG   r1   filtereds       r)   rp   zNumericArray.binoutput  s8    :**5$77$X..!!!r   rq   )rr   rs   rt   ru   r   vararray_typerT   rg   r   rl   rn   rp   rN   r   r)   r   r   R  s          "M/ / / /"8 8 8 8&
# 
# 
# 
#S S S# # #
" " " " "r   r   c                   2    e Zd ZdZeZeZdZddZ	d Z
d ZdS )Numericz4
    The base class for all numeric data types.
    Nc                 f   t                               | |||           t          j        | j                  j        | _        d| j        z   | _        |j        j	        Dt          j
        |j        j	        | j                  | _	        | j	        | _        | j        | _        d S t          j        | _        d S )Nr"   r0   )r   rT   r4   r$   r   r   r   r   valuesnullr   r   _is_nullr  isnanrO   s       r)   rT   zNumeric.__init__  s    4444--6!$t{!2<(
5<#4DKHHHDI9DL=DLLL8DLLLr   c                     t          j         || j                  | j                  }|d         |                     |d                   fS r  )r4   r  r   r   r  )rP   rY   r   s      r)   rn   zNumeric.binparse  sD    ttDM22$:PQQQay$,,vay1111r   c                     || j         k    S rM   )r  rP   rG   s     r)   r  zNumeric._is_null  s    	!!r   rq   )rr   rs   rt   ru   r   
array_typer   r
  r  rT   rn   r  rN   r   r)   r  r    sa          J"MD
$ 
$ 
$ 
$2 2 2" " " " "r   r  c                   l    e Zd ZdZej        ZddZd ZddZ	ddZ
ed             Zd Zd	 Zd
 Zd ZdS )FloatingPointz6
    The base class for floating-point datatypes.
    Nc                    |i }t                               | |||           |j        }|j        }|dg}ndg}|"|                    t          |                     ||                    d          r0|                    dt          |dd                    dd           nl|                    d          r0|                    dt          |dd                    dd	           n'|                    dt          |          dd	           |                    d
           d                    |          | _	        t          j        t          j        | j                  | _        | j        4d| _        |                     | j        d          | _        | j        | _        np|                     t          j        | j                  d          | _        |                     t          j        | j                  d          | _        | j        | _        |                    dd          dk    r| j        | _        d S | j        | _        d S )Nz{!r:>z{:E.r   r   gFf}r   NaNFr   r   r   )r  rT   	precisionwidthr<   r   
startswithr\   r   _output_formatr4   r3   nanr   r  _null_outputrp   _null_binoutput_filter_nanr  rl   r   _filter_nullr`   _parse_pedanticrg   _parse_permissive)rP   rQ   rR   rS   r   r!  format_partss          r)   rT   zFloatingPoint.__init__  s*   >Fufc222O	#9LL 6LE

+++ ##C(( =##$?IabbM(:(:$?$?$?$?@@@@%%c** =##$?IabbM(:(:$?$?$?$?@@@@##$;I$;$;$;$;<<<C    ggl338BFDK009 %D#'>>$(E#B#BD  $ 0D $BJty,A,A5 I ID#'>>"*TY2G2G#O#OD  $ 1D::h))[88-DJJJ/DJJJr   c                     dS r   rN   ra   s     r)   rb   z#FloatingPoint.supports_empty_values  r   r   c                     |                                 dk    r	| j        dfS t          |          }||                     |          fS Nr   T)r   r  floatr  rP   rG   rR   rS   r  s        r)   r)  zFloatingPoint._parse_pedantic  sA    ;;==B9d?"%LL$,,q//!!r   c                     	 t          |          }||                     |          fS # t          $ r; |                                dk    rt	          t
          |||           | j        dfcY S w xY wr.  )r/  r  r   r   r   r   r  r0  s        r)   r*  zFloatingPoint._parse_permissive  s}    	#eAdll1oo%% 	# 	# 	# {{}}""UFC0009d?"""	#s   %( AA-,A-c                     | j         S rM   )r#  )rP   s    r)   output_formatzFloatingPoint.output_format  s    ""r   c                 $   |r| j         S t          j        |          rt          j        |          s|j                            |          }| j                            |          }|                    d          rt                      | j        d         dk    r|
                    d          r
|d d         }|S t          j        |          rdS t          j        |          rdS t          j        |          rdS t          d	| d
           d S )Nr3   r   r.0r  z+InFz-InFzInvalid floating point value '')r%  r4   isfiniteisscalarr$   typer#  r   r"  RuntimeErrorr   r  isposinfisneginfr   )rP   rG   r1   r   s       r)   rl   zFloatingPoint.output  s    	%$$;u 	;u%% 0((//(//66F  )) %"nn$"1%,,1F1F,MXe__ 	5[ 	6[ 	6:%:::;;;;;r   c                 Z    |r| j         S t          |          }|                                S rM   )r&  r*   r  rk   s      r)   rp   zFloatingPoint.binoutput  s.     	(''!%((}}r   c                 B    t          j        |t           j        |          S rM   )r4   wherer$  rk   s      r)   r'  zFloatingPoint._filter_nan#  s    xbfe,,,r   c                 8    t          j        || j        |          S rM   )r4   rA  r  rk   s      r)   r(  zFloatingPoint._filter_null&  s    xdi///r   rq   )rr   rs   rt   ru   r4   r$  r   rT   rb   r)  r*  propertyr3  rl   rp   r'  r(  rN   r   r)   r  r    s          fG+0 +0 +0 +0Z  " " " "	# 	# 	# 	# # # X#< < <*  - - -0 0 0 0 0r   r  c                       e Zd ZdZdZdS )DoublezQ
    Handles the double datatype.  Double-precision IEEE
    floating-point.
    f8Nrr   rs   rt   ru   r   rN   r   r)   rE  rE  *           
 FFFr   rE  c                       e Zd ZdZdZdS )FloatzL
    Handles the float datatype.  Single-precision IEEE floating-point.
    f4NrG  rN   r   r)   rJ  rJ  3  s          FFFr   rJ  c                   8    e Zd ZdZdZd	dZd	dZd Zd Zd Z	dS )
Integerz8
    The base class for all the integral datatypes.
    r   Nc                 @    t                               | |||           d S rM   )r  rT   rO   s       r)   rT   zInteger.__init__B  s"    ufc22222r   c                 8   |i }d}t          |t                    r|                                }|dk    r?|d         rd}nt          t          t          d||           | j        | j        }n| j        }n|dk    r6d}| j        %t          t          t          d||           | j        }nV| j        }nN|                    d          rt          |dd          d	          }n t          |d
          }nt          |          }| j        || j        k    rd}|| j
        d         k     r2t          t          t          || j        f||           | j
        d         }nB|| j
        d         k    r1t          t          t          || j        f||           | j
        d         }||fS )NFr   r_   TrN   r$  0xr      
   r   r   )r   r   lowerr   r   r  r   r   r"  r\   	val_ranger   bit_size)rP   rG   rR   rS   r1   s        r)   rg   zInteger.parseE  s   >FeS!! 	KKMME{{01 =DD!#sB<<<9( IEE LEE%9$!#sB<<< LEE IEE!!$'' 'E!""Ir**E2JJE9 Udi%7%7D4>!$$$#sUDM$:FCHHHN1%EET^A&&&#sUDM$:FCHHHN1%Ed{r   c                     |r7| j         t          t          t                     dS t          | j                   S t          |          S )Nr  )r  r   r   r   rk   s      r)   rl   zInteger.outputm  sA     	"y c3'''uty>>!5zzr   c                     |r#| j         t          t                     n| j         }t          |          }|                                S rM   )r  r   r   r*   r  rk   s      r)   rp   zInteger.binoutputu  sA     	"y 	!%((}}r   c                     t          j        |          r6| j        t          j        || j        |          S t	          t
                     |S rM   )r4   anyr  rA  r   r   rk   s      r)   r  zInteger.filter_array  s@    6$<< 	y$xdi777r   rq   )
rr   rs   rt   ru   r   rT   rg   rl   rp   r  rN   r   r)   rM  rM  ;  s{          G3 3 3 3& & & &P        r   rM  c                       e Zd ZdZdZdZdZdS )UnsignedBytezE
    Handles the unsignedByte datatype.  Unsigned 8-bit integer.
    u1)r      z8-bit unsignedNrr   rs   rt   ru   r   rT  rU  rN   r   r)   r[  r[    s)          FIHHHr   r[  c                       e Zd ZdZdZdZdZdS )Shortz=
    Handles the short datatype.  Signed 16-bit integer.
    i2)i i  z16-bitNr^  rN   r   r)   r`  r`    s)          FIHHHr   r`  c                       e Zd ZdZdZdZdZdS )Intz;
    Handles the int datatype.  Signed 32-bit integer.
    i4)i   iz32-bitNr^  rN   r   r)   rc  rc    s)          F)IHHHr   rc  c                       e Zd ZdZdZdZdZdS )Longz<
    Handles the long datatype.  Signed 64-bit integer.
    i8)l         l    z64-bitNr^  rN   r   r)   rf  rf    s)          F;IHHHr   rf  c                       e Zd ZdZddZdS )ComplexArrayVarArrayzH
    Handles an array of variable-length arrays of complex numbers.
    Nc                 ,   |                                 dk    rt          j        g           dfS |                     |||          }| j        j        }| j        j        }t          |          |z  dk    r&t          t          |t          |          f||           g }g }t          dt          |          |          D ]G}	 |||	|	|z            ||          \  }}
|                    |           |                    |
           Ht          ||          dfS )Nr   Tr   Fr   r   s              r)   rg   zComplexArrayVarArray.parse  s   ;;==B8B<<%%ufc22
!j,u::""S5#e**-vs;;;q#e**e,, 	% 	%A%+eAE	M&:FCHHKE4MM%   t$$$$!&+66==r   rq   r   rN   r   r)   ri  ri    s2         > > > > > >r   ri  c                       e Zd ZdZddZdS )ComplexVarArrayz=
    Handles a variable-length array of complex numbers.
    Nc                    |                                 dk    rt          j        g           dfS |                     |||          }| j        j        }g }g }t          dt          |          d          D ]S}d |||dz            D             } ||||          \  }}	|                    |           |                    |	           Tt          t          j        || j        j                  |          dfS )Nr   Tr   r   c                 ,    g | ]}t          |          S rN   r/  r   r(   s     r)   r   z)ComplexVarArray.parse.<locals>.<listcomp>      888!U1XX888r   r0   F)r   r   r3   r   r   r   r;   r2   r<   r6   r4   r   )
rP   rG   rR   rS   r   r   r   r   r   r1   s
             r)   rg   zComplexVarArray.parse  s   ;;==B8B<<%%ufc22j,q#e**a(( 	% 	%A88uQQY'7888E%+eVS99KE4MM%   t$$$$ rxdj6GHHH+VV
 	
r   rq   r   rN   r   r)   rl  rl    s2         
 
 
 
 
 
r   rl  c                   .    e Zd ZdZeZddZddZddZdS )ComplexArrayz8
    Handles a fixed-size array of complex numbers.
    Nc                 d    t                               | |||||           | xj        dz  c_        d S )Nr   )r   rT   r   r   s         r)   rT   zComplexArray.__init__  s4    dE4FCHHHqr   c                 p    |                      |||          }|dgk    rg }|                     |||          S r   )r   r   r   s        r)   rg   zComplexArray.parse  s?    ufc22RD==Evs333r   c                 P   t          |          | j        k    r+t          t          | j        t          |          f||           | j        j        }g }g }t          d| j        d          D ]S}d |||dz            D             } ||||          \  }}	|                    |           |                    |	           Tt          j	        || j        j
                                      | j                  }t          j	        |d                              | j                  }||fS )Nr   r   c                 ,    g | ]}t          |          S rN   ro  rp  s     r)   r   z,ComplexArray.parse_parts.<locals>.<listcomp>  rq  r   r0   r/   )r2   r   r   r	   r   r   r;   r<   r4   r3   r   r   r   )
rP   r   rR   rS   r   r   r   r   rG   r1   s
             r)   r   zComplexArray.parse_parts  s   u::$$S4;E

3VSAAAZ+
q$+q)) 	% 	%A88uQQY'7888E$*UFC88KE4MM%   t$$$$&
(9:::BB4?SSh{&999AA$/RR{""r   rq   )	rr   rs   rt   ru   ri  r
  rT   rg   r   rN   r   r)   rs  rs    sa          )M   4 4 4 4# # # # # #r   rs  c                   N    e Zd ZdZeZeZej	        Z
ddZddZeZeZddZd ZdS )Complexz-
    The base class for complex numbers.
    Nc                 z    t                               | |||           t                              | |||           d S rM   )r  rT   r   rO   s       r)   rT   zComplex.__init__  s:    tUFC888tUFC00000r   c                 B   |                                 }|dk    s|                                dk    rt          j        dfS | j        }d  ||||          D             }t          |          dk    rt          t          |f||           |                     |||          S )Nr   r$  Tc                 ,    g | ]}t          |          S rN   ro  rp  s     r)   r   z!Complex.parse.<locals>.<listcomp>  s    @@@aq@@@r   r   )	r   rS  r4   r$  r   r2   r   r
   r   )rP   rG   rR   rS   strippedsplitterr   s          r)   rg   zComplex.parse  s    ;;==r>>X^^--6664<>@@88E63#?#?@@@u::??S5(FC000vs333r   c                 B    t          | }||                     |          fS rM   )complexr  )rP   r   rR   rS   rG   s        r)   r   zComplex.parse_parts  s"    dll5))))r   c                    |r| j         dS | j         }| j                            t          |j                            }| j                            t          |j                            }| j        d         dk    r>|                    d          r
|d d         }|                    d          r
|d d         }|dz   |z   S )Nr  r   r5  r6  r7  r   )r  r#  r   r/  realimagr   )rP   rG   r1   r  r  s        r)   rl   zComplex.output   s     	"y u	"))%
*;*;<<"))%
*;*;<<q!S((}}T"" !CRCy}}T"" !CRCyczD  r   rq   )rr   rs   rt   ru   rs  r  rl  r
  r4   r$  r   rT   rg   r*  r)  r   rl   rN   r   r)   ry  ry    s          J#MfG1 1 1 14 4 4 4 O* * * *! ! ! ! !r   ry  c                       e Zd ZdZdZdS )FloatComplexzb
    Handle floatComplex datatype.  Pair of single-precision IEEE
    floating-point numbers.
    c8NrG  rN   r   r)   r  r  0  rH  r   r  c                       e Zd ZdZdZdS )DoubleComplexzc
    Handle doubleComplex datatype.  Pair of double-precision IEEE
    floating-point numbers.
    c16NrG  rN   r   r)   r  r  9  s         
 FFFr   r  c                   `    e Zd ZdZeZd	dZed	d            Zed	d            Z	d Z
d Zd ZdS )
BitArrayz#
    Handles an array of bits.
    Nc                 n    t                               | |||||           | j        dz
  dz  dz   | _        d S )Nr      )r   rT   r   _bytesr   s         r)   rT   zBitArray.__init__I  s;    dE4FCHHHaA-2r   c                 H    t          t          j        dd|                     S )Nz\sr   )listresubr   s      r)   r   zBitArray._splitter_pedanticN  s    BF5"e,,---r   c                 ~    d| v rt          t          d||           t          t          j        dd|                     S )Nr   rN   z\s|,r   )r   r   r  r  r  r   s      r)   r   zBitArray._splitter_laxR  s;    %<<CVS)))BF7B..///r   c                     t          j        |          rt          t                     t          j        |          }dddd                    fd|j        D                       S )N0rz   FTr   c              3   (   K   | ]}|         V  d S rM   rN   )r   r(   mappings     r)   r   z"BitArray.output.<locals>.<genexpr>]  s'      66awqz666666r   )r4   rY  r   r   r   r   rE   )rP   rG   r1   r  s      @r)   rl   zBitArray.outputX  sc    6$<< 	CLLL
5!!S))ww66665:666666r   c                      || j                   }t          || j                  }|                    | j                  }t          j        | j        d          }||fS Nr:   r0   )r  rB   r   r   r   r4   r   )rP   rY   r5   r   r   s        r)   rn   zBitArray.binparse_  sX    tDK  !$4400htd;;;{""r   c                 p    t          j        |          rt          t                     t	          |          S rM   )r4   rY  r   r   rJ   rk   s      r)   rp   zBitArray.binoutputf  s+    6$<< 	CLLL&&&r   rq   )rr   rs   rt   ru   r   r
  rT   rv   r   r   rl   rn   rp   rN   r   r)   r  r  B  s          "M3 3 3 3
 . . . \. 0 0 0 \0
7 7 7# # #' ' ' ' 'r   r  c                   D    e Zd ZdZdZeZeZdZ	dZ
dZddZd Zd	 Zd
 ZdS )Bitz#
    Handles the bit datatype.
    r:   F   r   Nc                    |i }ddd}|du s|                                 dk    r'|d         st          t          t          d||           dS 	 ||         dfS # t          $ r t	          t
          |f||           Y d S w xY w)NTF)rz   r  r   r_   rN   r  )r   r   r   KeyErrorr   r   rP   rG   rR   rS   r  s        r)   rg   z	Bit.parsey  s    >F5))E>>U[[]]b0001 9c3FC888;5u~u,, 5 5 5uh4444445s   	A "A>=A>c                 :    |rt          t                     |rdS dS )Nrz   r  )r   r   rk   s      r)   rl   z
Bit.output  s'     	CLLL 	33r   c                 H     |d          }t          |          dz  dk    dfS )Nr   r  r   F)ord)rP   rY   r5   s      r)   rn   zBit.binparse  s)    tAwwD		CA%u,,r   c                 N    |rt          t                     |r| j        S | j        S rM   )r   r   
binary_onebinary_zerork   s      r)   rp   zBit.binoutput  s.     	CLLL 	#?"r   rq   )rr   rs   rt   ru   r   r  r  r   r
  r   r  r  rg   rl   rn   rp   rN   r   r)   r  r  m  s          FJ"MGJK5 5 5 5  - - -         r   r  c                   "    e Zd ZdZeZd Zd ZdS )BooleanArrayz-
    Handles an array of boolean values.
    c                 |    || j                   }| j        j        }g }g }|D ]:} ||          \  }}|                    |           |                    |           ;t	          j        |d                              | j                  }t	          j        |d                              | j                  }||fS r  )r   r   binparse_valuer<   r4   r3   r   r   )	rP   rY   r5   rn   r   r   r}   rG   r1   s	            r)   rn   zBooleanArray.binparse  s    tDK  :, 	% 	%D"(4..KE4MM%   t$$$$&---55doFFh{$777??PP{""r   c                     | j         j        t          j        |          }t          j        |          }fdt          j        |j        |j                  D             }t                              |          S )Nc                 .    g | ]\  }} ||          S rN   rN   )r   r(   r   rp   s      r)   r   z*BooleanArray.binoutput.<locals>.<listcomp>  s'    RRRda))Aq//RRRr   )r   rp   r4   r   r   rE   r   r   )rP   rG   r1   r   rp   s       @r)   rp   zBooleanArray.binoutput  sh    J(	
5!!z$RRRRbl5:ty.Q.QRRR  (((r   N)rr   rs   rt   ru   r   r
  rn   rp   rN   r   r)   r  r    sC          "M# # #) ) ) ) )r   r  c                      e Zd ZdZdZeZeZdZ	dZ
dZdZddZd	 Zd
 Z ed          d ed          d ed          d ed          d ed          d ed          d ed          d ed          d ed          di	Zd Zd ZdS )Booleanz'
    Handles the boolean datatype.
    r:   F   ?   T   FNc                     |dk    rdS |du rdS ddddddddddd
}	 ||                                          S # t          $ r t          t          |f||           Y d S w xY w)Nr   r  FTFFF)
TRUEFALSErz   r  Tr  r   r   ?r   )upperr  r   r   r  s        r)   rg   zBoolean.parse  s    B;;;E>>;!#
 
	15;;==)) 	1 	1 	1S5(FC000000	1s   7 "AAc                     |rdS |rdS dS )Nr  r  r  rN   rk   s      r)   rl   zBoolean.output  s!     	3 	3sr   c                 \    t           |d                    }|                     |          S )Nr   )r  r  )rP   rY   rG   s      r)   rn   zBoolean.binparse  s)    DDGG""5)))r   r  r  trz   r  r  r  r  r   r  r   r  c                 l    	 | j         |         S # t          $ r t          t          |f           Y d S w xY wrM   )_binparse_mappingr  r   r   r  s     r)   r  zBoolean.binparse_value  sK    	$)%00 	$ 	$ 	$S5(######	$s     33c                 4    |r| j         S |r| j        S | j        S rM   )binary_question_markbinary_truebinary_falserk   s      r)   rp   zBoolean.binoutput  s-     	-,, 	$##  r   rq   )rr   rs   rt   ru   r   r  r  r   r
  r   r  r  r  rg   rl   rn   r  r  r  rp   rN   r   r)   r  r    s         FJ"MGKL1 1 1 1,  * * *
 	C-C-C-C.C.C.D		=C-C-
$ $ $! ! ! ! !r   r  )doubler/  rA   booleanunsignedByteshortr\   longfloatComplexdoubleComplexr}   r   c                 >   |i }| j         t          vr"t          t          | j         | j        f|           t          | j                  } || ||          }| j        }| j         dvr||d         dk    r5|dd         }|                    d          }|dk    rd}n
|d|         }d}nd}|dk    r4d	 |                    d          D             }|                                 ng }|g k    r|	                    | |||          }|s|
                    | |||          }|S )
at  
    Get an appropriate converter instance for a given field.

    Parameters
    ----------
    field : astropy.io.votable.tree.Field

    config : dict, optional
        Parser configuration dictionary

    pos : tuple
        Position in the input XML file.  Used for error messages.

    Returns
    -------
    converter : astropy.io.votable.converters.Converter
    N)r}   r   r9   r{   r(   r   FTc                 ,    g | ]}t          |          S rN   )r\   rp  s     r)   r   z!get_converter.<locals>.<listcomp>=  s    >>>AQ>>>r   )datatypeconverter_mappingr   r   r   r   rfindr   reverser  r
  )rQ   rR   rS   cls	converterr   last_xfixeds           r)   r   r     sU   $ ~~...u~ux0&999
EN
+CE63''II ~4449NR=C!#2#I__S))F||		%gvg.	EEE??>>)=)=>>>II??!,,UIy&QQI 	U!//y)VTTIr   r  r/  rA   r  r  r\   r  r  r  r   r}   c                     d}d}| D ]n}t          |t          j                  rt          |          dk    r0|du r|j        }|j        dd          }K||j        k    r dS ||j        dd          k    rd}o||fS )NFrN   r   r   )FrN   )r   r4   ndarrayr2   r$   shape)columnfirst_dtypefirst_shaper(   s       r)   _all_matching_dtyper  \  s    KK 
 
!RZ(( 	CFFaKK%'K'!""+KKAG##99AGABBK''K##r   c                 ^   | j         t          vrt          | d          | j        dk    rdt	          | j                  dS | j        dk    rdt	          | j        dz            dS dt          | j                  i}t          |          r"d	                    d
 |D                       |d<   |S )au  
    Converts a numpy dtype and shape to a dictionary of attributes for
    a VOTable FIELD element and correspond to that type.

    Parameters
    ----------
    dtype : Numpy dtype instance

    shape : tuple

    Returns
    -------
    attributes : dict
        A dict containing 'datatype' and 'arraysize' keys that can be
        set on a VOTable FIELD element.
    z" can not be represented in VOTableSr}   r  r   r~   r   rW   r  r(   c              3   4   K   | ]}t          |          V  d S rM   )r   rp  s     r)   r   z)numpy_to_votable_dtype.<locals>.<genexpr>  s(      *A*Aa3q66*A*A*A*A*A*Ar   r   )numnumpy_dtype_to_field_mapping	TypeErrorr}   r   r   r2   r   )r$   r  r   s      r)   numpy_to_votable_dtyper  m  s    " y4445FFFGGGzS"U^1D1DEEE	s		)ENa<O8P8PQQQ:59EFu:: 	B"%((*A*A5*A*A*A"A"AF;r   c                    d}| j         j        | j         j                            d          }| j        j        dk    rn||ddS t          | d         t          j                  rBt          |           \  }}|dur,t          ||          }d|vrd|d<   n|dxx         dz  cc<   |S d	ddS t          | j        | j
        d
d                   }|d         d	k    r|dk    rd|d<   |S )a  
    Given a `astropy.table.Column` instance, returns the attributes
    necessary to create a VOTable FIELD element that corresponds to
    the type of the column.

    This necessarily must perform some heuristics to determine the
    type of variable length arrays fields, since they are not directly
    supported by Numpy.

    If the column has dtype of "object", it performs the following
    tests:

       - If all elements are byte or unicode strings, it creates a
         variable-length byte or unicode field, respectively.

       - If all elements are numpy arrays of the same dtype and with a
         consistent shape in all but the first dimension, it creates a
         variable length array of fixed sized arrays.  If the dtypes
         match, but the shapes do not, a variable length array is
         created.

    If the dtype of the input is not understood, it sets the data type
    to the most inclusive: a variable length unicodeChar array.

    Parameters
    ----------
    column : `astropy.table.Column` instance

    Returns
    -------
    attributes : dict
        A dict containing 'datatype' and 'arraysize' keys that can be
        set on a VOTable FIELD element.
    N_votable_string_dtyper|   r{   r  r   Fr   r   r   r  r}   )infometar`   r$   r}   r   r4   r  r  r  r  )r  votable_string_dtyper$   r  r   s        r)   r   r     s(   F  {#%{/334KLL|C+ 43GGGq	2:.. 	.v66LE5E!!/u==f,,*-F;'';'''3.''' *<<< $FL&,qrr2BCCFj]**/Cv/M/M#zMr   rq   )]ru   r  sysstructr   _struct_packr   _struct_unpacknumpyr4   r   astropy.utils.xml.writerr   
exceptionsr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __all__compiler   r   r   r   r   rX   rF   r%   r*   r6   rB   rJ   r   rx   r   r   r   r   r   r   r  r  rE  rJ  rM  r[  r`  rc  rf  ri  rl  rs  ry  r  r  r  r  r  r  r  r   float64r$   r  float32bool_uint8int16int32int64	complex64
complex128unicode_r  bytes_r  r  r   rN   r   r)   <module>r     s!    
			 



 ' ' ' ' ' ' + + + + + +           6 5 5 5 5 5                                         , M
L
L %"*U++ .// 	
  =H     ( ( () ) )@ 1  1  1FLX LX LX LX LX LX LX LX^h7 h7 h7 h7 h79 h7 h7 h7V>K >K >K >K >K) >K >K >KB+ + + + +I + + +8() () () () ()u () () ()V> > > > >H > > >2> > > > >X > > >,I" I" I" I" I"5 I" I" I"X" " " " "i " " ":l0 l0 l0 l0 l0G l0 l0 l0^    ]       M   J J J J Jg J J JZ         7          G       '       7   > > > > >8 > > >0
 
 
 
 
h 
 
 
2# # # # #< # # #B+! +! +! +! +!mU +! +! +!\    7       G   (' (' (' (' ('| (' (' ('V-  -  -  -  - ) -  -  - `) ) ) ) )< ) ) )8E! E! E! E! E!i E! E! E!R   "   7 7 7 7v BJLLHBJLLGBHJJ%BHJJ.BHJJ'BHJJ%BHJJ&BLNNnBMOOBKMM]   7= YRY[[.2 3$ $ $"  @< < < < <r   