Ë
    £èh/|  ã                  ó  — 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m	Z	m
Z
 d dlZd dlZd dlmZ d dlmZ d dlZd dlmZ d dlmZ d dl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$ d dl%m&Z& d dl'm(Z( d dl)m*Z*m+Z+ erd dl,m-Z- d dl.m/Z/ ddgZ0h d£Z1 ejd                  d«      Z3	 d,	 	 	 	 	 d-d„Z4d,d.d„Z5	 d/	 	 	 	 	 d-d„Z6d0d„Z7 G d„ d«      Z8d1d„Z9d2d„Z:d3d„Z;	 	 	 d4	 	 	 	 	 	 	 	 	 d5d„Z< ejz                  d«      Z> ejz                  d «      Z?d6d!„Z@ ejz                  d"«      ZA ejz                  d#«      ZBd7d$„ZCejˆ                  d8d%„«       ZEd8d&„ZFd'ZGd(ZHd9d)„ZId:d*„ZJejˆ                  ej–                  ddf	 	 	 	 	 	 	 d;d+„«       ZLy)<é    )ÚannotationsN)ÚTYPE_CHECKINGÚBinaryIOÚIterableÚIteratorÚCallableÚUnionÚOptional)Údefaultdict)ÚPath)Úconst)Úrepair)Úhas_dxf_unicodeÚdecode_dxf_unicodeÚhas_mif_encodingÚdecode_mif_to_unicode)ÚDXFTagÚ	DXFVertexÚDXFBinaryTagÚPOINT_CODESÚBINARY_DATAÚ
TYPE_TABLEÚMAX_GROUP_CODE)Ú
group_tagsÚTags)Úentity_structure_validator)Ú
toencoding)ÚAuditorÚ
AuditError©ÚDrawing)ÚSectionDictÚreadÚreadfile>   ÚEOFÚTABLEÚENDBLKÚENDSECÚENDTABÚSEQENDÚSECTIONÚezdxfÚsurrogateescapec                ó’   — t        | «      } t        | d¬«      5 }t        ||¬«      \  }}ddd«       | _        |fS # 1 sw Y   ŒxY w)u÷  Read a DXF document from file system similar to :func:`ezdxf.readfile`,
    but this function will repair as many flaws as possible, runs the required
    audit process automatically the DXF document and the :class:`Auditor`.

    Args:
        filename: file-system name of the DXF document to load
        errors: specify decoding error handler

            - "surrogateescape" to preserve possible binary data (default)
            - "ignore" to use the replacement char U+FFFD "ï¿½" for invalid data
            - "strict" to raise an :class:`UnicodeDecodeError` exception for invalid data

    Raises:
        DXFStructureError: for invalid or corrupted DXF structures
        UnicodeDecodeError: if `errors` is "strict" and a decoding error occurs

    Úrb©Úmode©ÚerrorsN)ÚstrÚopenr#   Úfilename)r6   r3   ÚfpÚdocÚauditors        ú-lib/python3.12/site-packages/ezdxf/recover.pyr$   r$   >   sH   € ô( �8‹}€HÜ	ˆh˜TÕ	" bÜ˜B vÔ.‰ˆˆW÷ 
#à€C„LØ�ˆ<Ð÷ 
#Ð	"ús	   ™=½Ac                óF   — t         j                  | |¬«      }t        |«      S )u(  Read a DXF document from a binary-stream similar to :func:`ezdxf.read`,
    but this function will detect the text encoding automatically and repair
    as many flaws as possible, runs the required audit process afterwards
    and returns the DXF document and the :class:`Auditor`.

    Args:
        stream: data stream to load in binary read mode
        errors: specify decoding error handler

            - "surrogateescape" to preserve possible binary data (default)
            - "ignore" to use the replacement char U+FFFD "ï¿½" for invalid data
            - "strict" to raise an :class:`UnicodeDecodeError` exception for invalid data

    Raises:
        DXFStructureError: for invalid or corrupted DXF structures
        UnicodeDecodeError: if `errors` is "strict" and a decoding error occurs

    r2   )ÚRecoverÚrunÚ_load_and_audit_document)Ústreamr3   Úrecover_tools      r:   r#   r#   Y   s!   € ô& —;‘;˜v¨f�;Ó5€LÜ# LÓ1Ð1ó    c                óÆ   — t        | «      } t        | d¬«      5 }t        j                  ||t        ¬«      }t        |«      \  }}ddd«       | _        |fS # 1 sw Y   ŒxY w)uU  Read a DXF document from file system similar to :func:`readfile`,
    but this function will use a special tag loader, which tries to recover the
    tag stream if invalid tags occur.  This function is intended to load
    corrupted DXF files and should only be used to explore such files, data loss
    is very likely.

    Args:
        filename: file-system name of the DXF document to load
        errors: specify decoding error handler

            - "surrogateescape" to preserve possible binary data (default)
            - "ignore" to use the replacement char U+FFFD "ï¿½" for invalid data
            - "strict" to raise an :class:`UnicodeDecodeError` exception for invalid data

    Raises:
        DXFStructureError: for invalid or corrupted DXF structures
        UnicodeDecodeError: if `errors` is "strict" and a decoding error occurs

    r/   r0   )r3   ÚloaderN)r4   r5   r<   r=   Úsynced_bytes_loaderr>   r6   )r6   r3   r7   r@   r8   r9   s         r:   ÚexplorerE   p   s]   € ô, �8‹}€HÜ	ˆh˜TÕ	" bÜ—{‘{ 2¨fÔ=P�{ÓQˆÜ/°Ó=‰ˆˆW÷ 
