
    q-Ph]                       U d dl mZ d dlZd dlZd dlmZmZmZmZm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZmZ d dlmZ d dlmZmZ d dlmZ  d dlm!Z" d dl#m$Z$ d dl%m&Z&  ej'        e(          5  d dl)m*Z* ddd           n# 1 swxY w Y   erzd dl+Z+d dl,m-Z-m.Z. d dl/m0Z0 d dlm1Z1m2Z2m3Z3 e+j4        dk    rd dlm5Z5 nd dl6m5Z5 e+j4        dk    rd dlm7Z7 nd dl6m7Z7 eee$e&e j        e j&        e1         e"j8        e"j9        f         Z:de;d<   dgZ<d,d Z=d-d"Z>ddd#d.d*Z? G d+ dee                   Z@dS )/    )annotationsN)TYPE_CHECKINGCallableGenericUnionoverload)	FrameType)deprecate_renamed_parameter)is_pycapsule)issue_unstable_warning)_get_stack_localsqualified_type_name)wrap_ldf)
from_arrowfrom_pandas)	DataFrame)_check_for_pandas_check_for_pyarrow)pandas)pyarrow)	LazyFrame)Series)PySQLContext)
CollectionMapping)TracebackType)AnyFinalLiteral)   
   )	TypeAlias)r       )Selfr"   CompatibleFrameType
SQLContextobjr   returnboolc                   t          |           p~t          | t                    pit          |           o%t          | t          j        t          j        f          p4t          |           o%t          | t          j	        t          j
        f          S )z2Check if the object can be converted to DataFrame.)r   
isinstancer   r   pdr   r   r   paTableRecordBatch)r'   s    R/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/polars/sql/context.py_compatible_framer1   ;   s{     	S 	Uc9%%	Uc""Qz#bi7P'Q'Q	U s##S
32>8R(S(S	    r   c                   t          | t          t          f          r|                                 S t          | t                    r&|                                                                 S t          |           rrt          | t          j        t          j        f          rLt          t          |           x}t                    r|                                }|                                S t          |           s5t          |           rGt          | t          j        t          j        f          r!t          |                                           S dt          |            }t!          |          )z'Return LazyFrame from compatible input.zunrecognised frame type: )r+   r   r   lazyr   to_framer   r,   r   r   r   r-   r.   r/   r   r   
ValueError)r'   framemsgs      r0   _ensure_lazyframer9   E   s0   #	9-.. xxzz	C	 	  ||~~""$$$	3		 
JsR\294M$N$N 
{3///e88 	%NN$$Ezz||	c		 3$.sRXr~4N$O$O ###%%%D*=c*B*BDDoor2   )	n_objectsnamedall_compatibler:   
int | Noner;   4str | Collection[str] | Callable[[str], bool] | Nonedict[str, Any]c                `    | rt           nt          t          t          f}t	          |||          S )z5Return compatible frame objects from the local stack.)of_typer:   r;   )r1   r   r   r   r   )r<   r:   r;   rA   s       r0   _get_frame_localsrB   X   s0     $2U	9f7UGW	OOOOr2   c                     e Zd ZU dZded<   ded<   ded<   e	 dRddd	d
dSd            Ze	 dRddddTd            Ze	 dRddddUd            Z eddd !          	 dVd	d	d#dWd$            Zeed	d%dXd)                        Z	eedYd+                        Z	eedZd-                        Z	ed	d%dZd.            Z	d[d0Z
d\d7Zd]d8Zedd%d^d9            Zed_d:            Zed`d;            Zedd%dad<            Zedbd=            Zedcd>            Zedd%dddA            Zd"d%dddBZdedFZ	 dVdGdHdfdKZ	 dVdgdLZdhdOZdidQZd"S )jr&   a   
    Run SQL queries against DataFrame, LazyFrame, and Series data.

    .. warning::
        This functionality is considered **unstable**, although it is close to being
        considered stable. It may be changed at any point without it being considered
        a breaking change.
    r   _ctxtzFinal[bool]_eager_executionzlist[set[str]]_tables_scope_stack.F)register_globalsr<   eagerselfSQLContext[LazyFrame]frames/Mapping[str, CompatibleFrameType | None] | NonerG   
