
    h                     
   S r SSKJrJrJr  SSKJr  SSKrSSKJ	r	   SSK
r
\
R                  rSr\	" S/ S	Q5      r/ S
QrSUS jrS r\
R*                  " \
R,                  5      \
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  S9\
R.                  " \
R,                  \
R,                  \
R,                  S9S 5       5       5       r\
R*                  " \
R,                  5      \
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  S9\
R.                  " \
R,                  \
R,                  S9SUS j5       5       5       rSrSr\
R:                  \
R<                  \
R*                  " \
R,                  5      \
R.                  " \
R0                  \
R0                  S9S 5       5       5       5       r\
R:                  \
R<                  \
R*                  " \
R,                  5      \
R.                  " \
R,                  S9S 5       5       5       5       r S r!\
R*                  " \
R,                  5      \
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  S9\
R.                  " \
R,                  \
R,                  \
R,                  \
R,                  \
R,                  \
R,                  \
R,                  S9S 5       5       5       r"S r#\
R*                  " \
R,                  5      \
R.                  " \
R0                  \
R0                  \
R0                  S9\
R.                  " \
R,                  \
R,                  \
R,                  S9S  5       5       5       r$S! r%S" r&\
R*                  " \
R,                  5      \
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  S9\
R.                  " \
R,                  \
R,                  \
R,                  \
R,                  \
R,                  S#9S$ 5       5       5       r'S% r(S& r)S' r*S( r+S) r,S* r-\
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  S+9S, 5       r.\
R*                  " \
R0                  5      \
R.                  " \
R,                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  S-9\
R.                  " \
R,                  \
R,                  \
R,                  \
R,                  S.9S/ 5       5       5       r/S0 r0S1 r1\
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  \
R,                  \
R,                  \
R,                  \
R,                  \
R,                  \
R0                  \
R0                  \
R0                  \
R0                  S29S3 5       r2SS4KJ3r3J4r4J5r5J6r6  \34S5 jr7S6 r8S7 r9S8 r:\
R:                  \
R<                  \
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  S99S: 5       5       5       r;S; r<S< r=\
R:                  \
R<                  \
R.                  " \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  \
R0                  S=9S> 5       5       5       r>S? r?S@ r@SA rA\
R*                  " \
R0                  5      \
R.                  " \
R,                  \
R0                  \
R0                  \
R0                  \
R0                  SB9\
R.                  " \
R,                  \
R,                  \
R,                  SC9SD 5       5       5       rBSE rCSF rDSG rESH rFSI rGSJ rHSK rISL rJSM rK SVSN jrLSO rMSP rNSQ rOSR rPSS rQ\RST:X  a4  SSKSrSSSKTrT\SR                  " \TR                  " 5       R                  5        gg! \\4 a
    SSKJ
r
   GN_f = f)WzNfontTools.misc.bezierTools.py -- tools for working with Bezier path segments.
    )
calcBoundssectRectrectArea)IdentityN)
namedtuple)cythong&.>Intersectionptt1t2)approximateCubicArcLengthapproximateCubicArcLengthCapproximateQuadraticArcLengthapproximateQuadraticArcLengthCcalcCubicArcLengthcalcCubicArcLengthCcalcQuadraticArcLengthcalcQuadraticArcLengthCcalcCubicBoundscalcQuadraticBounds	splitLinesplitQuadratic
splitCubicsplitQuadraticAtTsplitCubicAtTsplitCubicAtTCsplitCubicIntoTwoAtTCsolveQuadratic
solveCubicquadraticPointAtTcubicPointAtTcubicPointAtTClinePointAtTsegmentPointAtTlineLineIntersectionscurveLineIntersectionscurveCurveIntersectionssegmentSegmentIntersectionsc                 P    [        [        U 6 [        U6 [        U6 [        U6 U5      $ )a  Calculates the arc length for a cubic Bezier segment.

Whereas :func:`approximateCubicArcLength` approximates the length, this
function calculates it by "measuring", recursively dividing the curve
until the divided segments are shorter than ``tolerance``.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.
    tolerance: Controls the precision of the calcuation.

Returns:
    Arc length value.
)r   complex)pt1pt2pt3pt4	tolerances        L/var/www/html/env/lib/python3.13/site-packages/fontTools/misc/bezierTools.pyr   r   8   s,     w}gsmWc]I     c                 p    U SX-   -  -   U-   S-  nX2-   U-
  U -
  S-  nX U-   S-  XE-
  U4XDU-   X#-   S-  U44$ )N   g      ?      ? )p0p1p2p3midderiv3s         r1   _split_cubic_into_twor=   K   sc    RW"e
