o
    ‹åg+i  ã                   @  s  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 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 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 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 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! 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& dd lm'Z' dd!lm(Z( dd"lm)Z) erød d#lm*Z* d d$l+m,Z, d d%l-m.Z. d d&l-m/Z/ d d'l0m1Z1 d d(lm2Z2 d d)l3m4Z4 dd*l5m6Z6 G d+d,„ d,ƒZ7G d-d.„ d.ƒZ8d/S )0é    )Úannotations)ÚAny)ÚDict)ÚList)ÚOptional)ÚTuple)ÚTYPE_CHECKING)ÚUnion)ÚCheckConstraint)ÚColumn)ÚForeignKeyConstraint)ÚIndex)ÚMetaData)ÚPrimaryKeyConstraint©Úschema)Úselect)ÚTable)Útypes)ÚSchemaEventTarget)ÚOrderedDict)Útopologicalé   )Úexc)Ú_columns_for_constraint)Ú_copy)Ú_copy_expression)Ú_ensure_scope_for_ddl)Ú_fk_is_self_referential)Ú_idx_table_bound_expressions)Ú_is_type_bound)Ú_remove_column_from_collection)Ú_resolve_for_variant)Úconstraint_name_defined)Úconstraint_name_string)ÚLiteral)ÚDialect)ÚColumnClause)Úquoted_name)ÚFunction)Ú
Constraint)Ú
TypeEngine)ÚDefaultImplc                   @  sº   e Zd Zdd„ Zed1dd„ƒZed2dd	„ƒZd3dd„Zd4dd„Zd4dd„Z	d4dd„Z
d4dd„Zd5dd„Zd5dd„Zdd„ Zd6d"d#„Zd6d$d%„Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0S )7ÚBatchOperationsImplc                 C  s˜   || _ || _|| _|dvrtdƒ‚|| _|| _|| _t|ƒ| _|| _	t|	ƒ| _
| j
 dt| j
 dd¡ƒ¡ | j
d  d|jjf¡ |
| _|| _g | _d S )N)ÚautoÚalwaysÚneverz4recreate may be one of 'auto', 'always', or 'never'.Ú	listeners© Úcolumn_reflect)Ú
operationsÚ
table_namer   Ú
ValueErrorÚrecreateÚ	copy_fromÚ
table_argsÚdictÚtable_kwargsÚreflect_argsÚreflect_kwargsÚ
setdefaultÚlistÚgetÚappendÚimplÚautogen_column_reflectÚnaming_conventionÚpartial_reorderingÚbatch)Úselfr4   r5   r   r7   r8   r9   r;   r<   r=   rD   rE   r2   r2   úT/var/www/html/flaskapp/venv/lib/python3.10/site-packages/alembic/operations/batch.pyÚ__init__7   s,   ÿ

ÿ

ÿ
zBatchOperationsImpl.__init__Úreturnr&   c                 C  s
   | j jjS ©N)r4   rB   Údialect©rG   r2   r2   rH   rL   \   s   
zBatchOperationsImpl.dialectr,   c                 C  s   | j jS rK   )r4   rB   rM   r2   r2   rH   rB   `   s   zBatchOperationsImpl.implÚboolc                 C  s*   | j dkr| jj | ¡S | j dkrdS dS )Nr.   r/   TF)r7   r4   rB   Úrequires_recreate_in_batchrM   r2   r2   rH   Ú_should_recreated   s
   

z$BatchOperationsImpl._should_recreateÚNonec           
   	   C  s\  |   ¡ }t| jjƒ�š |s%| jD ]\}}}t| jj|ƒ}||i |¤Ž qnw| jr/t| jd�}ntƒ }| j	d ur=| j	}d}n.| jj
jrSt d| jj
jj› d| j› d�¡‚t| j|g| j¢R | j| j ¡ dœ| j¤Ž}d}t| j|| j| j|| jd�}	| jD ]\}}}t|	|ƒ}||i |¤Ž q||	 | j¡ W d   ƒ d S W d   ƒ d S 1 s§w   Y  d S )	N)rD   FzEThis operation cannot proceed in --sql mode; batch mode with dialect zF requires a live database connection with which to reflect the table "zØ". To generate a batch SQL migration script using table "move and copy", a complete Table object should be passed to the "copy_from" argument of the batch_alter_table() method so that table reflection can be skipped.)r   Úautoload_withT)rE   )rP   r   rB   Ú
connectionrF   Úgetattrr4   rD   r   r8   Úmigration_contextÚas_sqlr   ÚCommandErrorrL   Únamer5   r   r<   r   Úget_bindr=   ÚApplyBatchImplr9   r;   rE   Ú_create)
rG   Úshould_recreateÚopnameÚargÚkwÚfnÚm1Úexisting_tableÚ	reflectedÚ
batch_implr2   r2   rH   Úflushl   s`   þ