bool | intr<   r)   rH   Literal[False]named_framesCompatibleFrameType | Noner(   Nonec                   d S N rI   rK   rG   r<   rH   rO   s         r0   __init__zSQLContext.__init__w   	     sr2   )rG   r<   SQLContext[DataFrame]Literal[True]c                   d S rS   rT   rU   s         r0   rV   zSQLContext.__init__   rW   r2   c                   d S rS   rT   rU   s         r0   rV   zSQLContext.__init__   rW   r2   eager_executionz0.20.31)versionN)rG   rH   c               R   t          d           t          j                    | _        || _        t          |pi           }|r5t          d                                          D ]\  }}||vr	||vr|||<   |s|r,|                    |           | 	                    |           dS dS )u  
        Initialize a new `SQLContext`.

        .. versionchanged:: 0.20.31
            The `eager_execution` parameter was renamed `eager`.

        Parameters
        ----------
        frames
            A `{name:frame, ...}` mapping which can include Polars frames *and*
            pandas DataFrames, Series and pyarrow Table and RecordBatch objects.
        register_globals
            Register compatible objects (polars DataFrame, LazyFrame, and Series) found
            in the globals, automatically mapping their variable name to a table name.
            To register other objects (pandas/pyarrow data) pass them explicitly, or
            call the `execute_global` classmethod. If given an integer then only the
            most recent "n" objects found will be registered.
        eager
            If True, returns execution results as `DataFrame` instead of `LazyFrame`.
            (Note that the query itself is always executed in lazy-mode; this parameter
            impacts whether :meth:`execute` returns an eager or lazy result frame).
        **named_frames
            Named eager/lazy frames, provided as kwargs.

        Examples
        --------
        >>> lf = pl.LazyFrame({"a": [1, 2, 3], "b": ["x", None, "z"]})
        >>> res = pl.SQLContext(frame=lf).execute(
        ...     "SELECT b, a*2 AS two_a FROM frame WHERE b IS NOT NULL"
        ... )
        >>> res.collect()
        shape: (2, 2)
        ┌─────┬───────┐
        │ b   ┆ two_a │
        │ --- ┆ ---   │
        │ str ┆ i64   │
        ╞═════╪═══════╡
        │ x   ┆ 2     │
        │ z   ┆ 6     │
        └─────┴───────┘
        zY`SQLContext` is considered **unstable**, although it is close to being considered stable.Fr<   N)
r   r   newrD   rE   dictrB   itemsupdateregister_many)rI   rK   rG   rH   rO   namer'   s          r0   rV   zSQLContext.__init__   s    d 	g	
 	
 	
 "%''
 %fl## 	-.$  egg- -	c v%%$l*B*B),L& 	'\ 	'MM,'''v&&&&&	' 	'r2   )rH   querystrr   c                   d S rS   rT   clsrf   rH   s      r0   execute_globalzSQLContext.execute_global   s	     Cr2   r   c                   d S rS   rT   ri   s      r0   rk   zSQLContext.execute_global   s    ORsr2   DataFrame | LazyFramec                   d S rS   rT   ri   s      r0   rk   zSQLContext.execute_global   s    RURUr2   c               p   t          j        d|dt           j                  }t          |          dk    r%d t          j        d|d                   D             nt	                      }t          d|          } | |d	          5 }|                    ||
          cddd           S # 1 swxY w Y   dS )u  
        Immediately execute a SQL query, automatically registering frame globals.

        Notes
        -----
        * This convenience method automatically registers all compatible objects in
          the local stack that are referenced in the query, mapping their variable name
          to a table name. Note that in addition to polars DataFrame, LazyFrame, and
          Series this method *also* registers pandas DataFrame, Series, and pyarrow
          Table and RecordBatch objects.
        * Instead of calling this classmethod you should consider using `pl.sql`,
          which will use this code internally.

        Parameters
        ----------
        query
            A valid SQL query string.
        eager
            If True, returns execution results as `DataFrame` instead of `LazyFrame`.
            (Note that the query itself is always executed in lazy-mode).

        Examples
        --------
        >>> import pandas as pd
        >>> df = pl.LazyFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
        >>> df_pandas = pd.DataFrame({"a": [2, 3, 4], "c": [7, 8, 9]})

        Join a polars LazyFrame with a pandas DataFrame (note use of the preferred
        `pl.sql` method, which is equivalent to `SQLContext.execute_global`):

        >>> pl.sql("SELECT df.*, c FROM df JOIN df_pandas USING(a)").collect()
        shape: (2, 3)
        ┌─────┬─────┬─────┐
        │ a   ┆ b   ┆ c   │
        │ --- ┆ --- ┆ --- │
        │ i64 ┆ i64 ┆ i64 │
        ╞═════╪═════╪═════╡
        │ 2   ┆ 5   ┆ 7   │
        │ 3   ┆ 6   ┆ 8   │
        └─────┴─────┴─────┘
        z\bFROM\b   )maxsplitflagsc                    h | ]@}t          j        d |          s|                                +|                    d          AS )z^("[^"]+")$")rematchisidentifierstrip).0nms     r0   	<setcomp>z,SQLContext.execute_global.<locals>.<setcomp>  sX       8NB// 46??3D3D  r2   z\bT)r<   r;   F)rK   rG   )rf   rH   N)ru   splitIlensetrB   execute)rj   rf   rH   qpossible_namesrO   ctxs          r0   rk   zSQLContext.execute_global   s   ` H[%!24@@@ 1vvzz (5!A$//     	 )NSSSSu=== 	9;;U%;88	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9s   B++B/2B/SQLContext[FrameType]c                    t          | dg           | _        | j                            t          |                                                      | S )zITrack currently registered tables on scope entry; supports nested scopes.rF   )getattrrF   appendr   tablesrI   s    r0   	__enter__zSQLContext.__enter__)  sC    #*41F#K#K  ''DKKMM(:(:;;;r2   exc_typetype[BaseException] | Noneexc_valBaseException | Noneexc_tbTracebackType | Nonec                    |                      t          |                                           | j                                        z
             dS )z
        Unregister any tables created within the given scope on context exit.

        See Also
        --------
        unregister
        )namesN)