#ð €C„LØ�ˆ<Ð÷	 
#Ð	"ús   ™+AÁA c                ó(  — ddl m}  |«       }|j                  | j                  «       t	        |«      }| j
                  D ]  \  }}|j                  ||«       Œ | j                  D ]  \  }}|j                  ||«       Œ |j                  «        ||fS )Nr   r    )
Úezdxf.documentr!   Ú_load_section_dictÚsection_dictr   r3   Ú	add_errorÚfixesÚfixed_errorr=   )r@   r!   r8   r9   ÚcodeÚmsgs         r:   r>   r>   Ž   s„   € Ý&á
‹)€CØ×Ñ˜<×4Ñ4Ô5ä�c‹l€GØ!×(Ô(‰	ˆˆcØ×Ñ˜$ Õ$ð )à!×'Ô'‰	ˆˆcØ×Ñ˜D #Õ&ð (à‡K�K„MØ�ˆ<ÐrA   c                  óˆ   — e Zd ZdZddd„Ze	 	 d	 	 	 	 	 	 	 dd„«       Zdd„Zdd„Zdd„Z	dd„Z
	 	 	 	 	 	 dd	„Zdd
„Zd„ Zd„ Zy)r<   zLoose coupled recovering tools.Nc                ó†   — |xs t         | _        t        «       | _        g | _        g | _        t        j                  | _        y ©N)	Úbytes_loaderÚ
tag_loaderÚdictrI   r3   rK   r   ÚDXF12Ú
dxfversion)ÚselfrC   s     r:   Ú__init__zRecover.__init__¡   s9   € ð
 !Ò0¤LˆŒô ,0«6ˆÔð .0ˆŒØ,.ˆŒ
ô  Ÿ+™+ˆ�rA   c                ó  — t        |«      }|j                  ||«      }|j                  |«      }|j                  |«       |j                  j                  d«      }|r |j                  |«      }||j                  d<   |j                  dkD  r |j                  «        |j                  «        |j                  }|j                  dk  }	|j                  «       D ](  \  }
}|
dv sŒt        |j                  ||	«      «      ||
<   Œ* |S )zExecute the recover process.ÚTABLESÚAC1009>   ÚBLOCKSrZ   ÚOBJECTSÚENTITIES)r<   Ú	load_tagsÚrebuild_sectionsÚload_section_dictrI   ÚgetÚrebuild_tablesrV   Úrecover_rootdictÚfix_broken_layout_linksÚitemsÚlistÚcheck_entities)Úclsr?   rC   r3   r@   ÚtagsÚsectionsÚtablesrI   Úis_r12ÚnameÚentitiess               r:   r=   zRecover.run²   sþ   € ô ˜v“ˆØ×%Ñ% f¨fÓ5ˆØ×0Ñ0°Ó6ˆØ×&Ñ& xÔ0Ø×*Ñ*×.Ñ.¨xÓ8ˆÙØ!×0Ñ0°Ó8ˆFØ28ˆL×%Ñ% hÑ/Ø×"Ñ" XÒ-Ø×)Ñ)Ô+Ø×0Ñ0Ô2Ø#×0Ñ0ˆà×(Ñ(¨HÑ4ˆØ*×0Ñ0Ö2‰NˆD�(ØÐBÒBÜ%)Ø ×/Ñ/°¸&ÓAó&�˜TÒ"ð 3ð ÐrA   c                óH   — t        || j                  | j                  |¬«      S )N©Úmessagesr3   )Úsafe_tag_loaderrS   r3   )rW   r?   r3   s      r:   r_   zRecover.load_tagsÐ   s    € ÜØ�D—O‘O¨d¯k©kÀ&ô
ð 	
rA   c                óÚ   ‡ ‡‡‡‡‡‡‡	‡
‡‡— ˆˆˆ
ˆ fd„Šˆˆˆˆ ˆfd„Šˆˆˆˆˆ ˆfd„}ˆˆˆˆ	ˆ ˆˆfd„Šg Š	g Š
g ŠdŠ|D ]  Š‰\  ŠŠ‰dk(  r |«        Œ ‰«        Œ ‰
j                  ‰	«       ‰
S )aA  Collect tags between SECTION and ENDSEC or next SECTION tag
        as list of DXFTag objects, collects tags outside of sections
        as an extra section.

        Returns:
            List of sections as list of DXFTag() objects, the last section
            contains orphaned tags found outside of sections

        c                 óŒ   •— ‰r‰j                  ‰ «       n+‰j                  j                  t        j                  df«       g Š dŠy )Nz)DXF structure error: missing SECTION tag.F)ÚappendrK   r   ÚMISSING_SECTION_TAG)Ú	collectorÚinside_sectionrk   rW   s   €€€€r:   Úclose_sectionz/Recover.rebuild_sections.<locals>.close_sectioná   sE   ø€ ñ Ø—‘ 	Õ*ð —
