o
    il                     @   s  U d dl mZ d dlZd dlZd dlZd dlmZmZm	Z
mZmZ dZdZzd dlZd dlmZ W n eyD   G dd dZe ZY nw d dlmZ eejedkZeejed	kZ[[d
Zi Zeed< dd Zdd Zdd Z dd Z!e ejd;ddddZe ej"d;ddddZ"e ej#d<ddddZ#e ej$d<ddddZ$e ej%d=dddd Z%e ej&d=ddd!d"Z&e ej'd;ddd#d$Z'e ej(d;ddd%d&Z(e ej)d<ddd'd(Z)e ej*d<ddd)d*Z*e ej+d=ddd+d,Z+e ej,d=ddd-d.Z,e ej	d;ddd/d0Z	e ejd;ddd1d2Ze ej-d<ddd3d4Z-e ej.d<ddd5d6Z.e ej/d=ddd7d8Z/e ej0d=ddd9d:Z0dS )>    )NumberN)_fft_default_fft_funchfftihfft_swap_directionFc                   @   s   e Zd Zdd ZdS )_DummyModulec                 C   s   d S N )selfnamer
   r
   Q/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/cupyx/scipy/fft/_fft.py__getattr__   s   z_DummyModule.__getattr__N)__name__
__module____qualname__r   r
   r
   r
   r   r      s    r   )NumpyVersionz1.5.0z1.6.0znumpy.scipy.fft_implementedc                 C   s\   |rz	dd | D }W n t y   t Y S w dd | D }tdd t|| D s,tS |S )Nc                 S   s0   g | ]}|j r|jtju rt|jn|jqS r
   )	coercibletypenpndarraycupyasarrayvalue.0dr
   r
   r   
<listcomp>&   s
    z"__ua_convert__.<locals>.<listcomp>c                 S   s   g | ]}|j qS r
   )r   r   r
   r
   r   r   ,   s    c                 s   s,    | ]\}}|j tjupt|tjV  qd S r	   )r   r   r   
isinstancer   )r   rr   r
   r
   r   	<genexpr>.   s     z!__ua_convert__.<locals>.<genexpr>)	TypeErrorNotImplementedallzip)dispatchablescoercereplacedr
   r
   r   __ua_convert__#   s   
r)   c                 C   s<   t | d }|d u rtS d|v rtstd ||i |S )Nplanz1The 'plan' argument is supported in SciPy v1.5.0+)r   getr#   
_scipy_150warningswarn)methodargskwargsfnr
   r
   r   __ua_function__5   s   
r3   c                    s    fdd}|S )zBDecorator adds function to the dictionary of implemented functionsc                    s   | t  < | S r	   )r   )func
scipy_funcr
   r   inner@   s   z_implements.<locals>.innerr
   )r6   r7   r
   r5   r   _implements>   s   r8   c                 C   s   t | tr| fS | S )zEConvert scalars to a sequence, otherwise pass through ``x`` unchanged)r   r   )xr
   r
   r   _assequenceG   s   
