
    OgK                    r   d dl mZ d dlmZmZmZmZmZmZ d dl	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mZmZmZmZ d d	lmZmZmZmZmZm Z m!Z! d d
l"m#Z#m$Z$m%Z% d dl&m'Z' er d dl(m)Z) d dlm*Z*m+Z+ d dl,m-Z- d dl.m/Z/ d dl0m1Z1  e	jd                  d      Z3ddZ4ddZ5ddZ6 e       Z7 G d d      Z8y)    )annotations)TYPE_CHECKINGIterableIteratorUnioncastOptionalN)ParseException)Auditor
AuditError)BlockLayout)const	validator)DXFBlockInUseErrorDXFKeyErrorDXFStructureErrorDXFTableEntryErrorDXFTypeError)AttribBlockBlockRecordEndBlkentity_linkerfactoryis_graphic_entity)UVecNULLVECVec3)ARROWS)Drawing)	DXFEntityDXFTagStorage)EntityDB)AbstractTagWriter)Tableezdxfc                    | j                         } t        |       ryt        j                  |       ry| j	                  d      r)t        j
                  t        j                  |             ryy)NT_F)upperis_anonymous_blockr   is_ezdxf_arrow
startswithis_acad_arrow
arrow_namenames    Z/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/sections/blocks.pyis_special_blockr2   .   sX    ::<D $ T"s 1 1$ 78    c                D    t        |       dkD  xr | d   dk(  xr | d   dv S )N   r   *UEXDAT)lenr/   s    r1   r*   r*   @   s-     t9q=CT!W^CQ80CCr3   c                D   | j                   j                  dd      }|r|S | j                   j                  dd      }|sy| j                  }|S|j                  G|j                  j                  |      }t	        |t
              r|j                   j                  dd      S y)Nr0    owner)dxfgetdocentitydb
isinstancer   )blockr0   r;   r>   block_records        r1   recover_block_namerC   J   s    99==$DIIMM'2&E
))C 3<<3||''.lK0##''33r3   c                     e Zd ZdZ	 	 d	 	 	 ddZd Zedd       Zedd       Z	edd       Z
d dZd	 Zd!d
Zd"dZd#dZd$dZd%dZd&dZd'dZd(d%dZd)dZedf	 	 	 	 	 d*dZdef	 	 	 	 	 d+dZd,dZd-dZd.d/dZd0dZd1dZy)2BlocksSectionzm
    Manages BLOCK definitions in a dict(), block names are case insensitive
    e.g. 'Test' == 'TEST'.

    Nc                f    || _         || j                  |       | j                          d| _        y )Nr   )r>   load#_reconstruct_orphaned_block_records_anonymous_block_counter)selfr>   entitiess      r1   __init__zBlocksSection.__init__e   s1    
 IIh002()%r3   c                ,    t        | j                        S N)r8   block_recordsrJ   s    r1   __len__zBlocksSection.__len__p   s    4%%&&r3   c                Z    t        | t              s| j                  } | j                         S rN   )r@   strr0   lower)entitys    r1   keyzBlocksSection.keys   s!    &#&[[F||~r3   c                .    | j                   j                  S rN   )r>   rO   rP   s    r1   rO   zBlocksSection.block_recordsy   s    xx%%%r3   c                .    | j                   j                  S rN   )r>   r?   rP   s    r1   r?   zBlocksSection.entitydb}   s    xx   r3   c                   	 	 	 	 	 	 	 	 dfd}dfd}| j                   t        dd         }|j                         dk7  s|j                  d   dk7  rt	        d      d= g }t
        } |       D ]p  }t        |t              r0|t
        urt        j                  d	       |}|j                          Dt        |t              r|t
        u rt        j                  d
       n|j                  j                  dd      }|j                  j                  dd      }	|s:t        |      }|r-t        j                  d| d|	 d       ||j                  _        |rF ||||      }