‘
×!Ñ!ä"×6Ñ6ØCðôð ˆIØ"‰NrA   c                 ó”   •— ‰r2‰j                   j                  t        j                  df«        ‰ «        ‰j                  ‰«       dŠy )Nú(DXF structure error: missing ENDSEC tag.T©rK   rv   r   ÚMISSING_ENDSEC_TAG)rz   rx   ry   rW   Útags   €€€€€r:   Úopen_sectionz.Recover.rebuild_sections.<locals>.open_sectionñ   sC   ø€ áØ—
‘
×!Ñ!ä"×5Ñ5ØBðôñ ”Ø×Ñ˜SÔ!Ø!‰NrA   c                 ó¾   •— ‰dk(  r ‰«        y ‰dk(  r ‰ «        y ‰dk(  r6‰r3‰j                   j                  t        j                  df«        ‰ «        y y  ‰«        y )Nr+   r(   r%   r|   r}   )rz   Úcollectry   r€   rW   Úvalues   €€€€€€r:   Úprocess_structure_tagz7Recover.rebuild_sections.<locals>.process_structure_tagþ   s]   ø€ Ø˜	Ò!Ù•Ø˜(Ò"Ù•Ø˜%’Ù!Ø—J‘J×%Ñ%ä&×9Ñ9ØFðôñ "•Oð "ñ •	rA   c                 ó´   •— ‰r‰j                  ‰«       y ‰j                  j                  t        j                  d‰ › d‰› d�f«       ‰j                  ‰«       y )Nz1DXF structure error: found tag outside section: (z, Ú))rv   rK   r   ÚFOUND_TAG_OUTSIDE_SECTION)rM   rx   ry   ÚorphansrW   r   rƒ   s   €€€€€€€r:   r‚   z)Recover.rebuild_sections.<locals>.collect  sY   ø€ ÙØ× Ñ  Õ%à—
‘
×!Ñ!ä"×<Ñ<ðØ ˜6  E 7¨!ð-ðôð —‘˜sÕ#rA   Fr   ©rv   )rW   rj   r„   rz   rM   r‚   rx   ry   r€   rˆ   rk   r   rƒ   s   `  @@@@@@@@@@r:   r`   zRecover.rebuild_sectionsÕ   su   ÿú€ ÷	#÷ 	"ð 	"÷	ñ 	÷"	$ò 	$ð !#ˆØ')ˆØ"$ˆ	ØˆÛˆCØ‰KˆD�%Ø�qŠyÙ%Õ'á•	ð ð 	�‰˜Ô ØˆrA   c                ó  ‡ ‡
— dˆ
fd„}dˆ fd„}dˆ fd„}|j                  «       }|r|d   dk(  r|j                  |«       g }t        «       Š
|D ]D  }|d   \  }}|dk(  r
 |||«       Œ‰ j                  j                  t        j
                  df«       ŒF ‰
j                  d	t        dd
«      t        dd	«      g«      }	‰ j                  |	|«       t        |	«      ‰ _
        ‰ j                  t        j                  k  r |‰
«        |‰
«       y)zMerge sections of same type.c                óH   •— | ‰v r‰|    j                  |dd  «       y |‰| <   y )Né   )Úextend)rn   rj   rI   s     €r:   Úadd_sectionz.Recover.load_section_dict.<locals>.add_section-  s.   ø€ Ø�|Ñ#Ø˜TÑ"×)Ñ)¨$¨q¨r¨(Õ3à%)�˜TÒ"rA   c                ó    •— | j                  «       D ]:  \  }}|t        j                  v sŒt        t	        |d«      «      ‰j
                  |<   Œ< y ©Nr   )rf   r   ÚMANAGED_SECTIONSrg   r   rI   )Údrn   ÚsectionrW   s      €r:   Ú_build_section_dictz6Recover.load_section_dict.<locals>._build_section_dict3  sA   ø€ Ø!"§¡¦‘��gØœ5×1Ñ1Ò1Ü.2´:¸gÀqÓ3IÓ.J�D×%Ñ% dÒ+ñ "+rA   c                ó‚   •— dD ]9  }|| v sŒ| |= ‰j                   j                  t        j                  d|› d�f«       Œ; y )N)ÚCLASSESr]   ÚACDSDATAzRemoved unsupported z section for DXF R12.)rK   rv   r   ÚREMOVED_UNSUPPORTED_SECTION)r’   rn   rW   s     €r:   Ú_remove_unsupported_sectionsz?Recover.load_section_dict.<locals>._remove_unsupported_sections8  sH   ø€ Û:�Ø˜1’9Ø˜$˜Ø—J‘J×%Ñ%ä&×BÑBØ2°4°&Ð8MÐNðõñ ;rA   r   )r   r+   é   rŒ   z>DXF structure error: missing section name tag, ignore section.ÚHEADERr+   N)rn   r4   ÚreturnÚNone)r’   rT   rœ   r�   )r’   rT   )Úpoprv   rT   rK   r   ÚMISSING_SECTION_NAME_TAGÚ