r:   r*   c             	   C   (   ddl m} t| |f|f||j||dS )a  Compute the one-dimensional FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        n (None or int): Length of the transformed axis of the output. If ``n``
            is not given, the length of the input along the axis specified by
            ``axis`` is used.
        axis (int): Axis over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.Plan1d` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axis``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, n, axis)

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``n`` and type
            will convert to complex if that of the input is another.

    .. seealso:: :func:`scipy.fft.fft`
    r   cufftoverwrite_xr*   	cupy.cudar?   r   CUFFT_FORWARDr9   naxisnormrA   r*   r?   r
   r
   r   fftN      rI   c             	   C   r=   )a  Compute the one-dimensional inverse FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        n (None or int): Length of the transformed axis of the output. If ``n``
            is not given, the length of the input along the axis specified by
            ``axis`` is used.
        axis (int): Axis over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.Plan1d` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axis``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, n, axis)

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``n`` and type
            will convert to complex if that of the input is another.

    .. seealso:: :func:`scipy.fft.ifft`
    r   r>   r@   rC   r?   r   CUFFT_INVERSErE   r
   r
   r   ifftp   rJ   rM   r;   c                C      t | |||||dS )a  Compute the two-dimensional FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the transformed axes of the
            output. If ``s`` is not given, the lengths of the input along
            the axes specified by ``axes`` are used.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes)

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and
            type will convert to complex if that of the input is another.

    .. seealso:: :func:`scipy.fft.fft2`
    r<   )fftnr9   saxesrH   rA   r*   r
   r
   r   fft2   s   rU   c                C   rP   )a  Compute the two-dimensional inverse FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the transformed axes of the
            output. If ``s`` is not given, the lengths of the input along
            the axes specified by ``axes`` are used.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes)

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and
            type will convert to complex if that of the input is another.

    .. seealso:: :func:`scipy.fft.ifft2`
    r<   )ifftnrR   r
   r
   r   ifft2   s   rW   c             	   C   @   ddl m} t|}t|}t| ||}|| ||||j||dS )a  Compute the N-dimensional FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the transformed axes of the
            output. If ``s`` is not given, the lengths of the input along
            the axes specified by ``axes`` are used.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes)

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and
            type will convert to complex if that of the input is another.

    .. seealso:: :func:`scipy.fft.fftn`
    r   r>   r@   rC   r?   r:   r   rD   r9   rS   rT   rH   rA   r*   r?   r4   r
   r
   r   rQ         rQ   c             	   C   rX   )a  Compute the N-dimensional inverse FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the transformed axes of the
            output. If ``s`` is not given, the lengths of the input along
            the axes specified by ``axes`` are used.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes)

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and
            type will convert to complex if that of the input is another.

    .. seealso:: :func:`scipy.fft.ifftn`
    r   r>   r@   rC   r?   r:   r   rL   rZ   r
   r
   r   rV      r[   rV   c             
   C   *   ddl m} t| |f|f||jd||dS )a)  Compute the one-dimensional FFT for real input.

    The returned array contains the positive frequency components of the
    corresponding :func:`fft`, up to and including the Nyquist frequency.

    Args:
        x (cupy.ndarray): Array to be transformed.
        n (None or int): Length of the transformed axis of the output. If ``n``
            is not given, the length of the input along the axis specified by
            ``axis`` is used.
        axis (int): Axis over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.Plan1d` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axis``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, n, axis,
                                                        value_type='R2C')

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array.

    .. seealso:: :func:`scipy.fft.rfft`

    r   r>   R2Cr@   rB   rE   r
   r
   r   rfft  s   !r_   c             
   C   r]   )a  Compute the one-dimensional inverse FFT for real input.

    Args:
        x (cupy.ndarray): Array to be transformed.
        n (None or int): Length of the transformed axis of the output. If ``n``
            is not given, the length of the input along the axis specified by
            ``axis`` is used.
        axis (int): Axis over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.Plan1d` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axis``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, n, axis,
                                                        value_type='C2R')

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array.

    .. seealso:: :func:`scipy.fft.irfft`
    r   r>   C2Rr@   rK   rE   r
   r
   r   irfftF  s   ra   c                C   rP   )aI  Compute the two-dimensional FFT for real input.

    Args:
        a (cupy.ndarray): Array to be transform.
        s (None or tuple of ints): Shape to use from the input. If ``s`` is not
            given, the lengths of the input along the axes specified by
            ``axes`` are used.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes,
                                                        value_type='R2C')

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and type
            will convert to complex if the input is other. The length of the
            last axis transformed will be ``s[-1]//2+1``.

    .. seealso:: :func:`scipy.fft.rfft2`
    r<   )rfftnrR   r
   r
   r   rfft2h  s    rc   c                C   rP   )a  Compute the two-dimensional inverse FFT for real input.

    Args:
        a (cupy.ndarray): Array to be transform.
        s (None or tuple of ints): Shape of the output. If ``s`` is not given,
            they are determined from the lengths of the input along the axes
            specified by ``axes``.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes,
                                                        value_type='C2R')

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and type
            will convert to complex if the input is other. If ``s`` is not
            given, the length of final transformed axis of output will be
            `2*(m-1)` where `m` is the length of the final transformed axis of
            the input.

    .. seealso:: :func:`scipy.fft.irfft2`
    r<   )irfftnrR   r
   r
   r   irfft2  s   "re   c             
   C   F   ddl m} t|}t|}t| ||dd}|| ||||jd||dS )aG  Compute the N-dimensional FFT for real input.

    Args:
        a (cupy.ndarray): Array to be transform.
        s (None or tuple of ints): Shape to use from the input. If ``s`` is not
            given, the lengths of the input along the axes specified by
            ``axes`` are used.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes,
                                                        value_type='R2C')

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and type
            will convert to complex if the input is other. The length of the
            last axis transformed will be ``s[-1]//2+1``.

    .. seealso:: :func:`scipy.fft.rfftn`
    r   r>   r^   