t        |
t"              r| j%                  |
       n3t        j                  d|	 d       nt        j                  d|	 d       t
        }|j                          `|j'                  |       s y)z
        Load DXF entities into BlockLayouts. `entities` is a list of
        entity tags, separated by BLOCK and ENDBLK entities.

        c           	        	 t        dj                  | j                  j                              }|j                  | |       |D ]  }|j                  |        |S # t        $ r6 t        dj                  | j                  j                  ddi            }Y jt        $ r# t        d| j                  j                         w xY w)Nr   scaler   )
dxfattribsz"Invalid or missing name of BLOCK #)r   r=   r<   r0   r   newr   r   handle	set_block
add_entity)rA   endblkblock_entitiesrB   rU   rO   s        r1   load_block_recordz-BlocksSection.load.<locals>.load_block_record   s    
#M=3D3DUYY^^3TU ""5&1( 0''/0 & #!!%%eiinn'1%N    '89I9I8JK s   /A <C+Cc               3  J   K   t               } D ]  } | |      r|  y wrN   )r   )linkedrU   rK   s     r1   link_entitiesz)BlocksSection.load.<locals>.link_entities   s+     "_F" ! f~ L!s   ##r"   r   SECTIONr5   )   BLOCKSz+Critical structure error in BLOCKS section.z*Missing required ENDBLK, ignoring content.z9Found ENDBLK without a preceding BLOCK, ignoring content.r0   r:   r^   z<undefined>zRecovered block name "z" for block #.z#Ignoring invalid BLOCK definition #zIgnoring BLOCK without name #N)rA   r   ra   r   rb   list[DXFEntity]returnzBlockRecord | None)rl   zIterable['DXFEntity'])rO   r   dxftype
base_classr   _MISSING_BLOCK_r@   r   loggerwarningclearr   r<   r=   rC   infor0   r   addappend)rJ   rK   rc   rf   section_headcontentrA   rU   
block_namer^   rB   rO   s    `         @r1   rG   zBlocksSection.load   s   	 	 	  ,	   		 2	! **OXa[9!Y.,2I2I!2L Q
 3
 $$QRRQK#%&#o $	'F&%(/NN#OPFF+O+NNS "'vr!:J"YY]]8]CF%%7%>
%"KK"8MRXQYYZ [ .8EIIN!'8'P%lK@ HH\2"NN"EfXQ O )Fvha'PQ+E v&I$	'r3   c                <   | j                   D ]  }|j                  t        j                  d|j                  j
                  dd| j                        }t        j                  di | j                        }|j                  ||       | j                  |        y)zFind BLOCK_RECORD entries without block definition in the blocks
        section and create block definitions for this orphaned block records.

        NBLOCK)r   r   r   )r0   
base_point)r\   r>   ENDBLK)	rO   rA   r   create_db_entryr<   r0   r>   r_   rt   )rJ   rB   rA   ra   s       r1   rH   z1BlocksSection._reconstruct_orphaned_block_records   s    
 !.. 	'L!!)// , 0 0 5 5&/   !00!
 &&uf5&!	'r3   c                    |j                  d       | j                  D ]%  }t        |t              sJ |j	                  |       ' |j                  dd       y )Nz  0
SECTION
  2