setdefaultr   Úrescue_orphaned_header_varsÚ_detect_dxf_versionrV   r   rU   )rW   rk   rŽ   r”   r™   rˆ   r“   rM   rn   ÚheaderrI   s   `         @r:   ra   zRecover.load_section_dict*  sý   ù€ õ	*õ	Kõ
		ð —,‘,“.ˆÙ�w˜q‘z ^Ò3à�O‰O˜GÔ$ØˆGä&*£fˆÛˆGØ  ™‰JˆD�$Ø�qŠyÙ˜D 'Õ*à—
‘
×!Ñ!ä"×;Ñ;ØXðõð  ð ×(Ñ(Øä�q˜)Ó$Ü�q˜(Ó#ðó
ˆð 	×(Ñ(¨°Ô9Ü-¨fÓ5ˆŒØ�?‰?œeŸk™kÒ)Ù(¨Ô6Ù˜LÕ)rA   c                óÆ  ‡‡‡	— d
ˆˆ	ˆfd„}t        «       Š	t        t        «      Št        t        j
                  «      }‰D ]a  }|d   j                  j                  «       }|dk(  r$	 |d   j                  j                  «       }|‰	|<   ŒI||v sŒN‰|   j                  |«       Œc t        t        dd«      t        dd«      g«      gŠt        t        j
                  «      }| j                  t        j                  k  r@|j                  d«       d‰v r+| j                   j                  t"        j$                  d	f«       |D ]
  } ||«       Œ ‰S # t        t        f$ r Y �Œw xY w)zRebuild TABLES section.c           	     ó,  •— | ‰vry ‰j                  | «      }|r‰j                  |«       n0‰j                  t        t        dd«      t        d| «      g«      «       ‰j	                  ‰|    «       ‰j                  t        t        dd«      g«      «       y )Nr   r&   rŒ   r)   )rb   rv   r   r   r�   )rn   ÚheadÚcontentÚheadsrl   s     €€€r:   Úappend_tablez,Recover.rebuild_tables.<locals>.append_tablek  sz   ø€ Ø˜7Ñ"Øà—9‘9˜T“?ˆDÙØ—‘˜dÕ#ð —‘œd¤F¨1¨gÓ$6¼¸qÀ$»Ð#HÓIÔJØ�M‰M˜' $™-Ô(Ø�M‰Mœ$¤ q¨(Ó 3Ð4Ó5Õ6rA   r   r&   rš   r+   rŒ   rZ   ÚBLOCK_RECORDz3Removed unsupported BLOCK_RECORD table for DXF R12.)rn   r4   )rT   r   rg   Úsetr   ÚTABLE_NAMES_ACAD_ORDERrƒ   ÚupperÚ
IndexErrorÚAttributeErrorrv   r   r   rV   rU   ÚremoverK   r   ÚREMOVED_UNSUPPORTED_TABLE)
rW   rl   r©   Úvalid_tablesÚentryrn   Ú
table_nameÚnamesr§   r¨   s
    `      @@r:   rc   zRecover.rebuild_tablesd  s>  ú€ ÷	7ô “ˆÜœdÓ#ˆÜœ5×7Ñ7Ó8ˆãˆEØ˜‘8—>‘>×'Ñ'Ó)ˆDØ�wŠð.Ø!& q¡§¡×!5Ñ!5Ó!7�Jð ).�E˜*Ò%Ø˜Ò%Ø˜‘×$Ñ$ UÕ+ð ô œ˜q )Ó,¬f°Q¸Ó.AÐBÓCÐDˆä”U×1Ñ1Ó2ˆØ�?‰?œeŸk™kÒ)à�L‰L˜Ô(Ø Ñ(Ø—
‘
×!Ñ!ä"×<Ñ<ØMðôó ˆDÙ˜Õð àˆøô- #¤NÐ3ò Úðús   Á&EÅE ÅE c                ó~   — d }|D ]6  }|\  }}|dk(  r|}Œ|€Œ|j                  |«       |j                  |«       d }Œ8 y )Né	   r‰   )rW   r£   rˆ   Úvar_namer   rM   rƒ   s          r:   r¡   z#Recover.rescue_orphaned_header_vars™  sK   € ð ˆÛˆCØ‰KˆD�%Ø�qŠyØ‘ØÑ%Ø—‘˜hÔ'Ø—‘˜cÔ"Ø‘ñ rA   c              #  óž   K  — d}|D ]B  }|d   \  }}|t         v r|–— Œt        t        |«      «      }|r|j                  |«       |–— ŒD y ­w)N)éd   r   )ÚEXCLUDE_STRUCTURE_CHECKr   r   Úremove_tags)rW   ro   rm   Úsubclass_markersÚentityÚ_Údxftyperj   s           r:   rh   zRecover.check_entities¦  s\   è ø€ Ø!ÐÛˆFØ ™‰JˆAˆwØÔ1Ñ1Ø“ô Ô6°vÓ>Ó?�Ùð ×$Ñ$Ð%5Ô6Ø“
ñ ùs   ‚AAc                ól  — | j                   j                  d«      }|rt        |«      dk  ry t        |d   «      ry t	        |«      \  }}|rN|d   ||<   ||d<   	 |j                  «       }| j                  j                  t        j                  d|› d�f«       y y # t        j                  $ r d}Y ŒHw xY w)Nr]   rŒ   rš   r�   z%Recovered misplaced root DICTIONARY(#z).)rI   rb   ÚlenÚ_is_rootdictÚ_find_rootdictÚ
get_handler   ÚDXFValueErrorrK   rv   r   ÚMISPLACED_ROOT_DICT)rW   ÚobjectsÚindexÚrootdictÚhandles        r:   rd   zRecover.recover_rootdictµ  sÃ   € Ø×#Ñ#×'Ñ'¨	Ó2ˆÙœ#˜g›,¨Ò*Øô ˜ ™
Ô#ØÜ(¨Ó1‰ˆˆxÙØ$ Q™ZˆG�E‰NØ!ˆG�A‰Jð Ø!×,Ñ,Ó.�ð �J‰J×Ñä×2Ñ2Ø;¸F¸8À2ÐFðõð øô
 ×&Ñ&ò  Ø’ð ús   ÁB ÂB3Â2B3c                 ó   — y)z‡Fixes broke links (block_record_handle) between LAYOUT and BLOCK_RECORD
        entities. See issue #997 for more information.
        N© )rW   s    r:   re   zRecover.fix_broken_layout_linksÌ  s   € ð 	rA   rQ   )rC   úOptional[Callable])Nr-   )r?   r   rC   rÎ   r3   r4   rœ   r<   )r?   r   r3   r4   rœ   úIterator[DXFTag])rj   úIterable[DXFTag]rœ   úlist[list[DXFTag]])rk   rÑ   rœ   r�   )rl   ú