+CglR5(F	2g_clC0	FlRWOR0 r2   )r7   r8   r9   r:   )multarchboxc                     [        X-
  5      n[        X-
  5      [        X#-
  5      -   [        X4-
  5      -   nXP-  [        -   U:  a  XV-   S-  $ [        XX45      u  px[        U /UQ76 [        U /UQ76 -   $ Nr5   )absEPSILONr=   _calcCubicArcLengthCRecurse)	r>   r7   r8   r9   r:   r?   r@   onetwos	            r1   rE   rE   T   s     rw<D
bg,RW
%BG
4C{W#
c!!(8*46#69T:
:
 
 	
r2   r,   r-   r.   r/   )r0   r>   c                 ,    SSU-  -   n[        XPXU5      $ )zCalculates the arc length for a cubic Bezier segment.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.
    tolerance: Controls the precision of the calcuation.

Returns:
    Arc length value.
      ?g      ?)rE   )r,   r-   r.   r/   r0   r>   s         r1   r   r   h   s!    * y D&t#C@@r2      g|=v1v2c                 :    XR                  5       -  R                  $ N)	conjugaterealrL   s     r1   _dotrS      s    
 %%%r2   xc                 z    U [         R                  " U S-  S-   5      -  S-  [         R                  " U 5      S-  -   $ )N      )mathsqrtasinhrT   s    r1   _intSecAtanr\      s7     tyyA""Q&A):::r2   c                 @    [        [        U 6 [        U6 [        U6 5      $ )a6  Calculates the arc length for a quadratic Bezier segment.

Args:
    pt1: Start point of the Bezier as 2D tuple.
    pt2: Handle point of the Bezier as 2D tuple.
    pt3: End point of the Bezier as 2D tuple.

Returns:
    Arc length value.

Example::

    >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment
    0.0
    >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points
    80.0
    >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical
    80.0
    >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points
    107.70329614269008
    >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0))
    154.02976155645263
    >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0))
    120.21581243984076
    >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50))
    102.53273816445825
    >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # collinear points, control point outside
    66.66666666666667
    >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back
    40.0
)r   r+   r,   r-   r.   s      r1   r   r      s     @ #7C='3-#OOr2   )r,   r-   r.   d0d1dn)scaleorigDistabx0x1Lenc                    X-
  nX!-
  nXC-
  nUS-  n[        U5      nUS:X  a  [        X -
  5      $ [        Xc5      n[        U5      [        :  a?  [        X45      S:  a  [        X -
  5      $ [        U5      [        U5      pX-  X-  -   X-   -  $ [        XS5      U-  n[        XT5      U-  n[        S[        U5      [        U5      -
  -  U-  X|U-
  -  -  5      nU$ )a  Calculates the arc length for a quadratic Bezier segment.

Args:
    pt1: Start point of the Bezier as a complex number.
    pt2: Handle point of the Bezier as a complex number.
    pt3: End point of the Bezier as a complex number.

Returns:
    Arc length value.
y              ?        r   rW   )rC   rS   epsilonr\   )r,   r-   r.   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   s                 r1   r   r      s    @ 
B	B
A	BAFE|39~A{H
8}w<1sy>!2wB1!%((	ax	B	ax	B
a;r?[_45@ERTWDUV
WCJr2   c                 @    [        [        U 6 [        U6 [        U6 5      $ )a  Calculates the arc length for a quadratic Bezier segment.

Uses Gauss-Legendre quadrature for a branch-free approximation.
See :func:`calcQuadraticArcLength` for a slower but more accurate result.

Args:
    pt1: Start point of the Bezier as 2D tuple.
    pt2: Handle point of the Bezier as 2D tuple.
    pt3: End point of the Bezier as 2D tuple.

Returns:
    Approximate arc length value.
)r   r+   r^   s      r1   r   r      s      *'3-#QTVVr2   r^   )v0rM   rN   c                     [        SU -  SU-  -   SU-  -   5      n[        X -
  5      S-  n[        SU -  SU-  -
  SU-  -   5      nX4-   U-   $ )a  Calculates the arc length for a quadratic Bezier segment.

Uses Gauss-Legendre quadrature for a branch-free approximation.
See :func:`calcQuadraticArcLength` for a slower but more accurate result.

Args:
    pt1: Start point of the Bezier as a complex number.
    pt2: Handle point of the Bezier as a complex number.
    pt3: End point of the Bezier as a complex number.

Returns:
    Approximate arc length value.
g̔xb߿gb?gFVW?gqq?gFVWg̔xb?rC   )r,   r-   r.   rn   rM   rN   s         r1   r   r      sx    B 
S #4s#::=ORU=UU
B 
SY,	,B	c!$5$;;>ORU>UU
B 7R<r2   c                 ^   [        XU5      u  u  p4u  pVu  pxUS-  n	US-  n
/ nU	S:w  a  UR                  U* U	-  5        U
S:w  a  UR                  U* U
-  5        U Vs/ s H4  nSUs=::  a  S:  d  M  O  M  X<-  U-  X\-  -   U-   XL-  U-  Xl-  -   U-   4PM6     snX/-   n[        U5      $ s  snf )a  Calculates the bounding rectangle for a quadratic Bezier segment.

Args:
    pt1: Start point of the Bezier as a 2D tuple.
    pt2: Handle point of the Bezier as a 2D tuple.
    pt3: End point of the Bezier as a 2D tuple.

Returns:
    A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.

Example::

    >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0))
    (0, 0, 100, 50.0)
    >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100))
    (0.0, 0.0, 100, 100)
       @r   rX   )calcQuadraticParametersappendr   )r,   r-   r.   axaybxbycxcyax2ay2rootstpointss                 r1   r   r   *  s    $ $;3S#I HRhr
s(C
s(CE
axbS3Y
axbS3Y A:A: 	= 	=!bf	r	!26A:#6#;< 

	F
 fs   B*2B*6"B*c                 N    [        [        U 6 [        U6 [        U6 [        U6 5      $ )af  Approximates the arc length for a cubic Bezier segment.

Uses Gauss-Lobatto quadrature with n=5 points to approximate arc length.
See :func:`calcCubicArcLength` for a slower but more accurate result.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.

Returns:
    Arc length value.

Example::

    >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0))
    190.04332968932817
    >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100))
    154.8852074945903
    >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150.
    149.99999999999991
    >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150.
    136.9267662156362
    >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp
    154.80848416537057
)r   r+   rH   s       r1   r   r   L  s*    2 &w}gsmWc] r2   )rn   rM   rN   v3v4c                    [        X-
  5      S-  n[        SU -  SU-  -   SU-  -   SU-  -   5      n[        X0-
  U-   U-
  5      S-  n[        SU -  SU-  -
  SU-  -
  SU-  -   5      n[        X2-
  5      S-  nXE-   U-   U-   U-   $ )	zApproximates the arc length for a cubic Bezier segment.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.

Returns:
    Arc length value.
g333333?gc1g85$t?gu|Y?g#$?g?g#$gc1?rp   )	r,   r-   r.   r/   rn   rM   rN   r   r   s	            r1   r   r   j  s    > 
SY$	B	S 
c
!	"
c
!	" c
!	"
B 
SY_s"	#&9	9B	S 
c
!	"
c
!	" c
!	"
B 
SY$	B7R<"r!!r2   c                    [        XX#5      u  u  pEu  pgu  pu  pUS-  nUS-  nUS-  nUS-  n[        XU5       Vs/ s H  nSUs=::  a  S:  d  M  O  M  UPM     nn[        XU	5       Vs/ s H  nSUs=::  a  S:  d  M  O  M  UPM     nnUU-   nU Vs/ s H=  nUU-  U-  U-  UU-  U-  -   UU-  -   U
-   UU-  U-  U-  UU-  U-  -   U	U-  -   U-   4PM?     snX/-   n[        U5      $ s  snf s  snf s  snf )a(  Calculates the bounding rectangle for a quadratic Bezier segment.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.

Returns:
    A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.

Example::

    >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0))
    (0, 0, 100, 75.0)
    >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100))
    (0.0, 0.0, 100, 100)
    >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0)))
    35.566243 0.000000 64.433757 75.000000
      @rr   r   rX   )calcCubicParametersr   r   )r,   r-   r.   r/   ru   rv   rw   rx   ry   rz   dxdyax3ay3bx2by2r~   xRootsyRootsr}   r   s                        r1   r   r     sE   $ .A3-T*HRhr(2
s(C
s(C
s(C
s(C'"5D5Aa!aa5FD'"5D5Aa!aa5FDVOE 
 A FQJNR!VaZ'"q&025FQJNR!VaZ'"q&025	
  

F f EDs*   C+C+C++C0 C0C0AC5c                     U u  pEUu  pgXd-
  nXu-
  n	Un
UnX4U   nUS:X  a  X4/$ X*U4U   -
  U-  nSUs=::  a  S:  a  O  OX-  U
-   X-  U-   4nX4X4/$ X4/$ )a  Split a line at a given coordinate.

Args:
    pt1: Start point of line as 2D tuple.
    pt2: End point of line as 2D tuple.
    where: Position at which to split the line.
    isHorizontal: Direction of the ray splitting the line. If true,
        ``where`` is interpreted as a Y coordinate; if false, then
        ``where`` is interpreted as an X coordinate.

Returns:
    A list of two line segments (each line segment being two 2D tuples)
    if the line was successfully split, or a list containing the original
    line.

Example::

    >>> printSegments(splitLine((0, 0), (100, 100), 50, True))
    ((0, 0), (50, 50))
    ((50, 50), (100, 100))
    >>> printSegments(splitLine((0, 0), (100, 100), 100, True))
    ((0, 0), (100, 100))
    >>> printSegments(splitLine((0, 0), (100, 100), 0, True))
    ((0, 0), (0, 0))
    ((0, 0), (100, 100))
    >>> printSegments(splitLine((0, 0), (100, 100), 0, False))
    ((0, 0), (0, 0))
    ((0, 0), (100, 100))
    >>> printSegments(splitLine((100, 0), (0, 0), 50, False))
    ((100, 0), (50, 0))
    ((50, 0), (0, 0))
    >>> printSegments(splitLine((0, 100), (0, 0), 50, True))
    ((0, 100), (0, 50))
    ((0, 50), (0, 0))
r   rX   r6   )r,   r-   whereisHorizontalpt1xpt1ypt2xpt2yru   rv   rw   rx   re   r~   midPts                  r1   r   r     s    H JDJD	B	B	B	B	AAv
|	b,'	'1,AAzzRVb[(ul++
|r2   c                     [        XU5      u  pVn[        XT   Xd   Xt   U-
  5      n[        S U 5       5      nU(       d  XU4/$ [        XVU/UQ76 $ )a  Split a quadratic Bezier curve at a given coordinate.

Args:
    pt1,pt2,pt3: Control points of the Bezier as 2D tuples.
    where: Position at which to split the curve.
    isHorizontal: Direction of the ray splitting the curve. If true,
        ``where`` is interpreted as a Y coordinate; if false, then
        ``where`` is interpreted as an X coordinate.

Returns:
    A list of two curve segments (each curve segment being three 2D tuples)
    if the curve was successfully split, or a list containing the original
    curve.

Example::

    >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False))
    ((0, 0), (50, 100), (100, 0))
    >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False))
    ((0, 0), (25, 50), (50, 50))
    ((50, 50), (75, 50), (100, 0))
    >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False))
    ((0, 0), (12.5, 25), (25, 37.5))
    ((25, 37.5), (62.5, 75), (100, 0))
    >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True))
    ((0, 0), (7.32233, 14.6447), (14.6447, 25))
    ((14.6447, 25), (50, 75), (85.3553, 25))
    ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15))
    >>> # XXX I'm not at all sure if the following behavior is desirable:
    >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True))
    ((0, 0), (25, 50), (50, 50))
    ((50, 50), (50, 50), (50, 50))
    ((50, 50), (75, 50), (100, 0))