BLOCKS
r   ENDSEC)	write_strrO   r@   r   export_block_definition
write_tag2)rJ   	tagwriterrB   s      r1   
export_dxfzBlocksSection.export_dxf   sV    9: .. 	<LlK88800;	< 	Q)r3   c                    t        |      }||_        | j                  j                  |j                  j
                        sJ |S )zaAdd or replace a block layout object defined by its block record.
        (internal API)
        )r   block_layoutrO   	has_entryr<   r0   )rJ   rB   r   s      r1   rt   zBlocksSection.add   sB     #<0$0!!!++L,<,<,A,ABBBr3   c                (    d | j                   D        S )z<Iterable of all :class:`~ezdxf.layouts.BlockLayout` objects.c              3  4   K   | ]  }|j                     y wrN   )r   ).0rB   s     r1   	<genexpr>z)BlocksSection.__iter__.<locals>.<genexpr>  s     Ql))Qs   )rO   rP   s    r1   __iter__zBlocksSection.__iter__  s    Qd>P>PQQr3   c                8    | j                   j                  |      S )zVReturns ``True`` if :class:`~ezdxf.layouts.BlockLayout` `name`
        exist.
        )rO   r   rJ   r0   s     r1   __contains__zBlocksSection.__contains__  s     !!++D11r3   c                    	 t        d| j                  j                  |            }|j                  S # t        $ r t        |      w xY w)zuReturns :class:`~ezdxf.layouts.BlockLayout` `name`,
        raises :class:`DXFKeyError` if `name` not exist.
        r   )r   rO   r=   r   r   r   )rJ   r0   rB   s      r1   __getitem__zBlocksSection.__getitem__  sJ    	$t/A/A/E/Ed/KLL,,,! 	$d##	$s	   03 Ac                `    || v r| j                   j                  |       yt        d| d      )zDeletes :class:`~ezdxf.layouts.BlockLayout` `name` and all of
        its content, raises :class:`DXFKeyError` if `name` not exist.
        Block "" does not exist.N)rO   remover   r   s     r1   __delitem__zBlocksSection.__delitem__  s4     4<%%d+v->?@@r3   c                p    t        | j                  j                  j                  j	                               S )z"Returns a list of all block names.)listr>   rO   entrieskeysrP   s    r1   block_nameszBlocksSection.block_names  s&    DHH**22779::r3   c                H    	 | j                  |      S # t        $ r |cY S w xY w)zkReturns :class:`~ezdxf.layouts.BlockLayout` `name`, returns
        `default` if `name` not exist.
        )r   r   )rJ   r0   defaults      r1   r=   zBlocksSection.get#  s,    	##D)) 	N	s    !!c                H    | j                   j                  |   j                  S )z=Returns a block layout by block record handle. (internal API))r>   r?   r   )rJ   block_record_handles     r1   get_block_layout_by_handlez(BlocksSection.get_block_layout_by_handle,  s    xx  !45BBBr3   c                   | j                   J t        t        | j                   j                  j	                  |            }|xs i }|j
                  j                  |d<   ||d<   t        |      |d<   t        j                  d|| j                         }t        j                  dd|j
                  j                  i| j                         }|j                  ||       | j                  |      S )zCreate and add a new :class:`~ezdxf.layouts.BlockLayout`, `name`
        is the BLOCK name, `base_point` is the insertion point of the BLOCK.
        r;   r0   r{   rz   r|   )r>   )r>   r   r   rO   r]   r<   r^   r   r   r}   r_   rt   )rJ   r0   r{   r\   rB   headtails          r1   r]   zBlocksSection.new0  s     xx###K)?)?)C)CD)IJ%2
*..55
7!
6#'
#3
< &&w
DHHE&&w 0 0 7 78dhh
 	tT*xx%%r3   Uc                n    | j                  |      }| j                  ||dt        j                  i      }|S )a  Create and add a new anonymous :class:`~ezdxf.layouts.BlockLayout`,
        `type_char` is the BLOCK type, `base_point` is the insertion point of
        the BLOCK.

            ========= ==========
            type_char Anonymous Block Type
            ========= ==========
            ``'U'``   ``'*U###'`` anonymous BLOCK
            ``'E'``   ``'*E###'`` anonymous non-uniformly scaled BLOCK
            ``'X'``   ``'*X###'`` anonymous HATCH graphic
            ``'D'``   ``'*D###'`` anonymous DIMENSION graphic
            ``'A'``   ``'*A###'`` anonymous GROUP
            ``'T'``   ``'*T###'`` anonymous block for ACAD_TABLE content
            ========= ==========

        flags)anonymous_block_namer]   r   BLK_ANONYMOUS)rJ   	type_charr{   rx   rA   s        r1   new_anonymous_blockz!BlocksSection.new_anonymous_blockG  s6    & ..y9
Z'5;N;N1OPr3   c                    	 | xj                   dz  c_         d| | j                    }| j                  j                  |      s|S D)a  Create name for an anonymous block. (internal API)

        Args:
            type_char: letter

                U = *U### anonymous blocks
                E = *E### anonymous non-uniformly scaled blocks
                X = *X### anonymous hatches
                D = *D### anonymous dimensions
                A = *A### anonymous groups
                T = *T### anonymous ACAD_TABLE content

        r5   r6   )rI   rO   r   )rJ   r   rx   s      r1   r   z"BlocksSection.anonymous_block_name^  sN     ))Q.)YK(E(E'FGJ%%//