list[Tags]rœ   rÒ   )r£   zlist[DXFTag]rˆ   rÐ   rœ   r�   )ro   rÒ   rm   Úboolrœ   zIterator[Tags])Ú__name__Ú
__module__Ú__qualname__Ú__doc__rX   Úclassmethodr=   r_   r`   ra   rc   r¡   rh   rd   re   rÍ   rA   r:   r<   r<   ž   s�   „ Ù)ô&ð" ð &*Ø'ð	àðð #ðð ð	ð
 
òó ðó:
ó
Sój8*ót3ðj Ø"ð Ø-=ð à	ó óòó.rA   r<   c                óÖ   — d}| D ]S  }|rGt        |d   «      j                  «       }t        j                  d|«      r|c S  t        j
                  S |dk(  sŒRd}ŒU t        j
                  S )NFrš   z
AC[0-9]{4})r·   z$ACADVERT)r4   ÚstripÚreÚ	fullmatchr   rU   )r£   Únext_is_dxf_versionr   rV   s       r:   r¢   r¢   Ó  sj   € ØÐÛˆÙÜ˜S ™V›×*Ñ*Ó,ˆJÜ�|‰|˜M¨:Ô6Ø!Ò!àô �;‰;Ðð �/Ó!Ø"&Ñð ô �;‰;ÐrA   c                ó8   — | d   dk7  ryt        d„ | D «       «      S )Nr   )r   Ú
DICTIONARYFc              3  ó&   K  — | ]	  }|d k(  –— Œ y­w))é   Ú
ACAD_GROUPNrÍ   )Ú.0r   s     r:   Ú	<genexpr>z_is_rootdict.<locals>.<genexpr>å  s   è ø€ Ð:±6¨CˆsÐ'Õ'±6ùs   ‚)Úany)r¾   s    r:   rÃ   rÃ   á  s#   € Øˆa�yÐ%Ò%ØäÑ:±6Ó:Ó:Ð:rA   c                ób   — t        | «      D ]  \  }}t        |«      sŒ||fc S  dt        «       fS r�   )Ú	enumeraterÃ   r   )rÈ   rÉ   r¾   s      r:   rÄ   rÄ   è  s5   € Ü" 7Ö+‰ˆˆvÜ˜ÕØ˜&�=Ò ð ,ð Œd‹fˆ9ÐrA   c                ó  — |€t         }t        j                   || «      d«      \  }}t        |«      }t	        j
                  |«      }t	        j                  |«      }t	        j                  |«      }t        ||||¬«      S )uÿ  Yields :class:``DXFTag`` objects from a bytes `stream`
    (untrusted external  source), skips all comment tags (group code == 999).

    - Fixes unordered and invalid vertex tags.
    - Pass :func:`synced_bytes_loader` as argument `loader` to brute force
      load invalid tag structure.

    Args:
        stream: input data stream as bytes
        loader: low level tag loader, default loader is :func:`bytes_loader`
        messages: list to store error messages
        errors: specify decoding error handler

            - "surrogateescape" to preserve possible binary data (default)
            - "ignore" to use the replacement char U+FFFD "ï¿½" for invalid data
            - "strict" to raise an :class:`UnicodeDecodeError` exception for invalid data

    rŒ   rq   )	rR   Ú	itertoolsÚteeÚdetect_encodingr   Útag_reorder_layerÚfilter_invalid_point_codesÚfilter_invalid_handlesÚbyte_tag_compiler)r?   rC   rr   r3   rj   Údetector_streamÚencodings          r:   rs   rs   ï  st   € ð0 €~ÜˆÜ%ŸM™M©&°«.¸!Ó<Ñ€Dˆ/Ü˜Ó/€Hô ×#Ñ# DÓ)€DÜ×,Ñ,¨TÓ2€DÜ×(Ñ(¨Ó.€DÜ˜T 8°hÀvÔNÐNrA   z[+-]?\d+s   [+-]?\d+c                óœ   — t        j                  t        | t        «      rt        nt
        | «      }|r|j                  «       } t        | «      S )zÇEmulate the behavior of the C function stoll(), which just stop
    converting strings to integers at the first invalid char without raising
    an exception. e.g. "42xyz" is a valid integer 42

    )rÛ   ÚsearchÚ
isinstancer4   ÚINT_PATTERN_SÚINT_PATTERN_BÚgroupÚint©ÚsÚress     r:   Ú_search_intrü     s;   € ô �)‰)Ü# A¤sÔ+�´Àó€Cñ Ø�I‰I‹KˆÜˆq‹6€MrA   z#[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?s#   [+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?c                óœ   — t        j                  t        | t        «      rt        nt
        | «      }|r|j                  «       } t        | «      S )zÊEmulate the behavior of the C function stod(), which just stop
    converting strings to doubles at the first invalid char without raising
    an exception. e.g. "47.11xyz" is a valid double 47.11

    )rÛ   ró   rô   r4   ÚFLOAT_PATTERN_SÚFLOAT_PATTERN_Br÷   Úfloatrù   s     r:   Ú_search_floatr  )  s;   € ô �)‰)Ü% a¬Ô-�´?ÀAó€Cñ Ø�I‰I‹KˆÜ�‹8€OrA   c           	   #  ó²  K  — d}d}| j                   }|s[ |«       }|r	 t        |«      }ny	 |«       }|r6|j                  d
«      }|dk(  r|dk(  rd}|dk7  rt        ||«      –— |dz  }ny	|sŒZy	y	# t        $ rZ 	 t        |«      }nJ# t        $ r> |j	                  d¬«      j                  d«      }t        j                  d|› d|› d�«      ‚w xY wY Œ§w xY w­w)a‚  Yields :class:``DXFTag`` objects from a bytes `stream`
    (untrusted external  source), skips all comment tags (group code == 999).

    ``DXFTag.code`` is always an ``int`` and ``DXFTag.value`` is always a
    raw bytes value without line endings. Works with file system streams and
    :class:`BytesIO` streams.

    Raises:
        DXFStructureError: Found invalid group code.

    Frš   Úignorer2   z
zInvalid group code "z
" at line Ú.Nó   
r   s   EOFTéç  rŒ   )	Úreadlinerø   Ú
ValueErrorrü   ÚdecodeÚrstripr   ÚDXFStructureErrorr   )r?   ÚeofÚliner  rM   rƒ   s         r:   rR   rR   7  sý   è ø€ ð €CØ€DØ�‰€HÙÙ‹zˆáð	Ü˜4“y‘ð á“
ˆáØ—L‘L Ó)ˆEØ�qŠy˜U fš_Ø�Ø�sŠ{Ü˜T 5Ó)Ò)Ø�A‰I‰Dàô7 øô ò ðÜ& tÓ,‘DøÜ!ò ØŸ;™;¨h˜;Ó7×>Ñ>¸vÓF�DÜ×1Ñ1Ø.¨t¨f°J¸t¸fÀAÐFóð ðúñ ðüsG   ‚CŸA1 ªACÁ/CÁ1	CÁ;BÂCÂACÃCÃCÃCÃCc              #  ó  K  — d}t         dz   }| j                  }	 d}|r* |«       }|r	 t        |«      }d|cxk  r|k  rn nd}ny|rŒ* |«       }|r#|dk7  rt	        ||j                  d«      «      –— nyŒ\# t        $ r Y Œ<w xY w­w)a=  Yields :class:``DXFTag`` objects from a bytes `stream`
    (untrusted external source), skips all comment tags (group code == 999).

    ``DXFTag.code`` is always an ``int`` and ``DXFTag.value`` is always a
    raw bytes value without line endings. Works with file system streams and
    :class:`BytesIO` streams.

    Does not raise DXFStructureError on invalid group codes, instead skips
    lines until a valid group code or EOF is found.

    This can remove invalid lines before group codes, but can not
    detect invalid lines between group code and tag value.

    r  rš   Tr   FNr  )r   r  rü   r  r   r
  )r?   rM   Úupper_boundaryr  Úseeking_valid_group_coderƒ   s         r:   rD   rD   e  s¦   è ø€ ð €DÜ# aÑ'€NØ�‰€HØ
Ø#'Ð Ù&Ù“:ˆDÙð9Ü& tÓ,�Dð ˜DÔ1 >Õ1Ø38Ñ0àò 'ñ “
ˆÙØ�sŠ{Ü˜T 5§<¡<°Ó#8Ó9Ó9àð' øô "ò Ùðüs-   ‚&B©A7 ´BÁ	.BÁ7	BÂ BÂBÂBs   $DWGCODEPAGEs   $ACADVERc                ó†   — t        t        j                  «      }dj                  | D �cg c]	  }||vsŒ|‘Œ c}«      S c c}w )NÚ )r«   ÚstringÚ
whitespaceÚjoin)rú   ÚwsÚcs      r:   Ú_strip_whitespacer  ‘  s9   € Ü	ŒV×ÑÓ	€BØ�7‰7™qÓ0™q˜! A¨R¢K’A˜qÑ0Ó1Ð1ùÒ0s   ©	>³>c                óœ  — d}d}d}| D ]²  \  }}|dk(  r |t         k(  rt         }nx|t        k(  rot        }nh|dk(  r4|t         k(  r+t        |j                  t        j
                  «      «      }d}n/|dk(  r*|t        k(  r!|j                  t        j
                  «      }d}|sŒ–|sŒ™|t        j                  k\  rdc S |c S  t        j
                  S )aÛ  Detect text encoding from header variables $DWGCODEPAGE and $ACADVER
    out of a stream of DXFTag objects.

    Assuming a malformed DXF file:

    The header variables could reside outside of the HEADER section,
    an ENDSEC tag is not a reliable fact that no $DWGCODEPAGE or
    $ACADVER header variable will show up in the remaining tag stream.

    Worst case: DXF file without a $ACADVER var, and a $DWGCODEPAGE
    unequal to "ANSI_1252" at the end of the file.

    Nr·   rá   rš   Úutf8)ÚDWGCODEPAGEÚACADVERr   r	  r   ÚDEFAULT_ENCODINGÚDXF2007)rj   rñ   rV   Únext_tagrM   rƒ   s         r:   rë   rë   –  s¾   € ð €HØ€JØ€Hã‰ˆˆeØ�1Š9ØœÒ#Ü&‘Øœ'Ò!Ü"‘Ø�QŠY˜8¤{Ò2Ü! %§,¡,¬u×/EÑ/EÓ"FÓGˆHØ‰HØ�QŠY˜8¤wÒ.ØŸ™¤e×&<Ñ&<Ó=ˆJØˆHâš
Ø'¬5¯=©=Ò8�6ÒF¸hÒFð ô  ×!Ñ!Ð!rA   c              #  óŒ  ‡‡‡K  — ˆˆfd„}dˆˆfd„}dˆˆfd„}t        ‰t        «      sJ ‚t        |t        «      sJ ‚‰€g Št        | «      } d}dŠ	 	 |�|}d}nt        | «      }‰dz  Š|j                  }	|	t
        v rÛt        | «      }
‰dz  Š|
j                  |	dz   k7  rt        j                  d‰› d	�«      ‚t        | «      }‰dz  Š	 |j                  |	d
z   k(  r@	 t        |j                  «      t        |
j                  «      t        |j                  «      f}n-	 t        |j                  «      t        |
j                  «      f}|}t        |	|«      –— �n|	t        v r9t        |t        «      r|}n!	 t        j                  |	|j                  «      }|–— nÂt        j                   |	t        «      }|j                  }|t        u r|	dk(  r(|j                  j#                  «       j%                  «       }	 |j'                  ‰d¬«      }|	r-t1        |«      rt3        |«      }nt5        |«      rt7        |«      }t9        |	|«      –— n	 t9        |	 ||«      «      –— �Œ# t        $ r9  ||j                  «       ||
j                  «       ||j                  «      f}Y �ŒVw xY w# t        $ r(  ||j                  «       ||
j                  «      f}Y �ŒŒw xY w# t        $ r t        j                  d‰› d	�«      ‚w xY w# t        $ r t        j                  d‰› d	�«      ‚w xY w# t(        $ r; |j'                  ‰|¬«      }‰j+                  t,        j.                  d‰› �f«       Y �Œ]w xY w# t        $ r¿ |t:        u rH	 t9        |	 ||j                  «      «      –— n“# t        $ r t        j                   ||«      «      ‚w xY w|t        u rH	 t9        |	 ||j                  «      «      –— nC# t        $ r t        j                   ||«      «      ‚w xY wt        j                   ||«      «      ‚Y �ŒÕw xY w# t<        $ r Y yw xY w­w)u`  Compiles DXF tag values imported by bytes_loader() into Python types.

    Raises DXFStructureError() for invalid float values and invalid coordinate
    values.

    Expects DXF coordinates written in x, y[, z] order, see function
    :func:`safe_tag_loader` for usage with applied repair filters.

    Args:
        tags: DXF tag generator, yielding tag values as bytes like bytes_loader()
        encoding: text encoding
        messages: list to store error messages
        errors: specify decoding error handler

            - "surrogateescape" to preserve possible binary data (default)
            - "ignore" to use the replacement char U+FFFD "ï¿½" for invalid data
            - "strict" to raise an :class:`UnicodeDecodeError` exception for invalid data

    Raises:
        DXFStructureError: Found invalid DXF tag or unexpected coordinate order.

    c                ój   •— | j                   }| j                  j                  ‰«      }d|› d|› d‰› d�S )NzInvalid tag (z, "z") near line: r  )rM   rƒ   r	  )r   rM   rƒ   rñ   r  s      €€r:   Ú	error_msgz$byte_tag_compiler.<locals>.error_msgÙ  s;   ø€ Ø�x‰xˆØ—	‘	× Ñ  Ó*ˆØ˜t˜f C¨ w¨n¸T¸FÀ!ÐDÐDrA   c                óè   •— t        | t        «      r| j                  dd¬«      } t        | «      }d| › d‰› d|› d�}‰j	                  t
        j                  |f«       t        j                  |«       |S )Nr  r  ©rñ   r3   z!recovered invalid integer value "ú" near line ú as "Ú")	rô   Úbytesr	  rü   rv   r   ÚINVALID_INTEGER_VALUEÚloggerÚwarning©rú   rƒ   rN   r  rr   s      €€r:   Úrecover_intz&byte_tag_compiler.<locals>.recover_intÞ  sk   ø€ Ü�aœÔØ—‘ &°�Ó:ˆAÜ˜A“ˆØ1°!°°LÀÀÀeÈEÈ7ÐRSÐTˆØ�‰œ×9Ñ9¸3Ð?Ô@Ü�‰�sÔØˆrA   c                óþ   •— t        | t        «      r| j                  dd¬«      } t        | «      } t	        | «      }d| › d‰› d|› d�}‰j                  t        j                  |f«       t        j                  |«       |S )Nr  r  r$  z(recovered invalid floating point value "r%  r&  r'  )
rô   r(  r	  r  r  rv   r   ÚINVALID_FLOATING_POINT_VALUEr*  r+  r,  s      €€r:   Úrecover_floatz(byte_tag_compiler.<locals>.recover_floatç  sx   ø€ Ü�aœÔØ—‘ &°�Ó:ˆAÜ˜aÓ ˆÜ˜aÓ ˆØ8¸¸¸<ÈÀvÈUÐSXÐRYÐYZÐ[ˆØ�‰œ×@Ñ@À#ÐFÔGÜ�‰�sÔØˆrA   Nr   rŒ   é
   z)Missing required y-coordinate near line: r  é   z)Invalid floating point values near line: zInvalid binary data near line: Ústrictr2   z'Fixed unicode decoding error near line ©rú   úUnion[str, bytes]rœ   rø   ©rú   r5  rœ   r   )rô   r4   ÚiterÚnextrM   r   r   r  r   rƒ   r  r   r   r   Úfrom_stringr   rb   rÚ   r­   r	  ÚUnicodeDecodeErrorrv   r   ÚDECODING_ERRORr   r   r   r   r   rø   ÚStopIteration)rj   rñ   rr   r3   r"  r-  r0  Úundo_tagÚxrM   ÚyÚzÚpointr   Útype_rƒ   Ústr_r  s    ``              @r:   rï   rï   »  s  úè ø€ õ<Eö
öô �h¤Ô$Ð$Ð$Ü�fœcÔ"Ð"Ð"àÐØˆÜ�‹:€DØ€HØ€DØ
ðj	ØÐ#Ø�Ø‘ä˜“J�Ø˜‘	�Ø—6‘6ˆDØ”{Ñ"Ü˜“J�Ø˜‘	�à—6‘6˜T B™YÒ&Ü×1Ñ1ØCÀDÀ6ÈÐKóð ô ˜“J�Ø˜‘	�ðà—v‘v ¨¡Ò*ðä % a§g¡g£Ü % a§g¡g£Ü % a§g¡g£ð%™EðÜ%*¨1¯7©7£^´U¸1¿7¹7³^Ð$D˜Eð $%˜ô
    eÓ,Ô,ØœÑ$ä˜a¤Ô.Ø‘CðÜ*×6Ñ6°t¸Q¿W¹WÓE˜ð
 “	ä"Ÿ™ t¬SÓ1�Ø Ÿw™w�ØœC‘<Ø˜q’yà !§¡§¡£× 5Ñ 5Ó 7˜ð	Ø$Ÿ|™|¨H¸X˜|ÓF˜ñ ä*¨4Ô0Ü#5°dÓ#;™Dä-¨dÔ3Ü#8¸Ó#>˜DÜ   tÓ,Ó,ðHä$ T©5°«<Ó8Ò8ñw øô:  *ò á -¨a¯g©gÓ 6Ù -¨a¯g©gÓ 6Ù -¨a¯g©gÓ 6ð%›Eðûô  *ò á -¨a¯g©gÓ 6Ù -¨a¯g©gÓ 6ð%›Eðûô "ò Ü×1Ñ1ØCÀDÀ6ÈÐKóð ðûô &ò Ü#×5Ñ5Ø=¸d¸VÀ1ÐEóð ðûô .ò Ø$Ÿ|™|¨H¸V˜|ÓD˜Ø Ÿ™ä *× 9Ñ 9Ø"IÈ$ÈÐ Pð÷ðûô, &ò Hà ¤C™<ðLÜ&,¨T±;¸q¿w¹wÓ3GÓ&HÓ HøÜ#-ò LÜ&+×&=Ñ&=¹iÈ»lÓ&KÐ KðLúà"¤e™^ðLÜ&,¨T±=ÀÇÁÓ3IÓ&JÓ JøÜ#-ò LÜ&+×&=Ñ&=¹iÈ»lÓ&KÐ KðLúô #(×"9Ñ"9¹)ÀA»,Ó"GÐGúðHûô ò 	Ùð	üs  …AQÁA6P5 Ã
K Ã>I ÄK Ä*J# ÅK Å	+P5 Å5 K= ÆA P5 Ç6L# È	>P5 ÉM* ÉQÉ>J ÊK ÊJ Ê K Ê#-KËK ËKËK Ë#K:Ë:P5 Ë=#L Ì P5 Ì#A M'Í#P5 Í&M'Í'P5 Í*P2Í<NÎP2Î%O Ï P2ÏO+Ï*P2Ï+%PÐP2Ð.P5 Ð1P2Ð2P5 Ð5	QÐ>QÑ QÑQ)r-   )r6   zUnion[str, Path]r3   r4   rœ   útuple[Drawing, Auditor])r?   r   r3   r4   rœ   rD  )r  )rœ   rD  )r£   rg   rœ   r4   )r¾   r   rœ   rÓ   )rÈ   rÒ   rœ   ztuple[int, Tags])NNr-   )
r?   r   rC   rÎ   rr   úOptional[list]r3   r4   rœ   rÏ   r4  r6  )r?   r   rœ   rÏ   )rú   r4   rœ   r4   )rj   rÐ   rœ   r4   )rj   rÐ   rr   rE  r3   r4   rœ   rÏ   )MÚ
__future__r   r  Útypingr   r   r   r   r   r	   r
   ré   rÛ   Úcollectionsr   Úpathlibr   ÚloggingÚezdxf.lldxfr   r   Úezdxf.lldxf.encodingr   r   r   r   Úezdxf.lldxf.typesr   r   r   r   r   r   r   Úezdxf.lldxf.tagsr   r   Úezdxf.lldxf.validatorr   Úezdxf.tools.codepager   Úezdxf.auditr   r   rG   r!   Úezdxf.eztypesr"   Ú__all__r»   Ú	getLoggerr*  r$   r#   rE   r>   r<   r¢   rÃ   rÄ   rs   Úcompilerõ   rö   rü   rþ   rÿ   r  Úno_type_checkrR   rD   r  r  r  rë   r  rï   rÍ   rA   r:   Ú<module>rW     s  ðõ #ã Û ÷÷ ñ ó Û 	Ý #Ý Û å Ý ÷ó ÷÷ ñ ÷ .Ý <Ý +ß +áÝ&Ý)à�:Ð
€òÐ ð 
ˆ×	Ñ	˜7Ó	#€ð /@ðØðØ(+ðàóô62ð0 /7ðØðØ(+ðàóó<÷ rñ rój	ó;óð "&Ø#Ø#ð	!OØð!Oàð!Oð ð!Oð ð	!Oð
 ó!OðH �—
‘
˜;Ó'€Ø�—
‘
˜<Ó(€óð �"—*‘*ÐCÓD€Ø�"—*‘*ÐDÓE€óð ×Ñò*ó ð*óZ%ðP €Ø
€ó2ó
""ðJ ×Ñð ×#Ñ#Ø#Ø#ð	hØ
ðhð ðhð ð	hð
 òhó ñhrA   