value_typer@   rY   rZ   r
   r
   r   rb     s   rb   c             
   C   rf   )a  Compute the N-dimensional inverse FFT for real input.

    Args:
        a (cupy.ndarray): Array to be transform.
        s (None or tuple of ints): Shape of the output. If ``s`` is not given,
            they are determined from the lengths of the input along the axes
            specified by ``axes``.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, s, axes,
                                                        value_type='C2R')

            Note that ``plan`` is defaulted to ``None``, meaning CuPy will use
            an auto-generated plan behind the scene.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``s`` and type
            will convert to complex if the input is other. If ``s`` is not
            given, the length of final transformed axis of output will be
            ``2*(m-1)`` where `m` is the length of the final transformed axis
            of the input.

    .. seealso:: :func:`scipy.fft.irfftn`
    r   r>   r`   rg   r@   r\   rZ   r
   r
   r   rd     s   !rd   c                C      |durt dt| |||S )a  Compute the FFT of a signal that has Hermitian symmetry.

    Args:
        a (cupy.ndarray): Array to be transform.
        n (None or int): Length of the transformed axis of the output. For
            ``n`` output points, ``n//2+1`` input points are necessary. If
            ``n`` is not given, it is determined from the length of the input
            along the axis specified by ``axis``.
        axis (int): Axis over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (None): This argument is currently not supported.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``n`` and type
            will convert to complex if the input is other. If ``n`` is not
            given, the length of the transformed axis is ``2*(m-1)`` where `m`
            is the length of the transformed axis of the input.

    .. seealso:: :func:`scipy.fft.hfft`
    Nz(hfft plan is currently not yet supported)NotImplementedError_hfftr9   rF   rG   rH   rA   r*   r
   r
   r   r     s   r   c                C   ri   )a  Compute the FFT of a signal that has Hermitian symmetry.

    Args:
        a (cupy.ndarray): Array to be transform.
        n (None or int): Number of points along transformation axis in the
            input to use. If ``n`` is not given, the length of the input along
            the axis specified by ``axis`` is used.
        axis (int): Axis over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (None): This argument is currently not supported.

    Returns:
        cupy.ndarray:
            The transformed array which shape is specified by ``n`` and type
            will convert to complex if the input is other. The length of the
            transformed axis is ``n//2+1``.

    .. seealso:: :func:`scipy.fft.ihfft`
    Nz)ihfft plan is currently not yet supported)rj   _ihfftrl   r
   r
   r   r   "  s   r   c                C   &   |durt dt|  ||t|S )a"  Compute the FFT of a two-dimensional signal that has Hermitian symmetry.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the real output.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
            (This argument is currently not supported)
        plan (None): This argument is currently not supported.

    Returns:
        cupy.ndarray:
            The real result of the 2-D Hermitian complex real FFT.

    .. seealso:: :func:`scipy.fft.hfft2`
    Nz)hfft2 plan is currently not yet supported)rj   re   conjr   rR   r
   r
   r   hfft2@     rp   c                C   &   |durt dt| ||t| S )a7  Compute the Inverse FFT of a two-dimensional signal that has Hermitian
    symmetry.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the real output.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
            (This argument is currently not supported)
        plan (None): This argument is currently not supported.

    Returns:
        cupy.ndarray:
            The real result of the 2-D Hermitian inverse complex real FFT.

    .. seealso:: :func:`scipy.fft.ihfft2`
    Nz*ihfft2 plan is currently not yet supported)rj   rc   r   ro   rR   r
   r
   r   ihfft2[     rs   c                C   rn   )a   Compute the FFT of a N-dimensional signal that has Hermitian symmetry.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the real output.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
            (This argument is currently not supported)
        plan (None): This argument is currently not supported.

    Returns:
        cupy.ndarray:
            The real result of the N-D Hermitian complex real FFT.

    .. seealso:: :func:`scipy.fft.hfftn`
    Nz)hfftn plan is currently not yet supported)rj   rd   ro   r   rR   r
   r
   r   hfftnw  rq   ru   c                C   rr   )a5  Compute the Inverse FFT of a N-dimensional signal that has Hermitian
    symmetry.

    Args:
        x (cupy.ndarray): Array to be transformed.
        s (None or tuple of ints): Shape of the real output.
        axes (tuple of ints): Axes over which to compute the FFT.
        norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
            to specify the normalization mode. Default is ``None``, which is
            an alias of ``"backward"``.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
            (This argument is currently not supported)
        plan (None): This argument is currently not supported.

    Returns:
        cupy.ndarray:
            The real result of the N-D Hermitian inverse complex real FFT.

    .. seealso:: :func:`scipy.fft.ihfftn`
    Nz*ihfftn plan is currently not yet supported)rj   rb   r   ro   rR   r
   r
   r   ihfftn  rt   rv   )Nr;   NF)NrN   NF)NNNF)1numbersr   r-   numpyr   r   cupy.fft._fftr   r   r   rk   r   rm   r   r,   
_scipy_160scipy	scipy.fftrI   
_scipy_fftImportErrorr   	numpy.libr   Version__version____ua_domain__r   dict__annotations__r)   r3   r8   r:   rM   rU   rW   rQ   rV   r_   ra   rc   re   rb   rd   rp   rs   ru   rv   r
   r
   r
   r   <module>   s    
		!! %%&!"$')