U
    ;gN@                     @   s  U d dl 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 d dlmZ d dlmZmZmZ d dlmZ d dlmZ eeee   Zi Zeeef ed< dd	d
Zdd Zdd Zdd Zdd Z G dd deZ!e
dedZ"e
dedZ#G dd dee" Z$dS )    N)bisect_left)	DictGenericList
NamedTupleOptionalTypeTypeVarcastoverload)Literal)	constants
exceptionsutil)	BaseImage)
PyPNGImageprecomputed_qr_blanksc                 K   s   t f |}||  | S N)QRCodeadd_data
make_image)datakwargsqr r   //tmp/pip-unpacked-wheel-ij2mbwps/qrcode/main.pymake   s    

r   c                 C   s    t | dkrtd|  dd S )Nr   zInvalid box size (was z, expected larger than 0)int
ValueErrorsizer   r   r   _check_box_size    s    r"   c                 C   s   t | dk rtd|  d S )Nr   z=Invalid border value (was %s, expected 0 or larger than that)r   r    r   r   r   _check_border%   s    r#   c                 C   sN   | d krd S t | ts*tdt|  d| dk s:| dkrJtd|  dd S )NzInvalid mask pattern (was z, expected int)r      z(Mask pattern should be in range(8) (got ))
isinstancer   	TypeErrortyper   )mask_patternr   r   r   _check_mask_pattern,   s    
r*   c                 C   s   dd | D S )Nc                 S   s   g | ]}|d d  qS r   r   ).0rowr   r   r   
<listcomp>8   s     z!copy_2d_array.<locals>.<listcomp>r   )xr   r   r   copy_2d_array7   s    r/   c                   @   sd   e Zd ZU eed< eed< eed< eed< eed< eed< eed< eed< eed	< ed
ddZdS )ActiveWithNeighborsZNWNZNEWmeEZSWSZSEreturnc                 C   s   | j S r   )r3   selfr   r   r   __bool__F   s    zActiveWithNeighbors.__bool__N)__name__
__module____qualname__bool__annotations__r:   r   r   r   r   r0   ;   s   
r0   GenericImage)boundGenericImageLocalc                   @   sp  e Zd ZU eed< dZee ed< dej	ddddfee
e  dddZeed	d
dZejdd	ddZedd Zejdd Zdd Zd;ddZd<ddZdd Zdd Zd=ddZdd Zd>d d!Zd?d#d$Zed@ed ed%d&d'ZedAe
e ed%d(d'ZdBd)d'Zeeed*d+d,Zd-d. Z d/d0 Z!d1d2 Z"d3d4 Z#d5d6 Z$d7d8 Z%eee&d*d9d:Z'dS )Cr   modulesN_version
      )image_factoryc                 C   sb   t | t| || _t|| _t|| _t|| _|| _|| _|d k	rVt	|t
sVt|   d S r   )r"   r#   versionr   error_correctionbox_sizeborderr)   rG   
issubclassr   AssertionErrorclear)r9   rH   rI   rJ   rK   rG   r)   r   r   r   __init__R   s    	


zQRCode.__init__r6   c                 C   s   | j d kr|   tt| j S r   )rD   best_fitr
   r   r8   r   r   r   rH   i   s    
zQRCode.versionc                 C   s$   |d k	rt |}t| || _d S r   )r   r   check_versionrD   )r9   valuer   r   r   rH   o   s    
c                 C   s   | j S r   )_mask_patternr8   r   r   r   r)   v   s    zQRCode.mask_patternc                 C   s   t | || _d S r   )r*   rS   )r9   patternr   r   r   r)   z   s    c                 C   s   g g| _ d| _d| _g | _dS )z*
        Reset the internal data.
        r   N)rC   modules_count
data_cache	data_listr8   r   r   r   rN      s    zQRCode.clear   c                 C   sR   t |tjr| j| n.|r6| jtj||d n| jt| d| _dS )a  
        Add data to this QR Code.

        :param optimize: Data will be split into multiple chunks to optimize
            the QR size by finding to more compressed modes of at least this
            length. Set to ``0`` to avoid optimizing at all.
        )ZminimumN)r&   r   ZQRDatarW   appendextendZoptimal_data_chunksrV   )r9   r   optimizer   r   r   r      s    zQRCode.add_dataTc                 C   sJ   |s| j dkr| j| j d | jdkr8| d|   n| d| j dS )z
        Compile the data into a QR Code array.

        :param fit: If ``True`` (or if a size has not been provided), find the
            best fit for the data to avoid data overflow errors.
        NstartF)rH   rP   r)   makeImplbest_mask_pattern)r9   Zfitr   r   r   r      s
    