unregisterr   r   rF   pop)rI   r   r   r   s       r0   __exit__zSQLContext.__exit__/  sP     	t{{}}%%(@(D(D(F(FF 	 	
 	
 	
 	
 	
r2   c                r    t          |                                           }d| dt          |           ddS )Nz<SQLContext [tables:z] at 0xx>)r~   r   id)rI   n_tabless     r0   __repr__zSQLContext.__repr__@  s9    t{{}}%%DhDDr$xxDDDDDr2   c                   d S rS   rT   rI   rf   rH   s      r0   r   zSQLContext.executeG  	     Cr2   c                   d S rS   rT   r   s      r0   r   zSQLContext.executeL  r   r2   c                   d S rS   rT   r   s      r0   r   zSQLContext.executeQ  r   r2   c                   d S rS   rT   r   s      r0   r   zSQLContext.executeV  r   r2   c                   d S rS   rT   r   s      r0   r   zSQLContext.execute[  r   r2   c                   d S rS   rT   r   s      r0   r   zSQLContext.execute`  r   r2   bool | NoneLazyFrame | DataFramec                   d S rS   rT   r   s      r0   r   zSQLContext.executee  s	     !$r2   c                   t          | j                            |                    }|s| j        r|                                n|S )u  
        Parse the given SQL query and execute it against the registered frame data.

        Parameters
        ----------
        query
            A valid string SQL query.
        eager
            Apply the query eagerly, returning `DataFrame` instead of `LazyFrame`.
            If unset, the value of the init-time "eager" parameter will be used.
            Note that the query itself is always executed in lazy-mode; this
            parameter only impacts the type of the returned frame.

        Examples
        --------
        Declare frame data and register with a SQLContext:

        >>> df = pl.DataFrame(
        ...     data=[
        ...         ("The Godfather", 1972, 6_000_000, 134_821_952, 9.2),
        ...         ("The Dark Knight", 2008, 185_000_000, 533_316_061, 9.0),
        ...         ("Schindler's List", 1993, 22_000_000, 96_067_179, 8.9),
        ...         ("Pulp Fiction", 1994, 8_000_000, 107_930_000, 8.9),
        ...         ("The Shawshank Redemption", 1994, 25_000_000, 28_341_469, 9.3),
        ...     ],
        ...     schema=["title", "release_year", "budget", "gross", "imdb_score"],
        ...     orient="row",
        ... )
        >>> ctx = pl.SQLContext(films=df)

        Execute a SQL query against the registered frame data:

        >>> ctx.execute(
        ...     '''
        ...     SELECT title, release_year, imdb_score
        ...     FROM films
        ...     WHERE release_year > 1990
        ...     ORDER BY imdb_score DESC
        ...     ''',
        ...     eager=True,
        ... )
        shape: (4, 3)
        ┌──────────────────────────┬──────────────┬────────────┐
        │ title                    ┆ release_year ┆ imdb_score │
        │ ---                      ┆ ---          ┆ ---        │
        │ str                      ┆ i64          ┆ f64        │
        ╞══════════════════════════╪══════════════╪════════════╡
        │ The Shawshank Redemption ┆ 1994         ┆ 9.3        │
        │ The Dark Knight          ┆ 2008         ┆ 9.0        │
        │ Schindler's List         ┆ 1993         ┆ 8.9        │
        │ Pulp Fiction             ┆ 1994         ┆ 8.9        │
        └──────────────────────────┴──────────────┴────────────┘

        Execute a GROUP BY query:

        >>> ctx.execute(
        ...     '''
        ...     SELECT
        ...         MAX(release_year / 10) * 10 AS decade,
        ...         SUM(gross) AS total_gross,
        ...         COUNT(title) AS n_films,
        ...     FROM films
        ...     GROUP BY (release_year / 10) -- decade
        ...     ORDER BY total_gross DESC
        ...     ''',
        ...     eager=True,
        ... )
        shape: (3, 3)
        ┌────────┬─────────────┬─────────┐
        │ decade ┆ total_gross ┆ n_films │
        │ ---    ┆ ---         ┆ ---     │
        │ i64    ┆ i64         ┆ u32     │
        ╞════════╪═════════════╪═════════╡
        │ 2000   ┆ 533316061   ┆ 1       │
        │ 1990   ┆ 232338648   ┆ 3       │
        │ 1970   ┆ 134821952   ┆ 1       │
        └────────┴─────────────┴─────────┘
        )r   rD   r   rE   collect)rI   rf   rH   ress       r0   r   zSQLContext.executej  sA    b tz))%0011!&I$*?Is{{}}}cIr2   re   r7   r$   c                    |t                      nt          |          }| j                            ||j                   | S )u  
        Register a single frame as a table, using the given name.

        Parameters
        ----------
        name
            Name of the table.
        frame
            eager/lazy frame to associate with this table name.

        See Also
        --------
        register_globals
        register_many
        unregister

        Examples
        --------
        >>> df = pl.DataFrame({"hello": ["world"]})
        >>> ctx = pl.SQLContext()
        >>> ctx.register("frame_data", df).execute("SELECT * FROM frame_data").collect()
        shape: (1, 1)
        ┌───────┐
        │ hello │
        │ ---   │
        │ str   │
        ╞═══════╡
        │ world │
        └───────┘
        )r   r9   rD   register_ldf)rI   re   r7   s      r0   r   zSQLContext.register  s=    >  %}	2CE2J2J
D%*---r2   Tr_   nr=   c               P    t          ||          }|                     |          S )u9  
        Register all frames (lazy or eager) found in the current globals scope.

        Automatically maps variable names to table names.

        See Also
        --------
        register
        register_many
        unregister

        Parameters
        ----------
        n
            Register only the most recent "n" frames.
        all_compatible
            Control whether we *also* register pandas DataFrame, Series, and
            pyarrow Table and RecordBatch objects. If False, only Polars
            classes are registered with the SQL engine.

        Examples
        --------
        >>> df1 = pl.DataFrame({"a": [1, 2, 3], "b": ["x", None, "z"]})
        >>> df2 = pl.DataFrame({"a": [2, 3, 4], "c": ["t", "w", "v"]})

        Register frames directly from variables found in the current globals scope:

        >>> ctx = pl.SQLContext(register_globals=True)
        >>> ctx.tables()
        ['df1', 'df2']

        Query using the register variable/frame names

        >>> ctx.execute(
        ...     "SELECT a, b, c FROM df1 LEFT JOIN df2 USING (a) ORDER BY a DESC"
        ... ).collect()
        shape: (3, 3)
        ┌─────┬──────┬──────┐
        │ a   ┆ b    ┆ c    │
        │ --- ┆ ---  ┆ ---  │
        │ i64 ┆ str  ┆ str  │
        ╞═════╪══════╪══════╡
        │ 3   ┆ z    ┆ w    │
        │ 2   ┆ null ┆ t    │
        │ 1   ┆ x    ┆ null │
        └─────┴──────┴──────┘
        )r<   r:   )rK   )rB   rd   )rI   r   r<   rK   s       r0   rG   zSQLContext.register_globals  s.    d #.ANNN!!!000r2   c                    t          |pi           }|                    |           |                                D ]\  }}|                     ||           | S )a   
        Register multiple eager/lazy frames as tables, using the associated names.

        Parameters
        ----------
        frames
            A `{name:frame, ...}` mapping.
        **named_frames
            Named eager/lazy frames, provided as kwargs.

        See Also
        --------
        register
        register_globals
        unregister

        Examples
        --------
        >>> lf1 = pl.LazyFrame({"a": [1, 2, 3], "b": ["m", "n", "o"]})
        >>> lf2 = pl.LazyFrame({"a": [2, 3, 4], "c": ["p", "q", "r"]})
        >>> lf3 = pl.LazyFrame({"a": [3, 4, 5], "b": ["s", "t", "u"]})
        >>> lf4 = pl.LazyFrame({"a": [4, 5, 6], "c": ["v", "w", "x"]})

        Register multiple frames at once, either by passing in as a dict...

        >>> ctx = pl.SQLContext().register_many({"tbl1": lf1, "tbl2": lf2})
        >>> ctx.tables()
        ['tbl1', 'tbl2']

        ...or using keyword args:

        >>> ctx.register_many(tbl3=lf3, tbl4=lf4).tables()
        ['tbl1', 'tbl2', 'tbl3', 'tbl4']
        )ra   rc   rb   r   )rI   rK   rO   re   r7   s        r0   rd   zSQLContext.register_many  s_    N fl##l###!<<>> 	' 	'KD%MM$&&&&r2   r   str | Collection[str]c                t    t          |t                    r|g}|D ]}| j                            |           | S )a  
        Unregister one or more eager/lazy frames by name.

        Parameters
        ----------
        names
            Names of the tables to unregister.

        Notes
        -----
        You can also control table registration lifetime by using `SQLContext` as a
        context manager; this can often be more useful when such control is wanted:

        >>> df0 = pl.DataFrame({"colx": [0, 1, 2]})
        >>> df1 = pl.DataFrame({"colx": [1, 2, 3]})
        >>> df2 = pl.DataFrame({"colx": [2, 3, 4]})

        Frames registered in-scope are automatically unregistered on scope-exit. Note
        that frames registered on construction will persist through subsequent scopes.

        >>> # register one frame at construction time, and the other two in-scope
        >>> with pl.SQLContext(tbl0=df0) as ctx:
        ...     ctx.register_many(tbl1=df1, tbl2=df2).tables()
        ['tbl0', 'tbl1', 'tbl2']

        After scope exit, none of the tables registered in-scope remain:

        >>> ctx.tables()
        ['tbl0']

        See Also
        --------
        register
        register_globals
        register_many

        Examples
        --------
        >>> df0 = pl.DataFrame({"ints": [9, 8, 7, 6, 5]})
        >>> lf1 = pl.LazyFrame({"text": ["a", "b", "c"]})
        >>> lf2 = pl.LazyFrame({"misc": ["testing1234"]})

        Register with a SQLContext object:

        >>> ctx = pl.SQLContext(test1=df0, test2=lf1, test3=lf2)
        >>> ctx.tables()
        ['test1', 'test2', 'test3']

        Unregister one or more of the tables:

        >>> ctx.unregister(["test1", "test3"]).tables()
        ['test2']
        >>> ctx.unregister("test2").tables()
        []
        )r+   rg   rD   r   )rI   r   rz   s      r0   r   zSQLContext.unregisterC  sK    p eS!! 	GE 	& 	&BJ!!"%%%%r2   	list[str]c                N    t          | j                                                  S )u)  
        Return a list of the registered table names.

        Notes
        -----
        The :meth:`tables` method will return the same values as the
        "SHOW TABLES" SQL statement, but as a list instead of a frame.

        Executing as SQL:

        >>> frame_data = pl.DataFrame({"hello": ["world"]})
        >>> ctx = pl.SQLContext(hello_world=frame_data)
        >>> ctx.execute("SHOW TABLES", eager=True)
        shape: (1, 1)
        ┌─────────────┐
        │ name        │
        │ ---         │
        │ str         │
        ╞═════════════╡
        │ hello_world │
        └─────────────┘

        Calling the method:

        >>> ctx.tables()
        ['hello_world']

        Examples
        --------
        >>> df1 = pl.DataFrame({"hello": ["world"]})
        >>> df2 = pl.DataFrame({"foo": ["bar", "baz"]})
        >>> ctx = pl.SQLContext(hello_data=df1, foo_bar=df2)
        >>> ctx.tables()
        ['foo_bar', 'hello_data']
        )sortedrD   
get_tablesr   s    r0   r   zSQLContext.tables  s!    H dj++--...r2   ).)rI   rJ   rK   rL   rG   rM   r<   r)   rH   rN   rO   rP   r(   rQ   )rI   rX   rK   rL   rG   rM   r<   r)   rH   rY   rO   rP   r(   rQ   )rI   rX   rK   rL   rG   rM   r<   r)   rH   r)   rO   rP   r(   rQ   rS   )
rK   rL   rG   rM   rH   r)   rO   rP   r(   rQ   )rf   rg   rH   rN   r(   r   )rf   rg   rH   rY   r(   r   )rf   rg   rH   r)   r(   rm   )r(   r   )r   r   r   r   r   r   r(   rQ   )r(   rg   )rI   rX   rf   rg   rH   rQ   r(   r   )rI   rX   rf   rg   rH   rN   r(   r   )rI   rX   rf   rg   rH   rY   r(   r   )rI   rJ   rf   rg   rH   rQ   r(   r   )rI   rJ   rf   rg   rH   rN   r(   r   )rI   rJ   rf   rg   rH   rY   r(   r   )rf   rg   rH   r   r(   r   )re   rg   r7   rP   r(   r$   )r   r=   r<   r)   r(   r$   )rK   rL   rO   rP   r(   r$   )r   r   r(   r$   )r(   r   )__name__
__module____qualname____doc____annotations__r   rV   r
   classmethodrk   r   r   r   r   r   rG   rd   r   r   rT   r2   r0   r&   r&   c   s          !!!!''''  CF (+" %     X  CF (+"     X  CF (+"     X ! !2GYOOO CGA' (-A' A' A' A' A' POA'F 49     [ X RRR [ XRUUU [ XU*/<9 <9 <9 <9 <9 [<9|   
 
 
 
"E E E E BE     X    X    X BE     X    X    X 25$ $ $ $ $ X$
 37RJ RJ RJ RJ RJ RJh! ! ! !H #31>B31 31 31 31 31 31n CG+ + + + +Z< < < <|$/ $/ $/ $/ $/ $/r2   )r'   r   r(   r)   )r'   r   r(   r   )r<   r)   r:   r=   r;   r>   r(   r?   )A
__future__r   
contextlibru   typingr   r   r   r   r   polars._typingr	   polars._utils.deprecationr
   polars._utils.pycapsuler   polars._utils.unstabler   polars._utils.variousr   r   polars._utils.wrapr   polars.convertr   r   polars.dataframer   polars.dependenciesr   r   r   r,   r   r-   polars.lazyframer   polars.seriesr   suppressImportErrorpolars.polarsr   syscollections.abcr   r   typesr   r   r   r   version_infor"   typing_extensionsr$   r.   r/   r%   r   __all__r1   r9   rB   r&   rT   r2   r0   <module>r      s   " " " " " " "     				              % $ $ $ $ $ A A A A A A 0 0 0 0 0 0 9 9 9 9 9 9 H H H H H H H H ' ' ' ' ' ' 2 2 2 2 2 2 2 2 & & & & & & E E E E E E E E , , , , , , - - - - - - & & & & & &            Z%% + +******+ + + + + + + + + + + + + + +  JJJ33333333######**********
7""$$$$$$$//////
7""******%*

	#

	&     .      , !BF	P P P P P PB	/ B	/ B	/ B	/ B	/# B	/ B	/ B	/ B	/ B	/s   BBB