;!!	 r3   c                    t        t        | j                  j                  |            }|j	                  |       | j                  j                  ||       | j                  |       y)a"  Rename :class:`~ezdxf.layouts.BlockLayout` `old_name` to `new_name`

        .. warning::

            This is a low-level tool and does not rename the block references,
            so all block references to `old_name` are pointing to a non-existing
            block definition!

        N)r   r   rO   r=   renamereplacert   )rJ   old_namenew_namerB   s       r1   rename_blockzBlocksSection.rename_blockr  sQ     K););)?)?)IJH%""8\:r3   c                   |r| j                   J d       | j                   j                  j                  |      }|t        d| d      |j                  sy|j
                  rt        d| d      t        |      rt        d| d      d| d	}	 | j                   j                  |      }t        |      rt        d| d      | j                  |       y# t        $ r t        j                  d
| d       Y yw xY w)a  Delete block.

        Applies some safety checks when `safe` is ``True``.
        A :class:`DXFBlockInUseError` will be raised for:

            - blocks with active references
            - blocks representing existing layouts
            - special blocks used internally

        Args:
            name: block name (case-insensitive)
            safe: apply safety checks

        Raises:
            DXFKeyError: if block not exists
            DXFBlockInUseError: when safe is ``True`` and block is in use
        Nzvalid DXF document requiredr   r   z " represents an existing layout.zSpecial block "z," maybe used without explicit INSERT entity.zINSERT[name=="z"]iz Parsing error in query string: ""z" is still in use.)r>   blocksr=   r   is_aliveis_any_layoutr   r2   queryr
   rp   errorr8   r   )rJ   r0   saferA   query_string
block_refss         r1   delete_blockzBlocksSection.delete_block  s   $ 88'F)FF'HHOO''-E}!GD61B"CDD>>""(dV#CD   %(%dV+WX  ,D65L!XX^^L9

 :(74&8J)KLL " ?~QOPs   C "D Dc                b   | j                   J t        d | j                   j                  d      D              dfd}t               }| D ]H  }t        j                  |j
                        }|j                  r/ ||      s8|j                  |       J |D ]  }| j                  |        y)a  Delete all blocks without references except modelspace- or
        paperspace layout blocks, special arrow- and anonymous blocks
        (DIMENSION, ACAD_TABLE).

        .. warning::

            There could exist references to blocks which are not documented in the DXF
            reference, hidden in extended data sections or application defined data,
            which could invalidate a DXF document if these blocks will be deleted.

        Nc              3  n   K   | ]-  }t        j                  |j                  j                         / y wrN   )r   make_table_keyr<   r0   )r   rU   s     r1   r   z2BlocksSection.delete_all_blocks.<locals>.<genexpr>  s+       
 $$VZZ__5 