c              3   L   #    U  H  nS Us=::  a  S:  d  M  O  M  Uv   M     g7fr   rX   Nr6   .0r~   s     r1   	<genexpr>!splitQuadratic.<locals>.<genexpr>"       :)QqAzzqzq)   $$	$)rs   r   sorted_splitQuadraticAtT)	r,   r-   r.   r   r   re   rf   c	solutionss	            r1   r   r     se    F &c4GA!	!/E*AI :)::I3  aA2	22r2   c                     [        XX#5      u  pgp[        Xe   Xu   X   X   U-
  5      n
[        S U
 5       5      n
U
(       d  XX#4/$ [        XgX/U
Q76 $ )a  Split a cubic Bezier curve at a given coordinate.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.
    where: Position at which to split the curve.
    isHorizontal: Direction of the ray splitting the curve. If true,
        ``where`` is interpreted as a Y coordinate; if false, then
        ``where`` is interpreted as an X coordinate.

Returns:
    A list of two curve segments (each curve segment being four 2D tuples)
    if the curve was successfully split, or a list containing the original
    curve.

Example::

    >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False))
    ((0, 0), (25, 100), (75, 100), (100, 0))
    >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False))
    ((0, 0), (12.5, 50), (31.25, 75), (50, 75))
    ((50, 75), (68.75, 75), (87.5, 50), (100, 0))
    >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True))
    ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25))
    ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25))
    ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15))