zQRCode.makec                    s    j d d  _ j tkr,tt j   _nj fddt jD  _ dd   jd d  d jd        t jt j <  	||  j dkr 
|  jd krt j  j j _  j| d S )NrF      c                    s   g | ]}d g j  qS r   )rU   )r+   ir8   r   r   r-      s    z#QRCode.makeImpl.<locals>.<listcomp>r   r$   )rH   rU   r   r/   rC   rangesetup_position_probe_patternsetup_position_adjust_patternsetup_timing_patternsetup_type_infosetup_type_numberrV   r   Zcreate_datarI   rW   map_data)r9   testr)   r   r8   r   r^      s,    




  zQRCode.makeImplc                 C   s   t ddD ]}|| dks
| j|| kr*q
t ddD ]}|| dks4| j|| krTq4d|  krhdkrtn n|dksd|  krdkrn n|dksd|  krdkrn n0d|  krdkrn nd| j||  || < q4d	| j||  || < q4q
d S )
N   r      >   r   rl      rF   TFrb   rU   rC   )r9   r,   colrcr   r   r   rc      s@     
 
 
 
z#QRCode.setup_position_probe_patternc                 C   s   |dkrd}t | t |}t  }| jD ]2}||jd |t|||j  || q.t|}t	t j
| j ||| _| jdkrt |t | jk	r| j| jd | jS )zD
        Find the minimum size required to fit in the data.
        N   rF   )   r\   )r   rQ   Zmode_sizes_for_versionZ	BitBufferrW   putmodelenwriter   ZBIT_LIMIT_TABLErI   rH   r   ZDataOverflowErrorrP   )r9   r]   Z
mode_sizesbufferr   Zneeded_bitsr   r   r   rP      s(    



  
zQRCode.best_fitc                 C   sJ   d}d}t dD ]4}| d| t| j}|dks<||kr|}|}q|S )z7
        Find the most efficient mask pattern.
        r   rk   T)rb   r^   r   
lost_pointrC   )r9   Zmin_lost_pointrT   ra   ry   r   r   r   r_      s    zQRCode.best_mask_patternc                 C   s   |dkrddl }|j}| s&td| jdkr8|   | j}|dd|d d   d  t|D ]J}|d	 t|D ](}| j	| | r|d
 qz|d	 qz|d qd|dd|d d   d  |
  dS )zz
        Output the QR Code only using TTY colors.

        If the data has not been compiled yet, make it first.
        Nr   	Not a ttyz[1;47m rm   rF   z[0m
z[1;47m  [40mz  z[1;47m  [0m
)sysstdoutisattyOSErrorrV   r   rU   rw   rb   rC   flush)r9   outr|   modcountrp   rq   r   r   r   	print_tty  s$    

zQRCode.print_ttyFc           	         s&  |dkrt j}|r"| s"tdjdkr4  jdd dD }|rPd  r\|  td fdd	}t	j
 j
 d
D ]}|r r|j
 d k r|d |d t	j
 j
 D ].}|||||d |d>  }|||  q|r|d |d q|  dS )z
        Output the QR Code using ASCII characters.

        :param tty: use fixed TTY color codes (forces invert=True)
        :param invert: invert the ASCII characters (solid <-> transparent)
        Nrz   c                 S   s   g | ]}t |fd qS )cp437)bytesdecode)r+   coder   r   r   r-   5  s     z&QRCode.print_ascii.<locals>.<listcomp>)            Tr6   c                    sV    r"j r"t| |j  kr"dS t| |dk s>t| |krBdS ttj|  | S )Nrr   r   )rK   maxminr
   r   rC   )r.   yinvertr   r9   r   r   
get_module;  s
    z&QRCode.print_ascii.<locals>.get_modulerm   rr   z[48;5;232mz[38;5;255mz[0m
)r|   r}   r~   r   rV   r   rU   reverser   rb   rK   rw   r   )	r9   r   ttyr   codesr   rp   rq   posr   r   r   print_ascii$  s2    



