?z      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmn o p q r s t u v w x y z { | } ~        !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""###$$$$%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&''''''''((((((((((((((((((((( ( ) ) ) ))))))))))))))))))) )!)")#)$)%)&)')()))*)+),)-).)/)0)1)2)3)4)5)6)7)8)9):);)<)=)>)?)@)A)B)C)D)E)F)G)H)I)J)K)L)M)N)O)P)Q)R)S)T)U)V)W)X)Y)Z)[)\)])^)_)`)a)b)c)d)e)f)g)h)i)j)k)l)m)n)o)p)q)r)s)t)u)v)w)x)y)z){)|)})~)))))))))))))))))))))))))))))))))*********************************************************++++,,,,,,,,,,,,,,,,,,,,,,,,,----------------.... . . . . ................... .!.".#.$.%/&/'/(/)/*/+/,/-0.1/101112131415161718192:2;2<2=2>2?3@3A3B3C3D4E4F4G4H4I4J4K4L4M4N4O4P4Q4R4S4T4U4V4W4X4Y4Z4[4\5]5^5_5`5a5b5c5d5e5f5g5h5i5j5k5l5m5n5o5p5q5r5s5t5u5v5w5x6y6z6{6|6}7~777;None !"&'(*+,-./3457>CFIKLNUZ ;A State monad that can store earlier versions of the state. WCreate a snapshot of the current state and add it to the list of states that we store. run a persistentStateT, returns a triplet with the value, the last state and a list of all states (including the last one) in chronological order      None !"&'(*+,-./3457>CFIKLNUZrGet the index h such that everything strictly smaller than h has: p i = False, and all i >= h, we have p h = True)returns Nothing if no element satisfies pVrunning time: $O(log^2 n + T*log n)$, where $T$ is the time to execute the predicate.GPartition the seq s given a monotone predicate p into (xs,ys) such thathall elements in xs do *not* satisfy the predicate p all elements in ys do satisfy the predicate p+all elements in s occur in either xs or ys.Vrunning time: $O(log^2 n + T*log n)$, where $T$ is the time to execute the predicate.oGiven a monotonic predicate p, a lower bound l, and an upper bound u, with: p l = False p u = True l < u.rGet the index h such that everything strictly smaller than h has: p i = False, and all i >= h, we have p h = Truerunning time: $O(log(u - l))$8None !"&'(*+,-./3457>CFIKLNUZ%reexporting some standard combinatorsinfix variant of notfollowed byRunning parsers in reverse;Runs parser q ``in reverse'' on the end of the input stream1run the parsers in reverse order, first q, then p"the variants with missing bracketsNone !"&'(*+,-./3457>CFIKLNUZNone !"&'(*+,-./3457>CFIKLNUZ 'Cyclic representation of a permutation.Nidxes (fromEnum a) = (i,j) implies that a is the j^th item in the i^th orbit*Orbits (Cycles) are represented by vectors!The cycle containing a given item!Next item in a cyclic permutation cLookup the indices of an element, i.e. in which orbit the item is, and the index within the orbit.!CApply the permutation, i.e. consider the permutation as a function."7Find the cycle in the permutation starting at element s$jGiven the size n, and a list of Cycles, turns the cycles into a cyclic representation of the Permutation.&lens indexing into a vector !"#$%&'() !"#$%&)(' !"#$%& !"#$%&'()None !"&'(*+,-./3457>CFIKLNUZ**A dart represents a bi-directed edge. I.e. a dart has a direction, however the dart of the oposite direction is always present in the planar graph as well.1gAn Arc is a directed edge in a planar graph. The type s is used to tie this arc to a particular graph.4Reverse the direcion5A *connected* Planar graph with bidirected edges. I.e. the edges (darts) are directed, however, for every directed edge, the edge in the oposite direction is also in the graph.vThe types v, e, and f are the are the types of the data associated with the vertices, edges, and faces, respectively.HThe orbits in the embedding are assumed to be in counterclockwise order.6~A vertex in a planar graph. A vertex is tied to a particular planar graph by the phantom type s, and to a particular world w.:"The world in which the graph lives? Get the twin of this dart (edge)twin (dart 0 "+1")Dart (Arc 0) -1twin (dart 0 "-1")Dart (Arc 0) +1@test if a dart is PositiveAA faceGlens to access the Dart DataHedgeData is just an alias for G?Reorders the edge data to be in the right order to set edgeDataIConstruct a planar graphJConstruct a planar graph.KGet the number of verticesnumVertices myGraph4LGet the number of DartsnumDarts myGraph12MGet the number of EdgesnumEdges myGraph6NGet the number of facesnumFaces myGraph4OEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3]P7Enumerate all vertices, together with their vertex dataQEnumerate all dartsR&Get all darts together with their datamapM_ print $ darts myGraph (Dart (Arc 0) -1,"a-")(Dart (Arc 2) +1,"c+")(Dart (Arc 1) +1,"b+")(Dart (Arc 0) +1,"a+")(Dart (Arc 4) -1,"e-")(Dart (Arc 1) -1,"b-")(Dart (Arc 3) -1,"d-")(Dart (Arc 5) +1,"g+")(Dart (Arc 4) +1,"e+")(Dart (Arc 3) +1,"d+")(Dart (Arc 2) -1,"c-")(Dart (Arc 5) -1,"g-")S6Enumerate all edges. We report only the Positive dartsTMEnumerate all edges with their edge data. We report only the Positive darts.mapM_ print $ edges myGraph(Dart (Arc 2) +1,"c+")(Dart (Arc 1) +1,"b+")(Dart (Arc 0) +1,"a+")(Dart (Arc 5) +1,"g+")(Dart (Arc 4) +1,"e+")(Dart (Arc 3) +1,"d+")U=The tail of a dart, i.e. the vertex this dart is leaving fromV%The vertex this dart is heading in toW(endPoints d g = (tailOf d g, headOf d g)XCAll edges incident to vertex v, in counterclockwise order around v.YLAll incoming edges incident to vertex v, in counterclockwise order around v.ZLAll outgoing edges incident to vertex v, in counterclockwise order around v.[YGets the neighbours of a particular vertex, in counterclockwise order around the vertex.\\Get the vertex data associated with a node. Note that updating this data may be expensive!!]Edge data of a given dart^Data of a face of a given face_/Data corresponding to the endpoints of the dart`/Data corresponding to the endpoints of the dartaThe dual of this graph:{  let fromList = V.fromList/ answer = fromList [ fromList [dart 0 "-1"]S , fromList [dart 2 "+1",dart 4 "+1",dart 1 "-1",dart 0 "+1"]G , fromList [dart 1 "+1",dart 3 "-1",dart 2 "-1"]S , fromList [dart 4 "-1",dart 3 "+1",dart 5 "+1",dart 5 "-1"] ]. in (dual myGraph)^.embedding.orbits == answer:}Trueb'Enumerate all faces in the planar graphcAll faces with their face data.d The face to the left of the dartleftFace (dart 1 "+1") myGraphFaceId 1leftFace (dart 1 "-1") myGraphFaceId 2leftFace (dart 2 "+1") myGraphFaceId 2leftFace (dart 0 "+1") myGraphFaceId 0e!The face to the right of the dartrightFace (dart 1 "+1") myGraphFaceId 2rightFace (dart 1 "-1") myGraphFaceId 1rightFace (dart 2 "+1") myGraphFaceId 1rightFace (dart 0 "+1") myGraphFaceId 1ftThe darts bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.N*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef=*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef=123./04*+,-=>?@:;<96785DFGEHIJKLMNQRSTOPbcUVWXYZ[\]^_`aABCdef<*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefNone !"&'(*+,-./3457>CFIKLNUZgcAdjacency list representation of a graph: for each vertex we simply list all connected neighbours.hDFS on a planar graph.Running time: $O(n)$wNote that since our planar graphs are always connected there is no need need for dfs to take a list of start vertices.i+Transform into adjacencylist representationjFDFS, from a given vertex, on a graph in AdjacencyLists representation.Running time: $O(n)$ghijghijhgijghijNone !"&'(*+,-./3457>CFIKLNUZ Union find DSkMinimum spanning tree of the edges. The result is a rooted tree, in which the nodes are the vertices in the planar graph together with the edge weight of the edge to their parent. The root's weight is zero. The algorithm used is Kruskal's.running time: $O(n log n)$l6Computes the set of edges in the Minimum spanning treerunning time: $O(n log n)$m_Given an underlying planar graph, and a set of edges that form a tree, create the actual tree..pre: the planar graph has at least one vertex.~Union the components containing x and y. Returns weather or not the two components were already in the same component or not.Get the representative of the component containing x find :: (Enum a, Eq a) => UF s a -> a -> ST s a find uf = fmap fst . find' ufCget the representative (and its rank) of the component containing x klmklmklmklm None !"&'(*+,-./3457>CFIKLNUZ Strict pairn2Fisher Yates shuffle, which shuffles in O(n) time.`Generate a list of indices in decreasing order, coupled with a random value in the range [0,i].nnnn None !"&'(*+,-./34579>CFIKLNUZysmart constructoropqrstuvwxyz{|}~ opqrstuvwxyzvwxtuy~}zrs|opq{ opqrstuvwxyz{|}~ None !"&'(*+,-./3457>CFIKLNUZ7Given a list xs, generate all unique (unordered) pairs.All unieuqe unordered triplets. None !"&'(*+,-./3457>CFIKLNUZNonempty circular sequence.Gets the focus of the CSeq running time: O(1)GAccess the i^th item (w.r.t the focus) in the CSeq (indices modulo n). running time: $O(log (i mod n))$index (fromList [0..5]) 11index (fromList [0..5]) 22index (fromList [0..5]) 55index (fromList [0..5]) 104index (fromList [0..5]) 60index (fromList [0..5]) (-1)5index (fromList [0..5]) (-6)04Adjusts the i^th element w.r.t the focus in the CSeq running time: $O(log (i mod n))$'adjust (const 1000) 2 (fromList [0..5])CSeq [0,1,1000,3,4,5]:Access te ith item in the CSeq (w.r.t the focus) as a lens5smart constructor that automatically balances the seq4Builds a balanced seq with the element as the focus.rotates one to the rightrunning time: O(1) (amortized)rotateR $ fromList [3,4,5,1,2]CSeq [4,5,1,2,3]rotates the focus to the leftrunning time: O(1) (amortized)rotateL $ fromList [3,4,5,1,2]CSeq [2,3,4,5,1]8mapM_ print . take 5 $ iterate rotateL $ fromList [1..5]CSeq [1,2,3,4,5]CSeq [5,1,2,3,4]CSeq [4,5,1,2,3]CSeq [3,4,5,1,2]CSeq [2,3,4,5,1]1Convert to a single Seq, starting with the focus.9All elements, starting with the focus, going to the right8All elements, starting with the focus, going to the left#leftElements $ fromList [3,4,5,1,2]fromList [3,2,1,5,4] builds a CSeq Rotates i elements to the right.pre: 0 <= i < n"running time: $O(log i)$ amortizedrotateNR 0 $ fromList [1..5]CSeq [1,2,3,4,5]rotateNR 1 $ fromList [1..5]CSeq [2,3,4,5,1]rotateNR 4 $ fromList [1..5]CSeq [5,1,2,3,4]Rotates i elements to the left.pre: 0 <= i < n"running time: $O(log i)$ amoritzedrotateNL 0 $ fromList [1..5]CSeq [1,2,3,4,5]rotateNL 1 $ fromList [1..5]CSeq [5,1,2,3,4]rotateNL 2 $ fromList [1..5]CSeq [4,5,1,2,3]rotateNL 3 $ fromList [1..5]CSeq [3,4,5,1,2]rotateNL 4 $ fromList [1..5]CSeq [2,3,4,5,1]#Reversres the direction of the CSeqrunning time: $O(n)$"reverseDirection $ fromList [1..5]CSeq [1,5,4,3,2]Finds an element in the CSeq%findRotateTo (== 3) $ fromList [1..5]Just (CSeq [3,4,5,1,2])%findRotateTo (== 7) $ fromList [1..5]Nothing+All rotations, the input CSeq is the focus.,mapM_ print . allRotations $ fromList [1..5]CSeq [1,2,3,4,5]CSeq [2,3,4,5,1]CSeq [3,4,5,1,2]CSeq [4,5,1,2,3]CSeq [5,1,2,3,4] None !"&'(*+,-./3457>CFIKLNUZ^A view of the right end of the sequence, with the guarantee that it has at least one element. Right viewsYA view of the right end of the seq, with the guarantee that it has at least two elementsAt least one element Left views]Basically Data.Sequence but with the guarantee that the list contains at least two elements.[get the element with index i, counting from the left and starting at 0. O(log(min(i,n-i)))-Concatenate two sequences. O(log(min(n1,n2))),pre: the list contains at least two elementsfmap but with an indexLConvert a Seq into a Seq2. It is not checked that the length is at least twoO(1) get a left viewO(1) get a right viewTWe throw away information here; namely that the combined list contains two elements.At least two elements20-None !"&'(*+,-./3457>CFIKLNUZ?`UnBounded a` represents the type a, together with an element / larger than any other element, and an element ", smaller than any other element.2`Bottom a` represents the type a, together with a p element, i.e. an element that is smaller than any other element. We can think of `Bottom a` being defined as:data Bottom a = ValB/`Top a` represents the type a, together with a l element, i.e. an element that is greater than any other element. We can think of `Top a` being defined as:data Top a = ValT a | TopNone !"&'(*+,-./3457>CFIKLNUZGiven a circular list, whose elements are in increasing order, insert the new element into the Circular list in its sorted order.insertOrd 1 C.empty fromList [1]insertOrd 1 $ C.fromList [2]fromList [2,1]insertOrd 2 $ C.fromList [1,3]fromList [1,2,3]insertOrd 31 ordList fromList [5,6,10,20,30,31,1,2,3]insertOrd 1 ordListfromList [5,6,10,20,30,1,1,2,3]insertOrd 4 ordListfromList [5,6,10,20,30,1,2,3,4]insertOrd 11 ordList fromList [5,6,10,11,20,30,1,2,3]_Insert an element into an increasingly ordered circular list, with specified compare operator.List version of insertOrdBy; i.e. the list contains the elements in cirulcar order. Again produces a list that has the items in circular order.}Test if the circular list is a cyclic shift of the second list. Running time: O(n), where n is the size of the smallest listNone !"&'(*+,-./3457>CFIKLNUZNone !"&'(*+,-./3457>CFIKLNUZsDatatype representing d dimensional vectors. Our implementation wraps the implementation provided by fixed-vector..A proxy which can be used for the coordinates.-Pattern synonym for two and three dim vectorsLens into the i th element Similar to x above. Except that we don't have a static guarantee that the index is in bounds. Hence, we can only return a Traversal!Get the head and tail of a vector.Cross product of two three-dimensional vectorsConversion to a Linear.V3Conversion from a Linear.V3(Add an element at the back of the vector)Get a vector of the first d - 1 elements.&Get a prefix of i elements of a vectorMap with indices Construct a 2 dimensional vector  Construct a 3 dimensional vector #Destruct a 2 dim vector into a pair%        $     !     None !"&'(*+,-./3457>CFIKLNUZ$Test if v is a scalar multiple of u.$v2 1 1 `isScalarMultipleOf` v2 10 10True#v2 1 1 `isScalarMultipleOf` v2 10 1False(v2 1 1 `isScalarMultipleOf` v2 11.1 11.1True(v2 1 1 `isScalarMultipleOf` v2 11.1 11.2False(v2 2 1 `isScalarMultipleOf` v2 11.1 11.2False"v2 2 1 `isScalarMultipleOf` v2 4 2True"v2 2 1 `isScalarMultipleOf` v2 4 0False8Get the scalar labmda s.t. v = lambda * u (if it exists) ;    None !"&'(*+,-./13457:>CFIJKLNUZ TWhen using IntersectionOf we may need some constraints that are always true anyway.g  h  =* The intersection of g and h is non-empty.The default implementation computes the intersection of g and h, and uses nonEmptyIntersection to determine if the intersection is non-empty.Helper to implement .QThe type family specifying the list of possible result types of an intersection.6The result of interesecting two geometries is a CoRec, =A simple data type expressing that there are no intersections"=A type family for types that have an associated numeric type.#A type family for types that are associated with a dimension. The dimension is the dimension of the geometry they are embedded in.$Helper to produce a corec%0Returns True iff the resultt is a NoIntersection !"#$% !"#$%#" !$%  !"#$%None !"&'(*+,-./3457>CFIKLNUZ&1Quadrants of two dimensional points. in CCW order/PTypes that we can transform by mapping a function on each point in the structure2A d-dimensional point.5aWe provide pattern synonyms Point2 and Point3 for 2 and 3 dimensional points. i.e. we can write::{ let$ f :: Point 2 r -> r f (Point2 x y) = x in f (point2 1 2):}1 if we want.6Similarly, we can write::{ let& g :: Point 3 r -> r g (Point3 x y z) = z in g myPoint:}37-Point representing the origin in d dimensionsorigin :: Point 4 IntPoint4 [0,0,0,0]86Lens to access the vector corresponding to this point.(point3 1 2 3) ^. vectorVector3 [1,2,3]origin & vector .~ v3 1 2 3Point3 [1,2,3]9{Get the coordinate in a given dimension. This operation is unsafe in the sense that no bounds are checked. Consider using : instead.point3 1 2 3 ^. unsafeCoord 22:'Get the coordinate in a given dimension point3 1 2 3 ^. coord (C :: C 2)2%point3 1 2 3 & coord (C :: C 1) .~ 10Point3 [10,2,3]'point3 1 2 3 & coord (C :: C 3) %~ (+1)Point3 [1,2,4];Construct a 2 dimensional point point2 1 2 Point2 [1,2]<Destruct a 2 dimensional point_point2 $ point2 1 2(1,2)=Construct a 3 dimensional point point3 1 2 3Point3 [1,2,3]>Destruct a 3 dimensional point_point3 $ point3 1 2 3(1,2,3)?,Shorthand to access the first coordinate C 1point3 1 2 3 ^. xCoord1point2 1 2 & xCoord .~ 10 Point2 [10,2]@-Shorthand to access the second coordinate C 2point2 1 2 ^. yCoord2point3 1 2 3 & yCoord %~ (+1)Point3 [1,3,3]A,Shorthand to access the third coordinate C 3point3 1 2 3 ^. zCoord3point3 1 2 3 & zCoord %~ (+1)Point3 [1,2,4]BTGiven three points p q and r determine the orientation when going from p to r via q.CSort the points arround the given point p in counter clockwise order with respect to the rightward horizontal ray starting from p. If two points q and r are colinear with p, the closest one to p is reported first. running time: O(n log n)DQuadrants around point c; quadrants are closed on their "previous" boundary (i..e the boundary with the previous quadrant in the CCW order), open on next boundary. The origin itself is assigned the topRight quadrantE$Quadrants with respect to the originFgGiven a center point c, and a set of points, partition the points into quadrants around c (based on their x and y coordinates). The quadrants are reported in the order topLeft, topRight, bottomLeft, bottomRight. The points are in the same order as they were in the original input lists. Points with the same x-or y coordinate as p, are "rounded" to above.GCounter clockwise ordering of the points around c. Points are ordered with respect to the positive x-axis. Points nearer to the center come before points further away.HClockwise ordering of the points around c. Points are ordered with respect to the positive x-axis. Points nearer to the center come before points further away.IGiven a center c, a new point p, and a list of points ps, sorted in counter clockwise order around c. Insert p into the cyclic order. The focus of the returned cyclic list is the new point p.running time: O(n)J-Squared Euclidean distance between two pointsK%Euclidean distance between two points+&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN&&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK)234NM789:56;<=>1?@A/0L+,-.BC&'()*DEFGHIJK!&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNNone !"&'(*+,-./3457>CFIKLNUZQIA class representing types that can be transformed using a transformationS>A type representing a Transformation for d dimensional objectsV?a matrix of n rows, each of m columns, storing values of type r['Compose transformations (right to left)dcCreates a row with zeroes everywhere, except at position i, where the value is the supplied value.eRow in a translation matrixOPQRSTUVWXYZ[\]^_`abcdefOPQRSTUVWXYZ[\]^_`abcdeVWXYSTUZ[QR\P]f^_`OabcdeOPQRSTUVWXYZ[\]^_`abcdefNone  !"&'(*+,-./3457:>CFIKLNUZzlAttr implements the mapping from labels to types as specified by the (symbol representing) the type family fGive pref. to the *RIGHT* Possible values for an ipe arrow>IpeOpacity, IpeTyling, and IpeGradient are all symbolic valuesAllowed Fill typesPath AttributesPossible attributes for a path data PathAttributeUniverse = Stroke | Fill | Dash | Pen | LineCap | LineJoin | FillRule | Arrow | RArrow | Opacity | Tiling | Gradient deriving (Show,Eq)Possible values for DashTODOSymbol AttributesThe optional Attributes for a symbol data SymbolAttributeUniverse = SymbolStroke | SymbolFill | SymbolPen | Size deriving (Show,Eq)BMany types either consist of a symbolc value, or a value of type v"Possible values for TransformationCommon AttributesPossible values for Pin.gets and removes the attribute from Attributesunsets/Removes an attributeIFunction that states that all elements in xs satisfy a given constraint c3Wrap up a value with a capability given by its typedFor the types representing attribute values we can get the name/key to use when serializing to ipe.Writing Attribute namesghijklmnopqrstuvwxyz{|}~xghijklmnopqrstuvwxyz{|}~ghijklmnopqrstuvwxy~}z{|Sghijklmnopqrstuvwxyz{|}~None !"&'(*+,-./3457>CFIKLNUZ_Labels the edges of a plane graph with their distances, as specified by the distance function.?*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefNone !"&'(*+,-./3457>CFIKLNUZ AA range from l to u, ignoring/forgetting the type of the enpoints  Test if a value lies in a range.1 `inRange` (OpenRange 0 2)True1 `inRange` (OpenRange 0 1)False1 `inRange` (ClosedRange 0 1)True1 `inRange` (ClosedRange 1 1)True10 `inRange` (OpenRange 1 10)False10 `inRange` (ClosedRange 0 1)False Get the width of the intervalwidth $ ClosedRange 1 109width $ OpenRange 5 105 tClip the interval from below. I.e. intersect with the interval {l,infty), where { is either open, (, orr closed, [. hClip the interval from above. I.e. intersect with (-infty, u}, where } is either open, ), or closed, ],Check if the range is valid and nonEmpty, i.e. if the lower endpoint is indeed smaller than the right endpoint. Note that we treat empty open-ranges as invalid as well.!Compare end points, Closed < Open%Compare the end points, Open < Closed!Shift a range x units to the left-prettyShow $ shiftLeft 10 (ClosedRange 10 20) "[0, 10]"+prettyShow $ shiftLeft 10 (OpenRange 15 25) "(5, 15)"Shifts the range to the right.prettyShow $ shiftRight 10 (ClosedRange 10 20) "[20, 30]",prettyShow $ shiftRight 10 (OpenRange 15 25) "(25, 35)"                    None !"&'(*+,-./3457>CFIKLNUZAn Interval is essentially a 9: but with possible payload Test if a value lies in an interval. Note that the difference between inInterval and inRange is that the extra value is *not* used in the comparison with inInterval, whereas it is in inRange. !"#$%&'() !)('&% $#"! !"#$%&'()None !"&'(*+,-./3457>CFIKLNUZ*`Result of a query that asks if something is Inside a g, *on* the boundary of the g, or outside..#The boundary of a geometric object.*+,-./*+,-././*+,-*+,-./None !"&'(*+,-./3457>CFIKLNUZ0JA line is given by an anchor point and a vector indicating the direction.4Result of a side test8`Types for which we can compute a supporting line, i.e. a line that contains the thing of type t.<*A line may be constructed from two points.?]Given a line l with anchor point p, get the line perpendicular to l that also goes through p.@mTest if two lines are identical, meaning; if they have exactly the same anchor point and directional vector.A#Test if the two lines are parallel.TlineThrough origin (point2 1 0) `isParallelTo` lineThrough (point2 1 1) (point2 2 1)TrueTlineThrough origin (point2 1 0) `isParallelTo` lineThrough (point2 1 1) (point2 2 2)FalseBTest if point p lies on line l/origin `onLine` lineThrough origin (point2 1 0)True5point2 10 10 `onLine` lineThrough origin (point2 2 2)True4point2 10 5 `onLine` lineThrough origin (point2 2 2)FalseC'Squared distance from point p to line lDbThe squared distance between the point p and the line l, and the point m realizing this distance.E-Create a line from the linear function ax + bFgget values a,b s.t. the input line is described by y = ax + b. returns Nothing if the line is verticalGGiven a point q and a line l, compute to which side of l q lies. For vertical lines the left side of the line is interpeted as below.8point2 10 10 `onSide` (lineThrough origin $ point2 10 5)Above;point2 10 10 `onSide` (lineThrough origin $ point2 (-10) 5)Above%point2 5 5 `onSide` (verticalLine 10)Below;point2 5 5 `onSide` (lineThrough origin $ point2 (-3) (-3))OnH6Test if the query point q lies (strictly) above line lI#Get the bisector between two pointsKThe intersection of two lines is either: NoIntersection, a point or a line. 0123456789:;<=>?@ABCDEFGHIJKL0123456789:;<=>?@ABCDEFGHI0123;:L<=>?@ABKCD89JEF4567GHI0123456789:;<=>?@ABCDEFGHIJKLNone !"&'(*+,-./3457>CFIKLNUZWbGiven the point with the lowest coordinates and the point with highest coordinates, create a box.ZCheck if a point lies a boxQorigin `inBox` (boundingBoxList' [point3 1 2 3, point3 10 20 30] :: Box 3 () Int)FalseZorigin `inBox` (boundingBoxList' [point3 (-1) (-2) (-3), point3 10 20 30] :: Box 3 () Int)True[Get a vector with the extent of the box in each dimension. Note that the resulting vector is 0 indexed whereas one would normally count dimensions starting at zero.Iextent (boundingBoxList' [point3 1 2 3, point3 10 20 30] :: Box 3 () Int)Vector3 [Range {_lower = Closed 1, _upper = Closed 10},Range {_lower = Closed 2, _upper = Closed 20},Range {_lower = Closed 3, _upper = Closed 30}]\Get the size of the box (in all dimensions). Note that the resulting vector is 0 indexed whereas one would normally count dimensions starting at zero.>size (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)Vector3 [1,2,3]]XGiven a dimension, get the width of the box in that dimension. Dimensions are 1 indexed.LwidthIn (C :: C 1) (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)1LwidthIn (C :: C 3) (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)3^Same as ]6 but with a runtime int instead of a static dimension.DwidthIn' 1 (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)Just 1DwidthIn' 3 (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)Just 3EwidthIn' 10 (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)NothingaGet the corners of a rectangle, the order is: (TopLeft, TopRight, BottomRight, BottomLeft). The extra values in the Top points are taken from the Top point, the extra values in the Bottom points are taken from the Bottom pointcOUnsafe version of boundingBoxList, that does not check if the list is non-emptyMNOPQRSTUVWXYZ[\]^_`abcdefghMNOPQRSTUVWXYZ[\]^_`abcMNOPVUWhgfeXYZ[\]^T_`aRSQbcdMNOPQRSTUVWXYZ[\]^_`abcdefghNone !"&'(*+,-./3457>CFIKLNUZiwPart of a line. The interval is ranged based on the unit-vector of the line l, and s.t.t zero is the anchorPoint of l.oGet the point at the given position along line, where 0 corresponds to the anchorPoint of the line, and 1 to the point anchorPoint .+^ directionVectorp3Annotate the subRange with the actual ending pointsqNgiven point p on line (Line q v), Get the scalar lambda s.t. p = q + lambda vijklmnopqrs ijklmnopqr ijklnmopqsr ijklmnopqrsNone !"&'(*+,-./3457>CFIKLNUZ tLine segments. LineSegments have a start and end point, both of which may contain additional data of type p. We can think of a Line-Segment being defined asdata LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p))u6Pattern that essentially models the line segment as a:data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p))vHGets the start and end point, but forgetting if they are open or closed.y,Directly convert a line into a line segment.z'Test if a point lies on a line segment.N(point2 1 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))TrueN(point2 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))FalseN(point2 5 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))FalseQ(point2 (-1) 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))FalseN(point2 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 3 3 :+ ()))TrueVNote that the segments are assumed to be closed. So the end points lie on the segment.N(point2 2 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))TrueHorigin `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))True,This function works for arbitrary dimensons.R(point3 1 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point3 3 3 3 :+ ()))TrueR(point3 1 2 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point3 3 3 3 :+ ()))False{NThe left and right end point (or left below right if they have equal x-coords)|Length of the line segment}NSquared distance from the point to the Segment s. The same remark as for the ~ applies here.~ESquared distance from the point to the Segment s, and the point on s realizing it. Note that if the segment is *open*, the closest point returned may be one of the (open) end points, even though technically the end point does not lie on the segment. (The true closest point then lies arbitrarily close to the end point).,flips the start and end point of the segmenttuvwxyz{|}~      tuvwxyz{|}~ tuvwxyz{|}~tuvwxyz{|}~     None !"&'(*+,-./3457>CFIKLNUZOriented from *left to right*-The right side, oriented from *bottom* to topThe sides of the rectangle, in order (Top, Right, Bottom, Left). The sides themselves are also oriented in clockwise order. If, you want them in the same order as the functions , , , and , use  instead.YThe sides of the rectangle. The order of the segments is (Top, Right, Bottom, Left). Note that the segments themselves, are oriented as described by the functions topSide, bottomSide, leftSide, rightSide (basically: from left to right, and from bottom to top). If you want the segments oriented along the boundary of the rectangle, use the  function instead.MNOPQRSTUVWXYZ[\]^_`abc;None !"&'(*+,-./3457>CFIKLNUZ*Lines are transformable, via line segments0123456789:;<=>?@ABCDEFGHINone !"&'(*+,-./3457>CFIKLNUZ1Maps a line point (px,py) to a line (y=px*x - py)ZReturns Nothing if the input line is vertical Maps a line l: y = ax + b to a point (a,-b)#Pre: the input line is not vertical None !"&'(*+,-./3457>CFIKLNUZA Poly line in R^d0pre: The input list contains at least two points`pre: The input list contains at least two points. All extra vields are initialized with mempty.'We consider the line-segment as closed.@Convert to a closed line segment by taking the first two points.\Stricter version of asLineSegment that fails if the Polyline contains more than two points. !None !"&'(*+,-./3457>CFIKLNUZOWe distinguish between simple polygons (without holes) and Polygons with holes.,Access the i^th vertex on the outer boundaryGet all holes in a polygonXThe vertices in the polygon. No guarantees are given on the order in which they appear!KThe edges along the outer boundary of the polygon. The edges are half open.Gets the i^th edge on the outer boundary of the polygon, that is the edge with vertices i and i+1 with respect to the current focus. All indices modulo n.UGiven the vertices of the polygon. Produce a list of edges. The edges are half-open.ATest if q lies on the boundary of the polygon. Running time: O(n)"point2 1 1 `onBoundary` simplePolyFalse"point2 0 0 `onBoundary` simplePolyTrue#point2 10 0 `onBoundary` simplePolyTrue#point2 5 13 `onBoundary` simplePolyFalse#point2 5 10 `onBoundary` simplePolyFalse#point2 10 5 `onBoundary` simplePolyTrue#point2 20 5 `onBoundary` simplePolyFalseTODO: testcases multipolygonhCheck if a point lies inside a polygon, on the boundary, or outside of the polygon. Running time: O(n).!point2 1 1 `inPolygon` simplePolyInside!point2 0 0 `inPolygon` simplePoly OnBoundary"point2 10 0 `inPolygon` simplePoly OnBoundary"point2 5 13 `inPolygon` simplePolyInside"point2 5 10 `inPolygon` simplePolyInside"point2 10 5 `inPolygon` simplePoly OnBoundary"point2 20 5 `inPolygon` simplePolyOutsideUTODO: Add some testcases with multiPolygons TODO: Add some more onBoundary testcases1Test if a point lies strictly inside the polgyon.Compute the area of a polygonCompute the signed area of a simple polygon. The the vertices are in clockwise order, the signed area will be negative, if the verices are given in counter clockwise order, the area will be positive.)Compute the centroid of a simple polygon.VTest if the outer boundary of the polygon is in clockwise or counter clockwise order.running time: $O(1)$,Orient the outer boundary to clockwise orderDConvert a Polygon to a simple polygon by forgetting about any holes.(Comparison that compares which point is larger) in the direction given by the vector u.CFinds the extreme points, minimum and maximum, in a given directionrunning time: $O(n)$)Polygons are per definition 2 dimensional$""None !"&'(*+,-./3457>CFIKLNUZTwo dimensional convex hulls#None !"&'(*+,-./3457>CFIKLNUZaO(n log n) time ConvexHull using Graham-Scan. The resulting polygon is given in clockwise order.gHelper function so that that can compute both the upper or the lower hull, depending on the function f0Precondition: The list of input points is sorted$None !"&'(*+,-./3457>CFIKLNUZLine simplification with the well-known Douglas Peucker alogrithm. Given a distance value eps adn a polyline pl, constructs a simplification of pl (i.e. with vertices from pl) s.t. all other vertices are within dist eps to the original polyline.5Running time: O(n^2) worst case, O(n log n) expected.;Concatenate the two polylines, dropping their shared vertexJSplit the polyline at the given vertex. Both polylines contain this vertexGiven a sequence of points, find the index of the point that has the Furthest distance to the LineSegment. The result is the index of the point and this distance.%None !"&'(*+,-./3457>CFIKLNUZd-dimensional Half-Lines#Test if a point lies on a half-lineTransform a LineSegment into a half-line, by forgetting the second endpoint. Note that this also forgets about if the starting point was open or closed. !"   !"&None !"&'(*+,-./3457>CFIKLNUZ A d-dimensional ball.%Spheres, i.e. the boundary of a ball.?Given two points on the diameter of the ball, construct a ball.FConstruct a ball given the center point and a point p on the boundary.1A d dimensional unit ball centered at the origin.+Test if a point lies strictly inside a ball$(point2 0.5 0) `insideBall` unitBallTrue"(point2 1 0) `insideBall` unitBallFalse"(point2 2 0) `insideBall` unitBallFalse&Test if a point lies in or on the ball/Test if a point lies on the boundary of a ball.(point2 1 0) `onBall` unitBallTrue (point3 1 1 0) `onBall` unitBallFalsetGiven three points, get the disk through the three points. If the three input points are colinear we return Nothing1disk (point2 0 10) (point2 10 0) (point2 (-10) 0)FJust (Ball {_center = Point2 [0.0,0.0] :+ (), _squaredRadius = 100.0})#dA line segment may not intersect a circle, touch it, or intersect it properly in one or two points.$2No intersection, one touching point, or two points#$%&#$%&'None !"&'(*+,-./3457>CFIKLNUZCompute the area of a triangle2*the area of a triangle.hget the inscribed disk. Returns Nothing if the triangle is degenerate, i.e. if the points are colinear. '( '((None !"&'(*+,-./3457>CFIKLNUZMThe two bounding lines of the slab, first the lower one, then the higher one:0Smart consturctor for creating a horizontal slab.Smart consturctor for creating a vertical slab)*+,  )*+, )None  !"&'(*+,-./3457>CFIKLNUZ  Image ObjectsIpe Symbols, i.e. PointsA symbol (point) in ipe Text ObjectsGExample of an IpeSymbol. I.e. A symbol that expresses that the size is larger sizeSymbol :: Attributes (AttrMapSym1 r) (SymbolAttributes r) sizeSymbol = attr SSize (IpeSize $ Named "large")PathsIPaths consist of Path Segments. PathSegments come in the following forms:+/A path is a non-empty sequence of PathSegments.7#type that represents a path in ipe.CzThe mapping between the labels of the the attributes and the types of the attributes with these labels. For example, the V= label/attribute should have a value of type 'Matrix 3 3 r'.TBAn IpeObject' is essentially the oject ogether with its attributesV,Attributes' :: * -> [AttributeUniverse] -> *XGroups and ObjectsGroup Attributes,A group is essentially a list of IpeObjects.i;The definition of a view make active layer into an index ?x#for now we pretty much ignore these~ The maybe string is the encodingWAn IpePage is essentially a Group, together with a list of layers and a list of views.A complete ipe file$Creates a simple page with no views.JConvenience function to construct an ipe file consisting of a single page.7Create a single page ipe file from a list of IpeObjects8Takes and applies the ipe Matrix attribute of this item.2Applies the matrix to an ipe object if it has one.    -./012 !"#$%&'()*34+,-./012345656789:;<=>?@AB78CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`9:a;<bcdefghijklmnopqrstuvwxyz{|}~     !"#$%&'()+,-./012345789:;<=>?@ACDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`cdefghijklmnopxyz{|}~    )(* !"#$%&'543210/.6+,-AB789:;<=>?@LKJIHGFEDC_]^[\bbbbXYZaWVUT`MNOPQRShgfedcomnwvutsrqpijkl}|xyz{~l    -./012 !"#$%&'()*34+,-./0123456567 89:;<=>?@AB78CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`9:a;<bcdefghijklmnopqrstuvwxyz{|}~*None !"&'(*+,-./3457>CFIKLNUZ Types that correspond to an XML Element. All instances should produce an Element. If the type should produce a Node with the Text constructor, use the  typeclass instead.'For types that can produce a text valueGiven a prism to convert something of type g into an ipe file, a file path, and a g. Convert the geometry and write it to file.Write an IpeFiele to file.2Creates a single page ipe file with the given pageConvert the input to ipeXml, and prints it to standard out in such a way that the copied text can be pasted into ipe as a geometry object.$Convert input into an ipe selection.Convert to Ipe xml2Convert to ipe XML and write the output to a file.(Functon to write all attributes in a RecWriting the attribute valuesAdd attributes to a nodeSame as  but then for a Maybe nodeCThis instance converts the ratio to a Pico, and then displays that.997+None !"&'(*+,-./3457>CFIKLNUZ|Try to convert a path into a line segment, fails if the path is not a line segment or a polyline with more than two points.5Convert to a polyline. Ignores all non-polyline parts?Convert to a simple polygon: simply takes the first closed pathuse the first prism to select the ipe object to depicle with, and the second how to select the geometry object from there on. Then we can select the geometry object, directly with its attributes here.,None !"&'(*+,-./3457>CFIKLNUZORepresent stuff that can be used as a coordinate in ipe. (similar to show/read)Running the parsersThe parsers themselves/Generate a matrix from a list of 6 coordinates.-None !"&'(*+,-./3457>CFIKLNUZOBasically IpeReadText for attributes. This class is not really meant to be implemented directly. Just define an IpeReadText instance for the type (Apply f at), then the generic instance below takes care of looking up the name of the attribute, and calling the right ipeReadText value. This class is just so that reifyConstraint in 7 can select the right typeclass when building the rec.Reading an ipe lement from Xml'Reading an ipe elemtn from a Text value,Given a file path, tries to read an ipe file]Given a file path, tries to read an ipe file. This function applies all matrices to objects.wSince most Ipe file contain only one page, we provide a shortcut for that as well. This function applies all matrices.qGiven a Bytestring, try to parse the bytestring into anything that is IpeReadable, i.e. any of the Ipe elements.3Reads the data from a Bytestring into a proper Node=&Combination of zipRecWith and traverseReading the Attributes into a Rec (Attr f), all based on the types of f (the type family mapping labels to types), and a list of labels (ats).Reader for records. Given a proxy of some ipe type i, and a proxy of an coordinate type r, read the IpeAttributes for i from the xml node.If we can ipeRead an ipe element, and we can ipeReadAttrs its attributes we can properly read an ipe object using ipeReadObject>{Given a list of Nodes, try to parse all of them as a big text. If we encounter anything else then text, the parsing fails.?:try reading everything as an a. Throw away whatever fails.@Ipe read instances?=AB>CD?EFGHIJKLMNOPQRSTUVWXY@Z[\]^_`abcdefghijk<=AB>CD?EFGHIJKLMNOPQRSTUVWXY@Z[\]^_`abcdefghijk.None !"&'(*+,-./3457>CFIKLNUZ UClass that specifies a default conversion from a geometry type g into an ipe object.JAn IpeOut is essentially a funciton to convert a geometry object of type g into an ipe object of type i. Given an geometry object, and a record with its attributes, construct an ipe Object representing it using the default conversion. kasIpeObject with its arguments flipped. Convenient if you don't want to map asIpeObject over a list or so.,Create an ipe group without group attributesCreates a group out of ipeeHelper to construct an IpeOut g IpeObject , if we already know how to construct a specific Ipe type./Construct an ipe object from the core of an ExtDefault size of the cliping rectangle used to clip lines. This is Rectangle is large enough to cover the normal page size in ipe.UHelper to construct a IpeOut g Path, for when we already have an IpeOut g PathSegment       !"#$           $#"!       !"#$<None !"&'(*+,-./3457>CFIKLNUZAghijklmnopqrstuvwxyz{|}~     !"#$%&'()+,-./012345789:;<=>?@ACDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`cdefghijklmnopxyz{|}~     =Basic Geometry types(c) Frank StaalsSee LICENCE fileNone !"&'(*+,-./3457>CFIKLNUZlmnopq    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKOPQRSTUVWXYZ[\]^_`abcde0123456789:;<=>?@ABCDEFGHItuvwxyz{|}~/Convex Polygons(c) Frank StaalsSee LICENCE fileNone !"&'(*+,-./3457>CFIKLNUZ&CFinds the extreme points, minimum and maximum, in a given direction*pre: The input polygon is strictly convex.running time: $O(log n)$'BFinds the extreme maximum point in the given direction. Based on /http://geomalgorithms.com/a14-_extreme_pts.html*pre: The input polygon is strictly convex.running time: $O(log^2 n)$(Rotating Right  - rotate clockwise-Merging two convex hulls, based on the paper:Two Algorithms for Constructing a Delaunay Triangulation Lee and Schachter International Journal of Computer and Information Sciences, Vol 9, No. 3, 1980O: (combined hull, lower tangent that was added, upper tangent thtat was added))-Compute the lower tangent of the two polgyonspre: - polygons lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line separating the two polygons. - The vertices of the polygons are given in clockwise orderRRunning time: O(n+m), where n and m are the sizes of the two polygons respectively*-Compute the upper tangent of the two polgyonspre: - polygons lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line separating the two polygons. - The vertices of the polygons are given in clockwise orderRRunning time: O(n+m), where n and m are the sizes of the two polygons respectivelyrRotate to the rightmost pointsRotate to the leftmost point%t&'(uv)wx*+,rs%&'()*+,%()*,+&'%t&'(uv)wx*+,rs0None !"&'(*+,-./3457>CFIKLNUZ-6O(n log n) time ConvexHull using divide and conqueror.yz{-|--yz{-|1None !"&'(*+,-./3457>CFIKLNUZ.eThe result of a smallest enclosing disk computation: The smallest ball and the points defining it2List of two or three elements ./012345678 ./01234578 23465./0187./0123456782None !"&'(*+,-./3457>CFIKLNUZ9Horrible O(n^4) implementation that simply tries all disks, checks if they enclose all points, and takes the largest one. Basically, this is only useful to check correctness of the other algorithm(s)=BGiven a list of canidate enclosing disks, report the smallest one.>#check if a disk encloses all points9:;<=>9:;<=>9:;<=>9:;<=>3None !"&'(*+,-./3457>CFIKLNUZ?O(n) expected time algorithm to compute the smallest enclosing disk of a set of points. we need at least two points. implemented using randomized incremental construction@Smallest enclosing disk.A6Smallest enclosing disk, given that p should be on it.B;Smallest enclosing disk, given that p and q should be on itCConstructs the initial . from two points?@ABC?@ABC?@ABC?@ABC4None !"&'(*+,-./3457>CFIKLNUZDeNeighbours are stored in clockwise order: i.e. rotating right moves to the next clockwise neighbour.KRotating Right  - rotate clockwiseL*ST' is a strict triple (m,a,x) containing:fm: a Map, mapping edges, represented by a pair of vertexId's (u,v) with u < v, to arcId's."a: the next available unused arcID0x: the data value we are interested in computingDEFGHIJKLMNOPQRSTUVWXYZ[DEFGHIJKLMNOPQRSTUVWXYZ[KJIDEFGHVUTSWXYZNOPQRML[DEFGHIJKLMNOPQRSTUVWXYZ[5None !"&'(*+,-./3457>CFIKLNUZ^7Computes the delaunay triangulation of a set of points.lRunning time: $O(n log n)$ (note: We use an IntMap in the implementation. So maybe actually $O(n log^2 n)$)pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away)`Mapping that says for each vtx in the convex hull what the first entry in the adj. list should be. The input polygon is given in Clockwise orderaXGiven a polygon; construct the adjacency list representation pre: at least two elementsb&Merge the two delaunay triangulations.@running time: $O(n)$ (although we cheat a bit by using a IntMap)c'Merges the two delaunay traingulations.d'rotates'= around r and removes all neighbours of r that violate the delaunay condition. Returns the first vertex (as a Neighbour of r) that should remain in the Delaunay Triangulation, as well as a boolean A that helps deciding if we merge up by rotating left or rotating right (See description in the paper for more info)e&The code that does the actual rotatingfSymmetric to rotateRg=The code that does the actual rotating. Symmetric to rotateR'hereturns True if the forth point (vertex) does not lie in the disk defined by the first three points.i(Inserts an edge into the right position.jNmake sure that the first vtx in the adj list of v is its predecessor on the CHkhInserts an edge (and makes sure that the vertex is inserted in the correct. pos in the adjacency lists)lDeletes an edgem!Lifted version of Convex.IsLeftOfn"Lifted version of Convex.IsRightOfqan unsafeO version of rotateTo that assumes the element to rotate to occurs in the list.rIAdjacency lists are stored in clockwise order, so pred means rotate rightsKAdjacency lists are stored in clockwise order, so pred and succ rotate leftu%Removes duplicates from a sorted list\]^_`ab lower tangent upper tangentcdefghijklmnopqrstuvw\]^_`abcdefghijklmnopqrstuvw^_`ab]\cdefghijklmnopqrstuvw\]^_`abcdefghijklmnopqrstuvw6None !"&'(*+,-./3457>CFIKLNUZxNaive O(n^4) time implementation of the delaunay triangulation. Simply tries each triple (p,q,r) and tests if it is delaunay, i.e. if there are no other points in the circle defined by p, q, and r.pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away)ypGiven a list of edges, as vertexId pairs, construct a vector with the adjacency lists, each in CW sorted order.zGiven a particular point u and a list of points vs, sort the points vs in CW order around u. running time: O(m log m), where m=|vs| is the number of vertices to sort.{0Given a list of faces, construct a list of edges|aTest if the given three points form a triangle in the delaunay triangulation. running time: O(n)xyz{|xyz{|xyz{|xyz{|7None !"&'(*+,-./3457>CFIKLNUZ~Computes the Euclidean Minimum Spanning Tree. We compute the Delaunay Triangulation (DT), and then extract the EMST. Hence, the same restrictions apply as for the DT:pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away)running time: $O(n log n)$}~}~~}}~}>?@>?A>?B>?C>?D>?E>?F>GH>GIJKLMNOPQRSTUVVWXYZ[\]^_`abcdefghijjklmnoppqrsttuvwxyz{|}~~                              !"#$%&''())*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOOPQRSTUVWXYYZ[\]^__`abcdefghijklmnopqrstuvwxyz{|}~F     :: !"#$%&'()*+,-./0123456789:;<0=>?@ABCDEFGHIJKLLMMNlOPQRSTU{VWXYZ[\]^_`abcdefgghijklmnopqrst]uv)wxyz{|}~               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""###$$$$%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&''''''''(((((((((((((((((((( ( ( ) ) ) ))))))))))))))))))))))) )!)")#)$)%)&)')()))))*)+),)-).)/)0)1)2)3)4)5)6)7)8)9):);)<)=)>)?)@)A)B)C)D)E)F)G)H)I)J)K)L)M)N)O)P)Q)R)S)T)U)U)V)W)X)Y)Z)[)\)])^)_)`)a)b)c)d)e)e)f)g)h)i)j)k)l)m)n)o)p)q)r)s)s)t)u)v)w)x)x)y)z){)|)})~)~))))))))))))))))))))))))*********************************************************++++,,,,,,,,,,,,,,,,,,,,,,,,,----------------............... . . . . ............./////// /!01"1"1#1$1%1&1'11(1)1*2+2,2-2.2/203+3/313233444445464748494:4;4<444=4>4?4@4A4B4C4D4E4F4G4H5I5J5K5L5M5N55O55P55Q5R5S5T5U5V5!5 5W5X55Y5Z5[5\5]5^6K6_6`6a6b7c7d7e7fKgh8i8j8k8l8m8n8o8p8q8r8s8t8u8v8w8x8y8z8{8|8r8}8~8sF              ->>>>>>>>>>>>>>>>>>>>;;;  !!####%%%%%&&&&''(( ( ( ) ) ))))))))))))))----- -!-W-"-#-$-%-&-'-(-)-*-+-,---.-/-0-1-2-3-4-5-6-7-8-9-:-;-<-=->-?-@-A-B-C-D-E-F-G-H-I>?J>?K>?L>?M>?N>?O/P/Q/R/S/T/Z/Y0J0J0U0VWhgeom_B1f2DCxJCWtLeEJe0JHvFKData.Geometry.VectorControl.Monad.State.PersistentData.Sequence.UtilData.Geometry.Ipe.LiteralData.PermutationData.PlanarGraphAlgorithms.Graph.DFSAlgorithms.Graph.MSTSystem.Random.ShuffleData.BinaryTreeAlgorithms.UtilData.CircularSeq Data.Seq2Data.UnBoundedData.CircularList.UtilData.Ext Data.Geometry.Vector.VectorFixedData.Geometry.PropertiesData.Geometry.PointData.Geometry.TransformationData.Geometry.Ipe.AttributesData.PlaneGraph Data.RangeData.Geometry.IntervalData.Geometry.BoundaryData.Geometry.Line.InternalData.Geometry.Box.InternalData.Geometry.SubLineData.Geometry.LineSegmentData.Geometry.BoxData.Geometry.DualityData.Geometry.PolyLineData.Geometry.Polygon$Algorithms.Geometry.ConvexHull.Types)Algorithms.Geometry.ConvexHull.GrahamScan9Algorithms.Geometry.PolyLineSimplification.DouglasPeuckerData.Geometry.HalfLineData.Geometry.BallData.Geometry.TriangleData.Geometry.SlabData.Geometry.Ipe.TypesData.Geometry.Ipe.WriterData.Geometry.Ipe.FromIpeData.Geometry.Ipe.PathParserData.Geometry.Ipe.ReaderData.Geometry.Ipe.IpeOutData.Geometry.Polygon.Convex1Algorithms.Geometry.ConvexHull.DivideAndConqueror/Algorithms.Geometry.SmallestEnclosingBall.Types/Algorithms.Geometry.SmallestEnclosingBall.NaiveKAlgorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction/Algorithms.Geometry.DelaunayTriangulation.TypesViewR2:>>ViewL1:<ViewL2:<<Seq2duo<||>>< mapWithIndextakedroptoSeq fromSeqUnsafeheadL1 toNonEmptyviewL1FromNonEmptyviewl l1Singleton viewL1toR1viewr r1Singleton$fFoldableViewR1$fFunctorViewR1$fTraversableViewR1$fFoldableViewR2$fFunctorViewR2$fTraversableViewR2$fSemigroupViewL1$fFoldableViewL1$fFunctorViewL1$fTraversableViewL1$fFoldableViewL2$fFunctorViewL2$fTraversableViewL2 $fIxedSeq2$fSemigroupSeq2$fFoldableSeq2 $fFunctorSeq2$fTraversableSeq2 UnBounded MinInfinityVal _unUnBounded MaxInfinityBottom bottomToMaybeTop topToMaybeValTValB unUnBoundedunBoundedToMaybe insertOrd insertOrdBy insertOrdBy' splitIncr isShiftOf:+_core_extracoreextraext $fSemigroup:+$fBitraversable1:+$fBifoldable1:+$fBitraversable:+$fBifoldable:+$fBiapplicative:+ $fBiapply:+ $fBifunctor:+Prefixprefix'AlwaysTrueSnocAlwaysTrueDestructIndex'ArityVector_unVCVector2Vector3unVelementelement'destructcrosstoV3fromV3snocinitprefiximapv2v3_unV2_unV3 $fPrefixSS $fPrefixZd$fVectorVectorr$fMetricVector$fAffineVector$fAdditiveVector$fTraversableVector $fShowVectorisScalarMultipleOfscalarMultipleIsUnionableWithunionUnionAlwaysTrueIntersectionIsIntersectableWith intersect intersectsnonEmptyIntersectionIntersectionOf IntersectionNoIntersectionNumType DimensioncoRecdefaultNonEmptyIntersectionQuadrantTopRightTopLeft BottomLeft BottomRightCCWCoLinearCW PointFunctorpmap<=.PointtoVecPoint2Point3originvector unsafeCoordcoordpoint2_point2point3_point3xCoordyCoordzCoordccw sortArround quadrantWithquadrantpartitionIntoQuadrants ccwCmpAround cwCmpAroundinsertIntoCyclicOrdersquaredEuclideanDist euclideanDist$fPointFunctorPoint $fAffinePoint $fShowPointAlwaysTrueTransformation AlwaysTruePFTIsTransformable transformByTransformation_transformationMatrixMatrixmultMmulttransformationMatrix|.|transformAllBytransformPointFunctor translationscalinguniformScaling translateByscaleByscaleUniformlyBymkRowtransRow$fIsTransformablePointAttributeUniverseLayerPinTransformationsStrokeFillPenDashLineCapLineJoinFillRuleArrowRArrowOpacityTilingGradientClipAttrGAttr_getAttrGroupAttributesPathAttributesSymbolAttributesImageAttributesMiniPageAttributesTextLabelAttributesCommonAttributesSAttributeUniverseClipSym0 GradientSym0 TilingSym0 OpacitySym0 RArrowSym0 ArrowSym0 FillRuleSym0 LineJoinSym0 LineCapSym0DashSym0SizeSym0PenSym0FillSym0 StrokeSym0TransformationsSym0PinSym0 MatrixSym0 LayerSym0SLayerSMatrixSPinSTransformationsSStrokeSFillSPenSSizeSDashSLineCap SLineJoin SFillRuleSArrowSRArrowSOpacitySTiling SGradientSClip'TFCo:R:DemoteRepAttributeUniverseKProxy AttributesAttrs_unAttrsNoAttrgetAttr $fMonoidAttrIpeArrow _arrowName _arrowSize IpeGradient IpeTiling IpeOpacityFillTypeWindEOFillIpeDash DashNamed DashPatternIpeColorIpePenIpeSizeColourIpeValueNamedValuedTransformationTypesRigid TranslationsPinTypeNoYes HorizontalVerticalunAttrs zipRecsWithattrLens lookupAttrsetAttrtakeAttr unSetAttrattr$fIsStringIpeValue$fSemigroupAttributes$fMonoidAttributes$fEqAttributes AllSatisfyGDict IpeAttrNameattrName arrowName arrowSizewriteAttrNames$fIpeAttrNameClip$fIpeAttrNameGradient$fIpeAttrNameTiling$fIpeAttrNameOpacity$fIpeAttrNameRArrow$fIpeAttrNameArrow$fIpeAttrNameFillRule$fIpeAttrNameLineJoin$fIpeAttrNameLineCap$fIpeAttrNameDash$fIpeAttrNameSize$fIpeAttrNamePen$fIpeAttrNameFill$fIpeAttrNameStroke$fIpeAttrNameTransformations$fIpeAttrNamePin$fIpeAttrNameMatrix$fIpeAttrNameLayer PlaneGraphwithEdgeDistances_lower_upperEndPointOpenClosed unEndPointisOpenisClosed OpenRange ClosedRangeRange'lowerupper prettyShowinRangewidthmidPoint clipLower clipUpperisValid shiftLeft shiftRightInterval GInterval _unIntervalHasEndEndCoreEndExtraendHasStart StartCore StartExtrastart OpenIntervalClosedInterval unInterval inInterval shiftLeft'%$fIsIntersectableWithIntervalInterval$fHasEndInterval$fHasStartInterval$fBifunctorInterval$fTraversableInterval$fFoldableInterval$fFunctorInterval$fShowIntervalPointLocationResultInside OnBoundaryOutsideBoundaryLine _anchorPointSideTestBelowOnAboveHasSupportingLinesupportingLine anchorPoint lineThrough verticalLinehorizontalLineperpendicularTo isIdenticalTo isParallelToonLine sqDistanceTosqDistanceToArgfromLinearFunctiontoLinearFunctiononSide liesAbovebisector$fHasSupportingLineLine$fIsIntersectableWithLineLine $fShowLineBox_minP_maxPIsAlwaysTrueBoundingBox IsBoxable boundingBox RectanglemaxPminPfromCornerPointsminPointmaxPointinBoxextentwidthInwidthIn'heightcornersboundingBoxListboundingBoxList'$fIsBoxablePoint$fIsTransformableBox$fPointFunctorBox$fIsIntersectableWithBoxBox$fSemigroupBoxSubLine_line _subRangelinesubRangepointAt fixEndPointstoOffsetfromLine#$fIsIntersectableWithSubLineSubLine LineSegment LineSegment'ClosedLineSegment_SubLine toLineSegment onSegmentorderedEndPoints segmentLengthsqDistanceToSegsqDistanceToSegArg flipSegmenttopSide bottomSideleftSide rightSidesidessides'dualLine dualPoint dualPoint'PolyLine_pointspoints fromPoints fromPoints'fromLineSegment asLineSegmentasLineSegment'$fBifunctorPolyLine$fPointFunctorPolyLine$fIsTransformablePolyLine$fIsBoxablePolyLine$fSemigroupPolyLine$fFunctorPolyLine MultiPolygon SimplePolygonPolygon PolygonTypeSimpleMulti outerBoundaryholes outerVertexouterBoundaryEdgeholeListouterBoundaryEdgestoEdges onBoundary inPolygon insidePolygonarea signedAreacentroidisCounterClockwisetoClockwiseOrderasSimplePolygon cmpExtremeextremesLinear$fIsTransformablePolygon$fPointFunctorPolygon $fEqPolygon $fShowPolygon ConvexHull _extractHull extractHull convexHull upperHull lowerHulldouglasPeuckermergesplitmaxDistHalfLine _startPoint_halfLineDirectionhalfLineDirection startPointhalfLineToSubLine fromSubLine onHalfLine toHalfLine$fIsTransformableHalfLine$fHasSupportingLineHalfLine$fHasStartHalfLineBall_center_squaredRadiusTouchingCircleDiskSpherecenter squaredRadius fromDiameterfromCenterAndPointunitBallinBall insideBall inClosedBallonBalldisk($fIsIntersectableWithLineSegmentBoundary!$fIsIntersectableWithLineBoundary$fBifunctorBall $fFunctorBallTriangle doubleArea inscribedDisk$fIsTransformableTriangle$fPointFunctorTriangle$fFunctorTriangleSlab_unSlab OrthogonalHasBoundingLines boundingLinesinSlabunSlabhorizontalSlab verticalSlab $fIsIntersectableWithSubLineSlab$fIsIntersectableWithLineSlab$fHasBoundingLinesVertical$fHasBoundingLinesHorizontal$fIsIntersectableWithSlabSlab$fIsIntersectableWithSlabSlab0$fBifunctorSlab$fTraversableSlab$fFoldableSlab $fFunctorSlabImage _imageData_rect LayerName _layerName IpeSymbolSymbol _symbolPoint _symbolNameMiniPage TextLabelLabel imageDatarect$fIsTransformableMiniPage$fIsTransformableTextLabel$fIsTransformableImage PathSegmentPolyLineSegment PolygonPathCubicBezierSegmentQuadraticBezierSegmentEllipseSegment ArcSegment SplineSegmentClosedSplineSegment symbolName symbolPoint$fIsTransformableIpeSymbolPath _pathSegments_PolyLineSegment _PolygonPath_CubicBezierSegment_QuadraticBezierSegment_EllipseSegment _ArcSegment_SplineSegment_ClosedSplineSegment$fIsTransformablePathSegment OperationMoveToLineToCurveToQCurveToEllipseArcToSpline ClosedSpline ClosePath pathSegments$fIsTransformablePathAttrMap_MoveTo_LineTo_CurveTo _QCurveTo_Ellipse_ArcTo_Spline _ClosedSpline _ClosePath IpeObjectIpeGroupIpeImage IpeTextLabel IpeMiniPageIpeUseIpePath IpeObject' IpeAttributes Attributes' AttributesOfGroup _groupItems AttrMapSym0AttrMapSym0KindInference AttrMapSym1AttrMapSym1KindInference AttrMapSym2 attributes$fIsTransformableGroupTFCo:R:Apply(->)*AttrMapSym0l0 _IpeGroup _IpeImage _IpeTextLabel _IpeMiniPage_IpeUse_IpePathView _layerNames _activeLayerToObject ipeObject' groupItemscommonAttributes$fIsTransformableIpeObject$fToObjectPath$fToObjectIpeSymbol$fToObjectMiniPage$fToObjectTextLabel$fToObjectImage$fToObjectGroupIpeStyle _styleName _styleData activeLayer layerNames IpePreamble _encoding _preambleData styleData styleName basicIpeStyleIpePage_layers_views_content IpeBitmapencoding preambleDataIpeFile _preamble_styles_pagescontentlayersviews fromContentpagespreamblestylessinglePageFilesinglePageFromContent applyMatrix' applyMatrix applyMatricesapplyMatricesPageIpeWriteipeWrite IpeWriteText ipeWriteText writeIpeFile writeIpePageprintAsIpeSelectiontoIpeSelectionXMLtoIpeXML writeIpeFile' ipeWriteAttrswriteAttrValuesaddAttsmAddAtts writeByShowunwords'unlines' ipeWriteRec fromPolyLinecombine $fIpeWrite()$fIpeWriteLineSegment$fIpeWritePolyLine$fIpeWriteIpeFile$fIpeWriteIpePreamble$fIpeWriteIpeStyle$fIpeWriteIpePage$fIpeWriteView$fIpeWriteLayerName$fIpeWriteIpeObject$fIpeWriteTextLabel$fIpeWriteText()$fIpeWriteImage$fIpeWriteMiniPage $fIpeWrite:+$fIpeWriteGroup$fIpeWritePath$fIpeWriteTextPathSegment$fIpeWriteTextPolygon$fIpeWriteTextPolyLine$fIpeWriteTextOperation$fIpeWriteTextMatrix$fIpeWriteIpeSymbol$fIpeWriteTextPath$fIpeWriteTextIpeArrow$fIpeWriteTextFillType$fIpeWriteTextIpeDash$fIpeWriteTextPinType!$fIpeWriteTextTransformationTypes$fIpeWriteTextIpeValue$fIpeWriteTextPoint$fIpeWriteTextRatio$fIpeWriteTextFixed$fIpeWriteTextInt$fIpeWriteTextDouble$fIpeWriteTextText$fIpeWriteTextAttr_asLineSegment _asPolyLine_asSimplePolygon _withAttrsEither'Left'Right' CoordinatefromSeqdefaultFromSeqreadCoordinate readPoint runParsereither'readPathOperations errorText combineErrorssplitKeepDelims readMatrix readRectangle pOperationpPoint pCoordinate pRectanglepMatrixmkMatrix$fMonoidEither'$fCoordinateRatio$fCoordinateDouble IpeReadAttr ipeReadAttrIpeReadipeRead IpeReadText ipeReadTextConversionErrorreadRawIpeFile readIpeFilereadSinglePageFile fromIpeXMLreadXMLipeReadTextWith ipeReadRec ipeReadAttrs ipeReadObjectHasDefaultIpeOut DefaultIpeOut defaultIpeOutIpeOutasIpe asIpeObject asIpeObject'asIpeObjectWith asIpeGroup asIpeGroup' ipeObjectcoreOutipeMark ipeDiskMarknoAttrs addAttributesdefaultClipRectangleipeLineSegmentipeLineSegment' ipePolyLine ipePolyLine'ipeDisk ipeCircle ipeCircle'fromPathSegmentipeSimplePolygon$fHasDefaultIpeOutPolygon$fHasDefaultIpeOutPolyLine$fHasDefaultIpeOutBall$fHasDefaultIpeOutLineSegment$fHasDefaultIpeOutPoint ConvexPolygonextremesmaxInDirection lowerTangent upperTangent isRightOfisLeftOf DiskResult_enclosingDisk_definingPoints TwoOrThreeTwoThree$fFoldableTwoOrThreedefiningPoints enclosingDisksmallestEnclosingDiskpairstripletsdisk'smallestEnclosingDisk' enclosesAllsmallestEnclosingDiskWithPointsmallestEnclosingDiskWithPointsinitial Triangulation _vertexIds _positions _neighboursAdjVertexVertexIDST'ArcIDfst'snd'trd'Mapping neighbours positions vertexIdsshowDTtriangulationEdgestEdgesdrawTriangulation toPlaneGraphFirstsMergedelaunayTriangulationdelaunayTriangulation'firstsfromHullmoveUprotateR'rotateL'qTestinsert rotateToFirstinsert'deletelookup'size'pred'succ'focus'nub'withIDlookup'' toAdjLists sortAround' extractEdges isDelaunayMSTW euclideanMST drawTree' treeEdgesrunPersistentStateT'$fMonadStatesPersistentStateTpManypNotFollowedBy<*><><***>***> ReversablereverseSrunP'runPpMany1pChoicepNaturalpIntegerpCharpSpace pWhiteSpacepMaybepCountpSepBy<*><<***$fReversableText$fReversable[]parse_EE5NO1mlYLh4J8mgDEshNvText.Parsec.TextParserText.Parsec.Error ParseErrorreorderEdgeData$fReadDirection$fShowDirection $fShowArc _embedding _vertexData _rawDartData _faceData$fShowVertexId $fEnumDart $fShowDartTest rawDartDatatestPermtestG $fShowFaceIdUFfind'_unUFnewrands withFocusresplit allRotations' $fFunctorCSeq$fFoldableCSeq$fFoldable1CSeq$fTraversableCSeq $fShowCSeqTFCo:R:IxValueSeq2TFCo:R:IndexSeq2GBottomGTop $fShowBottom $fShowTop$fOrdTop$fFractionalUnBounded$fNumUnBounded$fShowUnBoundedlens_6THwE7flHbkHItCrVXejGzControl.Lens.TraversalTFCo:R:DimVectorScalarMultipleMaybeallZeroscalarMultiple'$fMonoidScalarMultiple Linear.VectorouterunitscaledbasisForbasis^/^**^sumVnegatedelEliftI2liftU2lerp^-^^+^zeroAdditiveTFCo:R:DimensionPointTFCo:R:NumTypePointTFCo:R:NumTypeTransformationcmpLowercmpUpper _unEndPoint clipLower' clipUpper'$fIsIntersectableWithRangeRangeTFCo:R:IntersectionOfRangeRange%TFCo:R:IntersectionOfIntervalIntervalTFCo:R:NumTypeIntervalTFCo:R:DimensionIntervalTFCo:R:DimensionBoundaryTFCo:R:NumTypeBoundaryTFCo:R:IntersectionOfLineLineTFCo:R:NumTypeLineTFCo:R:DimensionLineTFCo:R:NumTypeBoxTFCo:R:DimensionBoxTFCo:R:IntersectionOfBoxBox#TFCo:R:IntersectionOfSubLineSubLineTFCo:R:NumTypeSubLineTFCo:R:DimensionSubLine GLineSegment _unLineSeg unLineSegsegment2SubLinesubLineToSegment$$fIsIntersectableWithLineSegmentLine+$fIsIntersectableWithLineSegmentLineSegment$TFCo:R:IntersectionOfLineSegmentLine+TFCo:R:IntersectionOfLineSegmentLineSegment$fBifunctorLineSegment$fIsTransformableLineSegment$fIsBoxableLineSegment$fPointFunctorLineSegment$fShowLineSegment$fHasSupportingLineLineSegment$fHasEndLineSegment$fHasStartLineSegmentTFCo:R:NumTypeLineSegmentTFCo:R:DimensionLineSegment$fIsTransformableLineTFCo:R:IntersectionOfLineBox!TFCo:R:IntersectionOfLineBoundaryTFCo:R:NumTypePolyLineTFCo:R:DimensionPolyLineTFCo:R:DimensionPolygonTFCo:R:NumTypePolygonhullhull'incXdecY rightTurn(TFCo:R:IntersectionOfHalfLineLineSegment%TFCo:R:IntersectionOfHalfLineHalfLine!TFCo:R:IntersectionOfHalfLineLineTFCo:R:NumTypeHalfLineTFCo:R:DimensionHalfLine(TFCo:R:IntersectionOfLineSegmentBoundaryTFCo:R:DimensionBallTFCo:R:NumTypeBallTFCo:R:DimensionTriangleTFCo:R:NumTypeTriangle TFCo:R:IntersectionOfSubLineSlabTFCo:R:IntersectionOfLineSlabTFCo:R:IntersectionOfSlabSlabTFCo:R:IntersectionOfSlabSlab0TFCo:R:DimensionMiniPageTFCo:R:NumTypeMiniPageTFCo:R:DimensionTextLabelTFCo:R:NumTypeTextLabelTFCo:R:DimensionImageTFCo:R:NumTypeImageTFCo:R:DimensionIpeSymbolTFCo:R:NumTypeIpeSymbolTFCo:R:DimensionPathSegmentTFCo:R:NumTypePathSegmentTFCo:R:DimensionPathTFCo:R:NumTypePathTFCo:R:DimensionIpeObjectTFCo:R:NumTypeIpeObjectTFCo:R:DimensionGroupTFCo:R:NumTypeGroupzipTraverseWithallTextreadAll$fIpeReadIpeSymboltestSym readSymAttrs firstRighttestz validateAll validateAll'unTexttestP readPolyLinesreadPolyLines'polylinesFromIpeFile$fIpeReadPathSegment$fIpeReadPolyLine$fIpeReadTextPolyLine$fIpeReadIpeFile$fIpeReadIpePage $fIpeReadView$fIpeReadLayerName$fIpeReadGroup$fIpeReadIpeObject$fIpeReadImage$fIpeReadMiniPage$fIpeReadTextLabel $fIpeReadPath$fIpeReadAttrAttr$fIpeReadTextPath$fIpeReadTextNonEmpty$fIpeReadText[]$fIpeReadTextIpeSize$fIpeReadTextIpePen$fIpeReadTextIpeColor$fIpeReadTextBox$fIpeReadTextIpeDash$fIpeReadTextIpeArrow$fIpeReadTextFillType $fIpeReadTextTransformationTypes$fIpeReadTextPinType$fIpeReadTextLayerName$fIpeReadTextMatrix$fIpeReadTextPoint$fIpeReadTextInt$fIpeReadTextTextrelative_PointlensPV_PMV_PP rightMostleftMostmainWith rotateTo'coreEqunMerge$fSemigroupMerge