
     hyH                        d Z ddlmZmZmZ ddlZddlZddlmc m	Z ddlm
Z
mZ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 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mZm Z  d	dl!m"Z" d	dl#m$Z$m%Z%m&Z& 	 e'Z(	 ddlm+Z+ ddiZ- edd       eeeeeee dZ.deiZ/dZ0d d e.e0fdZ1dd d e.e0fdZ2 G d d      Z3y# e)$ r e*Z(Y Mw xY w# e,$ r e(Z+Y Sw xY w)aJ  (Experimental) replacement for import/export functionality.

This module contains the `Document` class, a container for a DOM-style 
document (e.g. svg, html, xml, etc.) designed to replace and improve 
upon the IO functionality of svgpathtools (i.e. the svg2paths and 
disvg/wsvg functions). 

An Historic Note:
     The functionality in this module is meant to replace and improve 
     upon the IO functionality previously provided by the the 
     `svg2paths` and `disvg`/`wsvg` functions. 

Example:
    Typical usage looks something like the following.

        >> from svgpathtools import Document
        >> doc = Document('my_file.html')
        >> for path in doc.paths():
        >>     # Do something with the transformed Path object.
        >>     foo(path)
        >>     # Inspect the raw SVG element, e.g. change its attributes
        >>     foo(path.element)
        >>     transform = result.transform
        >>     # Use the transform that was applied to the path.
        >>     foo(path.transform)
        >> foo(doc.tree)  # do stuff using ElementTree's functionality
        >> doc.display()  # display doc in OS's default application
        >> doc.save('my_new_file.html')

A Big Problem:  
    Derivatives and other functions may be messed up by 
    transforms unless transforms are flattened (and not included in 
    css)
    )divisionabsolute_importprint_functionN)Element
SubElementregister_namespace)parseString)StringIO)
gettempdir)time   )
parse_path)parse_transform)
path2pathdellipse2pathd
line2pathdpolyline2pathdpolygon2pathd
rect2pathd)open_in_browser)	transformPathis_path_segment)PathLikesvgzhttp://www.w3.org/2000/svg)pathcircleellipselinepolylinepolygonrectr   zsvg:gc                      yNT xs    q/home/developers/rajanand/mypropertyqr-fmb-refixing-v2/venv/lib/python3.12/site-packages/svgpathtools/document.py<lambda>r)   U           c                      yr$   r%   r&   s    r(   r)   r)   V   r*   r+   c           	      f   t        | t              s#t        dj                  t	        |                    |       s6t        j                  dj                  | | j                  d                   g S t        j                  dddg      fdfd} | t        j                  d	            g}g }|r|j                         }|j                         D ]  \  }	}
t        ||j                  j!                  d
|	z   t"                    D ]o  }|j$                  j'                  t)        |j                  d                  }t%        t+         |
|            |      }||_        ||_        |j/                  |       q  |j1                   ||j                  |j$                               |r|S )a.  Returns the paths inside a group (recursively), expressing the
    paths in the base coordinates.

    Note that if the group being passed in is nested inside some parent
    group(s), we cannot take the parent group(s) into account, because
    xml.etree.Element has no pointer to its parent. You should use
    Document.flattened_paths_from_group(group) to flatten a specific nested group into
    the root coordinates.

    Args:
        group is an Element
        path_conversions (dict):
            A dictionary to convert from an SVG element to a path data
            string. Any element tags that are not included in this
            dictionary will be ignored (including the `path` tag). To
            only convert explicit path elements, pass in
            `path_conversions=CONVERT_ONLY_PATHS`.
    zBMust provide an xml.etree.Element object. Instead you provided {0}zHThe input group [{}] (id attribute: {}) was rejected by the group filteridStackElementgroupr   c           
      d     | |j                  t        | j                  d                        S )Nr   )dotr   get)elementlast_tfr/   s     r(   new_stack_elementz*flattened_paths.<locals>.new_stack_element|   s.    GW[[GKK45&7 8 	8r+   c                     g }t        | j                  t                    D ]  }|j                   ||              |S N)filteriterfindSVG_NAMESPACEappend)parentr5   childrenelemgroup_filtergroup_search_xpathr6   s       r(   get_relevant_childrenz.flattened_paths.<locals>.get_relevant_children   sI    <!??+=}MO 	>DOO-dG<=	> r+      svg:)