c              3   L   #    U  H  nS Us=::  a  S:  d  M  O  M  Uv   M     g7fr   r6   r   s     r1   r   splitCubic.<locals>.<genexpr>G  r   r   )r   r    r   _splitCubicAtT)r,   r-   r.   r/   r   r   re   rf   r   ra   r   s              r1   r   r   (  si    6 %Ss8JA!	!/1?U;RI :)::I3$%%!1y11r2   c                 :    [        XU5      u  pEn[        XEU/UQ76 $ )a]  Split a quadratic Bezier curve at one or more values of t.

Args:
    pt1,pt2,pt3: Control points of the Bezier as 2D tuples.
    *ts: Positions at which to split the curve.

Returns:
    A list of curve segments (each curve segment being three 2D tuples).

Examples::

    >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5))
    ((0, 0), (25, 50), (50, 50))
    ((50, 50), (75, 50), (100, 0))
    >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75))
    ((0, 0), (25, 50), (50, 50))
    ((50, 50), (62.5, 50), (75, 37.5))
    ((75, 37.5), (87.5, 25), (100, 0))
)rs   r   )r,   r-   r.   tsre   rf   r   s          r1   r   r   M  s&    ( &c4GA!aA+++r2   c                 |    [        XX#5      u  pVpx[        XVXx/UQ76 n	U /U	S   SS Q7U	S'   / U	S   SS QUP7U	S'   U	$ )a  Split a cubic Bezier curve at one or more values of t.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.
    *ts: Positions at which to split the curve.

Returns:
    A list of curve segments (each curve segment being four 2D tuples).

Examples::

    >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5))
    ((0, 0), (12.5, 50), (31.25, 75), (50, 75))
    ((50, 75), (68.75, 75), (87.5, 50), (100, 0))
    >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75))
    ((0, 0), (12.5, 50), (31.25, 75), (50, 75))
    ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25))
    ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0))