þüÿþûüúú
Ì"þzBatchOperationsImpl.flushc                 O  ó   | j  d||f¡ d S )NÚalter_column©rF   rA   ©rG   r^   r_   r2   r2   rH   rg   ¥   ó   z BatchOperationsImpl.alter_columnc                 O  s8   d|v sd|v r|   ¡ st d¡‚| j d||f¡ d S )NÚinsert_beforeÚinsert_afterz^Can't specify insert_before or insert_after when using ALTER; please specify recreate='always'Ú
add_column)rP   r   rW   rF   rA   ri   r2   r2   rH   rm   ¨   s   ÿÿzBatchOperationsImpl.add_columnc                 O  rf   )NÚdrop_columnrh   ri   r2   r2   rH   rn   ²   rj   zBatchOperationsImpl.drop_columnÚconstr*   c                 C  ó   | j  d|fi f¡ d S )NÚadd_constraintrh   ©rG   ro   r2   r2   rH   rq   µ   ó   z"BatchOperationsImpl.add_constraintc                 C  rp   )NÚdrop_constraintrh   rr   r2   r2   rH   rt   ¸   rs   z#BatchOperationsImpl.drop_constraintc                 O  rf   )NÚrename_tablerh   ri   r2   r2   rH   ru   »   rj   z BatchOperationsImpl.rename_tableÚidxr   r_   r   c                 K  ó   | j  d|f|f¡ d S )NÚcreate_indexrh   ©rG   rv   r_   r2   r2   rH   rx   ¾   rs   z BatchOperationsImpl.create_indexc                 K  rw   )NÚ
drop_indexrh   ry   r2   r2   rH   rz   Á   rs   zBatchOperationsImpl.drop_indexc                 C  rp   )NÚcreate_table_commentrh   ©rG   Útabler2   r2   rH   r{   Ä   rs   z(BatchOperationsImpl.create_table_commentc                 C  rp   )NÚdrop_table_commentrh   r|   r2   r2   rH   r~   Ç   rs   z&BatchOperationsImpl.drop_table_commentc                 C  ó   t dƒ‚)Nz Can't create table in batch mode©ÚNotImplementedErrorr|   r2   r2   rH   Úcreate_tableÊ   ó   z BatchOperationsImpl.create_tablec                 C  r   )NzCan't drop table in batch moder€   r|   r2   r2   rH   Ú
drop_tableÍ   rƒ   zBatchOperationsImpl.drop_tablec                 C  rp   )NÚcreate_column_commentrh   ©rG   Úcolumnr2   r2   rH   r…   Ð   rs   z)BatchOperationsImpl.create_column_commentN)rJ   r&   )rJ   r,   )rJ   rN   ©rJ   rQ   ©ro   r*   rJ   rQ   )rv   r   r_   r   rJ   rQ   )Ú__name__Ú
__module__Ú__qualname__rI   ÚpropertyrL   rB   rP   re   rg   rm   rn   rq   rt   ru   rx   rz   r{   r~   r‚   r„   r…   r2   r2   r2   rH   r-   6   s*    %


9






r-   c                   @  sè   e Zd Z	dZd[dd„Zed\dd„ƒZd]dd„Zd]dd„Zd]dd„Zd^dd„Z	d_d#d$„Z
d`d&d'„Z	(	)	(	(	(	)dadbd8d9„Zdcd=d>„Z	(	(dddedAdB„ZdfdDdE„ZdFdG„ ZdHdI„ ZdJdK„ ZdgdNdO„ZdgdPdQ„ZdhdTdU„ZdhdVdW„ZdXdY„ Zd(S )irZ   r2   rB   r,   r}   r   r9   Útupler;   úDict[str, Any]rc   rN   rE   rJ   rQ   c                 C  sn   || _ || _|| _|| _|  |j¡| _d | _|| _d| _	t
dd„ | jjD ƒƒ| _t| jƒ| _|| _|  ¡  d S )Nr2   c                 s  s   � | ]
}|j d |ifV  qdS ©ÚexprN)rX   ©Ú.0Úcr2   r2   rH   Ú	<genexpr>ê   ó   € 
ÿz*ApplyBatchImpl.__init__.<locals>.<genexpr>)rB   r}   r9   r;   Ú_calc_temp_namerX   Útemp_table_nameÚ	new_tablerE   Úadd_col_orderingr   r”   Úcolumn_transfersr?   Úexisting_orderingrc   Ú_grab_table_elements)rG   rB   r}   r9   r;   rc   rE   r2   r2   rH   rI   Õ   s   	þ
ÿzApplyBatchImpl.__init__Ú	tablenameúUnion[quoted_name, str]Ústrc                 C  s   d| dd… S )Nz_alembic_tmp_%sr   é2   r2   )Úclsrž   r2   r2   rH   r—   ò   s   zApplyBatchImpl._calc_temp_namec                 C  sH  | j j}tƒ | _| j jD ]"}t||d�}d |_|_t|j	t
ƒr(|j	|j	us(J ‚|| j|j< qi | _g | _i | _i | _i | _| j jD ]%}t|ƒrIqB| jrUt|tƒrU|jsUqBt|jƒra|| j|j< qB| j |¡ qB| jsƒ| j jD ]}|jD ]}|jr�||f| j|j< qtqo| j jD ]}|| j|j< q‡| j jD ]}| j || j j| ¡ q”d S )Nr   F)r}   r   r   Úcolumnsr”   r   ÚuniqueÚindexÚ
isinstanceÚtyper   rX   Únamed_constraintsÚunnamed_constraintsÚcol_named_constraintsÚindexesÚnew_indexesÚconstraintsr    rc   r
   r$   rA   Úkwargsr;   r>   )rG   r   r”   Úc_copyro   Úcolrv   Úkr2   r2   rH   r�   ö   sL   ÿþý

€þÿz#ApplyBatchImpl._grab_table_elementsc                   sè   t ƒ }tˆ jƒ}ˆ jr*ˆ jD ]}t|ƒD ]\}}|dkr'| ||d  |f¡ qqntˆ jƒD ]\}}|dkrB| ||d  |f¡ q/| ˆ j¡ dd„ |D ƒ}tt	j
||dd�ƒ}t‡ fdd„|D ƒƒˆ _t‡ fd	d„|D ƒƒˆ _d S )
Nr   é   c                 S  s    g | ]}|d  |d kr|‘qS )r   r²   r2   )r“   Úpr2   r2   rH   Ú
<listcomp>8  s     zNApplyBatchImpl._adjust_self_columns_for_partial_reordering.<locals>.<listcomp>T)Údeterministic_orderc                 3  ó   � | ]
}|ˆ j | fV  qd S rK   )r£   ©r“   r±   rM   r2   rH   r•   =  s   € zMApplyBatchImpl._adjust_self_columns_for_partial_reordering.<locals>.<genexpr>c                 3  r¶   rK   )r›   r·   rM   r2   rH   r•   >  r–   )Úsetr?   r£   rE   Ú	enumerateÚaddrœ   Úupdaterš   r   Úsortr   r›   )rG   ÚpairsÚ
col_by_idxÚtuple_r¥   ÚelemÚ
pairs_listÚsorted_r2   rM   rH   Ú+_adjust_self_columns_for_partial_reordering$  s.   

€þÿ€ÿÿz:ApplyBatchImpl._adjust_self_columns_for_partial_reorderingc                 C  s  | j d u s	J dƒ‚tƒ }| jj}| js| jr|  ¡  t| j|gt	| j
 ¡ ƒt	| jƒ ¢R d|i| j¤Ž | _ }t	| j ¡ ƒ| j D ]B}dd„ t|ƒD ƒ}| | j¡sSqAt|tƒrlt|ƒret||| jd�}nt||d�}nt|||d�}t|tƒr~|  ||¡ | |¡ qAd S )NzCan only create new table oncer   c                 S  s   h | ]}|j ’qS r2   )Úkeyr’   r2   r2   rH   Ú	<setcomp>V  s    zAApplyBatchImpl._transfer_elements_to_new_table.<locals>.<setcomp>)r   Útarget_tabler   )r™   r   r}   r   rE   rš   rÃ   r   r˜   r?   r£   Úvaluesr9   r;   r¨   r©   r   Úissubsetr›   r¦   r   r   r   Ú_setup_referentÚappend_constraint)rG   Úmr   r™   ro   Úconst_columnsÚ
const_copyr2   r2   rH   Ú_transfer_elements_to_new_tableB  sB   þýüû	ÿ
ÿÿ
áz.ApplyBatchImpl._transfer_elements_to_new_tableúList[Index]c                   s¸   ˆ j d usJ ‚g }ˆ j ¡ D ]&}|jrqt|jg‡ fdd„t|ƒD ƒ¢R |jˆ j dœ|j¤Ž}| 	|¡ qˆ j
 ¡ D ]}| 	t|jg‡ fdd„|j ¡ D ƒ¢R d|ji|j¤Ž¡ q:|S )Nc                   s   g | ]}t |ˆ jƒ‘qS r2   )r   r™   )r“   r‘   rM   r2   rH   r´   �  ó    
ÿÿzCApplyBatchImpl._gather_indexes_from_both_tables.<locals>.<listcomp>)r¤   Ú_tablec                   s   g | ]}ˆ j j| ‘qS r2   )r™   r”   )r“   r°   rM   r2   rH   r´   �  s    r¤   )r™   r«   rÇ   Ú_column_flagr   rX   r   r¤   r®   rA   r¬   r£   Úkeys)rG   rv   Úidx_existingÚidx_copyr¥   r2   rM   rH   Ú _gather_indexes_from_both_tablest  s>   ÿ
þýùø
ÿýþüÿz/ApplyBatchImpl._gather_indexes_from_both_tablesÚmetadatar   Ú
constraintr   c                   sæ   |j d  ¡ }| d¡}|d }t|ƒdkr|d }nd }|| jkrqt ||¡}ddd„‰ ||jv rV|j| }|j D ]}	ˆ |	ƒ d¡d	 }
|
|jvrS| 	t
|
tjƒ¡ q:d S t||gd
d„ ‡ fdd„|j D ƒD ƒ¢R d|iŽ d S d S )Nr   Ú.éþÿÿÿé   rÀ   r   c                 S  s   |   ¡ S rK   )Ú_get_colspec)rÀ   r2   r2   rH   Úcolspec£  rƒ   z/ApplyBatchImpl._setup_referent.<locals>.colspecéÿÿÿÿc                 S  s   g | ]}t |tjƒ‘qS r2   )r   ÚsqltypesÚNULLTYPE)r“   Únr2   r2   rH   r´   °  rÐ   z2ApplyBatchImpl._setup_referent.<locals>.<listcomp>c                   s   g | ]}ˆ |ƒ  d ¡d ‘qS )rÙ   rÞ   )Úsplit)r“   rÀ   ©rÝ   r2   rH   r´   ²  s    ÿÿr   )rÀ   r   )ÚelementsrÜ   râ   Úlenr˜   Ú
sql_schemaÚ_get_table_keyÚtablesr”   Úappend_columnr   rß   rà   r   )rG   r×   rØ   ÚspecÚpartsÚtnameÚreferent_schemarÄ   ÚtrÀ   Úcolnamer2   rã   rH   rÉ   •  s<   







€ýþ
þþý

öózApplyBatchImpl._setup_referentÚop_implc              	   C  sö   |   ¡  | | | j¡ | jd usJ ‚| | j¡ z*| | j ¡  ¡  t	dd„ | j
 ¡ D ƒƒtdd„ | j
 ¡ D ƒŽ ¡¡ | | j¡ W n
   | | j¡ ‚ |j| j| jj| jjd� | jj| j_z|  ¡ D ]}| |¡ qeW | j| j_d S | j| j_w )Nc                 s  s    � | ]\}}d |v r|V  qdS r�   r2   )r“   r±   Útransferr2   r2   rH   r•   Æ  s   € þýz)ApplyBatchImpl._create.<locals>.<genexpr>c                 S  s   g | ]
}d |v r|d  ‘qS )r‘   r2   )r“   rñ   r2   r2   rH   r´   Ì  s
    þz*ApplyBatchImpl._create.<locals>.<listcomp>r   )rÎ   Úprep_table_for_batchr}   r™   r‚   Ú_execÚinsertÚinlineÚfrom_selectr?   r›   Úitemsr   rÇ   r„   ru   r˜   rX   r   rÖ   rx   )rG   rð   rv   r2   r2   rH   r[   º  s@   þþÿúýÿÿzApplyBatchImpl._createNFr5   Úcolumn_nameÚnullableúOptional[bool]Úserver_defaultú)Optional[Union[Function[Any], str, bool]]rX   úOptional[str]Útype_úOptional[TypeEngine]Úautoincrementú&Optional[Union[bool, Literal['auto']]]ÚcommentúUnion[str, Literal[False]]c	                 K  s  | j | }
| j| }|d ur:||kr:||
_||d< |	 dd ¡}|r:t|	d | jjƒ}t|tƒr:|jr:| j	 
|jd ¡ |d ur\t |¡}t|
jtƒrQd |
j_|
j_| j |
||¡ ||
_|d urc||
_|durw|d u rod |
_nt |¡ |
¡ |d ur€t|ƒ|
_|dur‰||
_d S d S )NrX   Úexisting_typeF)r£   r›   rX   r@   r"   rB   rL   r¦   r   r¨   Úpoprß   Úto_instancer§   Ú_create_eventsÚcreate_constraintÚcast_for_batch_migraterù   rû   ræ   ÚDefaultClauseÚ_set_parentrN   r   r  )rG   r5   rø   rù   rû   rX   rþ   r   r  r_   ÚexistingÚexisting_transferr  Úresolved_existing_typer2   r2   rH   rg   ã  sT   

ÿÿþþ
þÿÿ

ÿzApplyBatchImpl.alter_columnrï   rk   rl   c                 C  s  | j }dd„ t|ƒD ƒ}| jsP|r/|s/||v r(|| d }|t|ƒk r'|| }nt| jƒ| }|rP|sP||v rF|| d }|dkrE|| }n
dd„ | jD ƒ| }|r\|  j||ff7  _|rh|  j||ff7  _| js|s�|sƒ|r…|  j|d |ff7  _d S d S d S d S d S )Nc                 S  ó   i | ]\}}||“qS r2   r2   )r“   ÚirX   r2   r2   rH   Ú
<dictcomp>5  s    zEApplyBatchImpl._setup_dependencies_for_add_column.<locals>.<dictcomp>r²   r   c                 S  r  r2   r2   )r“   ÚaÚbr2   r2   rH   r  M  s    
ÿrÞ   )rœ   r¹   rE   rå   r:   rš   )rG   rï   rk   rl   Ú
index_colsÚcol_indexesrv   r2   r2   rH   Ú"_setup_dependencies_for_add_column.  sN   €ÿ€ÿþÿþýüúz1ApplyBatchImpl._setup_dependencies_for_add_columnr‡   úColumn[Any]c                 K  s8   |   |j||¡ t|| jjd�| j|j< i | j|j< d S )Nr   )r  rX   r   r}   r   r£   r›   )rG   r5   r‡   rk   rl   r_   r2   r2   rH   rm   ^  s
   ÿzApplyBatchImpl.add_columnú%Union[ColumnClause[Any], Column[Any]]c                 K  s†   |j | jjjv rt| jjj|ƒ | j|j = | j|j = | j |j ¡ d|v r=t|d t	ƒr?|d j rA| j
 |d j d ¡ d S d S d S d S )Nr  )rX   r}   Úprimary_keyr£   r!   r›   rœ   Úremover¦   r   r¨   r  )rG   r5   r‡   r_   r2   r2   rH   rn   n  s    
ÿ

ÿþ
ÿüzApplyBatchImpl.drop_columnc                 C  ó   dS )a^  the batch table creation function will issue create_column_comment
        on the real "impl" as part of the create table process.

        That is, the Column object will have the comment on it already,
        so when it is received by add_column() it will be a normal part of
        the CREATE TABLE and doesn't need an extra step here.

        Nr2   r†   r2   r2   rH   r…   †  ó    z$ApplyBatchImpl.create_column_commentc                 C  r  )z‹the batch table creation function will issue create_table_comment
        on the real "impl" as part of the create table process.

        Nr2   r|   r2   r2   rH   r{   �  r  z#ApplyBatchImpl.create_table_commentc                 C  r  )z‰the batch table creation function will issue drop_table_comment
        on the real "impl" as part of the create table process.

        Nr2   r|   r2   r2   rH   r~   –  r  z!ApplyBatchImpl.drop_table_commentro   r*   c                 C  sf   t |jƒs	tdƒ‚t|tjƒr| jj| jv r| j 	| jj¡ t
|jƒr+|| j|j< d S | j |¡ d S )NúConstraint must have a name)r#   rX   r6   r¦   ræ   r   r}   r  r©   r  r$   r¨   rA   rr   r2   r2   rH   rq   œ  s   

zApplyBatchImpl.add_constraintc                 C  sò   |j stdƒ‚zF|j | jv r4| j |j ¡\}}t| j|j  jƒD ]}|j |j kr2| j|j  j |¡ q nt|j ƒrA| j	 |j ¡}n|| j
v rL| j
 |¡ W n tyb   t|ƒr[Y d S td|j  ƒ‚w t|tƒru|jD ]}d| j|j  _qkd S d S )Nr  zNo such constraint: '%s'F)rX   r6   rª   r  r?   r£   r­   r  r$   r¨   r©   ÚKeyErrorr    r¦   r   r  )rG   ro   r°   Ú	col_constr2   r2   rH   rt   ¨  s2   €þ

€ù
	
þzApplyBatchImpl.drop_constraintrv   r   c                 C  s   || j |j< d S rK   )r¬   rX   ©rG   rv   r2   r2   rH   rx   Ä  s   zApplyBatchImpl.create_indexc                 C  s.   z| j |j= W d S  ty   td|j ƒ‚w )NzNo such index: '%s')r«   rX   r  r6   r   r2   r2   rH   rz   Ç  s
   ÿzApplyBatchImpl.drop_indexc                 O  r   )NÚTODOr€   ri   r2   r2   rH   ru   Í  rƒ   zApplyBatchImpl.rename_table)r2   )rB   r,   r}   r   r9   rŽ   r;   r�   rc   rN   rE   rŽ   rJ   rQ   )rž   rŸ   rJ   r    rˆ   )rJ   rÏ   )r×   r   rØ   r   rJ   rQ   )rð   r,   rJ   rQ   )NFNNNF)r5   r    rø   r    rù   rú   rû   rü   rX   rý   rþ   rÿ   r   r  r  r  rJ   rQ   )rï   r    rk   rý   rl   rý   rJ   rQ   )NN)
r5   r    r‡   r  rk   rý   rl   rý   rJ   rQ   )r5   r    r‡   r  rJ   rQ   r‰   )rv   r   rJ   rQ   )rŠ   r‹   rŒ   rI   Úclassmethodr—   r�   rÃ   rÎ   rÖ   rÉ   r[   rg   r  rm   rn   r…   r{   r~   rq   rt   rx   rz   ru   r2   r2   r2   rH   rZ   Ô   s>    ù

.

2
!
%-÷
K4û





rZ   N)9Ú
__future__r   Útypingr   r   r   r   r   r   r	   Ú
sqlalchemyr
   r   r   r   r   r   r   ræ   r   r   r   rß   Úsqlalchemy.sql.schemar   Úsqlalchemy.utilr   r   Úutilr   Úutil.sqla_compatr   r   r   r   r   r   r    r!   r"   r#   r$   r%   Úsqlalchemy.enginer&   Úsqlalchemy.sql.elementsr'   r(   Úsqlalchemy.sql.functionsr)   r*   Úsqlalchemy.sql.type_apir+   Úddl.implr,   r-   rZ   r2   r2   r2   rH   Ú<module>   sZ    