isinstancer   	TypeErrorformattypewarningswarnr3   collections
namedtuplenpidentitypopitemsr9   r0   r:   r;   r   r2   r   r   r4   r<   extend)r0   r@   path_filterpath_conversionsrA   rB   stackpathstopkey	converter	path_elempath_tfr   r/   r6   s    `  `         @@r(   flattened_pathsr[   U   s   * eW% 3396$u+3FH 	H `veUYYt_5	7	 )).+2K*@BL8 ubkk!n56EE
iik
 /446 	#NC#K1C1C3J2/ 0 #	--++#IMM+$>?A Ii,@!A7K(!(T"#	# 	*399cmmDE! $ Lr+   Tc                      yr$   r%   r&   s    r(   r)   r)      r*   r+   c                      yr$   r%   r&   s    r(   r)   r)      r*   r+   c                 Z    t         fd|j                         D              st        j                  d       g S t	               |r0 j                         D ]  }j                  t        |              nj                  t                      t	               | ur|gg}d}	|r|j                  d      }
|
d   }|j                  |t              D ]7  }| u r|
}	 n/t        |
      }|j                  |       |j                  |       9 |	o|	D ]i  }j                  t        |             |j                         D ]:  }|j                  d|z   t              D ]  }j                  t        |              < k n|r|	t        d      fd}fd	}t        |||||      S )
zFlatten all the paths in a specific group.

    The paths will be flattened into the 'root' frame. Note that root
    needs to be an ancestor of the group that is being flattened.
    Otherwise, no paths will be returned.c              3   &   K   | ]  }|u  
 y wr8   r%   ).0
descendantgroup_to_flattens     r(   	<genexpr>z-flattened_paths_from_group.<locals>.<genexpr>   s     L*:-L   z:The requested group_to_flatten is not a descendant of rootNr   rD   z5The group_to_flatten is not a descendant of the root!c                 2    t        |       v xr  |       S r8   r.   )r'   desired_groupsr@   s    r(   desired_group_filterz8flattened_paths_from_group.<locals>.desired_group_filter   s    1'<\!_<r+   c                 2    t        |       vxr  |       S r8   rg   )r'   ignore_pathsrR   s    r(   desired_path_filterz7flattened_paths_from_group.<locals>.desired_path_filter   s    1\)={1~=r+   )anyiterrI   rJ   setaddr.   rO   r:   r;   listr<   keys
ValueErrorr[   )rb   root	recursiver@   rR   rS   rA   r0   searchrouterV   frontierchild
future_toprW   rY   ri   rl   rh   rk   s   `  ``             @@r(   flattened_paths_from_groupr{      s    L		LL + 	, 	
 UN%**, 	*Er%y)	* 	2./05L##&**Q-C2wH!**+=}M *,,E!#Y
!!%(j)*  " <E
 #&&r%y1/446 <).s
M)R <I
 ),,R	];<<< 3 6 =TUU=> 4!57J+-?A Ar+   c                       e Zd ZddZed        Zd d efdZdd d	 efd
ZddZ	d Z
ddZddZddZd Zd ZddZddZy)DocumentNc                 V   t        |t              xs t        |t              }|rt        j                  j                  |      nd| _        |$t        j                  t        d            | _
        nt        j                  |      | _
        | j                  j                         | _        y)a\  A container for a DOM-style SVG document.

        The `Document` class provides a simple interface to modify and analyze 
        the path elements in a DOM-style document.  The DOM-style document is 
        parsed into an ElementTree object (stored in the `tree` attribute).

        This class provides functions for extracting SVG data into Path objects.
        The output Path objects will be transformed based on their parent groups.
        
        Args:
            filepath (str or file-like): The filepath of the
                DOM-style object or a file-like object containing it.
        Nr   )rE   stringr   osr   abspathoriginal_filepathetreeElementTreer   treeparsegetrootrt   )selffilepathfrom_filepaths      r(   __init__zDocument.__init__   sx    " #8V4V
8X8V>K!:QU))'%.9DI H-DIII%%'	r+   c                 .    t        |      }t        |      S )z9Constructor for creating a Document object from a string.)r
   r}   )cls