r   rX   N)r   r   )
r,   r-   r.   r/   r   re   rf   r   ra   splits
             r1   r   r   e  sd    ( %Ss8JA!1++E
 #eAhqrl#E!H&%)CR.&#&E"ILr2   )r,   r-   r.   r/   re   rf   r   ra   c              '   X   #    [        XX#5      u  pVpx[        XVXx/UQ76  Sh  vN   g N7f)a  Split a cubic Bezier curve at one or more values of t.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers..
    *ts: Positions at which to split the curve.

Yields:
    Curve segments (each curve segment being four complex numbers).
N)calcCubicParametersC_splitCubicAtTC)	r,   r-   r.   r/   r   re   rf   r   ra   s	            r1   r   r     s,     ( &c9JA!qQ/B///s    *(*)r~   r,   r-   r.   r/   pointAtToff1off2)r   _1_t_1_t_2_2_t_1_tc                     XD-  nSU-
  nXf-  nSU-  U-  nXv-  U -  SXt-  U-  Xe-  U-  -   -  -   XT-  U-  -   n	Xp-  X-  -   XR-  -   n
Xq-  X-  -   XS-  -   nXU -
  U-  -   nX2U-
  U-  -   nXX4XX#44$ )zSplit a cubic Bezier curve at t.

Args:
    pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.
    t: Position at which to split the curve.

Returns:
    A tuple of two curve segments (each curve segment being four complex numbers).
rX   rW   r4   r6   )r,   r-   r.   r/   r~   r   r   r   r   r   r   r   s               r1   r   r     s    0 
Bq5D[F1ut|Ha6:#3di#o#EFFRUU  <(.(283D<(.(283D
sa
C
sd"
"Ct&(BCCr2   c                    [        U5      n/ nUR                  SS5        UR                  S5        U u  pVUu  pxUu  p[        [	        U5      S-
  5       H  nX;   nX;S-      nX-
  nX-  nX_-  nXo-  nSU-  U-  U-   U-  nSU-  U-  U-   U-  nX-  nUU-  X|-  -   U	-   nUU-  X-  -   U
-   n[        UU4UU4UU45      u  nnnUR                  UUU45        M     U$ )Nr   rk   rJ   rX   rW   )listinsertrt   rangelencalcQuadraticPoints)re   rf   r   r   segmentsru   rv   rw   rx   ry   rz   ir   r   deltadelta_2a1xa1yb1xb1yt1_2c1xc1yr,   r-   r.   s                             r1   r   r     s   	bBHIIaIIcNFBFBFB3r7Q;UAY-ll2v{R5(2v{R5(w4i"'!B&4i"'!B&+S#Jc
S#JOS#c3(    Or2   c                 \   [        U5      nUR                  SS5        UR                  S5        / nU u  pgUu  pUu  pUu  p[        [	        U5      S-
  5       H  nXN   nXNS-      nUU-
  nUU-  nUU-  nX-  nUU-  nUU-  nUU-  nSU-  U-  U-   U-  nSU-  U-  U	-   U-  nSU-  U-  U
-   SU-  U-  -   U-  nSU	-  U-  U-   SU-  U-  -   U-  nUU-  UU-  -   X-  -   U-   nUU-  U	U-  -   X-  -   U-   n[        UU4UU4UU4UU45      u  nnn n!UR                  UUU U!45        M     U$ Nr   rk   rJ   rX   r4   rW   )r   r   rt   r   r   calcCubicPoints)"re   rf   r   ra   r   r   ru   rv   rw   rx   ry   rz   r   r   r   r   r   r   r   delta_3r   t1_3r   r   r   r   r   r   d1xd1yr,   r-   r.   r/   s"                                     r1   r   r     s   	bBIIaIIcNHFBFBFBFB3r7Q;UAYR%-'/wDy 7l7l2v{R7*2v{R7*2v{R!b&4-/582v{R!b&4-/584i"t)#bg-24i"t)#bg-2,#Jc
S#Jc

S#s 	c3,--  . Or2   )re   rf   r   ra   r   r   r   r   r   a1b1c1r`   c              '     #    [        U5      nUR                  SS5        UR                  S5        [        [	        U5      S-
  5       Hv  nXE   nXES-      nXv-
  nX-  n	X-  n
Xf-  nXk-  nX
-  nSU -  U-  U-   U	-  nSU-  U-  U-   SU -  U-  -   U-  nX-  X-  -   X&-  -   U-   n[        XUU5      u  nnnnUUUU4v   Mx     g 7fr   )r   r   rt   r   r   calcCubicPointsC)re   rf   r   ra   r   r   r   r   r   r   r   r   r   r   r   r   r`   r,   r-   r.   r/   s                        r1   r   r     s       
bBIIaIIcN3r7Q;UAY-/wy [!ebj1n'!ebj1nq1ut|+u4X 16)A--bb"=S#sCc""!  s   CC)rZ   acoscospic                     [        U 5      [        :  a!  [        U5      [        :  a  / nU$ U* U-  /n U$ X-  SU -  U-  -
  nUS:  a"  U" U5      nU* U-   S-  U -  U* U-
  S-  U -  /nU$ / nU$ )u'  Solve a quadratic equation.

Solves *a*x*x + b*x + c = 0* where a, b and c are real.

Args:
    a: coefficient of *x²*
    b: coefficient of *x*
    c: constant term

Returns:
    A list of roots. Note that the returned list is neither guaranteed to
    be sorted nor to contain unique values!
      @rk   rr   rC   rl   )re   rf   r   rZ   r}   DDrDDs          r1   r   r   /  s     1vq6GE L R!VHE L US1Wq[ 9r(Cb3h#%)QBH+;a+?@E L ELr2   c           
         [        U 5      [        :  a  [        XU5      $ [        U 5      n X-  nX -  nX0-  nXD-  SU-  -
  S-  nSU-  U-  U-  SU-  U-  -
  SU-  -   S-  nX-  n	Xw-  U-  n
U	[        :  a  SOU	n	[        U
5      [        :  a  SOU
n
X-
  nU	S:X  a  U
S:X  a  [	        U* S-  [
        5      nXU/$ U[        S-  ::  Gay  [        [        [        U[        U
5      -  S	5      S
5      5      nS[        U5      -  nUS-  nU[        US-  5      -  U-
  nU[        US[        -  -   S-  5      -  U-
  nU[        US[        -  -   S-  5      -  U-
  n[        UUU/5      u  nnnUU-
  [        :  a+  UU-
  [        :  a  [	        UU-   U-   S-  [
        5      =n=nnOUU-
  [        :  a)  [	        UU-   S-  [
        5      =nn[	        U[
        5      nOfUU-
  [        :  a)  [	        U[
        5      n[	        UU-   S-  [
        5      =nnO0[	        U[
        5      n[	        U[
        5      n[	        U[
        5      nUUU/$ [        [        U5      [        U5      -   S5      nXU-  -   nUS:  a  U* n[	        XS-  -
  [
        5      nU/$ )u  Solve a cubic equation.

Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real.

Args:
    a: coefficient of *x³*
    b: coefficient of *x²*
    c: coefficient of *x*
    d: constant term

Returns:
    A list of roots. Note that the returned list is neither guaranteed to
    be sorted nor to contain unique values!

Examples::

    >>> solveCubic(1, 1, -6, 0)
    [-3.0, -0.0, 2.0]
    >>> solveCubic(-10.0, -9.0, 48.0, -29.0)
    [-2.9, 1.0, 1.0]
    >>> solveCubic(-9.875, -9.0, 47.625, -28.75)
    [-2.911392, 1.0, 1.0]
    >>> solveCubic(1.0, -4.5, 6.75, -3.375)
    [1.5, 1.5, 1.5]
    >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123)
    [0.5, 0.5, 0.5]
    >>> solveCubic(
    ...     9.0, 0.0, 0.0, -7.62939453125e-05
    ... ) == [-0.0, -0.0, -0.0]
    True
r   g      "@rr   g      ;@g      K@r   rk   r5   rJ   g      g       r   UUUUUU?)rC   rl   r   floatroundepsilonDigitsr   maxminrZ   r   r   r   pow)re   rf   r   ra   r   a2a3QRR2Q3R2_Q3rU   thetarQ2a1_3rg   rh   x2s                      r1   r    r    P  s   L 1v aA&&aA	
B	
B	
B	38	s"A	rB	cBhm	+dRi	74?A	
B	
B7lB"gRBGE	SyR3Y2#)]+ay	'C-	SQb\3/67T!WnCx3us{##d*3b(C/00473b(C/0047RRL)
B7Wb7!2 "r'B,#!5}EEBEb"WwR"WO];;Br=)B"Wwr=)BR"WO];;Br=)Br=)Br=)BB|Uc!f$g.AI8A!3h,.s
r2   c                 b    Uu  p4Uu  pVU u  pxX7-
  S-  n	XH-
  S-  n
XW-
  U	-
  nXh-
  U
-
  nX4X4Xx44$ )Nrr   r6   )r,   r-   r.   r   y2x3y3ry   rz   rw   rx   ru   rv   s                r1   rs   rs     sV    FBFBFB
'SB
'SB	2B	2B8bXx''r2   c                     Uu  pEUu  pgUu  pU u  pXJ-
  S-  nX[-
  S-  nXd-
  S-  U-
  nXu-
  S-  U-
  nX-
  U-
  U-
  nX-
  U-
  U-
  nUU4X4X4X44$ Nr   r6   )r,   r-   r.   r/   r   r   r   r   x4y4r   r   ry   rz   rw   rx   ru   rv   s                     r1   r   r     s    FBFBFBFB
'SB
'SB
'S2	B
'S2	B	2	B	2	B8bXx"11r2   )r,   r-   r.   r/   re   rf   r   c                 @    X-
  S-  nX!-
  S-  U-
  nX0-
  U-
  U-
  nXeX@4$ r   r6   )r,   r-   r.   r/   r   rf   re   s          r1   r   r     s;     
cA	cAA	AA!>r2   c                 n    U u  p4Uu  pVUu  pxUn	Un
US-  U-   nUS-  U-   nX5-   U-   nXF-   U-   nX4X4X44$ rB   r6   )re   rf   r   ru   rv   rw   rx   ry   rz   rh   y1r   r   r   r   s                  r1   r   r     sd    FBFBFB	B	B
s(bB
s(bB	2B	2B8bXx''r2   c                     U u  pEUu  pgUu  pUu  pU
nUnUS-  U
-   nU	S-  U-   nXh-   S-  U-   nXy-   S-  U-   nXJ-   U-   U-   nX[-   U	-   U-   nX4X4UU4UU44$ r   r6   )re   rf   r   ra   ru   rv   rw   rx   ry   rz   r   r   rh   r   r   r   r   r   r   r   s                       r1   r   r     s    FBFBFBFB	B	B
s(bB
s(bB
'S2	B
'S2	B	2	B	2	B8bXBx"b11r2   re   rf   r   ra   r9   r:   p4c                 B    US-  U-   nX-   S-  U-   nX-   U-   U-   nX4XV4$ )Nr   r6   r   s          r1   r   r     s;     
eqB
%E	R	B	
QB2?r2   c                 R    U S   SU-
  -  US   U-  -   U S   SU-
  -  US   U-  -   4$ )zFinds the point at time `t` on a line.

Args:
    pt1, pt2: Coordinates of the line as 2D tuples.
    t: The time along the line.

Returns:
    A 2D tuple with the coordinates of the point.
r   rX   r6   )r,   r-   r~   s      r1   r$   r$     sC     Vq1uA
*c!fA.>Q!.KMMr2   c                     SU-
  SU-
  -  U S   -  SSU-
  -  U-  US   -  -   X3-  US   -  -   nSU-
  SU-
  -  U S   -  SSU-
  -  U-  US   -  -   X3-  US   -  -   nXE4$ )zFinds the point at time `t` on a quadratic curve.

Args:
    pt1, pt2, pt3: Coordinates of the curve as 2D tuples.
    t: The time along the curve.

Returns:
    A 2D tuple with the coordinates of the point.
rX   r   rW   r6   )r,   r-   r.   r~   rU   ys         r1   r!   r!     s     
Q1q5CF"Q!a%[1_s1v%==ANA	
Q1q5CF"Q!a%[1_s1v%==ANA6Mr2   c                     XD-  nSU-
  nXf-  nXv-  U S   -  SXt-  US   -  Xe-  US   -  -   -  -   XT-  US   -  -   nXv-  U S   -  SXt-  US   -  Xe-  US   -  -   -  -   XT-  US   -  -   n	X4$ )zFinds the point at time `t` on a cubic curve.

Args:
    pt1, pt2, pt3, pt4: Coordinates of the curve as 2D tuples.
    t: The time along the curve.

Returns:
    A 2D tuple with the coordinates of the point.
rX   r   r4   r6   )
r,   r-   r.   r/   r~   r   r   r   rU   r   s
             r1   r"   r"   ,  s     
Bq5D[FA
vzCF"TYQ%77
8	9
&3q6/	  	A
vzCF"TYQ%77
8	9
&3q6/	 
 6Mr2   )r~   r,   r-   r.   r/   )r   r   r   c                 `    XD-  nSU-
  nXf-  nXv-  U -  SXt-  U-  Xe-  U-  -   -  -   XT-  U-  -   $ )zFinds the point at time `t` on a cubic curve.

Args:
    pt1, pt2, pt3, pt4: Coordinates of the curve as complex numbers.
    t: The time along the curve.

Returns:
    A complex number with the coordinates of the point.
rX   r4   r6   )r,   r-   r.   r/   r~   r   r   r   s           r1   r#   r#   F  sP    & 
Bq5D[F=3fj3&6S&H!IIBFUXLXXr2   c                     [        U 5      S:X  a  [        / U QUP76 $ [        U 5      S:X  a  [        / U QUP76 $ [        U 5      S:X  a  [        / U QUP76 $ [	        S5      eNrW   r4      Unknown curve degree)r   r$   r!   r"   
ValueError)segr~   s     r1   r%   r%   _  sh    
3x1}$S$!$$	SQ )#)q))	SQ%c%1%%
+
,,r2   c                     U u  p4Uu  pVUu  px[        X5-
  5      [        :  a  [        XF-
  5      [        :  a  g[        X5-
  5      [        XF-
  5      :  a	  Xs-
  XS-
  -  $ X-
  Xd-
  -  $ )Nr   r   )	ser   sxsyexeypxpys	            r1   _line_t_of_ptr  n  sg    FBFBFB
27|g#bg,"8
27|c"'l"BG$$BG$$r2   c                     U S   US   -
  US   US   -
  -  nU S   US   -
  US   US   -
  -  nUS:*  =(       a    US:*  (       + $ )Nr   rX   rk   r6   )re   rf   originxDiffyDiffs        r1   '_both_points_are_on_same_side_of_originr  |  s`    qTF1I!A$"23EqTF1I!A$"23E-#..r2   c           	         U u  pEUu  pgUu  pUu  p[         R                  " X5      (       a8  [         R                  " XF5      (       a  [         R                  " XH5      (       d  / $ [         R                  " X5      (       a8  [         R                  " XW5      (       a  [         R                  " XY5      (       d  / $ [         R                  " X5      (       a  [         R                  " X5      (       a  / $ [         R                  " XF5      (       a  [         R                  " XW5      (       a  / $ [         R                  " Xd5      (       a8  UnX-
  X-
  -  nXU-
  -  U	-   nX4n[        U[        XU5      [        X#U5      S9/$ [         R                  " X5      (       a8  UnXu-
  Xd-
  -  nUX-
  -  U-   nX4n[        U[        XU5      [        X#U5      S9/$ Xu-
  Xd-
  -  nX-
  X-
  -  n[         R                  " UU5      (       a  / $ UU-  U-
  X-  -
  U	-   UU-
  -  nUX-
  -  U-   nX4n[	        XU 5      (       a1  [	        XU5      (       a   [        U[        XU5      [        X#U5      S9/$ / $ )a  Finds intersections between two line segments.

Args:
    s1, e1: Coordinates of the first line as 2D tuples.
    s2, e2: Coordinates of the second line as 2D tuples.

Returns:
    A list of ``Intersection`` objects, each object having ``pt``, ``t1``
    and ``t2`` attributes containing the intersection point, time on first
    segment and time on second segment respectively.

Examples::

    >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367))
    >>> len(a)
    1
    >>> intersection = a[0]
    >>> intersection.pt
    (374.44882952482897, 313.73458370177315)
    >>> (intersection.t1, intersection.t2)
    (0.45069111555824465, 0.5408153767394238)
r
   )rY   iscloser	   r  r  )s1e1s2e2s1xs1ye1xe1ys2xs2ye2xe2yrU   slope34r   r   slope12s                    r1   r&   r&     sE   . HCHCHCHCS4<<#9#9$,,sBXBX	S4<<#9#9$,,sBXBX	||C$,,s"8"8	||C$,,s"8"8	||C9+3w#%V-3bb8Q
 	

 ||C9+qw#%V-3bb8Q
 	
 ySY'GySY'G||GW%%		3	w}	,s	2w7HIA17c!A
B.
 
1""
=
=-3bb8Q
 	

 Ir2   c                     U S   nU S   n[         R                  " US   US   -
  US   US   -
  5      n[        R                  " U* 5      R	                  US   * US   * 5      $ )Nr   r   rX   )rY   atan2r   rotate	translate)segmentstartendangles       r1   _alignment_transformationr0    sj     AJE
"+CJJs1va(#a&58*;<E??E6",,eAhYq	BBr2   c                 <   [        U5      R                  U 5      n[        U 5      S:X  a"  [        U6 u  p4n[	        US   US   US   5      nO@[        U 5      S:X  a&  [        U6 u  p4pW[        US   US   US   US   5      nO[        S5      e[        S U 5       5      $ )Nr4   rX   r  r  c              3   L   #    U  H  nS Us=::  a  S::  d  M  O  M  Uv   M     g7f)rk   rX   Nr6   )r   r   s     r1   r   ._curve_line_intersections_t.<locals>.<genexpr>  s     <]cQm!m!m!]r   )	r0  transformPointsr   rs   r   r   r    r  r   )curvelinealigned_curvere   rf   r   intersectionsra   s           r1   _curve_line_intersections_tr9    s    -d3CCEJM
5zQ)=9a&qtQqT1Q48	Uq(-8
a"1Q41qtQqT:/00<]<<<r2   c           	         [        U 5      S:X  a  [        nO![        U 5      S:X  a  [        nO[        S5      e/ n[	        X5       H@  nU" / U QUP76 n[        / UQUP76 n[        / UQUP76 nUR                  [        XTUS95        MB     U$ )a  Finds intersections between a curve and a line.

Args:
    curve: List of coordinates of the curve segment as 2D tuples.
    line: List of coordinates of the line segment as 2D tuples.

Returns:
    A list of ``Intersection`` objects, each object having ``pt``, ``t1``
    and ``t2`` attributes containing the intersection point, time on first
    segment and time on second segment respectively.

Examples::
    >>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ]
    >>> line  = [ (25, 260), (230, 20) ]
    >>> intersections = curveLineIntersections(curve, line)
    >>> len(intersections)
    3
    >>> intersections[0].pt
    (84.9000930760723, 189.87306176459828)
r4   r  r  r
   )	r   r!   r"   r  r9  r  r$   rt   r	   )r5  r6  pointFinderr8  r~   r   line_ts          r1   r'   r'     s    * 5zQ'	Uq#/00M(5#%## ))b)(4((\R&AB 6 r2   c                 t    [        U 5      S:X  a  [        U 6 $ [        U 5      S:X  a  [        U 6 $ [        S5      e)Nr4   r  r  )r   r   r   r  )r   s    r1   _curve_boundsr>    s:    
1v{"A&&	Q1""
+
,,r2   c                     [        U 5      S:X  a  U u  p#[        X#U5      nX$4XC4/$ [        U 5      S:X  a  [        / U QUP76 $ [        U 5      S:X  a  [        / U QUP76 $ [	        S5      er  )r   r$   r   r   r  )r   r~   r
  r  midpoints        r1   _split_segment_at_trA    sw    
1v{a(}--
1v{ '!'Q''	Q1#a###
+
,,r2   c           
        ^ [        U 5      n[        U5      nU(       d  SnU(       d  Sn[        XV5      u  pxU(       d  / $ S n	[        U5      T:  a   [        U5      T:  a  U	" U5      U	" U5      4/$ [        U S5      u  pUS   U	" U5      4nU	" U5      US   4n[        US5      u  pUS   U	" U5      4nU	" U5      US   4n/ nUR	                  [        XTUUS95        UR	                  [        XTUUS95        UR	                  [        XTUUS95        UR	                  [        XTUUS95        U4S jn[        5       n/ nU H5  nU" U5      nUU;   a  M  UR                  U5        UR                  U5        M7     U$ )N)rk   rJ   c                     SU S   U S   -   -  $ )Nr5   r   rX   r6   )rs    r1   r@  ._curve_curve_intersections_t.<locals>.midpoint1  s    adQqTk""r2   r5   r   rX   )range1range2c                 H   > [        U S   T-  5      [        U S   T-  5      4$ )Nr   rX   )int)r   	precisions    r1   <lambda>._curve_curve_intersections_t.<locals>.<lambda>V  s&    SA!23SA9J5KLr2   )	r>  r   r   rA  extend_curve_curve_intersections_tsetaddrt   )curve1curve2rJ  rF  rG  bounds1bounds2
intersects_r@  c11c12	c11_range	c12_rangec21c22	c21_range	c22_rangefound
unique_keyseenunique_valuesr   keys     `                     r1   rN  rN  !  s    F#GF#G W.MJ	# 9$'):Y)F&!8F#3455"63/HCHV,-I&!6!9-I"63/HCHV,-I&!6!9-IE	LL$i	)	

 
LL$i	)	

 
LL$i	)	

 
LL$i	)	
 MJ5DMn$;R   r2   c                 Z    [        U 5      R                  U 5      n[        S U 5       5      $ )Nc              3   V   #    U  H  n[         R                  " US    S5      v   M!     g7f)rX   rk   N)rY   r  )r   ps     r1   r   _is_linelike.<locals>.<genexpr>f  s"     :	1t||AaD#&&	s   '))r0  r4  all)r,  	maybelines     r1   _is_linelikerj  d  s(    )'2BB7KI:	:::r2   c           
      `   [        U 5      (       a<  U S   U S   4n[        U5      (       a  US   US   4n[        / UQUQ76 $ [        X5      $ [        U5      (       a  US   US   4n[        X5      $ [        X5      nU Vs/ s H   n[	        [        XS   5      US   US   S9PM"     sn$ s  snf )a  Finds intersections between a curve and a curve.

Args:
    curve1: List of coordinates of the first curve segment as 2D tuples.
    curve2: List of coordinates of the second curve segment as 2D tuples.

Returns:
    A list of ``Intersection`` objects, each object having ``pt``, ``t1``
    and ``t2`` attributes containing the intersection point, time on first
    segment and time on second segment respectively.

Examples::
    >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]
    >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]
    >>> intersections = curveCurveIntersections(curve1, curve2)
    >>> len(intersections)
    3
    >>> intersections[0].pt
    (81.7831487395506, 109.88904552375288)
r   r   rX   r
   )rj  r&   r'   rN  r	   r%   )rQ  rR  line1line2intersection_tsr   s         r1   r(   r(   i  s    * Fq	6":%1Ivbz)E(8%8%88)&88	f		q	6":%%f4426BO "!B 	162a5RUK!  s   'B+c           	         Sn[        U5      [        U 5      :  a  XpSn[        U 5      S:  a'  [        U5      S:  a  [        X5      nOC[        X5      nO7[        U 5      S:X  a  [        U5      S:X  a  [        / U QUQ76 nO[	        S5      eU(       d  U$ U Vs/ s H,  n[        UR                  UR                  UR                  S9PM.     sn$ s  snf )a  Finds intersections between two segments.

Args:
    seg1: List of coordinates of the first segment as 2D tuples.
    seg2: List of coordinates of the second segment as 2D tuples.

Returns:
    A list of ``Intersection`` objects, each object having ``pt``, ``t1``
    and ``t2`` attributes containing the intersection point, time on first
    segment and time on second segment respectively.

Examples::
    >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]
    >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]
    >>> intersections = segmentSegmentIntersections(curve1, curve2)
    >>> len(intersections)
    3
    >>> intersections[0].pt
    (81.7831487395506, 109.88904552375288)
    >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ]
    >>> line  = [ (25, 260), (230, 20) ]
    >>> intersections = segmentSegmentIntersections(curve3, line)
    >>> len(intersections)
    3
    >>> intersections[0].pt
    (84.9000930760723, 189.87306176459828)

FTrW   z4Couldn't work out which intersection function to user
   )	r   r(   r'   r&   r  r	   r   r   r   )seg1seg2swappedr8  r   s        r1   r)   r)     s    < G
4y3t9d
4y1}t9q=3D?M24>M	TaCIN-;t;d;OPP=JK]LADDQTTadd3]KKKs   3Cc                 z     [        U 5      nSSR                  S U 5       5      -  $ ! [         a    SU -  s $ f = f)zk
>>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]])
'(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))'
z(%s)z, c              3   8   #    U  H  n[        U5      v   M     g 7frP   )_segmentrepr)r   rU   s     r1   r   _segmentrepr.<locals>.<genexpr>  s     !>2a,q//2s   z%g)iterjoin	TypeError)objits     r1   ru  ru    sG    
?#Y 		!>2!>>>>  czs   ( ::c                 >    U  H  n[        [        U5      5        M     g)zdHelper for the doctests, displaying each segment in a list of
segments on a single line as a tuple.
N)printru  )r   r,  s     r1   printSegmentsr~    s     l7#$ r2   __main__)g{Gzt?)gMbP?NN)X__doc__fontTools.misc.arrayToolsr   r   r   fontTools.misc.transformr   rY   collectionsr   r   AttributeErrorImportErrorfontTools.misccompiledCOMPILEDrD   r	   __all__r   r=   returnsdoublelocalsr+   rE   r   r   rl   cfuncinlinerS   r\   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rZ   r   r   r   r   r    rs   r   r   r   r   r   r$   r!   r"   r#   r%   r  r  r&   r0  r9  r'   r>  rA  rN  rj  r(   r)   ru  r~  __name__sysdoctestexittestmodfailedr6   r2   r1   <module>r     sX   E D -  "& ??  .*<=@& ~~~~~~~~	 FMM6==I	
 J 	
 	 mm	A	 A 
 &..V^^4& 5   & ;     ; PF ~~~~nnnn 
--]]mmmm}}}} &@W" 
 }}}}}}
 BD< 	 }}}}}}}}}}!" !"H#L6r*3Z"2J,0> nnnnnnnn	0	0 mm^^			 }}6==D	  D46 F nnnnnnnn}}}}
--MMMM~~~~~~~~##6 % $ "& BYB(2 nnnnnn  
(2  nnnnnnnn~~~~~~  
N4 mm &--fmmFMMJY K  Y -%/K\C
=#L-	- 9=@F;
$N-L`
?% zHHW__%%&	 S. 	$ &%%&s   a0 0bb