! j:       !"#$%&'()*+,-./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 { | } ~                                                                                                                                 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./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+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.{.|.}.~....//////000000000000000000000000000000000111222222222222222222222222222233333333333333333333334445555555555555555555555555555555555555566 6 6 6 6 6666666666666667777 7!7"7#7$7%7&7'7(7)7*7+7,7-7.7/708182838485868788898:8;8<8=8>8?8@8A8B8C8D8E8F8G8H8I8J8K8L8M8N8O8P8Q8R9S9T9U9V9W9X9Y9Z9[9\9]9^9_9`9a9b9c9d9e9f9g9h9i9j9k9l9m9n9o9p9q9r9s9t9u9v9w9x9y9z9{9|9}9~:::::::::::::::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ; ;;;;;;;;;;;;;;;;;;; ;!;";#;$;%;&;';(;);*;+;,;-;.;/;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<{<|<}<~<<<<<<<<<<<<<<<<<<<<<<============================>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>??????????????????@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @ @ @ @ A A A A A A A A A A A A A A A A B B B C C !D "D #D $E %E &E 'E (E )E *F +F ,G -G .G /G 0G 1G 2G 3G 4G 5G 6G 7G 8G 9G :G ;G <G =G >G ?G @G AG BG CG DG EG FG GG HG IG JG KG LG MG NG OG PH QH RH SH TH UH VI WI XI YI ZJ [J \J ]J ^J _J `J aJ bJ cJ dJ eJ fK gK hK iK jK kK lK mK nK oK pK qK rK sK tK uK vK wK xL yL zL {L |L }L ~L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N !N "N #N $N %N &N 'N (N )N *N +N ,N -N .N /N 0O 1O 2O 3P 4P 5P 6P 7P 8Q 9Q :Q ;Q <Q =Q >Q ?Q @Q AQ BQ CQ DQ EQ FQ GQ HQ IQ JQ KQ LQ MQ NQ OQ PQ QQ RQ SQ TQ UQ VQ WQ XQ YQ ZR [R \S ]S ^S _S `S aS bS cS dT eT fT gT hT iT jT kT lT mT nT oT pT qT rT sT tT uT vT wT xT yT zT {T |T }T ~T T T T T T T T T T T T T T T T T U U U U U U U U U U U U U U U U U U U V V V V W W W W W W W W W W W W W W W W W W W W W W W W W W W X X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Z Z Z Z [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ \ ] ] ] ] ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^b(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g  hgeometry>Represent a computation that needs a particular time as input.' hgeometry$Comparison function for timed values( hgeometryCoerce timed values* hgeometry#Runs a computation at a given time. !"#$%&'()*+,-./0#$%& !"'()*+,-./0None%&',-.1234567=>?@AHMPSUVX_g7 hgeometry;A State monad that can store earlier versions of the state.8 hgeometryWCreate a snapshot of the current state and add it to the list of states that we store.9 hgeometryrun a persistentStateT, returns a triplet with the value, the last state and a list of all states (including the last one) in chronological order6789:7689:None"#%&',-.1234567=>?@AHMPSUVX_gB hgeometryResult of splititng a treeD hgeometrySplitting and extractingCA pair that is strict in its first argument and lazy in the second.P hgeometryA balanced binary search treeT hgeometry!Describes how to search in a treeZ hgeometryCreates an empty BST[ hgeometry O(n\log n)] hgeometryCheck if the tree is empty^ hgeometry'Test if an element occurs in the BST.  O(\log n)_ hgeometry O(\log n)` hgeometrySearch for the Predecessor  O(\log n)a hgeometryInsert an element in the BST. O(\log n)b hgeometry'Delete (one occurance of) an element.  O(\log n)c hgeometry#Extract the minimum from the tree  O(\log n)e hgeometry#Extract the maximum from the tree  O(\log n)g hgeometryPJoins two BSTs. Assumes that the ranges are disjoint. It takes the left Tree nav O(\log n)h hgeometry.Joins two BSTs' with a specific Tree Navigator O(\log n)j hgeometry0Extract a prefix from the tree, i.e. a repeated c O(\log n +k), where k" is the size of the extracted partk hgeometry0Extract a suffix from the tree, i.e. a repeated c O(\log n +k), where k" is the size of the extracted partl hgeometrydSplits the tree at x. Note that if x occurs more often, no guarantees are given which one is found. O(\log n)m hgeometry$split based on a monotonic predicate O(\log n)n hgeometryfSplits at a given monotone predicate p, and then selects everything that satisfies the predicate sel.q hgeometry:Get the minimum in the tree. Errors when the tree is empty O(\log n)r hgeometry:Get the maximum in the tree. Errors when the tree is empty O(\log n)s hgeometry Extract all elements in the treeO(n)t hgeometry Extract all elements in the treeO(n)x hgeometryrebalance the tree<?A@BCDEGFHJKILMONPQRSTUWVXYZ[\]^_`abcdefghijklmnopqrstuvwxyz<TUWVXYPQRSMONLHJKIZ[\]^_`abcdefghDEGFijkBClmn?A@opqrstuvwxyz(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@ACHMPSUVX_g=  hgeometryEBinary tree in which we store the values of type a in internal nodes. hgeometryhBinary tree that stores its values (of type a) in the leaves. Internal nodes store something of type v. hgeometrysmart constructor hgeometry.Create a balanced tree, i.e. a tree of height  O(\log n)" with the elements in the leaves.O(n) time. hgeometryGiven a function to combine internal nodes into b's and leafs into b's, traverse the tree bottom up, and combine everything into one b. hgeometry?Traverses the tree bottom up, recomputing the assocated values. hgeometryfTakes two trees, that have the same structure, and uses the provided functions to "zip" them together hgeometry0Get the element stored at the root, if it exists hgeometryCreate a balanced binary tree.running time: O(n) hgeometry-Fold function for folding over a binary tree. hgeometry Convert a  BinaryTree into a RoseTree hgeometryDraw a binary tree.None%&',-.1234567=>?@AHMPSUVX_g  hgeometryFocus on the root hgeometryGo to the left child hgeometryGo to the right child hgeometryMove to the parent hgeometryNavigate to the root hgeometry@Returns a list of zippers; one focussed on each node in the tree hgeometry(Get the value stored at the current node hgeometry=Returns all subtrees; i.e. every node with all its decendents hgeometry:Splits the tree here, returns a pair (innerTree,outerTree)None%&',-.1234567=>?@AHMPSUVX_g hgeometryGiven 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] hgeometry_Insert an element into an increasingly ordered circular list, with specified compare operator. hgeometryList version of insertOrdBy; i.e. the list contains the elements in cirulcar order. Again produces a list that has the items in circular order. hgeometry}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 list None%&',-.1234567=>?@AHMPSUVX_gi hgeometryNonempty circular sequence hgeometry.Gets the focus of the CSeq running time: O(1) hgeometryGAccess 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)0 hgeometry4Adjusts the i^th element w.r.t the focus in the CSeqrunning time: O(\log (i \mod n))'adjust (const 1000) 2 (fromList [0..5])CSeq [0,1,1000,3,4,5] hgeometry:Access te ith item in the CSeq (w.r.t the focus) as a lens  hgeometry5smart constructor that automatically balances the seq  hgeometry4Builds a balanced seq with the element as the focus.  hgeometryrotates one to the rightrunning time: O(1) (amortized)rotateR $ fromList [3,4,5,1,2]CSeq [4,5,1,2,3]  hgeometryrotates 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]  hgeometry1Convert to a single Seq, starting with the focus.  hgeometry9All elements, starting with the focus, going to the right hgeometry8All elements, starting with the focus, going to the left#leftElements $ fromList [3,4,5,1,2]fromList [3,2,1,5,4] hgeometry builds a CSeq hgeometry Rotates i elements to the right.pre: 0 <= i < nrunning 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] hgeometryRotates i elements to the left.pre: 0 <= i < nrunning 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] hgeometry#Reversres the direction of the CSeqrunning time: O(n)"reverseDirection $ fromList [1..5]CSeq [1,5,4,3,2] hgeometryFinds an element in the CSeq%findRotateTo (== 3) $ fromList [1..5]Just (CSeq [3,4,5,1,2])%findRotateTo (== 7) $ fromList [1..5]Nothing hgeometry+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] hgeometry"Left zip": zip the two CLists, pairing up every element in the *left* list with its corresponding element in the right list. If there are more items in the right clist they are discarded. hgeometry see 'zipLWith hgeometry%same as zipLWith but with three items hgeometryGiven a circular seq, whose elements are in increasing order, insert the new element into the Circular seq in its sorted order.insertOrd 1 $ fromList [2] CSeq [2,1]insertOrd 2 $ fromList [1,3] CSeq [1,2,3]insertOrd 31 ordListCSeq [5,6,10,20,30,31,1,2,3]insertOrd 1 ordListCSeq [5,6,10,20,30,1,1,2,3]insertOrd 4 ordListCSeq [5,6,10,20,30,1,2,3,4]insertOrd 11 ordListCSeq [5,6,10,11,20,30,1,2,3]running time: O(n) hgeometry_Insert an element into an increasingly ordered circular list, with specified compare operator.running time: O(n)  hgeometryList version of insertOrdBy; i.e. the list contains the elements in cirulcar order. Again produces a list that has the items in circular order. hgeometry}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 list           None%&',-.1234567=>?@AHMPSUVX_go&'()&'()_None%&',-.1234567=>?@AHMPSUVX_g#  hgeometry%reexporting some standard combinators  hgeometryparses an integer with a prefix of zeros. Returns the total length of the string parced (i.e. number of digits) and the resulting antural number.  hgeometryinfix variant of notfollowed by  hgeometryRunning parsers in reverse;Runs parser q ``in reverse'' on the end of the input stream  hgeometry1run the parsers in reverse order, first q, then p  hgeometry"the variants with missing brackets          ! " # $ % &   '   ( 1 '1 2 2 (2 (C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g'* hgeometryBMany types either consist of a symbolc value, or a value of type v*,+*,+ (C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g*7 hgeometryCreates a named color56789:;<=>?@ABCDEFGHIJKLMNOPQ56789:;<=>?@ABCDEFGHIJKLMNOPQ (C) Frank Staalssee the LICENSE file Frank StaalsNone#%&',-.1234567=>?@ADHMPSUVX_gAl hgeometrylAttr implements the mapping from labels to types as specified by the (symbol representing) the type family f hgeometry Possible values for an ipe arrow hgeometry>IpeOpacity, IpeTyling, and IpeGradient are all symbolic values hgeometryAllowed Fill types hgeometryPath 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 Dash hgeometryTODOSymbol AttributesThe optional Attributes for a symbol data SymbolAttributeUniverse = SymbolStroke | SymbolFill | SymbolPen | Size deriving (Show,Eq) hgeometry"Possible values for Transformation hgeometryCommon AttributesPossible values for Pin hgeometryAn Attribute that is not set hgeometry;Constructor for constructing an Attr given an actual value. hgeometry.gets and removes the attribute from Attributes hgeometryunsets/Removes an attribute hgeometryGive pref. to the *RIGHT* hgeometryIFunction that states that all elements in xs satisfy a given constraint c hgeometrydFor the types representing attribute values we can get the name/key to use when serializing to ipe. hgeometryWriting Attribute namesq ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ;Vhgfedba`_]\[ZYWX^clmnopqrstuvwxyz{|}~^Vhgfedba`_]\[ZYWX^c~}|{zyxwvutsrqpolmn(C) Frank Staalssee the LICENSE file Frank StaalsNone!%&',-.12345678=>?@ADHMPSTUVX_gT  hgeometryTWhen using IntersectionOf we may need some constraints that are always true anyway. hgeometryg  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. hgeometryHelper to implement . hgeometryQThe type family specifying the list of possible result types of an intersection. hgeometry6The result of interesecting two geometries is a CoRec, hgeometry=A simple data type expressing that there are no intersections hgeometry=A type family for types that have an associated numeric type. hgeometryA type family for types that are associated with a dimension. The dimension is the dimension of the geometry they are embedded in. hgeometryHelper to produce a corec hgeometry5Returns True iff the result is *not* a NoIntersection(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.12345679=>?@AHMPSUVX_gY  hgeometry]Our Ext type that represents the core datatype core extended with extra information of type .   11None%&',-.1234567=>?@AHMPSUVX_gi% hgeometrysDatatype representing d dimensional vectors. Our implementation wraps the implementation provided by fixed-vector.( hgeometry.A proxy which can be used for the coordinates., hgeometry-Pattern synonym for two and three dim vectors. hgeometryLens into the i th element/ hgeometry 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 Traversal2 hgeometry!Get the head and tail of a vector3 hgeometry.Cross product of two three-dimensional vectors4 hgeometryVonversion to a Linear.V25 hgeometryConversion to a Linear.V36 hgeometryConversion from a Linear.V37 hgeometry(Add an element at the back of the vector8 hgeometry)Get a vector of the first d - 1 elements.: hgeometry&Get a prefix of i elements of a vector; hgeometry Construct a 2 dimensional vector< hgeometry Construct a 3 dimensional vector= hgeometry#Destruct a 2 dim vector into a pair%&'()*+,-./0123456789:;<=>()%&'-./0123456789:;<=>,+*None%&',-.1234567=>?@AHMPSUVX_gpS hgeometryGMapping between the implementation type, and the actual implementation.T hgeometryDatatype representing d dimensional vectors. The default implementation is based n VectorFixed. However, for small vectors we automatically select a more efficient representation.l hgeometry!Get the head and tail of a vectorRSTUVWXYZ[\]^_`abcdefghijklma`_^]\YZ[WXTUVSbRcdefghijklm(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g{ hgeometryDatatype representing d dimensional vectors. The default implementation is based n VectorFixed. However, for small vectors we automatically select a more efficient representation. hgeometryLens into the i th element hgeometry 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 hgeometry(Add an element at the back of the vector hgeometry)Get a vector of the first d - 1 elements. hgeometry&Get a prefix of i elements of a vector hgeometry.Cross product of two three-dimensional vectors(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g hgeometry$Test if v is a scalar multiple of u..Vector2 1 1 `isScalarMultipleOf` Vector2 10 10True-Vector2 1 1 `isScalarMultipleOf` Vector2 10 1False2Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.1True2Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.2False2Vector2 2 1 `isScalarMultipleOf` Vector2 11.1 11.2False,Vector2 2 1 `isScalarMultipleOf` Vector2 4 2True,Vector2 2 1 `isScalarMultipleOf` Vector2 4 0False hgeometry8Get the scalar labmda s.t. v = lambda * u (if it exists) < hgeometry'Actual implementation of scalarMultiple< ()() (C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gF hgeometry1Quadrants of two dimensional points. in CCW order hgeometryPTypes that we can transform by mapping a function on each point in the structure hgeometryA d-dimensional point. hgeometrySimilarly, we can write::{ let& g :: Point 3 r -> r g (Point3 x y z) = z in g myPoint:}3 hgeometryaWe 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. hgeometry-Point representing the origin in d dimensionsorigin :: Point 4 IntPoint4 [0,0,0,0] hgeometry6Lens to access the vector corresponding to this point.(point3 1 2 3) ^. vectorVector3 [1,2,3] origin & vector .~ Vector3 1 2 3Point3 [1,2,3] hgeometry{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 hgeometry'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] hgeometry-Constructs a point from a list of coordinates,pointFromList [1,2,3] :: Maybe (Point 3 Int)Just Point3 [1,2,3] hgeometry,Project a point down into a lower dimension. hgeometryConstruct a 2 dimensional point point2 1 2 Point2 [1,2] hgeometryDestruct a 2 dimensional point_point2 $ point2 1 2(1,2) hgeometryConstruct a 3 dimensional point point3 1 2 3Point3 [1,2,3] hgeometryDestruct a 3 dimensional point_point3 $ point3 1 2 3(1,2,3) hgeometry,Shorthand to access the first coordinate C 1point3 1 2 3 ^. xCoord1point2 1 2 & xCoord .~ 10 Point2 [10,2] hgeometry-Shorthand to access the second coordinate C 2point2 1 2 ^. yCoord2point3 1 2 3 & yCoord %~ (+1)Point3 [1,3,3] hgeometry,Shorthand to access the third coordinate C 3point3 1 2 3 ^. zCoord3point3 1 2 3 & zCoord %~ (+1)Point3 [1,2,4] hgeometryTGiven three points p q and r determine the orientation when going from p to r via q. hgeometryTGiven three points p q and r determine the orientation when going from p to r via q. hgeometrySort 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) hgeometryQuadrants 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 quadrant hgeometry$Quadrants with respect to the origin hgeometrygGiven 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. hgeometryCounter 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. hgeometryClockwise 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. hgeometryGiven 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) hgeometry-Squared Euclidean distance between two points hgeometry%Euclidean distance between two points))None%&',-.1234567=>?@AHMPSUVX_g2 hgeometryIA class representing types that can be transformed using a transformation hgeometry>A type representing a Transformation for d dimensional objects hgeometry?a matrix of n rows, each of m columns, storing values of type r hgeometry'Compose transformations (right to left) hgeometry"Compute the inverse transformation.inverseOf $ translation (Vector2 (10.0) (5.0))~Transformation {_transformationMatrix = Matrix Vector3 [Vector3 [1.0,0.0,-10.0],Vector3 [0.0,1.0,-5.0],Vector3 [0.0,0.0,1.0]]} hgeometrycCreates a row with zeroes everywhere, except at position i, where the value is the supplied value. hgeometryRow in a translation matrix transRow :: forall n r. ( Arity n, Arity (n- 1), ((n - 1) + 1) ~ n , Num r) => Int -> r -> Vector n r transRow i x = set (V.element (Proxy :: Proxy (n-1))) x $ mkRow i 1 hgeometryzGiven three new unit-length basis vectors (u,v,w) that map to (x,y,z), construct the appropriate rotation that does this.None%&',-.1234567=>?@AHMPSUVX_gڀ hgeometry`Result of a query that asks if something is Inside a g, *on* the boundary of the g, or outside. hgeometry#The boundary of a geometric object.(C) Frank Staalssee the LICENSE file Frank StaalsNone"%&',-.12345679=>?@AHMPSUVX_g" hgeometryJA line is given by an anchor point and a vector indicating the direction.' hgeometryResult of a side test+ hgeometry`Types for which we can compute a supporting line, i.e. a line that contains the thing of type t./ hgeometry*A line may be constructed from two points.2 hgeometry]Given a line l with anchor point p, get the line perpendicular to l that also goes through p.3 hgeometrymTest if two lines are identical, meaning; if they have exactly the same anchor point and directional vector.4 hgeometry#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)False5 hgeometryTest 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)False6 hgeometry8Specific 2d version of testing if apoint lies on a line.7 hgeometryGet the point at the given position along line, where 0 corresponds to the anchorPoint of the line, and 1 to the point anchorPoint .+^ directionVector8 hgeometryGiven point p and a line (Line q v), Get the scalar lambda s.t. p = q + lambda v. If p does not lie on the line this returns a Nothing.9 hgeometryuGiven point p *on* a line (Line q v), Get the scalar lambda s.t. p = q + lambda v. (So this is an unsafe version of 8)*pre: the input point p lies on the line l.: hgeometry'Squared distance from point p to line l; hgeometrybThe squared distance between the point p and the line l, and the point m realizing this distance.< hgeometry-Create a line from the linear function ax + b= hgeometrygget values a,b s.t. the input line is described by y = ax + b. returns Nothing if the line is vertical> hgeometryGiven 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))On? hgeometry6Test if the query point q lies (strictly) above line l@ hgeometry#Get the bisector between two pointsA hgeometryVCompares the lines on slope. Vertical lines are considered larger than anything else.B(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 3 3))LTE(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 (-3) 3))GTB(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 0 1))LT = hgeometryKThe intersection of two lines is either: NoIntersection, a point or a line."#%$'()*+,-./0123456789:;<=>?@A"#%$.-/0123456789:;+,<='()*>?@A(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gR hgeometry;LSeq n a certifies that the sequence has *at least* n items] hgeometryJPromises that the length of this LSeq is actually n. This is not checked.This function should be a noop^ hgeometry'Forces the first n elements of the LSeq` hgeometryappends two sequences.a hgeometry[get the element with index i, counting from the left and starting at 0. O(log(min(i,n-i)))n hgeometry"Gets the first element of the LSeq6head $ forceLSeq (Proxy :: Proxy 3) $ fromList [1,2,3]1o hgeometry Get the last element of the LSeq6last $ forceLSeq (Proxy :: Proxy 3) $ fromList [1,2,3]3"NOPQRSTUVWXYZ[\]^_`abcdefghijklmno"RWXjki_YZ[\abcdefhgno`PQlVUTNOmS]^O5Q5S5U5V5Y5Z5[5None%&',-.1234567=>?@AHMPSUVX_g)  hgeometryInsert into a monotone OrdSeq.*pre: the comparator maintains monotonicity O(\log n) hgeometryInsert into a sorted OrdSeq O(\log n) hgeometry O(\log n) hgeometryGiven a monotonic function f that maps a to b, split the sequence s depending on the b values. I.e. the result (l,m,r) is such that * all (< x) . fmap f $ l * all (== x) . fmap f $ m * all (> x) . fmap f $ r"splitOn id 3 $ fromAscList' [1..5](OrdSeq {_asFingerTree = fromList [Elem 1,Elem 2]},OrdSeq {_asFingerTree = fromList [Elem 3]},OrdSeq {_asFingerTree = fromList [Elem 4,Elem 5]})NsplitOn fst 2 $ fromAscList' [(0,"-"),(1,"A"),(2,"B"),(2,"C"),(3,"D"),(4,"E")](OrdSeq {_asFingerTree = fromList [Elem (0,"-"),Elem (1,"A")]},OrdSeq {_asFingerTree = fromList [Elem (2,"B"),Elem (2,"C")]},OrdSeq {_asFingerTree = fromList [Elem (3,"D"),Elem (4,"E")]}) O(\log n) hgeometrywGiven a monotonic predicate p, splits the sequence s into two sequences (as,bs) such that all (not p) as and all p bs O(\log n) hgeometry inserts all eleements in order  O(n\log n) hgeometry inserts all eleements in order  O(n\log n) hgeometryO(n) hgeometry O(\log n) hgeometry-Fmap, assumes the order does not change O(n) hgeometry*Gets the first element from the sequence O(1)(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g7A  hgeometry'Cyclic representation of a permutation. hgeometryNidxes (fromEnum a) = (i,j) implies that a is the j^th item in the i^th orbit hgeometry*Orbits (Cycles) are represented by vectors hgeometry!The cycle containing a given item hgeometry!Next item in a cyclic permutation hgeometry%Previous item in a cyclic permutation hgeometrycLookup the indices of an element, i.e. in which orbit the item is, and the index within the orbit.runnign time: O(1) hgeometryCApply the permutation, i.e. consider the permutation as a function. hgeometry7Find the cycle in the permutation starting at element s hgeometryjGiven the size n, and a list of Cycles, turns the cycles into a cyclic representation of the Permutation.(C) Frank Staalssee the LICENSE file Frank StaalsNone!%&',-.1234567=>?@AHMPSUVX_g[G hgeometryA 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. hgeometry_Darts have a direction which is either Positive or Negative (shown as +1 or -1, respectively). hgeometrygAn Arc is a directed edge in a planar graph. The type s is used to tie this arc to a particular graph. hgeometryReverse the direcion hgeometry Edge Oracle:main idea: store adjacency lists in such a way that we store an edge (u,v) either in u's adjacency list or in v's. This can be done s.t. all adjacency lists have length at most 6.Pnote: Every edge is stored exactly once (i.e. either at u or at v, but not both) hgeometry%Shorthand for FaceId's in the primal. hgeometryThe type to reprsent FaceId's hgeometry)get the data associated with the value i.running time: O(1) to read the data, O(n) to write it. hgeometryA *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.The orbits in the embedding are assumed to be in counterclockwise order. Therefore, every dart directly bounds the face to its right. hgeometry%Shorthand for vertices in the primal. hgeometry~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. hgeometryoWe can take the dual of a world. For the Primal this gives us the Dual, for the Dual this gives us the Primal. hgeometry"The world in which the graph lives hgeometry Get the twin of this dart (edge)twin (dart 0 "+1")Dart (Arc 0) -1twin (dart 0 "-1")Dart (Arc 0) +1 hgeometrytest if a dart is Positive hgeometry4Enumerates all darts such that allDarts !! i = d  = i == fromEnum d > hgeometry#The Dual of the Dual is the Primal. ? hgeometryEnclodes the planar graph as a JSON object. note that every face is stored together with a dart bounding the face. (and so that the face lies to its right. Otherwise we cannot reconstruct the face data appropriately. hgeometry1Helper function to build the graph from JSON datarunning time: O(n) hgeometryLGet the embedding, reprsented as a permutation of the darts, of this graph.  hgeometry!Get the dual graph of this graph.  hgeometrylens to access the Dart Data  hgeometryedgeData is just an alias for  @ hgeometryHelper function to update the data in a planar graph. Takes care to update both the data in the original graph as well as in the dual. A hgeometry+The function that does the actual work for  @ B hgeometry?Reorders the edge data to be in the right order to set edgeData hgeometryTraverse the vertices(^.vertexData)  $ traverseVertices (i x -> Just (i,x)) myGraph Just [(VertexId 0,()),(VertexId 1,()),(VertexId 2,()),(VertexId 3,())] >>> traverseVertices (i x -> print (i,x)) myGraph >> pure () (VertexId 0,()) (VertexId 1,()) (VertexId 2,()) (VertexId 3,()) hgeometryTraverses the darts6traverseDarts (\d x -> print (d,x)) myGraph >> pure () (Dart (Arc 0) +1,"a+")(Dart (Arc 0) -1,"a-")(Dart (Arc 1) +1,"b+")(Dart (Arc 1) -1,"b-")(Dart (Arc 2) +1,"c+")(Dart (Arc 2) -1,"c-")(Dart (Arc 3) +1,"d+")(Dart (Arc 3) -1,"d-")(Dart (Arc 4) +1,"e+")(Dart (Arc 4) -1,"e-")(Dart (Arc 5) +1,"g+")(Dart (Arc 5) -1,"g-") hgeometryTraverses the faces6traverseFaces (\i x -> print (i,x)) myGraph >> pure () (FaceId 0,()) (FaceId 1,()) (FaceId 2,()) (FaceId 3,()) hgeometryConstruct a planar graphrunning time: O(n). hgeometryNConstruct a planar graph, given the darts in cyclic order around each vertex.running time: O(n). hgeometry}Construct a planar graph from a adjacency matrix. For every vertex, all vertices should be given in counter clockwise order.&pre: No self-loops, and no multi-edgesrunning time: O(n). hgeometryProduces the adjacencylists for all vertices in the graph. For every vertex, the adjacent vertices are given in counter clockwise order.Note that in case a vertex u as a self loop, we have that this vertexId occurs twice in the list of neighbours, i.e.: u : [...,u,..,u,...]. Similarly, if there are multiple darts between a pair of edges they occur multiple times.running time: O(n) hgeometryGet the number of verticesnumVertices myGraph4 hgeometryGet the number of DartsnumDarts myGraph12 hgeometryGet the number of EdgesnumEdges myGraph6 hgeometryGet the number of facesnumFaces myGraph4 hgeometryEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3] hgeometry7Enumerate all vertices, together with their vertex data hgeometryEnumerate all darts hgeometry&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-") hgeometry6Enumerate all edges. We report only the Positive darts hgeometryMEnumerate 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+") hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1)  hgeometry%The vertex this dart is heading in torunning time: O(1)! hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1)" hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k is the output size# hgeometryLAll incoming edges incident to vertex v, in counterclockwise order around v.$ hgeometryLAll outgoing edges incident to vertex v, in counterclockwise order around v.% hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output size& hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1)' hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1)( hgeometry/Data corresponding to the endpoints of the dart) hgeometry/Data corresponding to the endpoints of the dartrunning time: O(1) C hgeometryThe 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"] ]5 in (computeDual myGraph)^.embedding.orbits == answer:}Truerunning time: O(n). D hgeometry"Does the actual work for dualGraph* hgeometry'Enumerate all faces in the planar graph+ hgeometryAll faces with their face data., hgeometry 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 0running time: O(1).- hgeometry!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 1running time: O(1).. hgeometry Get the next edge along the facerunning time: O(1)./ hgeometry$Get the previous edge along the facerunning time: O(1).0 hgeometry`Gets a dart bounding this face. I.e. a dart d such that the face lies to the right of the dart.1 hgeometrytThe darts bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.2 hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reported3 hgeometrywThe vertices bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.4 hgeometryGiven a planar graph, construct an edge oracle. Given a pair of vertices this allows us to efficiently find the dart representing this edge in the graph.(pre: No self-loops and no multi-edges!!!running time: O(n)5 hgeometryeBuilds an edge oracle that can be used to efficiently test if two vertices are connected by an edge.running time: O(n)6 hgeometry)Test if u and v are connected by an edge.running time: O(1)7 hgeometryEFind the edge data corresponding to edge (u,v) if such an edge existsrunning time: O(1)8 hgeometryhGiven a pair of vertices (u,v) returns the dart, oriented from u to v, corresponding to these vertices.running time: O(1)T      !"#$%&'()*+,-./012345678T    *+ !"#$%&'() ,-0123./45768None%&',-.1234567=>?@AHMPSUVX_gY hgeometrycAdjacency list representation of a graph: for each vertex we simply list all connected neighbours.Z hgeometryDFS 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.[ hgeometry+Transform into adjacencylist representation\ hgeometryFDFS, from a given vertex, on a graph in AdjacencyLists representation.Running time: O(n)YZ[\ZY[\None%&',-.1234567=>?@AHMPSUVX_g[ E hgeometry Union find DS] hgeometryMinimum 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)^ hgeometry6Computes the set of edges in the Minimum spanning treerunning time:  O(n \log n)_ hgeometry_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. F hgeometry~Union the components containing x and y. Returns weather or not the two components were already in the same component or not. G hgeometryGet 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]^_]^_(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.12345679=>?@AHMPSUVX_gh` hgeometry"Data type for representing ranges.d hgeometry2Endpoints of a range may either be open or closed.y hgeometryBA range from l to u, ignoring/forgetting the type of the endpoints~ hgeometry9Helper function to show a range in mathematical notation.prettyShow $ OpenRange 0 2"(0,2)"prettyShow $ ClosedRange 0 2"[0,2]"&prettyShow $ Range (Open 0) (Closed 5)"(0,5]" hgeometry 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 hgeometryGet the width of the intervalwidth $ ClosedRange 1 109width $ OpenRange 5 105 hgeometrytClip the interval from below. I.e. intersect with the interval {l,infty), where { is either open, (, orr closed, [. hgeometryhClip the interval from above. I.e. intersect with (-infty, u}, where } is either open, ), or closed, ], hgeometry>Wether or not the first range completely covers the second one hgeometryCheck 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. H hgeometry!Compare end points, Closed < Open I hgeometry%Compare the end points, Open < Closed hgeometry!Shift a range x units to the left-prettyShow $ shiftLeft 10 (ClosedRange 10 20)"[0,10]"+prettyShow $ shiftLeft 10 (OpenRange 15 25)"(5,15)" hgeometryShifts the range to the right.prettyShow $ shiftRight 10 (ClosedRange 10 20) "[20,30]",prettyShow $ shiftRight 10 (OpenRange 15 25) "(25,35)"`abcdfeghiyz{|}~dfehig`abc~|}{zyNone%&',-.1234567=>?@AHMPSUVX_g" hgeometry,Open on left endpoint; so Closed before open hgeometry.Order on right endpoint; so Open before ClosedNone%&',-.1234567=>?@AHMPSUVX_g hgeometryAn Interval is essentially a `a but with possible payload hgeometryTest 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.)`abcdfeghiyz{|}~ None %&',-.12345679=>?@AHMPSUVX_gc  hgeometry1Information stored in a node of the Interval Tree hgeometry.IntervalTree type, storing intervals of type i hgeometry$Anything that looks like an interval hgeometry8Given an ordered list of points, create an interval treeO(n) hgeometryBuild an interval tree O(n \log n) hgeometry@Lists the intervals. We don't guarantee anything about the orderrunning time: O(n). hgeometryFind all intervals that stab x O(\log n + k), where k is the output size hgeometryFind all intervals that stab x O(\log n + k), where k is the output size hgeometry@Insert : pre: the interval intersects some midpoint in the tree O(\log n) hgeometry Delete an interval from the Tree O(\log n)) (under some general position assumption)!(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g$4 hgeometryOInternal nodes store a split point, the range, and an associated data structure hgeometryCLeaf nodes store an atomic range, and an associated data structure. J hgeometry.We store atomic ranges a bit more efficiently. hgeometry(Segment tree on a Fixed set of endpoints hgeometryInterval hgeometry%Class for associcated data structures hgeometryNGiven a sorted list of endpoints, without duplicates, construct a segment treeO(n) time K hgeometryInterleaves the two lists8interleave (NonEmpty.fromList ["0","1","2"]) ["01","12"]"0" :| ["01","1","12","2"] hgeometryBuild a SegmentTree O(n \log n) L hgeometrylists all intervals hgeometry'Search for all intervals intersecting x O(\log n + k) where k is the output size hgeometryBReturns the associated values of the nodes on the search path to x O(\log n) M hgeometry(Gets the range associated with this node  hgeometryNPre: the interval should have one of the endpoints on which the tree is built.  hgeometry Delete an interval from the tree pre: The segment is in the tree!"   "   bNone%&',-.1234567=>?@AHMPSUVX_g&b"   "(C) Frank Staalssee the LICENSE file Frank StaalsNone"%&',-./1234567=>?@AHMPSUVX_gI* hgeometryCoordinate wize minimum5 hgeometryCoordinate wize maximumN hgeometrybGiven the point with the lowest coordinates and the point with highest coordinates, create a box.O hgeometrygrows the box by x on all sidesP hgeometry)Build a d dimensional Box given d ranges.Q hgeometryNGiven a center point and a vector specifying the box width's, construct a box.R hgeometryCenter of the boxU hgeometryCheck 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)TrueV hgeometryGet 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 (Closed 1) (Closed 10),Range (Closed 2) (Closed 20),Range (Closed 3) (Closed 30)]W hgeometryGet 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]X hgeometryXGiven 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)3Y hgeometrySame as X6 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)Nothing\ hgeometryGet 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 point^ hgeometryOUnsafe version of boundingBoxList, that does not check if the list is non-empty"*+,5678BCEDFIJKLMNOPQRSTUVWXYZ[\]^"*+,8567FBCEDMLNOPQRSTUVWXYKZ[\IJ]^#None%&',-.1234567=>?@AHMPSUVX_g]j hgeometryGiven a monotonic predicate, Get 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 prunning time: O(\log^2 n + T*\log n), where T' is the time to execute the predicate.k hgeometryGiven a monotonic predicate, get 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 prunning time:  O(T*\log n), where T' is the time to execute the predicate.l hgeometryGPartition 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.running time: O(\log^2 n + T*\log n), where T' is the time to execute the predicate.m hgeometryoGiven 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))jklmjklm$None%&',-.1234567=>?@AHMPSUVX_gq w hgeometryInsert into a monotone OrdSeq.*pre: the comparator maintains monotonicity O(\log^2 n)x hgeometryInsert into a sorted OrdSeq O(\log^2 n)z hgeometry O(\log^2 n){ hgeometryGiven a monotonic function f that maps a to b, split the sequence s depending on the b values. I.e. the result (l,m,r) is such that * all (< x) . fmap f $ l * all (== x) . fmap f $ m * all (> x) . fmap f $ r"splitOn id 3 $ fromAscList' [1..5]{(OrdSeq {_asSeq = fromList [Elem 1,Elem 2]},OrdSeq {_asSeq = fromList [Elem 3]},OrdSeq {_asSeq = fromList [Elem 4,Elem 5]})NsplitOn fst 2 $ fromAscList' [(0,"-"),(1,"A"),(2,"B"),(2,"C"),(3,"D"),(4,"E")](OrdSeq {_asSeq = fromList [Elem (0,"-"),Elem (1,"A")]},OrdSeq {_asSeq = fromList [Elem (2,"B"),Elem (2,"C")]},OrdSeq {_asSeq = fromList [Elem (3,"D"),Elem (4,"E")]}) O(\log^2 n)| hgeometrywGiven a monotonic predicate p, splits the sequence s into two sequences (as,bs) such that all (not p) as and all p bs O(\log^2 n) hgeometry inserts all eleements in order  O(n\log n) hgeometry inserts all eleements in order  O(n\log n) hgeometryO(n) hgeometry O(\log^2 n) hgeometry)Fmap, assumes the order does not change O(n) hgeometry*Gets the first element from the sequence O(1)nopqrstuvwxyz{|}~rstuvopqnwxyz{|}~%None%&',-.1234567=>?@AHMPSUVX_g hgeometryZipper for rose trees hgeometry+Create a new zipper focussiong on the root. hgeometry*Move the focus to the parent of this node. hgeometry/Move the focus to the first child of this node.firstChild $ root myTreeJust (Zipper {focus = Node {rootLabel = 1, subForest = []}, ancestors = [([],0,[Node {rootLabel = 2, subForest = []},Node {rootLabel = 3, subForest = [Node {rootLabel = 4, subForest = []}]}])]}) hgeometry/Move the focus to the next sibling of this node*(firstChild $ root myTree) >>= nextSiblingJust (Zipper {focus = Node {rootLabel = 2, subForest = []}, ancestors = [([Node {rootLabel = 1, subForest = []}],0,[Node {rootLabel = 3, subForest = [Node {rootLabel = 4, subForest = []}]}])]}) hgeometry/Move the focus to the next sibling of this node hgeometryiGiven a zipper that focussses on some subtree t, construct a list with zippers that focus on each child. hgeometryGiven a zipper that focussses on some subtree t, construct a list with zippers that focus on each of the nodes in the subtree of t. hgeometryCreates a new tree from the zipper that thas the current node as root. The ancestorTree (if there is any) forms the first child in this new root. hgeometry?Constructs a tree from the list of ancestors (if there are any) hgeometrywGiven a predicate on an element, find a node that matches the predicate, and turn that node into the root of the tree.running time: O(nT) where n is the size of the tree, and T& is the time to evaluate a predicate.findEvert (== 4) myTreeJust (Node {rootLabel = 4, subForest = [Node {rootLabel = 3, subForest = [Node {rootLabel = 0, subForest = [Node {rootLabel = 1, subForest = []},Node {rootLabel = 2, subForest = []}]}]}]})findEvert (== 5) myTreeNothing hgeometryGiven a predicate matching on a subtree, find a node that matches the predicate, and turn that node into the root of the tree.running time: O(nT(n)) where n is the size of the tree, and T(m); is the time to evaluate a predicate on a subtree of size m. hgeometryFunction to extract a path between a start node and an end node (if such a path exists). If there are multiple paths, no guarantees are given about which one is returned.running time:  O(n(T_p+T_s), where n is the size of the tree, and T_p and T_s( are the times it takes to evaluate the isStartingNode and  isEndingNode predicates.findPath (== 1) (==4) myTreeJust [1,0,3,4]findPath (== 1) (==2) myTree Just [1,0,2]findPath (== 1) (==1) myTreeJust [1]findPath (== 1) (==2) myTree Just [1,0,2]findPath (== 4) (==2) myTreeJust [4,3,0,2] hgeometryOGiven a predicate on a, find (the path to) a node that satisfies the predicate.findNode (== 4) myTree Just [0,3,4] hgeometry2Find all paths to nodes that satisfy the predicaterunning time: O(nT(n)) where n is the size of the tree, and T(m); is the time to evaluate a predicate on a subtree of size m.$findNodes ((< 4) . rootLabel) myTree[[0],[0,1],[0,2],[0,3]]#findNodes (even . rootLabel) myTree[[0],[0,2],[0,3,4]]4let size = length in findNodes ((> 1) . size) myTree [[0],[0,3]] hgeometryis this node a starting node hgeometryis this node an ending node&None%&',-.1234567=>?@AHMPSUVX_g hgeometry?`UnBounded a` represents the type a, together with an element / larger than any other element, and an element ", smaller than any other element. hgeometry2`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 = Bottom | ValB a hgeometry/`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 | Top'None %&',-.1234567=>?@AHMPSUVX_g  hgeometryrPart of a line. The interval is ranged based on the vector of the line l, and s.t.t zero is the anchorPoint of l. hgeometry3Annotate the subRange with the actual ending points hgeometryDforget the extra information stored at the endpoints of the subline. hgeometry?Transform into an subline with a potentially unbounded interval hgeometry?Try to make a potentially unbounded subline into a bounded one. hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r hgeometry*Get the endpoints of an unbounded interval((C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.1234567=>?@AHMPSUVX_gN  hgeometryLine 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 as\data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p)) hgeometryHGets the start and end point, but forgetting if they are open or closed. hgeometry6Pattern that essentially models the line segment as a:\data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p)) hgeometry,Directly convert a line into a line segment. hgeometry'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 hgeometryNThe left and right end point (or left below right if they have equal x-coords) hgeometryLength of the line segment hgeometryNSquared distance from the point to the Segment s. The same remark as for the  applies here. hgeometryESquared 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). hgeometry,flips the start and end point of the segment3`abcdfeghiyz{|}~3`abcdfeghiyz{|}~)(C) Frank Staalssee the LICENSE file Frank StaalsNone"%&',-.12345679=>?@AHMPSUVX_g hgeometryOriented from *left to right* hgeometry-The right side, oriented from *bottom* to top  hgeometryThe 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.  hgeometryYThe 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.(*+,5678BCDEFIJKLMNOPQRSTUVWXYZ[\]^    *None %&',-.1234567=>?@AHMPSUVX_g  hgeometry*A Poly line in R^d has at least 2 vertices hgeometry0pre: The input list contains at least two points hgeometry`pre: The input list contains at least two points. All extra vields are initialized with mempty. hgeometry'We consider the line-segment as closed. hgeometry@Convert to a closed line segment by taking the first two points. hgeometry\Stricter version of asLineSegment that fails if the Polyline contains more than two points.      +(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.1234567=>?@AHMPSUVX_g hgeometry$Data that we store in the split tree"! #$%()+*,-./78;:9<=>?@ABGHI%$#"! /.-,()+*A@B?<=>78;:9IHG,(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gAJ hgeometryCST monad with access to the vector storign the level of the points.K hgeometryConstruct a split treerunning time:  O(n \log n)L hgeometry5Given a split tree, generate the Well separated pairsrunning time: O(s^d n)M hgeometryKGiven the points, sorted in every dimension, recursively build a split treeThe algorithm works in rounds. Each round takes O(n) time, and halves the number of points. Thus, the total running time is O(n log n).The algorithm essentially builds a path in the split tree; at every node on the path that we construct, we split the point set into two sets (L,R) according to the longest side of the bounding box.The smaller set is "assigned" to the current node and set asside. We continue to build the path with the larger set until the total number of items remaining is less than n/2.`To start the next round, each node on the path needs to have the points assigned to that node, sorted in each dimension (i.e. the Vector (PointSeq))'s. Since we have the level assignment, we can compute these lists by traversing each original input list (i.e. one for every dimension) once, and partition the points based on their level assignment.N hgeometry2Assign the points to their the correct class. The  N$ class is considered the last classP hgeometry2Assign the points to their the correct class. The  N$ class is considered the last classR hgeometryGiven a sequence of points, whose index is increasing in the first dimension, i.e. if idx p < idx q, then p[0] < q[0]. Reindex the points so that they again have an index in the range [0,..,n'], where n' is the new number of points.Xrunning time: O(n' * d) (more or less; we are actually using an intmap for the lookups)alternatively: I can unsafe freeze and thaw an existing vector to pass it along to use as mapping. Except then I would have to force the evaluation order, i.e. we cannot be in R( for two of the nodes at the same time.0so, basically, run reIndex points in ST as well.S hgeometryAssigns the points to a level. Returns the list of levels used. The first level in the list is the level assigned to the rest of the nodes. Their level is actually still set to Nothing in the underlying array.T hgeometry9Remove already assigned pts from the ends of all vectors.U hgeometryAssign level l to point pV hgeometryGet the level of a pointW hgeometry5Test if the point already has a level assigned to it.X hgeometry1Remove allready assigned points from the sequencepre: there are points remainingY hgeometryGiven the points, ordered by their j^th coordinate, split the point set into a "left" and a "right" half, i.e. the points whose j^th coordinate is at most the given mid point m, and the points whose j^th coordinate is larger than m.,We return a pair (Largest set, Smallest set)fi ndAndCompact works by simultaneously traversing the points from left to right, and from right to left. As soon as we find a point crossing the mid point we stop and return. Thus, in principle this takes only O(|Smallest set|) time.running time: O(|Smallest set|) + R, where R is the number of *old* points (i.e. points that should have been removed) in the list.Z hgeometry*Find the widest dimension of the point set3pre: points are sorted according to their dimension\ hgeometry]get the extends of the set of points in every dimension, i.e. the left and right boundaries.3pre: points are sorted according to their dimension^ hgeometry4Test if the two sets are well separated with param s_ hgeometry1Test if the two boxes are sufficiently far appartb hgeometry)Computes the maximum width of a splitTreec hgeometryComputes! the bounding box of a split treee hgeometryTurn a traversal into lensP hgeometrynumber of classes hgeometrylevel assignment hgeometry input pointsS hgeometry"Number of items we need to collect hgeometry#Number of items we collected so far hgeometrynext level to use hgeometryLevels used so farY hgeometryWthe dimension we are in, i.e. so that we know which coordinate of the point to compare hgeometry the mid point^ hgeometryseparation factorJKLMNOPQRSTUVWXYZ[\]^_`abcdefKLMNOPQRJSTUVWXYZ[\]^_`abcdef-None%&',-.1234567=>?@AHMPSUVX_gMg hgeometryLine 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.h hgeometry;Concatenate the two polylines, dropping their shared vertexi hgeometryJSplit the polyline at the given vertex. Both polylines contain this vertexj hgeometryGiven 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.ghijghij.None%&',-.1234567=>?@AHMPSUVX_gP hgeometry]reports true if there is at least one segment for which this intersection point is interior.O(1)klnmopqsrtuvwxutpqsrvwxoklnm/None%&',-.1234567=>?@AHMPSUVX_gV* hgeometry#Compute all intersections (naively)O(n^2) hgeometryHTest if the two segments intersect, and if so add the segment to the map hgeometry"Add s and s' to the map with key p hgeometry(figure out which map to add the point to0None%&',-.1234567=>?@AHMPSUVX_gm hgeometry1The actual event consists of a point and its type hgeometryType of segment hgeometryCompute all intersectionsO((n+k)\log n), where k is the number of intersections. hgeometry`Computes all intersection points p s.t. p lies in the interior of at least one of the segments.O((n+k)\log n), where k is the number of intersections. hgeometry2Computes the event points for a given line segment hgeometry/Group the segments with the intersection points hgeometry\Group the startpoints such that segments with the same start point correspond to one event. hgeometry4An ordering that is decreasing on y, increasing on x hgeometry4Get the segments that start at the given event point hgeometryYCompare based on the x-coordinate of the intersection with the horizontal line through y hgeometryGiven a y coord and a line segment that intersects the horizontal line through y, compute the x-coordinate of this intersection point.Lnote that we will pretend that the line segment is closed, even if it is not hgeometry!Run the sweep handling all events hgeometryHandle an event point hgeometryjsplit the status structure, extracting the segments that contain p. the result is (before,contains,after) hgeometry`Given a point and the linesegements that contain it. Create a piece of status structure for it. hgeometry#Get the right endpoint of a segment hgeometryTest if a segment ends at p hgeometryFind all events1(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.1234567=>?@ADHMPSUVX_gq hgeometry*Lines are transformable, via line segments"#$%'*)(+,-./0123456789:;<=>?@A2None %&',-.1234567=>?@AHMPSUVX_gv} hgeometryMThe two bounding lines of the slab, first the lower one, then the higher one: hgeometry0Smart consturctor for creating a horizontal slab hgeometry.Smart consturctor for creating a vertical slab  3None!%&',-.12345679=>?@AHMPSUVX_g{ hgeometryHyperplanes embedded in a d dimensional space. hgeometrymTypes for which we can compute a supporting hyperplane, i.e. a hyperplane that contains the thing of type t. hgeometry%Test if a point lies on a hyperplane.  4None%&',-.1234567=>?@AHMPSUVX_gk hgeometry1Maps a line point (px,py) to a line (y=px*x - py) hgeometryZReturns Nothing if the input line is vertical Maps a line l: y = ax + b to a point (a,-b) hgeometry#Pre: the input line is not vertical5(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.1234567=>?@AHMPSUVX_g  hgeometryA d-dimensional ball. hgeometry%Spheres, i.e. the boundary of a ball. hgeometry&A lens to get/set the radius of a Ball hgeometry?Given two points on the diameter of the ball, construct a ball. hgeometryFConstruct a ball given the center point and a point p on the boundary. hgeometry1A d dimensional unit ball centered at the origin. hgeometry+Test if a point lies strictly inside a ball&(point2 0.5 0.0) `insideBall` unitBallTrue"(point2 1 0) `insideBall` unitBallFalse"(point2 2 0) `insideBall` unitBallFalse hgeometry&Test if a point lies in or on the ball hgeometry/Test if a point lies on the boundary of a ball.(point2 1 0) `onBall` unitBallTrue (point3 1 1 0) `onBall` unitBallFalse hgeometrytGiven 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}) hgeometry2Creates a circle from three points on the boundary O hgeometrydA line segment may not intersect a circle, touch it, or intersect it properly in one or two points. P hgeometry2No intersection, one touching point, or two points6None%&',-.1234567=>?@AHMPSUVX_g   hgeometryEconvenience function to construct a triangle without associated data.  hgeometryCompute the area of a triangle  hgeometry2*the area of a triangle.  hgeometry9Checks if the triangle is degenerate, i.e. has zero area. hgeometryhget the inscribed disk. Returns Nothing if the triangle is degenerate, i.e. if the points are colinear. hgeometry[Given a point q and a triangle, q inside the triangle, get the baricentric cordinates of q hgeometryGiven a vector of barricentric coordinates and a triangle, get the corresponding point in the same coordinate sytsem as the vertices of the triangle. hgeometryQTests if a point lies inside a triangle, on its boundary, or outside the triangle hgeometry<Test if a point lies inside or on the boundary of a triangle            7None!%&',-.12345679=>?@AHMPSUVX_g hgeometryd-dimensional Half-Lines% hgeometry#Test if a point lies on a half-line& hgeometryTransform 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. !"#$%& "!#$%&8(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g0 hgeometry0Strict pair whose elements are of the same type.$Strict pair with both items the same1 hgeometry Strict pair3 hgeometry strict triple9 hgeometry'Generate All unique unordered triplets.: hgeometry7Given a list xs, generate all unique (unordered) pairs.; hgeometry8A version of List.tails in which we remove the emptylist 0123476589:; 3476591208:;9(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gR hgeometryEither a simple or multipolygonX hgeometryOWe distinguish between simple polygons (without holes) and Polygons with holes.^ hgeometry,Access the i^th vertex on the outer boundary` hgeometryGet all holes in a polygona hgeometryXThe vertices in the polygon. No guarantees are given on the order in which they appear!b hgeometry9Creates a simple polygon from the given list of vertices.3pre: the input list constains no repeated vertices.c hgeometryKThe edges along the outer boundary of the polygon. The edges are half open.running time: O(n)d hgeometryLists all edges. The edges on the outer boundary are given before the ones on the holes. However, no other guarantees are given on the order.running time: O(n)e hgeometryvPairs every vertex with its incident edges. The first one is its predecessor edge, the second one its successor edge.<mapM_ print . polygonVertices $ withIncidentEdges simplePolyPoint2 [0 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ()))Point2 [10 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ()))Point2 [10 % 1,10 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ()))Point2 [5 % 1,15 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ())) LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ()))Point2 [1 % 1,11 % 1] :+ SP LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ())) LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ()))f hgeometryUGiven the vertices of the polygon. Produce a list of edges. The edges are half-open.g hgeometryATest 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 multipolygonh hgeometryhCheck 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 testcasesi hgeometry1Test if a point lies strictly inside the polgyon.j hgeometryCompute the area of a polygonk hgeometryCompute 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.l hgeometry)Compute the centroid of a simple polygon.m hgeometryVTest if the outer boundary of the polygon is in clockwise or counter clockwise order.running time: O(n)n hgeometry,Orient the outer boundary to clockwise ordero hgeometry4Orient the outer boundary to counter clockwise orderq hgeometryDConvert a Polygon to a simple polygon by forgetting about any holes.r hgeometry(Comparison that compares which point is larger) in the direction given by the vector u.s hgeometryCFinds the extreme points, minimum and maximum, in a given directionrunning time: O(n)t hgeometryassigns unique integer numbers to all vertices. Numbers start from 0, and are increasing along the outer boundary. The vertices of holes will be numbered last, in the same order.numberVertices simplePolySimplePolygon CSeq [Point2 [0 % 1,0 % 1] :+ SP 0 (),Point2 [10 % 1,0 % 1] :+ SP 1 (),Point2 [10 % 1,10 % 1] :+ SP 2 (),Point2 [5 % 1,15 % 1] :+ SP 3 (),Point2 [1 % 1,11 % 1] :+ SP 4 ()] Q hgeometry)Polygons are per definition 2 dimensional#RSTUWVXZY[\]^_`abcdefghijklmnopqrst#XZYUWV[TSR\]^_`abcdefghijklmnopqrst:(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.1234567=>?@AHMPSUVX_g0 ~ hgeometry'Data Type representing a convex polygon hgeometryCFinds the extreme points, minimum and maximum, in a given direction*pre: The input polygon is strictly convex.running time:  O(\log n) hgeometryBFinds 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) hgeometryRotating 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) hgeometry-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 hgeometry-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 respectively hgeometry]Computes the Minkowski sum of the two input polygons with $n$ and $m$ vertices respectively.%pre: input polygons are in CCW order.running time: O(n+m). R hgeometryERotate to the rightmost point (rightmost and topmost in case of ties) S hgeometry=Rotate to the leftmost point (and bottommost in case of ties) hgeometry=Rotate to the bottommost point (and leftmost in case of ties) T hgeometry.Helper to get the vertices of a convex polygon U hgeometry)Polygons are per definition 2 dimensional~~;(C) Frank Staalssee the LICENSE file Frank StaalsNone#%&',-.1234567=>?@AHMPSUVX_g2 hgeometry Image Objects hgeometryIpe Symbols, i.e. PointsA symbol (point) in ipe hgeometry Text Objects hgeometryGExample 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: hgeometry/A path is a non-empty sequence of PathSegments. hgeometry#type that represents a path in ipe. hgeometryzThe mapping between the labels of the the attributes and the types of the attributes with these labels. For example, the = label/attribute should have a value of type 'Matrix 3 3 r'. hgeometryBAn IpeObject' is essentially the oject ogether with its attributes hgeometry,Attributes' :: * -> [AttributeUniverse] -> * hgeometryGroups and ObjectsGroup Attributes,A group is essentially a list of IpeObjects. hgeometry;The definition of a view make active layer into an index ? hgeometry%Shorthand for constructing ipeObjects hgeometrycollect all non-group objects! hgeometry#for now we pretty much ignore these) hgeometry The maybe string is the encoding4 hgeometryWAn IpePage is essentially a Group, together with a list of layers and a list of views.> hgeometryA complete ipe fileF hgeometry$Creates a simple page with no views.L hgeometryJConvenience function to construct an ipe file consisting of a single page.M hgeometry7Create a single page ipe file from a list of IpeObjectsN hgeometry8Takes and applies the ipe Matrix attribute of this item.O hgeometry2Applies the matrix to an ipe object if it has one.     !"$#%&)*,+-./458769:;>?BA@CDEFIJKLMNOPQ     &%!"$#.-/)*,+;:945876EDCF>?BA@KJILMNOPQ<(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.1234567=>?@AHMPSUVX_gH R hgeometryTypes 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 T typeclass instead.T hgeometry'For types that can produce a text valueV hgeometryGiven 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.W hgeometry2Creates a single page ipe file with the given pageX hgeometryConvert 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.Y hgeometry$Convert input into an ipe selection.Z hgeometryConvert to Ipe xml[ hgeometry2Convert to ipe XML and write the output to a file.\ hgeometry(Functon to write all attributes in a Rec] hgeometryWriting the attribute values^ hgeometryAdd attributes to a node_ hgeometrySame as ^ but then for a Maybe nodeu hgeometryCThis instance converts the ratio to a Pico, and then displays that.RSTUVWXYZ[\]^_`abcdeVWXYZ[TURS\]^_`abcde=None%&',-.12345678=>?@AHMPSUVX_gM$ hgeometryORepresent stuff that can be used as a coordinate in ipe. (similar to show/read) hgeometryRunning the parsers hgeometryThe parsers themselves hgeometry/Generate a matrix from a list of 6 coordinates.>None %&',-.1234567=>?@AHMPSUVX_gi hgeometryOBasically 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. hgeometryReading an ipe lement from Xml hgeometry'Reading an ipe elemtn from a Text value hgeometry,Given a file path, tries to read an ipe file hgeometry]Given a file path, tries to read an ipe file. This function applies all matrices to objects. hgeometrywSince most Ipe file contain only one page, we provide a shortcut for that as well. This function applies all matrices. hgeometryqGiven a Bytestring, try to parse the bytestring into anything that is IpeReadable, i.e. any of the Ipe elements. hgeometry3Reads the data from a Bytestring into a proper Node V hgeometry&Combination of zipRecWith and traverse hgeometryReading 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). hgeometryReader 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. hgeometryIf we can ipeRead an ipe element, and we can ipeReadAttrs its attributes we can properly read an ipe object using ipeReadObject W hgeometry{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. X hgeometry:try reading everything as an a. Throw away whatever fails. hgeometryIpe read instances?(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g~F hgeometry|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. hgeometry5Convert to a polyline. Ignores all non-polyline partstestPath ^? _asPolyLinelJust (PolyLine {_points = LSeq (fromList [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [200,100] :+ ()])}) hgeometryConvert to a simple polygon hgeometryConvert to a triangle hgeometryConvert to a multipolygon hgeometryUse 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.-testObject ^? _withAttrs _IpePath _asPolyLine Just (PolyLine {_points = LSeq (fromList [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [200,100] :+ ()])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "red"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr}) hgeometry#Read all g's from some ipe page(s). hgeometryConvenience function from reading all g's from an ipe file. If there is an error reading or parsing the file the error is "thrown away".@(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g hgeometryUClass that specifies a default conversion from a geometry type g into an ipe object. hgeometryAdd attributes to an IpeObject' hgeometryRender an ipe object:{5 iO $ defIO myPolygon ! attr SFill (IpeColor "blue"), ! attr SLayer "alpha"+ ! attr SLayer "beta":}PIpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {Attr LayerName {_layerName = "beta"}, NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "blue"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr}):{I iO $ ipeGroup [ iO $ ipePolygon myPolygon ! attr SFill (IpeColor "red")' ] ! attr SLayer "alpha":}IpeGroup (Group [IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "red"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr})] :+ Attrs {Attr LayerName {_layerName = "alpha"}, NoAttr, NoAttr, NoAttr, NoAttr}) hgeometry.Render to an ipe object using the defIO IpeOut:{/ iO'' myPolygon $ attr SFill (IpeColor "red")' <> attr SLayer "alpha"& <> attr SLayer "beta":}OIpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {Attr LayerName {_layerName = "beta"}, NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "red"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr})4iO'' [ myPolygon , myPolygon ] $ attr SLayer "alpha"IpeGroup (Group [IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr}),IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr})] :+ Attrs {Attr LayerName {_layerName = "alpha"}, NoAttr, NoAttr, NoAttr, NoAttr}) hgeometry6generate an ipe object without any specific attributes hgeometry0Helper to construct a path from a singleton item  hgeometryDraw a polygon  c(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gYC ) * ; : 9 8 7 6 5 4 3 2 1 0 / . - , +*+,56Vc^XWYZ[\]_`abdefghlmnopqrstuvwxyz{|}~     !"#$%&)*+,-./456789:;>?@ABCDEFIJKLMNOPQRSTUVWXYZ[\]^_`abcde 56(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gR  ()"#$%'*)(+,-./0123456789:;<=>?@A`abcdfeghiyz{|}~  RSTUVWXYZ[\]^_`acdefghijklmnopqrste ()  RSTUVWXYZ[\]^_`acdefghijklmnopqrstA(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gc  hgeometryeThe result of a smallest enclosing disk computation: The smallest ball and the points defining it  hgeometryList of two or three elements                BNone%&',-.1234567=>?@AHMPSUVX_g  hgeometryBComputes the Euclidean diametral pair by naively trying all pairs.running time: O(n^2)  hgeometrymGiven a distance function and a list of points pts, computes the diametral pair by naively trying all pairs.running time: O(n^2)      CNone%&',-.1234567=>?@AHMPSUVX_gÁ  hgeometry O(n \log n)  hgeometry O(n \log n)    DNone%&',-.1234567=>?@AHMPSUVX_g  ! hgeometry O(n \log n)W time ConvexHull using Graham-Scan. The resulting polygon is given in clockwise order. Y hgeometrygHelper function so that that can compute both the upper or the lower hull, depending on the function f Z hgeometry0Precondition: The list of input points is sorted ! " # ! " #ENone%&',-.1234567=>?@AHMPSUVX_gb & hgeometryOGiven a list of non-vertical lines, computes the lower envelope using duality. O(n\log n) ' hgeometryGiven a list of non-vertical lines, computes the lower envelope by computing the upper convex hull. It uses the given algorithm to do so@running time: O(time required by the given upper hull algorithm) ( hgeometry=Computes the vertices of the envelope, in left to right order ) hgeometryrGiven two non-parallel lines, compute the intersection point and return the pair of a's associated with the lines $ % & ' ( ) % & $ ' ( )F(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gH * hgeometry O(n \log n)^ time ConvexHull using divide and conquer. The resulting polygon is given in clockwise order. * *GNone%&',-.1234567=>?@AHMPSUVX_g : hgeometry1Expects the input to be a set, i.e. no duplicatesrunning time:  O(n \log n) < hgeometryNub by sorting first A hgeometrySearches in a KDTreerunning time: O(n^{(d-1)/d} + k) E hgeometryrunning time: O(n) , - / . 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F 6 7 8 4 5 3 0 1 2 - / . 9 : ; < = > ? @ A B C D , E FH(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g P hgeometryHorrible 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) T hgeometryBGiven a list of canidate enclosing disks, report the smallest one. U hgeometry#check if a disk encloses all points P Q R S T U P Q R S T UI(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g V hgeometryA pair of points W hgeometry/Naive algorithm to compute the closest pair in d dimensions. Runs in O(n^2) time (for any constant dK). Note that we need at least two elements for there to be a closest pair. X hgeometryCreate a pair of points Y hgeometryxProduce all lists from a vec of elements. Since the Vec contains at least two elements, the resulting list is non-empty V W X Y W V X YJ(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gv Z hgeometryType used in the closest pair computation. The fields represent the points ordered on increasing y-order and the closest pair (if we know it) \ hgeometry+the closest pair and its (squared) distance ] hgeometryJClassical divide and conquer algorithm to compute the closest pair among n points.running time: O(n) ^ hgeometry\Given an ordering and two nonempty sequences ordered according to that ordering, merge them _ hgeometry*Function that does the actual merging work ` hgeometryRGiven some function that decides when to keep things while maintaining some state. a hgeometry7returns the minimum element according to some function. b hgeometry.Get the distance of a (candidate) closest pair _ hgeometry!current closest pair and its dist hgeometrypts on the left hgeometrypts on the right Z [ \ ] ^ _ ` a b ] \ Z [ ^ _ ` a bK(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gq f hgeometry(Data type for things that have a version h hgeometryWrite the output to yaml i hgeometryPrints the yaml j hgeometry-alias for decodeEither' from the Yaml Package k hgeometryalias for reading a yaml file l hgeometryEncode a yaml file n hgeometry7Given a list of candidate parsers, select the right one f g h i j k l m n h l j k i n f g mL(C) Frank Staalssee the LICENSE file Frank StaalsNone!%&',-.1234567=>?@AHMPSUVX_gWV4 x hgeometry&Note that the functor instance is in v  hgeometry#Embedded, *connected*, planar graph  hgeometryrConstruct a plane graph from a simple polygon. It is assumed that the polygon is given in counterclockwise order..the interior of the polygon will have faceId 0Ipre: the input polygon is given in counterclockwise order running time: O(n). [ hgeometry+Constructs a planar from the given vertices  hgeometry"Constructs a connected plane graph3pre: The segments form a single connected componentrunning time:  O(n\log n)  hgeometryGet the number of verticesnumVertices myGraph4  hgeometryGet the number of DartsnumDarts myGraph12  hgeometryGet the number of EdgesnumEdges myGraph6  hgeometryGet the number of facesnumFaces myGraph4  hgeometryEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3]  hgeometry7Enumerate all vertices, together with their vertex data  hgeometryEnumerate all darts  hgeometry6Enumerate all edges. We report only the Positive darts  hgeometry6Lens to access the raw dart data, use at your own risk  hgeometrylens to access the Dart Data  hgeometryLens to access face data  hgeometryMEnumerate 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+")  hgeometry&Enumerate all faces in the plane graph  hgeometryAll faces with their face data.  hgeometryHReports the outerface and all internal faces separately. running time: O(n)  hgeometry+Reports all internal faces. running time: O(n)  hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1)  hgeometry%The vertex this dart is heading in torunning time: O(1)  hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1)  hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k is the output size  hgeometryLAll incoming edges incident to vertex v, in counterclockwise order around v.  hgeometryLAll outgoing edges incident to vertex v, in counterclockwise order around v.  hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output size  hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1)  hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1)  hgeometry 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 0running time: O(1).  hgeometry!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 1running time: O(1).  hgeometry Get the next edge along the facerunning time: O(1).  hgeometry$Get the previous edge along the facerunning time: O(1).  hgeometrytThe darts bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.  hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reported  hgeometrywThe vertices bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.  hgeometryTraverse the vertices(^.vertexData)  $ traverseVertices (i x -> Just (i,x)) myGraph Just [(VertexId 0,()),(VertexId 1,()),(VertexId 2,()),(VertexId 3,())] >>> traverseVertices (i x -> print (i,x)) myGraph >> pure () (VertexId 0,()) (VertexId 1,()) (VertexId 2,()) (VertexId 3,())  hgeometryTraverses the darts6traverseDarts (\d x -> print (d,x)) myGraph >> pure () (Dart (Arc 0) +1,"a+")(Dart (Arc 0) -1,"a-")(Dart (Arc 1) +1,"b+")(Dart (Arc 1) -1,"b-")(Dart (Arc 2) +1,"c+")(Dart (Arc 2) -1,"c-")(Dart (Arc 3) +1,"d+")(Dart (Arc 3) -1,"d-")(Dart (Arc 4) +1,"e+")(Dart (Arc 4) -1,"e-")(Dart (Arc 5) +1,"g+")(Dart (Arc 5) -1,"g-")  hgeometryTraverses the faces6traverseFaces (\i x -> print (i,x)) myGraph >> pure () (FaceId 0,()) (FaceId 1,()) (FaceId 2,()) (FaceId 3,())  hgeometry.Getter for the data at the endpoints of a dartrunning time: O(1)  hgeometry/Data corresponding to the endpoints of the dartrunning time: O(1)  hgeometrygets the id of the outer facerunning time: O(n)  hgeometry[gets a dart incident to the outer face (in particular, that has the outerface on its left)running time: O(n)  hgeometry"Reports all edges as line segments  hgeometryLGiven a dart and the graph constructs the line segment representing the dartO(1)  hgeometryThe polygon describing the face runningtime: O(k), where k is the size of the face.  hgeometryAlias for rawFace Boundary runningtime: O(k), where k is the size of the face.  hgeometry#Lists all faces of the plane graph.  hgeometry%Reads a plane graph from a bytestring  hgeometry$Writes a plane graph to a bytestring  hgeometry_Labels the edges of a plane graph with their distances, as specified by the distance function.  hgeometry data inside hgeometrydata outside the polygonO  x y O  x y      MNone%&',-.1234567=>?@AHMPSUVX_gZ  N(C) Frank Staalssee the LICENSE file Frank StaalsNone"%&',-.1234567=>?@AHMPSUVX_gh#-  hgeometry=The Face data consists of the data itself and a list of holes  hgeometryA planarsubdivision is essentially a bunch of plane-graphs; one for every connected component. These graphs store the global ID's (darts, vertexId's, faceId's) in their data values. This essentially gives us a mapping between the two.note that a face may actually occur in multiple graphs, hence when we store the edges to the the holes, we store the global edgeId's rather than the local edgeId (dart)'s.%invariant: the outerface has faceId 0  hgeometryA connected component.For every face f, and every hole in this face, the facedata points to a dart d on the hole s.t. this dart has the face f on its left. i.e. leftFace d = f  hgeometryget the dataVal of a Raw  hgeometryNData type that expresses whether or not we are inside or outside the polygon.  hgeometry0Constructs a planarsubdivision from a PlaneGraph runningTime: O(n)  hgeometrynGiven a (connected) PlaneGraph and a dart that has the outerface on its left | Constructs a planarsubdivision runningTime: O(n)  hgeometry4Construct a planar subdivision from a simple polygonrunning time: O(n).  hgeometry*Constructs a connected planar subdivision.Cpre: the segments form a single connected component running time:  O(n\log n)  hgeometryGet the number of verticesnumVertices myGraph4  hgeometryGet the number of DartsnumDarts myGraph12  hgeometryGet the number of EdgesnumEdges myGraph6  hgeometryGet the number of facesnumFaces myGraph4  hgeometryEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3]  hgeometry7Enumerate all vertices, together with their vertex data  hgeometryEnumerate all darts  hgeometry6Enumerate all edges. We report only the Positive darts  hgeometryMEnumerate 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+")  hgeometryDEnumerates all faces with their face data exlcluding the outer face  hgeometrylens to access the Dart Data  hgeometrySLens to the facedata of the faces themselves. The indices correspond to the faceIds  hgeometry[Lens to the facedata of the vertexdata themselves. The indices correspond to the vertexId's  hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1)  hgeometry%The vertex this dart is heading in torunning time: O(1)  hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1)  hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k! is the number of edges reported.  hgeometrydGiven a dart d that points into some vertex v, report the next dart e in the cyclic order around v.running time: O(1)  hgeometryLAll incoming edges incident to vertex v, in counterclockwise order around v.  hgeometryLAll outgoing edges incident to vertex v, in counterclockwise order around v.  hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output size  hgeometry The face to the left of the dartrunning time: O(1).  hgeometry!The face to the right of the dartrunning time: O(1).  hgeometryThe darts on the outer boundary of the face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.  hgeometryThe vertices of the outer boundary of the face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.  hgeometryZLists the holes in this face, given as a list of darts to arbitrary darts on those faces.running time: O(k), where k! is the number of darts returned. \ hgeometryENote that using the setting part of this lens may be very expensive!!  hgeometry.Getter for the data at the endpoints of a dartrunning time: O(1)  hgeometry/data corresponding to the endpoints of the dartrunning time: O(1) ! hgeometrygets the id of the outer facerunning time: O(1) " hgeometry"Reports all edges as line segments # hgeometryLGiven a dart and the subdivision constructs the line segment representing itO(1) $ hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reported % hgeometry)Constructs the outer boundary of the faceO(k), where k4 is the complexity of the outer boundary of the face & hgeometry)Constructs the boundary of the given faceO(k), where k is the complexity of the face ' hgeometry*Lists all faces of the planar subdivision.  hgeometry data inside hgeometrydata outside the polygonY x y                           ! " # $ % & ' (Y x y                       ! $   # " & % '    ( O(C) Frank Staalssee the LICENSE file Frank StaalsNone!%&',-.1234567=>?@AHMPSUVX_gh 0 hgeometryConstruct a planar subdivision from a polygon. Since our PlanarSubdivision models only connected planar subdivisions, this may add dummy/invisible edges.running time: O(n) for a simple polygon,  O(n\log n) for a polygon with holes. 0 hgeometry data inside hgeometrydata outside the polygonZ x y                           ! " # $ % & ' ( 0 0PNone%&',-.1234567=>?@AHMPSUVX_g 5 hgeometry8Draws only the values for which we have a Just attribute 6 hgeometry"Draw everything using the defaults 3 4 5 6 7 4 5 6 3 7Q(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.1234567=>?@AHMPSUVX_gԐ 8 hgeometry;Data type representing a two dimensional planar arrangement E hgeometryBuilds an arrangement of n linesrunning time:  O(n^2\log n F hgeometryConstructs the arrangemnet inside the box. note that the resulting box may be larger than the given box to make sure that all vertices of the arrangement actually fit.running time:  O(n^2\log n G hgeometryConstructs the arrangemnet inside the box. (for parts to be useful, it is assumed this boxfits at least the boundingbox of the intersections in the Arrangement) L hgeometry5Constructs a boundingbox containing all intersectionsrunning time: O(n^2), where n is the number of input lines M hgeometryComputes all intersections N hgeometry1Computes the intersections with a particular side O hgeometryHConstructs the unbounded intersections. Reported in clockwise direction. Q hgeometryGLinks the vertices of the outer boundary with those in the subdivision T hgeometrynGiven a predicate that tests if two elements of a CSeq match, find a rotation of the seqs such at they match.Running time: O(n) U hgeometry\Given an Arrangement and a line in the arrangement, follow the line through he arrangement. V hgeometry4Find the starting point of the line the arrangement W hgeometrybGiven a point on the boundary of the boundedArea box; find the vertex this point corresponds to.running time:  O(\log n)basically; maps every point to a tuple of the point and the side the point occurs on. We then binary search to find the point we are looking for. X hgeometryOFind the starting dart of the given vertex v. Reports a dart s.t. tailOf d = v running me: O(k) where k is the degree of the vertex Y hgeometryGiven a dart d that incoming to v (headOf d == v), find the outgoing dart colinear with the incoming one. Again reports dart d' s.t. tailOf d' = vrunning time: O(k)1, where k is the degree of the vertex d points to 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 > 8 9 = < ; : D C B A E F G H I J K L M N O P Q R S T U V W X Yd(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gq 8 9 : ; < = > A B C D E F G U V W X Y 8 9 : ; < = B C A D > E F G U V W X YR(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g Z hgeometryDraws an arrangement [ hgeometryDraws an arrangement Z [ Z [SNone%&',-.1234567=>?@AHMPSUVX_g _ hgeometryUGiven a list of original edges and a list of diagonals, creates a planar-subdivisionrunning time:  O(n\log n) ` hgeometryUGiven a list of original edges and a list of diagonals, creates a planar-subdivisionrunning time:  O(n\log n) _ hgeometry3A counter-clockwise edge along the outer boundary hgeometryremaining original edges hgeometry diagonals ` hgeometry3A counter-clockwise edge along the outer boundary hgeometryremaining original edges hgeometry diagonals \ ^ ] _ ` \ ^ ] _ `TNone %&',-.1234567=>?@AHMPSUVX_g g hgeometry*for every e_i, the id of the helper vertex o hgeometry$assigns a vertex type to each vertex&pre: the polygon is given in CCW orderrunning time: O(n). p hgeometry$assigns a vertex type to each vertex&pre: the polygon is given in CCW orderrunning time: O(n). q hgeometryp  q = p.y < q.y || p.y == q.y && p.x q.y { hgeometrymGiven a polygon, find a set of non-intersecting diagonals that partition the polygon into y-monotone pieces.running time:  O(n\log n) | hgeometryPComputes a set of diagionals that decompose the polygon into y-monotone pieces.running time:  O(n\log n)  hgeometry1Adds edge (i,j) if e_j's helper is a merge vertex  hgeometry-Get the helper of edge i, and its vertex type  hgeometry`finds the edge j to the left of v_i, and connect v_i to it if the helper of j is a merge vertex  hgeometryBreturns True if v the interior of the polygon is to the right of v' d e g f h i n k m l j o p q v w x y z { | } ~  ' i n k m l j o p q h d e g f y x z { | w v } ~  UNone%&',-.1234567=>?@AHMPSUVX_g  hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)  hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)  hgeometryoGiven a y-monotone polygon in counter clockwise order computes the diagonals to add to triangulate the polygon-pre: the input polygon is y-monotone and has n \geq 3 verticesrunning time: O(n)  hgeometry5test if m does not block the line segment from v to u  hgeometry8given a comparison function, merge the two ordered lists  hgeometrykWhen the polygon is in counter clockwise order we return (leftChain,rightChain) ordered from the top-down.if there are multiple points with the maximum yCoord we pick the rightmost one, if there are multiple point with the minimum yCoord we pick the leftmost one.running time: O(n)  VNone%&',-.1234567=>?@AHMPSUVX_g J  hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)  hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)  hgeometryMComputes a set of diagaonals that together triangulate the input polygon of n vertices.running time:  O(n \log n)  hgeometryMComputes a set of diagaonals that together triangulate the input polygon of ns vertices. Returns a copy of the input polygon, whose boundaries are oriented in counter clockwise order, as well.running time:  O(n \log n)  WNone %&',-.1234567=>?@AHMPSUVX_g]  hgeometryeNeighbours are stored in clockwise order: i.e. rotating right moves to the next clockwise neighbour.  hgeometryRotating Right  - rotate clockwise  hgeometry*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 computing  hgeometry2convert the triangulation into a planarsubdivisionrunning time: O(n).  hgeometry,convert the triangulation into a plane graphrunning time: O(n).  XNone%&',-.1234567=>?@AHMPSUVX_g$-  hgeometryNaive 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)  hgeometrypGiven a list of edges, as vertexId pairs, construct a vector with the adjacency lists, each in CW sorted order.  hgeometryGiven 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.  hgeometry0Given a list of faces, construct a list of edges  hgeometryaTest if the given three points form a triangle in the delaunay triangulation. running time: O(n)  YNone%&',-.1234567=>?@AHMPSUVX_gF4  hgeometry7Computes the delaunay triangulation of a set of points.Running time:  O(n \log n)C (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)  hgeometryMapping 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 order  hgeometryXGiven a polygon; construct the adjacency list representation pre: at least two elements  hgeometry&Merge the two delaunay triangulations.running time: O(n), (although we cheat a bit by using a IntMap)  hgeometry'Merges the two delaunay traingulations.  hgeometry'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)  hgeometry&The code that does the actual rotating  hgeometrySymmetric to rotateR  hgeometry=The code that does the actual rotating. Symmetric to rotateR'  hgeometryereturns True if the forth point (vertex) does not lie in the disk defined by the first three points.  hgeometry(Inserts an edge into the right position.  hgeometryNmake sure that the first vtx in the adj list of v is its predecessor on the CH  hgeometryhInserts an edge (and makes sure that the vertex is inserted in the correct. pos in the adjacency lists)  hgeometryDeletes an edge  hgeometry!Lifted version of Convex.IsLeftOf  hgeometry"Lifted version of Convex.IsRightOf  hgeometryan unsafeO version of rotateTo that assumes the element to rotate to occurs in the list.  hgeometryIAdjacency lists are stored in clockwise order, so pred means rotate right  hgeometryKAdjacency lists are stored in clockwise order, so pred and succ rotate left  hgeometry%Removes duplicates from a sorted list  hgeometry lower tangent hgeometry upper tangent  Z(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gNr  hgeometryComputes 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)  [(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_g[!  hgeometrydefines a basic camera ] hgeometry1unit vector from camera into center of the screen ^ hgeometry!viewUp; assumed to be unit vector  hgeometryVLens to get and set the Camera normal, makes sure that the vector remains normalized.  hgeometryQLens to get and set the viewUp vector. Makes sure the vector remains normalized.  hgeometry+Full transformation that renders the figure  hgeometry2Translates world coordinates into view coordinates  hgeometry(Transformation into viewport coordinates  hgeometry#constructs a perspective projection  hgeometry[Rotates coordinate system around the camera, such that we look in the negative z direction  hgeometryFlips the y and z axis.  \None%&',-.1234567=>?@AHMPSUVX_g_ _ hgeometry Strict pair  hgeometry2Fisher Yates shuffle, which shuffles in O(n) time. ` hgeometry`Generate a list of indices in decreasing order, coupled with a random value in the range [0,i].  ](C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gh  hgeometryO(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  hgeometrySmallest enclosing disk.  hgeometry6Smallest enclosing disk, given that p should be on it.  hgeometry;Smallest enclosing disk, given that p and q should be on it  hgeometryConstructs the initial   from two points  ^(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.1234567=>?@AHMPSUVX_gj6 aefgefhijkijlijmijnijoijpijqirsirtiruivwivxivyivziv{iv|iv}iv~iviviviviviviviviviviviv      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_` 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 { | } ~                                                                                                                                           q                               ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I JKLMNOPQRSTUUVWXYZ[\]^^_`abcdefghijklmnopqrstuuvwwxyz{|}~}~uvxyzu{~|}      !"#$%&s'()*+,-./01234567889:;<=>?@ABCDDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ndem&(),+*FO      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`aaabcdefghijklmnopqrstuvwxyz{|}~CCDD                             !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " " " " " """""""""""""""""""" " "!"""#"$"%"&"'"(")"*"+","-"."/"0"1"2"3""4"5"""6"7"8"9":";"<"=">"?"@"A"B"C#D#E##F$$$$G$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%H%H%c%I%J%H%K%L%M%N%O%P%Q%R%S%T%U%V%W%X&Y&Z&&[&\&]&^&B&_&`&]&B&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&{&|&}&~&'''''''''''''''''''''''''(((((((((((((((((((((((()))))))******************++++++++++++++++++++++++++++++++C+D+++++++++++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-- -- . . . . .................../ //!/"/#/$0%0&0'0'0(0)0*0+0T0,0 0-0.0 0/000102030405060708090:0;0<0=0>0?0@0A1B1C1D2E2E2F2G2 2 2H2I2J2K2L2M2N2O2P2Q2R2S2T2U2V2W2X2Y2Z2[2\2]3^3^3_3`3a3b3c3d3d3e3f3g3h3i3j3k3l3m3n3o3p3q4r4s4t5u5u5v5w5x5y5y5z5{5|5z5{5|5}5~5555555555h55555C5555555566666666666666666666677777777777777777777888888888888888888888888888888888899999999999999999999999999999999999999999999:::::::::::: : : : : : ::::;;;;;;;;;;;;;;;;; ;!;";#;#;$;%;&;';;(;);*;+;,;-;.;/;0;1;2;3;4;5;6;7;8;9;:;;;<;=;>;?;@;A;B;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;r;s;t;u;v;w;x;y;z;{;|;};~;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<== = = == = =================== =!=">#>$>%>&>'>(>)>*>+>,>->.>/>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@{@|@}@~AAAAAAAAAAAAAAAABBBCCDDDEEEEEEFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHH$HHHHIIII$JJJJJJJJJJJJKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL LL L L L,L-LLL!L"L#L$L%L&L'L(L)L.L/L0L1L3L4L5LLLLLLL+LLLLLLLLLLLLLL L M N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N !N "N #N $N %N &N 'N (N )N *N +N ,N -N5N7N .N N /N 0N 1N 2N 3NNNNNNNNNNN N,N-NNN N N!N"N#N$N(N%N&N'N.N/N 4N5N 5NNN+NNNN4NNNN 6N 7N 8N 9N :N ;N <N =O >O ?O @P AP BP CP DP EQ FQ FQ GQ HQ IQ JQ KQ LQ MQ NQ OQ PQ QQ RQ SQ TQ UQ VQQ WQ XQ Q YQ ZQ [Q \Q ]Q ^Q _Q `Q aQ bQ cQ dR eR fS gS hS iS jS kS lS mS nT oTT pT qT'T rT+T sTT,T tT uT vT wT xT yT zT {T |T }T ~T TT T T T T T T6T T T T T T TT T T T T T U U U UCUDU U U U U U U U U U U U U U V V V V W W W W W W W W W W W W W W WWWW W W W W W W W W W X X X X X Y Y sY Y Y Y Y Y YhY YiY Y YY Y YY Y Y Y YsY Y Y Y Y Y Z Z ZZ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ \ ]]] ] ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^_ _ _ _ _ _       _ _ _ _ _ _ _ _ _ _ _ _ _ _                       !  "  #  $  %  &  '  (  ) * + , - . / 0 1 2 3L 4 5 6! 7! 8!! 9 : ; <5 =5 >9 ?: @: A: B: C> D> E>\D FD GL HN[ I[ J\\ K L(hgeometry-0.8.0.0-2B18HmKepFxHOPvqiUEkNDData.Geometry.Vector Data.GeometryAlgorithms.Geometry.SweepControl.Monad.State.Persistent Data.BalBSTData.BinaryTreeData.BinaryTree.ZipperData.CircularList.UtilData.CircularSeqData.Geometry.Ipe.LiteralData.Geometry.Ipe.ValueData.Geometry.Ipe.ColorData.Geometry.Ipe.AttributesData.Geometry.PropertiesData.Ext Data.Geometry.Vector.VectorFixed&Data.Geometry.Vector.VectorFamilyPeano!Data.Geometry.Vector.VectorFamilyData.Geometry.PointData.Geometry.TransformationData.Geometry.BoundaryData.Geometry.Line.Internal Data.LSeq Data.OrdSeqData.PermutationData.PlanarGraphAlgorithms.Graph.DFSAlgorithms.Graph.MST Data.RangeData.Geometry.Interval.UtilData.Geometry.IntervalData.Geometry.IntervalTree!Data.Geometry.SegmentTree.GenericData.Geometry.Box.InternalData.Sequence.Util Data.SlowSeqData.Tree.UtilData.UnBoundedData.Geometry.SubLineData.Geometry.LineSegmentData.Geometry.BoxData.Geometry.PolyLine8Algorithms.Geometry.WellSeparatedPairDecomposition.Types7Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD9Algorithms.Geometry.PolyLineSimplification.DouglasPeucker1Algorithms.Geometry.LineSegmentIntersection.Types1Algorithms.Geometry.LineSegmentIntersection.Naive:Algorithms.Geometry.LineSegmentIntersection.BentleyOttmannData.Geometry.LineData.Geometry.SlabData.Geometry.HyperPlaneData.Geometry.DualityData.Geometry.BallData.Geometry.TriangleData.Geometry.HalfLine Data.UtilData.Geometry.PolygonData.Geometry.Polygon.ConvexData.Geometry.Ipe.TypesData.Geometry.Ipe.WriterData.Geometry.Ipe.PathParserData.Geometry.Ipe.ReaderData.Geometry.Ipe.FromIpeData.Geometry.Ipe.IpeOut/Algorithms.Geometry.SmallestEnclosingBall.TypesAlgorithms.Geometry.Diameter+Algorithms.Geometry.LineSegmentIntersection)Algorithms.Geometry.ConvexHull.GrahamScan(Algorithms.Geometry.LowerEnvelope.DualCH/Algorithms.Geometry.ConvexHull.DivideAndConquerData.Geometry.KDTree/Algorithms.Geometry.SmallestEnclosingBall.Naive%Algorithms.Geometry.ClosestPair.Naive0Algorithms.Geometry.ClosestPair.DivideAndConquerData.Yaml.UtilData.PlaneGraphData.PlaneGraph.Draw%Data.Geometry.PlanarSubdivision.BasicData.Geometry.PlanarSubdivision$Data.Geometry.PlanarSubdivision.Draw"Data.Geometry.Arrangement.InternalData.Geometry.Arrangement.Draw.Algorithms.Geometry.PolygonTriangulation.Types5Algorithms.Geometry.PolygonTriangulation.MakeMonotoneViewL:<LSeq:|>EmptyL:<<:<|toSeq<||>><evalpromise forceLSeqappend partition mapWithIndextakedropunstableSortBy unstableSortfromSeqviewlviewrhead $fIxedLSeq $fMonoidLSeq$fSemigroupLSeq $fOrdViewL $fEqViewL$fTraversableViewL$fFoldableViewL$fFunctorViewL$fSemigroupViewL $fOrdViewR $fEqViewR$fTraversableViewR$fFoldableViewR$fFunctorViewR$fSemigroupViewR $fShowLSeq $fReadLSeq$fEqLSeq $fOrdLSeq$fFoldableLSeq $fFunctorLSeq$fTraversableLSeq $fGenericLSeq $fNFDataLSeq $fShowViewR $fShowViewLCompareOrdSeq _asFingerTreegetElemKeyNoKeygetKeyliftCmpinsertBy deleteAllBysplitBysplitOnsplitMonotonic deleteAll fromListBy fromListByOrd fromAscList'lookupBymemberBy mapMonotonic $fMonoidKey$fSemigroupKey$fMeasuredKeyElem$fFoldableOrdSeq$fMonoidOrdSeq$fSemigroupOrdSeq $fShowKey$fEqKey$fOrdKey $fShowOrdSeq $fEqOrdSeq Permutation_orbits_indexesOrbit$fShowPermutation$fEqPermutation$fGenericPermutationindexesorbitselemssizecycleOfnextprevious lookupIdxapply orbitFromcycleRep toCycleRep genIndexes$fTraversablePermutation$fFoldablePermutation$fFunctorPermutation$fNFDataPermutationDart_arc DirectionNegativePositiveArc_unArcrev $fShowArc$fReadDirection$fShowDirection$fNFDataDirection$fEqArc$fOrdArc $fEnumArc $fBoundedArc $fGenericArc $fNFDataArc $fEqDirection$fOrdDirection$fBoundedDirection$fEnumDirection$fGenericDirection$fEqDart $fOrdDart $fGenericDart EdgeOracleFaceId'FaceId _unFaceId HasDataOfDataOfdataOf PlanarGraph VertexId'VertexId _unVertexIdDualOfWorldPrimalDualarctwin isPositiveallDarts buildFromJSON embedding vertexData rawDartDatafaceDatadualdartDataedgeDatatraverseVertices traverseDarts traverseFaces planarGraph' planarGraphfromAdjacencyListstoAdjacencyLists numVerticesnumDartsnumEdgesnumFaces vertices'verticesdarts'dartsedges'edgestailOfheadOf endPoints incidentEdges incomingEdges outgoingEdges neighboursOfnextIncidentEdgeprevIncidentEdgeendPointDataOf endPointDatafaces'facesleftFace rightFacenextEdgeprevEdge boundaryDartboundary boundary'boundaryVertices edgeOraclebuildEdgeOraclehasEdgefindEdgefindDart $fEnumDart $fShowDart $fNFDataDart$fShowVertexId$fFromJSONPlanarGraph$fToJSONPlanarGraph$fEqPlanarGraph$fShowPlanarGraph$fHasDataOfPlanarGraphDart$fHasDataOfPlanarGraphVertexId $fShowFaceId$fHasDataOfPlanarGraphFaceId$fTraversableEdgeOracle$fFoldableEdgeOracle$fFunctorEdgeOracle $fShowWorld $fEqWorld $fEqVertexId $fOrdVertexId$fEnumVertexId$fToJSONVertexId$fFromJSONVertexId$fGenericVertexId$fNFDataVertexId$fGenericPlanarGraph $fEqFaceId $fOrdFaceId $fEnumFaceId$fToJSONFaceId$fFromJSONFaceId$fShowEdgeOracle$fEqEdgeOracleAdjacencyListsdfsadjacencyListsdfs'mstmstEdgesmakeTree_lower_upperEndPointOpenClosed unEndPointisOpenisClosed $fOrdEndPoint$fShowEndPoint$fReadEndPoint $fEqEndPoint$fFunctorEndPoint$fFoldableEndPoint$fTraversableEndPoint$fGenericEndPoint$fNFDataEndPoint $fEqRange$fFunctorRange$fFoldableRange$fTraversableRange$fGenericRange $fNFDataRangeRange' ClosedRange OpenRangelowerupper prettyShowinRangewidthmidPoint clipLower clipUppercoversisValid shiftLeft shiftRight$fIsIntersectableWithRangeRange $fShowRange_unL$fShowL$fEqL $fGenericL $fNFDataL_unRunL$fOrdL$fShowR$fEqR$fOrdR $fGenericR $fNFDataRunRInterval GInterval _unInterval $fEqInterval$fGenericIntervalHasEndEndCoreEndExtraendHasStart StartCore StartExtrastartClosedInterval OpenInterval inInterval shiftLeft'%$fIsIntersectableWithIntervalInterval$fBifunctorInterval$fTraversableInterval$fFoldableInterval$fFunctorInterval$fShowInterval$fHasStartInterval$fHasEndInterval$fNFDataIntervalNodeData _splitPoint_intervalsLeft_intervalsRight$fShowNodeData $fEqNodeData $fOrdNodeData$fGenericNodeData$fNFDataNodeData IntervalTree_unIntervalTree intervalsLeftintervalsRight splitPoint$fShowIntervalTree$fEqIntervalTree$fGenericIntervalTree$fNFDataIntervalTree IntervalLiketoRangeunIntervalTree createTree fromIntervalssearchstab$fIntervalLikeInterval$fIntervalLikeRange_range_assoc$fFunctorNodeDataLeafData _atomicRange _leafAssocassocrange$fNFDataAtomicRange$fShowAtomicRange$fEqAtomicRange$fFunctorAtomicRange$fGenericAtomicRange$fShowLeafData $fEqLeafData$fFunctorLeafData$fGenericLeafData SegmentTree_unSegmentTree atomicRange leafAssoc$fNFDataLeafData$fShowSegmentTree$fEqSegmentTree$fGenericSegmentTree$fNFDataSegmentTreeCountgetCountI_unIAssoc insertAssoc deleteAssoc unSegmentTreefromIntervals'$fIntervalLikeI $fAssoc[]I $fMeasured[]I $fMonoidCount$fSemigroupCount $fAssocCountC$fMeasuredCountC$fShowBuildLeaf $fEqBuildLeaf$fShowI$fReadI$fEqI$fOrdI $fGenericI $fNFDataI $fShowCount $fEqCount $fOrdCount $fNumCount$fIntegralCount $fEnumCount $fRealCount$fGenericCount $fNFDataCount $fGenericC $fNFDataCCWMin_cwMin $fShowCWMin $fEqCWMin $fOrdCWMin$fFunctorCWMin$fFoldableCWMin$fTraversableCWMin$fGenericCWMin $fNFDataCWMinCWMax_cwMaxcwMin$fSemigroupCWMin $fShowCWMax $fEqCWMax $fOrdCWMax$fFunctorCWMax$fFoldableCWMax$fTraversableCWMax$fGenericCWMax $fNFDataCWMaxBox_minP_maxPcwMax$fSemigroupCWMax $fGenericBox IsBoxable boundingBox RectanglemaxPminPboxgrow fromExtent fromCenter centerPointminPointmaxPointinBoxextentwidthInwidthIn'cornersboundingBoxListboundingBoxList'$fIsTransformableBox$fPointFunctorBox$fIsIntersectableWithPointBox$fBifunctorBox$fIsIntersectableWithBoxBox$fSemigroupBox$fIsBoxableBox$fIsBoxablePoint$fOrdBox$fEqBox $fShowBoxbinarySearchSeqbinarySearchVec binarySearch_asSeqZipper ancestorsroot firstChild nextSibling prevSibling allChildrenallTrees unZipperLocal constructTree findEvert findEvert'findPathfindNode findNodes $fShowZipper $fEqZipper UnBounded MinInfinity MaxInfinity _unUnBoundedBottom bottomToMaybe topToMaybeValBValT $fShowTop$fOrdTop $fOrd1Top $fShowBottom$fEqTop $fFunctorTop $fFoldableTop$fTraversableTop$fApplicativeTop $fMonadTop$fEq1Top $fEqBottom $fOrdBottom$fFunctorBottom$fFoldableBottom$fTraversableBottom$fApplicativeBottom $fMonadBottom $fEq1Bottom $fOrd1Bottom $fEqUnBounded$fOrdUnBounded$fFunctorUnBounded$fFoldableUnBounded$fTraversableUnBounded unUnBoundedunBoundedToMaybe$fFractionalUnBounded$fNumUnBounded$fShowUnBoundedSubLine_line _subRangelinesubRange fixEndPoints dropExtra _unBounded toUnbounded fromUnbounded onSubLine onSubLineUB onSubLine2 onSubLine2UBgetEndPointsUnBoundedfromLinetestz#$fIsIntersectableWithSubLineSubLine$$fIsIntersectableWithSubLineSubLine0$fTraversableSubLine$fFoldableSubLine$fFunctorSubLine $fEqSubLine $fShowSubLine LineSegmentClosedLineSegment LineSegment'_SubLine toLineSegment onSegmentorderedEndPoints segmentLengthsqDistanceToSegsqDistanceToSegArg flipSegment$$fIsIntersectableWithLineSegmentLine+$fIsIntersectableWithLineSegmentLineSegment$fBifunctorLineSegment$fIsTransformableLineSegment$fIsBoxableLineSegment$fPointFunctorLineSegment$fShowLineSegment$fHasSupportingLineLineSegment$fHasEndLineSegment$fHasStartLineSegment$fFunctorLineSegment$fEqLineSegmenttopSide bottomSideleftSide rightSidesidessides' $fNFDataBoxPolyLine_pointspoints fromPoints fromPoints'fromLineSegment asLineSegmentasLineSegment'$fBifunctorPolyLine$fPointFunctorPolyLine$fIsTransformablePolyLine$fIsBoxablePolyLine$fSemigroupPolyLine$fFunctorPolyLine $fOrdPolyLine $fEqPolyLine$fShowPolyLine _splitDim_bBox _nodeDataWSPPointSet SplitTreeLevel_unLevel _widestDimPointSeqbBoxnodeDatasplitDim$fTraversableNodeData$fFoldableNodeData$fMeasuredvNodeData $fShowLevel $fEqLevel $fOrdLevelFindAndCompactFAC _leftPart _rightPart _shortSide ShortSideIdxunLevel widestDim nextLevel$fShowShortSide $fEqShortSide$fEqFindAndCompact$fShowFindAndCompactleftPart rightPart shortSideRST fairSplitTreewellSeparatedPairsfairSplitTree'distributePoints transposedistributePoints' fromSeqUnsafe reIndexPoints assignLevels compactEnds assignLevellevelOfhasLevel compactEnds'findAndCompactwidestDimensionwidthsextends findPairsareWellSeparatedboxBoxareWellSeparated'boxBox1maxWidthbbOf children'ix'dropIdxdouglasPeuckermergemaxDistIntersectionPoint_intersectionPoint_associatedSegs Intersections Associated _endPointOf _interiorToSet' endPoints' associated endPointOf interiorTo$fMonoidAssociated$fSemigroupAssociated$fEqAssociated$fShowAssociated$fShowIntersectionPoint$fEqIntersectionPointassociatedSegsintersectionPointisEndPointIntersection intersections handlePointaddTo isEndPointOfpairsStatusStructure EventQueueEvent eventPoint eventType EventTypeStartEndinteriorIntersections asEventPts groupStarts ordPoints startSegsordAtxCoordAtsweep isClosedStarthandleextractContainstoStatusStruct rightEndpointendsAt findNewEvent$fOrdEventType $fEqEventType $fOrdEvent$fShowEventType $fShowEvent $fEqEvent$fIsIntersectableWithLineBox!$fIsIntersectableWithLineBoundary$fIsTransformableLineSlab_unSlab Orthogonal$fShowOrthogonal$fEqOrthogonal$fReadOrthogonal $fShowSlab$fEqSlabHasBoundingLines boundingLinesinSlabunSlabhorizontalSlab verticalSlab$fIsIntersectableWithSlabSlab$fIsIntersectableWithSlabSlab0$fBifunctorSlab$fTraversableSlab$fFoldableSlab $fFunctorSlab$$fIsIntersectableWithLineSegmentSlab $fIsIntersectableWithSubLineSlab$fIsIntersectableWithLineSlab$fHasBoundingLinesVertical$fHasBoundingLinesHorizontal HyperPlane_inPlane _normalVec$fGenericHyperPlaneHasSupportingPlanesupportingPlanePlaneinPlane normalVec onHyperPlane from3Points$fIsTransformableHyperPlane#$fIsIntersectableWithLineHyperPlane$fHasSupportingPlaneHyperPlane$fTraversableHyperPlane$fFoldableHyperPlane$fFunctorHyperPlane$fNFDataHyperPlane$fEqHyperPlane$fShowHyperPlanedualLine dualPoint dualPoint'Ball_center_squaredRadius $fGenericBallTouchingCircleDiskSpherecenter squaredRadiusradius fromDiameterfromCenterAndPointunitBallinBall insideBall inClosedBallonBalldisk$fBifunctorBall $fFunctorBall $fNFDataBall($fIsIntersectableWithLineSegmentBoundary$fShowTouching $fEqTouching $fOrdTouching$fFunctorTouching$fFoldableTouching$fTraversableTouching$fEqBall $fShowBallTriangle triangle' sideSegmentsarea doubleAreaisDegenerateTriangle inscribedDisktoBarricentricfromBarricentric inTriangle onTriangle!$fIsIntersectableWithLineTriangle"$fIsIntersectableWithLineTriangle0$fHasSupportingPlaneTriangle$fIsTransformableTriangle$fPointFunctorTriangle$fFunctorTriangle $fEqTriangle$fReadTriangle$fShowTriangleHalfLine _startPoint_halfLineDirection$fGenericHalfLinehalfLineDirection startPointhalfLineToSubLine fromSubLine onHalfLine toHalfLine$fIsTransformableHalfLine$fHasSupportingLineHalfLine$fHasStartHalfLine$fTraversableHalfLine$fFoldableHalfLine$fFunctorHalfLine$fNFDataHalfLine $fEqHalfLine$fShowHalfLineSPSTRtrd'uniqueTriplets uniquePairs nonEmptyTails$fField3STRSTRcd$fField2STRSTRbd$fField1STRSTRad $fNFDataSTR $fMonoidSTR$fSemigroupSTR $fBifunctorSP$fField2SPSPbc$fField1SPSPac $fNFDataSP $fMonoidSP $fSemigroupSP $fShowSTR$fEqSTR$fOrdSTR $fFunctorSTR $fGenericSTR$fShowSP$fEqSP$fOrdSP $fFunctorSP $fGenericSP SomePolygon MultiPolygon SimplePolygonPolygon PolygonTypeSimpleMultibitraverseVertices outerBoundary polygonHoles outerVertexouterBoundaryEdgeholeListpolygonVerticesouterBoundaryEdges listEdgeswithIncidentEdgestoEdges onBoundary inPolygon insidePolygon signedAreacentroidisCounterClockwisetoClockwiseOrdertoCounterClockWiseOrderreverseOuterBoundaryasSimplePolygon cmpExtremeextremesLinearnumberVertices$fIsBoxablePolygon$fIsTransformablePolygon$fPointFunctorPolygon $fEqPolygon $fShowPolygon$fNFDataPolygon$fBitraversablePolygon$fBifoldablePolygon$fBifunctorPolygon ConvexPolygon_simplePolygon$fShowConvexPolygon$fEqConvexPolygon$fNFDataConvexPolygon simplePolygonextremesmaxInDirection leftTangent rightTangent lowerTangent upperTangent isRightOfisLeftOf minkowskiSum bottomMost$fIsBoxableConvexPolygon$fIsTransformableConvexPolygon$fPointFunctorConvexPolygonImage _imageData_rect LayerName _layerName$fShowLayerName$fReadLayerName $fEqLayerName$fOrdLayerName$fIsStringLayerName $fShowImage $fEqImage $fOrdImage IpeSymbolSymbol _symbolPoint _symbolNameMiniPage TextLabelLabel imageDatarect$fIsTransformableImage$fIsTransformableTextLabel$fIsTransformableMiniPage$fShowTextLabel $fEqTextLabel$fOrdTextLabel$fShowMiniPage $fEqMiniPage $fOrdMiniPage$fShowIpeSymbol $fEqIpeSymbol$fOrdIpeSymbol PathSegmentPolyLineSegment PolygonPathCubicBezierSegmentQuadraticBezierSegmentEllipseSegment ArcSegment SplineSegmentClosedSplineSegment symbolName symbolPoint$fIsTransformableIpeSymbol$fShowPathSegment$fEqPathSegmentPath _pathSegments_PolyLineSegment _PolygonPath_CubicBezierSegment_QuadraticBezierSegment_EllipseSegment _ArcSegment_SplineSegment_ClosedSplineSegment$fIsTransformablePathSegment $fShowPath$fEqPath OperationMoveToLineToCurveToQCurveToEllipseArcToSpline ClosedSpline ClosePath pathSegments$fIsTransformablePath $fEqOperation$fShowOperationAttrMap_MoveTo_LineTo_CurveTo _QCurveTo_Ellipse_ArcTo_Spline _ClosedSpline _ClosePath IpeObjectIpeGroupIpeImage IpeTextLabel IpeMiniPageIpeUseIpePath IpeObject' IpeAttributes Attributes' AttributesOfGroup AttrMapSym0AttrMapSym0KindInference AttrMapSym1AttrMapSym1KindInference AttrMapSym2 attributes%$fSuppressUnusedWarnings->AttrMapSym1%$fSuppressUnusedWarnings->AttrMapSym0$fIsTransformableGroup $fShowGroup $fEqGroup $fEqIpeObject$fShowIpeObjectView _layerNames _activeLayerToObject mkIpeObject _IpeGroup _IpeImage _IpeTextLabel _IpeMiniPage_IpeUse_IpePath groupItems ipeObject'commonAttributes flattenGroups$fIsTransformableIpeObject$fToObjectPath$fToObjectIpeSymbol$fToObjectMiniPage$fToObjectTextLabel$fToObjectImage$fToObjectGroup$fEqView $fOrdView $fShowViewIpeStyle _styleName _styleData activeLayer layerNames $fEqIpeStyle$fShowIpeStyle IpePreamble _encoding _preambleData styleData styleName basicIpeStyle$fEqIpePreamble$fReadIpePreamble$fShowIpePreamble$fOrdIpePreambleIpePage_layers_views_content IpeBitmapencoding preambleData $fEqIpePage $fShowIpePageIpeFile _preamble_styles_pagescontentlayersviews fromContent $fEqIpeFile $fShowIpeFilepagespreamblestylessinglePageFilesinglePageFromContent applyMatrix' applyMatrix applyMatricesapplyMatricesPageIpeWriteipeWrite IpeWriteText ipeWriteText writeIpeFile writeIpePageprintAsIpeSelectiontoIpeSelectionXMLtoIpeXML writeIpeFile' ipeWriteAttrswriteAttrValuesaddAttsmAddAtts writeByShowunwords'unlines' ipeWriteRec fromPolyLinecombine$fIpeWriteText()$fIpeWriteTextPathSegment$fIpeWriteTextPolygon$fIpeWriteTextPolyLine$fIpeWriteTextOperation$fIpeWriteTextMatrix$fIpeWriteTextPath$fIpeWriteTextIpeArrow$fIpeWriteTextFillType$fIpeWriteTextIpeDash$fIpeWriteTextRGB$fIpeWriteTextPinType!$fIpeWriteTextTransformationTypes$fIpeWriteTextIpeValue$fIpeWriteTextPoint$fIpeWriteTextRatio$fIpeWriteTextFixed$fIpeWriteTextInteger$fIpeWriteTextInt$fIpeWriteTextDouble$fIpeWriteTextText$fIpeWriteTextEither$fIpeWriteTextAttr $fIpeWrite()$fIpeWriteLineSegment$fIpeWritePolyLine$fIpeWriteIpeFile$fIpeWriteIpePreamble$fIpeWriteIpeStyle$fIpeWriteIpePage$fIpeWriteView$fIpeWriteLayerName$fIpeWriteIpeObject$fIpeWriteTextLabel$fIpeWriteImage$fIpeWriteMiniPage $fIpeWrite:+$fIpeWriteGroup$fIpeWritePath$fIpeWriteIpeSymbol$fIpeWriteEither $fIpeWrite[]$fIpeWriteTextLayerName$fIpeWriteTextIpeColor$fIpeWriteTextIpePen$fIpeWriteTextIpeSizeEither'Left'Right' CoordinatedefaultFromSeqreadCoordinate readPoint runParsereither'readPathOperations errorText combineErrorssplitKeepDelims readMatrix readRectangle pOperationpPoint pCoordinate pRectanglepMatrixmkMatrix$fCoordinateRatio$fCoordinateDouble$fMonoidEither'$fSemigroupEither' $fShowEither' $fEqEither' IpeReadAttr ipeReadAttrIpeReadipeRead IpeReadText ipeReadTextConversionErrorreadRawIpeFile readIpeFilereadSinglePageFile fromIpeXMLreadXMLipeReadTextWith ipeReadRec ipeReadAttrs ipeReadObject$fIpeReadTextPath$fIpeReadTextNonEmpty$fIpeReadText[]$fIpeReadTextIpeSize$fIpeReadTextIpePen$fIpeReadTextIpeColor$fIpeReadTextRGB$fIpeReadTextBox$fIpeReadTextIpeDash$fIpeReadTextIpeArrow$fIpeReadTextFillType $fIpeReadTextTransformationTypes$fIpeReadTextPinType$fIpeReadTextLayerName$fIpeReadTextMatrix$fIpeReadTextPoint$fIpeReadTextInt$fIpeReadTextText$fIpeReadIpeFile$fIpeReadIpePage $fIpeReadView$fIpeReadLayerName$fIpeReadGroup$fIpeReadIpeObject$fIpeReadImage$fIpeReadMiniPage$fIpeReadTextLabel $fIpeReadPath$fIpeReadIpeSymbol$fIpeReadAttrAttrHasDefaultFromIpeDefaultFromIpedefaultFromIpe_asLineSegment _asPolyLine_asSimplePolygon _asTriangle_asMultiPolygon polygonToPath pathToPolygon _withAttrsreadAll readAllFrom fromSingleton$fHasDefaultFromIpePolygon$fHasDefaultFromIpePolygon0$fHasDefaultFromIpePolyLine$fHasDefaultFromIpeLineSegmentHasDefaultIpeOut DefaultIpeOutdefIOIpeOut!iOiO''iO'ipeMark ipeDiskMarkipeLineSegment ipePolyLineipeDisk ipeCirclepath pathSegment ipePolygonipeGroup$fHasDefaultIpeOutBall$fHasDefaultIpeOutConvexPolygon$fHasDefaultIpeOutEither$fHasDefaultIpeOutPolygon$fHasDefaultIpeOutLine$fHasDefaultIpeOutPolyLine$fHasDefaultIpeOutLineSegment$fHasDefaultIpeOutPoint$fHasDefaultIpeOut[]$fHasDefaultIpeOut:+ DiskResult_enclosingDisk_definingPoints TwoOrThree$fFoldableTwoOrThree$fShowTwoOrThree$fReadTwoOrThree$fEqTwoOrThree$fOrdTwoOrThree$fFunctorTwoOrThreedefiningPoints enclosingDisk diameterNaivediametralPairNaivediametralPairWithNaivehasInteriorIntersectionshasSelfIntersections convexHull upperHull lowerHullUpperHullAlgorithmEnvelope lowerEnvelopelowerEnvelopeWith intersect'$fSemigroupMergeKDTreeKDTree'KDTunKDTSplit'CoordunCoordtoMaybe buildKDTree buildKDTree'ordNub toPointSet compareOnbuild reportSubTree searchKDTree searchKDTree'boxOf containedIn asSingleton $fEnumCoord $fShowCoord $fEqCoord $fEqKDTree $fShowKDTree $fEqKDTree' $fShowKDTree'smallestEnclosingDisktripletsdisk'smallestEnclosingDisk' enclosesAllPP closestPairmkPairCCPCP mergeSortedBy mergePairsrunWhileminBygetDist$fSemigroupCCP $fShowCCP$fEqCCP Versioned encodeYaml printYaml decodeYamldecodeYamlFileencodeYamlFile unversionedparseVersioned$fToJSONVersioned $fFromJSONV$fShowVersioned$fReadVersioned$fGenericVersioned $fEqVersioned$fFunctorVersioned$fFoldableVersioned$fTraversableVersioned VertexData$fShowVertexData$fEqVertexData$fOrdVertexData$fGenericVertexData$fFunctorVertexData$fFoldableVertexData$fTraversableVertexData PlaneGraphlocationvData vtxDataToExt$fToJSONVertexData$fFromJSONVertexData$fBifunctorVertexData$fShowPlaneGraph$fEqPlaneGraph$fToJSONPlaneGraph$fFromJSONPlaneGraph$fGenericPlaneGraphgraphfromSimplePolygonfromConnectedSegmentsfaces'' internalFaces vertexDataOf locationOf endPointsOf outerFaceId outerFaceDart edgeSegments edgeSegmentrawFaceBoundaryrawFacePolygonrawFacePolygonsreadPlaneGraphwritePlaneGraphwithEdgeDistances$fHasDataOfPlaneGraphFaceId$fHasDataOfPlaneGraphDart$fHasDataOfPlaneGraphVertexId$fIsBoxablePlaneGraph$fFunctorPlaneGraphdrawPlaneGraphFaceData$fShowFaceData $fEqFaceData $fOrdFaceData$fFunctorFaceData$fFoldableFaceData$fTraversableFaceData$fGenericFaceDataPlanarSubdivision ComponentRaw_compId_idxVal_dataVal ComponentIdWrapfDataholesdataVal$fToJSONFaceData$fFromJSONFaceData$fBifunctorFaceData $fToJSONRaw $fFromJSONRaw$fShowComponentId$fEqComponentId$fOrdComponentId$fGenericComponentId$fBoundedComponentId$fEnumComponentId$fToJSONComponentId$fFromJSONComponentId$fEqRaw $fShowRaw $fFunctorRaw $fFoldableRaw$fTraversableRaw $fGenericRaw$fShowPlanarSubdivision$fEqPlanarSubdivision$fFunctorPlanarSubdivision$fGenericPlanarSubdivisionPolygonFaceData components rawFaceData rawVertexData componentfromPlaneGraphfromPlaneGraph'outerBoundaryDartsholesOf dartMapping"$fHasDataOfPlanarSubdivisionFaceId $fHasDataOfPlanarSubdivisionDart$$fHasDataOfPlanarSubdivisionVertexId$fIsBoxablePlanarSubdivision$fShowPolygonFaceData$fReadPolygonFaceData$fEqPolygonFaceData fromPolygon$fShowHoleData $fEqHoleDataMIOdrawColoredPlanarSubdivisiondrawPlanarSubdivisiondrawPlanarSubdivision'drawPlanarSubdivisionWith Arrangement _inputLines _subdivision _boundedArea_unboundedIntersectionsArrangementBoundary$fShowArrangement$fEqArrangement boundedArea inputLines subdivisionunboundedIntersectionsconstructArrangementconstructArrangementInBoxconstructArrangementInBox'computeSegsAndPartsperLine toSegmentsmakeBoundingBoxsideIntersectionsunBoundedPartsmap4link makePairsallPairs alignWith traverseLine findStartfindStartVertex findStartDartfollowdrawArrangementdrawColoredArrangementPolygonEdgeTypeOriginalDiagonalconstructSubdivisionconstructGraph$fShowPolygonEdgeType$fReadPolygonEdgeType$fEqPolygonEdgeType StatusStruct _statusStruct_helper VertexTypeMergeRegularclassifyVerticesclassifyVertices'cmpSweep$fShowVertexType$fReadVertexType$fEqVertexType$fShowStatusStruct VertexInfoSweephelper statusStructcomputeDiagonals makeMonotonetell'getIdx getVertexType getEventTypeinsertAtdeleteAt handleStart handleEnd tellIfMerge getHelper handleSplit handleMerge connectToLeft isLeftVertexhandleRegularLhandleRegularRStackPLRMonotonePolygon triangulate triangulate'chainOftoVtxsegprocessisInsidemergeBy splitPolygon testPoly5$fShowLR$fEqLRcomputeDiagonals' Triangulation _vertexIds _positions _neighboursAdjVertexVertexID$fShowTriangulation$fEqTriangulationST'ArcIDSTMapping neighbours positions vertexIdsshowDTtriangulationEdgestEdgesdrawTriangulationtoPlanarSubdivision toPlaneGraphdelaunayTriangulation toAdjLists sortAround' extractEdges isDelaunayFirstsdelaunayTriangulation'firstsfromHullmoveUprotateR'rotateL'qTest rotateToFirstinsert'lookup'size'pred'succ'focus'nub'withIDlookup''MSTW euclideanMST treeEdgesCamera $fShowCamera $fEqCamera $fOrdCameracameraPositionfarDistnearDistrawCameraNormal rawViewUpscreenDimensionsviewPlaneDepth cameraNormalviewUpcameraTransform worldToView toViewPortperspectiveProjectionrotateCoordSystemflipAxesshufflesmallestEnclosingDiskWithPointsmallestEnclosingDiskWithPointsinitial$fArbitraryDart$fArbitraryDirection$fArbitraryArc$fArbitraryLineSegment$fArbitrarySubLine$fArbitraryInterval $fArbitrary:+$fArbitraryRange$fArbitraryEndPoint$fArbitraryBox$fArbitraryLine$fArbitraryPoint$fArbitraryVector$fArbitraryLSeq$fArbitraryBinLeafTree$fArbitraryBinaryTree$fArbitraryOrdSeq withFocuspManypPaddedNaturalpNotFollowedBy<*><><***>***>parsec-3.1.13.0Text.Parsec.TextParserText.Parsec.Error ParseErrorrunP'runPpMany1pChoicepNaturalpIntegerpCharpSpace pWhiteSpacepMaybepCountpSepBy<*><<***%singletons-2.5-7Iv7r813Yh5B5GrxCKAk7xData.Singletons.InternalSingSLayerSClip SGradientSTilingSOpacitySRArrowSArrow SFillRule SLineJoinSLineCapSDashSSizeSPenSFillSStrokeSTransformationsSPinSMatrixscalarMultiple'D:R:IntersectionOfLineLinedualDualIdentity encodeJSON updateData updateData'reorderEdgeData computeDual computeDual'UFfind'cmpLowercmpUpper AtomicRange interleavegetRangebase GHC.MaybeNothing%D:R:IntersectionOfLineSegmentBoundaryD:R:IntersectionOfLineBoundaryD:R:DimensionPolygon rightMostleftMost getVerticesD:R:DimensionConvexPolygonzipTraverseWithallTexthullhull' fromVertices_rawCameraNormal _rawViewUprands