svg_stringsvg_file_objs      r(   from_svg_stringzDocument.from_svg_string  s      
+%%r+   c                      yr$   r%   r&   s    r(   r)   zDocument.<lambda>  r*   r+   c                      yr$   r%   r&   s    r(   r)   zDocument.<lambda>  r*   r+   c                 N    t        | j                  j                         |||      S )zReturns a list of all paths in the document.

        Note that any transform attributes are applied before returning
        the paths.
        )r[   r   r   )r   r@   rR   rS   s       r(   rU   zDocument.paths  s(     tyy002L*,<> 	>r+   Tc                      yr$   r%   r&   s    r(   r)   zDocument.<lambda>  r*   r+   c                      yr$   r%   r&   s    r(   r)   zDocument.<lambda>  r*   r+   c                     t        d |D              r| j                  |      }n*t        |t              st	        dj                  |            |t        j                  d       g S t        || j                  j                         ||||      S )Nc              3   <   K   | ]  }t        |t                y wr8   )rE   r   )r`   ss     r(   rc   z,Document.paths_from_group.<locals>.<genexpr>  s     4z!V$4   zMust provide a list of strings that represent a nested group name, or provide an xml.etree.Element object. Instead you provided {0}z#Could not find the requested group!)all	get_grouprE   r   rF   rG   rI   rJ   r{   r   r   )r   r0   ru   r@   rR   rS   s         r(   paths_from_groupzDocument.paths_from_group  s    4e44 NN5)EE7+++16%=: :
 =MM?@I)%1B1B1Di*6EUW 	Wr+   c                 t   || j                   j                         }nt        |      dkD  r$t        d |D              r| j	                  |      }nPt        |t              st        dj                  |            | j                  |      st        j                  d       t        |t              r|j                         }nRt        |      rt        |      j                         }n-t        |t              r|}nt        dj                  |            |i }n|j!                         }||d<   t#        |d|      S )zAdd a new path to the SVG.r   c              3   <   K   | ]  }t        |t                y wr8   )rE   str)r`   r?   s     r(   rc   z$Document.add_path.<locals>.<genexpr>3  s     #LdJtS$9#Lr   zWMust provide a list of strings or an xml.etree.Element object. Instead you provided {0}z4The requested group does not belong to this Documentz`Must provide a Path, a path segment type, or a valid SVG path d-string. Instead you provided {0}dr   )r   r   lenr   get_or_add_grouprE   r   rF   rG   contains_grouprI   rJ   r   r   r   r   copyr   )r   r   attribsr0   path_svgs        r(   add_pathzDocument.add_path*  s    =II%%'E Z!^#Le#L L))%0EE7+3396%=B B &&u- . / dD!vvxHT"Dz||~Hf% H>>DfTlL L ?GllnG%11r+   c                 \    t        fd| j                  j                         D              S )Nc              3   &   K   | ]  }|u  
 y wr8   r%   )r`   ownedr0   s     r(   rc   z*Document.contains_group.<locals>.<genexpr>Y  s     @e5E>@rd   )rm   r   rn   )r   r0   s    `r(   r   zDocument.contains_groupX  s    @tyy~~/?@@@r+   c                    | j                   j                         }t        |      r[|}|j                  d      }|j	                  t
        t              D ]  }|j                  |      |k(  s|} n ||u ryt        |      r[|S )a  Get a group from the tree, or None if the requested group
        does not exist. Use get_or_add_group(~) if you want a new group
        to be created if it did not already exist.

        `nested_names` is a list of strings which represent group names.
        Each group name will be nested inside of the previous group name.

        `name_attr` is the group attribute that is being used to
        represent the group's name. Default is 'id', but some SVGs may
        contain custom name labels, like 'inkscape:label'.

        Returns the request group. If the requested group did not
        exist, this function will return a None value.
        r   N)r   r   r   rO   r:   SVG_GROUP_TAGr;   r3   r   nested_names	name_attrr0   