zQRCode.print_ascii)rG   r7   c                 K   s   d S r   r   r9   rG   r   r   r   r   r   O  s    zQRCode.make_imagec                 K   s   d S r   r   r   r   r   r   r   S  s    c                 K   s   t | j | jdkr|   |dk	r4t|ts^tn*| j}|dkr^ddlm	}m
} |rZ|nt}|| j| j| jfd| ji|}|jrt| jD ]F}t| jD ]6}|jr|j||| d q| j| | r||| qq|jr|  |S )zu
        Make an image from the QR Code data.

        If the data has not been compiled yet, make it first.
        Nr   )ImagePilImageZqrcode_modules)r   )r"   rJ   rV   r   rL   r   rM   rG   Zqrcode.image.pilr   r   r   rK   rU   rC   Zneeds_drawrectrb   Zneeds_contextZdrawrect_contextZdrawrectZneeds_processingprocess)r9   rG   r   r   r   Zimrp   rq   r   r   r   r   Y  s8    

)r,   ro   r7   c                 C   s0   |dko.|t | jk o.|dko.|t | j| k S )Nr   )rv   rC   )r9   r,   ro   r   r   r   is_constrained  s    zQRCode.is_constrainedc                 C   s   t d| jd D ].}| j| d d k	r(q|d dk| j| d< qt d| jd D ].}| jd | d k	rhqP|d dk| jd |< qPd S )Nrk   rl   rm   r   rn   )r9   rp   rq   r   r   r   re     s    zQRCode.setup_timing_patternc                 C   s   t | j}tt|D ]}|| }tt|D ]}|| }| j| | d k	rPq0tddD ]r}tddD ]b}|dks|dks|dks|dks|dkr|dkrd| j||  || < qhd| j||  || < qhqZq0qd S )N   rm   r   TF)r   Zpattern_positionrH   rb   rv   rC   )r9   r   ra   r,   jro   rp   rq   r   r   r   rd     s.    z$QRCode.setup_position_adjust_patternc                 C   s   t | j}tdD ]>}| o,||? d@ dk}|| j|d  |d | j d d < qtdD ]>}| ot||? d@ dk}|| j|d | j d d  |d < q\d S )N   rr   r   rk   )r   ZBCH_type_numberrH   rb   rC   rU   )r9   ri   bitsra   modr   r   r   rg     s    &zQRCode.setup_type_numberc                 C   s"  | j d> |B }t|}tdD ]f}| o8||? d@ dk}|dk rR|| j| d< q |dk rn|| j|d  d< q || j| jd |  d< q tdD ]v}| o||? d@ dk}|dk r|| jd | j| d < q|dk r|| jd d| d d < q|| jd d| d < q| | j| jd  d< d S )Nr      rr   rl   rk   	   )rI   r   ZBCH_type_inforb   rC   rU   )r9   ri   r)   r   r   ra   r   r   r   r   rf     s"    
zQRCode.setup_type_infoc                 C   s  d}| j d }d}d}t|}t|}t| j d ddD ]}	|	dkrN|	d8 }	|	|	d f}
|
D ]p}| j| | d kr^d}||k r|| |? d@ dk}|||r| }|| j| |< |d8 }|dkr^|d7 }d}q^||7 }|dk s| j |krZ||8 }| }q:qZq:d S )Nrj   rr   r$   r   r   rl   F)rU   r   	mask_funcrv   rb   rC   )r9   r   r)   incr,   ZbitIndexZ	byteIndexr   data_lenro   Z	col_rangerq   Zdarkr   r   r   rh     s6    


zQRCode.map_datac                 C   s   | j dkr|   | js| jS t| j| jd  }dg| g| j }dg| j }| jD ] }||ttt | |  qV|dg| g| j 7 }|S )z
        Return the QR Code as a multidimensional array, including the border.

        To return the array without a border, set ``self.border`` to 0 first.
        Nrm   F)	rV   r   rK   rC   rv   rY   r
   r   r>   )r9   widthr   Zx_bordermoduler   r   r   
get_matrix	  s    

zQRCode.get_matrixc                 C   s`   g }t |d |d D ]@}t |d |d D ](}|| ||oPt| j| |  q,qt| S )Nrr   rm   )rb   rY   r   r>   rC   r0   )r9   r,   ro   contextrp   rq   r   r   r   active_with_neighbors  s
    (zQRCode.active_with_neighbors)rX   )T)N)N)NFF)N)N)N)(r;   r<   r=   ModulesTyper?   rD   r   r   r   ZERROR_CORRECT_Mr   r@   rO   propertyrH   setterr)   rN   r   r   r^   rc   rP   r_   r   r   r   r   r   rB   r>   r   re   rd   rg   rf   rh   r   r0   r   r   r   r   r   r   N   sZ   



	




+ 
)-r   )N)%r|   bisectr   typingr   r   r   r   r   r   r	   r
   r   Ztyping_extensionsr   Zqrcoder   r   r   Zqrcode.image.baser   Zqrcode.image.purer   r>   r   r   r   r?   r   r"   r#   r*   r/   r0   r@   rB   r   r   r   r   r   <module>   s$    ,