s   35INSERTc                $    t        |       ry| vS )NF)r2   )r0   active_referencess    r1   is_safez0BlocksSection.delete_all_blocks.<locals>.is_safe  s    %000r3   r0   rS   rl   bool)	r>   setr   r   r   r0   r   rt   r   )rJ   r   trashrA   r0   r   s        @r1   delete_all_blockszBlocksSection.delete_all_blocks  s     xx###  
((..2 
 

	1
  	 E++EJJ7D&&74=		$	 
  	#DT"	#r3   c                   | j                   |j                   u sJ d       | j                  D ]  }t        |t              sJ |j                  j
                  }g }|j                  }|D ]b  }t        |      sW|j                  t        j                  dt        |       d|j                  j                   d       |j                  |       nft        |t              rV|j                  t        j                  dt        |       d|j                  j                   d       |j                  |       |j                   s|j                  j"                  |k7  s|j                  t        j$                  dt        |       d	|j                  j"                   d
| d|j                  j                   d	       |j'                  |       e |D ]!  }|j                   s	 |j)                  |       #  y# t*        $ r Y 3w xY w)aD  Audit and repair BLOCKS section.

        .. important::

            Do not delete entities during the auditing process as this will alter
            the entity database while iterating it, instead use::

                auditor.trash(entity)

            to delete invalid entities after auditing automatically.

        z#Auditor for different DXF document.zRemoved invalid DXF entity z from BLOCK 'z'.)codemessagezRemoved standalone z entity from BLOCK 'zRemoved DXF entity z with invalid owner handle (#z != #z) from BLOCK 'N)r>   rO   r@   r   r<   r^   entity_spacer   fixed_errorr   REMOVED_INVALID_GRAPHIC_ENTITYrS   r0   r   r    REMOVED_STANDALONE_ATTRIB_ENTITYr   r;   (REMOVED_ENTITY_WITH_INVALID_OWNER_HANDLEru   r   
ValueError)rJ   auditorrB   r   unlink_entitiesesrU   s          r1   auditzBlocksSection.audit  s    xx7;;&M(MM& .. *	LlK888'3'7'7'>'>/1O**B 3(0'''FF"=c&k] K##/#3#3#8#8"9!= ( 
 MM&)/ '''HH"5c&k] C##/#3#3#8#8"9!= ( 
 MM&)::##'::'''PP"5c&k] C$$*JJ$4$4#5U;N:O P''3'7'7'<'<&=R!A (  $**62;3> * ??		&)K*	R & s   !G88	HH)NN)r>   zOptional[Drawing]rK   zOptional[list[DXFEntity]])rU   zUnion[str, BlockLayout]rl   rS   )rl   r%   )rl   r#   )rK   rk   rl   None)r   r$   rl   r   )rB   r   rl   r   )rl   zIterator[BlockLayout]r   )r0   rS   rl   r   )r0   rS   rl   r   )rl   z	list[str]rN   )r   rS   rl   r   )r0   rS   r{   r   rl   r   )r   rS   r{   r   rl   r   )r   rS   rl   rS   )r   rS   r   rS   rl   r   )T)r0   rS   r   r   rl   r   )rl   r   )r   r   rl   r   )__name__
__module____qualname____doc__rL   rQ   staticmethodrV   propertyrO   r?   rG   rH   r   rt   r   r   r   r   r   r=   r   r   r]   r   r   r   r   r   r    r3   r1   rE   rE   ^   s    "&.2	*	* ,	*'  
 & & ! !X't'.*R2$A;C #	&& &
 
&0  #w04	."(*X#@9r3   rE   r   )rA   r   rl   rS   )9
__future__r   typingr   r   r   r   r   r	   logging	pyparsingr
   ezdxf.auditr   r   ezdxf.layouts.blocklayoutr   ezdxf.lldxfr   r   ezdxf.lldxf.constr   r   r   r   r   ezdxf.entitiesr   r   r   r   r   r   r   
ezdxf.mathr   r   r   ezdxf.render.arrowsr   ezdxf.documentr    r!   r"   ezdxf.entitydbr#   ezdxf.lldxf.tagwriterr$   ezdxf.sections.tabler%   	getLoggerrp   r2   r*   rC   ro   rE   r   r3   r1   <module>r      s    #   $ + 1 (    + * &&7'7*			7	#$D" 'h hr3   