prev_group	next_namer?   s          r(   r   zDocument.get_group[  s     		!!#,J$((+I}mD 88I&)3 E
 U" , r+   c                 |   | j                   j                         }t        |      r|}|j                  d      }|j	                  t
        t              D ]  }|j                  |      |k(  s|} n ||u r<|j                  d|       |r(|j                  d      }| j                  d|i|      }|r(t        |      r|S )a  Get a group from the tree, or add a new one with the given
        name structure.

        `nested_names` is a list of strings which represent group names.
        Each group name will be nested inside of the previous group name.

        `name_attr` is the group attribute that is being used to
        represent the group's name. Default is 'id', but some SVGs may
        contain custom name labels, like 'inkscape:label'.

        Returns the requested group. If the requested group did not
        exist, this function will create it, as well as all parent
        groups that it requires. All created groups will be left with
        blank attributes.

        r   r.   )
r   r   r   rO   r:   r   r;   r3   insert	add_groupr   s          r(   r   zDocument.get_or_add_groupz  s    " 		!!#,J$((+I}mD 88I&)3 E
 U" ##Ay1" , 0 0 3I NND)+<eDE # ,$ r+   c                    || j                   j                         }n5| j                  |      s$t        j                  dj                  |             |i }n|j                         }t        |dj                  t        d         |      S )z&Add an empty group element to the SVG.z8The requested group {0} does not belong to this Documentz{{{0}}}gr   )	r   r   r   rI   rJ   rG   r   r   r;   )r   group_attribsr=   s      r(   r   zDocument.add_group  s    >YY&&(F$$V,MM **0&.:  M)..0M&*"3"3% #"#02 	2r+   c                 x    t        j                  | j                  j                               j	                         S r8   )r   tostringr   r   decode)r   s    r(   __repr__zDocument.__repr__  s'    ~~dii//1299;;r+   c                 J     t        t        |             j                  di |S )Nr%   )r	   reprtoprettyxml)r   kwargss     r(   prettyzDocument.pretty  s!    2{4:&22<V<<r+   c                     t        |d      5 }|r"|j                   | j                  di |       n|j                  t        |              d d d        y # 1 sw Y   y xY w)Nzw+r%   )openwriter   r   )r   r   prettifyr   
output_svgs        r(   savezDocument.save  sT    (D! 	-Z  !6v!67  d,		- 	- 	-s   ?AAc                    || j                   d\  }}nIt        j                  j                  t        j                  j	                  | j                               \  }}|dz   t        t                     j                  dd      z   |z   }t        j                  j                  t               |      }t        |d      5 }|j                  t        |              ddd       t        |       y# 1 sw Y   xY w)z:Displays/opens the doc using the OS's default application.N)unnamedz.svg_.-w)r   r   r   splitextbasenamer   r   replacejoinr   r   r   r   r   )r   r   	orig_nameexttmp_namer   s         r(   displayzDocument.display  s     %%-!2	3 GG$$RWW%5%5d6L6L%MN 	3 3TV)<)<S#)FFLHww||JL(;H (C  	)JT$Z(	) 	!	) 	)s   >C--C6r8   )NNrg   )F)__name__
__module____qualname__r   classmethodr   CONVERSIONSrU   r   r   r   r   r   r   r   r   r   r   r%   r+   r(   r}   r}      sl    (8 & & "0(;> 15>%3kW&,2\A>%N2 <=-"r+   r}   )4__doc__
__future__r   r   r   r   rK   xml.etree.ElementTreer   r   r   r   r   xml.dom.minidomr	   rI   ior
   tempfiler   r   numpyrM   parserr   r   svg_to_pathsr   r   r   r   r   r   	misctoolsr   r   r   r   r   
basestringr   	NameErrorr   r   ImportErrorr;   r   CONVERT_ONLY_PATHSr   r[   r{   r}   r%   r+   r(   <module>r      s  !H A @ 	  % % I I '       #F F & 2 2F
 45 56 7 "&'!)'!# j)  )7 .'4GT BF,:+90;2?	FARf" f"Y  F  Hs$   5B; 8C ;CCCC